safeword 0.78.0 → 0.78.2

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 (144) hide show
  1. package/codex-plugin/.codex-plugin/plugin.json +1 -1
  2. package/codex-plugin/hooks.json +5 -5
  3. package/dist/{architecture-4EIJWLZ2.js → architecture-N5ZC4CDU.js} +2 -2
  4. package/dist/{architecture-document-Z3GLUOE3.js → architecture-document-UBA5UT4J.js} +2 -2
  5. package/dist/{architecture-monorepo-EIF3E3L3.js → architecture-monorepo-E4JUYJGV.js} +2 -2
  6. package/dist/{boundary-U5U2PSX2.js → boundary-HLJILY7R.js} +2 -2
  7. package/dist/{chunk-VUWQD4AG.js → chunk-3SOJBMM6.js} +2 -2
  8. package/dist/{chunk-JZFZWY3K.js → chunk-4CKCRZDO.js} +2 -2
  9. package/dist/{chunk-SLRSGK2C.js → chunk-AV5LTEME.js} +8 -10
  10. package/dist/{chunk-SLRSGK2C.js.map → chunk-AV5LTEME.js.map} +1 -1
  11. package/dist/{chunk-3ETWYWGQ.js → chunk-BAVDDAN3.js} +4 -4
  12. package/dist/{chunk-4AIRSIOH.js → chunk-BSOUMHMQ.js} +724 -3
  13. package/dist/chunk-BSOUMHMQ.js.map +1 -0
  14. package/dist/chunk-FV2S4LAR.js +122 -0
  15. package/dist/chunk-FV2S4LAR.js.map +1 -0
  16. package/dist/{chunk-C377VEWH.js → chunk-GZ36UZJG.js} +3 -3
  17. package/dist/{chunk-FASTWBPY.js → chunk-J7UDLLTK.js} +3 -3
  18. package/dist/{chunk-RXQJH4LM.js → chunk-KXHVFCDT.js} +4 -4
  19. package/dist/{chunk-AQU52TJM.js → chunk-NOTBZCKG.js} +3 -3
  20. package/dist/{chunk-AQU52TJM.js.map → chunk-NOTBZCKG.js.map} +1 -1
  21. package/dist/{chunk-E4UMSKEX.js → chunk-NSZGI7HK.js} +2 -2
  22. package/dist/{chunk-E4UMSKEX.js.map → chunk-NSZGI7HK.js.map} +1 -1
  23. package/dist/chunk-QTG2EXFT.js +7 -0
  24. package/dist/chunk-QTG2EXFT.js.map +1 -0
  25. package/dist/{chunk-7KMQ3QPX.js → chunk-SME5SU3O.js} +4 -4
  26. package/dist/{chunk-7KMQ3QPX.js.map → chunk-SME5SU3O.js.map} +1 -1
  27. package/dist/{cleanup-QV2EBF6M.js → cleanup-X556LNWM.js} +5 -5
  28. package/dist/{cleanup-command-DTE64KTN.js → cleanup-command-RV2Q7G72.js} +6 -6
  29. package/dist/cli.js +86 -139
  30. package/dist/cli.js.map +1 -1
  31. package/dist/{clients-N4UXDPCN.js → clients-HP23HRN2.js} +2 -2
  32. package/dist/codex-bootstrap-MGY2D6HU.js +178 -0
  33. package/dist/codex-bootstrap-MGY2D6HU.js.map +1 -0
  34. package/dist/{codex-hook-VHGSPJN3.js → codex-hook-IPX3PDXX.js} +5 -5
  35. package/dist/{codify-DJELEKJ6.js → codify-J5ZLJ3HK.js} +2 -2
  36. package/dist/{commands-4NIKNAST.js → commands-L4AINARC.js} +14 -14
  37. package/dist/{config-5A4LJ62T.js → config-LUSJAK6B.js} +2 -2
  38. package/dist/{configured-paths-ZY2GRPYU.js → configured-paths-SPQ5XWOM.js} +2 -2
  39. package/dist/{contract-ZRRRAQWZ.js → contract-KEZY6YC3.js} +2 -2
  40. package/dist/{coordinator-ZPEXUBXT.js → coordinator-SA75UB3C.js} +126 -44
  41. package/dist/coordinator-SA75UB3C.js.map +1 -0
  42. package/dist/{corpus-ZJQNIU4R.js → corpus-PPOBTF4J.js} +2 -2
  43. package/dist/{doctor-HUUE7QWE.js → doctor-DSC36R4U.js} +8 -8
  44. package/dist/{feature-directories-7ACGMPS4.js → feature-directories-VOHVV26X.js} +2 -2
  45. package/dist/{finalization-5D5N64R7.js → finalization-7SMLMVLV.js} +2 -2
  46. package/dist/{gh-cli-46VSKW2O.js → gh-cli-ZMO7D2KE.js} +2 -2
  47. package/dist/{github-rest-SXLBFCQP.js → github-rest-KGKS4V2H.js} +2 -2
  48. package/dist/index.js +1 -1
  49. package/dist/{job-EW5LWBHH.js → job-CDADLJDF.js} +257 -87
  50. package/dist/job-CDADLJDF.js.map +1 -0
  51. package/dist/{learning-sync-DRQM2JF6.js → learning-sync-6BTHM6ZC.js} +2 -2
  52. package/dist/{legacy-global-guidance-DWGAGL44.js → legacy-global-guidance-2JL4Y5EB.js} +2 -2
  53. package/dist/{lint-gherkin-5LJX6BBU.js → lint-gherkin-COSHVS6Z.js} +2 -2
  54. package/dist/{operations-5CJI6U6T.js → operations-XVRQSLJG.js} +6 -6
  55. package/dist/{output-5TOP54O5.js → output-3LB2OEHN.js} +2 -2
  56. package/dist/{packet-IHZNYM3G.js → packet-5WT5M3OS.js} +2 -2
  57. package/dist/presets/typescript/index.js +1 -1
  58. package/dist/{profile-ZZGSSTSJ.js → profile-UMKQ5JVO.js} +2 -2
  59. package/dist/{prompt-C3MNQKAT.js → prompt-GWYDFMLO.js} +2 -2
  60. package/dist/{remove-PRBJCO6G.js → remove-E6HGNHOU.js} +6 -6
  61. package/dist/{retro-Z2DREW77.js → retro-IFSVU5KS.js} +429 -236
  62. package/dist/retro-IFSVU5KS.js.map +1 -0
  63. package/dist/{retro-draft-spool-YVNO4VSB.js → retro-draft-spool-4S3TCHWL.js} +2 -2
  64. package/dist/{retro-extract-NBSIY4ZY.js → retro-extract-OSBFAXLU.js} +2 -2
  65. package/dist/{review-pr-TTJKQC4H.js → review-pr-6S2352CK.js} +2 -2
  66. package/dist/{review-pr-publication-DR75RPF4.js → review-pr-publication-CGHCRRUI.js} +2 -2
  67. package/dist/{run-5JWZAFET.js → run-5JESKXUR.js} +2 -2
  68. package/dist/{self-report-3KBA5TG7.js → self-report-VPHBPPSJ.js} +2 -2
  69. package/dist/{status-OFXGT5ZO.js → status-7VIGNTUI.js} +5 -5
  70. package/dist/{status-K62NWMZ6.js → status-EX4L3ELO.js} +8 -8
  71. package/dist/{sync-config-B62CJ5OS.js → sync-config-O7J7IDGE.js} +2 -2
  72. package/dist/{sync-tracker-QMPXXLJ4.js → sync-tracker-U2GYOFUO.js} +2 -2
  73. package/dist/{test-execution-MCMXLV5O.js → test-execution-6LIPMBIH.js} +2 -2
  74. package/dist/{test-plan-RJTKHEYA.js → test-plan-VASHZXJ7.js} +2 -2
  75. package/dist/{ticket-new-RPLN56XK.js → ticket-new-3YXDIWPC.js} +2 -2
  76. package/dist/{ticket-sync-VHTAPISH.js → ticket-sync-LLUBXZ2R.js} +2 -2
  77. package/dist/{tracker-map-WFRDFSKN.js → tracker-map-HR4MBYG5.js} +2 -2
  78. package/dist/{tracker-sync-5D4XNQHS.js → tracker-sync-YDICZN66.js} +2 -2
  79. package/package.json +1 -1
  80. package/templates/hooks/codex/pre-tool-quality.ts +8 -1
  81. package/templates/hooks/cursor/before-shell-execution.ts +2 -1
  82. package/templates/hooks/lib/closeout-binding.ts +130 -31
  83. package/templates/hooks/pre-tool-quality.ts +1 -1
  84. package/templates/hooks/run-review.ts +94 -5
  85. package/templates/hooks/session-codex-start.ts +4 -1
  86. package/templates/scripts/closeout-cleanup.ts +46 -68
  87. package/dist/chunk-4AIRSIOH.js.map +0 -1
  88. package/dist/chunk-BAYWBZ32.js +0 -7
  89. package/dist/chunk-BAYWBZ32.js.map +0 -1
  90. package/dist/codex-bootstrap-7OUYHP4G.js +0 -127
  91. package/dist/codex-bootstrap-7OUYHP4G.js.map +0 -1
  92. package/dist/coordinator-ZPEXUBXT.js.map +0 -1
  93. package/dist/job-EW5LWBHH.js.map +0 -1
  94. package/dist/retro-Z2DREW77.js.map +0 -1
  95. /package/dist/{architecture-4EIJWLZ2.js.map → architecture-N5ZC4CDU.js.map} +0 -0
  96. /package/dist/{architecture-document-Z3GLUOE3.js.map → architecture-document-UBA5UT4J.js.map} +0 -0
  97. /package/dist/{architecture-monorepo-EIF3E3L3.js.map → architecture-monorepo-E4JUYJGV.js.map} +0 -0
  98. /package/dist/{boundary-U5U2PSX2.js.map → boundary-HLJILY7R.js.map} +0 -0
  99. /package/dist/{chunk-VUWQD4AG.js.map → chunk-3SOJBMM6.js.map} +0 -0
  100. /package/dist/{chunk-JZFZWY3K.js.map → chunk-4CKCRZDO.js.map} +0 -0
  101. /package/dist/{chunk-3ETWYWGQ.js.map → chunk-BAVDDAN3.js.map} +0 -0
  102. /package/dist/{chunk-C377VEWH.js.map → chunk-GZ36UZJG.js.map} +0 -0
  103. /package/dist/{chunk-FASTWBPY.js.map → chunk-J7UDLLTK.js.map} +0 -0
  104. /package/dist/{chunk-RXQJH4LM.js.map → chunk-KXHVFCDT.js.map} +0 -0
  105. /package/dist/{cleanup-QV2EBF6M.js.map → cleanup-X556LNWM.js.map} +0 -0
  106. /package/dist/{cleanup-command-DTE64KTN.js.map → cleanup-command-RV2Q7G72.js.map} +0 -0
  107. /package/dist/{clients-N4UXDPCN.js.map → clients-HP23HRN2.js.map} +0 -0
  108. /package/dist/{codex-hook-VHGSPJN3.js.map → codex-hook-IPX3PDXX.js.map} +0 -0
  109. /package/dist/{codify-DJELEKJ6.js.map → codify-J5ZLJ3HK.js.map} +0 -0
  110. /package/dist/{commands-4NIKNAST.js.map → commands-L4AINARC.js.map} +0 -0
  111. /package/dist/{config-5A4LJ62T.js.map → config-LUSJAK6B.js.map} +0 -0
  112. /package/dist/{configured-paths-ZY2GRPYU.js.map → configured-paths-SPQ5XWOM.js.map} +0 -0
  113. /package/dist/{contract-ZRRRAQWZ.js.map → contract-KEZY6YC3.js.map} +0 -0
  114. /package/dist/{corpus-ZJQNIU4R.js.map → corpus-PPOBTF4J.js.map} +0 -0
  115. /package/dist/{doctor-HUUE7QWE.js.map → doctor-DSC36R4U.js.map} +0 -0
  116. /package/dist/{feature-directories-7ACGMPS4.js.map → feature-directories-VOHVV26X.js.map} +0 -0
  117. /package/dist/{finalization-5D5N64R7.js.map → finalization-7SMLMVLV.js.map} +0 -0
  118. /package/dist/{gh-cli-46VSKW2O.js.map → gh-cli-ZMO7D2KE.js.map} +0 -0
  119. /package/dist/{github-rest-SXLBFCQP.js.map → github-rest-KGKS4V2H.js.map} +0 -0
  120. /package/dist/{learning-sync-DRQM2JF6.js.map → learning-sync-6BTHM6ZC.js.map} +0 -0
  121. /package/dist/{legacy-global-guidance-DWGAGL44.js.map → legacy-global-guidance-2JL4Y5EB.js.map} +0 -0
  122. /package/dist/{lint-gherkin-5LJX6BBU.js.map → lint-gherkin-COSHVS6Z.js.map} +0 -0
  123. /package/dist/{operations-5CJI6U6T.js.map → operations-XVRQSLJG.js.map} +0 -0
  124. /package/dist/{output-5TOP54O5.js.map → output-3LB2OEHN.js.map} +0 -0
  125. /package/dist/{packet-IHZNYM3G.js.map → packet-5WT5M3OS.js.map} +0 -0
  126. /package/dist/{profile-ZZGSSTSJ.js.map → profile-UMKQ5JVO.js.map} +0 -0
  127. /package/dist/{prompt-C3MNQKAT.js.map → prompt-GWYDFMLO.js.map} +0 -0
  128. /package/dist/{remove-PRBJCO6G.js.map → remove-E6HGNHOU.js.map} +0 -0
  129. /package/dist/{retro-draft-spool-YVNO4VSB.js.map → retro-draft-spool-4S3TCHWL.js.map} +0 -0
  130. /package/dist/{retro-extract-NBSIY4ZY.js.map → retro-extract-OSBFAXLU.js.map} +0 -0
  131. /package/dist/{review-pr-TTJKQC4H.js.map → review-pr-6S2352CK.js.map} +0 -0
  132. /package/dist/{review-pr-publication-DR75RPF4.js.map → review-pr-publication-CGHCRRUI.js.map} +0 -0
  133. /package/dist/{run-5JWZAFET.js.map → run-5JESKXUR.js.map} +0 -0
  134. /package/dist/{self-report-3KBA5TG7.js.map → self-report-VPHBPPSJ.js.map} +0 -0
  135. /package/dist/{status-K62NWMZ6.js.map → status-7VIGNTUI.js.map} +0 -0
  136. /package/dist/{status-OFXGT5ZO.js.map → status-EX4L3ELO.js.map} +0 -0
  137. /package/dist/{sync-config-B62CJ5OS.js.map → sync-config-O7J7IDGE.js.map} +0 -0
  138. /package/dist/{sync-tracker-QMPXXLJ4.js.map → sync-tracker-U2GYOFUO.js.map} +0 -0
  139. /package/dist/{test-execution-MCMXLV5O.js.map → test-execution-6LIPMBIH.js.map} +0 -0
  140. /package/dist/{test-plan-RJTKHEYA.js.map → test-plan-VASHZXJ7.js.map} +0 -0
  141. /package/dist/{ticket-new-RPLN56XK.js.map → ticket-new-3YXDIWPC.js.map} +0 -0
  142. /package/dist/{ticket-sync-VHTAPISH.js.map → ticket-sync-LLUBXZ2R.js.map} +0 -0
  143. /package/dist/{tracker-map-WFRDFSKN.js.map → tracker-map-HR4MBYG5.js.map} +0 -0
  144. /package/dist/{tracker-sync-5D4XNQHS.js.map → tracker-sync-YDICZN66.js.map} +0 -0
