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.
- package/README.md +45 -1
- package/ci-local/README.md +56 -11
- package/ci-local/ci-local.ps1 +445 -0
- package/ci-local/ci-local.sh +52 -9
- package/ci-local/docker/python.Dockerfile +7 -0
- package/ci-local/hooks/commit-msg +120 -44
- package/ci-local/hooks/commit-msg.test.sh +286 -0
- package/ci-local/hooks/pre-commit +9 -1
- package/ci-local/hooks/pre-push +13 -2
- package/ci-local/install.ps1 +367 -0
- package/ci-local/install.sh +151 -5
- package/ci-local/uninstall.ps1 +85 -0
- package/ci-local/uninstall.sh +95 -0
- package/dist/cli/dispatch/ci.d.ts +12 -0
- package/dist/cli/dispatch/ci.js +38 -0
- package/dist/cli/dispatch/security.d.ts +11 -0
- package/dist/cli/dispatch/security.js +68 -0
- package/dist/cli/dispatch/simple-renderers.d.ts +16 -0
- package/dist/cli/dispatch/simple-renderers.js +65 -0
- package/dist/cli/dispatch/skill-publish.d.ts +15 -0
- package/dist/cli/dispatch/skill-publish.js +44 -0
- package/dist/cli/dispatch/skills-cmd.d.ts +13 -0
- package/dist/cli/dispatch/skills-cmd.js +93 -0
- package/dist/cli/dispatch/tdd.d.ts +11 -0
- package/dist/cli/dispatch/tdd.js +45 -0
- package/dist/cli/dispatch/types.d.ts +29 -0
- package/dist/cli/dispatch/types.js +2 -0
- package/dist/cli/dispatch/workflow.d.ts +11 -0
- package/dist/cli/dispatch/workflow.js +67 -0
- package/dist/cli/help.d.ts +127 -0
- package/dist/cli/help.js +138 -0
- package/dist/cli/runtime.d.ts +16 -0
- package/dist/cli/runtime.js +38 -0
- package/dist/cli/validators.d.ts +17 -0
- package/dist/cli/validators.js +35 -0
- package/dist/commands/analyze.d.ts +1 -1
- package/dist/commands/analyze.js +14 -16
- package/dist/commands/ci.d.ts +50 -3
- package/dist/commands/ci.js +537 -182
- package/dist/commands/doctor.d.ts +2 -2
- package/dist/commands/doctor.js +112 -62
- package/dist/commands/init/report.d.ts +13 -0
- package/dist/commands/init/report.js +13 -0
- package/dist/commands/init/steps/agent-skills.d.ts +13 -0
- package/dist/commands/init/steps/agent-skills.js +45 -0
- package/dist/commands/init/steps/ai-sync.d.ts +15 -0
- package/dist/commands/init/steps/ai-sync.js +62 -0
- package/dist/commands/init/steps/ci.d.ts +24 -0
- package/dist/commands/init/steps/ci.js +74 -0
- package/dist/commands/init/steps/claude-md.d.ts +14 -0
- package/dist/commands/init/steps/claude-md.js +54 -0
- package/dist/commands/init/steps/code-graph.d.ts +16 -0
- package/dist/commands/init/steps/code-graph.js +68 -0
- package/dist/commands/init/steps/context-dir.d.ts +13 -0
- package/dist/commands/init/steps/context-dir.js +47 -0
- package/dist/commands/init/steps/docker-deploy.d.ts +16 -0
- package/dist/commands/init/steps/docker-deploy.js +60 -0
- package/dist/commands/init/steps/ghagga.d.ts +15 -0
- package/dist/commands/init/steps/ghagga.js +58 -0
- package/dist/commands/init/steps/git.d.ts +25 -0
- package/dist/commands/init/steps/git.js +81 -0
- package/dist/commands/init/steps/gitignore.d.ts +13 -0
- package/dist/commands/init/steps/gitignore.js +39 -0
- package/dist/commands/init/steps/local-ai.d.ts +14 -0
- package/dist/commands/init/steps/local-ai.js +53 -0
- package/dist/commands/init/steps/manifest.d.ts +13 -0
- package/dist/commands/init/steps/manifest.js +58 -0
- package/dist/commands/init/steps/memory.d.ts +15 -0
- package/dist/commands/init/steps/memory.js +60 -0
- package/dist/commands/init/steps/mock.d.ts +13 -0
- package/dist/commands/init/steps/mock.js +64 -0
- package/dist/commands/init/steps/sdd.d.ts +12 -0
- package/dist/commands/init/steps/sdd.js +40 -0
- package/dist/commands/init/steps/security.d.ts +28 -0
- package/dist/commands/init/steps/security.js +103 -0
- package/dist/commands/init/types.d.ts +30 -0
- package/dist/commands/init/types.js +2 -0
- package/dist/commands/init.d.ts +5 -4
- package/dist/commands/init.js +42 -387
- package/dist/commands/llmstxt.d.ts +1 -1
- package/dist/commands/llmstxt.js +36 -34
- package/dist/commands/plugin.d.ts +10 -1
- package/dist/commands/plugin.js +92 -47
- package/dist/commands/security.d.ts +11 -5
- package/dist/commands/security.js +236 -77
- package/dist/commands/skills/analysis.d.ts +19 -0
- package/dist/commands/skills/analysis.js +211 -0
- package/dist/commands/skills/benchmark.d.ts +6 -0
- package/dist/commands/skills/benchmark.js +82 -0
- package/dist/commands/skills/constants.d.ts +10 -0
- package/dist/commands/skills/constants.js +27 -0
- package/dist/commands/skills/directives.d.ts +21 -0
- package/dist/commands/skills/directives.js +101 -0
- package/dist/commands/skills/parsing.d.ts +16 -0
- package/dist/commands/skills/parsing.js +108 -0
- package/dist/commands/skills/rules.d.ts +5 -0
- package/dist/commands/skills/rules.js +32 -0
- package/dist/commands/skills/scoring.d.ts +47 -0
- package/dist/commands/skills/scoring.js +306 -0
- package/dist/commands/skills.d.ts +8 -69
- package/dist/commands/skills.js +9 -490
- package/dist/commands/tdd-pipeline.d.ts +17 -0
- package/dist/commands/tdd-pipeline.js +144 -0
- package/dist/commands/tdd.d.ts +1 -1
- package/dist/commands/tdd.js +21 -18
- package/dist/commands/workflow.d.ts +23 -0
- package/dist/commands/workflow.js +116 -0
- package/dist/constants.d.ts +15 -1
- package/dist/constants.js +161 -122
- package/dist/index.js +43 -280
- package/dist/lib/agent-skills.d.ts +36 -1
- package/dist/lib/agent-skills.js +168 -19
- package/dist/lib/atlassian-mcp.d.ts +42 -0
- package/dist/lib/atlassian-mcp.js +98 -0
- package/dist/lib/auto-skill-install.d.ts +37 -0
- package/dist/lib/auto-skill-install.js +91 -0
- package/dist/lib/auto-wire.d.ts +20 -0
- package/dist/lib/auto-wire.js +240 -0
- package/dist/lib/ci-config.d.ts +65 -0
- package/dist/lib/ci-config.js +297 -0
- package/dist/lib/claudemd.d.ts +13 -1
- package/dist/lib/claudemd.js +174 -24
- package/dist/lib/codex-export.d.ts +1 -1
- package/dist/lib/codex-export.js +26 -32
- package/dist/lib/common.d.ts +1 -1
- package/dist/lib/common.js +52 -44
- package/dist/lib/context.d.ts +17 -2
- package/dist/lib/context.js +142 -13
- package/dist/lib/crash-recovery.d.ts +34 -0
- package/dist/lib/crash-recovery.js +123 -0
- package/dist/lib/docker.d.ts +23 -2
- package/dist/lib/docker.js +168 -131
- package/dist/lib/exec.d.ts +10 -0
- package/dist/lib/exec.js +11 -0
- package/dist/lib/frontmatter.d.ts +1 -1
- package/dist/lib/frontmatter.js +29 -15
- package/dist/lib/harness-audit.d.ts +35 -0
- package/dist/lib/harness-audit.js +277 -0
- package/dist/lib/parallel-batch.d.ts +42 -0
- package/dist/lib/parallel-batch.js +88 -0
- package/dist/lib/plugin.d.ts +9 -3
- package/dist/lib/plugin.js +127 -70
- package/dist/lib/secret-scanner.d.ts +30 -0
- package/dist/lib/secret-scanner.js +274 -0
- package/dist/lib/security-analysis.d.ts +74 -0
- package/dist/lib/security-analysis.js +489 -0
- package/dist/lib/skill-publish.d.ts +40 -0
- package/dist/lib/skill-publish.js +164 -0
- package/dist/lib/skill-scanner.d.ts +63 -0
- package/dist/lib/skill-scanner.js +383 -0
- package/dist/lib/stack-detector.d.ts +38 -0
- package/dist/lib/stack-detector.js +207 -0
- package/dist/lib/supply-chain.d.ts +23 -0
- package/dist/lib/supply-chain.js +126 -0
- package/dist/lib/team-presets.d.ts +53 -0
- package/dist/lib/team-presets.js +201 -0
- package/dist/lib/template.d.ts +16 -1
- package/dist/lib/template.js +46 -17
- package/dist/lib/workflow/discovery.d.ts +27 -0
- package/dist/lib/workflow/discovery.js +85 -0
- package/dist/lib/workflow/index.d.ts +5 -0
- package/dist/lib/workflow/index.js +5 -0
- package/dist/lib/workflow/parser.d.ts +16 -0
- package/dist/lib/workflow/parser.js +198 -0
- package/dist/lib/workflow/renderer.d.ts +9 -0
- package/dist/lib/workflow/renderer.js +152 -0
- package/dist/lib/workflow/validator.d.ts +10 -0
- package/dist/lib/workflow/validator.js +189 -0
- package/dist/tasks/index.d.ts +4 -0
- package/dist/tasks/index.js +4 -0
- package/dist/tasks/scaffold-tasks.d.ts +3 -0
- package/dist/tasks/scaffold-tasks.js +14 -0
- package/dist/tasks/task-id.d.ts +30 -0
- package/dist/tasks/task-id.js +59 -0
- package/dist/tasks/task-tracker.d.ts +15 -0
- package/dist/tasks/task-tracker.js +81 -0
- package/dist/types/index.d.ts +134 -6
- package/dist/types/index.js +11 -1
- package/dist/ui/AnalyzeUI.d.ts +1 -1
- package/dist/ui/AnalyzeUI.js +38 -39
- package/dist/ui/App.d.ts +5 -3
- package/dist/ui/App.js +86 -46
- package/dist/ui/AutoSkills.d.ts +9 -0
- package/dist/ui/AutoSkills.js +124 -0
- package/dist/ui/CI.d.ts +2 -2
- package/dist/ui/CI.js +24 -26
- package/dist/ui/CIContext.d.ts +1 -1
- package/dist/ui/CIContext.js +2 -2
- package/dist/ui/CISelector.d.ts +2 -2
- package/dist/ui/CISelector.js +23 -15
- package/dist/ui/Doctor.d.ts +1 -1
- package/dist/ui/Doctor.js +35 -29
- package/dist/ui/Header.d.ts +1 -1
- package/dist/ui/Header.js +14 -14
- package/dist/ui/HookProfileSelector.d.ts +9 -0
- package/dist/ui/HookProfileSelector.js +54 -0
- package/dist/ui/LlmsTxt.d.ts +1 -1
- package/dist/ui/LlmsTxt.js +31 -22
- package/dist/ui/MemorySelector.d.ts +2 -2
- package/dist/ui/MemorySelector.js +28 -16
- package/dist/ui/NameInput.d.ts +1 -1
- package/dist/ui/NameInput.js +21 -21
- package/dist/ui/OptionSelector.d.ts +6 -2
- package/dist/ui/OptionSelector.js +83 -32
- package/dist/ui/Plugin.d.ts +4 -3
- package/dist/ui/Plugin.js +78 -35
- package/dist/ui/Progress.d.ts +3 -3
- package/dist/ui/Progress.js +23 -22
- package/dist/ui/Skills.d.ts +2 -2
- package/dist/ui/Skills.js +61 -32
- package/dist/ui/StackSelector.d.ts +2 -2
- package/dist/ui/StackSelector.js +27 -17
- package/dist/ui/Summary.d.ts +3 -3
- package/dist/ui/Summary.js +60 -50
- package/dist/ui/Welcome.d.ts +1 -1
- package/dist/ui/Welcome.js +15 -16
- package/dist/ui/theme.d.ts +1 -1
- package/dist/ui/theme.js +6 -6
- package/lib/common.psm1 +167 -0
- package/lib/common.sh +30 -0
- package/package.json +46 -24
- package/templates/common/atlassian/mcp-atlassian-snippet.json +16 -0
- package/templates/common/repoforge/mcp-repoforge-snippet.json +11 -0
- package/templates/common/repoforge/repoforge.yaml +34 -0
- package/templates/github/deploy-docker-zero-downtime.yml +140 -0
- package/templates/github/repoforge-graph.yml +45 -0
- package/templates/gitlab/deploy-docker-zero-downtime.yml +57 -0
- package/templates/local-ai/.env.example +17 -0
- package/templates/local-ai/docker-compose.yml +95 -0
- package/templates/security-hooks/claude-settings-security.json +30 -0
- package/templates/security-hooks/commit-msg-signing +29 -0
- package/templates/security-hooks/pre-commit-permissions +74 -0
- package/templates/security-hooks/pre-commit-secrets +74 -0
- package/templates/security-hooks/pre-push-branch-protection +62 -0
- package/templates/security-hooks/pre-push-deps +83 -0
- package/templates/security-hooks/pre-push-signing +67 -0
- package/templates/woodpecker/deploy-docker-zero-downtime.yml +50 -0
- package/templates/workflows/ci-pipeline.dot +15 -0
- package/templates/workflows/feature-flow.dot +21 -0
- package/templates/workflows/release.dot +16 -0
- package/dist/__integration__/helpers.d.ts +0 -20
- package/dist/__integration__/helpers.d.ts.map +0 -1
- package/dist/__integration__/helpers.js +0 -31
- package/dist/__integration__/helpers.js.map +0 -1
- package/dist/commands/analyze.d.ts.map +0 -1
- package/dist/commands/analyze.js.map +0 -1
- package/dist/commands/ci.d.ts.map +0 -1
- package/dist/commands/ci.js.map +0 -1
- package/dist/commands/doctor.d.ts.map +0 -1
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/llmstxt.d.ts.map +0 -1
- package/dist/commands/llmstxt.js.map +0 -1
- package/dist/commands/plugin.d.ts.map +0 -1
- package/dist/commands/plugin.js.map +0 -1
- package/dist/commands/security.d.ts.map +0 -1
- package/dist/commands/security.js.map +0 -1
- package/dist/commands/skills.d.ts.map +0 -1
- package/dist/commands/skills.js.map +0 -1
- package/dist/commands/tdd.d.ts.map +0 -1
- package/dist/commands/tdd.js.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/agent-skills.d.ts.map +0 -1
- package/dist/lib/agent-skills.js.map +0 -1
- package/dist/lib/claudemd.d.ts.map +0 -1
- package/dist/lib/claudemd.js.map +0 -1
- package/dist/lib/codex-export.d.ts.map +0 -1
- package/dist/lib/codex-export.js.map +0 -1
- package/dist/lib/common.d.ts.map +0 -1
- package/dist/lib/common.js.map +0 -1
- package/dist/lib/context.d.ts.map +0 -1
- package/dist/lib/context.js.map +0 -1
- package/dist/lib/docker.d.ts.map +0 -1
- package/dist/lib/docker.js.map +0 -1
- package/dist/lib/frontmatter.d.ts.map +0 -1
- package/dist/lib/frontmatter.js.map +0 -1
- package/dist/lib/plugin.d.ts.map +0 -1
- package/dist/lib/plugin.js.map +0 -1
- package/dist/lib/template.d.ts.map +0 -1
- package/dist/lib/template.js.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/ui/AnalyzeUI.d.ts.map +0 -1
- package/dist/ui/AnalyzeUI.js.map +0 -1
- package/dist/ui/App.d.ts.map +0 -1
- package/dist/ui/App.js.map +0 -1
- package/dist/ui/CI.d.ts.map +0 -1
- package/dist/ui/CI.js.map +0 -1
- package/dist/ui/CIContext.d.ts.map +0 -1
- package/dist/ui/CIContext.js.map +0 -1
- package/dist/ui/CISelector.d.ts.map +0 -1
- package/dist/ui/CISelector.js.map +0 -1
- package/dist/ui/Doctor.d.ts.map +0 -1
- package/dist/ui/Doctor.js.map +0 -1
- package/dist/ui/Header.d.ts.map +0 -1
- package/dist/ui/Header.js.map +0 -1
- package/dist/ui/LlmsTxt.d.ts.map +0 -1
- package/dist/ui/LlmsTxt.js.map +0 -1
- package/dist/ui/MemorySelector.d.ts.map +0 -1
- package/dist/ui/MemorySelector.js.map +0 -1
- package/dist/ui/NameInput.d.ts.map +0 -1
- package/dist/ui/NameInput.js.map +0 -1
- package/dist/ui/OptionSelector.d.ts.map +0 -1
- package/dist/ui/OptionSelector.js.map +0 -1
- package/dist/ui/Plugin.d.ts.map +0 -1
- package/dist/ui/Plugin.js.map +0 -1
- package/dist/ui/Progress.d.ts.map +0 -1
- package/dist/ui/Progress.js.map +0 -1
- package/dist/ui/Skills.d.ts.map +0 -1
- package/dist/ui/Skills.js.map +0 -1
- package/dist/ui/StackSelector.d.ts.map +0 -1
- package/dist/ui/StackSelector.js.map +0 -1
- package/dist/ui/Summary.d.ts.map +0 -1
- package/dist/ui/Summary.js.map +0 -1
- package/dist/ui/Welcome.d.ts.map +0 -1
- package/dist/ui/Welcome.js.map +0 -1
- package/dist/ui/theme.d.ts.map +0 -1
- package/dist/ui/theme.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { DoctorResult } from
|
|
2
|
-
export type CheckStatus =
|
|
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
|
*/
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
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(
|
|
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,
|
|
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(
|
|
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:
|
|
48
|
-
{ name:
|
|
49
|
-
{ name:
|
|
50
|
-
{ name:
|
|
51
|
-
{ name:
|
|
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, [
|
|
60
|
-
version = stdout.trim().split(
|
|
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:
|
|
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 ===
|
|
73
|
-
detail:
|
|
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:
|
|
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:
|
|
82
|
-
{ path: MODULES_DIR, label:
|
|
83
|
-
{ path: path.join(FORGE_ROOT,
|
|
84
|
-
{ path: path.join(FORGE_ROOT,
|
|
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({
|
|
90
|
+
structureChecks.push({
|
|
91
|
+
label: dir.label,
|
|
92
|
+
status: "ok",
|
|
93
|
+
detail: `${count} entries`,
|
|
94
|
+
});
|
|
90
95
|
}
|
|
91
96
|
else {
|
|
92
|
-
structureChecks.push({
|
|
97
|
+
structureChecks.push({
|
|
98
|
+
label: dir.label,
|
|
99
|
+
status: "fail",
|
|
100
|
+
detail: "missing",
|
|
101
|
+
});
|
|
93
102
|
}
|
|
94
103
|
}
|
|
95
|
-
sections.push({ title:
|
|
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:
|
|
102
|
-
status:
|
|
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:
|
|
109
|
-
status:
|
|
110
|
-
detail:
|
|
117
|
+
label: "Detected stack",
|
|
118
|
+
status: "skip",
|
|
119
|
+
detail: "no recognizable project files in current directory",
|
|
111
120
|
});
|
|
112
121
|
}
|
|
113
|
-
sections.push({ title:
|
|
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:
|
|
120
|
-
status:
|
|
128
|
+
label: "Forge manifest",
|
|
129
|
+
status: "ok",
|
|
121
130
|
detail: `project: ${manifest.projectName}, stack: ${manifest.stack}`,
|
|
122
131
|
});
|
|
123
132
|
manifestChecks.push({
|
|
124
|
-
label:
|
|
125
|
-
status:
|
|
126
|
-
detail: manifest.createdAt.split(
|
|
133
|
+
label: "Created",
|
|
134
|
+
status: "ok",
|
|
135
|
+
detail: manifest.createdAt.split("T")[0],
|
|
127
136
|
});
|
|
128
137
|
manifestChecks.push({
|
|
129
|
-
label:
|
|
130
|
-
status: manifest.modules.length > 0 ?
|
|
131
|
-
detail: manifest.modules.length > 0
|
|
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:
|
|
137
|
-
status:
|
|
138
|
-
detail:
|
|
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:
|
|
152
|
+
sections.push({ title: "Project Manifest", checks: manifestChecks });
|
|
142
153
|
// ── 5. Installed Modules ───────────────────────────────────────────────────
|
|
143
154
|
const moduleChecks = [];
|
|
144
|
-
const moduleNames = [
|
|
155
|
+
const moduleNames = ["engram", "obsidian-brain", "memory-simple", "ghagga"];
|
|
145
156
|
for (const mod of moduleNames) {
|
|
146
|
-
const modPath = path.join(cwd,
|
|
157
|
+
const modPath = path.join(cwd, ".javi-forge", "modules", mod);
|
|
147
158
|
if (await fs.pathExists(modPath)) {
|
|
148
|
-
moduleChecks.push({ label: mod, status:
|
|
159
|
+
moduleChecks.push({ label: mod, status: "ok", detail: "installed" });
|
|
149
160
|
}
|
|
150
161
|
else {
|
|
151
|
-
moduleChecks.push({
|
|
162
|
+
moduleChecks.push({
|
|
163
|
+
label: mod,
|
|
164
|
+
status: "skip",
|
|
165
|
+
detail: "not installed",
|
|
166
|
+
});
|
|
152
167
|
}
|
|
153
168
|
}
|
|
154
|
-
sections.push({ title:
|
|
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:
|
|
179
|
+
status: "ok",
|
|
165
180
|
detail: `v${plugin.version} from ${plugin.source}`,
|
|
166
181
|
});
|
|
167
182
|
}
|
|
168
183
|
}
|
|
169
184
|
else {
|
|
170
|
-
pluginChecks.push({
|
|
185
|
+
pluginChecks.push({
|
|
186
|
+
label: "Plugins",
|
|
187
|
+
status: "skip",
|
|
188
|
+
detail: "none installed",
|
|
189
|
+
});
|
|
171
190
|
}
|
|
172
191
|
}
|
|
173
192
|
else {
|
|
174
|
-
pluginChecks.push({
|
|
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:
|
|
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
|