@lightupai/polaris 0.0.87 → 0.0.89
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/package.json +1 -1
- package/src/client/client.ts +58 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightupai/polaris",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.89",
|
|
4
4
|
"description": "Record and stream Claude Code sessions to Slack. Like Gong for AI coding — capture every prompt, response, and tool call. Multiplayer collaboration across AI coding agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
package/src/client/client.ts
CHANGED
|
@@ -4,6 +4,9 @@ import {
|
|
|
4
4
|
ListToolsRequestSchema,
|
|
5
5
|
CallToolRequestSchema,
|
|
6
6
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
7
|
+
import { mkdir, writeFile, readFile, rm } from "node:fs/promises";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { createHash } from "node:crypto";
|
|
7
10
|
|
|
8
11
|
// --- Configuration ---
|
|
9
12
|
|
|
@@ -41,6 +44,34 @@ async function daemonGet(path: string): Promise<Response> {
|
|
|
41
44
|
return fetch(`${DAEMON_URL}${path}`, { headers: daemonHeaders() });
|
|
42
45
|
}
|
|
43
46
|
|
|
47
|
+
// --- Session state persistence ---
|
|
48
|
+
|
|
49
|
+
function sessionStatePath(): string {
|
|
50
|
+
const hash = createHash("sha256").update(process.cwd()).digest("hex").slice(0, 16);
|
|
51
|
+
return `${homedir()}/.polaris/sessions/${hash}.json`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function saveSessionState(project: string, session: string, user: string): Promise<void> {
|
|
55
|
+
try {
|
|
56
|
+
await mkdir(`${homedir()}/.polaris/sessions`, { recursive: true });
|
|
57
|
+
await writeFile(sessionStatePath(), JSON.stringify({ project, session, user, cwd: process.cwd() }));
|
|
58
|
+
} catch { /* best-effort */ }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function clearSessionState(): Promise<void> {
|
|
62
|
+
try {
|
|
63
|
+
await rm(sessionStatePath(), { force: true });
|
|
64
|
+
} catch { /* best-effort */ }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function loadSessionState(): Promise<{ project: string; session: string; user: string } | null> {
|
|
68
|
+
try {
|
|
69
|
+
const data = JSON.parse(await readFile(sessionStatePath(), "utf-8"));
|
|
70
|
+
if (data.project && data.session && data.user) return data;
|
|
71
|
+
} catch { /* no saved state */ }
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
|
|
44
75
|
// --- Current connection state ---
|
|
45
76
|
|
|
46
77
|
let currentProject = "";
|
|
@@ -206,6 +237,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
206
237
|
currentProject = body.project ?? project;
|
|
207
238
|
currentSession = body.session ?? session ?? "";
|
|
208
239
|
currentUser = user;
|
|
240
|
+
await saveSessionState(currentProject, currentSession, currentUser);
|
|
209
241
|
return { content: [{ type: "text", text: `Connected to #${currentProject}/${currentSession} as ${user}.` }] };
|
|
210
242
|
}
|
|
211
243
|
return { content: [{ type: "text", text: `Failed to connect: ${body.error ?? "unknown error"}` }] };
|
|
@@ -220,6 +252,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
220
252
|
currentProject = "";
|
|
221
253
|
currentSession = "";
|
|
222
254
|
currentUser = "";
|
|
255
|
+
await clearSessionState();
|
|
223
256
|
return { content: [{ type: "text", text: "Disconnected from Polaris." }] };
|
|
224
257
|
} catch {
|
|
225
258
|
return { content: [{ type: "text", text: "Failed to disconnect — daemon may not be running." }] };
|
|
@@ -364,6 +397,31 @@ async function main() {
|
|
|
364
397
|
console.error("Warning: Polaris daemon not reachable. Start it with `bun run src/daemon/daemon.ts`.");
|
|
365
398
|
}
|
|
366
399
|
|
|
400
|
+
// Auto-reconnect if a previous session was active in this workspace
|
|
401
|
+
const saved = await loadSessionState();
|
|
402
|
+
if (saved) {
|
|
403
|
+
try {
|
|
404
|
+
const res = await daemonPost("/connect", {
|
|
405
|
+
ccSessionId: CC_SESSION_ID,
|
|
406
|
+
project: saved.project,
|
|
407
|
+
session: saved.session,
|
|
408
|
+
user: saved.user,
|
|
409
|
+
});
|
|
410
|
+
const body = await res.json() as { status?: string; project?: string; session?: string; user?: string; error?: string };
|
|
411
|
+
if (res.ok) {
|
|
412
|
+
currentProject = body.project ?? saved.project;
|
|
413
|
+
currentSession = body.session ?? saved.session;
|
|
414
|
+
currentUser = saved.user;
|
|
415
|
+
console.error(`Polaris auto-reconnected to #${currentProject}/${currentSession}`);
|
|
416
|
+
} else {
|
|
417
|
+
// Session or project no longer exists — clear stale state
|
|
418
|
+
await clearSessionState();
|
|
419
|
+
}
|
|
420
|
+
} catch {
|
|
421
|
+
// Daemon not running — keep state file for next startup when daemon is available
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
367
425
|
// inject delivery is handled via the UserPromptSubmit hook (see daemon injectQueues); claude/channel push deferred
|
|
368
426
|
|
|
369
427
|
const transport = new StdioServerTransport();
|