tlc-claude-code 1.2.27 → 1.2.29
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.md +9 -4
- package/dashboard/dist/components/ActivityFeed.d.ts +17 -0
- package/dashboard/dist/components/ActivityFeed.js +42 -0
- package/dashboard/dist/components/ActivityFeed.test.d.ts +1 -0
- package/dashboard/dist/components/ActivityFeed.test.js +162 -0
- package/dashboard/dist/components/BranchSelector.d.ts +16 -0
- package/dashboard/dist/components/BranchSelector.js +49 -0
- package/dashboard/dist/components/BranchSelector.test.d.ts +1 -0
- package/dashboard/dist/components/BranchSelector.test.js +166 -0
- package/dashboard/dist/components/CommandPalette.d.ts +17 -0
- package/dashboard/dist/components/CommandPalette.js +118 -0
- package/dashboard/dist/components/CommandPalette.test.d.ts +1 -0
- package/dashboard/dist/components/CommandPalette.test.js +181 -0
- package/dashboard/dist/components/ConnectionStatus.d.ts +16 -0
- package/dashboard/dist/components/ConnectionStatus.js +27 -0
- package/dashboard/dist/components/ConnectionStatus.test.d.ts +1 -0
- package/dashboard/dist/components/ConnectionStatus.test.js +121 -0
- package/dashboard/dist/components/DeviceFrame.d.ts +19 -0
- package/dashboard/dist/components/DeviceFrame.js +52 -0
- package/dashboard/dist/components/DeviceFrame.test.d.ts +1 -0
- package/dashboard/dist/components/DeviceFrame.test.js +118 -0
- package/dashboard/dist/components/EnvironmentBadge.d.ts +11 -0
- package/dashboard/dist/components/EnvironmentBadge.js +16 -0
- package/dashboard/dist/components/EnvironmentBadge.test.d.ts +1 -0
- package/dashboard/dist/components/EnvironmentBadge.test.js +102 -0
- package/dashboard/dist/components/FocusIndicator.d.ts +19 -0
- package/dashboard/dist/components/FocusIndicator.js +47 -0
- package/dashboard/dist/components/FocusIndicator.test.d.ts +1 -0
- package/dashboard/dist/components/FocusIndicator.test.js +117 -0
- package/dashboard/dist/components/KeyboardHelp.d.ts +15 -0
- package/dashboard/dist/components/KeyboardHelp.js +61 -0
- package/dashboard/dist/components/KeyboardHelp.test.d.ts +1 -0
- package/dashboard/dist/components/KeyboardHelp.test.js +131 -0
- package/dashboard/dist/components/LogSearch.d.ts +13 -0
- package/dashboard/dist/components/LogSearch.js +43 -0
- package/dashboard/dist/components/LogSearch.test.d.ts +1 -0
- package/dashboard/dist/components/LogSearch.test.js +100 -0
- package/dashboard/dist/components/LogStream.d.ts +21 -0
- package/dashboard/dist/components/LogStream.js +123 -0
- package/dashboard/dist/components/LogStream.test.d.ts +1 -0
- package/dashboard/dist/components/LogStream.test.js +159 -0
- package/dashboard/dist/components/PreviewPanel.d.ts +18 -0
- package/dashboard/dist/components/PreviewPanel.js +73 -0
- package/dashboard/dist/components/PreviewPanel.test.d.ts +1 -0
- package/dashboard/dist/components/PreviewPanel.test.js +124 -0
- package/dashboard/dist/components/ProjectCard.d.ts +18 -0
- package/dashboard/dist/components/ProjectCard.js +19 -0
- package/dashboard/dist/components/ProjectCard.test.d.ts +1 -0
- package/dashboard/dist/components/ProjectCard.test.js +53 -0
- package/dashboard/dist/components/ProjectDetail.d.ts +44 -0
- package/dashboard/dist/components/ProjectDetail.js +65 -0
- package/dashboard/dist/components/ProjectDetail.test.d.ts +1 -0
- package/dashboard/dist/components/ProjectDetail.test.js +196 -0
- package/dashboard/dist/components/ProjectList.d.ts +11 -0
- package/dashboard/dist/components/ProjectList.js +62 -0
- package/dashboard/dist/components/ProjectList.test.d.ts +1 -0
- package/dashboard/dist/components/ProjectList.test.js +93 -0
- package/dashboard/dist/components/SettingsPanel.d.ts +32 -0
- package/dashboard/dist/components/SettingsPanel.js +154 -0
- package/dashboard/dist/components/SettingsPanel.test.d.ts +1 -0
- package/dashboard/dist/components/SettingsPanel.test.js +196 -0
- package/dashboard/dist/components/StatusBar.d.ts +16 -0
- package/dashboard/dist/components/StatusBar.js +47 -0
- package/dashboard/dist/components/StatusBar.test.d.ts +1 -0
- package/dashboard/dist/components/StatusBar.test.js +123 -0
- package/dashboard/dist/components/TaskBoard.d.ts +22 -0
- package/dashboard/dist/components/TaskBoard.js +102 -0
- package/dashboard/dist/components/TaskBoard.test.d.ts +1 -0
- package/dashboard/dist/components/TaskBoard.test.js +113 -0
- package/dashboard/dist/components/TaskCard.d.ts +17 -0
- package/dashboard/dist/components/TaskCard.js +29 -0
- package/dashboard/dist/components/TaskCard.test.d.ts +1 -0
- package/dashboard/dist/components/TaskCard.test.js +109 -0
- package/dashboard/dist/components/TaskDetail.d.ts +36 -0
- package/dashboard/dist/components/TaskDetail.js +41 -0
- package/dashboard/dist/components/TaskDetail.test.d.ts +1 -0
- package/dashboard/dist/components/TaskDetail.test.js +164 -0
- package/dashboard/dist/components/TaskFilter.d.ts +12 -0
- package/dashboard/dist/components/TaskFilter.js +138 -0
- package/dashboard/dist/components/TaskFilter.test.d.ts +1 -0
- package/dashboard/dist/components/TaskFilter.test.js +109 -0
- package/dashboard/dist/components/TeamPanel.d.ts +15 -0
- package/dashboard/dist/components/TeamPanel.js +24 -0
- package/dashboard/dist/components/TeamPanel.test.d.ts +1 -0
- package/dashboard/dist/components/TeamPanel.test.js +109 -0
- package/dashboard/dist/components/TeamPresence.d.ts +14 -0
- package/dashboard/dist/components/TeamPresence.js +31 -0
- package/dashboard/dist/components/TeamPresence.test.d.ts +1 -0
- package/dashboard/dist/components/TeamPresence.test.js +144 -0
- package/dashboard/dist/components/layout/Header.d.ts +9 -0
- package/dashboard/dist/components/layout/Header.js +11 -0
- package/dashboard/dist/components/layout/Header.test.d.ts +1 -0
- package/dashboard/dist/components/layout/Header.test.js +35 -0
- package/dashboard/dist/components/layout/Shell.d.ts +10 -0
- package/dashboard/dist/components/layout/Shell.js +5 -0
- package/dashboard/dist/components/layout/Shell.test.d.ts +1 -0
- package/dashboard/dist/components/layout/Shell.test.js +34 -0
- package/dashboard/dist/components/layout/Sidebar.d.ts +14 -0
- package/dashboard/dist/components/layout/Sidebar.js +8 -0
- package/dashboard/dist/components/layout/Sidebar.test.d.ts +1 -0
- package/dashboard/dist/components/layout/Sidebar.test.js +40 -0
- package/dashboard/dist/components/ui/Badge.d.ts +9 -0
- package/dashboard/dist/components/ui/Badge.js +13 -0
- package/dashboard/dist/components/ui/Badge.test.d.ts +1 -0
- package/dashboard/dist/components/ui/Badge.test.js +69 -0
- package/dashboard/dist/components/ui/Button.d.ts +12 -0
- package/dashboard/dist/components/ui/Button.js +14 -0
- package/dashboard/dist/components/ui/Button.test.d.ts +1 -0
- package/dashboard/dist/components/ui/Button.test.js +81 -0
- package/dashboard/dist/components/ui/Card.d.ts +21 -0
- package/dashboard/dist/components/ui/Card.js +20 -0
- package/dashboard/dist/components/ui/Card.test.d.ts +1 -0
- package/dashboard/dist/components/ui/Card.test.js +82 -0
- package/dashboard/dist/components/ui/Input.d.ts +13 -0
- package/dashboard/dist/components/ui/Input.js +8 -0
- package/dashboard/dist/components/ui/Input.test.d.ts +1 -0
- package/dashboard/dist/components/ui/Input.test.js +68 -0
- package/dashboard/dist/styles/tokens.d.ts +150 -0
- package/dashboard/dist/styles/tokens.js +184 -0
- package/dashboard/dist/styles/tokens.test.d.ts +1 -0
- package/dashboard/dist/styles/tokens.test.js +95 -0
- package/dashboard/dist/test/setup.d.ts +1 -0
- package/dashboard/dist/test/setup.js +1 -0
- package/dashboard/package.json +3 -0
- package/package.json +15 -4
- package/scripts/capture-screenshots.js +170 -0
- package/scripts/docs-update.js +253 -0
- package/scripts/generate-screenshots.js +321 -0
- package/scripts/project-docs.js +377 -0
- package/scripts/vps-setup.sh +477 -0
- package/server/lib/adapters/base-adapter.js +114 -0
- package/server/lib/adapters/base-adapter.test.js +90 -0
- package/server/lib/adapters/claude-adapter.js +141 -0
- package/server/lib/adapters/claude-adapter.test.js +180 -0
- package/server/lib/adapters/deepseek-adapter.js +153 -0
- package/server/lib/adapters/deepseek-adapter.test.js +193 -0
- package/server/lib/adapters/openai-adapter.js +190 -0
- package/server/lib/adapters/openai-adapter.test.js +231 -0
- package/server/lib/budget-tracker.js +169 -0
- package/server/lib/budget-tracker.test.js +165 -0
- package/server/lib/claude-injector.js +85 -0
- package/server/lib/claude-injector.test.js +161 -0
- package/server/lib/consensus-engine.js +135 -0
- package/server/lib/consensus-engine.test.js +152 -0
- package/server/lib/context-builder.js +112 -0
- package/server/lib/context-builder.test.js +120 -0
- package/server/lib/file-collector.js +322 -0
- package/server/lib/file-collector.test.js +307 -0
- package/server/lib/memory-classifier.js +175 -0
- package/server/lib/memory-classifier.test.js +169 -0
- package/server/lib/memory-committer.js +138 -0
- package/server/lib/memory-committer.test.js +136 -0
- package/server/lib/memory-hooks.js +127 -0
- package/server/lib/memory-hooks.test.js +136 -0
- package/server/lib/memory-init.js +104 -0
- package/server/lib/memory-init.test.js +119 -0
- package/server/lib/memory-observer.js +149 -0
- package/server/lib/memory-observer.test.js +158 -0
- package/server/lib/memory-reader.js +243 -0
- package/server/lib/memory-reader.test.js +216 -0
- package/server/lib/memory-storage.js +120 -0
- package/server/lib/memory-storage.test.js +136 -0
- package/server/lib/memory-writer.js +176 -0
- package/server/lib/memory-writer.test.js +231 -0
- package/server/lib/overdrive-command.js +30 -6
- package/server/lib/overdrive-command.test.js +8 -1
- package/server/lib/pattern-detector.js +216 -0
- package/server/lib/pattern-detector.test.js +241 -0
- package/server/lib/relevance-scorer.js +175 -0
- package/server/lib/relevance-scorer.test.js +107 -0
- package/server/lib/review-command.js +238 -0
- package/server/lib/review-command.test.js +245 -0
- package/server/lib/review-orchestrator.js +273 -0
- package/server/lib/review-orchestrator.test.js +300 -0
- package/server/lib/review-reporter.js +288 -0
- package/server/lib/review-reporter.test.js +240 -0
- package/server/lib/session-summary.js +90 -0
- package/server/lib/session-summary.test.js +156 -0
- package/templates/docs-sync.yml +91 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Documentation maintenance script
|
|
4
|
+
*
|
|
5
|
+
* Automatically:
|
|
6
|
+
* - Updates version references in docs
|
|
7
|
+
* - Checks for missing command documentation
|
|
8
|
+
* - Validates internal links
|
|
9
|
+
* - Regenerates screenshots if needed
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* node scripts/docs-update.js # Full update
|
|
13
|
+
* node scripts/docs-update.js --check # Check only, no changes
|
|
14
|
+
* node scripts/docs-update.js --screenshots # Regenerate screenshots
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
|
|
20
|
+
const ROOT = path.join(__dirname, '..');
|
|
21
|
+
const DOCS_DIR = path.join(ROOT, 'docs/wiki');
|
|
22
|
+
const COMMANDS_DIR = path.join(ROOT, '.claude/commands/tlc');
|
|
23
|
+
const PACKAGE_JSON = path.join(ROOT, 'package.json');
|
|
24
|
+
|
|
25
|
+
const args = process.argv.slice(2);
|
|
26
|
+
const checkOnly = args.includes('--check');
|
|
27
|
+
const screenshotsOnly = args.includes('--screenshots');
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get current version from package.json
|
|
31
|
+
*/
|
|
32
|
+
function getVersion() {
|
|
33
|
+
const pkg = JSON.parse(fs.readFileSync(PACKAGE_JSON, 'utf-8'));
|
|
34
|
+
return pkg.version;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get all command files
|
|
39
|
+
*/
|
|
40
|
+
function getCommands() {
|
|
41
|
+
if (!fs.existsSync(COMMANDS_DIR)) return [];
|
|
42
|
+
|
|
43
|
+
return fs.readdirSync(COMMANDS_DIR)
|
|
44
|
+
.filter(f => f.endsWith('.md'))
|
|
45
|
+
.map(f => {
|
|
46
|
+
const content = fs.readFileSync(path.join(COMMANDS_DIR, f), 'utf-8');
|
|
47
|
+
const name = f.replace('.md', '');
|
|
48
|
+
const titleMatch = content.match(/^#\s+(.+)/m);
|
|
49
|
+
const title = titleMatch ? titleMatch[1] : name;
|
|
50
|
+
|
|
51
|
+
return { name, title, file: f };
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Check command-reference.md for missing commands
|
|
57
|
+
*/
|
|
58
|
+
function checkCommandDocs() {
|
|
59
|
+
const commandRefPath = path.join(DOCS_DIR, 'command-reference.md');
|
|
60
|
+
if (!fs.existsSync(commandRefPath)) {
|
|
61
|
+
console.log('⚠ command-reference.md not found');
|
|
62
|
+
return { missing: [], outdated: [] };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const content = fs.readFileSync(commandRefPath, 'utf-8');
|
|
66
|
+
const commands = getCommands();
|
|
67
|
+
|
|
68
|
+
const missing = commands.filter(cmd => {
|
|
69
|
+
const pattern = new RegExp(`/tlc:${cmd.name}[^a-z]`, 'i');
|
|
70
|
+
return !pattern.test(content) && cmd.name !== 'tlc';
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
return { missing, total: commands.length };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Update version references in docs
|
|
78
|
+
*/
|
|
79
|
+
function updateVersions() {
|
|
80
|
+
const version = getVersion();
|
|
81
|
+
const versionPattern = /v\d+\.\d+\.\d+/g;
|
|
82
|
+
|
|
83
|
+
let updated = 0;
|
|
84
|
+
|
|
85
|
+
const files = fs.readdirSync(DOCS_DIR)
|
|
86
|
+
.filter(f => f.endsWith('.md'));
|
|
87
|
+
|
|
88
|
+
for (const file of files) {
|
|
89
|
+
const filepath = path.join(DOCS_DIR, file);
|
|
90
|
+
let content = fs.readFileSync(filepath, 'utf-8');
|
|
91
|
+
|
|
92
|
+
const matches = content.match(versionPattern);
|
|
93
|
+
if (matches) {
|
|
94
|
+
const oldContent = content;
|
|
95
|
+
content = content.replace(versionPattern, `v${version}`);
|
|
96
|
+
|
|
97
|
+
if (content !== oldContent && !checkOnly) {
|
|
98
|
+
fs.writeFileSync(filepath, content);
|
|
99
|
+
updated++;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return updated;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Check for broken internal links
|
|
109
|
+
*/
|
|
110
|
+
function checkLinks() {
|
|
111
|
+
const broken = [];
|
|
112
|
+
|
|
113
|
+
const files = fs.readdirSync(DOCS_DIR)
|
|
114
|
+
.filter(f => f.endsWith('.md'));
|
|
115
|
+
|
|
116
|
+
const existingPages = files.map(f => f.replace('.md', ''));
|
|
117
|
+
|
|
118
|
+
for (const file of files) {
|
|
119
|
+
const filepath = path.join(DOCS_DIR, file);
|
|
120
|
+
const content = fs.readFileSync(filepath, 'utf-8');
|
|
121
|
+
|
|
122
|
+
// Find markdown links
|
|
123
|
+
const linkPattern = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
124
|
+
let match;
|
|
125
|
+
|
|
126
|
+
while ((match = linkPattern.exec(content)) !== null) {
|
|
127
|
+
const [, , link] = match;
|
|
128
|
+
|
|
129
|
+
// Check internal links (no http/https)
|
|
130
|
+
if (!link.startsWith('http') && !link.startsWith('#')) {
|
|
131
|
+
const targetPage = link.replace(/\.md$/, '').replace(/^\//, '');
|
|
132
|
+
|
|
133
|
+
if (!existingPages.includes(targetPage) &&
|
|
134
|
+
!fs.existsSync(path.join(DOCS_DIR, link)) &&
|
|
135
|
+
!link.startsWith('images/')) {
|
|
136
|
+
broken.push({ file, link });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return broken;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Check screenshots exist
|
|
147
|
+
*/
|
|
148
|
+
function checkScreenshots() {
|
|
149
|
+
const imagesDir = path.join(DOCS_DIR, 'images');
|
|
150
|
+
const missing = [];
|
|
151
|
+
|
|
152
|
+
if (!fs.existsSync(imagesDir)) {
|
|
153
|
+
return { missing: ['images directory not found'], existing: 0 };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const files = fs.readdirSync(DOCS_DIR)
|
|
157
|
+
.filter(f => f.endsWith('.md'));
|
|
158
|
+
|
|
159
|
+
const existingImages = fs.readdirSync(imagesDir)
|
|
160
|
+
.filter(f => f.endsWith('.png') || f.endsWith('.jpg'));
|
|
161
|
+
|
|
162
|
+
for (const file of files) {
|
|
163
|
+
const filepath = path.join(DOCS_DIR, file);
|
|
164
|
+
const content = fs.readFileSync(filepath, 'utf-8');
|
|
165
|
+
|
|
166
|
+
// Find image references
|
|
167
|
+
const imagePattern = /!\[([^\]]*)\]\(images\/([^)]+)\)/g;
|
|
168
|
+
let match;
|
|
169
|
+
|
|
170
|
+
while ((match = imagePattern.exec(content)) !== null) {
|
|
171
|
+
const [, , imagePath] = match;
|
|
172
|
+
if (!existingImages.includes(imagePath)) {
|
|
173
|
+
missing.push({ file, image: imagePath });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return { missing, existing: existingImages.length };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Main function
|
|
183
|
+
*/
|
|
184
|
+
async function main() {
|
|
185
|
+
console.log('TLC Documentation Maintenance\n');
|
|
186
|
+
console.log('═'.repeat(50));
|
|
187
|
+
|
|
188
|
+
const version = getVersion();
|
|
189
|
+
console.log(`\nVersion: ${version}`);
|
|
190
|
+
|
|
191
|
+
// Screenshots only mode
|
|
192
|
+
if (screenshotsOnly) {
|
|
193
|
+
console.log('\nRegenerating screenshots...');
|
|
194
|
+
require('./generate-screenshots.js');
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Check commands
|
|
199
|
+
console.log('\n📚 Commands');
|
|
200
|
+
const { missing, total } = checkCommandDocs();
|
|
201
|
+
console.log(` ${total} commands found`);
|
|
202
|
+
if (missing.length > 0) {
|
|
203
|
+
console.log(` ⚠ ${missing.length} missing from command-reference.md:`);
|
|
204
|
+
missing.forEach(cmd => console.log(` - /tlc:${cmd.name}`));
|
|
205
|
+
} else {
|
|
206
|
+
console.log(' ✓ All commands documented');
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Check versions
|
|
210
|
+
console.log('\n🏷️ Versions');
|
|
211
|
+
const updated = updateVersions();
|
|
212
|
+
if (checkOnly) {
|
|
213
|
+
console.log(` ${updated > 0 ? '⚠' : '✓'} ${updated} files need version update`);
|
|
214
|
+
} else {
|
|
215
|
+
console.log(` ✓ ${updated} files updated to v${version}`);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Check links
|
|
219
|
+
console.log('\n🔗 Links');
|
|
220
|
+
const brokenLinks = checkLinks();
|
|
221
|
+
if (brokenLinks.length > 0) {
|
|
222
|
+
console.log(` ⚠ ${brokenLinks.length} broken links:`);
|
|
223
|
+
brokenLinks.forEach(({ file, link }) => console.log(` ${file}: ${link}`));
|
|
224
|
+
} else {
|
|
225
|
+
console.log(' ✓ All internal links valid');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Check screenshots
|
|
229
|
+
console.log('\n📸 Screenshots');
|
|
230
|
+
const { missing: missingImages, existing } = checkScreenshots();
|
|
231
|
+
console.log(` ${existing} screenshots found`);
|
|
232
|
+
if (missingImages.length > 0) {
|
|
233
|
+
console.log(` ⚠ ${missingImages.length} missing screenshots:`);
|
|
234
|
+
missingImages.forEach(({ file, image }) => console.log(` ${file}: ${image}`));
|
|
235
|
+
} else {
|
|
236
|
+
console.log(' ✓ All referenced screenshots exist');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Summary
|
|
240
|
+
console.log('\n' + '═'.repeat(50));
|
|
241
|
+
|
|
242
|
+
const issues = missing.length + brokenLinks.length + missingImages.length;
|
|
243
|
+
if (issues > 0) {
|
|
244
|
+
console.log(`\n⚠ ${issues} issue(s) found`);
|
|
245
|
+
if (!checkOnly) {
|
|
246
|
+
console.log('Run with --check to see issues without making changes');
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
249
|
+
console.log('\n✓ Documentation is up to date!');
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Generate terminal-style screenshots for documentation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { generateSync } = require('text-to-image');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const OUTPUT_DIR = path.join(__dirname, '../docs/wiki/images');
|
|
11
|
+
|
|
12
|
+
// Terminal styling
|
|
13
|
+
const options = {
|
|
14
|
+
bgColor: '#1e1e1e',
|
|
15
|
+
textColor: '#d4d4d4',
|
|
16
|
+
fontFamily: 'Consolas, Monaco, monospace',
|
|
17
|
+
fontSize: 14,
|
|
18
|
+
lineHeight: 20,
|
|
19
|
+
margin: 20,
|
|
20
|
+
maxWidth: 700,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Screenshot definitions
|
|
24
|
+
const screenshots = {
|
|
25
|
+
'dashboard-overview': `
|
|
26
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
27
|
+
│ TLC Dashboard v1.2.28 │
|
|
28
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
29
|
+
│ │
|
|
30
|
+
│ Project: my-awesome-app │
|
|
31
|
+
│ Phase 2: User Authentication ████████░░ 80% │
|
|
32
|
+
│ │
|
|
33
|
+
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
|
34
|
+
│ │ Tasks │ │ Tests │ │ Coverage │ │
|
|
35
|
+
│ │ ██████████ 4/5 │ │ ✓ 47 passing │ │ 87% │ │
|
|
36
|
+
│ │ │ │ ✗ 2 failing │ │ ████████░░ │ │
|
|
37
|
+
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
|
|
38
|
+
│ │
|
|
39
|
+
│ Team: @alice (Task 3) @bob (Task 4) @charlie (available) │
|
|
40
|
+
│ │
|
|
41
|
+
│ [1] Tasks [2] Logs [3] Preview [4] Team [?] Help │
|
|
42
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
43
|
+
`,
|
|
44
|
+
|
|
45
|
+
'tlc-next-prompt': `
|
|
46
|
+
$ /tlc:next
|
|
47
|
+
|
|
48
|
+
Phase 2: User Authentication
|
|
49
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
50
|
+
|
|
51
|
+
Next: Build remaining 3 tasks (auto-parallel)
|
|
52
|
+
• Task 3: Session management
|
|
53
|
+
• Task 4: Password reset
|
|
54
|
+
• Task 5: OAuth integration
|
|
55
|
+
|
|
56
|
+
Proceed? [Y/n]: _
|
|
57
|
+
`,
|
|
58
|
+
|
|
59
|
+
'tlc-progress': `
|
|
60
|
+
$ /tlc:progress
|
|
61
|
+
|
|
62
|
+
my-awesome-app - Progress
|
|
63
|
+
═══════════════════════════════════════════════════════════════
|
|
64
|
+
|
|
65
|
+
Milestone: v1.0
|
|
66
|
+
Phase 2: User Authentication ████████░░ 80%
|
|
67
|
+
|
|
68
|
+
Tasks:
|
|
69
|
+
[x] 1. Create user schema @alice
|
|
70
|
+
[x] 2. Add validation @bob
|
|
71
|
+
[>] 3. Session management @alice (in progress)
|
|
72
|
+
[ ] 4. Password reset
|
|
73
|
+
[ ] 5. OAuth integration
|
|
74
|
+
|
|
75
|
+
Tests: 47 passing | 2 failing
|
|
76
|
+
Coverage: 87%
|
|
77
|
+
|
|
78
|
+
Next: Complete Task 3, then /tlc:build continues
|
|
79
|
+
`,
|
|
80
|
+
|
|
81
|
+
'build-parallel': `
|
|
82
|
+
$ /tlc:build 2
|
|
83
|
+
|
|
84
|
+
Analyzing task dependencies...
|
|
85
|
+
|
|
86
|
+
Independent tasks detected: 4
|
|
87
|
+
Starting parallel build with 4 agents...
|
|
88
|
+
|
|
89
|
+
Agent 1 ████████░░ Task 1: Create schema
|
|
90
|
+
Agent 2 ██████░░░░ Task 2: Add validation
|
|
91
|
+
Agent 3 ████░░░░░░ Task 3: Create endpoints
|
|
92
|
+
Agent 4 ██░░░░░░░░ Task 4: Error handling
|
|
93
|
+
|
|
94
|
+
Tests: 12 passing | 3 failing (in progress)
|
|
95
|
+
|
|
96
|
+
Agent 1 completed: Task 1 ✓
|
|
97
|
+
Agent 2 completed: Task 2 ✓
|
|
98
|
+
`,
|
|
99
|
+
|
|
100
|
+
'tlc-who': `
|
|
101
|
+
$ /tlc:who
|
|
102
|
+
|
|
103
|
+
Phase 2: User Authentication
|
|
104
|
+
═══════════════════════════════════════════════════════════════
|
|
105
|
+
|
|
106
|
+
Team Activity:
|
|
107
|
+
|
|
108
|
+
@alice
|
|
109
|
+
✓ Task 1: Create user schema (completed 2h ago)
|
|
110
|
+
→ Task 3: Session management (working now)
|
|
111
|
+
|
|
112
|
+
@bob
|
|
113
|
+
✓ Task 2: Add validation (completed 1h ago)
|
|
114
|
+
→ Task 4: Password reset (working now)
|
|
115
|
+
|
|
116
|
+
@charlie
|
|
117
|
+
No tasks claimed
|
|
118
|
+
|
|
119
|
+
Available Tasks:
|
|
120
|
+
[ ] Task 5: OAuth integration
|
|
121
|
+
|
|
122
|
+
Open Bugs: 1
|
|
123
|
+
BUG-012: Medium - Session expires too quickly
|
|
124
|
+
`,
|
|
125
|
+
|
|
126
|
+
'dashboard-tasks': `
|
|
127
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
128
|
+
│ Task Board Phase 2 │
|
|
129
|
+
├───────────────────┬───────────────────┬─────────────────────────┤
|
|
130
|
+
│ TODO │ IN PROGRESS │ DONE │
|
|
131
|
+
├───────────────────┼───────────────────┼─────────────────────────┤
|
|
132
|
+
│ │ │ │
|
|
133
|
+
│ ┌─────────────┐ │ ┌─────────────┐ │ ┌─────────────┐ │
|
|
134
|
+
│ │ Task 5 │ │ │ Task 3 │ │ │ Task 1 │ │
|
|
135
|
+
│ │ OAuth │ │ │ Sessions │ │ │ Schema │ │
|
|
136
|
+
│ │ │ │ │ @alice │ │ │ @alice ✓ │ │
|
|
137
|
+
│ └─────────────┘ │ ├─────────────┤ │ ├─────────────┤ │
|
|
138
|
+
│ │ │ Task 4 │ │ │ Task 2 │ │
|
|
139
|
+
│ │ │ Password │ │ │ Validation │ │
|
|
140
|
+
│ │ │ @bob │ │ │ @bob ✓ │ │
|
|
141
|
+
│ │ └─────────────┘ │ └─────────────┘ │
|
|
142
|
+
│ │ │ │
|
|
143
|
+
├───────────────────┴───────────────────┴─────────────────────────┤
|
|
144
|
+
│ [h/l] Move [j/k] Navigate [m] Move task [Enter] Details │
|
|
145
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
146
|
+
`,
|
|
147
|
+
|
|
148
|
+
'dashboard-logs': `
|
|
149
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
150
|
+
│ Log Stream [Auto-scroll ON] │
|
|
151
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
152
|
+
│ Filter: [All] [app] [test] [git] Search: _________ │
|
|
153
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
154
|
+
│ │
|
|
155
|
+
│ 14:32:01 [app] Server started on port 5001 │
|
|
156
|
+
│ 14:32:03 [app] Connected to database │
|
|
157
|
+
│ 14:32:15 [test] Running test suite... │
|
|
158
|
+
│ 14:32:16 [test] ✓ user.create returns 201 │
|
|
159
|
+
│ 14:32:16 [test] ✓ user.create validates email │
|
|
160
|
+
│ 14:32:17 [test] ✗ user.login handles expired session │
|
|
161
|
+
│ 14:32:18 [git] Commit: feat: add session management │
|
|
162
|
+
│ 14:32:20 [app] Request: POST /api/users │
|
|
163
|
+
│ 14:32:21 [app] Response: 201 Created (23ms) │
|
|
164
|
+
│ │
|
|
165
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
166
|
+
│ [/] Search [f] Filter [c] Clear [Space] Pause │
|
|
167
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
168
|
+
`,
|
|
169
|
+
|
|
170
|
+
'dashboard-team': `
|
|
171
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
172
|
+
│ Team │
|
|
173
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
174
|
+
│ │
|
|
175
|
+
│ Online │
|
|
176
|
+
│ ──────── │
|
|
177
|
+
│ ● @alice Task 3: Session management 2m ago │
|
|
178
|
+
│ ● @bob Task 4: Password reset 5m ago │
|
|
179
|
+
│ │
|
|
180
|
+
│ Away │
|
|
181
|
+
│ ──────── │
|
|
182
|
+
│ ○ @charlie No task claimed 1h ago │
|
|
183
|
+
│ │
|
|
184
|
+
│ Activity Feed │
|
|
185
|
+
│ ──────────── │
|
|
186
|
+
│ 14:30 @alice committed "add session middleware" │
|
|
187
|
+
│ 14:25 @bob claimed Task 4 │
|
|
188
|
+
│ 14:20 @alice completed Task 1 │
|
|
189
|
+
│ 14:15 @charlie released Task 3 │
|
|
190
|
+
│ │
|
|
191
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
192
|
+
`,
|
|
193
|
+
|
|
194
|
+
'test-first-red': `
|
|
195
|
+
$ npm test
|
|
196
|
+
|
|
197
|
+
User Authentication
|
|
198
|
+
✗ creates user with valid data
|
|
199
|
+
Expected: 201
|
|
200
|
+
Received: undefined
|
|
201
|
+
|
|
202
|
+
✗ rejects duplicate email
|
|
203
|
+
Error: Cannot read property 'status' of undefined
|
|
204
|
+
|
|
205
|
+
✗ hashes password before storing
|
|
206
|
+
Expected: password to be hashed
|
|
207
|
+
Received: undefined
|
|
208
|
+
|
|
209
|
+
3 failing (0 passing)
|
|
210
|
+
|
|
211
|
+
─────────────────────────────────────────────────────────────
|
|
212
|
+
RED PHASE: Tests written, implementation needed
|
|
213
|
+
─────────────────────────────────────────────────────────────
|
|
214
|
+
`,
|
|
215
|
+
|
|
216
|
+
'test-first-green': `
|
|
217
|
+
$ npm test
|
|
218
|
+
|
|
219
|
+
User Authentication
|
|
220
|
+
✓ creates user with valid data (12ms)
|
|
221
|
+
✓ rejects duplicate email (8ms)
|
|
222
|
+
✓ hashes password before storing (15ms)
|
|
223
|
+
✓ validates email format (3ms)
|
|
224
|
+
✓ requires password minimum length (2ms)
|
|
225
|
+
|
|
226
|
+
Session Management
|
|
227
|
+
✓ creates session on login (18ms)
|
|
228
|
+
✓ invalidates session on logout (5ms)
|
|
229
|
+
|
|
230
|
+
7 passing (63ms)
|
|
231
|
+
|
|
232
|
+
─────────────────────────────────────────────────────────────
|
|
233
|
+
GREEN PHASE: All tests passing ✓
|
|
234
|
+
─────────────────────────────────────────────────────────────
|
|
235
|
+
`,
|
|
236
|
+
|
|
237
|
+
'auto-review': `
|
|
238
|
+
$ /tlc:build 2 (auto-review)
|
|
239
|
+
|
|
240
|
+
═══════════════════════════════════════════════════════════════
|
|
241
|
+
Auto-Review Results
|
|
242
|
+
═══════════════════════════════════════════════════════════════
|
|
243
|
+
|
|
244
|
+
Test Coverage
|
|
245
|
+
src/auth/user.ts 94% ████████████████████░░
|
|
246
|
+
src/auth/session.ts 88% ██████████████████░░░░
|
|
247
|
+
src/auth/password.ts 100% ██████████████████████
|
|
248
|
+
|
|
249
|
+
TDD Compliance
|
|
250
|
+
✓ Tests committed before implementation
|
|
251
|
+
✓ All new code has corresponding tests
|
|
252
|
+
✓ No untested functions added
|
|
253
|
+
|
|
254
|
+
Security Check
|
|
255
|
+
✓ No hardcoded secrets
|
|
256
|
+
✓ Passwords properly hashed
|
|
257
|
+
✓ SQL injection protection
|
|
258
|
+
|
|
259
|
+
Quality Score: 92/100
|
|
260
|
+
|
|
261
|
+
Verdict: ✓ APPROVED
|
|
262
|
+
═══════════════════════════════════════════════════════════════
|
|
263
|
+
`,
|
|
264
|
+
|
|
265
|
+
'new-project-wizard': `
|
|
266
|
+
$ /tlc:new-project
|
|
267
|
+
|
|
268
|
+
═══════════════════════════════════════════════════════════════
|
|
269
|
+
TLC New Project Setup
|
|
270
|
+
═══════════════════════════════════════════════════════════════
|
|
271
|
+
|
|
272
|
+
What are you building?
|
|
273
|
+
> A task management API with user authentication
|
|
274
|
+
|
|
275
|
+
Who will use it?
|
|
276
|
+
> Development team for internal project tracking
|
|
277
|
+
|
|
278
|
+
Tech stack preferences?
|
|
279
|
+
[x] Node.js + Express
|
|
280
|
+
[ ] Python + FastAPI
|
|
281
|
+
[ ] Go + Gin
|
|
282
|
+
[ ] Other
|
|
283
|
+
|
|
284
|
+
Test framework?
|
|
285
|
+
[x] Vitest (recommended)
|
|
286
|
+
[ ] Jest
|
|
287
|
+
[ ] Mocha
|
|
288
|
+
|
|
289
|
+
Creating project structure...
|
|
290
|
+
✓ PROJECT.md
|
|
291
|
+
✓ .planning/ROADMAP.md
|
|
292
|
+
✓ .tlc.json
|
|
293
|
+
✓ package.json
|
|
294
|
+
|
|
295
|
+
Project ready! Run /tlc:next to begin.
|
|
296
|
+
`,
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// Ensure output directory exists
|
|
300
|
+
if (!fs.existsSync(OUTPUT_DIR)) {
|
|
301
|
+
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Generate each screenshot
|
|
305
|
+
console.log('Generating screenshots...\n');
|
|
306
|
+
|
|
307
|
+
for (const [name, content] of Object.entries(screenshots)) {
|
|
308
|
+
const filename = `${name}.png`;
|
|
309
|
+
const filepath = path.join(OUTPUT_DIR, filename);
|
|
310
|
+
|
|
311
|
+
try {
|
|
312
|
+
const dataUri = generateSync(content.trim(), options);
|
|
313
|
+
const base64Data = dataUri.replace(/^data:image\/png;base64,/, '');
|
|
314
|
+
fs.writeFileSync(filepath, Buffer.from(base64Data, 'base64'));
|
|
315
|
+
console.log(` ✓ ${filename}`);
|
|
316
|
+
} catch (err) {
|
|
317
|
+
console.log(` ✗ ${filename}: ${err.message}`);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
console.log('\nDone! Screenshots saved to docs/wiki/images/');
|