khala-cli 0.4.11 → 0.4.13

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 (44) hide show
  1. package/dist/{chunk-HZH74L5T.mjs → chunk-2AIADANH.mjs} +6 -6
  2. package/dist/chunk-2BNIPJVW.mjs +27 -0
  3. package/dist/{chunk-YIKJI26V.mjs → chunk-32SGUUP5.mjs} +2 -2
  4. package/dist/{chunk-7FFHZ7EI.mjs → chunk-3GUVMXTM.mjs} +9 -9
  5. package/dist/{chunk-LDW4HOQW.mjs → chunk-3JA3Q5MK.mjs} +1 -1
  6. package/dist/{chunk-NN5RHU6C.mjs → chunk-6DE4V756.mjs} +10 -10
  7. package/dist/{chunk-FGHPOKXG.mjs → chunk-6P4PKPJW.mjs} +5 -5
  8. package/dist/{chunk-N6UYX3SY.mjs → chunk-72W7IC2O.mjs} +3 -3
  9. package/dist/{chunk-BVG7PJNZ.mjs → chunk-BJVJ5WJS.mjs} +16 -16
  10. package/dist/{chunk-NJ5ICCVZ.mjs → chunk-BWVC3EKG.mjs} +12 -12
  11. package/dist/{chunk-CXVANPY5.mjs → chunk-I4POSYHZ.mjs} +2 -2
  12. package/dist/{chunk-MAIMFERG.mjs → chunk-ICTAFDO6.mjs} +3 -3
  13. package/dist/{chunk-YFX5NDSL.mjs → chunk-JLENHMKE.mjs} +295 -78
  14. package/dist/{chunk-X3BAMHAR.mjs → chunk-JZZNVQKH.mjs} +2 -2
  15. package/dist/{chunk-NE4S7N3R.mjs → chunk-KMDLTHDW.mjs} +2 -2
  16. package/dist/{chunk-LNKI3CZO.mjs → chunk-MRSZOWFU.mjs} +1 -1
  17. package/dist/{chunk-JNSB3E6C.mjs → chunk-NHW62KEB.mjs} +1 -1
  18. package/dist/{chunk-4CENUF7M.mjs → chunk-O4QJ3ZT6.mjs} +3 -3
  19. package/dist/{chunk-3KHLSF4A.mjs → chunk-OIYAR2ND.mjs} +7 -7
  20. package/dist/{chunk-GVZD4TLW.mjs → chunk-ONAZVGVO.mjs} +45 -10
  21. package/dist/{chunk-R5NDTJRA.mjs → chunk-P3XZEYZF.mjs} +1 -1
  22. package/dist/{chunk-YNUCRFM2.mjs → chunk-QPYXV4BQ.mjs} +8 -8
  23. package/dist/{chunk-E5QRD6W3.mjs → chunk-QZUBLJW7.mjs} +2 -2
  24. package/dist/{chunk-NUQSDSVT.mjs → chunk-RUQDE5DI.mjs} +1 -1
  25. package/dist/{chunk-OSVXLZKJ.mjs → chunk-SDBMJPIA.mjs} +6 -6
  26. package/dist/{chunk-H2L5GQ5W.mjs → chunk-SKJ6YV3G.mjs} +12 -12
  27. package/dist/{chunk-WA5LB5GN.mjs → chunk-SUT7AKNZ.mjs} +6 -6
  28. package/dist/{chunk-TVQ4MSEI.mjs → chunk-SUUEWCY5.mjs} +1 -1
  29. package/dist/chunk-TVQ5NHFX.mjs +20 -0
  30. package/dist/chunk-WZD4JAG6.mjs +19 -0
  31. package/dist/{chunk-VWWI4S5A.mjs → chunk-XI5FPUNN.mjs} +2 -2
  32. package/dist/{chunk-NOKTVPSY.mjs → chunk-XR3JSUPF.mjs} +101 -73
  33. package/dist/{chunk-YDEZFVF7.mjs → chunk-XRV5GUSI.mjs} +3 -3
  34. package/dist/{chunk-4PUNVPC3.mjs → chunk-ZWWTVM6R.mjs} +2 -2
  35. package/dist/khala.mjs +11 -11
  36. package/dist/web/assets/local-DLmpMMaF.css +1 -0
  37. package/dist/web/assets/local-mElTRGcH.js +11 -0
  38. package/dist/web/index.html +2 -2
  39. package/package.json +1 -1
  40. package/dist/chunk-AQX2OYEF.mjs +0 -19
  41. package/dist/chunk-CYINL2V3.mjs +0 -20
  42. package/dist/chunk-MYIZQCRW.mjs +0 -27
  43. package/dist/web/assets/local-DPcMk9Xz.css +0 -1
  44. package/dist/web/assets/local-SDOFp8OA.js +0 -9
