@tacuchi/agent-workflow-cli 21.8.0 → 21.10.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 (106) hide show
  1. package/dist/adapters/git-cli.js +217 -0
  2. package/dist/adapters/git-cli.js.map +1 -1
  3. package/dist/application/check-branch-service.js +48 -20
  4. package/dist/application/check-branch-service.js.map +1 -1
  5. package/dist/application/dev-only-services.js +53 -4
  6. package/dist/application/dev-only-services.js.map +1 -1
  7. package/dist/application/flow/advance.js +10 -3
  8. package/dist/application/flow/advance.js.map +1 -1
  9. package/dist/application/flow/flow-service.js +7 -0
  10. package/dist/application/flow/flow-service.js.map +1 -1
  11. package/dist/application/flow/internal-actions.js +74 -3
  12. package/dist/application/flow/internal-actions.js.map +1 -1
  13. package/dist/application/flow/internal-drive.js +1 -0
  14. package/dist/application/flow/internal-drive.js.map +1 -1
  15. package/dist/application/flow/run-projection.js +10 -4
  16. package/dist/application/flow/run-projection.js.map +1 -1
  17. package/dist/application/flow/submit.js +164 -15
  18. package/dist/application/flow/submit.js.map +1 -1
  19. package/dist/application/history-table.js +37 -0
  20. package/dist/application/history-table.js.map +1 -1
  21. package/dist/application/hook-branch-check.js +17 -0
  22. package/dist/application/hook-branch-check.js.map +1 -1
  23. package/dist/application/local-proposal.js +37 -0
  24. package/dist/application/local-proposal.js.map +1 -1
  25. package/dist/application/resume-service.js +1 -0
  26. package/dist/application/resume-service.js.map +1 -1
  27. package/dist/application/retirement/apply.js +448 -0
  28. package/dist/application/retirement/apply.js.map +1 -0
  29. package/dist/application/retirement/attribution.js +395 -0
  30. package/dist/application/retirement/attribution.js.map +1 -0
  31. package/dist/application/retirement/graph.js +196 -0
  32. package/dist/application/retirement/graph.js.map +1 -0
  33. package/dist/application/retirement/history-events.js +158 -0
  34. package/dist/application/retirement/history-events.js.map +1 -0
  35. package/dist/application/retirement/journal.js +113 -0
  36. package/dist/application/retirement/journal.js.map +1 -0
  37. package/dist/application/retirement/prepare.js +233 -0
  38. package/dist/application/retirement/prepare.js.map +1 -0
  39. package/dist/application/retirement/preview.js +101 -0
  40. package/dist/application/retirement/preview.js.map +1 -0
  41. package/dist/application/retirement/resolve.js +356 -0
  42. package/dist/application/retirement/resolve.js.map +1 -0
  43. package/dist/application/session-close-service.js +108 -14
  44. package/dist/application/session-close-service.js.map +1 -1
  45. package/dist/application/session-create-service.js +103 -12
  46. package/dist/application/session-create-service.js.map +1 -1
  47. package/dist/application/session-custody-recorder.js +137 -0
  48. package/dist/application/session-custody-recorder.js.map +1 -0
  49. package/dist/application/session-custody-service.js +171 -0
  50. package/dist/application/session-custody-service.js.map +1 -0
  51. package/dist/application/session-resolver.js +21 -0
  52. package/dist/application/session-resolver.js.map +1 -1
  53. package/dist/application/status-service.js +5 -0
  54. package/dist/application/status-service.js.map +1 -1
  55. package/dist/application/workline-index-service.js +31 -0
  56. package/dist/application/workline-index-service.js.map +1 -1
  57. package/dist/application/worktree-service.js +247 -34
  58. package/dist/application/worktree-service.js.map +1 -1
  59. package/dist/cli/commands/check-branch.js +9 -5
  60. package/dist/cli/commands/check-branch.js.map +1 -1
  61. package/dist/cli/commands/dev-only.js +21 -2
  62. package/dist/cli/commands/dev-only.js.map +1 -1
  63. package/dist/cli/commands/flow.js +6 -2
  64. package/dist/cli/commands/flow.js.map +1 -1
  65. package/dist/cli/commands/index.js +6 -0
  66. package/dist/cli/commands/index.js.map +1 -1
  67. package/dist/cli/commands/retirement.js +137 -0
  68. package/dist/cli/commands/retirement.js.map +1 -0
  69. package/dist/cli/commands/session-close.js +12 -1
  70. package/dist/cli/commands/session-close.js.map +1 -1
  71. package/dist/cli/commands/session-create.js +4 -1
  72. package/dist/cli/commands/session-create.js.map +1 -1
  73. package/dist/cli/commands/sources.js +8 -4
  74. package/dist/cli/commands/sources.js.map +1 -1
  75. package/dist/cli/commands/worktree.js +14 -7
  76. package/dist/cli/commands/worktree.js.map +1 -1
  77. package/dist/cli/help-groups.js +4 -0
  78. package/dist/cli/help-groups.js.map +1 -1
  79. package/dist/cli/parser.js +26 -0
  80. package/dist/cli/parser.js.map +1 -1
  81. package/dist/domain/flow/answer.js +72 -4
  82. package/dist/domain/flow/answer.js.map +1 -1
  83. package/dist/domain/flow/authority.js +219 -47
  84. package/dist/domain/flow/authority.js.map +1 -1
  85. package/dist/domain/flow/rules.js +8 -1
  86. package/dist/domain/flow/rules.js.map +1 -1
  87. package/dist/domain/flow/run-state.js +34 -1
  88. package/dist/domain/flow/run-state.js.map +1 -1
  89. package/dist/domain/reservation.js +33 -0
  90. package/dist/domain/reservation.js.map +1 -0
  91. package/dist/domain/retirement/proposal.js +83 -0
  92. package/dist/domain/retirement/proposal.js.map +1 -0
  93. package/dist/domain/retirement/selector.js +109 -0
  94. package/dist/domain/retirement/selector.js.map +1 -0
  95. package/dist/domain/session/custody.js +176 -0
  96. package/dist/domain/session/custody.js.map +1 -0
  97. package/dist/domain/workline-node.js +56 -0
  98. package/dist/domain/workline-node.js.map +1 -0
  99. package/package.json +1 -1
  100. package/skills/w/commands/discard.md +49 -0
  101. package/skills/w/commands/reset.md +50 -0
  102. package/skills/w/context/MANIFEST.json +147 -139
  103. package/skills/w/loops/CODE-POLICIES.md +9 -9
  104. package/skills/w/loops/plan-exec-loop/LOOP.md +23 -13
  105. package/skills/w/loops/plan-new-loop/LOOP.md +1 -1
  106. package/skills/w/modules/PLAN-INPUT.md +1 -1
