javi-forge 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -1
- package/ci-local/README.md +56 -11
- package/ci-local/ci-local.ps1 +445 -0
- package/ci-local/ci-local.sh +52 -9
- package/ci-local/docker/python.Dockerfile +7 -0
- package/ci-local/hooks/commit-msg +120 -44
- package/ci-local/hooks/commit-msg.test.sh +286 -0
- package/ci-local/hooks/pre-commit +9 -1
- package/ci-local/hooks/pre-push +13 -2
- package/ci-local/install.ps1 +367 -0
- package/ci-local/install.sh +151 -5
- package/ci-local/uninstall.ps1 +85 -0
- package/ci-local/uninstall.sh +95 -0
- package/dist/cli/dispatch/ci.d.ts +12 -0
- package/dist/cli/dispatch/ci.js +38 -0
- package/dist/cli/dispatch/security.d.ts +11 -0
- package/dist/cli/dispatch/security.js +68 -0
- package/dist/cli/dispatch/simple-renderers.d.ts +16 -0
- package/dist/cli/dispatch/simple-renderers.js +65 -0
- package/dist/cli/dispatch/skill-publish.d.ts +15 -0
- package/dist/cli/dispatch/skill-publish.js +44 -0
- package/dist/cli/dispatch/skills-cmd.d.ts +13 -0
- package/dist/cli/dispatch/skills-cmd.js +93 -0
- package/dist/cli/dispatch/tdd.d.ts +11 -0
- package/dist/cli/dispatch/tdd.js +45 -0
- package/dist/cli/dispatch/types.d.ts +29 -0
- package/dist/cli/dispatch/types.js +2 -0
- package/dist/cli/dispatch/workflow.d.ts +11 -0
- package/dist/cli/dispatch/workflow.js +67 -0
- package/dist/cli/help.d.ts +127 -0
- package/dist/cli/help.js +138 -0
- package/dist/cli/runtime.d.ts +16 -0
- package/dist/cli/runtime.js +38 -0
- package/dist/cli/validators.d.ts +17 -0
- package/dist/cli/validators.js +35 -0
- package/dist/commands/analyze.d.ts +1 -1
- package/dist/commands/analyze.js +14 -16
- package/dist/commands/ci.d.ts +50 -3
- package/dist/commands/ci.js +537 -182
- package/dist/commands/doctor.d.ts +2 -2
- package/dist/commands/doctor.js +112 -62
- package/dist/commands/init/report.d.ts +13 -0
- package/dist/commands/init/report.js +13 -0
- package/dist/commands/init/steps/agent-skills.d.ts +13 -0
- package/dist/commands/init/steps/agent-skills.js +45 -0
- package/dist/commands/init/steps/ai-sync.d.ts +15 -0
- package/dist/commands/init/steps/ai-sync.js +62 -0
- package/dist/commands/init/steps/ci.d.ts +24 -0
- package/dist/commands/init/steps/ci.js +74 -0
- package/dist/commands/init/steps/claude-md.d.ts +14 -0
- package/dist/commands/init/steps/claude-md.js +54 -0
- package/dist/commands/init/steps/code-graph.d.ts +16 -0
- package/dist/commands/init/steps/code-graph.js +68 -0
- package/dist/commands/init/steps/context-dir.d.ts +13 -0
- package/dist/commands/init/steps/context-dir.js +47 -0
- package/dist/commands/init/steps/docker-deploy.d.ts +16 -0
- package/dist/commands/init/steps/docker-deploy.js +60 -0
- package/dist/commands/init/steps/ghagga.d.ts +15 -0
- package/dist/commands/init/steps/ghagga.js +58 -0
- package/dist/commands/init/steps/git.d.ts +25 -0
- package/dist/commands/init/steps/git.js +81 -0
- package/dist/commands/init/steps/gitignore.d.ts +13 -0
- package/dist/commands/init/steps/gitignore.js +39 -0
- package/dist/commands/init/steps/local-ai.d.ts +14 -0
- package/dist/commands/init/steps/local-ai.js +53 -0
- package/dist/commands/init/steps/manifest.d.ts +13 -0
- package/dist/commands/init/steps/manifest.js +58 -0
- package/dist/commands/init/steps/memory.d.ts +15 -0
- package/dist/commands/init/steps/memory.js +60 -0
- package/dist/commands/init/steps/mock.d.ts +13 -0
- package/dist/commands/init/steps/mock.js +64 -0
- package/dist/commands/init/steps/sdd.d.ts +12 -0
- package/dist/commands/init/steps/sdd.js +40 -0
- package/dist/commands/init/steps/security.d.ts +28 -0
- package/dist/commands/init/steps/security.js +103 -0
- package/dist/commands/init/types.d.ts +30 -0
- package/dist/commands/init/types.js +2 -0
- package/dist/commands/init.d.ts +5 -4
- package/dist/commands/init.js +42 -387
- package/dist/commands/llmstxt.d.ts +1 -1
- package/dist/commands/llmstxt.js +36 -34
- package/dist/commands/plugin.d.ts +10 -1
- package/dist/commands/plugin.js +92 -47
- package/dist/commands/security.d.ts +11 -5
- package/dist/commands/security.js +236 -77
- package/dist/commands/skills/analysis.d.ts +19 -0
- package/dist/commands/skills/analysis.js +211 -0
- package/dist/commands/skills/benchmark.d.ts +6 -0
- package/dist/commands/skills/benchmark.js +82 -0
- package/dist/commands/skills/constants.d.ts +10 -0
- package/dist/commands/skills/constants.js +27 -0
- package/dist/commands/skills/directives.d.ts +21 -0
- package/dist/commands/skills/directives.js +101 -0
- package/dist/commands/skills/parsing.d.ts +16 -0
- package/dist/commands/skills/parsing.js +108 -0
- package/dist/commands/skills/rules.d.ts +5 -0
- package/dist/commands/skills/rules.js +32 -0
- package/dist/commands/skills/scoring.d.ts +47 -0
- package/dist/commands/skills/scoring.js +306 -0
- package/dist/commands/skills.d.ts +8 -69
- package/dist/commands/skills.js +9 -490
- package/dist/commands/tdd-pipeline.d.ts +17 -0
- package/dist/commands/tdd-pipeline.js +144 -0
- package/dist/commands/tdd.d.ts +1 -1
- package/dist/commands/tdd.js +21 -18
- package/dist/commands/workflow.d.ts +23 -0
- package/dist/commands/workflow.js +116 -0
- package/dist/constants.d.ts +15 -1
- package/dist/constants.js +161 -122
- package/dist/index.js +43 -280
- package/dist/lib/agent-skills.d.ts +36 -1
- package/dist/lib/agent-skills.js +168 -19
- package/dist/lib/atlassian-mcp.d.ts +42 -0
- package/dist/lib/atlassian-mcp.js +98 -0
- package/dist/lib/auto-skill-install.d.ts +37 -0
- package/dist/lib/auto-skill-install.js +91 -0
- package/dist/lib/auto-wire.d.ts +20 -0
- package/dist/lib/auto-wire.js +240 -0
- package/dist/lib/ci-config.d.ts +65 -0
- package/dist/lib/ci-config.js +297 -0
- package/dist/lib/claudemd.d.ts +13 -1
- package/dist/lib/claudemd.js +174 -24
- package/dist/lib/codex-export.d.ts +1 -1
- package/dist/lib/codex-export.js +26 -32
- package/dist/lib/common.d.ts +1 -1
- package/dist/lib/common.js +52 -44
- package/dist/lib/context.d.ts +17 -2
- package/dist/lib/context.js +142 -13
- package/dist/lib/crash-recovery.d.ts +34 -0
- package/dist/lib/crash-recovery.js +123 -0
- package/dist/lib/docker.d.ts +23 -2
- package/dist/lib/docker.js +168 -131
- package/dist/lib/exec.d.ts +10 -0
- package/dist/lib/exec.js +11 -0
- package/dist/lib/frontmatter.d.ts +1 -1
- package/dist/lib/frontmatter.js +29 -15
- package/dist/lib/harness-audit.d.ts +35 -0
- package/dist/lib/harness-audit.js +277 -0
- package/dist/lib/parallel-batch.d.ts +42 -0
- package/dist/lib/parallel-batch.js +88 -0
- package/dist/lib/plugin.d.ts +9 -3
- package/dist/lib/plugin.js +127 -70
- package/dist/lib/secret-scanner.d.ts +30 -0
- package/dist/lib/secret-scanner.js +274 -0
- package/dist/lib/security-analysis.d.ts +74 -0
- package/dist/lib/security-analysis.js +489 -0
- package/dist/lib/skill-publish.d.ts +40 -0
- package/dist/lib/skill-publish.js +164 -0
- package/dist/lib/skill-scanner.d.ts +63 -0
- package/dist/lib/skill-scanner.js +383 -0
- package/dist/lib/stack-detector.d.ts +38 -0
- package/dist/lib/stack-detector.js +207 -0
- package/dist/lib/supply-chain.d.ts +23 -0
- package/dist/lib/supply-chain.js +126 -0
- package/dist/lib/team-presets.d.ts +53 -0
- package/dist/lib/team-presets.js +201 -0
- package/dist/lib/template.d.ts +16 -1
- package/dist/lib/template.js +46 -17
- package/dist/lib/workflow/discovery.d.ts +27 -0
- package/dist/lib/workflow/discovery.js +85 -0
- package/dist/lib/workflow/index.d.ts +5 -0
- package/dist/lib/workflow/index.js +5 -0
- package/dist/lib/workflow/parser.d.ts +16 -0
- package/dist/lib/workflow/parser.js +198 -0
- package/dist/lib/workflow/renderer.d.ts +9 -0
- package/dist/lib/workflow/renderer.js +152 -0
- package/dist/lib/workflow/validator.d.ts +10 -0
- package/dist/lib/workflow/validator.js +189 -0
- package/dist/tasks/index.d.ts +4 -0
- package/dist/tasks/index.js +4 -0
- package/dist/tasks/scaffold-tasks.d.ts +3 -0
- package/dist/tasks/scaffold-tasks.js +14 -0
- package/dist/tasks/task-id.d.ts +30 -0
- package/dist/tasks/task-id.js +59 -0
- package/dist/tasks/task-tracker.d.ts +15 -0
- package/dist/tasks/task-tracker.js +81 -0
- package/dist/types/index.d.ts +134 -6
- package/dist/types/index.js +11 -1
- package/dist/ui/AnalyzeUI.d.ts +1 -1
- package/dist/ui/AnalyzeUI.js +38 -39
- package/dist/ui/App.d.ts +5 -3
- package/dist/ui/App.js +86 -46
- package/dist/ui/AutoSkills.d.ts +9 -0
- package/dist/ui/AutoSkills.js +124 -0
- package/dist/ui/CI.d.ts +2 -2
- package/dist/ui/CI.js +24 -26
- package/dist/ui/CIContext.d.ts +1 -1
- package/dist/ui/CIContext.js +2 -2
- package/dist/ui/CISelector.d.ts +2 -2
- package/dist/ui/CISelector.js +23 -15
- package/dist/ui/Doctor.d.ts +1 -1
- package/dist/ui/Doctor.js +35 -29
- package/dist/ui/Header.d.ts +1 -1
- package/dist/ui/Header.js +14 -14
- package/dist/ui/HookProfileSelector.d.ts +9 -0
- package/dist/ui/HookProfileSelector.js +54 -0
- package/dist/ui/LlmsTxt.d.ts +1 -1
- package/dist/ui/LlmsTxt.js +31 -22
- package/dist/ui/MemorySelector.d.ts +2 -2
- package/dist/ui/MemorySelector.js +28 -16
- package/dist/ui/NameInput.d.ts +1 -1
- package/dist/ui/NameInput.js +21 -21
- package/dist/ui/OptionSelector.d.ts +6 -2
- package/dist/ui/OptionSelector.js +83 -32
- package/dist/ui/Plugin.d.ts +4 -3
- package/dist/ui/Plugin.js +78 -35
- package/dist/ui/Progress.d.ts +3 -3
- package/dist/ui/Progress.js +23 -22
- package/dist/ui/Skills.d.ts +2 -2
- package/dist/ui/Skills.js +61 -32
- package/dist/ui/StackSelector.d.ts +2 -2
- package/dist/ui/StackSelector.js +27 -17
- package/dist/ui/Summary.d.ts +3 -3
- package/dist/ui/Summary.js +60 -50
- package/dist/ui/Welcome.d.ts +1 -1
- package/dist/ui/Welcome.js +15 -16
- package/dist/ui/theme.d.ts +1 -1
- package/dist/ui/theme.js +6 -6
- package/lib/common.psm1 +167 -0
- package/lib/common.sh +30 -0
- package/package.json +46 -24
- package/templates/common/atlassian/mcp-atlassian-snippet.json +16 -0
- package/templates/common/repoforge/mcp-repoforge-snippet.json +11 -0
- package/templates/common/repoforge/repoforge.yaml +34 -0
- package/templates/github/deploy-docker-zero-downtime.yml +140 -0
- package/templates/github/repoforge-graph.yml +45 -0
- package/templates/gitlab/deploy-docker-zero-downtime.yml +57 -0
- package/templates/local-ai/.env.example +17 -0
- package/templates/local-ai/docker-compose.yml +95 -0
- package/templates/security-hooks/claude-settings-security.json +30 -0
- package/templates/security-hooks/commit-msg-signing +29 -0
- package/templates/security-hooks/pre-commit-permissions +74 -0
- package/templates/security-hooks/pre-commit-secrets +74 -0
- package/templates/security-hooks/pre-push-branch-protection +62 -0
- package/templates/security-hooks/pre-push-deps +83 -0
- package/templates/security-hooks/pre-push-signing +67 -0
- package/templates/woodpecker/deploy-docker-zero-downtime.yml +50 -0
- package/templates/workflows/ci-pipeline.dot +15 -0
- package/templates/workflows/feature-flow.dot +21 -0
- package/templates/workflows/release.dot +16 -0
- package/dist/__integration__/helpers.d.ts +0 -20
- package/dist/__integration__/helpers.d.ts.map +0 -1
- package/dist/__integration__/helpers.js +0 -31
- package/dist/__integration__/helpers.js.map +0 -1
- package/dist/commands/analyze.d.ts.map +0 -1
- package/dist/commands/analyze.js.map +0 -1
- package/dist/commands/ci.d.ts.map +0 -1
- package/dist/commands/ci.js.map +0 -1
- package/dist/commands/doctor.d.ts.map +0 -1
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/llmstxt.d.ts.map +0 -1
- package/dist/commands/llmstxt.js.map +0 -1
- package/dist/commands/plugin.d.ts.map +0 -1
- package/dist/commands/plugin.js.map +0 -1
- package/dist/commands/security.d.ts.map +0 -1
- package/dist/commands/security.js.map +0 -1
- package/dist/commands/skills.d.ts.map +0 -1
- package/dist/commands/skills.js.map +0 -1
- package/dist/commands/tdd.d.ts.map +0 -1
- package/dist/commands/tdd.js.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/agent-skills.d.ts.map +0 -1
- package/dist/lib/agent-skills.js.map +0 -1
- package/dist/lib/claudemd.d.ts.map +0 -1
- package/dist/lib/claudemd.js.map +0 -1
- package/dist/lib/codex-export.d.ts.map +0 -1
- package/dist/lib/codex-export.js.map +0 -1
- package/dist/lib/common.d.ts.map +0 -1
- package/dist/lib/common.js.map +0 -1
- package/dist/lib/context.d.ts.map +0 -1
- package/dist/lib/context.js.map +0 -1
- package/dist/lib/docker.d.ts.map +0 -1
- package/dist/lib/docker.js.map +0 -1
- package/dist/lib/frontmatter.d.ts.map +0 -1
- package/dist/lib/frontmatter.js.map +0 -1
- package/dist/lib/plugin.d.ts.map +0 -1
- package/dist/lib/plugin.js.map +0 -1
- package/dist/lib/template.d.ts.map +0 -1
- package/dist/lib/template.js.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/ui/AnalyzeUI.d.ts.map +0 -1
- package/dist/ui/AnalyzeUI.js.map +0 -1
- package/dist/ui/App.d.ts.map +0 -1
- package/dist/ui/App.js.map +0 -1
- package/dist/ui/CI.d.ts.map +0 -1
- package/dist/ui/CI.js.map +0 -1
- package/dist/ui/CIContext.d.ts.map +0 -1
- package/dist/ui/CIContext.js.map +0 -1
- package/dist/ui/CISelector.d.ts.map +0 -1
- package/dist/ui/CISelector.js.map +0 -1
- package/dist/ui/Doctor.d.ts.map +0 -1
- package/dist/ui/Doctor.js.map +0 -1
- package/dist/ui/Header.d.ts.map +0 -1
- package/dist/ui/Header.js.map +0 -1
- package/dist/ui/LlmsTxt.d.ts.map +0 -1
- package/dist/ui/LlmsTxt.js.map +0 -1
- package/dist/ui/MemorySelector.d.ts.map +0 -1
- package/dist/ui/MemorySelector.js.map +0 -1
- package/dist/ui/NameInput.d.ts.map +0 -1
- package/dist/ui/NameInput.js.map +0 -1
- package/dist/ui/OptionSelector.d.ts.map +0 -1
- package/dist/ui/OptionSelector.js.map +0 -1
- package/dist/ui/Plugin.d.ts.map +0 -1
- package/dist/ui/Plugin.js.map +0 -1
- package/dist/ui/Progress.d.ts.map +0 -1
- package/dist/ui/Progress.js.map +0 -1
- package/dist/ui/Skills.d.ts.map +0 -1
- package/dist/ui/Skills.js.map +0 -1
- package/dist/ui/StackSelector.d.ts.map +0 -1
- package/dist/ui/StackSelector.js.map +0 -1
- package/dist/ui/Summary.d.ts.map +0 -1
- package/dist/ui/Summary.js.map +0 -1
- package/dist/ui/Welcome.d.ts.map +0 -1
- package/dist/ui/Welcome.js.map +0 -1
- package/dist/ui/theme.d.ts.map +0 -1
- package/dist/ui/theme.js.map +0 -1
package/dist/ui/StackSelector.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { detectStack, STACK_LABELS } from
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
const ALL_STACKS = [
|
|
1
|
+
import { Box, Text, useInput } from "ink";
|
|
2
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { detectStack, STACK_LABELS } from "../lib/common.js";
|
|
4
|
+
import { useCIMode } from "./CIContext.js";
|
|
5
|
+
import { theme } from "./theme.js";
|
|
6
|
+
const ALL_STACKS = [
|
|
7
|
+
"node",
|
|
8
|
+
"python",
|
|
9
|
+
"go",
|
|
10
|
+
"rust",
|
|
11
|
+
"java-gradle",
|
|
12
|
+
"java-maven",
|
|
13
|
+
"elixir",
|
|
14
|
+
];
|
|
7
15
|
export default function StackSelector({ projectDir, onConfirm }) {
|
|
8
16
|
const isCI = useCIMode();
|
|
9
17
|
const autoConfirmed = useRef(false);
|
|
@@ -11,7 +19,7 @@ export default function StackSelector({ projectDir, onConfirm }) {
|
|
|
11
19
|
const [detectedStack, setDetectedStack] = useState(null);
|
|
12
20
|
const [detecting, setDetecting] = useState(true);
|
|
13
21
|
useEffect(() => {
|
|
14
|
-
detectStack(projectDir).then(result => {
|
|
22
|
+
detectStack(projectDir).then((result) => {
|
|
15
23
|
if (result) {
|
|
16
24
|
setDetectedStack(result.stackType);
|
|
17
25
|
const idx = ALL_STACKS.indexOf(result.stackType);
|
|
@@ -28,13 +36,13 @@ export default function StackSelector({ projectDir, onConfirm }) {
|
|
|
28
36
|
onConfirm(ALL_STACKS[cursor]);
|
|
29
37
|
}
|
|
30
38
|
}, [isCI, detecting]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
31
|
-
useInput((
|
|
39
|
+
useInput((_input, key) => {
|
|
32
40
|
if (detecting)
|
|
33
41
|
return;
|
|
34
42
|
if (key.upArrow)
|
|
35
|
-
setCursor(c => Math.max(0, c - 1));
|
|
43
|
+
setCursor((c) => Math.max(0, c - 1));
|
|
36
44
|
if (key.downArrow)
|
|
37
|
-
setCursor(c => Math.min(ALL_STACKS.length - 1, c + 1));
|
|
45
|
+
setCursor((c) => Math.min(ALL_STACKS.length - 1, c + 1));
|
|
38
46
|
if (key.return) {
|
|
39
47
|
onConfirm(ALL_STACKS[cursor]);
|
|
40
48
|
}
|
|
@@ -46,20 +54,22 @@ export default function StackSelector({ projectDir, onConfirm }) {
|
|
|
46
54
|
return (React.createElement(Box, { flexDirection: "column" },
|
|
47
55
|
React.createElement(Text, { bold: true }, "Select project stack:"),
|
|
48
56
|
detectedStack && (React.createElement(Text, { color: theme.success },
|
|
49
|
-
|
|
57
|
+
" ",
|
|
50
58
|
"Auto-detected: ",
|
|
51
59
|
STACK_LABELS[detectedStack])),
|
|
52
60
|
React.createElement(Box, { marginTop: 1, flexDirection: "column", borderStyle: "single", borderLeft: true, borderRight: false, borderTop: false, borderBottom: false, borderColor: theme.muted, paddingLeft: 1 }, ALL_STACKS.map((stack, i) => (React.createElement(Box, { key: stack },
|
|
53
|
-
React.createElement(Text, { color: i === cursor ? theme.primary :
|
|
54
|
-
i === cursor ?
|
|
55
|
-
stack === detectedStack ?
|
|
61
|
+
React.createElement(Text, { color: i === cursor ? theme.primary : "white" },
|
|
62
|
+
i === cursor ? "\u25b6 " : " ",
|
|
63
|
+
stack === detectedStack ? "\u25c9" : "\u25cb",
|
|
56
64
|
" ",
|
|
57
65
|
STACK_LABELS[stack],
|
|
58
|
-
stack === detectedStack && (React.createElement(Text, { color: theme.success, dimColor: true },
|
|
66
|
+
stack === detectedStack && (React.createElement(Text, { color: theme.success, dimColor: true },
|
|
67
|
+
" ",
|
|
68
|
+
"(detected)"))))))),
|
|
59
69
|
React.createElement(Box, { marginTop: 1, gap: 2 },
|
|
60
70
|
React.createElement(Text, { color: theme.primary }, STACK_LABELS[ALL_STACKS[cursor]]),
|
|
61
71
|
React.createElement(Text, { color: theme.muted, dimColor: true },
|
|
62
|
-
|
|
63
|
-
" navigate
|
|
72
|
+
"\u2191\u2193",
|
|
73
|
+
" navigate Enter confirm"))));
|
|
64
74
|
}
|
|
65
75
|
//# sourceMappingURL=StackSelector.js.map
|
package/dist/ui/Summary.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import type { InitStep } from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { InitStep } from "../types/index.js";
|
|
3
3
|
interface Props {
|
|
4
4
|
steps: InitStep[];
|
|
5
5
|
dryRun: boolean;
|
|
@@ -7,6 +7,6 @@ interface Props {
|
|
|
7
7
|
stack?: string;
|
|
8
8
|
elapsedMs?: number;
|
|
9
9
|
}
|
|
10
|
-
export default function Summary({ steps, dryRun, projectName, stack, elapsedMs }: Props): React.JSX.Element;
|
|
10
|
+
export default function Summary({ steps, dryRun, projectName, stack, elapsedMs, }: Props): React.JSX.Element;
|
|
11
11
|
export {};
|
|
12
12
|
//# sourceMappingURL=Summary.d.ts.map
|
package/dist/ui/Summary.js
CHANGED
|
@@ -1,29 +1,35 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { Box, Text, useApp, useInput } from "ink";
|
|
2
|
+
import React, { useEffect } from "react";
|
|
3
|
+
import { useCIMode } from "./CIContext.js";
|
|
4
|
+
import { theme } from "./theme.js";
|
|
5
5
|
/** Map stack to the install command hint */
|
|
6
6
|
function getInstallHint(stack) {
|
|
7
7
|
switch (stack) {
|
|
8
|
-
case
|
|
9
|
-
|
|
10
|
-
case
|
|
11
|
-
|
|
12
|
-
case
|
|
13
|
-
|
|
14
|
-
case
|
|
15
|
-
|
|
8
|
+
case "node":
|
|
9
|
+
return "pnpm install";
|
|
10
|
+
case "python":
|
|
11
|
+
return "pip install -r requirements.txt";
|
|
12
|
+
case "go":
|
|
13
|
+
return "go mod tidy";
|
|
14
|
+
case "rust":
|
|
15
|
+
return "cargo build";
|
|
16
|
+
case "java-gradle":
|
|
17
|
+
return "./gradlew build";
|
|
18
|
+
case "java-maven":
|
|
19
|
+
return "mvn install";
|
|
20
|
+
case "elixir":
|
|
21
|
+
return "mix deps.get";
|
|
22
|
+
default:
|
|
23
|
+
return null;
|
|
16
24
|
}
|
|
17
25
|
}
|
|
18
|
-
export default function Summary({ steps, dryRun, projectName, stack, elapsedMs }) {
|
|
26
|
+
export default function Summary({ steps, dryRun, projectName, stack, elapsedMs, }) {
|
|
19
27
|
const { exit } = useApp();
|
|
20
28
|
const isCI = useCIMode();
|
|
21
|
-
const done = steps.filter(s => s.status ===
|
|
22
|
-
const skipped = steps.filter(s => s.status ===
|
|
23
|
-
const errors = steps.filter(s => s.status ===
|
|
24
|
-
const elapsed = elapsedMs != null
|
|
25
|
-
? `${(elapsedMs / 1000).toFixed(1)}s`
|
|
26
|
-
: null;
|
|
29
|
+
const done = steps.filter((s) => s.status === "done").length;
|
|
30
|
+
const skipped = steps.filter((s) => s.status === "skipped").length;
|
|
31
|
+
const errors = steps.filter((s) => s.status === "error");
|
|
32
|
+
const elapsed = elapsedMs != null ? `${(elapsedMs / 1000).toFixed(1)}s` : null;
|
|
27
33
|
// Auto-exit in CI mode
|
|
28
34
|
useEffect(() => {
|
|
29
35
|
if (isCI) {
|
|
@@ -39,75 +45,79 @@ export default function Summary({ steps, dryRun, projectName, stack, elapsedMs }
|
|
|
39
45
|
const installHint = getInstallHint(stack);
|
|
40
46
|
return (React.createElement(Box, { flexDirection: "column" },
|
|
41
47
|
React.createElement(Text, { bold: true, color: errors.length > 0 ? theme.warning : theme.success },
|
|
42
|
-
dryRun ?
|
|
48
|
+
dryRun ? "\u25cb Dry run complete" : "\u2713 Project scaffolded",
|
|
43
49
|
elapsed && React.createElement(Text, { color: theme.muted },
|
|
44
|
-
"
|
|
50
|
+
" Completed in ",
|
|
45
51
|
elapsed)),
|
|
46
52
|
React.createElement(Box, { marginTop: 1 },
|
|
47
|
-
React.createElement(Text, { color: theme.muted }, "
|
|
53
|
+
React.createElement(Text, { color: theme.muted }, " Project: "),
|
|
48
54
|
React.createElement(Text, { color: theme.primary, bold: true }, projectName),
|
|
49
55
|
stack && React.createElement(Text, { color: theme.muted },
|
|
50
|
-
"
|
|
56
|
+
" (",
|
|
51
57
|
stack,
|
|
52
58
|
")")),
|
|
53
59
|
dryRun && (React.createElement(Box, { marginTop: 1 },
|
|
54
|
-
React.createElement(Text, { color: theme.warning, bold: true },
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
React.createElement(Text, { color: theme.warning, bold: true },
|
|
61
|
+
" ",
|
|
62
|
+
"No changes were made (dry run)"))),
|
|
63
|
+
React.createElement(Box, { marginTop: 1, flexDirection: "column" }, steps.map((step) => (React.createElement(Box, { key: step.id, marginLeft: 2 }, step.status === "done" ? (React.createElement(Text, { color: theme.success },
|
|
64
|
+
"\u2713",
|
|
57
65
|
" ",
|
|
58
66
|
step.label,
|
|
59
|
-
step.detail ? React.createElement(Text, { color: theme.muted, dimColor: true },
|
|
60
|
-
"
|
|
61
|
-
step.detail) : null)) : step.status ===
|
|
62
|
-
|
|
67
|
+
step.detail ? (React.createElement(Text, { color: theme.muted, dimColor: true },
|
|
68
|
+
" ",
|
|
69
|
+
step.detail)) : null)) : step.status === "skipped" ? (React.createElement(Text, { color: theme.muted },
|
|
70
|
+
"\u2013",
|
|
63
71
|
" ",
|
|
64
72
|
step.label,
|
|
65
73
|
step.detail ? React.createElement(Text, { dimColor: true },
|
|
66
|
-
"
|
|
67
|
-
step.detail) : null)) : step.status ===
|
|
68
|
-
|
|
74
|
+
" ",
|
|
75
|
+
step.detail) : null)) : step.status === "error" ? (React.createElement(Text, { color: theme.error },
|
|
76
|
+
"\u2717",
|
|
69
77
|
" ",
|
|
70
78
|
step.label,
|
|
71
|
-
step.detail ? React.createElement(Text, { color: theme.muted, dimColor: true },
|
|
72
|
-
"
|
|
73
|
-
step.detail) : null)) : null)))),
|
|
79
|
+
step.detail ? (React.createElement(Text, { color: theme.muted, dimColor: true },
|
|
80
|
+
" ",
|
|
81
|
+
step.detail)) : null)) : null)))),
|
|
74
82
|
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
75
83
|
React.createElement(Text, { color: theme.success },
|
|
76
|
-
"
|
|
77
|
-
|
|
84
|
+
" ",
|
|
85
|
+
"\u2713",
|
|
78
86
|
" ",
|
|
79
87
|
done,
|
|
80
88
|
" steps completed"),
|
|
81
89
|
skipped > 0 && (React.createElement(Text, { color: theme.muted },
|
|
82
|
-
"
|
|
83
|
-
|
|
90
|
+
" ",
|
|
91
|
+
"\u2013",
|
|
84
92
|
" ",
|
|
85
93
|
skipped,
|
|
86
94
|
" steps skipped")),
|
|
87
95
|
errors.length > 0 && (React.createElement(Box, { flexDirection: "column" },
|
|
88
96
|
React.createElement(Text, { color: theme.error },
|
|
89
|
-
"
|
|
90
|
-
|
|
97
|
+
" ",
|
|
98
|
+
"\u2717",
|
|
91
99
|
" ",
|
|
92
100
|
errors.length,
|
|
93
101
|
" errors:"),
|
|
94
|
-
errors.map(e => (React.createElement(Text, { key: `err-${e.id}`, color: theme.error },
|
|
95
|
-
"
|
|
96
|
-
|
|
102
|
+
errors.map((e) => (React.createElement(Text, { key: `err-${e.id}`, color: theme.error },
|
|
103
|
+
" ",
|
|
104
|
+
"\u2022",
|
|
97
105
|
" ",
|
|
98
106
|
e.label,
|
|
99
107
|
": ",
|
|
100
108
|
e.detail)))))),
|
|
101
109
|
!dryRun && errors.length === 0 && (React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
102
|
-
React.createElement(Text, { color: theme.muted, bold: true },
|
|
110
|
+
React.createElement(Text, { color: theme.muted, bold: true },
|
|
111
|
+
" ",
|
|
112
|
+
"Next steps:"),
|
|
103
113
|
React.createElement(Text, { color: theme.primary },
|
|
104
|
-
"
|
|
114
|
+
" cd ",
|
|
105
115
|
projectName),
|
|
106
116
|
installHint && React.createElement(Text, { color: theme.primary },
|
|
107
|
-
"
|
|
117
|
+
" ",
|
|
108
118
|
installHint),
|
|
109
|
-
React.createElement(Text, { color: theme.primary }, "
|
|
110
|
-
React.createElement(Text, { color: theme.primary }, "
|
|
119
|
+
React.createElement(Text, { color: theme.primary }, " npx javi-ai sync"),
|
|
120
|
+
React.createElement(Text, { color: theme.primary }, " javi-forge doctor"))),
|
|
111
121
|
React.createElement(Box, { marginTop: 1 },
|
|
112
122
|
React.createElement(Text, { color: theme.muted, dimColor: true }, "Press Enter to exit"))));
|
|
113
123
|
}
|
package/dist/ui/Welcome.d.ts
CHANGED
package/dist/ui/Welcome.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
1
|
+
import { Box, Text } from "ink";
|
|
2
|
+
import Spinner from "ink-spinner";
|
|
3
|
+
import React, { useEffect } from "react";
|
|
4
|
+
import { useCIMode } from "./CIContext.js";
|
|
5
|
+
import Header from "./Header.js";
|
|
6
|
+
import { theme } from "./theme.js";
|
|
7
7
|
export default function Welcome({ onDone }) {
|
|
8
8
|
const isCI = useCIMode();
|
|
9
9
|
useEffect(() => {
|
|
@@ -18,28 +18,27 @@ export default function Welcome({ onDone }) {
|
|
|
18
18
|
React.createElement(Box, { marginTop: 1, flexDirection: "column" },
|
|
19
19
|
React.createElement(Text, null,
|
|
20
20
|
React.createElement(Text, { color: theme.primary },
|
|
21
|
-
|
|
22
|
-
" Templates
|
|
21
|
+
"\u25c6",
|
|
22
|
+
" Templates "),
|
|
23
23
|
React.createElement(Text, { color: theme.muted }, " Go, Java, Node, Python, Rust CI")),
|
|
24
24
|
React.createElement(Text, null,
|
|
25
25
|
React.createElement(Text, { color: theme.success },
|
|
26
|
-
|
|
27
|
-
" Memory
|
|
26
|
+
"\u25c6",
|
|
27
|
+
" Memory "),
|
|
28
28
|
React.createElement(Text, { color: theme.muted }, " Engram, Obsidian Brain")),
|
|
29
29
|
React.createElement(Text, null,
|
|
30
30
|
React.createElement(Text, { color: theme.accent },
|
|
31
|
-
|
|
32
|
-
" SDD
|
|
31
|
+
"\u25c6",
|
|
32
|
+
" SDD "),
|
|
33
33
|
React.createElement(Text, { color: theme.muted }, " Spec-Driven Development")),
|
|
34
34
|
React.createElement(Text, null,
|
|
35
35
|
React.createElement(Text, { color: theme.warning },
|
|
36
|
-
|
|
37
|
-
" Review
|
|
36
|
+
"\u25c6",
|
|
37
|
+
" Review "),
|
|
38
38
|
React.createElement(Text, { color: theme.muted }, " GHAGGA code review"))),
|
|
39
39
|
React.createElement(Box, { marginTop: 1 },
|
|
40
40
|
React.createElement(Text, { color: theme.muted },
|
|
41
41
|
React.createElement(Spinner, { type: "dots" }),
|
|
42
|
-
|
|
43
|
-
"Detecting your environment...")))));
|
|
42
|
+
" Detecting your environment...")))));
|
|
44
43
|
}
|
|
45
44
|
//# sourceMappingURL=Welcome.js.map
|
package/dist/ui/theme.d.ts
CHANGED
package/dist/ui/theme.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export const theme = {
|
|
2
|
-
primary:
|
|
3
|
-
success:
|
|
4
|
-
warning:
|
|
5
|
-
error:
|
|
6
|
-
muted:
|
|
7
|
-
accent:
|
|
2
|
+
primary: "#f97316", // orange
|
|
3
|
+
success: "green",
|
|
4
|
+
warning: "yellow",
|
|
5
|
+
error: "red",
|
|
6
|
+
muted: "gray",
|
|
7
|
+
accent: "magenta",
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=theme.js.map
|
package/lib/common.psm1
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# lib/common.psm1 - Shared functions for javi-forge (PowerShell)
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Mirror of lib/common.sh for Windows / PowerShell users.
|
|
5
|
+
#
|
|
6
|
+
# Import from scripts: Import-Module "$PSScriptRoot/../lib/common.psm1" -Force
|
|
7
|
+
# Import from ci-local: Import-Module "$PSScriptRoot/../lib/common.psm1" -Force
|
|
8
|
+
#
|
|
9
|
+
# Keep this file in sync with lib/common.sh. The function signatures use
|
|
10
|
+
# PowerShell verb-noun conventions but the BEHAVIOUR must match the bash
|
|
11
|
+
# version. Diff against lib/common.sh on every change.
|
|
12
|
+
# =============================================================================
|
|
13
|
+
|
|
14
|
+
Set-StrictMode -Version Latest
|
|
15
|
+
|
|
16
|
+
# =============================================================================
|
|
17
|
+
# Logging helpers
|
|
18
|
+
# =============================================================================
|
|
19
|
+
function Write-Ok { param([string]$Message) Write-Host " [OK] $Message" -ForegroundColor Green }
|
|
20
|
+
function Write-Warn { param([string]$Message) Write-Host " [WARN] $Message" -ForegroundColor Yellow }
|
|
21
|
+
function Write-Fail { param([string]$Message) Write-Host " [FAIL] $Message" -ForegroundColor Red }
|
|
22
|
+
function Write-Info { param([string]$Message) Write-Host " [INFO] $Message" -ForegroundColor Cyan }
|
|
23
|
+
function Write-Step { param([string]$Message) Write-Host $Message -ForegroundColor Yellow }
|
|
24
|
+
|
|
25
|
+
# =============================================================================
|
|
26
|
+
# Backup-FileIfExists - Create a .bak copy of a file before overwriting
|
|
27
|
+
# =============================================================================
|
|
28
|
+
function Backup-FileIfExists {
|
|
29
|
+
param([Parameter(Mandatory)][string]$Path)
|
|
30
|
+
if (Test-Path -LiteralPath $Path -PathType Leaf) {
|
|
31
|
+
Copy-Item -LiteralPath $Path -Destination "$Path.bak" -Force
|
|
32
|
+
Write-Host " Backed up existing $Path" -ForegroundColor Yellow
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# =============================================================================
|
|
37
|
+
# Get-Stack - Auto-detect project technology stack
|
|
38
|
+
# =============================================================================
|
|
39
|
+
# Returns a hashtable with: StackType, BuildTool, JavaVersion
|
|
40
|
+
# Detects: java-gradle, java-maven, node, python, go, rust
|
|
41
|
+
# Mirrors detect_stack() from lib/common.sh.
|
|
42
|
+
# =============================================================================
|
|
43
|
+
function Get-Stack {
|
|
44
|
+
param([string]$ProjectDir = '.')
|
|
45
|
+
|
|
46
|
+
$result = @{
|
|
47
|
+
StackType = 'unknown'
|
|
48
|
+
BuildTool = ''
|
|
49
|
+
JavaVersion = '21'
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# Allow user override via $env:CI_LOCAL_STACK. Mirrors the bash side.
|
|
53
|
+
$override = $env:CI_LOCAL_STACK
|
|
54
|
+
if ($override) {
|
|
55
|
+
$valid = @('node', 'python', 'go', 'rust', 'java-gradle', 'java-maven')
|
|
56
|
+
if ($valid -contains $override) {
|
|
57
|
+
$result.StackType = $override
|
|
58
|
+
switch ($override) {
|
|
59
|
+
'node' {
|
|
60
|
+
if (Test-Path -LiteralPath (Join-Path $ProjectDir 'pnpm-lock.yaml') -PathType Leaf) { $result.BuildTool = 'pnpm' }
|
|
61
|
+
elseif (Test-Path -LiteralPath (Join-Path $ProjectDir 'yarn.lock') -PathType Leaf) { $result.BuildTool = 'yarn' }
|
|
62
|
+
else { $result.BuildTool = 'npm' }
|
|
63
|
+
}
|
|
64
|
+
'python' {
|
|
65
|
+
if (Test-Path -LiteralPath (Join-Path $ProjectDir 'uv.lock') -PathType Leaf) { $result.BuildTool = 'uv' }
|
|
66
|
+
elseif (Test-Path -LiteralPath (Join-Path $ProjectDir 'poetry.lock') -PathType Leaf) { $result.BuildTool = 'poetry' }
|
|
67
|
+
elseif (Test-Path -LiteralPath (Join-Path $ProjectDir 'Pipfile') -PathType Leaf) { $result.BuildTool = 'pipenv' }
|
|
68
|
+
else { $result.BuildTool = 'pip' }
|
|
69
|
+
}
|
|
70
|
+
'go' { $result.BuildTool = 'go' }
|
|
71
|
+
'rust' { $result.BuildTool = 'cargo' }
|
|
72
|
+
'java-gradle' { $result.BuildTool = 'gradle' }
|
|
73
|
+
'java-maven' { $result.BuildTool = 'maven' }
|
|
74
|
+
}
|
|
75
|
+
return $result
|
|
76
|
+
}
|
|
77
|
+
Write-Warning "CI_LOCAL_STACK='$override' is not recognised. Falling back to auto-detection."
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# Java + Gradle
|
|
81
|
+
$gradleKts = Join-Path $ProjectDir 'build.gradle.kts'
|
|
82
|
+
$gradle = Join-Path $ProjectDir 'build.gradle'
|
|
83
|
+
if ((Test-Path -LiteralPath $gradleKts -PathType Leaf) -or
|
|
84
|
+
(Test-Path -LiteralPath $gradle -PathType Leaf)) {
|
|
85
|
+
$result.StackType = 'java-gradle'
|
|
86
|
+
$result.BuildTool = 'gradle'
|
|
87
|
+
# Extract Java version from build file (regex parity with sh version)
|
|
88
|
+
$sourceFile = if (Test-Path -LiteralPath $gradleKts -PathType Leaf) { $gradleKts } else { $gradle }
|
|
89
|
+
try {
|
|
90
|
+
$content = Get-Content -LiteralPath $sourceFile -Raw -ErrorAction Stop
|
|
91
|
+
if ($sourceFile -like '*.kts') {
|
|
92
|
+
if ($content -match 'languageVersion\s*=\s*JavaLanguageVersion\.of\(\s*(\d+)') {
|
|
93
|
+
$result.JavaVersion = $Matches[1]
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
if ($content -match 'sourceCompatibility\s*=\s*[''"]?\s*(\d+)') {
|
|
97
|
+
$result.JavaVersion = $Matches[1]
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
} catch {
|
|
101
|
+
# Keep default '21'
|
|
102
|
+
}
|
|
103
|
+
return $result
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
# Java + Maven
|
|
107
|
+
if (Test-Path -LiteralPath (Join-Path $ProjectDir 'pom.xml') -PathType Leaf) {
|
|
108
|
+
$result.StackType = 'java-maven'
|
|
109
|
+
$result.BuildTool = 'maven'
|
|
110
|
+
return $result
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
# Node.js
|
|
114
|
+
if (Test-Path -LiteralPath (Join-Path $ProjectDir 'package.json') -PathType Leaf) {
|
|
115
|
+
$result.StackType = 'node'
|
|
116
|
+
if (Test-Path -LiteralPath (Join-Path $ProjectDir 'pnpm-lock.yaml') -PathType Leaf) { $result.BuildTool = 'pnpm' }
|
|
117
|
+
elseif (Test-Path -LiteralPath (Join-Path $ProjectDir 'yarn.lock') -PathType Leaf) { $result.BuildTool = 'yarn' }
|
|
118
|
+
else { $result.BuildTool = 'npm' }
|
|
119
|
+
return $result
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
# Python — uv > poetry > pipenv > pip
|
|
123
|
+
$pyMarker = @('pyproject.toml', 'setup.py', 'requirements.txt') |
|
|
124
|
+
ForEach-Object { Join-Path $ProjectDir $_ } |
|
|
125
|
+
Where-Object { Test-Path -LiteralPath $_ -PathType Leaf } |
|
|
126
|
+
Select-Object -First 1
|
|
127
|
+
if ($pyMarker) {
|
|
128
|
+
$result.StackType = 'python'
|
|
129
|
+
if (Test-Path -LiteralPath (Join-Path $ProjectDir 'uv.lock') -PathType Leaf) { $result.BuildTool = 'uv' }
|
|
130
|
+
elseif (Test-Path -LiteralPath (Join-Path $ProjectDir 'poetry.lock') -PathType Leaf) { $result.BuildTool = 'poetry' }
|
|
131
|
+
elseif (Test-Path -LiteralPath (Join-Path $ProjectDir 'Pipfile') -PathType Leaf) { $result.BuildTool = 'pipenv' }
|
|
132
|
+
else { $result.BuildTool = 'pip' }
|
|
133
|
+
return $result
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
# Go
|
|
137
|
+
if (Test-Path -LiteralPath (Join-Path $ProjectDir 'go.mod') -PathType Leaf) {
|
|
138
|
+
$result.StackType = 'go'
|
|
139
|
+
$result.BuildTool = 'go'
|
|
140
|
+
return $result
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
# Rust
|
|
144
|
+
if (Test-Path -LiteralPath (Join-Path $ProjectDir 'Cargo.toml') -PathType Leaf) {
|
|
145
|
+
$result.StackType = 'rust'
|
|
146
|
+
$result.BuildTool = 'cargo'
|
|
147
|
+
return $result
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return $result
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
# =============================================================================
|
|
154
|
+
# Test-CommandExists - Returns $true if a command is available in PATH
|
|
155
|
+
# =============================================================================
|
|
156
|
+
# Replaces "command -v X" from bash.
|
|
157
|
+
# =============================================================================
|
|
158
|
+
function Test-CommandExists {
|
|
159
|
+
param([Parameter(Mandatory)][string]$Name)
|
|
160
|
+
[bool](Get-Command -Name $Name -ErrorAction SilentlyContinue)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
Export-ModuleMember -Function `
|
|
164
|
+
Write-Ok, Write-Warn, Write-Fail, Write-Info, Write-Step, `
|
|
165
|
+
Backup-FileIfExists, `
|
|
166
|
+
Get-Stack, `
|
|
167
|
+
Test-CommandExists
|
package/lib/common.sh
CHANGED
|
@@ -95,6 +95,36 @@ detect_stack() {
|
|
|
95
95
|
BUILD_TOOL=""
|
|
96
96
|
JAVA_VERSION="21"
|
|
97
97
|
|
|
98
|
+
# Allow user to override auto-detection. Useful for hybrid projects
|
|
99
|
+
# (Node + Go) where the first-match rule otherwise locks the choice.
|
|
100
|
+
# Recognised values: node, python, go, rust, java-gradle, java-maven.
|
|
101
|
+
if [ -n "${CI_LOCAL_STACK:-}" ]; then
|
|
102
|
+
case "$CI_LOCAL_STACK" in
|
|
103
|
+
node|python|go|rust|java-gradle|java-maven)
|
|
104
|
+
STACK_TYPE="$CI_LOCAL_STACK"
|
|
105
|
+
case "$STACK_TYPE" in
|
|
106
|
+
node)
|
|
107
|
+
if [ -f "$project_dir/pnpm-lock.yaml" ]; then BUILD_TOOL="pnpm"
|
|
108
|
+
elif [ -f "$project_dir/yarn.lock" ]; then BUILD_TOOL="yarn"
|
|
109
|
+
else BUILD_TOOL="npm"; fi ;;
|
|
110
|
+
python)
|
|
111
|
+
if [ -f "$project_dir/uv.lock" ]; then BUILD_TOOL="uv"
|
|
112
|
+
elif [ -f "$project_dir/poetry.lock" ]; then BUILD_TOOL="poetry"
|
|
113
|
+
elif [ -f "$project_dir/Pipfile" ]; then BUILD_TOOL="pipenv"
|
|
114
|
+
else BUILD_TOOL="pip"; fi ;;
|
|
115
|
+
go) BUILD_TOOL="go" ;;
|
|
116
|
+
rust) BUILD_TOOL="cargo" ;;
|
|
117
|
+
java-gradle) BUILD_TOOL="gradle" ;;
|
|
118
|
+
java-maven) BUILD_TOOL="maven" ;;
|
|
119
|
+
esac
|
|
120
|
+
return
|
|
121
|
+
;;
|
|
122
|
+
*)
|
|
123
|
+
echo "WARNING: CI_LOCAL_STACK='$CI_LOCAL_STACK' is not recognised. Falling back to auto-detection." >&2
|
|
124
|
+
;;
|
|
125
|
+
esac
|
|
126
|
+
fi
|
|
127
|
+
|
|
98
128
|
# Java + Gradle
|
|
99
129
|
if [[ -f "$project_dir/build.gradle" || -f "$project_dir/build.gradle.kts" ]]; then
|
|
100
130
|
STACK_TYPE="java-gradle"
|