@slowcook-ai/cli 0.1.0 → 0.3.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 +76 -1
- package/dist/cli.js +15 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/init/index.d.ts +2 -0
- package/dist/commands/init/index.d.ts.map +1 -0
- package/dist/commands/init/index.js +181 -0
- package/dist/commands/init/index.js.map +1 -0
- package/dist/commands/init/plan.d.ts +58 -0
- package/dist/commands/init/plan.d.ts.map +1 -0
- package/dist/commands/init/plan.js +136 -0
- package/dist/commands/init/plan.js.map +1 -0
- package/dist/commands/init/templates.d.ts +17 -0
- package/dist/commands/init/templates.d.ts.map +1 -0
- package/dist/commands/init/templates.js +163 -0
- package/dist/commands/init/templates.js.map +1 -0
- package/dist/commands/manifest.d.ts +2 -0
- package/dist/commands/manifest.d.ts.map +1 -0
- package/dist/commands/manifest.js +189 -0
- package/dist/commands/manifest.js.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -8,7 +8,33 @@ CLI for the slowcook brewing harness. Installs the `slowcook` binary.
|
|
|
8
8
|
npm i -D @slowcook-ai/cli
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
## Commands (v0.
|
|
11
|
+
## Commands (v0.3)
|
|
12
|
+
|
|
13
|
+
### `slowcook init`
|
|
14
|
+
|
|
15
|
+
Scaffold slowcook configuration in a consumer project. Writes `.brewing/*`, `.github/workflows/slowcook.yml`, and a `CODEOWNERS` section. Idempotent — re-running skips existing files unless `--force`.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx slowcook init [--owner <handle>] [--force] [--dry-run] [--cwd <path>]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Options:**
|
|
22
|
+
|
|
23
|
+
| Flag | Default | Description |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| `--cwd <path>` | `.` | Target project directory |
|
|
26
|
+
| `--owner <handle>` | detected from git remote | CODEOWNERS handle/team (e.g. `@aminazar`, `@acme/frontend`) |
|
|
27
|
+
| `--force` | false | Overwrite existing slowcook files |
|
|
28
|
+
| `--dry-run` | false | Print the plan without writing anything |
|
|
29
|
+
|
|
30
|
+
**Stack detection (0.3):** reads `package.json`. Requires Vitest in `devDependencies`. If Playwright is present, it's noted as a warning and left out of `stack.json` until slowcook supports Playwright discovery.
|
|
31
|
+
|
|
32
|
+
**CODEOWNERS handling:** uses `# --- slowcook:frozen-paths BEGIN/END ---` markers so re-running or adopting slowcook in a repo that already has a `CODEOWNERS` is safe.
|
|
33
|
+
|
|
34
|
+
**Exit codes:**
|
|
35
|
+
|
|
36
|
+
- `0` — success (or dry-run completed)
|
|
37
|
+
- `2` — script error (no `package.json`, vitest not found, invalid JSON)
|
|
12
38
|
|
|
13
39
|
### `slowcook guard`
|
|
14
40
|
|
|
@@ -79,6 +105,55 @@ jobs:
|
|
|
79
105
|
|
|
80
106
|
The guard emits `::error file=...::` annotations and writes to `$GITHUB_STEP_SUMMARY` when run in GitHub Actions.
|
|
81
107
|
|
|
108
|
+
### `slowcook manifest` (record / verify)
|
|
109
|
+
|
|
110
|
+
Captures the set of discoverable tests so agents can't silently remove or exclude them. 0.2 supports Vitest; Playwright is coming later.
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# Record a snapshot of every test currently discoverable
|
|
114
|
+
npx slowcook manifest record
|
|
115
|
+
|
|
116
|
+
# Verify later that the recorded set still fully resolves
|
|
117
|
+
npx slowcook manifest verify
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Options (both subcommands):**
|
|
121
|
+
|
|
122
|
+
| Flag | Default | Description |
|
|
123
|
+
|---|---|---|
|
|
124
|
+
| `--stack-config <path>` | `.brewing/stack.json` | Consumer stack config |
|
|
125
|
+
| `--manifest <path>` | `.brewing/manifests/all.json` (or `.brewing/manifests/story-<id>.json` if `--story`) | Where to write / read the manifest |
|
|
126
|
+
| `--story <id>` | none | Tag manifest with a story id (enables per-story freezing) |
|
|
127
|
+
| `--cwd <path>` | `.` | Working directory for discovery commands |
|
|
128
|
+
|
|
129
|
+
**Config file** — `.brewing/stack.json` declares how to discover tests per suite:
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"language": "typescript",
|
|
134
|
+
"test": {
|
|
135
|
+
"backend": {
|
|
136
|
+
"runner": "vitest",
|
|
137
|
+
"run_command": "npx vitest run",
|
|
138
|
+
"discover_command": "npx vitest list",
|
|
139
|
+
"reporter_format": "vitest-list-lines"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Exit codes:**
|
|
146
|
+
|
|
147
|
+
- `record`: `0` manifest written, `2` script error (bad config, suite discovery failed)
|
|
148
|
+
- `verify`: `0` manifest matches (new tests since record are informational), `1` recorded tests no longer discoverable, `2` script error
|
|
149
|
+
|
|
150
|
+
**Use in GitHub Actions** — after the frozen-paths guard:
|
|
151
|
+
|
|
152
|
+
```yaml
|
|
153
|
+
- name: Verify test manifest
|
|
154
|
+
run: npx --yes @slowcook-ai/cli@latest manifest verify
|
|
155
|
+
```
|
|
156
|
+
|
|
82
157
|
## Coming in later versions
|
|
83
158
|
|
|
84
159
|
See the [monorepo README](../../README.md) for the roadmap.
|
package/dist/cli.js
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { guard } from "./commands/guard.js";
|
|
3
|
-
|
|
3
|
+
import { manifest } from "./commands/manifest.js";
|
|
4
|
+
import { init } from "./commands/init/index.js";
|
|
5
|
+
const VERSION = "0.3.0";
|
|
4
6
|
const USAGE = `
|
|
5
7
|
slowcook — TDD-first agentic development harness
|
|
6
8
|
|
|
7
9
|
Usage:
|
|
10
|
+
slowcook init [--owner <handle>] [--force] [--dry-run] [--cwd <path>]
|
|
8
11
|
slowcook guard --base <ref> --head <ref> [--override] [--config <path>]
|
|
12
|
+
slowcook manifest record [--stack-config <path>] [--manifest <path>] [--story <id>]
|
|
13
|
+
slowcook manifest verify [--stack-config <path>] [--manifest <path>] [--story <id>]
|
|
9
14
|
slowcook version
|
|
10
15
|
slowcook help
|
|
11
16
|
|
|
12
17
|
Commands available in ${VERSION}:
|
|
18
|
+
init Scaffold slowcook configuration in a consumer project.
|
|
13
19
|
guard Check for frozen-path violations between two git refs.
|
|
20
|
+
manifest Record or verify the set of discoverable tests.
|
|
14
21
|
|
|
15
22
|
Coming in later versions:
|
|
16
|
-
|
|
23
|
+
refine, testgen, brew, review, dashboard
|
|
17
24
|
|
|
18
25
|
Docs: https://github.com/aminazar/slowcook
|
|
19
26
|
`;
|
|
@@ -21,9 +28,15 @@ async function main() {
|
|
|
21
28
|
const args = process.argv.slice(2);
|
|
22
29
|
const command = args[0];
|
|
23
30
|
switch (command) {
|
|
31
|
+
case "init":
|
|
32
|
+
await init(args.slice(1), VERSION);
|
|
33
|
+
return;
|
|
24
34
|
case "guard":
|
|
25
35
|
await guard(args.slice(1));
|
|
26
36
|
return;
|
|
37
|
+
case "manifest":
|
|
38
|
+
await manifest(args.slice(1));
|
|
39
|
+
return;
|
|
27
40
|
case "version":
|
|
28
41
|
case "--version":
|
|
29
42
|
case "-v":
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAEhD,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB,MAAM,KAAK,GAAG;;;;;;;;;;;wBAWU,OAAO;;;;;;;;;CAS9B,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAExB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM;YACT,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACnC,OAAO;QACT,KAAK,OAAO;YACV,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3B,OAAO;QACT,KAAK,UAAU;YACb,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9B,OAAO;QACT,KAAK,SAAS,CAAC;QACf,KAAK,WAAW,CAAC;QACjB,KAAK,IAAI;YACP,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;YACnC,OAAO;QACT,KAAK,SAAS,CAAC;QACf,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,IAAI;YACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnB,OAAO;QACT;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW;IACjC,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/init/index.ts"],"names":[],"mappings":"AAmIA,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2E5E"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, } from "node:fs";
|
|
2
|
+
import { dirname, resolve, relative, isAbsolute } from "node:path";
|
|
3
|
+
import { execSync } from "node:child_process";
|
|
4
|
+
import { buildPlan, InitError } from "./plan.js";
|
|
5
|
+
function parseArgs(argv) {
|
|
6
|
+
const args = {
|
|
7
|
+
cwd: process.cwd(),
|
|
8
|
+
owner: undefined,
|
|
9
|
+
force: false,
|
|
10
|
+
dryRun: false,
|
|
11
|
+
};
|
|
12
|
+
for (let i = 0; i < argv.length; i++) {
|
|
13
|
+
const arg = argv[i];
|
|
14
|
+
const next = argv[i + 1];
|
|
15
|
+
if (arg === "--cwd" && next) {
|
|
16
|
+
args.cwd = resolve(next);
|
|
17
|
+
i++;
|
|
18
|
+
}
|
|
19
|
+
else if (arg === "--owner" && next) {
|
|
20
|
+
args.owner = next;
|
|
21
|
+
i++;
|
|
22
|
+
}
|
|
23
|
+
else if (arg === "--force") {
|
|
24
|
+
args.force = true;
|
|
25
|
+
}
|
|
26
|
+
else if (arg === "--dry-run") {
|
|
27
|
+
args.dryRun = true;
|
|
28
|
+
}
|
|
29
|
+
else if (arg === "--help" || arg === "-h") {
|
|
30
|
+
printHelp();
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return args;
|
|
35
|
+
}
|
|
36
|
+
function printHelp() {
|
|
37
|
+
console.log(`
|
|
38
|
+
slowcook init — scaffold slowcook configuration in a consumer project
|
|
39
|
+
|
|
40
|
+
Usage:
|
|
41
|
+
slowcook init [options]
|
|
42
|
+
|
|
43
|
+
Options:
|
|
44
|
+
--cwd <path> Target project directory (default: current directory)
|
|
45
|
+
--owner <handle> CODEOWNERS handle/team, e.g. "@aminazar" or "@acme/frontend".
|
|
46
|
+
If omitted, slowcook tries to detect from \`git remote get-url origin\`;
|
|
47
|
+
falls back to "@TODO-OWNER" with a warning.
|
|
48
|
+
--force Overwrite existing slowcook files (default: skip existing)
|
|
49
|
+
--dry-run Print the plan without writing anything to disk
|
|
50
|
+
--help, -h Show this help
|
|
51
|
+
|
|
52
|
+
Writes:
|
|
53
|
+
.brewing/frozen-paths.json
|
|
54
|
+
.brewing/stack.json
|
|
55
|
+
.brewing/README.md
|
|
56
|
+
.brewing/manifests/.gitkeep
|
|
57
|
+
.github/workflows/slowcook.yml
|
|
58
|
+
CODEOWNERS (appends slowcook section if file exists)
|
|
59
|
+
|
|
60
|
+
Exit codes:
|
|
61
|
+
0 success (or dry-run completed)
|
|
62
|
+
2 script error (no package.json, vitest not detected, etc.)
|
|
63
|
+
`);
|
|
64
|
+
}
|
|
65
|
+
function makeReader(cwd) {
|
|
66
|
+
return {
|
|
67
|
+
exists: (p) => existsSync(resolveIn(cwd, p)),
|
|
68
|
+
read: (p) => readFileSync(resolveIn(cwd, p), "utf8"),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function resolveIn(cwd, path) {
|
|
72
|
+
if (isAbsolute(path))
|
|
73
|
+
return path;
|
|
74
|
+
return resolve(cwd, path);
|
|
75
|
+
}
|
|
76
|
+
function detectOwnerFromGitRemote(cwd) {
|
|
77
|
+
try {
|
|
78
|
+
const url = execSync("git remote get-url origin", {
|
|
79
|
+
cwd,
|
|
80
|
+
encoding: "utf8",
|
|
81
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
82
|
+
}).trim();
|
|
83
|
+
// https://github.com/USER/REPO.git | git@github.com:USER/REPO.git
|
|
84
|
+
const m = url.match(/github\.com[:/]([^/]+)\/[^/.]+(?:\.git)?$/) ??
|
|
85
|
+
url.match(/gitlab\.com[:/]([^/]+)\/[^/.]+(?:\.git)?$/);
|
|
86
|
+
if (m && m[1])
|
|
87
|
+
return `@${m[1]}`;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// not a git repo, or no origin — fine, fall through
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
function formatAction(a) {
|
|
95
|
+
switch (a.kind) {
|
|
96
|
+
case "create":
|
|
97
|
+
return ` CREATE ${a.path}`;
|
|
98
|
+
case "overwrite":
|
|
99
|
+
return ` OVERWRITE ${a.path}`;
|
|
100
|
+
case "append":
|
|
101
|
+
return ` APPEND ${a.path} (preserving existing content)`;
|
|
102
|
+
case "skip-exists":
|
|
103
|
+
return ` SKIP ${a.path} (${a.reason})`;
|
|
104
|
+
case "conflict":
|
|
105
|
+
return ` CONFLICT ${a.path} (${a.reason})`;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function applyAction(cwd, a) {
|
|
109
|
+
if (a.kind === "skip-exists" || a.kind === "conflict")
|
|
110
|
+
return;
|
|
111
|
+
const full = resolveIn(cwd, a.path);
|
|
112
|
+
mkdirSync(dirname(full), { recursive: true });
|
|
113
|
+
const contents = a.kind === "create" || a.kind === "overwrite" || a.kind === "append"
|
|
114
|
+
? a.contents
|
|
115
|
+
: "";
|
|
116
|
+
writeFileSync(full, contents, "utf8");
|
|
117
|
+
}
|
|
118
|
+
export async function init(argv, cliVersion) {
|
|
119
|
+
const args = parseArgs(argv);
|
|
120
|
+
const reader = makeReader(args.cwd);
|
|
121
|
+
let owner = args.owner;
|
|
122
|
+
if (!owner) {
|
|
123
|
+
const detected = detectOwnerFromGitRemote(args.cwd);
|
|
124
|
+
if (detected) {
|
|
125
|
+
owner = detected;
|
|
126
|
+
console.log(`Detected CODEOWNERS handle from git remote: ${owner}`);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
owner = "@TODO-OWNER";
|
|
130
|
+
console.log("::warning::Could not detect a CODEOWNERS handle from git remote. Using @TODO-OWNER as a placeholder — replace it after init.");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
let plan;
|
|
134
|
+
try {
|
|
135
|
+
plan = buildPlan(reader, {
|
|
136
|
+
cwd: args.cwd,
|
|
137
|
+
owner,
|
|
138
|
+
force: args.force,
|
|
139
|
+
cliVersion,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
if (e instanceof InitError) {
|
|
144
|
+
console.error(`slowcook init: ${e.message}`);
|
|
145
|
+
process.exit(2);
|
|
146
|
+
}
|
|
147
|
+
throw e;
|
|
148
|
+
}
|
|
149
|
+
console.log(`Detected stack:`);
|
|
150
|
+
console.log(` language: ${plan.detected.language}`);
|
|
151
|
+
console.log(` vitest: ${plan.detected.hasVitest}`);
|
|
152
|
+
console.log(` playwright: ${plan.detected.hasPlaywright}`);
|
|
153
|
+
console.log();
|
|
154
|
+
if (plan.warnings.length > 0) {
|
|
155
|
+
console.log("Warnings:");
|
|
156
|
+
for (const w of plan.warnings)
|
|
157
|
+
console.log(` - ${w}`);
|
|
158
|
+
console.log();
|
|
159
|
+
}
|
|
160
|
+
console.log(`Planned file actions (cwd: ${relative(process.cwd(), args.cwd) || "."}):`);
|
|
161
|
+
for (const a of plan.actions)
|
|
162
|
+
console.log(formatAction(a));
|
|
163
|
+
console.log();
|
|
164
|
+
if (args.dryRun) {
|
|
165
|
+
console.log("Dry-run complete — no files written.");
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
for (const a of plan.actions)
|
|
169
|
+
applyAction(args.cwd, a);
|
|
170
|
+
const skippedCount = plan.actions.filter((a) => a.kind === "skip-exists").length;
|
|
171
|
+
console.log(`slowcook init: ${plan.actions.length - skippedCount} file(s) written, ${skippedCount} skipped.`);
|
|
172
|
+
console.log();
|
|
173
|
+
console.log("Next steps:");
|
|
174
|
+
console.log(` 1. Review .brewing/frozen-paths.json — add/remove directories to match your repo.`);
|
|
175
|
+
if (owner === "@TODO-OWNER") {
|
|
176
|
+
console.log(` 2. Replace @TODO-OWNER in CODEOWNERS with your GitHub handle/team.`);
|
|
177
|
+
}
|
|
178
|
+
console.log(` ${owner === "@TODO-OWNER" ? "3." : "2."} Run \`slowcook manifest record\` once your test set is stable.`);
|
|
179
|
+
console.log(` ${owner === "@TODO-OWNER" ? "4." : "3."} Commit and open a PR; slowcook CI will run on it.`);
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/init/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export interface PackageJson {
|
|
2
|
+
dependencies?: Record<string, string>;
|
|
3
|
+
devDependencies?: Record<string, string>;
|
|
4
|
+
scripts?: Record<string, string>;
|
|
5
|
+
}
|
|
6
|
+
export interface DetectedStack {
|
|
7
|
+
language: "typescript";
|
|
8
|
+
hasVitest: boolean;
|
|
9
|
+
hasPlaywright: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Minimal filesystem reader so planning is pure. */
|
|
12
|
+
export interface FileReader {
|
|
13
|
+
exists(path: string): boolean;
|
|
14
|
+
read(path: string): string;
|
|
15
|
+
}
|
|
16
|
+
export interface PlanOptions {
|
|
17
|
+
/** Consumer project root (where package.json lives). */
|
|
18
|
+
cwd: string;
|
|
19
|
+
/** CODEOWNERS handle/team (e.g., "@aminazar"). */
|
|
20
|
+
owner: string;
|
|
21
|
+
/** Overwrite existing files (default: skip-if-exists). */
|
|
22
|
+
force: boolean;
|
|
23
|
+
/** Version of the CLI invoking init; drives the CI workflow pin. */
|
|
24
|
+
cliVersion?: string;
|
|
25
|
+
}
|
|
26
|
+
export type FileAction = {
|
|
27
|
+
kind: "create";
|
|
28
|
+
path: string;
|
|
29
|
+
contents: string;
|
|
30
|
+
} | {
|
|
31
|
+
kind: "skip-exists";
|
|
32
|
+
path: string;
|
|
33
|
+
reason: string;
|
|
34
|
+
} | {
|
|
35
|
+
kind: "overwrite";
|
|
36
|
+
path: string;
|
|
37
|
+
contents: string;
|
|
38
|
+
} | {
|
|
39
|
+
kind: "append";
|
|
40
|
+
path: string;
|
|
41
|
+
contents: string;
|
|
42
|
+
existingContents: string;
|
|
43
|
+
} | {
|
|
44
|
+
kind: "conflict";
|
|
45
|
+
path: string;
|
|
46
|
+
reason: string;
|
|
47
|
+
};
|
|
48
|
+
export interface Plan {
|
|
49
|
+
detected: DetectedStack;
|
|
50
|
+
actions: FileAction[];
|
|
51
|
+
warnings: string[];
|
|
52
|
+
}
|
|
53
|
+
export declare function detectStack(pkg: PackageJson): DetectedStack;
|
|
54
|
+
export declare class InitError extends Error {
|
|
55
|
+
constructor(message: string);
|
|
56
|
+
}
|
|
57
|
+
export declare function buildPlan(reader: FileReader, options: PlanOptions): Plan;
|
|
58
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/commands/init/plan.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,qDAAqD;AACrD,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,KAAK,EAAE,OAAO,CAAC;IACf,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,GAC5E;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,MAAM,WAAW,IAAI;IACnB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAYD,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,aAAa,CAO3D;AAED,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAiExE"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// Pure planning logic for `slowcook init`. Takes a snapshot of the filesystem
|
|
2
|
+
// (via an injected reader), returns the planned actions. No I/O side effects
|
|
3
|
+
// here — all writes happen in the CLI wrapper so this is trivially testable.
|
|
4
|
+
import { frozenPathsJson, stackJson, brewingReadme, slowcookWorkflow, codeownersFullFile, codeownersSection, gitkeep, CLI_VERSION_FOR_TEMPLATES, SLOWCOOK_CODEOWNERS_MARKER_BEGIN, SLOWCOOK_CODEOWNERS_MARKER_END, } from "./templates.js";
|
|
5
|
+
const TARGETS = {
|
|
6
|
+
frozenPaths: ".brewing/frozen-paths.json",
|
|
7
|
+
stack: ".brewing/stack.json",
|
|
8
|
+
brewingReadme: ".brewing/README.md",
|
|
9
|
+
manifestsGitkeep: ".brewing/manifests/.gitkeep",
|
|
10
|
+
workflow: ".github/workflows/slowcook.yml",
|
|
11
|
+
codeowners: "CODEOWNERS",
|
|
12
|
+
packageJson: "package.json",
|
|
13
|
+
};
|
|
14
|
+
export function detectStack(pkg) {
|
|
15
|
+
const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };
|
|
16
|
+
return {
|
|
17
|
+
language: "typescript",
|
|
18
|
+
hasVitest: "vitest" in deps,
|
|
19
|
+
hasPlaywright: "@playwright/test" in deps || "playwright" in deps,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export class InitError extends Error {
|
|
23
|
+
constructor(message) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.name = "InitError";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function buildPlan(reader, options) {
|
|
29
|
+
if (!reader.exists(TARGETS.packageJson)) {
|
|
30
|
+
throw new InitError(`No package.json found at ${options.cwd}. \`slowcook init\` expects to run in a TS/JS project root.`);
|
|
31
|
+
}
|
|
32
|
+
let pkg;
|
|
33
|
+
try {
|
|
34
|
+
pkg = JSON.parse(reader.read(TARGETS.packageJson));
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
throw new InitError(`package.json is not valid JSON: ${e.message}`);
|
|
38
|
+
}
|
|
39
|
+
const detected = detectStack(pkg);
|
|
40
|
+
const warnings = [];
|
|
41
|
+
const actions = [];
|
|
42
|
+
const cliVersion = options.cliVersion ?? CLI_VERSION_FOR_TEMPLATES;
|
|
43
|
+
if (!detected.hasVitest) {
|
|
44
|
+
throw new InitError(`No test runner detected. slowcook 0.3 requires Vitest (found in devDependencies). ` +
|
|
45
|
+
`Install it with \`npm i -D vitest\` and re-run.`);
|
|
46
|
+
}
|
|
47
|
+
if (detected.hasPlaywright) {
|
|
48
|
+
warnings.push("Playwright detected. slowcook 0.3 doesn't yet implement Playwright discovery, " +
|
|
49
|
+
"so the e2e suite is intentionally omitted from stack.json. Add it back when " +
|
|
50
|
+
"playwright discovery ships in a later slowcook release.");
|
|
51
|
+
}
|
|
52
|
+
const tmplParams = {
|
|
53
|
+
owner: options.owner,
|
|
54
|
+
hasPlaywright: detected.hasPlaywright,
|
|
55
|
+
};
|
|
56
|
+
// 1. .brewing/frozen-paths.json
|
|
57
|
+
addSimpleFile(actions, reader, options.force, TARGETS.frozenPaths, frozenPathsJson());
|
|
58
|
+
// 2. .brewing/stack.json
|
|
59
|
+
addSimpleFile(actions, reader, options.force, TARGETS.stack, stackJson(tmplParams));
|
|
60
|
+
// 3. .brewing/README.md
|
|
61
|
+
addSimpleFile(actions, reader, options.force, TARGETS.brewingReadme, brewingReadme());
|
|
62
|
+
// 4. .brewing/manifests/.gitkeep (only if we're creating the dir)
|
|
63
|
+
if (!reader.exists(".brewing/manifests/")) {
|
|
64
|
+
actions.push({ kind: "create", path: TARGETS.manifestsGitkeep, contents: gitkeep() });
|
|
65
|
+
}
|
|
66
|
+
// 5. .github/workflows/slowcook.yml
|
|
67
|
+
addSimpleFile(actions, reader, options.force, TARGETS.workflow, slowcookWorkflow(cliVersion));
|
|
68
|
+
// 6. CODEOWNERS — special case (append if exists without our markers)
|
|
69
|
+
actions.push(planCodeowners(reader, options, tmplParams));
|
|
70
|
+
return { detected, actions, warnings };
|
|
71
|
+
}
|
|
72
|
+
function addSimpleFile(actions, reader, force, path, contents) {
|
|
73
|
+
if (!reader.exists(path)) {
|
|
74
|
+
actions.push({ kind: "create", path, contents });
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const existing = reader.read(path);
|
|
78
|
+
if (existing === contents) {
|
|
79
|
+
actions.push({ kind: "skip-exists", path, reason: "file already matches template" });
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (force) {
|
|
83
|
+
actions.push({ kind: "overwrite", path, contents });
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
actions.push({
|
|
87
|
+
kind: "skip-exists",
|
|
88
|
+
path,
|
|
89
|
+
reason: "file exists and differs from template (use --force to overwrite)",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
function planCodeowners(reader, options, params) {
|
|
93
|
+
const path = TARGETS.codeowners;
|
|
94
|
+
if (!reader.exists(path)) {
|
|
95
|
+
return { kind: "create", path, contents: codeownersFullFile(params) };
|
|
96
|
+
}
|
|
97
|
+
const existing = reader.read(path);
|
|
98
|
+
if (existing.includes(SLOWCOOK_CODEOWNERS_MARKER_BEGIN) &&
|
|
99
|
+
existing.includes(SLOWCOOK_CODEOWNERS_MARKER_END)) {
|
|
100
|
+
if (options.force) {
|
|
101
|
+
// Replace the slowcook section inline
|
|
102
|
+
const replaced = replaceCodeownersSection(existing, params);
|
|
103
|
+
return { kind: "overwrite", path, contents: replaced };
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
kind: "skip-exists",
|
|
107
|
+
path,
|
|
108
|
+
reason: "slowcook section already present (use --force to regenerate)",
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
// Existing CODEOWNERS without our markers → append
|
|
112
|
+
const toAppend = (existing.endsWith("\n") ? existing : existing + "\n") +
|
|
113
|
+
"\n" +
|
|
114
|
+
codeownersSection(params);
|
|
115
|
+
return {
|
|
116
|
+
kind: "append",
|
|
117
|
+
path,
|
|
118
|
+
contents: toAppend,
|
|
119
|
+
existingContents: existing,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function replaceCodeownersSection(existing, params) {
|
|
123
|
+
const begin = existing.indexOf(SLOWCOOK_CODEOWNERS_MARKER_BEGIN);
|
|
124
|
+
const endMarkerStart = existing.indexOf(SLOWCOOK_CODEOWNERS_MARKER_END);
|
|
125
|
+
if (begin === -1 || endMarkerStart === -1 || endMarkerStart < begin) {
|
|
126
|
+
// Shouldn't happen if caller verified markers exist, but be defensive
|
|
127
|
+
return existing + "\n" + codeownersSection(params);
|
|
128
|
+
}
|
|
129
|
+
const endMarkerEnd = endMarkerStart + SLOWCOOK_CODEOWNERS_MARKER_END.length;
|
|
130
|
+
// Include the trailing newline if present
|
|
131
|
+
const after = existing[endMarkerEnd] === "\n"
|
|
132
|
+
? existing.slice(endMarkerEnd + 1)
|
|
133
|
+
: existing.slice(endMarkerEnd);
|
|
134
|
+
return existing.slice(0, begin) + codeownersSection(params) + after;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/commands/init/plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const CLI_VERSION_FOR_TEMPLATES = "0.3.0";
|
|
2
|
+
export interface TemplateParams {
|
|
3
|
+
/** CODEOWNERS handle or team (e.g. "@aminazar" or "@acme/frontend"). */
|
|
4
|
+
owner: string;
|
|
5
|
+
/** Whether the project has Playwright installed (affects stack.json comments). */
|
|
6
|
+
hasPlaywright: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare const SLOWCOOK_CODEOWNERS_MARKER_BEGIN = "# --- slowcook:frozen-paths BEGIN ---";
|
|
9
|
+
export declare const SLOWCOOK_CODEOWNERS_MARKER_END = "# --- slowcook:frozen-paths END ---";
|
|
10
|
+
export declare function frozenPathsJson(): string;
|
|
11
|
+
export declare function stackJson(params: TemplateParams): string;
|
|
12
|
+
export declare function brewingReadme(): string;
|
|
13
|
+
export declare function slowcookWorkflow(cliVersion: string): string;
|
|
14
|
+
export declare function codeownersSection(params: TemplateParams): string;
|
|
15
|
+
export declare function codeownersFullFile(params: TemplateParams): string;
|
|
16
|
+
export declare function gitkeep(): string;
|
|
17
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/commands/init/templates.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,yBAAyB,UAAU,CAAC;AAEjD,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,gCAAgC,0CAA0C,CAAC;AACxF,eAAO,MAAM,8BAA8B,wCAAwC,CAAC;AAEpF,wBAAgB,eAAe,IAAI,MAAM,CAiCxC;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAkCxD;AAED,wBAAgB,aAAa,IAAI,MAAM,CA+BtC;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA2C3D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAchE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAQjE;AAED,wBAAgB,OAAO,IAAI,MAAM,CAEhC"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// Static and parameterized file contents written by `slowcook init`.
|
|
2
|
+
// Version is bumped in lockstep with the CLI package.
|
|
3
|
+
export const CLI_VERSION_FOR_TEMPLATES = "0.3.0";
|
|
4
|
+
export const SLOWCOOK_CODEOWNERS_MARKER_BEGIN = "# --- slowcook:frozen-paths BEGIN ---";
|
|
5
|
+
export const SLOWCOOK_CODEOWNERS_MARKER_END = "# --- slowcook:frozen-paths END ---";
|
|
6
|
+
export function frozenPathsJson() {
|
|
7
|
+
return (JSON.stringify({
|
|
8
|
+
$schema: "./frozen-paths.schema.json",
|
|
9
|
+
$doc: "Paths frozen by slowcook. See https://github.com/aminazar/slowcook for the design. " +
|
|
10
|
+
"To modify any of these: either get CODEOWNERS approval, or add the 'override-freeze' label " +
|
|
11
|
+
"to the PR (guard runs in advisory mode, audit trail preserved).",
|
|
12
|
+
directories: [
|
|
13
|
+
"tests/",
|
|
14
|
+
"tests-fixtures/",
|
|
15
|
+
"tests-helpers/",
|
|
16
|
+
".brewing/manifests/",
|
|
17
|
+
],
|
|
18
|
+
files: [
|
|
19
|
+
"vitest.config.ts",
|
|
20
|
+
"vitest.config.mjs",
|
|
21
|
+
"vitest.config.js",
|
|
22
|
+
".brewing/frozen-paths.json",
|
|
23
|
+
".brewing/stack.json",
|
|
24
|
+
".github/workflows/slowcook.yml",
|
|
25
|
+
],
|
|
26
|
+
partial: {
|
|
27
|
+
"package.json": {
|
|
28
|
+
frozen_key_paths: ["scripts.test", "scripts.test:watch"],
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
}, null, 2) + "\n");
|
|
32
|
+
}
|
|
33
|
+
export function stackJson(params) {
|
|
34
|
+
const doc = "Project-level stack configuration consumed by slowcook (@slowcook-ai/stack-ts). " +
|
|
35
|
+
"Tells the harness how to discover and run tests. Only include suites that are " +
|
|
36
|
+
"actually runnable — slowcook refuses to record an incomplete manifest." +
|
|
37
|
+
(params.hasPlaywright
|
|
38
|
+
? " (Playwright detected in package.json; slowcook's playwright discovery is not yet " +
|
|
39
|
+
"implemented, so the e2e suite is intentionally omitted. Add it back post-upgrade.)"
|
|
40
|
+
: "");
|
|
41
|
+
return (JSON.stringify({
|
|
42
|
+
$schema: "./stack.schema.json",
|
|
43
|
+
$doc: doc,
|
|
44
|
+
language: "typescript",
|
|
45
|
+
package_manager: "npm",
|
|
46
|
+
test: {
|
|
47
|
+
backend: {
|
|
48
|
+
runner: "vitest",
|
|
49
|
+
run_command: "npx vitest run",
|
|
50
|
+
discover_command: "npx vitest list",
|
|
51
|
+
reporter_format: "vitest-list-lines",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
lint: {
|
|
55
|
+
lint_command: "npm run lint",
|
|
56
|
+
typecheck_command: "npm run typecheck",
|
|
57
|
+
},
|
|
58
|
+
}, null, 2) + "\n");
|
|
59
|
+
}
|
|
60
|
+
export function brewingReadme() {
|
|
61
|
+
return `# \`.brewing/\`
|
|
62
|
+
|
|
63
|
+
Consumer-side configuration for [slowcook](https://github.com/aminazar/slowcook), a TDD-first agentic development harness.
|
|
64
|
+
|
|
65
|
+
## Contents
|
|
66
|
+
|
|
67
|
+
| Path | Purpose |
|
|
68
|
+
|---|---|
|
|
69
|
+
| \`frozen-paths.json\` | What's immutable during brewing (tests, configs, manifests) |
|
|
70
|
+
| \`stack.json\` | How slowcook invokes tests / coverage / lint for this project |
|
|
71
|
+
| \`manifests/\` | Per-story test manifests; populated by \`slowcook manifest record\` |
|
|
72
|
+
|
|
73
|
+
## Running slowcook locally
|
|
74
|
+
|
|
75
|
+
\`\`\`bash
|
|
76
|
+
npx --yes @slowcook-ai/cli@latest guard --base origin/main --head HEAD
|
|
77
|
+
npx --yes @slowcook-ai/cli@latest manifest record
|
|
78
|
+
npx --yes @slowcook-ai/cli@latest manifest verify
|
|
79
|
+
\`\`\`
|
|
80
|
+
|
|
81
|
+
## When you legitimately need to modify a frozen path
|
|
82
|
+
|
|
83
|
+
1. Open a PR with the change.
|
|
84
|
+
2. Add the \`override-freeze\` label to the PR.
|
|
85
|
+
3. Guard runs in advisory mode (surfaces violations but doesn't fail).
|
|
86
|
+
4. CODEOWNERS still requires explicit approval.
|
|
87
|
+
5. Merge audit trail: PR number + \`override-freeze\` label + approval.
|
|
88
|
+
|
|
89
|
+
Deliberately slightly inconvenient. Frozen-path changes are rare events that deserve a reviewer's eyes.
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
export function slowcookWorkflow(cliVersion) {
|
|
93
|
+
return `name: slowcook
|
|
94
|
+
|
|
95
|
+
on:
|
|
96
|
+
pull_request:
|
|
97
|
+
types: [opened, synchronize, reopened, labeled, unlabeled]
|
|
98
|
+
|
|
99
|
+
concurrency:
|
|
100
|
+
group: slowcook-\${{ github.event.pull_request.number }}
|
|
101
|
+
cancel-in-progress: true
|
|
102
|
+
|
|
103
|
+
# Pin CLI version for reproducibility; bump deliberately via a PR.
|
|
104
|
+
env:
|
|
105
|
+
SLOWCOOK_CLI: "@slowcook-ai/cli@${cliVersion}"
|
|
106
|
+
|
|
107
|
+
jobs:
|
|
108
|
+
check:
|
|
109
|
+
name: slowcook checks
|
|
110
|
+
runs-on: ubuntu-latest
|
|
111
|
+
steps:
|
|
112
|
+
- uses: actions/checkout@v4
|
|
113
|
+
with:
|
|
114
|
+
fetch-depth: 0
|
|
115
|
+
|
|
116
|
+
- uses: actions/setup-node@v4
|
|
117
|
+
with:
|
|
118
|
+
node-version: 20
|
|
119
|
+
|
|
120
|
+
- name: Guard — frozen paths
|
|
121
|
+
env:
|
|
122
|
+
HAS_OVERRIDE: \${{ contains(github.event.pull_request.labels.*.name, 'override-freeze') }}
|
|
123
|
+
run: |
|
|
124
|
+
set -eu
|
|
125
|
+
ARGS="--base origin/\${{ github.base_ref }} --head HEAD"
|
|
126
|
+
if [ "$HAS_OVERRIDE" = "true" ]; then
|
|
127
|
+
ARGS="$ARGS --override"
|
|
128
|
+
echo "::notice::'override-freeze' label present — guard runs in advisory mode."
|
|
129
|
+
fi
|
|
130
|
+
npx --yes "$SLOWCOOK_CLI" guard $ARGS
|
|
131
|
+
|
|
132
|
+
- name: Manifest — verify discoverable tests
|
|
133
|
+
run: npx --yes "$SLOWCOOK_CLI" manifest verify
|
|
134
|
+
`;
|
|
135
|
+
}
|
|
136
|
+
export function codeownersSection(params) {
|
|
137
|
+
return `${SLOWCOOK_CODEOWNERS_MARKER_BEGIN}
|
|
138
|
+
# Paths frozen by slowcook. Agent-authored PRs cannot modify them;
|
|
139
|
+
# human edits must be reviewed. See https://github.com/aminazar/slowcook.
|
|
140
|
+
|
|
141
|
+
/tests/ ${params.owner}
|
|
142
|
+
/tests-fixtures/ ${params.owner}
|
|
143
|
+
/tests-helpers/ ${params.owner}
|
|
144
|
+
/vitest.config.* ${params.owner}
|
|
145
|
+
/.brewing/ ${params.owner}
|
|
146
|
+
/.github/workflows/slowcook.yml ${params.owner}
|
|
147
|
+
/CODEOWNERS ${params.owner}
|
|
148
|
+
${SLOWCOOK_CODEOWNERS_MARKER_END}
|
|
149
|
+
`;
|
|
150
|
+
}
|
|
151
|
+
export function codeownersFullFile(params) {
|
|
152
|
+
// For repos that don't have CODEOWNERS yet — prepend a short header.
|
|
153
|
+
return `# CODEOWNERS
|
|
154
|
+
#
|
|
155
|
+
# Generated by \`slowcook init\`. The slowcook-managed section is between
|
|
156
|
+
# the marker comments; edit outside those markers freely.
|
|
157
|
+
|
|
158
|
+
${codeownersSection(params)}`;
|
|
159
|
+
}
|
|
160
|
+
export function gitkeep() {
|
|
161
|
+
return "";
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/commands/init/templates.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sDAAsD;AAEtD,MAAM,CAAC,MAAM,yBAAyB,GAAG,OAAO,CAAC;AASjD,MAAM,CAAC,MAAM,gCAAgC,GAAG,uCAAuC,CAAC;AACxF,MAAM,CAAC,MAAM,8BAA8B,GAAG,qCAAqC,CAAC;AAEpF,MAAM,UAAU,eAAe;IAC7B,OAAO,CACL,IAAI,CAAC,SAAS,CACZ;QACE,OAAO,EAAE,4BAA4B;QACrC,IAAI,EACF,qFAAqF;YACrF,6FAA6F;YAC7F,iEAAiE;QACnE,WAAW,EAAE;YACX,QAAQ;YACR,iBAAiB;YACjB,gBAAgB;YAChB,qBAAqB;SACtB;QACD,KAAK,EAAE;YACL,kBAAkB;YAClB,mBAAmB;YACnB,kBAAkB;YAClB,4BAA4B;YAC5B,qBAAqB;YACrB,gCAAgC;SACjC;QACD,OAAO,EAAE;YACP,cAAc,EAAE;gBACd,gBAAgB,EAAE,CAAC,cAAc,EAAE,oBAAoB,CAAC;aACzD;SACF;KACF,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI,CACT,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAsB;IAC9C,MAAM,GAAG,GACP,kFAAkF;QAClF,gFAAgF;QAChF,wEAAwE;QACxE,CAAC,MAAM,CAAC,aAAa;YACnB,CAAC,CAAC,oFAAoF;gBACpF,oFAAoF;YACtF,CAAC,CAAC,EAAE,CAAC,CAAC;IAEV,OAAO,CACL,IAAI,CAAC,SAAS,CACZ;QACE,OAAO,EAAE,qBAAqB;QAC9B,IAAI,EAAE,GAAG;QACT,QAAQ,EAAE,YAAY;QACtB,eAAe,EAAE,KAAK;QACtB,IAAI,EAAE;YACJ,OAAO,EAAE;gBACP,MAAM,EAAE,QAAQ;gBAChB,WAAW,EAAE,gBAAgB;gBAC7B,gBAAgB,EAAE,iBAAiB;gBACnC,eAAe,EAAE,mBAAmB;aACrC;SACF;QACD,IAAI,EAAE;YACJ,YAAY,EAAE,cAAc;YAC5B,iBAAiB,EAAE,mBAAmB;SACvC;KACF,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI,CACT,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BR,CAAC;AACF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IACjD,OAAO;;;;;;;;;;;;oCAY2B,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B7C,CAAC;AACF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAsB;IACtD,OAAO,GAAG,gCAAgC;;;;kCAIV,MAAM,CAAC,KAAK;kCACZ,MAAM,CAAC,KAAK;kCACZ,MAAM,CAAC,KAAK;kCACZ,MAAM,CAAC,KAAK;kCACZ,MAAM,CAAC,KAAK;kCACZ,MAAM,CAAC,KAAK;kCACZ,MAAM,CAAC,KAAK;EAC5C,8BAA8B;CAC/B,CAAC;AACF,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAsB;IACvD,qEAAqE;IACrE,OAAO;;;;;EAKP,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/commands/manifest.ts"],"names":[],"mappings":"AA0IA,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ5D"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, appendFileSync, } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { buildManifest, diffManifest, } from "@slowcook-ai/core";
|
|
4
|
+
import { discoverTests, validateStackConfig, } from "@slowcook-ai/stack-ts";
|
|
5
|
+
const CLI_VERSION = "0.2.0";
|
|
6
|
+
function defaultManifestPath(storyId) {
|
|
7
|
+
return storyId
|
|
8
|
+
? `.brewing/manifests/story-${storyId}.json`
|
|
9
|
+
: `.brewing/manifests/all.json`;
|
|
10
|
+
}
|
|
11
|
+
function parseArgs(argv) {
|
|
12
|
+
const sub = argv[0];
|
|
13
|
+
if (sub !== "record" && sub !== "verify") {
|
|
14
|
+
printHelp();
|
|
15
|
+
process.exit(64);
|
|
16
|
+
}
|
|
17
|
+
const args = {
|
|
18
|
+
subcommand: sub,
|
|
19
|
+
stackConfig: ".brewing/stack.json",
|
|
20
|
+
manifestPath: "",
|
|
21
|
+
storyId: null,
|
|
22
|
+
cwd: process.cwd(),
|
|
23
|
+
};
|
|
24
|
+
for (let i = 1; i < argv.length; i++) {
|
|
25
|
+
const arg = argv[i];
|
|
26
|
+
const next = argv[i + 1];
|
|
27
|
+
if (arg === "--stack-config" && next) {
|
|
28
|
+
args.stackConfig = next;
|
|
29
|
+
i++;
|
|
30
|
+
}
|
|
31
|
+
else if (arg === "--manifest" && next) {
|
|
32
|
+
args.manifestPath = next;
|
|
33
|
+
i++;
|
|
34
|
+
}
|
|
35
|
+
else if (arg === "--story" && next) {
|
|
36
|
+
args.storyId = next;
|
|
37
|
+
i++;
|
|
38
|
+
}
|
|
39
|
+
else if (arg === "--cwd" && next) {
|
|
40
|
+
args.cwd = next;
|
|
41
|
+
i++;
|
|
42
|
+
}
|
|
43
|
+
else if (arg === "--help" || arg === "-h") {
|
|
44
|
+
printHelp();
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (!args.manifestPath) {
|
|
49
|
+
args.manifestPath = defaultManifestPath(args.storyId);
|
|
50
|
+
}
|
|
51
|
+
return args;
|
|
52
|
+
}
|
|
53
|
+
function printHelp() {
|
|
54
|
+
console.log(`
|
|
55
|
+
slowcook manifest — record or verify the set of discoverable tests
|
|
56
|
+
|
|
57
|
+
Usage:
|
|
58
|
+
slowcook manifest record [options]
|
|
59
|
+
slowcook manifest verify [options]
|
|
60
|
+
|
|
61
|
+
Common options:
|
|
62
|
+
--stack-config <path> Path to stack.json (default: .brewing/stack.json)
|
|
63
|
+
--manifest <path> Path to write/read manifest JSON
|
|
64
|
+
(default: .brewing/manifests/all.json, or
|
|
65
|
+
.brewing/manifests/story-<id>.json if --story set)
|
|
66
|
+
--story <id> Tag manifest with this story id
|
|
67
|
+
--cwd <path> Working directory for discovery commands (default: .)
|
|
68
|
+
--help, -h Show this help
|
|
69
|
+
|
|
70
|
+
record:
|
|
71
|
+
Runs every suite's discover_command, writes a manifest capturing the set
|
|
72
|
+
of tests that exist right now. Meant for human-invoked freezing after a
|
|
73
|
+
story's tests are approved.
|
|
74
|
+
|
|
75
|
+
verify:
|
|
76
|
+
Re-runs discovery and compares against the recorded manifest. Exits 1 if
|
|
77
|
+
any recorded test is no longer discoverable (file deleted, renamed, or
|
|
78
|
+
broken). Newly-discovered tests are informational only.
|
|
79
|
+
|
|
80
|
+
Exit codes:
|
|
81
|
+
0 = verify: manifest matches; record: manifest written
|
|
82
|
+
1 = verify: missing tests detected
|
|
83
|
+
2 = script error (missing config, exec failure, parse error)
|
|
84
|
+
`);
|
|
85
|
+
}
|
|
86
|
+
function sh(stackConfigPath, cwd) {
|
|
87
|
+
let raw;
|
|
88
|
+
try {
|
|
89
|
+
raw = JSON.parse(readFileSync(stackConfigPath, "utf8"));
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
console.error(`Could not read stack config at ${stackConfigPath}: ${e.message}`);
|
|
93
|
+
process.exit(2);
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
return validateStackConfig(raw);
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
console.error(`Invalid stack config: ${e.message}`);
|
|
100
|
+
process.exit(2);
|
|
101
|
+
}
|
|
102
|
+
// unreachable — the two process.exit calls above terminate
|
|
103
|
+
}
|
|
104
|
+
function appendGhSummary(md) {
|
|
105
|
+
const summary = process.env["GITHUB_STEP_SUMMARY"];
|
|
106
|
+
if (!summary)
|
|
107
|
+
return;
|
|
108
|
+
try {
|
|
109
|
+
appendFileSync(summary, md);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// best effort
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
export async function manifest(argv) {
|
|
116
|
+
const args = parseArgs(argv);
|
|
117
|
+
const config = sh(args.stackConfig, args.cwd);
|
|
118
|
+
if (args.subcommand === "record") {
|
|
119
|
+
return recordManifest(args, config);
|
|
120
|
+
}
|
|
121
|
+
return verifyManifest(args, config);
|
|
122
|
+
}
|
|
123
|
+
function recordManifest(args, config) {
|
|
124
|
+
const { tests, suites, errors } = discoverTests(config, { cwd: args.cwd });
|
|
125
|
+
if (errors.length > 0) {
|
|
126
|
+
console.error("Discovery errors (refusing to record an incomplete manifest):");
|
|
127
|
+
for (const err of errors) {
|
|
128
|
+
console.error(` [${err.suite}] ${err.message}`);
|
|
129
|
+
}
|
|
130
|
+
process.exit(2);
|
|
131
|
+
}
|
|
132
|
+
const m = buildManifest({
|
|
133
|
+
slowcookVersion: CLI_VERSION,
|
|
134
|
+
storyId: args.storyId,
|
|
135
|
+
tests,
|
|
136
|
+
suites,
|
|
137
|
+
});
|
|
138
|
+
// Ensure directory exists
|
|
139
|
+
const dir = dirname(args.manifestPath);
|
|
140
|
+
if (!existsSync(dir))
|
|
141
|
+
mkdirSync(dir, { recursive: true });
|
|
142
|
+
writeFileSync(args.manifestPath, JSON.stringify(m, null, 2) + "\n", "utf8");
|
|
143
|
+
console.log(`Recorded ${m.tests.length} test(s) across ${m.suites.length} suite(s) → ${args.manifestPath}`);
|
|
144
|
+
for (const s of m.suites) {
|
|
145
|
+
console.log(` [${s.suite}] ${s.test_count} tests`);
|
|
146
|
+
}
|
|
147
|
+
appendGhSummary(`### Manifest recorded\n\n- ${m.tests.length} tests across ${m.suites.length} suites\n- Written to \`${args.manifestPath}\`\n`);
|
|
148
|
+
}
|
|
149
|
+
function verifyManifest(args, config) {
|
|
150
|
+
let manifest;
|
|
151
|
+
try {
|
|
152
|
+
manifest = JSON.parse(readFileSync(args.manifestPath, "utf8"));
|
|
153
|
+
}
|
|
154
|
+
catch (e) {
|
|
155
|
+
console.error(`Could not read manifest at ${args.manifestPath}: ${e.message}`);
|
|
156
|
+
process.exit(2);
|
|
157
|
+
}
|
|
158
|
+
const { tests, errors } = discoverTests(config, { cwd: args.cwd });
|
|
159
|
+
if (errors.length > 0) {
|
|
160
|
+
console.error("Discovery errors during verify:");
|
|
161
|
+
for (const err of errors) {
|
|
162
|
+
console.error(` [${err.suite}] ${err.message}`);
|
|
163
|
+
}
|
|
164
|
+
// Discovery errors mean we can't trust the current snapshot — exit 2.
|
|
165
|
+
process.exit(2);
|
|
166
|
+
}
|
|
167
|
+
const diff = diffManifest(manifest, tests);
|
|
168
|
+
if (diff.missing.length === 0) {
|
|
169
|
+
const msg = `Manifest verified: all ${manifest.tests.length} recorded tests still discoverable.${diff.added.length ? ` (${diff.added.length} new tests since record — informational.)` : ""}`;
|
|
170
|
+
console.log(msg);
|
|
171
|
+
appendGhSummary(`### Manifest verify\n\n✅ ${msg}\n`);
|
|
172
|
+
if (diff.added.length) {
|
|
173
|
+
console.log(`\nNew tests since record (informational):`);
|
|
174
|
+
for (const t of diff.added)
|
|
175
|
+
console.log(` + ${t.id}`);
|
|
176
|
+
}
|
|
177
|
+
process.exit(0);
|
|
178
|
+
}
|
|
179
|
+
console.error(`Manifest verify FAILED: ${diff.missing.length} recorded test(s) no longer discoverable.`);
|
|
180
|
+
for (const t of diff.missing) {
|
|
181
|
+
console.error(` - ${t.id}`);
|
|
182
|
+
console.log(`::error file=${t.file}::Manifest verify — test missing from current discovery: ${t.id}`);
|
|
183
|
+
}
|
|
184
|
+
appendGhSummary(`### Manifest verify\n\n❌ ${diff.missing.length} recorded test(s) missing from current discovery.\n\n${diff.missing
|
|
185
|
+
.map((t) => `- \`${t.id}\``)
|
|
186
|
+
.join("\n")}\n`);
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/commands/manifest.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slowcook-ai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "CLI for the slowcook brewing harness",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "aminazar",
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"README.md"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@slowcook-ai/core": "^0.
|
|
36
|
+
"@slowcook-ai/core": "^0.2.0",
|
|
37
|
+
"@slowcook-ai/stack-ts": "^0.2.0"
|
|
37
38
|
},
|
|
38
39
|
"publishConfig": {
|
|
39
40
|
"access": "public"
|