kojee-mcp 0.5.7 → 0.5.9

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.
@@ -0,0 +1,20 @@
1
+ // src/hooks/format-channel.ts
2
+ function sanitizeChannelAttr(value) {
3
+ return String(value ?? "").replace(/["<>\u0000-\u001f\u007f]/g, "");
4
+ }
5
+ function formatChannelEvents(events) {
6
+ const header = `[${events.length} unread Tandem ${events.length === 1 ? "event" : "events"}]
7
+
8
+ `;
9
+ const bodies = events.map((evt) => {
10
+ const attrs = Object.entries(evt.meta).map(([k, v]) => `${k}="${sanitizeChannelAttr(v)}"`).join(" ");
11
+ return `<channel source="kojee-mcp" ${attrs}>
12
+ ${evt.content}
13
+ </channel>`;
14
+ });
15
+ return header + bodies.join("\n\n");
16
+ }
17
+
18
+ export {
19
+ formatChannelEvents
20
+ };
@@ -9,13 +9,13 @@ import {
9
9
  } from "./chunk-BJMASMKX.js";
10
10
  import {
11
11
  AuthModule
12
- } from "./chunk-6SK6ITFE.js";
12
+ } from "./chunk-JXMVZEQ7.js";
13
13
  import {
14
14
  GatewayClient
15
- } from "./chunk-3XDJOHMZ.js";
15
+ } from "./chunk-HSR3GXCL.js";
16
16
  import {
17
17
  startEventStream
18
- } from "./chunk-UEGQGXPY.js";
18
+ } from "./chunk-MKDMAAMN.js";
19
19
  import {
20
20
  translateToolCallResult
21
21
  } from "./chunk-LDZXU3DW.js";
@@ -245,6 +245,7 @@ var claudeCodeAdapter = {
245
245
  from_display: event.from.displayname,
246
246
  severity: computeSeverity(event)
247
247
  };
248
+ if (event.wake_reason) meta.wake_reason = event.wake_reason;
248
249
  return { content: formatBody(event), meta };
249
250
  }
250
251
  };
@@ -377,7 +378,7 @@ async function startProxy(config) {
377
378
  cleanupDiscoveryByKey,
378
379
  sweepStaleDiscovery
379
380
  } = await import("./session-discovery-FNMJGFPM.js");
380
- const { startEventLog, sweepStaleEventLogs } = await import("./event-log-RSTM4PLL.js");
381
+ const { startEventLog, sweepStaleEventLogs } = await import("./event-log-B27VVEMK.js");
381
382
  const { resubscribeMemberships } = await import("./resubscribe-G5OGDZJD.js");
382
383
  const { resolveWebhookConfig } = await import("./webhook-config-O4WMQ532.js");
383
384
  const { createWebhookSink } = await import("./webhook-sink-NWGCUDGY.js");
@@ -514,7 +515,7 @@ async function startProxy(config) {
514
515
  activeStreamHandle = streamHandle;
515
516
  joinReconnect.notifyReady();
516
517
  } else if (needsWebhookEventStream()) {
517
- const { startEventLog, sweepStaleEventLogs } = await import("./event-log-RSTM4PLL.js");
518
+ const { startEventLog, sweepStaleEventLogs } = await import("./event-log-B27VVEMK.js");
518
519
  const { resolveWebhookConfig } = await import("./webhook-config-O4WMQ532.js");
519
520
  const { createWebhookSink } = await import("./webhook-sink-NWGCUDGY.js");
520
521
  const { resubscribeMemberships } = await import("./resubscribe-G5OGDZJD.js");
package/dist/cli.js CHANGED
@@ -1,71 +1,30 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ runPair
4
+ } from "./chunk-OGHDTFAX.js";
2
5
  import {
3
6
  VERSION,
4
7
  startProxy
5
- } from "./chunk-GATXJ6UT.js";
8
+ } from "./chunk-SCDWPGH3.js";
6
9
  import "./chunk-X672ZN7V.js";
7
10
  import "./chunk-BJMASMKX.js";
8
11
  import {
9
- loadPairedConfig,
10
- pairedConfigPath,
11
- savePairedConfig
12
+ pairedConfigPath
12
13
  } from "./chunk-YH27B6SW.js";
