issue-flow 0.11.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/README.md +79 -274
  2. package/dist/agent-BXRIEKVM.js +238 -0
  3. package/dist/agent-BXRIEKVM.js.map +1 -0
  4. package/dist/{analyze-XV3K25K3.js → analyze-WS47UYGN.js} +32 -15
  5. package/dist/analyze-WS47UYGN.js.map +1 -0
  6. package/dist/{apply-WUJHDD7A.js → apply-OS62UWRN.js} +15 -5
  7. package/dist/{apply-WUJHDD7A.js.map → apply-OS62UWRN.js.map} +1 -1
  8. package/dist/bench-SA3BOME5.js +906 -0
  9. package/dist/bench-SA3BOME5.js.map +1 -0
  10. package/dist/chunk-37N2RJW2.js +120 -0
  11. package/dist/chunk-37N2RJW2.js.map +1 -0
  12. package/dist/chunk-3XLCNVMD.js +180 -0
  13. package/dist/chunk-3XLCNVMD.js.map +1 -0
  14. package/dist/chunk-5TB6KLC2.js +72 -0
  15. package/dist/chunk-5TB6KLC2.js.map +1 -0
  16. package/dist/{chunk-OBLVLIUS.js → chunk-664Y3NDX.js} +25 -13
  17. package/dist/chunk-664Y3NDX.js.map +1 -0
  18. package/dist/chunk-6FDFRNXZ.js +357 -0
  19. package/dist/chunk-6FDFRNXZ.js.map +1 -0
  20. package/dist/chunk-7KD66LIM.js +658 -0
  21. package/dist/chunk-7KD66LIM.js.map +1 -0
  22. package/dist/chunk-7Z4Y3VKM.js +26 -0
  23. package/dist/chunk-7Z4Y3VKM.js.map +1 -0
  24. package/dist/chunk-ARFVHC2F.js +1111 -0
  25. package/dist/chunk-ARFVHC2F.js.map +1 -0
  26. package/dist/{chunk-RKTEV6EG.js → chunk-BHJCGWQX.js} +141 -12
  27. package/dist/chunk-BHJCGWQX.js.map +1 -0
  28. package/dist/chunk-BQDQTIM7.js +74 -0
  29. package/dist/chunk-BQDQTIM7.js.map +1 -0
  30. package/dist/chunk-CNBYCMSU.js +2709 -0
  31. package/dist/chunk-CNBYCMSU.js.map +1 -0
  32. package/dist/chunk-CRGIQFUQ.js +83 -0
  33. package/dist/chunk-CRGIQFUQ.js.map +1 -0
  34. package/dist/chunk-DIG5XKQQ.js +298 -0
  35. package/dist/chunk-DIG5XKQQ.js.map +1 -0
  36. package/dist/chunk-FZDR7CGH.js +71 -0
  37. package/dist/chunk-FZDR7CGH.js.map +1 -0
  38. package/dist/chunk-HEF2RMKN.js +413 -0
  39. package/dist/chunk-HEF2RMKN.js.map +1 -0
  40. package/dist/{chunk-IVHZEYAX.js → chunk-HJGGNLWI.js} +25 -19
  41. package/dist/chunk-HJGGNLWI.js.map +1 -0
  42. package/dist/chunk-HQAHNIAR.js +283 -0
  43. package/dist/chunk-HQAHNIAR.js.map +1 -0
  44. package/dist/{chunk-GANSDJV7.js → chunk-IHIEXUTC.js} +46 -24
  45. package/dist/chunk-IHIEXUTC.js.map +1 -0
  46. package/dist/chunk-IV5SS4JN.js +84 -0
  47. package/dist/chunk-IV5SS4JN.js.map +1 -0
  48. package/dist/{chunk-HC2MT7BX.js → chunk-IYV6KNVF.js} +158 -592
  49. package/dist/chunk-IYV6KNVF.js.map +1 -0
  50. package/dist/{chunk-LVKQ2AKT.js → chunk-J62QSVP6.js} +10 -8
  51. package/dist/chunk-J62QSVP6.js.map +1 -0
  52. package/dist/chunk-KMMASOA6.js +134 -0
  53. package/dist/chunk-KMMASOA6.js.map +1 -0
  54. package/dist/chunk-KQHB7ZT3.js +559 -0
  55. package/dist/chunk-KQHB7ZT3.js.map +1 -0
  56. package/dist/chunk-L6HSKTQE.js +77 -0
  57. package/dist/chunk-L6HSKTQE.js.map +1 -0
  58. package/dist/{chunk-6N7LZZ5U.js → chunk-LZ6GFQAG.js} +474 -160
  59. package/dist/chunk-LZ6GFQAG.js.map +1 -0
  60. package/dist/{chunk-HQYXVIH6.js → chunk-MIVHK5YI.js} +5 -5
  61. package/dist/chunk-NEZZ6KDR.js +1217 -0
  62. package/dist/chunk-NEZZ6KDR.js.map +1 -0
  63. package/dist/{run-DBF2VWUN.js → chunk-OPNGPUKJ.js} +747 -594
  64. package/dist/chunk-OPNGPUKJ.js.map +1 -0
  65. package/dist/chunk-P3LRUNC6.js +16 -0
  66. package/dist/chunk-P3LRUNC6.js.map +1 -0
  67. package/dist/{chunk-BXCPXRBR.js → chunk-PIVGJM6K.js} +129 -32
  68. package/dist/chunk-PIVGJM6K.js.map +1 -0
  69. package/dist/{chunk-AAY6KM7N.js → chunk-PV4OX5TC.js} +167 -196
  70. package/dist/chunk-PV4OX5TC.js.map +1 -0
  71. package/dist/chunk-QCXPNSEL.js +141 -0
  72. package/dist/chunk-QCXPNSEL.js.map +1 -0
  73. package/dist/{chunk-34WNTK3K.js → chunk-QXDNBYQF.js} +53 -13
  74. package/dist/chunk-QXDNBYQF.js.map +1 -0
  75. package/dist/chunk-SNTTOQAD.js +30 -0
  76. package/dist/chunk-SNTTOQAD.js.map +1 -0
  77. package/dist/{chunk-EY6WMHV2.js → chunk-TM67EHSV.js} +67 -23
  78. package/dist/chunk-TM67EHSV.js.map +1 -0
  79. package/dist/chunk-TVN2JVOF.js +77 -0
  80. package/dist/chunk-TVN2JVOF.js.map +1 -0
  81. package/dist/chunk-TX5WIVYP.js +129 -0
  82. package/dist/chunk-TX5WIVYP.js.map +1 -0
  83. package/dist/{chunk-KQ4JQN7T.js → chunk-UJ7XWK7J.js} +83 -21
  84. package/dist/chunk-UJ7XWK7J.js.map +1 -0
  85. package/dist/{chunk-47VIN33V.js → chunk-UOCPC2Y2.js} +596 -17
  86. package/dist/chunk-UOCPC2Y2.js.map +1 -0
  87. package/dist/chunk-XEYH6ZZI.js +289 -0
  88. package/dist/chunk-XEYH6ZZI.js.map +1 -0
  89. package/dist/cli.js +390 -40
  90. package/dist/cli.js.map +1 -1
  91. package/dist/config-MEM2IWWN.js +76 -0
  92. package/dist/contract-JH2WBIO6.js +8 -0
  93. package/dist/conventions-WV4NDXGH.js +143 -0
  94. package/dist/conventions-WV4NDXGH.js.map +1 -0
  95. package/dist/execute-NITIHHCK.js +31 -0
  96. package/dist/{generate-TBVTLMOP.js → generate-MVQI7A45.js} +39 -19
  97. package/dist/{generate-TBVTLMOP.js.map → generate-MVQI7A45.js.map} +1 -1
  98. package/dist/git-YRVRUN3C.js +31 -0
  99. package/dist/init-OKWEC3EV.js +21 -0
  100. package/dist/operations-LU6JA3BX.js +374 -0
  101. package/dist/operations-LU6JA3BX.js.map +1 -0
  102. package/dist/permissions-7NMDFU27.js +18 -0
  103. package/dist/plan-LEJJF3DE.js +31 -0
  104. package/dist/{policy-XQW5NUIE.js → policy-JSYEK5B2.js} +17 -4
  105. package/dist/policy-JSYEK5B2.js.map +1 -0
  106. package/dist/pr-HPVUZ7S3.js +36 -0
  107. package/dist/pr-review-R2QZBT3F.js +29 -0
  108. package/dist/pr-review-R2QZBT3F.js.map +1 -0
  109. package/dist/prd-5O6GYCC6.js +30 -0
  110. package/dist/prd-5O6GYCC6.js.map +1 -0
  111. package/dist/ps-TNE44R5V.js +90 -0
  112. package/dist/ps-TNE44R5V.js.map +1 -0
  113. package/dist/recorder-XGF55WXI.js +31 -0
  114. package/dist/recorder-XGF55WXI.js.map +1 -0
  115. package/dist/registry-LGPE53QD.js +15 -0
  116. package/dist/registry-LGPE53QD.js.map +1 -0
  117. package/dist/resume-QMEPMSZW.js +238 -0
  118. package/dist/resume-QMEPMSZW.js.map +1 -0
  119. package/dist/review-YKWD6SNN.js +32 -0
  120. package/dist/review-YKWD6SNN.js.map +1 -0
  121. package/dist/routing-2ZUMZPJB.js +91 -0
  122. package/dist/routing-2ZUMZPJB.js.map +1 -0
  123. package/dist/run-YU4TR62R.js +50 -0
  124. package/dist/run-YU4TR62R.js.map +1 -0
  125. package/dist/state-manager-X3PT3FGT.js +36 -0
  126. package/dist/state-manager-X3PT3FGT.js.map +1 -0
  127. package/dist/usage-VCFLDA5Y.js +174 -0
  128. package/dist/usage-VCFLDA5Y.js.map +1 -0
  129. package/dist/{web-ANQQTTRD.js → web-XVHLX62B.js} +43 -27
  130. package/dist/web-XVHLX62B.js.map +1 -0
  131. package/package.json +6 -2
  132. package/prompts/execute.md +7 -8
  133. package/prompts/plan.md +4 -5
  134. package/prompts/pr.md +13 -6
  135. package/web/AGENTS.md +3 -3
  136. package/web/public/app.css +38 -0
  137. package/web/public/app.js +132 -10
  138. package/web/public/index.html +24 -0
  139. package/dist/analyze-XV3K25K3.js.map +0 -1
  140. package/dist/chunk-34WNTK3K.js.map +0 -1
  141. package/dist/chunk-3BOHTH4V.js +0 -58
  142. package/dist/chunk-3BOHTH4V.js.map +0 -1
  143. package/dist/chunk-47VIN33V.js.map +0 -1
  144. package/dist/chunk-6N7LZZ5U.js.map +0 -1
  145. package/dist/chunk-AAY6KM7N.js.map +0 -1
  146. package/dist/chunk-BXCPXRBR.js.map +0 -1
  147. package/dist/chunk-EWDJENFW.js +0 -303
  148. package/dist/chunk-EWDJENFW.js.map +0 -1
  149. package/dist/chunk-EY6WMHV2.js.map +0 -1
  150. package/dist/chunk-GANSDJV7.js.map +0 -1
  151. package/dist/chunk-HC2MT7BX.js.map +0 -1
  152. package/dist/chunk-HDV3YDTG.js +0 -52
  153. package/dist/chunk-HDV3YDTG.js.map +0 -1
  154. package/dist/chunk-IVHZEYAX.js.map +0 -1
  155. package/dist/chunk-KQ4JQN7T.js.map +0 -1
  156. package/dist/chunk-LVKQ2AKT.js.map +0 -1
  157. package/dist/chunk-OBLVLIUS.js.map +0 -1
  158. package/dist/chunk-RKTEV6EG.js.map +0 -1
  159. package/dist/chunk-VQ5VN7DF.js +0 -1018
  160. package/dist/chunk-VQ5VN7DF.js.map +0 -1
  161. package/dist/config-4THHOXNN.js +0 -41
  162. package/dist/execute-5OEKLM5X.js +0 -15
  163. package/dist/init-PRMOTQ7N.js +0 -9
  164. package/dist/plan-Y2BYZD24.js +0 -17
  165. package/dist/policy-XQW5NUIE.js.map +0 -1
  166. package/dist/pr-H6GLOSXF.js +0 -21
  167. package/dist/pr-review-CK5FR6WX.js +0 -17
  168. package/dist/prd-4PWLCGH5.js +0 -17
  169. package/dist/review-QGVAHEZF.js +0 -15
  170. package/dist/run-DBF2VWUN.js.map +0 -1
  171. package/dist/web-ANQQTTRD.js.map +0 -1
  172. /package/dist/{chunk-HQYXVIH6.js.map → chunk-MIVHK5YI.js.map} +0 -0
  173. /package/dist/{config-4THHOXNN.js.map → config-MEM2IWWN.js.map} +0 -0
  174. /package/dist/{execute-5OEKLM5X.js.map → contract-JH2WBIO6.js.map} +0 -0
  175. /package/dist/{init-PRMOTQ7N.js.map → execute-NITIHHCK.js.map} +0 -0
  176. /package/dist/{plan-Y2BYZD24.js.map → git-YRVRUN3C.js.map} +0 -0
  177. /package/dist/{pr-H6GLOSXF.js.map → init-OKWEC3EV.js.map} +0 -0
  178. /package/dist/{pr-review-CK5FR6WX.js.map → permissions-7NMDFU27.js.map} +0 -0
  179. /package/dist/{prd-4PWLCGH5.js.map → plan-LEJJF3DE.js.map} +0 -0
  180. /package/dist/{review-QGVAHEZF.js.map → pr-HPVUZ7S3.js.map} +0 -0
