khala-cli 0.4.10 → 0.4.12
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/dist/{chunk-CKLCR5G4.mjs → chunk-25N4V2LE.mjs} +12 -12
- package/dist/{chunk-JKOJQTFT.mjs → chunk-2MEWZ7PJ.mjs} +2 -2
- package/dist/{chunk-EVT2DWNZ.mjs → chunk-374APJUQ.mjs} +1 -1
- package/dist/{chunk-VDZK4LW3.mjs → chunk-56GZYKLK.mjs} +3 -3
- package/dist/{chunk-ARIDZOTI.mjs → chunk-5HDFP7EB.mjs} +225 -70
- package/dist/{chunk-XR625T3I.mjs → chunk-6H34GNLY.mjs} +2 -2
- package/dist/{chunk-OEV5DFLW.mjs → chunk-757A5TML.mjs} +5 -3
- package/dist/chunk-7CKX3Q7L.mjs +27 -0
- package/dist/{chunk-VAC3JTAV.mjs → chunk-7GMBN2XQ.mjs} +12 -12
- package/dist/{chunk-CHC4VZF5.mjs → chunk-7YXXLBQW.mjs} +7 -7
- package/dist/{chunk-6AQVW5W7.mjs → chunk-C53OOWTD.mjs} +2 -2
- package/dist/{chunk-OIZ4R5H7.mjs → chunk-CKLFGEDW.mjs} +6 -6
- package/dist/{chunk-WUDXHF2Q.mjs → chunk-CYJZXNTH.mjs} +2 -2
- package/dist/{chunk-4BP7V3OP.mjs → chunk-EGMBLNRJ.mjs} +2 -2
- package/dist/{chunk-SRZTHCXP.mjs → chunk-G2RJ4C3T.mjs} +5 -5
- package/dist/{chunk-6J2PUM7L.mjs → chunk-IV5R3D2G.mjs} +6 -6
- package/dist/{chunk-UX34IVN5.mjs → chunk-JDKPAIJX.mjs} +2 -2
- package/dist/{chunk-C2WEDMAF.mjs → chunk-KI2MRAEE.mjs} +1 -1
- package/dist/{chunk-2AMWQ7RB.mjs → chunk-LPJQCFRQ.mjs} +98 -73
- package/dist/{chunk-G3NMB4PY.mjs → chunk-MNN5BRU5.mjs} +1 -1
- package/dist/{chunk-3E5DH3Y6.mjs → chunk-PAFNLPIE.mjs} +3 -3
- package/dist/{chunk-HHEZVPRR.mjs → chunk-QXL6ALYP.mjs} +1 -1
- package/dist/{chunk-PN25BUQ4.mjs → chunk-R3TTOYPJ.mjs} +1 -1
- package/dist/chunk-RGQPDR53.mjs +19 -0
- package/dist/{chunk-FJVVSKZ3.mjs → chunk-RL7VBTAR.mjs} +2 -2
- package/dist/chunk-SICAKRPY.mjs +20 -0
- package/dist/{chunk-4BZQ4GVW.mjs → chunk-SPGPUO3H.mjs} +3 -3
- package/dist/{chunk-QDPJ4VT2.mjs → chunk-TBQNSDP7.mjs} +10 -10
- package/dist/{chunk-ZSKLNZWZ.mjs → chunk-WWFOB6XW.mjs} +1 -1
- package/dist/{chunk-W6HM6F2U.mjs → chunk-XMNU4QC5.mjs} +6 -6
- package/dist/{chunk-PJKI7SRI.mjs → chunk-YK3LMWRB.mjs} +49 -10
- package/dist/{chunk-NDMFD5IM.mjs → chunk-YLEJQZFS.mjs} +8 -8
- package/dist/{chunk-WPNMWNCL.mjs → chunk-ZK6QVJ5Q.mjs} +9 -9
- package/dist/{chunk-5JSGA6OB.mjs → chunk-ZOUDN7LE.mjs} +16 -16
- package/dist/khala.mjs +11 -11
- package/dist/web/assets/local-CLw1_1-V.js +11 -0
- package/dist/web/assets/local-qpo5wk6U.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/chunk-6SUV3EW6.mjs +0 -27
- package/dist/chunk-TSK3HJEG.mjs +0 -20
- package/dist/chunk-WZJ6DQJV.mjs +0 -19
- package/dist/web/assets/local-CSPuGnH2.css +0 -1
- package/dist/web/assets/local-Dtyxaacx.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-
|
|
5
|
+
} from "./chunk-EGMBLNRJ.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-
|
|
16
|
+
} from "./chunk-757A5TML.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-
|
|
26
|
+
} from "./chunk-R3TTOYPJ.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-
|
|
35
|
+
} from "./chunk-WWFOB6XW.mjs";
|
|
36
36
|
import {
|
|
37
37
|
init_define_KHALA_BUNDLE
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-374APJUQ.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
|
|
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,42 @@ 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
|
-
|
|
82
|
-
|
|
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
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
109
|
+
throw new StateError("storage_failed");
|
|
110
|
+
}
|
|
111
|
+
async function applyListeningMode(files, next, meta, now = () => /* @__PURE__ */ new Date()) {
|
|
112
|
+
const { mode: previous, archived } = await readModeState(files);
|
|
113
|
+
if (previous === "async" && next !== "async") await skipBacklog(files);
|
|
114
|
+
await writeJsonAtomic(files.mode, { mode: next, ...archived ? { archived } : {}, ...meta, updatedAt: now().toISOString() });
|
|
94
115
|
return { previous, next };
|
|
95
116
|
}
|
|
96
117
|
|
|
@@ -100,11 +121,11 @@ init_define_KHALA_BUNDLE();
|
|
|
100
121
|
// src/wake/shared/settings.ts
|
|
101
122
|
init_define_KHALA_BUNDLE();
|
|
102
123
|
import * as fs2 from "node:fs/promises";
|
|
103
|
-
import
|
|
124
|
+
import path3 from "node:path";
|
|
104
125
|
import { randomBytes } from "node:crypto";
|
|
105
126
|
async function readWakeSettings(root) {
|
|
106
127
|
try {
|
|
107
|
-
const value = JSON.parse(await fs2.readFile(
|
|
128
|
+
const value = JSON.parse(await fs2.readFile(path3.join(root, "wake-settings.json"), "utf8"));
|
|
108
129
|
const entries = (input) => {
|
|
109
130
|
if (!input || typeof input !== "object" || Array.isArray(input)) return {};
|
|
110
131
|
return Object.fromEntries(Object.entries(input).filter(([, entry]) => entry && typeof entry === "object" && typeof entry.at === "string"));
|
|
@@ -117,7 +138,7 @@ async function readWakeSettings(root) {
|
|
|
117
138
|
}
|
|
118
139
|
async function writeWakeSettings(root, settings) {
|
|
119
140
|
await fs2.mkdir(root, { recursive: true, mode: 448 });
|
|
120
|
-
const target2 =
|
|
141
|
+
const target2 = path3.join(root, "wake-settings.json");
|
|
121
142
|
const temp = `${target2}.${randomBytes(8).toString("hex")}.tmp`;
|
|
122
143
|
try {
|
|
123
144
|
await fs2.writeFile(temp, JSON.stringify(settings), { mode: 384 });
|
|
@@ -144,7 +165,7 @@ init_define_KHALA_BUNDLE();
|
|
|
144
165
|
import { createInterface } from "node:readline";
|
|
145
166
|
import * as fs4 from "node:fs/promises";
|
|
146
167
|
import os2 from "node:os";
|
|
147
|
-
import
|
|
168
|
+
import path5 from "node:path";
|
|
148
169
|
|
|
149
170
|
// src/install/cursor.ts
|
|
150
171
|
init_define_KHALA_BUNDLE();
|
|
@@ -187,12 +208,12 @@ function nodeScriptCommand(platform, node, script) {
|
|
|
187
208
|
|
|
188
209
|
// src/install/launcher.ts
|
|
189
210
|
init_define_KHALA_BUNDLE();
|
|
190
|
-
function installedLauncher(platform,
|
|
211
|
+
function installedLauncher(platform, path8, home, env) {
|
|
191
212
|
const windows = platform === "win32";
|
|
192
213
|
const candidate = windows ? env.LOCALAPPDATA : env.XDG_DATA_HOME;
|
|
193
|
-
const dataHome = candidate &&
|
|
194
|
-
const prefix =
|
|
195
|
-
return { prefix, bin: windows ?
|
|
214
|
+
const dataHome = candidate && path8.isAbsolute(candidate) ? candidate : windows ? path8.join(home, "AppData", "Local") : path8.join(home, ".local", "share");
|
|
215
|
+
const prefix = path8.join(dataHome, "khala", "npm");
|
|
216
|
+
return { prefix, bin: windows ? path8.join(prefix, "khala.cmd") : path8.join(prefix, "bin", "khala") };
|
|
196
217
|
}
|
|
197
218
|
function launcherShellQuote(platform, bin) {
|
|
198
219
|
return platform === "win32" ? `"${bin}"` : `'${bin.replaceAll("'", `'\\''`)}'`;
|
|
@@ -201,7 +222,7 @@ function launcherShellQuote(platform, bin) {
|
|
|
201
222
|
// src/install/managed-file.ts
|
|
202
223
|
init_define_KHALA_BUNDLE();
|
|
203
224
|
import * as fs3 from "node:fs/promises";
|
|
204
|
-
import
|
|
225
|
+
import path4 from "node:path";
|
|
205
226
|
import { isDeepStrictEqual } from "node:util";
|
|
206
227
|
var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
207
228
|
var BOM = "\uFEFF";
|
|
@@ -250,7 +271,7 @@ var LEGACY_BACKUP = ".khala-bak";
|
|
|
250
271
|
var ManagedFiles = class {
|
|
251
272
|
store;
|
|
252
273
|
constructor(stateDir) {
|
|
253
|
-
this.store =
|
|
274
|
+
this.store = path4.join(stateDir, "install-originals.json");
|
|
254
275
|
}
|
|
255
276
|
async load() {
|
|
256
277
|
try {
|
|
@@ -266,14 +287,14 @@ var ManagedFiles = class {
|
|
|
266
287
|
await fs3.rm(this.store, { force: true });
|
|
267
288
|
return;
|
|
268
289
|
}
|
|
269
|
-
await fs3.mkdir(
|
|
290
|
+
await fs3.mkdir(path4.dirname(this.store), { recursive: true, mode: 448 });
|
|
270
291
|
const temp = `${this.store}.${process.pid}.tmp`;
|
|
271
292
|
await fs3.writeFile(temp, JSON.stringify(recordings, null, 2) + "\n", { mode: 384 });
|
|
272
293
|
await fs3.rename(temp, this.store);
|
|
273
294
|
}
|
|
274
295
|
/** The recorded original: `undefined` when nothing is recorded, `null` when the file did not exist. */
|
|
275
296
|
async original(file) {
|
|
276
|
-
const recording = (await this.load())[
|
|
297
|
+
const recording = (await this.load())[path4.resolve(file)];
|
|
277
298
|
if (recording) return recording.existed ? Buffer.from(recording.bytes ?? "", "base64") : null;
|
|
278
299
|
const legacy = await readBytes(file + LEGACY_BACKUP);
|
|
279
300
|
return legacy ?? void 0;
|
|
@@ -285,12 +306,12 @@ var ManagedFiles = class {
|
|
|
285
306
|
* the override still never replaces a previously saved recording.
|
|
286
307
|
*/
|
|
287
308
|
async record(file, options) {
|
|
288
|
-
const key =
|
|
309
|
+
const key = path4.resolve(file);
|
|
289
310
|
const recordings = await this.load();
|
|
290
311
|
if (recordings[key]) return;
|
|
291
312
|
const legacy = await readBytes(file + LEGACY_BACKUP);
|
|
292
313
|
const current = options ? options.original : legacy ?? await readBytes(file);
|
|
293
|
-
recordings[key] = current === null ? { existed: false, createdDirs: await missingDirs(
|
|
314
|
+
recordings[key] = current === null ? { existed: false, createdDirs: await missingDirs(path4.dirname(key)) } : { existed: true, bytes: current.toString("base64"), createdDirs: [] };
|
|
294
315
|
await this.save(recordings);
|
|
295
316
|
if (legacy) await fs3.rm(file + LEGACY_BACKUP, { force: true });
|
|
296
317
|
}
|
|
@@ -302,7 +323,7 @@ var ManagedFiles = class {
|
|
|
302
323
|
for (const { current } of entries) await this.record(current.file);
|
|
303
324
|
for (const { current, text, mode } of entries) {
|
|
304
325
|
if (text === current.text) continue;
|
|
305
|
-
await fs3.mkdir(
|
|
326
|
+
await fs3.mkdir(path4.dirname(current.file), { recursive: true });
|
|
306
327
|
await fs3.writeFile(current.file, text, mode === void 0 ? void 0 : { mode });
|
|
307
328
|
}
|
|
308
329
|
}
|
|
@@ -314,7 +335,7 @@ var ManagedFiles = class {
|
|
|
314
335
|
* stripped content. The recording is then dropped.
|
|
315
336
|
*/
|
|
316
337
|
async restore(current, format, strip) {
|
|
317
|
-
const key =
|
|
338
|
+
const key = path4.resolve(current.file);
|
|
318
339
|
const recordings = await this.load();
|
|
319
340
|
const recording = recordings[key];
|
|
320
341
|
const original = await this.original(current.file);
|
|
@@ -357,7 +378,7 @@ async function readBytes(file) {
|
|
|
357
378
|
}
|
|
358
379
|
async function missingDirs(dir) {
|
|
359
380
|
const missing = [];
|
|
360
|
-
for (let at = dir; ; at =
|
|
381
|
+
for (let at = dir; ; at = path4.dirname(at)) {
|
|
361
382
|
try {
|
|
362
383
|
await fs3.stat(at);
|
|
363
384
|
return missing;
|
|
@@ -365,24 +386,24 @@ async function missingDirs(dir) {
|
|
|
365
386
|
if (error.code !== "ENOENT") throw error;
|
|
366
387
|
}
|
|
367
388
|
missing.push(at);
|
|
368
|
-
if (
|
|
389
|
+
if (path4.dirname(at) === at) return missing;
|
|
369
390
|
}
|
|
370
391
|
}
|
|
371
392
|
|
|
372
393
|
// src/install/cursor.ts
|
|
373
394
|
var CURSOR_HOOK_EVENTS = ["beforeSubmitPrompt", "postToolUse", "stop"];
|
|
374
395
|
var HOOK_SUFFIX = " hook deliver --harness cursor";
|
|
375
|
-
function cursorPaths({ platform, path:
|
|
376
|
-
const cursorDir =
|
|
396
|
+
function cursorPaths({ platform, path: path8, home, env }, packageName = "khala-cli") {
|
|
397
|
+
const cursorDir = path8.join(home, ".cursor");
|
|
377
398
|
const windows = platform === "win32";
|
|
378
|
-
const { prefix } = installedLauncher(platform,
|
|
379
|
-
const modules = windows ?
|
|
399
|
+
const { prefix } = installedLauncher(platform, path8, home, env);
|
|
400
|
+
const modules = windows ? path8.join(prefix, "node_modules") : path8.join(prefix, "lib", "node_modules");
|
|
380
401
|
return {
|
|
381
402
|
cursorDir,
|
|
382
403
|
prefix,
|
|
383
|
-
mcpFile:
|
|
384
|
-
hooksFile:
|
|
385
|
-
script:
|
|
404
|
+
mcpFile: path8.join(cursorDir, "mcp.json"),
|
|
405
|
+
hooksFile: path8.join(cursorDir, "hooks.json"),
|
|
406
|
+
script: path8.join(modules, ...packageName.split("/"), "dist", "khala.mjs")
|
|
386
407
|
};
|
|
387
408
|
}
|
|
388
409
|
function cursorHookCommand(platform, node, script) {
|
|
@@ -481,8 +502,8 @@ var MUSE_WAKE_REQUEST = "muse-monitor-wake.json";
|
|
|
481
502
|
var shellQuote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
482
503
|
function museCliPath(env = process.env) {
|
|
483
504
|
const home = env.HOME || env.USERPROFILE || os2.homedir();
|
|
484
|
-
const { prefix } = cursorPaths({ platform: process.platform, path:
|
|
485
|
-
return process.platform === "win32" ?
|
|
505
|
+
const { prefix } = cursorPaths({ platform: process.platform, path: path5, home, env });
|
|
506
|
+
return process.platform === "win32" ? path5.join(prefix, "khala.cmd") : path5.join(prefix, "bin", "khala");
|
|
486
507
|
}
|
|
487
508
|
function museWatchCommand(sessionId, bin = museCliPath(), platform = process.platform) {
|
|
488
509
|
const quote = platform === "win32" ? (value) => `'${value.replaceAll("'", "''")}'` : shellQuote;
|
|
@@ -517,7 +538,7 @@ function createMuseMonitorDriver() {
|
|
|
517
538
|
if (ctx.signal.aborted || (await readActivity(ctx.files)).state !== "idle" || !await monitorArmed(ctx.files)) return "skipped";
|
|
518
539
|
const epoch = (await readActivity(ctx.files)).updatedAt;
|
|
519
540
|
for (const dir of monitorStorageCandidates(ctx.files)) {
|
|
520
|
-
if ((await readJson(
|
|
541
|
+
if ((await readJson(path5.join(dir, "monitor-wake-observed.json")))?.epoch === epoch) return "skipped";
|
|
521
542
|
}
|
|
522
543
|
const owner = await monitorOwner(ctx.files);
|
|
523
544
|
if (!owner) return "skipped";
|
|
@@ -530,7 +551,7 @@ function createMuseMonitorDriver() {
|
|
|
530
551
|
if (error.code !== "ENOENT") throw error;
|
|
531
552
|
}
|
|
532
553
|
}
|
|
533
|
-
await writeJsonAtomic(
|
|
554
|
+
await writeJsonAtomic(path5.join(ctx.files.dir, MUSE_WAKE_REQUEST), {
|
|
534
555
|
owner: owner.nonce,
|
|
535
556
|
line,
|
|
536
557
|
at: ctx.now,
|
|
@@ -545,8 +566,8 @@ function museJournalPath(sessionId, env) {
|
|
|
545
566
|
const created = new Date(Number.parseInt(sessionId.replaceAll("-", "").slice(0, 12), 16));
|
|
546
567
|
const date = [String(created.getFullYear()), String(created.getMonth() + 1).padStart(2, "0"), String(created.getDate()).padStart(2, "0")];
|
|
547
568
|
const home = env.HOME || env.USERPROFILE || os2.homedir();
|
|
548
|
-
const data = env.XDG_DATA_HOME &&
|
|
549
|
-
return
|
|
569
|
+
const data = env.XDG_DATA_HOME && path5.isAbsolute(env.XDG_DATA_HOME) ? env.XDG_DATA_HOME : path5.join(home, ".local", "share");
|
|
570
|
+
return path5.join(data, "muse", "sessions", ...date, sessionId, "session.jsonl");
|
|
550
571
|
}
|
|
551
572
|
async function museStopWakeText(stdin, files, env) {
|
|
552
573
|
const input = JSON.parse(stdin);
|
|
@@ -554,7 +575,7 @@ async function museStopWakeText(stdin, files, env) {
|
|
|
554
575
|
return museWakeProof(files, input.session_id, env, input.turn_id);
|
|
555
576
|
}
|
|
556
577
|
async function museWakeProof(files, sessionId, env, turnId) {
|
|
557
|
-
const request = await readJson(
|
|
578
|
+
const request = await readJson(path5.join(files.dir, MUSE_WAKE_REQUEST));
|
|
558
579
|
if (!request) return void 0;
|
|
559
580
|
const journal = museJournalPath(sessionId, env);
|
|
560
581
|
if (!journal) return void 0;
|
|
@@ -594,7 +615,7 @@ init_define_KHALA_BUNDLE();
|
|
|
594
615
|
import * as fs6 from "node:fs/promises";
|
|
595
616
|
import net from "node:net";
|
|
596
617
|
import os3 from "node:os";
|
|
597
|
-
import
|
|
618
|
+
import path6 from "node:path";
|
|
598
619
|
import { randomBytes as randomBytes2, randomUUID as randomUUID2 } from "node:crypto";
|
|
599
620
|
|
|
600
621
|
// src/wake/qwen-transcript.ts
|
|
@@ -633,23 +654,23 @@ async function verifyQwenTranscript(dir, filePath, now) {
|
|
|
633
654
|
}
|
|
634
655
|
|
|
635
656
|
// src/wake/qwen-socket.ts
|
|
636
|
-
var qwenHome = (env) => env.QWEN_HOME ?
|
|
657
|
+
var qwenHome = (env) => env.QWEN_HOME ? path6.resolve(env.QWEN_HOME) : path6.join(env.HOME ?? os3.homedir(), ".qwen");
|
|
637
658
|
async function qwenInboundAllowed(env, workspace = env.PWD ?? process.cwd()) {
|
|
638
|
-
for (const file of [
|
|
659
|
+
for (const file of [path6.join(qwenHome(env), "settings.json"), path6.join(workspace, ".qwen", "settings.json")]) {
|
|
639
660
|
const config = await readJson(file);
|
|
640
661
|
if (["hold", "refuse"].includes(config?.agents?.crossSessionInbound ?? "") || config?.agents?.crossSessionMessaging === false) return false;
|
|
641
662
|
}
|
|
642
663
|
return true;
|
|
643
664
|
}
|
|
644
|
-
var qwenControllerFile = (env) =>
|
|
665
|
+
var qwenControllerFile = (env) => path6.join(stateRoot(env), "qwen", "controller.json");
|
|
645
666
|
async function qwenSession(env) {
|
|
646
667
|
const socket = env.QWEN_CODE_MESSAGING_SOCKET;
|
|
647
668
|
if (!socket) return void 0;
|
|
648
669
|
try {
|
|
649
|
-
const dir =
|
|
670
|
+
const dir = path6.join(qwenHome(env), "sessions");
|
|
650
671
|
for (const file of await fs6.readdir(dir)) {
|
|
651
672
|
if (!/^\d+\.json$/u.test(file)) continue;
|
|
652
|
-
const record = await readJson(
|
|
673
|
+
const record = await readJson(path6.join(dir, file));
|
|
653
674
|
if (record?.ipcPath === socket && typeof record.sessionId === "string" && SESSION_ID_PATTERN.test(record.sessionId)) return record.sessionId;
|
|
654
675
|
}
|
|
655
676
|
} catch {
|
|
@@ -686,8 +707,8 @@ function qwenFrames(target2, line, from, replyToken, msgId) {
|
|
|
686
707
|
}
|
|
687
708
|
async function sendQwenWake(target2, line, signal, options = {}) {
|
|
688
709
|
if (signal.aborted) return "failed";
|
|
689
|
-
const dir = await fs6.mkdtemp(
|
|
690
|
-
const from =
|
|
710
|
+
const dir = await fs6.mkdtemp(path6.join(options.runtimeDir ?? os3.tmpdir(), "khala-qw-"));
|
|
711
|
+
const from = path6.join(dir, "r.sock");
|
|
691
712
|
if (Buffer.byteLength(from) > 103) {
|
|
692
713
|
await fs6.rm(dir, { recursive: true, force: true });
|
|
693
714
|
return "failed";
|
|
@@ -767,14 +788,14 @@ async function sendQwenWake(target2, line, signal, options = {}) {
|
|
|
767
788
|
function createQwenSocketDriver(deps = {}) {
|
|
768
789
|
const resolve = deps.resolve ?? target;
|
|
769
790
|
const policy = async (env) => {
|
|
770
|
-
const config = await readJson(
|
|
791
|
+
const config = await readJson(path6.join(qwenHome(env), "settings.json"));
|
|
771
792
|
return config?.agents;
|
|
772
793
|
};
|
|
773
794
|
const reason = async (ctx) => {
|
|
774
795
|
const config = await policy(ctx.env);
|
|
775
796
|
if (config?.crossSessionInbound === "hold") return "qwen_held";
|
|
776
797
|
if ((deps.platform ?? process.platform) === "win32") return "windows";
|
|
777
|
-
const receipt = await readJson(
|
|
798
|
+
const receipt = await readJson(path6.join(ctx.files.dir, "qwen-receipt.json"));
|
|
778
799
|
if (receipt?.status === "held" && config?.crossSessionInbound !== "accept") return "qwen_held";
|
|
779
800
|
if (config?.crossSessionMessaging === false || config?.crossSessionInbound === "refuse") return "qwen_refused";
|
|
780
801
|
if (!deps.resolve && !ctx.env.QWEN_CODE_MESSAGING_SOCKET) return "qwen_session_missing";
|
|
@@ -788,15 +809,15 @@ function createQwenSocketDriver(deps = {}) {
|
|
|
788
809
|
deadlineMs: 3e4,
|
|
789
810
|
verification: "transcript",
|
|
790
811
|
async verify(ctx) {
|
|
791
|
-
const journal = await readJson(
|
|
792
|
-
const receipt = await readJson(
|
|
812
|
+
const journal = await readJson(path6.join(ctx.files.dir, "wake-journal.json"));
|
|
813
|
+
const receipt = await readJson(path6.join(ctx.files.dir, "qwen-receipt.json"));
|
|
793
814
|
if (!journal?.attempts?.some((attempt) => attempt.driver === "socket") && receipt?.status !== "held") return;
|
|
794
|
-
const transcript = await readJson(
|
|
815
|
+
const transcript = await readJson(path6.join(ctx.files.dir, "qwen-transcript.json"));
|
|
795
816
|
if (!transcript?.path) return;
|
|
796
817
|
try {
|
|
797
818
|
const text = await verifyQwenTranscript(ctx.files.dir, transcript.path, ctx.now);
|
|
798
819
|
if (receipt?.status === "held" && receipt.nonce && text?.includes(`(k-${receipt.nonce})`)) {
|
|
799
|
-
await writeJsonAtomic(
|
|
820
|
+
await writeJsonAtomic(path6.join(ctx.files.dir, "qwen-receipt.json"), { status: "delivered" });
|
|
800
821
|
}
|
|
801
822
|
} catch {
|
|
802
823
|
}
|
|
@@ -810,7 +831,7 @@ function createQwenSocketDriver(deps = {}) {
|
|
|
810
831
|
const status = await (deps.send ?? sendQwenWake)(destination, line, ctx.signal);
|
|
811
832
|
await ensureStateDir(ctx.files.dir);
|
|
812
833
|
const nonce = line.match(/\(k-([0-9a-f]{8})\)$/u)?.[1];
|
|
813
|
-
await writeJsonAtomic(
|
|
834
|
+
await writeJsonAtomic(path6.join(ctx.files.dir, "qwen-receipt.json"), { status, nonce });
|
|
814
835
|
if (nonce && status === "held") await cancelAttempt(ctx.files.dir, nonce);
|
|
815
836
|
else if (nonce && status !== "delivered") await failAttempt(ctx.files.dir, nonce, ctx.now);
|
|
816
837
|
}
|
|
@@ -821,11 +842,11 @@ function createQwenSocketDriver(deps = {}) {
|
|
|
821
842
|
var MARKER = "monitor.json";
|
|
822
843
|
var OBSERVATION = "monitor-cursor.json";
|
|
823
844
|
var NONCE_PATTERN = /^[a-f0-9-]{36}$/;
|
|
824
|
-
var leaseFile = (dir, nonce) =>
|
|
845
|
+
var leaseFile = (dir, nonce) => path7.join(dir, `monitor-${nonce}.json`);
|
|
825
846
|
async function monitorOwner(files) {
|
|
826
847
|
const owners = [];
|
|
827
848
|
for (const dir of monitorStorageCandidates(files)) {
|
|
828
|
-
const owner = await readJson(
|
|
849
|
+
const owner = await readJson(path7.join(dir, MARKER));
|
|
829
850
|
if (!owner || !Number.isSafeInteger(owner.pid) || owner.pid <= 0 || typeof owner.nonce !== "string" || !NONCE_PATTERN.test(owner.nonce)) continue;
|
|
830
851
|
const lease = await readJson(leaseFile(dir, owner.nonce));
|
|
831
852
|
if (lease?.nonce !== owner.nonce) continue;
|
|
@@ -944,7 +965,7 @@ async function watchSession(files, io) {
|
|
|
944
965
|
}
|
|
945
966
|
const mode = await readListeningMode(target2);
|
|
946
967
|
const entries = await readEntries(target2);
|
|
947
|
-
const observed = await readJson(
|
|
968
|
+
const observed = await readJson(path7.join(await observationDir(target2), OBSERVATION));
|
|
948
969
|
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
970
|
const baseline = initialDelivered.get(target2.dir).cursor;
|
|
950
971
|
const initialCount = baseline.deliveredCount === 0 || entries[baseline.deliveredCount - 1]?.eventId === baseline.lastDeliveredEventId ? baseline.deliveredCount : 0;
|
|
@@ -970,7 +991,7 @@ async function watchSession(files, io) {
|
|
|
970
991
|
}
|
|
971
992
|
if (position !== entries.length && !done && await ownsSession() && JSON.stringify(await readJson(target2.session)) === JSON.stringify(latestSession)) {
|
|
972
993
|
try {
|
|
973
|
-
await writeJsonAtomic(
|
|
994
|
+
await writeJsonAtomic(path7.join(await observationDir(target2), OBSERVATION), {
|
|
974
995
|
userId: session.userId,
|
|
975
996
|
roomId: session.roomId,
|
|
976
997
|
count: entries.length,
|
|
@@ -982,7 +1003,7 @@ async function watchSession(files, io) {
|
|
|
982
1003
|
}
|
|
983
1004
|
}
|
|
984
1005
|
if (io.harness === "muse" && !done && await ownsSession()) {
|
|
985
|
-
const request = await readJson(
|
|
1006
|
+
const request = await readJson(path7.join(files.dir, MUSE_WAKE_REQUEST));
|
|
986
1007
|
const now = (io.now ?? Date.now)();
|
|
987
1008
|
const wakeNonce = typeof request?.line === "string" ? /\(k-([a-f0-9]{8})\)$/.exec(request.line)?.[1] : void 0;
|
|
988
1009
|
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 +1021,7 @@ async function watchSession(files, io) {
|
|
|
1000
1021
|
const activity = await readActivity(files);
|
|
1001
1022
|
if (eligible && await ownsSession() && activity.state === "idle") {
|
|
1002
1023
|
const epoch = activity.updatedAt;
|
|
1003
|
-
const dedupFile =
|
|
1024
|
+
const dedupFile = path7.join(storage, "monitor-wake-observed.json");
|
|
1004
1025
|
const observed = await readJson(dedupFile);
|
|
1005
1026
|
if (observed?.epoch === epoch) return;
|
|
1006
1027
|
await writeJsonAtomic(dedupFile, { epoch, line: request.line });
|
|
@@ -1031,7 +1052,7 @@ async function watchSession(files, io) {
|
|
|
1031
1052
|
watcher.on("error", (error) => stop(3, errorReason(error)));
|
|
1032
1053
|
lastHeartbeat = Date.now();
|
|
1033
1054
|
await writeJsonAtomic(leaseFile(storage, nonce), { nonce, pid: process.pid, heartbeatAt: new Date(lastHeartbeat).toISOString() });
|
|
1034
|
-
await writeJsonAtomic(
|
|
1055
|
+
await writeJsonAtomic(path7.join(storage, MARKER), { nonce, pid: process.pid, startedAt: Date.now() });
|
|
1035
1056
|
published = true;
|
|
1036
1057
|
timer = setInterval(notify, 100);
|
|
1037
1058
|
io.signal.addEventListener("abort", abort, { once: true });
|
|
@@ -1064,8 +1085,8 @@ ${WATCH_USAGE}`);
|
|
|
1064
1085
|
return 1;
|
|
1065
1086
|
};
|
|
1066
1087
|
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-
|
|
1068
|
-
const { adapterFor } = await import("./chunk-
|
|
1088
|
+
const { resolveHarness, resolveSessionId } = await import("./chunk-SICAKRPY.mjs");
|
|
1089
|
+
const { adapterFor } = await import("./chunk-RGQPDR53.mjs");
|
|
1069
1090
|
const harness = resolveHarness(argv, process.env);
|
|
1070
1091
|
if (harness === "invalid" || !adapterFor(harness)?.codec) return invalid("invalid_harness");
|
|
1071
1092
|
const index = argv.indexOf("--session");
|
|
@@ -1093,7 +1114,11 @@ export {
|
|
|
1093
1114
|
readWakeSettings,
|
|
1094
1115
|
updateWakeSettings,
|
|
1095
1116
|
driverAllowed,
|
|
1117
|
+
readModeState,
|
|
1118
|
+
delegateChannel,
|
|
1119
|
+
isDelegated,
|
|
1096
1120
|
readListeningMode,
|
|
1121
|
+
applyArchived,
|
|
1097
1122
|
applyListeningMode,
|
|
1098
1123
|
CURSOR_WORKSPACE_ENV,
|
|
1099
1124
|
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-
|
|
4
|
+
} from "./chunk-KI2MRAEE.mjs";
|
|
5
5
|
import {
|
|
6
6
|
StateError,
|
|
7
7
|
ensureStateDir,
|
|
8
8
|
writeJsonAtomic
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-R3TTOYPJ.mjs";
|
|
10
10
|
import {
|
|
11
11
|
__commonJS,
|
|
12
12
|
__export,
|
|
13
13
|
__toESM,
|
|
14
14
|
init_define_KHALA_BUNDLE
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-374APJUQ.mjs";
|
|
16
16
|
|
|
17
17
|
// ../../node_modules/.pnpm/immediate@3.3.0/node_modules/immediate/lib/nextTick.js
|
|
18
18
|
var require_nextTick = __commonJS({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
init_define_KHALA_BUNDLE
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-374APJUQ.mjs";
|
|
5
5
|
|
|
6
6
|
// src/events/member-rename.ts
|
|
7
7
|
init_define_KHALA_BUNDLE();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
init_define_KHALA_BUNDLE
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-374APJUQ.mjs";
|
|
5
5
|
|
|
6
6
|
// ../contracts/src/m1/harness.ts
|
|
7
7
|
init_define_KHALA_BUNDLE();
|
|
@@ -0,0 +1,19 @@
|
|
|
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-ZOUDN7LE.mjs";
|
|
7
|
+
import "./chunk-C53OOWTD.mjs";
|
|
8
|
+
import "./chunk-LPJQCFRQ.mjs";
|
|
9
|
+
import "./chunk-EGMBLNRJ.mjs";
|
|
10
|
+
import "./chunk-757A5TML.mjs";
|
|
11
|
+
import "./chunk-2MEWZ7PJ.mjs";
|
|
12
|
+
import "./chunk-R3TTOYPJ.mjs";
|
|
13
|
+
import "./chunk-WWFOB6XW.mjs";
|
|
14
|
+
import "./chunk-374APJUQ.mjs";
|
|
15
|
+
export {
|
|
16
|
+
ADAPTERS,
|
|
17
|
+
adapterFor,
|
|
18
|
+
createAdapterRegistry
|
|
19
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
resolveHarness,
|
|
4
|
+
resolveSession,
|
|
5
|
+
resolveSessionId
|
|
6
|
+
} from "./chunk-JDKPAIJX.mjs";
|
|
7
|
+
import "./chunk-ZOUDN7LE.mjs";
|
|
8
|
+
import "./chunk-C53OOWTD.mjs";
|
|
9
|
+
import "./chunk-LPJQCFRQ.mjs";
|
|
10
|
+
import "./chunk-EGMBLNRJ.mjs";
|
|
11
|
+
import "./chunk-757A5TML.mjs";
|
|
12
|
+
import "./chunk-2MEWZ7PJ.mjs";
|
|
13
|
+
import "./chunk-R3TTOYPJ.mjs";
|
|
14
|
+
import "./chunk-WWFOB6XW.mjs";
|
|
15
|
+
import "./chunk-374APJUQ.mjs";
|
|
16
|
+
export {
|
|
17
|
+
resolveHarness,
|
|
18
|
+
resolveSession,
|
|
19
|
+
resolveSessionId
|
|
20
|
+
};
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
listChannels
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-757A5TML.mjs";
|
|
5
5
|
import {
|
|
6
6
|
TERMINAL_SESSION_DETAILS,
|
|
7
7
|
cachedProcessReader,
|
|
8
8
|
readStateFile,
|
|
9
9
|
readStatus,
|
|
10
10
|
validAgentRejoinSecret
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-R3TTOYPJ.mjs";
|
|
12
12
|
import {
|
|
13
13
|
init_define_KHALA_BUNDLE
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-374APJUQ.mjs";
|
|
15
15
|
|
|
16
16
|
// src/session-start-wake.ts
|
|
17
17
|
init_define_KHALA_BUNDLE();
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
wakeDisableNotice
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XMNU4QC5.mjs";
|
|
5
5
|
import {
|
|
6
6
|
adapterFor,
|
|
7
7
|
createCopilotCodec,
|
|
8
8
|
recordHookSession
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ZOUDN7LE.mjs";
|
|
10
10
|
import {
|
|
11
11
|
capturePane
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-C53OOWTD.mjs";
|
|
13
13
|
import {
|
|
14
14
|
readListeningMode
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-LPJQCFRQ.mjs";
|
|
16
|
+
import "./chunk-EGMBLNRJ.mjs";
|
|
17
17
|
import {
|
|
18
18
|
advanceCursor,
|
|
19
19
|
clearUsageLimit,
|
|
@@ -24,21 +24,21 @@ import {
|
|
|
24
24
|
unread,
|
|
25
25
|
wakesAgent,
|
|
26
26
|
writeActivity
|
|
27
|
-
} from "./chunk-
|
|
28
|
-
import "./chunk-
|
|
27
|
+
} from "./chunk-757A5TML.mjs";
|
|
28
|
+
import "./chunk-2MEWZ7PJ.mjs";
|
|
29
29
|
import {
|
|
30
30
|
StateError,
|
|
31
31
|
TERMINAL_SESSION_DETAILS,
|
|
32
32
|
readJson,
|
|
33
33
|
readStatus,
|
|
34
34
|
sessionFiles
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-R3TTOYPJ.mjs";
|
|
36
36
|
import {
|
|
37
37
|
settleAttempts
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-WWFOB6XW.mjs";
|
|
39
39
|
import {
|
|
40
40
|
init_define_KHALA_BUNDLE
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-374APJUQ.mjs";
|
|
42
42
|
|
|
43
43
|
// hooks/deliver.ts
|
|
44
44
|
init_define_KHALA_BUNDLE();
|