@hale-bopp/valentino-engine 2.2.0 → 2.3.1

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 (82) hide show
  1. package/README.md +61 -0
  2. package/dist/bin/commands/cockpit.d.ts +16 -0
  3. package/dist/bin/commands/cockpit.d.ts.map +1 -0
  4. package/dist/bin/commands/cockpit.js +205 -0
  5. package/dist/bin/commands/cockpit.js.map +1 -0
  6. package/dist/bin/commands/theme-audit.d.ts +7 -0
  7. package/dist/bin/commands/theme-audit.d.ts.map +1 -0
  8. package/dist/bin/commands/theme-audit.js +70 -0
  9. package/dist/bin/commands/theme-audit.js.map +1 -0
  10. package/dist/bin/commands/validate.d.ts.map +1 -1
  11. package/dist/bin/commands/validate.js +94 -1
  12. package/dist/bin/commands/validate.js.map +1 -1
  13. package/dist/bin/valentino.js +14 -0
  14. package/dist/bin/valentino.js.map +1 -1
  15. package/dist/cockpit-server.d.ts +17 -0
  16. package/dist/cockpit-server.d.ts.map +1 -0
  17. package/dist/cockpit-server.js +505 -0
  18. package/dist/cockpit-server.js.map +1 -0
  19. package/dist/cockpit-web/index.html +979 -0
  20. package/dist/core/cockpit-api.d.ts +99 -0
  21. package/dist/core/cockpit-api.d.ts.map +1 -0
  22. package/dist/core/cockpit-api.js +269 -0
  23. package/dist/core/cockpit-api.js.map +1 -0
  24. package/dist/core/cockpit-repl.d.ts +51 -0
  25. package/dist/core/cockpit-repl.d.ts.map +1 -0
  26. package/dist/core/cockpit-repl.js +217 -0
  27. package/dist/core/cockpit-repl.js.map +1 -0
  28. package/dist/core/contrast-usage-probe.d.ts +84 -0
  29. package/dist/core/contrast-usage-probe.d.ts.map +1 -0
  30. package/dist/core/contrast-usage-probe.js +244 -0
  31. package/dist/core/contrast-usage-probe.js.map +1 -0
  32. package/dist/core/contrast-usage-probe.test.d.ts +2 -0
  33. package/dist/core/contrast-usage-probe.test.d.ts.map +1 -0
  34. package/dist/core/contrast-usage-probe.test.js +186 -0
  35. package/dist/core/contrast-usage-probe.test.js.map +1 -0
  36. package/dist/core/intent-parser.d.ts +67 -0
  37. package/dist/core/intent-parser.d.ts.map +1 -0
  38. package/dist/core/intent-parser.js +485 -0
  39. package/dist/core/intent-parser.js.map +1 -0
  40. package/dist/core/openrouter-client.d.ts +38 -0
  41. package/dist/core/openrouter-client.d.ts.map +1 -0
  42. package/dist/core/openrouter-client.js +123 -0
  43. package/dist/core/openrouter-client.js.map +1 -0
  44. package/dist/core/page-status.d.ts +15 -1
  45. package/dist/core/page-status.d.ts.map +1 -1
  46. package/dist/core/page-status.js +21 -0
  47. package/dist/core/page-status.js.map +1 -1
  48. package/dist/core/project-adapter.d.ts +73 -0
  49. package/dist/core/project-adapter.d.ts.map +1 -0
  50. package/dist/core/project-adapter.js +364 -0
  51. package/dist/core/project-adapter.js.map +1 -0
  52. package/dist/core/schema-export.d.ts +32 -0
  53. package/dist/core/schema-export.d.ts.map +1 -0
  54. package/dist/core/schema-export.js +493 -0
  55. package/dist/core/schema-export.js.map +1 -0
  56. package/dist/core/theme-audit.d.ts +104 -0
  57. package/dist/core/theme-audit.d.ts.map +1 -0
  58. package/dist/core/theme-audit.js +128 -0
  59. package/dist/core/theme-audit.js.map +1 -0
  60. package/dist/core/theme-audit.test.d.ts +2 -0
  61. package/dist/core/theme-audit.test.d.ts.map +1 -0
  62. package/dist/core/theme-audit.test.js +198 -0
  63. package/dist/core/theme-audit.test.js.map +1 -0
  64. package/dist/core/url-import.d.ts +41 -0
  65. package/dist/core/url-import.d.ts.map +1 -0
  66. package/dist/core/url-import.js +207 -0
  67. package/dist/core/url-import.js.map +1 -0
  68. package/dist/core/video-import.d.ts +46 -0
  69. package/dist/core/video-import.d.ts.map +1 -0
  70. package/dist/core/video-import.js +192 -0
  71. package/dist/core/video-import.js.map +1 -0
  72. package/dist/core/visual-import.d.ts +42 -0
  73. package/dist/core/visual-import.d.ts.map +1 -0
  74. package/dist/core/visual-import.js +227 -0
  75. package/dist/core/visual-import.js.map +1 -0
  76. package/dist/index.d.ts +25 -2
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +25 -1
  79. package/dist/index.js.map +1 -1
  80. package/dist/mcp/index.js +32 -0
  81. package/dist/mcp/index.js.map +1 -1
  82. package/package.json +9 -3
