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.
- package/README.md +4 -4
- package/dist/THIRD_PARTY_NOTICES.txt +781 -0
- package/dist/{chunk-APMWDF6B.mjs → chunk-3KDOTR54.mjs} +4 -2
- package/dist/{chunk-VUSV2ADL.mjs → chunk-3R6HFSLL.mjs} +147 -36
- package/dist/{chunk-2VCAW4GH.mjs → chunk-47XNLAJG.mjs} +5 -1
- package/dist/chunk-6BO3JSUP.mjs +33 -0
- package/dist/chunk-7R3EIDGR.mjs +58 -0
- package/dist/{chunk-5LIE5GUU.mjs → chunk-ANSR4IAW.mjs} +5 -1
- package/dist/chunk-BEO7WIIM.mjs +153 -0
- package/dist/chunk-BLCRVRIK.mjs +1000 -0
- package/dist/{chunk-54XFVSEC.mjs → chunk-BV45NK7K.mjs} +5 -1
- package/dist/{chunk-Z4JF2M5C.mjs → chunk-DJM23SIU.mjs} +8 -7
- package/dist/{chunk-2DHIAFEV.mjs → chunk-FO5GXCST.mjs} +24 -10
- package/dist/{chunk-CJTCU755.mjs → chunk-FZEH2IXZ.mjs} +95 -15
- package/dist/{chunk-RNDUFTBF.mjs → chunk-GSZADJMW.mjs} +233 -77
- package/dist/chunk-ITFD3JZS.mjs +1137 -0
- package/dist/chunk-K7V7X6WU.mjs +207 -0
- package/dist/chunk-KMLXOPBQ.mjs +20 -0
- package/dist/chunk-LBT47HLZ.mjs +19 -0
- package/dist/{chunk-IQJQ4RF5.mjs → chunk-NGSYOVQ4.mjs} +12 -1
- package/dist/chunk-NIX5F4LT.mjs +863 -0
- package/dist/chunk-NPSQNCOY.mjs +590 -0
- package/dist/chunk-P3YIN7G7.mjs +26 -0
- package/dist/chunk-PAJ4JJPV.mjs +9827 -0
- package/dist/{chunk-VAI7IUI4.mjs → chunk-PDZ5Z5ZE.mjs} +9 -6
- package/dist/chunk-QKWEZXR3.mjs +52 -0
- package/dist/chunk-SSO5RFOX.mjs +7 -0
- package/dist/{chunk-ZJ4W7P33.mjs → chunk-T7IL7V7Q.mjs} +11 -9
- package/dist/{chunk-VKQ3KUYO.mjs → chunk-TANCKTDK.mjs} +9 -4
- package/dist/{chunk-FV32AQTC.mjs → chunk-TEFOQXBK.mjs} +10 -6
- package/dist/{chunk-W6R4UJUQ.mjs → chunk-UK5GJO4Y.mjs} +15 -9
- package/dist/{chunk-BKLW2SPG.mjs → chunk-V4F3SYKW.mjs} +19 -10
- package/dist/{chunk-H3K4GA2P.mjs → chunk-WDOHRV3D.mjs} +31 -19
- package/dist/chunk-XBQDIKB5.mjs +18 -0
- package/dist/chunk-XUCWSYVS.mjs +148 -0
- package/dist/khala.mjs +20 -13
- package/dist/web/assets/local-CFzRHZpB.js +9 -0
- package/dist/web/assets/{local-OwDq47O4.css → local-ciypUFoK.css} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +5 -3
- package/dist/chunk-5BQTYU66.mjs +0 -886
- package/dist/chunk-5GLTKWJ5.mjs +0 -1
- package/dist/chunk-5PUQT3YS.mjs +0 -569
- package/dist/chunk-7HBRFY3Z.mjs +0 -8
- package/dist/chunk-CBPLCCRZ.mjs +0 -191
- package/dist/chunk-FH34B3I3.mjs +0 -235
- package/dist/chunk-NKX3SLS7.mjs +0 -227
- package/dist/web/assets/local-BQl2KrE1.js +0 -9
|
@@ -4,20 +4,22 @@ import {
|
|
|
4
4
|
checkName,
|
|
5
5
|
isDefaultAgentName,
|
|
6
6
|
restartHelper
|
|
7
|
-
} from "./chunk-
|
|
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-
|
|
16
|
+
} from "./chunk-NPSQNCOY.mjs";
|
|
14
17
|
import {
|
|
15
|
-
|
|
16
|
-
|
|
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
|
+
};
|
|
@@ -14,22 +14,24 @@ import {
|
|
|
14
14
|
decodeLocalSendResult,
|
|
15
15
|
ensureHelper,
|
|
16
16
|
localRoomPath
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import "./chunk-
|
|
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-
|
|
25
|
-
import "./chunk-
|
|
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-
|
|
29
|
-
import "./chunk-
|
|
30
|
-
import
|
|
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-
|
|
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
|
|
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
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
11
|
+
} from "./chunk-TANCKTDK.mjs";
|
|
9
12
|
import {
|
|
10
13
|
TERMINAL_SESSION_DETAILS,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import
|
|
15
|
-
|
|
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 =
|
|
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
|
|
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-
|
|
4
|
+
} from "./chunk-TEFOQXBK.mjs";
|
|
5
5
|
import {
|
|
6
6
|
adapterFor
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import
|
|
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-
|
|
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-
|
|
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-
|
|
42
|
+
} from "./chunk-BV45NK7K.mjs";
|
|
49
43
|
import {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
} from "./chunk-
|
|
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-
|
|
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
|
-
|
|
73
|
-
|
|
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
|
+
};
|