negotium 0.1.49 → 0.2.0

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 (50) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-helpers.js +58 -74
  3. package/dist/agent-helpers.js.map +15 -15
  4. package/dist/background-bash.js +22 -10
  5. package/dist/background-bash.js.map +3 -3
  6. package/dist/browser-runtime.js +35 -68
  7. package/dist/browser-runtime.js.map +7 -7
  8. package/dist/{chunk-5rpw9d1f.js → chunk-kc5kmr95.js} +28 -11
  9. package/dist/{chunk-5rpw9d1f.js.map → chunk-kc5kmr95.js.map} +4 -4
  10. package/dist/hosted-agent.js +36 -18
  11. package/dist/hosted-agent.js.map +7 -7
  12. package/dist/main.js +562 -98
  13. package/dist/main.js.map +21 -19
  14. package/dist/mcp-factories.js +62 -78
  15. package/dist/mcp-factories.js.map +16 -16
  16. package/dist/prompts.js +22 -10
  17. package/dist/prompts.js.map +3 -3
  18. package/dist/query-runtime.js +22 -10
  19. package/dist/query-runtime.js.map +4 -4
  20. package/dist/registry.js +5 -12
  21. package/dist/registry.js.map +5 -5
  22. package/dist/rollout.js +1 -1
  23. package/dist/runtime/src/agents/maestro-registry.ts +1 -1
  24. package/dist/runtime/src/agents/rollout/shared.ts +12 -4
  25. package/dist/runtime/src/mcp/mcp-helpers.ts +1 -1
  26. package/dist/runtime/src/mcp/wiki-server.ts +1 -1
  27. package/dist/runtime/src/migration/single-user.ts +621 -0
  28. package/dist/runtime/src/platform/config.ts +24 -11
  29. package/dist/runtime/src/platform/mcp-config.ts +4 -4
  30. package/dist/runtime/src/platform/playwright/manager.ts +10 -28
  31. package/dist/runtime/src/runtime/attachments.ts +3 -3
  32. package/dist/runtime/src/storage/browser-profiles.ts +11 -9
  33. package/dist/runtime/src/storage/conversations.ts +5 -18
  34. package/dist/runtime/src/storage/storage-host.ts +1 -1
  35. package/dist/runtime/src/storage/tasks.ts +2 -14
  36. package/dist/runtime/src/storage/vault.ts +3 -2
  37. package/dist/runtime/src/version.ts +1 -1
  38. package/dist/runtime-helpers.js +22 -10
  39. package/dist/runtime-helpers.js.map +5 -5
  40. package/dist/storage.js +5 -19
  41. package/dist/storage.js.map +5 -5
  42. package/dist/types/packages/core/src/mcp/mcp-helpers.d.ts +1 -1
  43. package/dist/types/packages/core/src/platform/config.d.ts +9 -1
  44. package/dist/types/packages/core/src/runtime/attachments.d.ts +1 -1
  45. package/dist/types/packages/core/src/storage/conversations.d.ts +2 -2
  46. package/dist/types/packages/core/src/version.d.ts +1 -1
  47. package/dist/vault.js +25 -12
  48. package/dist/vault.js.map +4 -4
  49. package/install-browser-rs.mjs +1 -1
  50. package/package.json +2 -2
