issue-flow 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/dist/agent-TB6W7PT7.js +30 -0
  2. package/dist/{analyze-O2PYDIFK.js → analyze-6M3KEOX7.js} +22 -22
  3. package/dist/{apply-SSU6QCD4.js → apply-ADB3ZK7W.js} +14 -14
  4. package/dist/{bench-ODFPAGW6.js → bench-FM7I7EIV.js} +23 -23
  5. package/dist/{chunk-BMHGRYL6.js → chunk-2SUFAE6X.js} +67 -24
  6. package/dist/chunk-2SUFAE6X.js.map +1 -0
  7. package/dist/{chunk-QRCGW2ZO.js → chunk-32JSYXEK.js} +8 -8
  8. package/dist/chunk-3R27MJ5R.js +25 -0
  9. package/dist/chunk-3R27MJ5R.js.map +1 -0
  10. package/dist/{chunk-MGCOQU6N.js → chunk-6YQT3SSM.js} +4 -4
  11. package/dist/chunk-6YQT3SSM.js.map +1 -0
  12. package/dist/{chunk-A35HE4V7.js → chunk-7F7LGMVO.js} +3 -3
  13. package/dist/{chunk-RPXDBX6R.js → chunk-A4H7P7T7.js} +102 -102
  14. package/dist/chunk-A4H7P7T7.js.map +1 -0
  15. package/dist/{chunk-2ZAM45PZ.js → chunk-ANI2NTR4.js} +9 -9
  16. package/dist/{chunk-ZPIVCM7Q.js → chunk-B3TSS7BT.js} +3 -3
  17. package/dist/chunk-C5TL7T4V.js +27 -0
  18. package/dist/chunk-C5TL7T4V.js.map +1 -0
  19. package/dist/chunk-D6ZBGJ3L.js +321 -0
  20. package/dist/chunk-D6ZBGJ3L.js.map +1 -0
  21. package/dist/{chunk-ZXPASFHG.js → chunk-DGRTJD5R.js} +3 -3
  22. package/dist/{chunk-6QYMSNVA.js → chunk-DUS5ZNKL.js} +476 -362
  23. package/dist/chunk-DUS5ZNKL.js.map +1 -0
  24. package/dist/{chunk-VR34TXHF.js → chunk-DV7HUC4Z.js} +7 -7
  25. package/dist/{chunk-6SRE4KD7.js → chunk-E6KXCV3T.js} +4 -4
  26. package/dist/{chunk-HGSYD57B.js → chunk-HJBF4WD2.js} +1656 -1070
  27. package/dist/chunk-HJBF4WD2.js.map +1 -0
  28. package/dist/{chunk-PCN7ZQND.js → chunk-HLAPOUEM.js} +8 -8
  29. package/dist/{chunk-WM3Y7Q4A.js → chunk-HY5HLFDU.js} +630 -571
  30. package/dist/chunk-HY5HLFDU.js.map +1 -0
  31. package/dist/{chunk-XDKGA6UX.js → chunk-ICM463EO.js} +64 -14
  32. package/dist/chunk-ICM463EO.js.map +1 -0
  33. package/dist/{chunk-MEFY4B7T.js → chunk-ISZ54SVE.js} +9 -9
  34. package/dist/{chunk-ARWNYXFL.js → chunk-KZ5EY5XX.js} +12 -12
  35. package/dist/{chunk-ZFIXEYUJ.js → chunk-KZXQWC7U.js} +32 -20
  36. package/dist/chunk-KZXQWC7U.js.map +1 -0
  37. package/dist/{chunk-KAHQ6F5C.js → chunk-LPWPFIIB.js} +11 -11
  38. package/dist/{chunk-FK4IDY6P.js → chunk-MI5TREN3.js} +9 -9
  39. package/dist/{chunk-UNQYMR3H.js → chunk-PPZ3K4YM.js} +2 -2
  40. package/dist/{chunk-F4OK7KEP.js → chunk-QMIQR7EE.js} +10 -10
  41. package/dist/{chunk-AYYMW33T.js → chunk-QPGEFLMY.js} +2 -2
  42. package/dist/chunk-RCZJQUTC.js +196 -0
  43. package/dist/chunk-RCZJQUTC.js.map +1 -0
  44. package/dist/{chunk-MROS3SKL.js → chunk-RNFUVKC3.js} +3 -3
  45. package/dist/{chunk-RWEXK55D.js → chunk-RYOUZ6EK.js} +2 -2
  46. package/dist/{chunk-6E2PEBFT.js → chunk-SGTTR4XW.js} +10 -10
  47. package/dist/{chunk-XQHFC62U.js → chunk-SOM4QA6C.js} +3 -3
  48. package/dist/{chunk-5ZKBIXET.js → chunk-UK4E2FUA.js} +132 -34
  49. package/dist/chunk-UK4E2FUA.js.map +1 -0
  50. package/dist/{chunk-6FXOU2KR.js → chunk-UWDCIFTP.js} +7 -7
  51. package/dist/{chunk-XG2NYDRA.js → chunk-VE3IYNDN.js} +3 -3
  52. package/dist/{chunk-3BWZO4YI.js → chunk-WCCZJL7W.js} +2 -2
  53. package/dist/{chunk-NVZMBXTE.js → chunk-XZUEFTUP.js} +6 -6
  54. package/dist/{chunk-TBDP6QPJ.js → chunk-YII4U7ZD.js} +10 -10
  55. package/dist/{chunk-TBDP6QPJ.js.map → chunk-YII4U7ZD.js.map} +1 -1
  56. package/dist/{chunk-4RXYFWP7.js → chunk-YUNBOUQH.js} +6 -6
  57. package/dist/{chunk-GSZCQUCY.js → chunk-YVPZUN6X.js} +2 -2
  58. package/dist/{chunk-XRLRKTQA.js → chunk-Z5O2XBWA.js} +14 -14
  59. package/dist/cli.js +61 -52
  60. package/dist/cli.js.map +1 -1
  61. package/dist/{config-UMP6DBJB.js → config-KGZUPAUP.js} +13 -13
  62. package/dist/{conventions-DKH7AE4T.js → conventions-RYN7OXJN.js} +15 -15
  63. package/dist/{diagnostics-GOGCLTRS.js → diagnostics-HTCWF7F4.js} +7 -7
  64. package/dist/execute-QL3ZQIAP.js +37 -0
  65. package/dist/{generate-AGBT7EHX.js → generate-CX6KNHZS.js} +22 -22
  66. package/dist/{git-AC542GU2.js → git-A2IP32PQ.js} +2 -2
  67. package/dist/init-PDVQDRS6.js +24 -0
  68. package/dist/{operations-JQYK2EMT.js → operations-CAKIT2BO.js} +15 -15
  69. package/dist/{permissions-6HL52K54.js → permissions-G4XCAESF.js} +4 -4
  70. package/dist/plan-PRORGS3L.js +34 -0
  71. package/dist/{policy-IMRXGG7X.js → policy-WX6O2JID.js} +14 -14
  72. package/dist/pr-27RMQI5F.js +39 -0
  73. package/dist/pr-review-VNESMAMT.js +32 -0
  74. package/dist/prd-ZNC4T5BS.js +33 -0
  75. package/dist/{ps-KUUZ6TUL.js → ps-76L6ZAZL.js} +12 -12
  76. package/dist/{recorder-BJ2KIAWT.js → recorder-N7U66HCO.js} +7 -7
  77. package/dist/{registry-SB7XTMGE.js → registry-XLHHYLTR.js} +5 -5
  78. package/dist/{resume-QNLQSCR5.js → resume-VLWIE264.js} +40 -38
  79. package/dist/{resume-QNLQSCR5.js.map → resume-VLWIE264.js.map} +1 -1
  80. package/dist/review-7CREJDKB.js +35 -0
  81. package/dist/routing-VCDYHSXA.js +33 -0
  82. package/dist/run-3MPORLF5.js +56 -0
  83. package/dist/{session-publisher-T7EI3CIP.js → session-publisher-KAJQRHNZ.js} +3 -2
  84. package/dist/{state-manager-ZEPWTCA6.js → state-manager-UPHO2EA2.js} +4 -4
  85. package/dist/state-manager-UPHO2EA2.js.map +1 -0
  86. package/dist/{usage-QL563I7F.js → usage-U7QNGCPK.js} +12 -12
  87. package/dist/{web-PPSMNTQ6.js → web-HUNDHCJ4.js} +21 -18
  88. package/dist/{web-PPSMNTQ6.js.map → web-HUNDHCJ4.js.map} +1 -1
  89. package/package.json +6 -5
  90. package/web/AGENTS.md +15 -11
  91. package/web/public/app.css +51 -0
  92. package/web/public/app.js +325 -56
  93. package/web/public/index.html +6 -2
  94. package/dist/agent-AT64RXTA.js +0 -30
  95. package/dist/chunk-5ZKBIXET.js.map +0 -1
  96. package/dist/chunk-6QYMSNVA.js.map +0 -1
  97. package/dist/chunk-7Z4Y3VKM.js +0 -26
  98. package/dist/chunk-7Z4Y3VKM.js.map +0 -1
  99. package/dist/chunk-BMHGRYL6.js.map +0 -1
  100. package/dist/chunk-HGSYD57B.js.map +0 -1
  101. package/dist/chunk-MGCOQU6N.js.map +0 -1
  102. package/dist/chunk-RPXDBX6R.js.map +0 -1
  103. package/dist/chunk-WM3Y7Q4A.js.map +0 -1
  104. package/dist/chunk-XDKGA6UX.js.map +0 -1
  105. package/dist/chunk-XLVGPXNL.js +0 -180
  106. package/dist/chunk-XLVGPXNL.js.map +0 -1
  107. package/dist/chunk-ZFIXEYUJ.js.map +0 -1
  108. package/dist/execute-E3BRMDAQ.js +0 -35
  109. package/dist/init-LLBVJNPE.js +0 -24
  110. package/dist/plan-HSLWDJEZ.js +0 -34
  111. package/dist/pr-6TCZXG6K.js +0 -39
  112. package/dist/pr-review-6MWJO2NP.js +0 -32
  113. package/dist/prd-D6YDYAFX.js +0 -33
  114. package/dist/review-3KJ4BH2V.js +0 -35
  115. package/dist/routing-TN7GLMGU.js +0 -94
  116. package/dist/routing-TN7GLMGU.js.map +0 -1
  117. package/dist/run-5EHIFF2V.js +0 -54
  118. /package/dist/{agent-AT64RXTA.js.map → agent-TB6W7PT7.js.map} +0 -0
  119. /package/dist/{analyze-O2PYDIFK.js.map → analyze-6M3KEOX7.js.map} +0 -0
  120. /package/dist/{apply-SSU6QCD4.js.map → apply-ADB3ZK7W.js.map} +0 -0
  121. /package/dist/{bench-ODFPAGW6.js.map → bench-FM7I7EIV.js.map} +0 -0
  122. /package/dist/{chunk-QRCGW2ZO.js.map → chunk-32JSYXEK.js.map} +0 -0
  123. /package/dist/{chunk-A35HE4V7.js.map → chunk-7F7LGMVO.js.map} +0 -0
  124. /package/dist/{chunk-2ZAM45PZ.js.map → chunk-ANI2NTR4.js.map} +0 -0
  125. /package/dist/{chunk-ZPIVCM7Q.js.map → chunk-B3TSS7BT.js.map} +0 -0
  126. /package/dist/{chunk-ZXPASFHG.js.map → chunk-DGRTJD5R.js.map} +0 -0
  127. /package/dist/{chunk-VR34TXHF.js.map → chunk-DV7HUC4Z.js.map} +0 -0
  128. /package/dist/{chunk-6SRE4KD7.js.map → chunk-E6KXCV3T.js.map} +0 -0
  129. /package/dist/{chunk-PCN7ZQND.js.map → chunk-HLAPOUEM.js.map} +0 -0
  130. /package/dist/{chunk-MEFY4B7T.js.map → chunk-ISZ54SVE.js.map} +0 -0
  131. /package/dist/{chunk-ARWNYXFL.js.map → chunk-KZ5EY5XX.js.map} +0 -0
  132. /package/dist/{chunk-KAHQ6F5C.js.map → chunk-LPWPFIIB.js.map} +0 -0
  133. /package/dist/{chunk-FK4IDY6P.js.map → chunk-MI5TREN3.js.map} +0 -0
  134. /package/dist/{chunk-UNQYMR3H.js.map → chunk-PPZ3K4YM.js.map} +0 -0
  135. /package/dist/{chunk-F4OK7KEP.js.map → chunk-QMIQR7EE.js.map} +0 -0
  136. /package/dist/{chunk-AYYMW33T.js.map → chunk-QPGEFLMY.js.map} +0 -0
  137. /package/dist/{chunk-MROS3SKL.js.map → chunk-RNFUVKC3.js.map} +0 -0
  138. /package/dist/{chunk-RWEXK55D.js.map → chunk-RYOUZ6EK.js.map} +0 -0
  139. /package/dist/{chunk-6E2PEBFT.js.map → chunk-SGTTR4XW.js.map} +0 -0
  140. /package/dist/{chunk-XQHFC62U.js.map → chunk-SOM4QA6C.js.map} +0 -0
  141. /package/dist/{chunk-6FXOU2KR.js.map → chunk-UWDCIFTP.js.map} +0 -0
  142. /package/dist/{chunk-XG2NYDRA.js.map → chunk-VE3IYNDN.js.map} +0 -0
  143. /package/dist/{chunk-3BWZO4YI.js.map → chunk-WCCZJL7W.js.map} +0 -0
  144. /package/dist/{chunk-NVZMBXTE.js.map → chunk-XZUEFTUP.js.map} +0 -0
  145. /package/dist/{chunk-4RXYFWP7.js.map → chunk-YUNBOUQH.js.map} +0 -0
  146. /package/dist/{chunk-GSZCQUCY.js.map → chunk-YVPZUN6X.js.map} +0 -0
  147. /package/dist/{chunk-XRLRKTQA.js.map → chunk-Z5O2XBWA.js.map} +0 -0
  148. /package/dist/{config-UMP6DBJB.js.map → config-KGZUPAUP.js.map} +0 -0
  149. /package/dist/{conventions-DKH7AE4T.js.map → conventions-RYN7OXJN.js.map} +0 -0
  150. /package/dist/{diagnostics-GOGCLTRS.js.map → diagnostics-HTCWF7F4.js.map} +0 -0
  151. /package/dist/{execute-E3BRMDAQ.js.map → execute-QL3ZQIAP.js.map} +0 -0
  152. /package/dist/{generate-AGBT7EHX.js.map → generate-CX6KNHZS.js.map} +0 -0
  153. /package/dist/{git-AC542GU2.js.map → git-A2IP32PQ.js.map} +0 -0
  154. /package/dist/{init-LLBVJNPE.js.map → init-PDVQDRS6.js.map} +0 -0
  155. /package/dist/{operations-JQYK2EMT.js.map → operations-CAKIT2BO.js.map} +0 -0
  156. /package/dist/{permissions-6HL52K54.js.map → permissions-G4XCAESF.js.map} +0 -0
  157. /package/dist/{plan-HSLWDJEZ.js.map → plan-PRORGS3L.js.map} +0 -0
  158. /package/dist/{policy-IMRXGG7X.js.map → policy-WX6O2JID.js.map} +0 -0
  159. /package/dist/{pr-6TCZXG6K.js.map → pr-27RMQI5F.js.map} +0 -0
  160. /package/dist/{pr-review-6MWJO2NP.js.map → pr-review-VNESMAMT.js.map} +0 -0
  161. /package/dist/{prd-D6YDYAFX.js.map → prd-ZNC4T5BS.js.map} +0 -0
  162. /package/dist/{ps-KUUZ6TUL.js.map → ps-76L6ZAZL.js.map} +0 -0
  163. /package/dist/{recorder-BJ2KIAWT.js.map → recorder-N7U66HCO.js.map} +0 -0
  164. /package/dist/{registry-SB7XTMGE.js.map → registry-XLHHYLTR.js.map} +0 -0
  165. /package/dist/{review-3KJ4BH2V.js.map → review-7CREJDKB.js.map} +0 -0
  166. /package/dist/{run-5EHIFF2V.js.map → routing-VCDYHSXA.js.map} +0 -0
  167. /package/dist/{session-publisher-T7EI3CIP.js.map → run-3MPORLF5.js.map} +0 -0
  168. /package/dist/{state-manager-ZEPWTCA6.js.map → session-publisher-KAJQRHNZ.js.map} +0 -0
  169. /package/dist/{usage-QL563I7F.js.map → usage-U7QNGCPK.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/session/publishers.ts","../src/core/session/events.ts","../src/core/session/derive.ts","../src/core/session/reducer-git.ts","../src/core/session/reducer-log.ts","../src/core/session/reducer-metrics.ts","../src/core/session/reducer-phase.ts","../src/core/session/reducer-stage.ts","../src/core/session/snapshot.ts","../src/core/session/reducer-resilience.ts","../src/core/session/reducer-session.ts","../src/core/session/reducer-story.ts","../src/core/session/reducer.ts","../src/core/session-publisher.ts"],"sourcesContent":["import { utimes } from 'node:fs/promises';\nimport { writeFileAtomic } from '../../utils/fs.js';\nimport { DEFAULT_SESSION_HEARTBEAT_MS, DEFAULT_THROTTLE_MS, type SessionEvent } from './events.js';\nimport { reduceSessionEvent } from './reducer.js';\nimport {\n createInitialSnapshot,\n type SessionReducerOptions,\n type SessionSnapshot,\n} from './snapshot.js';\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 /** Interval between mtime-only heartbeats (ms). Zero disables it. Default 10000. */\n heartbeatMs?: 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 heartbeatTimer: 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 const heartbeatMs = options.heartbeatMs ?? DEFAULT_SESSION_HEARTBEAT_MS;\n if (heartbeatMs > 0) {\n this.heartbeatTimer = setInterval(() => this.enqueueHeartbeat(), heartbeatMs);\n this.heartbeatTimer.unref();\n }\n }\n\n protected override afterPublish(event: SessionEvent): void {\n if (this.closed) return;\n const terminal =\n event.type === 'phase:end' || event.type === 'session:end' || event.type === 'verify: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 writeFileAtomic(this.filePath, payload);\n this.lastWrittenVersion = version;\n } catch (err) {\n this.warnOnce(err);\n }\n });\n }\n\n /**\n * Keep directory-based discovery alive without changing snapshot content or\n * its content-derived ETag. The write chain serializes the touch with atomic\n * snapshot replacement, and no heartbeat is attempted before the first file\n * has been written successfully.\n */\n private enqueueHeartbeat(): void {\n if (this.closed) return;\n this.writeChain = this.writeChain.then(async () => {\n if (this.closed || this.lastWrittenVersion === 0) return;\n const now = new Date();\n try {\n await utimes(this.filePath, now, now);\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 if (this.heartbeatTimer !== null) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n this.closed = true;\n await this.flush();\n }\n}\n","import type { FailureKind } from '../../resilience/errors.js';\nimport type { ExecutionRecord } from '../../telemetry/types.js';\nimport type { UserStory } from '../../types.js';\n\n/**\n * Session event contract: the union every publisher accepts and every reducer\n * folds. No imports from within `session/` — this module is the leaf of that\n * graph. The type-only imports below are package-level contracts the event\n * payload carries by identity (`UserStory`, `ExecutionRecord`, `FailureKind`).\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\n/** Default interval for touching a live session file without rewriting it. */\nexport const DEFAULT_SESSION_HEARTBEAT_MS = 10_000;\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 configuration?: SessionConfigurationSnapshot;\n branchCreated?: boolean | null;\n startCommit?: string | null;\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 | {\n type: 'phase:end';\n at: string;\n phase: string;\n success: boolean;\n error?: string;\n harnessExecutionMs?: number | null;\n orchestrationOverheadMs?: number | null;\n harnessStartupMs?: number | null;\n ttftMs?: number | null;\n attemptCount?: number | null;\n retryDurationMs?: number | null;\n }\n | {\n type: 'iteration:start';\n at: string;\n iteration: number;\n /**\n * Id of the story `execute` is about to work on, computed by\n * `core/engine.ts` with the same \"highest priority, `passes: false`\"\n * rule `prompts/execute.md` gives the agent. Optional so a caller that\n * cannot determine it (or an older build) is still a valid event —\n * `applyEvent` simply skips the `executing`/`pending` transition then.\n */\n storyId?: string;\n }\n | { type: 'iteration:end'; at: string; iteration: number }\n | {\n type: 'retry';\n at: string;\n attempt: number;\n delaySeconds?: number;\n reason?: string;\n /**\n * What the resilience layer classified the failure as. Optional so an\n * event written by an older build — or by a caller with nothing but a\n * message — stays valid; the reducer only counts retries either way.\n */\n kind?: FailureKind;\n }\n | {\n type: 'agent:attempt';\n at: string;\n attempt: number;\n provider: string;\n model?: string | null;\n primaryProvider: string;\n }\n | {\n type: 'failover';\n at: string;\n from: string;\n to: string;\n reason: FailureKind | null;\n cooldownUntil?: string | null;\n }\n | {\n type: 'agent:result';\n at: string;\n provider: string;\n success: boolean;\n failureKind?: FailureKind;\n cooldownUntil?: string | null;\n }\n | { type: 'agent:activity'; at: string; provider: 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 | {\n type: 'process:output';\n at: string;\n phase: string;\n executionId: string | null;\n provider: string;\n stream: 'stdout' | 'stderr' | 'combined';\n message: string;\n }\n | { type: 'execution:update'; at: string; execution: ExecutionRecord }\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 branchCreated?: boolean | null;\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 | {\n type: 'verify:end';\n at: string;\n verdict: 'passed' | 'failed' | 'unverified';\n level: string;\n independence: string | null;\n executionId: string | null;\n };\n\nexport interface SessionEnvironment {\n node: string;\n platform: string;\n /** Winning agent provider for the run. `null` on snapshots from earlier releases. */\n agent: string | null;\n /** Winning model for the run. `null` when unset or on older snapshots. */\n model: string | null;\n /**\n * Version of the `issue-flow` package that produced the run. `null` on\n * snapshots written before it was recorded. It is the version of the CLI, not\n * of the monitor serving the dashboard — the two can differ, which is exactly\n * what `--restart-web` exists to fix.\n */\n cliVersion: string | null;\n}\n\nexport interface SessionConfigurationValue {\n value: string | null;\n source: 'default' | 'global' | 'project' | 'env' | 'cli' | 'fallback' | 'recommended';\n}\n\nexport interface SessionPhaseConfiguration {\n phase: string;\n provider: SessionConfigurationValue;\n model: SessionConfigurationValue;\n}\n\nexport interface SessionConfigurationSnapshot {\n precedence: string[];\n defaultProvider: SessionConfigurationValue;\n defaultModel: SessionConfigurationValue;\n phases: SessionPhaseConfiguration[];\n fallbacks: string[];\n overrides: string[];\n}\n\nexport interface SessionCommit {\n hash: string;\n subject: string;\n committedAt?: string | null;\n storyId?: string | null;\n}\n\nexport interface SessionPullRequest {\n number: number;\n url: string;\n title: string;\n}\n","import type { UserStoryStatus } from '../../types.js';\nimport type { SessionEvent } from './events.js';\nimport type { SessionSnapshot, SessionStorySnapshot, SessionUsageSnapshot } from './snapshot.js';\n\nexport type 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 */\nexport function 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. */\nexport function accumulateUsage<T extends SessionUsageSnapshot>(\n target: T,\n event: MetricsUpdateEvent,\n): 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 */\nexport function 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 */\nexport function 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\nexport function 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 */\nexport function 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 */\nexport function 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 */\nexport function 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. */\nexport function 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","import { reported } from './derive.js';\nimport type { SessionEvent } from './events.js';\nimport type { SessionSnapshot } from './snapshot.js';\n\nexport type GitEvent = Extract<SessionEvent, { type: 'git:update' }>;\n\nexport function applyGitEvent(snapshot: SessionSnapshot, event: GitEvent): SessionSnapshot {\n switch (event.type) {\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 branchCreated: reported(event.branchCreated, snapshot.git.branchCreated),\n startCommit: snapshot.git.startCommit,\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}\n","import { stripVTControlCharacters } from 'node:util';\nimport { DEFAULT_LOG_LIMIT, type SessionEvent } from './events.js';\nimport type {\n SessionLogEntry,\n SessionProcessLogEntry,\n SessionReducerOptions,\n SessionSnapshot,\n} from './snapshot.js';\n\nexport type LogEvent = Extract<\n SessionEvent,\n { type: 'log' | 'process:output' | 'execution:update' }\n>;\n\nexport function applyLogEvent(\n snapshot: SessionSnapshot,\n event: LogEvent,\n options?: SessionReducerOptions,\n): SessionSnapshot {\n switch (event.type) {\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 'process:output': {\n const limit = options?.logLimit ?? DEFAULT_LOG_LIMIT;\n const entry: SessionProcessLogEntry = {\n at: event.at,\n phase: event.phase,\n executionId: event.executionId,\n provider: event.provider,\n stream: event.stream,\n message: stripVTControlCharacters(event.message),\n };\n return {\n ...snapshot,\n processLogs: [...snapshot.processLogs, entry].slice(-Math.max(1, limit)),\n };\n }\n\n case 'execution:update': {\n const index = snapshot.executions.findIndex((entry) => entry.id === event.execution.id);\n const executions = [...snapshot.executions];\n if (index === -1) executions.push(event.execution);\n else executions[index] = event.execution;\n return { ...snapshot, executions };\n }\n\n default: {\n const _exhaustive: never = event;\n return _exhaustive;\n }\n }\n}\n","import { accumulate, accumulateUsage } from './derive.js';\nimport type { SessionEvent } from './events.js';\nimport type { SessionSnapshot } from './snapshot.js';\n\nexport type MetricsEvent = Extract<SessionEvent, { type: 'metrics:update' }>;\n\nexport function applyMetricsEvent(snapshot: SessionSnapshot, event: MetricsEvent): SessionSnapshot {\n switch (event.type) {\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}\n","import { stripVTControlCharacters } from 'node:util';\nimport { computePercent, secondsBetween } from './derive.js';\nimport type { SessionEvent } from './events.js';\nimport { isTerminalStage, transitionStory } from './reducer-stage.js';\nimport { emptyPhaseTiming, emptyUsage, type SessionSnapshot } from './snapshot.js';\n\nexport type PhaseEvent = Extract<\n SessionEvent,\n {\n type: 'phase:start' | 'phase:end' | 'iteration:start' | 'iteration:end' | 'correction:cycle';\n }\n>;\n\nexport function applyPhaseEvent(snapshot: SessionSnapshot, event: PhaseEvent): SessionSnapshot {\n switch (event.type) {\n case 'phase:start':\n return applyPhaseStart(snapshot, event);\n case 'phase:end':\n return applyPhaseEnd(snapshot, event);\n case 'iteration:start':\n return applyIterationStart(snapshot, event);\n case 'iteration:end':\n return { ...snapshot, currentActivity: null };\n case 'correction:cycle':\n return applyCorrectionCycle(snapshot, event);\n default: {\n const _exhaustive: never = event;\n return _exhaustive;\n }\n }\n}\n\nfunction applyPhaseStart(\n snapshot: SessionSnapshot,\n event: Extract<PhaseEvent, { type: 'phase:start' }>,\n): SessionSnapshot {\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 ...emptyPhaseTiming(),\n ...emptyUsage(),\n },\n ];\n // The `execute` phase only completes (and `review` only starts) once\n // every story already passes — a pipeline invariant — so entering\n // `review` safely moves every passing story to 'in_review' in one go;\n // there is never a not-yet-passing story to skip over here.\n const stories =\n event.phase === 'review'\n ? snapshot.stories.map((story) =>\n story.passes ? transitionStory(story, 'in_review', event.at, null) : story,\n )\n : snapshot.stories;\n return {\n ...snapshot,\n currentPhase: event.phase,\n phases,\n stories,\n progress: known ? snapshot.progress : { ...snapshot.progress, phasesTotal: phases.length },\n };\n}\n\nfunction applyPhaseEnd(\n snapshot: SessionSnapshot,\n event: Extract<PhaseEvent, { type: 'phase:end' }>,\n): SessionSnapshot {\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 harnessExecutionMs: event.harnessExecutionMs ?? p.harnessExecutionMs,\n orchestrationOverheadMs: event.orchestrationOverheadMs ?? p.orchestrationOverheadMs,\n harnessStartupMs: event.harnessStartupMs ?? p.harnessStartupMs,\n ttftMs: event.ttftMs ?? p.ttftMs,\n attemptCount: event.attemptCount ?? p.attemptCount,\n retryDurationMs: event.retryDurationMs ?? p.retryDurationMs,\n }\n : p,\n );\n const phasesCompleted = phases.filter((p) => p.status === 'completed').length;\n // Success moves every passing story to 'done'. Failure (the correction\n // loop gave up after maxCorrectionCycles) closes every story that is not\n // already 'done' as 'failed' — including the ones that never reached\n // `passes`, which are precisely the stories the issue calls failed. A\n // phase that fails outside `review` closes the same non-terminal stages,\n // so nothing is left frozen on 'executing' after the run stops.\n const stories = !event.success\n ? snapshot.stories.map((story) =>\n isTerminalStage(story.stage) ? story : transitionStory(story, 'failed', event.at, null),\n )\n : event.phase === 'review'\n ? snapshot.stories.map((story) =>\n story.passes ? transitionStory(story, 'done', event.at, null) : story,\n )\n : snapshot.stories;\n return {\n ...snapshot,\n currentPhase: snapshot.currentPhase === event.phase ? null : snapshot.currentPhase,\n currentActivity: null,\n phases,\n stories,\n progress: {\n ...snapshot.progress,\n phasesCompleted,\n percent: computePercent(phasesCompleted, snapshot.progress.phasesTotal),\n },\n };\n}\n\nfunction applyIterationStart(\n snapshot: SessionSnapshot,\n event: Extract<PhaseEvent, { type: 'iteration:start' }>,\n): SessionSnapshot {\n // The story matching storyId becomes 'executing'; every other\n // not-yet-passing story becomes 'pending' (a story that was already\n // 'executing' in a previous iteration but lost the turn reverts here).\n // Passing stories are untouched — this event owns only the\n // execute-loop's own pending/executing transition, never review or\n // correction. No-op branches (`return story`) avoid needless object\n // churn when the stage is already correct.\n const storyId = event.storyId;\n const stories = snapshot.stories.map((story) => {\n if (story.passes) return story;\n if (story.id === storyId) {\n return transitionStory(story, 'executing', event.at, null);\n }\n return transitionStory(story, 'pending', event.at, null);\n });\n return {\n ...snapshot,\n execution: { ...snapshot.execution, iteration: event.iteration },\n stories,\n // Finally populates the `story` field of the activity payload during\n // execute — today this phase never publishes an `activity` event at\n // all (no streaming), so `currentActivity` stays whatever an earlier\n // phase left it at. Left untouched when storyId is absent (every\n // story already passes, or the caller could not determine one).\n currentActivity:\n storyId !== undefined\n ? { story: storyId, tool: null, detail: null, since: event.at }\n : snapshot.currentActivity,\n };\n}\n\nfunction applyCorrectionCycle(\n snapshot: SessionSnapshot,\n event: Extract<PhaseEvent, { type: 'correction:cycle' }>,\n): SessionSnapshot {\n // Correction is pipeline-wide, not per-story: commands/run.ts re-runs\n // the whole execute+review cycle on a review failure, with no notion\n // of which story a finding belongs to — so every passing story moves\n // to 'in_correction' together, carrying the cycle count as a readable\n // stageDetail.\n const stageDetail = `Cycle ${event.cycle}/${event.maxCycles}`;\n const stories = snapshot.stories.map((story) =>\n story.passes ? transitionStory(story, 'in_correction', event.at, stageDetail) : story,\n );\n return {\n ...snapshot,\n execution: {\n ...snapshot.execution,\n correctionCycle: event.cycle,\n maxCorrectionCycles: event.maxCycles,\n },\n stories,\n };\n}\n","import type { StoryStage, UserStory } from '../../types.js';\nimport type { SessionStorySnapshot } from './snapshot.js';\n\n/**\n * Stages that describe a finished story. A run that ends — successfully or\n * not — must never leave a story on any other stage, or the panel keeps\n * claiming it is executing long after the process is gone.\n */\nexport function isTerminalStage(stage: StoryStage): boolean {\n return stage === 'done' || stage === 'failed';\n}\n\nexport function transitionStory(\n story: SessionStorySnapshot,\n stage: StoryStage,\n at: string,\n detail: string | null,\n): SessionStorySnapshot {\n if (story.stage === stage && story.stageDetail === detail) return story;\n return {\n ...story,\n stage,\n stageSince: at,\n stageDetail: detail,\n history: [...story.history, { at, stage, detail }],\n };\n}\n\n/**\n * `stage`/`stageSince`/`stageDetail` for one story, on one `stories:update`.\n *\n * This event owns exactly one transition — `awaiting_review` the moment a\n * story flips to `passes: true` (or is first seen already passing, since its\n * real completion moment is unknown either way). Everything else is a\n * carry-over: a still-`passes: false` story keeps whatever `iteration:start`\n * last gave it (defaulting to `'pending'` the very first time it is ever\n * seen), and a story already passing before this event is left exactly as it\n * was — `phase:start`/`phase:end` (review) and `correction:cycle` own every\n * transition past `awaiting_review`.\n */\nexport function deriveStageOnStoriesUpdate(\n story: UserStory,\n before: SessionStorySnapshot | undefined,\n at: string,\n): Pick<SessionStorySnapshot, 'stage' | 'stageSince' | 'stageDetail'> {\n if (!story.passes) {\n return {\n stage: before?.stage ?? 'pending',\n stageSince: before?.stageSince ?? at,\n stageDetail: before?.stageDetail ?? null,\n };\n }\n if (before?.passes) {\n return { stage: before.stage, stageSince: before.stageSince, stageDetail: before.stageDetail };\n }\n return { stage: 'awaiting_review', stageSince: at, stageDetail: null };\n}\n","import type { FailureKind } from '../../resilience/errors.js';\nimport type { ExecutionRecord } from '../../telemetry/types.js';\nimport type { StoryStage, UserStoryStatus } from '../../types.js';\nimport type {\n SessionCommit,\n SessionConfigurationSnapshot,\n SessionEnvironment,\n SessionLogLevel,\n SessionPhaseStatus,\n SessionPullRequest,\n SessionStatus,\n} from './events.js';\n\nexport type {\n SessionCommit,\n SessionConfigurationSnapshot,\n SessionConfigurationValue,\n SessionEnvironment,\n SessionPhaseConfiguration,\n SessionPullRequest,\n} from './events.js';\n\nexport interface SessionLogEntry {\n at: string;\n level: SessionLogLevel;\n message: string;\n}\n\nexport interface SessionProcessLogEntry {\n at: string;\n phase: string;\n executionId: string | null;\n provider: string;\n stream: 'stdout' | 'stderr' | 'combined';\n message: string;\n}\n\nexport interface SessionStageHistoryEntry {\n at: string;\n stage: StoryStage;\n detail: string | null;\n}\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 /** Sum of invocation walls for this phase. */\n harnessExecutionMs: number | null;\n /** Phase wall minus harnessExecutionMs, when both are known. */\n orchestrationOverheadMs: number | null;\n /** Wall clock − CLI `duration_ms`. */\n harnessStartupMs: number | null;\n /** Time to first output, when the harness reports it. */\n ttftMs: number | null;\n attemptCount: number | null;\n retryDurationMs: number | 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 * Fine-grained execution stage, derived only from real pipeline events —\n * see {@link StoryStage} and the `applyEvent` cases for `iteration:start`,\n * `stories:update`, `phase:start`/`phase:end` (phase `'review'`) and\n * `correction:cycle`. Unlike `status`, this is not a post-hoc derivation\n * recomputed on every reduction: it is set directly, event by event, like\n * `completedAt`.\n */\n stage: StoryStage;\n /** ISO timestamp of the event that produced the current `stage`. */\n stageSince: string | null;\n /** Short human detail for the current stage (e.g. a correction cycle). */\n stageDetail: string | null;\n /** Append-only transition history retained in the snapshot for the drawer. */\n history: SessionStageHistoryEntry[];\n}\n\nexport interface SessionActivity {\n story: string | null;\n tool: string | null;\n detail: string | null;\n since: string;\n}\n\n/** Live resilience state for the current agent invocation. */\nexport interface SessionResilienceSnapshot {\n attempt: number;\n provider: string | null;\n model: string | null;\n lastFailureKind: FailureKind | null;\n cooldownUntil: string | null;\n lastActivityAt: string | null;\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 executions: ExecutionRecord[];\n processLogs: SessionProcessLogEntry[];\n configuration: SessionConfigurationSnapshot | null;\n resilience: SessionResilienceSnapshot;\n git: {\n branch: string | null;\n baseBranch: string | null;\n branchCreated: boolean | null;\n startCommit: string | null;\n commits: SessionCommit[];\n };\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 /** Acceptance-contract verdict. `null` until a contract has run. */\n verification: {\n verdict: 'passed' | 'failed' | 'unverified' | null;\n level: string | null;\n independence: string | null;\n } | 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. */\nexport function emptyUsage(): SessionUsageSnapshot {\n return {\n inputTokens: null,\n outputTokens: null,\n cacheReadTokens: null,\n cacheCreationTokens: null,\n costUsd: null,\n };\n}\n\nexport function emptyPhaseTiming(): Pick<\n SessionPhaseSnapshot,\n | 'harnessExecutionMs'\n | 'orchestrationOverheadMs'\n | 'harnessStartupMs'\n | 'ttftMs'\n | 'attemptCount'\n | 'retryDurationMs'\n> {\n return {\n harnessExecutionMs: null,\n orchestrationOverheadMs: null,\n harnessStartupMs: null,\n ttftMs: null,\n attemptCount: null,\n retryDurationMs: null,\n };\n}\n\nexport function 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 executions: [],\n processLogs: [],\n configuration: null,\n resilience: {\n attempt: 0,\n provider: null,\n model: null,\n lastFailureKind: null,\n cooldownUntil: null,\n lastActivityAt: null,\n },\n git: {\n branch: null,\n baseBranch: null,\n branchCreated: null,\n startCommit: null,\n commits: [],\n },\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 verification: null,\n };\n}\n","import type { SessionEvent } from './events.js';\nimport type { SessionSnapshot } from './snapshot.js';\n\nexport type ResilienceEvent = Extract<\n SessionEvent,\n { type: 'retry' | 'agent:attempt' | 'failover' | 'agent:result' | 'agent:activity' }\n>;\n\nexport function applyResilienceEvent(\n snapshot: SessionSnapshot,\n event: ResilienceEvent,\n): SessionSnapshot {\n switch (event.type) {\n case 'retry':\n return {\n ...snapshot,\n execution: { ...snapshot.execution, retries: snapshot.execution.retries + 1 },\n };\n\n case 'agent:attempt':\n return {\n ...snapshot,\n resilience: {\n ...snapshot.resilience,\n attempt: event.attempt,\n provider: event.provider,\n model: event.model ?? null,\n lastActivityAt: event.at,\n },\n };\n\n case 'failover':\n return {\n ...snapshot,\n resilience: {\n ...snapshot.resilience,\n provider: event.to,\n lastFailureKind: event.reason,\n cooldownUntil: event.cooldownUntil ?? null,\n lastActivityAt: event.at,\n },\n };\n\n case 'agent:result':\n return {\n ...snapshot,\n resilience: {\n ...snapshot.resilience,\n provider: event.provider,\n lastFailureKind: event.failureKind ?? snapshot.resilience.lastFailureKind,\n cooldownUntil: event.cooldownUntil ?? null,\n lastActivityAt: event.at,\n },\n };\n\n case 'agent:activity':\n return {\n ...snapshot,\n resilience: {\n ...snapshot.resilience,\n provider: event.provider,\n lastActivityAt: event.at,\n },\n };\n\n default: {\n const _exhaustive: never = event;\n return _exhaustive;\n }\n }\n}\n","import { stripVTControlCharacters } from 'node:util';\nimport { setTelemetrySessionId } from '../../telemetry/session-id.js';\nimport type { SessionEvent } from './events.js';\nimport { isTerminalStage, transitionStory } from './reducer-stage.js';\nimport {\n createInitialSnapshot,\n emptyPhaseTiming,\n emptyUsage,\n type SessionSnapshot,\n} from './snapshot.js';\n\nexport type SessionLifecycleEvent = Extract<\n SessionEvent,\n { type: 'session:start' | 'session:end' | 'issue:update' | 'verify:end' }\n>;\n\nexport function applySessionEvent(\n snapshot: SessionSnapshot,\n event: SessionLifecycleEvent,\n): SessionSnapshot {\n switch (event.type) {\n case 'session:start': {\n setTelemetrySessionId(event.sessionId);\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 ...emptyPhaseTiming(),\n ...emptyUsage(),\n })),\n git: {\n branch: event.branch ?? null,\n baseBranch: event.baseBranch ?? null,\n branchCreated: event.branchCreated ?? null,\n startCommit: event.startCommit ?? null,\n commits: [],\n },\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 configuration: event.configuration ?? null,\n environment: event.environment\n ? {\n node: event.environment.node,\n platform: event.environment.platform,\n agent: event.environment.agent ?? null,\n model: event.environment.model ?? null,\n cliVersion: event.environment.cliVersion ?? null,\n }\n : 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 'verify:end':\n return {\n ...snapshot,\n verification: {\n verdict: event.verdict,\n level: event.level,\n independence: event.independence,\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 // Close every non-terminal stage: the run is over, so nothing can be\n // 'executing'/'in_review'/'in_correction' any more. A story that never\n // reached `passes` on a run that did not complete is exactly what the\n // 'failed' stage means; anything else settles as 'done'.\n stories: snapshot.stories.map((story) => {\n if (isTerminalStage(story.stage)) return story;\n const stage =\n event.status === 'completed' && story.passes ? ('done' as const) : ('failed' as const);\n return transitionStory(story, stage, event.at, null);\n }),\n lastError: event.error\n ? { message: stripVTControlCharacters(event.error), at: event.at }\n : snapshot.lastError,\n };\n\n default: {\n const _exhaustive: never = event;\n return _exhaustive;\n }\n }\n}\n","import type { SessionEvent } from './events.js';\nimport { deriveStageOnStoriesUpdate } from './reducer-stage.js';\nimport type { SessionSnapshot } from './snapshot.js';\n\nexport type StoryEvent = Extract<SessionEvent, { type: 'stories:update' | 'activity' }>;\n\nexport function applyStoryEvent(snapshot: SessionSnapshot, event: StoryEvent): SessionSnapshot {\n switch (event.type) {\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 const stage = deriveStageOnStoriesUpdate(story, before, event.at);\n const history = before?.history ?? [];\n const stageChanged = before !== undefined && before.stage !== stage.stage;\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 ...stage,\n history: stageChanged\n ? [...history, { at: event.at, stage: stage.stage, detail: stage.stageDetail }]\n : history,\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 {\n ...snapshot,\n currentActivity: { story, tool, detail, since },\n resilience: { ...snapshot.resilience, lastActivityAt: event.at },\n };\n }\n\n default: {\n const _exhaustive: never = event;\n return _exhaustive;\n }\n }\n}\n","import {\n deriveNextSteps,\n deriveStoryStatuses,\n estimateRemainingSeconds,\n secondsBetween,\n} from './derive.js';\nimport type { SessionEvent } from './events.js';\nimport { applyGitEvent } from './reducer-git.js';\nimport { applyLogEvent } from './reducer-log.js';\nimport { applyMetricsEvent } from './reducer-metrics.js';\nimport { applyPhaseEvent } from './reducer-phase.js';\nimport { applyResilienceEvent } from './reducer-resilience.js';\nimport { applySessionEvent } from './reducer-session.js';\nimport { applyStoryEvent } from './reducer-story.js';\nimport type { SessionReducerOptions, SessionSnapshot } from './snapshot.js';\n\nexport {\n deriveStageOnStoriesUpdate,\n isTerminalStage,\n transitionStory,\n} from './reducer-stage.js';\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 case 'session:end':\n case 'issue:update':\n case 'verify:end':\n return applySessionEvent(snapshot, event);\n\n case 'phase:start':\n case 'phase:end':\n case 'iteration:start':\n case 'iteration:end':\n case 'correction:cycle':\n return applyPhaseEvent(snapshot, event);\n\n case 'stories:update':\n case 'activity':\n return applyStoryEvent(snapshot, event);\n\n case 'metrics:update':\n return applyMetricsEvent(snapshot, event);\n\n case 'git:update':\n return applyGitEvent(snapshot, event);\n\n case 'log':\n case 'process:output':\n case 'execution:update':\n return applyLogEvent(snapshot, event, options);\n\n case 'retry':\n case 'agent:attempt':\n case 'failover':\n case 'agent:result':\n case 'agent:activity':\n return applyResilienceEvent(snapshot, event);\n\n default: {\n const _exhaustive: never = event;\n void _exhaustive;\n return snapshot;\n }\n }\n}\n","import { NullPublisher, type SessionPublisher } from './session/publishers.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 MemoryPublisher\n * for every run and a FilePublisher on top when web monitoring is enabled.\n * The default NullPublisher makes every instrumentation point a no-op\n * before a run (or a standalone command) installs a publisher.\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"],"mappings":"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","names":["stripVTControlCharacters","stripVTControlCharacters","stripVTControlCharacters","stripVTControlCharacters"]}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  printInfo
4
- } from "./chunk-NVZMBXTE.js";
4
+ } from "./chunk-XZUEFTUP.js";
5
5
  import {
6
6
  ISSUES_DIR_NAME,
7
7
  PROVIDERS_HEALTH_FILENAME,
@@ -16,20 +16,20 @@ import {
16
16
  getProjectRoot,
17
17
  getRemoteUrl,
18
18
  normalizeRemoteUrl
19
- } from "./chunk-GSZCQUCY.js";
19
+ } from "./chunk-YVPZUN6X.js";
20
20
  import {
21
21
  bindTelemetry
22
- } from "./chunk-TBDP6QPJ.js";
22
+ } from "./chunk-YII4U7ZD.js";
23
23
  import {
24
24
  isoNow
25
- } from "./chunk-XQHFC62U.js";
25
+ } from "./chunk-SOM4QA6C.js";
26
26
  import {
27
27
  STORAGE_SCHEMA_VERSION,
28
28
  projectMetadataSchema
29
- } from "./chunk-XDKGA6UX.js";
29
+ } from "./chunk-ICM463EO.js";
30
30
  import {
31
31
  writeFileAtomic
32
- } from "./chunk-7Z4Y3VKM.js";
32
+ } from "./chunk-3R27MJ5R.js";
33
33
 
