agent-composer 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/README.md +495 -180
  2. package/composer.config.schema.json +206 -2
  3. package/dist/cli/cleanup.d.ts +24 -0
  4. package/dist/cli/cleanup.js +151 -0
  5. package/dist/cli/cleanup.js.map +1 -0
  6. package/dist/cli/doctor.d.ts +12 -0
  7. package/dist/cli/doctor.js +244 -4
  8. package/dist/cli/doctor.js.map +1 -1
  9. package/dist/cli/goal.d.ts +28 -0
  10. package/dist/cli/goal.js +251 -0
  11. package/dist/cli/goal.js.map +1 -0
  12. package/dist/cli/help.d.ts +3 -0
  13. package/dist/cli/help.js +31 -0
  14. package/dist/cli/help.js.map +1 -0
  15. package/dist/cli/init.d.ts +5 -0
  16. package/dist/cli/init.js +116 -21
  17. package/dist/cli/init.js.map +1 -1
  18. package/dist/cli/initArgs.d.ts +16 -0
  19. package/dist/cli/initArgs.js +19 -0
  20. package/dist/cli/initArgs.js.map +1 -0
  21. package/dist/cli/installGitHook.d.ts +7 -0
  22. package/dist/cli/installGitHook.js +61 -0
  23. package/dist/cli/installGitHook.js.map +1 -0
  24. package/dist/cli/mode.d.ts +6 -0
  25. package/dist/cli/mode.js +25 -0
  26. package/dist/cli/mode.js.map +1 -0
  27. package/dist/cli/status.d.ts +105 -0
  28. package/dist/cli/status.js +400 -0
  29. package/dist/cli/status.js.map +1 -0
  30. package/dist/config/env.d.ts +1 -1
  31. package/dist/config/modes.d.ts +10 -0
  32. package/dist/config/modes.js +26 -0
  33. package/dist/config/modes.js.map +1 -0
  34. package/dist/config/oracleRole.d.ts +10 -0
  35. package/dist/config/oracleRole.js +11 -0
  36. package/dist/config/oracleRole.js.map +1 -0
  37. package/dist/config/schema.d.ts +246 -0
  38. package/dist/config/schema.js +127 -2
  39. package/dist/config/schema.js.map +1 -1
  40. package/dist/evolve/reflection.d.ts +9 -0
  41. package/dist/evolve/reflection.js +14 -0
  42. package/dist/evolve/reflection.js.map +1 -1
  43. package/dist/evolve/runner.d.ts +2 -1
  44. package/dist/evolve/runner.js +2 -1
  45. package/dist/evolve/runner.js.map +1 -1
  46. package/dist/index.js +115 -6
  47. package/dist/index.js.map +1 -1
  48. package/dist/providers/AnthropicCompatibleProvider.d.ts +13 -1
  49. package/dist/providers/AnthropicCompatibleProvider.js +115 -9
  50. package/dist/providers/AnthropicCompatibleProvider.js.map +1 -1
  51. package/dist/providers/CLIProvider.d.ts +18 -0
  52. package/dist/providers/CLIProvider.js +265 -62
  53. package/dist/providers/CLIProvider.js.map +1 -1
  54. package/dist/providers/IProvider.d.ts +12 -0
  55. package/dist/providers/SpendGuardProvider.d.ts +32 -0
  56. package/dist/providers/SpendGuardProvider.js +98 -0
  57. package/dist/providers/SpendGuardProvider.js.map +1 -0
  58. package/dist/registry.d.ts +5 -2
  59. package/dist/registry.js +17 -2
  60. package/dist/registry.js.map +1 -1
  61. package/dist/server/activeRuns.d.ts +17 -0
  62. package/dist/server/activeRuns.js +114 -0
  63. package/dist/server/activeRuns.js.map +1 -0
  64. package/dist/server/codexLifecycleRunner.d.ts +29 -0
  65. package/dist/server/codexLifecycleRunner.js +188 -0
  66. package/dist/server/codexLifecycleRunner.js.map +1 -0
  67. package/dist/server/configMutation.d.ts +22 -0
  68. package/dist/server/configMutation.js +121 -0
  69. package/dist/server/configMutation.js.map +1 -0
  70. package/dist/server/handoffContext.d.ts +1 -0
  71. package/dist/server/handoffContext.js +12 -0
  72. package/dist/server/handoffContext.js.map +1 -0
  73. package/dist/server/progress.d.ts +24 -0
  74. package/dist/server/progress.js +109 -0
  75. package/dist/server/progress.js.map +1 -0
  76. package/dist/server/toolDescriptions.d.ts +60 -0
  77. package/dist/server/toolDescriptions.js +134 -0
  78. package/dist/server/toolDescriptions.js.map +1 -0
  79. package/dist/server.d.ts +19 -25
  80. package/dist/server.js +87 -377
  81. package/dist/server.js.map +1 -1
  82. package/dist/tools/audit.d.ts +2 -0
  83. package/dist/tools/audit.js +66 -0
  84. package/dist/tools/audit.js.map +1 -0
  85. package/dist/tools/code.d.ts +2 -0
  86. package/dist/tools/code.js +160 -0
  87. package/dist/tools/code.js.map +1 -0
  88. package/dist/tools/codexLifecycle.d.ts +2 -0
  89. package/dist/tools/codexLifecycle.js +206 -0
  90. package/dist/tools/codexLifecycle.js.map +1 -0
  91. package/dist/tools/config.d.ts +2 -0
  92. package/dist/tools/config.js +183 -0
  93. package/dist/tools/config.js.map +1 -0
  94. package/dist/tools/context.d.ts +31 -0
  95. package/dist/tools/context.js +2 -0
  96. package/dist/tools/context.js.map +1 -0
  97. package/dist/tools/goal.d.ts +2 -0
  98. package/dist/tools/goal.js +159 -0
  99. package/dist/tools/goal.js.map +1 -0
  100. package/dist/tools/handoff.d.ts +2 -0
  101. package/dist/tools/handoff.js +57 -0
  102. package/dist/tools/handoff.js.map +1 -0
  103. package/dist/tools/oracle.d.ts +2 -0
  104. package/dist/tools/oracle.js +248 -0
  105. package/dist/tools/oracle.js.map +1 -0
  106. package/dist/tools/research.d.ts +2 -0
  107. package/dist/tools/research.js +51 -0
  108. package/dist/tools/research.js.map +1 -0
  109. package/dist/tools/review.d.ts +2 -0
  110. package/dist/tools/review.js +233 -0
  111. package/dist/tools/review.js.map +1 -0
  112. package/dist/tools/route.d.ts +2 -0
  113. package/dist/tools/route.js +69 -0
  114. package/dist/tools/route.js.map +1 -0
  115. package/dist/tools/session.d.ts +2 -0
  116. package/dist/tools/session.js +37 -0
  117. package/dist/tools/session.js.map +1 -0
  118. package/dist/tools/status.d.ts +2 -0
  119. package/dist/tools/status.js +34 -0
  120. package/dist/tools/status.js.map +1 -0
  121. package/dist/tools/workflow.d.ts +2 -0
  122. package/dist/tools/workflow.js +27 -0
  123. package/dist/tools/workflow.js.map +1 -0
  124. package/dist/util/applyFileBlocks.d.ts +18 -0
  125. package/dist/util/applyFileBlocks.js +163 -0
  126. package/dist/util/applyFileBlocks.js.map +1 -0
  127. package/dist/util/asyncControl.d.ts +14 -0
  128. package/dist/util/asyncControl.js +106 -0
  129. package/dist/util/asyncControl.js.map +1 -0
  130. package/dist/util/auditLog.d.ts +56 -0
  131. package/dist/util/auditLog.js +232 -0
  132. package/dist/util/auditLog.js.map +1 -0
  133. package/dist/util/codexLifecycle.d.ts +55 -0
  134. package/dist/util/codexLifecycle.js +102 -0
  135. package/dist/util/codexLifecycle.js.map +1 -0
  136. package/dist/util/codexLifecycleJob.d.ts +209 -0
  137. package/dist/util/codexLifecycleJob.js +360 -0
  138. package/dist/util/codexLifecycleJob.js.map +1 -0
  139. package/dist/util/composerDisabled.d.ts +6 -0
  140. package/dist/util/composerDisabled.js +27 -0
  141. package/dist/util/composerDisabled.js.map +1 -0
  142. package/dist/util/dispatchHint.d.ts +5 -3
  143. package/dist/util/dispatchHint.js +62 -2
  144. package/dist/util/dispatchHint.js.map +1 -1
  145. package/dist/util/goal.d.ts +132 -0
  146. package/dist/util/goal.js +616 -0
  147. package/dist/util/goal.js.map +1 -0
  148. package/dist/util/goalReport.d.ts +51 -0
  149. package/dist/util/goalReport.js +164 -0
  150. package/dist/util/goalReport.js.map +1 -0
  151. package/dist/util/jobPolling.d.ts +9 -0
  152. package/dist/util/jobPolling.js +17 -0
  153. package/dist/util/jobPolling.js.map +1 -0
  154. package/dist/util/oracleJob.d.ts +66 -0
  155. package/dist/util/oracleJob.js +295 -0
  156. package/dist/util/oracleJob.js.map +1 -0
  157. package/dist/util/oracleLock.d.ts +38 -0
  158. package/dist/util/oracleLock.js +182 -0
  159. package/dist/util/oracleLock.js.map +1 -0
  160. package/dist/util/reviewDiff.d.ts +8 -0
  161. package/dist/util/reviewDiff.js +29 -0
  162. package/dist/util/reviewDiff.js.map +1 -0
  163. package/dist/util/reviewJob.d.ts +57 -0
  164. package/dist/util/reviewJob.js +207 -0
  165. package/dist/util/reviewJob.js.map +1 -0
  166. package/dist/util/workflowPlan.d.ts +24 -0
  167. package/dist/util/workflowPlan.js +49 -0
  168. package/dist/util/workflowPlan.js.map +1 -0
  169. package/package.json +8 -1
  170. package/plugin/composer-mastermind/commands/evolve.md +4 -0
  171. package/plugin/composer-mastermind/hooks/boundary_guard.sh +43 -2
  172. package/plugin/composer-mastermind/hooks/codex_warm_review.sh +161 -9
  173. package/plugin/composer-mastermind/hooks/learn.sh +172 -32
  174. package/plugin/composer-mastermind/hooks/precommit_codex_review.sh +438 -64
  175. package/plugin/composer-mastermind/skills/composer-mastermind/SKILL.md +190 -4
  176. package/scripts/composer-oracle-router-safe.sh +47 -0
  177. package/scripts/composer-statusline-segment.mjs +40 -0
  178. package/scripts/oracle-codex-handoff-safe.sh +49 -0
  179. package/scripts/oracle-plan-mcp.sh +66 -0
  180. package/scripts/oracle-pro-safe.sh +572 -0
