@chnxthr/knowledge-mcp 0.0.0-stage โ 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +37 -2
- package/dist/bootstrap.d.ts +1 -0
- package/dist/bootstrap.js +18 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +5 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/auth.d.ts +38 -0
- package/dist/core/auth.js +93 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/config.d.ts +259 -0
- package/dist/core/config.js +172 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/context.d.ts +25 -0
- package/dist/core/context.js +37 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/env.d.ts +2 -0
- package/dist/core/env.js +5 -0
- package/dist/core/env.js.map +1 -0
- package/dist/core/log_mask.d.ts +10 -0
- package/dist/core/log_mask.js +88 -0
- package/dist/core/log_mask.js.map +1 -0
- package/dist/core/oauth.d.ts +46 -0
- package/dist/core/oauth.js +507 -0
- package/dist/core/oauth.js.map +1 -0
- package/dist/core/paths.d.ts +5 -0
- package/dist/core/paths.js +47 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/scope.d.ts +28 -0
- package/dist/core/scope.js +54 -0
- package/dist/core/scope.js.map +1 -0
- package/dist/core/upstream.d.ts +30 -0
- package/dist/core/upstream.js +164 -0
- package/dist/core/upstream.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/define.d.ts +144 -0
- package/dist/plugin/define.js +44 -0
- package/dist/plugin/define.js.map +1 -0
- package/dist/plugin/load.d.ts +2 -0
- package/dist/plugin/load.js +41 -0
- package/dist/plugin/load.js.map +1 -0
- package/dist/plugin/ping.d.ts +9 -0
- package/dist/plugin/ping.js +29 -0
- package/dist/plugin/ping.js.map +1 -0
- package/dist/plugin/registry.d.ts +62 -0
- package/dist/plugin/registry.js +248 -0
- package/dist/plugin/registry.js.map +1 -0
- package/dist/plugin/result.d.ts +20 -0
- package/dist/plugin/result.js +59 -0
- package/dist/plugin/result.js.map +1 -0
- package/dist/plugins/drive/chunker.d.ts +28 -0
- package/dist/plugins/drive/chunker.js +356 -0
- package/dist/plugins/drive/chunker.js.map +1 -0
- package/dist/plugins/drive/clean_text.d.ts +13 -0
- package/dist/plugins/drive/clean_text.js +31 -0
- package/dist/plugins/drive/clean_text.js.map +1 -0
- package/dist/plugins/drive/client.d.ts +94 -0
- package/dist/plugins/drive/client.js +220 -0
- package/dist/plugins/drive/client.js.map +1 -0
- package/dist/plugins/drive/embeddings.d.ts +15 -0
- package/dist/plugins/drive/embeddings.js +118 -0
- package/dist/plugins/drive/embeddings.js.map +1 -0
- package/dist/plugins/drive/exclude.d.ts +11 -0
- package/dist/plugins/drive/exclude.js +36 -0
- package/dist/plugins/drive/exclude.js.map +1 -0
- package/dist/plugins/drive/extract_text.d.ts +26 -0
- package/dist/plugins/drive/extract_text.js +95 -0
- package/dist/plugins/drive/extract_text.js.map +1 -0
- package/dist/plugins/drive/get_token.d.ts +5 -0
- package/dist/plugins/drive/get_token.js +128 -0
- package/dist/plugins/drive/get_token.js.map +1 -0
- package/dist/plugins/drive/index.d.ts +5 -0
- package/dist/plugins/drive/index.js +72 -0
- package/dist/plugins/drive/index.js.map +1 -0
- package/dist/plugins/drive/indexer.d.ts +69 -0
- package/dist/plugins/drive/indexer.js +204 -0
- package/dist/plugins/drive/indexer.js.map +1 -0
- package/dist/plugins/drive/mathpix.d.ts +4 -0
- package/dist/plugins/drive/mathpix.js +102 -0
- package/dist/plugins/drive/mathpix.js.map +1 -0
- package/dist/plugins/drive/ooxml.d.ts +17 -0
- package/dist/plugins/drive/ooxml.js +152 -0
- package/dist/plugins/drive/ooxml.js.map +1 -0
- package/dist/plugins/drive/path.d.ts +40 -0
- package/dist/plugins/drive/path.js +87 -0
- package/dist/plugins/drive/path.js.map +1 -0
- package/dist/plugins/drive/qdrant.d.ts +123 -0
- package/dist/plugins/drive/qdrant.js +148 -0
- package/dist/plugins/drive/qdrant.js.map +1 -0
- package/dist/plugins/drive/reindex.d.ts +2 -0
- package/dist/plugins/drive/reindex.js +263 -0
- package/dist/plugins/drive/reindex.js.map +1 -0
- package/dist/plugins/drive/settings.d.ts +11 -0
- package/dist/plugins/drive/settings.js +13 -0
- package/dist/plugins/drive/settings.js.map +1 -0
- package/dist/plugins/drive/sync.d.ts +16 -0
- package/dist/plugins/drive/sync.js +139 -0
- package/dist/plugins/drive/sync.js.map +1 -0
- package/dist/plugins/drive/sync_state.d.ts +3 -0
- package/dist/plugins/drive/sync_state.js +26 -0
- package/dist/plugins/drive/sync_state.js.map +1 -0
- package/dist/plugins/drive/tools/list_drive_folder.d.ts +104 -0
- package/dist/plugins/drive/tools/list_drive_folder.js +221 -0
- package/dist/plugins/drive/tools/list_drive_folder.js.map +1 -0
- package/dist/plugins/drive/tools/read_drive_file.d.ts +66 -0
- package/dist/plugins/drive/tools/read_drive_file.js +206 -0
- package/dist/plugins/drive/tools/read_drive_file.js.map +1 -0
- package/dist/plugins/drive/tools/search_drive.d.ts +52 -0
- package/dist/plugins/drive/tools/search_drive.js +78 -0
- package/dist/plugins/drive/tools/search_drive.js.map +1 -0
- package/dist/plugins/drive/tools/semantic_search_drive.d.ts +109 -0
- package/dist/plugins/drive/tools/semantic_search_drive.js +228 -0
- package/dist/plugins/drive/tools/semantic_search_drive.js.map +1 -0
- package/dist/plugins/github/index.d.ts +1 -0
- package/dist/plugins/github/index.js +27 -0
- package/dist/plugins/github/index.js.map +1 -0
- package/dist/plugins/github/repo_tree.d.ts +57 -0
- package/dist/plugins/github/repo_tree.js +123 -0
- package/dist/plugins/github/repo_tree.js.map +1 -0
- package/dist/plugins/index.d.ts +11 -0
- package/dist/plugins/index.js +7 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/railway/index.d.ts +1 -0
- package/dist/plugins/railway/index.js +21 -0
- package/dist/plugins/railway/index.js.map +1 -0
- package/dist/plugins/railway/tools.d.ts +114 -0
- package/dist/plugins/railway/tools.js +165 -0
- package/dist/plugins/railway/tools.js.map +1 -0
- package/dist/plugins/slack/api.d.ts +63 -0
- package/dist/plugins/slack/api.js +280 -0
- package/dist/plugins/slack/api.js.map +1 -0
- package/dist/plugins/slack/index.d.ts +1 -0
- package/dist/plugins/slack/index.js +80 -0
- package/dist/plugins/slack/index.js.map +1 -0
- package/dist/plugins/slack/tools/slack_files.d.ts +87 -0
- package/dist/plugins/slack/tools/slack_files.js +204 -0
- package/dist/plugins/slack/tools/slack_files.js.map +1 -0
- package/dist/plugins/slack/tools/slack_list_channels.d.ts +46 -0
- package/dist/plugins/slack/tools/slack_list_channels.js +197 -0
- package/dist/plugins/slack/tools/slack_list_channels.js.map +1 -0
- package/dist/plugins/slack/tools/slack_read_channel.d.ts +56 -0
- package/dist/plugins/slack/tools/slack_read_channel.js +150 -0
- package/dist/plugins/slack/tools/slack_read_channel.js.map +1 -0
- package/dist/plugins/slack/tools/slack_search.d.ts +53 -0
- package/dist/plugins/slack/tools/slack_search.js +132 -0
- package/dist/plugins/slack/tools/slack_search.js.map +1 -0
- package/dist/run.d.ts +8 -0
- package/dist/run.js +270 -0
- package/dist/run.js.map +1 -0
- package/dist/server/http.d.ts +5 -0
- package/dist/server/http.js +406 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/identity.d.ts +17 -0
- package/dist/server/identity.js +47 -0
- package/dist/server/identity.js.map +1 -0
- package/dist/server/mcp.d.ts +7 -0
- package/dist/server/mcp.js +55 -0
- package/dist/server/mcp.js.map +1 -0
- package/dist/server/stdio.d.ts +2 -0
- package/dist/server/stdio.js +40 -0
- package/dist/server/stdio.js.map +1 -0
- package/dist/store/index.d.ts +11 -0
- package/dist/store/index.js +31 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/keys.d.ts +9 -0
- package/dist/store/keys.js +32 -0
- package/dist/store/keys.js.map +1 -0
- package/dist/store/sqlite.d.ts +38 -0
- package/dist/store/sqlite.js +316 -0
- package/dist/store/sqlite.js.map +1 -0
- package/dist/store/supabase.d.ts +35 -0
- package/dist/store/supabase.js +269 -0
- package/dist/store/supabase.js.map +1 -0
- package/dist/store/supabase_client.d.ts +10 -0
- package/dist/store/supabase_client.js +31 -0
- package/dist/store/supabase_client.js.map +1 -0
- package/dist/store/tool_log.d.ts +12 -0
- package/dist/store/tool_log.js +8 -0
- package/dist/store/tool_log.js.map +1 -0
- package/dist/store/types.d.ts +96 -0
- package/dist/store/types.js +2 -0
- package/dist/store/types.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +11 -0
- package/dist/version.js.map +1 -0
- package/package.json +80 -4
- package/sql/supabase.sql +185 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* slack_read_channel(channel, limit?, oldest?, includeThreads?) โ ์ฑ๋ ๋ํ ์ฝ๊ธฐ.
|
|
3
|
+
*
|
|
4
|
+
* conversations.history ๋ก ์ต๊ทผ ๋ฉ์์ง, ์ต์
์ผ๋ก thread replies ๊น์ง.
|
|
5
|
+
* channel ์ ์ด๋ฆ(#dev / dev) ๋๋ ID(Cโฆ/Gโฆ) ํ์ฉ โ ์ด๋ฆ์ด๋ฉด conversations.list ๋ก resolve.
|
|
6
|
+
* Bot token ์ฌ์ฉ. ์ ๋ขฐ ๊ฒฝ๊ณ = "๋ด์ด ๋ฉค๋ฒ์ธ ์ฑ๋"(slack_search ์ ๋์ผ). DM(Dโฆ)ยท๊ทธ๋ฃน DM ์ ์ฝ์ง ์๋๋ค
|
|
7
|
+
* (๋ด์๊ฒ ๋ณด๋ธ ๊ฐ์ธ DM ์ด ๋ค๋ฅธ ์ฌ์ฉ์์๊ฒ ์ด๋ฆฌ๋ ๊ฒ ๋ฐฉ์ง).
|
|
8
|
+
* ๊ถํ ๊ทธ๋ฃน: slack. ์ฑ๋ ๋ฒ์๋ app_users.allowed_slack_channels.
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
declare const inputSchema: z.ZodObject<{
|
|
12
|
+
channel: z.ZodString;
|
|
13
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
14
|
+
oldest: z.ZodOptional<z.ZodString>;
|
|
15
|
+
includeThreads: z.ZodDefault<z.ZodBoolean>;
|
|
16
|
+
}, "strip", z.ZodTypeAny, {
|
|
17
|
+
channel: string;
|
|
18
|
+
limit: number;
|
|
19
|
+
includeThreads: boolean;
|
|
20
|
+
oldest?: string | undefined;
|
|
21
|
+
}, {
|
|
22
|
+
channel: string;
|
|
23
|
+
limit?: number | undefined;
|
|
24
|
+
oldest?: string | undefined;
|
|
25
|
+
includeThreads?: boolean | undefined;
|
|
26
|
+
}>;
|
|
27
|
+
export declare const slackReadChannelTool: import("../../../plugin/define.js").Tool<z.ZodObject<{
|
|
28
|
+
channel: z.ZodString;
|
|
29
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
30
|
+
oldest: z.ZodOptional<z.ZodString>;
|
|
31
|
+
includeThreads: z.ZodDefault<z.ZodBoolean>;
|
|
32
|
+
}, "strip", z.ZodTypeAny, {
|
|
33
|
+
channel: string;
|
|
34
|
+
limit: number;
|
|
35
|
+
includeThreads: boolean;
|
|
36
|
+
oldest?: string | undefined;
|
|
37
|
+
}, {
|
|
38
|
+
channel: string;
|
|
39
|
+
limit?: number | undefined;
|
|
40
|
+
oldest?: string | undefined;
|
|
41
|
+
includeThreads?: boolean | undefined;
|
|
42
|
+
}>>;
|
|
43
|
+
export declare function handleSlackReadChannel(args: z.infer<typeof inputSchema>): Promise<{
|
|
44
|
+
content: {
|
|
45
|
+
type: "text";
|
|
46
|
+
text: string;
|
|
47
|
+
}[];
|
|
48
|
+
isError: boolean;
|
|
49
|
+
} | {
|
|
50
|
+
content: {
|
|
51
|
+
type: "text";
|
|
52
|
+
text: string;
|
|
53
|
+
}[];
|
|
54
|
+
isError?: undefined;
|
|
55
|
+
}>;
|
|
56
|
+
export {};
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* slack_read_channel(channel, limit?, oldest?, includeThreads?) โ ์ฑ๋ ๋ํ ์ฝ๊ธฐ.
|
|
3
|
+
*
|
|
4
|
+
* conversations.history ๋ก ์ต๊ทผ ๋ฉ์์ง, ์ต์
์ผ๋ก thread replies ๊น์ง.
|
|
5
|
+
* channel ์ ์ด๋ฆ(#dev / dev) ๋๋ ID(Cโฆ/Gโฆ) ํ์ฉ โ ์ด๋ฆ์ด๋ฉด conversations.list ๋ก resolve.
|
|
6
|
+
* Bot token ์ฌ์ฉ. ์ ๋ขฐ ๊ฒฝ๊ณ = "๋ด์ด ๋ฉค๋ฒ์ธ ์ฑ๋"(slack_search ์ ๋์ผ). DM(Dโฆ)ยท๊ทธ๋ฃน DM ์ ์ฝ์ง ์๋๋ค
|
|
7
|
+
* (๋ด์๊ฒ ๋ณด๋ธ ๊ฐ์ธ DM ์ด ๋ค๋ฅธ ์ฌ์ฉ์์๊ฒ ์ด๋ฆฌ๋ ๊ฒ ๋ฐฉ์ง).
|
|
8
|
+
* ๊ถํ ๊ทธ๋ฃน: slack. ์ฑ๋ ๋ฒ์๋ app_users.allowed_slack_channels.
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { defineTool } from '../../../plugin/define.js';
|
|
12
|
+
import { getAuth } from '../../../core/context.js';
|
|
13
|
+
import { allowedSlackChannels } from '../../../core/scope.js';
|
|
14
|
+
import { slackApi, SlackError, loadSlackUserMap, loadChannelNameMap, loadBotMemberChannelIds, mapLimit, } from '../api.js';
|
|
15
|
+
const DESCRIPTION = 'Slack ์ฑ๋์ ์ต๊ทผ ๋ํ๋ฅผ ์ฝ๋๋ค. channel ์ ์ด๋ฆ(#dev) ๋๋ ID(Cโฆ). ' +
|
|
16
|
+
'**๊ธฐ๋ณธ์ผ๋ก ๊ฐ ๋ฉ์์ง์ thread ๋ต๊ธ๊น์ง ํจ๊ป ๊ฐ์ ธ์จ๋ค(includeThreads=true ๊ธฐ๋ณธ).** ' +
|
|
17
|
+
'Slack discussions and decisions often live in thread replies, so ' +
|
|
18
|
+
'์์ค(๋ถ๋ชจ ๋ฉ์์ง)๋ง ๋ณด๋ฉด ๋งฅ๋ฝ์ด ํต์งธ๋ก ๋๋ฝ๋๋ค โ ๋ต๊ธ๊น์ง ์ฝ์ด์ผ ์ค์ ๊ฒฐ๋ก ์ด ๋ณด์ธ๋ค. ' +
|
|
19
|
+
'์์ค๋ง ๋น ๋ฅด๊ฒ ํ๊ณ ์ถ์ ๋๋ง includeThreads=false ๋ก ๋๋ค. ' +
|
|
20
|
+
'๋ด์ด ํด๋น ์ฑ๋ ๋ฉค๋ฒ์ฌ์ผ ์กฐํ ๊ฐ๋ฅ (๋น๊ณต๊ฐ ์ฑ๋์ ์ด๋ ํ์).';
|
|
21
|
+
const inputSchema = z.object({
|
|
22
|
+
channel: z.string().min(1).describe('์ฑ๋ ์ด๋ฆ(#dev ๋๋ dev) ๋๋ ID(Cโฆ).'),
|
|
23
|
+
limit: z.number().int().min(1).max(200).default(50).describe('๋ฉ์์ง ์ (1-200). default 50.'),
|
|
24
|
+
oldest: z.string().optional().describe('์ ํ. ์ด ์์ ์ดํ๋ง (YYYY-MM-DD ๋๋ Unix ts).'),
|
|
25
|
+
includeThreads: z
|
|
26
|
+
.boolean()
|
|
27
|
+
.default(true)
|
|
28
|
+
.describe('thread ๋ต๊ธ ํฌํจ ์ฌ๋ถ. **default true** โ ๋ต๊ธ์ ์ค์ ๋
ผ์๊ฐ ๋ด๊ฒจ ์์ด ๊ธฐ๋ณธ ํฌํจ. ๋ถ๋ชจ ๋ฉ์์ง๋ง ๋น ๋ฅด๊ฒ ๋ณด๋ ค๋ฉด false.'),
|
|
29
|
+
});
|
|
30
|
+
export const slackReadChannelTool = defineTool({
|
|
31
|
+
name: 'slack_read_channel',
|
|
32
|
+
description: DESCRIPTION,
|
|
33
|
+
input: inputSchema,
|
|
34
|
+
annotations: { readOnlyHint: true },
|
|
35
|
+
run: (args) => handleSlackReadChannel(args),
|
|
36
|
+
});
|
|
37
|
+
/** YYYY-MM-DD โ Unix epoch ์ด. ์ด๋ฏธ ts(์ซ์.์ซ์)๋ฉด ๊ทธ๋๋ก. */
|
|
38
|
+
function toOldestTs(oldest) {
|
|
39
|
+
if (!oldest)
|
|
40
|
+
return undefined;
|
|
41
|
+
if (/^\d+(\.\d+)?$/.test(oldest))
|
|
42
|
+
return oldest;
|
|
43
|
+
const d = new Date(oldest);
|
|
44
|
+
if (isNaN(d.getTime()))
|
|
45
|
+
return undefined;
|
|
46
|
+
return String(Math.floor(d.getTime() / 1000));
|
|
47
|
+
}
|
|
48
|
+
async function resolveChannelId(input) {
|
|
49
|
+
// ์ด๋ฏธ ID ํํ (๊ณต๊ฐ Cโฆ / ๋น๊ณต๊ฐ Gโฆ). DM(Dโฆ)์ ๋ฐ์ง ์๋๋ค.
|
|
50
|
+
if (/^D[A-Z0-9]{6,}$/.test(input))
|
|
51
|
+
throw new SlackError('DM ์ ์ฝ์ ์ ์์ต๋๋ค.');
|
|
52
|
+
if (/^[CG][A-Z0-9]{6,}$/.test(input))
|
|
53
|
+
return { id: input, name: null };
|
|
54
|
+
const cleaned = input.replace(/^#/, '');
|
|
55
|
+
// ๊ณต์ฉ ์ฑ๋๋ช
์บ์(TTL) ์กฐํ โ ๋งค ํธ์ถ conversations.list ์์ฐจ ์ํ๋ฅผ warmup ํ 0์ฝ๋ก.
|
|
56
|
+
const byName = await loadChannelNameMap();
|
|
57
|
+
const found = byName.get(cleaned);
|
|
58
|
+
if (found)
|
|
59
|
+
return { id: found.id, name: found.name };
|
|
60
|
+
throw new SlackError(`์ฑ๋ "${input}" ์ ์ฐพ์ ์ ์์ (๋ด์ด ๋ฉค๋ฒ๊ฐ ์๋๊ฑฐ๋ ์ด๋ฆ ์คํ).`);
|
|
61
|
+
}
|
|
62
|
+
// user-mapยทmapLimit ์ slack.ts ๊ณต์ฉ ๋ฒ์ (loadSlackUserMapยทmapLimit) ์ฌ์ฉ โ ๋๊ตฌ๋ณ ์ค๋ณต ๊ตฌํยท์บ์
|
|
63
|
+
// ๋ถ์ ์ ์ ๊ฑฐํด, search ๊ฐ ๋ฐ์ด ์บ์๋ฅผ read_channel ์ด ์ฌ์ฌ์ฉ(๋ฐ๋๋)ํ๊ณ users.list ์๋ณต์ด ์ค์ง ์ ๊ฑฐ.
|
|
64
|
+
export async function handleSlackReadChannel(args) {
|
|
65
|
+
const auth = getAuth();
|
|
66
|
+
const { channel, limit, oldest, includeThreads } = args;
|
|
67
|
+
try {
|
|
68
|
+
const { id: channelId, name: channelName } = await resolveChannelId(channel);
|
|
69
|
+
// ์ ๋ขฐ ๊ฒฝ๊ณ: ๋ด์ด ๋ฉค๋ฒ์ธ (๊ณต๊ฐ+๋น๊ณต๊ฐ) ์ฑ๋๋ง. ๊ทธ๋ฃน DM(Gโฆ)ยทDM ์ conversations.list ์ ์์ด ์ฌ๊ธฐ์ ๊ฑธ๋ฆฐ๋ค.
|
|
70
|
+
const botMemberIds = await loadBotMemberChannelIds();
|
|
71
|
+
if (!botMemberIds.has(channelId)) {
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{ type: 'text', text: `[forbidden] ์ฑ๋ '${channel}' ์ ๋ด์ด ๋ฉค๋ฒ๊ฐ ์๋๋๋ค. ๋ด์ ์ฑ๋์ ์ด๋ํด์ผ ์ฝ์ ์ ์์ต๋๋ค.` },
|
|
75
|
+
],
|
|
76
|
+
isError: true,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// ์ง์๋ณ Slack ์ฑ๋ scope ์ฒดํฌ (adminยท๋ฏธ์ค์ = ์ ์ฒด)
|
|
80
|
+
const channelScope = allowedSlackChannels(auth);
|
|
81
|
+
if (channelScope && !channelScope.has(channelId)) {
|
|
82
|
+
return {
|
|
83
|
+
content: [
|
|
84
|
+
{ type: 'text', text: `[forbidden] ์ฑ๋ '${channel}' ์ ํ์ฌ ์ง์ ๊ถํ์ผ๋ก ์ ๊ทผ ๋ถ๊ฐ์
๋๋ค.` },
|
|
85
|
+
],
|
|
86
|
+
isError: true,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
// user map(์บ์)๊ณผ ์ฑ๋ history ๋ฅผ ๋ณ๋ ฌ โ ์๋ก ๋
๋ฆฝ. (์์ ์ userMap ์ง๋ ฌ ํ history)
|
|
90
|
+
const [userMap, hist] = await Promise.all([
|
|
91
|
+
loadSlackUserMap(),
|
|
92
|
+
slackApi('conversations.history', { channel: channelId, limit, oldest: toOldestTs(oldest) }, 'bot'),
|
|
93
|
+
]);
|
|
94
|
+
const nameOf = (m) => m.user ? (userMap[m.user] ?? m.user) : (m.bot_id ? `bot:${m.bot_id}` : null);
|
|
95
|
+
// thread replies ๋ฅผ ๋์์ฑ 6 ์ผ๋ก ๋ณ๋ ฌ(์์ฐจ N+1 ์ ๊ฑฐ). thread ํ๋ ์คํจ๊ฐ ์ ์ฒด๋ฅผ ์ ๊นจ๊ฒ ๊ฒฉ๋ฆฌ.
|
|
96
|
+
const messages = await mapLimit(hist.messages ?? [], 6, async (m) => {
|
|
97
|
+
const hasThread = !!m.thread_ts && (m.reply_count ?? 0) > 0;
|
|
98
|
+
const entry = {
|
|
99
|
+
ts: m.ts,
|
|
100
|
+
datetime: m.ts ? new Date(Number(m.ts) * 1000).toISOString() : null,
|
|
101
|
+
user: nameOf(m),
|
|
102
|
+
text: m.text ?? '',
|
|
103
|
+
};
|
|
104
|
+
// ๋ถ๋ชจ ๋ฉ์์ง๋ฉด ๋ต๊ธ ์๋ฅผ ํญ์ ๋
ธ์ถ โ ํ์ฅ์ด ๊บผ์ง๊ฑฐ๋ ์คํจํด๋ "๋ต๊ธ์ด ๋ ์๋ค"๋ ์ ํธ๋ ๋จ๊ธด๋ค.
|
|
105
|
+
if (hasThread)
|
|
106
|
+
entry.reply_count = m.reply_count;
|
|
107
|
+
if (includeThreads && hasThread) {
|
|
108
|
+
try {
|
|
109
|
+
const rep = await slackApi('conversations.replies', { channel: channelId, ts: m.thread_ts, limit: 100 }, 'bot');
|
|
110
|
+
// replies[0] == ๋ถ๋ชจ ๋ฉ์์ง โ ์ ์ธ
|
|
111
|
+
entry.replies = (rep.messages ?? []).slice(1).map((r) => ({
|
|
112
|
+
ts: r.ts,
|
|
113
|
+
datetime: r.ts ? new Date(Number(r.ts) * 1000).toISOString() : null,
|
|
114
|
+
user: nameOf(r),
|
|
115
|
+
text: r.text ?? '',
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// ํ thread ์คํจ๊ฐ ์ฑ๋ ์ฝ๊ธฐ ์ ์ฒด๋ฅผ ๊นจ์ง ์๊ฒ. ๋จ ๋น []๋ก ์จ๊ธฐ์ง ์๊ณ ๋ช
์ โ
|
|
120
|
+
// rate-limit ๋ฑ์ผ๋ก ๋ต๊ธ์ ๋ชป ๊ฐ์ ธ์จ ๊ฒฝ์ฐ "๋ต๊ธ 0๊ฐ"๋ก ์ค์ธ๋์ง ์๊ฒ ์ ํธ๋ฅผ ๋จ๊ธด๋ค.
|
|
121
|
+
entry.replies = [];
|
|
122
|
+
entry.replies_error = true;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return entry;
|
|
126
|
+
});
|
|
127
|
+
return {
|
|
128
|
+
content: [
|
|
129
|
+
{
|
|
130
|
+
type: 'text',
|
|
131
|
+
text: JSON.stringify({
|
|
132
|
+
channel: channelName ? `#${channelName}` : channelId,
|
|
133
|
+
channelId,
|
|
134
|
+
count: messages.length,
|
|
135
|
+
includeThreads,
|
|
136
|
+
messages,
|
|
137
|
+
}, null, 2),
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
const msg = e instanceof SlackError ? e.message : e instanceof Error ? e.message : String(e);
|
|
144
|
+
return {
|
|
145
|
+
content: [{ type: 'text', text: `[error] ${msg}` }],
|
|
146
|
+
isError: true,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=slack_read_channel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack_read_channel.js","sourceRoot":"","sources":["../../../../src/plugins/slack/tools/slack_read_channel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* slack_search(query, count?) โ Slack ์ํฌ์คํ์ด์ค ๋ฉ์์ง ๊ฒ์.
|
|
3
|
+
*
|
|
4
|
+
* search.messages API ์ฌ์ฉ โ User token (xoxp-โฆ, search:read scope) ํ์.
|
|
5
|
+
* ๊ถํ ๊ทธ๋ฃน: slack. ๊ฒฐ๊ณผ๋ ๋ด์ด ๋ฉค๋ฒ์ธ ์ฑ๋๊ณผ ์ง์ ์ฑ๋ ๋ฒ์๋ก ๊ฑฐ๋ฅธ๋ค.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
declare const inputSchema: z.ZodObject<{
|
|
9
|
+
query: z.ZodString;
|
|
10
|
+
count: z.ZodDefault<z.ZodNumber>;
|
|
11
|
+
sort: z.ZodDefault<z.ZodEnum<["score", "timestamp"]>>;
|
|
12
|
+
expandThreads: z.ZodDefault<z.ZodBoolean>;
|
|
13
|
+
}, "strip", z.ZodTypeAny, {
|
|
14
|
+
sort: "timestamp" | "score";
|
|
15
|
+
count: number;
|
|
16
|
+
query: string;
|
|
17
|
+
expandThreads: boolean;
|
|
18
|
+
}, {
|
|
19
|
+
query: string;
|
|
20
|
+
sort?: "timestamp" | "score" | undefined;
|
|
21
|
+
count?: number | undefined;
|
|
22
|
+
expandThreads?: boolean | undefined;
|
|
23
|
+
}>;
|
|
24
|
+
export declare const slackSearchTool: import("../../../plugin/define.js").Tool<z.ZodObject<{
|
|
25
|
+
query: z.ZodString;
|
|
26
|
+
count: z.ZodDefault<z.ZodNumber>;
|
|
27
|
+
sort: z.ZodDefault<z.ZodEnum<["score", "timestamp"]>>;
|
|
28
|
+
expandThreads: z.ZodDefault<z.ZodBoolean>;
|
|
29
|
+
}, "strip", z.ZodTypeAny, {
|
|
30
|
+
sort: "timestamp" | "score";
|
|
31
|
+
count: number;
|
|
32
|
+
query: string;
|
|
33
|
+
expandThreads: boolean;
|
|
34
|
+
}, {
|
|
35
|
+
query: string;
|
|
36
|
+
sort?: "timestamp" | "score" | undefined;
|
|
37
|
+
count?: number | undefined;
|
|
38
|
+
expandThreads?: boolean | undefined;
|
|
39
|
+
}>>;
|
|
40
|
+
export declare function handleSlackSearch(args: z.infer<typeof inputSchema>): Promise<{
|
|
41
|
+
content: {
|
|
42
|
+
type: "text";
|
|
43
|
+
text: string;
|
|
44
|
+
}[];
|
|
45
|
+
isError?: undefined;
|
|
46
|
+
} | {
|
|
47
|
+
content: {
|
|
48
|
+
type: "text";
|
|
49
|
+
text: string;
|
|
50
|
+
}[];
|
|
51
|
+
isError: boolean;
|
|
52
|
+
}>;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* slack_search(query, count?) โ Slack ์ํฌ์คํ์ด์ค ๋ฉ์์ง ๊ฒ์.
|
|
3
|
+
*
|
|
4
|
+
* search.messages API ์ฌ์ฉ โ User token (xoxp-โฆ, search:read scope) ํ์.
|
|
5
|
+
* ๊ถํ ๊ทธ๋ฃน: slack. ๊ฒฐ๊ณผ๋ ๋ด์ด ๋ฉค๋ฒ์ธ ์ฑ๋๊ณผ ์ง์ ์ฑ๋ ๋ฒ์๋ก ๊ฑฐ๋ฅธ๋ค.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { defineTool } from '../../../plugin/define.js';
|
|
9
|
+
import { getAuth } from '../../../core/context.js';
|
|
10
|
+
import { allowedSlackChannels } from '../../../core/scope.js';
|
|
11
|
+
import { slackApi, SlackError, loadSlackUserMap, mapLimit, loadBotMemberChannelIds, } from '../api.js';
|
|
12
|
+
const DESCRIPTION = 'Slack ์ํฌ์คํ์ด์ค์์ ๋ฉ์์ง๋ฅผ ํค์๋๋ก ๊ฒ์. Slack ๊ฒ์ ์ฐ์ฐ์ ์ฌ์ฉ ๊ฐ๋ฅ ' +
|
|
13
|
+
'(์: "๋ฐฐํฌ in:#dev", "from:@alex ๊ฒฐ์ ", "JSON-LD after:2026-01-01"). ' +
|
|
14
|
+
'์ฌ๋ด ๋
ผ์ยท๊ฒฐ์ ์ด Slack ์ ์์ ๋ Drive ๊ฒ์๊ณผ ํจ๊ป ์ฌ์ฉ. ' +
|
|
15
|
+
'**๊ธฐ๋ณธ์ผ๋ก ๋ด์ด ๋ฉค๋ฒ์ธ ๋ชจ๋ ์ฑ๋์ ๊ฒ์ํ๋ค**(๊ณต๊ฐยท๋น๊ณต๊ฐ ๋ฌด๊ด, ๋ด์ด ์ด๋๋ ์ฑ๋ ์ ์ฒด). ์ฑ๋์ ์ขํ์ง ๋ง๊ณ ๋ฐ๋ก ํค์๋๋ก ๊ฒ์ํ๋ผ โ ํน์ ์ฑ๋๋ง ํ์ ํ ๋๋ง in:#์ฑ๋. DMยท๋ด ๋ฏธ์ด๋ ์ฑ๋์ ์ ์ธ. ' +
|
|
16
|
+
'**๊ฒ์์ ๋จ์ผ ๋ฉ์์ง๋ง ๋งค์นญํ๋ค โ ์ค์ ๋
ผ์ยท๊ฒฐ๋ก ์ ๊ทธ ๋ฉ์์ง์ thread ๋ต๊ธ์ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.** ' +
|
|
17
|
+
'๊ธฐ๋ณธ(expandThreads=true)์ผ๋ก ๋ด์ด ์ฝ์ ์ ์๋ ์ฑ๋์ ๋งค์นญ์ ์ฃผ๋ณ thread ๋งฅ๋ฝ๊น์ง ํจ๊ป ๊ฐ์ ธ์จ๋ค. ' +
|
|
18
|
+
'thread_unavailable=true ๋ฉด ๋ต๊ธ์ด ๋ ์์ผ๋ ๋ด์ด ๊ทธ ์ฑ๋ ๋ฉค๋ฒ๊ฐ ์๋๋ผ ๋ชป ์ฝ์ ๊ฒ โ slack_read_channel ๋ก๋ ๋งํ๋ค. ' +
|
|
19
|
+
'**"์ต๊ทผ/๊ทผํฉ/์ต์ ์งํ์ํฉ/๋๊ฐ ๋ญ๋ผ ํ๋" ์ฒ๋ผ ์ต์ ์ฑ์ด ์ค์ํ ์ง๋ฌธ์ด๋ฉด sort="timestamp"(์ต์ ์) ๋ฅผ ์จ๋ผ.** User token ํ์.';
|
|
20
|
+
const inputSchema = z.object({
|
|
21
|
+
query: z.string().min(1).describe('๊ฒ์์ด. Slack ์ฐ์ฐ์(in:, from:, after:, before:) ์ง์.'),
|
|
22
|
+
count: z.number().int().min(1).max(50).default(20).describe('์ต๋ ๊ฒฐ๊ณผ ์ (1-50). default 20.'),
|
|
23
|
+
sort: z
|
|
24
|
+
.enum(['score', 'timestamp'])
|
|
25
|
+
.default('score')
|
|
26
|
+
.describe('"score"(๊ด๋ จ๋, default) ๋๋ "timestamp"(์ต์ ์). ์ต์ ๋
ผ์ยท๊ทผํฉ ์ง๋ฌธ์ด๋ฉด timestamp.'),
|
|
27
|
+
expandThreads: z
|
|
28
|
+
.boolean()
|
|
29
|
+
.default(true)
|
|
30
|
+
.describe('๋งค์นญ ๋ฉ์์ง๊ฐ thread ์์ด๋ฉด ์ฃผ๋ณ ๋ต๊ธ๊น์ง ๊ฐ์ ธ์จ๋ค. default true(๋
ผ์ ๋งฅ๋ฝ ๋ณด์กด). ํ๋ฉด ๊ฒฐ๊ณผ๋ง ๋น ๋ฅด๊ฒ ๋ณด๋ ค๋ฉด false.'),
|
|
31
|
+
});
|
|
32
|
+
export const slackSearchTool = defineTool({
|
|
33
|
+
name: 'slack_search',
|
|
34
|
+
description: DESCRIPTION,
|
|
35
|
+
input: inputSchema,
|
|
36
|
+
annotations: { readOnlyHint: true },
|
|
37
|
+
run: (args) => handleSlackSearch(args),
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* ๊ฒ์ ํ๋ฉด = "๋ด์ด ๋ฉค๋ฒ์ธ ์ฑ๋" โ read_channel ๊ณผ ๋์ผํ ์ ๋ขฐ ๊ฒฝ๊ณ.
|
|
41
|
+
*
|
|
42
|
+
* search.messages ๋ User token(xoxp) ๊ถํ์ด๋ผ ํ ํฐ ์์ ์์ ๊ฐ์ธ DMยท๋น๊ณต๊ฐ ์ฑ๋๊น์ง ๋ณด์ธ๋ค.
|
|
43
|
+
* ๊ทธ๋๋ก ๋
ธ์ถํ๋ฉด ํ ํฐ ์์ ์์ ์ฌ์ ๋ํ๊ฐ ์๋ฏ๋ก, "๋ด์ด ์ด๋๋ ์ฑ๋"๋ก๋ง ํ์ ํ๋ค
|
|
44
|
+
* (๋ด ์ด๋ = ์ด์์คํดํธ๊ฐ ์ฝ์ด๋ ๋๋ค๊ณ ํ์ด ํ๊ฐํ ์ฑ๋). ์ฑ๋์ด ๋๋ถ๋ถ ๋น๊ณต๊ฐ๋ผ,
|
|
45
|
+
* ๊ณผ๊ฑฐ์ 'public๋ง' ํํฐ๋ ์ฌ์ค์ ์ ๋ถ๋ฅผ ๋ง์ ๊ฒ์์ด 0๊ฑด์ด์๋ค.
|
|
46
|
+
* - DM(Dโฆ)ยท๊ทธ๋ฃนDM(mpim): conversations.list ์ ์ ์กํ botMemberIds ์ ์์ฐ ๋ถ์ฌ โ ์ ์ธ.
|
|
47
|
+
* - ๋ด ๋ฏธ์ด๋ ๋น๊ณต๊ฐ ์ฑ๋: ํ๊ฐ๋์ง ์์ โ ์ ์ธ(read_channel ๋ก๋ ๋ชป ์ฝ์).
|
|
48
|
+
*/
|
|
49
|
+
function isAllowedSearchMatch(m, botMemberIds) {
|
|
50
|
+
const c = m.channel;
|
|
51
|
+
if (!c?.id)
|
|
52
|
+
return false;
|
|
53
|
+
if (c.is_im || c.is_mpim)
|
|
54
|
+
return false; // ์ด์ค ๋ฐฉ์ด โ DM ์ ์ ๋ ๊ฒ์ ํ๋ฉด์ ์ ์ฌ๋ฆผ
|
|
55
|
+
return botMemberIds.has(c.id);
|
|
56
|
+
}
|
|
57
|
+
export async function handleSlackSearch(args) {
|
|
58
|
+
const auth = getAuth();
|
|
59
|
+
const { query, count, sort, expandThreads } = args;
|
|
60
|
+
try {
|
|
61
|
+
const res = await slackApi('search.messages', { query, count, sort, highlight: false }, 'search');
|
|
62
|
+
// 1) ๋ด์ด ๋ฉค๋ฒ์ธ ์ฑ๋๋ง (DMยท๋ด ๋ฏธ์ด๋ ๋น๊ณต๊ฐ ์ฑ๋ ์ ์ธ โ User token ์ ๊ฐ์ธ ๊ฐ์๋ฒ์ ์ฐจ๋จ)
|
|
63
|
+
// 2) ์ง์๋ณ Slack ์ฑ๋ scope (adminยท๋ฏธ์ค์ = ์ ์ฒด). ๊ฒฐ๊ณผ ๋ฉ์์ง๋ฅผ ํ์ฉ ์ฑ๋๋ก ํํฐ.
|
|
64
|
+
const channelScope = allowedSlackChannels(auth);
|
|
65
|
+
const botMemberIds = await loadBotMemberChannelIds();
|
|
66
|
+
const matches = (res.messages?.matches ?? []).filter((m) => isAllowedSearchMatch(m, botMemberIds) &&
|
|
67
|
+
(!channelScope || (m.channel?.id != null && channelScope.has(m.channel.id))));
|
|
68
|
+
const results = matches.map((m) => ({
|
|
69
|
+
ts: m.ts,
|
|
70
|
+
datetime: m.ts ? new Date(Number(m.ts) * 1000).toISOString() : null,
|
|
71
|
+
user: m.username ?? m.user ?? null,
|
|
72
|
+
channel: m.channel?.name ? `#${m.channel.name}` : (m.channel?.id ?? null),
|
|
73
|
+
channelId: m.channel?.id ?? null,
|
|
74
|
+
text: m.text ?? '',
|
|
75
|
+
permalink: m.permalink ?? null,
|
|
76
|
+
}));
|
|
77
|
+
// search.messages ๋ ๋จ์ผ ๋ฉ์์ง๋ง ๋ฐํ โ ๋งค์นญ์ด thread ์์ด๋ฉด ์ฃผ๋ณ ๋ต๊ธ ๋งฅ๋ฝ์ด ๋๋ฝ๋๋ค.
|
|
78
|
+
// ๋ด์ด ๋ฉค๋ฒ์ธ ์ฑ๋์ conversations.replies(ts=๋งค์นญts)๋ก thread ์ ์ฒด๋ฅผ ๊ฐ์ ธ์ ๋ถ์ธ๋ค.
|
|
79
|
+
// (Slack ์ thread ๋ด ์๋ฌด ๋ฉ์์ง ts ๋ก๋ thread ์ ์ฒด๋ฅผ ๋๋ ค์ค๋ค โ ๋ถ๋ชจ/๋ต๊ธ ๋ฌด๊ด)
|
|
80
|
+
// ๋ด ๋ฏธ์ฐธ์ฌ ์ฑ๋์ not_in_channel ๋ฑ์ผ๋ก ์คํจ โ thread_unavailable ๋ก๋ง ํ๊ธฐ(ํ๋ฉด ๊ฒฐ๊ณผ ์ ์ง).
|
|
81
|
+
if (expandThreads && results.length > 0) {
|
|
82
|
+
const userMap = await loadSlackUserMap();
|
|
83
|
+
const nameOf = (t) => t.user ? (userMap[t.user] ?? t.user) : t.bot_id ? `bot:${t.bot_id}` : null;
|
|
84
|
+
const seenThreads = new Set(); // channelId:rootTs โ ๊ฐ์ thread ์ค๋ณต ํ์ฅ ๋ฐฉ์ง
|
|
85
|
+
await mapLimit(results, 6, async (r) => {
|
|
86
|
+
if (!r.channelId || !r.ts)
|
|
87
|
+
return;
|
|
88
|
+
try {
|
|
89
|
+
const rep = await slackApi('conversations.replies', { channel: r.channelId, ts: r.ts, limit: 100 }, 'bot');
|
|
90
|
+
const msgs = rep.messages ?? [];
|
|
91
|
+
if (msgs.length <= 1)
|
|
92
|
+
return; // thread ์๋(๋จ์ผ ๋ฉ์์ง) โ ๋ถ์ผ ๋งฅ๋ฝ ์์
|
|
93
|
+
const rootTs = msgs[0]?.ts ?? r.ts;
|
|
94
|
+
const key = `${r.channelId}:${rootTs}`;
|
|
95
|
+
if (seenThreads.has(key)) {
|
|
96
|
+
r.thread_root_ts = rootTs; // ์ด๋ฏธ ๋ค๋ฅธ ๋งค์นญ์์ ํ์ฅํ thread
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
seenThreads.add(key);
|
|
100
|
+
r.thread = msgs.map((t) => ({
|
|
101
|
+
ts: t.ts,
|
|
102
|
+
user: nameOf(t),
|
|
103
|
+
text: t.text ?? '',
|
|
104
|
+
is_match: t.ts === r.ts, // ๊ฒ์์ ๊ฑธ๋ฆฐ ๋ฐ๋ก ๊ทธ ๋ฉ์์ง ํ์
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// ๋ด์ด ์ฑ๋ ๋ฉค๋ฒ๊ฐ ์๋(not_in_channel) ๋ฑ โ ๋ต๊ธ์ด ๋ ์์ ์ ์์ผ๋ ๋ชป ์ฝ์
|
|
109
|
+
r.thread_unavailable = true;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
content: [
|
|
115
|
+
{
|
|
116
|
+
type: 'text',
|
|
117
|
+
text: JSON.stringify(
|
|
118
|
+
// total(Slack ์๋ณธ ๊ฑด์)์ ์ฃ์ง ์๋๋ค โ DMยท๊ถํ ๋ฐ ์ฑ๋์ ์ผ์น ๊ฑด์๊น์ง ๋๋ฌ๋๋ค.
|
|
119
|
+
{ query, count: results.length, results }, null, 2),
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
const msg = e instanceof SlackError ? e.message : e instanceof Error ? e.message : String(e);
|
|
126
|
+
return {
|
|
127
|
+
content: [{ type: 'text', text: `[error] ${msg}` }],
|
|
128
|
+
isError: true,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=slack_search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack_search.js","sourceRoot":"","sources":["../../../../src/plugins/slack/tools/slack_search.ts"],"names":[],"mappings":"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"}
|
package/dist/run.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Plugin } from './plugin/define.js';
|
|
2
|
+
export interface RunOptions {
|
|
3
|
+
/** Plugins to serve. Default: the built-in Drive, Slack, GitHub and Railway plugins. */
|
|
4
|
+
plugins?: Plugin[];
|
|
5
|
+
/** Arguments without node and the script path. Default: process.argv.slice(2). */
|
|
6
|
+
argv?: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function run(opts?: RunOptions): Promise<void>;
|