@@ -1,339 +1,18 @@
1
1
  #!/usr/bin/env node
2
-
3
- // src/policy/schemas.ts
4
- import { z } from "zod";
5
- var policyDiscoveryConfigSchema = z.object({
6
- issueTemplates: z.boolean().default(true),
7
- pullRequestTemplate: z.boolean().default(true),
8
- docs: z.boolean().default(true),
9
- codeowners: z.boolean().default(true),
10
- labels: z.boolean().default(true),
11
- issueTypes: z.boolean().default(true)
12
- });
13
- var policyIssuesDeclarationSchema = z.object({
14
- titleConvention: z.string().min(1).optional(),
15
- /**
16
- * Whether Issue Flow may create a label the repository does not have.
17
- *
18
- * `.optional()` rather than `.default(false)`: the resolved declarations must
19
- * stay "only what was written", or the group would always look declared and
20
- * `sources` would report a provenance nobody asked for. The effective default
21
- * — false — lives at the call site.
22
- *
23
- * That default is a deliberate change of behaviour: creating taxonomy without
24
- * asking is the defect this exists to stop. A repository that wants the old
25
- * behaviour opts back into it.
26
- */
27
- allowLabelCreation: z.boolean().optional()
28
- });
29
- var policyPullRequestsDeclarationSchema = z.object({
30
- baseBranch: z.string().min(1).optional(),
31
- titleConvention: z.string().min(1).optional()
32
- });
33
- var policyGitDeclarationSchema = z.object({
34
- branchConvention: z.string().min(1).optional(),
35
- commitConvention: z.string().min(1).optional()
36
- });
37
- var policyConfigSchema = z.object({
38
- enabled: z.boolean().default(true),
39
- /**
40
- * Token budget for the `__REPO_POLICY__` projection. Sections above it are
41
- * replaced whole by a pointer rather than truncated — see
42
- * `policy/placeholders.ts`.
43
- */
44
- contextBudget: z.number().int().positive().default(1500),
45
- discovery: policyDiscoveryConfigSchema.prefault({}),
46
- issues: policyIssuesDeclarationSchema.prefault({}),
47
- pullRequests: policyPullRequestsDeclarationSchema.prefault({}),
48
- git: policyGitDeclarationSchema.prefault({})
49
- });
50
- var policyConfigInputSchema = z.object({
51
- enabled: z.boolean().optional(),
52
- contextBudget: z.number().int().positive().optional(),
53
- // Spelled out rather than `policyDiscoveryConfigSchema.partial()`: in zod 4
54
- // a `.default()` survives `.partial()`, so every toggle would come back
55
- // materialized and the input layer would stop meaning "what the user wrote".
56
- discovery: z.object({
57
- issueTemplates: z.boolean().optional(),
58
- pullRequestTemplate: z.boolean().optional(),
59
- docs: z.boolean().optional(),
60
- codeowners: z.boolean().optional(),
61
- labels: z.boolean().optional(),
62
- issueTypes: z.boolean().optional()
63
- }).optional(),
64
- issues: z.object({ titleConvention: z.string().nullish(), allowLabelCreation: z.boolean().optional() }).optional(),
65
- pullRequests: z.object({ baseBranch: z.string().nullish(), titleConvention: z.string().nullish() }).optional(),
66
- git: z.object({ branchConvention: z.string().nullish(), commitConvention: z.string().nullish() }).optional()
67
- });
68
-
69
- // src/schemas.ts
70
- import { z as z2 } from "zod";
71
- var claudeUsageSchema = z2.object({
72
- inputTokens: z2.number().optional(),
73
- outputTokens: z2.number().optional(),
74
- cacheReadTokens: z2.number().optional(),
75
- cacheCreationTokens: z2.number().optional(),
76
- costUsd: z2.number().optional()
77
- });
78
- var userStoryStatusSchema = z2.enum(["backlog", "in_progress", "in_review", "done"]);
79
- var storyStageSchema = z2.enum([
80
- "pending",
81
- "executing",
82
- "awaiting_review",
83
- "in_review",
84
- "in_correction",
85
- "done",
86
- "failed"
87
- ]);
88
- var userStorySchema = z2.object({
89
- id: z2.string(),
90
- title: z2.string(),
91
- description: z2.string(),
92
- acceptanceCriteria: z2.array(z2.string()),
93
- priority: z2.number().int().positive(),
94
- passes: z2.boolean(),
95
- notes: z2.string(),
96
- ...claudeUsageSchema.shape,
97
- durationSeconds: z2.number().optional(),
98
- status: userStoryStatusSchema.optional(),
99
- dependencies: z2.array(z2.string()).optional(),
100
- stage: storyStageSchema.optional(),
101
- stageSince: z2.string().optional(),
102
- stageDetail: z2.string().optional()
103
- });
104
- var pipelineStateSchema = z2.object({
105
- analyzeCompleted: z2.boolean().optional(),
106
- prdCompleted: z2.boolean(),
107
- jsonCompleted: z2.boolean(),
108
- executionCompleted: z2.boolean(),
109
- reviewCompleted: z2.boolean(),
110
- prCreated: z2.boolean(),
111
- prReviewCompleted: z2.boolean().optional()
112
- });
113
- var pullRequestRefSchema = z2.object({
114
- number: z2.number().int().positive(),
115
- url: z2.string(),
116
- headBranch: z2.string(),
117
- createdAt: z2.string()
118
- });
119
- var prReviewRecommendationSchema = z2.enum([
120
- "APPROVE",
121
- "APPROVE_WITH_SUGGESTIONS",
122
- "REQUEST_CHANGES"
123
- ]);
124
- var prReviewStateSchema = z2.object({
125
- enabled: z2.boolean().default(false),
126
- pullRequestNumber: z2.number().int().positive().optional(),
127
- rounds: z2.number().int().min(0).default(0),
128
- lastRecommendation: prReviewRecommendationSchema.optional(),
129
- lastReviewedAt: z2.string().optional()
130
- });
131
- var lastErrorSchema = z2.object({
132
- category: z2.string(),
133
- message: z2.string(),
134
- at: z2.string()
135
- });
136
- var issueMetadataSchema = z2.object({
137
- schemaVersion: z2.literal(1),
138
- id: z2.string().min(1),
139
- number: z2.number().int().positive().nullable(),
140
- source: z2.enum(["github", "local"]),
141
- title: z2.string(),
142
- labels: z2.array(z2.string()),
143
- state: z2.enum(["open", "closed"]),
144
- createdAt: z2.string(),
145
- updatedAt: z2.string(),
146
- contentHash: z2.string(),
147
- remote: z2.object({
148
- provider: z2.enum(["github", "local"]),
149
- ref: z2.string(),
150
- syncedAt: z2.string(),
151
- syncedContentHash: z2.string()
152
- }).optional()
153
- });
154
- var taskPlanSchema = z2.object({
155
- project: z2.string(),
156
- issueNumber: z2.union([z2.number().int().positive(), z2.string().min(1)]),
157
- issueUrl: z2.string().optional().default(""),
158
- branchName: z2.string(),
159
- noBranch: z2.boolean().optional().default(false),
160
- description: z2.string(),
161
- issueStatus: z2.enum(["pending", "in_progress", "completed"]),
162
- completedAt: z2.string().nullable(),
163
- lastAttemptAt: z2.string().nullable(),
164
- lastError: lastErrorSchema.nullable(),
165
- correctionCycle: z2.number().int().min(0),
166
- maxCorrectionCycles: z2.number().int().min(0),
167
- /**
168
- * Findings from the most recent failed review, verbatim. Non-null means the
169
- * issue has a pending correction even if every userStories[].passes is
170
- * already true — the execute phase must address these before the field is
171
- * cleared back to null. See core/engine.ts's early-return guards.
172
- */
173
- lastReviewFindings: z2.string().nullable().optional().default(null),
174
- pipeline: pipelineStateSchema,
175
- pullRequest: pullRequestRefSchema.optional(),
176
- prReview: prReviewStateSchema.optional(),
177
- userStories: z2.array(userStorySchema)
178
- });
179
- var headlessResultSchema = z2.object({
180
- success: z2.boolean(),
181
- result: z2.string(),
182
- cost: claudeUsageSchema.nullable(),
183
- error: z2.string().nullable()
184
- });
185
- var sessionLogEntrySchema = z2.object({
186
- at: z2.string(),
187
- level: z2.enum(["info", "warn", "error"]),
188
- message: z2.string()
189
- });
190
- var sessionUsageShape = {
191
- inputTokens: z2.number().nullable().default(null),
192
- outputTokens: z2.number().nullable().default(null),
193
- cacheReadTokens: z2.number().nullable().default(null),
194
- cacheCreationTokens: z2.number().nullable().default(null),
195
- costUsd: z2.number().nullable().default(null)
196
- };
197
- var sessionPhaseSchema = z2.object({
198
- name: z2.string(),
199
- status: z2.enum(["pending", "running", "completed", "failed"]),
200
- startedAt: z2.string().nullable(),
201
- endedAt: z2.string().nullable(),
202
- durationSeconds: z2.number().nullable(),
203
- error: z2.string().nullable(),
204
- ...sessionUsageShape
205
- });
206
- var sessionStorySchema = z2.object({
207
- id: z2.string(),
208
- title: z2.string(),
209
- priority: z2.number(),
210
- passes: z2.boolean(),
211
- completedAt: z2.string().nullable(),
212
- // Also introduced with the metrics, hence the same tolerant default.
213
- durationSeconds: z2.number().nullable().default(null),
214
- // Snapshot fields are always present on output and defaulted on input, so a
215
- // session.json written before they existed still parses. This is the mirror
216
- // image of userStorySchema, where the same two fields are plainly optional.
217
- status: userStoryStatusSchema.default("backlog"),
218
- dependencies: z2.array(z2.string()).default([]),
219
- // Published for the panel's story detail view. Same tolerant default as the
220
- // fields above: absent (older session.json) and empty resolve to the same
221
- // value, so the client never has to tell them apart.
222
- description: z2.string().default(""),
223
- acceptanceCriteria: z2.array(z2.string()).default([]),
224
- // Additive like the rest of this schema: a session.json written before
225
- // `stage` existed parses into 'pending'/null, the same values a fresh
226
- // snapshot starts a story at.
227
- stage: storyStageSchema.default("pending"),
228
- stageSince: z2.string().nullable().default(null),
229
- stageDetail: z2.string().nullable().default(null),
230
- ...sessionUsageShape
231
- });
232
- var sessionSnapshotSchema = z2.object({
233
- schemaVersion: z2.literal(1),
234
- sessionId: z2.string().nullable(),
235
- readOnly: z2.literal(true),
236
- capabilities: z2.array(z2.string()),
237
- issue: z2.object({
238
- number: z2.number().nullable(),
239
- url: z2.string().nullable(),
240
- // Additive: a session.json written before the Issue section was enriched
241
- // parses into the same "not reported" values createInitialSnapshot() uses.
242
- title: z2.string().nullable().default(null),
243
- description: z2.string().nullable().default(null),
244
- labels: z2.array(z2.string()).default([]),
245
- state: z2.string().nullable().default(null)
246
- }),
247
- status: z2.enum(["idle", "running", "completed", "failed"]),
248
- startedAt: z2.string().nullable(),
249
- updatedAt: z2.string().nullable(),
250
- endedAt: z2.string().nullable(),
251
- elapsedSeconds: z2.number().nullable(),
252
- estimatedRemainingSeconds: z2.number().nullable(),
253
- progress: z2.object({
254
- percent: z2.number(),
255
- phasesCompleted: z2.number(),
256
- phasesTotal: z2.number(),
257
- storiesCompleted: z2.number(),
258
- storiesTotal: z2.number()
259
- }),
260
- currentPhase: z2.string().nullable(),
261
- currentActivity: z2.object({
262
- story: z2.string().nullable(),
263
- tool: z2.string().nullable(),
264
- detail: z2.string().nullable(),
265
- since: z2.string()
266
- }).nullable(),
267
- phases: z2.array(sessionPhaseSchema),
268
- stories: z2.array(sessionStorySchema),
269
- // The whole aggregate is additive: a snapshot from before it existed parses
270
- // into the same "nothing reported" object the reducer starts from.
271
- metrics: z2.object({
272
- totalInputTokens: z2.number().nullable().default(null),
273
- totalOutputTokens: z2.number().nullable().default(null),
274
- totalCacheReadTokens: z2.number().nullable().default(null),
275
- totalCacheCreationTokens: z2.number().nullable().default(null),
276
- totalCostUsd: z2.number().nullable().default(null)
277
- }).default({
278
- totalInputTokens: null,
279
- totalOutputTokens: null,
280
- totalCacheReadTokens: null,
281
- totalCacheCreationTokens: null,
282
- totalCostUsd: null
283
- }),
284
- execution: z2.object({
285
- iteration: z2.number(),
286
- retries: z2.number(),
287
- correctionCycle: z2.number(),
288
- maxCorrectionCycles: z2.number().nullable()
289
- }),
290
- git: z2.object({
291
- branch: z2.string().nullable(),
292
- baseBranch: z2.string().nullable(),
293
- commits: z2.array(z2.object({ hash: z2.string(), subject: z2.string() }))
294
- }),
295
- // Additive like the metrics aggregate: a session.json written before the
296
- // repository section existed parses into the same all-null object
297
- // createInitialSnapshot() starts from.
298
- repository: z2.object({
299
- name: z2.string().nullable().default(null),
300
- remoteUrl: z2.string().nullable().default(null),
301
- branch: z2.string().nullable().default(null),
302
- headCommit: z2.string().nullable().default(null),
303
- root: z2.string().nullable().default(null)
304
- }).default({ name: null, remoteUrl: null, branch: null, headCommit: null, root: null }),
305
- pullRequests: z2.array(z2.object({ number: z2.number(), url: z2.string(), title: z2.string() })),
306
- logs: z2.array(sessionLogEntrySchema),
307
- errors: z2.array(sessionLogEntrySchema),
308
- warnings: z2.array(sessionLogEntrySchema),
309
- lastError: z2.object({ message: z2.string(), at: z2.string() }).nullable(),
310
- nextSteps: z2.array(z2.string()),
311
- environment: z2.object({ node: z2.string(), platform: z2.string() }).nullable()
312
- });
313
- var webConfigSchema = z2.object({
314
- enabled: z2.boolean().default(false),
315
- port: z2.number().int().min(1).max(65535).default(3737),
316
- host: z2.string().min(1).default("0.0.0.0"),
317
- refreshSeconds: z2.number().positive().default(5),
318
- logLimit: z2.number().int().positive().default(200),
319
- includeLogs: z2.boolean().default(true)
320
- });
321
- var issuesConfigSchema = z2.object({
322
- defaultGenerateTarget: z2.enum(["github", "local", "both"]).default("github"),
323
- preferredProvider: z2.enum(["github", "local"]).default("github"),
324
- conflictPolicy: z2.enum(["ask", "prefer-local", "prefer-github"]).default("ask"),
325
- requireConfirmation: z2.boolean().default(true)
326
- });
327
- var prReviewConfigSchema = z2.object({
328
- publisher: z2.enum(["local"]).default("local")
329
- });
2
+ import {
3
+ setTelemetrySessionId
4
+ } from "./chunk-P3LRUNC6.js";
5
+ import {
6
+ isoNow
7
+ } from "./chunk-DIG5XKQQ.js";
330
8
 
