javi-forge 1.5.0 → 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.
Files changed (217) hide show
  1. package/README.md +191 -3
  2. package/ci-local/hooks/pre-push +17 -13
  3. package/dist/commands/analyze.d.ts +1 -1
  4. package/dist/commands/analyze.js +15 -15
  5. package/dist/commands/atlassian-mcp.d.ts +42 -0
  6. package/dist/commands/atlassian-mcp.js +98 -0
  7. package/dist/commands/ci.d.ts +3 -3
  8. package/dist/commands/ci.js +185 -147
  9. package/dist/commands/crash-recovery.d.ts +34 -0
  10. package/dist/commands/crash-recovery.js +123 -0
  11. package/dist/commands/doctor.d.ts +2 -2
  12. package/dist/commands/doctor.js +113 -61
  13. package/dist/commands/harness-audit.d.ts +35 -0
  14. package/dist/commands/harness-audit.js +277 -0
  15. package/dist/commands/init.d.ts +1 -1
  16. package/dist/commands/init.js +415 -118
  17. package/dist/commands/llmstxt.d.ts +1 -1
  18. package/dist/commands/llmstxt.js +36 -34
  19. package/dist/commands/parallel-batch.d.ts +42 -0
  20. package/dist/commands/parallel-batch.js +90 -0
  21. package/dist/commands/plugin.d.ts +26 -1
  22. package/dist/commands/plugin.js +138 -24
  23. package/dist/commands/secret-scanner.d.ts +30 -0
  24. package/dist/commands/secret-scanner.js +272 -0
  25. package/dist/commands/security-analysis.d.ts +74 -0
  26. package/dist/commands/security-analysis.js +487 -0
  27. package/dist/commands/security.d.ts +31 -0
  28. package/dist/commands/security.js +445 -0
  29. package/dist/commands/skill-scanner.d.ts +63 -0
  30. package/dist/commands/skill-scanner.js +383 -0
  31. package/dist/commands/skills.d.ts +139 -0
  32. package/dist/commands/skills.js +895 -0
  33. package/dist/commands/supply-chain.d.ts +23 -0
  34. package/dist/commands/supply-chain.js +126 -0
  35. package/dist/commands/tdd-pipeline.d.ts +17 -0
  36. package/dist/commands/tdd-pipeline.js +144 -0
  37. package/dist/commands/tdd.d.ts +21 -0
  38. package/dist/commands/tdd.js +120 -0
  39. package/dist/commands/team-presets.d.ts +53 -0
  40. package/dist/commands/team-presets.js +201 -0
  41. package/dist/commands/workflow.d.ts +23 -0
  42. package/dist/commands/workflow.js +114 -0
  43. package/dist/constants.d.ts +21 -0
  44. package/dist/constants.js +208 -37
  45. package/dist/index.js +400 -54
  46. package/dist/lib/agent-skills.d.ts +73 -0
  47. package/dist/lib/agent-skills.js +260 -0
  48. package/dist/lib/auto-skill-install.d.ts +37 -0
  49. package/dist/lib/auto-skill-install.js +92 -0
  50. package/dist/lib/auto-wire.d.ts +20 -0
  51. package/dist/lib/auto-wire.js +240 -0
  52. package/dist/lib/claudemd.d.ts +20 -0
  53. package/dist/lib/claudemd.js +222 -0
  54. package/dist/lib/codex-export.d.ts +16 -0
  55. package/dist/lib/codex-export.js +109 -0
  56. package/dist/lib/common.d.ts +1 -1
  57. package/dist/lib/common.js +52 -44
  58. package/dist/lib/context.d.ts +27 -0
  59. package/dist/lib/context.js +204 -0
  60. package/dist/lib/docker.d.ts +1 -1
  61. package/dist/lib/docker.js +141 -112
  62. package/dist/lib/frontmatter.d.ts +1 -1
  63. package/dist/lib/frontmatter.js +29 -15
  64. package/dist/lib/plugin.d.ts +19 -1
  65. package/dist/lib/plugin.js +174 -47
  66. package/dist/lib/skill-publish.d.ts +40 -0
  67. package/dist/lib/skill-publish.js +146 -0
  68. package/dist/lib/stack-detector.d.ts +38 -0
  69. package/dist/lib/stack-detector.js +207 -0
  70. package/dist/lib/template.d.ts +16 -1
  71. package/dist/lib/template.js +46 -17
  72. package/dist/lib/workflow/discovery.d.ts +19 -0
  73. package/dist/lib/workflow/discovery.js +68 -0
  74. package/dist/lib/workflow/index.d.ts +5 -0
  75. package/dist/lib/workflow/index.js +5 -0
  76. package/dist/lib/workflow/parser.d.ts +16 -0
  77. package/dist/lib/workflow/parser.js +198 -0
  78. package/dist/lib/workflow/renderer.d.ts +9 -0
  79. package/dist/lib/workflow/renderer.js +152 -0
  80. package/dist/lib/workflow/validator.d.ts +10 -0
  81. package/dist/lib/workflow/validator.js +189 -0
  82. package/dist/tasks/index.d.ts +4 -0
  83. package/dist/tasks/index.js +4 -0
  84. package/dist/tasks/scaffold-tasks.d.ts +3 -0
  85. package/dist/tasks/scaffold-tasks.js +14 -0
  86. package/dist/tasks/task-id.d.ts +30 -0
  87. package/dist/tasks/task-id.js +55 -0
  88. package/dist/tasks/task-tracker.d.ts +15 -0
  89. package/dist/tasks/task-tracker.js +81 -0
  90. package/dist/types/index.d.ts +252 -5
  91. package/dist/types/index.js +11 -1
  92. package/dist/ui/AnalyzeUI.d.ts +1 -1
  93. package/dist/ui/AnalyzeUI.js +38 -39
  94. package/dist/ui/App.d.ts +5 -3
  95. package/dist/ui/App.js +92 -46
  96. package/dist/ui/AutoSkills.d.ts +9 -0
  97. package/dist/ui/AutoSkills.js +124 -0
  98. package/dist/ui/CI.d.ts +2 -2
  99. package/dist/ui/CI.js +24 -26
  100. package/dist/ui/CIContext.d.ts +1 -1
  101. package/dist/ui/CIContext.js +3 -2
  102. package/dist/ui/CISelector.d.ts +2 -2
  103. package/dist/ui/CISelector.js +23 -15
  104. package/dist/ui/Doctor.d.ts +1 -1
  105. package/dist/ui/Doctor.js +35 -29
  106. package/dist/ui/Header.d.ts +1 -1
  107. package/dist/ui/Header.js +14 -14
  108. package/dist/ui/HookProfileSelector.d.ts +9 -0
  109. package/dist/ui/HookProfileSelector.js +54 -0
  110. package/dist/ui/LlmsTxt.d.ts +1 -1
  111. package/dist/ui/LlmsTxt.js +31 -22
  112. package/dist/ui/MemorySelector.d.ts +2 -2
  113. package/dist/ui/MemorySelector.js +28 -16
  114. package/dist/ui/NameInput.d.ts +1 -1
  115. package/dist/ui/NameInput.js +21 -21
  116. package/dist/ui/OptionSelector.d.ts +8 -2
  117. package/dist/ui/OptionSelector.js +83 -26
  118. package/dist/ui/Plugin.d.ts +4 -3
  119. package/dist/ui/Plugin.js +89 -29
  120. package/dist/ui/Progress.d.ts +3 -3
  121. package/dist/ui/Progress.js +23 -22
  122. package/dist/ui/Skills.d.ts +11 -0
  123. package/dist/ui/Skills.js +148 -0
  124. package/dist/ui/StackSelector.d.ts +2 -2
  125. package/dist/ui/StackSelector.js +26 -16
  126. package/dist/ui/Summary.d.ts +3 -3
  127. package/dist/ui/Summary.js +60 -50
  128. package/dist/ui/Welcome.d.ts +1 -1
  129. package/dist/ui/Welcome.js +15 -16
  130. package/dist/ui/theme.d.ts +1 -1
  131. package/dist/ui/theme.js +6 -6
  132. package/package.json +9 -6
  133. package/templates/common/atlassian/mcp-atlassian-snippet.json +16 -0
  134. package/templates/common/repoforge/mcp-repoforge-snippet.json +11 -0
  135. package/templates/common/repoforge/repoforge.yaml +34 -0
  136. package/templates/github/deploy-docker-zero-downtime.yml +140 -0
  137. package/templates/github/repoforge-graph.yml +45 -0
  138. package/templates/gitlab/deploy-docker-zero-downtime.yml +57 -0
  139. package/templates/local-ai/.env.example +17 -0
  140. package/templates/local-ai/docker-compose.yml +95 -0
  141. package/templates/security-hooks/claude-settings-security.json +30 -0
  142. package/templates/security-hooks/commit-msg-signing +29 -0
  143. package/templates/security-hooks/pre-commit-permissions +74 -0
  144. package/templates/security-hooks/pre-commit-secrets +74 -0
  145. package/templates/security-hooks/pre-push-branch-protection +62 -0
  146. package/templates/security-hooks/pre-push-deps +83 -0
  147. package/templates/security-hooks/pre-push-signing +67 -0
  148. package/templates/woodpecker/deploy-docker-zero-downtime.yml +50 -0
  149. package/templates/workflows/ci-pipeline.dot +15 -0
  150. package/templates/workflows/feature-flow.dot +21 -0
  151. package/templates/workflows/release.dot +16 -0
  152. package/dist/__integration__/helpers.d.ts +0 -20
  153. package/dist/__integration__/helpers.d.ts.map +0 -1
  154. package/dist/__integration__/helpers.js +0 -31
  155. package/dist/__integration__/helpers.js.map +0 -1
  156. package/dist/commands/analyze.d.ts.map +0 -1
  157. package/dist/commands/analyze.js.map +0 -1
  158. package/dist/commands/ci.d.ts.map +0 -1
  159. package/dist/commands/ci.js.map +0 -1
  160. package/dist/commands/doctor.d.ts.map +0 -1
  161. package/dist/commands/doctor.js.map +0 -1
  162. package/dist/commands/init.d.ts.map +0 -1
  163. package/dist/commands/init.js.map +0 -1
  164. package/dist/commands/llmstxt.d.ts.map +0 -1
  165. package/dist/commands/llmstxt.js.map +0 -1
  166. package/dist/commands/plugin.d.ts.map +0 -1
  167. package/dist/commands/plugin.js.map +0 -1
  168. package/dist/constants.d.ts.map +0 -1
  169. package/dist/constants.js.map +0 -1
  170. package/dist/index.d.ts.map +0 -1
  171. package/dist/index.js.map +0 -1
  172. package/dist/lib/common.d.ts.map +0 -1
  173. package/dist/lib/common.js.map +0 -1
  174. package/dist/lib/docker.d.ts.map +0 -1
  175. package/dist/lib/docker.js.map +0 -1
  176. package/dist/lib/frontmatter.d.ts.map +0 -1
  177. package/dist/lib/frontmatter.js.map +0 -1
  178. package/dist/lib/plugin.d.ts.map +0 -1
  179. package/dist/lib/plugin.js.map +0 -1
  180. package/dist/lib/template.d.ts.map +0 -1
  181. package/dist/lib/template.js.map +0 -1
  182. package/dist/types/index.d.ts.map +0 -1
  183. package/dist/types/index.js.map +0 -1
  184. package/dist/ui/AnalyzeUI.d.ts.map +0 -1
  185. package/dist/ui/AnalyzeUI.js.map +0 -1
  186. package/dist/ui/App.d.ts.map +0 -1
  187. package/dist/ui/App.js.map +0 -1
  188. package/dist/ui/CI.d.ts.map +0 -1
  189. package/dist/ui/CI.js.map +0 -1
  190. package/dist/ui/CIContext.d.ts.map +0 -1
  191. package/dist/ui/CIContext.js.map +0 -1
  192. package/dist/ui/CISelector.d.ts.map +0 -1
  193. package/dist/ui/CISelector.js.map +0 -1
  194. package/dist/ui/Doctor.d.ts.map +0 -1
  195. package/dist/ui/Doctor.js.map +0 -1
  196. package/dist/ui/Header.d.ts.map +0 -1
  197. package/dist/ui/Header.js.map +0 -1
  198. package/dist/ui/LlmsTxt.d.ts.map +0 -1
  199. package/dist/ui/LlmsTxt.js.map +0 -1
  200. package/dist/ui/MemorySelector.d.ts.map +0 -1
  201. package/dist/ui/MemorySelector.js.map +0 -1
  202. package/dist/ui/NameInput.d.ts.map +0 -1
  203. package/dist/ui/NameInput.js.map +0 -1
  204. package/dist/ui/OptionSelector.d.ts.map +0 -1
  205. package/dist/ui/OptionSelector.js.map +0 -1
  206. package/dist/ui/Plugin.d.ts.map +0 -1
  207. package/dist/ui/Plugin.js.map +0 -1
  208. package/dist/ui/Progress.d.ts.map +0 -1
  209. package/dist/ui/Progress.js.map +0 -1
  210. package/dist/ui/StackSelector.d.ts.map +0 -1
  211. package/dist/ui/StackSelector.js.map +0 -1
  212. package/dist/ui/Summary.d.ts.map +0 -1
  213. package/dist/ui/Summary.js.map +0 -1
  214. package/dist/ui/Welcome.d.ts.map +0 -1
  215. package/dist/ui/Welcome.js.map +0 -1
  216. package/dist/ui/theme.d.ts.map +0 -1
  217. package/dist/ui/theme.js.map +0 -1
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Agent Teams parallel dispatch presets — predefined team configurations
3
+ * for common workflows like review, debug, and security scanning.
4
+ *
5
+ * Each preset defines which sub-agents to spawn in parallel, their roles,
6
+ * and how to aggregate results.
7
+ */
8
+ // ── Built-in presets ──
9
+ export const TEAM_PRESETS = {
10
+ review: {
11
+ name: "review",
12
+ description: "Multi-perspective code review team",
13
+ roles: [
14
+ {
15
+ id: "quality",
16
+ name: "Quality Reviewer",
17
+ skill: "adversarial-review",
18
+ perspective: "code quality, readability, maintainability",
19
+ priority: "high",
20
+ },
21
+ {
22
+ id: "security",
23
+ name: "Security Auditor",
24
+ skill: "adversarial-review",
25
+ perspective: "security vulnerabilities, injection, auth",
26
+ priority: "critical",
27
+ },
28
+ {
29
+ id: "testing",
30
+ name: "Test Reviewer",
31
+ skill: "testing:test-coverage",
32
+ perspective: "test coverage, edge cases, test quality",
33
+ priority: "medium",
34
+ },
35
+ ],
36
+ aggregation: "all-must-pass",
37
+ maxParallel: 3,
38
+ },
39
+ debug: {
40
+ name: "debug",
41
+ description: "Parallel debugging team",
42
+ roles: [
43
+ {
44
+ id: "hypothesis",
45
+ name: "Hypothesis Generator",
46
+ skill: "debug-mode",
47
+ perspective: "generate and rank failure hypotheses",
48
+ priority: "high",
49
+ },
50
+ {
51
+ id: "logs",
52
+ name: "Log Analyzer",
53
+ skill: "debug-mode",
54
+ perspective: "parse logs, stack traces, error patterns",
55
+ priority: "high",
56
+ },
57
+ {
58
+ id: "repro",
59
+ name: "Reproducer",
60
+ skill: "testing:e2e",
61
+ perspective: "create minimal reproduction steps",
62
+ priority: "medium",
63
+ },
64
+ ],
65
+ aggregation: "any-pass",
66
+ maxParallel: 3,
67
+ },
68
+ security: {
69
+ name: "security",
70
+ description: "Security scanning team",
71
+ roles: [
72
+ {
73
+ id: "sast",
74
+ name: "SAST Scanner",
75
+ skill: "adversarial-review",
76
+ perspective: "static analysis, code patterns, OWASP",
77
+ priority: "critical",
78
+ },
79
+ {
80
+ id: "deps",
81
+ name: "Dependency Auditor",
82
+ skill: "adversarial-review",
83
+ perspective: "supply chain, outdated deps, known CVEs",
84
+ priority: "critical",
85
+ },
86
+ {
87
+ id: "secrets",
88
+ name: "Secret Scanner",
89
+ skill: "adversarial-review",
90
+ perspective: "hardcoded secrets, API keys, credentials",
91
+ priority: "critical",
92
+ },
93
+ ],
94
+ aggregation: "all-must-pass",
95
+ maxParallel: 3,
96
+ },
97
+ "tdd-cycle": {
98
+ name: "tdd-cycle",
99
+ description: "TDD pipeline team",
100
+ roles: [
101
+ {
102
+ id: "test-writer",
103
+ name: "Test Writer",
104
+ skill: "testing:tdd",
105
+ perspective: "write failing tests first",
106
+ priority: "high",
107
+ },
108
+ {
109
+ id: "implementer",
110
+ name: "Implementer",
111
+ skill: "sdd-apply",
112
+ perspective: "make tests pass with minimal code",
113
+ priority: "high",
114
+ },
115
+ {
116
+ id: "refactorer",
117
+ name: "Refactorer",
118
+ skill: "refactoring:cleanup",
119
+ perspective: "clean up without breaking tests",
120
+ priority: "medium",
121
+ },
122
+ ],
123
+ aggregation: "all-must-pass",
124
+ maxParallel: 1, // sequential for TDD
125
+ },
126
+ };
127
+ // ── Preset management ──
128
+ export function getPreset(name) {
129
+ return TEAM_PRESETS[name] ?? null;
130
+ }
131
+ export function listPresets() {
132
+ return Object.values(TEAM_PRESETS).map((p) => ({
133
+ name: p.name,
134
+ description: p.description,
135
+ roleCount: p.roles.length,
136
+ }));
137
+ }
138
+ // ── Dispatch creation ──
139
+ export function createDispatch(presetName, targetFiles, context = {}) {
140
+ const preset = getPreset(presetName);
141
+ if (!preset)
142
+ return null;
143
+ return {
144
+ preset: presetName,
145
+ roles: preset.roles,
146
+ targetFiles,
147
+ context,
148
+ };
149
+ }
150
+ // ── Result aggregation ──
151
+ export function aggregateResults(preset, results) {
152
+ const totalDurationMs = Math.max(...results.map((r) => r.durationMs), 0);
153
+ let passed;
154
+ switch (preset.aggregation) {
155
+ case "all-must-pass":
156
+ passed = results.every((r) => r.passed);
157
+ break;
158
+ case "majority":
159
+ passed = results.filter((r) => r.passed).length > results.length / 2;
160
+ break;
161
+ case "any-pass":
162
+ passed = results.some((r) => r.passed);
163
+ break;
164
+ }
165
+ const criticalFindings = results
166
+ .filter((r) => r.severity === "critical" && !r.passed)
167
+ .flatMap((r) => r.findings);
168
+ const summary = passed
169
+ ? `All ${results.length} agents passed.`
170
+ : `${results.filter((r) => !r.passed).length}/${results.length} agents reported issues.${criticalFindings.length > 0 ? ` ${criticalFindings.length} critical findings.` : ""}`;
171
+ return {
172
+ preset: preset.name,
173
+ passed,
174
+ agents: results,
175
+ totalDurationMs,
176
+ summary,
177
+ };
178
+ }
179
+ // ── Formatting ──
180
+ export function formatTeamResult(result) {
181
+ const icon = result.passed ? "✅" : "❌";
182
+ const lines = [
183
+ `${icon} Team: ${result.preset} — ${result.summary}`,
184
+ "",
185
+ ];
186
+ for (const agent of result.agents) {
187
+ const aIcon = agent.passed ? "✓" : "✗";
188
+ const dur = `${(agent.durationMs / 1000).toFixed(1)}s`;
189
+ lines.push(` ${aIcon} ${agent.roleName} [${agent.severity}] ${dur}`);
190
+ if (agent.findings.length > 0) {
191
+ for (const f of agent.findings.slice(0, 3)) {
192
+ lines.push(` - ${f}`);
193
+ }
194
+ if (agent.findings.length > 3) {
195
+ lines.push(` ... +${agent.findings.length - 3} more`);
196
+ }
197
+ }
198
+ }
199
+ return lines.join("\n");
200
+ }
201
+ //# sourceMappingURL=team-presets.js.map
@@ -0,0 +1,23 @@
1
+ import type { InitStep } from "../types/index.js";
2
+ export type WorkflowAction = "show" | "validate" | "list";
3
+ type StepCallback = (step: InitStep) => void;
4
+ /**
5
+ * Show a workflow graph as ASCII art.
6
+ */
7
+ export declare function runWorkflowShow(projectDir: string, onStep: StepCallback, options?: {
8
+ target?: string;
9
+ template?: string;
10
+ }): Promise<string | null>;
11
+ /**
12
+ * Validate a project against a workflow graph.
13
+ */
14
+ export declare function runWorkflowValidate(projectDir: string, onStep: StepCallback, options?: {
15
+ target?: string;
16
+ template?: string;
17
+ }): Promise<string | null>;
18
+ /**
19
+ * List available workflows (project + built-in templates).
20
+ */
21
+ export declare function runWorkflowList(projectDir: string, onStep: StepCallback): Promise<string>;
22
+ export {};
23
+ //# sourceMappingURL=workflow.d.ts.map
@@ -0,0 +1,114 @@
1
+ import fs from "fs-extra";
2
+ import { discoverWorkflows, getAvailableChecks, listBuiltinTemplates, loadBuiltinTemplate, parseDot, parseMermaid, renderAscii, validateWorkflow, } from "../lib/workflow/index.js";
3
+ function report(onStep, id, label, status, detail) {
4
+ onStep({ id, label, status, detail });
5
+ }
6
+ /**
7
+ * Resolve a workflow graph from either a file path or a built-in template name.
8
+ */
9
+ async function resolveGraph(target, projectDir, template, onStep) {
10
+ // Option 1: Built-in template
11
+ if (template) {
12
+ report(onStep, "resolve", `Loading template: ${template}`, "running");
13
+ const tpl = await loadBuiltinTemplate(template);
14
+ if (!tpl) {
15
+ report(onStep, "resolve", `Loading template: ${template}`, "error", `Template "${template}" not found`);
16
+ return null;
17
+ }
18
+ const parser = tpl.format === "dot" ? parseDot : parseMermaid;
19
+ const graph = parser(tpl.content, template);
20
+ report(onStep, "resolve", `Loading template: ${template}`, "done", `${graph.nodes.length} nodes, ${graph.edges.length} edges`);
21
+ return graph;
22
+ }
23
+ // Option 2: Explicit file path
24
+ if (target) {
25
+ report(onStep, "resolve", `Loading workflow: ${target}`, "running");
26
+ if (!(await fs.pathExists(target))) {
27
+ report(onStep, "resolve", `Loading workflow: ${target}`, "error", "File not found");
28
+ return null;
29
+ }
30
+ const content = await fs.readFile(target, "utf-8");
31
+ const isDot = target.endsWith(".dot");
32
+ const parser = isDot ? parseDot : parseMermaid;
33
+ const name = target
34
+ .split("/")
35
+ .pop()
36
+ ?.replace(/\.\w+$/, "") ?? "workflow";
37
+ const graph = parser(content, name);
38
+ report(onStep, "resolve", `Loading workflow: ${target}`, "done", `${graph.nodes.length} nodes, ${graph.edges.length} edges`);
39
+ return graph;
40
+ }
41
+ // Option 3: Auto-discover first workflow in project
42
+ report(onStep, "resolve", "Discovering workflows", "running");
43
+ const discovered = await discoverWorkflows(projectDir);
44
+ if (discovered.length === 0) {
45
+ report(onStep, "resolve", "Discovering workflows", "error", "No workflows found in .javi-forge/workflows/");
46
+ return null;
47
+ }
48
+ const first = discovered[0];
49
+ const content = await fs.readFile(first.path, "utf-8");
50
+ const parser = first.format === "dot" ? parseDot : parseMermaid;
51
+ const graph = parser(content, first.name);
52
+ report(onStep, "resolve", "Discovering workflows", "done", `Using ${first.name} (${graph.nodes.length} nodes)`);
53
+ return graph;
54
+ }
55
+ /**
56
+ * Show a workflow graph as ASCII art.
57
+ */
58
+ export async function runWorkflowShow(projectDir, onStep, options = {}) {
59
+ const graph = await resolveGraph(options.target, projectDir, options.template, onStep);
60
+ if (!graph)
61
+ return null;
62
+ report(onStep, "render", "Rendering graph", "running");
63
+ const ascii = renderAscii(graph);
64
+ report(onStep, "render", "Rendering graph", "done");
65
+ return ascii;
66
+ }
67
+ /**
68
+ * Validate a project against a workflow graph.
69
+ */
70
+ export async function runWorkflowValidate(projectDir, onStep, options = {}) {
71
+ const graph = await resolveGraph(options.target, projectDir, options.template, onStep);
72
+ if (!graph)
73
+ return null;
74
+ report(onStep, "validate", "Validating workflow", "running");
75
+ const results = await validateWorkflow(graph, projectDir);
76
+ report(onStep, "validate", "Validating workflow", "done");
77
+ const ascii = renderAscii(graph, results);
78
+ return ascii;
79
+ }
80
+ /**
81
+ * List available workflows (project + built-in templates).
82
+ */
83
+ export async function runWorkflowList(projectDir, onStep) {
84
+ report(onStep, "list", "Listing workflows", "running");
85
+ const project = await discoverWorkflows(projectDir);
86
+ const builtin = await listBuiltinTemplates();
87
+ const checks = getAvailableChecks();
88
+ const lines = [];
89
+ if (project.length > 0) {
90
+ lines.push("Project workflows (.javi-forge/workflows/):");
91
+ for (const w of project) {
92
+ lines.push(` - ${w.name} (${w.format})`);
93
+ }
94
+ }
95
+ else {
96
+ lines.push("No project workflows found.");
97
+ lines.push(" Create .javi-forge/workflows/*.dot or *.mermaid");
98
+ }
99
+ lines.push("");
100
+ if (builtin.length > 0) {
101
+ lines.push("Built-in templates (use --template <name>):");
102
+ for (const t of builtin) {
103
+ lines.push(` - ${t.name} (${t.format})`);
104
+ }
105
+ }
106
+ lines.push("");
107
+ lines.push("Available validation checks:");
108
+ for (const c of checks) {
109
+ lines.push(` - ${c}`);
110
+ }
111
+ report(onStep, "list", "Listing workflows", "done");
112
+ return lines.join("\n");
113
+ }
114
+ //# sourceMappingURL=workflow.js.map
@@ -1,3 +1,4 @@
1
+ import type { HookProfile, StackClaudeMdEntry, StackContextEntry } from "./types/index.js";
1
2
  /** Root of the javi-forge package (one level up from dist/) */