@@ -0,0 +1,122 @@
1
+ // src/cli-protocol/policy.ts
2
+ var EFFECT_NOUNS = {
3
+ files: "file",
4
+ packages: "package",
5
+ configuration: "configuration",
6
+ network: "network",
7
+ destructive: "destructive"
8
+ };
9
+ function firstNonEmptyEffect(effects) {
10
+ return Object.keys(effects).find(
11
+ (effectClass) => effects[effectClass].length > 0
12
+ );
13
+ }
14
+ function assertNetworkPolicy(definition, result, offline) {
15
+ if (offline && result.effects.network.length > 0) {
16
+ throw new Error(`Command ${definition.name} reported network effects while running offline`);
17
+ }
18
+ if (definition.networkPolicy === "never" && result.effects.network.length > 0) {
19
+ throw new Error(`Command ${definition.name} reported undeclared network effects`);
20
+ }
21
+ }
22
+ function assertEffectPolicy(definition, result, options) {
23
+ assertNetworkPolicy(definition, result, options.offline);
24
+ if (definition.effectClass === "observe" || definition.effectClass === "plan") {
25
+ const effectClass = firstNonEmptyEffect(result.effects);
26
+ if (effectClass !== void 0) {
27
+ throw new Error(
28
+ `The ${definition.effectClass} command ${definition.name} reported ${EFFECT_NOUNS[effectClass]} effects`
29
+ );
30
+ }
31
+ }
32
+ if (definition.effectClass === "hook" && (result.effects.packages.length > 0 || result.effects.network.length > 0 || result.effects.destructive.length > 0)) {
33
+ throw new Error(`Hook command ${definition.name} reported forbidden lifecycle effects`);
34
+ }
35
+ }
36
+ var MANAGED_PROGRESS_SIGNAL = "SAFEWORD_REVIEW_PROGRESS";
37
+ function consumeManagedProgressSignal(environment) {
38
+ const enabled = environment[MANAGED_PROGRESS_SIGNAL] === "1";
39
+ Reflect.deleteProperty(environment, MANAGED_PROGRESS_SIGNAL);
40
+ return enabled;
41
+ }
42
+ function shouldReportProgress(options) {
43
+ return !options.quiet && (!options.json || options.managedReview);
44
+ }
45
+ function createBestEffortByteSink(write) {
46
+ return (buffer) => {
47
+ let offset = 0;
48
+ try {
49
+ while (offset < buffer.length) {
50
+ const written = write(buffer, offset, buffer.length - offset);
51
+ if (!Number.isSafeInteger(written) || written <= 0 || written > buffer.length - offset) {
52
+ return;
53
+ }
54
+ offset += written;
55
+ }
56
+ } catch {
57
+ }
58
+ };
59
+ }
60
+ function createBestEffortProgressSink(write) {
61
+ const writeBytes = createBestEffortByteSink(write);
62
+ return (message) => {
63
+ writeBytes(Buffer.from(`${message}
64
+ `));
65
+ };
66
+ }
67
+ function createManagedReviewProgress(progress) {
68
+ return { ...progress, managed: true };
69
+ }
70
+ var PROGRESS_ANNOUNCE_DELAY_MS = 100;
71
+ var PROGRESS_HEARTBEAT_INTERVAL_MS = 3e4;
72
+ function resolveHeartbeatIntervalMs(environment = process.env) {
73
+ if (environment.NODE_ENV !== "test") return PROGRESS_HEARTBEAT_INTERVAL_MS;
74
+ const override = Number(environment.SAFEWORD_PROGRESS_HEARTBEAT_MS);
75
+ if (!Number.isSafeInteger(override) || override < 1 || override > PROGRESS_HEARTBEAT_INTERVAL_MS) {
76
+ return PROGRESS_HEARTBEAT_INTERVAL_MS;
77
+ }
78
+ return override;
79
+ }
80
+ function createProgressReporter(adapters) {
81
+ let announcementHandle;
82
+ let heartbeatHandle;
83
+ const heartbeatIntervalMs = resolveHeartbeatIntervalMs();
84
+ function scheduleHeartbeat(message) {
85
+ heartbeatHandle = adapters.schedule(() => {
86
+ adapters.emit(message);
87
+ scheduleHeartbeat(message);
88
+ }, heartbeatIntervalMs);
89
+ }
90
+ return {
91
+ start(message) {
92
+ if (announcementHandle !== void 0) adapters.cancel(announcementHandle);
93
+ if (heartbeatHandle !== void 0) adapters.cancel(heartbeatHandle);
94
+ heartbeatHandle = void 0;
95
+ announcementHandle = adapters.schedule(() => {
96
+ adapters.emit(message);
97
+ announcementHandle = void 0;
98
+ }, PROGRESS_ANNOUNCE_DELAY_MS);
99
+ },
100
+ heartbeat(message) {
101
+ if (heartbeatHandle !== void 0) adapters.cancel(heartbeatHandle);
102
+ scheduleHeartbeat(message);
103
+ },
104
+ stop() {
105
+ if (announcementHandle !== void 0) adapters.cancel(announcementHandle);
106
+ if (heartbeatHandle !== void 0) adapters.cancel(heartbeatHandle);
107
+ announcementHandle = void 0;
108
+ heartbeatHandle = void 0;
109
+ }
110
+ };
111
+ }
112
+
113
+ export {
114
+ assertEffectPolicy,
115
+ consumeManagedProgressSignal,
116
+ shouldReportProgress,
117
+ createBestEffortByteSink,
118
+ createBestEffortProgressSink,
119
+ createManagedReviewProgress,
120
+ createProgressReporter
121
+ };
122
+ //# sourceMappingURL=chunk-FV2S4LAR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli-protocol/policy.ts"],"sourcesContent":["import type { CommandDefinition } from './catalog.js';\nimport type { ProgressReporter } from './handler.js';\nimport type { CliResult, Effects } from './result.js';\n\nconst EFFECT_NOUNS: Readonly<Record<keyof Effects, string>> = {\n files: 'file',\n packages: 'package',\n configuration: 'configuration',\n network: 'network',\n destructive: 'destructive',\n};\n\nfunction firstNonEmptyEffect(effects: Effects): keyof Effects | undefined {\n return (Object.keys(effects) as (keyof Effects)[]).find(\n effectClass => effects[effectClass].length > 0,\n );\n}\n\nfunction assertNetworkPolicy(\n definition: CommandDefinition,\n result: CliResult,\n offline: boolean,\n): void {\n if (offline && result.effects.network.length > 0) {\n throw new Error(`Command ${definition.name} reported network effects while running offline`);\n }\n if (definition.networkPolicy === 'never' && result.effects.network.length > 0) {\n throw new Error(`Command ${definition.name} reported undeclared network effects`);\n }\n}\n\nexport function assertEffectPolicy(\n definition: CommandDefinition,\n result: CliResult,\n options: { offline: boolean },\n): void {\n assertNetworkPolicy(definition, result, options.offline);\n\n if (definition.effectClass === 'observe' || definition.effectClass === 'plan') {\n const effectClass = firstNonEmptyEffect(result.effects);\n if (effectClass !== undefined) {\n throw new Error(\n `The ${definition.effectClass} command ${definition.name} reported ${EFFECT_NOUNS[effectClass]} effects`,\n );\n }\n }\n\n if (\n definition.effectClass === 'hook' &&\n (result.effects.packages.length > 0 ||\n result.effects.network.length > 0 ||\n result.effects.destructive.length > 0)\n ) {\n throw new Error(`Hook command ${definition.name} reported forbidden lifecycle effects`);\n }\n}\n\ninterface ProgressAdapters {\n readonly schedule: (callback: () => void, delayMilliseconds: number) => unknown;\n readonly cancel: (handle: unknown) => void;\n readonly emit: (message: string) => void;\n}\n\nconst MANAGED_PROGRESS_SIGNAL = 'SAFEWORD_REVIEW_PROGRESS';\n\nexport function consumeManagedProgressSignal(environment: NodeJS.ProcessEnv): boolean {\n const enabled = environment[MANAGED_PROGRESS_SIGNAL] === '1';\n Reflect.deleteProperty(environment, MANAGED_PROGRESS_SIGNAL);\n return enabled;\n}\n\nexport function shouldReportProgress(options: {\n readonly json: boolean;\n readonly managedReview: boolean;\n readonly quiet: boolean;\n}): boolean {\n return !options.quiet && (!options.json || options.managedReview);\n}\n\nexport function createBestEffortByteSink(\n write: (buffer: Uint8Array, offset: number, length: number) => number,\n): (buffer: Uint8Array) => void {\n return buffer => {\n let offset = 0;\n try {\n while (offset < buffer.length) {\n const written = write(buffer, offset, buffer.length - offset);\n if (!Number.isSafeInteger(written) || written <= 0 || written > buffer.length - offset) {\n return;\n }\n offset += written;\n }\n } catch {\n // Progress is advisory and must never affect the typed command result.\n }\n };\n}\n\nexport function createBestEffortProgressSink(\n write: (buffer: Uint8Array, offset: number, length: number) => number,\n): (message: string) => void {\n const writeBytes = createBestEffortByteSink(write);\n return message => {\n writeBytes(Buffer.from(`${message}\\n`));\n };\n}\n\nexport function createManagedReviewProgress(progress: ProgressReporter): ProgressReporter {\n return { ...progress, managed: true };\n}\n\n/** Operations finishing faster than this are not worth announcing. */\nconst PROGRESS_ANNOUNCE_DELAY_MS = 100;\n/** A long wait needs proof that the coordinator is still responsive. */\nconst PROGRESS_HEARTBEAT_INTERVAL_MS = 30_000;\n\n/**\n * Shorten the heartbeat so a test can observe a real one without waiting 30\n * seconds. Internal and test-only: production always uses the bounded default.\n */\nexport function resolveHeartbeatIntervalMs(environment: NodeJS.ProcessEnv = process.env): number {\n if (environment.NODE_ENV !== 'test') return PROGRESS_HEARTBEAT_INTERVAL_MS;\n const override = Number(environment.SAFEWORD_PROGRESS_HEARTBEAT_MS);\n if (\n !Number.isSafeInteger(override) ||\n override < 1 ||\n override > PROGRESS_HEARTBEAT_INTERVAL_MS\n ) {\n return PROGRESS_HEARTBEAT_INTERVAL_MS;\n }\n return override;\n}\n\nexport function createProgressReporter(adapters: ProgressAdapters): ProgressReporter {\n let announcementHandle: unknown;\n let heartbeatHandle: unknown;\n const heartbeatIntervalMs = resolveHeartbeatIntervalMs();\n\n function scheduleHeartbeat(message: string): void {\n heartbeatHandle = adapters.schedule(() => {\n adapters.emit(message);\n scheduleHeartbeat(message);\n }, heartbeatIntervalMs);\n }\n\n return {\n start(message: string): void {\n if (announcementHandle !== undefined) adapters.cancel(announcementHandle);\n if (heartbeatHandle !== undefined) adapters.cancel(heartbeatHandle);\n heartbeatHandle = undefined;\n announcementHandle = adapters.schedule(() => {\n adapters.emit(message);\n announcementHandle = undefined;\n }, PROGRESS_ANNOUNCE_DELAY_MS);\n },\n heartbeat(message: string): void {\n if (heartbeatHandle !== undefined) adapters.cancel(heartbeatHandle);\n scheduleHeartbeat(message);\n },\n stop(): void {\n if (announcementHandle !== undefined) adapters.cancel(announcementHandle);\n if (heartbeatHandle !== undefined) adapters.cancel(heartbeatHandle);\n announcementHandle = undefined;\n heartbeatHandle = undefined;\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@ import {
2
2
  assertSafeClaudeCleanupTarget,