@@ -0,0 +1,356 @@
1
+ /**
2
+ * From "what did they name" to "exactly which nodes come out", or a refusal.
3
+ *
4
+ * Everything here is read-only and every refusal is actionable: a destructive
5
+ * command that answers "no" without saying which candidates it saw, or which edge
6
+ * it could not prove, forces the person to guess — and guessing is what the whole
7
+ * design exists to prevent. So each rejection carries its code, the candidates and
8
+ * the one next move.
9
+ *
10
+ * The two modes ask genuinely different questions and share only the graph:
11
+ *
12
+ * - **discard** asks "what does this node OWN, transitively and exclusively?"
13
+ * Anything reachable through a provable edge comes out with it; a node that also
14
+ * belongs to something outside the closure stops the whole operation.
15
+ * - **reset** asks "which single INCOMPLETE session is this, and what did it
16
+ * receive?" It never cascades: work that descends from what the session produced
17
+ * would be orphaned, so its presence is a refusal rather than a wider closure.
18
+ */
19
+ import { selectorText } from "../../domain/retirement/selector.js";
20
+ import { formatNodeId, } from "../../domain/workline-node.js";
21
+ /**
22
+ * The node a selector names, or the candidates that make it ambiguous.
23
+ *
24
+ * A bare number is the only form that can be ambiguous by construction, and it is
25
+ * accepted at all because typing `plan:` in front of the number every time is
26
+ * ceremony when only one node answers. The moment two do, the ambiguity is the
27
+ * answer.
28
+ */
29
+ export function resolveTarget(graph, selector) {
30
+ const matches = candidatesFor(graph, selector);
31
+ if (matches.length === 1 && matches[0] !== undefined)
32
+ return { ok: true, node: matches[0] };
33
+ if (matches.length === 0) {
34
+ return {
35
+ ok: false,
36
+ rejection: {
37
+ code: "TARGET_NOT_FOUND",
38
+ message: `no existe ningún nodo que coincida con '${selectorText(selector)}'`,
39
+ candidates: [],
40
+ action: "revisá `aw status` y reintentá con una identidad existente",
41
+ },
42
+ };
43
+ }
44
+ return {
45
+ ok: false,
46
+ rejection: {
47
+ code: "TARGET_AMBIGUOUS",
48
+ message: `'${selectorText(selector)}' coincide con ${matches.length} nodos`,
49
+ candidates: matches.map((n) => formatNodeId(n.id)),
50
+ action: "reintentá con la forma explícita: spec:<NNN>, plan:<PPP>, quick:<NNN> o session:<carpeta>",
51
+ },
52
+ };
53
+ }
54
+ function candidatesFor(graph, selector) {
55
+ switch (selector.form) {
56
+ case "path":
57
+ return graph.all().filter((n) => n.path === selector.path);
58
+ case "folder":
59
+ return graph
60
+ .all()
61
+ .filter((n) => n.kind === "session" && n.session?.folder === selector.folder);
62
+ case "qualified":
63
+ return selector.kind === "quick"
64
+ ? quickCandidates(graph, selector.key)
65
+ : graph.all().filter((n) => n.kind === selector.kind && matchesKey(n, selector.key));
66
+ case "bare":
67
+ return graph.all().filter((n) => matchesKey(n, selector.key));
68
+ }
69
+ }
70
+ /**
71
+ * `quick:<NNN>` addresses a SESSION whose flow was the quick one.
72
+ *
73
+ * A quick has no document of its own, so it is not a node kind — it is a session
74
+ * with a type. Keeping it out of the graph's vocabulary and in the selector's is
75
+ * what stops the graph from having a fourth kind that owns nothing.
76
+ */
77
+ function quickCandidates(graph, key) {
78
+ return graph
79
+ .all()
80
+ .filter((n) => n.kind === "session" && n.session?.type === "quick" && matchesKey(n, key));
81
+ }
82
+ /** A session answers to its number as well as to its folder; a doc only to its number. */
83
+ function matchesKey(node, key) {
84
+ if (node.kind !== "session")
85
+ return node.id.key === key;
86
+ const folder = node.session?.folder ?? node.id.key;
87
+ return folder === key || folder.startsWith(`${key}-`) || folder.startsWith(`session${key}-`);
88
+ }
89
+ /**
90
+ * Everything a discard takes with it, or the reason it takes nothing.
91
+ *
92
+ * The walk only ever follows PROVABLE edges, and it checks two things about each
93
+ * node it reaches: that its own custody can still say what it owns, and that
94
+ * nothing outside the closure descends from it. The second check is what makes
95
+ * "exclusive ownership" a computed fact — a session that belongs to two plans is
96
+ * not a descendant of either, it is shared work, and the operation stops.
97
+ */
98
+ export function resolveDiscardClosure(graph, target) {
99
+ const walked = walkDescendants(graph, target);
100
+ if ("rejection" in walked)
101
+ return { ok: false, rejection: walked.rejection };
102
+ const shared = sharedConsumer(graph, walked.collected);
103
+ if (shared !== null)
104
+ return { ok: false, rejection: shared };
105
+ const missing = missingEvidence([...walked.collected.values()].map((e) => e.node));
106
+ if (missing !== null)
107
+ return { ok: false, rejection: missing };
108
+ return {
109
+ ok: true,
110
+ closure: { mode: "discard", target, entries: removalOrder([...walked.collected.values()]) },
111
+ };
112
+ }
113
+ /**
114
+ * The breadth-first walk down the provable edges, or the first edge that stops it.
115
+ *
116
+ * Separated from the checks that follow it because the two ask different
117
+ * questions: this one is "what hangs off the target", and the ones after it are
118
+ * "may we take all of that". Reading them together is what made a single function
119
+ * hard to hold in the head.
120
+ */
121
+ function walkDescendants(graph, target) {
122
+ const collected = new Map();
123
+ collected.set(formatNodeId(target.id), { node: target, reason: "target" });
124
+ const pending = [target.id];
125
+ const seen = new Set();
126
+ while (pending.length > 0) {
127
+ const current = pending.shift();
128
+ const key = formatNodeId(current);
129
+ if (seen.has(key))
130
+ continue;
131
+ seen.add(key);
132
+ // An edge nobody can prove cannot be followed AND cannot be ignored: the node
133
+ // on its other end may or may not belong here, and both answers are guesses.
134
+ const unprovable = graph.unprovableInto(current);
135
+ if (unprovable.length > 0)
136
+ return { rejection: unprovableEdges(key, unprovable) };
137
+ const rejection = collectChildren(graph, current, collected, pending);
138
+ if (rejection !== null)
139
+ return { rejection };
140
+ }
141
+ return { collected };
142
+ }
143
+ /** One node's children into the closure, or the cycle that has no removal order. */
144
+ function collectChildren(graph, parent, collected, pending) {
145
+ const parentKey = formatNodeId(parent);
146
+ for (const edge of graph.childrenOf(parent)) {
147
+ const child = graph.get(edge.from);
148
+ if (child === undefined)
149
+ continue;
150
+ const childKey = formatNodeId(child.id);
151
+ if (childKey === parentKey)
152
+ return cyclic(childKey);
153
+ if (!collected.has(childKey)) {
154
+ collected.set(childKey, {
155
+ node: child,
156
+ reason: child.kind === "session" ? "internal-session" : "descendant",
157
+ });
158
+ }
159
+ pending.push(child.id);
160
+ }
161
+ return null;
162
+ }
163
+ function unprovableEdges(key, edges) {
164
+ return {
165
+ code: "EVIDENCE_MISSING",
166
+ message: `'${key}' tiene descendientes cuya procedencia no se puede probar`,
167
+ candidates: edges.map((e) => `${formatNodeId(e.from)} (${e.evidence})`),
168
+ action: "esas sesiones nacieron sin custodia: retirálas individualmente por su carpeta, o dejá el objetivo como está",
169
+ };
170
+ }
171
+ /**
172
+ * A node inside the closure that something OUTSIDE also descends from.
173
+ *
174
+ * Counted over the closure's own members rather than over the target alone,
175
+ * because the sharing that matters can be two levels down: a session that hangs
176
+ * off both the plan being discarded and another one is not the target's to delete,
177
+ * even though the target never mentions it.
178
+ */
179
+ function sharedConsumer(graph, collected) {
180
+ for (const { node } of collected.values()) {
181
+ for (const edge of graph.parentsOf(node.id)) {
182
+ if (collected.has(formatNodeId(edge.to)))
183
+ continue;
184
+ // A parent outside the closure is normal for the TARGET itself — that is
185
+ // what it hangs from. It is only sharing when the node came in as a
186
+ // descendant, because then two things own it.
187
+ const entry = collected.get(formatNodeId(node.id));
188
+ if (entry?.reason === "target")
189
+ continue;
190
+ return {
191
+ code: "SHARED_CONSUMER",
192
+ message: `'${formatNodeId(node.id)}' también pertenece a '${formatNodeId(edge.to)}', fuera del alcance`,
193
+ candidates: [formatNodeId(node.id), formatNodeId(edge.to)],
194
+ action: "el alcance no es de propiedad exclusiva: retirá primero el consumidor compartido o elegí un objetivo más chico",
195
+ };
196
+ }
197
+ }
198
+ return null;
199
+ }
200
+ /** A session in the closure whose custody cannot say what it owns. */
201
+ function missingEvidence(nodes) {
202
+ for (const node of nodes) {
203
+ const gap = node.session?.custody_gap ?? null;
204
+ if (gap === null)
205
+ continue;
206
+ return {
207
+ code: "EVIDENCE_MISSING",
208
+ message: `'${formatNodeId(node.id)}' no tiene una custodia reconstruible: ${gap}`,
209
+ candidates: [formatNodeId(node.id)],
210
+ action: "sin baseline no se puede probar qué le pertenece: cerrá o retirá esa sesión a mano antes de retirar el objetivo",
211
+ };
212
+ }
213
+ return null;
214
+ }
215
+ function cyclic(key) {
216
+ return {
217
+ code: "CYCLIC_PROVENANCE",
218
+ message: `la procedencia de '${key}' se cierra sobre sí misma`,
219
+ candidates: [key],
220
+ action: "corregí la procedencia declarada antes de retirar: un ciclo no tiene orden de retiro",
221
+ };
222
+ }
223
+ /**
224
+ * Sessions first, then documents, deepest first.
225
+ *
226
+ * Removal order is material — it is in the seal — because a document removed
227
+ * before the sessions that point at it leaves, for as long as the operation runs,
228
+ * a session whose provenance resolves to nothing.
229
+ */
230
+ function removalOrder(entries) {
231
+ const rank = (entry) => {
232
+ if (entry.node.kind === "session")
233
+ return 0;
234
+ if (entry.reason === "target")
235
+ return 2;
236
+ return 1;
237
+ };
238
+ return [...entries].sort((a, b) => {
239
+ const byRank = rank(a) - rank(b);
240
+ if (byRank !== 0)
241
+ return byRank;
242
+ return formatNodeId(a.node.id) < formatNodeId(b.node.id) ? -1 : 1;
243
+ });
244
+ }
245
+ /**
246
+ * The single incomplete session a reset target names.
247
+ *
248
+ * A session can be named directly; a document names one only when exactly one of
249
+ * its sessions is incomplete. Both roads end in the same requirement, and the
250
+ * assumption behind it is explicit in the spec: a FINISHED session does not become
251
+ * resettable by being selected.
252
+ */
253
+ export function resolveResetSession(graph, target) {
254
+ if (target.kind === "session") {
255
+ const facts = target.session;
256
+ if (facts === null)
257
+ return { ok: false, rejection: noIncomplete(formatNodeId(target.id)) };
258
+ if (facts.completion === "converged") {
259
+ return {
260
+ ok: false,
261
+ rejection: {
262
+ code: "RESET_SESSION_CONVERGED",
263
+ message: `la sesión '${facts.folder}' ya convergió: no es una sesión incompleta`,
264
+ candidates: [facts.folder],
265
+ action: "para retirarla junto con lo que produjo usá `aw discard`; `reset` sólo vuelve atrás lo inconcluso",
266
+ },
267
+ };
268
+ }
269
+ if (facts.completion === "unknown") {
270
+ return {
271
+ ok: false,
272
+ rejection: {
273
+ code: "EVIDENCE_MISSING",
274
+ message: `no se puede probar hasta dónde llegó '${facts.folder}': ${facts.custody_gap ?? "sin evidencia"}`,
275
+ candidates: [facts.folder],
276
+ action: "es una sesión legacy: no hay baseline que restaurar, y reset no lo inventa",
277
+ },
278
+ };
279
+ }
280
+ return { ok: true, node: target };
281
+ }
282
+ const sessions = graph.sessionsOf(target.id);
283
+ const incomplete = sessions.filter((s) => s.session?.completion === "incomplete");
284
+ if (incomplete.length === 1 && incomplete[0] !== undefined) {
285
+ return resolveResetSession(graph, incomplete[0]);
286
+ }
287
+ if (incomplete.length === 0) {
288
+ return { ok: false, rejection: noIncomplete(formatNodeId(target.id), sessions) };
289
+ }
290
+ return {
291
+ ok: false,
292
+ rejection: {
293
+ code: "RESET_AMBIGUOUS_SESSION",
294
+ message: `'${formatNodeId(target.id)}' tiene ${incomplete.length} sesiones incompletas`,
295
+ candidates: incomplete.map((s) => s.session?.folder ?? formatNodeId(s.id)),
296
+ action: "nombrá la sesión exacta con session:<carpeta>",
297
+ },
298
+ };
299
+ }
300
+ function noIncomplete(target, seen = []) {
301
+ return {
302
+ code: "RESET_NO_INCOMPLETE_SESSION",
303
+ message: `'${target}' no resuelve a ninguna sesión incompleta`,
304
+ candidates: seen.map((s) => `${s.session?.folder ?? formatNodeId(s.id)} (${s.session?.completion ?? "?"})`),
305
+ action: "reset necesita una sesión que no haya convergido; revisá `aw status --detail`",
306
+ };
307
+ }
308
+ /**
309
+ * What a reset takes out: the session, plus the documents it BORN.
310
+ *
311
+ * It stops at one level on purpose. A document this session created that already
312
+ * has work of its own is not something a reset may remove — that work would be
313
+ * orphaned — so its presence is a refusal, which is the same rule discard applies
314
+ * to shared ownership, read from the other direction.
315
+ */
316
+ export function resolveResetClosure(graph, session) {
317
+ const entries = [
318
+ { node: session, reason: "target" },
319
+ ];
320
+ const custody = session.session?.custody ?? null;
321
+ if (custody === null) {
322
+ return {
323
+ ok: false,
324
+ rejection: {
325
+ code: "EVIDENCE_MISSING",
326
+ message: `'${formatNodeId(session.id)}' no tiene custodia: no hay salidas ni entradas que probar`,
327
+ candidates: [formatNodeId(session.id)],
328
+ action: "es una sesión legacy: retirala a mano o usá discard sobre su carpeta",
329
+ },
330
+ };
331
+ }
332
+ for (const artifact of custody.artifacts) {
333
+ if (artifact.role !== "output")
334
+ continue;
335
+ const node = graph.all().find((n) => n.path === artifact.path);
336
+ if (node === undefined)
337
+ continue;
338
+ const others = graph
339
+ .childrenOf(node.id)
340
+ .filter((e) => formatNodeId(e.from) !== formatNodeId(session.id));
341
+ if (others.length > 0) {
342
+ return {
343
+ ok: false,
344
+ rejection: {
345
+ code: "SHARED_CONSUMER",
346
+ message: `'${artifact.path}' ya tiene trabajo que depende de él`,
347
+ candidates: others.map((e) => formatNodeId(e.from)),
348
+ action: "retirá primero ese trabajo, o usá discard sobre el documento si querés llevártelo todo",
349
+ },
350
+ };
351
+ }
352
+ entries.push({ node, reason: "descendant" });
353
+ }
354
+ return { ok: true, closure: { mode: "reset", target: session, entries: removalOrder(entries) } };
355
+ }
356
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/application/retirement/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAuB,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACxF,OAAO,EAGL,YAAY,GACb,MAAM,+BAA+B,CAAC;AAyBvC;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,KAAsB,EAAE,QAAwB;IAC5E,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC/C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5F,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,SAAS,EAAE;gBACT,IAAI,EAAE,kBAAkB;gBACxB,OAAO,EAAE,2CAA2C,YAAY,CAAC,QAAQ,CAAC,GAAG;gBAC7E,UAAU,EAAE,EAAE;gBACd,MAAM,EAAE,4DAA4D;aACrE;SACF,CAAC;IACJ,CAAC;IACD,OAAO;QACL,EAAE,EAAE,KAAK;QACT,SAAS,EAAE;YACT,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,IAAI,YAAY,CAAC,QAAQ,CAAC,kBAAkB,OAAO,CAAC,MAAM,QAAQ;YAC3E,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClD,MAAM,EACJ,2FAA2F;SAC9F;KACF,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAsB,EAAE,QAAwB;IACrE,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,MAAM;YACT,OAAO,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7D,KAAK,QAAQ;YACX,OAAO,KAAK;iBACT,GAAG,EAAE;iBACL,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC;QAClF,KAAK,WAAW;YACd,OAAO,QAAQ,CAAC,IAAI,KAAK,OAAO;gBAC9B,CAAC,CAAC,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC;gBACtC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,IAAI,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QACzF,KAAK,MAAM;YACT,OAAO,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAClE,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,KAAsB,EAAE,GAAW;IAC1D,OAAO,KAAK;SACT,GAAG,EAAE;SACL,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,EAAE,IAAI,KAAK,OAAO,IAAI,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AAC9F,CAAC;AAED,0FAA0F;AAC1F,SAAS,UAAU,CAAC,IAAe,EAAE,GAAW;IAC9C,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC;IACxD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC;IACnD,OAAO,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC;AAC/F,CAAC;AAaD;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAsB,EACtB,MAAiB;IAEjB,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9C,IAAI,WAAW,IAAI,MAAM;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;IAE7E,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IACvD,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAC7D,MAAM,OAAO,GAAG,eAAe,CAAC,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACnF,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;IAE/D,OAAO;QACL,EAAE,EAAE,IAAI;QACR,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE;KAC5F,CAAC;AACJ,CAAC;AAID;;;;;;;GAOG;AACH,SAAS,eAAe,CACtB,KAAsB,EACtB,MAAiB;IAEjB,MAAM,SAAS,GAAc,IAAI,GAAG,EAAE,CAAC;IACvC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAE3E,MAAM,OAAO,GAAqB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,EAAoB,CAAC;QAClD,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEd,8EAA8E;QAC9E,6EAA6E;QAC7E,MAAM,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,EAAE,SAAS,EAAE,eAAe,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,CAAC;QAElF,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QACtE,IAAI,SAAS,KAAK,IAAI;YAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAC/C,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,CAAC;AACvB,CAAC;AAED,oFAAoF;AACpF,SAAS,eAAe,CACtB,KAAsB,EACtB,MAAsB,EACtB,SAAoB,EACpB,OAAyB;IAEzB,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE;gBACtB,IAAI,EAAE,KAAK;gBACX,MAAM,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,YAAY;aACrE,CAAC,CAAC;QACL,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,eAAe,CAAC,GAAW,EAAE,KAA8B;IAClE,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,OAAO,EAAE,IAAI,GAAG,2DAA2D;QAC3E,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,GAAG,CAAC;QACvE,MAAM,EACJ,6GAA6G;KAChH,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CACrB,KAAsB,EACtB,SAA2E;IAE3E,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;QAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YAC5C,IAAI,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAAE,SAAS;YACnD,yEAAyE;YACzE,oEAAoE;YACpE,8CAA8C;YAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACnD,IAAI,KAAK,EAAE,MAAM,KAAK,QAAQ;gBAAE,SAAS;YACzC,OAAO;gBACL,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,0BAA0B,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,sBAAsB;gBACvG,UAAU,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC1D,MAAM,EACJ,gHAAgH;aACnH,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sEAAsE;AACtE,SAAS,eAAe,CAAC,KAA2B;IAClD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,WAAW,IAAI,IAAI,CAAC;QAC9C,IAAI,GAAG,KAAK,IAAI;YAAE,SAAS;QAC3B,OAAO;YACL,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,0CAA0C,GAAG,EAAE;YACjF,UAAU,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACnC,MAAM,EACJ,iHAAiH;SACpH,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,MAAM,CAAC,GAAW;IACzB,OAAO;QACL,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,sBAAsB,GAAG,4BAA4B;QAC9D,UAAU,EAAE,CAAC,GAAG,CAAC;QACjB,MAAM,EAAE,sFAAsF;KAC/F,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,YAAY,CACnB,OAAmE;IAEnE,MAAM,IAAI,GAAG,CAAC,KAA0D,EAAU,EAAE;QAClF,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC;QACxC,OAAO,CAAC,CAAC;IACX,CAAC,CAAC;IACF,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC;QAChC,OAAO,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAsB,EAAE,MAAiB;IAC3E,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC;QAC7B,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC3F,IAAI,KAAK,CAAC,UAAU,KAAK,WAAW,EAAE,CAAC;YACrC,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,SAAS,EAAE;oBACT,IAAI,EAAE,yBAAyB;oBAC/B,OAAO,EAAE,cAAc,KAAK,CAAC,MAAM,6CAA6C;oBAChF,UAAU,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;oBAC1B,MAAM,EACJ,mGAAmG;iBACtG;aACF,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACnC,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,SAAS,EAAE;oBACT,IAAI,EAAE,kBAAkB;oBACxB,OAAO,EAAE,yCAAyC,KAAK,CAAC,MAAM,MAAM,KAAK,CAAC,WAAW,IAAI,eAAe,EAAE;oBAC1G,UAAU,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;oBAC1B,MAAM,EAAE,4EAA4E;iBACrF;aACF,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACpC,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,UAAU,KAAK,YAAY,CAAC,CAAC;IAClF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QAC3D,OAAO,mBAAmB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC;IACnF,CAAC;IACD,OAAO;QACL,EAAE,EAAE,KAAK;QACT,SAAS,EAAE;YACT,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,UAAU,CAAC,MAAM,uBAAuB;YACvF,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC1E,MAAM,EAAE,+CAA+C;SACxD;KACF,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,MAAc,EAAE,OAA6B,EAAE;IACnE,OAAO;QACL,IAAI,EAAE,6BAA6B;QACnC,OAAO,EAAE,IAAI,MAAM,2CAA2C;QAC9D,UAAU,EAAE,IAAI,CAAC,GAAG,CAClB,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,UAAU,IAAI,GAAG,GAAG,CACtF;QACD,MAAM,EAAE,+EAA+E;KACxF,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAsB,EAAE,OAAkB;IAC5E,MAAM,OAAO,GAA+D;QAC1E,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE;KACpC,CAAC;IACF,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC;IACjD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,SAAS,EAAE;gBACT,IAAI,EAAE,kBAAkB;gBACxB,OAAO,EAAE,IAAI,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,4DAA4D;gBACjG,UAAU,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACtC,MAAM,EAAE,sEAAsE;aAC/E;SACF,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACzC,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ;YAAE,SAAS;QACzC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC/D,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS;QACjC,MAAM,MAAM,GAAG,KAAK;aACjB,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;aACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACpE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,SAAS,EAAE;oBACT,IAAI,EAAE,iBAAiB;oBACvB,OAAO,EAAE,IAAI,QAAQ,CAAC,IAAI,sCAAsC;oBAChE,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBACnD,MAAM,EACJ,wFAAwF;iBAC3F;aACF,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;AACnG,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { join } from "node:path";
2
+ import { reservationMarker } from "../domain/reservation.js";
2
3
  import { historyFields, upsertHistoryRow } from "./history-update-service.js";
