agent-kitchen 0.5.0 → 0.7.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 +14 -4
- package/dist/cli.js +10 -5
- package/dist/commands/doctor.d.ts +1 -9
- package/dist/commands/doctor.js +22 -6
- package/dist/commands/sync.d.ts +22 -1
- package/dist/commands/sync.js +227 -54
- package/dist/commit-texts.d.ts +18 -0
- package/dist/commit-texts.js +29 -0
- package/dist/decisions.d.ts +54 -0
- package/dist/decisions.js +91 -0
- package/dist/git-finish.d.ts +53 -0
- package/dist/git-finish.js +252 -0
- package/dist/menu.d.ts +33 -0
- package/dist/menu.js +48 -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.d.ts +12 -6
- package/dist/pieces/issue-flow.js +151 -29
- package/dist/pieces/skills-manager.d.ts +6 -3
- package/dist/pieces/skills-manager.js +33 -12
- package/dist/pieces/skills.js +3 -4
- package/dist/progress.d.ts +29 -0
- package/dist/progress.js +75 -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/dist/tools.d.ts +33 -2
- package/dist/tools.js +52 -5
- package/package.json +1 -1
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: (manager) => `Falta: corre '${manager} 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/dist/tools.d.ts
CHANGED
|
@@ -26,6 +26,13 @@ export declare function isRelease(version: string): boolean;
|
|
|
26
26
|
* @example await npmLatest("@ramon-sg/claude-cloud") // "1.0.0"
|
|
27
27
|
*/
|
|
28
28
|
export declare function npmLatest(name: string): Promise<string | null>;
|
|
29
|
+
/**
|
|
30
|
+
* The dependencies a version of a package declares on npm.
|
|
31
|
+
* @param spec - The package and its version, as `name@x.y.z`.
|
|
32
|
+
* @returns Each dependency's range, or null if npm cannot tell.
|
|
33
|
+
* @example await npmDependencies("@ramon-sg/issue-flow@0.3.0") // { "@ramon-sg/github-rest": "^0.3.0" }
|
|
34
|
+
*/
|
|
35
|
+
export declare function npmDependencies(spec: string): Promise<Record<string, string> | null>;
|
|
29
36
|
/**
|
|
30
37
|
* The highest `vX.Y.Z` tag of a GitHub repo.
|
|
31
38
|
* @param repo - The repo, as owner/name.
|
|
@@ -64,14 +71,38 @@ export declare function runNpx(root: string, args: string[]): Promise<ToolRun>;
|
|
|
64
71
|
*/
|
|
65
72
|
export declare function failedOutput(output: string): string;
|
|
66
73
|
/**
|
|
67
|
-
* Runs `npx --yes <args>` in the repo and returns what it printed
|
|
74
|
+
* Runs `npx --yes <args>` in the repo and returns what it printed.
|
|
68
75
|
* @param root - The repo.
|
|
69
76
|
* @param args - The package and its arguments.
|
|
70
77
|
* @param lookup - True to give up after the lookups' time limit, for a read that only informs.
|
|
71
|
-
* @returns Its stdout and exit code, or null if npx could not start.
|
|
78
|
+
* @returns Its stdout, stderr and exit code, or null if npx could not start.
|
|
72
79
|
* @example await captureNpx(root, ["@ramon-sg/issue-flow@0.2.0", "doctor", "--json"])
|
|
73
80
|
*/
|
|
74
81
|
export declare function captureNpx(root: string, args: string[], lookup?: boolean): Promise<{
|
|
75
82
|
out: string;
|
|
83
|
+
err: string;
|
|
76
84
|
status: number | null;
|
|
77
85
|
} | null>;
|
|
86
|
+
/**
|
|
87
|
+
* Runs the repo's package manager's install: quietly, or with its output on the terminal
|
|
88
|
+
* with `--verbose`.
|
|
89
|
+
* @param root - The repo.
|
|
90
|
+
* @param manager - `npm`, `pnpm`, `bun` or `yarn`.
|
|
91
|
+
* @returns Whether it worked and, if it ran quietly, what it printed.
|
|
92
|
+
* @example await runInstall(root, "pnpm")
|
|
93
|
+
*/
|
|
94
|
+
export declare function runInstall(root: string, manager: string): Promise<ToolRun>;
|
|
95
|
+
/**
|
|
96
|
+
* Runs `npx --yes <args>` in the repo without some variables of the environment, and returns
|
|
97
|
+
* what it printed.
|
|
98
|
+
* @param root - The repo.
|
|
99
|
+
* @param args - The package and its arguments.
|
|
100
|
+
* @param unset - The variables left out.
|
|
101
|
+
* @returns Its stdout, stderr and exit code.
|
|
102
|
+
* @example await captureNpxWithout(root, ["@ramon-sg/github-rest@0.3.0", "pr", "create"], ["GH_REPO"])
|
|
103
|
+
*/
|
|
104
|
+
export declare function captureNpxWithout(root: string, args: string[], unset: string[]): Promise<{
|
|
105
|
+
out: string;
|
|
106
|
+
err: string;
|
|
107
|
+
status: number | null;
|
|
108
|
+
}>;
|
package/dist/tools.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file How agent-kitchen reaches the other tools and their releases: `npx` to run them (always
|
|
3
3
|
* by their scoped name or GitHub spec, because the unscoped names on npm belong to other
|
|
4
|
-
* people), `npm view` for the latest version on npm, and `git ls-remote` for the latest
|
|
4
|
+
* people), `npm view` for the latest version on npm and a version's dependencies, and `git ls-remote` for the latest
|
|
5
5
|
* `vX.Y.Z` tag on GitHub. Everything is asynchronous so the lookups run at the same time,
|
|
6
6
|
* and each lookup runs once per process. A lookup that fails, or takes over 20 seconds,
|
|
7
7
|
* gives null: the piece is shown, not offered. git never asks for credentials here.
|
|
@@ -67,7 +67,10 @@ export function isRelease(version) {
|
|
|
67
67
|
*/
|
|
68
68
|
function run(program, args, options = {}) {
|
|
69
69
|
return new Promise((resolve) => {
|
|
70
|
-
const
|
|
70
|
+
const env = { ...process.env, ...options.env };
|
|
71
|
+
for (const name of options.unset ?? [])
|
|
72
|
+
delete env[name];
|
|
73
|
+
const child = spawn(program, args, { cwd: options.cwd, env, stdio: options.inherit === true ? "inherit" : ["ignore", "pipe", "pipe"] });
|
|
71
74
|
let out = "";
|
|
72
75
|
let err = "";
|
|
73
76
|
child.stdout?.on("data", (chunk) => (out += chunk.toString()));
|
|
@@ -108,6 +111,26 @@ export function npmLatest(name) {
|
|
|
108
111
|
return isRelease(version) ? version : null;
|
|
109
112
|
});
|
|
110
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* The dependencies a version of a package declares on npm.
|
|
116
|
+
* @param spec - The package and its version, as `name@x.y.z`.
|
|
117
|
+
* @returns Each dependency's range, or null if npm cannot tell.
|
|
118
|
+
* @example await npmDependencies("@ramon-sg/issue-flow@0.3.0") // { "@ramon-sg/github-rest": "^0.3.0" }
|
|
119
|
+
*/
|
|
120
|
+
export function npmDependencies(spec) {
|
|
121
|
+
return once(`npm-deps:${spec}`, async () => {
|
|
122
|
+
const result = await run("npm", ["view", spec, "dependencies", "--json", "--fetch-retries=0"], { timeout: LOOKUP_TIMEOUT_MS });
|
|
123
|
+
if (result.status !== 0)
|
|
124
|
+
return null;
|
|
125
|
+
try {
|
|
126
|
+
const found = JSON.parse(result.out);
|
|
127
|
+
return typeof found === "object" && found !== null && !Array.isArray(found) ? found : null;
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
111
134
|
/**
|
|
112
135
|
* The highest `vX.Y.Z` tag of a GitHub repo.
|
|
113
136
|
* @param repo - The repo, as owner/name.
|
|
@@ -162,14 +185,38 @@ export function failedOutput(output) {
|
|
|
162
185
|
return lines.slice(-FAILED_LINES).map((line) => ` ${line}\n`).join("");
|
|
163
186
|
}
|
|
164
187
|
/**
|
|
165
|
-
* Runs `npx --yes <args>` in the repo and returns what it printed
|
|
188
|
+
* Runs `npx --yes <args>` in the repo and returns what it printed.
|
|
166
189
|
* @param root - The repo.
|
|
167
190
|
* @param args - The package and its arguments.
|
|
168
191
|
* @param lookup - True to give up after the lookups' time limit, for a read that only informs.
|
|
169
|
-
* @returns Its stdout and exit code, or null if npx could not start.
|
|
192
|
+
* @returns Its stdout, stderr and exit code, or null if npx could not start.
|
|
170
193
|
* @example await captureNpx(root, ["@ramon-sg/issue-flow@0.2.0", "doctor", "--json"])
|
|
171
194
|
*/
|
|
172
195
|
export async function captureNpx(root, args, lookup = false) {
|
|
173
196
|
const result = await run("npx", ["--yes", ...args], { cwd: root, ...(lookup ? { timeout: LOOKUP_TIMEOUT_MS } : {}) });
|
|
174
|
-
return result.status === null && result.out === "" ? null : { out: result.out, status: result.status };
|
|
197
|
+
return result.status === null && result.out === "" ? null : { out: result.out, err: result.err, status: result.status };
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Runs the repo's package manager's install: quietly, or with its output on the terminal
|
|
201
|
+
* with `--verbose`.
|
|
202
|
+
* @param root - The repo.
|
|
203
|
+
* @param manager - `npm`, `pnpm`, `bun` or `yarn`.
|
|
204
|
+
* @returns Whether it worked and, if it ran quietly, what it printed.
|
|
205
|
+
* @example await runInstall(root, "pnpm")
|
|
206
|
+
*/
|
|
207
|
+
export async function runInstall(root, manager) {
|
|
208
|
+
const result = await run(manager, ["install"], { cwd: root, inherit: verbose });
|
|
209
|
+
return { ok: result.status === 0, output: `${result.out}${result.err}` };
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Runs `npx --yes <args>` in the repo without some variables of the environment, and returns
|
|
213
|
+
* what it printed.
|
|
214
|
+
* @param root - The repo.
|
|
215
|
+
* @param args - The package and its arguments.
|
|
216
|
+
* @param unset - The variables left out.
|
|
217
|
+
* @returns Its stdout, stderr and exit code.
|
|
218
|
+
* @example await captureNpxWithout(root, ["@ramon-sg/github-rest@0.3.0", "pr", "create"], ["GH_REPO"])
|
|
219
|
+
*/
|
|
220
|
+
export async function captureNpxWithout(root, args, unset) {
|
|
221
|
+
return run("npx", ["--yes", ...args], { cwd: root, unset });
|
|
175
222
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-kitchen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.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",
|