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.
Files changed (53) hide show
  1. package/README.md +4 -4
  2. package/dist/THIRD_PARTY_NOTICES.txt +809 -0
  3. package/dist/chunk-2AMWQ7RB.mjs +1127 -0
  4. package/dist/chunk-3E5DH3Y6.mjs +9864 -0
  5. package/dist/{chunk-IQJQ4RF5.mjs → chunk-4BP7V3OP.mjs} +12 -1
  6. package/dist/{chunk-FV32AQTC.mjs → chunk-4BZQ4GVW.mjs} +10 -6
  7. package/dist/chunk-5JSGA6OB.mjs +1483 -0
  8. package/dist/chunk-6AQVW5W7.mjs +60 -0
  9. package/dist/{chunk-W6R4UJUQ.mjs → chunk-6J2PUM7L.mjs} +16 -9
  10. package/dist/chunk-6SUV3EW6.mjs +27 -0
  11. package/dist/{chunk-RNDUFTBF.mjs → chunk-ARIDZOTI.mjs} +499 -115
  12. package/dist/chunk-C2WEDMAF.mjs +15 -0
  13. package/dist/{chunk-Z4JF2M5C.mjs → chunk-CHC4VZF5.mjs} +9 -9
  14. package/dist/chunk-CKLCR5G4.mjs +1369 -0
  15. package/dist/chunk-EVT2DWNZ.mjs +58 -0
  16. package/dist/chunk-FJVVSKZ3.mjs +22 -0
  17. package/dist/{chunk-APMWDF6B.mjs → chunk-G3NMB4PY.mjs} +4 -2
  18. package/dist/chunk-HHEZVPRR.mjs +7 -0
  19. package/dist/{chunk-54XFVSEC.mjs → chunk-JKOJQTFT.mjs} +103 -5
  20. package/dist/{chunk-ZJ4W7P33.mjs → chunk-NDMFD5IM.mjs} +15 -10
  21. package/dist/{chunk-VKQ3KUYO.mjs → chunk-OEV5DFLW.mjs} +77 -7
  22. package/dist/chunk-OIZ4R5H7.mjs +173 -0
  23. package/dist/{chunk-CJTCU755.mjs → chunk-PJKI7SRI.mjs} +256 -26
  24. package/dist/chunk-PN25BUQ4.mjs +599 -0
  25. package/dist/chunk-QDPJ4VT2.mjs +432 -0
  26. package/dist/{chunk-2DHIAFEV.mjs → chunk-SRZTHCXP.mjs} +24 -10
  27. package/dist/chunk-TSK3HJEG.mjs +20 -0
  28. package/dist/chunk-UX34IVN5.mjs +33 -0
  29. package/dist/{chunk-BKLW2SPG.mjs → chunk-VAC3JTAV.mjs} +34 -17
  30. package/dist/{chunk-VAI7IUI4.mjs → chunk-VDZK4LW3.mjs} +30 -12
  31. package/dist/chunk-W6HM6F2U.mjs +901 -0
  32. package/dist/{chunk-H3K4GA2P.mjs → chunk-WPNMWNCL.mjs} +33 -21
  33. package/dist/chunk-WUDXHF2Q.mjs +14 -0
  34. package/dist/chunk-WZJ6DQJV.mjs +19 -0
  35. package/dist/{chunk-5LIE5GUU.mjs → chunk-XR625T3I.mjs} +5 -1
  36. package/dist/chunk-ZSKLNZWZ.mjs +224 -0
  37. package/dist/iterm2_send.py +56 -0
  38. package/dist/khala.mjs +20 -13
  39. package/dist/web/assets/local-CSPuGnH2.css +1 -0
  40. package/dist/web/assets/local-Dtyxaacx.js +9 -0
  41. package/dist/web/index.html +2 -2
  42. package/package.json +5 -3
  43. package/dist/chunk-2VCAW4GH.mjs +0 -34
  44. package/dist/chunk-5BQTYU66.mjs +0 -886
  45. package/dist/chunk-5GLTKWJ5.mjs +0 -1
  46. package/dist/chunk-5PUQT3YS.mjs +0 -569
  47. package/dist/chunk-7HBRFY3Z.mjs +0 -8
  48. package/dist/chunk-CBPLCCRZ.mjs +0 -191
  49. package/dist/chunk-FH34B3I3.mjs +0 -235
  50. package/dist/chunk-NKX3SLS7.mjs +0 -227
  51. package/dist/chunk-VUSV2ADL.mjs +0 -267
  52. package/dist/web/assets/local-BQl2KrE1.js +0 -9
  53. 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-FV32AQTC.mjs";
4
+ } from "./chunk-4BZQ4GVW.mjs";
5
5
  import {
6
6
  adapterFor
7
- } from "./chunk-5BQTYU66.mjs";
8
- import "./chunk-VKQ3KUYO.mjs";
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
- resolveStateDir
12
- } from "./chunk-CBPLCCRZ.mjs";
13
- import "./chunk-IQJQ4RF5.mjs";
14
- import "./chunk-NKX3SLS7.mjs";
15
- import "./chunk-7HBRFY3Z.mjs";
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 readJson(file) {
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 cursor = await readJson(path.join(dir, "cursor.json"));
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.kind === "message") messages++;
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 readJson(path.join(directory, "mode.json")))?.mode === "async") continue;
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 readJson(owner))?.nonce === nonce;
139
+ const owns = async () => (await readJson2(owner))?.nonce === nonce;
123
140
  const idle = async () => {
124
- const activity = await readJson(path.join(dir, "activity.json"));
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 readJson(channel.files.mode))?.mode !== "async") messages += await unreadChannelMessages(channel.files.dir);
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-2DHIAFEV.mjs";
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-CBPLCCRZ.mjs";
16
+ } from "./chunk-PN25BUQ4.mjs";
14
17
  import {
15
- harnessInfo,
16
- isHarnessId,
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 response = await post(endpoint(input, "/api/agent/join/ready"), input.origin, {}, deps, input.pollSecret);
289
- if (response.status === 204) return;
290
- const code = serverCode(await json(response));
291
- if (response.status === 404) fail("ready_not_found");
292
- if (response.status === 409) fail("not_confirmed");
293
- gatewayError(response.status, code);
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