@tacuchi/agent-workflow-cli 20.22.0 → 20.24.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 (168) hide show
  1. package/dist/adapters/git-cli.js +42 -0
  2. package/dist/adapters/git-cli.js.map +1 -1
  3. package/dist/application/artifacts-service.js +5 -5
  4. package/dist/application/artifacts-service.js.map +1 -1
  5. package/dist/application/checkpoint-service.js +60 -55
  6. package/dist/application/checkpoint-service.js.map +1 -1
  7. package/dist/application/checkpoint-write-service.js +61 -66
  8. package/dist/application/checkpoint-write-service.js.map +1 -1
  9. package/dist/application/context/budget-service.js +128 -0
  10. package/dist/application/context/budget-service.js.map +1 -0
  11. package/dist/application/context/bundle-root.js +41 -0
  12. package/dist/application/context/bundle-root.js.map +1 -0
  13. package/dist/application/context/manifest.js +150 -0
  14. package/dist/application/context/manifest.js.map +1 -0
  15. package/dist/application/context/measure.js +227 -0
  16. package/dist/application/context/measure.js.map +1 -0
  17. package/dist/application/context/plan-service.js +177 -0
  18. package/dist/application/context/plan-service.js.map +1 -0
  19. package/dist/application/decisiones-service.js +5 -5
  20. package/dist/application/decisiones-service.js.map +1 -1
  21. package/dist/application/export-service.js +250 -0
  22. package/dist/application/export-service.js.map +1 -0
  23. package/dist/application/fix-git-service.js +244 -0
  24. package/dist/application/fix-git-service.js.map +1 -0
  25. package/dist/application/history-update-service.js +35 -24
  26. package/dist/application/history-update-service.js.map +1 -1
  27. package/dist/application/lifecycle-target.js +39 -0
  28. package/dist/application/lifecycle-target.js.map +1 -0
  29. package/dist/application/parsers/spec-relation.js +80 -0
  30. package/dist/application/parsers/spec-relation.js.map +1 -0
  31. package/dist/application/paths-service.js +8 -0
  32. package/dist/application/paths-service.js.map +1 -1
  33. package/dist/application/persist-service.js +285 -0
  34. package/dist/application/persist-service.js.map +1 -0
  35. package/dist/application/release-data/artifacts.js +17 -21
  36. package/dist/application/release-data/artifacts.js.map +1 -1
  37. package/dist/application/resume-service.js +184 -0
  38. package/dist/application/resume-service.js.map +1 -0
  39. package/dist/application/semantic-operation/protocol.js +247 -0
  40. package/dist/application/semantic-operation/protocol.js.map +1 -0
  41. package/dist/application/semantic-operation/publish.js +80 -0
  42. package/dist/application/semantic-operation/publish.js.map +1 -0
  43. package/dist/application/session-binding-service.js +125 -0
  44. package/dist/application/session-binding-service.js.map +1 -0
  45. package/dist/application/session-close-service.js +60 -39
  46. package/dist/application/session-close-service.js.map +1 -1
  47. package/dist/application/session-create-service.js +45 -19
  48. package/dist/application/session-create-service.js.map +1 -1
  49. package/dist/application/session-resolver.js +180 -44
  50. package/dist/application/session-resolver.js.map +1 -1
  51. package/dist/application/session-resume-service.js +39 -9
  52. package/dist/application/session-resume-service.js.map +1 -1
  53. package/dist/application/sessions-service.js +0 -2
  54. package/dist/application/sessions-service.js.map +1 -1
  55. package/dist/application/status-service.js +24 -388
  56. package/dist/application/status-service.js.map +1 -1
  57. package/dist/application/tasks-service.js +5 -5
  58. package/dist/application/tasks-service.js.map +1 -1
  59. package/dist/application/workline-index-service.js +510 -0
  60. package/dist/application/workline-index-service.js.map +1 -0
  61. package/dist/cli/commands/checkpoint-read.js +10 -6
  62. package/dist/cli/commands/checkpoint-read.js.map +1 -1
  63. package/dist/cli/commands/checkpoint-write.js +38 -11
  64. package/dist/cli/commands/checkpoint-write.js.map +1 -1
  65. package/dist/cli/commands/context-budget.js +79 -0
  66. package/dist/cli/commands/context-budget.js.map +1 -0
  67. package/dist/cli/commands/context-plan.js +75 -0
  68. package/dist/cli/commands/context-plan.js.map +1 -0
  69. package/dist/cli/commands/export.js +117 -0
  70. package/dist/cli/commands/export.js.map +1 -0
  71. package/dist/cli/commands/fix-git.js +109 -0
  72. package/dist/cli/commands/fix-git.js.map +1 -0
  73. package/dist/cli/commands/generate-launch.js +35 -3
  74. package/dist/cli/commands/generate-launch.js.map +1 -1
  75. package/dist/cli/commands/history-update.js +1 -1
  76. package/dist/cli/commands/history-update.js.map +1 -1
  77. package/dist/cli/commands/index.js +15 -0
  78. package/dist/cli/commands/index.js.map +1 -1
  79. package/dist/cli/commands/persist.js +67 -0
  80. package/dist/cli/commands/persist.js.map +1 -0
  81. package/dist/cli/commands/resume-summary.js +14 -3
  82. package/dist/cli/commands/resume-summary.js.map +1 -1
  83. package/dist/cli/commands/resume.js +73 -0
  84. package/dist/cli/commands/resume.js.map +1 -0
  85. package/dist/cli/commands/session-artifacts.js +12 -11
  86. package/dist/cli/commands/session-artifacts.js.map +1 -1
  87. package/dist/cli/commands/session-close.js +8 -7
  88. package/dist/cli/commands/session-close.js.map +1 -1
  89. package/dist/cli/commands/session-create.js +5 -1
  90. package/dist/cli/commands/session-create.js.map +1 -1
  91. package/dist/cli/commands/session-resume.js +16 -10
  92. package/dist/cli/commands/session-resume.js.map +1 -1
  93. package/dist/cli/commands/status.js +66 -2
  94. package/dist/cli/commands/status.js.map +1 -1
  95. package/dist/cli/commands/workspace-init.js +21 -2
  96. package/dist/cli/commands/workspace-init.js.map +1 -1
  97. package/dist/cli/context-id.js +133 -0
  98. package/dist/cli/context-id.js.map +1 -0
  99. package/dist/cli/help-groups.js +20 -1
  100. package/dist/cli/help-groups.js.map +1 -1
  101. package/dist/cli/main.js +44 -16
  102. package/dist/cli/main.js.map +1 -1
  103. package/dist/cli/output-mode.js +41 -0
  104. package/dist/cli/output-mode.js.map +1 -0
  105. package/dist/cli/parser.js +10 -0
  106. package/dist/cli/parser.js.map +1 -1
  107. package/dist/cli/registry.js.map +1 -1
  108. package/dist/cli/render.js +53 -0
  109. package/dist/cli/render.js.map +1 -1
  110. package/package.json +1 -1
  111. package/skills/w/SKILL.md +2 -2
  112. package/skills/w/commands/export-diagrams.md +13 -21
  113. package/skills/w/commands/export-manuals.md +15 -21
  114. package/skills/w/commands/export-reports.md +14 -21
  115. package/skills/w/commands/export-scripts.md +14 -21
  116. package/skills/w/commands/fix-git.md +24 -16
  117. package/skills/w/commands/generate-launch.md +13 -32
  118. package/skills/w/commands/persist.md +21 -77
  119. package/skills/w/commands/plan-exec.md +14 -30
  120. package/skills/w/commands/plan-new.md +11 -38
  121. package/skills/w/commands/plan-refine.md +13 -41
  122. package/skills/w/commands/quick.md +13 -20
  123. package/skills/w/commands/resume.md +19 -56
  124. package/skills/w/commands/spec-new.md +28 -69
  125. package/skills/w/commands/spec-refine.md +12 -37
  126. package/skills/w/commands/status.md +12 -55
  127. package/skills/w/commands/workspace-init.md +14 -21
  128. package/skills/w/context/MANIFEST.json +486 -0
  129. package/skills/w/harness/HARNESS.md +1 -1
  130. package/skills/w/hooks/README.md +21 -2
  131. package/skills/w/hooks/hooks.template.json +2 -2
  132. package/skills/w/loops/CHASSIS.md +53 -104
  133. package/skills/w/loops/CODE-POLICIES.md +4 -9
  134. package/skills/w/loops/plan-exec-loop/LOOP.md +5 -12
  135. package/skills/w/loops/plan-new-loop/LOOP.md +8 -32
  136. package/skills/w/loops/plan-refine-loop/LOOP.md +8 -36
  137. package/skills/w/loops/quick-loop/LOOP.md +4 -10
  138. package/skills/w/loops/spec-refine-loop/LOOP.md +7 -49
  139. package/skills/w/modules/ADOPTED-CONTEXT.md +10 -0
  140. package/skills/w/modules/COMPACTION.md +13 -0
  141. package/skills/w/modules/DB-RESEARCH-RULE.md +11 -0
  142. package/skills/w/modules/DB-SCRIPTS-ONLY.md +12 -0
  143. package/skills/w/modules/EXEC-DB-POLICY.md +7 -0
  144. package/skills/w/modules/EXEC-PROBE-TASKS.md +11 -0
  145. package/skills/w/modules/IDEATION-GATE.md +16 -0
  146. package/skills/w/modules/INCREMENTAL-STRATEGY.md +7 -0
  147. package/skills/w/modules/LAUNCH-DETECTION.md +26 -0
  148. package/skills/w/modules/PERSIST-ROUTING.md +16 -0
  149. package/skills/w/modules/PLAN-DESIGN-SPECS.md +12 -0
  150. package/skills/w/modules/PLAN-INPUT.md +26 -0
  151. package/skills/w/modules/PLAN-MODE.md +26 -0
  152. package/skills/w/modules/PLAN-PROBE-TASKS.md +10 -0
  153. package/skills/w/modules/PLAN-REFINE-DESIGN-SPECS.md +7 -0
  154. package/skills/w/modules/PLAN-REFINE-KEYS.md +9 -0
  155. package/skills/w/modules/PLAN-REFINE-SPLIT.md +12 -0
  156. package/skills/w/modules/PLAN-SPLIT-GATE.md +14 -0
  157. package/skills/w/modules/PROBE.md +12 -0
  158. package/skills/w/modules/PROMPT-CONTINUITY.md +13 -0
  159. package/skills/w/modules/RECONNAISSANCE.md +48 -0
  160. package/skills/w/modules/REPLANNING.md +12 -0
  161. package/skills/w/modules/SESSION-NUMBERING.md +19 -0
  162. package/skills/w/modules/SIMULATION-LIFECYCLE.md +11 -0
  163. package/skills/w/modules/SPEC-CHANGE-SHAPE.md +37 -0
  164. package/skills/w/modules/SPEC-REFINE-KEYS.md +14 -0
  165. package/skills/w/modules/SPLIT-GATE.md +42 -0
  166. package/skills/w/modules/WORKSPACE-SCAFFOLD.md +28 -0
  167. package/skills/w/roles/git/ROLE.md +7 -8
  168. package/skills/w/roles/ui-spec/ROLE.md +1 -1
