javi-forge 1.6.1 → 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 (159) 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.js +1 -3
  37. package/dist/commands/ci.d.ts +47 -0
  38. package/dist/commands/ci.js +380 -63
  39. package/dist/commands/doctor.js +2 -4
  40. package/dist/commands/init/report.d.ts +13 -0
  41. package/dist/commands/init/report.js +13 -0
  42. package/dist/commands/init/steps/agent-skills.d.ts +13 -0
  43. package/dist/commands/init/steps/agent-skills.js +45 -0
  44. package/dist/commands/init/steps/ai-sync.d.ts +15 -0
  45. package/dist/commands/init/steps/ai-sync.js +62 -0
  46. package/dist/commands/init/steps/ci.d.ts +24 -0
  47. package/dist/commands/init/steps/ci.js +74 -0
  48. package/dist/commands/init/steps/claude-md.d.ts +14 -0
  49. package/dist/commands/init/steps/claude-md.js +54 -0
  50. package/dist/commands/init/steps/code-graph.d.ts +16 -0
  51. package/dist/commands/init/steps/code-graph.js +68 -0
  52. package/dist/commands/init/steps/context-dir.d.ts +13 -0
  53. package/dist/commands/init/steps/context-dir.js +47 -0
  54. package/dist/commands/init/steps/docker-deploy.d.ts +16 -0
  55. package/dist/commands/init/steps/docker-deploy.js +60 -0
  56. package/dist/commands/init/steps/ghagga.d.ts +15 -0
  57. package/dist/commands/init/steps/ghagga.js +58 -0
  58. package/dist/commands/init/steps/git.d.ts +25 -0
  59. package/dist/commands/init/steps/git.js +81 -0
  60. package/dist/commands/init/steps/gitignore.d.ts +13 -0
  61. package/dist/commands/init/steps/gitignore.js +39 -0
  62. package/dist/commands/init/steps/local-ai.d.ts +14 -0
  63. package/dist/commands/init/steps/local-ai.js +53 -0
  64. package/dist/commands/init/steps/manifest.d.ts +13 -0
  65. package/dist/commands/init/steps/manifest.js +58 -0
  66. package/dist/commands/init/steps/memory.d.ts +15 -0
  67. package/dist/commands/init/steps/memory.js +60 -0
  68. package/dist/commands/init/steps/mock.d.ts +13 -0
  69. package/dist/commands/init/steps/mock.js +64 -0
  70. package/dist/commands/init/steps/sdd.d.ts +12 -0
  71. package/dist/commands/init/steps/sdd.js +40 -0
  72. package/dist/commands/init/steps/security.d.ts +28 -0
  73. package/dist/commands/init/steps/security.js +103 -0
  74. package/dist/commands/init/types.d.ts +30 -0
  75. package/dist/commands/init/types.js +2 -0
  76. package/dist/commands/init.d.ts +5 -4
  77. package/dist/commands/init.js +42 -630
  78. package/dist/commands/llmstxt.js +1 -1
  79. package/dist/commands/plugin.js +1 -1
  80. package/dist/commands/security.js +23 -4
  81. package/dist/commands/skills/analysis.d.ts +19 -0
  82. package/dist/commands/skills/analysis.js +211 -0
  83. package/dist/commands/skills/benchmark.d.ts +6 -0
  84. package/dist/commands/skills/benchmark.js +82 -0
  85. package/dist/commands/skills/constants.d.ts +10 -0
  86. package/dist/commands/skills/constants.js +27 -0
  87. package/dist/commands/skills/directives.d.ts +21 -0
  88. package/dist/commands/skills/directives.js +101 -0
  89. package/dist/commands/skills/parsing.d.ts +16 -0
  90. package/dist/commands/skills/parsing.js +108 -0
  91. package/dist/commands/skills/rules.d.ts +5 -0
  92. package/dist/commands/skills/rules.js +32 -0
  93. package/dist/commands/skills/scoring.d.ts +47 -0
  94. package/dist/commands/skills/scoring.js +306 -0
  95. package/dist/commands/skills.d.ts +7 -125
  96. package/dist/commands/skills.js +8 -874
  97. package/dist/commands/tdd-pipeline.js +1 -1
  98. package/dist/commands/tdd.js +1 -1
  99. package/dist/commands/workflow.js +2 -0
  100. package/dist/constants.js +2 -2
  101. package/dist/index.js +26 -473
  102. package/dist/lib/agent-skills.js +1 -1
  103. package/dist/{commands → lib}/atlassian-mcp.js +2 -2
  104. package/dist/lib/auto-skill-install.js +2 -3
  105. package/dist/lib/auto-wire.js +7 -7
  106. package/dist/lib/ci-config.d.ts +65 -0
  107. package/dist/lib/ci-config.js +297 -0
  108. package/dist/lib/claudemd.js +1 -1
  109. package/dist/lib/codex-export.js +4 -8
  110. package/dist/lib/common.js +2 -2
  111. package/dist/lib/context.js +2 -2
  112. package/dist/{commands → lib}/crash-recovery.js +4 -4
  113. package/dist/lib/docker.d.ts +22 -1
  114. package/dist/lib/docker.js +57 -49
  115. package/dist/lib/exec.d.ts +10 -0
  116. package/dist/lib/exec.js +11 -0
  117. package/dist/lib/frontmatter.js +2 -2
  118. package/dist/{commands → lib}/harness-audit.js +1 -1
  119. package/dist/{commands → lib}/parallel-batch.js +1 -3
  120. package/dist/lib/plugin.js +2 -4
  121. package/dist/{commands → lib}/secret-scanner.js +3 -1
  122. package/dist/{commands → lib}/security-analysis.js +4 -2
  123. package/dist/lib/skill-publish.js +23 -5
  124. package/dist/{commands → lib}/skill-scanner.d.ts +1 -1
  125. package/dist/{commands → lib}/skill-scanner.js +3 -3
  126. package/dist/lib/stack-detector.js +3 -3
  127. package/dist/{commands → lib}/supply-chain.js +1 -1
  128. package/dist/lib/template.js +2 -2
  129. package/dist/lib/workflow/discovery.d.ts +8 -0
  130. package/dist/lib/workflow/discovery.js +18 -1
  131. package/dist/lib/workflow/parser.js +15 -15
  132. package/dist/lib/workflow/validator.js +4 -4
  133. package/dist/tasks/index.d.ts +3 -3
  134. package/dist/tasks/index.js +3 -3
  135. package/dist/tasks/scaffold-tasks.d.ts +1 -1
  136. package/dist/tasks/scaffold-tasks.js +10 -10
  137. package/dist/tasks/task-id.d.ts +1 -1
  138. package/dist/tasks/task-id.js +9 -5
  139. package/dist/tasks/task-tracker.d.ts +1 -1
  140. package/dist/tasks/task-tracker.js +7 -7
  141. package/dist/ui/App.js +1 -1
  142. package/dist/ui/CIContext.js +1 -2
  143. package/dist/ui/Header.js +4 -4
  144. package/dist/ui/NameInput.js +1 -1
  145. package/dist/ui/Progress.d.ts +1 -1
  146. package/dist/ui/Progress.js +1 -1
  147. package/dist/ui/StackSelector.js +1 -1
  148. package/lib/common.psm1 +167 -0
  149. package/lib/common.sh +30 -0
  150. package/package.json +38 -19
  151. /package/dist/{commands → lib}/atlassian-mcp.d.ts +0 -0
  152. /package/dist/{commands → lib}/crash-recovery.d.ts +0 -0
  153. /package/dist/{commands → lib}/harness-audit.d.ts +0 -0
  154. /package/dist/{commands → lib}/parallel-batch.d.ts +0 -0
  155. /package/dist/{commands → lib}/secret-scanner.d.ts +0 -0
  156. /package/dist/{commands → lib}/security-analysis.d.ts +0 -0
  157. /package/dist/{commands → lib}/supply-chain.d.ts +0 -0
  158. /package/dist/{commands → lib}/team-presets.d.ts +0 -0
  159. /package/dist/{commands → lib}/team-presets.js +0 -0
