@tacuchi/agent-workflow-cli 25.3.1 → 25.4.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 +1 -1
- package/dist/application/doctor/repair-runner.js +35 -2
- package/dist/application/doctor/repair-runner.js.map +1 -1
- package/dist/application/self/install-plugin-skills-git.js +28 -1
- package/dist/application/self/install-plugin-skills-git.js.map +1 -1
- package/dist/application/self/skills-apply.js +623 -0
- package/dist/application/self/skills-apply.js.map +1 -0
- package/dist/application/self/skills-catalog.js +35 -0
- package/dist/application/self/skills-catalog.js.map +1 -0
- package/dist/application/self/skills-change.js +479 -0
- package/dist/application/self/skills-change.js.map +1 -0
- package/dist/application/self/skills-discovery.js +275 -0
- package/dist/application/self/skills-discovery.js.map +1 -0
- package/dist/application/self/skills-manager.js +69 -499
- package/dist/application/self/skills-manager.js.map +1 -1
- package/dist/application/self/skills-payload.js +566 -0
- package/dist/application/self/skills-payload.js.map +1 -0
- package/dist/application/self/skills-registry.js +31 -11
- package/dist/application/self/skills-registry.js.map +1 -1
- package/dist/cli/tui/data/recommended-skills.js +333 -8
- package/dist/cli/tui/data/recommended-skills.js.map +1 -1
- package/dist/cli/tui/tabs/skills-tab.js +448 -204
- package/dist/cli/tui/tabs/skills-tab.js.map +1 -1
- package/dist/domain/doctor/operations.js +3 -1
- package/dist/domain/doctor/operations.js.map +1 -1
- package/package.json +1 -1
- package/skills/w/roles/README.md +2 -0
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
// Applying an approved proposal (Spec 043 · AC-10, AC-12), and surviving a
|
|
2
|
+
// failure halfway through.
|
|
3
|
+
//
|
|
4
|
+
// The five rules this file exists to keep:
|
|
5
|
+
// 1. ONE writer at a time — the lock sits next to the shared registry, not
|
|
6
|
+
// in a workspace: two projects install into the same HOME.
|
|
7
|
+
// 2. Nothing is removed before its replacement is staged. Every payload and
|
|
8
|
+
// every replica is ready first; only then does the first swap happen.
|
|
9
|
+
// 3. Every destination keeps a BACKUP until the whole set is verified, and
|
|
10
|
+
// the backups live outside every host discovery root — a `.hidden` name
|
|
11
|
+
// inside one is still a skill the host would load.
|
|
12
|
+
// 4. A journal records the operation, its approved digest and the state of
|
|
13
|
+
// each destination. An exception compensates in reverse order; an
|
|
14
|
+
// interruption leaves the journal for the next run to find. A pending
|
|
15
|
+
// journal is never applied over blindly.
|
|
16
|
+
// 5. `applied` and `verified` are different words. Verification checks the
|
|
17
|
+
// bytes this manager wrote — never that a host reloaded anything.
|
|
18
|
+
import { randomUUID } from "node:crypto";
|
|
19
|
+
import { lstat, mkdir, readFile, rename, rm, symlink, writeFile } from "node:fs/promises";
|
|
20
|
+
import { basename, dirname, join } from "node:path";
|
|
21
|
+
import { acquireLock } from "../lock-service.js";
|
|
22
|
+
import { semanticDigest } from "../semantic-operation/protocol.js";
|
|
23
|
+
import { copyDir } from "./install-plugin-skills.js";
|
|
24
|
+
import { REPLICA_MARKER_FILENAME, canonicalSkillsRoot, claudeReplicaRoot, geminiReplicaRoot, inspectSkillOwnership, } from "./skills-manager.js";
|
|
25
|
+
import { readSkillsRegistry, skillsRegistryPath, } from "./skills-registry.js";
|
|
26
|
+
/** Sibling of the registry, OUTSIDE `<host>/skills`: what a host scans is the
|
|
27
|
+
* skills root, so staging and backups live one level up from it. */
|
|
28
|
+
const WORK_DIRNAME = ".workline-skills";
|
|
29
|
+
const JOURNAL_FILE = "journal.json";
|
|
30
|
+
const MANIFEST = "SKILL.md";
|
|
31
|
+
const LOCK_FILE = ".skills-registry.lock";
|
|
32
|
+
/** A second writer waits this long before reporting the holder. */
|
|
33
|
+
const LOCK_WAIT_MS = 10_000;
|
|
34
|
+
export function skillsWorkRoot(home) {
|
|
35
|
+
return join(home, ".agents", WORK_DIRNAME);
|
|
36
|
+
}
|
|
37
|
+
export function skillsJournalPath(home) {
|
|
38
|
+
return join(skillsWorkRoot(home), JOURNAL_FILE);
|
|
39
|
+
}
|
|
40
|
+
/** Staging and backups for one destination root, on ITS filesystem and
|
|
41
|
+
* outside its discovery root. */
|
|
42
|
+
function workRootFor(destinationRoot, id) {
|
|
43
|
+
return join(dirname(destinationRoot), WORK_DIRNAME, id);
|
|
44
|
+
}
|
|
45
|
+
/** The pending operation a previous run left behind, if any. */
|
|
46
|
+
export async function readSkillJournal(ctx) {
|
|
47
|
+
const path = skillsJournalPath(ctx.env.homeDir());
|
|
48
|
+
if (!(await ctx.fs.exists(path)))
|
|
49
|
+
return null;
|
|
50
|
+
try {
|
|
51
|
+
const parsed = JSON.parse(await ctx.fs.readText(path));
|
|
52
|
+
return typeof parsed?.id === "string" ? parsed : null;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function writeJournal(ctx, journal) {
|
|
59
|
+
const path = skillsJournalPath(ctx.env.homeDir());
|
|
60
|
+
await mkdir(dirname(path), { recursive: true });
|
|
61
|
+
await writeFile(path, `${JSON.stringify(journal, null, 2)}\n`, "utf8");
|
|
62
|
+
}
|
|
63
|
+
/** Registry write that cannot be seen half-done, preserving every entry the
|
|
64
|
+
* operation does not touch. */
|
|
65
|
+
async function writeRegistryAtomically(home, registry) {
|
|
66
|
+
const path = skillsRegistryPath(home);
|
|
67
|
+
const temp = `${path}.tmp-${process.pid}`;
|
|
68
|
+
await mkdir(dirname(path), { recursive: true });
|
|
69
|
+
await writeFile(temp, `${JSON.stringify(registry, null, 2)}\n`, "utf8");
|
|
70
|
+
await rename(temp, path);
|
|
71
|
+
}
|
|
72
|
+
/** Digest of a skill's manifest — the cheap check that bytes arrived. */
|
|
73
|
+
async function manifestDigest(dir) {
|
|
74
|
+
const content = await readFile(join(dir, MANIFEST), "utf8").catch(() => null);
|
|
75
|
+
return content === null ? null : semanticDigest(content);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* What must still be true under the lock.
|
|
79
|
+
*
|
|
80
|
+
* The proposal was sealed outside it, so between the preview and here another
|
|
81
|
+
* writer may have installed, removed or replaced any of these names. Applying
|
|
82
|
+
* over that would honour an approval nobody gave for this state.
|
|
83
|
+
*/
|
|
84
|
+
async function checkPreconditions(ctx, proposal) {
|
|
85
|
+
const read = await readSkillsRegistry(ctx);
|
|
86
|
+
if (read.warning) {
|
|
87
|
+
return {
|
|
88
|
+
code: "REGISTRY_UNREADABLE",
|
|
89
|
+
message: `${read.warning} Corregí (o borrá) el archivo antes de aplicar.`,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
for (const [name, before] of Object.entries(proposal.previousRegistry)) {
|
|
93
|
+
const current = read.registry.skills[name] ?? null;
|
|
94
|
+
if (semanticDigest(current) !== semanticDigest(before)) {
|
|
95
|
+
return {
|
|
96
|
+
code: "PROPOSAL_STALE",
|
|
97
|
+
message: `'${name}' cambió en el registro desde la vista previa`,
|
|
98
|
+
action: "volvé a preparar el cambio: la aprobación anterior no cubre este estado",
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// Not "is anything foreign?" — a withdrawal's proposal DECLARED the foreign
|
|
102
|
+
// location it would preserve, and refusing that would refuse the very case
|
|
103
|
+
// the preview described. What must not have changed is the picture the
|
|
104
|
+
// approval was given over.
|
|
105
|
+
const ownership = await inspectSkillOwnership(ctx, name, current ?? undefined);
|
|
106
|
+
const declared = new Map(proposal.destinations
|
|
107
|
+
.filter((destination) => basename(destination.location) === name)
|
|
108
|
+
.map((destination) => [destination.location, destination.ownership]));
|
|
109
|
+
const live = [
|
|
110
|
+
[ownership.canonical.path, ownership.canonical.state],
|
|
111
|
+
...ownership.replicas.map((replica) => [replica.path, replica.state]),
|
|
112
|
+
];
|
|
113
|
+
for (const [location, state] of live) {
|
|
114
|
+
const assumed = declared.get(location);
|
|
115
|
+
if (assumed !== undefined && assumed !== state) {
|
|
116
|
+
return {
|
|
117
|
+
code: "OWNERSHIP_CHANGED",
|
|
118
|
+
message: `${location} pasó de '${assumed}' a '${state}' desde la vista previa`,
|
|
119
|
+
action: "volvé a preparar el cambio: la aprobación no cubre este estado",
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
for (const skill of proposal.additions) {
|
|
125
|
+
const staged = await manifestDigest(skill.stagedAt);
|
|
126
|
+
if (staged === null) {
|
|
127
|
+
return {
|
|
128
|
+
code: "PAYLOAD_GONE",
|
|
129
|
+
message: `el payload preparado de '${skill.name}' ya no está disponible`,
|
|
130
|
+
action: "volvé a preparar el cambio: el temporal de la preparación se liberó",
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return { registry: read.registry };
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Every payload and every replica, ready BEFORE the first removal.
|
|
138
|
+
*
|
|
139
|
+
* This is the order AC-10 asks for: a replacement that fails while being
|
|
140
|
+
* fetched or copied must leave the previous installation untouched, and the
|
|
141
|
+
* only way to promise that is to have the new bytes complete first.
|
|
142
|
+
*/
|
|
143
|
+
async function stageDestinations(ctx, proposal, id) {
|
|
144
|
+
const home = ctx.env.homeDir();
|
|
145
|
+
const canonicalRoot = canonicalSkillsRoot(home);
|
|
146
|
+
const staged = [];
|
|
147
|
+
const payloads = new Map(proposal.additions.map((skill) => [skill.name, skill]));
|
|
148
|
+
for (const destination of proposal.destinations) {
|
|
149
|
+
const name = basename(destination.location);
|
|
150
|
+
if (destination.host === "registry" || destination.action === "unchanged") {
|
|
151
|
+
staged.push({ destination, staged: null, link: null, name });
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (destination.action === "delete") {
|
|
155
|
+
staged.push({ destination, staged: null, link: null, name });
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
const payload = payloads.get(name);
|
|
159
|
+
const work = join(workRootFor(dirname(destination.location), id), "staging");
|
|
160
|
+
await mkdir(work, { recursive: true });
|
|
161
|
+
const target = join(work, name);
|
|
162
|
+
if (destination.host === "agents") {
|
|
163
|
+
if (payload === undefined) {
|
|
164
|
+
staged.push({ destination, staged: null, link: null, name });
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
await copyDir(payload.stagedAt, target);
|
|
168
|
+
staged.push({ destination, staged: target, link: null, name });
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
// A replica of the claude host prefers a link to the canonical; the gemini
|
|
172
|
+
// one is always a copy (its walker does not follow directory links).
|
|
173
|
+
const canonical = join(canonicalRoot, name);
|
|
174
|
+
if (destination.host === "claude") {
|
|
175
|
+
staged.push({ destination, staged: null, link: canonical, name });
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
await copyDir(payload === undefined ? canonical : payload.stagedAt, target);
|
|
179
|
+
await writeFile(join(target, REPLICA_MARKER_FILENAME), `${canonical}\n`, "utf8");
|
|
180
|
+
staged.push({ destination, staged: target, link: null, name });
|
|
181
|
+
}
|
|
182
|
+
return staged;
|
|
183
|
+
}
|
|
184
|
+
/** Moves whatever is at `location` into the backup area, or `null` if empty.
|
|
185
|
+
* `lstat`, not `exists`: a replica may BE a symlink, and it has to be moved
|
|
186
|
+
* as the link it is rather than followed. */
|
|
187
|
+
async function backup(location, id) {
|
|
188
|
+
if ((await lstat(location).catch(() => null)) === null)
|
|
189
|
+
return null;
|
|
190
|
+
const dir = join(workRootFor(dirname(location), id), "backup");
|
|
191
|
+
await mkdir(dir, { recursive: true });
|
|
192
|
+
const destination = join(dir, basename(location));
|
|
193
|
+
await rename(location, destination);
|
|
194
|
+
return destination;
|
|
195
|
+
}
|
|
196
|
+
/** Publishes one staged destination, keeping its previous bytes aside. */
|
|
197
|
+
async function publish(entry, id) {
|
|
198
|
+
const { destination } = entry;
|
|
199
|
+
const record = {
|
|
200
|
+
location: destination.location,
|
|
201
|
+
host: destination.host,
|
|
202
|
+
action: destination.action,
|
|
203
|
+
status: "pending",
|
|
204
|
+
backup: null,
|
|
205
|
+
};
|
|
206
|
+
if (destination.action === "unchanged") {
|
|
207
|
+
return {
|
|
208
|
+
...record,
|
|
209
|
+
status: "unchanged",
|
|
210
|
+
detail: "se conservó: no lo materializó este manager",
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
record.backup = await backup(destination.location, id);
|
|
214
|
+
if (destination.action === "delete") {
|
|
215
|
+
return { ...record, status: "applied" };
|
|
216
|
+
}
|
|
217
|
+
await mkdir(dirname(destination.location), { recursive: true });
|
|
218
|
+
if (entry.link !== null) {
|
|
219
|
+
try {
|
|
220
|
+
await symlink(entry.link, destination.location);
|
|
221
|
+
return { ...record, status: "applied", detail: "symlink" };
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// No symlinks (Windows without Developer Mode): a real copy, marked.
|
|
225
|
+
await copyDir(entry.link, destination.location);
|
|
226
|
+
await writeFile(join(destination.location, REPLICA_MARKER_FILENAME), `${entry.link}\n`, "utf8");
|
|
227
|
+
return { ...record, status: "applied", detail: "copy" };
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (entry.staged === null) {
|
|
231
|
+
return { ...record, status: "failed", detail: "no había bytes preparados para este destino" };
|
|
232
|
+
}
|
|
233
|
+
await rename(entry.staged, destination.location);
|
|
234
|
+
return { ...record, status: "applied" };
|
|
235
|
+
}
|
|
236
|
+
/** Puts back what a failed run had already moved, newest first. */
|
|
237
|
+
async function compensate(applied) {
|
|
238
|
+
const restored = [];
|
|
239
|
+
const pending = [];
|
|
240
|
+
for (const record of [...applied].reverse()) {
|
|
241
|
+
if (record.status !== "applied")
|
|
242
|
+
continue;
|
|
243
|
+
try {
|
|
244
|
+
await rm(record.location, { recursive: true, force: true });
|
|
245
|
+
if (record.backup !== null)
|
|
246
|
+
await rename(record.backup, record.location);
|
|
247
|
+
restored.push(record.location);
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
// A location changed outside the operation, or the restore itself
|
|
251
|
+
// failed: the backup STAYS and the state is declared mixed.
|
|
252
|
+
pending.push(record.location);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return { restored, pending };
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* The independent check, per destination: the bytes this manager wrote are
|
|
259
|
+
* there. Four things are checkable and all four are checked — the link's
|
|
260
|
+
* target, the copied content, the registry entries and the payload's manifest.
|
|
261
|
+
* Nothing here claims a host loaded anything.
|
|
262
|
+
*/
|
|
263
|
+
async function verify(record, home, expected, proposed) {
|
|
264
|
+
if (record.status === "unchanged")
|
|
265
|
+
return null;
|
|
266
|
+
const name = basename(record.location);
|
|
267
|
+
if (record.host === "registry") {
|
|
268
|
+
const read = await readSkillsRegistryAt(record.location);
|
|
269
|
+
const mismatch = Object.entries(proposed).find(([entry, value]) => value === null ? read.has(entry) : !read.has(entry));
|
|
270
|
+
return {
|
|
271
|
+
checked: `entradas del registro en ${record.location}`,
|
|
272
|
+
passed: read.readable && mismatch === undefined,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
if (record.action === "delete") {
|
|
276
|
+
const gone = (await lstat(record.location).catch(() => null)) === null;
|
|
277
|
+
return { checked: "la ubicación ya no existe", passed: gone };
|
|
278
|
+
}
|
|
279
|
+
const digest = await manifestDigest(record.host === "claude" && record.detail === "symlink"
|
|
280
|
+
? join(canonicalSkillsRoot(home), name)
|
|
281
|
+
: record.location);
|
|
282
|
+
const want = expected.get(name);
|
|
283
|
+
return {
|
|
284
|
+
checked: `SKILL.md de ${record.location}`,
|
|
285
|
+
passed: digest !== null && (want === undefined || digest === want),
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
/** The registry as it stands on disk, for the verification to read back. */
|
|
289
|
+
async function readSkillsRegistryAt(path) {
|
|
290
|
+
const raw = await readFile(path, "utf8").catch(() => null);
|
|
291
|
+
if (raw === null)
|
|
292
|
+
return { readable: false, has: () => false };
|
|
293
|
+
try {
|
|
294
|
+
const parsed = JSON.parse(raw);
|
|
295
|
+
const skills = parsed.skills ?? {};
|
|
296
|
+
return { readable: true, has: (name) => Object.hasOwn(skills, name) };
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
return { readable: false, has: () => false };
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
/** Removes the backups of a finished, verified operation, then its work dirs. */
|
|
303
|
+
async function cleanup(records, home, id) {
|
|
304
|
+
const pending = [];
|
|
305
|
+
for (const record of records) {
|
|
306
|
+
if (record.backup === null)
|
|
307
|
+
continue;
|
|
308
|
+
try {
|
|
309
|
+
await rm(record.backup, { recursive: true, force: true });
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
pending.push(record.backup);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
// Best effort: the per-destination removal above is the one that matters, and
|
|
316
|
+
// a leftover empty work dir is declared as pending cleanup, never as failure.
|
|
317
|
+
for (const root of managedWorkRoots(home)) {
|
|
318
|
+
await rm(join(root, id), { recursive: true, force: true }).catch(() => pending.push(join(root, id)));
|
|
319
|
+
}
|
|
320
|
+
return pending;
|
|
321
|
+
}
|
|
322
|
+
/** The work roots of the three managed hosts — outside every skills root. */
|
|
323
|
+
function managedWorkRoots(home) {
|
|
324
|
+
return [canonicalSkillsRoot(home), claudeReplicaRoot(home), geminiReplicaRoot(home)].map((root) => join(dirname(root), WORK_DIRNAME));
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* The registry the application writes: the approved entries plus the two facts
|
|
328
|
+
* only the application knows — WHEN it materialized and whether the primary
|
|
329
|
+
* replica ended up a link or a copy. Entries the operation does not name are
|
|
330
|
+
* carried over untouched.
|
|
331
|
+
*/
|
|
332
|
+
function registryAfter(before, proposal, records) {
|
|
333
|
+
const skills = { ...before.skills };
|
|
334
|
+
const installedAt = new Date().toISOString();
|
|
335
|
+
const materialized = new Set(proposal.additions.map((skill) => skill.name));
|
|
336
|
+
for (const [name, entry] of Object.entries(proposal.proposedRegistry)) {
|
|
337
|
+
if (entry === null) {
|
|
338
|
+
delete skills[name];
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
if (!proposal.installs || !materialized.has(name)) {
|
|
342
|
+
skills[name] = entry;
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
const claude = records.find((record) => record.host === "claude" && basename(record.location) === name);
|
|
346
|
+
const mode = claude?.detail === "symlink" ? "symlink" : claude?.detail === "copy" ? "copy" : null;
|
|
347
|
+
skills[name] = {
|
|
348
|
+
...entry,
|
|
349
|
+
...(mode !== null ? { mode } : {}),
|
|
350
|
+
installedAt,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
return { skills };
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Applies exactly the approved proposal, or refuses.
|
|
357
|
+
*
|
|
358
|
+
* The approval is the proposal's own digest: a retry whose set, bytes,
|
|
359
|
+
* destinations or effects differ produces another digest and has to be
|
|
360
|
+
* approved again. That is what makes "only what was approved is applied" a
|
|
361
|
+
* property of the data.
|
|
362
|
+
*/
|
|
363
|
+
export async function applySkillChange(ctx, proposal, approval) {
|
|
364
|
+
if (approval !== proposal.digest) {
|
|
365
|
+
return {
|
|
366
|
+
status: "refused",
|
|
367
|
+
refusal: {
|
|
368
|
+
code: "APPROVAL_MISMATCH",
|
|
369
|
+
message: "la aprobación no corresponde a esta propuesta",
|
|
370
|
+
action: "volvé a preparar el cambio y aprobá la vista previa que devuelve",
|
|
371
|
+
},
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
const home = ctx.env.homeDir();
|
|
375
|
+
const lock = await acquireLock(join(home, ".agents", LOCK_FILE), ctx.fs, {
|
|
376
|
+
waitMs: LOCK_WAIT_MS,
|
|
377
|
+
});
|
|
378
|
+
try {
|
|
379
|
+
const pending = await readSkillJournal(ctx);
|
|
380
|
+
if (pending !== null) {
|
|
381
|
+
return {
|
|
382
|
+
status: "refused",
|
|
383
|
+
refusal: {
|
|
384
|
+
code: "JOURNAL_PENDING",
|
|
385
|
+
message: `quedó una operación '${pending.operation}' sin concluir (${pending.id})`,
|
|
386
|
+
action: "resolvé esa operación primero: restaurá el estado anterior o preparala de nuevo; aplicar encima repetiría efectos a ciegas",
|
|
387
|
+
},
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
const preconditions = await checkPreconditions(ctx, proposal);
|
|
391
|
+
if ("code" in preconditions)
|
|
392
|
+
return { status: "refused", refusal: preconditions };
|
|
393
|
+
return await run(ctx, proposal, preconditions.registry);
|
|
394
|
+
}
|
|
395
|
+
finally {
|
|
396
|
+
await lock.release();
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Puts back what this run had already published, and says so.
|
|
401
|
+
*
|
|
402
|
+
* A compensation that succeeds leaves nothing behind — no journal, no mixed
|
|
403
|
+
* state. One that cannot finish KEEPS the backups and names the locations,
|
|
404
|
+
* because a rollback reported as complete over a half-restored tree is the one
|
|
405
|
+
* lie this whole mechanism exists to avoid.
|
|
406
|
+
*/
|
|
407
|
+
async function rollback(ctx, journal, proposal, before, err) {
|
|
408
|
+
const home = ctx.env.homeDir();
|
|
409
|
+
const recovery = await compensate(journal.destinations);
|
|
410
|
+
if (journal.registryWritten) {
|
|
411
|
+
await writeRegistryAtomically(home, before).catch(() => recovery.pending.push("registry"));
|
|
412
|
+
}
|
|
413
|
+
journal.destinations = journal.destinations.map((record) => ({
|
|
414
|
+
...record,
|
|
415
|
+
status: recovery.pending.includes(record.location) ? "failed" : "restored",
|
|
416
|
+
}));
|
|
417
|
+
if (recovery.pending.length === 0) {
|
|
418
|
+
await rm(skillsJournalPath(home), { force: true }).catch(() => { });
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
await writeJournal(ctx, journal);
|
|
422
|
+
}
|
|
423
|
+
return {
|
|
424
|
+
operation: proposal.operation,
|
|
425
|
+
digest: proposal.digest,
|
|
426
|
+
destinations: journal.destinations.map((record) => ({
|
|
427
|
+
location: record.location,
|
|
428
|
+
host: record.host,
|
|
429
|
+
status: record.status,
|
|
430
|
+
verification: null,
|
|
431
|
+
...(record.detail !== undefined ? { detail: record.detail } : {}),
|
|
432
|
+
})),
|
|
433
|
+
recovery: {
|
|
434
|
+
restored: recovery.restored,
|
|
435
|
+
pending: recovery.pending,
|
|
436
|
+
action: recovery.pending.length === 0
|
|
437
|
+
? "se restauró el estado anterior; nada quedó a medias"
|
|
438
|
+
: `estado mixto: los respaldos de ${recovery.pending.join(", ")} se conservan. Resolvé cada ubicación y volvé a preparar el cambio`,
|
|
439
|
+
},
|
|
440
|
+
cleanup: null,
|
|
441
|
+
summary: `Falló '${proposal.operation}': ${err.message}`,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
async function run(ctx, proposal, before) {
|
|
445
|
+
const home = ctx.env.homeDir();
|
|
446
|
+
const id = randomUUID();
|
|
447
|
+
const journal = {
|
|
448
|
+
id,
|
|
449
|
+
operation: proposal.operation,
|
|
450
|
+
approvedDigest: proposal.digest,
|
|
451
|
+
owner: { pid: process.pid, ts: new Date().toISOString() },
|
|
452
|
+
destinations: [],
|
|
453
|
+
registryBefore: before,
|
|
454
|
+
registryWritten: false,
|
|
455
|
+
};
|
|
456
|
+
const expected = new Map(await Promise.all(proposal.additions.map(async (skill) => [skill.name, (await manifestDigest(skill.stagedAt)) ?? ""])));
|
|
457
|
+
let stagedSet;
|
|
458
|
+
try {
|
|
459
|
+
stagedSet = await stageDestinations(ctx, proposal, id);
|
|
460
|
+
}
|
|
461
|
+
catch (err) {
|
|
462
|
+
// Nothing was removed yet: the previous installation is intact. Every
|
|
463
|
+
// host's staging goes, not just the anchor's — each one lives next to its
|
|
464
|
+
// own root and would otherwise be left behind in the user's home.
|
|
465
|
+
for (const root of managedWorkRoots(home)) {
|
|
466
|
+
await rm(join(root, id), { recursive: true, force: true }).catch(() => { });
|
|
467
|
+
}
|
|
468
|
+
return {
|
|
469
|
+
status: "refused",
|
|
470
|
+
refusal: {
|
|
471
|
+
code: "STAGING_FAILED",
|
|
472
|
+
message: `no se pudo preparar el reemplazo: ${err.message}`,
|
|
473
|
+
action: "la instalación anterior quedó intacta; volvé a preparar el cambio",
|
|
474
|
+
},
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
await writeJournal(ctx, journal);
|
|
478
|
+
try {
|
|
479
|
+
for (const entry of stagedSet.filter((item) => item.destination.host !== "registry")) {
|
|
480
|
+
journal.destinations.push(await publish(entry, id));
|
|
481
|
+
await writeJournal(ctx, journal);
|
|
482
|
+
}
|
|
483
|
+
const registryDestination = stagedSet.find((item) => item.destination.host === "registry")?.destination;
|
|
484
|
+
if (registryDestination !== undefined) {
|
|
485
|
+
await writeRegistryAtomically(home, registryAfter(before, proposal, journal.destinations));
|
|
486
|
+
journal.registryWritten = true;
|
|
487
|
+
journal.destinations.push({
|
|
488
|
+
location: registryDestination.location,
|
|
489
|
+
host: "registry",
|
|
490
|
+
action: registryDestination.action,
|
|
491
|
+
status: "applied",
|
|
492
|
+
backup: null,
|
|
493
|
+
});
|
|
494
|
+
await writeJournal(ctx, journal);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
catch (err) {
|
|
498
|
+
return { status: "applied", result: await rollback(ctx, journal, proposal, before, err) };
|
|
499
|
+
}
|
|
500
|
+
const destinations = [];
|
|
501
|
+
for (const record of journal.destinations) {
|
|
502
|
+
destinations.push({
|
|
503
|
+
location: record.location,
|
|
504
|
+
host: record.host,
|
|
505
|
+
status: record.status,
|
|
506
|
+
verification: await verify(record, home, expected, proposal.proposedRegistry),
|
|
507
|
+
...(record.detail !== undefined ? { detail: record.detail } : {}),
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
const failedCheck = destinations.filter((result) => result.verification !== null && !result.verification.passed);
|
|
511
|
+
// A receipt is terminal only when every check passed; the backups go only
|
|
512
|
+
// then, and a cleanup failure never un-verifies bytes already checked.
|
|
513
|
+
const cleanupPending = failedCheck.length === 0 ? await cleanup(journal.destinations, home, id) : [];
|
|
514
|
+
if (failedCheck.length === 0) {
|
|
515
|
+
await rm(skillsJournalPath(home), { force: true }).catch(() => { });
|
|
516
|
+
}
|
|
517
|
+
else {
|
|
518
|
+
journal.destinations = journal.destinations.map((record) => ({
|
|
519
|
+
...record,
|
|
520
|
+
status: failedCheck.some((result) => result.location === record.location)
|
|
521
|
+
? "failed"
|
|
522
|
+
: record.status,
|
|
523
|
+
}));
|
|
524
|
+
await writeJournal(ctx, journal);
|
|
525
|
+
}
|
|
526
|
+
return {
|
|
527
|
+
status: "applied",
|
|
528
|
+
result: {
|
|
529
|
+
operation: proposal.operation,
|
|
530
|
+
digest: proposal.digest,
|
|
531
|
+
destinations,
|
|
532
|
+
recovery: failedCheck.length === 0
|
|
533
|
+
? null
|
|
534
|
+
: {
|
|
535
|
+
restored: [],
|
|
536
|
+
pending: failedCheck.map((result) => result.location),
|
|
537
|
+
action: "los respaldos se conservan: comprobá esas ubicaciones y volvé a preparar el cambio",
|
|
538
|
+
},
|
|
539
|
+
cleanup: cleanupPending.length > 0 ? { pending: cleanupPending } : null,
|
|
540
|
+
summary: failedCheck.length === 0
|
|
541
|
+
? `'${proposal.operation}' aplicada y comprobada en ${destinations.length} ubicaciones.`
|
|
542
|
+
: `'${proposal.operation}' aplicada con ${failedCheck.length} comprobación(es) fallida(s).`,
|
|
543
|
+
},
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Resolves the operation a previous run left pending.
|
|
548
|
+
*
|
|
549
|
+
* `restore` puts every applied destination back from its backup; `discard`
|
|
550
|
+
* accepts the current state and drops the journal. Neither repeats an effect:
|
|
551
|
+
* a new attempt needs a new proposal, because the bytes and the destinations
|
|
552
|
+
* are what an approval covers.
|
|
553
|
+
*/
|
|
554
|
+
export async function recoverSkillJournal(ctx, choice) {
|
|
555
|
+
const home = ctx.env.homeDir();
|
|
556
|
+
const journal = await readSkillJournal(ctx);
|
|
557
|
+
if (journal === null) {
|
|
558
|
+
return {
|
|
559
|
+
status: "refused",
|
|
560
|
+
refusal: { code: "NO_JOURNAL", message: "no hay ninguna operación pendiente" },
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
const lock = await acquireLock(join(home, ".agents", LOCK_FILE), ctx.fs, {
|
|
564
|
+
waitMs: LOCK_WAIT_MS,
|
|
565
|
+
});
|
|
566
|
+
try {
|
|
567
|
+
if (choice === "discard") {
|
|
568
|
+
const pending = await cleanup(journal.destinations, home, journal.id);
|
|
569
|
+
await rm(skillsJournalPath(home), { force: true }).catch(() => { });
|
|
570
|
+
return {
|
|
571
|
+
status: "applied",
|
|
572
|
+
result: {
|
|
573
|
+
operation: journal.operation,
|
|
574
|
+
digest: journal.approvedDigest,
|
|
575
|
+
destinations: journal.destinations.map((record) => ({
|
|
576
|
+
location: record.location,
|
|
577
|
+
host: record.host,
|
|
578
|
+
status: record.status,
|
|
579
|
+
verification: null,
|
|
580
|
+
})),
|
|
581
|
+
recovery: null,
|
|
582
|
+
cleanup: pending.length > 0 ? { pending } : null,
|
|
583
|
+
summary: `Se aceptó el estado actual de '${journal.operation}' y se descartó su journal.`,
|
|
584
|
+
},
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
const recovery = await compensate(journal.destinations);
|
|
588
|
+
if (journal.registryWritten) {
|
|
589
|
+
await writeRegistryAtomically(home, journal.registryBefore).catch(() => recovery.pending.push("registry"));
|
|
590
|
+
}
|
|
591
|
+
if (recovery.pending.length === 0) {
|
|
592
|
+
await rm(skillsJournalPath(home), { force: true }).catch(() => { });
|
|
593
|
+
}
|
|
594
|
+
return {
|
|
595
|
+
status: "applied",
|
|
596
|
+
result: {
|
|
597
|
+
operation: journal.operation,
|
|
598
|
+
digest: journal.approvedDigest,
|
|
599
|
+
destinations: journal.destinations.map((record) => ({
|
|
600
|
+
location: record.location,
|
|
601
|
+
host: record.host,
|
|
602
|
+
status: recovery.pending.includes(record.location) ? "failed" : "restored",
|
|
603
|
+
verification: null,
|
|
604
|
+
})),
|
|
605
|
+
recovery: {
|
|
606
|
+
restored: recovery.restored,
|
|
607
|
+
pending: recovery.pending,
|
|
608
|
+
action: recovery.pending.length === 0
|
|
609
|
+
? "se restauró el estado anterior de la operación pendiente"
|
|
610
|
+
: `estado mixto: los respaldos de ${recovery.pending.join(", ")} se conservan`,
|
|
611
|
+
},
|
|
612
|
+
cleanup: null,
|
|
613
|
+
summary: recovery.pending.length === 0
|
|
614
|
+
? `Se restauró el estado previo a '${journal.operation}'.`
|
|
615
|
+
: `Restauración parcial de '${journal.operation}': quedan ubicaciones por resolver.`,
|
|
616
|
+
},
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
finally {
|
|
620
|
+
await lock.release();
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
//# sourceMappingURL=skills-apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills-apply.js","sourceRoot":"","sources":["../../../src/application/self/skills-apply.ts"],"names":[],"mappings":"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"}
|