negotium 0.2.18 → 0.2.20

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 (55) hide show
  1. package/dist/agent-helpers.js +367 -313
  2. package/dist/agent-helpers.js.map +18 -18
  3. package/dist/background-bash.js +3 -2
  4. package/dist/background-bash.js.map +3 -3
  5. package/dist/browser-runtime.js +60 -36
  6. package/dist/browser-runtime.js.map +6 -6
  7. package/dist/{chunk-fc58cqry.js → chunk-g2kqfdwm.js} +154 -24
  8. package/dist/{chunk-fc58cqry.js.map → chunk-g2kqfdwm.js.map} +7 -6
  9. package/dist/hosted-agent.js +183 -53
  10. package/dist/hosted-agent.js.map +8 -7
  11. package/dist/main.js +1395 -626
  12. package/dist/main.js.map +27 -26
  13. package/dist/mcp-factories.js +1204 -624
  14. package/dist/mcp-factories.js.map +21 -20
  15. package/dist/prompts.js +3 -2
  16. package/dist/prompts.js.map +3 -3
  17. package/dist/query-runtime.js +47 -26
  18. package/dist/query-runtime.js.map +4 -4
  19. package/dist/registry.js +3 -3
  20. package/dist/registry.js.map +2 -2
  21. package/dist/rollout.js +1 -1
  22. package/dist/runtime/src/agents/archiver.ts +4 -3
  23. package/dist/runtime/src/application/switch-topic-access-mode.ts +81 -8
  24. package/dist/runtime/src/bus.ts +19 -2
  25. package/dist/runtime/src/mcp/canonical-proxy-server.ts +13 -14
  26. package/dist/runtime/src/mcp/session-comm/runtime.ts +16 -0
  27. package/dist/runtime/src/mcp/wiki-search-index.ts +359 -0
  28. package/dist/runtime/src/mcp/wiki-server.ts +559 -98
  29. package/dist/runtime/src/platform/config.ts +13 -1
  30. package/dist/runtime/src/platform/mcp-config.ts +1 -1
  31. package/dist/runtime/src/prompts/agents/wiki-archiver.md +62 -47
  32. package/dist/runtime/src/runtime/ask-callbacks.ts +19 -11
  33. package/dist/runtime/src/runtime/background-sessions.ts +9 -7
  34. package/dist/runtime/src/runtime/visual-store.ts +31 -23
  35. package/dist/runtime/src/storage/api-topics.ts +26 -0
  36. package/dist/runtime/src/storage/browser-profiles.ts +16 -8
  37. package/dist/runtime/src/storage/runtime-events.ts +30 -20
  38. package/dist/runtime/src/storage/runtime-gateway-submissions.ts +24 -16
  39. package/dist/runtime/src/storage/runtime-turn-requests.ts +9 -1
  40. package/dist/runtime/src/storage/self-schedules.ts +32 -24
  41. package/dist/runtime/src/storage/storage-host.ts +105 -43
  42. package/dist/runtime/src/storage/vault.ts +12 -3
  43. package/dist/runtime/src/version.ts +1 -1
  44. package/dist/runtime-helpers.js +47 -26
  45. package/dist/runtime-helpers.js.map +4 -4
  46. package/dist/storage.js +76 -41
  47. package/dist/storage.js.map +4 -4
  48. package/dist/types/packages/core/src/agents/archiver.d.ts +1 -1
  49. package/dist/types/packages/core/src/mcp/wiki-search-index.d.ts +59 -0
  50. package/dist/types/packages/core/src/storage/api-topics.d.ts +15 -0
  51. package/dist/types/packages/core/src/storage/storage-host.d.ts +10 -0
  52. package/dist/types/packages/core/src/version.d.ts +1 -1
  53. package/dist/vault.js +140 -10
  54. package/dist/vault.js.map +6 -5
  55. package/package.json +1 -1
