javi-forge 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/README.md +45 -1
  2. package/ci-local/README.md +56 -11
  3. package/ci-local/ci-local.ps1 +445 -0
  4. package/ci-local/ci-local.sh +52 -9
  5. package/ci-local/docker/python.Dockerfile +7 -0
  6. package/ci-local/hooks/commit-msg +120 -44
  7. package/ci-local/hooks/commit-msg.test.sh +286 -0
  8. package/ci-local/hooks/pre-commit +9 -1
  9. package/ci-local/hooks/pre-push +13 -2
  10. package/ci-local/install.ps1 +367 -0
  11. package/ci-local/install.sh +151 -5
  12. package/ci-local/uninstall.ps1 +85 -0
  13. package/ci-local/uninstall.sh +95 -0
  14. package/dist/cli/dispatch/ci.d.ts +12 -0
  15. package/dist/cli/dispatch/ci.js +38 -0
  16. package/dist/cli/dispatch/security.d.ts +11 -0
  17. package/dist/cli/dispatch/security.js +68 -0
  18. package/dist/cli/dispatch/simple-renderers.d.ts +16 -0
  19. package/dist/cli/dispatch/simple-renderers.js +65 -0
  20. package/dist/cli/dispatch/skill-publish.d.ts +15 -0
  21. package/dist/cli/dispatch/skill-publish.js +44 -0
  22. package/dist/cli/dispatch/skills-cmd.d.ts +13 -0
  23. package/dist/cli/dispatch/skills-cmd.js +93 -0
  24. package/dist/cli/dispatch/tdd.d.ts +11 -0
  25. package/dist/cli/dispatch/tdd.js +45 -0
  26. package/dist/cli/dispatch/types.d.ts +29 -0
  27. package/dist/cli/dispatch/types.js +2 -0
  28. package/dist/cli/dispatch/workflow.d.ts +11 -0
  29. package/dist/cli/dispatch/workflow.js +67 -0
  30. package/dist/cli/help.d.ts +127 -0
  31. package/dist/cli/help.js +138 -0
  32. package/dist/cli/runtime.d.ts +16 -0
  33. package/dist/cli/runtime.js +38 -0
  34. package/dist/cli/validators.d.ts +17 -0
  35. package/dist/cli/validators.js +35 -0
  36. package/dist/commands/analyze.d.ts +1 -1
  37. package/dist/commands/analyze.js +14 -16
  38. package/dist/commands/ci.d.ts +50 -3
  39. package/dist/commands/ci.js +537 -182
  40. package/dist/commands/doctor.d.ts +2 -2
  41. package/dist/commands/doctor.js +112 -62
  42. package/dist/commands/init/report.d.ts +13 -0
  43. package/dist/commands/init/report.js +13 -0
  44. package/dist/commands/init/steps/agent-skills.d.ts +13 -0
  45. package/dist/commands/init/steps/agent-skills.js +45 -0
  46. package/dist/commands/init/steps/ai-sync.d.ts +15 -0
  47. package/dist/commands/init/steps/ai-sync.js +62 -0
  48. package/dist/commands/init/steps/ci.d.ts +24 -0
  49. package/dist/commands/init/steps/ci.js +74 -0
  50. package/dist/commands/init/steps/claude-md.d.ts +14 -0
  51. package/dist/commands/init/steps/claude-md.js +54 -0
  52. package/dist/commands/init/steps/code-graph.d.ts +16 -0
  53. package/dist/commands/init/steps/code-graph.js +68 -0
  54. package/dist/commands/init/steps/context-dir.d.ts +13 -0
  55. package/dist/commands/init/steps/context-dir.js +47 -0
  56. package/dist/commands/init/steps/docker-deploy.d.ts +16 -0
  57. package/dist/commands/init/steps/docker-deploy.js +60 -0
  58. package/dist/commands/init/steps/ghagga.d.ts +15 -0
  59. package/dist/commands/init/steps/ghagga.js +58 -0
  60. package/dist/commands/init/steps/git.d.ts +25 -0
  61. package/dist/commands/init/steps/git.js +81 -0
  62. package/dist/commands/init/steps/gitignore.d.ts +13 -0
  63. package/dist/commands/init/steps/gitignore.js +39 -0
  64. package/dist/commands/init/steps/local-ai.d.ts +14 -0
  65. package/dist/commands/init/steps/local-ai.js +53 -0
  66. package/dist/commands/init/steps/manifest.d.ts +13 -0
  67. package/dist/commands/init/steps/manifest.js +58 -0
  68. package/dist/commands/init/steps/memory.d.ts +15 -0
  69. package/dist/commands/init/steps/memory.js +60 -0
  70. package/dist/commands/init/steps/mock.d.ts +13 -0
  71. package/dist/commands/init/steps/mock.js +64 -0
  72. package/dist/commands/init/steps/sdd.d.ts +12 -0
  73. package/dist/commands/init/steps/sdd.js +40 -0
  74. package/dist/commands/init/steps/security.d.ts +28 -0
  75. package/dist/commands/init/steps/security.js +103 -0
  76. package/dist/commands/init/types.d.ts +30 -0
  77. package/dist/commands/init/types.js +2 -0
  78. package/dist/commands/init.d.ts +5 -4
  79. package/dist/commands/init.js +42 -387
  80. package/dist/commands/llmstxt.d.ts +1 -1
  81. package/dist/commands/llmstxt.js +36 -34
  82. package/dist/commands/plugin.d.ts +10 -1
  83. package/dist/commands/plugin.js +92 -47
  84. package/dist/commands/security.d.ts +11 -5
  85. package/dist/commands/security.js +236 -77
  86. package/dist/commands/skills/analysis.d.ts +19 -0
  87. package/dist/commands/skills/analysis.js +211 -0
  88. package/dist/commands/skills/benchmark.d.ts +6 -0
  89. package/dist/commands/skills/benchmark.js +82 -0
  90. package/dist/commands/skills/constants.d.ts +10 -0
  91. package/dist/commands/skills/constants.js +27 -0
  92. package/dist/commands/skills/directives.d.ts +21 -0
  93. package/dist/commands/skills/directives.js +101 -0
  94. package/dist/commands/skills/parsing.d.ts +16 -0
  95. package/dist/commands/skills/parsing.js +108 -0
  96. package/dist/commands/skills/rules.d.ts +5 -0
  97. package/dist/commands/skills/rules.js +32 -0
  98. package/dist/commands/skills/scoring.d.ts +47 -0
  99. package/dist/commands/skills/scoring.js +306 -0
  100. package/dist/commands/skills.d.ts +8 -69
  101. package/dist/commands/skills.js +9 -490
  102. package/dist/commands/tdd-pipeline.d.ts +17 -0
  103. package/dist/commands/tdd-pipeline.js +144 -0
  104. package/dist/commands/tdd.d.ts +1 -1
  105. package/dist/commands/tdd.js +21 -18
  106. package/dist/commands/workflow.d.ts +23 -0
  107. package/dist/commands/workflow.js +116 -0
  108. package/dist/constants.d.ts +15 -1
  109. package/dist/constants.js +161 -122
  110. package/dist/index.js +43 -280
  111. package/dist/lib/agent-skills.d.ts +36 -1
  112. package/dist/lib/agent-skills.js +168 -19
  113. package/dist/lib/atlassian-mcp.d.ts +42 -0
  114. package/dist/lib/atlassian-mcp.js +98 -0
  115. package/dist/lib/auto-skill-install.d.ts +37 -0
  116. package/dist/lib/auto-skill-install.js +91 -0
  117. package/dist/lib/auto-wire.d.ts +20 -0
  118. package/dist/lib/auto-wire.js +240 -0
  119. package/dist/lib/ci-config.d.ts +65 -0
  120. package/dist/lib/ci-config.js +297 -0
  121. package/dist/lib/claudemd.d.ts +13 -1
  122. package/dist/lib/claudemd.js +174 -24
  123. package/dist/lib/codex-export.d.ts +1 -1
  124. package/dist/lib/codex-export.js +26 -32
  125. package/dist/lib/common.d.ts +1 -1
  126. package/dist/lib/common.js +52 -44
  127. package/dist/lib/context.d.ts +17 -2
  128. package/dist/lib/context.js +142 -13
  129. package/dist/lib/crash-recovery.d.ts +34 -0
  130. package/dist/lib/crash-recovery.js +123 -0
  131. package/dist/lib/docker.d.ts +23 -2
  132. package/dist/lib/docker.js +168 -131
  133. package/dist/lib/exec.d.ts +10 -0
  134. package/dist/lib/exec.js +11 -0
  135. package/dist/lib/frontmatter.d.ts +1 -1
  136. package/dist/lib/frontmatter.js +29 -15
  137. package/dist/lib/harness-audit.d.ts +35 -0
  138. package/dist/lib/harness-audit.js +277 -0
  139. package/dist/lib/parallel-batch.d.ts +42 -0
  140. package/dist/lib/parallel-batch.js +88 -0
  141. package/dist/lib/plugin.d.ts +9 -3
  142. package/dist/lib/plugin.js +127 -70
  143. package/dist/lib/secret-scanner.d.ts +30 -0
  144. package/dist/lib/secret-scanner.js +274 -0
  145. package/dist/lib/security-analysis.d.ts +74 -0
  146. package/dist/lib/security-analysis.js +489 -0
  147. package/dist/lib/skill-publish.d.ts +40 -0
  148. package/dist/lib/skill-publish.js +164 -0
  149. package/dist/lib/skill-scanner.d.ts +63 -0
  150. package/dist/lib/skill-scanner.js +383 -0
  151. package/dist/lib/stack-detector.d.ts +38 -0
  152. package/dist/lib/stack-detector.js +207 -0
  153. package/dist/lib/supply-chain.d.ts +23 -0
  154. package/dist/lib/supply-chain.js +126 -0
  155. package/dist/lib/team-presets.d.ts +53 -0
  156. package/dist/lib/team-presets.js +201 -0
  157. package/dist/lib/template.d.ts +16 -1
  158. package/dist/lib/template.js +46 -17
  159. package/dist/lib/workflow/discovery.d.ts +27 -0
  160. package/dist/lib/workflow/discovery.js +85 -0
  161. package/dist/lib/workflow/index.d.ts +5 -0
  162. package/dist/lib/workflow/index.js +5 -0
  163. package/dist/lib/workflow/parser.d.ts +16 -0
  164. package/dist/lib/workflow/parser.js +198 -0
  165. package/dist/lib/workflow/renderer.d.ts +9 -0
  166. package/dist/lib/workflow/renderer.js +152 -0
  167. package/dist/lib/workflow/validator.d.ts +10 -0
  168. package/dist/lib/workflow/validator.js +189 -0
  169. package/dist/tasks/index.d.ts +4 -0
  170. package/dist/tasks/index.js +4 -0
  171. package/dist/tasks/scaffold-tasks.d.ts +3 -0
  172. package/dist/tasks/scaffold-tasks.js +14 -0
  173. package/dist/tasks/task-id.d.ts +30 -0
  174. package/dist/tasks/task-id.js +59 -0
  175. package/dist/tasks/task-tracker.d.ts +15 -0
  176. package/dist/tasks/task-tracker.js +81 -0
  177. package/dist/types/index.d.ts +134 -6
  178. package/dist/types/index.js +11 -1
  179. package/dist/ui/AnalyzeUI.d.ts +1 -1
  180. package/dist/ui/AnalyzeUI.js +38 -39
  181. package/dist/ui/App.d.ts +5 -3
  182. package/dist/ui/App.js +86 -46
  183. package/dist/ui/AutoSkills.d.ts +9 -0
  184. package/dist/ui/AutoSkills.js +124 -0
  185. package/dist/ui/CI.d.ts +2 -2
  186. package/dist/ui/CI.js +24 -26
  187. package/dist/ui/CIContext.d.ts +1 -1
  188. package/dist/ui/CIContext.js +2 -2
  189. package/dist/ui/CISelector.d.ts +2 -2
  190. package/dist/ui/CISelector.js +23 -15
  191. package/dist/ui/Doctor.d.ts +1 -1
  192. package/dist/ui/Doctor.js +35 -29
  193. package/dist/ui/Header.d.ts +1 -1
  194. package/dist/ui/Header.js +14 -14
  195. package/dist/ui/HookProfileSelector.d.ts +9 -0
  196. package/dist/ui/HookProfileSelector.js +54 -0
  197. package/dist/ui/LlmsTxt.d.ts +1 -1
  198. package/dist/ui/LlmsTxt.js +31 -22
  199. package/dist/ui/MemorySelector.d.ts +2 -2
  200. package/dist/ui/MemorySelector.js +28 -16
  201. package/dist/ui/NameInput.d.ts +1 -1
  202. package/dist/ui/NameInput.js +21 -21
  203. package/dist/ui/OptionSelector.d.ts +6 -2
  204. package/dist/ui/OptionSelector.js +83 -32
  205. package/dist/ui/Plugin.d.ts +4 -3
  206. package/dist/ui/Plugin.js +78 -35
  207. package/dist/ui/Progress.d.ts +3 -3
  208. package/dist/ui/Progress.js +23 -22
  209. package/dist/ui/Skills.d.ts +2 -2
  210. package/dist/ui/Skills.js +61 -32
  211. package/dist/ui/StackSelector.d.ts +2 -2
  212. package/dist/ui/StackSelector.js +27 -17
  213. package/dist/ui/Summary.d.ts +3 -3
  214. package/dist/ui/Summary.js +60 -50
  215. package/dist/ui/Welcome.d.ts +1 -1
  216. package/dist/ui/Welcome.js +15 -16
  217. package/dist/ui/theme.d.ts +1 -1
  218. package/dist/ui/theme.js +6 -6
  219. package/lib/common.psm1 +167 -0
  220. package/lib/common.sh +30 -0
  221. package/package.json +46 -24
  222. package/templates/common/atlassian/mcp-atlassian-snippet.json +16 -0
  223. package/templates/common/repoforge/mcp-repoforge-snippet.json +11 -0
  224. package/templates/common/repoforge/repoforge.yaml +34 -0
  225. package/templates/github/deploy-docker-zero-downtime.yml +140 -0
  226. package/templates/github/repoforge-graph.yml +45 -0
  227. package/templates/gitlab/deploy-docker-zero-downtime.yml +57 -0
  228. package/templates/local-ai/.env.example +17 -0
  229. package/templates/local-ai/docker-compose.yml +95 -0
  230. package/templates/security-hooks/claude-settings-security.json +30 -0
  231. package/templates/security-hooks/commit-msg-signing +29 -0
  232. package/templates/security-hooks/pre-commit-permissions +74 -0
  233. package/templates/security-hooks/pre-commit-secrets +74 -0
  234. package/templates/security-hooks/pre-push-branch-protection +62 -0
  235. package/templates/security-hooks/pre-push-deps +83 -0
  236. package/templates/security-hooks/pre-push-signing +67 -0
  237. package/templates/woodpecker/deploy-docker-zero-downtime.yml +50 -0
  238. package/templates/workflows/ci-pipeline.dot +15 -0
  239. package/templates/workflows/feature-flow.dot +21 -0
  240. package/templates/workflows/release.dot +16 -0
  241. package/dist/__integration__/helpers.d.ts +0 -20
  242. package/dist/__integration__/helpers.d.ts.map +0 -1
  243. package/dist/__integration__/helpers.js +0 -31
  244. package/dist/__integration__/helpers.js.map +0 -1
  245. package/dist/commands/analyze.d.ts.map +0 -1
  246. package/dist/commands/analyze.js.map +0 -1
  247. package/dist/commands/ci.d.ts.map +0 -1
  248. package/dist/commands/ci.js.map +0 -1
  249. package/dist/commands/doctor.d.ts.map +0 -1
  250. package/dist/commands/doctor.js.map +0 -1
  251. package/dist/commands/init.d.ts.map +0 -1
  252. package/dist/commands/init.js.map +0 -1
  253. package/dist/commands/llmstxt.d.ts.map +0 -1
  254. package/dist/commands/llmstxt.js.map +0 -1
  255. package/dist/commands/plugin.d.ts.map +0 -1
  256. package/dist/commands/plugin.js.map +0 -1
  257. package/dist/commands/security.d.ts.map +0 -1
  258. package/dist/commands/security.js.map +0 -1
  259. package/dist/commands/skills.d.ts.map +0 -1
  260. package/dist/commands/skills.js.map +0 -1
  261. package/dist/commands/tdd.d.ts.map +0 -1
  262. package/dist/commands/tdd.js.map +0 -1
  263. package/dist/constants.d.ts.map +0 -1
  264. package/dist/constants.js.map +0 -1
  265. package/dist/index.d.ts.map +0 -1
  266. package/dist/index.js.map +0 -1
  267. package/dist/lib/agent-skills.d.ts.map +0 -1
  268. package/dist/lib/agent-skills.js.map +0 -1
  269. package/dist/lib/claudemd.d.ts.map +0 -1
  270. package/dist/lib/claudemd.js.map +0 -1
  271. package/dist/lib/codex-export.d.ts.map +0 -1
  272. package/dist/lib/codex-export.js.map +0 -1
  273. package/dist/lib/common.d.ts.map +0 -1
  274. package/dist/lib/common.js.map +0 -1
  275. package/dist/lib/context.d.ts.map +0 -1
  276. package/dist/lib/context.js.map +0 -1
  277. package/dist/lib/docker.d.ts.map +0 -1
  278. package/dist/lib/docker.js.map +0 -1
  279. package/dist/lib/frontmatter.d.ts.map +0 -1
  280. package/dist/lib/frontmatter.js.map +0 -1
  281. package/dist/lib/plugin.d.ts.map +0 -1
  282. package/dist/lib/plugin.js.map +0 -1
  283. package/dist/lib/template.d.ts.map +0 -1
  284. package/dist/lib/template.js.map +0 -1
  285. package/dist/types/index.d.ts.map +0 -1
  286. package/dist/types/index.js.map +0 -1
  287. package/dist/ui/AnalyzeUI.d.ts.map +0 -1
  288. package/dist/ui/AnalyzeUI.js.map +0 -1
  289. package/dist/ui/App.d.ts.map +0 -1
  290. package/dist/ui/App.js.map +0 -1
  291. package/dist/ui/CI.d.ts.map +0 -1
  292. package/dist/ui/CI.js.map +0 -1
  293. package/dist/ui/CIContext.d.ts.map +0 -1
  294. package/dist/ui/CIContext.js.map +0 -1
  295. package/dist/ui/CISelector.d.ts.map +0 -1
  296. package/dist/ui/CISelector.js.map +0 -1
  297. package/dist/ui/Doctor.d.ts.map +0 -1
  298. package/dist/ui/Doctor.js.map +0 -1
  299. package/dist/ui/Header.d.ts.map +0 -1
  300. package/dist/ui/Header.js.map +0 -1
  301. package/dist/ui/LlmsTxt.d.ts.map +0 -1
  302. package/dist/ui/LlmsTxt.js.map +0 -1
  303. package/dist/ui/MemorySelector.d.ts.map +0 -1
  304. package/dist/ui/MemorySelector.js.map +0 -1
  305. package/dist/ui/NameInput.d.ts.map +0 -1
  306. package/dist/ui/NameInput.js.map +0 -1
  307. package/dist/ui/OptionSelector.d.ts.map +0 -1
  308. package/dist/ui/OptionSelector.js.map +0 -1
  309. package/dist/ui/Plugin.d.ts.map +0 -1
  310. package/dist/ui/Plugin.js.map +0 -1
  311. package/dist/ui/Progress.d.ts.map +0 -1
  312. package/dist/ui/Progress.js.map +0 -1
  313. package/dist/ui/Skills.d.ts.map +0 -1
  314. package/dist/ui/Skills.js.map +0 -1
  315. package/dist/ui/StackSelector.d.ts.map +0 -1
  316. package/dist/ui/StackSelector.js.map +0 -1
  317. package/dist/ui/Summary.d.ts.map +0 -1
  318. package/dist/ui/Summary.js.map +0 -1
  319. package/dist/ui/Welcome.d.ts.map +0 -1
  320. package/dist/ui/Welcome.js.map +0 -1
  321. package/dist/ui/theme.d.ts.map +0 -1
  322. package/dist/ui/theme.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import type { DoctorResult } from '../types/index.js';