@@ -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
@@ -0,0 +1,68 @@
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import { TEMPLATES_DIR } from "../../../constants.js";
4
+ import { backupIfExists, ensureDirExists } from "../../../lib/common.js";
5
+ import { report } from "../report.js";
6
+ /**
7
+ * Step 15: Scaffold RepoForge code graph.
8
+ *
9
+ * - When options.codeGraph is false, reports "skipped".
10
+ * - Otherwise:
11
+ * 1. Copies .repoforge.yaml config (skip if exists).
12
+ * 2. Ensures .repoforge/ output dir exists.
13
+ * 3. Copies the graph generation CI workflow when ciProvider === "github".
14
+ * 4. Copies the MCP config snippet with __PROJECT_NAME__ interpolation.
15
+ * - Errors are swallowed and reported as status:"error" — never thrown.
16
+ *
17
+ * Extracted VERBATIM from src/commands/init.ts (PR 5 of 6).
18
+ */
19
+ export const stepCodeGraph = async (ctx) => {
20
+ const { projectDir, dryRun, onStep, options } = ctx;
21
+ const { projectName, ciProvider } = options;
22
+ const stepId = "code-graph";
23
+ report(onStep, stepId, "Scaffold RepoForge code graph", "running");
24
+ try {
25
+ if (options.codeGraph) {
26
+ if (!dryRun) {
27
+ // 1. Copy .repoforge.yaml config
28
+ const repoforgeConfigSrc = path.join(TEMPLATES_DIR, "common", "repoforge", "repoforge.yaml");
29
+ const repoforgeConfigDest = path.join(projectDir, ".repoforge.yaml");
30
+ if (!(await fs.pathExists(repoforgeConfigDest))) {
31
+ await fs.copy(repoforgeConfigSrc, repoforgeConfigDest);
32
+ }
33
+ // 2. Ensure .repoforge/ output dir exists
34
+ await ensureDirExists(path.join(projectDir, ".repoforge"));
35
+ // 3. Copy CI workflow for graph generation (GitHub only)
36
+ if (ciProvider === "github") {
37
+ const graphWorkflowSrc = path.join(TEMPLATES_DIR, "github", "repoforge-graph.yml");
38
+ if (await fs.pathExists(graphWorkflowSrc)) {
39
+ const graphWorkflowDest = path.join(projectDir, ".github", "workflows", "repoforge-graph.yml");
40
+ await ensureDirExists(path.dirname(graphWorkflowDest));
41
+ await backupIfExists(graphWorkflowDest);
42
+ await fs.copy(graphWorkflowSrc, graphWorkflowDest, {
43
+ overwrite: false,
44
+ });
45
+ }
46
+ }
47
+ // 4. Copy MCP config snippet for repoforge code intelligence
48
+ const mcpSnippetSrc = path.join(TEMPLATES_DIR, "common", "repoforge", "mcp-repoforge-snippet.json");
49
+ if (await fs.pathExists(mcpSnippetSrc)) {
50
+ const mcpSnippetDest = path.join(projectDir, ".repoforge", "mcp-config-snippet.json");
51
+ let content = await fs.readFile(mcpSnippetSrc, "utf-8");
52
+ content = content.replace(/__PROJECT_NAME__/g, projectName);
53
+ await fs.writeFile(mcpSnippetDest, content, "utf-8");
54
+ }
55
+ }
56
+ report(onStep, stepId, "Scaffold RepoForge code graph", "done", dryRun
57
+ ? "dry-run: would scaffold .repoforge.yaml + CI + MCP"
58
+ : ".repoforge.yaml + CI + MCP snippet");
59
+ }
60
+ else {
61
+ report(onStep, stepId, "Scaffold RepoForge code graph", "skipped", "not selected");
62
+ }
63
+ }
64
+ catch (e) {
65
+ report(onStep, stepId, "Scaffold RepoForge code graph", "error", String(e));
66
+ }
67
+ };
68
+ //# sourceMappingURL=code-graph.js.map
@@ -0,0 +1,13 @@
1
+ import type { StepFn } from "../types.js";
2
+ /**
3
+ * Step 11: Generate .context/ directory.
4
+ *
5
+ * - When contextDir is false, reports "skipped".
6
+ * - If .context/ already exists, reports "done" with "already exists".
7
+ * - Otherwise generates INDEX.md + summary.md via generateContextDir().
8
+ * - Errors are swallowed and reported as status:"error" — never thrown.
9
+ *
10
+ * Extracted VERBATIM from src/commands/init.ts (PR 4 of 6).
11
+ */
12
+ export declare const stepContextDir: StepFn;
13
+ //# sourceMappingURL=context-dir.d.ts.map
@@ -0,0 +1,47 @@
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import { ensureDirExists } from "../../../lib/common.js";
4
+ import { generateContextDir } from "../../../lib/context.js";
5
+ import { report } from "../report.js";
6
+ /**
7
+ * Step 11: Generate .context/ directory.
8
+ *
9
+ * - When contextDir is false, reports "skipped".
10
+ * - If .context/ already exists, reports "done" with "already exists".
11
+ * - Otherwise generates INDEX.md + summary.md via generateContextDir().
12
+ * - Errors are swallowed and reported as status:"error" — never thrown.
13
+ *
14
+ * Extracted VERBATIM from src/commands/init.ts (PR 4 of 6).
15
+ */
16
+ export const stepContextDir = async (ctx) => {
17
+ const { projectDir, dryRun, onStep, options } = ctx;
18
+ const { contextDir } = options;
19
+ const stepId = "context-dir";
20
+ report(onStep, stepId, "Generate .context/ directory", "running");
21
+ try {
22
+ if (contextDir) {
23
+ const contextDirPath = path.join(projectDir, ".context");
24
+ if (await fs.pathExists(contextDirPath)) {
25
+ report(onStep, stepId, "Generate .context/ directory", "done", "already exists");
26
+ }
27
+ else {
28
+ if (!dryRun) {
29
+ const { index, summary } = await generateContextDir(options);
30
+ await ensureDirExists(contextDirPath);
31
+ await fs.writeFile(path.join(contextDirPath, "INDEX.md"), index, "utf-8");
32
+ await fs.writeFile(path.join(contextDirPath, "summary.md"), summary, "utf-8");
33
+ }
34
+ report(onStep, stepId, "Generate .context/ directory", "done", dryRun
35
+ ? "dry-run: would generate .context/"
36
+ : ".context/INDEX.md + summary.md");
37
+ }
38
+ }
39
+ else {
40
+ report(onStep, stepId, "Generate .context/ directory", "skipped", "not selected");
41
+ }
42
+ }
43
+ catch (e) {
44
+ report(onStep, stepId, "Generate .context/ directory", "error", String(e));
45
+ }
46
+ };
47
+ //# sourceMappingURL=context-dir.js.map
@@ -0,0 +1,16 @@
1
+ import type { StepFn } from "../types.js";
2
+ /**
3
+ * Step 13: Scaffold Docker zero-downtime deploy.
4
+ *
5
+ * - When options.dockerDeploy is false, reports "skipped".
6
+ * - Resolves the deploy destination for the configured CI provider; reports
7
+ * "error" when no destination/template exists for that provider.
8
+ * - If the destination file already exists, reports "done" with "already exists".
9
+ * - Otherwise renders the deploy workflow with options.dockerServiceName ?? "app"
10
+ * and writes it (backing up any existing file).
11
+ * - Errors are swallowed and reported as status:"error" — never thrown.
12
+ *
13
+ * Extracted VERBATIM from src/commands/init.ts (PR 4 of 6).
14
+ */
15
+ export declare const stepDockerDeploy: StepFn;
16
+ //# sourceMappingURL=docker-deploy.d.ts.map
@@ -0,0 +1,60 @@
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import { backupIfExists, ensureDirExists } from "../../../lib/common.js";
4
+ import { generateDeployWorkflow, getDeployDestination, } from "../../../lib/template.js";
5
+ import { report } from "../report.js";
6
+ /**
7
+ * Step 13: Scaffold Docker zero-downtime deploy.
8
+ *
9
+ * - When options.dockerDeploy is false, reports "skipped".
10
+ * - Resolves the deploy destination for the configured CI provider; reports
11
+ * "error" when no destination/template exists for that provider.
12
+ * - If the destination file already exists, reports "done" with "already exists".
13
+ * - Otherwise renders the deploy workflow with options.dockerServiceName ?? "app"
14
+ * and writes it (backing up any existing file).
15
+ * - Errors are swallowed and reported as status:"error" — never thrown.
16
+ *
17
+ * Extracted VERBATIM from src/commands/init.ts (PR 4 of 6).
18
+ */
19
+ export const stepDockerDeploy = async (ctx) => {
20
+ const { projectDir, dryRun, onStep, options } = ctx;
21
+ const { ciProvider } = options;
22
+ const stepId = "docker-deploy";
23
+ report(onStep, stepId, "Scaffold Docker zero-downtime deploy", "running");
24
+ try {
25
+ if (options.dockerDeploy) {
26
+ const deployDest = getDeployDestination(ciProvider);
27
+ if (deployDest) {
28
+ const fullDest = path.join(projectDir, deployDest);
29
+ if (await fs.pathExists(fullDest)) {
30
+ report(onStep, stepId, "Scaffold Docker zero-downtime deploy", "done", "already exists");
31
+ }
32
+ else {
33
+ const serviceName = options.dockerServiceName || "app";
34
+ const content = await generateDeployWorkflow(ciProvider, serviceName);
35
+ if (content) {
36
+ if (!dryRun) {
37
+ await backupIfExists(fullDest);
38
+ await ensureDirExists(path.dirname(fullDest));
39
+ await fs.writeFile(fullDest, content, "utf-8");
40
+ }
41
+ report(onStep, stepId, "Scaffold Docker zero-downtime deploy", "done", dryRun ? `dry-run: would create ${deployDest}` : deployDest);
42
+ }
43
+ else {
44
+ report(onStep, stepId, "Scaffold Docker zero-downtime deploy", "error", `no deploy template for ${ciProvider}`);
45
+ }
46
+ }
47
+ }
48
+ else {
49
+ report(onStep, stepId, "Scaffold Docker zero-downtime deploy", "error", `no deploy destination for ${ciProvider}`);
50
+ }
51
+ }
52
+ else {
53
+ report(onStep, stepId, "Scaffold Docker zero-downtime deploy", "skipped", "not selected");
54
+ }
55
+ }
56
+ catch (e) {
57
+ report(onStep, stepId, "Scaffold Docker zero-downtime deploy", "error", String(e));
58
+ }
59
+ };
60
+ //# sourceMappingURL=docker-deploy.js.map
@@ -0,0 +1,15 @@
1
+ import type { StepFn } from "../types.js";
2
+ /**
3
+ * Step 9: Install GHAGGA review system.
4
+ *
5
+ * - When ghagga is false, reports "skipped".
6
+ * - Copies <MODULES_DIR>/ghagga → <project>/.javi-forge/modules/ghagga (no overwrite).
7
+ * - For GitHub provider, also copies the ghagga-review.yml caller workflow into
8
+ * <project>/.github/workflows/.
9
+ * - If module source dir is missing, reports "error" with "module not found".
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 stepGhagga: StepFn;
15
+ //# sourceMappingURL=ghagga.d.ts.map
@@ -0,0 +1,58 @@
1
+ import path from "node:path";
2
+ import fs from "fs-extra";
3
+ import { FORGE_ROOT, MODULES_DIR } from "../../../constants.js";
4
+ import { ensureDirExists } from "../../../lib/common.js";
5
+ import { report } from "../report.js";
6
+ /**
7
+ * Step 9: Install GHAGGA review system.
8
+ *
9
+ * - When ghagga is false, reports "skipped".
10
+ * - Copies <MODULES_DIR>/ghagga → <project>/.javi-forge/modules/ghagga (no overwrite).
11
+ * - For GitHub provider, also copies the ghagga-review.yml caller workflow into
12
+ * <project>/.github/workflows/.
13
+ * - If module source dir is missing, reports "error" with "module not found".
14
+ * - Errors are swallowed and reported as status:"error" — never thrown.
15
+ *
16
+ * Extracted VERBATIM from src/commands/init.ts (PR 3 of 6).
17
+ */
18
+ export const stepGhagga = async (ctx) => {
19
+ const { projectDir, dryRun, onStep, options } = ctx;
20
+ const { ghagga, ciProvider } = options;
21
+ const stepId = "ghagga";
22
+ report(onStep, stepId, "Install GHAGGA review system", "running");
23
+ try {
24
+ if (ghagga) {
25
+ const ghaggaSrc = path.join(MODULES_DIR, "ghagga");
26
+ if (await fs.pathExists(ghaggaSrc)) {
27
+ if (!dryRun) {
28
+ const ghaggaDest = path.join(projectDir, ".javi-forge", "modules", "ghagga");
29
+ await ensureDirExists(ghaggaDest);
30
+ await fs.copy(ghaggaSrc, ghaggaDest, {
31
+ overwrite: false,
32
+ errorOnExist: false,
33
+ });
34
+ // Copy ghagga caller workflow to CI provider location
35
+ if (ciProvider === "github") {
36
+ const workflowSrc = path.join(FORGE_ROOT, "templates", "github", "ghagga-review.yml");
37
+ if (await fs.pathExists(workflowSrc)) {
38
+ const workflowDest = path.join(projectDir, ".github", "workflows", "ghagga-review.yml");
39
+ await ensureDirExists(path.dirname(workflowDest));
40
+ await fs.copy(workflowSrc, workflowDest, { overwrite: false });
41
+ }
42
+ }
43
+ }
44
+ report(onStep, stepId, "Install GHAGGA review system", "done");
45
+ }
46
+ else {
47
+ report(onStep, stepId, "Install GHAGGA review system", "error", "module not found");
48
+ }
49
+ }
50
+ else {
51
+ report(onStep, stepId, "Install GHAGGA review system", "skipped", "not selected");
52
+ }
53
+ }
54
+ catch (e) {
55
+ report(onStep, stepId, "Install GHAGGA review system", "error", String(e));
56
+ }
57
+ };
58
+ //# sourceMappingURL=ghagga.js.map
@@ -0,0 +1,25 @@
1
+ import type { StepFn } from "../types.js";
2
+ /**
3
+ * Step 1: Initialize git repository.
4
+ *
5
+ * - If .git is missing, runs `git init` in the project dir.
6
+ * - If .git already exists, reports "done" with detail "already exists".
7
+ * - In dry-run, skips the actual `git init` call but still reports.
8
+ * - Errors are swallowed and reported as status:"error" — never thrown.
9
+ *
10
+ * Extracted VERBATIM from src/commands/init.ts (PR 1 of 6).
11
+ */
12
+ export declare const stepGitInit: StepFn;
13
+ /**
14
+ * Step 2: Configure git hooks path.
15
+ *
16
+ * - Copies templates/ci-local/ → <project>/ci-local/ (no overwrite).
17
+ * - chmod 0755 on hook files.
18
+ * - Sets git config core.hooksPath to ci-local/hooks.
19
+ * - Skips entirely when CI_LOCAL_DIR template is missing.
20
+ * - Errors are swallowed and reported as status:"error" — never thrown.
21
+ *
22
+ * Extracted VERBATIM from src/commands/init.ts (PR 1 of 6).
23
+ */
24
+ export declare const stepGitHooks: StepFn;
25
+ //# sourceMappingURL=git.d.ts.map