tlc-claude-code 1.4.4 → 1.4.6
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/dashboard/dist/App.js +28 -2
- package/dashboard/dist/api/health-diagnostics.d.ts +26 -0
- package/dashboard/dist/api/health-diagnostics.js +85 -0
- package/dashboard/dist/api/health-diagnostics.test.d.ts +1 -0
- package/dashboard/dist/api/health-diagnostics.test.js +126 -0
- package/dashboard/dist/api/index.d.ts +5 -0
- package/dashboard/dist/api/index.js +5 -0
- package/dashboard/dist/api/notes-api.d.ts +18 -0
- package/dashboard/dist/api/notes-api.js +68 -0
- package/dashboard/dist/api/notes-api.test.d.ts +1 -0
- package/dashboard/dist/api/notes-api.test.js +113 -0
- package/dashboard/dist/api/safeFetch.d.ts +50 -0
- package/dashboard/dist/api/safeFetch.js +135 -0
- package/dashboard/dist/api/safeFetch.test.d.ts +1 -0
- package/dashboard/dist/api/safeFetch.test.js +215 -0
- package/dashboard/dist/api/tasks-api.d.ts +32 -0
- package/dashboard/dist/api/tasks-api.js +98 -0
- package/dashboard/dist/api/tasks-api.test.d.ts +1 -0
- package/dashboard/dist/api/tasks-api.test.js +383 -0
- package/dashboard/dist/components/BugsPane.d.ts +20 -0
- package/dashboard/dist/components/BugsPane.js +210 -0
- package/dashboard/dist/components/BugsPane.test.d.ts +1 -0
- package/dashboard/dist/components/BugsPane.test.js +256 -0
- package/dashboard/dist/components/HealthPane.d.ts +3 -1
- package/dashboard/dist/components/HealthPane.js +44 -6
- package/dashboard/dist/components/HealthPane.test.js +105 -2
- package/dashboard/dist/components/RouterPane.d.ts +4 -3
- package/dashboard/dist/components/RouterPane.js +60 -57
- package/dashboard/dist/components/RouterPane.test.js +150 -96
- package/dashboard/dist/components/UpdateBanner.d.ts +26 -0
- package/dashboard/dist/components/UpdateBanner.js +30 -0
- package/dashboard/dist/components/UpdateBanner.test.d.ts +1 -0
- package/dashboard/dist/components/UpdateBanner.test.js +96 -0
- package/dashboard/dist/components/ui/EmptyState.d.ts +14 -0
- package/dashboard/dist/components/ui/EmptyState.js +58 -0
- package/dashboard/dist/components/ui/EmptyState.test.d.ts +1 -0
- package/dashboard/dist/components/ui/EmptyState.test.js +97 -0
- package/dashboard/dist/components/ui/ErrorState.d.ts +17 -0
- package/dashboard/dist/components/ui/ErrorState.js +80 -0
- package/dashboard/dist/components/ui/ErrorState.test.d.ts +1 -0
- package/dashboard/dist/components/ui/ErrorState.test.js +166 -0
- package/dashboard/package.json +3 -0
- package/package.json +4 -1
- package/server/dashboard/index.html +284 -13
- package/server/dashboard/login.html +262 -0
- package/server/index.js +304 -0
- package/server/lib/api-provider.js +104 -186
- package/server/lib/api-provider.test.js +238 -336
- package/server/lib/cli-detector.js +90 -166
- package/server/lib/cli-detector.test.js +114 -269
- package/server/lib/cli-provider.js +142 -212
- package/server/lib/cli-provider.test.js +196 -349
- package/server/lib/debug.test.js +3 -3
- package/server/lib/devserver-router-api.js +54 -249
- package/server/lib/devserver-router-api.test.js +126 -426
- package/server/lib/introspect.js +309 -0
- package/server/lib/introspect.test.js +286 -0
- package/server/lib/model-router.js +107 -245
- package/server/lib/model-router.test.js +122 -313
- package/server/lib/output-schemas.js +146 -269
- package/server/lib/output-schemas.test.js +106 -307
- package/server/lib/plan-parser.js +59 -16
- package/server/lib/provider-interface.js +99 -153
- package/server/lib/provider-interface.test.js +228 -394
- package/server/lib/provider-queue.js +164 -158
- package/server/lib/provider-queue.test.js +186 -315
- package/server/lib/router-config.js +99 -221
- package/server/lib/router-config.test.js +83 -237
- package/server/lib/router-setup-command.js +94 -419
- package/server/lib/router-setup-command.test.js +96 -375
- package/server/lib/router-status-api.js +93 -0
- package/server/lib/router-status-api.test.js +270 -0
|
@@ -1,249 +1,54 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Devserver Router API - HTTP
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
res.json({ taskId });
|
|
58
|
-
} catch (err) {
|
|
59
|
-
res.status(500).json({ error: err.message });
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Handle GET /api/task/:taskId - Get task status
|
|
66
|
-
* @param {Object} queue - Queue instance
|
|
67
|
-
* @returns {Function} Express handler
|
|
68
|
-
*/
|
|
69
|
-
export function handleTaskStatus(queue) {
|
|
70
|
-
return async (req, res) => {
|
|
71
|
-
try {
|
|
72
|
-
const { taskId } = req.params;
|
|
73
|
-
const task = queue.getTask(taskId);
|
|
74
|
-
|
|
75
|
-
if (!task) {
|
|
76
|
-
return res.status(404).json({ error: 'Task not found' });
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
res.json({
|
|
80
|
-
status: task.status,
|
|
81
|
-
result: task.result,
|
|
82
|
-
error: task.error,
|
|
83
|
-
createdAt: task.createdAt,
|
|
84
|
-
completedAt: task.completedAt,
|
|
85
|
-
});
|
|
86
|
-
} catch (err) {
|
|
87
|
-
res.status(500).json({ error: err.message });
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Handle POST /api/review - Multi-model review
|
|
94
|
-
* @param {Object} router - Router instance
|
|
95
|
-
* @returns {Function} Express handler
|
|
96
|
-
*/
|
|
97
|
-
export function handleReview(router) {
|
|
98
|
-
return async (req, res) => {
|
|
99
|
-
try {
|
|
100
|
-
const { code, prompt = 'Review this code', options = {} } = req.body;
|
|
101
|
-
|
|
102
|
-
const fullPrompt = code ? `${prompt}\n\n\`\`\`\n${code}\n\`\`\`` : prompt;
|
|
103
|
-
|
|
104
|
-
const results = await router.run('review', fullPrompt, options);
|
|
105
|
-
|
|
106
|
-
// Calculate consensus
|
|
107
|
-
const consensus = calculateConsensus(results);
|
|
108
|
-
|
|
109
|
-
res.json({
|
|
110
|
-
consensus,
|
|
111
|
-
results,
|
|
112
|
-
});
|
|
113
|
-
} catch (err) {
|
|
114
|
-
res.status(500).json({ error: err.message });
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Handle POST /api/design - Design generation
|
|
121
|
-
* @param {Object} router - Router instance
|
|
122
|
-
* @returns {Function} Express handler
|
|
123
|
-
*/
|
|
124
|
-
export function handleDesign(router) {
|
|
125
|
-
return async (req, res) => {
|
|
126
|
-
try {
|
|
127
|
-
const { prompt, options = {} } = req.body;
|
|
128
|
-
|
|
129
|
-
const results = await router.run('design', prompt, options);
|
|
130
|
-
|
|
131
|
-
// Return first successful result
|
|
132
|
-
const successful = results.find((r) => r.success);
|
|
133
|
-
|
|
134
|
-
res.json({
|
|
135
|
-
result: successful?.result || null,
|
|
136
|
-
provider: successful?.provider,
|
|
137
|
-
error: successful ? null : 'No successful design generated',
|
|
138
|
-
});
|
|
139
|
-
} catch (err) {
|
|
140
|
-
res.status(500).json({ error: err.message });
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Handle GET /api/health - Provider health
|
|
147
|
-
* @param {Object} router - Router instance
|
|
148
|
-
* @returns {Function} Express handler
|
|
149
|
-
*/
|
|
150
|
-
export function handleHealth(router) {
|
|
151
|
-
return async (req, res) => {
|
|
152
|
-
try {
|
|
153
|
-
const status = router.getStatus();
|
|
154
|
-
|
|
155
|
-
// Check if at least one provider is available
|
|
156
|
-
const hasAvailable = Object.values(status.providers || {}).some(
|
|
157
|
-
(p) => p.detected || p.type === 'api'
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
res.json({
|
|
161
|
-
healthy: hasAvailable,
|
|
162
|
-
providers: status.providers,
|
|
163
|
-
devserver: status.devserver,
|
|
164
|
-
});
|
|
165
|
-
} catch (err) {
|
|
166
|
-
res.status(500).json({ error: err.message, healthy: false });
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Authentication middleware
|
|
173
|
-
* @param {string} secret - Expected secret
|
|
174
|
-
* @returns {Function} Express middleware
|
|
175
|
-
*/
|
|
176
|
-
export function validateAuth(secret) {
|
|
177
|
-
return (req, res, next) => {
|
|
178
|
-
const authHeader = req.headers.authorization;
|
|
179
|
-
|
|
180
|
-
if (!authHeader) {
|
|
181
|
-
return res.status(401).json({ error: 'Authorization header required' });
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const token = authHeader.replace('Bearer ', '');
|
|
185
|
-
|
|
186
|
-
if (token !== secret) {
|
|
187
|
-
return res.status(401).json({ error: 'Invalid authorization token' });
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
next();
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Request body validation middleware
|
|
196
|
-
* @param {string[]} requiredFields - Required field names
|
|
197
|
-
* @returns {Function} Express middleware
|
|
198
|
-
*/
|
|
199
|
-
export function validateRequestBody(requiredFields) {
|
|
200
|
-
return (req, res, next) => {
|
|
201
|
-
const body = req.body || {};
|
|
202
|
-
const missing = requiredFields.filter((field) => !body[field]);
|
|
203
|
-
|
|
204
|
-
if (missing.length > 0) {
|
|
205
|
-
return res.status(400).json({
|
|
206
|
-
error: `Missing required fields: ${missing.join(', ')}`,
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
next();
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Calculate consensus from multiple provider results
|
|
216
|
-
* @param {Object[]} results - Provider results
|
|
217
|
-
* @returns {Object} Consensus result
|
|
218
|
-
*/
|
|
219
|
-
function calculateConsensus(results) {
|
|
220
|
-
const successful = results.filter((r) => r.success);
|
|
221
|
-
|
|
222
|
-
if (successful.length === 0) {
|
|
223
|
-
return { approved: false, reason: 'No successful reviews' };
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// Count approvals
|
|
227
|
-
const approvals = successful.filter((r) => r.result?.approved).length;
|
|
228
|
-
const total = successful.length;
|
|
229
|
-
|
|
230
|
-
// Majority vote
|
|
231
|
-
const approved = approvals > total / 2;
|
|
232
|
-
|
|
233
|
-
// Average score if available
|
|
234
|
-
const scores = successful
|
|
235
|
-
.map((r) => r.result?.score)
|
|
236
|
-
.filter((s) => typeof s === 'number');
|
|
237
|
-
|
|
238
|
-
const averageScore =
|
|
239
|
-
scores.length > 0
|
|
240
|
-
? Math.round(scores.reduce((a, b) => a + b, 0) / scores.length)
|
|
241
|
-
: null;
|
|
242
|
-
|
|
243
|
-
return {
|
|
244
|
-
approved,
|
|
245
|
-
votes: { approve: approvals, reject: total - approvals },
|
|
246
|
-
averageScore,
|
|
247
|
-
providers: successful.map((r) => r.provider),
|
|
248
|
-
};
|
|
249
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Devserver Router API - HTTP API for devserver task execution
|
|
3
|
+
* Phase 33, Task 7
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export async function handleRun(req, res, ctx = {}) {
|
|
7
|
+
if (ctx.requireAuth && !req.headers?.authorization) {
|
|
8
|
+
return res.status(401).json({ error: 'Unauthorized' });
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const { provider, prompt } = req.body || {};
|
|
12
|
+
if (!provider || !prompt) {
|
|
13
|
+
return res.status(400).json({ error: 'provider and prompt required' });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const taskId = ctx.queue?.enqueue({ provider, prompt }) || 'task-' + Date.now();
|
|
17
|
+
res.json({ taskId });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function handleTask(req, res, ctx = {}) {
|
|
21
|
+
const { taskId } = req.params;
|
|
22
|
+
const task = ctx.queue?.getTask(taskId) || { status: 'unknown' };
|
|
23
|
+
res.json(task);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function handleReview(req, res, ctx = {}) {
|
|
27
|
+
const { code } = req.body;
|
|
28
|
+
const providers = ctx.providers || ['claude'];
|
|
29
|
+
const results = [];
|
|
30
|
+
|
|
31
|
+
for (const provider of providers) {
|
|
32
|
+
const result = await ctx.runProvider(provider, { prompt: 'Review: ' + code });
|
|
33
|
+
results.push(result.parsed);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const scores = results.map(r => r?.score || 0);
|
|
37
|
+
const avgScore = scores.reduce((a, b) => a + b, 0) / scores.length;
|
|
38
|
+
const approved = results.filter(r => r?.approved).length > results.length / 2;
|
|
39
|
+
|
|
40
|
+
res.json({ results, consensus: { score: avgScore, approved } });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function handleDesign(req, res, ctx = {}) {
|
|
44
|
+
const { description } = req.body;
|
|
45
|
+
const result = await ctx.runProvider('gemini', { prompt: 'Design: ' + description });
|
|
46
|
+
res.json(result.parsed || {});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function handleHealth(req, res, ctx = {}) {
|
|
50
|
+
const providers = ctx.getProviderStatus?.() || {};
|
|
51
|
+
res.json({ status: 'ok', providers });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default { handleRun, handleTask, handleReview, handleDesign, handleHealth };
|