kojee-mcp 0.5.18 → 0.5.19

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.
@@ -35,7 +35,7 @@ function startEventLog(opts) {
35
35
  const statusMaxBytes = opts.statusMaxBytes ?? DEFAULT_STATUS_MAX_BYTES;
36
36
  fs.mkdirSync(dir, { recursive: true });
37
37
  let filePath = path.join(dir, `kojee-events-${opts.key}.log`);
38
- if (opts.key.startsWith("wd-") && livePathOwnedBySibling(filePath)) {
38
+ if (livePathOwnedBySibling(filePath)) {
39
39
  filePath = path.join(dir, `kojee-events-${opts.key}-${process.pid}.log`);
40
40
  }
41
41
  const statusPath = statusLogPath(filePath);
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  GatewayClient,
6
6
  applyStableSessionId
7
- } from "./chunk-34IRTWP6.js";
7
+ } from "./chunk-U4MNICQI.js";
8
8
  import {
9
9
  AuthModule
10
10
  } from "./chunk-JXMVZEQ7.js";
@@ -186,9 +186,9 @@ async function startProxy(config) {
186
186
  console.error(
187
187
  `[kojee-mcp] Ready \u2014 ${registry.toolCount} tools available from ${config.url}`
188
188
  );
189
- if (instanceKey.startsWith("wd-")) {
189
+ if (instanceKey.startsWith("mint-")) {
190
190
  console.error(
191
- "[kojee-mcp] degraded per-window fidelity: no per-window session id \u2014 two concurrent windows in the same project dir share ONE seat. Set KOJEE_INSTANCE=<unique-per-window> to keep them distinct."
191
+ "[kojee-mcp] no stable session identity \u2014 minted a fresh per-launch seat (re-seats on restart). Set KOJEE_INSTANCE=<stable-per-session-value> for a restart-stable seat (required for daemons like Hermes)."
192
192
  );
193
193
  }
194
194
  let activeStreamHandle = null;
@@ -238,7 +238,7 @@ async function startProxy(config) {
238
238
  }
239
239
  console.error(`[kojee-mcp] Tandem memberships: ${tandemMembershipCount === -1 ? "unknown" : tandemMembershipCount}`);
240
240
  let server;
241
- const { selectDelivery } = await import("./registry-LBWRSM5Z.js");
241
+ const { selectDelivery } = await import("./registry-CGLE5X54.js");
242
242
  const delivery = selectDelivery(adapter.runtime, {
243
243
  supportsChannels: adapter.supportsChannels
244
244
  });
@@ -9,9 +9,6 @@ import {
9
9
  translateJsonRpcError,
10
10
  translateNetworkError
11
11
  } from "./chunk-2OLXXOT3.js";
12
- import {
13
- findClaudeAncestorPid
14
- } from "./chunk-VHKPWUX7.js";
15
12
 
16
13
  // src/gateway-client.ts
17
14
  import crypto from "crypto";
@@ -190,70 +187,28 @@ var GatewayClient = class {
190
187
  };
191
188
 
192
189
  // src/runtime/cc-session-id.ts
193
- import fs from "fs";
194
- import { execFileSync } from "child_process";
195
- import { createHash } from "crypto";
196
- var CC_SESSION_ENV = "CLAUDE_CODE_SESSION_ID";
197
- function extractCcSessionId(raw) {
198
- if (raw.includes("\0")) {
199
- for (const entry of raw.split("\0")) {
200
- if (entry.startsWith(`${CC_SESSION_ENV}=`)) {
201
- const v = entry.slice(CC_SESSION_ENV.length + 1);
202
- return v.length > 0 ? v : null;
203
- }
204
- }
205
- return null;
206
- }
207
- const re = new RegExp(`(?:^|\\s)${CC_SESSION_ENV}=([^\\s]+)`, "g");
208
- let last = null;
209
- let m;
210
- while ((m = re.exec(raw)) !== null) last = m[1];
211
- return last;
212
- }
213
- function defaultReadProcessEnvRaw(pid, platform) {
214
- try {
215
- if (platform === "linux") {
216
- return fs.readFileSync(`/proc/${pid}/environ`, "utf8");
217
- }
218
- if (platform === "darwin") {
219
- return execFileSync("ps", ["eww", "-p", String(pid), "-o", "command="], {
220
- encoding: "utf8",
221
- timeout: 2e3
222
- });
223
- }
224
- } catch {
225
- return null;
226
- }
227
- return null;
228
- }
190
+ import { randomUUID } from "crypto";
191
+ var SESSION_ID_ENV_VARS = ["CLAUDE_CODE_SESSION_ID"];
229
192
  function sanitizeKey(value) {
230
193
  return value.replace(/[^A-Za-z0-9_-]/g, "");
231
194
  }
232
195
  function resolveInstanceKey(deps = {}) {
233
196
  const env = deps.env ?? process.env;
234
- const platform = deps.platform ?? process.platform;
235
- const ccPid = deps.ccPid ?? null;
236
- if (ccPid !== null) {
237
- const reader = deps.readProcessEnvRaw ?? defaultReadProcessEnvRaw;
238
- const raw = reader(ccPid, platform);
239
- if (raw) {
240
- const sid = sanitizeKey(extractCcSessionId(raw) ?? "");
241
- if (sid) return sid;
242
- }
197
+ for (const name of SESSION_ID_ENV_VARS) {
198
+ const sid = sanitizeKey((env[name] ?? "").trim());
199
+ if (sid) return sid;
243
200
  }
244
201
  const explicit = sanitizeKey((env.KOJEE_INSTANCE ?? "").trim());
245
202
  if (explicit) return `inst-${explicit}`;
246
- const base = deps.projectDir ?? env.CLAUDE_PROJECT_DIR ?? deps.cwd ?? process.cwd() ?? "";
247
- const hash = createHash("sha256").update(base).digest("hex").slice(0, 12);
248
- return `wd-${hash}`;
203
+ const mint = deps.randomUUID ?? randomUUID;
204
+ return `mint-${mint()}`;
249
205
  }
250
206
 
251
207
  // src/runtime/stable-session.ts
252
208
  async function applyStableSessionId(token, deps = {}) {
253
209
  let instanceKey = deps.instanceKey;
254
210
  if (instanceKey === void 0) {
255
- const ccPid = deps.ccPid !== void 0 ? deps.ccPid : await findClaudeAncestorPid();
256
- instanceKey = resolveInstanceKey({ ccPid });
211
+ instanceKey = resolveInstanceKey({ env: deps.env });
257
212
  }
258
213
  const sessionId = deriveStableSessionId(token, instanceKey);
259
214
  setStableSessionId(sessionId);
package/dist/cli.js CHANGED
@@ -4,12 +4,12 @@ import {
4
4
  } from "./chunk-OGHDTFAX.js";
5
5
  import {
6
6
  startProxy
7
- } from "./chunk-TN45ULEB.js";
7
+ } from "./chunk-PSVVRGJC.js";
8
8
  import "./chunk-XXFVWP6H.js";
9
9
  import {
10
10
  pairedConfigPath
11
11
  } from "./chunk-YH27B6SW.js";
12
- import "./chunk-34IRTWP6.js";
12
+ import "./chunk-U4MNICQI.js";
13
13
  import "./chunk-JXMVZEQ7.js";
14
14
  import "./chunk-NR4Y54OL.js";
15
15
  import {
@@ -44,7 +44,7 @@ program.command("pair <code>").description("Pair this machine against Kojee usin
44
44
  });
45
45
  program.command("hook").description("Run a kojee MCP hook script (called by Claude Code via ~/.claude/settings.json)").requiredOption("--type <type>", "Hook type: stop, user-prompt-submit, or codex-stop").action(async (opts) => {
46
46
  if (opts.type === "stop") {
47
- const { runStopHook } = await import("./stop-hook-YAVJ3EJD.js");
47
+ const { runStopHook } = await import("./stop-hook-QZTFH5WV.js");
48
48
  await runStopHook();
49
49
  process.exit(0);
50
50
  } else if (opts.type === "user-prompt-submit") {
@@ -78,7 +78,7 @@ Restart Claude Code for hooks to take effect.`
78
78
  program.command("send <tandem_id>").description(
79
79
  "Send a Tandem message using this machine's paired credentials (~/.kojee). Prints one JSON envelope to stdout: {ok, message_id, cursor, text} on success, {ok:false, error:<typed code>, message} on failure (exit 1)."
80
80
  ).requiredOption("--body <text>", "Message body (required)").option("--reply-to <message_id>", "Message id this send replies to").option("--kind <kind>", "Message kind: message | status (default: backend default)").action(async (tandemId, opts) => {
81
- const { runSendCli } = await import("./send-cli-T6RPZZQ4.js");
81
+ const { runSendCli } = await import("./send-cli-IPADRDD2.js");
82
82
  const { exitCode, envelope } = await runSendCli({
83
83
  tandemId,
84
84
  body: opts.body,
@@ -89,7 +89,7 @@ program.command("send <tandem_id>").description(
89
89
  process.exit(exitCode);
90
90
  });
91
91
  program.command("tail <path>").description("Stream a file's contents and follow appends (portable replacement for `tail -F`)").action(async (filePath) => {
92
- const { runTail } = await import("./tail-stream-5DAVRQYK.js");
92
+ const { runTail } = await import("./tail-stream-CEJZGSIR.js");
93
93
  try {
94
94
  await runTail(filePath);
95
95
  } catch (err) {
@@ -98,7 +98,7 @@ program.command("tail <path>").description("Stream a file's contents and follow
98
98
  }
99
99
  });
100
100
  program.command("doctor").description("Diagnose the kojee wake path (proxy, hook-server, SSE stream, event log, Monitor) and print the exact wake recipe").action(async () => {
101
- const { runDoctor } = await import("./doctor-DVPT2ZRH.js");
101
+ const { runDoctor } = await import("./doctor-U3MTB4GY.js");
102
102
  const code = await runDoctor();
103
103
  process.exit(code);
104
104
  });
@@ -2,7 +2,7 @@ import "./chunk-XLKGPGZT.js";
2
2
  import {
3
3
  monitorHeartbeatPath,
4
4
  statusLogPath
5
- } from "./chunk-CO73VGWM.js";
5
+ } from "./chunk-DURRQDYI.js";
6
6
  import {
7
7
  discoveryPathForKey,
8
8
  readSessionDiscoveryByKey,
@@ -5,7 +5,7 @@ import {
5
5
  startEventLog,
6
6
  statusLogPath,
7
7
  sweepStaleEventLogs
8
- } from "./chunk-CO73VGWM.js";
8
+ } from "./chunk-DURRQDYI.js";
9
9
  import "./chunk-DO42NPNR.js";
10
10
  import "./chunk-BLEGIR35.js";
11
11
  export {
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  listTandemIds,
3
3
  startProxy
4
- } from "./chunk-TN45ULEB.js";
4
+ } from "./chunk-PSVVRGJC.js";
5
5
  import "./chunk-XXFVWP6H.js";
6
- import "./chunk-34IRTWP6.js";
6
+ import "./chunk-U4MNICQI.js";
7
7
  import "./chunk-JXMVZEQ7.js";
8
8
  import "./chunk-NR4Y54OL.js";
9
9
  import "./chunk-CH32ELFX.js";
package/dist/lib.d.ts CHANGED
@@ -440,13 +440,16 @@ declare function resubscribeMemberships(opts: ResubscribeOptions): Promise<numbe
440
440
 
441
441
  interface StableSessionDeps {
442
442
  /**
443
- * The Claude Code ancestor PID, when the caller already has it (the daemon).
444
- * Pass `null` to SKIP the ancestry read (non-CC contexts, tests) — resolution
445
- * then falls to KOJEE_INSTANCE → working-dir hash. Omit to resolve ancestry.
443
+ * DEPRECATED / IGNORED. The resolver no longer reads process ancestry — it
444
+ * reads the runtime's session id from the proxy's OWN env (see
445
+ * {@link resolveInstanceKey}). Accepted only so callers that still pass
446
+ * `{ ccPid }` keep compiling; it has no effect on resolution.
446
447
  */
447
448
  ccPid?: number | null;
449
+ /** Environment for {@link resolveInstanceKey} (defaults to `process.env`). Tests pin it. */
450
+ env?: NodeJS.ProcessEnv;
448
451
  /**
449
- * An explicit instanceKey — bypasses ancestry AND resolveInstanceKey entirely.
452
+ * An explicit instanceKey — bypasses {@link resolveInstanceKey} entirely.
450
453
  * Used where the window identity is known out-of-band (an embedder's account
451
454
  * key, tests).
452
455
  */
@@ -459,10 +462,10 @@ interface StableSessionDeps {
459
462
  * same id → the backend converges on ONE seat per (credential, window) across
460
463
  * restarts (no phantom seats; reaper retired).
461
464
  *
462
- * instanceKey precedence: an explicit `deps.instanceKey` wins; otherwise it's
463
- * resolved by {@link resolveInstanceKey} from `deps.ccPid` (or a fresh ancestry
464
- * read when `ccPid` is omitted) → CC session id, else KOJEE_INSTANCE, else a
465
- * working-dir hash.
465
+ * instanceKey precedence: an explicit `deps.instanceKey` wins; otherwise
466
+ * {@link resolveInstanceKey} resolves it from the proxy's OWN env → the runtime
467
+ * session id (e.g. CLAUDE_CODE_SESSION_ID), else KOJEE_INSTANCE, else a minted
468
+ * per-launch id. (No process-ancestry read, no directory hash — both removed.)
466
469
  *
467
470
  * Returns the resolved instanceKey + the installed sessionId so callers that
468
471
  * also need the key (room-memory, discovery) don't resolve it twice.
@@ -565,9 +568,10 @@ interface ToolCallHooks {
565
568
  */
566
569
  interface WakeDeliveryContext {
567
570
  /**
568
- * This instance's stable key (#28): the CC session_id when readable, else
569
- * KOJEE_INSTANCE / a working-dir hash. Used to derive the per-runtime
570
- * event-log filename and other per-session artifacts.
571
+ * This instance's stable key (#28): the runtime's own-env session id, else
572
+ * `inst-<KOJEE_INSTANCE>`, else a minted `mint-<uuid>` (see `resolveInstanceKey`).
573
+ * Used to derive the per-runtime event-log filename and other per-session
574
+ * artifacts.
571
575
  */
572
576
  instanceKey: string;
573
577
  /** The detected runtime label (drives capability + which delivery is built). */
package/dist/lib.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  GatewayClient,
15
15
  applyStableSessionId
16
- } from "./chunk-34IRTWP6.js";
16
+ } from "./chunk-U4MNICQI.js";
17
17
  import {
18
18
  AuthModule
19
19
  } from "./chunk-JXMVZEQ7.js";
@@ -30,7 +30,6 @@ import {
30
30
  } from "./chunk-CH32ELFX.js";
31
31
  import "./chunk-BLEGIR35.js";
32
32
  import "./chunk-2OLXXOT3.js";
33
- import "./chunk-VHKPWUX7.js";
34
33
  export {
35
34
  AuthModule,
36
35
  GatewayClient,
@@ -97,7 +97,7 @@ function createClaudeCodeDelivery() {
97
97
  cleanupDiscoveryByKey,
98
98
  sweepStaleDiscovery
99
99
  } = await import("./session-discovery-FNMJGFPM.js");
100
- const { startEventLog, sweepStaleEventLogs } = await import("./event-log-VZD7NKYX.js");
100
+ const { startEventLog, sweepStaleEventLogs } = await import("./event-log-HOBO3ECB.js");
101
101
  const { resubscribeMemberships } = await import("./resubscribe-G5OGDZJD.js");
102
102
  const { resolveWebhookConfig } = await import("./webhook-config-O4WMQ532.js");
103
103
  const { createWebhookSink } = await import("./webhook-sink-N6AUTFL3.js");
@@ -274,7 +274,7 @@ function createWebhookDelivery(name) {
274
274
  return {
275
275
  name,
276
276
  async start(ctx) {
277
- const { startEventLog, sweepStaleEventLogs } = await import("./event-log-VZD7NKYX.js");
277
+ const { startEventLog, sweepStaleEventLogs } = await import("./event-log-HOBO3ECB.js");
278
278
  const { resolveWebhookConfig } = await import("./webhook-config-O4WMQ532.js");
279
279
  const { createWebhookSink } = await import("./webhook-sink-N6AUTFL3.js");
280
280
  const { resubscribeMemberships } = await import("./resubscribe-G5OGDZJD.js");
@@ -10,14 +10,13 @@ import {
10
10
  import {
11
11
  GatewayClient,
12
12
  applyStableSessionId
13
- } from "./chunk-34IRTWP6.js";
13
+ } from "./chunk-U4MNICQI.js";
14
14
  import "./chunk-NR4Y54OL.js";
15
15
  import {
16
16
  loadKeystore
17
17
  } from "./chunk-CH32ELFX.js";
18
18
  import "./chunk-BLEGIR35.js";
19
19
  import "./chunk-2OLXXOT3.js";
20
- import "./chunk-VHKPWUX7.js";
21
20
 
22
21
  // src/tandem/send-cli.ts
23
22
  import os from "os";
@@ -8,7 +8,7 @@ import {
8
8
  import {
9
9
  monitorHeartbeatPath,
10
10
  nudgeSentinelPath
11
- } from "./chunk-CO73VGWM.js";
11
+ } from "./chunk-DURRQDYI.js";
12
12
  import {
13
13
  readSessionDiscoveryByKey
14
14
  } from "./chunk-DO42NPNR.js";
@@ -3,7 +3,7 @@ import {
3
3
  STATUS_LINE_PREFIX,
4
4
  monitorHeartbeatPath,
5
5
  statusLogPath
6
- } from "./chunk-CO73VGWM.js";
6
+ } from "./chunk-DURRQDYI.js";
7
7
  import "./chunk-DO42NPNR.js";
8
8
  import {
9
9
  createAdaptiveWatchdog
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kojee-mcp",
3
- "version": "0.5.18",
3
+ "version": "0.5.19",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "exports": {