khala-cli 0.4.2 → 0.4.5

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 (35) hide show
  1. package/dist/{chunk-T6RZE5IQ.mjs → chunk-6LC66VHK.mjs} +10 -7
  2. package/dist/chunk-7G2G4E4U.mjs +236 -0
  3. package/dist/chunk-AUJEUKVM.mjs +121 -0
  4. package/dist/{chunk-NUS6M27N.mjs → chunk-EW22K3JO.mjs} +445 -199
  5. package/dist/chunk-EXHCVFVH.mjs +26 -0
  6. package/dist/{chunk-CDHHFC6C.mjs → chunk-H46OG22B.mjs} +22 -6
  7. package/dist/{chunk-YP45XTOH.mjs → chunk-HB3UGIZG.mjs} +5 -5
  8. package/dist/chunk-IR3VN2ID.mjs +52 -0
  9. package/dist/{chunk-B5BFL7OD.mjs → chunk-KCJFSVDN.mjs} +55 -4
  10. package/dist/{chunk-K4MDSFHU.mjs → chunk-MBLP7LQJ.mjs} +103 -38
  11. package/dist/{chunk-RW3DXWNC.mjs → chunk-OLZ62X7S.mjs} +1 -1
  12. package/dist/chunk-P5CP32X2.mjs +170 -0
  13. package/dist/{chunk-A3LJU4JA.mjs → chunk-PXKGKVGW.mjs} +1 -1
  14. package/dist/{chunk-7MQAMABY.mjs → chunk-RSDOTTZQ.mjs} +4 -4
  15. package/dist/chunk-SN3STAO2.mjs +190 -0
  16. package/dist/{chunk-MHZWR4A3.mjs → chunk-SQXDATEC.mjs} +1 -1
  17. package/dist/chunk-T7YRVE43.mjs +238 -0
  18. package/dist/{chunk-BZ53MZEE.mjs → chunk-TZKEQIHP.mjs} +8 -4
  19. package/dist/{chunk-46PTKRZC.mjs → chunk-V4Y26O4R.mjs} +171 -113
  20. package/dist/chunk-V7M27QLT.mjs +21 -0
  21. package/dist/{chunk-2OO725IZ.mjs → chunk-Y2DRTRBJ.mjs} +3 -3
  22. package/dist/{chunk-JRZZVTQ4.mjs → chunk-Y4WVILEJ.mjs} +94 -10
  23. package/dist/khala.mjs +12 -10
  24. package/dist/web/assets/apple-touch-icon-Du9V6qit.png +0 -0
  25. package/dist/web/assets/favicon-16x16-D5waNSZD.png +0 -0
  26. package/dist/web/assets/favicon-32x32-B9Ubw1Dx.png +0 -0
  27. package/dist/web/assets/favicon-zCD0pKtT.ico +0 -0
  28. package/dist/web/assets/local-C1vz22ps.js +9 -0
  29. package/dist/web/assets/local-DdjwMERJ.css +1 -0
  30. package/dist/web/index.html +7 -2
  31. package/package.json +1 -1
  32. package/dist/chunk-N6LMHR7P.mjs +0 -455
  33. package/dist/chunk-U5ZMOPUK.mjs +0 -149
  34. package/dist/web/assets/local-CVA9799w.js +0 -9
  35. package/dist/web/assets/local-DHYvcQG0.css +0 -1
