issue-flow 0.7.7 → 0.8.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/{analyze-2RVGY5OK.js → analyze-RBNKXWL5.js} +6 -6
- package/dist/{chunk-6L2BPOE3.js → chunk-36ECROTC.js} +7 -7
- package/dist/{chunk-EOTULFWV.js → chunk-A4M6AKIK.js} +6 -6
- package/dist/{chunk-RUTDK6ZF.js → chunk-BASRRXAM.js} +2 -2
- package/dist/{chunk-WO6ERABE.js → chunk-BH7DYADV.js} +10 -1
- package/dist/chunk-BH7DYADV.js.map +1 -0
- package/dist/{chunk-JOK7VXRV.js → chunk-F52S6ZGF.js} +3 -3
- package/dist/{chunk-EYVXLRRD.js → chunk-HSGTZ3CT.js} +3 -3
- package/dist/{chunk-XPW46TI5.js → chunk-J3PJBZXJ.js} +3 -3
- package/dist/{chunk-6UTVPKNF.js → chunk-J4SICTAN.js} +7 -7
- package/dist/{chunk-KHTLN54U.js → chunk-JWZKV3CL.js} +2 -2
- package/dist/{chunk-3E6KASSE.js → chunk-MK43N4X3.js} +7 -7
- package/dist/{chunk-ZYBYMEWG.js → chunk-QO2MWMAZ.js} +2 -2
- package/dist/{chunk-OPIDR2DC.js → chunk-RQW5W4XC.js} +2 -2
- package/dist/{chunk-WGDLUPSF.js → chunk-TGP6WK65.js} +5 -5
- package/dist/{chunk-G37JNQKB.js → chunk-VPDWTZ3F.js} +2 -2
- package/dist/{chunk-6IOPYFUM.js → chunk-VSF2CR3G.js} +6 -6
- package/dist/cli.js +15 -15
- package/dist/{config-OAZG7KIK.js → config-R7O5YC65.js} +3 -3
- package/dist/execute-LU3HWA54.js +14 -0
- package/dist/{generate-BEJF3SVJ.js → generate-TGJQLGMV.js} +6 -6
- package/dist/init-WP7Z2LFQ.js +9 -0
- package/dist/plan-2MWMCKRY.js +16 -0
- package/dist/pr-XVQDEQ7B.js +16 -0
- package/dist/pr-review-VO6ZXAFM.js +16 -0
- package/dist/prd-FPZAHQEO.js +16 -0
- package/dist/review-AHALLMXO.js +14 -0
- package/dist/{run-SEB6F3W4.js → run-2CXVR3VZ.js} +16 -16
- package/dist/{web-3SBYL7QJ.js → web-JVPK2PIF.js} +4 -4
- package/package.json +1 -1
- package/web/CLAUDE.md +48 -0
- package/web/public/app.css +266 -0
- package/web/public/app.js +237 -0
- package/web/public/index.html +26 -0
- package/dist/chunk-WO6ERABE.js.map +0 -1
- package/dist/execute-AOEM52CD.js +0 -14
- package/dist/init-TBC3WI74.js +0 -9
- package/dist/plan-YDZYB2BO.js +0 -16
- package/dist/pr-SIXMJIZF.js +0 -16
- package/dist/pr-review-AY56ZPJR.js +0 -16
- package/dist/prd-MBSSBLGO.js +0 -16
- package/dist/review-2MDDHZ4X.js +0 -14
- /package/dist/{analyze-2RVGY5OK.js.map → analyze-RBNKXWL5.js.map} +0 -0
- /package/dist/{chunk-6L2BPOE3.js.map → chunk-36ECROTC.js.map} +0 -0
- /package/dist/{chunk-EOTULFWV.js.map → chunk-A4M6AKIK.js.map} +0 -0
- /package/dist/{chunk-RUTDK6ZF.js.map → chunk-BASRRXAM.js.map} +0 -0
- /package/dist/{chunk-JOK7VXRV.js.map → chunk-F52S6ZGF.js.map} +0 -0
- /package/dist/{chunk-EYVXLRRD.js.map → chunk-HSGTZ3CT.js.map} +0 -0
- /package/dist/{chunk-XPW46TI5.js.map → chunk-J3PJBZXJ.js.map} +0 -0
- /package/dist/{chunk-6UTVPKNF.js.map → chunk-J4SICTAN.js.map} +0 -0
- /package/dist/{chunk-KHTLN54U.js.map → chunk-JWZKV3CL.js.map} +0 -0
- /package/dist/{chunk-3E6KASSE.js.map → chunk-MK43N4X3.js.map} +0 -0
- /package/dist/{chunk-ZYBYMEWG.js.map → chunk-QO2MWMAZ.js.map} +0 -0
- /package/dist/{chunk-OPIDR2DC.js.map → chunk-RQW5W4XC.js.map} +0 -0
- /package/dist/{chunk-WGDLUPSF.js.map → chunk-TGP6WK65.js.map} +0 -0
- /package/dist/{chunk-G37JNQKB.js.map → chunk-VPDWTZ3F.js.map} +0 -0
- /package/dist/{chunk-6IOPYFUM.js.map → chunk-VSF2CR3G.js.map} +0 -0
- /package/dist/{config-OAZG7KIK.js.map → config-R7O5YC65.js.map} +0 -0
- /package/dist/{execute-AOEM52CD.js.map → execute-LU3HWA54.js.map} +0 -0
- /package/dist/{generate-BEJF3SVJ.js.map → generate-TGJQLGMV.js.map} +0 -0
- /package/dist/{init-TBC3WI74.js.map → init-WP7Z2LFQ.js.map} +0 -0
- /package/dist/{plan-YDZYB2BO.js.map → plan-2MWMCKRY.js.map} +0 -0
- /package/dist/{pr-SIXMJIZF.js.map → pr-XVQDEQ7B.js.map} +0 -0
- /package/dist/{pr-review-AY56ZPJR.js.map → pr-review-VO6ZXAFM.js.map} +0 -0
- /package/dist/{prd-MBSSBLGO.js.map → prd-FPZAHQEO.js.map} +0 -0
- /package/dist/{review-2MDDHZ4X.js.map → review-AHALLMXO.js.map} +0 -0
- /package/dist/{run-SEB6F3W4.js.map → run-2CXVR3VZ.js.map} +0 -0
- /package/dist/{web-3SBYL7QJ.js.map → web-JVPK2PIF.js.map} +0 -0
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
import {
|
|
3
3
|
issuePlaceholders,
|
|
4
4
|
resolveCommandIssue
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-HSGTZ3CT.js";
|
|
6
6
|
import {
|
|
7
7
|
runHeadless
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-JWZKV3CL.js";
|
|
9
9
|
import {
|
|
10
10
|
publishPhaseMetrics
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-QO2MWMAZ.js";
|
|
12
12
|
import {
|
|
13
13
|
applyPlaceholders,
|
|
14
14
|
loadPrompt
|
|
15
15
|
} from "./chunk-SLHZPB3C.js";
|
|
16
16
|
import {
|
|
17
17
|
resolveIssuePaths
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-BASRRXAM.js";
|
|
19
19
|
import {
|
|
20
20
|
getGlobalTimeout,
|
|
21
21
|
loadTaskPlan,
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
printInfo,
|
|
24
24
|
printSuccess,
|
|
25
25
|
saveTaskPlan
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-BH7DYADV.js";
|
|
27
27
|
|
|
28
28
|
// src/commands/analyze.ts
|
|
29
29
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
@@ -84,4 +84,4 @@ async function runAnalyze(issue, resolvedIssue) {
|
|
|
84
84
|
export {
|
|
85
85
|
runAnalyze
|
|
86
86
|
};
|
|
87
|
-
//# sourceMappingURL=analyze-
|
|
87
|
+
//# sourceMappingURL=analyze-RBNKXWL5.js.map
|
|
@@ -2,34 +2,34 @@
|
|
|
2
2
|
import {
|
|
3
3
|
readFileWithGrace,
|
|
4
4
|
runPhaseWithRetry
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-RQW5W4XC.js";
|
|
6
6
|
import {
|
|
7
7
|
issuePlaceholders,
|
|
8
8
|
resolveCommandIssue
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-HSGTZ3CT.js";
|
|
10
10
|
import {
|
|
11
11
|
isTransientFailure
|
|
12
12
|
} from "./chunk-HDV3YDTG.js";
|
|
13
13
|
import {
|
|
14
14
|
runHeadless
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-JWZKV3CL.js";
|
|
16
16
|
import {
|
|
17
17
|
publishPhaseMetrics
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-QO2MWMAZ.js";
|
|
19
19
|
import {
|
|
20
20
|
applyPlaceholders,
|
|
21
21
|
loadPrompt
|
|
22
22
|
} from "./chunk-SLHZPB3C.js";
|
|
23
23
|
import {
|
|
24
24
|
resolveIssuePaths
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-BASRRXAM.js";
|
|
26
26
|
import {
|
|
27
27
|
getGlobalTimeout,
|
|
28
28
|
loadTaskPlan,
|
|
29
29
|
printError,
|
|
30
30
|
printSuccess,
|
|
31
31
|
saveTaskPlan
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-BH7DYADV.js";
|
|
33
33
|
|
|
34
34
|
// src/commands/prd.ts
|
|
35
35
|
import { mkdir } from "fs/promises";
|
|
@@ -103,4 +103,4 @@ async function runPrd(issue, resolvedIssue) {
|
|
|
103
103
|
export {
|
|
104
104
|
runPrd
|
|
105
105
|
};
|
|
106
|
-
//# sourceMappingURL=chunk-
|
|
106
|
+
//# sourceMappingURL=chunk-36ECROTC.js.map
|
|
@@ -2,27 +2,27 @@
|
|
|
2
2
|
import {
|
|
3
3
|
issuePlaceholders,
|
|
4
4
|
resolveCommandIssue
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-HSGTZ3CT.js";
|
|
6
6
|
import {
|
|
7
7
|
runHeadless
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-JWZKV3CL.js";
|
|
9
9
|
import {
|
|
10
10
|
publishPhaseMetrics
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-QO2MWMAZ.js";
|
|
12
12
|
import {
|
|
13
13
|
applyPlaceholders,
|
|
14
14
|
loadPrompt
|
|
15
15
|
} from "./chunk-SLHZPB3C.js";
|
|
16
16
|
import {
|
|
17
17
|
resolveIssuePaths
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-BASRRXAM.js";
|
|
19
19
|
import {
|
|
20
20
|
getGlobalTimeout,
|
|
21
21
|
loadTaskPlan,
|
|
22
22
|
printError,
|
|
23
23
|
printSuccess,
|
|
24
24
|
saveTaskPlan
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-BH7DYADV.js";
|
|
26
26
|
|
|
27
27
|
// src/commands/review.ts
|
|
28
28
|
function parseReviewResult(output) {
|
|
@@ -107,4 +107,4 @@ async function runReview(issue, resolvedIssue) {
|
|
|
107
107
|
export {
|
|
108
108
|
runReview
|
|
109
109
|
};
|
|
110
|
-
//# sourceMappingURL=chunk-
|
|
110
|
+
//# sourceMappingURL=chunk-A4M6AKIK.js.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
printWarning,
|
|
8
8
|
webConfigSchema,
|
|
9
9
|
writeFileAtomic
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-BH7DYADV.js";
|
|
11
11
|
|
|
12
12
|
// src/config.ts
|
|
13
13
|
import { readFile as readFile2 } from "fs/promises";
|
|
@@ -795,4 +795,4 @@ export {
|
|
|
795
795
|
loadIssuesConfig,
|
|
796
796
|
loadPrReviewConfig
|
|
797
797
|
};
|
|
798
|
-
//# sourceMappingURL=chunk-
|
|
798
|
+
//# sourceMappingURL=chunk-BASRRXAM.js.map
|
|
@@ -138,6 +138,11 @@ var sessionStorySchema = z.object({
|
|
|
138
138
|
// image of userStorySchema, where the same two fields are plainly optional.
|
|
139
139
|
status: userStoryStatusSchema.default("backlog"),
|
|
140
140
|
dependencies: z.array(z.string()).default([]),
|
|
141
|
+
// Published for the panel's story detail view. Same tolerant default as the
|
|
142
|
+
// fields above: absent (older session.json) and empty resolve to the same
|
|
143
|
+
// value, so the client never has to tell them apart.
|
|
144
|
+
description: z.string().default(""),
|
|
145
|
+
acceptanceCriteria: z.array(z.string()).default([]),
|
|
141
146
|
...sessionUsageShape
|
|
142
147
|
});
|
|
143
148
|
var sessionSnapshotSchema = z.object({
|
|
@@ -502,6 +507,10 @@ function applyEvent(snapshot, event, options) {
|
|
|
502
507
|
// value survives just for 'in_review', which no derivation produces.
|
|
503
508
|
status: story.status ?? before?.status ?? "backlog",
|
|
504
509
|
dependencies: story.dependencies ?? [],
|
|
510
|
+
// Required on UserStory, so the plan is always the source — no
|
|
511
|
+
// carry-over from `before` the way the accumulated fields need.
|
|
512
|
+
description: story.description,
|
|
513
|
+
acceptanceCriteria: story.acceptanceCriteria,
|
|
505
514
|
durationSeconds: before?.durationSeconds ?? null,
|
|
506
515
|
inputTokens: before?.inputTokens ?? null,
|
|
507
516
|
outputTokens: before?.outputTokens ?? null,
|
|
@@ -1213,4 +1222,4 @@ export {
|
|
|
1213
1222
|
formatDuration,
|
|
1214
1223
|
ElapsedTimer
|
|
1215
1224
|
};
|
|
1216
|
-
//# sourceMappingURL=chunk-
|
|
1225
|
+
//# sourceMappingURL=chunk-BH7DYADV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schemas.ts","../src/core/session-state.ts","../src/core/session-publisher.ts","../src/core/state-manager.ts","../src/utils/fs.ts","../src/core/metrics.ts","../src/core/verbose.ts","../src/ui/logger.ts"],"sourcesContent":["import { z } from 'zod';\nimport type { ClaudeUsage } from './core/metrics.js';\nimport type { SessionSnapshot } from './core/session-state.js';\nimport type { IssueMetadata, IssuesConfig } from './issues/types.js';\n\n/**\n * Zod schemas for validating tasks.json structure, Issue metadata, headless\n * invocation outputs, the web monitoring session snapshot and the web\n * configuration.\n */\n\n/**\n * Token/cost metrics of a single `claude` invocation, mirroring ClaudeUsage in\n * src/core/metrics.ts. Every field is optional: the CLI only reports what it\n * knows, and an absent field means \"not reported\", never zero.\n */\nexport const claudeUsageSchema = z.object({\n inputTokens: z.number().optional(),\n outputTokens: z.number().optional(),\n cacheReadTokens: z.number().optional(),\n cacheCreationTokens: z.number().optional(),\n costUsd: z.number().optional(),\n}) satisfies z.ZodType<ClaudeUsage>;\n\nexport const userStoryStatusSchema = z.enum(['backlog', 'in_progress', 'in_review', 'done']);\n\n/**\n * The metrics fields are additive and optional: plans written before they\n * existed keep parsing, and nothing is filled in with artificial zeros.\n *\n * `status` and `dependencies` follow the same rule and are `.optional()` rather\n * than `.default()` on purpose: a legacy plan must not gain a `'backlog'` and an\n * empty array it never declared just because `saveTaskPlan` rewrote it.\n */\nexport const userStorySchema = z.object({\n id: z.string(),\n title: z.string(),\n description: z.string(),\n acceptanceCriteria: z.array(z.string()),\n priority: z.number().int().positive(),\n passes: z.boolean(),\n notes: z.string(),\n ...claudeUsageSchema.shape,\n durationSeconds: z.number().optional(),\n status: userStoryStatusSchema.optional(),\n dependencies: z.array(z.string()).optional(),\n});\n\nexport const pipelineStateSchema = z.object({\n analyzeCompleted: z.boolean().optional(),\n prdCompleted: z.boolean(),\n jsonCompleted: z.boolean(),\n executionCompleted: z.boolean(),\n reviewCompleted: z.boolean(),\n prCreated: z.boolean(),\n prReviewCompleted: z.boolean().optional(),\n});\n\n/**\n * Pull Request opened by the `pr` phase. Optional on the plan: plans written\n * before the field existed (and runs with `--no-branch`) simply omit it.\n */\nexport const pullRequestRefSchema = z.object({\n number: z.number().int().positive(),\n url: z.string(),\n headBranch: z.string(),\n createdAt: z.string(),\n});\n\nexport const prReviewRecommendationSchema = z.enum([\n 'APPROVE',\n 'APPROVE_WITH_SUGGESTIONS',\n 'REQUEST_CHANGES',\n]);\n\n/**\n * State of the opt-in `pr-review` phase. `enabled` and `rounds` carry defaults\n * so a partially written object still parses instead of invalidating the plan.\n */\nexport const prReviewStateSchema = z.object({\n enabled: z.boolean().default(false),\n pullRequestNumber: z.number().int().positive().optional(),\n rounds: z.number().int().min(0).default(0),\n lastRecommendation: prReviewRecommendationSchema.optional(),\n lastReviewedAt: z.string().optional(),\n});\n\nconst lastErrorSchema = z.object({\n category: z.string(),\n message: z.string(),\n at: z.string(),\n});\n\n/**\n * Persisted metadata for an Issue stored on disk (issues/<id>/metadata.json).\n * `satisfies` keeps this schema in lockstep with the IssueMetadata interface in\n * src/issues/types.ts — changing one without the other fails the typecheck.\n */\nexport const issueMetadataSchema = z.object({\n schemaVersion: z.literal(1),\n id: z.string().min(1),\n number: z.number().int().positive().nullable(),\n source: z.enum(['github', 'local']),\n title: z.string(),\n labels: z.array(z.string()),\n state: z.enum(['open', 'closed']),\n createdAt: z.string(),\n updatedAt: z.string(),\n contentHash: z.string(),\n remote: z\n .object({\n provider: z.enum(['github', 'local']),\n ref: z.string(),\n syncedAt: z.string(),\n syncedContentHash: z.string(),\n })\n .optional(),\n}) satisfies z.ZodType<IssueMetadata>;\n\n/**\n * tasks.json structure. Deliberately permissive: plans written by older\n * versions must keep loading, so `issueUrl` is optional (Issues with no remote\n * have no URL) and `issueNumber` accepts non-numeric local identifiers.\n */\nexport const taskPlanSchema = z.object({\n project: z.string(),\n issueNumber: z.union([z.number().int().positive(), z.string().min(1)]),\n issueUrl: z.string().optional().default(''),\n branchName: z.string(),\n noBranch: z.boolean().optional().default(false),\n description: z.string(),\n issueStatus: z.enum(['pending', 'in_progress', 'completed']),\n completedAt: z.string().nullable(),\n lastAttemptAt: z.string().nullable(),\n lastError: lastErrorSchema.nullable(),\n correctionCycle: z.number().int().min(0),\n maxCorrectionCycles: z.number().int().min(0),\n /**\n * Findings from the most recent failed review, verbatim. Non-null means the\n * issue has a pending correction even if every userStories[].passes is\n * already true — the execute phase must address these before the field is\n * cleared back to null. See core/engine.ts's early-return guards.\n */\n lastReviewFindings: z.string().nullable().optional().default(null),\n pipeline: pipelineStateSchema,\n pullRequest: pullRequestRefSchema.optional(),\n prReview: prReviewStateSchema.optional(),\n userStories: z.array(userStorySchema),\n});\n\nexport const headlessResultSchema = z.object({\n success: z.boolean(),\n result: z.string(),\n cost: claudeUsageSchema.nullable(),\n error: z.string().nullable(),\n});\n\nconst sessionLogEntrySchema = z.object({\n at: z.string(),\n level: z.enum(['info', 'warn', 'error']),\n message: z.string(),\n});\n\n/**\n * Usage counters attached to a phase or a story in the session snapshot.\n * Unlike claudeUsageSchema (a single invocation, optional fields), these are\n * always present and nullable: null means \"never reported\", not zero.\n *\n * They default to null on input so a session.json written before the metrics\n * existed still parses -- absent and null mean the same thing here, and the\n * parsed value keeps the `number | null` shape the snapshot interface declares.\n */\nconst sessionUsageShape = {\n inputTokens: z.number().nullable().default(null),\n outputTokens: z.number().nullable().default(null),\n cacheReadTokens: z.number().nullable().default(null),\n cacheCreationTokens: z.number().nullable().default(null),\n costUsd: z.number().nullable().default(null),\n};\n\nconst sessionPhaseSchema = z.object({\n name: z.string(),\n status: z.enum(['pending', 'running', 'completed', 'failed']),\n startedAt: z.string().nullable(),\n endedAt: z.string().nullable(),\n durationSeconds: z.number().nullable(),\n error: z.string().nullable(),\n ...sessionUsageShape,\n});\n\nconst sessionStorySchema = z.object({\n id: z.string(),\n title: z.string(),\n priority: z.number(),\n passes: z.boolean(),\n completedAt: z.string().nullable(),\n // Also introduced with the metrics, hence the same tolerant default.\n durationSeconds: z.number().nullable().default(null),\n // Snapshot fields are always present on output and defaulted on input, so a\n // session.json written before they existed still parses. This is the mirror\n // image of userStorySchema, where the same two fields are plainly optional.\n status: userStoryStatusSchema.default('backlog'),\n dependencies: z.array(z.string()).default([]),\n // Published for the panel's story detail view. Same tolerant default as the\n // fields above: absent (older session.json) and empty resolve to the same\n // value, so the client never has to tell them apart.\n description: z.string().default(''),\n acceptanceCriteria: z.array(z.string()).default([]),\n ...sessionUsageShape,\n});\n\n/**\n * Session snapshot served by the web monitoring mode (session.json and the\n * HTTP endpoint). `satisfies` keeps this schema in lockstep with the\n * SessionSnapshot interface in src/core/session-state.ts — changing one\n * without the other fails the typecheck.\n */\nexport const sessionSnapshotSchema = z.object({\n schemaVersion: z.literal(1),\n sessionId: z.string().nullable(),\n readOnly: z.literal(true),\n capabilities: z.array(z.string()),\n issue: z.object({\n number: z.number().nullable(),\n url: z.string().nullable(),\n // Additive: a session.json written before the Issue section was enriched\n // parses into the same \"not reported\" values createInitialSnapshot() uses.\n title: z.string().nullable().default(null),\n description: z.string().nullable().default(null),\n labels: z.array(z.string()).default([]),\n state: z.string().nullable().default(null),\n }),\n status: z.enum(['idle', 'running', 'completed', 'failed']),\n startedAt: z.string().nullable(),\n updatedAt: z.string().nullable(),\n endedAt: z.string().nullable(),\n elapsedSeconds: z.number().nullable(),\n estimatedRemainingSeconds: z.number().nullable(),\n progress: z.object({\n percent: z.number(),\n phasesCompleted: z.number(),\n phasesTotal: z.number(),\n storiesCompleted: z.number(),\n storiesTotal: z.number(),\n }),\n currentPhase: z.string().nullable(),\n currentActivity: z\n .object({\n story: z.string().nullable(),\n tool: z.string().nullable(),\n detail: z.string().nullable(),\n since: z.string(),\n })\n .nullable(),\n phases: z.array(sessionPhaseSchema),\n stories: z.array(sessionStorySchema),\n // The whole aggregate is additive: a snapshot from before it existed parses\n // into the same \"nothing reported\" object the reducer starts from.\n metrics: z\n .object({\n totalInputTokens: z.number().nullable().default(null),\n totalOutputTokens: z.number().nullable().default(null),\n totalCacheReadTokens: z.number().nullable().default(null),\n totalCacheCreationTokens: z.number().nullable().default(null),\n totalCostUsd: z.number().nullable().default(null),\n })\n .default({\n totalInputTokens: null,\n totalOutputTokens: null,\n totalCacheReadTokens: null,\n totalCacheCreationTokens: null,\n totalCostUsd: null,\n }),\n execution: z.object({\n iteration: z.number(),\n retries: z.number(),\n correctionCycle: z.number(),\n maxCorrectionCycles: z.number().nullable(),\n }),\n git: z.object({\n branch: z.string().nullable(),\n baseBranch: z.string().nullable(),\n commits: z.array(z.object({ hash: z.string(), subject: z.string() })),\n }),\n // Additive like the metrics aggregate: a session.json written before the\n // repository section existed parses into the same all-null object\n // createInitialSnapshot() starts from.\n repository: z\n .object({\n name: z.string().nullable().default(null),\n remoteUrl: z.string().nullable().default(null),\n branch: z.string().nullable().default(null),\n headCommit: z.string().nullable().default(null),\n root: z.string().nullable().default(null),\n })\n .default({ name: null, remoteUrl: null, branch: null, headCommit: null, root: null }),\n pullRequests: z.array(z.object({ number: z.number(), url: z.string(), title: z.string() })),\n logs: z.array(sessionLogEntrySchema),\n errors: z.array(sessionLogEntrySchema),\n warnings: z.array(sessionLogEntrySchema),\n lastError: z.object({ message: z.string(), at: z.string() }).nullable(),\n nextSteps: z.array(z.string()),\n environment: z.object({ node: z.string(), platform: z.string() }).nullable(),\n}) satisfies z.ZodType<SessionSnapshot>;\n\n/**\n * Resolved web monitoring configuration. Every field has a default, so\n * parsing a partial object (e.g. the `web` key of .issue-flow.json) fills in\n * the documented defaults.\n */\nexport const webConfigSchema = z.object({\n enabled: z.boolean().default(false),\n port: z.number().int().min(1).max(65535).default(3737),\n host: z.string().min(1).default('0.0.0.0'),\n refreshSeconds: z.number().positive().default(5),\n logLimit: z.number().int().positive().default(200),\n includeLogs: z.boolean().default(true),\n});\n\n/**\n * Resolved Issue provider configuration. Every field has a default that keeps\n * the GitHub-only behaviour, so parsing an empty object yields the exact\n * behaviour of releases without the provider layer.\n */\nexport const issuesConfigSchema = z.object({\n defaultGenerateTarget: z.enum(['github', 'local', 'both']).default('github'),\n preferredProvider: z.enum(['github', 'local']).default('github'),\n conflictPolicy: z.enum(['ask', 'prefer-local', 'prefer-github']).default('ask'),\n requireConfirmation: z.boolean().default(true),\n}) satisfies z.ZodType<IssuesConfig>;\n\n/**\n * Resolved `pr-review` configuration (the `prReview` key of .issue-flow.json).\n *\n * `publisher` selects the implementation `createPrReviewPublisher()` builds. v1\n * ships only the local one, so the enum has a single member on purpose: adding\n * a GitHub adapter is a new entry here plus a new factory, never a change to\n * the phase.\n */\nexport const prReviewConfigSchema = z.object({\n publisher: z.enum(['local']).default('local'),\n});\n\nexport type ValidatedTaskPlan = z.infer<typeof taskPlanSchema>;\nexport type ValidatedIssueMetadata = z.infer<typeof issueMetadataSchema>;\nexport type ValidatedHeadlessResult = z.infer<typeof headlessResultSchema>;\nexport type ValidatedSessionSnapshot = z.infer<typeof sessionSnapshotSchema>;\nexport type WebConfig = z.infer<typeof webConfigSchema>;\nexport type PrReviewConfig = z.infer<typeof prReviewConfigSchema>;\n","import { mkdir, rename, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { stripVTControlCharacters } from 'node:util';\nimport type { UserStory, UserStoryStatus } from '../types.js';\n\n/**\n * Session state publishing layer for the optional web monitoring mode.\n *\n * Instrumentation points call publish() with SessionEvents; a pure reducer\n * folds each event into an in-memory SessionSnapshot that any surface\n * (file, HTTP endpoint, future webhooks) can consume in a single format.\n *\n * Monitoring must never affect the pipeline: publish() is synchronous and\n * never throws, and all publisher I/O failures are swallowed after a\n * single warning.\n */\n\nexport type SessionLogLevel = 'info' | 'warn' | 'error';\nexport type SessionStatus = 'idle' | 'running' | 'completed' | 'failed';\nexport type SessionPhaseStatus = 'pending' | 'running' | 'completed' | 'failed';\n\n/** Default max entries retained in the logs ring buffer. */\nexport const DEFAULT_LOG_LIMIT = 200;\n\n/** Default minimum interval between FilePublisher disk writes. */\nexport const DEFAULT_THROTTLE_MS = 1000;\n\nexport type SessionEvent =\n | {\n type: 'session:start';\n at: string;\n sessionId: string;\n /** `null` for local identifiers that are not numbers. */\n issueNumber: number | null;\n issueUrl?: string;\n branch?: string;\n baseBranch?: string;\n phases: string[];\n environment?: SessionEnvironment;\n }\n | {\n /**\n * Structural data of the Issue being worked on, published once the\n * provider has resolved it. Merged over the `issue` section instead of\n * replacing it, so the number and the URL that came with `session:start`\n * survive an origin that reports neither.\n */\n type: 'issue:update';\n at: string;\n number: number | null;\n url?: string;\n title: string | null;\n /** Issue body, published whole — no truncation. */\n description: string | null;\n labels: string[];\n state: string | null;\n }\n | { type: 'phase:start'; at: string; phase: string }\n | { type: 'phase:end'; at: string; phase: string; success: boolean; error?: string }\n | { type: 'iteration:start'; at: string; iteration: number }\n | { type: 'iteration:end'; at: string; iteration: number }\n | { type: 'retry'; at: string; attempt: number; delaySeconds?: number; reason?: string }\n | { type: 'stories:update'; at: string; stories: UserStory[] }\n | { type: 'activity'; at: string; story?: string; tool?: string; detail?: string }\n | { type: 'log'; at: string; level: SessionLogLevel; message: string }\n | { type: 'correction:cycle'; at: string; cycle: number; maxCycles: number }\n | {\n type: 'metrics:update';\n at: string;\n /**\n * Where the metrics land:\n * - `phase`: the named phase plus the issue-wide aggregate;\n * - `iteration`: one execute-loop pass — same targets as `phase`;\n * - `story`: the story alone, never the phase nor the aggregate (the\n * iteration event of the same cycle already counted those tokens).\n */\n scope: 'phase' | 'iteration' | 'story';\n phase?: string;\n storyId?: string;\n iteration?: number;\n inputTokens?: number;\n outputTokens?: number;\n cacheReadTokens?: number;\n cacheCreationTokens?: number;\n costUsd?: number;\n durationSeconds?: number;\n }\n | {\n /**\n * One publication feeds both the `git` section (branch, base, commits)\n * and the `repository` section (identity and location). They come from\n * the same collection pass, so extending this event keeps `branch`\n * consistent across the two instead of racing a second event.\n *\n * Every field is optional: `undefined` means \"not collected in this\n * publication\" and leaves the snapshot untouched, while an explicit\n * `null` means \"collected and unavailable\" and is written as-is.\n */\n type: 'git:update';\n at: string;\n branch?: string;\n baseBranch?: string;\n commits?: SessionCommit[];\n pullRequests?: SessionPullRequest[];\n /** `owner/repo`, derived from the origin remote. */\n repositoryName?: string | null;\n remoteUrl?: string | null;\n headCommit?: string | null;\n repositoryRoot?: string | null;\n }\n | { type: 'session:end'; at: string; status: 'completed' | 'failed'; error?: string };\n\nexport interface SessionEnvironment {\n node: string;\n platform: string;\n}\n\nexport interface SessionLogEntry {\n at: string;\n level: SessionLogLevel;\n message: string;\n}\n\n/**\n * Token/cost counters attached to a phase or a story.\n *\n * `null` means \"never reported\" — the `claude` CLI does not always return\n * usage data, and a metric that was never observed must stay distinguishable\n * from an observed zero.\n */\nexport interface SessionUsageSnapshot {\n inputTokens: number | null;\n outputTokens: number | null;\n cacheReadTokens: number | null;\n cacheCreationTokens: number | null;\n costUsd: number | null;\n}\n\n/** Issue-wide totals, accumulated from phase- and iteration-scoped metrics. */\nexport interface SessionMetricsSnapshot {\n totalInputTokens: number | null;\n totalOutputTokens: number | null;\n totalCacheReadTokens: number | null;\n totalCacheCreationTokens: number | null;\n totalCostUsd: number | null;\n}\n\nexport interface SessionPhaseSnapshot extends SessionUsageSnapshot {\n name: string;\n status: SessionPhaseStatus;\n startedAt: string | null;\n endedAt: string | null;\n durationSeconds: number | null;\n error: string | null;\n}\n\nexport interface SessionStorySnapshot extends SessionUsageSnapshot {\n id: string;\n title: string;\n priority: number;\n passes: boolean;\n /**\n * When the story flipped to passing during this session; null for stories\n * that were already passing at session start (their duration is unknown).\n */\n completedAt: string | null;\n /** Wall-clock seconds attributed to the story, or null when unknown. */\n durationSeconds: number | null;\n /**\n * Board-style status, recomputed on every reduction by\n * {@link deriveStoryStatus}. Observational: the pipeline keeps deciding what\n * to execute from `passes`.\n */\n status: UserStoryStatus;\n /** IDs of the stories this one depends on, as declared in the plan. */\n dependencies: string[];\n /** The plan's description; empty string when the plan carries none. */\n description: string;\n /** The plan's acceptance criteria; empty when the plan carries none. */\n acceptanceCriteria: string[];\n}\n\nexport interface SessionActivity {\n story: string | null;\n tool: string | null;\n detail: string | null;\n since: string;\n}\n\nexport interface SessionCommit {\n hash: string;\n subject: string;\n}\n\nexport interface SessionPullRequest {\n number: number;\n url: string;\n title: string;\n}\n\n/**\n * The Issue under execution, as far as the session knows it.\n *\n * `number`/`url` come with `session:start`; the remaining fields arrive with\n * `issue:update`, once the provider has resolved the Issue. Everything is\n * nullable because a run may start before (or without) that resolution —\n * `null` means \"not reported\", never \"empty\".\n */\nexport interface SessionIssueSnapshot {\n number: number | null;\n url: string | null;\n title: string | null;\n /** Issue body in full; the consumer decides how to fold it. */\n description: string | null;\n labels: string[];\n /** Provider lifecycle state ('open' / 'closed' for the built-ins). */\n state: string | null;\n}\n\n/**\n * Where the run is happening: which repository, which checkout, which commit.\n *\n * Fed by `git:update` (see `publishGitState`). Every field is nullable because\n * each source is independent and failure-tolerant — no remote configured, a\n * repository with no commits yet or a missing git binary all show up as\n * `null` instead of failing the publication.\n */\nexport interface SessionRepositorySnapshot {\n /** `owner/repo`, derived from the origin remote; null without one. */\n name: string | null;\n remoteUrl: string | null;\n branch: string | null;\n /** Abbreviated hash of HEAD. */\n headCommit: string | null;\n /** Absolute path of the working directory the pipeline runs from. */\n root: string | null;\n}\n\nexport interface SessionSnapshot {\n schemaVersion: 1;\n sessionId: string | null;\n readOnly: true;\n capabilities: string[];\n issue: SessionIssueSnapshot;\n status: SessionStatus;\n startedAt: string | null;\n updatedAt: string | null;\n endedAt: string | null;\n elapsedSeconds: number | null;\n estimatedRemainingSeconds: number | null;\n progress: {\n percent: number;\n phasesCompleted: number;\n phasesTotal: number;\n storiesCompleted: number;\n storiesTotal: number;\n };\n currentPhase: string | null;\n currentActivity: SessionActivity | null;\n phases: SessionPhaseSnapshot[];\n stories: SessionStorySnapshot[];\n metrics: SessionMetricsSnapshot;\n execution: {\n iteration: number;\n retries: number;\n correctionCycle: number;\n maxCorrectionCycles: number | null;\n };\n git: { branch: string | null; baseBranch: string | null; commits: SessionCommit[] };\n repository: SessionRepositorySnapshot;\n pullRequests: SessionPullRequest[];\n logs: SessionLogEntry[];\n errors: SessionLogEntry[];\n warnings: SessionLogEntry[];\n lastError: { message: string; at: string } | null;\n nextSteps: string[];\n environment: SessionEnvironment | null;\n}\n\nexport interface SessionReducerOptions {\n /** Max entries retained in the logs ring buffer. */\n logLimit?: number;\n}\n\n/** Fresh, all-null usage counters for a new phase or story entry. */\nfunction emptyUsage(): SessionUsageSnapshot {\n return {\n inputTokens: null,\n outputTokens: null,\n cacheReadTokens: null,\n cacheCreationTokens: null,\n costUsd: null,\n };\n}\n\nfunction emptyMetrics(): SessionMetricsSnapshot {\n return {\n totalInputTokens: null,\n totalOutputTokens: null,\n totalCacheReadTokens: null,\n totalCacheCreationTokens: null,\n totalCostUsd: null,\n };\n}\n\nexport function createInitialSnapshot(): SessionSnapshot {\n return {\n schemaVersion: 1,\n sessionId: null,\n readOnly: true,\n capabilities: [],\n issue: { number: null, url: null, title: null, description: null, labels: [], state: null },\n status: 'idle',\n startedAt: null,\n updatedAt: null,\n endedAt: null,\n elapsedSeconds: null,\n estimatedRemainingSeconds: null,\n progress: {\n percent: 0,\n phasesCompleted: 0,\n phasesTotal: 0,\n storiesCompleted: 0,\n storiesTotal: 0,\n },\n currentPhase: null,\n currentActivity: null,\n phases: [],\n stories: [],\n metrics: emptyMetrics(),\n execution: { iteration: 0, retries: 0, correctionCycle: 0, maxCorrectionCycles: null },\n git: { branch: null, baseBranch: null, commits: [] },\n repository: { name: null, remoteUrl: null, branch: null, headCommit: null, root: null },\n pullRequests: [],\n logs: [],\n errors: [],\n warnings: [],\n lastError: null,\n nextSteps: [],\n environment: null,\n };\n}\n\ntype MetricsUpdateEvent = Extract<SessionEvent, { type: 'metrics:update' }>;\n\n/**\n * Add a reported delta to an accumulator. `undefined` means \"not reported\":\n * it leaves the accumulator untouched, so a metric the CLI never returned\n * stays null instead of collapsing to zero.\n */\nfunction accumulate(current: number | null, delta: number | undefined): number | null {\n return delta === undefined ? current : (current ?? 0) + delta;\n}\n\n/** Fold the event's token/cost fields into a phase or story entry. */\nfunction accumulateUsage<T extends SessionUsageSnapshot>(target: T, event: MetricsUpdateEvent): T {\n return {\n ...target,\n inputTokens: accumulate(target.inputTokens, event.inputTokens),\n outputTokens: accumulate(target.outputTokens, event.outputTokens),\n cacheReadTokens: accumulate(target.cacheReadTokens, event.cacheReadTokens),\n cacheCreationTokens: accumulate(target.cacheCreationTokens, event.cacheCreationTokens),\n costUsd: accumulate(target.costUsd, event.costUsd),\n };\n}\n\n/**\n * Pick between a reported value and the one already in the snapshot.\n * Unlike `??`, an explicitly reported `null` wins: only `undefined` — the\n * absence of the field on the event — keeps the previous value.\n */\nfunction reported<T>(value: T | undefined, previous: T): T {\n return value === undefined ? previous : value;\n}\n\n/**\n * Seconds between two ISO timestamps, or null when either is unparsable.\n */\nfunction secondsBetween(from: string | null, to: string): number | null {\n if (from === null) return null;\n const fromMs = Date.parse(from);\n const toMs = Date.parse(to);\n if (Number.isNaN(fromMs) || Number.isNaN(toMs)) return null;\n return Math.max(0, Math.round((toMs - fromMs) / 1000));\n}\n\nfunction computePercent(phasesCompleted: number, phasesTotal: number): number {\n if (phasesTotal === 0) return 0;\n return Math.round((phasesCompleted / phasesTotal) * 100);\n}\n\n/**\n * Estimated seconds until all stories pass: average duration of the stories\n * completed during this session × pending stories. Durations are the gaps\n * between consecutive completions (the first is measured from startedAt).\n * Published as null with fewer than two samples.\n */\nfunction estimateRemainingSeconds(snapshot: SessionSnapshot): number | null {\n const completions = snapshot.stories\n .map((story) => (story.completedAt === null ? Number.NaN : Date.parse(story.completedAt)))\n .filter((ms) => !Number.isNaN(ms))\n .sort((a, b) => a - b);\n if (completions.length < 2) return null;\n\n const startMs = snapshot.startedAt === null ? Number.NaN : Date.parse(snapshot.startedAt);\n const boundaries = Number.isNaN(startMs) ? completions : [startMs, ...completions];\n const durations: number[] = [];\n for (let i = 1; i < boundaries.length; i++) {\n durations.push(Math.max(0, boundaries[i] - boundaries[i - 1]));\n }\n if (durations.length === 0) return null;\n\n const averageMs = durations.reduce((sum, d) => sum + d, 0) / durations.length;\n const pending = snapshot.stories.filter((story) => !story.passes).length;\n return Math.round((averageMs * pending) / 1000);\n}\n\n/**\n * Remaining pipeline phases, in order. The phase list originates from the\n * session:start event, whose caller passes PIPELINE_PHASES (or\n * PIPELINE_PHASES_NO_BRANCH in --no-branch mode) from src/core/pipeline.ts.\n */\nfunction deriveNextSteps(snapshot: SessionSnapshot): string[] {\n if (snapshot.status === 'completed') return [];\n return snapshot.phases.filter((phase) => phase.status === 'pending').map((phase) => phase.name);\n}\n\n/**\n * Board status of a single story, in a fixed order that makes the derivation\n * idempotent — recomputing it over its own result yields the same value:\n *\n * 1. `passes: true` → `done` (execution is the only authority on completion);\n * 2. already `in_review` → kept, since nothing here can produce or clear it;\n * 3. the story owns the current activity → `in_progress`;\n * 4. otherwise → `backlog`.\n *\n * `in_review` is therefore never derived: it only enters through an explicit\n * `status` in tasks.json, and leaves when the story starts passing.\n */\nfunction deriveStoryStatus(\n story: SessionStorySnapshot,\n activeStory: string | null,\n): UserStoryStatus {\n if (story.passes) return 'done';\n if (story.status === 'in_review') return 'in_review';\n if (activeStory !== null && activeStory === story.id) return 'in_progress';\n return 'backlog';\n}\n\n/** Recompute every story's status; entries that do not change keep identity. */\nfunction deriveStoryStatuses(snapshot: SessionSnapshot): SessionStorySnapshot[] {\n const activeStory = snapshot.currentActivity?.story ?? null;\n return snapshot.stories.map((story) => {\n const status = deriveStoryStatus(story, activeStory);\n return status === story.status ? story : { ...story, status };\n });\n}\n\n/**\n * Fold a SessionEvent into a SessionSnapshot. Pure: never mutates the input\n * and performs no I/O. Unknown event types return the snapshot unchanged.\n *\n * errors/warnings are derived slices of the logs ring buffer, recomputed on\n * each reduction — they are never accumulated separately. The same applies\n * to estimatedRemainingSeconds, nextSteps and each story's status.\n */\nexport function reduceSessionEvent(\n snapshot: SessionSnapshot,\n event: SessionEvent,\n options?: SessionReducerOptions,\n): SessionSnapshot {\n const next = applyEvent(snapshot, event, options);\n if (next === snapshot) return snapshot;\n\n const elapsedSeconds = secondsBetween(next.startedAt, event.at) ?? next.elapsedSeconds;\n return {\n ...next,\n updatedAt: event.at,\n elapsedSeconds,\n stories: deriveStoryStatuses(next),\n estimatedRemainingSeconds: estimateRemainingSeconds(next),\n errors: next.logs.filter((entry) => entry.level === 'error'),\n warnings: next.logs.filter((entry) => entry.level === 'warn'),\n nextSteps: deriveNextSteps(next),\n };\n}\n\nfunction applyEvent(\n snapshot: SessionSnapshot,\n event: SessionEvent,\n options?: SessionReducerOptions,\n): SessionSnapshot {\n switch (event.type) {\n case 'session:start': {\n const initial = createInitialSnapshot();\n return {\n ...initial,\n sessionId: event.sessionId,\n issue: { ...initial.issue, number: event.issueNumber, url: event.issueUrl ?? null },\n status: 'running',\n startedAt: event.at,\n progress: {\n ...initial.progress,\n phasesTotal: event.phases.length,\n },\n phases: event.phases.map((name) => ({\n name,\n status: 'pending' as const,\n startedAt: null,\n endedAt: null,\n durationSeconds: null,\n error: null,\n ...emptyUsage(),\n })),\n git: { branch: event.branch ?? null, baseBranch: event.baseBranch ?? null, commits: [] },\n // The branch is the one piece of repository identity the session\n // already knows here; the rest waits for publishGitState. Seeding it\n // keeps git.branch and repository.branch consistent for a poll that\n // lands before the first git:update.\n repository: { ...initial.repository, branch: event.branch ?? null },\n environment: event.environment ?? null,\n };\n }\n\n case 'issue:update':\n return {\n ...snapshot,\n issue: {\n ...snapshot.issue,\n // Merge, not replacement: the run may know a number and a URL that\n // the provider does not report (a local Issue mirroring a remote\n // one), and enriching the section must never erase them.\n number: event.number ?? snapshot.issue.number,\n url: event.url ?? snapshot.issue.url,\n title: event.title,\n description: event.description,\n labels: event.labels,\n state: event.state,\n },\n };\n\n case 'phase:start': {\n const known = snapshot.phases.some((p) => p.name === event.phase);\n const phases = known\n ? snapshot.phases.map((p) =>\n p.name === event.phase\n ? {\n ...p,\n status: 'running' as const,\n startedAt: event.at,\n endedAt: null,\n error: null,\n }\n : p,\n )\n : [\n ...snapshot.phases,\n {\n name: event.phase,\n status: 'running' as const,\n startedAt: event.at,\n endedAt: null,\n durationSeconds: null,\n error: null,\n ...emptyUsage(),\n },\n ];\n return {\n ...snapshot,\n currentPhase: event.phase,\n phases,\n progress: known ? snapshot.progress : { ...snapshot.progress, phasesTotal: phases.length },\n };\n }\n\n case 'phase:end': {\n const phases = snapshot.phases.map((p) =>\n p.name === event.phase\n ? {\n ...p,\n status: event.success ? ('completed' as const) : ('failed' as const),\n endedAt: event.at,\n durationSeconds: secondsBetween(p.startedAt, event.at),\n error: event.error ? stripVTControlCharacters(event.error) : null,\n }\n : p,\n );\n const phasesCompleted = phases.filter((p) => p.status === 'completed').length;\n return {\n ...snapshot,\n currentPhase: snapshot.currentPhase === event.phase ? null : snapshot.currentPhase,\n currentActivity: null,\n phases,\n progress: {\n ...snapshot.progress,\n phasesCompleted,\n percent: computePercent(phasesCompleted, snapshot.progress.phasesTotal),\n },\n };\n }\n\n case 'iteration:start':\n return {\n ...snapshot,\n execution: { ...snapshot.execution, iteration: event.iteration },\n };\n\n case 'iteration:end':\n return { ...snapshot, currentActivity: null };\n\n case 'retry':\n return {\n ...snapshot,\n execution: { ...snapshot.execution, retries: snapshot.execution.retries + 1 },\n };\n\n case 'stories:update': {\n const previous = new Map(snapshot.stories.map((story) => [story.id, story]));\n const stories = event.stories.map((story) => {\n const before = previous.get(story.id);\n // Stamp the flip to passing; stories already passing when first seen\n // keep null (completed before this session, duration unknown).\n const completedAt = !story.passes\n ? null\n : before && !before.passes\n ? event.at\n : (before?.completedAt ?? null);\n // stories:update rebuilds the array from the plan on every publish, so\n // metrics already attributed to a story must be carried over here or\n // the next update would wipe them.\n return {\n id: story.id,\n title: story.title,\n priority: story.priority,\n passes: story.passes,\n completedAt,\n // Seed only: deriveStoryStatus() recomputes it right after, so an\n // explicit 'done' in the plan on a story with passes: false is not\n // honoured — `passes` remains the single source of truth. The plan's\n // value survives just for 'in_review', which no derivation produces.\n status: story.status ?? before?.status ?? 'backlog',\n dependencies: story.dependencies ?? [],\n // Required on UserStory, so the plan is always the source — no\n // carry-over from `before` the way the accumulated fields need.\n description: story.description,\n acceptanceCriteria: story.acceptanceCriteria,\n durationSeconds: before?.durationSeconds ?? null,\n inputTokens: before?.inputTokens ?? null,\n outputTokens: before?.outputTokens ?? null,\n cacheReadTokens: before?.cacheReadTokens ?? null,\n cacheCreationTokens: before?.cacheCreationTokens ?? null,\n costUsd: before?.costUsd ?? null,\n };\n });\n return {\n ...snapshot,\n stories,\n progress: {\n ...snapshot.progress,\n storiesCompleted: stories.filter((s) => s.passes).length,\n storiesTotal: stories.length,\n },\n };\n }\n\n case 'activity': {\n const story = event.story ?? null;\n const tool = event.tool ?? null;\n const detail = event.detail ?? null;\n const current = snapshot.currentActivity;\n // Same activity repeated: keep `since` so the UI can show \"for how long\".\n const since =\n current && current.story === story && current.tool === tool && current.detail === detail\n ? current.since\n : event.at;\n return { ...snapshot, currentActivity: { story, tool, detail, since } };\n }\n\n case 'log': {\n const limit = options?.logLimit ?? DEFAULT_LOG_LIMIT;\n const entry: SessionLogEntry = {\n at: event.at,\n level: event.level,\n message: stripVTControlCharacters(event.message),\n };\n const logs = [...snapshot.logs, entry].slice(-Math.max(1, limit));\n return { ...snapshot, logs };\n }\n\n case 'git:update':\n return {\n ...snapshot,\n git: {\n branch: event.branch ?? snapshot.git.branch,\n baseBranch: event.baseBranch ?? snapshot.git.baseBranch,\n commits: event.commits ?? snapshot.git.commits,\n },\n repository: {\n // `undefined` is \"not collected\", so the previous value stands; an\n // explicit `null` is \"collected and unavailable\" and overwrites it.\n name: reported(event.repositoryName, snapshot.repository.name),\n remoteUrl: reported(event.remoteUrl, snapshot.repository.remoteUrl),\n branch: event.branch ?? snapshot.repository.branch,\n headCommit: reported(event.headCommit, snapshot.repository.headCommit),\n root: reported(event.repositoryRoot, snapshot.repository.root),\n },\n pullRequests: event.pullRequests ?? snapshot.pullRequests,\n };\n\n case 'correction:cycle':\n return {\n ...snapshot,\n execution: {\n ...snapshot.execution,\n correctionCycle: event.cycle,\n maxCorrectionCycles: event.maxCycles,\n },\n };\n\n case 'metrics:update': {\n if (event.scope === 'story') {\n // Story metrics are a rateio of the iteration that completed them;\n // the iteration-scoped event already fed the phase and the aggregate,\n // so counting them again here would double the totals.\n if (event.storyId === undefined) return snapshot;\n if (!snapshot.stories.some((s) => s.id === event.storyId)) return snapshot;\n return {\n ...snapshot,\n stories: snapshot.stories.map((story) =>\n story.id === event.storyId\n ? {\n ...accumulateUsage(story, event),\n durationSeconds: accumulate(story.durationSeconds, event.durationSeconds),\n }\n : story,\n ),\n };\n }\n\n // phase and iteration scopes both land on the named phase. An event for\n // a phase the snapshot never saw is ignored rather than appended: it\n // would show up as a phantom entry in the UI.\n if (event.phase === undefined) return snapshot;\n if (!snapshot.phases.some((p) => p.name === event.phase)) return snapshot;\n return {\n ...snapshot,\n // durationSeconds is deliberately untouched here: phase:start and\n // phase:end remain the single source of a phase's wall-clock time.\n phases: snapshot.phases.map((phase) =>\n phase.name === event.phase ? accumulateUsage(phase, event) : phase,\n ),\n metrics: {\n totalInputTokens: accumulate(snapshot.metrics.totalInputTokens, event.inputTokens),\n totalOutputTokens: accumulate(snapshot.metrics.totalOutputTokens, event.outputTokens),\n totalCacheReadTokens: accumulate(\n snapshot.metrics.totalCacheReadTokens,\n event.cacheReadTokens,\n ),\n totalCacheCreationTokens: accumulate(\n snapshot.metrics.totalCacheCreationTokens,\n event.cacheCreationTokens,\n ),\n totalCostUsd: accumulate(snapshot.metrics.totalCostUsd, event.costUsd),\n },\n };\n }\n\n case 'session:end':\n return {\n ...snapshot,\n status: event.status,\n endedAt: event.at,\n currentPhase: null,\n currentActivity: null,\n lastError: event.error\n ? { message: stripVTControlCharacters(event.error), at: event.at }\n : snapshot.lastError,\n };\n\n default:\n return snapshot;\n }\n}\n\nexport interface SessionPublisher {\n /**\n * Publish an event. Synchronous, never throws, never returns a promise —\n * safe to call from any instrumentation point without affecting execution.\n */\n publish(event: SessionEvent): void;\n /** Current in-memory snapshot. */\n snapshot(): SessionSnapshot;\n /** Monotonic counter, bumped on every applied event (basis for ETags). */\n version(): number;\n /** Force any pending output to be written. Never rejects. */\n flush(): Promise<void>;\n /** Flush and release resources. Never rejects. */\n close(): Promise<void>;\n}\n\n/**\n * Default publisher when monitoring is off: every call is a no-op, so each\n * instrumentation point costs a method call that returns immediately.\n */\nexport class NullPublisher implements SessionPublisher {\n private readonly empty = createInitialSnapshot();\n\n publish(_event: SessionEvent): void {}\n\n snapshot(): SessionSnapshot {\n return this.empty;\n }\n\n version(): number {\n return 0;\n }\n\n async flush(): Promise<void> {}\n\n async close(): Promise<void> {}\n}\n\nexport interface MemoryPublisherOptions extends SessionReducerOptions {\n /** Called at most once, on the first internal failure. */\n onWarn?: (message: string) => void;\n /**\n * When false, log events are dropped before reaching the snapshot, so no\n * log line is ever published (session.json or HTTP). Default true.\n */\n includeLogs?: boolean;\n}\n\n/**\n * In-memory publisher: reduces events over a snapshot and tracks a monotonic\n * version. Base class for publishers with an output surface (file, HTTP).\n */\nexport class MemoryPublisher implements SessionPublisher {\n protected state: SessionSnapshot = createInitialSnapshot();\n protected versionCounter = 0;\n private warned = false;\n private readonly onWarn: (message: string) => void;\n private readonly reducerOptions: SessionReducerOptions;\n private readonly includeLogs: boolean;\n\n constructor(options: MemoryPublisherOptions = {}) {\n this.onWarn = options.onWarn ?? ((message) => process.stderr.write(`${message}\\n`));\n this.reducerOptions = { logLimit: options.logLimit };\n this.includeLogs = options.includeLogs ?? true;\n }\n\n publish(event: SessionEvent): void {\n if (event.type === 'log' && !this.includeLogs) return;\n try {\n this.state = reduceSessionEvent(this.state, event, this.reducerOptions);\n this.versionCounter++;\n this.afterPublish(event);\n } catch (err) {\n this.warnOnce(err);\n }\n }\n\n /** Hook for subclasses; runs inside publish()'s try/catch. */\n protected afterPublish(_event: SessionEvent): void {}\n\n snapshot(): SessionSnapshot {\n return this.state;\n }\n\n version(): number {\n return this.versionCounter;\n }\n\n async flush(): Promise<void> {}\n\n async close(): Promise<void> {}\n\n protected warnOnce(err: unknown): void {\n if (this.warned) return;\n this.warned = true;\n const message = err instanceof Error ? err.message : String(err);\n try {\n this.onWarn(\n `issue-flow: web monitoring hit an error (will keep retrying silently): ${message}`,\n );\n } catch {\n // Even a failing warn callback must not propagate to the pipeline.\n }\n }\n}\n\nexport interface FilePublisherOptions extends MemoryPublisherOptions {\n /** Minimum interval between disk writes (ms). Default 1000. */\n throttleMs?: number;\n}\n\n/**\n * Publisher that mirrors the snapshot to issues/N/session.json.\n *\n * Writes are atomic (write-to-temp + rename) and throttled; terminal events\n * (phase:end, session:end) force an immediate write. All I/O failures are\n * swallowed after a single warning.\n */\nexport class FilePublisher extends MemoryPublisher {\n private readonly filePath: string;\n private readonly throttleMs: number;\n private timer: NodeJS.Timeout | null = null;\n private lastWriteStartedAt = 0;\n private lastWrittenVersion = 0;\n private writeChain: Promise<void> = Promise.resolve();\n private closed = false;\n\n constructor(filePath: string, options: FilePublisherOptions = {}) {\n super(options);\n this.filePath = filePath;\n this.throttleMs = options.throttleMs ?? DEFAULT_THROTTLE_MS;\n }\n\n protected override afterPublish(event: SessionEvent): void {\n if (this.closed) return;\n const terminal = event.type === 'phase:end' || event.type === 'session:end';\n this.scheduleWrite(terminal);\n }\n\n private scheduleWrite(force: boolean): void {\n if (force) {\n if (this.timer !== null) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n this.enqueueWrite();\n return;\n }\n if (this.timer !== null) return;\n const wait = Math.max(0, this.throttleMs - (Date.now() - this.lastWriteStartedAt));\n if (wait === 0) {\n this.enqueueWrite();\n return;\n }\n this.timer = setTimeout(() => {\n this.timer = null;\n this.enqueueWrite();\n }, wait);\n this.timer.unref();\n }\n\n private enqueueWrite(): void {\n this.lastWriteStartedAt = Date.now();\n this.writeChain = this.writeChain.then(async () => {\n const version = this.versionCounter;\n if (version === this.lastWrittenVersion) return;\n const payload = `${JSON.stringify(this.state, null, 2)}\\n`;\n try {\n await atomicWriteFile(this.filePath, payload);\n this.lastWrittenVersion = version;\n } catch (err) {\n this.warnOnce(err);\n }\n });\n }\n\n override async flush(): Promise<void> {\n if (this.timer !== null) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n if (this.versionCounter !== this.lastWrittenVersion) {\n this.enqueueWrite();\n }\n await this.writeChain;\n }\n\n override async close(): Promise<void> {\n await this.flush();\n this.closed = true;\n }\n}\n\n/**\n * Atomic write: write to a temp file next to the target, then rename. The\n * same-directory temp keeps the rename on a single filesystem (rename is\n * atomic; no EXDEV fallback needed, unlike an os.tmpdir() temp on Linux\n * tmpfs) and leaves nothing behind. The FilePublisher write chain is the\n * single writer, so the fixed .tmp name never races.\n *\n * The target directory (issues/N/) may not exist yet the first time a fresh\n * issue publishes — pipeline phases create it lazily, and this can be the\n * very first write. mkdir recursive is idempotent, so it's cheap to ensure\n * on every write rather than relying on call order elsewhere.\n */\nasync function atomicWriteFile(path: string, content: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n const tmpFile = `${path}.tmp`;\n await writeFile(tmpFile, content, 'utf-8');\n await rename(tmpFile, path);\n}\n","import { NullPublisher, type SessionPublisher } from './session-state.js';\n\n/**\n * Global slot for the active SessionPublisher, following the same pattern as\n * setVerbose in verbose.ts. Instrumentation points (logger, engine, headless)\n * read the slot via getSessionPublisher(); run.ts installs a FilePublisher\n * when web monitoring is enabled. The default NullPublisher makes every\n * instrumentation point a no-op when monitoring is off.\n */\n\nconst NULL_PUBLISHER = new NullPublisher();\n\nlet _publisher: SessionPublisher = NULL_PUBLISHER;\n\n/**\n * Install the active session publisher. Pass undefined to reset to the\n * default NullPublisher.\n */\nexport function setSessionPublisher(publisher: SessionPublisher | undefined): void {\n _publisher = publisher ?? NULL_PUBLISHER;\n}\n\nexport function getSessionPublisher(): SessionPublisher {\n return _publisher;\n}\n","import { readFile } from 'node:fs/promises';\nimport { ZodError } from 'zod';\nimport { taskPlanSchema } from '../schemas.js';\nimport type { LastError, PipelineState, TaskPlan, UserStory } from '../types.js';\nimport { writeFileAtomic } from '../utils/fs.js';\nimport { type ClaudeUsage, sumUsage } from './metrics.js';\n\n/**\n * Get the current ISO timestamp.\n */\nexport function isoNow(): string {\n return new Date().toISOString().replace(/\\.\\d{3}Z$/, 'Z');\n}\n\n/**\n * Load and parse a tasks.json file.\n * Validates that it has the expected structure.\n */\nexport async function loadTaskPlan(path: string): Promise<TaskPlan> {\n const content = await readFile(path, 'utf-8');\n const raw = JSON.parse(content);\n\n try {\n return taskPlanSchema.parse(raw) as TaskPlan;\n } catch (err) {\n if (err instanceof ZodError) {\n const issues = err.issues.map((i) => ` - ${i.path.join('.')}: ${i.message}`).join('\\n');\n throw new Error(`Invalid tasks.json at ${path}:\\n${issues}`);\n }\n throw err;\n }\n}\n\n/**\n * Save a TaskPlan to disk atomically (write-to-temp + rename).\n * This prevents corruption if the process is interrupted during write.\n */\nexport async function saveTaskPlan(path: string, plan: TaskPlan): Promise<void> {\n await writeFileAtomic(path, `${JSON.stringify(plan, null, 2)}\\n`);\n}\n\n/**\n * Initialize default state fields on a TaskPlan.\n * Fills in missing fields with defaults, matching the Bash script behavior.\n *\n * The opt-in fields (`pullRequest`, `prReview`, `pipeline.prReviewCompleted`)\n * are deliberately absent from the defaults: they ride along on the spread when\n * present and stay out of the file entirely when the phases never ran.\n */\nexport function initializeState(plan: TaskPlan): TaskPlan {\n const defaultPipeline: PipelineState = {\n prdCompleted: false,\n jsonCompleted: false,\n executionCompleted: false,\n reviewCompleted: false,\n prCreated: false,\n };\n\n return {\n ...plan,\n issueStatus: plan.issueStatus ?? 'pending',\n completedAt: plan.completedAt ?? null,\n lastAttemptAt: plan.lastAttemptAt ?? null,\n lastError: plan.lastError ?? null,\n correctionCycle: plan.correctionCycle ?? 0,\n maxCorrectionCycles: plan.maxCorrectionCycles ?? 3,\n lastReviewFindings: plan.lastReviewFindings ?? null,\n pipeline: plan.pipeline ? { ...defaultPipeline, ...plan.pipeline } : defaultPipeline,\n };\n}\n\n/**\n * Whether the issue has a review failure that execute must still address,\n * even if every userStories[].passes is already true.\n */\nexport function hasPendingCorrection(plan: TaskPlan): boolean {\n return Boolean(plan.lastReviewFindings);\n}\n\n/**\n * Check if all user stories have passes=true.\n * Returns false if there are no stories.\n */\nexport function allStoriesPass(plan: TaskPlan): boolean {\n if (plan.userStories.length === 0) {\n return false;\n }\n\n return plan.userStories.every((story) => story.passes === true);\n}\n\n/**\n * Mark a specific story as passing.\n */\nexport function markStoryPassing(plan: TaskPlan, storyId: string): TaskPlan {\n return {\n ...plan,\n userStories: plan.userStories.map((story) =>\n story.id === storyId ? { ...story, passes: true } : story,\n ),\n };\n}\n\n/**\n * Accumulate a usage share (and duration) onto the given stories.\n *\n * Pure, like the rest of this module: returns a new plan and never touches the\n * input. Accumulation is summing and treats `undefined` as \"not reported\": a\n * field neither the story nor the share carries stays absent, so a plan written\n * by a CLI that reports no usage never gains artificial zeros.\n *\n * The share is what `divideUsage()` already split across the stories that\n * completed in the same execute iteration — see core/engine.ts.\n */\nexport function applyStoryMetrics(\n plan: TaskPlan,\n storyIds: string[],\n share: ClaudeUsage,\n durationSeconds?: number,\n): TaskPlan {\n if (storyIds.length === 0) return plan;\n\n const targets = new Set(storyIds);\n\n return {\n ...plan,\n userStories: plan.userStories.map((story) => {\n if (!targets.has(story.id)) return story;\n\n const updated: UserStory = { ...story, ...sumUsage(story, share) };\n if (story.durationSeconds !== undefined || durationSeconds !== undefined) {\n updated.durationSeconds = (story.durationSeconds ?? 0) + (durationSeconds ?? 0);\n }\n return updated;\n }),\n };\n}\n\n/**\n * Mark the issue as in_progress.\n */\nexport function markIssueInProgress(plan: TaskPlan, timestamp?: string): TaskPlan {\n const ts = timestamp ?? isoNow();\n return {\n ...plan,\n issueStatus: 'in_progress',\n completedAt: null,\n lastAttemptAt: ts,\n };\n}\n\n/**\n * Mark the issue as completed.\n */\nexport function markIssueCompleted(plan: TaskPlan): TaskPlan {\n const ts = isoNow();\n return {\n ...plan,\n issueStatus: 'completed',\n completedAt: ts,\n lastAttemptAt: ts,\n lastError: null,\n pipeline: plan.pipeline ? { ...plan.pipeline, executionCompleted: true } : plan.pipeline,\n };\n}\n\n/**\n * Set the lastError field on the task plan.\n */\nexport function setLastError(plan: TaskPlan, category: string, message: string): TaskPlan {\n const ts = isoNow();\n const error: LastError = {\n category,\n message,\n at: ts,\n };\n\n return {\n ...plan,\n lastAttemptAt: ts,\n lastError: error,\n };\n}\n\n/**\n * Clear the lastError field, but only if it was set before the attempt started.\n * This prevents clearing errors that were set during the current attempt.\n */\nexport function clearLastError(plan: TaskPlan, attemptStartedAt: string): TaskPlan {\n const ts = isoNow();\n\n // If the error was set after the attempt started, keep it\n if (plan.lastError && plan.lastError.at > attemptStartedAt) {\n return {\n ...plan,\n lastAttemptAt: ts,\n };\n }\n\n return {\n ...plan,\n lastAttemptAt: ts,\n lastError: null,\n };\n}\n\n/**\n * Trim an error message to at most 8 non-empty lines.\n */\nexport function trimErrorMessage(message: string): string {\n return message\n .split('\\n')\n .filter((line) => line.trim().length > 0)\n .slice(0, 8)\n .join('\\n');\n}\n","import { copyFile, mkdtemp, rename, unlink, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { basename, join } from 'node:path';\n\n/**\n * Write a file atomically (write-to-temp + rename).\n *\n * A crash mid-write leaves the previous content untouched instead of a\n * truncated file, which matters for every artifact the pipeline reloads on the\n * next run (tasks.json, metadata.json).\n */\nexport async function writeFileAtomic(path: string, content: string): Promise<void> {\n const tmpDir = await mkdtemp(join(tmpdir(), 'issue-flow-'));\n const tmpFile = join(tmpDir, basename(path));\n\n await writeFile(tmpFile, content, 'utf-8');\n\n try {\n await rename(tmpFile, path);\n } catch (err: unknown) {\n // EXDEV: rename fails across different devices/drives (common on Windows)\n if ((err as NodeJS.ErrnoException).code === 'EXDEV') {\n await copyFile(tmpFile, path);\n await unlink(tmpFile);\n } else {\n throw err;\n }\n }\n}\n","/**\n * Single source of truth for translating the `claude` CLI JSON output into\n * token/cost metrics.\n *\n * Three call sites consume this (headless json, headless stream-json and the\n * execute-phase executor); keeping the parsing here is what stops them from\n * diverging again the next time the CLI payload changes shape.\n */\n\nexport interface ClaudeUsage {\n inputTokens?: number;\n outputTokens?: number;\n cacheReadTokens?: number;\n cacheCreationTokens?: number;\n costUsd?: number;\n}\n\n/** Field names of {@link ClaudeUsage}, used by the summing helper. */\nconst USAGE_FIELDS = [\n 'inputTokens',\n 'outputTokens',\n 'cacheReadTokens',\n 'cacheCreationTokens',\n 'costUsd',\n] as const;\n\n/**\n * Coerce a value to a finite number, or undefined when it is absent/unusable.\n * Never throws — malformed payloads simply yield undefined.\n */\nfunction num(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Parse a `claude` CLI result payload into a {@link ClaudeUsage}.\n *\n * Reads the current format (`total_cost_usd` plus a nested `usage` object) and\n * falls back to the legacy flat keys (`cost_usd`, `num_input_tokens`,\n * `num_output_tokens`) when the newer ones are absent.\n *\n * Returns null when the payload carries no recognizable field at all, and a\n * partial object when only some fields are present. Never throws.\n */\nexport function parseUsage(payload: unknown): ClaudeUsage | null {\n if (!isRecord(payload)) return null;\n\n const usageRaw = isRecord(payload.usage) ? payload.usage : undefined;\n\n const usage: ClaudeUsage = {};\n\n const inputTokens = usageRaw ? num(usageRaw.input_tokens) : undefined;\n const outputTokens = usageRaw ? num(usageRaw.output_tokens) : undefined;\n const cacheReadTokens = usageRaw ? num(usageRaw.cache_read_input_tokens) : undefined;\n const cacheCreationTokens = usageRaw ? num(usageRaw.cache_creation_input_tokens) : undefined;\n const costUsd = num(payload.total_cost_usd);\n\n // Legacy fallbacks — only consulted when the modern key is missing.\n const legacyInput = num(payload.num_input_tokens);\n const legacyOutput = num(payload.num_output_tokens);\n const legacyCost = num(payload.cost_usd);\n\n const resolvedInput = inputTokens ?? legacyInput;\n const resolvedOutput = outputTokens ?? legacyOutput;\n const resolvedCost = costUsd ?? legacyCost;\n\n if (resolvedInput !== undefined) usage.inputTokens = resolvedInput;\n if (resolvedOutput !== undefined) usage.outputTokens = resolvedOutput;\n if (cacheReadTokens !== undefined) usage.cacheReadTokens = cacheReadTokens;\n if (cacheCreationTokens !== undefined) usage.cacheCreationTokens = cacheCreationTokens;\n if (resolvedCost !== undefined) usage.costUsd = resolvedCost;\n\n return Object.keys(usage).length > 0 ? usage : null;\n}\n\n/**\n * Sum two usages field by field.\n *\n * `undefined` means \"not reported\", not zero: a field absent on both sides\n * stays absent in the result, while a field present on a single side is\n * carried over untouched.\n */\nexport function sumUsage(\n a: ClaudeUsage | null | undefined,\n b: ClaudeUsage | null | undefined,\n): ClaudeUsage {\n const result: ClaudeUsage = {};\n\n for (const field of USAGE_FIELDS) {\n const left = a?.[field];\n const right = b?.[field];\n if (left === undefined && right === undefined) continue;\n result[field] = (left ?? 0) + (right ?? 0);\n }\n\n return result;\n}\n\n/**\n * Split a usage evenly across `parts`.\n *\n * This is the rateio used when several stories complete in the same execute\n * iteration: the iteration's tokens cannot be attributed to a single story, so\n * each one receives an equal share. Token counts are rounded to integers;\n * the cost keeps full precision.\n *\n * `parts <= 1` (or a non-finite value) returns the usage unchanged. Fields the\n * CLI never reported stay absent — dividing \"not reported\" still yields\n * \"not reported\", never zero.\n */\nexport function divideUsage(usage: ClaudeUsage | null | undefined, parts: number): ClaudeUsage {\n const result: ClaudeUsage = {};\n if (!usage) return result;\n\n const divisor = Number.isFinite(parts) && parts > 1 ? parts : 1;\n\n for (const field of USAGE_FIELDS) {\n const value = usage[field];\n if (value === undefined) continue;\n result[field] = field === 'costUsd' ? value / divisor : Math.round(value / divisor);\n }\n\n return result;\n}\n\n/**\n * Compact token count: `1523` → `1.5k`, `2_400_000` → `2.4M`.\n */\nfunction compactTokens(value: number): string {\n const abs = Math.abs(value);\n if (abs >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M`;\n if (abs >= 1_000) return `${(value / 1_000).toFixed(1)}k`;\n return String(Math.round(value));\n}\n\n/**\n * Human-readable one-liner, e.g. `2 in / 4 out · 15.5k cache · ~$0.1607`.\n *\n * Segments whose data is missing are omitted entirely — callers can rely on an\n * empty string meaning \"no metrics at all\" and skip the line altogether rather\n * than printing zeros or NaN.\n */\nexport function formatTokens(usage: ClaudeUsage | null | undefined): string {\n if (!usage) return '';\n\n const segments: string[] = [];\n\n const io: string[] = [];\n if (usage.inputTokens !== undefined) io.push(`${compactTokens(usage.inputTokens)} in`);\n if (usage.outputTokens !== undefined) io.push(`${compactTokens(usage.outputTokens)} out`);\n if (io.length > 0) segments.push(io.join(' / '));\n\n const cache =\n usage.cacheReadTokens !== undefined || usage.cacheCreationTokens !== undefined\n ? (usage.cacheReadTokens ?? 0) + (usage.cacheCreationTokens ?? 0)\n : undefined;\n if (cache !== undefined) segments.push(`${compactTokens(cache)} cache`);\n\n if (usage.costUsd !== undefined) segments.push(`~$${usage.costUsd.toFixed(4)}`);\n\n return segments.join(' · ');\n}\n\n/**\n * True when the usage carries at least one reported field. Handy for deciding\n * whether a metrics line or event is worth emitting at all.\n */\nexport function hasUsageData(usage: ClaudeUsage | null | undefined): boolean {\n if (!usage) return false;\n return USAGE_FIELDS.some((field) => usage[field] !== undefined);\n}\n","let _verbose = false;\n\nexport function setVerbose(enabled: boolean): void {\n _verbose = enabled;\n}\n\nexport function isVerbose(): boolean {\n return _verbose;\n}\n\nlet _onOutput: ((line: string) => void) | undefined;\n\n/**\n * Set a global output callback for routing verbose output (e.g., through listr2 task.output).\n * Pass undefined to clear and fall back to direct stderr writes.\n */\nexport function setOutputCallback(callback: ((line: string) => void) | undefined): void {\n _onOutput = callback;\n}\n\nexport function getOutputCallback(): ((line: string) => void) | undefined {\n return _onOutput;\n}\n\nlet _onStoryUpdate: ((stories: import('../types.js').UserStory[]) => void) | undefined;\n\n/**\n * Set a global callback for story progress updates during engine execution.\n * Called after each iteration with the latest user stories state.\n * Pass undefined to clear.\n */\nexport function setStoryUpdateCallback(\n callback: ((stories: import('../types.js').UserStory[]) => void) | undefined,\n): void {\n _onStoryUpdate = callback;\n}\n\nexport function getStoryUpdateCallback():\n | ((stories: import('../types.js').UserStory[]) => void)\n | undefined {\n return _onStoryUpdate;\n}\n\nlet _globalTimeout: number | undefined;\n\nexport function setGlobalTimeout(ms: number): void {\n _globalTimeout = ms;\n}\n\nexport function getGlobalTimeout(): number | undefined {\n return _globalTimeout;\n}\n","import chalk from 'chalk';\nimport ora, { type Ora } from 'ora';\nimport { getSessionPublisher } from '../core/session-publisher.js';\nimport type { SessionLogLevel } from '../core/session-state.js';\nimport { isoNow } from '../core/state-manager.js';\nimport { getOutputCallback } from '../core/verbose.js';\n\n/**\n * Detect if unicode output is supported.\n */\nexport function useUnicode(): boolean {\n if (process.env.NO_COLOR != null && process.env.NO_COLOR !== '') return false;\n if (!process.stdout.isTTY) return false;\n return true;\n}\n\n/**\n * Detect if color output is supported.\n */\nexport function useColor(): boolean {\n if (process.env.NO_COLOR != null && process.env.NO_COLOR !== '') return false;\n if (!process.stdout.isTTY) return false;\n return true;\n}\n\nexport interface Icons {\n success: string;\n fail: string;\n pending: string;\n retry: string;\n warn: string;\n start: string;\n end: string;\n notReached: string;\n tool: string;\n connector: string;\n}\n\nexport function getIcons(): Icons {\n if (useUnicode()) {\n return {\n success: '\\u2713',\n fail: '\\u2717',\n pending: '\\u23F3',\n retry: '\\u21BB',\n warn: '\\u26A0',\n start: '\\u25B6',\n end: '\\u25A0',\n notReached: '\\u25CB',\n tool: '\\u25B8',\n connector: '\\u2502',\n };\n }\n return {\n success: '[OK]',\n fail: '[FAIL]',\n pending: '[...]',\n retry: '[RETRY]',\n warn: '[WARN]',\n start: '[START]',\n end: '[END]',\n notReached: '[ ]',\n tool: '>',\n connector: '|',\n };\n}\n\n/**\n * Get the terminal width.\n */\nexport function getTermWidth(): number {\n return process.stdout.columns ?? 80;\n}\n\n/**\n * Emit a line of output. Routes through the global output callback when\n * running inside a listr2 task context, otherwise falls back to console.log.\n *\n * Also forwards the line to the session publisher with its structured level;\n * ANSI codes are stripped by the reducer, so terminal output stays untouched.\n */\nfunction emit(line: string, level: SessionLogLevel = 'info'): void {\n getSessionPublisher().publish({ type: 'log', at: isoNow(), level, message: line });\n const cb = getOutputCallback();\n if (cb) {\n cb(line);\n } else {\n console.log(line);\n }\n}\n\nexport function printSuccess(message: string): void {\n const icons = getIcons();\n if (useColor()) {\n emit(chalk.green(`${icons.success} ${message}`));\n } else {\n emit(`${icons.success} ${message}`);\n }\n}\n\nexport function printError(message: string): void {\n const icons = getIcons();\n if (useColor()) {\n emit(chalk.red(`${icons.fail} ${message}`), 'error');\n } else {\n emit(`${icons.fail} ${message}`, 'error');\n }\n}\n\nexport function printWarning(message: string): void {\n const icons = getIcons();\n if (useColor()) {\n emit(chalk.yellow(`${icons.warn} ${message}`), 'warn');\n } else {\n emit(`${icons.warn} ${message}`, 'warn');\n }\n}\n\nexport function printRetry(message: string): void {\n const icons = getIcons();\n if (useColor()) {\n emit(chalk.yellow(`${icons.retry} ${message}`), 'warn');\n } else {\n emit(`${icons.retry} ${message}`, 'warn');\n }\n}\n\nexport function printInfo(message: string): void {\n const icons = getIcons();\n if (useColor()) {\n emit(chalk.blue(`${icons.start} ${message}`));\n } else {\n emit(`${icons.start} ${message}`);\n }\n}\n\n/**\n * Create an ora spinner with consistent styling.\n */\nexport function createSpinner(message: string): Ora {\n return ora({\n text: message,\n color: 'blue',\n spinner: 'dots',\n });\n}\n\n/**\n * Format a duration in seconds to a human-readable string.\n */\nexport function formatDuration(totalSeconds: number): string {\n const hours = Math.floor(totalSeconds / 3600);\n const mins = Math.floor((totalSeconds % 3600) / 60);\n const secs = totalSeconds % 60;\n\n if (hours > 0) {\n return `${hours}h ${mins}m ${secs}s`;\n }\n if (mins > 0) {\n return `${mins}m ${secs}s`;\n }\n return `${secs}s`;\n}\n\n/**\n * Timer that calls a callback every second with the formatted elapsed time.\n */\nexport class ElapsedTimer {\n private startTime: number;\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private cleanup = () => this.stop();\n\n constructor(private onTick: (elapsed: string) => void) {\n this.startTime = Date.now();\n }\n\n start(): this {\n this.startTime = Date.now();\n this.intervalId = setInterval(() => {\n const seconds = Math.floor((Date.now() - this.startTime) / 1000);\n this.onTick(formatDuration(seconds));\n }, 1_000);\n // Prevent the timer from keeping the process alive\n if (this.intervalId && typeof this.intervalId === 'object' && 'unref' in this.intervalId) {\n this.intervalId.unref();\n }\n process.on('exit', this.cleanup);\n return this;\n }\n\n getElapsedSeconds(): number {\n return Math.floor((Date.now() - this.startTime) / 1000);\n }\n\n stop(): number {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n process.removeListener('exit', this.cleanup);\n return this.getElapsedSeconds();\n }\n}\n"],"mappings":"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","names":["rename","writeFile"]}
|
|
@@ -5,13 +5,13 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
getGlobalRoot,
|
|
7
7
|
webLockSchema
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-BASRRXAM.js";
|
|
9
9
|
import {
|
|
10
10
|
NullPublisher,
|
|
11
11
|
isoNow,
|
|
12
12
|
printInfo,
|
|
13
13
|
printWarning
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-BH7DYADV.js";
|
|
15
15
|
|
|
16
16
|
// src/web/lock.ts
|
|
17
17
|
import { spawn as nodeSpawn } from "child_process";
|
|
@@ -444,4 +444,4 @@ export {
|
|
|
444
444
|
ensureSingleWebServer,
|
|
445
445
|
ensureWebMonitor
|
|
446
446
|
};
|
|
447
|
-
//# sourceMappingURL=chunk-
|
|
447
|
+
//# sourceMappingURL=chunk-F52S6ZGF.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
resolveIssuePaths,
|
|
6
6
|
resolveProjectPaths,
|
|
7
7
|
run
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-BASRRXAM.js";
|
|
9
9
|
import {
|
|
10
10
|
isoNow,
|
|
11
11
|
issueMetadataSchema,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
printInfo,
|
|
14
14
|
printWarning,
|
|
15
15
|
writeFileAtomic
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-BH7DYADV.js";
|
|
17
17
|
|
|
18
18
|
// src/issues/registry.ts
|
|
19
19
|
var providers = /* @__PURE__ */ new Map();
|
|
@@ -753,4 +753,4 @@ export {
|
|
|
753
753
|
issuePlaceholders,
|
|
754
754
|
resolveCommandIssue
|
|
755
755
|
};
|
|
756
|
-
//# sourceMappingURL=chunk-
|
|
756
|
+
//# sourceMappingURL=chunk-HSGTZ3CT.js.map
|
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
normalizeRemoteUrl,
|
|
10
10
|
run,
|
|
11
11
|
stripRemoteUrlCredentials
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-BASRRXAM.js";
|
|
13
13
|
import {
|
|
14
14
|
NullPublisher,
|
|
15
15
|
isoNow
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-BH7DYADV.js";
|
|
17
17
|
|
|
18
18
|
// src/core/session-git.ts
|
|
19
19
|
async function listPullRequests(branch) {
|
|
@@ -109,4 +109,4 @@ export {
|
|
|
109
109
|
listPullRequests,
|
|
110
110
|
publishGitState
|
|
111
111
|
};
|
|
112
|
-
//# sourceMappingURL=chunk-
|
|
112
|
+
//# sourceMappingURL=chunk-J3PJBZXJ.js.map
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runPhaseWithRetry
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RQW5W4XC.js";
|
|
5
5
|
import {
|
|
6
6
|
issuePlaceholders,
|
|
7
7
|
resolveCommandIssue
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-HSGTZ3CT.js";
|
|
9
9
|
import {
|
|
10
10
|
isTransientFailure
|
|
11
11
|
} from "./chunk-HDV3YDTG.js";
|
|
12
12
|
import {
|
|
13
13
|
runHeadless
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-JWZKV3CL.js";
|
|
15
15
|
import {
|
|
16
16
|
publishPhaseMetrics
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-QO2MWMAZ.js";
|
|
18
18
|
import {
|
|
19
19
|
applyPlaceholders,
|
|
20
20
|
loadPrompt
|
|
21
21
|
} from "./chunk-SLHZPB3C.js";
|
|
22
22
|
import {
|
|
23
23
|
resolveIssuePaths
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-BASRRXAM.js";
|
|
25
25
|
import {
|
|
26
26
|
getGlobalTimeout,
|
|
27
27
|
isoNow,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
printError,
|
|
30
30
|
printSuccess,
|
|
31
31
|
saveTaskPlan
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-BH7DYADV.js";
|
|
33
33
|
|
|
34
34
|
// src/commands/pr.ts
|
|
35
35
|
import { execa } from "execa";
|
|
@@ -134,4 +134,4 @@ async function runPr(issue, resolvedIssue) {
|
|
|
134
134
|
export {
|
|
135
135
|
runPr
|
|
136
136
|
};
|
|
137
|
-
//# sourceMappingURL=chunk-
|
|
137
|
+
//# sourceMappingURL=chunk-J4SICTAN.js.map
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
isoNow,
|
|
11
11
|
parseUsage,
|
|
12
12
|
useColor
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BH7DYADV.js";
|
|
14
14
|
|
|
15
15
|
// src/core/headless.ts
|
|
16
16
|
import { createInterface } from "readline";
|
|
@@ -279,4 +279,4 @@ async function runHeadless(options) {
|
|
|
279
279
|
export {
|
|
280
280
|
runHeadless
|
|
281
281
|
};
|
|
282
|
-
//# sourceMappingURL=chunk-
|
|
282
|
+
//# sourceMappingURL=chunk-JWZKV3CL.js.map
|
|
@@ -2,27 +2,27 @@
|
|
|
2
2
|
import {
|
|
3
3
|
readFileWithGrace,
|
|
4
4
|
runPhaseWithRetry
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-RQW5W4XC.js";
|
|
6
6
|
import {
|
|
7
7
|
issuePlaceholders,
|
|
8
8
|
resolveCommandIssue
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-HSGTZ3CT.js";
|
|
10
10
|
import {
|
|
11
11
|
isTransientFailure
|
|
12
12
|
} from "./chunk-HDV3YDTG.js";
|
|
13
13
|
import {
|
|
14
14
|
runHeadless
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-JWZKV3CL.js";
|
|
16
16
|
import {
|
|
17
17
|
publishPhaseMetrics
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-QO2MWMAZ.js";
|
|
19
19
|
import {
|
|
20
20
|
applyPlaceholders,
|
|
21
21
|
loadPrompt
|
|
22
22
|
} from "./chunk-SLHZPB3C.js";
|
|
23
23
|
import {
|
|
24
24
|
resolveIssuePaths
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-BASRRXAM.js";
|
|
26
26
|
import {
|
|
27
27
|
getGlobalTimeout,
|
|
28
28
|
loadTaskPlan,
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
printSuccess,
|
|
31
31
|
saveTaskPlan,
|
|
32
32
|
taskPlanSchema
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-BH7DYADV.js";
|
|
34
34
|
|
|
35
35
|
// src/commands/plan.ts
|
|
36
36
|
import { mkdir, readFile } from "fs/promises";
|
|
@@ -120,4 +120,4 @@ ${issues}`
|
|
|
120
120
|
export {
|
|
121
121
|
runPlan
|
|
122
122
|
};
|
|
123
|
-
//# sourceMappingURL=chunk-
|
|
123
|
+
//# sourceMappingURL=chunk-MK43N4X3.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
hasUsageData,
|
|
5
5
|
isoNow,
|
|
6
6
|
sumUsage
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BH7DYADV.js";
|
|
8
8
|
|
|
9
9
|
// src/core/session-metrics.ts
|
|
10
10
|
function elapsedSecondsSince(startedAtMs) {
|
|
@@ -75,4 +75,4 @@ export {
|
|
|
75
75
|
publishIterationMetrics,
|
|
76
76
|
publishStoryMetrics
|
|
77
77
|
};
|
|
78
|
-
//# sourceMappingURL=chunk-
|
|
78
|
+
//# sourceMappingURL=chunk-QO2MWMAZ.js.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
getSessionPublisher,
|
|
8
8
|
isoNow,
|
|
9
9
|
printRetry
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-BH7DYADV.js";
|
|
11
11
|
|
|
12
12
|
// src/core/phase-runner.ts
|
|
13
13
|
import { readFile } from "fs/promises";
|
|
@@ -55,4 +55,4 @@ export {
|
|
|
55
55
|
runPhaseWithRetry,
|
|
56
56
|
readFileWithGrace
|
|
57
57
|
};
|
|
58
|
-
//# sourceMappingURL=chunk-
|
|
58
|
+
//# sourceMappingURL=chunk-RQW5W4XC.js.map
|