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
package/dist/lib/codex-export.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import { parseFrontmatter } from
|
|
5
|
-
const DEFAULT_MODEL =
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import { PLUGIN_MANIFEST_FILE, PLUGINS_DIR } from "../constants.js";
|
|
4
|
+
import { parseFrontmatter } from "./frontmatter.js";
|
|
5
|
+
const DEFAULT_MODEL = "o4-mini";
|
|
6
6
|
// ── Conversion ─────────────────────────────────────────────────────────────
|
|
7
7
|
/**
|
|
8
8
|
* Convert a SKILL.md raw content string into a CodexTomlEntry.
|
|
@@ -12,15 +12,11 @@ export function skillToCodexToml(raw) {
|
|
|
12
12
|
const parsed = parseFrontmatter(raw);
|
|
13
13
|
if (!parsed)
|
|
14
14
|
return null;
|
|
15
|
-
const name = parsed.data
|
|
16
|
-
if (typeof name !==
|
|
15
|
+
const name = parsed.data.name;
|
|
16
|
+
if (typeof name !== "string" || !name)
|
|
17
17
|
return null;
|
|
18
|
-
const description = typeof parsed.data
|
|
19
|
-
|
|
20
|
-
: '';
|
|
21
|
-
const model = typeof parsed.data['model'] === 'string'
|
|
22
|
-
? parsed.data['model']
|
|
23
|
-
: DEFAULT_MODEL;
|
|
18
|
+
const description = typeof parsed.data.description === "string" ? parsed.data.description : "";
|
|
19
|
+
const model = typeof parsed.data.model === "string" ? parsed.data.model : DEFAULT_MODEL;
|
|
24
20
|
const instructions = description
|
|
25
21
|
? `${description}\n\n${parsed.content}`.trim()
|
|
26
22
|
: parsed.content.trim();
|
|
@@ -39,8 +35,8 @@ export function serializeToml(entry) {
|
|
|
39
35
|
`instructions = """`,
|
|
40
36
|
escapedInstructions,
|
|
41
37
|
`"""`,
|
|
42
|
-
|
|
43
|
-
].join(
|
|
38
|
+
"",
|
|
39
|
+
].join("\n");
|
|
44
40
|
}
|
|
45
41
|
// ── File I/O ───────────────────────────────────────────────────────────────
|
|
46
42
|
/**
|
|
@@ -49,35 +45,35 @@ export function serializeToml(entry) {
|
|
|
49
45
|
*/
|
|
50
46
|
export async function exportPluginAsCodexToml(name) {
|
|
51
47
|
const pluginDir = path.join(PLUGINS_DIR, name);
|
|
52
|
-
if (!await fs.pathExists(pluginDir)) {
|
|
48
|
+
if (!(await fs.pathExists(pluginDir))) {
|
|
53
49
|
return { success: false, error: `plugin "${name}" is not installed` };
|
|
54
50
|
}
|
|
55
51
|
// Read plugin manifest for skill list
|
|
56
52
|
const manifestPath = path.join(pluginDir, PLUGIN_MANIFEST_FILE);
|
|
57
|
-
if (!await fs.pathExists(manifestPath)) {
|
|
58
|
-
return { success: false, error:
|
|
53
|
+
if (!(await fs.pathExists(manifestPath))) {
|
|
54
|
+
return { success: false, error: "plugin.json not found" };
|
|
59
55
|
}
|
|
60
56
|
let manifest;
|
|
61
57
|
try {
|
|
62
|
-
manifest = await fs.readJson(manifestPath);
|
|
58
|
+
manifest = (await fs.readJson(manifestPath));
|
|
63
59
|
}
|
|
64
60
|
catch {
|
|
65
|
-
return { success: false, error:
|
|
61
|
+
return { success: false, error: "invalid plugin.json" };
|
|
66
62
|
}
|
|
67
63
|
const skillNames = manifest.skills ?? [];
|
|
68
64
|
if (skillNames.length === 0) {
|
|
69
|
-
return { success: false, error:
|
|
65
|
+
return { success: false, error: "plugin has no skills to export" };
|
|
70
66
|
}
|
|
71
|
-
const codexDir = path.join(pluginDir,
|
|
67
|
+
const codexDir = path.join(pluginDir, "codex");
|
|
72
68
|
await fs.ensureDir(codexDir);
|
|
73
69
|
const writtenFiles = [];
|
|
74
70
|
for (const skillName of skillNames) {
|
|
75
|
-
const skillPath = path.join(pluginDir,
|
|
76
|
-
if (!await fs.pathExists(skillPath))
|
|
71
|
+
const skillPath = path.join(pluginDir, "skills", skillName, "SKILL.md");
|
|
72
|
+
if (!(await fs.pathExists(skillPath)))
|
|
77
73
|
continue;
|
|
78
74
|
let raw;
|
|
79
75
|
try {
|
|
80
|
-
raw = await fs.readFile(skillPath,
|
|
76
|
+
raw = await fs.readFile(skillPath, "utf-8");
|
|
81
77
|
}
|
|
82
78
|
catch {
|
|
83
79
|
continue;
|
|
@@ -87,25 +83,23 @@ export async function exportPluginAsCodexToml(name) {
|
|
|
87
83
|
continue;
|
|
88
84
|
const toml = serializeToml(entry);
|
|
89
85
|
const outPath = path.join(codexDir, `${skillName}.toml`);
|
|
90
|
-
await fs.writeFile(outPath, toml,
|
|
86
|
+
await fs.writeFile(outPath, toml, "utf-8");
|
|
91
87
|
writtenFiles.push(outPath);
|
|
92
88
|
}
|
|
93
89
|
if (writtenFiles.length === 0) {
|
|
94
|
-
return { success: false, error:
|
|
90
|
+
return { success: false, error: "no skills with valid frontmatter found" };
|
|
95
91
|
}
|
|
96
92
|
return { success: true, files: writtenFiles };
|
|
97
93
|
}
|
|
98
94
|
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
99
95
|
function escapeTomlString(value) {
|
|
100
96
|
return value
|
|
101
|
-
.replace(/\\/g,
|
|
97
|
+
.replace(/\\/g, "\\\\")
|
|
102
98
|
.replace(/"/g, '\\"')
|
|
103
|
-
.replace(/\n/g,
|
|
99
|
+
.replace(/\n/g, "\\n");
|
|
104
100
|
}
|
|
105
101
|
function escapeTomlMultiline(value) {
|
|
106
102
|
// In TOML multiline basic strings ("""), only backslashes and triple quotes need escaping
|
|
107
|
-
return value
|
|
108
|
-
.replace(/\\/g, '\\\\')
|
|
109
|
-
.replace(/"""/g, '"\\"\"');
|
|
103
|
+
return value.replace(/\\/g, "\\\\").replace(/"""/g, '"\\""');
|
|
110
104
|
}
|
|
111
105
|
//# sourceMappingURL=codex-export.js.map
|
package/dist/lib/common.d.ts
CHANGED
package/dist/lib/common.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
3
|
/**
|
|
4
4
|
* Detect the project stack by looking for well-known build/config files.
|
|
5
5
|
* Returns the first match (precedence order matters).
|
|
@@ -7,70 +7,78 @@ import path from 'path';
|
|
|
7
7
|
export async function detectStack(projectDir) {
|
|
8
8
|
const exists = async (file) => fs.pathExists(path.join(projectDir, file));
|
|
9
9
|
// Java — Gradle
|
|
10
|
-
if (await exists(
|
|
10
|
+
if ((await exists("build.gradle")) || (await exists("build.gradle.kts"))) {
|
|
11
11
|
const javaVersion = await detectJavaVersion(projectDir);
|
|
12
|
-
return { stackType:
|
|
12
|
+
return { stackType: "java-gradle", buildTool: "gradle", javaVersion };
|
|
13
13
|
}
|
|
14
14
|
// Java — Maven
|
|
15
|
-
if (await exists(
|
|
15
|
+
if (await exists("pom.xml")) {
|
|
16
16
|
const javaVersion = await detectJavaVersion(projectDir);
|
|
17
|
-
return { stackType:
|
|
17
|
+
return { stackType: "java-maven", buildTool: "maven", javaVersion };
|
|
18
18
|
}
|
|
19
19
|
// Node.js
|
|
20
|
-
if (await exists(
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
if (await exists("package.json")) {
|
|
21
|
+
const _pkg = await fs
|
|
22
|
+
.readJson(path.join(projectDir, "package.json"))
|
|
23
|
+
.catch(() => ({}));
|
|
24
|
+
const buildTool = (await exists("pnpm-lock.yaml"))
|
|
25
|
+
? "pnpm"
|
|
26
|
+
: (await exists("yarn.lock"))
|
|
27
|
+
? "yarn"
|
|
28
|
+
: "npm";
|
|
29
|
+
return { stackType: "node", buildTool };
|
|
26
30
|
}
|
|
27
31
|
// Python
|
|
28
|
-
if (await exists(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
if ((await exists("pyproject.toml")) ||
|
|
33
|
+
(await exists("requirements.txt")) ||
|
|
34
|
+
(await exists("setup.py"))) {
|
|
35
|
+
const buildTool = (await exists("pyproject.toml"))
|
|
36
|
+
? "pyproject"
|
|
37
|
+
: (await exists("Pipfile"))
|
|
38
|
+
? "pipenv"
|
|
39
|
+
: "pip";
|
|
40
|
+
return { stackType: "python", buildTool };
|
|
33
41
|
}
|
|
34
42
|
// Go
|
|
35
|
-
if (await exists(
|
|
36
|
-
return { stackType:
|
|
43
|
+
if (await exists("go.mod")) {
|
|
44
|
+
return { stackType: "go", buildTool: "go" };
|
|
37
45
|
}
|
|
38
46
|
// Rust
|
|
39
|
-
if (await exists(
|
|
40
|
-
return { stackType:
|
|
47
|
+
if (await exists("Cargo.toml")) {
|
|
48
|
+
return { stackType: "rust", buildTool: "cargo" };
|
|
41
49
|
}
|
|
42
50
|
// Elixir
|
|
43
|
-
if (await exists(
|
|
44
|
-
return { stackType:
|
|
51
|
+
if (await exists("mix.exs")) {
|
|
52
|
+
return { stackType: "elixir", buildTool: "mix" };
|
|
45
53
|
}
|
|
46
54
|
return null;
|
|
47
55
|
}
|
|
48
56
|
/** Try to detect Java version from gradle or maven config */
|
|
49
57
|
async function detectJavaVersion(projectDir) {
|
|
50
58
|
// Try build.gradle
|
|
51
|
-
const gradleFile = path.join(projectDir,
|
|
59
|
+
const gradleFile = path.join(projectDir, "build.gradle");
|
|
52
60
|
if (await fs.pathExists(gradleFile)) {
|
|
53
|
-
const content = await fs.readFile(gradleFile,
|
|
54
|
-
const match = content.match(/sourceCompatibility\s*=\s*['"]?(\d+)/)
|
|
55
|
-
|
|
61
|
+
const content = await fs.readFile(gradleFile, "utf-8");
|
|
62
|
+
const match = content.match(/sourceCompatibility\s*=\s*['"]?(\d+)/) ||
|
|
63
|
+
content.match(/JavaVersion\.VERSION_(\d+)/);
|
|
56
64
|
if (match)
|
|
57
65
|
return match[1];
|
|
58
66
|
}
|
|
59
67
|
// Try build.gradle.kts
|
|
60
|
-
const ktsFile = path.join(projectDir,
|
|
68
|
+
const ktsFile = path.join(projectDir, "build.gradle.kts");
|
|
61
69
|
if (await fs.pathExists(ktsFile)) {
|
|
62
|
-
const content = await fs.readFile(ktsFile,
|
|
63
|
-
const match = content.match(/jvmTarget\s*=\s*['"](\d+)['"]/)
|
|
64
|
-
|
|
70
|
+
const content = await fs.readFile(ktsFile, "utf-8");
|
|
71
|
+
const match = content.match(/jvmTarget\s*=\s*['"](\d+)['"]/) ||
|
|
72
|
+
content.match(/JavaVersion\.VERSION_(\d+)/);
|
|
65
73
|
if (match)
|
|
66
74
|
return match[1];
|
|
67
75
|
}
|
|
68
76
|
// Try pom.xml
|
|
69
|
-
const pomFile = path.join(projectDir,
|
|
77
|
+
const pomFile = path.join(projectDir, "pom.xml");
|
|
70
78
|
if (await fs.pathExists(pomFile)) {
|
|
71
|
-
const content = await fs.readFile(pomFile,
|
|
72
|
-
const match = content.match(/<java\.version>(\d+)</)
|
|
73
|
-
|
|
79
|
+
const content = await fs.readFile(pomFile, "utf-8");
|
|
80
|
+
const match = content.match(/<java\.version>(\d+)</) ||
|
|
81
|
+
content.match(/<maven\.compiler\.source>(\d+)</);
|
|
74
82
|
if (match)
|
|
75
83
|
return match[1];
|
|
76
84
|
}
|
|
@@ -90,22 +98,22 @@ export async function ensureDirExists(dirPath) {
|
|
|
90
98
|
}
|
|
91
99
|
/** Check if a directory is a git repository */
|
|
92
100
|
export async function isGitRepo(dir) {
|
|
93
|
-
return fs.pathExists(path.join(dir,
|
|
101
|
+
return fs.pathExists(path.join(dir, ".git"));
|
|
94
102
|
}
|
|
95
103
|
/** Resolve the forge assets root (the package root directory) */
|
|
96
104
|
export function getForgeRoot() {
|
|
97
105
|
// When running from dist/, go up one level
|
|
98
106
|
const thisDir = path.dirname(new URL(import.meta.url).pathname);
|
|
99
|
-
return path.resolve(thisDir,
|
|
107
|
+
return path.resolve(thisDir, "..");
|
|
100
108
|
}
|
|
101
109
|
/** Stack display names */
|
|
102
110
|
export const STACK_LABELS = {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
111
|
+
node: "Node.js / TypeScript",
|
|
112
|
+
python: "Python",
|
|
113
|
+
go: "Go",
|
|
114
|
+
rust: "Rust",
|
|
115
|
+
"java-gradle": "Java (Gradle)",
|
|
116
|
+
"java-maven": "Java (Maven)",
|
|
117
|
+
elixir: "Elixir",
|
|
110
118
|
};
|
|
111
119
|
//# sourceMappingURL=common.js.map
|
package/dist/lib/context.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import type { InitOptions, StackContextEntry } from
|
|
1
|
+
import type { InitOptions, StackContextEntry } from "../types/index.js";
|
|
2
2
|
export declare function buildIndexMd(projectName: string, stackCtx: StackContextEntry, ciProvider: string, memory: string): string;
|
|
3
|
-
export declare function buildSummaryMd(projectName: string, stack: string, ciProvider: string, memory: string, modules: string[]): string;
|
|
3
|
+
export declare function buildSummaryMd(projectName: string, stack: string, ciProvider: string, memory: string, modules: string[], dependencies?: string[]): string;
|
|
4
|
+
/**
|
|
5
|
+
* Detect top-level dependencies from project manifest files.
|
|
6
|
+
* Returns up to 10 dependency names (key deps only, not devDeps).
|
|
7
|
+
*/
|
|
8
|
+
export declare function detectDependencies(projectDir: string, stack: string): Promise<string[]>;
|
|
4
9
|
/**
|
|
5
10
|
* Generate .context/ directory content from InitOptions metadata.
|
|
6
11
|
* Pure function — does NOT perform filesystem I/O.
|
|
@@ -9,4 +14,14 @@ export declare function generateContextDir(options: InitOptions): Promise<{
|
|
|
9
14
|
index: string;
|
|
10
15
|
summary: string;
|
|
11
16
|
}>;
|
|
17
|
+
/**
|
|
18
|
+
* Refresh .context/ directory from the forge manifest and live project state.
|
|
19
|
+
* Reads manifest, detects current dependencies, regenerates INDEX.md + summary.md.
|
|
20
|
+
* Returns null if the project is not forge-managed or has no .context/ dir.
|
|
21
|
+
*/
|
|
22
|
+
export declare function refreshContextDir(projectDir: string): Promise<{
|
|
23
|
+
index: string;
|
|
24
|
+
summary: string;
|
|
25
|
+
updated: boolean;
|
|
26
|
+
} | null>;
|
|
12
27
|
//# sourceMappingURL=context.d.ts.map
|
package/dist/lib/context.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import { STACK_CONTEXT_MAP } from "../constants.js";
|
|
2
4
|
// =============================================================================
|
|
3
5
|
// Internal helpers
|
|
4
6
|
// =============================================================================
|
|
5
7
|
function getStackContext(stack) {
|
|
6
|
-
return STACK_CONTEXT_MAP[stack] ?? STACK_CONTEXT_MAP
|
|
8
|
+
return STACK_CONTEXT_MAP[stack] ?? STACK_CONTEXT_MAP.default;
|
|
7
9
|
}
|
|
8
10
|
export function buildIndexMd(projectName, stackCtx, ciProvider, memory) {
|
|
9
|
-
return `# ${projectName} —
|
|
11
|
+
return `# ${projectName} — Project Index
|
|
10
12
|
|
|
11
|
-
##
|
|
13
|
+
## Structure
|
|
12
14
|
|
|
13
15
|
\`\`\`
|
|
14
16
|
${stackCtx.tree}
|
|
@@ -20,13 +22,14 @@ ${stackCtx.tree}
|
|
|
20
22
|
|
|
21
23
|
## Conventions
|
|
22
24
|
|
|
23
|
-
- **Stack
|
|
25
|
+
- **Stack**: ${stackCtx.conventions}
|
|
24
26
|
- **CI**: ${ciProvider}
|
|
25
27
|
- **Memory**: ${memory}
|
|
26
28
|
`;
|
|
27
29
|
}
|
|
28
|
-
export function buildSummaryMd(projectName, stack, ciProvider, memory, modules) {
|
|
29
|
-
const modulesList = modules.length > 0 ? modules.join(
|
|
30
|
+
export function buildSummaryMd(projectName, stack, ciProvider, memory, modules, dependencies = []) {
|
|
31
|
+
const modulesList = modules.length > 0 ? modules.join(", ") : "none";
|
|
32
|
+
const depsList = dependencies.length > 0 ? dependencies.join(", ") : "none detected";
|
|
30
33
|
return `# ${projectName}
|
|
31
34
|
|
|
32
35
|
## Overview
|
|
@@ -35,10 +38,11 @@ ${stack}-based project scaffolded with javi-forge.
|
|
|
35
38
|
|
|
36
39
|
## Stack
|
|
37
40
|
|
|
38
|
-
- **
|
|
41
|
+
- **Runtime**: ${stack}
|
|
39
42
|
- **CI**: ${ciProvider}
|
|
40
43
|
- **Memory**: ${memory}
|
|
41
44
|
- **Modules**: ${modulesList}
|
|
45
|
+
- **Dependencies**: ${depsList}
|
|
42
46
|
|
|
43
47
|
## Key Decisions
|
|
44
48
|
|
|
@@ -47,6 +51,99 @@ ${stack}-based project scaffolded with javi-forge.
|
|
|
47
51
|
`;
|
|
48
52
|
}
|
|
49
53
|
// =============================================================================
|
|
54
|
+
// Dependency detection
|
|
55
|
+
// =============================================================================
|
|
56
|
+
/**
|
|
57
|
+
* Detect top-level dependencies from project manifest files.
|
|
58
|
+
* Returns up to 10 dependency names (key deps only, not devDeps).
|
|
59
|
+
*/
|
|
60
|
+
export async function detectDependencies(projectDir, stack) {
|
|
61
|
+
const MAX_DEPS = 10;
|
|
62
|
+
try {
|
|
63
|
+
switch (stack) {
|
|
64
|
+
case "node": {
|
|
65
|
+
const pkgPath = path.join(projectDir, "package.json");
|
|
66
|
+
if (!(await fs.pathExists(pkgPath)))
|
|
67
|
+
return [];
|
|
68
|
+
const pkg = await fs.readJson(pkgPath).catch(() => ({}));
|
|
69
|
+
const deps = Object.keys(pkg.dependencies ?? {});
|
|
70
|
+
return deps.slice(0, MAX_DEPS);
|
|
71
|
+
}
|
|
72
|
+
case "python": {
|
|
73
|
+
const pyprojectPath = path.join(projectDir, "pyproject.toml");
|
|
74
|
+
if (await fs.pathExists(pyprojectPath)) {
|
|
75
|
+
const content = await fs.readFile(pyprojectPath, "utf-8");
|
|
76
|
+
const match = content.match(/dependencies\s*=\s*\[([\s\S]*?)\]/);
|
|
77
|
+
if (match?.[1]) {
|
|
78
|
+
const deps = match[1]
|
|
79
|
+
.split("\n")
|
|
80
|
+
.map((l) => l.replace(/[",]/g, "").trim())
|
|
81
|
+
.filter((l) => l.length > 0 && !l.startsWith("#"))
|
|
82
|
+
.map((l) => l.split(/[>=<~!]/)[0].trim())
|
|
83
|
+
.filter(Boolean);
|
|
84
|
+
return deps.slice(0, MAX_DEPS);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const reqPath = path.join(projectDir, "requirements.txt");
|
|
88
|
+
if (await fs.pathExists(reqPath)) {
|
|
89
|
+
const content = await fs.readFile(reqPath, "utf-8");
|
|
90
|
+
const deps = content
|
|
91
|
+
.split("\n")
|
|
92
|
+
.map((l) => l.trim())
|
|
93
|
+
.filter((l) => l.length > 0 && !l.startsWith("#") && !l.startsWith("-"))
|
|
94
|
+
.map((l) => l.split(/[>=<~!]/)[0].trim())
|
|
95
|
+
.filter(Boolean);
|
|
96
|
+
return deps.slice(0, MAX_DEPS);
|
|
97
|
+
}
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
case "go": {
|
|
101
|
+
const goModPath = path.join(projectDir, "go.mod");
|
|
102
|
+
if (!(await fs.pathExists(goModPath)))
|
|
103
|
+
return [];
|
|
104
|
+
const content = await fs.readFile(goModPath, "utf-8");
|
|
105
|
+
const requireBlock = content.match(/require\s*\(([\s\S]*?)\)/);
|
|
106
|
+
if (requireBlock?.[1]) {
|
|
107
|
+
const deps = requireBlock[1]
|
|
108
|
+
.split("\n")
|
|
109
|
+
.map((l) => l.trim())
|
|
110
|
+
.filter((l) => l.length > 0 && !l.startsWith("//"))
|
|
111
|
+
.map((l) => {
|
|
112
|
+
const parts = l.split(/\s+/);
|
|
113
|
+
const mod = parts[0] ?? "";
|
|
114
|
+
return mod.split("/").pop() ?? mod;
|
|
115
|
+
})
|
|
116
|
+
.filter(Boolean);
|
|
117
|
+
return deps.slice(0, MAX_DEPS);
|
|
118
|
+
}
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
case "rust": {
|
|
122
|
+
const cargoPath = path.join(projectDir, "Cargo.toml");
|
|
123
|
+
if (!(await fs.pathExists(cargoPath)))
|
|
124
|
+
return [];
|
|
125
|
+
const content = await fs.readFile(cargoPath, "utf-8");
|
|
126
|
+
const depsSection = content.match(/\[dependencies\]([\s\S]*?)(?=\n\[|$)/);
|
|
127
|
+
if (depsSection?.[1]) {
|
|
128
|
+
const deps = depsSection[1]
|
|
129
|
+
.split("\n")
|
|
130
|
+
.map((l) => l.trim())
|
|
131
|
+
.filter((l) => l.length > 0 && !l.startsWith("#"))
|
|
132
|
+
.map((l) => l.split(/\s*=/)[0].trim())
|
|
133
|
+
.filter(Boolean);
|
|
134
|
+
return deps.slice(0, MAX_DEPS);
|
|
135
|
+
}
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
default:
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// =============================================================================
|
|
50
147
|
// Public API
|
|
51
148
|
// =============================================================================
|
|
52
149
|
/**
|
|
@@ -59,17 +156,49 @@ export async function generateContextDir(options) {
|
|
|
59
156
|
// Collect enabled modules for summary
|
|
60
157
|
const modules = [];
|
|
61
158
|
if (options.aiSync)
|
|
62
|
-
modules.push(
|
|
159
|
+
modules.push("ai-sync");
|
|
63
160
|
if (options.sdd)
|
|
64
|
-
modules.push(
|
|
161
|
+
modules.push("sdd");
|
|
65
162
|
if (options.ghagga)
|
|
66
|
-
modules.push(
|
|
163
|
+
modules.push("ghagga");
|
|
67
164
|
if (options.mock)
|
|
68
|
-
modules.push(
|
|
165
|
+
modules.push("mock");
|
|
69
166
|
if (options.contextDir)
|
|
70
|
-
modules.push(
|
|
167
|
+
modules.push("context");
|
|
71
168
|
const index = buildIndexMd(projectName, stackCtx, ciProvider, memory);
|
|
72
169
|
const summary = buildSummaryMd(projectName, stack, ciProvider, memory, modules);
|
|
73
170
|
return { index, summary };
|
|
74
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* Refresh .context/ directory from the forge manifest and live project state.
|
|
174
|
+
* Reads manifest, detects current dependencies, regenerates INDEX.md + summary.md.
|
|
175
|
+
* Returns null if the project is not forge-managed or has no .context/ dir.
|
|
176
|
+
*/
|
|
177
|
+
export async function refreshContextDir(projectDir) {
|
|
178
|
+
const manifestPath = path.join(projectDir, ".javi-forge", "manifest.json");
|
|
179
|
+
const contextDirPath = path.join(projectDir, ".context");
|
|
180
|
+
// Only refresh if forge-managed and .context/ exists
|
|
181
|
+
if (!(await fs.pathExists(manifestPath)) ||
|
|
182
|
+
!(await fs.pathExists(contextDirPath))) {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
let manifest;
|
|
186
|
+
try {
|
|
187
|
+
manifest = (await fs.readJson(manifestPath));
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
const stackCtx = getStackContext(manifest.stack);
|
|
193
|
+
const dependencies = await detectDependencies(projectDir, manifest.stack);
|
|
194
|
+
const index = buildIndexMd(manifest.projectName, stackCtx, manifest.ciProvider, manifest.memory);
|
|
195
|
+
const summary = buildSummaryMd(manifest.projectName, manifest.stack, manifest.ciProvider, manifest.memory, manifest.modules, dependencies);
|
|
196
|
+
// Write updated files
|
|
197
|
+
await fs.writeFile(path.join(contextDirPath, "INDEX.md"), index, "utf-8");
|
|
198
|
+
await fs.writeFile(path.join(contextDirPath, "summary.md"), summary, "utf-8");
|
|
199
|
+
// Update manifest timestamp
|
|
200
|
+
manifest.updatedAt = new Date().toISOString();
|
|
201
|
+
await fs.writeJson(manifestPath, manifest, { spaces: 2 });
|
|
202
|
+
return { index, summary, updated: true };
|
|
203
|
+
}
|
|
75
204
|
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crash recovery — reconstruct pipeline state from git commit history
|
|
3
|
+
* when checkpoint files are corrupted or lost. Git is the single
|
|
4
|
+
* source of truth for what was actually done.
|
|
5
|
+
*/
|
|
6
|
+
export interface RecoveredTask {
|
|
7
|
+
commitHash: string;
|
|
8
|
+
message: string;
|
|
9
|
+
timestamp: string;
|
|
10
|
+
filesChanged: string[];
|
|
11
|
+
taskId: string | null;
|
|
12
|
+
phase: string | null;
|
|
13
|
+
}
|
|
14
|
+
export interface RecoveryReport {
|
|
15
|
+
branch: string;
|
|
16
|
+
totalCommits: number;
|
|
17
|
+
tasks: RecoveredTask[];
|
|
18
|
+
phases: Record<string, number>;
|
|
19
|
+
lastActivity: string | null;
|
|
20
|
+
}
|
|
21
|
+
export declare function getGitLog(projectDir: string, options?: {
|
|
22
|
+
maxCommits?: number;
|
|
23
|
+
since?: string;
|
|
24
|
+
}): Promise<string>;
|
|
25
|
+
export declare function getCurrentBranch(projectDir: string): Promise<string>;
|
|
26
|
+
export declare function parseCommitPhase(message: string): string | null;
|
|
27
|
+
export declare function extractTaskId(message: string): string | null;
|
|
28
|
+
export declare function parseGitLog(raw: string): RecoveredTask[];
|
|
29
|
+
export declare function recoverFromGit(projectDir: string, options?: {
|
|
30
|
+
maxCommits?: number;
|
|
31
|
+
since?: string;
|
|
32
|
+
}): Promise<RecoveryReport>;
|
|
33
|
+
export declare function formatRecovery(report: RecoveryReport): string;
|
|
34
|
+
//# sourceMappingURL=crash-recovery.d.ts.map
|