forgecraft-mcp 1.3.2 → 1.6.1
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 +2 -2
- package/dist/analyzers/anchors/anchor-loader.d.ts +47 -0
- package/dist/analyzers/anchors/anchor-loader.d.ts.map +1 -0
- package/dist/analyzers/anchors/anchor-loader.js +113 -0
- package/dist/analyzers/anchors/anchor-loader.js.map +1 -0
- package/dist/analyzers/anti-pattern.d.ts.map +1 -1
- package/dist/analyzers/anti-pattern.js +38 -26
- package/dist/analyzers/anti-pattern.js.map +1 -1
- package/dist/analyzers/completeness-helpers.d.ts +5 -0
- package/dist/analyzers/completeness-helpers.d.ts.map +1 -1
- package/dist/analyzers/completeness-helpers.js +17 -0
- package/dist/analyzers/completeness-helpers.js.map +1 -1
- package/dist/analyzers/completeness.d.ts.map +1 -1
- package/dist/analyzers/completeness.js +4 -4
- package/dist/analyzers/completeness.js.map +1 -1
- package/dist/analyzers/gs-scorer.d.ts +3 -1
- package/dist/analyzers/gs-scorer.d.ts.map +1 -1
- package/dist/analyzers/gs-scorer.js +5 -2
- package/dist/analyzers/gs-scorer.js.map +1 -1
- package/dist/analyzers/scorers/composable-scorer.d.ts +4 -2
- package/dist/analyzers/scorers/composable-scorer.d.ts.map +1 -1
- package/dist/analyzers/scorers/composable-scorer.js +50 -2
- package/dist/analyzers/scorers/composable-scorer.js.map +1 -1
- package/dist/analyzers/scorers/executable-scorer.d.ts +3 -2
- package/dist/analyzers/scorers/executable-scorer.d.ts.map +1 -1
- package/dist/analyzers/scorers/executable-scorer.js +64 -4
- package/dist/analyzers/scorers/executable-scorer.js.map +1 -1
- package/dist/analyzers/scorers/scorer-utils.d.ts +5 -3
- package/dist/analyzers/scorers/scorer-utils.d.ts.map +1 -1
- package/dist/analyzers/scorers/scorer-utils.js +34 -9
- package/dist/analyzers/scorers/scorer-utils.js.map +1 -1
- package/dist/analyzers/scorers/self-describing-scorer.d.ts +7 -4
- package/dist/analyzers/scorers/self-describing-scorer.d.ts.map +1 -1
- package/dist/analyzers/scorers/self-describing-scorer.js +17 -18
- package/dist/analyzers/scorers/self-describing-scorer.js.map +1 -1
- package/dist/artifacts/commit-hooks.d.ts +1 -1
- package/dist/artifacts/commit-hooks.d.ts.map +1 -1
- package/dist/artifacts/commit-hooks.js +2 -0
- package/dist/artifacts/commit-hooks.js.map +1 -1
- package/dist/cli/commands.d.ts +35 -1
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +109 -2
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +7 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +10 -1
- package/dist/cli.js.map +1 -1
- package/dist/disciplines/catalog.d.ts +16 -0
- package/dist/disciplines/catalog.d.ts.map +1 -0
- package/dist/disciplines/catalog.js +196 -0
- package/dist/disciplines/catalog.js.map +1 -0
- package/dist/disciplines/runner.d.ts +13 -0
- package/dist/disciplines/runner.d.ts.map +1 -0
- package/dist/disciplines/runner.js +35 -0
- package/dist/disciplines/runner.js.map +1 -0
- package/dist/registry/remote-gates.js +1 -1
- package/dist/registry/remote-gates.js.map +1 -1
- package/dist/sentinel/detect.d.ts +41 -0
- package/dist/sentinel/detect.d.ts.map +1 -0
- package/dist/sentinel/detect.js +122 -0
- package/dist/sentinel/detect.js.map +1 -0
- package/dist/sentinel/write.d.ts +54 -0
- package/dist/sentinel/write.d.ts.map +1 -0
- package/dist/sentinel/write.js +75 -0
- package/dist/sentinel/write.js.map +1 -0
- package/dist/shared/cnt-health.d.ts.map +1 -1
- package/dist/shared/cnt-health.js +12 -4
- package/dist/shared/cnt-health.js.map +1 -1
- package/dist/shared/config.d.ts +8 -0
- package/dist/shared/config.d.ts.map +1 -1
- package/dist/shared/config.js +23 -0
- package/dist/shared/config.js.map +1 -1
- package/dist/shared/project-gates-helpers.d.ts +9 -0
- package/dist/shared/project-gates-helpers.d.ts.map +1 -1
- package/dist/shared/project-gates-helpers.js +35 -0
- package/dist/shared/project-gates-helpers.js.map +1 -1
- package/dist/shared/result-utils.d.ts +27 -0
- package/dist/shared/result-utils.d.ts.map +1 -0
- package/dist/shared/result-utils.js +41 -0
- package/dist/shared/result-utils.js.map +1 -0
- package/dist/shared/types/config.d.ts +7 -1
- package/dist/shared/types/config.d.ts.map +1 -1
- package/dist/shared/types/gates.d.ts +28 -0
- package/dist/shared/types/gates.d.ts.map +1 -1
- package/dist/shared/types/project.d.ts +66 -0
- package/dist/shared/types/project.d.ts.map +1 -1
- package/dist/shared/types/project.js.map +1 -1
- package/dist/shared/types/verify.d.ts +51 -1
- package/dist/shared/types/verify.d.ts.map +1 -1
- package/dist/shared/types/verify.js +37 -1
- package/dist/shared/types/verify.js.map +1 -1
- package/dist/tools/advise-session-advisor.d.ts +16 -0
- package/dist/tools/advise-session-advisor.d.ts.map +1 -0
- package/dist/tools/advise-session-advisor.js +89 -0
- package/dist/tools/advise-session-advisor.js.map +1 -0
- package/dist/tools/advise-session-signals.d.ts +21 -0
- package/dist/tools/advise-session-signals.d.ts.map +1 -0
- package/dist/tools/advise-session-signals.js +113 -0
- package/dist/tools/advise-session-signals.js.map +1 -0
- package/dist/tools/advise-session.d.ts +22 -0
- package/dist/tools/advise-session.d.ts.map +1 -0
- package/dist/tools/advise-session.js +31 -0
- package/dist/tools/advise-session.js.map +1 -0
- package/dist/tools/change-request.d.ts +53 -0
- package/dist/tools/change-request.d.ts.map +1 -0
- package/dist/tools/change-request.js +375 -0
- package/dist/tools/change-request.js.map +1 -0
- package/dist/tools/check-cascade-contracts.d.ts +13 -0
- package/dist/tools/check-cascade-contracts.d.ts.map +1 -1
- package/dist/tools/check-cascade-contracts.js +73 -2
- package/dist/tools/check-cascade-contracts.js.map +1 -1
- package/dist/tools/check-cascade.d.ts +4 -3
- package/dist/tools/check-cascade.d.ts.map +1 -1
- package/dist/tools/check-cascade.js +30 -12
- package/dist/tools/check-cascade.js.map +1 -1
- package/dist/tools/check-spec-consistency.d.ts +25 -0
- package/dist/tools/check-spec-consistency.d.ts.map +1 -0
- package/dist/tools/check-spec-consistency.js +339 -0
- package/dist/tools/check-spec-consistency.js.map +1 -0
- package/dist/tools/check-t4.d.ts +54 -0
- package/dist/tools/check-t4.d.ts.map +1 -0
- package/dist/tools/check-t4.js +305 -0
- package/dist/tools/check-t4.js.map +1 -0
- package/dist/tools/close-cycle-helpers.d.ts +21 -2
- package/dist/tools/close-cycle-helpers.d.ts.map +1 -1
- package/dist/tools/close-cycle-helpers.js +66 -10
- package/dist/tools/close-cycle-helpers.js.map +1 -1
- package/dist/tools/close-cycle.d.ts +2 -2
- package/dist/tools/close-cycle.d.ts.map +1 -1
- package/dist/tools/close-cycle.js +342 -4
- package/dist/tools/close-cycle.js.map +1 -1
- package/dist/tools/consolidate-status.d.ts +112 -0
- package/dist/tools/consolidate-status.d.ts.map +1 -0
- package/dist/tools/consolidate-status.js +356 -0
- package/dist/tools/consolidate-status.js.map +1 -0
- package/dist/tools/executable-gates.d.ts +52 -0
- package/dist/tools/executable-gates.d.ts.map +1 -0
- package/dist/tools/executable-gates.js +332 -0
- package/dist/tools/executable-gates.js.map +1 -0
- package/dist/tools/forgecraft-dispatch-extended.d.ts.map +1 -1
- package/dist/tools/forgecraft-dispatch-extended.js +75 -0
- package/dist/tools/forgecraft-dispatch-extended.js.map +1 -1
- package/dist/tools/forgecraft-dispatch.d.ts.map +1 -1
- package/dist/tools/forgecraft-dispatch.js +21 -0
- package/dist/tools/forgecraft-dispatch.js.map +1 -1
- package/dist/tools/forgecraft-router.d.ts +8 -0
- package/dist/tools/forgecraft-router.d.ts.map +1 -1
- package/dist/tools/forgecraft-router.js +21 -1
- package/dist/tools/forgecraft-router.js.map +1 -1
- package/dist/tools/forgecraft-schema-params.d.ts +61 -4
- package/dist/tools/forgecraft-schema-params.d.ts.map +1 -1
- package/dist/tools/forgecraft-schema-params.js +95 -0
- package/dist/tools/forgecraft-schema-params.js.map +1 -1
- package/dist/tools/forgecraft-schema.d.ts +62 -5
- package/dist/tools/forgecraft-schema.d.ts.map +1 -1
- package/dist/tools/forgecraft-schema.js +24 -0
- package/dist/tools/forgecraft-schema.js.map +1 -1
- package/dist/tools/gate-violations.d.ts +59 -0
- package/dist/tools/gate-violations.d.ts.map +1 -0
- package/dist/tools/gate-violations.js +152 -0
- package/dist/tools/gate-violations.js.map +1 -0
- package/dist/tools/generate-adr.js +6 -6
- package/dist/tools/generate-adr.js.map +1 -1
- package/dist/tools/generate-env-probe.d.ts +49 -0
- package/dist/tools/generate-env-probe.d.ts.map +1 -0
- package/dist/tools/generate-env-probe.js +365 -0
- package/dist/tools/generate-env-probe.js.map +1 -0
- package/dist/tools/generate-harness.d.ts +52 -0
- package/dist/tools/generate-harness.d.ts.map +1 -0
- package/dist/tools/generate-harness.js +333 -0
- package/dist/tools/generate-harness.js.map +1 -0
- package/dist/tools/generate-roadmap.d.ts +1 -1
- package/dist/tools/generate-roadmap.d.ts.map +1 -1
- package/dist/tools/generate-roadmap.js +38 -4
- package/dist/tools/generate-roadmap.js.map +1 -1
- package/dist/tools/generate-session-prompt.d.ts +4 -4
- package/dist/tools/generate-session-prompt.d.ts.map +1 -1
- package/dist/tools/generate-session-prompt.js +66 -16
- package/dist/tools/generate-session-prompt.js.map +1 -1
- package/dist/tools/generate-slo-probe.d.ts +53 -0
- package/dist/tools/generate-slo-probe.d.ts.map +1 -0
- package/dist/tools/generate-slo-probe.js +366 -0
- package/dist/tools/generate-slo-probe.js.map +1 -0
- package/dist/tools/layer-status-gates.d.ts +24 -0
- package/dist/tools/layer-status-gates.d.ts.map +1 -0
- package/dist/tools/layer-status-gates.js +151 -0
- package/dist/tools/layer-status-gates.js.map +1 -0
- package/dist/tools/layer-status.d.ts +133 -0
- package/dist/tools/layer-status.d.ts.map +1 -0
- package/dist/tools/layer-status.js +593 -0
- package/dist/tools/layer-status.js.map +1 -0
- package/dist/tools/postcondition-coverage.d.ts +57 -0
- package/dist/tools/postcondition-coverage.d.ts.map +1 -0
- package/dist/tools/postcondition-coverage.js +256 -0
- package/dist/tools/postcondition-coverage.js.map +1 -0
- package/dist/tools/probe-runners.d.ts +21 -0
- package/dist/tools/probe-runners.d.ts.map +1 -0
- package/dist/tools/probe-runners.js +246 -0
- package/dist/tools/probe-runners.js.map +1 -0
- package/dist/tools/probe-templates.d.ts +27 -0
- package/dist/tools/probe-templates.d.ts.map +1 -0
- package/dist/tools/probe-templates.js +279 -0
- package/dist/tools/probe-templates.js.map +1 -0
- package/dist/tools/propose-session.d.ts +28 -0
- package/dist/tools/propose-session.d.ts.map +1 -0
- package/dist/tools/propose-session.js +333 -0
- package/dist/tools/propose-session.js.map +1 -0
- package/dist/tools/roadmap-builder.d.ts +34 -1
- package/dist/tools/roadmap-builder.d.ts.map +1 -1
- package/dist/tools/roadmap-builder.js +153 -11
- package/dist/tools/roadmap-builder.js.map +1 -1
- package/dist/tools/run-env-probe.d.ts +57 -0
- package/dist/tools/run-env-probe.d.ts.map +1 -0
- package/dist/tools/run-env-probe.js +270 -0
- package/dist/tools/run-env-probe.js.map +1 -0
- package/dist/tools/run-harness.d.ts +52 -0
- package/dist/tools/run-harness.d.ts.map +1 -0
- package/dist/tools/run-harness.js +279 -0
- package/dist/tools/run-harness.js.map +1 -0
- package/dist/tools/run-slo-probe.d.ts +50 -0
- package/dist/tools/run-slo-probe.d.ts.map +1 -0
- package/dist/tools/run-slo-probe.js +281 -0
- package/dist/tools/run-slo-probe.js.map +1 -0
- package/dist/tools/scaffold-writer.d.ts.map +1 -1
- package/dist/tools/scaffold-writer.js +4 -0
- package/dist/tools/scaffold-writer.js.map +1 -1
- package/dist/tools/session-prompt-builders.d.ts +20 -0
- package/dist/tools/session-prompt-builders.d.ts.map +1 -1
- package/dist/tools/session-prompt-builders.js +111 -14
- package/dist/tools/session-prompt-builders.js.map +1 -1
- package/dist/tools/session-prompt-sections.d.ts +4 -2
- package/dist/tools/session-prompt-sections.d.ts.map +1 -1
- package/dist/tools/session-prompt-sections.js +22 -10
- package/dist/tools/session-prompt-sections.js.map +1 -1
- package/dist/tools/setup-monitoring.d.ts +41 -0
- package/dist/tools/setup-monitoring.d.ts.map +1 -0
- package/dist/tools/setup-monitoring.js +364 -0
- package/dist/tools/setup-monitoring.js.map +1 -0
- package/dist/tools/verify-formatter.d.ts.map +1 -1
- package/dist/tools/verify-formatter.js +15 -1
- package/dist/tools/verify-formatter.js.map +1 -1
- package/dist/tools/verify.d.ts.map +1 -1
- package/dist/tools/verify.js +3 -0
- package/dist/tools/verify.js.map +1 -1
- package/package.json +11 -2
- package/templates/api/harness/uc-template.hurl +20 -0
- package/templates/docs-manifest.yaml +224 -0
- package/templates/game/harness/uc-template.sim.ts +29 -0
- package/templates/universal/claude-md-blocks/layer-navigation.md +20 -0
- package/templates/universal/claude-md-blocks/nfr-contracts.md +22 -0
- package/templates/universal/hooks.yaml +212 -20
- package/templates/web-react/harness/uc-template.spec.ts +35 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gate-violations tool.
|
|
3
|
+
*
|
|
4
|
+
* Reads .forgecraft/gate-violations.jsonl and surfaces active violations
|
|
5
|
+
* (those newer than the last git commit). Stale violations (from before
|
|
6
|
+
* the last commit) are shown separately so history is preserved.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
10
|
+
import { join, resolve } from "node:path";
|
|
11
|
+
import { execSync } from "node:child_process";
|
|
12
|
+
// ── Schema ──────────────────────────────────────────────────────────────
|
|
13
|
+
export const readGateViolationsSchema = z.object({
|
|
14
|
+
project_dir: z.string().describe("Absolute path to the project root."),
|
|
15
|
+
});
|
|
16
|
+
// ── Handler ─────────────────────────────────────────────────────────────
|
|
17
|
+
/**
|
|
18
|
+
* Read gate violations from the project's .forgecraft directory.
|
|
19
|
+
*
|
|
20
|
+
* @param args - Validated input containing project directory
|
|
21
|
+
* @returns MCP tool result with formatted violation report
|
|
22
|
+
*/
|
|
23
|
+
export async function readGateViolationsHandler(args) {
|
|
24
|
+
const projectDir = resolve(args.project_dir);
|
|
25
|
+
const report = buildGateViolationReport(projectDir);
|
|
26
|
+
return {
|
|
27
|
+
content: [{ type: "text", text: formatGateViolationReport(report) }],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
// ── Core builder ────────────────────────────────────────────────────────
|
|
31
|
+
/**
|
|
32
|
+
* Build a GateViolationReport from the project directory.
|
|
33
|
+
* Violations newer than the last commit are "active"; older ones are "stale".
|
|
34
|
+
*
|
|
35
|
+
* @param projectDir - Absolute path to project root
|
|
36
|
+
* @returns Violation report partitioned into active and stale
|
|
37
|
+
*/
|
|
38
|
+
export function buildGateViolationReport(projectDir) {
|
|
39
|
+
const lastCommitAt = readLastCommitTimestamp(projectDir);
|
|
40
|
+
const allViolations = readViolationsFile(projectDir);
|
|
41
|
+
if (lastCommitAt === null) {
|
|
42
|
+
return { active: allViolations, stale: [], lastCommitAt: null };
|
|
43
|
+
}
|
|
44
|
+
const lastCommitMs = new Date(lastCommitAt).getTime();
|
|
45
|
+
const active = [];
|
|
46
|
+
const stale = [];
|
|
47
|
+
for (const v of allViolations) {
|
|
48
|
+
const violationMs = new Date(v.timestamp).getTime();
|
|
49
|
+
if (isNaN(violationMs) || violationMs > lastCommitMs) {
|
|
50
|
+
active.push(v);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
stale.push(v);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return { active, stale, lastCommitAt };
|
|
57
|
+
}
|
|
58
|
+
// ── File readers ────────────────────────────────────────────────────────
|
|
59
|
+
/**
|
|
60
|
+
* Read and parse the gate-violations.jsonl file.
|
|
61
|
+
* Returns an empty array when the file is absent or unreadable.
|
|
62
|
+
*
|
|
63
|
+
* @param projectDir - Absolute path to project root
|
|
64
|
+
* @returns Array of parsed gate violations
|
|
65
|
+
*/
|
|
66
|
+
export function readViolationsFile(projectDir) {
|
|
67
|
+
const filePath = join(projectDir, ".forgecraft", "gate-violations.jsonl");
|
|
68
|
+
if (!existsSync(filePath))
|
|
69
|
+
return [];
|
|
70
|
+
try {
|
|
71
|
+
const lines = readFileSync(filePath, "utf-8")
|
|
72
|
+
.split("\n")
|
|
73
|
+
.map((l) => l.trim())
|
|
74
|
+
.filter((l) => l.length > 0);
|
|
75
|
+
return lines
|
|
76
|
+
.map((line) => {
|
|
77
|
+
try {
|
|
78
|
+
const parsed = JSON.parse(line);
|
|
79
|
+
return {
|
|
80
|
+
hook: String(parsed["hook"] ?? "unknown"),
|
|
81
|
+
severity: String(parsed["severity"] ?? "error"),
|
|
82
|
+
message: String(parsed["message"] ?? ""),
|
|
83
|
+
timestamp: String(parsed["timestamp"] ?? ""),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
.filter((v) => v !== null);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get the ISO timestamp of the last git commit in the project.
|
|
98
|
+
* Returns null when .git is absent or git is unavailable.
|
|
99
|
+
*
|
|
100
|
+
* @param projectDir - Absolute path to project root
|
|
101
|
+
* @returns ISO 8601 timestamp string or null
|
|
102
|
+
*/
|
|
103
|
+
function readLastCommitTimestamp(projectDir) {
|
|
104
|
+
if (!existsSync(join(projectDir, ".git")))
|
|
105
|
+
return null;
|
|
106
|
+
try {
|
|
107
|
+
const raw = execSync("git log -1 --format=%cI", {
|
|
108
|
+
cwd: projectDir,
|
|
109
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
110
|
+
})
|
|
111
|
+
.toString()
|
|
112
|
+
.trim();
|
|
113
|
+
return raw.length > 0 ? raw : null;
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// ── Formatter ───────────────────────────────────────────────────────────
|
|
120
|
+
/**
|
|
121
|
+
* Format a GateViolationReport as a human-readable markdown block.
|
|
122
|
+
*
|
|
123
|
+
* @param report - The violation report to format
|
|
124
|
+
* @returns Formatted markdown text
|
|
125
|
+
*/
|
|
126
|
+
export function formatGateViolationReport(report) {
|
|
127
|
+
if (report.active.length === 0 && report.stale.length === 0) {
|
|
128
|
+
return "## Gate Violations\n\nNo violations recorded. Last commit gate was clean.";
|
|
129
|
+
}
|
|
130
|
+
const lines = ["## Gate Violations"];
|
|
131
|
+
if (report.lastCommitAt) {
|
|
132
|
+
lines.push(`_Last commit: ${report.lastCommitAt}_`);
|
|
133
|
+
}
|
|
134
|
+
lines.push("");
|
|
135
|
+
if (report.active.length > 0) {
|
|
136
|
+
lines.push(`### ❌ Active (${report.active.length}) — from after last commit`);
|
|
137
|
+
for (const v of report.active) {
|
|
138
|
+
lines.push(`- **${v.hook}** [${v.severity}]: ${v.message}`);
|
|
139
|
+
lines.push(` _${v.timestamp}_`);
|
|
140
|
+
}
|
|
141
|
+
lines.push("");
|
|
142
|
+
}
|
|
143
|
+
if (report.stale.length > 0) {
|
|
144
|
+
lines.push(`### ⚪ Stale (${report.stale.length}) — cleared by last commit`);
|
|
145
|
+
for (const v of report.stale) {
|
|
146
|
+
lines.push(`- ~~${v.hook}~~: ${v.message}`);
|
|
147
|
+
}
|
|
148
|
+
lines.push("");
|
|
149
|
+
}
|
|
150
|
+
return lines.join("\n");
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=gate-violations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-violations.js","sourceRoot":"","sources":["../../src/tools/gate-violations.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,2EAA2E;AAE3E,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;CACvE,CAAC,CAAC;AAmBH,2EAA2E;AAE3E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,IAA6B;IAE7B,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,wBAAwB,CAAC,UAAU,CAAC,CAAC;IACpD,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,CAAC,MAAM,CAAC,EAAE,CAAC;KACrE,CAAC;AACJ,CAAC;AAED,2EAA2E;AAE3E;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CACtC,UAAkB;IAElB,MAAM,YAAY,GAAG,uBAAuB,CAAC,UAAU,CAAC,CAAC;IACzD,MAAM,aAAa,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAErD,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IAClE,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IACtD,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,MAAM,KAAK,GAAoB,EAAE,CAAC;IAElC,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;QAC9B,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QACpD,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,YAAY,EAAE,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;AACzC,CAAC;AAED,2EAA2E;AAE3E;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,UAAkB;IAElB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,EAAE,uBAAuB,CAAC,CAAC;IAC1E,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC;IAErC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC;aAC1C,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAE/B,OAAO,KAAK;aACT,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACZ,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;gBAC3D,OAAO;oBACL,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;oBACzC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC;oBAC/C,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;oBACxC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;iBAC7C,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAAsB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,uBAAuB,CAAC,UAAkB;IACjD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,QAAQ,CAAC,yBAAyB,EAAE;YAC9C,GAAG,EAAE,UAAU;YACf,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC;aACC,QAAQ,EAAE;aACV,IAAI,EAAE,CAAC;QACV,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,2EAA2E;AAE3E;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAA2B;IACnE,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5D,OAAO,2EAA2E,CAAC;IACrF,CAAC;IAED,MAAM,KAAK,GAAa,CAAC,oBAAoB,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,iBAAiB,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC;IACtD,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CACR,iBAAiB,MAAM,CAAC,MAAM,CAAC,MAAM,4BAA4B,CAClE,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5D,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;QACnC,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CACR,gBAAgB,MAAM,CAAC,KAAK,CAAC,MAAM,4BAA4B,CAChE,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9C,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -100,7 +100,7 @@ export async function generateAdrHandler(args) {
|
|
|
100
100
|
content,
|
|
101
101
|
"```",
|
|
102
102
|
``,
|
|
103
|
-
`> **Next step:** If any sections contain
|
|
103
|
+
`> **Next step:** If any sections contain \`[NEEDS CLARIFICATION]\` markers, resolve them before committing.`,
|
|
104
104
|
`> ADR files are immutable once accepted — use a new ADR to supersede this one.`,
|
|
105
105
|
];
|
|
106
106
|
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
@@ -140,7 +140,7 @@ function renderAdr(fields) {
|
|
|
140
140
|
const date = new Date().toISOString().slice(0, 10);
|
|
141
141
|
const alternativeBlock = alternatives && alternatives.length > 0
|
|
142
142
|
? alternatives.map((a) => `- ${a}`).join("\n")
|
|
143
|
-
: "- [
|
|
143
|
+
: "- [NEEDS CLARIFICATION: list alternatives considered and why each was rejected]";
|
|
144
144
|
return [
|
|
145
145
|
`# ${id}: ${title}`,
|
|
146
146
|
``,
|
|
@@ -154,12 +154,12 @@ function renderAdr(fields) {
|
|
|
154
154
|
`## Context`,
|
|
155
155
|
``,
|
|
156
156
|
context ??
|
|
157
|
-
"[
|
|
157
|
+
"[NEEDS CLARIFICATION: describe the situation that forced this decision — what constraints, requirements, and forces are at play]",
|
|
158
158
|
``,
|
|
159
159
|
`## Decision`,
|
|
160
160
|
``,
|
|
161
161
|
decision ??
|
|
162
|
-
"[
|
|
162
|
+
"[NEEDS CLARIFICATION: state what was decided and why this option was chosen over the alternatives]",
|
|
163
163
|
``,
|
|
164
164
|
`## Alternatives Considered`,
|
|
165
165
|
``,
|
|
@@ -168,11 +168,11 @@ function renderAdr(fields) {
|
|
|
168
168
|
`## Consequences`,
|
|
169
169
|
``,
|
|
170
170
|
consequences ??
|
|
171
|
-
"[
|
|
171
|
+
"[NEEDS CLARIFICATION: describe what becomes easier, harder, or newly constrained as a result of this decision]",
|
|
172
172
|
``,
|
|
173
173
|
`---`,
|
|
174
174
|
``,
|
|
175
|
-
`_This ADR was generated by ForgeCraft.
|
|
175
|
+
`_This ADR was generated by ForgeCraft. Resolve any [NEEDS CLARIFICATION] sections before accepting — the AI cannot act on ambiguity it cannot see._`,
|
|
176
176
|
].join("\n");
|
|
177
177
|
}
|
|
178
178
|
//# sourceMappingURL=generate-adr.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-adr.js","sourceRoot":"","sources":["../../src/tools/generate-adr.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"generate-adr.js","sourceRoot":"","sources":["../../src/tools/generate-adr.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* generate_env_probe tool handler.
|
|
3
|
+
*
|
|
4
|
+
* Reads environment probe specs from .forgecraft/env/*.yaml and scaffolds
|
|
5
|
+
* executable probe files in tests/env/. Idempotent — skips existing unless force=true.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import type { ToolResult } from "../shared/types.js";
|
|
9
|
+
export declare const generateEnvProbeSchema: z.ZodObject<{
|
|
10
|
+
project_dir: z.ZodString;
|
|
11
|
+
force: z.ZodOptional<z.ZodBoolean>;
|
|
12
|
+
}, "strip", z.ZodTypeAny, {
|
|
13
|
+
project_dir: string;
|
|
14
|
+
force?: boolean | undefined;
|
|
15
|
+
}, {
|
|
16
|
+
project_dir: string;
|
|
17
|
+
force?: boolean | undefined;
|
|
18
|
+
}>;
|
|
19
|
+
export type GenerateEnvProbeInput = z.infer<typeof generateEnvProbeSchema>;
|
|
20
|
+
export interface EnvProbeSpec {
|
|
21
|
+
service: string;
|
|
22
|
+
title?: string;
|
|
23
|
+
probes?: Array<{
|
|
24
|
+
id: string;
|
|
25
|
+
type: string;
|
|
26
|
+
description?: string;
|
|
27
|
+
url?: string;
|
|
28
|
+
vars?: string[];
|
|
29
|
+
host?: string;
|
|
30
|
+
port?: number;
|
|
31
|
+
}>;
|
|
32
|
+
}
|
|
33
|
+
export interface EnvGenerateResult {
|
|
34
|
+
service: string;
|
|
35
|
+
probeId: string;
|
|
36
|
+
probeType: string;
|
|
37
|
+
probeFile: string;
|
|
38
|
+
status: "generated" | "skipped" | "error";
|
|
39
|
+
reason?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function envExtensionForType(probeType: string): string;
|
|
42
|
+
export declare function generateEnvProbeContent(service: string, probeId: string, probeType: string, description: string, extra?: {
|
|
43
|
+
url?: string;
|
|
44
|
+
vars?: string[];
|
|
45
|
+
host?: string;
|
|
46
|
+
port?: number;
|
|
47
|
+
}): string;
|
|
48
|
+
export declare function generateEnvProbeHandler(args: GenerateEnvProbeInput): Promise<ToolResult>;
|
|
49
|
+
//# sourceMappingURL=generate-env-probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-env-probe.d.ts","sourceRoot":"","sources":["../../src/tools/generate-env-probe.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,eAAO,MAAM,sBAAsB;;;;;;;;;EAMjC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAI3E,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAiB7D;AA2ND,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACtE,MAAM,CAsCR;AAID,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,UAAU,CAAC,CA+GrB"}
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* generate_env_probe tool handler.
|
|
3
|
+
*
|
|
4
|
+
* Reads environment probe specs from .forgecraft/env/*.yaml and scaffolds
|
|
5
|
+
* executable probe files in tests/env/. Idempotent — skips existing unless force=true.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, } from "node:fs";
|
|
9
|
+
import { join, resolve } from "node:path";
|
|
10
|
+
import yaml from "js-yaml";
|
|
11
|
+
// ── Schema ───────────────────────────────────────────────────────────
|
|
12
|
+
export const generateEnvProbeSchema = z.object({
|
|
13
|
+
project_dir: z.string().describe("Absolute path to the project root."),
|
|
14
|
+
force: z
|
|
15
|
+
.boolean()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe("Overwrite existing probe files. Default: false."),
|
|
18
|
+
});
|
|
19
|
+
// ── Probe type → file extension ───────────────────────────────────────
|
|
20
|
+
export function envExtensionForType(probeType) {
|
|
21
|
+
switch (probeType) {
|
|
22
|
+
case "health_check":
|
|
23
|
+
return ".health.sh";
|
|
24
|
+
case "env_var":
|
|
25
|
+
return ".env.sh";
|
|
26
|
+
case "port_check":
|
|
27
|
+
return ".port.sh";
|
|
28
|
+
case "schema_validate":
|
|
29
|
+
return ".schema.sh";
|
|
30
|
+
case "docker_check":
|
|
31
|
+
return ".docker.sh";
|
|
32
|
+
case "migration_check":
|
|
33
|
+
return ".migration.sh";
|
|
34
|
+
default:
|
|
35
|
+
return ".sh";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// ── Probe content generators ──────────────────────────────────────────
|
|
39
|
+
function generateHealthCheckContent(service, probeId, description, url) {
|
|
40
|
+
const targetUrl = url ?? "http://{{host}}:{{port}}/health";
|
|
41
|
+
return `#!/usr/bin/env bash
|
|
42
|
+
# Service: ${service}
|
|
43
|
+
# Probe: ${probeId}
|
|
44
|
+
# Type: health_check
|
|
45
|
+
# Description: ${description}
|
|
46
|
+
set -euo pipefail
|
|
47
|
+
|
|
48
|
+
# TODO: set actual health endpoint URL
|
|
49
|
+
URL="${targetUrl}"
|
|
50
|
+
|
|
51
|
+
if ! command -v curl &>/dev/null; then
|
|
52
|
+
echo "FAIL: curl not found — cannot run health check"
|
|
53
|
+
exit 1
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "$URL" || echo "000")
|
|
57
|
+
|
|
58
|
+
if [ "$HTTP_STATUS" = "200" ]; then
|
|
59
|
+
echo "PASS: ${probeId} — health endpoint returned 200"
|
|
60
|
+
else
|
|
61
|
+
echo "FAIL: ${probeId} — health endpoint returned $HTTP_STATUS (expected 200)"
|
|
62
|
+
exit 1
|
|
63
|
+
fi
|
|
64
|
+
`;
|
|
65
|
+
}
|
|
66
|
+
function generateEnvVarContent(service, probeId, description, vars) {
|
|
67
|
+
const varList = vars && vars.length > 0 ? vars : ["# TODO: add required env var names"];
|
|
68
|
+
const checkLines = vars && vars.length > 0
|
|
69
|
+
? vars
|
|
70
|
+
.map((v) => `if [ -z "\${${v}:-}" ]; then\n echo "FAIL: ${probeId} — required env var ${v} is not set or empty"\n exit 1\nfi`)
|
|
71
|
+
.join("\n")
|
|
72
|
+
: `# TODO: check required env vars\necho "TODO: implement env var checks for ${probeId}"\nexit 1`;
|
|
73
|
+
return `#!/usr/bin/env bash
|
|
74
|
+
# Service: ${service}
|
|
75
|
+
# Probe: ${probeId}
|
|
76
|
+
# Type: env_var
|
|
77
|
+
# Description: ${description}
|
|
78
|
+
# Required vars: ${varList.join(", ")}
|
|
79
|
+
set -euo pipefail
|
|
80
|
+
|
|
81
|
+
${checkLines}
|
|
82
|
+
|
|
83
|
+
echo "PASS: ${probeId} — all required env vars are set"
|
|
84
|
+
`;
|
|
85
|
+
}
|
|
86
|
+
function generatePortCheckContent(service, probeId, description, host, port) {
|
|
87
|
+
const targetHost = host ?? "{{db_host}}";
|
|
88
|
+
const targetPort = port ?? 5432;
|
|
89
|
+
return `#!/usr/bin/env bash
|
|
90
|
+
# Service: ${service}
|
|
91
|
+
# Probe: ${probeId}
|
|
92
|
+
# Type: port_check
|
|
93
|
+
# Description: ${description}
|
|
94
|
+
set -euo pipefail
|
|
95
|
+
|
|
96
|
+
# TODO: set actual host and port
|
|
97
|
+
HOST="${targetHost}"
|
|
98
|
+
PORT="${targetPort}"
|
|
99
|
+
|
|
100
|
+
if command -v nc &>/dev/null; then
|
|
101
|
+
if nc -z -w 5 "$HOST" "$PORT" 2>/dev/null; then
|
|
102
|
+
echo "PASS: ${probeId} — port $HOST:$PORT is reachable"
|
|
103
|
+
else
|
|
104
|
+
echo "FAIL: ${probeId} — port $HOST:$PORT is not reachable"
|
|
105
|
+
exit 1
|
|
106
|
+
fi
|
|
107
|
+
elif command -v curl &>/dev/null; then
|
|
108
|
+
if curl -s --max-time 5 "telnet://$HOST:$PORT" &>/dev/null || curl -s --connect-timeout 5 "$HOST:$PORT" &>/dev/null; then
|
|
109
|
+
echo "PASS: ${probeId} — port $HOST:$PORT is reachable"
|
|
110
|
+
else
|
|
111
|
+
echo "FAIL: ${probeId} — port $HOST:$PORT is not reachable"
|
|
112
|
+
exit 1
|
|
113
|
+
fi
|
|
114
|
+
else
|
|
115
|
+
echo "FAIL: ${probeId} — neither nc nor curl found"
|
|
116
|
+
exit 1
|
|
117
|
+
fi
|
|
118
|
+
`;
|
|
119
|
+
}
|
|
120
|
+
function generateSchemaValidateContent(service, probeId, description) {
|
|
121
|
+
return `#!/usr/bin/env bash
|
|
122
|
+
# Service: ${service}
|
|
123
|
+
# Probe: ${probeId}
|
|
124
|
+
# Type: schema_validate
|
|
125
|
+
# Description: ${description}
|
|
126
|
+
set -euo pipefail
|
|
127
|
+
|
|
128
|
+
# TODO: set path to .env.example and actual env file
|
|
129
|
+
ENV_EXAMPLE=".env.example"
|
|
130
|
+
ENV_FILE=".env"
|
|
131
|
+
|
|
132
|
+
if [ ! -f "$ENV_EXAMPLE" ]; then
|
|
133
|
+
echo "FAIL: ${probeId} — .env.example not found at $ENV_EXAMPLE"
|
|
134
|
+
exit 1
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
MISSING=()
|
|
138
|
+
while IFS= read -r line; do
|
|
139
|
+
# Extract var name (skip comments and empty lines)
|
|
140
|
+
[[ "$line" =~ ^#.*$ || -z "$line" ]] && continue
|
|
141
|
+
VAR_NAME=$(echo "$line" | cut -d= -f1)
|
|
142
|
+
if [ -z "\${!VAR_NAME:-}" ]; then
|
|
143
|
+
MISSING+=("$VAR_NAME")
|
|
144
|
+
fi
|
|
145
|
+
done < "$ENV_EXAMPLE"
|
|
146
|
+
|
|
147
|
+
if [ \${#MISSING[@]} -gt 0 ]; then
|
|
148
|
+
echo "FAIL: ${probeId} — missing env vars: \${MISSING[*]}"
|
|
149
|
+
exit 1
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
echo "PASS: ${probeId} — env schema validated against .env.example"
|
|
153
|
+
`;
|
|
154
|
+
}
|
|
155
|
+
function generateDockerCheckContent(service, probeId, description) {
|
|
156
|
+
return `#!/usr/bin/env bash
|
|
157
|
+
# Service: ${service}
|
|
158
|
+
# Probe: ${probeId}
|
|
159
|
+
# Type: docker_check
|
|
160
|
+
# Description: ${description}
|
|
161
|
+
set -euo pipefail
|
|
162
|
+
|
|
163
|
+
# TODO: set actual container name
|
|
164
|
+
CONTAINER_NAME="${service}"
|
|
165
|
+
|
|
166
|
+
if ! command -v docker &>/dev/null; then
|
|
167
|
+
echo "FAIL: ${probeId} — docker not found"
|
|
168
|
+
exit 1
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
if docker compose ps --format json 2>/dev/null | grep -q "$CONTAINER_NAME"; then
|
|
172
|
+
STATUS=$(docker compose ps --format json 2>/dev/null | grep "$CONTAINER_NAME" | grep -o '"State":"[^"]*"' | head -1)
|
|
173
|
+
if echo "$STATUS" | grep -q '"running"'; then
|
|
174
|
+
echo "PASS: ${probeId} — container $CONTAINER_NAME is running"
|
|
175
|
+
else
|
|
176
|
+
echo "FAIL: ${probeId} — container $CONTAINER_NAME is not running: $STATUS"
|
|
177
|
+
exit 1
|
|
178
|
+
fi
|
|
179
|
+
elif docker ps --filter "name=$CONTAINER_NAME" --format "{{.Status}}" 2>/dev/null | grep -q "Up"; then
|
|
180
|
+
echo "PASS: ${probeId} — container $CONTAINER_NAME is running"
|
|
181
|
+
else
|
|
182
|
+
echo "FAIL: ${probeId} — container $CONTAINER_NAME is not running"
|
|
183
|
+
exit 1
|
|
184
|
+
fi
|
|
185
|
+
`;
|
|
186
|
+
}
|
|
187
|
+
function generateMigrationCheckContent(service, probeId, description) {
|
|
188
|
+
return `#!/usr/bin/env bash
|
|
189
|
+
# Service: ${service}
|
|
190
|
+
# Probe: ${probeId}
|
|
191
|
+
# Type: migration_check
|
|
192
|
+
# Description: ${description}
|
|
193
|
+
set -euo pipefail
|
|
194
|
+
|
|
195
|
+
DB_URL="\${DATABASE_URL:-}"
|
|
196
|
+
if [ -z "$DB_URL" ]; then
|
|
197
|
+
echo "FAIL: ${probeId} — DATABASE_URL not set"
|
|
198
|
+
exit 1
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
# TODO: adapt to your migration tool (prisma, flyway, liquibase, etc.)
|
|
202
|
+
if command -v prisma &>/dev/null; then
|
|
203
|
+
PENDING=$(npx prisma migrate status 2>&1 | grep -c "pending" || true)
|
|
204
|
+
if [ "$PENDING" -gt 0 ]; then
|
|
205
|
+
echo "FAIL: ${probeId} — $PENDING pending migration(s)"
|
|
206
|
+
exit 1
|
|
207
|
+
fi
|
|
208
|
+
echo "PASS: ${probeId} — no pending migrations"
|
|
209
|
+
else
|
|
210
|
+
echo "TODO: implement migration check for ${probeId} — set up migration tool"
|
|
211
|
+
exit 1
|
|
212
|
+
fi
|
|
213
|
+
`;
|
|
214
|
+
}
|
|
215
|
+
export function generateEnvProbeContent(service, probeId, probeType, description, extra) {
|
|
216
|
+
switch (probeType) {
|
|
217
|
+
case "health_check":
|
|
218
|
+
return generateHealthCheckContent(service, probeId, description, extra?.url);
|
|
219
|
+
case "env_var":
|
|
220
|
+
return generateEnvVarContent(service, probeId, description, extra?.vars);
|
|
221
|
+
case "port_check":
|
|
222
|
+
return generatePortCheckContent(service, probeId, description, extra?.host, extra?.port);
|
|
223
|
+
case "schema_validate":
|
|
224
|
+
return generateSchemaValidateContent(service, probeId, description);
|
|
225
|
+
case "docker_check":
|
|
226
|
+
return generateDockerCheckContent(service, probeId, description);
|
|
227
|
+
case "migration_check":
|
|
228
|
+
return generateMigrationCheckContent(service, probeId, description);
|
|
229
|
+
default:
|
|
230
|
+
return `#!/usr/bin/env bash
|
|
231
|
+
# Service: ${service}
|
|
232
|
+
# Probe: ${probeId}
|
|
233
|
+
# Type: ${probeType}
|
|
234
|
+
# Description: ${description}
|
|
235
|
+
set -euo pipefail
|
|
236
|
+
|
|
237
|
+
# TODO: implement probe check for ${probeId}
|
|
238
|
+
echo "TODO: implement ${probeId}"
|
|
239
|
+
exit 1
|
|
240
|
+
`;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// ── Handler ───────────────────────────────────────────────────────────
|
|
244
|
+
export async function generateEnvProbeHandler(args) {
|
|
245
|
+
const projectDir = resolve(args.project_dir);
|
|
246
|
+
const force = args.force ?? false;
|
|
247
|
+
const envSpecDir = join(projectDir, ".forgecraft", "env");
|
|
248
|
+
if (!existsSync(envSpecDir)) {
|
|
249
|
+
return {
|
|
250
|
+
content: [
|
|
251
|
+
{
|
|
252
|
+
type: "text",
|
|
253
|
+
text: "No env probe specs found. Create .forgecraft/env/service.yaml to define environment contracts.",
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
// Read all spec files
|
|
259
|
+
let specFiles = [];
|
|
260
|
+
try {
|
|
261
|
+
specFiles = readdirSync(envSpecDir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
specFiles = [];
|
|
265
|
+
}
|
|
266
|
+
if (specFiles.length === 0) {
|
|
267
|
+
return {
|
|
268
|
+
content: [
|
|
269
|
+
{
|
|
270
|
+
type: "text",
|
|
271
|
+
text: "No env probe specs found. Create .forgecraft/env/service.yaml to define environment contracts.",
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
const envDir = join(projectDir, "tests", "env");
|
|
277
|
+
try {
|
|
278
|
+
mkdirSync(envDir, { recursive: true });
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
/* ignore */
|
|
282
|
+
}
|
|
283
|
+
const results = [];
|
|
284
|
+
for (const specFile of specFiles) {
|
|
285
|
+
let spec;
|
|
286
|
+
try {
|
|
287
|
+
const raw = readFileSync(join(envSpecDir, specFile), "utf-8");
|
|
288
|
+
spec = yaml.load(raw);
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
if (!spec?.service || !spec.probes)
|
|
294
|
+
continue;
|
|
295
|
+
for (const probe of spec.probes) {
|
|
296
|
+
const ext = envExtensionForType(probe.type);
|
|
297
|
+
const fileName = `${spec.service}-${probe.id}${ext}`;
|
|
298
|
+
const filePath = join(envDir, fileName);
|
|
299
|
+
const relPath = `tests/env/${fileName}`;
|
|
300
|
+
if (existsSync(filePath) && !force) {
|
|
301
|
+
results.push({
|
|
302
|
+
service: spec.service,
|
|
303
|
+
probeId: probe.id,
|
|
304
|
+
probeType: probe.type,
|
|
305
|
+
probeFile: relPath,
|
|
306
|
+
status: "skipped",
|
|
307
|
+
reason: "already exists",
|
|
308
|
+
});
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
const content = generateEnvProbeContent(spec.service, probe.id, probe.type, probe.description ?? probe.id, {
|
|
312
|
+
url: probe.url,
|
|
313
|
+
vars: probe.vars,
|
|
314
|
+
host: probe.host,
|
|
315
|
+
port: probe.port,
|
|
316
|
+
});
|
|
317
|
+
try {
|
|
318
|
+
writeFileSync(filePath, content, "utf-8");
|
|
319
|
+
results.push({
|
|
320
|
+
service: spec.service,
|
|
321
|
+
probeId: probe.id,
|
|
322
|
+
probeType: probe.type,
|
|
323
|
+
probeFile: relPath,
|
|
324
|
+
status: "generated",
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
catch (err) {
|
|
328
|
+
results.push({
|
|
329
|
+
service: spec.service,
|
|
330
|
+
probeId: probe.id,
|
|
331
|
+
probeType: probe.type,
|
|
332
|
+
probeFile: relPath,
|
|
333
|
+
status: "error",
|
|
334
|
+
reason: `write failed: ${String(err)}`,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return { content: [{ type: "text", text: formatEnvReport(results) }] };
|
|
340
|
+
}
|
|
341
|
+
// ── Report formatter ──────────────────────────────────────────────────
|
|
342
|
+
function formatEnvReport(results) {
|
|
343
|
+
const generated = results.filter((r) => r.status === "generated");
|
|
344
|
+
const skipped = results.filter((r) => r.status === "skipped");
|
|
345
|
+
const noSpec = results.filter((r) => r.status === "error");
|
|
346
|
+
const lines = [
|
|
347
|
+
"## Env Probe Generation Report",
|
|
348
|
+
"",
|
|
349
|
+
`Generated: ${generated.length} Skipped: ${skipped.length} No spec: ${noSpec.length}`,
|
|
350
|
+
"",
|
|
351
|
+
"| Service | Probe | Type | File | Status |",
|
|
352
|
+
"|---|---|---|---|---|",
|
|
353
|
+
];
|
|
354
|
+
for (const r of results) {
|
|
355
|
+
const statusLabel = r.status === "generated"
|
|
356
|
+
? "✅ generated"
|
|
357
|
+
: r.status === "skipped"
|
|
358
|
+
? "⏭ skipped"
|
|
359
|
+
: `❌ error: ${r.reason ?? ""}`;
|
|
360
|
+
lines.push(`| ${r.service} | ${r.probeId} | ${r.probeType} | ${r.probeFile} | ${statusLabel} |`);
|
|
361
|
+
}
|
|
362
|
+
lines.push("", "To run: call run_env_probe");
|
|
363
|
+
return lines.join("\n");
|
|
364
|
+
}
|
|
365
|
+
//# sourceMappingURL=generate-env-probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-env-probe.js","sourceRoot":"","sources":["../../src/tools/generate-env-probe.ts"],"names":[],"mappings":"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"}
|