@@ -32,6 +32,9 @@
32
32
  },
33
33
  "coderCli": {
34
34
  "$ref": "#/$defs/roleConfig"
35
+ },
36
+ "oraclePlanner": {
37
+ "$ref": "#/$defs/roleConfig"
35
38
  }
36
39
  }
37
40
  },
@@ -43,6 +46,31 @@
43
46
  },
44
47
  "codexRescue": {
45
48
  "$ref": "#/$defs/codexRescue"
49
+ },
50
+ "codexLifecycle": {
51
+ "$ref": "#/$defs/codexLifecycle"
52
+ },
53
+ "oracle": {
54
+ "type": "object",
55
+ "additionalProperties": false,
56
+ "properties": {
57
+ "defaultMode": {
58
+ "enum": ["auto", "quick", "standard", "deep", "plan", "review", "debug", "research"]
59
+ },
60
+ "requireExplicitTag": { "type": "boolean" }
61
+ }
62
+ },
63
+ "codexProfiles": {
64
+ "type": "object",
65
+ "additionalProperties": {
66
+ "type": "object",
67
+ "additionalProperties": false,
68
+ "properties": {
69
+ "model": { "type": "string", "minLength": 1, "not": { "const": "gpt-5.5-pro" } },
70
+ "reasoningEffort": { "enum": ["low", "medium", "high"] },
71
+ "sandbox": { "enum": ["read-only", "workspace-write"] }
72
+ }
73
+ }
46
74
  }