@@ -155,7 +155,7 @@ function resolveBrowserRsBin(envValue) {
155
155
  if (!override && !versionAtLeast(BROWSER_RS_VERSION.replace(/^v/, ""), BROWSER_RS_MIN_SECURE_VERSION)) {
156
156
  return;
157
157
  }
158
- const candidate = override ? resolve(override) : resolve(STATE_DIR, "bin", "browser-rs", BROWSER_RS_VERSION, "browser-rs");
158
+ const candidate = override ? resolve(override) : resolve(BINARIES_DIR, "browser-rs", BROWSER_RS_VERSION, "browser-rs");
159
159
  try {
160
160
  accessSync(candidate, constants.X_OK);
161
161
  return browserRsMeetsMinimumVersion(candidate) ? candidate : undefined;
@@ -167,7 +167,7 @@ function resolveBrowserMcpBin(envValue) {
167
167
  const override = envValue?.trim();
168
168
  if (override)
169
169
  return resolve(override);
170
- return BROWSER_RS_BIN ?? resolve(STATE_DIR, "bin", "browser-rs", BROWSER_RS_VERSION, "browser-rs");
170
+ return BROWSER_RS_BIN ?? resolve(BINARIES_DIR, "browser-rs", BROWSER_RS_VERSION, "browser-rs");
171
171
  }
172
172
  function resolveBrowserProxy() {
173
173
  const raw = envText("BROWSER_PROXY_URL");
@@ -199,7 +199,7 @@ function resolveTopicWorkspaceDir(topicId) {
199
199
  }
200
200
  function loadOrCreateLocalSecret(envKey, filename, options = {}) {
201
201
  const envValue = envText(envKey);
202
- const secretFile = resolve(STATE_DIR, filename);
202
+ const secretFile = resolve(SECRETS_DIR, filename);
203
203
  mkdirSync(dirname(secretFile), { recursive: true });
204
204
  if (envValue) {
205
205
  if (options.persistEnvValue) {
@@ -240,7 +240,7 @@ function resolveDefaultModel(agent, registryDefaultModel) {
240
240
  function codexAuthFilePath() {
241
241
  return process.env.NEGOTIUM_CODEX_AUTH_FILE || join(homedir(), ".codex", "auth.json");
242
242
  }
243
- var HOME, PROJECT_ROOT, STATE_DIR_ENV, STATE_DIR, WORKSPACE_DIR, TOPIC_WORKSPACE_DIR, SHARED_WIKI_DIR, CONTEXTS_DIR, BROWSER_PROFILES_DIR, DM_WORKSPACE_DIR, SESSION_WORKSPACE_DIR, CLAUDE_EXECUTABLE_ENV, CLAUDE_EXECUTABLE, DEFAULT_OUTPUT_LANGUAGE = "English", BROWSER_RS_VERSION = "v0.1.16", BROWSER_RS_MIN_SECURE_VERSION = "0.1.15", BROWSER_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, BACKGROUND_BASH_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, SESSIONS_DB, DEBUG_FILE, USERS_LOG_DIR, RUN_DIR, PROGRESS_DIR, DM_CMD_DIR, DM_RESP_DIR, SESSION_INBOX_DIR, SESSION_ASKS_DIR, 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;
243
+ 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, CONTEXTS_DIR, DM_WORKSPACE_DIR, SESSION_WORKSPACE_DIR, CLAUDE_EXECUTABLE_ENV, CLAUDE_EXECUTABLE, DEFAULT_OUTPUT_LANGUAGE = "English", BROWSER_RS_VERSION = "v0.1.16", BROWSER_RS_MIN_SECURE_VERSION = "0.1.15", BROWSER_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, BACKGROUND_BASH_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, 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;
244
244
  var init_config = __esm(() => {
245
245
  init_config_helpers();
246
246
  init_logger();
@@ -252,10 +252,14 @@ var init_config = __esm(() => {
252
252
  WORKSPACE_DIR = resolveLocalStateDir("NEGOTIUM_WORKSPACE_DIR", "workspace");
253
253
  TOPIC_WORKSPACE_DIR = resolve(WORKSPACE_DIR, "topics");
254
254
  SHARED_WIKI_DIR = resolve(WORKSPACE_DIR, "wiki");
255
- CONTEXTS_DIR = resolve(WORKSPACE_DIR, "contexts");
256
- BROWSER_PROFILES_DIR = resolve(WORKSPACE_DIR, "browser-profiles");
257
- DM_WORKSPACE_DIR = resolve(WORKSPACE_DIR, "dm");
258
- SESSION_WORKSPACE_DIR = resolve(WORKSPACE_DIR, "sessions");
255
+ CRON_WORKSPACE_DIR = resolve(WORKSPACE_DIR, "cron");
256
+ BROWSER_DIR = resolveLocalStateDir("NEGOTIUM_BROWSER_DIR", "browser");
257
+ BROWSER_PROFILES_DIR = resolve(BROWSER_DIR, "profiles");
258
+ BINARIES_DIR = resolve(STATE_DIR, "binaries");
259
+ SECRETS_DIR = resolve(STATE_DIR, "secrets");
260
+ CONTEXTS_DIR = resolve(STATE_DIR, "data", "contexts");
261
+ DM_WORKSPACE_DIR = resolve(STATE_DIR, "data", "dm");
262
+ SESSION_WORKSPACE_DIR = resolve(STATE_DIR, "data", "sessions");
259
263
  CLAUDE_EXECUTABLE_ENV = envText("NEGOTIUM_CLAUDE_EXECUTABLE");
260
264
  CLAUDE_EXECUTABLE = CLAUDE_EXECUTABLE_ENV ? resolve(CLAUDE_EXECUTABLE_ENV) : undefined;
261
265
  BROWSER_RS_BIN = resolveBrowserRsBin(envText("NEGOTIUM_BROWSER_RS_BIN"));
@@ -284,10 +288,12 @@ var init_config = __esm(() => {
284
288
  hostname = process.env.HOSTNAME || "127.0.0.1";
285
289
  DATA_DIR = resolveLocalStateDir("NEGOTIUM_DATA_DIR", "data");
286
290
  LOG_DIR = resolveLocalStateDir("NEGOTIUM_LOG_DIR", "logs");
291
+ UPLOADS_DIR = resolve(DATA_DIR, "uploads");
292
+ VAULT_DIR = resolve(DATA_DIR, "vault");
287
293
  SESSIONS_DB = process.env.SESSIONS_DB_PATH ? resolve(process.env.SESSIONS_DB_PATH) : resolve(DATA_DIR, "sessions.db");
288
294
  DEBUG_FILE = resolve(DATA_DIR, "debug-users.json");
289
295
  USERS_LOG_DIR = resolve(DATA_DIR, "users");
290
- RUN_DIR = resolveLocalStateDir("NEGOTIUM_RUN_DIR", "run");
296
+ RUN_DIR = resolveLocalStateDir("NEGOTIUM_RUN_DIR", "runtime");
291
297
  PROGRESS_DIR = resolve(RUN_DIR, "progress");
292
298
  DM_CMD_DIR = resolve(RUN_DIR, "dm-commands");
293
299
  DM_RESP_DIR = resolve(RUN_DIR, "dm-responses");
@@ -298,6 +304,8 @@ var init_config = __esm(() => {
298
304
  PLAYWRIGHT_PORTS_DIR = resolve(RUN_DIR, "playwright-ports");
299
305
  mkdirSync(STATE_DIR, { recursive: true });
300
306
  mkdirSync(DATA_DIR, { recursive: true });
307
+ mkdirSync(UPLOADS_DIR, { recursive: true });
308
+ mkdirSync(VAULT_DIR, { recursive: true, mode: 448 });
301
309
  mkdirSync(LOG_DIR, { recursive: true });
302
310
  mkdirSync(PROGRESS_DIR, { recursive: true });
303
311
  mkdirSync(DM_CMD_DIR, { recursive: true });
@@ -308,10 +316,14 @@ var init_config = __esm(() => {
308
316
  mkdirSync(WORKSPACE_DIR, { recursive: true });
309
317
  mkdirSync(TOPIC_WORKSPACE_DIR, { recursive: true });
310
318
  mkdirSync(SHARED_WIKI_DIR, { recursive: true });
319
+ mkdirSync(CRON_WORKSPACE_DIR, { recursive: true });
311
320
  mkdirSync(CONTEXTS_DIR, { recursive: true });
312
- mkdirSync(BROWSER_PROFILES_DIR, { recursive: true });
313
321
  mkdirSync(DM_WORKSPACE_DIR, { recursive: true });
314
322
  mkdirSync(SESSION_WORKSPACE_DIR, { recursive: true });
323
+ mkdirSync(BROWSER_DIR, { recursive: true });
324
+ mkdirSync(BROWSER_PROFILES_DIR, { recursive: true });
325
+ mkdirSync(BINARIES_DIR, { recursive: true });
326
+ mkdirSync(SECRETS_DIR, { recursive: true, mode: 448 });
315
327
  ACTIVE_QUERY_STALE_MS = 10 * 60 * 1000;
316
328
  AGENTS_PROMPTS_DIR = resolve(PROJECT_ROOT, "src/prompts/agents");
317
329
  RESOURCES_DIR = resolve(PROJECT_ROOT, "src/resources");
@@ -530,7 +542,12 @@ var init_shared = __esm(() => {
530
542
  init_config();
531
543
  init_logger();
532
544
  __dirname2 = dirname3(fileURLToPath2(import.meta.url));
533
- trustedWorkspaceRoots = [WORKSPACE_DIR, DM_WORKSPACE_DIR, TOPIC_WORKSPACE_DIR].map((root) => resolve3(root));
545
+ trustedWorkspaceRoots = [
546
+ WORKSPACE_DIR,
547
+ DM_WORKSPACE_DIR,
548
+ SESSION_WORKSPACE_DIR,
549
+ TOPIC_WORKSPACE_DIR
550
+ ].map((root) => resolve3(root));
534
551
  FIXTURES_DIR = join3(__dirname2, "..", "fixtures");
535
552
  UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
536
553
  });
@@ -1493,7 +1510,7 @@ function defaultWorkspaceDir() {
1493
1510
  return envPath("NEGOTIUM_WORKSPACE_DIR", join7(defaultStateDir(), "workspace"));
1494
1511
  }
1495
1512
  function defaultSessionAsksDir() {
1496
- const runDir = envPath("NEGOTIUM_RUN_DIR", join7(defaultStateDir(), "run"));
1513
+ const runDir = envPath("NEGOTIUM_RUN_DIR", join7(defaultStateDir(), "runtime"));
1497
1514
  return join7(runDir, "session-asks");
1498
1515
  }
1499
1516
  function defaultSessionsDatabasePath() {
@@ -1599,15 +1616,8 @@ import {
1599
1616
  writeFileSync as writeFileSync5
1600
1617
  } from "fs";
1601
1618
  import { dirname as dirname7, join as join8 } from "path";
1602
- function safeUserIdComponent(userId) {
1603
- const str = String(userId);
1604
- if (!str || /[/\\]|\.\./.test(str)) {
1605
- throw new Error(`conversations: refusing unsafe userId path component: ${str}`);
1606
- }
1607
- return str;
1608
- }
1609
- function conversationDir(userId) {
1610
- return join8(resolveStorageDataDir(), "conversations", safeUserIdComponent(userId));
1619
+ function conversationDir(_userId) {
1620
+ return join8(resolveStorageDataDir(), "conversations");
1611
1621
  }
1612
1622
  function topicFilename(topicName) {
1613
1623
  const t = sanitizeTopicName(topicName, true);
@@ -1845,7 +1855,7 @@ function writeRollout(options) {
1845
1855
  version: 1,
1846
1856
  cwd: options.cwd,
1847
1857
  createdAt: existingCreatedAt(path) ?? new Date().toISOString(),
1848
- sdkVersion: "0.1.53"
1858
+ sdkVersion: "0.1.54"
1849
1859
  }
1850
1860
  },
1851
1861
  ...messages
@@ -4281,8 +4291,9 @@ function initializeVaultDatabase(database) {
4281
4291
  }
4282
4292
  }
4283
4293
  function openVaultDatabase(dataDir) {
4284
- const path = join12(dataDir, "vault.db");
4285
- mkdirSync9(dataDir, { recursive: true });
4294
+ const vaultDir = join12(dataDir, "vault");
4295
+ const path = join12(vaultDir, "vault.db");
4296
+ mkdirSync9(vaultDir, { recursive: true, mode: 448 });
4286
4297
  const database = new Database(path, { create: true });
4287
4298
  chmodSync2(path, 384);
4288
4299
  initializeVaultDatabase(database);
@@ -4635,7 +4646,7 @@ function createBrowserProfile(ownerId, rawName) {
4635
4646
  const name = normalizeBrowserProfileName(rawName);
4636
4647
  if (name === DEFAULT_BROWSER_PROFILE)
4637
4648
  return name;
4638
- db.query("INSERT OR IGNORE INTO browser_profiles (owner_id, name, created_at) VALUES (?, ?, ?)").run(ownerId, name, new Date().toISOString());
4649
+ db.query("INSERT OR IGNORE INTO browser_profiles (owner_id, name, created_at) VALUES (?, ?, ?)").run("local", name, new Date().toISOString());
4639
4650
  return name;
4640
4651
  }
4641
4652
  function assignTopicBrowserProfile(opts) {
@@ -4675,7 +4686,6 @@ import {
4675
4686
  existsSync as existsSync11,
4676
4687
  mkdirSync as mkdirSync10,
4677
4688
  readFileSync as readFileSync9,
4678
- renameSync as renameSync5,
4679
4689
  rmSync,
4680
4690
  unlinkSync as unlinkSync10,
4681
4691
  writeFileSync as writeFileSync7
@@ -4691,7 +4701,7 @@ function defaultTopicBinding(userId, topic) {
4691
4701
  if (!topic)
4692
4702
  return managerHost.resolveNamedBinding(userId, "default");
4693
4703
  const ownerId = getBrowserProfileOwner(topic, userId);
4694
- const profile = migrateLegacyTopicProfile(ownerId, topic);
4704
+ const profile = getTopicBrowserProfile(topic);
4695
4705
  return managerHost.resolveNamedBinding(ownerId, profile);
4696
4706
  }
4697
4707
  function resolvePlaywrightProfileBinding(ownerId, rawProfile) {
@@ -4703,34 +4713,15 @@ function validateProfileBinding(binding) {
4703
4713
  }
4704
4714
  return Object.freeze({ ...binding });
4705
4715
  }
4706
- function defaultNamedBinding(ownerId, rawProfile) {
4716
+ function defaultNamedBinding(_ownerId, rawProfile) {
4707
4717
  const profile = normalizeBrowserProfileName(rawProfile);
4708
- const instanceKey = `profile:${encodeURIComponent(ownerId)}:${profile}`;
4718
+ const instanceKey = `profile:${profile}`;
4709
4719
  return {
4710
4720
  instanceKey,
4711
- ownerId,
4721
+ ownerId: "local",
4712
4722
  profile
4713
4723
  };
4714
4724
  }
4715
- function legacyBrowserProfileName(topic) {
4716
- return `legacy_${createHash2("sha256").update(topic).digest("hex").slice(0, 12)}`;
4717
- }
4718
- function migrateLegacyTopicProfile(ownerId, topic) {
4719
- const current2 = getTopicBrowserProfile(topic);
4720
- if (current2 !== "default" || !hasBrowserProfileTopic(topic))
4721
- return current2;
4722
- const legacyDir = resolve9(BROWSER_PROFILES_DIR, sanitizeTopicName(topic));
4723
- if (!existsSync11(legacyDir))
4724
- return current2;
4725
- const profile = legacyBrowserProfileName(topic);
4726
- const profileDir = defaultProfileDir(ownerId, profile);
4727
- mkdirSync10(dirname8(profileDir), { recursive: true });
4728
- if (!existsSync11(profileDir))
4729
- renameSync5(legacyDir, profileDir);
4730
- assignTopicBrowserProfile({ topicId: topic, actorUserId: ownerId, profile });
4731
- logger.info({ ownerId, topic, profile }, "Adopted legacy topic browser profile");
4732
- return profile;
4733
- }
4734
4725
  function defaultChildEnvironment(context) {
4735
4726
  const childEnvironment = {};
4736
4727
  for (const key of [
@@ -4761,6 +4752,10 @@ function defaultChildEnvironment(context) {
4761
4752
  return childEnvironment;
4762
4753
  }
4763
4754
  function parseInstanceKey(instanceKey) {
4755
+ const shared = /^profile:(.+)$/.exec(instanceKey);
4756
+ if (shared && !shared[1].includes(":")) {
4757
+ return { ownerId: "local", profile: normalizeBrowserProfileName(shared[1]) };
4758
+ }
4764
4759
  const match = /^profile:([^:]+):(.+)$/.exec(instanceKey);
4765
4760
  if (!match)
4766
4761
  return { ownerId: "legacy", profile: sanitizeTopicName(instanceKey) };
@@ -4903,12 +4898,8 @@ async function allocatePort() {
4903
4898
  function releasePort(port) {
4904
4899
  usedPorts.delete(port);
4905
4900
  }
4906
- function ownerDirectory(ownerId) {
4907
- const digest = createHash2("sha256").update(ownerId).digest("hex").slice(0, 16);
4908
- return `${sanitizeTopicName(ownerId).slice(0, 24)}_${digest}`;
4909
- }
4910
- function defaultProfileDir(ownerId, profile) {
4911
- return resolve9(BROWSER_PROFILES_DIR, "profiles", ownerDirectory(ownerId), profile);
4901
+ function defaultProfileDir(_ownerId, profile) {
4902
+ return resolve9(BROWSER_PROFILES_DIR, profile);
4912
4903
  }
4913
4904
  function resolveUserDataDir(instanceKey) {
4914
4905
  return managerHost.resolveInstanceDataDir(instanceKey);
@@ -5952,15 +5943,8 @@ RULES:
5952
5943
  - Keep the entire summary under 1500 words.`, CHARS_PER_TEXT_TOKEN = 3.5, CHARS_PER_CJK_TOKEN = 0.9;
5953
5944
 
5954
5945
  // ../../packages/core/src/storage/tasks.ts
5955
- import { existsSync as existsSync12, mkdirSync as mkdirSync11, readFileSync as readFileSync10, renameSync as renameSync6, statSync as statSync4, writeFileSync as writeFileSync8 } from "fs";
5946
+ import { existsSync as existsSync12, mkdirSync as mkdirSync11, readFileSync as readFileSync10, renameSync as renameSync5, statSync as statSync4, writeFileSync as writeFileSync8 } from "fs";
5956
5947
  import { dirname as dirname9, join as join15 } from "path";
5957
- function safeUserIdComponent2(userId) {
5958
- const str = String(userId);
5959
- if (!str || /[/\\]|\.\./.test(str)) {
5960
- throw new Error(`tasks: refusing unsafe userId path component: ${str}`);
5961
- }
5962
- return str;
5963
- }
5964
5948
  function safeTaskScopeKey(scopeKey) {
5965
5949
  const safe = sanitizeFileName(scopeKey);
5966
5950
  if (!safe || safe === "." || safe === "..") {
@@ -5972,7 +5956,7 @@ function taskScopeKey(opts) {
5972
5956
  return opts.topicId?.trim() || opts.session || "default";
5973
5957
  }
5974
5958
  function getTaskFilePath(userId, scopeKey) {
5975
- return join15(resolveStorageDataDir(), "tasks", safeUserIdComponent2(userId), `${safeTaskScopeKey(scopeKey)}.json`);
5959
+ return join15(resolveStorageDataDir(), "tasks", `${safeTaskScopeKey(scopeKey)}.json`);
5976
5960
  }
5977
5961
  function readTasks(userId, scopeKey) {
5978
5962
  const path = getTaskFilePath(userId, scopeKey);
@@ -5992,7 +5976,7 @@ function writeTasks(userId, scopeKey, tasks) {
5992
5976
  const payload = { version: 1, tasks };
5993
5977
  const tmp = `${path}.${process.pid}.tmp`;
5994
5978
  writeFileSync8(tmp, JSON.stringify(payload, null, 2), "utf-8");
5995
- renameSync6(tmp, path);
5979
+ renameSync5(tmp, path);
5996
5980
  }
5997
5981
  function taskFileMtimeNs(userId, scopeKey) {
5998
5982
  try {
@@ -6816,7 +6800,7 @@ function getMcpServersForQuery(opts) {
6816
6800
  if (!opts.topicId)
6817
6801
  throw new Error("getMcpServersForQuery: cron sessionType requires topicId");
6818
6802
  return getCronMcpServers({
6819
- userId: opts.userId || "default",
6803
+ userId: opts.userId || "local",
6820
6804
  session: opts.session || "cron",
6821
6805
  topicId: opts.topicId,
6822
6806
  queryId: opts.queryId,
@@ -6833,7 +6817,7 @@ function getMcpServersForQuery(opts) {
6833
6817
  }
6834
6818
  if (opts.sessionType === "dm" || opts.sessionType === "ephemeral") {
6835
6819
  return getDmMcpServers({
6836
- userId: opts.userId || "default",
6820
+ userId: opts.userId || "local",
6837
6821
  agent: opts.agent,
6838
6822
  playwrightPort: opts.playwrightPort,
6839
6823
  playwrightCapability: opts.playwrightCapability
@@ -6841,7 +6825,7 @@ function getMcpServersForQuery(opts) {
6841
6825
  }
6842
6826
  if (opts.sessionType === "manager") {
6843
6827
  return getManagerMcpServers({
6844
- userId: opts.userId || "default",
6828
+ userId: opts.userId || "local",
6845
6829
  session: opts.session,
6846
6830
  topicId: opts.topicId,
6847
6831
  queryId: opts.queryId,
@@ -6858,7 +6842,7 @@ function getMcpServersForQuery(opts) {
6858
6842
  });
6859
6843
  }
6860
6844
  return getForumMcpServers({
6861
- userId: opts.userId || "default",
6845
+ userId: opts.userId || "local",
6862
6846
  session: opts.session || "default",
6863
6847
  topicId: opts.topicId,
6864
6848
  subagentParentTopicId: opts.subagentParentTopicId,
@@ -7693,7 +7677,7 @@ var init_claude_provider = __esm(async () => {
7693
7677
  });
7694
7678
 
7695
7679
  // ../../packages/core/src/version.ts
7696
- var NEGOTIUM_VERSION = "0.1.49";
7680
+ var NEGOTIUM_VERSION = "0.2.0";
7697
7681
 
7698
7682
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
7699
7683
  import { spawn as spawn6 } from "child_process";
@@ -7704,7 +7688,7 @@ import {
7704
7688
  existsSync as existsSync14,
7705
7689
  mkdtempSync,
7706
7690
  readFileSync as readFileSync12,
7707
- renameSync as renameSync7,
7691
+ renameSync as renameSync6,
7708
7692
  rmSync as rmSync2,
7709
7693
  unlinkSync as unlinkSync11,
7710
7694
  writeFileSync as writeFileSync9
@@ -7752,7 +7736,7 @@ function writePrivateFileAtomic(path, contents) {
7752
7736
  const tempPath = `${path}.${process.pid}.${randomUUID8()}.tmp`;
7753
7737
  try {
7754
7738
  writeFileSync9(tempPath, contents, { encoding: "utf8", mode: 384 });
7755
- renameSync7(tempPath, path);
7739
+ renameSync6(tempPath, path);
7756
7740
  chmodSync4(path, 384);
7757
7741
  } finally {
7758
7742
  try {
@@ -10916,7 +10900,7 @@ var init_idle_archiver = __esm(async () => {
10916
10900
  });
10917
10901
 
10918
10902
  // ../../packages/core/src/agents/topic-cleanup.ts
10919
- import { mkdirSync as mkdirSync13, renameSync as renameSync8, unlinkSync as unlinkSync12, writeFileSync as writeFileSync11 } from "fs";
10903
+ import { mkdirSync as mkdirSync13, renameSync as renameSync7, unlinkSync as unlinkSync12, writeFileSync as writeFileSync11 } from "fs";
10920
10904
  import { dirname as dirname13 } from "path";
10921
10905
  function collectSessionIdsByAgent(entries, extraSessions = []) {
10922
10906
  const out = new Map;
@@ -10987,7 +10971,7 @@ function createTopicLogMaintenance(host) {
10987
10971
  writeFileSync11(tempPath, retained.length > 0 ? `${retained.map((entry) => JSON.stringify(entry)).join(`
10988
10972
  `)}
10989
10973
  ` : "", { flag: "wx" });
10990
- renameSync8(tempPath, path);
10974
+ renameSync7(tempPath, path);
10991
10975
  } catch (e) {
10992
10976
  try {
10993
10977
  unlinkSync12(tempPath);
@@ -11950,7 +11934,7 @@ var init_session_inbox_cleanup = __esm(() => {
11950
11934
  });
11951
11935
 
11952
11936
  // ../../packages/core/src/query/state.ts
11953
- import { mkdirSync as mkdirSync15, renameSync as renameSync9, unlinkSync as unlinkSync15, writeFileSync as writeFileSync13 } from "fs";
11937
+ import { mkdirSync as mkdirSync15, renameSync as renameSync8, unlinkSync as unlinkSync15, writeFileSync as writeFileSync13 } from "fs";
11954
11938
  import { basename as basename5, join as join25 } from "path";
11955
11939
  function createQueryStateStore(options) {
11956
11940
  const sanitize = options.sanitizeTopicId ?? sanitizeId;
@@ -11972,7 +11956,7 @@ function createQueryStateStore(options) {
11972
11956
  const target = queryStateFile(userId, topicId);
11973
11957
  const tmp = `${target}.${process.pid}.${Date.now()}.tmp`;
11974
11958
  writeFileSync13(tmp, JSON.stringify(state));
11975
- renameSync9(tmp, target);
11959
+ renameSync8(tmp, target);
11976
11960
  },
11977
11961
  clear(userId, topicId, legacyTopicName) {
11978
11962
  const paths = [
@@ -13154,7 +13138,7 @@ function promptWithAttachments(prompt, attachments) {
13154
13138
  return composeAttachmentPrompt(prompt, attachments.map(({ filename, path }) => attachmentPromptLine(filename, path)));
13155
13139
  }
13156
13140
  function ingestAttachment(args) {
13157
- const destDir = join27(workspaceCwdFor(args.topicId), "uploads");
13141
+ const destDir = join27(UPLOADS_DIR, args.topicId);
13158
13142
  mkdirSync17(destDir, { recursive: true });
13159
13143
  const safeName = safeAttachmentFilename(args.filename, "upload");
13160
13144
  const destPath = join27(destDir, `${Date.now()}-${randomUUID13().slice(0, 8)}-${safeName}`);
@@ -19338,4 +19322,4 @@ export {
19338
19322
  createAgentHealthMcpServer
19339
19323
  };
19340
19324
 
19341
- //# debugId=BC568829D61D883264756E2164756E21
19325
+ //# debugId=BC238DE297D39F6964756E2164756E21