negotium 0.1.11 → 0.1.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 (165) hide show
  1. package/README.md +11 -2
  2. package/dist/canonical-mcp-bridge.js +2 -3
  3. package/dist/canonical-mcp-bridge.js.map +1 -1
  4. package/dist/{chunk-gz12qcf0.js → chunk-a9y2rwxf.js} +2 -2
  5. package/dist/{chunk-gz12qcf0.js.map → chunk-a9y2rwxf.js.map} +3 -3
  6. package/dist/{chunk-j0kjscb7.js → chunk-s2gez3wg.js} +20 -2
  7. package/dist/{chunk-j0kjscb7.js.map → chunk-s2gez3wg.js.map} +2 -2
  8. package/dist/cron.js +292 -256
  9. package/dist/cron.js.map +23 -22
  10. package/dist/hosted-agent.js +3012 -17
  11. package/dist/hosted-agent.js.map +30 -3
  12. package/dist/main.js +31323 -36
  13. package/dist/main.js.map +198 -3
  14. package/dist/prompts.js +12 -9
  15. package/dist/prompts.js.map +5 -5
  16. package/dist/registry.js +10 -6
  17. package/dist/registry.js.map +3 -3
  18. package/dist/rollout.js +1 -1
  19. package/dist/runtime/cron/store.ts +24 -1
  20. package/dist/runtime/src/application/submit-user-message.ts +3 -0
  21. package/dist/runtime/src/index.ts +7 -0
  22. package/dist/runtime/src/mcp/runtime-spec.ts +3 -0
  23. package/dist/runtime/src/mcp/session-comm/server.ts +1 -1
  24. package/dist/runtime/src/platform/config.ts +2 -2
  25. package/dist/runtime/src/platform/mcp-config.ts +13 -0
  26. package/dist/runtime/src/prompts/builders.ts +20 -6
  27. package/dist/runtime/src/query/active-rooms.ts +2 -0
  28. package/dist/runtime/src/runtime/delivery-ack.ts +112 -0
  29. package/dist/runtime/src/runtime/errors.ts +12 -12
  30. package/dist/runtime/src/runtime/turn-runner.ts +12 -0
  31. package/dist/runtime/src/storage/api-messages.ts +7 -5
  32. package/dist/runtime/src/storage/api-topics.ts +5 -2
  33. package/dist/runtime/src/storage/forum-db.ts +4 -1
  34. package/dist/runtime/src/storage/runtime-turn-requests.ts +1 -0
  35. package/dist/runtime/src/storage/session-asks.ts +13 -5
  36. package/dist/runtime/src/storage/storage-contract.ts +54 -0
  37. package/dist/runtime/src/storage/storage-host.ts +89 -36
  38. package/dist/runtime/src/storage/storage-public-host.ts +16 -0
  39. package/dist/runtime/src/storage/storage-public.ts +21 -5
  40. package/dist/runtime/src/storage/token-stats.ts +1 -1
  41. package/dist/runtime/src/types/api.ts +2 -0
  42. package/dist/runtime/src/types.ts +2 -0
  43. package/dist/runtime/src/version.ts +1 -1
  44. package/dist/runtime-helpers.js +29 -18
  45. package/dist/runtime-helpers.js.map +8 -7
  46. package/dist/storage.js +260 -202
  47. package/dist/storage.js.map +11 -9
  48. package/dist/types/packages/core/src/mcp/runtime-spec.d.ts +2 -0
  49. package/dist/types/packages/core/src/platform/mcp-config.d.ts +4 -0
  50. package/dist/types/packages/core/src/prompts/builders.d.ts +2 -0
  51. package/dist/types/packages/core/src/storage/api-messages.d.ts +6 -6
  52. package/dist/types/packages/core/src/storage/api-topics.d.ts +20 -2
  53. package/dist/types/packages/core/src/storage/forum-db.d.ts +2 -1
  54. package/dist/types/packages/core/src/storage/session-asks.d.ts +3 -2
  55. package/dist/types/packages/core/src/storage/storage-contract.d.ts +46 -0
  56. package/dist/types/packages/core/src/storage/storage-host.d.ts +12 -19
  57. package/dist/types/packages/core/src/storage/storage-public-host.d.ts +7 -0
  58. package/dist/types/packages/core/src/storage/storage-public.d.ts +4 -2
  59. package/dist/types/packages/core/src/types/api.d.ts +2 -0
  60. package/dist/types/packages/core/src/types.d.ts +2 -0
  61. package/dist/types/packages/core/src/version.d.ts +1 -1
  62. package/dist/types/packages/module-cron/src/store.d.ts +22 -2
  63. package/dist/vault.js +2 -2
  64. package/dist/vault.js.map +3 -3
  65. package/package.json +1 -1
  66. package/dist/chunk-01xcc856.js +0 -149
  67. package/dist/chunk-01xcc856.js.map +0 -10
  68. package/dist/chunk-1a6kv9vt.js +0 -118
  69. package/dist/chunk-1a6kv9vt.js.map +0 -10
  70. package/dist/chunk-1b62d730.js +0 -117
  71. package/dist/chunk-1b62d730.js.map +0 -10
  72. package/dist/chunk-1k7t7bnx.js +0 -97
  73. package/dist/chunk-1k7t7bnx.js.map +0 -10
  74. package/dist/chunk-28apmz4r.js +0 -431
  75. package/dist/chunk-28apmz4r.js.map +0 -11
  76. package/dist/chunk-2fvydfkx.js +0 -141
  77. package/dist/chunk-2fvydfkx.js.map +0 -10
  78. package/dist/chunk-41ygvg5k.js +0 -2387
  79. package/dist/chunk-41ygvg5k.js.map +0 -26
  80. package/dist/chunk-4q966ttx.js +0 -371
  81. package/dist/chunk-4q966ttx.js.map +0 -11
  82. package/dist/chunk-51rcsavw.js +0 -1712
  83. package/dist/chunk-51rcsavw.js.map +0 -18
  84. package/dist/chunk-59d0shyj.js +0 -103
  85. package/dist/chunk-59d0shyj.js.map +0 -10
  86. package/dist/chunk-5fzgvn79.js +0 -3536
  87. package/dist/chunk-5fzgvn79.js.map +0 -20
  88. package/dist/chunk-61px0717.js +0 -153
  89. package/dist/chunk-61px0717.js.map +0 -11
  90. package/dist/chunk-66y0hr8c.js +0 -2136
  91. package/dist/chunk-66y0hr8c.js.map +0 -29
  92. package/dist/chunk-69k45zg8.js +0 -250
  93. package/dist/chunk-69k45zg8.js.map +0 -11
  94. package/dist/chunk-6ah5farg.js +0 -130
  95. package/dist/chunk-6ah5farg.js.map +0 -10
  96. package/dist/chunk-6d4fmea5.js +0 -117
  97. package/dist/chunk-6d4fmea5.js.map +0 -12
  98. package/dist/chunk-8cahx7xc.js +0 -46
  99. package/dist/chunk-8cahx7xc.js.map +0 -10
  100. package/dist/chunk-8f20fk4n.js +0 -252
  101. package/dist/chunk-8f20fk4n.js.map +0 -10
  102. package/dist/chunk-91ckrvk8.js +0 -318
  103. package/dist/chunk-91ckrvk8.js.map +0 -10
  104. package/dist/chunk-93krf6ng.js +0 -3069
  105. package/dist/chunk-93krf6ng.js.map +0 -32
  106. package/dist/chunk-9qx1t77a.js +0 -214
  107. package/dist/chunk-9qx1t77a.js.map +0 -10
  108. package/dist/chunk-beqhdr9w.js +0 -589
  109. package/dist/chunk-beqhdr9w.js.map +0 -11
  110. package/dist/chunk-bftftsgq.js +0 -1637
  111. package/dist/chunk-bftftsgq.js.map +0 -15
  112. package/dist/chunk-c500xe9z.js +0 -33
  113. package/dist/chunk-c500xe9z.js.map +0 -10
  114. package/dist/chunk-cjsnkvq2.js +0 -23
  115. package/dist/chunk-cjsnkvq2.js.map +0 -10
  116. package/dist/chunk-cxa7yghg.js +0 -577
  117. package/dist/chunk-cxa7yghg.js.map +0 -14
  118. package/dist/chunk-edb07sjp.js +0 -567
  119. package/dist/chunk-edb07sjp.js.map +0 -14
  120. package/dist/chunk-f361dwba.js +0 -589
  121. package/dist/chunk-f361dwba.js.map +0 -11
  122. package/dist/chunk-f5xgprg1.js +0 -59
  123. package/dist/chunk-f5xgprg1.js.map +0 -10
  124. package/dist/chunk-ffefbd3r.js +0 -17
  125. package/dist/chunk-ffefbd3r.js.map +0 -10
  126. package/dist/chunk-fswhzdf5.js +0 -64
  127. package/dist/chunk-fswhzdf5.js.map +0 -10
  128. package/dist/chunk-g144wdrs.js +0 -2907
  129. package/dist/chunk-g144wdrs.js.map +0 -24
  130. package/dist/chunk-h980hb2n.js +0 -512
  131. package/dist/chunk-h980hb2n.js.map +0 -13
  132. package/dist/chunk-h9vbhhgr.js +0 -1337
  133. package/dist/chunk-h9vbhhgr.js.map +0 -16
  134. package/dist/chunk-hwy3n31w.js +0 -21
  135. package/dist/chunk-hwy3n31w.js.map +0 -9
  136. package/dist/chunk-jtrk0khr.js +0 -108
  137. package/dist/chunk-jtrk0khr.js.map +0 -10
  138. package/dist/chunk-jzz91jwh.js +0 -70
  139. package/dist/chunk-jzz91jwh.js.map +0 -10
  140. package/dist/chunk-m9e3tbr8.js +0 -708
  141. package/dist/chunk-m9e3tbr8.js.map +0 -14
  142. package/dist/chunk-mh5mexsf.js +0 -147
  143. package/dist/chunk-mh5mexsf.js.map +0 -11
  144. package/dist/chunk-npd8n03v.js +0 -2152
  145. package/dist/chunk-npd8n03v.js.map +0 -15
  146. package/dist/chunk-pg1azh6n.js +0 -2
  147. package/dist/chunk-pg1azh6n.js.map +0 -9
  148. package/dist/chunk-qwy57177.js +0 -237
  149. package/dist/chunk-qwy57177.js.map +0 -11
  150. package/dist/chunk-r31q21h5.js +0 -53
  151. package/dist/chunk-r31q21h5.js.map +0 -10
  152. package/dist/chunk-rbvctv1n.js +0 -366
  153. package/dist/chunk-rbvctv1n.js.map +0 -10
  154. package/dist/chunk-sa874j5c.js +0 -9
  155. package/dist/chunk-sa874j5c.js.map +0 -10
  156. package/dist/chunk-sctcs5zb.js +0 -281
  157. package/dist/chunk-sctcs5zb.js.map +0 -10
  158. package/dist/chunk-tsstrcfc.js +0 -122
  159. package/dist/chunk-tsstrcfc.js.map +0 -10
  160. package/dist/chunk-wk2qf31s.js +0 -58
  161. package/dist/chunk-wk2qf31s.js.map +0 -10
  162. package/dist/chunk-wx7ag4dd.js +0 -2936
  163. package/dist/chunk-wx7ag4dd.js.map +0 -20
  164. package/dist/chunk-znx1fpfd.js +0 -61
  165. package/dist/chunk-znx1fpfd.js.map +0 -10