@@ -230,7 +230,7 @@ function browserRsMeetsMinimumVersion(candidate) {
230
230
  try {
231
231
  const output = execFileSync(candidate, ["--version"], {
232
232
  encoding: "utf8",
233
- timeout: 2000,
233
+ timeout: BROWSER_RS_VERSION_PROBE_TIMEOUT_MS,
234
234
  stdio: ["ignore", "pipe", "ignore"]
235
235
  }).trim();
236
236
  const match = output.match(/^browser-rs (\d+)\.(\d+)\.(\d+)$/);
@@ -341,7 +341,7 @@ function resolveDefaultModel(agent, registryDefaultModel) {
341
341
  function codexAuthFilePath() {
342
342
  return process.env.NEGOTIUM_CODEX_AUTH_FILE || join(process.env.CODEX_HOME || join(homedir(), ".codex"), "auth.json");
343
343
  }
344
- var HOME, PROJECT_ROOT, STATE_DIR_ENV, STATE_DIR, WORKSPACE_DIR, TOPIC_WORKSPACE_DIR, SHARED_WIKI_DIR, CRON_WORKSPACE_DIR, BROWSER_DIR, BROWSER_PROFILES_DIR, BINARIES_DIR, SECRETS_DIR, DM_WORKSPACE_DIR, SESSION_WORKSPACE_DIR, CLAUDE_EXECUTABLE_ENV, CLAUDE_EXECUTABLE, DEFAULT_OUTPUT_LANGUAGE = "English", BROWSER_RS_VERSION = "v0.1.19", BROWSER_RS_MIN_SECURE_VERSION = "0.1.15", SNIPPETS_API_URL, BROWSER_RS_BIN, BASH_RS_VERSION = "v0.1.5", BASH_RS_BIN, PLAYWRIGHT_MCP_BIN, TSX_BIN, TSX_LOADER, TSCONFIG_PATH, SESSION_COMM_SERVER, TASK_SERVER, BROWSER_MCP_SSE_PROXY_SERVER, CANONICAL_MCP_PROXY_SERVER, WIKI_SERVER, TOKEN_STATS_SERVER, COMPACTION_LOG_SERVER, SYSTEM_HEALTH_SERVER, AGENT_HEALTH_SERVER, VAULT_SERVER, BG_BASH_BASE_PORT, BG_BASH_MAX_PORT, RUNTIME_MCP_SECRET, NODE_CONTROL_TOKEN, VAULT_MASTER_KEY, NEGOTIUM_PORT, hostname, DATA_DIR, LOG_DIR, UPLOADS_DIR, VAULT_DIR, SESSIONS_DB, DEBUG_FILE, USERS_LOG_DIR, RUN_DIR, PROGRESS_DIR, DM_CMD_DIR, DM_RESP_DIR, SESSION_INBOX_DIR, SESSION_ASKS_DIR, BASHRS_SPILL_ROOT, PLAYWRIGHT_BASE_PORT, PLAYWRIGHT_MAX_PORT, PLAYWRIGHT_PORTS_DIR, ACTIVE_QUERY_STALE_MS, AGENTS_PROMPTS_DIR, RESOURCES_DIR, FILE_TAG_REGEX, MODEL_SONNET = "claude-sonnet-5", MODEL_OPUS = "claude-opus-5", MODEL_FABLE = "claude-fable-5", FALLBACK_AGENT, SESSION_AGENT, GATEWAY_AGENT, FALLBACK_MODEL, SESSION_MODEL, GATEWAY_MODEL, FFMPEG_BIN, FFPROBE_BIN, PYTHON_BIN, FASTER_WHISPER_WRAPPER, WHISPER_MODEL, TESSERACT_BIN, PDFTOTEXT_BIN, _envMaxTellDepth, MAX_TELL_DEPTH;
344
+ var HOME, PROJECT_ROOT, STATE_DIR_ENV, STATE_DIR, WORKSPACE_DIR, TOPIC_WORKSPACE_DIR, SHARED_WIKI_DIR, CRON_WORKSPACE_DIR, BROWSER_DIR, BROWSER_PROFILES_DIR, BINARIES_DIR, SECRETS_DIR, DM_WORKSPACE_DIR, SESSION_WORKSPACE_DIR, CLAUDE_EXECUTABLE_ENV, CLAUDE_EXECUTABLE, DEFAULT_OUTPUT_LANGUAGE = "English", BROWSER_RS_VERSION = "v0.1.19", BROWSER_RS_MIN_SECURE_VERSION = "0.1.15", BROWSER_RS_VERSION_PROBE_TIMEOUT_MS = 15000, SNIPPETS_API_URL, BROWSER_RS_BIN, BASH_RS_VERSION = "v0.1.5", BASH_RS_BIN, PLAYWRIGHT_MCP_BIN, TSX_BIN, TSX_LOADER, TSCONFIG_PATH, SESSION_COMM_SERVER, TASK_SERVER, BROWSER_MCP_SSE_PROXY_SERVER, CANONICAL_MCP_PROXY_SERVER, WIKI_SERVER, TOKEN_STATS_SERVER, COMPACTION_LOG_SERVER, SYSTEM_HEALTH_SERVER, AGENT_HEALTH_SERVER, VAULT_SERVER, BG_BASH_BASE_PORT, BG_BASH_MAX_PORT, RUNTIME_MCP_SECRET, NODE_CONTROL_TOKEN, VAULT_MASTER_KEY, NEGOTIUM_PORT, hostname, DATA_DIR, LOG_DIR, UPLOADS_DIR, VAULT_DIR, SESSIONS_DB, DEBUG_FILE, USERS_LOG_DIR, RUN_DIR, PROGRESS_DIR, DM_CMD_DIR, DM_RESP_DIR, SESSION_INBOX_DIR, SESSION_ASKS_DIR, BASHRS_SPILL_ROOT, PLAYWRIGHT_BASE_PORT, PLAYWRIGHT_MAX_PORT, PLAYWRIGHT_PORTS_DIR, ACTIVE_QUERY_STALE_MS, AGENTS_PROMPTS_DIR, RESOURCES_DIR, FILE_TAG_REGEX, MODEL_SONNET = "claude-sonnet-5", MODEL_OPUS = "claude-opus-5", MODEL_FABLE = "claude-fable-5", FALLBACK_AGENT, SESSION_AGENT, GATEWAY_AGENT, FALLBACK_MODEL, SESSION_MODEL, GATEWAY_MODEL, FFMPEG_BIN, FFPROBE_BIN, PYTHON_BIN, FASTER_WHISPER_WRAPPER, WHISPER_MODEL, TESSERACT_BIN, PDFTOTEXT_BIN, _envMaxTellDepth, MAX_TELL_DEPTH;
345
345
  var init_config = __esm(() => {
346
346
  init_config_helpers();
347
347
  init_logger();
@@ -1423,6 +1423,163 @@ var init_sqlite = __esm(async () => {
1423
1423
  }
1424
1424
  });
1425
1425
 
1426
+ // ../../packages/core/src/storage/storage-host.ts
1427
+ import { mkdirSync as mkdirSync2 } from "fs";
1428
+ import { homedir as homedir2 } from "os";
1429
+ import { dirname as dirname2, join as join2, resolve as resolve3 } from "path";
1430
+ function storageState() {
1431
+ const holder = globalThis;
1432
+ const existing = holder[STORAGE_HOST_STATE];
1433
+ if (existing)
1434
+ return existing;
1435
+ const created = {
1436
+ configuredHost: {},
1437
+ fallbackDatabase: null,
1438
+ fallbackDatabasePath: null,
1439
+ frames: [],
1440
+ schemaInitializers: [],
1441
+ initializedSchemas: new WeakMap,
1442
+ initializingDatabases: new WeakSet
1443
+ };
1444
+ Object.defineProperty(holder, STORAGE_HOST_STATE, {
1445
+ value: created,
1446
+ enumerable: false,
1447
+ writable: false,
1448
+ configurable: false
1449
+ });
1450
+ return created;
1451
+ }
1452
+ function envPath(name, fallback) {
1453
+ const value = process.env[name]?.trim();
1454
+ return resolve3(value || fallback);
1455
+ }
1456
+ function defaultStateDir() {
1457
+ return envPath("NEGOTIUM_STATE_DIR", join2(homedir2(), ".negotium"));
1458
+ }
1459
+ function defaultDataDir() {
1460
+ return envPath("NEGOTIUM_DATA_DIR", join2(defaultStateDir(), "data"));
1461
+ }
1462
+ function defaultLogDir() {
1463
+ return envPath("NEGOTIUM_LOG_DIR", join2(defaultStateDir(), "logs"));
1464
+ }
1465
+ function defaultWorkspaceDir() {
1466
+ return envPath("NEGOTIUM_WORKSPACE_DIR", join2(defaultStateDir(), "workspace"));
1467
+ }
1468
+ function defaultSessionAsksDir() {
1469
+ const runDir = envPath("NEGOTIUM_RUN_DIR", join2(defaultStateDir(), "runtime"));
1470
+ return join2(runDir, "session-asks");
1471
+ }
1472
+ function defaultSessionsDatabasePath() {
1473
+ return envPath("SESSIONS_DB_PATH", join2(resolveStorageDataDir(), "sessions.db"));
1474
+ }
1475
+ function isSqliteBusy(error) {
1476
+ const message = error instanceof Error ? error.message : String(error);
1477
+ return /database is (?:locked|busy)|SQLITE_(?:BUSY|LOCKED)/i.test(message);
1478
+ }
1479
+ function execWithBusyRetry(database, sql, timeoutMs = SQLITE_INIT_TIMEOUT_MS) {
1480
+ const deadline = Date.now() + timeoutMs;
1481
+ while (true) {
1482
+ try {
1483
+ database.exec(sql);
1484
+ return;
1485
+ } catch (error) {
1486
+ if (!isSqliteBusy(error) || Date.now() >= deadline)
1487
+ throw error;
1488
+ Atomics.wait(SQLITE_INIT_SLEEP, 0, 0, Math.min(SQLITE_INIT_RETRY_MS, deadline - Date.now()));
1489
+ }
1490
+ }
1491
+ }
1492
+ function initializeDatabase(database) {
1493
+ database.exec("PRAGMA busy_timeout = 5000");
1494
+ execWithBusyRetry(database, "PRAGMA journal_mode = WAL");
1495
+ database.exec("PRAGMA foreign_keys = ON");
1496
+ database.exec("PRAGMA wal_autocheckpoint = 1000");
1497
+ try {
1498
+ database.exec("PRAGMA wal_checkpoint(TRUNCATE)");
1499
+ } catch {}
1500
+ }
1501
+ function defaultDatabase() {
1502
+ const path = defaultSessionsDatabasePath();
1503
+ const state = storageState();
1504
+ if (state.fallbackDatabase && state.fallbackDatabasePath === path)
1505
+ return state.fallbackDatabase;
1506
+ if (state.fallbackDatabase)
1507
+ state.fallbackDatabase.close();
1508
+ mkdirSync2(dirname2(path), { recursive: true });
1509
+ state.fallbackDatabase = new Database(path, { create: true });
1510
+ state.fallbackDatabasePath = path;
1511
+ initializeDatabase(state.fallbackDatabase);
1512
+ return state.fallbackDatabase;
1513
+ }
1514
+ function resolveStorageDatabase() {
1515
+ return storageState().configuredHost.database ?? defaultDatabase();
1516
+ }
1517
+ function resolveStorageDataDir() {
1518
+ return storageState().configuredHost.dataDir ?? defaultDataDir();
1519
+ }
1520
+ function resolveStorageLogDir() {
1521
+ return storageState().configuredHost.logDir ?? defaultLogDir();
1522
+ }
1523
+ function resolveStorageSessionAsksDir() {
1524
+ return storageState().configuredHost.sessionAsksDir ?? defaultSessionAsksDir();
1525
+ }
1526
+ function resolveStorageWorkspaceDir() {
1527
+ return storageState().configuredHost.workspaceDir ?? defaultWorkspaceDir();
1528
+ }
1529
+ function resolveStorageSharedWikiDir() {
1530
+ return storageState().configuredHost.sharedWikiDir ?? join2(resolveStorageWorkspaceDir(), "wiki");
1531
+ }
1532
+ function registerStorageSchemaInitializer(initialize, priority = 100) {
1533
+ const initializers = storageState().schemaInitializers;
1534
+ initializers.push({ initialize, priority });
1535
+ initializers.sort((a, b) => a.priority - b.priority);
1536
+ }
1537
+ function ensureStorageSchemas(database = resolveStorageDatabase()) {
1538
+ const state = storageState();
1539
+ if (state.initializingDatabases.has(database))
1540
+ return;
1541
+ let initialized = state.initializedSchemas.get(database);
1542
+ if (!initialized) {
1543
+ initialized = new Set;
1544
+ state.initializedSchemas.set(database, initialized);
1545
+ }
1546
+ state.initializingDatabases.add(database);
1547
+ try {
1548
+ for (const entry of state.schemaInitializers) {
1549
+ if (initialized.has(entry.initialize))
1550
+ continue;
1551
+ initialized.add(entry.initialize);
1552
+ try {
1553
+ entry.initialize(database);
1554
+ } catch (error) {
1555
+ initialized.delete(entry.initialize);
1556
+ throw error;
1557
+ }
1558
+ }
1559
+ } finally {
1560
+ state.initializingDatabases.delete(database);
1561
+ }
1562
+ }
1563
+ var STORAGE_HOST_STATE, SQLITE_INIT_RETRY_MS = 25, SQLITE_INIT_TIMEOUT_MS = 5000, SQLITE_INIT_SLEEP, internalStorageDatabase;
1564
+ var init_storage_host = __esm(async () => {
1565
+ await init_sqlite();
1566
+ STORAGE_HOST_STATE = Symbol.for("negotium.storage-host.state.v1");
1567
+ SQLITE_INIT_SLEEP = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
1568
+ internalStorageDatabase = new Proxy({}, {
1569
+ get(_target, property) {
1570
+ const database = resolveStorageDatabase();
1571
+ ensureStorageSchemas(database);
1572
+ const value = Reflect.get(database, property, database);
1573
+ return typeof value === "function" ? value.bind(database) : value;
1574
+ },
1575
+ set(_target, property, value) {
1576
+ const database = resolveStorageDatabase();
1577
+ ensureStorageSchemas(database);
1578
+ return Reflect.set(database, property, value, database);
1579
+ }
1580
+ });
1581
+ });
1582
+
1426
1583
  // ../../packages/core/src/storage/vault-crypto-core.ts
1427
1584
  import { createCipheriv, createDecipheriv, createHash as createHash2, randomBytes as randomBytes3 } from "crypto";
1428
1585
  function encryptionKey(masterKey) {
@@ -1479,8 +1636,8 @@ var init_vault_crypto = __esm(() => {
1479
1636
  });
1480
1637
 
1481
1638
  // ../../packages/core/src/storage/vault.ts
1482
- import { chmodSync as chmodSync2, mkdirSync as mkdirSync2 } from "fs";
1483
- import { join as join2 } from "path";
1639
+ import { chmodSync as chmodSync2, mkdirSync as mkdirSync3 } from "fs";
1640
+ import { join as join3 } from "path";
1484
1641
  function initializeVaultDatabase(database) {
1485
1642
  database.exec("PRAGMA journal_mode = WAL");
1486
1643
  database.exec("PRAGMA busy_timeout = 5000");
@@ -1515,17 +1672,18 @@ function initializeVaultDatabase(database) {
1515
1672
  }
1516
1673
  }
1517
1674
  function openVaultDatabase(dataDir) {
1518
- const vaultDir = join2(dataDir, "vault");
1519
- const path = join2(vaultDir, "vault.db");
1520
- mkdirSync2(vaultDir, { recursive: true, mode: 448 });
1675
+ const vaultDir = join3(dataDir, "vault");
1676
+ const path = join3(vaultDir, "vault.db");
1677
+ mkdirSync3(vaultDir, { recursive: true, mode: 448 });
1521
1678
  const database = new Database(path, { create: true });
1522
1679
  chmodSync2(path, 384);
1523
1680
  initializeVaultDatabase(database);
1524
1681
  return database;
1525
1682
  }
1526
1683
  function activeVaultDatabase() {
1527
- if (!vaultDb)
1528
- vaultDb = openVaultDatabase(DATA_DIR);
1684
+ if (!vaultDb) {
1685
+ vaultDb = openVaultDatabase(resolveStorageDataDir());
1686
+ }
1529
1687
  return vaultDb;
1530
1688
  }
1531
1689
  function normalizeVaultKey(key) {
@@ -1615,14 +1773,17 @@ var vaultDb, vaultMasterKey, VAULT_VALUE_MAX_BYTES;
1615
1773
  var init_vault = __esm(async () => {
1616
1774
  init_config();
1617
1775
  init_vault_crypto();
1618
- await init_sqlite();
1776
+ await __promiseAll([
1777
+ init_sqlite(),
1778
+ init_storage_host()
1779
+ ]);
1619
1780
  vaultMasterKey = VAULT_MASTER_KEY;
1620
1781
  VAULT_VALUE_MAX_BYTES = 64 * 1024;
1621
1782
  });
1622
1783
 
1623
1784
  // ../../packages/core/src/agents/execution-host.ts
1624
1785
  import { AsyncLocalStorage } from "async_hooks";
1625
- import { dirname as dirname2 } from "path";
1786
+ import { dirname as dirname3 } from "path";
1626
1787
  function activeHost() {
1627
1788
  const scoped = scopedHost.getStore();
1628
1789
  if (scoped)
@@ -1657,7 +1818,7 @@ function hostedCodexAuthFilePath() {
1657
1818
  return activeHost().codexAuthFilePath();
1658
1819
  }
1659
1820
  function hostedCodexHomePath() {
1660
- return dirname2(hostedCodexAuthFilePath());
1821
+ return dirname3(hostedCodexAuthFilePath());
1661
1822
  }
1662
1823
  var defaultHost, hostRegistrations, scopedHost;
1663
1824
  var init_execution_host = __esm(async () => {
@@ -1706,8 +1867,8 @@ function renderUserTurnBatch(messages) {
1706
1867
  }
1707
1868
 
1708
1869
  // ../../packages/core/src/agents/rollout/shared.ts
1709
- import { mkdirSync as mkdirSync3 } from "fs";
1710
- import { resolve as resolve3 } from "path";
1870
+ import { mkdirSync as mkdirSync4 } from "fs";
1871
+ import { resolve as resolve4 } from "path";
1711
1872
  function clone(obj) {
1712
1873
  return structuredClone(obj);
1713
1874
  }
@@ -1717,7 +1878,7 @@ function assertUuidLike(label, value) {
1717
1878
  }
1718
1879
  }
1719
1880
  function assertCwdInWorkspace(cwd) {
1720
- const abs = resolve3(cwd);
1881
+ const abs = resolve4(cwd);
1721
1882
  const ok = trustedWorkspaceRoots.some((root) => abs === root || abs.startsWith(`${root}/`));
1722
1883
  if (!ok) {
1723
1884
  throw new Error(`rollout: cwd outside trusted workspace roots: ${cwd} (resolved=${abs})`);
@@ -1726,7 +1887,7 @@ function assertCwdInWorkspace(cwd) {
1726
1887
  function ensureCwdExists(cwd) {
1727
1888
  assertCwdInWorkspace(cwd);
1728
1889
  try {
1729
- mkdirSync3(cwd, { recursive: true });
1890
+ mkdirSync4(cwd, { recursive: true });
1730
1891
  } catch (err) {
1731
1892
  logger.warn({ err, cwd }, "rollout: ensureCwdExists failed \u2014 caller should pre-create cwd");
1732
1893
  }
@@ -1847,8 +2008,8 @@ var init_shared = __esm(() => {
1847
2008
  DM_WORKSPACE_DIR,
1848
2009
  SESSION_WORKSPACE_DIR,
1849
2010
  TOPIC_WORKSPACE_DIR
1850
- ].map((root) => resolve3(root));
1851
- FIXTURES_DIR = resolve3(PROJECT_ROOT, "src", "agents", "fixtures");
2011
+ ].map((root) => resolve4(root));
2012
+ FIXTURES_DIR = resolve4(PROJECT_ROOT, "src", "agents", "fixtures");
1852
2013
  UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1853
2014
  });
1854
2015
 
@@ -1883,7 +2044,7 @@ import {
1883
2044
  appendFileSync,
1884
2045
  closeSync,
1885
2046
  fsyncSync,
1886
- mkdirSync as mkdirSync4,
2047
+ mkdirSync as mkdirSync5,
1887
2048
  openSync,
1888
2049
  readFileSync as readFileSync2,
1889
2050
  renameSync,
@@ -1891,7 +2052,7 @@ import {
1891
2052
  unlinkSync as unlinkSync2,
1892
2053
  writeFileSync as writeFileSync2
1893
2054
  } from "fs";
1894
- import { dirname as dirname3 } from "path";
2055
+ import { dirname as dirname4 } from "path";
1895
2056
  function parseJsonlText(raw) {
1896
2057
  return raw.trim().split(`
1897
2058
  `).filter(Boolean).map((line) => JSON.parse(line));
@@ -1928,7 +2089,7 @@ function appendJsonlEntry(filePath, entry) {
1928
2089
  `);
1929
2090
  }
1930
2091
  function appendJsonlLine(filePath, line) {
1931
- mkdirSync4(dirname3(filePath), { recursive: true });
2092
+ mkdirSync5(dirname4(filePath), { recursive: true });
1932
2093
  const lockPath = `${filePath}${LOCK_SUFFIX}`;
1933
2094
  const payload = line.endsWith(`
1934
2095
  `) ? line : `${line}
@@ -1959,8 +2120,8 @@ function appendJsonlLine(filePath, line) {
1959
2120
  }
1960
2121
  }
1961
2122
  function writeJsonlFile(filePath, entries) {
1962
- const dir = dirname3(filePath);
1963
- mkdirSync4(dir, { recursive: true });
2123
+ const dir = dirname4(filePath);
2124
+ mkdirSync5(dir, { recursive: true });
1964
2125
  const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
1965
2126
  const payload = `${entries.map((e) => JSON.stringify(e)).join(`
1966
2127
  `)}
@@ -2018,12 +2179,12 @@ var init_jsonl = __esm(() => {
2018
2179
  // ../../packages/core/src/agents/rollout/claude.ts
2019
2180
  import { randomUUID } from "crypto";
2020
2181
  import { existsSync as existsSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
2021
- import { homedir as homedir2 } from "os";
2022
- import { join as join3 } from "path";
2182
+ import { homedir as homedir3 } from "os";
2183
+ import { join as join4 } from "path";
2023
2184
  function loadClaudeAttachments() {
2024
2185
  if (_attachmentsCache)
2025
2186
  return _attachmentsCache;
2026
- const raw = readFileSync3(join3(FIXTURES_DIR, "claude-attachments.jsonl"), "utf8");
2187
+ const raw = readFileSync3(join4(FIXTURES_DIR, "claude-attachments.jsonl"), "utf8");
2027
2188
  const lines = parseJsonlText(raw);
2028
2189
  if (lines.length < 2) {
2029
2190
  throw new Error(`loadClaudeAttachments: expected >=2 entries in claude-attachments.jsonl, got ${lines.length}`);
@@ -2124,8 +2285,8 @@ function writeClaudeRollout(opts) {
2124
2285
  });
2125
2286
  lastUuid = assistantUuid;
2126
2287
  }
2127
- const projectsDir = join3(homedir2(), ".claude", "projects", encodeClaudeCwd(opts.cwd));
2128
- const path = join3(projectsDir, `${sessionId}.jsonl`);
2288
+ const projectsDir = join4(homedir3(), ".claude", "projects", encodeClaudeCwd(opts.cwd));
2289
+ const path = join4(projectsDir, `${sessionId}.jsonl`);
2129
2290
  writeJsonlFile(path, lines);
2130
2291
  logger.info({ sessionId, path, pairs: pairs.length }, "writeClaudeRollout: synthetic rollout placed");
2131
2292
  return { sessionId, rolloutPath: path };
@@ -2138,9 +2299,9 @@ var init_claude = __esm(() => {
2138
2299
  });
2139
2300
 
2140
2301
  // ../../packages/core/src/agents/claude-registry.ts
2141
- import { existsSync as existsSync3, mkdirSync as mkdirSync5, readdirSync, renameSync as renameSync2, unlinkSync as unlinkSync3 } from "fs";
2142
- import { homedir as homedir3 } from "os";
2143
- import { join as join4 } from "path";
2302
+ import { existsSync as existsSync3, mkdirSync as mkdirSync6, readdirSync, renameSync as renameSync2, unlinkSync as unlinkSync3 } from "fs";
2303
+ import { homedir as homedir4 } from "os";
2304
+ import { join as join5 } from "path";
2144
2305
  var ALIAS_MAP, VALID_ALIASES, VALID_EFFORTS, claudeRegistry, claudeRegistryOperations;
2145
2306
  var init_claude_registry = __esm(() => {
2146
2307
  init_claude();
@@ -2187,15 +2348,15 @@ var init_claude_registry = __esm(() => {
2187
2348
  const result = await forkSession(parentSessionId, {
2188
2349
  ...title ? { title } : {}
2189
2350
  });
2190
- const projectsRoot = join4(homedir3(), ".claude", "projects");
2191
- const destDir = join4(projectsRoot, encodeClaudeCwd(cwd));
2192
- const destPath = join4(destDir, `${result.sessionId}.jsonl`);
2351
+ const projectsRoot = join5(homedir4(), ".claude", "projects");
2352
+ const destDir = join5(projectsRoot, encodeClaudeCwd(cwd));
2353
+ const destPath = join5(destDir, `${result.sessionId}.jsonl`);
2193
2354
  if (!existsSync3(destPath)) {
2194
- const sourcePath = readdirSync(projectsRoot).map((d) => join4(projectsRoot, d, `${result.sessionId}.jsonl`)).find((p) => existsSync3(p));
2355
+ const sourcePath = readdirSync(projectsRoot).map((d) => join5(projectsRoot, d, `${result.sessionId}.jsonl`)).find((p) => existsSync3(p));
2195
2356
  if (!sourcePath) {
2196
2357
  throw new Error(`claude forkSession: fork rollout ${result.sessionId}.jsonl not found under ${projectsRoot}`);
2197
2358
  }
2198
- mkdirSync5(destDir, { recursive: true });
2359
+ mkdirSync6(destDir, { recursive: true });
2199
2360
  renameSync2(sourcePath, destPath);
2200
2361
  }
2201
2362
  return {
@@ -2204,10 +2365,10 @@ var init_claude_registry = __esm(() => {
2204
2365
  };
2205
2366
  },
2206
2367
  async cleanupRollouts({ cwd, sessionIds }) {
2207
- const projectsDir = join4(homedir3(), ".claude", "projects", encodeClaudeCwd(cwd));
2368
+ const projectsDir = join5(homedir4(), ".claude", "projects", encodeClaudeCwd(cwd));
2208
2369
  const failures = [];
2209
2370
  for (const sid of sessionIds) {
2210
- const path = join4(projectsDir, `${sid}.jsonl`);
2371
+ const path = join5(projectsDir, `${sid}.jsonl`);
2211
2372
  try {
2212
2373
  unlinkSync3(path);
2213
2374
  } catch (e) {
@@ -2225,7 +2386,7 @@ var init_claude_registry = __esm(() => {
2225
2386
  });
2226
2387
 
2227
2388
  // ../../packages/core/src/version.ts
2228
- var NEGOTIUM_VERSION = "0.2.18";
2389
+ var NEGOTIUM_VERSION = "0.2.20";
2229
2390
 
2230
2391
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
2231
2392
  import { spawn as spawn2 } from "child_process";
@@ -2243,7 +2404,7 @@ import {
2243
2404
  } from "fs";
2244
2405
  import { createRequire as createRequire2 } from "module";
2245
2406
  import { tmpdir } from "os";
2246
- import { dirname as dirname4, join as join5 } from "path";
2407
+ import { dirname as dirname5, join as join6 } from "path";
2247
2408
  function readPackageVersion(packageJsonPath) {
2248
2409
  const parsed = JSON.parse(readFileSync4(packageJsonPath, "utf8"));
2249
2410
  if (typeof parsed.version !== "string" || !parsed.version.trim()) {
@@ -2252,7 +2413,7 @@ function readPackageVersion(packageJsonPath) {
2252
2413
  return parsed.version;
2253
2414
  }
2254
2415
  function codexCliScriptPath() {
2255
- return join5(dirname4(bundledCodexPackagePath), "bin", "codex.js");
2416
+ return join6(dirname5(bundledCodexPackagePath), "bin", "codex.js");
2256
2417
  }
2257
2418
  function parseCodexModelCache(contents, sourcePath) {
2258
2419
  let parsed;
@@ -2293,14 +2454,14 @@ function writePrivateFileAtomic(path, contents) {
2293
2454
  }
2294
2455
  }
2295
2456
  function bundledCodexModelCachePath(authFilePath) {
2296
- return join5(dirname4(authFilePath), NEGOTIUM_MODEL_CACHE);
2457
+ return join6(dirname5(authFilePath), NEGOTIUM_MODEL_CACHE);
2297
2458
  }
2298
2459
  async function bootstrapCodexModelCache(codexHome, cachePath) {
2299
2460
  const child = spawn2(process.execPath, [codexCliScriptPath(), "app-server", "--stdio"], {
2300
2461
  env: { ...process.env, CODEX_HOME: codexHome },
2301
2462
  stdio: ["pipe", "pipe", "pipe"]
2302
2463
  });
2303
- await new Promise((resolve4, reject) => {
2464
+ await new Promise((resolve5, reject) => {
2304
2465
  let settled = false;
2305
2466
  let stdoutBuffer = "";
2306
2467
  let stderr = "";
@@ -2319,7 +2480,7 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
2319
2480
  else if (!existsSync4(cachePath))
2320
2481
  reject(new Error("Codex did not create its model cache"));
2321
2482
  else
2322
- resolve4();
2483
+ resolve5();
2323
2484
  };
2324
2485
  const send = (message) => {
2325
2486
  child.stdin.write(`${JSON.stringify(message)}
@@ -2378,16 +2539,16 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
2378
2539
  });
2379
2540
  }
2380
2541
  async function bootstrapIsolatedCodexModelCache(authFilePath, bootstrap) {
2381
- const sourceHome = dirname4(authFilePath);
2382
- const isolatedHome = mkdtempSync(join5(tmpdir(), "negotium-codex-models-"));
2383
- const isolatedCachePath = join5(isolatedHome, "models_cache.json");
2542
+ const sourceHome = dirname5(authFilePath);
2543
+ const isolatedHome = mkdtempSync(join6(tmpdir(), "negotium-codex-models-"));
2544
+ const isolatedCachePath = join6(isolatedHome, "models_cache.json");
2384
2545
  try {
2385
- const isolatedAuthPath = join5(isolatedHome, "auth.json");
2546
+ const isolatedAuthPath = join6(isolatedHome, "auth.json");
2386
2547
  copyFileSync(authFilePath, isolatedAuthPath);
2387
2548
  chmodSync3(isolatedAuthPath, 384);
2388
- const sourceConfigPath = join5(sourceHome, "config.toml");
2549
+ const sourceConfigPath = join6(sourceHome, "config.toml");
2389
2550
  if (existsSync4(sourceConfigPath)) {
2390
- const isolatedConfigPath = join5(isolatedHome, "config.toml");
2551
+ const isolatedConfigPath = join6(isolatedHome, "config.toml");
2391
2552
  copyFileSync(sourceConfigPath, isolatedConfigPath);
2392
2553
  chmodSync3(isolatedConfigPath, 384);
2393
2554
  }
@@ -2398,7 +2559,7 @@ async function bootstrapIsolatedCodexModelCache(authFilePath, bootstrap) {
2398
2559
  }
2399
2560
  }
2400
2561
  async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexModelCache) {
2401
- const codexHome = dirname4(authFilePath);
2562
+ const codexHome = dirname5(authFilePath);
2402
2563
  const configuredCachePath = process.env.NEGOTIUM_CODEX_MODELS_CACHE_FILE;
2403
2564
  if (configuredCachePath) {
2404
2565
  if (!existsSync4(configuredCachePath)) {
@@ -2408,7 +2569,7 @@ async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexMod
2408
2569
  return configuredCachePath;
2409
2570
  }
2410
2571
  const bundledCachePath = bundledCodexModelCachePath(authFilePath);
2411
- const sharedCachePath = join5(codexHome, "models_cache.json");
2572
+ const sharedCachePath = join6(codexHome, "models_cache.json");
2412
2573
  if (existsSync4(sharedCachePath)) {
2413
2574
  try {
2414
2575
  const shared = readCompatibleCodexModelCache(sharedCachePath);
@@ -2427,8 +2588,8 @@ async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexMod
2427
2588
  return bundledCachePath;
2428
2589
  }
2429
2590
  function writeCodexCatalogWithNativeMultiAgentDisabled(authFilePath, sourcePath) {
2430
- const codexHome = dirname4(authFilePath);
2431
- const outputPath = join5(codexHome, NEGOTIUM_MODEL_CATALOG);
2591
+ const codexHome = dirname5(authFilePath);
2592
+ const outputPath = join6(codexHome, NEGOTIUM_MODEL_CATALOG);
2432
2593
  const parsed = readCodexModelCache(sourcePath).parsed;
2433
2594
  const models = parsed.models.map((model, index) => {
2434
2595
  if (!model || typeof model !== "object" || Array.isArray(model)) {
@@ -2456,14 +2617,14 @@ var init_codex_native_multi_agent = __esm(() => {
2456
2617
  // ../../packages/core/src/agents/rollout/codex.ts
2457
2618
  import { randomBytes as randomBytes4 } from "crypto";
2458
2619
  import { existsSync as existsSync5, readFileSync as readFileSync5, realpathSync as realpathSync2, statSync as statSync2, unlinkSync as unlinkSync5 } from "fs";
2459
- import { basename, dirname as dirname5, join as join6, resolve as resolve4 } from "path";
2620
+ import { basename, dirname as dirname6, join as join7, resolve as resolve5 } from "path";
2460
2621
  function codexSessionsDir() {
2461
- return join6(hostedCodexHomePath(), "sessions");
2622
+ return join7(hostedCodexHomePath(), "sessions");
2462
2623
  }
2463
2624
  function loadCodexShell() {
2464
2625
  if (_shellCache)
2465
2626
  return _shellCache;
2466
- const raw = readFileSync5(join6(FIXTURES_DIR, "codex-shell.jsonl"), "utf8");
2627
+ const raw = readFileSync5(join7(FIXTURES_DIR, "codex-shell.jsonl"), "utf8");
2467
2628
  const lines = parseJsonlText(raw);
2468
2629
  if (lines.length < 5) {
2469
2630
  throw new Error(`loadCodexShell: expected >=5 entries in codex-shell.jsonl, got ${lines.length}`);
@@ -2530,16 +2691,16 @@ function codexRolloutPath(threadId, fallback) {
2530
2691
  const hh = String(createdAt.getHours()).padStart(2, "0");
2531
2692
  const min = String(createdAt.getMinutes()).padStart(2, "0");
2532
2693
  const ss = String(createdAt.getSeconds()).padStart(2, "0");
2533
- const dir = join6(codexSessionsDir(), yyyy, mm, dd);
2534
- return join6(dir, `rollout-${yyyy}-${mm}-${dd}T${hh}-${min}-${ss}-${threadId}.jsonl`);
2694
+ const dir = join7(codexSessionsDir(), yyyy, mm, dd);
2695
+ return join7(dir, `rollout-${yyyy}-${mm}-${dd}T${hh}-${min}-${ss}-${threadId}.jsonl`);
2535
2696
  }
2536
2697
  function canonicalFilePath(path) {
2537
- const absolute = resolve4(path);
2698
+ const absolute = resolve5(path);
2538
2699
  try {
2539
2700
  return realpathSync2(absolute);
2540
2701
  } catch {
2541
2702
  try {
2542
- return join6(realpathSync2(dirname5(absolute)), basename(absolute));
2703
+ return join7(realpathSync2(dirname6(absolute)), basename(absolute));
2543
2704
  } catch {
2544
2705
  return absolute;
2545
2706
  }
@@ -2769,19 +2930,19 @@ function latestCodexRolloutPath(threadId) {
2769
2930
  try {
2770
2931
  if (buckets) {
2771
2932
  for (const bucket of buckets) {
2772
- const dir = join6(sessionsDir, bucket);
2933
+ const dir = join7(sessionsDir, bucket);
2773
2934
  if (!existsSync5(dir))
2774
2935
  continue;
2775
2936
  const glob = new Bun.Glob(`rollout-*-${threadId}.jsonl`);
2776
2937
  for (const rel of glob.scanSync({ cwd: dir, onlyFiles: true })) {
2777
- candidates.push(join6(dir, rel));
2938
+ candidates.push(join7(dir, rel));
2778
2939
  }
2779
2940
  }
2780
2941
  }
2781
2942
  if (candidates.length === 0) {
2782
2943
  const glob = new Bun.Glob(`**/rollout-*-${threadId}.jsonl`);
2783
2944
  for (const rel of glob.scanSync({ cwd: sessionsDir, onlyFiles: true })) {
2784
- candidates.push(join6(sessionsDir, rel));
2945
+ candidates.push(join7(sessionsDir, rel));
2785
2946
  }
2786
2947
  }
2787
2948
  return candidates.sort((a, b) => statSync2(b).mtimeMs - statSync2(a).mtimeMs)[0];
@@ -2902,13 +3063,13 @@ function sweepPriorRolloutsForThread(threadId) {
2902
3063
  return;
2903
3064
  }
2904
3065
  for (const bucket of buckets) {
2905
- const dir = join6(sessionsDir, bucket);
3066
+ const dir = join7(sessionsDir, bucket);
2906
3067
  if (!existsSync5(dir))
2907
3068
  continue;
2908
3069
  try {
2909
3070
  const glob = new Bun.Glob(`rollout-*-${threadId}.jsonl`);
2910
3071
  for (const rel of glob.scanSync({ cwd: dir, onlyFiles: true })) {
2911
- const fullPath = join6(dir, rel);
3072
+ const fullPath = join7(dir, rel);
2912
3073
  try {
2913
3074
  unlinkSync5(fullPath);
2914
3075
  } catch (e) {
@@ -2926,7 +3087,7 @@ function sweepPriorRolloutsFullTree(threadId, sessionsDir) {
2926
3087
  try {
2927
3088
  const glob = new Bun.Glob(`**/rollout-*-${threadId}.jsonl`);
2928
3089
  for (const rel of glob.scanSync({ cwd: sessionsDir, onlyFiles: true })) {
2929
- const fullPath = join6(sessionsDir, rel);
3090
+ const fullPath = join7(sessionsDir, rel);
2930
3091
  try {
2931
3092
  unlinkSync5(fullPath);
2932
3093
  } catch (e) {
@@ -2992,7 +3153,7 @@ import { spawn as spawn3 } from "child_process";
2992
3153
  function createCodexAppServerForker(host) {
2993
3154
  return async (parentThreadId) => {
2994
3155
  const child = host.spawnServer();
2995
- return await new Promise((resolve5, reject) => {
3156
+ return await new Promise((resolve6, reject) => {
2996
3157
  let settled = false;
2997
3158
  let stdoutBuffer = "";
2998
3159
  let stderr = "";
@@ -3009,7 +3170,7 @@ function createCodexAppServerForker(host) {
3009
3170
  if (error)
3010
3171
  reject(error);
3011
3172
  else if (result)
3012
- resolve5(result);
3173
+ resolve6(result);
3013
3174
  else
3014
3175
  reject(new Error("Codex thread fork returned no result"));
3015
3176
  };
@@ -3106,7 +3267,7 @@ var init_codex_app_server = __esm(async () => {
3106
3267
 
3107
3268
  // ../../packages/core/src/agents/codex-registry.ts
3108
3269
  import { existsSync as existsSync6, unlinkSync as unlinkSync6 } from "fs";
3109
- import { join as join7 } from "path";
3270
+ import { join as join8 } from "path";
3110
3271
  var VALID_EFFORTS2, codexRegistry, codexRegistryOperations;
3111
3272
  var init_codex_registry = __esm(async () => {
3112
3273
  init_logger();
@@ -3151,7 +3312,7 @@ var init_codex_registry = __esm(async () => {
3151
3312
  async cleanupRollouts({ sessionIds }) {
3152
3313
  if (sessionIds.length === 0)
3153
3314
  return;
3154
- const sessionsDir = join7(hostedCodexHomePath(), "sessions");
3315
+ const sessionsDir = join8(hostedCodexHomePath(), "sessions");
3155
3316
  if (!existsSync6(sessionsDir))
3156
3317
  return;
3157
3318
  const failures = [];
@@ -3159,7 +3320,7 @@ var init_codex_registry = __esm(async () => {
3159
3320
  try {
3160
3321
  const glob = new Bun.Glob(`**/rollout-*-${tid}.jsonl`);
3161
3322
  for await (const rel of glob.scan({ cwd: sessionsDir, onlyFiles: true })) {
3162
- const path = join7(sessionsDir, rel);
3323
+ const path = join8(sessionsDir, rel);
3163
3324
  try {
3164
3325
  unlinkSync6(path);
3165
3326
  } catch (e) {
@@ -3183,17 +3344,17 @@ var init_codex_registry = __esm(async () => {
3183
3344
 
3184
3345
  // ../../packages/core/src/agents/maestro-registry.ts
3185
3346
  import { randomUUID as randomUUID3 } from "crypto";
3186
- import { existsSync as existsSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
3187
- import { homedir as homedir4 } from "os";
3188
- import { join as join8, resolve as resolve5 } from "path";
3347
+ import { existsSync as existsSync7, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
3348
+ import { homedir as homedir5 } from "os";
3349
+ import { join as join9, resolve as resolve6 } from "path";
3189
3350
  function maestroSessionsDir() {
3190
- return join8(process.env.MAESTRO_DATA_DIR ? resolve5(process.env.MAESTRO_DATA_DIR) : join8(homedir4(), ".maestro"), "sessions");
3351
+ return join9(process.env.MAESTRO_DATA_DIR ? resolve6(process.env.MAESTRO_DATA_DIR) : join9(homedir5(), ".maestro"), "sessions");
3191
3352
  }
3192
3353
  function maestroSessionPath(sessionId) {
3193
- return join8(maestroSessionsDir(), `${sessionId}.jsonl`);
3354
+ return join9(maestroSessionsDir(), `${sessionId}.jsonl`);
3194
3355
  }
3195
3356
  function maestroActiveSessionPath(sessionId) {
3196
- return join8(maestroSessionsDir(), `${sessionId}.active.jsonl`);
3357
+ return join9(maestroSessionsDir(), `${sessionId}.active.jsonl`);
3197
3358
  }
3198
3359
  function existingCreatedAt(path) {
3199
3360
  if (!existsSync7(path))
@@ -3215,7 +3376,7 @@ function writeRollout(options) {
3215
3376
  assertUuidLike("sessionId", sessionId);
3216
3377
  ensureCwdExists(options.cwd);
3217
3378
  const path = maestroSessionPath(sessionId);
3218
- mkdirSync6(maestroSessionsDir(), { recursive: true });
3379
+ mkdirSync7(maestroSessionsDir(), { recursive: true });
3219
3380
  const messages = extractChatPairs(options.entries).flatMap((pair) => [
3220
3381
  { role: "user", content: nonEmptyTurnText(pair.userText) },
3221
3382
  { role: "assistant", content: nonEmptyTurnText(pair.assistantText) }
@@ -3367,141 +3528,6 @@ function sanitizeId(id) {
3367
3528
  return id.replace(/[^a-zA-Z0-9_-]/g, "_") || "_";
3368
3529
  }
3369
3530
 
3370
- // ../../packages/core/src/storage/storage-host.ts
3371
- import { mkdirSync as mkdirSync7 } from "fs";
3372
- import { homedir as homedir5 } from "os";
3373
- import { dirname as dirname6, join as join9, resolve as resolve6 } from "path";
3374
- function envPath(name, fallback) {
3375
- const value = process.env[name]?.trim();
3376
- return resolve6(value || fallback);
3377
- }
3378
- function defaultStateDir() {
3379
- return envPath("NEGOTIUM_STATE_DIR", join9(homedir5(), ".negotium"));
3380
- }
3381
- function defaultDataDir() {
3382
- return envPath("NEGOTIUM_DATA_DIR", join9(defaultStateDir(), "data"));
3383
- }
3384
- function defaultLogDir() {
3385
- return envPath("NEGOTIUM_LOG_DIR", join9(defaultStateDir(), "logs"));
3386
- }
3387
- function defaultWorkspaceDir() {
3388
- return envPath("NEGOTIUM_WORKSPACE_DIR", join9(defaultStateDir(), "workspace"));
3389
- }
3390
- function defaultSessionAsksDir() {
3391
- const runDir = envPath("NEGOTIUM_RUN_DIR", join9(defaultStateDir(), "runtime"));
3392
- return join9(runDir, "session-asks");
3393
- }
3394
- function defaultSessionsDatabasePath() {
3395
- return envPath("SESSIONS_DB_PATH", join9(resolveStorageDataDir(), "sessions.db"));
3396
- }
3397
- function isSqliteBusy(error) {
3398
- const message = error instanceof Error ? error.message : String(error);
3399
- return /database is (?:locked|busy)|SQLITE_(?:BUSY|LOCKED)/i.test(message);
3400
- }
3401
- function execWithBusyRetry(database, sql, timeoutMs = SQLITE_INIT_TIMEOUT_MS) {
3402
- const deadline = Date.now() + timeoutMs;
3403
- while (true) {
3404
- try {
3405
- database.exec(sql);
3406
- return;
3407
- } catch (error) {
3408
- if (!isSqliteBusy(error) || Date.now() >= deadline)
3409
- throw error;
3410
- Atomics.wait(SQLITE_INIT_SLEEP, 0, 0, Math.min(SQLITE_INIT_RETRY_MS, deadline - Date.now()));
3411
- }
3412
- }
3413
- }
3414
- function initializeDatabase(database) {
3415
- database.exec("PRAGMA busy_timeout = 5000");
3416
- execWithBusyRetry(database, "PRAGMA journal_mode = WAL");
3417
- database.exec("PRAGMA foreign_keys = ON");
3418
- database.exec("PRAGMA wal_autocheckpoint = 1000");
3419
- try {
3420
- database.exec("PRAGMA wal_checkpoint(TRUNCATE)");
3421
- } catch {}
3422
- }
3423
- function defaultDatabase() {
3424
- const path = defaultSessionsDatabasePath();
3425
- if (fallbackDatabase && fallbackDatabasePath === path)
3426
- return fallbackDatabase;
3427
- if (fallbackDatabase)
3428
- fallbackDatabase.close();
3429
- mkdirSync7(dirname6(path), { recursive: true });
3430
- fallbackDatabase = new Database(path, { create: true });
3431
- fallbackDatabasePath = path;
3432
- initializeDatabase(fallbackDatabase);
3433
- return fallbackDatabase;
3434
- }
3435
- function resolveStorageDatabase() {
3436
- return configuredHost.database ?? defaultDatabase();
3437
- }
3438
- function resolveStorageDataDir() {
3439
- return configuredHost.dataDir ?? defaultDataDir();
3440
- }
3441
- function resolveStorageLogDir() {
3442
- return configuredHost.logDir ?? defaultLogDir();
3443
- }
3444
- function resolveStorageSessionAsksDir() {
3445
- return configuredHost.sessionAsksDir ?? defaultSessionAsksDir();
3446
- }
3447
- function resolveStorageWorkspaceDir() {
3448
- return configuredHost.workspaceDir ?? defaultWorkspaceDir();
3449
- }
3450
- function resolveStorageSharedWikiDir() {
3451
- return configuredHost.sharedWikiDir ?? join9(resolveStorageWorkspaceDir(), "wiki");
3452
- }
3453
- function registerStorageSchemaInitializer(initialize, priority = 100) {
3454
- schemaInitializers.push({ initialize, priority });
3455
- schemaInitializers.sort((a, b) => a.priority - b.priority);
3456
- }
3457
- function ensureStorageSchemas(database = resolveStorageDatabase()) {
3458
- if (initializingDatabases.has(database))
3459
- return;
3460
- let initialized = initializedSchemas.get(database);
3461
- if (!initialized) {
3462
- initialized = new Set;
3463
- initializedSchemas.set(database, initialized);
3464
- }
3465
- initializingDatabases.add(database);
3466
- try {
3467
- for (const entry of schemaInitializers) {
3468
- if (initialized.has(entry.initialize))
3469
- continue;
3470
- initialized.add(entry.initialize);
3471
- try {
3472
- entry.initialize(database);
3473
- } catch (error) {
3474
- initialized.delete(entry.initialize);
3475
- throw error;
3476
- }
3477
- }
3478
- } finally {
3479
- initializingDatabases.delete(database);
3480
- }
3481
- }
3482
- var configuredHost, fallbackDatabase = null, fallbackDatabasePath = null, schemaInitializers, initializedSchemas, initializingDatabases, SQLITE_INIT_RETRY_MS = 25, SQLITE_INIT_TIMEOUT_MS = 5000, SQLITE_INIT_SLEEP, internalStorageDatabase;
3483
- var init_storage_host = __esm(async () => {
3484
- await init_sqlite();
3485
- configuredHost = {};
3486
- schemaInitializers = [];
3487
- initializedSchemas = new WeakMap;
3488
- initializingDatabases = new WeakSet;
3489
- SQLITE_INIT_SLEEP = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
3490
- internalStorageDatabase = new Proxy({}, {
3491
- get(_target, property) {
3492
- const database = resolveStorageDatabase();
3493
- ensureStorageSchemas(database);
3494
- const value = Reflect.get(database, property, database);
3495
- return typeof value === "function" ? value.bind(database) : value;
3496
- },
3497
- set(_target, property, value) {
3498
- const database = resolveStorageDatabase();
3499
- ensureStorageSchemas(database);
3500
- return Reflect.set(database, property, value, database);
3501
- }
3502
- });
3503
- });
3504
-
3505
3531
  // ../../packages/core/src/storage/tasks.ts
3506
3532
  import { existsSync as existsSync8, mkdirSync as mkdirSync8, readFileSync as readFileSync7, renameSync as renameSync4, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
3507
3533
  import { dirname as dirname7, join as join10 } from "path";
@@ -6055,7 +6081,10 @@ function listRuntimeEventsAfter(seq, limit = 500) {
6055
6081
  }
6056
6082
  var RUNTIME_EVENT_TYPES, types;
6057
6083
  var init_runtime_events = __esm(async () => {
6058
- await init_forum_db();
6084
+ await __promiseAll([
6085
+ init_forum_db(),
6086
+ init_storage_host()
6087
+ ]);
6059
6088
  RUNTIME_EVENT_TYPES = [
6060
6089
  "message",
6061
6090
  "message-updated",
@@ -6064,26 +6093,28 @@ var init_runtime_events = __esm(async () => {
6064
6093
  "topic-updated",
6065
6094
  "topic-deleted"
6066
6095
  ];
6067
- db.exec(`
6068
- CREATE TABLE IF NOT EXISTS runtime_events (
6069
- seq INTEGER PRIMARY KEY AUTOINCREMENT,
6070
- source_id TEXT NOT NULL,
6071
- event_type TEXT NOT NULL CHECK (
6072
- event_type IN (
6073
- 'message',
6074
- 'message-updated',
6075
- 'ai-status',
6076
- 'topic-created',
6077
- 'topic-updated',
6078
- 'topic-deleted'
6079
- )
6080
- ),
6081
- topic_id TEXT NOT NULL,
6082
- payload_json TEXT NOT NULL,
6083
- created_at TEXT NOT NULL
6084
- )
6085
- `);
6086
- db.exec("CREATE INDEX IF NOT EXISTS idx_runtime_events_topic_seq ON runtime_events(topic_id, seq)");
6096
+ registerStorageSchemaInitializer((database) => {
6097
+ database.exec(`
6098
+ CREATE TABLE IF NOT EXISTS runtime_events (
6099
+ seq INTEGER PRIMARY KEY AUTOINCREMENT,
6100
+ source_id TEXT NOT NULL,
6101
+ event_type TEXT NOT NULL CHECK (
6102
+ event_type IN (
6103
+ 'message',
6104
+ 'message-updated',
6105
+ 'ai-status',
6106
+ 'topic-created',
6107
+ 'topic-updated',
6108
+ 'topic-deleted'
6109
+ )
6110
+ ),
6111
+ topic_id TEXT NOT NULL,
6112
+ payload_json TEXT NOT NULL,
6113
+ created_at TEXT NOT NULL
6114
+ )
6115
+ `);
6116
+ database.exec("CREATE INDEX IF NOT EXISTS idx_runtime_events_topic_seq ON runtime_events(topic_id, seq)");
6117
+ });
6087
6118
  types = new Set(RUNTIME_EVENT_TYPES);
6088
6119
  });
6089
6120
 
@@ -6243,13 +6274,17 @@ class SqliteRuntimeBus {
6243
6274
  };
6244
6275
  }
6245
6276
  }
6246
- var current, WsHub;
6277
+ function runtimeBus() {
6278
+ if (!current)
6279
+ current = new SqliteRuntimeBus;
6280
+ return current;
6281
+ }
6282
+ var current = null, WsHub;
6247
6283
  var init_bus = __esm(async () => {
6248
6284
  await init_runtime_events();
6249
- current = new SqliteRuntimeBus;
6250
6285
  WsHub = {
6251
6286
  get() {
6252
- return current;
6287
+ return runtimeBus();
6253
6288
  }
6254
6289
  };
6255
6290
  });
@@ -7946,9 +7981,9 @@ function formatArchiverBytes(bytes) {
7946
7981
  function formatArchiverTool(name, input) {
7947
7982
  const params = Object.entries(input).map(([key, value]) => {
7948
7983
  const rendered = typeof value === "string" ? value : JSON.stringify(value);
7949
- return `${key}: ${sessionText(rendered ?? "")}`;
7984
+ return `${key}: ${summarizeDisplayText(sessionText(rendered ?? ""))}`;
7950
7985
  }).join(", ");
7951
- return `${name}${params ? `(${params})` : ""}`;
7986
+ return summarizeDisplayText(`${name}${params ? `(${params})` : ""}`);
7952
7987
  }
7953
7988
  function createArchiverRuntime(host) {
7954
7989
  const activeSessions = new Map;
@@ -8255,6 +8290,7 @@ function runArchiverTurn(params) {
8255
8290
  }
8256
8291
  var MAX_BRIEF_ENTRIES = 8, defaultArchiverRuntime;
8257
8292
  var init_archiver = __esm(async () => {
8293
+ init_tool_format();
8258
8294
  init_config();
8259
8295
  init_logger();
8260
8296
  init_builders();
@@ -10287,32 +10323,35 @@ var init_self_schedules = __esm(async () => {
10287
10323
  await __promiseAll([
10288
10324
  init_forum_db(),
10289
10325
  init_runtime_leases(),
10290
- init_runtime_topic_state()
10326
+ init_runtime_topic_state(),
10327
+ init_storage_host()
10291
10328
  ]);
10292
- db.exec(`
10293
- CREATE TABLE IF NOT EXISTS runtime_self_schedules (
10294
- id TEXT PRIMARY KEY,
10295
- topic_id TEXT NOT NULL,
10296
- user_id TEXT NOT NULL,
10297
- message TEXT NOT NULL,
10298
- deliver_at INTEGER NOT NULL,
10299
- created_at INTEGER NOT NULL,
10300
- updated_at INTEGER NOT NULL,
10301
- status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'running')),
10302
- claimed_by TEXT,
10303
- claimed_at INTEGER,
10304
- running_query_id TEXT
10305
- )
10306
- `);
10307
- db.exec(`
10308
- CREATE UNIQUE INDEX IF NOT EXISTS idx_runtime_self_schedules_one_pending
10309
- ON runtime_self_schedules(topic_id)
10310
- WHERE status = 'pending'
10311
- `);
10312
- db.exec(`
10313
- CREATE INDEX IF NOT EXISTS idx_runtime_self_schedules_due
10314
- ON runtime_self_schedules(status, deliver_at)
10315
- `);
10329
+ registerStorageSchemaInitializer((database) => {
10330
+ database.exec(`
10331
+ CREATE TABLE IF NOT EXISTS runtime_self_schedules (
10332
+ id TEXT PRIMARY KEY,
10333
+ topic_id TEXT NOT NULL,
10334
+ user_id TEXT NOT NULL,
10335
+ message TEXT NOT NULL,
10336
+ deliver_at INTEGER NOT NULL,
10337
+ created_at INTEGER NOT NULL,
10338
+ updated_at INTEGER NOT NULL,
10339
+ status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'running')),
10340
+ claimed_by TEXT,
10341
+ claimed_at INTEGER,
10342
+ running_query_id TEXT
10343
+ )
10344
+ `);
10345
+ database.exec(`
10346
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_runtime_self_schedules_one_pending
10347
+ ON runtime_self_schedules(topic_id)
10348
+ WHERE status = 'pending'
10349
+ `);
10350
+ database.exec(`
10351
+ CREATE INDEX IF NOT EXISTS idx_runtime_self_schedules_due
10352
+ ON runtime_self_schedules(status, deliver_at)
10353
+ `);
10354
+ });
10316
10355
  });
10317
10356
 
10318
10357
  // ../../packages/core/src/platform/playwright/manager-utils.ts
@@ -10914,15 +10953,20 @@ function assignTopicBrowserProfile(opts) {
10914
10953
  }
10915
10954
  var DEFAULT_BROWSER_PROFILE = "default";
10916
10955
  var init_browser_profiles = __esm(async () => {
10917
- await init_forum_db();
10918
- db.exec(`
10919
- CREATE TABLE IF NOT EXISTS browser_profiles (
10920
- owner_id TEXT NOT NULL,
10921
- name TEXT NOT NULL,
10922
- created_at TEXT NOT NULL,
10923
- PRIMARY KEY (owner_id, name)
10924
- )
10925
- `);
10956
+ await __promiseAll([
10957
+ init_forum_db(),
10958
+ init_storage_host()
10959
+ ]);
10960
+ registerStorageSchemaInitializer((database) => {
10961
+ database.exec(`
10962
+ CREATE TABLE IF NOT EXISTS browser_profiles (
10963
+ owner_id TEXT NOT NULL,
10964
+ name TEXT NOT NULL,
10965
+ created_at TEXT NOT NULL,
10966
+ PRIMARY KEY (owner_id, name)
10967
+ )
10968
+ `);
10969
+ });
10926
10970
  });
10927
10971
 
10928
10972
  // ../../packages/core/src/platform/playwright/manager.ts
@@ -11879,6 +11923,7 @@ function text(value, maxLen) {
11879
11923
  }
11880
11924
  var providers, transientSessions;
11881
11925
  var init_background_sessions = __esm(async () => {
11926
+ init_tool_format();
11882
11927
  init_background_session_policy();
11883
11928
  await __promiseAll([
11884
11929
  init_archiver(),
@@ -12184,10 +12229,11 @@ var init_runtime_turn_requests = __esm(async () => {
12184
12229
  await __promiseAll([
12185
12230
  init_forum_db(),
12186
12231
  init_runtime_leases(),
12187
- init_runtime_topic_state()
12232
+ init_runtime_topic_state(),
12233
+ init_storage_host()
12188
12234
  ]);
12189
12235
  REQUEST_CLAIM_STALE_MS = TURN_LEASE_STALE_MS;
12190
- ensureRuntimeUserTurnRequestsSchema(db);
12236
+ registerStorageSchemaInitializer((database) => ensureRuntimeUserTurnRequestsSchema(database));
12191
12237
  });
12192
12238
 
12193
12239
  // ../../packages/core/src/topics/session.ts
@@ -13603,19 +13649,22 @@ var pendingAsks, MAX_ASK_AGE_MS;
13603
13649
  var init_ask_callbacks = __esm(async () => {
13604
13650
  await __promiseAll([
13605
13651
  init_forum_db(),
13606
- init_session_asks()
13652
+ init_session_asks(),
13653
+ init_storage_host()
13607
13654
  ]);
13608
- db.exec(`
13609
- CREATE TABLE IF NOT EXISTS remote_ask_callbacks (
13610
- target_query_id TEXT PRIMARY KEY,
13611
- request_id TEXT NOT NULL,
13612
- node_name TEXT NOT NULL,
13613
- node_cell_id TEXT NOT NULL,
13614
- topic_id TEXT NOT NULL,
13615
- user_id TEXT NOT NULL,
13616
- created_at INTEGER NOT NULL
13617
- )
13618
- `);
13655
+ registerStorageSchemaInitializer((database) => {
13656
+ database.exec(`
13657
+ CREATE TABLE IF NOT EXISTS remote_ask_callbacks (
13658
+ target_query_id TEXT PRIMARY KEY,
13659
+ request_id TEXT NOT NULL,
13660
+ node_name TEXT NOT NULL,
13661
+ node_cell_id TEXT NOT NULL,
13662
+ topic_id TEXT NOT NULL,
13663
+ user_id TEXT NOT NULL,
13664
+ created_at INTEGER NOT NULL
13665
+ )
13666
+ `);
13667
+ });
13619
13668
  pendingAsks = new Map;
13620
13669
  MAX_ASK_AGE_MS = PENDING_ASK_TTL_MS;
13621
13670
  });
@@ -13828,30 +13877,35 @@ paint();document.body.appendChild(b)}
13828
13877
  if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",init);else init()})();
13829
13878
  </script>`;
13830
13879
  var init_visual_store = __esm(async () => {
13831
- await init_forum_db();
13832
- db.exec(`
13833
- CREATE TABLE IF NOT EXISTS api_topic_visuals (
13834
- id INTEGER PRIMARY KEY AUTOINCREMENT,
13835
- topic_id TEXT NOT NULL,
13836
- html TEXT NOT NULL,
13837
- title TEXT,
13838
- created_at INTEGER NOT NULL,
13839
- kind TEXT NOT NULL DEFAULT 'html',
13840
- source TEXT,
13841
- file_id TEXT,
13842
- mime_type TEXT,
13843
- media_token TEXT
13844
- );
13845
- CREATE INDEX IF NOT EXISTS idx_api_topic_visuals_topic
13846
- ON api_topic_visuals(topic_id, created_at DESC);
13847
-
13848
- CREATE TABLE IF NOT EXISTS api_topic_visual_views (
13849
- topic_id TEXT NOT NULL,
13850
- user_id TEXT NOT NULL,
13851
- visual_id INTEGER NOT NULL,
13852
- PRIMARY KEY (topic_id, user_id)
13853
- );
13854
- `);
13880
+ await __promiseAll([
13881
+ init_forum_db(),
13882
+ init_storage_host()
13883
+ ]);
13884
+ registerStorageSchemaInitializer((database) => {
13885
+ database.exec(`
13886
+ CREATE TABLE IF NOT EXISTS api_topic_visuals (
13887
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
13888
+ topic_id TEXT NOT NULL,
13889
+ html TEXT NOT NULL,
13890
+ title TEXT,
13891
+ created_at INTEGER NOT NULL,
13892
+ kind TEXT NOT NULL DEFAULT 'html',
13893
+ source TEXT,
13894
+ file_id TEXT,
13895
+ mime_type TEXT,
13896
+ media_token TEXT
13897
+ );
13898
+ CREATE INDEX IF NOT EXISTS idx_api_topic_visuals_topic
13899
+ ON api_topic_visuals(topic_id, created_at DESC);
13900
+
13901
+ CREATE TABLE IF NOT EXISTS api_topic_visual_views (
13902
+ topic_id TEXT NOT NULL,
13903
+ user_id TEXT NOT NULL,
13904
+ visual_id INTEGER NOT NULL,
13905
+ PRIMARY KEY (topic_id, user_id)
13906
+ );
13907
+ `);
13908
+ });
13855
13909
  for (const statement of [
13856
13910
  "ALTER TABLE api_topic_visuals ADD COLUMN kind TEXT NOT NULL DEFAULT 'html'",
13857
13911
  "ALTER TABLE api_topic_visuals ADD COLUMN source TEXT",
@@ -18776,4 +18830,4 @@ export {
18776
18830
  DEFAULT_SELF_CONFIG_PRODUCT
18777
18831
  };
18778
18832
 
18779
- //# debugId=407E1CBFBD75364B64756E2164756E21
18833
+ //# debugId=260456A5E72011F164756E2164756E21