13
- import {
14
- AuthModule
15
- } from "./chunk-6SK6ITFE.js";
14
+ import "./chunk-JXMVZEQ7.js";
15
+ import "./chunk-HSR3GXCL.js";
16
+ import "./chunk-MKDMAAMN.js";
17
+ import "./chunk-2MIISF2W.js";
16
18
  import {
17
19
  defaultPairedKeystorePath,
18
20
  deriveKeystorePath
19
- } from "./chunk-3XDJOHMZ.js";
20
- import "./chunk-UEGQGXPY.js";
21
- import "./chunk-2MIISF2W.js";
22
- import "./chunk-LDZXU3DW.js";
21
+ } from "./chunk-CH32ELFX.js";
23
22
  import "./chunk-BLEGIR35.js";
23
+ import "./chunk-LDZXU3DW.js";
24
24
 
25
25
  // src/cli.ts
26
26
  import { Command } from "commander";
27
27
  import path from "path";
28
-
29
- // src/tandem/pair.ts
30
- import fs from "fs";
31
- async function runPair(opts) {
32
- if (loadPairedConfig(opts.configPath) !== null) {
33
- throw new Error(
34
- `Already paired (config exists at ${opts.configPath}). To re-pair this slot, delete the config file first. For a second account, use --keystore-path /custom/keypair.json.`
35
- );
36
- }
37
- try {
38
- fs.unlinkSync(opts.keystorePath);
39
- } catch {
40
- }
41
- const auth = new AuthModule(opts.code, opts.url, opts.keystorePath);
42
- await auth.ensureEnrolled();
43
- let principal_id;
44
- let agent_id;
45
- try {
46
- const me = await fetch(`${opts.url}/api/v1/users/me/`, {
47
- headers: { Authorization: `DPoP ${opts.code}` }
48
- });
49
- if (me.ok) {
50
- const body = await me.json();
51
- principal_id = body.principal_id;
52
- agent_id = body.agent_id;
53
- }
54
- } catch {
55
- }
56
- const config = {
57
- token: opts.code,
58
- broker_url: opts.url,
59
- paired_at: (/* @__PURE__ */ new Date()).toISOString(),
60
- ...principal_id ? { principal_id } : {},
61
- ...agent_id ? { agent_id } : {}
62
- };
63
- savePairedConfig(opts.configPath, config);
64
- const who = principal_id && agent_id ? `${principal_id} (${agent_id})` : "(use kojee-mcp without args to start the proxy)";
65
- return { message: `Paired as ${who}. Keypair: ${opts.keystorePath}. Config: ${opts.configPath}.` };
66
- }
67
-
68
- // src/cli.ts
69
28
  var program = new Command().name("kojee-mcp").description(
70
29
  "Local MCP proxy for Kojee \u2014 handles DPoP auth, tool discovery, and governance transparently"
71
30
  ).version(VERSION).enablePositionalOptions();
@@ -83,11 +42,11 @@ program.command("pair <code>").description("Pair this machine against Kojee usin
83
42
  });
84
43
  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) => {
85
44
  if (opts.type === "stop") {
86
- const { runStopHook } = await import("./stop-hook-46BJD55B.js");
45
+ const { runStopHook } = await import("./stop-hook-GEJF47SN.js");
87
46
  await runStopHook();
88
47
  process.exit(0);
89
48
  } else if (opts.type === "user-prompt-submit") {
90
- const { runUserPromptSubmitHook } = await import("./user-prompt-submit-hook-ZD2XKN7U.js");
49
+ const { runUserPromptSubmitHook } = await import("./user-prompt-submit-hook-DGRRFHOB.js");
91
50
  await runUserPromptSubmitHook();
92
51
  process.exit(0);
93
52
  } else if (opts.type === "codex-stop") {
@@ -100,7 +59,7 @@ program.command("hook").description("Run a kojee MCP hook script (called by Clau
100
59
  }
101
60
  });
