khala-cli 0.4.8 → 0.4.9

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 (48) hide show
  1. package/README.md +4 -4
  2. package/dist/THIRD_PARTY_NOTICES.txt +781 -0
  3. package/dist/{chunk-APMWDF6B.mjs → chunk-3KDOTR54.mjs} +4 -2
  4. package/dist/{chunk-VUSV2ADL.mjs → chunk-3R6HFSLL.mjs} +147 -36
  5. package/dist/{chunk-2VCAW4GH.mjs → chunk-47XNLAJG.mjs} +5 -1
  6. package/dist/chunk-6BO3JSUP.mjs +33 -0
  7. package/dist/chunk-7R3EIDGR.mjs +58 -0
  8. package/dist/{chunk-5LIE5GUU.mjs → chunk-ANSR4IAW.mjs} +5 -1
  9. package/dist/chunk-BEO7WIIM.mjs +153 -0
  10. package/dist/chunk-BLCRVRIK.mjs +1000 -0
  11. package/dist/{chunk-54XFVSEC.mjs → chunk-BV45NK7K.mjs} +5 -1
  12. package/dist/{chunk-Z4JF2M5C.mjs → chunk-DJM23SIU.mjs} +8 -7
  13. package/dist/{chunk-2DHIAFEV.mjs → chunk-FO5GXCST.mjs} +24 -10
  14. package/dist/{chunk-CJTCU755.mjs → chunk-FZEH2IXZ.mjs} +95 -15
  15. package/dist/{chunk-RNDUFTBF.mjs → chunk-GSZADJMW.mjs} +233 -77
  16. package/dist/chunk-ITFD3JZS.mjs +1137 -0
  17. package/dist/chunk-K7V7X6WU.mjs +207 -0
  18. package/dist/chunk-KMLXOPBQ.mjs +20 -0
  19. package/dist/chunk-LBT47HLZ.mjs +19 -0
  20. package/dist/{chunk-IQJQ4RF5.mjs → chunk-NGSYOVQ4.mjs} +12 -1
  21. package/dist/chunk-NIX5F4LT.mjs +863 -0
  22. package/dist/chunk-NPSQNCOY.mjs +590 -0
  23. package/dist/chunk-P3YIN7G7.mjs +26 -0
  24. package/dist/chunk-PAJ4JJPV.mjs +9827 -0
  25. package/dist/{chunk-VAI7IUI4.mjs → chunk-PDZ5Z5ZE.mjs} +9 -6
  26. package/dist/chunk-QKWEZXR3.mjs +52 -0
  27. package/dist/chunk-SSO5RFOX.mjs +7 -0
  28. package/dist/{chunk-ZJ4W7P33.mjs → chunk-T7IL7V7Q.mjs} +11 -9
  29. package/dist/{chunk-VKQ3KUYO.mjs → chunk-TANCKTDK.mjs} +9 -4
  30. package/dist/{chunk-FV32AQTC.mjs → chunk-TEFOQXBK.mjs} +10 -6
  31. package/dist/{chunk-W6R4UJUQ.mjs → chunk-UK5GJO4Y.mjs} +15 -9
  32. package/dist/{chunk-BKLW2SPG.mjs → chunk-V4F3SYKW.mjs} +19 -10
  33. package/dist/{chunk-H3K4GA2P.mjs → chunk-WDOHRV3D.mjs} +31 -19
  34. package/dist/chunk-XBQDIKB5.mjs +18 -0
  35. package/dist/chunk-XUCWSYVS.mjs +148 -0
  36. package/dist/khala.mjs +20 -13
  37. package/dist/web/assets/local-CFzRHZpB.js +9 -0
  38. package/dist/web/assets/{local-OwDq47O4.css → local-ciypUFoK.css} +1 -1
  39. package/dist/web/index.html +2 -2
  40. package/package.json +5 -3
  41. package/dist/chunk-5BQTYU66.mjs +0 -886
  42. package/dist/chunk-5GLTKWJ5.mjs +0 -1
  43. package/dist/chunk-5PUQT3YS.mjs +0 -569
  44. package/dist/chunk-7HBRFY3Z.mjs +0 -8
  45. package/dist/chunk-CBPLCCRZ.mjs +0 -191
  46. package/dist/chunk-FH34B3I3.mjs +0 -235
  47. package/dist/chunk-NKX3SLS7.mjs +0 -227
  48. package/dist/web/assets/local-BQl2KrE1.js +0 -9
