chorus-codes 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.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/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/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 +240 -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 → 8H2I8TTPlrKuWCV-SxY5f}/_buildManifest.js +0 -0
- /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 8H2I8TTPlrKuWCV-SxY5f}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 8H2I8TTPlrKuWCV-SxY5f}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.validateTemplateYaml = validateTemplateYaml;
|
|
7
|
+
/**
|
|
8
|
+
* Shared template-YAML validation. Used by:
|
|
9
|
+
* - the cockpit dialog (live as the user types) to show inline errors
|
|
10
|
+
* and gate the Save button
|
|
11
|
+
* - the daemon's POST /templates handler to reject bad shapes server-side
|
|
12
|
+
*
|
|
13
|
+
* Two-stage validation matches the cockpit's UX:
|
|
14
|
+
* 1. yaml.parse — surfaces syntax errors with line/col
|
|
15
|
+
* 2. TemplateSchema (zod) — surfaces structural errors with field paths
|
|
16
|
+
*
|
|
17
|
+
* The helper is intentionally pure: no I/O, no logging. Safe to call from
|
|
18
|
+
* a React render path or a Fastify handler.
|
|
19
|
+
*/
|
|
20
|
+
const yaml_1 = __importDefault(require("yaml"));
|
|
21
|
+
const template_schema_1 = require("./template-schema");
|
|
22
|
+
const VALID_RESULT = Object.freeze({
|
|
23
|
+
valid: true,
|
|
24
|
+
issues: [],
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* Parse + validate a template YAML string. Returns a flat issue list
|
|
28
|
+
* suitable for inline rendering. Empty input is treated as invalid with
|
|
29
|
+
* a clear message rather than silently passing.
|
|
30
|
+
*/
|
|
31
|
+
function validateTemplateYaml(input) {
|
|
32
|
+
const trimmed = input.trim();
|
|
33
|
+
if (trimmed.length === 0) {
|
|
34
|
+
return {
|
|
35
|
+
valid: false,
|
|
36
|
+
issues: [{ path: '<yaml>', message: 'Template YAML is empty.' }],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
// Stage 1: YAML syntax.
|
|
40
|
+
let parsed;
|
|
41
|
+
try {
|
|
42
|
+
parsed = yaml_1.default.parse(input);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
// yaml package errors carry .linePos { line, col } when available; fall
|
|
46
|
+
// back to the raw message so the user always gets *something*.
|
|
47
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
48
|
+
const linePos = err
|
|
49
|
+
.linePos?.[0];
|
|
50
|
+
return {
|
|
51
|
+
valid: false,
|
|
52
|
+
issues: [
|
|
53
|
+
{
|
|
54
|
+
path: '<yaml>',
|
|
55
|
+
message: msg,
|
|
56
|
+
...(linePos ? { line: linePos.line, col: linePos.col } : {}),
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
if (parsed === null || parsed === undefined) {
|
|
62
|
+
return {
|
|
63
|
+
valid: false,
|
|
64
|
+
issues: [
|
|
65
|
+
{
|
|
66
|
+
path: '<yaml>',
|
|
67
|
+
message: 'Template YAML parsed to null — at minimum it must define id, name, and phases.',
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Stage 2: structural validation against the daemon's TemplateSchema.
|
|
73
|
+
const result = template_schema_1.TemplateSchema.safeParse(parsed);
|
|
74
|
+
if (result.success)
|
|
75
|
+
return VALID_RESULT;
|
|
76
|
+
const issues = result.error.issues.map((i) => ({
|
|
77
|
+
path: i.path.length > 0 ? i.path.join('.') : '<root>',
|
|
78
|
+
message: i.message,
|
|
79
|
+
}));
|
|
80
|
+
return { valid: false, issues };
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=template-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-validation.js","sourceRoot":"","sources":["../../src/lib/template-validation.ts"],"names":[],"mappings":";;;;;AA6CA,oDAoDC;AAjGD;;;;;;;;;;;;GAYG;AACH,gDAAwB;AACxB,uDAAmD;AAqBnD,MAAM,YAAY,GAA6B,MAAM,CAAC,MAAM,CAAC;IAC3D,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,EAAE;CACX,CAAC,CAAC;AAEH;;;;GAIG;AACH,SAAgB,oBAAoB,CAAC,KAAa;IAChD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC;SACjE,CAAC;IACJ,CAAC;IAED,wBAAwB;IACxB,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,cAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,wEAAwE;QACxE,+DAA+D;QAC/D,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAI,GAA0D;aACxE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE;gBACN;oBACE,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,GAAG;oBACZ,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC7D;aACF;SACF,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC5C,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE;gBACN;oBACE,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,gFAAgF;iBAC1F;aACF;SACF,CAAC;IACJ,CAAC;IAED,sEAAsE;IACtE,MAAM,MAAM,GAAG,gCAAc,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,YAAY,CAAC;IAExC,MAAM,MAAM,GAA8B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ;QACrD,OAAO,EAAE,CAAC,CAAC,OAAO;KACnB,CAAC,CAAC,CAAC;IACJ,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Voices seed + migration logic.
|
|
4
|
+
*
|
|
5
|
+
* Two phases per planning/voices.md:
|
|
6
|
+
* - Phase 1 (synchronous, pre-listen): seed single-model CLIs +
|
|
7
|
+
* auto-disable absent CLIs + first-boot migration from
|
|
8
|
+
* <lineage>.enabled_models settings.
|
|
9
|
+
* - Phase 2 (background warmup, post-listen): shell out to
|
|
10
|
+
* `opencode models`, seed gateway-prefixed multi-model voices.
|
|
11
|
+
* Allowed up to 10s timeout. Daemon doesn't block boot on this.
|
|
12
|
+
*
|
|
13
|
+
* Single-model CLIs use IMMUTABLE IDs. Versioned model upgrades rewrite
|
|
14
|
+
* model_id+label without rotating the row's primary key (gem-2 round 1
|
|
15
|
+
* BLOCKER 3).
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports._internals = void 0;
|
|
19
|
+
exports.classifyOpencodeModel = classifyOpencodeModel;
|
|
20
|
+
exports.seedCliVoices = seedCliVoices;
|
|
21
|
+
exports.seedOpencodeVoicesAsync = seedOpencodeVoicesAsync;
|
|
22
|
+
const node_child_process_1 = require("node:child_process");
|
|
23
|
+
const node_util_1 = require("node:util");
|
|
24
|
+
const cli_detect_js_1 = require("./cli-detect.js");
|
|
25
|
+
const index_js_1 = require("./db/index.js");
|
|
26
|
+
const lineage_maps_js_1 = require("./lineage-maps.js");
|
|
27
|
+
const run = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
28
|
+
/**
|
|
29
|
+
* Daemon-side lineage → UI-side lineage (for UI_LINEAGE_AVAILABLE_MODELS
|
|
30
|
+
* lookup, which is keyed by UI names — per round 2 cdx-1 BLOCKER).
|
|
31
|
+
*/
|
|
32
|
+
const LINEAGE_TO_UI = {
|
|
33
|
+
anthropic: 'claude',
|
|
34
|
+
openai: 'codex',
|
|
35
|
+
google: 'gemini',
|
|
36
|
+
opencode: 'opencode',
|
|
37
|
+
moonshot: 'kimi',
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Single-model CLIs: each maps to (provider, daemon-lineage). Used by
|
|
41
|
+
* Phase 1 seed. The provider IS the voice's immutable id.
|
|
42
|
+
*/
|
|
43
|
+
const SINGLE_MODEL_CLIS = [
|
|
44
|
+
{ cli: 'claude-code', provider: 'claude-code', lineage: 'anthropic' },
|
|
45
|
+
{ cli: 'codex-cli', provider: 'codex-cli', lineage: 'openai' },
|
|
46
|
+
{ cli: 'gemini-cli', provider: 'gemini-cli', lineage: 'google' },
|
|
47
|
+
{ cli: 'kimi-cli', provider: 'kimi-cli', lineage: 'moonshot' },
|
|
48
|
+
];
|
|
49
|
+
/**
|
|
50
|
+
* OpenCode gateway model name → (lineage, vendor_family). The model name
|
|
51
|
+
* suffix drives the mapping, not the gateway prefix — `opencode-go/kimi-*`
|
|
52
|
+
* and `opencode-zen/kimi-*` are both lineage=moonshot. Diversity scoring
|
|
53
|
+
* reads `lineage`; cost UX reads `vendor_family`.
|
|
54
|
+
*
|
|
55
|
+
* Reused for OpenRouter model ids (`anthropic/claude-...`,
|
|
56
|
+
* `openai/gpt-...`, etc.) — the qualified prefix pattern is identical.
|
|
57
|
+
*/
|
|
58
|
+
function classifyOpencodeModel(qualified) {
|
|
59
|
+
// Strip gateway prefix; everything after the first slash is the model name.
|
|
60
|
+
const slash = qualified.indexOf('/');
|
|
61
|
+
const gateway = slash >= 0 ? qualified.slice(0, slash) : '';
|
|
62
|
+
const tail = slash >= 0 ? qualified.slice(slash + 1) : qualified;
|
|
63
|
+
const t = tail.toLowerCase();
|
|
64
|
+
// opencode-go gateway: every voice here runs through the `opencode`
|
|
65
|
+
// binary (no separate kimi/anthropic/openai CLI invocation). Lineage is
|
|
66
|
+
// 'opencode' regardless of model family — otherwise template editor
|
|
67
|
+
// renders impossible combos like (lineage=Kimi, model=opencode-go/kimi-k2.6),
|
|
68
|
+
// implying a kimi-CLI subscription that may not exist. Model family
|
|
69
|
+
// moves into `vendor_family` so diversity scoring and cost UX still
|
|
70
|
+
// see "moonshot" / "deepseek" / "anthropic" / etc.
|
|
71
|
+
if (gateway === 'opencode-go') {
|
|
72
|
+
if (t.includes('kimi'))
|
|
73
|
+
return { lineage: 'opencode', vendor_family: 'moonshot' };
|
|
74
|
+
if (t.includes('claude'))
|
|
75
|
+
return { lineage: 'opencode', vendor_family: 'anthropic' };
|
|
76
|
+
if (t.includes('gpt') || /(?:^|[^a-z])o[1-9](?:$|[^a-z0-9])/.test(t)) {
|
|
77
|
+
return { lineage: 'opencode', vendor_family: 'openai' };
|
|
78
|
+
}
|
|
79
|
+
if (t.includes('gemini'))
|
|
80
|
+
return { lineage: 'opencode', vendor_family: 'google' };
|
|
81
|
+
if (t.includes('deepseek'))
|
|
82
|
+
return { lineage: 'opencode', vendor_family: 'deepseek' };
|
|
83
|
+
if (t.includes('llama') || t.includes('meta'))
|
|
84
|
+
return { lineage: 'opencode', vendor_family: 'meta' };
|
|
85
|
+
if (t.includes('mistral') || t.includes('mixtral'))
|
|
86
|
+
return { lineage: 'opencode', vendor_family: 'mistral' };
|
|
87
|
+
if (t.includes('grok') || t.includes('xai'))
|
|
88
|
+
return { lineage: 'opencode', vendor_family: 'xai' };
|
|
89
|
+
return { lineage: 'opencode', vendor_family: null };
|
|
90
|
+
}
|
|
91
|
+
// Native lineage matching (OpenRouter `anthropic/...`, `openai/...`,
|
|
92
|
+
// `google/...`, `moonshotai/...`, etc.) — the qualified prefix doesn't
|
|
93
|
+
// route through opencode binary, so lineage tracks the model family.
|
|
94
|
+
if (t.includes('kimi'))
|
|
95
|
+
return { lineage: 'moonshot', vendor_family: null };
|
|
96
|
+
if (t.includes('claude'))
|
|
97
|
+
return { lineage: 'anthropic', vendor_family: null };
|
|
98
|
+
if (t.includes('gpt') || /(?:^|[^a-z])o[1-9](?:$|[^a-z0-9])/.test(t)) {
|
|
99
|
+
return { lineage: 'openai', vendor_family: null };
|
|
100
|
+
}
|
|
101
|
+
if (t.includes('gemini'))
|
|
102
|
+
return { lineage: 'google', vendor_family: null };
|
|
103
|
+
if (t.includes('deepseek'))
|
|
104
|
+
return { lineage: 'opencode', vendor_family: 'deepseek' };
|
|
105
|
+
if (t.includes('llama') || t.includes('meta'))
|
|
106
|
+
return { lineage: 'opencode', vendor_family: 'meta' };
|
|
107
|
+
if (t.includes('mistral') || t.includes('mixtral'))
|
|
108
|
+
return { lineage: 'opencode', vendor_family: 'mistral' };
|
|
109
|
+
if (t.includes('grok') || t.includes('xai'))
|
|
110
|
+
return { lineage: 'opencode', vendor_family: 'xai' };
|
|
111
|
+
return { lineage: 'opencode', vendor_family: null };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Live model probe for Codex CLI — `codex debug models` renders the raw
|
|
115
|
+
* model catalog as JSON. Filter to `visibility=='list'` so we don't seed
|
|
116
|
+
* hidden internals (`codex-auto-review`, `gpt-oss-*`).
|
|
117
|
+
*
|
|
118
|
+
* Returns null on any failure (CLI absent, JSON parse, schema mismatch,
|
|
119
|
+
* timeout) so the caller falls back to the static catalog.
|
|
120
|
+
*/
|
|
121
|
+
async function probeCodexModelsLive() {
|
|
122
|
+
try {
|
|
123
|
+
const { stdout } = await run('codex', ['debug', 'models'], { timeout: 5_000 });
|
|
124
|
+
const parsed = JSON.parse(stdout);
|
|
125
|
+
if (typeof parsed !== 'object' || parsed === null ||
|
|
126
|
+
!Array.isArray(parsed.models)) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
const models = parsed.models;
|
|
130
|
+
const out = [];
|
|
131
|
+
for (const m of models) {
|
|
132
|
+
if (typeof m.slug === 'string' && m.visibility === 'list')
|
|
133
|
+
out.push(m.slug);
|
|
134
|
+
}
|
|
135
|
+
return out.length > 0 ? out : null;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Phase 1 — synchronous seed for single-model CLIs.
|
|
143
|
+
*
|
|
144
|
+
* - For each detected single-model CLI: upsert immutable voice row
|
|
145
|
+
* (id = provider) with the latest model from
|
|
146
|
+
* UI_LINEAGE_AVAILABLE_MODELS[ui_lineage][0].
|
|
147
|
+
* - For each previously-detected single-model CLI now absent: set
|
|
148
|
+
* enabled=0 (auto-disable, NOT delete) — phase composition shouldn't
|
|
149
|
+
* dispatch to a CLI the user uninstalled.
|
|
150
|
+
* - First-boot migration: if voices table is empty AND <lineage>.enabled_models
|
|
151
|
+
* settings exist, seed disabled rows for non-enabled curated models so
|
|
152
|
+
* the user's prior toggles are preserved.
|
|
153
|
+
* - First-install (no migration data, no existing voices): seed every
|
|
154
|
+
* curated/discovered model row as enabled so the user can opt out of
|
|
155
|
+
* anything they don't want — vs. the prior "default model only enabled"
|
|
156
|
+
* which left the home page looking sparse.
|
|
157
|
+
*
|
|
158
|
+
* Returns counts for logging.
|
|
159
|
+
*/
|
|
160
|
+
async function seedCliVoices() {
|
|
161
|
+
const detect = (0, cli_detect_js_1.detectAllClis)();
|
|
162
|
+
const detectedById = new Map(detect.map((d) => [d.id, d]));
|
|
163
|
+
// First-boot migration: only fires when voices table is completely empty
|
|
164
|
+
// AND at least one <lineage>.enabled_models setting exists (i.e. the user
|
|
165
|
+
// is upgrading from v0.7 hardening cycle, not starting fresh).
|
|
166
|
+
const existingVoices = await index_js_1.voices.list();
|
|
167
|
+
const isFirstBoot = existingVoices.length === 0;
|
|
168
|
+
const migrationData = isFirstBoot ? await readMigrationSettings() : null;
|
|
169
|
+
// Live model discovery for CLIs that expose a programmatic catalog.
|
|
170
|
+
// Codex is the only single-model CLI that does (`codex debug models`).
|
|
171
|
+
// Claude / Gemini / Kimi don't, so they always use the static catalog.
|
|
172
|
+
const codexLive = detectedById.get('codex-cli')?.found
|
|
173
|
+
? await probeCodexModelsLive()
|
|
174
|
+
: null;
|
|
175
|
+
let added = 0;
|
|
176
|
+
let updated = 0;
|
|
177
|
+
let disabled = 0;
|
|
178
|
+
// === Phase 1a: single-model CLIs ===
|
|
179
|
+
// Two cases per CLI:
|
|
180
|
+
// - DETECTED: upsert the immutable provider row with the latest model
|
|
181
|
+
// + (on first boot) seed curated non-default rows so fleet cards
|
|
182
|
+
// can list them.
|
|
183
|
+
// - NOT DETECTED on first boot but settings exist: migrate anyway
|
|
184
|
+
// (round 1 cdx-1 BLOCKER — otherwise the user's gemini.enabled_models
|
|
185
|
+
// would never migrate if gemini-cli isn't installed yet, and once
|
|
186
|
+
// voices table is non-empty the migration won't re-fire). Rows seed
|
|
187
|
+
// with the migrated enabled state; later when the CLI installs,
|
|
188
|
+
// voices.upsert preserves enabled and just rewrites model_id+label.
|
|
189
|
+
// - NOT DETECTED on regular boot (existing row enabled): auto-disable.
|
|
190
|
+
for (const { cli, provider, lineage } of SINGLE_MODEL_CLIS) {
|
|
191
|
+
const detected = detectedById.get(cli);
|
|
192
|
+
const existingRow = existingVoices.find((v) => v.id === provider);
|
|
193
|
+
const uiLineage = LINEAGE_TO_UI[lineage];
|
|
194
|
+
// Prefer live probe over static catalog; fall back to static when the
|
|
195
|
+
// CLI doesn't expose model listing or the probe failed.
|
|
196
|
+
const liveModels = cli === 'codex-cli' ? codexLive : null;
|
|
197
|
+
const staticModels = lineage_maps_js_1.UI_LINEAGE_AVAILABLE_MODELS[uiLineage] ?? [];
|
|
198
|
+
const models = liveModels ?? staticModels;
|
|
199
|
+
const latestModel = models[0] ?? `${cli}-default`;
|
|
200
|
+
const label = `${humanLineageLabel(lineage)} (${latestModel})`;
|
|
201
|
+
if (detected?.found) {
|
|
202
|
+
// Default-enabled rule:
|
|
203
|
+
// - With migration data → respect the user's prior setting per
|
|
204
|
+
// migrationFor() (absent setting → default-only enabled).
|
|
205
|
+
// - First install (no migration, fresh voices table) → ALL curated
|
|
206
|
+
// models start enabled so the user can opt out, not opt in. Per
|
|
207
|
+
// v0.8 onboarding UX request.
|
|
208
|
+
// - Subsequent boots → voices.upsert preserves existing `enabled`
|
|
209
|
+
// so user toggles are sticky.
|
|
210
|
+
// - Re-detect of a previously auto_missing row → re-enable +
|
|
211
|
+
// clear disabled_reason. One flaky boot used to leave the row
|
|
212
|
+
// silently off forever; this restores it the moment detection
|
|
213
|
+
// succeeds again, while still respecting deliberate user toggles
|
|
214
|
+
// (disabled_reason='user' rows are NOT auto-restored).
|
|
215
|
+
const wasAutoMissing = existingRow?.enabled === false &&
|
|
216
|
+
existingRow?.disabled_reason === 'auto_missing';
|
|
217
|
+
const enabledOverride = wasAutoMissing
|
|
218
|
+
? true
|
|
219
|
+
: migrationData
|
|
220
|
+
? migrationFor(migrationData, uiLineage, latestModel)
|
|
221
|
+
: (isFirstBoot ? true : undefined);
|
|
222
|
+
const before = await index_js_1.voices.getById(provider);
|
|
223
|
+
await index_js_1.voices.upsert({
|
|
224
|
+
id: provider,
|
|
225
|
+
label,
|
|
226
|
+
source: 'cli',
|
|
227
|
+
provider,
|
|
228
|
+
model_id: latestModel,
|
|
229
|
+
lineage,
|
|
230
|
+
...(enabledOverride !== undefined ? { enabled: enabledOverride } : {}),
|
|
231
|
+
// Clear the auto_missing tombstone when re-enabling. For all other
|
|
232
|
+
// paths leave disabled_reason untouched (omitted → preserved).
|
|
233
|
+
...(wasAutoMissing ? { disabled_reason: null } : {}),
|
|
234
|
+
});
|
|
235
|
+
if (before)
|
|
236
|
+
updated++;
|
|
237
|
+
else
|
|
238
|
+
added++;
|
|
239
|
+
// Reconcile non-default curated/discovered models on EVERY boot —
|
|
240
|
+
// not just first boot. Why: when the catalog changes (new model
|
|
241
|
+
// added in lineage-maps.ts, codex live probe surfaces a new slug),
|
|
242
|
+
// existing installs should pick up the additions automatically.
|
|
243
|
+
// The previous "first-boot only" guard left users stuck on the
|
|
244
|
+
// catalog snapshot from when they first installed.
|
|
245
|
+
const catalogIds = new Set(models.map((m) => `${provider}:${m}`));
|
|
246
|
+
for (const m of models.slice(1)) {
|
|
247
|
+
const id = `${provider}:${m}`;
|
|
248
|
+
const exists = await index_js_1.voices.getById(id);
|
|
249
|
+
if (exists) {
|
|
250
|
+
// Row already there — voices.upsert preserves enabled state, so
|
|
251
|
+
// don't pass `enabled` (would silently re-enable user-disabled
|
|
252
|
+
// rows on every boot). Just refresh the label in case
|
|
253
|
+
// humanLineageLabel changed.
|
|
254
|
+
await index_js_1.voices.upsert({
|
|
255
|
+
id,
|
|
256
|
+
label: `${humanLineageLabel(lineage)} (${m})`,
|
|
257
|
+
source: 'cli',
|
|
258
|
+
provider,
|
|
259
|
+
model_id: m,
|
|
260
|
+
lineage,
|
|
261
|
+
});
|
|
262
|
+
updated++;
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
// Net-new row. enabled state:
|
|
266
|
+
// - migration data present → respect user's prior intent
|
|
267
|
+
// - first install → opt-out (enabled=true)
|
|
268
|
+
// - subsequent boot picking up a NEW catalog entry → enabled=true
|
|
269
|
+
// so users see "we added Sonnet 4.5" without having to opt in
|
|
270
|
+
const enabled = migrationData
|
|
271
|
+
? (migrationFor(migrationData, uiLineage, m) ?? false)
|
|
272
|
+
: true;
|
|
273
|
+
await index_js_1.voices.upsert({
|
|
274
|
+
id,
|
|
275
|
+
label: `${humanLineageLabel(lineage)} (${m})`,
|
|
276
|
+
source: 'cli',
|
|
277
|
+
provider,
|
|
278
|
+
model_id: m,
|
|
279
|
+
lineage,
|
|
280
|
+
enabled,
|
|
281
|
+
});
|
|
282
|
+
added++;
|
|
283
|
+
}
|
|
284
|
+
// Catalog drift: delete rows whose model is no longer in the
|
|
285
|
+
// current catalog (deprecated entries cleaned out of
|
|
286
|
+
// lineage-maps.ts or vanished from a live probe). Hard delete,
|
|
287
|
+
// not disable — leaving deprecated model names like
|
|
288
|
+
// "claude-sonnet-4" hanging in the fleet UI confuses new users
|
|
289
|
+
// ("is this Sonnet 4.6?"). The immutable provider-id row at
|
|
290
|
+
// `id === provider` is intentionally skipped — that one rotates
|
|
291
|
+
// its model_id forward to the latest model and never gets dropped.
|
|
292
|
+
const sameProviderRows = existingVoices.filter((v) => v.provider === provider && v.id !== provider);
|
|
293
|
+
for (const row of sameProviderRows) {
|
|
294
|
+
if (catalogIds.has(row.id))
|
|
295
|
+
continue;
|
|
296
|
+
await index_js_1.voices.delete(row.id);
|
|
297
|
+
disabled++;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
else if (existingRow && existingRow.enabled) {
|
|
301
|
+
// Regular boot, CLI was present last boot but is now absent —
|
|
302
|
+
// auto-disable (not delete). Per round 1 deepseek MED.
|
|
303
|
+
//
|
|
304
|
+
// Stamp disabled_reason='auto_missing' so the re-detect branch above
|
|
305
|
+
// can safely re-enable when the CLI returns. Without the reason flag
|
|
306
|
+
// a transient PATH/detection miss would silently disable forever
|
|
307
|
+
// (the bug that led gemini-3.1-pro-preview to stay off across boots).
|
|
308
|
+
await index_js_1.voices.update(provider, {
|
|
309
|
+
enabled: false,
|
|
310
|
+
disabled_reason: 'auto_missing',
|
|
311
|
+
});
|
|
312
|
+
disabled++;
|
|
313
|
+
}
|
|
314
|
+
else if (isFirstBoot && migrationData && hasMigrationDataFor(migrationData, uiLineage)) {
|
|
315
|
+
// First boot, CLI not currently detected, but the user has a prior
|
|
316
|
+
// <lineage>.enabled_models setting — migrate the rows now so the
|
|
317
|
+
// intent isn't lost. When the CLI later installs, voices.upsert
|
|
318
|
+
// preserves the enabled state. Per round 1 cdx-1 BLOCKER.
|
|
319
|
+
const enabledOverride = migrationFor(migrationData, uiLineage, latestModel);
|
|
320
|
+
await index_js_1.voices.upsert({
|
|
321
|
+
id: provider,
|
|
322
|
+
label,
|
|
323
|
+
source: 'cli',
|
|
324
|
+
provider,
|
|
325
|
+
model_id: latestModel,
|
|
326
|
+
lineage,
|
|
327
|
+
...(enabledOverride !== undefined ? { enabled: enabledOverride } : {}),
|
|
328
|
+
});
|
|
329
|
+
added++;
|
|
330
|
+
for (const m of models.slice(1)) {
|
|
331
|
+
const id = `${provider}:${m}`;
|
|
332
|
+
const enabled = migrationFor(migrationData, uiLineage, m) ?? false;
|
|
333
|
+
await index_js_1.voices.upsert({
|
|
334
|
+
id,
|
|
335
|
+
label: `${humanLineageLabel(lineage)} (${m})`,
|
|
336
|
+
source: 'cli',
|
|
337
|
+
provider,
|
|
338
|
+
model_id: m,
|
|
339
|
+
lineage,
|
|
340
|
+
enabled,
|
|
341
|
+
});
|
|
342
|
+
added++;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return { added, updated, disabled };
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Whether the migration data has an EXPLICIT setting (not absent) for
|
|
350
|
+
* this lineage. Empty array still counts — that's the user explicitly
|
|
351
|
+
* disabling everything in v0.7. Absent (undefined value) means the
|
|
352
|
+
* user never touched this lineage; in that case we don't seed anything
|
|
353
|
+
* for an undetected CLI (no migration intent to preserve).
|
|
354
|
+
*/
|
|
355
|
+
function hasMigrationDataFor(data, ui) {
|
|
356
|
+
return data.byUiLineage.get(ui) !== undefined;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Phase 2 — background warmup for OpenCode multi-model voices. Called
|
|
360
|
+
* AFTER `fastify.listen()` so a slow/broken `opencode models` shell-out
|
|
361
|
+
* doesn't add up to 10s of boot latency. Best-effort; logs but never
|
|
362
|
+
* crashes the daemon.
|
|
363
|
+
*/
|
|
364
|
+
async function seedOpencodeVoicesAsync() {
|
|
365
|
+
const detect = (0, cli_detect_js_1.detectAllClis)();
|
|
366
|
+
const opencode = detect.find((d) => d.id === 'opencode-cli');
|
|
367
|
+
const existingOpencode = await index_js_1.voices.list({ provider: 'opencode-cli' });
|
|
368
|
+
if (!opencode?.found) {
|
|
369
|
+
// CLI not detected — auto-disable any existing opencode voices.
|
|
370
|
+
// Stamp disabled_reason so the next successful boot can auto-restore
|
|
371
|
+
// (mirrors the SINGLE_MODEL_CLIS branch above).
|
|
372
|
+
let disabled = 0;
|
|
373
|
+
for (const v of existingOpencode) {
|
|
374
|
+
if (v.enabled) {
|
|
375
|
+
await index_js_1.voices.update(v.id, {
|
|
376
|
+
enabled: false,
|
|
377
|
+
disabled_reason: 'auto_missing',
|
|
378
|
+
});
|
|
379
|
+
disabled++;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return { added: 0, updated: 0, disabled };
|
|
383
|
+
}
|
|
384
|
+
let modelList;
|
|
385
|
+
try {
|
|
386
|
+
const { stdout } = await run('opencode', ['models'], { timeout: 10_000 });
|
|
387
|
+
modelList = stdout
|
|
388
|
+
.split('\n')
|
|
389
|
+
.map((l) => l.trim())
|
|
390
|
+
.filter((l) => l.length > 0);
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
// Shell-out failed (timeout, ENOENT after path mutation, etc.) — log
|
|
394
|
+
// and skip. Existing voices stay as-is until the next successful boot.
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
// First-install default rule for OpenCode: enable every model in the
|
|
398
|
+
// user's Go plan (opencode-go/*) and leave the other gateways
|
|
399
|
+
// (opencode/*, opencode-zen/*) disabled. The Go plan is the paid tier
|
|
400
|
+
// most users will be on; other gateways are pay-as-you-go and shouldn't
|
|
401
|
+
// bill silently from a fresh install.
|
|
402
|
+
const isOpencodeGoModel = (qualified) => qualified.startsWith('opencode-go/');
|
|
403
|
+
const migration = await readOpencodeMigration();
|
|
404
|
+
const isFirstBoot = existingOpencode.length === 0;
|
|
405
|
+
let added = 0;
|
|
406
|
+
let updated = 0;
|
|
407
|
+
const disabled = 0;
|
|
408
|
+
const seenIds = new Set();
|
|
409
|
+
// Iterate the FULL discovered list so disabled-but-discoverable models
|
|
410
|
+
// get rows for the user to re-enable (cdx-1 round 1 MED).
|
|
411
|
+
for (const qualified of modelList) {
|
|
412
|
+
const id = `opencode-cli:${qualified}`;
|
|
413
|
+
seenIds.add(id);
|
|
414
|
+
const { lineage, vendor_family } = classifyOpencodeModel(qualified);
|
|
415
|
+
const label = qualified;
|
|
416
|
+
const before = await index_js_1.voices.getById(id);
|
|
417
|
+
const wasAutoMissing = before?.enabled === false && before?.disabled_reason === 'auto_missing';
|
|
418
|
+
// enabled state policy:
|
|
419
|
+
// - Existing row, auto_missing tombstone → re-enable + clear reason
|
|
420
|
+
// (the opencode CLI was absent on a prior boot and is now back).
|
|
421
|
+
// - Existing row, anything else → preserve (omit enabled).
|
|
422
|
+
// - Net-new row + migration data → user's prior intent.
|
|
423
|
+
// - Net-new row, first install → opencode-go/* enabled, others off.
|
|
424
|
+
// - Net-new row, mid-life new model → off (user opts in via fleet).
|
|
425
|
+
let enabledOverride;
|
|
426
|
+
if (wasAutoMissing) {
|
|
427
|
+
enabledOverride = true;
|
|
428
|
+
}
|
|
429
|
+
else if (!before) {
|
|
430
|
+
if (migration) {
|
|
431
|
+
enabledOverride = migrationFor(migration, 'opencode', qualified) ?? false;
|
|
432
|
+
}
|
|
433
|
+
else if (isFirstBoot) {
|
|
434
|
+
enabledOverride = isOpencodeGoModel(qualified);
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
enabledOverride = false;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
await index_js_1.voices.upsert({
|
|
441
|
+
id,
|
|
442
|
+
label,
|
|
443
|
+
source: 'cli',
|
|
444
|
+
provider: 'opencode-cli',
|
|
445
|
+
model_id: qualified,
|
|
446
|
+
lineage,
|
|
447
|
+
vendor_family,
|
|
448
|
+
...(enabledOverride !== undefined ? { enabled: enabledOverride } : {}),
|
|
449
|
+
...(wasAutoMissing ? { disabled_reason: null } : {}),
|
|
450
|
+
});
|
|
451
|
+
if (before)
|
|
452
|
+
updated++;
|
|
453
|
+
else
|
|
454
|
+
added++;
|
|
455
|
+
}
|
|
456
|
+
return { added, updated, disabled };
|
|
457
|
+
}
|
|
458
|
+
async function readMigrationSettings() {
|
|
459
|
+
const byUiLineage = new Map();
|
|
460
|
+
let anySet = false;
|
|
461
|
+
const lineages = ['claude', 'codex', 'gemini', 'kimi', 'opencode'];
|
|
462
|
+
for (const ui of lineages) {
|
|
463
|
+
const raw = await index_js_1.settings.get(`${ui}.enabled_models`);
|
|
464
|
+
if (raw === null || raw === undefined) {
|
|
465
|
+
byUiLineage.set(ui, undefined);
|
|
466
|
+
}
|
|
467
|
+
else if (Array.isArray(raw)) {
|
|
468
|
+
byUiLineage.set(ui, raw.filter((x) => typeof x === 'string'));
|
|
469
|
+
anySet = true;
|
|
470
|
+
}
|
|
471
|
+
else {
|
|
472
|
+
byUiLineage.set(ui, undefined);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
// Returning null when zero settings exist is what makes the "fresh install
|
|
476
|
+
// = enable everything" branch fire in seedCliVoices. Any explicit setting
|
|
477
|
+
// (including empty array) means the user touched the config and we
|
|
478
|
+
// respect the prior intent.
|
|
479
|
+
return anySet ? { byUiLineage } : null;
|
|
480
|
+
}
|
|
481
|
+
async function readOpencodeMigration() {
|
|
482
|
+
const raw = await index_js_1.settings.get('opencode.enabled_models');
|
|
483
|
+
if (raw === null || raw === undefined)
|
|
484
|
+
return null;
|
|
485
|
+
const list = Array.isArray(raw) ? raw.filter((x) => typeof x === 'string') : undefined;
|
|
486
|
+
const byUiLineage = new Map([['opencode', list]]);
|
|
487
|
+
return { byUiLineage };
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Migration semantics (per cdx-1 round 1 MED):
|
|
491
|
+
* - Setting absent → undefined → "default model only" (return undefined
|
|
492
|
+
* here; caller treats undefined as "use the default = enabled").
|
|
493
|
+
* - Empty array → return false (no models enabled).
|
|
494
|
+
* - Populated array → return whether `model` is in the list.
|
|
495
|
+
*
|
|
496
|
+
* Special-case for the latest/default model: when the setting is absent,
|
|
497
|
+
* we want default model = enabled and other curated models = disabled. The
|
|
498
|
+
* caller (seedCliVoices) checks `migrationFor(... defaultModel)` separately
|
|
499
|
+
* from non-default models and applies this fallback for the default only.
|
|
500
|
+
*/
|
|
501
|
+
function migrationFor(data, uiLineage, model) {
|
|
502
|
+
const list = data.byUiLineage.get(uiLineage);
|
|
503
|
+
if (list === undefined) {
|
|
504
|
+
// Absent: use the default-model rule. The first model in
|
|
505
|
+
// UI_LINEAGE_AVAILABLE_MODELS[uiLineage] is the default; everything
|
|
506
|
+
// else is disabled. For OpenCode the "default" is determined by the
|
|
507
|
+
// FLEET_DEFAULTS set, not this function — caller handles that.
|
|
508
|
+
if (uiLineage === 'opencode')
|
|
509
|
+
return undefined;
|
|
510
|
+
const models = lineage_maps_js_1.UI_LINEAGE_AVAILABLE_MODELS[uiLineage] ?? [];
|
|
511
|
+
return models[0] === model;
|
|
512
|
+
}
|
|
513
|
+
if (list.length === 0)
|
|
514
|
+
return false;
|
|
515
|
+
return list.includes(model);
|
|
516
|
+
}
|
|
517
|
+
function humanLineageLabel(l) {
|
|
518
|
+
switch (l) {
|
|
519
|
+
case 'anthropic': return 'Claude';
|
|
520
|
+
case 'openai': return 'Codex';
|
|
521
|
+
case 'google': return 'Gemini';
|
|
522
|
+
case 'opencode': return 'OpenCode';
|
|
523
|
+
case 'moonshot': return 'Kimi';
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
/** @internal — exported for unit tests. */
|
|
527
|
+
exports._internals = {
|
|
528
|
+
classifyOpencodeModel,
|
|
529
|
+
migrationFor,
|
|
530
|
+
LINEAGE_TO_UI,
|
|
531
|
+
SINGLE_MODEL_CLIS,
|
|
532
|
+
};
|
|
533
|
+
//# sourceMappingURL=voices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voices.js","sourceRoot":"","sources":["../../src/lib/voices.ts"],"names":[],"mappings":"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"}
|