forgeprint 0.1.1 → 0.2.1

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/bin.js.map +1 -1
  4. package/dist/changed.d.ts +17 -0
  5. package/dist/changed.d.ts.map +1 -0
  6. package/dist/changed.js +62 -0
  7. package/dist/changed.js.map +1 -0
  8. package/dist/cli.d.ts +1 -1
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/cli.js +209 -25
  11. package/dist/cli.js.map +1 -1
  12. package/dist/config.d.ts +1 -0
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +6 -0
  15. package/dist/config.js.map +1 -1
  16. package/dist/index.d.ts +5 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +5 -0
  19. package/dist/index.js.map +1 -1
  20. package/dist/lint-setup.d.ts.map +1 -1
  21. package/dist/lint-setup.js +37 -2
  22. package/dist/lint-setup.js.map +1 -1
  23. package/dist/manifest.d.ts +2 -0
  24. package/dist/manifest.d.ts.map +1 -1
  25. package/dist/manifest.js +1 -1
  26. package/dist/manifest.js.map +1 -1
  27. package/dist/paths.d.ts +1 -0
  28. package/dist/paths.d.ts.map +1 -1
  29. package/dist/paths.js +1 -0
  30. package/dist/paths.js.map +1 -1
  31. package/dist/recipe.d.ts +43 -0
  32. package/dist/recipe.d.ts.map +1 -0
  33. package/dist/recipe.js +131 -0
  34. package/dist/recipe.js.map +1 -0
  35. package/dist/requests.d.ts +54 -0
  36. package/dist/requests.d.ts.map +1 -0
  37. package/dist/requests.js +102 -0
  38. package/dist/requests.js.map +1 -0
  39. package/dist/skills.d.ts +23 -0
  40. package/dist/skills.d.ts.map +1 -0
  41. package/dist/skills.js +162 -0
  42. package/dist/skills.js.map +1 -0
  43. package/dist/test-setup.d.ts +54 -0
  44. package/dist/test-setup.d.ts.map +1 -0
  45. package/dist/test-setup.js +219 -0
  46. package/dist/test-setup.js.map +1 -0
  47. package/dist/validate.d.ts.map +1 -1
  48. package/dist/validate.js +6 -0
  49. package/dist/validate.js.map +1 -1
  50. package/package.json +2 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,71 @@
