negotium 0.2.19 → 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.
- package/dist/agent-helpers.js +367 -313
- package/dist/agent-helpers.js.map +17 -17
- package/dist/background-bash.js +3 -2
- package/dist/background-bash.js.map +3 -3
- package/dist/browser-runtime.js +60 -36
- package/dist/browser-runtime.js.map +6 -6
- package/dist/{chunk-fc58cqry.js → chunk-g2kqfdwm.js} +154 -24
- package/dist/{chunk-fc58cqry.js.map → chunk-g2kqfdwm.js.map} +6 -5
- package/dist/hosted-agent.js +183 -53
- package/dist/hosted-agent.js.map +7 -6
- package/dist/main.js +671 -425
- package/dist/main.js.map +23 -23
- package/dist/mcp-factories.js +334 -280
- package/dist/mcp-factories.js.map +17 -17
- package/dist/prompts.js +3 -2
- package/dist/prompts.js.map +3 -3
- package/dist/query-runtime.js +47 -26
- package/dist/query-runtime.js.map +4 -4
- package/dist/registry.js +3 -3
- package/dist/registry.js.map +2 -2
- package/dist/rollout.js +1 -1
- package/dist/runtime/src/agents/archiver.ts +3 -2
- package/dist/runtime/src/application/switch-topic-access-mode.ts +81 -8
- package/dist/runtime/src/bus.ts +19 -2
- package/dist/runtime/src/mcp/session-comm/runtime.ts +16 -0
- package/dist/runtime/src/platform/config.ts +13 -1
- package/dist/runtime/src/runtime/ask-callbacks.ts +19 -11
- package/dist/runtime/src/runtime/background-sessions.ts +9 -7
- package/dist/runtime/src/runtime/visual-store.ts +31 -23
- package/dist/runtime/src/storage/api-topics.ts +26 -0
- package/dist/runtime/src/storage/browser-profiles.ts +16 -8
- package/dist/runtime/src/storage/runtime-events.ts +30 -20
- package/dist/runtime/src/storage/runtime-gateway-submissions.ts +24 -16
- package/dist/runtime/src/storage/runtime-turn-requests.ts +9 -1
- package/dist/runtime/src/storage/self-schedules.ts +32 -24
- package/dist/runtime/src/storage/storage-host.ts +105 -43
- package/dist/runtime/src/storage/vault.ts +12 -3
- package/dist/runtime/src/version.ts +1 -1
- package/dist/runtime-helpers.js +47 -26
- package/dist/runtime-helpers.js.map +4 -4
- package/dist/storage.js +76 -41
- package/dist/storage.js.map +4 -4
- package/dist/types/packages/core/src/storage/api-topics.d.ts +15 -0
- package/dist/types/packages/core/src/storage/storage-host.d.ts +10 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/dist/vault.js +140 -10
- package/dist/vault.js.map +6 -5
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -152,7 +152,7 @@ function browserRsMeetsMinimumVersion(candidate) {
|
|
|
152
152
|
try {
|
|
153
153
|
const output = execFileSync(candidate, ["--version"], {
|
|
154
154
|
encoding: "utf8",
|
|
155
|
-
timeout:
|
|
155
|
+
timeout: BROWSER_RS_VERSION_PROBE_TIMEOUT_MS,
|
|
156
156
|
stdio: ["ignore", "pipe", "ignore"]
|
|
157
157
|
}).trim();
|
|
158
158
|
const match = output.match(/^browser-rs (\d+)\.(\d+)\.(\d+)$/);
|
|
@@ -263,7 +263,7 @@ function resolveDefaultModel(agent, registryDefaultModel) {
|
|
|
263
263
|
function codexAuthFilePath() {
|
|
264
264
|
return process.env.NEGOTIUM_CODEX_AUTH_FILE || join(process.env.CODEX_HOME || join(homedir(), ".codex"), "auth.json");
|
|
265
265
|
}
|
|
266
|
-
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;
|
|
266
|
+
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;
|
|
267
267
|
var init_config = __esm(() => {
|
|
268
268
|
init_config_helpers();
|
|
269
269
|
init_logger();
|
|
@@ -421,6 +421,225 @@ var init_sqlite = __esm(async () => {
|
|
|
421
421
|
}
|
|
422
422
|
});
|
|
423
423
|
|
|
424
|
+
// ../../packages/core/src/storage/storage-host.ts
|
|
425
|
+
import { mkdirSync as mkdirSync2 } from "fs";
|
|
426
|
+
import { homedir as homedir2 } from "os";
|
|
427
|
+
import { dirname as dirname2, join as join2, resolve as resolve2 } from "path";
|
|
428
|
+
function storageState() {
|
|
429
|
+
const holder = globalThis;
|
|
430
|
+
const existing = holder[STORAGE_HOST_STATE];
|
|
431
|
+
if (existing)
|
|
432
|
+
return existing;
|
|
433
|
+
const created = {
|
|
434
|
+
configuredHost: {},
|
|
435
|
+
fallbackDatabase: null,
|
|
436
|
+
fallbackDatabasePath: null,
|
|
437
|
+
frames: [],
|
|
438
|
+
schemaInitializers: [],
|
|
439
|
+
initializedSchemas: new WeakMap,
|
|
440
|
+
initializingDatabases: new WeakSet
|
|
441
|
+
};
|
|
442
|
+
Object.defineProperty(holder, STORAGE_HOST_STATE, {
|
|
443
|
+
value: created,
|
|
444
|
+
enumerable: false,
|
|
445
|
+
writable: false,
|
|
446
|
+
configurable: false
|
|
447
|
+
});
|
|
448
|
+
return created;
|
|
449
|
+
}
|
|
450
|
+
function envPath(name, fallback) {
|
|
451
|
+
const value = process.env[name]?.trim();
|
|
452
|
+
return resolve2(value || fallback);
|
|
453
|
+
}
|
|
454
|
+
function defaultStateDir() {
|
|
455
|
+
return envPath("NEGOTIUM_STATE_DIR", join2(homedir2(), ".negotium"));
|
|
456
|
+
}
|
|
457
|
+
function defaultDataDir() {
|
|
458
|
+
return envPath("NEGOTIUM_DATA_DIR", join2(defaultStateDir(), "data"));
|
|
459
|
+
}
|
|
460
|
+
function defaultLogDir() {
|
|
461
|
+
return envPath("NEGOTIUM_LOG_DIR", join2(defaultStateDir(), "logs"));
|
|
462
|
+
}
|
|
463
|
+
function defaultWorkspaceDir() {
|
|
464
|
+
return envPath("NEGOTIUM_WORKSPACE_DIR", join2(defaultStateDir(), "workspace"));
|
|
465
|
+
}
|
|
466
|
+
function defaultSessionAsksDir() {
|
|
467
|
+
const runDir = envPath("NEGOTIUM_RUN_DIR", join2(defaultStateDir(), "runtime"));
|
|
468
|
+
return join2(runDir, "session-asks");
|
|
469
|
+
}
|
|
470
|
+
function defaultSessionsDatabasePath() {
|
|
471
|
+
return envPath("SESSIONS_DB_PATH", join2(resolveStorageDataDir(), "sessions.db"));
|
|
472
|
+
}
|
|
473
|
+
function isSqliteBusy(error) {
|
|
474
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
475
|
+
return /database is (?:locked|busy)|SQLITE_(?:BUSY|LOCKED)/i.test(message);
|
|
476
|
+
}
|
|
477
|
+
function execWithBusyRetry(database, sql, timeoutMs = SQLITE_INIT_TIMEOUT_MS) {
|
|
478
|
+
const deadline = Date.now() + timeoutMs;
|
|
479
|
+
while (true) {
|
|
480
|
+
try {
|
|
481
|
+
database.exec(sql);
|
|
482
|
+
return;
|
|
483
|
+
} catch (error) {
|
|
484
|
+
if (!isSqliteBusy(error) || Date.now() >= deadline)
|
|
485
|
+
throw error;
|
|
486
|
+
Atomics.wait(SQLITE_INIT_SLEEP, 0, 0, Math.min(SQLITE_INIT_RETRY_MS, deadline - Date.now()));
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
function initializeDatabase(database) {
|
|
491
|
+
database.exec("PRAGMA busy_timeout = 5000");
|
|
492
|
+
execWithBusyRetry(database, "PRAGMA journal_mode = WAL");
|
|
493
|
+
database.exec("PRAGMA foreign_keys = ON");
|
|
494
|
+
database.exec("PRAGMA wal_autocheckpoint = 1000");
|
|
495
|
+
try {
|
|
496
|
+
database.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
497
|
+
} catch {}
|
|
498
|
+
}
|
|
499
|
+
function defaultDatabase() {
|
|
500
|
+
const path = defaultSessionsDatabasePath();
|
|
501
|
+
const state = storageState();
|
|
502
|
+
if (state.fallbackDatabase && state.fallbackDatabasePath === path)
|
|
503
|
+
return state.fallbackDatabase;
|
|
504
|
+
if (state.fallbackDatabase)
|
|
505
|
+
state.fallbackDatabase.close();
|
|
506
|
+
mkdirSync2(dirname2(path), { recursive: true });
|
|
507
|
+
state.fallbackDatabase = new Database(path, { create: true });
|
|
508
|
+
state.fallbackDatabasePath = path;
|
|
509
|
+
initializeDatabase(state.fallbackDatabase);
|
|
510
|
+
return state.fallbackDatabase;
|
|
511
|
+
}
|
|
512
|
+
function resolveStorageDatabase() {
|
|
513
|
+
return storageState().configuredHost.database ?? defaultDatabase();
|
|
514
|
+
}
|
|
515
|
+
function resolveStorageDataDir() {
|
|
516
|
+
return storageState().configuredHost.dataDir ?? defaultDataDir();
|
|
517
|
+
}
|
|
518
|
+
function resolveStorageLogDir() {
|
|
519
|
+
return storageState().configuredHost.logDir ?? defaultLogDir();
|
|
520
|
+
}
|
|
521
|
+
function resolveStorageSessionAsksDir() {
|
|
522
|
+
return storageState().configuredHost.sessionAsksDir ?? defaultSessionAsksDir();
|
|
523
|
+
}
|
|
524
|
+
function resolveStorageWorkspaceDir() {
|
|
525
|
+
return storageState().configuredHost.workspaceDir ?? defaultWorkspaceDir();
|
|
526
|
+
}
|
|
527
|
+
function resolveStorageSharedWikiDir() {
|
|
528
|
+
return storageState().configuredHost.sharedWikiDir ?? join2(resolveStorageWorkspaceDir(), "wiki");
|
|
529
|
+
}
|
|
530
|
+
function resolveStorageUsersLogDir() {
|
|
531
|
+
return storageState().configuredHost.usersLogDir ?? join2(resolveStorageDataDir(), "users");
|
|
532
|
+
}
|
|
533
|
+
function normalizeStorageHostPatch(options) {
|
|
534
|
+
const patch = {};
|
|
535
|
+
if (options.database !== undefined) {
|
|
536
|
+
options.database.exec("PRAGMA foreign_keys = ON");
|
|
537
|
+
patch.database = options.database;
|
|
538
|
+
}
|
|
539
|
+
for (const key of STORAGE_PATH_KEYS) {
|
|
540
|
+
const value = options[key];
|
|
541
|
+
if (value === undefined)
|
|
542
|
+
continue;
|
|
543
|
+
if (!value.trim())
|
|
544
|
+
throw new TypeError(`${key} must not be empty`);
|
|
545
|
+
patch[key] = resolve2(value);
|
|
546
|
+
}
|
|
547
|
+
return Object.freeze(patch);
|
|
548
|
+
}
|
|
549
|
+
function refreshConfiguredHost() {
|
|
550
|
+
const state = storageState();
|
|
551
|
+
state.configuredHost = Object.freeze(Object.assign({}, ...state.frames.filter((frame) => frame.active).map((frame) => frame.patch)));
|
|
552
|
+
}
|
|
553
|
+
function configureStorageHost(options) {
|
|
554
|
+
const frame = { active: true, patch: normalizeStorageHostPatch(options) };
|
|
555
|
+
storageState().frames.push(frame);
|
|
556
|
+
refreshConfiguredHost();
|
|
557
|
+
return () => {
|
|
558
|
+
if (!frame.active)
|
|
559
|
+
return;
|
|
560
|
+
frame.active = false;
|
|
561
|
+
const frames = storageState().frames;
|
|
562
|
+
const index = frames.indexOf(frame);
|
|
563
|
+
if (index >= 0)
|
|
564
|
+
frames.splice(index, 1);
|
|
565
|
+
refreshConfiguredHost();
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
function resetStorageHost() {
|
|
569
|
+
const frames = storageState().frames;
|
|
570
|
+
for (const frame of frames)
|
|
571
|
+
frame.active = false;
|
|
572
|
+
frames.length = 0;
|
|
573
|
+
refreshConfiguredHost();
|
|
574
|
+
}
|
|
575
|
+
function closeStorageDatabase() {
|
|
576
|
+
const state = storageState();
|
|
577
|
+
if (!state.fallbackDatabase)
|
|
578
|
+
return;
|
|
579
|
+
state.fallbackDatabase.close();
|
|
580
|
+
state.fallbackDatabase = null;
|
|
581
|
+
state.fallbackDatabasePath = null;
|
|
582
|
+
}
|
|
583
|
+
function registerStorageSchemaInitializer(initialize, priority = 100) {
|
|
584
|
+
const initializers = storageState().schemaInitializers;
|
|
585
|
+
initializers.push({ initialize, priority });
|
|
586
|
+
initializers.sort((a, b) => a.priority - b.priority);
|
|
587
|
+
}
|
|
588
|
+
function ensureStorageSchemas(database = resolveStorageDatabase()) {
|
|
589
|
+
const state = storageState();
|
|
590
|
+
if (state.initializingDatabases.has(database))
|
|
591
|
+
return;
|
|
592
|
+
let initialized = state.initializedSchemas.get(database);
|
|
593
|
+
if (!initialized) {
|
|
594
|
+
initialized = new Set;
|
|
595
|
+
state.initializedSchemas.set(database, initialized);
|
|
596
|
+
}
|
|
597
|
+
state.initializingDatabases.add(database);
|
|
598
|
+
try {
|
|
599
|
+
for (const entry of state.schemaInitializers) {
|
|
600
|
+
if (initialized.has(entry.initialize))
|
|
601
|
+
continue;
|
|
602
|
+
initialized.add(entry.initialize);
|
|
603
|
+
try {
|
|
604
|
+
entry.initialize(database);
|
|
605
|
+
} catch (error) {
|
|
606
|
+
initialized.delete(entry.initialize);
|
|
607
|
+
throw error;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
} finally {
|
|
611
|
+
state.initializingDatabases.delete(database);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
var STORAGE_HOST_STATE, SQLITE_INIT_RETRY_MS = 25, SQLITE_INIT_TIMEOUT_MS = 5000, SQLITE_INIT_SLEEP, STORAGE_PATH_KEYS, internalStorageDatabase, storageDatabase;
|
|
615
|
+
var init_storage_host = __esm(async () => {
|
|
616
|
+
await init_sqlite();
|
|
617
|
+
STORAGE_HOST_STATE = Symbol.for("negotium.storage-host.state.v1");
|
|
618
|
+
SQLITE_INIT_SLEEP = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
|
|
619
|
+
STORAGE_PATH_KEYS = [
|
|
620
|
+
"dataDir",
|
|
621
|
+
"logDir",
|
|
622
|
+
"sessionAsksDir",
|
|
623
|
+
"workspaceDir",
|
|
624
|
+
"sharedWikiDir",
|
|
625
|
+
"usersLogDir"
|
|
626
|
+
];
|
|
627
|
+
internalStorageDatabase = new Proxy({}, {
|
|
628
|
+
get(_target, property) {
|
|
629
|
+
const database = resolveStorageDatabase();
|
|
630
|
+
ensureStorageSchemas(database);
|
|
631
|
+
const value = Reflect.get(database, property, database);
|
|
632
|
+
return typeof value === "function" ? value.bind(database) : value;
|
|
633
|
+
},
|
|
634
|
+
set(_target, property, value) {
|
|
635
|
+
const database = resolveStorageDatabase();
|
|
636
|
+
ensureStorageSchemas(database);
|
|
637
|
+
return Reflect.set(database, property, value, database);
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
storageDatabase = internalStorageDatabase;
|
|
641
|
+
});
|
|
642
|
+
|
|
424
643
|
// ../../packages/core/src/storage/vault-crypto-core.ts
|
|
425
644
|
import { createCipheriv, createDecipheriv, createHash, randomBytes as randomBytes2 } from "crypto";
|
|
426
645
|
function encryptionKey(masterKey) {
|
|
@@ -477,8 +696,8 @@ var init_vault_crypto = __esm(() => {
|
|
|
477
696
|
});
|
|
478
697
|
|
|
479
698
|
// ../../packages/core/src/storage/vault.ts
|
|
480
|
-
import { chmodSync as chmodSync2, mkdirSync as
|
|
481
|
-
import { join as
|
|
699
|
+
import { chmodSync as chmodSync2, mkdirSync as mkdirSync3 } from "fs";
|
|
700
|
+
import { join as join3 } from "path";
|
|
482
701
|
function initializeVaultDatabase(database) {
|
|
483
702
|
database.exec("PRAGMA journal_mode = WAL");
|
|
484
703
|
database.exec("PRAGMA busy_timeout = 5000");
|
|
@@ -513,17 +732,18 @@ function initializeVaultDatabase(database) {
|
|
|
513
732
|
}
|
|
514
733
|
}
|
|
515
734
|
function openVaultDatabase(dataDir) {
|
|
516
|
-
const vaultDir =
|
|
517
|
-
const path =
|
|
518
|
-
|
|
735
|
+
const vaultDir = join3(dataDir, "vault");
|
|
736
|
+
const path = join3(vaultDir, "vault.db");
|
|
737
|
+
mkdirSync3(vaultDir, { recursive: true, mode: 448 });
|
|
519
738
|
const database = new Database(path, { create: true });
|
|
520
739
|
chmodSync2(path, 384);
|
|
521
740
|
initializeVaultDatabase(database);
|
|
522
741
|
return database;
|
|
523
742
|
}
|
|
524
743
|
function activeVaultDatabase() {
|
|
525
|
-
if (!vaultDb)
|
|
526
|
-
vaultDb = openVaultDatabase(
|
|
744
|
+
if (!vaultDb) {
|
|
745
|
+
vaultDb = openVaultDatabase(resolveStorageDataDir());
|
|
746
|
+
}
|
|
527
747
|
return vaultDb;
|
|
528
748
|
}
|
|
529
749
|
function configureVaultStorage(options) {
|
|
@@ -532,7 +752,7 @@ function configureVaultStorage(options) {
|
|
|
532
752
|
}
|
|
533
753
|
const previousDb = vaultDb;
|
|
534
754
|
const previousMasterKey = vaultMasterKey;
|
|
535
|
-
const configuredDb = options.database ?? openVaultDatabase(options.dataDir ??
|
|
755
|
+
const configuredDb = options.database ?? openVaultDatabase(options.dataDir ?? resolveStorageDataDir());
|
|
536
756
|
if (options.database)
|
|
537
757
|
initializeVaultDatabase(configuredDb);
|
|
538
758
|
vaultDb = configuredDb;
|
|
@@ -687,7 +907,10 @@ var vaultDb, vaultMasterKey, VAULT_KEY_PATTERN, VAULT_VALUE_MIN_BYTES = 4, VAULT
|
|
|
687
907
|
var init_vault = __esm(async () => {
|
|
688
908
|
init_config();
|
|
689
909
|
init_vault_crypto();
|
|
690
|
-
await
|
|
910
|
+
await __promiseAll([
|
|
911
|
+
init_sqlite(),
|
|
912
|
+
init_storage_host()
|
|
913
|
+
]);
|
|
691
914
|
vaultMasterKey = VAULT_MASTER_KEY;
|
|
692
915
|
VAULT_KEY_PATTERN = /^[A-Z][A-Z0-9_]{0,127}$/;
|
|
693
916
|
VAULT_VALUE_MAX_BYTES = 64 * 1024;
|
|
@@ -701,8 +924,8 @@ __export(exports_auth_check, {
|
|
|
701
924
|
});
|
|
702
925
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
703
926
|
import { existsSync as existsSync2 } from "fs";
|
|
704
|
-
import { homedir as
|
|
705
|
-
import { join as
|
|
927
|
+
import { homedir as homedir3, platform } from "os";
|
|
928
|
+
import { join as join4 } from "path";
|
|
706
929
|
function hasMaestroCredential(host, key, userId) {
|
|
707
930
|
if (userId && host.getVaultValue(userId, key)?.trim())
|
|
708
931
|
return true;
|
|
@@ -722,7 +945,7 @@ function checkAgentAuth(agent, host = defaultAgentAuthHost, userId) {
|
|
|
722
945
|
case "claude": {
|
|
723
946
|
if (host.environment.ANTHROPIC_API_KEY)
|
|
724
947
|
return { ok: true };
|
|
725
|
-
const path =
|
|
948
|
+
const path = join4(host.homeDirectory(), ".claude", ".credentials.json");
|
|
726
949
|
if (host.operatingSystem() === "darwin") {
|
|
727
950
|
if (host.hasMacOsCredential("Claude Code-credentials") || host.exists(path)) {
|
|
728
951
|
return { ok: true };
|
|
@@ -775,7 +998,7 @@ var init_auth_check = __esm(async () => {
|
|
|
775
998
|
codexAuthFilePath,
|
|
776
999
|
exists: existsSync2,
|
|
777
1000
|
environment: process.env,
|
|
778
|
-
homeDirectory:
|
|
1001
|
+
homeDirectory: homedir3,
|
|
779
1002
|
operatingSystem: platform,
|
|
780
1003
|
hasMacOsCredential(service) {
|
|
781
1004
|
try {
|
|
@@ -842,12 +1065,12 @@ function createCodexTreeManager(host, options = {}) {
|
|
|
842
1065
|
const previous = spawnChain;
|
|
843
1066
|
let release;
|
|
844
1067
|
let released = false;
|
|
845
|
-
spawnChain = new Promise((
|
|
1068
|
+
spawnChain = new Promise((resolve3) => {
|
|
846
1069
|
release = () => {
|
|
847
1070
|
if (released)
|
|
848
1071
|
return;
|
|
849
1072
|
released = true;
|
|
850
|
-
|
|
1073
|
+
resolve3();
|
|
851
1074
|
};
|
|
852
1075
|
});
|
|
853
1076
|
await previous;
|
|
@@ -954,7 +1177,7 @@ function createCodexTreeManager(host, options = {}) {
|
|
|
954
1177
|
return;
|
|
955
1178
|
const deadline = Date.now() + Math.max(0, graceMs);
|
|
956
1179
|
while (Date.now() < deadline && hasSurvivors(plan.targets)) {
|
|
957
|
-
await new Promise((
|
|
1180
|
+
await new Promise((resolve3) => setTimeout(resolve3, Math.min(100, Math.max(1, deadline - Date.now()))));
|
|
958
1181
|
}
|
|
959
1182
|
killStragglers(plan);
|
|
960
1183
|
}
|
|
@@ -1102,8 +1325,8 @@ function renderUserTurnBatch(messages) {
|
|
|
1102
1325
|
}
|
|
1103
1326
|
|
|
1104
1327
|
// ../../packages/core/src/agents/rollout/shared.ts
|
|
1105
|
-
import { mkdirSync as
|
|
1106
|
-
import { resolve as
|
|
1328
|
+
import { mkdirSync as mkdirSync4 } from "fs";
|
|
1329
|
+
import { resolve as resolve3 } from "path";
|
|
1107
1330
|
function clone(obj) {
|
|
1108
1331
|
return structuredClone(obj);
|
|
1109
1332
|
}
|
|
@@ -1113,7 +1336,7 @@ function assertUuidLike(label, value) {
|
|
|
1113
1336
|
}
|
|
1114
1337
|
}
|
|
1115
1338
|
function assertCwdInWorkspace(cwd) {
|
|
1116
|
-
const abs =
|
|
1339
|
+
const abs = resolve3(cwd);
|
|
1117
1340
|
const ok = trustedWorkspaceRoots.some((root) => abs === root || abs.startsWith(`${root}/`));
|
|
1118
1341
|
if (!ok) {
|
|
1119
1342
|
throw new Error(`rollout: cwd outside trusted workspace roots: ${cwd} (resolved=${abs})`);
|
|
@@ -1122,7 +1345,7 @@ function assertCwdInWorkspace(cwd) {
|
|
|
1122
1345
|
function ensureCwdExists(cwd) {
|
|
1123
1346
|
assertCwdInWorkspace(cwd);
|
|
1124
1347
|
try {
|
|
1125
|
-
|
|
1348
|
+
mkdirSync4(cwd, { recursive: true });
|
|
1126
1349
|
} catch (err) {
|
|
1127
1350
|
logger.warn({ err, cwd }, "rollout: ensureCwdExists failed \u2014 caller should pre-create cwd");
|
|
1128
1351
|
}
|
|
@@ -1243,8 +1466,8 @@ var init_shared = __esm(() => {
|
|
|
1243
1466
|
DM_WORKSPACE_DIR,
|
|
1244
1467
|
SESSION_WORKSPACE_DIR,
|
|
1245
1468
|
TOPIC_WORKSPACE_DIR
|
|
1246
|
-
].map((root) =>
|
|
1247
|
-
FIXTURES_DIR =
|
|
1469
|
+
].map((root) => resolve3(root));
|
|
1470
|
+
FIXTURES_DIR = resolve3(PROJECT_ROOT, "src", "agents", "fixtures");
|
|
1248
1471
|
UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
1249
1472
|
});
|
|
1250
1473
|
|
|
@@ -1279,7 +1502,7 @@ import {
|
|
|
1279
1502
|
appendFileSync,
|
|
1280
1503
|
closeSync,
|
|
1281
1504
|
fsyncSync,
|
|
1282
|
-
mkdirSync as
|
|
1505
|
+
mkdirSync as mkdirSync5,
|
|
1283
1506
|
openSync,
|
|
1284
1507
|
readFileSync as readFileSync2,
|
|
1285
1508
|
renameSync,
|
|
@@ -1287,7 +1510,7 @@ import {
|
|
|
1287
1510
|
unlinkSync as unlinkSync2,
|
|
1288
1511
|
writeFileSync as writeFileSync2
|
|
1289
1512
|
} from "fs";
|
|
1290
|
-
import { dirname as
|
|
1513
|
+
import { dirname as dirname3 } from "path";
|
|
1291
1514
|
function readJsonlLines(filePath) {
|
|
1292
1515
|
return readFileSync2(filePath, "utf-8").trim().split(`
|
|
1293
1516
|
`).filter(Boolean);
|
|
@@ -1335,7 +1558,7 @@ function appendJsonlEntry(filePath, entry) {
|
|
|
1335
1558
|
`);
|
|
1336
1559
|
}
|
|
1337
1560
|
function appendJsonlLine(filePath, line) {
|
|
1338
|
-
|
|
1561
|
+
mkdirSync5(dirname3(filePath), { recursive: true });
|
|
1339
1562
|
const lockPath = `${filePath}${LOCK_SUFFIX}`;
|
|
1340
1563
|
const payload = line.endsWith(`
|
|
1341
1564
|
`) ? line : `${line}
|
|
@@ -1366,8 +1589,8 @@ function appendJsonlLine(filePath, line) {
|
|
|
1366
1589
|
}
|
|
1367
1590
|
}
|
|
1368
1591
|
function writeJsonlFile(filePath, entries) {
|
|
1369
|
-
const dir =
|
|
1370
|
-
|
|
1592
|
+
const dir = dirname3(filePath);
|
|
1593
|
+
mkdirSync5(dir, { recursive: true });
|
|
1371
1594
|
const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
1372
1595
|
const payload = `${entries.map((e) => JSON.stringify(e)).join(`
|
|
1373
1596
|
`)}
|
|
@@ -1425,12 +1648,12 @@ var init_jsonl = __esm(() => {
|
|
|
1425
1648
|
// ../../packages/core/src/agents/rollout/claude.ts
|
|
1426
1649
|
import { randomUUID } from "crypto";
|
|
1427
1650
|
import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
1428
|
-
import { homedir as
|
|
1429
|
-
import { join as
|
|
1651
|
+
import { homedir as homedir4 } from "os";
|
|
1652
|
+
import { join as join5 } from "path";
|
|
1430
1653
|
function loadClaudeAttachments() {
|
|
1431
1654
|
if (_attachmentsCache)
|
|
1432
1655
|
return _attachmentsCache;
|
|
1433
|
-
const raw = readFileSync3(
|
|
1656
|
+
const raw = readFileSync3(join5(FIXTURES_DIR, "claude-attachments.jsonl"), "utf8");
|
|
1434
1657
|
const lines = parseJsonlText(raw);
|
|
1435
1658
|
if (lines.length < 2) {
|
|
1436
1659
|
throw new Error(`loadClaudeAttachments: expected >=2 entries in claude-attachments.jsonl, got ${lines.length}`);
|
|
@@ -1531,8 +1754,8 @@ function writeClaudeRollout(opts) {
|
|
|
1531
1754
|
});
|
|
1532
1755
|
lastUuid = assistantUuid;
|
|
1533
1756
|
}
|
|
1534
|
-
const projectsDir =
|
|
1535
|
-
const path =
|
|
1757
|
+
const projectsDir = join5(homedir4(), ".claude", "projects", encodeClaudeCwd(opts.cwd));
|
|
1758
|
+
const path = join5(projectsDir, `${sessionId}.jsonl`);
|
|
1536
1759
|
writeJsonlFile(path, lines);
|
|
1537
1760
|
logger.info({ sessionId, path, pairs: pairs.length }, "writeClaudeRollout: synthetic rollout placed");
|
|
1538
1761
|
return { sessionId, rolloutPath: path };
|
|
@@ -1545,9 +1768,9 @@ var init_claude = __esm(() => {
|
|
|
1545
1768
|
});
|
|
1546
1769
|
|
|
1547
1770
|
// ../../packages/core/src/agents/claude-registry.ts
|
|
1548
|
-
import { existsSync as existsSync4, mkdirSync as
|
|
1549
|
-
import { homedir as
|
|
1550
|
-
import { join as
|
|
1771
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync6, readdirSync, renameSync as renameSync2, unlinkSync as unlinkSync3 } from "fs";
|
|
1772
|
+
import { homedir as homedir5 } from "os";
|
|
1773
|
+
import { join as join6 } from "path";
|
|
1551
1774
|
var ALIAS_MAP, VALID_ALIASES, VALID_EFFORTS, claudeRegistry, claudeRegistryOperations;
|
|
1552
1775
|
var init_claude_registry = __esm(() => {
|
|
1553
1776
|
init_claude();
|
|
@@ -1594,15 +1817,15 @@ var init_claude_registry = __esm(() => {
|
|
|
1594
1817
|
const result = await forkSession(parentSessionId, {
|
|
1595
1818
|
...title ? { title } : {}
|
|
1596
1819
|
});
|
|
1597
|
-
const projectsRoot =
|
|
1598
|
-
const destDir =
|
|
1599
|
-
const destPath =
|
|
1820
|
+
const projectsRoot = join6(homedir5(), ".claude", "projects");
|
|
1821
|
+
const destDir = join6(projectsRoot, encodeClaudeCwd(cwd));
|
|
1822
|
+
const destPath = join6(destDir, `${result.sessionId}.jsonl`);
|
|
1600
1823
|
if (!existsSync4(destPath)) {
|
|
1601
|
-
const sourcePath = readdirSync(projectsRoot).map((d) =>
|
|
1824
|
+
const sourcePath = readdirSync(projectsRoot).map((d) => join6(projectsRoot, d, `${result.sessionId}.jsonl`)).find((p) => existsSync4(p));
|
|
1602
1825
|
if (!sourcePath) {
|
|
1603
1826
|
throw new Error(`claude forkSession: fork rollout ${result.sessionId}.jsonl not found under ${projectsRoot}`);
|
|
1604
1827
|
}
|
|
1605
|
-
|
|
1828
|
+
mkdirSync6(destDir, { recursive: true });
|
|
1606
1829
|
renameSync2(sourcePath, destPath);
|
|
1607
1830
|
}
|
|
1608
1831
|
return {
|
|
@@ -1611,10 +1834,10 @@ var init_claude_registry = __esm(() => {
|
|
|
1611
1834
|
};
|
|
1612
1835
|
},
|
|
1613
1836
|
async cleanupRollouts({ cwd, sessionIds }) {
|
|
1614
|
-
const projectsDir =
|
|
1837
|
+
const projectsDir = join6(homedir5(), ".claude", "projects", encodeClaudeCwd(cwd));
|
|
1615
1838
|
const failures = [];
|
|
1616
1839
|
for (const sid of sessionIds) {
|
|
1617
|
-
const path =
|
|
1840
|
+
const path = join6(projectsDir, `${sid}.jsonl`);
|
|
1618
1841
|
try {
|
|
1619
1842
|
unlinkSync3(path);
|
|
1620
1843
|
} catch (e) {
|
|
@@ -1636,7 +1859,7 @@ var exports_version = {};
|
|
|
1636
1859
|
__export(exports_version, {
|
|
1637
1860
|
NEGOTIUM_VERSION: () => NEGOTIUM_VERSION
|
|
1638
1861
|
});
|
|
1639
|
-
var NEGOTIUM_VERSION = "0.2.
|
|
1862
|
+
var NEGOTIUM_VERSION = "0.2.20";
|
|
1640
1863
|
|
|
1641
1864
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
1642
1865
|
import { spawn } from "child_process";
|
|
@@ -1654,7 +1877,7 @@ import {
|
|
|
1654
1877
|
} from "fs";
|
|
1655
1878
|
import { createRequire as createRequire2 } from "module";
|
|
1656
1879
|
import { tmpdir } from "os";
|
|
1657
|
-
import { dirname as
|
|
1880
|
+
import { dirname as dirname4, join as join7 } from "path";
|
|
1658
1881
|
function readPackageVersion(packageJsonPath) {
|
|
1659
1882
|
const parsed = JSON.parse(readFileSync4(packageJsonPath, "utf8"));
|
|
1660
1883
|
if (typeof parsed.version !== "string" || !parsed.version.trim()) {
|
|
@@ -1663,7 +1886,7 @@ function readPackageVersion(packageJsonPath) {
|
|
|
1663
1886
|
return parsed.version;
|
|
1664
1887
|
}
|
|
1665
1888
|
function codexCliScriptPath() {
|
|
1666
|
-
return
|
|
1889
|
+
return join7(dirname4(bundledCodexPackagePath), "bin", "codex.js");
|
|
1667
1890
|
}
|
|
1668
1891
|
function parseCodexModelCache(contents, sourcePath) {
|
|
1669
1892
|
let parsed;
|
|
@@ -1704,14 +1927,14 @@ function writePrivateFileAtomic(path, contents) {
|
|
|
1704
1927
|
}
|
|
1705
1928
|
}
|
|
1706
1929
|
function bundledCodexModelCachePath(authFilePath) {
|
|
1707
|
-
return
|
|
1930
|
+
return join7(dirname4(authFilePath), NEGOTIUM_MODEL_CACHE);
|
|
1708
1931
|
}
|
|
1709
1932
|
async function bootstrapCodexModelCache(codexHome, cachePath) {
|
|
1710
1933
|
const child = spawn(process.execPath, [codexCliScriptPath(), "app-server", "--stdio"], {
|
|
1711
1934
|
env: { ...process.env, CODEX_HOME: codexHome },
|
|
1712
1935
|
stdio: ["pipe", "pipe", "pipe"]
|
|
1713
1936
|
});
|
|
1714
|
-
await new Promise((
|
|
1937
|
+
await new Promise((resolve4, reject) => {
|
|
1715
1938
|
let settled = false;
|
|
1716
1939
|
let stdoutBuffer = "";
|
|
1717
1940
|
let stderr = "";
|
|
@@ -1730,7 +1953,7 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
|
|
|
1730
1953
|
else if (!existsSync5(cachePath))
|
|
1731
1954
|
reject(new Error("Codex did not create its model cache"));
|
|
1732
1955
|
else
|
|
1733
|
-
|
|
1956
|
+
resolve4();
|
|
1734
1957
|
};
|
|
1735
1958
|
const send = (message) => {
|
|
1736
1959
|
child.stdin.write(`${JSON.stringify(message)}
|
|
@@ -1789,16 +2012,16 @@ async function bootstrapCodexModelCache(codexHome, cachePath) {
|
|
|
1789
2012
|
});
|
|
1790
2013
|
}
|
|
1791
2014
|
async function bootstrapIsolatedCodexModelCache(authFilePath, bootstrap) {
|
|
1792
|
-
const sourceHome =
|
|
1793
|
-
const isolatedHome = mkdtempSync(
|
|
1794
|
-
const isolatedCachePath =
|
|
2015
|
+
const sourceHome = dirname4(authFilePath);
|
|
2016
|
+
const isolatedHome = mkdtempSync(join7(tmpdir(), "negotium-codex-models-"));
|
|
2017
|
+
const isolatedCachePath = join7(isolatedHome, "models_cache.json");
|
|
1795
2018
|
try {
|
|
1796
|
-
const isolatedAuthPath =
|
|
2019
|
+
const isolatedAuthPath = join7(isolatedHome, "auth.json");
|
|
1797
2020
|
copyFileSync(authFilePath, isolatedAuthPath);
|
|
1798
2021
|
chmodSync3(isolatedAuthPath, 384);
|
|
1799
|
-
const sourceConfigPath =
|
|
2022
|
+
const sourceConfigPath = join7(sourceHome, "config.toml");
|
|
1800
2023
|
if (existsSync5(sourceConfigPath)) {
|
|
1801
|
-
const isolatedConfigPath =
|
|
2024
|
+
const isolatedConfigPath = join7(isolatedHome, "config.toml");
|
|
1802
2025
|
copyFileSync(sourceConfigPath, isolatedConfigPath);
|
|
1803
2026
|
chmodSync3(isolatedConfigPath, 384);
|
|
1804
2027
|
}
|
|
@@ -1809,7 +2032,7 @@ async function bootstrapIsolatedCodexModelCache(authFilePath, bootstrap) {
|
|
|
1809
2032
|
}
|
|
1810
2033
|
}
|
|
1811
2034
|
async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexModelCache) {
|
|
1812
|
-
const codexHome =
|
|
2035
|
+
const codexHome = dirname4(authFilePath);
|
|
1813
2036
|
const configuredCachePath = process.env.NEGOTIUM_CODEX_MODELS_CACHE_FILE;
|
|
1814
2037
|
if (configuredCachePath) {
|
|
1815
2038
|
if (!existsSync5(configuredCachePath)) {
|
|
@@ -1819,7 +2042,7 @@ async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexMod
|
|
|
1819
2042
|
return configuredCachePath;
|
|
1820
2043
|
}
|
|
1821
2044
|
const bundledCachePath = bundledCodexModelCachePath(authFilePath);
|
|
1822
|
-
const sharedCachePath =
|
|
2045
|
+
const sharedCachePath = join7(codexHome, "models_cache.json");
|
|
1823
2046
|
if (existsSync5(sharedCachePath)) {
|
|
1824
2047
|
try {
|
|
1825
2048
|
const shared = readCompatibleCodexModelCache(sharedCachePath);
|
|
@@ -1838,8 +2061,8 @@ async function ensureCodexModelCache(authFilePath, bootstrap = bootstrapCodexMod
|
|
|
1838
2061
|
return bundledCachePath;
|
|
1839
2062
|
}
|
|
1840
2063
|
function writeCodexCatalogWithNativeMultiAgentDisabled(authFilePath, sourcePath) {
|
|
1841
|
-
const codexHome =
|
|
1842
|
-
const outputPath =
|
|
2064
|
+
const codexHome = dirname4(authFilePath);
|
|
2065
|
+
const outputPath = join7(codexHome, NEGOTIUM_MODEL_CATALOG);
|
|
1843
2066
|
const parsed = readCodexModelCache(sourcePath).parsed;
|
|
1844
2067
|
const models = parsed.models.map((model, index) => {
|
|
1845
2068
|
if (!model || typeof model !== "object" || Array.isArray(model)) {
|
|
@@ -1866,9 +2089,9 @@ var init_codex_native_multi_agent = __esm(() => {
|
|
|
1866
2089
|
|
|
1867
2090
|
// ../../packages/core/src/security/sensitive-path.ts
|
|
1868
2091
|
import { realpathSync } from "fs";
|
|
1869
|
-
import { resolve as
|
|
2092
|
+
import { resolve as resolve4 } from "path";
|
|
1870
2093
|
function isSensitivePath(filePath) {
|
|
1871
|
-
const normalized =
|
|
2094
|
+
const normalized = resolve4(filePath);
|
|
1872
2095
|
if (SENSITIVE_PATH_PATTERNS.some((p) => p.test(normalized)))
|
|
1873
2096
|
return true;
|
|
1874
2097
|
try {
|
|
@@ -2388,12 +2611,12 @@ function createBackgroundBashManager(options = {}) {
|
|
|
2388
2611
|
usedPorts.clear();
|
|
2389
2612
|
knownContexts.clear();
|
|
2390
2613
|
const deadline = now() + 3000;
|
|
2391
|
-
await Promise.all(entries.map((instance) => new Promise((
|
|
2614
|
+
await Promise.all(entries.map((instance) => new Promise((resolve5) => {
|
|
2392
2615
|
if (instance.process.exitCode !== null || instance.process.killed)
|
|
2393
|
-
return
|
|
2394
|
-
instance.process.once("exit",
|
|
2395
|
-
instance.process.once("error",
|
|
2396
|
-
const timer = setTimeout(
|
|
2616
|
+
return resolve5();
|
|
2617
|
+
instance.process.once("exit", resolve5);
|
|
2618
|
+
instance.process.once("error", resolve5);
|
|
2619
|
+
const timer = setTimeout(resolve5, Math.max(0, deadline - now()));
|
|
2397
2620
|
timer.unref?.();
|
|
2398
2621
|
})));
|
|
2399
2622
|
}
|
|
@@ -3006,7 +3229,7 @@ var init_mcp_config = __esm(() => {
|
|
|
3006
3229
|
|
|
3007
3230
|
// ../../packages/core/src/agents/execution-host.ts
|
|
3008
3231
|
import { AsyncLocalStorage } from "async_hooks";
|
|
3009
|
-
import { dirname as
|
|
3232
|
+
import { dirname as dirname5 } from "path";
|
|
3010
3233
|
function activeHost() {
|
|
3011
3234
|
const scoped = scopedHost.getStore();
|
|
3012
3235
|
if (scoped)
|
|
@@ -3041,7 +3264,7 @@ function hostedCodexAuthFilePath() {
|
|
|
3041
3264
|
return activeHost().codexAuthFilePath();
|
|
3042
3265
|
}
|
|
3043
3266
|
function hostedCodexHomePath() {
|
|
3044
|
-
return
|
|
3267
|
+
return dirname5(hostedCodexAuthFilePath());
|
|
3045
3268
|
}
|
|
3046
3269
|
var defaultHost, hostRegistrations, scopedHost;
|
|
3047
3270
|
var init_execution_host = __esm(async () => {
|
|
@@ -3065,14 +3288,14 @@ var init_execution_host = __esm(async () => {
|
|
|
3065
3288
|
// ../../packages/core/src/agents/rollout/codex.ts
|
|
3066
3289
|
import { randomBytes as randomBytes4 } from "crypto";
|
|
3067
3290
|
import { existsSync as existsSync6, readFileSync as readFileSync5, realpathSync as realpathSync2, statSync as statSync2, unlinkSync as unlinkSync5 } from "fs";
|
|
3068
|
-
import { basename, dirname as
|
|
3291
|
+
import { basename, dirname as dirname6, join as join8, resolve as resolve5 } from "path";
|
|
3069
3292
|
function codexSessionsDir() {
|
|
3070
|
-
return
|
|
3293
|
+
return join8(hostedCodexHomePath(), "sessions");
|
|
3071
3294
|
}
|
|
3072
3295
|
function loadCodexShell() {
|
|
3073
3296
|
if (_shellCache)
|
|
3074
3297
|
return _shellCache;
|
|
3075
|
-
const raw = readFileSync5(
|
|
3298
|
+
const raw = readFileSync5(join8(FIXTURES_DIR, "codex-shell.jsonl"), "utf8");
|
|
3076
3299
|
const lines = parseJsonlText(raw);
|
|
3077
3300
|
if (lines.length < 5) {
|
|
3078
3301
|
throw new Error(`loadCodexShell: expected >=5 entries in codex-shell.jsonl, got ${lines.length}`);
|
|
@@ -3139,16 +3362,16 @@ function codexRolloutPath(threadId, fallback) {
|
|
|
3139
3362
|
const hh = String(createdAt.getHours()).padStart(2, "0");
|
|
3140
3363
|
const min = String(createdAt.getMinutes()).padStart(2, "0");
|
|
3141
3364
|
const ss = String(createdAt.getSeconds()).padStart(2, "0");
|
|
3142
|
-
const dir =
|
|
3143
|
-
return
|
|
3365
|
+
const dir = join8(codexSessionsDir(), yyyy, mm, dd);
|
|
3366
|
+
return join8(dir, `rollout-${yyyy}-${mm}-${dd}T${hh}-${min}-${ss}-${threadId}.jsonl`);
|
|
3144
3367
|
}
|
|
3145
3368
|
function canonicalFilePath(path) {
|
|
3146
|
-
const absolute =
|
|
3369
|
+
const absolute = resolve5(path);
|
|
3147
3370
|
try {
|
|
3148
3371
|
return realpathSync2(absolute);
|
|
3149
3372
|
} catch {
|
|
3150
3373
|
try {
|
|
3151
|
-
return
|
|
3374
|
+
return join8(realpathSync2(dirname6(absolute)), basename(absolute));
|
|
3152
3375
|
} catch {
|
|
3153
3376
|
return absolute;
|
|
3154
3377
|
}
|
|
@@ -3378,19 +3601,19 @@ function latestCodexRolloutPath(threadId) {
|
|
|
3378
3601
|
try {
|
|
3379
3602
|
if (buckets) {
|
|
3380
3603
|
for (const bucket of buckets) {
|
|
3381
|
-
const dir =
|
|
3604
|
+
const dir = join8(sessionsDir, bucket);
|
|
3382
3605
|
if (!existsSync6(dir))
|
|
3383
3606
|
continue;
|
|
3384
3607
|
const glob = new Bun.Glob(`rollout-*-${threadId}.jsonl`);
|
|
3385
3608
|
for (const rel of glob.scanSync({ cwd: dir, onlyFiles: true })) {
|
|
3386
|
-
candidates.push(
|
|
3609
|
+
candidates.push(join8(dir, rel));
|
|
3387
3610
|
}
|
|
3388
3611
|
}
|
|
3389
3612
|
}
|
|
3390
3613
|
if (candidates.length === 0) {
|
|
3391
3614
|
const glob = new Bun.Glob(`**/rollout-*-${threadId}.jsonl`);
|
|
3392
3615
|
for (const rel of glob.scanSync({ cwd: sessionsDir, onlyFiles: true })) {
|
|
3393
|
-
candidates.push(
|
|
3616
|
+
candidates.push(join8(sessionsDir, rel));
|
|
3394
3617
|
}
|
|
3395
3618
|
}
|
|
3396
3619
|
return candidates.sort((a, b) => statSync2(b).mtimeMs - statSync2(a).mtimeMs)[0];
|
|
@@ -3511,13 +3734,13 @@ function sweepPriorRolloutsForThread(threadId) {
|
|
|
3511
3734
|
return;
|
|
3512
3735
|
}
|
|
3513
3736
|
for (const bucket of buckets) {
|
|
3514
|
-
const dir =
|
|
3737
|
+
const dir = join8(sessionsDir, bucket);
|
|
3515
3738
|
if (!existsSync6(dir))
|
|
3516
3739
|
continue;
|
|
3517
3740
|
try {
|
|
3518
3741
|
const glob = new Bun.Glob(`rollout-*-${threadId}.jsonl`);
|
|
3519
3742
|
for (const rel of glob.scanSync({ cwd: dir, onlyFiles: true })) {
|
|
3520
|
-
const fullPath =
|
|
3743
|
+
const fullPath = join8(dir, rel);
|
|
3521
3744
|
try {
|
|
3522
3745
|
unlinkSync5(fullPath);
|
|
3523
3746
|
} catch (e) {
|
|
@@ -3535,7 +3758,7 @@ function sweepPriorRolloutsFullTree(threadId, sessionsDir) {
|
|
|
3535
3758
|
try {
|
|
3536
3759
|
const glob = new Bun.Glob(`**/rollout-*-${threadId}.jsonl`);
|
|
3537
3760
|
for (const rel of glob.scanSync({ cwd: sessionsDir, onlyFiles: true })) {
|
|
3538
|
-
const fullPath =
|
|
3761
|
+
const fullPath = join8(sessionsDir, rel);
|
|
3539
3762
|
try {
|
|
3540
3763
|
unlinkSync5(fullPath);
|
|
3541
3764
|
} catch (e) {
|
|
@@ -3601,7 +3824,7 @@ import { spawn as spawn3 } from "child_process";
|
|
|
3601
3824
|
function createCodexAppServerForker(host) {
|
|
3602
3825
|
return async (parentThreadId) => {
|
|
3603
3826
|
const child = host.spawnServer();
|
|
3604
|
-
return await new Promise((
|
|
3827
|
+
return await new Promise((resolve6, reject) => {
|
|
3605
3828
|
let settled = false;
|
|
3606
3829
|
let stdoutBuffer = "";
|
|
3607
3830
|
let stderr = "";
|
|
@@ -3618,7 +3841,7 @@ function createCodexAppServerForker(host) {
|
|
|
3618
3841
|
if (error)
|
|
3619
3842
|
reject(error);
|
|
3620
3843
|
else if (result)
|
|
3621
|
-
|
|
3844
|
+
resolve6(result);
|
|
3622
3845
|
else
|
|
3623
3846
|
reject(new Error("Codex thread fork returned no result"));
|
|
3624
3847
|
};
|
|
@@ -3715,7 +3938,7 @@ var init_codex_app_server = __esm(async () => {
|
|
|
3715
3938
|
|
|
3716
3939
|
// ../../packages/core/src/agents/codex-registry.ts
|
|
3717
3940
|
import { existsSync as existsSync7, unlinkSync as unlinkSync6 } from "fs";
|
|
3718
|
-
import { join as
|
|
3941
|
+
import { join as join9 } from "path";
|
|
3719
3942
|
var VALID_EFFORTS2, codexRegistry, codexRegistryOperations;
|
|
3720
3943
|
var init_codex_registry = __esm(async () => {
|
|
3721
3944
|
init_logger();
|
|
@@ -3760,7 +3983,7 @@ var init_codex_registry = __esm(async () => {
|
|
|
3760
3983
|
async cleanupRollouts({ sessionIds }) {
|
|
3761
3984
|
if (sessionIds.length === 0)
|
|
3762
3985
|
return;
|
|
3763
|
-
const sessionsDir =
|
|
3986
|
+
const sessionsDir = join9(hostedCodexHomePath(), "sessions");
|
|
3764
3987
|
if (!existsSync7(sessionsDir))
|
|
3765
3988
|
return;
|
|
3766
3989
|
const failures = [];
|
|
@@ -3768,7 +3991,7 @@ var init_codex_registry = __esm(async () => {
|
|
|
3768
3991
|
try {
|
|
3769
3992
|
const glob = new Bun.Glob(`**/rollout-*-${tid}.jsonl`);
|
|
3770
3993
|
for await (const rel of glob.scan({ cwd: sessionsDir, onlyFiles: true })) {
|
|
3771
|
-
const path =
|
|
3994
|
+
const path = join9(sessionsDir, rel);
|
|
3772
3995
|
try {
|
|
3773
3996
|
unlinkSync6(path);
|
|
3774
3997
|
} catch (e) {
|
|
@@ -3792,17 +4015,17 @@ var init_codex_registry = __esm(async () => {
|
|
|
3792
4015
|
|
|
3793
4016
|
// ../../packages/core/src/agents/maestro-registry.ts
|
|
3794
4017
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
3795
|
-
import { existsSync as existsSync8, mkdirSync as
|
|
3796
|
-
import { homedir as
|
|
3797
|
-
import { join as
|
|
4018
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
4019
|
+
import { homedir as homedir6 } from "os";
|
|
4020
|
+
import { join as join10, resolve as resolve6 } from "path";
|
|
3798
4021
|
function maestroSessionsDir() {
|
|
3799
|
-
return
|
|
4022
|
+
return join10(process.env.MAESTRO_DATA_DIR ? resolve6(process.env.MAESTRO_DATA_DIR) : join10(homedir6(), ".maestro"), "sessions");
|
|
3800
4023
|
}
|
|
3801
4024
|
function maestroSessionPath(sessionId) {
|
|
3802
|
-
return
|
|
4025
|
+
return join10(maestroSessionsDir(), `${sessionId}.jsonl`);
|
|
3803
4026
|
}
|
|
3804
4027
|
function maestroActiveSessionPath(sessionId) {
|
|
3805
|
-
return
|
|
4028
|
+
return join10(maestroSessionsDir(), `${sessionId}.active.jsonl`);
|
|
3806
4029
|
}
|
|
3807
4030
|
function existingCreatedAt(path) {
|
|
3808
4031
|
if (!existsSync8(path))
|
|
@@ -3824,7 +4047,7 @@ function writeRollout(options) {
|
|
|
3824
4047
|
assertUuidLike("sessionId", sessionId);
|
|
3825
4048
|
ensureCwdExists(options.cwd);
|
|
3826
4049
|
const path = maestroSessionPath(sessionId);
|
|
3827
|
-
|
|
4050
|
+
mkdirSync7(maestroSessionsDir(), { recursive: true });
|
|
3828
4051
|
const messages = extractChatPairs(options.entries).flatMap((pair) => [
|
|
3829
4052
|
{ role: "user", content: nonEmptyTurnText(pair.userText) },
|
|
3830
4053
|
{ role: "assistant", content: nonEmptyTurnText(pair.assistantText) }
|
|
@@ -4026,200 +4249,6 @@ function sanitizeId(id) {
|
|
|
4026
4249
|
return id.replace(/[^a-zA-Z0-9_-]/g, "_") || "_";
|
|
4027
4250
|
}
|
|
4028
4251
|
|
|
4029
|
-
// ../../packages/core/src/storage/storage-host.ts
|
|
4030
|
-
import { mkdirSync as mkdirSync7 } from "fs";
|
|
4031
|
-
import { homedir as homedir6 } from "os";
|
|
4032
|
-
import { dirname as dirname6, join as join10, resolve as resolve6 } from "path";
|
|
4033
|
-
function envPath(name, fallback) {
|
|
4034
|
-
const value = process.env[name]?.trim();
|
|
4035
|
-
return resolve6(value || fallback);
|
|
4036
|
-
}
|
|
4037
|
-
function defaultStateDir() {
|
|
4038
|
-
return envPath("NEGOTIUM_STATE_DIR", join10(homedir6(), ".negotium"));
|
|
4039
|
-
}
|
|
4040
|
-
function defaultDataDir() {
|
|
4041
|
-
return envPath("NEGOTIUM_DATA_DIR", join10(defaultStateDir(), "data"));
|
|
4042
|
-
}
|
|
4043
|
-
function defaultLogDir() {
|
|
4044
|
-
return envPath("NEGOTIUM_LOG_DIR", join10(defaultStateDir(), "logs"));
|
|
4045
|
-
}
|
|
4046
|
-
function defaultWorkspaceDir() {
|
|
4047
|
-
return envPath("NEGOTIUM_WORKSPACE_DIR", join10(defaultStateDir(), "workspace"));
|
|
4048
|
-
}
|
|
4049
|
-
function defaultSessionAsksDir() {
|
|
4050
|
-
const runDir = envPath("NEGOTIUM_RUN_DIR", join10(defaultStateDir(), "runtime"));
|
|
4051
|
-
return join10(runDir, "session-asks");
|
|
4052
|
-
}
|
|
4053
|
-
function defaultSessionsDatabasePath() {
|
|
4054
|
-
return envPath("SESSIONS_DB_PATH", join10(resolveStorageDataDir(), "sessions.db"));
|
|
4055
|
-
}
|
|
4056
|
-
function isSqliteBusy(error) {
|
|
4057
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
4058
|
-
return /database is (?:locked|busy)|SQLITE_(?:BUSY|LOCKED)/i.test(message);
|
|
4059
|
-
}
|
|
4060
|
-
function execWithBusyRetry(database, sql, timeoutMs = SQLITE_INIT_TIMEOUT_MS) {
|
|
4061
|
-
const deadline = Date.now() + timeoutMs;
|
|
4062
|
-
while (true) {
|
|
4063
|
-
try {
|
|
4064
|
-
database.exec(sql);
|
|
4065
|
-
return;
|
|
4066
|
-
} catch (error) {
|
|
4067
|
-
if (!isSqliteBusy(error) || Date.now() >= deadline)
|
|
4068
|
-
throw error;
|
|
4069
|
-
Atomics.wait(SQLITE_INIT_SLEEP, 0, 0, Math.min(SQLITE_INIT_RETRY_MS, deadline - Date.now()));
|
|
4070
|
-
}
|
|
4071
|
-
}
|
|
4072
|
-
}
|
|
4073
|
-
function initializeDatabase(database) {
|
|
4074
|
-
database.exec("PRAGMA busy_timeout = 5000");
|
|
4075
|
-
execWithBusyRetry(database, "PRAGMA journal_mode = WAL");
|
|
4076
|
-
database.exec("PRAGMA foreign_keys = ON");
|
|
4077
|
-
database.exec("PRAGMA wal_autocheckpoint = 1000");
|
|
4078
|
-
try {
|
|
4079
|
-
database.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
4080
|
-
} catch {}
|
|
4081
|
-
}
|
|
4082
|
-
function defaultDatabase() {
|
|
4083
|
-
const path = defaultSessionsDatabasePath();
|
|
4084
|
-
if (fallbackDatabase && fallbackDatabasePath === path)
|
|
4085
|
-
return fallbackDatabase;
|
|
4086
|
-
if (fallbackDatabase)
|
|
4087
|
-
fallbackDatabase.close();
|
|
4088
|
-
mkdirSync7(dirname6(path), { recursive: true });
|
|
4089
|
-
fallbackDatabase = new Database(path, { create: true });
|
|
4090
|
-
fallbackDatabasePath = path;
|
|
4091
|
-
initializeDatabase(fallbackDatabase);
|
|
4092
|
-
return fallbackDatabase;
|
|
4093
|
-
}
|
|
4094
|
-
function resolveStorageDatabase() {
|
|
4095
|
-
return configuredHost.database ?? defaultDatabase();
|
|
4096
|
-
}
|
|
4097
|
-
function resolveStorageDataDir() {
|
|
4098
|
-
return configuredHost.dataDir ?? defaultDataDir();
|
|
4099
|
-
}
|
|
4100
|
-
function resolveStorageLogDir() {
|
|
4101
|
-
return configuredHost.logDir ?? defaultLogDir();
|
|
4102
|
-
}
|
|
4103
|
-
function resolveStorageSessionAsksDir() {
|
|
4104
|
-
return configuredHost.sessionAsksDir ?? defaultSessionAsksDir();
|
|
4105
|
-
}
|
|
4106
|
-
function resolveStorageWorkspaceDir() {
|
|
4107
|
-
return configuredHost.workspaceDir ?? defaultWorkspaceDir();
|
|
4108
|
-
}
|
|
4109
|
-
function resolveStorageSharedWikiDir() {
|
|
4110
|
-
return configuredHost.sharedWikiDir ?? join10(resolveStorageWorkspaceDir(), "wiki");
|
|
4111
|
-
}
|
|
4112
|
-
function resolveStorageUsersLogDir() {
|
|
4113
|
-
return configuredHost.usersLogDir ?? join10(resolveStorageDataDir(), "users");
|
|
4114
|
-
}
|
|
4115
|
-
function normalizeStorageHostPatch(options) {
|
|
4116
|
-
const patch = {};
|
|
4117
|
-
if (options.database !== undefined) {
|
|
4118
|
-
options.database.exec("PRAGMA foreign_keys = ON");
|
|
4119
|
-
patch.database = options.database;
|
|
4120
|
-
}
|
|
4121
|
-
for (const key of STORAGE_PATH_KEYS) {
|
|
4122
|
-
const value = options[key];
|
|
4123
|
-
if (value === undefined)
|
|
4124
|
-
continue;
|
|
4125
|
-
if (!value.trim())
|
|
4126
|
-
throw new TypeError(`${key} must not be empty`);
|
|
4127
|
-
patch[key] = resolve6(value);
|
|
4128
|
-
}
|
|
4129
|
-
return Object.freeze(patch);
|
|
4130
|
-
}
|
|
4131
|
-
function refreshConfiguredHost() {
|
|
4132
|
-
configuredHost = Object.freeze(Object.assign({}, ...storageHostFrames.filter((frame) => frame.active).map((frame) => frame.patch)));
|
|
4133
|
-
}
|
|
4134
|
-
function configureStorageHost(options) {
|
|
4135
|
-
const frame = { active: true, patch: normalizeStorageHostPatch(options) };
|
|
4136
|
-
storageHostFrames.push(frame);
|
|
4137
|
-
refreshConfiguredHost();
|
|
4138
|
-
return () => {
|
|
4139
|
-
if (!frame.active)
|
|
4140
|
-
return;
|
|
4141
|
-
frame.active = false;
|
|
4142
|
-
const index = storageHostFrames.indexOf(frame);
|
|
4143
|
-
if (index >= 0)
|
|
4144
|
-
storageHostFrames.splice(index, 1);
|
|
4145
|
-
refreshConfiguredHost();
|
|
4146
|
-
};
|
|
4147
|
-
}
|
|
4148
|
-
function resetStorageHost() {
|
|
4149
|
-
for (const frame of storageHostFrames)
|
|
4150
|
-
frame.active = false;
|
|
4151
|
-
storageHostFrames.length = 0;
|
|
4152
|
-
refreshConfiguredHost();
|
|
4153
|
-
}
|
|
4154
|
-
function closeStorageDatabase() {
|
|
4155
|
-
if (!fallbackDatabase)
|
|
4156
|
-
return;
|
|
4157
|
-
fallbackDatabase.close();
|
|
4158
|
-
fallbackDatabase = null;
|
|
4159
|
-
fallbackDatabasePath = null;
|
|
4160
|
-
}
|
|
4161
|
-
function registerStorageSchemaInitializer(initialize, priority = 100) {
|
|
4162
|
-
schemaInitializers.push({ initialize, priority });
|
|
4163
|
-
schemaInitializers.sort((a, b) => a.priority - b.priority);
|
|
4164
|
-
}
|
|
4165
|
-
function ensureStorageSchemas(database = resolveStorageDatabase()) {
|
|
4166
|
-
if (initializingDatabases.has(database))
|
|
4167
|
-
return;
|
|
4168
|
-
let initialized = initializedSchemas.get(database);
|
|
4169
|
-
if (!initialized) {
|
|
4170
|
-
initialized = new Set;
|
|
4171
|
-
initializedSchemas.set(database, initialized);
|
|
4172
|
-
}
|
|
4173
|
-
initializingDatabases.add(database);
|
|
4174
|
-
try {
|
|
4175
|
-
for (const entry of schemaInitializers) {
|
|
4176
|
-
if (initialized.has(entry.initialize))
|
|
4177
|
-
continue;
|
|
4178
|
-
initialized.add(entry.initialize);
|
|
4179
|
-
try {
|
|
4180
|
-
entry.initialize(database);
|
|
4181
|
-
} catch (error) {
|
|
4182
|
-
initialized.delete(entry.initialize);
|
|
4183
|
-
throw error;
|
|
4184
|
-
}
|
|
4185
|
-
}
|
|
4186
|
-
} finally {
|
|
4187
|
-
initializingDatabases.delete(database);
|
|
4188
|
-
}
|
|
4189
|
-
}
|
|
4190
|
-
var configuredHost, fallbackDatabase = null, fallbackDatabasePath = null, storageHostFrames, schemaInitializers, initializedSchemas, initializingDatabases, SQLITE_INIT_RETRY_MS = 25, SQLITE_INIT_TIMEOUT_MS = 5000, SQLITE_INIT_SLEEP, STORAGE_PATH_KEYS, internalStorageDatabase, storageDatabase;
|
|
4191
|
-
var init_storage_host = __esm(async () => {
|
|
4192
|
-
await init_sqlite();
|
|
4193
|
-
configuredHost = {};
|
|
4194
|
-
storageHostFrames = [];
|
|
4195
|
-
schemaInitializers = [];
|
|
4196
|
-
initializedSchemas = new WeakMap;
|
|
4197
|
-
initializingDatabases = new WeakSet;
|
|
4198
|
-
SQLITE_INIT_SLEEP = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
|
|
4199
|
-
STORAGE_PATH_KEYS = [
|
|
4200
|
-
"dataDir",
|
|
4201
|
-
"logDir",
|
|
4202
|
-
"sessionAsksDir",
|
|
4203
|
-
"workspaceDir",
|
|
4204
|
-
"sharedWikiDir",
|
|
4205
|
-
"usersLogDir"
|
|
4206
|
-
];
|
|
4207
|
-
internalStorageDatabase = new Proxy({}, {
|
|
4208
|
-
get(_target, property) {
|
|
4209
|
-
const database = resolveStorageDatabase();
|
|
4210
|
-
ensureStorageSchemas(database);
|
|
4211
|
-
const value = Reflect.get(database, property, database);
|
|
4212
|
-
return typeof value === "function" ? value.bind(database) : value;
|
|
4213
|
-
},
|
|
4214
|
-
set(_target, property, value) {
|
|
4215
|
-
const database = resolveStorageDatabase();
|
|
4216
|
-
ensureStorageSchemas(database);
|
|
4217
|
-
return Reflect.set(database, property, value, database);
|
|
4218
|
-
}
|
|
4219
|
-
});
|
|
4220
|
-
storageDatabase = internalStorageDatabase;
|
|
4221
|
-
});
|
|
4222
|
-
|
|
4223
4252
|
// ../../packages/core/src/storage/tasks.ts
|
|
4224
4253
|
var exports_tasks = {};
|
|
4225
4254
|
__export(exports_tasks, {
|
|
@@ -6745,7 +6774,10 @@ function listRecentRuntimeEventsForTopic(topicId, limit = 300) {
|
|
|
6745
6774
|
}
|
|
6746
6775
|
var RUNTIME_EVENT_TYPES, types;
|
|
6747
6776
|
var init_runtime_events = __esm(async () => {
|
|
6748
|
-
await
|
|
6777
|
+
await __promiseAll([
|
|
6778
|
+
init_forum_db(),
|
|
6779
|
+
init_storage_host()
|
|
6780
|
+
]);
|
|
6749
6781
|
RUNTIME_EVENT_TYPES = [
|
|
6750
6782
|
"message",
|
|
6751
6783
|
"message-updated",
|
|
@@ -6754,26 +6786,28 @@ var init_runtime_events = __esm(async () => {
|
|
|
6754
6786
|
"topic-updated",
|
|
6755
6787
|
"topic-deleted"
|
|
6756
6788
|
];
|
|
6757
|
-
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
event_type
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6789
|
+
registerStorageSchemaInitializer((database) => {
|
|
6790
|
+
database.exec(`
|
|
6791
|
+
CREATE TABLE IF NOT EXISTS runtime_events (
|
|
6792
|
+
seq INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
6793
|
+
source_id TEXT NOT NULL,
|
|
6794
|
+
event_type TEXT NOT NULL CHECK (
|
|
6795
|
+
event_type IN (
|
|
6796
|
+
'message',
|
|
6797
|
+
'message-updated',
|
|
6798
|
+
'ai-status',
|
|
6799
|
+
'topic-created',
|
|
6800
|
+
'topic-updated',
|
|
6801
|
+
'topic-deleted'
|
|
6802
|
+
)
|
|
6803
|
+
),
|
|
6804
|
+
topic_id TEXT NOT NULL,
|
|
6805
|
+
payload_json TEXT NOT NULL,
|
|
6806
|
+
created_at TEXT NOT NULL
|
|
6807
|
+
)
|
|
6808
|
+
`);
|
|
6809
|
+
database.exec("CREATE INDEX IF NOT EXISTS idx_runtime_events_topic_seq ON runtime_events(topic_id, seq)");
|
|
6810
|
+
});
|
|
6777
6811
|
types = new Set(RUNTIME_EVENT_TYPES);
|
|
6778
6812
|
});
|
|
6779
6813
|
|
|
@@ -6934,18 +6968,19 @@ class SqliteRuntimeBus {
|
|
|
6934
6968
|
}
|
|
6935
6969
|
}
|
|
6936
6970
|
function runtimeBus() {
|
|
6971
|
+
if (!current)
|
|
6972
|
+
current = new SqliteRuntimeBus;
|
|
6937
6973
|
return current;
|
|
6938
6974
|
}
|
|
6939
6975
|
function setRuntimeBus(bus) {
|
|
6940
6976
|
current = bus;
|
|
6941
6977
|
}
|
|
6942
|
-
var current, WsHub;
|
|
6978
|
+
var current = null, WsHub;
|
|
6943
6979
|
var init_bus = __esm(async () => {
|
|
6944
6980
|
await init_runtime_events();
|
|
6945
|
-
current = new SqliteRuntimeBus;
|
|
6946
6981
|
WsHub = {
|
|
6947
6982
|
get() {
|
|
6948
|
-
return
|
|
6983
|
+
return runtimeBus();
|
|
6949
6984
|
}
|
|
6950
6985
|
};
|
|
6951
6986
|
});
|
|
@@ -7479,6 +7514,7 @@ var exports_api_topics = {};
|
|
|
7479
7514
|
__export(exports_api_topics, {
|
|
7480
7515
|
upsertTopic: () => upsertTopic,
|
|
7481
7516
|
setTopicSessionId: () => setTopicSessionId,
|
|
7517
|
+
setTopicAccessModes: () => setTopicAccessModes,
|
|
7482
7518
|
setApiTopicAgent: () => setApiTopicAgent,
|
|
7483
7519
|
revokeSubagentTellTarget: () => revokeSubagentTellTarget,
|
|
7484
7520
|
reparentTopicChildren: () => reparentTopicChildren,
|
|
@@ -7945,6 +7981,16 @@ function upsertTopic(t) {
|
|
|
7945
7981
|
}
|
|
7946
7982
|
})();
|
|
7947
7983
|
}
|
|
7984
|
+
function setTopicAccessModes(topicIds, accessMode) {
|
|
7985
|
+
if (topicIds.length === 0)
|
|
7986
|
+
return;
|
|
7987
|
+
const normalized = normalizeTopicAccessMode(accessMode);
|
|
7988
|
+
db.transaction(() => {
|
|
7989
|
+
const update = db.query("UPDATE api_topics SET access_mode = ? WHERE id = ?");
|
|
7990
|
+
for (const topicId of topicIds)
|
|
7991
|
+
update.run(normalized, topicId);
|
|
7992
|
+
})();
|
|
7993
|
+
}
|
|
7948
7994
|
function listTopics() {
|
|
7949
7995
|
const rows = db.query("SELECT * FROM api_topics ORDER BY last_message_at DESC").all();
|
|
7950
7996
|
const participants = getAllTopicParticipants();
|
|
@@ -9525,32 +9571,35 @@ var init_self_schedules = __esm(async () => {
|
|
|
9525
9571
|
await __promiseAll([
|
|
9526
9572
|
init_forum_db(),
|
|
9527
9573
|
init_runtime_leases(),
|
|
9528
|
-
init_runtime_topic_state()
|
|
9574
|
+
init_runtime_topic_state(),
|
|
9575
|
+
init_storage_host()
|
|
9529
9576
|
]);
|
|
9530
|
-
|
|
9531
|
-
|
|
9532
|
-
|
|
9533
|
-
|
|
9534
|
-
|
|
9535
|
-
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
|
|
9541
|
-
|
|
9542
|
-
|
|
9543
|
-
|
|
9544
|
-
|
|
9545
|
-
|
|
9546
|
-
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
|
|
9552
|
-
|
|
9553
|
-
|
|
9577
|
+
registerStorageSchemaInitializer((database) => {
|
|
9578
|
+
database.exec(`
|
|
9579
|
+
CREATE TABLE IF NOT EXISTS runtime_self_schedules (
|
|
9580
|
+
id TEXT PRIMARY KEY,
|
|
9581
|
+
topic_id TEXT NOT NULL,
|
|
9582
|
+
user_id TEXT NOT NULL,
|
|
9583
|
+
message TEXT NOT NULL,
|
|
9584
|
+
deliver_at INTEGER NOT NULL,
|
|
9585
|
+
created_at INTEGER NOT NULL,
|
|
9586
|
+
updated_at INTEGER NOT NULL,
|
|
9587
|
+
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'running')),
|
|
9588
|
+
claimed_by TEXT,
|
|
9589
|
+
claimed_at INTEGER,
|
|
9590
|
+
running_query_id TEXT
|
|
9591
|
+
)
|
|
9592
|
+
`);
|
|
9593
|
+
database.exec(`
|
|
9594
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_runtime_self_schedules_one_pending
|
|
9595
|
+
ON runtime_self_schedules(topic_id)
|
|
9596
|
+
WHERE status = 'pending'
|
|
9597
|
+
`);
|
|
9598
|
+
database.exec(`
|
|
9599
|
+
CREATE INDEX IF NOT EXISTS idx_runtime_self_schedules_due
|
|
9600
|
+
ON runtime_self_schedules(status, deliver_at)
|
|
9601
|
+
`);
|
|
9602
|
+
});
|
|
9554
9603
|
});
|
|
9555
9604
|
|
|
9556
9605
|
// ../../packages/core/src/topics/links.ts
|
|
@@ -10240,15 +10289,20 @@ function deleteBrowserProfile(ownerId, rawName) {
|
|
|
10240
10289
|
}
|
|
10241
10290
|
var DEFAULT_BROWSER_PROFILE = "default";
|
|
10242
10291
|
var init_browser_profiles = __esm(async () => {
|
|
10243
|
-
await
|
|
10244
|
-
|
|
10245
|
-
|
|
10246
|
-
|
|
10247
|
-
|
|
10248
|
-
|
|
10249
|
-
|
|
10250
|
-
|
|
10251
|
-
|
|
10292
|
+
await __promiseAll([
|
|
10293
|
+
init_forum_db(),
|
|
10294
|
+
init_storage_host()
|
|
10295
|
+
]);
|
|
10296
|
+
registerStorageSchemaInitializer((database) => {
|
|
10297
|
+
database.exec(`
|
|
10298
|
+
CREATE TABLE IF NOT EXISTS browser_profiles (
|
|
10299
|
+
owner_id TEXT NOT NULL,
|
|
10300
|
+
name TEXT NOT NULL,
|
|
10301
|
+
created_at TEXT NOT NULL,
|
|
10302
|
+
PRIMARY KEY (owner_id, name)
|
|
10303
|
+
)
|
|
10304
|
+
`);
|
|
10305
|
+
});
|
|
10252
10306
|
});
|
|
10253
10307
|
|
|
10254
10308
|
// ../../packages/core/src/platform/playwright/manager.ts
|
|
@@ -11977,9 +12031,9 @@ function formatArchiverBytes(bytes) {
|
|
|
11977
12031
|
function formatArchiverTool(name, input) {
|
|
11978
12032
|
const params = Object.entries(input).map(([key, value]) => {
|
|
11979
12033
|
const rendered = typeof value === "string" ? value : JSON.stringify(value);
|
|
11980
|
-
return `${key}: ${sessionText(rendered ?? "")}`;
|
|
12034
|
+
return `${key}: ${summarizeDisplayText(sessionText(rendered ?? ""))}`;
|
|
11981
12035
|
}).join(", ");
|
|
11982
|
-
return `${name}${params ? `(${params})` : ""}
|
|
12036
|
+
return summarizeDisplayText(`${name}${params ? `(${params})` : ""}`);
|
|
11983
12037
|
}
|
|
11984
12038
|
function createArchiverRuntime(host) {
|
|
11985
12039
|
const activeSessions = new Map;
|
|
@@ -12289,6 +12343,7 @@ function listActiveMemoryArchiverSessions(userId) {
|
|
|
12289
12343
|
}
|
|
12290
12344
|
var MAX_BRIEF_ENTRIES = 8, defaultArchiverRuntime;
|
|
12291
12345
|
var init_archiver = __esm(async () => {
|
|
12346
|
+
init_tool_format();
|
|
12292
12347
|
init_config();
|
|
12293
12348
|
init_logger();
|
|
12294
12349
|
init_builders();
|
|
@@ -13096,7 +13151,7 @@ function detailedToolStep(payload) {
|
|
|
13096
13151
|
const label = compactToolLabel(String(payload.label ?? name));
|
|
13097
13152
|
if (shortName === "ask_session" || shortName === "tell_session") {
|
|
13098
13153
|
const target = typeof input.to === "string" && input.to.trim() ? input.to.trim() : "session";
|
|
13099
|
-
const msg = typeof input.message === "string" ? text(input.message) : "";
|
|
13154
|
+
const msg = typeof input.message === "string" ? summarizeDisplayText(text(input.message)) : "";
|
|
13100
13155
|
const action = shortName === "ask_session" ? "Ask" : "Tell";
|
|
13101
13156
|
return `${action} ${target}${msg ? ` \u2014 ${msg}` : ""}`;
|
|
13102
13157
|
}
|
|
@@ -13122,22 +13177,22 @@ function detailedToolStep(payload) {
|
|
|
13122
13177
|
return `${action} file`;
|
|
13123
13178
|
}
|
|
13124
13179
|
if (shortName === "grep" || shortName === "glob") {
|
|
13125
|
-
const pattern = typeof input.pattern === "string" ? input.pattern : "";
|
|
13180
|
+
const pattern = typeof input.pattern === "string" ? summarizeDisplayText(text(input.pattern)) : "";
|
|
13126
13181
|
const action = shortName === "grep" ? "Grep" : "Glob";
|
|
13127
13182
|
if (pattern)
|
|
13128
|
-
return `${action} '${
|
|
13183
|
+
return `${action} '${pattern}'${path ? ` in ${path}` : ""}`;
|
|
13129
13184
|
if (path)
|
|
13130
13185
|
return `${action} ${path}`;
|
|
13131
13186
|
}
|
|
13132
13187
|
if (shortName === "bash") {
|
|
13133
|
-
const cmd = typeof input.command === "string" ? text(input.command) : "";
|
|
13188
|
+
const cmd = typeof input.command === "string" ? summarizeDisplayText(text(input.command)) : "";
|
|
13134
13189
|
return cmd ? `Bash: ${cmd}` : "Bash";
|
|
13135
13190
|
}
|
|
13136
13191
|
if (shortName === "webfetch" || shortName === "url_fetch") {
|
|
13137
|
-
const url = typeof input.url === "string" ? text(input.url) : "";
|
|
13192
|
+
const url = typeof input.url === "string" ? summarizeDisplayText(text(input.url)) : "";
|
|
13138
13193
|
return url ? `Fetch ${url}` : "WebFetch";
|
|
13139
13194
|
}
|
|
13140
|
-
return label;
|
|
13195
|
+
return summarizeDisplayText(label);
|
|
13141
13196
|
}
|
|
13142
13197
|
function backgroundSessionProgress(topicId, queryId) {
|
|
13143
13198
|
let status = "Running";
|
|
@@ -13165,7 +13220,7 @@ function backgroundSessionProgress(topicId, queryId) {
|
|
|
13165
13220
|
step = text(payload.content);
|
|
13166
13221
|
else if (kind === "tool_output") {
|
|
13167
13222
|
const toolName = toolNames.get(text(payload.toolUseId)) ?? "Tool";
|
|
13168
|
-
step = payload.isError ? `${toolName} failed: ${text(payload.content) || "unknown error"}` : `${toolName} result \xB7 ${byteSize(payload.content)}`;
|
|
13223
|
+
step = payload.isError ? `${toolName} failed: ${summarizeDisplayText(text(payload.content)) || "unknown error"}` : `${toolName} result \xB7 ${byteSize(payload.content)}`;
|
|
13169
13224
|
} else if (kind === "ai_done") {
|
|
13170
13225
|
const usage = payload.usage && typeof payload.usage === "object" ? payload.usage : undefined;
|
|
13171
13226
|
const input = typeof usage?.input === "number" ? usage.input.toLocaleString() : "";
|
|
@@ -13230,6 +13285,7 @@ function listBackgroundSessionsForUser(userId) {
|
|
|
13230
13285
|
}
|
|
13231
13286
|
var providers, transientSessions;
|
|
13232
13287
|
var init_background_sessions = __esm(async () => {
|
|
13288
|
+
init_tool_format();
|
|
13233
13289
|
init_background_session_policy();
|
|
13234
13290
|
await __promiseAll([
|
|
13235
13291
|
init_archiver(),
|
|
@@ -13535,10 +13591,11 @@ var init_runtime_turn_requests = __esm(async () => {
|
|
|
13535
13591
|
await __promiseAll([
|
|
13536
13592
|
init_forum_db(),
|
|
13537
13593
|
init_runtime_leases(),
|
|
13538
|
-
init_runtime_topic_state()
|
|
13594
|
+
init_runtime_topic_state(),
|
|
13595
|
+
init_storage_host()
|
|
13539
13596
|
]);
|
|
13540
13597
|
REQUEST_CLAIM_STALE_MS = TURN_LEASE_STALE_MS;
|
|
13541
|
-
ensureRuntimeUserTurnRequestsSchema(
|
|
13598
|
+
registerStorageSchemaInitializer((database) => ensureRuntimeUserTurnRequestsSchema(database));
|
|
13542
13599
|
});
|
|
13543
13600
|
|
|
13544
13601
|
// ../../packages/core/src/topics/session.ts
|
|
@@ -15800,19 +15857,22 @@ var pendingAsks, MAX_ASK_AGE_MS;
|
|
|
15800
15857
|
var init_ask_callbacks = __esm(async () => {
|
|
15801
15858
|
await __promiseAll([
|
|
15802
15859
|
init_forum_db(),
|
|
15803
|
-
init_session_asks()
|
|
15860
|
+
init_session_asks(),
|
|
15861
|
+
init_storage_host()
|
|
15804
15862
|
]);
|
|
15805
|
-
|
|
15806
|
-
|
|
15807
|
-
|
|
15808
|
-
|
|
15809
|
-
|
|
15810
|
-
|
|
15811
|
-
|
|
15812
|
-
|
|
15813
|
-
|
|
15814
|
-
|
|
15815
|
-
|
|
15863
|
+
registerStorageSchemaInitializer((database) => {
|
|
15864
|
+
database.exec(`
|
|
15865
|
+
CREATE TABLE IF NOT EXISTS remote_ask_callbacks (
|
|
15866
|
+
target_query_id TEXT PRIMARY KEY,
|
|
15867
|
+
request_id TEXT NOT NULL,
|
|
15868
|
+
node_name TEXT NOT NULL,
|
|
15869
|
+
node_cell_id TEXT NOT NULL,
|
|
15870
|
+
topic_id TEXT NOT NULL,
|
|
15871
|
+
user_id TEXT NOT NULL,
|
|
15872
|
+
created_at INTEGER NOT NULL
|
|
15873
|
+
)
|
|
15874
|
+
`);
|
|
15875
|
+
});
|
|
15816
15876
|
pendingAsks = new Map;
|
|
15817
15877
|
MAX_ASK_AGE_MS = PENDING_ASK_TTL_MS;
|
|
15818
15878
|
});
|
|
@@ -16034,30 +16094,35 @@ paint();document.body.appendChild(b)}
|
|
|
16034
16094
|
if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",init);else init()})();
|
|
16035
16095
|
</script>`;
|
|
16036
16096
|
var init_visual_store = __esm(async () => {
|
|
16037
|
-
await
|
|
16038
|
-
|
|
16039
|
-
|
|
16040
|
-
|
|
16041
|
-
|
|
16042
|
-
|
|
16043
|
-
|
|
16044
|
-
|
|
16045
|
-
|
|
16046
|
-
|
|
16047
|
-
|
|
16048
|
-
|
|
16049
|
-
|
|
16050
|
-
|
|
16051
|
-
|
|
16052
|
-
|
|
16053
|
-
|
|
16054
|
-
|
|
16055
|
-
|
|
16056
|
-
|
|
16057
|
-
|
|
16058
|
-
|
|
16059
|
-
|
|
16060
|
-
|
|
16097
|
+
await __promiseAll([
|
|
16098
|
+
init_forum_db(),
|
|
16099
|
+
init_storage_host()
|
|
16100
|
+
]);
|
|
16101
|
+
registerStorageSchemaInitializer((database) => {
|
|
16102
|
+
database.exec(`
|
|
16103
|
+
CREATE TABLE IF NOT EXISTS api_topic_visuals (
|
|
16104
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
16105
|
+
topic_id TEXT NOT NULL,
|
|
16106
|
+
html TEXT NOT NULL,
|
|
16107
|
+
title TEXT,
|
|
16108
|
+
created_at INTEGER NOT NULL,
|
|
16109
|
+
kind TEXT NOT NULL DEFAULT 'html',
|
|
16110
|
+
source TEXT,
|
|
16111
|
+
file_id TEXT,
|
|
16112
|
+
mime_type TEXT,
|
|
16113
|
+
media_token TEXT
|
|
16114
|
+
);
|
|
16115
|
+
CREATE INDEX IF NOT EXISTS idx_api_topic_visuals_topic
|
|
16116
|
+
ON api_topic_visuals(topic_id, created_at DESC);
|
|
16117
|
+
|
|
16118
|
+
CREATE TABLE IF NOT EXISTS api_topic_visual_views (
|
|
16119
|
+
topic_id TEXT NOT NULL,
|
|
16120
|
+
user_id TEXT NOT NULL,
|
|
16121
|
+
visual_id INTEGER NOT NULL,
|
|
16122
|
+
PRIMARY KEY (topic_id, user_id)
|
|
16123
|
+
);
|
|
16124
|
+
`);
|
|
16125
|
+
});
|
|
16061
16126
|
for (const statement of [
|
|
16062
16127
|
"ALTER TABLE api_topic_visuals ADD COLUMN kind TEXT NOT NULL DEFAULT 'html'",
|
|
16063
16128
|
"ALTER TABLE api_topic_visuals ADD COLUMN source TEXT",
|
|
@@ -20168,20 +20233,26 @@ function recordRuntimeGatewaySubmission(submission) {
|
|
|
20168
20233
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(submission.clientMessageId, submission.requestId, submission.topicId, submission.messageId, submission.userId, submission.createdAt, submission.ackCursor, submission.messageCursor, submission.payloadHash ?? null);
|
|
20169
20234
|
}
|
|
20170
20235
|
var init_runtime_gateway_submissions = __esm(async () => {
|
|
20171
|
-
await
|
|
20172
|
-
|
|
20173
|
-
|
|
20174
|
-
|
|
20175
|
-
|
|
20176
|
-
|
|
20177
|
-
|
|
20178
|
-
|
|
20179
|
-
|
|
20180
|
-
|
|
20181
|
-
|
|
20182
|
-
|
|
20183
|
-
|
|
20184
|
-
|
|
20236
|
+
await __promiseAll([
|
|
20237
|
+
init_forum_db(),
|
|
20238
|
+
init_storage_host()
|
|
20239
|
+
]);
|
|
20240
|
+
registerStorageSchemaInitializer((database) => {
|
|
20241
|
+
database.exec(`
|
|
20242
|
+
CREATE TABLE IF NOT EXISTS runtime_gateway_submissions (
|
|
20243
|
+
client_message_id TEXT PRIMARY KEY,
|
|
20244
|
+
request_id TEXT NOT NULL UNIQUE,
|
|
20245
|
+
topic_id TEXT NOT NULL,
|
|
20246
|
+
message_id TEXT NOT NULL,
|
|
20247
|
+
user_id TEXT NOT NULL,
|
|
20248
|
+
created_at TEXT NOT NULL,
|
|
20249
|
+
ack_cursor INTEGER NOT NULL DEFAULT 0,
|
|
20250
|
+
message_cursor INTEGER NOT NULL DEFAULT 0,
|
|
20251
|
+
payload_hash TEXT
|
|
20252
|
+
)
|
|
20253
|
+
`);
|
|
20254
|
+
database.exec("CREATE INDEX IF NOT EXISTS idx_runtime_gateway_submissions_topic ON runtime_gateway_submissions(topic_id)");
|
|
20255
|
+
});
|
|
20185
20256
|
try {
|
|
20186
20257
|
db.exec("ALTER TABLE runtime_gateway_submissions ADD COLUMN ack_cursor INTEGER NOT NULL DEFAULT 0");
|
|
20187
20258
|
} catch {}
|
|
@@ -20191,7 +20262,6 @@ var init_runtime_gateway_submissions = __esm(async () => {
|
|
|
20191
20262
|
try {
|
|
20192
20263
|
db.exec("ALTER TABLE runtime_gateway_submissions ADD COLUMN message_cursor INTEGER NOT NULL DEFAULT 0");
|
|
20193
20264
|
} catch {}
|
|
20194
|
-
db.exec("CREATE INDEX IF NOT EXISTS idx_runtime_gateway_submissions_topic ON runtime_gateway_submissions(topic_id)");
|
|
20195
20265
|
});
|
|
20196
20266
|
|
|
20197
20267
|
// ../../packages/core/src/application/submit-runtime-gateway-turn.ts
|
|
@@ -20364,6 +20434,33 @@ var init_submit_user_message = __esm(async () => {
|
|
|
20364
20434
|
});
|
|
20365
20435
|
|
|
20366
20436
|
// ../../packages/core/src/application/switch-topic-access-mode.ts
|
|
20437
|
+
function collectSubagentDescendants(rootTopicId) {
|
|
20438
|
+
const all = listTopics();
|
|
20439
|
+
const childrenByParent = new Map;
|
|
20440
|
+
for (const topic of all) {
|
|
20441
|
+
if (!topic.isSubagent || !topic.parentTopicId)
|
|
20442
|
+
continue;
|
|
20443
|
+
const siblings = childrenByParent.get(topic.parentTopicId);
|
|
20444
|
+
if (siblings)
|
|
20445
|
+
siblings.push(topic);
|
|
20446
|
+
else
|
|
20447
|
+
childrenByParent.set(topic.parentTopicId, [topic]);
|
|
20448
|
+
}
|
|
20449
|
+
const descendants = [];
|
|
20450
|
+
const seen = new Set([rootTopicId]);
|
|
20451
|
+
const queue = [rootTopicId];
|
|
20452
|
+
while (queue.length > 0) {
|
|
20453
|
+
const parentId = queue.shift();
|
|
20454
|
+
for (const child of childrenByParent.get(parentId) ?? []) {
|
|
20455
|
+
if (seen.has(child.id))
|
|
20456
|
+
continue;
|
|
20457
|
+
seen.add(child.id);
|
|
20458
|
+
descendants.push(child);
|
|
20459
|
+
queue.push(child.id);
|
|
20460
|
+
}
|
|
20461
|
+
}
|
|
20462
|
+
return descendants;
|
|
20463
|
+
}
|
|
20367
20464
|
function switchTopicAccessMode(params) {
|
|
20368
20465
|
const topic = getTopic(params.topicId);
|
|
20369
20466
|
if (!topic)
|
|
@@ -20371,13 +20468,32 @@ function switchTopicAccessMode(params) {
|
|
|
20371
20468
|
const owner = topic.participants.some((participant) => participant.userId === params.userId && participant.role === "owner");
|
|
20372
20469
|
if (!owner)
|
|
20373
20470
|
return { ok: false, error: "Only topic owners can change privacy" };
|
|
20374
|
-
topic.
|
|
20375
|
-
|
|
20376
|
-
|
|
20471
|
+
if (topic.isSubagent) {
|
|
20472
|
+
return {
|
|
20473
|
+
ok: false,
|
|
20474
|
+
error: "Subagent rooms inherit privacy from their parent topic"
|
|
20475
|
+
};
|
|
20476
|
+
}
|
|
20477
|
+
const descendants = collectSubagentDescendants(topic.id);
|
|
20478
|
+
const changed = [topic, ...descendants].filter((candidate) => (candidate.accessMode ?? "private") !== params.accessMode);
|
|
20479
|
+
if (changed.length === 0) {
|
|
20480
|
+
return {
|
|
20481
|
+
ok: true,
|
|
20482
|
+
accessMode: params.accessMode,
|
|
20483
|
+
text: params.accessMode === "shared" ? `"${topic.title}" is already public to the connected Otium Hub.` : `"${topic.title}" is already private to this worker.`,
|
|
20484
|
+
topicIds: []
|
|
20485
|
+
};
|
|
20486
|
+
}
|
|
20487
|
+
setTopicAccessModes(changed.map((candidate) => candidate.id), params.accessMode);
|
|
20488
|
+
for (const candidate of changed)
|
|
20489
|
+
WsHub.get().broadcastTopicUpdated(candidate.id);
|
|
20490
|
+
const subagentCount = changed.filter((candidate) => candidate.id !== topic.id).length;
|
|
20491
|
+
const suffix = subagentCount > 0 ? ` (${subagentCount} subagent room${subagentCount === 1 ? "" : "s"} updated)` : "";
|
|
20377
20492
|
return {
|
|
20378
20493
|
ok: true,
|
|
20379
20494
|
accessMode: params.accessMode,
|
|
20380
|
-
|
|
20495
|
+
topicIds: changed.map((candidate) => candidate.id),
|
|
20496
|
+
text: (params.accessMode === "shared" ? `"${topic.title}" is public to the connected Otium Hub.` : `"${topic.title}" is private to this worker.`) + suffix
|
|
20381
20497
|
};
|
|
20382
20498
|
}
|
|
20383
20499
|
var init_switch_topic_access_mode = __esm(async () => {
|
|
@@ -27509,6 +27625,7 @@ __export(exports_storage_public, {
|
|
|
27509
27625
|
setTopicAgentAndSession: () => setTopicAgentAndSession,
|
|
27510
27626
|
setTopicAgentAndClearSession: () => setTopicAgentAndClearSession,
|
|
27511
27627
|
setTopicAgent: () => setTopicAgent,
|
|
27628
|
+
setTopicAccessModes: () => setTopicAccessModes,
|
|
27512
27629
|
setSessionForTopic: () => setSessionForTopic,
|
|
27513
27630
|
setLastShownConfig: () => setLastShownConfig,
|
|
27514
27631
|
setGlobalAiName: () => setGlobalAiName,
|
|
@@ -32474,7 +32591,7 @@ function setTopics(state, topics, preferredTitle) {
|
|
|
32474
32591
|
activeTopicId: nextActive,
|
|
32475
32592
|
scrollOffset: nextActive === state.activeTopicId ? state.scrollOffset : 0,
|
|
32476
32593
|
askChoiceIndex: nextActive === state.activeTopicId ? state.askChoiceIndex : 0,
|
|
32477
|
-
topicPickerIndex: state.overlay === "topics" ? pickedTopicIndex : Math.max(0, orderedTopics.findIndex((topic) => topic.id === nextActive)),
|
|
32594
|
+
topicPickerIndex: state.overlay === "topics" || state.overlay === "confirm-share" ? pickedTopicIndex : Math.max(0, orderedTopics.findIndex((topic) => topic.id === nextActive)),
|
|
32478
32595
|
topicPickerBackgroundId: state.topicPickerBackgroundId
|
|
32479
32596
|
});
|
|
32480
32597
|
}
|
|
@@ -34136,14 +34253,16 @@ function subagentTreePrefix(topic, topics, rootTopicId) {
|
|
|
34136
34253
|
function topicPickerHints(topicPickerRoot) {
|
|
34137
34254
|
const exit = topicPickerRoot ? "Esc/Ctrl-C exit" : "Esc close \xB7 Ctrl-C exit; work continues";
|
|
34138
34255
|
const shortExit = topicPickerRoot ? "Esc/Ctrl-C exit" : "Esc close";
|
|
34139
|
-
|
|
34256
|
+
const candidates = [
|
|
34257
|
+
`\u2191\u2193 select \xB7 Enter open \xB7 type to filter \xB7 Ctrl-N new \xB7 Ctrl-D delete \xB7 Ctrl-P public/private \xB7 ${exit}`,
|
|
34258
|
+
`\u2191\u2193 select \xB7 Enter open \xB7 type to filter \xB7 Ctrl-N new \xB7 Ctrl-D delete \xB7 Ctrl-P public/private \xB7 ${shortExit}`,
|
|
34140
34259
|
`\u2191\u2193 select \xB7 Enter open \xB7 type to filter \xB7 Ctrl-N new \xB7 Ctrl-D delete \xB7 ${exit}`,
|
|
34141
|
-
`\u2191\u2193 select \xB7 Enter open \xB7 type to filter \xB7 Ctrl-N
|
|
34142
|
-
|
|
34143
|
-
"
|
|
34144
|
-
"
|
|
34145
|
-
"Ctrl-N/D"
|
|
34260
|
+
`\u2191\u2193 select \xB7 Enter open \xB7 type to filter \xB7 Ctrl-N/D/P \xB7 ${shortExit}`,
|
|
34261
|
+
"\u2191\u2193 \xB7 Enter \xB7 type to filter \xB7 Ctrl-N/D/P",
|
|
34262
|
+
"type to filter \xB7 Ctrl-N/D/P",
|
|
34263
|
+
"Ctrl-N/D/P"
|
|
34146
34264
|
];
|
|
34265
|
+
return [...new Set(candidates)].sort((a, b) => displayWidth(b) - displayWidth(a));
|
|
34147
34266
|
}
|
|
34148
34267
|
function topicOverlayCursor(state, width, bodyHeight) {
|
|
34149
34268
|
if (state.overlay !== "topics")
|
|
@@ -34499,6 +34618,34 @@ function conversationLines(state, width, height, animationFrame = 0, nowMs = ter
|
|
|
34499
34618
|
line(" Press y to delete or n to cancel.", { fg: theme.amber })
|
|
34500
34619
|
].slice(0, height);
|
|
34501
34620
|
}
|
|
34621
|
+
if (state.overlay === "confirm-share") {
|
|
34622
|
+
const topic = state.topics.find((candidate) => candidate.id === state.pendingShareTopicId);
|
|
34623
|
+
const subagents = (() => {
|
|
34624
|
+
if (!topic)
|
|
34625
|
+
return 0;
|
|
34626
|
+
const reached = new Set([topic.id]);
|
|
34627
|
+
for (;; ) {
|
|
34628
|
+
const next = state.topics.filter((candidate) => candidate.isSubagent && !reached.has(candidate.id) && candidate.parentTopicId !== undefined && reached.has(candidate.parentTopicId));
|
|
34629
|
+
if (next.length === 0)
|
|
34630
|
+
break;
|
|
34631
|
+
for (const candidate of next)
|
|
34632
|
+
reached.add(candidate.id);
|
|
34633
|
+
}
|
|
34634
|
+
return reached.size - 1;
|
|
34635
|
+
})();
|
|
34636
|
+
const scope = subagents > 0 ? ` Its ${subagents} subagent room${subagents === 1 ? "" : "s"} become public too.` : " Subagent rooms spawned from it will be public too.";
|
|
34637
|
+
return [
|
|
34638
|
+
line(""),
|
|
34639
|
+
line(` Make \u201C${topic?.title ?? "this topic"}\u201D public?`, {
|
|
34640
|
+
fg: theme.amber,
|
|
34641
|
+
bold: true
|
|
34642
|
+
}),
|
|
34643
|
+
line(""),
|
|
34644
|
+
line(" The transcript becomes visible to the connected Otium Hub."),
|
|
34645
|
+
line(scope),
|
|
34646
|
+
line(" Press y to publish or n to cancel.", { fg: theme.amber })
|
|
34647
|
+
].slice(0, height);
|
|
34648
|
+
}
|
|
34502
34649
|
const all = conversationContentLines(state, width, animationFrame, nowMs, includeTasks);
|
|
34503
34650
|
const { contentHeight, maxOffset, offset } = conversationViewport(all.length, height, state.scrollOffset);
|
|
34504
34651
|
const end = all.length - offset;
|
|
@@ -34766,6 +34913,9 @@ function footerHintText(state) {
|
|
|
34766
34913
|
}
|
|
34767
34914
|
return state.topicPickerRoot ? ["Esc/Ctrl-C exit ", "Esc exit "] : ["Esc close \xB7 Ctrl-C exit; work continues ", "Esc close \xB7 Ctrl-C exit ", "Esc "];
|
|
34768
34915
|
}
|
|
34916
|
+
if (state.overlay === "confirm-share") {
|
|
34917
|
+
return ["Y make public \xB7 N cancel ", "Y/N "];
|
|
34918
|
+
}
|
|
34769
34919
|
if (state.overlay === "background-session") {
|
|
34770
34920
|
return [
|
|
34771
34921
|
"wheel/PgUp/PgDn scroll \xB7 Esc back \xB7 read-only ",
|
|
@@ -37722,6 +37872,16 @@ class TerminalApp {
|
|
|
37722
37872
|
}
|
|
37723
37873
|
return;
|
|
37724
37874
|
}
|
|
37875
|
+
if (this.#state.overlay === "confirm-share") {
|
|
37876
|
+
const key = chunk.toLowerCase();
|
|
37877
|
+
if (CONFIRM_KEYS.has(key))
|
|
37878
|
+
this.#confirmTopicShare();
|
|
37879
|
+
else if (CANCEL_KEYS.has(key) || chunk === "\x1B") {
|
|
37880
|
+
this.#state = { ...this.#state, overlay: "topics", pendingShareTopicId: undefined };
|
|
37881
|
+
this.#queueRender();
|
|
37882
|
+
}
|
|
37883
|
+
return;
|
|
37884
|
+
}
|
|
37725
37885
|
if (this.#state.overlay === "background-session") {
|
|
37726
37886
|
if (chunk === "\x1B") {
|
|
37727
37887
|
this.#state = { ...this.#state, overlay: "topics" };
|
|
@@ -38030,6 +38190,22 @@ class TerminalApp {
|
|
|
38030
38190
|
this.#queueRender();
|
|
38031
38191
|
return;
|
|
38032
38192
|
}
|
|
38193
|
+
if (chunk === TOGGLE_ACCESS_MODE_KEY) {
|
|
38194
|
+
const topic = pickedTopic(this.#state);
|
|
38195
|
+
if (topic) {
|
|
38196
|
+
this.#requestAccessModeToggle(topic);
|
|
38197
|
+
return;
|
|
38198
|
+
}
|
|
38199
|
+
if (!this.#state.topicPickerBackgroundId)
|
|
38200
|
+
return;
|
|
38201
|
+
this.#state = {
|
|
38202
|
+
...this.#state,
|
|
38203
|
+
notice: "Background sessions are read-only",
|
|
38204
|
+
noticeLevel: "warn"
|
|
38205
|
+
};
|
|
38206
|
+
this.#queueRender();
|
|
38207
|
+
return;
|
|
38208
|
+
}
|
|
38033
38209
|
if (FILTER_BACKSPACE_KEYS.has(chunk)) {
|
|
38034
38210
|
if (this.#state.topicFilter.length === 0)
|
|
38035
38211
|
return;
|
|
@@ -38472,6 +38648,65 @@ class TerminalApp {
|
|
|
38472
38648
|
};
|
|
38473
38649
|
this.#queueRender();
|
|
38474
38650
|
}
|
|
38651
|
+
async#requestAccessModeToggle(topic) {
|
|
38652
|
+
if (topic.kind !== "agent") {
|
|
38653
|
+
this.#state = {
|
|
38654
|
+
...this.#state,
|
|
38655
|
+
notice: `${topic.kind === "manager" ? "Manager" : "Channel"} topics cannot be published`,
|
|
38656
|
+
noticeLevel: "warn"
|
|
38657
|
+
};
|
|
38658
|
+
this.#queueRender();
|
|
38659
|
+
return;
|
|
38660
|
+
}
|
|
38661
|
+
if (topic.isSubagent) {
|
|
38662
|
+
this.#state = {
|
|
38663
|
+
...this.#state,
|
|
38664
|
+
notice: "Subagent rooms inherit privacy from their parent topic",
|
|
38665
|
+
noticeLevel: "warn"
|
|
38666
|
+
};
|
|
38667
|
+
this.#queueRender();
|
|
38668
|
+
return;
|
|
38669
|
+
}
|
|
38670
|
+
if (topic.accessMode === "shared") {
|
|
38671
|
+
await this.#applyAccessMode(topic, "private");
|
|
38672
|
+
return;
|
|
38673
|
+
}
|
|
38674
|
+
this.#state = {
|
|
38675
|
+
...this.#state,
|
|
38676
|
+
overlay: "confirm-share",
|
|
38677
|
+
pendingShareTopicId: topic.id
|
|
38678
|
+
};
|
|
38679
|
+
this.#queueRender();
|
|
38680
|
+
}
|
|
38681
|
+
async#confirmTopicShare() {
|
|
38682
|
+
const topic = this.#state.topics.find((candidate) => candidate.id === this.#state.pendingShareTopicId);
|
|
38683
|
+
this.#state = { ...this.#state, overlay: "topics", pendingShareTopicId: undefined };
|
|
38684
|
+
if (!topic) {
|
|
38685
|
+
this.#state = {
|
|
38686
|
+
...this.#state,
|
|
38687
|
+
notice: "That topic no longer exists",
|
|
38688
|
+
noticeLevel: "warn"
|
|
38689
|
+
};
|
|
38690
|
+
this.#queueRender();
|
|
38691
|
+
return;
|
|
38692
|
+
}
|
|
38693
|
+
await this.#applyAccessMode(topic, "shared");
|
|
38694
|
+
}
|
|
38695
|
+
async#applyAccessMode(topic, accessMode) {
|
|
38696
|
+
this.#state = { ...this.#state, overlay: "topics" };
|
|
38697
|
+
try {
|
|
38698
|
+
const notice = await this.#client.setAccessMode(topic, accessMode);
|
|
38699
|
+
await this.#refreshTopics();
|
|
38700
|
+
this.#state = { ...this.#state, notice, noticeLevel: "success" };
|
|
38701
|
+
} catch (error2) {
|
|
38702
|
+
this.#state = {
|
|
38703
|
+
...this.#state,
|
|
38704
|
+
notice: error2 instanceof Error ? error2.message : String(error2),
|
|
38705
|
+
noticeLevel: "error"
|
|
38706
|
+
};
|
|
38707
|
+
}
|
|
38708
|
+
this.#queueRender();
|
|
38709
|
+
}
|
|
38475
38710
|
#requestTopicDelete(topic) {
|
|
38476
38711
|
if (!topic)
|
|
38477
38712
|
return;
|
|
@@ -38750,6 +38985,7 @@ class TerminalApp {
|
|
|
38750
38985
|
...this.#state,
|
|
38751
38986
|
overlay: null,
|
|
38752
38987
|
pendingDeleteTopicId: undefined,
|
|
38988
|
+
pendingShareTopicId: undefined,
|
|
38753
38989
|
creatingTopic: false,
|
|
38754
38990
|
notice: "Input cleared",
|
|
38755
38991
|
noticeLevel: "info"
|
|
@@ -38812,7 +39048,7 @@ class TerminalApp {
|
|
|
38812
39048
|
await this.#client.stop();
|
|
38813
39049
|
}
|
|
38814
39050
|
}
|
|
38815
|
-
var KITTY_KEYBOARD_PUSH = "\x1B[>1u", KITTY_KEYBOARD_POP = "\x1B[<u", CANVAS_RGB, ENTER_ALT_SCREEN, EXIT_ALT_SCREEN, ABORT_ENTER_ALT_SCREEN, NEW_TOPIC_KEY = "\x0E", DELETE_TOPIC_KEY = "\x04", FILTER_BACKSPACE_KEYS, CONFIRM_KEYS, CANCEL_KEYS, INPUT_CARRY_FLUSH_MS = 15;
|
|
39051
|
+
var KITTY_KEYBOARD_PUSH = "\x1B[>1u", KITTY_KEYBOARD_POP = "\x1B[<u", CANVAS_RGB, ENTER_ALT_SCREEN, EXIT_ALT_SCREEN, ABORT_ENTER_ALT_SCREEN, NEW_TOPIC_KEY = "\x0E", DELETE_TOPIC_KEY = "\x04", TOGGLE_ACCESS_MODE_KEY = "\x10", FILTER_BACKSPACE_KEYS, CONFIRM_KEYS, CANCEL_KEYS, INPUT_CARRY_FLUSH_MS = 15;
|
|
38816
39052
|
var init_app = __esm(async () => {
|
|
38817
39053
|
init_color_depth();
|
|
38818
39054
|
init_commands();
|
|
@@ -44460,8 +44696,13 @@ function shareOtiumTopic(options) {
|
|
|
44460
44696
|
if (!owned.ok)
|
|
44461
44697
|
return owned;
|
|
44462
44698
|
if (!isTopicShared(owned.topic)) {
|
|
44463
|
-
|
|
44464
|
-
|
|
44699
|
+
const switched = switchTopicAccessMode({
|
|
44700
|
+
topicId: options.localTopicId,
|
|
44701
|
+
userId: options.userId,
|
|
44702
|
+
accessMode: "shared"
|
|
44703
|
+
});
|
|
44704
|
+
if (!switched.ok)
|
|
44705
|
+
return { ok: false, error: switched.error, status: 409 };
|
|
44465
44706
|
}
|
|
44466
44707
|
return bindOtiumTopic(options);
|
|
44467
44708
|
}
|
|
@@ -44471,8 +44712,13 @@ function setOtiumTopicPrivate(options) {
|
|
|
44471
44712
|
return owned;
|
|
44472
44713
|
const removedBindings = unbindSharedPeerSessionsForLocalTopic(options.localTopicId);
|
|
44473
44714
|
if (isTopicShared(owned.topic)) {
|
|
44474
|
-
|
|
44475
|
-
|
|
44715
|
+
const switched = switchTopicAccessMode({
|
|
44716
|
+
topicId: options.localTopicId,
|
|
44717
|
+
userId: options.userId,
|
|
44718
|
+
accessMode: "private"
|
|
44719
|
+
});
|
|
44720
|
+
if (!switched.ok)
|
|
44721
|
+
return { ok: false, error: switched.error, status: 409 };
|
|
44476
44722
|
}
|
|
44477
44723
|
return { ok: true, localTopicId: options.localTopicId, removedBindings };
|
|
44478
44724
|
}
|
|
@@ -46915,4 +47161,4 @@ switch (command) {
|
|
|
46915
47161
|
}
|
|
46916
47162
|
}
|
|
46917
47163
|
|
|
46918
|
-
//# debugId=
|
|
47164
|
+
//# debugId=69B455239128A0A264756E2164756E21
|