issue-flow 0.16.0 → 0.17.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.
- package/dist/agent-TB6W7PT7.js +30 -0
- package/dist/{analyze-556KCJKZ.js → analyze-6M3KEOX7.js} +22 -22
- package/dist/{apply-WVV7G7WN.js → apply-ADB3ZK7W.js} +14 -14
- package/dist/{bench-UBFGKUHR.js → bench-FM7I7EIV.js} +23 -23
- package/dist/{chunk-YA6FWFYW.js → chunk-2SUFAE6X.js} +53 -11
- package/dist/chunk-2SUFAE6X.js.map +1 -0
- package/dist/{chunk-DBEMD34J.js → chunk-32JSYXEK.js} +8 -8
- package/dist/chunk-3R27MJ5R.js +25 -0
- package/dist/chunk-3R27MJ5R.js.map +1 -0
- package/dist/{chunk-QZOBR6YF.js → chunk-6YQT3SSM.js} +4 -4
- package/dist/chunk-6YQT3SSM.js.map +1 -0
- package/dist/{chunk-OGVWJO4S.js → chunk-7F7LGMVO.js} +3 -3
- package/dist/{chunk-X6GY3CM2.js → chunk-A4H7P7T7.js} +102 -102
- package/dist/chunk-A4H7P7T7.js.map +1 -0
- package/dist/{chunk-OGN2NX57.js → chunk-ANI2NTR4.js} +9 -9
- package/dist/{chunk-VK65RNFA.js → chunk-B3TSS7BT.js} +3 -3
- package/dist/chunk-D6ZBGJ3L.js +321 -0
- package/dist/chunk-D6ZBGJ3L.js.map +1 -0
- package/dist/{chunk-MXCOSPLJ.js → chunk-DGRTJD5R.js} +3 -3
- package/dist/{chunk-ROIIEVZH.js → chunk-DUS5ZNKL.js} +474 -361
- package/dist/chunk-DUS5ZNKL.js.map +1 -0
- package/dist/{chunk-VTF4RWS5.js → chunk-DV7HUC4Z.js} +7 -7
- package/dist/{chunk-OOX3RMD3.js → chunk-E6KXCV3T.js} +4 -4
- package/dist/{chunk-OLUOZLU5.js → chunk-HJBF4WD2.js} +1653 -1071
- package/dist/chunk-HJBF4WD2.js.map +1 -0
- package/dist/{chunk-4FUWWBTP.js → chunk-HLAPOUEM.js} +8 -8
- package/dist/{chunk-J2LJB2OH.js → chunk-HY5HLFDU.js} +630 -571
- package/dist/chunk-HY5HLFDU.js.map +1 -0
- package/dist/{chunk-QVLIIGBU.js → chunk-ICM463EO.js} +60 -13
- package/dist/chunk-ICM463EO.js.map +1 -0
- package/dist/{chunk-KV2K7MK2.js → chunk-ISZ54SVE.js} +9 -9
- package/dist/{chunk-GV2DABNZ.js → chunk-KZ5EY5XX.js} +12 -12
- package/dist/{chunk-SW2MF47D.js → chunk-KZXQWC7U.js} +19 -19
- package/dist/{chunk-2H43OVTU.js → chunk-LPWPFIIB.js} +11 -11
- package/dist/{chunk-EPFC4LHT.js → chunk-MI5TREN3.js} +9 -9
- package/dist/{chunk-R42YHLDV.js → chunk-PPZ3K4YM.js} +2 -2
- package/dist/{chunk-H3EYBJZU.js → chunk-QMIQR7EE.js} +10 -10
- package/dist/{chunk-FKWYD44M.js → chunk-QPGEFLMY.js} +2 -2
- package/dist/chunk-RCZJQUTC.js +196 -0
- package/dist/chunk-RCZJQUTC.js.map +1 -0
- package/dist/{chunk-NQCR3HSU.js → chunk-RNFUVKC3.js} +3 -3
- package/dist/{chunk-G5LACAXO.js → chunk-RYOUZ6EK.js} +2 -2
- package/dist/{chunk-BSBJXPLC.js → chunk-SGTTR4XW.js} +10 -10
- package/dist/{chunk-GVOZ6NDO.js → chunk-SOM4QA6C.js} +3 -3
- package/dist/{chunk-73TS2H42.js → chunk-UK4E2FUA.js} +132 -34
- package/dist/chunk-UK4E2FUA.js.map +1 -0
- package/dist/{chunk-PGN2VX4Y.js → chunk-UWDCIFTP.js} +7 -7
- package/dist/{chunk-MCLPSL6B.js → chunk-VE3IYNDN.js} +3 -3
- package/dist/{chunk-IAMIBZRF.js → chunk-WCCZJL7W.js} +2 -2
- package/dist/{chunk-SVDEWOUD.js → chunk-XZUEFTUP.js} +6 -6
- package/dist/{chunk-GPLP7EPL.js → chunk-YII4U7ZD.js} +10 -10
- package/dist/{chunk-GPLP7EPL.js.map → chunk-YII4U7ZD.js.map} +1 -1
- package/dist/{chunk-WLJVL25O.js → chunk-YUNBOUQH.js} +6 -6
- package/dist/{chunk-WNROH2YE.js → chunk-YVPZUN6X.js} +2 -2
- package/dist/{chunk-Q2TZA6AC.js → chunk-Z5O2XBWA.js} +14 -14
- package/dist/cli.js +57 -49
- package/dist/cli.js.map +1 -1
- package/dist/{config-UE7IP36J.js → config-KGZUPAUP.js} +13 -13
- package/dist/{conventions-Z3QC2NSG.js → conventions-RYN7OXJN.js} +15 -15
- package/dist/{diagnostics-2Z5HFQOO.js → diagnostics-HTCWF7F4.js} +7 -7
- package/dist/execute-QL3ZQIAP.js +37 -0
- package/dist/{generate-PB4L7V5N.js → generate-CX6KNHZS.js} +22 -22
- package/dist/{git-7MUOGVRG.js → git-A2IP32PQ.js} +2 -2
- package/dist/init-PDVQDRS6.js +24 -0
- package/dist/{operations-QDJAFZUN.js → operations-CAKIT2BO.js} +15 -15
- package/dist/{permissions-XVXXENVP.js → permissions-G4XCAESF.js} +4 -4
- package/dist/plan-PRORGS3L.js +34 -0
- package/dist/{policy-6WQZB6B2.js → policy-WX6O2JID.js} +14 -14
- package/dist/pr-27RMQI5F.js +39 -0
- package/dist/pr-review-VNESMAMT.js +32 -0
- package/dist/prd-ZNC4T5BS.js +33 -0
- package/dist/{ps-CX7756QG.js → ps-76L6ZAZL.js} +12 -12
- package/dist/{recorder-RK6XZYF3.js → recorder-N7U66HCO.js} +7 -7
- package/dist/{registry-POSB35Q4.js → registry-XLHHYLTR.js} +5 -5
- package/dist/{resume-OQJZV3JH.js → resume-VLWIE264.js} +39 -38
- package/dist/{resume-OQJZV3JH.js.map → resume-VLWIE264.js.map} +1 -1
- package/dist/review-7CREJDKB.js +35 -0
- package/dist/routing-VCDYHSXA.js +33 -0
- package/dist/run-3MPORLF5.js +56 -0
- package/dist/{session-publisher-VVXOCJ2S.js → session-publisher-KAJQRHNZ.js} +3 -2
- package/dist/{state-manager-TIC73GQY.js → state-manager-UPHO2EA2.js} +4 -4
- package/dist/state-manager-UPHO2EA2.js.map +1 -0
- package/dist/{usage-WDDNSIHP.js → usage-U7QNGCPK.js} +12 -12
- package/dist/{web-IPGY52AK.js → web-HUNDHCJ4.js} +20 -18
- package/dist/{web-IPGY52AK.js.map → web-HUNDHCJ4.js.map} +1 -1
- package/package.json +6 -5
- package/web/AGENTS.md +10 -11
- package/web/public/app.css +38 -0
- package/web/public/app.js +277 -56
- package/dist/agent-PMWCDWOW.js +0 -30
- package/dist/chunk-73TS2H42.js.map +0 -1
- package/dist/chunk-7Z4Y3VKM.js +0 -26
- package/dist/chunk-7Z4Y3VKM.js.map +0 -1
- package/dist/chunk-AOAQU7PD.js +0 -180
- package/dist/chunk-AOAQU7PD.js.map +0 -1
- package/dist/chunk-J2LJB2OH.js.map +0 -1
- package/dist/chunk-OLUOZLU5.js.map +0 -1
- package/dist/chunk-QVLIIGBU.js.map +0 -1
- package/dist/chunk-QZOBR6YF.js.map +0 -1
- package/dist/chunk-ROIIEVZH.js.map +0 -1
- package/dist/chunk-X6GY3CM2.js.map +0 -1
- package/dist/chunk-YA6FWFYW.js.map +0 -1
- package/dist/execute-QYLJ5L4T.js +0 -36
- package/dist/init-XBERAZ4O.js +0 -24
- package/dist/plan-RXOW32KY.js +0 -34
- package/dist/pr-3WFYAVA7.js +0 -39
- package/dist/pr-review-RK63ZEMM.js +0 -32
- package/dist/prd-LRV6IW3E.js +0 -33
- package/dist/review-AEFISJZD.js +0 -35
- package/dist/routing-EA5NJGNU.js +0 -94
- package/dist/routing-EA5NJGNU.js.map +0 -1
- package/dist/run-HSC7R33Y.js +0 -55
- /package/dist/{agent-PMWCDWOW.js.map → agent-TB6W7PT7.js.map} +0 -0
- /package/dist/{analyze-556KCJKZ.js.map → analyze-6M3KEOX7.js.map} +0 -0
- /package/dist/{apply-WVV7G7WN.js.map → apply-ADB3ZK7W.js.map} +0 -0
- /package/dist/{bench-UBFGKUHR.js.map → bench-FM7I7EIV.js.map} +0 -0
- /package/dist/{chunk-DBEMD34J.js.map → chunk-32JSYXEK.js.map} +0 -0
- /package/dist/{chunk-OGVWJO4S.js.map → chunk-7F7LGMVO.js.map} +0 -0
- /package/dist/{chunk-OGN2NX57.js.map → chunk-ANI2NTR4.js.map} +0 -0
- /package/dist/{chunk-VK65RNFA.js.map → chunk-B3TSS7BT.js.map} +0 -0
- /package/dist/{chunk-MXCOSPLJ.js.map → chunk-DGRTJD5R.js.map} +0 -0
- /package/dist/{chunk-VTF4RWS5.js.map → chunk-DV7HUC4Z.js.map} +0 -0
- /package/dist/{chunk-OOX3RMD3.js.map → chunk-E6KXCV3T.js.map} +0 -0
- /package/dist/{chunk-4FUWWBTP.js.map → chunk-HLAPOUEM.js.map} +0 -0
- /package/dist/{chunk-KV2K7MK2.js.map → chunk-ISZ54SVE.js.map} +0 -0
- /package/dist/{chunk-GV2DABNZ.js.map → chunk-KZ5EY5XX.js.map} +0 -0
- /package/dist/{chunk-SW2MF47D.js.map → chunk-KZXQWC7U.js.map} +0 -0
- /package/dist/{chunk-2H43OVTU.js.map → chunk-LPWPFIIB.js.map} +0 -0
- /package/dist/{chunk-EPFC4LHT.js.map → chunk-MI5TREN3.js.map} +0 -0
- /package/dist/{chunk-R42YHLDV.js.map → chunk-PPZ3K4YM.js.map} +0 -0
- /package/dist/{chunk-H3EYBJZU.js.map → chunk-QMIQR7EE.js.map} +0 -0
- /package/dist/{chunk-FKWYD44M.js.map → chunk-QPGEFLMY.js.map} +0 -0
- /package/dist/{chunk-NQCR3HSU.js.map → chunk-RNFUVKC3.js.map} +0 -0
- /package/dist/{chunk-G5LACAXO.js.map → chunk-RYOUZ6EK.js.map} +0 -0
- /package/dist/{chunk-BSBJXPLC.js.map → chunk-SGTTR4XW.js.map} +0 -0
- /package/dist/{chunk-GVOZ6NDO.js.map → chunk-SOM4QA6C.js.map} +0 -0
- /package/dist/{chunk-PGN2VX4Y.js.map → chunk-UWDCIFTP.js.map} +0 -0
- /package/dist/{chunk-MCLPSL6B.js.map → chunk-VE3IYNDN.js.map} +0 -0
- /package/dist/{chunk-IAMIBZRF.js.map → chunk-WCCZJL7W.js.map} +0 -0
- /package/dist/{chunk-SVDEWOUD.js.map → chunk-XZUEFTUP.js.map} +0 -0
- /package/dist/{chunk-WLJVL25O.js.map → chunk-YUNBOUQH.js.map} +0 -0
- /package/dist/{chunk-WNROH2YE.js.map → chunk-YVPZUN6X.js.map} +0 -0
- /package/dist/{chunk-Q2TZA6AC.js.map → chunk-Z5O2XBWA.js.map} +0 -0
- /package/dist/{config-UE7IP36J.js.map → config-KGZUPAUP.js.map} +0 -0
- /package/dist/{conventions-Z3QC2NSG.js.map → conventions-RYN7OXJN.js.map} +0 -0
- /package/dist/{diagnostics-2Z5HFQOO.js.map → diagnostics-HTCWF7F4.js.map} +0 -0
- /package/dist/{execute-QYLJ5L4T.js.map → execute-QL3ZQIAP.js.map} +0 -0
- /package/dist/{generate-PB4L7V5N.js.map → generate-CX6KNHZS.js.map} +0 -0
- /package/dist/{git-7MUOGVRG.js.map → git-A2IP32PQ.js.map} +0 -0
- /package/dist/{init-XBERAZ4O.js.map → init-PDVQDRS6.js.map} +0 -0
- /package/dist/{operations-QDJAFZUN.js.map → operations-CAKIT2BO.js.map} +0 -0
- /package/dist/{permissions-XVXXENVP.js.map → permissions-G4XCAESF.js.map} +0 -0
- /package/dist/{plan-RXOW32KY.js.map → plan-PRORGS3L.js.map} +0 -0
- /package/dist/{policy-6WQZB6B2.js.map → policy-WX6O2JID.js.map} +0 -0
- /package/dist/{pr-3WFYAVA7.js.map → pr-27RMQI5F.js.map} +0 -0
- /package/dist/{pr-review-RK63ZEMM.js.map → pr-review-VNESMAMT.js.map} +0 -0
- /package/dist/{prd-LRV6IW3E.js.map → prd-ZNC4T5BS.js.map} +0 -0
- /package/dist/{ps-CX7756QG.js.map → ps-76L6ZAZL.js.map} +0 -0
- /package/dist/{recorder-RK6XZYF3.js.map → recorder-N7U66HCO.js.map} +0 -0
- /package/dist/{registry-POSB35Q4.js.map → registry-XLHHYLTR.js.map} +0 -0
- /package/dist/{review-AEFISJZD.js.map → review-7CREJDKB.js.map} +0 -0
- /package/dist/{run-HSC7R33Y.js.map → routing-VCDYHSXA.js.map} +0 -0
- /package/dist/{session-publisher-VVXOCJ2S.js.map → run-3MPORLF5.js.map} +0 -0
- /package/dist/{state-manager-TIC73GQY.js.map → session-publisher-KAJQRHNZ.js.map} +0 -0
- /package/dist/{usage-WDDNSIHP.js.map → usage-U7QNGCPK.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/telemetry/recorder.ts","../src/telemetry/pricing.ts","../src/telemetry/types.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { hostname } from 'node:os';\nimport type { ClaudeUsage } from '../core/metrics.js';\nimport { isoNow, loadTaskPlan, saveTaskPlan } from '../core/state-manager.js';\nimport { classify } from '../resilience/errors.js';\nimport type { TaskPlan } from '../types.js';\nimport { resolveCost } from './pricing.js';\nimport { redactFailureMessage } from './redact.js';\nimport { getTelemetrySessionId, setTelemetrySessionId } from './session-id.js';\nimport {\n DEFAULT_TELEMETRY_CONFIG,\n type ExecutionPurpose,\n type ExecutionRecord,\n type ExecutionStatus,\n type ExecutionTrigger,\n type NormalizedUsage,\n type StopReason,\n type TelemetryConfig,\n} from './types.js';\n\nexport interface TelemetryContext {\n tasksPath: string;\n sessionId?: string | null;\n config?: TelemetryConfig;\n}\n\nlet context: TelemetryContext | null = null;\nlet discardedCount = 0;\n\nexport function bindTelemetry(next: TelemetryContext | null): void {\n context = next;\n}\n\nexport function getTelemetryContext(): TelemetryContext | null {\n return context;\n}\n\nexport function discardedExecutionCount(): number {\n return discardedCount;\n}\n\nexport function resetTelemetryState(): void {\n context = null;\n discardedCount = 0;\n setTelemetrySessionId(null);\n}\n\nasync function resolveConfig(ctx: TelemetryContext): Promise<TelemetryConfig> {\n if (ctx.config !== undefined) return ctx.config;\n try {\n const { loadTelemetryConfig } = await import('../config.js');\n ctx.config = await loadTelemetryConfig();\n return ctx.config;\n } catch {\n return DEFAULT_TELEMETRY_CONFIG;\n }\n}\n\nfunction cap(records: ExecutionRecord[], max: number): ExecutionRecord[] {\n if (records.length <= max) return records;\n discardedCount += records.length - max;\n return records.slice(records.length - max);\n}\n\nasync function mutate(tasksPath: string, update: (plan: TaskPlan) => TaskPlan): Promise<void> {\n const plan = await loadTaskPlan(tasksPath);\n await saveTaskPlan(tasksPath, update(plan));\n}\n\nexport function usageFromClaude(usage: ClaudeUsage | null | undefined): NormalizedUsage | null {\n if (usage === undefined || usage === null) return null;\n const next: NormalizedUsage = { source: 'provider' };\n if (usage.inputTokens !== undefined) next.inputTokens = usage.inputTokens;\n if (usage.outputTokens !== undefined) next.outputTokens = usage.outputTokens;\n if (usage.cacheReadTokens !== undefined) next.cacheReadTokens = usage.cacheReadTokens;\n if (usage.cacheCreationTokens !== undefined) next.cacheCreationTokens = usage.cacheCreationTokens;\n return next;\n}\n\nexport interface BeginExecutionInput {\n purpose: ExecutionPurpose;\n attempt?: number;\n trigger?: ExecutionTrigger;\n triggerReason?: ExecutionRecord['triggerReason'];\n harness: string;\n provider?: string | null;\n harnessVersion?: string | null;\n modelRequested?: string | null;\n modelResolved?: string | null;\n modelSource?: ExecutionRecord['agent']['model']['source'];\n iteration?: number;\n correctionCycle?: number;\n storyIds?: string[];\n routingDecision?: ExecutionRecord['routingDecision'];\n}\n\nexport async function beginExecution(input: BeginExecutionInput): Promise<string | null> {\n const ctx = context;\n if (ctx === null) return null;\n const cfg = await resolveConfig(ctx);\n if (!cfg.enabled) return null;\n\n const id = randomUUID();\n const record: ExecutionRecord = {\n id,\n sessionId: ctx.sessionId ?? getTelemetrySessionId(),\n purpose: input.purpose,\n attempt: input.attempt ?? 1,\n trigger: input.trigger ?? 'initial',\n triggerReason: input.triggerReason ?? null,\n agent: {\n harness: input.harness,\n provider: input.provider ?? null,\n harnessVersion: input.harnessVersion ?? null,\n model: {\n requested: input.modelRequested ?? null,\n resolved: input.modelResolved ?? null,\n source: input.modelSource ?? (input.modelResolved ? 'provider' : 'unavailable'),\n },\n providerSessionId: null,\n },\n startedAt: isoNow(),\n finishedAt: null,\n durationMs: null,\n usage: null,\n cost: { status: 'unknown', reason: 'not_reported' },\n status: 'running',\n failure: null,\n owner: { pid: process.pid, host: hostname() },\n ...(input.iteration === undefined ? {} : { iteration: input.iteration }),\n ...(input.correctionCycle === undefined ? {} : { correctionCycle: input.correctionCycle }),\n ...(input.storyIds === undefined ? {} : { storyIds: input.storyIds }),\n ...(input.routingDecision === undefined || input.routingDecision === null\n ? {}\n : { routingDecision: input.routingDecision }),\n };\n\n try {\n await mutate(ctx.tasksPath, (plan) => ({\n ...plan,\n executions: cap([...(plan.executions ?? []), record], cfg.maxExecutions),\n }));\n const { getSessionPublisher } = await import('../core/session-publisher.js');\n getSessionPublisher().publish({\n type: 'execution:update',\n at: record.startedAt,\n execution: record,\n });\n return id;\n } catch {\n return null;\n }\n}\n\n/** Wall clock vs CLI envelope: startup the harness does not report. */\nexport function timingFromUsage(\n wallClockMs: number | null,\n usage: ClaudeUsage | null | undefined,\n): Pick<\n ExecutionRecord,\n 'cliDurationMs' | 'harnessStartupMs' | 'apiDurationMs' | 'ttftMs' | 'numTurns'\n> {\n const cli = usage?.cliDurationMs;\n const cliDurationMs = cli === undefined ? null : cli;\n const harnessStartupMs =\n wallClockMs !== null && cli !== undefined ? Math.max(0, wallClockMs - cli) : null;\n return {\n cliDurationMs,\n harnessStartupMs,\n apiDurationMs: usage?.apiDurationMs ?? null,\n ttftMs: usage?.ttftMs ?? null,\n numTurns: usage?.numTurns ?? null,\n };\n}\n\nexport async function attachVerdict(verdict: ExecutionRecord['verdict']): Promise<void> {\n const ctx = context;\n if (ctx === null || verdict == null) return;\n try {\n await mutate(ctx.tasksPath, (plan) => {\n const records = [...(plan.executions ?? [])];\n if (records.length === 0) return plan;\n const index = records.length - 1;\n const current = records[index];\n if (current === undefined) return plan;\n records[index] = { ...current, verdict };\n return { ...plan, executions: records };\n });\n } catch {\n // Observational: a failed write must never change the invocation outcome.\n }\n}\n\nexport interface EndExecutionInput {\n id: string;\n status?: ExecutionStatus;\n usage?: ClaudeUsage | null;\n reportedUsd?: number | null;\n error?: string | null;\n exitCode?: number | null;\n storyIds?: string[];\n cancelled?: boolean;\n timedOut?: boolean;\n modelResolved?: string | null;\n modelSource?: ExecutionRecord['agent']['model']['source'];\n harnessVersion?: string | null;\n providerSessionId?: string | null;\n stopReason?: StopReason | null;\n}\n\nexport async function endExecution(input: EndExecutionInput): Promise<void> {\n const ctx = context;\n if (ctx === null) return;\n const cfg = await resolveConfig(ctx);\n if (!cfg.enabled) return;\n\n const usage = usageFromClaude(input.usage);\n const timedOut = input.timedOut === true || /\\btimed out\\b/i.test(input.error ?? '');\n const cancelled = input.cancelled === true;\n let status: ExecutionStatus = input.status ?? 'completed';\n if (input.status === undefined) {\n if (cancelled) status = 'cancelled';\n else if (timedOut) status = 'timeout';\n else if (input.error) status = 'failed';\n }\n\n const failure =\n status === 'completed'\n ? null\n : {\n kind: classify({\n source: 'agent',\n stdout: input.error ?? '',\n exitCode: input.exitCode,\n timedOut,\n }).kind,\n message: redactFailureMessage(input.error ?? status),\n exitCode: input.exitCode ?? null,\n };\n\n const completed: { value: ExecutionRecord | null } = { value: null };\n try {\n await mutate(ctx.tasksPath, (plan) => {\n const records = [...(plan.executions ?? [])];\n const index = records.findIndex((record) => record.id === input.id);\n if (index === -1) return plan;\n const current = records[index];\n if (current === undefined) return plan;\n const started = Date.parse(current.startedAt);\n const finishedAt = isoNow();\n const modelResolved = input.modelResolved ?? current.agent.model.resolved;\n const modelKey = modelResolved ?? current.agent.model.requested;\n records[index] = {\n ...current,\n agent: {\n ...current.agent,\n harnessVersion: input.harnessVersion ?? current.agent.harnessVersion,\n providerSessionId: input.providerSessionId ?? current.agent.providerSessionId,\n model: {\n ...current.agent.model,\n resolved: modelResolved,\n source:\n input.modelSource ??\n (modelResolved\n ? current.agent.model.source === 'unavailable'\n ? 'provider'\n : current.agent.model.source\n : current.agent.model.source),\n },\n },\n finishedAt,\n durationMs: Number.isFinite(started) ? Math.max(0, Date.now() - started) : null,\n ...timingFromUsage(\n Number.isFinite(started) ? Math.max(0, Date.now() - started) : null,\n input.usage,\n ),\n usage,\n cost: resolveCost({\n reportedUsd: input.reportedUsd ?? input.usage?.costUsd,\n usage,\n modelKey,\n estimate: cfg.pricing.estimate,\n overrides: cfg.pricing.overrides,\n }),\n status,\n failure,\n owner: null,\n ...(input.storyIds === undefined ? {} : { storyIds: input.storyIds }),\n ...(input.stopReason === undefined ? {} : { stopReason: input.stopReason }),\n };\n completed.value = records[index] ?? null;\n return { ...plan, executions: records };\n });\n if (completed.value !== null) {\n const { getSessionPublisher } = await import('../core/session-publisher.js');\n getSessionPublisher().publish({\n type: 'execution:update',\n at: completed.value.finishedAt ?? isoNow(),\n execution: completed.value,\n });\n }\n } catch {\n // Observational: a failed write must never change the invocation outcome.\n }\n}\n\nexport async function recordInvocation<T>(\n input: BeginExecutionInput,\n invoke: () => Promise<T>,\n finish: (result: T) => EndExecutionInput,\n): Promise<T> {\n const id = await beginExecution(input);\n try {\n const result = await invoke();\n if (id !== null) {\n await endExecution({ ...finish(result), id });\n }\n return result;\n } catch (err) {\n if (id !== null) {\n await endExecution({\n id,\n status: 'failed',\n error: err instanceof Error ? err.message : String(err),\n });\n }\n throw err;\n }\n}\n","import { isoNow } from '../core/state-manager.js';\nimport type { CostRecord, NormalizedUsage, PricingSnapshot, TelemetryConfig } from './types.js';\n\nexport const PRICING_TABLE_VERSION = '2026-08-30';\n\ninterface PricingRow {\n inputPerMillion: number;\n outputPerMillion: number;\n cacheReadPerMillion?: number;\n cacheWritePerMillion?: number;\n}\n\n/** Microdollars-per-million would be more precise; dollars keep the snapshot readable. */\nconst TABLE: Record<string, PricingRow> = {\n 'claude-sonnet-4': {\n inputPerMillion: 3,\n outputPerMillion: 15,\n cacheReadPerMillion: 0.3,\n cacheWritePerMillion: 3.75,\n },\n 'claude-sonnet-4-5': {\n inputPerMillion: 3,\n outputPerMillion: 15,\n cacheReadPerMillion: 0.3,\n cacheWritePerMillion: 3.75,\n },\n 'claude-opus-4': {\n inputPerMillion: 15,\n outputPerMillion: 75,\n cacheReadPerMillion: 1.5,\n cacheWritePerMillion: 18.75,\n },\n 'gpt-5': { inputPerMillion: 1.25, outputPerMillion: 10 },\n 'gpt-5.1': { inputPerMillion: 1.25, outputPerMillion: 10 },\n};\n\n/** Aliases a harness accepts in place of a model id. */\nconst ALIASES: Record<string, string> = {\n sonnet: 'claude-sonnet-4-5',\n opus: 'claude-opus-4',\n};\n\n/**\n * Map a resolved model id onto a table key.\n *\n * What reaches here is whatever the harness reported: a dated snapshot\n * (`claude-sonnet-4-5-20250929`), a vendor-prefixed id\n * (`anthropic/claude-sonnet-4-5`) or a configured alias (`sonnet`). An exact\n * lookup misses all three, and the estimate silently degrades to `unknown`.\n * An override is always honoured under the key the user wrote.\n */\nexport function normalizeModelKey(modelKey: string): string {\n const lower = modelKey.trim().toLowerCase();\n const withoutVendor = lower.slice(lower.lastIndexOf('/') + 1);\n const withoutSnapshot = withoutVendor.replace(/-\\d{8}$/, '').replace(/-latest$/, '');\n return ALIASES[withoutSnapshot] ?? withoutSnapshot;\n}\n\nfunction rowFor(\n modelKey: string,\n overrides: TelemetryConfig['pricing']['overrides'],\n): PricingRow | null {\n const normalized = normalizeModelKey(modelKey);\n const override = overrides[modelKey] ?? overrides[normalized];\n const base = TABLE[modelKey] ?? TABLE[normalized];\n if (override === undefined && base === undefined) return null;\n return {\n inputPerMillion: override?.inputPerMillion ?? base?.inputPerMillion ?? 0,\n outputPerMillion: override?.outputPerMillion ?? base?.outputPerMillion ?? 0,\n cacheReadPerMillion: override?.cacheReadPerMillion ?? base?.cacheReadPerMillion,\n cacheWritePerMillion: override?.cacheWritePerMillion ?? base?.cacheWritePerMillion,\n };\n}\n\nfunction dollars(tokens: number | undefined, perMillion: number | undefined): number {\n if (tokens === undefined || perMillion === undefined) return 0;\n return (tokens * perMillion) / 1_000_000;\n}\n\nexport function resolveCost(options: {\n reportedUsd?: number | null;\n usage: NormalizedUsage | null;\n modelKey: string | null;\n estimate: boolean;\n overrides?: TelemetryConfig['pricing']['overrides'];\n}): CostRecord {\n if (options.reportedUsd !== undefined && options.reportedUsd !== null) {\n return { status: 'reported', amount: options.reportedUsd, currency: 'USD' };\n }\n if (!options.estimate) {\n return { status: 'unknown', reason: 'not_reported' };\n }\n if (options.modelKey === null || options.modelKey === '') {\n return { status: 'unknown', reason: 'unknown_model' };\n }\n const row = rowFor(options.modelKey, options.overrides ?? {});\n if (row === null) {\n return { status: 'unknown', reason: 'unknown_model' };\n }\n if (options.usage === null || options.usage.source === 'unavailable') {\n return { status: 'unknown', reason: 'not_reported' };\n }\n const amount =\n dollars(options.usage.inputTokens, row.inputPerMillion) +\n dollars(options.usage.outputTokens, row.outputPerMillion) +\n dollars(options.usage.cacheReadTokens, row.cacheReadPerMillion) +\n dollars(options.usage.cacheCreationTokens, row.cacheWritePerMillion);\n const pricing: PricingSnapshot = {\n tableVersion: PRICING_TABLE_VERSION,\n modelKey: options.modelKey,\n inputPerMillion: row.inputPerMillion,\n outputPerMillion: row.outputPerMillion,\n capturedAt: isoNow(),\n ...(row.cacheReadPerMillion === undefined\n ? {}\n : { cacheReadPerMillion: row.cacheReadPerMillion }),\n ...(row.cacheWritePerMillion === undefined\n ? {}\n : { cacheWritePerMillion: row.cacheWritePerMillion }),\n };\n return { status: 'estimated', amount, currency: 'USD', pricing };\n}\n\nexport function estimateCost(\n usage: NormalizedUsage,\n modelKey: string,\n overrides: TelemetryConfig['pricing']['overrides'] = {},\n): CostRecord {\n return resolveCost({ usage, modelKey, estimate: true, overrides });\n}\n","import type { FailureKind } from '../resilience/errors.js';\n\nexport const EXECUTION_PURPOSES = [\n 'analyze',\n 'generate',\n 'prd',\n 'plan',\n 'execute',\n 'review',\n 'pr',\n 'pr-review',\n 'verify',\n] as const;\n\nexport type ExecutionPurpose = (typeof EXECUTION_PURPOSES)[number];\n\nexport type ExecutionTrigger = 'initial' | 'retry' | 'fallback' | 'correction' | 'escalation';\n\nexport type ExecutionStatus =\n | 'running'\n | 'completed'\n | 'failed'\n | 'timeout'\n | 'cancelled'\n | 'interrupted';\n\nexport type StopReason =\n | 'completed'\n | 'failed'\n | 'timeout'\n | 'cancelled'\n | 'max_attempts'\n | 'max_cost'\n | 'max_duration';\n\nexport type VerdictStatus = 'passed' | 'failed' | 'unverified';\n\nexport interface NormalizedUsage {\n inputTokens?: number;\n outputTokens?: number;\n cacheReadTokens?: number;\n cacheCreationTokens?: number;\n reasoningTokens?: number;\n details?: Record<string, number>;\n source: 'provider' | 'unavailable';\n}\n\nexport interface PricingSnapshot {\n tableVersion: string;\n modelKey: string;\n inputPerMillion: number;\n outputPerMillion: number;\n cacheReadPerMillion?: number;\n cacheWritePerMillion?: number;\n capturedAt: string;\n}\n\nexport type CostRecord =\n | { status: 'reported'; amount: number; currency: 'USD' }\n | { status: 'estimated'; amount: number; currency: 'USD'; pricing: PricingSnapshot }\n | {\n status: 'unknown';\n reason: 'not_reported' | 'no_pricing' | 'unknown_model' | 'subscription' | 'zero_rated';\n };\n\nexport interface ExecutionAgent {\n harness: string;\n provider: string | null;\n harnessVersion?: string | null;\n model: {\n requested: string | null;\n resolved: string | null;\n source: 'provider' | 'config' | 'unavailable';\n };\n providerSessionId: string | null;\n}\n\nexport interface ExecutionOwner {\n pid: number;\n host: string;\n}\n\nexport interface ExecutionVerdict {\n status: VerdictStatus;\n level?: string | null;\n independence?: string | null;\n}\n\nexport interface RoutingDecision {\n selected: string;\n actual?: string;\n candidates?: unknown[];\n reasonCodes?: string[];\n [key: string]: unknown;\n}\n\nexport interface ExecutionRecord {\n id: string;\n sessionId: string | null;\n purpose: ExecutionPurpose;\n attempt: number;\n trigger: ExecutionTrigger;\n triggerReason: FailureKind | null;\n agent: ExecutionAgent;\n startedAt: string;\n finishedAt: string | null;\n durationMs: number | null;\n /** Envelope duration when the CLI reports it. */\n cliDurationMs?: number | null;\n /** wallClock − cliDuration: startup the CLI does not see. */\n harnessStartupMs?: number | null;\n /** Envelope `duration_api_ms` when reported. */\n apiDurationMs?: number | null;\n /** Time to first output, when reported. */\n ttftMs?: number | null;\n numTurns?: number | null;\n usage: NormalizedUsage | null;\n cost: CostRecord;\n status: ExecutionStatus;\n failure: {\n kind: FailureKind;\n message: string;\n exitCode: number | null;\n } | null;\n stopReason?: StopReason | null;\n iteration?: number;\n /** Correction cycle active when this invocation started; 0 is the initial pass. */\n correctionCycle?: number;\n storyIds?: string[];\n owner?: ExecutionOwner | null;\n routingDecision?: RoutingDecision | null;\n verdict?: ExecutionVerdict | null;\n}\n\nexport interface CostTotals {\n reported: number;\n estimated: number;\n unknownExecutions: number;\n}\n\nexport interface ExecutionSummary {\n count: number;\n discarded: number;\n byStatus: Partial<Record<ExecutionStatus, number>>;\n usage: {\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheCreationTokens: number;\n reasoningTokens: number;\n };\n totalCost: CostTotals;\n}\n\nexport interface TelemetryConfig {\n enabled: boolean;\n maxExecutions: number;\n pricing: {\n estimate: boolean;\n overrides: Record<string, Partial<PricingSnapshot>>;\n };\n}\n\nexport const DEFAULT_TELEMETRY_CONFIG: TelemetryConfig = {\n enabled: true,\n maxExecutions: 500,\n pricing: { estimate: false, overrides: {} },\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/telemetry/recorder.ts","../src/telemetry/pricing.ts","../src/telemetry/types.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { hostname } from 'node:os';\nimport type { ClaudeUsage } from '../core/metrics.js';\nimport { isoNow, loadTaskPlan, saveTaskPlan } from '../core/state-manager.js';\nimport { classify } from '../resilience/errors.js';\nimport type { TaskPlan } from '../types.js';\nimport { resolveCost } from './pricing.js';\nimport { redactFailureMessage } from './redact.js';\nimport { getTelemetrySessionId, setTelemetrySessionId } from './session-id.js';\nimport {\n DEFAULT_TELEMETRY_CONFIG,\n type ExecutionPurpose,\n type ExecutionRecord,\n type ExecutionStatus,\n type ExecutionTrigger,\n type NormalizedUsage,\n type StopReason,\n type TelemetryConfig,\n} from './types.js';\n\nexport interface TelemetryContext {\n tasksPath: string;\n sessionId?: string | null;\n config?: TelemetryConfig;\n}\n\nlet context: TelemetryContext | null = null;\nlet discardedCount = 0;\n\nexport function bindTelemetry(next: TelemetryContext | null): void {\n context = next;\n}\n\nexport function getTelemetryContext(): TelemetryContext | null {\n return context;\n}\n\nexport function discardedExecutionCount(): number {\n return discardedCount;\n}\n\nexport function resetTelemetryState(): void {\n context = null;\n discardedCount = 0;\n setTelemetrySessionId(null);\n}\n\nasync function resolveConfig(ctx: TelemetryContext): Promise<TelemetryConfig> {\n if (ctx.config !== undefined) return ctx.config;\n try {\n const { loadTelemetryConfig } = await import('../config.js');\n ctx.config = await loadTelemetryConfig();\n return ctx.config;\n } catch {\n return DEFAULT_TELEMETRY_CONFIG;\n }\n}\n\nfunction cap(records: ExecutionRecord[], max: number): ExecutionRecord[] {\n if (records.length <= max) return records;\n discardedCount += records.length - max;\n return records.slice(records.length - max);\n}\n\nasync function mutate(tasksPath: string, update: (plan: TaskPlan) => TaskPlan): Promise<void> {\n const plan = await loadTaskPlan(tasksPath);\n await saveTaskPlan(tasksPath, update(plan));\n}\n\nexport function usageFromClaude(usage: ClaudeUsage | null | undefined): NormalizedUsage | null {\n if (usage === undefined || usage === null) return null;\n const next: NormalizedUsage = { source: 'provider' };\n if (usage.inputTokens !== undefined) next.inputTokens = usage.inputTokens;\n if (usage.outputTokens !== undefined) next.outputTokens = usage.outputTokens;\n if (usage.cacheReadTokens !== undefined) next.cacheReadTokens = usage.cacheReadTokens;\n if (usage.cacheCreationTokens !== undefined) next.cacheCreationTokens = usage.cacheCreationTokens;\n return next;\n}\n\nexport interface BeginExecutionInput {\n purpose: ExecutionPurpose;\n attempt?: number;\n trigger?: ExecutionTrigger;\n triggerReason?: ExecutionRecord['triggerReason'];\n harness: string;\n provider?: string | null;\n harnessVersion?: string | null;\n modelRequested?: string | null;\n modelResolved?: string | null;\n modelSource?: ExecutionRecord['agent']['model']['source'];\n iteration?: number;\n correctionCycle?: number;\n storyIds?: string[];\n routingDecision?: ExecutionRecord['routingDecision'];\n}\n\nexport async function beginExecution(input: BeginExecutionInput): Promise<string | null> {\n const ctx = context;\n if (ctx === null) return null;\n const cfg = await resolveConfig(ctx);\n if (!cfg.enabled) return null;\n\n const id = randomUUID();\n const record: ExecutionRecord = {\n id,\n sessionId: ctx.sessionId ?? getTelemetrySessionId(),\n purpose: input.purpose,\n attempt: input.attempt ?? 1,\n trigger: input.trigger ?? 'initial',\n triggerReason: input.triggerReason ?? null,\n agent: {\n harness: input.harness,\n provider: input.provider ?? null,\n harnessVersion: input.harnessVersion ?? null,\n model: {\n requested: input.modelRequested ?? null,\n resolved: input.modelResolved ?? null,\n source: input.modelSource ?? (input.modelResolved ? 'provider' : 'unavailable'),\n },\n providerSessionId: null,\n },\n startedAt: isoNow(),\n finishedAt: null,\n durationMs: null,\n usage: null,\n cost: { status: 'unknown', reason: 'not_reported' },\n status: 'running',\n failure: null,\n owner: { pid: process.pid, host: hostname() },\n ...(input.iteration === undefined ? {} : { iteration: input.iteration }),\n ...(input.correctionCycle === undefined ? {} : { correctionCycle: input.correctionCycle }),\n ...(input.storyIds === undefined ? {} : { storyIds: input.storyIds }),\n ...(input.routingDecision === undefined || input.routingDecision === null\n ? {}\n : { routingDecision: input.routingDecision }),\n };\n\n try {\n await mutate(ctx.tasksPath, (plan) => ({\n ...plan,\n executions: cap([...(plan.executions ?? []), record], cfg.maxExecutions),\n }));\n const { getSessionPublisher } = await import('../core/session-publisher.js');\n getSessionPublisher().publish({\n type: 'execution:update',\n at: record.startedAt,\n execution: record,\n });\n return id;\n } catch {\n return null;\n }\n}\n\n/** Wall clock vs CLI envelope: startup the harness does not report. */\nexport function timingFromUsage(\n wallClockMs: number | null,\n usage: ClaudeUsage | null | undefined,\n): Pick<\n ExecutionRecord,\n 'cliDurationMs' | 'harnessStartupMs' | 'apiDurationMs' | 'ttftMs' | 'numTurns'\n> {\n const cli = usage?.cliDurationMs;\n const cliDurationMs = cli === undefined ? null : cli;\n const harnessStartupMs =\n wallClockMs !== null && cli !== undefined ? Math.max(0, wallClockMs - cli) : null;\n return {\n cliDurationMs,\n harnessStartupMs,\n apiDurationMs: usage?.apiDurationMs ?? null,\n ttftMs: usage?.ttftMs ?? null,\n numTurns: usage?.numTurns ?? null,\n };\n}\n\nexport async function attachVerdict(verdict: ExecutionRecord['verdict']): Promise<void> {\n const ctx = context;\n if (ctx === null || verdict == null) return;\n try {\n await mutate(ctx.tasksPath, (plan) => {\n const records = [...(plan.executions ?? [])];\n if (records.length === 0) return plan;\n const index = records.length - 1;\n const current = records[index];\n if (current === undefined) return plan;\n records[index] = { ...current, verdict };\n return { ...plan, executions: records };\n });\n } catch {\n // Observational: a failed write must never change the invocation outcome.\n }\n}\n\nexport interface EndExecutionInput {\n id: string;\n status?: ExecutionStatus;\n usage?: ClaudeUsage | null;\n reportedUsd?: number | null;\n error?: string | null;\n exitCode?: number | null;\n storyIds?: string[];\n cancelled?: boolean;\n timedOut?: boolean;\n modelResolved?: string | null;\n modelSource?: ExecutionRecord['agent']['model']['source'];\n harnessVersion?: string | null;\n providerSessionId?: string | null;\n stopReason?: StopReason | null;\n}\n\nexport async function endExecution(input: EndExecutionInput): Promise<void> {\n const ctx = context;\n if (ctx === null) return;\n const cfg = await resolveConfig(ctx);\n if (!cfg.enabled) return;\n\n const usage = usageFromClaude(input.usage);\n const timedOut = input.timedOut === true || /\\btimed out\\b/i.test(input.error ?? '');\n const cancelled = input.cancelled === true;\n let status: ExecutionStatus = input.status ?? 'completed';\n if (input.status === undefined) {\n if (cancelled) status = 'cancelled';\n else if (timedOut) status = 'timeout';\n else if (input.error) status = 'failed';\n }\n\n const failure =\n status === 'completed'\n ? null\n : {\n kind: classify({\n source: 'agent',\n stdout: input.error ?? '',\n exitCode: input.exitCode,\n timedOut,\n }).kind,\n message: redactFailureMessage(input.error ?? status),\n exitCode: input.exitCode ?? null,\n };\n\n const completed: { value: ExecutionRecord | null } = { value: null };\n try {\n await mutate(ctx.tasksPath, (plan) => {\n const records = [...(plan.executions ?? [])];\n const index = records.findIndex((record) => record.id === input.id);\n if (index === -1) return plan;\n const current = records[index];\n if (current === undefined) return plan;\n const started = Date.parse(current.startedAt);\n const finishedAt = isoNow();\n const modelResolved = input.modelResolved ?? current.agent.model.resolved;\n const modelKey = modelResolved ?? current.agent.model.requested;\n records[index] = {\n ...current,\n agent: {\n ...current.agent,\n harnessVersion: input.harnessVersion ?? current.agent.harnessVersion,\n providerSessionId: input.providerSessionId ?? current.agent.providerSessionId,\n model: {\n ...current.agent.model,\n resolved: modelResolved,\n source:\n input.modelSource ??\n (modelResolved\n ? current.agent.model.source === 'unavailable'\n ? 'provider'\n : current.agent.model.source\n : current.agent.model.source),\n },\n },\n finishedAt,\n durationMs: Number.isFinite(started) ? Math.max(0, Date.now() - started) : null,\n ...timingFromUsage(\n Number.isFinite(started) ? Math.max(0, Date.now() - started) : null,\n input.usage,\n ),\n usage,\n cost: resolveCost({\n reportedUsd: input.reportedUsd ?? input.usage?.costUsd,\n usage,\n modelKey,\n estimate: cfg.pricing.estimate,\n overrides: cfg.pricing.overrides,\n }),\n status,\n failure,\n owner: null,\n ...(input.storyIds === undefined ? {} : { storyIds: input.storyIds }),\n ...(input.stopReason === undefined ? {} : { stopReason: input.stopReason }),\n };\n completed.value = records[index] ?? null;\n return { ...plan, executions: records };\n });\n if (completed.value !== null) {\n const { getSessionPublisher } = await import('../core/session-publisher.js');\n getSessionPublisher().publish({\n type: 'execution:update',\n at: completed.value.finishedAt ?? isoNow(),\n execution: completed.value,\n });\n }\n } catch {\n // Observational: a failed write must never change the invocation outcome.\n }\n}\n\nexport async function recordInvocation<T>(\n input: BeginExecutionInput,\n invoke: () => Promise<T>,\n finish: (result: T) => EndExecutionInput,\n): Promise<T> {\n const id = await beginExecution(input);\n try {\n const result = await invoke();\n if (id !== null) {\n await endExecution({ ...finish(result), id });\n }\n return result;\n } catch (err) {\n if (id !== null) {\n await endExecution({\n id,\n status: 'failed',\n error: err instanceof Error ? err.message : String(err),\n });\n }\n throw err;\n }\n}\n","import { isoNow } from '../core/state-manager.js';\nimport type { CostRecord, NormalizedUsage, PricingSnapshot, TelemetryConfig } from './types.js';\n\nexport const PRICING_TABLE_VERSION = '2026-08-30';\n\ninterface PricingRow {\n inputPerMillion: number;\n outputPerMillion: number;\n cacheReadPerMillion?: number;\n cacheWritePerMillion?: number;\n}\n\n/** Microdollars-per-million would be more precise; dollars keep the snapshot readable. */\nconst TABLE: Record<string, PricingRow> = {\n 'claude-sonnet-4': {\n inputPerMillion: 3,\n outputPerMillion: 15,\n cacheReadPerMillion: 0.3,\n cacheWritePerMillion: 3.75,\n },\n 'claude-sonnet-4-5': {\n inputPerMillion: 3,\n outputPerMillion: 15,\n cacheReadPerMillion: 0.3,\n cacheWritePerMillion: 3.75,\n },\n 'claude-opus-4': {\n inputPerMillion: 15,\n outputPerMillion: 75,\n cacheReadPerMillion: 1.5,\n cacheWritePerMillion: 18.75,\n },\n 'gpt-5': { inputPerMillion: 1.25, outputPerMillion: 10 },\n 'gpt-5.1': { inputPerMillion: 1.25, outputPerMillion: 10 },\n};\n\n/** Aliases a harness accepts in place of a model id. */\nconst ALIASES: Record<string, string> = {\n sonnet: 'claude-sonnet-4-5',\n opus: 'claude-opus-4',\n};\n\n/**\n * Map a resolved model id onto a table key.\n *\n * What reaches here is whatever the harness reported: a dated snapshot\n * (`claude-sonnet-4-5-20250929`), a vendor-prefixed id\n * (`anthropic/claude-sonnet-4-5`) or a configured alias (`sonnet`). An exact\n * lookup misses all three, and the estimate silently degrades to `unknown`.\n * An override is always honoured under the key the user wrote.\n */\nexport function normalizeModelKey(modelKey: string): string {\n const lower = modelKey.trim().toLowerCase();\n const withoutVendor = lower.slice(lower.lastIndexOf('/') + 1);\n const withoutSnapshot = withoutVendor.replace(/-\\d{8}$/, '').replace(/-latest$/, '');\n return ALIASES[withoutSnapshot] ?? withoutSnapshot;\n}\n\nfunction rowFor(\n modelKey: string,\n overrides: TelemetryConfig['pricing']['overrides'],\n): PricingRow | null {\n const normalized = normalizeModelKey(modelKey);\n const override = overrides[modelKey] ?? overrides[normalized];\n const base = TABLE[modelKey] ?? TABLE[normalized];\n if (override === undefined && base === undefined) return null;\n return {\n inputPerMillion: override?.inputPerMillion ?? base?.inputPerMillion ?? 0,\n outputPerMillion: override?.outputPerMillion ?? base?.outputPerMillion ?? 0,\n cacheReadPerMillion: override?.cacheReadPerMillion ?? base?.cacheReadPerMillion,\n cacheWritePerMillion: override?.cacheWritePerMillion ?? base?.cacheWritePerMillion,\n };\n}\n\nfunction dollars(tokens: number | undefined, perMillion: number | undefined): number {\n if (tokens === undefined || perMillion === undefined) return 0;\n return (tokens * perMillion) / 1_000_000;\n}\n\nexport function resolveCost(options: {\n reportedUsd?: number | null;\n usage: NormalizedUsage | null;\n modelKey: string | null;\n estimate: boolean;\n overrides?: TelemetryConfig['pricing']['overrides'];\n}): CostRecord {\n if (options.reportedUsd !== undefined && options.reportedUsd !== null) {\n return { status: 'reported', amount: options.reportedUsd, currency: 'USD' };\n }\n if (!options.estimate) {\n return { status: 'unknown', reason: 'not_reported' };\n }\n if (options.modelKey === null || options.modelKey === '') {\n return { status: 'unknown', reason: 'unknown_model' };\n }\n const row = rowFor(options.modelKey, options.overrides ?? {});\n if (row === null) {\n return { status: 'unknown', reason: 'unknown_model' };\n }\n if (options.usage === null || options.usage.source === 'unavailable') {\n return { status: 'unknown', reason: 'not_reported' };\n }\n const amount =\n dollars(options.usage.inputTokens, row.inputPerMillion) +\n dollars(options.usage.outputTokens, row.outputPerMillion) +\n dollars(options.usage.cacheReadTokens, row.cacheReadPerMillion) +\n dollars(options.usage.cacheCreationTokens, row.cacheWritePerMillion);\n const pricing: PricingSnapshot = {\n tableVersion: PRICING_TABLE_VERSION,\n modelKey: options.modelKey,\n inputPerMillion: row.inputPerMillion,\n outputPerMillion: row.outputPerMillion,\n capturedAt: isoNow(),\n ...(row.cacheReadPerMillion === undefined\n ? {}\n : { cacheReadPerMillion: row.cacheReadPerMillion }),\n ...(row.cacheWritePerMillion === undefined\n ? {}\n : { cacheWritePerMillion: row.cacheWritePerMillion }),\n };\n return { status: 'estimated', amount, currency: 'USD', pricing };\n}\n\nexport function estimateCost(\n usage: NormalizedUsage,\n modelKey: string,\n overrides: TelemetryConfig['pricing']['overrides'] = {},\n): CostRecord {\n return resolveCost({ usage, modelKey, estimate: true, overrides });\n}\n","import type { FailureKind } from '../resilience/errors.js';\n\nexport const EXECUTION_PURPOSES = [\n 'analyze',\n 'generate',\n 'prd',\n 'plan',\n 'execute',\n 'review',\n 'pr',\n 'pr-review',\n 'verify',\n] as const;\n\nexport type ExecutionPurpose = (typeof EXECUTION_PURPOSES)[number];\n\nexport type ExecutionTrigger = 'initial' | 'retry' | 'fallback' | 'correction' | 'escalation';\n\nexport type ExecutionStatus =\n | 'running'\n | 'completed'\n | 'failed'\n | 'timeout'\n | 'cancelled'\n | 'interrupted';\n\nexport type StopReason =\n | 'completed'\n | 'failed'\n | 'timeout'\n | 'cancelled'\n | 'max_attempts'\n | 'max_cost'\n | 'max_duration';\n\nexport type VerdictStatus = 'passed' | 'failed' | 'unverified';\n\nexport interface NormalizedUsage {\n inputTokens?: number;\n outputTokens?: number;\n cacheReadTokens?: number;\n cacheCreationTokens?: number;\n reasoningTokens?: number;\n details?: Record<string, number>;\n source: 'provider' | 'unavailable';\n}\n\nexport interface PricingSnapshot {\n tableVersion: string;\n modelKey: string;\n inputPerMillion: number;\n outputPerMillion: number;\n cacheReadPerMillion?: number;\n cacheWritePerMillion?: number;\n capturedAt: string;\n}\n\nexport type CostRecord =\n | { status: 'reported'; amount: number; currency: 'USD' }\n | { status: 'estimated'; amount: number; currency: 'USD'; pricing: PricingSnapshot }\n | {\n status: 'unknown';\n reason: 'not_reported' | 'no_pricing' | 'unknown_model' | 'subscription' | 'zero_rated';\n };\n\nexport interface ExecutionAgent {\n harness: string;\n provider: string | null;\n harnessVersion?: string | null;\n model: {\n requested: string | null;\n resolved: string | null;\n source: 'provider' | 'config' | 'routing' | 'unavailable';\n };\n providerSessionId: string | null;\n}\n\nexport interface ExecutionOwner {\n pid: number;\n host: string;\n}\n\nexport interface ExecutionVerdict {\n status: VerdictStatus;\n level?: string | null;\n independence?: string | null;\n}\n\nexport interface RoutingDecision {\n selected: string | { harness: string; provider: string; model?: string | null; tier?: string };\n actual?: string | { harness: string; provider: string; model?: string | null; tier?: string };\n candidates?: unknown[];\n reasonCodes?: string[];\n [key: string]: unknown;\n}\n\nexport interface ExecutionRecord {\n id: string;\n sessionId: string | null;\n purpose: ExecutionPurpose;\n attempt: number;\n trigger: ExecutionTrigger;\n triggerReason: FailureKind | null;\n agent: ExecutionAgent;\n startedAt: string;\n finishedAt: string | null;\n durationMs: number | null;\n /** Envelope duration when the CLI reports it. */\n cliDurationMs?: number | null;\n /** wallClock − cliDuration: startup the CLI does not see. */\n harnessStartupMs?: number | null;\n /** Envelope `duration_api_ms` when reported. */\n apiDurationMs?: number | null;\n /** Time to first output, when reported. */\n ttftMs?: number | null;\n numTurns?: number | null;\n usage: NormalizedUsage | null;\n cost: CostRecord;\n status: ExecutionStatus;\n failure: {\n kind: FailureKind;\n message: string;\n exitCode: number | null;\n } | null;\n stopReason?: StopReason | null;\n iteration?: number;\n /** Correction cycle active when this invocation started; 0 is the initial pass. */\n correctionCycle?: number;\n storyIds?: string[];\n owner?: ExecutionOwner | null;\n routingDecision?: RoutingDecision | null;\n verdict?: ExecutionVerdict | null;\n}\n\nexport interface CostTotals {\n reported: number;\n estimated: number;\n unknownExecutions: number;\n}\n\nexport interface ExecutionSummary {\n count: number;\n discarded: number;\n byStatus: Partial<Record<ExecutionStatus, number>>;\n usage: {\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheCreationTokens: number;\n reasoningTokens: number;\n };\n totalCost: CostTotals;\n}\n\nexport interface TelemetryConfig {\n enabled: boolean;\n maxExecutions: number;\n pricing: {\n estimate: boolean;\n overrides: Record<string, Partial<PricingSnapshot>>;\n };\n}\n\nexport const DEFAULT_TELEMETRY_CONFIG: TelemetryConfig = {\n enabled: true,\n maxExecutions: 500,\n pricing: { estimate: false, overrides: {} },\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
NullPublisher
|
|
4
|
-
} from "./chunk-ROIIEVZH.js";
|
|
5
2
|
import {
|
|
6
3
|
getBaseBranch,
|
|
7
4
|
getCommitsSince,
|
|
@@ -12,10 +9,13 @@ import {
|
|
|
12
9
|
normalizeRemoteUrl,
|
|
13
10
|
run,
|
|
14
11
|
stripRemoteUrlCredentials
|
|
15
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-YVPZUN6X.js";
|
|
13
|
+
import {
|
|
14
|
+
NullPublisher
|
|
15
|
+
} from "./chunk-DUS5ZNKL.js";
|
|
16
16
|
import {
|
|
17
17
|
isoNow
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-SOM4QA6C.js";
|
|
19
19
|
|
|
20
20
|
// src/core/session-git.ts
|
|
21
21
|
async function listPullRequests(branch, options = {}) {
|
|
@@ -112,4 +112,4 @@ export {
|
|
|
112
112
|
listPullRequests,
|
|
113
113
|
publishGitState
|
|
114
114
|
};
|
|
115
|
-
//# sourceMappingURL=chunk-
|
|
115
|
+
//# sourceMappingURL=chunk-YUNBOUQH.js.map
|
|
@@ -201,7 +201,7 @@ function inferSource(command) {
|
|
|
201
201
|
}
|
|
202
202
|
function diagnoseCommandFailure(command, args, result) {
|
|
203
203
|
if (result.exitCode === 0) return;
|
|
204
|
-
void import("./diagnostics-
|
|
204
|
+
void import("./diagnostics-HTCWF7F4.js").then(({ writeDiagnostic }) => {
|
|
205
205
|
writeDiagnostic({
|
|
206
206
|
level: "warning",
|
|
207
207
|
message: `Command failed: ${basename(command)}`,
|
|
@@ -622,4 +622,4 @@ export {
|
|
|
622
622
|
committedStoryIds,
|
|
623
623
|
isWorkingTreeClean
|
|
624
624
|
};
|
|
625
|
-
//# sourceMappingURL=chunk-
|
|
625
|
+
//# sourceMappingURL=chunk-YVPZUN6X.js.map
|
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
listPullRequests
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-YUNBOUQH.js";
|
|
5
5
|
import {
|
|
6
6
|
publishPhaseMetrics,
|
|
7
7
|
resolvePolicyPlaceholders
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-HLAPOUEM.js";
|
|
9
9
|
import {
|
|
10
10
|
applyPlaceholders,
|
|
11
11
|
loadPrompt
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-7F7LGMVO.js";
|
|
13
13
|
import {
|
|
14
14
|
DEFAULT_HEADLESS_TIMEOUT_MS,
|
|
15
15
|
runHeadless
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-UK4E2FUA.js";
|
|
17
17
|
import {
|
|
18
18
|
loadPrReviewConfig
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-HY5HLFDU.js";
|
|
20
20
|
import {
|
|
21
21
|
resolveIssuePaths
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-DV7HUC4Z.js";
|
|
23
23
|
import {
|
|
24
24
|
getGlobalTimeout,
|
|
25
25
|
printError,
|
|
26
26
|
printInfo,
|
|
27
27
|
printSuccess,
|
|
28
28
|
printWarning
|
|
29
|
-
} from "./chunk-
|
|
30
|
-
import {
|
|
31
|
-
getSessionPublisher
|
|
32
|
-
} from "./chunk-ROIIEVZH.js";
|
|
29
|
+
} from "./chunk-XZUEFTUP.js";
|
|
33
30
|
import {
|
|
34
31
|
getCurrentBranch,
|
|
35
32
|
run
|
|
36
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-YVPZUN6X.js";
|
|
34
|
+
import {
|
|
35
|
+
getSessionPublisher
|
|
36
|
+
} from "./chunk-DUS5ZNKL.js";
|
|
37
37
|
import {
|
|
38
38
|
isoNow,
|
|
39
39
|
loadTaskPlan,
|
|
40
40
|
saveTaskPlan
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-SOM4QA6C.js";
|
|
42
42
|
import {
|
|
43
43
|
writeFileAtomic
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-3R27MJ5R.js";
|
|
45
45
|
|
|
46
46
|
// src/commands/pr-review.ts
|
|
47
47
|
import { join as join3 } from "path";
|
|
@@ -802,4 +802,4 @@ export {
|
|
|
802
802
|
exitCodeFor,
|
|
803
803
|
runPrReview
|
|
804
804
|
};
|
|
805
|
-
//# sourceMappingURL=chunk-
|
|
805
|
+
//# sourceMappingURL=chunk-Z5O2XBWA.js.map
|
package/dist/cli.js
CHANGED
|
@@ -12,27 +12,27 @@ import {
|
|
|
12
12
|
setRoutingCliOverrides,
|
|
13
13
|
setVerifyCliOverrides,
|
|
14
14
|
setWebCliOverrides
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-HY5HLFDU.js";
|
|
16
|
+
import "./chunk-DV7HUC4Z.js";
|
|
17
17
|
import {
|
|
18
18
|
printError,
|
|
19
19
|
setGlobalTimeout,
|
|
20
20
|
setInactivityTimeout,
|
|
21
21
|
setVerbose
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-FKWYD44M.js";
|
|
22
|
+
} from "./chunk-XZUEFTUP.js";
|
|
23
|
+
import "./chunk-QPGEFLMY.js";
|
|
25
24
|
import "./chunk-HAKDLR6N.js";
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-
|
|
28
|
-
import "./chunk-
|
|
29
|
-
import "./chunk-
|
|
30
|
-
import "./chunk-
|
|
25
|
+
import "./chunk-YVPZUN6X.js";
|
|
26
|
+
import "./chunk-DUS5ZNKL.js";
|
|
27
|
+
import "./chunk-YII4U7ZD.js";
|
|
28
|
+
import "./chunk-PPZ3K4YM.js";
|
|
29
|
+
import "./chunk-SOM4QA6C.js";
|
|
31
30
|
import {
|
|
32
31
|
isAgentProviderId
|
|
33
|
-
} from "./chunk-
|
|
34
|
-
import "./chunk-7Z4Y3VKM.js";
|
|
32
|
+
} from "./chunk-ICM463EO.js";
|
|
35
33
|
import "./chunk-XEYH6ZZI.js";
|
|
34
|
+
import "./chunk-P3LRUNC6.js";
|
|
35
|
+
import "./chunk-3R27MJ5R.js";
|
|
36
36
|
|
|
37
37
|
// src/cli.ts
|
|
38
38
|
import { Command, InvalidArgumentError, Option } from "commander";
|
|
@@ -353,8 +353,8 @@ withIssueOptions(
|
|
|
353
353
|
)
|
|
354
354
|
).action(
|
|
355
355
|
async (options) => {
|
|
356
|
-
const { loadIssuesConfig } = await import("./config-
|
|
357
|
-
const { runInit } = await import("./init-
|
|
356
|
+
const { loadIssuesConfig } = await import("./config-KGZUPAUP.js");
|
|
357
|
+
const { runInit } = await import("./init-PDVQDRS6.js");
|
|
358
358
|
const { preferredProvider } = await loadIssuesConfig();
|
|
359
359
|
const code = await runInit(preferredProvider, {
|
|
360
360
|
...options,
|
|
@@ -376,7 +376,7 @@ withGlobalOptions(
|
|
|
376
376
|
}
|
|
377
377
|
throw error;
|
|
378
378
|
}
|
|
379
|
-
const { runGenerate } = await import("./generate-
|
|
379
|
+
const { runGenerate } = await import("./generate-CX6KNHZS.js");
|
|
380
380
|
const code = await runGenerate(options.prompt, target);
|
|
381
381
|
process.exit(code);
|
|
382
382
|
});
|
|
@@ -419,7 +419,7 @@ withUserStoryNumberingOptions(
|
|
|
419
419
|
}
|
|
420
420
|
throw error;
|
|
421
421
|
}
|
|
422
|
-
const { runPipeline } = await import("./run-
|
|
422
|
+
const { runPipeline } = await import("./run-3MPORLF5.js");
|
|
423
423
|
const code = await runPipeline(
|
|
424
424
|
issues,
|
|
425
425
|
options.mode,
|
|
@@ -448,7 +448,7 @@ withIssueOptions(
|
|
|
448
448
|
program.command("resume").description("Resume an interrupted pipeline from the phase it stopped at").argument("[issue]", "Issue to resume. Omitted: the most recently attempted one").option("--all", "Resume every unfinished issue of this project, in order").option("--mode <mode>", "Execution mode: auto | manual", "auto")
|
|
449
449
|
)
|
|
450
450
|
).action(async (issue, options) => {
|
|
451
|
-
const { runResume } = await import("./resume-
|
|
451
|
+
const { runResume } = await import("./resume-VLWIE264.js");
|
|
452
452
|
const code = await runResume(issue, {
|
|
453
453
|
...options.all === void 0 ? {} : { all: options.all },
|
|
454
454
|
...options.mode === void 0 ? {} : { mode: options.mode }
|
|
@@ -458,7 +458,7 @@ withIssueOptions(
|
|
|
458
458
|
withGlobalOptions(
|
|
459
459
|
program.command("status").description("What is running right now, in which phase, and since when").argument("[issue]", "Restrict the report to one issue").option("--json", "Emit the assembled state as JSON")
|
|
460
460
|
).action(async (issue, options) => {
|
|
461
|
-
const { runStatus } = await import("./operations-
|
|
461
|
+
const { runStatus } = await import("./operations-CAKIT2BO.js");
|
|
462
462
|
process.exit(
|
|
463
463
|
await runStatus(issue, { ...options.json === void 0 ? {} : { json: options.json } })
|
|
464
464
|
);
|
|
@@ -467,7 +467,7 @@ withGlobalOptions(
|
|
|
467
467
|
program.command("usage").description("Aggregate execution telemetry from tasks.json").argument("[issue]", "Restrict the report to one issue").option("--issue <issue>", "Same as the positional argument").option("--since <date>", "Only executions started on or after this ISO date").option("--by <key>", "Group by harness, provider, model, purpose or status").option("--json", "Emit the assembled totals as JSON")
|
|
468
468
|
).action(
|
|
469
469
|
async (issue, options) => {
|
|
470
|
-
const { runUsage, USAGE_GROUP_KEYS } = await import("./usage-
|
|
470
|
+
const { runUsage, USAGE_GROUP_KEYS } = await import("./usage-U7QNGCPK.js");
|
|
471
471
|
const by = options.by;
|
|
472
472
|
if (by !== void 0 && !USAGE_GROUP_KEYS.includes(by)) {
|
|
473
473
|
printError("Must be one of: harness, provider, model, purpose, status.");
|
|
@@ -485,20 +485,20 @@ withGlobalOptions(
|
|
|
485
485
|
withGlobalOptions(
|
|
486
486
|
program.command("ps").description("Every issue-flow run active on this machine").option("--json", "Emit the listing as JSON").option("--watch", "Refresh the listing until interrupted")
|
|
487
487
|
).action(async (options) => {
|
|
488
|
-
const { runPs } = await import("./ps-
|
|
488
|
+
const { runPs } = await import("./ps-76L6ZAZL.js");
|
|
489
489
|
process.exit(await runPs(options));
|
|
490
490
|
});
|
|
491
491
|
withGlobalOptions(
|
|
492
492
|
program.command("runs").description("History of the runs of this project, with how each ended")
|
|
493
493
|
).action(async () => {
|
|
494
|
-
const { runRuns } = await import("./operations-
|
|
494
|
+
const { runRuns } = await import("./operations-CAKIT2BO.js");
|
|
495
495
|
process.exit(await runRuns());
|
|
496
496
|
});
|
|
497
497
|
withGlobalOptions(
|
|
498
498
|
program.command("logs").description("Read the execution journal (events.jsonl), filtered and readable").argument("[issue]", "Issue to read. Omitted: the most recently attempted one").option("--issue <issue>", "Same as the positional argument").option("--follow", "Keep reading as the journal grows").option("--tail <n>", "How many entries to show first (default 50)", parseInteger).option("--kind <kinds>", "Only these event types, comma separated (retry, phase:end, \u2026)")
|
|
499
499
|
).action(
|
|
500
500
|
async (issue, options) => {
|
|
501
|
-
const { runLogs } = await import("./operations-
|
|
501
|
+
const { runLogs } = await import("./operations-CAKIT2BO.js");
|
|
502
502
|
const kinds = options.kind === void 0 ? void 0 : options.kind.split(",").map((kind) => kind.trim()).filter((kind) => kind !== "");
|
|
503
503
|
process.exit(
|
|
504
504
|
await runLogs(issue ?? options.issue, {
|
|
@@ -512,13 +512,13 @@ withGlobalOptions(
|
|
|
512
512
|
withGlobalOptions(
|
|
513
513
|
program.command("pause").description("Ask the running pipeline to stop after writing a checkpoint")
|
|
514
514
|
).action(async () => {
|
|
515
|
-
const { runPause } = await import("./operations-
|
|
515
|
+
const { runPause } = await import("./operations-CAKIT2BO.js");
|
|
516
516
|
process.exit(await runPause());
|
|
517
517
|
});
|
|
518
518
|
withGlobalOptions(
|
|
519
519
|
program.command("cancel").description("Stop the run and mark the issue so a resume does not pick it up").argument("[issue]", "Issue to cancel. Omitted: the most recently attempted one")
|
|
520
520
|
).action(async (issue) => {
|
|
521
|
-
const { runCancel } = await import("./operations-
|
|
521
|
+
const { runCancel } = await import("./operations-CAKIT2BO.js");
|
|
522
522
|
process.exit(await runCancel(issue));
|
|
523
523
|
});
|
|
524
524
|
withIssueOptions(
|
|
@@ -526,7 +526,7 @@ withIssueOptions(
|
|
|
526
526
|
program.command("analyze").description("Analyze an issue with the configured agent").argument("<issue>", "Issue number")
|
|
527
527
|
)
|
|
528
528
|
).action(async (issue) => {
|
|
529
|
-
const { runAnalyze } = await import("./analyze-
|
|
529
|
+
const { runAnalyze } = await import("./analyze-6M3KEOX7.js");
|
|
530
530
|
const code = await runAnalyze(issue);
|
|
531
531
|
process.exit(code);
|
|
532
532
|
});
|
|
@@ -535,7 +535,7 @@ withIssueOptions(
|
|
|
535
535
|
program.command("prd").description("Generate a PRD from an analyzed issue with the configured agent").argument("<issue>", "Issue number")
|
|
536
536
|
)
|
|
537
537
|
).action(async (issue) => {
|
|
538
|
-
const { runPrd } = await import("./prd-
|
|
538
|
+
const { runPrd } = await import("./prd-ZNC4T5BS.js");
|
|
539
539
|
const code = await runPrd(issue);
|
|
540
540
|
process.exit(code);
|
|
541
541
|
});
|
|
@@ -556,7 +556,7 @@ withUserStoryNumberingOptions(
|
|
|
556
556
|
}
|
|
557
557
|
throw error;
|
|
558
558
|
}
|
|
559
|
-
const { runPlan } = await import("./plan-
|
|
559
|
+
const { runPlan } = await import("./plan-PRORGS3L.js");
|
|
560
560
|
const code = await runPlan(issue, void 0, numbering);
|
|
561
561
|
process.exit(code);
|
|
562
562
|
});
|
|
@@ -575,7 +575,7 @@ withWebOptions(
|
|
|
575
575
|
).action(
|
|
576
576
|
async (positionalMaxIter, options) => {
|
|
577
577
|
try {
|
|
578
|
-
const { runExecute } = await import("./execute-
|
|
578
|
+
const { runExecute } = await import("./execute-QL3ZQIAP.js");
|
|
579
579
|
const code = await runExecute(positionalMaxIter, options);
|
|
580
580
|
process.exit(code);
|
|
581
581
|
} catch (error) {
|
|
@@ -589,7 +589,7 @@ withIssueOptions(
|
|
|
589
589
|
program.command("review").description("Validate an issue resolution with the configured agent").argument("<issue>", "Issue number")
|
|
590
590
|
)
|
|
591
591
|
).action(async (issue) => {
|
|
592
|
-
const { runReview } = await import("./review-
|
|
592
|
+
const { runReview } = await import("./review-7CREJDKB.js");
|
|
593
593
|
const code = await runReview(issue);
|
|
594
594
|
process.exit(code);
|
|
595
595
|
});
|
|
@@ -598,7 +598,7 @@ withIssueOptions(
|
|
|
598
598
|
program.command("pr").description("Create a pull request with the configured agent").argument("<issue>", "Issue number")
|
|
599
599
|
)
|
|
600
600
|
).action(async (issue) => {
|
|
601
|
-
const { runPr } = await import("./pr-
|
|
601
|
+
const { runPr } = await import("./pr-27RMQI5F.js");
|
|
602
602
|
const code = await runPr(issue);
|
|
603
603
|
process.exit(code);
|
|
604
604
|
});
|
|
@@ -606,63 +606,71 @@ var webCommand = program.command("web").description("Manage the web monitoring s
|
|
|
606
606
|
webCommand.command("serve").description(
|
|
607
607
|
"Run the web monitor server in the foreground (internal \u2014 spawned detached by --web)"
|
|
608
608
|
).option("--port <n>", "Web server port (default: 3737)", parseInteger).option("--host <h>", "Web server host (default: 0.0.0.0)").option("--refresh <s>", "Suggested UI polling interval in seconds", parseInteger).action(async (options) => {
|
|
609
|
-
const { runWebServe } = await import("./web-
|
|
609
|
+
const { runWebServe } = await import("./web-HUNDHCJ4.js");
|
|
610
610
|
const code = await runWebServe(options);
|
|
611
611
|
if (code !== 0) {
|
|
612
612
|
process.exit(code);
|
|
613
613
|
}
|
|
614
614
|
});
|
|
615
615
|
webCommand.command("stop").description("Stop the running web monitor server").action(async () => {
|
|
616
|
-
const { runWebStop } = await import("./web-
|
|
616
|
+
const { runWebStop } = await import("./web-HUNDHCJ4.js");
|
|
617
617
|
const code = await runWebStop();
|
|
618
618
|
process.exit(code);
|
|
619
619
|
});
|
|
620
620
|
withGlobalOptions(
|
|
621
621
|
program.command("policy").description("Inspect the policies discovered in this repository and their provenance").option("--scope <dir>", "Resolve the policy for a subdirectory (monorepo)").option("--json", "Emit the resolved policy as JSON")
|
|
622
622
|
).action(async (options) => {
|
|
623
|
-
const { runPolicy } = await import("./policy-
|
|
623
|
+
const { runPolicy } = await import("./policy-WX6O2JID.js");
|
|
624
624
|
const code = await runPolicy(options);
|
|
625
625
|
process.exit(code);
|
|
626
626
|
});
|
|
627
627
|
var routingCommand = withGlobalOptions(
|
|
628
|
-
program.command("routing").description("Inspect
|
|
628
|
+
program.command("routing").description("Inspect and configure adaptive harness/model routing")
|
|
629
629
|
);
|
|
630
|
-
routingCommand.option("--json", "Emit the resolved routing config as JSON").action(async (
|
|
631
|
-
const { runRoutingInspect } = await import("./routing-
|
|
632
|
-
process.exit(await runRoutingInspect(
|
|
630
|
+
routingCommand.option("--json", "Emit the resolved routing config as JSON").action(async (_options, command) => {
|
|
631
|
+
const { runRoutingInspect } = await import("./routing-VCDYHSXA.js");
|
|
632
|
+
process.exit(await runRoutingInspect(command.opts()));
|
|
633
|
+
});
|
|
634
|
+
routingCommand.command("explain").description("Explain the resolved routing target for every phase").option("--json", "Emit JSON").action(async (_options, command) => {
|
|
635
|
+
const { runRoutingExplain } = await import("./routing-VCDYHSXA.js");
|
|
636
|
+
process.exit(await runRoutingExplain(command.optsWithGlobals()));
|
|
637
|
+
});
|
|
638
|
+
routingCommand.command("use").description("Enable an embedded routing policy").argument("<policy>", "Policy name (recommended)").option("--global", "Write ~/.issue-flow/config.json (default)").option("--project", "Write .issue-flow.json instead").action(async (policy, _options, command) => {
|
|
639
|
+
const { runRoutingUse } = await import("./routing-VCDYHSXA.js");
|
|
640
|
+
process.exit(await runRoutingUse(policy, command.optsWithGlobals()));
|
|
633
641
|
});
|
|
634
|
-
routingCommand.command("report").description("Shadow agreement between selected and actual harness").option("--issue <n>", "Issue number").option("--json", "Emit JSON").action(async (
|
|
635
|
-
const { runRoutingReport } = await import("./routing-
|
|
636
|
-
process.exit(await runRoutingReport(
|
|
642
|
+
routingCommand.command("report").description("Shadow agreement between selected and actual harness").option("--issue <n>", "Issue number").option("--json", "Emit JSON").action(async (_options, command) => {
|
|
643
|
+
const { runRoutingReport } = await import("./routing-VCDYHSXA.js");
|
|
644
|
+
process.exit(await runRoutingReport(command.optsWithGlobals()));
|
|
637
645
|
});
|
|
638
646
|
var conventionsCommand = withGlobalOptions(
|
|
639
647
|
program.command("conventions").description("Compute the repository Git convention (branch, commit, PR title)")
|
|
640
648
|
);
|
|
641
649
|
conventionsCommand.command("branch").description("Print the deterministic branch name for an issue").option("--issue <n>", "Issue number").option("--title <text>", "Issue title, when the issue cannot be resolved").option("--json", "Emit JSON").action(async (options) => {
|
|
642
|
-
const { runConventionsBranch } = await import("./conventions-
|
|
650
|
+
const { runConventionsBranch } = await import("./conventions-RYN7OXJN.js");
|
|
643
651
|
process.exit(await runConventionsBranch(options));
|
|
644
652
|
});
|
|
645
653
|
conventionsCommand.command("commit").description("Print a Conventional Commit message").requiredOption("--type <type>", "Change type (feat, fix, docs, \u2026)").option("--scope <scope>", "Optional scope").requiredOption("--subject <text>", "Commit subject").option("--issue <n>", "Issue number for the Refs trailer").option("--story <id>", "Story id (US-010)").option("--breaking <text>", "Breaking change description").option("--json", "Emit JSON").action(
|
|
646
654
|
async (options) => {
|
|
647
|
-
const { runConventionsCommit } = await import("./conventions-
|
|
655
|
+
const { runConventionsCommit } = await import("./conventions-RYN7OXJN.js");
|
|
648
656
|
process.exit(await runConventionsCommit(options));
|
|
649
657
|
}
|
|
650
658
|
);
|
|
651
659
|
conventionsCommand.command("pr-title").description("Print the Conventional Commit Pull Request title").option("--issue <n>", "Issue number").option("--title <text>", "Issue title, when the issue cannot be resolved").option("--json", "Emit JSON").action(async (options) => {
|
|
652
|
-
const { runConventionsPrTitle } = await import("./conventions-
|
|
660
|
+
const { runConventionsPrTitle } = await import("./conventions-RYN7OXJN.js");
|
|
653
661
|
process.exit(await runConventionsPrTitle(options));
|
|
654
662
|
});
|
|
655
663
|
var agentCommand = withGlobalOptions(
|
|
656
664
|
program.command("agent").description("Inspect the resolved agent and model for each phase").option("--json", "Emit the resolved agent configuration as JSON")
|
|
657
665
|
);
|
|
658
666
|
agentCommand.action(async (options) => {
|
|
659
|
-
const { runAgent } = await import("./agent-
|
|
667
|
+
const { runAgent } = await import("./agent-TB6W7PT7.js");
|
|
660
668
|
const code = await runAgent(options);
|
|
661
669
|
process.exit(code);
|
|
662
670
|
});
|
|
663
671
|
agentCommand.command("use").description("Write an agent preference to config.json or .issue-flow.json").argument("<provider>", "claude, codex, cursor or antigravity").option("--model <model>", "Model identifier for this preference").option("--global", "Write to ~/.issue-flow/config.json (default)").option("--project", "Write to .issue-flow.json in the repository").option("--phase <phase>", "Write only the override for this phase").action(
|
|
664
672
|
async (provider, options) => {
|
|
665
|
-
const { runAgentUse } = await import("./agent-
|
|
673
|
+
const { runAgentUse } = await import("./agent-TB6W7PT7.js");
|
|
666
674
|
const code = await runAgentUse(provider, options);
|
|
667
675
|
process.exit(code);
|
|
668
676
|
}
|
|
@@ -674,7 +682,7 @@ withGlobalOptions(
|
|
|
674
682
|
)
|
|
675
683
|
).action(
|
|
676
684
|
async (pr, options) => {
|
|
677
|
-
const { runPrReview } = await import("./pr-review-
|
|
685
|
+
const { runPrReview } = await import("./pr-review-VNESMAMT.js");
|
|
678
686
|
const code = await runPrReview(pr, options);
|
|
679
687
|
process.exit(code);
|
|
680
688
|
}
|
|
@@ -700,7 +708,7 @@ withGlobalOptions(
|
|
|
700
708
|
printError("Unknown bench mode. Use 'synthetic' or 'real'.");
|
|
701
709
|
process.exit(1);
|
|
702
710
|
}
|
|
703
|
-
const { runBench } = await import("./bench-
|
|
711
|
+
const { runBench } = await import("./bench-FM7I7EIV.js");
|
|
704
712
|
process.exit(
|
|
705
713
|
await runBench({
|
|
706
714
|
...options.mode === void 0 ? {} : { mode: options.mode },
|
|
@@ -718,13 +726,13 @@ withGlobalOptions(
|
|
|
718
726
|
}
|
|
719
727
|
);
|
|
720
728
|
program.action(async () => {
|
|
721
|
-
const { listLiveRuns } = await import("./registry-
|
|
729
|
+
const { listLiveRuns } = await import("./registry-XLHHYLTR.js");
|
|
722
730
|
const runs = await listLiveRuns();
|
|
723
731
|
if (runs.length === 0) {
|
|
724
732
|
program.help();
|
|
725
733
|
return;
|
|
726
734
|
}
|
|
727
|
-
const { runPs } = await import("./ps-
|
|
735
|
+
const { runPs } = await import("./ps-76L6ZAZL.js");
|
|
728
736
|
process.exit(await runPs());
|
|
729
737
|
});
|
|
730
738
|
program.parse();
|