@r3dlex/ai-catapult 0.1.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.
Files changed (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -0
  3. package/bin/ai-catapult.js +229 -0
  4. package/dist/claude-plugin/.claude-plugin/marketplace.json +28 -0
  5. package/dist/claude-plugin/.claude-plugin/plugin.json +21 -0
  6. package/dist/claude-plugin/skills/ai-catapult-init/REFERENCE.md +1284 -0
  7. package/dist/claude-plugin/skills/ai-catapult-init/SKILL.md +79 -0
  8. package/dist/claude-plugin/skills/ai-catapult-init/modules/README.md +48 -0
  9. package/dist/claude-plugin/skills/ai-catapult-init/modules/archgate.md +42 -0
  10. package/dist/claude-plugin/skills/ai-catapult-init/modules/brd-prd-traceability.md +64 -0
  11. package/dist/claude-plugin/skills/ai-catapult-init/modules/cascade.md +110 -0
  12. package/dist/claude-plugin/skills/ai-catapult-init/modules/ci-policy.md +107 -0
  13. package/dist/claude-plugin/skills/ai-catapult-init/modules/documentation-blueprint.md +185 -0
  14. package/dist/claude-plugin/skills/ai-catapult-init/modules/evals.md +93 -0
  15. package/dist/claude-plugin/skills/ai-catapult-init/modules/foundation.md +19 -0
  16. package/dist/claude-plugin/skills/ai-catapult-init/modules/host-policy-automation.md +151 -0
  17. package/dist/claude-plugin/skills/ai-catapult-init/modules/language-packs.md +63 -0
  18. package/dist/claude-plugin/skills/ai-catapult-init/modules/mcp-a2a.md +63 -0
  19. package/dist/claude-plugin/skills/ai-catapult-init/modules/memory.md +102 -0
  20. package/dist/claude-plugin/skills/ai-catapult-init/modules/migration.md +107 -0
  21. package/dist/claude-plugin/skills/ai-catapult-init/modules/phases/01-discover-decide.md +33 -0
  22. package/dist/claude-plugin/skills/ai-catapult-init/modules/phases/README.md +33 -0
  23. package/dist/claude-plugin/skills/ai-catapult-init/modules/readme-documentation.md +120 -0
  24. package/dist/claude-plugin/skills/ai-catapult-init/modules/release-versioning.md +188 -0
  25. package/dist/claude-plugin/skills/ai-catapult-init/modules/skill-modernization.md +72 -0
  26. package/dist/claude-plugin/skills/ai-catapult-init/modules/sync.md +111 -0
  27. package/dist/claude-plugin/skills/ai-catapult-init/modules/topology.md +102 -0
  28. package/dist/claude-plugin/skills/ai-catapult-init/modules/traceability.md +136 -0
  29. package/dist/claude-plugin/skills/ai-catapult-init/modules/tracker-adapters.md +51 -0
  30. package/dist/claude-plugin/skills/ai-catapult-init/modules/validation.md +276 -0
  31. package/dist/claude-plugin/skills/ai-catapult-init/modules/workflow.md +45 -0
  32. package/dist/claude-plugin/skills/ai-catapult-init/templates/AGENTS.md +69 -0
  33. package/dist/claude-plugin/skills/ai-catapult-init/templates/CLAUDE.md +3 -0
  34. package/dist/claude-plugin/skills/ai-catapult-init/templates/GEMINI.md +3 -0
  35. package/dist/claude-plugin/skills/ai-catapult-init/templates/boundary-manifest.json +247 -0
  36. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/drift/backups/.gitkeep +0 -0
  37. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/drift/last-drift.json +7 -0
  38. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/evals/.gitkeep +0 -0
  39. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/evals/coverage-exceptions.json +1 -0
  40. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/handoff/.gitkeep +0 -0
  41. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/matrix.json +19 -0
  42. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/mcp/a2a-handoff.md +51 -0
  43. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/mcp/registry.json +27 -0
  44. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/observability/audit-checklist.md +32 -0
  45. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/observability/conventions.md +35 -0
  46. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/phases/01-discover-decide/status.json +16 -0
  47. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/phases/02-govern-plan/status.json +15 -0
  48. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/phases/03-configure-generate/status.json +22 -0
  49. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/phases/04-validate-handoff/status.json +18 -0
  50. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/policies/model-routing.json +29 -0
  51. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/reviews/ai-failure-modes.md +42 -0
  52. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/rules/security.md +38 -0
  53. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/rules/technical-bounds.md +38 -0
  54. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/skills/git-ops.json +6 -0
  55. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/skills/workspace-sync.json +6 -0
  56. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/system-prompts/architect.md +31 -0
  57. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/system-prompts/developer.md +31 -0
  58. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/system-prompts/qa-engineer.md +31 -0
  59. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/traceability/.gitkeep +0 -0
  60. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/workflows/repo-workflow.json +42 -0
  61. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-ai/workflows/repo-workflow.md +52 -0
  62. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-github/workflows/ci-prek.yml +21 -0
  63. package/dist/claude-plugin/skills/ai-catapult-init/templates/dot-rules.ts +178 -0
  64. package/dist/claude-plugin/skills/ai-catapult-init/templates/prek.toml +13 -0
  65. package/dist/codex-plugin/.codex-plugin/plugin.json +11 -0
  66. package/dist/codex-plugin/skills/ai-catapult-init/REFERENCE.md +1284 -0
  67. package/dist/codex-plugin/skills/ai-catapult-init/SKILL.md +79 -0
  68. package/dist/codex-plugin/skills/ai-catapult-init/modules/README.md +48 -0
  69. package/dist/codex-plugin/skills/ai-catapult-init/modules/archgate.md +42 -0
  70. package/dist/codex-plugin/skills/ai-catapult-init/modules/brd-prd-traceability.md +64 -0
  71. package/dist/codex-plugin/skills/ai-catapult-init/modules/cascade.md +110 -0
  72. package/dist/codex-plugin/skills/ai-catapult-init/modules/ci-policy.md +107 -0
  73. package/dist/codex-plugin/skills/ai-catapult-init/modules/documentation-blueprint.md +185 -0
  74. package/dist/codex-plugin/skills/ai-catapult-init/modules/evals.md +93 -0
  75. package/dist/codex-plugin/skills/ai-catapult-init/modules/foundation.md +19 -0
  76. package/dist/codex-plugin/skills/ai-catapult-init/modules/host-policy-automation.md +151 -0
  77. package/dist/codex-plugin/skills/ai-catapult-init/modules/language-packs.md +63 -0
  78. package/dist/codex-plugin/skills/ai-catapult-init/modules/mcp-a2a.md +63 -0
  79. package/dist/codex-plugin/skills/ai-catapult-init/modules/memory.md +102 -0
  80. package/dist/codex-plugin/skills/ai-catapult-init/modules/migration.md +107 -0
  81. package/dist/codex-plugin/skills/ai-catapult-init/modules/phases/01-discover-decide.md +33 -0
  82. package/dist/codex-plugin/skills/ai-catapult-init/modules/phases/README.md +33 -0
  83. package/dist/codex-plugin/skills/ai-catapult-init/modules/readme-documentation.md +120 -0
  84. package/dist/codex-plugin/skills/ai-catapult-init/modules/release-versioning.md +188 -0
  85. package/dist/codex-plugin/skills/ai-catapult-init/modules/skill-modernization.md +72 -0
  86. package/dist/codex-plugin/skills/ai-catapult-init/modules/sync.md +111 -0
  87. package/dist/codex-plugin/skills/ai-catapult-init/modules/topology.md +102 -0
  88. package/dist/codex-plugin/skills/ai-catapult-init/modules/traceability.md +136 -0
  89. package/dist/codex-plugin/skills/ai-catapult-init/modules/tracker-adapters.md +51 -0
  90. package/dist/codex-plugin/skills/ai-catapult-init/modules/validation.md +276 -0
  91. package/dist/codex-plugin/skills/ai-catapult-init/modules/workflow.md +45 -0
  92. package/dist/codex-plugin/skills/ai-catapult-init/templates/AGENTS.md +69 -0
  93. package/dist/codex-plugin/skills/ai-catapult-init/templates/CLAUDE.md +3 -0
  94. package/dist/codex-plugin/skills/ai-catapult-init/templates/GEMINI.md +3 -0
  95. package/dist/codex-plugin/skills/ai-catapult-init/templates/boundary-manifest.json +247 -0
  96. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/drift/backups/.gitkeep +0 -0
  97. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/drift/last-drift.json +7 -0
  98. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/evals/.gitkeep +0 -0
  99. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/evals/coverage-exceptions.json +1 -0
  100. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/handoff/.gitkeep +0 -0
  101. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/matrix.json +19 -0
  102. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/mcp/a2a-handoff.md +51 -0
  103. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/mcp/registry.json +27 -0
  104. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/observability/audit-checklist.md +32 -0
  105. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/observability/conventions.md +35 -0
  106. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/phases/01-discover-decide/status.json +16 -0
  107. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/phases/02-govern-plan/status.json +15 -0
  108. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/phases/03-configure-generate/status.json +22 -0
  109. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/phases/04-validate-handoff/status.json +18 -0
  110. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/policies/model-routing.json +29 -0
  111. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/reviews/ai-failure-modes.md +42 -0
  112. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/rules/security.md +38 -0
  113. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/rules/technical-bounds.md +38 -0
  114. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/skills/git-ops.json +6 -0
  115. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/skills/workspace-sync.json +6 -0
  116. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/system-prompts/architect.md +31 -0
  117. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/system-prompts/developer.md +31 -0
  118. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/system-prompts/qa-engineer.md +31 -0
  119. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/traceability/.gitkeep +0 -0
  120. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/workflows/repo-workflow.json +42 -0
  121. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-ai/workflows/repo-workflow.md +52 -0
  122. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-github/workflows/ci-prek.yml +21 -0
  123. package/dist/codex-plugin/skills/ai-catapult-init/templates/dot-rules.ts +178 -0
  124. package/dist/codex-plugin/skills/ai-catapult-init/templates/prek.toml +13 -0
  125. package/package.json +51 -0
  126. package/scripts/build-claude-plugin.sh +179 -0
  127. package/scripts/build-codex-plugin.sh +104 -0
  128. package/scripts/snapshot-dist.sh +26 -0
  129. package/setup.sh +63 -0
  130. package/skills.lock.json +6 -0
  131. package/src/install.js +380 -0
  132. package/src/scaffold.js +220 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andre Burgstahler (r3dlex)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,139 @@
1
+ # ai-catapult
2
+
3
+ Scaffold [init-ai-repo v3 AI-SDLC governance](https://github.com/r3dlex/init-ai-repo) into any repository — no LLM required, no config needed, one command.
4
+
5
+ ## What it does
6
+
7
+ `ai-catapult` is a deterministic CLI that writes a complete v3 `.ai/` governance skeleton into your repo: directory structure, matrix, system prompts, rules, workflows, traceability wiring, and agent contracts. It also ships as a **Claude Code plugin** and a **Codex plugin** so the scaffold runs from inside your AI coding agent without leaving your editor.
8
+
9
+ It repackages the `init-ai-repo`/`ai-catapult-init` skill as a standalone tool — same output, zero dependency on a running LLM session.
10
+
11
+ ## Quick start
12
+
13
+ ```sh
14
+ # Scaffold governance skeleton into the current directory
15
+ npx ai-catapult init
16
+
17
+ # Then install the plugin into detected harnesses (Claude Code and/or Codex)
18
+ npx ai-catapult install
19
+ ```
20
+
21
+ Or install globally:
22
+
23
+ ```sh
24
+ npm install -g ai-catapult
25
+ ai-catapult init
26
+ ai-catapult install
27
+ ```
28
+
29
+ ## Commands
30
+
31
+ ### `ai-catapult init [target]`
32
+
33
+ Scaffold the mechanical v3 `.ai/` governance skeleton into `<target>` (default: current directory).
34
+
35
+ ```
36
+ Options:
37
+ --repo-id <id> Repository identifier (default: basename of target)
38
+ --date <YYYY-MM-DD> Scaffold date token (default: today)
39
+ --upstream-url <url> Upstream git URL for matrix.json
40
+ --upstream-ref <ref> Upstream git ref (default: main)
41
+ --force Overwrite existing files without error
42
+ -h, --help Show help
43
+ ```
44
+
45
+ ### `ai-catapult install`
46
+
47
+ Install the ai-catapult plugin into detected AI coding harnesses.
48
+
49
+ Harnesses detected automatically:
50
+ - **Claude Code** — `~/.claude/` present
51
+ - **Codex** — `${CODEX_HOME:-~/.codex}/` present
52
+
53
+ ```
54
+ Options:
55
+ --harness <claude|codex|all> Select harness(es) (default: auto-detect)
56
+ --dry-run Print what would happen without writing
57
+ --force Overwrite even if dir contains a foreign plugin
58
+ -h, --help Show help
59
+ ```
60
+
61
+ After install, reload Claude Code and run `/ai-catapult-init` to complete the in-harness judgment-laden phases.
62
+
63
+ ## Claude Code plugin
64
+
65
+ `ai-catapult` ships as a Claude Code plugin bundling the `ai-catapult-init` skill.
66
+
67
+ ### Install path
68
+
69
+ Running `npx ai-catapult install` copies the plugin payload to:
70
+ ```
71
+ ~/.claude/plugins/ai-catapult/
72
+ ```
73
+
74
+ Then follow the printed two-step registration inside Claude Code:
75
+ ```
76
+ /plugin marketplace add ~/.claude/plugins/ai-catapult
77
+ /plugin install ai-catapult@ai-catapult-local
78
+ ```
79
+
80
+ The installer does **not** write `installed_plugins.json` — that is a Claude Code internal file. Use the `/plugin` commands above to register the plugin.
81
+
82
+ ### Build the plugin locally
83
+
84
+ ```sh
85
+ bash setup.sh # vendor the pinned skill source
86
+ npm run build:plugin:claude # assemble into dist/claude-plugin/
87
+ ```
88
+
89
+ ## Codex plugin
90
+
91
+ `ai-catapult` ships as a Codex plugin bundling the `ai-catapult-init` skill.
92
+
93
+ ### Install path
94
+
95
+ Running `npx ai-catapult install` copies the plugin payload to:
96
+ ```
97
+ ${CODEX_HOME:-~/.codex}/plugins/cache/ai-catapult-local/ai-catapult/local/
98
+ ```
99
+
100
+ Then add the printed TOML block to your `${CODEX_HOME:-~/.codex}/config.toml`:
101
+ ```toml
102
+ [marketplaces.ai-catapult-local]
103
+ source_type = "local"
104
+ source = "<printed payload path>"
105
+
106
+ [plugins."ai-catapult@ai-catapult-local"]
107
+ enabled = true
108
+ ```
109
+
110
+ The installer does **not** auto-mutate `config.toml` — you add the block manually. See [docs/codex-install.md](docs/codex-install.md) for details.
111
+
112
+ ### Build the plugin locally
113
+
114
+ ```sh
115
+ bash setup.sh # vendor the pinned skill source
116
+ npm run build:plugin:codex # assemble into dist/codex-plugin/
117
+ ```
118
+
119
+ ## Publishing
120
+
121
+ Both `ai-catapult` (unscoped) and `@r3dlex/ai-catapult` (scoped mirror) are published to npm.
122
+
123
+ ### Dry-run (safe, default)
124
+
125
+ ```sh
126
+ bash scripts/publish-both.sh
127
+ ```
128
+
129
+ ### Real publish (double-gated)
130
+
131
+ ```sh
132
+ AI_CATAPULT_PUBLISH=1 bash scripts/publish-both.sh --yes
133
+ ```
134
+
135
+ Semver-tagged releases are automated via `.github/workflows/release.yml` (requires `NPM_TOKEN` in repo secrets).
136
+
137
+ ## License
138
+
139
+ MIT © Andre Burgstahler (r3dlex)
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { dirname, join, resolve, basename } from 'node:path';
5
+ import { scaffold } from '../src/scaffold.js';
6
+ import { runInstall } from '../src/install.js';
7
+
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
10
+
11
+ const VENDOR_TEMPLATES = join(__dirname, '..', 'vendor/skills/ai-catapult-init/templates');
12
+
13
+ const HELP = `Usage: ai-catapult <command> [options]
14
+
15
+ Commands:
16
+ init [target] Scaffold v3 .ai/ governance skeleton into <target> (default: cwd)
17
+ install Install Claude Code and Codex plugins into detected harnesses
18
+
19
+ Options:
20
+ -v, --version Print version
21
+ -h, --help Show this help`;
22
+
23
+ const INIT_HELP = `Usage: ai-catapult init [target] [options]
24
+
25
+ Scaffold the mechanical v3 .ai/ governance skeleton into <target>.
26
+ No LLM required. Judgment-laden content is deferred to the in-harness plugin.
27
+
28
+ Arguments:
29
+ target Directory to scaffold into (default: current directory)
30
+
31
+ Options:
32
+ --repo-id <id> Repository identifier, e.g. "my-repo" (default: basename of target)
33
+ --date <YYYY-MM-DD> Scaffold date token (default: today)
34
+ --upstream-url <url> Upstream git URL for matrix.json (default: "")
35
+ --upstream-ref <ref> Upstream git ref for matrix.json (default: "main")
36
+ --force Overwrite existing files without error
37
+ -h, --help Show this help`;
38
+
39
+ // ---------------------------------------------------------------------------
40
+ // Argument parsing
41
+ // ---------------------------------------------------------------------------
42
+
43
+ /**
44
+ * Parse flags from an argv array (already sliced past [node, script]).
45
+ * Returns { positionals: string[], flags: Map<string, string|boolean>, firstPositionalIdx: number }
46
+ * --foo bar → flags.get('foo') === 'bar'
47
+ * --foo → flags.get('foo') === true
48
+ * -h → flags.get('h') === true
49
+ */
50
+ function parseArgs(argv) {
51
+ const positionals = [];
52
+ const flags = new Map();
53
+ // Track the raw index of the first positional in argv (for subcommand slicing)
54
+ let firstPositionalIdx = -1;
55
+ let i = 0;
56
+ while (i < argv.length) {
57
+ const arg = argv[i];
58
+ if (arg === '--') {
59
+ positionals.push(...argv.slice(i + 1));
60
+ break;
61
+ }
62
+ if (arg.startsWith('--')) {
63
+ const key = arg.slice(2);
64
+ const next = argv[i + 1];
65
+ if (next !== undefined && !next.startsWith('-')) {
66
+ flags.set(key, next);
67
+ i += 2;
68
+ } else {
69
+ flags.set(key, true);
70
+ i += 1;
71
+ }
72
+ } else if (arg.startsWith('-') && arg.length === 2) {
73
+ flags.set(arg.slice(1), true);
74
+ i += 1;
75
+ } else {
76
+ if (firstPositionalIdx === -1) firstPositionalIdx = i;
77
+ positionals.push(arg);
78
+ i += 1;
79
+ }
80
+ }
81
+ return { positionals, flags, firstPositionalIdx };
82
+ }
83
+
84
+ // ---------------------------------------------------------------------------
85
+ // Finish prompt builder
86
+ // ---------------------------------------------------------------------------
87
+
88
+ /**
89
+ * Build the structured next-steps block shown to the user after a successful
90
+ * scaffold. Content is deterministic given same inputs.
91
+ *
92
+ * @param {object} opts
93
+ * @param {string} opts.targetDir - resolved absolute target path (used in "scaffolded into" line)
94
+ * @param {string} opts.pathDisplay - base used for anchor path bullet lines (e.g. targetDir for
95
+ * stdout, '.' for the file so it stays machine-independent)
96
+ * @param {string[]} opts.emittedPaths - relative paths actually written
97
+ * @param {string[]} opts.judgmentLadenPaths - from boundary-manifest.json
98
+ * @returns {string}
99
+ */
100
+ function buildFinishPrompt({ targetDir, pathDisplay, emittedPaths, judgmentLadenPaths }) {
101
+ // Pick two anchor paths that are always mechanical (existence already verified
102
+ // by scaffold — if they are missing scaffold would have failed earlier).
103
+ const matrixPath = emittedPaths.includes('.ai/matrix.json') ? '.ai/matrix.json' : emittedPaths[0] ?? null;
104
+ const agentsPath = emittedPaths.includes('AGENTS.md') ? 'AGENTS.md' : null;
105
+
106
+ const anchorLines = [];
107
+ if (matrixPath) anchorLines.push(` • ${pathDisplay}/${matrixPath}`);
108
+ if (agentsPath) anchorLines.push(` • ${pathDisplay}/${agentsPath}`);
109
+
110
+ const jlLines = judgmentLadenPaths.map((p) => ` • ${p}`).join('\n');
111
+
112
+ return [
113
+ '╔══════════════════════════════════════════════════════════════╗',
114
+ '║ ai-catapult — scaffold complete ║',
115
+ '╚══════════════════════════════════════════════════════════════╝',
116
+ '',
117
+ 'Mechanical v3 skeleton scaffolded into:',
118
+ ` ${pathDisplay}`,
119
+ '',
120
+ 'Key emitted paths (verified on disk):',
121
+ ...anchorLines,
122
+ '',
123
+ 'Judgment-laden phases NOT yet written (require in-harness plugin):',
124
+ jlLines,
125
+ '',
126
+ '── Next step: complete in-harness ─────────────────────────────',
127
+ '',
128
+ '1. Install the ai-catapult plugin:',
129
+ ' npx ai-catapult install',
130
+ '',
131
+ '2. Open the scaffolded repo in Claude Code or Codex, then run:',
132
+ ' Claude Code: /ai-catapult-init',
133
+ ' Codex: invoke the ai-catapult-init skill',
134
+ '',
135
+ 'The ai-catapult-init skill will guide you through topology decisions,',
136
+ 'ADRs, cascade configuration, and traceability — the judgment-laden',
137
+ 'phases that require knowledge of your specific repository.',
138
+ '────────────────────────────────────────────────────────────────',
139
+ ].join('\n');
140
+ }
141
+
142
+ // ---------------------------------------------------------------------------
143
+ // Subcommand: init
144
+ // ---------------------------------------------------------------------------
145
+
146
+ function runInit(argv) {
147
+ const { positionals, flags } = parseArgs(argv);
148
+
149
+ if (flags.has('help') || flags.has('h')) {
150
+ console.log(INIT_HELP);
151
+ process.exit(0);
152
+ }
153
+
154
+ const targetDir = positionals[0] ? resolve(positionals[0]) : process.cwd();
155
+ const today = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
156
+
157
+ const repoId = String(flags.get('repo-id') || basename(targetDir));
158
+ const date = String(flags.get('date') || today);
159
+ const upstreamUrl = String(flags.get('upstream-url') || '');
160
+ const upstreamRef = String(flags.get('upstream-ref') || 'main');
161
+ const force = flags.has('force');
162
+
163
+ const { emittedPaths, judgmentLadenPaths } = scaffold({
164
+ targetDir, templatesDir: VENDOR_TEMPLATES, repoId, date, upstreamUrl, upstreamRef, force,
165
+ });
166
+
167
+ // Build finish prompt for stdout — uses absolute targetDir so the user sees
168
+ // real paths they can open directly.
169
+ const finishPromptStdout = buildFinishPrompt({ targetDir, pathDisplay: targetDir, emittedPaths, judgmentLadenPaths });
170
+
171
+ // Emit to stdout.
172
+ process.stdout.write(finishPromptStdout + '\n');
173
+
174
+ // Build finish prompt for the file — uses '.' as the path base so the file
175
+ // contains only relative paths and is byte-identical across machines/CI runs.
176
+ const finishPromptFile = buildFinishPrompt({ targetDir, pathDisplay: '.', emittedPaths, judgmentLadenPaths });
177
+
178
+ // Write to <target>/.ai/handoff/NEXT-STEPS.md.
179
+ // Safe to write unconditionally: scaffold's collision guard has already run
180
+ // and would have exited 1 on mechanical collisions before reaching this line.
181
+ const nextStepsPath = join(targetDir, '.ai/handoff/NEXT-STEPS.md');
182
+ mkdirSync(dirname(nextStepsPath), { recursive: true });
183
+ writeFileSync(nextStepsPath, finishPromptFile, 'utf8');
184
+ }
185
+
186
+ // runInstall is imported from src/install.js
187
+
188
+ // ---------------------------------------------------------------------------
189
+ // Main dispatch
190
+ // ---------------------------------------------------------------------------
191
+
192
+ const rawArgv = process.argv.slice(2);
193
+ const { positionals: topPositionals, flags: topFlags, firstPositionalIdx } = parseArgs(rawArgv);
194
+
195
+ if (topFlags.has('version') || topFlags.has('v')) {
196
+ console.log(pkg.version);
197
+ process.exit(0);
198
+ }
199
+
200
+ const verb = topPositionals[0];
201
+
202
+ // Global --help/-h only when no verb is given; with a verb the subcommand
203
+ // handles its own --help flag.
204
+ if (!verb && (topFlags.has('help') || topFlags.has('h') || rawArgv.length === 0)) {
205
+ console.log(HELP);
206
+ process.exit(0);
207
+ }
208
+
209
+ // No verb and no global flag already handled above; bare invocation → help.
210
+ if (!verb) {
211
+ console.log(HELP);
212
+ process.exit(0);
213
+ }
214
+
215
+ if (verb === 'init') {
216
+ // Fix #2: use firstPositionalIdx (the index of 'init' in rawArgv) rather than
217
+ // rawArgv.indexOf('init'), which would match the first literal 'init' anywhere
218
+ // — e.g. `ai-catapult --date init init <target>` would mis-dispatch to ./init.
219
+ runInit(rawArgv.slice(firstPositionalIdx + 1));
220
+ process.exit(0);
221
+ }
222
+
223
+ if (verb === 'install') {
224
+ runInstall(rawArgv.slice(firstPositionalIdx + 1));
225
+ process.exit(0);
226
+ }
227
+
228
+ process.stderr.write(`Unknown argument: ${verb}. Run ai-catapult --help for usage.\n`);
229
+ process.exit(1);
@@ -0,0 +1,28 @@
1
+ {
2
+ "$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
3
+ "name": "ai-catapult",
4
+ "description": "Scaffold init-ai-repo v3 AI-SDLC governance — deterministic, no LLM required",
5
+ "owner": {
6
+ "name": "r3dlex"
7
+ },
8
+ "plugins": [
9
+ {
10
+ "name": "ai-catapult",
11
+ "description": "Scaffold init-ai-repo v3 AI-SDLC governance into any repository. One command, zero config, no LLM required. Provides the ai-catapult-init skill for Claude Code.",
12
+ "version": "0.1.0",
13
+ "author": {
14
+ "name": "r3dlex"
15
+ },
16
+ "source": "./",
17
+ "category": "productivity",
18
+ "homepage": "https://github.com/r3dlex/ai-catapult",
19
+ "tags": [
20
+ "ai-sdlc",
21
+ "governance",
22
+ "scaffold",
23
+ "init-ai-repo"
24
+ ]
25
+ }
26
+ ],
27
+ "version": "0.1.0"
28
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "ai-catapult",
3
+ "version": "0.1.0",
4
+ "description": "Scaffold init-ai-repo v3 AI-SDLC governance into any repository — no LLM required, one command. Ships as a Claude Code skill.",
5
+ "author": {
6
+ "name": "r3dlex"
7
+ },
8
+ "repository": "https://github.com/r3dlex/ai-catapult",
9
+ "homepage": "https://github.com/r3dlex/ai-catapult",
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "ai-sdlc",
13
+ "governance",
14
+ "scaffold",
15
+ "init-ai-repo",
16
+ "claude-code"
17
+ ],
18
+ "skills": [
19
+ "./skills/ai-catapult-init/"
20
+ ]
21
+ }