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.
- package/.claude-plugin/README.md +1 -1
- package/CLAUDE.md +903 -99
- package/README.md +143 -207
- package/bin/specweave.js +67 -0
- package/dist/cli/commands/abandon.d.ts +13 -0
- package/dist/cli/commands/abandon.d.ts.map +1 -0
- package/dist/cli/commands/abandon.js +15 -0
- package/dist/cli/commands/abandon.js.map +1 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +90 -18
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/pause.d.ts +13 -0
- package/dist/cli/commands/pause.d.ts.map +1 -0
- package/dist/cli/commands/pause.js +15 -0
- package/dist/cli/commands/pause.js.map +1 -0
- package/dist/cli/commands/qa.d.ts +54 -0
- package/dist/cli/commands/qa.d.ts.map +1 -0
- package/dist/cli/commands/qa.js +98 -0
- package/dist/cli/commands/qa.js.map +1 -0
- package/dist/cli/commands/resume.d.ts +12 -0
- package/dist/cli/commands/resume.d.ts.map +1 -0
- package/dist/cli/commands/resume.js +14 -0
- package/dist/cli/commands/resume.js.map +1 -0
- package/dist/cli/commands/status.d.ts +12 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +23 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/ado.d.ts +57 -0
- package/dist/cli/helpers/issue-tracker/ado.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/ado.js +223 -0
- package/dist/cli/helpers/issue-tracker/ado.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/github.d.ts +65 -0
- package/dist/cli/helpers/issue-tracker/github.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/github.js +284 -0
- package/dist/cli/helpers/issue-tracker/github.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/index.d.ts +22 -0
- package/dist/cli/helpers/issue-tracker/index.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/index.js +270 -0
- package/dist/cli/helpers/issue-tracker/index.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/jira.d.ts +61 -0
- package/dist/cli/helpers/issue-tracker/jira.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/jira.js +265 -0
- package/dist/cli/helpers/issue-tracker/jira.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/types.d.ts +86 -0
- package/dist/cli/helpers/issue-tracker/types.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/types.js +16 -0
- package/dist/cli/helpers/issue-tracker/types.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/utils.d.ts +103 -0
- package/dist/cli/helpers/issue-tracker/utils.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/utils.js +240 -0
- package/dist/cli/helpers/issue-tracker/utils.js.map +1 -0
- package/dist/core/increment/limits.d.ts +68 -0
- package/dist/core/increment/limits.d.ts.map +1 -0
- package/dist/core/increment/limits.js +224 -0
- package/dist/core/increment/limits.js.map +1 -0
- package/dist/core/increment/metadata-manager.d.ts +114 -0
- package/dist/core/increment/metadata-manager.d.ts.map +1 -0
- package/dist/core/increment/metadata-manager.js +320 -0
- package/dist/core/increment/metadata-manager.js.map +1 -0
- package/dist/core/increment/status-commands.d.ts +43 -0
- package/dist/core/increment/status-commands.d.ts.map +1 -0
- package/dist/core/increment/status-commands.js +277 -0
- package/dist/core/increment/status-commands.js.map +1 -0
- package/dist/core/plugin-detector.d.ts +1 -0
- package/dist/core/plugin-detector.d.ts.map +1 -1
- package/dist/core/plugin-detector.js +25 -0
- package/dist/core/plugin-detector.js.map +1 -1
- package/dist/core/qa/qa-runner.d.ts +16 -0
- package/dist/core/qa/qa-runner.d.ts.map +1 -0
- package/dist/core/qa/qa-runner.js +404 -0
- package/dist/core/qa/qa-runner.js.map +1 -0
- package/dist/core/qa/quality-gate-decider.d.ts +53 -0
- package/dist/core/qa/quality-gate-decider.d.ts.map +1 -0
- package/dist/core/qa/quality-gate-decider.js +268 -0
- package/dist/core/qa/quality-gate-decider.js.map +1 -0
- package/dist/core/qa/risk-calculator.d.ts +126 -0
- package/dist/core/qa/risk-calculator.d.ts.map +1 -0
- package/dist/core/qa/risk-calculator.js +247 -0
- package/dist/core/qa/risk-calculator.js.map +1 -0
- package/dist/core/qa/types.d.ts +315 -0
- package/dist/core/qa/types.d.ts.map +1 -0
- package/dist/core/qa/types.js +8 -0
- package/dist/core/qa/types.js.map +1 -0
- package/dist/core/types/config.d.ts +35 -0
- package/dist/core/types/config.d.ts.map +1 -1
- package/dist/core/types/config.js +16 -0
- package/dist/core/types/config.js.map +1 -1
- package/dist/core/types/increment-metadata.d.ts +120 -0
- package/dist/core/types/increment-metadata.d.ts.map +1 -0
- package/dist/core/types/increment-metadata.js +138 -0
- package/dist/core/types/increment-metadata.js.map +1 -0
- package/dist/hooks/lib/invoke-translator-skill.d.ts +60 -0
- package/dist/hooks/lib/invoke-translator-skill.d.ts.map +1 -0
- package/dist/hooks/lib/invoke-translator-skill.js +201 -0
- package/dist/hooks/lib/invoke-translator-skill.js.map +1 -0
- package/dist/hooks/lib/translate-file.d.ts +59 -0
- package/dist/hooks/lib/translate-file.d.ts.map +1 -0
- package/dist/hooks/lib/translate-file.js +350 -0
- package/dist/hooks/lib/translate-file.js.map +1 -0
- package/dist/locales/en/cli.json +3 -1
- package/dist/metrics/calculators/change-failure-rate.d.ts +22 -0
- package/dist/metrics/calculators/change-failure-rate.d.ts.map +1 -0
- package/dist/metrics/calculators/change-failure-rate.js +70 -0
- package/dist/metrics/calculators/change-failure-rate.js.map +1 -0
- package/dist/metrics/calculators/deployment-frequency.d.ts +20 -0
- package/dist/metrics/calculators/deployment-frequency.d.ts.map +1 -0
- package/dist/metrics/calculators/deployment-frequency.js +61 -0
- package/dist/metrics/calculators/deployment-frequency.js.map +1 -0
- package/dist/metrics/calculators/lead-time.d.ts +22 -0
- package/dist/metrics/calculators/lead-time.d.ts.map +1 -0
- package/dist/metrics/calculators/lead-time.js +82 -0
- package/dist/metrics/calculators/lead-time.js.map +1 -0
- package/dist/metrics/calculators/mttr.d.ts +21 -0
- package/dist/metrics/calculators/mttr.d.ts.map +1 -0
- package/dist/metrics/calculators/mttr.js +60 -0
- package/dist/metrics/calculators/mttr.js.map +1 -0
- package/dist/metrics/dora-calculator.d.ts +24 -0
- package/dist/metrics/dora-calculator.d.ts.map +1 -0
- package/dist/metrics/dora-calculator.js +104 -0
- package/dist/metrics/dora-calculator.js.map +1 -0
- package/dist/metrics/github-client.d.ts +51 -0
- package/dist/metrics/github-client.d.ts.map +1 -0
- package/dist/metrics/github-client.js +133 -0
- package/dist/metrics/github-client.js.map +1 -0
- package/dist/metrics/types.d.ts +112 -0
- package/dist/metrics/types.d.ts.map +1 -0
- package/dist/metrics/types.js +10 -0
- package/dist/metrics/types.js.map +1 -0
- package/dist/metrics/utils/percentile.d.ts +25 -0
- package/dist/metrics/utils/percentile.d.ts.map +1 -0
- package/dist/metrics/utils/percentile.js +46 -0
- package/dist/metrics/utils/percentile.js.map +1 -0
- package/dist/metrics/utils/tier-classifier.d.ts +61 -0
- package/dist/metrics/utils/tier-classifier.d.ts.map +1 -0
- package/dist/metrics/utils/tier-classifier.js +100 -0
- package/dist/metrics/utils/tier-classifier.js.map +1 -0
- package/dist/utils/auth-helpers.d.ts +58 -0
- package/dist/utils/auth-helpers.d.ts.map +1 -0
- package/dist/utils/auth-helpers.js +108 -0
- package/dist/utils/auth-helpers.js.map +1 -0
- package/dist/utils/env-file.d.ts +88 -0
- package/dist/utils/env-file.d.ts.map +1 -0
- package/dist/utils/env-file.js +180 -0
- package/dist/utils/env-file.js.map +1 -0
- package/dist/utils/plugin-detection.d.ts +50 -0
- package/dist/utils/plugin-detection.d.ts.map +1 -0
- package/dist/utils/plugin-detection.js +229 -0
- package/dist/utils/plugin-detection.js.map +1 -0
- package/dist/utils/secrets-loader.d.ts +88 -0
- package/dist/utils/secrets-loader.d.ts.map +1 -0
- package/dist/utils/secrets-loader.js +271 -0
- package/dist/utils/secrets-loader.js.map +1 -0
- package/dist/utils/translation.d.ts +187 -0
- package/dist/utils/translation.d.ts.map +1 -0
- package/dist/utils/translation.js +414 -0
- package/dist/utils/translation.js.map +1 -0
- package/package.json +28 -44
- package/plugins/specweave/.claude-plugin/plugin.json +3 -3
- package/plugins/specweave/agents/pm/AGENT.md +330 -54
- package/plugins/specweave/agents/test-aware-planner/AGENT.md +1035 -0
- package/plugins/specweave/agents/test-aware-planner/templates/README.md +118 -0
- package/plugins/specweave/agents/test-aware-planner/templates/task-non-testable.md.template +24 -0
- package/plugins/specweave/agents/test-aware-planner/templates/task-testable.md.template +53 -0
- package/plugins/specweave/agents/test-aware-planner/templates/tasks-frontmatter.md.template +11 -0
- package/plugins/specweave/commands/README.md +88 -163
- package/plugins/specweave/commands/specweave-abandon.md +314 -0
- package/plugins/specweave/commands/specweave-check-tests.md +546 -0
- package/plugins/specweave/commands/{do.md → specweave-do.md} +5 -7
- package/plugins/specweave/commands/{increment.md → specweave-increment.md} +231 -4
- package/plugins/specweave/commands/specweave-pause.md +189 -0
- package/plugins/specweave/commands/specweave-qa.md +245 -0
- package/plugins/specweave/commands/specweave-resume.md +216 -0
- package/plugins/specweave/commands/specweave-status.md +397 -0
- package/plugins/specweave/commands/specweave-sync-tasks.md +256 -0
- package/plugins/specweave/commands/{translate.md → specweave-translate.md} +3 -3
- package/plugins/specweave/commands/specweave-update-scope.md +351 -0
- package/plugins/specweave/commands/specweave.md +21 -21
- package/plugins/specweave/hooks/post-increment-planning.sh +335 -0
- package/plugins/specweave/hooks/post-task-completion.sh +141 -0
- package/plugins/specweave/skills/SKILLS-INDEX.md +1 -1
- package/plugins/specweave/skills/brownfield-analyzer/SKILL.md +9 -9
- package/plugins/specweave/skills/increment-planner/SKILL.md +400 -212
- package/plugins/specweave/skills/increment-quality-judge-v2/SKILL.md +499 -0
- package/plugins/specweave/skills/plugin-detector/SKILL.md +114 -1
- package/plugins/specweave/skills/project-kickstarter/SKILL.md +74 -1
- package/plugins/specweave/skills/{rfc-generator → spec-generator}/SKILL.md +22 -29
- package/plugins/specweave/skills/specweave-detector/SKILL.md +3 -3
- package/plugins/specweave/skills/specweave-framework/SKILL.md +2 -2
- package/plugins/specweave-ado/.claude-plugin/plugin.json +18 -4
- package/plugins/specweave-ado/agents/ado-manager/AGENT.md +426 -0
- package/plugins/specweave-ado/commands/close-workitem.md +52 -0
- package/plugins/specweave-ado/commands/create-workitem.md +53 -0
- package/plugins/specweave-ado/commands/status.md +53 -0
- package/plugins/specweave-ado/commands/sync.md +55 -0
- package/plugins/specweave-ado/lib/ado-client.ts +361 -0
- package/plugins/specweave-ado/reference/ado-specweave-mapping.md +552 -0
- package/plugins/specweave-ado/skills/ado-sync/SKILL.md +344 -193
- package/plugins/specweave-docs/skills/docusaurus/SKILL.md +73 -0
- package/plugins/specweave-github/agents/github-manager/AGENT.md +49 -0
- package/plugins/specweave-github/commands/{github-close-issue.md → close-issue.md} +1 -1
- package/plugins/specweave-github/commands/{github-create-issue.md → create-issue.md} +1 -1
- package/plugins/specweave-github/commands/{github-status.md → status.md} +1 -1
- package/plugins/specweave-github/commands/{github-sync-tasks.md → sync-tasks.md} +1 -1
- package/plugins/specweave-github/commands/{github-sync.md → sync.md} +1 -1
- package/plugins/specweave-github/reference/github-specweave-mapping.md +377 -0
- package/plugins/specweave-github/skills/github-sync/SKILL.md +11 -3
- package/plugins/specweave-infrastructure/commands/{specweave.monitor-setup.md → monitor-setup.md} +5 -0
- package/plugins/specweave-infrastructure/commands/{specweave.slo-implement.md → slo-implement.md} +5 -0
- package/plugins/specweave-jira/agents/jira-manager/AGENT.md +380 -0
- package/plugins/specweave-jira/commands/{specweave.sync-jira.md → sync.md} +1 -1
- package/plugins/specweave-jira/reference/jira-specweave-mapping.md +508 -0
- package/plugins/specweave-ml/commands/ml-deploy.md +1 -1
- package/plugins/specweave-ml/commands/ml-evaluate.md +1 -1
- package/plugins/specweave-ml/commands/ml-explain.md +1 -1
- package/plugins/specweave-ml/commands/{specweave.ml-pipeline.md → ml-pipeline.md} +5 -0
- package/src/templates/AGENTS.md.template +331 -31
- package/src/templates/CLAUDE.md.template +36 -21
- package/src/templates/COMPLETION-REPORT.template.md +128 -0
- package/src/templates/README.md.template +17 -16
- package/src/templates/docs/README.md +11 -9
- package/src/templates/docs/spec-template.md +229 -0
- package/plugins/specweave/commands/inc.md +0 -85
- package/plugins/specweave/commands/list-increments.md +0 -180
- package/src/adapters/README.md +0 -275
- package/src/adapters/adapter-base.ts +0 -182
- package/src/adapters/adapter-interface.ts +0 -166
- package/src/adapters/adapter-loader.ts +0 -256
- package/src/adapters/agents-md-generator.ts +0 -228
- package/src/adapters/claude/README.md +0 -233
- package/src/adapters/claude/adapter.ts +0 -468
- package/src/adapters/claude-md-generator.ts +0 -377
- package/src/adapters/codex/README.md +0 -105
- package/src/adapters/codex/adapter.ts +0 -333
- package/src/adapters/cursor/.cursor/context/docs-context.md +0 -62
- package/src/adapters/cursor/.cursor/context/increments-context.md +0 -71
- package/src/adapters/cursor/.cursor/context/strategy-context.md +0 -73
- package/src/adapters/cursor/.cursor/context/tests-context.md +0 -89
- package/src/adapters/cursor/README.md +0 -283
- package/src/adapters/cursor/adapter.ts +0 -451
- package/src/adapters/doc-generator.ts +0 -331
- package/src/adapters/gemini/README.md +0 -97
- package/src/adapters/gemini/adapter.ts +0 -298
- package/src/adapters/generic/README.md +0 -277
- package/src/adapters/generic/adapter.ts +0 -378
- package/src/adapters/registry.yaml +0 -187
- /package/plugins/specweave/commands/{costs.md → specweave-costs.md} +0 -0
- /package/plugins/specweave/commands/{done.md → specweave-done.md} +0 -0
- /package/plugins/specweave/commands/{next.md → specweave-next.md} +0 -0
- /package/plugins/specweave/commands/{progress.md → specweave-progress.md} +0 -0
- /package/plugins/specweave/commands/{sync-docs.md → specweave-sync-docs.md} +0 -0
- /package/plugins/specweave/commands/{tdd-cycle.md → specweave-tdd-cycle.md} +0 -0
- /package/plugins/specweave/commands/{tdd-green.md → specweave-tdd-green.md} +0 -0
- /package/plugins/specweave/commands/{tdd-red.md → specweave-tdd-red.md} +0 -0
- /package/plugins/specweave/commands/{tdd-refactor.md → specweave-tdd-refactor.md} +0 -0
- /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"}
|