camelagi 0.5.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 +224 -0
- package/camelagi.mjs +2 -0
- package/config.example.yaml +107 -0
- package/dist/agent/agent-openai.js +206 -0
- package/dist/agent/agent-openai.js.map +1 -0
- package/dist/agent/agent-sdk.js +209 -0
- package/dist/agent/agent-sdk.js.map +1 -0
- package/dist/agent/tool-adapter.js +31 -0
- package/dist/agent/tool-adapter.js.map +1 -0
- package/dist/agent/types.js +3 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/agent.js +17 -0
- package/dist/agent.js.map +1 -0
- package/dist/approval-forward.js +42 -0
- package/dist/approval-forward.js.map +1 -0
- package/dist/approvals.js +151 -0
- package/dist/approvals.js.map +1 -0
- package/dist/boot.js +34 -0
- package/dist/boot.js.map +1 -0
- package/dist/bootstrap.js +451 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/camelagi-gateway.mjs +93611 -0
- package/dist/camelagi-gateway.mjs.map +7 -0
- package/dist/channels/adapter.js +10 -0
- package/dist/channels/adapter.js.map +1 -0
- package/dist/channels/discord.js +232 -0
- package/dist/channels/discord.js.map +1 -0
- package/dist/channels/handler.js +349 -0
- package/dist/channels/handler.js.map +1 -0
- package/dist/channels/index.js +19 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/channels/registry.js +71 -0
- package/dist/channels/registry.js.map +1 -0
- package/dist/channels/telegram.js +83 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/channels/types.js +3 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/chunker.js +102 -0
- package/dist/chunker.js.map +1 -0
- package/dist/cli/cmd-agents.js +65 -0
- package/dist/cli/cmd-agents.js.map +1 -0
- package/dist/cli/cmd-bootstrap.js +10 -0
- package/dist/cli/cmd-bootstrap.js.map +1 -0
- package/dist/cli/cmd-chat.js +32 -0
- package/dist/cli/cmd-chat.js.map +1 -0
- package/dist/cli/cmd-config.js +88 -0
- package/dist/cli/cmd-config.js.map +1 -0
- package/dist/cli/cmd-cron.js +120 -0
- package/dist/cli/cmd-cron.js.map +1 -0
- package/dist/cli/cmd-daemon.js +37 -0
- package/dist/cli/cmd-daemon.js.map +1 -0
- package/dist/cli/cmd-doctor.js +18 -0
- package/dist/cli/cmd-doctor.js.map +1 -0
- package/dist/cli/cmd-logs.js +30 -0
- package/dist/cli/cmd-logs.js.map +1 -0
- package/dist/cli/cmd-pairing.js +41 -0
- package/dist/cli/cmd-pairing.js.map +1 -0
- package/dist/cli/cmd-reset.js +39 -0
- package/dist/cli/cmd-reset.js.map +1 -0
- package/dist/cli/cmd-serve.js +30 -0
- package/dist/cli/cmd-serve.js.map +1 -0
- package/dist/cli/cmd-sessions.js +56 -0
- package/dist/cli/cmd-sessions.js.map +1 -0
- package/dist/cli/cmd-setup.js +11 -0
- package/dist/cli/cmd-setup.js.map +1 -0
- package/dist/cli/cmd-soul.js +43 -0
- package/dist/cli/cmd-soul.js.map +1 -0
- package/dist/cli/parse.js +50 -0
- package/dist/cli/parse.js.map +1 -0
- package/dist/cli/registry.js +15 -0
- package/dist/cli/registry.js.map +1 -0
- package/dist/cli.js +103 -0
- package/dist/cli.js.map +1 -0
- package/dist/compact.js +92 -0
- package/dist/compact.js.map +1 -0
- package/dist/config.js +153 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.js +21 -0
- package/dist/constants.js.map +1 -0
- package/dist/core/config.js +212 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/constants.js +21 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/errors.js +5 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/log.js +41 -0
- package/dist/core/log.js.map +1 -0
- package/dist/core/models.js +123 -0
- package/dist/core/models.js.map +1 -0
- package/dist/core/types.js +3 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/update-check.js +51 -0
- package/dist/core/update-check.js.map +1 -0
- package/dist/cron.js +81 -0
- package/dist/cron.js.map +1 -0
- package/dist/daemon.js +109 -0
- package/dist/daemon.js.map +1 -0
- package/dist/doctor.js +194 -0
- package/dist/doctor.js.map +1 -0
- package/dist/errors.js +5 -0
- package/dist/errors.js.map +1 -0
- package/dist/extensions/approval-forward.js +42 -0
- package/dist/extensions/approval-forward.js.map +1 -0
- package/dist/extensions/approvals.js +144 -0
- package/dist/extensions/approvals.js.map +1 -0
- package/dist/extensions/cron.js +306 -0
- package/dist/extensions/cron.js.map +1 -0
- package/dist/extensions/hooks.js +72 -0
- package/dist/extensions/hooks.js.map +1 -0
- package/dist/extensions/skills.js +97 -0
- package/dist/extensions/skills.js.map +1 -0
- package/dist/gateway/csrf.js +44 -0
- package/dist/gateway/csrf.js.map +1 -0
- package/dist/gateway/logger.js +81 -0
- package/dist/gateway/logger.js.map +1 -0
- package/dist/gateway/rate-limit.js +33 -0
- package/dist/gateway/rate-limit.js.map +1 -0
- package/dist/gateway/routes.js +315 -0
- package/dist/gateway/routes.js.map +1 -0
- package/dist/gateway/state.js +54 -0
- package/dist/gateway/state.js.map +1 -0
- package/dist/gateway/ws-handler.js +200 -0
- package/dist/gateway/ws-handler.js.map +1 -0
- package/dist/gateway-entry.js +16 -0
- package/dist/gateway-entry.js.map +1 -0
- package/dist/hooks.js +72 -0
- package/dist/hooks.js.map +1 -0
- package/dist/lanes.js +62 -0
- package/dist/lanes.js.map +1 -0
- package/dist/model.js +30 -0
- package/dist/model.js.map +1 -0
- package/dist/policy.js +22 -0
- package/dist/policy.js.map +1 -0
- package/dist/queue.js +45 -0
- package/dist/queue.js.map +1 -0
- package/dist/retry.js +96 -0
- package/dist/retry.js.map +1 -0
- package/dist/runs.js +83 -0
- package/dist/runs.js.map +1 -0
- package/dist/runtime/compact.js +99 -0
- package/dist/runtime/compact.js.map +1 -0
- package/dist/runtime/lanes.js +66 -0
- package/dist/runtime/lanes.js.map +1 -0
- package/dist/runtime/orchestrate.js +121 -0
- package/dist/runtime/orchestrate.js.map +1 -0
- package/dist/runtime/queue.js +50 -0
- package/dist/runtime/queue.js.map +1 -0
- package/dist/runtime/retry.js +127 -0
- package/dist/runtime/retry.js.map +1 -0
- package/dist/runtime/runs.js +105 -0
- package/dist/runtime/runs.js.map +1 -0
- package/dist/serve.js +209 -0
- package/dist/serve.js.map +1 -0
- package/dist/session.js +75 -0
- package/dist/session.js.map +1 -0
- package/dist/setup.js +254 -0
- package/dist/setup.js.map +1 -0
- package/dist/skills.js +89 -0
- package/dist/skills.js.map +1 -0
- package/dist/subagent.js +71 -0
- package/dist/subagent.js.map +1 -0
- package/dist/system-prompt.js +157 -0
- package/dist/system-prompt.js.map +1 -0
- package/dist/telegram/admin-bot.js +705 -0
- package/dist/telegram/admin-bot.js.map +1 -0
- package/dist/telegram/agent-bot.js +551 -0
- package/dist/telegram/agent-bot.js.map +1 -0
- package/dist/telegram/bot-approval.js +63 -0
- package/dist/telegram/bot-approval.js.map +1 -0
- package/dist/telegram/draft-stream.js +86 -0
- package/dist/telegram/draft-stream.js.map +1 -0
- package/dist/telegram/format.js +106 -0
- package/dist/telegram/format.js.map +1 -0
- package/dist/telegram/helpers.js +87 -0
- package/dist/telegram/helpers.js.map +1 -0
- package/dist/telegram/pairing-notify.js +52 -0
- package/dist/telegram/pairing-notify.js.map +1 -0
- package/dist/telegram/pairing.js +138 -0
- package/dist/telegram/pairing.js.map +1 -0
- package/dist/telegram/resolve.js +33 -0
- package/dist/telegram/resolve.js.map +1 -0
- package/dist/telegram/transcribe.js +77 -0
- package/dist/telegram/transcribe.js.map +1 -0
- package/dist/telegram/types.js +3 -0
- package/dist/telegram/types.js.map +1 -0
- package/dist/telegram/voice-wizard.js +84 -0
- package/dist/telegram/voice-wizard.js.map +1 -0
- package/dist/telegram/wizard.js +89 -0
- package/dist/telegram/wizard.js.map +1 -0
- package/dist/telegram/wizards.js +297 -0
- package/dist/telegram/wizards.js.map +1 -0
- package/dist/telegram-admin.js +800 -0
- package/dist/telegram-admin.js.map +1 -0
- package/dist/telegram.js +118 -0
- package/dist/telegram.js.map +1 -0
- package/dist/tools/cron.js +94 -0
- package/dist/tools/cron.js.map +1 -0
- package/dist/tools/edit.js +29 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/exec.js +38 -0
- package/dist/tools/exec.js.map +1 -0
- package/dist/tools/fetch.js +28 -0
- package/dist/tools/fetch.js.map +1 -0
- package/dist/tools/index.js +16 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/memory.js +164 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/tools/patch.js +284 -0
- package/dist/tools/patch.js.map +1 -0
- package/dist/tools/read.js +26 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/search.js +62 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/subagent.js +48 -0
- package/dist/tools/subagent.js.map +1 -0
- package/dist/tools/write.js +22 -0
- package/dist/tools/write.js.map +1 -0
- package/dist/tui/commands.js +450 -0
- package/dist/tui/commands.js.map +1 -0
- package/dist/tui/components/assistant-message.js +26 -0
- package/dist/tui/components/assistant-message.js.map +1 -0
- package/dist/tui/components/chat-log.js +94 -0
- package/dist/tui/components/chat-log.js.map +1 -0
- package/dist/tui/components/custom-editor.js +40 -0
- package/dist/tui/components/custom-editor.js.map +1 -0
- package/dist/tui/components/hint-bar.js +13 -0
- package/dist/tui/components/hint-bar.js.map +1 -0
- package/dist/tui/components/tool-execution.js +73 -0
- package/dist/tui/components/tool-execution.js.map +1 -0
- package/dist/tui/components/user-message.js +19 -0
- package/dist/tui/components/user-message.js.map +1 -0
- package/dist/tui/components/welcome.js +147 -0
- package/dist/tui/components/welcome.js.map +1 -0
- package/dist/tui/context.js +3 -0
- package/dist/tui/context.js.map +1 -0
- package/dist/tui/theme.js +91 -0
- package/dist/tui/theme.js.map +1 -0
- package/dist/tui/tui.js +389 -0
- package/dist/tui/tui.js.map +1 -0
- package/dist/tui/ws-handler.js +154 -0
- package/dist/tui/ws-handler.js.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/usage.js +88 -0
- package/dist/usage.js.map +1 -0
- package/dist/workspace.js +245 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { register } from "./registry.js";
|
|
2
|
+
register({
|
|
3
|
+
name: "daemon",
|
|
4
|
+
description: "Manage launchd daemon (install, uninstall, status)",
|
|
5
|
+
usage: `Usage: camelagi daemon <subcommand>
|
|
6
|
+
|
|
7
|
+
Manage the macOS launchd background service.
|
|
8
|
+
|
|
9
|
+
Subcommands:
|
|
10
|
+
status Show daemon status (default)
|
|
11
|
+
install Install and start the daemon
|
|
12
|
+
uninstall Stop and remove the daemon
|
|
13
|
+
|
|
14
|
+
Examples:
|
|
15
|
+
camelagi daemon
|
|
16
|
+
camelagi daemon install
|
|
17
|
+
camelagi daemon status`,
|
|
18
|
+
run: async (args) => {
|
|
19
|
+
const sub = args[0];
|
|
20
|
+
const { install, uninstall, status } = await import("../daemon.js");
|
|
21
|
+
if (sub === "install") {
|
|
22
|
+
install();
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
if (sub === "uninstall") {
|
|
26
|
+
uninstall();
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
if (sub === "status" || !sub) {
|
|
30
|
+
status();
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
console.error(`Unknown daemon subcommand: ${sub}. Use: install, uninstall, status`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=cmd-daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-daemon.js","sourceRoot":"","sources":["../../src/cli/cmd-daemon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,QAAQ,CAAC;IACP,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,oDAAoD;IACjE,KAAK,EAAE;;;;;;;;;;;;yBAYgB;IACvB,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QAEpE,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YAAC,OAAO,EAAE,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;QACtD,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YAAC,SAAS,EAAE,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;QAC1D,IAAI,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC;YAAC,MAAM,EAAE,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;QAE5D,OAAO,CAAC,KAAK,CAAC,8BAA8B,GAAG,mCAAmC,CAAC,CAAC;QACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { register } from "./registry.js";
|
|
2
|
+
import { ensureDirs } from "../core/config.js";
|
|
3
|
+
register({
|
|
4
|
+
name: "doctor",
|
|
5
|
+
description: "Run health checks",
|
|
6
|
+
run: async () => {
|
|
7
|
+
ensureDirs();
|
|
8
|
+
console.log("\n\x1b[36m CamelAGI Doctor\x1b[0m\n");
|
|
9
|
+
const { runDoctor, formatChecks } = await import("../doctor.js");
|
|
10
|
+
const checks = await runDoctor();
|
|
11
|
+
console.log(formatChecks(checks));
|
|
12
|
+
const errors = checks.filter((c) => c.status === "error");
|
|
13
|
+
const warns = checks.filter((c) => c.status === "warn");
|
|
14
|
+
console.log(`\n ${checks.length} checks: ${checks.length - errors.length - warns.length} ok, ${warns.length} warnings, ${errors.length} errors\n`);
|
|
15
|
+
process.exit(errors.length > 0 ? 1 : 0);
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=cmd-doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-doctor.js","sourceRoot":"","sources":["../../src/cli/cmd-doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,QAAQ,CAAC;IACP,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,mBAAmB;IAChC,GAAG,EAAE,KAAK,IAAI,EAAE;QACd,UAAU,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACjE,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,MAAM,YAAY,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,MAAM,cAAc,MAAM,CAAC,MAAM,WAAW,CAAC,CAAC;QACpJ,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { register } from "./registry.js";
|
|
2
|
+
import { getFlagInt } from "./parse.js";
|
|
3
|
+
register({
|
|
4
|
+
name: "logs",
|
|
5
|
+
description: "Tail server request log",
|
|
6
|
+
usage: `Usage: camelagi logs [options]
|
|
7
|
+
|
|
8
|
+
Display recent server request logs.
|
|
9
|
+
|
|
10
|
+
Options:
|
|
11
|
+
-n <number> Number of lines to show (default: 50, min: 1)
|
|
12
|
+
|
|
13
|
+
Examples:
|
|
14
|
+
camelagi logs
|
|
15
|
+
camelagi logs -n 100`,
|
|
16
|
+
run: async (args) => {
|
|
17
|
+
let lines = 50;
|
|
18
|
+
try {
|
|
19
|
+
lines = getFlagInt(args, "-n", 1) ?? 50;
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
const { tailLog } = await import("../gateway/logger.js");
|
|
26
|
+
console.log(tailLog(lines));
|
|
27
|
+
process.exit(0);
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=cmd-logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-logs.js","sourceRoot":"","sources":["../../src/cli/cmd-logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,QAAQ,CAAC;IACP,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,yBAAyB;IACtC,KAAK,EAAE;;;;;;;;;uBASc;IACrB,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAClB,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,IAAI,CAAC;YACH,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// CLI command: camelagi pairing — manage pairing requests from the terminal
|
|
2
|
+
import { register } from "./registry.js";
|
|
3
|
+
import { listPendingRequests, approveRequest, denyRequest } from "../telegram/pairing.js";
|
|
4
|
+
import readline from "node:readline";
|
|
5
|
+
function ask(rl, question) {
|
|
6
|
+
return new Promise((resolve) => rl.question(question, resolve));
|
|
7
|
+
}
|
|
8
|
+
register({
|
|
9
|
+
name: "pairing",
|
|
10
|
+
description: "List and approve/deny pending pairing requests",
|
|
11
|
+
async run() {
|
|
12
|
+
const requests = listPendingRequests();
|
|
13
|
+
if (requests.length === 0) {
|
|
14
|
+
console.log(" No pending pairing requests.");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
18
|
+
for (const r of requests) {
|
|
19
|
+
const userLabel = r.username ? `@${r.username}` : r.firstName ?? String(r.userId);
|
|
20
|
+
console.log(`\n Request: ${r.code}`);
|
|
21
|
+
console.log(` User: ${userLabel} (${r.userId})`);
|
|
22
|
+
console.log(` Agent: ${r.agentId}`);
|
|
23
|
+
const answer = await ask(rl, `\n Approve? (y/n): `);
|
|
24
|
+
if (answer.trim().toLowerCase() === "y") {
|
|
25
|
+
const approved = approveRequest(r.code);
|
|
26
|
+
if (approved) {
|
|
27
|
+
console.log(` ✓ Approved. User now has access.`);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
console.log(` ✗ Request expired or already handled.`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
denyRequest(r.code);
|
|
35
|
+
console.log(` ✗ Denied.`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
rl.close();
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=cmd-pairing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-pairing.js","sourceRoot":"","sources":["../../src/cli/cmd-pairing.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAE5E,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,SAAS,GAAG,CAAC,EAAsB,EAAE,QAAgB;IACnD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,QAAQ,CAAC;IACP,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,gDAAgD;IAC7D,KAAK,CAAC,GAAG;QACP,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;QAEvC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QAED,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAEtF,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAElF,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACtC,OAAO,CAAC,GAAG,CAAC,cAAc,SAAS,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YAEvC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,sBAAsB,CAAC,CAAC;YACrD,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,EAAE,CAAC;gBACxC,MAAM,QAAQ,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBACxC,IAAI,QAAQ,EAAE,CAAC;oBACb,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;gBACpD,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;gBACzD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBACpB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { register } from "./registry.js";
|
|
2
|
+
import { paths } from "../core/config.js";
|
|
3
|
+
import { hasFlag } from "./parse.js";
|
|
4
|
+
register({
|
|
5
|
+
name: "reset",
|
|
6
|
+
description: "Delete all config, sessions, agents (fresh start)",
|
|
7
|
+
usage: `Usage: camelagi reset [options]
|
|
8
|
+
|
|
9
|
+
Delete ALL data in ~/.camelagi (config, sessions, agents, workspaces).
|
|
10
|
+
|
|
11
|
+
Options:
|
|
12
|
+
--confirm Skip the confirmation prompt
|
|
13
|
+
|
|
14
|
+
Examples:
|
|
15
|
+
camelagi reset
|
|
16
|
+
camelagi reset --confirm`,
|
|
17
|
+
run: async (args) => {
|
|
18
|
+
const { default: fs } = await import("node:fs");
|
|
19
|
+
const { default: readline } = await import("node:readline");
|
|
20
|
+
const configDir = paths.configDir;
|
|
21
|
+
if (!fs.existsSync(configDir)) {
|
|
22
|
+
console.log("Nothing to reset — ~/.camelagi does not exist.");
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
if (!hasFlag(args, "--confirm")) {
|
|
26
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
27
|
+
const answer = await new Promise((resolve) => rl.question("\x1b[31m This will delete ALL config, sessions, agents, and workspaces.\x1b[0m\n Are you sure? (yes/no): ", resolve));
|
|
28
|
+
rl.close();
|
|
29
|
+
if (answer.trim().toLowerCase() !== "yes") {
|
|
30
|
+
console.log(" Cancelled.");
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
fs.rmSync(configDir, { recursive: true, force: true });
|
|
35
|
+
console.log(" \x1b[32m✓\x1b[0m ~/.camelagi deleted. Run \x1b[36mcamelagi bootstrap\x1b[0m to start fresh.");
|
|
36
|
+
process.exit(0);
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=cmd-reset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-reset.js","sourceRoot":"","sources":["../../src/cli/cmd-reset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,QAAQ,CAAC;IACP,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,mDAAmD;IAChE,KAAK,EAAE;;;;;;;;;2BASkB;IACzB,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAClB,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QAChD,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;QAE5D,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QAElC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;YAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;YAChC,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YACtF,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE,CACnD,EAAE,CAAC,QAAQ,CAAC,6GAA6G,EAAE,OAAO,CAAC,CACpI,CAAC;YACF,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;gBAC1C,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;gBAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,+FAA+F,CAAC,CAAC;QAC7G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { register } from "./registry.js";
|
|
2
|
+
import { getFlagInt } from "./parse.js";
|
|
3
|
+
register({
|
|
4
|
+
name: "serve",
|
|
5
|
+
description: "Start gateway server",
|
|
6
|
+
usage: `Usage: camelagi serve [options]
|
|
7
|
+
|
|
8
|
+
Start the gateway server (Express + WebSocket).
|
|
9
|
+
|
|
10
|
+
Options:
|
|
11
|
+
--port <number> Port to listen on (1-65535, default: from config)
|
|
12
|
+
|
|
13
|
+
Examples:
|
|
14
|
+
camelagi serve
|
|
15
|
+
camelagi serve --port 3000`,
|
|
16
|
+
run: async (args) => {
|
|
17
|
+
let port;
|
|
18
|
+
try {
|
|
19
|
+
port = getFlagInt(args, "--port", 1, 65535);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
const { startServer } = await import("../serve.js");
|
|
26
|
+
await startServer({ port, cron: true, boot: true });
|
|
27
|
+
// startServer keeps the process alive
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=cmd-serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-serve.js","sourceRoot":"","sources":["../../src/cli/cmd-serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,QAAQ,CAAC;IACP,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,sBAAsB;IACnC,KAAK,EAAE;;;;;;;;;6BASoB;IAC3B,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAClB,IAAI,IAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QACpD,MAAM,WAAW,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,sCAAsC;IACxC,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { register } from "./registry.js";
|
|
2
|
+
import { hasFlag } from "./parse.js";
|
|
3
|
+
register({
|
|
4
|
+
name: "sessions",
|
|
5
|
+
description: "List saved sessions",
|
|
6
|
+
usage: `Usage: camelagi sessions [subcommand]
|
|
7
|
+
|
|
8
|
+
List or manage saved chat sessions.
|
|
9
|
+
|
|
10
|
+
Subcommands:
|
|
11
|
+
(none) List all sessions (default)
|
|
12
|
+
rm <id> Delete a session (prompts for confirmation)
|
|
13
|
+
|
|
14
|
+
Options:
|
|
15
|
+
--yes, -y Skip confirmation prompt (with rm)
|
|
16
|
+
|
|
17
|
+
Examples:
|
|
18
|
+
camelagi sessions
|
|
19
|
+
camelagi sessions rm session-abc123
|
|
20
|
+
camelagi sessions rm session-abc123 --yes`,
|
|
21
|
+
run: async (args) => {
|
|
22
|
+
const { listSessions, deleteSession } = await import("../session.js");
|
|
23
|
+
if (args[0] === "rm" && args[1]) {
|
|
24
|
+
if (!hasFlag(args, "--yes") && !hasFlag(args, "-y")) {
|
|
25
|
+
const { default: readline } = await import("node:readline");
|
|
26
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
27
|
+
const answer = await new Promise((resolve) => rl.question(` Delete session "${args[1]}"? (yes/no): `, resolve));
|
|
28
|
+
rl.close();
|
|
29
|
+
if (answer.trim().toLowerCase() !== "yes") {
|
|
30
|
+
console.log(" Cancelled.");
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
deleteSession(args[1]);
|
|
35
|
+
console.log(`Deleted session: ${args[1]}`);
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}
|
|
38
|
+
if (args[0] && args[0] !== "rm") {
|
|
39
|
+
console.error(`Unknown subcommand: ${args[0]}. Use: camelagi sessions [rm <id>]`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
const sessions = listSessions();
|
|
43
|
+
if (sessions.length === 0) {
|
|
44
|
+
console.log("No sessions.");
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
for (const s of sessions) {
|
|
48
|
+
const date = new Date(s.createdAt).toLocaleString();
|
|
49
|
+
const label = s.label ? `, ${s.label}` : "";
|
|
50
|
+
console.log(` ${s.id} (${s.model}${label}, ${date})`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
process.exit(0);
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=cmd-sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-sessions.js","sourceRoot":"","sources":["../../src/cli/cmd-sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,QAAQ,CAAC;IACP,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE,qBAAqB;IAClC,KAAK,EAAE;;;;;;;;;;;;;;4CAcmC;IAC1C,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAClB,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;QAEtE,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;gBACpD,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;gBAC5D,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;gBACtF,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE,CACnD,EAAE,CAAC,QAAQ,CAAC,qBAAqB,IAAI,CAAC,CAAC,CAAC,eAAe,EAAE,OAAO,CAAC,CAClE,CAAC;gBACF,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;oBAC1C,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;oBAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;YACH,CAAC;YAED,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC;YAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;QAChC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAC;gBACpD,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,GAAG,KAAK,KAAK,IAAI,GAAG,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { register } from "./registry.js";
|
|
2
|
+
register({
|
|
3
|
+
name: "setup",
|
|
4
|
+
description: "Interactive setup wizard",
|
|
5
|
+
run: async () => {
|
|
6
|
+
const { runSetup } = await import("../setup.js");
|
|
7
|
+
await runSetup();
|
|
8
|
+
process.exit(0);
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=cmd-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-setup.js","sourceRoot":"","sources":["../../src/cli/cmd-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,QAAQ,CAAC;IACP,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,0BAA0B;IACvC,GAAG,EAAE,KAAK,IAAI,EAAE;QACd,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QACjD,MAAM,QAAQ,EAAE,CAAC;QACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { register } from "./registry.js";
|
|
2
|
+
import { loadConfig, ensureDirs } from "../core/config.js";
|
|
3
|
+
register({
|
|
4
|
+
name: "soul",
|
|
5
|
+
description: "View/edit agent's SOUL.md in $EDITOR",
|
|
6
|
+
run: async (args) => {
|
|
7
|
+
ensureDirs();
|
|
8
|
+
const { agentMemoryDir, seedAgentWorkspace } = await import("../workspace.js");
|
|
9
|
+
const config = loadConfig();
|
|
10
|
+
const agentEntries = Object.entries(config.agents ?? {});
|
|
11
|
+
if (agentEntries.length === 0) {
|
|
12
|
+
console.error("No agents configured.");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
// If no id given and only one agent, use that
|
|
16
|
+
let targetId = args[0];
|
|
17
|
+
if (!targetId && agentEntries.length === 1) {
|
|
18
|
+
targetId = agentEntries[0][0];
|
|
19
|
+
}
|
|
20
|
+
if (!targetId) {
|
|
21
|
+
console.log("Usage: camelagi soul <id>\n");
|
|
22
|
+
for (const [id] of agentEntries) {
|
|
23
|
+
console.log(` ${id}`);
|
|
24
|
+
}
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
if (!config.agents[targetId]) {
|
|
28
|
+
console.error(`Agent "${targetId}" not found.`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const { default: fs } = await import("node:fs");
|
|
32
|
+
const { default: path } = await import("node:path");
|
|
33
|
+
const soulPath = path.join(agentMemoryDir(targetId), "SOUL.md");
|
|
34
|
+
if (!fs.existsSync(soulPath)) {
|
|
35
|
+
seedAgentWorkspace(targetId, config.agents[targetId].name);
|
|
36
|
+
}
|
|
37
|
+
const editorCmd = process.env.EDITOR || process.env.VISUAL || "nano";
|
|
38
|
+
const { spawnSync } = await import("node:child_process");
|
|
39
|
+
spawnSync(editorCmd, [soulPath], { stdio: "inherit" });
|
|
40
|
+
process.exit(0);
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
//# sourceMappingURL=cmd-soul.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-soul.js","sourceRoot":"","sources":["../../src/cli/cmd-soul.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE3D,QAAQ,CAAC;IACP,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,sCAAsC;IACnD,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAClB,UAAU,EAAE,CAAC;QACb,MAAM,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QAEzD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,8CAA8C;QAC9C,IAAI,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,CAAC,QAAQ,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;YAC3C,KAAK,MAAM,CAAC,EAAE,CAAC,IAAI,YAAY,EAAE,CAAC;gBAChC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACzB,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,KAAK,CAAC,UAAU,QAAQ,cAAc,CAAC,CAAC;YAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QAChD,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC;QAEhE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC;QACrE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACzD,SAAS,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Common CLI argument parsing helpers
|
|
2
|
+
/** Get flag value: --port 8080 → "8080" */
|
|
3
|
+
export function getFlag(args, name) {
|
|
4
|
+
const idx = args.indexOf(name);
|
|
5
|
+
return idx !== -1 && idx + 1 < args.length ? args[idx + 1] : undefined;
|
|
6
|
+
}
|
|
7
|
+
/** Get flag as int with validation */
|
|
8
|
+
export function getFlagInt(args, name, min, max) {
|
|
9
|
+
const raw = getFlag(args, name);
|
|
10
|
+
if (raw === undefined)
|
|
11
|
+
return undefined;
|
|
12
|
+
const n = parseInt(raw, 10);
|
|
13
|
+
if (isNaN(n))
|
|
14
|
+
throw new Error(`Invalid value for ${name}: "${raw}" (expected a number)`);
|
|
15
|
+
if (min !== undefined && n < min)
|
|
16
|
+
throw new Error(`${name} must be >= ${min}`);
|
|
17
|
+
if (max !== undefined && n > max)
|
|
18
|
+
throw new Error(`${name} must be <= ${max}`);
|
|
19
|
+
return n;
|
|
20
|
+
}
|
|
21
|
+
/** Check if flag is present (no value): --confirm */
|
|
22
|
+
export function hasFlag(args, name) {
|
|
23
|
+
return args.includes(name);
|
|
24
|
+
}
|
|
25
|
+
/** Validate a cron schedule string format and warn about limitations */
|
|
26
|
+
export function validateSchedule(schedule) {
|
|
27
|
+
// Duration: 5m, 1h, 1d, 30s
|
|
28
|
+
if (/^\d+[smhd]$/.test(schedule))
|
|
29
|
+
return;
|
|
30
|
+
// One-shot relative: +20m, +1h
|
|
31
|
+
if (/^\+\d+[smhd]$/.test(schedule))
|
|
32
|
+
return;
|
|
33
|
+
// Cron expression: 5 whitespace-separated fields
|
|
34
|
+
const fields = schedule.trim().split(/\s+/);
|
|
35
|
+
if (fields.length === 5) {
|
|
36
|
+
// Only */N minute-field patterns are fully supported; other cron expressions
|
|
37
|
+
// (e.g. "0 9 * * *") fall back to a 1-minute interval which is rarely intended.
|
|
38
|
+
if (!fields[0].startsWith("*/")) {
|
|
39
|
+
console.warn(`\x1b[33mWarning:\x1b[0m Cron expression "${schedule}" will run as a 1-minute interval.\n` +
|
|
40
|
+
` Only \`*/N * * * *\` patterns are fully supported. Consider using a duration (e.g. "1d") instead.`);
|
|
41
|
+
}
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// ISO timestamp
|
|
45
|
+
if (schedule.length > 8 && !isNaN(Date.parse(schedule)))
|
|
46
|
+
return;
|
|
47
|
+
throw new Error(`Invalid schedule format: "${schedule}"\n` +
|
|
48
|
+
` Supported: 5m, 1h, 1d (interval), +20m (one-shot), */5 * * * * (cron), ISO timestamp`);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/cli/parse.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,2CAA2C;AAC3C,MAAM,UAAU,OAAO,CAAC,IAAc,EAAE,IAAY;IAClD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,GAAG,KAAK,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACzE,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,UAAU,CAAC,IAAc,EAAE,IAAY,EAAE,GAAY,EAAE,GAAY;IACjF,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAChC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5B,IAAI,KAAK,CAAC,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,MAAM,GAAG,uBAAuB,CAAC,CAAC;IACzF,IAAI,GAAG,KAAK,SAAS,IAAI,CAAC,GAAG,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,eAAe,GAAG,EAAE,CAAC,CAAC;IAC/E,IAAI,GAAG,KAAK,SAAS,IAAI,CAAC,GAAG,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,eAAe,GAAG,EAAE,CAAC,CAAC;IAC/E,OAAO,CAAC,CAAC;AACX,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,OAAO,CAAC,IAAc,EAAE,IAAY;IAClD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,4BAA4B;IAC5B,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO;IACzC,+BAA+B;IAC/B,IAAI,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO;IAC3C,iDAAiD;IACjD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,6EAA6E;QAC7E,gFAAgF;QAChF,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CACV,4CAA4C,QAAQ,sCAAsC;gBAC1F,qGAAqG,CACtG,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IACD,gBAAgB;IAChB,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAAE,OAAO;IAEhE,MAAM,IAAI,KAAK,CACb,6BAA6B,QAAQ,KAAK;QAC1C,wFAAwF,CACzF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// CLI command registry — replaces brittle if-else chain with a simple map
|
|
2
|
+
const commands = new Map();
|
|
3
|
+
export function register(cmd) {
|
|
4
|
+
commands.set(cmd.name, cmd);
|
|
5
|
+
}
|
|
6
|
+
export function resolve(name) {
|
|
7
|
+
return commands.get(name);
|
|
8
|
+
}
|
|
9
|
+
export function allCommands() {
|
|
10
|
+
return Array.from(commands.values());
|
|
11
|
+
}
|
|
12
|
+
export function isRegistered(name) {
|
|
13
|
+
return commands.has(name);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/cli/registry.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAS1E,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAsB,CAAC;AAE/C,MAAM,UAAU,QAAQ,CAAC,GAAe;IACtC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// camelagi CLI — gateway-first architecture
|
|
3
|
+
// All agent execution flows through the gateway server.
|
|
4
|
+
import { resolve, allCommands } from "./cli/registry.js";
|
|
5
|
+
import { printUpdateNotice } from "./core/update-check.js";
|
|
6
|
+
// Register all commands (side-effect imports)
|
|
7
|
+
import "./cli/cmd-reset.js";
|
|
8
|
+
import "./cli/cmd-bootstrap.js";
|
|
9
|
+
import "./cli/cmd-setup.js";
|
|
10
|
+
import "./cli/cmd-doctor.js";
|
|
11
|
+
import "./cli/cmd-config.js";
|
|
12
|
+
import "./cli/cmd-cron.js";
|
|
13
|
+
import "./cli/cmd-daemon.js";
|
|
14
|
+
import "./cli/cmd-logs.js";
|
|
15
|
+
import "./cli/cmd-serve.js";
|
|
16
|
+
import "./cli/cmd-agents.js";
|
|
17
|
+
import "./cli/cmd-soul.js";
|
|
18
|
+
import "./cli/cmd-sessions.js";
|
|
19
|
+
import "./cli/cmd-chat.js";
|
|
20
|
+
import "./cli/cmd-pairing.js";
|
|
21
|
+
const args = process.argv.slice(2);
|
|
22
|
+
// Non-blocking update check on every invocation
|
|
23
|
+
printUpdateNotice();
|
|
24
|
+
// camelagi --version / -v
|
|
25
|
+
if (args[0] === "--version" || args[0] === "-v") {
|
|
26
|
+
const { createRequire } = await import("node:module");
|
|
27
|
+
const require = createRequire(import.meta.url);
|
|
28
|
+
const pkg = require("../package.json");
|
|
29
|
+
console.log(pkg.version);
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
// camelagi --help / -h / (no args)
|
|
33
|
+
if (args[0] === "--help" || args[0] === "-h" || args.length === 0) {
|
|
34
|
+
const commands = allCommands();
|
|
35
|
+
const maxLen = Math.max(...commands.map((c) => c.name.length));
|
|
36
|
+
console.log(`
|
|
37
|
+
camelagi - Personal AI assistant
|
|
38
|
+
|
|
39
|
+
Usage:
|
|
40
|
+
camelagi "your message" One-shot message
|
|
41
|
+
camelagi <command> [options] Run a command
|
|
42
|
+
|
|
43
|
+
Commands:`);
|
|
44
|
+
for (const cmd of commands) {
|
|
45
|
+
console.log(` ${cmd.name.padEnd(maxLen + 2)}${cmd.description}`);
|
|
46
|
+
}
|
|
47
|
+
console.log(`
|
|
48
|
+
Environment:
|
|
49
|
+
ANTHROPIC_API_KEY Anthropic API key
|
|
50
|
+
OPENAI_API_KEY OpenAI API key
|
|
51
|
+
CAMELAGI_MODEL Model override (e.g. gpt-4o)
|
|
52
|
+
CAMELAGI_PROVIDER Provider override (anthropic|openai)
|
|
53
|
+
CAMELAGI_TOKEN Auth token for gateway server
|
|
54
|
+
TELEGRAM_BOT_TOKEN Telegram bot token
|
|
55
|
+
|
|
56
|
+
Config file: ~/.camelagi/config.yaml
|
|
57
|
+
`);
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
// Dispatch to registered command
|
|
61
|
+
const cmd = resolve(args[0]);
|
|
62
|
+
if (cmd) {
|
|
63
|
+
if (args[1] === "--help" || args[1] === "-h") {
|
|
64
|
+
console.log(cmd.usage ?? `Usage: camelagi ${cmd.name}\n\n${cmd.description}`);
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}
|
|
67
|
+
await cmd.run(args.slice(1));
|
|
68
|
+
}
|
|
69
|
+
else if (args[0] && !args[0].startsWith("-")) {
|
|
70
|
+
// camelagi "your message" — one-shot mode via embedded gateway
|
|
71
|
+
const message = args.join(" ");
|
|
72
|
+
const { startServer } = await import("./serve.js");
|
|
73
|
+
const handle = await startServer({
|
|
74
|
+
port: 0,
|
|
75
|
+
silent: true,
|
|
76
|
+
channels: false,
|
|
77
|
+
boot: false,
|
|
78
|
+
cron: false,
|
|
79
|
+
});
|
|
80
|
+
try {
|
|
81
|
+
const res = await fetch(`http://127.0.0.1:${handle.port}/chat`, {
|
|
82
|
+
method: "POST",
|
|
83
|
+
headers: { "Content-Type": "application/json" },
|
|
84
|
+
body: JSON.stringify({ message, session: `oneshot-${Date.now()}` }),
|
|
85
|
+
});
|
|
86
|
+
const data = await res.json();
|
|
87
|
+
if (res.ok) {
|
|
88
|
+
console.log(data.response);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
console.error(`Error: ${data.error}`);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
await handle.close();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,4CAA4C;AAC5C,wDAAwD;AAExD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,8CAA8C;AAC9C,OAAO,oBAAoB,CAAC;AAC5B,OAAO,wBAAwB,CAAC;AAChC,OAAO,oBAAoB,CAAC;AAC5B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,mBAAmB,CAAC;AAC3B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,mBAAmB,CAAC;AAC3B,OAAO,oBAAoB,CAAC;AAC5B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,mBAAmB,CAAC;AAC3B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,mBAAmB,CAAC;AAC3B,OAAO,sBAAsB,CAAC;AAE9B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,gDAAgD;AAChD,iBAAiB,EAAE,CAAC;AAEpB,0BAA0B;AAC1B,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IAChD,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,mCAAmC;AACnC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAClE,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC;;;;;;;UAOJ,CAAC,CAAC;IACV,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;CAUb,CAAC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,iCAAiC;AACjC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7B,IAAI,GAAG,EAAE,CAAC;IACR,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,mBAAmB,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,CAAC;KAAM,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;IAC/C,+DAA+D;IAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE/B,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC;QAC/B,IAAI,EAAE,CAAC;QACP,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,MAAM,CAAC,IAAI,OAAO,EAAE;YAC9D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC;SACpE,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAA2C,CAAC;QAEvE,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC"}
|
package/dist/compact.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Context compaction: summarize old messages when context gets too large
|
|
2
|
+
import { chatDirect } from "./model.js";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { workspacePaths } from "./workspace.js";
|
|
6
|
+
import { CHARS_PER_TOKEN, COMPACTION_TRIGGER_RATIO, MEMORY_FLUSH_MAX_CHARS } from "./core/constants.js";
|
|
7
|
+
function estimateTokens(messages) {
|
|
8
|
+
let chars = 0;
|
|
9
|
+
for (const msg of messages) {
|
|
10
|
+
chars += msg.content.length;
|
|
11
|
+
}
|
|
12
|
+
return Math.ceil(chars / CHARS_PER_TOKEN);
|
|
13
|
+
}
|
|
14
|
+
function splitHistory(messages, keepTurns) {
|
|
15
|
+
if (keepTurns <= 0)
|
|
16
|
+
return { old: messages, recent: [] };
|
|
17
|
+
const turnStarts = [];
|
|
18
|
+
for (let i = 0; i < messages.length; i++) {
|
|
19
|
+
if (messages[i].role === "user") {
|
|
20
|
+
turnStarts.push(i);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (turnStarts.length <= keepTurns) {
|
|
24
|
+
return { old: [], recent: messages };
|
|
25
|
+
}
|
|
26
|
+
const cutoff = turnStarts[turnStarts.length - keepTurns];
|
|
27
|
+
return {
|
|
28
|
+
old: messages.slice(0, cutoff),
|
|
29
|
+
recent: messages.slice(cutoff),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const COMPACT_PROMPT = `Summarize the following conversation history concisely. Preserve:
|
|
33
|
+
- Key facts, decisions, and context established
|
|
34
|
+
- Important file paths, names, and technical details mentioned
|
|
35
|
+
- Current state of any ongoing tasks
|
|
36
|
+
- User preferences or instructions given
|
|
37
|
+
|
|
38
|
+
Be concise but don't lose critical context. Output only the summary, no preamble.`;
|
|
39
|
+
export async function compactHistory(client, model, history, opts) {
|
|
40
|
+
if (!opts.enabled)
|
|
41
|
+
return null;
|
|
42
|
+
const tokens = estimateTokens(history);
|
|
43
|
+
if (tokens < opts.maxTokens * COMPACTION_TRIGGER_RATIO)
|
|
44
|
+
return null;
|
|
45
|
+
const { old, recent } = splitHistory(history, opts.keepTurns);
|
|
46
|
+
if (old.length === 0)
|
|
47
|
+
return null;
|
|
48
|
+
await memoryFlush(client, model, old);
|
|
49
|
+
const oldText = old.map((m) => {
|
|
50
|
+
return `[${m.role}]: ${m.content}`;
|
|
51
|
+
}).join("\n\n");
|
|
52
|
+
const summaryResult = await chatDirect(client, model, COMPACT_PROMPT, oldText);
|
|
53
|
+
const summaryMessage = {
|
|
54
|
+
role: "user",
|
|
55
|
+
content: `[Previous conversation summary]\n${summaryResult.content}\n[End of summary — conversation continues below]`,
|
|
56
|
+
};
|
|
57
|
+
return [summaryMessage, ...recent];
|
|
58
|
+
}
|
|
59
|
+
// --- Memory flush ---
|
|
60
|
+
const FLUSH_PROMPT = `You are about to lose the following conversation history due to context compaction.
|
|
61
|
+
Extract any durable facts worth remembering: decisions made, user preferences discovered,
|
|
62
|
+
project details, file paths, names, dates, or anything the user would expect you to know later.
|
|
63
|
+
|
|
64
|
+
Format as concise bullet points. If nothing is worth saving, reply with "NOTHING".`;
|
|
65
|
+
async function memoryFlush(client, model, oldMessages) {
|
|
66
|
+
if (oldMessages.length === 0)
|
|
67
|
+
return;
|
|
68
|
+
try {
|
|
69
|
+
const oldText = oldMessages.map((m) => {
|
|
70
|
+
return `[${m.role}]: ${m.content}`;
|
|
71
|
+
}).join("\n\n");
|
|
72
|
+
if (oldText.length < 200)
|
|
73
|
+
return;
|
|
74
|
+
const response = await chatDirect(client, model, FLUSH_PROMPT, oldText.slice(0, MEMORY_FLUSH_MAX_CHARS));
|
|
75
|
+
const extracted = response.content;
|
|
76
|
+
if (extracted.trim() === "NOTHING" || extracted.trim().length < 10)
|
|
77
|
+
return;
|
|
78
|
+
const { workspaceDir } = workspacePaths;
|
|
79
|
+
const memoryDir = path.join(workspaceDir, "memory");
|
|
80
|
+
fs.mkdirSync(memoryDir, { recursive: true });
|
|
81
|
+
const today = new Date().toISOString().split("T")[0];
|
|
82
|
+
const dailyFile = path.join(memoryDir, `${today}.md`);
|
|
83
|
+
const header = fs.existsSync(dailyFile) ? "" : `# ${today}\n\n`;
|
|
84
|
+
const timestamp = new Date().toTimeString().split(" ")[0];
|
|
85
|
+
const entry = `${header}## ${timestamp} (auto-flush)\n\n${extracted}\n\n`;
|
|
86
|
+
fs.appendFileSync(dailyFile, entry);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Memory flush is best-effort
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=compact.js.map
|