chorus-codes 0.7.0 → 0.7.2
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/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/cache/.previewinfo +1 -1
- package/.next/cache/.rscinfo +1 -1
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/new.html +1 -1
- package/.next/server/app/new.rsc +1 -1
- package/.next/server/app/new.segments/_full.segment.rsc +1 -1
- package/.next/server/app/new.segments/_head.segment.rsc +1 -1
- package/.next/server/app/new.segments/_index.segment.rsc +1 -1
- package/.next/server/app/new.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/new.segments/new/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/new.segments/new.segment.rsc +1 -1
- package/.next/server/app/onboarding.html +1 -1
- package/.next/server/app/onboarding.rsc +1 -1
- package/.next/server/app/onboarding.segments/_full.segment.rsc +1 -1
- package/.next/server/app/onboarding.segments/_head.segment.rsc +1 -1
- package/.next/server/app/onboarding.segments/_index.segment.rsc +1 -1
- package/.next/server/app/onboarding.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/onboarding.segments/onboarding/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/onboarding.segments/onboarding.segment.rsc +1 -1
- package/.next/server/app/personas.html +1 -1
- package/.next/server/app/personas.rsc +1 -1
- package/.next/server/app/personas.segments/_full.segment.rsc +1 -1
- package/.next/server/app/personas.segments/_head.segment.rsc +1 -1
- package/.next/server/app/personas.segments/_index.segment.rsc +1 -1
- package/.next/server/app/personas.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/personas.segments/personas/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/personas.segments/personas.segment.rsc +1 -1
- package/.next/server/app/settings.html +1 -1
- package/.next/server/app/settings.rsc +1 -1
- package/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/server/app/templates.html +1 -1
- package/.next/server/app/templates.rsc +1 -1
- package/.next/server/app/templates.segments/_full.segment.rsc +1 -1
- package/.next/server/app/templates.segments/_head.segment.rsc +1 -1
- package/.next/server/app/templates.segments/_index.segment.rsc +1 -1
- package/.next/server/app/templates.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/templates.segments/templates/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/templates.segments/templates.segment.rsc +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/trace +1 -1
- package/.next/trace-build +1 -1
- package/README.md +38 -15
- package/dist/cli/commands/doctor.js +116 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/init.js +211 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/start.js +298 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.js +54 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.js +97 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/connect.js +108 -0
- package/dist/cli/connect.js.map +1 -0
- package/dist/cli/index.js +99 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/port-utils.js +260 -0
- package/dist/cli/port-utils.js.map +1 -0
- package/dist/cli/runtime-env.js +60 -0
- package/dist/cli/runtime-env.js.map +1 -0
- package/dist/cli/shared.js +54 -0
- package/dist/cli/shared.js.map +1 -0
- package/dist/cli/ui.js +60 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/daemon/agents/claude.js +98 -0
- package/dist/daemon/agents/claude.js.map +1 -0
- package/dist/daemon/agents/codex.js +160 -0
- package/dist/daemon/agents/codex.js.map +1 -0
- package/dist/daemon/agents/gemini.js +111 -0
- package/dist/daemon/agents/gemini.js.map +1 -0
- package/dist/daemon/agents/index.js +59 -0
- package/dist/daemon/agents/index.js.map +1 -0
- package/dist/daemon/agents/kimi.js +206 -0
- package/dist/daemon/agents/kimi.js.map +1 -0
- package/dist/daemon/agents/opencode.js +228 -0
- package/dist/daemon/agents/opencode.js.map +1 -0
- package/dist/daemon/agents/openrouter.js +274 -0
- package/dist/daemon/agents/openrouter.js.map +1 -0
- package/dist/daemon/agents/parsers/claude.js +63 -0
- package/dist/daemon/agents/parsers/claude.js.map +1 -0
- package/dist/daemon/agents/parsers/codex.js +51 -0
- package/dist/daemon/agents/parsers/codex.js.map +1 -0
- package/dist/daemon/agents/parsers/gemini.js +144 -0
- package/dist/daemon/agents/parsers/gemini.js.map +1 -0
- package/dist/daemon/agents/parsers/index.js +31 -0
- package/dist/daemon/agents/parsers/index.js.map +1 -0
- package/dist/daemon/agents/parsers/kimi.js +8 -0
- package/dist/daemon/agents/parsers/kimi.js.map +1 -0
- package/dist/daemon/agents/parsers/opencode.js +105 -0
- package/dist/daemon/agents/parsers/opencode.js.map +1 -0
- package/dist/daemon/agents/parsers/openrouter.js +69 -0
- package/dist/daemon/agents/parsers/openrouter.js.map +1 -0
- package/dist/daemon/agents/parsers/shared.js +17 -0
- package/dist/daemon/agents/parsers/shared.js.map +1 -0
- package/dist/daemon/agents/preflight.js +83 -0
- package/dist/daemon/agents/preflight.js.map +1 -0
- package/dist/daemon/agents/quote.js +45 -0
- package/dist/daemon/agents/quote.js.map +1 -0
- package/dist/daemon/agents/sandbox-guard.js +69 -0
- package/dist/daemon/agents/sandbox-guard.js.map +1 -0
- package/dist/daemon/agents/types.js +6 -0
- package/dist/daemon/agents/types.js.map +1 -0
- package/dist/daemon/api-response.js +65 -0
- package/dist/daemon/api-response.js.map +1 -0
- package/dist/daemon/error-detector.js +329 -0
- package/dist/daemon/error-detector.js.map +1 -0
- package/dist/daemon/headless.js +533 -0
- package/dist/daemon/headless.js.map +1 -0
- package/dist/daemon/index.js +333 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/openrouter.js +192 -0
- package/dist/daemon/openrouter.js.map +1 -0
- package/dist/daemon/orchestrators/claude.js +163 -0
- package/dist/daemon/orchestrators/claude.js.map +1 -0
- package/dist/daemon/orchestrators/codex.js +101 -0
- package/dist/daemon/orchestrators/codex.js.map +1 -0
- package/dist/daemon/orchestrators/cursor-windsurf.js +118 -0
- package/dist/daemon/orchestrators/cursor-windsurf.js.map +1 -0
- package/dist/daemon/orchestrators/gemini.js +108 -0
- package/dist/daemon/orchestrators/gemini.js.map +1 -0
- package/dist/daemon/orchestrators/index.js +90 -0
- package/dist/daemon/orchestrators/index.js.map +1 -0
- package/dist/daemon/orchestrators/kimi.js +108 -0
- package/dist/daemon/orchestrators/kimi.js.map +1 -0
- package/dist/daemon/orchestrators/opencode.js +152 -0
- package/dist/daemon/orchestrators/opencode.js.map +1 -0
- package/dist/daemon/orchestrators/shared.js +60 -0
- package/dist/daemon/orchestrators/shared.js.map +1 -0
- package/dist/daemon/output-watcher.js +131 -0
- package/dist/daemon/output-watcher.js.map +1 -0
- package/dist/daemon/participant-aborts.js +123 -0
- package/dist/daemon/participant-aborts.js.map +1 -0
- package/dist/daemon/reaper.js +46 -0
- package/dist/daemon/reaper.js.map +1 -0
- package/dist/daemon/routes/chats-events.js +62 -0
- package/dist/daemon/routes/chats-events.js.map +1 -0
- package/dist/daemon/routes/chats-stream.js +241 -0
- package/dist/daemon/routes/chats-stream.js.map +1 -0
- package/dist/daemon/routes/chats-validation.js +13 -0
- package/dist/daemon/routes/chats-validation.js.map +1 -0
- package/dist/daemon/routes/chats.js +545 -0
- package/dist/daemon/routes/chats.js.map +1 -0
- package/dist/daemon/routes/openrouter.js +103 -0
- package/dist/daemon/routes/openrouter.js.map +1 -0
- package/dist/daemon/routes/settings.js +199 -0
- package/dist/daemon/routes/settings.js.map +1 -0
- package/dist/daemon/routes/stats.js +155 -0
- package/dist/daemon/routes/stats.js.map +1 -0
- package/dist/daemon/routes/system.js +208 -0
- package/dist/daemon/routes/system.js.map +1 -0
- package/dist/daemon/routes/templates-personas.js +254 -0
- package/dist/daemon/routes/templates-personas.js.map +1 -0
- package/dist/daemon/routes/voices.js +139 -0
- package/dist/daemon/routes/voices.js.map +1 -0
- package/dist/daemon/runner/doer-driver.js +346 -0
- package/dist/daemon/runner/doer-driver.js.map +1 -0
- package/dist/daemon/runner/doer.js +336 -0
- package/dist/daemon/runner/doer.js.map +1 -0
- package/dist/daemon/runner/prior-round.js +140 -0
- package/dist/daemon/runner/prior-round.js.map +1 -0
- package/dist/daemon/runner/prompt-builder.js +292 -0
- package/dist/daemon/runner/prompt-builder.js.map +1 -0
- package/dist/daemon/runner/review-only-phase.js +103 -0
- package/dist/daemon/runner/review-only-phase.js.map +1 -0
- package/dist/daemon/runner/reviewer-driver.js +410 -0
- package/dist/daemon/runner/reviewer-driver.js.map +1 -0
- package/dist/daemon/runner/reviewer.js +384 -0
- package/dist/daemon/runner/reviewer.js.map +1 -0
- package/dist/daemon/runner/run-with-fallback.js +56 -0
- package/dist/daemon/runner/run-with-fallback.js.map +1 -0
- package/dist/daemon/runner/sanitize-name.js +8 -0
- package/dist/daemon/runner/sanitize-name.js.map +1 -0
- package/dist/daemon/runner/stream-file-writer.js +116 -0
- package/dist/daemon/runner/stream-file-writer.js.map +1 -0
- package/dist/daemon/runner/swap-sidecar.js +102 -0
- package/dist/daemon/runner/swap-sidecar.js.map +1 -0
- package/dist/daemon/runner/template-fallback.js +119 -0
- package/dist/daemon/runner/template-fallback.js.map +1 -0
- package/dist/daemon/runner/types.js +3 -0
- package/dist/daemon/runner/types.js.map +1 -0
- package/dist/daemon/runner/verdict.js +51 -0
- package/dist/daemon/runner/verdict.js.map +1 -0
- package/dist/daemon/runner-multiplex.js +364 -0
- package/dist/daemon/runner-multiplex.js.map +1 -0
- package/dist/daemon/runner.js +427 -0
- package/dist/daemon/runner.js.map +1 -0
- package/dist/daemon/ship.js +340 -0
- package/dist/daemon/ship.js.map +1 -0
- package/dist/daemon/template-cache.js +37 -0
- package/dist/daemon/template-cache.js.map +1 -0
- package/dist/daemon/tmux-types.js +9 -0
- package/dist/daemon/tmux-types.js.map +1 -0
- package/dist/daemon/tmux.js +341 -0
- package/dist/daemon/tmux.js.map +1 -0
- package/dist/lib/atomic-write.js +55 -0
- package/dist/lib/atomic-write.js.map +1 -0
- package/dist/lib/chat-events-bus.js +27 -0
- package/dist/lib/chat-events-bus.js.map +1 -0
- package/dist/lib/chat-slug.js +105 -0
- package/dist/lib/chat-slug.js.map +1 -0
- package/dist/lib/cli-detect.js +388 -0
- package/dist/lib/cli-detect.js.map +1 -0
- package/dist/lib/cli-health.js +156 -0
- package/dist/lib/cli-health.js.map +1 -0
- package/dist/lib/cli-paths.js +113 -0
- package/dist/lib/cli-paths.js.map +1 -0
- package/dist/lib/cli-precheck.js +141 -0
- package/dist/lib/cli-precheck.js.map +1 -0
- package/dist/lib/db/chats.js +244 -0
- package/dist/lib/db/chats.js.map +1 -0
- package/dist/lib/db/connection.js +254 -0
- package/dist/lib/db/connection.js.map +1 -0
- package/dist/lib/db/index.js +34 -0
- package/dist/lib/db/index.js.map +1 -0
- package/dist/lib/db/personas.js +65 -0
- package/dist/lib/db/personas.js.map +1 -0
- package/dist/lib/db/phase-events.js +172 -0
- package/dist/lib/db/phase-events.js.map +1 -0
- package/dist/lib/db/secrets.js +53 -0
- package/dist/lib/db/secrets.js.map +1 -0
- package/dist/lib/db/settings.js +47 -0
- package/dist/lib/db/settings.js.map +1 -0
- package/dist/lib/db/templates.js +75 -0
- package/dist/lib/db/templates.js.map +1 -0
- package/dist/lib/db/voices.js +184 -0
- package/dist/lib/db/voices.js.map +1 -0
- package/dist/lib/lineage-maps.js +200 -0
- package/dist/lib/lineage-maps.js.map +1 -0
- package/dist/lib/logger.js +186 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/personas.js +117 -0
- package/dist/lib/personas.js.map +1 -0
- package/dist/lib/runtime-path.js +222 -0
- package/dist/lib/runtime-path.js.map +1 -0
- package/dist/lib/settings/billing.js +58 -0
- package/dist/lib/settings/billing.js.map +1 -0
- package/dist/lib/settings/permissions.js +81 -0
- package/dist/lib/settings/permissions.js.map +1 -0
- package/dist/lib/settings/transport.js +113 -0
- package/dist/lib/settings/transport.js.map +1 -0
- package/dist/lib/telemetry.js +290 -0
- package/dist/lib/telemetry.js.map +1 -0
- package/dist/lib/template-schema.js +319 -0
- package/dist/lib/template-schema.js.map +1 -0
- package/dist/lib/template-validation.js +82 -0
- package/dist/lib/template-validation.js.map +1 -0
- package/dist/lib/voices.js +533 -0
- package/dist/lib/voices.js.map +1 -0
- package/dist/mcp/client.js +138 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/index.js +178 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/tools.js +355 -0
- package/dist/mcp/tools.js.map +1 -0
- package/package.json +2 -1
- package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0beh7rg._.js +0 -6077
- package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0beh7rg._.js.map +0 -69
- package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0pjsj.j._.js +0 -6318
- package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0pjsj.j._.js.map +0 -71
- package/.next/dev/types/cache-life.d.ts +0 -145
- package/.next/dev/types/routes.d.ts +0 -84
- package/.next/dev/types/validator.ts +0 -178
- /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 9cD3yIOGe_Aqr17uJHTQS}/_buildManifest.js +0 -0
- /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 9cD3yIOGe_Aqr17uJHTQS}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 9cD3yIOGe_Aqr17uJHTQS}/_ssgManifest.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/lib/db/settings.ts"],"names":[],"mappings":";;;AAAA,mDAAwC;AAO3B,QAAA,QAAQ,GAAG;IACtB,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,EAAE,GAAG,MAAM,IAAA,qBAAK,GAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC;YAC9B,GAAG,EAAE,0CAA0C;YAC/C,IAAI,EAAE,CAAC,GAAG,CAAC;SACZ,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAe,CAAC;QAC7C,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAc;QACnC,MAAM,EAAE,GAAG,MAAM,IAAA,qBAAK,GAAE,CAAC;QACzB,MAAM,WAAW,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC9E,MAAM,EAAE,CAAC,OAAO,CAAC;YACf,GAAG,EAAE,4DAA4D;YACjE,IAAI,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC;SACzB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,EAAE,GAAG,MAAM,IAAA,qBAAK,GAAE,CAAC;QACzB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;QACnE,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,GAAG,CAAC,GAAa,CAAC;YAC5B,MAAM,CAAC,GAAG,GAAG,CAAC,KAAe,CAAC;YAC9B,IAAI,CAAC;gBACH,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,CAAC;YAAC,MAAM,CAAC;gBACP,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACb,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.templates = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const connection_js_1 = require("./connection.js");
|
|
6
|
+
const TemplateSchema = zod_1.z.object({
|
|
7
|
+
id: zod_1.z.string(),
|
|
8
|
+
source: zod_1.z.enum(['builtin', 'user']),
|
|
9
|
+
yaml: zod_1.z.string(),
|
|
10
|
+
created_at: zod_1.z.number().int(),
|
|
11
|
+
updated_at: zod_1.z.number().int(),
|
|
12
|
+
});
|
|
13
|
+
/**
|
|
14
|
+
* SQLite stores text columns as TEXT, but `INSERT ... readfile(...)` and
|
|
15
|
+
* some admin tools write BLOBs. Transport-specific note (verified during
|
|
16
|
+
* plan review):
|
|
17
|
+
* - better-sqlite3 surfaces BLOBs as Node Buffer (extends Uint8Array).
|
|
18
|
+
* - @libsql/client surfaces BLOBs as ArrayBuffer (NOT instanceof Uint8Array).
|
|
19
|
+
* Check ArrayBuffer first; fall through to Uint8Array as a defensive
|
|
20
|
+
* belt in case a Buffer-typed value sneaks in via direct stmt.run paths
|
|
21
|
+
* or future migrations.
|
|
22
|
+
*/
|
|
23
|
+
function coerceTemplateYaml(row) {
|
|
24
|
+
if (!row || typeof row !== 'object')
|
|
25
|
+
return row;
|
|
26
|
+
const r = row;
|
|
27
|
+
if (r.yaml instanceof ArrayBuffer) {
|
|
28
|
+
return { ...r, yaml: new TextDecoder().decode(new Uint8Array(r.yaml)) };
|
|
29
|
+
}
|
|
30
|
+
if (r.yaml instanceof Uint8Array) {
|
|
31
|
+
return { ...r, yaml: new TextDecoder().decode(r.yaml) };
|
|
32
|
+
}
|
|
33
|
+
return r;
|
|
34
|
+
}
|
|
35
|
+
exports.templates = {
|
|
36
|
+
async create(id, yaml, source = 'user') {
|
|
37
|
+
const db = await (0, connection_js_1.getDb)();
|
|
38
|
+
const now = Date.now();
|
|
39
|
+
await db.execute({
|
|
40
|
+
sql: `
|
|
41
|
+
INSERT OR REPLACE INTO templates (id, source, yaml, created_at, updated_at)
|
|
42
|
+
VALUES (?, ?, ?, ?, ?)
|
|
43
|
+
`,
|
|
44
|
+
args: [id, source, yaml, now, now],
|
|
45
|
+
});
|
|
46
|
+
const row = await exports.templates.getById(id);
|
|
47
|
+
if (!row)
|
|
48
|
+
throw new Error(`templates.create: row vanished: ${id}`);
|
|
49
|
+
return row;
|
|
50
|
+
},
|
|
51
|
+
async list() {
|
|
52
|
+
const db = await (0, connection_js_1.getDb)();
|
|
53
|
+
const result = await db.execute('SELECT * FROM templates ORDER BY created_at DESC');
|
|
54
|
+
return result.rows.map((row) => TemplateSchema.parse(coerceTemplateYaml(row)));
|
|
55
|
+
},
|
|
56
|
+
async getById(id) {
|
|
57
|
+
const db = await (0, connection_js_1.getDb)();
|
|
58
|
+
const result = await db.execute({
|
|
59
|
+
sql: 'SELECT * FROM templates WHERE id = ?',
|
|
60
|
+
args: [id],
|
|
61
|
+
});
|
|
62
|
+
if (result.rows.length === 0)
|
|
63
|
+
return null;
|
|
64
|
+
return TemplateSchema.parse(coerceTemplateYaml(result.rows[0]));
|
|
65
|
+
},
|
|
66
|
+
/** Hard-delete by id. Caller is responsible for refusing built-in rows
|
|
67
|
+
* before reaching here — the boot seed in src/daemon/index.ts re-creates
|
|
68
|
+
* built-in templates from `templates/*.yaml`, so a built-in delete would
|
|
69
|
+
* come back on next start. */
|
|
70
|
+
async delete(id) {
|
|
71
|
+
const db = await (0, connection_js_1.getDb)();
|
|
72
|
+
await db.execute({ sql: 'DELETE FROM templates WHERE id = ?', args: [id] });
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/lib/db/templates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.voices = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const connection_js_1 = require("./connection.js");
|
|
6
|
+
const VoiceRowSchema = zod_1.z.object({
|
|
7
|
+
id: zod_1.z.string(),
|
|
8
|
+
label: zod_1.z.string(),
|
|
9
|
+
source: zod_1.z.enum(['cli', 'api']),
|
|
10
|
+
provider: zod_1.z.string(),
|
|
11
|
+
model_id: zod_1.z.string(),
|
|
12
|
+
lineage: zod_1.z.enum(['anthropic', 'openai', 'google', 'opencode', 'moonshot']),
|
|
13
|
+
vendor_family: zod_1.z.string().nullable(),
|
|
14
|
+
input_cost_per_mtok: zod_1.z.number().nullable(),
|
|
15
|
+
output_cost_per_mtok: zod_1.z.number().nullable(),
|
|
16
|
+
enabled: zod_1.z.coerce.boolean(),
|
|
17
|
+
disabled_reason: zod_1.z.enum(['user', 'auto_missing']).nullable().optional().default(null),
|
|
18
|
+
created_at: zod_1.z.number().int(),
|
|
19
|
+
updated_at: zod_1.z.number().int(),
|
|
20
|
+
});
|
|
21
|
+
exports.voices = {
|
|
22
|
+
/**
|
|
23
|
+
* Upsert a voice row. Updates label/model_id/cost/vendor_family on
|
|
24
|
+
* existing rows. `enabled` and `disabled_reason` follow this precedence:
|
|
25
|
+
*
|
|
26
|
+
* 1. Caller passes the field explicitly → use it (caller intent wins).
|
|
27
|
+
* For disabled_reason, an explicit `null` means "clear".
|
|
28
|
+
* 2. Caller omits the field on an existing row → preserve current value.
|
|
29
|
+
* 3. Caller omits on a fresh row → default (`enabled=true`,
|
|
30
|
+
* `disabled_reason=null`).
|
|
31
|
+
*
|
|
32
|
+
* The previous "existing always wins on enabled" behaviour silently
|
|
33
|
+
* dropped seed overrides — meaning auto_missing rows could never be
|
|
34
|
+
* re-enabled when the CLI returned, and migration-data overrides were
|
|
35
|
+
* dead code on existing installs.
|
|
36
|
+
*/
|
|
37
|
+
async upsert(input) {
|
|
38
|
+
const db = await (0, connection_js_1.getDb)();
|
|
39
|
+
const now = Date.now();
|
|
40
|
+
const existing = await exports.voices.getById(input.id);
|
|
41
|
+
const enabledExplicit = input.enabled !== undefined;
|
|
42
|
+
const reasonExplicit = 'disabled_reason' in input;
|
|
43
|
+
let enabledValue;
|
|
44
|
+
if (enabledExplicit)
|
|
45
|
+
enabledValue = input.enabled ? 1 : 0;
|
|
46
|
+
else if (existing)
|
|
47
|
+
enabledValue = existing.enabled ? 1 : 0;
|
|
48
|
+
else
|
|
49
|
+
enabledValue = 1;
|
|
50
|
+
let reasonValue;
|
|
51
|
+
if (reasonExplicit)
|
|
52
|
+
reasonValue = input.disabled_reason ?? null;
|
|
53
|
+
else if (existing)
|
|
54
|
+
reasonValue = existing.disabled_reason ?? null;
|
|
55
|
+
else
|
|
56
|
+
reasonValue = null;
|
|
57
|
+
await db.execute({
|
|
58
|
+
sql: `
|
|
59
|
+
INSERT OR REPLACE INTO voices
|
|
60
|
+
(id, label, source, provider, model_id, lineage, vendor_family,
|
|
61
|
+
input_cost_per_mtok, output_cost_per_mtok, enabled,
|
|
62
|
+
disabled_reason, created_at, updated_at)
|
|
63
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
64
|
+
`,
|
|
65
|
+
args: [
|
|
66
|
+
input.id,
|
|
67
|
+
input.label,
|
|
68
|
+
input.source,
|
|
69
|
+
input.provider,
|
|
70
|
+
input.model_id,
|
|
71
|
+
input.lineage,
|
|
72
|
+
input.vendor_family ?? null,
|
|
73
|
+
input.input_cost_per_mtok ?? null,
|
|
74
|
+
input.output_cost_per_mtok ?? null,
|
|
75
|
+
enabledValue,
|
|
76
|
+
reasonValue,
|
|
77
|
+
existing?.created_at ?? now,
|
|
78
|
+
now,
|
|
79
|
+
],
|
|
80
|
+
});
|
|
81
|
+
const row = await exports.voices.getById(input.id);
|
|
82
|
+
if (!row)
|
|
83
|
+
throw new Error(`voices.upsert: row vanished: ${input.id}`);
|
|
84
|
+
return row;
|
|
85
|
+
},
|
|
86
|
+
async list(filter) {
|
|
87
|
+
const db = await (0, connection_js_1.getDb)();
|
|
88
|
+
const where = [];
|
|
89
|
+
const args = [];
|
|
90
|
+
if (filter?.lineage) {
|
|
91
|
+
where.push('lineage = ?');
|
|
92
|
+
args.push(filter.lineage);
|
|
93
|
+
}
|
|
94
|
+
if (filter?.source) {
|
|
95
|
+
where.push('source = ?');
|
|
96
|
+
args.push(filter.source);
|
|
97
|
+
}
|
|
98
|
+
if (filter?.provider) {
|
|
99
|
+
where.push('provider = ?');
|
|
100
|
+
args.push(filter.provider);
|
|
101
|
+
}
|
|
102
|
+
if (filter?.enabled !== undefined) {
|
|
103
|
+
where.push('enabled = ?');
|
|
104
|
+
args.push(filter.enabled ? 1 : 0);
|
|
105
|
+
}
|
|
106
|
+
const sql = 'SELECT * FROM voices' +
|
|
107
|
+
(where.length > 0 ? ' WHERE ' + where.join(' AND ') : '') +
|
|
108
|
+
' ORDER BY provider ASC, label ASC';
|
|
109
|
+
const result = await db.execute({ sql, args: args });
|
|
110
|
+
return result.rows.map((row) => VoiceRowSchema.parse(row));
|
|
111
|
+
},
|
|
112
|
+
async getById(id) {
|
|
113
|
+
const db = await (0, connection_js_1.getDb)();
|
|
114
|
+
const result = await db.execute({
|
|
115
|
+
sql: 'SELECT * FROM voices WHERE id = ?',
|
|
116
|
+
args: [id],
|
|
117
|
+
});
|
|
118
|
+
if (result.rows.length === 0)
|
|
119
|
+
return null;
|
|
120
|
+
return VoiceRowSchema.parse(result.rows[0]);
|
|
121
|
+
},
|
|
122
|
+
async update(id, partial) {
|
|
123
|
+
const db = await (0, connection_js_1.getDb)();
|
|
124
|
+
const existing = await exports.voices.getById(id);
|
|
125
|
+
if (!existing)
|
|
126
|
+
throw new Error(`Voice ${id} not found`);
|
|
127
|
+
const enabledChanged = partial.enabled !== undefined && partial.enabled !== existing.enabled;
|
|
128
|
+
const reasonExplicit = 'disabled_reason' in partial;
|
|
129
|
+
// Default reason policy: when the caller flips enabled without
|
|
130
|
+
// touching disabled_reason, we record intent automatically.
|
|
131
|
+
// - enabled true→false → 'user' (cockpit/API toggle counts as user
|
|
132
|
+
// intent unless caller says otherwise)
|
|
133
|
+
// - enabled false→true → null (re-enabling clears any stale auto/user)
|
|
134
|
+
let nextReason;
|
|
135
|
+
if (reasonExplicit) {
|
|
136
|
+
nextReason = partial.disabled_reason ?? null;
|
|
137
|
+
}
|
|
138
|
+
else if (enabledChanged) {
|
|
139
|
+
nextReason = partial.enabled ? null : 'user';
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
nextReason = existing.disabled_reason ?? null;
|
|
143
|
+
}
|
|
144
|
+
const next = {
|
|
145
|
+
label: partial.label ?? existing.label,
|
|
146
|
+
enabled: partial.enabled ?? existing.enabled,
|
|
147
|
+
input_cost_per_mtok: partial.input_cost_per_mtok !== undefined
|
|
148
|
+
? partial.input_cost_per_mtok
|
|
149
|
+
: existing.input_cost_per_mtok,
|
|
150
|
+
output_cost_per_mtok: partial.output_cost_per_mtok !== undefined
|
|
151
|
+
? partial.output_cost_per_mtok
|
|
152
|
+
: existing.output_cost_per_mtok,
|
|
153
|
+
model_id: partial.model_id ?? existing.model_id,
|
|
154
|
+
disabled_reason: nextReason,
|
|
155
|
+
};
|
|
156
|
+
await db.execute({
|
|
157
|
+
sql: `
|
|
158
|
+
UPDATE voices
|
|
159
|
+
SET label = ?, enabled = ?, input_cost_per_mtok = ?, output_cost_per_mtok = ?, model_id = ?,
|
|
160
|
+
disabled_reason = ?, updated_at = ?
|
|
161
|
+
WHERE id = ?
|
|
162
|
+
`,
|
|
163
|
+
args: [
|
|
164
|
+
next.label,
|
|
165
|
+
next.enabled ? 1 : 0,
|
|
166
|
+
next.input_cost_per_mtok,
|
|
167
|
+
next.output_cost_per_mtok,
|
|
168
|
+
next.model_id,
|
|
169
|
+
next.disabled_reason,
|
|
170
|
+
Date.now(),
|
|
171
|
+
id,
|
|
172
|
+
],
|
|
173
|
+
});
|
|
174
|
+
const row = await exports.voices.getById(id);
|
|
175
|
+
if (!row)
|
|
176
|
+
throw new Error(`voices.update: row vanished: ${id}`);
|
|
177
|
+
return row;
|
|
178
|
+
},
|
|
179
|
+
async delete(id) {
|
|
180
|
+
const db = await (0, connection_js_1.getDb)();
|
|
181
|
+
await db.execute({ sql: 'DELETE FROM voices WHERE id = ?', args: [id] });
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
//# sourceMappingURL=voices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voices.js","sourceRoot":"","sources":["../../../src/lib/db/voices.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Single source of truth for lineage display labels and colour swatches.
|
|
4
|
+
*
|
|
5
|
+
* Two parallel maps because the data flows from two directions:
|
|
6
|
+
* - Templates use the daemon-side YAML schema lineage names ("anthropic",
|
|
7
|
+
* "openai", "google", "opencode", "moonshot"). UI helpers translate
|
|
8
|
+
* these to the cockpit-side ReviewerLineage names ("claude", "codex",
|
|
9
|
+
* "gemini", "opencode", "kimi") via UI_LINEAGE_MAP / mapLineage.
|
|
10
|
+
* - Personas use the daemon-side names directly via recommended_lineage.
|
|
11
|
+
*
|
|
12
|
+
* Keep both maps keyed by the daemon-side names; let callers translate
|
|
13
|
+
* inputs once at the boundary and look up via the canonical key.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.UI_LINEAGE_BRAND = exports.UI_LINEAGE_AVAILABLE_MODELS = exports.UI_LINEAGE_DEFAULT_MODEL = exports.UI_LINEAGE_LABEL = exports.LINEAGE_LABEL = void 0;
|
|
17
|
+
exports.lineageLabel = lineageLabel;
|
|
18
|
+
exports.lineageDot = lineageDot;
|
|
19
|
+
exports.uiLineageLabel = uiLineageLabel;
|
|
20
|
+
exports.uiLineageDot = uiLineageDot;
|
|
21
|
+
exports.uiLineageDefaultModel = uiLineageDefaultModel;
|
|
22
|
+
exports.LINEAGE_LABEL = {
|
|
23
|
+
anthropic: "Claude",
|
|
24
|
+
openai: "Codex",
|
|
25
|
+
google: "Gemini",
|
|
26
|
+
opencode: "OpenCode",
|
|
27
|
+
moonshot: "Kimi",
|
|
28
|
+
};
|
|
29
|
+
/** Tailwind background colour class for the small lineage dot indicator. */
|
|
30
|
+
const LINEAGE_DOT = {
|
|
31
|
+
anthropic: "bg-violet-400",
|
|
32
|
+
openai: "bg-orange-400",
|
|
33
|
+
google: "bg-blue-400",
|
|
34
|
+
opencode: "bg-emerald-400",
|
|
35
|
+
moonshot: "bg-pink-400",
|
|
36
|
+
};
|
|
37
|
+
/** Returns the human label for a lineage, falling back to the raw key. */
|
|
38
|
+
function lineageLabel(lineage) {
|
|
39
|
+
if (!lineage)
|
|
40
|
+
return "";
|
|
41
|
+
return exports.LINEAGE_LABEL[lineage] ?? lineage;
|
|
42
|
+
}
|
|
43
|
+
/** Returns the dot colour class, falling back to a neutral muted dot. */
|
|
44
|
+
function lineageDot(lineage) {
|
|
45
|
+
if (!lineage)
|
|
46
|
+
return "bg-muted";
|
|
47
|
+
return LINEAGE_DOT[lineage] ?? "bg-muted";
|
|
48
|
+
}
|
|
49
|
+
exports.UI_LINEAGE_LABEL = {
|
|
50
|
+
claude: "Claude",
|
|
51
|
+
codex: "Codex",
|
|
52
|
+
gemini: "Gemini",
|
|
53
|
+
opencode: "OpenCode",
|
|
54
|
+
kimi: "Kimi",
|
|
55
|
+
// Meta-lineage for HTTP-dispatched voices. The real underlying lineage
|
|
56
|
+
// (anthropic/openai/google/etc.) is preserved on the voices table for
|
|
57
|
+
// diversity scoring; this label is what the cockpit cards show because
|
|
58
|
+
// the runner creates `reviewer-openrouter-N` dirs regardless of the
|
|
59
|
+
// underlying model.
|
|
60
|
+
openrouter: "OpenRouter",
|
|
61
|
+
};
|
|
62
|
+
const UI_LINEAGE_DOT = {
|
|
63
|
+
claude: "bg-violet-400",
|
|
64
|
+
codex: "bg-orange-400",
|
|
65
|
+
gemini: "bg-blue-400",
|
|
66
|
+
opencode: "bg-emerald-400",
|
|
67
|
+
kimi: "bg-pink-400",
|
|
68
|
+
// Cyan picked over amber — amber reads as "warning/in-progress" in UI
|
|
69
|
+
// convention, which clashed with lineage-as-brand semantics. Cyan is
|
|
70
|
+
// brand-distinct without state ambiguity.
|
|
71
|
+
openrouter: "bg-cyan-400",
|
|
72
|
+
};
|
|
73
|
+
function uiLineageLabel(lineage) {
|
|
74
|
+
if (!lineage)
|
|
75
|
+
return "";
|
|
76
|
+
return exports.UI_LINEAGE_LABEL[lineage] ?? lineage;
|
|
77
|
+
}
|
|
78
|
+
function uiLineageDot(lineage) {
|
|
79
|
+
if (!lineage)
|
|
80
|
+
return "bg-muted";
|
|
81
|
+
return UI_LINEAGE_DOT[lineage] ?? "bg-muted";
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Default model per UI lineage when a template's `models: []` is empty.
|
|
85
|
+
* Mirrors the per-lineage defaults used by phase-editor and new-template-dialog;
|
|
86
|
+
* lifted here so the run page can show the actual model on cards even when
|
|
87
|
+
* the YAML omits it.
|
|
88
|
+
*/
|
|
89
|
+
exports.UI_LINEAGE_DEFAULT_MODEL = {
|
|
90
|
+
claude: "claude-opus-4-7",
|
|
91
|
+
codex: "gpt-5.5",
|
|
92
|
+
gemini: "gemini-3.1-pro-preview",
|
|
93
|
+
opencode: "kimi-k2.6",
|
|
94
|
+
kimi: "kimi-k2.6",
|
|
95
|
+
// No sensible default for openrouter — user explicitly selects a model.
|
|
96
|
+
// Empty string lets `models?.[0] ?? defaultModel` resolve to "" which
|
|
97
|
+
// the run page treats as "no model" (skips the · model · separator).
|
|
98
|
+
openrouter: "",
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Curated model lists per CLI. Used as a fallback when the CLI doesn't
|
|
102
|
+
* expose a live model-listing command (claude / gemini / kimi today). For
|
|
103
|
+
* codex we run `codex debug models` at seed time and prefer the live
|
|
104
|
+
* catalog; the list below is the safety net if that probe fails.
|
|
105
|
+
*
|
|
106
|
+
* Cross-checked against `opencode models` (which aggregates upstream
|
|
107
|
+
* provider names) and `codex debug models` so entries here are real
|
|
108
|
+
* model ids the corresponding CLI accepts. Don't list speculative names —
|
|
109
|
+
* a wrong entry here is what makes the home page look unprofessional.
|
|
110
|
+
*
|
|
111
|
+
* Order = recommended first; the first entry is the canonical default
|
|
112
|
+
* and matches UI_LINEAGE_DEFAULT_MODEL.
|
|
113
|
+
*
|
|
114
|
+
* OpenCode is omitted because it's always discovered live via
|
|
115
|
+
* `opencode models` (gateway-aware). Cursor/Windsurf are IDE
|
|
116
|
+
* orchestrators with no model selection of their own.
|
|
117
|
+
*/
|
|
118
|
+
exports.UI_LINEAGE_AVAILABLE_MODELS = {
|
|
119
|
+
claude: [
|
|
120
|
+
"claude-opus-4-7",
|
|
121
|
+
"claude-sonnet-4-6",
|
|
122
|
+
"claude-sonnet-4-5",
|
|
123
|
+
"claude-haiku-4-5",
|
|
124
|
+
"claude-opus-4-5",
|
|
125
|
+
],
|
|
126
|
+
codex: [
|
|
127
|
+
"gpt-5.5",
|
|
128
|
+
"gpt-5.4",
|
|
129
|
+
"gpt-5.4-mini",
|
|
130
|
+
"gpt-5.3-codex",
|
|
131
|
+
"gpt-5.2",
|
|
132
|
+
],
|
|
133
|
+
// Gemini list verified 2026-05-04 by `gemini -p "ok" --model <X>`.
|
|
134
|
+
// gemini-3-flash returned ModelNotFoundError; only the names below
|
|
135
|
+
// are accepted by the current Gemini CLI version.
|
|
136
|
+
gemini: [
|
|
137
|
+
"gemini-3.1-pro-preview",
|
|
138
|
+
"gemini-2.5-pro",
|
|
139
|
+
"gemini-2.5-flash",
|
|
140
|
+
],
|
|
141
|
+
// Kimi list cross-checked against the official kimi-cli docs +
|
|
142
|
+
// source (2026-05-04):
|
|
143
|
+
// - CHANGELOG.md: kimi-k2.6, kimi-k2-thinking
|
|
144
|
+
// - klips/klip-6: kimi-k2-thinking-turbo (recommended turbo flagship)
|
|
145
|
+
// - sdks/kimi-sdk/README.md, klips/klip-7: kimi-k2-turbo-preview
|
|
146
|
+
// - Welcome screen dropped hardcoded kimi-k2.5, but it still works
|
|
147
|
+
// Not end-to-end probed because the dedicated kimi CLI needs a
|
|
148
|
+
// separate Moonshot account login; cross-referenced from official docs
|
|
149
|
+
// is the next-best signal.
|
|
150
|
+
// Index 0 must match UI_LINEAGE_DEFAULT_MODEL.kimi to keep the seed's
|
|
151
|
+
// immutable provider row pointed at the same default. kimi-k2.6 has
|
|
152
|
+
// been the chorus default since v0.7; not auto-rotating to the
|
|
153
|
+
// turbo-thinking variant here so existing installs don't silently
|
|
154
|
+
// change behavior. Users can still toggle the turbo entries on.
|
|
155
|
+
kimi: [
|
|
156
|
+
"kimi-k2.6",
|
|
157
|
+
"kimi-k2-thinking-turbo",
|
|
158
|
+
"kimi-k2-turbo-preview",
|
|
159
|
+
"kimi-k2-thinking",
|
|
160
|
+
"kimi-k2.5",
|
|
161
|
+
],
|
|
162
|
+
};
|
|
163
|
+
function uiLineageDefaultModel(lineage) {
|
|
164
|
+
if (!lineage)
|
|
165
|
+
return undefined;
|
|
166
|
+
return exports.UI_LINEAGE_DEFAULT_MODEL[lineage];
|
|
167
|
+
}
|
|
168
|
+
exports.UI_LINEAGE_BRAND = {
|
|
169
|
+
claude: {
|
|
170
|
+
dot: "bg-violet-400",
|
|
171
|
+
ring: "ring-violet-400/40",
|
|
172
|
+
gradient: "bg-gradient-to-b from-violet-500/15 to-card",
|
|
173
|
+
},
|
|
174
|
+
codex: {
|
|
175
|
+
dot: "bg-orange-400",
|
|
176
|
+
ring: "ring-orange-400/40",
|
|
177
|
+
gradient: "bg-gradient-to-b from-orange-500/15 to-card",
|
|
178
|
+
},
|
|
179
|
+
gemini: {
|
|
180
|
+
dot: "bg-blue-400",
|
|
181
|
+
ring: "ring-blue-400/40",
|
|
182
|
+
gradient: "bg-gradient-to-b from-blue-500/15 to-card",
|
|
183
|
+
},
|
|
184
|
+
opencode: {
|
|
185
|
+
dot: "bg-emerald-400",
|
|
186
|
+
ring: "ring-emerald-400/40",
|
|
187
|
+
gradient: "bg-gradient-to-b from-emerald-500/15 to-card",
|
|
188
|
+
},
|
|
189
|
+
kimi: {
|
|
190
|
+
dot: "bg-pink-400",
|
|
191
|
+
ring: "ring-pink-400/40",
|
|
192
|
+
gradient: "bg-gradient-to-b from-pink-500/15 to-card",
|
|
193
|
+
},
|
|
194
|
+
openrouter: {
|
|
195
|
+
dot: "bg-cyan-400",
|
|
196
|
+
ring: "ring-cyan-400/40",
|
|
197
|
+
gradient: "bg-gradient-to-b from-cyan-500/15 to-card",
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
//# sourceMappingURL=lineage-maps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lineage-maps.js","sourceRoot":"","sources":["../../src/lib/lineage-maps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Structured logging substrate (round-2-deferred §3).
|
|
4
|
+
*
|
|
5
|
+
* Every log line is one JSON object on stdout. The wire shape mirrors
|
|
6
|
+
* pino's defaults so a future swap to pino is transparent for any
|
|
7
|
+
* downstream consumer (`chorus logs --chat <id>`, log aggregators, etc):
|
|
8
|
+
*
|
|
9
|
+
* {"level":30,"time":1714654200000,"pid":1234,"hostname":"box","chatId":"abc","msg":"phase done"}
|
|
10
|
+
*
|
|
11
|
+
* - `level` is the numeric pino value (debug=20, info=30, warn=40, error=50)
|
|
12
|
+
* - `time` is ms since epoch (not `ts`)
|
|
13
|
+
* - `pid` + `hostname` are emitted once per line, captured at logger-init
|
|
14
|
+
*
|
|
15
|
+
* Child loggers carry their context fields — call sites in the runner do
|
|
16
|
+
* `const log = chatLogger(chatId, { phase: 'review', role: 'reviewer' })`
|
|
17
|
+
* log.info({lineage:'openai'}, 'reviewer started')
|
|
18
|
+
* and the chatId / phase / role get baked into every line that logger
|
|
19
|
+
* emits without each call site repeating them.
|
|
20
|
+
*
|
|
21
|
+
* No runtime dependency. The default is `console.log(JSON.stringify(...))` —
|
|
22
|
+
* if a future load profile justifies it, swap to pino without changing
|
|
23
|
+
* call sites OR the wire shape.
|
|
24
|
+
*
|
|
25
|
+
* `CHORUS_LOG_LEVEL` env var gates the floor (debug | info | warn | error).
|
|
26
|
+
* Default is info. Setting it to debug surfaces verbose internals; setting
|
|
27
|
+
* it to error silences phase-progress noise during dogfood streaming.
|
|
28
|
+
*
|
|
29
|
+
* Round-1 dogfood (PR #7) caught:
|
|
30
|
+
* - ts/level were clobberable by user fields → core fields now win
|
|
31
|
+
* - JSON.stringify could throw on circular refs / BigInt → safe wrapper
|
|
32
|
+
* emits a degraded fallback line instead of crashing the daemon
|
|
33
|
+
* - Error objects serialized to `{}` → expanded to {message,name,stack}
|
|
34
|
+
*
|
|
35
|
+
* Test seam: pass `_writer` when constructing — tests inject a function
|
|
36
|
+
* that pushes lines into an array and assert exact JSON shape. Production
|
|
37
|
+
* call sites use the default `console.log` chain.
|
|
38
|
+
*/
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.logger = void 0;
|
|
41
|
+
exports.createLogger = createLogger;
|
|
42
|
+
exports.chatLogger = chatLogger;
|
|
43
|
+
const os_1 = require("os");
|
|
44
|
+
/** Pino-compatible numeric levels. Wire shape matches pino's default. */
|
|
45
|
+
const LEVEL_RANK = {
|
|
46
|
+
debug: 20,
|
|
47
|
+
info: 30,
|
|
48
|
+
warn: 40,
|
|
49
|
+
error: 50,
|
|
50
|
+
};
|
|
51
|
+
const defaultWriter = (line) => {
|
|
52
|
+
// process.stdout.write is sync + line-buffered when stdout is a pipe (the
|
|
53
|
+
// typical daemon shape). console.log adds a trailing newline that we
|
|
54
|
+
// want; it's also what existing chorus call sites use, so output ordering
|
|
55
|
+
// stays the same when sites migrate.
|
|
56
|
+
console.log(line);
|
|
57
|
+
};
|
|
58
|
+
/** Captured once at module load. Daemon doesn't move between machines. */
|
|
59
|
+
const HOST = (() => {
|
|
60
|
+
try {
|
|
61
|
+
return (0, os_1.hostname)();
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return 'unknown';
|
|
65
|
+
}
|
|
66
|
+
})();
|
|
67
|
+
const PID = process.pid;
|
|
68
|
+
/**
|
|
69
|
+
* Replacer for JSON.stringify that:
|
|
70
|
+
* - Expands `Error` instances to {message, name, stack, cause?}
|
|
71
|
+
* - Defangs BigInt to its string form (JSON.stringify throws on raw BigInt)
|
|
72
|
+
* - Detects circular references and returns the literal string
|
|
73
|
+
* '[Circular]' rather than throwing.
|
|
74
|
+
*
|
|
75
|
+
* Falls through to the default stringify behaviour for everything else.
|
|
76
|
+
*/
|
|
77
|
+
function buildSafeReplacer() {
|
|
78
|
+
const seen = new WeakSet();
|
|
79
|
+
return function safe(_key, value) {
|
|
80
|
+
if (typeof value === 'bigint')
|
|
81
|
+
return value.toString();
|
|
82
|
+
if (value instanceof Error) {
|
|
83
|
+
const out = {
|
|
84
|
+
message: value.message,
|
|
85
|
+
name: value.name,
|
|
86
|
+
stack: value.stack,
|
|
87
|
+
};
|
|
88
|
+
const cause = value.cause;
|
|
89
|
+
if (cause !== undefined)
|
|
90
|
+
out.cause = cause;
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
if (value !== null && typeof value === 'object') {
|
|
94
|
+
if (seen.has(value))
|
|
95
|
+
return '[Circular]';
|
|
96
|
+
seen.add(value);
|
|
97
|
+
}
|
|
98
|
+
return value;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Stringify a log line without ever throwing. The replacer handles
|
|
103
|
+
* Error / BigInt / circular refs; if it still fails (toJSON that
|
|
104
|
+
* throws, exotic proxies, etc.) we emit a degraded fallback line
|
|
105
|
+
* referencing the failure rather than crashing the daemon's logger.
|
|
106
|
+
*/
|
|
107
|
+
function safeStringify(line) {
|
|
108
|
+
try {
|
|
109
|
+
return JSON.stringify(line, buildSafeReplacer());
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
return JSON.stringify({
|
|
113
|
+
level: line.level,
|
|
114
|
+
time: line.time,
|
|
115
|
+
pid: line.pid,
|
|
116
|
+
hostname: line.hostname,
|
|
117
|
+
msg: 'log_serialize_failed',
|
|
118
|
+
err: err instanceof Error ? err.message : String(err),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
class LoggerImpl {
|
|
123
|
+
bound;
|
|
124
|
+
threshold;
|
|
125
|
+
writer;
|
|
126
|
+
constructor(bound, threshold, writer) {
|
|
127
|
+
this.bound = bound;
|
|
128
|
+
this.threshold = threshold;
|
|
129
|
+
this.writer = writer;
|
|
130
|
+
}
|
|
131
|
+
emit(level, fieldsOrMsg, msg) {
|
|
132
|
+
if (LEVEL_RANK[level] < this.threshold)
|
|
133
|
+
return;
|
|
134
|
+
const isFields = typeof fieldsOrMsg === 'object' && fieldsOrMsg !== null;
|
|
135
|
+
const fields = isFields ? fieldsOrMsg : {};
|
|
136
|
+
const message = isFields ? msg : fieldsOrMsg;
|
|
137
|
+
// Spread order: user-provided spreads FIRST, then core wire fields
|
|
138
|
+
// (level, time, pid, hostname). User fields cannot clobber the core
|
|
139
|
+
// shape — round-1 dogfood caught a `log.info({level:'fake'})` foot-gun.
|
|
140
|
+
const line = {
|
|
141
|
+
...this.bound,
|
|
142
|
+
...fields,
|
|
143
|
+
...(message !== undefined ? { msg: message } : {}),
|
|
144
|
+
level: LEVEL_RANK[level],
|
|
145
|
+
time: Date.now(),
|
|
146
|
+
pid: PID,
|
|
147
|
+
hostname: HOST,
|
|
148
|
+
};
|
|
149
|
+
this.writer(safeStringify(line));
|
|
150
|
+
}
|
|
151
|
+
debug(fields, msg) { this.emit('debug', fields, msg); }
|
|
152
|
+
info(fields, msg) { this.emit('info', fields, msg); }
|
|
153
|
+
warn(fields, msg) { this.emit('warn', fields, msg); }
|
|
154
|
+
error(fields, msg) { this.emit('error', fields, msg); }
|
|
155
|
+
child(bound) {
|
|
156
|
+
return new LoggerImpl({ ...this.bound, ...bound }, this.threshold, this.writer);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function resolveThreshold() {
|
|
160
|
+
const raw = (process.env.CHORUS_LOG_LEVEL ?? '').toLowerCase();
|
|
161
|
+
if (raw === 'debug' || raw === 'info' || raw === 'warn' || raw === 'error') {
|
|
162
|
+
return LEVEL_RANK[raw];
|
|
163
|
+
}
|
|
164
|
+
return LEVEL_RANK.info;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Build the root logger. The daemon constructs ONE root and passes child
|
|
168
|
+
* loggers down to call sites. Tests construct their own with an in-memory
|
|
169
|
+
* writer.
|
|
170
|
+
*/
|
|
171
|
+
function createLogger(opts) {
|
|
172
|
+
const writer = opts?._writer ?? defaultWriter;
|
|
173
|
+
const threshold = opts?._level ? LEVEL_RANK[opts._level] : resolveThreshold();
|
|
174
|
+
return new LoggerImpl({}, threshold, writer);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Module-singleton root logger for general-purpose call sites that don't
|
|
178
|
+
* have a chat / request context. Prefer `chatLogger(chatId)` when the
|
|
179
|
+
* chat correlation key is known.
|
|
180
|
+
*/
|
|
181
|
+
exports.logger = createLogger();
|
|
182
|
+
/** Convenience: child logger pre-bound to a chat correlation key. */
|
|
183
|
+
function chatLogger(chatId, extra) {
|
|
184
|
+
return exports.logger.child({ chatId, ...extra });
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=logger.js.map
|