3
3
  containedClaudeCleanupPath,
4
4
  observeClaudeLegacy
5
- } from "./chunk-JZFZWY3K.js";
5
+ } from "./chunk-4CKCRZDO.js";
6
6
  import {
7
7
  canonicalClaudeProjectRoot
8
8
  } from "./chunk-34NCOTP5.js";
@@ -19,7 +19,7 @@ import {
19
19
  cataloguedClaudeLegacyPaths,
20
20
  isAcceptedHistoricalFile,
21
21
  isAcceptedHistoricalHook
22
- } from "./chunk-E4UMSKEX.js";
22
+ } from "./chunk-NSZGI7HK.js";
23
23
  import {
24
24
  writeDurableFile,
25
25
  writeDurableFileExclusive
@@ -833,4 +833,4 @@ export {
833
833
  migrateClaudeLegacyAutomatically,
834
834
  recoverClaudeCleanup
835
835
  };
836
- //# sourceMappingURL=chunk-C377VEWH.js.map
836
+ //# sourceMappingURL=chunk-GZ36UZJG.js.map
@@ -2,10 +2,10 @@ import {
2
2
  ReconcileExecutionError,
3
3
  createProjectContext,
4
4
  reconcile
5
- } from "./chunk-AQU52TJM.js";
5
+ } from "./chunk-NOTBZCKG.js";
6
6
  import {
7
7
  SAFEWORD_SCHEMA
8
- } from "./chunk-4AIRSIOH.js";
8
+ } from "./chunk-BSOUMHMQ.js";
9
9
  import {
10
10
  uninstallDependencies
11
11
  } from "./chunk-6S7CTKGC.js";
