mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 17:31:43 +00:00
cody-slack: initial implementation (#50470)
Cody Slack bot experimental implementation.
- Take a look at README.md for technical details.
- Introduces new client package `cody-slack`.
- No changes made to other client packages.
## Test plan
CI and talk to @cody_dev in Slack 😜
This commit is contained in:
parent
ba4cbedb6b
commit
ea74d8d784
@ -8,6 +8,7 @@ client/client-api/node_modules
|
||||
client/codeintellify/node_modules
|
||||
client/cody/node_modules
|
||||
client/cody-shared/node_modules
|
||||
client/cody-slack/node_modules
|
||||
client/cody-ui/node_modules
|
||||
client/cody-web/node_modules
|
||||
client/common/node_modules
|
||||
|
||||
2
client/cody-slack/.eslintignore
Normal file
2
client/cody-slack/.eslintignore
Normal file
@ -0,0 +1,2 @@
|
||||
/dist/
|
||||
/out/
|
||||
24
client/cody-slack/.eslintrc.js
Normal file
24
client/cody-slack/.eslintrc.js
Normal file
@ -0,0 +1,24 @@
|
||||
// @ts-check
|
||||
|
||||
const baseConfig = require('../../.eslintrc')
|
||||
module.exports = {
|
||||
extends: '../../.eslintrc.js',
|
||||
parserOptions: {
|
||||
...baseConfig.parserOptions,
|
||||
project: [__dirname + '/tsconfig.json'],
|
||||
},
|
||||
overrides: baseConfig.overrides,
|
||||
rules: {
|
||||
'id-length': 'off',
|
||||
'no-console': 'off',
|
||||
'no-restricted-imports': [
|
||||
'error',
|
||||
{
|
||||
patterns: ['!@sourcegraph/cody-shared/*'], // allow any imports from the @sourcegraph/cody-shared package
|
||||
},
|
||||
],
|
||||
'unicorn/filename-case': 'off',
|
||||
'arrow-body-style': 'off',
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
},
|
||||
}
|
||||
3
client/cody-slack/.gitignore
vendored
Normal file
3
client/cody-slack/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules/
|
||||
out/
|
||||
dist/
|
||||
52
client/cody-slack/BUILD.bazel
generated
Normal file
52
client/cody-slack/BUILD.bazel
generated
Normal file
@ -0,0 +1,52 @@
|
||||
load("@aspect_rules_js//npm:defs.bzl", "npm_package")
|
||||
load("@aspect_rules_ts//ts:defs.bzl", "ts_config")
|
||||
load("@npm//:defs.bzl", "npm_link_all_packages")
|
||||
load("//dev:defs.bzl", "ts_project")
|
||||
|
||||
npm_link_all_packages(name = "node_modules")
|
||||
|
||||
ts_config(
|
||||
name = "tsconfig",
|
||||
src = "tsconfig.json",
|
||||
visibility = ["//client:__subpackages__"],
|
||||
deps = [
|
||||
"//:tsconfig",
|
||||
"//client/cody-shared:tsconfig",
|
||||
"//client/common:tsconfig",
|
||||
],
|
||||
)
|
||||
|
||||
ts_project(
|
||||
name = "cody-slack",
|
||||
srcs = [
|
||||
"src/app.ts",
|
||||
"src/constants.ts",
|
||||
"src/mention-handler.ts",
|
||||
"src/services/codebase-context.ts",
|
||||
"src/services/openai-completions-client.ts",
|
||||
"src/services/sourcegraph-client.ts",
|
||||
"src/services/stream-completions.ts",
|
||||
"src/slack/helpers.ts",
|
||||
"src/slack/init.ts",
|
||||
"src/slack/message-interaction.ts",
|
||||
"src/slack/preamble.ts",
|
||||
],
|
||||
tsconfig = ":tsconfig",
|
||||
deps = [
|
||||
":node_modules/@slack/bolt",
|
||||
":node_modules/@slack/web-api",
|
||||
":node_modules/@sourcegraph/cody-shared",
|
||||
":node_modules/openai",
|
||||
"//:node_modules/@types/lodash",
|
||||
"//:node_modules/envalid",
|
||||
"//:node_modules/lodash",
|
||||
],
|
||||
)
|
||||
|
||||
npm_package(
|
||||
name = "cody-slack_pkg",
|
||||
srcs = [
|
||||
"package.json",
|
||||
":cody-slack",
|
||||
],
|
||||
)
|
||||
201
client/cody-slack/LICENSE
Normal file
201
client/cody-slack/LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2022 Sourcegraph, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
23
client/cody-slack/README.md
Normal file
23
client/cody-slack/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
## Cody Slack (experimental)
|
||||
|
||||
Cody-Slack is an experimental Slack bot designed to bring the power of Cody to your Slack workspace. The main goal is to provide a useful developer experience tool that shares knowledge directly within Slack, interacts with different data stores (Sourcegraph repo, handbook, docs website), uses tools like GitHub CLI to do things and ultimately boosts productivity.
|
||||
|
||||
## Architecture
|
||||
|
||||
Cody-Slack's architecture is similar to the VSCode extension, as it's built on top of the `cody-shared` package. The Slack bot responds only to `app_mention` messages and uses all messages from a Slack thread where it's mentioned as a prompt context to improve responses.
|
||||
|
||||
Currently, key settings like repo (`sourcegraph/sourcegraph`), embeddings type (`blended`), and serverEndpoint (`s2`) are hardcoded. The Slack bot leverages Sourcegraph embeddings endpoint and Slack thread messages to create prompts. It then streams results back to the Slack thread, throttling message updates to avoid bumping into the Slack rate limiter.
|
||||
|
||||
By default, the Slack bot uses the Claude model, but it also has an implemented OpenAI completion client for future testing.
|
||||
|
||||
## Local Development
|
||||
|
||||
Use the `sg run cody-slack` command and provide all required environment variables via `sg.config.overwrite.yaml`. You can use `ngrok` to expose the local port to the internet and set the URL as [the Events Request URL](https://api.slack.com/apis/connections/events-api#request-urls) in the Slack configuration. To avoid affecting the production version of the Slack bot, create your own application for local development purposes.
|
||||
|
||||
An alternative option is to use [Socket Mode](https://api.slack.com/apis/connections/socket), which automatically connects to the Slack backend. However, Socket Mode has proven unreliable, as it regularly loses events, making local development challenging. Several GitHub issues are related to this problem.
|
||||
|
||||
Is there a better way to approach the local development of the Slack bot with the Events API? File a PR to update this section if you know about it!
|
||||
|
||||
## Deployment
|
||||
|
||||
The production deployment is rather simple: all code is bundled together using esbuild into a single JavaScript file (`pnpm build`), which is then uploaded to a Heroku eco dyno (`pnpm release`). The second command works only for @valerybugakov locally since the deployment is configured for his account. While this approach is suitable for prototyping with a 5-second re-deployment time, it would be great to host the Slack bot on Sourcegraph infrastructure (help wanted 👋).
|
||||
11
client/cody-slack/jest.config.js
Normal file
11
client/cody-slack/jest.config.js
Normal file
@ -0,0 +1,11 @@
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('@jest/types').Config.InitialOptions} */
|
||||
const config = require('../../jest.config.base')
|
||||
|
||||
/** @type {import('@jest/types').Config.InitialOptions} */
|
||||
module.exports = {
|
||||
...config,
|
||||
displayName: 'cody-slack',
|
||||
rootDir: __dirname,
|
||||
}
|
||||
23
client/cody-slack/package.json
Normal file
23
client/cody-slack/package.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "@sourcegraph/cody-slack",
|
||||
"private": true,
|
||||
"displayName": "Sourcegraph Cody Slack",
|
||||
"version": "0.0.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Your programming sidekick powered by AI and Sourcegraph's code search and intelligence.",
|
||||
"scripts": {
|
||||
"start": "ts-node-transpile-only ./src/app.ts",
|
||||
"lint": "pnpm run lint:js",
|
||||
"lint:js": "eslint --cache '**/*.[tj]s?(x)'",
|
||||
"build": "esbuild ./src/app.ts --bundle --outfile=dist/app.js --format=cjs --platform=node",
|
||||
"build-ts": "tsc -b --emitDeclarationOnly",
|
||||
"release": "pnpm run build && cd dist && git add . && git commit -m wip && git push heroku master"
|
||||
},
|
||||
"dependencies": {
|
||||
"@slack/bolt": "^3.12.2",
|
||||
"@slack/web-api": "^6.8.1",
|
||||
"@sourcegraph/cody-shared": "workspace:*",
|
||||
"@sourcegraph/common": "workspace:*",
|
||||
"openai": "^3.2.1"
|
||||
}
|
||||
}
|
||||
36
client/cody-slack/src/app.ts
Normal file
36
client/cody-slack/src/app.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { ENVIRONMENT_CONFIG, DEFAULT_APP_SETTINGS } from './constants'
|
||||
import { handleHumanMessage } from './mention-handler'
|
||||
import { createCodebaseContext } from './services/codebase-context'
|
||||
import { isBotEvent } from './slack/helpers'
|
||||
import { app } from './slack/init'
|
||||
|
||||
const { PORT } = ENVIRONMENT_CONFIG
|
||||
|
||||
// Main function to start the bot
|
||||
async function startBot() {
|
||||
// Create a context for the codebase using the default app settings
|
||||
const codebaseContext = await createCodebaseContext(DEFAULT_APP_SETTINGS.codebase, DEFAULT_APP_SETTINGS.contextType)
|
||||
|
||||
// Listen for mentions in the Slack app
|
||||
app.event<'app_mention'>('app_mention', async ({ event }) => {
|
||||
// Ignore events generated by bots
|
||||
if (isBotEvent(event)) {
|
||||
return
|
||||
}
|
||||
|
||||
console.log('APP_MENTION', event.text)
|
||||
// Process the mention event generated by a human user
|
||||
await handleHumanMessage(event, codebaseContext)
|
||||
})
|
||||
|
||||
// Start the Slack app on the specified port
|
||||
return app.start(PORT)
|
||||
}
|
||||
|
||||
// Start the bot and log the status
|
||||
startBot()
|
||||
.then(() => console.log(`⚡️ Cody Slack-bot is running on port ${PORT}!`))
|
||||
.catch(error => {
|
||||
console.error('Error starting the bot:', error)
|
||||
process.exit(1)
|
||||
})
|
||||
19
client/cody-slack/src/constants.ts
Normal file
19
client/cody-slack/src/constants.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { cleanEnv, str, num } from 'envalid'
|
||||
|
||||
export const ENVIRONMENT_CONFIG = cleanEnv(process.env, {
|
||||
PORT: num({ default: 3000 }),
|
||||
|
||||
// OPENAI_API_KEY: str(),
|
||||
SOURCEGRAPH_ACCESS_TOKEN: str(),
|
||||
|
||||
SLACK_APP_TOKEN: str(),
|
||||
SLACK_BOT_TOKEN: str(),
|
||||
SLACK_SIGNING_SECRET: str(),
|
||||
})
|
||||
|
||||
export const DEFAULT_APP_SETTINGS = {
|
||||
codebase: 'github.com/sourcegraph/sourcegraph',
|
||||
serverEndpoint: 'https://sourcegraph.sourcegraph.com',
|
||||
contextType: 'blended',
|
||||
debug: 'development',
|
||||
} as const
|
||||
131
client/cody-slack/src/mention-handler.ts
Normal file
131
client/cody-slack/src/mention-handler.ts
Normal file
@ -0,0 +1,131 @@
|
||||
import { AppMentionEvent } from '@slack/bolt'
|
||||
import { Message as SlackReplyMessage } from '@slack/web-api/dist/response/ChannelsRepliesResponse'
|
||||
import { throttle } from 'lodash'
|
||||
|
||||
import { Transcript } from '@sourcegraph/cody-shared/src/chat/transcript'
|
||||
import { reformatBotMessage } from '@sourcegraph/cody-shared/src/chat/viewHelpers'
|
||||
import { CodebaseContext } from '@sourcegraph/cody-shared/src/codebase-context'
|
||||
import { Message as PromptMessage } from '@sourcegraph/cody-shared/src/sourcegraph-api'
|
||||
|
||||
import { intentDetector } from './services/sourcegraph-client'
|
||||
import { streamCompletions } from './services/stream-completions'
|
||||
import * as slackHelpers from './slack/helpers'
|
||||
import { interactionFromMessage } from './slack/message-interaction'
|
||||
import { SLACK_PREAMBLE } from './slack/preamble'
|
||||
|
||||
const IN_PROGRESS_MESSAGE = '...✍️'
|
||||
|
||||
/**
|
||||
* Handles human-generated messages in a Slack bot application.
|
||||
* Processes the messages, generates a prompt, and streams completions.
|
||||
*/
|
||||
export async function handleHumanMessage(event: AppMentionEvent, codebaseContext: CodebaseContext): Promise<void> {
|
||||
const channel = event.channel
|
||||
const thread_ts = slackHelpers.getEventTs(event)
|
||||
|
||||
// Restore transcript from the Slack thread
|
||||
const messages = await slackHelpers.getThreadMessages(channel, thread_ts)
|
||||
const transcript = await restoreTranscriptFromSlackThread(codebaseContext, messages)
|
||||
|
||||
// Send an in-progress message
|
||||
const response = await slackHelpers.postMessage(IN_PROGRESS_MESSAGE, channel, thread_ts)
|
||||
|
||||
// Generate a prompt and start completion streaming
|
||||
const prompt = await transcript.toPrompt(SLACK_PREAMBLE)
|
||||
console.log('PROMPT', prompt)
|
||||
startCompletionStreaming(prompt, channel, response?.ts)
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores a transcript from the given Slack thread messages.
|
||||
*/
|
||||
async function restoreTranscriptFromSlackThread(codebaseContext: CodebaseContext, messages: SlackReplyMessage[]) {
|
||||
const transcript = new Transcript()
|
||||
const mergedMessages = mergeSequentialUserMessages(messages)
|
||||
|
||||
for (const [index, message] of mergedMessages.entries()) {
|
||||
const interaction = await interactionFromMessage(
|
||||
message.human,
|
||||
intentDetector,
|
||||
// Fetch codebase context only for the last message
|
||||
index === mergedMessages.length - 1 ? codebaseContext : null
|
||||
)
|
||||
|
||||
transcript.addInteraction(interaction)
|
||||
|
||||
if (message.assistant?.text) {
|
||||
transcript.addAssistantResponse(message.assistant?.text)
|
||||
}
|
||||
}
|
||||
|
||||
return transcript
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts streaming completions for the given prompt.
|
||||
*/
|
||||
function startCompletionStreaming(
|
||||
promptMessages: PromptMessage[],
|
||||
channel: string,
|
||||
inProgressMessageTs?: string
|
||||
): void {
|
||||
streamCompletions(promptMessages, {
|
||||
onChange: text => {
|
||||
onBotMessageChange(reformatBotMessage(text, ''), channel, inProgressMessageTs)?.catch(console.error)
|
||||
},
|
||||
onComplete: () => {
|
||||
console.log('Streaming complete!')
|
||||
},
|
||||
onError: err => {
|
||||
console.error(err)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Throttled function to update the bot message when there is a change.
|
||||
* Ensures message updates are throttled to avoid exceeding Slack API rate limits.
|
||||
*/
|
||||
const onBotMessageChange = throttle(async (text: string, channel, inProgressMessageTs?: string) => {
|
||||
if (inProgressMessageTs) {
|
||||
await slackHelpers.updateMessage(channel, inProgressMessageTs, text)
|
||||
} else {
|
||||
console.error('The in-progress mesasge is not found!')
|
||||
}
|
||||
// Throttle message updates to keep Slack API rate limiter happy.
|
||||
}, 1000)
|
||||
|
||||
interface SlackInteraction {
|
||||
human: SlackReplyMessage
|
||||
assistant?: SlackReplyMessage
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges sequential user messages in a Slack thread to avoid missing important context.
|
||||
*/
|
||||
function mergeSequentialUserMessages(messages: SlackReplyMessage[]) {
|
||||
const mergedMessages: SlackInteraction[] = []
|
||||
|
||||
for (const message of messages) {
|
||||
const text = message.text?.replace(/<@[\dA-Z]+>/gm, '').trim()
|
||||
const lastInteraction = mergedMessages[mergedMessages.length - 1]
|
||||
const updatedMessage = { ...message, blocks: undefined, text }
|
||||
|
||||
if (!lastInteraction) {
|
||||
mergedMessages.push({ human: updatedMessage })
|
||||
continue
|
||||
}
|
||||
|
||||
if (message.bot_id) {
|
||||
if (!lastInteraction.assistant) {
|
||||
lastInteraction.assistant = updatedMessage
|
||||
}
|
||||
} else if (!lastInteraction.assistant) {
|
||||
lastInteraction.human.text = `${lastInteraction.human.text || ''}; ${text}`
|
||||
} else {
|
||||
mergedMessages.push({ human: updatedMessage })
|
||||
}
|
||||
}
|
||||
|
||||
return mergedMessages
|
||||
}
|
||||
43
client/cody-slack/src/services/codebase-context.ts
Normal file
43
client/cody-slack/src/services/codebase-context.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { memoize } from 'lodash'
|
||||
|
||||
import { CodebaseContext } from '@sourcegraph/cody-shared/src/codebase-context'
|
||||
import { SourcegraphEmbeddingsSearchClient } from '@sourcegraph/cody-shared/src/embeddings/client'
|
||||
import { KeywordContextFetcher } from '@sourcegraph/cody-shared/src/keyword-context'
|
||||
import { isError } from '@sourcegraph/cody-shared/src/utils'
|
||||
|
||||
import { sourcegraphClient } from './sourcegraph-client'
|
||||
|
||||
/**
|
||||
* Memoized function to get the repository ID for a given codebase.
|
||||
*/
|
||||
const getRepoId = memoize(async (codebase: string) => {
|
||||
const repoId = codebase ? await sourcegraphClient.getRepoId(codebase) : null
|
||||
|
||||
if (isError(repoId)) {
|
||||
const errorMessage =
|
||||
`Cody could not find the '${codebase}' repository on your Sourcegraph instance.\n` +
|
||||
'Please check that the repository exists and is entered correctly in the cody.codebase setting.'
|
||||
console.error(errorMessage)
|
||||
}
|
||||
|
||||
return repoId
|
||||
})
|
||||
|
||||
export async function createCodebaseContext(
|
||||
codebase: string,
|
||||
contextType: 'embeddings' | 'keyword' | 'none' | 'blended'
|
||||
) {
|
||||
const repoId = await getRepoId(codebase)
|
||||
const embeddingsSearch =
|
||||
repoId && !isError(repoId) ? new SourcegraphEmbeddingsSearchClient(sourcegraphClient, repoId) : null
|
||||
|
||||
const codebaseContext = new CodebaseContext(contextType, embeddingsSearch, new LocalKeywordContextFetcherMock())
|
||||
|
||||
return codebaseContext
|
||||
}
|
||||
|
||||
class LocalKeywordContextFetcherMock implements KeywordContextFetcher {
|
||||
public getContext() {
|
||||
return Promise.resolve([])
|
||||
}
|
||||
}
|
||||
85
client/cody-slack/src/services/openai-completions-client.ts
Normal file
85
client/cody-slack/src/services/openai-completions-client.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import { IncomingMessage } from 'http'
|
||||
|
||||
import { Configuration, OpenAIApi } from 'openai'
|
||||
|
||||
import { SourcegraphCompletionsClient } from '@sourcegraph/cody-shared/src/sourcegraph-api/completions/client'
|
||||
import {
|
||||
CompletionCallbacks,
|
||||
CompletionParameters,
|
||||
} from '@sourcegraph/cody-shared/src/sourcegraph-api/completions/types'
|
||||
|
||||
export class OpenAICompletionsClient extends SourcegraphCompletionsClient {
|
||||
private openai: OpenAIApi
|
||||
|
||||
constructor(
|
||||
protected apiKey: string,
|
||||
instanceUrl: string = '',
|
||||
protected accessToken: string = '',
|
||||
protected mode: 'development' | 'production' = 'production'
|
||||
) {
|
||||
super(instanceUrl, accessToken, mode)
|
||||
|
||||
const configuration = new Configuration({
|
||||
apiKey: this.apiKey,
|
||||
})
|
||||
this.openai = new OpenAIApi(configuration)
|
||||
}
|
||||
|
||||
public stream(params: CompletionParameters, cb: CompletionCallbacks) {
|
||||
this.openai
|
||||
.createChatCompletion(
|
||||
{
|
||||
model: 'gpt-3.5-turbo',
|
||||
messages: params.messages.map(message => {
|
||||
return {
|
||||
role: message.speaker === 'human' ? 'user' : 'assistant',
|
||||
content: message.text,
|
||||
}
|
||||
}),
|
||||
stream: true,
|
||||
},
|
||||
{ responseType: 'stream' }
|
||||
)
|
||||
.then(response => {
|
||||
const stream = response.data as unknown as IncomingMessage
|
||||
|
||||
let modelResponseText = ''
|
||||
|
||||
stream.on('data', (chunk: Buffer) => {
|
||||
// Split messames in the event stream.
|
||||
const payloads = chunk.toString().split('\n\n')
|
||||
|
||||
for (const payload of payloads) {
|
||||
if (payload.includes('[DONE]')) {
|
||||
return
|
||||
}
|
||||
|
||||
if (payload.startsWith('data:')) {
|
||||
const data = payload.replaceAll(/(\n)?^data:\s*/g, '') // in case there's multiline data event
|
||||
|
||||
try {
|
||||
const delta = JSON.parse(data.trim())
|
||||
const newTextChunk = delta.choices[0].delta?.content
|
||||
|
||||
if (newTextChunk) {
|
||||
modelResponseText += newTextChunk
|
||||
cb.onChange(modelResponseText)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(
|
||||
`Error with JSON.parse: ${chunk.toString()}\nPayload: ${payload};\nError: ${error}`
|
||||
)
|
||||
cb.onError(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
stream.on('error', e => cb.onError(e.message))
|
||||
stream.on('end', () => cb.onComplete())
|
||||
})
|
||||
.catch(console.error)
|
||||
|
||||
return () => {}
|
||||
}
|
||||
}
|
||||
13
client/cody-slack/src/services/sourcegraph-client.ts
Normal file
13
client/cody-slack/src/services/sourcegraph-client.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { SourcegraphIntentDetectorClient } from '@sourcegraph/cody-shared/src/intent-detector/client'
|
||||
import { SourcegraphGraphQLAPIClient } from '@sourcegraph/cody-shared/src/sourcegraph-api/graphql'
|
||||
|
||||
import { DEFAULT_APP_SETTINGS, ENVIRONMENT_CONFIG } from '../constants'
|
||||
|
||||
const { SOURCEGRAPH_ACCESS_TOKEN } = ENVIRONMENT_CONFIG
|
||||
|
||||
export const sourcegraphClient = new SourcegraphGraphQLAPIClient(
|
||||
DEFAULT_APP_SETTINGS.serverEndpoint,
|
||||
SOURCEGRAPH_ACCESS_TOKEN
|
||||
)
|
||||
|
||||
export const intentDetector = new SourcegraphIntentDetectorClient(sourcegraphClient)
|
||||
40
client/cody-slack/src/services/stream-completions.ts
Normal file
40
client/cody-slack/src/services/stream-completions.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { SOLUTION_TOKEN_LENGTH } from '@sourcegraph/cody-shared/src/prompt/constants'
|
||||
import { SourcegraphNodeCompletionsClient } from '@sourcegraph/cody-shared/src/sourcegraph-api/completions/nodeClient'
|
||||
import {
|
||||
CompletionParameters,
|
||||
CompletionCallbacks,
|
||||
Message,
|
||||
} from '@sourcegraph/cody-shared/src/sourcegraph-api/completions/types'
|
||||
|
||||
import { DEFAULT_APP_SETTINGS, ENVIRONMENT_CONFIG } from '../constants'
|
||||
|
||||
import { OpenAICompletionsClient } from './openai-completions-client'
|
||||
|
||||
const { SOURCEGRAPH_ACCESS_TOKEN } = ENVIRONMENT_CONFIG
|
||||
|
||||
const DEFAULT_CHAT_COMPLETION_PARAMETERS: Omit<CompletionParameters, 'messages'> = {
|
||||
temperature: 0.2,
|
||||
maxTokensToSample: SOLUTION_TOKEN_LENGTH,
|
||||
topK: -1,
|
||||
topP: -1,
|
||||
}
|
||||
|
||||
const completionsClient = getCompletionsClient()
|
||||
|
||||
export function streamCompletions(messages: Message[], cb: CompletionCallbacks) {
|
||||
return completionsClient.stream({ messages, ...DEFAULT_CHAT_COMPLETION_PARAMETERS }, cb)
|
||||
}
|
||||
|
||||
function getCompletionsClient() {
|
||||
const { OPENAI_API_KEY } = process.env
|
||||
|
||||
if (OPENAI_API_KEY) {
|
||||
return new OpenAICompletionsClient(OPENAI_API_KEY)
|
||||
}
|
||||
|
||||
return new SourcegraphNodeCompletionsClient(
|
||||
DEFAULT_APP_SETTINGS.serverEndpoint,
|
||||
SOURCEGRAPH_ACCESS_TOKEN,
|
||||
DEFAULT_APP_SETTINGS.debug
|
||||
)
|
||||
}
|
||||
55
client/cody-slack/src/slack/helpers.ts
Normal file
55
client/cody-slack/src/slack/helpers.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { KnownEventFromType, SlackEvent } from '@slack/bolt'
|
||||
import { ChatPostMessageResponse } from '@slack/web-api'
|
||||
|
||||
import { webClient } from './init'
|
||||
|
||||
export async function getThreadMessages(channel: string, thread_ts: string) {
|
||||
const result = await webClient.conversations.replies({
|
||||
channel,
|
||||
ts: thread_ts,
|
||||
})
|
||||
|
||||
return result?.messages || []
|
||||
}
|
||||
|
||||
export function getEventTs(event: KnownEventFromType<'app_mention'> | KnownEventFromType<'message'>) {
|
||||
if ('thread_ts' in event && event.thread_ts !== event.ts) {
|
||||
return event.thread_ts || event.ts
|
||||
}
|
||||
|
||||
return event.ts
|
||||
}
|
||||
|
||||
export const isBotEvent = (event: SlackEvent) => {
|
||||
return 'subtype' in event && event.subtype !== 'bot_message'
|
||||
}
|
||||
|
||||
export async function updateMessage(channel: string, messageTs: string, newText: string): Promise<void> {
|
||||
const response = await webClient.chat.update({
|
||||
channel,
|
||||
ts: messageTs, // The timestamp of the message you want to update.
|
||||
text: newText, // The new text for the updated message.
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error updating message: ${response.error}`)
|
||||
}
|
||||
}
|
||||
|
||||
export async function postMessage(
|
||||
message: string,
|
||||
channel: string,
|
||||
thread_ts: string
|
||||
): Promise<ChatPostMessageResponse | undefined> {
|
||||
const response = await webClient.chat.postMessage({
|
||||
channel,
|
||||
text: message,
|
||||
thread_ts, // Use the timestamp of the parent message to reply in the thread.
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Error sending message: ${response.error}`)
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
14
client/cody-slack/src/slack/init.ts
Normal file
14
client/cody-slack/src/slack/init.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { App } from '@slack/bolt'
|
||||
import { WebClient, LogLevel } from '@slack/web-api'
|
||||
|
||||
import { ENVIRONMENT_CONFIG } from '../constants'
|
||||
|
||||
// Initialize the Bolt.js app and the WebClient using environment variables.
|
||||
export const app = new App({
|
||||
appToken: ENVIRONMENT_CONFIG.SLACK_APP_TOKEN,
|
||||
token: ENVIRONMENT_CONFIG.SLACK_BOT_TOKEN,
|
||||
signingSecret: ENVIRONMENT_CONFIG.SLACK_SIGNING_SECRET,
|
||||
logLevel: LogLevel.INFO,
|
||||
})
|
||||
|
||||
export const webClient = new WebClient(ENVIRONMENT_CONFIG.SLACK_BOT_TOKEN)
|
||||
55
client/cody-slack/src/slack/message-interaction.ts
Normal file
55
client/cody-slack/src/slack/message-interaction.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { Message } from '@slack/web-api/dist/response/ChannelsRepliesResponse'
|
||||
|
||||
import { Interaction } from '@sourcegraph/cody-shared/src/chat/transcript/interaction'
|
||||
import { CodebaseContext } from '@sourcegraph/cody-shared/src/codebase-context'
|
||||
import { ContextMessage } from '@sourcegraph/cody-shared/src/codebase-context/messages'
|
||||
import { IntentDetector } from '@sourcegraph/cody-shared/src/intent-detector'
|
||||
import { MAX_HUMAN_INPUT_TOKENS } from '@sourcegraph/cody-shared/src/prompt/constants'
|
||||
import { truncateText } from '@sourcegraph/cody-shared/src/prompt/truncation'
|
||||
import { getShortTimestamp } from '@sourcegraph/cody-shared/src/timestamp'
|
||||
|
||||
export async function interactionFromMessage(
|
||||
message: Message,
|
||||
intentDetector: IntentDetector,
|
||||
codebaseContext: CodebaseContext | null
|
||||
): Promise<Interaction | null> {
|
||||
if (!message.text) {
|
||||
return Promise.resolve(null)
|
||||
}
|
||||
|
||||
const timestamp = getShortTimestamp()
|
||||
const textWithoutMentions = message.text?.replace(/<@[\dA-Z]+>/gm, '').trim()
|
||||
const text = truncateText(textWithoutMentions, MAX_HUMAN_INPUT_TOKENS)
|
||||
|
||||
const contextMessages =
|
||||
codebaseContext === null ? Promise.resolve([]) : getContextMessages(text, intentDetector, codebaseContext)
|
||||
|
||||
return Promise.resolve(
|
||||
new Interaction(
|
||||
{ speaker: 'human', text, displayText: text, timestamp },
|
||||
{ speaker: 'assistant', text: '', displayText: '', timestamp },
|
||||
contextMessages
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export async function getContextMessages(
|
||||
text: string,
|
||||
intentDetector: IntentDetector,
|
||||
codebaseContext: CodebaseContext
|
||||
): Promise<ContextMessage[]> {
|
||||
const contextMessages: ContextMessage[] = []
|
||||
|
||||
const isCodebaseContextRequired = await intentDetector.isCodebaseContextRequired(text)
|
||||
|
||||
if (isCodebaseContextRequired) {
|
||||
const codebaseContextMessages = await codebaseContext.getContextMessages(text, {
|
||||
numCodeResults: 8,
|
||||
numTextResults: 2,
|
||||
})
|
||||
|
||||
contextMessages.push(...codebaseContextMessages)
|
||||
}
|
||||
|
||||
return contextMessages
|
||||
}
|
||||
52
client/cody-slack/src/slack/preamble.ts
Normal file
52
client/cody-slack/src/slack/preamble.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { Message } from '@sourcegraph/cody-shared/src/sourcegraph-api'
|
||||
|
||||
import { DEFAULT_APP_SETTINGS } from '../constants'
|
||||
|
||||
const actions = `You are Cody, an AI-powered coding assistant created by Sourcegraph. You work inside a Slack workspace. You have access to the Slack thread conversation with all the replies. You perform the following actions:
|
||||
- Answer general programming questions.
|
||||
- Answer general questions about the Slack thread you're in.
|
||||
- Answer questions about the code that I have provided to you.
|
||||
- Generate code that matches a written description.
|
||||
- Explain what a section of code does.`
|
||||
|
||||
const rules = `In your responses, obey the following rules:
|
||||
- Be as brief and concise as possible without losing clarity.
|
||||
- The current Slack thread is the same as the conversation you're having with the user. Use this information to answer questions.
|
||||
- All code snippets have to be markdown-formatted without that language specifier, and placed in-between triple backticks like this \`\`\`.
|
||||
- Answer questions only if you know the answer or can make a well-informed guess. Otherwise, tell me you don't know and what context I need to provide you for you to answer the question.
|
||||
- Only reference file names or URLs if you are sure they exist.`
|
||||
|
||||
const answer = `Understood. I am Cody, an AI assistant made by Sourcegraph to help with programming tasks and assist in Slack conversations.
|
||||
I work inside a Slack workspace. I have access have access to the currently active Slack thread conversation with all the replies.
|
||||
I will answer questions, explain code, and generate code as concisely and clearly as possible.
|
||||
My responses will be formatted using Markdown syntax for code blocks without language specifiers.
|
||||
I will acknowledge when I don't know an answer or need more context. I will use the Slack thread conversation history to answer your questions.`
|
||||
|
||||
function getSlackPreamble(codebase: string): Message[] {
|
||||
const preamble = [actions, rules]
|
||||
const preambleResponse = [answer]
|
||||
|
||||
if (codebase) {
|
||||
const codebasePreamble =
|
||||
`You have access to the \`${codebase}\` repository. You are able to answer questions about the \`${codebase}\` repository. ` +
|
||||
`I will provide the relevant code snippets from the \`${codebase}\` repository when necessary to answer my questions.`
|
||||
|
||||
preamble.push(codebasePreamble)
|
||||
preambleResponse.push(
|
||||
`I have access to the \`${codebase}\` repository and can answer questions about its files.`
|
||||
)
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
speaker: 'human',
|
||||
text: preamble.join('\n\n'),
|
||||
},
|
||||
{
|
||||
speaker: 'assistant',
|
||||
text: preambleResponse.join('\n'),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
export const SLACK_PREAMBLE = getSlackPreamble(DEFAULT_APP_SETTINGS.codebase)
|
||||
20
client/cody-slack/tsconfig.json
Normal file
20
client/cody-slack/tsconfig.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"sourceRoot": "src",
|
||||
"rootDir": ".",
|
||||
"outDir": "./out",
|
||||
"baseUrl": "./src",
|
||||
},
|
||||
"include": ["src", "package.json", ".eslintrc.js", "jest.config.js"],
|
||||
"exclude": ["out", "dist"],
|
||||
"references": [
|
||||
{
|
||||
"path": "../cody-shared",
|
||||
},
|
||||
{
|
||||
"path": "../common",
|
||||
},
|
||||
],
|
||||
}
|
||||
@ -100,6 +100,7 @@ Available commands in `sg.config.yaml`:
|
||||
* codeintel-executor
|
||||
* codeintel-executor-firecracker
|
||||
* codeintel-worker
|
||||
* cody-slack: Start Cody-Slack locally server locally
|
||||
* debug-env: Debug env vars
|
||||
* docsite: Docsite instance serving the docs
|
||||
* embeddings
|
||||
|
||||
247
pnpm-lock.yaml
247
pnpm-lock.yaml
@ -941,6 +941,20 @@ importers:
|
||||
dependencies:
|
||||
'@sourcegraph/common': link:../common
|
||||
|
||||
client/cody-slack:
|
||||
specifiers:
|
||||
'@slack/bolt': ^3.12.2
|
||||
'@slack/web-api': ^6.8.1
|
||||
'@sourcegraph/cody-shared': workspace:*
|
||||
'@sourcegraph/common': workspace:*
|
||||
openai: ^3.2.1
|
||||
dependencies:
|
||||
'@slack/bolt': 3.12.2
|
||||
'@slack/web-api': 6.8.1
|
||||
'@sourcegraph/cody-shared': link:../cody-shared
|
||||
'@sourcegraph/common': link:../common
|
||||
openai: 3.2.1
|
||||
|
||||
client/cody-ui:
|
||||
specifiers:
|
||||
'@sourcegraph/cody-shared': workspace:*
|
||||
@ -3231,7 +3245,6 @@ packages:
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-arm64/0.16.17:
|
||||
@ -3257,7 +3270,6 @@ packages:
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-x64/0.16.17:
|
||||
@ -3283,7 +3295,6 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/darwin-arm64/0.16.17:
|
||||
@ -3309,7 +3320,6 @@ packages:
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/darwin-x64/0.16.17:
|
||||
@ -3335,7 +3345,6 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/freebsd-arm64/0.16.17:
|
||||
@ -3361,7 +3370,6 @@ packages:
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/freebsd-x64/0.16.17:
|
||||
@ -3387,7 +3395,6 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-arm/0.16.17:
|
||||
@ -3413,7 +3420,6 @@ packages:
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-arm64/0.16.17:
|
||||
@ -3439,7 +3445,6 @@ packages:
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-ia32/0.16.17:
|
||||
@ -3465,7 +3470,6 @@ packages:
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-loong64/0.16.17:
|
||||
@ -3491,7 +3495,6 @@ packages:
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-mips64el/0.16.17:
|
||||
@ -3517,7 +3520,6 @@ packages:
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-ppc64/0.16.17:
|
||||
@ -3543,7 +3545,6 @@ packages:
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-riscv64/0.16.17:
|
||||
@ -3569,7 +3570,6 @@ packages:
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-s390x/0.16.17:
|
||||
@ -3595,7 +3595,6 @@ packages:
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-x64/0.16.17:
|
||||
@ -3621,7 +3620,6 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/netbsd-x64/0.16.17:
|
||||
@ -3647,7 +3645,6 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/openbsd-x64/0.16.17:
|
||||
@ -3673,7 +3670,6 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/sunos-x64/0.16.17:
|
||||
@ -3699,7 +3695,6 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-arm64/0.16.17:
|
||||
@ -3725,7 +3720,6 @@ packages:
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-ia32/0.16.17:
|
||||
@ -3751,7 +3745,6 @@ packages:
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-x64/0.16.17:
|
||||
@ -3777,7 +3770,6 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/@eslint/eslintrc/1.4.1:
|
||||
@ -6828,6 +6820,32 @@ packages:
|
||||
resolution: {integrity: sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==}
|
||||
dev: true
|
||||
|
||||
/@slack/bolt/3.12.2:
|
||||
resolution: {integrity: sha512-Rv5apx14Nx25ho7MHigZcmYG+P/TzKB4MEdY/UDM7ntCCmTBdRd5d+teERmGPNalFjz/tEfQ5bw+Z8zZjHIOXA==}
|
||||
engines: {node: '>=12.13.0', npm: '>=6.12.0'}
|
||||
dependencies:
|
||||
'@slack/logger': 3.0.0
|
||||
'@slack/oauth': 2.6.0
|
||||
'@slack/socket-mode': 1.3.2
|
||||
'@slack/types': 2.8.0
|
||||
'@slack/web-api': 6.8.1
|
||||
'@types/express': 4.17.11
|
||||
'@types/node': 18.11.8
|
||||
'@types/promise.allsettled': 1.0.3
|
||||
'@types/tsscmp': 1.0.0
|
||||
axios: 0.26.1
|
||||
express: 4.18.2
|
||||
please-upgrade-node: 3.2.0
|
||||
promise.allsettled: 1.0.2
|
||||
raw-body: 2.5.1
|
||||
tsscmp: 1.0.6
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- debug
|
||||
- supports-color
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
/@slack/logger/2.0.0:
|
||||
resolution: {integrity: sha512-OkIJpiU2fz6HOJujhlhfIGrc8hB4ibqtf7nnbJQDerG0BqwZCfmgtK5sWzZ0TkXVRBKD5MpLrTmCYyMxoMCgPw==}
|
||||
engines: {node: '>= 8.9.0', npm: '>= 5.5.1'}
|
||||
@ -6835,11 +6853,57 @@ packages:
|
||||
'@types/node': 13.13.5
|
||||
dev: true
|
||||
|
||||
/@slack/logger/3.0.0:
|
||||
resolution: {integrity: sha512-DTuBFbqu4gGfajREEMrkq5jBhcnskinhr4+AnfJEk48zhVeEv3XnUKGIX98B74kxhYsIMfApGGySTn7V3b5yBA==}
|
||||
engines: {node: '>= 12.13.0', npm: '>= 6.12.0'}
|
||||
dependencies:
|
||||
'@types/node': 13.13.5
|
||||
dev: false
|
||||
|
||||
/@slack/oauth/2.6.0:
|
||||
resolution: {integrity: sha512-t75jfYUoVVq4x9TnJrNn5VQRfr9n/3Fvuq3M6gf3URmKCvm/kQyZGp0Ff8AK/dzdYYWKDfSVD9GQImhF578MZA==}
|
||||
engines: {node: '>=12.13.0', npm: '>=6.12.0'}
|
||||
dependencies:
|
||||
'@slack/logger': 3.0.0
|
||||
'@slack/web-api': 6.8.1
|
||||
'@types/jsonwebtoken': 8.5.9
|
||||
'@types/node': 13.13.5
|
||||
jsonwebtoken: 9.0.0
|
||||
lodash.isstring: 4.0.1
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: false
|
||||
|
||||
/@slack/socket-mode/1.3.2:
|
||||
resolution: {integrity: sha512-6LiwYE6k4DNbnctZZSLfERiOzWngAvXogxQEYzUkxeZgh2GC6EdmRq6OEbZXOBe71/K66YVx05VfR7B4b1ScTQ==}
|
||||
engines: {node: '>=12.13.0', npm: '>=6.12.0'}
|
||||
dependencies:
|
||||
'@slack/logger': 3.0.0
|
||||
'@slack/web-api': 6.8.1
|
||||
'@types/node': 13.13.5
|
||||
'@types/p-queue': 2.3.2
|
||||
'@types/ws': 7.4.7
|
||||
eventemitter3: 3.1.2
|
||||
finity: 0.5.4
|
||||
p-cancelable: 1.1.0
|
||||
p-queue: 2.4.2
|
||||
ws: 7.5.9
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- debug
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
/@slack/types/1.7.0:
|
||||
resolution: {integrity: sha512-aigLPmTO513JxeFyeII/74y+S5jU39tabDWPsZyMHJWCYqK3vCkRvV73NL+Ay+Tq5RC2NgSmkedk1wvQJ6oXLg==}
|
||||
engines: {node: '>= 8.9.0', npm: '>= 5.5.1'}
|
||||
dev: true
|
||||
|
||||
/@slack/types/2.8.0:
|
||||
resolution: {integrity: sha512-ghdfZSF0b4NC9ckBA8QnQgC9DJw2ZceDq0BIjjRSv6XAZBXJdWgxIsYz0TYnWSiqsKZGH2ZXbj9jYABZdH3OSQ==}
|
||||
engines: {node: '>= 12.13.0', npm: '>= 6.12.0'}
|
||||
dev: false
|
||||
|
||||
/@slack/web-api/5.15.0:
|
||||
resolution: {integrity: sha512-tjQ8Zqv/Fmj9SOL9yIEd7IpTiKfKHi9DKAkfRVeotoX0clMr3SqQtBqO+KZMX27gm7dmgJsQaDKlILyzdCO+IA==}
|
||||
engines: {node: '>= 8.9.0', npm: '>= 5.5.1'}
|
||||
@ -6858,6 +6922,25 @@ packages:
|
||||
- debug
|
||||
dev: true
|
||||
|
||||
/@slack/web-api/6.8.1:
|
||||
resolution: {integrity: sha512-eMPk2S99S613gcu7odSw/LV+Qxr8A+RXvBD0GYW510wJuTERiTjP5TgCsH8X09+lxSumbDE88wvWbuFuvGa74g==}
|
||||
engines: {node: '>= 12.13.0', npm: '>= 6.12.0'}
|
||||
dependencies:
|
||||
'@slack/logger': 3.0.0
|
||||
'@slack/types': 2.8.0
|
||||
'@types/is-stream': 1.1.0
|
||||
'@types/node': 13.13.5
|
||||
axios: 0.27.2
|
||||
eventemitter3: 3.1.2
|
||||
form-data: 2.5.1
|
||||
is-electron: 2.2.0
|
||||
is-stream: 1.1.0
|
||||
p-queue: 6.6.2
|
||||
p-retry: 4.6.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: false
|
||||
|
||||
/@snyk/dep-graph/2.6.0:
|
||||
resolution: {integrity: sha512-9NPk7cTvDNA90NyNQvh87LYKgkCoD67i+FGdRpwA0/CL59RRY7cG37RTFe++Y3ZALxpYK1sLNzU+yeB7vzVhqQ==}
|
||||
engines: {node: '>=10'}
|
||||
@ -9083,7 +9166,6 @@ packages:
|
||||
resolution: {integrity: sha512-jkZatu4QVbR60mpIzjINmtS1ZF4a/FqdTUTBeQDVOQ2PYyidtwFKr0B5G6ERukKwliq+7mIXvxyppwzG5EgRYg==}
|
||||
dependencies:
|
||||
'@types/node': 13.13.5
|
||||
dev: true
|
||||
|
||||
/@types/isomorphic-fetch/0.0.36:
|
||||
resolution: {integrity: sha512-ulw4d+vW1HKn4oErSmNN2HYEcHGq0N1C5exlrMM0CRqX1UUpFhGb5lwiom5j9KN3LBJJDLRmYIZz1ghm7FIzZw==}
|
||||
@ -9182,7 +9264,6 @@ packages:
|
||||
resolution: {integrity: sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==}
|
||||
dependencies:
|
||||
'@types/node': 13.13.5
|
||||
dev: true
|
||||
|
||||
/@types/keyv/3.1.4:
|
||||
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
|
||||
@ -9270,6 +9351,10 @@ packages:
|
||||
/@types/node/16.18.11:
|
||||
resolution: {integrity: sha512-3oJbGBUWuS6ahSnEq1eN2XrCyf4YsWI8OyCvo7c64zQJNplk3mO84t53o8lfTk+2ji59g5ycfc6qQ3fdHliHuA==}
|
||||
|
||||
/@types/node/18.11.8:
|
||||
resolution: {integrity: sha512-uGwPWlE0Hj972KkHtCDVwZ8O39GmyjfMane1Z3GUBGGnkZ2USDq7SxLpVIiIHpweY9DS0QTDH0Nw7RNBsAAZ5A==}
|
||||
dev: false
|
||||
|
||||
/@types/normalize-package-data/2.4.0:
|
||||
resolution: {integrity: sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==}
|
||||
dev: true
|
||||
@ -9277,6 +9362,10 @@ packages:
|
||||
/@types/npmlog/4.1.2:
|
||||
resolution: {integrity: sha512-4QQmOF5KlwfxJ5IGXFIudkeLCdMABz03RcUXu+LCb24zmln8QW6aDjuGl4d4XPVLf2j+FnjelHTP7dvceAFbhA==}
|
||||
|
||||
/@types/p-queue/2.3.2:
|
||||
resolution: {integrity: sha512-eKAv5Ql6k78dh3ULCsSBxX6bFNuGjTmof5Q/T6PiECDq0Yf8IIn46jCyp3RJvCi8owaEmm3DZH1PEImjBMd/vQ==}
|
||||
dev: false
|
||||
|
||||
/@types/parse-json/4.0.0:
|
||||
resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==}
|
||||
|
||||
@ -9328,6 +9417,10 @@ packages:
|
||||
resolution: {integrity: sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==}
|
||||
dev: true
|
||||
|
||||
/@types/promise.allsettled/1.0.3:
|
||||
resolution: {integrity: sha512-b/IFHHTkYkTqu41IH9UtpICwqrpKj2oNlb4KHPzFQDMiz+h1BgAeATeO0/XTph4+UkH9W2U0E4B4j64KWOovag==}
|
||||
dev: false
|
||||
|
||||
/@types/prop-types/15.7.5:
|
||||
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
|
||||
|
||||
@ -9568,6 +9661,10 @@ packages:
|
||||
resolution: {integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==}
|
||||
dev: true
|
||||
|
||||
/@types/tsscmp/1.0.0:
|
||||
resolution: {integrity: sha512-rj18XR6c4Ohds86Lq8MI1NMRrXes4eLo4H06e5bJyKucE1rXGsfBBbFGD2oDC+DSufQCpnU3TTW7QAiwLx+7Yw==}
|
||||
dev: false
|
||||
|
||||
/@types/undertaker-registry/1.0.1:
|
||||
resolution: {integrity: sha512-Z4TYuEKn9+RbNVk1Ll2SS4x1JeLHecolIbM/a8gveaHsW0Hr+RQMraZACwTO2VD7JvepgA6UO1A1VrbktQrIbQ==}
|
||||
dev: true
|
||||
@ -9646,6 +9743,12 @@ packages:
|
||||
- webpack-cli
|
||||
dev: true
|
||||
|
||||
/@types/ws/7.4.7:
|
||||
resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==}
|
||||
dependencies:
|
||||
'@types/node': 13.13.5
|
||||
dev: false
|
||||
|
||||
/@types/ws/8.5.3:
|
||||
resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==}
|
||||
dependencies:
|
||||
@ -11028,7 +11131,6 @@ packages:
|
||||
es-abstract: 1.21.1
|
||||
es-array-method-boxes-properly: 1.0.0
|
||||
is-string: 1.0.7
|
||||
dev: true
|
||||
|
||||
/array.prototype.reduce/1.0.4:
|
||||
resolution: {integrity: sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==}
|
||||
@ -11207,6 +11309,15 @@ packages:
|
||||
- debug
|
||||
dev: false
|
||||
|
||||
/axios/0.27.2:
|
||||
resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.1
|
||||
form-data: 4.0.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: false
|
||||
|
||||
/axobject-query/2.2.0:
|
||||
resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==}
|
||||
dev: true
|
||||
@ -11775,8 +11886,7 @@ packages:
|
||||
dev: true
|
||||
|
||||
/buffer-equal-constant-time/1.0.1:
|
||||
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
|
||||
dev: true
|
||||
resolution: {integrity: sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=}
|
||||
|
||||
/buffer-equal/1.0.0:
|
||||
resolution: {integrity: sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==}
|
||||
@ -13210,7 +13320,7 @@ packages:
|
||||
postcss-modules-values: 4.0.0_postcss@8.4.21
|
||||
postcss-value-parser: 4.2.0
|
||||
semver: 7.3.8
|
||||
webpack: 5.75.0_pdcrf7mb3dfag2zju4x4octu4a
|
||||
webpack: 5.75.0_esbuild@0.17.8
|
||||
|
||||
/css-minimizer-webpack-plugin/4.2.2_zj7shrtzhjuywytipisjis56au:
|
||||
resolution: {integrity: sha512-s3Of/4jKfw1Hj9CxEO1E5oXhQAxlayuHO2y/ML+C6I9sQ7FdzfEV6QgMLN3vI+qFsjJGIAFLKtQK7t8BOXAIyA==}
|
||||
@ -14610,10 +14720,9 @@ packages:
|
||||
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
dev: true
|
||||
|
||||
/ee-first/1.1.1:
|
||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||
resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=}
|
||||
|
||||
/electron-to-chromium/1.4.284:
|
||||
resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==}
|
||||
@ -14815,7 +14924,6 @@ packages:
|
||||
|
||||
/es-array-method-boxes-properly/1.0.0:
|
||||
resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==}
|
||||
dev: true
|
||||
|
||||
/es-get-iterator/1.1.0:
|
||||
resolution: {integrity: sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==}
|
||||
@ -14827,7 +14935,6 @@ packages:
|
||||
is-set: 2.0.1
|
||||
is-string: 1.0.7
|
||||
isarray: 2.0.5
|
||||
dev: true
|
||||
|
||||
/es-module-lexer/0.9.3:
|
||||
resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==}
|
||||
@ -14999,7 +15106,6 @@ packages:
|
||||
'@esbuild/win32-arm64': 0.17.8
|
||||
'@esbuild/win32-ia32': 0.17.8
|
||||
'@esbuild/win32-x64': 0.17.8
|
||||
dev: false
|
||||
|
||||
/escalade/3.1.1:
|
||||
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
||||
@ -15508,7 +15614,6 @@ packages:
|
||||
|
||||
/eventemitter3/3.1.2:
|
||||
resolution: {integrity: sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==}
|
||||
dev: true
|
||||
|
||||
/eventemitter3/4.0.7:
|
||||
resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
|
||||
@ -16079,6 +16184,10 @@ packages:
|
||||
parse-filepath: 1.0.2
|
||||
dev: true
|
||||
|
||||
/finity/0.5.4:
|
||||
resolution: {integrity: sha512-3l+5/1tuw616Lgb0QBimxfdd2TqaDGpfCBpfX6EqtFmqUV3FtQnVEX4Aa62DagYEqnsTIjZcTfbq9msDbXYgyA==}
|
||||
dev: false
|
||||
|
||||
/flagged-respawn/1.0.0:
|
||||
resolution: {integrity: sha512-uEIeQj2Z4a7Jzpb682FYsKc4YWHKaykTndikWrRtoWhOc1w3/97An5RcLhwBSq7phxokzK5kFHEKRKT0raGgTg==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
@ -16225,7 +16334,6 @@ packages:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.35
|
||||
dev: true
|
||||
|
||||
/form-data/3.0.0:
|
||||
resolution: {integrity: sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==}
|
||||
@ -16376,7 +16484,7 @@ packages:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
inherits: 2.0.4
|
||||
mkdirp: 0.5.5
|
||||
mkdirp: 0.5.6
|
||||
rimraf: 2.6.3
|
||||
dev: true
|
||||
|
||||
@ -18169,6 +18277,10 @@ packages:
|
||||
is-window: 1.0.2
|
||||
dev: true
|
||||
|
||||
/is-electron/2.2.0:
|
||||
resolution: {integrity: sha512-SpMppC2XR3YdxSzczXReBjqs2zGscWQpBIKqwXYBFic0ERaxNVgwLCHwOLZeESfdJQjX0RDvrJ1lBXX2ij+G1Q==}
|
||||
dev: false
|
||||
|
||||
/is-extendable/0.1.1:
|
||||
resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -18265,7 +18377,6 @@ packages:
|
||||
|
||||
/is-map/2.0.1:
|
||||
resolution: {integrity: sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==}
|
||||
dev: true
|
||||
|
||||
/is-negated-glob/1.0.0:
|
||||
resolution: {integrity: sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==}
|
||||
@ -18402,7 +18513,6 @@ packages:
|
||||
|
||||
/is-set/2.0.1:
|
||||
resolution: {integrity: sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==}
|
||||
dev: true
|
||||
|
||||
/is-shared-array-buffer/1.0.2:
|
||||
resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==}
|
||||
@ -18517,7 +18627,6 @@ packages:
|
||||
|
||||
/isarray/2.0.5:
|
||||
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
|
||||
dev: true
|
||||
|
||||
/isexe/2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
@ -18650,14 +18759,12 @@ packages:
|
||||
|
||||
/iterate-iterator/1.0.1:
|
||||
resolution: {integrity: sha512-3Q6tudGN05kbkDQDI4CqjaBf4qf85w6W6GnuZDtUVYwKgtC1q8yxYX7CZed7N+tLzQqS6roujWvszf13T+n9aw==}
|
||||
dev: true
|
||||
|
||||
/iterate-value/1.0.2:
|
||||
resolution: {integrity: sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==}
|
||||
dependencies:
|
||||
es-get-iterator: 1.1.0
|
||||
iterate-iterator: 1.0.1
|
||||
dev: true
|
||||
|
||||
/its-fine/1.1.0_react@18.1.0:
|
||||
resolution: {integrity: sha512-nEoEt5EYSed1mmvwCRv3l1+6T7pyu4ltyBihzPjUtaSWhFhUPU/c7xkPDIutTh8FeIv0F1F5wOFYI8a2s5rlBA==}
|
||||
@ -18735,7 +18842,7 @@ packages:
|
||||
jest-util: 28.1.3
|
||||
jest-validate: 28.1.3
|
||||
prompts: 2.4.2
|
||||
yargs: 17.6.2
|
||||
yargs: 17.7.1
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- supports-color
|
||||
@ -19801,6 +19908,16 @@ packages:
|
||||
semver: 5.7.1
|
||||
dev: true
|
||||
|
||||
/jsonwebtoken/9.0.0:
|
||||
resolution: {integrity: sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==}
|
||||
engines: {node: '>=12', npm: '>=6'}
|
||||
dependencies:
|
||||
jws: 3.2.2
|
||||
lodash: 4.17.21
|
||||
ms: 2.1.3
|
||||
semver: 7.3.8
|
||||
dev: false
|
||||
|
||||
/jsx-ast-utils/3.3.0:
|
||||
resolution: {integrity: sha512-XzO9luP6L0xkxwhIJMTJQpZo/eeN60K08jHdexfD569AGxeNug6UketeHXEhROoM8aR7EcUoOQmIhcJQjcuq8Q==}
|
||||
engines: {node: '>=4.0'}
|
||||
@ -19832,14 +19949,12 @@ packages:
|
||||
buffer-equal-constant-time: 1.0.1
|
||||
ecdsa-sig-formatter: 1.0.11
|
||||
safe-buffer: 5.2.1
|
||||
dev: true
|
||||
|
||||
/jws/3.2.2:
|
||||
resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==}
|
||||
dependencies:
|
||||
jwa: 1.4.1
|
||||
safe-buffer: 5.2.1
|
||||
dev: true
|
||||
|
||||
/keytar/7.9.0:
|
||||
resolution: {integrity: sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==}
|
||||
@ -20309,7 +20424,6 @@ packages:
|
||||
|
||||
/lodash.isstring/4.0.1:
|
||||
resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==}
|
||||
dev: true
|
||||
|
||||
/lodash.isundefined/3.0.1:
|
||||
resolution: {integrity: sha512-MXB1is3s899/cD8jheYYE2V9qTHwKvt+npCwpD+1Sxm3Q3cECXCiYHjeHWXNwr6Q0SOBPrYUDxendrO6goVTEA==}
|
||||
@ -20687,7 +20801,7 @@ packages:
|
||||
resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==}
|
||||
|
||||
/media-typer/0.3.0:
|
||||
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
|
||||
resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
/mem/4.3.0:
|
||||
@ -21371,6 +21485,7 @@ packages:
|
||||
|
||||
/minimist/1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
dev: true
|
||||
|
||||
/minipass-collect/1.0.2:
|
||||
resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==}
|
||||
@ -21437,7 +21552,7 @@ packages:
|
||||
resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
minimist: 1.2.8
|
||||
minimist: 1.2.6
|
||||
|
||||
/mkdirp/1.0.4:
|
||||
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
|
||||
@ -22305,7 +22420,6 @@ packages:
|
||||
/p-cancelable/1.1.0:
|
||||
resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/p-cancelable/2.0.0:
|
||||
resolution: {integrity: sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==}
|
||||
@ -22400,13 +22514,17 @@ packages:
|
||||
aggregate-error: 3.1.0
|
||||
dev: true
|
||||
|
||||
/p-queue/2.4.2:
|
||||
resolution: {integrity: sha512-n8/y+yDJwBjoLQe1GSJbbaYQLTI7QHNZI2+rpmCDbe++WLf9HC3gf6iqj5yfPAV71W4UF3ql5W1+UBPXoXTxng==}
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
|
||||
/p-queue/6.6.2:
|
||||
resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
eventemitter3: 4.0.7
|
||||
p-timeout: 3.2.0
|
||||
dev: true
|
||||
|
||||
/p-retry/4.6.0:
|
||||
resolution: {integrity: sha512-SAHbQEwg3X5DRNaLmWjT+DlGc93ba5i+aP3QLfVNDncQEQO4xjbYW4N/lcVTSuP0aJietGfx2t94dJLzfBMpXw==}
|
||||
@ -22420,7 +22538,6 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
p-finally: 1.0.0
|
||||
dev: true
|
||||
|
||||
/p-timeout/4.1.0:
|
||||
resolution: {integrity: sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw==}
|
||||
@ -22784,6 +22901,12 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/please-upgrade-node/3.2.0:
|
||||
resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==}
|
||||
dependencies:
|
||||
semver-compare: 1.0.0
|
||||
dev: false
|
||||
|
||||
/plur/4.0.0:
|
||||
resolution: {integrity: sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==}
|
||||
engines: {node: '>=10'}
|
||||
@ -23029,7 +23152,7 @@ packages:
|
||||
klona: 2.0.5
|
||||
postcss: 8.4.21
|
||||
semver: 7.3.8
|
||||
webpack: 5.75.0_pdcrf7mb3dfag2zju4x4octu4a
|
||||
webpack: 5.75.0_esbuild@0.17.8
|
||||
|
||||
/postcss-media-query-parser/0.2.3:
|
||||
resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==}
|
||||
@ -23623,7 +23746,6 @@ packages:
|
||||
es-abstract: 1.21.1
|
||||
function-bind: 1.1.1
|
||||
iterate-value: 1.0.2
|
||||
dev: true
|
||||
|
||||
/promise.prototype.finally/3.1.0:
|
||||
resolution: {integrity: sha512-7p/K2f6dI+dM8yjRQEGrTQs5hTQixUAdOGpMEA3+pVxpX5oHKRSKAXyLw9Q9HUWDTdwtoo39dSHGQtN90HcEwQ==}
|
||||
@ -25263,7 +25385,7 @@ packages:
|
||||
klona: 2.0.5
|
||||
neo-async: 2.6.2
|
||||
sass: 1.32.4
|
||||
webpack: 5.75.0_pdcrf7mb3dfag2zju4x4octu4a
|
||||
webpack: 5.75.0_esbuild@0.17.8
|
||||
|
||||
/sass/1.32.4:
|
||||
resolution: {integrity: sha512-N0BT0PI/t3+gD8jKa83zJJUb7ssfQnRRfqN+GIErokW6U4guBpfYl8qYB+OFLEho+QvnV5ZH1R9qhUC/Z2Ch9w==}
|
||||
@ -25358,6 +25480,10 @@ packages:
|
||||
dependencies:
|
||||
node-forge: 1.3.1
|
||||
|
||||
/semver-compare/1.0.0:
|
||||
resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==}
|
||||
dev: false
|
||||
|
||||
/semver-diff/2.1.0:
|
||||
resolution: {integrity: sha512-gL8F8L4ORwsS0+iQ34yCYv///jsOq0ZL7WP55d1HnJ32o7tyFYEFQZQA22mrLIacZdU6xecaBBZ+uEiffGNyXw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -26461,7 +26587,7 @@ packages:
|
||||
peerDependencies:
|
||||
webpack: ^5.0.0
|
||||
dependencies:
|
||||
webpack: 5.75.0_pdcrf7mb3dfag2zju4x4octu4a
|
||||
webpack: 5.75.0_esbuild@0.17.8
|
||||
|
||||
/style-mod/4.0.0:
|
||||
resolution: {integrity: sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw==}
|
||||
@ -27006,7 +27132,6 @@ packages:
|
||||
serialize-javascript: 6.0.0
|
||||
terser: 5.16.1
|
||||
webpack: 5.75.0_esbuild@0.17.8
|
||||
dev: false
|
||||
|
||||
/terser-webpack-plugin/5.3.6_zj7shrtzhjuywytipisjis56au:
|
||||
resolution: {integrity: sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==}
|
||||
@ -27429,6 +27554,11 @@ packages:
|
||||
/tslib/2.1.0:
|
||||
resolution: {integrity: sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==}
|
||||
|
||||
/tsscmp/1.0.6:
|
||||
resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==}
|
||||
engines: {node: '>=0.6.x'}
|
||||
dev: false
|
||||
|
||||
/tsutils-etc/1.4.1_o4lkiqkygxao4n37kchtvzdmeq:
|
||||
resolution: {integrity: sha512-6UPYgc7OXcIW5tFxlsZF3OVSBvDInl/BkS3Xsu64YITXk7WrnWTVByKWPCThFDBp5gl5IGHOzGMdQuDCE7OL4g==}
|
||||
hasBin: true
|
||||
@ -27439,7 +27569,7 @@ packages:
|
||||
'@types/yargs': 17.0.16
|
||||
tsutils: 3.21.0_typescript@5.0.2
|
||||
typescript: 5.0.2
|
||||
yargs: 17.6.2
|
||||
yargs: 17.7.1
|
||||
dev: true
|
||||
|
||||
/tsutils/3.21.0_typescript@5.0.2:
|
||||
@ -28625,7 +28755,7 @@ packages:
|
||||
dependencies:
|
||||
memory-fs: 0.4.1
|
||||
mime: 2.6.0
|
||||
mkdirp: 0.5.5
|
||||
mkdirp: 0.5.6
|
||||
range-parser: 1.2.1
|
||||
webpack: 5.75.0_pdcrf7mb3dfag2zju4x4octu4a
|
||||
webpack-log: 2.0.0
|
||||
@ -28824,7 +28954,6 @@ packages:
|
||||
- '@swc/core'
|
||||
- esbuild
|
||||
- uglify-js
|
||||
dev: false
|
||||
|
||||
/webpack/5.75.0_pdcrf7mb3dfag2zju4x4octu4a:
|
||||
resolution: {integrity: sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==}
|
||||
@ -29323,7 +29452,6 @@ packages:
|
||||
/y18n/5.0.8:
|
||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||
engines: {node: '>=10'}
|
||||
dev: false
|
||||
|
||||
/yallist/2.1.2:
|
||||
resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}
|
||||
@ -29479,7 +29607,6 @@ packages:
|
||||
string-width: 4.2.3
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 21.1.1
|
||||
dev: false
|
||||
|
||||
/yargs/7.1.0:
|
||||
resolution: {integrity: sha512-JHLTJJ5uqdt0peYp5mHzmSNV4uHXWphgSlKk5jg3sY5XYPTBw0hzw0SDNnYISn7pAXeAv5pKT4CNY+EcCTptBg==}
|
||||
|
||||
@ -452,6 +452,15 @@ commands:
|
||||
INTEGRATION_TESTS: true
|
||||
NODE_ENV: production
|
||||
|
||||
cody-slack:
|
||||
description: Start Cody-Slack locally server locally
|
||||
cmd: pnpm --filter @sourcegraph/cody-slack run start
|
||||
env:
|
||||
SLACK_APP_TOKEN: XXX
|
||||
SLACK_SIGNING_SECRET: XXX
|
||||
SLACK_BOT_TOKEN: XXX
|
||||
SOURCEGRAPH_ACCESS_TOKEN: XXX
|
||||
|
||||
docsite:
|
||||
description: Docsite instance serving the docs
|
||||
cmd: .bin/docsite_${DOCSITE_VERSION} -config doc/docsite.json serve -http=localhost:5080
|
||||
|
||||
Loading…
Reference in New Issue
Block a user