@tacuchi/agent-workflow-cli 20.21.0 → 20.23.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/README.md +17 -6
- package/dist/adapters/git-cli.js +42 -0
- package/dist/adapters/git-cli.js.map +1 -1
- package/dist/application/artifacts-service.js +5 -5
- package/dist/application/artifacts-service.js.map +1 -1
- package/dist/application/checkpoint-service.js +60 -55
- package/dist/application/checkpoint-service.js.map +1 -1
- package/dist/application/checkpoint-write-service.js +61 -66
- package/dist/application/checkpoint-write-service.js.map +1 -1
- package/dist/application/decisiones-service.js +5 -5
- package/dist/application/decisiones-service.js.map +1 -1
- package/dist/application/export-service.js +250 -0
- package/dist/application/export-service.js.map +1 -0
- package/dist/application/fix-git-service.js +244 -0
- package/dist/application/fix-git-service.js.map +1 -0
- package/dist/application/history-update-service.js +35 -24
- package/dist/application/history-update-service.js.map +1 -1
- package/dist/application/lifecycle-target.js +39 -0
- package/dist/application/lifecycle-target.js.map +1 -0
- package/dist/application/markdown.js +61 -16
- package/dist/application/markdown.js.map +1 -1
- package/dist/application/parsers/phases.js +38 -45
- package/dist/application/parsers/phases.js.map +1 -1
- package/dist/application/parsers/plan-status.js +75 -0
- package/dist/application/parsers/plan-status.js.map +1 -0
- package/dist/application/parsers/spec-relation.js +80 -0
- package/dist/application/parsers/spec-relation.js.map +1 -0
- package/dist/application/paths-service.js +8 -0
- package/dist/application/paths-service.js.map +1 -1
- package/dist/application/persist-service.js +285 -0
- package/dist/application/persist-service.js.map +1 -0
- package/dist/application/release-data/artifacts.js +17 -21
- package/dist/application/release-data/artifacts.js.map +1 -1
- package/dist/application/resume-service.js +184 -0
- package/dist/application/resume-service.js.map +1 -0
- package/dist/application/semantic-operation/protocol.js +247 -0
- package/dist/application/semantic-operation/protocol.js.map +1 -0
- package/dist/application/semantic-operation/publish.js +80 -0
- package/dist/application/semantic-operation/publish.js.map +1 -0
- package/dist/application/session-binding-service.js +125 -0
- package/dist/application/session-binding-service.js.map +1 -0
- package/dist/application/session-close-service.js +60 -39
- package/dist/application/session-close-service.js.map +1 -1
- package/dist/application/session-create-service.js +45 -19
- package/dist/application/session-create-service.js.map +1 -1
- package/dist/application/session-resolver.js +180 -44
- package/dist/application/session-resolver.js.map +1 -1
- package/dist/application/session-resume-service.js +39 -9
- package/dist/application/session-resume-service.js.map +1 -1
- package/dist/application/sessions-service.js +0 -2
- package/dist/application/sessions-service.js.map +1 -1
- package/dist/application/status-service.js +24 -352
- package/dist/application/status-service.js.map +1 -1
- package/dist/application/tasks-service.js +5 -5
- package/dist/application/tasks-service.js.map +1 -1
- package/dist/application/workline-index-service.js +510 -0
- package/dist/application/workline-index-service.js.map +1 -0
- package/dist/cli/commands/checkpoint-read.js +10 -6
- package/dist/cli/commands/checkpoint-read.js.map +1 -1
- package/dist/cli/commands/checkpoint-write.js +38 -11
- package/dist/cli/commands/checkpoint-write.js.map +1 -1
- package/dist/cli/commands/export.js +117 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/fix-git.js +109 -0
- package/dist/cli/commands/fix-git.js.map +1 -0
- package/dist/cli/commands/generate-launch.js +35 -3
- package/dist/cli/commands/generate-launch.js.map +1 -1
- package/dist/cli/commands/history-update.js +1 -1
- package/dist/cli/commands/history-update.js.map +1 -1
- package/dist/cli/commands/index.js +11 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/persist.js +67 -0
- package/dist/cli/commands/persist.js.map +1 -0
- package/dist/cli/commands/resume-summary.js +14 -3
- package/dist/cli/commands/resume-summary.js.map +1 -1
- package/dist/cli/commands/resume.js +73 -0
- package/dist/cli/commands/resume.js.map +1 -0
- package/dist/cli/commands/session-artifacts.js +12 -11
- package/dist/cli/commands/session-artifacts.js.map +1 -1
- package/dist/cli/commands/session-close.js +8 -7
- package/dist/cli/commands/session-close.js.map +1 -1
- package/dist/cli/commands/session-create.js +5 -1
- package/dist/cli/commands/session-create.js.map +1 -1
- package/dist/cli/commands/session-resume.js +16 -10
- package/dist/cli/commands/session-resume.js.map +1 -1
- package/dist/cli/commands/status.js +66 -2
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/workspace-init.js +21 -2
- package/dist/cli/commands/workspace-init.js.map +1 -1
- package/dist/cli/context-id.js +133 -0
- package/dist/cli/context-id.js.map +1 -0
- package/dist/cli/help-groups.js +16 -1
- package/dist/cli/help-groups.js.map +1 -1
- package/dist/cli/main.js +44 -16
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/output-mode.js +41 -0
- package/dist/cli/output-mode.js.map +1 -0
- package/dist/cli/parser.js +6 -0
- package/dist/cli/parser.js.map +1 -1
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli/render.js +53 -0
- package/dist/cli/render.js.map +1 -1
- package/package.json +1 -1
- package/skills/w/SKILL.md +3 -1
- package/skills/w/commands/export-diagrams.md +19 -10
- package/skills/w/commands/export-manuals.md +20 -10
- package/skills/w/commands/export-reports.md +20 -11
- package/skills/w/commands/export-scripts.md +20 -10
- package/skills/w/commands/fix-git.md +31 -12
- package/skills/w/commands/generate-launch.md +1 -1
- package/skills/w/commands/persist.md +33 -68
- package/skills/w/commands/plan-new.md +1 -1
- package/skills/w/commands/resume.md +25 -41
- package/skills/w/commands/spec-refine.md +12 -0
- package/skills/w/commands/status.md +12 -40
- package/skills/w/commands/workspace-init.md +3 -3
- package/skills/w/hooks/README.md +21 -2
- package/skills/w/hooks/hooks.template.json +2 -2
- package/skills/w/loops/README.md +5 -3
- package/skills/w/loops/plan-exec-loop/LOOP.md +10 -5
- package/skills/w/loops/plan-new-loop/LOOP.md +17 -8
- package/skills/w/loops/plan-refine-loop/LOOP.md +3 -1
- package/skills/w/loops/spec-refine-loop/LOOP.md +20 -7
- package/skills/w/roles/git/ROLE.md +7 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decisiones-service.js","sourceRoot":"","sources":["../../src/application/decisiones-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/E,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,
|
|
1
|
+
{"version":3,"file":"decisiones-service.js","sourceRoot":"","sources":["../../src/application/decisiones-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/E,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAEL,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAqB/B,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,EAAkB,EAClB,GAAY,EACZ,KAAmB,EACnB,KAA6B;IAE7B,MAAM,UAAU,GAAG,MAAM,oBAAoB,CAAC,EAAE,EAAE,KAAK,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IACpF,IAAI,UAAU,CAAC,OAAO,KAAK,UAAU;QAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3E,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;IAClE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,MAAM;YACvB,IAAI,EAAE,OAAO,CAAC,qBAAqB,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;YAC1E,MAAM,EAAE,KAAK;YACb,KAAK,EAAE,CAAC;YACR,KAAK,EAAE,EAAE;SACV,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACzD,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,MAAM;QACvB,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,KAAK;KACN,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { localDateIso } from "./dates.js";
|
|
2
|
+
import { runNextNumber } from "./dev-only-services.js";
|
|
3
|
+
import { withCwdLock } from "./lock-service.js";
|
|
4
|
+
import { runReleaseData } from "./release-data-service.js";
|
|
5
|
+
import { approvalDigest, buildSemanticRequest, parseSemanticResponse, } from "./semantic-operation/protocol.js";
|
|
6
|
+
import { publishArtifacts } from "./semantic-operation/publish.js";
|
|
7
|
+
const POLICIES = {
|
|
8
|
+
diagrams: {
|
|
9
|
+
dir: "docs/diagrams",
|
|
10
|
+
shape: "dossier",
|
|
11
|
+
required: ["README.md"],
|
|
12
|
+
extensions: [".md", ".dsl", ".puml", ".mmd"],
|
|
13
|
+
contract: "Un dossier con README.md obligatorio, los diagramas en Markdown y, opcionalmente, su DSL (.dsl/.puml/.mmd).",
|
|
14
|
+
},
|
|
15
|
+
manuals: {
|
|
16
|
+
dir: "docs/manuals",
|
|
17
|
+
shape: "dossier",
|
|
18
|
+
required: ["README.md"],
|
|
19
|
+
extensions: [".md"],
|
|
20
|
+
// The only file an export may replace, and only with an explicit approval.
|
|
21
|
+
overwritable: "docs/manuals/INDEX.md",
|
|
22
|
+
contract: "Un dossier con README.md obligatorio y los manuales en Markdown. Podés incluir docs/manuals/INDEX.md para actualizar el índice: es el ÚNICO archivo sobrescribible y exige aprobación explícita.",
|
|
23
|
+
},
|
|
24
|
+
reports: {
|
|
25
|
+
dir: "docs/reports",
|
|
26
|
+
shape: "document",
|
|
27
|
+
required: [],
|
|
28
|
+
extensions: [".md"],
|
|
29
|
+
contract: "UN informe en Markdown que declare su audiencia y su acotación en las primeras líneas.",
|
|
30
|
+
},
|
|
31
|
+
scripts: {
|
|
32
|
+
dir: "docs/scripts",
|
|
33
|
+
shape: "dossier",
|
|
34
|
+
required: ["00-ROLLBACK.sql", "README.md"],
|
|
35
|
+
extensions: [".sql", ".md"],
|
|
36
|
+
contract: "Un dossier con 00-ROLLBACK.sql y README.md obligatorios, más los forwards NN-<nombre>.sql numerados de forma continua desde 01. El CLI NUNCA ejecuta SQL.",
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
const LIMITS = { max_artifacts: 64, max_artifact_bytes: 512 * 1024 };
|
|
40
|
+
const FORWARD_RE = /^(\d{2})-[^/]+\.sql$/;
|
|
41
|
+
// ── prepare ──────────────────────────────────────────────────────────────────
|
|
42
|
+
export async function prepareExport(fs, env, paths, category, selection = {}) {
|
|
43
|
+
const policy = POLICIES[category];
|
|
44
|
+
const corpus = await readCorpus(fs, env, paths, selection);
|
|
45
|
+
if ("error" in corpus) {
|
|
46
|
+
return {
|
|
47
|
+
ok: false,
|
|
48
|
+
failure: {
|
|
49
|
+
code: "EXPORT_CORPUS_UNAVAILABLE",
|
|
50
|
+
message: corpus.error,
|
|
51
|
+
action: "revisá el workspace y los filtros --sessions/--since/--source",
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (corpus.sessions.length === 0) {
|
|
56
|
+
return {
|
|
57
|
+
ok: false,
|
|
58
|
+
failure: {
|
|
59
|
+
code: "EXPORT_CORPUS_EMPTY",
|
|
60
|
+
message: "ninguna sesión coincide con los filtros",
|
|
61
|
+
action: "ampliá --since, quitá --sessions, o revisá que existan sesiones cerradas",
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const next = (await runNextNumber(fs, env, { directory: policy.dir, dryRun: true })).next;
|
|
66
|
+
const date = selection.date ?? localDateIso(new Date());
|
|
67
|
+
const unit = policy.shape === "dossier" ? `${policy.dir}/${next}-export-${category}-${date}` : policy.dir;
|
|
68
|
+
const inventory = {
|
|
69
|
+
category,
|
|
70
|
+
destination: unit,
|
|
71
|
+
shape: policy.shape,
|
|
72
|
+
required: policy.required,
|
|
73
|
+
extensions: policy.extensions,
|
|
74
|
+
overwritable: policy.overwritable ?? null,
|
|
75
|
+
sessions: corpus.sessions,
|
|
76
|
+
date,
|
|
77
|
+
};
|
|
78
|
+
const readSet = corpus.sessions.map((s) => s.path ?? s.folder);
|
|
79
|
+
const request = buildSemanticRequest({
|
|
80
|
+
operation: `export-${category}`,
|
|
81
|
+
// The corpus seals the request: a session appearing or closing between
|
|
82
|
+
// prepare and apply changes what the dossier should have contained.
|
|
83
|
+
inputs: { corpus: corpus.sessions, next, date },
|
|
84
|
+
contract: `${policy.contract} Respondé artifacts con paths dentro de ${unit}${policy.overwritable ? ` (o exactamente ${policy.overwritable})` : ""}. El NNN es consultivo: el CLI reasigna el número dentro del lock.`,
|
|
85
|
+
inventory,
|
|
86
|
+
allowedDestinations: [unit, ...(policy.overwritable ? [policy.overwritable] : [])],
|
|
87
|
+
limits: LIMITS,
|
|
88
|
+
readSet,
|
|
89
|
+
readSetBytes: readSet.length,
|
|
90
|
+
});
|
|
91
|
+
return { ok: true, value: { category, request, next, unit } };
|
|
92
|
+
}
|
|
93
|
+
async function readCorpus(fs, env, paths, selection) {
|
|
94
|
+
const input = {
|
|
95
|
+
includeClosed: true,
|
|
96
|
+
// Graduated bundles are previous exports: re-exporting them would duplicate
|
|
97
|
+
// what already lives in docs/.
|
|
98
|
+
includeGraduated: false,
|
|
99
|
+
...(selection.sessions !== undefined ? { sessions: selection.sessions } : {}),
|
|
100
|
+
...(selection.since !== undefined ? { since: selection.since } : {}),
|
|
101
|
+
...(selection.source !== undefined ? { sourceAlias: selection.source } : {}),
|
|
102
|
+
};
|
|
103
|
+
const data = await runReleaseData(fs, env, paths, input);
|
|
104
|
+
if ("error" in data)
|
|
105
|
+
return { error: data.error };
|
|
106
|
+
return { sessions: data.sessions };
|
|
107
|
+
}
|
|
108
|
+
// ── validate ─────────────────────────────────────────────────────────────────
|
|
109
|
+
export function validateExport(raw, prepared) {
|
|
110
|
+
const parsed = parseSemanticResponse(raw, prepared.request);
|
|
111
|
+
if (!parsed.ok)
|
|
112
|
+
return parsed;
|
|
113
|
+
const policy = POLICIES[prepared.category];
|
|
114
|
+
const artifacts = parsed.value.artifacts ?? [];
|
|
115
|
+
const inUnit = artifacts.filter((a) => a.path !== policy.overwritable);
|
|
116
|
+
const overwrites = artifacts.some((a) => a.path === policy.overwritable)
|
|
117
|
+
? (policy.overwritable ?? null)
|
|
118
|
+
: null;
|
|
119
|
+
const shape = checkShape(inUnit, policy, prepared.unit);
|
|
120
|
+
if (shape !== null)
|
|
121
|
+
return { ok: false, failure: shape };
|
|
122
|
+
return {
|
|
123
|
+
ok: true,
|
|
124
|
+
value: {
|
|
125
|
+
preview: {
|
|
126
|
+
category: prepared.category,
|
|
127
|
+
destination: prepared.unit,
|
|
128
|
+
files: artifacts.map((a) => ({
|
|
129
|
+
path: a.path,
|
|
130
|
+
bytes: Buffer.byteLength(a.content, "utf8"),
|
|
131
|
+
})),
|
|
132
|
+
overwrites,
|
|
133
|
+
},
|
|
134
|
+
approval_digest: approvalDigest(parsed.value),
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function checkShape(artifacts, policy, unit) {
|
|
139
|
+
if (artifacts.length === 0)
|
|
140
|
+
return reject("la propuesta no trae ningún artefacto del dossier");
|
|
141
|
+
if (policy.shape === "document" && artifacts.length > 1) {
|
|
142
|
+
return reject(`esta categoría publica UN documento y llegaron ${artifacts.length}`);
|
|
143
|
+
}
|
|
144
|
+
const names = artifacts.map((a) => a.path.slice(unit.length + 1));
|
|
145
|
+
for (const artifact of artifacts) {
|
|
146
|
+
if (!policy.extensions.some((ext) => artifact.path.endsWith(ext))) {
|
|
147
|
+
return reject(`'${artifact.path}' no usa una extensión permitida (${policy.extensions.join(", ")})`);
|
|
148
|
+
}
|
|
149
|
+
if (artifact.content.trim().length === 0) {
|
|
150
|
+
return reject(`'${artifact.path}' está vacío`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
for (const required of policy.required) {
|
|
154
|
+
if (!names.includes(required))
|
|
155
|
+
return reject(`falta '${required}' en el dossier`);
|
|
156
|
+
}
|
|
157
|
+
return policy.required.includes("00-ROLLBACK.sql") ? checkForwards(names) : null;
|
|
158
|
+
}
|
|
159
|
+
/** Forwards numbered continuously from 01 — a gap makes the apply order unreadable. */
|
|
160
|
+
function checkForwards(names) {
|
|
161
|
+
const forwards = names
|
|
162
|
+
.map((name) => FORWARD_RE.exec(name)?.[1])
|
|
163
|
+
.filter((n) => n !== undefined && n !== "00")
|
|
164
|
+
.map((n) => Number.parseInt(n, 10))
|
|
165
|
+
.sort((a, b) => a - b);
|
|
166
|
+
if (forwards.length === 0)
|
|
167
|
+
return reject("el bundle no trae ningún forward NN-<nombre>.sql");
|
|
168
|
+
for (let i = 0; i < forwards.length; i++) {
|
|
169
|
+
if (forwards[i] !== i + 1) {
|
|
170
|
+
return reject(`la numeración de forwards no es continua desde 01: ${forwards.join(", ")}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
export async function applyExport(fs, env, paths, input) {
|
|
176
|
+
const validated = validateExport(input.raw, input.prepared);
|
|
177
|
+
if (!validated.ok)
|
|
178
|
+
return validated;
|
|
179
|
+
if (validated.value.approval_digest !== input.approval) {
|
|
180
|
+
return {
|
|
181
|
+
ok: false,
|
|
182
|
+
failure: {
|
|
183
|
+
code: "APPROVAL_MISMATCH",
|
|
184
|
+
message: "el approval digest no corresponde a esta propuesta",
|
|
185
|
+
action: "volvé a correr validate y aprobá el digest que devuelve",
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (validated.value.preview.overwrites !== null && input.allowOverwrite !== true) {
|
|
190
|
+
return {
|
|
191
|
+
ok: false,
|
|
192
|
+
failure: {
|
|
193
|
+
code: "OVERWRITE_NOT_AUTHORIZED",
|
|
194
|
+
message: `la propuesta reemplaza '${validated.value.preview.overwrites}'`,
|
|
195
|
+
action: "confirmá con --overwrite si querés reemplazarlo, o quitalo de la propuesta",
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const parsed = parseSemanticResponse(input.raw, input.prepared.request);
|
|
200
|
+
if (!parsed.ok)
|
|
201
|
+
return parsed;
|
|
202
|
+
const policy = POLICIES[input.prepared.category];
|
|
203
|
+
const result = await withCwdLock(fs, paths, async () => {
|
|
204
|
+
const minted = (await runNextNumber(fs, env, { directory: policy.dir })).next;
|
|
205
|
+
const artifacts = (parsed.value.artifacts ?? []).map((artifact) => renumber(artifact, input.prepared, minted, policy));
|
|
206
|
+
// Whole dossier or nothing: `publishArtifacts` restores every previous
|
|
207
|
+
// state on the first failure.
|
|
208
|
+
return await publishArtifacts(fs, paths.workspaceDir(), artifacts, {
|
|
209
|
+
overwrite: input.allowOverwrite === true,
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
if ("error" in result) {
|
|
213
|
+
return {
|
|
214
|
+
ok: false,
|
|
215
|
+
failure: {
|
|
216
|
+
code: "LOCK_BUSY",
|
|
217
|
+
message: result.error,
|
|
218
|
+
action: "esperá a que termine la otra operación y volvé a aplicar",
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
if (!result.ok)
|
|
223
|
+
return result;
|
|
224
|
+
return { ok: true, value: { category: input.prepared.category, written: result.value.written } };
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* The number in the answer was consultative. The real one is minted inside the
|
|
228
|
+
* lock, so the destination is rebuilt here — never trusted from the proposal.
|
|
229
|
+
*/
|
|
230
|
+
function renumber(artifact, prepared, minted, policy) {
|
|
231
|
+
if (artifact.path === policy.overwritable)
|
|
232
|
+
return artifact;
|
|
233
|
+
if (policy.shape === "document") {
|
|
234
|
+
const name = artifact.path.slice(policy.dir.length + 1).replace(/^\d{3}-/, "");
|
|
235
|
+
return { path: `${policy.dir}/${minted}-${name}`, content: artifact.content };
|
|
236
|
+
}
|
|
237
|
+
const unit = prepared.unit.replace(/\/\d{3}-/, `/${minted}-`);
|
|
238
|
+
return {
|
|
239
|
+
path: `${unit}/${artifact.path.slice(prepared.unit.length + 1)}`,
|
|
240
|
+
content: artifact.content,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
function reject(message) {
|
|
244
|
+
return {
|
|
245
|
+
code: "EXPORT_SHAPE_INVALID",
|
|
246
|
+
message,
|
|
247
|
+
action: "corregí la propuesta según el 'contract' del request y reenviala",
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=export-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-service.js","sourceRoot":"","sources":["../../src/application/export-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { buildSemanticRequest, parseSemanticResponse, } from "./semantic-operation/protocol.js";
|
|
3
|
+
/**
|
|
4
|
+
* `fix-git` — resolve merge conflicts whose resolution is unambiguous.
|
|
5
|
+
*
|
|
6
|
+
* The AI contributes intent and content for one conflict at a time; the CLI
|
|
7
|
+
* decides which paths are still authorized, revalidates that the conflict is
|
|
8
|
+
* the same one it prepared, and owns edit / stage / commit.
|
|
9
|
+
*
|
|
10
|
+
* Two authorization rules, deliberately different:
|
|
11
|
+
*
|
|
12
|
+
* - **`apply` is authorized by the invocation itself** — but only for a set
|
|
13
|
+
* that is entirely unambiguous and still current. Anything else stops.
|
|
14
|
+
* - **`commit` is a separate action** and always needs its own confirmation.
|
|
15
|
+
* Never `--no-verify`, never `--amend`, never a push.
|
|
16
|
+
*/
|
|
17
|
+
const OPERATION = "fix-git";
|
|
18
|
+
const LIMITS = { max_artifacts: 64, max_artifact_bytes: 512 * 1024 };
|
|
19
|
+
const CONFLICT_MARKER = /^(<{7}|={7}|>{7})(\s|$)/m;
|
|
20
|
+
const CONTRACT = [
|
|
21
|
+
"Respondé UN objeto JSON con version, operation e input_digest copiados del request,",
|
|
22
|
+
"state='proposed' y artifacts: un { path, content } por CADA archivo en conflicto,",
|
|
23
|
+
"donde content es el archivo resuelto COMPLETO, sin marcadores de conflicto.",
|
|
24
|
+
"Si alguno no tiene resolución inequívoca, respondé state='ambiguous' (o 'unsupported'",
|
|
25
|
+
"para binarios) con reason — el CLI lo devuelve como elección y no escribe nada.",
|
|
26
|
+
"No incluyas ningún path fuera del set de conflictos.",
|
|
27
|
+
].join(" ");
|
|
28
|
+
// ── prepare ──────────────────────────────────────────────────────────────────
|
|
29
|
+
export async function prepareFixGit(git, repo, alias) {
|
|
30
|
+
if (!(await git.isGitRepo(repo))) {
|
|
31
|
+
return { ok: false, failure: notRepo(repo) };
|
|
32
|
+
}
|
|
33
|
+
if (!(await git.isMerging(repo))) {
|
|
34
|
+
return {
|
|
35
|
+
ok: false,
|
|
36
|
+
failure: {
|
|
37
|
+
code: "NOT_MERGING",
|
|
38
|
+
message: `'${repo}' no está en medio de un merge`,
|
|
39
|
+
action: "no hay conflictos que resolver: revisá el repo o el alias",
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const paths = await git.conflictedFiles(repo);
|
|
44
|
+
if (paths.length === 0) {
|
|
45
|
+
return {
|
|
46
|
+
ok: false,
|
|
47
|
+
failure: {
|
|
48
|
+
code: "NO_CONFLICTS",
|
|
49
|
+
message: "el merge está en curso pero no quedan archivos en conflicto",
|
|
50
|
+
action: "revisá `git status`: puede faltar solo el commit del merge",
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const stages = [];
|
|
55
|
+
for (const path of paths)
|
|
56
|
+
stages.push(await git.conflictStages(repo, path));
|
|
57
|
+
const context = {
|
|
58
|
+
repo,
|
|
59
|
+
alias,
|
|
60
|
+
merge_origin: (await git.mergeOrigin(repo)) ?? null,
|
|
61
|
+
current_branch: (await git.currentBranch(repo)) ?? null,
|
|
62
|
+
conflicts: stages.map(summarize),
|
|
63
|
+
};
|
|
64
|
+
const request = buildSemanticRequest({
|
|
65
|
+
operation: OPERATION,
|
|
66
|
+
// Sealed over the hashes, not the content: the seal must change exactly
|
|
67
|
+
// when the conflict changes, and only then.
|
|
68
|
+
inputs: context.conflicts,
|
|
69
|
+
contract: CONTRACT,
|
|
70
|
+
inventory: { context, stages: stages.map(stageView) },
|
|
71
|
+
allowedDestinations: paths,
|
|
72
|
+
limits: LIMITS,
|
|
73
|
+
readSet: paths,
|
|
74
|
+
readSetBytes: stages.reduce((sum, s) => sum + totalBytes(s), 0),
|
|
75
|
+
});
|
|
76
|
+
return { ok: true, value: { context, request, stages } };
|
|
77
|
+
}
|
|
78
|
+
function summarize(stages) {
|
|
79
|
+
return {
|
|
80
|
+
path: stages.path,
|
|
81
|
+
base_hash: stages.base.hash,
|
|
82
|
+
ours_hash: stages.ours.hash,
|
|
83
|
+
theirs_hash: stages.theirs.hash,
|
|
84
|
+
binary: stages.binary,
|
|
85
|
+
bytes: totalBytes(stages),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function stageView(stages) {
|
|
89
|
+
return {
|
|
90
|
+
path: stages.path,
|
|
91
|
+
binary: stages.binary,
|
|
92
|
+
base: stages.base.content,
|
|
93
|
+
ours: stages.ours.content,
|
|
94
|
+
theirs: stages.theirs.content,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function totalBytes(stages) {
|
|
98
|
+
return stages.base.bytes + stages.ours.bytes + stages.theirs.bytes;
|
|
99
|
+
}
|
|
100
|
+
export function validateFixGit(raw, prepared) {
|
|
101
|
+
const parsed = parseSemanticResponse(raw, prepared.request);
|
|
102
|
+
if (!parsed.ok)
|
|
103
|
+
return parsed;
|
|
104
|
+
const proposed = new Map((parsed.value.artifacts ?? []).map((a) => [a.path, a.content]));
|
|
105
|
+
const resolutions = [];
|
|
106
|
+
for (const conflict of prepared.context.conflicts) {
|
|
107
|
+
// Binary stays a human job: turning it into text would silently corrupt it.
|
|
108
|
+
if (conflict.binary) {
|
|
109
|
+
return { ok: false, failure: unsupportedBinary(conflict.path) };
|
|
110
|
+
}
|
|
111
|
+
const content = proposed.get(conflict.path);
|
|
112
|
+
if (content === undefined) {
|
|
113
|
+
return {
|
|
114
|
+
ok: false,
|
|
115
|
+
failure: {
|
|
116
|
+
code: "FIX_GIT_INCOMPLETE",
|
|
117
|
+
message: `falta la resolución de '${conflict.path}'`,
|
|
118
|
+
action: "resolvé TODOS los conflictos vigentes, o declará state='ambiguous'",
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
if (CONFLICT_MARKER.test(content)) {
|
|
123
|
+
return {
|
|
124
|
+
ok: false,
|
|
125
|
+
failure: {
|
|
126
|
+
code: "FIX_GIT_MARKERS_LEFT",
|
|
127
|
+
message: `'${conflict.path}' conserva marcadores de conflicto`,
|
|
128
|
+
action: "entregá el archivo resuelto completo, sin <<<<<<< ======= >>>>>>>",
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
resolutions.push({ path: conflict.path, content, bytes: Buffer.byteLength(content, "utf8") });
|
|
133
|
+
}
|
|
134
|
+
// No leftover check here on purpose: `allowed_destinations` IS the conflict
|
|
135
|
+
// set, so the protocol already rejects any path the answer invented. Checking
|
|
136
|
+
// it twice was dead code — mutation testing proved the second copy unreachable.
|
|
137
|
+
return { ok: true, value: resolutions };
|
|
138
|
+
}
|
|
139
|
+
// ── apply ────────────────────────────────────────────────────────────────────
|
|
140
|
+
/**
|
|
141
|
+
* Writes and stages, and only for a set that is still exactly the one prepared.
|
|
142
|
+
* The invocation is the authorization — which is why the currency check is not
|
|
143
|
+
* optional: a conflict another process already resolved is not ours to touch.
|
|
144
|
+
*/
|
|
145
|
+
export async function applyFixGit(fs, git, prepared, resolutions) {
|
|
146
|
+
const fresh = await prepareFixGit(git, prepared.context.repo, prepared.context.alias);
|
|
147
|
+
if (!fresh.ok)
|
|
148
|
+
return fresh;
|
|
149
|
+
if (fresh.value.request.input_digest !== prepared.request.input_digest) {
|
|
150
|
+
return {
|
|
151
|
+
ok: false,
|
|
152
|
+
failure: {
|
|
153
|
+
code: "SEMANTIC_STALE",
|
|
154
|
+
message: "el set de conflictos cambió desde el prepare",
|
|
155
|
+
action: "volvé a correr prepare: otro proceso tocó el merge",
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const resolved = [];
|
|
160
|
+
const staged = [];
|
|
161
|
+
for (const resolution of resolutions) {
|
|
162
|
+
const absolute = join(prepared.context.repo, resolution.path);
|
|
163
|
+
try {
|
|
164
|
+
await fs.writeText(absolute, resolution.content);
|
|
165
|
+
resolved.push(resolution.path);
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
return { ok: false, failure: writeFailed(resolution.path, err, resolved, staged) };
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
await git.stagePath(prepared.context.repo, resolution.path);
|
|
172
|
+
staged.push(resolution.path);
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
return { ok: false, failure: stageFailed(resolution.path, err, resolved, staged) };
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const remaining = await git.conflictedFiles(prepared.context.repo);
|
|
179
|
+
return { ok: true, value: { resolved, staged, remaining } };
|
|
180
|
+
}
|
|
181
|
+
// ── commit (a separate, always-confirmed action) ─────────────────────────────
|
|
182
|
+
export async function commitFixGit(git, repo, message) {
|
|
183
|
+
const remaining = await git.conflictedFiles(repo);
|
|
184
|
+
if (remaining.length > 0) {
|
|
185
|
+
return {
|
|
186
|
+
ok: false,
|
|
187
|
+
failure: {
|
|
188
|
+
code: "FIX_GIT_UNMERGED",
|
|
189
|
+
message: `quedan ${remaining.length} archivo(s) sin resolver: ${remaining.join(", ")}`,
|
|
190
|
+
action: "resolvé el resto antes de cerrar el merge",
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
await git.commit(repo, message);
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
return {
|
|
199
|
+
ok: false,
|
|
200
|
+
failure: {
|
|
201
|
+
code: "COMMIT_FAILED",
|
|
202
|
+
message: `git commit falló: ${errorText(err)}`,
|
|
203
|
+
action: "revisá la salida de git (hooks incluidos) y reintentá",
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
return { ok: true, value: { committed: true, message } };
|
|
208
|
+
}
|
|
209
|
+
// ── failures ─────────────────────────────────────────────────────────────────
|
|
210
|
+
function notRepo(repo) {
|
|
211
|
+
return {
|
|
212
|
+
code: "NOT_A_REPO",
|
|
213
|
+
message: `'${repo}' no es un repositorio git`,
|
|
214
|
+
action: "pasá --source <alias> o --path <ruta> de un repo válido",
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function unsupportedBinary(path) {
|
|
218
|
+
return {
|
|
219
|
+
code: "FIX_GIT_BINARY",
|
|
220
|
+
message: `'${path}' es binario: no se resuelve automáticamente`,
|
|
221
|
+
action: "elegí una versión a mano (`git checkout --ours|--theirs`) y volvé a intentar el resto",
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function writeFailed(path, err, resolved, staged) {
|
|
225
|
+
return {
|
|
226
|
+
code: "FIX_GIT_WRITE_FAILED",
|
|
227
|
+
message: `no se pudo escribir '${path}': ${errorText(err)}`,
|
|
228
|
+
action: `${describeProgress(resolved, staged)}; el resto sigue en conflicto y es identificable con \`git status\``,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function stageFailed(path, err, resolved, staged) {
|
|
232
|
+
return {
|
|
233
|
+
code: "FIX_GIT_STAGE_FAILED",
|
|
234
|
+
message: `git add falló en '${path}': ${errorText(err)}`,
|
|
235
|
+
action: `${describeProgress(resolved, staged)}; mirá \`git status\` para ver qué quedó sin stagear y reintentá`,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
function describeProgress(resolved, staged) {
|
|
239
|
+
return `se escribieron ${resolved.length} archivo(s) y se stagearon ${staged.length}`;
|
|
240
|
+
}
|
|
241
|
+
function errorText(err) {
|
|
242
|
+
return err instanceof Error ? err.message : String(err);
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=fix-git-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-git-service.js","sourceRoot":"","sources":["../../src/application/fix-git-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,29 +2,45 @@ import { localDateIso } from "./dates.js";
|
|
|
2
2
|
import { buildRow, upsertRow } from "./history-table.js";
|
|
3
3
|
import { withCwdLock } from "./lock-service.js";
|
|
4
4
|
import { renderRefs } from "./render/history-row.js";
|
|
5
|
-
import {
|
|
6
|
-
export async function runHistoryUpdate(fs,
|
|
5
|
+
import { resolveSessionTarget } from "./session-resolver.js";
|
|
6
|
+
export async function runHistoryUpdate(fs, paths, input) {
|
|
7
7
|
const validation = validate(input);
|
|
8
8
|
if (validation)
|
|
9
9
|
return validation;
|
|
10
10
|
const code = input.code ?? "";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
11
|
+
// HISTORY is infrastructure: it records a row for a code even when the folder
|
|
12
|
+
// is gone, and it NEVER establishes a conversation association (`bind` off).
|
|
13
|
+
const resolution = await resolveSessionTarget(fs, paths, { code, allowClosed: true });
|
|
14
|
+
const session = resolution.outcome === "resolved" ? resolution.session : null;
|
|
15
|
+
return withCwdLock(fs, paths, () => upsertHistoryRow(fs, paths, historyFields(input, session, code)));
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Upsert the HISTORY.md row WITHOUT acquiring the workspace lock — for callers
|
|
19
|
+
* that already hold it. `session-close` mutates the `.closed` marker, the
|
|
20
|
+
* bindings registry and this row inside ONE lock boundary; going through the
|
|
21
|
+
* public command instead would nest the acquisition.
|
|
22
|
+
*/
|
|
23
|
+
export async function upsertHistoryRow(fs, paths, fields) {
|
|
24
|
+
const action = await upsertRow(fs, paths.cwdHistoryFile(), fields.code, () => buildRow({
|
|
25
|
+
code: fields.code,
|
|
26
|
+
sesionName: fields.sesionName,
|
|
27
|
+
date: fields.date,
|
|
28
|
+
state: fields.state,
|
|
29
|
+
refs: renderRefs(fields.refs),
|
|
30
|
+
}));
|
|
31
|
+
// `flow` stays in the output shape for consumer compat; sessions carry no
|
|
32
|
+
// flow segment anymore, so it is always null.
|
|
33
|
+
return { code: fields.code, flow: null, action, state: fields.state };
|
|
34
|
+
}
|
|
35
|
+
/** Merge the caller's overrides with what the resolved session already knows. */
|
|
36
|
+
export function historyFields(input, session, code) {
|
|
37
|
+
return {
|
|
38
|
+
code: normalizeCode(code),
|
|
39
|
+
sesionName: input.sesionName || session?.name || code,
|
|
40
|
+
date: input.date || session?.date || localDateIso(new Date()),
|
|
41
|
+
state: input.state ?? "active",
|
|
42
|
+
...(input.refs !== undefined ? { refs: input.refs } : {}),
|
|
43
|
+
};
|
|
28
44
|
}
|
|
29
45
|
function validate(input) {
|
|
30
46
|
if (!input.code || !input.state)
|
|
@@ -34,11 +50,6 @@ function validate(input) {
|
|
|
34
50
|
}
|
|
35
51
|
return null;
|
|
36
52
|
}
|
|
37
|
-
function mergeFields(input, session, code) {
|
|
38
|
-
const sesionName = input.sesionName || session?.name || code;
|
|
39
|
-
const date = input.date || session?.date || localDateIso(new Date());
|
|
40
|
-
return { sesionName, date };
|
|
41
|
-
}
|
|
42
53
|
function normalizeCode(code) {
|
|
43
54
|
return code.includes("session") ? (code.replace("session", "").split("-")[0] ?? code) : code;
|
|
44
55
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history-update-service.js","sourceRoot":"","sources":["../../src/application/history-update-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"history-update-service.js","sourceRoot":"","sources":["../../src/application/history-update-service.ts"],"names":[],"mappings":"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"}
|