@@ -4,20 +4,22 @@ import {
4
4
  checkName,
5
5
  isDefaultAgentName,
6
6
  restartHelper
7
- } from "./chunk-2DHIAFEV.mjs";
7
+ } from "./chunk-FO5GXCST.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-NPSQNCOY.mjs";
14
17
  import {
15
- harnessInfo,
16
- isHarnessId,
17
- validateAgentName
18
- } from "./chunk-NKX3SLS7.mjs";
18
+ init_define_KHALA_BUNDLE
19
+ } from "./chunk-7R3EIDGR.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);
@@ -0,0 +1,52 @@
1
+ import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
2
+ import {
3
+ nearestNonShellAncestor,
4
+ readJson,
5
+ readProcess,
6
+ writeJsonAtomic
7
+ } from "./chunk-NPSQNCOY.mjs";
8
+ import {
9
+ init_define_KHALA_BUNDLE
10
+ } from "./chunk-7R3EIDGR.mjs";
11
+
12
+ // src/wake/terminal/capture.ts
13
+ init_define_KHALA_BUNDLE();
14
+ import path from "node:path";
15
+ import { unlink } from "node:fs/promises";
16
+ function validPane(value) {
17
+ if (!value || typeof value !== "object") return false;
18
+ const pane = value;
19
+ return typeof pane.paneId === "string" && (pane.kind === "tmux" ? /^%\d+$/.test(pane.paneId) : pane.kind === "wezterm" && /^\d+$/.test(pane.paneId)) && Number.isSafeInteger(pane.agentPid) && pane.agentPid > 0 && typeof pane.capturedAt === "string" && Number.isFinite(Date.parse(pane.capturedAt)) && (pane.socket === void 0 || pane.kind === "tmux" && typeof pane.socket === "string" && pane.socket.startsWith("/") && !pane.socket.includes("\0")) && (pane.agentStartTime === void 0 || typeof pane.agentStartTime === "string" && pane.agentStartTime.length > 0);
20
+ }
21
+ async function readPane(files) {
22
+ const pane = await readJson(path.join(files.dir, "pane.json"));
23
+ return validPane(pane) ? pane : null;
24
+ }
25
+ async function capturePane(files, env, options = {}) {
26
+ const file = path.join(files.dir, "pane.json");
27
+ const clear = async () => {
28
+ await unlink(file).catch((error) => {
29
+ if (error.code !== "ENOENT") throw error;
30
+ });
31
+ return null;
32
+ };
33
+ if ((options.platform ?? process.platform) === "win32") return clear();
34
+ let target;
35
+ if (env.TMUX) {
36
+ const socket = env.TMUX.match(/^(.*),\d+,\d+$/)?.[1];
37
+ if (!socket?.startsWith("/") || socket.includes("\0") || !/^%\d+$/.test(env.TMUX_PANE ?? "")) return clear();
38
+ target = { kind: "tmux", paneId: env.TMUX_PANE, socket };
39
+ } else if (/^\d+$/.test(env.WEZTERM_PANE ?? "")) target = { kind: "wezterm", paneId: env.WEZTERM_PANE };
40
+ else return clear();
41
+ const agent = await nearestNonShellAncestor(options.pid ?? process.pid, options.readProcess ?? readProcess);
42
+ if (!agent) return clear();
43
+ const pane = { ...target, agentPid: agent.pid, agentStartTime: agent.startTime, capturedAt: (options.now ?? (() => /* @__PURE__ */ new Date()))().toISOString() };
44
+ if (!validPane(pane)) return clear();
45
+ await writeJsonAtomic(file, pane);
46
+ return pane;
47
+ }
48
+
49
+ export {
50
+ readPane,
51
+ capturePane
52
+ };
@@ -0,0 +1,7 @@
1
+ import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
2
+ import {
3
+ init_define_KHALA_BUNDLE
4
+ } from "./chunk-7R3EIDGR.mjs";
5
+
6
+ // src/events/member-rename.ts
7
+ init_define_KHALA_BUNDLE();
@@ -14,22 +14,24 @@ import {
14
14
  decodeLocalSendResult,
15
15
  ensureHelper,
16
16
  localRoomPath
17
- } from "./chunk-2DHIAFEV.mjs";
18
- import "./chunk-5LIE5GUU.mjs";
19
- import "./chunk-APMWDF6B.mjs";
20
- import "./chunk-5GLTKWJ5.mjs";
17
+ } from "./chunk-FO5GXCST.mjs";
18
+ import "./chunk-SSO5RFOX.mjs";
21
19
  import {
22
20
  CHANNEL_EVENT_TYPE,
23
21
  memberRenameContent
24
- } from "./chunk-54XFVSEC.mjs";
25
- import "./chunk-CBPLCCRZ.mjs";
22
+ } from "./chunk-BV45NK7K.mjs";
23
+ import "./chunk-ANSR4IAW.mjs";
24
+ import "./chunk-3KDOTR54.mjs";
26
25
  import {
27
26
  LISTENING_MODE_COMMAND_TYPE
28
- } from "./chunk-IQJQ4RF5.mjs";
29
- import "./chunk-NKX3SLS7.mjs";
30
- import "./chunk-7HBRFY3Z.mjs";
27
+ } from "./chunk-NGSYOVQ4.mjs";
28
+ import "./chunk-NPSQNCOY.mjs";
29
+ import {
30
+ init_define_KHALA_BUNDLE
31
+ } from "./chunk-7R3EIDGR.mjs";
31
32
 