2
3
  export declare const FORGE_ROOT: string;
3
4
  /** Templates directory */
@@ -8,6 +9,10 @@ export declare const MODULES_DIR: string;
8
9
  export declare const WORKFLOWS_DIR: string;
9
10
  /** CI-local directory */
10
11
  export declare const CI_LOCAL_DIR: string;
12
+ /** Security hooks template directory */
13
+ export declare const SECURITY_HOOKS_DIR: string;
14
+ /** Local AI stack template directory */
15
+ export declare const LOCAL_AI_TEMPLATE_DIR: string;
11
16
  /** Dependabot fragment directory */
12
17
  export declare const DEPENDABOT_FRAGMENTS_DIR: string;
13
18
  /** Plugins directory (installed plugins) */
@@ -18,8 +23,24 @@ export declare const PLUGIN_REGISTRY_URL = "https://raw.githubusercontent.com/JN
18
23
  export declare const PLUGIN_MANIFEST_FILE = "plugin.json";
19
24
  /** Valid plugin asset directories */
20
25
  export declare const PLUGIN_ASSET_DIRS: readonly ["skills", "commands", "hooks", "agents"];
26
+ /** Agent Skills spec manifest filename */
27
+ export declare const AGENT_SKILLS_MANIFEST_FILE = "skills.json";
21
28
  /** Stack-to-dependabot fragment mapping */