47
75
  },
48
76
  "$defs": {
@@ -122,6 +150,7 @@
122
150
  "model": {
123
151
  "type": "string",
124
152
  "minLength": 1,
153
+ "not": { "const": "gpt-5.5-pro" },
125
154
  "description": "Optional Codex model passed to codex-companion via --model."
126
155
  },
127
156
  "preCommitHook": {
@@ -193,11 +222,176 @@
193
222
  "model": {
194
223
  "type": "string",
195
224
  "minLength": 1,
225
+ "not": { "const": "gpt-5.5-pro" },
196
226
  "default": "gpt-5.4-mini",
197
227
  "description": "Model label used in Codex Rescue guidance."
198
228
  }
199
229
  }
200
230
  },
231
+ "codexLifecycle": {
232
+ "type": "object",
233
+ "additionalProperties": false,
234
+ "description": "Optional deterministic policy for deciding when Codex should participate beyond the mechanical review gate. It never invokes Codex by itself.",
235
+ "properties": {
236
+ "enabled": {
237
+ "type": "boolean",
238
+ "default": false,
239
+ "description": "Master opt-in switch. false keeps lifecycle participation policy off."
240
+ },
241
+ "mode": {
242
+ "type": "string",
243
+ "enum": [
244
+ "ask",
245
+ "auto"
246
+ ],
247
+ "default": "ask",
248
+ "description": "ask: return ask decisions for qualified events. auto: return run decisions for qualified events."
249
+ },
250
+ "execution": {
251
+ "type": "string",
252
+ "enum": [
253
+ "foreground",
254
+ "background"
255
+ ],
256
+ "default": "background",
257
+ "description": "Preferred Codex execution mode when the policy qualifies an event."
258
+ },
259
+ "model": {
260
+ "type": "string",
261
+ "minLength": 1,
262
+ "not": { "const": "gpt-5.5-pro" },
263
+ "default": "gpt-5.4-mini",
264
+ "description": "Codex model label to use for lifecycle participation prompts."
265
+ },
266
+ "triggers": {
267
+ "$ref": "#/$defs/codexLifecycleTriggers"
268
+ },
269
+ "thresholds": {
270
+ "$ref": "#/$defs/codexLifecycleThresholds"
271
+ },
272
+ "fallback": {
273
+ "$ref": "#/$defs/codexLifecycleFallback"
274
+ },
275
+ "totalWallClockMs": {
276
+ "type": "integer",
277
+ "minimum": 1,
278
+ "default": 900000,
279
+ "description": "Hard total_wall_clock_ms cap in milliseconds across one lifecycle run and all fallback roles. Omitted = 900000."
280
+ }
281
+ }
282
+ },
283
+ "codexLifecycleTriggers": {
284
+ "type": "object",
285
+ "additionalProperties": false,
286
+ "description": "Lifecycle stages where Coco may ask the policy whether Codex should participate.",
287
+ "properties": {
288
+ "postResearch": {
289
+ "type": "boolean",
290
+ "default": false,
291
+ "description": "Consider Codex after a research result is produced."
292
+ },
293
+ "postPlan": {
294
+ "type": "boolean",
295
+ "default": true,
296
+ "description": "Consider Codex after a plan is written, before code."
297
+ },
298
+ "postCodeApply": {
299
+ "type": "boolean",
300
+ "default": true,
301
+ "description": "Consider Codex after code has been applied."
302
+ },
303
+ "postTestFailure": {
304
+ "type": "boolean",
305
+ "default": true,
306
+ "description": "Consider Codex after targeted tests fail."
307
+ },
308
+ "afterFailedAttempts": {
309
+ "type": "boolean",
310
+ "default": true,
311
+ "description": "Consider Codex after repeated failed fix attempts."
312
+ },
313
+ "preCommit": {
314
+ "type": "boolean",
315
+ "default": false,
316
+ "description": "Consider lifecycle policy before commit. The mechanical codexReview preCommitHook remains the hard gate."
317
+ },
318
+ "stopWarm": {
319
+ "type": "boolean",
320
+ "default": false,
321
+ "description": "Consider passive Stop-time warm checks. Keep off unless background participation is desired."
322
+ }
323
+ }
324
+ },
325
+ "codexLifecycleThresholds": {
326
+ "type": "object",
327
+ "additionalProperties": false,
328
+ "description": "Deterministic score thresholds used by composer_codex_lifecycle_decide.",
329
+ "properties": {
330
+ "minScore": {
331
+ "type": "number",
332
+ "minimum": 0,
333
+ "maximum": 100,
334
+ "default": 60,
335
+ "description": "Minimum score required to return ask/run instead of skip."
336
+ },
337
+ "minExpectedOutputTokens": {
338
+ "type": "integer",
339
+ "minimum": 1,
340
+ "default": 500,
341
+ "description": "Expected output size that contributes to the lifecycle score."
342
+ },
343
+ "minChangedFiles": {
344
+ "type": "integer",
345
+ "minimum": 1,
346
+ "default": 2,
347
+ "description": "Changed-file count that contributes to the lifecycle score."
348
+ },
349
+ "minDiffLines": {
350
+ "type": "integer",
351
+ "minimum": 1,
352
+ "default": 80,
353
+ "description": "Diff-line count that contributes to the lifecycle score."
354
+ },
355
+ "failedAttempts": {
356
+ "type": "integer",
357
+ "minimum": 1,
358
+ "default": 2,
359
+ "description": "Failed attempts required before the repeated-failure score applies."
360
+ }
361
+ }
362
+ },
363
+ "codexLifecycleFallback": {
364
+ "type": "object",
365
+ "additionalProperties": false,
366
+ "description": "Optional fallback provider roles used when the primary Codex lifecycle provider is unavailable.",
367
+ "properties": {
368
+ "enabled": {
369
+ "type": "boolean",
370
+ "default": false,
371
+ "description": "When true, lifecycle runs try fallback roles after coderCli is unavailable."
372
+ },
373
+ "order": {
374
+ "type": "array",
375
+ "minItems": 1,
376
+ "default": [
377
+ "reviewerClaude",
378
+ "reviewer",
379
+ "coder"
380
+ ],
381
+ "items": {
382
+ "type": "string",
383
+ "enum": [
384
+ "researcher",
385
+ "coder",
386
+ "reviewer",
387
+ "reviewerClaude",
388
+ "coderCli"
389
+ ]
390
+ },
391
+ "description": "Provider role fallback order after coderCli. Duplicate coderCli entries are ignored at runtime."
392
+ }
393
+ }
394
+ },
201
395
  "codexPreCommitHook": {
202
396
  "type": "object",
203
397
  "required": [
@@ -223,11 +417,16 @@
223
417
  "timeoutMs": {
224
418
  "type": "integer",
225
419
  "minimum": 1,
226
- "description": "Review wall-clock timeout in milliseconds. Omitted = 120000."
420
+ "description": "Review wall-clock timeout in milliseconds. Omitted = 900000."
227
421
  },
228
422
  "failClosed": {
229
423
  "type": "boolean",
230
424
  "description": "If true, reviewer unavailability blocks commit. Omitted = false."
425
+ },
426
+ "maxConsecutiveBlocks": {
427
+ "type": "integer",
428
+ "minimum": 0,
429
+ "description": "Opt-in anti-oscillation cap. After this many consecutive needs-attention blocks for the same branch/base, allow once with a loud audit entry and reset. Omitted or 0 = disabled."
231
430
  }
232
431
  }
233
432
  },
