c0de-agent 0.0.0 → 1.0.0
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 +101 -0
- package/dist/cli/commands/acp.d.ts +19 -0
- package/dist/cli/commands/acp.js +50 -0
- package/dist/cli/commands/chat.d.ts +13 -0
- package/dist/cli/commands/chat.js +26 -0
- package/dist/cli/commands/config.d.ts +17 -0
- package/dist/cli/commands/config.js +77 -0
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.js +14 -0
- package/dist/cli/commands/plugin.d.ts +11 -0
- package/dist/cli/commands/plugin.js +31 -0
- package/dist/cli/commands/serve.d.ts +18 -0
- package/dist/cli/commands/serve.js +35 -0
- package/dist/cli/commands/update.d.ts +24 -0
- package/dist/cli/commands/update.js +40 -0
- package/dist/cli/deps.d.ts +19 -0
- package/dist/cli/deps.js +57 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.js +149 -0
- package/dist/cli/modes/acp.d.ts +18 -0
- package/dist/cli/modes/acp.js +57 -0
- package/dist/cli/modes/print.d.ts +16 -0
- package/dist/cli/modes/print.js +30 -0
- package/dist/cli/parser.d.ts +19 -0
- package/dist/cli/parser.js +28 -0
- package/dist/cli/utils/output.d.ts +11 -0
- package/dist/cli/utils/output.js +23 -0
- package/dist/cli/utils/prompt.d.ts +12 -0
- package/dist/cli/utils/prompt.js +18 -0
- package/dist/core/agent.d.ts +12 -0
- package/dist/core/agent.js +95 -0
- package/dist/core/agents/builtin.d.ts +6 -0
- package/dist/core/agents/builtin.js +76 -0
- package/dist/core/agents/discovery.d.ts +6 -0
- package/dist/core/agents/discovery.js +96 -0
- package/dist/core/agents/index.d.ts +6 -0
- package/dist/core/agents/index.js +4 -0
- package/dist/core/agents/parallel.d.ts +13 -0
- package/dist/core/agents/parallel.js +37 -0
- package/dist/core/agents/registry.d.ts +4 -0
- package/dist/core/agents/registry.js +23 -0
- package/dist/core/agents/types.d.ts +37 -0
- package/dist/core/agents/types.js +1 -0
- package/dist/core/compact.d.ts +11 -0
- package/dist/core/compact.js +31 -0
- package/dist/core/config.d.ts +7 -0
- package/dist/core/config.js +84 -0
- package/dist/core/context.d.ts +23 -0
- package/dist/core/context.js +93 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.js +11 -0
- package/dist/core/loop.d.ts +25 -0
- package/dist/core/loop.js +651 -0
- package/dist/core/metrics.d.ts +27 -0
- package/dist/core/metrics.js +94 -0
- package/dist/core/prompt-registry.d.ts +21 -0
- package/dist/core/prompt-registry.js +200 -0
- package/dist/core/prompt.d.ts +11 -0
- package/dist/core/prompt.js +13 -0
- package/dist/core/secret.d.ts +12 -0
- package/dist/core/secret.js +51 -0
- package/dist/core/slash.d.ts +15 -0
- package/dist/core/slash.js +114 -0
- package/dist/core/steering.d.ts +8 -0
- package/dist/core/steering.js +15 -0
- package/dist/core/title.d.ts +42 -0
- package/dist/core/title.js +115 -0
- package/dist/core/tool-exec.d.ts +20 -0
- package/dist/core/tool-exec.js +64 -0
- package/dist/core/types.d.ts +95 -0
- package/dist/core/types.js +1 -0
- package/dist/core/worktree.d.ts +24 -0
- package/dist/core/worktree.js +68 -0
- package/dist/dap/index.d.ts +6 -0
- package/dist/dap/index.js +4 -0
- package/dist/dap/protocol.d.ts +40 -0
- package/dist/dap/protocol.js +132 -0
- package/dist/dap/session.d.ts +23 -0
- package/dist/dap/session.js +130 -0
- package/dist/dap/transport.d.ts +8 -0
- package/dist/dap/transport.js +30 -0
- package/dist/dap/types.d.ts +50 -0
- package/dist/dap/types.js +2 -0
- package/dist/db/client.d.ts +22 -0
- package/dist/db/client.js +39 -0
- package/dist/db/index.d.ts +6 -0
- package/dist/db/index.js +4 -0
- package/dist/db/migrate.d.ts +9 -0
- package/dist/db/migrate.js +15 -0
- package/dist/db/schema.d.ts +965 -0
- package/dist/db/schema.js +112 -0
- package/dist/db/types.d.ts +11 -0
- package/dist/db/types.js +1 -0
- package/dist/llm/index.d.ts +13 -0
- package/dist/llm/index.js +8 -0
- package/dist/llm/protocols/openai-compat.d.ts +139 -0
- package/dist/llm/protocols/openai-compat.js +214 -0
- package/dist/llm/protocols/utils/index.d.ts +2 -0
- package/dist/llm/protocols/utils/index.js +2 -0
- package/dist/llm/protocols/utils/lifecycle.d.ts +23 -0
- package/dist/llm/protocols/utils/lifecycle.js +46 -0
- package/dist/llm/protocols/utils/tool-stream.d.ts +46 -0
- package/dist/llm/protocols/utils/tool-stream.js +94 -0
- package/dist/llm/provider-error.d.ts +5 -0
- package/dist/llm/provider-error.js +33 -0
- package/dist/llm/provider.d.ts +32 -0
- package/dist/llm/provider.js +191 -0
- package/dist/llm/registry.d.ts +44 -0
- package/dist/llm/registry.js +107 -0
- package/dist/llm/retry.d.ts +37 -0
- package/dist/llm/retry.js +82 -0
- package/dist/llm/routing.d.ts +36 -0
- package/dist/llm/routing.js +53 -0
- package/dist/llm/schema/errors.d.ts +88 -0
- package/dist/llm/schema/errors.js +33 -0
- package/dist/llm/schema/events.d.ts +135 -0
- package/dist/llm/schema/events.js +35 -0
- package/dist/llm/schema/ids.d.ts +22 -0
- package/dist/llm/schema/ids.js +3 -0
- package/dist/llm/schema/index.d.ts +5 -0
- package/dist/llm/schema/index.js +5 -0
- package/dist/llm/schema/messages.d.ts +97 -0
- package/dist/llm/schema/messages.js +18 -0
- package/dist/llm/schema/options.d.ts +54 -0
- package/dist/llm/schema/options.js +54 -0
- package/dist/llm/token.d.ts +2 -0
- package/dist/llm/token.js +13 -0
- package/dist/llm/transport.d.ts +31 -0
- package/dist/llm/transport.js +165 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.js +3 -0
- package/dist/plugins/builtin.d.ts +6 -0
- package/dist/plugins/builtin.js +54 -0
- package/dist/plugins/hooks.d.ts +3 -0
- package/dist/plugins/hooks.js +79 -0
- package/dist/plugins/index.d.ts +9 -0
- package/dist/plugins/index.js +8 -0
- package/dist/plugins/init.d.ts +23 -0
- package/dist/plugins/init.js +30 -0
- package/dist/plugins/lifecycle.d.ts +6 -0
- package/dist/plugins/lifecycle.js +74 -0
- package/dist/plugins/loader.d.ts +16 -0
- package/dist/plugins/loader.js +68 -0
- package/dist/plugins/logger.d.ts +4 -0
- package/dist/plugins/logger.js +31 -0
- package/dist/plugins/registry.d.ts +7 -0
- package/dist/plugins/registry.js +24 -0
- package/dist/plugins/types.d.ts +113 -0
- package/dist/plugins/types.js +1 -0
- package/dist/project/detect.d.ts +4 -0
- package/dist/project/detect.js +131 -0
- package/dist/project/index.d.ts +4 -0
- package/dist/project/index.js +2 -0
- package/dist/project/project.d.ts +23 -0
- package/dist/project/project.js +87 -0
- package/dist/project/resolve.d.ts +8 -0
- package/dist/project/resolve.js +81 -0
- package/dist/server/agent-manager.d.ts +32 -0
- package/dist/server/agent-manager.js +54 -0
- package/dist/server/app.d.ts +5 -0
- package/dist/server/app.js +75 -0
- package/dist/server/context.d.ts +20 -0
- package/dist/server/context.js +47 -0
- package/dist/server/dev.d.ts +11 -0
- package/dist/server/dev.js +83 -0
- package/dist/server/index.d.ts +11 -0
- package/dist/server/index.js +7 -0
- package/dist/server/middleware/auth.d.ts +15 -0
- package/dist/server/middleware/auth.js +29 -0
- package/dist/server/middleware/cors.d.ts +16 -0
- package/dist/server/middleware/cors.js +44 -0
- package/dist/server/middleware/error.d.ts +15 -0
- package/dist/server/middleware/error.js +11 -0
- package/dist/server/permission/interactive.d.ts +24 -0
- package/dist/server/permission/interactive.js +56 -0
- package/dist/server/permission/store.d.ts +30 -0
- package/dist/server/permission/store.js +47 -0
- package/dist/server/routes/agent.d.ts +4 -0
- package/dist/server/routes/agent.js +19 -0
- package/dist/server/routes/catalog.d.ts +42 -0
- package/dist/server/routes/catalog.js +194 -0
- package/dist/server/routes/chat.d.ts +8 -0
- package/dist/server/routes/chat.js +282 -0
- package/dist/server/routes/commands.d.ts +5 -0
- package/dist/server/routes/commands.js +17 -0
- package/dist/server/routes/config.d.ts +4 -0
- package/dist/server/routes/config.js +27 -0
- package/dist/server/routes/files.d.ts +4 -0
- package/dist/server/routes/files.js +183 -0
- package/dist/server/routes/filesystem.d.ts +29 -0
- package/dist/server/routes/filesystem.js +108 -0
- package/dist/server/routes/health.d.ts +3 -0
- package/dist/server/routes/health.js +13 -0
- package/dist/server/routes/permissions.d.ts +5 -0
- package/dist/server/routes/permissions.js +23 -0
- package/dist/server/routes/project.d.ts +4 -0
- package/dist/server/routes/project.js +51 -0
- package/dist/server/routes/provider.d.ts +16 -0
- package/dist/server/routes/provider.js +66 -0
- package/dist/server/routes/session.d.ts +4 -0
- package/dist/server/routes/session.js +130 -0
- package/dist/server/routes/tool.d.ts +4 -0
- package/dist/server/routes/tool.js +28 -0
- package/dist/server/routes/update.d.ts +14 -0
- package/dist/server/routes/update.js +49 -0
- package/dist/server/server.d.ts +43 -0
- package/dist/server/server.js +197 -0
- package/dist/server/types.d.ts +73 -0
- package/dist/server/types.js +2 -0
- package/dist/server/util/safe-path.d.ts +7 -0
- package/dist/server/util/safe-path.js +7 -0
- package/dist/session/archive.d.ts +15 -0
- package/dist/session/archive.js +129 -0
- package/dist/session/branch.d.ts +9 -0
- package/dist/session/branch.js +63 -0
- package/dist/session/compaction.d.ts +27 -0
- package/dist/session/compaction.js +192 -0
- package/dist/session/context.d.ts +16 -0
- package/dist/session/context.js +173 -0
- package/dist/session/index.d.ts +10 -0
- package/dist/session/index.js +10 -0
- package/dist/session/message.d.ts +22 -0
- package/dist/session/message.js +145 -0
- package/dist/session/session.d.ts +37 -0
- package/dist/session/session.js +144 -0
- package/dist/session/snapshot.d.ts +11 -0
- package/dist/session/snapshot.js +60 -0
- package/dist/session/squash.d.ts +9 -0
- package/dist/session/squash.js +88 -0
- package/dist/session/token.d.ts +10 -0
- package/dist/session/token.js +33 -0
- package/dist/session/types.d.ts +122 -0
- package/dist/session/types.js +1 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/index.js +1 -0
- package/dist/shared/types/agent.d.ts +202 -0
- package/dist/shared/types/agent.js +1 -0
- package/dist/shared/types/base.d.ts +32 -0
- package/dist/shared/types/base.js +1 -0
- package/dist/shared/types/config.d.ts +104 -0
- package/dist/shared/types/config.js +1 -0
- package/dist/shared/types/index.d.ts +6 -0
- package/dist/shared/types/index.js +1 -0
- package/dist/shared/types/llm.d.ts +122 -0
- package/dist/shared/types/llm.js +1 -0
- package/dist/shared/types/message.d.ts +71 -0
- package/dist/shared/types/message.js +1 -0
- package/dist/shared/types/tool.d.ts +134 -0
- package/dist/shared/types/tool.js +1 -0
- package/dist/shared/utils/path.d.ts +15 -0
- package/dist/shared/utils/path.js +23 -0
- package/dist/shared/utils.d.ts +5 -0
- package/dist/shared/utils.js +10 -0
- package/dist/tools/builtin/bash.d.ts +12 -0
- package/dist/tools/builtin/bash.js +121 -0
- package/dist/tools/builtin/dap.d.ts +23 -0
- package/dist/tools/builtin/dap.js +231 -0
- package/dist/tools/builtin/edit.d.ts +12 -0
- package/dist/tools/builtin/edit.js +151 -0
- package/dist/tools/builtin/glob.d.ts +11 -0
- package/dist/tools/builtin/glob.js +120 -0
- package/dist/tools/builtin/grep.d.ts +6 -0
- package/dist/tools/builtin/grep.js +141 -0
- package/dist/tools/builtin/read.d.ts +6 -0
- package/dist/tools/builtin/read.js +73 -0
- package/dist/tools/builtin/resolvers.d.ts +12 -0
- package/dist/tools/builtin/resolvers.js +79 -0
- package/dist/tools/builtin/task.d.ts +9 -0
- package/dist/tools/builtin/task.js +100 -0
- package/dist/tools/builtin/write.d.ts +6 -0
- package/dist/tools/builtin/write.js +36 -0
- package/dist/tools/builtin/yield.d.ts +9 -0
- package/dist/tools/builtin/yield.js +40 -0
- package/dist/tools/executor.d.ts +9 -0
- package/dist/tools/executor.js +54 -0
- package/dist/tools/hashline/index.d.ts +2 -0
- package/dist/tools/hashline/index.js +3 -0
- package/dist/tools/hashline/patch.d.ts +48 -0
- package/dist/tools/hashline/patch.js +201 -0
- package/dist/tools/index.d.ts +30 -0
- package/dist/tools/index.js +55 -0
- package/dist/tools/permission.d.ts +13 -0
- package/dist/tools/permission.js +39 -0
- package/dist/tools/registry.d.ts +15 -0
- package/dist/tools/registry.js +54 -0
- package/dist/tools/resolver.d.ts +15 -0
- package/dist/tools/resolver.js +47 -0
- package/dist/tools/truncate.d.ts +8 -0
- package/dist/tools/truncate.js +50 -0
- package/dist/tools/types.d.ts +101 -0
- package/dist/tools/types.js +1 -0
- package/dist/tools/validate.d.ts +8 -0
- package/dist/tools/validate.js +130 -0
- package/dist/tools/websearch/fetch.d.ts +11 -0
- package/dist/tools/websearch/fetch.js +21 -0
- package/dist/tools/websearch/index.d.ts +19 -0
- package/dist/tools/websearch/index.js +78 -0
- package/dist/tools/websearch/providers/brave.d.ts +5 -0
- package/dist/tools/websearch/providers/brave.js +53 -0
- package/dist/tools/websearch/providers/duckduckgo.d.ts +3 -0
- package/dist/tools/websearch/providers/duckduckgo.js +75 -0
- package/dist/tools/websearch/providers/tavily.d.ts +11 -0
- package/dist/tools/websearch/providers/tavily.js +89 -0
- package/dist/tools/websearch/types.d.ts +51 -0
- package/dist/tools/websearch/types.js +18 -0
- package/dist/tools/websearch/websearch.d.ts +10 -0
- package/dist/tools/websearch/websearch.js +48 -0
- package/dist/update/index.d.ts +10 -0
- package/dist/update/index.js +6 -0
- package/dist/update/ipc.d.ts +15 -0
- package/dist/update/ipc.js +41 -0
- package/dist/update/scheduler.d.ts +34 -0
- package/dist/update/scheduler.js +57 -0
- package/dist/update/snapshot.d.ts +39 -0
- package/dist/update/snapshot.js +99 -0
- package/dist/update/updater.d.ts +48 -0
- package/dist/update/updater.js +83 -0
- package/dist/update/version.d.ts +18 -0
- package/dist/update/version.js +49 -0
- package/drizzle/0000_magical_nightshade.sql +55 -0
- package/drizzle/0001_chemical_doctor_faustus.sql +13 -0
- package/drizzle/0002_amusing_micromacro.sql +12 -0
- package/drizzle/0003_regular_purifiers.sql +2 -0
- package/drizzle/meta/0000_snapshot.json +448 -0
- package/drizzle/meta/0001_snapshot.json +539 -0
- package/drizzle/meta/0002_snapshot.json +633 -0
- package/drizzle/meta/0003_snapshot.json +645 -0
- package/drizzle/meta/_journal.json +34 -0
- package/package.json +100 -8
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// src/cli/index.ts — c0de CLI bin entry.
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { parseArgs } from 'node:util';
|
|
5
|
+
import { loadConfig } from '../core/config.js';
|
|
6
|
+
import { createDB, migrateDB } from '../db/index.js';
|
|
7
|
+
import { runAcpCommand } from './commands/acp.js';
|
|
8
|
+
import { runChatCommand } from './commands/chat.js';
|
|
9
|
+
import { runConfigCommand } from './commands/config.js';
|
|
10
|
+
import { runInitCommand } from './commands/init.js';
|
|
11
|
+
import { runPluginCommand } from './commands/plugin.js';
|
|
12
|
+
import { runServeCommand } from './commands/serve.js';
|
|
13
|
+
import { runUpdateCommand } from './commands/update.js';
|
|
14
|
+
import { buildAgentDeps } from './deps.js';
|
|
15
|
+
const COMMANDS = [
|
|
16
|
+
{
|
|
17
|
+
name: 'chat',
|
|
18
|
+
description: 'Ask a one-shot question; print the answer.',
|
|
19
|
+
options: [
|
|
20
|
+
{ name: 'model', type: 'string' },
|
|
21
|
+
{ name: 'format', type: 'string' },
|
|
22
|
+
{ name: 'yes', type: 'boolean', short: 'y' },
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: 'serve',
|
|
27
|
+
description: 'Start the HTTP server (default when no command given).',
|
|
28
|
+
options: [
|
|
29
|
+
{ name: 'port', type: 'string' },
|
|
30
|
+
{ name: 'open', type: 'boolean' },
|
|
31
|
+
{ name: 'restore', type: 'string' },
|
|
32
|
+
{ name: 'handoff-port', type: 'string' },
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'init',
|
|
37
|
+
description: 'Create a .c0de/config.json in the current project.',
|
|
38
|
+
options: [{ name: 'force', type: 'boolean', short: 'f' }],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'config',
|
|
42
|
+
description: 'Get or set configuration values.',
|
|
43
|
+
options: [{ name: 'global', type: 'boolean', short: 'g' }],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'plugin',
|
|
47
|
+
description: 'List or enable plugins.',
|
|
48
|
+
options: [],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'acp',
|
|
52
|
+
description: 'Run in Agent Client Protocol mode (editor integration).',
|
|
53
|
+
options: [],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: 'update',
|
|
57
|
+
description: 'Check npm registry for a newer version (--apply to hot-update).',
|
|
58
|
+
options: [{ name: 'apply', type: 'boolean' }],
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
async function dispatch(argv, overrides = {}) {
|
|
62
|
+
const [command, ...rest] = argv;
|
|
63
|
+
const name = command ?? 'serve';
|
|
64
|
+
if (name === 'serve' && overrides.runServe) {
|
|
65
|
+
await overrides.runServe();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const spec = COMMANDS.find((c) => c.name === name);
|
|
69
|
+
if (!spec)
|
|
70
|
+
throw new Error(`cli: unknown command "${name}"`);
|
|
71
|
+
const { values, positionals } = parseArgs({
|
|
72
|
+
options: Object.fromEntries((spec.options ?? []).map((o) => [
|
|
73
|
+
o.name,
|
|
74
|
+
{ type: o.type, ...(o.short ? { short: o.short } : {}) },
|
|
75
|
+
])),
|
|
76
|
+
args: rest,
|
|
77
|
+
allowPositionals: true,
|
|
78
|
+
strict: true,
|
|
79
|
+
});
|
|
80
|
+
const args = { options: values, positionals };
|
|
81
|
+
const cwd = process.cwd();
|
|
82
|
+
switch (name) {
|
|
83
|
+
case 'serve': {
|
|
84
|
+
await runServeCommand({ args, cwd });
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
case 'chat': {
|
|
88
|
+
const config = await loadConfig(cwd);
|
|
89
|
+
const db = await createDB({ driver: 'pglite' });
|
|
90
|
+
await migrateDB(db);
|
|
91
|
+
try {
|
|
92
|
+
const deps = await buildAgentDeps(config, { db, cwd });
|
|
93
|
+
await runChatCommand({ args, config, deps });
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
await db.close();
|
|
97
|
+
}
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
case 'init': {
|
|
101
|
+
await runInitCommand({ args, cwd });
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
case 'config': {
|
|
105
|
+
await runConfigCommand({ args, cwd });
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
case 'plugin': {
|
|
109
|
+
await runPluginCommand({ args, cwd });
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
case 'acp': {
|
|
113
|
+
const config = await loadConfig(cwd);
|
|
114
|
+
const db = await createDB({ driver: 'pglite' });
|
|
115
|
+
await migrateDB(db);
|
|
116
|
+
try {
|
|
117
|
+
const deps = await buildAgentDeps(config, { db, cwd });
|
|
118
|
+
await runAcpCommand({ config, deps });
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
await db.close();
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
case 'update': {
|
|
126
|
+
await runUpdateCommand({ args, cwd });
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
default: {
|
|
130
|
+
throw new Error(`cli: unknown command "${name}"`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async function main() {
|
|
135
|
+
const argv = process.argv.slice(2);
|
|
136
|
+
try {
|
|
137
|
+
await dispatch(argv);
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
export { COMMANDS, dispatch };
|
|
145
|
+
// bin 入口:仅在直接执行时运行 main(非被 import)。
|
|
146
|
+
const isMain = process.argv[1] === fileURLToPath(import.meta.url);
|
|
147
|
+
if (isMain) {
|
|
148
|
+
void main();
|
|
149
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type ACPRequest = {
|
|
2
|
+
id: number | string | null;
|
|
3
|
+
method: string;
|
|
4
|
+
params: Record<string, unknown>;
|
|
5
|
+
};
|
|
6
|
+
type ACPHandler = (params: Record<string, unknown>) => Promise<Record<string, unknown>>;
|
|
7
|
+
type AcpLoopOptions = {
|
|
8
|
+
reader: AsyncGenerator<string>;
|
|
9
|
+
writer: (line: string) => void;
|
|
10
|
+
handlers: Record<string, ACPHandler>;
|
|
11
|
+
};
|
|
12
|
+
declare function parseACPRequest(line: string): ACPRequest | null;
|
|
13
|
+
declare function formatACPResponse(id: number | string | null, result: Record<string, unknown>): string;
|
|
14
|
+
declare function formatACPError(id: number | string | null, code: number, message: string): string;
|
|
15
|
+
declare function formatACPEvent(method: string, params: Record<string, unknown>): string;
|
|
16
|
+
declare function runAcpLoop(opts: AcpLoopOptions): Promise<void>;
|
|
17
|
+
export type { ACPHandler, ACPRequest, AcpLoopOptions };
|
|
18
|
+
export { formatACPError, formatACPEvent, formatACPResponse, parseACPRequest, runAcpLoop };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
function parseACPRequest(line) {
|
|
2
|
+
let obj;
|
|
3
|
+
try {
|
|
4
|
+
obj = JSON.parse(line);
|
|
5
|
+
}
|
|
6
|
+
catch {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
if (obj === null || typeof obj !== 'object')
|
|
10
|
+
return null;
|
|
11
|
+
const o = obj;
|
|
12
|
+
if (typeof o.method !== 'string')
|
|
13
|
+
return null;
|
|
14
|
+
return {
|
|
15
|
+
id: (o.id ?? null),
|
|
16
|
+
method: o.method,
|
|
17
|
+
params: (o.params ?? {}),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function formatACPResponse(id, result) {
|
|
21
|
+
return JSON.stringify({ jsonrpc: '2.0', id, result });
|
|
22
|
+
}
|
|
23
|
+
function formatACPError(id, code, message) {
|
|
24
|
+
return JSON.stringify({ jsonrpc: '2.0', id, error: { code, message } });
|
|
25
|
+
}
|
|
26
|
+
function formatACPEvent(method, params) {
|
|
27
|
+
return JSON.stringify({ jsonrpc: '2.0', method, params });
|
|
28
|
+
}
|
|
29
|
+
async function runAcpLoop(opts) {
|
|
30
|
+
for await (const line of opts.reader) {
|
|
31
|
+
const trimmed = line.trim();
|
|
32
|
+
if (!trimmed)
|
|
33
|
+
continue;
|
|
34
|
+
const req = parseACPRequest(trimmed);
|
|
35
|
+
if (!req) {
|
|
36
|
+
opts.writer(formatACPError(null, -32700, 'Parse error'));
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const handler = opts.handlers[req.method];
|
|
40
|
+
if (!handler) {
|
|
41
|
+
if (req.id !== null)
|
|
42
|
+
opts.writer(formatACPError(req.id, -32601, `Method not found: ${req.method}`));
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const result = await handler(req.params);
|
|
47
|
+
if (req.id !== null)
|
|
48
|
+
opts.writer(formatACPResponse(req.id, result));
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
if (req.id !== null) {
|
|
52
|
+
opts.writer(formatACPError(req.id, -32603, err instanceof Error ? err.message : String(err)));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export { formatACPError, formatACPEvent, formatACPResponse, parseACPRequest, runAcpLoop };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { LoopDeps } from '../../core/loop.js';
|
|
2
|
+
import type { AgentEvent } from '../../shared/types/agent.js';
|
|
3
|
+
import type { Config } from '../../shared/types/config.js';
|
|
4
|
+
type PrintOptions = {
|
|
5
|
+
model?: string;
|
|
6
|
+
format?: 'text' | 'json';
|
|
7
|
+
maxTokens?: number;
|
|
8
|
+
/** 事件观察回调(CLI 用于把 tool/thinking 写到 stderr)。 */
|
|
9
|
+
onEvent?: (event: AgentEvent) => void;
|
|
10
|
+
};
|
|
11
|
+
/** 从事件流累积 assistant 文本。纯函数。 */
|
|
12
|
+
declare function collectAssistantText(events: AgentEvent[]): string;
|
|
13
|
+
/** Print 模式:临时会话 → agent → 收集文本 → 返回。 */
|
|
14
|
+
declare function runPrintMode(config: Config, message: string, deps: LoopDeps, opts?: PrintOptions): Promise<string>;
|
|
15
|
+
export type { PrintOptions };
|
|
16
|
+
export { collectAssistantText, runPrintMode };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { createAgent, runAgent } from '../../core/agent.js';
|
|
2
|
+
import { createSession } from '../../session/session.js';
|
|
3
|
+
/** 从事件流累积 assistant 文本。纯函数。 */
|
|
4
|
+
function collectAssistantText(events) {
|
|
5
|
+
let text = '';
|
|
6
|
+
for (const e of events) {
|
|
7
|
+
if (e._tag === 'text_delta')
|
|
8
|
+
text += e.text;
|
|
9
|
+
}
|
|
10
|
+
return text;
|
|
11
|
+
}
|
|
12
|
+
/** Print 模式:临时会话 → agent → 收集文本 → 返回。 */
|
|
13
|
+
async function runPrintMode(config, message, deps, opts = {}) {
|
|
14
|
+
const session = await createSession(deps.db, 'cli-print');
|
|
15
|
+
const agentConfig = {
|
|
16
|
+
provider: config.defaultProvider,
|
|
17
|
+
model: opts.model ?? config.defaultModel,
|
|
18
|
+
tools: config.tools.enabled,
|
|
19
|
+
plugins: config.plugins.enabled,
|
|
20
|
+
...(opts.maxTokens !== undefined ? { maxTokens: opts.maxTokens } : {}),
|
|
21
|
+
};
|
|
22
|
+
const state = await createAgent(session, agentConfig, deps);
|
|
23
|
+
const events = [];
|
|
24
|
+
for await (const event of runAgent(state, [{ _tag: 'text', text: message }], deps)) {
|
|
25
|
+
events.push(event);
|
|
26
|
+
opts.onEvent?.(event);
|
|
27
|
+
}
|
|
28
|
+
return collectAssistantText(events);
|
|
29
|
+
}
|
|
30
|
+
export { collectAssistantText, runPrintMode };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
type OptionType = 'string' | 'boolean';
|
|
2
|
+
type CommandOption = {
|
|
3
|
+
name: string;
|
|
4
|
+
type: OptionType;
|
|
5
|
+
short?: string;
|
|
6
|
+
default?: unknown;
|
|
7
|
+
};
|
|
8
|
+
type CommandSpec = {
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
options?: CommandOption[];
|
|
12
|
+
};
|
|
13
|
+
type CommandArgs = {
|
|
14
|
+
options: Record<string, unknown>;
|
|
15
|
+
positionals: string[];
|
|
16
|
+
};
|
|
17
|
+
declare function parseCommand(spec: CommandSpec, argv: string[]): CommandArgs;
|
|
18
|
+
export type { CommandArgs, CommandOption, CommandSpec, OptionType };
|
|
19
|
+
export { parseCommand };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util';
|
|
2
|
+
function parseCommand(spec, argv) {
|
|
3
|
+
const opts = {};
|
|
4
|
+
const defaults = {};
|
|
5
|
+
for (const o of spec.options ?? []) {
|
|
6
|
+
const key = o.name;
|
|
7
|
+
opts[key] = { type: o.type, ...(o.short ? { short: o.short } : {}) };
|
|
8
|
+
if (o.default !== undefined)
|
|
9
|
+
defaults[key] = o.default;
|
|
10
|
+
}
|
|
11
|
+
const { values, positionals } = parseArgs({
|
|
12
|
+
options: opts,
|
|
13
|
+
args: argv,
|
|
14
|
+
allowPositionals: true,
|
|
15
|
+
strict: true,
|
|
16
|
+
});
|
|
17
|
+
const merged = { ...defaults };
|
|
18
|
+
for (const k of Object.keys(opts)) {
|
|
19
|
+
if (values[k] !== undefined) {
|
|
20
|
+
merged[k] = values[k];
|
|
21
|
+
}
|
|
22
|
+
else if (opts[k]?.type === 'boolean' && defaults[k] === undefined) {
|
|
23
|
+
merged[k] = false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return { options: merged, positionals };
|
|
27
|
+
}
|
|
28
|
+
export { parseCommand };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare function platformOpener(platform: string): string;
|
|
2
|
+
type SpawnLike = (cmd: string, args: string[]) => unknown;
|
|
3
|
+
type OpenBrowserOptions = {
|
|
4
|
+
platform?: string;
|
|
5
|
+
/** 测试注入。 */
|
|
6
|
+
spawnFn?: SpawnLike;
|
|
7
|
+
};
|
|
8
|
+
declare function openBrowser(url: string, opts?: OpenBrowserOptions): Promise<void>;
|
|
9
|
+
declare function printStartupBanner(url: string, write?: (s: string) => void): void;
|
|
10
|
+
export type { OpenBrowserOptions, SpawnLike };
|
|
11
|
+
export { openBrowser, platformOpener, printStartupBanner };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
function platformOpener(platform) {
|
|
3
|
+
if (platform === 'darwin')
|
|
4
|
+
return 'open';
|
|
5
|
+
if (platform === 'win32')
|
|
6
|
+
return 'start';
|
|
7
|
+
return 'xdg-open';
|
|
8
|
+
}
|
|
9
|
+
async function openBrowser(url, opts = {}) {
|
|
10
|
+
const platform = opts.platform ?? process.platform;
|
|
11
|
+
const cmd = platformOpener(platform);
|
|
12
|
+
const doSpawn = opts.spawnFn ??
|
|
13
|
+
((c, a) => {
|
|
14
|
+
const child = spawn(c, a, { detached: true, stdio: 'ignore' });
|
|
15
|
+
child.unref();
|
|
16
|
+
return child;
|
|
17
|
+
});
|
|
18
|
+
doSpawn(cmd, [url]);
|
|
19
|
+
}
|
|
20
|
+
function printStartupBanner(url, write = process.stderr.write.bind(process.stderr)) {
|
|
21
|
+
write(`\nc0de-agent server running at ${url}\nOpen this URL in your browser.\n\n`);
|
|
22
|
+
}
|
|
23
|
+
export { openBrowser, platformOpener, printStartupBanner };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type PromptInterface = {
|
|
2
|
+
question: (q: string) => Promise<string>;
|
|
3
|
+
close: () => void;
|
|
4
|
+
};
|
|
5
|
+
type ConfirmOptions = {
|
|
6
|
+
defaultYes?: boolean;
|
|
7
|
+
/** 测试注入。 */
|
|
8
|
+
rl?: PromptInterface;
|
|
9
|
+
};
|
|
10
|
+
declare function confirm(question: string, opts?: ConfirmOptions): Promise<boolean>;
|
|
11
|
+
export type { ConfirmOptions, PromptInterface };
|
|
12
|
+
export { confirm };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import readline from 'node:readline/promises';
|
|
2
|
+
async function confirm(question, opts = {}) {
|
|
3
|
+
const defaultYes = opts.defaultYes ?? false;
|
|
4
|
+
const hint = defaultYes ? '[Y/n]' : '[y/N]';
|
|
5
|
+
const rl = opts.rl ?? readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
6
|
+
const own = !opts.rl;
|
|
7
|
+
try {
|
|
8
|
+
const answer = (await rl.question(`${question} ${hint} `)).trim().toLowerCase();
|
|
9
|
+
if (answer === '')
|
|
10
|
+
return defaultYes;
|
|
11
|
+
return answer === 'y' || answer === 'yes';
|
|
12
|
+
}
|
|
13
|
+
finally {
|
|
14
|
+
if (own)
|
|
15
|
+
rl.close();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export { confirm };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AgentConfig, AgentEvent, AgentState, AgentStatus } from '../shared/types/agent.js';
|
|
2
|
+
import type { MessageContent, Session } from '../shared/types/message.js';
|
|
3
|
+
import type { AgentDependencies } from './types.js';
|
|
4
|
+
declare function createAgent(session: Session, config: AgentConfig, deps: AgentDependencies): Promise<AgentState>;
|
|
5
|
+
declare function runAgent(state: AgentState, userInput: MessageContent[], deps: AgentDependencies): AsyncGenerator<AgentEvent>;
|
|
6
|
+
declare function pauseAgent(state: AgentState): void;
|
|
7
|
+
declare function resumeAgent(state: AgentState): void;
|
|
8
|
+
declare function abortAgent(state: AgentState): void;
|
|
9
|
+
declare function getAgentStatus(state: AgentState): AgentStatus;
|
|
10
|
+
/** 判断 agent 是否处于暂停态(spec §19.2)。 */
|
|
11
|
+
declare function isAgentPaused(state: AgentState): boolean;
|
|
12
|
+
export { abortAgent, createAgent, getAgentStatus, isAgentPaused, pauseAgent, resumeAgent, runAgent };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { appendMessage, getMessages } from '../session/message.js';
|
|
2
|
+
import { getLLMSegments } from '../session/session.js';
|
|
3
|
+
import { generateId } from '../shared/index.js';
|
|
4
|
+
import { listTools } from '../tools/registry.js';
|
|
5
|
+
import { estimateBudget } from './context.js';
|
|
6
|
+
import { agentLoop } from './loop.js';
|
|
7
|
+
import { DEFAULT_SESSION_TITLE, generateSessionTitle } from './title.js';
|
|
8
|
+
async function createAgent(session, config, deps) {
|
|
9
|
+
const messages = await getMessages(deps.db, session.id);
|
|
10
|
+
const used = estimateBudget(messages);
|
|
11
|
+
// 加载会话已有分段:每次 /api/chat 创建新 agent 时,从 DB 恢复完整段历史,
|
|
12
|
+
// 使本轮新增的 segment/call 追加到既有历史而非覆盖(saveLLMSegments 为全量写回)。
|
|
13
|
+
const segments = await getLLMSegments(deps.db, session.id);
|
|
14
|
+
const allTools = listTools(deps.toolRegistry, { config: {}, cwd: deps.cwd });
|
|
15
|
+
const tools = allTools.filter((t) => config.tools.includes(t.name));
|
|
16
|
+
return {
|
|
17
|
+
id: generateId(),
|
|
18
|
+
session,
|
|
19
|
+
messages,
|
|
20
|
+
tools,
|
|
21
|
+
config,
|
|
22
|
+
status: { _tag: 'idle' },
|
|
23
|
+
abortController: new AbortController(),
|
|
24
|
+
steeringQueue: [],
|
|
25
|
+
segments,
|
|
26
|
+
tokenBudget: {
|
|
27
|
+
total: 128_000,
|
|
28
|
+
reserved: 25_600,
|
|
29
|
+
available: 102_400,
|
|
30
|
+
historyBudget: 76_800,
|
|
31
|
+
used,
|
|
32
|
+
keepRecent: 12_800,
|
|
33
|
+
},
|
|
34
|
+
calibrationFactor: 1.0,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
async function* runAgent(state, userInput, deps) {
|
|
38
|
+
// 幂等重发保护:若 DB 末尾已是相同 user message(服务重启后续传场景),
|
|
39
|
+
// 跳过 append 避免重复。比较 text parts 内容即可区分不同消息。
|
|
40
|
+
const last = state.messages[state.messages.length - 1];
|
|
41
|
+
const isDupUser = last?.role === 'user' &&
|
|
42
|
+
last.content.length === userInput.length &&
|
|
43
|
+
last.content.every((p, i) => {
|
|
44
|
+
const q = userInput[i];
|
|
45
|
+
return p._tag === 'text' && q?._tag === 'text' ? p.text === q.text : false;
|
|
46
|
+
});
|
|
47
|
+
if (!isDupUser) {
|
|
48
|
+
await appendMessage(deps.db, state.session.id, {
|
|
49
|
+
role: 'user',
|
|
50
|
+
content: userInput,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
// 标题生成用纯文本(join text parts),忽略 image/tool 等非文本 part。
|
|
54
|
+
const titleText = userInput
|
|
55
|
+
.filter((p) => p._tag === 'text')
|
|
56
|
+
.map((p) => (p._tag === 'text' ? p.text : ''))
|
|
57
|
+
.join('');
|
|
58
|
+
// 第一条用户消息后,后台为会话生成简短标题(fire-and-forget)。
|
|
59
|
+
// 条件:标题仍是默认占位 + 持久化前无任何消息(即首条消息)。
|
|
60
|
+
// 失败被吞掉,绝不阻塞主对话流。
|
|
61
|
+
if (state.session.title === DEFAULT_SESSION_TITLE && state.messages.length === 0) {
|
|
62
|
+
void generateSessionTitle({
|
|
63
|
+
db: deps.db,
|
|
64
|
+
llmRegistry: deps.llmRegistry,
|
|
65
|
+
config: deps.config,
|
|
66
|
+
...(deps.titleChatFn ? { chatFn: deps.titleChatFn } : {}),
|
|
67
|
+
}, state.session.id, titleText, state.config.provider, state.config.model).catch(() => { });
|
|
68
|
+
}
|
|
69
|
+
state.status = { _tag: 'running', turnCount: 0 };
|
|
70
|
+
yield* agentLoop(state, deps);
|
|
71
|
+
}
|
|
72
|
+
function pauseAgent(state) {
|
|
73
|
+
if (state.status._tag !== 'running')
|
|
74
|
+
return;
|
|
75
|
+
state.status = { _tag: 'paused', pauseReason: 'User requested pause' };
|
|
76
|
+
}
|
|
77
|
+
function resumeAgent(state) {
|
|
78
|
+
if (state.status._tag !== 'paused')
|
|
79
|
+
return;
|
|
80
|
+
state.status = { _tag: 'running', turnCount: 0 };
|
|
81
|
+
}
|
|
82
|
+
function abortAgent(state) {
|
|
83
|
+
state.abortController.abort();
|
|
84
|
+
if (state.status._tag === 'running' || state.status._tag === 'paused') {
|
|
85
|
+
state.status = { _tag: 'stopped', reason: 'aborted' };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function getAgentStatus(state) {
|
|
89
|
+
return state.status;
|
|
90
|
+
}
|
|
91
|
+
/** 判断 agent 是否处于暂停态(spec §19.2)。 */
|
|
92
|
+
function isAgentPaused(state) {
|
|
93
|
+
return state.status._tag === 'paused';
|
|
94
|
+
}
|
|
95
|
+
export { abortAgent, createAgent, getAgentStatus, isAgentPaused, pauseAgent, resumeAgent, runAgent };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AgentDefinition } from './types.js';
|
|
2
|
+
/** 通用 subagent worker 骨架(叠加角色 prompt)。 */
|
|
3
|
+
declare const WORKER_BASE = "You are a worker agent for delegated tasks.\n\nYou have FULL access to the tools provided. Use them as needed to complete the assigned work.\n\n<directives>\n- You MUST finish only the assigned work and return the minimum useful result. Do not repeat what you wrote to filesystem.\n- You MUST be concise. NEVER include filler, repetition, or tool transcripts. The user cannot see you. Your result is just notes for the main agent.\n- You SHOULD prefer narrow lookups (grep/glob), then read only the needed ranges. Ignore anything beyond your scope.\n- You SHOULD prefer edits to existing files over creating new ones.\n- You NEVER create documentation files (*.md, README) unless explicitly requested.\n- You MUST follow the assignment exactly.\n</directives>\n\nWhen done, call the `yield` tool with your structured result. This is the ONLY way to return a final result.";
|
|
4
|
+
/** 6 个内置 agent(2 primary + 4 subagent)。 */
|
|
5
|
+
declare const BUILTIN_AGENTS: AgentDefinition[];
|
|
6
|
+
export { BUILTIN_AGENTS, WORKER_BASE };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/** 通用 subagent worker 骨架(叠加角色 prompt)。 */
|
|
2
|
+
const WORKER_BASE = `You are a worker agent for delegated tasks.
|
|
3
|
+
|
|
4
|
+
You have FULL access to the tools provided. Use them as needed to complete the assigned work.
|
|
5
|
+
|
|
6
|
+
<directives>
|
|
7
|
+
- You MUST finish only the assigned work and return the minimum useful result. Do not repeat what you wrote to filesystem.
|
|
8
|
+
- You MUST be concise. NEVER include filler, repetition, or tool transcripts. The user cannot see you. Your result is just notes for the main agent.
|
|
9
|
+
- You SHOULD prefer narrow lookups (grep/glob), then read only the needed ranges. Ignore anything beyond your scope.
|
|
10
|
+
- You SHOULD prefer edits to existing files over creating new ones.
|
|
11
|
+
- You NEVER create documentation files (*.md, README) unless explicitly requested.
|
|
12
|
+
- You MUST follow the assignment exactly.
|
|
13
|
+
</directives>
|
|
14
|
+
|
|
15
|
+
When done, call the \`yield\` tool with your structured result. This is the ONLY way to return a final result.`;
|
|
16
|
+
/** Plan 模式 primary agent 的 role prompt(覆盖 role section)。 */
|
|
17
|
+
const PLAN_ROLE = `You are c0de-agent in **Plan Mode**. Your job is to investigate the codebase and produce a clear, actionable plan — NOT to make changes directly.
|
|
18
|
+
|
|
19
|
+
- Use read-only tools (grep/glob/read) to understand the structure and relevant code.
|
|
20
|
+
- Ask clarifying questions when requirements are ambiguous.
|
|
21
|
+
- When ready, present a concrete implementation plan (files to touch, approach, risks).
|
|
22
|
+
- Do NOT use edit/write tools to modify code. You may run bash for investigation only.`;
|
|
23
|
+
/** 6 个内置 agent(2 primary + 4 subagent)。 */
|
|
24
|
+
const BUILTIN_AGENTS = [
|
|
25
|
+
{
|
|
26
|
+
name: 'default',
|
|
27
|
+
description: '通用助手(默认)。全工具,动态系统提示。',
|
|
28
|
+
systemPrompt: '',
|
|
29
|
+
mode: 'primary',
|
|
30
|
+
source: 'builtin',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'plan',
|
|
34
|
+
description: '计划模式(只读)。专注调研与方案设计,不直接改代码。',
|
|
35
|
+
tools: ['read', 'grep', 'glob', 'bash'],
|
|
36
|
+
systemPrompt: PLAN_ROLE,
|
|
37
|
+
mode: 'primary',
|
|
38
|
+
source: 'builtin',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'general',
|
|
42
|
+
description: '通用助手,全工具,可递归派生子任务。默认子 agent。',
|
|
43
|
+
systemPrompt: `${WORKER_BASE}\n\nYou are a general-purpose agent. Tackle any delegated task with the tools available.`,
|
|
44
|
+
mode: 'subagent',
|
|
45
|
+
maxRecursion: 1,
|
|
46
|
+
source: 'builtin',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'coder',
|
|
50
|
+
description: '实现专家,专注写代码实现。可读写文件、执行命令。',
|
|
51
|
+
systemPrompt: `${WORKER_BASE}\n\nYou specialize as: an implementation engineer. Bring exactly that expertise — write clean, correct, well-tested code. Prefer surgical edits. Verify your work (run relevant tests/commands) before yielding.`,
|
|
52
|
+
tools: ['read', 'write', 'edit', 'bash', 'grep', 'glob'],
|
|
53
|
+
mode: 'subagent',
|
|
54
|
+
maxRecursion: 0,
|
|
55
|
+
source: 'builtin',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'researcher',
|
|
59
|
+
description: '只读代码调研专家,用 grep/glob/read 摸清结构后返回压缩上下文。不改任何文件。',
|
|
60
|
+
systemPrompt: `${WORKER_BASE}\n\nYou specialize as: a read-only codebase scout. Map the relevant code, return compressed context (key files, structures, signatures). NEVER modify files. NEVER run write/edit/bash.`,
|
|
61
|
+
tools: ['grep', 'glob', 'read'],
|
|
62
|
+
mode: 'subagent',
|
|
63
|
+
maxRecursion: 0,
|
|
64
|
+
source: 'builtin',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'reviewer',
|
|
68
|
+
description: '代码审查专家,返回结构化发现(问题、建议、严重性)。',
|
|
69
|
+
systemPrompt: `${WORKER_BASE}\n\nYou specialize as: a code reviewer. Read the code under review, assess correctness/quality/risks. Return findings via yield as { findings: [{ severity, file, line, issue, suggestion }], summary: string }. severity ∈ 'critical' | 'warning' | 'info'.`,
|
|
70
|
+
tools: ['grep', 'glob', 'read'],
|
|
71
|
+
mode: 'subagent',
|
|
72
|
+
maxRecursion: 0,
|
|
73
|
+
source: 'builtin',
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
export { BUILTIN_AGENTS, WORKER_BASE };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AgentDefinition, AgentSource } from './types.js';
|
|
2
|
+
/** 解析单个 markdown 文件为 AgentDefinition。无 frontmatter 返回 null。 */
|
|
3
|
+
declare function loadAgentFile(filePath: string, source: AgentSource): Promise<AgentDefinition | null>;
|
|
4
|
+
/** 加载项目 agents 目录下所有 .md 为 AgentDefinition(源: project)。 */
|
|
5
|
+
declare function loadAgents(projectDir: string): Promise<AgentDefinition[]>;
|
|
6
|
+
export { loadAgentFile, loadAgents };
|