22
29
  export declare const STACK_DEPENDABOT_MAP: Record<string, string[]>;
30
+ /** Stack-to-CLAUDE.md metadata mapping */
31
+ export declare const STACK_CLAUDEMD_MAP: Record<string, StackClaudeMdEntry>;
32
+ /** Stack-to-context template mapping */
33
+ export declare const STACK_CONTEXT_MAP: Record<string, StackContextEntry>;
34
+ /** Deploy template filename mapping (per CI provider) */
35
+ export declare const DEPLOY_TEMPLATE_MAP: Record<string, string>;
36
+ /** Deploy destination path mapping (per CI provider) */
37
+ export declare const DEPLOY_DESTINATION_MAP: Record<string, string>;
38
+ /** Hook reliability profile definitions */
39
+ export declare const HOOK_PROFILES: Record<HookProfile, {
40
+ label: string;
41
+ description: string;
42
+ hooks: string[];
43
+ }>;
23
44
  /** Stack-to-CI template filename mapping */
24
45
  export declare const STACK_CI_MAP: Record<string, Record<string, string>>;
25
46
  //# sourceMappingURL=constants.d.ts.map
package/dist/constants.js CHANGED
@@ -1,61 +1,232 @@
1
- import path from 'path';
2
- import { fileURLToPath } from 'url';
1
+ import path from "path";
2
+ import { fileURLToPath } from "url";
3
3
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
4
4
  /** Root of the javi-forge package (one level up from dist/) */
