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,340 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Ship phase — open a GitHub PR with the doer's diff after reviewers agree.
|
|
4
|
+
*
|
|
5
|
+
* v0.5 scope (Option 2): branch + commit + push + `gh pr create`. STOPS
|
|
6
|
+
* there. No auto-merge, no CI awaiting, no conflict auto-resolve. Those are
|
|
7
|
+
* v0.6+. The pitch: chorus brings you a PR; a human clicks Merge.
|
|
8
|
+
*
|
|
9
|
+
* Lifecycle:
|
|
10
|
+
* 1. detectGitContext(repoPath) — verify it's a repo, gh installed/authed,
|
|
11
|
+
* base branch resolvable, working tree state OK
|
|
12
|
+
* 2. createShipBranch(...) — branch off baseBranch
|
|
13
|
+
* 3. commitChanges(...) — stage + commit doer's diff
|
|
14
|
+
* 4. pushBranch(...) — push the chorus/<chatId> branch
|
|
15
|
+
* 5. openPr(...) — `gh pr create` against baseBranch
|
|
16
|
+
*
|
|
17
|
+
* On any failure: leave the repo as the user expects (no orphan branches
|
|
18
|
+
* pushed without a PR; no hanging staging area). Caller flips chat status
|
|
19
|
+
* to `blocked` and stores the error string.
|
|
20
|
+
*
|
|
21
|
+
* Graceful degrade: when chat has no repoPath, when gh isn't installed,
|
|
22
|
+
* when there's no remote — caller skips ship and ends chat at `approved`.
|
|
23
|
+
* Not an error.
|
|
24
|
+
*/
|
|
25
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
28
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
29
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
30
|
+
}
|
|
31
|
+
Object.defineProperty(o, k2, desc);
|
|
32
|
+
}) : (function(o, m, k, k2) {
|
|
33
|
+
if (k2 === undefined) k2 = k;
|
|
34
|
+
o[k2] = m[k];
|
|
35
|
+
}));
|
|
36
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
37
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
38
|
+
}) : function(o, v) {
|
|
39
|
+
o["default"] = v;
|
|
40
|
+
});
|
|
41
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
42
|
+
var ownKeys = function(o) {
|
|
43
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
44
|
+
var ar = [];
|
|
45
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
46
|
+
return ar;
|
|
47
|
+
};
|
|
48
|
+
return ownKeys(o);
|
|
49
|
+
};
|
|
50
|
+
return function (mod) {
|
|
51
|
+
if (mod && mod.__esModule) return mod;
|
|
52
|
+
var result = {};
|
|
53
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
54
|
+
__setModuleDefault(result, mod);
|
|
55
|
+
return result;
|
|
56
|
+
};
|
|
57
|
+
})();
|
|
58
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
59
|
+
exports.sanitizeStderr = sanitizeStderr;
|
|
60
|
+
exports.detectGitContext = detectGitContext;
|
|
61
|
+
exports.runShipPhase = runShipPhase;
|
|
62
|
+
const child_process_1 = require("child_process");
|
|
63
|
+
const fs = __importStar(require("fs"));
|
|
64
|
+
const path = __importStar(require("path"));
|
|
65
|
+
const os = __importStar(require("os"));
|
|
66
|
+
/**
|
|
67
|
+
* Sanitise git/gh stderr before persisting it into the chat row's ship_error
|
|
68
|
+
* column or surfacing in the cockpit. The raw output may include the user's
|
|
69
|
+
* home directory, ssh key paths, and full local repo paths — none of which
|
|
70
|
+
* a non-author cockpit viewer should see. We:
|
|
71
|
+
* - replace HOME with `~`
|
|
72
|
+
* - replace any /Users/<name>/ or /home/<name>/ with `~/`
|
|
73
|
+
* - strip lines that mention `id_rsa`, `id_ed25519`, etc. entirely
|
|
74
|
+
* - cap at 600 chars so a runaway stderr can't blow up the DB row
|
|
75
|
+
*/
|
|
76
|
+
function sanitizeStderr(raw) {
|
|
77
|
+
if (!raw)
|
|
78
|
+
return '';
|
|
79
|
+
const home = os.homedir();
|
|
80
|
+
let s = raw;
|
|
81
|
+
if (home && home.length > 3) {
|
|
82
|
+
s = s.split(home).join('~');
|
|
83
|
+
}
|
|
84
|
+
// Unix homedirs.
|
|
85
|
+
s = s.replace(/\/(?:Users|home)\/[^/\s:'"]+/g, '~');
|
|
86
|
+
// Windows homedirs (C:\Users\foo\... or D:\Users\foo\...). Case-insensitive.
|
|
87
|
+
s = s.replace(/[A-Za-z]:\\Users\\[^\\\s:'"]+/g, '~');
|
|
88
|
+
s = s
|
|
89
|
+
.split('\n')
|
|
90
|
+
.filter((line) => !/\bid_(?:rsa|ed25519|ecdsa|dsa)\b/i.test(line))
|
|
91
|
+
.join('\n');
|
|
92
|
+
s = s.trim();
|
|
93
|
+
if (s.length > 600)
|
|
94
|
+
s = s.slice(0, 600) + '… [truncated]';
|
|
95
|
+
return s;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Validate the repo path is shippable. Read-only — never mutates the repo.
|
|
99
|
+
*
|
|
100
|
+
* Caller-controlled UX: when this returns `ok: false`, runner decides
|
|
101
|
+
* whether to surface the issue (e.g. "gh not installed → ship skipped,
|
|
102
|
+
* status=approved") or treat it as a hard fail. Currently every failure
|
|
103
|
+
* mode here results in skip-ship-end-approved — Ship is opt-in by template
|
|
104
|
+
* + repoPath, not a guarantee.
|
|
105
|
+
*/
|
|
106
|
+
function detectGitContext(repoPath, baseBranchOverride) {
|
|
107
|
+
// 1. Path exists + is a directory.
|
|
108
|
+
if (!fs.existsSync(repoPath)) {
|
|
109
|
+
return { ok: false, reason: 'not_a_repo', detail: `Path does not exist: ${repoPath}` };
|
|
110
|
+
}
|
|
111
|
+
const stat = fs.statSync(repoPath);
|
|
112
|
+
if (!stat.isDirectory()) {
|
|
113
|
+
return { ok: false, reason: 'not_a_repo', detail: `Not a directory: ${repoPath}` };
|
|
114
|
+
}
|
|
115
|
+
// 2. Is a git repo?
|
|
116
|
+
const insideRepo = git(repoPath, ['rev-parse', '--is-inside-work-tree']);
|
|
117
|
+
if (!insideRepo.ok || insideRepo.stdout.trim() !== 'true') {
|
|
118
|
+
return { ok: false, reason: 'not_a_repo', detail: `Not a git repo: ${repoPath}` };
|
|
119
|
+
}
|
|
120
|
+
// 3. Has a remote (any name; we use origin if present, first otherwise).
|
|
121
|
+
const remotes = git(repoPath, ['remote', '-v']);
|
|
122
|
+
if (!remotes.ok || remotes.stdout.trim().length === 0) {
|
|
123
|
+
return { ok: false, reason: 'no_remote', detail: 'No git remote configured.' };
|
|
124
|
+
}
|
|
125
|
+
// Prefer 'origin'; fall back to first remote.
|
|
126
|
+
const remoteLines = remotes.stdout.split('\n').filter((l) => l.trim().length > 0);
|
|
127
|
+
const originLine = remoteLines.find((l) => l.startsWith('origin\t')) ?? remoteLines[0];
|
|
128
|
+
const remoteUrl = (originLine.split(/\s+/)[1] ?? '').trim();
|
|
129
|
+
if (!remoteUrl) {
|
|
130
|
+
return { ok: false, reason: 'no_remote', detail: 'Remote URL empty.' };
|
|
131
|
+
}
|
|
132
|
+
// 4. gh CLI installed.
|
|
133
|
+
const ghVersion = run('gh', ['--version'], { cwd: repoPath });
|
|
134
|
+
if (!ghVersion.ok) {
|
|
135
|
+
return {
|
|
136
|
+
ok: false,
|
|
137
|
+
reason: 'gh_not_installed',
|
|
138
|
+
detail: 'gh CLI not on PATH. Install from https://cli.github.com.',
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// 5. gh authenticated for this host.
|
|
142
|
+
const ghAuth = run('gh', ['auth', 'status'], { cwd: repoPath });
|
|
143
|
+
if (!ghAuth.ok) {
|
|
144
|
+
return {
|
|
145
|
+
ok: false,
|
|
146
|
+
reason: 'gh_not_authed',
|
|
147
|
+
detail: `gh not authenticated. Run \`gh auth login\` first. (${sanitizeStderr(ghAuth.stderr).split('\n')[0] ?? ''})`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// 6. Resolve base branch — explicit override > origin/HEAD > origin/main > main.
|
|
151
|
+
const baseBranch = baseBranchOverride ?? detectDefaultBranch(repoPath);
|
|
152
|
+
if (!baseBranch) {
|
|
153
|
+
return {
|
|
154
|
+
ok: false,
|
|
155
|
+
reason: 'base_branch_unresolvable',
|
|
156
|
+
detail: 'Could not detect default branch. Pass `template.ship.baseBranch` explicitly.',
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// 7. Capture starting branch so we can return to it after ship.
|
|
160
|
+
const head = git(repoPath, ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
161
|
+
const startingBranch = head.ok ? head.stdout.trim() : baseBranch;
|
|
162
|
+
return {
|
|
163
|
+
ok: true,
|
|
164
|
+
context: { repoPath, baseBranch, startingBranch, remoteUrl },
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Detect the default branch by asking the remote. Prefers origin/HEAD
|
|
169
|
+
* symref (set by `git clone`); falls back to common branch names.
|
|
170
|
+
*/
|
|
171
|
+
function detectDefaultBranch(repoPath) {
|
|
172
|
+
// Try origin/HEAD symref (cleanest signal).
|
|
173
|
+
const symref = git(repoPath, ['symbolic-ref', 'refs/remotes/origin/HEAD']);
|
|
174
|
+
if (symref.ok) {
|
|
175
|
+
// e.g. "refs/remotes/origin/main" → "main"
|
|
176
|
+
const m = /refs\/remotes\/origin\/(.+)$/.exec(symref.stdout.trim());
|
|
177
|
+
if (m)
|
|
178
|
+
return m[1];
|
|
179
|
+
}
|
|
180
|
+
// Fallback: try common defaults.
|
|
181
|
+
for (const candidate of ['main', 'master', 'develop']) {
|
|
182
|
+
const exists = git(repoPath, ['rev-parse', '--verify', `origin/${candidate}`]);
|
|
183
|
+
if (exists.ok)
|
|
184
|
+
return candidate;
|
|
185
|
+
}
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Run the full ship sequence. Idempotent on the branch name: if the chorus
|
|
190
|
+
* branch already exists locally, we reuse it (allows retries without
|
|
191
|
+
* stomping). If no diff vs base — return `no_changes_to_ship`.
|
|
192
|
+
*/
|
|
193
|
+
function runShipPhase(opts) {
|
|
194
|
+
const { context, chatId, templateId, branchPattern, titleTemplate, summary, doerOutput } = opts;
|
|
195
|
+
const branch = branchPattern.replace('{chatId}', chatId);
|
|
196
|
+
// 1. Anything to ship? Compare working tree + index against base.
|
|
197
|
+
const diff = git(context.repoPath, ['diff', '--name-only', `${context.baseBranch}...HEAD`]);
|
|
198
|
+
const indexDiff = git(context.repoPath, ['status', '--porcelain']);
|
|
199
|
+
const hasCommittedChanges = diff.ok && diff.stdout.trim().length > 0;
|
|
200
|
+
const hasUncommittedChanges = indexDiff.ok && indexDiff.stdout.trim().length > 0;
|
|
201
|
+
if (!hasCommittedChanges && !hasUncommittedChanges) {
|
|
202
|
+
return {
|
|
203
|
+
ok: false,
|
|
204
|
+
stage: 'no_changes_to_ship',
|
|
205
|
+
detail: `No diff vs ${context.baseBranch}; nothing to commit.`,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
// 2. Branch off base. Use checkout -B for idempotence (replaces if exists).
|
|
209
|
+
// Fetch first so we branch off latest origin/<base>.
|
|
210
|
+
git(context.repoPath, ['fetch', 'origin', context.baseBranch]);
|
|
211
|
+
const branchCreate = git(context.repoPath, [
|
|
212
|
+
'checkout',
|
|
213
|
+
'-B',
|
|
214
|
+
branch,
|
|
215
|
+
`origin/${context.baseBranch}`,
|
|
216
|
+
]);
|
|
217
|
+
if (!branchCreate.ok) {
|
|
218
|
+
return {
|
|
219
|
+
ok: false,
|
|
220
|
+
stage: 'branch_create_failed',
|
|
221
|
+
detail: `git checkout -B ${branch} failed: ${sanitizeStderr(branchCreate.stderr)}`,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
// After checkout -B, the working tree changes from the chat's edits are
|
|
225
|
+
// re-applied (git carries them through as long as base + chat don't
|
|
226
|
+
// conflict on the same files). If they did conflict, status will show
|
|
227
|
+
// unmerged paths — we surface that as a commit failure below.
|
|
228
|
+
// 3. Stage + commit. Skip if there's nothing to commit (already on
|
|
229
|
+
// committed history from base — rare but possible if doer used `git commit`
|
|
230
|
+
// directly inside the repo).
|
|
231
|
+
const stage = git(context.repoPath, ['add', '-A']);
|
|
232
|
+
if (!stage.ok) {
|
|
233
|
+
return {
|
|
234
|
+
ok: false,
|
|
235
|
+
stage: 'commit_failed',
|
|
236
|
+
detail: `git add -A failed: ${sanitizeStderr(stage.stderr)}`,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
const commitMsg = formatCommitMessage(templateId, chatId, summary);
|
|
240
|
+
const commit = git(context.repoPath, ['commit', '-m', commitMsg, '--allow-empty']);
|
|
241
|
+
if (!commit.ok) {
|
|
242
|
+
return {
|
|
243
|
+
ok: false,
|
|
244
|
+
stage: 'commit_failed',
|
|
245
|
+
detail: `git commit failed: ${sanitizeStderr(commit.stderr)}`,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
// 4. Push.
|
|
249
|
+
const push = git(context.repoPath, ['push', '-u', 'origin', branch]);
|
|
250
|
+
if (!push.ok) {
|
|
251
|
+
return {
|
|
252
|
+
ok: false,
|
|
253
|
+
stage: 'push_failed',
|
|
254
|
+
detail: `git push failed: ${sanitizeStderr(push.stderr)}`,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
// 5. Open PR via gh.
|
|
258
|
+
const prTitle = titleTemplate
|
|
259
|
+
.replace('{template}', templateId)
|
|
260
|
+
.replace('{chatId}', chatId)
|
|
261
|
+
.replace('{summary}', summary.split('\n')[0]?.slice(0, 60) ?? '');
|
|
262
|
+
const prBody = formatPrBody(templateId, chatId, summary, doerOutput);
|
|
263
|
+
const prCreate = run('gh', [
|
|
264
|
+
'pr',
|
|
265
|
+
'create',
|
|
266
|
+
'--base',
|
|
267
|
+
context.baseBranch,
|
|
268
|
+
'--head',
|
|
269
|
+
branch,
|
|
270
|
+
'--title',
|
|
271
|
+
prTitle,
|
|
272
|
+
'--body',
|
|
273
|
+
prBody,
|
|
274
|
+
], { cwd: context.repoPath });
|
|
275
|
+
if (!prCreate.ok) {
|
|
276
|
+
return {
|
|
277
|
+
ok: false,
|
|
278
|
+
stage: 'pr_create_failed',
|
|
279
|
+
detail: `gh pr create failed: ${sanitizeStderr(prCreate.stderr) || sanitizeStderr(prCreate.stdout)}`,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
// gh prints the PR URL on success; capture it.
|
|
283
|
+
const prUrl = prCreate.stdout.trim().split('\n').pop() ?? '';
|
|
284
|
+
return { ok: true, prUrl, branch };
|
|
285
|
+
}
|
|
286
|
+
function formatCommitMessage(templateId, chatId, summary) {
|
|
287
|
+
const firstLine = summary.split('\n')[0]?.slice(0, 70) ?? `chorus: ${templateId}`;
|
|
288
|
+
return `${firstLine}\n\nGenerated by chorus chat ${chatId} (${templateId} template).\n`;
|
|
289
|
+
}
|
|
290
|
+
function formatPrBody(templateId, chatId, summary, doerOutput) {
|
|
291
|
+
const truncated = doerOutput.length > 8000
|
|
292
|
+
? `${doerOutput.slice(0, 8000)}\n\n_(truncated — full output in chat)_`
|
|
293
|
+
: doerOutput;
|
|
294
|
+
return [
|
|
295
|
+
`Generated by [chorus](https://chorus.codes) — multi-LLM peer-reviewed PR.`,
|
|
296
|
+
``,
|
|
297
|
+
`**Template:** \`${templateId}\``,
|
|
298
|
+
`**Chat ID:** \`${chatId}\``,
|
|
299
|
+
`**Summary:** ${summary.split('\n')[0] ?? '(no summary)'}`,
|
|
300
|
+
``,
|
|
301
|
+
`---`,
|
|
302
|
+
``,
|
|
303
|
+
`## Doer output`,
|
|
304
|
+
``,
|
|
305
|
+
truncated,
|
|
306
|
+
].join('\n');
|
|
307
|
+
}
|
|
308
|
+
function git(repoPath, args) {
|
|
309
|
+
return run('git', args, { cwd: repoPath });
|
|
310
|
+
}
|
|
311
|
+
function run(command, args, opts) {
|
|
312
|
+
try {
|
|
313
|
+
const result = (0, child_process_1.spawnSync)(command, args, {
|
|
314
|
+
cwd: opts.cwd,
|
|
315
|
+
encoding: 'utf-8',
|
|
316
|
+
// 60s per command — covers a slow `gh pr create` against a heavy repo.
|
|
317
|
+
timeout: 60_000,
|
|
318
|
+
});
|
|
319
|
+
return {
|
|
320
|
+
ok: result.status === 0,
|
|
321
|
+
stdout: result.stdout ?? '',
|
|
322
|
+
stderr: result.stderr ?? '',
|
|
323
|
+
code: result.status,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
catch (err) {
|
|
327
|
+
return {
|
|
328
|
+
ok: false,
|
|
329
|
+
stdout: '',
|
|
330
|
+
stderr: err instanceof Error ? err.message : String(err),
|
|
331
|
+
code: null,
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// Suppress linter: execFileSync is imported for symmetry with other shims
|
|
336
|
+
// but currently unused here. Keep the import for future v0.6 work that
|
|
337
|
+
// pipes longer doer outputs via stdin.
|
|
338
|
+
void child_process_1.execFileSync;
|
|
339
|
+
void path;
|
|
340
|
+
//# sourceMappingURL=ship.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ship.js","sourceRoot":"","sources":["../../src/daemon/ship.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Parsed-template cache. Every SSE attach used to re-yaml.parse +
|
|
4
|
+
* zod.parse the template row, which is hot when 5+ tabs watch the same
|
|
5
|
+
* run on a long chat. Keyed by (templateId, updated_at) so an upsert
|
|
6
|
+
* through POST /templates naturally invalidates without an explicit
|
|
7
|
+
* bust call.
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.getParsedTemplate = getParsedTemplate;
|
|
14
|
+
const yaml_1 = __importDefault(require("yaml"));
|
|
15
|
+
const template_schema_js_1 = require("../lib/template-schema.js");
|
|
16
|
+
// Soft cap so the cache can't grow unbounded under a runaway template
|
|
17
|
+
// upsert workload. 50 is well above the realistic working set (10
|
|
18
|
+
// builtins + a handful of user clones); trim oldest-first via Map
|
|
19
|
+
// insertion order.
|
|
20
|
+
const TEMPLATE_CACHE_MAX = 50;
|
|
21
|
+
const cache = new Map();
|
|
22
|
+
function getParsedTemplate(templateId, yamlText, stamp) {
|
|
23
|
+
const hit = cache.get(templateId);
|
|
24
|
+
if (hit && hit.stamp === stamp)
|
|
25
|
+
return hit.parsed;
|
|
26
|
+
const parsed = template_schema_js_1.TemplateSchema.parse(yaml_1.default.parse(yamlText));
|
|
27
|
+
cache.set(templateId, { stamp, parsed });
|
|
28
|
+
// Map iteration order is insertion order; first key is oldest.
|
|
29
|
+
while (cache.size > TEMPLATE_CACHE_MAX) {
|
|
30
|
+
const oldest = cache.keys().next().value;
|
|
31
|
+
if (oldest === undefined)
|
|
32
|
+
break;
|
|
33
|
+
cache.delete(oldest);
|
|
34
|
+
}
|
|
35
|
+
return parsed;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=template-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-cache.js","sourceRoot":"","sources":["../../src/daemon/template-cache.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;AAcH,8CAgBC;AA5BD,gDAAwB;AACxB,kEAA2D;AAI3D,sEAAsE;AACtE,kEAAkE;AAClE,kEAAkE;AAClE,mBAAmB;AACnB,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAC9B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqD,CAAC;AAE3E,SAAgB,iBAAiB,CAC/B,UAAkB,EAClB,QAAgB,EAChB,KAAa;IAEb,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAClC,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,KAAK,KAAK;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC;IAClD,MAAM,MAAM,GAAG,mCAAc,CAAC,KAAK,CAAC,cAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1D,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACzC,+DAA+D;IAC/D,OAAO,KAAK,CAAC,IAAI,GAAG,kBAAkB,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;QACzC,IAAI,MAAM,KAAK,SAAS;YAAE,MAAM;QAChC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Tmux session manager interface. Implementation in src/daemon/tmux.ts.
|
|
3
|
+
//
|
|
4
|
+
// Spec foundations:
|
|
5
|
+
// /home/ubuntu/.claude/projects/-home-ubuntu/memory/chorus_tmux_session_lifecycle.md
|
|
6
|
+
// /home/ubuntu/.claude/projects/-home-ubuntu/memory/feedback_shell_injection_via_tmux.md
|
|
7
|
+
// /home/ubuntu/.claude/projects/-home-ubuntu/memory/feedback_codex_home_per_account.md
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
//# sourceMappingURL=tmux-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmux-types.js","sourceRoot":"","sources":["../../src/daemon/tmux-types.ts"],"names":[],"mappings":";AAAA,wEAAwE;AACxE,EAAE;AACF,oBAAoB;AACpB,uFAAuF;AACvF,2FAA2F;AAC3F,yFAAyF"}
|