@@ -349,4 +349,4 @@ export {
349
349
  diffFileSnapshots,
350
350
  removeProject
351
351
  };
352
- //# sourceMappingURL=chunk-FASTWBPY.js.map
352
+ //# sourceMappingURL=chunk-J7UDLLTK.js.map
@@ -25,11 +25,11 @@ import {
25
25
  createProjectContext,
26
26
  getMissingPacks,
27
27
  reconcile
28
- } from "./chunk-AQU52TJM.js";
28
+ } from "./chunk-NOTBZCKG.js";
29
29
  import {
30
30
  legacyObservationIsEmpty,
31
31
  observeClaudeLegacy
32
- } from "./chunk-JZFZWY3K.js";
32
+ } from "./chunk-4CKCRZDO.js";
33
33
  import {
34
34
  hasLegacyClaudePluginMode,
35
35
  readClaudePluginMode
@@ -43,7 +43,7 @@ import {
43
43
  isCursorProjectPath,
44
44
  schemaForProjectSurfaces,
45
45
  typescriptPackages
46
- } from "./chunk-4AIRSIOH.js";
46
+ } from "./chunk-BSOUMHMQ.js";
47
47
  import {
48
48
  codexFinalizationIsComplete
49
49
  } from "./chunk-AXAGJLMP.js";