@@ -1,149 +0,0 @@
1
- import { createRequire as __khalaCreateRequire } from 'node:module'; const require = __khalaCreateRequire(import.meta.url);
2
- import {
3
- StateError,
4
- filesForDir,
5
- readJson,
6
- writeJsonAtomic
7
- } from "./chunk-B5BFL7OD.mjs";
8
- import {
9
- DEFAULT_LISTENING_MODE,
10
- decodeChannelEvent,
11
- decodeListeningMode,
12
- formatChannelEventLine
13
- } from "./chunk-N6LMHR7P.mjs";
14
-
15
- // src/inbox.ts
16
- import * as fs from "node:fs/promises";
17
- async function readEntries(files) {
18
- let content;
19
- try {
20
- content = await fs.readFile(files.inbox, "utf8");
21
- } catch (error) {
22
- if (error.code === "ENOENT") return [];
23
- throw new StateError("storage_failed");
24
- }
25
- const entries = [];
26
- for (const line of content.split("\n").slice(0, -1)) {
27
- try {
28
- const entry = JSON.parse(line);
29
- if (entry && ["eventId", "roomId", "ts", "sender", "senderLabel", "body"].every((key) => typeof entry[key] === "string") && ["human", "agent", "unknown"].includes(entry.senderKind) && ["message", "event"].includes(entry.kind)) entries.push(entry);
30
- } catch {
31
- }
32
- }
33
- return entries;
34
- }
35
- async function appendEntries(files, entries) {
36
- const seen = new Set((await readEntries(files)).map((entry) => entry.eventId));
37
- const fresh = entries.filter((entry) => {
38
- if (seen.has(entry.eventId)) return false;
39
- seen.add(entry.eventId);
40
- return true;
41
- });
42
- if (fresh.length) {
43
- try {
44
- await fs.appendFile(files.inbox, fresh.map((entry) => JSON.stringify(entry) + "\n").join(""), { mode: 384, flag: "a" });
45
- } catch {
46
- throw new StateError("storage_failed");
47
- }
48
- }
49
- return fresh;
50
- }
51
- async function readCursor(files) {
52
- const cursor = await readJson(files.cursor);
53
- return cursor && (cursor.lastDeliveredEventId === null || typeof cursor.lastDeliveredEventId === "string") && Number.isSafeInteger(cursor.deliveredCount) && cursor.deliveredCount >= 0 ? cursor : { lastDeliveredEventId: null, deliveredCount: 0 };
54
- }
55
- async function unread(files) {
56
- const cursor = await readCursor(files);
57
- const entries = await readEntries(files);
58
- return { entries: entries.slice(cursor.deliveredCount), cursor };
59
- }
60
- async function unreadCounts(files) {
61
- const { entries } = await unread(files);
62
- return { total: entries.length, messages: entries.filter((entry) => entry.kind === "message").length };
63
- }
64
- async function advanceCursor(files, expected, delivered) {
65
- const current = await readCursor(files);
66
- if (current.deliveredCount !== expected.deliveredCount || current.lastDeliveredEventId !== expected.lastDeliveredEventId) return "conflict";
67
- if (!delivered.length) return expected;
68
- const entries = await readEntries(files);
69
- const slice = entries.slice(expected.deliveredCount, expected.deliveredCount + delivered.length);
70
- if (slice.length !== delivered.length || slice.some((entry, index) => entry.eventId !== delivered[index]?.eventId)) return "conflict";
71
- const next = { lastDeliveredEventId: delivered[delivered.length - 1].eventId, deliveredCount: expected.deliveredCount + delivered.length };
72
- await writeJsonAtomic(files.cursor, next);
73
- return next;
74
- }
75
- async function appendInbox(dir, entry) {
76
- return (await appendEntries(filesForDir(dir), [entry])).length === 1;
77
- }
78
- function unreadCount(dir) {
79
- return unreadCounts(filesForDir(dir));
80
- }
81
-
82
- // src/activity.ts
83
- import path from "node:path";
84
- async function readActivity(files) {
85
- const activity = await readJson(path.join(files.dir, "activity.json"));
86
- return activity && ["idle", "busy"].includes(activity.state) && typeof activity.updatedAt === "string" && Number.isFinite(Date.parse(activity.updatedAt)) ? activity : { state: "busy", updatedAt: (/* @__PURE__ */ new Date(0)).toISOString() };
87
- }
88
- async function writeActivity(files, state, now = () => /* @__PURE__ */ new Date()) {
89
- const activity = { state, updatedAt: now().toISOString() };
90
- await writeJsonAtomic(path.join(files.dir, "activity.json"), activity);
91
- return activity;
92
- }
93
-
94
- // src/mode.ts
95
- async function readListeningMode(files) {
96
- const content = await readJson(files.mode);
97
- const decoded = decodeListeningMode(typeof content === "object" && content !== null ? content.mode : void 0);
98
- return decoded.ok ? decoded.value : DEFAULT_LISTENING_MODE;
99
- }
100
- async function applyListeningMode(files, next, meta, now = () => /* @__PURE__ */ new Date()) {
101
- const previous = await readListeningMode(files);
102
- if (previous === "async" && next !== "async") {
103
- for (let attempt = 0; attempt < 2; attempt++) {
104
- const { cursor, entries } = await unread(files);
105
- if (await advanceCursor(files, cursor, entries) !== "conflict") break;
106
- if (attempt === 1) throw new StateError("storage_failed");
107
- }
108
- }
109
- await writeJsonAtomic(files.mode, { mode: next, ...meta, updatedAt: now().toISOString() });
110
- return { previous, next };
111
- }
112
-
113
- // src/events/receive.ts
114
- function toEventInboxEntry(base, rawContent) {
115
- const decoded = decodeChannelEvent(rawContent);
116
- if (!decoded.ok) return null;
117
- const content = decoded.value;
118
- return {
119
- entry: { ...base, kind: "event", body: formatChannelEventLine(content) + (content.url ? " " + content.url : "") },
120
- ...content.key !== void 0 ? { key: content.key } : {}
121
- };
122
- }
123
- function createEventKeyFilter() {
124
- const seen = /* @__PURE__ */ new Set();
125
- return (key) => {
126
- if (key === void 0) return true;
127
- if (seen.has(key)) return false;
128
- seen.add(key);
129
- return true;
130
- };
131
- }
132
- function isWakeEntry(entry) {
133
- return entry.kind === "message";
134
- }
135
-
136
- export {
137
- readCursor,
138
- unread,
139
- advanceCursor,
140
- appendInbox,
141
- unreadCount,
142
- readActivity,
143
- writeActivity,
144
- readListeningMode,
145
- applyListeningMode,
146
- toEventInboxEntry,
147
- createEventKeyFilter,
148
- isWakeEntry
149
- };