32
33
  // src/local/session.ts
34
+ init_define_KHALA_BUNDLE();
33
35
  import { randomUUID } from "node:crypto";
34
36
  var LocalCallError = class extends Error {
35
37
  constructor(status, code) {
@@ -6,14 +6,17 @@ import {
6
6
  ensureStateDir,
7
7
  filesForDir,
8
8
  readJson,
9
- readStatus,
10
9
  removeStateFile,
11
10
  stateKey,
12
11
  writeJsonAtomic,
13
12
  writeStateFile
14
- } from "./chunk-CBPLCCRZ.mjs";
13
+ } from "./chunk-NPSQNCOY.mjs";
14
+ import {
15
+ init_define_KHALA_BUNDLE
16
+ } from "./chunk-7R3EIDGR.mjs";
15
17
 
16
18
  // src/inbox.ts
19
+ init_define_KHALA_BUNDLE();
17
20
  import * as fs from "node:fs/promises";
18
21
  async function readEntries(files) {
19
22
  let content;
@@ -81,6 +84,7 @@ function unreadCount(dir) {
81
84
  }
82
85
 
83
86
  // src/channels.ts
87
+ init_define_KHALA_BUNDLE();
84
88
  import * as fs2 from "node:fs/promises";
85
89
  import path from "node:path";
86
90
  function channelKey(roomId2) {
@@ -134,7 +138,7 @@ async function listChannels(files) {
134
138
  if (await exists(files.inbox)) {
135
139
  const id = await legacyRoomId(files);
136
140
  if (id) {
137
- const status = await readStatus(files);
141
+ const status = await readJson(files.status);
138
142
  channels.push({ key: channelKey(id), roomId: id, ...typeof status?.channelName === "string" ? { channelName: status.channelName } : {}, files, legacy: true });
139
143
  }
140
144
  }
@@ -161,7 +165,7 @@ async function migrateLegacy(files) {
161
165
  console.warn(`Khala cursor migration: conflicting cursors for ${id}; using earlier position ${safe.deliveredCount} to avoid skipping messages (legacy=${legacyCursor.deliveredCount}, channel=${channelCursor.deliveredCount}).`);
162
166
  }
163
167
  }
164
- const status = await readStatus(files);
168
+ const status = await readJson(files.status);
165
169
  const metadata = await readJson(path.join(nested.dir, "channel.json"));
166
170
  if (!metadata || roomId(metadata) !== id) {
167
171
  await writeStateFile(nested.dir, "channel.json", {
@@ -203,6 +207,7 @@ function resolveChannel(list, ref) {
203
207
  }
204
208
 
205
209
  // src/activity.ts
210
+ init_define_KHALA_BUNDLE();
206
211
  import path2 from "node:path";
207
212
  async function readActivity(files) {
208
213
  const activity = await readJson(path2.join(files.dir, "activity.json"));
@@ -1,27 +1,31 @@
1
1
  import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
2
2
  import {
3
3
  listChannels
4
- } from "./chunk-VKQ3KUYO.mjs";
4
+ } from "./chunk-TANCKTDK.mjs";
5
5
  import {
6
6
  TERMINAL_SESSION_DETAILS,
7
+ cachedProcessReader,
7
8
  readStateFile,
8
- readStatus
9
- } from "./chunk-CBPLCCRZ.mjs";
10
- import {
9
+ readStatus,
11
10
  validAgentRejoinSecret
12
- } from "./chunk-NKX3SLS7.mjs";
11
+ } from "./chunk-NPSQNCOY.mjs";
12
+ import {
13
+ init_define_KHALA_BUNDLE
14
+ } from "./chunk-7R3EIDGR.mjs";
13
15
 
14
16
  // src/session-start-wake.ts
17
+ init_define_KHALA_BUNDLE();
15
18
  import { createHash } from "node:crypto";
16
19
  import path from "node:path";
17
20
  async function sessionStartWakeChannels(files, env) {
21
+ const read = cachedProcessReader();
18
22
  const channels = await listChannels(files);
19
23
  const secret = (await readStateFile(files.dir, "rejoin.json"))?.secret;
20
24
  const hash = validAgentRejoinSecret(secret) ? createHash("sha256").update(secret).digest("hex") : void 0;
21
25
  const candidates = channels.length ? channels : [{ files, roomId: void 0 }];
22
26
  const result = [];
23
27
  for (const channel of candidates) {
24
- const status = await readStatus(channel.files);
28
+ const status = await readStatus(channel.files, read);
25
29
  if (TERMINAL_SESSION_DETAILS.some((detail) => detail === status?.detail)) continue;
26
30
  if (status?.state === "connected" || status?.state === "send_failed") {
27
31
  result.push({ files: channel.files, connected: true });
@@ -1,28 +1,34 @@
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-TEFOQXBK.mjs";
5
+ import {
6
+ capturePane
7
+ } from "./chunk-QKWEZXR3.mjs";
5
8
  import {
6
9
  listChannels,
7
10
  writeActivity
8
- } from "./chunk-VKQ3KUYO.mjs";
11
+ } from "./chunk-TANCKTDK.mjs";
9
12
  import {
10
13
  TERMINAL_SESSION_DETAILS,
11
- readStatus,
12
- sessionFiles
13
- } from "./chunk-CBPLCCRZ.mjs";
14
- import "./chunk-NKX3SLS7.mjs";
15
- import "./chunk-7HBRFY3Z.mjs";
14
+ openSessionDir,
15
+ readJson
16
+ } from "./chunk-NPSQNCOY.mjs";
17
+ import {
18
+ init_define_KHALA_BUNDLE
19
+ } from "./chunk-7R3EIDGR.mjs";
16
20
 
17
21
  // hooks/session-start.ts
22
+ init_define_KHALA_BUNDLE();
18
23
  async function run(stdin, argv) {
19
24
  if (argv.length) return 0;
20
25
  try {
21
26
  const input = JSON.parse(stdin);
22
27
  if (input?.hook_event_name !== "SessionStart" || typeof input.session_id !== "string") return 0;
23
- const files = sessionFiles("claude", input.session_id);
28
+ const files = await openSessionDir("claude", input.session_id);
29
+ await capturePane(files, process.env);
24
30
  const channels = await listChannels(files);
25
- const statuses = channels.length ? await Promise.all(channels.map(async (channel) => ({ status: await readStatus(channel.files), channelName: channel.channelName ?? channel.roomId }))) : [{ status: await readStatus(files), channelName: void 0 }];
31
+ const statuses = channels.length ? await Promise.all(channels.map(async (channel) => ({ status: await readJson(channel.files.status), channelName: channel.channelName ?? channel.roomId }))) : [{ status: await readJson(files.status), channelName: void 0 }];
26
32
  if (process.env.CLAUDE_CODE_ENTRYPOINT === "cli" && ["startup", "resume"].includes(input.source) && (await sessionStartWakeChannels(files, process.env)).length) {
27
33
  await writeActivity(files, "idle");
28
34
  }
@@ -1,20 +1,28 @@
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-TEFOQXBK.mjs";
5
5
  import {
6
6
  adapterFor
7
- } from "./chunk-5BQTYU66.mjs";
8
- import "./chunk-VKQ3KUYO.mjs";
7
+ } from "./chunk-ITFD3JZS.mjs";
8
+ import "./chunk-QKWEZXR3.mjs";
9
+ import {
10
+ driverAllowed
11
+ } from "./chunk-NIX5F4LT.mjs";
12
+ import "./chunk-NGSYOVQ4.mjs";
13
+ import "./chunk-TANCKTDK.mjs";
9
14
  import {
10
15
  filesForDir,
11
- resolveStateDir
12
- } from "./chunk-CBPLCCRZ.mjs";
13
- import "./chunk-IQJQ4RF5.mjs";
14
- import "./chunk-NKX3SLS7.mjs";
15
- import "./chunk-7HBRFY3Z.mjs";
16
+ resolveStateDir,
17
+ stateRoot
18
+ } from "./chunk-NPSQNCOY.mjs";
19
+ import "./chunk-K7V7X6WU.mjs";
20
+ import {
21
+ init_define_KHALA_BUNDLE
22
+ } from "./chunk-7R3EIDGR.mjs";
16
23
 
17
24
  // hooks/claude-wake.ts
25
+ init_define_KHALA_BUNDLE();
18
26
  import fs from "node:fs/promises";
19
27
  import path from "node:path";
20
28
  import { randomBytes } from "node:crypto";
@@ -91,6 +99,7 @@ async function watch(stdin, _argv, io = { stderr: process.stderr, env: process.e
91
99
  const parent = process.ppid;
92
100
  const input = JSON.parse(stdin);
93
101
  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;
102
+ if (!await driverAllowed(stateRoot(io.env), "claude", "watcher", false)) return 0;
94
103
  const dir = resolveStateDir(adapterFor("claude").id, input.session_id, io.env);
95
104
  if (!(await fs.stat(dir)).isDirectory()) return 0;
96
105
  if (input.hook_event_name === "SessionStart") {
@@ -133,10 +142,10 @@ async function watch(stdin, _argv, io = { stderr: process.stderr, env: process.e
133
142
  return messages;
134
143
  };
135
144
  while (io.now().getTime() < deadline) {
136
- if (!await owns() || !parentAlive(parent)) return 0;
145
+ if (!await driverAllowed(stateRoot(io.env), "claude", "watcher", false) || !await owns() || !parentAlive(parent)) return 0;
137
146
  if (input.hook_event_name === "SessionStart" && !(await sessionStartWakeChannels(filesForDir(dir), io.env)).length) return 0;
138
147
  if (await idle() && await unread() > 0) {
139
- if (await unread() > 0 && await idle() && await owns() && parentAlive(parent) && io.now().getTime() < deadline) {
148
+ if (await driverAllowed(stateRoot(io.env), "claude", "watcher", false) && await unread() > 0 && await idle() && await owns() && parentAlive(parent) && io.now().getTime() < deadline) {
140
149
  io.stderr.write(NOTICE);
141
150
  state = "woke";
142
151
  return 2;
@@ -2,7 +2,7 @@ import { createRequire as __khalaCreateRequire } from 'node:module'; const requi
2
2
  import {
3
3
  parseChannelLink,
4
4
  resolveLocalOwnerName
5
- } from "./chunk-VAI7IUI4.mjs";
5
+ } from "./chunk-PDZ5Z5ZE.mjs";
6
6
  import {
7
7
  LOCAL_AGENT_DEVICE_PREFIX,
8
8
  LOCAL_IDLE_EXIT_MS,
@@ -32,26 +32,20 @@ import {
32
32
  normalizeInitials,
33
33
  olderHelperVersion,
34
34
  readHelperFile
35
- } from "./chunk-2DHIAFEV.mjs";
36
- import {
37
- KHALA_AGENT_VERSION
38
- } from "./chunk-5LIE5GUU.mjs";
39
- import {
40
- bundle
41
- } from "./chunk-APMWDF6B.mjs";
42
- import "./chunk-5GLTKWJ5.mjs";
35
+ } from "./chunk-FO5GXCST.mjs";
36
+ import "./chunk-SSO5RFOX.mjs";
43
37
  import {
44
38
  CHANNEL_EVENT_TYPE,
45
39
  decodeChannelEvent,
46
40
  encodeChannelEvent,
47
41
  memberRenameContent
48
- } from "./chunk-54XFVSEC.mjs";
42
+ } from "./chunk-BV45NK7K.mjs";
49
43
  import {
50
- StateError,
51
- ensureStateDir,
52
- readJson,
53
- writeJsonAtomic
54
- } from "./chunk-CBPLCCRZ.mjs";
44
+ KHALA_AGENT_VERSION
45
+ } from "./chunk-ANSR4IAW.mjs";
46
+ import {
47
+ bundle
48
+ } from "./chunk-3KDOTR54.mjs";
55
49
  import {
56
50
  DEFAULT_LISTENING_MODE,
57
51
  LISTENING_MODE_COMMAND_TYPE,
@@ -59,29 +53,38 @@ import {
59
53
  decodeListeningMode,
60
54
  decodeListeningModeCommand,
61
55
  memberListeningMode
62
- } from "./chunk-IQJQ4RF5.mjs";
56
+ } from "./chunk-NGSYOVQ4.mjs";
63
57
  import {
64
58
  LEGACY_HARNESSES,
59
+ StateError,
65
60
  agentConfirmPagePath,
66
61
  decodeWith,
62
+ ensureStateDir,
67
63
  isHarnessId,
68
64
  object,
65
+ readJson,
69
66
  utf8Length,
70
67
  validAgentRejoinSecret,
71
- validAgentSessionId
72
- } from "./chunk-NKX3SLS7.mjs";
73
- import "./chunk-7HBRFY3Z.mjs";
68
+ validAgentSessionId,
69
+ writeJsonAtomic
70
+ } from "./chunk-NPSQNCOY.mjs";
71
+ import {
72
+ init_define_KHALA_BUNDLE
73
+ } from "./chunk-7R3EIDGR.mjs";
74
74
 
75
75
  // src/local/cli.ts
76
+ init_define_KHALA_BUNDLE();
76
77
  import { setTimeout as sleepDefault } from "node:timers/promises";
77
78
 
78
79
  // src/local/serve.ts
80
+ init_define_KHALA_BUNDLE();
79
81
  import { createHash as createHash3, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual3 } from "node:crypto";
80
82
  import { unlink } from "node:fs/promises";
81
83
  import path3 from "node:path";
82
84
  import { fileURLToPath } from "node:url";
83
85
 
84
86
  // src/local/store.ts
87
+ init_define_KHALA_BUNDLE();
85
88
  import * as fs from "node:fs/promises";
86
89
  import path from "node:path";
87
90
  import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
@@ -564,6 +567,7 @@ async function openLocalStore(input) {
564
567
  }
565
568
 
566
569
  // src/local/http.ts
570
+ init_define_KHALA_BUNDLE();
567
571
  import { createServer } from "node:http";
568
572
  import * as fs2 from "node:fs/promises";
569
573
  import path2 from "node:path";
@@ -838,9 +842,11 @@ function createHelperServer(options) {
838
842
  }
839
843
 
840
844
  // src/local/routes/agent-join.ts
845
+ init_define_KHALA_BUNDLE();
841
846
  import { createHash as createHash2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
842
847
 
843
848
  // ../contracts/src/m1/channel-names.ts
849
+ init_define_KHALA_BUNDLE();
844
850
  var key = (name) => name.trim().toLowerCase();
845
851
  function takenNames(names) {
846
852
  return new Set([...names].map(key));
@@ -970,7 +976,11 @@ function agentJoinRoutes() {
970
976
  ];
971
977
  }
972
978
 
979
+ // src/local/routes/rooms.ts
980
+ init_define_KHALA_BUNDLE();
981
+
973
982
  // src/local/wire.ts
983
+ init_define_KHALA_BUNDLE();
974
984
  function legacyHarnessView(content) {
975
985
  if (!("harness" in content) || content.harness === void 0 || LEGACY_HARNESSES.includes(content.harness)) return content;
976
986
  const legacy = { ...content };
@@ -1191,6 +1201,7 @@ function roomRoutes() {
1191
1201
  }
1192
1202
 
1193
1203
  // src/local/routes/owner.ts
1204
+ init_define_KHALA_BUNDLE();
1194
1205
  var ID = /^[A-Za-z0-9._-]{1,64}$/u;
1195
1206
  var USER = /^@[^\s:]+:\S+$/u;
1196
1207
  var fail4 = (status, error2) => ({ status, json: { error: error2 } });
@@ -1382,6 +1393,7 @@ function ownerRoutes(options = {}) {
1382
1393
  }
1383
1394
 
1384
1395
  // src/local/routes/profile.ts
1396
+ init_define_KHALA_BUNDLE();
1385
1397
  var fail5 = (status, error2) => ({ status, json: { error: error2 } });
1386
1398
  var field = (body, key2) => decodeWith(() => object(body, "", [key2]).field(key2));
1387
1399
  var iso = (ctx) => new Date(ctx.now()).toISOString();
@@ -0,0 +1,18 @@
1
+ import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
2
+ import {
3
+ ADAPTERS,
4
+ adapterFor,
5
+ createAdapterRegistry
6
+ } from "./chunk-ITFD3JZS.mjs";
7
+ import "./chunk-QKWEZXR3.mjs";
8
+ import "./chunk-NIX5F4LT.mjs";
9
+ import "./chunk-NGSYOVQ4.mjs";
10
+ import "./chunk-TANCKTDK.mjs";
11
+ import "./chunk-NPSQNCOY.mjs";
12
+ import "./chunk-K7V7X6WU.mjs";
13
+ import "./chunk-7R3EIDGR.mjs";
14
+ export {
15
+ ADAPTERS,
16
+ adapterFor,
17
+ createAdapterRegistry
18
+ };
@@ -0,0 +1,148 @@
1
+ import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
2
+ import {
3
+ adapterFor
4
+ } from "./chunk-ITFD3JZS.mjs";
5
+ import {
6
+ readWakeSettings
7
+ } from "./chunk-NIX5F4LT.mjs";
8
+ import {
9
+ HARNESS_REGISTRY,
10
+ filesForDir,
11
+ readStateFile,
12
+ stateRoot
13
+ } from "./chunk-NPSQNCOY.mjs";
14
+ import {
15
+ readWakeState
16
+ } from "./chunk-K7V7X6WU.mjs";
17
+ import {
18
+ init_define_KHALA_BUNDLE
19
+ } from "./chunk-7R3EIDGR.mjs";
20
+
21
+ // src/wake/status.ts
22
+ init_define_KHALA_BUNDLE();
23
+ import path from "node:path";
24
+ var CODEX_DAEMON_WAKE_NOTE = "Codex threads can keep answering mentions while the app-server daemon runs, even after the TUI exits. Stop with khala_leave, khala wake off --harness codex, or codex app-server daemon stop.";
25
+ var WAKE_STATES = {
26
+ active: { reason: "Idle wake is on.", remedy: "" },
27
+ needs_consent: { reason: "Idle wake needs consent.", remedy: "khala wake on --driver <d>" },
28
+ unavailable: { reason: "No remote-control API is available.", remedy: "", reasons: {
29
+ wake_status_unavailable: "Wake status is unavailable.",
30
+ queue_missing: "Codex queue is missing.",
31
+ codex_binary_missing: "Codex queue is missing.",
32
+ codex_queue_unavailable: "Codex queue is unavailable.",
33
+ nonce_timeout: "The wake verification deadline passed.",
34
+ windows: "Windows has no supported remote-control API.",
35
+ driver_missing: "No wake driver is installed for this transport.",
36
+ monitor_missing: "The Muse monitor is not armed; start monitor on khala watch with persistent: true, wake_delay_ms: 0, show_lines: true.",
37
+ watcher_missing: "The Claude watcher is not armed.",
38
+ terminal_aborted: "The terminal wake check was cancelled.",
39
+ terminal_unavailable_on_platform: "This platform has no supported terminal remote-control API.",
40
+ terminal_empty_prompt_unavailable: "This harness has no verified empty-prompt pattern.",
41
+ terminal_consent_required: "Terminal wake needs consent; run khala wake on --driver terminal.",
42
+ terminal_capture_pending_prompt: "Terminal capture is pending; send the first Codex prompt.",
43
+ "no remote-control API": "No terminal remote-control API is available.",
44
+ terminal_not_idle: "The agent must be idle for at least 30 seconds before a terminal wake.",
45
+ terminal_agent_exited: "The captured agent process has exited or changed.",
46
+ terminal_pane_unsafe: "The terminal pane is unavailable or its input mode is unsafe.",
47
+ terminal_pane_not_owned: "The agent does not own the terminal pane foreground process group.",
48
+ terminal_prompt_not_empty: "The terminal prompt contains a draft or its cursor has moved.",
49
+ terminal_probe_failed: "The terminal remote-control check failed.",
50
+ wezterm_pane_missing: "The captured WezTerm pane is no longer available.",
51
+ wezterm_tty_unavailable: "WezTerm did not report the pane terminal device; ownership cannot be verified.",
52
+ wezterm_cursor_unavailable: "WezTerm did not report the cursor position; an empty prompt cannot be verified."
53
+ } },
54
+ disabled: { reason: "Idle wake is off.", remedy: "khala wake on --driver <d>" },
55
+ disabled_after_failures: { reason: "Idle wake was disabled after two unverified wakes.", remedy: "khala wake on --driver <d>" },
56
+ lapsed: { reason: "The Claude watcher passed its deadline; any prompt re-arms it.", remedy: "Send any prompt to re-arm the watcher." },
57
+ none_by_design: { reason: "The generic tier has no idle wake by design.", remedy: "" }
58
+ };
59
+ function wakeStatusText(driver, state, unavailableReason) {
60
+ const text = WAKE_STATES[state];
61
+ return { driver, state, reason: state === "unavailable" && unavailableReason ? WAKE_STATES.unavailable.reasons[unavailableReason] : text.reason, ...text.remedy ? { remedy: text.remedy.replace("<d>", driver) } : {} };
62
+ }
63
+ function wakeDrivers(harness) {
64
+ const adapter = adapterFor(harness);
65
+ const drivers = (adapter?.wakeLadder ?? []).map((driver) => ({ ...driver, runtime: driver }));
66
+ for (const driver of adapter?.wakeConsentDrivers ?? []) if (!drivers.some((item) => item.id === driver.id)) drivers.push(driver);
67
+ if (harness === "claude" && !drivers.some((driver) => driver.id === "watcher")) drivers.unshift({ id: "watcher", rung: 2, optIn: false });
68
+ return drivers.sort((a, b) => a.rung - b.rung);
69
+ }
70
+ function watcherAlive(pid) {
71
+ if (typeof pid !== "number" || !Number.isSafeInteger(pid) || pid <= 0) return false;
72
+ try {
73
+ process.kill(pid, 0);
74
+ return true;
75
+ } catch (error) {
76
+ return error.code === "EPERM";
77
+ }
78
+ }
79
+ async function wakeStatus(harness, options = {}) {
80
+ const env = options.env ?? process.env;
81
+ const settings = await readWakeSettings(stateRoot(env));
82
+ const states = options.files ? await readWakeState(options.files.dir) : {};
83
+ const drivers = wakeDrivers(harness);
84
+ if (!drivers.length) return [{ harness, rung: 0, ...wakeStatusText("none", harness === "generic" ? "none_by_design" : "unavailable", harness === "generic" ? void 0 : "driver_missing") }];
85
+ const rows = [];
86
+ for (const driver of drivers) {
87
+ const key = `${harness}/${driver.id}`;
88
+ let state;
89
+ let unavailableReason;
90
+ if (Object.hasOwn(settings.off, key)) state = "disabled";
91
+ else if (states[driver.id]?.disabled) state = "disabled_after_failures";
92
+ else if (driver.optIn && !Object.hasOwn(settings.consent, key)) state = "needs_consent";
93
+ else if (driver.id === "watcher") {
94
+ const watcher = options.files ? await readStateFile(options.files.dir, "watcher.json") : null;
95
+ state = watcher?.state === "expired" ? "lapsed" : watcher?.state === "armed" && watcherAlive(watcher.pid) ? "active" : "unavailable";
96
+ if (state === "unavailable") unavailableReason = "watcher_missing";
97
+ } else if (driver.runtime) {
98
+ const files = options.files ?? filesForDir(path.join(stateRoot(env), harness, "status"));
99
+ const ctx = { files, harness, sessionId: options.sessionId ?? "status", env, signal: new AbortController().signal, now: Date.now() };
100
+ const available = await driver.runtime.available(ctx);
101
+ state = available ? "active" : "unavailable";
102
+ if (!available) {
103
+ const reason = await driver.runtime.unavailableReason?.(ctx);
104
+ if (reason && Object.hasOwn(WAKE_STATES.unavailable.reasons, reason)) unavailableReason = reason;
105
+ }
106
+ } else {
107
+ state = "unavailable";
108
+ unavailableReason = process.platform === "win32" && driver.id === "terminal" ? "windows" : "driver_missing";
109
+ }
110
+ rows.push({
111
+ harness,
112
+ rung: driver.rung,
113
+ ...wakeStatusText(driver.id, state, unavailableReason),
114
+ ...harness === "codex" && driver.id === "queue" ? { note: CODEX_DAEMON_WAKE_NOTE } : {}
115
+ });
116
+ }
117
+ return rows;
118
+ }
119
+ function selectedWakeStatus(rows) {
120
+ const row = rows.find((item) => item.state === "active") ?? rows[0];
121
+ const { driver, state, reason, remedy, note } = row;
122
+ return { driver, state, reason, ...remedy ? { remedy } : {}, ...note ? { note } : {} };
123
+ }
124
+ var WAKE_HARNESSES = HARNESS_REGISTRY.map((row) => row.id);
125
+ async function wakeDisableNotice(dir) {
126
+ const { takeWakeDisableNotices } = await import("./chunk-KMLXOPBQ.mjs");
127
+ let drivers;
128
+ try {
129
+ const states = await readWakeState(dir);
130
+ if (!Object.values(states).some((state) => state.disabled && !state.noticeShown)) return void 0;
131
+ drivers = await takeWakeDisableNotices(dir);
132
+ } catch {
133
+ return void 0;
134
+ }
135
+ return drivers.length ? drivers.map((driver) => {
136
+ const status = wakeStatusText(driver, "disabled_after_failures");
137
+ return `Idle wake (${driver}): ${status.reason} Run \`${status.remedy}\` to re-enable it.`;
138
+ }).join("\n") : void 0;
139
+ }
140
+
141
+ export {
142
+ wakeStatusText,
143
+ wakeDrivers,
144
+ wakeStatus,
145
+ selectedWakeStatus,
146
+ WAKE_HARNESSES,
147
+ wakeDisableNotice
148
+ };