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
@@ -0,0 +1,54 @@
1
+ export interface StorageStatement<Result = unknown, _Params = unknown> {
2
+ get(...params: any[]): Result | null | undefined;
3
+ all(...params: any[]): Result[];
4
+ run(...params: any[]): any;
5
+ }
6
+
7
+ export interface StorageTransaction<Args extends unknown[], Result> {
8
+ (...args: Args): Result;
9
+ deferred: (...args: Args) => Result;
10
+ immediate: (...args: Args) => Result;
11
+ exclusive: (...args: Args) => Result;
12
+ }
13
+
14
+ /** Structural SQLite surface supported by Bun and Negotium's Node shim. */
15
+ export interface StorageDatabase {
16
+ query<Result = unknown, Params = unknown>(sql: string): StorageStatement<Result, Params>;
17
+ prepare<Result = unknown, Params = unknown>(sql: string): StorageStatement<Result, Params>;
18
+ exec(sql: string): void;
19
+ run(sql: string, ...params: any[]): any;
20
+ transaction<Args extends unknown[], Result>(
21
+ fn: (...args: Args) => Result,
22
+ ): StorageTransaction<Args, Result>;
23
+ }
24
+
25
+ /** Broad structural input accepted from Bun, Node, or a host-provided adapter. */
26
+ export interface StorageDatabaseAdapter {
27
+ query(...args: any[]): any;
28
+ prepare(...args: any[]): any;
29
+ exec(sql: string): void;
30
+ run(sql: string, ...params: any[]): any;
31
+ transaction(...args: any[]): any;
32
+ }
33
+
34
+ export type StorageDatabaseInput = StorageDatabase | StorageDatabaseAdapter;
35
+
36
+ export interface StorageHostConfig {
37
+ /** Borrowed SQLite connection. Negotium never closes an injected database. */
38
+ database?: StorageDatabaseInput;
39
+ /** Persistent JSON/JSONL state root. */
40
+ dataDir?: string;
41
+ /** Activity and token-usage log root. */
42
+ logDir?: string;
43
+ /** Durable ask edge root. Defaults to Negotium's runtime ask directory. */
44
+ sessionAsksDir?: string;
45
+ /** Shared topic workspace root used by wiki/archive helpers. */
46
+ workspaceDir?: string;
47
+ /** Shared wiki root. Defaults to `<workspaceDir>/wiki`. */
48
+ sharedWikiDir?: string;
49
+ /** Per-user sent-file log root. Defaults to `<dataDir>/users`. */
50
+ usersLogDir?: string;
51
+ }
52
+
53
+ /** Compatibility name retained for 0.1.11 consumers. */
54
+ export type StorageHostOptions = StorageHostConfig;
@@ -2,34 +2,40 @@ import { mkdirSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { dirname, join, resolve } from "node:path";
4
4
  import { Database } from "#storage/sqlite";
5
+ import type { StorageDatabase, StorageHostConfig } from "#storage/storage-contract";
5
6
 
6
- export type StorageDatabase = InstanceType<typeof Database>;
7
+ export type {
8
+ StorageDatabase,
9
+ StorageDatabaseAdapter,
10
+ StorageDatabaseInput,
11
+ StorageHostConfig,
12
+ StorageHostOptions,
13
+ StorageStatement,
14
+ StorageTransaction,
15
+ } from "#storage/storage-contract";
7
16
 
8
- export interface StorageHostOptions {
9
- /** Borrowed SQLite connection. Negotium never closes an injected database. */
10
- database?: StorageDatabase;
11
- /** Persistent JSON/JSONL state root. */
12
- dataDir?: string;
13
- /** Activity and token-usage log root. */
14
- logDir?: string;
15
- /** Durable ask edge root. Defaults to Negotium's runtime ask directory. */
16
- sessionAsksDir?: string;
17
- /** Shared topic workspace root used by wiki/archive helpers. */
18
- workspaceDir?: string;
17
+ let configuredHost: Readonly<StorageHostConfig> = {};
18
+ type InternalStorageDatabase = InstanceType<typeof Database>;
19
+ type OwnedStorageDatabase = InternalStorageDatabase & { close(): void };
20
+ let fallbackDatabase: OwnedStorageDatabase | null = null;
21
+ let fallbackDatabasePath: string | null = null;
22
+
23
+ interface StorageHostFrame {
24
+ active: boolean;
25
+ patch: Readonly<StorageHostConfig>;
19
26
  }
20
27
 
21
- let configuredHost: Readonly<StorageHostOptions> = {};
22
- let fallbackDatabase: StorageDatabase | null = null;
28
+ const storageHostFrames: StorageHostFrame[] = [];
23
29
 
24
- type StorageSchemaInitializer = (database: StorageDatabase) => void;
30
+ type StorageSchemaInitializer = (database: InternalStorageDatabase) => void;
25
31
  interface RegisteredSchemaInitializer {
26
32
  initialize: StorageSchemaInitializer;
27
33
  priority: number;
28
34
  }
29
35
 
30
36
  const schemaInitializers: RegisteredSchemaInitializer[] = [];
31
- const initializedSchemas = new WeakMap<StorageDatabase, Set<StorageSchemaInitializer>>();
32
- const initializingDatabases = new WeakSet<StorageDatabase>();
37
+ const initializedSchemas = new WeakMap<InternalStorageDatabase, Set<StorageSchemaInitializer>>();
38
+ const initializingDatabases = new WeakSet<InternalStorageDatabase>();
33
39
 
34
40
  function envPath(name: string, fallback: string): string {
35
41
  const value = process.env[name]?.trim();
@@ -58,10 +64,10 @@ function defaultSessionAsksDir(): string {
58
64
  }
59
65
 
60
66
  function defaultSessionsDatabasePath(): string {
61
- return envPath("SESSIONS_DB_PATH", join(defaultDataDir(), "sessions.db"));
67
+ return envPath("SESSIONS_DB_PATH", join(resolveStorageDataDir(), "sessions.db"));
62
68
  }
63
69
 
64
- function initializeDatabase(database: StorageDatabase): void {
70
+ function initializeDatabase(database: InternalStorageDatabase): void {
65
71
  database.exec("PRAGMA journal_mode = WAL");
66
72
  database.exec("PRAGMA foreign_keys = ON");
67
73
  database.exec("PRAGMA busy_timeout = 5000");
@@ -73,17 +79,19 @@ function initializeDatabase(database: StorageDatabase): void {
73
79
  }
74
80
  }
75
81
 
76
- function defaultDatabase(): StorageDatabase {
77
- if (fallbackDatabase) return fallbackDatabase;
82
+ function defaultDatabase(): InternalStorageDatabase {
78
83
  const path = defaultSessionsDatabasePath();
84
+ if (fallbackDatabase && fallbackDatabasePath === path) return fallbackDatabase;
85
+ if (fallbackDatabase) fallbackDatabase.close();
79
86
  mkdirSync(dirname(path), { recursive: true });
80
- fallbackDatabase = new Database(path, { create: true });
87
+ fallbackDatabase = new Database(path, { create: true }) as unknown as OwnedStorageDatabase;
88
+ fallbackDatabasePath = path;
81
89
  initializeDatabase(fallbackDatabase);
82
90
  return fallbackDatabase;
83
91
  }
84
92
 
85
- export function resolveStorageDatabase(): StorageDatabase {
86
- return configuredHost.database ?? defaultDatabase();
93
+ export function resolveStorageDatabase(): InternalStorageDatabase {
94
+ return (configuredHost.database ?? defaultDatabase()) as InternalStorageDatabase;
87
95
  }
88
96
 
89
97
  export function resolveStorageDataDir(): string {
@@ -103,11 +111,41 @@ export function resolveStorageWorkspaceDir(): string {
103
111
  }
104
112
 
105
113
  export function resolveStorageSharedWikiDir(): string {
106
- return join(resolveStorageWorkspaceDir(), "wiki");
114
+ return configuredHost.sharedWikiDir ?? join(resolveStorageWorkspaceDir(), "wiki");
107
115
  }
108
116
 
109
117
  export function resolveStorageUsersLogDir(): string {
110
- return join(resolveStorageDataDir(), "users");
118
+ return configuredHost.usersLogDir ?? join(resolveStorageDataDir(), "users");
119
+ }
120
+
121
+ const STORAGE_PATH_KEYS = [
122
+ "dataDir",
123
+ "logDir",
124
+ "sessionAsksDir",
125
+ "workspaceDir",
126
+ "sharedWikiDir",
127
+ "usersLogDir",
128
+ ] as const;
129
+
130
+ function normalizeStorageHostPatch(options: StorageHostConfig): Readonly<StorageHostConfig> {
131
+ const patch: StorageHostConfig = {};
132
+ if (options.database !== undefined) patch.database = options.database;
133
+ for (const key of STORAGE_PATH_KEYS) {
134
+ const value = options[key];
135
+ if (value === undefined) continue;
136
+ if (!value.trim()) throw new TypeError(`${key} must not be empty`);
137
+ patch[key] = resolve(value);
138
+ }
139
+ return Object.freeze(patch);
140
+ }
141
+
142
+ function refreshConfiguredHost(): void {
143
+ configuredHost = Object.freeze(
144
+ Object.assign(
145
+ {},
146
+ ...storageHostFrames.filter((frame) => frame.active).map((frame) => frame.patch),
147
+ ),
148
+ );
111
149
  }
112
150
 
113
151
  /**
@@ -117,22 +155,32 @@ export function resolveStorageUsersLogDir(): string {
117
155
  * touches a filesystem path. The returned disposer restores the exact prior
118
156
  * host, which keeps tests and nested embeddings isolated.
119
157
  */
120
- export function configureStorageHost(options: StorageHostOptions): () => void {
121
- const previous = configuredHost;
122
- configuredHost = Object.freeze({ ...previous, ...options });
123
- let restored = false;
158
+ export function configureStorageHost(options: StorageHostConfig): () => void {
159
+ const frame: StorageHostFrame = { active: true, patch: normalizeStorageHostPatch(options) };
160
+ storageHostFrames.push(frame);
161
+ refreshConfiguredHost();
124
162
  return () => {
125
- if (restored) return;
126
- restored = true;
127
- configuredHost = previous;
163
+ if (!frame.active) return;
164
+ frame.active = false;
165
+ const index = storageHostFrames.indexOf(frame);
166
+ if (index >= 0) storageHostFrames.splice(index, 1);
167
+ refreshConfiguredHost();
128
168
  };
129
169
  }
130
170
 
171
+ /** Remove every configured host layer and restore standalone fallbacks. */
172
+ export function resetStorageHost(): void {
173
+ for (const frame of storageHostFrames) frame.active = false;
174
+ storageHostFrames.length = 0;
175
+ refreshConfiguredHost();
176
+ }
177
+
131
178
  /** Close only Negotium's fallback connection. Injected connections are borrowed. */
132
179
  export function closeStorageDatabase(): void {
133
- if (configuredHost.database || !fallbackDatabase) return;
180
+ if (!fallbackDatabase) return;
134
181
  fallbackDatabase.close();
135
182
  fallbackDatabase = null;
183
+ fallbackDatabasePath = null;
136
184
  }
137
185
 
138
186
  export function registerStorageSchemaInitializer(
@@ -143,7 +191,9 @@ export function registerStorageSchemaInitializer(
143
191
  schemaInitializers.sort((a, b) => a.priority - b.priority);
144
192
  }
145
193
 
146
- export function ensureStorageSchemas(database = resolveStorageDatabase()): void {
194
+ export function ensureStorageSchemas(
195
+ database: InternalStorageDatabase = resolveStorageDatabase(),
196
+ ): void {
147
197
  if (initializingDatabases.has(database)) return;
148
198
  let initialized = initializedSchemas.get(database);
149
199
  if (!initialized) {
@@ -170,7 +220,7 @@ export function ensureStorageSchemas(database = resolveStorageDatabase()): void
170
220
  }
171
221
 
172
222
  /** Stable proxy identity used by legacy imports and embedding hosts. */
173
- export const storageDatabase = new Proxy({} as StorageDatabase, {
223
+ export const internalStorageDatabase = new Proxy({} as InternalStorageDatabase, {
174
224
  get(_target, property) {
175
225
  const database = resolveStorageDatabase();
176
226
  ensureStorageSchemas(database);
@@ -183,3 +233,6 @@ export const storageDatabase = new Proxy({} as StorageDatabase, {
183
233
  return Reflect.set(database as object, property, value, database);
184
234
  },
185
235
  });
236
+
237
+ /** Structurally typed view intended for embedding hosts. */
238
+ export const storageDatabase = internalStorageDatabase as unknown as StorageDatabase;
@@ -0,0 +1,16 @@
1
+ import type { StorageDatabase, StorageHostConfig } from "#storage/storage-contract";
2
+ import {
3
+ configureStorageHost as configureInternalStorageHost,
4
+ resetStorageHost as resetInternalStorageHost,
5
+ storageDatabase,
6
+ } from "#storage/storage-host";
7
+
8
+ /** Configure the lazy process-local storage boundary and return an idempotent disposer. */
9
+ export const configureStorageHost: (options: StorageHostConfig) => () => void =
10
+ configureInternalStorageHost;
11
+
12
+ /** Remove every configured host layer and restore standalone fallbacks. */
13
+ export const resetStorageHost: () => void = resetInternalStorageHost;
14
+
15
+ /** Stable structurally typed proxy over the currently active database. */
16
+ export const db: StorageDatabase = storageDatabase;
@@ -57,11 +57,16 @@ export {
57
57
  } from "#storage/forum/index";
58
58
  export * as sessionAsks from "#storage/session-asks";
59
59
  export * from "#storage/session-asks";
60
- export type { StorageDatabase, StorageHostOptions } from "#storage/storage-host";
61
- export {
62
- configureStorageHost,
63
- storageDatabase as db,
64
- } from "#storage/storage-host";
60
+ export type {
61
+ StorageDatabase,
62
+ StorageDatabaseAdapter,
63
+ StorageDatabaseInput,
64
+ StorageHostConfig,
65
+ StorageHostOptions,
66
+ StorageStatement,
67
+ StorageTransaction,
68
+ } from "#storage/storage-contract";
69
+ export { configureStorageHost, db, resetStorageHost } from "#storage/storage-public-host";
65
70
  export * as tasks from "#storage/tasks";
66
71
  export * from "#storage/tasks";
67
72
  export * as tokenStats from "#storage/token-stats";
@@ -78,3 +83,14 @@ export * as wiki from "#storage/wiki";
78
83
  export * from "#storage/wiki";
79
84
  export * as wikiSummaryNames from "#storage/wiki-summary-names";
80
85
  export * from "#storage/wiki-summary-names";
86
+ export type { AgentKind, EffortLevel } from "#types";
87
+ export type {
88
+ AiMode,
89
+ MessageDto,
90
+ ParticipantDto,
91
+ ResponsePolicy,
92
+ TopicAccessMode,
93
+ TopicDto,
94
+ TopicKind,
95
+ TopicVisibility,
96
+ } from "#types/api";
@@ -36,7 +36,7 @@ export function tokenStatsFileId(userId: number | string): string {
36
36
  const rawUserId = String(userId);
37
37
  // Preserve existing filenames for ordinary IDs, but never let an external
38
38
  // identity introduce path separators or unbounded filename length.
39
- return /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId)
39
+ return /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..")
40
40
  ? rawUserId
41
41
  : `sha256-${createHash("sha256").update(rawUserId).digest("hex")}`;
42
42
  }
@@ -206,6 +206,8 @@ export interface MessageDto {
206
206
  authorAvatarUrl?: string | null;
207
207
  text: string;
208
208
  attachments?: AttachmentDto[];
209
+ /** Internal hint: an external channel may claim and acknowledge attachment delivery. */
210
+ deliveryAckRequested?: boolean;
209
211
  queryId?: string;
210
212
  agentType?: AgentKind;
211
213
  model?: string;
@@ -182,6 +182,8 @@ export interface AgentQueryOptions {
182
182
  autoContinue?: boolean;
183
183
  /** Expose Otium-only visual panel tools for this turn. Default-deny. */
184
184
  visualTools?: boolean;
185
+ /** Expose adapter-backed file-delivery tools for this turn. Default-deny. */
186
+ fileDeliveryTools?: boolean;
185
187
  abortController?: AbortController;
186
188
  model?: string;
187
189
  /** Provider-side hard budget when the selected SDK supports one. */
@@ -1 +1 @@
1
- export const NEGOTIUM_VERSION = "0.1.11";
1
+ export const NEGOTIUM_VERSION = "0.1.13";
@@ -212,7 +212,7 @@ var WHISPER_MODEL = envText("WHISPER_MODEL_FILE") ?? "turbo";
212
212
  var TESSERACT_BIN = envText("TESSERACT_BIN") ?? "tesseract";
213
213
  var PDFTOTEXT_BIN = envText("PDFTOTEXT_BIN") ?? "pdftotext";
214
214
  var _envMaxTellDepth = Number.parseInt(process.env.MAX_TELL_DEPTH ?? "", 10);
215
- var MAX_TELL_DEPTH = Number.isInteger(_envMaxTellDepth) && _envMaxTellDepth > 0 ? _envMaxTellDepth : 3;
215
+ var MAX_TELL_DEPTH = Number.isInteger(_envMaxTellDepth) && _envMaxTellDepth > 0 ? _envMaxTellDepth : 20;
216
216
 
217
217
  // ../../packages/core/src/storage/storage-host.ts
218
218
  import { mkdirSync as mkdirSync2 } from "fs";
@@ -273,6 +273,7 @@ if (isBun) {
273
273
  // ../../packages/core/src/storage/storage-host.ts
274
274
  var configuredHost = {};
275
275
  var fallbackDatabase = null;
276
+ var fallbackDatabasePath = null;
276
277
  var schemaInitializers = [];
277
278
  var initializedSchemas = new WeakMap;
278
279
  var initializingDatabases = new WeakSet;
@@ -287,7 +288,7 @@ function defaultDataDir() {
287
288
  return envPath("NEGOTIUM_DATA_DIR", join2(defaultStateDir(), "data"));
288
289
  }
289
290
  function defaultSessionsDatabasePath() {
290
- return envPath("SESSIONS_DB_PATH", join2(defaultDataDir(), "sessions.db"));
291
+ return envPath("SESSIONS_DB_PATH", join2(resolveStorageDataDir(), "sessions.db"));
291
292
  }
292
293
  function initializeDatabase(database) {
293
294
  database.exec("PRAGMA journal_mode = WAL");
@@ -299,17 +300,23 @@ function initializeDatabase(database) {
299
300
  } catch {}
300
301
  }
301
302
  function defaultDatabase() {
302
- if (fallbackDatabase)
303
- return fallbackDatabase;
304
303
  const path = defaultSessionsDatabasePath();
304
+ if (fallbackDatabase && fallbackDatabasePath === path)
305
+ return fallbackDatabase;
306
+ if (fallbackDatabase)
307
+ fallbackDatabase.close();
305
308
  mkdirSync2(dirname2(path), { recursive: true });
306
309
  fallbackDatabase = new Database(path, { create: true });
310
+ fallbackDatabasePath = path;
307
311
  initializeDatabase(fallbackDatabase);
308
312
  return fallbackDatabase;
309
313
  }
310
314
  function resolveStorageDatabase() {
311
315
  return configuredHost.database ?? defaultDatabase();
312
316
  }
317
+ function resolveStorageDataDir() {
318
+ return configuredHost.dataDir ?? defaultDataDir();
319
+ }
313
320
  function registerStorageSchemaInitializer(initialize, priority = 100) {
314
321
  schemaInitializers.push({ initialize, priority });
315
322
  schemaInitializers.sort((a, b) => a.priority - b.priority);
@@ -339,7 +346,7 @@ function ensureStorageSchemas(database = resolveStorageDatabase()) {
339
346
  initializingDatabases.delete(database);
340
347
  }
341
348
  }
342
- var storageDatabase = new Proxy({}, {
349
+ var internalStorageDatabase = new Proxy({}, {
343
350
  get(_target, property) {
344
351
  const database = resolveStorageDatabase();
345
352
  ensureStorageSchemas(database);
@@ -352,9 +359,13 @@ var storageDatabase = new Proxy({}, {
352
359
  return Reflect.set(database, property, value, database);
353
360
  }
354
361
  });
362
+
363
+ // ../../packages/core/src/storage/forum-db.ts
364
+ var db = internalStorageDatabase;
365
+
355
366
  // ../../packages/core/src/storage/api-messages.ts
356
367
  function initializeApiMessagesSchema() {
357
- storageDatabase.exec(`
368
+ db.exec(`
358
369
  CREATE TABLE IF NOT EXISTS api_messages (
359
370
  id TEXT PRIMARY KEY,
360
371
  topic_id TEXT NOT NULL,
@@ -378,34 +389,34 @@ function initializeApiMessagesSchema() {
378
389
  )
379
390
  `);
380
391
  try {
381
- storageDatabase.exec("ALTER TABLE api_messages ADD COLUMN source_adapter TEXT");
392
+ db.exec("ALTER TABLE api_messages ADD COLUMN source_adapter TEXT");
382
393
  } catch {}
383
394
  try {
384
- storageDatabase.exec("ALTER TABLE api_messages ADD COLUMN deleted INTEGER NOT NULL DEFAULT 0");
395
+ db.exec("ALTER TABLE api_messages ADD COLUMN deleted INTEGER NOT NULL DEFAULT 0");
385
396
  } catch {}
386
397
  try {
387
- storageDatabase.exec("ALTER TABLE api_messages ADD COLUMN edited_at TEXT");
398
+ db.exec("ALTER TABLE api_messages ADD COLUMN edited_at TEXT");
388
399
  } catch {}
389
400
  try {
390
- storageDatabase.exec("ALTER TABLE api_messages ADD COLUMN reactions TEXT");
401
+ db.exec("ALTER TABLE api_messages ADD COLUMN reactions TEXT");
391
402
  } catch {}
392
403
  try {
393
- storageDatabase.exec("ALTER TABLE api_messages ADD COLUMN kind TEXT");
404
+ db.exec("ALTER TABLE api_messages ADD COLUMN kind TEXT");
394
405
  } catch {}
395
406
  try {
396
- storageDatabase.exec("ALTER TABLE api_messages ADD COLUMN ask_user_question TEXT");
407
+ db.exec("ALTER TABLE api_messages ADD COLUMN ask_user_question TEXT");
397
408
  } catch {}
398
409
  try {
399
- storageDatabase.exec("ALTER TABLE api_messages ADD COLUMN mentions TEXT");
410
+ db.exec("ALTER TABLE api_messages ADD COLUMN mentions TEXT");
400
411
  } catch {}
401
412
  try {
402
- storageDatabase.exec("ALTER TABLE api_messages ADD COLUMN thread_root_id TEXT");
413
+ db.exec("ALTER TABLE api_messages ADD COLUMN thread_root_id TEXT");
403
414
  } catch {}
404
415
  try {
405
- storageDatabase.exec("ALTER TABLE api_messages ADD COLUMN subagent_card TEXT");
416
+ db.exec("ALTER TABLE api_messages ADD COLUMN subagent_card TEXT");
406
417
  } catch {}
407
- storageDatabase.exec("CREATE INDEX IF NOT EXISTS idx_api_messages_topic ON api_messages(topic_id)");
408
- storageDatabase.exec("CREATE INDEX IF NOT EXISTS idx_api_messages_thread_root ON api_messages(thread_root_id)");
418
+ db.exec("CREATE INDEX IF NOT EXISTS idx_api_messages_topic ON api_messages(topic_id)");
419
+ db.exec("CREATE INDEX IF NOT EXISTS idx_api_messages_thread_root ON api_messages(thread_root_id)");
409
420
  }
410
421
  registerStorageSchemaInitializer(initializeApiMessagesSchema, 30);
411
422
  var appendHooks = new Set;
@@ -537,4 +548,4 @@ export {
537
548
  MERMAID_BROWSER_ASSET_PATH
538
549
  };
539
550
 
540
- //# debugId=BE4405D4EC79C76A64756E2164756E21
551
+ //# debugId=B54B49179ACB3E0164756E2164756E21