5
- export const FORGE_ROOT = path.resolve(__dirname, '..');
5
+ export const FORGE_ROOT = path.resolve(__dirname, "..");
6
6
  /** Templates directory */
7
- export const TEMPLATES_DIR = path.join(FORGE_ROOT, 'templates');
7
+ export const TEMPLATES_DIR = path.join(FORGE_ROOT, "templates");
8
8
  /** Modules directory */
9
- export const MODULES_DIR = path.join(FORGE_ROOT, 'modules');
9
+ export const MODULES_DIR = path.join(FORGE_ROOT, "modules");
10
10
  /** Workflows directory */
11
- export const WORKFLOWS_DIR = path.join(FORGE_ROOT, 'workflows');
11
+ export const WORKFLOWS_DIR = path.join(FORGE_ROOT, "workflows");
12
12
  /** CI-local directory */
13
- export const CI_LOCAL_DIR = path.join(FORGE_ROOT, 'ci-local');
13
+ export const CI_LOCAL_DIR = path.join(FORGE_ROOT, "ci-local");
14
+ /** Security hooks template directory */
15
+ export const SECURITY_HOOKS_DIR = path.join(TEMPLATES_DIR, "security-hooks");
16
+ /** Local AI stack template directory */
17
+ export const LOCAL_AI_TEMPLATE_DIR = path.join(TEMPLATES_DIR, "local-ai");
14
18
  /** Dependabot fragment directory */