@@ -0,0 +1,505 @@
1
+ /**
2
+ * Cockpit Server — HTTP API + Web UI for the Valentino Conversational Cockpit.
3
+ * Feature #778 (Il Sarto Parla), PBI #781 (Phase 2).
4
+ *
5
+ * Wraps cockpit-api over HTTP. Serves a built-in web UI.
6
+ * Zero external dependencies — uses Node built-in http module.
7
+ *
8
+ * Usage:
9
+ * npx tsx src/cockpit-server.ts <spec.json> [--port 3781]
10
+ * valentino cockpit <spec.json> --serve [--port 3781]
11
+ */
12
+ import { createServer } from 'http';
13
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
14
+ import { resolve, dirname, join } from 'path';
15
+ import { fileURLToPath } from 'url';
16
+ import { executeCockpitAction, validateCockpitAction, describeCockpitAction, } from './core/cockpit-api.js';
17
+ import { parseIntentLocal, parseIntent } from './core/intent-parser.js';
18
+ import { getPageSpecSchema, getCockpitActionSchema, getAllSectionSchemas } from './core/schema-export.js';
19
+ import { createOpenRouterCallback, testOpenRouterConnection } from './core/openrouter-client.js';
20
+ import { importFromImage, createVisionCallback } from './core/visual-import.js';
21
+ import { importFromUrl } from './core/url-import.js';
22
+ import { importFromVideo } from './core/video-import.js';
23
+ import { importFromProject, scanProjectDirectory } from './core/project-adapter.js';
24
+ // ---------------------------------------------------------------------------
25
+ // Request helpers
26
+ // ---------------------------------------------------------------------------
27
+ async function readBody(req) {
28
+ const chunks = [];
29
+ for await (const chunk of req) {
30
+ chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
31
+ }
32
+ return Buffer.concat(chunks).toString('utf-8');
33
+ }
34
+ function json(res, data, status = 200) {
35
+ res.writeHead(status, {
36
+ 'Content-Type': 'application/json',
37
+ 'Access-Control-Allow-Origin': '*',
38
+ });
39
+ res.end(JSON.stringify(data));
40
+ }
41
+ function cors(res) {
42
+ res.writeHead(204, {
43
+ 'Access-Control-Allow-Origin': '*',
44
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
45
+ 'Access-Control-Allow-Headers': 'Content-Type',
46
+ });
47
+ res.end();
48
+ }
49
+ // ---------------------------------------------------------------------------
50
+ // API routes
51
+ // ---------------------------------------------------------------------------
52
+ function handleApi(req, res, state) {
53
+ const url = new URL(req.url || '/', `http://localhost`);
54
+ const path = url.pathname;
55
+ // CORS preflight
56
+ if (req.method === 'OPTIONS') {
57
+ cors(res);
58
+ return;
59
+ }
60
+ // GET /api/spec — current spec
61
+ if (path === '/api/spec' && req.method === 'GET') {
62
+ json(res, {
63
+ spec: state.spec,
64
+ actionCount: state.actionCount,
65
+ undoAvailable: state.history.length,
66
+ });
67
+ return;
68
+ }
69
+ // GET /api/schema — JSON schemas for LLM context
70
+ if (path === '/api/schema' && req.method === 'GET') {
71
+ json(res, {
72
+ pageSpec: getPageSpecSchema(),
73
+ cockpitAction: getCockpitActionSchema(),
74
+ sections: getAllSectionSchemas(),
75
+ });
76
+ return;
77
+ }
78
+ // POST /api/parse — parse natural language
79
+ if (path === '/api/parse' && req.method === 'POST') {
80
+ readBody(req).then(body => {
81
+ const { text } = JSON.parse(body);
82
+ if (!text) {
83
+ json(res, { error: 'Missing "text" field' }, 400);
84
+ return;
85
+ }
86
+ const result = parseIntentLocal(text, state.spec);
87
+ json(res, result);
88
+ }).catch(() => json(res, { error: 'Invalid JSON body' }, 400));
89
+ return;
90
+ }
91
+ // POST /api/action — execute cockpit action
92
+ if (path === '/api/action' && req.method === 'POST') {
93
+ readBody(req).then(body => {
94
+ const action = JSON.parse(body);
95
+ const preErrors = validateCockpitAction(action, state.spec);
96
+ if (preErrors.length > 0) {
97
+ json(res, { success: false, errors: preErrors }, 400);
98
+ return;
99
+ }
100
+ // Save undo point for mutations
101
+ if (action.action !== 'query') {
102
+ state.history.push(structuredClone(state.spec));
103
+ }
104
+ const result = executeCockpitAction(state.spec, action);
105
+ if (result.success && action.action !== 'query') {
106
+ state.spec = result.spec;
107
+ state.actionCount++;
108
+ }
109
+ json(res, {
110
+ ...result,
111
+ description: describeCockpitAction(action),
112
+ actionCount: state.actionCount,
113
+ undoAvailable: state.history.length,
114
+ });
115
+ }).catch(() => json(res, { error: 'Invalid JSON body' }, 400));
116
+ return;
117
+ }
118
+ // POST /api/speak — natural language → parse + execute (LLM-aware)
119
+ if (path === '/api/speak' && req.method === 'POST') {
120
+ readBody(req).then(async (body) => {
121
+ const { text } = JSON.parse(body);
122
+ if (!text) {
123
+ json(res, { error: 'Missing "text" field' }, 400);
124
+ return;
125
+ }
126
+ // Use LLM if available, otherwise local
127
+ const parseResult = await parseIntent(text, state.spec, state.llm || undefined);
128
+ if (!parseResult.intent) {
129
+ json(res, {
130
+ success: false,
131
+ parsed: false,
132
+ message: 'Could not parse intent',
133
+ mode: parseResult.mode,
134
+ raw: text,
135
+ });
136
+ return;
137
+ }
138
+ const { action, confidence, description } = parseResult.intent;
139
+ const preErrors = validateCockpitAction(action, state.spec);
140
+ if (preErrors.length > 0) {
141
+ json(res, { success: false, parsed: true, description, errors: preErrors });
142
+ return;
143
+ }
144
+ if (action.action !== 'query') {
145
+ state.history.push(structuredClone(state.spec));
146
+ }
147
+ const result = executeCockpitAction(state.spec, action);
148
+ if (result.success && action.action !== 'query') {
149
+ state.spec = result.spec;
150
+ state.actionCount++;
151
+ }
152
+ json(res, {
153
+ ...result,
154
+ parsed: true,
155
+ description,
156
+ confidence,
157
+ mode: parseResult.mode,
158
+ fallbackReason: parseResult.fallbackReason,
159
+ actionCount: state.actionCount,
160
+ undoAvailable: state.history.length,
161
+ });
162
+ }).catch(e => json(res, { error: 'Invalid JSON body' }, 400));
163
+ return;
164
+ }
165
+ // GET /api/config — current LLM config
166
+ if (path === '/api/config' && req.method === 'GET') {
167
+ json(res, {
168
+ llmConnected: state.llm !== null,
169
+ llmConfig: state.llmConfig,
170
+ });
171
+ return;
172
+ }
173
+ // POST /api/config — set OpenRouter API key + model
174
+ if (path === '/api/config' && req.method === 'POST') {
175
+ readBody(req).then(async (body) => {
176
+ const { apiKey, model } = JSON.parse(body);
177
+ if (!apiKey) {
178
+ json(res, { error: 'Missing "apiKey" field' }, 400);
179
+ return;
180
+ }
181
+ const config = { apiKey, model };
182
+ const test = await testOpenRouterConnection(config);
183
+ if (test.ok) {
184
+ state.llm = createOpenRouterCallback(config);
185
+ state.llmConfig = { model: model || test.model || 'default', connected: true };
186
+ json(res, { success: true, model: state.llmConfig.model });
187
+ }
188
+ else {
189
+ json(res, { success: false, error: test.error }, 400);
190
+ }
191
+ }).catch(() => json(res, { error: 'Invalid JSON body' }, 400));
192
+ return;
193
+ }
194
+ // DELETE /api/config — disconnect LLM
195
+ if (path === '/api/config' && req.method === 'DELETE') {
196
+ state.llm = null;
197
+ state.llmConfig = null;
198
+ json(res, { success: true });
199
+ return;
200
+ }
201
+ // POST /api/import/image — visual import from screenshot
202
+ if (path === '/api/import/image' && req.method === 'POST') {
203
+ readBody(req).then(async (body) => {
204
+ const { image, mimeType, id, profile, language } = JSON.parse(body);
205
+ if (!image) {
206
+ json(res, { error: 'Missing "image" field (base64)' }, 400);
207
+ return;
208
+ }
209
+ // Need an API key for vision
210
+ const apiKey = state.llmConfig?.connected
211
+ ? undefined // will use existing config
212
+ : process.env.OPENROUTER_API_KEY;
213
+ // Try to extract key from current LLM state or env
214
+ let visionKey;
215
+ // Check env first
216
+ if (process.env.OPENROUTER_API_KEY) {
217
+ visionKey = process.env.OPENROUTER_API_KEY;
218
+ }
219
+ if (!visionKey) {
220
+ json(res, {
221
+ success: false,
222
+ error: 'Vision import requires an OpenRouter API key. Configure it in Settings or set OPENROUTER_API_KEY env var.',
223
+ }, 400);
224
+ return;
225
+ }
226
+ const visionModel = process.env.OPENROUTER_VISION_MODEL || 'anthropic/claude-sonnet-4-6';
227
+ const visionLlm = createVisionCallback(visionKey, visionModel);
228
+ const result = await importFromImage(image, mimeType || 'image/png', visionLlm, {
229
+ id: id || `imported-${Date.now()}`,
230
+ profile,
231
+ language: language || 'it',
232
+ });
233
+ if (result.success && result.spec) {
234
+ // Replace current spec with imported one
235
+ state.history.push(structuredClone(state.spec));
236
+ state.spec = result.spec;
237
+ state.actionCount++;
238
+ }
239
+ json(res, {
240
+ ...result,
241
+ actionCount: state.actionCount,
242
+ undoAvailable: state.history.length,
243
+ });
244
+ }).catch(() => json(res, { error: 'Invalid JSON body' }, 400));
245
+ return;
246
+ }
247
+ // POST /api/import/url — import from URL
248
+ if (path === '/api/import/url' && req.method === 'POST') {
249
+ readBody(req).then(async (body) => {
250
+ const { url: targetUrl, id, language, forceHtmlFallback } = JSON.parse(body);
251
+ if (!targetUrl) {
252
+ json(res, { error: 'Missing "url" field' }, 400);
253
+ return;
254
+ }
255
+ const visionKey = process.env.OPENROUTER_API_KEY;
256
+ if (!visionKey) {
257
+ json(res, {
258
+ success: false,
259
+ error: 'URL import requires OPENROUTER_API_KEY env var or Settings config.',
260
+ }, 400);
261
+ return;
262
+ }
263
+ const visionModel = process.env.OPENROUTER_VISION_MODEL || 'anthropic/claude-sonnet-4-6';
264
+ const visionLlm = createVisionCallback(visionKey, visionModel);
265
+ // HTML fallback LLM — uses text model (cheaper)
266
+ const textModel = process.env.OPENROUTER_MODEL || 'anthropic/claude-haiku-4.5-20251001';
267
+ const htmlLlm = async (systemPrompt, userPrompt) => {
268
+ const resp = await fetch('https://openrouter.ai/api/v1/chat/completions', {
269
+ method: 'POST',
270
+ headers: {
271
+ 'Content-Type': 'application/json',
272
+ 'Authorization': `Bearer ${visionKey}`,
273
+ 'HTTP-Referer': 'https://valentino-engine.dev',
274
+ },
275
+ body: JSON.stringify({
276
+ model: textModel,
277
+ max_tokens: 4096,
278
+ temperature: 0.1,
279
+ messages: [
280
+ { role: 'system', content: systemPrompt },
281
+ { role: 'user', content: userPrompt },
282
+ ],
283
+ }),
284
+ });
285
+ const data = await resp.json();
286
+ return data.choices?.[0]?.message?.content || '';
287
+ };
288
+ const pageId = id || new URL(targetUrl).hostname.replace(/\./g, '-');
289
+ const result = await importFromUrl(targetUrl, visionLlm, htmlLlm, {
290
+ id: pageId,
291
+ language: language || 'it',
292
+ forceHtmlFallback: forceHtmlFallback ?? true, // default to HTML since Playwright likely not installed
293
+ });
294
+ if (result.success && result.spec) {
295
+ state.history.push(structuredClone(state.spec));
296
+ state.spec = result.spec;
297
+ state.actionCount++;
298
+ }
299
+ json(res, {
300
+ ...result,
301
+ actionCount: state.actionCount,
302
+ undoAvailable: state.history.length,
303
+ });
304
+ }).catch(() => json(res, { error: 'Invalid JSON body' }, 400));
305
+ return;
306
+ }
307
+ // POST /api/import/video — import from video frames
308
+ if (path === '/api/import/video' && req.method === 'POST') {
309
+ readBody(req).then(async (body) => {
310
+ const { frames, id, language } = JSON.parse(body);
311
+ if (!frames || !Array.isArray(frames) || frames.length === 0) {
312
+ json(res, { error: 'Missing "frames" array' }, 400);
313
+ return;
314
+ }
315
+ const visionKey = process.env.OPENROUTER_API_KEY;
316
+ if (!visionKey) {
317
+ json(res, { success: false, error: 'Video import requires OPENROUTER_API_KEY.' }, 400);
318
+ return;
319
+ }
320
+ const visionModel = process.env.OPENROUTER_VISION_MODEL || 'anthropic/claude-sonnet-4-6';
321
+ const visionLlm = createVisionCallback(visionKey, visionModel);
322
+ const result = await importFromVideo(frames, visionLlm, {
323
+ id: id || `video-${Date.now()}`,
324
+ language: language || 'it',
325
+ });
326
+ if (result.success && result.spec) {
327
+ state.history.push(structuredClone(state.spec));
328
+ state.spec = result.spec;
329
+ state.actionCount++;
330
+ }
331
+ json(res, {
332
+ ...result,
333
+ actionCount: state.actionCount,
334
+ undoAvailable: state.history.length,
335
+ });
336
+ }).catch(() => json(res, { error: 'Invalid JSON body' }, 400));
337
+ return;
338
+ }
339
+ // GET /api/import/project/scan — scan project directory
340
+ if (path === '/api/import/project/scan' && req.method === 'POST') {
341
+ readBody(req).then(body => {
342
+ const { path: projectPath } = JSON.parse(body);
343
+ if (!projectPath) {
344
+ json(res, { error: 'Missing "path" field' }, 400);
345
+ return;
346
+ }
347
+ const scan = scanProjectDirectory(projectPath);
348
+ json(res, scan);
349
+ }).catch(() => json(res, { error: 'Invalid JSON body' }, 400));
350
+ return;
351
+ }
352
+ // POST /api/import/project — full project import
353
+ if (path === '/api/import/project' && req.method === 'POST') {
354
+ readBody(req).then(async (body) => {
355
+ const { path: projectPath, language } = JSON.parse(body);
356
+ if (!projectPath) {
357
+ json(res, { error: 'Missing "path" field' }, 400);
358
+ return;
359
+ }
360
+ const visionKey = process.env.OPENROUTER_API_KEY;
361
+ if (!visionKey) {
362
+ json(res, { success: false, error: 'Project import requires OPENROUTER_API_KEY.' }, 400);
363
+ return;
364
+ }
365
+ const textModel = process.env.OPENROUTER_MODEL || 'anthropic/claude-haiku-4.5-20251001';
366
+ const htmlLlm = async (systemPrompt, userPrompt) => {
367
+ const resp = await fetch('https://openrouter.ai/api/v1/chat/completions', {
368
+ method: 'POST',
369
+ headers: {
370
+ 'Content-Type': 'application/json',
371
+ 'Authorization': `Bearer ${visionKey}`,
372
+ 'HTTP-Referer': 'https://valentino-engine.dev',
373
+ },
374
+ body: JSON.stringify({
375
+ model: textModel,
376
+ max_tokens: 4096,
377
+ temperature: 0.1,
378
+ messages: [
379
+ { role: 'system', content: systemPrompt },
380
+ { role: 'user', content: userPrompt },
381
+ ],
382
+ }),
383
+ });
384
+ const data = await resp.json();
385
+ return data.choices?.[0]?.message?.content || '';
386
+ };
387
+ const result = await importFromProject(projectPath, htmlLlm, { language: language || 'it' });
388
+ if (result.success && result.primarySpec) {
389
+ state.history.push(structuredClone(state.spec));
390
+ state.spec = result.primarySpec;
391
+ state.actionCount++;
392
+ }
393
+ json(res, {
394
+ ...result,
395
+ actionCount: state.actionCount,
396
+ undoAvailable: state.history.length,
397
+ });
398
+ }).catch(() => json(res, { error: 'Invalid JSON body' }, 400));
399
+ return;
400
+ }
401
+ // POST /api/undo
402
+ if (path === '/api/undo' && req.method === 'POST') {
403
+ if (state.history.length === 0) {
404
+ json(res, { success: false, message: 'Nothing to undo' });
405
+ return;
406
+ }
407
+ state.spec = state.history.pop();
408
+ json(res, { success: true, spec: state.spec, undoAvailable: state.history.length });
409
+ return;
410
+ }
411
+ // POST /api/save — persist to disk
412
+ if (path === '/api/save' && req.method === 'POST') {
413
+ try {
414
+ writeFileSync(state.specPath, JSON.stringify(state.spec, null, 2) + '\n');
415
+ json(res, { success: true, path: state.specPath });
416
+ }
417
+ catch (err) {
418
+ json(res, { success: false, error: String(err) }, 500);
419
+ }
420
+ return;
421
+ }
422
+ json(res, { error: 'Not found' }, 404);
423
+ }
424
+ // ---------------------------------------------------------------------------
425
+ // Static file serving (built-in web UI)
426
+ // ---------------------------------------------------------------------------
427
+ function getWebUiPath() {
428
+ const thisDir = dirname(fileURLToPath(import.meta.url));
429
+ return join(thisDir, 'cockpit-web', 'index.html');
430
+ }
431
+ function serveStatic(res) {
432
+ const uiPath = getWebUiPath();
433
+ if (!existsSync(uiPath)) {
434
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
435
+ res.end('Web UI not found: ' + uiPath);
436
+ return;
437
+ }
438
+ const html = readFileSync(uiPath, 'utf-8');
439
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
440
+ res.end(html);
441
+ }
442
+ export function startCockpitServer(options) {
443
+ const port = options.port || 3781;
444
+ const specPath = resolve(options.specPath);
445
+ if (!existsSync(specPath)) {
446
+ console.error(`File not found: ${specPath}`);
447
+ process.exit(1);
448
+ }
449
+ const spec = JSON.parse(readFileSync(specPath, 'utf-8'));
450
+ // Auto-configure LLM from env var
451
+ let llm = null;
452
+ let llmConfig = null;
453
+ const envKey = process.env.OPENROUTER_API_KEY;
454
+ const envModel = process.env.OPENROUTER_MODEL;
455
+ if (envKey) {
456
+ const config = { apiKey: envKey, model: envModel };
457
+ llm = createOpenRouterCallback(config);
458
+ llmConfig = { model: envModel || 'anthropic/claude-haiku-4.5-20251001', connected: true };
459
+ }
460
+ const state = {
461
+ spec,
462
+ specPath,
463
+ history: [],
464
+ actionCount: 0,
465
+ llm,
466
+ llmConfig,
467
+ };
468
+ const server = createServer((req, res) => {
469
+ const url = req.url || '/';
470
+ if (url.startsWith('/api/')) {
471
+ handleApi(req, res, state);
472
+ }
473
+ else {
474
+ serveStatic(res);
475
+ }
476
+ });
477
+ server.listen(port, () => {
478
+ console.log(`\n \uD83C\uDFA8 Valentino Cockpit — Il Sarto Parla`);
479
+ console.log(` Page: ${spec.id} (${spec.sections.length} sections)`);
480
+ console.log(` Server: http://localhost:${port}`);
481
+ console.log(` API: http://localhost:${port}/api/spec`);
482
+ if (state.llm) {
483
+ console.log(` LLM: ${state.llmConfig?.model} (from env)`);
484
+ }
485
+ else {
486
+ console.log(` LLM: not configured (set OPENROUTER_API_KEY or use settings)`);
487
+ }
488
+ console.log(`\n Open the URL in your browser to start.\n`);
489
+ });
490
+ }
491
+ // ---------------------------------------------------------------------------
492
+ // CLI entry point
493
+ // ---------------------------------------------------------------------------
494
+ if (process.argv[1] && (process.argv[1].endsWith('cockpit-server.ts') || process.argv[1].endsWith('cockpit-server.js'))) {
495
+ const args = process.argv.slice(2);
496
+ const specPath = args.find(a => !a.startsWith('-'));
497
+ const portFlag = args.indexOf('--port');
498
+ const port = portFlag !== -1 ? parseInt(args[portFlag + 1], 10) : undefined;
499
+ if (!specPath) {
500
+ console.error('Usage: cockpit-server <spec.json> [--port 3781]');
501
+ process.exit(1);
502
+ }
503
+ startCockpitServer({ specPath, port });
504
+ }
505
+ //# sourceMappingURL=cockpit-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cockpit-server.js","sourceRoot":"","sources":["../src/cockpit-server.ts"],"names":[],"mappings":"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"}