@@ -1,366 +0,0 @@
1
- // @bun
2
- import {
3
- resolveStorageSessionAsksDir
4
- } from "./chunk-1a6kv9vt.js";
5
- import"./chunk-f5xgprg1.js";
6
- import"./chunk-hwy3n31w.js";
7
-
8
- // ../../packages/core/src/storage/session-asks.ts
9
- import { createHash } from "crypto";
10
- import {
11
- closeSync,
12
- mkdirSync,
13
- openSync,
14
- readdirSync,
15
- readFileSync,
16
- statSync,
17
- unlinkSync,
18
- writeFileSync
19
- } from "fs";
20
- import { dirname, join } from "path";
21
- var PENDING_ASK_TTL_MS = 15 * 60 * 1000;
22
- function pendingAskDir(userId) {
23
- const rawUserId = String(userId);
24
- const safeUserId = /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) ? rawUserId : `sha256-${createHash("sha256").update(rawUserId).digest("hex")}`;
25
- return join(resolveStorageSessionAsksDir(), safeUserId);
26
- }
27
- var ASK_FILENAME_PREFIX = "v3-";
28
- var V2_ASK_FILENAME_PREFIX = "v2-";
29
- function encodeAskKey(key) {
30
- return JSON.stringify([key.from, key.to]);
31
- }
32
- function pendingAskPath(key) {
33
- const digest = createHash("sha256").update(encodeAskKey(key)).digest("hex");
34
- return join(pendingAskDir(key.userId), `${ASK_FILENAME_PREFIX}${digest}.pending`);
35
- }
36
- function v2PendingAskPath(key) {
37
- const encoded = Buffer.from(encodeAskKey(key), "utf8").toString("base64url");
38
- return join(pendingAskDir(key.userId), `${V2_ASK_FILENAME_PREFIX}${encoded}.pending`);
39
- }
40
- function legacyPendingAskPath(key) {
41
- if (key.from.includes("/") || key.from.includes("\\") || key.to.includes("/") || key.to.includes("\\") || key.from.includes("\x00") || key.to.includes("\x00")) {
42
- return null;
43
- }
44
- const dir = pendingAskDir(key.userId);
45
- const candidate = join(dir, `${key.from}___${key.to}.pending`);
46
- return dirname(candidate) === dir ? candidate : null;
47
- }
48
- function parsePendingAskFilename(fileName) {
49
- if (!fileName.endsWith(".pending"))
50
- return null;
51
- const raw = fileName.slice(0, -".pending".length);
52
- if (raw.startsWith(V2_ASK_FILENAME_PREFIX)) {
53
- try {
54
- const decoded = JSON.parse(Buffer.from(raw.slice(V2_ASK_FILENAME_PREFIX.length), "base64url").toString("utf8"));
55
- if (Array.isArray(decoded) && decoded.length === 2 && decoded.every((part) => typeof part === "string")) {
56
- return { from: decoded[0], to: decoded[1] };
57
- }
58
- } catch {}
59
- }
60
- const sep = raw.indexOf("___");
61
- if (sep < 0)
62
- return null;
63
- return { from: raw.slice(0, sep), to: raw.slice(sep + 3) };
64
- }
65
- function readPendingAskFile(path, fallback) {
66
- try {
67
- const raw = readFileSync(path, "utf8").trim();
68
- if (!raw)
69
- return null;
70
- if (!raw.startsWith("{")) {
71
- const ts = new Date(statSync(path).mtimeMs).toISOString();
72
- return {
73
- userId: fallback.userId,
74
- from: fallback.from,
75
- to: fallback.to,
76
- requestId: raw,
77
- state: "requested",
78
- createdAt: ts,
79
- updatedAt: ts
80
- };
81
- }
82
- const parsed = JSON.parse(raw);
83
- if (!parsed.requestId || !parsed.from || !parsed.to)
84
- return null;
85
- const now = new Date().toISOString();
86
- return {
87
- userId: fallback.userId,
88
- from: parsed.from,
89
- to: parsed.to,
90
- requestId: parsed.requestId,
91
- contextId: parsed.contextId,
92
- state: parsed.state ?? "requested",
93
- createdAt: parsed.createdAt ?? now,
94
- updatedAt: parsed.updatedAt ?? parsed.createdAt ?? now
95
- };
96
- } catch {
97
- return null;
98
- }
99
- }
100
- function isStale(record, path) {
101
- const ts = record ? Date.parse(record.updatedAt || record.createdAt) : Number.NaN;
102
- if (Number.isFinite(ts))
103
- return Date.now() - ts > PENDING_ASK_TTL_MS;
104
- try {
105
- return Date.now() - statSync(path).mtimeMs > PENDING_ASK_TTL_MS;
106
- } catch {
107
- return false;
108
- }
109
- }
110
- function writePendingAsk(record) {
111
- const path = pendingAskPath(record);
112
- mkdirSync(pendingAskDir(record.userId), { recursive: true });
113
- writeFileSync(path, `${JSON.stringify(record)}
114
- `);
115
- }
116
- function writePendingAskIfAbsent(record) {
117
- const path = pendingAskPath(record);
118
- mkdirSync(pendingAskDir(record.userId), { recursive: true });
119
- let fd = null;
120
- try {
121
- fd = openSync(path, "wx");
122
- writeFileSync(fd, `${JSON.stringify(record)}
123
- `);
124
- return true;
125
- } catch (error) {
126
- if (error.code === "EEXIST")
127
- return false;
128
- throw error;
129
- } finally {
130
- if (fd !== null)
131
- closeSync(fd);
132
- }
133
- }
134
- function readPendingAsk(key) {
135
- const canonicalPath = pendingAskPath(key);
136
- const canonical = readPendingAskFile(canonicalPath, key);
137
- if (canonical && canonical.from === key.from && canonical.to === key.to) {
138
- return { path: canonicalPath, record: canonical };
139
- }
140
- for (const compatibilityPath of [v2PendingAskPath(key), legacyPendingAskPath(key)]) {
141
- if (!compatibilityPath)
142
- continue;
143
- const legacy = readPendingAskFile(compatibilityPath, key);
144
- if (!legacy || legacy.from !== key.from || legacy.to !== key.to)
145
- continue;
146
- const migrated = writePendingAskIfAbsent(legacy);
147
- const next = migrated ? legacy : readPendingAskFile(canonicalPath, key);
148
- if (next && next.from === key.from && next.to === key.to) {
149
- try {
150
- unlinkSync(compatibilityPath);
151
- } catch {}
152
- return { path: canonicalPath, record: next };
153
- }
154
- return { path: compatibilityPath, record: legacy };
155
- }
156
- return null;
157
- }
158
- function createPendingAsk(args) {
159
- const migrated = readPendingAsk(args);
160
- if (migrated && !isStale(migrated.record, migrated.path)) {
161
- return { ok: false, existing: migrated.record, stale: false };
162
- }
163
- if (migrated) {
164
- try {
165
- unlinkSync(migrated.path);
166
- } catch {
167
- return { ok: false, existing: migrated.record, stale: true };
168
- }
169
- }
170
- const path = pendingAskPath(args);
171
- const now = new Date().toISOString();
172
- const record = {
173
- userId: args.userId,
174
- from: args.from,
175
- to: args.to,
176
- requestId: args.requestId,
177
- contextId: args.contextId,
178
- state: "requested",
179
- createdAt: now,
180
- updatedAt: now
181
- };
182
- mkdirSync(pendingAskDir(args.userId), { recursive: true });
183
- for (let attempt = 0;attempt < 2; attempt++) {
184
- let fd = null;
185
- try {
186
- fd = openSync(path, "wx");
187
- writeFileSync(fd, `${JSON.stringify(record)}
188
- `);
189
- return { ok: true, record };
190
- } catch (err) {
191
- if (err.code !== "EEXIST")
192
- throw err;
193
- const existing = readPendingAskFile(path, args);
194
- if (!isStale(existing, path))
195
- return { ok: false, existing, stale: false };
196
- try {
197
- unlinkSync(path);
198
- } catch {
199
- return { ok: false, existing, stale: true };
200
- }
201
- } finally {
202
- if (fd !== null)
203
- closeSync(fd);
204
- }
205
- }
206
- return { ok: false, existing: readPendingAskFile(path, args), stale: true };
207
- }
208
- function markPendingAskState(args) {
209
- const pending = readPendingAsk(args);
210
- if (!pending)
211
- return null;
212
- const record = pending.record;
213
- if (args.requestId && record.requestId !== args.requestId)
214
- return record;
215
- const next = {
216
- ...record,
217
- state: args.state,
218
- updatedAt: new Date().toISOString()
219
- };
220
- writePendingAsk(next);
221
- if (pending.path !== pendingAskPath(next)) {
222
- try {
223
- unlinkSync(pending.path);
224
- } catch {}
225
- }
226
- return next;
227
- }
228
- function clearPendingAsk(args) {
229
- const pending = readPendingAsk(args);
230
- const path = pending?.path ?? pendingAskPath(args);
231
- const record = pending?.record ?? null;
232
- if (args.requestId && record && record.requestId !== args.requestId)
233
- return false;
234
- try {
235
- unlinkSync(path);
236
- return true;
237
- } catch {
238
- return false;
239
- }
240
- }
241
- function markPendingAskSources(args) {
242
- for (const source of args.sources ?? []) {
243
- if (!source.from)
244
- continue;
245
- markPendingAskState({
246
- userId: args.userId,
247
- from: args.callerTopic,
248
- to: source.from,
249
- requestId: source.requestId,
250
- state: args.state
251
- });
252
- }
253
- }
254
- function clearPendingAskSources(args) {
255
- for (const source of args.sources ?? []) {
256
- if (!source.from)
257
- continue;
258
- clearPendingAsk({
259
- userId: args.userId,
260
- from: args.callerTopic,
261
- to: source.from,
262
- requestId: source.requestId
263
- });
264
- }
265
- }
266
- function listPendingAsksForCaller(args) {
267
- const dir = pendingAskDir(args.userId);
268
- let files;
269
- try {
270
- files = readdirSync(dir);
271
- } catch {
272
- return [];
273
- }
274
- const records = new Map;
275
- for (const fileName of files) {
276
- const isV3 = fileName.startsWith(ASK_FILENAME_PREFIX);
277
- const parsed = isV3 ? { from: args.from, to: "" } : parsePendingAskFilename(fileName);
278
- if (!parsed)
279
- continue;
280
- const path = join(dir, fileName);
281
- const record = readPendingAskFile(path, {
282
- userId: args.userId,
283
- from: parsed.from,
284
- to: parsed.to
285
- });
286
- if (!record || record.from !== args.from)
287
- continue;
288
- if (isStale(record, path)) {
289
- try {
290
- unlinkSync(path);
291
- } catch {}
292
- continue;
293
- }
294
- const canonical = readPendingAsk(record);
295
- if (!canonical || canonical.record.from !== args.from)
296
- continue;
297
- if (path !== canonical.path) {
298
- try {
299
- unlinkSync(path);
300
- } catch {}
301
- }
302
- if (isStale(canonical.record, canonical.path)) {
303
- try {
304
- unlinkSync(canonical.path);
305
- } catch {}
306
- continue;
307
- }
308
- records.set(encodeAskKey(canonical.record), canonical.record);
309
- }
310
- return [...records.values()];
311
- }
312
- function deletePendingAsksForTopic(args) {
313
- const dir = pendingAskDir(args.userId);
314
- let files;
315
- try {
316
- files = readdirSync(dir);
317
- } catch {
318
- return 0;
319
- }
320
- let deleted = 0;
321
- for (const fileName of files) {
322
- const path = join(dir, fileName);
323
- const parsed = parsePendingAskFilename(fileName);
324
- const record = readPendingAskFile(path, {
325
- userId: args.userId,
326
- from: parsed?.from ?? "",
327
- to: parsed?.to ?? ""
328
- });
329
- const from = record?.from ?? parsed?.from;
330
- const to = record?.to ?? parsed?.to;
331
- if (from !== args.topicName && to !== args.topicName)
332
- continue;
333
- try {
334
- unlinkSync(path);
335
- deleted++;
336
- } catch {}
337
- }
338
- return deleted;
339
- }
340
- function describePendingAskState(state) {
341
- switch (state) {
342
- case "requested":
343
- return "\uB300\uC0C1 \uC138\uC158 \uCC98\uB9AC \uC911";
344
- case "reply_ready":
345
- return "\uC751\uB2F5 \uC0DD\uC131 \uC644\uB8CC, \uC774 \uC138\uC158 \uC8FC\uC785 \uC900\uBE44 \uC911";
346
- case "queued_for_caller":
347
- return "\uC751\uB2F5 \uC0DD\uC131 \uC644\uB8CC, \uC774 \uC138\uC158 \uC2E4\uD589 \uC885\uB8CC \uD6C4 \uC8FC\uC785 \uB300\uAE30 \uC911";
348
- case "injecting_to_caller":
349
- return "\uC751\uB2F5\uC744 \uC774 \uC138\uC158\uC5D0 \uC8FC\uC785 \uC911";
350
- }
351
- }
352
- export {
353
- markPendingAskState,
354
- markPendingAskSources,
355
- listPendingAsksForCaller,
356
- describePendingAskState,
357
- deletePendingAsksForTopic,
358
- createPendingAsk,
359
- clearPendingAskSources,
360
- clearPendingAsk,
361
- PENDING_ASK_TTL_MS
362
- };
363
-
364
- export { PENDING_ASK_TTL_MS, clearPendingAsk, deletePendingAsksForTopic };
365
-
366
- //# debugId=8F8CE24813BAC54F64756E2164756E21
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../packages/core/src/storage/session-asks.ts"],
4
- "sourcesContent": [
5
- "import { createHash } from \"node:crypto\";\nimport {\n closeSync,\n mkdirSync,\n openSync,\n readdirSync,\n readFileSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { resolveStorageSessionAsksDir } from \"#storage/storage-host\";\n\nexport const PENDING_ASK_TTL_MS = 15 * 60 * 1000;\n\nexport type PendingAskState =\n | \"requested\"\n | \"reply_ready\"\n | \"queued_for_caller\"\n | \"injecting_to_caller\";\n\nexport type PendingAskUserId = number | string;\n\nexport interface PendingAskRecord {\n userId: PendingAskUserId;\n from: string;\n to: string;\n requestId: string;\n contextId?: string;\n state: PendingAskState;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface AskReplySource {\n from?: string;\n requestId?: string;\n contextId?: string;\n}\n\ninterface AskKey {\n userId: PendingAskUserId;\n from: string;\n to: string;\n}\n\ninterface AskIdentity extends AskKey {\n requestId?: string;\n}\n\nfunction pendingAskDir(userId: PendingAskUserId): string {\n const rawUserId = String(userId);\n const safeUserId = /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId)\n ? rawUserId\n : `sha256-${createHash(\"sha256\").update(rawUserId).digest(\"hex\")}`;\n return join(resolveStorageSessionAsksDir(), safeUserId);\n}\n\nconst ASK_FILENAME_PREFIX = \"v3-\";\nconst V2_ASK_FILENAME_PREFIX = \"v2-\";\n\nfunction encodeAskKey(key: Pick<AskKey, \"from\" | \"to\">): string {\n return JSON.stringify([key.from, key.to]);\n}\n\nfunction pendingAskPath(key: AskKey): string {\n const digest = createHash(\"sha256\").update(encodeAskKey(key)).digest(\"hex\");\n return join(pendingAskDir(key.userId), `${ASK_FILENAME_PREFIX}${digest}.pending`);\n}\n\nfunction v2PendingAskPath(key: AskKey): string {\n const encoded = Buffer.from(encodeAskKey(key), \"utf8\").toString(\"base64url\");\n return join(pendingAskDir(key.userId), `${V2_ASK_FILENAME_PREFIX}${encoded}.pending`);\n}\n\nfunction legacyPendingAskPath(key: AskKey): string | null {\n if (\n key.from.includes(\"/\") ||\n key.from.includes(\"\\\\\") ||\n key.to.includes(\"/\") ||\n key.to.includes(\"\\\\\") ||\n key.from.includes(\"\\0\") ||\n key.to.includes(\"\\0\")\n ) {\n return null;\n }\n const dir = pendingAskDir(key.userId);\n const candidate = join(dir, `${key.from}___${key.to}.pending`);\n return dirname(candidate) === dir ? candidate : null;\n}\n\nfunction parsePendingAskFilename(fileName: string): { from: string; to: string } | null {\n if (!fileName.endsWith(\".pending\")) return null;\n const raw = fileName.slice(0, -\".pending\".length);\n if (raw.startsWith(V2_ASK_FILENAME_PREFIX)) {\n try {\n const decoded = JSON.parse(\n Buffer.from(raw.slice(V2_ASK_FILENAME_PREFIX.length), \"base64url\").toString(\"utf8\"),\n ) as unknown;\n if (\n Array.isArray(decoded) &&\n decoded.length === 2 &&\n decoded.every((part) => typeof part === \"string\")\n ) {\n return { from: decoded[0], to: decoded[1] };\n }\n } catch {\n // A legacy caller key may itself start with \"v2-\". Fall through to the\n // delimiter parser when the suffix is not a valid v2 payload.\n }\n }\n\n // Read files created before the opaque v2 key was introduced.\n const sep = raw.indexOf(\"___\");\n if (sep < 0) return null;\n return { from: raw.slice(0, sep), to: raw.slice(sep + 3) };\n}\n\nfunction readPendingAskFile(path: string, fallback: AskKey): PendingAskRecord | null {\n try {\n const raw = readFileSync(path, \"utf8\").trim();\n if (!raw) return null;\n if (!raw.startsWith(\"{\")) {\n const ts = new Date(statSync(path).mtimeMs).toISOString();\n return {\n userId: fallback.userId,\n from: fallback.from,\n to: fallback.to,\n requestId: raw,\n state: \"requested\",\n createdAt: ts,\n updatedAt: ts,\n };\n }\n const parsed = JSON.parse(raw) as Partial<PendingAskRecord>;\n if (!parsed.requestId || !parsed.from || !parsed.to) return null;\n const now = new Date().toISOString();\n return {\n // The directory selected by the caller is authoritative. Never let a\n // tampered record redirect a later migration/update into another user root.\n userId: fallback.userId,\n from: parsed.from,\n to: parsed.to,\n requestId: parsed.requestId,\n contextId: parsed.contextId,\n state: parsed.state ?? \"requested\",\n createdAt: parsed.createdAt ?? now,\n updatedAt: parsed.updatedAt ?? parsed.createdAt ?? now,\n };\n } catch {\n return null;\n }\n}\n\nfunction isStale(record: PendingAskRecord | null, path: string): boolean {\n const ts = record ? Date.parse(record.updatedAt || record.createdAt) : Number.NaN;\n if (Number.isFinite(ts)) return Date.now() - ts > PENDING_ASK_TTL_MS;\n try {\n return Date.now() - statSync(path).mtimeMs > PENDING_ASK_TTL_MS;\n } catch {\n return false;\n }\n}\n\nfunction writePendingAsk(record: PendingAskRecord): void {\n const path = pendingAskPath(record);\n mkdirSync(pendingAskDir(record.userId), { recursive: true });\n writeFileSync(path, `${JSON.stringify(record)}\\n`);\n}\n\nfunction writePendingAskIfAbsent(record: PendingAskRecord): boolean {\n const path = pendingAskPath(record);\n mkdirSync(pendingAskDir(record.userId), { recursive: true });\n let fd: number | null = null;\n try {\n fd = openSync(path, \"wx\");\n writeFileSync(fd, `${JSON.stringify(record)}\\n`);\n return true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"EEXIST\") return false;\n throw error;\n } finally {\n if (fd !== null) closeSync(fd);\n }\n}\n\nfunction readPendingAsk(key: AskKey): { path: string; record: PendingAskRecord } | null {\n const canonicalPath = pendingAskPath(key);\n const canonical = readPendingAskFile(canonicalPath, key);\n if (canonical && canonical.from === key.from && canonical.to === key.to) {\n return { path: canonicalPath, record: canonical };\n }\n\n for (const compatibilityPath of [v2PendingAskPath(key), legacyPendingAskPath(key)]) {\n if (!compatibilityPath) continue;\n const legacy = readPendingAskFile(compatibilityPath, key);\n if (!legacy || legacy.from !== key.from || legacy.to !== key.to) continue;\n\n const migrated = writePendingAskIfAbsent(legacy);\n const next = migrated ? legacy : readPendingAskFile(canonicalPath, key);\n if (next && next.from === key.from && next.to === key.to) {\n try {\n unlinkSync(compatibilityPath);\n } catch {\n // The canonical record is durable; concurrent cleanup may win.\n }\n return { path: canonicalPath, record: next };\n }\n\n // Never discard a valid compatibility record when a corrupt or racing\n // canonical file cannot be trusted.\n return { path: compatibilityPath, record: legacy };\n }\n\n return null;\n}\n\nexport function createPendingAsk(args: {\n userId: PendingAskUserId;\n from: string;\n to: string;\n requestId: string;\n contextId?: string;\n}):\n | { ok: true; record: PendingAskRecord }\n | { ok: false; existing: PendingAskRecord | null; stale: boolean } {\n const migrated = readPendingAsk(args);\n if (migrated && !isStale(migrated.record, migrated.path)) {\n return { ok: false, existing: migrated.record, stale: false };\n }\n if (migrated) {\n try {\n unlinkSync(migrated.path);\n } catch {\n return { ok: false, existing: migrated.record, stale: true };\n }\n }\n const path = pendingAskPath(args);\n const now = new Date().toISOString();\n const record: PendingAskRecord = {\n userId: args.userId,\n from: args.from,\n to: args.to,\n requestId: args.requestId,\n contextId: args.contextId,\n state: \"requested\",\n createdAt: now,\n updatedAt: now,\n };\n\n mkdirSync(pendingAskDir(args.userId), { recursive: true });\n for (let attempt = 0; attempt < 2; attempt++) {\n let fd: number | null = null;\n try {\n fd = openSync(path, \"wx\");\n writeFileSync(fd, `${JSON.stringify(record)}\\n`);\n return { ok: true, record };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"EEXIST\") throw err;\n const existing = readPendingAskFile(path, args);\n if (!isStale(existing, path)) return { ok: false, existing, stale: false };\n try {\n unlinkSync(path);\n } catch {\n return { ok: false, existing, stale: true };\n }\n } finally {\n if (fd !== null) closeSync(fd);\n }\n }\n\n return { ok: false, existing: readPendingAskFile(path, args), stale: true };\n}\n\nexport function markPendingAskState(\n args: AskIdentity & { state: PendingAskState },\n): PendingAskRecord | null {\n const pending = readPendingAsk(args);\n if (!pending) return null;\n const record = pending.record;\n if (args.requestId && record.requestId !== args.requestId) return record;\n const next = {\n ...record,\n state: args.state,\n updatedAt: new Date().toISOString(),\n };\n writePendingAsk(next);\n if (pending.path !== pendingAskPath(next)) {\n try {\n unlinkSync(pending.path);\n } catch {\n // The canonical v3 record already contains the update.\n }\n }\n return next;\n}\n\nexport function clearPendingAsk(args: AskIdentity): boolean {\n const pending = readPendingAsk(args);\n const path = pending?.path ?? pendingAskPath(args);\n const record = pending?.record ?? null;\n if (args.requestId && record && record.requestId !== args.requestId) return false;\n try {\n unlinkSync(path);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function markPendingAskSources(args: {\n userId: PendingAskUserId;\n callerTopic: string;\n sources?: AskReplySource[];\n state: PendingAskState;\n}): void {\n for (const source of args.sources ?? []) {\n if (!source.from) continue;\n markPendingAskState({\n userId: args.userId,\n from: args.callerTopic,\n to: source.from,\n requestId: source.requestId,\n state: args.state,\n });\n }\n}\n\nexport function clearPendingAskSources(args: {\n userId: PendingAskUserId;\n callerTopic: string;\n sources?: AskReplySource[];\n}): void {\n for (const source of args.sources ?? []) {\n if (!source.from) continue;\n clearPendingAsk({\n userId: args.userId,\n from: args.callerTopic,\n to: source.from,\n requestId: source.requestId,\n });\n }\n}\n\nexport function listPendingAsksForCaller(args: {\n userId: PendingAskUserId;\n from: string;\n}): PendingAskRecord[] {\n const dir = pendingAskDir(args.userId);\n let files: string[];\n try {\n files = readdirSync(dir);\n } catch {\n return [];\n }\n\n const records = new Map<string, PendingAskRecord>();\n for (const fileName of files) {\n const isV3 = fileName.startsWith(ASK_FILENAME_PREFIX);\n const parsed = isV3 ? { from: args.from, to: \"\" } : parsePendingAskFilename(fileName);\n if (!parsed) continue;\n const path = join(dir, fileName);\n const record = readPendingAskFile(path, {\n userId: args.userId,\n from: parsed.from,\n to: parsed.to,\n });\n if (!record || record.from !== args.from) continue;\n if (isStale(record, path)) {\n try {\n unlinkSync(path);\n } catch {\n // Best-effort stale cleanup only.\n }\n continue;\n }\n const canonical = readPendingAsk(record);\n if (!canonical || canonical.record.from !== args.from) continue;\n if (path !== canonical.path) {\n try {\n unlinkSync(path);\n } catch {\n // Canonical record wins; duplicate compatibility cleanup is best effort.\n }\n }\n if (isStale(canonical.record, canonical.path)) {\n try {\n unlinkSync(canonical.path);\n } catch {\n // Best-effort stale cleanup only.\n }\n continue;\n }\n records.set(encodeAskKey(canonical.record), canonical.record);\n }\n return [...records.values()];\n}\n\n/** Remove durable ask edges to or from a topic that no longer exists. */\nexport function deletePendingAsksForTopic(args: {\n userId: PendingAskUserId;\n topicName: string;\n}): number {\n const dir = pendingAskDir(args.userId);\n let files: string[];\n try {\n files = readdirSync(dir);\n } catch {\n return 0;\n }\n\n let deleted = 0;\n for (const fileName of files) {\n const path = join(dir, fileName);\n const parsed = parsePendingAskFilename(fileName);\n const record = readPendingAskFile(path, {\n userId: args.userId,\n from: parsed?.from ?? \"\",\n to: parsed?.to ?? \"\",\n });\n const from = record?.from ?? parsed?.from;\n const to = record?.to ?? parsed?.to;\n if (from !== args.topicName && to !== args.topicName) continue;\n try {\n unlinkSync(path);\n deleted++;\n } catch {\n // Best-effort teardown; stale cleanup will retry any file that survives.\n }\n }\n return deleted;\n}\n\nexport function describePendingAskState(state: PendingAskState): string {\n switch (state) {\n case \"requested\":\n return \"대상 세션 처리 중\";\n case \"reply_ready\":\n return \"응답 생성 완료, 이 세션 주입 준비 중\";\n case \"queued_for_caller\":\n return \"응답 생성 완료, 이 세션 실행 종료 후 주입 대기 중\";\n case \"injecting_to_caller\":\n return \"응답을 이 세션에 주입 중\";\n }\n}\n"
6
- ],
7
- "mappings": "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",
8
- "debugId": "8F8CE24813BAC54F64756E2164756E21",
9
- "names": []
10
- }
@@ -1,9 +0,0 @@
1
- // ../../packages/adapter-sdk/src/index.ts
2
- var NEGOTIUM_ADAPTER_API_VERSION = 3;
3
- function defineNegotiumAdapter(definition) {
4
- return { apiVersion: NEGOTIUM_ADAPTER_API_VERSION, ...definition };
5
- }
6
-
7
- export { defineNegotiumAdapter };
8
-
9
- //# debugId=4B9EA4CD81D4F9FD64756E2164756E21
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../packages/adapter-sdk/src/index.ts"],
4
- "sourcesContent": [
5
- "/** Stable lifecycle contract implemented by every first-party channel adapter. */\n\nexport const NEGOTIUM_ADAPTER_API_VERSION = 3 as const;\n\nexport type Awaitable<T> = T | Promise<T>;\n\nexport interface NegotiumAdapterHandle<Name extends string = string> {\n /** Stable adapter key used in logs, configuration, and contract tests. */\n readonly name: Name;\n /** Stop accepting channel input and release every owned resource. Idempotent. */\n stop(): Awaitable<void>;\n}\n\n/** User-facing transcript semantics; transport gaps stay explicit metadata. */\nexport interface NegotiumAdapterProjectionCapabilities {\n /** Whether the surface can render a room timeline or only newly delivered events. */\n readonly transcript: \"full\" | \"live-only\";\n /** Whether pre-existing topic messages can populate the surface on binding. */\n readonly historyBackfill: boolean;\n /** How authors originating in another adapter are represented. */\n readonly externalAuthors: \"native\" | \"relayed\";\n}\n\n/** Optional behavioral surfaces are declared independently from lifecycle. */\nexport interface NegotiumAdapterCapabilities {\n /** Accepts a human message originating on this adapter. */\n readonly localUserInput: boolean;\n /** Exposes create/delete/reset/compact topic commands. */\n readonly topicManagement: boolean;\n /** Executes a turn placed by an external peer runtime. */\n readonly externalPlacedTurn: boolean;\n}\n\nexport interface NegotiumAdapterDefinition<\n Name extends string,\n Options,\n Handle extends NegotiumAdapterHandle<Name>,\n> {\n readonly apiVersion: typeof NEGOTIUM_ADAPTER_API_VERSION;\n readonly name: Name;\n readonly capabilities: NegotiumAdapterCapabilities;\n readonly projection: NegotiumAdapterProjectionCapabilities;\n start(options: Options): Awaitable<Handle>;\n}\n\nexport function defineNegotiumAdapter<\n const Name extends string,\n Options,\n Handle extends NegotiumAdapterHandle<Name>,\n>(\n definition: Omit<NegotiumAdapterDefinition<Name, Options, Handle>, \"apiVersion\">,\n): NegotiumAdapterDefinition<Name, Options, Handle> {\n return { apiVersion: NEGOTIUM_ADAPTER_API_VERSION, ...definition };\n}\n"
6
- ],
7
- "mappings": ";AAEO,IAAM,+BAA+B;AA2CrC,SAAS,qBAIf,CACC,YACkD;AAAA,EAClD,OAAO,EAAE,YAAY,iCAAiC,WAAW;AAAA;",
8
- "debugId": "4B9EA4CD81D4F9FD64756E2164756E21",
9
- "names": []
10
- }