kojee-mcp 0.5.19 → 0.7.0
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 +13 -8
- package/dist/ancestry-A2F5KQ6A.js +10 -0
- package/dist/cc-session-id-RURNIHHC.js +10 -0
- package/dist/{chunk-U4MNICQI.js → chunk-247WFMCJ.js} +12 -22
- package/dist/{chunk-PSVVRGJC.js → chunk-5H75AEZ2.js} +22 -9
- package/dist/{chunk-YH27B6SW.js → chunk-5SZHXYPK.js} +16 -3
- package/dist/{chunk-DO42NPNR.js → chunk-67F67AQ6.js} +14 -3
- package/dist/{chunk-CH32ELFX.js → chunk-6G6YYST6.js} +1 -1
- package/dist/chunk-D6JKFJ6A.js +11 -0
- package/dist/chunk-E6WMFMM2.js +100 -0
- package/dist/chunk-EIAUW6KO.js +82 -0
- package/dist/chunk-EIH2LNF4.js +45 -0
- package/dist/{chunk-74XFVX6Z.js → chunk-FSKGQ6GT.js} +47 -10
- package/dist/{chunk-GI2CKKBL.js → chunk-GKXHKR3B.js} +1 -1
- package/dist/{wizard-Y3ULSO2C.js → chunk-GVWYW7MY.js} +247 -138
- package/dist/{chunk-JXMVZEQ7.js → chunk-I67C2HYA.js} +1 -1
- package/dist/chunk-KNEJTD6G.js +31 -0
- package/dist/{chunk-NR4Y54OL.js → chunk-MIEI4PLB.js} +1 -19
- package/dist/chunk-NE2F5CKS.js +113 -0
- package/dist/{chunk-XXFVWP6H.js → chunk-OB5T6P24.js} +1 -1
- package/dist/{chunk-65KRRDHP.js → chunk-OBIJ6WQP.js} +82 -27
- package/dist/{chunk-DXJ6QLSJ.js → chunk-PKOBR7ZN.js} +1 -1
- package/dist/{chunk-2OLXXOT3.js → chunk-PPTKGWFF.js} +69 -3
- package/dist/{chunk-X672ZN7V.js → chunk-QEJUNP3X.js} +3 -2
- package/dist/chunk-QJFMU4QC.js +33 -0
- package/dist/{chunk-EW72ZNQL.js → chunk-RDLF4NQC.js} +1 -1
- package/dist/{chunk-XIDCYUTK.js → chunk-SGRVG4HW.js} +9 -4
- package/dist/{chunk-DURRQDYI.js → chunk-TNZITJAB.js} +45 -15
- package/dist/chunk-U5HHHRXA.js +103 -0
- package/dist/chunk-WBXU27BF.js +35 -0
- package/dist/chunk-WIU5WGDF.js +10 -0
- package/dist/chunk-XJEBJIQE.js +52 -0
- package/dist/chunk-Z5LPNJQ6.js +20 -0
- package/dist/cli.js +121 -89
- package/dist/{chunk-35XBRG3V.js → codex-stop-hook-EOMQD3J4.js} +11 -15
- package/dist/connect-handler-HIRM624N.js +137 -0
- package/dist/{control-token-4BUCTYQB.js → control-token-KXSZ3GBY.js} +2 -2
- package/dist/{doctor-U3MTB4GY.js → doctor-PLKLHTJM.js} +48 -22
- package/dist/{doctor-codex-PA3WO6LR.js → doctor-codex-HARAAH4Y.js} +23 -6
- package/dist/doctor-openclaw-LL6NSPLC.js +86 -0
- package/dist/{event-log-HOBO3ECB.js → event-log-2NBJEIEP.js} +5 -3
- package/dist/{event-stream-XX5EZ6HN.js → event-stream-KRYWEYWO.js} +7 -4
- package/dist/{hook-server-XK2NHLJV.js → hook-server-CWBH6PFL.js} +2 -2
- package/dist/index.js +13 -11
- package/dist/{install-LJY2CHKG.js → install-V7LSQCYZ.js} +37 -22
- package/dist/{keystore-XLEV3FL5.js → keystore-LQNFDHGO.js} +2 -2
- package/dist/lib.d.ts +4 -1
- package/dist/lib.js +12 -9
- package/dist/pair-HTCVSMR6.js +11 -0
- package/dist/{paired-config-JTFLHMZ2.js → paired-config-GUDDO2CH.js} +4 -2
- package/dist/{parent-watchdog-TLU355FB.js → parent-watchdog-LTUNF7PD.js} +24 -5
- package/dist/{registry-CGLE5X54.js → registry-VRFHKOPP.js} +195 -26
- package/dist/resolve-slot-BFIB46Y5.js +13 -0
- package/dist/{runtime-record-WO4IECM6.js → runtime-record-OXRLTOLC.js} +2 -2
- package/dist/{send-cli-IPADRDD2.js → send-cli-45RLGYIC.js} +24 -12
- package/dist/{server-LTFG4GMV.js → server-YTHOMA4H.js} +5 -3
- package/dist/{session-discovery-FNMJGFPM.js → session-discovery-NHCZ2XWA.js} +2 -2
- package/dist/setup-handler-UHVKSX7E.js +159 -0
- package/dist/{stop-hook-QZTFH5WV.js → stop-hook-YI4KRKF2.js} +17 -20
- package/dist/{tail-stream-CEJZGSIR.js → tail-stream-NBGHHBS4.js} +61 -22
- package/dist/{user-prompt-submit-hook-FQ43NIHC.js → user-prompt-submit-hook-DTXXFDSD.js} +11 -14
- package/package.json +2 -1
- package/dist/ancestry-ONFBQEP5.js +0 -8
- package/dist/chunk-BLEGIR35.js +0 -43
- package/dist/chunk-CLKCNV2A.js +0 -100
- package/dist/chunk-OGHDTFAX.js +0 -50
- package/dist/chunk-VHKPWUX7.js +0 -41
- package/dist/codex-stop-hook-VY7DOMAG.js +0 -16
- package/dist/doctor-openclaw-SS2TMQOX.js +0 -95
- package/dist/pair-P4ILCMT7.js +0 -10
package/dist/cli.js
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runPair
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-EIAUW6KO.js";
|
|
5
5
|
import {
|
|
6
6
|
startProxy
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-5H75AEZ2.js";
|
|
8
|
+
import "./chunk-OB5T6P24.js";
|
|
9
9
|
import {
|
|
10
10
|
pairedConfigPath
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-5SZHXYPK.js";
|
|
12
|
+
import "./chunk-247WFMCJ.js";
|
|
13
|
+
import "./chunk-I67C2HYA.js";
|
|
14
|
+
import "./chunk-Z5LPNJQ6.js";
|
|
15
|
+
import "./chunk-MIEI4PLB.js";
|
|
15
16
|
import {
|
|
16
17
|
defaultPairedKeystorePath,
|
|
17
18
|
deriveKeystorePath
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import "./chunk-
|
|
19
|
+
} from "./chunk-6G6YYST6.js";
|
|
20
|
+
import "./chunk-U5HHHRXA.js";
|
|
20
21
|
import {
|
|
21
22
|
VERSION
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-SGRVG4HW.js";
|
|
24
|
+
import "./chunk-QEJUNP3X.js";
|
|
25
|
+
import "./chunk-PPTKGWFF.js";
|
|
26
|
+
import "./chunk-XJEBJIQE.js";
|
|
27
|
+
import "./chunk-KNEJTD6G.js";
|
|
26
28
|
|
|
27
29
|
// src/cli.ts
|
|
28
30
|
import { Command } from "commander";
|
|
@@ -42,17 +44,30 @@ program.command("pair <code>").description("Pair this machine against Kojee usin
|
|
|
42
44
|
process.exit(1);
|
|
43
45
|
}
|
|
44
46
|
});
|
|
47
|
+
program.command("connect <code>").description(
|
|
48
|
+
"Connect this runtime to Kojee with a per-agent pair code from the dashboard (claude-code | codex | openclaw | hermes). claude-code/codex/openclaw write a per-runtime paired slot (~/.kojee/agents/<runtime>/config.json) and point the runtime launcher at it via --paired-config; hermes writes the global ~/.kojee/config.json (its daemon + `kojee-mcp send` read that). Idempotent."
|
|
49
|
+
).requiredOption("--runtime <id>", "Target runtime: claude-code | codex | openclaw | hermes").option("--url <url>", "Broker base URL (default: the canonical staging broker)").action(async (code, opts) => {
|
|
50
|
+
const { runConnect } = await import("./connect-handler-HIRM624N.js");
|
|
51
|
+
const result = await runConnect({
|
|
52
|
+
code,
|
|
53
|
+
runtime: opts.runtime,
|
|
54
|
+
...opts.url ? { url: opts.url } : {}
|
|
55
|
+
});
|
|
56
|
+
for (const m of result.messages) console.error(m);
|
|
57
|
+
console.error(result.output);
|
|
58
|
+
process.exit(result.exitCode);
|
|
59
|
+
});
|
|
45
60
|
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
61
|
if (opts.type === "stop") {
|
|
47
|
-
const { runStopHook } = await import("./stop-hook-
|
|
62
|
+
const { runStopHook } = await import("./stop-hook-YI4KRKF2.js");
|
|
48
63
|
await runStopHook();
|
|
49
64
|
process.exit(0);
|
|
50
65
|
} else if (opts.type === "user-prompt-submit") {
|
|
51
|
-
const { runUserPromptSubmitHook } = await import("./user-prompt-submit-hook-
|
|
66
|
+
const { runUserPromptSubmitHook } = await import("./user-prompt-submit-hook-DTXXFDSD.js");
|
|
52
67
|
await runUserPromptSubmitHook();
|
|
53
68
|
process.exit(0);
|
|
54
69
|
} else if (opts.type === "codex-stop") {
|
|
55
|
-
const { runCodexStopHook } = await import("./codex-stop-hook-
|
|
70
|
+
const { runCodexStopHook } = await import("./codex-stop-hook-EOMQD3J4.js");
|
|
56
71
|
await runCodexStopHook();
|
|
57
72
|
process.exit(0);
|
|
58
73
|
} else {
|
|
@@ -61,16 +76,17 @@ program.command("hook").description("Run a kojee MCP hook script (called by Clau
|
|
|
61
76
|
}
|
|
62
77
|
});
|
|
63
78
|
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) => {
|
|
64
|
-
const { installHooks, uninstallHooks } = await import("./install-
|
|
79
|
+
const { installHooks, uninstallHooks } = await import("./install-V7LSQCYZ.js");
|
|
65
80
|
if (opts.uninstall) {
|
|
66
81
|
const removed = uninstallHooks({ hooksPath: opts.hooksPath });
|
|
67
82
|
console.error(removed ? "Removed kojee hook entries." : "No kojee hook entries found.");
|
|
68
83
|
} else {
|
|
69
84
|
const { stop, ups } = installHooks({ hooksPath: opts.hooksPath });
|
|
85
|
+
const label = (s) => s === "added" ? "\u2713 added" : s === "updated" ? "\u21BB updated" : "\u21BB already installed";
|
|
70
86
|
console.error(
|
|
71
87
|
"Installed kojee hooks in " + (opts.hooksPath ?? "~/.claude/settings.json") + `:
|
|
72
|
-
- Stop: ${stop
|
|
73
|
-
- UserPromptSubmit: ${ups
|
|
88
|
+
- Stop: ${label(stop)}
|
|
89
|
+
- UserPromptSubmit: ${label(ups)}
|
|
74
90
|
Restart Claude Code for hooks to take effect.`
|
|
75
91
|
);
|
|
76
92
|
}
|
|
@@ -78,7 +94,7 @@ Restart Claude Code for hooks to take effect.`
|
|
|
78
94
|
program.command("send <tandem_id>").description(
|
|
79
95
|
"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
96
|
).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-
|
|
97
|
+
const { runSendCli } = await import("./send-cli-45RLGYIC.js");
|
|
82
98
|
const { exitCode, envelope } = await runSendCli({
|
|
83
99
|
tandemId,
|
|
84
100
|
body: opts.body,
|
|
@@ -89,7 +105,7 @@ program.command("send <tandem_id>").description(
|
|
|
89
105
|
process.exit(exitCode);
|
|
90
106
|
});
|
|
91
107
|
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-
|
|
108
|
+
const { runTail } = await import("./tail-stream-NBGHHBS4.js");
|
|
93
109
|
try {
|
|
94
110
|
await runTail(filePath);
|
|
95
111
|
} catch (err) {
|
|
@@ -98,75 +114,70 @@ program.command("tail <path>").description("Stream a file's contents and follow
|
|
|
98
114
|
}
|
|
99
115
|
});
|
|
100
116
|
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-
|
|
117
|
+
const { runDoctor } = await import("./doctor-PLKLHTJM.js");
|
|
102
118
|
const code = await runDoctor();
|
|
103
119
|
process.exit(code);
|
|
104
120
|
});
|
|
105
|
-
|
|
106
|
-
"
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
"
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
const {
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
} : {}
|
|
166
|
-
});
|
|
167
|
-
console.error(result.output);
|
|
168
|
-
process.exit(result.exitCode);
|
|
169
|
-
});
|
|
121
|
+
function addInstallOptions(cmd, runtimeHelp) {
|
|
122
|
+
return cmd.option("--runtime <id>", runtimeHelp).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; requires --url)").option("--url <url>", "Broker base URL (token mode / pair URL; default https://rosie-staging.kojee.net)").option("--pair <code>", "Pair code \u2014 runs the pair flow before configuring (alias of --pair-code)").option("--pair-code <code>", "Pair code \u2014 runs the pair flow before configuring (connect runtimes write ~/.kojee/agents/<runtime>/config.json; hermes/openclaw write ~/.kojee/config.json)").option("--webhook-url <url>", "Webhook receiver URL (codex/hermes/openclaw)").option("--webhook-secret <secret>", "Webhook HMAC secret (generated if omitted)").option(
|
|
123
|
+
"--webhook-signature-format <preset>",
|
|
124
|
+
'Signature preset: "github" = header X-Hub-Signature-256, value sha256=<hex> (default: bare hex in X-Kojee-Signature)'
|
|
125
|
+
).option(
|
|
126
|
+
"--webhook-signature-header <name>",
|
|
127
|
+
"Signature header name (default X-Kojee-Signature; overrides the preset's header)"
|
|
128
|
+
).option(
|
|
129
|
+
"--webhook-signature-prefix <prefix>",
|
|
130
|
+
"Literal string prepended to the hex digest (default empty; overrides the preset's prefix)"
|
|
131
|
+
).option("--uninstall", "Remove the kojee config for the chosen (or recorded) runtime");
|
|
132
|
+
}
|
|
133
|
+
function makeInstallAction(verb) {
|
|
134
|
+
return async (opts) => {
|
|
135
|
+
const interactive = process.stdin.isTTY === true && opts.runtime === void 0;
|
|
136
|
+
const { runSetup, resolvePairCode } = await import("./setup-handler-UHVKSX7E.js");
|
|
137
|
+
const pairCode = resolvePairCode(opts);
|
|
138
|
+
const result = await runSetup({
|
|
139
|
+
verb,
|
|
140
|
+
...opts.runtime !== void 0 ? { runtime: opts.runtime } : {},
|
|
141
|
+
...opts.configPath ? { configPath: opts.configPath } : {},
|
|
142
|
+
...opts.hooksPath ? { hooksPath: opts.hooksPath } : {},
|
|
143
|
+
...opts.token ? { token: opts.token } : {},
|
|
144
|
+
...opts.url ? { url: opts.url } : {},
|
|
145
|
+
...pairCode ? { pairCode } : {},
|
|
146
|
+
...opts.webhookUrl ? { webhookUrl: opts.webhookUrl } : {},
|
|
147
|
+
...opts.webhookSecret ? { webhookSecret: opts.webhookSecret } : {},
|
|
148
|
+
...opts.webhookSignatureFormat ? { webhookSignatureFormat: opts.webhookSignatureFormat } : {},
|
|
149
|
+
...opts.webhookSignatureHeader ? { webhookSignatureHeader: opts.webhookSignatureHeader } : {},
|
|
150
|
+
...opts.webhookSignaturePrefix !== void 0 ? { webhookSignaturePrefix: opts.webhookSignaturePrefix } : {},
|
|
151
|
+
...opts.uninstall ? { uninstall: true } : {},
|
|
152
|
+
interactive,
|
|
153
|
+
...interactive ? {
|
|
154
|
+
prompts: {
|
|
155
|
+
promptRuntime: promptRuntimeFromTty,
|
|
156
|
+
promptUrl: promptUrlFromTty,
|
|
157
|
+
promptAuth: promptAuthFromTty,
|
|
158
|
+
promptToken: promptTokenFromTty,
|
|
159
|
+
promptPairCode: promptPairCodeFromTty,
|
|
160
|
+
promptWebhookUrl: promptWebhookUrlFromTty
|
|
161
|
+
}
|
|
162
|
+
} : {}
|
|
163
|
+
});
|
|
164
|
+
for (const m of result.messages) console.error(m);
|
|
165
|
+
console.error(result.output);
|
|
166
|
+
process.exit(result.exitCode);
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
addInstallOptions(
|
|
170
|
+
program.command("init").description(
|
|
171
|
+
"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`."
|
|
172
|
+
),
|
|
173
|
+
"Target runtime: claude-code | hermes | openclaw | codex"
|
|
174
|
+
).action(makeInstallAction("init"));
|
|
175
|
+
addInstallOptions(
|
|
176
|
+
program.command("setup").description(
|
|
177
|
+
"One-line install: pair + write the runtime's MCP config + hooks in one shot (claude-code | codex). `--pair <code> --url <broker> --runtime <id>`, or the token form `--token <T> --url <U> --runtime <id>` for CI."
|
|
178
|
+
),
|
|
179
|
+
"Target runtime: claude-code | codex"
|
|
180
|
+
).action(makeInstallAction("setup"));
|
|
170
181
|
async function withReadline(fn) {
|
|
171
182
|
const readline = await import("readline/promises");
|
|
172
183
|
const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
|
|
@@ -208,6 +219,9 @@ async function promptWebhookUrlFromTty() {
|
|
|
208
219
|
return withReadline((ask) => ask("Webhook receiver URL (press Enter to skip and set it up later):\n> "));
|
|
209
220
|
}
|
|
210
221
|
program.option("--token <token>", "Gateway token (for token-mode)").option("--url <url>", "Broker base URL (for token-mode; required if --token is passed)").option(
|
|
222
|
+
"--paired-config <path>",
|
|
223
|
+
"Explicit per-runtime paired config path (written by `connect`)"
|
|
224
|
+
).option(
|
|
211
225
|
"--keystore-path <path>",
|
|
212
226
|
"Path to keypair file (defaults to per-token path under ~/.kojee/)"
|
|
213
227
|
).action(async (opts) => {
|
|
@@ -216,18 +230,36 @@ program.option("--token <token>", "Gateway token (for token-mode)").option("--ur
|
|
|
216
230
|
let keystorePath = opts.keystorePath;
|
|
217
231
|
const authMode = token ? "token" : "paired";
|
|
218
232
|
if (token) {
|
|
233
|
+
if (opts.pairedConfig) {
|
|
234
|
+
console.error(
|
|
235
|
+
"[kojee-mcp] both --token and --paired-config given; using --token (the per-runtime paired config is ignored)."
|
|
236
|
+
);
|
|
237
|
+
}
|
|
219
238
|
if (!url) {
|
|
220
239
|
console.error("--url is required when --token is provided");
|
|
221
240
|
process.exit(1);
|
|
222
241
|
}
|
|
223
242
|
url = url.replace(/\/+$/, "");
|
|
224
243
|
keystorePath ??= deriveKeystorePath(token);
|
|
244
|
+
} else if (opts.pairedConfig) {
|
|
245
|
+
const { resolveLaunchCreds } = await import("./resolve-slot-BFIB46Y5.js");
|
|
246
|
+
const resolved = resolveLaunchCreds({
|
|
247
|
+
pairedConfig: opts.pairedConfig,
|
|
248
|
+
...url ? { url } : {}
|
|
249
|
+
});
|
|
250
|
+
if (!resolved.ok) {
|
|
251
|
+
console.error(resolved.error);
|
|
252
|
+
process.exit(1);
|
|
253
|
+
}
|
|
254
|
+
token = resolved.token;
|
|
255
|
+
url = resolved.url;
|
|
256
|
+
keystorePath = resolved.keystorePath;
|
|
225
257
|
} else {
|
|
226
|
-
const { loadPairedConfig } = await import("./paired-config-
|
|
258
|
+
const { loadPairedConfig } = await import("./paired-config-GUDDO2CH.js");
|
|
227
259
|
const cfg = loadPairedConfig();
|
|
228
260
|
if (!cfg) {
|
|
229
261
|
console.error(
|
|
230
|
-
"No --token provided and no ~/.kojee/config.json found. Run `kojee-mcp
|
|
262
|
+
"No --token provided and no ~/.kojee/config.json found. Run `kojee-mcp connect <code> --runtime <id>` (or `kojee-mcp pair`) first."
|
|
231
263
|
);
|
|
232
264
|
process.exit(1);
|
|
233
265
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
readHookStdin
|
|
3
3
|
} from "./chunk-LSUB6QMP.js";
|
|
4
|
+
import {
|
|
5
|
+
codexPendingMarkerPath
|
|
6
|
+
} from "./chunk-WIU5WGDF.js";
|
|
4
7
|
import {
|
|
5
8
|
buildCodexWakeReason
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-QEJUNP3X.js";
|
|
7
10
|
|
|
8
11
|
// src/hooks/codex-stop-hook.ts
|
|
9
12
|
import fs from "fs";
|
|
10
|
-
import os from "os";
|
|
11
|
-
import path from "path";
|
|
12
13
|
var CODEX_PEEK_MS = clampPeekMs(
|
|
13
14
|
Number.parseInt(process.env["KOJEE_CODEX_PEEK_MS"] ?? "150", 10)
|
|
14
15
|
);
|
|
@@ -26,12 +27,8 @@ function decideCodexStopHook(deps) {
|
|
|
26
27
|
reason: buildCodexWakeReason(peek.cursor)
|
|
27
28
|
});
|
|
28
29
|
}
|
|
29
|
-
function
|
|
30
|
-
const
|
|
31
|
-
return path.join(os.homedir(), ".kojee", `codex-pending-${safe}`);
|
|
32
|
-
}
|
|
33
|
-
function defaultPeekPending(sessionId) {
|
|
34
|
-
const markerPath = codexPendingMarkerPath(sessionId);
|
|
30
|
+
function defaultPeekPending() {
|
|
31
|
+
const markerPath = codexPendingMarkerPath();
|
|
35
32
|
try {
|
|
36
33
|
const st = fs.statSync(markerPath);
|
|
37
34
|
const ageMs = Date.now() - st.mtimeMs;
|
|
@@ -49,12 +46,12 @@ function defaultPeekPending(sessionId) {
|
|
|
49
46
|
}
|
|
50
47
|
}
|
|
51
48
|
async function runCodexStopHook() {
|
|
52
|
-
const {
|
|
49
|
+
const { stopHookActive } = await readHookStdin();
|
|
53
50
|
const out = decideCodexStopHook({
|
|
54
51
|
stopHookActive,
|
|
55
52
|
peekPending: () => {
|
|
56
53
|
try {
|
|
57
|
-
return defaultPeekPending(
|
|
54
|
+
return defaultPeekPending();
|
|
58
55
|
} catch {
|
|
59
56
|
return { pending: false, cursor: null };
|
|
60
57
|
}
|
|
@@ -63,11 +60,10 @@ async function runCodexStopHook() {
|
|
|
63
60
|
process.stdout.write(out);
|
|
64
61
|
}
|
|
65
62
|
var CODEX_PEEK_BUDGET_MS = CODEX_PEEK_MS;
|
|
66
|
-
|
|
67
63
|
export {
|
|
68
|
-
|
|
64
|
+
CODEX_PEEK_BUDGET_MS,
|
|
69
65
|
codexPendingMarkerPath,
|
|
66
|
+
decideCodexStopHook,
|
|
70
67
|
defaultPeekPending,
|
|
71
|
-
runCodexStopHook
|
|
72
|
-
CODEX_PEEK_BUDGET_MS
|
|
68
|
+
runCodexStopHook
|
|
73
69
|
};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_BROKER_URL,
|
|
3
|
+
reconcileConnectPairSlot,
|
|
4
|
+
runWizard
|
|
5
|
+
} from "./chunk-GVWYW7MY.js";
|
|
6
|
+
import "./chunk-E6WMFMM2.js";
|
|
7
|
+
import "./chunk-OBIJ6WQP.js";
|
|
8
|
+
import "./chunk-QJFMU4QC.js";
|
|
9
|
+
import "./chunk-D6JKFJ6A.js";
|
|
10
|
+
import {
|
|
11
|
+
CONNECT_RUNTIMES
|
|
12
|
+
} from "./chunk-EIH2LNF4.js";
|
|
13
|
+
import "./chunk-RDLF4NQC.js";
|
|
14
|
+
import "./chunk-SQL56SEB.js";
|
|
15
|
+
import "./chunk-77HWBSRH.js";
|
|
16
|
+
import "./chunk-V5VZPYMZ.js";
|
|
17
|
+
import {
|
|
18
|
+
runPair
|
|
19
|
+
} from "./chunk-EIAUW6KO.js";
|
|
20
|
+
import {
|
|
21
|
+
loadPairedConfig,
|
|
22
|
+
pairedConfigPath,
|
|
23
|
+
perRuntimeConfigPath
|
|
24
|
+
} from "./chunk-5SZHXYPK.js";
|
|
25
|
+
import "./chunk-I67C2HYA.js";
|
|
26
|
+
import "./chunk-MIEI4PLB.js";
|
|
27
|
+
import {
|
|
28
|
+
defaultPairedKeystorePath,
|
|
29
|
+
deriveKeystorePath
|
|
30
|
+
} from "./chunk-6G6YYST6.js";
|
|
31
|
+
import "./chunk-U5HHHRXA.js";
|
|
32
|
+
import "./chunk-QEJUNP3X.js";
|
|
33
|
+
|
|
34
|
+
// src/wizard/connect-handler.ts
|
|
35
|
+
import os from "os";
|
|
36
|
+
import path from "path";
|
|
37
|
+
function absConfigPath(runtime) {
|
|
38
|
+
const p = path.resolve(perRuntimeConfigPath(runtime));
|
|
39
|
+
if (process.platform === "win32" && !/^[a-zA-Z]:/.test(p)) {
|
|
40
|
+
return path.resolve(path.join(os.homedir(), ".kojee", "agents", runtime, "config.json"));
|
|
41
|
+
}
|
|
42
|
+
return p;
|
|
43
|
+
}
|
|
44
|
+
function identityLabel(cfg) {
|
|
45
|
+
if (cfg?.agent_id && cfg?.principal_id) return `${cfg.agent_id} (${cfg.principal_id})`;
|
|
46
|
+
if (cfg?.agent_id) return cfg.agent_id;
|
|
47
|
+
if (cfg?.principal_id) return cfg.principal_id;
|
|
48
|
+
return "this runtime";
|
|
49
|
+
}
|
|
50
|
+
async function runConnect(opts) {
|
|
51
|
+
if (opts.runtime === "hermes") return runConnectHermes(opts);
|
|
52
|
+
const messages = [];
|
|
53
|
+
const runtime = opts.runtime;
|
|
54
|
+
if (!CONNECT_RUNTIMES.includes(runtime)) {
|
|
55
|
+
return {
|
|
56
|
+
messages,
|
|
57
|
+
output: `\`connect\` supports: ${CONNECT_RUNTIMES.join(", ")}, hermes. Unknown --runtime "${runtime}". (claude-code/codex/openclaw write a per-runtime paired slot; hermes writes the global ~/.kojee/config.json.)`,
|
|
58
|
+
exitCode: 2
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const url = (opts.url ?? DEFAULT_BROKER_URL).replace(/\/+$/, "");
|
|
62
|
+
const configPath = absConfigPath(runtime);
|
|
63
|
+
const oldConfig = loadPairedConfig(configPath);
|
|
64
|
+
const reconcile = reconcileConnectPairSlot(runtime, opts.code);
|
|
65
|
+
if (!reconcile.ok) {
|
|
66
|
+
return { messages, output: reconcile.output, exitCode: reconcile.exitCode };
|
|
67
|
+
}
|
|
68
|
+
messages.push(...reconcile.messages);
|
|
69
|
+
const pair = opts.runPair ?? runPair;
|
|
70
|
+
try {
|
|
71
|
+
const r = await pair({
|
|
72
|
+
code: opts.code,
|
|
73
|
+
url,
|
|
74
|
+
keystorePath: deriveKeystorePath(opts.code),
|
|
75
|
+
configPath,
|
|
76
|
+
runtime,
|
|
77
|
+
allowOverwrite: true
|
|
78
|
+
});
|
|
79
|
+
messages.push(r.message);
|
|
80
|
+
} catch (err) {
|
|
81
|
+
return { messages, output: `Connect failed while pairing: ${err.message}`, exitCode: 1 };
|
|
82
|
+
}
|
|
83
|
+
const wizard = opts.runWizard ?? runWizard;
|
|
84
|
+
const wiz = await wizard({ runtime, pairedConfigPath: configPath, interactive: false });
|
|
85
|
+
if (wiz.exitCode !== 0) {
|
|
86
|
+
return { messages, output: wiz.output, exitCode: wiz.exitCode };
|
|
87
|
+
}
|
|
88
|
+
const newConfig = loadPairedConfig(configPath);
|
|
89
|
+
const newLabel = identityLabel(newConfig);
|
|
90
|
+
const summary = oldConfig ? `\u21BB re-connected ${runtime} as ${newLabel} (was ${identityLabel(oldConfig)})` : `\u2713 connected ${runtime} as ${newLabel} \u2192 ${url}`;
|
|
91
|
+
const output = `${summary}
|
|
92
|
+
Restart ${runtime} to pick up the connection.`;
|
|
93
|
+
return { messages, output, exitCode: 0 };
|
|
94
|
+
}
|
|
95
|
+
async function runConnectHermes(opts) {
|
|
96
|
+
const messages = [];
|
|
97
|
+
const url = (opts.url ?? DEFAULT_BROKER_URL).replace(/\/+$/, "");
|
|
98
|
+
const configPath = pairedConfigPath();
|
|
99
|
+
const oldConfig = loadPairedConfig(configPath);
|
|
100
|
+
const guard = reconcileConnectPairSlot("hermes", opts.code);
|
|
101
|
+
if (!guard.ok) {
|
|
102
|
+
return { messages, output: guard.output, exitCode: guard.exitCode };
|
|
103
|
+
}
|
|
104
|
+
messages.push(...guard.messages);
|
|
105
|
+
const pair = opts.runPair ?? runPair;
|
|
106
|
+
try {
|
|
107
|
+
const r = await pair({
|
|
108
|
+
code: opts.code,
|
|
109
|
+
url,
|
|
110
|
+
keystorePath: defaultPairedKeystorePath(),
|
|
111
|
+
configPath,
|
|
112
|
+
runtime: "hermes",
|
|
113
|
+
allowOverwrite: true
|
|
114
|
+
// connect is idempotent
|
|
115
|
+
});
|
|
116
|
+
messages.push(r.message);
|
|
117
|
+
} catch (err) {
|
|
118
|
+
return { messages, output: `Connect failed while pairing: ${err.message}`, exitCode: 1 };
|
|
119
|
+
}
|
|
120
|
+
const wizard = opts.runWizard ?? runWizard;
|
|
121
|
+
const wiz = await wizard({ runtime: "hermes", interactive: false });
|
|
122
|
+
if (wiz.exitCode !== 0) {
|
|
123
|
+
return { messages, output: wiz.output, exitCode: wiz.exitCode };
|
|
124
|
+
}
|
|
125
|
+
const label = identityLabel(loadPairedConfig(configPath));
|
|
126
|
+
const summary = oldConfig ? `\u21BB re-connected hermes as ${label}` : `\u2713 connected hermes as ${label} \u2192 ${url}`;
|
|
127
|
+
return {
|
|
128
|
+
messages,
|
|
129
|
+
output: `${summary}
|
|
130
|
+
Start (or restart) the hermes daemon to pick up the connection.`,
|
|
131
|
+
exitCode: 0
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
export {
|
|
135
|
+
runConnect,
|
|
136
|
+
runConnectHermes
|
|
137
|
+
};
|
|
@@ -1,28 +1,31 @@
|
|
|
1
1
|
import "./chunk-XLKGPGZT.js";
|
|
2
|
+
import {
|
|
3
|
+
loadControlToken
|
|
4
|
+
} from "./chunk-GKXHKR3B.js";
|
|
2
5
|
import {
|
|
3
6
|
monitorHeartbeatPath,
|
|
4
7
|
statusLogPath
|
|
5
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-TNZITJAB.js";
|
|
6
9
|
import {
|
|
7
10
|
discoveryPathForKey,
|
|
8
11
|
readSessionDiscoveryByKey,
|
|
9
12
|
sessionDiscoveryDir
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import {
|
|
12
|
-
loadControlToken
|
|
13
|
-
} from "./chunk-GI2CKKBL.js";
|
|
13
|
+
} from "./chunk-67F67AQ6.js";
|
|
14
14
|
import {
|
|
15
15
|
loadPairedConfig
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-5SZHXYPK.js";
|
|
17
|
+
import "./chunk-U5HHHRXA.js";
|
|
18
18
|
import {
|
|
19
19
|
buildMonitorSpawn,
|
|
20
20
|
buildReplyRecipe
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-QEJUNP3X.js";
|
|
22
22
|
import {
|
|
23
23
|
deriveDiscoveryKey,
|
|
24
24
|
findClaudeAncestorPid
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-XJEBJIQE.js";
|
|
26
|
+
import {
|
|
27
|
+
resolveSharedSessionId
|
|
28
|
+
} from "./chunk-KNEJTD6G.js";
|
|
26
29
|
|
|
27
30
|
// src/doctor.ts
|
|
28
31
|
import fs from "fs";
|
|
@@ -95,7 +98,8 @@ function defaultIsPidAlive(pid) {
|
|
|
95
98
|
process.kill(pid, 0);
|
|
96
99
|
return true;
|
|
97
100
|
} catch (err) {
|
|
98
|
-
|
|
101
|
+
const code = err.code;
|
|
102
|
+
if (code === "EPERM" || code === "EACCES") return true;
|
|
99
103
|
return false;
|
|
100
104
|
}
|
|
101
105
|
}
|
|
@@ -132,6 +136,19 @@ function defaultReadLastStatusLine(path2) {
|
|
|
132
136
|
}
|
|
133
137
|
}
|
|
134
138
|
}
|
|
139
|
+
async function resolveDefaultPairedScope() {
|
|
140
|
+
const { resolvePairedSlot } = await import("./resolve-slot-BFIB46Y5.js");
|
|
141
|
+
const { readRecordedRuntime } = await import("./runtime-record-OXRLTOLC.js");
|
|
142
|
+
const { deriveKeystorePath } = await import("./keystore-LQNFDHGO.js");
|
|
143
|
+
const runtime = readRecordedRuntime() ?? process.env["KOJEE_RUNTIME"];
|
|
144
|
+
const resolution = resolvePairedSlot({ ...runtime ? { runtime } : {} });
|
|
145
|
+
const cfg = loadPairedConfig(resolution.configPath);
|
|
146
|
+
let present = cfg !== null && typeof cfg.token === "string" && cfg.token !== "";
|
|
147
|
+
if (present && resolution.scope === "paired" && cfg) {
|
|
148
|
+
present = fs.existsSync(deriveKeystorePath(cfg.token));
|
|
149
|
+
}
|
|
150
|
+
return { scope: resolution.scope, present, ...runtime ? { runtime } : {} };
|
|
151
|
+
}
|
|
135
152
|
async function collectDoctorReport(deps = {}) {
|
|
136
153
|
const fetchFn = deps.fetchFn ?? fetch;
|
|
137
154
|
const isPidAlive = deps.isPidAlive ?? defaultIsPidAlive;
|
|
@@ -140,23 +157,32 @@ async function collectDoctorReport(deps = {}) {
|
|
|
140
157
|
const readDiscovery = deps.readDiscovery ?? readSessionDiscoveryByKey;
|
|
141
158
|
const projectDir = deps.projectDir ?? process.env["CLAUDE_PROJECT_DIR"];
|
|
142
159
|
const ccPid = deps.ccPid !== void 0 ? deps.ccPid : await findClaudeAncestorPid();
|
|
143
|
-
const
|
|
160
|
+
const sessionId = deps.sessionId !== void 0 ? deps.sessionId : resolveSharedSessionId();
|
|
161
|
+
const discoveryKey = deriveDiscoveryKey(projectDir, ccPid, sessionId);
|
|
144
162
|
const discoveryPath = discoveryPathForKey(discoveryKey);
|
|
145
163
|
const checks = [];
|
|
146
164
|
const discovery = readDiscovery(discoveryKey);
|
|
147
165
|
const tokenMode = discovery?.authMode === "token";
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
166
|
+
const pairedScope = deps.pairedScope ?? (deps.pairedConfigPresent !== void 0 ? { scope: "legacy", present: deps.pairedConfigPresent } : await resolveDefaultPairedScope());
|
|
167
|
+
if (tokenMode) {
|
|
168
|
+
checks.push({
|
|
151
169
|
name: "paired config",
|
|
152
170
|
ok: true,
|
|
153
171
|
detail: "n/a (token mode) \u2014 proxy launched with --token; no ~/.kojee/config.json by design"
|
|
154
|
-
}
|
|
172
|
+
});
|
|
173
|
+
} else if (pairedScope.scope === "paired") {
|
|
174
|
+
checks.push({
|
|
155
175
|
name: "paired config",
|
|
156
|
-
ok:
|
|
157
|
-
detail:
|
|
158
|
-
}
|
|
159
|
-
|
|
176
|
+
ok: pairedScope.present,
|
|
177
|
+
detail: pairedScope.present ? `present (per-runtime: ${pairedScope.runtime ?? "?"}) + token-derived keystore` : `MISSING per-runtime slot for ${pairedScope.runtime ?? "?"} \u2014 run \`kojee-mcp connect <code> --runtime ${pairedScope.runtime ?? "<id>"}\``
|
|
178
|
+
});
|
|
179
|
+
} else {
|
|
180
|
+
checks.push({
|
|
181
|
+
name: "paired config",
|
|
182
|
+
ok: pairedScope.present,
|
|
183
|
+
detail: pairedScope.present ? "present (legacy global slot)" : "MISSING \u2014 run `kojee-mcp connect <code> --runtime <id>` (or `kojee-mcp pair`)"
|
|
184
|
+
});
|
|
185
|
+
}
|
|
160
186
|
let logPath = null;
|
|
161
187
|
if (!discovery) {
|
|
162
188
|
checks.push({
|
|
@@ -326,15 +352,15 @@ function formatDoctorReport(report) {
|
|
|
326
352
|
return lines.join("\n");
|
|
327
353
|
}
|
|
328
354
|
async function runDoctor() {
|
|
329
|
-
const { readRecordedRuntime } = await import("./runtime-record-
|
|
355
|
+
const { readRecordedRuntime } = await import("./runtime-record-OXRLTOLC.js");
|
|
330
356
|
if (readRecordedRuntime() === "codex") {
|
|
331
|
-
const { collectCodexDoctorReport, formatCodexDoctorReport } = await import("./doctor-codex-
|
|
357
|
+
const { collectCodexDoctorReport, formatCodexDoctorReport } = await import("./doctor-codex-HARAAH4Y.js");
|
|
332
358
|
const report2 = collectCodexDoctorReport();
|
|
333
359
|
console.error(formatCodexDoctorReport(report2));
|
|
334
360
|
return report2.verdict === "broken" ? 1 : 0;
|
|
335
361
|
}
|
|
336
362
|
if (readRecordedRuntime() === "openclaw") {
|
|
337
|
-
const { collectOpenclawDoctorReport, formatOpenclawDoctorReport } = await import("./doctor-openclaw-
|
|
363
|
+
const { collectOpenclawDoctorReport, formatOpenclawDoctorReport } = await import("./doctor-openclaw-LL6NSPLC.js");
|
|
338
364
|
const report2 = collectOpenclawDoctorReport();
|
|
339
365
|
console.error(formatOpenclawDoctorReport(report2));
|
|
340
366
|
return report2.verdict === "broken" ? 1 : 0;
|