javi-forge 1.6.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 (231) hide show
  1. package/dist/commands/analyze.d.ts +1 -1
  2. package/dist/commands/analyze.js +15 -15
  3. package/dist/commands/atlassian-mcp.d.ts +42 -0
  4. package/dist/commands/atlassian-mcp.js +98 -0
  5. package/dist/commands/ci.d.ts +3 -3
  6. package/dist/commands/ci.js +185 -147
  7. package/dist/commands/crash-recovery.d.ts +34 -0
  8. package/dist/commands/crash-recovery.js +123 -0
  9. package/dist/commands/doctor.d.ts +2 -2
  10. package/dist/commands/doctor.js +113 -61
  11. package/dist/commands/harness-audit.d.ts +35 -0
  12. package/dist/commands/harness-audit.js +277 -0
  13. package/dist/commands/init.d.ts +1 -1
  14. package/dist/commands/init.js +384 -141
  15. package/dist/commands/llmstxt.d.ts +1 -1
  16. package/dist/commands/llmstxt.js +36 -34
  17. package/dist/commands/parallel-batch.d.ts +42 -0
  18. package/dist/commands/parallel-batch.js +90 -0
  19. package/dist/commands/plugin.d.ts +10 -1
  20. package/dist/commands/plugin.js +92 -47
  21. package/dist/commands/secret-scanner.d.ts +30 -0
  22. package/dist/commands/secret-scanner.js +272 -0
  23. package/dist/commands/security-analysis.d.ts +74 -0
  24. package/dist/commands/security-analysis.js +487 -0
  25. package/dist/commands/security.d.ts +11 -5
  26. package/dist/commands/security.js +216 -76
  27. package/dist/commands/skill-scanner.d.ts +63 -0
  28. package/dist/commands/skill-scanner.js +383 -0
  29. package/dist/commands/skills.d.ts +62 -5
  30. package/dist/commands/skills.js +439 -54
  31. package/dist/commands/supply-chain.d.ts +23 -0
  32. package/dist/commands/supply-chain.js +126 -0
  33. package/dist/commands/tdd-pipeline.d.ts +17 -0
  34. package/dist/commands/tdd-pipeline.js +144 -0
  35. package/dist/commands/tdd.d.ts +1 -1
  36. package/dist/commands/tdd.js +21 -18
  37. package/dist/commands/team-presets.d.ts +53 -0
  38. package/dist/commands/team-presets.js +201 -0
  39. package/dist/commands/workflow.d.ts +23 -0
  40. package/dist/commands/workflow.js +114 -0
  41. package/dist/constants.d.ts +15 -1
  42. package/dist/constants.js +161 -122
  43. package/dist/index.js +308 -98
  44. package/dist/lib/agent-skills.d.ts +36 -1
  45. package/dist/lib/agent-skills.js +168 -19
  46. package/dist/lib/auto-skill-install.d.ts +37 -0
  47. package/dist/lib/auto-skill-install.js +92 -0
  48. package/dist/lib/auto-wire.d.ts +20 -0
  49. package/dist/lib/auto-wire.js +240 -0
  50. package/dist/lib/claudemd.d.ts +13 -1
  51. package/dist/lib/claudemd.js +174 -24
  52. package/dist/lib/codex-export.d.ts +1 -1
  53. package/dist/lib/codex-export.js +29 -31
  54. package/dist/lib/common.d.ts +1 -1
  55. package/dist/lib/common.js +52 -44
  56. package/dist/lib/context.d.ts +17 -2
  57. package/dist/lib/context.js +142 -13
  58. package/dist/lib/docker.d.ts +1 -1
  59. package/dist/lib/docker.js +141 -112
  60. package/dist/lib/frontmatter.d.ts +1 -1
  61. package/dist/lib/frontmatter.js +29 -15
  62. package/dist/lib/plugin.d.ts +9 -3
  63. package/dist/lib/plugin.js +128 -69
  64. package/dist/lib/skill-publish.d.ts +40 -0
  65. package/dist/lib/skill-publish.js +146 -0
  66. package/dist/lib/stack-detector.d.ts +38 -0
  67. package/dist/lib/stack-detector.js +207 -0
  68. package/dist/lib/template.d.ts +16 -1
  69. package/dist/lib/template.js +46 -17
  70. package/dist/lib/workflow/discovery.d.ts +19 -0
  71. package/dist/lib/workflow/discovery.js +68 -0
  72. package/dist/lib/workflow/index.d.ts +5 -0
  73. package/dist/lib/workflow/index.js +5 -0
  74. package/dist/lib/workflow/parser.d.ts +16 -0
  75. package/dist/lib/workflow/parser.js +198 -0
  76. package/dist/lib/workflow/renderer.d.ts +9 -0
  77. package/dist/lib/workflow/renderer.js +152 -0
  78. package/dist/lib/workflow/validator.d.ts +10 -0
  79. package/dist/lib/workflow/validator.js +189 -0
  80. package/dist/tasks/index.d.ts +4 -0
  81. package/dist/tasks/index.js +4 -0
  82. package/dist/tasks/scaffold-tasks.d.ts +3 -0
  83. package/dist/tasks/scaffold-tasks.js +14 -0
  84. package/dist/tasks/task-id.d.ts +30 -0
  85. package/dist/tasks/task-id.js +55 -0
  86. package/dist/tasks/task-tracker.d.ts +15 -0
  87. package/dist/tasks/task-tracker.js +81 -0
  88. package/dist/types/index.d.ts +134 -6
  89. package/dist/types/index.js +11 -1
  90. package/dist/ui/AnalyzeUI.d.ts +1 -1
  91. package/dist/ui/AnalyzeUI.js +38 -39
  92. package/dist/ui/App.d.ts +5 -3
  93. package/dist/ui/App.js +86 -46
  94. package/dist/ui/AutoSkills.d.ts +9 -0
  95. package/dist/ui/AutoSkills.js +124 -0
  96. package/dist/ui/CI.d.ts +2 -2
  97. package/dist/ui/CI.js +24 -26
  98. package/dist/ui/CIContext.d.ts +1 -1
  99. package/dist/ui/CIContext.js +3 -2
  100. package/dist/ui/CISelector.d.ts +2 -2
  101. package/dist/ui/CISelector.js +23 -15
  102. package/dist/ui/Doctor.d.ts +1 -1
  103. package/dist/ui/Doctor.js +35 -29
  104. package/dist/ui/Header.d.ts +1 -1
  105. package/dist/ui/Header.js +14 -14
  106. package/dist/ui/HookProfileSelector.d.ts +9 -0
  107. package/dist/ui/HookProfileSelector.js +54 -0
  108. package/dist/ui/LlmsTxt.d.ts +1 -1
  109. package/dist/ui/LlmsTxt.js +31 -22
  110. package/dist/ui/MemorySelector.d.ts +2 -2
  111. package/dist/ui/MemorySelector.js +28 -16
  112. package/dist/ui/NameInput.d.ts +1 -1
  113. package/dist/ui/NameInput.js +21 -21
  114. package/dist/ui/OptionSelector.d.ts +6 -2
  115. package/dist/ui/OptionSelector.js +83 -32
  116. package/dist/ui/Plugin.d.ts +4 -3
  117. package/dist/ui/Plugin.js +78 -35
  118. package/dist/ui/Progress.d.ts +3 -3
  119. package/dist/ui/Progress.js +23 -22
  120. package/dist/ui/Skills.d.ts +2 -2
  121. package/dist/ui/Skills.js +61 -32
  122. package/dist/ui/StackSelector.d.ts +2 -2
  123. package/dist/ui/StackSelector.js +26 -16
  124. package/dist/ui/Summary.d.ts +3 -3
  125. package/dist/ui/Summary.js +60 -50
  126. package/dist/ui/Welcome.d.ts +1 -1
  127. package/dist/ui/Welcome.js +15 -16
  128. package/dist/ui/theme.d.ts +1 -1
  129. package/dist/ui/theme.js +6 -6
  130. package/package.json +9 -6
  131. package/templates/common/atlassian/mcp-atlassian-snippet.json +16 -0
  132. package/templates/common/repoforge/mcp-repoforge-snippet.json +11 -0
  133. package/templates/common/repoforge/repoforge.yaml +34 -0
  134. package/templates/github/deploy-docker-zero-downtime.yml +140 -0
  135. package/templates/github/repoforge-graph.yml +45 -0
  136. package/templates/gitlab/deploy-docker-zero-downtime.yml +57 -0
  137. package/templates/local-ai/.env.example +17 -0
  138. package/templates/local-ai/docker-compose.yml +95 -0
  139. package/templates/security-hooks/claude-settings-security.json +30 -0
  140. package/templates/security-hooks/commit-msg-signing +29 -0
  141. package/templates/security-hooks/pre-commit-permissions +74 -0
  142. package/templates/security-hooks/pre-commit-secrets +74 -0
  143. package/templates/security-hooks/pre-push-branch-protection +62 -0
  144. package/templates/security-hooks/pre-push-deps +83 -0
  145. package/templates/security-hooks/pre-push-signing +67 -0
  146. package/templates/woodpecker/deploy-docker-zero-downtime.yml +50 -0
  147. package/templates/workflows/ci-pipeline.dot +15 -0
  148. package/templates/workflows/feature-flow.dot +21 -0
  149. package/templates/workflows/release.dot +16 -0
  150. package/dist/__integration__/helpers.d.ts +0 -20
  151. package/dist/__integration__/helpers.d.ts.map +0 -1
  152. package/dist/__integration__/helpers.js +0 -31
  153. package/dist/__integration__/helpers.js.map +0 -1
  154. package/dist/commands/analyze.d.ts.map +0 -1
  155. package/dist/commands/analyze.js.map +0 -1
  156. package/dist/commands/ci.d.ts.map +0 -1
  157. package/dist/commands/ci.js.map +0 -1
  158. package/dist/commands/doctor.d.ts.map +0 -1
  159. package/dist/commands/doctor.js.map +0 -1
  160. package/dist/commands/init.d.ts.map +0 -1
  161. package/dist/commands/init.js.map +0 -1
  162. package/dist/commands/llmstxt.d.ts.map +0 -1
  163. package/dist/commands/llmstxt.js.map +0 -1
  164. package/dist/commands/plugin.d.ts.map +0 -1
  165. package/dist/commands/plugin.js.map +0 -1
  166. package/dist/commands/security.d.ts.map +0 -1
  167. package/dist/commands/security.js.map +0 -1
  168. package/dist/commands/skills.d.ts.map +0 -1
  169. package/dist/commands/skills.js.map +0 -1
  170. package/dist/commands/tdd.d.ts.map +0 -1
  171. package/dist/commands/tdd.js.map +0 -1
  172. package/dist/constants.d.ts.map +0 -1
  173. package/dist/constants.js.map +0 -1
  174. package/dist/index.d.ts.map +0 -1
  175. package/dist/index.js.map +0 -1
  176. package/dist/lib/agent-skills.d.ts.map +0 -1
  177. package/dist/lib/agent-skills.js.map +0 -1
  178. package/dist/lib/claudemd.d.ts.map +0 -1
  179. package/dist/lib/claudemd.js.map +0 -1
  180. package/dist/lib/codex-export.d.ts.map +0 -1
  181. package/dist/lib/codex-export.js.map +0 -1
  182. package/dist/lib/common.d.ts.map +0 -1
  183. package/dist/lib/common.js.map +0 -1
  184. package/dist/lib/context.d.ts.map +0 -1
  185. package/dist/lib/context.js.map +0 -1
  186. package/dist/lib/docker.d.ts.map +0 -1
  187. package/dist/lib/docker.js.map +0 -1
  188. package/dist/lib/frontmatter.d.ts.map +0 -1
  189. package/dist/lib/frontmatter.js.map +0 -1
  190. package/dist/lib/plugin.d.ts.map +0 -1
  191. package/dist/lib/plugin.js.map +0 -1
  192. package/dist/lib/template.d.ts.map +0 -1
  193. package/dist/lib/template.js.map +0 -1
  194. package/dist/types/index.d.ts.map +0 -1
  195. package/dist/types/index.js.map +0 -1
  196. package/dist/ui/AnalyzeUI.d.ts.map +0 -1
  197. package/dist/ui/AnalyzeUI.js.map +0 -1
  198. package/dist/ui/App.d.ts.map +0 -1
  199. package/dist/ui/App.js.map +0 -1
  200. package/dist/ui/CI.d.ts.map +0 -1
  201. package/dist/ui/CI.js.map +0 -1
  202. package/dist/ui/CIContext.d.ts.map +0 -1
  203. package/dist/ui/CIContext.js.map +0 -1
  204. package/dist/ui/CISelector.d.ts.map +0 -1
  205. package/dist/ui/CISelector.js.map +0 -1
  206. package/dist/ui/Doctor.d.ts.map +0 -1
  207. package/dist/ui/Doctor.js.map +0 -1
  208. package/dist/ui/Header.d.ts.map +0 -1
  209. package/dist/ui/Header.js.map +0 -1
  210. package/dist/ui/LlmsTxt.d.ts.map +0 -1
  211. package/dist/ui/LlmsTxt.js.map +0 -1
  212. package/dist/ui/MemorySelector.d.ts.map +0 -1
  213. package/dist/ui/MemorySelector.js.map +0 -1
  214. package/dist/ui/NameInput.d.ts.map +0 -1
  215. package/dist/ui/NameInput.js.map +0 -1
  216. package/dist/ui/OptionSelector.d.ts.map +0 -1
  217. package/dist/ui/OptionSelector.js.map +0 -1
  218. package/dist/ui/Plugin.d.ts.map +0 -1
  219. package/dist/ui/Plugin.js.map +0 -1
  220. package/dist/ui/Progress.d.ts.map +0 -1
  221. package/dist/ui/Progress.js.map +0 -1
  222. package/dist/ui/Skills.d.ts.map +0 -1
  223. package/dist/ui/Skills.js.map +0 -1
  224. package/dist/ui/StackSelector.d.ts.map +0 -1
  225. package/dist/ui/StackSelector.js.map +0 -1
  226. package/dist/ui/Summary.d.ts.map +0 -1
  227. package/dist/ui/Summary.js.map +0 -1
  228. package/dist/ui/Welcome.d.ts.map +0 -1
  229. package/dist/ui/Welcome.js.map +0 -1
  230. package/dist/ui/theme.d.ts.map +0 -1
  231. package/dist/ui/theme.js.map +0 -1
