@paths.design/caws-cli 11.1.5 → 11.1.7

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 (93) hide show
  1. package/README.md +1 -1
  2. package/dist/init/hook-packs/manifest-claude-code.d.ts +1 -1
  3. package/dist/init/hook-packs/manifest-claude-code.d.ts.map +1 -1
  4. package/dist/init/hook-packs/manifest-claude-code.js +59 -6
  5. package/dist/init/hook-packs/manifest-claude-code.js.map +1 -1
  6. package/dist/init/hook-packs/types.js +1 -1
  7. package/dist/init/hook-packs/types.js.map +1 -1
  8. package/dist/shell/commands/agents.d.ts +49 -0
  9. package/dist/shell/commands/agents.d.ts.map +1 -0
  10. package/dist/shell/commands/agents.js +577 -0
  11. package/dist/shell/commands/agents.js.map +1 -0
  12. package/dist/shell/commands/claim.d.ts.map +1 -1
  13. package/dist/shell/commands/claim.js +3 -4
  14. package/dist/shell/commands/claim.js.map +1 -1
  15. package/dist/shell/commands/status.d.ts +12 -0
  16. package/dist/shell/commands/status.d.ts.map +1 -1
  17. package/dist/shell/commands/status.js +236 -21
  18. package/dist/shell/commands/status.js.map +1 -1
  19. package/dist/shell/commands/worktree.d.ts +9 -0
  20. package/dist/shell/commands/worktree.d.ts.map +1 -1
  21. package/dist/shell/commands/worktree.js +302 -0
  22. package/dist/shell/commands/worktree.js.map +1 -1
  23. package/dist/shell/index.d.ts +4 -2
  24. package/dist/shell/index.d.ts.map +1 -1
  25. package/dist/shell/index.js +12 -1
  26. package/dist/shell/index.js.map +1 -1
  27. package/dist/shell/register.d.ts.map +1 -1
  28. package/dist/shell/register.js +150 -0
  29. package/dist/shell/register.js.map +1 -1
  30. package/dist/shell/render/status.d.ts +7 -1
  31. package/dist/shell/render/status.d.ts.map +1 -1
  32. package/dist/shell/render/status.js +72 -0
  33. package/dist/shell/render/status.js.map +1 -1
  34. package/dist/store/agents-store.d.ts.map +1 -1
  35. package/dist/store/agents-store.js +9 -0
  36. package/dist/store/agents-store.js.map +1 -1
  37. package/dist/store/apply-patch.d.ts.map +1 -1
  38. package/dist/store/apply-patch.js +15 -0
  39. package/dist/store/apply-patch.js.map +1 -1
  40. package/dist/store/doctor-snapshot.d.ts.map +1 -1
  41. package/dist/store/doctor-snapshot.js +143 -3
  42. package/dist/store/doctor-snapshot.js.map +1 -1
  43. package/dist/store/git-sparse-checkout.d.ts +25 -0
  44. package/dist/store/git-sparse-checkout.d.ts.map +1 -0
  45. package/dist/store/git-sparse-checkout.js +101 -0
  46. package/dist/store/git-sparse-checkout.js.map +1 -0
  47. package/dist/store/index.d.ts +2 -0
  48. package/dist/store/index.d.ts.map +1 -1
  49. package/dist/store/index.js +10 -1
  50. package/dist/store/index.js.map +1 -1
  51. package/dist/store/leases-store.d.ts +89 -0
  52. package/dist/store/leases-store.d.ts.map +1 -0
  53. package/dist/store/leases-store.js +369 -0
  54. package/dist/store/leases-store.js.map +1 -0
  55. package/dist/store/lifecycle-transaction.d.ts.map +1 -1
  56. package/dist/store/lifecycle-transaction.js +34 -1
  57. package/dist/store/lifecycle-transaction.js.map +1 -1
  58. package/dist/store/rules.d.ts +21 -1
  59. package/dist/store/rules.d.ts.map +1 -1
  60. package/dist/store/rules.js +22 -0
  61. package/dist/store/rules.js.map +1 -1
  62. package/dist/store/types.d.ts +25 -1
  63. package/dist/store/types.d.ts.map +1 -1
  64. package/dist/store/worktrees-migration.d.ts +141 -0
  65. package/dist/store/worktrees-migration.d.ts.map +1 -0
  66. package/dist/store/worktrees-migration.js +356 -0
  67. package/dist/store/worktrees-migration.js.map +1 -0
  68. package/dist/store/worktrees-writer.d.ts.map +1 -1
  69. package/dist/store/worktrees-writer.js +37 -1
  70. package/dist/store/worktrees-writer.js.map +1 -1
  71. package/package.json +2 -2
  72. package/templates/hook-packs/claude-code/CLAUDE.md +5 -5
  73. package/templates/hook-packs/claude-code/agent-heartbeat.sh +131 -0
  74. package/templates/hook-packs/claude-code/agent-register.sh +62 -0
  75. package/templates/hook-packs/claude-code/agent-stop.sh +51 -0
  76. package/templates/hook-packs/claude-code/audit.sh +1 -1
  77. package/templates/hook-packs/claude-code/block-dangerous.sh +1 -1
  78. package/templates/hook-packs/claude-code/classify_command.py +454 -12
  79. package/templates/hook-packs/claude-code/dispatch/post_tool_use.sh +1 -1
  80. package/templates/hook-packs/claude-code/dispatch/pre_tool_use.sh +11 -2
  81. package/templates/hook-packs/claude-code/dispatch/session_start.sh +6 -2
  82. package/templates/hook-packs/claude-code/dispatch/stop.sh +7 -2
  83. package/templates/hook-packs/claude-code/guard-strikes.sh +1 -1
  84. package/templates/hook-packs/claude-code/lib/parse-input.sh +1 -1
  85. package/templates/hook-packs/claude-code/lib/run-handlers.sh +1 -1
  86. package/templates/hook-packs/claude-code/reset-danger-latch.sh +1 -1
  87. package/templates/hook-packs/claude-code/reset-strikes.sh +1 -1
  88. package/templates/hook-packs/claude-code/runtime-paths.sh +1 -1
  89. package/templates/hook-packs/claude-code/scope-guard.sh +1 -1
  90. package/templates/hook-packs/claude-code/session-caws-status.sh +7 -1
  91. package/templates/hook-packs/claude-code/session-log.sh +1 -1
  92. package/templates/hook-packs/claude-code/worktree-guard.sh +130 -4
  93. package/templates/hook-packs/claude-code/worktree-write-guard.sh +133 -18
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ // Sparse-checkout helper for CAWS-created worktrees
3
+ // (WORKTREE-SPEC-AUTHORITY-CONTROL-PLANE-001 A1).
4
+ //
5
+ // CAWS state is control-plane. The .caws/specs/ directory exists exactly
6
+ // once for the project, owned by the main checkout. When `caws worktree
7
+ // create` adds a linked worktree, git's default full checkout would
8
+ // materialize .caws/specs/<id>.yaml into the worktree filesystem,
9
+ // producing the v10.2 split-brain authority class: an editable spec
10
+ // copy inside the worktree, divergent from control-plane bytes,
11
+ // silently consulted by anything that walks cwd upward.
12
+ //
13
+ // This helper configures non-cone sparse-checkout on a freshly-added
14
+ // worktree so the .caws/specs/ tree is excluded from checkout. The
15
+ // rest of the worktree is a normal full checkout — the historic
16
+ // objection to sparse-checkout (broken cross-module imports caused by
17
+ // nearly-empty worktrees) is preserved by including everything OTHER
18
+ // than the authority files.
19
+ //
20
+ // Sparse-checkout vs the worktree-guard.sh hook policy: the hook
21
+ // (`.claude/hooks/worktree-guard.sh:52-56`) blocks agent-issued
22
+ // `git sparse-checkout` commands because sparse-checkout can be
23
+ // misused to hide source files and break work. This helper's use is
24
+ // different: it excludes ONLY the .caws/specs/ authority files, never
25
+ // source code, and runs from the CLI writer (via child_process.spawn)
26
+ // which does not go through the Bash tool hook surface. The hook's
27
+ // purpose is preserved.
28
+ //
29
+ // Pattern: `/*` includes everything; `!/.caws/specs/` excludes the
30
+ // authority directory. Non-cone mode is required because cone mode
31
+ // would force enumeration of all top-level directories. Non-cone
32
+ // sparse-checkout requires git 2.27+, which is documented in the
33
+ // spec's non_functional.reliability clause.
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.configureWorktreeSparseCheckout = configureWorktreeSparseCheckout;
36
+ const child_process_1 = require("child_process");
37
+ /**
38
+ * Configure non-cone sparse-checkout on `wtPath` so that `.caws/specs/`
39
+ * is excluded from checkout, then run `git checkout` to materialize the
40
+ * remaining tree.
41
+ *
42
+ * Returns Result-shape `{ ok: true }` on success or `{ ok: false,
43
+ * reason }` on the first failing git invocation. The caller is
44
+ * responsible for compensating side effects (typically by running
45
+ * `git worktree remove --force <wtPath>` on the partially-created
46
+ * worktree).
47
+ *
48
+ * IMPORTANT: this function does NOT call `git worktree add`. The caller
49
+ * must have already added the worktree with `--no-checkout` so that no
50
+ * files have been materialized yet. Calling this on a worktree that
51
+ * was added with a normal full checkout would not retroactively remove
52
+ * already-checked-out `.caws/specs/` files.
53
+ */
54
+ function configureWorktreeSparseCheckout(wtPath) {
55
+ // 1) Initialize sparse-checkout in non-cone mode.
56
+ const initResult = runGit(wtPath, ['sparse-checkout', 'init', '--no-cone']);
57
+ if (!initResult.ok)
58
+ return { ok: false, reason: initResult.reason, step: 'init' };
59
+ // 2) Set the pattern: include everything, exclude .caws/specs/.
60
+ // Non-cone mode interprets these as gitignore-style patterns
61
+ // relative to the worktree root. The leading slash in '/.caws/specs/'
62
+ // anchors the exclusion to the worktree root (not subdirectories
63
+ // named .caws/specs/ further down — there are none in this
64
+ // project, but the anchor is correct discipline).
65
+ const setResult = runGit(wtPath, [
66
+ 'sparse-checkout',
67
+ 'set',
68
+ '--no-cone',
69
+ '/*',
70
+ '!/.caws/specs/',
71
+ ]);
72
+ if (!setResult.ok)
73
+ return { ok: false, reason: setResult.reason, step: 'set' };
74
+ // 3) Materialize the included files. `git worktree add --no-checkout`
75
+ // leaves the worktree empty; this populates everything sparse-
76
+ // checkout admits.
77
+ const checkoutResult = runGit(wtPath, ['checkout']);
78
+ if (!checkoutResult.ok)
79
+ return { ok: false, reason: checkoutResult.reason, step: 'checkout' };
80
+ return { ok: true };
81
+ }
82
+ function runGit(cwd, args) {
83
+ try {
84
+ const stdout = (0, child_process_1.execFileSync)('git', [...args], {
85
+ cwd,
86
+ encoding: 'utf8',
87
+ stdio: ['ignore', 'pipe', 'pipe'],
88
+ });
89
+ return { ok: true, stdout: stdout.toString() };
90
+ }
91
+ catch (e) {
92
+ const cause = e;
93
+ const stderr = cause.stderr instanceof Buffer
94
+ ? cause.stderr.toString()
95
+ : typeof cause.stderr === 'string'
96
+ ? cause.stderr
97
+ : (cause.message ?? 'unknown git error');
98
+ return { ok: false, reason: stderr.trim() };
99
+ }
100
+ }
101
+ //# sourceMappingURL=git-sparse-checkout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-sparse-checkout.js","sourceRoot":"","sources":["../../src/store/git-sparse-checkout.ts"],"names":[],"mappings":";AAAA,oDAAoD;AACpD,kDAAkD;AAClD,EAAE;AACF,yEAAyE;AACzE,wEAAwE;AACxE,oEAAoE;AACpE,kEAAkE;AAClE,oEAAoE;AACpE,gEAAgE;AAChE,wDAAwD;AACxD,EAAE;AACF,qEAAqE;AACrE,mEAAmE;AACnE,gEAAgE;AAChE,sEAAsE;AACtE,qEAAqE;AACrE,4BAA4B;AAC5B,EAAE;AACF,iEAAiE;AACjE,gEAAgE;AAChE,gEAAgE;AAChE,oEAAoE;AACpE,sEAAsE;AACtE,sEAAsE;AACtE,mEAAmE;AACnE,wBAAwB;AACxB,EAAE;AACF,mEAAmE;AACnE,mEAAmE;AACnE,iEAAiE;AACjE,iEAAiE;AACjE,4CAA4C;;AAqB5C,0EA8BC;AAjDD,iDAA6C;AAE7C;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,+BAA+B,CAC7C,MAAc;IAEd,kDAAkD;IAClD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,iBAAiB,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAC5E,IAAI,CAAC,UAAU,CAAC,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAElF,gEAAgE;IAChE,gEAAgE;IAChE,yEAAyE;IACzE,oEAAoE;IACpE,8DAA8D;IAC9D,qDAAqD;IACrD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE;QAC/B,iBAAiB;QACjB,KAAK;QACL,WAAW;QACX,IAAI;QACJ,gBAAgB;KACjB,CAAC,CAAC;IACH,IAAI,CAAC,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAE/E,sEAAsE;IACtE,kEAAkE;IAClE,sBAAsB;IACtB,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IACpD,IAAI,CAAC,cAAc,CAAC,EAAE;QACpB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAExE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,MAAM,CAAC,GAAW,EAAE,IAAuB;IAClD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,4BAAY,EAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE;YAC5C,GAAG;YACH,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QACH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IACjD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,CAAmD,CAAC;QAClE,MAAM,MAAM,GACV,KAAK,CAAC,MAAM,YAAY,MAAM;YAC5B,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE;YACzB,CAAC,CAAC,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;gBAChC,CAAC,CAAC,KAAK,CAAC,MAAM;gBACd,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,mBAAmB,CAAC,CAAC;QAC/C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;IAC9C,CAAC;AACH,CAAC"}
@@ -12,6 +12,8 @@ export { loadWorktrees } from './worktrees-store';
12
12
  export { loadAgents } from './agents-store';
