specweave 0.6.8 → 0.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.
Files changed (255) hide show
  1. package/.claude-plugin/README.md +1 -1
  2. package/CLAUDE.md +903 -99
  3. package/README.md +143 -207
  4. package/bin/specweave.js +67 -0
  5. package/dist/cli/commands/abandon.d.ts +13 -0
  6. package/dist/cli/commands/abandon.d.ts.map +1 -0
  7. package/dist/cli/commands/abandon.js +15 -0
  8. package/dist/cli/commands/abandon.js.map +1 -0
  9. package/dist/cli/commands/init.d.ts.map +1 -1
  10. package/dist/cli/commands/init.js +90 -18
  11. package/dist/cli/commands/init.js.map +1 -1
  12. package/dist/cli/commands/pause.d.ts +13 -0
  13. package/dist/cli/commands/pause.d.ts.map +1 -0
  14. package/dist/cli/commands/pause.js +15 -0
  15. package/dist/cli/commands/pause.js.map +1 -0
  16. package/dist/cli/commands/qa.d.ts +54 -0
  17. package/dist/cli/commands/qa.d.ts.map +1 -0
  18. package/dist/cli/commands/qa.js +98 -0
  19. package/dist/cli/commands/qa.js.map +1 -0
  20. package/dist/cli/commands/resume.d.ts +12 -0
  21. package/dist/cli/commands/resume.d.ts.map +1 -0
  22. package/dist/cli/commands/resume.js +14 -0
  23. package/dist/cli/commands/resume.js.map +1 -0
  24. package/dist/cli/commands/status.d.ts +12 -0
  25. package/dist/cli/commands/status.d.ts.map +1 -0
  26. package/dist/cli/commands/status.js +23 -0
  27. package/dist/cli/commands/status.js.map +1 -0
  28. package/dist/cli/helpers/issue-tracker/ado.d.ts +57 -0
  29. package/dist/cli/helpers/issue-tracker/ado.d.ts.map +1 -0
  30. package/dist/cli/helpers/issue-tracker/ado.js +223 -0
  31. package/dist/cli/helpers/issue-tracker/ado.js.map +1 -0
  32. package/dist/cli/helpers/issue-tracker/github.d.ts +65 -0
  33. package/dist/cli/helpers/issue-tracker/github.d.ts.map +1 -0
  34. package/dist/cli/helpers/issue-tracker/github.js +284 -0
  35. package/dist/cli/helpers/issue-tracker/github.js.map +1 -0
  36. package/dist/cli/helpers/issue-tracker/index.d.ts +22 -0
  37. package/dist/cli/helpers/issue-tracker/index.d.ts.map +1 -0
  38. package/dist/cli/helpers/issue-tracker/index.js +270 -0
  39. package/dist/cli/helpers/issue-tracker/index.js.map +1 -0
  40. package/dist/cli/helpers/issue-tracker/jira.d.ts +61 -0
  41. package/dist/cli/helpers/issue-tracker/jira.d.ts.map +1 -0
  42. package/dist/cli/helpers/issue-tracker/jira.js +265 -0
  43. package/dist/cli/helpers/issue-tracker/jira.js.map +1 -0
  44. package/dist/cli/helpers/issue-tracker/types.d.ts +86 -0
  45. package/dist/cli/helpers/issue-tracker/types.d.ts.map +1 -0
  46. package/dist/cli/helpers/issue-tracker/types.js +16 -0
  47. package/dist/cli/helpers/issue-tracker/types.js.map +1 -0
  48. package/dist/cli/helpers/issue-tracker/utils.d.ts +103 -0
  49. package/dist/cli/helpers/issue-tracker/utils.d.ts.map +1 -0
  50. package/dist/cli/helpers/issue-tracker/utils.js +240 -0
  51. package/dist/cli/helpers/issue-tracker/utils.js.map +1 -0
  52. package/dist/core/increment/limits.d.ts +68 -0
  53. package/dist/core/increment/limits.d.ts.map +1 -0
  54. package/dist/core/increment/limits.js +224 -0
  55. package/dist/core/increment/limits.js.map +1 -0
  56. package/dist/core/increment/metadata-manager.d.ts +114 -0
  57. package/dist/core/increment/metadata-manager.d.ts.map +1 -0
  58. package/dist/core/increment/metadata-manager.js +320 -0
  59. package/dist/core/increment/metadata-manager.js.map +1 -0
  60. package/dist/core/increment/status-commands.d.ts +43 -0
  61. package/dist/core/increment/status-commands.d.ts.map +1 -0
  62. package/dist/core/increment/status-commands.js +277 -0
  63. package/dist/core/increment/status-commands.js.map +1 -0
  64. package/dist/core/plugin-detector.d.ts +1 -0
  65. package/dist/core/plugin-detector.d.ts.map +1 -1
  66. package/dist/core/plugin-detector.js +25 -0
  67. package/dist/core/plugin-detector.js.map +1 -1
  68. package/dist/core/qa/qa-runner.d.ts +16 -0
  69. package/dist/core/qa/qa-runner.d.ts.map +1 -0
  70. package/dist/core/qa/qa-runner.js +404 -0
  71. package/dist/core/qa/qa-runner.js.map +1 -0
  72. package/dist/core/qa/quality-gate-decider.d.ts +53 -0
  73. package/dist/core/qa/quality-gate-decider.d.ts.map +1 -0
  74. package/dist/core/qa/quality-gate-decider.js +268 -0
  75. package/dist/core/qa/quality-gate-decider.js.map +1 -0
  76. package/dist/core/qa/risk-calculator.d.ts +126 -0
  77. package/dist/core/qa/risk-calculator.d.ts.map +1 -0
  78. package/dist/core/qa/risk-calculator.js +247 -0
  79. package/dist/core/qa/risk-calculator.js.map +1 -0
  80. package/dist/core/qa/types.d.ts +315 -0
  81. package/dist/core/qa/types.d.ts.map +1 -0
  82. package/dist/core/qa/types.js +8 -0
  83. package/dist/core/qa/types.js.map +1 -0
  84. package/dist/core/types/config.d.ts +35 -0
  85. package/dist/core/types/config.d.ts.map +1 -1
  86. package/dist/core/types/config.js +16 -0
  87. package/dist/core/types/config.js.map +1 -1
  88. package/dist/core/types/increment-metadata.d.ts +120 -0
  89. package/dist/core/types/increment-metadata.d.ts.map +1 -0
  90. package/dist/core/types/increment-metadata.js +138 -0
  91. package/dist/core/types/increment-metadata.js.map +1 -0
  92. package/dist/hooks/lib/invoke-translator-skill.d.ts +60 -0
  93. package/dist/hooks/lib/invoke-translator-skill.d.ts.map +1 -0
  94. package/dist/hooks/lib/invoke-translator-skill.js +201 -0
  95. package/dist/hooks/lib/invoke-translator-skill.js.map +1 -0
  96. package/dist/hooks/lib/translate-file.d.ts +59 -0
  97. package/dist/hooks/lib/translate-file.d.ts.map +1 -0
  98. package/dist/hooks/lib/translate-file.js +350 -0
  99. package/dist/hooks/lib/translate-file.js.map +1 -0
  100. package/dist/locales/en/cli.json +3 -1
  101. package/dist/metrics/calculators/change-failure-rate.d.ts +22 -0
  102. package/dist/metrics/calculators/change-failure-rate.d.ts.map +1 -0
  103. package/dist/metrics/calculators/change-failure-rate.js +70 -0
  104. package/dist/metrics/calculators/change-failure-rate.js.map +1 -0
  105. package/dist/metrics/calculators/deployment-frequency.d.ts +20 -0
  106. package/dist/metrics/calculators/deployment-frequency.d.ts.map +1 -0
  107. package/dist/metrics/calculators/deployment-frequency.js +61 -0
  108. package/dist/metrics/calculators/deployment-frequency.js.map +1 -0
  109. package/dist/metrics/calculators/lead-time.d.ts +22 -0
  110. package/dist/metrics/calculators/lead-time.d.ts.map +1 -0
  111. package/dist/metrics/calculators/lead-time.js +82 -0
  112. package/dist/metrics/calculators/lead-time.js.map +1 -0
  113. package/dist/metrics/calculators/mttr.d.ts +21 -0
  114. package/dist/metrics/calculators/mttr.d.ts.map +1 -0
  115. package/dist/metrics/calculators/mttr.js +60 -0
  116. package/dist/metrics/calculators/mttr.js.map +1 -0
  117. package/dist/metrics/dora-calculator.d.ts +24 -0
  118. package/dist/metrics/dora-calculator.d.ts.map +1 -0
  119. package/dist/metrics/dora-calculator.js +104 -0
  120. package/dist/metrics/dora-calculator.js.map +1 -0
  121. package/dist/metrics/github-client.d.ts +51 -0
  122. package/dist/metrics/github-client.d.ts.map +1 -0
  123. package/dist/metrics/github-client.js +133 -0
  124. package/dist/metrics/github-client.js.map +1 -0
  125. package/dist/metrics/types.d.ts +112 -0
  126. package/dist/metrics/types.d.ts.map +1 -0
  127. package/dist/metrics/types.js +10 -0
  128. package/dist/metrics/types.js.map +1 -0
  129. package/dist/metrics/utils/percentile.d.ts +25 -0
  130. package/dist/metrics/utils/percentile.d.ts.map +1 -0
  131. package/dist/metrics/utils/percentile.js +46 -0
  132. package/dist/metrics/utils/percentile.js.map +1 -0
  133. package/dist/metrics/utils/tier-classifier.d.ts +61 -0
  134. package/dist/metrics/utils/tier-classifier.d.ts.map +1 -0
  135. package/dist/metrics/utils/tier-classifier.js +100 -0
  136. package/dist/metrics/utils/tier-classifier.js.map +1 -0
  137. package/dist/utils/auth-helpers.d.ts +58 -0
  138. package/dist/utils/auth-helpers.d.ts.map +1 -0
  139. package/dist/utils/auth-helpers.js +108 -0
  140. package/dist/utils/auth-helpers.js.map +1 -0
  141. package/dist/utils/env-file.d.ts +88 -0
  142. package/dist/utils/env-file.d.ts.map +1 -0
  143. package/dist/utils/env-file.js +180 -0
  144. package/dist/utils/env-file.js.map +1 -0
  145. package/dist/utils/plugin-detection.d.ts +50 -0
  146. package/dist/utils/plugin-detection.d.ts.map +1 -0
  147. package/dist/utils/plugin-detection.js +229 -0
  148. package/dist/utils/plugin-detection.js.map +1 -0
  149. package/dist/utils/secrets-loader.d.ts +88 -0
  150. package/dist/utils/secrets-loader.d.ts.map +1 -0
  151. package/dist/utils/secrets-loader.js +271 -0
  152. package/dist/utils/secrets-loader.js.map +1 -0
  153. package/dist/utils/translation.d.ts +187 -0
  154. package/dist/utils/translation.d.ts.map +1 -0
  155. package/dist/utils/translation.js +414 -0
  156. package/dist/utils/translation.js.map +1 -0
  157. package/package.json +28 -44
  158. package/plugins/specweave/.claude-plugin/plugin.json +3 -3
  159. package/plugins/specweave/agents/pm/AGENT.md +330 -54
  160. package/plugins/specweave/agents/test-aware-planner/AGENT.md +1035 -0
  161. package/plugins/specweave/agents/test-aware-planner/templates/README.md +118 -0
  162. package/plugins/specweave/agents/test-aware-planner/templates/task-non-testable.md.template +24 -0
  163. package/plugins/specweave/agents/test-aware-planner/templates/task-testable.md.template +53 -0
  164. package/plugins/specweave/agents/test-aware-planner/templates/tasks-frontmatter.md.template +11 -0
  165. package/plugins/specweave/commands/README.md +88 -163
  166. package/plugins/specweave/commands/specweave-abandon.md +314 -0
  167. package/plugins/specweave/commands/specweave-check-tests.md +546 -0
  168. package/plugins/specweave/commands/{do.md → specweave-do.md} +5 -7
  169. package/plugins/specweave/commands/{increment.md → specweave-increment.md} +231 -4
  170. package/plugins/specweave/commands/specweave-pause.md +189 -0
  171. package/plugins/specweave/commands/specweave-qa.md +245 -0
  172. package/plugins/specweave/commands/specweave-resume.md +216 -0
  173. package/plugins/specweave/commands/specweave-status.md +397 -0
  174. package/plugins/specweave/commands/specweave-sync-tasks.md +256 -0
  175. package/plugins/specweave/commands/{translate.md → specweave-translate.md} +3 -3
  176. package/plugins/specweave/commands/specweave-update-scope.md +351 -0
  177. package/plugins/specweave/commands/specweave.md +21 -21
  178. package/plugins/specweave/hooks/post-increment-planning.sh +335 -0
  179. package/plugins/specweave/hooks/post-task-completion.sh +141 -0
  180. package/plugins/specweave/skills/SKILLS-INDEX.md +1 -1
  181. package/plugins/specweave/skills/brownfield-analyzer/SKILL.md +9 -9
  182. package/plugins/specweave/skills/increment-planner/SKILL.md +400 -212
  183. package/plugins/specweave/skills/increment-quality-judge-v2/SKILL.md +499 -0
  184. package/plugins/specweave/skills/plugin-detector/SKILL.md +114 -1
  185. package/plugins/specweave/skills/project-kickstarter/SKILL.md +74 -1
  186. package/plugins/specweave/skills/{rfc-generator → spec-generator}/SKILL.md +22 -29
  187. package/plugins/specweave/skills/specweave-detector/SKILL.md +3 -3
  188. package/plugins/specweave/skills/specweave-framework/SKILL.md +2 -2
  189. package/plugins/specweave-ado/.claude-plugin/plugin.json +18 -4
  190. package/plugins/specweave-ado/agents/ado-manager/AGENT.md +426 -0
  191. package/plugins/specweave-ado/commands/close-workitem.md +52 -0
  192. package/plugins/specweave-ado/commands/create-workitem.md +53 -0
  193. package/plugins/specweave-ado/commands/status.md +53 -0
  194. package/plugins/specweave-ado/commands/sync.md +55 -0
  195. package/plugins/specweave-ado/lib/ado-client.ts +361 -0
  196. package/plugins/specweave-ado/reference/ado-specweave-mapping.md +552 -0
  197. package/plugins/specweave-ado/skills/ado-sync/SKILL.md +344 -193
  198. package/plugins/specweave-docs/skills/docusaurus/SKILL.md +73 -0
  199. package/plugins/specweave-github/agents/github-manager/AGENT.md +49 -0
  200. package/plugins/specweave-github/commands/{github-close-issue.md → close-issue.md} +1 -1
  201. package/plugins/specweave-github/commands/{github-create-issue.md → create-issue.md} +1 -1
  202. package/plugins/specweave-github/commands/{github-status.md → status.md} +1 -1
  203. package/plugins/specweave-github/commands/{github-sync-tasks.md → sync-tasks.md} +1 -1
  204. package/plugins/specweave-github/commands/{github-sync.md → sync.md} +1 -1
  205. package/plugins/specweave-github/reference/github-specweave-mapping.md +377 -0
  206. package/plugins/specweave-github/skills/github-sync/SKILL.md +11 -3
  207. package/plugins/specweave-infrastructure/commands/{specweave.monitor-setup.md → monitor-setup.md} +5 -0
  208. package/plugins/specweave-infrastructure/commands/{specweave.slo-implement.md → slo-implement.md} +5 -0
  209. package/plugins/specweave-jira/agents/jira-manager/AGENT.md +380 -0
  210. package/plugins/specweave-jira/commands/{specweave.sync-jira.md → sync.md} +1 -1
  211. package/plugins/specweave-jira/reference/jira-specweave-mapping.md +508 -0
  212. package/plugins/specweave-ml/commands/ml-deploy.md +1 -1
  213. package/plugins/specweave-ml/commands/ml-evaluate.md +1 -1
  214. package/plugins/specweave-ml/commands/ml-explain.md +1 -1
  215. package/plugins/specweave-ml/commands/{specweave.ml-pipeline.md → ml-pipeline.md} +5 -0
  216. package/src/templates/AGENTS.md.template +331 -31
  217. package/src/templates/CLAUDE.md.template +36 -21
  218. package/src/templates/COMPLETION-REPORT.template.md +128 -0
  219. package/src/templates/README.md.template +17 -16
  220. package/src/templates/docs/README.md +11 -9
  221. package/src/templates/docs/spec-template.md +229 -0
  222. package/plugins/specweave/commands/inc.md +0 -85
  223. package/plugins/specweave/commands/list-increments.md +0 -180
  224. package/src/adapters/README.md +0 -275
  225. package/src/adapters/adapter-base.ts +0 -182
  226. package/src/adapters/adapter-interface.ts +0 -166
  227. package/src/adapters/adapter-loader.ts +0 -256
  228. package/src/adapters/agents-md-generator.ts +0 -228
  229. package/src/adapters/claude/README.md +0 -233
  230. package/src/adapters/claude/adapter.ts +0 -468
  231. package/src/adapters/claude-md-generator.ts +0 -377
  232. package/src/adapters/codex/README.md +0 -105
  233. package/src/adapters/codex/adapter.ts +0 -333
  234. package/src/adapters/cursor/.cursor/context/docs-context.md +0 -62
  235. package/src/adapters/cursor/.cursor/context/increments-context.md +0 -71
  236. package/src/adapters/cursor/.cursor/context/strategy-context.md +0 -73
  237. package/src/adapters/cursor/.cursor/context/tests-context.md +0 -89
  238. package/src/adapters/cursor/README.md +0 -283
  239. package/src/adapters/cursor/adapter.ts +0 -451
  240. package/src/adapters/doc-generator.ts +0 -331
  241. package/src/adapters/gemini/README.md +0 -97
  242. package/src/adapters/gemini/adapter.ts +0 -298
  243. package/src/adapters/generic/README.md +0 -277
  244. package/src/adapters/generic/adapter.ts +0 -378
  245. package/src/adapters/registry.yaml +0 -187
  246. /package/plugins/specweave/commands/{costs.md → specweave-costs.md} +0 -0
  247. /package/plugins/specweave/commands/{done.md → specweave-done.md} +0 -0
  248. /package/plugins/specweave/commands/{next.md → specweave-next.md} +0 -0
  249. /package/plugins/specweave/commands/{progress.md → specweave-progress.md} +0 -0
  250. /package/plugins/specweave/commands/{sync-docs.md → specweave-sync-docs.md} +0 -0
  251. /package/plugins/specweave/commands/{tdd-cycle.md → specweave-tdd-cycle.md} +0 -0
  252. /package/plugins/specweave/commands/{tdd-green.md → specweave-tdd-green.md} +0 -0
  253. /package/plugins/specweave/commands/{tdd-red.md → specweave-tdd-red.md} +0 -0
  254. /package/plugins/specweave/commands/{tdd-refactor.md → specweave-tdd-refactor.md} +0 -0
  255. /package/plugins/specweave/commands/{validate.md → specweave-validate.md} +0 -0
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Environment File Utilities
3
+ *
4
+ * Parse, update, and validate .env files
5
+ *
6
+ * @module utils/env-file
7
+ */
8
+ import * as fs from 'fs';
9
+ import * as path from 'path';
10
+ /**
11
+ * Parse .env file content into key-value pairs
12
+ *
13
+ * @param content - Content of .env file
14
+ * @returns Record of key-value pairs
15
+ */
16
+ export function parseEnvFile(content) {
17
+ const result = {};
18
+ const lines = content.split('\n');
19
+ for (const line of lines) {
20
+ const trimmed = line.trim();
21
+ // Skip empty lines and comments
22
+ if (!trimmed || trimmed.startsWith('#')) {
23
+ continue;
24
+ }
25
+ // Parse KEY=VALUE
26
+ const equalsIndex = trimmed.indexOf('=');
27
+ if (equalsIndex > 0) {
28
+ const key = trimmed.substring(0, equalsIndex).trim();
29
+ const value = trimmed.substring(equalsIndex + 1).trim();
30
+ // Remove quotes if present
31
+ const unquotedValue = value.replace(/^["']|["']$/g, '');
32
+ result[key] = unquotedValue;
33
+ }
34
+ }
35
+ return result;
36
+ }
37
+ /**
38
+ * Update or add environment variable in .env content
39
+ *
40
+ * @param envContent - Current .env file content
41
+ * @param key - Environment variable key
42
+ * @param value - Environment variable value
43
+ * @returns Updated .env content
44
+ */
45
+ export function updateEnvVar(envContent, key, value) {
46
+ const regex = new RegExp(`^${key}=.*$`, 'm');
47
+ if (regex.test(envContent)) {
48
+ // Update existing variable
49
+ return envContent.replace(regex, `${key}=${value}`);
50
+ }
51
+ else {
52
+ // Add new variable (append)
53
+ const trimmed = envContent.trim();
54
+ return trimmed ? `${trimmed}\n${key}=${value}\n` : `${key}=${value}\n`;
55
+ }
56
+ }
57
+ /**
58
+ * Update multiple environment variables
59
+ *
60
+ * @param envContent - Current .env file content
61
+ * @param vars - Array of environment variables to update
62
+ * @returns Updated .env content
63
+ */
64
+ export function updateEnvVars(envContent, vars) {
65
+ let result = envContent;
66
+ for (const { key, value } of vars) {
67
+ result = updateEnvVar(result, key, value);
68
+ }
69
+ return result;
70
+ }
71
+ /**
72
+ * Read .env file from project directory
73
+ *
74
+ * @param projectPath - Path to project root
75
+ * @returns Content of .env file, or empty string if not found
76
+ */
77
+ export function readEnvFile(projectPath) {
78
+ const envPath = path.join(projectPath, '.env');
79
+ if (fs.existsSync(envPath)) {
80
+ return fs.readFileSync(envPath, 'utf-8');
81
+ }
82
+ return '';
83
+ }
84
+ /**
85
+ * Write .env file to project directory
86
+ *
87
+ * @param projectPath - Path to project root
88
+ * @param content - Content to write
89
+ */
90
+ export function writeEnvFile(projectPath, content) {
91
+ const envPath = path.join(projectPath, '.env');
92
+ fs.writeFileSync(envPath, content, 'utf-8');
93
+ // Set user-only read/write permissions (0o600) for security
94
+ // This prevents other users on the system from reading sensitive credentials
95
+ try {
96
+ fs.chmodSync(envPath, 0o600);
97
+ }
98
+ catch (error) {
99
+ // Non-critical error - log but continue (Windows doesn't support chmod)
100
+ if (process.env.DEBUG) {
101
+ console.error(`Warning: Could not set .env permissions: ${error}`);
102
+ }
103
+ }
104
+ }
105
+ /**
106
+ * Create .env file from .env.example template
107
+ *
108
+ * @param projectPath - Path to project root
109
+ * @returns Content of .env file (from template or empty)
110
+ */
111
+ export function createEnvFromTemplate(projectPath) {
112
+ const envExamplePath = path.join(projectPath, '.env.example');
113
+ if (fs.existsSync(envExamplePath)) {
114
+ return fs.readFileSync(envExamplePath, 'utf-8');
115
+ }
116
+ return '';
117
+ }
118
+ /**
119
+ * Verify .env is in .gitignore
120
+ *
121
+ * @param projectPath - Path to project root
122
+ * @returns True if .env is gitignored, false otherwise
123
+ */
124
+ export function isEnvGitignored(projectPath) {
125
+ const gitignorePath = path.join(projectPath, '.gitignore');
126
+ if (!fs.existsSync(gitignorePath)) {
127
+ return false;
128
+ }
129
+ const gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8');
130
+ return gitignoreContent.includes('.env');
131
+ }
132
+ /**
133
+ * Add .env to .gitignore if not already present
134
+ *
135
+ * @param projectPath - Path to project root
136
+ */
137
+ export function ensureEnvGitignored(projectPath) {
138
+ const gitignorePath = path.join(projectPath, '.gitignore');
139
+ if (!isEnvGitignored(projectPath)) {
140
+ // Append .env to .gitignore
141
+ const existingContent = fs.existsSync(gitignorePath)
142
+ ? fs.readFileSync(gitignorePath, 'utf-8')
143
+ : '';
144
+ const updatedContent = existingContent.trim()
145
+ ? `${existingContent}\n.env\n`
146
+ : '.env\n';
147
+ fs.writeFileSync(gitignorePath, updatedContent, 'utf-8');
148
+ }
149
+ }
150
+ /**
151
+ * Validate required environment variables are present
152
+ *
153
+ * @param envContent - Content of .env file
154
+ * @param requiredKeys - Array of required keys
155
+ * @returns Object with validation result and missing keys
156
+ */
157
+ export function validateEnvVars(envContent, requiredKeys) {
158
+ const parsed = parseEnvFile(envContent);
159
+ const missing = [];
160
+ for (const key of requiredKeys) {
161
+ if (!parsed[key] || parsed[key].trim() === '') {
162
+ missing.push(key);
163
+ }
164
+ }
165
+ return {
166
+ valid: missing.length === 0,
167
+ missing
168
+ };
169
+ }
170
+ /**
171
+ * Check if .env file exists in project
172
+ *
173
+ * @param projectPath - Path to project root
174
+ * @returns True if .env exists, false otherwise
175
+ */
176
+ export function envFileExists(projectPath) {
177
+ const envPath = path.join(projectPath, '.env');
178
+ return fs.existsSync(envPath);
179
+ }
180
+ //# sourceMappingURL=env-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-file.js","sourceRoot":"","sources":["../../src/utils/env-file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Plugin Detection Utility
3
+ *
4
+ * Maps project tech stack signals to SpecWeave plugins.
5
+ * Used by:
6
+ * - specweave init (scan project structure)
7
+ * - plugin-detector skill (runtime detection)
8
+ */
9
+ /**
10
+ * Plugin detection result
11
+ */
12
+ export interface DetectedPlugin {
13
+ name: string;
14
+ reason: string;
15
+ confidence: 'high' | 'medium' | 'low';
16
+ signals: string[];
17
+ }
18
+ /**
19
+ * Project tech stack signals
20
+ */
21
+ interface TechStackSignals {
22
+ hasPackageJson: boolean;
23
+ hasPyProject: boolean;
24
+ hasRequirementsTxt: boolean;
25
+ hasCsproj: boolean;
26
+ hasGemfile: boolean;
27
+ dependencies: string[];
28
+ devDependencies: string[];
29
+ files: string[];
30
+ folders: string[];
31
+ gitRemote: string | null;
32
+ }
33
+ /**
34
+ * Scan project directory for tech stack signals
35
+ */
36
+ export declare function scanProjectStructure(projectDir: string): Promise<TechStackSignals>;
37
+ /**
38
+ * Detect required plugins based on tech stack signals
39
+ */
40
+ export declare function detectPlugins(signals: TechStackSignals): DetectedPlugin[];
41
+ /**
42
+ * Format detected plugins for CLI output
43
+ */
44
+ export declare function formatDetectedPlugins(plugins: DetectedPlugin[]): string;
45
+ /**
46
+ * Generate install commands for detected plugins
47
+ */
48
+ export declare function generateInstallCommands(plugins: DetectedPlugin[]): string[];
49
+ export {};
50
+ //# sourceMappingURL=plugin-detection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-detection.d.ts","sourceRoot":"","sources":["../../src/utils/plugin-detection.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,UAAU,gBAAgB;IAExB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IAGpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,EAAE,MAAM,EAAE,CAAC;IAG1B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAGlB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkExF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,cAAc,EAAE,CAwLzE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,CAoCvE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAQ3E"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Plugin Detection Utility
3
+ *
4
+ * Maps project tech stack signals to SpecWeave plugins.
5
+ * Used by:
6
+ * - specweave init (scan project structure)
7
+ * - plugin-detector skill (runtime detection)
8
+ */
9
+ import * as fs from 'fs';
10
+ import * as path from 'path';
11
+ /**
12
+ * Scan project directory for tech stack signals
13
+ */
14
+ export async function scanProjectStructure(projectDir) {
15
+ const signals = {
16
+ hasPackageJson: false,
17
+ hasPyProject: false,
18
+ hasRequirementsTxt: false,
19
+ hasCsproj: false,
20
+ hasGemfile: false,
21
+ dependencies: [],
22
+ devDependencies: [],
23
+ files: [],
24
+ folders: [],
25
+ gitRemote: null,
26
+ };
27
+ // Check package.json
28
+ const packageJsonPath = path.join(projectDir, 'package.json');
29
+ if (fs.existsSync(packageJsonPath)) {
30
+ signals.hasPackageJson = true;
31
+ try {
32
+ const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
33
+ signals.dependencies = Object.keys(pkg.dependencies || {});
34
+ signals.devDependencies = Object.keys(pkg.devDependencies || {});
35
+ }
36
+ catch (e) {
37
+ // Ignore parse errors
38
+ }
39
+ }
40
+ // Check Python files
41
+ signals.hasPyProject = fs.existsSync(path.join(projectDir, 'pyproject.toml'));
42
+ signals.hasRequirementsTxt = fs.existsSync(path.join(projectDir, 'requirements.txt'));
43
+ // Check .NET files
44
+ const csprojFiles = fs.readdirSync(projectDir).filter(f => f.endsWith('.csproj'));
45
+ signals.hasCsproj = csprojFiles.length > 0;
46
+ // Check Ruby
47
+ signals.hasGemfile = fs.existsSync(path.join(projectDir, 'Gemfile'));
48
+ // Scan folders (top-level only to avoid deep recursion)
49
+ try {
50
+ const entries = fs.readdirSync(projectDir, { withFileTypes: true });
51
+ signals.folders = entries
52
+ .filter(e => e.isDirectory() && !e.name.startsWith('.'))
53
+ .map(e => e.name);
54
+ signals.files = entries
55
+ .filter(e => e.isFile())
56
+ .map(e => e.name);
57
+ }
58
+ catch (e) {
59
+ // Ignore permission errors
60
+ }
61
+ // Check git remote
62
+ const gitConfigPath = path.join(projectDir, '.git', 'config');
63
+ if (fs.existsSync(gitConfigPath)) {
64
+ try {
65
+ const gitConfig = fs.readFileSync(gitConfigPath, 'utf-8');
66
+ const remoteMatch = gitConfig.match(/url\s*=\s*(.+)/);
67
+ if (remoteMatch) {
68
+ signals.gitRemote = remoteMatch[1].trim();
69
+ }
70
+ }
71
+ catch (e) {
72
+ // Ignore errors
73
+ }
74
+ }
75
+ return signals;
76
+ }
77
+ /**
78
+ * Detect required plugins based on tech stack signals
79
+ */
80
+ export function detectPlugins(signals) {
81
+ const detected = [];
82
+ // Helper to add detection
83
+ const addPlugin = (name, reason, confidence, signals) => {
84
+ detected.push({ name, reason, confidence, signals });
85
+ };
86
+ // Frontend detection
87
+ const frontendDeps = ['react', 'next', 'vue', 'angular', 'svelte', '@angular/core', 'vue-router', 'react-router-dom'];
88
+ const hasFrontend = signals.dependencies.some(dep => frontendDeps.some(fd => dep.includes(fd)));
89
+ if (hasFrontend) {
90
+ const matchedDeps = signals.dependencies.filter(dep => frontendDeps.some(fd => dep.includes(fd)));
91
+ addPlugin('specweave-frontend', 'Frontend framework detected', 'high', matchedDeps);
92
+ }
93
+ // Backend detection - Node.js
94
+ const backendNodeDeps = ['express', 'fastify', 'nestjs', 'koa', '@nestjs/core', 'hapi'];
95
+ const hasNodeBackend = signals.dependencies.some(dep => backendNodeDeps.some(bd => dep.includes(bd)));
96
+ if (hasNodeBackend) {
97
+ const matchedDeps = signals.dependencies.filter(dep => backendNodeDeps.some(bd => dep.includes(bd)));
98
+ addPlugin('specweave-backend', 'Node.js backend framework detected', 'high', matchedDeps);
99
+ }
100
+ // Backend detection - .NET
101
+ if (signals.hasCsproj) {
102
+ addPlugin('specweave-backend', '.NET project detected', 'high', ['*.csproj files']);
103
+ }
104
+ // Backend detection - Python
105
+ if (signals.hasPyProject || signals.hasRequirementsTxt) {
106
+ addPlugin('specweave-backend', 'Python project detected', 'medium', signals.hasPyProject ? ['pyproject.toml'] : ['requirements.txt']);
107
+ }
108
+ // Kubernetes detection
109
+ const k8sFolders = ['k8s', 'kubernetes', '.kube', 'helm'];
110
+ const hasK8s = signals.folders.some(f => k8sFolders.includes(f.toLowerCase()));
111
+ if (hasK8s) {
112
+ const matchedFolders = signals.folders.filter(f => k8sFolders.includes(f.toLowerCase()));
113
+ addPlugin('specweave-kubernetes', 'Kubernetes configuration detected', 'high', matchedFolders);
114
+ }
115
+ // Infrastructure detection
116
+ const infraFiles = ['docker-compose.yml', 'docker-compose.yaml', 'Dockerfile'];
117
+ const hasInfra = signals.files.some(f => infraFiles.includes(f));
118
+ const infraFolders = ['terraform', 'infrastructure'];
119
+ const hasInfraFolders = signals.folders.some(f => infraFolders.includes(f.toLowerCase()));
120
+ if (hasInfra || hasInfraFolders) {
121
+ const matchedSignals = [
122
+ ...signals.files.filter(f => infraFiles.includes(f)),
123
+ ...signals.folders.filter(f => infraFolders.includes(f.toLowerCase()))
124
+ ];
125
+ addPlugin('specweave-infrastructure', 'Infrastructure as Code detected', 'high', matchedSignals);
126
+ }
127
+ // GitHub detection
128
+ if (signals.gitRemote && signals.gitRemote.includes('github.com')) {
129
+ addPlugin('specweave-github', 'GitHub repository detected', 'high', [signals.gitRemote]);
130
+ }
131
+ // Payment processing detection
132
+ const paymentDeps = ['stripe', '@stripe/stripe-js', 'paypal', 'braintree'];
133
+ const hasPayments = signals.dependencies.some(dep => paymentDeps.some(pd => dep.includes(pd)));
134
+ if (hasPayments) {
135
+ const matchedDeps = signals.dependencies.filter(dep => paymentDeps.some(pd => dep.includes(pd)));
136
+ addPlugin('specweave-payments', 'Payment processing library detected', 'high', matchedDeps);
137
+ }
138
+ // Machine Learning detection
139
+ const mlDeps = ['tensorflow', '@tensorflow/tfjs', 'torch', 'pytorch', 'sklearn', 'keras'];
140
+ const hasML = signals.dependencies.some(dep => mlDeps.some(md => dep.includes(md)));
141
+ if (hasML) {
142
+ const matchedDeps = signals.dependencies.filter(dep => mlDeps.some(md => dep.includes(md)));
143
+ addPlugin('specweave-ml', 'Machine learning library detected', 'high', matchedDeps);
144
+ }
145
+ // Testing detection
146
+ const testingDeps = ['playwright', '@playwright/test', 'cypress', 'selenium-webdriver', '@testing-library/react'];
147
+ const hasTesting = signals.devDependencies.some(dep => testingDeps.some(td => dep.includes(td)));
148
+ if (hasTesting) {
149
+ const matchedDeps = signals.devDependencies.filter(dep => testingDeps.some(td => dep.includes(td)));
150
+ addPlugin('specweave-testing', 'E2E testing framework detected', 'medium', matchedDeps);
151
+ }
152
+ // Documentation detection
153
+ const docsDeps = ['docusaurus', '@docusaurus/core', 'vuepress', 'docsify'];
154
+ const hasDocs = signals.dependencies.some(dep => docsDeps.some(dd => dep.includes(dd)));
155
+ const docsFolders = ['docs', 'documentation', 'doc'];
156
+ const hasDocsFolders = signals.folders.some(f => docsFolders.includes(f.toLowerCase()));
157
+ if (hasDocs || hasDocsFolders) {
158
+ const matchedSignals = [
159
+ ...signals.dependencies.filter(dep => docsDeps.some(dd => dep.includes(dd))),
160
+ ...signals.folders.filter(f => docsFolders.includes(f.toLowerCase()))
161
+ ];
162
+ addPlugin('specweave-docs', 'Documentation site detected', hasDocs ? 'high' : 'medium', matchedSignals);
163
+ }
164
+ // Figma detection
165
+ const figmaDeps = ['figma-api', '@figma/rest-api', 'figma-js'];
166
+ const hasFigma = signals.dependencies.some(dep => figmaDeps.some(fd => dep.includes(fd)));
167
+ const figmaFiles = ['.figmarc', 'figma.config.js'];
168
+ const hasFigmaFiles = signals.files.some(f => figmaFiles.includes(f));
169
+ if (hasFigma || hasFigmaFiles) {
170
+ const matchedSignals = [
171
+ ...signals.dependencies.filter(dep => figmaDeps.some(fd => dep.includes(fd))),
172
+ ...signals.files.filter(f => figmaFiles.includes(f))
173
+ ];
174
+ addPlugin('specweave-figma', 'Figma integration detected', 'high', matchedSignals);
175
+ }
176
+ // Diagrams detection (low confidence - common folder names)
177
+ const diagramsFolders = ['diagrams', 'architecture'];
178
+ const hasDiagrams = signals.folders.some(f => diagramsFolders.includes(f.toLowerCase()));
179
+ if (hasDiagrams) {
180
+ const matchedFolders = signals.folders.filter(f => diagramsFolders.includes(f.toLowerCase()));
181
+ addPlugin('specweave-diagrams', 'Architecture diagrams folder detected', 'low', matchedFolders);
182
+ }
183
+ return detected;
184
+ }
185
+ /**
186
+ * Format detected plugins for CLI output
187
+ */
188
+ export function formatDetectedPlugins(plugins) {
189
+ if (plugins.length === 0) {
190
+ return ' No additional plugins recommended for this project.';
191
+ }
192
+ // Group by confidence
193
+ const high = plugins.filter(p => p.confidence === 'high');
194
+ const medium = plugins.filter(p => p.confidence === 'medium');
195
+ const low = plugins.filter(p => p.confidence === 'low');
196
+ let output = '';
197
+ if (high.length > 0) {
198
+ output += ' Recommended (high confidence):\n';
199
+ high.forEach(p => {
200
+ output += ` • ${p.name} - ${p.reason}\n`;
201
+ output += ` Signals: ${p.signals.join(', ')}\n`;
202
+ });
203
+ }
204
+ if (medium.length > 0) {
205
+ output += '\n Suggested (medium confidence):\n';
206
+ medium.forEach(p => {
207
+ output += ` • ${p.name} - ${p.reason}\n`;
208
+ output += ` Signals: ${p.signals.join(', ')}\n`;
209
+ });
210
+ }
211
+ if (low.length > 0) {
212
+ output += '\n Optional (low confidence):\n';
213
+ low.forEach(p => {
214
+ output += ` • ${p.name} - ${p.reason}\n`;
215
+ });
216
+ }
217
+ return output;
218
+ }
219
+ /**
220
+ * Generate install commands for detected plugins
221
+ */
222
+ export function generateInstallCommands(plugins) {
223
+ // Only include high and medium confidence
224
+ const toInstall = plugins.filter(p => p.confidence === 'high' || p.confidence === 'medium');
225
+ // Deduplicate by name
226
+ const uniquePlugins = Array.from(new Set(toInstall.map(p => p.name)));
227
+ return uniquePlugins.map(name => `/plugin install ${name}@specweave`);
228
+ }
229
+ //# sourceMappingURL=plugin-detection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-detection.js","sourceRoot":"","sources":["../../src/utils/plugin-detection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Secrets Loader Utility
3
+ *
4
+ * Loads secrets from .specweave/secrets.env file
5
+ * Provides clear validation and helpful error messages
6
+ *
7
+ * DESIGN PHILOSOPHY:
8
+ * - Secrets are OPTIONAL (framework works without them)
9
+ * - Clear error messages tell users WHERE to put secrets
10
+ * - Template file provides step-by-step instructions
11
+ * - Security by default (gitignored)
12
+ *
13
+ * @see .specweave/secrets.env.template
14
+ */
15
+ /**
16
+ * Supported secret keys
17
+ */
18
+ export type SecretKey = 'ANTHROPIC_API_KEY' | 'OPENAI_API_KEY' | 'GITHUB_TOKEN' | 'JIRA_API_TOKEN' | 'JIRA_DOMAIN' | 'JIRA_EMAIL' | 'AZURE_DEVOPS_PAT' | 'AZURE_DEVOPS_ORG';
19
+ /**
20
+ * Secret configuration
21
+ */
22
+ export interface SecretConfig {
23
+ key: SecretKey;
24
+ description: string;
25
+ required: boolean;
26
+ validation?: (value: string) => boolean;
27
+ setupInstructions: string;
28
+ }
29
+ /**
30
+ * Load secrets from .specweave/secrets.env file
31
+ *
32
+ * @param projectRoot - Project root directory (auto-detected if not provided)
33
+ * @returns Map of loaded secrets
34
+ */
35
+ export declare function loadSecrets(projectRoot?: string): Map<SecretKey, string>;
36
+ /**
37
+ * Get a specific secret
38
+ *
39
+ * Priority order:
40
+ * 1. Environment variable (process.env)
41
+ * 2. .specweave/secrets.env file
42
+ * 3. null (not found)
43
+ *
44
+ * @param key - Secret key
45
+ * @param projectRoot - Project root (auto-detected if not provided)
46
+ * @returns Secret value or null
47
+ */
48
+ export declare function getSecret(key: SecretKey, projectRoot?: string): string | null;
49
+ /**
50
+ * Validate a secret value
51
+ *
52
+ * @param key - Secret key
53
+ * @param value - Secret value
54
+ * @returns true if valid, false otherwise
55
+ */
56
+ export declare function validateSecret(key: SecretKey, value: string): boolean;
57
+ /**
58
+ * Get setup instructions for a secret
59
+ *
60
+ * @param key - Secret key
61
+ * @returns Setup instructions
62
+ */
63
+ export declare function getSetupInstructions(key: SecretKey): string;
64
+ /**
65
+ * Display helpful error message when a secret is missing
66
+ *
67
+ * @param key - Secret key
68
+ * @param context - Context message (what failed)
69
+ */
70
+ export declare function displaySecretMissingError(key: SecretKey, context?: string): void;
71
+ /**
72
+ * Check if template file exists, create if missing
73
+ *
74
+ * @param projectRoot - Project root
75
+ */
76
+ export declare function ensureSecretsTemplate(projectRoot?: string): void;
77
+ /**
78
+ * Validate all secrets in secrets.env file
79
+ *
80
+ * @param projectRoot - Project root
81
+ * @returns Validation results
82
+ */
83
+ export declare function validateAllSecrets(projectRoot?: string): {
84
+ valid: string[];
85
+ invalid: string[];
86
+ missing: string[];
87
+ };
88
+ //# sourceMappingURL=secrets-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets-loader.d.ts","sourceRoot":"","sources":["../../src/utils/secrets-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH;;GAEG;AACH,MAAM,MAAM,SAAS,GACjB,mBAAmB,GACnB,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,aAAa,GACb,YAAY,GACZ,kBAAkB,GAClB,kBAAkB,CAAC;AAEvB;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,SAAS,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAyGD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CA2CxE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS7E;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAMrE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAmBhF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAchE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG;IACxD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAwBA"}