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,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerSystemRoutes = registerSystemRoutes;
|
|
4
|
+
const index_js_1 = require("../../lib/db/index.js");
|
|
5
|
+
const api_response_js_1 = require("../api-response.js");
|
|
6
|
+
function registerSystemRoutes(fastify, deps) {
|
|
7
|
+
// List blocked chats — consumed by the MCP `list_blocked` tool. There
|
|
8
|
+
// is no cockpit /blocked page today; older comments referenced one
|
|
9
|
+
// that never landed.
|
|
10
|
+
fastify.get('/blocked', async () => {
|
|
11
|
+
try {
|
|
12
|
+
const items = await index_js_1.chats.list({ status: 'blocked' });
|
|
13
|
+
return (0, api_response_js_1.successResponse)((0, api_response_js_1.listEnvelope)(items));
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
17
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
// ─── CLI health snapshot ──────────────────────────────────────────────
|
|
21
|
+
fastify.get('/cli/health', async () => {
|
|
22
|
+
try {
|
|
23
|
+
const { getAllHealth } = await import('../../lib/cli-health.js');
|
|
24
|
+
const items = await getAllHealth();
|
|
25
|
+
return (0, api_response_js_1.successResponse)((0, api_response_js_1.listEnvelope)(items));
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
29
|
+
return (0, api_response_js_1.errorResponse)('internal', message);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
// ─── Onboarding: detect installed CLIs + validate manual paths ────────
|
|
33
|
+
fastify.get('/onboard/detect-clis', async () => {
|
|
34
|
+
try {
|
|
35
|
+
const { detectAllClis } = await import('../../lib/cli-detect.js');
|
|
36
|
+
return (0, api_response_js_1.successResponse)((0, api_response_js_1.listEnvelope)(detectAllClis()));
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
40
|
+
return (0, api_response_js_1.errorResponse)('internal', message);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
fastify.post('/onboard/validate-cli-path', async (req) => {
|
|
44
|
+
try {
|
|
45
|
+
const { id, path: customPath } = req.body || {};
|
|
46
|
+
if (!id || typeof customPath !== 'string') {
|
|
47
|
+
return (0, api_response_js_1.errorResponse)('bad_request', 'id and path are required');
|
|
48
|
+
}
|
|
49
|
+
const { validateCliPath } = await import('../../lib/cli-detect.js');
|
|
50
|
+
return (0, api_response_js_1.successResponse)(validateCliPath(id, customPath));
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
54
|
+
return (0, api_response_js_1.errorResponse)('internal', message);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
/**
|
|
58
|
+
* Persist a validated manual CLI path so it survives daemon restarts
|
|
59
|
+
* and is visible to subsequent reviewer spawns. Pre-fix the cockpit
|
|
60
|
+
* just kept successful validations in React state — the next boot lost
|
|
61
|
+
* the hint entirely (the bug the launch dogfood pass surfaced).
|
|
62
|
+
*
|
|
63
|
+
* Caller MUST validate via `/onboard/validate-cli-path` first; we
|
|
64
|
+
* re-validate here as a safety net so a stale React state can't store
|
|
65
|
+
* a path that no longer runs.
|
|
66
|
+
*/
|
|
67
|
+
fastify.post('/onboard/save-cli-path', async (req) => {
|
|
68
|
+
try {
|
|
69
|
+
const { id, path: customPath } = req.body || {};
|
|
70
|
+
if (!id || typeof customPath !== 'string') {
|
|
71
|
+
return (0, api_response_js_1.errorResponse)('bad_request', 'id and path are required');
|
|
72
|
+
}
|
|
73
|
+
const { validateCliPath, clearDetectionCache } = await import('../../lib/cli-detect.js');
|
|
74
|
+
const validation = validateCliPath(id, customPath);
|
|
75
|
+
if (!validation.found) {
|
|
76
|
+
return (0, api_response_js_1.errorResponse)('validation', validation.reason ?? 'path failed validation');
|
|
77
|
+
}
|
|
78
|
+
const { cliPaths } = await import('../../lib/cli-paths.js');
|
|
79
|
+
await cliPaths.set(id, validation.path);
|
|
80
|
+
// Refresh sync caches so subsequent detection + spawns honour the
|
|
81
|
+
// new path immediately, not after the next boot.
|
|
82
|
+
await cliPaths.refreshCache();
|
|
83
|
+
clearDetectionCache();
|
|
84
|
+
// Also refresh the headless spawn PATH so the new dirname is
|
|
85
|
+
// prepended without requiring a daemon restart.
|
|
86
|
+
try {
|
|
87
|
+
const { buildRuntimePath } = await import('../../lib/runtime-path.js');
|
|
88
|
+
const { setSpawnPath } = await import('../headless.js');
|
|
89
|
+
const merged = await buildRuntimePath({
|
|
90
|
+
additionalDirs: cliPaths.cachedDirs(),
|
|
91
|
+
});
|
|
92
|
+
setSpawnPath(merged);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
/* spawn-path refresh is best-effort; spawnEnv() already
|
|
96
|
+
prepends cli-paths cachedDirs at spawn time */
|
|
97
|
+
}
|
|
98
|
+
return (0, api_response_js_1.successResponse)({ id, path: validation.path });
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
102
|
+
return (0, api_response_js_1.errorResponse)('internal', message);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
/** Read every saved manual CLI path. Drives the cockpit's "saved" badge
|
|
106
|
+
* and `chorus doctor`. Empty values are omitted. */
|
|
107
|
+
fastify.get('/onboard/cli-paths', async () => {
|
|
108
|
+
try {
|
|
109
|
+
const { cliPaths } = await import('../../lib/cli-paths.js');
|
|
110
|
+
const all = await cliPaths.listAll();
|
|
111
|
+
const compact = {};
|
|
112
|
+
for (const [id, p] of Object.entries(all)) {
|
|
113
|
+
if (p)
|
|
114
|
+
compact[id] = p;
|
|
115
|
+
}
|
|
116
|
+
return (0, api_response_js_1.successResponse)(compact);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
120
|
+
return (0, api_response_js_1.errorResponse)('internal', message);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
/** Forget a saved manual path. Cockpit calls this when the user
|
|
124
|
+
* clicks "use auto-detect instead". */
|
|
125
|
+
fastify.delete('/onboard/cli-paths/:id', async (req) => {
|
|
126
|
+
try {
|
|
127
|
+
const { cliPaths } = await import('../../lib/cli-paths.js');
|
|
128
|
+
const { clearDetectionCache } = await import('../../lib/cli-detect.js');
|
|
129
|
+
await cliPaths.clear(req.params.id);
|
|
130
|
+
clearDetectionCache();
|
|
131
|
+
return (0, api_response_js_1.successResponse)({ id: req.params.id, cleared: true });
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
135
|
+
return (0, api_response_js_1.errorResponse)('internal', message);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
// ─── Orchestrators (editors that call chorus via MCP) ────────────────
|
|
139
|
+
fastify.get('/orchestrators', async () => {
|
|
140
|
+
try {
|
|
141
|
+
const { listOrchestrators } = await import('../orchestrators/index.js');
|
|
142
|
+
return (0, api_response_js_1.successResponse)((0, api_response_js_1.listEnvelope)(listOrchestrators()));
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
146
|
+
return (0, api_response_js_1.errorResponse)('internal', message);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
fastify.post('/orchestrators/:name/connect', async (request) => {
|
|
150
|
+
try {
|
|
151
|
+
const { connectByName, listOrchestrators } = await import('../orchestrators/index.js');
|
|
152
|
+
const result = await connectByName(request.params.name, {
|
|
153
|
+
binPath: deps.chorusBinPath,
|
|
154
|
+
});
|
|
155
|
+
const status = listOrchestrators().find((o) => o.name === request.params.name);
|
|
156
|
+
return (0, api_response_js_1.successResponse)({ ...result, status });
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
160
|
+
return (0, api_response_js_1.errorResponse)('validation', message);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
// ─── OpenCode model discovery ────────────────────────────────────────
|
|
164
|
+
// Lists models the local `opencode` CLI knows about, grouped by gateway
|
|
165
|
+
// prefix (`opencode/`, `opencode-go/`, `opencode-zen/`). Used by the
|
|
166
|
+
// onboarding flow so users can pick which subscription models they want
|
|
167
|
+
// chorus to expose as voices.
|
|
168
|
+
fastify.get('/orchestrators/opencode/models', async () => {
|
|
169
|
+
try {
|
|
170
|
+
// Resolve the actual installed path rather than spawning bare
|
|
171
|
+
// 'opencode' — when the daemon's $PATH doesn't include the
|
|
172
|
+
// installer's bin dir (common: opencode lives at
|
|
173
|
+
// ~/.opencode/bin, not in /usr/local/bin), bare lookup ENOENTs
|
|
174
|
+
// even when detection found the binary fine.
|
|
175
|
+
const { detectAllClis } = await import('../../lib/cli-detect.js');
|
|
176
|
+
const opencode = detectAllClis().find((c) => c.id === 'opencode-cli');
|
|
177
|
+
if (!opencode?.found || !opencode.path) {
|
|
178
|
+
return (0, api_response_js_1.errorResponse)('cli_failed', 'opencode CLI not found on this host. Install from https://opencode.ai or set its path manually in onboarding.');
|
|
179
|
+
}
|
|
180
|
+
const { execFile } = await import('node:child_process');
|
|
181
|
+
const { promisify } = await import('node:util');
|
|
182
|
+
const run = promisify(execFile);
|
|
183
|
+
const { stdout } = await run(opencode.path, ['models'], { timeout: 10_000 });
|
|
184
|
+
const flat = stdout
|
|
185
|
+
.split('\n')
|
|
186
|
+
.map((l) => l.trim())
|
|
187
|
+
.filter((l) => l.length > 0);
|
|
188
|
+
const gateways = {};
|
|
189
|
+
for (const m of flat) {
|
|
190
|
+
const slash = m.indexOf('/');
|
|
191
|
+
const gw = slash > 0 ? m.slice(0, slash) : 'other';
|
|
192
|
+
if (!gateways[gw])
|
|
193
|
+
gateways[gw] = [];
|
|
194
|
+
gateways[gw].push(m);
|
|
195
|
+
}
|
|
196
|
+
// Fleet defaults — kimi + deepseek via Go subscription. Only suggest
|
|
197
|
+
// those that actually appear in the user's `opencode models` output.
|
|
198
|
+
const FLEET = ['opencode-go/kimi-k2.6', 'opencode-go/deepseek-v4-pro'];
|
|
199
|
+
const defaultPicks = FLEET.filter((m) => flat.includes(m));
|
|
200
|
+
return (0, api_response_js_1.successResponse)({ gateways, flat, defaultPicks });
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
204
|
+
return (0, api_response_js_1.errorResponse)('cli_failed', message);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../../src/daemon/routes/system.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,254 @@
|
|
|
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.registerTemplateRoutes = registerTemplateRoutes;
|
|
7
|
+
exports.registerPersonaRoutes = registerPersonaRoutes;
|
|
8
|
+
const yaml_1 = __importDefault(require("yaml"));
|
|
9
|
+
const index_js_1 = require("../../lib/db/index.js");
|
|
10
|
+
const template_validation_js_1 = require("../../lib/template-validation.js");
|
|
11
|
+
const api_response_js_1 = require("../api-response.js");
|
|
12
|
+
function registerTemplateRoutes(fastify) {
|
|
13
|
+
// List all templates
|
|
14
|
+
fastify.get('/templates', async () => {
|
|
15
|
+
try {
|
|
16
|
+
const list = await index_js_1.templates.list();
|
|
17
|
+
return (0, api_response_js_1.successResponse)((0, api_response_js_1.listEnvelope)(list));
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
21
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
// Get one template
|
|
25
|
+
fastify.get('/templates/:id', async (request) => {
|
|
26
|
+
try {
|
|
27
|
+
const template = await index_js_1.templates.getById(request.params.id);
|
|
28
|
+
if (!template) {
|
|
29
|
+
return (0, api_response_js_1.errorResponse)('not_found', `Template ${request.params.id} not found`);
|
|
30
|
+
}
|
|
31
|
+
const parsed = yaml_1.default.parse(template.yaml);
|
|
32
|
+
return (0, api_response_js_1.successResponse)({ ...template, parsed });
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
36
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
// Save / update template.
|
|
40
|
+
//
|
|
41
|
+
// Source promotion semantics:
|
|
42
|
+
// - New rows (no existing) → source='user'.
|
|
43
|
+
// - Edits to a builtin → source='user' AND we promote *only* if the YAML
|
|
44
|
+
// actually changed. Why: seedBuiltinTemplates() resyncs every builtin
|
|
45
|
+
// row from prompts/templates/*.yaml on each daemon boot. If we left an
|
|
46
|
+
// edited row marked 'builtin', the seed loop would clobber the user's
|
|
47
|
+
// changes on next restart. Promoting to 'user' makes the seed loop
|
|
48
|
+
// skip the row (it only refreshes source='builtin'), so edits persist.
|
|
49
|
+
// The user accepts the tradeoff: their fork no longer auto-receives
|
|
50
|
+
// future builtin updates from chorus upgrades. That's the *expected*
|
|
51
|
+
// behaviour of "I edited this, it's mine now."
|
|
52
|
+
// - Edits to an existing user row → stay 'user' (no-op).
|
|
53
|
+
// - Save with identical YAML on a builtin → stay 'builtin' (we don't
|
|
54
|
+
// accidentally fork from a no-op resave).
|
|
55
|
+
//
|
|
56
|
+
// Validation runs in two stages so the cockpit can surface the *right*
|
|
57
|
+
// error to the user:
|
|
58
|
+
// 1. yaml.parse — catches syntax errors (indent, missing colon, etc.).
|
|
59
|
+
// 2. TemplateSchema (zod) — catches structural errors (missing phases,
|
|
60
|
+
// unknown lineage, reviewer.require out of bounds, hybrid review_only,
|
|
61
|
+
// …). Without this stage a malformed-but-parseable template would
|
|
62
|
+
// land in the DB and crash the runner the first time it loads it
|
|
63
|
+
// (getParsedTemplate calls TemplateSchema.parse with no fallback).
|
|
64
|
+
//
|
|
65
|
+
// Zod errors are flattened to {path, message} pairs so the editor can
|
|
66
|
+
// pin each error to its field; the response shape matches the existing
|
|
67
|
+
// ApiResponse `{ error, details: { issues } }` envelope.
|
|
68
|
+
fastify.post('/templates', async (request) => {
|
|
69
|
+
try {
|
|
70
|
+
const { id, yaml: yamlContent } = request.body;
|
|
71
|
+
if (!id || !yamlContent) {
|
|
72
|
+
return (0, api_response_js_1.errorResponse)('validation', 'id and yaml are required');
|
|
73
|
+
}
|
|
74
|
+
const validation = (0, template_validation_js_1.validateTemplateYaml)(yamlContent);
|
|
75
|
+
if (!validation.valid) {
|
|
76
|
+
const summary = validation.issues
|
|
77
|
+
.slice(0, 3)
|
|
78
|
+
.map((i) => `${i.path}: ${i.message}`)
|
|
79
|
+
.join('; ');
|
|
80
|
+
return (0, api_response_js_1.errorResponse)('validation', `Template failed validation: ${summary}${validation.issues.length > 3 ? ` (+${validation.issues.length - 3} more)` : ''}`, { issues: validation.issues });
|
|
81
|
+
}
|
|
82
|
+
const existing = await index_js_1.templates.getById(id);
|
|
83
|
+
let source;
|
|
84
|
+
if (!existing) {
|
|
85
|
+
source = 'user';
|
|
86
|
+
}
|
|
87
|
+
else if (existing.source === 'builtin' && existing.yaml === yamlContent) {
|
|
88
|
+
// No-op resave on a builtin — keep it as 'builtin' so the disk
|
|
89
|
+
// resync still works on next boot.
|
|
90
|
+
source = 'builtin';
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// Real edit OR an existing user row — both end up as 'user'.
|
|
94
|
+
source = 'user';
|
|
95
|
+
}
|
|
96
|
+
const template = await index_js_1.templates.create(id, yamlContent, source);
|
|
97
|
+
return (0, api_response_js_1.successResponse)({ ...template, sourcePromoted: existing?.source === 'builtin' && source === 'user' });
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
101
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
// Delete a user template. Built-ins refuse because the boot seed in
|
|
105
|
+
// src/daemon/index.ts re-creates them from `templates/*.yaml` on next
|
|
106
|
+
// start — surfacing a 400 here makes the cockpit hide the delete button
|
|
107
|
+
// for builtins instead of silently no-op'ing. Mirrors the persona DELETE
|
|
108
|
+
// route shape.
|
|
109
|
+
fastify.delete('/templates/:id', async (request) => {
|
|
110
|
+
try {
|
|
111
|
+
const existing = await index_js_1.templates.getById(request.params.id);
|
|
112
|
+
if (!existing) {
|
|
113
|
+
return (0, api_response_js_1.errorResponse)('not_found', `Template ${request.params.id} not found`);
|
|
114
|
+
}
|
|
115
|
+
if (existing.source === 'builtin') {
|
|
116
|
+
return (0, api_response_js_1.errorResponse)('validation', 'Built-in templates cannot be deleted (the boot seed would recreate them). Edit instead — your changes will be preserved.');
|
|
117
|
+
}
|
|
118
|
+
await index_js_1.templates.delete(request.params.id);
|
|
119
|
+
return (0, api_response_js_1.successResponse)({ id: request.params.id });
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
123
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
const PERSONA_ID_RE = /^[a-z0-9][a-z0-9-]{1,63}$/;
|
|
128
|
+
// Ids that would collide with cockpit URL segments or sentinel persona
|
|
129
|
+
// values used in template prompts. Keeping this conservative — it's
|
|
130
|
+
// easier to lift later than to migrate user data after a clash.
|
|
131
|
+
const RESERVED_PERSONA_IDS = new Set([
|
|
132
|
+
'new',
|
|
133
|
+
'edit',
|
|
134
|
+
'create',
|
|
135
|
+
'delete',
|
|
136
|
+
'api',
|
|
137
|
+
'admin',
|
|
138
|
+
'default',
|
|
139
|
+
'system',
|
|
140
|
+
'none',
|
|
141
|
+
]);
|
|
142
|
+
const VALID_LINEAGES = new Set([
|
|
143
|
+
'anthropic',
|
|
144
|
+
'openai',
|
|
145
|
+
'google',
|
|
146
|
+
'opencode',
|
|
147
|
+
'moonshot',
|
|
148
|
+
'openrouter',
|
|
149
|
+
]);
|
|
150
|
+
function registerPersonaRoutes(fastify) {
|
|
151
|
+
fastify.get('/personas', async () => {
|
|
152
|
+
try {
|
|
153
|
+
const { listPersonas } = await import('../../lib/personas.js');
|
|
154
|
+
const items = await listPersonas();
|
|
155
|
+
return (0, api_response_js_1.successResponse)((0, api_response_js_1.listEnvelope)(items));
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
159
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
fastify.get('/personas/:id', async (request) => {
|
|
163
|
+
try {
|
|
164
|
+
const { getPersona } = await import('../../lib/personas.js');
|
|
165
|
+
const row = await getPersona(request.params.id);
|
|
166
|
+
if (!row) {
|
|
167
|
+
return (0, api_response_js_1.errorResponse)('not_found', `Persona ${request.params.id} not found`);
|
|
168
|
+
}
|
|
169
|
+
return (0, api_response_js_1.successResponse)(row);
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
173
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
// Create or update a persona. Edits to a builtin row demote it to
|
|
177
|
+
// builtin=false so the boot-time seed in seedBuiltinPersonas() skips it
|
|
178
|
+
// and the user's edits persist across restarts (same source-promotion
|
|
179
|
+
// tradeoff as templates: the row no longer auto-receives upstream changes).
|
|
180
|
+
fastify.post('/personas', async (request) => {
|
|
181
|
+
try {
|
|
182
|
+
const { id, label, one_liner, system_prompt, recommended_lineage, forked_from } = request.body ?? {};
|
|
183
|
+
if (!id || !label || !one_liner || !system_prompt) {
|
|
184
|
+
return (0, api_response_js_1.errorResponse)('validation', 'id, label, one_liner, and system_prompt are required');
|
|
185
|
+
}
|
|
186
|
+
if (!PERSONA_ID_RE.test(id)) {
|
|
187
|
+
return (0, api_response_js_1.errorResponse)('validation', 'id must match /^[a-z0-9][a-z0-9-]{1,63}$/ (lowercase, dashes)');
|
|
188
|
+
}
|
|
189
|
+
if (RESERVED_PERSONA_IDS.has(id)) {
|
|
190
|
+
return (0, api_response_js_1.errorResponse)('validation', `id "${id}" is reserved (would collide with a UI/API route). Pick a more specific name.`);
|
|
191
|
+
}
|
|
192
|
+
if (recommended_lineage !== undefined &&
|
|
193
|
+
recommended_lineage !== null &&
|
|
194
|
+
recommended_lineage !== '' &&
|
|
195
|
+
!VALID_LINEAGES.has(recommended_lineage)) {
|
|
196
|
+
return (0, api_response_js_1.errorResponse)('validation', `recommended_lineage must be one of: ${[...VALID_LINEAGES].join(', ')}`);
|
|
197
|
+
}
|
|
198
|
+
const { personas } = await import('../../lib/db/index.js');
|
|
199
|
+
const existing = await personas.getById(id);
|
|
200
|
+
// Provenance precedence: existing row's forked_from wins (so re-saving
|
|
201
|
+
// a row never loses its origin), then any client-supplied forked_from
|
|
202
|
+
// (set by the cockpit's Duplicate handler), else null. Built-ins
|
|
203
|
+
// edited *in place* (id stays the same) intentionally drop forked_from
|
|
204
|
+
// — recording forked_from=existing.id would create a self-cycle that
|
|
205
|
+
// breaks any recursive lineage traversal. Sourcefulness is captured
|
|
206
|
+
// in the sourcePromoted flag returned to the client and the row's
|
|
207
|
+
// builtin=false status; we don't need a row pointing at itself.
|
|
208
|
+
const resolvedForkedFrom = existing
|
|
209
|
+
? (existing.forked_from ?? null)
|
|
210
|
+
: (forked_from && forked_from !== id ? forked_from : null);
|
|
211
|
+
const row = await personas.upsert({
|
|
212
|
+
id,
|
|
213
|
+
label,
|
|
214
|
+
one_liner,
|
|
215
|
+
system_prompt,
|
|
216
|
+
recommended_lineage: recommended_lineage && recommended_lineage !== '' ? recommended_lineage : null,
|
|
217
|
+
// Any save through the HTTP API marks the row as user-owned so
|
|
218
|
+
// seedBuiltinPersonas() leaves it alone on next boot.
|
|
219
|
+
builtin: false,
|
|
220
|
+
forked_from: resolvedForkedFrom,
|
|
221
|
+
});
|
|
222
|
+
return (0, api_response_js_1.successResponse)({
|
|
223
|
+
...row,
|
|
224
|
+
sourcePromoted: existing?.builtin === true,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
229
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
// Delete a user persona. Builtin rows can't be deleted because the boot
|
|
233
|
+
// seed would just re-create them — surfacing a 400 here makes the cockpit
|
|
234
|
+
// hide the delete button for builtins instead of silently no-op'ing.
|
|
235
|
+
fastify.delete('/personas/:id', async (request) => {
|
|
236
|
+
try {
|
|
237
|
+
const { personas } = await import('../../lib/db/index.js');
|
|
238
|
+
const existing = await personas.getById(request.params.id);
|
|
239
|
+
if (!existing) {
|
|
240
|
+
return (0, api_response_js_1.errorResponse)('not_found', `Persona ${request.params.id} not found`);
|
|
241
|
+
}
|
|
242
|
+
if (existing.builtin) {
|
|
243
|
+
return (0, api_response_js_1.errorResponse)('validation', 'Built-in personas cannot be deleted (the boot seed would recreate them). Edit instead — your changes will be preserved.');
|
|
244
|
+
}
|
|
245
|
+
await personas.delete(request.params.id);
|
|
246
|
+
return (0, api_response_js_1.successResponse)({ id: request.params.id });
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
250
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=templates-personas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates-personas.js","sourceRoot":"","sources":["../../../src/daemon/routes/templates-personas.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerVoiceRoutes = registerVoiceRoutes;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const index_js_1 = require("../../lib/db/index.js");
|
|
6
|
+
const api_response_js_1 = require("../api-response.js");
|
|
7
|
+
const Lineage = zod_1.z.enum(['anthropic', 'openai', 'google', 'opencode', 'moonshot']);
|
|
8
|
+
const Source = zod_1.z.enum(['cli', 'api']);
|
|
9
|
+
const ListQuerySchema = zod_1.z.object({
|
|
10
|
+
lineage: Lineage.optional(),
|
|
11
|
+
source: Source.optional(),
|
|
12
|
+
provider: zod_1.z.string().optional(),
|
|
13
|
+
enabled: zod_1.z
|
|
14
|
+
.enum(['true', 'false'])
|
|
15
|
+
.optional()
|
|
16
|
+
.transform((v) => (v === undefined ? undefined : v === 'true')),
|
|
17
|
+
});
|
|
18
|
+
// Cost fields: $/Mtok must be a finite, non-negative number. `null` is a
|
|
19
|
+
// distinct legitimate state ("unknown / not set"), `0` is also legitimate
|
|
20
|
+
// (free tier, opencode-go subscription, plan-priced reviewers). Negative
|
|
21
|
+
// or non-finite (NaN, Infinity) costs would corrupt downstream cost
|
|
22
|
+
// dashboards and the run-page chips, so we reject them at the boundary
|
|
23
|
+
// rather than letting bad values reach the DB.
|
|
24
|
+
const Cost = zod_1.z.number().finite().min(0).nullable().optional();
|
|
25
|
+
const PostBodySchema = zod_1.z.object({
|
|
26
|
+
provider: zod_1.z.string().min(1),
|
|
27
|
+
model_id: zod_1.z.string().min(1),
|
|
28
|
+
label: zod_1.z.string().min(1),
|
|
29
|
+
source: Source.default('api'),
|
|
30
|
+
lineage: Lineage,
|
|
31
|
+
vendor_family: zod_1.z.string().nullable().optional(),
|
|
32
|
+
input_cost_per_mtok: Cost,
|
|
33
|
+
output_cost_per_mtok: Cost,
|
|
34
|
+
enabled: zod_1.z.boolean().optional(),
|
|
35
|
+
});
|
|
36
|
+
const PutBodySchema = zod_1.z.object({
|
|
37
|
+
label: zod_1.z.string().min(1).optional(),
|
|
38
|
+
enabled: zod_1.z.boolean().optional(),
|
|
39
|
+
input_cost_per_mtok: Cost,
|
|
40
|
+
output_cost_per_mtok: Cost,
|
|
41
|
+
});
|
|
42
|
+
function registerVoiceRoutes(fastify) {
|
|
43
|
+
// List voices, optionally filtered. Default = all rows (incl. disabled).
|
|
44
|
+
fastify.get('/voices', async (request, reply) => {
|
|
45
|
+
try {
|
|
46
|
+
const parsed = ListQuerySchema.safeParse(request.query);
|
|
47
|
+
if (!parsed.success) {
|
|
48
|
+
return (0, api_response_js_1.sendError)(reply, 'validation', parsed.error.message);
|
|
49
|
+
}
|
|
50
|
+
const items = await index_js_1.voices.list(parsed.data);
|
|
51
|
+
return (0, api_response_js_1.successResponse)((0, api_response_js_1.listEnvelope)(items));
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
55
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
// Single-row read.
|
|
59
|
+
fastify.get('/voices/:id', async (request, reply) => {
|
|
60
|
+
try {
|
|
61
|
+
const v = await index_js_1.voices.getById(request.params.id);
|
|
62
|
+
if (!v) {
|
|
63
|
+
return (0, api_response_js_1.sendError)(reply, 'not_found', `Voice ${request.params.id} not found`);
|
|
64
|
+
}
|
|
65
|
+
return (0, api_response_js_1.successResponse)(v);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
69
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
// Add a voice (used by OpenRouter inline + by direct API additions).
|
|
73
|
+
fastify.post('/voices', async (request, reply) => {
|
|
74
|
+
try {
|
|
75
|
+
const parsed = PostBodySchema.safeParse(request.body);
|
|
76
|
+
if (!parsed.success) {
|
|
77
|
+
return (0, api_response_js_1.sendError)(reply, 'validation', parsed.error.message);
|
|
78
|
+
}
|
|
79
|
+
const id = `${parsed.data.provider}:${parsed.data.model_id}`;
|
|
80
|
+
const existing = await index_js_1.voices.getById(id);
|
|
81
|
+
if (existing) {
|
|
82
|
+
return (0, api_response_js_1.sendError)(reply, 'conflict', `Voice ${id} already exists`);
|
|
83
|
+
}
|
|
84
|
+
const row = await index_js_1.voices.upsert({
|
|
85
|
+
id,
|
|
86
|
+
label: parsed.data.label,
|
|
87
|
+
source: parsed.data.source,
|
|
88
|
+
provider: parsed.data.provider,
|
|
89
|
+
model_id: parsed.data.model_id,
|
|
90
|
+
lineage: parsed.data.lineage,
|
|
91
|
+
vendor_family: parsed.data.vendor_family ?? null,
|
|
92
|
+
input_cost_per_mtok: parsed.data.input_cost_per_mtok ?? null,
|
|
93
|
+
output_cost_per_mtok: parsed.data.output_cost_per_mtok ?? null,
|
|
94
|
+
enabled: parsed.data.enabled,
|
|
95
|
+
});
|
|
96
|
+
return (0, api_response_js_1.successResponse)(row);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
100
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
// Toggle enabled / update label / update costs.
|
|
104
|
+
// source/provider/lineage/vendor_family/model_id are immutable post-create.
|
|
105
|
+
// Note: model_id IS rewritten on cli rows during the seed loop, but only
|
|
106
|
+
// by the seed (via voices.upsert), not via this route.
|
|
107
|
+
fastify.put('/voices/:id', async (request, reply) => {
|
|
108
|
+
try {
|
|
109
|
+
const parsed = PutBodySchema.safeParse(request.body);
|
|
110
|
+
if (!parsed.success) {
|
|
111
|
+
return (0, api_response_js_1.sendError)(reply, 'validation', parsed.error.message);
|
|
112
|
+
}
|
|
113
|
+
const existing = await index_js_1.voices.getById(request.params.id);
|
|
114
|
+
if (!existing) {
|
|
115
|
+
return (0, api_response_js_1.sendError)(reply, 'not_found', `Voice ${request.params.id} not found`);
|
|
116
|
+
}
|
|
117
|
+
const row = await index_js_1.voices.update(request.params.id, parsed.data);
|
|
118
|
+
return (0, api_response_js_1.successResponse)(row);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
122
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
// DELETE allowed for both cli + api source. cli rows auto-heal on next
|
|
126
|
+
// seed if the model is still detected by the gateway (per gem-2 round 1
|
|
127
|
+
// MED — unblocks cleanup of deprecated OpenCode models).
|
|
128
|
+
fastify.delete('/voices/:id', async (request) => {
|
|
129
|
+
try {
|
|
130
|
+
await index_js_1.voices.delete(request.params.id);
|
|
131
|
+
return (0, api_response_js_1.successResponse)({ id: request.params.id, deleted: true });
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
135
|
+
return (0, api_response_js_1.errorResponse)('db_error', message);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=voices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voices.js","sourceRoot":"","sources":["../../../src/daemon/routes/voices.ts"],"names":[],"mappings":"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"}
|