3
4
  import { withCwdLock } from "./lock-service.js";
4
5
  import { canonicalArtifactPath } from "./session-artifacts.js";
@@ -21,6 +22,13 @@ export async function runSessionClose(fs, paths, input, isolation) {
21
22
  // the canonical path.
22
23
  const checkpointPath = canonicalArtifactPath(session.path, "checkpoint");
23
24
  await ensureFile(fs, checkpointPath, "# CHECKPOINT\n");
25
+ // BEFORE the marker, and that is the whole of it: `.closed` is what makes the
26
+ // integrate commands below stop resolving, so a check that ran after writing it
27
+ // would be a receipt for a state it had just made harder to leave.
28
+ const units = await heldUnits(isolation, session.folder);
29
+ if (input.requireIntegrated === true && (units.held.length > 0 || units.error !== undefined)) {
30
+ return refuseHeld(session.code ?? input.code, session.folder, units);
31
+ }
24
32
  const refs = input.refs?.trim();
25
33
  const closure = await closeUnderLock(fs, paths, session, {
26
34
  code: session.code ?? input.code,
@@ -39,33 +47,119 @@ export async function runSessionClose(fs, paths, input, isolation) {
39
47
  ...(closure.history ? { history: closure.history } : {}),
40
48
  ...(closure.history_error !== undefined ? { history_error: closure.history_error } : {}),
41
49
  };
42
- const held = await heldUnits(isolation, session.folder);
43
- if (held.length > 0)
44
- sessionClose.pending_integration = held;
50
+ reportHeld(sessionClose, session.folder, units);
51
+ reportReservations(sessionClose, await releaseReservations(fs, paths, session.folder));
45
52
  // Last write of the session's life, and the one that matters most: whoever
46
53
  // opens a closed session months later reads the block, and a block left saying
47
54
  // "abierta" would be the closing act failing to record itself.
48
55
  await writeSessionNarrative(fs, paths, { folder: session.folder, path: session.path });
49
56
  return { sessionClose };
50
57
  }
58
+ /** Units survived the close: say so, and say how to come back for them. */
59
+ function reportHeld(output, folder, units) {
60
+ if (units.error !== undefined)
61
+ output.pending_integration_error = units.error;
62
+ if (units.held.length === 0)
63
+ return;
64
+ output.pending_integration = units.held;
65
+ output.reopen = `aw session-resume --code ${folder} --reopen`;
66
+ }
67
+ function reportReservations(output, reservations) {
68
+ if (reservations.released.length > 0)
69
+ output.reservations_released = reservations.released;
70
+ if (reservations.error !== undefined)
71
+ output.reservations_error = reservations.error;
72
+ }
73
+ /** The close that stopped, told so the reader can act without asking anything else. */
74
+ function refuseHeld(code, folder, units) {
75
+ return {
76
+ sessionHeld: {
77
+ code,
78
+ folder,
79
+ closed: false,
80
+ reason: units.error !== undefined
81
+ ? `no se pudo comprobar si la sesión conserva unidades — ${units.error}`
82
+ : `la sesión todavía tiene ${units.held.length} unidad(es) sin integrar: su trabajo son commits que no están en ninguna rama de trabajo`,
83
+ pending_integration: units.held,
84
+ integrate: `aw worktree integrate --code ${folder}`,
85
+ },
86
+ };
87
+ }
88
+ /**
89
+ * The units this session holds — or the fact that nobody could tell.
90
+ *
91
+ * The two are different answers and this used to flatten them into one: an
92
+ * unreadable isolation state came back as an empty list, which reads as "there is
93
+ * nothing to integrate". Harmless while closing only REPORTED; not harmless now
94
+ * that it can refuse, because the one state that must never close silently is
95
+ * exactly the one whose evidence could not be read.
96
+ */
51
97
  async function heldUnits(isolation, folder) {
52
98
  if (isolation === undefined)
53
- return [];
99
+ return { held: [] };
54
100
  let units;
55
101
  try {
56
102
  units = await isolation();
57
103
  }
58
- catch {
59
- return [];
104
+ catch (error) {
105
+ return {
106
+ held: [],
107
+ error: `no se pudieron leer las unidades de ${folder}: ${error instanceof Error ? error.message : String(error)}`,
108
+ };
109
+ }
110
+ return {
111
+ held: units
112
+ .filter((u) => u.session === folder)
113
+ .map((u) => ({
114
+ alias: u.alias,
115
+ branch: u.branch,
116
+ path: u.path,
117
+ command: `aw worktree integrate --source ${u.alias} --code ${folder}`,
118
+ })),
119
+ };
120
+ }
121
+ /**
122
+ * Give back every correlative this session claimed and never wrote into.
123
+ *
124
+ * Bytes-exact and owner-scoped, which is the whole safety argument: the only
125
+ * files it can remove are the ones still holding this session's own marker, so a
126
+ * published document, a slot somebody edited and another session's reservation
127
+ * are all invisible to it. Non-fatal — a close that failed over garbage
128
+ * collection would strand a session — but never silent: what it could not scan
129
+ * comes back as the error beside what it did release, because an empty list and
130
+ * an unreadable directory are different facts.
131
+ *
132
+ * The scan walks every immediate subdirectory of `docs/`, not a list of
133
+ * categories: the claim mechanism is category-agnostic, and a hardcoded list is a
134
+ * second place to update the day something else claims a number.
135
+ */
136
+ async function releaseReservations(fs, paths, folder) {
137
+ const marker = reservationMarker(folder);
138
+ const docs = join(paths.workspaceDir(), "docs");
139
+ const released = [];
140
+ try {
141
+ if (!(await fs.exists(docs)))
142
+ return { released };
143
+ for (const category of await fs.list(docs)) {
144
+ if (category.type !== "dir")
145
+ continue;
146
+ for (const entry of await fs.list(category.path)) {
147
+ if (entry.type !== "file" || !/^\d{3}-/.test(entry.name))
148
+ continue;
149
+ if ((await fs.readText(entry.path)) !== marker)
150
+ continue;
151
+ await fs.remove(entry.path);
152
+ released.push(`docs/${category.name}/${entry.name}`);
153
+ }
154
+ }
155
+ }
156
+ catch (error) {
157
+ return {
158
+ released: released.sort(),
159
+ error: `no se pudo revisar las reservas de ${folder} en docs/: ${error instanceof Error ? error.message : String(error)}`,
160
+ };
60
161
  }
61
- return units
62
- .filter((u) => u.session === folder)
63
- .map((u) => ({
64
- alias: u.alias,
65
- branch: u.branch,
66
- path: u.path,
67
- command: `aw worktree integrate --source ${u.alias} --code ${folder}`,
68
- }));
162
+ return { released: released.sort() };
69
163
  }
70
164
  /**
71
165
  * The whole shared-state mutation of a close, under ONE lock acquisition:
@@ -1 +1 @@
1
- {"version":3,"file":"session-close-service.js","sourceRoot":"","sources":["../../src/application/session-close-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-close-service.js","sourceRoot":"","sources":["../../src/application/session-close-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EACL,aAAa,EAGb,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AA4G/B,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,EAAkB,EAClB,KAAmB,EACnB,KAAwB,EACxB,SAA2B;IAE3B,4EAA4E;IAC5E,yEAAyE;IACzE,kBAAkB;IAClB,IAAI,CAAC,KAAK,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC;IAC3D,MAAM,UAAU,GAAG,MAAM,oBAAoB,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAClG,IAAI,UAAU,CAAC,OAAO,KAAK,UAAU;QAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3E,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;IAEnC,4EAA4E;IAC5E,+EAA+E;IAC/E,8EAA8E;IAC9E,sBAAsB;IACtB,MAAM,cAAc,GAAG,qBAAqB,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACzE,MAAM,UAAU,CAAC,EAAE,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAAC;IAEvD,8EAA8E;IAC9E,gFAAgF;IAChF,mEAAmE;IACnE,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,IAAI,KAAK,CAAC,iBAAiB,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,EAAE,CAAC;QAC7F,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;QACvD,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;QAChC,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3D,CAAC,CAAC;IACH,IAAI,OAAO,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAEvC,MAAM,YAAY,GAAuB;QACvC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;QAChC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,IAAI;QACZ,eAAe,EAAE,cAAc;QAC/B,YAAY,EAAE,qBAAqB,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;QAC5D,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;QAClD,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACzF,CAAC;IACF,UAAU,CAAC,YAAY,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAChD,kBAAkB,CAAC,YAAY,EAAE,MAAM,mBAAmB,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACvF,2EAA2E;IAC3E,+EAA+E;IAC/E,+DAA+D;IAC/D,MAAM,qBAAqB,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACvF,OAAO,EAAE,YAAY,EAAE,CAAC;AAC1B,CAAC;AAED,2EAA2E;AAC3E,SAAS,UAAU,CAAC,MAA0B,EAAE,MAAc,EAAE,KAAgB;IAC9E,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,yBAAyB,GAAG,KAAK,CAAC,KAAK,CAAC;IAC9E,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACpC,MAAM,CAAC,mBAAmB,GAAG,KAAK,CAAC,IAAI,CAAC;IACxC,MAAM,CAAC,MAAM,GAAG,4BAA4B,MAAM,WAAW,CAAC;AAChE,CAAC;AAED,SAAS,kBAAkB,CACzB,MAA0B,EAC1B,YAAoD;IAEpD,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,CAAC,qBAAqB,GAAG,YAAY,CAAC,QAAQ,CAAC;IAC3F,IAAI,YAAY,CAAC,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,kBAAkB,GAAG,YAAY,CAAC,KAAK,CAAC;AACvF,CAAC;AAED,uFAAuF;AACvF,SAAS,UAAU,CAAC,IAAY,EAAE,MAAc,EAAE,KAAgB;IAChE,OAAO;QACL,WAAW,EAAE;YACX,IAAI;YACJ,MAAM;YACN,MAAM,EAAE,KAAK;YACb,MAAM,EACJ,KAAK,CAAC,KAAK,KAAK,SAAS;gBACvB,CAAC,CAAC,yDAAyD,KAAK,CAAC,KAAK,EAAE;gBACxE,CAAC,CAAC,2BAA2B,KAAK,CAAC,IAAI,CAAC,MAAM,0FAA0F;YAC5I,mBAAmB,EAAE,KAAK,CAAC,IAAI;YAC/B,SAAS,EAAE,gCAAgC,MAAM,EAAE;SACpD;KACF,CAAC;AACJ,CAAC;AAaD;;;;;;;;GAQG;AACH,KAAK,UAAU,SAAS,CACtB,SAAsC,EACtC,MAAc;IAEd,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IACjD,IAAI,KAA2C,CAAC;IAChD,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,IAAI,EAAE,EAAE;YACR,KAAK,EAAE,uCAAuC,MAAM,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;SAClH,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,KAAK;aACR,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC;aACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,kCAAkC,CAAC,CAAC,KAAK,WAAW,MAAM,EAAE;SACtE,CAAC,CAAC;KACN,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,KAAK,UAAU,mBAAmB,CAChC,EAAkB,EAClB,KAAmB,EACnB,MAAc;IAEd,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,CAAC;QACH,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;QAClD,KAAK,MAAM,QAAQ,IAAI,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK;gBAAE,SAAS;YACtC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;oBAAE,SAAS;gBACnE,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,MAAM;oBAAE,SAAS;gBACzD,MAAM,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC5B,QAAQ,CAAC,IAAI,CAAC,QAAQ,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE;YACzB,KAAK,EAAE,sCAAsC,MAAM,cAAc,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;SAC1H,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;AACvC,CAAC;AAQD;;;;;;;;;GASG;AACH,KAAK,UAAU,cAAc,CAC3B,EAAkB,EAClB,KAAmB,EACnB,OAAqB,EACrB,GAAoC;IAMpC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,IAAqB,EAAE;QACtE,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1E,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC;YACpB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,yBAAyB,EAAE,EAAE,CAAC;QAChG,CAAC;QACD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAY,EAAE,oBAAoB,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;QACvE,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,gBAAgB,CACpC,EAAE,EACF,KAAK,EACL,aAAa,CAAC,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,CAC9D,CAAC;YACF,OAAO,CAAC,OAAO,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;QACrE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,wEAAwE;YACxE,OAAO,CAAC,aAAa,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,IAAI,OAAO,IAAI,MAAM;QAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACzE,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;AACrD,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,EAAkB,EAAE,IAAY,EAAE,cAAsB;IAChF,IAAI,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC;QAAE,OAAO;IAClC,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;AAC3C,CAAC"}