1
+ # Changelog — forgeprint
2
+
3
+ The catalog tooling. Every pipeline step is a command here, so a contributor
4
+ gets the same answer locally that a pull request gets in CI (ADR 0002).
5
+
6
+ ## 0.2.1 — 2026-09-22
7
+
8
+ ### Added
9
+
10
+ - `forgeprint build-requests` — writes `docs/requests.json` from the open
11
+ `blueprint-request` issues through `gh`, with the date it was taken. It is
12
+ the site's fallback when a reader cannot reach the issues API
13
+ (ADR 0007). Without `gh` it leaves the committed file alone rather than
14
+ replacing a good list with an empty one.
15
+ - `validate` now checks every `SKILL.md` against the format the distribution
16
+ tools read — frontmatter, a name that matches its folder, a description, a
17
+ licence, `allowed-tools` as a string, no committed install metadata, and no
18
+ two skills sharing a name (ADR 0006).
19
+ - `featured_contributors` in `forgeprint.json`, for the people the site
20
+ credits.
21
+
22
+ ## 0.2.0 — 2026-09-22
23
+
24
+ The release that makes a setup recipe executable rather than readable.
25
+
26
+ ### Added
27
+
28
+ - `forgeprint test-setup` — runs a recipe in a fresh temporary directory: every
29
+ step, then its verification, stopping at the first failure with the command
30
+ and its output. It checks the tools a manifest declares in `requires_tools`
31
+ before it starts and installs nothing; a missing tool is a refusal that names
32
+ the tool (ADR 0005). Flags: `--all`, `--options database=postgres,auth=jwt`,
33
+ `--all-options` for the full matrix, `--keep` to keep the working directory.
34
+ - `--changed-since <ref>` on `test-setup` — the blueprints a branch changed,
35
+ and every blueprint when the recipe runner itself changed. It compares
36
+ commits, not the working tree. When nothing changed it says so and succeeds,
37
+ which is what lets the recipe run be a required status check without
38
+ blocking pull requests that touch no blueprint.
39
+ - A recipe parser behind `test-setup`: a step is one command (the last code
40
+ span) or one file (a path in backticks followed by a fenced block), and a
41
+ step ends at the next heading, so the prose after a recipe is never run.
42
+ - `--all` on `lint-setup` and `similarity`.
43
+ - Two `lint-setup` rules that came out of running the recipes for real:
44
+ `one-action-per-step` and `write-step-needs-path`.
45
+
46
+ ### Fixed
47
+
48
+ - `forgeprint --version` reported `0.1.0` whatever was installed. It now
49
+ reports the package version, and a test keeps the two in step.
50
+
51
+ ## 0.1.1 — 2026-09-22
52
+
53
+ - Published unscoped as `forgeprint`. `0.1.0` went out depending on
54
+ `@forgeprint/cli`, which does not exist and made the package uninstallable;
55
+ it is deprecated on npm.
56
+
57
+ ## 0.1.0 — 2026-09-22
58
+
59
+ First release.
60
+
61
+ - `validate` — schema, taxonomy, required files, one blueprint per
62
+ `stack + project_type + requirements`, a CHANGELOG entry per version, and
63
+ generated files that are committed and current.
64
+ - `lint-setup` — the structure and safety rules for `setup.md`: numbered steps,
65
+ a verification per step, pinned versions, and no `sudo`, no pipe to a shell,
66
+ no recursive delete, no system paths (rule 20).
67
+ - `similarity` — the duplicate report: tag overlap and TF-IDF text similarity
68
+ against the closest blueprint in the catalog.
69
+ - `build-index`, `build-schema`, `build-codeowners` — the generated files that
70
+ are committed to the repository so that Pages and CODEOWNERS work without a
71
+ build service.
package/dist/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createProgram } from './cli.js';
3
3
  try {
4
- createProgram().parse(process.argv);
4
+ await createProgram().parseAsync(process.argv);
5
5
  }