2
- export type CheckStatus = 'ok' | 'fail' | 'skip';
1
+ import type { DoctorResult } from "../types/index.js";
2
+ export type CheckStatus = "ok" | "fail" | "skip";
3
3
  /**
4
4
  * Run comprehensive health checks for the project and framework.
5
5
  */
@@ -1,15 +1,14 @@
1
- import fs from 'fs-extra';
2
- import path from 'path';
3
- import { execFile } from 'child_process';
4
- import { promisify } from 'util';
5
- import { detectStack } from '../lib/common.js';
6
- import { listInstalledPlugins } from '../lib/plugin.js';
7
- import { FORGE_ROOT, TEMPLATES_DIR, MODULES_DIR, PLUGINS_DIR } from '../constants.js';
8
- const execFileAsync = promisify(execFile);
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import { FORGE_ROOT, MODULES_DIR, PLUGINS_DIR, TEMPLATES_DIR, } from "../constants.js";
4
+ import { detectStack } from "../lib/common.js";
5
+ import { refreshContextDir } from "../lib/context.js";
6
+ import { execFileAsync } from "../lib/exec.js";
7
+ import { listInstalledPlugins } from "../lib/plugin.js";
9
8
  /** Resolve a binary name to its full path, returns null if not found */
10
9
  async function which(bin) {
11
10
  try {
12
- const { stdout } = await execFileAsync('which', [bin]);
11
+ const { stdout } = await execFileAsync("which", [bin]);
13
12
  return stdout.trim() || null;
14
13
  }
15
14
  catch {
@@ -18,11 +17,11 @@ async function which(bin) {
18
17
  }
19
18
  /** Read the forge manifest from a project directory */
20
19
  async function readManifest(projectDir) {
21
- const manifestPath = path.join(projectDir, '.javi-forge', 'manifest.json');
22
- if (!await fs.pathExists(manifestPath))
20
+ const manifestPath = path.join(projectDir, ".javi-forge", "manifest.json");
21
+ if (!(await fs.pathExists(manifestPath)))
23
22
  return null;
24
23
  try {
25
- return await fs.readJson(manifestPath);
24
+ return (await fs.readJson(manifestPath));
26
25
  }
27
26
  catch {
28
27
  return null;
@@ -30,10 +29,10 @@ async function readManifest(projectDir) {
30
29
  }
31
30
  /** Count entries in a directory */
32
31
  async function countDir(dir) {
33
- if (!await fs.pathExists(dir))
32
+ if (!(await fs.pathExists(dir)))
34
33
  return 0;
35
34
  const entries = await fs.readdir(dir);
36
- return entries.filter(e => !e.startsWith('.')).length;
35
+ return entries.filter((e) => !e.startsWith(".")).length;
37
36
  }
38
37
  /**
39
38
  * Run comprehensive health checks for the project and framework.
@@ -44,114 +43,130 @@ export async function runDoctor(projectDir) {
44
43
  // ── 1. System Tools ────────────────────────────────────────────────────────
45
44
  const toolChecks = [];
46
45
  const tools = [
47
- { name: 'git', label: 'Git' },
48
- { name: 'docker', label: 'Docker' },
49
- { name: 'semgrep', label: 'Semgrep' },
50
- { name: 'node', label: 'Node.js' },
51
- { name: 'pnpm', label: 'pnpm' },
46
+ { name: "git", label: "Git" },
47
+ { name: "docker", label: "Docker" },
48
+ { name: "semgrep", label: "Semgrep" },
49
+ { name: "node", label: "Node.js" },
50
+ { name: "pnpm", label: "pnpm" },
52
51
  ];
53
52
  for (const tool of tools) {
54
53
  const bin = await which(tool.name);
55
54
  if (bin) {
56
55
  // Try to get version
57
- let version = '';
56
+ let version = "";
58
57
  try {
59
- const { stdout } = await execFileAsync(tool.name, ['--version']);
60
- version = stdout.trim().split('\n')[0] ?? '';
58
+ const { stdout } = await execFileAsync(tool.name, ["--version"]);
59
+ version = stdout.trim().split("\n")[0] ?? "";
60
+ }
61
+ catch {
62
+ /* ignore */
61
63
  }
62
- catch { /* ignore */ }
63
64
  toolChecks.push({
64
65
  label: tool.label,
65
- status: 'ok',
66
+ status: "ok",
66
67
  detail: version ? `${version}` : `found at ${bin}`,
67
68
  });
68
69
  }
69
70
  else {
70
71
  toolChecks.push({
71
72
  label: tool.label,
72
- status: tool.name === 'docker' || tool.name === 'semgrep' ? 'skip' : 'fail',
73
- detail: 'not found in PATH',
73
+ status: tool.name === "docker" || tool.name === "semgrep" ? "skip" : "fail",
74
+ detail: "not found in PATH",
74
75
  });
75
76
  }
76
77
  }
77
- sections.push({ title: 'System Tools', checks: toolChecks });
78
+ sections.push({ title: "System Tools", checks: toolChecks });
78
79
  // ── 2. Framework Structure ─────────────────────────────────────────────────
79
80
  const structureChecks = [];
80
81
  const expectedDirs = [
81
- { path: TEMPLATES_DIR, label: 'templates/' },
82
- { path: MODULES_DIR, label: 'modules/' },
83
- { path: path.join(FORGE_ROOT, 'workflows'), label: 'workflows/' },
84
- { path: path.join(FORGE_ROOT, 'ci-local'), label: 'ci-local/' },
82
+ { path: TEMPLATES_DIR, label: "templates/" },
83
+ { path: MODULES_DIR, label: "modules/" },
84
+ { path: path.join(FORGE_ROOT, "workflows"), label: "workflows/" },
85
+ { path: path.join(FORGE_ROOT, "ci-local"), label: "ci-local/" },
85
86
  ];
86
87
  for (const dir of expectedDirs) {
87
88
  if (await fs.pathExists(dir.path)) {
88
89
  const count = await countDir(dir.path);
89
- structureChecks.push({ label: dir.label, status: 'ok', detail: `${count} entries` });
90
+ structureChecks.push({
91
+ label: dir.label,
92
+ status: "ok",
93
+ detail: `${count} entries`,
94
+ });
90
95
  }
91
96
  else {
92
- structureChecks.push({ label: dir.label, status: 'fail', detail: 'missing' });
97
+ structureChecks.push({
98
+ label: dir.label,
99
+ status: "fail",
100
+ detail: "missing",
101
+ });
93
102
  }
94
103
  }
95
- sections.push({ title: 'Framework Structure', checks: structureChecks });
104
+ sections.push({ title: "Framework Structure", checks: structureChecks });
96
105
  // ── 3. Stack Detection ─────────────────────────────────────────────────────
97
106
  const stackChecks = [];
98
107
  const detection = await detectStack(cwd);
99
108
  if (detection) {
100
109
  stackChecks.push({
101
- label: 'Detected stack',
102
- status: 'ok',
103
- detail: `${detection.stackType} (${detection.buildTool})${detection.javaVersion ? ` Java ${detection.javaVersion}` : ''}`,
110
+ label: "Detected stack",
111
+ status: "ok",
112
+ detail: `${detection.stackType} (${detection.buildTool})${detection.javaVersion ? ` Java ${detection.javaVersion}` : ""}`,
104
113
  });
105
114
  }
106
115
  else {
107
116
  stackChecks.push({
108
- label: 'Detected stack',
109
- status: 'skip',
110
- detail: 'no recognizable project files in current directory',
117
+ label: "Detected stack",
118
+ status: "skip",
119
+ detail: "no recognizable project files in current directory",
111
120
  });
112
121
  }
113
- sections.push({ title: 'Stack Detection', checks: stackChecks });
122
+ sections.push({ title: "Stack Detection", checks: stackChecks });
114
123
  // ── 4. Project Manifest ────────────────────────────────────────────────────
115
124
  const manifestChecks = [];
116
125
  const manifest = await readManifest(cwd);
117
126
  if (manifest) {
118
127
  manifestChecks.push({
119
- label: 'Forge manifest',
120
- status: 'ok',
128
+ label: "Forge manifest",
129
+ status: "ok",
121
130
  detail: `project: ${manifest.projectName}, stack: ${manifest.stack}`,
122
131
  });
123
132
  manifestChecks.push({
124
- label: 'Created',
125
- status: 'ok',
126
- detail: manifest.createdAt.split('T')[0],
133
+ label: "Created",
134
+ status: "ok",
135
+ detail: manifest.createdAt.split("T")[0],
127
136
  });
128
137
  manifestChecks.push({
129
- label: 'Modules',
130
- status: manifest.modules.length > 0 ? 'ok' : 'skip',
131
- detail: manifest.modules.length > 0 ? manifest.modules.join(', ') : 'none installed',
138
+ label: "Modules",
139
+ status: manifest.modules.length > 0 ? "ok" : "skip",
140
+ detail: manifest.modules.length > 0
141
+ ? manifest.modules.join(", ")
142
+ : "none installed",
132
143
  });
133
144
  }
134
145
  else {
135
146
  manifestChecks.push({
136
- label: 'Forge manifest',
137
- status: 'skip',
138
- detail: 'not a forge-managed project (run javi-forge init)',
147
+ label: "Forge manifest",
148
+ status: "skip",
149
+ detail: "not a forge-managed project (run javi-forge init)",
139
150
  });
140
151
  }
141
- sections.push({ title: 'Project Manifest', checks: manifestChecks });
152
+ sections.push({ title: "Project Manifest", checks: manifestChecks });
142
153
  // ── 5. Installed Modules ───────────────────────────────────────────────────
143
154
  const moduleChecks = [];
144
- const moduleNames = ['engram', 'obsidian-brain', 'memory-simple', 'ghagga'];
155
+ const moduleNames = ["engram", "obsidian-brain", "memory-simple", "ghagga"];
145
156
  for (const mod of moduleNames) {
146
- const modPath = path.join(cwd, '.javi-forge', 'modules', mod);
157
+ const modPath = path.join(cwd, ".javi-forge", "modules", mod);
147
158
  if (await fs.pathExists(modPath)) {
148
- moduleChecks.push({ label: mod, status: 'ok', detail: 'installed' });
159
+ moduleChecks.push({ label: mod, status: "ok", detail: "installed" });
149
160
  }
150
161
  else {
151
- moduleChecks.push({ label: mod, status: 'skip', detail: 'not installed' });
162
+ moduleChecks.push({
163
+ label: mod,
164
+ status: "skip",
165
+ detail: "not installed",
166
+ });
152
167
  }
153
168
  }
154
- sections.push({ title: 'Installed Modules', checks: moduleChecks });
169
+ sections.push({ title: "Installed Modules", checks: moduleChecks });
155
170
  // ── 6. Plugins ─────────────────────────────────────────────────────────────
156
171
  const pluginChecks = [];
157
172
  const pluginsDirExists = await fs.pathExists(PLUGINS_DIR);
@@ -161,19 +176,54 @@ export async function runDoctor(projectDir) {
161
176
  for (const plugin of plugins) {
162
177
  pluginChecks.push({
163
178
  label: plugin.name,
164
- status: 'ok',
179
+ status: "ok",
165
180
  detail: `v${plugin.version} from ${plugin.source}`,
166
181
  });
167
182
  }
168
183
  }
169
184
  else {
170
- pluginChecks.push({ label: 'Plugins', status: 'skip', detail: 'none installed' });
185
+ pluginChecks.push({
186
+ label: "Plugins",
187
+ status: "skip",
188
+ detail: "none installed",
189
+ });
171
190
  }
172
191
  }
