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.
- package/README.md +191 -3
- package/ci-local/hooks/pre-push +17 -13
- package/dist/commands/analyze.d.ts +1 -1
- package/dist/commands/analyze.js +15 -15
- package/dist/commands/atlassian-mcp.d.ts +42 -0
- package/dist/commands/atlassian-mcp.js +98 -0
- package/dist/commands/ci.d.ts +3 -3
- package/dist/commands/ci.js +185 -147
- package/dist/commands/crash-recovery.d.ts +34 -0
- package/dist/commands/crash-recovery.js +123 -0
- package/dist/commands/doctor.d.ts +2 -2
- package/dist/commands/doctor.js +113 -61
- package/dist/commands/harness-audit.d.ts +35 -0
- package/dist/commands/harness-audit.js +277 -0
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.js +415 -118
- package/dist/commands/llmstxt.d.ts +1 -1
- package/dist/commands/llmstxt.js +36 -34
- package/dist/commands/parallel-batch.d.ts +42 -0
- package/dist/commands/parallel-batch.js +90 -0
- package/dist/commands/plugin.d.ts +26 -1
- package/dist/commands/plugin.js +138 -24
- package/dist/commands/secret-scanner.d.ts +30 -0
- package/dist/commands/secret-scanner.js +272 -0
- package/dist/commands/security-analysis.d.ts +74 -0
- package/dist/commands/security-analysis.js +487 -0
- package/dist/commands/security.d.ts +31 -0
- package/dist/commands/security.js +445 -0
- package/dist/commands/skill-scanner.d.ts +63 -0
- package/dist/commands/skill-scanner.js +383 -0
- package/dist/commands/skills.d.ts +139 -0
- package/dist/commands/skills.js +895 -0
- package/dist/commands/supply-chain.d.ts +23 -0
- package/dist/commands/supply-chain.js +126 -0
- package/dist/commands/tdd-pipeline.d.ts +17 -0
- package/dist/commands/tdd-pipeline.js +144 -0
- package/dist/commands/tdd.d.ts +21 -0
- package/dist/commands/tdd.js +120 -0
- package/dist/commands/team-presets.d.ts +53 -0
- package/dist/commands/team-presets.js +201 -0
- package/dist/commands/workflow.d.ts +23 -0
- package/dist/commands/workflow.js +114 -0
- package/dist/constants.d.ts +21 -0
- package/dist/constants.js +208 -37
- package/dist/index.js +400 -54
- package/dist/lib/agent-skills.d.ts +73 -0
- package/dist/lib/agent-skills.js +260 -0
- package/dist/lib/auto-skill-install.d.ts +37 -0
- package/dist/lib/auto-skill-install.js +92 -0
- package/dist/lib/auto-wire.d.ts +20 -0
- package/dist/lib/auto-wire.js +240 -0
- package/dist/lib/claudemd.d.ts +20 -0
- package/dist/lib/claudemd.js +222 -0
- package/dist/lib/codex-export.d.ts +16 -0
- package/dist/lib/codex-export.js +109 -0
- package/dist/lib/common.d.ts +1 -1
- package/dist/lib/common.js +52 -44
- package/dist/lib/context.d.ts +27 -0
- package/dist/lib/context.js +204 -0
- package/dist/lib/docker.d.ts +1 -1
- package/dist/lib/docker.js +141 -112
- package/dist/lib/frontmatter.d.ts +1 -1
- package/dist/lib/frontmatter.js +29 -15
- package/dist/lib/plugin.d.ts +19 -1
- package/dist/lib/plugin.js +174 -47
- package/dist/lib/skill-publish.d.ts +40 -0
- package/dist/lib/skill-publish.js +146 -0
- package/dist/lib/stack-detector.d.ts +38 -0
- package/dist/lib/stack-detector.js +207 -0
- package/dist/lib/template.d.ts +16 -1
- package/dist/lib/template.js +46 -17
- package/dist/lib/workflow/discovery.d.ts +19 -0
- package/dist/lib/workflow/discovery.js +68 -0
- package/dist/lib/workflow/index.d.ts +5 -0
- package/dist/lib/workflow/index.js +5 -0
- package/dist/lib/workflow/parser.d.ts +16 -0
- package/dist/lib/workflow/parser.js +198 -0
- package/dist/lib/workflow/renderer.d.ts +9 -0
- package/dist/lib/workflow/renderer.js +152 -0
- package/dist/lib/workflow/validator.d.ts +10 -0
- package/dist/lib/workflow/validator.js +189 -0
- package/dist/tasks/index.d.ts +4 -0
- package/dist/tasks/index.js +4 -0
- package/dist/tasks/scaffold-tasks.d.ts +3 -0
- package/dist/tasks/scaffold-tasks.js +14 -0
- package/dist/tasks/task-id.d.ts +30 -0
- package/dist/tasks/task-id.js +55 -0
- package/dist/tasks/task-tracker.d.ts +15 -0
- package/dist/tasks/task-tracker.js +81 -0
- package/dist/types/index.d.ts +252 -5
- package/dist/types/index.js +11 -1
- package/dist/ui/AnalyzeUI.d.ts +1 -1
- package/dist/ui/AnalyzeUI.js +38 -39
- package/dist/ui/App.d.ts +5 -3
- package/dist/ui/App.js +92 -46
- package/dist/ui/AutoSkills.d.ts +9 -0
- package/dist/ui/AutoSkills.js +124 -0
- package/dist/ui/CI.d.ts +2 -2
- package/dist/ui/CI.js +24 -26
- package/dist/ui/CIContext.d.ts +1 -1
- package/dist/ui/CIContext.js +3 -2
- package/dist/ui/CISelector.d.ts +2 -2
- package/dist/ui/CISelector.js +23 -15
- package/dist/ui/Doctor.d.ts +1 -1
- package/dist/ui/Doctor.js +35 -29
- package/dist/ui/Header.d.ts +1 -1
- package/dist/ui/Header.js +14 -14
- package/dist/ui/HookProfileSelector.d.ts +9 -0
- package/dist/ui/HookProfileSelector.js +54 -0
- package/dist/ui/LlmsTxt.d.ts +1 -1
- package/dist/ui/LlmsTxt.js +31 -22
- package/dist/ui/MemorySelector.d.ts +2 -2
- package/dist/ui/MemorySelector.js +28 -16
- package/dist/ui/NameInput.d.ts +1 -1
- package/dist/ui/NameInput.js +21 -21
- package/dist/ui/OptionSelector.d.ts +8 -2
- package/dist/ui/OptionSelector.js +83 -26
- package/dist/ui/Plugin.d.ts +4 -3
- package/dist/ui/Plugin.js +89 -29
- package/dist/ui/Progress.d.ts +3 -3
- package/dist/ui/Progress.js +23 -22
- package/dist/ui/Skills.d.ts +11 -0
- package/dist/ui/Skills.js +148 -0
- package/dist/ui/StackSelector.d.ts +2 -2
- package/dist/ui/StackSelector.js +26 -16
- package/dist/ui/Summary.d.ts +3 -3
- package/dist/ui/Summary.js +60 -50
- package/dist/ui/Welcome.d.ts +1 -1
- package/dist/ui/Welcome.js +15 -16
- package/dist/ui/theme.d.ts +1 -1
- package/dist/ui/theme.js +6 -6
- package/package.json +9 -6
- package/templates/common/atlassian/mcp-atlassian-snippet.json +16 -0
- package/templates/common/repoforge/mcp-repoforge-snippet.json +11 -0
- package/templates/common/repoforge/repoforge.yaml +34 -0
- package/templates/github/deploy-docker-zero-downtime.yml +140 -0
- package/templates/github/repoforge-graph.yml +45 -0
- package/templates/gitlab/deploy-docker-zero-downtime.yml +57 -0
- package/templates/local-ai/.env.example +17 -0
- package/templates/local-ai/docker-compose.yml +95 -0
- package/templates/security-hooks/claude-settings-security.json +30 -0
- package/templates/security-hooks/commit-msg-signing +29 -0
- package/templates/security-hooks/pre-commit-permissions +74 -0
- package/templates/security-hooks/pre-commit-secrets +74 -0
- package/templates/security-hooks/pre-push-branch-protection +62 -0
- package/templates/security-hooks/pre-push-deps +83 -0
- package/templates/security-hooks/pre-push-signing +67 -0
- package/templates/woodpecker/deploy-docker-zero-downtime.yml +50 -0
- package/templates/workflows/ci-pipeline.dot +15 -0
- package/templates/workflows/feature-flow.dot +21 -0
- package/templates/workflows/release.dot +16 -0
- package/dist/__integration__/helpers.d.ts +0 -20
- package/dist/__integration__/helpers.d.ts.map +0 -1
- package/dist/__integration__/helpers.js +0 -31
- package/dist/__integration__/helpers.js.map +0 -1
- package/dist/commands/analyze.d.ts.map +0 -1
- package/dist/commands/analyze.js.map +0 -1
- package/dist/commands/ci.d.ts.map +0 -1
- package/dist/commands/ci.js.map +0 -1
- package/dist/commands/doctor.d.ts.map +0 -1
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/llmstxt.d.ts.map +0 -1
- package/dist/commands/llmstxt.js.map +0 -1
- package/dist/commands/plugin.d.ts.map +0 -1
- package/dist/commands/plugin.js.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/common.d.ts.map +0 -1
- package/dist/lib/common.js.map +0 -1
- package/dist/lib/docker.d.ts.map +0 -1
- package/dist/lib/docker.js.map +0 -1
- package/dist/lib/frontmatter.d.ts.map +0 -1
- package/dist/lib/frontmatter.js.map +0 -1
- package/dist/lib/plugin.d.ts.map +0 -1
- package/dist/lib/plugin.js.map +0 -1
- package/dist/lib/template.d.ts.map +0 -1
- package/dist/lib/template.js.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/ui/AnalyzeUI.d.ts.map +0 -1
- package/dist/ui/AnalyzeUI.js.map +0 -1
- package/dist/ui/App.d.ts.map +0 -1
- package/dist/ui/App.js.map +0 -1
- package/dist/ui/CI.d.ts.map +0 -1
- package/dist/ui/CI.js.map +0 -1
- package/dist/ui/CIContext.d.ts.map +0 -1
- package/dist/ui/CIContext.js.map +0 -1
- package/dist/ui/CISelector.d.ts.map +0 -1
- package/dist/ui/CISelector.js.map +0 -1
- package/dist/ui/Doctor.d.ts.map +0 -1
- package/dist/ui/Doctor.js.map +0 -1
- package/dist/ui/Header.d.ts.map +0 -1
- package/dist/ui/Header.js.map +0 -1
- package/dist/ui/LlmsTxt.d.ts.map +0 -1
- package/dist/ui/LlmsTxt.js.map +0 -1
- package/dist/ui/MemorySelector.d.ts.map +0 -1
- package/dist/ui/MemorySelector.js.map +0 -1
- package/dist/ui/NameInput.d.ts.map +0 -1
- package/dist/ui/NameInput.js.map +0 -1
- package/dist/ui/OptionSelector.d.ts.map +0 -1
- package/dist/ui/OptionSelector.js.map +0 -1
- package/dist/ui/Plugin.d.ts.map +0 -1
- package/dist/ui/Plugin.js.map +0 -1
- package/dist/ui/Progress.d.ts.map +0 -1
- package/dist/ui/Progress.js.map +0 -1
- package/dist/ui/StackSelector.d.ts.map +0 -1
- package/dist/ui/StackSelector.js.map +0 -1
- package/dist/ui/Summary.d.ts.map +0 -1
- package/dist/ui/Summary.js.map +0 -1
- package/dist/ui/Welcome.d.ts.map +0 -1
- package/dist/ui/Welcome.js.map +0 -1
- package/dist/ui/theme.d.ts.map +0 -1
- package/dist/ui/theme.js.map +0 -1
package/dist/types/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export type Stack =
|
|
2
|
-
export type CIProvider =
|
|
3
|
-
export type MemoryOption =
|
|
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;
|
|
@@ -11,12 +12,32 @@ export interface InitOptions {
|
|
|
11
12
|
sdd: boolean;
|
|
12
13
|
ghagga: boolean;
|
|
13
14
|
mock: boolean;
|
|
15
|
+
contextDir: boolean;
|
|
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;
|
|
14
25
|
dryRun: boolean;
|
|
15
26
|
}
|
|
27
|
+
export interface StackClaudeMdEntry {
|
|
28
|
+
skills: string[];
|
|
29
|
+
conventions: string;
|
|
30
|
+
testFramework: string;
|
|
31
|
+
}
|
|
32
|
+
export interface StackContextEntry {
|
|
33
|
+
tree: string;
|
|
34
|
+
conventions: string;
|
|
35
|
+
entryPoint: string;
|
|
36
|
+
}
|
|
16
37
|
export interface InitStep {
|
|
17
38
|
id: string;
|
|
18
39
|
label: string;
|
|
19
|
-
status:
|
|
40
|
+
status: "pending" | "running" | "done" | "error" | "skipped";
|
|
20
41
|
detail?: string;
|
|
21
42
|
}
|
|
22
43
|
export interface StackDetection {
|
|
@@ -36,7 +57,7 @@ export interface ForgeManifest {
|
|
|
36
57
|
}
|
|
37
58
|
export interface DoctorCheck {
|
|
38
59
|
label: string;
|
|
39
|
-
status:
|
|
60
|
+
status: "ok" | "fail" | "skip";
|
|
40
61
|
detail?: string;
|
|
41
62
|
}
|
|
42
63
|
export interface DoctorSection {
|
|
@@ -46,6 +67,13 @@ export interface DoctorSection {
|
|
|
46
67
|
export interface DoctorResult {
|
|
47
68
|
sections: DoctorSection[];
|
|
48
69
|
}
|
|
70
|
+
export type TddPipelineMode = "strict" | "warn";
|
|
71
|
+
export interface TddPipelineResult {
|
|
72
|
+
installed: string[];
|
|
73
|
+
skipped: string[];
|
|
74
|
+
errors: string[];
|
|
75
|
+
mode: TddPipelineMode;
|
|
76
|
+
}
|
|
49
77
|
export interface PluginManifest {
|
|
50
78
|
name: string;
|
|
51
79
|
version: string;
|
|
@@ -87,4 +115,223 @@ export interface InstalledPlugin {
|
|
|
87
115
|
source: string;
|
|
88
116
|
manifest: PluginManifest;
|
|
89
117
|
}
|
|
118
|
+
export interface PluginSyncResult {
|
|
119
|
+
added: string[];
|
|
120
|
+
removed: string[];
|
|
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[];
|
|
137
|
+
}
|
|
138
|
+
export interface AgentSkillEntry {
|
|
139
|
+
name: string;
|
|
140
|
+
description: string;
|
|
141
|
+
path: string;
|
|
142
|
+
}
|
|
143
|
+
export interface AgentSkillsManifest {
|
|
144
|
+
name: string;
|
|
145
|
+
version: string;
|
|
146
|
+
description: string;
|
|
147
|
+
skills: AgentSkillEntry[];
|
|
148
|
+
metadata?: {
|
|
149
|
+
forge_source?: string;
|
|
150
|
+
};
|
|
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
|
+
}
|
|
168
|
+
export interface CodexTomlEntry {
|
|
169
|
+
name: string;
|
|
170
|
+
model: string;
|
|
171
|
+
instructions: string;
|
|
172
|
+
}
|
|
173
|
+
export interface CodexExportResult {
|
|
174
|
+
success: boolean;
|
|
175
|
+
files?: string[];
|
|
176
|
+
error?: string;
|
|
177
|
+
}
|
|
178
|
+
export type SecuritySeverity = "critical" | "high" | "moderate" | "low" | "info";
|
|
179
|
+
export interface SecurityFinding {
|
|
180
|
+
id: string;
|
|
181
|
+
severity: SecuritySeverity;
|
|
182
|
+
package: string;
|
|
183
|
+
title: string;
|
|
184
|
+
url?: string;
|
|
185
|
+
}
|
|
186
|
+
export interface SecurityBaseline {
|
|
187
|
+
version: string;
|
|
188
|
+
createdAt: string;
|
|
189
|
+
updatedAt?: string;
|
|
190
|
+
stack: string;
|
|
191
|
+
buildTool: string;
|
|
192
|
+
findings: SecurityFinding[];
|
|
193
|
+
findingKeys: string[];
|
|
194
|
+
allowlist?: string[];
|
|
195
|
+
}
|
|
196
|
+
export interface SecurityCheckOptions {
|
|
197
|
+
minSeverity?: SecuritySeverity;
|
|
198
|
+
staleDays?: number;
|
|
199
|
+
}
|
|
200
|
+
export interface SecurityCheckResult {
|
|
201
|
+
baseline: SecurityBaseline;
|
|
202
|
+
current: SecurityFinding[];
|
|
203
|
+
regressions: SecurityFinding[];
|
|
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;
|
|
216
|
+
}
|
|
217
|
+
export interface SkillCriticalRule {
|
|
218
|
+
skillName: string;
|
|
219
|
+
skillPath: string;
|
|
220
|
+
rule: string;
|
|
221
|
+
/** Normalized rule for comparison (lowercase, trimmed) */
|
|
222
|
+
normalized: string;
|
|
223
|
+
}
|
|
224
|
+
export type ConflictKind = "regex-pair" | "directive-clash";
|
|
225
|
+
export interface SkillConflict {
|
|
226
|
+
ruleA: SkillCriticalRule;
|
|
227
|
+
ruleB: SkillCriticalRule;
|
|
228
|
+
reason: string;
|
|
229
|
+
/** How the conflict was detected */
|
|
230
|
+
kind: ConflictKind;
|
|
231
|
+
}
|
|
232
|
+
export interface SkillBudgetEntry {
|
|
233
|
+
skillName: string;
|
|
234
|
+
skillPath: string;
|
|
235
|
+
tokens: number;
|
|
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
|
+
}
|
|
247
|
+
export interface SkillBudgetResult {
|
|
248
|
+
entries: SkillBudgetEntry[];
|
|
249
|
+
totalTokens: number;
|
|
250
|
+
budget: number;
|
|
251
|
+
overBudget: boolean;
|
|
252
|
+
suggestions: string[];
|
|
253
|
+
/** Structured optimization sets: minimal combinations to meet budget */
|
|
254
|
+
optimizations: SkillBudgetSuggestion[];
|
|
255
|
+
}
|
|
256
|
+
export interface SkillDuplicate {
|
|
257
|
+
skillA: string;
|
|
258
|
+
skillB: string;
|
|
259
|
+
/** Overlapping trigger keywords */
|
|
260
|
+
sharedTriggers: string[];
|
|
261
|
+
similarity: number;
|
|
262
|
+
}
|
|
263
|
+
export interface SkillDoctorResult {
|
|
264
|
+
conflicts: SkillConflict[];
|
|
265
|
+
budget: SkillBudgetResult;
|
|
266
|
+
duplicates: SkillDuplicate[];
|
|
267
|
+
}
|
|
268
|
+
export type SkillGrade = "A" | "B" | "C" | "D" | "F";
|
|
269
|
+
export interface SkillScore {
|
|
270
|
+
skillName: string;
|
|
271
|
+
completeness: number;
|
|
272
|
+
clarity: number;
|
|
273
|
+
testability: number;
|
|
274
|
+
tokenEfficiency: number;
|
|
275
|
+
safety: number;
|
|
276
|
+
agentReadiness: number;
|
|
277
|
+
overall: number;
|
|
278
|
+
grade: SkillGrade;
|
|
279
|
+
threshold: number;
|
|
280
|
+
passing: boolean;
|
|
281
|
+
}
|
|
282
|
+
export interface SkillRegistryGateResult {
|
|
283
|
+
skillName: string;
|
|
284
|
+
score: SkillScore;
|
|
285
|
+
accepted: boolean;
|
|
286
|
+
reason?: string;
|
|
287
|
+
}
|
|
288
|
+
export interface SkillBenchmarkCheck {
|
|
289
|
+
name: string;
|
|
290
|
+
passed: boolean;
|
|
291
|
+
detail?: string;
|
|
292
|
+
}
|
|
293
|
+
export interface SkillBenchmarkResult {
|
|
294
|
+
skillName: string;
|
|
295
|
+
checks: SkillBenchmarkCheck[];
|
|
296
|
+
passRate: number;
|
|
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
|
+
}
|
|
90
337
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/types/index.js
CHANGED
|
@@ -1,2 +1,12 @@
|
|
|
1
|
-
|
|
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
|
package/dist/ui/AnalyzeUI.d.ts
CHANGED
package/dist/ui/AnalyzeUI.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { runAnalyze } from
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
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 ===
|
|
38
|
-
const errorCount = steps.filter(s => s.status ===
|
|
39
|
-
const notInstalled = steps.some(s => s.status ===
|
|
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
|
-
|
|
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 ===
|
|
54
|
-
|
|
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 ===
|
|
60
|
-
|
|
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
|
-
|
|
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 }, "
|
|
76
|
-
React.createElement(Text, { color: theme.primary }, "
|
|
77
|
-
React.createElement(Text, { color: theme.muted }, "
|
|
78
|
-
React.createElement(Text, { color: theme.primary }, "
|
|
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 ?
|
|
82
|
-
elapsed && React.createElement(Text, { color: theme.muted },
|
|
83
|
-
"
|
|
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
|
-
|
|
85
|
+
" ",
|
|
86
|
+
"\u2713",
|
|
88
87
|
" ",
|
|
89
88
|
doneCount,
|
|
90
89
|
" checks passed")),
|
|
91
90
|
errorCount > 0 && (React.createElement(Text, { color: theme.error },
|
|
92
|
-
"
|
|
93
|
-
|
|
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
|
|
2
|
-
import type {
|
|
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,50 +1,85 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import OptionSelector from
|
|
11
|
-
import Progress from
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const [
|
|
17
|
-
const [
|
|
18
|
-
const [
|
|
19
|
-
const [
|
|
20
|
-
const [
|
|
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);
|
|
24
|
+
const [contextDir, setContextDir] = useState(true);
|
|
25
|
+
const [claudeMd, setClaudeMd] = useState(true);
|
|
23
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);
|
|
24
31
|
const [steps, setSteps] = useState([]);
|
|
25
32
|
const [startTime] = useState(Date.now());
|
|
26
33
|
const handleNameConfirm = (name, dir) => {
|
|
27
34
|
setProjectName(name);
|
|
28
35
|
setProjectDir(dir);
|
|
29
|
-
setStage(presetStack ?
|
|
36
|
+
setStage(presetStack ? "ci" : "stack");
|
|
30
37
|
};
|
|
31
38
|
const handleStackConfirm = (s) => {
|
|
32
39
|
setStack(s);
|
|
33
|
-
setStage(presetCI ?
|
|
40
|
+
setStage(presetCI ? "memory" : "ci");
|
|
34
41
|
};
|
|
35
42
|
const handleCIConfirm = (p) => {
|
|
36
43
|
setCIProvider(p);
|
|
37
|
-
setStage(presetMemory ?
|
|
44
|
+
setStage(presetMemory ? "options" : "memory");
|
|
38
45
|
};
|
|
39
46
|
const handleMemoryConfirm = (m) => {
|
|
40
47
|
setMemory(m);
|
|
41
|
-
setStage(
|
|
48
|
+
setStage("options");
|
|
42
49
|
};
|
|
43
|
-
const handleOptionsConfirm =
|
|
50
|
+
const handleOptionsConfirm = (opts) => {
|
|
44
51
|
setAiSync(opts.aiSync);
|
|
45
52
|
setSdd(opts.sdd);
|
|
53
|
+
setContextDir(opts.contextDir);
|
|
54
|
+
setClaudeMd(opts.claudeMd);
|
|
46
55
|
setGhagga(opts.ghagga);
|
|
47
|
-
|
|
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");
|
|
48
83
|
await initProject({
|
|
49
84
|
projectName,
|
|
50
85
|
projectDir,
|
|
@@ -54,10 +89,18 @@ export default function App({ dryRun = false, presetStack, presetCI, presetMemor
|
|
|
54
89
|
aiSync: opts.aiSync,
|
|
55
90
|
sdd: opts.sdd,
|
|
56
91
|
ghagga: opts.ghagga,
|
|
92
|
+
contextDir: opts.contextDir,
|
|
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",
|
|
57
100
|
mock: presetMock,
|
|
58
101
|
dryRun,
|
|
59
|
-
}, (step) => setSteps(prev => {
|
|
60
|
-
const idx = prev.findIndex(s => s.id === step.id);
|
|
102
|
+
}, (step) => setSteps((prev) => {
|
|
103
|
+
const idx = prev.findIndex((s) => s.id === step.id);
|
|
61
104
|
if (idx >= 0) {
|
|
62
105
|
const next = [...prev];
|
|
63
106
|
next[idx] = step;
|
|
@@ -65,37 +108,40 @@ export default function App({ dryRun = false, presetStack, presetCI, presetMemor
|
|
|
65
108
|
}
|
|
66
109
|
return [...prev, step];
|
|
67
110
|
}));
|
|
68
|
-
setStage(
|
|
111
|
+
setStage("done");
|
|
69
112
|
};
|
|
70
|
-
const subtitle = stage ===
|
|
71
|
-
|
|
72
|
-
|
|
113
|
+
const subtitle = stage === "running"
|
|
114
|
+
? "scaffolding..."
|
|
115
|
+
: stage === "done"
|
|
116
|
+
? "complete"
|
|
117
|
+
: undefined;
|
|
73
118
|
return (React.createElement(Box, { flexDirection: "column", padding: 1 },
|
|
74
|
-
stage !==
|
|
75
|
-
stage ===
|
|
119
|
+
stage !== "welcome" && React.createElement(Header, { subtitle: subtitle, dryRun: dryRun }),
|
|
120
|
+
stage === "welcome" && (React.createElement(Welcome, { onDone: () => {
|
|
76
121
|
// Skip stages for which presets are already provided
|
|
77
122
|
if (presetName && presetStack && presetCI && presetMemory) {
|
|
78
|
-
setStage(
|
|
123
|
+
setStage("options");
|
|
79
124
|
}
|
|
80
125
|
else if (presetName && presetStack && presetCI) {
|
|
81
|
-
setStage(
|
|
126
|
+
setStage("memory");
|
|
82
127
|
}
|
|
83
128
|
else if (presetName && presetStack) {
|
|
84
|
-
setStage(
|
|
129
|
+
setStage("ci");
|
|
85
130
|
}
|
|
86
131
|
else if (presetName) {
|
|
87
|
-
setStage(
|
|
132
|
+
setStage("stack");
|
|
88
133
|
}
|
|
89
134
|
else {
|
|
90
|
-
setStage(
|
|
135
|
+
setStage("name");
|
|
91
136
|
}
|
|
92
137
|
} })),
|
|
93
|
-
stage ===
|
|
94
|
-
stage ===
|
|
95
|
-
stage ===
|
|
96
|
-
stage ===
|
|
97
|
-
stage ===
|
|
98
|
-
stage ===
|
|
99
|
-
stage ===
|
|
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 }))));
|
|
100
146
|
}
|
|
101
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
|