6
6
  catch (error) {
7
7
  console.error(`error ${error instanceof Error ? error.message : String(error)}`);
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,IAAI,CAAC;IACH,aAAa,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,IAAI,CAAC;IACH,MAAM,aAAa,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACjD,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,CAAC,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The files that changed between `ref` and the working tree's commit.
3
+ *
4
+ * Three dots: what this branch did, not what happened on the base branch
5
+ * meanwhile.
6
+ */
7
+ export declare function changedFiles(root: string, ref: string): string[];
8
+ /**
9
+ * Which of `slugs` the changed paths affect, in catalog order.
10
+ *
11
+ * Deliberately blunt: a touched blueprint folder selects that blueprint, and a
12
+ * touched runner selects all of them. Anything else — documentation, the site,
13
+ * the MCP server — selects none, and the caller reports that rather than
14
+ * failing.
15
+ */
16
+ export declare function affectedBlueprints(changed: readonly string[], slugs: readonly string[]): string[];
17
+ //# sourceMappingURL=changed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changed.d.ts","sourceRoot":"","sources":["../src/changed.ts"],"names":[],"mappings":"AAyBA;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAoBhE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAQjG"}
@@ -0,0 +1,62 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ /**
3
+ * Selecting the blueprints a change actually affects.
4
+ *
5
+ * A pull request that edits the README should not spend twenty minutes
6
+ * building containers, and a required status check that never reports blocks
7
+ * the merge. So the workflow runs on every pull request and asks this module
8
+ * what to run, instead of a `paths:` filter deciding whether the check exists
9
+ * at all (see docs/repo-settings.md).
10
+ *
11
+ * The decision lives here rather than in the workflow because it has to be
12
+ * reproducible on a laptop: `test-setup --changed-since main` answers the same
13
+ * question a reviewer has (ADR 0002).
14
+ */
15
+ /**
16
+ * A change under the recipe runner affects every blueprint, because it changes
17
+ * what "the recipe passed" means. Paths are repository-relative, the way `git
18
+ * diff --name-only` prints them.
19
+ */
20
+ const RUNNER_PATHS = ['packages/cli/'];
21
+ const BLUEPRINT_PATH = /^blueprints\/([^/]+)\//;
22
+ /**
23
+ * The files that changed between `ref` and the working tree's commit.
24
+ *
25
+ * Three dots: what this branch did, not what happened on the base branch
26
+ * meanwhile.
27
+ */
28
+ export function changedFiles(root, ref) {
29
+ let output;
30
+ try {
31
+ output = execFileSync('git', ['diff', '--name-only', `${ref}...HEAD`], {
32
+ cwd: root,
33
+ encoding: 'utf8',
34
+ stdio: ['ignore', 'pipe', 'pipe'],
35
+ });
36
+ }
37
+ catch (error) {
38
+ const detail = error instanceof Error ? error.message.split('\n')[0] : String(error);
39
+ throw new Error(`Cannot compare against "${ref}": ${detail ?? ''}\n` +
40
+ 'The reference has to exist locally; in CI that means fetching enough history.', { cause: error });
41
+ }
42
+ return output
43
+ .split('\n')
44
+ .map((line) => line.trim())
45
+ .filter((line) => line !== '');
46
+ }
47
+ /**
48
+ * Which of `slugs` the changed paths affect, in catalog order.
49
+ *
50
+ * Deliberately blunt: a touched blueprint folder selects that blueprint, and a
51
+ * touched runner selects all of them. Anything else — documentation, the site,
52
+ * the MCP server — selects none, and the caller reports that rather than
53
+ * failing.
54
+ */
55
+ export function affectedBlueprints(changed, slugs) {
56
+ if (changed.some((path) => RUNNER_PATHS.some((prefix) => path.startsWith(prefix)))) {
57
+ return [...slugs];
58
+ }
59
+ const touched = new Set(changed.map((path) => BLUEPRINT_PATH.exec(path)?.[1]).filter((slug) => slug !== undefined));
60
+ return slugs.filter((slug) => touched.has(slug));
61
+ }
62
+ //# sourceMappingURL=changed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changed.js","sourceRoot":"","sources":["../src/changed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;;;;;;;;;;GAYG;AAEH;;;;GAIG;AACH,MAAM,YAAY,GAAG,CAAC,eAAe,CAAC,CAAC;AAEvC,MAAM,cAAc,GAAG,wBAAwB,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,GAAW;IACpD,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,GAAG,SAAS,CAAC,EAAE;YACrE,GAAG,EAAE,IAAI;YACT,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrF,MAAM,IAAI,KAAK,CACb,2BAA2B,GAAG,MAAM,MAAM,IAAI,EAAE,IAAI;YAClD,+EAA+E,EACjF,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;IACJ,CAAC;IACD,OAAO,MAAM;SACV,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAA0B,EAAE,KAAwB;IACrF,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACnF,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;IACpB,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,CAC3F,CAAC;IACF,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACnD,CAAC"}
package/dist/cli.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Command } from 'commander';
2
- export declare const VERSION = "0.1.0";
2
+ export declare const VERSION = "0.2.1";
3
3
  /**
4
4
  * Every pipeline step is a command here, so that contributors and maintainers
5
5
  * get the same result locally that CI produces (ADR 0002).
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,eAAO,MAAM,OAAO,UAAU,CAAC;AAM/B;;;GAGG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAmHvC"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBpC,eAAO,MAAM,OAAO,UAAU,CAAC;AAM/B;;;GAGG;AACH,wBAAgB,aAAa,IAAI,OAAO,CA0QvC"}
package/dist/cli.js CHANGED
@@ -1,17 +1,23 @@
1
- import { mkdirSync, writeFileSync } from 'node:fs';
2
- import { dirname } from 'node:path';
1
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { dirname, join } from 'node:path';
3
4
  import { Command } from 'commander';
4
5
  import { renderCodeowners } from './build-codeowners.js';
5
6
  import { loadBlueprints, renderIndex } from './build-index.js';
6
7
  import { buildManifestJsonSchema } from './build-schema.js';
7
- import { readBlueprintFile, readBlueprintFolder, readManifest } from './catalog.js';
8
+ import { listBlueprintSlugs, readBlueprintFile, readBlueprintFolder, readManifest, } from './catalog.js';
9
+ import { affectedBlueprints, changedFiles } from './changed.js';
8
10
  import { CONFIG_FILE, loadConfig } from './config.js';
9
11
  import { lintSetup } from './lint-setup.js';
12
+ import { checkOptions, resolveSetupOptions } from './options.js';
13
+ import { parseRecipe } from './recipe.js';
14
+ import { fetchRequests, hasGitHubCli, renderRequests } from './requests.js';
15
+ import { checkTools, runDirectoryName, runRecipe } from './test-setup.js';
10
16
  import { compareBlueprints, DEFAULT_THRESHOLD, renderReport } from './similarity.js';
11
17
  import { findRepoRoot, repoPaths } from './paths.js';
12
18
  import { loadTaxonomy } from './taxonomy.js';
13
19
  import { validateCatalog } from './validate.js';
14
- export const VERSION = '0.1.0';
20
+ export const VERSION = '0.2.1';
15
21
  /**
16
22
  * Every pipeline step is a command here, so that contributors and maintainers
17
23
  * get the same result locally that CI produces (ADR 0002).
@@ -43,29 +49,37 @@ export function createProgram() {
43
49
  });
44
50
  program
45
51
  .command('lint-setup')
46
- .argument('<slug>', 'blueprint to check')
52
+ .argument('[slug]', 'blueprint to check; omit with --all')
53
+ .option('--all', 'check every blueprint in the catalog')
47
54
  .description('check a blueprint setup.md against the structure and safety rules')
48
- .action((slug) => {
55
+ .action((slug, options) => {
49
56
  const root = rootOf();
50
- const folder = readBlueprintFolder(root, slug);
51
- const manifest = readManifest(loadTaxonomy(root), folder);
52
- const problems = lintSetup(readBlueprintFile(folder, 'setup.md'), {
53
- options: manifest.options ?? {},
54
- });
55
- for (const problem of problems) {
56
- console.error(`error setup.md:${problem.line} ${problem.rule}: ${problem.message}`);
57
+ const taxonomy = loadTaxonomy(root);
58
+ const slugs = targets(root, slug, options.all === true);
59
+ let problemCount = 0;
60
+ for (const target of slugs) {
61
+ const folder = readBlueprintFolder(root, target);
62
+ const manifest = readManifest(taxonomy, folder);
63
+ const problems = lintSetup(readBlueprintFile(folder, 'setup.md'), {
64
+ options: manifest.options ?? {},
65
+ });
66
+ for (const problem of problems) {
67
+ console.error(`error ${target}/setup.md:${problem.line} ${problem.rule}: ${problem.message}`);
68
+ }
69
+ problemCount += problems.length;
57
70
  }
58
- if (problems.length === 0) {
59
- console.log(`ok ${slug}/setup.md passes the setup rules`);
71
+ if (problemCount === 0) {
72
+ console.log(`ok ${slugs.length} setup recipe(s) pass the setup rules`);
60
73
  return;
61
74
  }
62
75
  console.error(`
63
- ${problems.length} problem(s) in ${slug}/setup.md`);
76
+ ${problemCount} problem(s) in ${slugs.length} setup recipe(s)`);
64
77
  process.exitCode = 1;
65
78
  });
66
79
  program
67
80
  .command('similarity')
68
- .argument('<slug>', 'blueprint to compare against the rest of the catalog')
81
+ .argument('[slug]', 'blueprint to compare; omit with --all')
82
+ .option('--all', 'report on every blueprint in the catalog')
69
83
  .option('--threshold <ratio>', 'flag above this similarity', String(DEFAULT_THRESHOLD))
70
84
  .option('--fail-on-flag', 'exit non-zero on a red flag, not only on a rule 9 rejection')
71
85
  .description('report how close a blueprint is to the ones already in the catalog')
@@ -73,22 +87,110 @@ ${problems.length} problem(s) in ${slug}/setup.md`);
73
87
  const root = rootOf();
74
88
  const taxonomy = loadTaxonomy(root);
75
89
  const blueprints = loadBlueprints(root, taxonomy);
76
- const subject = blueprints.find((blueprint) => blueprint.slug === slug);
77
- if (subject === undefined)
78
- throw new Error(`No such blueprint: ${slug}`);
79
90
  const threshold = Number(options.threshold);
80
91
  if (!Number.isFinite(threshold) || threshold <= 0 || threshold > 1) {
81
92
  throw new Error('--threshold must be a ratio between 0 and 1');
82
93
  }
83
- const report = compareBlueprints(subject, blueprints.filter((blueprint) => blueprint.slug !== slug), threshold);
84
- console.log(renderReport(report));
94
+ let rejected = false;
95
+ let flagged = false;
96
+ for (const target of targets(root, slug, options.all === true)) {
97
+ const subject = blueprints.find((blueprint) => blueprint.slug === target);
98
+ if (subject === undefined)
99
+ throw new Error(`No such blueprint: ${target}`);
100
+ const report = compareBlueprints(subject, blueprints.filter((blueprint) => blueprint.slug !== target), threshold);
101
+ console.log(renderReport(report));
102
+ console.log('');
103
+ rejected ||= report.closest?.sameCombination === true;
104
+ flagged ||= report.flagged;
105
+ }
85
106
  // A red flag is a question for the reviewer, which the pull request
86
107
  // template makes them answer (rule 11). Only the objective rule — one
87
108
  // blueprint per stack + project_type + requirements — fails the command.
88
- if (report.closest?.sameCombination === true || options.failOnFlag === true) {
89
- if (report.flagged || report.closest?.sameCombination === true)
90
- process.exitCode = 1;
109
+ if (rejected || (options.failOnFlag === true && flagged))
110
+ process.exitCode = 1;
111
+ });
112
+ program
113
+ .command('test-setup')
114
+ .argument('[slug]', 'blueprint to run; omit with --all')
115
+ .option('--all', 'run every blueprint in the catalog')
116
+ .option('--options <pairs>', 'option values, for example database=postgres,auth=jwt')
117
+ .option('--all-options', 'run every combination of the declared options')
118
+ .option('--changed-since <ref>', 'only the blueprints changed since this git reference')
119
+ .option('--keep', 'keep the working directory instead of deleting it')
120
+ .description('run a setup recipe in a fresh directory and verify every step')
121
+ .action(async (slug, flags) => {
122
+ const root = rootOf();
123
+ const taxonomy = loadTaxonomy(root);
124
+ let failures = 0;
125
+ let selected = targets(root, slug, flags.all === true);
126
+ if (flags.changedSince !== undefined) {
127
+ const ref = flags.changedSince;
128
+ selected = affectedBlueprints(changedFiles(root, ref), selected);
129
+ if (selected.length === 0) {
130
+ // Not a skip and not a failure: the question was asked and the
131
+ // answer is nothing to run. A required check has to say that out
132
+ // loud, or the pull request waits forever.
133
+ console.log(`ok no blueprint changed since ${ref}; no recipe to run`);
134
+ return;
135
+ }
136
+ console.log(`Changed since ${ref}: ${selected.join(', ')}`);
137
+ }
138
+ for (const target of selected) {
139
+ const folder = readBlueprintFolder(root, target);
140
+ const manifest = readManifest(taxonomy, folder);
141
+ // Nothing is installed: a missing tool is a refusal, not a guess at a
142
+ // different toolchain (ADR 0005).
143
+ const missing = await checkTools(manifest.requires_tools ?? []);
144
+ if (missing.length > 0) {
145
+ for (const problem of missing)
146
+ console.error(`error ${target}: ${problem.message}`);
147
+ console.error(`\n${target} cannot be tested on this machine. Nothing was installed.`);
148
+ failures += 1;
149
+ continue;
150
+ }
151
+ for (const chosen of combinations(manifest, flags)) {
152
+ checkOptions(manifest, chosen);
153
+ const label = describeOptions(chosen);
154
+ console.log(`\n${target}${label === '' ? '' : ` ${label}`}`);
155
+ const resolved = resolveSetupOptions(readBlueprintFile(folder, 'setup.md'), chosen);
156
+ const recipe = parseRecipe(resolved.markdown);
157
+ if (recipe.problems.length > 0) {
158
+ for (const problem of recipe.problems) {
159
+ console.error(`error setup.md:${problem.line}: ${problem.message}`);
160
+ }
161
+ failures += 1;
162
+ continue;
163
+ }
164
+ const dir = mkdtempSync(join(tmpdir(), `${runDirectoryName(target, chosen)}-`));
165
+ const started = Date.now();
166
+ const result = await runRecipe(recipe.steps, {
167
+ dir,
168
+ // The step's own number can outrun the count: a branch the caller
169
+ // did not pick leaves a gap in the numbering of the one they did.
170
+ onStep: (step, position, total) => {
171
+ console.log(` [${String(position).padStart(2)}/${total}] ${step.number}. ${step.title}`);
172
+ },
173
+ });
174
+ if (result.ok) {
175
+ console.log(`ok ${recipe.steps.length} step(s) in ${seconds(started)}`);
176
+ if (flags.keep === true)
177
+ console.log(` working directory: ${dir}`);
178
+ else
179
+ rmSync(dir, { recursive: true, force: true });
180
+ }
181
+ else {
182
+ const failure = result.failure;
183
+ console.error(`\nerror step ${String(failure?.step.number)} failed during the ` +
184
+ `${String(failure?.phase)} (exit ${String(failure?.exitCode)})`);
185
+ console.error(` ${failedCommand(failure)}`);
186
+ console.error(indent(tail(failure?.output ?? '', 40)));
187
+ console.error(` working directory kept at ${dir}`);
188
+ failures += 1;
189
+ }
190
+ }
91
191
  }
192
+ if (failures > 0)
193
+ process.exitCode = 1;
92
194
  });
93
195
  program
94
196
  .command('build-index')
@@ -105,6 +207,27 @@ ${problems.length} problem(s) in ${slug}/setup.md`);
105
207
  const root = rootOf();
106
208
  write(repoPaths.manifestSchema(root), buildManifestJsonSchema(loadTaxonomy(root)));
107
209
  });
210
+ program
211
+ .command('build-requests')
212
+ .description('regenerate docs/requests.json from the open blueprint-request issues')
213
+ .option('--repository <owner/repo>', `repository to read (default: repository in ${CONFIG_FILE})`)
214
+ .action((options) => {
215
+ const root = rootOf();
216
+ const repository = options.repository ?? loadConfig(root).repository;
217
+ if (repository === undefined) {
218
+ throw new Error(`No repository: pass --repository or set repository in ${CONFIG_FILE}`);
219
+ }
220
+ // Without gh there is nothing to ask, and an empty list would delete a
221
+ // good one. The build carries on either way: the demand list is never
222
+ // worth failing on (ADR 0002).
223
+ if (!hasGitHubCli()) {
224
+ console.log('skip gh is not installed; docs/requests.json left as it is');
225
+ return;
226
+ }
227
+ const requests = fetchRequests(repository);
228
+ write(repoPaths.requests(root), renderRequests(repository, requests));
229
+ console.log(` ${String(requests.length)} open request(s)`);
230
+ });
108
231
  program
109
232
  .command('build-codeowners')
110
233
  .description('regenerate .github/CODEOWNERS from every manifest maintainers field')
@@ -120,6 +243,67 @@ ${problems.length} problem(s) in ${slug}/setup.md`);
120
243
  });
121
244
  return program;
122
245
  }
246
+ /** Every combination of the declared options, or just the first of each. */
247
+ function combinations(manifest, flags) {
248
+ if (flags.options !== undefined)
249
+ return [parsePairs(flags.options)];
250
+ const fields = Object.entries(manifest.options ?? {});
251
+ if (fields.length === 0)
252
+ return [{}];
253
+ if (flags.allOptions !== true) {
254
+ // One run, deterministically the first value of each field. The full matrix
255
+ // is slow enough that making it the default would mean nobody runs it.
256
+ return [Object.fromEntries(fields.map(([field, values]) => [field, values[0] ?? '']))];
257
+ }
258
+ return fields.reduce((rows, [field, values]) => rows.flatMap((row) => values.map((value) => ({ ...row, [field]: value }))), [{}]);
259
+ }
260
+ function parsePairs(text) {
261
+ return Object.fromEntries(text.split(',').map((pair) => {
262
+ const [field = '', value = ''] = pair.split('=');
263
+ if (field.trim() === '' || value.trim() === '') {
264
+ throw new Error(`--options takes field=value pairs, got "${pair}"`);
265
+ }
266
+ return [field.trim(), value.trim()];
267
+ }));
268
+ }
269
+ function describeOptions(chosen) {
270
+ return Object.entries(chosen)
271
+ .map(([field, value]) => `${field}=${value}`)
272
+ .join(' ');
273
+ }
274
+ /** What to show for a failure: the verification, or the action that ran. */
275
+ function failedCommand(failure) {
276
+ if (failure === undefined)
277
+ return '';
278
+ if (failure.phase === 'verify')
279
+ return failure.step.verify;
280
+ return failure.step.action.kind === 'run'
281
+ ? failure.step.action.command
282
+ : `write ${failure.step.action.path}`;
283
+ }
284
+ function seconds(started) {
285
+ return `${((Date.now() - started) / 1000).toFixed(1)}s`;
286
+ }
287
+ function tail(text, lines) {
288
+ return text.split('\n').slice(-lines).join('\n');
289
+ }
290
+ function indent(text) {
291
+ return text
292
+ .split('\n')
293
+ .map((line) => ` | ${line}`)
294
+ .join('\n');
295
+ }
296
+ /** The blueprints a command should act on: one slug, or the whole catalog. */
297
+ function targets(root, slug, all) {
298
+ if (all && slug !== undefined) {
299
+ throw new Error('Pass a slug or --all, not both');
300
+ }
301
+ if (all)
302
+ return listBlueprintSlugs(root);
303
+ if (slug === undefined)
304
+ throw new Error('Pass a blueprint slug, or --all for every blueprint');
305
+ return [slug];
306
+ }
123
307
  function write(file, contents) {
124
308
  mkdirSync(dirname(file), { recursive: true });
125
309
  writeFileSync(file, contents, 'utf8');
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -6,6 +6,7 @@ import { z } from 'zod';
6
6
  export declare const configSchema: z.ZodObject<{
7
7
  core_maintainer: z.ZodOptional<z.ZodString>;
8
8
  repository: z.ZodOptional<z.ZodString>;
9
+ featured_contributors: z.ZodOptional<z.ZodArray<z.ZodString>>;
9
10
  }, z.core.$strict>;
10
11
  export type Config = z.infer<typeof configSchema>;
11
12
  export declare const CONFIG_FILE = "forgeprint.json";
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;GAGG;AACH,eAAO,MAAM,YAAY;;;kBAQd,CAAC;AAEZ,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,eAAO,MAAM,WAAW,oBAAoB,CAAC;AAE7C,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ/C"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;kBAed,CAAC;AAEZ,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,eAAO,MAAM,WAAW,oBAAoB,CAAC;AAE7C,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ/C"}
package/dist/config.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { z } from 'zod';
4
+ import { GITHUB_HANDLE_PATTERN } from './manifest.js';
4
5
  import { describeError } from './taxonomy.js';