13
13
  export { appendEvent, loadEvents } from './events-store';
14
14
  export { applyRegistryPatch } from './apply-patch';
15
+ export { safeLeaseFilename, loadLeases, applyLeasePatch, applyLeasePatches, pruneLeasesByStatus, } from './leases-store';
16
+ export type { LoadLeasesResult, PruneOptions, PruneResult, } from './leases-store';
15
17
  export { loadWaivers, writeWaiver, markRevoked } from './waivers-store';
16
18
  export type { WaiversLoadResult } from './waivers-store';
17
19
  export { initProject, DEFAULT_POLICY_YAML } from './init-store';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC3D,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,aAAa,GACd,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE/E,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE5D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACxE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAChE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEnE,OAAO,EACL,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,GACf,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC3D,YAAY,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,aAAa,GACd,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE/E,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE5D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAKnD,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,WAAW,GACZ,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACxE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAChE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEnE,OAAO,EACL,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,GACf,MAAM,mBAAmB,CAAC"}
@@ -5,7 +5,7 @@
5
5
  // It is consumed programmatically; no public CLI commands are registered
6
6
  // here. CLI command surface lands in Slice 5c.
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.composeStoreSnapshot = exports.composeDoctorSnapshot = exports.DEFAULT_POLICY_YAML = exports.initProject = exports.markRevoked = exports.writeWaiver = exports.loadWaivers = exports.applyRegistryPatch = exports.loadEvents = exports.appendEvent = exports.loadAgents = exports.loadWorktrees = exports.loadPolicy = exports.loadSpecs = exports.readYamlSource = exports.readYamlFile = exports.readJsonFile = exports.writeFileAtomic = exports.fsyncDir = exports.storeDiagnostic = exports.resolveRepoRoot = exports.defaultGitRunner = exports.STORE_RULE_PREFIXES = exports.STORE_RULES = void 0;
8
+ exports.composeStoreSnapshot = exports.composeDoctorSnapshot = exports.DEFAULT_POLICY_YAML = exports.initProject = exports.markRevoked = exports.writeWaiver = exports.loadWaivers = exports.pruneLeasesByStatus = exports.applyLeasePatches = exports.applyLeasePatch = exports.loadLeases = exports.safeLeaseFilename = exports.applyRegistryPatch = exports.loadEvents = exports.appendEvent = exports.loadAgents = exports.loadWorktrees = exports.loadPolicy = exports.loadSpecs = exports.readYamlSource = exports.readYamlFile = exports.readJsonFile = exports.writeFileAtomic = exports.fsyncDir = exports.storeDiagnostic = exports.resolveRepoRoot = exports.defaultGitRunner = exports.STORE_RULE_PREFIXES = exports.STORE_RULES = void 0;
9
9
  var rules_1 = require("./rules");
