tlc-claude-code 1.4.2 → 1.4.5

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.
Files changed (113) hide show
  1. package/dashboard/dist/App.js +28 -2
  2. package/dashboard/dist/api/health-diagnostics.d.ts +26 -0
  3. package/dashboard/dist/api/health-diagnostics.js +85 -0
  4. package/dashboard/dist/api/health-diagnostics.test.d.ts +1 -0
  5. package/dashboard/dist/api/health-diagnostics.test.js +126 -0
  6. package/dashboard/dist/api/index.d.ts +5 -0
  7. package/dashboard/dist/api/index.js +5 -0
  8. package/dashboard/dist/api/notes-api.d.ts +18 -0
  9. package/dashboard/dist/api/notes-api.js +68 -0
  10. package/dashboard/dist/api/notes-api.test.d.ts +1 -0
  11. package/dashboard/dist/api/notes-api.test.js +113 -0
  12. package/dashboard/dist/api/safeFetch.d.ts +50 -0
  13. package/dashboard/dist/api/safeFetch.js +135 -0
  14. package/dashboard/dist/api/safeFetch.test.d.ts +1 -0
  15. package/dashboard/dist/api/safeFetch.test.js +215 -0
  16. package/dashboard/dist/api/tasks-api.d.ts +32 -0
  17. package/dashboard/dist/api/tasks-api.js +98 -0
  18. package/dashboard/dist/api/tasks-api.test.d.ts +1 -0
  19. package/dashboard/dist/api/tasks-api.test.js +383 -0
  20. package/dashboard/dist/components/BugsPane.d.ts +20 -0
  21. package/dashboard/dist/components/BugsPane.js +210 -0
  22. package/dashboard/dist/components/BugsPane.test.d.ts +1 -0
  23. package/dashboard/dist/components/BugsPane.test.js +256 -0
  24. package/dashboard/dist/components/HealthPane.d.ts +3 -1
  25. package/dashboard/dist/components/HealthPane.js +44 -6
  26. package/dashboard/dist/components/HealthPane.test.js +105 -2
  27. package/dashboard/dist/components/RouterPane.d.ts +4 -3
  28. package/dashboard/dist/components/RouterPane.js +60 -57
  29. package/dashboard/dist/components/RouterPane.test.js +150 -96
  30. package/dashboard/dist/components/UpdateBanner.d.ts +26 -0
  31. package/dashboard/dist/components/UpdateBanner.js +30 -0
  32. package/dashboard/dist/components/UpdateBanner.test.d.ts +1 -0
  33. package/dashboard/dist/components/UpdateBanner.test.js +96 -0
  34. package/dashboard/dist/components/accessibility.test.d.ts +1 -0
  35. package/dashboard/dist/components/accessibility.test.js +116 -0
  36. package/dashboard/dist/components/layout/MobileNav.d.ts +16 -0
  37. package/dashboard/dist/components/layout/MobileNav.js +31 -0
  38. package/dashboard/dist/components/layout/MobileNav.test.d.ts +1 -0
  39. package/dashboard/dist/components/layout/MobileNav.test.js +111 -0
  40. package/dashboard/dist/components/performance.test.d.ts +1 -0
  41. package/dashboard/dist/components/performance.test.js +114 -0
  42. package/dashboard/dist/components/responsive.test.d.ts +1 -0
  43. package/dashboard/dist/components/responsive.test.js +114 -0
  44. package/dashboard/dist/components/ui/Dropdown.d.ts +22 -0
  45. package/dashboard/dist/components/ui/Dropdown.js +109 -0
  46. package/dashboard/dist/components/ui/Dropdown.test.d.ts +1 -0
  47. package/dashboard/dist/components/ui/Dropdown.test.js +105 -0
  48. package/dashboard/dist/components/ui/EmptyState.d.ts +14 -0
  49. package/dashboard/dist/components/ui/EmptyState.js +58 -0
  50. package/dashboard/dist/components/ui/EmptyState.test.d.ts +1 -0
  51. package/dashboard/dist/components/ui/EmptyState.test.js +97 -0
  52. package/dashboard/dist/components/ui/ErrorState.d.ts +17 -0
  53. package/dashboard/dist/components/ui/ErrorState.js +80 -0
  54. package/dashboard/dist/components/ui/ErrorState.test.d.ts +1 -0
  55. package/dashboard/dist/components/ui/ErrorState.test.js +166 -0
  56. package/dashboard/dist/components/ui/Modal.d.ts +13 -0
  57. package/dashboard/dist/components/ui/Modal.js +25 -0
  58. package/dashboard/dist/components/ui/Modal.test.d.ts +1 -0
  59. package/dashboard/dist/components/ui/Modal.test.js +91 -0
  60. package/dashboard/dist/components/ui/Skeleton.d.ts +32 -0
  61. package/dashboard/dist/components/ui/Skeleton.js +48 -0
  62. package/dashboard/dist/components/ui/Skeleton.test.d.ts +1 -0
  63. package/dashboard/dist/components/ui/Skeleton.test.js +125 -0
  64. package/dashboard/dist/components/ui/Toast.d.ts +32 -0
  65. package/dashboard/dist/components/ui/Toast.js +21 -0
  66. package/dashboard/dist/components/ui/Toast.test.d.ts +1 -0
  67. package/dashboard/dist/components/ui/Toast.test.js +118 -0
  68. package/dashboard/dist/hooks/useTheme.d.ts +37 -0
  69. package/dashboard/dist/hooks/useTheme.js +96 -0
  70. package/dashboard/dist/hooks/useTheme.test.d.ts +1 -0
  71. package/dashboard/dist/hooks/useTheme.test.js +94 -0
  72. package/dashboard/dist/hooks/useWebSocket.d.ts +17 -0
  73. package/dashboard/dist/hooks/useWebSocket.js +100 -0
  74. package/dashboard/dist/hooks/useWebSocket.test.d.ts +1 -0
  75. package/dashboard/dist/hooks/useWebSocket.test.js +115 -0
  76. package/dashboard/dist/stores/projectStore.d.ts +44 -0
  77. package/dashboard/dist/stores/projectStore.js +76 -0
  78. package/dashboard/dist/stores/projectStore.test.d.ts +1 -0
  79. package/dashboard/dist/stores/projectStore.test.js +114 -0
  80. package/dashboard/dist/stores/uiStore.d.ts +29 -0
  81. package/dashboard/dist/stores/uiStore.js +72 -0
  82. package/dashboard/dist/stores/uiStore.test.d.ts +1 -0
  83. package/dashboard/dist/stores/uiStore.test.js +93 -0
  84. package/dashboard/package.json +6 -3
  85. package/docker-compose.dev.yml +6 -1
  86. package/package.json +1 -1
  87. package/server/dashboard/index.html +1545 -791
  88. package/server/index.js +64 -0
  89. package/server/lib/api-provider.js +104 -186
  90. package/server/lib/api-provider.test.js +238 -336
  91. package/server/lib/cli-detector.js +90 -166
  92. package/server/lib/cli-detector.test.js +114 -269
  93. package/server/lib/cli-provider.js +142 -212
  94. package/server/lib/cli-provider.test.js +196 -349
  95. package/server/lib/debug.test.js +1 -1
  96. package/server/lib/devserver-router-api.js +54 -249
  97. package/server/lib/devserver-router-api.test.js +126 -426
  98. package/server/lib/introspect.js +309 -0
  99. package/server/lib/introspect.test.js +286 -0
  100. package/server/lib/model-router.js +107 -245
  101. package/server/lib/model-router.test.js +122 -313
  102. package/server/lib/output-schemas.js +146 -269
  103. package/server/lib/output-schemas.test.js +106 -307
  104. package/server/lib/provider-interface.js +99 -153
  105. package/server/lib/provider-interface.test.js +228 -394
  106. package/server/lib/provider-queue.js +164 -158
  107. package/server/lib/provider-queue.test.js +186 -315
  108. package/server/lib/router-config.js +99 -221
  109. package/server/lib/router-config.test.js +83 -237
  110. package/server/lib/router-setup-command.js +94 -419
  111. package/server/lib/router-setup-command.test.js +96 -375
  112. package/server/lib/router-status-api.js +93 -0
  113. package/server/lib/router-status-api.test.js +270 -0