173
192
  else {
174
- pluginChecks.push({ label: 'Plugins directory', status: 'skip', detail: 'not created yet' });
193
+ pluginChecks.push({
194
+ label: "Plugins directory",
195
+ status: "skip",
196
+ detail: "not created yet",
197
+ });
198
+ }
199
+ sections.push({ title: "Plugins", checks: pluginChecks });
200
+ // ── 7. Context Directory Refresh ───────────────────────────────────────────
201
+ const contextChecks = [];
202
+ try {
203
+ const result = await refreshContextDir(cwd);
204
+ if (result) {
205
+ contextChecks.push({
206
+ label: ".context/ refresh",
207
+ status: "ok",
208
+ detail: "INDEX.md + summary.md updated",
209
+ });
210
+ }
211
+ else {
212
+ contextChecks.push({
213
+ label: ".context/ refresh",
214
+ status: "skip",
215
+ detail: "no .context/ or no manifest found",
216
+ });
217
+ }
218
+ }
219
+ catch (e) {
220
+ contextChecks.push({
221
+ label: ".context/ refresh",
222
+ status: "fail",
223
+ detail: `refresh failed: ${String(e)}`,
224
+ });
175
225
  }
176
- sections.push({ title: 'Plugins', checks: pluginChecks });
226
+ sections.push({ title: "Context Directory", checks: contextChecks });
177
227
  return { sections };