10
10
  Object.defineProperty(exports, "STORE_RULES", { enumerable: true, get: function () { return rules_1.STORE_RULES; } });
11
11
  Object.defineProperty(exports, "STORE_RULE_PREFIXES", { enumerable: true, get: function () { return rules_1.STORE_RULE_PREFIXES; } });
@@ -34,6 +34,15 @@ Object.defineProperty(exports, "appendEvent", { enumerable: true, get: function
34
34
  Object.defineProperty(exports, "loadEvents", { enumerable: true, get: function () { return events_store_1.loadEvents; } });
35
35
  var apply_patch_1 = require("./apply-patch");
36
36
  Object.defineProperty(exports, "applyRegistryPatch", { enumerable: true, get: function () { return apply_patch_1.applyRegistryPatch; } });
37
+ // ─── leases (MULTI-AGENT-ACTIVITY-REGISTRY-001) ──────────────────────────
38
+ // Lease I/O surface — separate from applyRegistryPatch. LeasePatch is
39
+ // applied ONLY through applyLeasePatch / applyLeasePatches.
40
+ var leases_store_1 = require("./leases-store");
41
+ Object.defineProperty(exports, "safeLeaseFilename", { enumerable: true, get: function () { return leases_store_1.safeLeaseFilename; } });
42
+ Object.defineProperty(exports, "loadLeases", { enumerable: true, get: function () { return leases_store_1.loadLeases; } });
43
+ Object.defineProperty(exports, "applyLeasePatch", { enumerable: true, get: function () { return leases_store_1.applyLeasePatch; } });
44
+ Object.defineProperty(exports, "applyLeasePatches", { enumerable: true, get: function () { return leases_store_1.applyLeasePatches; } });
45
+ Object.defineProperty(exports, "pruneLeasesByStatus", { enumerable: true, get: function () { return leases_store_1.pruneLeasesByStatus; } });
37
46
  var waivers_store_1 = require("./waivers-store");
38
47
  Object.defineProperty(exports, "loadWaivers", { enumerable: true, get: function () { return waivers_store_1.loadWaivers; } });
39
48
  Object.defineProperty(exports, "writeWaiver", { enumerable: true, get: function () { return waivers_store_1.writeWaiver; } });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":";AAAA,gDAAgD;AAChD,EAAE;AACF,wEAAwE;AACxE,yEAAyE;AACzE,+CAA+C;;;AAE/C,iCAA2D;AAAlD,oGAAA,WAAW,OAAA;AAAE,4GAAA,mBAAmB,OAAA;AAUzC,yCAIqB;AAHnB,6GAAA,gBAAgB,OAAA;AAChB,4GAAA,eAAe,OAAA;AACf,4GAAA,eAAe,OAAA;AAIjB,+CAA2D;AAAlD,wGAAA,QAAQ,OAAA;AAAE,+GAAA,eAAe,OAAA;AAClC,2CAA4C;AAAnC,0GAAA,YAAY,OAAA;AACrB,2CAA4D;AAAnD,0GAAA,YAAY,OAAA;AAAE,4GAAA,cAAc,OAAA;AAErC,6CAA0C;AAAjC,wGAAA,SAAS,OAAA;AAClB,+CAA4C;AAAnC,0GAAA,UAAU,OAAA;AACnB,qDAAkD;AAAzC,gHAAA,aAAa,OAAA;AACtB,+CAA4C;AAAnC,0GAAA,UAAU,OAAA;AACnB,+CAAyD;AAAhD,2GAAA,WAAW,OAAA;AAAE,0GAAA,UAAU,OAAA;AAEhC,6CAAmD;AAA1C,iHAAA,kBAAkB,OAAA;AAE3B,iDAAwE;AAA/D,4GAAA,WAAW,OAAA;AAAE,4GAAA,WAAW,OAAA;AAAE,4GAAA,WAAW,OAAA;AAG9C,2CAAgE;AAAvD,yGAAA,WAAW,OAAA;AAAE,iHAAA,mBAAmB,OAAA;AAGzC,qDAG2B;AAFzB,wHAAA,qBAAqB,OAAA;AACrB,uHAAA,oBAAoB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":";AAAA,gDAAgD;AAChD,EAAE;AACF,wEAAwE;AACxE,yEAAyE;AACzE,+CAA+C;;;AAE/C,iCAA2D;AAAlD,oGAAA,WAAW,OAAA;AAAE,4GAAA,mBAAmB,OAAA;AAUzC,yCAIqB;AAHnB,6GAAA,gBAAgB,OAAA;AAChB,4GAAA,eAAe,OAAA;AACf,4GAAA,eAAe,OAAA;AAIjB,+CAA2D;AAAlD,wGAAA,QAAQ,OAAA;AAAE,+GAAA,eAAe,OAAA;AAClC,2CAA4C;AAAnC,0GAAA,YAAY,OAAA;AACrB,2CAA4D;AAAnD,0GAAA,YAAY,OAAA;AAAE,4GAAA,cAAc,OAAA;AAErC,6CAA0C;AAAjC,wGAAA,SAAS,OAAA;AAClB,+CAA4C;AAAnC,0GAAA,UAAU,OAAA;AACnB,qDAAkD;AAAzC,gHAAA,aAAa,OAAA;AACtB,+CAA4C;AAAnC,0GAAA,UAAU,OAAA;AACnB,+CAAyD;AAAhD,2GAAA,WAAW,OAAA;AAAE,0GAAA,UAAU,OAAA;AAEhC,6CAAmD;AAA1C,iHAAA,kBAAkB,OAAA;AAE3B,4EAA4E;AAC5E,sEAAsE;AACtE,4DAA4D;AAC5D,+CAMwB;AALtB,iHAAA,iBAAiB,OAAA;AACjB,0GAAA,UAAU,OAAA;AACV,+GAAA,eAAe,OAAA;AACf,iHAAA,iBAAiB,OAAA;AACjB,mHAAA,mBAAmB,OAAA;AAQrB,iDAAwE;AAA/D,4GAAA,WAAW,OAAA;AAAE,4GAAA,WAAW,OAAA;AAAE,4GAAA,WAAW,OAAA;AAG9C,2CAAgE;AAAvD,yGAAA,WAAW,OAAA;AAAE,iHAAA,mBAAmB,OAAA;AAGzC,qDAG2B;AAFzB,wHAAA,qBAAqB,OAAA;AACrB,uHAAA,oBAAoB,OAAA"}
@@ -0,0 +1,89 @@
1
+ import { type Diagnostic, type LeasePatch, type LeaseRegistry, type Result } from '@paths.design/caws-kernel';
2
+ export interface LoadLeasesResult {
3
+ readonly leases: LeaseRegistry;
4
+ readonly diagnostics: ReadonlyArray<Diagnostic>;
5
+ }
6
+ /**
7
+ * Validate a session_id for filesystem safety, returning the filename
8
+ * to use (with .json suffix) on success.
9
+ */
10
+ export declare function safeLeaseFilename(sessionId: unknown): Result<string>;
11
+ /**
12
+ * Load all lease files under .caws/leases/.
13
+ *
14
+ * LENIENT per file: a malformed individual lease produces a diagnostic
15
+ * in the returned diagnostics array and is excluded from the registry;
16
+ * the call returns ok with the parseable subset.
17
+ *
18
+ * STRICT on directory: an unreadable .caws/leases/ directory returns
19
+ * err with LEASE_DIR_UNREADABLE. A missing directory returns
20
+ * ok({ leases: {}, diagnostics: [] }) — leases are operational cache;
21
+ * absence is normal.
22
+ *
23
+ * Per-file failure classes (each emits one diagnostic, excludes the file):
24
+ * - filename does not match the lease pattern (skipped silently —
25
+ * these are not lease files, just other content in the dir)
26
+ * - JSON parse failure → LEASE_FILE_MALFORMED
27
+ * - JSON parses but is not an object → LEASE_FILE_MALFORMED
28
+ * - session_id mismatch between filename and content → LEASE_FILE_MALFORMED
29
+ */
30
+ export declare function loadLeases(cawsDir: string): Result<LoadLeasesResult>;
31
+ /**
32
+ * Apply a single LeasePatch via atomic per-file write.
33
+ *
34
+ * Creates the leases directory if missing. No lock acquired (per spec
35
+ * invariant 11). No event emitted (per spec invariant 10 and doctrine
36
+ * §6 invariant 10).
37
+ *
38
+ * Patch semantics:
39
+ * - write_lease: serialize patch.lease as JSON, atomic-write to
40
+ * <cawsDir>/leases/<safe-session-id>.json.
41
+ * - mark_stopped: read existing lease file; if absent, return ok with
42
+ * a warning diagnostic (NOT a fabricated record); if present,
43
+ * update status='stopped', stopped_at=patch.transitioned_at,
44
+ * last_seen_reason='session_stop'; atomic-write back.
45
+ * - delete_lease: fs.unlinkSync the lease file; idempotent on absence.
46
+ */
47
+ export declare function applyLeasePatch(cawsDir: string, patch: LeasePatch): Result<{
48
+ readonly wrote: boolean;
49
+ readonly diagnostics: ReadonlyArray<Diagnostic>;
50
+ }>;
51
+ /**
52
+ * Apply a batch of lease patches. Per-patch failures do NOT abort the
53
+ * batch — each patch's diagnostics are aggregated into the return.
54
+ *
55
+ * Use for operator commands like prune that emit multiple delete_lease
56
+ * patches. Single-session register/heartbeat/stop go through
57
+ * applyLeasePatch directly.
58
+ */
59
+ export declare function applyLeasePatches(cawsDir: string, patches: ReadonlyArray<LeasePatch>): Result<{
60
+ readonly applied: number;
61
+ readonly diagnostics: ReadonlyArray<Diagnostic>;
62
+ }>;
63
+ /**
64
+ * Operator-invoked prune: delete lease files matching a status + age
65
+ * threshold.
66
+ *
67
+ * Selection: status === target AND (now - reference) > retentionMs, where
68
+ * reference is `stopped_at` for status='stopped' and `last_active` for
69
+ * status='active' (with TTL-based read-side 'stale' bucketing).
70
+ *
71
+ * Default `dryRun: true` (caller must explicitly pass false to delete).
72
+ * Returns count of files that would be / were deleted plus any
73
+ * diagnostics from the delete operations.
74
+ */
75
+ export interface PruneOptions {
76
+ readonly status: 'stopped' | 'stale';
77
+ /** Active records whose age exceeds this are bucketed as stale for the prune decision. */
78
+ readonly staleTtlMs?: number;
79
+ readonly retentionMs: number;
80
+ readonly now: Date;
81
+ readonly dryRun?: boolean;
82
+ }
83
+ export interface PruneResult {
84
+ readonly candidates: ReadonlyArray<string>;
85
+ readonly deleted: ReadonlyArray<string>;
86
+ readonly diagnostics: ReadonlyArray<Diagnostic>;
87
+ }
88
+ export declare function pruneLeasesByStatus(cawsDir: string, opts: PruneOptions): Result<PruneResult>;
89
+ //# sourceMappingURL=leases-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leases-store.d.ts","sourceRoot":"","sources":["../../src/store/leases-store.ts"],"names":[],"mappings":"AAoCA,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,MAAM,EACZ,MAAM,2BAA2B,CAAC;AA+BnC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;CACjD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAuCpE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,gBAAgB,CAAC,CA6FpE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,UAAU,GAChB,MAAM,CAAC;IAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAAA;CAAE,CAAC,CAmGtF;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,CAAC,UAAU,CAAC,GACjC,MAAM,CAAC;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAAA;CAAE,CAAC,CAevF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IACrC,0FAA0F;IAC1F,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;IACnB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;CACjD;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,YAAY,GACjB,MAAM,CAAC,WAAW,CAAC,CAyDrB"}
@@ -0,0 +1,369 @@
1
+ "use strict";
2
+ // Agent-lease store — the SOLE I/O surface for .caws/leases/.
3
+ //
4
+ // MULTI-AGENT-ACTIVITY-REGISTRY-001 acceptance A5–A8, A12.
5
+ //
6
+ // Architectural separation (load-bearing — see spec invariant 2):
7
+ //
8
+ // - This module owns ALL lease I/O. apply-patch.ts is NOT extended to
9
+ // handle LeasePatch. Lease writes never flow through applyRegistryPatch.
10
+ // Routing lease writes through the governance apply path would re-merge
11
+ // the operational-cache / governance-state boundary this slice exists
12
+ // to preserve.
13
+ //
14
+ // - Lease writes are NEVER inside lifecycle-transaction. They never block
15
+ // work, never corrupt governance state, and a write failure is warn-
16
+ // and-continue (per doctrine §6 invariant 11).
17
+ //
18
+ // - Lease writes NEVER append events.jsonl (per doctrine §6 invariant 10).
19
+ // Events are durable governance facts; leases are operational cache.
20
+ //
21
+ // - loadLeases is LENIENT per file. A single malformed lease file
22
+ // produces a diagnostic and is excluded from the returned registry;
23
+ // the call still returns ok. Only an unreadable lease directory
24
+ // causes the call to fail.
25
+ //
26
+ // - safeLeaseFilename enforces a strict character allowlist
27
+ // (^[A-Za-z0-9._:-]+$) at the I/O boundary. The kernel constructs
28
+ // records; the store decides what is filesystem-safe. The literal
29
+ // 'unknown' is REFUSED (would collide across all anonymous sessions).
30
+ //
31
+ // - mark_stopped against a missing lease is a warn no-op, NOT a
32
+ // fabricated record. Stopping a session we never registered is
33
+ // evidence of a lifecycle mismatch, not a write opportunity.
34
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
35
+ if (k2 === undefined) k2 = k;
36
+ var desc = Object.getOwnPropertyDescriptor(m, k);
37
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
38
+ desc = { enumerable: true, get: function() { return m[k]; } };
39
+ }
40
+ Object.defineProperty(o, k2, desc);
41
+ }) : (function(o, m, k, k2) {
42
+ if (k2 === undefined) k2 = k;
43
+ o[k2] = m[k];
44
+ }));
45
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
46
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
47
+ }) : function(o, v) {
48
+ o["default"] = v;
49
+ });
50
+ var __importStar = (this && this.__importStar) || (function () {
51
+ var ownKeys = function(o) {
52
+ ownKeys = Object.getOwnPropertyNames || function (o) {
53
+ var ar = [];
54
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
55
+ return ar;
56
+ };
57
+ return ownKeys(o);
58
+ };
59
+ return function (mod) {
60
+ if (mod && mod.__esModule) return mod;
61
+ var result = {};
62
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
63
+ __setModuleDefault(result, mod);
64
+ return result;
65
+ };
66
+ })();
67
+ Object.defineProperty(exports, "__esModule", { value: true });
68
+ exports.safeLeaseFilename = safeLeaseFilename;
69
+ exports.loadLeases = loadLeases;
70
+ exports.applyLeasePatch = applyLeasePatch;
71
+ exports.applyLeasePatches = applyLeasePatches;
72
+ exports.pruneLeasesByStatus = pruneLeasesByStatus;
73
+ const fs = __importStar(require("node:fs"));
74
+ const path = __importStar(require("node:path"));
75
+ const caws_kernel_1 = require("@paths.design/caws-kernel");
76
+ const atomic_write_1 = require("./atomic-write");
77
+ const repo_root_1 = require("./repo-root");
78
+ const rules_1 = require("./rules");
79
+ const LEASES_DIRNAME = 'leases';
80
+ /**
81
+ * Strict-allowlist regex for lease filenames.
82
+ *
83
+ * Allowed characters: ASCII letters, digits, dot, underscore, colon,
84
+ * hyphen. This intentionally rejects:
85
+ * - empty string
86
+ * - 'unknown' (parse-input.sh's fallback when hook payload has no
87
+ * session_id; writing 'unknown.json' would collide across every
88
+ * anonymous session)
89
+ * - whitespace
90
+ * - path separators ('/', '\')
91
+ * - parent-directory references ('..')
92
+ * - shell-meta characters
93
+ *
94
+ * UUIDs (8-4-4-4-12 with hyphens) and `caws-<hex>` (resolveSession's mint
95
+ * format) both pass. The regex is the single source of truth; both the
96
+ * kernel and shell layers MUST route filename derivation through
97
+ * safeLeaseFilename, never direct path joins on raw session_id.
98
+ */
99
+ const LEASE_FILENAME_RE = /^[A-Za-z0-9._:-]+$/;
100
+ /**
101
+ * Validate a session_id for filesystem safety, returning the filename
102
+ * to use (with .json suffix) on success.
103
+ */
104
+ function safeLeaseFilename(sessionId) {
105
+ if (typeof sessionId !== 'string') {
106
+ return (0, caws_kernel_1.err)((0, repo_root_1.storeDiagnostic)(rules_1.STORE_RULES.LEASE_SESSION_ID_INVALID, 'Lease session_id must be a string.', { data: { actual_type: typeof sessionId } }));
107
+ }
108
+ if (sessionId.length === 0) {
109
+ return (0, caws_kernel_1.err)((0, repo_root_1.storeDiagnostic)(rules_1.STORE_RULES.LEASE_SESSION_ID_INVALID, 'Lease session_id must be a non-empty string.'));
110
+ }
111
+ if (sessionId === 'unknown') {
112
+ return (0, caws_kernel_1.err)((0, repo_root_1.storeDiagnostic)(rules_1.STORE_RULES.LEASE_SESSION_ID_INVALID, "Lease session_id 'unknown' is refused — it would collide across anonymous sessions. " +
113
+ 'Hook scripts MUST guard [ -z "$HOOK_SESSION_ID" ] || [ "$HOOK_SESSION_ID" = "unknown" ] before invoking the CLI.', { data: { session_id: sessionId } }));
114
+ }
115
+ if (!LEASE_FILENAME_RE.test(sessionId)) {
116
+ return (0, caws_kernel_1.err)((0, repo_root_1.storeDiagnostic)(rules_1.STORE_RULES.LEASE_SESSION_ID_UNSAFE, `Lease session_id "${sessionId}" contains characters outside the strict allowlist ` +
117
+ '^[A-Za-z0-9._:-]+$. Path separators, whitespace, and shell metacharacters are forbidden.', { data: { session_id: sessionId } }));
118
+ }
119
+ return (0, caws_kernel_1.ok)(`${sessionId}.json`);
120
+ }
121
+ /**
122
+ * Load all lease files under .caws/leases/.
123
+ *
124
+ * LENIENT per file: a malformed individual lease produces a diagnostic
125
+ * in the returned diagnostics array and is excluded from the registry;
126
+ * the call returns ok with the parseable subset.
127
+ *
128
+ * STRICT on directory: an unreadable .caws/leases/ directory returns
129
+ * err with LEASE_DIR_UNREADABLE. A missing directory returns
130
+ * ok({ leases: {}, diagnostics: [] }) — leases are operational cache;
131
+ * absence is normal.
132
+ *
133
+ * Per-file failure classes (each emits one diagnostic, excludes the file):
134
+ * - filename does not match the lease pattern (skipped silently —
135
+ * these are not lease files, just other content in the dir)
136
+ * - JSON parse failure → LEASE_FILE_MALFORMED
137
+ * - JSON parses but is not an object → LEASE_FILE_MALFORMED
138
+ * - session_id mismatch between filename and content → LEASE_FILE_MALFORMED
139
+ */
140
+ function loadLeases(cawsDir) {
141
+ const leasesDir = path.join(cawsDir, LEASES_DIRNAME);
142
+ if (!fs.existsSync(leasesDir)) {
143
+ return (0, caws_kernel_1.ok)({ leases: {}, diagnostics: [] });
144
+ }
145
+ let entries;
146
+ try {
147
+ entries = fs.readdirSync(leasesDir);
148
+ }
149
+ catch (e) {
150
+ return (0, caws_kernel_1.err)((0, repo_root_1.storeDiagnostic)(rules_1.STORE_RULES.LEASE_DIR_UNREADABLE, `Lease directory unreadable: ${e.message}`, { subject: leasesDir }));
151
+ }
152
+ const leases = {};
153
+ const diagnostics = [];
154
+ for (const entry of entries) {
155
+ if (!entry.endsWith('.json'))
156
+ continue;
157
+ const sessionId = entry.slice(0, -'.json'.length);
158
+ if (!LEASE_FILENAME_RE.test(sessionId)) {
159
+ // Not a lease file by our naming convention; ignore silently
160
+ // rather than fabricate a malformed diagnostic for unrelated
161
+ // files an operator may have dropped here.
162
+ continue;
163
+ }
164
+ const filePath = path.join(leasesDir, entry);
165
+ let raw;
166
+ try {
167
+ raw = fs.readFileSync(filePath, 'utf8');
168
+ }
169
+ catch (e) {
170
+ diagnostics.push((0, repo_root_1.storeDiagnostic)(rules_1.STORE_RULES.LEASE_FILE_MALFORMED, `Lease file unreadable: ${e.message}`, { subject: filePath, data: { session_id: sessionId } }));
171
+ continue;
172
+ }
173
+ let parsed;
174
+ try {
175
+ parsed = JSON.parse(raw);
176
+ }
177
+ catch (e) {
178
+ diagnostics.push((0, repo_root_1.storeDiagnostic)(rules_1.STORE_RULES.LEASE_FILE_MALFORMED, `Lease file is not valid JSON: ${e.message}`, { subject: filePath, data: { session_id: sessionId } }));
179
+ continue;
180
+ }
181
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
182
+ diagnostics.push((0, repo_root_1.storeDiagnostic)(rules_1.STORE_RULES.LEASE_FILE_MALFORMED, 'Lease file root is not a JSON object.', { subject: filePath, data: { session_id: sessionId } }));
183
+ continue;
184
+ }
185
+ const obj = parsed;
186
+ if (typeof obj['session_id'] !== 'string' || obj['session_id'] !== sessionId) {
187
+ diagnostics.push((0, repo_root_1.storeDiagnostic)(rules_1.STORE_RULES.LEASE_FILE_MALFORMED, `Lease file session_id "${obj['session_id']}" does not match filename "${sessionId}".`, { subject: filePath, data: { filename_session_id: sessionId, payload_session_id: obj['session_id'] } }));
188
+ continue;
189
+ }
190
+ // Treat the parsed object as an AgentLease. Field-level shape
191
+ // validation is deferred to a future kernel-side validateAgentLease
192
+ // function; for now, the kernel's TypeScript shape is the structural
193
+ // contract, and ill-typed-but-parseable files load successfully.
194
+ leases[sessionId] = obj;
195
+ }
196
+ return (0, caws_kernel_1.ok)({ leases, diagnostics });
197
+ }
198
+ /**
199
+ * Apply a single LeasePatch via atomic per-file write.
200
+ *
201
+ * Creates the leases directory if missing. No lock acquired (per spec
202
+ * invariant 11). No event emitted (per spec invariant 10 and doctrine
203
+ * §6 invariant 10).
204
+ *
205
+ * Patch semantics:
206
+ * - write_lease: serialize patch.lease as JSON, atomic-write to
207
+ * <cawsDir>/leases/<safe-session-id>.json.
208
+ * - mark_stopped: read existing lease file; if absent, return ok with
209
+ * a warning diagnostic (NOT a fabricated record); if present,
210
+ * update status='stopped', stopped_at=patch.transitioned_at,
211
+ * last_seen_reason='session_stop'; atomic-write back.
212
+ * - delete_lease: fs.unlinkSync the lease file; idempotent on absence.
213
+ */
214
+ function applyLeasePatch(cawsDir, patch) {
215
+ const filenameRes = safeLeaseFilename(patch.session_id);
216
+ if (filenameRes.ok === false)
217
+ return filenameRes;
218
+ const filename = filenameRes.value;
219
+ const leasesDir = path.join(cawsDir, LEASES_DIRNAME);
220
+ const filePath = path.join(leasesDir, filename);
221
+ try {
222
+ fs.mkdirSync(leasesDir, { recursive: true });
223
+ }
224
+ catch (e) {
225
+ return (0, caws_kernel_1.err)((0, repo_root_1.storeDiagnostic)(rules_1.STORE_RULES.LEASE_WRITE_FAILED, `Failed to create lease directory: ${e.message}`, { subject: leasesDir }));
226
+ }
227
+ if (patch.kind === 'write_lease') {
228
+ const contents = JSON.stringify(patch.lease, null, 2) + '\n';
229
+ const w = (0, atomic_write_1.writeFileAtomic)(filePath, contents);
230
+ if (w.ok === false)
231
+ return (0, caws_kernel_1.err)(w.errors);
232
+ return (0, caws_kernel_1.ok)({ wrote: true, diagnostics: [] });
233
+ }
234
+ if (patch.kind === 'mark_stopped') {
235
+ if (!fs.existsSync(filePath)) {
236
+ // Stopping a session we never registered is a lifecycle mismatch,
237
+ // not a write opportunity. Surface as a warning diagnostic; do
238
+ // NOT fabricate a historical record.
239
+ const warn = (0, caws_kernel_1.diagnostic)({
240
+ rule: rules_1.STORE_RULES.LEASE_STOP_NO_PRIOR_LEASE,
241
+ authority: 'kernel/diagnostics',
242
+ severity: 'warning',
243
+ message: `mark_stopped: no existing lease for session "${patch.session_id}" — nothing to update.`,
244
+ subject: filePath,
245
+ data: { session_id: patch.session_id },
246
+ });
247
+ return (0, caws_kernel_1.ok)({ wrote: false, diagnostics: [warn] });
248
+ }
249
+ let raw;
250
+ try {
251
+ raw = fs.readFileSync(filePath, 'utf8');
252
+ }
253
+ catch (e) {
254
+ return (0, caws_kernel_1.err)((0, repo_root_1.storeDiagnostic)(rules_1.STORE_RULES.LEASE_WRITE_FAILED, `Failed to read existing lease for mark_stopped: ${e.message}`, { subject: filePath }));
255
+ }
256
+ let prior;
257
+ try {
258
+ prior = JSON.parse(raw);
259
+ }
260
+ catch (e) {
261
+ return (0, caws_kernel_1.err)((0, repo_root_1.storeDiagnostic)(rules_1.STORE_RULES.LEASE_FILE_MALFORMED, `Existing lease file is not valid JSON: ${e.message}`, { subject: filePath }));
262
+ }
263
+ const updated = {
264
+ ...prior,
265
+ status: 'stopped',
266
+ stopped_at: patch.transitioned_at,
267
+ last_seen_reason: 'session_stop',
268
+ };
269
+ const contents = JSON.stringify(updated, null, 2) + '\n';
270
+ const w = (0, atomic_write_1.writeFileAtomic)(filePath, contents);
271
+ if (w.ok === false)
272
+ return (0, caws_kernel_1.err)(w.errors);
273
+ return (0, caws_kernel_1.ok)({ wrote: true, diagnostics: [] });
274
+ }
275
+ // delete_lease
276
+ if (!fs.existsSync(filePath)) {
277
+ // Idempotent: deleting an absent lease is a no-op success.
278
+ return (0, caws_kernel_1.ok)({ wrote: false, diagnostics: [] });
279
+ }
280
+ try {
281
+ fs.unlinkSync(filePath);
282
+ }
283
+ catch (e) {
284
+ return (0, caws_kernel_1.err)((0, repo_root_1.storeDiagnostic)(rules_1.STORE_RULES.LEASE_WRITE_FAILED, `Failed to delete lease file: ${e.message}`, { subject: filePath }));
285
+ }
286
+ return (0, caws_kernel_1.ok)({ wrote: true, diagnostics: [] });
287
+ }
288
+ /**
289
+ * Apply a batch of lease patches. Per-patch failures do NOT abort the
290
+ * batch — each patch's diagnostics are aggregated into the return.
291
+ *
292
+ * Use for operator commands like prune that emit multiple delete_lease
293
+ * patches. Single-session register/heartbeat/stop go through
294
+ * applyLeasePatch directly.
295
+ */
296
+ function applyLeasePatches(cawsDir, patches) {
297
+ let applied = 0;
298
+ const diagnostics = [];
299
+ for (const patch of patches) {
300
+ const r = applyLeasePatch(cawsDir, patch);
301
+ if (r.ok === false) {
302
+ diagnostics.push(...r.errors);
303
+ continue;
304
+ }
305
+ if (r.value.wrote)
306
+ applied++;
307
+ diagnostics.push(...r.value.diagnostics);
308
+ }
309
+ return (0, caws_kernel_1.ok)({ applied, diagnostics });
310
+ }
311
+ function pruneLeasesByStatus(cawsDir, opts) {
312
+ const dryRun = opts.dryRun ?? true;
313
+ const staleTtlMs = opts.staleTtlMs ?? 30 * 60 * 1000; // 30m default
314
+ const loadRes = loadLeases(cawsDir);
315
+ if (loadRes.ok === false)
316
+ return (0, caws_kernel_1.err)(loadRes.errors);
317
+ const { leases, diagnostics: loadDiags } = loadRes.value;
318
+ const nowMs = opts.now.getTime();
319
+ const candidates = [];
320
+ // Object.values widens index-signature types to unknown[] under
321
+ // strict TS; coerce back to the kernel-declared element type so the
322
+ // loop body can read fields without per-line casts.
323
+ for (const lease of Object.values(leases)) {
324
+ if (opts.status === 'stopped') {
325
+ if (lease.status !== 'stopped')
326
+ continue;
327
+ const stoppedAtMs = lease.stopped_at ? Date.parse(lease.stopped_at) : NaN;
328
+ const reference = Number.isFinite(stoppedAtMs)
329
+ ? stoppedAtMs
330
+ : Date.parse(lease.last_active);
331
+ if (!Number.isFinite(reference))
332
+ continue;
333
+ if (nowMs - reference > opts.retentionMs)
334
+ candidates.push(lease.session_id);
335
+ }
336
+ else {
337
+ // status === 'stale'
338
+ if (lease.status !== 'active' && lease.status !== 'stopping')
339
+ continue;
340
+ const lastActiveMs = Date.parse(lease.last_active);
341
+ if (!Number.isFinite(lastActiveMs)) {
342
+ // Unparseable → treat as stale for prune purposes.
343
+ candidates.push(lease.session_id);
344
+ continue;
345
+ }
346
+ const age = nowMs - lastActiveMs;
347
+ // Must be stale (age > staleTtl) AND have been stale long enough
348
+ // (age > staleTtl + retention).
349
+ if (age > staleTtlMs && age - staleTtlMs > opts.retentionMs) {
350
+ candidates.push(lease.session_id);
351
+ }
352
+ }
353
+ }
354
+ const diagnostics = [...loadDiags];
355
+ const deleted = [];
356
+ if (!dryRun) {
357
+ for (const sessionId of candidates) {
358
+ const r = applyLeasePatch(cawsDir, { kind: 'delete_lease', session_id: sessionId });
359
+ if (r.ok === false) {
360
+ diagnostics.push(...r.errors);
361
+ continue;
362
+ }
363
+ deleted.push(sessionId);
364
+ diagnostics.push(...r.value.diagnostics);
365
+ }
366
+ }
367
+ return (0, caws_kernel_1.ok)({ candidates, deleted, diagnostics });
368
+ }
369
+ //# sourceMappingURL=leases-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leases-store.js","sourceRoot":"","sources":["../../src/store/leases-store.ts"],"names":[],"mappings":"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"}