331
9
  // src/core/session-state.ts
332
- import { mkdir, rename, writeFile } from "fs/promises";
10
+ import { mkdir, rename, utimes, writeFile } from "fs/promises";
333
11
  import { dirname } from "path";
334
12
  import { stripVTControlCharacters } from "util";
335
13
  var DEFAULT_LOG_LIMIT = 200;
336
14
  var DEFAULT_THROTTLE_MS = 1e3;
15
+ var DEFAULT_SESSION_HEARTBEAT_MS = 1e4;
337
16
  function emptyUsage() {
338
17
  return {
339
18
  inputTokens: null,
@@ -343,6 +22,16 @@ function emptyUsage() {
343
22
  costUsd: null
344
23
  };
345
24
  }
25
+ function emptyPhaseTiming() {
26
+ return {
27
+ harnessExecutionMs: null,
28
+ orchestrationOverheadMs: null,
29
+ harnessStartupMs: null,
30
+ ttftMs: null,
31
+ attemptCount: null,
32
+ retryDurationMs: null
33
+ };
34
+ }
346
35
  function emptyMetrics() {
347
36
  return {
348
37
  totalInputTokens: null,
@@ -378,6 +67,14 @@ function createInitialSnapshot() {
378
67
  stories: [],
379
68
  metrics: emptyMetrics(),
380
69
  execution: { iteration: 0, retries: 0, correctionCycle: 0, maxCorrectionCycles: null },
70
+ resilience: {
71
+ attempt: 0,
72
+ provider: null,
73
+ model: null,
74
+ lastFailureKind: null,
75
+ cooldownUntil: null,
76
+ lastActivityAt: null
77
+ },
381
78
  git: { branch: null, baseBranch: null, commits: [] },
382
79
  repository: { name: null, remoteUrl: null, branch: null, headCommit: null, root: null },
383
80
  pullRequests: [],
@@ -386,7 +83,8 @@ function createInitialSnapshot() {
386
83
  warnings: [],
387
84
  lastError: null,
388
85
  nextSteps: [],
389
- environment: null
86
+ environment: null,
87
+ verification: null
390
88
  };
391
89
  }
392
90
  function accumulate(current, delta) {
@@ -481,6 +179,7 @@ function deriveStageOnStoriesUpdate(story, before, at) {
481
179
  function applyEvent(snapshot, event, options) {
482
180
  switch (event.type) {
483
181
  case "session:start": {
182
+ setTelemetrySessionId(event.sessionId);
484
183
  const initial = createInitialSnapshot();
485
184
  return {
486
185
  ...initial,
@@ -499,6 +198,7 @@ function applyEvent(snapshot, event, options) {
499
198
  endedAt: null,
500
199
  durationSeconds: null,
501
200
  error: null,
201
+ ...emptyPhaseTiming(),
502
202
  ...emptyUsage()
503
203
  })),
504
204
  git: { branch: event.branch ?? null, baseBranch: event.baseBranch ?? null, commits: [] },
@@ -507,7 +207,12 @@ function applyEvent(snapshot, event, options) {
507
207
  // keeps git.branch and repository.branch consistent for a poll that
508
208
  // lands before the first git:update.
509
209
  repository: { ...initial.repository, branch: event.branch ?? null },
510
- environment: event.environment ?? null
210
+ environment: event.environment ? {
211
+ node: event.environment.node,
212
+ platform: event.environment.platform,
213
+ agent: event.environment.agent ?? null,
214
+ model: event.environment.model ?? null
215
+ } : null
511
216
  };
512
217
  }
513
218
  case "issue:update":
@@ -545,6 +250,7 @@ function applyEvent(snapshot, event, options) {
545
250
  endedAt: null,
546
251
  durationSeconds: null,
547
252
  error: null,
253
+ ...emptyPhaseTiming(),
548
254
  ...emptyUsage()
549
255
  }
550
256
  ];
@@ -566,7 +272,13 @@ function applyEvent(snapshot, event, options) {
566
272
  status: event.success ? "completed" : "failed",
567
273
  endedAt: event.at,
568
274
  durationSeconds: secondsBetween(p.startedAt, event.at),
569
- error: event.error ? stripVTControlCharacters(event.error) : null
275
+ error: event.error ? stripVTControlCharacters(event.error) : null,
276
+ harnessExecutionMs: event.harnessExecutionMs ?? p.harnessExecutionMs,
277
+ orchestrationOverheadMs: event.orchestrationOverheadMs ?? p.orchestrationOverheadMs,
278
+ harnessStartupMs: event.harnessStartupMs ?? p.harnessStartupMs,
279
+ ttftMs: event.ttftMs ?? p.ttftMs,
280
+ attemptCount: event.attemptCount ?? p.attemptCount,
281
+ retryDurationMs: event.retryDurationMs ?? p.retryDurationMs
570
282
  } : p
571
283
  );
572
284
  const phasesCompleted = phases.filter((p) => p.status === "completed").length;
@@ -616,6 +328,48 @@ function applyEvent(snapshot, event, options) {
616
328
  ...snapshot,
617
329
  execution: { ...snapshot.execution, retries: snapshot.execution.retries + 1 }
618
330
  };
331
+ case "agent:attempt":
332
+ return {
333
+ ...snapshot,
334
+ resilience: {
335
+ ...snapshot.resilience,
336
+ attempt: event.attempt,
337
+ provider: event.provider,
338
+ model: event.model ?? null,
339
+ lastActivityAt: event.at
340
+ }
341
+ };
342
+ case "failover":
343
+ return {
344
+ ...snapshot,
345
+ resilience: {
346
+ ...snapshot.resilience,
347
+ provider: event.to,
348
+ lastFailureKind: event.reason,
349
+ cooldownUntil: event.cooldownUntil ?? null,
350
+ lastActivityAt: event.at
351
+ }
352
+ };
353
+ case "agent:result":
354
+ return {
355
+ ...snapshot,
356
+ resilience: {
357
+ ...snapshot.resilience,
358
+ provider: event.provider,
359
+ lastFailureKind: event.failureKind ?? snapshot.resilience.lastFailureKind,
360
+ cooldownUntil: event.cooldownUntil ?? null,
361
+ lastActivityAt: event.at
362
+ }
363
+ };
364
+ case "agent:activity":
365
+ return {
366
+ ...snapshot,
367
+ resilience: {
368
+ ...snapshot.resilience,
369
+ provider: event.provider,
370
+ lastActivityAt: event.at
371
+ }
372
+ };
619
373
  case "stories:update": {
620
374
  const previous = new Map(snapshot.stories.map((story) => [story.id, story]));
621
375
  const stories = event.stories.map((story) => {
@@ -662,7 +416,11 @@ function applyEvent(snapshot, event, options) {
662
416
  const detail = event.detail ?? null;
663
417
  const current = snapshot.currentActivity;
664
418
  const since = current && current.story === story && current.tool === tool && current.detail === detail ? current.since : event.at;
665
- return { ...snapshot, currentActivity: { story, tool, detail, since } };
419
+ return {
420
+ ...snapshot,
421
+ currentActivity: { story, tool, detail, since },
422
+ resilience: { ...snapshot.resilience, lastActivityAt: event.at }
423
+ };
666
424
  }
667
425
  case "log": {
668
426
  const limit = options?.logLimit ?? DEFAULT_LOG_LIMIT;
@@ -746,6 +504,15 @@ function applyEvent(snapshot, event, options) {
746
504
  }
747
505
  };
748
506
  }
507
+ case "verify:end":
508
+ return {
509
+ ...snapshot,
510
+ verification: {
511
+ verdict: event.verdict,
512
+ level: event.level,
513
+ independence: event.independence
514
+ }
515
+ };
749
516
  case "session:end":
750
517
  return {
751
518
  ...snapshot,
@@ -835,6 +602,7 @@ var FilePublisher = class extends MemoryPublisher {
835
602
  filePath;
836
603
  throttleMs;
837
604
  timer = null;
605
+ heartbeatTimer = null;
838
606
  lastWriteStartedAt = 0;
839
607
  lastWrittenVersion = 0;
840
608
  writeChain = Promise.resolve();
@@ -843,10 +611,15 @@ var FilePublisher = class extends MemoryPublisher {
843
611
  super(options);
844
612
  this.filePath = filePath;
845
613
  this.throttleMs = options.throttleMs ?? DEFAULT_THROTTLE_MS;
614
+ const heartbeatMs = options.heartbeatMs ?? DEFAULT_SESSION_HEARTBEAT_MS;
615
+ if (heartbeatMs > 0) {
616
+ this.heartbeatTimer = setInterval(() => this.enqueueHeartbeat(), heartbeatMs);
617
+ this.heartbeatTimer.unref();
618
+ }
846
619
  }
847
620
  afterPublish(event) {
848
621
  if (this.closed) return;
849
- const terminal = event.type === "phase:end" || event.type === "session:end";
622
+ const terminal = event.type === "phase:end" || event.type === "session:end" || event.type === "verify:end";
850
623
  this.scheduleWrite(terminal);
851
624
  }
852
625
  scheduleWrite(force) {
@@ -885,6 +658,24 @@ var FilePublisher = class extends MemoryPublisher {
885
658
  }
886
659
  });
887
660
  }
661
+ /**
662
+ * Keep directory-based discovery alive without changing snapshot content or
663
+ * its content-derived ETag. The write chain serializes the touch with atomic
664
+ * snapshot replacement, and no heartbeat is attempted before the first file
665
+ * has been written successfully.
666
+ */
667
+ enqueueHeartbeat() {
668
+ if (this.closed) return;
669
+ this.writeChain = this.writeChain.then(async () => {
670
+ if (this.closed || this.lastWrittenVersion === 0) return;
671
+ const now = /* @__PURE__ */ new Date();
672
+ try {
673
+ await utimes(this.filePath, now, now);
674
+ } catch (err) {
675
+ this.warnOnce(err);
676
+ }
677
+ });
678
+ }
888
679
  async flush() {
889
680
  if (this.timer !== null) {
890
681
  clearTimeout(this.timer);
@@ -896,8 +687,12 @@ var FilePublisher = class extends MemoryPublisher {
896
687
  await this.writeChain;
897
688
  }
898
689
  async close() {
899
- await this.flush();
690
+ if (this.heartbeatTimer !== null) {
691
+ clearInterval(this.heartbeatTimer);
692
+ this.heartbeatTimer = null;
693
+ }
900
694
  this.closed = true;
695
+ await this.flush();
901
696
  }
902
697
  };
903
698
  async function atomicWriteFile(path, content) {
@@ -917,230 +712,6 @@ function getSessionPublisher() {
917
712
  return _publisher;
918
713
  }
919
714
 
920
- // src/core/state-manager.ts
921
- import { readFile } from "fs/promises";
922
- import { ZodError } from "zod";
923
-
924
- // src/utils/fs.ts
925
- import { copyFile, mkdtemp, rename as rename2, unlink, writeFile as writeFile2 } from "fs/promises";
926
- import { tmpdir } from "os";
927
- import { basename, join } from "path";
928
- async function writeFileAtomic(path, content) {
929
- const tmpDir = await mkdtemp(join(tmpdir(), "issue-flow-"));
930
- const tmpFile = join(tmpDir, basename(path));
931
- await writeFile2(tmpFile, content, "utf-8");
932
- try {
933
- await rename2(tmpFile, path);
934
- } catch (err) {
935
- if (err.code === "EXDEV") {
936
- await copyFile(tmpFile, path);
937
- await unlink(tmpFile);
938
- } else {
939
- throw err;
940
- }
941
- }
942
- }
943
-
944
- // src/core/metrics.ts
945
- var USAGE_FIELDS = [
946
- "inputTokens",
947
- "outputTokens",
948
- "cacheReadTokens",
949
- "cacheCreationTokens",
950
- "costUsd"
951
- ];
952
- function num(value) {
953
- return typeof value === "number" && Number.isFinite(value) ? value : void 0;
954
- }
955
- function isRecord(value) {
956
- return typeof value === "object" && value !== null;
957
- }
958
- function parseUsage(payload) {
959
- if (!isRecord(payload)) return null;
960
- const usageRaw = isRecord(payload.usage) ? payload.usage : void 0;
961
- const usage = {};
962
- const inputTokens = usageRaw ? num(usageRaw.input_tokens) : void 0;
963
- const outputTokens = usageRaw ? num(usageRaw.output_tokens) : void 0;
964
- const cacheReadTokens = usageRaw ? num(usageRaw.cache_read_input_tokens) : void 0;
965
- const cacheCreationTokens = usageRaw ? num(usageRaw.cache_creation_input_tokens) : void 0;
966
- const costUsd = num(payload.total_cost_usd);
967
- const legacyInput = num(payload.num_input_tokens);
968
- const legacyOutput = num(payload.num_output_tokens);
969
- const legacyCost = num(payload.cost_usd);
970
- const resolvedInput = inputTokens ?? legacyInput;
971
- const resolvedOutput = outputTokens ?? legacyOutput;
972
- const resolvedCost = costUsd ?? legacyCost;
973
- if (resolvedInput !== void 0) usage.inputTokens = resolvedInput;
974
- if (resolvedOutput !== void 0) usage.outputTokens = resolvedOutput;
975
- if (cacheReadTokens !== void 0) usage.cacheReadTokens = cacheReadTokens;
976
- if (cacheCreationTokens !== void 0) usage.cacheCreationTokens = cacheCreationTokens;
977
- if (resolvedCost !== void 0) usage.costUsd = resolvedCost;
978
- return Object.keys(usage).length > 0 ? usage : null;
979
- }
980
- function sumUsage(a, b) {
981
- const result = {};
982
- for (const field of USAGE_FIELDS) {
983
- const left = a?.[field];
984
- const right = b?.[field];
985
- if (left === void 0 && right === void 0) continue;
986
- result[field] = (left ?? 0) + (right ?? 0);
987
- }
988
- return result;
989
- }
990
- function divideUsage(usage, parts) {
991
- const result = {};
992
- if (!usage) return result;
993
- const divisor = Number.isFinite(parts) && parts > 1 ? parts : 1;
994
- for (const field of USAGE_FIELDS) {
995
- const value = usage[field];
996
- if (value === void 0) continue;
997
- result[field] = field === "costUsd" ? value / divisor : Math.round(value / divisor);
998
- }
999
- return result;
1000
- }
1001
- function compactTokens(value) {
1002
- const abs = Math.abs(value);
1003
- if (abs >= 1e6) return `${(value / 1e6).toFixed(1)}M`;
1004
- if (abs >= 1e3) return `${(value / 1e3).toFixed(1)}k`;
1005
- return String(Math.round(value));
1006
- }
1007
- function formatTokens(usage) {
1008
- if (!usage) return "";
1009
- const segments = [];
1010
- const io = [];
1011
- if (usage.inputTokens !== void 0) io.push(`${compactTokens(usage.inputTokens)} in`);
1012
- if (usage.outputTokens !== void 0) io.push(`${compactTokens(usage.outputTokens)} out`);
1013
- if (io.length > 0) segments.push(io.join(" / "));
1014
- const cache = usage.cacheReadTokens !== void 0 || usage.cacheCreationTokens !== void 0 ? (usage.cacheReadTokens ?? 0) + (usage.cacheCreationTokens ?? 0) : void 0;
1015
- if (cache !== void 0) segments.push(`${compactTokens(cache)} cache`);
1016
- if (usage.costUsd !== void 0) segments.push(`~$${usage.costUsd.toFixed(4)}`);
1017
- return segments.join(" \xB7 ");
1018
- }
1019
- function hasUsageData(usage) {
1020
- if (!usage) return false;
1021
- return USAGE_FIELDS.some((field) => usage[field] !== void 0);
1022
- }
1023
-
1024
- // src/core/state-manager.ts
1025
- function isoNow() {
1026
- return (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
1027
- }
1028
- async function loadTaskPlan(path) {
1029
- const content = await readFile(path, "utf-8");
1030
- const raw = JSON.parse(content);
1031
- try {
1032
- return taskPlanSchema.parse(raw);
1033
- } catch (err) {
1034
- if (err instanceof ZodError) {
1035
- const issues = err.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n");
1036
- throw new Error(`Invalid tasks.json at ${path}:
1037
- ${issues}`);
1038
- }
1039
- throw err;
1040
- }
1041
- }
1042
- async function saveTaskPlan(path, plan) {
1043
- await writeFileAtomic(path, `${JSON.stringify(plan, null, 2)}
1044
- `);
1045
- }
1046
- function initializeState(plan) {
1047
- const defaultPipeline = {
1048
- prdCompleted: false,
1049
- jsonCompleted: false,
1050
- executionCompleted: false,
1051
- reviewCompleted: false,
1052
- prCreated: false
1053
- };
1054
- return {
1055
- ...plan,
1056
- issueStatus: plan.issueStatus ?? "pending",
1057
- completedAt: plan.completedAt ?? null,
1058
- lastAttemptAt: plan.lastAttemptAt ?? null,
1059
- lastError: plan.lastError ?? null,
1060
- correctionCycle: plan.correctionCycle ?? 0,
1061
- maxCorrectionCycles: plan.maxCorrectionCycles ?? 3,
1062
- lastReviewFindings: plan.lastReviewFindings ?? null,
1063
- pipeline: plan.pipeline ? { ...defaultPipeline, ...plan.pipeline } : defaultPipeline
1064
- };
1065
- }
1066
- function hasPendingCorrection(plan) {
1067
- return Boolean(plan.lastReviewFindings);
1068
- }
1069
- function allStoriesPass(plan) {
1070
- if (plan.userStories.length === 0) {
1071
- return false;
1072
- }
1073
- return plan.userStories.every((story) => story.passes === true);
1074
- }
1075
- function selectActiveStory(stories) {
1076
- return [...stories].filter((story) => !story.passes).sort((a, b) => a.priority - b.priority)[0];
1077
- }
1078
- function applyStoryMetrics(plan, storyIds, share, durationSeconds) {
1079
- if (storyIds.length === 0) return plan;
1080
- const targets = new Set(storyIds);
1081
- return {
1082
- ...plan,
1083
- userStories: plan.userStories.map((story) => {
1084
- if (!targets.has(story.id)) return story;
1085
- const updated = { ...story, ...sumUsage(story, share) };
1086
- if (story.durationSeconds !== void 0 || durationSeconds !== void 0) {
1087
- updated.durationSeconds = (story.durationSeconds ?? 0) + (durationSeconds ?? 0);
1088
- }
1089
- return updated;
1090
- })
1091
- };
1092
- }
1093
- function markIssueInProgress(plan, timestamp) {
1094
- const ts = timestamp ?? isoNow();
1095
- return {
1096
- ...plan,
1097
- issueStatus: "in_progress",
1098
- completedAt: null,
1099
- lastAttemptAt: ts
1100
- };
1101
- }
1102
- function markIssueCompleted(plan) {
1103
- const ts = isoNow();
1104
- return {
1105
- ...plan,
1106
- issueStatus: "completed",
1107
- completedAt: ts,
1108
- lastAttemptAt: ts,
1109
- lastError: null,
1110
- pipeline: plan.pipeline ? { ...plan.pipeline, executionCompleted: true } : plan.pipeline
1111
- };
1112
- }
1113
- function setLastError(plan, category, message) {
1114
- const ts = isoNow();
1115
- const error = {
1116
- category,
1117
- message,
1118
- at: ts
1119
- };
1120
- return {
1121
- ...plan,
1122
- lastAttemptAt: ts,
1123
- lastError: error
1124
- };
1125
- }
1126
- function clearLastError(plan, attemptStartedAt) {
1127
- const ts = isoNow();
1128
- if (plan.lastError && plan.lastError.at > attemptStartedAt) {
1129
- return {
1130
- ...plan,
1131
- lastAttemptAt: ts
1132
- };
1133
- }
1134
- return {
1135
- ...plan,
1136
- lastAttemptAt: ts,
1137
- lastError: null
1138
- };
1139
- }
1140
- function trimErrorMessage(message) {
1141
- return message.split("\n").filter((line) => line.trim().length > 0).slice(0, 8).join("\n");
1142
- }
1143
-
1144
715
  // src/core/verbose.ts
1145
716
  var _verbose = false;
1146
717
  function setVerbose(enabled) {
@@ -1170,6 +741,13 @@ function setStoryStageCallback(callback) {
1170
741
  function getStoryStageCallback() {
1171
742
  return _onStoryStage;
1172
743
  }
744
+ var _onActivity;
745
+ function setActivityCallback(callback) {
746
+ _onActivity = callback;
747
+ }
748
+ function getActivityCallback() {
749
+ return _onActivity;
750
+ }
1173
751
  var _globalTimeout;
1174
752
  function setGlobalTimeout(ms) {
1175
753
  _globalTimeout = ms;
@@ -1177,6 +755,13 @@ function setGlobalTimeout(ms) {
1177
755
  function getGlobalTimeout() {
1178
756
  return _globalTimeout;
1179
757
  }
758
+ var _inactivityTimeout;
759
+ function setInactivityTimeout(ms) {
760
+ _inactivityTimeout = ms;
761
+ }
762
+ function getInactivityTimeout() {
763
+ return _inactivityTimeout;
764
+ }
1180
765
 
1181
766
  // src/ui/logger.ts
1182
767
  import chalk from "chalk";
@@ -1203,7 +788,8 @@ function getIcons() {
1203
788
  end: "\u25A0",
1204
789
  notReached: "\u25CB",
1205
790
  tool: "\u25B8",
1206
- connector: "\u2502"
791
+ connector: "\u2502",
792
+ info: "\xB7"
1207
793
  };
1208
794
  }
1209
795
  return {
@@ -1216,7 +802,8 @@ function getIcons() {
1216
802
  end: "[END]",
1217
803
  notReached: "[ ]",
1218
804
  tool: ">",
1219
- connector: "|"
805
+ connector: "|",
806
+ info: "-"
1220
807
  };
1221
808
  }
1222
809
  function getTermWidth() {
@@ -1266,9 +853,9 @@ function printRetry(message) {
1266
853
  function printInfo(message) {
1267
854
  const icons = getIcons();
1268
855
  if (useColor()) {
1269
- emit(chalk.blue(`${icons.start} ${message}`));
856
+ emit(chalk.blue(`${icons.info} ${message}`));
1270
857
  } else {
1271
- emit(`${icons.start} ${message}`);
858
+ emit(`${icons.info} ${message}`);
1272
859
  }
1273
860
  }
1274
861
  function createSpinner(message) {
@@ -1325,38 +912,13 @@ var ElapsedTimer = class {
1325
912
  };
1326
913
 
1327
914
  export {
1328
- policyConfigSchema,
1329
- policyConfigInputSchema,
1330
- pullRequestRefSchema,
1331
- issueMetadataSchema,
1332
- taskPlanSchema,
1333
- sessionSnapshotSchema,
1334
- webConfigSchema,
1335
- issuesConfigSchema,
1336
- prReviewConfigSchema,
915
+ createInitialSnapshot,
916
+ reduceSessionEvent,
1337
917
  NullPublisher,
918
+ MemoryPublisher,
1338
919
  FilePublisher,
1339
920
  setSessionPublisher,
1340
921
  getSessionPublisher,
1341
- writeFileAtomic,
1342
- parseUsage,
1343
- sumUsage,
1344
- divideUsage,
1345
- formatTokens,
1346
- hasUsageData,
1347
- isoNow,
1348
- loadTaskPlan,
1349
- saveTaskPlan,
1350
- initializeState,
1351
- hasPendingCorrection,
1352
- allStoriesPass,
1353
- selectActiveStory,
1354
- applyStoryMetrics,
1355
- markIssueInProgress,
1356
- markIssueCompleted,
1357
- setLastError,
1358
- clearLastError,
1359
- trimErrorMessage,
1360
922
  setVerbose,
1361
923
  isVerbose,
1362
924
  setOutputCallback,
@@ -1365,8 +927,12 @@ export {
1365
927
  getStoryUpdateCallback,
1366
928
  setStoryStageCallback,
1367
929
  getStoryStageCallback,
930
+ setActivityCallback,
931
+ getActivityCallback,
1368
932
  setGlobalTimeout,
1369
933
  getGlobalTimeout,
934
+ setInactivityTimeout,
935
+ getInactivityTimeout,
1370
936
  useUnicode,
1371
937
  useColor,
1372
938
  getIcons,
@@ -1380,4 +946,4 @@ export {
1380
946
  formatDuration,
1381
947
  ElapsedTimer
1382
948
  };
1383
- //# sourceMappingURL=chunk-HC2MT7BX.js.map
949
+ //# sourceMappingURL=chunk-IYV6KNVF.js.map