chorus-codes 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/cache/.previewinfo +1 -1
- package/.next/cache/.rscinfo +1 -1
- package/.next/cache/.tsbuildinfo +1 -1
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/new.html +1 -1
- package/.next/server/app/new.rsc +1 -1
- package/.next/server/app/new.segments/_full.segment.rsc +1 -1
- package/.next/server/app/new.segments/_head.segment.rsc +1 -1
- package/.next/server/app/new.segments/_index.segment.rsc +1 -1
- package/.next/server/app/new.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/new.segments/new/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/new.segments/new.segment.rsc +1 -1
- package/.next/server/app/onboarding.html +1 -1
- package/.next/server/app/onboarding.rsc +1 -1
- package/.next/server/app/onboarding.segments/_full.segment.rsc +1 -1
- package/.next/server/app/onboarding.segments/_head.segment.rsc +1 -1
- package/.next/server/app/onboarding.segments/_index.segment.rsc +1 -1
- package/.next/server/app/onboarding.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/onboarding.segments/onboarding/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/onboarding.segments/onboarding.segment.rsc +1 -1
- package/.next/server/app/personas.html +1 -1
- package/.next/server/app/personas.rsc +1 -1
- package/.next/server/app/personas.segments/_full.segment.rsc +1 -1
- package/.next/server/app/personas.segments/_head.segment.rsc +1 -1
- package/.next/server/app/personas.segments/_index.segment.rsc +1 -1
- package/.next/server/app/personas.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/personas.segments/personas/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/personas.segments/personas.segment.rsc +1 -1
- package/.next/server/app/settings.html +1 -1
- package/.next/server/app/settings.rsc +1 -1
- package/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/server/app/templates.html +1 -1
- package/.next/server/app/templates.rsc +1 -1
- package/.next/server/app/templates.segments/_full.segment.rsc +1 -1
- package/.next/server/app/templates.segments/_head.segment.rsc +1 -1
- package/.next/server/app/templates.segments/_index.segment.rsc +1 -1
- package/.next/server/app/templates.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/templates.segments/templates/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/templates.segments/templates.segment.rsc +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/trace +1 -1
- package/.next/trace-build +1 -1
- package/README.md +38 -15
- package/dist/cli/commands/doctor.js +116 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/init.js +211 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/start.js +298 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.js +54 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.js +97 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/connect.js +108 -0
- package/dist/cli/connect.js.map +1 -0
- package/dist/cli/index.js +99 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/port-utils.js +260 -0
- package/dist/cli/port-utils.js.map +1 -0
- package/dist/cli/runtime-env.js +60 -0
- package/dist/cli/runtime-env.js.map +1 -0
- package/dist/cli/shared.js +54 -0
- package/dist/cli/shared.js.map +1 -0
- package/dist/cli/ui.js +60 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/daemon/agents/claude.js +98 -0
- package/dist/daemon/agents/claude.js.map +1 -0
- package/dist/daemon/agents/codex.js +160 -0
- package/dist/daemon/agents/codex.js.map +1 -0
- package/dist/daemon/agents/gemini.js +111 -0
- package/dist/daemon/agents/gemini.js.map +1 -0
- package/dist/daemon/agents/index.js +59 -0
- package/dist/daemon/agents/index.js.map +1 -0
- package/dist/daemon/agents/kimi.js +206 -0
- package/dist/daemon/agents/kimi.js.map +1 -0
- package/dist/daemon/agents/opencode.js +228 -0
- package/dist/daemon/agents/opencode.js.map +1 -0
- package/dist/daemon/agents/openrouter.js +274 -0
- package/dist/daemon/agents/openrouter.js.map +1 -0
- package/dist/daemon/agents/parsers/claude.js +63 -0
- package/dist/daemon/agents/parsers/claude.js.map +1 -0
- package/dist/daemon/agents/parsers/codex.js +51 -0
- package/dist/daemon/agents/parsers/codex.js.map +1 -0
- package/dist/daemon/agents/parsers/gemini.js +144 -0
- package/dist/daemon/agents/parsers/gemini.js.map +1 -0
- package/dist/daemon/agents/parsers/index.js +31 -0
- package/dist/daemon/agents/parsers/index.js.map +1 -0
- package/dist/daemon/agents/parsers/kimi.js +8 -0
- package/dist/daemon/agents/parsers/kimi.js.map +1 -0
- package/dist/daemon/agents/parsers/opencode.js +105 -0
- package/dist/daemon/agents/parsers/opencode.js.map +1 -0
- package/dist/daemon/agents/parsers/openrouter.js +69 -0
- package/dist/daemon/agents/parsers/openrouter.js.map +1 -0
- package/dist/daemon/agents/parsers/shared.js +17 -0
- package/dist/daemon/agents/parsers/shared.js.map +1 -0
- package/dist/daemon/agents/preflight.js +83 -0
- package/dist/daemon/agents/preflight.js.map +1 -0
- package/dist/daemon/agents/quote.js +45 -0
- package/dist/daemon/agents/quote.js.map +1 -0
- package/dist/daemon/agents/sandbox-guard.js +69 -0
- package/dist/daemon/agents/sandbox-guard.js.map +1 -0
- package/dist/daemon/agents/types.js +6 -0
- package/dist/daemon/agents/types.js.map +1 -0
- package/dist/daemon/api-response.js +65 -0
- package/dist/daemon/api-response.js.map +1 -0
- package/dist/daemon/error-detector.js +329 -0
- package/dist/daemon/error-detector.js.map +1 -0
- package/dist/daemon/headless.js +533 -0
- package/dist/daemon/headless.js.map +1 -0
- package/dist/daemon/index.js +333 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/openrouter.js +192 -0
- package/dist/daemon/openrouter.js.map +1 -0
- package/dist/daemon/orchestrators/claude.js +163 -0
- package/dist/daemon/orchestrators/claude.js.map +1 -0
- package/dist/daemon/orchestrators/codex.js +101 -0
- package/dist/daemon/orchestrators/codex.js.map +1 -0
- package/dist/daemon/orchestrators/cursor-windsurf.js +118 -0
- package/dist/daemon/orchestrators/cursor-windsurf.js.map +1 -0
- package/dist/daemon/orchestrators/gemini.js +108 -0
- package/dist/daemon/orchestrators/gemini.js.map +1 -0
- package/dist/daemon/orchestrators/index.js +90 -0
- package/dist/daemon/orchestrators/index.js.map +1 -0
- package/dist/daemon/orchestrators/kimi.js +108 -0
- package/dist/daemon/orchestrators/kimi.js.map +1 -0
- package/dist/daemon/orchestrators/opencode.js +152 -0
- package/dist/daemon/orchestrators/opencode.js.map +1 -0
- package/dist/daemon/orchestrators/shared.js +60 -0
- package/dist/daemon/orchestrators/shared.js.map +1 -0
- package/dist/daemon/output-watcher.js +131 -0
- package/dist/daemon/output-watcher.js.map +1 -0
- package/dist/daemon/participant-aborts.js +123 -0
- package/dist/daemon/participant-aborts.js.map +1 -0
- package/dist/daemon/reaper.js +46 -0
- package/dist/daemon/reaper.js.map +1 -0
- package/dist/daemon/routes/chats-events.js +62 -0
- package/dist/daemon/routes/chats-events.js.map +1 -0
- package/dist/daemon/routes/chats-stream.js +241 -0
- package/dist/daemon/routes/chats-stream.js.map +1 -0
- package/dist/daemon/routes/chats-validation.js +13 -0
- package/dist/daemon/routes/chats-validation.js.map +1 -0
- package/dist/daemon/routes/chats.js +545 -0
- package/dist/daemon/routes/chats.js.map +1 -0
- package/dist/daemon/routes/openrouter.js +103 -0
- package/dist/daemon/routes/openrouter.js.map +1 -0
- package/dist/daemon/routes/settings.js +199 -0
- package/dist/daemon/routes/settings.js.map +1 -0
- package/dist/daemon/routes/stats.js +155 -0
- package/dist/daemon/routes/stats.js.map +1 -0
- package/dist/daemon/routes/system.js +208 -0
- package/dist/daemon/routes/system.js.map +1 -0
- package/dist/daemon/routes/templates-personas.js +254 -0
- package/dist/daemon/routes/templates-personas.js.map +1 -0
- package/dist/daemon/routes/voices.js +139 -0
- package/dist/daemon/routes/voices.js.map +1 -0
- package/dist/daemon/runner/doer-driver.js +346 -0
- package/dist/daemon/runner/doer-driver.js.map +1 -0
- package/dist/daemon/runner/doer.js +336 -0
- package/dist/daemon/runner/doer.js.map +1 -0
- package/dist/daemon/runner/prior-round.js +140 -0
- package/dist/daemon/runner/prior-round.js.map +1 -0
- package/dist/daemon/runner/prompt-builder.js +292 -0
- package/dist/daemon/runner/prompt-builder.js.map +1 -0
- package/dist/daemon/runner/review-only-phase.js +103 -0
- package/dist/daemon/runner/review-only-phase.js.map +1 -0
- package/dist/daemon/runner/reviewer-driver.js +410 -0
- package/dist/daemon/runner/reviewer-driver.js.map +1 -0
- package/dist/daemon/runner/reviewer.js +384 -0
- package/dist/daemon/runner/reviewer.js.map +1 -0
- package/dist/daemon/runner/run-with-fallback.js +56 -0
- package/dist/daemon/runner/run-with-fallback.js.map +1 -0
- package/dist/daemon/runner/sanitize-name.js +8 -0
- package/dist/daemon/runner/sanitize-name.js.map +1 -0
- package/dist/daemon/runner/stream-file-writer.js +116 -0
- package/dist/daemon/runner/stream-file-writer.js.map +1 -0
- package/dist/daemon/runner/swap-sidecar.js +102 -0
- package/dist/daemon/runner/swap-sidecar.js.map +1 -0
- package/dist/daemon/runner/template-fallback.js +119 -0
- package/dist/daemon/runner/template-fallback.js.map +1 -0
- package/dist/daemon/runner/types.js +3 -0
- package/dist/daemon/runner/types.js.map +1 -0
- package/dist/daemon/runner/verdict.js +51 -0
- package/dist/daemon/runner/verdict.js.map +1 -0
- package/dist/daemon/runner-multiplex.js +364 -0
- package/dist/daemon/runner-multiplex.js.map +1 -0
- package/dist/daemon/runner.js +427 -0
- package/dist/daemon/runner.js.map +1 -0
- package/dist/daemon/ship.js +340 -0
- package/dist/daemon/ship.js.map +1 -0
- package/dist/daemon/template-cache.js +37 -0
- package/dist/daemon/template-cache.js.map +1 -0
- package/dist/daemon/tmux-types.js +9 -0
- package/dist/daemon/tmux-types.js.map +1 -0
- package/dist/daemon/tmux.js +341 -0
- package/dist/daemon/tmux.js.map +1 -0
- package/dist/lib/atomic-write.js +55 -0
- package/dist/lib/atomic-write.js.map +1 -0
- package/dist/lib/chat-events-bus.js +27 -0
- package/dist/lib/chat-events-bus.js.map +1 -0
- package/dist/lib/chat-slug.js +105 -0
- package/dist/lib/chat-slug.js.map +1 -0
- package/dist/lib/cli-detect.js +388 -0
- package/dist/lib/cli-detect.js.map +1 -0
- package/dist/lib/cli-health.js +156 -0
- package/dist/lib/cli-health.js.map +1 -0
- package/dist/lib/cli-paths.js +113 -0
- package/dist/lib/cli-paths.js.map +1 -0
- package/dist/lib/cli-precheck.js +141 -0
- package/dist/lib/cli-precheck.js.map +1 -0
- package/dist/lib/db/chats.js +244 -0
- package/dist/lib/db/chats.js.map +1 -0
- package/dist/lib/db/connection.js +254 -0
- package/dist/lib/db/connection.js.map +1 -0
- package/dist/lib/db/index.js +34 -0
- package/dist/lib/db/index.js.map +1 -0
- package/dist/lib/db/personas.js +65 -0
- package/dist/lib/db/personas.js.map +1 -0
- package/dist/lib/db/phase-events.js +172 -0
- package/dist/lib/db/phase-events.js.map +1 -0
- package/dist/lib/db/secrets.js +53 -0
- package/dist/lib/db/secrets.js.map +1 -0
- package/dist/lib/db/settings.js +47 -0
- package/dist/lib/db/settings.js.map +1 -0
- package/dist/lib/db/templates.js +75 -0
- package/dist/lib/db/templates.js.map +1 -0
- package/dist/lib/db/voices.js +184 -0
- package/dist/lib/db/voices.js.map +1 -0
- package/dist/lib/lineage-maps.js +200 -0
- package/dist/lib/lineage-maps.js.map +1 -0
- package/dist/lib/logger.js +186 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/personas.js +117 -0
- package/dist/lib/personas.js.map +1 -0
- package/dist/lib/runtime-path.js +222 -0
- package/dist/lib/runtime-path.js.map +1 -0
- package/dist/lib/settings/billing.js +58 -0
- package/dist/lib/settings/billing.js.map +1 -0
- package/dist/lib/settings/permissions.js +81 -0
- package/dist/lib/settings/permissions.js.map +1 -0
- package/dist/lib/settings/transport.js +113 -0
- package/dist/lib/settings/transport.js.map +1 -0
- package/dist/lib/telemetry.js +290 -0
- package/dist/lib/telemetry.js.map +1 -0
- package/dist/lib/template-schema.js +319 -0
- package/dist/lib/template-schema.js.map +1 -0
- package/dist/lib/template-validation.js +82 -0
- package/dist/lib/template-validation.js.map +1 -0
- package/dist/lib/voices.js +533 -0
- package/dist/lib/voices.js.map +1 -0
- package/dist/mcp/client.js +138 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/index.js +178 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/tools.js +355 -0
- package/dist/mcp/tools.js.map +1 -0
- package/package.json +2 -1
- package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0beh7rg._.js +0 -6077
- package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0beh7rg._.js.map +0 -69
- package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0pjsj.j._.js +0 -6318
- package/.next/dev/static/chunks/05w9_next_dist_shared_lib_0pjsj.j._.js.map +0 -71
- package/.next/dev/types/cache-life.d.ts +0 -145
- package/.next/dev/types/routes.d.ts +0 -84
- package/.next/dev/types/validator.ts +0 -178
- /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 9cD3yIOGe_Aqr17uJHTQS}/_buildManifest.js +0 -0
- /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 9cD3yIOGe_Aqr17uJHTQS}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{dJlbRLlhISA0JGtHKVqgQ → 9cD3yIOGe_Aqr17uJHTQS}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.runDoerHeadless = runDoerHeadless;
|
|
37
|
+
/**
|
|
38
|
+
* Doer streaming execution.
|
|
39
|
+
*
|
|
40
|
+
* Drives one doer subprocess via its AgentShim's runHeadless iterator,
|
|
41
|
+
* forwarding text_delta events to a buffered StreamFileWriter and to the
|
|
42
|
+
* SSE bus, and producing the final `{content, full}` shape the phase
|
|
43
|
+
* loop consumes.
|
|
44
|
+
*
|
|
45
|
+
* Critical invariants (covered by tests/runner-doer.test.ts):
|
|
46
|
+
* - text_delta events accumulate AND get flushed to answer.md
|
|
47
|
+
* - message_done with non-empty finalText overwrites authoritatively +
|
|
48
|
+
* appends ## DONE sentinel when missing
|
|
49
|
+
* - message_done with EMPTY finalText keeps accumulated deltas
|
|
50
|
+
* (the Gemini "result-line-only" failure mode)
|
|
51
|
+
* - error event flips errored AND preserves accumulated content
|
|
52
|
+
* - StreamFileWriter buffer is flushed in the finally block on every path
|
|
53
|
+
*/
|
|
54
|
+
const fs = __importStar(require("fs"));
|
|
55
|
+
const path = __importStar(require("path"));
|
|
56
|
+
const template_schema_js_1 = require("../../lib/template-schema.js");
|
|
57
|
+
const permissions_js_1 = require("../../lib/settings/permissions.js");
|
|
58
|
+
const cli_health_js_1 = require("../../lib/cli-health.js");
|
|
59
|
+
const stream_file_writer_js_1 = require("./stream-file-writer.js");
|
|
60
|
+
async function runDoerHeadless(args) {
|
|
61
|
+
const { shim, chatId, phase, round, agentName, askContent, answerFile, doerCwd, abortSignal, onEvent, modelOverride, } = args;
|
|
62
|
+
if (!shim.runHeadless) {
|
|
63
|
+
// Defensive — caller should have checked. Fail closed.
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
const perms = await (0, permissions_js_1.getPermissions)();
|
|
67
|
+
let accumulated = '';
|
|
68
|
+
let finalText;
|
|
69
|
+
let errored = false;
|
|
70
|
+
// Captured from the first error event so we can write it to
|
|
71
|
+
// answer.md when the subprocess dies before producing any content.
|
|
72
|
+
// Mirrors the reviewer-side handling so chat dirs are self-
|
|
73
|
+
// explanatory after a silent-failure crash.
|
|
74
|
+
let errorSummary;
|
|
75
|
+
let capturedUsage;
|
|
76
|
+
const startedAt = Date.now();
|
|
77
|
+
// Initialize answer.md so the artifacts endpoint sees the file mid-stream.
|
|
78
|
+
fs.writeFileSync(answerFile, '');
|
|
79
|
+
const writer = new stream_file_writer_js_1.StreamFileWriter(answerFile);
|
|
80
|
+
const stream = shim.runHeadless({
|
|
81
|
+
cwd: doerCwd,
|
|
82
|
+
promptText: askContent,
|
|
83
|
+
model: modelOverride ?? phase.doer.models?.[0],
|
|
84
|
+
sandbox: perms.sandboxProfile,
|
|
85
|
+
autoApprove: perms.autoApprovePrompts,
|
|
86
|
+
networkAccess: perms.networkAccess,
|
|
87
|
+
abortSignal,
|
|
88
|
+
timeoutMs: phase.timeoutMs ?? template_schema_js_1.DEFAULT_PHASE_TIMEOUT_MS,
|
|
89
|
+
});
|
|
90
|
+
try {
|
|
91
|
+
for await (const event of stream) {
|
|
92
|
+
if (event.type === 'text_delta') {
|
|
93
|
+
accumulated += event.text;
|
|
94
|
+
writer.write(event.text);
|
|
95
|
+
onEvent({
|
|
96
|
+
chatId,
|
|
97
|
+
type: 'phase_progress',
|
|
98
|
+
payload: {
|
|
99
|
+
phaseId: phase.id,
|
|
100
|
+
round,
|
|
101
|
+
role: 'doer',
|
|
102
|
+
agent: agentName,
|
|
103
|
+
output: accumulated.slice(-500),
|
|
104
|
+
},
|
|
105
|
+
ts: Date.now(),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
else if (event.type === 'tool_call_start') {
|
|
109
|
+
onEvent({
|
|
110
|
+
chatId,
|
|
111
|
+
type: 'phase_progress',
|
|
112
|
+
payload: {
|
|
113
|
+
phaseId: phase.id,
|
|
114
|
+
round,
|
|
115
|
+
role: 'doer',
|
|
116
|
+
agent: agentName,
|
|
117
|
+
tool: event.tool,
|
|
118
|
+
},
|
|
119
|
+
ts: Date.now(),
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
else if (event.type === 'progress') {
|
|
123
|
+
onEvent({
|
|
124
|
+
chatId,
|
|
125
|
+
type: 'phase_progress',
|
|
126
|
+
payload: {
|
|
127
|
+
phaseId: phase.id,
|
|
128
|
+
round,
|
|
129
|
+
role: 'doer',
|
|
130
|
+
agent: agentName,
|
|
131
|
+
elapsedMs: event.elapsedMs,
|
|
132
|
+
},
|
|
133
|
+
ts: Date.now(),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
else if (event.type === 'message_done') {
|
|
137
|
+
finalText = event.finalText;
|
|
138
|
+
if (event.usage)
|
|
139
|
+
capturedUsage = event.usage;
|
|
140
|
+
writer.flushNow();
|
|
141
|
+
if (event.finalText.trim().length === 0) {
|
|
142
|
+
const existing = fs.existsSync(answerFile)
|
|
143
|
+
? fs.readFileSync(answerFile, 'utf-8')
|
|
144
|
+
: '';
|
|
145
|
+
if (!/\n##\s*DONE\s*\n?$/i.test(existing.trimEnd())) {
|
|
146
|
+
fs.appendFileSync(answerFile, existing.endsWith('\n') ? '\n## DONE\n' : '\n\n## DONE\n');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const needsSentinel = !/\n##\s*DONE\s*\n?$/i.test(event.finalText.trimEnd());
|
|
151
|
+
const finalContent = needsSentinel
|
|
152
|
+
? `${event.finalText}\n\n## DONE\n`
|
|
153
|
+
: event.finalText.endsWith('\n')
|
|
154
|
+
? event.finalText
|
|
155
|
+
: `${event.finalText}\n`;
|
|
156
|
+
fs.writeFileSync(answerFile, finalContent);
|
|
157
|
+
}
|
|
158
|
+
// Tell the cockpit this participant is fully on disk so it can
|
|
159
|
+
// flip the card immediately rather than wait for the 8s polling
|
|
160
|
+
// tick. Mirrored in reviewer.ts.
|
|
161
|
+
// Persist runtime stats next to answer.md — see reviewer.ts for
|
|
162
|
+
// rationale. Use path.dirname + path.join (clearer than the
|
|
163
|
+
// anchored regex; flagged in retroactive PR #16 review).
|
|
164
|
+
try {
|
|
165
|
+
const statsPath = path.join(path.dirname(answerFile), '_stats.json');
|
|
166
|
+
fs.writeFileSync(statsPath, JSON.stringify({
|
|
167
|
+
durationMs: Date.now() - startedAt,
|
|
168
|
+
...(capturedUsage ? { usage: capturedUsage } : {}),
|
|
169
|
+
}), 'utf-8');
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
/* sidecar is informational; ignore write errors */
|
|
173
|
+
}
|
|
174
|
+
// participant_done payload carries identity only — the cockpit
|
|
175
|
+
// refetches /api/run-artifacts on this event to pick up the
|
|
176
|
+
// sidecar-backed stats. Earlier diff also embedded durationMs
|
|
177
|
+
// and usage in the SSE payload; retroactive PR #16 review by
|
|
178
|
+
// both opencode reviewers flagged those as dead bytes never
|
|
179
|
+
// consumed on the cockpit side.
|
|
180
|
+
onEvent({
|
|
181
|
+
chatId,
|
|
182
|
+
type: 'participant_done',
|
|
183
|
+
payload: {
|
|
184
|
+
phaseId: phase.id,
|
|
185
|
+
round,
|
|
186
|
+
role: 'doer',
|
|
187
|
+
agent: agentName,
|
|
188
|
+
},
|
|
189
|
+
ts: Date.now(),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
else if (event.type === 'error') {
|
|
193
|
+
errored = true;
|
|
194
|
+
// Mirror reviewer.ts: persist OpenRouter HTTP-error state into
|
|
195
|
+
// cli-health so the home-page card flips to quota/auth/rate-limit
|
|
196
|
+
// and so the run-page error event carries a remediation CTA.
|
|
197
|
+
const classified = (0, cli_health_js_1.classifyOpenRouterError)(event.kind, event.message);
|
|
198
|
+
if (classified) {
|
|
199
|
+
(0, cli_health_js_1.recordHealth)({
|
|
200
|
+
lineage: 'openrouter',
|
|
201
|
+
status: classified.status,
|
|
202
|
+
message: classified.message,
|
|
203
|
+
}).catch((healthErr) => {
|
|
204
|
+
console.error('[chorus] recordHealth failed for openrouter:', healthErr);
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
if (!errorSummary) {
|
|
208
|
+
errorSummary = {
|
|
209
|
+
kind: event.kind,
|
|
210
|
+
message: classified?.message ?? event.message,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
onEvent({
|
|
214
|
+
chatId,
|
|
215
|
+
type: 'cli_error',
|
|
216
|
+
payload: {
|
|
217
|
+
phaseId: phase.id,
|
|
218
|
+
phaseKind: phase.kind,
|
|
219
|
+
phaseIdx: 0,
|
|
220
|
+
round,
|
|
221
|
+
role: 'doer',
|
|
222
|
+
agent: agentName,
|
|
223
|
+
error: {
|
|
224
|
+
kind: event.kind,
|
|
225
|
+
message: classified?.message ?? event.message,
|
|
226
|
+
...(classified?.cta ? { cta: classified.cta } : {}),
|
|
227
|
+
lineage: phase.doer.lineage,
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
ts: Date.now(),
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
errored = true;
|
|
237
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
238
|
+
if (!errorSummary) {
|
|
239
|
+
errorSummary = { kind: 'stream_failure', message };
|
|
240
|
+
}
|
|
241
|
+
onEvent({
|
|
242
|
+
chatId,
|
|
243
|
+
type: 'cli_error',
|
|
244
|
+
payload: {
|
|
245
|
+
phaseId: phase.id,
|
|
246
|
+
phaseKind: phase.kind,
|
|
247
|
+
phaseIdx: 0,
|
|
248
|
+
round,
|
|
249
|
+
role: 'doer',
|
|
250
|
+
agent: agentName,
|
|
251
|
+
error: {
|
|
252
|
+
kind: 'stream_failure',
|
|
253
|
+
message,
|
|
254
|
+
lineage: phase.doer.lineage,
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
ts: Date.now(),
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
finally {
|
|
261
|
+
writer.flushNow();
|
|
262
|
+
// When the subprocess died without producing any content, write the
|
|
263
|
+
// error summary to answer.md so the chat dir is self-explanatory.
|
|
264
|
+
// Same pattern as runReviewerHeadless — see comment there.
|
|
265
|
+
if (errored && accumulated.length === 0 && (!finalText || finalText.length === 0) && errorSummary) {
|
|
266
|
+
try {
|
|
267
|
+
// Mirror reviewer.ts: include cli-health resetAt for quota /
|
|
268
|
+
// rate-limit failures so the cockpit can render a countdown.
|
|
269
|
+
let resetAt;
|
|
270
|
+
try {
|
|
271
|
+
const h = await (0, cli_health_js_1.getHealth)(phase.doer.lineage);
|
|
272
|
+
if (typeof h.resetAt === 'number' && h.resetAt > Date.now()) {
|
|
273
|
+
resetAt = h.resetAt;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
/* health lookup is informational */
|
|
278
|
+
}
|
|
279
|
+
fs.writeFileSync(answerFile, `## DOER FAILED\n\n` +
|
|
280
|
+
`**Kind:** ${errorSummary.kind}\n` +
|
|
281
|
+
`**Lineage:** ${phase.doer.lineage}\n` +
|
|
282
|
+
`**Model:** ${modelOverride ?? phase.doer.models?.[0] ?? '(default)'}\n` +
|
|
283
|
+
(resetAt ? `**Resets:** ${new Date(resetAt).toISOString()}\n` : '') +
|
|
284
|
+
`\n${errorSummary.message}\n`);
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
/* best-effort — don't fail the runner because of a write error */
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// If the StreamFileWriter went dead (FS ENOSPC, EACCES, etc.) it
|
|
291
|
+
// dropped the failing chunk to avoid retrying the same sync write
|
|
292
|
+
// forever. Surface this so the user sees "stream stopped writing"
|
|
293
|
+
// rather than silently truncated answer.md.
|
|
294
|
+
if (writer.isDead()) {
|
|
295
|
+
const err = writer.lastError();
|
|
296
|
+
onEvent({
|
|
297
|
+
chatId,
|
|
298
|
+
type: 'cli_warning',
|
|
299
|
+
payload: {
|
|
300
|
+
phaseId: phase.id,
|
|
301
|
+
round,
|
|
302
|
+
role: 'doer',
|
|
303
|
+
agent: agentName,
|
|
304
|
+
reason: 'stream_writer_dead',
|
|
305
|
+
message: `answer.md write failed; subsequent deltas dropped: ${err ? err.message : 'unknown'}`,
|
|
306
|
+
cta: 'Check disk space + permissions on ~/.chorus/chats. Re-run when fixed.',
|
|
307
|
+
},
|
|
308
|
+
ts: Date.now(),
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (errored && finalText === undefined && accumulated.length === 0) {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
const content = finalText && finalText.length > 0 ? finalText : accumulated;
|
|
316
|
+
if (finalText === undefined && content.trim().length === 0) {
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
// `full` means "the doer's answer is complete" — a truthful signal to
|
|
320
|
+
// downstream reviewers that they can review the artifact as-is. An
|
|
321
|
+
// errored stream that wrote partial bytes before the subprocess crashed
|
|
322
|
+
// must NOT be marked full: reviewers receiving truncated mid-paragraph
|
|
323
|
+
// text will silently produce nonsense verdicts on a half-written answer.
|
|
324
|
+
// Only treat as full when EITHER the parser saw a final message_done
|
|
325
|
+
// (finalText set) AND no error, OR we accumulated text without any
|
|
326
|
+
// error mid-stream. The launch-eve gemini review of runner orchestration
|
|
327
|
+
// flagged this — earlier code returned full=true whenever
|
|
328
|
+
// `accumulated.length > 0`, regardless of `errored` state.
|
|
329
|
+
const isFull = !errored && (finalText !== undefined || accumulated.length > 0);
|
|
330
|
+
return {
|
|
331
|
+
content,
|
|
332
|
+
full: isFull,
|
|
333
|
+
...(capturedUsage ? { usage: capturedUsage } : {}),
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
//# sourceMappingURL=doer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doer.js","sourceRoot":"","sources":["../../../src/daemon/runner/doer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.readPriorRoundFeedback = readPriorRoundFeedback;
|
|
37
|
+
/**
|
|
38
|
+
* Prior-round feedback reader.
|
|
39
|
+
*
|
|
40
|
+
* On round ≥ 2 the doer was rerunning the SAME prompt as round 1 — only
|
|
41
|
+
* the round number in the heading changed. Reviewer findings from round
|
|
42
|
+
* N-1 were never threaded back, so disagreement → retry was effectively
|
|
43
|
+
* "ask again, hope the LLM rolls a better die" instead of a real revision
|
|
44
|
+
* loop.
|
|
45
|
+
*
|
|
46
|
+
* This helper assembles a "## Prior round feedback" markdown block from
|
|
47
|
+
* the previous round's reviewer answer.md files. The doer prompt builder
|
|
48
|
+
* inlines it before the "## How to respond" footer.
|
|
49
|
+
*
|
|
50
|
+
* Caps:
|
|
51
|
+
* - per-reviewer slice: 16KB (truncated answers still mark the cut)
|
|
52
|
+
* - total block: 64KB (additional reviewers replaced with marker)
|
|
53
|
+
*
|
|
54
|
+
* Numbers chosen to leave the 256KB doer prompt budget mostly intact for
|
|
55
|
+
* attached files + persona + task framing, while still surfacing enough
|
|
56
|
+
* reviewer text to be actionable.
|
|
57
|
+
*/
|
|
58
|
+
const fs = __importStar(require("fs"));
|
|
59
|
+
const path = __importStar(require("path"));
|
|
60
|
+
const PER_REVIEWER_MAX_BYTES = 16 * 1024;
|
|
61
|
+
const TOTAL_FEEDBACK_MAX_BYTES = 64 * 1024;
|
|
62
|
+
/**
|
|
63
|
+
* Returns a markdown block summarizing the previous round's reviewer
|
|
64
|
+
* findings, or empty string when there's nothing to feed back.
|
|
65
|
+
*
|
|
66
|
+
* Empty cases:
|
|
67
|
+
* - round <= 1 (no prior round exists)
|
|
68
|
+
* - prior round dir missing (e.g. crash mid-round)
|
|
69
|
+
* - no reviewer-* dirs found
|
|
70
|
+
* - all reviewer answer.md files unreadable / empty
|
|
71
|
+
*/
|
|
72
|
+
function readPriorRoundFeedback(chatDir, round) {
|
|
73
|
+
if (round <= 1)
|
|
74
|
+
return '';
|
|
75
|
+
const priorRoundDir = path.join(chatDir, `round-${round - 1}`);
|
|
76
|
+
if (!fs.existsSync(priorRoundDir))
|
|
77
|
+
return '';
|
|
78
|
+
let entries;
|
|
79
|
+
try {
|
|
80
|
+
entries = fs.readdirSync(priorRoundDir);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return '';
|
|
84
|
+
}
|
|
85
|
+
// Stable sort by dir name so reviewer order in the prompt matches the
|
|
86
|
+
// run page rendering. dir name embeds the reviewer index already.
|
|
87
|
+
const reviewerDirs = entries
|
|
88
|
+
.filter((n) => n.startsWith('reviewer-'))
|
|
89
|
+
.sort();
|
|
90
|
+
if (reviewerDirs.length === 0)
|
|
91
|
+
return '';
|
|
92
|
+
const chunks = [];
|
|
93
|
+
let totalBytes = 0;
|
|
94
|
+
for (const dir of reviewerDirs) {
|
|
95
|
+
const answerPath = path.join(priorRoundDir, dir, 'answer.md');
|
|
96
|
+
if (!fs.existsSync(answerPath))
|
|
97
|
+
continue;
|
|
98
|
+
let body;
|
|
99
|
+
try {
|
|
100
|
+
body = fs.readFileSync(answerPath, 'utf-8');
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (body.trim().length === 0)
|
|
106
|
+
continue;
|
|
107
|
+
// Reviewer dir name shape: `reviewer-<agentName>-<idx>`. Strip the
|
|
108
|
+
// prefix + trailing index so the heading reads cleanly. Falls back
|
|
109
|
+
// to the raw dir name if the regex misses (defensive — agent names
|
|
110
|
+
// with internal dashes still match because we anchor on -<digits>$).
|
|
111
|
+
const labelMatch = dir.match(/^reviewer-(.+)-(\d+)$/);
|
|
112
|
+
const label = labelMatch
|
|
113
|
+
? `${labelMatch[1]} (#${labelMatch[2]})`
|
|
114
|
+
: dir;
|
|
115
|
+
const truncated = body.length > PER_REVIEWER_MAX_BYTES;
|
|
116
|
+
const slice = truncated ? body.slice(0, PER_REVIEWER_MAX_BYTES) : body;
|
|
117
|
+
const block = `### Reviewer: ${label}\n` +
|
|
118
|
+
slice +
|
|
119
|
+
(truncated ? `\n\n_(truncated — full answer was ${body.length} bytes)_\n` : '');
|
|
120
|
+
const blockBytes = Buffer.byteLength(block, 'utf-8');
|
|
121
|
+
if (totalBytes + blockBytes > TOTAL_FEEDBACK_MAX_BYTES) {
|
|
122
|
+
const remaining = reviewerDirs.length - chunks.length;
|
|
123
|
+
chunks.push(`### _(${remaining} more reviewer${remaining === 1 ? '' : 's'} omitted — feedback block exceeded ${TOTAL_FEEDBACK_MAX_BYTES}-byte cap)_`);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
chunks.push(block);
|
|
127
|
+
totalBytes += blockBytes;
|
|
128
|
+
}
|
|
129
|
+
if (chunks.length === 0)
|
|
130
|
+
return '';
|
|
131
|
+
return [
|
|
132
|
+
'## Prior round feedback',
|
|
133
|
+
'',
|
|
134
|
+
'The previous round did not reach reviewer consensus. Read each reviewer\'s findings below and revise your answer to address them — do not just repeat what you wrote before. Where reviewers disagree with each other, use your judgment.',
|
|
135
|
+
'',
|
|
136
|
+
...chunks,
|
|
137
|
+
'',
|
|
138
|
+
].join('\n');
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=prior-round.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prior-round.js","sourceRoot":"","sources":["../../../src/daemon/runner/prior-round.ts"],"names":[],"mappings":"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"}
|