@@ -312,7 +511,7 @@
312
511
  "required": [
313
512
  "type"
314
513
  ],
315
- "description": "Extended-thinking knob for Anthropic-compat providers (GLM glm-5.1, glm-4.6+, Claude). Ignored by other providers. Added 2026-05-25 for v0.1.3.",
514
+ "description": "Extended-thinking knob for Anthropic-compat providers (GLM glm-5.2, glm-4.6+, Claude). Ignored by other providers. Added 2026-05-25 for v0.1.3.",
316
515
  "properties": {
317
516
  "type": {
318
517
  "type": "string",
@@ -334,6 +533,11 @@
334
533
  "minimum": 1,
335
534
  "description": "CLIProvider wall-clock timeout in milliseconds for one attempt. Ignored by non-CLI providers."
336
535
  },
536
+ "totalWallClockMs": {
537
+ "type": "integer",
538
+ "minimum": 1,
539
+ "description": "Hard total_wall_clock_ms cap in milliseconds for one CLIProvider invocation, including all retries. Omitted = timeoutMs."
540
+ },
337
541
  "maxBuffer": {
338
542
  "type": "integer",
339
543
  "minimum": 1,
@@ -0,0 +1,24 @@
1
+ export interface CleanupOptions {
2
+ oracle?: boolean;
3
+ state?: boolean;
4
+ goals?: boolean;
5
+ olderThanMs?: number;
6
+ dryRun?: boolean;
7
+ }
8
+ interface CleanupEnv {
9
+ projectRoot: string;
10
+ stateDir: string;
11
+ nowMs: number;
12
+ }
13
+ export declare function defaultStateDir(): string;
14
+ /** Pure: returns the absolute entry paths that cleanup would remove. */
15
+ export declare function planCleanup(opts: CleanupOptions, env: CleanupEnv): string[];
16
+ /** Parse `cleanup` flags. Returns CleanupOptions or an { error } message. */
17
+ export declare function parseCleanupArgs(flags: readonly string[]): CleanupOptions | {
18
+ error: string;
19
+ };
20
+ export declare function runCleanup(opts: CleanupOptions, env?: Partial<CleanupEnv>): {
21
+ removed: string[];
22
+ dryRun: boolean;
23
+ };
24
+ export {};
@@ -0,0 +1,151 @@
1
+ import { existsSync, lstatSync, readdirSync, rmSync, statSync } from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { isTerminal, readGoal } from "../util/goal.js";
5
+ function cleanupRoots(env) {
6
+ return [
7
+ { dir: path.join(env.projectRoot, ".composer", "oracle"), isOracle: true, isState: false },
8
+ { dir: path.join(env.projectRoot, ".composer", "results"), isOracle: false, isState: false },
9
+ { dir: path.join(env.projectRoot, ".composer", "goals"), isOracle: false, isState: false, kind: "goals" },
10
+ { dir: path.join(env.stateDir, "oracle-jobs"), isOracle: true, isState: true },
11
+ { dir: path.join(env.stateDir, "oracle-locks"), isOracle: true, isState: true },
12
+ { dir: path.join(env.stateDir, "codex-lifecycle"), isOracle: false, isState: true },
13
+ { dir: path.join(env.stateDir, "audit"), isOracle: false, isState: true },
14
+ ];
15
+ }
16
+ export function defaultStateDir() {
17
+ const override = process.env["COMPOSER_STATE_DIR"]?.trim();
18
+ if (override)
19
+ return path.resolve(override);
20
+ return path.join(os.homedir(), ".local", "state", "composer");
21
+ }
22
+ /** Pure: returns the absolute entry paths that cleanup would remove. */
23
+ export function planCleanup(opts, env) {
24
+ const roots = cleanupRoots(env).filter((r) => (!opts.oracle || r.isOracle) && (!opts.state || r.isState) && (opts.goals || r.kind !== "goals"));
25
+ const out = [];
26
+ for (const root of roots) {
27
+ if (!existsSync(root.dir))
28
+ continue;
29
+ let st;
30
+ try {
31
+ st = lstatSync(root.dir);
32
+ }
33
+ catch {
34
+ continue;
35
+ }
36
+ if (st.isSymbolicLink() || !st.isDirectory())
37
+ continue; // safety: never follow symlinks
38
+ let entries;
39
+ try {
40
+ entries = readdirSync(root.dir);
41
+ }
42
+ catch {
43
+ continue;
44
+ }
45
+ if (root.kind === "goals") {
46
+ for (const name of entries) {
47
+ if (!name.endsWith(".json"))
48
+ continue;
49
+ const full = path.join(root.dir, name);
50
+ if (opts.olderThanMs !== undefined) {
51
+ let mtime = 0;
52
+ try {
53
+ mtime = statSync(full).mtimeMs;
54
+ }
55
+ catch {
56
+ continue;
57
+ }
58
+ if (env.nowMs - mtime < opts.olderThanMs)
59
+ continue;
60
+ }
61
+ const goalId = name.slice(0, -".json".length);
62
+ try {
63
+ const record = readGoal(env.projectRoot, goalId);
64
+ if (record && isTerminal(record.state))
65
+ out.push(full);
66
+ }
67
+ catch {
68
+ continue;
69
+ }
70
+ }
71
+ continue;
72
+ }
73
+ for (const name of entries) {
74
+ const full = path.join(root.dir, name);
75
+ if (opts.olderThanMs !== undefined) {
76
+ let mtime = 0;
77
+ try {
78
+ mtime = statSync(full).mtimeMs;
79
+ }
80
+ catch {
81
+ continue;
82
+ }
83
+ if (env.nowMs - mtime < opts.olderThanMs)
84
+ continue;
85
+ }
86
+ out.push(full);
87
+ }
88
+ }
89
+ return out;
90
+ }
91
+ /** Parse `cleanup` flags. Returns CleanupOptions or an { error } message. */
92
+ export function parseCleanupArgs(flags) {
93
+ const opts = {};
94
+ for (let i = 0; i < flags.length; i++) {
95
+ const f = flags[i];
96
+ if (f === "--oracle")
97
+ opts.oracle = true;
98
+ else if (f === "--state")
99
+ opts.state = true;
100
+ else if (f === "--goals")
101
+ opts.goals = true;
102
+ else if (f === "--dry-run")
103
+ opts.dryRun = true;
104
+ else if (f === "--older-than" || f?.startsWith("--older-than=")) {
105
+ const raw = f.includes("=") ? f.slice(f.indexOf("=") + 1) : flags[++i];
106
+ const ms = parseDuration(raw);
107
+ if (ms === null)
108
+ return { error: `cleanup: invalid --older-than value: ${raw ?? "(missing)"} (use e.g. 14d, 12h, 30m)` };
109
+ opts.olderThanMs = ms;
110
+ }
111
+ else
112
+ return { error: `cleanup: unknown argument: ${f}` };
113
+ }
114
+ return opts;
115
+ }
116
+ function parseDuration(raw) {
117
+ if (!raw)
118
+ return null;
119
+ const m = /^(\d+)([dhm])$/.exec(raw.trim());
120
+ if (!m)
121
+ return null;
122
+ const n = Number(m[1]);
123
+ const unit = m[2];
124
+ const mult = unit === "d" ? 86400000 : unit === "h" ? 3600000 : 60000;
125
+ return n * mult;
126
+ }
127
+ export function runCleanup(opts, env) {
128
+ const resolved = {
129
+ projectRoot: env?.projectRoot ?? process.cwd(),
130
+ stateDir: env?.stateDir ?? defaultStateDir(),
131
+ nowMs: env?.nowMs ?? Date.now(),
132
+ };
133
+ const targets = planCleanup(opts, resolved);
134
+ for (const t of targets) {
135
+ if (opts.dryRun) {
136
+ process.stdout.write(`would remove: ${t}\n`);
137
+ }
138
+ else {
139
+ try {
140
+ rmSync(t, { recursive: true, force: true });
141
+ process.stdout.write(`removed: ${t}\n`);
142
+ }
143
+ catch (e) {
144
+ process.stderr.write(`failed to remove ${t}: ${e instanceof Error ? e.message : String(e)}\n`);
145
+ }
146
+ }
147
+ }
148
+ process.stdout.write(`cleanup: ${opts.dryRun ? "would remove" : "removed"} ${targets.length} item(s)\n`);
149
+ return { removed: targets, dryRun: opts.dryRun === true };
150
+ }
151
+ //# sourceMappingURL=cleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../src/cli/cleanup.ts"],"names":[],"mappings":"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"}
@@ -15,7 +15,19 @@ export interface DoctorReport {
15
15
  export declare function resolveCodexPluginRoot(pluginsDir: string): CodexPluginRoot | null;
16
16
  export declare function buildConfigChecks(config: ComposerConfig): DoctorCheck[];
17
17
  export declare function isHealthy(checks: DoctorCheck[]): boolean;
18
+ export declare const ORACLE_BAD_NODE_MAJORS: number[];
19
+ export declare function classifyOracleNode(input: {
20
+ oracleFound: boolean;
21
+ nodeVersion: string | null;
22
+ oraclePlannerConfigured: boolean;
23
+ }): DoctorCheck;
24
+ export declare function classifyPreCommitJq(input: {
25
+ gateFailClosedEnabled: boolean;
26
+ jqAvailable: boolean;
27
+ }): DoctorCheck;
28
+ export declare function checkOracleRuntime(config: ComposerConfig | null): DoctorCheck;
18
29
  export declare function runDoctor(opts: {
19
30
  cwd: string;
20
31
  verbose?: boolean;
21
32
  }): Promise<DoctorReport>;
33
+ export declare function checkGitPreCommitHook(cwd: string, config: ComposerConfig): DoctorCheck;