@@ -962,4 +962,4 @@ export {
962
962
  observeCursorProject,
963
963
  unselectedCursorFinding
964
964
  };
965
- //# sourceMappingURL=chunk-RXQJH4LM.js.map
965
+ //# sourceMappingURL=chunk-KXHVFCDT.js.map
@@ -3,8 +3,9 @@ import {
3
3
  getWorkspacePackageNames
4
4
  } from "./chunk-Q5KLE6ZF.js";
5
5
  import {
6
+ parse,
6
7
  setupPythonTooling
7
- } from "./chunk-4AIRSIOH.js";
8
+ } from "./chunk-BSOUMHMQ.js";
8
9
  import {
9
10
  SAFEWORD_PRIMARY_LINT_SCRIPT,
10
11
  detect
@@ -886,7 +887,6 @@ import {
886
887
  writeFileSync
887
888
  } from "fs";
888
889
  import nodePath2 from "path";
889
- import { parse } from "smol-toml";
890
890
  var SAFEWORD_CLIPPY_LINTS = `[lints.clippy]
891
891
  # Enable pedantic for stricter linting (priority -1 allows individual overrides)
892
892
  pedantic = { level = "deny", priority = -1 }
@@ -1646,4 +1646,4 @@ export {
1646
1646
  LEFTHOOK_CONFIGS,
1647
1647
  createProjectContext
1648
1648
  };
1649
- //# sourceMappingURL=chunk-AQU52TJM.js.map
1649
+ //# sourceMappingURL=chunk-NOTBZCKG.js.map