178
228
  }
179
229
  //# sourceMappingURL=doctor.js.map
@@ -0,0 +1,13 @@
1
+ import type { InitStep } from "../../types/index.js";
2
+ import type { StepCallback } from "./types.js";
3
+ /**
4
+ * Emit a step progress event via the callback.
5
+ *
6
+ * Centralized helper extracted during the init.ts split. Functionally
7
+ * identical to the original inline report function, with an explicit
8
+ * `void` return type added for type clarity. Behavior MUST stay
9
+ * compatible so tests asserting on emitted steps[] (and the ordering
10
+ * contract test) keep passing through the PR 1-6 extraction.
11
+ */
12
+ export declare function report(onStep: StepCallback, id: string, label: string, status: InitStep["status"], detail?: string): void;
13
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Emit a step progress event via the callback.
3
+ *
4
+ * Centralized helper extracted during the init.ts split. Functionally
5
+ * identical to the original inline report function, with an explicit
6
+ * `void` return type added for type clarity. Behavior MUST stay
7
+ * compatible so tests asserting on emitted steps[] (and the ordering
8
+ * contract test) keep passing through the PR 1-6 extraction.
9
+ */
10
+ export function report(onStep, id, label, status, detail) {
11
+ onStep({ id, label, status, detail });
12
+ }
13
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1,13 @@
1
+ import type { StepFn } from "../types.js";
2
+ /**
3
+ * Step 17: Generate Agent Skills manifest (skills.json).
4
+ *
5
+ * - In dry-run mode, reports what would be created without touching disk.
6
+ * - Otherwise writes <projectDir>/<AGENT_SKILLS_MANIFEST_FILE> with an empty
7
+ * skills array unless the file already exists (idempotent).
8
+ * - Errors are swallowed and reported as status:"error" — never thrown.
9
+ *
10
+ * Extracted VERBATIM from src/commands/init.ts (PR 6 of 6).
11
+ */
12
+ export declare const stepAgentSkills: StepFn;
13
+ //# sourceMappingURL=agent-skills.d.ts.map
@@ -0,0 +1,45 @@
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import { AGENT_SKILLS_MANIFEST_FILE } from "../../../constants.js";
4
+ import { report } from "../report.js";
5
+ /**
6
+ * Step 17: Generate Agent Skills manifest (skills.json).
7
+ *
8
+ * - In dry-run mode, reports what would be created without touching disk.
9
+ * - Otherwise writes <projectDir>/<AGENT_SKILLS_MANIFEST_FILE> with an empty
10
+ * skills array unless the file already exists (idempotent).
11
+ * - Errors are swallowed and reported as status:"error" — never thrown.
12
+ *
13
+ * Extracted VERBATIM from src/commands/init.ts (PR 6 of 6).
14
+ */
15
+ export const stepAgentSkills = async (ctx) => {
16
+ const { projectDir, dryRun, onStep, options } = ctx;
17
+ const { projectName } = options;
18
+ const stepId = "agent-skills";
19
+ report(onStep, stepId, "Generate Agent Skills manifest (skills.json)", "running");
20
+ try {
21
+ if (!dryRun) {
22
+ const skillsManifest = {
23
+ name: projectName,
24
+ version: "0.1.0",
25
+ description: `Agent Skills manifest for ${projectName}`,
26
+ skills: [],
27
+ };
28
+ const skillsJsonPath = path.join(projectDir, AGENT_SKILLS_MANIFEST_FILE);
29
+ if (!(await fs.pathExists(skillsJsonPath))) {
30
+ await fs.writeJson(skillsJsonPath, skillsManifest, { spaces: 2 });
31
+ report(onStep, stepId, "Generate Agent Skills manifest (skills.json)", "done", AGENT_SKILLS_MANIFEST_FILE);
32
+ }
33
+ else {
34
+ report(onStep, stepId, "Generate Agent Skills manifest (skills.json)", "done", "already exists");
35
+ }
36
+ }
37
+ else {
38
+ report(onStep, stepId, "Generate Agent Skills manifest (skills.json)", "done", `dry-run: would generate ${AGENT_SKILLS_MANIFEST_FILE}`);
39
+ }
40
+ }
41
+ catch (e) {
42
+ report(onStep, stepId, "Generate Agent Skills manifest (skills.json)", "error", String(e));
43
+ }
44
+ };
45
+ //# sourceMappingURL=agent-skills.js.map
@@ -0,0 +1,15 @@
1
+ import type { StepFn } from "../types.js";
2
+ /**
3
+ * Step 7: AI config sync (delegated to javi-ai).
4
+ *
5
+ * - When aiSync is false, reports "skipped".
6
+ * - When dryRun, reports a done message without invoking javi-ai.
7
+ * - Otherwise shells out to `npx javi-ai sync --project-dir <projectDir> --target all`.
8
+ * - Detects soft failures via stderr (e.g. "Raw mode is not supported", "ERROR").
9
+ * - Hard failures (ENOENT, not found, ERR_MODULE_NOT_FOUND) report a helpful install hint.
10
+ * - Errors are swallowed and reported as status:"error" — never thrown.
11
+ *
12
+ * Extracted VERBATIM from src/commands/init.ts (PR 3 of 6).
13
+ */
14
+ export declare const stepAISync: StepFn;
15
+ //# sourceMappingURL=ai-sync.d.ts.map
@@ -0,0 +1,62 @@
1
+ import { execFileAsync } from "../../../lib/exec.js";
2
+ import { report } from "../report.js";
3
+ /**
4
+ * Step 7: AI config sync (delegated to javi-ai).
5
+ *
6
+ * - When aiSync is false, reports "skipped".
7
+ * - When dryRun, reports a done message without invoking javi-ai.
8
+ * - Otherwise shells out to `npx javi-ai sync --project-dir <projectDir> --target all`.
9
+ * - Detects soft failures via stderr (e.g. "Raw mode is not supported", "ERROR").
10
+ * - Hard failures (ENOENT, not found, ERR_MODULE_NOT_FOUND) report a helpful install hint.
11
+ * - Errors are swallowed and reported as status:"error" — never thrown.
12
+ *
13
+ * Extracted VERBATIM from src/commands/init.ts (PR 3 of 6).
14
+ */
15
+ export const stepAISync = async (ctx) => {
16
+ const { projectDir, dryRun, onStep, options } = ctx;
17
+ const { aiSync } = options;
18
+ const stepId = "ai-sync";
19
+ report(onStep, stepId, "Sync AI config via javi-ai", "running");
20
+ try {
21
+ if (aiSync) {
22
+ if (!dryRun) {
23
+ try {
24
+ const { stderr } = await execFileAsync("npx", ["javi-ai", "sync", "--project-dir", projectDir, "--target", "all"], {
25
+ cwd: projectDir,
26
+ timeout: 120_000,
27
+ });
28
+ // javi-ai may exit 0 but crash (e.g. Ink raw mode error) — detect via stderr
29
+ if (stderr &&
30
+ (stderr.includes("Raw mode is not supported") ||
31
+ stderr.includes("ERROR"))) {
32
+ report(onStep, stepId, "Sync AI config via javi-ai", "error", "javi-ai crashed. Run manually: npx javi-ai sync --project-dir . --target all");
33
+ }
34
+ else {
35
+ report(onStep, stepId, "Sync AI config via javi-ai", "done", "javi-ai sync --target all");
36
+ }
37
+ }
38
+ catch (syncErr) {
39
+ const msg = syncErr instanceof Error ? syncErr.message : String(syncErr);
40
+ if (msg.includes("ENOENT") ||
41
+ msg.includes("not found") ||
42
+ msg.includes("ERR_MODULE_NOT_FOUND")) {
43
+ report(onStep, stepId, "Sync AI config via javi-ai", "error", "javi-ai not found. Install with: npm install -g javi-ai (or run npx javi-ai sync manually)");
44
+ }
45
+ else {
46
+ report(onStep, stepId, "Sync AI config via javi-ai", "error", msg);
47
+ }
48
+ }
49
+ }
50
+ else {
51
+ report(onStep, stepId, "Sync AI config via javi-ai", "done", "dry-run: would run javi-ai sync --target all");
52
+ }
53
+ }
54
+ else {
55
+ report(onStep, stepId, "Sync AI config via javi-ai", "skipped", "not selected");
56
+ }
57
+ }
58
+ catch (e) {
59
+ report(onStep, stepId, "Sync AI config via javi-ai", "error", String(e));
60
+ }
61
+ };
62
+ //# sourceMappingURL=ai-sync.js.map
@@ -0,0 +1,24 @@
1
+ import type { StepFn } from "../types.js";
2
+ /**
3
+ * Step 3: Copy CI template.
4
+ *
5
+ * - Generates the CI workflow for the detected stack + provider.
6
+ * - Writes to getCIDestination(ciProvider), backing up any existing file.
7
+ * - Skips with "no template for <stack>" when generateCIWorkflow returns empty.
8
+ * - Errors are swallowed and reported as status:"error" — never thrown.
9
+ *
10
+ * Extracted VERBATIM from src/commands/init.ts (PR 2 of 6).
11
+ */
12
+ export declare const stepCITemplate: StepFn;
13
+ /**
14
+ * Step 5: Generate dependabot.yml.
15
+ *
16
+ * - Only runs when ciProvider === "github".
17
+ * - Writes .github/dependabot.yml with backup of any existing file.
18
+ * - Otherwise reports skipped with "not needed for <ciProvider>".
19
+ * - Errors are swallowed and reported as status:"error" — never thrown.
20
+ *
21
+ * Extracted VERBATIM from src/commands/init.ts (PR 2 of 6).
22
+ */
23
+ export declare const stepDependabot: StepFn;
24
+ //# sourceMappingURL=ci.d.ts.map
@@ -0,0 +1,74 @@
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import { backupIfExists, ensureDirExists } from "../../../lib/common.js";
4
+ import { generateCIWorkflow, generateDependabotYml, getCIDestination, } from "../../../lib/template.js";
5
+ import { report } from "../report.js";
6
+ /**
7
+ * Step 3: Copy CI template.
8
+ *
9
+ * - Generates the CI workflow for the detected stack + provider.
10
+ * - Writes to getCIDestination(ciProvider), backing up any existing file.
11
+ * - Skips with "no template for <stack>" when generateCIWorkflow returns empty.
12
+ * - Errors are swallowed and reported as status:"error" — never thrown.
13
+ *
14
+ * Extracted VERBATIM from src/commands/init.ts (PR 2 of 6).
15
+ */
16
+ export const stepCITemplate = async (ctx) => {
17
+ const { projectDir, dryRun, onStep, options } = ctx;
18
+ const { stack, ciProvider } = options;
19
+ const stepId = "ci-template";
20
+ report(onStep, stepId, `Copy ${ciProvider} CI workflow`, "running");
21
+ try {
22
+ const ciContent = await generateCIWorkflow(stack, ciProvider);
23
+ if (ciContent) {
24
+ const dest = path.join(projectDir, getCIDestination(ciProvider));
25
+ if (!dryRun) {
26
+ await backupIfExists(dest);
27
+ await ensureDirExists(path.dirname(dest));
28
+ await fs.writeFile(dest, ciContent, "utf-8");
29
+ }
30
+ report(onStep, stepId, `Copy ${ciProvider} CI workflow`, "done", getCIDestination(ciProvider));
31
+ }
32
+ else {
33
+ report(onStep, stepId, `Copy ${ciProvider} CI workflow`, "skipped", `no template for ${stack}`);
34
+ }
35
+ }
36
+ catch (e) {
37
+ report(onStep, stepId, `Copy ${ciProvider} CI workflow`, "error", String(e));
38
+ }
39
+ };
40
+ /**
41
+ * Step 5: Generate dependabot.yml.
42
+ *
43
+ * - Only runs when ciProvider === "github".
44
+ * - Writes .github/dependabot.yml with backup of any existing file.
45
+ * - Otherwise reports skipped with "not needed for <ciProvider>".
46
+ * - Errors are swallowed and reported as status:"error" — never thrown.
47
+ *
48
+ * Extracted VERBATIM from src/commands/init.ts (PR 2 of 6).
49
+ */
50
+ export const stepDependabot = async (ctx) => {
51
+ const { projectDir, dryRun, onStep, options } = ctx;
52
+ const { stack, ciProvider } = options;
53
+ const stepId = "dependabot";
54
+ report(onStep, stepId, "Generate dependabot.yml", "running");
55
+ try {
56
+ if (ciProvider === "github") {
57
+ const content = await generateDependabotYml([stack], true);
58
+ const dest = path.join(projectDir, ".github", "dependabot.yml");
59
+ if (!dryRun) {
60
+ await backupIfExists(dest);
61
+ await ensureDirExists(path.dirname(dest));
62
+ await fs.writeFile(dest, content, "utf-8");
63
+ }
64
+ report(onStep, stepId, "Generate dependabot.yml", "done");
65
+ }
66
+ else {
67
+ report(onStep, stepId, "Generate dependabot.yml", "skipped", `not needed for ${ciProvider}`);
68
+ }
69
+ }
70
+ catch (e) {
71
+ report(onStep, stepId, "Generate dependabot.yml", "error", String(e));
72
+ }
73
+ };
74
+ //# sourceMappingURL=ci.js.map
@@ -0,0 +1,14 @@
1
+ import type { StepFn } from "../types.js";
2
+ /**
3
+ * Step 12: Generate CLAUDE.md (smart: project-aware).
4
+ *
5
+ * - When claudeMd is false, reports "skipped".
6
+ * - If CLAUDE.md already exists at the project root, reports "done" with "already exists".
7
+ * - Otherwise detects the project stack and writes a smart CLAUDE.md;
8
+ * the detail mentions the number of recommended skills detected.
9
+ * - Errors are swallowed and reported as status:"error" — never thrown.
10
+ *
11
+ * Extracted VERBATIM from src/commands/init.ts (PR 4 of 6).
12
+ */
13
+ export declare const stepClaudeMd: StepFn;
14
+ //# sourceMappingURL=claude-md.d.ts.map
@@ -0,0 +1,54 @@
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import { generateSmartClaudeMd } from "../../../lib/claudemd.js";
4
+ import { detectProjectStack } from "../../../lib/stack-detector.js";
5
+ import { report } from "../report.js";
6
+ /**
7
+ * Step 12: Generate CLAUDE.md (smart: project-aware).
8
+ *
9
+ * - When claudeMd is false, reports "skipped".
10
+ * - If CLAUDE.md already exists at the project root, reports "done" with "already exists".
11
+ * - Otherwise detects the project stack and writes a smart CLAUDE.md;
12
+ * the detail mentions the number of recommended skills detected.
13
+ * - Errors are swallowed and reported as status:"error" — never thrown.
14
+ *
15
+ * Extracted VERBATIM from src/commands/init.ts (PR 4 of 6).
16
+ */
17
+ export const stepClaudeMd = async (ctx) => {
18
+ const { projectDir, dryRun, onStep, options } = ctx;
19
+ const { claudeMd } = options;
20
+ const stepId = "claude-md";
21
+ report(onStep, stepId, "Generate CLAUDE.md", "running");
22
+ try {
23
+ if (claudeMd) {
24
+ const claudeMdPath = path.join(projectDir, "CLAUDE.md");
25
+ if (await fs.pathExists(claudeMdPath)) {
26
+ report(onStep, stepId, "Generate CLAUDE.md", "done", "already exists");
27
+ }
28
+ else {
29
+ if (!dryRun) {
30
+ // Detect project stack for smart CLAUDE.md generation
31
+ const detection = await detectProjectStack(projectDir).catch(() => null);
32
+ const content = generateSmartClaudeMd(options, detection);
33
+ await fs.writeFile(claudeMdPath, content, "utf-8");
34
+ // detection itself can be null from .catch(() => null) above;
35
+ // recommendedSkills is always an array if detection succeeds.
36
+ const skillCount = detection?.recommendedSkills.length ?? 0;
37
+ report(onStep, stepId, "Generate CLAUDE.md", "done", skillCount > 0
38
+ ? `CLAUDE.md (${skillCount} skills detected)`
39
+ : "CLAUDE.md");
40
+ }
41
+ else {
42
+ report(onStep, stepId, "Generate CLAUDE.md", "done", "dry-run: would generate CLAUDE.md");
43
+ }
44
+ }
45
+ }
46
+ else {
47
+ report(onStep, stepId, "Generate CLAUDE.md", "skipped", "not selected");
48
+ }
49
+ }
50
+ catch (e) {
51
+ report(onStep, stepId, "Generate CLAUDE.md", "error", String(e));
52
+ }
53
+ };
54
+ //# sourceMappingURL=claude-md.js.map
@@ -0,0 +1,16 @@
1
+ import type { StepFn } from "../types.js";
2
+ /**
3
+ * Step 15: Scaffold RepoForge code graph.
4
+ *
5
+ * - When options.codeGraph is false, reports "skipped".
6
+ * - Otherwise:
7
+ * 1. Copies .repoforge.yaml config (skip if exists).
8
+ * 2. Ensures .repoforge/ output dir exists.
9
+ * 3. Copies the graph generation CI workflow when ciProvider === "github".
10
+ * 4. Copies the MCP config snippet with __PROJECT_NAME__ interpolation.
11
+ * - Errors are swallowed and reported as status:"error" — never thrown.
12
+ *
13
+ * Extracted VERBATIM from src/commands/init.ts (PR 5 of 6).
14
+ */
15
+ export declare const stepCodeGraph: StepFn;
16
+ //# sourceMappingURL=code-graph.d.ts.map