specweave 0.30.11 ā 0.30.13
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/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +25 -2
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/ado-area-selector.d.ts.map +1 -1
- package/dist/src/cli/helpers/ado-area-selector.js +13 -0
- package/dist/src/cli/helpers/ado-area-selector.js.map +1 -1
- package/dist/src/cli/helpers/init/living-docs-preflight.d.ts +5 -1
- package/dist/src/cli/helpers/init/living-docs-preflight.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/living-docs-preflight.js +80 -28
- package/dist/src/cli/helpers/init/living-docs-preflight.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +7 -2
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.d.ts +7 -0
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.js +33 -2
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.js.map +1 -1
- package/dist/src/cli/workers/brownfield-worker.d.ts +13 -0
- package/dist/src/cli/workers/brownfield-worker.d.ts.map +1 -1
- package/dist/src/cli/workers/brownfield-worker.js +154 -0
- package/dist/src/cli/workers/brownfield-worker.js.map +1 -1
- package/dist/src/cli/workers/clone-worker.js +19 -3
- package/dist/src/cli/workers/clone-worker.js.map +1 -1
- package/dist/src/cli/workers/living-docs-worker.js +272 -11
- package/dist/src/cli/workers/living-docs-worker.js.map +1 -1
- package/dist/src/core/background/brownfield-launcher.d.ts +2 -1
- package/dist/src/core/background/brownfield-launcher.d.ts.map +1 -1
- package/dist/src/core/background/brownfield-launcher.js.map +1 -1
- package/dist/src/core/background/types.d.ts +10 -2
- package/dist/src/core/background/types.d.ts.map +1 -1
- package/dist/src/core/discrepancy/brownfield-types.d.ts +3 -1
- package/dist/src/core/discrepancy/brownfield-types.d.ts.map +1 -1
- package/dist/src/core/living-docs/board-matcher.d.ts +120 -0
- package/dist/src/core/living-docs/board-matcher.d.ts.map +1 -0
- package/dist/src/core/living-docs/board-matcher.js +466 -0
- package/dist/src/core/living-docs/board-matcher.js.map +1 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts +39 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.js +197 -0
- package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
- package/dist/src/core/living-docs/foundation-builder.js +1 -1
- package/dist/src/core/living-docs/foundation-builder.js.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts +19 -8
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +148 -52
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/suggestions-generator.js +1 -1
- package/dist/src/core/living-docs/suggestions-generator.js.map +1 -1
- package/dist/src/core/living-docs/umbrella-detector.d.ts +4 -0
- package/dist/src/core/living-docs/umbrella-detector.d.ts.map +1 -1
- package/dist/src/core/living-docs/umbrella-detector.js +20 -1
- package/dist/src/core/living-docs/umbrella-detector.js.map +1 -1
- package/dist/src/core/living-docs/workitem-matcher.js +5 -5
- package/dist/src/core/living-docs/workitem-matcher.js.map +1 -1
- package/dist/src/core/llm/availability-messages.d.ts +33 -0
- package/dist/src/core/llm/availability-messages.d.ts.map +1 -0
- package/dist/src/core/llm/availability-messages.js +170 -0
- package/dist/src/core/llm/availability-messages.js.map +1 -0
- package/dist/src/core/llm/index.d.ts +34 -0
- package/dist/src/core/llm/index.d.ts.map +1 -0
- package/dist/src/core/llm/index.js +35 -0
- package/dist/src/core/llm/index.js.map +1 -0
- package/dist/src/core/llm/provider-factory.d.ts +48 -0
- package/dist/src/core/llm/provider-factory.d.ts.map +1 -0
- package/dist/src/core/llm/provider-factory.js +274 -0
- package/dist/src/core/llm/provider-factory.js.map +1 -0
- package/dist/src/core/llm/providers/anthropic-provider.d.ts +66 -0
- package/dist/src/core/llm/providers/anthropic-provider.d.ts.map +1 -0
- package/dist/src/core/llm/providers/anthropic-provider.js +195 -0
- package/dist/src/core/llm/providers/anthropic-provider.js.map +1 -0
- package/dist/src/core/llm/providers/azure-openai-provider.d.ts +47 -0
- package/dist/src/core/llm/providers/azure-openai-provider.d.ts.map +1 -0
- package/dist/src/core/llm/providers/azure-openai-provider.js +116 -0
- package/dist/src/core/llm/providers/azure-openai-provider.js.map +1 -0
- package/dist/src/core/llm/providers/bedrock-provider.d.ts +44 -0
- package/dist/src/core/llm/providers/bedrock-provider.d.ts.map +1 -0
- package/dist/src/core/llm/providers/bedrock-provider.js +149 -0
- package/dist/src/core/llm/providers/bedrock-provider.js.map +1 -0
- package/dist/src/core/llm/providers/claude-code-provider.d.ts +115 -0
- package/dist/src/core/llm/providers/claude-code-provider.d.ts.map +1 -0
- package/dist/src/core/llm/providers/claude-code-provider.js +379 -0
- package/dist/src/core/llm/providers/claude-code-provider.js.map +1 -0
- package/dist/src/core/llm/providers/ollama-provider.d.ts +40 -0
- package/dist/src/core/llm/providers/ollama-provider.d.ts.map +1 -0
- package/dist/src/core/llm/providers/ollama-provider.js +116 -0
- package/dist/src/core/llm/providers/ollama-provider.js.map +1 -0
- package/dist/src/core/llm/providers/openai-provider.d.ts +44 -0
- package/dist/src/core/llm/providers/openai-provider.d.ts.map +1 -0
- package/dist/src/core/llm/providers/openai-provider.js +119 -0
- package/dist/src/core/llm/providers/openai-provider.js.map +1 -0
- package/dist/src/core/llm/providers/vertex-ai-provider.d.ts +46 -0
- package/dist/src/core/llm/providers/vertex-ai-provider.d.ts.map +1 -0
- package/dist/src/core/llm/providers/vertex-ai-provider.js +123 -0
- package/dist/src/core/llm/providers/vertex-ai-provider.js.map +1 -0
- package/dist/src/core/llm/types.d.ts +181 -0
- package/dist/src/core/llm/types.d.ts.map +1 -0
- package/dist/src/core/llm/types.js +56 -0
- package/dist/src/core/llm/types.js.map +1 -0
- package/dist/src/importers/item-converter.d.ts +4 -0
- package/dist/src/importers/item-converter.d.ts.map +1 -1
- package/dist/src/importers/item-converter.js +73 -12
- package/dist/src/importers/item-converter.js.map +1 -1
- package/dist/src/init/repo/types.d.ts +1 -1
- package/dist/src/living-docs/enterprise-analyzer.d.ts +160 -0
- package/dist/src/living-docs/enterprise-analyzer.d.ts.map +1 -0
- package/dist/src/living-docs/enterprise-analyzer.js +887 -0
- package/dist/src/living-docs/enterprise-analyzer.js.map +1 -0
- package/dist/src/living-docs/epic-id-allocator.d.ts +4 -0
- package/dist/src/living-docs/epic-id-allocator.d.ts.map +1 -1
- package/dist/src/living-docs/epic-id-allocator.js +4 -0
- package/dist/src/living-docs/epic-id-allocator.js.map +1 -1
- package/dist/src/living-docs/fs-id-allocator.d.ts +9 -0
- package/dist/src/living-docs/fs-id-allocator.d.ts.map +1 -1
- package/dist/src/living-docs/fs-id-allocator.js +16 -5
- package/dist/src/living-docs/fs-id-allocator.js.map +1 -1
- package/dist/src/living-docs/smart-doc-organizer.d.ts +114 -0
- package/dist/src/living-docs/smart-doc-organizer.d.ts.map +1 -0
- package/dist/src/living-docs/smart-doc-organizer.js +535 -0
- package/dist/src/living-docs/smart-doc-organizer.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/commands/specweave-archive.md +69 -2
- package/plugins/specweave/commands/specweave-judge.md +265 -0
- package/plugins/specweave/commands/specweave-organize-docs.md +185 -0
- package/plugins/specweave/hooks/hooks.json +3 -3
- package/plugins/specweave/hooks/universal/hook-wrapper.cmd +26 -0
- package/plugins/specweave/hooks/universal/hook-wrapper.sh +67 -0
- package/plugins/specweave-docs/commands/build.md +158 -0
- package/plugins/specweave-docs/commands/{docs-generate.md ā generate.md} +7 -2
- package/plugins/specweave-docs/commands/health.md +268 -0
- package/plugins/specweave-docs/commands/{docs-init.md ā init.md} +7 -2
- package/plugins/specweave-docs/commands/organize.md +184 -0
- package/plugins/specweave-docs/commands/preview.md +138 -0
- package/plugins/specweave-docs/skills/preview/SKILL.md +105 -0
- package/plugins/specweave-release/commands/specweave-release-npm.md +22 -235
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart Documentation Organizer
|
|
3
|
+
*
|
|
4
|
+
* Intelligently organizes large documentation folders by:
|
|
5
|
+
* 1. Detecting themes from file content and titles
|
|
6
|
+
* 2. Generating themed category index files for navigation
|
|
7
|
+
* 3. Creating Docusaurus-compatible sidebar structures
|
|
8
|
+
* 4. Auto-organizing when folder exceeds threshold (default: 30 files)
|
|
9
|
+
*
|
|
10
|
+
* Philosophy: Generate indexes, don't move files (preserves URLs)
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
import { glob } from 'glob';
|
|
15
|
+
import { consoleLogger } from '../utils/logger.js';
|
|
16
|
+
// Theme definitions with keywords for detection
|
|
17
|
+
const THEME_DEFINITIONS = [
|
|
18
|
+
{
|
|
19
|
+
id: 'sync',
|
|
20
|
+
name: 'Synchronization & Integration',
|
|
21
|
+
keywords: ['sync', 'integration', 'bidirectional', 'import', 'export', 'pull', 'push'],
|
|
22
|
+
icon: 'š',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: 'hooks',
|
|
26
|
+
name: 'Hooks & Events',
|
|
27
|
+
keywords: ['hook', 'event', 'trigger', 'callback', 'post-task', 'pre-tool', 'session'],
|
|
28
|
+
icon: 'šŖ',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'github',
|
|
32
|
+
name: 'GitHub Integration',
|
|
33
|
+
keywords: ['github', 'gh-', 'issue', 'pull-request', 'pr-', 'actions', 'workflow'],
|
|
34
|
+
icon: 'š',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 'external-tools',
|
|
38
|
+
name: 'External Tools (ADO, JIRA)',
|
|
39
|
+
keywords: ['jira', 'ado', 'azure-devops', 'external-tool', 'area-path', 'work-item', 'epic'],
|
|
40
|
+
icon: 'š',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'testing',
|
|
44
|
+
name: 'Testing & Quality',
|
|
45
|
+
keywords: ['test', 'fixture', 'mock', 'coverage', 'tdd', 'isolation', 'assertion', 'qa'],
|
|
46
|
+
icon: 'š§Ŗ',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'brownfield',
|
|
50
|
+
name: 'Brownfield & Migration',
|
|
51
|
+
keywords: ['brownfield', 'migration', 'legacy', 'onboard', 'existing', 'import'],
|
|
52
|
+
icon: 'šļø',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: 'architecture',
|
|
56
|
+
name: 'Core Architecture',
|
|
57
|
+
keywords: ['pattern', 'factory', 'abstraction', 'layer', 'modular', 'structure', 'design'],
|
|
58
|
+
icon: 'šļø',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: 'performance',
|
|
62
|
+
name: 'Performance & Optimization',
|
|
63
|
+
keywords: ['cache', 'performance', 'optimization', 'pagination', 'batch', 'lazy', 'ttl'],
|
|
64
|
+
icon: 'ā”',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'security',
|
|
68
|
+
name: 'Security & Permissions',
|
|
69
|
+
keywords: ['permission', 'security', 'gate', 'auth', 'token', 'secret', 'credential'],
|
|
70
|
+
icon: 'š',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: 'increments',
|
|
74
|
+
name: 'Increment Lifecycle',
|
|
75
|
+
keywords: ['increment', 'status', 'lifecycle', 'backlog', 'phase', 'workflow', 'completion'],
|
|
76
|
+
icon: 'š¦',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: 'config',
|
|
80
|
+
name: 'Configuration & Setup',
|
|
81
|
+
keywords: ['config', 'env', 'setup', 'init', 'setting', 'option', 'parameter'],
|
|
82
|
+
icon: 'āļø',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: 'docs',
|
|
86
|
+
name: 'Documentation & Living Docs',
|
|
87
|
+
keywords: ['doc', 'living', 'spec', 'readme', 'naming', 'convention', 'folder'],
|
|
88
|
+
icon: 'š',
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
/**
|
|
92
|
+
* Smart Documentation Organizer
|
|
93
|
+
*/
|
|
94
|
+
export class SmartDocOrganizer {
|
|
95
|
+
constructor(options) {
|
|
96
|
+
this.projectPath = options.projectPath;
|
|
97
|
+
this.logger = options.logger ?? consoleLogger;
|
|
98
|
+
this.threshold = options.thresholdForOrganization ?? 30;
|
|
99
|
+
this.generateIndexes = options.generateIndexes ?? true;
|
|
100
|
+
this.dryRun = options.dryRun ?? false;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Analyze a documentation folder and create organization plan
|
|
104
|
+
*/
|
|
105
|
+
async analyzeFolder(folderPath) {
|
|
106
|
+
const absolutePath = path.isAbsolute(folderPath)
|
|
107
|
+
? folderPath
|
|
108
|
+
: path.join(this.projectPath, folderPath);
|
|
109
|
+
if (!fs.existsSync(absolutePath)) {
|
|
110
|
+
throw new Error(`Folder not found: ${absolutePath}`);
|
|
111
|
+
}
|
|
112
|
+
// Get all markdown files (exclude index files we generate)
|
|
113
|
+
const files = await glob('*.md', {
|
|
114
|
+
cwd: absolutePath,
|
|
115
|
+
nodir: true,
|
|
116
|
+
ignore: ['README.md', '_index-*.md', 'category-*.md'],
|
|
117
|
+
});
|
|
118
|
+
this.logger.info(`Analyzing ${files.length} files in ${folderPath}`);
|
|
119
|
+
// Classify each file by theme
|
|
120
|
+
const themedFiles = [];
|
|
121
|
+
for (const file of files) {
|
|
122
|
+
const fullPath = path.join(absolutePath, file);
|
|
123
|
+
const themed = await this.classifyFile(fullPath);
|
|
124
|
+
themedFiles.push(themed);
|
|
125
|
+
}
|
|
126
|
+
// Group by theme
|
|
127
|
+
const themeCategories = this.groupByTheme(themedFiles);
|
|
128
|
+
// Identify uncategorized files
|
|
129
|
+
const uncategorized = themedFiles.filter(f => f.primaryTheme === 'uncategorized');
|
|
130
|
+
// Determine if organization is needed
|
|
131
|
+
const needsOrganization = files.length > this.threshold;
|
|
132
|
+
// Generate suggested indexes
|
|
133
|
+
const suggestedIndexes = themeCategories
|
|
134
|
+
.filter(tc => tc.count >= 3) // Only suggest for themes with 3+ files
|
|
135
|
+
.map(tc => `_index-${tc.theme.id}.md`);
|
|
136
|
+
return {
|
|
137
|
+
folder: folderPath,
|
|
138
|
+
totalFiles: files.length,
|
|
139
|
+
themeCategories,
|
|
140
|
+
uncategorized,
|
|
141
|
+
suggestedIndexes,
|
|
142
|
+
needsOrganization,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Classify a file by detecting themes from content and filename
|
|
147
|
+
*/
|
|
148
|
+
async classifyFile(filePath) {
|
|
149
|
+
const fileName = path.basename(filePath, '.md');
|
|
150
|
+
const stats = fs.statSync(filePath);
|
|
151
|
+
let content = '';
|
|
152
|
+
let title = fileName;
|
|
153
|
+
try {
|
|
154
|
+
content = fs.readFileSync(filePath, 'utf-8');
|
|
155
|
+
// Extract title from first heading
|
|
156
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
157
|
+
if (titleMatch) {
|
|
158
|
+
title = titleMatch[1].replace(/^ADR-\d+:\s*/, ''); // Remove ADR prefix
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// Skip files that can't be read
|
|
163
|
+
}
|
|
164
|
+
// Combine filename and content for theme detection
|
|
165
|
+
const searchText = `${fileName} ${title} ${content}`.toLowerCase();
|
|
166
|
+
// Score each theme
|
|
167
|
+
const themeScores = [];
|
|
168
|
+
for (const theme of THEME_DEFINITIONS) {
|
|
169
|
+
let score = 0;
|
|
170
|
+
for (const keyword of theme.keywords) {
|
|
171
|
+
// Count keyword occurrences
|
|
172
|
+
const regex = new RegExp(keyword, 'gi');
|
|
173
|
+
const matches = searchText.match(regex);
|
|
174
|
+
if (matches) {
|
|
175
|
+
score += matches.length;
|
|
176
|
+
// Boost score if keyword in filename
|
|
177
|
+
if (fileName.toLowerCase().includes(keyword)) {
|
|
178
|
+
score += 5;
|
|
179
|
+
}
|
|
180
|
+
// Boost score if keyword in title
|
|
181
|
+
if (title.toLowerCase().includes(keyword)) {
|
|
182
|
+
score += 3;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (score > 0) {
|
|
187
|
+
themeScores.push({ theme, score });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Sort by score descending
|
|
191
|
+
themeScores.sort((a, b) => b.score - a.score);
|
|
192
|
+
// Get primary theme and all matching themes
|
|
193
|
+
const themes = themeScores.slice(0, 3).map(ts => ts.theme.id);
|
|
194
|
+
const primaryTheme = themes[0] ?? 'uncategorized';
|
|
195
|
+
return {
|
|
196
|
+
path: filePath,
|
|
197
|
+
name: fileName,
|
|
198
|
+
title,
|
|
199
|
+
themes,
|
|
200
|
+
primaryTheme,
|
|
201
|
+
lastModified: stats.mtime,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Group files by their primary theme
|
|
206
|
+
*/
|
|
207
|
+
groupByTheme(files) {
|
|
208
|
+
const themeMap = new Map();
|
|
209
|
+
for (const file of files) {
|
|
210
|
+
const theme = file.primaryTheme;
|
|
211
|
+
if (!themeMap.has(theme)) {
|
|
212
|
+
themeMap.set(theme, []);
|
|
213
|
+
}
|
|
214
|
+
themeMap.get(theme).push(file);
|
|
215
|
+
}
|
|
216
|
+
const categories = [];
|
|
217
|
+
for (const [themeId, themeFiles] of themeMap) {
|
|
218
|
+
if (themeId === 'uncategorized')
|
|
219
|
+
continue;
|
|
220
|
+
const themeDef = THEME_DEFINITIONS.find(t => t.id === themeId);
|
|
221
|
+
if (themeDef) {
|
|
222
|
+
categories.push({
|
|
223
|
+
theme: themeDef,
|
|
224
|
+
files: themeFiles.sort((a, b) => a.name.localeCompare(b.name)),
|
|
225
|
+
count: themeFiles.length,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Sort by count descending
|
|
230
|
+
return categories.sort((a, b) => b.count - a.count);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Generate themed index files for Docusaurus navigation
|
|
234
|
+
*/
|
|
235
|
+
async generateCategoryIndexes(plan) {
|
|
236
|
+
if (!plan.needsOrganization && !this.generateIndexes) {
|
|
237
|
+
return [];
|
|
238
|
+
}
|
|
239
|
+
const generatedFiles = [];
|
|
240
|
+
const folderPath = path.isAbsolute(plan.folder)
|
|
241
|
+
? plan.folder
|
|
242
|
+
: path.join(this.projectPath, plan.folder);
|
|
243
|
+
// Generate main category index
|
|
244
|
+
const mainIndexPath = path.join(folderPath, '_categories.md');
|
|
245
|
+
const mainIndexContent = this.generateMainCategoryIndex(plan);
|
|
246
|
+
if (!this.dryRun) {
|
|
247
|
+
fs.writeFileSync(mainIndexPath, mainIndexContent);
|
|
248
|
+
this.logger.info(`Generated: ${mainIndexPath}`);
|
|
249
|
+
}
|
|
250
|
+
generatedFiles.push(mainIndexPath);
|
|
251
|
+
// Generate individual theme indexes
|
|
252
|
+
for (const category of plan.themeCategories) {
|
|
253
|
+
if (category.count < 3)
|
|
254
|
+
continue; // Skip themes with too few files
|
|
255
|
+
const indexPath = path.join(folderPath, `_index-${category.theme.id}.md`);
|
|
256
|
+
const indexContent = this.generateThemeIndex(category, plan.folder);
|
|
257
|
+
if (!this.dryRun) {
|
|
258
|
+
fs.writeFileSync(indexPath, indexContent);
|
|
259
|
+
this.logger.info(`Generated: ${indexPath}`);
|
|
260
|
+
}
|
|
261
|
+
generatedFiles.push(indexPath);
|
|
262
|
+
}
|
|
263
|
+
return generatedFiles;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Generate main category index with links to themed indexes
|
|
267
|
+
*/
|
|
268
|
+
generateMainCategoryIndex(plan) {
|
|
269
|
+
const lines = [];
|
|
270
|
+
const folderName = path.basename(plan.folder);
|
|
271
|
+
lines.push('---');
|
|
272
|
+
lines.push('sidebar_position: 1');
|
|
273
|
+
lines.push(`title: "${this.formatTitle(folderName)} by Category"`);
|
|
274
|
+
lines.push('---');
|
|
275
|
+
lines.push('');
|
|
276
|
+
lines.push(`# ${this.formatTitle(folderName)} by Category`);
|
|
277
|
+
lines.push('');
|
|
278
|
+
lines.push(`This folder contains **${plan.totalFiles}** documents organized into the following categories:`);
|
|
279
|
+
lines.push('');
|
|
280
|
+
// Category table
|
|
281
|
+
lines.push('| Category | Count | Description |');
|
|
282
|
+
lines.push('|----------|-------|-------------|');
|
|
283
|
+
for (const category of plan.themeCategories) {
|
|
284
|
+
if (category.count < 3)
|
|
285
|
+
continue;
|
|
286
|
+
const link = `[${category.theme.icon} ${category.theme.name}](./_index-${category.theme.id}.md)`;
|
|
287
|
+
lines.push(`| ${link} | ${category.count} | View all ${category.theme.name.toLowerCase()} documents |`);
|
|
288
|
+
}
|
|
289
|
+
// Uncategorized section
|
|
290
|
+
if (plan.uncategorized.length > 0) {
|
|
291
|
+
lines.push(`| š Other | ${plan.uncategorized.length} | Documents not matching specific themes |`);
|
|
292
|
+
}
|
|
293
|
+
lines.push('');
|
|
294
|
+
lines.push('## Quick Stats');
|
|
295
|
+
lines.push('');
|
|
296
|
+
lines.push(`- **Total Documents**: ${plan.totalFiles}`);
|
|
297
|
+
lines.push(`- **Categorized**: ${plan.totalFiles - plan.uncategorized.length}`);
|
|
298
|
+
lines.push(`- **Categories**: ${plan.themeCategories.filter(c => c.count >= 3).length}`);
|
|
299
|
+
lines.push('');
|
|
300
|
+
// Recent documents
|
|
301
|
+
const allFiles = plan.themeCategories.flatMap(c => c.files);
|
|
302
|
+
const recent = allFiles
|
|
303
|
+
.sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime())
|
|
304
|
+
.slice(0, 5);
|
|
305
|
+
if (recent.length > 0) {
|
|
306
|
+
lines.push('## Recently Updated');
|
|
307
|
+
lines.push('');
|
|
308
|
+
for (const file of recent) {
|
|
309
|
+
const themeDef = THEME_DEFINITIONS.find(t => t.id === file.primaryTheme);
|
|
310
|
+
const icon = themeDef?.icon ?? 'š';
|
|
311
|
+
lines.push(`- ${icon} [${file.title}](./${file.name}.md) - ${file.lastModified.toLocaleDateString()}`);
|
|
312
|
+
}
|
|
313
|
+
lines.push('');
|
|
314
|
+
}
|
|
315
|
+
lines.push('---');
|
|
316
|
+
lines.push('*Auto-generated by SmartDocOrganizer*');
|
|
317
|
+
return lines.join('\n');
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Generate themed index with all files in that category
|
|
321
|
+
*/
|
|
322
|
+
generateThemeIndex(category, folderPath) {
|
|
323
|
+
const lines = [];
|
|
324
|
+
lines.push('---');
|
|
325
|
+
lines.push('sidebar_position: 2');
|
|
326
|
+
lines.push(`title: "${category.theme.icon} ${category.theme.name}"`);
|
|
327
|
+
lines.push('---');
|
|
328
|
+
lines.push('');
|
|
329
|
+
lines.push(`# ${category.theme.icon} ${category.theme.name}`);
|
|
330
|
+
lines.push('');
|
|
331
|
+
lines.push(`**${category.count}** documents in this category.`);
|
|
332
|
+
lines.push('');
|
|
333
|
+
// Group by sub-theme if many files
|
|
334
|
+
if (category.count > 15) {
|
|
335
|
+
// Further sub-group by first keyword match
|
|
336
|
+
const subGroups = this.subGroupByKeyword(category.files, category.theme);
|
|
337
|
+
for (const [subGroup, files] of subGroups) {
|
|
338
|
+
if (files.length > 0) {
|
|
339
|
+
lines.push(`## ${subGroup}`);
|
|
340
|
+
lines.push('');
|
|
341
|
+
for (const file of files) {
|
|
342
|
+
lines.push(`- [${file.title}](./${file.name}.md)`);
|
|
343
|
+
}
|
|
344
|
+
lines.push('');
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
// Simple list
|
|
350
|
+
lines.push('## Documents');
|
|
351
|
+
lines.push('');
|
|
352
|
+
for (const file of category.files) {
|
|
353
|
+
const date = file.lastModified.toLocaleDateString();
|
|
354
|
+
lines.push(`- [${file.title}](./${file.name}.md) *(${date})*`);
|
|
355
|
+
}
|
|
356
|
+
lines.push('');
|
|
357
|
+
}
|
|
358
|
+
lines.push('---');
|
|
359
|
+
lines.push(`[ā Back to Categories](./_categories.md)`);
|
|
360
|
+
return lines.join('\n');
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Sub-group files by keyword for large categories
|
|
364
|
+
*/
|
|
365
|
+
subGroupByKeyword(files, theme) {
|
|
366
|
+
const groups = new Map();
|
|
367
|
+
// Initialize groups for main keywords
|
|
368
|
+
const mainKeywords = theme.keywords.slice(0, 4);
|
|
369
|
+
for (const kw of mainKeywords) {
|
|
370
|
+
groups.set(this.formatTitle(kw), []);
|
|
371
|
+
}
|
|
372
|
+
groups.set('Other', []);
|
|
373
|
+
for (const file of files) {
|
|
374
|
+
const content = `${file.name} ${file.title}`.toLowerCase();
|
|
375
|
+
let assigned = false;
|
|
376
|
+
for (const kw of mainKeywords) {
|
|
377
|
+
if (content.includes(kw)) {
|
|
378
|
+
groups.get(this.formatTitle(kw)).push(file);
|
|
379
|
+
assigned = true;
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (!assigned) {
|
|
384
|
+
groups.get('Other').push(file);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
// Remove empty groups
|
|
388
|
+
for (const [key, value] of groups) {
|
|
389
|
+
if (value.length === 0) {
|
|
390
|
+
groups.delete(key);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return groups;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Format string to title case, preserving known acronyms
|
|
397
|
+
*/
|
|
398
|
+
formatTitle(str) {
|
|
399
|
+
const acronyms = ['adr', 'api', 'cli', 'hld', 'tdd', 'ado', 'pr', 'ci', 'cd', 'url', 'jwt', 'iac', 'sla', 'slo'];
|
|
400
|
+
return str
|
|
401
|
+
.replace(/[-_]/g, ' ')
|
|
402
|
+
.split(' ')
|
|
403
|
+
.map(word => {
|
|
404
|
+
const lower = word.toLowerCase();
|
|
405
|
+
if (acronyms.includes(lower)) {
|
|
406
|
+
return word.toUpperCase();
|
|
407
|
+
}
|
|
408
|
+
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
409
|
+
})
|
|
410
|
+
.join(' ');
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Update Docusaurus sidebar configuration
|
|
414
|
+
*/
|
|
415
|
+
async updateDocusaurusSidebar(plans) {
|
|
416
|
+
const sidebarConfig = [];
|
|
417
|
+
for (const plan of plans) {
|
|
418
|
+
if (!plan.needsOrganization)
|
|
419
|
+
continue;
|
|
420
|
+
const folderName = path.basename(plan.folder);
|
|
421
|
+
const categoryItems = [];
|
|
422
|
+
// Add main categories index first
|
|
423
|
+
categoryItems.push({
|
|
424
|
+
type: 'doc',
|
|
425
|
+
id: `${folderName}/_categories`,
|
|
426
|
+
label: 'š Browse by Category',
|
|
427
|
+
});
|
|
428
|
+
// Add theme-specific indexes
|
|
429
|
+
for (const category of plan.themeCategories) {
|
|
430
|
+
if (category.count < 3)
|
|
431
|
+
continue;
|
|
432
|
+
categoryItems.push({
|
|
433
|
+
type: 'doc',
|
|
434
|
+
id: `${folderName}/_index-${category.theme.id}`,
|
|
435
|
+
label: `${category.theme.icon} ${category.theme.name}`,
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
// Add auto-generated items
|
|
439
|
+
categoryItems.push({
|
|
440
|
+
type: 'autogenerated',
|
|
441
|
+
dirName: folderName,
|
|
442
|
+
});
|
|
443
|
+
sidebarConfig.push({
|
|
444
|
+
type: 'category',
|
|
445
|
+
label: this.formatTitle(folderName),
|
|
446
|
+
items: categoryItems,
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
return JSON.stringify(sidebarConfig, null, 2);
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Run full organization on internal docs
|
|
453
|
+
*/
|
|
454
|
+
async organizeInternalDocs() {
|
|
455
|
+
const internalDocsPath = path.join(this.projectPath, '.specweave/docs/internal');
|
|
456
|
+
if (!fs.existsSync(internalDocsPath)) {
|
|
457
|
+
throw new Error('No .specweave/docs/internal directory found');
|
|
458
|
+
}
|
|
459
|
+
const plans = [];
|
|
460
|
+
const generatedFiles = [];
|
|
461
|
+
// Analyze key folders that might need organization
|
|
462
|
+
const foldersToAnalyze = [
|
|
463
|
+
'architecture/adr',
|
|
464
|
+
'architecture/hld',
|
|
465
|
+
'architecture/concepts',
|
|
466
|
+
'delivery/guides',
|
|
467
|
+
'operations',
|
|
468
|
+
'governance',
|
|
469
|
+
];
|
|
470
|
+
for (const folder of foldersToAnalyze) {
|
|
471
|
+
const fullPath = path.join(internalDocsPath, folder);
|
|
472
|
+
if (!fs.existsSync(fullPath))
|
|
473
|
+
continue;
|
|
474
|
+
try {
|
|
475
|
+
const plan = await this.analyzeFolder(fullPath);
|
|
476
|
+
plans.push(plan);
|
|
477
|
+
if (plan.needsOrganization) {
|
|
478
|
+
const files = await this.generateCategoryIndexes(plan);
|
|
479
|
+
generatedFiles.push(...files);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
catch (err) {
|
|
483
|
+
this.logger.warn(`Failed to analyze ${folder}: ${err}`);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
// Generate summary
|
|
487
|
+
const summary = this.generateSummary(plans, generatedFiles);
|
|
488
|
+
return { plans, generatedFiles, summary };
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Generate organization summary
|
|
492
|
+
*/
|
|
493
|
+
generateSummary(plans, generatedFiles) {
|
|
494
|
+
const lines = [];
|
|
495
|
+
lines.push('# Documentation Organization Summary');
|
|
496
|
+
lines.push('');
|
|
497
|
+
const needsOrg = plans.filter(p => p.needsOrganization);
|
|
498
|
+
const totalFiles = plans.reduce((sum, p) => sum + p.totalFiles, 0);
|
|
499
|
+
lines.push(`- **Folders Analyzed**: ${plans.length}`);
|
|
500
|
+
lines.push(`- **Total Documents**: ${totalFiles}`);
|
|
501
|
+
lines.push(`- **Folders Needing Organization**: ${needsOrg.length}`);
|
|
502
|
+
lines.push(`- **Index Files Generated**: ${generatedFiles.length}`);
|
|
503
|
+
lines.push('');
|
|
504
|
+
if (needsOrg.length > 0) {
|
|
505
|
+
lines.push('## Organized Folders');
|
|
506
|
+
lines.push('');
|
|
507
|
+
for (const plan of needsOrg) {
|
|
508
|
+
lines.push(`### ${plan.folder}`);
|
|
509
|
+
lines.push(`- Files: ${plan.totalFiles}`);
|
|
510
|
+
lines.push(`- Categories: ${plan.themeCategories.filter(c => c.count >= 3).length}`);
|
|
511
|
+
lines.push('- Top themes:');
|
|
512
|
+
for (const cat of plan.themeCategories.slice(0, 5)) {
|
|
513
|
+
lines.push(` - ${cat.theme.icon} ${cat.theme.name}: ${cat.count} files`);
|
|
514
|
+
}
|
|
515
|
+
lines.push('');
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
lines.push('## Next Steps');
|
|
519
|
+
lines.push('');
|
|
520
|
+
lines.push('Run `/specweave-docs-preview:preview` to view the organized documentation.');
|
|
521
|
+
lines.push('');
|
|
522
|
+
return lines.join('\n');
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Convenience function to organize docs
|
|
527
|
+
*/
|
|
528
|
+
export async function organizeDocumentation(projectPath, options) {
|
|
529
|
+
const organizer = new SmartDocOrganizer({
|
|
530
|
+
projectPath,
|
|
531
|
+
...options,
|
|
532
|
+
});
|
|
533
|
+
return organizer.organizeInternalDocs();
|
|
534
|
+
}
|
|
535
|
+
//# sourceMappingURL=smart-doc-organizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-doc-organizer.js","sourceRoot":"","sources":["../../../src/living-docs/smart-doc-organizer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
|
-
"version": "0.30.
|
|
3
|
+
"version": "0.30.13",
|
|
4
4
|
"description": "Spec-driven development framework for Claude Code. AI-native workflow with living documentation, intelligent agents, and multilingual support (9 languages). Enterprise-grade traceability with permanent specs and temporary increments.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -58,6 +58,36 @@ This command automatically synchronizes living docs by archiving features in:
|
|
|
58
58
|
- `--archive-completed`: Archive all completed increments (use with caution!)
|
|
59
59
|
- `--preserve-active`: Never archive active/paused increments (default: true)
|
|
60
60
|
- `--dry-run`: Show what would be archived without moving files
|
|
61
|
+
- `--external`: **Archive external living docs** (FS-XXXE folders imported from ADO/JIRA/GitHub)
|
|
62
|
+
|
|
63
|
+
## NEW: External Living Docs Archiving (v0.30.12+)
|
|
64
|
+
|
|
65
|
+
**CRITICAL POLICY**: External items (imported from ADO/JIRA/GitHub) are **NEVER auto-archived** during import. Archive is **USER-INITIATED ONLY** via the `--external` flag.
|
|
66
|
+
|
|
67
|
+
External features are identified by the `E` suffix (e.g., `FS-001E`, `FS-042E`).
|
|
68
|
+
|
|
69
|
+
### External Archive Usage
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Archive specific external features
|
|
73
|
+
/specweave:archive --external FS-001E FS-002E
|
|
74
|
+
|
|
75
|
+
# Archive external features older than 90 days
|
|
76
|
+
/specweave:archive --external --older-than 90
|
|
77
|
+
|
|
78
|
+
# Keep last 10 external features, archive the rest
|
|
79
|
+
/specweave:archive --external --keep-last 10
|
|
80
|
+
|
|
81
|
+
# Preview external archive (dry run)
|
|
82
|
+
/specweave:archive --external --dry-run --keep-last 5
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Why Separate External Archiving?
|
|
86
|
+
|
|
87
|
+
1. **Increments are source of truth** for new features you create
|
|
88
|
+
2. **External imports are READ-ONLY references** - they track work in external tools
|
|
89
|
+
3. **Different lifecycles** - increments close when work is done, external items may stay open indefinitely
|
|
90
|
+
4. **Prevent accidental archiving** - external items should only be archived when YOU decide
|
|
61
91
|
|
|
62
92
|
## CRITICAL SAFETY FEATURE
|
|
63
93
|
|
|
@@ -298,11 +328,48 @@ import { Task } from '@claude/types';
|
|
|
298
328
|
const task = new Task('archive-increments', 'Archive completed increments');
|
|
299
329
|
|
|
300
330
|
task.run(async () => {
|
|
331
|
+
// Parse arguments
|
|
332
|
+
const args = process.argv.slice(2);
|
|
333
|
+
const isExternalMode = args.includes('--external');
|
|
334
|
+
|
|
335
|
+
// ================================================================
|
|
336
|
+
// EXTERNAL MODE: Archive external living docs (FS-XXXE folders)
|
|
337
|
+
// ================================================================
|
|
338
|
+
if (isExternalMode) {
|
|
339
|
+
const { FeatureArchiver } = await import('../../../dist/src/core/living-docs/feature-archiver.js');
|
|
340
|
+
const featureArchiver = new FeatureArchiver(process.cwd());
|
|
341
|
+
|
|
342
|
+
// Get feature IDs (non-flag arguments that match FS-*E pattern - external only)
|
|
343
|
+
// NOTE: Regex requires 'E' suffix to ensure only external features are targeted
|
|
344
|
+
const featureIds = args.filter(arg =>
|
|
345
|
+
!arg.startsWith('--') && /^FS-\d+E$/.test(arg)
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
const externalOptions = {
|
|
349
|
+
featureIds: featureIds.length > 0 ? featureIds : undefined,
|
|
350
|
+
olderThanDays: parseOption(args, '--older-than'),
|
|
351
|
+
keepLast: parseOption(args, '--keep-last'),
|
|
352
|
+
dryRun: args.includes('--dry-run'),
|
|
353
|
+
updateLinks: true
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
console.log('š¦ External living docs archive mode');
|
|
357
|
+
const result = await featureArchiver.archiveExternalFeatures(externalOptions);
|
|
358
|
+
|
|
359
|
+
console.log(`\nā
External archive complete:`);
|
|
360
|
+
console.log(` Archived: ${result.archivedFeatures.length} features`);
|
|
361
|
+
if (result.errors.length > 0) {
|
|
362
|
+
console.log(` Errors: ${result.errors.length}`);
|
|
363
|
+
}
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// ================================================================
|
|
368
|
+
// INCREMENT MODE: Archive completed increments (default)
|
|
369
|
+
// ================================================================
|
|
301
370
|
const { IncrementArchiver } = await import('../../../dist/src/core/increment/increment-archiver.js');
|
|
302
371
|
const archiver = new IncrementArchiver(process.cwd());
|
|
303
372
|
|
|
304
|
-
// Parse arguments
|
|
305
|
-
const args = process.argv.slice(2);
|
|
306
373
|
const incrementIds = args.filter(arg => !arg.startsWith('--'));
|
|
307
374
|
|
|
308
375
|
// Parse options
|