musubi-sdd 6.2.2 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +3 -3
- package/README.md +3 -3
- package/bin/musubi-dashboard.js +22 -13
- package/bin/musubi-design.js +3 -3
- package/bin/musubi-gaps.js +9 -9
- package/bin/musubi-init.js +14 -1310
- package/bin/musubi-requirements.js +1 -1
- package/bin/musubi-tasks.js +5 -5
- package/bin/musubi-trace.js +23 -23
- package/bin/musubi-upgrade.js +7 -2
- package/bin/musubi.js +1 -1
- package/package.json +2 -2
- package/src/analyzers/gap-detector.js +3 -3
- package/src/analyzers/traceability.js +17 -17
- package/src/cli/dashboard-cli.js +54 -60
- package/src/cli/init-generators.js +464 -0
- package/src/cli/init-helpers.js +884 -0
- package/src/constitutional/checker.js +67 -65
- package/src/constitutional/ci-reporter.js +50 -43
- package/src/constitutional/index.js +2 -2
- package/src/constitutional/phase-minus-one.js +22 -25
- package/src/constitutional/steering-sync.js +28 -39
- package/src/dashboard/index.js +2 -2
- package/src/dashboard/sprint-planner.js +17 -19
- package/src/dashboard/sprint-reporter.js +46 -37
- package/src/dashboard/transition-recorder.js +12 -18
- package/src/dashboard/workflow-dashboard.js +27 -38
- package/src/enterprise/error-recovery.js +109 -49
- package/src/enterprise/experiment-report.js +62 -36
- package/src/enterprise/index.js +5 -5
- package/src/enterprise/rollback-manager.js +28 -29
- package/src/enterprise/tech-article.js +41 -35
- package/src/generators/design.js +3 -3
- package/src/generators/requirements.js +5 -3
- package/src/generators/tasks.js +2 -2
- package/src/integrations/platforms.js +1 -1
- package/src/templates/agents/claude-code/CLAUDE.md +1 -1
- package/src/templates/agents/claude-code/skills/design-reviewer/SKILL.md +132 -113
- package/src/templates/agents/claude-code/skills/requirements-reviewer/SKILL.md +85 -56
- package/src/templates/agents/codex/AGENTS.md +2 -2
- package/src/templates/agents/cursor/AGENTS.md +2 -2
- package/src/templates/agents/gemini-cli/GEMINI.md +2 -2
- package/src/templates/agents/github-copilot/AGENTS.md +2 -2
- package/src/templates/agents/github-copilot/commands/sdd-requirements.prompt.md +23 -4
- package/src/templates/agents/qwen-code/QWEN.md +2 -2
- package/src/templates/agents/shared/AGENTS.md +1 -1
- package/src/templates/agents/windsurf/AGENTS.md +2 -2
- package/src/templates/skills/browser-agent.md +1 -1
- package/src/traceability/extractor.js +21 -20
- package/src/traceability/gap-detector.js +19 -17
- package/src/traceability/index.js +2 -2
- package/src/traceability/matrix-storage.js +20 -22
- package/src/validators/constitution.js +5 -2
- package/src/validators/critic-system.js +6 -6
- package/src/validators/traceability-validator.js +3 -3
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MUSUBI Initialization Generators
|
|
3
|
+
*
|
|
4
|
+
* Generator functions for musubi-init.js
|
|
5
|
+
* Extracted to reduce file size and improve maintainability
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs-extra');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Generate language-specific dependency files for single-package projects
|
|
12
|
+
*/
|
|
13
|
+
async function generateDependencyFiles(primaryLang, answers) {
|
|
14
|
+
const projectName = answers.projectName || 'my-project';
|
|
15
|
+
const safeName = projectName.toLowerCase().replace(/[^a-z0-9-]/g, '-');
|
|
16
|
+
|
|
17
|
+
if (primaryLang === 'javascript') {
|
|
18
|
+
// Check if package.json already exists
|
|
19
|
+
if (!(await fs.pathExists('package.json'))) {
|
|
20
|
+
const packageJson = {
|
|
21
|
+
name: safeName,
|
|
22
|
+
version: '0.1.0',
|
|
23
|
+
description: answers.description || '',
|
|
24
|
+
type: 'module',
|
|
25
|
+
main: 'dist/index.js',
|
|
26
|
+
types: 'dist/index.d.ts',
|
|
27
|
+
scripts: {
|
|
28
|
+
build: 'tsc',
|
|
29
|
+
test: 'jest',
|
|
30
|
+
lint: 'eslint src/',
|
|
31
|
+
format: 'prettier --write .',
|
|
32
|
+
},
|
|
33
|
+
devDependencies: {
|
|
34
|
+
typescript: '^5.0.0',
|
|
35
|
+
'@types/node': '^20.0.0',
|
|
36
|
+
jest: '^29.0.0',
|
|
37
|
+
'@types/jest': '^29.0.0',
|
|
38
|
+
eslint: '^9.0.0',
|
|
39
|
+
prettier: '^3.0.0',
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
await fs.writeFile('package.json', JSON.stringify(packageJson, null, 2) + '\n');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Generate tsconfig.json
|
|
46
|
+
if (!(await fs.pathExists('tsconfig.json'))) {
|
|
47
|
+
const tsconfig = {
|
|
48
|
+
compilerOptions: {
|
|
49
|
+
target: 'ES2022',
|
|
50
|
+
module: 'NodeNext',
|
|
51
|
+
moduleResolution: 'NodeNext',
|
|
52
|
+
declaration: true,
|
|
53
|
+
outDir: './dist',
|
|
54
|
+
rootDir: './src',
|
|
55
|
+
strict: true,
|
|
56
|
+
esModuleInterop: true,
|
|
57
|
+
skipLibCheck: true,
|
|
58
|
+
forceConsistentCasingInFileNames: true,
|
|
59
|
+
},
|
|
60
|
+
include: ['src/**/*'],
|
|
61
|
+
exclude: ['node_modules', 'dist'],
|
|
62
|
+
};
|
|
63
|
+
await fs.writeFile('tsconfig.json', JSON.stringify(tsconfig, null, 2) + '\n');
|
|
64
|
+
}
|
|
65
|
+
} else if (primaryLang === 'rust') {
|
|
66
|
+
// Check if Cargo.toml already exists
|
|
67
|
+
if (!(await fs.pathExists('Cargo.toml'))) {
|
|
68
|
+
const cargoToml = `[package]
|
|
69
|
+
name = "${safeName}"
|
|
70
|
+
version = "0.1.0"
|
|
71
|
+
edition = "2021"
|
|
72
|
+
description = "${answers.description || ''}"
|
|
73
|
+
license = "MIT"
|
|
74
|
+
|
|
75
|
+
[dependencies]
|
|
76
|
+
tokio = { version = "1", features = ["full"] }
|
|
77
|
+
serde = { version = "1", features = ["derive"] }
|
|
78
|
+
serde_json = "1"
|
|
79
|
+
thiserror = "1"
|
|
80
|
+
tracing = "0.1"
|
|
81
|
+
|
|
82
|
+
[dev-dependencies]
|
|
83
|
+
tokio-test = "0.4"
|
|
84
|
+
`;
|
|
85
|
+
await fs.writeFile('Cargo.toml', cargoToml);
|
|
86
|
+
|
|
87
|
+
// Create src/main.rs or src/lib.rs
|
|
88
|
+
await fs.ensureDir('src');
|
|
89
|
+
if (!(await fs.pathExists('src/main.rs')) && !(await fs.pathExists('src/lib.rs'))) {
|
|
90
|
+
const mainRs = `//! ${answers.description || projectName}
|
|
91
|
+
|
|
92
|
+
fn main() {
|
|
93
|
+
println!("Hello from ${projectName}!");
|
|
94
|
+
}
|
|
95
|
+
`;
|
|
96
|
+
await fs.writeFile('src/main.rs', mainRs);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
} else if (primaryLang === 'python') {
|
|
100
|
+
// Check if pyproject.toml already exists
|
|
101
|
+
if (!(await fs.pathExists('pyproject.toml'))) {
|
|
102
|
+
const pyprojectToml = `[project]
|
|
103
|
+
name = "${safeName}"
|
|
104
|
+
version = "0.1.0"
|
|
105
|
+
description = "${answers.description || ''}"
|
|
106
|
+
requires-python = ">=3.11"
|
|
107
|
+
dependencies = []
|
|
108
|
+
|
|
109
|
+
[project.optional-dependencies]
|
|
110
|
+
dev = [
|
|
111
|
+
"pytest>=7.0",
|
|
112
|
+
"ruff>=0.1",
|
|
113
|
+
"mypy>=1.0",
|
|
114
|
+
]
|
|
115
|
+
|
|
116
|
+
[tool.ruff]
|
|
117
|
+
line-length = 100
|
|
118
|
+
target-version = "py311"
|
|
119
|
+
|
|
120
|
+
[tool.ruff.lint]
|
|
121
|
+
select = ["E", "F", "I", "N", "W"]
|
|
122
|
+
|
|
123
|
+
[tool.mypy]
|
|
124
|
+
python_version = "3.11"
|
|
125
|
+
strict = true
|
|
126
|
+
|
|
127
|
+
[tool.pytest.ini_options]
|
|
128
|
+
testpaths = ["tests"]
|
|
129
|
+
`;
|
|
130
|
+
await fs.writeFile('pyproject.toml', pyprojectToml);
|
|
131
|
+
|
|
132
|
+
// Create src directory and __init__.py
|
|
133
|
+
const srcDir = `src/${safeName.replace(/-/g, '_')}`;
|
|
134
|
+
await fs.ensureDir(srcDir);
|
|
135
|
+
if (!(await fs.pathExists(`${srcDir}/__init__.py`))) {
|
|
136
|
+
await fs.writeFile(
|
|
137
|
+
`${srcDir}/__init__.py`,
|
|
138
|
+
`"""${answers.description || projectName}"""\n\n__version__ = "0.1.0"\n`
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
} else if (primaryLang === 'go') {
|
|
143
|
+
// Check if go.mod already exists
|
|
144
|
+
if (!(await fs.pathExists('go.mod'))) {
|
|
145
|
+
const goMod = `module github.com/${safeName}
|
|
146
|
+
|
|
147
|
+
go 1.21
|
|
148
|
+
|
|
149
|
+
require (
|
|
150
|
+
// Add dependencies here
|
|
151
|
+
)
|
|
152
|
+
`;
|
|
153
|
+
await fs.writeFile('go.mod', goMod);
|
|
154
|
+
|
|
155
|
+
// Create main.go
|
|
156
|
+
await fs.ensureDir('cmd');
|
|
157
|
+
if (!(await fs.pathExists('cmd/main.go'))) {
|
|
158
|
+
const mainGo = `package main
|
|
159
|
+
|
|
160
|
+
import "fmt"
|
|
161
|
+
|
|
162
|
+
func main() {
|
|
163
|
+
fmt.Println("Hello from ${projectName}!")
|
|
164
|
+
}
|
|
165
|
+
`;
|
|
166
|
+
await fs.writeFile('cmd/main.go', mainGo);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
} else if (primaryLang === 'java') {
|
|
170
|
+
// Generate pom.xml for Maven
|
|
171
|
+
if (!(await fs.pathExists('pom.xml'))) {
|
|
172
|
+
const pomXml = `<?xml version="1.0" encoding="UTF-8"?>
|
|
173
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
174
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
175
|
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
176
|
+
<modelVersion>4.0.0</modelVersion>
|
|
177
|
+
|
|
178
|
+
<groupId>com.example</groupId>
|
|
179
|
+
<artifactId>${safeName}</artifactId>
|
|
180
|
+
<version>0.1.0</version>
|
|
181
|
+
<packaging>jar</packaging>
|
|
182
|
+
|
|
183
|
+
<name>${projectName}</name>
|
|
184
|
+
<description>${answers.description || ''}</description>
|
|
185
|
+
|
|
186
|
+
<properties>
|
|
187
|
+
<maven.compiler.source>21</maven.compiler.source>
|
|
188
|
+
<maven.compiler.target>21</maven.compiler.target>
|
|
189
|
+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
190
|
+
</properties>
|
|
191
|
+
|
|
192
|
+
<dependencies>
|
|
193
|
+
<dependency>
|
|
194
|
+
<groupId>org.junit.jupiter</groupId>
|
|
195
|
+
<artifactId>junit-jupiter</artifactId>
|
|
196
|
+
<version>5.10.0</version>
|
|
197
|
+
<scope>test</scope>
|
|
198
|
+
</dependency>
|
|
199
|
+
</dependencies>
|
|
200
|
+
</project>
|
|
201
|
+
`;
|
|
202
|
+
await fs.writeFile('pom.xml', pomXml);
|
|
203
|
+
}
|
|
204
|
+
} else if (primaryLang === 'csharp') {
|
|
205
|
+
// Generate .csproj file
|
|
206
|
+
const csprojPath = `${projectName}.csproj`;
|
|
207
|
+
if (!(await fs.pathExists(csprojPath))) {
|
|
208
|
+
const csproj = `<Project Sdk="Microsoft.NET.Sdk">
|
|
209
|
+
|
|
210
|
+
<PropertyGroup>
|
|
211
|
+
<OutputType>Exe</OutputType>
|
|
212
|
+
<TargetFramework>net8.0</TargetFramework>
|
|
213
|
+
<ImplicitUsings>enable</ImplicitUsings>
|
|
214
|
+
<Nullable>enable</Nullable>
|
|
215
|
+
</PropertyGroup>
|
|
216
|
+
|
|
217
|
+
<ItemGroup>
|
|
218
|
+
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
|
219
|
+
</ItemGroup>
|
|
220
|
+
|
|
221
|
+
</Project>
|
|
222
|
+
`;
|
|
223
|
+
await fs.writeFile(csprojPath, csproj);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Language information for tech.md generation
|
|
230
|
+
*/
|
|
231
|
+
const LANG_INFO = {
|
|
232
|
+
javascript: {
|
|
233
|
+
name: 'JavaScript/TypeScript',
|
|
234
|
+
version: 'ES2022+ / TypeScript 5.0+',
|
|
235
|
+
runtime: 'Node.js 20+ LTS, Bun, Deno',
|
|
236
|
+
packageManager: 'npm, pnpm, yarn',
|
|
237
|
+
frameworks: 'React, Vue, Next.js, Express, Fastify',
|
|
238
|
+
testing: 'Jest, Vitest, Playwright',
|
|
239
|
+
},
|
|
240
|
+
python: {
|
|
241
|
+
name: 'Python',
|
|
242
|
+
version: '3.11+',
|
|
243
|
+
runtime: 'CPython, PyPy',
|
|
244
|
+
packageManager: 'pip, poetry, uv',
|
|
245
|
+
frameworks: 'FastAPI, Django, Flask',
|
|
246
|
+
testing: 'pytest, unittest',
|
|
247
|
+
},
|
|
248
|
+
rust: {
|
|
249
|
+
name: 'Rust',
|
|
250
|
+
version: '1.75+ stable',
|
|
251
|
+
runtime: 'Native binary',
|
|
252
|
+
packageManager: 'Cargo',
|
|
253
|
+
frameworks: 'Axum, Actix-web, Tokio',
|
|
254
|
+
testing: 'cargo test, criterion',
|
|
255
|
+
},
|
|
256
|
+
go: {
|
|
257
|
+
name: 'Go',
|
|
258
|
+
version: '1.21+',
|
|
259
|
+
runtime: 'Native binary',
|
|
260
|
+
packageManager: 'Go modules',
|
|
261
|
+
frameworks: 'Gin, Echo, Chi',
|
|
262
|
+
testing: 'go test, testify',
|
|
263
|
+
},
|
|
264
|
+
java: {
|
|
265
|
+
name: 'Java/Kotlin',
|
|
266
|
+
version: 'Java 21 LTS / Kotlin 1.9+',
|
|
267
|
+
runtime: 'JVM, GraalVM',
|
|
268
|
+
packageManager: 'Maven, Gradle',
|
|
269
|
+
frameworks: 'Spring Boot, Quarkus, Ktor',
|
|
270
|
+
testing: 'JUnit 5, Kotest',
|
|
271
|
+
},
|
|
272
|
+
csharp: {
|
|
273
|
+
name: 'C#/.NET',
|
|
274
|
+
version: '.NET 8+',
|
|
275
|
+
runtime: '.NET Runtime',
|
|
276
|
+
packageManager: 'NuGet',
|
|
277
|
+
frameworks: 'ASP.NET Core, MAUI',
|
|
278
|
+
testing: 'xUnit, NUnit',
|
|
279
|
+
},
|
|
280
|
+
cpp: {
|
|
281
|
+
name: 'C/C++',
|
|
282
|
+
version: 'C++20',
|
|
283
|
+
runtime: 'Native binary',
|
|
284
|
+
packageManager: 'vcpkg, Conan',
|
|
285
|
+
frameworks: 'Qt, Boost',
|
|
286
|
+
testing: 'GoogleTest, Catch2',
|
|
287
|
+
},
|
|
288
|
+
swift: {
|
|
289
|
+
name: 'Swift',
|
|
290
|
+
version: '5.9+',
|
|
291
|
+
runtime: 'Native binary',
|
|
292
|
+
packageManager: 'Swift Package Manager',
|
|
293
|
+
frameworks: 'SwiftUI, Vapor',
|
|
294
|
+
testing: 'XCTest',
|
|
295
|
+
},
|
|
296
|
+
ruby: {
|
|
297
|
+
name: 'Ruby',
|
|
298
|
+
version: '3.2+',
|
|
299
|
+
runtime: 'CRuby, JRuby',
|
|
300
|
+
packageManager: 'Bundler, RubyGems',
|
|
301
|
+
frameworks: 'Rails, Sinatra',
|
|
302
|
+
testing: 'RSpec, Minitest',
|
|
303
|
+
},
|
|
304
|
+
php: {
|
|
305
|
+
name: 'PHP',
|
|
306
|
+
version: '8.2+',
|
|
307
|
+
runtime: 'PHP-FPM, Swoole',
|
|
308
|
+
packageManager: 'Composer',
|
|
309
|
+
frameworks: 'Laravel, Symfony',
|
|
310
|
+
testing: 'PHPUnit, Pest',
|
|
311
|
+
},
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Generate language-specific tech.md content
|
|
316
|
+
*/
|
|
317
|
+
function generateTechMd(languages, answers, _locale) {
|
|
318
|
+
const isUndecided = languages[0] === 'undecided';
|
|
319
|
+
const date = new Date().toISOString().split('T')[0];
|
|
320
|
+
|
|
321
|
+
if (isUndecided) {
|
|
322
|
+
return `# Technology Stack
|
|
323
|
+
|
|
324
|
+
**Project**: ${answers.projectName}
|
|
325
|
+
**Last Updated**: ${date}
|
|
326
|
+
**Status**: Technology stack to be determined
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## Overview
|
|
331
|
+
|
|
332
|
+
The technology stack for this project has not yet been decided. This document will be updated once the technical decisions are made.
|
|
333
|
+
|
|
334
|
+
## Decision Criteria
|
|
335
|
+
|
|
336
|
+
When selecting technologies, consider:
|
|
337
|
+
|
|
338
|
+
1. **Application Type**: What type of application is being built?
|
|
339
|
+
2. **Performance Requirements**: What are the performance constraints?
|
|
340
|
+
3. **Team Expertise**: What technologies is the team familiar with?
|
|
341
|
+
4. **Ecosystem**: What libraries and tools are available?
|
|
342
|
+
5. **Long-term Maintainability**: How well-supported is the technology?
|
|
343
|
+
|
|
344
|
+
## Candidates Under Consideration
|
|
345
|
+
|
|
346
|
+
| Aspect | Options | Decision |
|
|
347
|
+
|--------|---------|----------|
|
|
348
|
+
| Primary Language | TBD | ⏳ Pending |
|
|
349
|
+
| Web Framework | TBD | ⏳ Pending |
|
|
350
|
+
| Database | TBD | ⏳ Pending |
|
|
351
|
+
| Hosting | TBD | ⏳ Pending |
|
|
352
|
+
|
|
353
|
+
## Next Steps
|
|
354
|
+
|
|
355
|
+
1. [ ] Define functional requirements
|
|
356
|
+
2. [ ] Identify performance constraints
|
|
357
|
+
3. [ ] Evaluate team skills
|
|
358
|
+
4. [ ] Create proof-of-concept
|
|
359
|
+
5. [ ] Make final decision and update this document
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
*Run \`musubi steering\` to update this document after decisions are made.*
|
|
364
|
+
`;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Generate tech.md for selected languages
|
|
368
|
+
const primaryLang = languages[0];
|
|
369
|
+
const primary = LANG_INFO[primaryLang] || { name: primaryLang, version: 'Latest' };
|
|
370
|
+
|
|
371
|
+
let languageTable = `### Programming Languages
|
|
372
|
+
|
|
373
|
+
| Language | Version | Role | Notes |
|
|
374
|
+
|----------|---------|------|-------|
|
|
375
|
+
`;
|
|
376
|
+
|
|
377
|
+
for (let i = 0; i < languages.length; i++) {
|
|
378
|
+
const lang = languages[i];
|
|
379
|
+
const info = LANG_INFO[lang] || { name: lang, version: 'Latest' };
|
|
380
|
+
const role = i === 0 ? 'Primary' : 'Secondary';
|
|
381
|
+
languageTable += `| ${info.name} | ${info.version} | ${role} | ${info.runtime || ''} |\n`;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
let frameworksSection = '';
|
|
385
|
+
for (const lang of languages) {
|
|
386
|
+
const info = LANG_INFO[lang];
|
|
387
|
+
if (info && info.frameworks) {
|
|
388
|
+
frameworksSection += `
|
|
389
|
+
### ${info.name} Ecosystem
|
|
390
|
+
|
|
391
|
+
- **Package Manager**: ${info.packageManager}
|
|
392
|
+
- **Frameworks**: ${info.frameworks}
|
|
393
|
+
- **Testing**: ${info.testing}
|
|
394
|
+
`;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return `# Technology Stack
|
|
399
|
+
|
|
400
|
+
**Project**: ${answers.projectName}
|
|
401
|
+
**Last Updated**: ${date}
|
|
402
|
+
**Version**: 0.1.0
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## Overview
|
|
407
|
+
|
|
408
|
+
${answers.description}
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## Primary Technologies
|
|
413
|
+
|
|
414
|
+
${languageTable}
|
|
415
|
+
${frameworksSection}
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## Development Environment
|
|
420
|
+
|
|
421
|
+
### Required Tools
|
|
422
|
+
|
|
423
|
+
- Primary language runtime (see above)
|
|
424
|
+
- Git 2.40+
|
|
425
|
+
- IDE: VS Code / JetBrains / Neovim
|
|
426
|
+
|
|
427
|
+
### Recommended Extensions
|
|
428
|
+
|
|
429
|
+
- Language-specific LSP
|
|
430
|
+
- Linter/Formatter integration
|
|
431
|
+
- Test runner integration
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## Architecture Decisions
|
|
436
|
+
|
|
437
|
+
| Decision | Choice | Rationale |
|
|
438
|
+
|----------|--------|-----------|
|
|
439
|
+
| Primary Language | ${primary.name} | Selected during project initialization |
|
|
440
|
+
| Package Manager | ${primary.packageManager || 'TBD'} | Standard for ${primary.name} |
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Dependencies
|
|
445
|
+
|
|
446
|
+
### Production Dependencies
|
|
447
|
+
|
|
448
|
+
*To be documented as dependencies are added.*
|
|
449
|
+
|
|
450
|
+
### Development Dependencies
|
|
451
|
+
|
|
452
|
+
*To be documented as dependencies are added.*
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
*Generated by MUSUBI SDD - Update with \`musubi steering\`*
|
|
457
|
+
`;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
module.exports = {
|
|
461
|
+
generateDependencyFiles,
|
|
462
|
+
generateTechMd,
|
|
463
|
+
LANG_INFO,
|
|
464
|
+
};
|