@@ -0,0 +1,247 @@
1
+ import { createHash } from "node:crypto";
2
+ /**
3
+ * The bounded CLI↔AI handshake shared by every hybrid command.
4
+ *
5
+ * The split is the whole point: the CLI owns inventory, numbering, validation,
6
+ * authorization and writing; the AI owns exactly one semantic step —
7
+ * classification, synthesis or intent — and its answer is data to be validated,
8
+ * never an instruction to be trusted.
9
+ *
10
+ * Three stages, and only the third can touch the filesystem:
11
+ *
12
+ * - `prepare` builds a {@link SemanticRequest}: what was read, where writing is
13
+ * allowed, the limits, and an `input_digest` sealing the state it saw.
14
+ * - `validate` parses the answer against that request and, if it survives,
15
+ * returns a preview plus an `approval_digest` over the exact bytes proposed.
16
+ * - `apply` recomputes the input digest, checks the approval still matches, and
17
+ * only then publishes.
18
+ *
19
+ * Validation is manual (DEC-001: no Zod) and **fail-closed**: anything absent,
20
+ * malformed, stale, oversized or outside the allowlist stops before the first
21
+ * write and comes back with a next action.
22
+ */
23
+ export const SEMANTIC_PROTOCOL_VERSION = 1;
24
+ /** Stable SHA-256 of a value: object keys sorted so equal state digests equally. */
25
+ export function semanticDigest(value) {
26
+ return createHash("sha256").update(canonicalJson(value), "utf8").digest("hex");
27
+ }
28
+ function canonicalJson(value) {
29
+ if (value === null || typeof value !== "object")
30
+ return JSON.stringify(value) ?? "null";
31
+ if (Array.isArray(value))
32
+ return `[${value.map(canonicalJson).join(",")}]`;
33
+ const entries = Object.entries(value)
34
+ .filter(([, v]) => v !== undefined)
35
+ .sort(([a], [b]) => a.localeCompare(b))
36
+ .map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`);
37
+ return `{${entries.join(",")}}`;
38
+ }
39
+ export function buildSemanticRequest(input) {
40
+ const request = {
41
+ version: SEMANTIC_PROTOCOL_VERSION,
42
+ operation: input.operation,
43
+ input_digest: semanticDigest(input.inputs),
44
+ contract: input.contract,
45
+ inventory: input.inventory,
46
+ allowed_destinations: input.allowedDestinations,
47
+ limits: input.limits,
48
+ read_set: input.readSet,
49
+ metrics: { request_bytes: 0, read_set_bytes: input.readSetBytes },
50
+ };
51
+ // Measured after the shape is final, then written back: the number describes
52
+ // the payload actually sent, which is what the spec 009 budgets will consume.
53
+ request.metrics.request_bytes = Buffer.byteLength(JSON.stringify(request), "utf8");
54
+ return request;
55
+ }
56
+ /**
57
+ * Parse and validate an answer against the request that produced it. Every
58
+ * rejection names the problem and a next action; none of them writes.
59
+ */
60
+ export function parseSemanticResponse(raw, request) {
61
+ const parsed = parseJson(raw);
62
+ if (!parsed.ok)
63
+ return parsed;
64
+ const envelope = parsed.value;
65
+ const header = checkHeader(envelope, request);
66
+ if (header !== null)
67
+ return { ok: false, failure: header };
68
+ const state = envelope.state;
69
+ if (state === "ambiguous" || state === "unsupported") {
70
+ return {
71
+ ok: false,
72
+ failure: {
73
+ code: state === "ambiguous" ? "SEMANTIC_AMBIGUOUS" : "SEMANTIC_UNSUPPORTED",
74
+ message: envelope.reason ?? `la respuesta se declaró '${state}' sin explicar por qué`,
75
+ action: state === "ambiguous"
76
+ ? "resolvé la ambigüedad y volvé a responder, o acotá la operación"
77
+ : "la operación no aplica a este contenido: no hay nada que escribir",
78
+ },
79
+ };
80
+ }
81
+ const artifacts = checkArtifacts(envelope.artifacts, request);
82
+ if (!artifacts.ok)
83
+ return artifacts;
84
+ return {
85
+ ok: true,
86
+ value: {
87
+ version: SEMANTIC_PROTOCOL_VERSION,
88
+ operation: request.operation,
89
+ input_digest: request.input_digest,
90
+ state: "proposed",
91
+ ...(isRecord(envelope.decisions) ? { decisions: envelope.decisions } : {}),
92
+ artifacts: artifacts.value,
93
+ },
94
+ };
95
+ }
96
+ function parseJson(raw) {
97
+ if (raw.trim().length === 0) {
98
+ return {
99
+ ok: false,
100
+ failure: {
101
+ code: "SEMANTIC_RESPONSE_MISSING",
102
+ message: "no llegó respuesta semántica por stdin",
103
+ action: "volvé a invocar pasando el JSON de respuesta por stdin",
104
+ },
105
+ };
106
+ }
107
+ try {
108
+ return { ok: true, value: JSON.parse(raw) };
109
+ }
110
+ catch {
111
+ return {
112
+ ok: false,
113
+ failure: {
114
+ code: "SEMANTIC_RESPONSE_INVALID",
115
+ message: "la respuesta semántica no es JSON válido",
116
+ action: "reenviá la respuesta como un único objeto JSON completo",
117
+ },
118
+ };
119
+ }
120
+ }
121
+ function checkHeader(envelope, request) {
122
+ if (!isRecord(envelope)) {
123
+ return invalid("la respuesta no es un objeto JSON");
124
+ }
125
+ if (envelope.version !== SEMANTIC_PROTOCOL_VERSION) {
126
+ return invalid(`versión de protocolo no soportada: ${String(envelope.version)}`);
127
+ }
128
+ if (envelope.operation !== request.operation) {
129
+ return invalid(`la respuesta dice operación '${String(envelope.operation)}' y esta es '${request.operation}'`);
130
+ }
131
+ // The staleness seal: the world moved between prepare and this answer, so the
132
+ // inventory, the numbering and the duplicate check it reasoned over are gone.
133
+ if (envelope.input_digest !== request.input_digest) {
134
+ return {
135
+ code: "SEMANTIC_STALE",
136
+ message: "la respuesta responde a un estado anterior del workspace",
137
+ action: "volvé a correr prepare y respondé sobre el request nuevo",
138
+ };
139
+ }
140
+ const state = envelope.state;
141
+ if (state !== "proposed" && state !== "ambiguous" && state !== "unsupported") {
142
+ return invalid(`estado desconocido: ${String(state)}`);
143
+ }
144
+ return null;
145
+ }
146
+ function checkArtifacts(raw, request) {
147
+ if (!Array.isArray(raw) || raw.length === 0) {
148
+ return { ok: false, failure: invalid("una respuesta 'proposed' debe traer artifacts") };
149
+ }
150
+ if (raw.length > request.limits.max_artifacts) {
151
+ return {
152
+ ok: false,
153
+ failure: invalid(`${raw.length} artefactos exceden el máximo de ${request.limits.max_artifacts}`),
154
+ };
155
+ }
156
+ const seen = new Set();
157
+ const out = [];
158
+ for (const entry of raw) {
159
+ if (!isRecord(entry) || typeof entry.path !== "string" || typeof entry.content !== "string") {
160
+ return { ok: false, failure: invalid("cada artefacto necesita 'path' y 'content' de texto") };
161
+ }
162
+ const path = checkPath(entry.path, request.allowed_destinations);
163
+ if (!path.ok)
164
+ return path;
165
+ if (seen.has(path.value)) {
166
+ return { ok: false, failure: invalid(`el artefacto '${path.value}' viene repetido`) };
167
+ }
168
+ const bytes = Buffer.byteLength(entry.content, "utf8");
169
+ if (bytes > request.limits.max_artifact_bytes) {
170
+ return {
171
+ ok: false,
172
+ failure: invalid(`'${path.value}' pesa ${bytes} B y el máximo es ${request.limits.max_artifact_bytes} B`),
173
+ };
174
+ }
175
+ seen.add(path.value);
176
+ out.push({ path: path.value, content: entry.content });
177
+ }
178
+ return { ok: true, value: out };
179
+ }
180
+ /**
181
+ * A destination is only legal if it is workspace-relative and lands INSIDE one
182
+ * of the declared directories. Absolute paths, `..`, backslashes and bare
183
+ * prefix matches (`docs/specs-evil`) are all rejected — the allowlist is the
184
+ * write boundary, so it is checked on normalized segments, never on a string
185
+ * `startsWith`.
186
+ */
187
+ function checkPath(raw, allowed) {
188
+ const path = raw.trim();
189
+ const reject = (why) => ({
190
+ ok: false,
191
+ failure: {
192
+ code: "SEMANTIC_PATH_REJECTED",
193
+ message: `destino no permitido ('${raw}'): ${why}`,
194
+ action: `escribí solo dentro de: ${allowed.join(", ")}`,
195
+ },
196
+ });
197
+ if (path.length === 0)
198
+ return reject("está vacío");
199
+ if (path.includes("\\"))
200
+ return reject("usa separador de Windows");
201
+ if (path.startsWith("/") || /^[A-Za-z]:/.test(path))
202
+ return reject("es absoluto");
203
+ const segments = path.split("/");
204
+ if (segments.some((s) => s === ".." || s === "." || s.length === 0)) {
205
+ return reject("contiene segmentos relativos o vacíos");
206
+ }
207
+ // A destination is either a directory to write INSIDE (persist, exports) or an
208
+ // exact file already identified as writable (fix-git's conflict set). Both are
209
+ // compared on segments, so `docs/research-evil` never passes as `docs/research`.
210
+ const inside = allowed.some((dest) => {
211
+ const destSegments = dest.split("/").filter((s) => s.length > 0);
212
+ if (segments.length < destSegments.length)
213
+ return false;
214
+ if (!destSegments.every((segment, i) => segments[i] === segment))
215
+ return false;
216
+ return segments.length > destSegments.length || path === dest;
217
+ });
218
+ if (!inside)
219
+ return reject("cae fuera de los destinos declarados");
220
+ return { ok: true, value: path };
221
+ }
222
+ /**
223
+ * Seal over the exact artifacts shown to the human. `apply` refuses anything
224
+ * whose digest differs, so what gets approved is what gets written — not a
225
+ * later edit of the same proposal.
226
+ */
227
+ export function approvalDigest(response) {
228
+ return semanticDigest({
229
+ operation: response.operation,
230
+ input_digest: response.input_digest,
231
+ artifacts: (response.artifacts ?? []).map((a) => ({
232
+ path: a.path,
233
+ content_digest: semanticDigest(a.content),
234
+ })),
235
+ });
236
+ }
237
+ function invalid(message) {
238
+ return {
239
+ code: "SEMANTIC_RESPONSE_INVALID",
240
+ message,
241
+ action: "corregí la respuesta según el 'contract' del request y reenviala",
242
+ };
243
+ }
244
+ function isRecord(value) {
245
+ return typeof value === "object" && value !== null && !Array.isArray(value);
246
+ }
247
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../src/application/semantic-operation/protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import { dirname, join } from "node:path";
2
+ export async function publishArtifacts(fs, root, artifacts, options = {}) {
3
+ const done = [];
4
+ for (const artifact of artifacts) {
5
+ const absolute = join(root, artifact.path);
6
+ const failure = await writeOne(fs, absolute, artifact, options, done);
7
+ if (failure !== null) {
8
+ await rollback(fs, done);
9
+ return { ok: false, failure };
10
+ }
11
+ }
12
+ return { ok: true, value: { written: artifacts.map((a) => a.path) } };
13
+ }
14
+ async function writeOne(fs, absolute, artifact, options, done) {
15
+ try {
16
+ await fs.mkdirp(dirname(absolute));
17
+ const previous = await readPrevious(fs, absolute);
18
+ if (previous !== null && options.overwrite !== true) {
19
+ return {
20
+ code: "PUBLISH_TARGET_EXISTS",
21
+ message: `'${artifact.path}' ya existe y no se autorizó sobrescribir`,
22
+ action: "confirmá la sobrescritura explícitamente, o publicá en otro destino",
23
+ };
24
+ }
25
+ if (previous === null) {
26
+ // Exclusive create closes the check-then-write window: a concurrent run
27
+ // that got there first loses here, not silently.
28
+ const { created } = await fs.writeTextExclusive(absolute, artifact.content);
29
+ if (!created) {
30
+ return {
31
+ code: "PUBLISH_TARGET_EXISTS",
32
+ message: `'${artifact.path}' fue creado por otro proceso durante la publicación`,
33
+ action: "volvé a correr prepare: el inventario y la numeración cambiaron",
34
+ };
35
+ }
36
+ }
37
+ else {
38
+ await fs.writeText(absolute, artifact.content);
39
+ }
40
+ done.push({ absolute, previous });
41
+ return null;
42
+ }
43
+ catch (err) {
44
+ return {
45
+ code: "PUBLISH_FAILED",
46
+ message: `no se pudo escribir '${artifact.path}': ${errorText(err)}`,
47
+ action: "revisá permisos y espacio en disco, y volvé a intentar",
48
+ };
49
+ }
50
+ }
51
+ async function readPrevious(fs, absolute) {
52
+ if (!(await fs.exists(absolute)))
53
+ return null;
54
+ try {
55
+ return await fs.readText(absolute);
56
+ }
57
+ catch {
58
+ // Unreadable but present: treat it as existing so we never clobber blindly,
59
+ // and as unrestorable so a rollback leaves it exactly as it was found.
60
+ return "";
61
+ }
62
+ }
63
+ /** Undo in reverse order, best effort — a failed undo must not mask the cause. */
64
+ async function rollback(fs, done) {
65
+ for (const entry of [...done].reverse()) {
66
+ try {
67
+ if (entry.previous === null)
68
+ await fs.remove(entry.absolute);
69
+ else
70
+ await fs.writeText(entry.absolute, entry.previous);
71
+ }
72
+ catch {
73
+ // ignore; the original failure is what the caller reports
74
+ }
75
+ }
76
+ }
77
+ function errorText(err) {
78
+ return err instanceof Error ? err.message : String(err);
79
+ }
80
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../../src/application/semantic-operation/publish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ import { createHash } from "node:crypto";
2
+ /**
3
+ * Durable conversation→session association.
4
+ *
5
+ * The registry lives at `.workflow/sessions/.bindings.json` — machine-local
6
+ * state, gitignored along with the sessions dir. Keys are the SHA-256 of the
7
+ * host's opaque conversation id (the raw id is NEVER persisted); values are
8
+ * canonical session folder names.
9
+ *
10
+ * Every function here is **lock-free**: the caller owns the workspace lock so
11
+ * one operation = one lock boundary (no nested acquisition). Reads are safe
12
+ * without the lock because `writeText` renames atomically onto the path.
13
+ *
14
+ * Validation is manual (DEC-001: no Zod) and **fail-closed**: an unreadable,
15
+ * malformed or unknown-version registry is reported as invalid and never
16
+ * overwritten — repairing it automatically would silently drop associations.
17
+ */
18
+ /** Only this schema version is accepted. */
19
+ export const BINDINGS_VERSION = 1;
20
+ /** SHA-256 of the opaque conversation id — the only form that reaches disk. */
21
+ export function hashContextId(contextId) {
22
+ return createHash("sha256").update(contextId, "utf8").digest("hex");
23
+ }
24
+ function parseBindingRegistry(raw) {
25
+ if (raw.trim().length === 0)
26
+ return { ok: true, registry: emptyRegistry() };
27
+ let parsed;
28
+ try {
29
+ parsed = JSON.parse(raw);
30
+ }
31
+ catch {
32
+ return { ok: false, reason: "el registro de bindings no es JSON válido" };
33
+ }
34
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
35
+ return { ok: false, reason: "el registro de bindings no es un objeto JSON" };
36
+ }
37
+ const { version, bindings } = parsed;
38
+ if (version !== BINDINGS_VERSION) {
39
+ return { ok: false, reason: `versión de registro no soportada: ${String(version)}` };
40
+ }
41
+ if (typeof bindings !== "object" || bindings === null || Array.isArray(bindings)) {
42
+ return { ok: false, reason: "el campo 'bindings' no es un mapa" };
43
+ }
44
+ const entries = {};
45
+ for (const [key, value] of Object.entries(bindings)) {
46
+ if (key.length === 0 || typeof value !== "string" || value.length === 0) {
47
+ return { ok: false, reason: `entrada de binding inválida en la clave '${key}'` };
48
+ }
49
+ entries[key] = value;
50
+ }
51
+ return { ok: true, registry: { version: BINDINGS_VERSION, bindings: entries } };
52
+ }
53
+ export async function readBindingRegistry(fs, paths) {
54
+ const path = paths.cwdSessionBindingsFile();
55
+ if (!(await fs.exists(path)))
56
+ return { ok: true, registry: emptyRegistry() };
57
+ let raw;
58
+ try {
59
+ raw = await fs.readText(path);
60
+ }
61
+ catch {
62
+ return { ok: false, reason: `no se pudo leer el registro de bindings (${path})` };
63
+ }
64
+ return parseBindingRegistry(raw);
65
+ }
66
+ /** Which session this conversation is associated with, if any. */
67
+ export async function lookupBinding(fs, paths, contextId) {
68
+ const read = await readBindingRegistry(fs, paths);
69
+ if (!read.ok)
70
+ return { status: "invalid", reason: read.reason };
71
+ const folder = read.registry.bindings[hashContextId(contextId)];
72
+ return folder === undefined ? { status: "unbound" } : { status: "bound", folder };
73
+ }
74
+ /**
75
+ * Associate this conversation with `folder`, replacing only its own entry.
76
+ * `changed: false` when the association already pointed there (no write).
77
+ */
78
+ export async function bindContextToSession(fs, paths, contextId, folder) {
79
+ const read = await readBindingRegistry(fs, paths);
80
+ if (!read.ok)
81
+ return { ok: false, reason: read.reason };
82
+ const key = hashContextId(contextId);
83
+ if (read.registry.bindings[key] === folder)
84
+ return { ok: true, changed: false };
85
+ const bindings = { ...read.registry.bindings, [key]: folder };
86
+ await writeBindingRegistry(fs, paths, bindings);
87
+ return { ok: true, changed: true };
88
+ }
89
+ /**
90
+ * Drop every association pointing at `folder` (session closed). Other
91
+ * conversations keep theirs — a closed session never redirects to another line.
92
+ */
93
+ export async function invalidateBindingsTo(fs, paths, folder) {
94
+ const read = await readBindingRegistry(fs, paths);
95
+ if (!read.ok)
96
+ return { ok: false, reason: read.reason };
97
+ const kept = {};
98
+ let removed = 0;
99
+ for (const [key, value] of Object.entries(read.registry.bindings)) {
100
+ if (value === folder)
101
+ removed += 1;
102
+ else
103
+ kept[key] = value;
104
+ }
105
+ if (removed > 0)
106
+ await writeBindingRegistry(fs, paths, kept);
107
+ return { ok: true, removed };
108
+ }
109
+ function emptyRegistry() {
110
+ return { version: BINDINGS_VERSION, bindings: {} };
111
+ }
112
+ async function writeBindingRegistry(fs, paths, bindings) {
113
+ // Keys sorted so the file is byte-stable across runs regardless of insertion
114
+ // order (diffable, golden-friendly).
115
+ const sorted = {};
116
+ for (const key of Object.keys(bindings).sort()) {
117
+ const value = bindings[key];
118
+ if (value !== undefined)
119
+ sorted[key] = value;
120
+ }
121
+ const payload = { version: BINDINGS_VERSION, bindings: sorted };
122
+ await fs.mkdirp(paths.cwdSessionsDir());
123
+ await fs.writeText(paths.cwdSessionBindingsFile(), `${JSON.stringify(payload, null, 2)}\n`);
124
+ }
125
+ //# sourceMappingURL=session-binding-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-binding-service.js","sourceRoot":"","sources":["../../src/application/session-binding-service.ts"],"names":[],"mappings":"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"}
@@ -1,55 +1,76 @@
1
1
  import { join } from "node:path";
2
- import { runHistoryUpdate } from "./history-update-service.js";
2
+ import { historyFields, upsertHistoryRow } from "./history-update-service.js";
3
+ import { withCwdLock } from "./lock-service.js";
3
4
  import { canonicalArtifactPath } from "./session-artifacts.js";
4
- import { CLOSED_MARKER, resolveSession } from "./session-resolver.js";
5
- export async function runSessionClose(fs, env, paths, input) {
5
+ import { invalidateBindingsTo } from "./session-binding-service.js";
6
+ import { CLOSED_MARKER, resolveSessionTarget, } from "./session-resolver.js";
7
+ export async function runSessionClose(fs, paths, input) {
8
+ // Closing is destructive to continuity: it always names its target. Falling
9
+ // back to "the sole active one" would let a conversation close a line it
10
+ // never selected.
6
11
  if (!input.code)
7
12
  return { error: "--code es obligatorio" };
8
- const session = await resolveSession(fs, env, paths, input.code, true);
9
- if (!session)
10
- return { error: `Sesión no encontrada: ${input.code}` };
11
- // Persist the durable artifacts in the session folder (they survive close).
12
- // CHECKPOINT is a resume safety net (no-op when the loop already wrote one).
13
- // BACKLOG is NOT fabricated here: the owning loop writes a real BACKLOG.md
14
- // only when there is deferred/followup content, so close no longer creates
15
- // an empty boilerplate file. `backlog_path` still reports the canonical path.
13
+ const resolution = await resolveSessionTarget(fs, paths, { code: input.code, allowClosed: true });
14
+ if (resolution.outcome !== "resolved")
15
+ return { sessionError: resolution };
16
+ const session = resolution.session;
17
+ // Durable artifacts survive close. CHECKPOINT is a resume safety net (no-op
18
+ // when the loop already wrote one). BACKLOG is NOT fabricated: the owning loop
19
+ // writes it only when there is deferred content; `backlog_path` still reports
20
+ // the canonical path.
16
21
  const checkpointPath = canonicalArtifactPath(session.path, "checkpoint");
17
- const backlogPath = canonicalArtifactPath(session.path, "backlog");
18
22
  await ensureFile(fs, checkpointPath, "# CHECKPOINT\n");
19
- // Mark the session closed via the folder-local sentinel file.
20
- // Sessions are internal/light: closing does not touch the project block.
21
- await fs.writeText(join(session.path, CLOSED_MARKER), "");
23
+ const refs = input.refs?.trim();
24
+ const closure = await closeUnderLock(fs, paths, session, {
25
+ code: session.code ?? input.code,
26
+ ...(refs !== undefined && refs.length > 0 ? { refs } : {}),
27
+ });
28
+ if ("error" in closure)
29
+ return closure;
22
30
  const sessionClose = {
23
- code: session.code ?? input.code ?? "",
31
+ code: session.code ?? input.code,
24
32
  folder: session.folder,
25
33
  closed: true,
26
34
  checkpoint_path: checkpointPath,
27
- backlog_path: backlogPath,
35
+ backlog_path: canonicalArtifactPath(session.path, "backlog"),
36
+ ...(refs !== undefined && refs.length > 0 ? { refs } : {}),
37
+ bindings_invalidated: closure.bindings_invalidated,
38
+ ...(closure.history ? { history: closure.history } : {}),
39
+ ...(closure.history_error !== undefined ? { history_error: closure.history_error } : {}),
28
40
  };
29
- if (input.refs && input.refs.trim().length > 0) {
30
- sessionClose.refs = input.refs.trim();
31
- }
32
- // Sessions are gitignored (machine-local live log); HISTORY.md is the durable,
33
- // committable record close upserts its row here so it actually gets written
34
- // (doctrine-only wiring proved dead: nothing ever called `aw history-update`).
35
- // Non-fatal: a busy lock or a write failure never blocks closing.
36
- try {
37
- const history = await runHistoryUpdate(fs, env, paths, {
38
- code: sessionClose.code,
39
- state: "closed",
40
- ...(sessionClose.refs !== undefined ? { refs: sessionClose.refs } : {}),
41
- });
42
- if ("error" in history) {
43
- sessionClose.history_error = history.error;
41
+ return { sessionClose };
42
+ }
43
+ /**
44
+ * The whole shared-state mutation of a close, under ONE lock acquisition:
45
+ * invalidate the associations pointing here, write the `.closed` marker, upsert
46
+ * the HISTORY row. HISTORY goes through the lock-free primitive on purpose —
47
+ * its public command takes the lock itself, and nesting would deadlock.
48
+ *
49
+ * The registry goes FIRST: if it cannot be read, the close aborts having
50
+ * mutated nothing, rather than leaving a closed session that conversations are
51
+ * still associated with.
52
+ */
53
+ async function closeUnderLock(fs, paths, session, row) {
54
+ const result = await withCwdLock(fs, paths, async () => {
55
+ const invalidated = await invalidateBindingsTo(fs, paths, session.folder);
56
+ if (!invalidated.ok) {
57
+ return { ok: false, failure: { error: invalidated.reason, code: "SESSION_BINDING_INVALID" } };
44
58
  }
45
- else {
46
- sessionClose.history = { action: history.action, state: history.state };
59
+ await fs.writeText(join(session.path, CLOSED_MARKER), "");
60
+ const closure = { bindings_invalidated: invalidated.removed };
61
+ try {
62
+ const history = await upsertHistoryRow(fs, paths, historyFields({ ...row, state: "closed" }, session, row.code));
63
+ closure.history = { action: history.action, state: history.state };
47
64
  }
48
- }
49
- catch (err) {
50
- sessionClose.history_error = err instanceof Error ? err.message : String(err);
51
- }
52
- return { sessionClose };
65
+ catch (err) {
66
+ // Non-fatal, as before: the caller re-runs `aw history-update` on this.
67
+ closure.history_error = err instanceof Error ? err.message : String(err);
68
+ }
69
+ return { ok: true, closure };
70
+ });
71
+ if ("error" in result)
72
+ return { error: result.error, code: "LOCK_BUSY" };
73
+ return result.ok ? result.closure : result.failure;
53
74
  }
54
75
  async function ensureFile(fs, path, defaultContent) {
55
76
  if (await fs.exists(path))
@@ -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":"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"}