@tacuchi/agent-workflow-cli 21.8.0 → 21.9.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.
- package/dist/adapters/git-cli.js +217 -0
- package/dist/adapters/git-cli.js.map +1 -1
- package/dist/application/flow/flow-service.js +7 -0
- package/dist/application/flow/flow-service.js.map +1 -1
- package/dist/application/flow/internal-actions.js +5 -0
- package/dist/application/flow/internal-actions.js.map +1 -1
- package/dist/application/history-table.js +37 -0
- package/dist/application/history-table.js.map +1 -1
- package/dist/application/local-proposal.js +37 -0
- package/dist/application/local-proposal.js.map +1 -1
- package/dist/application/retirement/apply.js +448 -0
- package/dist/application/retirement/apply.js.map +1 -0
- package/dist/application/retirement/attribution.js +395 -0
- package/dist/application/retirement/attribution.js.map +1 -0
- package/dist/application/retirement/graph.js +196 -0
- package/dist/application/retirement/graph.js.map +1 -0
- package/dist/application/retirement/history-events.js +158 -0
- package/dist/application/retirement/history-events.js.map +1 -0
- package/dist/application/retirement/journal.js +113 -0
- package/dist/application/retirement/journal.js.map +1 -0
- package/dist/application/retirement/prepare.js +233 -0
- package/dist/application/retirement/prepare.js.map +1 -0
- package/dist/application/retirement/preview.js +101 -0
- package/dist/application/retirement/preview.js.map +1 -0
- package/dist/application/retirement/resolve.js +356 -0
- package/dist/application/retirement/resolve.js.map +1 -0
- package/dist/application/session-create-service.js +103 -12
- package/dist/application/session-create-service.js.map +1 -1
- package/dist/application/session-custody-recorder.js +137 -0
- package/dist/application/session-custody-recorder.js.map +1 -0
- package/dist/application/session-custody-service.js +171 -0
- package/dist/application/session-custody-service.js.map +1 -0
- package/dist/application/status-service.js +5 -0
- package/dist/application/status-service.js.map +1 -1
- package/dist/application/workline-index-service.js +31 -0
- package/dist/application/workline-index-service.js.map +1 -1
- package/dist/application/worktree-service.js +47 -1
- package/dist/application/worktree-service.js.map +1 -1
- package/dist/cli/commands/index.js +6 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/retirement.js +137 -0
- package/dist/cli/commands/retirement.js.map +1 -0
- package/dist/cli/commands/session-create.js +4 -1
- package/dist/cli/commands/session-create.js.map +1 -1
- package/dist/cli/help-groups.js +4 -0
- package/dist/cli/help-groups.js.map +1 -1
- package/dist/domain/flow/authority.js +8 -0
- package/dist/domain/flow/authority.js.map +1 -1
- package/dist/domain/retirement/proposal.js +83 -0
- package/dist/domain/retirement/proposal.js.map +1 -0
- package/dist/domain/retirement/selector.js +109 -0
- package/dist/domain/retirement/selector.js.map +1 -0
- package/dist/domain/session/custody.js +176 -0
- package/dist/domain/session/custody.js.map +1 -0
- package/dist/domain/workline-node.js +56 -0
- package/dist/domain/workline-node.js.map +1 -0
- package/package.json +1 -1
- package/skills/w/commands/discard.md +49 -0
- package/skills/w/commands/reset.md +50 -0
- package/skills/w/context/MANIFEST.json +147 -139
|
@@ -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":"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"}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
+
import { checkSafeRelativePath } from "../domain/safe-path.js";
|
|
3
|
+
import { nodeFromDocPath } from "../domain/workline-node.js";
|
|
4
|
+
import { localDateIso } from "./dates.js";
|
|
5
|
+
import { maxHistoryNumber } from "./history-table.js";
|
|
2
6
|
import { withCwdLock } from "./lock-service.js";
|
|
3
7
|
import { canonicalArtifactPath } from "./session-artifacts.js";
|
|
4
8
|
import { bindContextToSession, readBindingRegistry } from "./session-binding-service.js";
|
|
9
|
+
import { baselineOf, birthCustody, custodyPath, writeCustody } from "./session-custody-service.js";
|
|
5
10
|
import { renderSessionMarkdown } from "./templates/session.js";
|
|
6
11
|
const VALID_TYPES = ["research", "refine", "exec", "quick"];
|
|
7
12
|
export async function runSessionCreate(fs, paths, input) {
|
|
@@ -9,7 +14,14 @@ export async function runSessionCreate(fs, paths, input) {
|
|
|
9
14
|
if ("error" in validated)
|
|
10
15
|
return validated;
|
|
11
16
|
const { type, name, objetivo } = validated;
|
|
12
|
-
|
|
17
|
+
// Baselines are read BEFORE the claim so the bytes sealed are the ones that
|
|
18
|
+
// existed before this session could touch anything, and a declared input that
|
|
19
|
+
// cannot be read fails the creation instead of producing a custody that
|
|
20
|
+
// pretends to know what it received.
|
|
21
|
+
const baselines = await readBaselines(fs, paths, input.inputs ?? []);
|
|
22
|
+
if ("error" in baselines)
|
|
23
|
+
return baselines;
|
|
24
|
+
const folderInfo = await claimSessionFolder(fs, paths, name, input.contextId, baselines.artifacts);
|
|
13
25
|
if ("error" in folderInfo)
|
|
14
26
|
return folderInfo;
|
|
15
27
|
const sessionPath = folderInfo.sessionPath;
|
|
@@ -28,11 +40,47 @@ export async function runSessionCreate(fs, paths, input) {
|
|
|
28
40
|
folder: folderInfo.folder,
|
|
29
41
|
path: sessionPath,
|
|
30
42
|
session_path: sessionFilePath,
|
|
43
|
+
custody_path: folderInfo.custodyPath,
|
|
44
|
+
inputs: baselines.artifacts.map((a) => a.path),
|
|
31
45
|
};
|
|
32
46
|
if (origin && origin.length > 0)
|
|
33
47
|
record.origin = origin;
|
|
34
48
|
return { sessionCreate: record };
|
|
35
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* The sealed previous state of every declared input, or the refusal.
|
|
52
|
+
*
|
|
53
|
+
* The path guard is the workspace's own (`checkSafeRelativePath`), the same one
|
|
54
|
+
* every other write boundary uses: a second, hand-rolled version of "is this
|
|
55
|
+
* relative" is how two boundaries end up disagreeing about which paths are
|
|
56
|
+
* allowed. A repeated input is collapsed rather than sealed twice — the baseline
|
|
57
|
+
* of a path is one fact.
|
|
58
|
+
*/
|
|
59
|
+
async function readBaselines(fs, paths, inputs) {
|
|
60
|
+
const artifacts = [];
|
|
61
|
+
const root = paths.workspaceDir();
|
|
62
|
+
for (const raw of inputs) {
|
|
63
|
+
const safe = checkSafeRelativePath(raw);
|
|
64
|
+
if (!safe.ok) {
|
|
65
|
+
return {
|
|
66
|
+
error: `--input '${raw}' tiene que ser una ruta relativa al workspace: ${safe.why}`,
|
|
67
|
+
code: "INVALID_INPUT",
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (artifacts.some((a) => a.path === safe.path))
|
|
71
|
+
continue;
|
|
72
|
+
try {
|
|
73
|
+
artifacts.push(await baselineOf(fs, root, safe.path));
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
return {
|
|
77
|
+
error: `no se pudo sellar el estado previo de '${safe.path}': ${err instanceof Error ? err.message : String(err)}`,
|
|
78
|
+
code: "CUSTODY_BASELINE_UNREADABLE",
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return { artifacts };
|
|
83
|
+
}
|
|
36
84
|
function validateInput(input) {
|
|
37
85
|
const type = input.type?.trim().toLowerCase();
|
|
38
86
|
if (!type) {
|
|
@@ -56,11 +104,17 @@ function validateInput(input) {
|
|
|
56
104
|
return { type: type, name, objetivo };
|
|
57
105
|
}
|
|
58
106
|
/**
|
|
59
|
-
* Claim number + folder + conversation association under ONE lock: two
|
|
107
|
+
* Claim number + folder + custody + conversation association under ONE lock: two
|
|
60
108
|
* concurrent creations must not read the same counter and race for the same
|
|
61
|
-
* `NNN`, and the new line must belong to its conversation
|
|
109
|
+
* `NNN`, and the new line must belong to its conversation — and hold its sealed
|
|
110
|
+
* baseline — the moment it exists.
|
|
111
|
+
*
|
|
112
|
+
* The custody is written INSIDE the critical section for the same reason the
|
|
113
|
+
* number is minted there: a session that becomes visible before its baseline is
|
|
114
|
+
* sealed is a session another process can start driving, and the first mutation
|
|
115
|
+
* would then land against a custody nobody had written yet.
|
|
62
116
|
*/
|
|
63
|
-
async function claimSessionFolder(fs, paths, name, contextId) {
|
|
117
|
+
async function claimSessionFolder(fs, paths, name, contextId, artifacts) {
|
|
64
118
|
const id = contextId?.trim() ?? "";
|
|
65
119
|
const result = await withCwdLock(fs, paths, async () => {
|
|
66
120
|
// Fail before creating anything when the registry cannot be read: a session
|
|
@@ -82,30 +136,67 @@ async function claimSessionFolder(fs, paths, name, contextId) {
|
|
|
82
136
|
// `NNN-` prefix is assigned here. A descriptor that already carries a leading
|
|
83
137
|
// `NNN-` is normalized away first so the prefix can't double up.
|
|
84
138
|
const descriptor = name.replace(/^\d{3}-/, "");
|
|
85
|
-
const number = await nextSessionNumber(fs, sessionsDir);
|
|
139
|
+
const number = await nextSessionNumber(fs, paths, sessionsDir);
|
|
86
140
|
const folder = `${number}-${descriptor}`;
|
|
87
141
|
const sessionPath = join(sessionsDir, folder);
|
|
88
142
|
if (await fs.exists(sessionPath)) {
|
|
89
143
|
return { ok: false, failure: { error: `Ya existe ${sessionPath}` } };
|
|
90
144
|
}
|
|
91
145
|
await fs.mkdirp(sessionPath);
|
|
146
|
+
await writeCustody(fs, sessionPath, birthCustody({
|
|
147
|
+
subject: { kind: "session", key: folder },
|
|
148
|
+
subjectPath: sessionPath,
|
|
149
|
+
parents: parentsOf(artifacts),
|
|
150
|
+
artifacts,
|
|
151
|
+
created: localDateIso(new Date()),
|
|
152
|
+
}));
|
|
92
153
|
if (id.length > 0)
|
|
93
154
|
await bindContextToSession(fs, paths, id, folder);
|
|
94
|
-
return {
|
|
155
|
+
return {
|
|
156
|
+
ok: true,
|
|
157
|
+
info: { folder, number, sessionPath, custodyPath: custodyPath(sessionPath) },
|
|
158
|
+
};
|
|
95
159
|
});
|
|
96
160
|
if ("error" in result)
|
|
97
161
|
return { error: result.error, code: "LOCK_BUSY" };
|
|
98
162
|
return result.ok ? result.info : result.failure;
|
|
99
163
|
}
|
|
100
164
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
165
|
+
* The typed parents a set of declared inputs implies.
|
|
166
|
+
*
|
|
167
|
+
* An input is the document the run works ON, so the document IS its parent — and
|
|
168
|
+
* the edge is provable, because the path was declared by the caller and its
|
|
169
|
+
* identity is fixed by the workspace layout. An input that names no spec or plan
|
|
170
|
+
* (a checkpoint, a loose file) contributes no parent rather than a guessed one.
|
|
171
|
+
*/
|
|
172
|
+
function parentsOf(artifacts) {
|
|
173
|
+
const parents = [];
|
|
174
|
+
for (const artifact of artifacts) {
|
|
175
|
+
const node = nodeFromDocPath(artifact.path);
|
|
176
|
+
if (node === null)
|
|
177
|
+
continue;
|
|
178
|
+
if (parents.some((p) => p.kind === node.kind && p.key === node.key))
|
|
179
|
+
continue;
|
|
180
|
+
parents.push(node);
|
|
181
|
+
}
|
|
182
|
+
return parents;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Next global session number: the maximum of what the sessions folder holds and
|
|
186
|
+
* what `HISTORY.md` remembers, plus one, zero-padded. Type-agnostic — one
|
|
187
|
+
* sequence for every session regardless of kind.
|
|
188
|
+
*
|
|
189
|
+
* HISTORY is read as well as the folder because a RETIRED session leaves no
|
|
190
|
+
* folder behind: scanning live directories alone would hand `119` to a new
|
|
191
|
+
* session after the old `119` was discarded, and the two would then share a row
|
|
192
|
+
* key, a unit branch and a `--code`. Numbering is monotonic even across
|
|
193
|
+
* deletions — an identity is spent once. Legacy `sessionNNN-…` folders carry no
|
|
194
|
+
* leading digit and are ignored by the folder half, while the history half still
|
|
195
|
+
* recognizes their rows.
|
|
105
196
|
*/
|
|
106
|
-
async function nextSessionNumber(fs, sessionsDir) {
|
|
197
|
+
async function nextSessionNumber(fs, paths, sessionsDir) {
|
|
107
198
|
const entries = await fs.list(sessionsDir);
|
|
108
|
-
let max =
|
|
199
|
+
let max = await maxHistoryNumber(fs, paths.cwdHistoryFile());
|
|
109
200
|
for (const entry of entries) {
|
|
110
201
|
const m = entry.name.match(/^(\d{3})/);
|
|
111
202
|
if (m?.[1])
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-create-service.js","sourceRoot":"","sources":["../../src/application/session-create-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"session-create-service.js","sourceRoot":"","sources":["../../src/application/session-create-service.ts"],"names":[],"mappings":"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"}
|