@@ -1,6 +1,7 @@
1
- export type Stack = 'node' | 'python' | 'go' | 'rust' | 'java-gradle' | 'java-maven' | 'elixir';
2
- export type CIProvider = 'github' | 'gitlab' | 'woodpecker';
3
- export type MemoryOption = 'engram' | 'obsidian-brain' | 'memory-simple' | 'none';
1
+ export type Stack = "node" | "python" | "go" | "rust" | "java-gradle" | "java-maven" | "elixir";
2
+ export type CIProvider = "github" | "gitlab" | "woodpecker";
3
+ export type MemoryOption = "engram" | "obsidian-brain" | "memory-simple" | "none";
4
+ export type HookProfile = "minimal" | "standard" | "strict";
4
5
  export interface InitOptions {
5
6
  projectName: string;
6
7
  projectDir: string;
@@ -13,6 +14,14 @@ export interface InitOptions {
13
14
  mock: boolean;
14
15
  contextDir: boolean;
15
16
  claudeMd: boolean;
17
+ securityHooks: boolean;
18
+ hookProfile: HookProfile;
19
+ codeGraph: boolean;
20
+ dockerDeploy: boolean;
21
+ /** Service name for docker rollout (default: 'app') */
22
+ dockerServiceName: string;
23
+ /** Scaffold local AI dev stack (Ollama + optional services) */
24
+ localAi: boolean;
16
25
  dryRun: boolean;
17
26
  }
18
27
  export interface StackClaudeMdEntry {
@@ -28,7 +37,7 @@ export interface StackContextEntry {
28
37
  export interface InitStep {
29
38
  id: string;
30
39
  label: string;
31
- status: 'pending' | 'running' | 'done' | 'error' | 'skipped';
40
+ status: "pending" | "running" | "done" | "error" | "skipped";
32
41
  detail?: string;
33
42
  }
34
43
  export interface StackDetection {
@@ -48,7 +57,7 @@ export interface ForgeManifest {
48
57
  }
49
58
  export interface DoctorCheck {
50
59
  label: string;
51
- status: 'ok' | 'fail' | 'skip';
60
+ status: "ok" | "fail" | "skip";
52
61
  detail?: string;
53
62
  }
54
63
  export interface DoctorSection {
@@ -58,6 +67,13 @@ export interface DoctorSection {
58
67
  export interface DoctorResult {
59
68
  sections: DoctorSection[];
60
69
  }
70
+ export type TddPipelineMode = "strict" | "warn";
71
+ export interface TddPipelineResult {
72
+ installed: string[];
73
+ skipped: string[];
74
+ errors: string[];
75
+ mode: TddPipelineMode;
76
+ }
61
77
  export interface PluginManifest {
62
78
  name: string;
63
79
  version: string;
@@ -103,6 +119,21 @@ export interface PluginSyncResult {
103
119
  added: string[];
104
120
  removed: string[];
105
121
  unchanged: string[];
122
+ wired: AutoWireEntry[];
123
+ unwired: AutoWireEntry[];
124
+ }
125
+ export type AutoWireTarget = "claude-md" | "settings-json";
126
+ export interface AutoWireEntry {
127
+ plugin: string;
128
+ target: AutoWireTarget;
129
+ capability: string;
130
+ /** e.g. skill path or hook command */
131
+ value: string;
132
+ }
133
+ export interface AutoWireResult {
134
+ wired: AutoWireEntry[];
135
+ unwired: AutoWireEntry[];
136
+ errors: string[];
106
137
  }
107
138
  export interface AgentSkillEntry {
108
139
  name: string;
@@ -118,6 +149,22 @@ export interface AgentSkillsManifest {
118
149
  forge_source?: string;
119
150
  };
120
151
  }
152
+ /**
153
+ * Aggregated skills.json that merges multiple plugins into a single
154
+ * Agent Skills spec manifest. Used by `npx skills add` and 40+ AI agents.
155
+ */
156
+ export interface AggregatedSkillsManifest {
157
+ name: string;
158
+ version: string;
159
+ description: string;
160
+ skills: AgentSkillEntry[];
161
+ sources: AgentSkillSource[];
162
+ }
163
+ export interface AgentSkillSource {
164
+ plugin: string;
165
+ version: string;
166
+ repository?: string;
167
+ }
121
168
  export interface CodexTomlEntry {
122
169
  name: string;
123
170
  model: string;
@@ -128,7 +175,7 @@ export interface CodexExportResult {
128
175
  files?: string[];
129
176
  error?: string;
130
177
  }
131
- export type SecuritySeverity = 'critical' | 'high' | 'moderate' | 'low' | 'info';
178
+ export type SecuritySeverity = "critical" | "high" | "moderate" | "low" | "info";
132
179
  export interface SecurityFinding {
133
180
  id: string;
134
181
  severity: SecuritySeverity;
@@ -139,16 +186,33 @@ export interface SecurityFinding {
139
186
  export interface SecurityBaseline {
140
187
  version: string;
141
188
  createdAt: string;
189
+ updatedAt?: string;
142
190
  stack: string;
143
191
  buildTool: string;
144
192
  findings: SecurityFinding[];
145
193
  findingKeys: string[];
194
+ allowlist?: string[];
195
+ }
196
+ export interface SecurityCheckOptions {
197
+ minSeverity?: SecuritySeverity;
198
+ staleDays?: number;
146
199
  }
147
200
  export interface SecurityCheckResult {
148
201
  baseline: SecurityBaseline;
149
202
  current: SecurityFinding[];
150
203
  regressions: SecurityFinding[];
151
204
  resolved: SecurityFinding[];
205
+ filteredRegressions: SecurityFinding[];
206
+ staleWarning?: string;
207
+ summary: SecuritySummary;
208
+ }
209
+ export interface SecuritySummary {
210
+ total: number;
211
+ bySeverity: Record<SecuritySeverity, number>;
212
+ regressionCount: number;
213
+ resolvedCount: number;
214
+ filteredCount: number;
215
+ baselineAge: number;
152
216
  }
153
217
  export interface SkillCriticalRule {
154
218
  skillName: string;
@@ -157,22 +221,37 @@ export interface SkillCriticalRule {
157
221
  /** Normalized rule for comparison (lowercase, trimmed) */
158
222
  normalized: string;
159
223
  }
224
+ export type ConflictKind = "regex-pair" | "directive-clash";
160
225
  export interface SkillConflict {
161
226
  ruleA: SkillCriticalRule;
162
227
  ruleB: SkillCriticalRule;
163
228
  reason: string;
229
+ /** How the conflict was detected */
230
+ kind: ConflictKind;
164
231
  }
165
232
  export interface SkillBudgetEntry {
166
233
  skillName: string;
167
234
  skillPath: string;
168
235
  tokens: number;
169
236
  }
237
+ export interface SkillBudgetSuggestion {
238
+ /** Skills to disable in this suggestion set */
239
+ disableSkills: string[];
240
+ /** Total tokens freed by disabling these skills */
241
+ tokensSaved: number;
242
+ /** Remaining tokens after disabling */
243
+ remainingTokens: number;
244
+ /** Whether this set brings usage under budget */
245
+ meetsbudget: boolean;
246
+ }
170
247
  export interface SkillBudgetResult {
171
248
  entries: SkillBudgetEntry[];
172
249
  totalTokens: number;
173
250
  budget: number;
174
251
  overBudget: boolean;
175
252
  suggestions: string[];
253
+ /** Structured optimization sets: minimal combinations to meet budget */
254
+ optimizations: SkillBudgetSuggestion[];
176
255
  }
177
256
  export interface SkillDuplicate {
178
257
  skillA: string;
@@ -186,16 +265,26 @@ export interface SkillDoctorResult {
186
265
  budget: SkillBudgetResult;
187
266
  duplicates: SkillDuplicate[];
188
267
  }
268
+ export type SkillGrade = "A" | "B" | "C" | "D" | "F";
189
269
  export interface SkillScore {
190
270
  skillName: string;
191
271
  completeness: number;
192
272
  clarity: number;
193
273
  testability: number;
194
274
  tokenEfficiency: number;
275
+ safety: number;
276
+ agentReadiness: number;
195
277
  overall: number;
278
+ grade: SkillGrade;
196
279
  threshold: number;
197
280
  passing: boolean;
198
281
  }
282
+ export interface SkillRegistryGateResult {
283
+ skillName: string;
284
+ score: SkillScore;
285
+ accepted: boolean;
286
+ reason?: string;
287
+ }
199
288
  export interface SkillBenchmarkCheck {
200
289
  name: string;
201
290
  passed: boolean;
@@ -206,4 +295,43 @@ export interface SkillBenchmarkResult {
206
295
  checks: SkillBenchmarkCheck[];
207
296
  passRate: number;
208
297
  }
298
+ declare const WORKFLOW_FORMAT: {
299
+ readonly DOT: "dot";
300
+ readonly MERMAID: "mermaid";
301
+ };
302
+ export type WorkflowFormat = (typeof WORKFLOW_FORMAT)[keyof typeof WORKFLOW_FORMAT];
303
+ declare const WORKFLOW_VALIDATION_STATUS: {
304
+ readonly PASS: "pass";
305
+ readonly FAIL: "fail";
306
+ readonly SKIP: "skip";
307
+ };
308
+ export type WorkflowValidationStatus = (typeof WORKFLOW_VALIDATION_STATUS)[keyof typeof WORKFLOW_VALIDATION_STATUS];
309
+ export { WORKFLOW_FORMAT, WORKFLOW_VALIDATION_STATUS };
310
+ export interface WorkflowNode {
311
+ id: string;
312
+ label: string;
313
+ check?: string;
314
+ metadata?: Record<string, string>;
315
+ }
316
+ export interface WorkflowEdge {
317
+ from: string;
318
+ to: string;
319
+ label?: string;
320
+ }
321
+ export interface WorkflowGraph {
322
+ name: string;
323
+ nodes: WorkflowNode[];
324
+ edges: WorkflowEdge[];
325
+ format: WorkflowFormat;
326
+ }
327
+ export interface WorkflowValidationResult {
328
+ node: string;
329
+ status: WorkflowValidationStatus;
330
+ detail?: string;
331
+ }
332
+ export interface WorkflowDiscoveryEntry {
333
+ name: string;
334
+ path: string;
335
+ format: WorkflowFormat;
336
+ }
209
337
  //# sourceMappingURL=index.d.ts.map
@@ -1,2 +1,12 @@
1
- export {};
1
+ // ── Workflow Graphs ─────────────────────────────────────────────────────────
2
+ const WORKFLOW_FORMAT = {
3
+ DOT: "dot",
4
+ MERMAID: "mermaid",
5
+ };
6
+ const WORKFLOW_VALIDATION_STATUS = {
7
+ PASS: "pass",
8
+ FAIL: "fail",
9
+ SKIP: "skip",
10
+ };
11
+ export { WORKFLOW_FORMAT, WORKFLOW_VALIDATION_STATUS };
2
12
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React from "react";
2
2
  interface Props {
3
3
  dryRun: boolean;
4
4
  }
@@ -1,10 +1,10 @@
1
- import React, { useEffect, useState } from 'react';
2
- import { Box, Text, useApp, useInput } from 'ink';
3
- import Spinner from 'ink-spinner';
4
- import { runAnalyze } from '../commands/analyze.js';
5
- import Header from './Header.js';
6
- import { theme } from './theme.js';
7
- import { useCIMode } from './CIContext.js';
1
+ import { Box, Text, useApp, useInput } from "ink";
2
+ import Spinner from "ink-spinner";
3
+ import React, { useEffect, useState } from "react";
4
+ import { runAnalyze } from "../commands/analyze.js";
5
+ import { useCIMode } from "./CIContext.js";
6
+ import Header from "./Header.js";
7
+ import { theme } from "./theme.js";
8
8
  export default function AnalyzeUI({ dryRun }) {
9
9
  const { exit } = useApp();
10
10
  const isCI = useCIMode();
@@ -12,8 +12,8 @@ export default function AnalyzeUI({ dryRun }) {
12
12
  const [finished, setFinished] = useState(false);
13
13
  const [startTime] = useState(Date.now());
14
14
  useEffect(() => {
15
- runAnalyze(process.cwd(), dryRun, (step) => setSteps(prev => {
16
- const idx = prev.findIndex(s => s.id === step.id);
15
+ runAnalyze(process.cwd(), dryRun, (step) => setSteps((prev) => {
16
+ const idx = prev.findIndex((s) => s.id === step.id);
17
17
  if (idx >= 0) {
18
18
  const next = [...prev];
19
19
  next[idx] = step;
@@ -34,9 +34,9 @@ export default function AnalyzeUI({ dryRun }) {
34
34
  if (finished && (key.return || key.escape))
35
35
  exit();
36
36
  }, { isActive: !isCI });
37
- const doneCount = steps.filter(s => s.status === 'done').length;
38
- const errorCount = steps.filter(s => s.status === 'error').length;
39
- const notInstalled = steps.some(s => s.status === 'error' && s.detail?.includes('not found'));
37
+ const doneCount = steps.filter((s) => s.status === "done").length;
38
+ const errorCount = steps.filter((s) => s.status === "error").length;
39
+ const notInstalled = steps.some((s) => s.status === "error" && s.detail?.includes("not found"));
40
40
  const elapsed = finished
41
41
  ? `${((Date.now() - startTime) / 1000).toFixed(1)}s`
42
42
  : null;
@@ -45,52 +45,51 @@ export default function AnalyzeUI({ dryRun }) {
45
45
  !finished && steps.length === 0 && (React.createElement(Box, { marginLeft: 2 },
46
46
  React.createElement(Text, { color: theme.warning },
47
47
  React.createElement(Spinner, { type: "dots" }),
48
- ' ',
49
- "Checking for repoforge..."))),
50
- React.createElement(Box, { flexDirection: "column" }, steps.map(step => (React.createElement(Box, { key: step.id, marginLeft: 2 }, step.status === 'running' ? (React.createElement(Text, { color: theme.warning },
48
+ " Checking for repoforge..."))),
49
+ React.createElement(Box, { flexDirection: "column" }, steps.map((step) => (React.createElement(Box, { key: step.id, marginLeft: 2 }, step.status === "running" ? (React.createElement(Text, { color: theme.warning },
51
50
  React.createElement(Spinner, { type: "dots" }),
52
- ' ',
53
- step.label)) : step.status === 'done' ? (React.createElement(Text, { color: theme.success },
54
- '\u2713',
51
+ " ",
52
+ step.label)) : step.status === "done" ? (React.createElement(Text, { color: theme.success },
53
+ "\u2713",
55
54
  " ",
56
55
  step.label,
57
- step.detail && React.createElement(Text, { color: theme.muted, dimColor: true },
58
- " ",
59
- step.detail))) : step.status === 'error' ? (React.createElement(Text, { color: theme.error },
60
- '\u2717',
56
+ step.detail && (React.createElement(Text, { color: theme.muted, dimColor: true },
57
+ " ",
58
+ step.detail)))) : step.status === "error" ? (React.createElement(Text, { color: theme.error },
59
+ "\u2717",
61
60
  " ",
62
61
  step.label,
63
- step.detail && React.createElement(Text, { color: theme.muted, dimColor: true },
64
- " ",
65
- step.detail))) : (React.createElement(Text, { color: theme.muted },
66
- '\u2013',
62
+ step.detail && (React.createElement(Text, { color: theme.muted, dimColor: true },
63
+ " ",
64
+ step.detail)))) : (React.createElement(Text, { color: theme.muted },
65
+ "\u2013",
67
66
  " ",
68
67
  step.label,
69
68
  step.detail && React.createElement(Text, { dimColor: true },
70
- " ",
69
+ " ",
71
70
  step.detail))))))),
72
71
  finished && notInstalled && (React.createElement(Box, { marginTop: 1, flexDirection: "column", marginLeft: 2 },
73
72
  React.createElement(Text, { color: theme.warning, bold: true }, "repoforge is not installed"),
74
73
  React.createElement(Box, { marginTop: 1, flexDirection: "column" },
75
- React.createElement(Text, { color: theme.muted }, " Install it with:"),
76
- React.createElement(Text, { color: theme.primary }, " pip install repoforge"),
77
- React.createElement(Text, { color: theme.muted }, " Then run:"),
78
- React.createElement(Text, { color: theme.primary }, " javi-forge analyze")))),
74
+ React.createElement(Text, { color: theme.muted }, " Install it with:"),
75
+ React.createElement(Text, { color: theme.primary }, " pip install repoforge"),
76
+ React.createElement(Text, { color: theme.muted }, " Then run:"),
77
+ React.createElement(Text, { color: theme.primary }, " javi-forge analyze")))),
79
78
  finished && (React.createElement(Box, { marginTop: 1, flexDirection: "column" },
80
79
  React.createElement(Text, { bold: true, color: errorCount > 0 ? theme.warning : theme.success },
81
- dryRun ? '\u25cb Dry run complete' : '\u2713 Analysis complete',
82
- elapsed && React.createElement(Text, { color: theme.muted },
83
- " Completed in ",
84
- elapsed)),
80
+ dryRun ? "\u25cb Dry run complete" : "\u2713 Analysis complete",
81
+ elapsed && (React.createElement(Text, { color: theme.muted },
82
+ " Completed in ",
83
+ elapsed))),
85
84
  doneCount > 0 && (React.createElement(Text, { color: theme.success },
86
- " ",
87
- '\u2713',
85
+ " ",
86
+ "\u2713",
88
87
  " ",
89
88
  doneCount,
90
89
  " checks passed")),
91
90
  errorCount > 0 && (React.createElement(Text, { color: theme.error },
92
- " ",
93
- '\u2717',
91
+ " ",
92
+ "\u2717",
94
93
  " ",
95
94
  errorCount,
96
95
  " errors")),
package/dist/ui/App.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import React from 'react';
2
- import type { Stack, CIProvider, MemoryOption } from '../types/index.js';
1
+ import React from "react";
2
+ import type { CIProvider, HookProfile, MemoryOption, Stack } from "../types/index.js";
3
3
  interface AppProps {
4
4
  dryRun?: boolean;
5
5
  presetStack?: Stack;
@@ -8,7 +8,9 @@ interface AppProps {
8
8
  presetName?: string;
9
9
  presetGhagga?: boolean;
10
10
  presetMock?: boolean;
11
+ presetLocalAi?: boolean;
12
+ presetHookProfile?: HookProfile;
11
13
  }
12
- export default function App({ dryRun, presetStack, presetCI, presetMemory, presetName, presetGhagga, presetMock, }: AppProps): React.JSX.Element;
14
+ export default function App({ dryRun, presetStack, presetCI, presetMemory, presetName, presetGhagga, presetMock, presetLocalAi, presetHookProfile, }: AppProps): React.JSX.Element;
13
15
  export {};
14
16
  //# sourceMappingURL=App.d.ts.map
package/dist/ui/App.js CHANGED
@@ -1,54 +1,85 @@
1
- import React, { useState } from 'react';
2
- import { Box } from 'ink';
3
- import path from 'path';
4
- import Welcome from './Welcome.js';
5
- import Header from './Header.js';
6
- import NameInput from './NameInput.js';
7
- import StackSelector from './StackSelector.js';
8
- import CISelector from './CISelector.js';
9
- import MemorySelector from './MemorySelector.js';
10
- import OptionSelector from './OptionSelector.js';
11
- import Progress from './Progress.js';
12
- import Summary from './Summary.js';
13
- import { initProject } from '../commands/init.js';
14
- export default function App({ dryRun = false, presetStack, presetCI, presetMemory, presetName, presetGhagga = false, presetMock = false, }) {
15
- const [stage, setStage] = useState('welcome');
16
- const [projectName, setProjectName] = useState(presetName ?? '');
17
- const [projectDir, setProjectDir] = useState(presetName ? path.resolve(process.cwd(), presetName) : '');
18
- const [stack, setStack] = useState(presetStack ?? 'node');
19
- const [ciProvider, setCIProvider] = useState(presetCI ?? 'github');
20
- const [memory, setMemory] = useState(presetMemory ?? 'engram');
1
+ import { Box } from "ink";
2
+ import path from "path";
3
+ import React, { useState } from "react";
4
+ import { initProject } from "../commands/init.js";
5
+ import CISelector from "./CISelector.js";
6
+ import Header from "./Header.js";
7
+ import HookProfileSelector from "./HookProfileSelector.js";
8
+ import MemorySelector from "./MemorySelector.js";
9
+ import NameInput from "./NameInput.js";
10
+ import OptionSelector from "./OptionSelector.js";
11
+ import Progress from "./Progress.js";
12
+ import StackSelector from "./StackSelector.js";
13
+ import Summary from "./Summary.js";
14
+ import Welcome from "./Welcome.js";
15
+ export default function App({ dryRun = false, presetStack, presetCI, presetMemory, presetName, presetGhagga = false, presetMock = false, presetLocalAi = false, presetHookProfile, }) {
16
+ const [stage, setStage] = useState("welcome");
17
+ const [projectName, setProjectName] = useState(presetName ?? "");
18
+ const [projectDir, setProjectDir] = useState(presetName ? path.resolve(process.cwd(), presetName) : "");
19
+ const [stack, setStack] = useState(presetStack ?? "node");
20
+ const [ciProvider, setCIProvider] = useState(presetCI ?? "github");
21
+ const [memory, setMemory] = useState(presetMemory ?? "engram");
21
22
  const [aiSync, setAiSync] = useState(true);
22
23
  const [sdd, setSdd] = useState(true);
23
24
  const [contextDir, setContextDir] = useState(true);
24
25
  const [claudeMd, setClaudeMd] = useState(true);
25
26
  const [ghagga, setGhagga] = useState(presetGhagga);
27
+ const [securityHooks, setSecurityHooks] = useState(true);
28
+ const [hookProfile, setHookProfile] = useState(presetHookProfile ?? "standard");
29
+ const [codeGraph, setCodeGraph] = useState(false);
30
+ const [localAi, setLocalAi] = useState(false);
26
31
  const [steps, setSteps] = useState([]);
27
32
  const [startTime] = useState(Date.now());
28
33
  const handleNameConfirm = (name, dir) => {
29
34
  setProjectName(name);
30
35
  setProjectDir(dir);
31
- setStage(presetStack ? 'ci' : 'stack');
36
+ setStage(presetStack ? "ci" : "stack");
32
37
  };
33
38
  const handleStackConfirm = (s) => {
34
39
  setStack(s);
35
- setStage(presetCI ? 'memory' : 'ci');
40
+ setStage(presetCI ? "memory" : "ci");
36
41
  };
37
42
  const handleCIConfirm = (p) => {
38
43
  setCIProvider(p);
39
- setStage(presetMemory ? 'options' : 'memory');
44
+ setStage(presetMemory ? "options" : "memory");
40
45
  };
41
46
  const handleMemoryConfirm = (m) => {
42
47
  setMemory(m);
43
- setStage('options');
48
+ setStage("options");
44
49
  };
45
- const handleOptionsConfirm = async (opts) => {
50
+ const handleOptionsConfirm = (opts) => {
46
51
  setAiSync(opts.aiSync);
47
52
  setSdd(opts.sdd);
48
53
  setContextDir(opts.contextDir);
49
54
  setClaudeMd(opts.claudeMd);
50
55
  setGhagga(opts.ghagga);
51
- setStage('running');
56
+ setSecurityHooks(opts.securityHooks);
57
+ setCodeGraph(opts.codeGraph);
58
+ setLocalAi(opts.localAi);
59
+ // If securityHooks is selected, ask for profile; otherwise skip to running
60
+ if (opts.securityHooks) {
61
+ setStage("hook-profile");
62
+ }
63
+ else {
64
+ void runInit({ ...opts, hookProfile });
65
+ }
66
+ };
67
+ const handleHookProfileConfirm = (profile) => {
68
+ setHookProfile(profile);
69
+ void runInit({
70
+ aiSync,
71
+ sdd,
72
+ contextDir,
73
+ claudeMd,
74
+ ghagga,
75
+ securityHooks,
76
+ codeGraph,
77
+ localAi,
78
+ hookProfile: profile,
79
+ });
80
+ };
81
+ const runInit = async (opts) => {
82
+ setStage("running");
52
83
  await initProject({
53
84
  projectName,
54
85
  projectDir,
@@ -60,10 +91,16 @@ export default function App({ dryRun = false, presetStack, presetCI, presetMemor
60
91
  ghagga: opts.ghagga,
61
92
  contextDir: opts.contextDir,
62
93
  claudeMd: opts.claudeMd,
94
+ securityHooks: opts.securityHooks,
95
+ hookProfile: opts.hookProfile,
96
+ codeGraph: opts.codeGraph,
97
+ localAi: opts.localAi,
98
+ dockerDeploy: false,
99
+ dockerServiceName: "app",
63
100
  mock: presetMock,
64
101
  dryRun,
65
- }, (step) => setSteps(prev => {
66
- const idx = prev.findIndex(s => s.id === step.id);
102
+ }, (step) => setSteps((prev) => {
103
+ const idx = prev.findIndex((s) => s.id === step.id);
67
104
  if (idx >= 0) {
68
105
  const next = [...prev];
69
106
  next[idx] = step;
@@ -71,37 +108,40 @@ export default function App({ dryRun = false, presetStack, presetCI, presetMemor
71
108
  }
72
109
  return [...prev, step];
73
110
  }));
74
- setStage('done');
111
+ setStage("done");
75
112
  };
76
- const subtitle = stage === 'running' ? 'scaffolding...' :
77
- stage === 'done' ? 'complete' :
78
- undefined;
113
+ const subtitle = stage === "running"
114
+ ? "scaffolding..."
115
+ : stage === "done"
116
+ ? "complete"
117
+ : undefined;
79
118
  return (React.createElement(Box, { flexDirection: "column", padding: 1 },
80
- stage !== 'welcome' && React.createElement(Header, { subtitle: subtitle, dryRun: dryRun }),
81
- stage === 'welcome' && (React.createElement(Welcome, { onDone: () => {
119
+ stage !== "welcome" && React.createElement(Header, { subtitle: subtitle, dryRun: dryRun }),
120
+ stage === "welcome" && (React.createElement(Welcome, { onDone: () => {
82
121
  // Skip stages for which presets are already provided
83
122
  if (presetName && presetStack && presetCI && presetMemory) {
84
- setStage('options');
123
+ setStage("options");
85
124
  }
86
125
  else if (presetName && presetStack && presetCI) {
87
- setStage('memory');
126
+ setStage("memory");
88
127
  }
89
128
  else if (presetName && presetStack) {
90
- setStage('ci');
129
+ setStage("ci");
91
130
  }
92
131
  else if (presetName) {
93
- setStage('stack');
132
+ setStage("stack");
94
133
  }
95
134
  else {
96
- setStage('name');
135
+ setStage("name");
97
136
  }
98
137
  } })),
99
- stage === 'name' && (React.createElement(NameInput, { defaultName: projectName || 'my-project', onConfirm: handleNameConfirm })),
100
- stage === 'stack' && (React.createElement(StackSelector, { projectDir: projectDir || process.cwd(), onConfirm: handleStackConfirm })),
101
- stage === 'ci' && (React.createElement(CISelector, { onConfirm: handleCIConfirm })),
102
- stage === 'memory' && (React.createElement(MemorySelector, { onConfirm: handleMemoryConfirm })),
103
- stage === 'options' && (React.createElement(OptionSelector, { onConfirm: handleOptionsConfirm, presetGhagga: presetGhagga })),
104
- stage === 'running' && (React.createElement(Progress, { steps: steps, projectName: projectName, contextLine: `${projectName} (${stack} + ${ciProvider})`, onDone: () => setStage('done') })),
105
- stage === 'done' && (React.createElement(Summary, { steps: steps, dryRun: dryRun, projectName: projectName, stack: stack, elapsedMs: Date.now() - startTime }))));
138
+ stage === "name" && (React.createElement(NameInput, { defaultName: projectName || "my-project", onConfirm: handleNameConfirm })),
139
+ stage === "stack" && (React.createElement(StackSelector, { projectDir: projectDir || process.cwd(), onConfirm: handleStackConfirm })),
140
+ stage === "ci" && React.createElement(CISelector, { onConfirm: handleCIConfirm }),
141
+ stage === "memory" && React.createElement(MemorySelector, { onConfirm: handleMemoryConfirm }),
142
+ stage === "options" && (React.createElement(OptionSelector, { onConfirm: handleOptionsConfirm, presetGhagga: presetGhagga, presetLocalAi: presetLocalAi })),
143
+ stage === "hook-profile" && (React.createElement(HookProfileSelector, { onConfirm: handleHookProfileConfirm, presetProfile: presetHookProfile })),
144
+ stage === "running" && (React.createElement(Progress, { steps: steps, projectName: projectName, contextLine: `${projectName} (${stack} + ${ciProvider})`, onDone: () => setStage("done") })),
145
+ stage === "done" && (React.createElement(Summary, { steps: steps, dryRun: dryRun, projectName: projectName, stack: stack, elapsedMs: Date.now() - startTime }))));
106
146
  }
107
147
  //# sourceMappingURL=App.js.map
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ interface AutoSkillsProps {
3
+ projectDir: string;
4
+ skillsDir?: string;
5
+ dryRun?: boolean;
6
+ }
7
+ export default function AutoSkills({ projectDir, skillsDir, dryRun, }: AutoSkillsProps): React.JSX.Element;
8
+ export {};
9
+ //# sourceMappingURL=AutoSkills.d.ts.map