@@ -2,7 +2,7 @@ import { createRequire as __khalaCreateRequire } from 'node:module'; const requi
2
2
  import {
3
3
  DEFAULT_LISTENING_MODE,
4
4
  decodeListeningMode
5
- } from "./chunk-CXVANPY5.mjs";
5
+ } from "./chunk-I4POSYHZ.mjs";
6
6
  import {
7
7
  advanceCursor,
8
8
  isWakeEntry,
@@ -13,7 +13,7 @@ import {
13
13
  readEntries,
14
14
  unread,
15
15
  wakesAgent
16
- } from "./chunk-N6UYX3SY.mjs";
16
+ } from "./chunk-72W7IC2O.mjs";
17
17
  import {
18
18
  SESSION_ID_PATTERN,
19
19
  StateError,
@@ -23,7 +23,7 @@ import {
23
23
  sessionFiles,
24
24
  stateRoot,
25
25
  writeJsonAtomic
26
- } from "./chunk-JNSB3E6C.mjs";
26
+ } from "./chunk-NHW62KEB.mjs";
27
27
  import {
28
28
  cancelAttempt,
29
29
  confirmWakeText,
@@ -32,16 +32,16 @@ import {
32
32
  settleAttempts,
33
33
  wakeLine,
34
34
  withWakeLock
35
- } from "./chunk-TVQ4MSEI.mjs";
35
+ } from "./chunk-SUUEWCY5.mjs";
36
36
  import {
37
37
  init_define_KHALA_BUNDLE
38
- } from "./chunk-LDW4HOQW.mjs";
38
+ } from "./chunk-3JA3Q5MK.mjs";
39
39
 
40
40
  // src/watch.ts
41
41
  init_define_KHALA_BUNDLE();
42
42
  import * as fs7 from "node:fs/promises";
43
43
  import { watch as watchDirectory } from "node:fs";
44
- import path6 from "node:path";
44
+ import path7 from "node:path";
45
45
  import { randomUUID as randomUUID3 } from "node:crypto";
46
46
 
47
47
  // src/monitor-storage.ts
