@event4u/agent-config 11.0.0 → 12.0.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 (249) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +71 -249
  3. package/dist/agent-src/commands/agent-handoff.md +0 -1
  4. package/dist/agent-src/commands/agent-status.md +0 -1
  5. package/dist/agent-src/commands/agents/audit.md +0 -1
  6. package/dist/agent-src/commands/agents/init.md +0 -1
  7. package/dist/agent-src/commands/agents/optimize.md +0 -1
  8. package/dist/agent-src/commands/agents/user/accept.md +0 -1
  9. package/dist/agent-src/commands/agents/user/delete.md +0 -1
  10. package/dist/agent-src/commands/agents/user/init.md +0 -1
  11. package/dist/agent-src/commands/agents/user/review.md +0 -1
  12. package/dist/agent-src/commands/agents/user/show.md +0 -1
  13. package/dist/agent-src/commands/agents/user/update.md +0 -1
  14. package/dist/agent-src/commands/agents/user.md +0 -1
  15. package/dist/agent-src/commands/agents.md +0 -1
  16. package/dist/agent-src/commands/analytics/prune.md +0 -1
  17. package/dist/agent-src/commands/analytics/show.md +0 -1
  18. package/dist/agent-src/commands/analytics.md +0 -1
  19. package/dist/agent-src/commands/analyze/conformance.md +0 -1
  20. package/dist/agent-src/commands/analyze/decision.md +0 -1
  21. package/dist/agent-src/commands/analyze/inbox.md +0 -1
  22. package/dist/agent-src/commands/analyze/incident.md +0 -1
  23. package/dist/agent-src/commands/analyze/near-miss.md +0 -1
  24. package/dist/agent-src/commands/analyze/postmortem.md +0 -1
  25. package/dist/agent-src/commands/analyze/premortem.md +0 -1
  26. package/dist/agent-src/commands/analyze/reference-repo.md +0 -1
  27. package/dist/agent-src/commands/analyze.md +0 -1
  28. package/dist/agent-src/commands/brand/identity.md +0 -1
  29. package/dist/agent-src/commands/brand/review.md +0 -1
  30. package/dist/agent-src/commands/brand/strategy.md +0 -1
  31. package/dist/agent-src/commands/brand/tokens.md +0 -1
  32. package/dist/agent-src/commands/brand/voice.md +0 -1
  33. package/dist/agent-src/commands/brand.md +0 -1
  34. package/dist/agent-src/commands/bug/fix.md +0 -1
  35. package/dist/agent-src/commands/bug/investigate.md +0 -1
  36. package/dist/agent-src/commands/bug.md +0 -1
  37. package/dist/agent-src/commands/challenge-me/vision.md +0 -1
  38. package/dist/agent-src/commands/challenge-me/with-docs.md +0 -1
  39. package/dist/agent-src/commands/challenge-me.md +0 -1
  40. package/dist/agent-src/commands/chat-history/import.md +0 -1
  41. package/dist/agent-src/commands/chat-history.md +0 -1
  42. package/dist/agent-src/commands/check-current-md.md +0 -1
  43. package/dist/agent-src/commands/commit/in-chunks.md +0 -1
  44. package/dist/agent-src/commands/commit.md +0 -1
  45. package/dist/agent-src/commands/condense.md +0 -1
  46. package/dist/agent-src/commands/context/create.md +0 -1
  47. package/dist/agent-src/commands/context/refactor.md +0 -1
  48. package/dist/agent-src/commands/context.md +0 -1
  49. package/dist/agent-src/commands/contribution-precheck.md +0 -1
  50. package/dist/agent-src/commands/cost/profile.md +0 -1
  51. package/dist/agent-src/commands/cost/report.md +0 -1
  52. package/dist/agent-src/commands/cost.md +0 -1
  53. package/dist/agent-src/commands/council/analysis.md +0 -1
  54. package/dist/agent-src/commands/council/debate.md +0 -1
  55. package/dist/agent-src/commands/council/default.md +0 -1
  56. package/dist/agent-src/commands/council/design.md +0 -1
  57. package/dist/agent-src/commands/council/optimize.md +0 -1
  58. package/dist/agent-src/commands/council/pr.md +0 -1
  59. package/dist/agent-src/commands/council.md +0 -1
  60. package/dist/agent-src/commands/design-system/capture.md +0 -1
  61. package/dist/agent-src/commands/design-system/generate.md +0 -1
  62. package/dist/agent-src/commands/design-system/import.md +0 -1
  63. package/dist/agent-src/commands/design-system.md +0 -1
  64. package/dist/agent-src/commands/estimate-ticket.md +0 -1
  65. package/dist/agent-src/commands/explain-run.md +0 -1
  66. package/dist/agent-src/commands/feature/dev.md +0 -1
  67. package/dist/agent-src/commands/feature/explore.md +0 -1
  68. package/dist/agent-src/commands/feature/plan.md +0 -1
  69. package/dist/agent-src/commands/feature/refactor.md +0 -1
  70. package/dist/agent-src/commands/feature/roadmap.md +0 -1
  71. package/dist/agent-src/commands/feature.md +0 -1
  72. package/dist/agent-src/commands/fix/ci.md +0 -1
  73. package/dist/agent-src/commands/fix/comments.md +0 -1
  74. package/dist/agent-src/commands/fix/portability.md +0 -1
  75. package/dist/agent-src/commands/fix/pr-comments-loop.md +0 -1
  76. package/dist/agent-src/commands/fix/pr-comments.md +0 -1
  77. package/dist/agent-src/commands/fix/quality.md +0 -1
  78. package/dist/agent-src/commands/fix/refs.md +0 -1
  79. package/dist/agent-src/commands/fix/route.md +0 -1
  80. package/dist/agent-src/commands/fix/seeder.md +0 -1
  81. package/dist/agent-src/commands/fix.md +0 -1
  82. package/dist/agent-src/commands/ghostwriter/delete.md +0 -1
  83. package/dist/agent-src/commands/ghostwriter/fetch.md +0 -1
  84. package/dist/agent-src/commands/ghostwriter/list.md +0 -1
  85. package/dist/agent-src/commands/ghostwriter/show.md +0 -1
  86. package/dist/agent-src/commands/ghostwriter/write.md +0 -1
  87. package/dist/agent-src/commands/ghostwriter.md +0 -1
  88. package/dist/agent-src/commands/grill-me.md +0 -1
  89. package/dist/agent-src/commands/humanize.md +0 -1
  90. package/dist/agent-src/commands/image/analyse.md +0 -1
  91. package/dist/agent-src/commands/image/create.md +0 -1
  92. package/dist/agent-src/commands/image/verify.md +0 -1
  93. package/dist/agent-src/commands/image.md +0 -1
  94. package/dist/agent-src/commands/implement-ticket.md +0 -1
  95. package/dist/agent-src/commands/jira-ticket.md +0 -1
  96. package/dist/agent-src/commands/judge/on-diff.md +0 -1
  97. package/dist/agent-src/commands/judge/solo.md +0 -1
  98. package/dist/agent-src/commands/judge/steps.md +0 -1
  99. package/dist/agent-src/commands/judge.md +0 -1
  100. package/dist/agent-src/commands/knowledge/cross-repo.md +0 -1
  101. package/dist/agent-src/commands/knowledge/forget.md +0 -1
  102. package/dist/agent-src/commands/knowledge/ingest.md +0 -1
  103. package/dist/agent-src/commands/knowledge/list.md +0 -1
  104. package/dist/agent-src/commands/knowledge.md +0 -1
  105. package/dist/agent-src/commands/memory/add.md +0 -1
  106. package/dist/agent-src/commands/memory/learn-low-impact.md +0 -1
  107. package/dist/agent-src/commands/memory/load.md +0 -1
  108. package/dist/agent-src/commands/memory/mine-session.md +0 -1
  109. package/dist/agent-src/commands/memory/promote.md +0 -1
  110. package/dist/agent-src/commands/memory/propose.md +0 -1
  111. package/dist/agent-src/commands/memory.md +0 -1
  112. package/dist/agent-src/commands/mission/upgrade.md +0 -1
  113. package/dist/agent-src/commands/mode.md +0 -1
  114. package/dist/agent-src/commands/module/create.md +0 -1
  115. package/dist/agent-src/commands/module/explore.md +0 -1
  116. package/dist/agent-src/commands/module.md +0 -1
  117. package/dist/agent-src/commands/optimize/agents-dir.md +0 -1
  118. package/dist/agent-src/commands/optimize/augmentignore.md +0 -1
  119. package/dist/agent-src/commands/optimize/deep.md +0 -1
  120. package/dist/agent-src/commands/optimize/project.md +0 -1
  121. package/dist/agent-src/commands/optimize/prompt.md +0 -1
  122. package/dist/agent-src/commands/optimize/rtk.md +0 -1
  123. package/dist/agent-src/commands/optimize/skills.md +0 -1
  124. package/dist/agent-src/commands/optimize.md +0 -1
  125. package/dist/agent-src/commands/orchestrate.md +0 -1
  126. package/dist/agent-src/commands/override/create.md +0 -1
  127. package/dist/agent-src/commands/override/manage.md +0 -1
  128. package/dist/agent-src/commands/override.md +0 -1
  129. package/dist/agent-src/commands/package/reset.md +0 -1
  130. package/dist/agent-src/commands/package/test.md +0 -1
  131. package/dist/agent-src/commands/package.md +0 -1
  132. package/dist/agent-src/commands/post-as/ghostwriter.md +0 -1
  133. package/dist/agent-src/commands/post-as/me.md +0 -1
  134. package/dist/agent-src/commands/post-as.md +0 -1
  135. package/dist/agent-src/commands/pr/create/description-only.md +0 -1
  136. package/dist/agent-src/commands/pr/create.md +23 -9
  137. package/dist/agent-src/commands/prediction-pool.md +0 -1
  138. package/dist/agent-src/commands/prepare-for-review.md +0 -1
  139. package/dist/agent-src/commands/profile/activate.md +0 -1
  140. package/dist/agent-src/commands/profile/deactivate.md +0 -1
  141. package/dist/agent-src/commands/profile/show.md +0 -1
  142. package/dist/agent-src/commands/profile.md +0 -1
  143. package/dist/agent-src/commands/project/analyze.md +0 -1
  144. package/dist/agent-src/commands/project/health.md +0 -1
  145. package/dist/agent-src/commands/project.md +0 -1
  146. package/dist/agent-src/commands/refine-ticket.md +0 -1
  147. package/dist/agent-src/commands/research/deep.md +0 -1
  148. package/dist/agent-src/commands/research/report.md +0 -1
  149. package/dist/agent-src/commands/research.md +0 -1
  150. package/dist/agent-src/commands/review/changes.md +0 -1
  151. package/dist/agent-src/commands/review/routing.md +0 -1
  152. package/dist/agent-src/commands/review.md +0 -1
  153. package/dist/agent-src/commands/roadmap/ai-council.md +0 -1
  154. package/dist/agent-src/commands/roadmap/create.md +0 -1
  155. package/dist/agent-src/commands/roadmap/materialize.md +0 -1
  156. package/dist/agent-src/commands/roadmap/next.md +0 -1
  157. package/dist/agent-src/commands/roadmap/process-full.md +0 -1
  158. package/dist/agent-src/commands/roadmap/process-phase.md +0 -1
  159. package/dist/agent-src/commands/roadmap/process-step.md +0 -1
  160. package/dist/agent-src/commands/roadmap.md +0 -1
  161. package/dist/agent-src/commands/rule-compliance-audit.md +0 -1
  162. package/dist/agent-src/commands/security-audit-config.md +0 -1
  163. package/dist/agent-src/commands/skill/preview.md +0 -1
  164. package/dist/agent-src/commands/skill.md +0 -1
  165. package/dist/agent-src/commands/skills/discover.md +0 -1
  166. package/dist/agent-src/commands/skills.md +0 -1
  167. package/dist/agent-src/commands/sync/agent-settings.md +0 -1
  168. package/dist/agent-src/commands/sync/gitignore/fix.md +0 -1
  169. package/dist/agent-src/commands/sync/gitignore.md +0 -1
  170. package/dist/agent-src/commands/sync.md +0 -1
  171. package/dist/agent-src/commands/tdd/green.md +0 -1
  172. package/dist/agent-src/commands/tdd/red.md +0 -1
  173. package/dist/agent-src/commands/tdd/refactor.md +0 -1
  174. package/dist/agent-src/commands/tdd.md +0 -1
  175. package/dist/agent-src/commands/team/adversarial.md +0 -1
  176. package/dist/agent-src/commands/team/delegate.md +0 -1
  177. package/dist/agent-src/commands/team/review.md +0 -1
  178. package/dist/agent-src/commands/team/status.md +0 -1
  179. package/dist/agent-src/commands/team-knowledge/bootstrap.md +0 -1
  180. package/dist/agent-src/commands/team-knowledge/consolidate.md +0 -1
  181. package/dist/agent-src/commands/team-knowledge.md +0 -1
  182. package/dist/agent-src/commands/team.md +0 -1
  183. package/dist/agent-src/commands/tests/create.md +0 -1
  184. package/dist/agent-src/commands/tests/e2e-heal.md +0 -1
  185. package/dist/agent-src/commands/tests/e2e-plan.md +0 -1
  186. package/dist/agent-src/commands/tests/execute.md +0 -1
  187. package/dist/agent-src/commands/tests.md +0 -1
  188. package/dist/agent-src/commands/threat-model.md +0 -1
  189. package/dist/agent-src/commands/update-form-request-messages.md +0 -1
  190. package/dist/agent-src/commands/upstream-contribute.md +0 -1
  191. package/dist/agent-src/commands/video/from-script.md +0 -1
  192. package/dist/agent-src/commands/video/from-song.md +0 -1
  193. package/dist/agent-src/commands/video/scene.md +0 -1
  194. package/dist/agent-src/commands/video/stitch.md +0 -1
  195. package/dist/agent-src/commands/video/storyboard.md +0 -1
  196. package/dist/agent-src/commands/video.md +0 -1
  197. package/dist/agent-src/commands/work.md +0 -1
  198. package/dist/agent-src/commands/worktree/cleanup.md +0 -1
  199. package/dist/agent-src/commands/worktree/create.md +0 -1
  200. package/dist/agent-src/commands/worktree/status.md +0 -1
  201. package/dist/agent-src/commands/worktree/verify.md +0 -1
  202. package/dist/agent-src/commands/worktree.md +0 -1
  203. package/dist/agent-src/skills/docx-authoring/SKILL.md +1 -0
  204. package/dist/agent-src/skills/git-workflow/SKILL.md +9 -1
  205. package/dist/agent-src/skills/pdf-tools/SKILL.md +1 -0
  206. package/dist/agent-src/skills/skill-writing/SKILL.md +35 -0
  207. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  208. package/dist/cli/commands/commands.candidates.test.js +1 -1
  209. package/dist/cli/commands/commands.candidates.test.js.map +1 -1
  210. package/dist/cli/commands/commands.js +9 -15
  211. package/dist/cli/commands/commands.js.map +1 -1
  212. package/dist/cli/commands/profiles.test.js +7 -7
  213. package/dist/cli/commands/profiles.test.js.map +1 -1
  214. package/dist/cli/discovery/loadManifest.js.map +1 -1
  215. package/dist/cli/main.js +2 -2
  216. package/dist/cli/main.js.map +1 -1
  217. package/dist/cli-delegate/cmd_conformance.js +14 -2
  218. package/dist/discovery/deprecation-report.md +1 -1
  219. package/dist/discovery/discovery-manifest.json +211 -410
  220. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  221. package/dist/discovery/discovery-manifest.summary.md +2 -2
  222. package/dist/discovery/dormancy-report.md +1 -1
  223. package/dist/discovery/orphan-report.md +1 -1
  224. package/dist/discovery/packs.json +3 -3
  225. package/dist/discovery/trust-report.md +1 -1
  226. package/dist/discovery/workspaces.json +3 -3
  227. package/dist/hooks/dispatch.js +14 -2
  228. package/dist/mcp/registry-manifest.json +3 -3
  229. package/dist/mcp/server.json +2 -2
  230. package/dist/mcp/server.mjs +46 -5
  231. package/docs/MIGRATION.md +1 -0
  232. package/docs/contracts/settings-classes.md +41 -0
  233. package/package.json +1 -1
  234. package/src/config/agent-settings.template.yml +34 -0
  235. package/src/config/gate-violation-baselines.json +3 -3
  236. package/src/scripts/_dispatch.bash +42 -5
  237. package/src/scripts/audit_command_surface.ts +21 -15
  238. package/src/scripts/build_catalog_index.ts +1 -1
  239. package/src/scripts/build_discovery_manifest.ts +30 -34
  240. package/src/scripts/check_branch_freshness.ts +210 -61
  241. package/src/scripts/gen_discovery_baseline.ts +3 -3
  242. package/src/scripts/hook_manifest.yaml +20 -0
  243. package/src/scripts/hooks/subagent_ledger_hook.ts +17 -4
  244. package/src/scripts/lint_command_tiers.ts +29 -75
  245. package/src/scripts/lint_originality.ts +101 -14
  246. package/src/scripts/schemas/command.schema.json +4 -9
  247. package/src/scripts/schemas/skill.schema.json +10 -1
  248. package/src/scripts/skill_linter.ts +82 -2
  249. package/src/scripts/worktree_cleanup_check.ts +111 -7