34
34
  // src/storage/resolve.ts
35
35
  import { stat as stat2 } from "fs/promises";
@@ -280,4 +280,4 @@ export {
280
280
  resolveQueuePaths,
281
281
  resolveIssuePaths
282
282
  };
283
- //# sourceMappingURL=chunk-VR34TXHF.js.map
283
+ //# sourceMappingURL=chunk-DV7HUC4Z.js.map
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  loadPolicyConfig,
4
4
  mergeConfigLayers
5
- } from "./chunk-WM3Y7Q4A.js";
5
+ } from "./chunk-HY5HLFDU.js";
6
6
  import {
7
7
  printWarning
8
- } from "./chunk-NVZMBXTE.js";
8
+ } from "./chunk-XZUEFTUP.js";
9
9
  import {
10
10
  getProjectRoot,
11
11
  run
12
- } from "./chunk-GSZCQUCY.js";
12
+ } from "./chunk-YVPZUN6X.js";
13
13
 
14
14
  // src/conventions/git/types.ts
15
15
  var CHANGE_TYPES = [
@@ -1559,4 +1559,4 @@ export {
1559
1559
  issueReferenceLines,
1560
1560
  loadRepositoryPolicy
1561
1561
  };
1562
- //# sourceMappingURL=chunk-6SRE4KD7.js.map
1562
+ //# sourceMappingURL=chunk-E6KXCV3T.js.map