15
- export const DEPENDABOT_FRAGMENTS_DIR = path.join(TEMPLATES_DIR, 'common', 'dependabot');
19
+ export const DEPENDABOT_FRAGMENTS_DIR = path.join(TEMPLATES_DIR, "common", "dependabot");
16
20
  /** Plugins directory (installed plugins) */
17
- export const PLUGINS_DIR = path.join(FORGE_ROOT, 'plugins');
21
+ export const PLUGINS_DIR = path.join(FORGE_ROOT, "plugins");
18
22
  /** Plugin registry URL */
19
- export const PLUGIN_REGISTRY_URL = 'https://raw.githubusercontent.com/JNZader/javi-forge-registry/main/registry.json';
23
+ export const PLUGIN_REGISTRY_URL = "https://raw.githubusercontent.com/JNZader/javi-forge-registry/main/registry.json";
20
24
  /** Plugin manifest filename */
21
- export const PLUGIN_MANIFEST_FILE = 'plugin.json';
25
+ export const PLUGIN_MANIFEST_FILE = "plugin.json";
22
26
  /** Valid plugin asset directories */
23
- export const PLUGIN_ASSET_DIRS = ['skills', 'commands', 'hooks', 'agents'];
27
+ export const PLUGIN_ASSET_DIRS = [
28
+ "skills",
29
+ "commands",
30
+ "hooks",
31
+ "agents",
32
+ ];
33
+ /** Agent Skills spec manifest filename */
34
+ export const AGENT_SKILLS_MANIFEST_FILE = "skills.json";
24
35
  /** Stack-to-dependabot fragment mapping */
