agent-kitchen 0.9.0 → 0.10.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 +2 -2
- package/dist/cli.js +2 -2
- package/dist/commands/sync.d.ts +1 -1
- package/dist/commands/sync.js +22 -4
- package/dist/decisions.d.ts +1 -1
- package/dist/decisions.js +1 -1
- package/dist/output.d.ts +1 -1
- package/dist/output.js +1 -1
- package/dist/piece.d.ts +1 -1
- package/dist/piece.js +1 -1
- package/dist/pieces/cloud.d.ts +8 -7
- package/dist/pieces/cloud.js +19 -14
- package/dist/texts/catalog.d.ts +2 -0
- package/dist/texts/es.js +7 -6
- package/dist/tools.d.ts +25 -3
- package/dist/tools.js +71 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ Al arrancar revisa si npm tiene una versión más nueva de sí mismo. Si la hay,
|
|
|
26
26
|
|---|---|---|---|---|---|
|
|
27
27
|
| `skills-manager` | La versión de [`@ramon-sg/skills-manager`](https://github.com/ramon-sg/skills-manager) que corre `agent-kitchen`: como mínimo 1.2.0. Si falta la agrega y si es menor la sube; nunca la baja. Un rango o `workspace:` no se toca, y avisa si la versión que corre queda bajo el mínimo. Solo en repos que usan skills y tienen `package.json`, o donde issue-flow se instala en la misma corrida: entonces crea el `package.json` | `package.json` | — | La agrega `agent-kitchen` | La sube `agent-kitchen` |
|
|
28
28
|
| `issue-flow` | Flujo de issues ([`@ramon-sg/issue-flow`](https://github.com/ramon-sg/issue-flow)): rama, worktree y PR en draft por issue, y sus 5 skills | `package.json` | npm | `issue-flow apply` (`init` antes de 0.3.0), y sus skills a la misma tag | `issue-flow apply` en la versión nueva (`upgrade` antes de 0.3.0), y sus skills a la misma tag. Desde 0.3.0, si su doctor ve hooks o el `$schema` atrás, `apply` en la versión del repo. Desde 0.3.0, si `github-rest` es una versión exacta bajo el mínimo que pide esa versión del flujo, la sube. Desde 0.2.6, si a GitHub le faltan labels del flujo (`spike`, `P1`–`P4`…), `issue-flow labels sync` los crea |
|
|
29
|
-
| `
|
|
29
|
+
| `agent-cloud-kit` | Sesiones en la nube ([`agent-cloud-kit`](https://github.com/ramon-sg/agent-cloud-kit)): herramientas, Docker y el clone completo | `.claude/cloud.json`, `.agents/skills/cloud-ready/` | npm | `agent-cloud-kit init` | Cambia la versión que fija `.claude/cloud.json` y corre el `init` de la versión nueva, para que la skill `cloud-ready` quede igual. Al terminar `apply` sugiere `npx agent-cloud-kit prepare` |
|
|
30
30
|
| `claude-repo-guard` | Barandas ([`claude-repo-guard`](https://github.com/ramon-sg/claude-repo-guard)): modo auto con sandbox, escribe solo en su worktree | `.claude/repo-guard.manifest.json` | Tags `vX.Y.Z` de GitHub | `apply` en esa tag (`install` antes de 0.5.0) | `apply` en la tag nueva |
|
|
31
31
|
| `skills` | Skills con [`skills-manager`](https://github.com/ramon-sg/skills-manager): las del flujo y las de [`agent-skills`](https://github.com/ramon-sg/agent-skills) (planes, auditoría de código y de tests) | `.agents/skills.lock.json` | Tags del catálogo | `skills-manager init --select` con las elegidas | `skills-manager update` |
|
|
32
32
|
| `agents-md` | Una línea en `AGENTS.md` que le pide al agente mirar la versión instalada de una biblioteca antes de usarla. Si el repo tiene `CLAUDE.md`, le agrega `@AGENTS.md`, porque si no Claude Code no lee `AGENTS.md`. Solo en repos con `package.json` | `AGENTS.md` | — | La escribe `agent-kitchen` | — |
|
|
@@ -51,7 +51,7 @@ npx agent-kitchen apply --yes # hace lo sugerido sin preguntar
|
|
|
51
51
|
npx agent-kitchen apply --pr # en una copia de origin, y abre un PR en draft
|
|
52
52
|
npx agent-kitchen apply --here # en tu copia, sin commit
|
|
53
53
|
npx agent-kitchen apply --verbose # muestra la salida de cada herramienta
|
|
54
|
-
npx agent-kitchen apply --skip
|
|
54
|
+
npx agent-kitchen apply --skip agent-cloud-kit # deja fuera una pieza (o varias, con comas)
|
|
55
55
|
npx agent-kitchen apply --pieces # cambia qué piezas usa el repo (solo en una terminal)
|
|
56
56
|
npx agent-kitchen doctor # revisa cada pieza con su propio doctor
|
|
57
57
|
```
|
package/dist/cli.js
CHANGED
|
@@ -14,7 +14,7 @@ import { KitError, processOutput, UsageError } from "./output.js";
|
|
|
14
14
|
import { FLOW_PACKAGE, GENERAL_CATALOGS } from "./piece.js";
|
|
15
15
|
import { PACKAGE as CLOUD_PACKAGE } from "./pieces/cloud.js";
|
|
16
16
|
import { REPO as GUARD_REPO } from "./pieces/guard.js";
|
|
17
|
-
import { compareVersions, isRelease, latestTag, npmLatest } from "./tools.js";
|
|
17
|
+
import { compareVersions, isRelease, latestTag, npmLatest, npmLatestExact } from "./tools.js";
|
|
18
18
|
/** This package on npm. */
|
|
19
19
|
const PACKAGE = "agent-kitchen";
|
|
20
20
|
/** Set in the run that a newer agent-kitchen was handed to, so it never hands over again. */
|
|
@@ -52,7 +52,7 @@ function ownVersion() {
|
|
|
52
52
|
*/
|
|
53
53
|
function startLookups() {
|
|
54
54
|
void npmLatest(FLOW_PACKAGE);
|
|
55
|
-
void
|
|
55
|
+
void npmLatestExact(CLOUD_PACKAGE);
|
|
56
56
|
void latestTag(GUARD_REPO);
|
|
57
57
|
for (const catalog of GENERAL_CATALOGS)
|
|
58
58
|
void latestTag(catalog);
|
package/dist/commands/sync.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface SyncOptions {
|
|
|
17
17
|
/**
|
|
18
18
|
* The names `--skip` takes.
|
|
19
19
|
* @returns The pieces' names.
|
|
20
|
-
* @example pieceNames() // ["skills-manager", "issue-flow", "
|
|
20
|
+
* @example pieceNames() // ["skills-manager", "issue-flow", "agent-cloud-kit", "claude-repo-guard", "skills", "agents-md"]
|
|
21
21
|
*/
|
|
22
22
|
export declare function pieceNames(): string[];
|
|
23
23
|
/**
|
package/dist/commands/sync.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* draft (see pr-clone.ts), `--here` in the person's checkout, leaving the changes uncommitted.
|
|
6
6
|
* In a terminal, without either, it asks; with `--yes` or without a terminal, or without an
|
|
7
7
|
* origin, it works here. Here it warns if the checkout has changes or is behind its upstream.
|
|
8
|
-
* Then it looks at each piece (the version of skills-manager, the issue flow,
|
|
8
|
+
* Then it looks at each piece (the version of skills-manager, the issue flow, agent-cloud-kit,
|
|
9
9
|
* claude-repo-guard, the skills, the rule in AGENTS.md) with
|
|
10
10
|
* every lookup at once, shows what the repo has, and offers the steps that install what is
|
|
11
11
|
* missing or update what is behind. In a terminal it asks first, all in one go: everything
|
|
@@ -37,7 +37,7 @@ import { issueFlowStatus, NAME as FLOW } from "../pieces/issue-flow.js";
|
|
|
37
37
|
import { keepOwn, NAME as SKILLS, ownInPick, skillsStatus } from "../pieces/skills.js";
|
|
38
38
|
import { agentsMdStatus, NAME as AGENTS_MD } from "../pieces/agents-md.js";
|
|
39
39
|
import { NAME as SKILLS_MANAGER, skillsManagerStatus } from "../pieces/skills-manager.js";
|
|
40
|
-
import { mainCheckout, packageManager, packageText } from "../repo.js";
|
|
40
|
+
import { mainCheckout, packageManager, packageText, readJson } from "../repo.js";
|
|
41
41
|
import { download, failedOutput, runInstall, setVerbose } from "../tools.js";
|
|
42
42
|
import { commitLine, DECISIONS_LINE } from "../commit-texts.js";
|
|
43
43
|
import { progressFor } from "../progress.js";
|
|
@@ -47,7 +47,7 @@ const PIECES = [SKILLS_MANAGER, FLOW, CLOUD, GUARD, SKILLS, AGENTS_MD];
|
|
|
47
47
|
/**
|
|
48
48
|
* The names `--skip` takes.
|
|
49
49
|
* @returns The pieces' names.
|
|
50
|
-
* @example pieceNames() // ["skills-manager", "issue-flow", "
|
|
50
|
+
* @example pieceNames() // ["skills-manager", "issue-flow", "agent-cloud-kit", "claude-repo-guard", "skills", "agents-md"]
|
|
51
51
|
*/
|
|
52
52
|
export function pieceNames() {
|
|
53
53
|
return [...PIECES];
|
|
@@ -405,7 +405,13 @@ async function applyIn(work, options, out) {
|
|
|
405
405
|
const steps = statuses.flatMap((status) => status.steps);
|
|
406
406
|
const progress = progressFor(out, options.verbose);
|
|
407
407
|
// In a clone, a run that only wrote the decisions file still ends in a PR.
|
|
408
|
-
const endWithoutSteps = async () =>
|
|
408
|
+
const endWithoutSteps = async () => {
|
|
409
|
+
if (work.kind === "pr")
|
|
410
|
+
return wrote ? openPr(work, commitLabels([], true), [], progress, out) : 0;
|
|
411
|
+
if (!options.dryRun)
|
|
412
|
+
printCloudNext(root, skip, out);
|
|
413
|
+
return 0;
|
|
414
|
+
};
|
|
409
415
|
if (steps.length === 0) {
|
|
410
416
|
if (saves)
|
|
411
417
|
wrote = saveDecisions(root, saved, statuses, [], pr, out) || wrote;
|
|
@@ -446,8 +452,20 @@ async function applyIn(work, options, out) {
|
|
|
446
452
|
if (installFailed)
|
|
447
453
|
failed.push(phrases({ kind: "install-deps", manager: packageManager(root) }).menu);
|
|
448
454
|
out.stdout(`\n${ui.summary(failed)} ${ui.next(installFailed ? packageManager(root) : null)}\n`);
|
|
455
|
+
if (!options.dryRun)
|
|
456
|
+
printCloudNext(root, skip, out);
|
|
449
457
|
return failed.length === 0 ? 0 : 1;
|
|
450
458
|
}
|
|
459
|
+
/**
|
|
460
|
+
* Says what to run next for the cloud, if agent-cloud-kit is installed and was not left out.
|
|
461
|
+
* @param root - The repo.
|
|
462
|
+
* @param skip - The pieces left out.
|
|
463
|
+
* @param out - Where to write.
|
|
464
|
+
*/
|
|
465
|
+
function printCloudNext(root, skip, out) {
|
|
466
|
+
if (!skip.includes(CLOUD) && readJson(root, ".claude/cloud.json") !== null)
|
|
467
|
+
out.stdout(`${ui.cloudNext}\n`);
|
|
468
|
+
}
|
|
451
469
|
/**
|
|
452
470
|
* Runs the repo's install with the same progress as a step, and shows its output if it fails.
|
|
453
471
|
* @param root - The repo.
|
package/dist/decisions.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export declare function readDecisions(root: string): Saved | null;
|
|
|
24
24
|
* The decidable pieces with no decision yet.
|
|
25
25
|
* @param saved - What was read, or null if there is no file.
|
|
26
26
|
* @returns Their names; all of them without a file.
|
|
27
|
-
* @example undecided(null) // ["issue-flow", "
|
|
27
|
+
* @example undecided(null) // ["issue-flow", "agent-cloud-kit", ...]
|
|
28
28
|
*/
|
|
29
29
|
export declare function undecided(saved: Saved | null): string[];
|
|
30
30
|
/**
|
package/dist/decisions.js
CHANGED
|
@@ -43,7 +43,7 @@ export function readDecisions(root) {
|
|
|
43
43
|
* The decidable pieces with no decision yet.
|
|
44
44
|
* @param saved - What was read, or null if there is no file.
|
|
45
45
|
* @returns Their names; all of them without a file.
|
|
46
|
-
* @example undecided(null) // ["issue-flow", "
|
|
46
|
+
* @example undecided(null) // ["issue-flow", "agent-cloud-kit", ...]
|
|
47
47
|
*/
|
|
48
48
|
export function undecided(saved) {
|
|
49
49
|
return DECIDABLE.filter((name) => saved?.pieces[name] === undefined);
|
package/dist/output.d.ts
CHANGED
|
@@ -24,6 +24,6 @@ export declare function processOutput(): Output;
|
|
|
24
24
|
* Prints a warning on stderr with the program's name.
|
|
25
25
|
* @param out - Where to write.
|
|
26
26
|
* @param text - The warning.
|
|
27
|
-
* @example warn(out, "
|
|
27
|
+
* @example warn(out, "agent-cloud-kit init failed")
|
|
28
28
|
*/
|
|
29
29
|
export declare function warn(out: Output, text: string): void;
|
package/dist/output.js
CHANGED
|
@@ -24,7 +24,7 @@ export function processOutput() {
|
|
|
24
24
|
* Prints a warning on stderr with the program's name.
|
|
25
25
|
* @param out - Where to write.
|
|
26
26
|
* @param text - The warning.
|
|
27
|
-
* @example warn(out, "
|
|
27
|
+
* @example warn(out, "agent-cloud-kit init failed")
|
|
28
28
|
*/
|
|
29
29
|
export function warn(out, text) {
|
|
30
30
|
out.stderr(`agent-kitchen: ${text}\n`);
|
package/dist/piece.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file What agent-kitchen knows of each piece it manages, and the names they share. A piece
|
|
3
|
-
* (the version of skills-manager, the issue flow,
|
|
3
|
+
* (the version of skills-manager, the issue flow, agent-cloud-kit, claude-repo-guard, the
|
|
4
4
|
* skills, the rule in AGENTS.md) tells what the repo has and the steps that would install or
|
|
5
5
|
* update it; agent-kitchen shows them, lets the person pick, and runs the picked ones in
|
|
6
6
|
* order. Every step runs the piece's own tool, which owns its files: agent-kitchen only
|
package/dist/piece.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file What agent-kitchen knows of each piece it manages, and the names they share. A piece
|
|
3
|
-
* (the version of skills-manager, the issue flow,
|
|
3
|
+
* (the version of skills-manager, the issue flow, agent-cloud-kit, claude-repo-guard, the
|
|
4
4
|
* skills, the rule in AGENTS.md) tells what the repo has and the steps that would install or
|
|
5
5
|
* update it; agent-kitchen shows them, lets the person pick, and runs the picked ones in
|
|
6
6
|
* order. Every step runs the piece's own tool, which owns its files: agent-kitchen only
|
package/dist/pieces/cloud.d.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file Claude cloud sessions (
|
|
2
|
+
* @file Claude cloud sessions (`agent-cloud-kit`). The repo's version is the one
|
|
3
3
|
* `.claude/cloud.json` pins: the cloud machine runs exactly that one. Installing runs its
|
|
4
|
-
* `init`; updating
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* `init`; updating moves that version (and a `$schema` pinned to a version) and then runs the
|
|
5
|
+
* new version's `init`, so the `cloud-ready` skill copied into the repo matches it (`init` is
|
|
6
|
+
* idempotent: it adds no second hook and keeps `.claude/cloud.json`). Outside the cloud its
|
|
7
|
+
* hook does nothing, so a repo nobody opens in the cloud loses nothing.
|
|
7
8
|
*/
|
|
8
9
|
import type { Check, PieceStatus } from "../piece.js";
|
|
9
10
|
/** The piece's name, as `--skip` takes it. */
|
|
10
|
-
export declare const NAME = "
|
|
11
|
+
export declare const NAME = "agent-cloud-kit";
|
|
11
12
|
/** The package on npm. */
|
|
12
|
-
export declare const PACKAGE = "
|
|
13
|
+
export declare const PACKAGE = "agent-cloud-kit";
|
|
13
14
|
/**
|
|
14
|
-
* What the repo has of
|
|
15
|
+
* What the repo has of agent-cloud-kit, and the step it needs.
|
|
15
16
|
* @param root - The repo.
|
|
16
17
|
* @returns The piece's status.
|
|
17
18
|
* @example (await cloudStatus(root)).state // "1.0.0, al día"
|
package/dist/pieces/cloud.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { readJson, writeJson } from "../repo.js";
|
|
2
|
-
import {
|
|
2
|
+
import { compareSemver, isExactVersion, npmLatestExact, runNpx } from "../tools.js";
|
|
3
3
|
/** The piece's name, as `--skip` takes it. */
|
|
4
|
-
export const NAME = "
|
|
4
|
+
export const NAME = "agent-cloud-kit";
|
|
5
5
|
/** The package on npm. */
|
|
6
|
-
export const PACKAGE = "
|
|
6
|
+
export const PACKAGE = "agent-cloud-kit";
|
|
7
7
|
/** Its config in the repo, which pins its version. */
|
|
8
8
|
const CONFIG = ".claude/cloud.json";
|
|
9
9
|
/**
|
|
10
|
-
* The version `.claude/cloud.json` pins.
|
|
10
|
+
* The version `.claude/cloud.json` pins: exact semver, so a release candidate counts.
|
|
11
11
|
* @param config - The config, or null.
|
|
12
12
|
* @returns The version, or null if it has none.
|
|
13
13
|
*/
|
|
14
14
|
function pinned(config) {
|
|
15
|
-
return typeof config?.version === "string" &&
|
|
15
|
+
return typeof config?.version === "string" && isExactVersion(config.version) ? config.version : null;
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* The step the repo needs, if any.
|
|
@@ -33,35 +33,40 @@ function stepFor(config, latest) {
|
|
|
33
33
|
const run = await runNpx(context.root, [spec, "init"]);
|
|
34
34
|
if (run.ok)
|
|
35
35
|
return true;
|
|
36
|
-
context.fail(`
|
|
36
|
+
context.fail(`agent-cloud-kit init falló; corre 'npx ${spec} init'.`, run.output);
|
|
37
37
|
return false;
|
|
38
38
|
},
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
-
if (latest === null || (version !== null &&
|
|
41
|
+
if (latest === null || (version !== null && compareSemver(latest, version) <= 0))
|
|
42
42
|
return null;
|
|
43
43
|
return {
|
|
44
44
|
piece: NAME,
|
|
45
45
|
checked: true,
|
|
46
|
-
downloads: [],
|
|
46
|
+
downloads: [`${PACKAGE}@${latest}`],
|
|
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
|
-
const schema = typeof current.$schema === "string" ? current.$schema.replace(
|
|
50
|
+
const schema = typeof current.$schema === "string" ? current.$schema.replace(/\/agent-cloud-kit@[^/]+\//, `/${PACKAGE}@${latest}/`) : undefined;
|
|
51
51
|
writeJson(context.root, CONFIG, { ...current, ...(schema === undefined ? {} : { $schema: schema }), version: latest });
|
|
52
|
-
|
|
52
|
+
const spec = `${PACKAGE}@${latest}`;
|
|
53
|
+
const run = await runNpx(context.root, [spec, "init"]);
|
|
54
|
+
if (run.ok)
|
|
55
|
+
return true;
|
|
56
|
+
context.fail(`agent-cloud-kit init falló; corre 'npx ${spec} init'.`, run.output);
|
|
57
|
+
return false;
|
|
53
58
|
},
|
|
54
59
|
};
|
|
55
60
|
}
|
|
56
61
|
/**
|
|
57
|
-
* What the repo has of
|
|
62
|
+
* What the repo has of agent-cloud-kit, and the step it needs.
|
|
58
63
|
* @param root - The repo.
|
|
59
64
|
* @returns The piece's status.
|
|
60
65
|
* @example (await cloudStatus(root)).state // "1.0.0, al día"
|
|
61
66
|
*/
|
|
62
67
|
export async function cloudStatus(root) {
|
|
63
68
|
const config = readJson(root, CONFIG);
|
|
64
|
-
const latest = await
|
|
69
|
+
const latest = await npmLatestExact(PACKAGE);
|
|
65
70
|
const version = pinned(config);
|
|
66
71
|
const step = stepFor(config, latest);
|
|
67
72
|
const known = latest === null ? " (npm no responde)" : "";
|
|
@@ -79,10 +84,10 @@ export async function cloudChecks(root) {
|
|
|
79
84
|
if (config === null)
|
|
80
85
|
return [{ name: NAME, status: "info", detail: "no instalado" }];
|
|
81
86
|
const version = pinned(config);
|
|
82
|
-
const latest = await
|
|
87
|
+
const latest = await npmLatestExact(PACKAGE);
|
|
83
88
|
if (version === null)
|
|
84
89
|
return [{ name: NAME, status: "fail", detail: `${CONFIG} no fija una versión exacta: pon en "version" la que se usa, como "${latest ?? "1.0.0"}"` }];
|
|
85
|
-
if (latest !== null &&
|
|
90
|
+
if (latest !== null && compareSemver(latest, version) > 0)
|
|
86
91
|
return [{ name: NAME, status: "info", detail: `${version}, hay ${latest}: corre npx agent-kitchen apply` }];
|
|
87
92
|
return [{ name: NAME, status: "ok", detail: version }];
|
|
88
93
|
}
|
package/dist/texts/catalog.d.ts
CHANGED
|
@@ -39,6 +39,8 @@ export interface Catalog {
|
|
|
39
39
|
summary: (failed: string[]) => string;
|
|
40
40
|
/** What is left to do by hand after the steps, in the checkout; with the manager if its install failed. */
|
|
41
41
|
next: (failedInstall: string | null) => string;
|
|
42
|
+
/** The step after apply when agent-cloud-kit is installed. */
|
|
43
|
+
cloudNext: string;
|
|
42
44
|
/** A new piece left out because no one was asked about it. */
|
|
43
45
|
undecided: (names: string[]) => string;
|
|
44
46
|
/** The repo's own skills left out of a pick. */
|
package/dist/texts/es.js
CHANGED
|
@@ -53,14 +53,14 @@ export const es = {
|
|
|
53
53
|
done: `github-rest subido de ${from} a ${to}, el mínimo de issue-flow ${flow}`,
|
|
54
54
|
}),
|
|
55
55
|
"cloud-install": ({ version }) => ({
|
|
56
|
-
menu: `Instalar
|
|
57
|
-
doing: `Instalando
|
|
58
|
-
done: `
|
|
56
|
+
menu: `Instalar agent-cloud-kit ${version ?? "1.x"}: prepara las sesiones en la nube de Claude`,
|
|
57
|
+
doing: `Instalando agent-cloud-kit ${version ?? "1.x"}…`,
|
|
58
|
+
done: `agent-cloud-kit ${version ?? "1.x"} instalado: prepara las sesiones en la nube de Claude`,
|
|
59
59
|
}),
|
|
60
60
|
"cloud-update": ({ from, to, config }) => ({
|
|
61
|
-
menu: `Actualizar
|
|
62
|
-
doing: `Actualizando
|
|
63
|
-
done: `
|
|
61
|
+
menu: `Actualizar agent-cloud-kit ${from ?? "?"} → ${to} (la versión que fija ${config})`,
|
|
62
|
+
doing: `Actualizando agent-cloud-kit de ${from ?? "?"} a ${to}…`,
|
|
63
|
+
done: `agent-cloud-kit actualizado de ${from ?? "?"} a ${to} en ${config}`,
|
|
64
64
|
}),
|
|
65
65
|
"guard-install": ({ version }) => ({
|
|
66
66
|
menu: `Instalar claude-repo-guard ${version ?? "(main)"}: modo auto con sandbox, y un documento de qué protege`,
|
|
@@ -128,6 +128,7 @@ export const es = {
|
|
|
128
128
|
suggested: (dryRun) => `Pasos sugeridos${dryRun ? "" : " (para hacerlos, corre agent-kitchen apply en una terminal, o con --yes)"}:`,
|
|
129
129
|
summary: (failed) => (failed.length === 0 ? "Listo." : `Terminó, pero fallaron: ${failed.join("; ")}.`),
|
|
130
130
|
next: (failedInstall) => `Falta: ${failedInstall === null ? "" : `corre '${failedInstall} install', `}revisa el diff y haz commit.`,
|
|
131
|
+
cloudNext: "Siguiente paso para la nube: npx agent-cloud-kit prepare",
|
|
131
132
|
undecided: (names) => `Pieza nueva sin decisión: ${list(names)}. Corre agent-kitchen apply en una terminal para elegir.`,
|
|
132
133
|
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
134
|
saved: (file, commits) => `Guardé qué piezas usa el repo en ${file}${commits ? "" : "; commitéalo"}.`,
|
package/dist/tools.d.ts
CHANGED
|
@@ -19,13 +19,35 @@ export declare function compareVersions(left: string, right: string): number;
|
|
|
19
19
|
* @example isRelease("1.2.3") // true
|
|
20
20
|
*/
|
|
21
21
|
export declare function isRelease(version: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Whether a version is exact semver: a release like 1.2.3, or one with a prerelease like 1.2.3-rc.0.
|
|
24
|
+
* @param version - The text.
|
|
25
|
+
* @returns True for an exact version; ranges, tags and build metadata are not.
|
|
26
|
+
* @example isExactVersion("1.0.0-rc.0") // true
|
|
27
|
+
*/
|
|
28
|
+
export declare function isExactVersion(version: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Compares two exact versions by semver precedence, prereleases included.
|
|
31
|
+
* @param left - A version like 1.0.0-rc.0.
|
|
32
|
+
* @param right - Another.
|
|
33
|
+
* @returns Negative if left is older, 0 if equal, positive if newer.
|
|
34
|
+
* @example compareSemver("1.0.0-rc.1", "1.0.0") // -1
|
|
35
|
+
*/
|
|
36
|
+
export declare function compareSemver(left: string, right: string): number;
|
|
22
37
|
/**
|
|
23
38
|
* The latest version of a package on npm.
|
|
24
39
|
* @param name - The package.
|
|
25
40
|
* @returns The version, or null if npm cannot tell.
|
|
26
|
-
* @example await npmLatest("
|
|
41
|
+
* @example await npmLatest("agent-cloud-kit") // "1.0.0"
|
|
27
42
|
*/
|
|
28
43
|
export declare function npmLatest(name: string): Promise<string | null>;
|
|
44
|
+
/**
|
|
45
|
+
* The `latest` version of a package on npm, even if it is a prerelease like 1.0.0-rc.0.
|
|
46
|
+
* @param name - The package.
|
|
47
|
+
* @returns The version, or null if npm cannot tell or it is not exact semver.
|
|
48
|
+
* @example await npmLatestExact("agent-cloud-kit") // "1.0.0-rc.0"
|
|
49
|
+
*/
|
|
50
|
+
export declare function npmLatestExact(name: string): Promise<string | null>;
|
|
29
51
|
/**
|
|
30
52
|
* The dependencies a version of a package declares on npm.
|
|
31
53
|
* @param spec - The package and its version, as `name@x.y.z`.
|
|
@@ -46,7 +68,7 @@ export declare function latestTag(repo: string): Promise<string | null>;
|
|
|
46
68
|
* @param root - The repo.
|
|
47
69
|
* @param spec - The package, as npx takes it.
|
|
48
70
|
* @returns When it is done.
|
|
49
|
-
* @example void download(root, "
|
|
71
|
+
* @example void download(root, "agent-cloud-kit@1.0.0")
|
|
50
72
|
*/
|
|
51
73
|
export declare function download(root: string, spec: string): Promise<void>;
|
|
52
74
|
/** How a tool ended, and what it printed if it was kept. */
|
|
@@ -60,7 +82,7 @@ export interface ToolRun {
|
|
|
60
82
|
* @param root - The repo.
|
|
61
83
|
* @param args - The package and its arguments.
|
|
62
84
|
* @returns Whether it exited 0, and what it printed.
|
|
63
|
-
* @example await runNpx(root, ["
|
|
85
|
+
* @example await runNpx(root, ["agent-cloud-kit@1.0.0", "init"])
|
|
64
86
|
*/
|
|
65
87
|
export declare function runNpx(root: string, args: string[]): Promise<ToolRun>;
|
|
66
88
|
/**
|
package/dist/tools.js
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
import { spawn } from "node:child_process";
|
|
13
13
|
/** A release version. */
|
|
14
14
|
const VERSION = /^(\d+)\.(\d+)\.(\d+)$/;
|
|
15
|
+
/** An exact semver version: release plus an optional prerelease, no build metadata. */
|
|
16
|
+
const SEMVER = /^(\d+)\.(\d+)\.(\d+)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?$/;
|
|
15
17
|
/** How long a lookup of the latest version may take before it counts as unknown. */
|
|
16
18
|
const LOOKUP_TIMEOUT_MS = 20_000;
|
|
17
19
|
/** A release tag in `git ls-remote --tags --refs` output. */
|
|
@@ -58,6 +60,50 @@ export function compareVersions(left, right) {
|
|
|
58
60
|
export function isRelease(version) {
|
|
59
61
|
return VERSION.test(version);
|
|
60
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Whether a version is exact semver: a release like 1.2.3, or one with a prerelease like 1.2.3-rc.0.
|
|
65
|
+
* @param version - The text.
|
|
66
|
+
* @returns True for an exact version; ranges, tags and build metadata are not.
|
|
67
|
+
* @example isExactVersion("1.0.0-rc.0") // true
|
|
68
|
+
*/
|
|
69
|
+
export function isExactVersion(version) {
|
|
70
|
+
return SEMVER.test(version);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Compares two exact versions by semver precedence, prereleases included.
|
|
74
|
+
* @param left - A version like 1.0.0-rc.0.
|
|
75
|
+
* @param right - Another.
|
|
76
|
+
* @returns Negative if left is older, 0 if equal, positive if newer.
|
|
77
|
+
* @example compareSemver("1.0.0-rc.1", "1.0.0") // -1
|
|
78
|
+
*/
|
|
79
|
+
export function compareSemver(left, right) {
|
|
80
|
+
const [a, b] = [SEMVER.exec(left), SEMVER.exec(right)];
|
|
81
|
+
for (let index = 1; index <= 3; index += 1) {
|
|
82
|
+
const diff = Number(a?.[index] ?? 0) - Number(b?.[index] ?? 0);
|
|
83
|
+
if (diff !== 0)
|
|
84
|
+
return diff;
|
|
85
|
+
}
|
|
86
|
+
const [pre, other] = [a?.[4], b?.[4]];
|
|
87
|
+
if (pre === other)
|
|
88
|
+
return 0;
|
|
89
|
+
if (pre === undefined)
|
|
90
|
+
return 1;
|
|
91
|
+
if (other === undefined)
|
|
92
|
+
return -1;
|
|
93
|
+
const [x, y] = [pre.split("."), other.split(".")];
|
|
94
|
+
for (let index = 0; index < Math.min(x.length, y.length); index += 1) {
|
|
95
|
+
const [p, q] = [x[index], y[index]];
|
|
96
|
+
if (p === q)
|
|
97
|
+
continue;
|
|
98
|
+
const [pNumber, qNumber] = [/^\d+$/.test(p), /^\d+$/.test(q)];
|
|
99
|
+
if (pNumber && qNumber)
|
|
100
|
+
return Number(p) - Number(q);
|
|
101
|
+
if (pNumber !== qNumber)
|
|
102
|
+
return pNumber ? -1 : 1;
|
|
103
|
+
return p < q ? -1 : 1;
|
|
104
|
+
}
|
|
105
|
+
return x.length - y.length;
|
|
106
|
+
}
|
|
61
107
|
/**
|
|
62
108
|
* Runs a program and collects what it prints.
|
|
63
109
|
* @param program - The program.
|
|
@@ -102,15 +148,35 @@ function once(key, lookup) {
|
|
|
102
148
|
* The latest version of a package on npm.
|
|
103
149
|
* @param name - The package.
|
|
104
150
|
* @returns The version, or null if npm cannot tell.
|
|
105
|
-
* @example await npmLatest("
|
|
151
|
+
* @example await npmLatest("agent-cloud-kit") // "1.0.0"
|
|
106
152
|
*/
|
|
107
153
|
export function npmLatest(name) {
|
|
108
154
|
return once(`npm:${name}`, async () => {
|
|
109
|
-
const
|
|
110
|
-
const version = result.status === 0 ? result.out.trim() : "";
|
|
155
|
+
const version = await npmVersion(name);
|
|
111
156
|
return isRelease(version) ? version : null;
|
|
112
157
|
});
|
|
113
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* The `latest` version of a package on npm, even if it is a prerelease like 1.0.0-rc.0.
|
|
161
|
+
* @param name - The package.
|
|
162
|
+
* @returns The version, or null if npm cannot tell or it is not exact semver.
|
|
163
|
+
* @example await npmLatestExact("agent-cloud-kit") // "1.0.0-rc.0"
|
|
164
|
+
*/
|
|
165
|
+
export function npmLatestExact(name) {
|
|
166
|
+
return once(`npm-exact:${name}`, async () => {
|
|
167
|
+
const version = await npmVersion(name);
|
|
168
|
+
return isExactVersion(version) ? version : null;
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* What `npm view <name> version` prints.
|
|
173
|
+
* @param name - The package.
|
|
174
|
+
* @returns The text, or "" if npm fails.
|
|
175
|
+
*/
|
|
176
|
+
async function npmVersion(name) {
|
|
177
|
+
const result = await run("npm", ["view", name, "version", "--fetch-retries=0"], { timeout: LOOKUP_TIMEOUT_MS });
|
|
178
|
+
return result.status === 0 ? result.out.trim() : "";
|
|
179
|
+
}
|
|
114
180
|
/**
|
|
115
181
|
* The dependencies a version of a package declares on npm.
|
|
116
182
|
* @param spec - The package and its version, as `name@x.y.z`.
|
|
@@ -152,7 +218,7 @@ export function latestTag(repo) {
|
|
|
152
218
|
* @param root - The repo.
|
|
153
219
|
* @param spec - The package, as npx takes it.
|
|
154
220
|
* @returns When it is done.
|
|
155
|
-
* @example void download(root, "
|
|
221
|
+
* @example void download(root, "agent-cloud-kit@1.0.0")
|
|
156
222
|
*/
|
|
157
223
|
export function download(root, spec) {
|
|
158
224
|
const known = downloads.get(spec);
|
|
@@ -168,7 +234,7 @@ export function download(root, spec) {
|
|
|
168
234
|
* @param root - The repo.
|
|
169
235
|
* @param args - The package and its arguments.
|
|
170
236
|
* @returns Whether it exited 0, and what it printed.
|
|
171
|
-
* @example await runNpx(root, ["
|
|
237
|
+
* @example await runNpx(root, ["agent-cloud-kit@1.0.0", "init"])
|
|
172
238
|
*/
|
|
173
239
|
export async function runNpx(root, args) {
|
|
174
240
|
const result = await run("npx", ["--yes", ...args], { cwd: root, inherit: verbose });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-kitchen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.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",
|