@@ -34,6 +34,7 @@ import { execFileSync } from 'node:child_process';
34
34
  import * as fs from 'node:fs';
35
35
  import * as path from 'node:path';
36
36
  import { fileURLToPath, pathToFileURL } from 'node:url';
37
+ import { read_live_records, register_dir } from './_lib/session_register.js';
37
38
 
38
39
  export interface CheckResult {
39
40
  allowed: boolean;
@@ -304,8 +305,20 @@ function isAncestor(repoPath: string, branch: string, trunk: string): boolean {
304
305
  }
305
306
  }
306
307
 
307
- export function isStandardLocation(repoPath: string, worktreePath: string): boolean {
308
- const rel = path.relative(canonical(repoPath), canonical(worktreePath));
308
+ /**
309
+ * `basePath` MUST be the main worktree, never the invoking repo path.
310
+ *
311
+ * Measured 2026-08-13, and the failure is total rather than partial: called with
312
+ * a linked worktree as the base, every sibling worktree resolves to `..` and the
313
+ * safe set collapses to empty. Same binary, same repo, same minute — from inside
314
+ * `.claude/worktrees/<branch>`: 304 registered, safe 0, 278 "non-standard"; from
315
+ * the main checkout: safe 181, 81 non-standard. A maintainer who ran the
316
+ * inventory from a worktree would read "nothing to clean" and conclude the
317
+ * estate was fine, which is the worst shape a cleanup tool can fail in — it
318
+ * fails silently, and toward inaction.
319
+ */
320
+ export function isStandardLocation(basePath: string, worktreePath: string): boolean {
321
+ const rel = path.relative(canonical(basePath), canonical(worktreePath));
309
322
  if (rel.startsWith('..') || path.isAbsolute(rel)) return false;
310
323
  return STANDARD_WORKTREE_DIRS.some(
311
324
  (dir) => rel === dir || rel.startsWith(`${dir}${path.sep}`),
@@ -348,16 +361,70 @@ function lastGitActivity(worktreePath: string): Date | null {
348
361
  * Classify every worktree. `now` is injectable so the live-window boundary is
349
362
  * testable rather than wall-clock dependent.
350
363
  */
351
- export function buildInventory(repoPath: string, now: Date = new Date()): Inventory {
364
+ /**
365
+ * Two conditions the `safe` predicate does NOT carry by default, both off unless
366
+ * asked for. They exist because an approval can be stricter than the tool, and
367
+ * silently removing under the looser predicate is the substitution such an
368
+ * approval is written to prevent.
369
+ *
370
+ * `minAgeDays` is a floor on git inactivity, layered ON TOP of the 48-hour live
371
+ * window rather than replacing it: 48h answers "is someone in it right now", a
372
+ * 60-day floor answers "is this abandoned". Different questions.
373
+ *
374
+ * `excludeLiveSessions` reads the session register — real records with a real
375
+ * `worktree` path and a real TTL — instead of inferring occupancy from file
376
+ * mtime, which this module's own header already rules out as a liveness signal.
377
+ */
378
+ export interface InventoryOptions {
379
+ now?: Date;
380
+ minAgeDays?: number | null;
381
+ excludeLiveSessions?: boolean;
382
+ }
383
+
384
+ export function buildInventory(
385
+ repoPath: string,
386
+ nowOrOptions: Date | InventoryOptions = new Date(),
387
+ ): Inventory {
388
+ const opts: InventoryOptions =
389
+ nowOrOptions instanceof Date ? { now: nowOrOptions } : nowOrOptions;
390
+ const now = opts.now ?? new Date();
391
+ const minAgeDays = opts.minAgeDays ?? null;
392
+ const ageCutoff = minAgeDays === null ? null : now.getTime() - minAgeDays * 86400 * 1000;
393
+ return buildInventoryInner(repoPath, now, ageCutoff, minAgeDays, opts.excludeLiveSessions === true);
394
+ }
395
+
396
+ function buildInventoryInner(
397
+ repoPath: string,
398
+ nowArg: Date,
399
+ ageCutoff: number | null,
400
+ minAgeDays: number | null,
401
+ excludeLiveSessions: boolean,
402
+ ): Inventory {
403
+ const now = nowArg;
352
404
  const trunk = resolveTrunk(repoPath);
353
405
  const entries = listWorktrees(repoPath);
354
406
  const mainPath = canonical(entries.length > 0 ? entries[0]!.path : repoPath);
355
407
  const liveCutoff = now.getTime() - LIVE_WINDOW_HOURS * 3600 * 1000;
356
408
 
409
+ // Registered session worktrees, canonicalised so the comparison survives a
410
+ // symlinked checkout root the same way every other path here does. Empty set
411
+ // when the option is off, when no register directory exists (the normal
412
+ // state before any session registers), or when every record has expired.
413
+ const sessionPaths = new Set<string>();
414
+ if (excludeLiveSessions) {
415
+ const dir = register_dir(mainPath);
416
+ if (dir !== null) {
417
+ for (const rec of read_live_records(dir, { now })) {
418
+ sessionPaths.add(canonical(rec.worktree));
419
+ }
420
+ }
421
+ }
422
+
357
423
  const rows: InventoryRow[] = entries.map((e) => {
358
424
  const resolved = canonical(e.path);
359
425
  const isMain = resolved === mainPath;
360
- const standardLocation = isMain ? true : isStandardLocation(repoPath, resolved);
426
+ // `mainPath`, NOT `repoPath` — see isStandardLocation's contract.
427
+ const standardLocation = isMain ? true : isStandardLocation(mainPath, resolved);
361
428
  const reasons: string[] = [];
362
429
 
363
430
  if (!fs.existsSync(resolved)) {
@@ -389,6 +456,20 @@ export function buildInventory(repoPath: string, now: Date = new Date()): Invent
389
456
  if (e.branch === null) {
390
457
  reasons.push('detached HEAD — no branch to judge reachability for');
391
458
  }
459
+ if (sessionPaths.has(resolved)) {
460
+ reasons.push('a live agent session is registered in this worktree');
461
+ }
462
+ if (ageCutoff !== null && (activity === null || activity.getTime() >= ageCutoff)) {
463
+ // `activity === null` disqualifies rather than passes: an unreadable
464
+ // git-dir mtime is absence of evidence, and under an explicit
465
+ // minimum-age floor that has to read as "cannot show it is old
466
+ // enough", never as "old enough".
467
+ reasons.push(
468
+ activity === null
469
+ ? `git activity unreadable — cannot prove ${minAgeDays}+ days of inactivity`
470
+ : `git activity within the last ${minAgeDays} days`,
471
+ );
472
+ }
392
473
  if (!standardLocation) {
393
474
  reasons.push('non-standard location — outside the conventional worktree roots');
394
475
  }
@@ -465,7 +546,7 @@ export function removalPlan(inv: Inventory): string[] {
465
546
  function usage(): never {
466
547
  process.stderr.write(
467
548
  'usage: worktree_cleanup_check check <worktree-path> | scope-overlap [repo-path] | ' +
468
- 'inventory [repo-path] [--json|--plan]\n',
549
+ 'inventory [repo-path] [--json|--plan] [--min-age-days=N] [--exclude-live-sessions]\n',
469
550
  );
470
551
  process.exit(2);
471
552
  }
@@ -509,9 +590,32 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
509
590
  const rest = argv.slice(1);
510
591
  const flags = rest.filter((a) => a.startsWith('--'));
511
592
  const positional = rest.filter((a) => !a.startsWith('--'));
512
- if (positional.length > 1 || flags.some((f) => f !== '--json' && f !== '--plan')) usage();
593
+ const KNOWN = ['--json', '--plan', '--exclude-live-sessions'];
594
+ const ageFlag = flags.find((f) => f.startsWith('--min-age-days='));
595
+ if (
596
+ positional.length > 1 ||
597
+ flags.some((f) => !KNOWN.includes(f) && !f.startsWith('--min-age-days='))
598
+ ) {
599
+ usage();
600
+ }
601
+ let minAgeDays: number | null = null;
602
+ if (ageFlag !== undefined) {
603
+ const raw = ageFlag.slice('--min-age-days='.length);
604
+ const n = Number(raw);
605
+ // Refuse rather than silently fall back to null: a typo'd floor that
606
+ // reads as "no floor" would widen the safe set at exactly the moment
607
+ // the caller asked to narrow it.
608
+ if (!Number.isFinite(n) || !Number.isInteger(n) || n < 0) {
609
+ process.stderr.write(`--min-age-days needs a non-negative integer, got '${raw}'\n`);
610
+ return 2;
611
+ }
612
+ minAgeDays = n;
613
+ }
513
614
  const repo = path.resolve(positional[0] ?? '.');
514
- const inv = buildInventory(repo);
615
+ const inv = buildInventory(repo, {
616
+ minAgeDays,
617
+ excludeLiveSessions: flags.includes('--exclude-live-sessions'),
618
+ });
515
619
 
516
620
  if (flags.includes('--json')) {
517
621
  process.stdout.write(`${JSON.stringify(inv, null, 2)}\n`);