@lightupai/polaris 0.0.25 → 0.0.27

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightupai/polaris",
3
- "version": "0.0.25",
3
+ "version": "0.0.27",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "polaris": "bin/polaris",
@@ -2,7 +2,7 @@
2
2
  name: polaris
3
3
  description: Connect to a Polaris multiplayer collaboration session
4
4
  allowed-tools: polaris_connect polaris_disconnect polaris_status polaris_reply polaris_context polaris_rename
5
- argument-hint: [join <project> | rename <new-name> | disconnect | (no args for status)]
5
+ argument-hint: [join #channel | rename <new-name> | disconnect | (no args for status)]
6
6
  ---
7
7
 
8
8
  ## Polaris — Multiplayer Collaboration
@@ -13,12 +13,12 @@ Manage your connection to a Polaris collaboration session.
13
13
 
14
14
  Based on the arguments provided, do ONE of the following:
15
15
 
16
- **`/polaris join <project>`** — Connect to a session:
17
- 1. Call `polaris_connect` with the given project and user identity `user:manu.bansal`
18
- 2. A session name is auto-generated (e.g., `s-7a3f`)
16
+ **`/polaris join #channel-name`** — Connect to a channel:
17
+ 1. Call `polaris_connect` with the given channel and user identity `user:manu.bansal`
18
+ 2. A session name is auto-generated
19
19
  3. Report the connection status including the session name
20
20
 
21
- **`/polaris rename <new-name>`** — Rename the current project:
21
+ **`/polaris rename <new-name>`** — Rename the current channel:
22
22
  1. Call `polaris_rename` with the new name
23
23
  2. Report the result
24
24
 
package/src/cli/cli.ts CHANGED
@@ -183,7 +183,7 @@ async function install(participantId?: string) {
183
183
  name: polaris
184
184
  description: Connect to a Polaris multiplayer collaboration session
185
185
  allowed-tools: polaris_connect polaris_disconnect polaris_status polaris_reply polaris_context polaris_rename
186
- argument-hint: [join <project> | rename <new-name> | disconnect | (no args for status)]
186
+ argument-hint: [join #channel | rename <new-name> | disconnect | (no args for status)]
187
187
  ---
188
188
 
189
189
  ## Polaris — Multiplayer Collaboration
@@ -194,7 +194,7 @@ Manage your connection to a Polaris collaboration session.
194
194
 
195
195
  Based on the arguments provided, do ONE of the following:
196
196
 
197
- **\`/polaris join <project>\`** — Connect to a session:
197
+ **\`/polaris join #channel-name\`** — Connect to a channel:
198
198
  1. Call \`polaris_connect\` with the given project and user identity ${identity}
199
199
  2. A session name is auto-generated
200
200
  3. Report the connection status including the session name
@@ -315,7 +315,7 @@ async function login(appUrl: string, profileName?: string) {
315
315
  name: polaris
316
316
  description: Connect to a Polaris multiplayer collaboration session
317
317
  allowed-tools: polaris_connect polaris_disconnect polaris_status polaris_reply polaris_context polaris_rename
318
- argument-hint: [join <project> | rename <new-name> | disconnect | (no args for status)]
318
+ argument-hint: [join #channel | rename <new-name> | disconnect | (no args for status)]
319
319
  ---
320
320
 
321
321
  ## Polaris — Multiplayer Collaboration
@@ -326,7 +326,7 @@ Manage your connection to a Polaris collaboration session.
326
326
 
327
327
  Based on the arguments provided, do ONE of the following:
328
328
 
329
- **\`/polaris join <project>\`** — Connect to a session:
329
+ **\`/polaris join #channel-name\`** — Connect to a channel:
330
330
  1. Call \`polaris_connect\` with the given project and user identity ${identity}
331
331
  2. A session name is auto-generated
332
332
  3. Report the connection status including the session name
@@ -533,7 +533,7 @@ switch (command) {
533
533
  }).unref?.();
534
534
  console.log(" ✓ Daemon started in background");
535
535
 
536
- console.log("\nNext: restart Claude Code, then run `/polaris join <project>` in your AI agent.");
536
+ console.log("\nNext: restart Claude Code, then run `/polaris join #channel-name` in your AI agent.");
537
537
  break;
538
538
  }
539
539
 
@@ -579,7 +579,7 @@ switch (command) {
579
579
  }).unref?.();
580
580
  console.log(" ✓ Daemon started in background");
581
581
 
582
- console.log("\nNext: restart Claude Code, then run `/polaris join <project>` in your AI agent.");
582
+ console.log("\nNext: restart Claude Code, then run `/polaris join #channel-name` in your AI agent.");
583
583
  break;
584
584
 
585
585
  default:
@@ -53,12 +53,12 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => ({
53
53
  inputSchema: {
54
54
  type: "object" as const,
55
55
  properties: {
56
- project: { type: "string", description: "Project name" },
56
+ channel: { type: "string", description: "Channel name (e.g., #polaris-dev or polaris-dev)" },
57
57
  user: { type: "string", description: "Your participant ID (e.g., user:manu)" },
58
58
  session: { type: "string", description: "Session name (optional — auto-generated if omitted)" },
59
59
  agent: { type: "string", description: "Agent identity (optional — defaults to agent:claude)" },
60
60
  },
61
- required: ["project", "user"],
61
+ required: ["channel", "user"],
62
62
  },
63
63
  },
64
64
  {
@@ -117,7 +117,8 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
117
117
  const { name, arguments: args } = req.params;
118
118
 
119
119
  if (name === "polaris_connect") {
120
- const { project, user, session, agent } = args as { project: string; user: string; session?: string; agent?: string };
120
+ const { channel, user, session, agent } = args as { channel: string; user: string; session?: string; agent?: string };
121
+ const project = channel.replace(/^#/, ""); // strip leading # if present
121
122
  try {
122
123
  const res = await daemonPost("/connect", {
123
124
  ccSessionId: CC_SESSION_ID,
@@ -131,7 +132,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
131
132
  currentProject = body.project ?? project;
132
133
  currentSession = body.session ?? session ?? "";
133
134
  currentUser = user;
134
- return { content: [{ type: "text", text: `Connected to ${currentProject}/${currentSession} as ${user}.` }] };
135
+ return { content: [{ type: "text", text: `Connected to #${currentProject}/${currentSession} as ${user}.` }] };
135
136
  }
136
137
  return { content: [{ type: "text", text: `Failed to connect: ${body.error ?? "unknown error"}` }] };
137
138
  } catch {
@@ -13,6 +13,7 @@ interface SessionMapping {
13
13
  agent: string;
14
14
  slackChannel?: string;
15
15
  ws: WebSocket | null;
16
+ pendingMapping?: boolean; // true until a hook event maps the real CC session ID
16
17
  }
17
18
 
18
19
  function generateSessionName(): string {
@@ -232,6 +233,7 @@ export function startDaemon(port = Number(process.env.POLARIS_DAEMON_PORT ?? 432
232
233
  user: body.user,
233
234
  agent: agentId,
234
235
  ws: null,
236
+ pendingMapping: true, // waiting for hook event to map the real CC session ID
235
237
  };
236
238
  sessions.set(body.ccSessionId, mapping);
237
239
 
@@ -347,18 +349,24 @@ export function startDaemon(port = Number(process.env.POLARIS_DAEMON_PORT ?? 432
347
349
  if (!mapping || !mapping.project) {
348
350
  // CC session_id doesn't match any registered MCP client.
349
351
  // The MCP server uses a different UUID than CC's session_id.
350
- // Try to find the MCP session that this CC session belongs to.
351
- // Heuristic: if only one connected session exists, route to it.
352
- // Otherwise, drop the event — the user needs to /polaris join first.
353
- const connectedSessions = Array.from(sessions.values()).filter((m) => m.project);
354
- if (connectedSessions.length === 1) {
355
- mapping = connectedSessions[0];
356
- // Remember this mapping for future events from this CC session
352
+ // Match to a session with pendingMapping (most recent first).
353
+ const pending = Array.from(sessions.values()).filter((m) => m.project && m.pendingMapping);
354
+ if (pending.length > 0) {
355
+ // Map the CC session ID to the most recently connected pending session
356
+ mapping = pending[pending.length - 1];
357
+ mapping.pendingMapping = false;
358
+ // Register under the real CC session ID for future events
357
359
  sessions.set(ccSessionId, { ...mapping, ccSessionId });
360
+ console.error(`[daemon] Mapped CC session ${ccSessionId.slice(0, 8)} → ${mapping.project}/${mapping.session}`);
358
361
  } else {
359
- // Multiple or zero sessions — can't determine which one.
360
- // Drop silently; events will flow once /polaris join maps the session.
361
- return json({ status: connectedSessions.length > 0 ? "ambiguous" : "not_connected" });
362
+ // No pending sessions — try single-session fallback
363
+ const connectedSessions = Array.from(sessions.values()).filter((m) => m.project);
364
+ if (connectedSessions.length === 1) {
365
+ mapping = connectedSessions[0];
366
+ sessions.set(ccSessionId, { ...mapping, ccSessionId });
367
+ } else {
368
+ return json({ status: connectedSessions.length > 0 ? "ambiguous" : "not_connected" });
369
+ }
362
370
  }
363
371
  }
364
372
 
package/src/web/views.ts CHANGED
@@ -208,7 +208,7 @@ function renderProjectsSessionsSection(ctx: ViewContext, sessions: SessionFixtur
208
208
  <summary class="text-xs text-polaris-700 hover:text-polaris-800 font-medium cursor-pointer select-none">+ Join another session</summary>
209
209
  <div class="mt-2 bg-white border border-gray-200 rounded-lg p-4">
210
210
  <p class="text-sm text-gray-500">Inside your AI agent, run:</p>
211
- ${copyBlock("/polaris join &lt;project&gt;")}
211
+ ${copyBlock("/polaris join #channel-name")}
212
212
  </div>
213
213
  </details>
214
214
  <div class="space-y-4">
@@ -231,7 +231,7 @@ function renderProjectsSessionsSection(ctx: ViewContext, sessions: SessionFixtur
231
231
  : "Inside your AI agent (Claude Code, Cursor, etc.), run:"}</p>
232
232
  ${ctx.hasConnectedSession
233
233
  ? ""
234
- : copyBlock("/polaris join my-project")}
234
+ : copyBlock("/polaris join #my-channel")}
235
235
  </div>
236
236
  </div>`);
237
237
  }
package/tests/web.test.ts CHANGED
@@ -38,7 +38,7 @@ describe("renderSetupView", () => {
38
38
  // Install CLI command is present
39
39
  expect(html).toContain("npx @lightupai/polaris");
40
40
  // Connect session command is present
41
- expect(html).toContain("/polaris join my-project");
41
+ expect(html).toContain("/polaris join #my-channel");
42
42
  });
43
43
 
44
44
  test("slack done: floor shows connected, devices is highlighted, sessions grayed", () => {
@@ -66,7 +66,7 @@ describe("renderSetupView", () => {
66
66
  const lastHighlight = html.lastIndexOf("border-polaris-300");
67
67
  expect(lastHighlight).toBeGreaterThan(sessIdx);
68
68
  // Connect session command present
69
- expect(html).toContain("/polaris join my-project");
69
+ expect(html).toContain("/polaris join #my-channel");
70
70
  });
71
71
 
72
72
  test("includes nav with user info", () => {