@@ -76,21 +76,44 @@ async function monitorStorage(files) {
76
76
 
77
77
  // src/mode.ts
78
78
  init_define_KHALA_BUNDLE();
79
+ import path2 from "node:path";
80
+ async function readModeState(files) {
81
+ const content = await readJson(files.mode);
82
+ const record = typeof content === "object" && content !== null ? content : {};
83
+ const decoded = decodeListeningMode(record.mode);
84
+ return { mode: decoded.ok ? decoded.value : DEFAULT_LISTENING_MODE, archived: record.archived === true };
85
+ }
86
+ var delegateFile = (files) => path2.join(files.dir, "delegate.json");
87
+ async function delegateChannel(files, ms) {
88
+ await writeJsonAtomic(delegateFile(files), { until: Date.now() + ms });
89
+ }
90
+ async function isDelegated(files) {
91
+ const lease = await readJson(delegateFile(files)).catch(() => null);
92
+ return typeof lease?.until === "number" && lease.until > Date.now();
93
+ }
79
94
  async function readListeningMode(files) {
95
+ const state = await readModeState(files);
96
+ return state.archived || await isDelegated(files) ? "async" : state.mode;
97
+ }
98
+ async function applyArchived(files, archived) {
80
99
  const content = await readJson(files.mode);
81
- const decoded = decodeListeningMode(typeof content === "object" && content !== null ? content.mode : void 0);
82
- return decoded.ok ? decoded.value : DEFAULT_LISTENING_MODE;
100
+ if (content?.archived === true === archived) return;
101
+ if (!archived && (await readModeState(files)).mode !== "async") await skipBacklog(files);
102
+ await writeJsonAtomic(files.mode, { ...content ?? {}, archived });
83
103
  }
84
- async function applyListeningMode(files, next, meta, now = () => /* @__PURE__ */ new Date()) {
85
- const previous = await readListeningMode(files);
86
- if (previous === "async" && next !== "async") {
87
- for (let attempt = 0; attempt < 2; attempt++) {
88
- const { cursor, entries } = await unread(files);
89
- if (await advanceCursor(files, cursor, entries) !== "conflict") break;
90
- if (attempt === 1) throw new StateError("storage_failed");
91
- }
104
+ async function skipBacklog(files) {
105
+ for (let attempt = 0; attempt < 2; attempt++) {
106
+ const { cursor, entries } = await unread(files);
107
+ if (await advanceCursor(files, cursor, entries) !== "conflict") return;
92
108
  }
93
- await writeJsonAtomic(files.mode, { mode: next, ...meta, updatedAt: now().toISOString() });
109
+ throw new StateError("storage_failed");
110
+ }
111
+ var ATTENTION = { async: 0, sync: 1, steer: 2 };
112
+ async function applyListeningMode(files, next, meta, now = () => /* @__PURE__ */ new Date()) {
113
+ const { keepBacklog, ...record } = meta;
114
+ const { mode: previous, archived } = await readModeState(files);
115
+ if (previous === "async" && next !== "async" && !keepBacklog) await skipBacklog(files);
116
+ await writeJsonAtomic(files.mode, { mode: next, ...archived ? { archived } : {}, ...record, updatedAt: now().toISOString() });
94
117
  return { previous, next };
95
118
  }
96
119
 
@@ -100,11 +123,11 @@ init_define_KHALA_BUNDLE();
100
123
  // src/wake/shared/settings.ts
101
124
  init_define_KHALA_BUNDLE();
102
125
  import * as fs2 from "node:fs/promises";
103
- import path2 from "node:path";
126
+ import path3 from "node:path";
104
127
  import { randomBytes } from "node:crypto";
105
128
  async function readWakeSettings(root) {
106
129
  try {
107
- const value = JSON.parse(await fs2.readFile(path2.join(root, "wake-settings.json"), "utf8"));
130
+ const value = JSON.parse(await fs2.readFile(path3.join(root, "wake-settings.json"), "utf8"));
108
131
  const entries = (input) => {
109
132
  if (!input || typeof input !== "object" || Array.isArray(input)) return {};
110
133
  return Object.fromEntries(Object.entries(input).filter(([, entry]) => entry && typeof entry === "object" && typeof entry.at === "string"));
@@ -117,7 +140,7 @@ async function readWakeSettings(root) {
117
140
  }
118
141
  async function writeWakeSettings(root, settings) {
119
142
  await fs2.mkdir(root, { recursive: true, mode: 448 });
120
- const target2 = path2.join(root, "wake-settings.json");
143
+ const target2 = path3.join(root, "wake-settings.json");
121
144
  const temp = `${target2}.${randomBytes(8).toString("hex")}.tmp`;
122
145
  try {
123
146
  await fs2.writeFile(temp, JSON.stringify(settings), { mode: 384 });
@@ -144,7 +167,7 @@ init_define_KHALA_BUNDLE();
144
167
  import { createInterface } from "node:readline";
145
168
  import * as fs4 from "node:fs/promises";
146
169
  import os2 from "node:os";
147
- import path4 from "node:path";
170
+ import path5 from "node:path";
148
171
 
149
172
  // src/install/cursor.ts
150
173
  init_define_KHALA_BUNDLE();
@@ -187,12 +210,12 @@ function nodeScriptCommand(platform, node, script) {
187
210
 
188
211
  // src/install/launcher.ts
189
212
  init_define_KHALA_BUNDLE();
190
- function installedLauncher(platform, path7, home, env) {
213
+ function installedLauncher(platform, path8, home, env) {
191
214
  const windows = platform === "win32";
192
215
  const candidate = windows ? env.LOCALAPPDATA : env.XDG_DATA_HOME;
193
- const dataHome = candidate && path7.isAbsolute(candidate) ? candidate : windows ? path7.join(home, "AppData", "Local") : path7.join(home, ".local", "share");
194
- const prefix = path7.join(dataHome, "khala", "npm");
195
- return { prefix, bin: windows ? path7.join(prefix, "khala.cmd") : path7.join(prefix, "bin", "khala") };
216
+ const dataHome = candidate && path8.isAbsolute(candidate) ? candidate : windows ? path8.join(home, "AppData", "Local") : path8.join(home, ".local", "share");
217
+ const prefix = path8.join(dataHome, "khala", "npm");
218
+ return { prefix, bin: windows ? path8.join(prefix, "khala.cmd") : path8.join(prefix, "bin", "khala") };
196
219
  }
197
220
  function launcherShellQuote(platform, bin) {
198
221
  return platform === "win32" ? `"${bin}"` : `'${bin.replaceAll("'", `'\\''`)}'`;
@@ -201,7 +224,7 @@ function launcherShellQuote(platform, bin) {
201
224
  // src/install/managed-file.ts
202
225
  init_define_KHALA_BUNDLE();
203
226
  import * as fs3 from "node:fs/promises";
204
- import path3 from "node:path";
227
+ import path4 from "node:path";
205
228
  import { isDeepStrictEqual } from "node:util";
206
229
  var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
207
230
  var BOM = "\uFEFF";
@@ -250,7 +273,7 @@ var LEGACY_BACKUP = ".khala-bak";
250
273
  var ManagedFiles = class {
251
274
  store;
252
275
  constructor(stateDir) {
253
- this.store = path3.join(stateDir, "install-originals.json");
276
+ this.store = path4.join(stateDir, "install-originals.json");
254
277
  }
255
278
  async load() {
256
279
  try {
@@ -266,14 +289,14 @@ var ManagedFiles = class {
266
289
  await fs3.rm(this.store, { force: true });
267
290
  return;
268
291
  }
269
- await fs3.mkdir(path3.dirname(this.store), { recursive: true, mode: 448 });
292
+ await fs3.mkdir(path4.dirname(this.store), { recursive: true, mode: 448 });
270
293
  const temp = `${this.store}.${process.pid}.tmp`;
271
294
  await fs3.writeFile(temp, JSON.stringify(recordings, null, 2) + "\n", { mode: 384 });
272
295
  await fs3.rename(temp, this.store);
273
296
  }
274
297
  /** The recorded original: `undefined` when nothing is recorded, `null` when the file did not exist. */
275
298
  async original(file) {
276
- const recording = (await this.load())[path3.resolve(file)];
299
+ const recording = (await this.load())[path4.resolve(file)];
277
300
  if (recording) return recording.existed ? Buffer.from(recording.bytes ?? "", "base64") : null;
278
301
  const legacy = await readBytes(file + LEGACY_BACKUP);
279
302
  return legacy ?? void 0;
@@ -285,12 +308,12 @@ var ManagedFiles = class {
285
308
  * the override still never replaces a previously saved recording.
286
309
  */
287
310
  async record(file, options) {
288
- const key = path3.resolve(file);
311
+ const key = path4.resolve(file);
289
312
  const recordings = await this.load();
290
313
  if (recordings[key]) return;
291
314
  const legacy = await readBytes(file + LEGACY_BACKUP);
292
315
  const current = options ? options.original : legacy ?? await readBytes(file);
293
- recordings[key] = current === null ? { existed: false, createdDirs: await missingDirs(path3.dirname(key)) } : { existed: true, bytes: current.toString("base64"), createdDirs: [] };
316
+ recordings[key] = current === null ? { existed: false, createdDirs: await missingDirs(path4.dirname(key)) } : { existed: true, bytes: current.toString("base64"), createdDirs: [] };
294
317
  await this.save(recordings);
295
318
  if (legacy) await fs3.rm(file + LEGACY_BACKUP, { force: true });
296
319
  }
@@ -302,7 +325,7 @@ var ManagedFiles = class {
302
325
  for (const { current } of entries) await this.record(current.file);
303
326
  for (const { current, text, mode } of entries) {
304
327
  if (text === current.text) continue;
305
- await fs3.mkdir(path3.dirname(current.file), { recursive: true });
328
+ await fs3.mkdir(path4.dirname(current.file), { recursive: true });
306
329
  await fs3.writeFile(current.file, text, mode === void 0 ? void 0 : { mode });
307
330
  }
308
331
  }
@@ -314,7 +337,7 @@ var ManagedFiles = class {
314
337
  * stripped content. The recording is then dropped.
315
338
  */
316
339
  async restore(current, format, strip) {
317
- const key = path3.resolve(current.file);
340
+ const key = path4.resolve(current.file);
318
341
  const recordings = await this.load();
319
342
  const recording = recordings[key];
320
343
  const original = await this.original(current.file);
@@ -357,7 +380,7 @@ async function readBytes(file) {
357
380
  }
358
381
  async function missingDirs(dir) {
359
382
  const missing = [];
360
- for (let at = dir; ; at = path3.dirname(at)) {
383
+ for (let at = dir; ; at = path4.dirname(at)) {
361
384
  try {
362
385
  await fs3.stat(at);
363
386
  return missing;
@@ -365,24 +388,24 @@ async function missingDirs(dir) {
365
388
  if (error.code !== "ENOENT") throw error;
366
389
  }
367
390
  missing.push(at);
368
- if (path3.dirname(at) === at) return missing;
391
+ if (path4.dirname(at) === at) return missing;
369
392
  }
370
393
  }
371
394
 
372
395
  // src/install/cursor.ts
373
396
  var CURSOR_HOOK_EVENTS = ["beforeSubmitPrompt", "postToolUse", "stop"];
374
397
  var HOOK_SUFFIX = " hook deliver --harness cursor";
375
- function cursorPaths({ platform, path: path7, home, env }, packageName = "khala-cli") {
376
- const cursorDir = path7.join(home, ".cursor");
398
+ function cursorPaths({ platform, path: path8, home, env }, packageName = "khala-cli") {
399
+ const cursorDir = path8.join(home, ".cursor");
377
400
  const windows = platform === "win32";
378
- const { prefix } = installedLauncher(platform, path7, home, env);
379
- const modules = windows ? path7.join(prefix, "node_modules") : path7.join(prefix, "lib", "node_modules");
401
+ const { prefix } = installedLauncher(platform, path8, home, env);
402
+ const modules = windows ? path8.join(prefix, "node_modules") : path8.join(prefix, "lib", "node_modules");
380
403
  return {
381
404
  cursorDir,
382
405
  prefix,
383
- mcpFile: path7.join(cursorDir, "mcp.json"),
384
- hooksFile: path7.join(cursorDir, "hooks.json"),
385
- script: path7.join(modules, ...packageName.split("/"), "dist", "khala.mjs")
406
+ mcpFile: path8.join(cursorDir, "mcp.json"),
407
+ hooksFile: path8.join(cursorDir, "hooks.json"),
408
+ script: path8.join(modules, ...packageName.split("/"), "dist", "khala.mjs")
386
409
  };
387
410
  }
388
411
  function cursorHookCommand(platform, node, script) {
@@ -481,8 +504,8 @@ var MUSE_WAKE_REQUEST = "muse-monitor-wake.json";
481
504
  var shellQuote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
482
505
  function museCliPath(env = process.env) {
483
506
  const home = env.HOME || env.USERPROFILE || os2.homedir();
484
- const { prefix } = cursorPaths({ platform: process.platform, path: path4, home, env });
485
- return process.platform === "win32" ? path4.join(prefix, "khala.cmd") : path4.join(prefix, "bin", "khala");
507
+ const { prefix } = cursorPaths({ platform: process.platform, path: path5, home, env });
508
+ return process.platform === "win32" ? path5.join(prefix, "khala.cmd") : path5.join(prefix, "bin", "khala");
486
509
  }
487
510
  function museWatchCommand(sessionId, bin = museCliPath(), platform = process.platform) {
488
511
  const quote = platform === "win32" ? (value) => `'${value.replaceAll("'", "''")}'` : shellQuote;
@@ -517,7 +540,7 @@ function createMuseMonitorDriver() {
517
540
  if (ctx.signal.aborted || (await readActivity(ctx.files)).state !== "idle" || !await monitorArmed(ctx.files)) return "skipped";
518
541
  const epoch = (await readActivity(ctx.files)).updatedAt;
519
542
  for (const dir of monitorStorageCandidates(ctx.files)) {
520
- if ((await readJson(path4.join(dir, "monitor-wake-observed.json")))?.epoch === epoch) return "skipped";
543
+ if ((await readJson(path5.join(dir, "monitor-wake-observed.json")))?.epoch === epoch) return "skipped";
521
544
  }
522
545
  const owner = await monitorOwner(ctx.files);
523
546
  if (!owner) return "skipped";
@@ -530,7 +553,7 @@ function createMuseMonitorDriver() {
530
553
  if (error.code !== "ENOENT") throw error;
531
554
  }
532
555
  }
533
- await writeJsonAtomic(path4.join(ctx.files.dir, MUSE_WAKE_REQUEST), {
556
+ await writeJsonAtomic(path5.join(ctx.files.dir, MUSE_WAKE_REQUEST), {
534
557
  owner: owner.nonce,
535
558
  line,
536
559
  at: ctx.now,
@@ -545,8 +568,8 @@ function museJournalPath(sessionId, env) {
545
568
  const created = new Date(Number.parseInt(sessionId.replaceAll("-", "").slice(0, 12), 16));
546
569
  const date = [String(created.getFullYear()), String(created.getMonth() + 1).padStart(2, "0"), String(created.getDate()).padStart(2, "0")];
547
570
  const home = env.HOME || env.USERPROFILE || os2.homedir();
548
- const data = env.XDG_DATA_HOME && path4.isAbsolute(env.XDG_DATA_HOME) ? env.XDG_DATA_HOME : path4.join(home, ".local", "share");
549
- return path4.join(data, "muse", "sessions", ...date, sessionId, "session.jsonl");
571
+ const data = env.XDG_DATA_HOME && path5.isAbsolute(env.XDG_DATA_HOME) ? env.XDG_DATA_HOME : path5.join(home, ".local", "share");
572
+ return path5.join(data, "muse", "sessions", ...date, sessionId, "session.jsonl");
550
573
  }
551
574
  async function museStopWakeText(stdin, files, env) {
552
575
  const input = JSON.parse(stdin);
@@ -554,7 +577,7 @@ async function museStopWakeText(stdin, files, env) {
554
577
  return museWakeProof(files, input.session_id, env, input.turn_id);
555
578
  }
556
579
  async function museWakeProof(files, sessionId, env, turnId) {
557
- const request = await readJson(path4.join(files.dir, MUSE_WAKE_REQUEST));
580
+ const request = await readJson(path5.join(files.dir, MUSE_WAKE_REQUEST));
558
581
  if (!request) return void 0;
559
582
  const journal = museJournalPath(sessionId, env);
560
583
  if (!journal) return void 0;
@@ -594,7 +617,7 @@ init_define_KHALA_BUNDLE();
594
617
  import * as fs6 from "node:fs/promises";
595
618
  import net from "node:net";
596
619
  import os3 from "node:os";
597
- import path5 from "node:path";
620
+ import path6 from "node:path";
598
621
  import { randomBytes as randomBytes2, randomUUID as randomUUID2 } from "node:crypto";
599
622
 
600
623
  // src/wake/qwen-transcript.ts
@@ -633,23 +656,23 @@ async function verifyQwenTranscript(dir, filePath, now) {
633
656
  }
634
657
 
635
658
  // src/wake/qwen-socket.ts
636
- var qwenHome = (env) => env.QWEN_HOME ? path5.resolve(env.QWEN_HOME) : path5.join(env.HOME ?? os3.homedir(), ".qwen");
659
+ var qwenHome = (env) => env.QWEN_HOME ? path6.resolve(env.QWEN_HOME) : path6.join(env.HOME ?? os3.homedir(), ".qwen");
637
660
  async function qwenInboundAllowed(env, workspace = env.PWD ?? process.cwd()) {
638
- for (const file of [path5.join(qwenHome(env), "settings.json"), path5.join(workspace, ".qwen", "settings.json")]) {
661
+ for (const file of [path6.join(qwenHome(env), "settings.json"), path6.join(workspace, ".qwen", "settings.json")]) {
639
662
  const config = await readJson(file);
640
663
  if (["hold", "refuse"].includes(config?.agents?.crossSessionInbound ?? "") || config?.agents?.crossSessionMessaging === false) return false;
641
664
  }
642
665
  return true;
643
666
  }
644
- var qwenControllerFile = (env) => path5.join(stateRoot(env), "qwen", "controller.json");
667
+ var qwenControllerFile = (env) => path6.join(stateRoot(env), "qwen", "controller.json");
645
668
  async function qwenSession(env) {
646
669
  const socket = env.QWEN_CODE_MESSAGING_SOCKET;
647
670
  if (!socket) return void 0;
648
671
  try {
649
- const dir = path5.join(qwenHome(env), "sessions");
672
+ const dir = path6.join(qwenHome(env), "sessions");
650
673
  for (const file of await fs6.readdir(dir)) {
651
674
  if (!/^\d+\.json$/u.test(file)) continue;
652
- const record = await readJson(path5.join(dir, file));
675
+ const record = await readJson(path6.join(dir, file));
653
676
  if (record?.ipcPath === socket && typeof record.sessionId === "string" && SESSION_ID_PATTERN.test(record.sessionId)) return record.sessionId;
654
677
  }
655
678
  } catch {
@@ -686,8 +709,8 @@ function qwenFrames(target2, line, from, replyToken, msgId) {
686
709
  }
687
710
  async function sendQwenWake(target2, line, signal, options = {}) {
688
711
  if (signal.aborted) return "failed";
689
- const dir = await fs6.mkdtemp(path5.join(options.runtimeDir ?? os3.tmpdir(), "khala-qw-"));
690
- const from = path5.join(dir, "r.sock");
712
+ const dir = await fs6.mkdtemp(path6.join(options.runtimeDir ?? os3.tmpdir(), "khala-qw-"));
713
+ const from = path6.join(dir, "r.sock");
691
714
  if (Buffer.byteLength(from) > 103) {
692
715
  await fs6.rm(dir, { recursive: true, force: true });
693
716
  return "failed";
@@ -767,14 +790,14 @@ async function sendQwenWake(target2, line, signal, options = {}) {
767
790
  function createQwenSocketDriver(deps = {}) {
768
791
  const resolve = deps.resolve ?? target;
769
792
  const policy = async (env) => {
770
- const config = await readJson(path5.join(qwenHome(env), "settings.json"));
793
+ const config = await readJson(path6.join(qwenHome(env), "settings.json"));
771
794
  return config?.agents;
772
795
  };
773
796
  const reason = async (ctx) => {
774
797
  const config = await policy(ctx.env);
775
798
  if (config?.crossSessionInbound === "hold") return "qwen_held";
776
799
  if ((deps.platform ?? process.platform) === "win32") return "windows";
777
- const receipt = await readJson(path5.join(ctx.files.dir, "qwen-receipt.json"));
800
+ const receipt = await readJson(path6.join(ctx.files.dir, "qwen-receipt.json"));
778
801
  if (receipt?.status === "held" && config?.crossSessionInbound !== "accept") return "qwen_held";
779
802
  if (config?.crossSessionMessaging === false || config?.crossSessionInbound === "refuse") return "qwen_refused";
780
803
  if (!deps.resolve && !ctx.env.QWEN_CODE_MESSAGING_SOCKET) return "qwen_session_missing";
@@ -788,15 +811,15 @@ function createQwenSocketDriver(deps = {}) {
788
811
  deadlineMs: 3e4,
789
812
  verification: "transcript",
790
813
  async verify(ctx) {
791
- const journal = await readJson(path5.join(ctx.files.dir, "wake-journal.json"));
792
- const receipt = await readJson(path5.join(ctx.files.dir, "qwen-receipt.json"));
814
+ const journal = await readJson(path6.join(ctx.files.dir, "wake-journal.json"));
815
+ const receipt = await readJson(path6.join(ctx.files.dir, "qwen-receipt.json"));
793
816
  if (!journal?.attempts?.some((attempt) => attempt.driver === "socket") && receipt?.status !== "held") return;
794
- const transcript = await readJson(path5.join(ctx.files.dir, "qwen-transcript.json"));
817
+ const transcript = await readJson(path6.join(ctx.files.dir, "qwen-transcript.json"));
795
818
  if (!transcript?.path) return;
796
819
  try {
797
820
  const text = await verifyQwenTranscript(ctx.files.dir, transcript.path, ctx.now);
798
821
  if (receipt?.status === "held" && receipt.nonce && text?.includes(`(k-${receipt.nonce})`)) {
799
- await writeJsonAtomic(path5.join(ctx.files.dir, "qwen-receipt.json"), { status: "delivered" });
822
+ await writeJsonAtomic(path6.join(ctx.files.dir, "qwen-receipt.json"), { status: "delivered" });
800
823
  }
801
824
  } catch {
802
825
  }
@@ -810,7 +833,7 @@ function createQwenSocketDriver(deps = {}) {
810
833
  const status = await (deps.send ?? sendQwenWake)(destination, line, ctx.signal);
811
834
  await ensureStateDir(ctx.files.dir);
812
835
  const nonce = line.match(/\(k-([0-9a-f]{8})\)$/u)?.[1];
813
- await writeJsonAtomic(path5.join(ctx.files.dir, "qwen-receipt.json"), { status, nonce });
836
+ await writeJsonAtomic(path6.join(ctx.files.dir, "qwen-receipt.json"), { status, nonce });
814
837
  if (nonce && status === "held") await cancelAttempt(ctx.files.dir, nonce);
815
838
  else if (nonce && status !== "delivered") await failAttempt(ctx.files.dir, nonce, ctx.now);
816
839
  }
@@ -821,11 +844,11 @@ function createQwenSocketDriver(deps = {}) {
821
844
  var MARKER = "monitor.json";
822
845
  var OBSERVATION = "monitor-cursor.json";
823
846
  var NONCE_PATTERN = /^[a-f0-9-]{36}$/;
824
- var leaseFile = (dir, nonce) => path6.join(dir, `monitor-${nonce}.json`);
847
+ var leaseFile = (dir, nonce) => path7.join(dir, `monitor-${nonce}.json`);
825
848
  async function monitorOwner(files) {
826
849
  const owners = [];
827
850
  for (const dir of monitorStorageCandidates(files)) {
828
- const owner = await readJson(path6.join(dir, MARKER));
851
+ const owner = await readJson(path7.join(dir, MARKER));
829
852
  if (!owner || !Number.isSafeInteger(owner.pid) || owner.pid <= 0 || typeof owner.nonce !== "string" || !NONCE_PATTERN.test(owner.nonce)) continue;
830
853
  const lease = await readJson(leaseFile(dir, owner.nonce));
831
854
  if (lease?.nonce !== owner.nonce) continue;
@@ -944,7 +967,7 @@ async function watchSession(files, io) {
944
967
  }
945
968
  const mode = await readListeningMode(target2);
946
969
  const entries = await readEntries(target2);
947
- const observed = await readJson(path6.join(await observationDir(target2), OBSERVATION));
970
+ const observed = await readJson(path7.join(await observationDir(target2), OBSERVATION));
948
971
  const position = observed?.userId === session.userId && observed?.roomId === session.roomId && Number.isSafeInteger(observed.count) && observed.count >= 0 && observed.count <= entries.length && (observed.count === 0 || entries[observed.count - 1]?.eventId === observed.lastEventId) ? observed.count : 0;
949
972
  const baseline = initialDelivered.get(target2.dir).cursor;
950
973
  const initialCount = baseline.deliveredCount === 0 || entries[baseline.deliveredCount - 1]?.eventId === baseline.lastDeliveredEventId ? baseline.deliveredCount : 0;
@@ -970,7 +993,7 @@ async function watchSession(files, io) {
970
993
  }
971
994
  if (position !== entries.length && !done && await ownsSession() && JSON.stringify(await readJson(target2.session)) === JSON.stringify(latestSession)) {
972
995
  try {
973
- await writeJsonAtomic(path6.join(await observationDir(target2), OBSERVATION), {
996
+ await writeJsonAtomic(path7.join(await observationDir(target2), OBSERVATION), {
974
997
  userId: session.userId,
975
998
  roomId: session.roomId,
976
999
  count: entries.length,
@@ -982,7 +1005,7 @@ async function watchSession(files, io) {
982
1005
  }
983
1006
  }
984
1007
  if (io.harness === "muse" && !done && await ownsSession()) {
985
- const request = await readJson(path6.join(files.dir, MUSE_WAKE_REQUEST));
1008
+ const request = await readJson(path7.join(files.dir, MUSE_WAKE_REQUEST));
986
1009
  const now = (io.now ?? Date.now)();
987
1010
  const wakeNonce = typeof request?.line === "string" ? /\(k-([a-f0-9]{8})\)$/.exec(request.line)?.[1] : void 0;
988
1011
  if (request?.owner === nonce && wakeNonce && wakeLine(wakeNonce) === request.line && request.line !== emittedRequest && now >= request.at && now < request.deadline && await driverAllowed(stateRoot(io.env ?? process.env), "muse", "monitor", false) && !(await readWakeState(files.dir)).monitor?.disabled && (await readActivity(files)).state === "idle") {
@@ -1000,7 +1023,7 @@ async function watchSession(files, io) {
1000
1023
  const activity = await readActivity(files);
1001
1024
  if (eligible && await ownsSession() && activity.state === "idle") {
1002
1025
  const epoch = activity.updatedAt;
1003
- const dedupFile = path6.join(storage, "monitor-wake-observed.json");
1026
+ const dedupFile = path7.join(storage, "monitor-wake-observed.json");
1004
1027
  const observed = await readJson(dedupFile);
1005
1028
  if (observed?.epoch === epoch) return;
1006
1029
  await writeJsonAtomic(dedupFile, { epoch, line: request.line });
@@ -1031,7 +1054,7 @@ async function watchSession(files, io) {
1031
1054
  watcher.on("error", (error) => stop(3, errorReason(error)));
1032
1055
  lastHeartbeat = Date.now();
1033
1056
  await writeJsonAtomic(leaseFile(storage, nonce), { nonce, pid: process.pid, heartbeatAt: new Date(lastHeartbeat).toISOString() });
1034
- await writeJsonAtomic(path6.join(storage, MARKER), { nonce, pid: process.pid, startedAt: Date.now() });
1057
+ await writeJsonAtomic(path7.join(storage, MARKER), { nonce, pid: process.pid, startedAt: Date.now() });
1035
1058
  published = true;
1036
1059
  timer = setInterval(notify, 100);
1037
1060
  io.signal.addEventListener("abort", abort, { once: true });
@@ -1064,8 +1087,8 @@ ${WATCH_USAGE}`);
1064
1087
  return 1;
1065
1088
  };
1066
1089
  if (argv.length !== 0 && !(argv.length === 2 && ["--session", "--harness"].includes(argv[0])) && !(argv.length === 4 && argv[0] === "--harness" && argv[2] === "--session")) return invalid("invalid_arguments");
1067
- const { resolveHarness, resolveSessionId } = await import("./chunk-CYINL2V3.mjs");
1068
- const { adapterFor } = await import("./chunk-AQX2OYEF.mjs");
1090
+ const { resolveHarness, resolveSessionId } = await import("./chunk-TVQ5NHFX.mjs");
1091
+ const { adapterFor } = await import("./chunk-WZD4JAG6.mjs");
1069
1092
  const harness = resolveHarness(argv, process.env);
1070
1093
  if (harness === "invalid" || !adapterFor(harness)?.codec) return invalid("invalid_harness");
1071
1094
  const index = argv.indexOf("--session");
@@ -1093,7 +1116,12 @@ export {
1093
1116
  readWakeSettings,
1094
1117
  updateWakeSettings,
1095
1118
  driverAllowed,
1119
+ readModeState,
1120
+ delegateChannel,
1121
+ isDelegated,
1096
1122
  readListeningMode,
1123
+ applyArchived,
1124
+ ATTENTION,
1097
1125
  applyListeningMode,
1098
1126
  CURSOR_WORKSPACE_ENV,
1099
1127
  CURSOR_DEFAULT_SESSION,
@@ -1,18 +1,18 @@
1
1
  import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
2
2
  import {
3
3
  retryUnexpired
4
- } from "./chunk-LNKI3CZO.mjs";
4
+ } from "./chunk-MRSZOWFU.mjs";
5
5
  import {
6
6
  StateError,
7
7
  ensureStateDir,
8
8
  writeJsonAtomic
9
- } from "./chunk-JNSB3E6C.mjs";
9
+ } from "./chunk-NHW62KEB.mjs";
10
10
  import {
11
11
  __commonJS,
12
12
  __export,
13
13
  __toESM,
14
14
  init_define_KHALA_BUNDLE
15
- } from "./chunk-LDW4HOQW.mjs";
15
+ } from "./chunk-3JA3Q5MK.mjs";
16
16
 
17
17
  // ../../node_modules/.pnpm/immediate@3.3.0/node_modules/immediate/lib/nextTick.js
18
18
  var require_nextTick = __commonJS({
@@ -4,10 +4,10 @@ import {
4
4
  readJson,
5
5
  readProcess,
6
6
  writeJsonAtomic
7
- } from "./chunk-JNSB3E6C.mjs";
7
+ } from "./chunk-NHW62KEB.mjs";
8
8
  import {
9
9
  init_define_KHALA_BUNDLE
10
- } from "./chunk-LDW4HOQW.mjs";
10
+ } from "./chunk-3JA3Q5MK.mjs";
11
11
 
12
12
  // src/wake/terminal/capture.ts
13
13
  init_define_KHALA_BUNDLE();
package/dist/khala.mjs CHANGED
@@ -2,11 +2,11 @@
2
2
  import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
3
3
  import {
4
4
  KHALA_AGENT_VERSION
5
- } from "./chunk-YIKJI26V.mjs";
6
- import "./chunk-NUQSDSVT.mjs";
5
+ } from "./chunk-32SGUUP5.mjs";
6
+ import "./chunk-RUQDE5DI.mjs";
7
7
  import {
8
8
  init_define_KHALA_BUNDLE
9
- } from "./chunk-LDW4HOQW.mjs";
9
+ } from "./chunk-3JA3Q5MK.mjs";
10
10
 
11
11
  // src/cli-bundle.ts
12
12
  init_define_KHALA_BUNDLE();
@@ -84,15 +84,15 @@ async function runCli(argv, modules) {
84
84
 
85
85
  // src/cli-bundle.ts
86
86
  var hooks = {
87
- "session-start": () => import("./chunk-WA5LB5GN.mjs"),
88
- deliver: () => import("./chunk-NN5RHU6C.mjs"),
89
- "claude-wake": () => import("./chunk-H2L5GQ5W.mjs")
87
+ "session-start": () => import("./chunk-SUT7AKNZ.mjs"),
88
+ deliver: () => import("./chunk-6DE4V756.mjs"),
89
+ "claude-wake": () => import("./chunk-SKJ6YV3G.mjs")
90
90
  };
91
91
  process.exitCode = await runCli(process.argv.slice(2), {
92
- mcp: () => () => import("./chunk-YFX5NDSL.mjs"),
93
- watch: () => () => import("./chunk-3KHLSF4A.mjs"),
94
- local: () => () => import("./chunk-7FFHZ7EI.mjs"),
95
- install: () => () => import("./chunk-NJ5ICCVZ.mjs"),
96
- wake: () => () => import("./chunk-MYIZQCRW.mjs"),
92
+ mcp: () => () => import("./chunk-JLENHMKE.mjs"),
93
+ watch: () => () => import("./chunk-OIYAR2ND.mjs"),
94
+ local: () => () => import("./chunk-3GUVMXTM.mjs"),
95
+ install: () => () => import("./chunk-BWVC3EKG.mjs"),
96
+ wake: () => () => import("./chunk-2BNIPJVW.mjs"),
97
97
  hook: (name) => Object.hasOwn(hooks, name) ? hooks[name] : void 0
98
98
  });