@vyuhlabs/dxkit 2.4.7 → 2.5.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.
Files changed (309) hide show
  1. package/CHANGELOG.md +456 -30
  2. package/README.md +360 -439
  3. package/dist/analyzers/bom/gather.d.ts +3 -3
  4. package/dist/analyzers/bom/gather.js +3 -3
  5. package/dist/analyzers/bom/index.js +2 -2
  6. package/dist/analyzers/bom/index.js.map +1 -1
  7. package/dist/analyzers/dashboard/index.d.ts.map +1 -1
  8. package/dist/analyzers/dashboard/index.js +4 -3
  9. package/dist/analyzers/dashboard/index.js.map +1 -1
  10. package/dist/analyzers/developer/index.d.ts.map +1 -1
  11. package/dist/analyzers/developer/index.js +2 -1
  12. package/dist/analyzers/developer/index.js.map +1 -1
  13. package/dist/analyzers/dispatcher.d.ts +15 -0
  14. package/dist/analyzers/dispatcher.d.ts.map +1 -1
  15. package/dist/analyzers/dispatcher.js +42 -6
  16. package/dist/analyzers/dispatcher.js.map +1 -1
  17. package/dist/analyzers/health.d.ts.map +1 -1
  18. package/dist/analyzers/health.js +11 -1
  19. package/dist/analyzers/health.js.map +1 -1
  20. package/dist/analyzers/licenses/gather.d.ts +1 -1
  21. package/dist/analyzers/licenses/gather.d.ts.map +1 -1
  22. package/dist/analyzers/licenses/gather.js +18 -2
  23. package/dist/analyzers/licenses/gather.js.map +1 -1
  24. package/dist/analyzers/quality/index.d.ts.map +1 -1
  25. package/dist/analyzers/quality/index.js +10 -2
  26. package/dist/analyzers/quality/index.js.map +1 -1
  27. package/dist/analyzers/security/aggregator.d.ts.map +1 -1
  28. package/dist/analyzers/security/aggregator.js +8 -48
  29. package/dist/analyzers/security/aggregator.js.map +1 -1
  30. package/dist/analyzers/security/gather.d.ts +4 -3
  31. package/dist/analyzers/security/gather.d.ts.map +1 -1
  32. package/dist/analyzers/security/gather.js +23 -5
  33. package/dist/analyzers/security/gather.js.map +1 -1
  34. package/dist/analyzers/security/index.d.ts +1 -1
  35. package/dist/analyzers/security/index.js +2 -2
  36. package/dist/analyzers/security/index.js.map +1 -1
  37. package/dist/analyzers/tools/autogen-header.js +1 -1
  38. package/dist/analyzers/tools/cloc.js +3 -3
  39. package/dist/analyzers/tools/cloc.js.map +1 -1
  40. package/dist/analyzers/tools/deadline.d.ts +67 -0
  41. package/dist/analyzers/tools/deadline.d.ts.map +1 -0
  42. package/dist/analyzers/tools/deadline.js +81 -0
  43. package/dist/analyzers/tools/deadline.js.map +1 -0
  44. package/dist/analyzers/tools/exclusions.d.ts +6 -6
  45. package/dist/analyzers/tools/exclusions.js +6 -6
  46. package/dist/analyzers/tools/fingerprint.d.ts +91 -26
  47. package/dist/analyzers/tools/fingerprint.d.ts.map +1 -1
  48. package/dist/analyzers/tools/fingerprint.js +111 -22
  49. package/dist/analyzers/tools/fingerprint.js.map +1 -1
  50. package/dist/analyzers/tools/generic.d.ts.map +1 -1
  51. package/dist/analyzers/tools/generic.js +7 -2
  52. package/dist/analyzers/tools/generic.js.map +1 -1
  53. package/dist/analyzers/tools/gitleaks.d.ts +24 -1
  54. package/dist/analyzers/tools/gitleaks.d.ts.map +1 -1
  55. package/dist/analyzers/tools/gitleaks.js +21 -12
  56. package/dist/analyzers/tools/gitleaks.js.map +1 -1
  57. package/dist/analyzers/tools/graphify.js +1 -1
  58. package/dist/analyzers/tools/jscpd.js +1 -1
  59. package/dist/analyzers/tools/jscpd.js.map +1 -1
  60. package/dist/analyzers/tools/lint-label.d.ts +29 -0
  61. package/dist/analyzers/tools/lint-label.d.ts.map +1 -0
  62. package/dist/analyzers/tools/lint-label.js +23 -0
  63. package/dist/analyzers/tools/lint-label.js.map +1 -0
  64. package/dist/analyzers/tools/nuget-package-reference.d.ts +6 -4
  65. package/dist/analyzers/tools/nuget-package-reference.d.ts.map +1 -1
  66. package/dist/analyzers/tools/nuget-package-reference.js +7 -5
  67. package/dist/analyzers/tools/nuget-package-reference.js.map +1 -1
  68. package/dist/analyzers/tools/report-date.d.ts +17 -0
  69. package/dist/analyzers/tools/report-date.d.ts.map +1 -0
  70. package/dist/analyzers/tools/report-date.js +26 -0
  71. package/dist/analyzers/tools/report-date.js.map +1 -0
  72. package/dist/analyzers/tools/runner.js +3 -3
  73. package/dist/analyzers/tools/runner.js.map +1 -1
  74. package/dist/analyzers/tools/vendored-advisor.js +1 -1
  75. package/dist/analyzers/tools/walk-paths.d.ts +1 -1
  76. package/dist/analyzers/tools/walk-paths.js +1 -1
  77. package/dist/analyzers/tools/walk-source-files.js +1 -1
  78. package/dist/analyzers/types.d.ts +6 -4
  79. package/dist/analyzers/types.d.ts.map +1 -1
  80. package/dist/baseline/baseline-file.d.ts +104 -0
  81. package/dist/baseline/baseline-file.d.ts.map +1 -0
  82. package/dist/baseline/baseline-file.js +110 -0
  83. package/dist/baseline/baseline-file.js.map +1 -0
  84. package/dist/baseline/check-renderers.d.ts +108 -0
  85. package/dist/baseline/check-renderers.d.ts.map +1 -0
  86. package/dist/baseline/check-renderers.js +379 -0
  87. package/dist/baseline/check-renderers.js.map +1 -0
  88. package/dist/baseline/check.d.ts +127 -0
  89. package/dist/baseline/check.d.ts.map +1 -0
  90. package/dist/baseline/check.js +462 -0
  91. package/dist/baseline/check.js.map +1 -0
  92. package/dist/baseline/content-hash.d.ts +83 -0
  93. package/dist/baseline/content-hash.d.ts.map +1 -0
  94. package/dist/baseline/content-hash.js +131 -0
  95. package/dist/baseline/content-hash.js.map +1 -0
  96. package/dist/baseline/create.d.ts +96 -0
  97. package/dist/baseline/create.d.ts.map +1 -0
  98. package/dist/baseline/create.js +339 -0
  99. package/dist/baseline/create.js.map +1 -0
  100. package/dist/baseline/entry-to-located.d.ts +35 -0
  101. package/dist/baseline/entry-to-located.d.ts.map +1 -0
  102. package/dist/baseline/entry-to-located.js +72 -0
  103. package/dist/baseline/entry-to-located.js.map +1 -0
  104. package/dist/baseline/finding-identity.d.ts +47 -0
  105. package/dist/baseline/finding-identity.d.ts.map +1 -0
  106. package/dist/baseline/finding-identity.js +292 -0
  107. package/dist/baseline/finding-identity.js.map +1 -0
  108. package/dist/baseline/git-aware-match.d.ts +146 -0
  109. package/dist/baseline/git-aware-match.d.ts.map +1 -0
  110. package/dist/baseline/git-aware-match.js +439 -0
  111. package/dist/baseline/git-aware-match.js.map +1 -0
  112. package/dist/baseline/policy.d.ts +171 -0
  113. package/dist/baseline/policy.d.ts.map +1 -0
  114. package/dist/baseline/policy.js +206 -0
  115. package/dist/baseline/policy.js.map +1 -0
  116. package/dist/baseline/producers/health.d.ts +30 -0
  117. package/dist/baseline/producers/health.d.ts.map +1 -0
  118. package/dist/baseline/producers/health.js +42 -0
  119. package/dist/baseline/producers/health.js.map +1 -0
  120. package/dist/baseline/producers/index.d.ts +164 -0
  121. package/dist/baseline/producers/index.d.ts.map +1 -0
  122. package/dist/baseline/producers/index.js +200 -0
  123. package/dist/baseline/producers/index.js.map +1 -0
  124. package/dist/baseline/producers/licenses.d.ts +23 -0
  125. package/dist/baseline/producers/licenses.d.ts.map +1 -0
  126. package/dist/baseline/producers/licenses.js +46 -0
  127. package/dist/baseline/producers/licenses.js.map +1 -0
  128. package/dist/baseline/producers/quality.d.ts +39 -0
  129. package/dist/baseline/producers/quality.d.ts.map +1 -0
  130. package/dist/baseline/producers/quality.js +84 -0
  131. package/dist/baseline/producers/quality.js.map +1 -0
  132. package/dist/baseline/producers/secret-hmac.d.ts +45 -0
  133. package/dist/baseline/producers/secret-hmac.d.ts.map +1 -0
  134. package/dist/baseline/producers/secret-hmac.js +70 -0
  135. package/dist/baseline/producers/secret-hmac.js.map +1 -0
  136. package/dist/baseline/producers/security.d.ts +59 -0
  137. package/dist/baseline/producers/security.d.ts.map +1 -0
  138. package/dist/baseline/producers/security.js +135 -0
  139. package/dist/baseline/producers/security.js.map +1 -0
  140. package/dist/baseline/producers/tests.d.ts +36 -0
  141. package/dist/baseline/producers/tests.d.ts.map +1 -0
  142. package/dist/baseline/producers/tests.js +69 -0
  143. package/dist/baseline/producers/tests.js.map +1 -0
  144. package/dist/baseline/salt.d.ts +45 -0
  145. package/dist/baseline/salt.d.ts.map +1 -0
  146. package/dist/baseline/salt.js +113 -0
  147. package/dist/baseline/salt.js.map +1 -0
  148. package/dist/baseline/show.d.ts +79 -0
  149. package/dist/baseline/show.d.ts.map +1 -0
  150. package/dist/baseline/show.js +233 -0
  151. package/dist/baseline/show.js.map +1 -0
  152. package/dist/baseline/types.d.ts +482 -0
  153. package/dist/baseline/types.d.ts.map +1 -0
  154. package/dist/baseline/types.js +53 -0
  155. package/dist/baseline/types.js.map +1 -0
  156. package/dist/cli.d.ts.map +1 -1
  157. package/dist/cli.js +395 -92
  158. package/dist/cli.js.map +1 -1
  159. package/dist/codebase-scanner.d.ts.map +1 -1
  160. package/dist/codebase-scanner.js +0 -1
  161. package/dist/codebase-scanner.js.map +1 -1
  162. package/dist/constants.d.ts.map +1 -1
  163. package/dist/constants.js +0 -4
  164. package/dist/constants.js.map +1 -1
  165. package/dist/detect.js +3 -3
  166. package/dist/detect.js.map +1 -1
  167. package/dist/doctor.d.ts.map +1 -1
  168. package/dist/doctor.js +22 -25
  169. package/dist/doctor.js.map +1 -1
  170. package/dist/fail-on.d.ts +84 -0
  171. package/dist/fail-on.d.ts.map +1 -0
  172. package/dist/fail-on.js +128 -0
  173. package/dist/fail-on.js.map +1 -0
  174. package/dist/generator.d.ts.map +1 -1
  175. package/dist/generator.js +2 -141
  176. package/dist/generator.js.map +1 -1
  177. package/dist/languages/capabilities/provider.d.ts +4 -4
  178. package/dist/languages/capabilities/types.d.ts +1 -1
  179. package/dist/languages/csharp.d.ts.map +1 -1
  180. package/dist/languages/csharp.js +15 -24
  181. package/dist/languages/csharp.js.map +1 -1
  182. package/dist/languages/go.d.ts.map +1 -1
  183. package/dist/languages/go.js +0 -15
  184. package/dist/languages/go.js.map +1 -1
  185. package/dist/languages/index.d.ts +4 -3
  186. package/dist/languages/index.d.ts.map +1 -1
  187. package/dist/languages/index.js +3 -2
  188. package/dist/languages/index.js.map +1 -1
  189. package/dist/languages/java.d.ts.map +1 -1
  190. package/dist/languages/java.js +0 -6
  191. package/dist/languages/java.js.map +1 -1
  192. package/dist/languages/kotlin.d.ts.map +1 -1
  193. package/dist/languages/kotlin.js +0 -11
  194. package/dist/languages/kotlin.js.map +1 -1
  195. package/dist/languages/python.d.ts.map +1 -1
  196. package/dist/languages/python.js +0 -15
  197. package/dist/languages/python.js.map +1 -1
  198. package/dist/languages/ruby.d.ts.map +1 -1
  199. package/dist/languages/ruby.js +0 -6
  200. package/dist/languages/ruby.js.map +1 -1
  201. package/dist/languages/rust.d.ts.map +1 -1
  202. package/dist/languages/rust.js +0 -4
  203. package/dist/languages/rust.js.map +1 -1
  204. package/dist/languages/types.d.ts +9 -35
  205. package/dist/languages/types.d.ts.map +1 -1
  206. package/dist/languages/typescript.d.ts.map +1 -1
  207. package/dist/languages/typescript.js +26 -4
  208. package/dist/languages/typescript.js.map +1 -1
  209. package/dist/lib.d.ts +2 -3
  210. package/dist/lib.d.ts.map +1 -1
  211. package/dist/lib.js +3 -6
  212. package/dist/lib.js.map +1 -1
  213. package/dist/prompts.d.ts.map +1 -1
  214. package/dist/prompts.js +0 -10
  215. package/dist/prompts.js.map +1 -1
  216. package/dist/report-schema.d.ts +42 -0
  217. package/dist/report-schema.d.ts.map +1 -0
  218. package/dist/report-schema.js +54 -0
  219. package/dist/report-schema.js.map +1 -0
  220. package/dist/ship-installers.d.ts +106 -0
  221. package/dist/ship-installers.d.ts.map +1 -0
  222. package/dist/ship-installers.js +415 -0
  223. package/dist/ship-installers.js.map +1 -0
  224. package/dist/types.d.ts +0 -4
  225. package/dist/types.d.ts.map +1 -1
  226. package/dist/update.d.ts.map +1 -1
  227. package/dist/update.js +0 -4
  228. package/dist/update.js.map +1 -1
  229. package/package.json +17 -11
  230. package/templates/.claude/agents/onboarding.md +5 -4
  231. package/templates/.claude/agents-available/codebase-explorer.md +1 -1
  232. package/templates/.claude/agents-available/debugger.md +2 -2
  233. package/templates/.claude/agents-available/health-auditor.md +2 -2
  234. package/templates/.claude/commands/doctor.md +20 -12
  235. package/templates/.claude/skills/build/SKILL.md.template +22 -30
  236. package/templates/.claude/skills/deploy/SKILL.md.template +5 -25
  237. package/templates/.claude/skills/doctor/SKILL.md +24 -47
  238. package/templates/.claude/skills/gcloud/SKILL.md +5 -5
  239. package/templates/.claude/skills/learned/SKILL.md +1 -1
  240. package/templates/.claude/skills/pulumi/SKILL.md +2 -2
  241. package/templates/.claude/skills/quality/SKILL.md.template +4 -23
  242. package/templates/.claude/skills/review/SKILL.md.template +4 -3
  243. package/templates/.claude/skills/scaffold/SKILL.md.template +5 -15
  244. package/templates/.claude/skills/secrets/SKILL.md +20 -21
  245. package/templates/.claude/skills/session/SKILL.md +20 -31
  246. package/templates/.claude/skills/test/SKILL.md.template +1 -7
  247. package/templates/.devcontainer/devcontainer.json +81 -0
  248. package/templates/.devcontainer/install-agent-clis.sh +42 -0
  249. package/templates/.devcontainer/post-create.sh +67 -0
  250. package/templates/.githooks/pre-commit +55 -0
  251. package/templates/.githooks/pre-push +63 -0
  252. package/templates/.github/workflows/dxkit-baseline-refresh.yml +78 -0
  253. package/templates/.github/workflows/dxkit-guardrails.yml +98 -0
  254. package/templates/CLAUDE.md.template +62 -196
  255. package/dist/project-yaml.d.ts +0 -13
  256. package/dist/project-yaml.d.ts.map +0 -1
  257. package/dist/project-yaml.js +0 -188
  258. package/dist/project-yaml.js.map +0 -1
  259. package/templates/.ai/README.md +0 -117
  260. package/templates/.ai/prompts/execution-prompt.md +0 -9
  261. package/templates/.ai/prompts/planning-prompt.md +0 -18
  262. package/templates/.ai/prompts/session-end-template.md +0 -182
  263. package/templates/.ai/prompts/session-end.md +0 -132
  264. package/templates/.ai/prompts/session-start.md +0 -109
  265. package/templates/.ai/prompts/step-by-step.md +0 -113
  266. package/templates/.ai/sessions/.gitkeep +0 -0
  267. package/templates/.claude/commands/setup-pr-review.md +0 -72
  268. package/templates/.devcontainer/Dockerfile.dev.template +0 -89
  269. package/templates/.devcontainer/devcontainer.json.template +0 -184
  270. package/templates/.devcontainer/docker-compose.yml.template +0 -105
  271. package/templates/.devcontainer/init-scripts/01-init.sql.template +0 -12
  272. package/templates/.devcontainer/post-create.sh.template +0 -298
  273. package/templates/.github/workflows/ci.yml.template +0 -399
  274. package/templates/.github/workflows/quality.yml.template +0 -376
  275. package/templates/.pre-commit-config.yaml.template +0 -106
  276. package/templates/.project/config/edit_config.py +0 -275
  277. package/templates/.project/config/project_config.py +0 -894
  278. package/templates/.project/scripts/codegen/generate-all.sh +0 -20
  279. package/templates/.project/scripts/codegen/validate-all.sh +0 -17
  280. package/templates/.project/scripts/docs/generate-all.sh +0 -30
  281. package/templates/.project/scripts/docs/serve.sh +0 -20
  282. package/templates/.project/scripts/quality/fix-all.sh +0 -138
  283. package/templates/.project/scripts/quality/lint-go.sh +0 -34
  284. package/templates/.project/scripts/quality/lint-python.sh +0 -54
  285. package/templates/.project/scripts/quality/run-all.sh +0 -497
  286. package/templates/.project/scripts/session/commit.sh +0 -70
  287. package/templates/.project/scripts/session/create-pr.sh +0 -165
  288. package/templates/.project/scripts/session/end.sh +0 -207
  289. package/templates/.project/scripts/session/start.sh +0 -233
  290. package/templates/.project/scripts/setup/doctor.sh +0 -404
  291. package/templates/.project/scripts/setup/interactive-setup.sh +0 -585
  292. package/templates/.project/scripts/sync/sync-template.sh +0 -328
  293. package/templates/.project/scripts/test/run-all.sh +0 -179
  294. package/templates/.project/scripts/test/run-quick.sh +0 -25
  295. package/templates/Makefile +0 -514
  296. package/templates/config/versions.yaml +0 -57
  297. package/templates/configs/go/.golangci.yml.template +0 -172
  298. package/templates/configs/go/go.mod.template +0 -15
  299. package/templates/configs/java/README.md +0 -6
  300. package/templates/configs/kotlin/README.md +0 -6
  301. package/templates/configs/node/package.json.template +0 -67
  302. package/templates/configs/node/tsconfig.json.template +0 -53
  303. package/templates/configs/python/pyproject.toml.template +0 -92
  304. package/templates/configs/python/pytest.ini.template +0 -64
  305. package/templates/configs/python/ruff.toml.template +0 -79
  306. package/templates/configs/ruby/README.md +0 -6
  307. package/templates/configs/rust/Cargo.toml.template +0 -51
  308. package/templates/configs/shared/.editorconfig +0 -67
  309. package/templates/scripts/validate-templates.sh +0 -449
