@mycompbox/compbox-cli 1.13.0

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.
Files changed (98) hide show
  1. package/.tsbuildinfo +1 -0
  2. package/commands/configure.d.ts +24 -0
  3. package/commands/configure.d.ts.map +1 -0
  4. package/commands/configure.js +170 -0
  5. package/commands/configure.js.map +1 -0
  6. package/commands/doctor.d.ts +136 -0
  7. package/commands/doctor.d.ts.map +1 -0
  8. package/commands/doctor.js +606 -0
  9. package/commands/doctor.js.map +1 -0
  10. package/commands/install.d.ts +3 -0
  11. package/commands/install.d.ts.map +1 -0
  12. package/commands/install.js +88 -0
  13. package/commands/install.js.map +1 -0
  14. package/commands/list.d.ts +3 -0
  15. package/commands/list.d.ts.map +1 -0
  16. package/commands/list.js +141 -0
  17. package/commands/list.js.map +1 -0
  18. package/commands/login.d.ts +15 -0
  19. package/commands/login.d.ts.map +1 -0
  20. package/commands/login.js +102 -0
  21. package/commands/login.js.map +1 -0
  22. package/commands/publish.d.ts +3 -0
  23. package/commands/publish.d.ts.map +1 -0
  24. package/commands/publish.js +102 -0
  25. package/commands/publish.js.map +1 -0
  26. package/commands/run.d.ts +76 -0
  27. package/commands/run.d.ts.map +1 -0
  28. package/commands/run.js +417 -0
  29. package/commands/run.js.map +1 -0
  30. package/commands/service.d.ts +29 -0
  31. package/commands/service.d.ts.map +1 -0
  32. package/commands/service.js +142 -0
  33. package/commands/service.js.map +1 -0
  34. package/commands/update.d.ts +3 -0
  35. package/commands/update.d.ts.map +1 -0
  36. package/commands/update.js +141 -0
  37. package/commands/update.js.map +1 -0
  38. package/index.d.ts +3 -0
  39. package/index.d.ts.map +1 -0
  40. package/index.js +8508 -0
  41. package/index.js.map +1 -0
  42. package/package.json +30 -0
  43. package/utils/agent-invoker.d.ts +393 -0
  44. package/utils/agent-invoker.d.ts.map +1 -0
  45. package/utils/agent-invoker.js +1632 -0
  46. package/utils/agent-invoker.js.map +1 -0
  47. package/utils/api-client.d.ts +54 -0
  48. package/utils/api-client.d.ts.map +1 -0
  49. package/utils/api-client.js +214 -0
  50. package/utils/api-client.js.map +1 -0
  51. package/utils/auth-client.d.ts +61 -0
  52. package/utils/auth-client.d.ts.map +1 -0
  53. package/utils/auth-client.js +135 -0
  54. package/utils/auth-client.js.map +1 -0
  55. package/utils/claude-runtime.d.ts +116 -0
  56. package/utils/claude-runtime.d.ts.map +1 -0
  57. package/utils/claude-runtime.js +291 -0
  58. package/utils/claude-runtime.js.map +1 -0
  59. package/utils/config-store.d.ts +128 -0
  60. package/utils/config-store.d.ts.map +1 -0
  61. package/utils/config-store.js +137 -0
  62. package/utils/config-store.js.map +1 -0
  63. package/utils/file-manager.d.ts +32 -0
  64. package/utils/file-manager.d.ts.map +1 -0
  65. package/utils/file-manager.js +208 -0
  66. package/utils/file-manager.js.map +1 -0
  67. package/utils/keychain.d.ts +46 -0
  68. package/utils/keychain.d.ts.map +1 -0
  69. package/utils/keychain.js +167 -0
  70. package/utils/keychain.js.map +1 -0
  71. package/utils/loopback.d.ts +45 -0
  72. package/utils/loopback.d.ts.map +1 -0
  73. package/utils/loopback.js +95 -0
  74. package/utils/loopback.js.map +1 -0
  75. package/utils/mailbox-client.d.ts +98 -0
  76. package/utils/mailbox-client.d.ts.map +1 -0
  77. package/utils/mailbox-client.js +178 -0
  78. package/utils/mailbox-client.js.map +1 -0
  79. package/utils/mcp-config-writer.d.ts +133 -0
  80. package/utils/mcp-config-writer.d.ts.map +1 -0
  81. package/utils/mcp-config-writer.js +184 -0
  82. package/utils/mcp-config-writer.js.map +1 -0
  83. package/utils/pack-bundler.d.ts +30 -0
  84. package/utils/pack-bundler.d.ts.map +1 -0
  85. package/utils/pack-bundler.js +141 -0
  86. package/utils/pack-bundler.js.map +1 -0
  87. package/utils/prompt.d.ts +31 -0
  88. package/utils/prompt.d.ts.map +1 -0
  89. package/utils/prompt.js +86 -0
  90. package/utils/prompt.js.map +1 -0
  91. package/utils/table-formatter.d.ts +42 -0
  92. package/utils/table-formatter.d.ts.map +1 -0
  93. package/utils/table-formatter.js +125 -0
  94. package/utils/table-formatter.js.map +1 -0
  95. package/utils/version-resolver.d.ts +31 -0
  96. package/utils/version-resolver.d.ts.map +1 -0
  97. package/utils/version-resolver.js +75 -0
  98. package/utils/version-resolver.js.map +1 -0
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAevD,SAAS,iBAAiB;IACxB,2EAA2E;IAC3E,2EAA2E;IAC3E,IAAI,OAAO,eAAe,KAAK,WAAW,EAAE,CAAC;QAC3C,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,+DAA+D;IAC/D,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;IAC9D,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,sFAAsF,CAAC;KACnG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;AAEhC,oBAAoB;AACpB,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACnC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;AACrC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAC/B,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AAEnC,kBAAkB;AAClB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@mycompbox/compbox-cli",
3
+ "version": "1.13.0",
4
+ "description": "CompBox CLI - Install, update, and manage Skill Packs",
5
+ "type": "module",
6
+ "bin": {
7
+ "compbox": "./index.js"
8
+ },
9
+ "main": "./index.js",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/mycompbox/CompBox.git",
13
+ "directory": "packages/cli"
14
+ },
15
+ "publishConfig": {
16
+ "registry": "https://registry.npmjs.org",
17
+ "access": "public"
18
+ },
19
+ "dependencies": {
20
+ "@anthropic-ai/sdk": "^0.110.0",
21
+ "axios": "^1.7.0",
22
+ "chalk": "^5.4.0",
23
+ "cli-table3": "^0.6.5",
24
+ "commander": "^12.1.0",
25
+ "form-data": "^4.0.0",
26
+ "ora": "^8.1.0",
27
+ "semver": "^7.7.4",
28
+ "tar": "^7.5.9"
29
+ }
30
+ }
@@ -0,0 +1,393 @@
1
+ /**
2
+ * Agent invoker (ENG-E23 / ENG-122-2) — the daemon's "heart": actually runs a
3
+ * claimed job instead of immediately reporting it as unimplemented.
4
+ *
5
+ * Two agentModes are implemented, both for `epic_request` jobs only
6
+ * (`start_execution` — running planner/orchestrator locally — is NOT
7
+ * implemented here):
8
+ * - `api`: Anthropic Messages API, directly (Anthropic API key, billed
9
+ * per-token). See invokeEpicRequestViaApi.
10
+ * - `claude-subscription`: shells out to the local `claude` CLI
11
+ * non-interactively, using whichever account is already logged in on
12
+ * this machine (personal Pro/Max or a company Team seat) — no API key
13
+ * ever touches CompBox. See invokeEpicRequestViaSubscription.
14
+ *
15
+ * Common to both:
16
+ * - The interview is driven by the shared, declarative INTERVIEW_DEFINITION
17
+ * (@mycompbox/shared, ENG-143) so the machine/mailbox interview reaches the
18
+ * SAME depth as the CLI request-formulator: it covers all seven sections
19
+ * (problem, solution, impact, success metrics, target audience, technical
20
+ * context, alternatives) rather than only the 3 required fields. The system
21
+ * prompt is rendered from that definition (buildInterviewSystemPrompt), and
22
+ * the completion object carries the required fields plus any optional ones
23
+ * the employee provided; there is no shortened variant left in this path.
24
+ *
25
+ * Turn relay: the mailbox has no "wait for a new turn" primitive for a
26
+ * machine caller (next-job's "resume active job" path returns immediately
27
+ * with whatever the job's current state is — see jobService.ts tryClaimOnce).
28
+ * So after posting an agent question, this module polls next-job on a short
29
+ * client-side interval until it observes a new trailing user turn, with a
30
+ * bounded overall timeout so an abandoned interview eventually fails cleanly
31
+ * instead of polling forever.
32
+ */
33
+ import Anthropic from '@anthropic-ai/sdk';
34
+ import { spawn } from 'node:child_process';
35
+ import { type PxpipeRouting, type InterviewSeedPayload } from '@mycompbox/shared';
36
+ import type { MailboxAttachment, MailboxClient, MailboxJob, MailboxJobTurn } from './mailbox-client.js';
37
+ /**
38
+ * pxpipe routing (ENG-136). Anthropic SDK options carrying the proxy `baseURL`
39
+ * when routed through pxpipe, otherwise just the API key. Pure — unit tested.
40
+ */
41
+ export declare function anthropicClientOptions(apiKey: string, routing: PxpipeRouting): {
42
+ apiKey: string;
43
+ baseURL?: string;
44
+ };
45
+ /**
46
+ * pxpipe routing (ENG-136). Child-process env carrying `ANTHROPIC_BASE_URL` when
47
+ * routed through pxpipe, otherwise the base env unchanged. Pure — unit tested.
48
+ */
49
+ export declare function claudeSpawnEnv(base: NodeJS.ProcessEnv, routing: PxpipeRouting): NodeJS.ProcessEnv;
50
+ /** A warning sink; defaults to stderr so a skipped attachment is visible in daemon logs. */
51
+ export type WarnFn = (message: string) => void;
52
+ /** Whether a MIME type is a supported (vision-capable) image type. Pure. */
53
+ export declare function isSupportedImageMediaType(mime: string): boolean;
54
+ /**
55
+ * Select the image attachments to actually fetch for a turn: supported image
56
+ * types only, capped by count and by cumulative DECLARED bytes (the real fetched
57
+ * bytes are re-capped in {@link fetchImageBlocks}). Non-images and over-budget
58
+ * entries are dropped. Pure — no network, no warnings.
59
+ */
60
+ export declare function selectImageAttachments(attachments: MailboxAttachment[] | undefined): MailboxAttachment[];
61
+ /** Count of supported image attachments on a turn (for the subscription note). Pure. */
62
+ export declare function imageAttachmentCount(attachments: MailboxAttachment[] | undefined): number;
63
+ /**
64
+ * Fetch the bytes for each already-selected attachment and turn them into
65
+ * Anthropic base64 image blocks. A broken/unreachable/empty attachment is
66
+ * SKIPPED with a warning — never fatal (requirement 5). Cumulative FETCHED bytes
67
+ * are capped so a lying `sizeBytes` can't blow the budget. `fetchImpl` is
68
+ * injectable for tests.
69
+ */
70
+ export declare function fetchImageBlocks(attachments: MailboxAttachment[], warn?: WarnFn, fetchImpl?: typeof fetch): Promise<Anthropic.ImageBlockParam[]>;
71
+ /**
72
+ * Assemble a user-message `content` for API mode: the raw string when there are
73
+ * no image blocks (byte-identical to the pre-ENG-153 behavior), otherwise an
74
+ * ordered `[...images, {text}]` content array (images first — Anthropic's
75
+ * recommended ordering for a vision prompt). Pure.
76
+ */
77
+ export declare function buildApiUserContent(text: string, imageBlocks: Anthropic.ImageBlockParam[]): string | Anthropic.ContentBlockParam[];
78
+ /**
79
+ * The `content` to push for a USER turn in API mode: fetches + attaches image
80
+ * blocks when the turn has image attachments, otherwise returns the plain text
81
+ * unchanged (no fetch, no warning — a turn with no attachments behaves exactly
82
+ * as today). `fetchImpl` is injectable for tests.
83
+ */
84
+ export declare function apiUserTurnContent(turn: Pick<MailboxJobTurn, 'content' | 'attachments'>, warn?: WarnFn, fetchImpl?: typeof fetch): Promise<string | Anthropic.ContentBlockParam[]>;
85
+ /**
86
+ * Subscription-mode (A4) degradation: append an explicit `[N image(s)
87
+ * attached]` note to the prompt text when the turn carries images (the local
88
+ * `claude -p` invocation has no inline-image channel, so vision is deferred to
89
+ * API mode). Returns the text UNCHANGED when there are no images, so a
90
+ * no-attachment turn is byte-identical to today. Pure.
91
+ */
92
+ export declare function appendAttachmentNote(text: string, imageCount: number): string;
93
+ export interface InvokeResult {
94
+ status: 'done' | 'failed';
95
+ result: Record<string, unknown>;
96
+ }
97
+ export interface EpicRequestDraft {
98
+ title: string;
99
+ problemStatement: string;
100
+ proposedSolution: string;
101
+ impactAssessment: string;
102
+ /**
103
+ * Plain-text markdown description synthesized by the model from the whole
104
+ * conversation — sent as the Epic Request's top-level `description` field
105
+ * (distinct from structuredDesc). REQUIRED: compliance-validation's
106
+ * ER_NO_DESCRIPTION rule (see .github/skills/internal/compliance-validation)
107
+ * fails critical if this is empty, regardless of how good structuredDesc
108
+ * is — verified live: an epic request created with only the 3 structured
109
+ * fields populated (no description) scored 12/100, critical-fail, on
110
+ * ER_NO_DESCRIPTION, ER_NO_PROBLEM_STATEMENT, and ER_NO_IMPACT_ASSESSMENT
111
+ * (the latter two because a single terse summary sentence fell just under
112
+ * the rubric's 50-word/30-word minimums — 47 and 25 words respectively).
113
+ */
114
+ description: string;
115
+ successMetrics?: string;
116
+ targetAudience?: string;
117
+ alternatives?: string;
118
+ dependencies?: string;
119
+ estimatedEffort?: string;
120
+ }
121
+ /**
122
+ * ENG-149 — parse a claimed job's `payload` as an interview-CONTINUATION seed
123
+ * (the ENG-148 dispatch shape), or return null for a normal fresh-start job
124
+ * (empty/absent payload). Validates the two ids are present; tolerates a
125
+ * missing/malformed `priorTranscript` by defaulting it to empty (the daemon
126
+ * still seeds context from the job's own `turns`, which ENG-148 copies into
127
+ * jobB). Exported for unit testing.
128
+ */
129
+ export declare function parseSeedPayload(payload: unknown): InterviewSeedPayload | null;
130
+ /**
131
+ * ENG-149 — the interview system prompt for a job: a seed-aware RESUME/ENRICH
132
+ * prompt for a continuation, otherwise the module-level fresh-start prompt.
133
+ */
134
+ export declare function resolveSystemPrompt(seed: InterviewSeedPayload | null): string;
135
+ /** The server-computed compliance summary the daemon gates the interview on. */
136
+ export interface ComplianceSummary {
137
+ overall: number;
138
+ tier: 'pass' | 'advisory' | 'critical-fail';
139
+ issues: {
140
+ message: string;
141
+ tier: 'critical' | 'advisory';
142
+ }[];
143
+ }
144
+ /**
145
+ * Submit the current draft and read back the server-computed compliance score
146
+ * (bug #2 — audit-aware finishing). Fresh interview: the FIRST submit
147
+ * (`currentErId === null`) CREATES the ER; every later quality round UPDATES that
148
+ * same ER. Continuation: `currentErId` is the target ER from the start, so every
149
+ * submit UPDATES it in place (never a duplicate). Returns the ER id plus its
150
+ * compliance summary (null when the server attaches none).
151
+ */
152
+ export declare function submitAndScore(ctx: {
153
+ apiBaseUrl: string;
154
+ userApiToken: string;
155
+ }, currentErId: string | null, draft: EpicRequestDraft): Promise<{
156
+ erId: string;
157
+ compliance: ComplianceSummary | null;
158
+ }>;
159
+ /**
160
+ * Whether the request is good enough to finish. Reaching the target tier
161
+ * (`pass` = >=90 with no criticals) finishes early. A null score is fail-open:
162
+ * the gate can only act on a score the server actually returned.
163
+ */
164
+ export declare function meetsComplianceTarget(compliance: ComplianceSummary | null): boolean;
165
+ /**
166
+ * Turn a failing compliance score into a corrective instruction: fix by
167
+ * EXPANDING what's already known where possible, otherwise ask ONE question.
168
+ */
169
+ export declare function buildAuditFeedback(compliance: ComplianceSummary): string;
170
+ /**
171
+ * Extracts a completion draft from a model reply, tolerant of the common LLM
172
+ * JSON defects (fenced/plain/bare, trailing commas, and — the big one — literal
173
+ * newlines inside string values). Returns null only when no repair strategy
174
+ * yields a VALID {@link isEpicRequestDraft} object.
175
+ */
176
+ export declare function extractCompletionJson(text: string): EpicRequestDraft | null;
177
+ /**
178
+ * True when a reply is clearly an ATTEMPT to finish (a JSON completion) even if
179
+ * it failed to parse/validate — so the daemon can correct the model instead of
180
+ * relaying raw JSON to the employee as if it were a question (which loops).
181
+ */
182
+ export declare function looksLikeCompletionAttempt(text: string): boolean;
183
+ /**
184
+ * Runs the epic_request interview end-to-end: converses with the user via
185
+ * post-turn/next-job until it has a title + the 3 required structured-desc
186
+ * fields, then creates a personal-scope epic request via the real API
187
+ * (POST /api/v1/me/epic-requests) using the user's own stored token.
188
+ */
189
+ export declare function invokeEpicRequestViaApi(job: MailboxJob, ctx: {
190
+ mailboxClient: MailboxClient;
191
+ machineToken: string;
192
+ apiBaseUrl: string;
193
+ userApiToken: string;
194
+ anthropicApiKey: string;
195
+ }): Promise<InvokeResult>;
196
+ /**
197
+ * Runs the epic_request interview end-to-end using the local `claude` CLI
198
+ * (the employee's own Claude Code login) instead of the Anthropic API.
199
+ * Mirrors invokeEpicRequestViaApi's turn loop and completion handling
200
+ * exactly — only how a single assistant turn is produced differs.
201
+ */
202
+ export declare function invokeEpicRequestViaSubscription(job: MailboxJob, ctx: {
203
+ mailboxClient: MailboxClient;
204
+ machineToken: string;
205
+ apiBaseUrl: string;
206
+ userApiToken: string;
207
+ }): Promise<InvokeResult>;
208
+ /**
209
+ * Per-run wall-clock budget for the headless planner child (H4). Deliberately
210
+ * FAR larger than the interview's {@link CLAUDE_CLI_TURN_TIMEOUT_MS} (~2 min):
211
+ * a full 5-stage `--from-request` planning pipeline (analyze → decompose →
212
+ * detail → evaluate → verify, with many MCP calls and self-correction passes)
213
+ * routinely runs many minutes. 30 minutes bounds a hung run without cutting a
214
+ * legitimate one short.
215
+ */
216
+ export declare const PLANNER_RUN_TIMEOUT_MS: number;
217
+ /**
218
+ * Cadence for the keep-alive heartbeat fired WHILE the planner child runs (H4).
219
+ * The daemon's own 60s runtime heartbeat lives in the poll loop, which is
220
+ * blocked for the entire (long) duration of this job — so without an
221
+ * independent heartbeat here the machine's `lastSeenAt` goes stale and central
222
+ * flips it offline mid-run. This interval pings on its own timer until the
223
+ * child exits.
224
+ */
225
+ export declare const PLANNER_HEARTBEAT_INTERVAL_MS: number;
226
+ /**
227
+ * Build the `claude` argv for a headless planner run (H1). Pure + exported so a
228
+ * unit test can assert the exact command shape: the `@planner` routing prompt,
229
+ * an unattended permission mode, and — critically — the ABSENCE of `--tools ""`
230
+ * and `--safe-mode` (which would strip the MCP tools and @agent routing the
231
+ * planner depends on). No `--system-prompt` (the persona comes from CLAUDE.md
232
+ * routing) and no `--model` override (planning is reasoning-heavy; let the
233
+ * account default apply — pxpipe routing rides on ANTHROPIC_BASE_URL, not the
234
+ * model name).
235
+ */
236
+ export declare function buildPlannerArgs(epicRequestId: string): string[];
237
+ /** Actionable failure when no project repo is configured (mirrors ENG-135's not-found copy). */
238
+ export declare function projectDirNotConfiguredMessage(): string;
239
+ /** Actionable failure when the configured path is not a git repository. */
240
+ export declare function projectDirNotGitRepoMessage(dir: string): string;
241
+ export interface NeedsReviewResult {
242
+ needsReview: boolean;
243
+ /** The parsed marker payload, when one was recovered. */
244
+ marker?: Record<string, unknown>;
245
+ }
246
+ /**
247
+ * Detect a planner (or orchestrator-compatible) "needs human review" outcome in
248
+ * the child's output (ENG-164-4). Matches BOTH markers so detection stays
249
+ * compatible across the pipeline:
250
+ *
251
+ * - Planner (ENG-161): a JSON object whose `outcome` is `"needs-human-review"`
252
+ * (emitted as the final output when EVALUATE lands advisory/critical-fail in
253
+ * non-interactive mode) — see `.github/agents/claude/planner.md` Stage 4.
254
+ * - Orchestrator (ENG-162): a `COMPBOX_NEEDS_HUMAN_REVIEW {json}` prefixed
255
+ * final line — matched by prefix, exactly as ENG-165 will parse it.
256
+ *
257
+ * Pure + exported for unit testing. Fail-safe: if the phrase is present but no
258
+ * clean JSON object can be isolated, it still reports `needsReview: true` (better
259
+ * to surface for review than to mis-report success).
260
+ */
261
+ export declare function detectNeedsHumanReview(output: string): NeedsReviewResult;
262
+ export interface StartExecutionPlanCtx {
263
+ mailboxClient: MailboxClient;
264
+ machineToken: string;
265
+ jobId: string;
266
+ apiBaseUrl: string;
267
+ userApiToken: string;
268
+ /** The approved Epic Request to plan from (payload.epicRequestId). */
269
+ epicRequestId: string;
270
+ /** Resolved project repo dir (may be undefined/invalid — validated here). */
271
+ projectDir: string | undefined;
272
+ }
273
+ export interface StartExecutionPlanDeps {
274
+ /** Injectable child spawner (defaults to node's `spawn`) — tests never spawn a real `claude`. */
275
+ spawnImpl?: typeof spawn;
276
+ /** Injectable fetch for the converted-epic lookup (defaults to global fetch). */
277
+ fetchImpl?: typeof fetch;
278
+ /** Injectable git-repo predicate (defaults to a `.git` existence check via config-store). */
279
+ isGitRepo?: (dir: string) => boolean;
280
+ /** Injectable pxpipe routing resolver (defaults to the shared resolver). */
281
+ resolveRoutingImpl?: () => Promise<PxpipeRouting>;
282
+ /** Best-effort keep-alive fired every {@link PLANNER_HEARTBEAT_INTERVAL_MS} while the child runs (H4). */
283
+ heartbeat?: () => void | Promise<void>;
284
+ heartbeatIntervalMs?: number;
285
+ timeoutMs?: number;
286
+ }
287
+ /**
288
+ * Run the planner headless for a `start_execution`/`plan` job (ENG-164).
289
+ *
290
+ * Flow: validate the project repo → spawn the local `claude` CLI in that repo
291
+ * cwd with MCP + CLAUDE.md routing enabled (H1: unattended permission mode, NOT
292
+ * `--tools ""`/`--safe-mode`) running `@planner --from-request <ER> --gates=auto
293
+ * --non-interactive` with `COMPBOX_NONINTERACTIVE=1` and pxpipe's
294
+ * `ANTHROPIC_BASE_URL` preserved → keep the machine alive with a periodic
295
+ * heartbeat during the long run (H4) → relay a start + final turn to the
296
+ * mailbox → on a clean run resolve the produced epic id from the ER's
297
+ * `convertedEpicId` and complete `{ epicId }`; on a needs-review outcome or a
298
+ * non-zero exit, fail with a result the web failure banner can display.
299
+ */
300
+ export declare function invokeStartExecutionPlan(ctx: StartExecutionPlanCtx, deps?: StartExecutionPlanDeps): Promise<InvokeResult>;
301
+ /**
302
+ * Per-run wall-clock budget for the headless orchestrator child (H4). Executing
303
+ * a full epic (every phase, every feature-worker, reviewer + QA + security
304
+ * passes, worktree merges) runs FAR longer than a planning pass, so this is set
305
+ * well above {@link PLANNER_RUN_TIMEOUT_MS} (30 min). Three hours bounds a hung
306
+ * run without cutting a legitimate multi-feature epic short.
307
+ */
308
+ export declare const ORCHESTRATOR_RUN_TIMEOUT_MS: number;
309
+ /** Keep-alive cadence while the orchestrator child runs (H4) — same as the planner path. */
310
+ export declare const ORCHESTRATOR_HEARTBEAT_INTERVAL_MS: number;
311
+ /**
312
+ * Build the `claude` argv for a headless orchestrator run (H1). Pure + exported
313
+ * so a unit test can assert the exact command shape: the `@orchestrator execute
314
+ * epic <id> --non-interactive` routing prompt, an unattended permission mode,
315
+ * and the ABSENCE of `--tools ""`/`--safe-mode` (which would strip the MCP tools
316
+ * + @agent routing the orchestrator depends on). No `--system-prompt` (the
317
+ * persona comes from CLAUDE.md routing) and no `--model` override (execution is
318
+ * reasoning-heavy; the account default applies — pxpipe rides on
319
+ * ANTHROPIC_BASE_URL, not the model name). `--non-interactive` is what engages
320
+ * the agent-side serial-in-process fallback (H3).
321
+ */
322
+ export declare function buildOrchestratorArgs(epicId: string): string[];
323
+ /** Actionable failure when the configured project path is not a git repository. */
324
+ export declare function orchestrateNotGitRepoMessage(dir: string): string;
325
+ /** Actionable failure when `git worktree` is unavailable in the project dir. */
326
+ export declare function worktreeUnavailableMessage(dir: string): string;
327
+ /** Actionable failure when no JS test toolchain (package manager) is reachable. */
328
+ export declare function toolchainMissingMessage(dir: string): string;
329
+ /**
330
+ * Default precondition: `git worktree list` succeeds in `dir` (proves git is
331
+ * installed AND the directory is a worktree-capable checkout). Uses the same
332
+ * augmented child PATH as the spawn below so a launchd/GUI-spawned daemon (whose
333
+ * inherited PATH often lacks the git install dir) resolves `git` the same way
334
+ * the real run will. Injectable in tests — never shells out there.
335
+ */
336
+ export declare function defaultWorktreeCapable(dir: string): boolean;
337
+ /**
338
+ * Default precondition: a JS test toolchain is reachable. `node` is inherently
339
+ * present (this daemon runs on it), so the real check is that a package manager
340
+ * (pnpm preferred, npm fallback) resolves on the augmented PATH — the
341
+ * orchestrator's phase verification (install/build/typecheck/test) needs one.
342
+ * Injectable in tests — never shells out there.
343
+ */
344
+ export declare function defaultToolchainPresent(_dir: string): boolean;
345
+ export interface StartExecutionOrchestrateCtx {
346
+ mailboxClient: MailboxClient;
347
+ machineToken: string;
348
+ jobId: string;
349
+ /** The existing epic to execute (payload.epicId). */
350
+ epicId: string;
351
+ /** Resolved project repo dir (may be undefined/invalid — validated here). */
352
+ projectDir: string | undefined;
353
+ }
354
+ export interface StartExecutionOrchestrateDeps {
355
+ /** Injectable child spawner (defaults to node's `spawn`) — tests never spawn a real `claude`. */
356
+ spawnImpl?: typeof spawn;
357
+ /** Injectable git-repo predicate (defaults to a `.git` existence check via config-store). */
358
+ isGitRepo?: (dir: string) => boolean;
359
+ /** Injectable git-worktree-capability predicate (defaults to `git worktree list`). */
360
+ worktreeCapable?: (dir: string) => boolean;
361
+ /** Injectable test-toolchain predicate (defaults to a package-manager probe). */
362
+ toolchainPresent?: (dir: string) => boolean;
363
+ /** Injectable pxpipe routing resolver (defaults to the shared resolver). */
364
+ resolveRoutingImpl?: () => Promise<PxpipeRouting>;
365
+ /** Best-effort keep-alive fired every {@link ORCHESTRATOR_HEARTBEAT_INTERVAL_MS} while the child runs (H4). */
366
+ heartbeat?: () => void | Promise<void>;
367
+ heartbeatIntervalMs?: number;
368
+ timeoutMs?: number;
369
+ }
370
+ /**
371
+ * Turn a detected needs-review marker into the job result the web renders
372
+ * (ENG-165-3). Names the halting gate (and its reason/phase/feature when the
373
+ * orchestrator supplied them) so the failure banner is specific rather than a
374
+ * generic "needs review". Pure — exported for unit testing.
375
+ */
376
+ export declare function buildOrchestrateNeedsReviewResult(epicId: string, marker: Record<string, unknown> | undefined): Record<string, unknown>;
377
+ /**
378
+ * Run the orchestrator headless for a `start_execution`/`orchestrate` job
379
+ * (ENG-165).
380
+ *
381
+ * Flow: validate the project repo (git repo → worktree-capable → test toolchain
382
+ * present) → spawn the local `claude` CLI in that repo cwd with ENG-164's MCP +
383
+ * CLAUDE.md-routing profile (H1: unattended permission mode, NOT
384
+ * `--tools ""`/`--safe-mode`) running `@orchestrator execute epic <epicId>
385
+ * --non-interactive` with `COMPBOX_NONINTERACTIVE=1` (H3 signal) and pxpipe's
386
+ * `ANTHROPIC_BASE_URL` preserved → keep the machine alive with a periodic
387
+ * heartbeat during the long run (H4) → relay a start + final turn to the mailbox
388
+ * → on a needs-review HARD-gate marker complete as a needs-review failure naming
389
+ * the gate (ENG-165-3); on a non-zero exit fail with the reason; on a clean run
390
+ * complete `{ epicId }`. Never hangs.
391
+ */
392
+ export declare function invokeStartExecutionOrchestrate(ctx: StartExecutionOrchestrateCtx, deps?: StartExecutionOrchestrateDeps): Promise<InvokeResult>;
393
+ //# sourceMappingURL=agent-invoker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-invoker.d.ts","sourceRoot":"","sources":["../../src/utils/agent-invoker.ts"],"names":[],"mappings":"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"}