specweave 0.17.6 ā 0.17.8
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.md +365 -9
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.d.ts +9 -4
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.d.ts.map +1 -1
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.js +82 -12
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts +2 -2
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js +69 -10
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js.map +1 -1
- package/dist/src/cli/commands/detect-project.d.ts +9 -0
- package/dist/src/cli/commands/detect-project.d.ts.map +1 -0
- package/dist/src/cli/commands/detect-project.js +85 -0
- package/dist/src/cli/commands/detect-project.js.map +1 -0
- package/dist/src/cli/commands/detect-specs.d.ts +9 -0
- package/dist/src/cli/commands/detect-specs.d.ts.map +1 -0
- package/dist/src/cli/commands/detect-specs.js +73 -0
- package/dist/src/cli/commands/detect-specs.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +8 -15
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/core/living-docs/content-classifier.d.ts +83 -0
- package/dist/src/core/living-docs/content-classifier.d.ts.map +1 -0
- package/dist/src/core/living-docs/content-classifier.js +393 -0
- package/dist/src/core/living-docs/content-classifier.js.map +1 -0
- package/dist/src/core/living-docs/content-distributor.d.ts +126 -0
- package/dist/src/core/living-docs/content-distributor.d.ts.map +1 -0
- package/dist/src/core/living-docs/content-distributor.js +339 -0
- package/dist/src/core/living-docs/content-distributor.js.map +1 -0
- package/dist/src/core/living-docs/content-parser.d.ts +140 -0
- package/dist/src/core/living-docs/content-parser.d.ts.map +1 -0
- package/dist/src/core/living-docs/content-parser.js +316 -0
- package/dist/src/core/living-docs/content-parser.js.map +1 -0
- package/dist/src/core/living-docs/cross-linker.d.ts +126 -0
- package/dist/src/core/living-docs/cross-linker.d.ts.map +1 -0
- package/dist/src/core/living-docs/cross-linker.js +374 -0
- package/dist/src/core/living-docs/cross-linker.js.map +1 -0
- package/dist/src/core/living-docs/index.d.ts +89 -0
- package/dist/src/core/living-docs/index.d.ts.map +1 -0
- package/dist/src/core/living-docs/index.js +169 -0
- package/dist/src/core/living-docs/index.js.map +1 -0
- package/dist/src/core/living-docs/project-detector.d.ts +103 -0
- package/dist/src/core/living-docs/project-detector.d.ts.map +1 -0
- package/dist/src/core/living-docs/project-detector.js +314 -0
- package/dist/src/core/living-docs/project-detector.js.map +1 -0
- package/dist/src/core/repo-structure/prompt-consolidator.d.ts +1 -1
- package/dist/src/core/repo-structure/prompt-consolidator.d.ts.map +1 -1
- package/dist/src/core/repo-structure/prompt-consolidator.js +51 -22
- package/dist/src/core/repo-structure/prompt-consolidator.js.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts +2 -0
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.js +126 -62
- package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
- package/dist/src/core/spec-content-sync.d.ts +6 -0
- package/dist/src/core/spec-content-sync.d.ts.map +1 -1
- package/dist/src/core/spec-content-sync.js +25 -7
- package/dist/src/core/spec-content-sync.js.map +1 -1
- package/dist/src/core/spec-detector.d.ts +54 -0
- package/dist/src/core/spec-detector.d.ts.map +1 -0
- package/dist/src/core/spec-detector.js +197 -0
- package/dist/src/core/spec-detector.js.map +1 -0
- package/dist/src/core/spec-identifier-detector.d.ts +49 -0
- package/dist/src/core/spec-identifier-detector.d.ts.map +1 -0
- package/dist/src/core/spec-identifier-detector.js +198 -0
- package/dist/src/core/spec-identifier-detector.js.map +1 -0
- package/dist/src/core/types/spec-identifier.d.ts +67 -0
- package/dist/src/core/types/spec-identifier.d.ts.map +1 -0
- package/dist/src/core/types/spec-identifier.js +23 -0
- package/dist/src/core/types/spec-identifier.js.map +1 -0
- package/dist/src/utils/docs-preview/config-generator.d.ts.map +1 -1
- package/dist/src/utils/docs-preview/config-generator.js +11 -0
- package/dist/src/utils/docs-preview/config-generator.js.map +1 -1
- package/package.json +2 -1
- package/plugins/specweave/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave/lib/hooks/sync-living-docs.js +61 -5
- package/plugins/specweave/lib/hooks/sync-living-docs.ts +102 -13
- package/plugins/specweave-ado/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-docs-preview/commands/preview.md +11 -11
- package/plugins/specweave-github/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-github/hooks/post-task-completion.sh +59 -30
- package/plugins/specweave-github/lib/github-spec-content-sync.js +55 -6
- package/plugins/specweave-github/lib/github-spec-content-sync.ts +84 -12
- package/plugins/specweave-jira/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-mobile/.claude-plugin/plugin.json +1 -4
- package/plugins/specweave-release/.claude-plugin/plugin.json +3 -15
- package/src/templates/AGENTS.md.template +297 -0
- package/dist/locales/de/.gitkeep +0 -0
- package/dist/locales/de/cli.json +0 -108
- package/dist/locales/en/cli.json +0 -287
- package/dist/locales/en/errors.json +0 -7
- package/dist/locales/en/templates.json +0 -6
- package/dist/locales/es/.gitkeep +0 -0
- package/dist/locales/es/cli.json +0 -41
- package/dist/locales/fr/.gitkeep +0 -0
- package/dist/locales/fr/cli.json +0 -108
- package/dist/locales/ja/.gitkeep +0 -0
- package/dist/locales/ja/cli.json +0 -108
- package/dist/locales/ko/.gitkeep +0 -0
- package/dist/locales/ko/cli.json +0 -108
- package/dist/locales/pt/.gitkeep +0 -0
- package/dist/locales/pt/cli.json +0 -108
- package/dist/locales/ru/.gitkeep +0 -0
- package/dist/locales/ru/cli.json +0 -269
- package/dist/locales/zh/.gitkeep +0 -0
- package/dist/locales/zh/cli.json +0 -108
- package/plugins/specweave/plugin.json +0 -22
- package/plugins/specweave-ado/plugin.json +0 -20
- package/plugins/specweave-github/plugin.json +0 -19
- package/plugins/specweave-jira/plugin.json +0 -20
|
@@ -12,12 +12,46 @@ import { GitHubClientV2 } from './github-client-v2.js';
|
|
|
12
12
|
import { parseSpecContent, detectContentChanges, buildExternalDescription, hasExternalLink, updateSpecWithExternalLink, } from '../../../src/core/spec-content-sync.js';
|
|
13
13
|
import path from 'path';
|
|
14
14
|
import fs from 'fs/promises';
|
|
15
|
+
/**
|
|
16
|
+
* Get GitHub owner/repo from project config
|
|
17
|
+
*/
|
|
18
|
+
async function getGitHubRepoForProject(project, specPath) {
|
|
19
|
+
try {
|
|
20
|
+
// Find project root
|
|
21
|
+
let currentDir = path.dirname(specPath);
|
|
22
|
+
let configPath = path.join(currentDir, '.specweave', 'config.json');
|
|
23
|
+
// Search upward for .specweave/config.json
|
|
24
|
+
while (!await fs.access(configPath).then(() => true).catch(() => false)) {
|
|
25
|
+
const parentDir = path.dirname(currentDir);
|
|
26
|
+
if (parentDir === currentDir) {
|
|
27
|
+
return null; // Reached root
|
|
28
|
+
}
|
|
29
|
+
currentDir = parentDir;
|
|
30
|
+
configPath = path.join(currentDir, '.specweave', 'config.json');
|
|
31
|
+
}
|
|
32
|
+
// Read config
|
|
33
|
+
const configContent = await fs.readFile(configPath, 'utf-8');
|
|
34
|
+
const config = JSON.parse(configContent);
|
|
35
|
+
// Get project config
|
|
36
|
+
const projectConfig = config.specs?.projects?.[project];
|
|
37
|
+
if (!projectConfig?.github) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
owner: projectConfig.github.owner,
|
|
42
|
+
repo: projectConfig.github.repo
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
15
49
|
/**
|
|
16
50
|
* Sync spec content to GitHub issue
|
|
17
51
|
* Creates issue if it doesn't exist, updates if it does
|
|
18
52
|
*/
|
|
19
53
|
export async function syncSpecContentToGitHub(options) {
|
|
20
|
-
|
|
54
|
+
let { specPath, owner, repo, dryRun = false, verbose = false } = options;
|
|
21
55
|
try {
|
|
22
56
|
// 1. Parse spec content
|
|
23
57
|
const spec = await parseSpecContent(specPath);
|
|
@@ -29,11 +63,28 @@ export async function syncSpecContentToGitHub(options) {
|
|
|
29
63
|
};
|
|
30
64
|
}
|
|
31
65
|
if (verbose) {
|
|
32
|
-
console.log(`š Parsed spec: ${spec.
|
|
66
|
+
console.log(`š Parsed spec: ${spec.identifier.compact}`);
|
|
67
|
+
console.log(` Project: ${spec.project}`);
|
|
33
68
|
console.log(` Title: ${spec.title}`);
|
|
34
69
|
console.log(` User Stories: ${spec.userStories.length}`);
|
|
35
70
|
}
|
|
36
|
-
// 2.
|
|
71
|
+
// 2. Auto-detect owner/repo from project config if not provided
|
|
72
|
+
if (!owner || !repo) {
|
|
73
|
+
const repoConfig = await getGitHubRepoForProject(spec.project, specPath);
|
|
74
|
+
if (!repoConfig) {
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
action: 'error',
|
|
78
|
+
error: `No GitHub repository configured for project "${spec.project}". Add specs.projects.${spec.project}.github in config.json`,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
owner = repoConfig.owner;
|
|
82
|
+
repo = repoConfig.repo;
|
|
83
|
+
if (verbose) {
|
|
84
|
+
console.log(` Auto-detected repo: ${owner}/${repo}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// 3. Check if issue already exists
|
|
37
88
|
const existingIssueNumber = await hasExternalLink(specPath, 'github');
|
|
38
89
|
const client = GitHubClientV2.fromRepo(owner, repo);
|
|
39
90
|
if (existingIssueNumber) {
|
|
@@ -59,8 +110,9 @@ export async function syncSpecContentToGitHub(options) {
|
|
|
59
110
|
async function createGitHubIssue(client, spec, options) {
|
|
60
111
|
const { specPath, dryRun, verbose } = options;
|
|
61
112
|
try {
|
|
62
|
-
// Build issue title and body
|
|
63
|
-
|
|
113
|
+
// Build issue title and body using compact format
|
|
114
|
+
// Examples: [BE-JIRA-AUTH-123] User Authentication, [FE-user-login-ui] Login UI
|
|
115
|
+
const title = `[${spec.identifier.compact}] ${spec.title}`;
|
|
64
116
|
const body = buildExternalDescription(spec);
|
|
65
117
|
if (verbose) {
|
|
66
118
|
console.log(`\nš Creating GitHub issue:`);
|
|
@@ -78,8 +130,13 @@ async function createGitHubIssue(client, spec, options) {
|
|
|
78
130
|
externalUrl: 'https://github.com/DRY-RUN',
|
|
79
131
|
};
|
|
80
132
|
}
|
|
81
|
-
// Create issue
|
|
82
|
-
const labels = [
|
|
133
|
+
// Create issue with project-specific labels
|
|
134
|
+
const labels = [
|
|
135
|
+
'specweave',
|
|
136
|
+
'spec',
|
|
137
|
+
spec.project, // backend, frontend, mobile, etc.
|
|
138
|
+
spec.metadata.priority || 'P2'
|
|
139
|
+
].filter(Boolean);
|
|
83
140
|
const issue = await client.createEpicIssue(title, body, undefined, labels);
|
|
84
141
|
if (verbose) {
|
|
85
142
|
console.log(`ā
Created issue #${issue.number}`);
|
|
@@ -114,8 +171,10 @@ async function updateGitHubIssue(client, spec, issueNumber, options) {
|
|
|
114
171
|
console.log(`\nš Checking for changes in issue #${issueNumber}`);
|
|
115
172
|
}
|
|
116
173
|
// Detect changes
|
|
174
|
+
// Strip any ID prefix from title (flexible format: [BE-JIRA-123], [FE-login-ui], etc.)
|
|
175
|
+
const cleanTitle = issue.title.replace(/^\[[A-Z]{2,4}-[A-Z0-9-]+\]\s*/, '');
|
|
117
176
|
const changes = detectContentChanges(spec, {
|
|
118
|
-
title:
|
|
177
|
+
title: cleanTitle,
|
|
119
178
|
description: issue.body || '',
|
|
120
179
|
userStoryCount: countUserStoriesInBody(issue.body || ''),
|
|
121
180
|
});
|
|
@@ -136,8 +195,8 @@ async function updateGitHubIssue(client, spec, issueNumber, options) {
|
|
|
136
195
|
console.log(` - ${change}`);
|
|
137
196
|
}
|
|
138
197
|
}
|
|
139
|
-
// Build updated content
|
|
140
|
-
const newTitle = `[${spec.
|
|
198
|
+
// Build updated content using compact format
|
|
199
|
+
const newTitle = `[${spec.identifier.compact}] ${spec.title}`;
|
|
141
200
|
const newBody = buildExternalDescription(spec);
|
|
142
201
|
if (dryRun) {
|
|
143
202
|
console.log('\nš Dry run - would update issue:');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github-spec-content-sync.js","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-spec-content-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,0BAA0B,GAI3B,MAAM,wCAAwC,CAAC;AAChD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,aAAa,CAAC;AAU7B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAiC;IAEjC,
|
|
1
|
+
{"version":3,"file":"github-spec-content-sync.js","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/github-spec-content-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-project.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/detect-project.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Detect Project CLI
|
|
4
|
+
*
|
|
5
|
+
* Detects which project (backend, frontend, mobile, etc.) a feature belongs to
|
|
6
|
+
* based on keywords in the increment name or description.
|
|
7
|
+
*/
|
|
8
|
+
import { detectProjectFromIncrement } from '../../core/spec-detector.js';
|
|
9
|
+
import { ConfigManager } from '../../core/config-manager.js';
|
|
10
|
+
async function main() {
|
|
11
|
+
try {
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
// Parse arguments
|
|
14
|
+
let incrementName = '';
|
|
15
|
+
let description = '';
|
|
16
|
+
for (let i = 0; i < args.length; i++) {
|
|
17
|
+
if (args[i] === '--name' && i + 1 < args.length) {
|
|
18
|
+
incrementName = args[i + 1];
|
|
19
|
+
}
|
|
20
|
+
else if (args[i] === '--description' && i + 1 < args.length) {
|
|
21
|
+
description = args[i + 1];
|
|
22
|
+
}
|
|
23
|
+
else if (!args[i].startsWith('--')) {
|
|
24
|
+
// Positional argument = increment name
|
|
25
|
+
incrementName = args[i];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (!incrementName) {
|
|
29
|
+
console.error('Usage: detect-project <increment-name> [--description <text>]');
|
|
30
|
+
console.error('');
|
|
31
|
+
console.error('Examples:');
|
|
32
|
+
console.error(' detect-project "Add user authentication API"');
|
|
33
|
+
console.error(' detect-project "Dark mode toggle" --description "Add dark mode to mobile app"');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
// Load config
|
|
37
|
+
const configManager = new ConfigManager(process.cwd());
|
|
38
|
+
const config = await configManager.loadAsync();
|
|
39
|
+
// Detect project
|
|
40
|
+
const project = detectProjectFromIncrement(incrementName, description, config);
|
|
41
|
+
// Get project config for additional details
|
|
42
|
+
const projectConfig = config.specs?.projects?.[project];
|
|
43
|
+
// Output JSON
|
|
44
|
+
console.log(JSON.stringify({
|
|
45
|
+
project,
|
|
46
|
+
projectName: projectConfig?.displayName || project,
|
|
47
|
+
description: projectConfig?.description || '',
|
|
48
|
+
confidence: calculateConfidence(incrementName, description, project, config)
|
|
49
|
+
}, null, 2));
|
|
50
|
+
process.exit(0);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error('Error detecting project:', error);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Calculate confidence score for project detection
|
|
59
|
+
*/
|
|
60
|
+
function calculateConfidence(incrementName, description, detectedProject, config) {
|
|
61
|
+
const text = `${incrementName} ${description}`.toLowerCase();
|
|
62
|
+
let score = 0;
|
|
63
|
+
// Check if any keywords matched
|
|
64
|
+
const projectConfig = config.specs?.projects?.[detectedProject];
|
|
65
|
+
const keywords = projectConfig?.keywords || [];
|
|
66
|
+
for (const keyword of keywords) {
|
|
67
|
+
if (text.includes(keyword.toLowerCase())) {
|
|
68
|
+
score += 0.3; // Each keyword match = +30%
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Check for common patterns
|
|
72
|
+
if (detectedProject === 'backend' && (text.includes('api') || text.includes('server'))) {
|
|
73
|
+
score += 0.2;
|
|
74
|
+
}
|
|
75
|
+
if (detectedProject === 'frontend' && (text.includes('ui') || text.includes('web'))) {
|
|
76
|
+
score += 0.2;
|
|
77
|
+
}
|
|
78
|
+
if (detectedProject === 'mobile' && (text.includes('ios') || text.includes('android'))) {
|
|
79
|
+
score += 0.2;
|
|
80
|
+
}
|
|
81
|
+
// Cap at 1.0 (100%)
|
|
82
|
+
return Math.min(score, 1.0);
|
|
83
|
+
}
|
|
84
|
+
main();
|
|
85
|
+
//# sourceMappingURL=detect-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-project.js","sourceRoot":"","sources":["../../../../src/cli/commands/detect-project.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-specs.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/detect-specs.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Detect Specs CLI
|
|
4
|
+
*
|
|
5
|
+
* Detects all specs referenced in the current or specified increment.
|
|
6
|
+
* Used by hooks to find which specs need to be synced to GitHub.
|
|
7
|
+
*/
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import fs from 'fs-extra';
|
|
10
|
+
import { detectSpecsInIncrement } from '../../core/spec-detector.js';
|
|
11
|
+
import { ConfigManager } from '../../core/config-manager.js';
|
|
12
|
+
async function main() {
|
|
13
|
+
try {
|
|
14
|
+
const args = process.argv.slice(2);
|
|
15
|
+
let incrementPath;
|
|
16
|
+
// Parse arguments
|
|
17
|
+
for (let i = 0; i < args.length; i++) {
|
|
18
|
+
if (args[i] === '--increment' && i + 1 < args.length) {
|
|
19
|
+
incrementPath = args[i + 1];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// If no increment specified, detect current increment
|
|
23
|
+
if (!incrementPath) {
|
|
24
|
+
const incrementsDir = path.join(process.cwd(), '.specweave/increments');
|
|
25
|
+
if (!fs.existsSync(incrementsDir)) {
|
|
26
|
+
console.error('No .specweave/increments directory found');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
// Find most recent increment (excluding _backlog)
|
|
30
|
+
const increments = fs
|
|
31
|
+
.readdirSync(incrementsDir)
|
|
32
|
+
.filter(f => {
|
|
33
|
+
const stat = fs.statSync(path.join(incrementsDir, f));
|
|
34
|
+
return stat.isDirectory() && f !== '_backlog';
|
|
35
|
+
})
|
|
36
|
+
.map(f => ({
|
|
37
|
+
name: f,
|
|
38
|
+
mtime: fs.statSync(path.join(incrementsDir, f)).mtime
|
|
39
|
+
}))
|
|
40
|
+
.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
|
|
41
|
+
if (increments.length === 0) {
|
|
42
|
+
console.error('No active increments found');
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
incrementPath = path.join(incrementsDir, increments[0].name);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// Resolve relative path
|
|
49
|
+
if (!path.isAbsolute(incrementPath)) {
|
|
50
|
+
incrementPath = path.join(process.cwd(), '.specweave/increments', incrementPath);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Validate increment exists
|
|
54
|
+
if (!fs.existsSync(incrementPath)) {
|
|
55
|
+
console.error(`Increment not found: ${incrementPath}`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
// Load config
|
|
59
|
+
const configManager = new ConfigManager(process.cwd());
|
|
60
|
+
const config = await configManager.loadAsync();
|
|
61
|
+
// Detect specs
|
|
62
|
+
const result = await detectSpecsInIncrement(incrementPath, config);
|
|
63
|
+
// Output JSON
|
|
64
|
+
console.log(JSON.stringify(result, null, 2));
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.error('Error detecting specs:', error);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
main();
|
|
73
|
+
//# sourceMappingURL=detect-specs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-specs.js","sourceRoot":"","sources":["../../../../src/cli/commands/detect-specs.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACnC,IAAI,aAAiC,CAAC;QAEtC,kBAAkB;QAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,aAAa,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;gBACrD,aAAa,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,sDAAsD;QACtD,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,uBAAuB,CAAC,CAAC;YAExE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;gBAClC,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;gBAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,kDAAkD;YAClD,MAAM,UAAU,GAAG,EAAE;iBAClB,WAAW,CAAC,aAAa,CAAC;iBAC1B,MAAM,CAAC,CAAC,CAAC,EAAE;gBACV,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;gBACtD,OAAO,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,UAAU,CAAC;YAChD,CAAC,CAAC;iBACD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACT,IAAI,EAAE,CAAC;gBACP,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK;aACtD,CAAC,CAAC;iBACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAEzD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5B,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;gBAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACN,wBAAwB;YACxB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;gBACpC,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,uBAAuB,EAAE,aAAa,CAAC,CAAC;YACnF,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,wBAAwB,aAAa,EAAE,CAAC,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,cAAc;QACd,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,SAAS,EAAE,CAAC;QAE/C,eAAe;QACf,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAEnE,cAAc;QACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAE7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/init.ts"],"names":[],"mappings":"AA0BA,UAAU,WAAW;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/init.ts"],"names":[],"mappings":"AA0BA,UAAU,WAAW;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA8ID,wBAAsB,WAAW,CAC/B,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CA07Bf"}
|
|
@@ -112,25 +112,18 @@ async function createMultiProjectFolders(targetDir) {
|
|
|
112
112
|
await fs.writeJson(configPath, config, { spaces: 2 });
|
|
113
113
|
console.log(chalk.blue('\nš Creating Multi-Project Folders'));
|
|
114
114
|
console.log(chalk.gray(` Detected: ${jiraProjects.length} Jira projects (${jiraProjects.join(', ')})`));
|
|
115
|
-
// Create project-specific folders following
|
|
116
|
-
// Structure: .specweave/docs/internal/
|
|
115
|
+
// Create project-specific folders following SIMPLIFIED architecture (increment 0026)
|
|
116
|
+
// Structure: .specweave/docs/internal/specs/{project-id}/
|
|
117
|
+
// NOTE: Only specs folder is created. All docs live at root internal/ level.
|
|
117
118
|
for (const projectKey of jiraProjects) {
|
|
118
119
|
const projectId = projectKey.toLowerCase(); // FE ā fe, BE ā be
|
|
119
120
|
const internalDocsPath = path.join(targetDir, '.specweave', 'docs', 'internal');
|
|
120
|
-
// Create
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
path.join(internalDocsPath, 'team', projectId), // Team playbooks
|
|
125
|
-
path.join(internalDocsPath, 'project-arch', projectId), // Project-specific ADRs (renamed from architecture)
|
|
126
|
-
path.join(internalDocsPath, 'legacy', projectId) // Brownfield imports
|
|
127
|
-
];
|
|
128
|
-
for (const subfolder of projectSubfolders) {
|
|
129
|
-
if (!fs.existsSync(subfolder)) {
|
|
130
|
-
fs.mkdirSync(subfolder, { recursive: true });
|
|
131
|
-
}
|
|
121
|
+
// Create ONLY specs folder (simplified structure)
|
|
122
|
+
const specsPath = path.join(internalDocsPath, 'specs', projectId);
|
|
123
|
+
if (!fs.existsSync(specsPath)) {
|
|
124
|
+
fs.mkdirSync(specsPath, { recursive: true });
|
|
132
125
|
}
|
|
133
|
-
console.log(chalk.green(` ā Created project: ${projectKey} (
|
|
126
|
+
console.log(chalk.green(` ā Created project: ${projectKey} (simplified structure)`));
|
|
134
127
|
}
|
|
135
128
|
console.log('');
|
|
136
129
|
}
|