@kitman-sh/cli 0.9.0 → 0.10.53

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 (37) hide show
  1. package/dist/chunk-11p4wf6n.js +3551 -0
  2. package/dist/chunk-1mc9vgcr.js +39 -0
  3. package/dist/chunk-30397r95.js +30 -0
  4. package/dist/chunk-3bj7sc3v.js +389 -0
  5. package/dist/chunk-6vns3ej0.js +23 -0
  6. package/dist/chunk-7thnf14y.js +936 -0
  7. package/dist/chunk-arvwar2c.js +141 -0
  8. package/dist/chunk-b6thzgc9.js +32 -0
  9. package/dist/{chunk-8bvf4fh4.js → chunk-ctasxxz5.js} +26 -11
  10. package/dist/{chunk-5gjpv3ax.js → chunk-dzh9e6n2.js} +824 -651
  11. package/dist/{chunk-snn0e1qb.js → chunk-eg8f5ncv.js} +7 -3
  12. package/dist/chunk-g5bs3f6z.js +173 -0
  13. package/dist/chunk-jafetf7z.js +109 -0
  14. package/dist/chunk-jagzz148.js +527 -0
  15. package/dist/{chunk-1d4316hp.js → chunk-jfvq7s24.js} +38 -25
  16. package/dist/chunk-mbctzx7e.js +11436 -0
  17. package/dist/chunk-mej2bx5n.js +100 -0
  18. package/dist/chunk-p6spvbwq.js +6305 -0
  19. package/dist/chunk-pp1p3g6e.js +133 -0
  20. package/dist/chunk-r8p3nxcp.js +231 -0
  21. package/dist/chunk-txwt6r25.js +1731 -0
  22. package/dist/chunk-v290mf51.js +5242 -0
  23. package/dist/chunk-vjmz23rs.js +13 -0
  24. package/dist/chunk-vyv0p5eq.js +3183 -0
  25. package/dist/chunk-wh1pa2aa.js +15322 -0
  26. package/dist/chunk-x0b92bjb.js +222 -0
  27. package/dist/{chunk-8z5b6fpd.js → chunk-x9dhxfts.js} +216 -152
  28. package/dist/chunk-z821b2gp.js +164 -0
  29. package/dist/index.js +13 -5738
  30. package/dist/opencode-reader.main.ts +4 -0
  31. package/package.json +6 -5
  32. package/dist/chunk-3gxahgnq.js +0 -28495
  33. package/dist/chunk-ehzbtavj.js +0 -247
  34. package/dist/chunk-f5z8tgss.js +0 -1214
  35. package/dist/chunk-kdb1cbnx.js +0 -1273
  36. package/dist/chunk-ke1w0hx7.js +0 -5771
  37. package/dist/chunk-z6hc4ew9.js +0 -13
