khala-cli 0.4.8 → 0.4.10
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 +4 -4
- package/dist/THIRD_PARTY_NOTICES.txt +809 -0
- package/dist/chunk-2AMWQ7RB.mjs +1127 -0
- package/dist/chunk-3E5DH3Y6.mjs +9864 -0
- package/dist/{chunk-IQJQ4RF5.mjs → chunk-4BP7V3OP.mjs} +12 -1
- package/dist/{chunk-FV32AQTC.mjs → chunk-4BZQ4GVW.mjs} +10 -6
- package/dist/chunk-5JSGA6OB.mjs +1483 -0
- package/dist/chunk-6AQVW5W7.mjs +60 -0
- package/dist/{chunk-W6R4UJUQ.mjs → chunk-6J2PUM7L.mjs} +16 -9
- package/dist/chunk-6SUV3EW6.mjs +27 -0
- package/dist/{chunk-RNDUFTBF.mjs → chunk-ARIDZOTI.mjs} +499 -115
- package/dist/chunk-C2WEDMAF.mjs +15 -0
- package/dist/{chunk-Z4JF2M5C.mjs → chunk-CHC4VZF5.mjs} +9 -9
- package/dist/chunk-CKLCR5G4.mjs +1369 -0
- package/dist/chunk-EVT2DWNZ.mjs +58 -0
- package/dist/chunk-FJVVSKZ3.mjs +22 -0
- package/dist/{chunk-APMWDF6B.mjs → chunk-G3NMB4PY.mjs} +4 -2
- package/dist/chunk-HHEZVPRR.mjs +7 -0
- package/dist/{chunk-54XFVSEC.mjs → chunk-JKOJQTFT.mjs} +103 -5
- package/dist/{chunk-ZJ4W7P33.mjs → chunk-NDMFD5IM.mjs} +15 -10
- package/dist/{chunk-VKQ3KUYO.mjs → chunk-OEV5DFLW.mjs} +77 -7
- package/dist/chunk-OIZ4R5H7.mjs +173 -0
- package/dist/{chunk-CJTCU755.mjs → chunk-PJKI7SRI.mjs} +256 -26
- package/dist/chunk-PN25BUQ4.mjs +599 -0
- package/dist/chunk-QDPJ4VT2.mjs +432 -0
- package/dist/{chunk-2DHIAFEV.mjs → chunk-SRZTHCXP.mjs} +24 -10
- package/dist/chunk-TSK3HJEG.mjs +20 -0
- package/dist/chunk-UX34IVN5.mjs +33 -0
- package/dist/{chunk-BKLW2SPG.mjs → chunk-VAC3JTAV.mjs} +34 -17
- package/dist/{chunk-VAI7IUI4.mjs → chunk-VDZK4LW3.mjs} +30 -12
- package/dist/chunk-W6HM6F2U.mjs +901 -0
- package/dist/{chunk-H3K4GA2P.mjs → chunk-WPNMWNCL.mjs} +33 -21
- package/dist/chunk-WUDXHF2Q.mjs +14 -0
- package/dist/chunk-WZJ6DQJV.mjs +19 -0
- package/dist/{chunk-5LIE5GUU.mjs → chunk-XR625T3I.mjs} +5 -1
- package/dist/chunk-ZSKLNZWZ.mjs +224 -0
- package/dist/iterm2_send.py +56 -0
- package/dist/khala.mjs +20 -13
- package/dist/web/assets/local-CSPuGnH2.css +1 -0
- package/dist/web/assets/local-Dtyxaacx.js +9 -0
- package/dist/web/index.html +2 -2
- package/package.json +5 -3
- package/dist/chunk-2VCAW4GH.mjs +0 -34
- package/dist/chunk-5BQTYU66.mjs +0 -886
- package/dist/chunk-5GLTKWJ5.mjs +0 -1
- package/dist/chunk-5PUQT3YS.mjs +0 -569
- package/dist/chunk-7HBRFY3Z.mjs +0 -8
- package/dist/chunk-CBPLCCRZ.mjs +0 -191
- package/dist/chunk-FH34B3I3.mjs +0 -235
- package/dist/chunk-NKX3SLS7.mjs +0 -227
- package/dist/chunk-VUSV2ADL.mjs +0 -267
- package/dist/web/assets/local-BQl2KrE1.js +0 -9
- package/dist/web/assets/local-OwDq47O4.css +0 -1
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
sessionStartWakeChannels
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4BZQ4GVW.mjs";
|
|
5
5
|
import {
|
|
6
6
|
adapterFor
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-5JSGA6OB.mjs";
|
|
8
|
+
import "./chunk-6AQVW5W7.mjs";
|
|
9
|
+
import {
|
|
10
|
+
driverAllowed,
|
|
11
|
+
readListeningMode
|
|
12
|
+
} from "./chunk-2AMWQ7RB.mjs";
|
|
13
|
+
import "./chunk-4BP7V3OP.mjs";
|
|
14
|
+
import {
|
|
15
|
+
wakesAgent
|
|
16
|
+
} from "./chunk-OEV5DFLW.mjs";
|
|
17
|
+
import "./chunk-JKOJQTFT.mjs";
|
|
9
18
|
import {
|
|
10
19
|
filesForDir,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
import "./chunk-
|
|
20
|
+
readJson,
|
|
21
|
+
resolveStateDir,
|
|
22
|
+
stateRoot
|
|
23
|
+
} from "./chunk-PN25BUQ4.mjs";
|
|
24
|
+
import "./chunk-ZSKLNZWZ.mjs";
|
|
25
|
+
import {
|
|
26
|
+
init_define_KHALA_BUNDLE
|
|
27
|
+
} from "./chunk-EVT2DWNZ.mjs";
|
|
16
28
|
|
|
17
29
|
// hooks/claude-wake.ts
|
|
30
|
+
init_define_KHALA_BUNDLE();
|
|
18
31
|
import fs from "node:fs/promises";
|
|
19
32
|
import path from "node:path";
|
|
20
33
|
import { randomBytes } from "node:crypto";
|
|
@@ -22,7 +35,7 @@ import { setTimeout as sleep } from "node:timers/promises";
|
|
|
22
35
|
var NOTICE = "Khala: new channel messages. They arrive in the next hook context.\n";
|
|
23
36
|
var DEADLINE_MS = 24 * 60 * 60 * 1e3;
|
|
24
37
|
var POLL_MS = 500;
|
|
25
|
-
async function
|
|
38
|
+
async function readJson2(file) {
|
|
26
39
|
try {
|
|
27
40
|
return JSON.parse(await fs.readFile(file, "utf8"));
|
|
28
41
|
} catch (error) {
|
|
@@ -31,7 +44,10 @@ async function readJson(file) {
|
|
|
31
44
|
}
|
|
32
45
|
}
|
|
33
46
|
async function unreadChannelMessages(dir) {
|
|
34
|
-
const
|
|
47
|
+
const files = filesForDir(dir);
|
|
48
|
+
const mode = await readListeningMode(files);
|
|
49
|
+
const you = (await readJson(files.status))?.displayName;
|
|
50
|
+
const cursor = await readJson2(path.join(dir, "cursor.json"));
|
|
35
51
|
const delivered = cursor && (cursor.lastDeliveredEventId === null || typeof cursor.lastDeliveredEventId === "string") && Number.isSafeInteger(cursor.deliveredCount) && typeof cursor.deliveredCount === "number" && cursor.deliveredCount >= 0 ? cursor.deliveredCount : 0;
|
|
36
52
|
let content;
|
|
37
53
|
try {
|
|
@@ -49,7 +65,7 @@ async function unreadChannelMessages(dir) {
|
|
|
49
65
|
continue;
|
|
50
66
|
}
|
|
51
67
|
if (!entry || !["eventId", "roomId", "ts", "sender", "senderLabel", "body"].every((key) => typeof entry[key] === "string") || !["human", "agent", "unknown"].includes(entry.senderKind) || !["message", "event"].includes(entry.kind)) continue;
|
|
52
|
-
if (index++ >= delivered && entry
|
|
68
|
+
if (index++ >= delivered && wakesAgent(entry, mode, you)) messages++;
|
|
53
69
|
}
|
|
54
70
|
return messages;
|
|
55
71
|
}
|
|
@@ -64,7 +80,7 @@ async function unreadMessages(dir) {
|
|
|
64
80
|
}
|
|
65
81
|
let messages = 0;
|
|
66
82
|
for (const directory of directories) {
|
|
67
|
-
if ((await
|
|
83
|
+
if ((await readJson2(path.join(directory, "mode.json")))?.mode === "async") continue;
|
|
68
84
|
messages += await unreadChannelMessages(directory);
|
|
69
85
|
}
|
|
70
86
|
return messages;
|
|
@@ -91,6 +107,7 @@ async function watch(stdin, _argv, io = { stderr: process.stderr, env: process.e
|
|
|
91
107
|
const parent = process.ppid;
|
|
92
108
|
const input = JSON.parse(stdin);
|
|
93
109
|
if (!["Stop", "SessionStart"].includes(input?.hook_event_name) || typeof input.session_id !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(input.session_id)) return 0;
|
|
110
|
+
if (!await driverAllowed(stateRoot(io.env), "claude", "watcher", false)) return 0;
|
|
94
111
|
const dir = resolveStateDir(adapterFor("claude").id, input.session_id, io.env);
|
|
95
112
|
if (!(await fs.stat(dir)).isDirectory()) return 0;
|
|
96
113
|
if (input.hook_event_name === "SessionStart") {
|
|
@@ -119,24 +136,24 @@ async function watch(stdin, _argv, io = { stderr: process.stderr, env: process.e
|
|
|
119
136
|
};
|
|
120
137
|
const deadline = started.getTime() + testDuration(io.env.KHALA_WAKE_TEST_DEADLINE_MS, DEADLINE_MS);
|
|
121
138
|
const poll = testDuration(io.env.KHALA_WAKE_TEST_POLL_MS, POLL_MS);
|
|
122
|
-
const owns = async () => (await
|
|
139
|
+
const owns = async () => (await readJson2(owner))?.nonce === nonce;
|
|
123
140
|
const idle = async () => {
|
|
124
|
-
const activity = await
|
|
141
|
+
const activity = await readJson2(path.join(dir, "activity.json"));
|
|
125
142
|
return activity?.state === "idle" && typeof activity.updatedAt === "string" && Number.isFinite(Date.parse(activity.updatedAt));
|
|
126
143
|
};
|
|
127
144
|
const unread = async () => {
|
|
128
145
|
if (input.hook_event_name !== "SessionStart") return unreadMessages(dir);
|
|
129
146
|
let messages = 0;
|
|
130
147
|
for (const channel of await sessionStartWakeChannels(filesForDir(dir), io.env)) {
|
|
131
|
-
if (channel.connected && (await
|
|
148
|
+
if (channel.connected && (await readJson2(channel.files.mode))?.mode !== "async") messages += await unreadChannelMessages(channel.files.dir);
|
|
132
149
|
}
|
|
133
150
|
return messages;
|
|
134
151
|
};
|
|
135
152
|
while (io.now().getTime() < deadline) {
|
|
136
|
-
if (!await owns() || !parentAlive(parent)) return 0;
|
|
153
|
+
if (!await driverAllowed(stateRoot(io.env), "claude", "watcher", false) || !await owns() || !parentAlive(parent)) return 0;
|
|
137
154
|
if (input.hook_event_name === "SessionStart" && !(await sessionStartWakeChannels(filesForDir(dir), io.env)).length) return 0;
|
|
138
155
|
if (await idle() && await unread() > 0) {
|
|
139
|
-
if (await unread() > 0 && await idle() && await owns() && parentAlive(parent) && io.now().getTime() < deadline) {
|
|
156
|
+
if (await driverAllowed(stateRoot(io.env), "claude", "watcher", false) && await unread() > 0 && await idle() && await owns() && parentAlive(parent) && io.now().getTime() < deadline) {
|
|
140
157
|
io.stderr.write(NOTICE);
|
|
141
158
|
state = "woke";
|
|
142
159
|
return 2;
|
|
@@ -4,20 +4,22 @@ import {
|
|
|
4
4
|
checkName,
|
|
5
5
|
isDefaultAgentName,
|
|
6
6
|
restartHelper
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-SRZTHCXP.mjs";
|
|
8
8
|
import {
|
|
9
9
|
StateError,
|
|
10
|
+
harnessInfo,
|
|
11
|
+
isHarnessId,
|
|
10
12
|
readJson,
|
|
11
13
|
stateRoot,
|
|
14
|
+
validateAgentName,
|
|
12
15
|
writeJsonAtomic
|
|
13
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-PN25BUQ4.mjs";
|
|
14
17
|
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
validateAgentName
|
|
18
|
-
} from "./chunk-NKX3SLS7.mjs";
|
|
18
|
+
init_define_KHALA_BUNDLE
|
|
19
|
+
} from "./chunk-EVT2DWNZ.mjs";
|
|
19
20
|
|
|
20
21
|
// src/local/identity.ts
|
|
22
|
+
init_define_KHALA_BUNDLE();
|
|
21
23
|
import * as fs from "node:fs/promises";
|
|
22
24
|
import os from "node:os";
|
|
23
25
|
import path from "node:path";
|
|
@@ -76,6 +78,7 @@ async function resolveLocalOwnerName(env = process.env) {
|
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
// src/join.ts
|
|
81
|
+
init_define_KHALA_BUNDLE();
|
|
79
82
|
function parseChannelLink(link) {
|
|
80
83
|
try {
|
|
81
84
|
const url = new URL(link);
|
|
@@ -285,12 +288,27 @@ async function pollUntilDeadline(input, options) {
|
|
|
285
288
|
}
|
|
286
289
|
}
|
|
287
290
|
async function reportReady(input, deps = {}) {
|
|
288
|
-
const
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
291
|
+
const now = deps.now ?? Date.now;
|
|
292
|
+
const deadline = now() + (deps.timeoutMs ?? 12e4);
|
|
293
|
+
for (let delay = 1e3; ; delay = Math.min(delay * 2, 15e3)) {
|
|
294
|
+
const response = await post(endpoint(input, "/api/agent/join/ready"), input.origin, {}, deps, input.pollSecret);
|
|
295
|
+
if (response.status === 204) return;
|
|
296
|
+
const code = serverCode(await json(response));
|
|
297
|
+
if ((response.status === 429 || response.status === 503 && code === "unavailable") && now() + delay <= deadline) {
|
|
298
|
+
try {
|
|
299
|
+
await (deps.sleep ?? sleep)(delay, deps.signal);
|
|
300
|
+
} catch {
|
|
301
|
+
fail("network");
|
|
302
|
+
}
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
readyError(response.status, code);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function readyError(status, code) {
|
|
309
|
+
if (status === 404) fail("ready_not_found");
|
|
310
|
+
if (status === 409) fail("not_confirmed");
|
|
311
|
+
gatewayError(status, code);
|
|
294
312
|
fail("protocol");
|
|
295
313
|
}
|
|
296
314
|
|