25
36
  export const STACK_DEPENDABOT_MAP = {
26
- 'node': ['npm'],
27
- 'python': ['pip'],
28
- 'go': ['gomod'],
29
- 'rust': ['cargo'],
30
- 'java-gradle': ['gradle'],
31
- 'java-maven': ['maven'],
32
- 'elixir': [],
37
+ node: ["npm"],
38
+ python: ["pip"],
39
+ go: ["gomod"],
40
+ rust: ["cargo"],
41
+ "java-gradle": ["gradle"],
42
+ "java-maven": ["maven"],
43
+ elixir: [],
44
+ };
45
+ /** Stack-to-CLAUDE.md metadata mapping */
46
+ export const STACK_CLAUDEMD_MAP = {
47
+ node: {
48
+ skills: ["typescript", "react-19", "tailwind-4"],
49
+ conventions: "TypeScript strict, ESM modules, functional components",
50
+ testFramework: "vitest",
51
+ },
52
+ python: {
53
+ skills: ["pytest", "django-drf"],
54
+ conventions: "PEP 8, type hints, ruff linting",
55
+ testFramework: "pytest",
56
+ },
57
+ go: {
58
+ skills: [],
59
+ conventions: "gofmt, golangci-lint, table-driven tests",
60
+ testFramework: "go test",
61
+ },
62
+ rust: {
63
+ skills: [],
64
+ conventions: "cargo fmt, clippy, edition 2021+",
65
+ testFramework: "cargo test",
66
+ },
67
+ "java-gradle": {
68
+ skills: [],
69
+ conventions: "Gradle Kotlin DSL, JUnit 5, Checkstyle",
70
+ testFramework: "JUnit 5",
71
+ },
72
+ "java-maven": {
73
+ skills: [],
74
+ conventions: "Maven standard layout, JUnit 5, Checkstyle",
75
+ testFramework: "JUnit 5",
76
+ },
77
+ elixir: {
78
+ skills: [],
79
+ conventions: "mix format, Credo, OTP conventions",
80
+ testFramework: "ExUnit",
81
+ },
82
+ default: {
83
+ skills: [],
84
+ conventions: "Follow language-specific best practices",
85
+ testFramework: "project default",
86
+ },
87
+ };
88
+ /** Stack-to-context template mapping */
89
+ export const STACK_CONTEXT_MAP = {
90
+ node: {
91
+ tree: [
92
+ "src/ — source code",
93
+ " index.ts — entry point",
94
+ "tests/ — test suites",
95
+ "package.json — dependencies & scripts",
96
+ "tsconfig.json — TypeScript config",
97
+ ].join("\n"),
98
+ conventions: "TypeScript strict, ESM modules, vitest for testing",
99
+ entryPoint: "src/index.ts",
100
+ },
101
+ python: {
102
+ tree: [
103
+ "src/ — source packages",
104
+ " __init__.py — package root",
105
+ "tests/ — pytest suites",
106
+ "pyproject.toml — project config",
107
+ ].join("\n"),
108
+ conventions: "PEP 8, type hints, pytest, ruff for linting",
109
+ entryPoint: "src/__init__.py",
110
+ },
111
+ go: {
112
+ tree: [
113
+ "cmd/ — CLI entry points",
114
+ "internal/ — private packages",
115
+ "pkg/ — public packages",
116
+ "go.mod — module definition",
117
+ "go.sum — dependency checksums",
118
+ ].join("\n"),
119
+ conventions: "gofmt, golangci-lint, table-driven tests",
120
+ entryPoint: "cmd/main.go",
121
+ },
122
+ rust: {
123
+ tree: [
124
+ "src/ — source code",
125
+ " main.rs — entry point",
126
+ " lib.rs — library root",
127
+ "tests/ — integration tests",
128
+ "Cargo.toml — manifest & dependencies",
129
+ ].join("\n"),
130
+ conventions: "cargo fmt, clippy lints, edition 2021+",
131
+ entryPoint: "src/main.rs",
132
+ },
133
+ "java-gradle": {
134
+ tree: [
135
+ "src/main/java/ — application source",
136
+ "src/test/java/ — test source",
137
+ "src/main/resources/ — config & assets",
138
+ "build.gradle.kts — Gradle build script",
139
+ "settings.gradle.kts — project settings",
140
+ ].join("\n"),
141
+ conventions: "Gradle Kotlin DSL, JUnit 5, Checkstyle",
142
+ entryPoint: "src/main/java/Main.java",
143
+ },
144
+ "java-maven": {
145
+ tree: [
146
+ "src/main/java/ — application source",
147
+ "src/test/java/ — test source",
148
+ "src/main/resources/ — config & assets",
149
+ "pom.xml — Maven POM",
150
+ ].join("\n"),
151
+ conventions: "Maven standard layout, JUnit 5, Checkstyle",
152
+ entryPoint: "src/main/java/Main.java",
153
+ },
154
+ elixir: {
155
+ tree: [
156
+ "lib/ — application source",
157
+ " application.ex — OTP application",
158
+ "test/ — ExUnit tests",
159
+ "config/ — runtime config",
160
+ "mix.exs — project definition",
161
+ ].join("\n"),
162
+ conventions: "mix format, Credo, ExUnit, OTP conventions",
163
+ entryPoint: "lib/application.ex",
164
+ },
165
+ default: {
166
+ tree: [
167
+ "src/ — source code",
168
+ "tests/ — test suites",
169
+ "README.md — project documentation",
170
+ ].join("\n"),
171
+ conventions: "Follow language-specific best practices",
172
+ entryPoint: "src/index",
173
+ },
174
+ };
175
+ /** Deploy template filename mapping (per CI provider) */
176
+ export const DEPLOY_TEMPLATE_MAP = {
177
+ github: "deploy-docker-zero-downtime.yml",
178
+ gitlab: "deploy-docker-zero-downtime.yml",
179
+ woodpecker: "deploy-docker-zero-downtime.yml",
180
+ };
181
+ /** Deploy destination path mapping (per CI provider) */
182
+ export const DEPLOY_DESTINATION_MAP = {
183
+ github: ".github/workflows/deploy.yml",
184
+ gitlab: ".gitlab-ci-deploy.yml",
185
+ woodpecker: ".woodpecker/deploy.yml",
186
+ };
187
+ /** Hook reliability profile definitions */
188
+ export const HOOK_PROFILES = {
189
+ minimal: {
190
+ label: "Minimal",
191
+ description: "pre-commit only: lint + format check",
192
+ hooks: ["pre-commit"],
193
+ },
194
+ standard: {
195
+ label: "Standard",
196
+ description: "pre-commit + pre-push + CI gate check",
197
+ hooks: ["pre-commit", "pre-push", "ci-gate"],
198
+ },
199
+ strict: {
200
+ label: "Strict",
201
+ description: "all standard + commit-msg validation + security scan on every push",
202
+ hooks: ["pre-commit", "pre-push", "ci-gate", "commit-msg", "security-scan"],
203
+ },
33
204
  };