@@ -1,269 +1,146 @@
1
- /**
2
- * Output Schemas - Standard JSON schemas for provider outputs
3
- *
4
- * Ensures consistent output format across all providers.
5
- */
6
-
7
- import fs from 'fs/promises';
8
-
9
- /**
10
- * Built-in schemas for common operations
11
- */
12
- export const BUILTIN_SCHEMAS = {
13
- 'review-result': {
14
- type: 'object',
15
- properties: {
16
- summary: { type: 'string', description: 'Brief summary of the review' },
17
- issues: {
18
- type: 'array',
19
- items: {
20
- type: 'object',
21
- properties: {
22
- severity: {
23
- type: 'string',
24
- enum: ['critical', 'moderate', 'suggestion'],
25
- description: 'Issue severity level',
26
- },
27
- file: { type: 'string', description: 'File path' },
28
- line: { type: 'integer', description: 'Line number' },
29
- title: { type: 'string', description: 'Issue title' },
30
- description: { type: 'string', description: 'Detailed description' },
31
- suggestion: { type: 'string', description: 'Suggested fix' },
32
- },
33
- required: ['severity', 'file', 'title', 'description'],
34
- },
35
- },
36
- score: {
37
- type: 'integer',
38
- minimum: 0,
39
- maximum: 100,
40
- description: 'Overall code quality score',
41
- },
42
- approved: { type: 'boolean', description: 'Whether the code is approved' },
43
- },
44
- required: ['summary', 'issues', 'score', 'approved'],
45
- },
46
-
47
- 'design-result': {
48
- type: 'object',
49
- properties: {
50
- mockups: {
51
- type: 'array',
52
- items: {
53
- type: 'object',
54
- properties: {
55
- name: { type: 'string', description: 'Mockup name' },
56
- description: { type: 'string', description: 'Mockup description' },
57
- imageUrl: { type: 'string', description: 'Generated image URL' },
58
- components: {
59
- type: 'array',
60
- items: { type: 'string' },
61
- description: 'UI components used',
62
- },
63
- },
64
- required: ['name', 'description'],
65
- },
66
- },
67
- rationale: { type: 'string', description: 'Design rationale' },
68
- alternatives: {
69
- type: 'array',
70
- items: {
71
- type: 'object',
72
- properties: {
73
- name: { type: 'string' },
74
- description: { type: 'string' },
75
- tradeoffs: { type: 'string' },
76
- },
77
- },
78
- description: 'Alternative design approaches',
79
- },
80
- },
81
- required: ['mockups', 'rationale'],
82
- },
83
-
84
- 'code-result': {
85
- type: 'object',
86
- properties: {
87
- files: {
88
- type: 'array',
89
- items: {
90
- type: 'object',
91
- properties: {
92
- path: { type: 'string', description: 'File path' },
93
- content: { type: 'string', description: 'File content' },
94
- action: {
95
- type: 'string',
96
- enum: ['create', 'modify', 'delete'],
97
- description: 'Action to take',
98
- },
99
- },
100
- required: ['path', 'content', 'action'],
101
- },
102
- },
103
- explanation: { type: 'string', description: 'Explanation of changes' },
104
- tests: {
105
- type: 'array',
106
- items: {
107
- type: 'object',
108
- properties: {
109
- name: { type: 'string' },
110
- description: { type: 'string' },
111
- },
112
- },
113
- description: 'Suggested tests',
114
- },
115
- },
116
- required: ['files', 'explanation'],
117
- },
118
- };
119
-
120
- /**
121
- * Load a schema from file
122
- * @param {string} filePath - Path to schema file
123
- * @returns {Promise<Object>} Parsed schema
124
- */
125
- export async function loadSchema(filePath) {
126
- const content = await fs.readFile(filePath, 'utf8');
127
- return JSON.parse(content);
128
- }
129
-
130
- /**
131
- * Validate output against a schema
132
- * @param {any} data - Data to validate
133
- * @param {Object} schema - JSON schema
134
- * @returns {Object} Validation result { valid, errors }
135
- */
136
- export function validateOutput(data, schema) {
137
- const errors = [];
138
-
139
- function validate(value, schemaNode, path = '') {
140
- if (!schemaNode) return;
141
-
142
- // Type validation
143
- if (schemaNode.type) {
144
- const actualType = Array.isArray(value) ? 'array' : typeof value;
145
- const expectedType = schemaNode.type;
146
-
147
- // Handle integer as number
148
- if (expectedType === 'integer') {
149
- if (typeof value !== 'number' || !Number.isInteger(value)) {
150
- errors.push(`${path}: expected integer, got ${actualType}`);
151
- return;
152
- }
153
- } else if (expectedType !== actualType) {
154
- errors.push(`${path}: expected ${expectedType}, got ${actualType}`);
155
- return;
156
- }
157
- }
158
-
159
- // Enum validation
160
- if (schemaNode.enum && !schemaNode.enum.includes(value)) {
161
- errors.push(`${path}: value must be one of: ${schemaNode.enum.join(', ')}`);
162
- }
163
-
164
- // Number constraints
165
- if (typeof value === 'number') {
166
- if (schemaNode.minimum !== undefined && value < schemaNode.minimum) {
167
- errors.push(`${path}: value must be >= ${schemaNode.minimum}`);
168
- }
169
- if (schemaNode.maximum !== undefined && value > schemaNode.maximum) {
170
- errors.push(`${path}: value must be <= ${schemaNode.maximum}`);
171
- }
172
- }
173
-
174
- // Object validation
175
- if (schemaNode.type === 'object' && typeof value === 'object' && value !== null) {
176
- // Required fields
177
- if (schemaNode.required) {
178
- for (const field of schemaNode.required) {
179
- if (!(field in value)) {
180
- errors.push(`${path}.${field}: required field missing`);
181
- }
182
- }
183
- }
184
-
185
- // Validate properties
186
- if (schemaNode.properties) {
187
- for (const [key, propSchema] of Object.entries(schemaNode.properties)) {
188
- if (key in value) {
189
- validate(value[key], propSchema, `${path}.${key}`);
190
- }
191
- }
192
- }
193
- }
194
-
195
- // Array validation
196
- if (schemaNode.type === 'array' && Array.isArray(value)) {
197
- if (schemaNode.items) {
198
- value.forEach((item, index) => {
199
- validate(item, schemaNode.items, `${path}[${index}]`);
200
- });
201
- }
202
- }
203
- }
204
-
205
- validate(data, schema, 'root');
206
-
207
- return {
208
- valid: errors.length === 0,
209
- errors,
210
- };
211
- }
212
-
213
- /**
214
- * Convert schema to human-readable prompt instructions
215
- * @param {Object} schema - JSON schema
216
- * @returns {string} Text instructions
217
- */
218
- export function schemaToPromptInstructions(schema) {
219
- const lines = ['Your response must be valid JSON matching this structure:'];
220
-
221
- function describeSchema(node, indent = 0) {
222
- const prefix = ' '.repeat(indent);
223
-
224
- if (node.type === 'object' && node.properties) {
225
- lines.push(`${prefix}{`);
226
-
227
- for (const [key, prop] of Object.entries(node.properties)) {
228
- const required = node.required?.includes(key) ? ' (required)' : '';
229
- const type = prop.type || 'any';
230
-
231
- if (prop.enum) {
232
- lines.push(`${prefix} "${key}": one of [${prop.enum.join(', ')}]${required}`);
233
- } else if (type === 'object' && prop.properties) {
234
- lines.push(`${prefix} "${key}": {${required}`);
235
- describeSchema(prop, indent + 2);
236
- lines.push(`${prefix} }`);
237
- } else if (type === 'array') {
238
- lines.push(`${prefix} "${key}": array of ${prop.items?.type || 'items'}${required}`);
239
- } else {
240
- lines.push(`${prefix} "${key}": ${type}${required}`);
241
- }
242
- }
243
-
244
- lines.push(`${prefix}}`);
245
- }
246
- }
247
-
248
- describeSchema(schema);
249
-
250
- return lines.join('\n');
251
- }
252
-
253
- /**
254
- * Build a prompt that includes schema instructions
255
- * @param {string} prompt - Original prompt
256
- * @param {Object} schema - JSON schema
257
- * @returns {string} Enhanced prompt
258
- */
259
- export function buildPromptWithSchema(prompt, schema) {
260
- if (!schema) return prompt;
261
-
262
- const instructions = schemaToPromptInstructions(schema);
263
-
264
- return `${prompt}
265
-
266
- ${instructions}
267
-
268
- Respond ONLY with valid JSON matching the above structure.`;
269
- }
1
+ /**
2
+ * Output Schemas - Standard JSON schemas for provider outputs
3
+ * Phase 33, Task 6
4
+ */
5
+
6
+ import { readFile } from 'fs/promises';
7
+ import { join } from 'path';
8
+
9
+ // Built-in schemas
10
+ export const reviewResultSchema = {
11
+ type: 'object',
12
+ required: ['summary', 'issues', 'score', 'approved'],
13
+ properties: {
14
+ summary: { type: 'string', description: 'Brief summary of the review' },
15
+ issues: {
16
+ type: 'array',
17
+ items: {
18
+ type: 'object',
19
+ properties: {
20
+ severity: { type: 'string', enum: ['error', 'warning', 'info'] },
21
+ message: { type: 'string' },
22
+ file: { type: 'string' },
23
+ line: { type: 'number' },
24
+ },
25
+ },
26
+ },
27
+ score: { type: 'number', minimum: 0, maximum: 100 },
28
+ approved: { type: 'boolean' },
29
+ },
30
+ };
31
+
32
+ export const designResultSchema = {
33
+ type: 'object',
34
+ required: ['mockups', 'rationale', 'alternatives'],
35
+ properties: {
36
+ mockups: {
37
+ type: 'array',
38
+ items: {
39
+ type: 'object',
40
+ properties: {
41
+ name: { type: 'string' },
42
+ description: { type: 'string' },
43
+ imageUrl: { type: 'string' },
44
+ },
45
+ },
46
+ },
47
+ rationale: { type: 'string' },
48
+ alternatives: {
49
+ type: 'array',
50
+ items: { type: 'string' },
51
+ },
52
+ },
53
+ };
54
+
55
+ export const codeResultSchema = {
56
+ type: 'object',
57
+ required: ['files', 'explanation', 'tests'],
58
+ properties: {
59
+ files: {
60
+ type: 'array',
61
+ items: {
62
+ type: 'object',
63
+ properties: {
64
+ path: { type: 'string' },
65
+ content: { type: 'string' },
66
+ action: { type: 'string', enum: ['create', 'modify', 'delete'] },
67
+ },
68
+ },
69
+ },
70
+ explanation: { type: 'string' },
71
+ tests: {
72
+ type: 'array',
73
+ items: { type: 'string' },
74
+ },
75
+ },
76
+ };
77
+
78
+ /**
79
+ * Load schema from file
80
+ */
81
+ export async function loadSchema(name) {
82
+ const schemaPath = join(process.cwd(), '.tlc', 'schemas', name + '.json');
83
+ const content = await readFile(schemaPath, 'utf-8');
84
+ return JSON.parse(content);
85
+ }
86
+
87
+ /**
88
+ * Validate output against schema
89
+ */
90
+ export function validateOutput(data, schema) {
91
+ const errors = [];
92
+
93
+ // Check required fields
94
+ if (schema.required) {
95
+ for (const field of schema.required) {
96
+ if (!(field in data)) {
97
+ errors.push('Missing required field: ' + field);
98
+ }
99
+ }
100
+ }
101
+
102
+ // Check type
103
+ if (schema.type === 'object' && typeof data !== 'object') {
104
+ errors.push('Expected object');
105
+ }
106
+
107
+ return {
108
+ valid: errors.length === 0,
109
+ errors,
110
+ };
111
+ }
112
+
113
+ /**
114
+ * Build prompt with schema instructions
115
+ */
116
+ export function buildPromptWithSchema(prompt, schema) {
117
+ const instructions = schemaToPromptInstructions(schema);
118
+ return prompt + '\n\nRespond with JSON matching this schema:\n' + instructions;
119
+ }
120
+
121
+ /**
122
+ * Convert schema to human-readable instructions
123
+ */
124
+ export function schemaToPromptInstructions(schema) {
125
+ const lines = ['{\n'];
126
+
127
+ if (schema.properties) {
128
+ for (const [key, prop] of Object.entries(schema.properties)) {
129
+ const desc = prop.description || prop.type;
130
+ lines.push(' "' + key + '": // ' + desc + '\n');
131
+ }
132
+ }
133
+
134
+ lines.push('}');
135
+ return lines.join('');
136
+ }
137
+
138
+ export default {
139
+ loadSchema,
140
+ validateOutput,
141
+ reviewResultSchema,
142
+ designResultSchema,
143
+ codeResultSchema,
144
+ buildPromptWithSchema,
145
+ schemaToPromptInstructions,
146
+ };