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
|
@@ -3,18 +3,22 @@ import {
|
|
|
3
3
|
STATUS_LINE_PREFIX,
|
|
4
4
|
monitorHeartbeatPath,
|
|
5
5
|
statusLogPath
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-TNZITJAB.js";
|
|
7
|
+
import "./chunk-67F67AQ6.js";
|
|
8
8
|
import {
|
|
9
9
|
createAdaptiveWatchdog
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-FSKGQ6GT.js";
|
|
11
|
+
import "./chunk-Z5LPNJQ6.js";
|
|
12
|
+
import "./chunk-MIEI4PLB.js";
|
|
13
|
+
import "./chunk-U5HHHRXA.js";
|
|
13
14
|
|
|
14
15
|
// src/tail-stream.ts
|
|
15
16
|
import fs from "fs";
|
|
16
17
|
var STATUS_LINE_RE = new RegExp(`^\\[[^\\]]*\\] ${STATUS_LINE_PREFIX} (.*)$`);
|
|
17
18
|
var HEARTBEAT_FIELDS_RE = /(^|\s)status=heartbeat(\s|$)/;
|
|
19
|
+
var ROTATED_FIELDS_RE = /(^|\s)status=rotated(\s|$)/;
|
|
20
|
+
var ROTATED_DROPPED_RE = /(^|\s)dropped=(\d+)(\s|$)/;
|
|
21
|
+
var MESSAGE_CURSOR_RE = /(^|\s)cursor=(\S+)(\s|$)/;
|
|
18
22
|
var HEARTBEAT_STALE_FLOOR_MS = envInt("KOJEE_TAIL_STALE_MS", 12e4);
|
|
19
23
|
var STALE_CHECK_INTERVAL_MS = envInt("KOJEE_TAIL_CHECK_MS", 5e3);
|
|
20
24
|
function envInt(name, fallback) {
|
|
@@ -38,14 +42,18 @@ async function runTail(messagesPath) {
|
|
|
38
42
|
}
|
|
39
43
|
}
|
|
40
44
|
};
|
|
45
|
+
let lastCursor = null;
|
|
41
46
|
function onMessageLine(line) {
|
|
42
47
|
lastLifeAt = Date.now();
|
|
43
48
|
if (staleAnnounced) {
|
|
44
49
|
staleAnnounced = false;
|
|
45
50
|
process.stdout.write("[kojee] stream recovered \u2014 events flowing again.\n");
|
|
46
51
|
}
|
|
52
|
+
const cm = MESSAGE_CURSOR_RE.exec(line);
|
|
53
|
+
if (cm && cm[2]) lastCursor = cm[2];
|
|
47
54
|
process.stdout.write(line + "\n");
|
|
48
55
|
}
|
|
56
|
+
let statusSeeded = false;
|
|
49
57
|
function onStatusLine(line) {
|
|
50
58
|
const now = Date.now();
|
|
51
59
|
const m = STATUS_LINE_RE.exec(line);
|
|
@@ -58,12 +66,27 @@ async function runTail(messagesPath) {
|
|
|
58
66
|
staleAnnounced = false;
|
|
59
67
|
process.stdout.write("[kojee] stream recovered \u2014 heartbeats resumed.\n");
|
|
60
68
|
}
|
|
69
|
+
if (statusSeeded && ROTATED_FIELDS_RE.test(fields)) {
|
|
70
|
+
const dm = ROTATED_DROPPED_RE.exec(fields);
|
|
71
|
+
const dropped = dm ? dm[2] : "?";
|
|
72
|
+
const since = lastCursor ? `since=${lastCursor}` : "since=<your last cursor>";
|
|
73
|
+
process.stdout.write(
|
|
74
|
+
`[kojee] WARNING: event log rotated (dropped=${dropped}) \u2014 older events were truncated and may have been missed; run tandem_messages(${since}) to backfill.
|
|
75
|
+
`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
61
78
|
}
|
|
62
79
|
const followers = [
|
|
63
80
|
makeFollower(messagesPath, onMessageLine, touchHeartbeat),
|
|
64
81
|
makeFollower(statusPath, onStatusLine, touchHeartbeat)
|
|
65
82
|
];
|
|
66
|
-
void Promise.all(
|
|
83
|
+
void Promise.all([
|
|
84
|
+
followers[0].start(),
|
|
85
|
+
followers[1].start().then(() => {
|
|
86
|
+
statusSeeded = true;
|
|
87
|
+
})
|
|
88
|
+
]).catch(() => {
|
|
89
|
+
});
|
|
67
90
|
const staleTimer = setInterval(() => {
|
|
68
91
|
if (staleAnnounced) return;
|
|
69
92
|
const now = Date.now();
|
|
@@ -107,21 +130,32 @@ function makeFollower(filePath, onLine, onActivity) {
|
|
|
107
130
|
offset = 0;
|
|
108
131
|
}
|
|
109
132
|
if (stat.size === offset) return;
|
|
110
|
-
|
|
133
|
+
let fh = null;
|
|
134
|
+
let chunk = null;
|
|
111
135
|
try {
|
|
136
|
+
fh = await fs.promises.open(filePath, "r");
|
|
112
137
|
const len = stat.size - offset;
|
|
113
138
|
const buf = Buffer.alloc(len);
|
|
114
139
|
await fh.read(buf, 0, len, offset);
|
|
115
|
-
|
|
140
|
+
chunk = buf.toString("utf8");
|
|
116
141
|
offset = stat.size;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const line = buffer.slice(0, nl);
|
|
120
|
-
buffer = buffer.slice(nl + 1);
|
|
121
|
-
onLine(line);
|
|
122
|
-
}
|
|
142
|
+
} catch {
|
|
143
|
+
chunk = null;
|
|
123
144
|
} finally {
|
|
124
|
-
|
|
145
|
+
if (fh) {
|
|
146
|
+
try {
|
|
147
|
+
await fh.close();
|
|
148
|
+
} catch {
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (chunk === null) return;
|
|
153
|
+
buffer += chunk;
|
|
154
|
+
let nl;
|
|
155
|
+
while ((nl = buffer.indexOf("\n")) !== -1) {
|
|
156
|
+
const line = buffer.slice(0, nl);
|
|
157
|
+
buffer = buffer.slice(nl + 1);
|
|
158
|
+
onLine(line);
|
|
125
159
|
}
|
|
126
160
|
}
|
|
127
161
|
let draining = Promise.resolve();
|
|
@@ -137,17 +171,21 @@ function makeFollower(filePath, onLine, onActivity) {
|
|
|
137
171
|
if (stopped) return;
|
|
138
172
|
onActivity();
|
|
139
173
|
await scheduleDrain();
|
|
140
|
-
watcher = fs.watch(filePath, { persistent: true });
|
|
141
|
-
watcher.on("change", () => {
|
|
142
|
-
onActivity();
|
|
143
|
-
void scheduleDrain();
|
|
144
|
-
});
|
|
145
|
-
watcher.on("error", () => {
|
|
146
|
-
});
|
|
147
174
|
pollTimer = setInterval(() => {
|
|
148
175
|
onActivity();
|
|
149
176
|
void scheduleDrain();
|
|
150
177
|
}, 1e3);
|
|
178
|
+
try {
|
|
179
|
+
watcher = fs.watch(filePath, { persistent: true });
|
|
180
|
+
watcher.on("change", () => {
|
|
181
|
+
onActivity();
|
|
182
|
+
void scheduleDrain();
|
|
183
|
+
});
|
|
184
|
+
watcher.on("error", () => {
|
|
185
|
+
});
|
|
186
|
+
} catch {
|
|
187
|
+
watcher = null;
|
|
188
|
+
}
|
|
151
189
|
},
|
|
152
190
|
stop() {
|
|
153
191
|
stopped = true;
|
|
@@ -160,5 +198,6 @@ function sleep(ms) {
|
|
|
160
198
|
return new Promise((r) => setTimeout(r, ms));
|
|
161
199
|
}
|
|
162
200
|
export {
|
|
201
|
+
makeFollower,
|
|
163
202
|
runTail
|
|
164
203
|
};
|
|
@@ -1,27 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-
|
|
2
|
+
resolveHookDiscovery
|
|
3
|
+
} from "./chunk-WBXU27BF.js";
|
|
4
4
|
import {
|
|
5
5
|
readHookStdin
|
|
6
6
|
} from "./chunk-LSUB6QMP.js";
|
|
7
|
-
import {
|
|
8
|
-
readSessionDiscoveryByKey
|
|
9
|
-
} from "./chunk-DO42NPNR.js";
|
|
10
7
|
import {
|
|
11
8
|
controlTokenAuthHeaders
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-BLEGIR35.js";
|
|
9
|
+
} from "./chunk-GKXHKR3B.js";
|
|
14
10
|
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
formatChannelEvents
|
|
12
|
+
} from "./chunk-PHXO5P25.js";
|
|
13
|
+
import "./chunk-67F67AQ6.js";
|
|
14
|
+
import "./chunk-U5HHHRXA.js";
|
|
15
|
+
import "./chunk-XJEBJIQE.js";
|
|
16
|
+
import "./chunk-KNEJTD6G.js";
|
|
18
17
|
|
|
19
18
|
// src/hooks/user-prompt-submit-hook.ts
|
|
20
19
|
async function runUserPromptSubmitHook() {
|
|
21
|
-
await readHookStdin();
|
|
22
|
-
const
|
|
23
|
-
const key = deriveDiscoveryKey(process.env["CLAUDE_PROJECT_DIR"], ccPid);
|
|
24
|
-
const discovery = readSessionDiscoveryByKey(key);
|
|
20
|
+
const { sessionId: stdinSessionId } = await readHookStdin();
|
|
21
|
+
const { discovery } = await resolveHookDiscovery(stdinSessionId);
|
|
25
22
|
if (!discovery) {
|
|
26
23
|
process.stdout.write("{}");
|
|
27
24
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kojee-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"jose": "^5.0.0",
|
|
34
34
|
"ps-list": "^8.1.1",
|
|
35
35
|
"ulidx": "^2.3.0",
|
|
36
|
+
"undici": "^8.5.0",
|
|
36
37
|
"zod": "^3.22.0"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
package/dist/chunk-BLEGIR35.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
// src/secure-file.ts
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
import os from "os";
|
|
4
|
-
import { execFileSync } from "child_process";
|
|
5
|
-
function isWindows() {
|
|
6
|
-
return process.platform === "win32";
|
|
7
|
-
}
|
|
8
|
-
function secureFile(filePath) {
|
|
9
|
-
if (isWindows()) {
|
|
10
|
-
restrictAclToCurrentUser(filePath, "(F)");
|
|
11
|
-
} else {
|
|
12
|
-
try {
|
|
13
|
-
fs.chmodSync(filePath, 384);
|
|
14
|
-
} catch {
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function secureDir(dirPath) {
|
|
19
|
-
if (isWindows()) {
|
|
20
|
-
restrictAclToCurrentUser(dirPath, "(OI)(CI)(F)");
|
|
21
|
-
} else {
|
|
22
|
-
try {
|
|
23
|
-
fs.chmodSync(dirPath, 448);
|
|
24
|
-
} catch {
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
function restrictAclToCurrentUser(target, permission) {
|
|
29
|
-
try {
|
|
30
|
-
const user = os.userInfo().username;
|
|
31
|
-
execFileSync(
|
|
32
|
-
"icacls",
|
|
33
|
-
[target, "/inheritance:r", "/grant:r", `${user}:${permission}`],
|
|
34
|
-
{ stdio: "ignore" }
|
|
35
|
-
);
|
|
36
|
-
} catch {
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export {
|
|
41
|
-
secureFile,
|
|
42
|
-
secureDir
|
|
43
|
-
};
|
package/dist/chunk-CLKCNV2A.js
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
kojeeHomeDir
|
|
3
|
-
} from "./chunk-SQL56SEB.js";
|
|
4
|
-
import {
|
|
5
|
-
secureFile
|
|
6
|
-
} from "./chunk-BLEGIR35.js";
|
|
7
|
-
|
|
8
|
-
// src/wizard/capabilities/openclaw-channel-config.ts
|
|
9
|
-
import fs from "fs";
|
|
10
|
-
import path from "path";
|
|
11
|
-
function defaultOpenclawConfigPath() {
|
|
12
|
-
return path.join(kojeeHomeDir(), ".openclaw", "config.json");
|
|
13
|
-
}
|
|
14
|
-
var CHANNEL_ID = "kojee-tandem";
|
|
15
|
-
function mergeOpenclawChannelConfig(existing, block) {
|
|
16
|
-
const prevChannels = existing.channels && typeof existing.channels === "object" ? existing.channels : {};
|
|
17
|
-
return {
|
|
18
|
-
...existing,
|
|
19
|
-
channels: {
|
|
20
|
-
...prevChannels,
|
|
21
|
-
[CHANNEL_ID]: { ...block }
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
function readOpenclawConfig(configPath) {
|
|
26
|
-
try {
|
|
27
|
-
const parsed = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
28
|
-
return parsed && typeof parsed === "object" ? parsed : {};
|
|
29
|
-
} catch {
|
|
30
|
-
return {};
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function readOpenclawConfigState(configPath) {
|
|
34
|
-
let raw;
|
|
35
|
-
try {
|
|
36
|
-
raw = fs.readFileSync(configPath, "utf8");
|
|
37
|
-
} catch {
|
|
38
|
-
return { cfg: {}, unparseable: false };
|
|
39
|
-
}
|
|
40
|
-
try {
|
|
41
|
-
const parsed = JSON.parse(raw);
|
|
42
|
-
return {
|
|
43
|
-
cfg: parsed && typeof parsed === "object" ? parsed : {},
|
|
44
|
-
unparseable: false
|
|
45
|
-
};
|
|
46
|
-
} catch {
|
|
47
|
-
return { cfg: {}, unparseable: true };
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
function atomicWrite(filePath, content, secret) {
|
|
51
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
52
|
-
const tmp = `${filePath}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
|
|
53
|
-
fs.writeFileSync(tmp, content, { ...secret ? { mode: 384 } : {} });
|
|
54
|
-
if (secret) secureFile(tmp);
|
|
55
|
-
fs.renameSync(tmp, filePath);
|
|
56
|
-
if (secret) secureFile(filePath);
|
|
57
|
-
}
|
|
58
|
-
function writeOpenclawChannelConfig(configPath, block, opts = {}) {
|
|
59
|
-
const { cfg, unparseable } = readOpenclawConfigState(configPath);
|
|
60
|
-
let backedUp;
|
|
61
|
-
if (unparseable) {
|
|
62
|
-
const stamp = opts.timestamp ?? corruptStamp();
|
|
63
|
-
backedUp = `${configPath}.corrupt-${stamp}`;
|
|
64
|
-
fs.copyFileSync(configPath, backedUp);
|
|
65
|
-
}
|
|
66
|
-
const merged = mergeOpenclawChannelConfig(cfg, block);
|
|
67
|
-
atomicWrite(configPath, JSON.stringify(merged, null, 2) + "\n", Boolean(block.credential));
|
|
68
|
-
return backedUp ? { backedUp } : {};
|
|
69
|
-
}
|
|
70
|
-
function corruptStamp() {
|
|
71
|
-
return (/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/g, "").replace(/\.\d+Z$/, "Z");
|
|
72
|
-
}
|
|
73
|
-
function removeOpenclawChannel(configPath) {
|
|
74
|
-
let raw;
|
|
75
|
-
try {
|
|
76
|
-
raw = fs.readFileSync(configPath, "utf8");
|
|
77
|
-
} catch {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
let cfg;
|
|
81
|
-
try {
|
|
82
|
-
cfg = JSON.parse(raw);
|
|
83
|
-
} catch {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
const channels = cfg.channels && typeof cfg.channels === "object" ? cfg.channels : void 0;
|
|
87
|
-
if (!channels || !(CHANNEL_ID in channels)) return false;
|
|
88
|
-
const { [CHANNEL_ID]: _removed, ...rest } = channels;
|
|
89
|
-
const next = { ...cfg, channels: rest };
|
|
90
|
-
atomicWrite(configPath, JSON.stringify(next, null, 2) + "\n", false);
|
|
91
|
-
return true;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export {
|
|
95
|
-
defaultOpenclawConfigPath,
|
|
96
|
-
CHANNEL_ID,
|
|
97
|
-
readOpenclawConfig,
|
|
98
|
-
writeOpenclawChannelConfig,
|
|
99
|
-
removeOpenclawChannel
|
|
100
|
-
};
|
package/dist/chunk-OGHDTFAX.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
loadPairedConfig,
|
|
3
|
-
savePairedConfig
|
|
4
|
-
} from "./chunk-YH27B6SW.js";
|
|
5
|
-
import {
|
|
6
|
-
AuthModule
|
|
7
|
-
} from "./chunk-JXMVZEQ7.js";
|
|
8
|
-
|
|
9
|
-
// src/tandem/pair.ts
|
|
10
|
-
import fs from "fs";
|
|
11
|
-
async function runPair(opts) {
|
|
12
|
-
if (loadPairedConfig(opts.configPath) !== null) {
|
|
13
|
-
throw new Error(
|
|
14
|
-
`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.`
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
try {
|
|
18
|
-
fs.unlinkSync(opts.keystorePath);
|
|
19
|
-
} catch {
|
|
20
|
-
}
|
|
21
|
-
const auth = new AuthModule(opts.code, opts.url, opts.keystorePath);
|
|
22
|
-
await auth.ensureEnrolled();
|
|
23
|
-
let principal_id;
|
|
24
|
-
let agent_id;
|
|
25
|
-
try {
|
|
26
|
-
const me = await fetch(`${opts.url}/api/v1/users/me/`, {
|
|
27
|
-
headers: { Authorization: `DPoP ${opts.code}` }
|
|
28
|
-
});
|
|
29
|
-
if (me.ok) {
|
|
30
|
-
const body = await me.json();
|
|
31
|
-
principal_id = body.principal_id;
|
|
32
|
-
agent_id = body.agent_id;
|
|
33
|
-
}
|
|
34
|
-
} catch {
|
|
35
|
-
}
|
|
36
|
-
const config = {
|
|
37
|
-
token: opts.code,
|
|
38
|
-
broker_url: opts.url,
|
|
39
|
-
paired_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
40
|
-
...principal_id ? { principal_id } : {},
|
|
41
|
-
...agent_id ? { agent_id } : {}
|
|
42
|
-
};
|
|
43
|
-
savePairedConfig(opts.configPath, config);
|
|
44
|
-
const who = principal_id && agent_id ? `${principal_id} (${agent_id})` : "(use kojee-mcp without args to start the proxy)";
|
|
45
|
-
return { message: `Paired as ${who}. Keypair: ${opts.keystorePath}. Config: ${opts.configPath}.` };
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export {
|
|
49
|
-
runPair
|
|
50
|
-
};
|
package/dist/chunk-VHKPWUX7.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
// src/runtime/ancestry.ts
|
|
2
|
-
import psList from "ps-list";
|
|
3
|
-
import { createHash } from "crypto";
|
|
4
|
-
async function findClaudeAncestorPid(startPid = process.ppid) {
|
|
5
|
-
let processes;
|
|
6
|
-
try {
|
|
7
|
-
processes = await psList();
|
|
8
|
-
} catch {
|
|
9
|
-
return null;
|
|
10
|
-
}
|
|
11
|
-
const byPid = /* @__PURE__ */ new Map();
|
|
12
|
-
for (const p of processes) byPid.set(p.pid, p);
|
|
13
|
-
let pid = startPid;
|
|
14
|
-
for (let depth = 0; depth < 20 && pid !== void 0 && pid > 1; depth++) {
|
|
15
|
-
const row = byPid.get(pid);
|
|
16
|
-
if (!row) return null;
|
|
17
|
-
const haystack = `${row.name} ${row.cmd ?? ""}`;
|
|
18
|
-
if (/\bclaude\b/i.test(haystack)) return pid;
|
|
19
|
-
if (row.ppid === void 0 || row.ppid === pid) return null;
|
|
20
|
-
pid = row.ppid;
|
|
21
|
-
}
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
function deriveDiscoveryKey(projectDir, ccPid) {
|
|
25
|
-
const hasProjectDir = typeof projectDir === "string" && projectDir.length > 0;
|
|
26
|
-
if (!hasProjectDir && ccPid === null) {
|
|
27
|
-
return `orphan-${process.pid}`;
|
|
28
|
-
}
|
|
29
|
-
if (!hasProjectDir) {
|
|
30
|
-
const hash2 = createHash("sha256").update("<no-project>").digest("hex").slice(0, 12);
|
|
31
|
-
return `${hash2}-${ccPid}`;
|
|
32
|
-
}
|
|
33
|
-
const hash = createHash("sha256").update(projectDir).digest("hex").slice(0, 12);
|
|
34
|
-
if (ccPid === null) return `${hash}-orphan`;
|
|
35
|
-
return `${hash}-${ccPid}`;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export {
|
|
39
|
-
findClaudeAncestorPid,
|
|
40
|
-
deriveDiscoveryKey
|
|
41
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CODEX_PEEK_BUDGET_MS,
|
|
3
|
-
codexPendingMarkerPath,
|
|
4
|
-
decideCodexStopHook,
|
|
5
|
-
defaultPeekPending,
|
|
6
|
-
runCodexStopHook
|
|
7
|
-
} from "./chunk-35XBRG3V.js";
|
|
8
|
-
import "./chunk-LSUB6QMP.js";
|
|
9
|
-
import "./chunk-X672ZN7V.js";
|
|
10
|
-
export {
|
|
11
|
-
CODEX_PEEK_BUDGET_MS,
|
|
12
|
-
codexPendingMarkerPath,
|
|
13
|
-
decideCodexStopHook,
|
|
14
|
-
defaultPeekPending,
|
|
15
|
-
runCodexStopHook
|
|
16
|
-
};
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CHANNEL_ID,
|
|
3
|
-
defaultOpenclawConfigPath,
|
|
4
|
-
readOpenclawConfig
|
|
5
|
-
} from "./chunk-CLKCNV2A.js";
|
|
6
|
-
import "./chunk-SQL56SEB.js";
|
|
7
|
-
import {
|
|
8
|
-
loadPairedConfig
|
|
9
|
-
} from "./chunk-YH27B6SW.js";
|
|
10
|
-
import "./chunk-BLEGIR35.js";
|
|
11
|
-
|
|
12
|
-
// src/doctor-openclaw.ts
|
|
13
|
-
import { execFileSync } from "child_process";
|
|
14
|
-
var WIZARD_RERUN = "re-run `kojee-mcp init --runtime openclaw`";
|
|
15
|
-
var VERIFY_HINT = "openclaw plugins inspect kojee-tandem / openclaw channels status";
|
|
16
|
-
function resolveCredentialSource(block, env, loadPaired) {
|
|
17
|
-
const channelCred = typeof block.credential === "string" ? block.credential.trim() : "";
|
|
18
|
-
if (channelCred) return "config";
|
|
19
|
-
if ((env["KOJEE_GATEWAY_TOKEN"] ?? "").trim()) return "env";
|
|
20
|
-
const paired = loadPaired();
|
|
21
|
-
if (paired?.token) return "paired-config";
|
|
22
|
-
return "none";
|
|
23
|
-
}
|
|
24
|
-
function defaultCliProbe() {
|
|
25
|
-
try {
|
|
26
|
-
execFileSync("openclaw", ["plugins", "inspect", CHANNEL_ID], { stdio: "ignore" });
|
|
27
|
-
return true;
|
|
28
|
-
} catch (err) {
|
|
29
|
-
if (err?.code === "ENOENT") return null;
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function collectOpenclawDoctorReport(deps = {}) {
|
|
34
|
-
const readConfig = deps.readConfig ?? (() => readOpenclawConfig(defaultOpenclawConfigPath()));
|
|
35
|
-
const env = deps.env ?? process.env;
|
|
36
|
-
const loadPaired = deps.loadPaired ?? (() => loadPairedConfig());
|
|
37
|
-
const checks = [];
|
|
38
|
-
const cfg = readConfig();
|
|
39
|
-
const channels = cfg.channels && typeof cfg.channels === "object" ? cfg.channels : {};
|
|
40
|
-
const block = channels[CHANNEL_ID] && typeof channels[CHANNEL_ID] === "object" ? channels[CHANNEL_ID] : null;
|
|
41
|
-
const enabled = block?.enabled === true;
|
|
42
|
-
checks.push({
|
|
43
|
-
name: `~/.openclaw/config.json channels.${CHANNEL_ID}`,
|
|
44
|
-
ok: enabled,
|
|
45
|
-
detail: enabled ? "present with enabled:true (the wizard-written channel block)" : block ? `present but enabled:false \u2014 ${WIZARD_RERUN}` : `MISSING channels.${CHANNEL_ID} block \u2014 ${WIZARD_RERUN}`
|
|
46
|
-
});
|
|
47
|
-
const source = resolveCredentialSource(block ?? {}, env, loadPaired);
|
|
48
|
-
const credOk = source !== "none";
|
|
49
|
-
checks.push({
|
|
50
|
-
name: "gateway credential",
|
|
51
|
-
ok: credOk,
|
|
52
|
-
detail: credOk ? `resolves \u2014 source: ${source} (token value never printed)` : `NONE resolves (no channel credential, KOJEE_GATEWAY_TOKEN, or paired ~/.kojee/config.json) \u2014 ${WIZARD_RERUN}`
|
|
53
|
-
});
|
|
54
|
-
const probed = deps.openclawCliProbe ? deps.openclawCliProbe() : defaultCliProbe();
|
|
55
|
-
if (probed === true) {
|
|
56
|
-
checks.push({
|
|
57
|
-
name: "openclaw plugin (kojee-tandem)",
|
|
58
|
-
ok: true,
|
|
59
|
-
detail: `discoverable via OpenClaw's plugin manager (\`${VERIFY_HINT}\`)`
|
|
60
|
-
});
|
|
61
|
-
} else if (probed === false) {
|
|
62
|
-
checks.push({
|
|
63
|
-
name: "openclaw plugin (kojee-tandem)",
|
|
64
|
-
ok: "warn",
|
|
65
|
-
detail: `NOT found by OpenClaw's plugin manager \u2014 install it: \`openclaw plugins install\`, then \`${VERIFY_HINT}\``
|
|
66
|
-
});
|
|
67
|
-
} else {
|
|
68
|
-
checks.push({
|
|
69
|
-
name: "openclaw plugin (kojee-tandem)",
|
|
70
|
-
ok: "warn",
|
|
71
|
-
detail: `owner-verify step (delegated install): confirm with \`${VERIFY_HINT}\``
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
const verdict = checks.some((c) => c.ok === false) ? "broken" : checks.some((c) => c.ok === "warn") ? "degraded" : "healthy";
|
|
75
|
-
return { checks, verdict };
|
|
76
|
-
}
|
|
77
|
-
function formatOpenclawDoctorReport(report) {
|
|
78
|
-
const mark = (ok) => ok === true ? "\u2713" : ok === "warn" ? "\u26A0" : ok === "unknown" ? "?" : "\u2717";
|
|
79
|
-
const lines = [];
|
|
80
|
-
lines.push(`kojee-mcp doctor (openclaw) \u2014 verdict: ${report.verdict.toUpperCase()}`);
|
|
81
|
-
lines.push("");
|
|
82
|
-
lines.push(" Wake mode: native OpenClaw channel plugin (in-process; the gateway streams Tandem events).");
|
|
83
|
-
lines.push(" Plugin install is delegated to OpenClaw's own plugin manager (the wizard owns only the channel config).");
|
|
84
|
-
lines.push("");
|
|
85
|
-
for (const c of report.checks) {
|
|
86
|
-
lines.push(` ${mark(c.ok)} ${c.name}: ${c.detail}`);
|
|
87
|
-
}
|
|
88
|
-
lines.push("");
|
|
89
|
-
lines.push(`NOTE: live openclaw verification (plugin loaded, gateway streaming) is an owner step: \`${VERIFY_HINT}\`.`);
|
|
90
|
-
return lines.join("\n");
|
|
91
|
-
}
|
|
92
|
-
export {
|
|
93
|
-
collectOpenclawDoctorReport,
|
|
94
|
-
formatOpenclawDoctorReport
|
|
95
|
-
};
|