spectoflow 0.23.0 → 0.23.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.
- package/lib/hub-server.js +16 -3
- package/package.json +1 -1
package/lib/hub-server.js
CHANGED
|
@@ -55,6 +55,19 @@ function getProject(id) {
|
|
|
55
55
|
return proj;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
// Only called after getProject(id) already returned null — figures out WHY, so the 404 points the
|
|
59
|
+
// user at the right fix instead of a bare "unknown project". The two common real causes: never
|
|
60
|
+
// registered at all, vs. registered but this project predates handlers.js (needs `spectoflow
|
|
61
|
+
// update`) or its folder moved/was deleted.
|
|
62
|
+
function projectErrorMessage(id) {
|
|
63
|
+
const entry = registry.listProjects().find((p) => p.id === id);
|
|
64
|
+
if (!entry) return 'Unknown project.';
|
|
65
|
+
if (!fs.existsSync(entry.path)) return `Project "${entry.name}" is registered, but its folder no longer exists at ${entry.path}.`;
|
|
66
|
+
const handlersPath = path.join(entry.path, '.spectoflow', 'dashboard', 'handlers.js');
|
|
67
|
+
if (!fs.existsSync(handlersPath)) return `Project "${entry.name}" needs an update — run \`spectoflow update\` inside it, then reload this page.`;
|
|
68
|
+
return `Project "${entry.name}" is registered, but its dashboard code failed to load — check its .spectoflow/dashboard/handlers.js for errors.`;
|
|
69
|
+
}
|
|
70
|
+
|
|
58
71
|
// Clears every require.cache entry under this project's own .spectoflow/ tree (its vendored
|
|
59
72
|
// handlers.js and everything IT requires — orchestrator.js, runner.js, files.js, summarize.js,
|
|
60
73
|
// lib/store.js, lib/agents-registry.js) and drops its cached Map entry. The require cache keys by
|
|
@@ -195,7 +208,7 @@ const server = http.createServer(async (req, res) => {
|
|
|
195
208
|
if (p === '/api/events') {
|
|
196
209
|
const id = u.searchParams.get('p');
|
|
197
210
|
const proj = id && getProject(id);
|
|
198
|
-
if (!proj) return sendJSON(res, 404, { error:
|
|
211
|
+
if (!proj) return sendJSON(res, 404, { error: projectErrorMessage(id) });
|
|
199
212
|
res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive' });
|
|
200
213
|
res.write('data: ' + JSON.stringify({ type: 'hello' }) + '\n\n');
|
|
201
214
|
proj.clients.add(res); req.on('close', () => proj.clients.delete(res));
|
|
@@ -211,7 +224,7 @@ const server = http.createServer(async (req, res) => {
|
|
|
211
224
|
if (p.startsWith('/api/')) {
|
|
212
225
|
const id = u.searchParams.get('p');
|
|
213
226
|
const proj = id && getProject(id);
|
|
214
|
-
if (!proj) return sendJSON(res, 404, { error:
|
|
227
|
+
if (!proj) return sendJSON(res, 404, { error: projectErrorMessage(id) });
|
|
215
228
|
const handled = await proj.handlers.handleApi(req, res, u, proj.emit);
|
|
216
229
|
if (handled) return;
|
|
217
230
|
res.writeHead(404); return res.end('Not found');
|
|
@@ -220,7 +233,7 @@ const server = http.createServer(async (req, res) => {
|
|
|
220
233
|
if (m) {
|
|
221
234
|
const id = m[1];
|
|
222
235
|
const proj = getProject(id);
|
|
223
|
-
if (!proj) { res.writeHead(404); return res.end(
|
|
236
|
+
if (!proj) { res.writeHead(404); return res.end(projectErrorMessage(id)); }
|
|
224
237
|
registry.touchProject(id);
|
|
225
238
|
return serveStatic(m[2] || '/', req, res);
|
|
226
239
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spectoflow",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.1",
|
|
4
4
|
"description": "Agent-agnostic spec-driven development framework + real-time local control plane. Markdown artifacts, intent router, workflow-by-scope.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"spec-driven-development",
|