5
6
  /**
6
7
  * Repository-level settings that the tooling cannot infer. Optional: every
@@ -12,6 +13,11 @@ export const configSchema = z
12
13
  core_maintainer: z.string().min(1),
13
14
  /** `owner/repo`, used in generated links. */
14
15
  repository: z.string().regex(/^[^/\s]+\/[^/\s]+$/),
16
+ /**
17
+ * GitHub logins the site credits on the front page. People, not counts:
18
+ * the catalog is written by somebody, and the site says who.
19
+ */
20
+ featured_contributors: z.array(z.string().regex(GITHUB_HANDLE_PATTERN, 'must be a GitHub login')),
15
21
  })
16
22
  .partial()
17
23
  .strict();
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,0EAA0E;IAC1E,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,6CAA6C;IAC7C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC;CACnD,CAAC;KACD,OAAO,EAAE;KACT,MAAM,EAAE,CAAC;AAIZ,MAAM,CAAC,MAAM,WAAW,GAAG,iBAAiB,CAAC;AAE7C,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACrC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,WAAW,WAAW,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACvF,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC;KAC1B,MAAM,CAAC;IACN,0EAA0E;IAC1E,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,6CAA6C;IAC7C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,oBAAoB,CAAC;IAClD;;;OAGG;IACH,qBAAqB,EAAE,CAAC,CAAC,KAAK,CAC5B,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,qBAAqB,EAAE,wBAAwB,CAAC,CAClE;CACF,CAAC;KACD,OAAO,EAAE;KACT,MAAM,EAAE,CAAC;AAIZ,MAAM,CAAC,MAAM,WAAW,GAAG,iBAAiB,CAAC;AAE7C,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACrC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,WAAW,WAAW,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACvF,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './build-codeowners.js';
2
2
  export * from './build-index.js';