@@ -0,0 +1,222 @@
1
+ // @bun
2
+ import {
3
+ getOrUndefined,
4
+ liftThrowable,
5
+ TaggedError,
6
+ all3,
7
+ suspend3,
8
+ void_3,
9
+ gen,
10
+ fail7,
11
+ try_2,
12
+ mapError2,
13
+ timeoutOrElse,
14
+ scoped,
15
+ declare,
16
+ decodeEffect,
17
+ String4,
18
+ Boolean2,
19
+ Struct,
20
+ ArraySchema,
21
+ Literals,
22
+ NullOr,
23
+ Finite,
24
+ encodeUnknownJsonStringSync
25
+ } from "./chunk-mbctzx7e.js";
26
+ import {
27
+ isNumber,
28
+ isJsonObject,
29
+ isString
30
+ } from "./chunk-arvwar2c.js";
31
+ import {
32
+ make11,
33
+ runForEach,
34
+ compiled2
35
+ } from "./chunk-11p4wf6n.js";
36
+ import {
37
+ ChildProcessSpawner,
38
+ make7
39
+ } from "./chunk-3bj7sc3v.js";
40
+
41
+ // packages/agent-runtime/src/opencode-store.ts
42
+ import { lstatSync, readFileSync, realpathSync } from "fs";
43
+ import { DatabaseSync } from "node:sqlite";
44
+ import { fileURLToPath } from "url";
45
+ class OpencodeReadFailed extends TaggedError("OpencodeReadFailed") {
46
+ get message() {
47
+ return `OpenCode's session could not be read: ${this.reason}`;
48
+ }
49
+ }
50
+ var sliceBytes2 = 1024 * 1024;
51
+ var maxLineBytes2 = 8 * 1024 * 1024;
52
+ var linesPerTurn2 = 1024;
53
+ var decodedOption2 = liftThrowable((text) => JSON.parse(text));
54
+ var decoded2 = (text) => getOrUndefined(decodedOption2(text));
55
+ var Parsed = declare((_value) => true);
56
+ var OpencodeV2PartSchema = Struct({ ordinal: Finite, part: Parsed });
57
+ var OpencodeV2MessageSchema = Struct({
58
+ id: String4,
59
+ seq: Finite,
60
+ closed: Boolean2,
61
+ parts: NullOr(ArraySchema(OpencodeV2PartSchema))
62
+ });
63
+ var PartSchema = Struct({
64
+ id: String4,
65
+ position: Finite,
66
+ role: NullOr(String4),
67
+ part: Parsed
68
+ });
69
+ var maxRoleChars = 64;
70
+ var maxPartsPerMessage = 4096;
71
+ var bytesOf = (column) => `length(cast(${column} as blob))`;
72
+ var unlessLong = (column) => `case when ${bytesOf(column)} <= ${maxLineBytes2} then ${column} end`;
73
+ var decodedParts = (db, ids) => {
74
+ const statement = db.prepare(`select part.rowid as position, ${unlessLong("message.data")} as message, ${unlessLong("part.data")} as part from part join message on message.id = part.message_id where part.id = ?`);
75
+ const parts = [];
76
+ let bytes = 0;
77
+ let reached = 0;
78
+ while (reached < ids.length && bytes < sliceBytes2) {
79
+ const id = ids[reached++];
80
+ const row = id === undefined ? undefined : statement.get(id);
81
+ if (id !== undefined && isNumber(row?.position)) {
82
+ const message = isString(row.message) ? decoded2(row.message) : undefined;
83
+ const part = isString(row.part) ? decoded2(row.part) : undefined;
84
+ bytes += isString(row.part) ? row.part.length : 0;
85
+ const role = isJsonObject(message) ? message.role : undefined;
86
+ const shortRole = isString(role) && role.length <= maxRoleChars ? role : null;
87
+ parts.push({ id, position: row.position, role: shortRole, part: part ?? null });
88
+ }
89
+ }
90
+ return { parts, rest: ids.slice(reached) };
91
+ };
92
+ var partsPast = "from part join message on message.id = part.message_id where part.session_id = ? and part.rowid > ?";
93
+ var opencodeV2Parts = (db, hasPartTable, id, data) => {
94
+ const rows = hasPartTable ? db.prepare("select ordinal, data from session_part where message_id = ? order by ordinal").all(id) : [];
95
+ if (rows.length > 0)
96
+ return rows.flatMap((row) => isNumber(row.ordinal) && isString(row.data) ? [{ ordinal: row.ordinal, part: decoded2(row.data) ?? null }] : []);
97
+ const content = isJsonObject(data) ? data.content : undefined;
98
+ return Array.isArray(content) ? content.map((part, ordinal) => ({ ordinal, part })) : [];
99
+ };
100
+ var opencodeSessionTables = [
101
+ { table: "session_v2", kind: "opencode_v2" },
102
+ { table: "session", kind: "opencode" }
103
+ ];
104
+ var reading = (output, read) => ({
105
+ output,
106
+ read
107
+ });
108
+ var readings = {
109
+ newestSession: reading(NullOr(Struct({ kind: Literals(["opencode", "opencode_v2"]), id: String4, createdAt: Finite })), (db, { worktree, startedAt }) => {
110
+ const present = new Set(db.prepare("select name from sqlite_master where type = 'table'").all().map((row) => row.name));
111
+ const newest = opencodeSessionTables.filter(({ table }) => present.has(table)).flatMap(({ table, kind }) => {
112
+ const row = db.prepare(`select id, time_created from ${table} where directory = ? and parent_id is null and time_created >= ? order by time_created desc limit 1`).get(worktree, startedAt);
113
+ return isString(row?.id) && isNumber(row.time_created) ? [{ kind, id: row.id, createdAt: row.time_created }] : [];
114
+ });
115
+ return newest.reduce((best, session) => best === null || session.createdAt > best.createdAt ? session : best, null);
116
+ }),
117
+ parts: reading(Struct({ parts: ArraySchema(PartSchema), rest: ArraySchema(String4) }), (db, { ids }) => decodedParts(db, ids)),
118
+ partsPast: reading(ArraySchema(PartSchema), (db, { position }, sessionId) => {
119
+ const rows = db.prepare(`select part.id as id ${partsPast} order by part.rowid limit ?`).all(sessionId, position, linesPerTurn2);
120
+ return decodedParts(db, rows.flatMap((row) => isString(row.id) ? [row.id] : [])).parts;
121
+ }),
122
+ partsPastCount: reading(Finite, (db, { position }, sessionId) => Number(db.prepare(`select count(*) as parts ${partsPast}`).get(sessionId, position)?.parts)),
123
+ messagesPast: reading(ArraySchema(OpencodeV2MessageSchema), (db, { seq }, sessionId) => {
124
+ const hasPartTable = db.prepare("select 1 from sqlite_master where name = 'session_part'").get() !== undefined;
125
+ const size = hasPartTable ? `${bytesOf("data")} + coalesce((select sum(${bytesOf("data")}) from session_part where message_id = session_message.id), 0)` : bytesOf("data");
126
+ const found = db.prepare(`select id, seq, ${size} as size, json_extract(data, '$.time.completed') is not null as completed from session_message where session_id = ? and type = 'assistant' and seq > ? order by seq limit ?`).all(sessionId, seq, linesPerTurn2 + 1);
127
+ const read = db.prepare("select data from session_message where id = ?");
128
+ const messages = [];
129
+ let bytes = 0;
130
+ for (const [index, row] of found.slice(0, linesPerTurn2).entries()) {
131
+ if (bytes >= sliceBytes2)
132
+ break;
133
+ if (!isString(row.id) || !isNumber(row.seq) || !isNumber(row.size))
134
+ continue;
135
+ const closed = row.completed === 1 || index < found.length - 1;
136
+ if (row.size > maxLineBytes2) {
137
+ messages.push({ id: row.id, seq: row.seq, closed, parts: null });
138
+ continue;
139
+ }
140
+ const data = read.get(row.id)?.data;
141
+ bytes += row.size;
142
+ const parts = opencodeV2Parts(db, hasPartTable, row.id, isString(data) ? decoded2(data) : undefined);
143
+ messages.push({ id: row.id, seq: row.seq, closed, parts: parts.length > maxPartsPerMessage ? null : parts });
144
+ }
145
+ return messages;
146
+ }),
147
+ extent: reading(Finite, (db, _input, sessionId) => Number(db.prepare(`with recursive sessions(id) as (select ? union select session_v2.id from session_v2 join sessions on session_v2.parent_id = sessions.id)
148
+ select coalesce(max(time_updated), 0) as extent from session_message where session_id in sessions`).get(sessionId)?.extent))
149
+ };
150
+ var maxReaderHeapBytes = 256 * 1024 * 1024;
151
+ var inDatabase = (database, hostile, use) => {
152
+ const db = new DatabaseSync(database, { readOnly: true });
153
+ try {
154
+ if (hostile)
155
+ db.exec(`pragma trusted_schema = off; pragma query_only = on; pragma hard_heap_limit = ${maxReaderHeapBytes};`);
156
+ return use(db);
157
+ } finally {
158
+ db.close();
159
+ }
160
+ };
161
+ var maxAnswerBytes = 16 * 1024 * 1024;
162
+ var answerTimeout = "3 seconds";
163
+ var opencodeReaderCommand = () => compiled2 ? [process.execPath, "opencode-read"] : [process.execPath, fileURLToPath(import.meta.resolve("./opencode-reader.main.ts"))];
164
+ var isolatedRead = (store, name, input) => gen(function* () {
165
+ const spawner = yield* ChildProcessSpawner;
166
+ const [command, ...args] = opencodeReaderCommand();
167
+ const handle = yield* spawner.spawn(make7(command, args, {
168
+ stdin: make11(new TextEncoder().encode(encodeUnknownJsonStringSync({ store, name, input }))),
169
+ stderr: "ignore",
170
+ extendEnv: false,
171
+ env: {},
172
+ killSignal: "SIGKILL"
173
+ }));
174
+ const chunks = [];
175
+ let bytes = 0;
176
+ const [, exitCode] = yield* all3([
177
+ runForEach(handle.stdout, (chunk) => suspend3(() => {
178
+ bytes += chunk.length;
179
+ chunks.push(chunk);
180
+ return bytes > maxAnswerBytes ? fail7(new OpencodeReadFailed({ reason: "the reader said too much" })) : void_3;
181
+ })),
182
+ handle.exitCode
183
+ ], { concurrency: 2 });
184
+ if (exitCode !== 0)
185
+ return yield* new OpencodeReadFailed({ reason: `the reader exited with ${exitCode}` });
186
+ const answer = decoded2(new TextDecoder().decode(Buffer.concat(chunks)));
187
+ return yield* decodeEffect(readings[name].output)(answer);
188
+ }).pipe(scoped, mapError2((error) => error instanceof OpencodeReadFailed ? error : new OpencodeReadFailed({ reason: error.message })), timeoutOrElse({
189
+ duration: answerTimeout,
190
+ orElse: () => fail7(new OpencodeReadFailed({ reason: "the reader did not answer in time" }))
191
+ }));
192
+ var readOpencode2 = (store, name, input) => store.confinedTo === undefined ? try_2({
193
+ try: () => answerFrom(store, name, input, false),
194
+ catch: (error) => new OpencodeReadFailed({ reason: String(error) })
195
+ }) : isolatedRead(store, name, input);
196
+ var answerFrom = (store, name, input, hostile) => inDatabase(store.database, hostile, (db) => readings[name].read(db, input, store.sessionId ?? ""));
197
+ var assertConfined = (database, root) => {
198
+ for (const file of [database, `${database}-wal`, `${database}-shm`, `${database}-journal`]) {
199
+ const stat = lstatSync(file, { throwIfNoEntry: false });
200
+ if (file === database && stat === undefined)
201
+ throw new Error("No database");
202
+ if (stat !== undefined && (!stat.isFile() || stat.nlink !== 1))
203
+ throw new Error("Not a plain file");
204
+ }
205
+ if (!realpathSync(database).startsWith(`${realpathSync(root)}/`))
206
+ throw new Error("Outside its directory");
207
+ };
208
+ var runOpencodeReader2 = () => {
209
+ const request = decoded2(readFileSync(0, "utf8"));
210
+ if (!isJsonObject(request) || !isJsonObject(request.store))
211
+ throw new Error("No request");
212
+ const { database, sessionId, confinedTo } = request.store;
213
+ if (!isString(database) || !isString(confinedTo))
214
+ throw new Error("No confined database");
215
+ assertConfined(database, confinedTo);
216
+ const store = { database, confinedTo, ...isString(sessionId) ? { sessionId } : undefined };
217
+ const reading = request.name;
218
+ const input = request.input;
219
+ process.stdout.write(encodeUnknownJsonStringSync(answerFrom(store, reading, input, true)));
220
+ };
221
+
222
+ export { sliceBytes2, maxLineBytes2, linesPerTurn2, decodedOption2, decoded2, readOpencode2, runOpencodeReader2 };