@@ -1,585 +0,0 @@
1
- #!/bin/bash
2
- set -e
3
-
4
- # Colors
5
- CYAN='\033[36m'
6
- GREEN='\033[32m'
7
- YELLOW='\033[33m'
8
- RED='\033[31m'
9
- BOLD='\033[1m'
10
- DIM='\033[2m'
11
- RESET='\033[0m'
12
-
13
- echo ""
14
- echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
15
- echo -e "${CYAN} PROJECT SETUP${RESET}"
16
- echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
17
- echo ""
18
-
19
- # ============================================================================
20
- # Helper Functions
21
- # ============================================================================
22
-
23
- # Read a value from .project.yaml
24
- read_config() {
25
- local path="$1"
26
- local default="$2"
27
- if [ -f ".project.yaml" ] && command -v python3 &> /dev/null; then
28
- python3 -c "
29
- import yaml
30
- try:
31
- with open('.project.yaml') as f:
32
- c = yaml.safe_load(f)
33
- keys = '$path'.split('.')
34
- val = c
35
- for k in keys:
36
- val = val.get(k, {}) if isinstance(val, dict) else {}
37
- print('true' if val is True else ('false' if val is False else (val if val else '$default')))
38
- except:
39
- print('$default')
40
- " 2>/dev/null || echo "$default"
41
- else
42
- echo "$default"
43
- fi
44
- }
45
-
46
- # ============================================================================
47
- # Quality Tools Installation
48
- # ============================================================================
49
-
50
- echo -e "${BOLD}Installing Quality Tools${RESET}"
51
- echo ""
52
-
53
- # Check enabled languages from config
54
- PYTHON_ENABLED=$(read_config "languages.python.enabled" "false")
55
- GO_ENABLED=$(read_config "languages.go.enabled" "false")
56
- NODE_ENABLED=$(read_config "languages.node.enabled" "false")
57
- RUST_ENABLED=$(read_config "languages.rust.enabled" "false")
58
-
59
- # Go tools
60
- if [ "$GO_ENABLED" = "true" ] && command -v go &> /dev/null; then
61
- echo -e "${CYAN}Go tools:${RESET}"
62
- if ! command -v golangci-lint &> /dev/null; then
63
- echo -e " ${CYAN}→${RESET} Installing golangci-lint..."
64
- go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest > /dev/null 2>&1 && \
65
- echo -e " ${GREEN}✓${RESET} golangci-lint installed"
66
- else
67
- echo -e " ${GREEN}✓${RESET} golangci-lint already installed"
68
- fi
69
-
70
- if ! command -v goimports &> /dev/null; then
71
- echo -e " ${CYAN}→${RESET} Installing goimports..."
72
- go install golang.org/x/tools/cmd/goimports@latest > /dev/null 2>&1 && \
73
- echo -e " ${GREEN}✓${RESET} goimports installed"
74
- else
75
- echo -e " ${GREEN}✓${RESET} goimports already installed"
76
- fi
77
- echo ""
78
- fi
79
-
80
- # Python tools
81
- if [ "$PYTHON_ENABLED" = "true" ] && command -v pip &> /dev/null; then
82
- echo -e "${CYAN}Python tools:${RESET}"
83
- if [ -f "pyproject.toml" ]; then
84
- echo -e " ${CYAN}→${RESET} Installing Python dev dependencies..."
85
- # Versions synced with .template/config/versions.yaml
86
- pip install -q -e ".[dev]" 2>/dev/null || pip install -q "ruff>=0.8.0" "mypy>=1.8.0" "pytest>=8.0.0" pytest-cov 2>/dev/null
87
- echo -e " ${GREEN}✓${RESET} Python tools installed"
88
- else
89
- # Versions synced with .template/config/versions.yaml
90
- pip install -q "ruff>=0.8.0" "mypy>=1.8.0" "pytest>=8.0.0" pytest-cov 2>/dev/null
91
- echo -e " ${GREEN}✓${RESET} Python tools installed"
92
- fi
93
- echo ""
94
- fi
95
-
96
- # Node.js tools
97
- if [ "$NODE_ENABLED" = "true" ] && command -v npm &> /dev/null; then
98
- echo -e "${CYAN}Node.js tools:${RESET}"
99
- if [ -f "package.json" ]; then
100
- echo -e " ${CYAN}→${RESET} Installing npm dependencies..."
101
- if npm install --silent 2>/dev/null; then
102
- echo -e " ${GREEN}✓${RESET} npm dependencies installed"
103
- else
104
- echo -e " ${YELLOW}!${RESET} npm install failed (peer dependency conflicts?)"
105
- echo -e " ${DIM} Try: npm install --legacy-peer-deps${RESET}"
106
- fi
107
- fi
108
- echo ""
109
- fi
110
-
111
- # Rust tools
112
- if [ "$RUST_ENABLED" = "true" ] && command -v rustup &> /dev/null; then
113
- echo -e "${CYAN}Rust tools:${RESET}"
114
- rustup component add rustfmt clippy 2>/dev/null
115
- echo -e " ${GREEN}✓${RESET} rustfmt and clippy installed"
116
- echo ""
117
- fi
118
-
119
- # ============================================================================
120
- # Cloud Tools Authentication
121
- # ============================================================================
122
-
123
- # Read tool configuration
124
- CLAUDE_CODE_ENABLED=$(read_config "tools.claude_code" "false")
125
- GITHUB_CLI_ENABLED=$(read_config "tools.github_cli" "false")
126
- GCLOUD_ENABLED=$(read_config "tools.gcloud" "false")
127
- PULUMI_ENABLED=$(read_config "tools.pulumi" "false")
128
- INFISICAL_ENABLED=$(read_config "tools.infisical" "false")
129
-
130
- # Check if any cloud tools are enabled
131
- if [ "$CLAUDE_CODE_ENABLED" = "true" ] || [ "$GITHUB_CLI_ENABLED" = "true" ] || \
132
- [ "$GCLOUD_ENABLED" = "true" ] || [ "$PULUMI_ENABLED" = "true" ] || \
133
- [ "$INFISICAL_ENABLED" = "true" ]; then
134
-
135
- echo ""
136
- echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
137
- echo -e "${CYAN} CLOUD TOOLS AUTHENTICATION${RESET}"
138
- echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
139
- echo ""
140
- echo -e "${DIM}Set up authentication for your cloud tools.${RESET}"
141
- echo -e "${DIM}You can skip any tool by pressing Enter or Ctrl+C.${RESET}"
142
- echo ""
143
- fi
144
-
145
- # GitHub CLI
146
- if [ "$GITHUB_CLI_ENABLED" = "true" ]; then
147
- if command -v gh &> /dev/null; then
148
- echo -e "${BOLD}GitHub CLI${RESET}"
149
- if gh auth status &> /dev/null; then
150
- echo -e " ${GREEN}✓${RESET} Already authenticated"
151
- gh auth status 2>&1 | head -3 | sed 's/^/ /'
152
- else
153
- echo -e " ${YELLOW}!${RESET} Not authenticated"
154
- read -p " Login to GitHub? [Y/n]: " -n 1 -r gh_login
155
- echo ""
156
- if [[ ! $gh_login =~ ^[Nn]$ ]]; then
157
- gh auth login
158
- fi
159
- fi
160
- echo ""
161
- fi
162
- fi
163
-
164
- # Claude Code CLI
165
- if [ "$CLAUDE_CODE_ENABLED" = "true" ]; then
166
- if command -v claude &> /dev/null; then
167
- echo -e "${BOLD}Claude Code CLI${RESET}"
168
-
169
- # Check if API key is configured
170
- API_KEY_SET=false
171
- if [ -n "$ANTHROPIC_API_KEY" ] || ([ -f ".env" ] && grep -q "ANTHROPIC_API_KEY" .env 2>/dev/null); then
172
- API_KEY_SET=true
173
- fi
174
-
175
- # Check if OAuth is configured (by checking if claude can run without prompting)
176
- # We can't easily check OAuth status without running claude interactively,
177
- # so we just check if credentials file exists
178
- OAUTH_SET=false
179
- if [ -f "$HOME/.claude/credentials.json" ] || [ -f "$HOME/.config/claude/credentials.json" ]; then
180
- OAUTH_SET=true
181
- fi
182
-
183
- if [ "$API_KEY_SET" = "true" ]; then
184
- echo -e " ${GREEN}✓${RESET} API key configured (for programmatic use)"
185
- fi
186
- if [ "$OAUTH_SET" = "true" ]; then
187
- echo -e " ${GREEN}✓${RESET} OAuth login configured (for interactive use)"
188
- fi
189
-
190
- if [ "$API_KEY_SET" = "false" ] && [ "$OAUTH_SET" = "false" ]; then
191
- echo -e " ${YELLOW}!${RESET} Not authenticated"
192
- echo ""
193
- echo -e " ${DIM}Claude Code supports two authentication methods:${RESET}"
194
- echo -e " ${DIM} 1. OAuth login (recommended) - Login with Claude.ai/Console account${RESET}"
195
- echo -e " ${DIM} 2. API key - For programmatic/CI use${RESET}"
196
- echo ""
197
- echo " Choose authentication method:"
198
- echo " 1) OAuth login (recommended for interactive use)"
199
- echo " 2) API key (for CI/programmatic use)"
200
- echo " 3) Skip"
201
- read -p " Enter choice [1-3]: " auth_choice
202
-
203
- case $auth_choice in
204
- 1)
205
- echo ""
206
- echo -e " ${CYAN}→${RESET} Starting Claude Code for OAuth login..."
207
- echo -e " ${DIM}This will open a browser for authentication.${RESET}"
208
- echo -e " ${DIM}After login, you can exit with Ctrl+C or /exit${RESET}"
209
- echo ""
210
- read -p " Press Enter to continue..."
211
- claude || true
212
- echo -e " ${GREEN}✓${RESET} OAuth setup complete"
213
- ;;
214
- 2)
215
- echo ""
216
- echo -e " ${DIM}Get your API key from: https://console.anthropic.com/settings/keys${RESET}"
217
- read -p " Enter Anthropic API key: " api_key
218
- if [ -n "$api_key" ]; then
219
- # Add to .env file
220
- if [ ! -f ".env" ]; then
221
- echo "# Environment variables" > .env
222
- echo "" >> .env
223
- fi
224
- # Remove existing key if present
225
- if [ -f ".env" ]; then
226
- grep -v "^ANTHROPIC_API_KEY=" .env > .env.tmp 2>/dev/null || true
227
- mv .env.tmp .env
228
- fi
229
- echo "ANTHROPIC_API_KEY=$api_key" >> .env
230
- echo -e " ${GREEN}✓${RESET} API key saved to .env"
231
- echo -e " ${DIM}Run: source .env (or restart your shell)${RESET}"
232
- fi
233
- ;;
234
- *)
235
- echo -e " ${DIM}Skipped${RESET}"
236
- ;;
237
- esac
238
- elif [ "$API_KEY_SET" = "false" ]; then
239
- # OAuth is set but API key is not - offer to add API key for CI
240
- read -p " Add API key for CI/programmatic use? [y/N]: " -n 1 -r add_api_key
241
- echo ""
242
- if [[ $add_api_key =~ ^[Yy]$ ]]; then
243
- echo -e " ${DIM}Get your API key from: https://console.anthropic.com/settings/keys${RESET}"
244
- read -p " Enter Anthropic API key: " api_key
245
- if [ -n "$api_key" ]; then
246
- if [ ! -f ".env" ]; then
247
- echo "# Environment variables" > .env
248
- echo "" >> .env
249
- fi
250
- echo "ANTHROPIC_API_KEY=$api_key" >> .env
251
- echo -e " ${GREEN}✓${RESET} API key saved to .env"
252
- fi
253
- fi
254
- fi
255
- echo ""
256
- fi
257
- fi
258
-
259
- # Google Cloud SDK
260
- if [ "$GCLOUD_ENABLED" = "true" ]; then
261
- echo -e "${BOLD}Google Cloud SDK${RESET}"
262
-
263
- # Check if CLI is available
264
- GCLOUD_CLI_AVAILABLE=false
265
- if command -v gcloud &> /dev/null; then
266
- GCLOUD_CLI_AVAILABLE=true
267
- else
268
- echo -e " ${DIM}CLI not installed yet (will be installed on container rebuild)${RESET}"
269
- fi
270
-
271
- # Check if project ID already in .env
272
- GCLOUD_CONFIGURED=false
273
- if [ -f ".env" ] && grep -q "GOOGLE_CLOUD_PROJECT" .env 2>/dev/null; then
274
- GCLOUD_CONFIGURED=true
275
- GCP_PROJECT=$(grep "GOOGLE_CLOUD_PROJECT" .env | cut -d= -f2)
276
- echo -e " ${GREEN}✓${RESET} Project ID configured: $GCP_PROJECT"
277
-
278
- read -p " Reconfigure GCP project? [y/N]: " -n 1 -r reconfig
279
- echo ""
280
- if [[ $reconfig =~ ^[Yy]$ ]]; then
281
- GCLOUD_CONFIGURED=false
282
- fi
283
- fi
284
-
285
- if [ "$GCLOUD_CLI_AVAILABLE" = "true" ]; then
286
- # CLI is available - check auth status
287
- if gcloud auth list --filter=status:ACTIVE --format="value(account)" 2>/dev/null | grep -q "@"; then
288
- ACCOUNT=$(gcloud auth list --filter=status:ACTIVE --format="value(account)" 2>/dev/null | head -1)
289
- echo -e " ${GREEN}✓${RESET} Authenticated as: $ACCOUNT"
290
-
291
- # Sync project from gcloud config if not in .env
292
- if [ "$GCLOUD_CONFIGURED" = "false" ]; then
293
- PROJECT=$(gcloud config get-value project 2>/dev/null)
294
- if [ -n "$PROJECT" ] && [ "$PROJECT" != "(unset)" ]; then
295
- echo -e " ${GREEN}✓${RESET} Current gcloud project: $PROJECT"
296
- read -p " Use this project? [Y/n]: " -n 1 -r use_current
297
- echo ""
298
- if [[ ! $use_current =~ ^[Nn]$ ]]; then
299
- gcp_project="$PROJECT"
300
- else
301
- read -p " Enter GCP project ID: " gcp_project
302
- fi
303
- else
304
- read -p " Enter GCP project ID (or press Enter to skip): " gcp_project
305
- fi
306
-
307
- if [ -n "$gcp_project" ]; then
308
- gcloud config set project "$gcp_project"
309
- # Save to .env
310
- if [ ! -f ".env" ]; then
311
- echo "# Environment variables" > .env
312
- echo "" >> .env
313
- fi
314
- grep -v "^GOOGLE_CLOUD_PROJECT=" .env > .env.tmp 2>/dev/null || true
315
- mv .env.tmp .env
316
- echo "GOOGLE_CLOUD_PROJECT=$gcp_project" >> .env
317
- echo -e " ${GREEN}✓${RESET} Project set to: $gcp_project"
318
- fi
319
- fi
320
- else
321
- echo -e " ${YELLOW}!${RESET} Not authenticated"
322
- read -p " Login to Google Cloud? [Y/n]: " -n 1 -r gcloud_login
323
- echo ""
324
- if [[ ! $gcloud_login =~ ^[Nn]$ ]]; then
325
- gcloud auth login
326
- read -p " Enter GCP project ID (or press Enter to skip): " gcp_project
327
- if [ -n "$gcp_project" ]; then
328
- gcloud config set project "$gcp_project"
329
- # Save to .env
330
- if [ ! -f ".env" ]; then
331
- echo "# Environment variables" > .env
332
- echo "" >> .env
333
- fi
334
- grep -v "^GOOGLE_CLOUD_PROJECT=" .env > .env.tmp 2>/dev/null || true
335
- mv .env.tmp .env
336
- echo "GOOGLE_CLOUD_PROJECT=$gcp_project" >> .env
337
- echo -e " ${GREEN}✓${RESET} Project saved to .env"
338
- fi
339
- fi
340
- fi
341
- else
342
- # CLI not available - just prompt for project ID to save in .env
343
- if [ "$GCLOUD_CONFIGURED" = "false" ]; then
344
- echo ""
345
- echo -e " ${DIM}Enter your GCP project ID to save for later use.${RESET}"
346
- read -p " Enter GCP project ID (or press Enter to skip): " gcp_project
347
-
348
- if [ -n "$gcp_project" ]; then
349
- # Save to .env
350
- if [ ! -f ".env" ]; then
351
- echo "# Environment variables" > .env
352
- echo "" >> .env
353
- fi
354
- grep -v "^GOOGLE_CLOUD_PROJECT=" .env > .env.tmp 2>/dev/null || true
355
- mv .env.tmp .env
356
- echo "GOOGLE_CLOUD_PROJECT=$gcp_project" >> .env
357
- echo -e " ${GREEN}✓${RESET} Project ID saved to .env"
358
- echo -e " ${DIM}Run 'gcloud auth login' after CLI is installed${RESET}"
359
- else
360
- echo -e " ${DIM}Skipped${RESET}"
361
- fi
362
- fi
363
- fi
364
- echo ""
365
- fi
366
-
367
- # Pulumi
368
- if [ "$PULUMI_ENABLED" = "true" ]; then
369
- echo -e "${BOLD}Pulumi${RESET}"
370
-
371
- # Check if pulumi is in PATH or in ~/.pulumi/bin
372
- PULUMI_CMD=""
373
- if command -v pulumi &> /dev/null; then
374
- PULUMI_CMD="pulumi"
375
- elif [ -f "$HOME/.pulumi/bin/pulumi" ]; then
376
- PULUMI_CMD="$HOME/.pulumi/bin/pulumi"
377
- fi
378
-
379
- if [ -n "$PULUMI_CMD" ]; then
380
- if $PULUMI_CMD whoami &> /dev/null; then
381
- PULUMI_USER=$($PULUMI_CMD whoami 2>/dev/null)
382
- echo -e " ${GREEN}✓${RESET} Logged in as: $PULUMI_USER"
383
- else
384
- echo -e " ${YELLOW}!${RESET} Not logged in"
385
- read -p " Login to Pulumi? [Y/n]: " -n 1 -r pulumi_login
386
- echo ""
387
- if [[ ! $pulumi_login =~ ^[Nn]$ ]]; then
388
- $PULUMI_CMD login
389
- fi
390
- fi
391
- else
392
- echo -e " ${DIM}CLI not installed yet (will be installed on container rebuild)${RESET}"
393
- echo -e " ${DIM}Run 'pulumi login' after CLI is installed${RESET}"
394
- fi
395
- echo ""
396
- fi
397
-
398
- # Infisical
399
- if [ "$INFISICAL_ENABLED" = "true" ]; then
400
- echo -e "${BOLD}Infisical (Secrets Management)${RESET}"
401
-
402
- # Check if CLI is available
403
- INFISICAL_CLI_AVAILABLE=false
404
- if command -v infisical &> /dev/null; then
405
- INFISICAL_CLI_AVAILABLE=true
406
- else
407
- echo -e " ${DIM}CLI not installed yet (will be installed on container rebuild)${RESET}"
408
- fi
409
-
410
- # Check if already configured in .env
411
- INFISICAL_CONFIGURED=false
412
- if [ -f ".env" ] && grep -q "INFISICAL_TOKEN" .env 2>/dev/null; then
413
- INFISICAL_CONFIGURED=true
414
- echo -e " ${GREEN}✓${RESET} Infisical token configured in .env"
415
-
416
- # Show current config
417
- if grep -q "INFISICAL_PROJECT_ID" .env 2>/dev/null; then
418
- PROJECT_ID=$(grep "INFISICAL_PROJECT_ID" .env | cut -d= -f2)
419
- echo -e " ${GREEN}✓${RESET} Project ID: $PROJECT_ID"
420
- fi
421
- if grep -q "INFISICAL_ENV" .env 2>/dev/null; then
422
- ENV_NAME=$(grep "INFISICAL_ENV" .env | cut -d= -f2)
423
- echo -e " ${GREEN}✓${RESET} Environment: $ENV_NAME"
424
- fi
425
-
426
- read -p " Reconfigure Infisical? [y/N]: " -n 1 -r reconfig
427
- echo ""
428
- if [[ ! $reconfig =~ ^[Yy]$ ]]; then
429
- INFISICAL_CONFIGURED=true
430
- else
431
- INFISICAL_CONFIGURED=false
432
- fi
433
- fi
434
-
435
- if [ "$INFISICAL_CONFIGURED" = "false" ]; then
436
- echo ""
437
- echo -e " ${DIM}Configure Infisical to pull secrets from a specific project/path.${RESET}"
438
- echo -e " ${DIM}Get your service token from: https://app.infisical.com${RESET}"
439
- echo ""
440
-
441
- # Service Token
442
- read -p " Enter Infisical Service Token (or press Enter to skip): " infisical_token
443
-
444
- if [ -n "$infisical_token" ]; then
445
- # Project ID
446
- read -p " Enter Project ID: " project_id
447
-
448
- # Environment
449
- echo " Environment options: dev, staging, prod (or custom)"
450
- read -p " Enter environment [dev]: " env_name
451
- env_name="${env_name:-dev}"
452
-
453
- # Save to .env
454
- if [ ! -f ".env" ]; then
455
- echo "# Environment variables" > .env
456
- echo "" >> .env
457
- fi
458
-
459
- # Remove existing Infisical config if present
460
- if [ -f ".env" ]; then
461
- grep -v "^INFISICAL_" .env > .env.tmp 2>/dev/null || true
462
- mv .env.tmp .env
463
- fi
464
-
465
- # Add Infisical config
466
- cat >> .env << INFISICAL_EOF
467
-
468
- # Infisical Configuration
469
- INFISICAL_TOKEN=$infisical_token
470
- INFISICAL_PROJECT_ID=$project_id
471
- INFISICAL_ENV=$env_name
472
- INFISICAL_EOF
473
-
474
- echo -e " ${GREEN}✓${RESET} Infisical configuration saved to .env"
475
-
476
- # Offer to pull secrets now (only if CLI is available)
477
- if [ "$INFISICAL_CLI_AVAILABLE" = "true" ]; then
478
- read -p " Pull secrets now? [Y/n]: " -n 1 -r pull_now
479
- echo ""
480
- if [[ ! $pull_now =~ ^[Nn]$ ]]; then
481
- echo -e " ${CYAN}→${RESET} Pulling secrets (env: $env_name)..."
482
-
483
- # Export secrets using the token
484
- if INFISICAL_TOKEN="$infisical_token" infisical export \
485
- --projectId="$project_id" \
486
- --env="$env_name" \
487
- --format=dotenv > .env.secrets 2>/dev/null; then
488
-
489
- # Merge secrets (avoiding duplicates and Infisical config)
490
- while IFS= read -r line; do
491
- # Skip empty lines and comments
492
- [[ -z "$line" || "$line" == \#* ]] && continue
493
- key=$(echo "$line" | cut -d= -f1)
494
- # Don't overwrite Infisical config vars
495
- if [[ "$key" != INFISICAL_* ]] && ! grep -q "^$key=" .env 2>/dev/null; then
496
- echo "$line" >> .env
497
- fi
498
- done < .env.secrets
499
- rm .env.secrets
500
-
501
- echo -e " ${GREEN}✓${RESET} Secrets pulled and merged into .env"
502
- else
503
- echo -e " ${YELLOW}!${RESET} Failed to pull secrets (check token/permissions)"
504
- rm -f .env.secrets
505
- fi
506
- fi
507
- else
508
- echo -e " ${DIM}Run 'make secrets-pull' after CLI is installed to pull secrets${RESET}"
509
- fi
510
-
511
- echo ""
512
- echo -e " ${DIM}To pull secrets later: make secrets-pull${RESET}"
513
- else
514
- echo -e " ${DIM}Skipped${RESET}"
515
- fi
516
- fi
517
- echo ""
518
- fi
519
-
520
- # ============================================================================
521
- # Create .env template if it doesn't exist
522
- # ============================================================================
523
-
524
- if [ ! -f ".env" ] && [ ! -f ".env.example" ]; then
525
- echo -e "${BOLD}Environment Variables${RESET}"
526
- echo ""
527
-
528
- # Check what tools are enabled and create appropriate .env.example
529
- cat > .env.example << 'ENVEOF'
530
- # Environment Variables
531
- # Copy this file to .env and fill in your values
532
- # cp .env.example .env
533
-
534
- ENVEOF
535
-
536
- if [ "$CLAUDE_CODE_ENABLED" = "true" ]; then
537
- echo "# Claude Code" >> .env.example
538
- echo "ANTHROPIC_API_KEY=your-api-key-here" >> .env.example
539
- echo "" >> .env.example
540
- fi
541
-
542
- if [ "$GCLOUD_ENABLED" = "true" ]; then
543
- echo "# Google Cloud" >> .env.example
544
- echo "GOOGLE_CLOUD_PROJECT=your-project-id" >> .env.example
545
- echo "# GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json" >> .env.example
546
- echo "" >> .env.example
547
- fi
548
-
549
- if [ "$INFISICAL_ENABLED" = "true" ]; then
550
- echo "# Infisical - Get service token from https://app.infisical.com" >> .env.example
551
- echo "INFISICAL_TOKEN=your-service-token" >> .env.example
552
- echo "INFISICAL_PROJECT_ID=your-project-id" >> .env.example
553
- echo "INFISICAL_ENV=dev" >> .env.example
554
- echo "" >> .env.example
555
- fi
556
-
557
- if [ "$PULUMI_ENABLED" = "true" ]; then
558
- echo "# Pulumi" >> .env.example
559
- echo "# PULUMI_ACCESS_TOKEN=your-token-here" >> .env.example
560
- echo "" >> .env.example
561
- fi
562
-
563
- echo -e " ${GREEN}✓${RESET} Created .env.example template"
564
- echo -e " ${DIM}Copy to .env and fill in your values: cp .env.example .env${RESET}"
565
- echo ""
566
- fi
567
-
568
- # ============================================================================
569
- # Summary
570
- # ============================================================================
571
-
572
- echo ""
573
- echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
574
- echo -e "${GREEN} SETUP COMPLETE${RESET}"
575
- echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
576
- echo ""
577
- echo -e "${BOLD}Next steps:${RESET}"
578
- echo " • Run ${CYAN}make doctor${RESET} to verify your setup"
579
- echo " • Run ${CYAN}make help${RESET} to see available commands"
580
- echo " • Run ${CYAN}make check${RESET} to verify quality and tests"
581
- echo ""
582
- if [ -f ".env.example" ] && [ ! -f ".env" ]; then
583
- echo -e "${YELLOW}Don't forget:${RESET} Copy .env.example to .env and add your secrets"
584
- echo ""
585
- fi