agent-kitchen 0.6.0 → 0.8.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/commands/sync.d.ts +5 -4
- package/dist/commands/sync.js +63 -64
- package/dist/commit-texts.d.ts +18 -0
- package/dist/commit-texts.js +29 -0
- package/dist/git-finish.js +2 -3
- package/dist/menu.js +2 -1
- package/dist/piece.d.ts +8 -2
- package/dist/pieces/agents-md.js +1 -3
- package/dist/pieces/cloud.js +2 -2
- package/dist/pieces/guard.js +3 -3
- package/dist/pieces/issue-flow.js +6 -6
- package/dist/pieces/skills-manager.js +3 -3
- package/dist/pieces/skills.js +3 -4
- package/dist/progress.d.ts +30 -0
- package/dist/progress.js +76 -0
- package/dist/repo.d.ts +7 -0
- package/dist/repo.js +10 -0
- package/dist/texts/catalog.d.ts +50 -0
- package/dist/texts/catalog.js +1 -0
- package/dist/texts/es.d.ts +7 -0
- package/dist/texts/es.js +139 -0
- package/dist/texts/index.d.ts +30 -0
- package/dist/texts/index.js +31 -0
- package/dist/texts/step-text.d.ts +85 -0
- package/dist/texts/step-text.js +7 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -59,7 +59,7 @@ npx agent-kitchen doctor # revisa cada pieza con su propio
|
|
|
59
59
|
|
|
60
60
|
- **Sin terminal y sin `--yes`** (por ejemplo, desde un agente), solo muestra lo que ofrecería.
|
|
61
61
|
- **Corre en el checkout principal,** no en un worktree, y desde tu terminal. Dentro de una sesión de Claude, el sandbox de `claude-repo-guard` no deja escribir `.claude/settings.json`.
|
|
62
|
-
- **Al terminar,** corre el `install` de tu gestor de paquetes
|
|
62
|
+
- **Al terminar,** si los pasos cambiaron `package.json`, corre el `install` de tu gestor de paquetes. Te queda revisar el diff y hacer commit. O usa `--commit`.
|
|
63
63
|
|
|
64
64
|
**`--commit`** deja los cambios commiteados sin que lo haga un agente:
|
|
65
65
|
|
package/dist/commands/sync.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Output } from "../output.js";
|
|
2
|
+
import type { Step } from "../piece.js";
|
|
2
3
|
/** Options of the command. */
|
|
3
4
|
export interface SyncOptions {
|
|
4
5
|
cwd: string;
|
|
@@ -26,13 +27,13 @@ export declare function pieceNames(): string[];
|
|
|
26
27
|
export declare function noStepsMessage(why: "leave" | "none", wrote: boolean): string;
|
|
27
28
|
/**
|
|
28
29
|
* What the commit of `--commit` lists: the steps that worked, and the decisions file if this
|
|
29
|
-
* run wrote it.
|
|
30
|
-
* @param done - The
|
|
30
|
+
* run wrote it, in the commit's texts (not the interface's).
|
|
31
|
+
* @param done - The steps that worked.
|
|
31
32
|
* @param wrote - Whether the decisions file was written in this run.
|
|
32
|
-
* @returns The
|
|
33
|
+
* @returns The lines.
|
|
33
34
|
* @example commitLabels([], true) // ["Guardar qué piezas usa el repo en .agents/kitchen.json"]
|
|
34
35
|
*/
|
|
35
|
-
export declare function commitLabels(done:
|
|
36
|
+
export declare function commitLabels(done: Pick<Step, "text">[], wrote: boolean): string[];
|
|
36
37
|
/**
|
|
37
38
|
* Runs the command; see the file's header.
|
|
38
39
|
* @param options - The options.
|
package/dist/commands/sync.js
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* flow's version), one line each, with the
|
|
12
12
|
* tools' output only when one fails; one that fails does not stop the rest. With `--yes`
|
|
13
13
|
* it does what is suggested without asking (and keeps the repo's own skills); without a
|
|
14
|
-
* terminal it only shows the steps.
|
|
14
|
+
* terminal it only shows the steps. Without `--commit`, it installs at the end if the steps
|
|
15
|
+
* changed package.json. With `--commit` it first checks the repo is clean and on
|
|
15
16
|
* its base branch, and at the end installs if package.json changed and asks what to do with
|
|
16
17
|
* the changes (see git-finish.ts), also when the only change is the decisions file below;
|
|
17
18
|
* the steps then show as plain lines, since a spinner before a question leaves it deaf.
|
|
@@ -23,7 +24,6 @@
|
|
|
23
24
|
* `--pieces` (terminal only, not with `--yes` or `--dry-run`) first asks which pieces the repo
|
|
24
25
|
* uses, writes all of them to the file, and then goes on as usual.
|
|
25
26
|
*/
|
|
26
|
-
import { spinner } from "@clack/prompts";
|
|
27
27
|
import { DECIDABLE, decide, DECISIONS, off, readDecisions, undecided, writeDecisions } from "../decisions.js";
|
|
28
28
|
import { baseBranch, branchName, changedPaths, checkReady, finish } from "../git-finish.js";
|
|
29
29
|
import { askFinish, askPath, askPieces, askReplace, askSkills, askSteps } from "../menu.js";
|
|
@@ -34,8 +34,11 @@ import { issueFlowStatus, NAME as FLOW } from "../pieces/issue-flow.js";
|
|
|
34
34
|
import { keepOwn, NAME as SKILLS, ownInPick, skillsStatus } from "../pieces/skills.js";
|
|
35
35
|
import { agentsMdStatus, NAME as AGENTS_MD } from "../pieces/agents-md.js";
|
|
36
36
|
import { NAME as SKILLS_MANAGER, skillsManagerStatus } from "../pieces/skills-manager.js";
|
|
37
|
-
import { mainCheckout, packageManager } from "../repo.js";
|
|
37
|
+
import { mainCheckout, packageManager, packageText } from "../repo.js";
|
|
38
38
|
import { download, failedOutput, runInstall, setVerbose } from "../tools.js";
|
|
39
|
+
import { commitLine, DECISIONS_LINE } from "../commit-texts.js";
|
|
40
|
+
import { progressFor } from "../progress.js";
|
|
41
|
+
import { phrases, stepLabel, ui } from "../texts/index.js";
|
|
39
42
|
/** Every piece, in the order its steps run. */
|
|
40
43
|
const PIECES = [SKILLS_MANAGER, FLOW, CLOUD, GUARD, SKILLS, AGENTS_MD];
|
|
41
44
|
/**
|
|
@@ -115,9 +118,7 @@ function saveDecisions(root, saved, statuses, chosen, commits, out) {
|
|
|
115
118
|
* @example noStepsMessage("none", true) // "No elegiste pasos; solo guardé qué piezas usa el repo.\n"
|
|
116
119
|
*/
|
|
117
120
|
export function noStepsMessage(why, wrote) {
|
|
118
|
-
|
|
119
|
-
return wrote ? "No corrí ningún paso; solo guardé qué piezas usa el repo.\n" : "No se cambió nada.\n";
|
|
120
|
-
return wrote ? "No elegiste pasos; solo guardé qué piezas usa el repo.\n" : "No elegiste nada; no se cambió nada.\n";
|
|
121
|
+
return `${ui.noSteps(why, wrote)}\n`;
|
|
121
122
|
}
|
|
122
123
|
/**
|
|
123
124
|
* The line that says the decisions were saved.
|
|
@@ -125,20 +126,19 @@ export function noStepsMessage(why, wrote) {
|
|
|
125
126
|
* @returns The line.
|
|
126
127
|
*/
|
|
127
128
|
function savedMessage(commits) {
|
|
128
|
-
return
|
|
129
|
+
return `${ui.saved(DECISIONS, commits)}\n`;
|
|
129
130
|
}
|
|
130
|
-
/** The line the commit of `--commit` adds for the decisions file. */
|
|
131
|
-
const DECISIONS_STEP = `Guardar qué piezas usa el repo en ${DECISIONS}`;
|
|
132
131
|
/**
|
|
133
132
|
* What the commit of `--commit` lists: the steps that worked, and the decisions file if this
|
|
134
|
-
* run wrote it.
|
|
135
|
-
* @param done - The
|
|
133
|
+
* run wrote it, in the commit's texts (not the interface's).
|
|
134
|
+
* @param done - The steps that worked.
|
|
136
135
|
* @param wrote - Whether the decisions file was written in this run.
|
|
137
|
-
* @returns The
|
|
136
|
+
* @returns The lines.
|
|
138
137
|
* @example commitLabels([], true) // ["Guardar qué piezas usa el repo en .agents/kitchen.json"]
|
|
139
138
|
*/
|
|
140
139
|
export function commitLabels(done, wrote) {
|
|
141
|
-
|
|
140
|
+
const lines = done.map((step) => commitLine(step.text));
|
|
141
|
+
return wrote ? [...lines, DECISIONS_LINE] : lines;
|
|
142
142
|
}
|
|
143
143
|
/**
|
|
144
144
|
* Asks which pieces the repo uses and writes the answer for every decidable piece.
|
|
@@ -149,7 +149,7 @@ export function commitLabels(done, wrote) {
|
|
|
149
149
|
* @returns False if the person cancelled.
|
|
150
150
|
*/
|
|
151
151
|
async function choosePieces(root, saved, commits, out) {
|
|
152
|
-
out.stdout(
|
|
152
|
+
out.stdout(`${ui.checking}\n`);
|
|
153
153
|
// No skip here: an installed, undecided piece passed in --skip still starts ticked.
|
|
154
154
|
const statuses = await statusesOf(root, []);
|
|
155
155
|
const ticked = DECIDABLE.filter((name) => saved?.pieces[name] === true || (saved?.pieces[name] === undefined && statuses.some((status) => status.name === name && status.installed)));
|
|
@@ -173,7 +173,7 @@ function keepOwnSkills(root, step, out) {
|
|
|
173
173
|
if (own.length === 0)
|
|
174
174
|
return;
|
|
175
175
|
Object.assign(step.skills, keepOwn(step.skills, own));
|
|
176
|
-
out.stdout(
|
|
176
|
+
out.stdout(`${ui.ownSkillsKept(own)}\n`);
|
|
177
177
|
}
|
|
178
178
|
/**
|
|
179
179
|
* Asks, for a step that installs skills, which ones, and whether to replace the repo's own.
|
|
@@ -217,14 +217,13 @@ async function chooseSteps(root, steps, options, out) {
|
|
|
217
217
|
const suggested = steps.filter((step) => step.checked);
|
|
218
218
|
if (options.yes) {
|
|
219
219
|
if (suggested.length === 0)
|
|
220
|
-
out.stdout(
|
|
220
|
+
out.stdout(`${ui.onlyOptional(steps.map(stepLabel))}\n`);
|
|
221
221
|
for (const step of suggested)
|
|
222
222
|
keepOwnSkills(root, step, out);
|
|
223
223
|
return suggested;
|
|
224
224
|
}
|
|
225
225
|
if (options.dryRun || !out.interactive) {
|
|
226
|
-
|
|
227
|
-
out.stdout(`Pasos sugeridos${hint}:\n${steps.map((step) => ` [${step.checked ? "x" : " "}] ${step.label}\n`).join("")}`);
|
|
226
|
+
out.stdout(`${ui.suggested(options.dryRun)}\n${steps.map((step) => ` [${step.checked ? "x" : " "}] ${stepLabel(step)}\n`).join("")}`);
|
|
228
227
|
return null;
|
|
229
228
|
}
|
|
230
229
|
for (const step of suggested)
|
|
@@ -242,22 +241,6 @@ async function chooseSteps(root, steps, options, out) {
|
|
|
242
241
|
}
|
|
243
242
|
return chosen;
|
|
244
243
|
}
|
|
245
|
-
/**
|
|
246
|
-
* How progress is shown: a spinner in a terminal (unless the tools print with
|
|
247
|
-
* `--verbose`), plain lines otherwise. Only for the steps, after every question: a spinner
|
|
248
|
-
* shown before a question leaves the second question deaf to the keyboard (@clack/prompts
|
|
249
|
-
* 1.8.1).
|
|
250
|
-
* @param out - Where to write.
|
|
251
|
-
* @param verbose - Whether the tools print on the terminal.
|
|
252
|
-
* @returns The progress.
|
|
253
|
-
*/
|
|
254
|
-
function progressFor(out, verbose) {
|
|
255
|
-
if (out.interactive && !verbose) {
|
|
256
|
-
const spin = spinner();
|
|
257
|
-
return { start: (text) => spin.start(text), stop: (text, ok) => (ok ? spin.stop(text) : spin.error(text)) };
|
|
258
|
-
}
|
|
259
|
-
return { start: (text) => out.stdout(`→ ${text}\n`), stop: (text, ok) => out.stdout(`${ok ? "✓" : "✗"} ${text}\n`) };
|
|
260
|
-
}
|
|
261
244
|
/**
|
|
262
245
|
* Runs one step and shows how it went: its notes, and what to do if it failed.
|
|
263
246
|
* @param root - The repo.
|
|
@@ -275,19 +258,21 @@ async function runStep(root, step, progress, out) {
|
|
|
275
258
|
note: (text) => notes.push(text),
|
|
276
259
|
fail: (text, output) => failures.push(` ${text}\n${output === undefined ? "" : failedOutput(output)}`),
|
|
277
260
|
};
|
|
278
|
-
progress.start(step.
|
|
279
|
-
await Promise.all(step.downloads.map((spec) => download(root, spec)));
|
|
261
|
+
progress.start(step.text);
|
|
280
262
|
let ok;
|
|
281
263
|
try {
|
|
264
|
+
await Promise.all(step.downloads.map((spec) => download(root, spec)));
|
|
282
265
|
ok = await step.run(context);
|
|
283
266
|
}
|
|
284
267
|
catch (error) {
|
|
285
|
-
if (!(error instanceof KitError))
|
|
268
|
+
if (!(error instanceof KitError)) {
|
|
269
|
+
progress.stop(step.text, false);
|
|
286
270
|
throw error;
|
|
271
|
+
}
|
|
287
272
|
failures.push(` ${error.message}\n`);
|
|
288
273
|
ok = false;
|
|
289
274
|
}
|
|
290
|
-
progress.stop(step.
|
|
275
|
+
progress.stop(step.text, ok);
|
|
291
276
|
for (const note of notes)
|
|
292
277
|
out.stdout(` · ${note}\n`);
|
|
293
278
|
for (const failure of failures)
|
|
@@ -333,32 +318,33 @@ export async function sync(options, out) {
|
|
|
333
318
|
const asks = out.interactive && !options.yes && !options.dryRun;
|
|
334
319
|
const saves = asks && options.skip.length === 0;
|
|
335
320
|
if (out.interactive)
|
|
336
|
-
out.stdout(
|
|
321
|
+
out.stdout(`${ui.checking}\n`);
|
|
337
322
|
let statuses = await statusesOf(root, skip);
|
|
338
323
|
if (saved !== null && !asks && !options.dryRun) {
|
|
339
324
|
const left = undecided(saved).filter((name) => statuses.some((status) => status.name === name && !status.installed));
|
|
340
325
|
if (left.length > 0) {
|
|
341
326
|
skip.push(...left);
|
|
342
327
|
statuses = await statusesOf(root, skip);
|
|
343
|
-
out.stdout(
|
|
328
|
+
out.stdout(`${ui.undecided(left)}\n`);
|
|
344
329
|
}
|
|
345
330
|
}
|
|
346
331
|
if (saved !== null) {
|
|
347
332
|
const fresh = undecided(saved);
|
|
348
333
|
for (const status of statuses.filter((each) => fresh.includes(each.name))) {
|
|
349
|
-
status.state +=
|
|
334
|
+
status.state += ui.fresh;
|
|
350
335
|
for (const step of status.steps)
|
|
351
|
-
step.
|
|
336
|
+
step.fresh = true;
|
|
352
337
|
}
|
|
353
338
|
}
|
|
354
339
|
printStatus(statuses, off(saved).filter((name) => !options.skip.includes(name)), out);
|
|
355
340
|
const steps = statuses.flatMap((status) => status.steps);
|
|
356
341
|
// With --commit, a run that only wrote the decisions file still ends with the question.
|
|
357
|
-
const
|
|
342
|
+
const progress = progressFor(out, options.verbose, base !== null);
|
|
343
|
+
const endWithoutSteps = async () => (base !== null && wrote ? commitChanges(root, base, commitLabels([], true), [], progress, options, out) : 0);
|
|
358
344
|
if (steps.length === 0) {
|
|
359
345
|
if (saves)
|
|
360
346
|
wrote = saveDecisions(root, saved, statuses, [], base !== null, out) || wrote;
|
|
361
|
-
out.stdout(
|
|
347
|
+
out.stdout(`${ui.upToDate}\n`);
|
|
362
348
|
return endWithoutSteps();
|
|
363
349
|
}
|
|
364
350
|
const chosen = await chooseSteps(root, steps, options, out);
|
|
@@ -382,31 +368,51 @@ export async function sync(options, out) {
|
|
|
382
368
|
out.stdout(noStepsMessage("none", wrote));
|
|
383
369
|
return endWithoutSteps();
|
|
384
370
|
}
|
|
385
|
-
const
|
|
386
|
-
const
|
|
371
|
+
const pkgBefore = packageText(root);
|
|
372
|
+
const failedSteps = [];
|
|
387
373
|
for (const step of chosen) {
|
|
388
374
|
if (!(await runStep(root, step, progress, out)))
|
|
389
|
-
|
|
375
|
+
failedSteps.push(step);
|
|
390
376
|
}
|
|
377
|
+
const failed = failedSteps.map(stepLabel);
|
|
391
378
|
if (base !== null)
|
|
392
|
-
return commitChanges(root, base, commitLabels(chosen.filter((step) => !
|
|
393
|
-
const
|
|
394
|
-
|
|
379
|
+
return commitChanges(root, base, commitLabels(chosen.filter((step) => !failedSteps.includes(step)), wrote), failed, progress, options, out);
|
|
380
|
+
const installFailed = packageText(root) !== pkgBefore ? !(await install(root, progress, out)) : false;
|
|
381
|
+
if (installFailed)
|
|
382
|
+
failed.push(phrases({ kind: "install-deps", manager: packageManager(root) }).menu);
|
|
383
|
+
out.stdout(`\n${ui.summary(failed)} ${ui.next(installFailed ? packageManager(root) : null)}\n`);
|
|
395
384
|
return failed.length === 0 ? 0 : 1;
|
|
396
385
|
}
|
|
386
|
+
/**
|
|
387
|
+
* Runs the repo's install with the same progress as a step, and shows its output if it fails.
|
|
388
|
+
* @param root - The repo.
|
|
389
|
+
* @param progress - How progress is shown.
|
|
390
|
+
* @param out - Where to write.
|
|
391
|
+
* @returns Whether it worked.
|
|
392
|
+
*/
|
|
393
|
+
async function install(root, progress, out) {
|
|
394
|
+
const text = { kind: "install-deps", manager: packageManager(root) };
|
|
395
|
+
progress.start(text);
|
|
396
|
+
const installed = await runInstall(root, text.manager);
|
|
397
|
+
progress.stop(text, installed.ok);
|
|
398
|
+
if (!installed.ok)
|
|
399
|
+
out.stderr(failedOutput(installed.output));
|
|
400
|
+
return installed.ok;
|
|
401
|
+
}
|
|
397
402
|
/**
|
|
398
403
|
* The end of `--commit`: the install if package.json changed, the changes, the question (or
|
|
399
404
|
* the branch with a PR under --yes) and what git did.
|
|
400
405
|
* @param root - The repo.
|
|
401
406
|
* @param base - The base branch.
|
|
402
|
-
* @param done - What the commit lists: the
|
|
403
|
-
* @param failed - The
|
|
407
|
+
* @param done - What the commit lists: the steps that worked, and the decisions file if written.
|
|
408
|
+
* @param failed - The steps that failed, as the interface names them.
|
|
409
|
+
* @param progress - How progress is shown, for the install.
|
|
404
410
|
* @param options - The options.
|
|
405
411
|
* @param out - Where to write and ask.
|
|
406
412
|
* @returns 0, or 1 if a step, the install or git failed.
|
|
407
413
|
*/
|
|
408
|
-
async function commitChanges(root, base, done, failed, options, out) {
|
|
409
|
-
const summary =
|
|
414
|
+
async function commitChanges(root, base, done, failed, progress, options, out) {
|
|
415
|
+
const summary = ui.summary(failed);
|
|
410
416
|
const changed = changedPaths(root);
|
|
411
417
|
if (changed.length === 0) {
|
|
412
418
|
out.stdout(`\n${summary} No cambió ningún archivo: no hay nada que commitear.\n`);
|
|
@@ -414,16 +420,9 @@ async function commitChanges(root, base, done, failed, options, out) {
|
|
|
414
420
|
}
|
|
415
421
|
const manager = packageManager(root);
|
|
416
422
|
const packageChanged = changed.includes("package.json");
|
|
417
|
-
if (packageChanged) {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
const installed = await runInstall(root, manager);
|
|
421
|
-
out.stdout(`${installed.ok ? "✓" : "✗"} ${label}\n`);
|
|
422
|
-
if (!installed.ok) {
|
|
423
|
-
out.stderr(failedOutput(installed.output));
|
|
424
|
-
out.stdout(`\n${summary} No commiteé: el install falló y los cambios quedan sin commit.\n`);
|
|
425
|
-
return 1;
|
|
426
|
-
}
|
|
423
|
+
if (packageChanged && !(await install(root, progress, out))) {
|
|
424
|
+
out.stdout(`\n${summary} No commiteé: el install falló y los cambios quedan sin commit.\n`);
|
|
425
|
+
return 1;
|
|
427
426
|
}
|
|
428
427
|
const paths = changedPaths(root);
|
|
429
428
|
out.stdout(`\n${summary} Cambios:\n${paths.map((path) => ` ${path}`).join("\n")}\n`);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { StepText } from "./texts/step-text.js";
|
|
2
|
+
/** The subject of the commit and the title of the PR. */
|
|
3
|
+
export declare const COMMIT_TITLE = "chore: agent-kitchen apply";
|
|
4
|
+
/** The line of the decisions file. */
|
|
5
|
+
export declare const DECISIONS_LINE = "Guardar qu\u00E9 piezas usa el repo en .agents/kitchen.json";
|
|
6
|
+
/**
|
|
7
|
+
* A step's line in the commit and the PR.
|
|
8
|
+
* @param text - What the step does.
|
|
9
|
+
* @returns The line, without the dash.
|
|
10
|
+
* @example commitLine({ kind: "flow-install", version: "0.2.0" }) // "Instalar issue-flow 0.2.0: config del flujo, hooks y scripts"
|
|
11
|
+
*/
|
|
12
|
+
export declare function commitLine(text: StepText): string;
|
|
13
|
+
/**
|
|
14
|
+
* The body of the PR.
|
|
15
|
+
* @param lines - What the commit lists.
|
|
16
|
+
* @returns The body.
|
|
17
|
+
*/
|
|
18
|
+
export declare function prBody(lines: string[]): string;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The texts of the commit and the PR of `apply --commit`. They are always in Spanish,
|
|
3
|
+
* whatever language the interface shows: a repo's history should not change language with the
|
|
4
|
+
* terminal of whoever ran the command. A step reads as its Spanish menu order.
|
|
5
|
+
*/
|
|
6
|
+
import { DECISIONS } from "./decisions.js";
|
|
7
|
+
import { es } from "./texts/es.js";
|
|
8
|
+
import { phrasesIn } from "./texts/index.js";
|
|
9
|
+
/** The subject of the commit and the title of the PR. */
|
|
10
|
+
export const COMMIT_TITLE = "chore: agent-kitchen apply";
|
|
11
|
+
/** The line of the decisions file. */
|
|
12
|
+
export const DECISIONS_LINE = `Guardar qué piezas usa el repo en ${DECISIONS}`;
|
|
13
|
+
/**
|
|
14
|
+
* A step's line in the commit and the PR.
|
|
15
|
+
* @param text - What the step does.
|
|
16
|
+
* @returns The line, without the dash.
|
|
17
|
+
* @example commitLine({ kind: "flow-install", version: "0.2.0" }) // "Instalar issue-flow 0.2.0: config del flujo, hooks y scripts"
|
|
18
|
+
*/
|
|
19
|
+
export function commitLine(text) {
|
|
20
|
+
return phrasesIn(es, text).menu;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The body of the PR.
|
|
24
|
+
* @param lines - What the commit lists.
|
|
25
|
+
* @returns The body.
|
|
26
|
+
*/
|
|
27
|
+
export function prBody(lines) {
|
|
28
|
+
return `Cambios de \`agent-kitchen apply\`:\n\n${lines.map((line) => `- ${line}`).join("\n")}\n`;
|
|
29
|
+
}
|
package/dist/git-finish.js
CHANGED
|
@@ -10,12 +10,11 @@ import { spawnSync } from "node:child_process";
|
|
|
10
10
|
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
11
11
|
import { tmpdir } from "node:os";
|
|
12
12
|
import { join, relative } from "node:path";
|
|
13
|
+
import { COMMIT_TITLE as TITLE, prBody } from "./commit-texts.js";
|
|
13
14
|
import { KitError } from "./output.js";
|
|
14
15
|
import { FLOW_CONFIG } from "./piece.js";
|
|
15
16
|
import { dependencyVersion, readJson } from "./repo.js";
|
|
16
17
|
import { captureNpxWithout, isRelease, npmLatest } from "./tools.js";
|
|
17
|
-
/** The subject of the commit and the title of the PR. */
|
|
18
|
-
const TITLE = "chore: agent-kitchen apply";
|
|
19
18
|
/** github-rest on npm, which opens the PR (REST, never gh's GraphQL). */
|
|
20
19
|
const GITHUB_REST = "@ramon-sg/github-rest";
|
|
21
20
|
/**
|
|
@@ -153,7 +152,7 @@ async function openPr(root, branch, base, steps) {
|
|
|
153
152
|
return { error: `no sé qué versión de ${GITHUB_REST} usar.` };
|
|
154
153
|
const dir = mkdtempSync(join(tmpdir(), "agent-kitchen-pr-"));
|
|
155
154
|
const bodyFile = join(dir, "body.md");
|
|
156
|
-
writeFileSync(bodyFile,
|
|
155
|
+
writeFileSync(bodyFile, prBody(steps));
|
|
157
156
|
try {
|
|
158
157
|
const result = await captureNpxWithout(root, [`${GITHUB_REST}@${version}`, "pr", "create", "--head", branch, "--base", base, "--title", TITLE, "--body-file", bodyFile], ["GH_REPO"]);
|
|
159
158
|
const url = result.out.trim().split("\n").at(-1) ?? "";
|
package/dist/menu.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { styleText } from "node:util";
|
|
8
8
|
import { confirm, groupMultiselect, isCancel, MULTISELECT_INSTRUCTIONS, multiselect, select, SELECT_INSTRUCTIONS } from "@clack/prompts";
|
|
9
|
+
import { stepLabel } from "./texts/index.js";
|
|
9
10
|
/** Width a skill's description is cut to in the menu. */
|
|
10
11
|
const DESCRIPTION_WIDTH = 70;
|
|
11
12
|
/**
|
|
@@ -24,7 +25,7 @@ function spanishKeys() {
|
|
|
24
25
|
*/
|
|
25
26
|
export function menuOptions(steps) {
|
|
26
27
|
return {
|
|
27
|
-
options: steps.map((step, index) => ({ value: index, label: step
|
|
28
|
+
options: steps.map((step, index) => ({ value: index, label: stepLabel(step) })),
|
|
28
29
|
initialValues: steps.flatMap((step, index) => (step.checked ? [index] : [])),
|
|
29
30
|
};
|
|
30
31
|
}
|
package/dist/piece.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* writes the few lines that join two pieces, the one line of AGENTS.md, which has no tool,
|
|
8
8
|
* and the version of skills-manager in package.json, which agent-kitchen is the one to run.
|
|
9
9
|
*/
|
|
10
|
+
import type { StepText } from "./texts/step-text.js";
|
|
10
11
|
/** The issue flow on npm. */
|
|
11
12
|
export declare const FLOW_PACKAGE = "@ramon-sg/issue-flow";
|
|
12
13
|
/** The GitHub repo of the issue flow, which is also the catalog of its skills. */
|
|
@@ -36,10 +37,15 @@ export interface SkillPick {
|
|
|
36
37
|
picked: string[];
|
|
37
38
|
replace: string[];
|
|
38
39
|
}
|
|
39
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* One step a piece offers: what it does (as data; texts/ turns it into words for each place
|
|
42
|
+
* it shows), what it downloads, and how it runs. `fresh` marks a step of a piece the repo has
|
|
43
|
+
* not decided on yet.
|
|
44
|
+
*/
|
|
40
45
|
export interface Step {
|
|
41
46
|
piece: string;
|
|
42
|
-
|
|
47
|
+
text: StepText;
|
|
48
|
+
fresh?: boolean;
|
|
43
49
|
checked: boolean;
|
|
44
50
|
downloads: string[];
|
|
45
51
|
skills?: SkillPick;
|
package/dist/pieces/agents-md.js
CHANGED
|
@@ -100,10 +100,8 @@ export async function agentsMdStatus(root, flowComing) {
|
|
|
100
100
|
const summary = "regla de versiones instaladas en AGENTS.md";
|
|
101
101
|
if (!lack.rule && !lack.import)
|
|
102
102
|
return { name: NAME, summary, installed: true, state: "al día", steps: [] };
|
|
103
|
-
const files = [...(lack.rule ? ["AGENTS.md"] : []), ...(lack.import ? ["CLAUDE.md"] : [])];
|
|
104
|
-
const label = lack.rule ? `Agregar a AGENTS.md la regla de versiones instaladas${lack.import ? " (y @AGENTS.md en CLAUDE.md)" : ""}` : "Agregar @AGENTS.md a CLAUDE.md, para que Claude Code lea AGENTS.md";
|
|
105
103
|
const state = lack.rule ? "falta la regla" : "CLAUDE.md no importa AGENTS.md";
|
|
106
|
-
return { name: NAME, summary, installed: !lack.rule, state, steps: [{ piece: NAME, checked: true, downloads: [],
|
|
104
|
+
return { name: NAME, summary, installed: !lack.rule, state, steps: [{ piece: NAME, checked: true, downloads: [], text: { kind: "agents-md", rule: lack.rule, claudeImport: lack.import }, run: async (context) => write(context) }] };
|
|
107
105
|
}
|
|
108
106
|
/**
|
|
109
107
|
* Whether AGENTS.md has the rule and CLAUDE.md, if there is one, imports it. Only noted.
|
package/dist/pieces/cloud.js
CHANGED
|
@@ -28,7 +28,7 @@ function stepFor(config, latest) {
|
|
|
28
28
|
piece: NAME,
|
|
29
29
|
checked: true,
|
|
30
30
|
downloads: [spec],
|
|
31
|
-
|
|
31
|
+
text: { kind: "cloud-install", version: latest },
|
|
32
32
|
run: async (context) => {
|
|
33
33
|
const run = await runNpx(context.root, [spec, "init"]);
|
|
34
34
|
if (run.ok)
|
|
@@ -44,7 +44,7 @@ function stepFor(config, latest) {
|
|
|
44
44
|
piece: NAME,
|
|
45
45
|
checked: true,
|
|
46
46
|
downloads: [],
|
|
47
|
-
|
|
47
|
+
text: { kind: "cloud-update", from: version, to: latest, config: CONFIG },
|
|
48
48
|
run: async (context) => {
|
|
49
49
|
const current = readJson(context.root, CONFIG) ?? {};
|
|
50
50
|
const schema = typeof current.$schema === "string" ? current.$schema.replace(/@ramon-sg\/claude-cloud@[^/]+\//, `${PACKAGE}@${latest}/`) : undefined;
|
package/dist/pieces/guard.js
CHANGED
|
@@ -141,11 +141,11 @@ function installedVersion(root) {
|
|
|
141
141
|
*/
|
|
142
142
|
function stepFor(root, installed, latest, flowComing) {
|
|
143
143
|
if (installed === undefined)
|
|
144
|
-
return { piece: NAME, checked: true, downloads: [guardSpec(latest)],
|
|
144
|
+
return { piece: NAME, checked: true, downloads: [guardSpec(latest)], text: { kind: "guard-install", version: latest }, run: (context) => install(context, latest) };
|
|
145
145
|
if (latest !== null && (installed === null || compareVersions(latest, installed) > 0))
|
|
146
|
-
return { piece: NAME, checked: true, downloads: [guardSpec(latest)],
|
|
146
|
+
return { piece: NAME, checked: true, downloads: [guardSpec(latest)], text: { kind: "guard-update", from: installed, to: latest }, run: (context) => install(context, latest) };
|
|
147
147
|
if (flowComing || guardOptions(root, process.platform).changes.length > 0)
|
|
148
|
-
return { piece: NAME, checked: true, downloads: [guardSpec(installed)],
|
|
148
|
+
return { piece: NAME, checked: true, downloads: [guardSpec(installed)], text: { kind: "guard-adjust" }, run: (context) => addOptions(context, installed) };
|
|
149
149
|
return null;
|
|
150
150
|
}
|
|
151
151
|
/**
|
|
@@ -197,7 +197,7 @@ async function missingLabels(root, version) {
|
|
|
197
197
|
* @returns The step.
|
|
198
198
|
*/
|
|
199
199
|
function labelsStep(version, missing) {
|
|
200
|
-
return { piece: NAME, checked: true, downloads: [`${FLOW_PACKAGE}@${version}`],
|
|
200
|
+
return { piece: NAME, checked: true, downloads: [`${FLOW_PACKAGE}@${version}`], text: { kind: "flow-labels", missing }, run: async (context) => {
|
|
201
201
|
if (flowVersion(context.root) !== version) {
|
|
202
202
|
context.note(`no se crearon: el repo no tiene issue-flow ${version}`);
|
|
203
203
|
return true;
|
|
@@ -233,7 +233,7 @@ function restStep(root, version, minimum) {
|
|
|
233
233
|
const current = dependencyVersion(readJson(root, "package.json"), GITHUB_REST);
|
|
234
234
|
if (!below(current))
|
|
235
235
|
return null;
|
|
236
|
-
return { piece: NAME, checked: true, downloads: [],
|
|
236
|
+
return { piece: NAME, checked: true, downloads: [], text: { kind: "github-rest-bump", from: current, to: minimum, flow: version }, run: async (context) => {
|
|
237
237
|
if (flowVersion(context.root) !== version)
|
|
238
238
|
context.note(`no se subió: el repo no tiene issue-flow ${version}`);
|
|
239
239
|
else if (!below(dependencyVersion(readJson(context.root, "package.json"), GITHUB_REST)))
|
|
@@ -256,16 +256,16 @@ function restStep(root, version, minimum) {
|
|
|
256
256
|
function stepFor(installed, latest, root, repair) {
|
|
257
257
|
if (installed === null && latest !== null) {
|
|
258
258
|
const run = usesApply(latest) ? async (context) => (await applyFlow(context, latest)) && (await moveSkills(context, latest)) : (context) => runFlow(context, latest, ["init", "--yes"]);
|
|
259
|
-
return { piece: NAME, checked: true, downloads: [`${FLOW_PACKAGE}@${latest}`],
|
|
259
|
+
return { piece: NAME, checked: true, downloads: [`${FLOW_PACKAGE}@${latest}`], text: { kind: "flow-install", version: latest }, run };
|
|
260
260
|
}
|
|
261
261
|
if (installed !== null && latest !== null && compareVersions(latest, installed) > 0) {
|
|
262
262
|
const update = (context) => (usesApply(latest) ? applyFlow(context, latest) : runFlow(context, latest, ["upgrade"]));
|
|
263
|
-
return { piece: NAME, checked: true, downloads: [`${FLOW_PACKAGE}@${latest}`],
|
|
263
|
+
return { piece: NAME, checked: true, downloads: [`${FLOW_PACKAGE}@${latest}`], text: { kind: "flow-update", from: installed, to: latest }, run: async (context) => (await update(context)) && (await moveSkills(context, latest)) };
|
|
264
264
|
}
|
|
265
265
|
if (installed !== null && repair)
|
|
266
|
-
return { piece: NAME, checked: true, downloads: [`${FLOW_PACKAGE}@${installed}`],
|
|
266
|
+
return { piece: NAME, checked: true, downloads: [`${FLOW_PACKAGE}@${installed}`], text: { kind: "flow-repair", version: installed }, run: async (context) => (await applyFlow(context, installed)) && (skillsOff(context.root, installed).length === 0 || (await moveSkills(context, installed))) };
|
|
267
267
|
if (installed !== null && skillsOff(root, installed).length > 0)
|
|
268
|
-
return { piece: NAME, checked: true, downloads: [],
|
|
268
|
+
return { piece: NAME, checked: true, downloads: [], text: { kind: "flow-skills", version: installed }, run: (context) => moveSkills(context, installed) };
|
|
269
269
|
return null;
|
|
270
270
|
}
|
|
271
271
|
/**
|
|
@@ -66,7 +66,7 @@ export function skillsManagerStatus(root, withSkills, flowComing) {
|
|
|
66
66
|
piece: NAME,
|
|
67
67
|
checked: true,
|
|
68
68
|
downloads: [`${SKILLS_MANAGER}@${MIN_VERSION}`],
|
|
69
|
-
|
|
69
|
+
text: { kind: "skills-manager-create", version: MIN_VERSION },
|
|
70
70
|
run: async (context) => {
|
|
71
71
|
if (readJson(context.root, "package.json") === null)
|
|
72
72
|
writeJson(context.root, "package.json", { private: true, devDependencies: { [SKILLS_MANAGER]: MIN_VERSION } });
|
|
@@ -85,13 +85,13 @@ export function skillsManagerStatus(root, withSkills, flowComing) {
|
|
|
85
85
|
}
|
|
86
86
|
if (now.kind === "exact" && !below(now.version))
|
|
87
87
|
return { name: NAME, summary, installed: true, state: `${now.version}, al día`, steps: [] };
|
|
88
|
-
const
|
|
88
|
+
const text = now.kind === "missing" ? { kind: "skills-manager-add", version: MIN_VERSION } : { kind: "skills-manager-bump", from: now.version, to: MIN_VERSION };
|
|
89
89
|
const state = now.kind === "missing" ? "no está en package.json" : `${now.version}, bajo ${MIN_VERSION}`;
|
|
90
90
|
const step = {
|
|
91
91
|
piece: NAME,
|
|
92
92
|
checked: true,
|
|
93
93
|
downloads: [`${SKILLS_MANAGER}@${MIN_VERSION}`],
|
|
94
|
-
|
|
94
|
+
text,
|
|
95
95
|
run: async (context) => {
|
|
96
96
|
const current = pinned(context.root);
|
|
97
97
|
if (current.kind === "missing" || (current.kind === "exact" && below(current.version))) {
|
package/dist/pieces/skills.js
CHANGED
|
@@ -174,7 +174,7 @@ async function updateStep(root, catalog, ref) {
|
|
|
174
174
|
piece: NAME,
|
|
175
175
|
checked: true,
|
|
176
176
|
downloads: [skillsManagerSpec(root)],
|
|
177
|
-
|
|
177
|
+
text: { kind: "skills-update", catalog, from, to: latest, names: behind.map((skill) => skill.name) },
|
|
178
178
|
run: async (context) => {
|
|
179
179
|
if (ref !== null)
|
|
180
180
|
pinCatalog(context.root, catalog, `v${latest}`);
|
|
@@ -215,10 +215,9 @@ export async function skillsStatus(root, withFlow) {
|
|
|
215
215
|
});
|
|
216
216
|
const offered = candidates ?? fallback;
|
|
217
217
|
const catalogs = [...new Set(offered.map((candidate) => candidate.catalog))];
|
|
218
|
-
const label = `Instalar ${offered.length} skills de ${catalogs.join(" y ")}`;
|
|
219
218
|
const skills = { candidates: offered, picked: offered.map((candidate) => candidate.id), replace: [] };
|
|
220
219
|
const state = candidates === null ? "no instaladas (no se pudieron leer los catálogos)" : "no instaladas";
|
|
221
|
-
return { name: NAME, summary, installed: false, state, steps: [{ piece: NAME, checked: true, downloads: [],
|
|
220
|
+
return { name: NAME, summary, installed: false, state, steps: [{ piece: NAME, checked: true, downloads: [], text: { kind: "skills-install", count: offered.length, catalogs }, skills, run: (context) => install(context, skills) }] };
|
|
222
221
|
}
|
|
223
222
|
const general = manifestCatalogs(root).filter((source) => source.catalog !== FLOW_CATALOG);
|
|
224
223
|
const steps = (await Promise.all(general.map((source) => updateStep(root, source.catalog, source.ref)))).flatMap((step) => step ?? []);
|
|
@@ -227,7 +226,7 @@ export async function skillsStatus(root, withFlow) {
|
|
|
227
226
|
const fresh = (candidates ?? []).filter((candidate) => locked[candidate.name] === undefined);
|
|
228
227
|
if (fresh.length > 0) {
|
|
229
228
|
const skills = { candidates: fresh, picked: [], replace: [] };
|
|
230
|
-
steps.push({ piece: NAME, checked: false, downloads: [skillsManagerSpec(root)],
|
|
229
|
+
steps.push({ piece: NAME, checked: false, downloads: [skillsManagerSpec(root)], text: { kind: "skills-add", names: fresh.map((candidate) => candidate.name) }, skills, run: (context) => install(context, skills) });
|
|
231
230
|
}
|
|
232
231
|
const count = manifestCatalogs(root).reduce((total, source) => total + catalogSkills(root, source.catalog).length, 0);
|
|
233
232
|
const behind = steps.filter((step) => step.checked).length;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Output } from "./output.js";
|
|
2
|
+
import type { StepText } from "./texts/step-text.js";
|
|
3
|
+
/** How a step's progress is shown. */
|
|
4
|
+
export interface Progress {
|
|
5
|
+
start: (text: StepText) => void;
|
|
6
|
+
stop: (text: StepText, ok: boolean) => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Progress as plain lines: the start (marked ◒, like the spinner), a line now and then while it
|
|
10
|
+
* runs, and the end (marked ✓ or ✗).
|
|
11
|
+
* @param out - Where to write.
|
|
12
|
+
* @param options - Whether to print while it runs, how often, and the clock.
|
|
13
|
+
* @returns The progress.
|
|
14
|
+
* @example plainProgress(out, { ticks: true }).start({ kind: "guard-adjust" })
|
|
15
|
+
*/
|
|
16
|
+
export declare function plainProgress(out: Output, options: {
|
|
17
|
+
ticks: boolean;
|
|
18
|
+
tickMs?: number;
|
|
19
|
+
now?: () => number;
|
|
20
|
+
}): Progress;
|
|
21
|
+
/**
|
|
22
|
+
* How progress is shown: a spinner in a terminal, plain lines otherwise or when `plain` asks
|
|
23
|
+
* for them. Only for the steps, after every question: a spinner shown before a question
|
|
24
|
+
* leaves the second question deaf to the keyboard (@clack/prompts 1.8.1).
|
|
25
|
+
* @param out - Where to write.
|
|
26
|
+
* @param verbose - Whether the tools print on the terminal.
|
|
27
|
+
* @param plain - Whether a question may come after the steps (`--commit`).
|
|
28
|
+
* @returns The progress.
|
|
29
|
+
*/
|
|
30
|
+
export declare function progressFor(out: Output, verbose: boolean, plain: boolean): Progress;
|
package/dist/progress.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file How a step's progress is shown. Its start says what is happening ("Actualizando…") and
|
|
3
|
+
* its end what is left, with how long it took. In a terminal, a spinner; otherwise plain
|
|
4
|
+
* lines, and a step that takes a while prints how long it has been running, so it does not
|
|
5
|
+
* look stuck (unless the tools print their own output, with `--verbose`).
|
|
6
|
+
*/
|
|
7
|
+
import { spinner } from "@clack/prompts";
|
|
8
|
+
import { phrases, ui } from "./texts/index.js";
|
|
9
|
+
/** How often a plain step says it is still running. */
|
|
10
|
+
const TICK_MS = 10_000;
|
|
11
|
+
/**
|
|
12
|
+
* The end line of a step.
|
|
13
|
+
* @param text - What the step does.
|
|
14
|
+
* @param ok - Whether it worked.
|
|
15
|
+
* @param ms - How long it took.
|
|
16
|
+
* @returns The line, without the mark.
|
|
17
|
+
*/
|
|
18
|
+
function endLine(text, ok, ms) {
|
|
19
|
+
const said = phrases(text);
|
|
20
|
+
return `${ok ? said.done : ui.failed(said.menu)} (${ui.duration(ms)})`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Progress as plain lines: the start (marked ◒, like the spinner), a line now and then while it
|
|
24
|
+
* runs, and the end (marked ✓ or ✗).
|
|
25
|
+
* @param out - Where to write.
|
|
26
|
+
* @param options - Whether to print while it runs, how often, and the clock.
|
|
27
|
+
* @returns The progress.
|
|
28
|
+
* @example plainProgress(out, { ticks: true }).start({ kind: "guard-adjust" })
|
|
29
|
+
*/
|
|
30
|
+
export function plainProgress(out, options) {
|
|
31
|
+
const now = options.now ?? Date.now;
|
|
32
|
+
let started = 0;
|
|
33
|
+
let timer;
|
|
34
|
+
return {
|
|
35
|
+
start: (text) => {
|
|
36
|
+
started = now();
|
|
37
|
+
out.stdout(`◒ ${phrases(text).doing}\n`);
|
|
38
|
+
if (options.ticks)
|
|
39
|
+
timer = setInterval(() => out.stdout(`${ui.still(ui.duration(now() - started))}\n`), options.tickMs ?? TICK_MS);
|
|
40
|
+
},
|
|
41
|
+
stop: (text, ok) => {
|
|
42
|
+
clearInterval(timer);
|
|
43
|
+
timer = undefined;
|
|
44
|
+
out.stdout(`${ok ? "✓" : "✗"} ${endLine(text, ok, now() - started)}\n`);
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* How progress is shown: a spinner in a terminal, plain lines otherwise or when `plain` asks
|
|
50
|
+
* for them. Only for the steps, after every question: a spinner shown before a question
|
|
51
|
+
* leaves the second question deaf to the keyboard (@clack/prompts 1.8.1).
|
|
52
|
+
* @param out - Where to write.
|
|
53
|
+
* @param verbose - Whether the tools print on the terminal.
|
|
54
|
+
* @param plain - Whether a question may come after the steps (`--commit`).
|
|
55
|
+
* @returns The progress.
|
|
56
|
+
*/
|
|
57
|
+
export function progressFor(out, verbose, plain) {
|
|
58
|
+
if (out.interactive && !verbose && !plain) {
|
|
59
|
+
const spin = spinner();
|
|
60
|
+
let started = 0;
|
|
61
|
+
return {
|
|
62
|
+
start: (text) => {
|
|
63
|
+
started = Date.now();
|
|
64
|
+
spin.start(phrases(text).doing);
|
|
65
|
+
},
|
|
66
|
+
stop: (text, ok) => {
|
|
67
|
+
const line = endLine(text, ok, Date.now() - started);
|
|
68
|
+
if (ok)
|
|
69
|
+
spin.stop(line);
|
|
70
|
+
else
|
|
71
|
+
spin.error(line);
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return plainProgress(out, { ticks: !verbose });
|
|
76
|
+
}
|
package/dist/repo.d.ts
CHANGED
|
@@ -46,6 +46,13 @@ export declare function dependencyVersion(pkg: Record<string, unknown> | null, n
|
|
|
46
46
|
* @example packageManager(root) // "pnpm"
|
|
47
47
|
*/
|
|
48
48
|
export declare function packageManager(root: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* The text of the repo's package.json, to tell later whether a run changed it.
|
|
51
|
+
* @param root - The repo.
|
|
52
|
+
* @returns Its text, or null if there is none.
|
|
53
|
+
* @example packageText(root) // '{ "devDependencies": … }'
|
|
54
|
+
*/
|
|
55
|
+
export declare function packageText(root: string): string | null;
|
|
49
56
|
/**
|
|
50
57
|
* The version of a package installed in the repo's `node_modules`.
|
|
51
58
|
* @param root - The repo.
|
package/dist/repo.js
CHANGED
|
@@ -115,6 +115,16 @@ export function packageManager(root) {
|
|
|
115
115
|
return field;
|
|
116
116
|
return LOCKFILES.find(([file]) => existsSync(join(root, file)))?.[1] ?? "npm";
|
|
117
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* The text of the repo's package.json, to tell later whether a run changed it.
|
|
120
|
+
* @param root - The repo.
|
|
121
|
+
* @returns Its text, or null if there is none.
|
|
122
|
+
* @example packageText(root) // '{ "devDependencies": … }'
|
|
123
|
+
*/
|
|
124
|
+
export function packageText(root) {
|
|
125
|
+
const file = join(root, "package.json");
|
|
126
|
+
return existsSync(file) ? readFileSync(file, "utf8") : null;
|
|
127
|
+
}
|
|
118
128
|
/**
|
|
119
129
|
* The version of a package installed in the repo's `node_modules`.
|
|
120
130
|
* @param root - The repo.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The shape of a catalog of the texts the person sees while `apply` runs its steps.
|
|
3
|
+
* Every language implements `Catalog`; the compiler then asks for every kind of step and every
|
|
4
|
+
* message. The interface uses `ui`; the commit and the PR do not (see commit-texts.ts).
|
|
5
|
+
*/
|
|
6
|
+
import type { StepKind, StepOf } from "./step-text.js";
|
|
7
|
+
/** One step's texts, one per place it shows. */
|
|
8
|
+
export interface StepPhrases {
|
|
9
|
+
/** In the menu and the lists of steps, as an order: "Actualizar issue-flow 0.2.7 → 0.3.0". */
|
|
10
|
+
menu: string;
|
|
11
|
+
/** While it runs: "Actualizando issue-flow de 0.2.7 a 0.3.0…". */
|
|
12
|
+
doing: string;
|
|
13
|
+
/** When it worked, saying what is left: "issue-flow actualizado de 0.2.7 a 0.3.0". */
|
|
14
|
+
done: string;
|
|
15
|
+
}
|
|
16
|
+
/** Every text of `apply` around its steps. */
|
|
17
|
+
export interface Catalog {
|
|
18
|
+
/** Each kind of step's texts. */
|
|
19
|
+
steps: {
|
|
20
|
+
[K in StepKind]: (step: StepOf<K>) => StepPhrases;
|
|
21
|
+
};
|
|
22
|
+
/** Added to a step of a piece the repo has not decided on yet. */
|
|
23
|
+
fresh: string;
|
|
24
|
+
/** The end line of a step that failed, from its menu text. */
|
|
25
|
+
failed: (menu: string) => string;
|
|
26
|
+
/** A duration, short: "0,4 s", "12 s", "1 min 5 s". */
|
|
27
|
+
duration: (ms: number) => string;
|
|
28
|
+
/** The line a long step prints while it runs, so it does not look stuck. */
|
|
29
|
+
still: (elapsed: string) => string;
|
|
30
|
+
/** The line before looking at the pieces. */
|
|
31
|
+
checking: string;
|
|
32
|
+
/** Nothing to install or update. */
|
|
33
|
+
upToDate: string;
|
|
34
|
+
/** With --yes and nothing suggested: the optional steps. */
|
|
35
|
+
onlyOptional: (menus: string[]) => string;
|
|
36
|
+
/** The heading of the steps listed without running them. */
|
|
37
|
+
suggested: (dryRun: boolean) => string;
|
|
38
|
+
/** The last line when every step worked or some failed. */
|
|
39
|
+
summary: (failed: string[]) => string;
|
|
40
|
+
/** What is left to do by hand after the steps, without --commit; with the manager if its install failed. */
|
|
41
|
+
next: (failedInstall: string | null) => string;
|
|
42
|
+
/** A new piece left out because no one was asked about it. */
|
|
43
|
+
undecided: (names: string[]) => string;
|
|
44
|
+
/** The repo's own skills left out of a pick. */
|
|
45
|
+
ownSkillsKept: (names: string[]) => string;
|
|
46
|
+
/** The decisions were saved. */
|
|
47
|
+
saved: (file: string, commits: boolean) => string;
|
|
48
|
+
/** The closing line when no step ran: the person left, or picked none. */
|
|
49
|
+
noSteps: (why: "leave" | "none", wrote: boolean) => string;
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The texts in Spanish. The menu orders ("Actualizar"), progress says what is happening
|
|
3
|
+
* ("Actualizando") and the end line says what is left ("actualizado").
|
|
4
|
+
*/
|
|
5
|
+
import type { Catalog } from "./catalog.js";
|
|
6
|
+
/** The texts in Spanish. */
|
|
7
|
+
export declare const es: Catalog;
|
package/dist/texts/es.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A list of names, joined with commas.
|
|
3
|
+
* @param names - The names.
|
|
4
|
+
* @returns The list.
|
|
5
|
+
*/
|
|
6
|
+
const list = (names) => names.join(", ");
|
|
7
|
+
/** The texts in Spanish. */
|
|
8
|
+
export const es = {
|
|
9
|
+
steps: {
|
|
10
|
+
"skills-manager-create": ({ version }) => ({
|
|
11
|
+
menu: `Crear package.json con skills-manager ${version}`,
|
|
12
|
+
doing: `Creando package.json con skills-manager ${version}…`,
|
|
13
|
+
done: `package.json creado con skills-manager ${version}`,
|
|
14
|
+
}),
|
|
15
|
+
"skills-manager-add": ({ version }) => ({
|
|
16
|
+
menu: `Agregar skills-manager ${version} a package.json`,
|
|
17
|
+
doing: `Agregando skills-manager ${version} a package.json…`,
|
|
18
|
+
done: `skills-manager ${version} agregado a package.json`,
|
|
19
|
+
}),
|
|
20
|
+
"skills-manager-bump": ({ from, to }) => ({
|
|
21
|
+
menu: `Subir skills-manager ${from} → ${to}, el mínimo de agent-kitchen`,
|
|
22
|
+
doing: `Subiendo skills-manager de ${from} a ${to}…`,
|
|
23
|
+
done: `skills-manager subido de ${from} a ${to}`,
|
|
24
|
+
}),
|
|
25
|
+
"flow-install": ({ version }) => ({
|
|
26
|
+
menu: `Instalar issue-flow ${version}: config del flujo, hooks y scripts`,
|
|
27
|
+
doing: `Instalando issue-flow ${version}…`,
|
|
28
|
+
done: `issue-flow ${version} instalado: config del flujo, hooks y scripts`,
|
|
29
|
+
}),
|
|
30
|
+
"flow-update": ({ from, to }) => ({
|
|
31
|
+
menu: `Actualizar issue-flow ${from} → ${to}, con sus hooks y sus skills`,
|
|
32
|
+
doing: `Actualizando issue-flow de ${from} a ${to}…`,
|
|
33
|
+
done: `issue-flow actualizado de ${from} a ${to}, con sus hooks y sus skills`,
|
|
34
|
+
}),
|
|
35
|
+
"flow-repair": ({ version }) => ({
|
|
36
|
+
menu: `Reparar issue-flow ${version}: hooks y $schema`,
|
|
37
|
+
doing: `Reparando issue-flow ${version}…`,
|
|
38
|
+
done: `issue-flow ${version} reparado: hooks y $schema`,
|
|
39
|
+
}),
|
|
40
|
+
"flow-skills": ({ version }) => ({
|
|
41
|
+
menu: `Poner las skills del flujo en v${version}, la versión de issue-flow`,
|
|
42
|
+
doing: `Poniendo las skills del flujo en v${version}…`,
|
|
43
|
+
done: `Skills del flujo en v${version}, la versión de issue-flow`,
|
|
44
|
+
}),
|
|
45
|
+
"flow-labels": ({ missing }) => ({
|
|
46
|
+
menu: `Crear en GitHub los labels que faltan: ${list(missing)}`,
|
|
47
|
+
doing: `Creando en GitHub los labels que faltan: ${list(missing)}…`,
|
|
48
|
+
done: `Labels creados en GitHub: ${list(missing)}`,
|
|
49
|
+
}),
|
|
50
|
+
"github-rest-bump": ({ from, to, flow }) => ({
|
|
51
|
+
menu: `Subir github-rest ${from} → ${to}, el mínimo de issue-flow ${flow}`,
|
|
52
|
+
doing: `Subiendo github-rest de ${from} a ${to}…`,
|
|
53
|
+
done: `github-rest subido de ${from} a ${to}, el mínimo de issue-flow ${flow}`,
|
|
54
|
+
}),
|
|
55
|
+
"cloud-install": ({ version }) => ({
|
|
56
|
+
menu: `Instalar claude-cloud ${version ?? "1.x"}: prepara las sesiones en la nube de Claude`,
|
|
57
|
+
doing: `Instalando claude-cloud ${version ?? "1.x"}…`,
|
|
58
|
+
done: `claude-cloud ${version ?? "1.x"} instalado: prepara las sesiones en la nube de Claude`,
|
|
59
|
+
}),
|
|
60
|
+
"cloud-update": ({ from, to, config }) => ({
|
|
61
|
+
menu: `Actualizar claude-cloud ${from ?? "?"} → ${to} (la versión que fija ${config})`,
|
|
62
|
+
doing: `Actualizando claude-cloud de ${from ?? "?"} a ${to}…`,
|
|
63
|
+
done: `claude-cloud actualizado de ${from ?? "?"} a ${to} en ${config}`,
|
|
64
|
+
}),
|
|
65
|
+
"guard-install": ({ version }) => ({
|
|
66
|
+
menu: `Instalar claude-repo-guard ${version ?? "(main)"}: modo auto con sandbox, y un documento de qué protege`,
|
|
67
|
+
doing: `Instalando claude-repo-guard ${version ?? "(main)"}…`,
|
|
68
|
+
done: `claude-repo-guard ${version ?? "(main)"} instalado: modo auto con sandbox, y un documento de qué protege`,
|
|
69
|
+
}),
|
|
70
|
+
"guard-update": ({ from, to }) => ({
|
|
71
|
+
menu: `Actualizar claude-repo-guard ${from ?? "?"} → ${to}`,
|
|
72
|
+
doing: `Actualizando claude-repo-guard de ${from ?? "?"} a ${to}…`,
|
|
73
|
+
done: `claude-repo-guard actualizado de ${from ?? "?"} a ${to}`,
|
|
74
|
+
}),
|
|
75
|
+
"guard-adjust": () => ({
|
|
76
|
+
menu: "Ajustar claude-repo-guard a lo que necesita el flujo de issues",
|
|
77
|
+
doing: "Ajustando claude-repo-guard al flujo de issues…",
|
|
78
|
+
done: "claude-repo-guard ajustado a lo que necesita el flujo de issues",
|
|
79
|
+
}),
|
|
80
|
+
"skills-install": ({ count, catalogs }) => ({
|
|
81
|
+
menu: `Instalar ${count} skills de ${catalogs.join(" y ")}`,
|
|
82
|
+
doing: `Instalando ${count} skills de ${catalogs.join(" y ")}…`,
|
|
83
|
+
done: `${count} skills instaladas de ${catalogs.join(" y ")}`,
|
|
84
|
+
}),
|
|
85
|
+
"skills-update": ({ catalog, from, to, names }) => ({
|
|
86
|
+
menu: `Actualizar skills de ${catalog} ${from} → v${to}: ${list(names)}`,
|
|
87
|
+
doing: `Actualizando skills de ${catalog} de ${from} a v${to}…`,
|
|
88
|
+
done: `Skills de ${catalog} actualizadas a v${to}: ${list(names)}`,
|
|
89
|
+
}),
|
|
90
|
+
"skills-add": ({ names }) => ({
|
|
91
|
+
menu: `Agregar skills nuevas (${names.length}): ${list(names)}`,
|
|
92
|
+
doing: `Agregando skills nuevas: ${list(names)}…`,
|
|
93
|
+
done: `Skills nuevas agregadas: ${list(names)}`,
|
|
94
|
+
}),
|
|
95
|
+
"agents-md": ({ rule, claudeImport }) => {
|
|
96
|
+
const files = [...(rule ? ["AGENTS.md"] : []), ...(claudeImport ? ["CLAUDE.md"] : [])].join(", ");
|
|
97
|
+
if (!rule)
|
|
98
|
+
return {
|
|
99
|
+
menu: `Agregar @AGENTS.md a CLAUDE.md, para que Claude Code lea AGENTS.md: ${files}`,
|
|
100
|
+
doing: "Agregando @AGENTS.md a CLAUDE.md…",
|
|
101
|
+
done: "@AGENTS.md agregado a CLAUDE.md: Claude Code lee AGENTS.md",
|
|
102
|
+
};
|
|
103
|
+
const also = claudeImport ? " (y @AGENTS.md en CLAUDE.md)" : "";
|
|
104
|
+
return {
|
|
105
|
+
menu: `Agregar a AGENTS.md la regla de versiones instaladas${also}: ${files}`,
|
|
106
|
+
doing: `Agregando a AGENTS.md la regla de versiones instaladas${also}…`,
|
|
107
|
+
done: `Regla de versiones instaladas agregada a AGENTS.md${also}`,
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
"install-deps": ({ manager }) => ({
|
|
111
|
+
menu: `Instalar las dependencias con ${manager}`,
|
|
112
|
+
doing: `Instalando las dependencias con ${manager}…`,
|
|
113
|
+
done: `Dependencias instaladas con ${manager}`,
|
|
114
|
+
}),
|
|
115
|
+
},
|
|
116
|
+
fresh: " (nueva)",
|
|
117
|
+
failed: (menu) => `Falló: ${menu}`,
|
|
118
|
+
duration: (ms) => {
|
|
119
|
+
if (ms < 10_000)
|
|
120
|
+
return `${(ms / 1000).toFixed(1).replace(".", ",")} s`;
|
|
121
|
+
const seconds = Math.round(ms / 1000);
|
|
122
|
+
return seconds < 60 ? `${seconds} s` : `${Math.floor(seconds / 60)} min${seconds % 60 === 0 ? "" : ` ${seconds % 60} s`}`;
|
|
123
|
+
},
|
|
124
|
+
still: (elapsed) => ` … sigue (${elapsed})`,
|
|
125
|
+
checking: "Revisando el repo y las últimas versiones…",
|
|
126
|
+
upToDate: "Todo al día: no hay nada que instalar ni actualizar.",
|
|
127
|
+
onlyOptional: (menus) => `Todo al día. Opcional, para elegir en una terminal: ${menus.join("; ")}.`,
|
|
128
|
+
suggested: (dryRun) => `Pasos sugeridos${dryRun ? "" : " (para hacerlos, corre agent-kitchen apply en una terminal, o con --yes)"}:`,
|
|
129
|
+
summary: (failed) => (failed.length === 0 ? "Listo." : `Terminó, pero fallaron: ${failed.join("; ")}.`),
|
|
130
|
+
next: (failedInstall) => `Falta: ${failedInstall === null ? "" : `corre '${failedInstall} install', `}revisa el diff y haz commit.`,
|
|
131
|
+
undecided: (names) => `Pieza nueva sin decisión: ${list(names)}. Corre agent-kitchen apply en una terminal para elegir.`,
|
|
132
|
+
ownSkillsKept: (names) => `Se dejan fuera las skills que el repo ya tiene como propias: ${list(names)}. Para reemplazarlas, corre agent-kitchen apply en una terminal.`,
|
|
133
|
+
saved: (file, commits) => `Guardé qué piezas usa el repo en ${file}${commits ? "" : "; commitéalo"}.`,
|
|
134
|
+
noSteps: (why, wrote) => {
|
|
135
|
+
if (why === "leave")
|
|
136
|
+
return wrote ? "No corrí ningún paso; solo guardé qué piezas usa el repo." : "No se cambió nada.";
|
|
137
|
+
return wrote ? "No elegiste pasos; solo guardé qué piezas usa el repo." : "No elegiste nada; no se cambió nada.";
|
|
138
|
+
},
|
|
139
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file The interface's texts, and how a step reads in a list. Another language is a file
|
|
3
|
+
* like es.ts that implements `Catalog`, chosen here.
|
|
4
|
+
*/
|
|
5
|
+
import type { Step } from "../piece.js";
|
|
6
|
+
import type { Catalog, StepPhrases } from "./catalog.js";
|
|
7
|
+
import type { StepText } from "./step-text.js";
|
|
8
|
+
/** The catalog the interface uses. */
|
|
9
|
+
export declare const ui: Catalog;
|
|
10
|
+
/**
|
|
11
|
+
* A step's texts in a catalog.
|
|
12
|
+
* @param catalog - The catalog.
|
|
13
|
+
* @param text - What the step does.
|
|
14
|
+
* @returns Its texts.
|
|
15
|
+
* @example phrasesIn(es, { kind: "guard-adjust" }).doing // "Ajustando claude-repo-guard al flujo de issues…"
|
|
16
|
+
*/
|
|
17
|
+
export declare function phrasesIn(catalog: Catalog, text: StepText): StepPhrases;
|
|
18
|
+
/**
|
|
19
|
+
* A step's texts in the interface.
|
|
20
|
+
* @param text - What the step does.
|
|
21
|
+
* @returns Its texts.
|
|
22
|
+
*/
|
|
23
|
+
export declare function phrases(text: StepText): StepPhrases;
|
|
24
|
+
/**
|
|
25
|
+
* How a step reads in the menu and in lists: its order, marked if its piece is new.
|
|
26
|
+
* @param step - The step.
|
|
27
|
+
* @returns The text.
|
|
28
|
+
* @example stepLabel(step) // "Actualizar issue-flow 0.2.7 → 0.3.0, con sus hooks y sus skills"
|
|
29
|
+
*/
|
|
30
|
+
export declare function stepLabel(step: Pick<Step, "text" | "fresh">): string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { es } from "./es.js";
|
|
2
|
+
/** The catalog the interface uses. */
|
|
3
|
+
export const ui = es;
|
|
4
|
+
/**
|
|
5
|
+
* A step's texts in a catalog.
|
|
6
|
+
* @param catalog - The catalog.
|
|
7
|
+
* @param text - What the step does.
|
|
8
|
+
* @returns Its texts.
|
|
9
|
+
* @example phrasesIn(es, { kind: "guard-adjust" }).doing // "Ajustando claude-repo-guard al flujo de issues…"
|
|
10
|
+
*/
|
|
11
|
+
export function phrasesIn(catalog, text) {
|
|
12
|
+
const render = catalog.steps[text.kind];
|
|
13
|
+
return render(text);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A step's texts in the interface.
|
|
17
|
+
* @param text - What the step does.
|
|
18
|
+
* @returns Its texts.
|
|
19
|
+
*/
|
|
20
|
+
export function phrases(text) {
|
|
21
|
+
return phrasesIn(ui, text);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* How a step reads in the menu and in lists: its order, marked if its piece is new.
|
|
25
|
+
* @param step - The step.
|
|
26
|
+
* @returns The text.
|
|
27
|
+
* @example stepLabel(step) // "Actualizar issue-flow 0.2.7 → 0.3.0, con sus hooks y sus skills"
|
|
28
|
+
*/
|
|
29
|
+
export function stepLabel(step) {
|
|
30
|
+
return `${phrases(step.text).menu}${step.fresh === true ? ui.fresh : ""}`;
|
|
31
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file What a step does, as data: its kind, the piece's versions and what it brings. No
|
|
3
|
+
* words here; each place that shows a step (the menu, the start and end of its progress, the
|
|
4
|
+
* commit) turns this into its own text, so the interface can change language without the
|
|
5
|
+
* commits changing too.
|
|
6
|
+
*/
|
|
7
|
+
/** A version that may be unknown (`null`), shown as `?` or as the place it comes from. */
|
|
8
|
+
type MaybeVersion = string | null;
|
|
9
|
+
/** What a step does, one kind per thing a piece can offer. */
|
|
10
|
+
export type StepText = {
|
|
11
|
+
kind: "skills-manager-create";
|
|
12
|
+
version: string;
|
|
13
|
+
} | {
|
|
14
|
+
kind: "skills-manager-add";
|
|
15
|
+
version: string;
|
|
16
|
+
} | {
|
|
17
|
+
kind: "skills-manager-bump";
|
|
18
|
+
from: string;
|
|
19
|
+
to: string;
|
|
20
|
+
} | {
|
|
21
|
+
kind: "flow-install";
|
|
22
|
+
version: string;
|
|
23
|
+
} | {
|
|
24
|
+
kind: "flow-update";
|
|
25
|
+
from: string;
|
|
26
|
+
to: string;
|
|
27
|
+
} | {
|
|
28
|
+
kind: "flow-repair";
|
|
29
|
+
version: string;
|
|
30
|
+
} | {
|
|
31
|
+
kind: "flow-skills";
|
|
32
|
+
version: string;
|
|
33
|
+
} | {
|
|
34
|
+
kind: "flow-labels";
|
|
35
|
+
missing: string[];
|
|
36
|
+
} | {
|
|
37
|
+
kind: "github-rest-bump";
|
|
38
|
+
from: string;
|
|
39
|
+
to: string;
|
|
40
|
+
flow: string;
|
|
41
|
+
} | {
|
|
42
|
+
kind: "cloud-install";
|
|
43
|
+
version: MaybeVersion;
|
|
44
|
+
} | {
|
|
45
|
+
kind: "cloud-update";
|
|
46
|
+
from: MaybeVersion;
|
|
47
|
+
to: string;
|
|
48
|
+
config: string;
|
|
49
|
+
} | {
|
|
50
|
+
kind: "guard-install";
|
|
51
|
+
version: MaybeVersion;
|
|
52
|
+
} | {
|
|
53
|
+
kind: "guard-update";
|
|
54
|
+
from: MaybeVersion;
|
|
55
|
+
to: string;
|
|
56
|
+
} | {
|
|
57
|
+
kind: "guard-adjust";
|
|
58
|
+
} | {
|
|
59
|
+
kind: "skills-install";
|
|
60
|
+
count: number;
|
|
61
|
+
catalogs: string[];
|
|
62
|
+
} | {
|
|
63
|
+
kind: "skills-update";
|
|
64
|
+
catalog: string;
|
|
65
|
+
from: string;
|
|
66
|
+
to: string;
|
|
67
|
+
names: string[];
|
|
68
|
+
} | {
|
|
69
|
+
kind: "skills-add";
|
|
70
|
+
names: string[];
|
|
71
|
+
} | {
|
|
72
|
+
kind: "agents-md";
|
|
73
|
+
rule: boolean;
|
|
74
|
+
claudeImport: boolean;
|
|
75
|
+
} | {
|
|
76
|
+
kind: "install-deps";
|
|
77
|
+
manager: string;
|
|
78
|
+
};
|
|
79
|
+
/** The kinds of step. */
|
|
80
|
+
export type StepKind = StepText["kind"];
|
|
81
|
+
/** The data of one kind of step. */
|
|
82
|
+
export type StepOf<K extends StepKind> = Extract<StepText, {
|
|
83
|
+
kind: K;
|
|
84
|
+
}>;
|
|
85
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file What a step does, as data: its kind, the piece's versions and what it brings. No
|
|
3
|
+
* words here; each place that shows a step (the menu, the start and end of its progress, the
|
|
4
|
+
* commit) turns this into its own text, so the interface can change language without the
|
|
5
|
+
* commits changing too.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-kitchen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "One command to install, update and check a repo's agent tooling: the issue flow and its skills, the general skills, Claude cloud sessions, claude-repo-guard and the installed-versions rule in AGENTS.md.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|