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,292 @@
|
|
|
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.packAttachedFiles = packAttachedFiles;
|
|
37
|
+
exports.buildAsk = buildAsk;
|
|
38
|
+
exports.buildReviewerAsk = buildReviewerAsk;
|
|
39
|
+
/**
|
|
40
|
+
* Pure prompt-construction helpers.
|
|
41
|
+
*
|
|
42
|
+
* Three functions that take phase config + user inputs and return the
|
|
43
|
+
* ask.md text the runner pastes into the doer/reviewer CLIs. No fs writes,
|
|
44
|
+
* no subprocess — just string assembly + (for packAttachedFiles) read-only
|
|
45
|
+
* filesystem inspection that's exercised through tests against tmp dirs.
|
|
46
|
+
*
|
|
47
|
+
* Extracted out of runner.ts so the streaming hot paths can be split later
|
|
48
|
+
* without breaking these contracts.
|
|
49
|
+
*/
|
|
50
|
+
const fs = __importStar(require("fs"));
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
// Per-file cap and total cap when inlining attached files into a prompt.
|
|
53
|
+
// Numbers chosen to keep prompts comfortably within Anthropic / OpenAI / Google
|
|
54
|
+
// 1M-token budgets while still surfacing realistic source files. Hardcoded
|
|
55
|
+
// for now; if template authors need larger payloads we'd lift these into
|
|
56
|
+
// template config (template.inputs.maxFileBytes / maxTotalBytes).
|
|
57
|
+
const ATTACHED_FILE_MAX_BYTES = 64 * 1024;
|
|
58
|
+
const ATTACHED_FILES_TOTAL_BYTES = 256 * 1024;
|
|
59
|
+
/**
|
|
60
|
+
* Inline the contents of user-attached files into a single markdown block
|
|
61
|
+
* the doer/reviewer can read directly. Drops files that:
|
|
62
|
+
* - traverse out of repoPath/cwd via `..` (security)
|
|
63
|
+
* - are symlinks (TOCTOU defence)
|
|
64
|
+
* - aren't regular files (sockets, fifos, etc.)
|
|
65
|
+
* - don't exist
|
|
66
|
+
* - would blow past the 256KB total cap
|
|
67
|
+
*
|
|
68
|
+
* Each surviving file is fenced as a markdown code block with its
|
|
69
|
+
* extension as the language hint.
|
|
70
|
+
*/
|
|
71
|
+
function packAttachedFiles(paths, repoPath) {
|
|
72
|
+
if (!paths || paths.length === 0)
|
|
73
|
+
return '';
|
|
74
|
+
const chunks = [];
|
|
75
|
+
let totalBytes = 0;
|
|
76
|
+
const cwdRoot = path.resolve(repoPath ?? process.cwd());
|
|
77
|
+
for (const rel of paths) {
|
|
78
|
+
if (path.isAbsolute(rel)) {
|
|
79
|
+
chunks.push(`### \`${rel}\` — _absolute path rejected, skipping_`);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const abs = path.resolve(path.join(cwdRoot, rel));
|
|
83
|
+
const display = rel;
|
|
84
|
+
if (!abs.startsWith(cwdRoot + path.sep) && abs !== cwdRoot) {
|
|
85
|
+
chunks.push(`### \`${display}\` — _path traversal rejected, skipping_`);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (!fs.existsSync(abs)) {
|
|
89
|
+
chunks.push(`### \`${display}\` — _file not found, skipping_`);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
let body;
|
|
93
|
+
try {
|
|
94
|
+
let fd = -1;
|
|
95
|
+
try {
|
|
96
|
+
// O_NOFOLLOW on Linux/macOS fails with ELOOP if path is a symlink.
|
|
97
|
+
// On Windows, O_NOFOLLOW is unsupported; fall back to lstat+read.
|
|
98
|
+
if (process.platform !== 'win32') {
|
|
99
|
+
try {
|
|
100
|
+
fd = fs.openSync(abs, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
|
|
101
|
+
}
|
|
102
|
+
catch (openErr) {
|
|
103
|
+
// ELOOP = symlink detected via O_NOFOLLOW
|
|
104
|
+
if (openErr instanceof Error && openErr.message.includes('ELOOP')) {
|
|
105
|
+
chunks.push(`### \`${display}\` — _symlink rejected, skipping_`);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
throw openErr;
|
|
109
|
+
}
|
|
110
|
+
const stat = fs.fstatSync(fd);
|
|
111
|
+
if (!stat.isFile()) {
|
|
112
|
+
chunks.push(`### \`${display}\` — _not a regular file, skipping_`);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
body = fs.readFileSync(abs, 'utf-8');
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
// Windows fallback: lstat + read (not race-proof but best effort)
|
|
119
|
+
const lstat = fs.lstatSync(abs);
|
|
120
|
+
if (lstat.isSymbolicLink()) {
|
|
121
|
+
chunks.push(`### \`${display}\` — _symlink rejected, skipping_`);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (!lstat.isFile()) {
|
|
125
|
+
chunks.push(`### \`${display}\` — _not a regular file, skipping_`);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
body = fs.readFileSync(abs, 'utf-8');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
if (fd >= 0)
|
|
133
|
+
fs.closeSync(fd);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
138
|
+
chunks.push(`### \`${display}\` — _read error: ${msg}_`);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const truncated = body.length > ATTACHED_FILE_MAX_BYTES;
|
|
142
|
+
const slice = truncated ? body.slice(0, ATTACHED_FILE_MAX_BYTES) : body;
|
|
143
|
+
const remainingBudget = ATTACHED_FILES_TOTAL_BYTES - totalBytes;
|
|
144
|
+
if (slice.length > remainingBudget) {
|
|
145
|
+
chunks.push(`### \`${display}\` — _skipped: would exceed ${ATTACHED_FILES_TOTAL_BYTES}-byte total cap_`);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
totalBytes += slice.length;
|
|
149
|
+
const ext = path.extname(display).slice(1) || '';
|
|
150
|
+
chunks.push(`### \`${display}\`${truncated ? ` (truncated to ${ATTACHED_FILE_MAX_BYTES} bytes)` : ''}\n\`\`\`${ext}\n${slice}\n\`\`\``);
|
|
151
|
+
}
|
|
152
|
+
if (chunks.length === 0)
|
|
153
|
+
return '';
|
|
154
|
+
return ['## Attached files', '', ...chunks, ''].join('\n');
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Wrap a persona system_prompt in a fenced block for ask.md. Returns
|
|
158
|
+
* empty string when no persona prompt is provided so call sites can do
|
|
159
|
+
* `[personaBlock(...), ...rest].join('\n')` without conditionals.
|
|
160
|
+
*
|
|
161
|
+
* **Fence rationale (retroactive PR #17 review, all 3 reviewers flagged):**
|
|
162
|
+
* persona.system_prompt is user-editable text from the personas table.
|
|
163
|
+
* Without delimiters a malicious or just typo'd persona can ship markdown
|
|
164
|
+
* structure (`# heading`, `---` HR, ``` code fences) that bleeds into the
|
|
165
|
+
* task framing — at best confusing the LLM about heading hierarchy, at
|
|
166
|
+
* worst overriding "Your role" / "How to respond" sections downstream.
|
|
167
|
+
*
|
|
168
|
+
* We use HTML/XML-style tags rather than markdown fences because:
|
|
169
|
+
* - Markdown fences would force the LLM to read the persona AS code,
|
|
170
|
+
* not instructions.
|
|
171
|
+
* - HTML tags are widely understood by current LLMs as semantic
|
|
172
|
+
* boundaries (Anthropic + OpenAI both document this pattern).
|
|
173
|
+
* - A persona that contains the literal `</persona_instructions>` to
|
|
174
|
+
* try to break out is the only escape vector, and we strip it.
|
|
175
|
+
*/
|
|
176
|
+
function personaPromptBlock(systemPrompt) {
|
|
177
|
+
if (!systemPrompt || systemPrompt.trim().length === 0)
|
|
178
|
+
return '';
|
|
179
|
+
// Defensive escape: strip any closing tag that would break out of our
|
|
180
|
+
// fence. Keeps the worst case (a malicious persona) from rewriting the
|
|
181
|
+
// task framing. Open tags are harmless; only the closer matters.
|
|
182
|
+
const sanitized = systemPrompt.trim().replace(/<\/persona_instructions>/gi, '');
|
|
183
|
+
return [
|
|
184
|
+
'<persona_instructions>',
|
|
185
|
+
sanitized,
|
|
186
|
+
'</persona_instructions>',
|
|
187
|
+
'',
|
|
188
|
+
].join('\n');
|
|
189
|
+
}
|
|
190
|
+
/** Build the doer ask.md prompt for one phase iteration. */
|
|
191
|
+
function buildAsk(phase, _phaseIdx, round, work, inputs, filesBlock, personaSystemPrompt, priorRoundFeedback) {
|
|
192
|
+
const lines = [];
|
|
193
|
+
const personaBlock = personaPromptBlock(personaSystemPrompt);
|
|
194
|
+
if (personaBlock) {
|
|
195
|
+
lines.push(personaBlock);
|
|
196
|
+
}
|
|
197
|
+
lines.push(`# Chorus task — round ${round}, phase ${phase.id}`);
|
|
198
|
+
lines.push('');
|
|
199
|
+
lines.push('## Your role');
|
|
200
|
+
lines.push('doer');
|
|
201
|
+
lines.push('');
|
|
202
|
+
lines.push('## What to do');
|
|
203
|
+
lines.push(phase.title);
|
|
204
|
+
if (phase.description) {
|
|
205
|
+
lines.push('');
|
|
206
|
+
lines.push(phase.description);
|
|
207
|
+
}
|
|
208
|
+
lines.push('');
|
|
209
|
+
lines.push("## The user's request");
|
|
210
|
+
lines.push(work);
|
|
211
|
+
lines.push('');
|
|
212
|
+
if (filesBlock) {
|
|
213
|
+
lines.push(filesBlock);
|
|
214
|
+
}
|
|
215
|
+
if (inputs.include && inputs.include.length > 0) {
|
|
216
|
+
lines.push('## Inputs (from prior phases)');
|
|
217
|
+
for (const includePhaseId of inputs.include) {
|
|
218
|
+
lines.push(`- Phase ${includePhaseId}: (link to answer.md)`);
|
|
219
|
+
}
|
|
220
|
+
lines.push('');
|
|
221
|
+
}
|
|
222
|
+
if (inputs.exclude && inputs.exclude.length > 0) {
|
|
223
|
+
lines.push('## Excluded (do NOT read)');
|
|
224
|
+
for (const excludePhaseId of inputs.exclude) {
|
|
225
|
+
lines.push(`- Phase ${excludePhaseId}: explicitly blocked`);
|
|
226
|
+
}
|
|
227
|
+
lines.push('');
|
|
228
|
+
}
|
|
229
|
+
if (priorRoundFeedback && priorRoundFeedback.trim().length > 0) {
|
|
230
|
+
lines.push(priorRoundFeedback);
|
|
231
|
+
}
|
|
232
|
+
lines.push('## How to respond');
|
|
233
|
+
lines.push('Write your full answer and end with: ## DONE');
|
|
234
|
+
return lines.join('\n');
|
|
235
|
+
}
|
|
236
|
+
/** Build the reviewer ask.md prompt for one phase iteration. */
|
|
237
|
+
function buildReviewerAsk(phase, _phaseIdx, round, work, doerOutput, filesBlock, personaSystemPrompt) {
|
|
238
|
+
const lines = [];
|
|
239
|
+
const personaBlock = personaPromptBlock(personaSystemPrompt);
|
|
240
|
+
if (personaBlock) {
|
|
241
|
+
lines.push(personaBlock);
|
|
242
|
+
}
|
|
243
|
+
lines.push(`# Chorus review — round ${round}, phase ${phase.id}`);
|
|
244
|
+
lines.push('');
|
|
245
|
+
lines.push('## Your role');
|
|
246
|
+
lines.push('reviewer');
|
|
247
|
+
lines.push('');
|
|
248
|
+
lines.push('## What to review');
|
|
249
|
+
lines.push(phase.title);
|
|
250
|
+
if (phase.description) {
|
|
251
|
+
lines.push('');
|
|
252
|
+
lines.push(phase.description);
|
|
253
|
+
}
|
|
254
|
+
lines.push('');
|
|
255
|
+
lines.push("## The user's request");
|
|
256
|
+
lines.push(work);
|
|
257
|
+
lines.push('');
|
|
258
|
+
if (filesBlock) {
|
|
259
|
+
lines.push(filesBlock);
|
|
260
|
+
}
|
|
261
|
+
lines.push('## Artifact to review');
|
|
262
|
+
lines.push('```');
|
|
263
|
+
// Truncation cap: 256 KB matches MAX_PHASE_OUTPUT_BYTES in lib/db. The
|
|
264
|
+
// prior 2000-char cap silently amputated any diff or draft over ~50
|
|
265
|
+
// lines, which made review-only mode useless and degraded standard
|
|
266
|
+
// review mode whenever the doer wrote a real implementation. 256 KB
|
|
267
|
+
// covers ~5000 lines of typical code; bigger artifacts truncate with a
|
|
268
|
+
// visible marker so reviewers can still flag the gap.
|
|
269
|
+
const ARTIFACT_PROMPT_CAP_BYTES = 256 * 1024;
|
|
270
|
+
const byteLen = Buffer.byteLength(doerOutput, 'utf-8');
|
|
271
|
+
if (byteLen <= ARTIFACT_PROMPT_CAP_BYTES) {
|
|
272
|
+
lines.push(doerOutput);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
// Slice on bytes, then walk back to the last valid UTF-8 start byte so
|
|
276
|
+
// we don't hand the LLM a U+FFFD-laden tail. UTF-8 continuation bytes
|
|
277
|
+
// start with 0b10xxxxxx — walk left while the cut byte is a
|
|
278
|
+
// continuation byte; landing on a start byte (or ASCII) is safe.
|
|
279
|
+
const buf = Buffer.from(doerOutput, 'utf-8');
|
|
280
|
+
let cut = ARTIFACT_PROMPT_CAP_BYTES;
|
|
281
|
+
while (cut > 0 && (buf[cut] & 0b1100_0000) === 0b1000_0000)
|
|
282
|
+
cut--;
|
|
283
|
+
lines.push(buf.subarray(0, cut).toString('utf-8'));
|
|
284
|
+
lines.push(`... (truncated — full artifact was ${byteLen} bytes, cap is ${ARTIFACT_PROMPT_CAP_BYTES} bytes)`);
|
|
285
|
+
}
|
|
286
|
+
lines.push('```');
|
|
287
|
+
lines.push('');
|
|
288
|
+
lines.push('## Your verdict');
|
|
289
|
+
lines.push('Do you approve? Answer: approve or request changes, end with: ## DONE');
|
|
290
|
+
return lines.join('\n');
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=prompt-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../../../src/daemon/runner/prompt-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
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.runReviewOnlyPhase = runReviewOnlyPhase;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const reviewer_driver_js_1 = require("./reviewer-driver.js");
|
|
10
|
+
/**
|
|
11
|
+
* Run a review-only phase. The artifact (supplied at chat-create time) is
|
|
12
|
+
* written to a synthetic doer answer slot; reviewers then critique it
|
|
13
|
+
* just like a real doer's answer. Single pass — no iterate, no retry.
|
|
14
|
+
* Reviewer agreement/disagreement is reported via outcome.allReviewersFailed;
|
|
15
|
+
* the verdict itself doesn't gate further phases (review-only is the whole
|
|
16
|
+
* point of the chat).
|
|
17
|
+
*
|
|
18
|
+
* Synthetic doer events make the cockpit + replay code paths Just Work
|
|
19
|
+
* without special-casing the missing doer card.
|
|
20
|
+
*/
|
|
21
|
+
async function runReviewOnlyPhase(args) {
|
|
22
|
+
const { chatDir, chatId, phase, phaseIdx, artifact, work, filesBlock, tmuxMgr, errorDetector, onEvent, abortSignal, } = args;
|
|
23
|
+
if (abortSignal.aborted) {
|
|
24
|
+
return { completed: false, allReviewersFailed: false, agreed: false, summary: 'aborted' };
|
|
25
|
+
}
|
|
26
|
+
const round = 1; // review-only is always single-pass
|
|
27
|
+
const roundDir = path_1.default.join(chatDir, `round-${round}`);
|
|
28
|
+
if (!fs_1.default.existsSync(roundDir)) {
|
|
29
|
+
fs_1.default.mkdirSync(roundDir, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
// Synthetic doer dir holds the artifact as answer.md so the cockpit's
|
|
32
|
+
// existing replay code finds it under the same path shape it expects.
|
|
33
|
+
const syntheticDoerDir = path_1.default.join(roundDir, 'doer-artifact');
|
|
34
|
+
if (!fs_1.default.existsSync(syntheticDoerDir)) {
|
|
35
|
+
fs_1.default.mkdirSync(syntheticDoerDir, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
const answerFile = path_1.default.join(syntheticDoerDir, 'answer.md');
|
|
38
|
+
// Strip trailing whitespace before the sentinel check so an artifact
|
|
39
|
+
// ending with "## DONE\n" or "## DONE " doesn't produce a duplicate
|
|
40
|
+
// sentinel after we append. Idempotent: artifacts without the sentinel
|
|
41
|
+
// get a clean "\n\n## DONE\n" tail.
|
|
42
|
+
const trimmed = artifact.replace(/\s+$/, '');
|
|
43
|
+
const artifactWithSentinel = /##\s*DONE$/i.test(trimmed)
|
|
44
|
+
? `${trimmed}\n`
|
|
45
|
+
: `${trimmed}\n\n## DONE\n`;
|
|
46
|
+
fs_1.default.writeFileSync(answerFile, artifactWithSentinel);
|
|
47
|
+
// Synthetic doer phase events. agent='artifact' is a sentinel value the
|
|
48
|
+
// cockpit can render as "user-supplied" rather than as a real CLI run.
|
|
49
|
+
onEvent({
|
|
50
|
+
chatId,
|
|
51
|
+
type: 'phase_start',
|
|
52
|
+
payload: {
|
|
53
|
+
phaseId: phase.id,
|
|
54
|
+
phaseIdx,
|
|
55
|
+
kind: phase.kind,
|
|
56
|
+
round,
|
|
57
|
+
role: 'doer',
|
|
58
|
+
agent: 'artifact',
|
|
59
|
+
synthetic: true,
|
|
60
|
+
},
|
|
61
|
+
ts: Date.now(),
|
|
62
|
+
});
|
|
63
|
+
onEvent({
|
|
64
|
+
chatId,
|
|
65
|
+
type: 'phase_progress',
|
|
66
|
+
payload: {
|
|
67
|
+
phaseId: phase.id,
|
|
68
|
+
round,
|
|
69
|
+
role: 'doer',
|
|
70
|
+
agent: 'artifact',
|
|
71
|
+
output: artifact.slice(0, 500),
|
|
72
|
+
synthetic: true,
|
|
73
|
+
},
|
|
74
|
+
ts: Date.now(),
|
|
75
|
+
});
|
|
76
|
+
// The synthetic StandardPhase shape carries the same reviewer block
|
|
77
|
+
// plus a no-op iterate config so runReviewers can consume it. Local
|
|
78
|
+
// to this call — never escapes back into the template.
|
|
79
|
+
const syntheticStandardPhase = {
|
|
80
|
+
id: phase.id,
|
|
81
|
+
kind: 'review',
|
|
82
|
+
title: phase.title,
|
|
83
|
+
description: phase.description,
|
|
84
|
+
doer: { lineage: 'any' },
|
|
85
|
+
reviewer: phase.reviewer,
|
|
86
|
+
inputs: phase.inputs,
|
|
87
|
+
iterate: {
|
|
88
|
+
maxRounds: 1,
|
|
89
|
+
onDisagreement: 'continue',
|
|
90
|
+
shareSessionAcrossRounds: false,
|
|
91
|
+
shareSessionAcrossPhases: false,
|
|
92
|
+
},
|
|
93
|
+
timeoutMs: phase.timeoutMs,
|
|
94
|
+
};
|
|
95
|
+
const consensus = await (0, reviewer_driver_js_1.runReviewers)(chatDir, chatId, syntheticStandardPhase, phaseIdx, round, artifact, work, filesBlock, tmuxMgr, errorDetector, onEvent, abortSignal, args.templateFallbackReviewer);
|
|
96
|
+
return {
|
|
97
|
+
completed: !abortSignal.aborted,
|
|
98
|
+
allReviewersFailed: consensus.allFailed,
|
|
99
|
+
agreed: consensus.agreed,
|
|
100
|
+
summary: consensus.summary,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=review-only-phase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-only-phase.js","sourceRoot":"","sources":["../../../src/daemon/runner/review-only-phase.ts"],"names":[],"mappings":";;;;;AAmBA,gDAqIC;AAxJD,4CAAoB;AACpB,gDAAwB;AAIxB,6DAAoD;AAGpD;;;;;;;;;;GAUG;AACI,KAAK,UAAU,kBAAkB,CAAC,IAaxC;IAQC,MAAM,EACJ,OAAO,EACP,MAAM,EACN,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,OAAO,EACP,aAAa,EACb,OAAO,EACP,WAAW,GACZ,GAAG,IAAI,CAAC;IAET,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;QACxB,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAC5F,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,oCAAoC;IACrD,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,KAAK,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,YAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,sEAAsE;IACtE,sEAAsE;IACtE,MAAM,gBAAgB,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAC9D,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACrC,YAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IAC5D,qEAAqE;IACrE,qEAAqE;IACrE,uEAAuE;IACvE,oCAAoC;IACpC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC7C,MAAM,oBAAoB,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC;QACtD,CAAC,CAAC,GAAG,OAAO,IAAI;QAChB,CAAC,CAAC,GAAG,OAAO,eAAe,CAAC;IAC9B,YAAE,CAAC,aAAa,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;IAEnD,wEAAwE;IACxE,uEAAuE;IACvE,OAAO,CAAC;QACN,MAAM;QACN,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE;YACP,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,QAAQ;YACR,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,KAAK;YACL,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,UAAU;YACjB,SAAS,EAAE,IAAI;SAChB;QACD,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;KACf,CAAC,CAAC;IACH,OAAO,CAAC;QACN,MAAM;QACN,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE;YACP,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,KAAK;YACL,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;YAC9B,SAAS,EAAE,IAAI;SAChB;QACD,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;KACf,CAAC,CAAC;IAEH,oEAAoE;IACpE,oEAAoE;IACpE,uDAAuD;IACvD,MAAM,sBAAsB,GAAkB;QAC5C,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;QACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,OAAO,EAAE;YACP,SAAS,EAAE,CAAC;YACZ,cAAc,EAAE,UAAU;YAC1B,wBAAwB,EAAE,KAAK;YAC/B,wBAAwB,EAAE,KAAK;SAChC;QACD,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,IAAA,iCAAY,EAClC,OAAO,EACP,MAAM,EACN,sBAAsB,EACtB,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,OAAO,EACP,aAAa,EACb,OAAO,EACP,WAAW,EACX,IAAI,CAAC,wBAAwB,CAC9B,CAAC;IAEF,OAAO;QACL,SAAS,EAAE,CAAC,WAAW,CAAC,OAAO;QAC/B,kBAAkB,EAAE,SAAS,CAAC,SAAS;QACvC,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,OAAO,EAAE,SAAS,CAAC,OAAO;KAC3B,CAAC;AACJ,CAAC"}
|