kojee-mcp 0.7.2 → 0.7.3
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/dist/{chunk-RVLUZLXD.js → chunk-6XWTUDWW.js} +15 -6
- package/dist/{chunk-ZUIYFRO5.js → chunk-A4IOKD4Z.js} +49 -2
- package/dist/{chunk-R5GC2GRD.js → chunk-ABECLEYE.js} +3 -3
- package/dist/{chunk-XFGGMDZ4.js → chunk-FJUAMJHU.js} +2 -2
- package/dist/{chunk-E35VWFZV.js → chunk-TCWIXG5C.js} +1 -1
- package/dist/{chunk-EDHG4375.js → chunk-XPIW4N55.js} +11 -9
- package/dist/cli.js +11 -11
- package/dist/{codex-prompt-submit-hook-FOBPGZHJ.js → codex-prompt-submit-hook-J5PZEJSK.js} +1 -1
- package/dist/{codex-stop-hook-PNWYNQKM.js → codex-stop-hook-32W4BIOM.js} +1 -1
- package/dist/{connect-handler-2JFIMQY6.js → connect-handler-NZINEMG3.js} +3 -3
- package/dist/{doctor-HXMCO5PR.js → doctor-WUU5BVPT.js} +2 -2
- package/dist/{doctor-codex-ZSALZPH3.js → doctor-codex-PJFWIABF.js} +2 -2
- package/dist/index.js +4 -4
- package/dist/{install-GGI6GU6C.js → install-JQNDGAAQ.js} +13 -1
- package/dist/{registry-42Y45L6I.js → registry-2QS42EQF.js} +6 -6
- package/dist/{server-JWIH7OFA.js → server-DU3LFS32.js} +2 -2
- package/dist/{setup-handler-GBPXDETR.js → setup-handler-44ASXYMS.js} +3 -3
- package/dist/{stop-hook-PWTAP227.js → stop-hook-N6TX4YQT.js} +1 -1
- package/package.json +1 -1
- package/skills/using-tandems/SKILL.md +1 -1
|
@@ -118,13 +118,13 @@ function scrubPlaceholderWebhookEnv(envKeys) {
|
|
|
118
118
|
function writeCodexConfig(inputs) {
|
|
119
119
|
const configPath = inputs.configPath ?? defaultCodexConfigPath();
|
|
120
120
|
const hooksPath = inputs.hooksPath ?? defaultCodexHooksPath();
|
|
121
|
-
let
|
|
121
|
+
let existingToml = "";
|
|
122
122
|
try {
|
|
123
|
-
|
|
123
|
+
existingToml = fs.readFileSync(configPath, "utf8");
|
|
124
124
|
} catch {
|
|
125
125
|
}
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
const newToml = upsertKojeeTomlTables(
|
|
127
|
+
existingToml,
|
|
128
128
|
inputs.webhookUrl,
|
|
129
129
|
inputs.webhookSecret,
|
|
130
130
|
inputs.signatureEnv ?? [],
|
|
@@ -132,12 +132,21 @@ function writeCodexConfig(inputs) {
|
|
|
132
132
|
inputs.url,
|
|
133
133
|
inputs.pairedConfigPath
|
|
134
134
|
);
|
|
135
|
-
|
|
135
|
+
const tomlChanged = newToml !== existingToml;
|
|
136
|
+
if (tomlChanged) writeFile600(configPath, newToml);
|
|
136
137
|
const hooks = readJson(hooksPath);
|
|
137
138
|
hooks.hooks ??= {};
|
|
138
139
|
upsertKojeeHookEntry(hooks, "Stop", codexStopHookCommand());
|
|
139
140
|
upsertKojeeHookEntry(hooks, "UserPromptSubmit", codexPromptSubmitHookCommand());
|
|
140
|
-
|
|
141
|
+
const newHooks = JSON.stringify(hooks, null, 2);
|
|
142
|
+
let existingHooksRaw = "";
|
|
143
|
+
try {
|
|
144
|
+
existingHooksRaw = fs.readFileSync(hooksPath, "utf8");
|
|
145
|
+
} catch {
|
|
146
|
+
}
|
|
147
|
+
const hooksChanged = newHooks !== existingHooksRaw;
|
|
148
|
+
if (hooksChanged) writeFile600(hooksPath, newHooks);
|
|
149
|
+
return { tomlChanged, hooksChanged };
|
|
141
150
|
}
|
|
142
151
|
function upsertKojeeHookEntry(hooks, event, command) {
|
|
143
152
|
hooks.hooks ??= {};
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
buildCondensedTandemRules,
|
|
7
7
|
buildMonitorSpawn,
|
|
8
8
|
buildReplyRecipe
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-FJUAMJHU.js";
|
|
10
10
|
import {
|
|
11
11
|
translateToolCallResult
|
|
12
12
|
} from "./chunk-PPTKGWFF.js";
|
|
@@ -40,6 +40,45 @@ function buildChannelInstructions(_tandemMembershipCount, eventLogPath) {
|
|
|
40
40
|
function tandemIdArg(args) {
|
|
41
41
|
return typeof args["tandem_id"] === "string" ? args["tandem_id"] : null;
|
|
42
42
|
}
|
|
43
|
+
function parseJoinDisplayName(content) {
|
|
44
|
+
for (const item of content) {
|
|
45
|
+
if (item.type !== "text" || typeof item.text !== "string") continue;
|
|
46
|
+
try {
|
|
47
|
+
const parsed = JSON.parse(item.text);
|
|
48
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
49
|
+
const name = parsed["display_name"];
|
|
50
|
+
if (typeof name === "string" && name.length > 0) return name;
|
|
51
|
+
}
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
function parseJoinStatus(content) {
|
|
58
|
+
for (const item of content) {
|
|
59
|
+
if (item.type !== "text" || typeof item.text !== "string") continue;
|
|
60
|
+
try {
|
|
61
|
+
const parsed = JSON.parse(item.text);
|
|
62
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
63
|
+
const status = parsed["status"];
|
|
64
|
+
if (typeof status === "string") return status;
|
|
65
|
+
}
|
|
66
|
+
} catch {
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
var SKIP_ADVISORY_STATUSES = /* @__PURE__ */ new Set(["pending_approval", "needs_invite"]);
|
|
72
|
+
function buildUnnamedJoinAdvisory(args, content) {
|
|
73
|
+
const seatName = args["seat_name"];
|
|
74
|
+
if (typeof seatName === "string" && seatName.trim().length > 0) return null;
|
|
75
|
+
const status = parseJoinStatus(content);
|
|
76
|
+
if (status !== null && SKIP_ADVISORY_STATUSES.has(status)) return null;
|
|
77
|
+
const displayName = parseJoinDisplayName(content);
|
|
78
|
+
const handleClause = displayName !== null ? `the room minted a generated handle ('${displayName}')` : "the room minted a generated handle";
|
|
79
|
+
const text = `[kojee] You joined WITHOUT seat_name \u2014 ${handleClause}. If you previously held a name in this room, re-join now with tandem_join(tandem_id, seat_name=<your name>) to rebind your seat; mentions to your old name will NOT reach this seat until you do.`;
|
|
80
|
+
return { type: "text", text };
|
|
81
|
+
}
|
|
43
82
|
var DRAIN_TOOLS = /* @__PURE__ */ new Set(["tandem_messages", "tandem_ack"]);
|
|
44
83
|
function extractDrainCursor(name, args, content) {
|
|
45
84
|
const candidates = [];
|
|
@@ -74,13 +113,21 @@ function extractDrainCursor(name, args, content) {
|
|
|
74
113
|
}
|
|
75
114
|
async function executeToolCall(registry, name, args, hooks) {
|
|
76
115
|
const rawResult = await registry.callTool(name, args);
|
|
77
|
-
|
|
116
|
+
let result = translateToolCallResult(rawResult);
|
|
78
117
|
if (!result.isError && name === "tandem_join") {
|
|
79
118
|
try {
|
|
80
119
|
hooks?.onTandemJoin?.(tandemIdArg(args));
|
|
81
120
|
} catch (err) {
|
|
82
121
|
console.error("[mcp] onTandemJoin hook failed:", err?.message ?? String(err));
|
|
83
122
|
}
|
|
123
|
+
try {
|
|
124
|
+
const advisory = buildUnnamedJoinAdvisory(args, result.content);
|
|
125
|
+
if (advisory !== null) {
|
|
126
|
+
result = { ...result, content: [...result.content, advisory] };
|
|
127
|
+
}
|
|
128
|
+
} catch (err) {
|
|
129
|
+
console.error("[mcp] unnamed-join advisory decoration failed:", err?.message ?? String(err));
|
|
130
|
+
}
|
|
84
131
|
}
|
|
85
132
|
if (!result.isError && name === "tandem_leave") {
|
|
86
133
|
try {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
claudeCodeAdapter
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TCWIXG5C.js";
|
|
4
4
|
import {
|
|
5
5
|
GatewayClient,
|
|
6
6
|
applyStableSessionId
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import {
|
|
12
12
|
createMcpServer,
|
|
13
13
|
startMcpServer
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-A4IOKD4Z.js";
|
|
15
15
|
import {
|
|
16
16
|
findClaudeAncestorPid
|
|
17
17
|
} from "./chunk-XJEBJIQE.js";
|
|
@@ -295,7 +295,7 @@ async function startProxy(config) {
|
|
|
295
295
|
}
|
|
296
296
|
console.error(`[kojee-mcp] Tandem memberships: ${tandemMembershipCount === -1 ? "unknown" : tandemMembershipCount}`);
|
|
297
297
|
let server;
|
|
298
|
-
const { selectDelivery } = await import("./registry-
|
|
298
|
+
const { selectDelivery } = await import("./registry-2QS42EQF.js");
|
|
299
299
|
const delivery = selectDelivery(adapter.runtime, {
|
|
300
300
|
supportsChannels: adapter.supportsChannels,
|
|
301
301
|
// Per-window delivered mirror for the tandem_pending tool (codex only —
|
|
@@ -16,7 +16,7 @@ function buildCatchUpNote() {
|
|
|
16
16
|
return "Cursors are allocated per-Tandem, and the event-log interleaves every subscribed room into one stream \u2014 so track the last `cursor=<n>` you saw keyed by the line's `tandem=<id>` field, and only treat a jump WITHIN the same tandem_id as a gap (a jump between lines from different rooms is normal interleaving, not a missed message). If the cursor jumps within one tandem, or the log resets (the proxy caps and truncates the messages log in place on overflow \u2014 a `status=rotated` line is recorded in the status sibling), you may have missed messages: catch up with tandem_messages(tandem_id, since=<last cursor you saw for THAT tandem>).";
|
|
17
17
|
}
|
|
18
18
|
function buildCondensedTandemRules() {
|
|
19
|
-
return "Tandem ground rules: (1) catch up before you speak \u2014 fetch messages since your last cursor (cursors are per-Tandem); never answer from a stale view. (2) close every loop \u2014 taking / done (with evidence) / blocked, said out loud; silence is a bug on a team. (3) your seat_name IS your room identity \u2014 keep it stable across sessions and reconnects. (4) plan your wake path per task and set your wake filter deliberately (heads-down \u2192 mentions; waiting on one reply \u2192 listen; co-working \u2192 all), and tell the room your posture WHEN IT CHANGES \u2014 skip the check-in ceremony when you are merely re-joining/reconnecting with the same posture.";
|
|
19
|
+
return "Tandem ground rules: (1) catch up before you speak \u2014 fetch messages since your last cursor (cursors are per-Tandem); never answer from a stale view. (2) close every loop \u2014 taking / done (with evidence) / blocked, said out loud; silence is a bug on a team. (3) your seat_name IS your room identity \u2014 keep it stable across sessions and reconnects. (4) plan your wake path per task and set your wake filter deliberately (heads-down \u2192 mentions; waiting on one reply \u2192 listen; co-working \u2192 all), and tell the room your posture WHEN IT CHANGES \u2014 skip the check-in ceremony when you are merely re-joining/reconnecting with the same posture. (5) send all replies and check-ins as kind=message \u2014 never kind=status; status is lifecycle-only (joined/left, system-generated).";
|
|
20
20
|
}
|
|
21
21
|
function buildMonitorNudge(logPath) {
|
|
22
22
|
return `[kojee] Tandem events are being logged but no Monitor is reading them \u2014 you may be missing wake notifications. Spawn the watcher once: ${buildMonitorSpawn(logPath)}. Then ${buildReplyRecipe()}.`;
|
|
@@ -29,7 +29,7 @@ function buildWebhookReceiverNote(sig) {
|
|
|
29
29
|
return "Webhook sink (optional, OFF unless KOJEE_WEBHOOK_URL + KOJEE_WEBHOOK_SECRET are set): the proxy POSTs every Tandem event as JSON to your endpoint. The body is the canonical normalized TandemEvent \u2014 " + WEBHOOK_BODY_SHAPE + ` \u2014 where from.session_id and severity are present only when the wire carried them (the body is fully normalized: it carries from.principal, never the raw backend sender envelope). To build a receiver: (1) verify the ${header} header \u2014 it is ${digestDesc} of the RAW request body bytes keyed by your KOJEE_WEBHOOK_SECRET; recompute over the received bytes and timing-safe compare, reject mismatches. (2) Dedupe by message_id \u2014 the body's \`id\`, also in the X-Kojee-Delivery header: delivery is AT-LEAST-ONCE (the proxy replays backlog from the cursor on restart), so the same event may arrive more than once \u2014 there is no exactly-once promise.`;
|
|
30
30
|
}
|
|
31
31
|
var CODEX_LISTEN_CAP_MS = 8e3;
|
|
32
|
-
var CODEX_WAKE_BELL = "[kojee] Tandem events may be pending. Call tandem_pending now and drain each room it lists (tandem_messages(id, since=cursor)), then reply in the room. If it returns none for you, ignore this.";
|
|
32
|
+
var CODEX_WAKE_BELL = "[kojee] Tandem events may be pending. Call tandem_pending now and drain each room it lists (tandem_messages(id, since=cursor)), then reply in the room with a normal message (kind=message \u2014 never status). If it returns none for you, ignore this.";
|
|
33
33
|
|
|
34
34
|
export {
|
|
35
35
|
buildMonitorSpawn,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
isPlaceholderWebhookUrl,
|
|
6
6
|
removeCodexConfig,
|
|
7
7
|
writeCodexConfig
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-6XWTUDWW.js";
|
|
9
9
|
import {
|
|
10
10
|
removeOpenclawMcpServer,
|
|
11
11
|
writeOpenclawMcpConfig
|
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
CODEX_LISTEN_CAP_MS,
|
|
50
50
|
buildCondensedTandemRules,
|
|
51
51
|
buildWebhookReceiverNote
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-FJUAMJHU.js";
|
|
53
53
|
|
|
54
54
|
// src/wizard/pair-slot.ts
|
|
55
55
|
import fs from "fs";
|
|
@@ -790,7 +790,7 @@ function whatHappensNext(runtime, opts) {
|
|
|
790
790
|
return lines.join("\n");
|
|
791
791
|
}
|
|
792
792
|
async function configureClaudeCode(opts) {
|
|
793
|
-
const { runInit } = await import("./install-
|
|
793
|
+
const { runInit } = await import("./install-JQNDGAAQ.js");
|
|
794
794
|
const report = runInit({
|
|
795
795
|
...opts.configPath ? { configPath: opts.configPath } : {},
|
|
796
796
|
...opts.hooksPath ? { hooksPath: opts.hooksPath } : {},
|
|
@@ -854,7 +854,7 @@ function configureCodex(opts) {
|
|
|
854
854
|
const secret = connectPairedMode || !hasRealUrl ? void 0 : wh.secret || generateWebhookSecret();
|
|
855
855
|
const tokenArgs = opts.token && opts.url ? { token: opts.token, url: opts.url } : {};
|
|
856
856
|
const pairedArgs = opts.pairedConfigPath ? { pairedConfigPath: opts.pairedConfigPath } : {};
|
|
857
|
-
writeCodexConfig({
|
|
857
|
+
const writeResult = writeCodexConfig({
|
|
858
858
|
...opts.configPath ? { configPath: opts.configPath } : {},
|
|
859
859
|
...opts.hooksPath ? { hooksPath: opts.hooksPath } : {},
|
|
860
860
|
...url !== void 0 ? { webhookUrl: url } : {},
|
|
@@ -890,10 +890,12 @@ function configureCodex(opts) {
|
|
|
890
890
|
lines.push(indent(buildCodexStopHookBlock()));
|
|
891
891
|
lines.push(indent(buildCodexPromptSubmitHookBlock()));
|
|
892
892
|
lines.push("");
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
893
|
+
if (writeResult.hooksChanged) {
|
|
894
|
+
lines.push(
|
|
895
|
+
"IMPORTANT: Codex will re-prompt to trust hooks on its next launch \u2014 approve it, or wakes silently stop."
|
|
896
|
+
);
|
|
897
|
+
lines.push("");
|
|
898
|
+
}
|
|
897
899
|
lines.push(
|
|
898
900
|
connectPairedMode ? "webhook: (unchanged \u2014 `connect` rewrites only the credential args, not the wake path)" : `webhook: ${wh.url ? wh.redactedSummary : "OPTIONAL \u2014 not configured (wake is self-contained; set KOJEE_WEBHOOK_URL only for an extra low-latency push path)"}`
|
|
899
901
|
);
|
|
@@ -1033,7 +1035,7 @@ async function runWizardUninstall(runtime, opts) {
|
|
|
1033
1035
|
const effective = opts.runtime !== void 0 ? runtime : readRecordedRuntime() ?? runtime;
|
|
1034
1036
|
const lines = [`Uninstalling runtime: ${effective}`];
|
|
1035
1037
|
if (effective === "claude-code") {
|
|
1036
|
-
const { runUninstall } = await import("./install-
|
|
1038
|
+
const { runUninstall } = await import("./install-JQNDGAAQ.js");
|
|
1037
1039
|
const report = runUninstall({
|
|
1038
1040
|
...opts.configPath ? { configPath: opts.configPath } : {},
|
|
1039
1041
|
...opts.hooksPath ? { hooksPath: opts.hooksPath } : {}
|
package/dist/cli.js
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
} from "./chunk-EIAUW6KO.js";
|
|
5
5
|
import {
|
|
6
6
|
startProxy
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-ABECLEYE.js";
|
|
8
|
+
import "./chunk-TCWIXG5C.js";
|
|
9
9
|
import {
|
|
10
10
|
pairedConfigPath
|
|
11
11
|
} from "./chunk-5SZHXYPK.js";
|
|
@@ -18,11 +18,11 @@ import {
|
|
|
18
18
|
deriveKeystorePath
|
|
19
19
|
} from "./chunk-6G6YYST6.js";
|
|
20
20
|
import "./chunk-U5HHHRXA.js";
|
|
21
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-A4IOKD4Z.js";
|
|
22
22
|
import {
|
|
23
23
|
VERSION
|
|
24
24
|
} from "./chunk-5DHIUN73.js";
|
|
25
|
-
import "./chunk-
|
|
25
|
+
import "./chunk-FJUAMJHU.js";
|
|
26
26
|
import "./chunk-PPTKGWFF.js";
|
|
27
27
|
import "./chunk-XJEBJIQE.js";
|
|
28
28
|
import "./chunk-KNEJTD6G.js";
|
|
@@ -48,7 +48,7 @@ program.command("pair <code>").description("Pair this machine against Kojee usin
|
|
|
48
48
|
program.command("connect <code>").description(
|
|
49
49
|
"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."
|
|
50
50
|
).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) => {
|
|
51
|
-
const { runConnect } = await import("./connect-handler-
|
|
51
|
+
const { runConnect } = await import("./connect-handler-NZINEMG3.js");
|
|
52
52
|
const result = await runConnect({
|
|
53
53
|
code,
|
|
54
54
|
runtime: opts.runtime,
|
|
@@ -63,7 +63,7 @@ program.command("hook").description("Run a kojee MCP hook script (called by Clau
|
|
|
63
63
|
"Hook type: stop, user-prompt-submit, codex-stop, or codex-prompt-submit"
|
|
64
64
|
).action(async (opts) => {
|
|
65
65
|
if (opts.type === "stop") {
|
|
66
|
-
const { runStopHook } = await import("./stop-hook-
|
|
66
|
+
const { runStopHook } = await import("./stop-hook-N6TX4YQT.js");
|
|
67
67
|
await runStopHook();
|
|
68
68
|
process.exit(0);
|
|
69
69
|
} else if (opts.type === "user-prompt-submit") {
|
|
@@ -71,11 +71,11 @@ program.command("hook").description("Run a kojee MCP hook script (called by Clau
|
|
|
71
71
|
await runUserPromptSubmitHook();
|
|
72
72
|
process.exit(0);
|
|
73
73
|
} else if (opts.type === "codex-stop") {
|
|
74
|
-
const { runCodexStopHook } = await import("./codex-stop-hook-
|
|
74
|
+
const { runCodexStopHook } = await import("./codex-stop-hook-32W4BIOM.js");
|
|
75
75
|
await runCodexStopHook();
|
|
76
76
|
process.exit(0);
|
|
77
77
|
} else if (opts.type === "codex-prompt-submit") {
|
|
78
|
-
const { runCodexPromptSubmitHook } = await import("./codex-prompt-submit-hook-
|
|
78
|
+
const { runCodexPromptSubmitHook } = await import("./codex-prompt-submit-hook-J5PZEJSK.js");
|
|
79
79
|
await runCodexPromptSubmitHook();
|
|
80
80
|
process.exit(0);
|
|
81
81
|
} else {
|
|
@@ -86,7 +86,7 @@ program.command("hook").description("Run a kojee MCP hook script (called by Clau
|
|
|
86
86
|
}
|
|
87
87
|
});
|
|
88
88
|
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) => {
|
|
89
|
-
const { installHooks, uninstallHooks } = await import("./install-
|
|
89
|
+
const { installHooks, uninstallHooks } = await import("./install-JQNDGAAQ.js");
|
|
90
90
|
if (opts.uninstall) {
|
|
91
91
|
const removed = uninstallHooks({ hooksPath: opts.hooksPath });
|
|
92
92
|
console.error(removed ? "Removed kojee hook entries." : "No kojee hook entries found.");
|
|
@@ -124,7 +124,7 @@ program.command("tail <path>").description("Stream a file's contents and follow
|
|
|
124
124
|
}
|
|
125
125
|
});
|
|
126
126
|
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 () => {
|
|
127
|
-
const { runDoctor } = await import("./doctor-
|
|
127
|
+
const { runDoctor } = await import("./doctor-WUU5BVPT.js");
|
|
128
128
|
const code = await runDoctor();
|
|
129
129
|
process.exit(code);
|
|
130
130
|
});
|
|
@@ -143,7 +143,7 @@ function addInstallOptions(cmd, runtimeHelp) {
|
|
|
143
143
|
function makeInstallAction(verb) {
|
|
144
144
|
return async (opts) => {
|
|
145
145
|
const interactive = process.stdin.isTTY === true && opts.runtime === void 0;
|
|
146
|
-
const { runSetup, resolvePairCode } = await import("./setup-handler-
|
|
146
|
+
const { runSetup, resolvePairCode } = await import("./setup-handler-44ASXYMS.js");
|
|
147
147
|
const pairCode = resolvePairCode(opts);
|
|
148
148
|
const result = await runSetup({
|
|
149
149
|
verb,
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
DEFAULT_BROKER_URL,
|
|
3
3
|
reconcileConnectPairSlot,
|
|
4
4
|
runWizard
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-XPIW4N55.js";
|
|
6
|
+
import "./chunk-6XWTUDWW.js";
|
|
7
7
|
import "./chunk-E6WMFMM2.js";
|
|
8
8
|
import "./chunk-77HWBSRH.js";
|
|
9
9
|
import "./chunk-TMCNB4JH.js";
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
} from "./chunk-6G6YYST6.js";
|
|
31
31
|
import "./chunk-U5HHHRXA.js";
|
|
32
32
|
import "./chunk-5DHIUN73.js";
|
|
33
|
-
import "./chunk-
|
|
33
|
+
import "./chunk-FJUAMJHU.js";
|
|
34
34
|
|
|
35
35
|
// src/wizard/connect-handler.ts
|
|
36
36
|
import os from "os";
|
|
@@ -18,7 +18,7 @@ import "./chunk-U5HHHRXA.js";
|
|
|
18
18
|
import {
|
|
19
19
|
buildMonitorSpawn,
|
|
20
20
|
buildReplyRecipe
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-FJUAMJHU.js";
|
|
22
22
|
import {
|
|
23
23
|
deriveDiscoveryKey,
|
|
24
24
|
findClaudeAncestorPid
|
|
@@ -354,7 +354,7 @@ function formatDoctorReport(report) {
|
|
|
354
354
|
async function runDoctor() {
|
|
355
355
|
const { readRecordedRuntime } = await import("./runtime-record-OXRLTOLC.js");
|
|
356
356
|
if (readRecordedRuntime() === "codex") {
|
|
357
|
-
const { collectCodexDoctorReport, formatCodexDoctorReport } = await import("./doctor-codex-
|
|
357
|
+
const { collectCodexDoctorReport, formatCodexDoctorReport } = await import("./doctor-codex-PJFWIABF.js");
|
|
358
358
|
const report2 = collectCodexDoctorReport();
|
|
359
359
|
console.error(formatCodexDoctorReport(report2));
|
|
360
360
|
return report2.verdict === "broken" ? 1 : 0;
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
defaultCodexConfigPath,
|
|
3
3
|
defaultCodexHooksPath,
|
|
4
4
|
isPlaceholderWebhookUrl
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6XWTUDWW.js";
|
|
6
6
|
import "./chunk-TMCNB4JH.js";
|
|
7
7
|
import "./chunk-D6JKFJ6A.js";
|
|
8
8
|
import {
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
} from "./chunk-5DHIUN73.js";
|
|
21
21
|
import {
|
|
22
22
|
CODEX_LISTEN_CAP_MS
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-FJUAMJHU.js";
|
|
24
24
|
|
|
25
25
|
// src/doctor-codex.ts
|
|
26
26
|
import fs from "fs";
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
listTandemIds,
|
|
3
3
|
startProxy
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-ABECLEYE.js";
|
|
5
|
+
import "./chunk-TCWIXG5C.js";
|
|
6
6
|
import "./chunk-247WFMCJ.js";
|
|
7
7
|
import "./chunk-Z5LPNJQ6.js";
|
|
8
8
|
import "./chunk-I67C2HYA.js";
|
|
9
9
|
import "./chunk-MIEI4PLB.js";
|
|
10
10
|
import "./chunk-6G6YYST6.js";
|
|
11
11
|
import "./chunk-U5HHHRXA.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-A4IOKD4Z.js";
|
|
13
13
|
import "./chunk-5DHIUN73.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-FJUAMJHU.js";
|
|
15
15
|
import "./chunk-PPTKGWFF.js";
|
|
16
16
|
import "./chunk-XJEBJIQE.js";
|
|
17
17
|
import "./chunk-KNEJTD6G.js";
|
|
@@ -93,7 +93,19 @@ function installHooks(opts = {}) {
|
|
|
93
93
|
const cfg = readConfig(p);
|
|
94
94
|
const stop = installHookEntry(cfg, "Stop", buildHookCommand("stop"));
|
|
95
95
|
const ups = installHookEntry(cfg, "UserPromptSubmit", buildHookCommand("user-prompt-submit"));
|
|
96
|
-
|
|
96
|
+
if (stop !== "already-installed" || ups !== "already-installed") {
|
|
97
|
+
writeConfig(p, cfg);
|
|
98
|
+
} else {
|
|
99
|
+
const newContent = JSON.stringify(cfg, null, 2);
|
|
100
|
+
let onDisk = "";
|
|
101
|
+
try {
|
|
102
|
+
onDisk = fs.readFileSync(p, "utf8");
|
|
103
|
+
} catch {
|
|
104
|
+
}
|
|
105
|
+
if (newContent !== onDisk) {
|
|
106
|
+
writeConfig(p, cfg);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
97
109
|
return { stop, ups };
|
|
98
110
|
}
|
|
99
111
|
function uninstallHooks(opts = {}) {
|
|
@@ -13,12 +13,12 @@ import {
|
|
|
13
13
|
} from "./chunk-IZN7IZPW.js";
|
|
14
14
|
import {
|
|
15
15
|
claudeCodeAdapter
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-TCWIXG5C.js";
|
|
17
|
+
import "./chunk-A4IOKD4Z.js";
|
|
18
18
|
import {
|
|
19
19
|
VERSION
|
|
20
20
|
} from "./chunk-5DHIUN73.js";
|
|
21
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-FJUAMJHU.js";
|
|
22
22
|
import "./chunk-PPTKGWFF.js";
|
|
23
23
|
|
|
24
24
|
// src/delivery/lib/fanout.ts
|
|
@@ -127,7 +127,7 @@ function createClaudeCodeDelivery() {
|
|
|
127
127
|
const { resolveWebhookConfig } = await import("./webhook-config-O4WMQ532.js");
|
|
128
128
|
const { createWebhookSink } = await import("./webhook-sink-N6AUTFL3.js");
|
|
129
129
|
const { startEventStream } = await import("./event-stream-WPN3EN7C.js");
|
|
130
|
-
const { createMcpServer } = await import("./server-
|
|
130
|
+
const { createMcpServer } = await import("./server-DU3LFS32.js");
|
|
131
131
|
const { deriveDiscoveryKey } = await import("./ancestry-A2F5KQ6A.js");
|
|
132
132
|
const { resolveSharedSessionId } = await import("./cc-session-id-RURNIHHC.js");
|
|
133
133
|
sweepStaleDiscovery();
|
|
@@ -324,7 +324,7 @@ function createWebhookDelivery(name, pendingLedger) {
|
|
|
324
324
|
const { createWebhookSink } = await import("./webhook-sink-N6AUTFL3.js");
|
|
325
325
|
const { resubscribeMemberships } = await import("./resubscribe-G5OGDZJD.js");
|
|
326
326
|
const { startEventStream } = await import("./event-stream-WPN3EN7C.js");
|
|
327
|
-
const { createMcpServer } = await import("./server-
|
|
327
|
+
const { createMcpServer } = await import("./server-DU3LFS32.js");
|
|
328
328
|
sweepStaleEventLogs();
|
|
329
329
|
eventLog = startEventLog({
|
|
330
330
|
key: ctx.instanceKey,
|
|
@@ -518,7 +518,7 @@ function createOpenclawDelivery(deps = {}) {
|
|
|
518
518
|
const { startEventLog, sweepStaleEventLogs } = await import("./event-log-2NBJEIEP.js");
|
|
519
519
|
const { resubscribeMemberships } = await import("./resubscribe-G5OGDZJD.js");
|
|
520
520
|
const { startEventStream } = await import("./event-stream-WPN3EN7C.js");
|
|
521
|
-
const { createMcpServer } = await import("./server-
|
|
521
|
+
const { createMcpServer } = await import("./server-DU3LFS32.js");
|
|
522
522
|
sweepStaleEventLogs();
|
|
523
523
|
eventLog = startEventLog({
|
|
524
524
|
key: ctx.instanceKey,
|
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
executeToolCall,
|
|
6
6
|
extractDrainCursor,
|
|
7
7
|
startMcpServer
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-A4IOKD4Z.js";
|
|
9
9
|
import "./chunk-5DHIUN73.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-FJUAMJHU.js";
|
|
11
11
|
import "./chunk-PPTKGWFF.js";
|
|
12
12
|
export {
|
|
13
13
|
buildChannelInstructions,
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
pairSlotFor,
|
|
4
4
|
reconcileConnectPairSlot,
|
|
5
5
|
runWizard
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-XPIW4N55.js";
|
|
7
|
+
import "./chunk-6XWTUDWW.js";
|
|
8
8
|
import "./chunk-E6WMFMM2.js";
|
|
9
9
|
import {
|
|
10
10
|
isWizardRuntime
|
|
@@ -26,7 +26,7 @@ import "./chunk-MIEI4PLB.js";
|
|
|
26
26
|
import "./chunk-6G6YYST6.js";
|
|
27
27
|
import "./chunk-U5HHHRXA.js";
|
|
28
28
|
import "./chunk-5DHIUN73.js";
|
|
29
|
-
import "./chunk-
|
|
29
|
+
import "./chunk-FJUAMJHU.js";
|
|
30
30
|
|
|
31
31
|
// src/wizard/setup-handler.ts
|
|
32
32
|
var SETUP_SUPPORTED_RUNTIMES = ["claude-code", "codex"];
|
package/package.json
CHANGED
|
@@ -25,7 +25,7 @@ not your every sentence. When the hats tension, the principal wins.
|
|
|
25
25
|
- **Close every loop.** Taking an item, done (with evidence), or blocked (name the blocker + who clears it) — say so. Silence is a bug on a team.
|
|
26
26
|
- **Plan your wake path per task, re-plan as it changes.** Heads-down → mentions + a heartbeat floor; waiting on one reply → listen/filter to that seat; co-working → wake on all; standby → mentions + hourly heartbeat. Move your filter deliberately, and tell the room your posture when it changes — a plain re-join/reconnect with the same posture needs no check-in message.
|
|
27
27
|
- **Don't assume others use the room well — engineer around it.** Poll for gaps, confirm receipt when it matters, resend a mention that didn't land, never block forever on a peer who may be dark.
|
|
28
|
-
- **Signal cheap, wake rarely.** Acknowledge with a non-waking
|
|
28
|
+
- **Signal cheap, wake rarely.** Acknowledge with a reaction or ack (non-waking); reserve a message for what *changes someone's next move*. Cheap signals are reactions/acks — never `kind=status` messages (status is lifecycle-only, system-generated for joined/left events; never send it yourself).
|
|
29
29
|
- **Take your lane.** Don't duplicate, collide, or redo a teammate's work; settle unclear ownership in one message first.
|
|
30
30
|
- **Be a reliable, considerate presence.** Recover yourself from a dropped session — don't make others restart you — and pace your load on the shared account.
|
|
31
31
|
|