102
61
  program.command("install-hooks").description("Install kojee Stop + UserPromptSubmit hooks in ~/.claude/settings.json (idempotent)").option("--hooks-path <path>", "Override default ~/.claude/settings.json").option("--uninstall", "Remove kojee hook entries instead of installing them").action(async (opts) => {
103
- const { installHooks, uninstallHooks } = await import("./install-WBIUVBZW.js");
62
+ const { installHooks, uninstallHooks } = await import("./install-LJY2CHKG.js");
104
63
  if (opts.uninstall) {
105
64
  const removed = uninstallHooks({ hooksPath: opts.hooksPath });
106
65
  console.error(removed ? "Removed kojee hook entries." : "No kojee hook entries found.");
@@ -117,7 +76,7 @@ Restart Claude Code for hooks to take effect.`
117
76
  program.command("send <tandem_id>").description(
118
77
  "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)."
119
78
  ).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) => {
120
- const { runSendCli } = await import("./send-cli-C2F4WTBN.js");
79
+ const { runSendCli } = await import("./send-cli-CN5EX7PO.js");
121
80
  const { exitCode, envelope } = await runSendCli({
122
81
  tandemId,
123
82
  body: opts.body,
@@ -128,7 +87,7 @@ program.command("send <tandem_id>").description(
128
87
  process.exit(exitCode);
129
88
  });
130
89
  program.command("tail <path>").description("Stream a file's contents and follow appends (portable replacement for `tail -F`)").action(async (filePath) => {
131
- const { runTail } = await import("./tail-stream-VUZBYKXS.js");
90
+ const { runTail } = await import("./tail-stream-JNR4WFW3.js");
132
91
  try {
133
92
  await runTail(filePath);
134
93
  } catch (err) {
@@ -137,13 +96,13 @@ program.command("tail <path>").description("Stream a file's contents and follow
137
96
  }
138
97
  });
139
98
  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 () => {
140
- const { runDoctor } = await import("./doctor-QCQDFLEH.js");
99
+ const { runDoctor } = await import("./doctor-XK335W7B.js");
141
100
  const code = await runDoctor();
142
101
  process.exit(code);
143
102
  });
144
103
  program.command("init").description(
145
104
  "Set up kojee for a runtime (claude-code | hermes | openclaw | codex). Interactive when stdin is a TTY; `--runtime <id>` for non-interactive/CI. Run after `kojee-mcp pair`."
146
- ).option("--runtime <id>", "Target runtime: claude-code | hermes | openclaw | codex").option("--config-path <path>", "Override the runtime's MCP-config path").option("--hooks-path <path>", "Override the runtime's hooks-file path").option("--webhook-url <url>", "Webhook receiver URL (codex/hermes/openclaw)").option("--webhook-secret <secret>", "Webhook HMAC secret (generated if omitted)").option(
105
+ ).option("--runtime <id>", "Target runtime: claude-code | hermes | openclaw | codex").option("--config-path <path>", "Override the runtime's MCP-config path").option("--hooks-path <path>", "Override the runtime's hooks-file path").option("--token <token>", "Gateway token \u2014 token mode (writes --token/--url into the MCP config)").option("--url <url>", "Broker base URL (token mode / pair URL; default https://rosie-staging.kojee.net)").option("--pair-code <code>", "Pair code \u2014 runs the pair flow (writes ~/.kojee/config.json) before configuring").option("--webhook-url <url>", "Webhook receiver URL (codex/hermes/openclaw)").option("--webhook-secret <secret>", "Webhook HMAC secret (generated if omitted)").option(
147
106
  "--webhook-signature-format <preset>",
148
107
  'Signature preset: "github" = header X-Hub-Signature-256, value sha256=<hex> (default: bare hex in X-Kojee-Signature)'
149
108
  ).option(
@@ -153,43 +112,98 @@ program.command("init").description(
153
112
  "--webhook-signature-prefix <prefix>",
154
113
  "Literal string prepended to the hex digest (default empty; overrides the preset's prefix)"
155
114
  ).option("--uninstall", "Remove the kojee config for the chosen (or recorded) runtime").action(async (opts) => {
156
- const { loadPairedConfig: loadPairedConfig2 } = await import("./paired-config-JTFLHMZ2.js");
157
- if (loadPairedConfig2() === null && !opts.uninstall) {
158
- console.error("Not paired. Run `kojee-mcp pair <code> --url <broker>` first, then re-run `init`.");
115
+ const interactive = process.stdin.isTTY === true && opts.runtime === void 0;
116
+ if (opts.pairCode && !opts.uninstall) {
117
+ const { runPair: runPair2 } = await import("./pair-P4ILCMT7.js");
118
+ const { pairedConfigPath: pairedConfigPath2 } = await import("./paired-config-JTFLHMZ2.js");
119
+ const { defaultPairedKeystorePath: defaultPairedKeystorePath2 } = await import("./keystore-XLEV3FL5.js");
120
+ const url = (opts.url ?? "https://rosie-staging.kojee.net").replace(/\/+$/, "");
121
+ try {
122
+ const r = await runPair2({
123
+ code: opts.pairCode,
124
+ url,
125
+ keystorePath: defaultPairedKeystorePath2(),
126
+ configPath: pairedConfigPath2()
127
+ });
128
+ console.error(r.message);
129
+ } catch (err) {
130
+ console.error("[kojee-mcp init] Pairing failed:", err.message);
131
+ process.exit(1);
132
+ }
133
+ }
134
+ const { loadPairedConfig } = await import("./paired-config-JTFLHMZ2.js");
135
+ const hasCredential = loadPairedConfig() !== null || opts.token !== void 0;
136
+ if (!hasCredential && !interactive && !opts.uninstall) {
137
+ console.error("Not paired. Run `kojee-mcp pair <code> --url <broker>` first, then re-run `init` \u2014 or pass --token/--pair-code, or run `init` in a terminal for the guided wizard.");
159
138
  process.exit(1);
160
139
  }
161
- const { runWizard } = await import("./wizard-UOXQYJLP.js");
162
- const interactive = process.stdin.isTTY === true && opts.runtime === void 0;
140
+ const { runWizard } = await import("./wizard-PLGHYCT3.js");
163
141
  const result = await runWizard({
164
142
  ...opts.runtime !== void 0 ? { runtime: opts.runtime } : {},
165
143
  ...opts.uninstall ? { uninstall: true } : {},
166
144
  ...opts.configPath ? { configPath: opts.configPath } : {},
167
145
  ...opts.hooksPath ? { hooksPath: opts.hooksPath } : {},
146
+ // Token-mode threading (token + url ⇒ --token/--url in the written config).
147
+ // Normalize the URL exactly like the proxy action does (strip trailing /).
148
+ ...opts.token ? { token: opts.token } : {},
149
+ ...opts.url ? { url: opts.url.replace(/\/+$/, "") } : {},
168
150
  ...opts.webhookUrl ? { webhookUrl: opts.webhookUrl } : {},
169
151
  ...opts.webhookSecret ? { webhookSecret: opts.webhookSecret } : {},
170
152
  ...opts.webhookSignatureFormat ? { webhookSignatureFormat: opts.webhookSignatureFormat } : {},
171
153
  ...opts.webhookSignatureHeader ? { webhookSignatureHeader: opts.webhookSignatureHeader } : {},
172
154
  ...opts.webhookSignaturePrefix !== void 0 ? { webhookSignaturePrefix: opts.webhookSignaturePrefix } : {},
173
155
  interactive,
174
- ...interactive ? { promptRuntime: promptRuntimeFromTty } : {}
156
+ ...interactive ? {
157
+ promptRuntime: promptRuntimeFromTty,
158
+ promptUrl: promptUrlFromTty,
159
+ promptAuth: promptAuthFromTty,
160
+ promptToken: promptTokenFromTty,
161
+ promptPairCode: promptPairCodeFromTty,
162
+ promptWebhookUrl: promptWebhookUrlFromTty
163
+ } : {}
175
164
  });
176
165
  console.error(result.output);
177
166
  process.exit(result.exitCode);
178
167
  });
179
- async function promptRuntimeFromTty() {
180
- const { RUNTIME_MENU } = await import("./runtimes-CO43XUUK.js");
168
+ async function withReadline(fn) {
181
169
  const readline = await import("readline/promises");
182
170
  const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
183
171
  try {
172
+ return await fn((q) => rl.question(q));
173
+ } finally {
174
+ rl.close();
175
+ }
176
+ }
177
+ async function promptRuntimeFromTty() {
178
+ const { RUNTIME_MENU } = await import("./runtimes-CO43XUUK.js");
179
+ return withReadline(async (ask) => {
184
180
  const menu = RUNTIME_MENU.map((m) => `[${m.index}] ${m.runtime}`).join(" ");
185
- const answer = (await rl.question(`Which runtime is this proxy for? ${menu}
181
+ const answer = (await ask(`Which runtime is this proxy for? ${menu}
186
182
  > `)).trim();
187
183
  const byIndex = RUNTIME_MENU.find((m) => String(m.index) === answer);
188
184
  if (byIndex) return byIndex.runtime;
189
185
  return answer;
190
- } finally {
191
- rl.close();
192
- }
186
+ });
187
+ }
188
+ async function promptUrlFromTty(defaultUrl) {
189
+ return withReadline((ask) => ask(`Broker URL [${defaultUrl}]
190
+ > `));
191
+ }
192
+ async function promptAuthFromTty() {
193
+ return withReadline(async (ask) => {
194
+ const answer = (await ask("Auth: [1] paste a token [2] enter a pair code\n> ")).trim().toLowerCase();
195
+ if (answer === "2" || answer.startsWith("p")) return "pair";
196
+ return "token";
197
+ });
198
+ }
199
+ async function promptTokenFromTty() {
200
+ return withReadline((ask) => ask("Paste your gateway token:\n> "));
201
+ }
202
+ async function promptPairCodeFromTty() {
203
+ return withReadline((ask) => ask("Enter your pair code (from the dashboard):\n> "));
204
+ }
205
+ async function promptWebhookUrlFromTty() {
206
+ return withReadline((ask) => ask("Webhook receiver URL (press Enter to skip and set it up later):\n> "));
193
207
  }
