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,271 @@
|
|
|
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
|
+
import fs from 'fs-extra';
|
|
16
|
+
import path from 'path';
|
|
17
|
+
/**
|
|
18
|
+
* Secrets registry
|
|
19
|
+
*/
|
|
20
|
+
const SECRETS_CONFIG = {
|
|
21
|
+
ANTHROPIC_API_KEY: {
|
|
22
|
+
description: 'Anthropic API key for automatic translation',
|
|
23
|
+
required: false,
|
|
24
|
+
validation: (value) => value.startsWith('sk-ant-api03-'),
|
|
25
|
+
setupInstructions: `
|
|
26
|
+
🔑 ANTHROPIC_API_KEY Setup Instructions:
|
|
27
|
+
|
|
28
|
+
WHY NEEDED:
|
|
29
|
+
Enables automatic translation during increment creation.
|
|
30
|
+
Without this key, translation requires manual intervention.
|
|
31
|
+
|
|
32
|
+
HOW TO GET IT:
|
|
33
|
+
1. Visit: https://console.anthropic.com/
|
|
34
|
+
2. Sign in or create account
|
|
35
|
+
3. Navigate to "API Keys"
|
|
36
|
+
4. Click "Create Key"
|
|
37
|
+
5. Copy your key (starts with "sk-ant-api03-...")
|
|
38
|
+
|
|
39
|
+
WHERE TO PUT IT:
|
|
40
|
+
Option A (Recommended): Create .specweave/secrets.env file
|
|
41
|
+
1. Copy template: cp .specweave/secrets.env.template .specweave/secrets.env
|
|
42
|
+
2. Edit .specweave/secrets.env
|
|
43
|
+
3. Add line: ANTHROPIC_API_KEY=sk-ant-api03-YOUR-KEY
|
|
44
|
+
|
|
45
|
+
Option B: Set environment variable
|
|
46
|
+
# macOS/Linux
|
|
47
|
+
export ANTHROPIC_API_KEY="sk-ant-api03-YOUR-KEY"
|
|
48
|
+
# Add to ~/.zshrc for permanence
|
|
49
|
+
|
|
50
|
+
# Windows PowerShell
|
|
51
|
+
[System.Environment]::SetEnvironmentVariable('ANTHROPIC_API_KEY', 'sk-ant-api03-YOUR-KEY', 'User')
|
|
52
|
+
|
|
53
|
+
COST:
|
|
54
|
+
~$0.0075 per increment (negligible)
|
|
55
|
+
~$0.15 per month (20 increments)
|
|
56
|
+
|
|
57
|
+
SECURITY:
|
|
58
|
+
✓ .specweave/secrets.env is automatically gitignored
|
|
59
|
+
✓ Keep your API key private
|
|
60
|
+
✓ Rotate periodically
|
|
61
|
+
`,
|
|
62
|
+
},
|
|
63
|
+
OPENAI_API_KEY: {
|
|
64
|
+
description: 'OpenAI API key (alternative to Anthropic)',
|
|
65
|
+
required: false,
|
|
66
|
+
validation: (value) => value.startsWith('sk-'),
|
|
67
|
+
setupInstructions: 'Visit: https://platform.openai.com/api-keys',
|
|
68
|
+
},
|
|
69
|
+
GITHUB_TOKEN: {
|
|
70
|
+
description: 'GitHub Personal Access Token',
|
|
71
|
+
required: false,
|
|
72
|
+
validation: (value) => value.length > 20,
|
|
73
|
+
setupInstructions: 'Visit: https://github.com/settings/tokens',
|
|
74
|
+
},
|
|
75
|
+
JIRA_API_TOKEN: {
|
|
76
|
+
description: 'Jira API Token',
|
|
77
|
+
required: false,
|
|
78
|
+
setupInstructions: 'Visit Jira: Account Settings → Security → API Tokens',
|
|
79
|
+
},
|
|
80
|
+
JIRA_DOMAIN: {
|
|
81
|
+
description: 'Jira Domain (e.g., company.atlassian.net)',
|
|
82
|
+
required: false,
|
|
83
|
+
setupInstructions: 'Your Jira domain from the URL',
|
|
84
|
+
},
|
|
85
|
+
JIRA_EMAIL: {
|
|
86
|
+
description: 'Jira Account Email',
|
|
87
|
+
required: false,
|
|
88
|
+
setupInstructions: 'Email associated with your Jira account',
|
|
89
|
+
},
|
|
90
|
+
AZURE_DEVOPS_PAT: {
|
|
91
|
+
description: 'Azure DevOps Personal Access Token',
|
|
92
|
+
required: false,
|
|
93
|
+
setupInstructions: 'Visit: Azure DevOps → User Settings → Personal Access Tokens',
|
|
94
|
+
},
|
|
95
|
+
AZURE_DEVOPS_ORG: {
|
|
96
|
+
description: 'Azure DevOps Organization',
|
|
97
|
+
required: false,
|
|
98
|
+
setupInstructions: 'Your Azure DevOps organization name',
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Find project root by searching for .specweave/ directory
|
|
103
|
+
*/
|
|
104
|
+
function findProjectRoot(startDir = process.cwd()) {
|
|
105
|
+
let currentDir = startDir;
|
|
106
|
+
const root = path.parse(currentDir).root;
|
|
107
|
+
while (currentDir !== root) {
|
|
108
|
+
const specweavePath = path.join(currentDir, '.specweave');
|
|
109
|
+
if (fs.existsSync(specweavePath)) {
|
|
110
|
+
return currentDir;
|
|
111
|
+
}
|
|
112
|
+
currentDir = path.dirname(currentDir);
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Load secrets from .specweave/secrets.env file
|
|
118
|
+
*
|
|
119
|
+
* @param projectRoot - Project root directory (auto-detected if not provided)
|
|
120
|
+
* @returns Map of loaded secrets
|
|
121
|
+
*/
|
|
122
|
+
export function loadSecrets(projectRoot) {
|
|
123
|
+
const secrets = new Map();
|
|
124
|
+
// Find project root
|
|
125
|
+
const root = projectRoot || findProjectRoot();
|
|
126
|
+
if (!root) {
|
|
127
|
+
return secrets; // No project root found, return empty
|
|
128
|
+
}
|
|
129
|
+
const secretsPath = path.join(root, '.specweave', 'secrets.env');
|
|
130
|
+
// Check if secrets.env exists
|
|
131
|
+
if (!fs.existsSync(secretsPath)) {
|
|
132
|
+
// No secrets file, return empty (this is OK - secrets are optional)
|
|
133
|
+
return secrets;
|
|
134
|
+
}
|
|
135
|
+
// Read and parse secrets.env
|
|
136
|
+
try {
|
|
137
|
+
const content = fs.readFileSync(secretsPath, 'utf-8');
|
|
138
|
+
const lines = content.split('\n');
|
|
139
|
+
for (const line of lines) {
|
|
140
|
+
// Skip comments and empty lines
|
|
141
|
+
if (line.trim().startsWith('#') || !line.trim()) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
// Parse KEY=VALUE
|
|
145
|
+
const match = line.match(/^([A-Z_]+)=(.*)$/);
|
|
146
|
+
if (match) {
|
|
147
|
+
const [, key, value] = match;
|
|
148
|
+
if (key in SECRETS_CONFIG && value.trim()) {
|
|
149
|
+
secrets.set(key, value.trim());
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
console.error(`⚠️ Failed to load secrets from ${secretsPath}`);
|
|
156
|
+
console.error(` Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
157
|
+
}
|
|
158
|
+
return secrets;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get a specific secret
|
|
162
|
+
*
|
|
163
|
+
* Priority order:
|
|
164
|
+
* 1. Environment variable (process.env)
|
|
165
|
+
* 2. .specweave/secrets.env file
|
|
166
|
+
* 3. null (not found)
|
|
167
|
+
*
|
|
168
|
+
* @param key - Secret key
|
|
169
|
+
* @param projectRoot - Project root (auto-detected if not provided)
|
|
170
|
+
* @returns Secret value or null
|
|
171
|
+
*/
|
|
172
|
+
export function getSecret(key, projectRoot) {
|
|
173
|
+
// Priority 1: Environment variable
|
|
174
|
+
if (process.env[key]) {
|
|
175
|
+
return process.env[key];
|
|
176
|
+
}
|
|
177
|
+
// Priority 2: secrets.env file
|
|
178
|
+
const secrets = loadSecrets(projectRoot);
|
|
179
|
+
return secrets.get(key) || null;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Validate a secret value
|
|
183
|
+
*
|
|
184
|
+
* @param key - Secret key
|
|
185
|
+
* @param value - Secret value
|
|
186
|
+
* @returns true if valid, false otherwise
|
|
187
|
+
*/
|
|
188
|
+
export function validateSecret(key, value) {
|
|
189
|
+
const config = SECRETS_CONFIG[key];
|
|
190
|
+
if (!config.validation) {
|
|
191
|
+
return true; // No validation function, assume valid
|
|
192
|
+
}
|
|
193
|
+
return config.validation(value);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Get setup instructions for a secret
|
|
197
|
+
*
|
|
198
|
+
* @param key - Secret key
|
|
199
|
+
* @returns Setup instructions
|
|
200
|
+
*/
|
|
201
|
+
export function getSetupInstructions(key) {
|
|
202
|
+
return SECRETS_CONFIG[key].setupInstructions;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Display helpful error message when a secret is missing
|
|
206
|
+
*
|
|
207
|
+
* @param key - Secret key
|
|
208
|
+
* @param context - Context message (what failed)
|
|
209
|
+
*/
|
|
210
|
+
export function displaySecretMissingError(key, context) {
|
|
211
|
+
const config = SECRETS_CONFIG[key];
|
|
212
|
+
console.error('\n' + '='.repeat(80));
|
|
213
|
+
console.error(`❌ Missing Secret: ${key}`);
|
|
214
|
+
console.error('='.repeat(80));
|
|
215
|
+
if (context) {
|
|
216
|
+
console.error(`\n📋 Context: ${context}\n`);
|
|
217
|
+
}
|
|
218
|
+
console.error(`📝 Description: ${config.description}\n`);
|
|
219
|
+
console.error(`⚙️ Required: ${config.required ? 'Yes' : 'No (optional)'}\n`);
|
|
220
|
+
console.error(config.setupInstructions);
|
|
221
|
+
console.error('\n' + '='.repeat(80));
|
|
222
|
+
console.error('💡 After setting up, retry the operation');
|
|
223
|
+
console.error('='.repeat(80) + '\n');
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Check if template file exists, create if missing
|
|
227
|
+
*
|
|
228
|
+
* @param projectRoot - Project root
|
|
229
|
+
*/
|
|
230
|
+
export function ensureSecretsTemplate(projectRoot) {
|
|
231
|
+
const root = projectRoot || findProjectRoot();
|
|
232
|
+
if (!root) {
|
|
233
|
+
return; // No project root, skip
|
|
234
|
+
}
|
|
235
|
+
const templatePath = path.join(root, '.specweave', 'secrets.env.template');
|
|
236
|
+
if (fs.existsSync(templatePath)) {
|
|
237
|
+
return; // Template exists, nothing to do
|
|
238
|
+
}
|
|
239
|
+
// Template should be created during `specweave init`
|
|
240
|
+
// If missing, user might be in an old project
|
|
241
|
+
console.warn('⚠️ Secrets template missing. Run: specweave init --refresh');
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Validate all secrets in secrets.env file
|
|
245
|
+
*
|
|
246
|
+
* @param projectRoot - Project root
|
|
247
|
+
* @returns Validation results
|
|
248
|
+
*/
|
|
249
|
+
export function validateAllSecrets(projectRoot) {
|
|
250
|
+
const secrets = loadSecrets(projectRoot);
|
|
251
|
+
const valid = [];
|
|
252
|
+
const invalid = [];
|
|
253
|
+
const missing = [];
|
|
254
|
+
for (const [key, config] of Object.entries(SECRETS_CONFIG)) {
|
|
255
|
+
const value = getSecret(key, projectRoot);
|
|
256
|
+
if (!value) {
|
|
257
|
+
if (config.required) {
|
|
258
|
+
missing.push(key);
|
|
259
|
+
}
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
if (validateSecret(key, value)) {
|
|
263
|
+
valid.push(key);
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
invalid.push(key);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return { valid, invalid, missing };
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=secrets-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets-loader.js","sourceRoot":"","sources":["../../src/utils/secrets-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translation Utilities
|
|
3
|
+
*
|
|
4
|
+
* LLM-native translation system for SpecWeave multilingual support.
|
|
5
|
+
* Provides zero-cost language detection and cost-efficient translation
|
|
6
|
+
* using Claude Haiku via current LLM session.
|
|
7
|
+
*
|
|
8
|
+
* Strategy:
|
|
9
|
+
* - Language Detection: Simple heuristic (no API calls, <1ms)
|
|
10
|
+
* - Translation: Claude Haiku via current session (~$0.0025 per file)
|
|
11
|
+
* - Preservation: Markdown, code blocks, technical terms stay intact
|
|
12
|
+
*
|
|
13
|
+
* @see .specweave/increments/0006-llm-native-i18n/reports/DESIGN-POST-GENERATION-TRANSLATION.md
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Supported languages for translation
|
|
17
|
+
*/
|
|
18
|
+
export type SupportedLanguage = 'en' | 'ru' | 'es' | 'zh' | 'de' | 'fr' | 'ja' | 'ko' | 'pt' | 'ar' | 'he' | 'unknown';
|
|
19
|
+
/**
|
|
20
|
+
* Language detection result
|
|
21
|
+
*/
|
|
22
|
+
export interface LanguageDetectionResult {
|
|
23
|
+
language: SupportedLanguage;
|
|
24
|
+
confidence: number;
|
|
25
|
+
nonAsciiRatio: number;
|
|
26
|
+
detectionMethod: 'heuristic' | 'explicit';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Preserved content structure for code blocks
|
|
30
|
+
*/
|
|
31
|
+
export interface PreservedContent {
|
|
32
|
+
preserved: string;
|
|
33
|
+
blocks: string[];
|
|
34
|
+
inlineCode: string[];
|
|
35
|
+
links: string[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Translation result with metadata
|
|
39
|
+
*/
|
|
40
|
+
export interface TranslationResult {
|
|
41
|
+
translated: string;
|
|
42
|
+
sourceLanguage: SupportedLanguage;
|
|
43
|
+
targetLanguage: SupportedLanguage;
|
|
44
|
+
estimatedTokens: number;
|
|
45
|
+
estimatedCost: number;
|
|
46
|
+
preservedBlocks: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Detects the language of the given content using simple heuristics
|
|
50
|
+
*
|
|
51
|
+
* @param content - The text content to analyze
|
|
52
|
+
* @returns Language detection result with confidence score
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const result = detectLanguage('Это тестовый документ');
|
|
57
|
+
* console.log(result.language); // 'ru'
|
|
58
|
+
* console.log(result.confidence); // 0.95
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function detectLanguage(content: string): LanguageDetectionResult;
|
|
62
|
+
/**
|
|
63
|
+
* Detects specific language from content
|
|
64
|
+
*
|
|
65
|
+
* @param content - The text content to analyze
|
|
66
|
+
* @returns Detected language code or 'unknown'
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* detectSpecificLanguage('Это текст'); // 'ru'
|
|
71
|
+
* detectSpecificLanguage('这是文本'); // 'zh'
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export declare function detectSpecificLanguage(content: string): SupportedLanguage;
|
|
75
|
+
/**
|
|
76
|
+
* Preserves code blocks, inline code, and links before translation
|
|
77
|
+
*
|
|
78
|
+
* @param content - Markdown content to preserve
|
|
79
|
+
* @returns Preserved content with placeholders
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const content = 'Text\n```js\ncode\n```\nMore text';
|
|
84
|
+
* const preserved = preserveCodeBlocks(content);
|
|
85
|
+
* // preserved.blocks = ['```js\ncode\n```']
|
|
86
|
+
* // preserved.preserved = 'Text\n__CODE_BLOCK_0__\nMore text'
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare function preserveCodeBlocks(content: string): PreservedContent;
|
|
90
|
+
/**
|
|
91
|
+
* Restores preserved code blocks, inline code, and links after translation
|
|
92
|
+
*
|
|
93
|
+
* @param translated - Translated text with placeholders
|
|
94
|
+
* @param preserved - Preserved content structure
|
|
95
|
+
* @returns Restored text with original code blocks and links
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const translated = 'Текст\n__CODE_BLOCK_0__\nБольше текста';
|
|
100
|
+
* const preserved = { blocks: ['```js\ncode\n```'], inlineCode: [], links: [] };
|
|
101
|
+
* const restored = restoreCodeBlocks(translated, preserved);
|
|
102
|
+
* // Result: 'Текст\n```js\ncode\n```\nБольше текста'
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export declare function restoreCodeBlocks(translated: string, preserved: Pick<PreservedContent, 'blocks' | 'inlineCode' | 'links'>): string;
|
|
106
|
+
/**
|
|
107
|
+
* Estimates the number of tokens in a text
|
|
108
|
+
* Rule of thumb: ~4 characters per token for English, ~2-3 for other languages
|
|
109
|
+
*
|
|
110
|
+
* @param text - Text to estimate
|
|
111
|
+
* @param language - Language code for estimation
|
|
112
|
+
* @returns Estimated token count
|
|
113
|
+
*/
|
|
114
|
+
export declare function estimateTokens(text: string, language?: SupportedLanguage): number;
|
|
115
|
+
/**
|
|
116
|
+
* Estimates translation cost using Claude Haiku pricing
|
|
117
|
+
* Haiku pricing (as of 2025): $0.25 per 1M input tokens, $1.25 per 1M output tokens
|
|
118
|
+
*
|
|
119
|
+
* @param inputTokens - Input token count
|
|
120
|
+
* @param outputTokens - Output token count (defaults to input for balanced estimate)
|
|
121
|
+
* @returns Estimated cost in USD
|
|
122
|
+
*/
|
|
123
|
+
export declare function estimateTranslationCost(inputTokens: number, outputTokens?: number): number;
|
|
124
|
+
/**
|
|
125
|
+
* Generates translation prompt for LLM
|
|
126
|
+
*
|
|
127
|
+
* @param content - Content to translate
|
|
128
|
+
* @param sourceLanguage - Source language code
|
|
129
|
+
* @param targetLanguage - Target language code (default: 'en')
|
|
130
|
+
* @returns Translation prompt for LLM
|
|
131
|
+
*/
|
|
132
|
+
export declare function generateTranslationPrompt(content: string, sourceLanguage: SupportedLanguage, targetLanguage?: SupportedLanguage): string;
|
|
133
|
+
/**
|
|
134
|
+
* Translates content to English using LLM (Claude Haiku)
|
|
135
|
+
* This function generates the prompt but delegates actual LLM invocation
|
|
136
|
+
* to the caller (via Task tool, skill, or direct API)
|
|
137
|
+
*
|
|
138
|
+
* @param content - Content to translate
|
|
139
|
+
* @param sourceLanguage - Source language code
|
|
140
|
+
* @returns Translation prompt and metadata (caller must invoke LLM)
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* const content = 'Это тестовый документ';
|
|
145
|
+
* const result = prepareTranslation(content, 'ru');
|
|
146
|
+
* // Caller then invokes LLM with result.prompt
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
export declare function prepareTranslation(content: string, sourceLanguage: SupportedLanguage, targetLanguage?: SupportedLanguage): {
|
|
150
|
+
prompt: string;
|
|
151
|
+
preserved: PreservedContent;
|
|
152
|
+
estimatedTokens: number;
|
|
153
|
+
estimatedCost: number;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Post-processes translated content
|
|
157
|
+
* Restores code blocks, validates markdown, cleans up extra whitespace
|
|
158
|
+
*
|
|
159
|
+
* @param translated - Translated text from LLM
|
|
160
|
+
* @param preserved - Preserved content structure
|
|
161
|
+
* @returns Cleaned and restored translated content
|
|
162
|
+
*/
|
|
163
|
+
export declare function postProcessTranslation(translated: string, preserved: PreservedContent): string;
|
|
164
|
+
/**
|
|
165
|
+
* Validates that translated content preserves markdown structure
|
|
166
|
+
* Returns warnings if structure doesn't match
|
|
167
|
+
*
|
|
168
|
+
* @param original - Original content
|
|
169
|
+
* @param translated - Translated content
|
|
170
|
+
* @returns Array of validation warnings (empty if valid)
|
|
171
|
+
*/
|
|
172
|
+
export declare function validateTranslation(original: string, translated: string): string[];
|
|
173
|
+
/**
|
|
174
|
+
* Gets human-readable language name
|
|
175
|
+
*
|
|
176
|
+
* @param code - Language code
|
|
177
|
+
* @returns Human-readable name
|
|
178
|
+
*/
|
|
179
|
+
export declare function getLanguageName(code: SupportedLanguage): string;
|
|
180
|
+
/**
|
|
181
|
+
* Formats cost for display
|
|
182
|
+
*
|
|
183
|
+
* @param cost - Cost in USD
|
|
184
|
+
* @returns Formatted string (e.g., "$0.0025" or "<$0.001")
|
|
185
|
+
*/
|
|
186
|
+
export declare function formatCost(cost: number): string;
|
|
187
|
+
//# sourceMappingURL=translation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translation.d.ts","sourceRoot":"","sources":["../../src/utils/translation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,SAAS,CAAC;AAEd;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,WAAW,GAAG,UAAU,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,iBAAiB,CAAC;IAClC,cAAc,EAAE,iBAAiB,CAAC;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AA4CD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,uBAAuB,CAmCvE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAgCzE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CA6BpE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC,GACnE,MAAM,CAqBR;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,iBAAwB,GAAG,MAAM,CAGvF;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAUR;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,iBAAiB,EACjC,cAAc,GAAE,iBAAwB,GACvC,MAAM,CAiDR;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,iBAAiB,EACjC,cAAc,GAAE,iBAAwB,GACvC;IACD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,gBAAgB,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB,CAkBA;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,gBAAgB,GAC1B,MAAM,CAaR;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,MAAM,EAAE,CA0CV;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAiB/D;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK/C"}
|