34
205
  /** Stack-to-CI template filename mapping */
35
206
  export const STACK_CI_MAP = {
36
207
  github: {
37
- 'node': 'ci-node.yml',
38
- 'python': 'ci-python.yml',
39
- 'go': 'ci-go.yml',
40
- 'rust': 'ci-rust.yml',
41
- 'java-gradle': 'ci-java.yml',
42
- 'java-maven': 'ci-java.yml',
208
+ node: "ci-node.yml",
209
+ python: "ci-python.yml",
210
+ go: "ci-go.yml",
211
+ rust: "ci-rust.yml",
212
+ "java-gradle": "ci-java.yml",
213
+ "java-maven": "ci-java.yml",
43
214
  },
44
215
  gitlab: {
45
- 'node': 'gitlab-ci-node.yml',
46
- 'python': 'gitlab-ci-python.yml',
47
- 'go': 'gitlab-ci-go.yml',
48
- 'rust': 'gitlab-ci-rust.yml',
49
- 'java-gradle': 'gitlab-ci-java.yml',
50
- 'java-maven': 'gitlab-ci-java.yml',
216
+ node: "gitlab-ci-node.yml",
217
+ python: "gitlab-ci-python.yml",
218
+ go: "gitlab-ci-go.yml",
219
+ rust: "gitlab-ci-rust.yml",
220
+ "java-gradle": "gitlab-ci-java.yml",
221
+ "java-maven": "gitlab-ci-java.yml",
51
222
  },
52
223
  woodpecker: {
53
- 'node': 'woodpecker-node.yml',
54
- 'python': 'woodpecker-python.yml',
55
- 'go': 'woodpecker-go.yml',
56
- 'rust': 'woodpecker-rust.yml',
57
- 'java-gradle': 'woodpecker-java.yml',
58
- 'java-maven': 'woodpecker-java.yml',
224
+ node: "woodpecker-node.yml",
225
+ python: "woodpecker-python.yml",
226
+ go: "woodpecker-go.yml",
227
+ rust: "woodpecker-rust.yml",
228
+ "java-gradle": "woodpecker-java.yml",
229
+ "java-maven": "woodpecker-java.yml",
59
230
  },
60
231
  };
61
232
  //# sourceMappingURL=constants.js.map