3
3
  export * from './build-schema.js';
4
4
  export * from './catalog.js';
5
+ export * from './changed.js';
5
6
  export * from './cli.js';
6
7
  export * from './config.js';
7
8
  export * from './json.js';
@@ -9,7 +10,11 @@ export * from './lint-setup.js';
9
10
  export * from './manifest.js';
10
11
  export * from './options.js';
11
12
  export * from './paths.js';
13
+ export * from './recipe.js';
14
+ export * from './requests.js';
12
15
  export * from './similarity.js';
16
+ export * from './skills.js';
13
17
  export * from './taxonomy.js';
18
+ export * from './test-setup.js';
14
19
  export * from './validate.js';
15
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ export * from './build-codeowners.js';
2
2
  export * from './build-index.js';
3
3
  export * from './build-schema.js';
4
4
  export * from './catalog.js';
5
+ export * from './changed.js';
5
6
  export * from './cli.js';
6
7
  export * from './config.js';
7
8
  export * from './json.js';
@@ -9,7 +10,11 @@ export * from './lint-setup.js';
9
10
  export * from './manifest.js';
10
11
  export * from './options.js';
11
12
  export * from './paths.js';
13
+ export * from './recipe.js';
14
+ export * from './requests.js';
12
15
  export * from './similarity.js';
16
+ export * from './skills.js';
13
17
  export * from './taxonomy.js';
18
+ export * from './test-setup.js';
14
19
  export * from './validate.js';
15
20
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"lint-setup.d.ts","sourceRoot":"","sources":["../src/lint-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AA2HD,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;CAChE;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAY,EAAE,GAAE,WAAgB,GAAG,YAAY,EAAE,CA0L5F"}
1
+ {"version":3,"file":"lint-setup.d.ts","sourceRoot":"","sources":["../src/lint-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AA8HD,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;CAChE;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAY,EAAE,GAAE,WAAgB,GAAG,YAAY,EAAE,CA2N5F"}