194
208
  program.option("--token <token>", "Gateway token (for token-mode)").option("--url <url>", "Broker base URL (for token-mode; required if --token is passed)").option(
195
209
  "--keystore-path <path>",
@@ -207,8 +221,8 @@ program.option("--token <token>", "Gateway token (for token-mode)").option("--ur
207
221
  url = url.replace(/\/+$/, "");
208
222
  keystorePath ??= deriveKeystorePath(token);
209
223
  } else {
210
- const { loadPairedConfig: loadPairedConfig2 } = await import("./paired-config-JTFLHMZ2.js");
211
- const cfg = loadPairedConfig2();
224
+ const { loadPairedConfig } = await import("./paired-config-JTFLHMZ2.js");
225
+ const cfg = loadPairedConfig();
212
226
  if (!cfg) {
213
227
  console.error(
214
228
  "No --token provided and no ~/.kojee/config.json found. Run `kojee-mcp pair <code> --url <broker>` first."
@@ -1,7 +1,11 @@
1
1
  import {
2
2
  monitorHeartbeatPath,
3
3
  statusLogPath
4
- } from "./chunk-2TUAFAIW.js";
4
+ } from "./chunk-DS26OORG.js";
5
+ import {
6
+ discoveryPathForKey,
7
+ readSessionDiscoveryByKey
8
+ } from "./chunk-DO42NPNR.js";
5
9
  import {
6
10
  loadControlToken
7
11
  } from "./chunk-GI2CKKBL.js";
@@ -16,10 +20,6 @@ import {
16
20
  import {
17
21
  loadPairedConfig
18
22
  } from "./chunk-YH27B6SW.js";
19
- import {
20
- discoveryPathForKey,
21
- readSessionDiscoveryByKey
22
- } from "./chunk-DO42NPNR.js";
23
23
  import "./chunk-BLEGIR35.js";
24
24
 
25
25
  // src/doctor.ts
@@ -233,7 +233,7 @@ function formatDoctorReport(report) {
233
233
  async function runDoctor() {
234
234
  const { readRecordedRuntime } = await import("./runtime-record-WO4IECM6.js");
235
235
  if (readRecordedRuntime() === "codex") {
236
- const { collectCodexDoctorReport, formatCodexDoctorReport } = await import("./doctor-codex-NZ53ROQA.js");
236
+ const { collectCodexDoctorReport, formatCodexDoctorReport } = await import("./doctor-codex-SMROUYGV.js");
237
237
  const report2 = collectCodexDoctorReport();
238
238
  console.error(formatCodexDoctorReport(report2));
239
239
  return report2.verdict === "broken" ? 1 : 0;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  defaultCodexConfigPath,
3
3
  defaultCodexHooksPath
4
- } from "./chunk-64EOLZNI.js";
4
+ } from "./chunk-65KRRDHP.js";
5
5
  import "./chunk-SQL56SEB.js";
6
6
  import {
7
7
  resolveWebhookConfig
@@ -5,7 +5,7 @@ import {
5
5
  startEventLog,
6
6
  statusLogPath,
7
7
  sweepStaleEventLogs
8
- } from "./chunk-2TUAFAIW.js";
8
+ } from "./chunk-DS26OORG.js";
9
9
  import "./chunk-DO42NPNR.js";
10
10
  import "./chunk-BLEGIR35.js";
11
11
  export {
package/dist/index.js CHANGED
@@ -1,15 +1,16 @@
1
1
  import {
2
2
  listTandemIds,
3
3
  startProxy
4
- } from "./chunk-GATXJ6UT.js";
4
+ } from "./chunk-SCDWPGH3.js";
5
5
  import "./chunk-X672ZN7V.js";
6
6
  import "./chunk-BJMASMKX.js";
7
- import "./chunk-6SK6ITFE.js";
8
- import "./chunk-3XDJOHMZ.js";
9
- import "./chunk-UEGQGXPY.js";
7
+ import "./chunk-JXMVZEQ7.js";
8
+ import "./chunk-HSR3GXCL.js";
9
+ import "./chunk-MKDMAAMN.js";
10
10
  import "./chunk-2MIISF2W.js";
11
- import "./chunk-LDZXU3DW.js";
11
+ import "./chunk-CH32ELFX.js";
12
12
  import "./chunk-BLEGIR35.js";
13
+ import "./chunk-LDZXU3DW.js";
13
14
  export {
14
15
  listTandemIds,
15
16
  startProxy
@@ -94,21 +94,28 @@ function uninstallHooks(opts = {}) {
94
94
  writeConfig(p, cfg);
95
95
  return removed;
96
96
  }
97
+ function mcpServerArgs(opts) {
98
+ if (opts.token && opts.url) {
99
+ return [...MCP_SERVER_ARGS, "--token", opts.token, "--url", opts.url];
100
+ }
101
+ return [...MCP_SERVER_ARGS];
102
+ }
97
103
  function installMcpServer(opts = {}) {
98
104
  const p = opts.configPath ?? defaultConfigPath();
99
105
  const cfg = readConfig(p);
100
106
  cfg.mcpServers ??= {};
107
+ const args = mcpServerArgs(opts);
101
108
  const existing = cfg.mcpServers["kojee"];
102
109
  if (existing) {
103
110
  const sameCommand = existing.command === MCP_SERVER_CMD;
104
- const sameArgs = JSON.stringify(existing.args ?? []) === JSON.stringify(MCP_SERVER_ARGS);
111
+ const sameArgs = JSON.stringify(existing.args ?? []) === JSON.stringify(args);
105
112
  const sameEnv = JSON.stringify(existing.env ?? {}) === JSON.stringify(MCP_SERVER_ENV);
106
113
  if (sameCommand && sameArgs && sameEnv) return "already-installed";
107
114
  return "preserved-different";
108
115
  }
109
116
  cfg.mcpServers["kojee"] = {
110
117
  command: MCP_SERVER_CMD,
111
- args: [...MCP_SERVER_ARGS],
118
+ args,
112
119
  env: { ...MCP_SERVER_ENV }
113
120
  };
114
121
  writeConfig(p, cfg);
@@ -135,7 +142,11 @@ function runInit(opts = {}) {
135
142
  reports.push({ kind: t.kind, path: t.path, ...t.hooksPath ? { hooksPath: t.hooksPath } : {}, mcpServer: "not-found" });
136
143
  continue;
137
144
  }
138
- const mcpServer = installMcpServer({ configPath: t.path });
145
+ const mcpServer = installMcpServer({
146
+ configPath: t.path,
147
+ ...opts.token ? { token: opts.token } : {},
148
+ ...opts.url ? { url: opts.url } : {}
149
+ });
139
150
  let stopHook;
140
151
  let upsHook;
141
152
  if (t.kind === "cli") {
@@ -0,0 +1,15 @@
1
+ import {
2
+ defaultPairedKeystorePath,
3
+ deriveKeystorePath,
4
+ generateES256KeyPair,
5
+ loadKeystore,
6
+ saveKeystore
7
+ } from "./chunk-CH32ELFX.js";
8
+ import "./chunk-BLEGIR35.js";
9
+ export {
10
+ defaultPairedKeystorePath,
11
+ deriveKeystorePath,
12
+ generateES256KeyPair,
13
+ loadKeystore,
14
+ saveKeystore
15
+ };
package/dist/lib.d.ts CHANGED
@@ -38,6 +38,8 @@ interface TandemEvent {
38
38
  }>;
39
39
  reply_to?: string | null;
40
40
  severity?: string;
41
+ wake?: boolean;
42
+ wake_reason?: string;
41
43
  }
42
44
 
43
45
  /**
package/dist/lib.js CHANGED
@@ -7,25 +7,27 @@ import {
7
7
  } from "./chunk-YH27B6SW.js";
8
8
  import {
9
9
  AuthModule
10
- } from "./chunk-6SK6ITFE.js";
10
+ } from "./chunk-JXMVZEQ7.js";
11
11
  import {
12
- GatewayClient,
13
- defaultPairedKeystorePath,
14
- deriveKeystorePath,
15
- generateES256KeyPair,
16
- loadKeystore,
17
- saveKeystore
18
- } from "./chunk-3XDJOHMZ.js";
12
+ GatewayClient
13
+ } from "./chunk-HSR3GXCL.js";
19
14
  import {
20
15
  normalizeBackendEvent,
21
16
  sanitizeDisplayname,
22
17
  startEventStream
23
- } from "./chunk-UEGQGXPY.js";
18
+ } from "./chunk-MKDMAAMN.js";
24
19
  import {
25
20
  createDPoPProof
26
21
  } from "./chunk-2MIISF2W.js";
27
- import "./chunk-LDZXU3DW.js";
22
+ import {
23
+ defaultPairedKeystorePath,
24
+ deriveKeystorePath,
25
+ generateES256KeyPair,
26
+ loadKeystore,
27
+ saveKeystore
28
+ } from "./chunk-CH32ELFX.js";
28
29
  import "./chunk-BLEGIR35.js";
30
+ import "./chunk-LDZXU3DW.js";
29
31
  export {
30
32
  AuthModule,
31
33
  GatewayClient,
@@ -0,0 +1,10 @@
1
+ import {
2
+ runPair
3
+ } from "./chunk-OGHDTFAX.js";
4
+ import "./chunk-YH27B6SW.js";
5
+ import "./chunk-JXMVZEQ7.js";
6
+ import "./chunk-CH32ELFX.js";
7
+ import "./chunk-BLEGIR35.js";
8
+ export {
9
+ runPair
10
+ };
@@ -2,17 +2,19 @@ import {
2
2
  loadPairedConfig
3
3
  } from "./chunk-YH27B6SW.js";
4
4
  import {
5
- GatewayClient,
6
- loadKeystore
7
- } from "./chunk-3XDJOHMZ.js";
5
+ GatewayClient
6
+ } from "./chunk-HSR3GXCL.js";
8
7
  import "./chunk-2MIISF2W.js";
8
+ import {
9
+ loadKeystore
10
+ } from "./chunk-CH32ELFX.js";
11
+ import "./chunk-BLEGIR35.js";
9
12
  import {
10
13
  executeSend,
11
14
  parseSendRequest,
12
15
  sendFailure
13
16
  } from "./chunk-HIZ4NDWN.js";
14
17
  import "./chunk-LDZXU3DW.js";
15
- import "./chunk-BLEGIR35.js";
16
18
 
17
19
  // src/tandem/send-cli.ts
18
20
  import os from "os";
@@ -1,10 +1,16 @@
1
+ import {
2
+ formatChannelEvents
3
+ } from "./chunk-PHXO5P25.js";
1
4
  import {
2
5
  readHookStdin
3
6
  } from "./chunk-LSUB6QMP.js";
4
7
  import {
5
8
  monitorHeartbeatPath,
6
9
  nudgeSentinelPath
7
- } from "./chunk-2TUAFAIW.js";
10
+ } from "./chunk-DS26OORG.js";
11
+ import {
12
+ readSessionDiscoveryByKey
13
+ } from "./chunk-DO42NPNR.js";
8
14
  import {
9
15
  controlTokenAuthHeaders
10
16
  } from "./chunk-GI2CKKBL.js";
@@ -15,9 +21,6 @@ import {
15
21
  deriveDiscoveryKey,
16
22
  findClaudeAncestorPid
17
23
  } from "./chunk-BJMASMKX.js";
18
- import {
19
- readSessionDiscoveryByKey
20
- } from "./chunk-DO42NPNR.js";
21
24
  import "./chunk-BLEGIR35.js";
22
25
 
23
26
  // src/hooks/stop-hook.ts
@@ -37,7 +40,7 @@ async function decideStopHook(deps) {
37
40
  if (!deps.discovery) return "{}";
38
41
  const body = await deps.pollEvents().catch(() => null);
39
42
  if (body && body.count > 0) {
40
- return JSON.stringify({ decision: "block", reason: formatEvents(body.events) });
43
+ return JSON.stringify({ decision: "block", reason: formatChannelEvents(body.events) });
41
44
  }
42
45
  const logPath = deps.discovery.eventLogPath;
43
46
  if (logPath && deps.logHasContent(logPath) && !deps.monitorIsLive(logPath)) {
@@ -109,18 +112,6 @@ function monitorIsLive(logPath) {
109
112
  return false;
110
113
  }
111
114
  }
112
- function formatEvents(events) {
113
- const header = `[${events.length} unread Tandem ${events.length === 1 ? "event" : "events"}]
114
-
115
- `;
116
- const bodies = events.map((evt) => {
117
- const attrs = Object.entries(evt.meta).map(([k, v]) => `${k}="${v}"`).join(" ");
118
- return `<channel source="kojee-mcp" ${attrs}>
119
- ${evt.content}
120
- </channel>`;
121
- });
122
- return header + bodies.join("\n\n");
123
- }
124
115
  export {
125
116
  decideStopHook,
126
117
  runStopHook
@@ -2,12 +2,12 @@ import {
2
2
  STATUS_LINE_PREFIX,
3
3
  monitorHeartbeatPath,
4
4
  statusLogPath
5
- } from "./chunk-2TUAFAIW.js";
5
+ } from "./chunk-DS26OORG.js";
6
+ import "./chunk-DO42NPNR.js";
6
7
  import {
7
8
  createAdaptiveWatchdog
8
- } from "./chunk-UEGQGXPY.js";
9
+ } from "./chunk-MKDMAAMN.js";
9
10
  import "./chunk-2MIISF2W.js";
10
- import "./chunk-DO42NPNR.js";
11
11
  import "./chunk-BLEGIR35.js";
12
12
 
13
13
  // src/tail-stream.ts
@@ -1,6 +1,12 @@
1
+ import {
2
+ formatChannelEvents
3
+ } from "./chunk-PHXO5P25.js";
1
4
  import {
2
5
  readHookStdin
3
6
  } from "./chunk-LSUB6QMP.js";
7
+ import {
8
+ readSessionDiscoveryByKey
9
+ } from "./chunk-DO42NPNR.js";
4
10
  import {
5
11
  controlTokenAuthHeaders
6
12
  } from "./chunk-GI2CKKBL.js";
@@ -8,9 +14,6 @@ import {
8
14
  deriveDiscoveryKey,
9
15
  findClaudeAncestorPid
10
16
  } from "./chunk-BJMASMKX.js";
11
- import {
12
- readSessionDiscoveryByKey
13
- } from "./chunk-DO42NPNR.js";
14
17
  import "./chunk-BLEGIR35.js";
15
18
 
16
19
  // src/hooks/user-prompt-submit-hook.ts
@@ -42,19 +45,7 @@ async function runUserPromptSubmitHook() {
42
45
  process.stdout.write("{}");
43
46
  return;
44
47
  }
45
- process.stdout.write(JSON.stringify({ additionalContext: formatEvents(body.events) }));
46
- }
47
- function formatEvents(events) {
48
- const header = `[${events.length} unread Tandem ${events.length === 1 ? "event" : "events"}]
49
-
50
- `;
51
- const bodies = events.map((evt) => {
52
- const attrs = Object.entries(evt.meta).map(([k, v]) => `${k}="${v}"`).join(" ");
53
- return `<channel source="kojee-mcp" ${attrs}>
54
- ${evt.content}
55
- </channel>`;
56
- });
57
- return header + bodies.join("\n\n");
48
+ process.stdout.write(JSON.stringify({ additionalContext: formatChannelEvents(body.events) }));
58
49
  }
59
50
  export {
60
51
  runUserPromptSubmitHook