@lightupai/polaris 0.0.23 → 0.0.24
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 +1 -0
- package/package.json +1 -1
- package/src/daemon/daemon.ts +34 -10
package/README.md
CHANGED
|
@@ -119,6 +119,7 @@ tests/ Test suite (bun test)
|
|
|
119
119
|
- [ ] Reconciliation and recovery — `polaris recover` command that diffs the daemon JSONL log against the DB, backfills missing events, and posts an abridged recovery summary to Slack as a thread reply at the correct timeline position
|
|
120
120
|
- [ ] CD pipeline for Hetzner — auto-deploy to production on merge to master (SSH + docker compose up), similar to the npm publish job
|
|
121
121
|
- [ ] Auto-update local skill/hooks — locally installed skill and hook files go stale when the repo changes. `polaris install` fixes it but there's no staleness detection or auto-update mechanism
|
|
122
|
+
- [ ] Slack channel name collision — if a channel name was previously deleted, Slack reserves it. Bridge should handle `name_taken` by trying a prefix/suffix (e.g., `p-project-name`)
|
|
122
123
|
|
|
123
124
|
## Development
|
|
124
125
|
|
package/package.json
CHANGED
package/src/daemon/daemon.ts
CHANGED
|
@@ -346,19 +346,43 @@ export function startDaemon(port = Number(process.env.POLARIS_DAEMON_PORT ?? 432
|
|
|
346
346
|
let mapping = sessions.get(ccSessionId);
|
|
347
347
|
if (!mapping || !mapping.project) {
|
|
348
348
|
// CC session_id doesn't match any registered MCP client.
|
|
349
|
-
//
|
|
350
|
-
//
|
|
349
|
+
// This CC session hasn't been /polaris join'd yet.
|
|
350
|
+
// Auto-create a new Polaris session in the same project as an existing session.
|
|
351
351
|
const connectedSessions = Array.from(sessions.values()).filter((m) => m.project);
|
|
352
|
-
if (connectedSessions.length ===
|
|
353
|
-
// Only one active session — route to it and remember the mapping
|
|
354
|
-
mapping = connectedSessions[0];
|
|
355
|
-
sessions.set(ccSessionId, { ...mapping, ccSessionId, slackChannel: undefined });
|
|
356
|
-
} else if (connectedSessions.length > 1) {
|
|
357
|
-
// Multiple sessions — can't determine which one. Discard.
|
|
358
|
-
return json({ status: "ambiguous" });
|
|
359
|
-
} else {
|
|
352
|
+
if (connectedSessions.length === 0) {
|
|
360
353
|
return json({ status: "not_connected" });
|
|
361
354
|
}
|
|
355
|
+
|
|
356
|
+
// Use the first connected session as a template for project/user/agent
|
|
357
|
+
const template = connectedSessions[0];
|
|
358
|
+
const newSession = generateSessionName();
|
|
359
|
+
|
|
360
|
+
// Create the session on the API
|
|
361
|
+
const serviceUrl = getServiceUrl();
|
|
362
|
+
try {
|
|
363
|
+
const createRes = await fetch(`${serviceUrl}/projects/${template.project}/sessions`, {
|
|
364
|
+
method: "POST",
|
|
365
|
+
headers: await authHeaders(),
|
|
366
|
+
body: JSON.stringify({ name: newSession, driver: template.user }),
|
|
367
|
+
});
|
|
368
|
+
if (!createRes.ok && createRes.status !== 409) {
|
|
369
|
+
return json({ status: "session_create_failed" });
|
|
370
|
+
}
|
|
371
|
+
} catch {
|
|
372
|
+
return json({ status: "api_unreachable" });
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
mapping = {
|
|
376
|
+
ccSessionId,
|
|
377
|
+
project: template.project,
|
|
378
|
+
session: newSession,
|
|
379
|
+
user: template.user,
|
|
380
|
+
agent: template.agent,
|
|
381
|
+
slackChannel: template.slackChannel,
|
|
382
|
+
ws: null,
|
|
383
|
+
};
|
|
384
|
+
sessions.set(ccSessionId, mapping);
|
|
385
|
+
console.error(`[daemon] Auto-created session ${template.project}/${newSession} for CC session ${ccSessionId.slice(0, 8)}`);
|
|
362
386
|
}
|
|
363
387
|
|
|
364
388
|
// Determine sender: human for prompts, agent for everything else
|