negotium 0.2.23 → 0.2.25
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 +84 -30
- package/dist/agent-helpers.js.map +6 -6
- package/dist/background-bash.js +2 -1
- package/dist/background-bash.js.map +3 -3
- package/dist/browser-runtime.js +2 -1
- package/dist/browser-runtime.js.map +3 -3
- package/dist/{chunk-rhp26p2c.js → chunk-1y2xw0xe.js} +2 -1
- package/dist/{chunk-rhp26p2c.js.map → chunk-1y2xw0xe.js.map} +3 -3
- package/dist/hosted-agent.js +3 -2
- package/dist/hosted-agent.js.map +4 -4
- package/dist/main.js +224 -366
- package/dist/main.js.map +27 -28
- package/dist/mcp-factories.js +86 -31
- package/dist/mcp-factories.js.map +7 -7
- package/dist/prompts.js +2 -1
- package/dist/prompts.js.map +3 -3
- package/dist/query-runtime.js +2 -1
- package/dist/query-runtime.js.map +3 -3
- package/dist/registry.js +3 -3
- package/dist/registry.js.map +2 -2
- package/dist/rollout.js +1 -1
- package/dist/runtime/src/index.ts +3 -7
- package/dist/runtime/src/mcp/session-comm/default-host.ts +6 -1
- package/dist/runtime/src/mcp/session-comm/topic-catalog.ts +17 -1
- package/dist/runtime/src/mcp/session-comm/topics.ts +23 -1
- package/dist/runtime/src/node-host.ts +4 -4
- package/dist/runtime/src/platform/config.ts +12 -0
- package/dist/runtime/src/storage/api-topics.ts +160 -52
- package/dist/runtime/src/storage/storage-public.ts +0 -1
- package/dist/runtime/src/topics/create.ts +12 -6
- package/dist/runtime/src/topics/derive.ts +20 -11
- package/dist/runtime/src/types/api.ts +8 -4
- package/dist/runtime/src/version.ts +1 -1
- package/dist/runtime-helpers.js +2 -1
- package/dist/runtime-helpers.js.map +3 -3
- package/dist/storage.js +92 -38
- package/dist/storage.js.map +3 -3
- package/dist/types/packages/core/src/mcp/session-comm/topic-catalog.d.ts +7 -0
- package/dist/types/packages/core/src/platform/config.d.ts +12 -0
- package/dist/types/packages/core/src/storage/api-topics.d.ts +34 -19
- package/dist/types/packages/core/src/storage/storage-public.d.ts +1 -1
- package/dist/types/packages/core/src/topics/derive.d.ts +13 -4
- package/dist/types/packages/core/src/types/api.d.ts +8 -4
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/dist/vault.js +2 -1
- package/dist/vault.js.map +3 -3
- package/package.json +1 -1
- package/dist/runtime/src/application/switch-topic-access-mode.ts +0 -110
package/dist/mcp-factories.js
CHANGED
|
@@ -313,7 +313,7 @@ function resolveDefaultModel(agent, registryDefaultModel) {
|
|
|
313
313
|
function codexAuthFilePath() {
|
|
314
314
|
return process.env.NEGOTIUM_CODEX_AUTH_FILE || join(process.env.CODEX_HOME || join(homedir(), ".codex"), "auth.json");
|
|
315
315
|
}
|
|
316
|
-
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;
|
|
316
|
+
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, NODE_ID, 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;
|
|
317
317
|
var init_config = __esm(() => {
|
|
318
318
|
init_config_helpers();
|
|
319
319
|
init_logger();
|
|
@@ -355,6 +355,7 @@ var init_config = __esm(() => {
|
|
|
355
355
|
BG_BASH_MAX_PORT = parsePortEnv(process.env.BG_BASH_MAX_PORT, 9799);
|
|
356
356
|
RUNTIME_MCP_SECRET = loadOrCreateLocalSecret("RUNTIME_MCP_SECRET", "runtime-mcp-secret");
|
|
357
357
|
NODE_CONTROL_TOKEN = loadOrCreateLocalSecret("NEGOTIUM_CONTROL_TOKEN", "node-control-token");
|
|
358
|
+
NODE_ID = loadOrCreateLocalSecret("NEGOTIUM_NODE_ID", "node-id");
|
|
358
359
|
VAULT_MASTER_KEY = loadOrCreateLocalSecret("NEGOTIUM_VAULT_MASTER_KEY", "vault-master-key", { persistEnvValue: true });
|
|
359
360
|
delete process.env.NEGOTIUM_VAULT_MASTER_KEY;
|
|
360
361
|
NEGOTIUM_PORT = parseInt(process.env.NEGOTIUM_PORT || "7777", 10);
|
|
@@ -1015,7 +1016,7 @@ var init_claude_registry = __esm(() => {
|
|
|
1015
1016
|
});
|
|
1016
1017
|
|
|
1017
1018
|
// ../../packages/core/src/version.ts
|
|
1018
|
-
var NEGOTIUM_VERSION = "0.2.
|
|
1019
|
+
var NEGOTIUM_VERSION = "0.2.25";
|
|
1019
1020
|
|
|
1020
1021
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
1021
1022
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -4058,6 +4059,12 @@ var init_constants = __esm(() => {
|
|
|
4058
4059
|
});
|
|
4059
4060
|
|
|
4060
4061
|
// ../../packages/core/src/storage/api-topics.ts
|
|
4062
|
+
function defaultTopicSurface() {
|
|
4063
|
+
return normalizeTopicSurface(process.env.NEGOTIUM_DEFAULT_SURFACE);
|
|
4064
|
+
}
|
|
4065
|
+
function normalizeTopicSurface(value2) {
|
|
4066
|
+
return value2 === "telegram" || value2 === "otium" || value2 === "terminal" ? value2 : "terminal";
|
|
4067
|
+
}
|
|
4061
4068
|
function tableColumns(table) {
|
|
4062
4069
|
const rows = db.query(`PRAGMA table_info(${table})`).all();
|
|
4063
4070
|
return new Set(rows.map((row) => row.name));
|
|
@@ -4181,7 +4188,7 @@ function initializeApiTopicsSchema() {
|
|
|
4181
4188
|
is_fork INTEGER NOT NULL DEFAULT 0 CHECK (is_fork IN (0,1)),
|
|
4182
4189
|
is_subagent INTEGER NOT NULL DEFAULT 0 CHECK (is_subagent IN (0,1)),
|
|
4183
4190
|
visibility TEXT NOT NULL DEFAULT 'visible' CHECK (visibility IN ('visible','hidden')),
|
|
4184
|
-
|
|
4191
|
+
surface TEXT NOT NULL DEFAULT 'terminal' CHECK (surface IN ('terminal','telegram','otium')),
|
|
4185
4192
|
browser_profile TEXT NOT NULL DEFAULT 'default',
|
|
4186
4193
|
browser_profile_owner TEXT,
|
|
4187
4194
|
session_id TEXT,
|
|
@@ -4227,8 +4234,8 @@ function initializeApiTopicsSchema() {
|
|
|
4227
4234
|
const legacyBaseEffort = row.base_effort ?? row.default_effort;
|
|
4228
4235
|
db.query(`INSERT INTO api_topics_next
|
|
4229
4236
|
(id,title,kind,description,agent,base_model,base_effort,response_policy,
|
|
4230
|
-
created_at,last_message_at,parent_topic_id,memory_topic_id,memory_key,is_fork,is_subagent,visibility,
|
|
4231
|
-
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`).run(String(row.id), String(row.title), normalized.kind, typeof row.description === "string" ? row.description : null, normalized.agent ?? null, typeof legacyBaseModel === "string" ? legacyBaseModel : null, typeof legacyBaseEffort === "string" ? legacyBaseEffort : null, normalized.aiMode, String(row.created_at), typeof row.last_message_at === "string" ? row.last_message_at : null, typeof row.parent_topic_id === "string" ? row.parent_topic_id : null, typeof row.memory_topic_id === "string" ? row.memory_topic_id : null, typeof row.memory_key === "string" ? row.memory_key : null, Number(row.is_fork ?? 0) !== 0 ? 1 : 0, Number(row.is_subagent ?? 0) !== 0 ? 1 : 0, row.visibility === "hidden" ? "hidden" : "visible", row.
|
|
4237
|
+
created_at,last_message_at,parent_topic_id,memory_topic_id,memory_key,is_fork,is_subagent,visibility,surface,session_id)
|
|
4238
|
+
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`).run(String(row.id), String(row.title), normalized.kind, typeof row.description === "string" ? row.description : null, normalized.agent ?? null, typeof legacyBaseModel === "string" ? legacyBaseModel : null, typeof legacyBaseEffort === "string" ? legacyBaseEffort : null, normalized.aiMode, String(row.created_at), typeof row.last_message_at === "string" ? row.last_message_at : null, typeof row.parent_topic_id === "string" ? row.parent_topic_id : null, typeof row.memory_topic_id === "string" ? row.memory_topic_id : null, typeof row.memory_key === "string" ? row.memory_key : null, Number(row.is_fork ?? 0) !== 0 ? 1 : 0, Number(row.is_subagent ?? 0) !== 0 ? 1 : 0, row.visibility === "hidden" ? "hidden" : "visible", row.surface === undefined ? defaultTopicSurface() : normalizeTopicSurface(row.surface), typeof row.session_id === "string" ? row.session_id : null);
|
|
4232
4239
|
}
|
|
4233
4240
|
db.exec("DROP TABLE IF EXISTS topic_members");
|
|
4234
4241
|
db.exec("DROP TABLE api_topics");
|
|
@@ -4282,8 +4289,15 @@ function initializeApiTopicsSchema() {
|
|
|
4282
4289
|
if (!tableColumns("api_topics").has("visibility")) {
|
|
4283
4290
|
db.exec("ALTER TABLE api_topics ADD COLUMN visibility TEXT NOT NULL DEFAULT 'visible'");
|
|
4284
4291
|
}
|
|
4285
|
-
if (!tableColumns("api_topics").has("
|
|
4286
|
-
db.exec("ALTER TABLE api_topics ADD COLUMN
|
|
4292
|
+
if (!tableColumns("api_topics").has("surface")) {
|
|
4293
|
+
db.exec("ALTER TABLE api_topics ADD COLUMN surface TEXT NOT NULL DEFAULT 'terminal'");
|
|
4294
|
+
}
|
|
4295
|
+
if (tableColumns("api_topics").has("access_mode")) {
|
|
4296
|
+
try {
|
|
4297
|
+
db.exec("ALTER TABLE api_topics DROP COLUMN access_mode");
|
|
4298
|
+
} catch (err) {
|
|
4299
|
+
logger.warn({ err }, "api_topics: could not drop the retired access_mode column");
|
|
4300
|
+
}
|
|
4287
4301
|
}
|
|
4288
4302
|
if (!tableColumns("api_topics").has("browser_profile")) {
|
|
4289
4303
|
db.exec("ALTER TABLE api_topics ADD COLUMN browser_profile TEXT NOT NULL DEFAULT 'default'");
|
|
@@ -4310,7 +4324,48 @@ function initializeApiTopicsSchema() {
|
|
|
4310
4324
|
)
|
|
4311
4325
|
WHERE browser_profile_owner IS NULL
|
|
4312
4326
|
`);
|
|
4327
|
+
backfillTopicSurfaces();
|
|
4313
4328
|
db.exec("CREATE INDEX IF NOT EXISTS idx_api_topics_last_message ON api_topics(last_message_at DESC)");
|
|
4329
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_api_topics_surface ON api_topics(surface)");
|
|
4330
|
+
}
|
|
4331
|
+
function backfillTopicSurfaces() {
|
|
4332
|
+
db.exec(`
|
|
4333
|
+
CREATE TABLE IF NOT EXISTS api_schema_migrations (
|
|
4334
|
+
key TEXT PRIMARY KEY,
|
|
4335
|
+
applied_at TEXT NOT NULL
|
|
4336
|
+
)
|
|
4337
|
+
`);
|
|
4338
|
+
const applied = db.query("SELECT key FROM api_schema_migrations WHERE key = ?").get(SURFACE_BACKFILL_MIGRATION);
|
|
4339
|
+
if (applied)
|
|
4340
|
+
return;
|
|
4341
|
+
const surface = defaultTopicSurface();
|
|
4342
|
+
db.transaction(() => {
|
|
4343
|
+
db.query("UPDATE api_topics SET surface = ?").run(surface);
|
|
4344
|
+
renameSurfaceTitleCollisions();
|
|
4345
|
+
db.query("INSERT INTO api_schema_migrations (key, applied_at) VALUES (?, ?)").run(SURFACE_BACKFILL_MIGRATION, new Date().toISOString());
|
|
4346
|
+
})();
|
|
4347
|
+
logger.info({ surface }, "api_topics: surface backfilled");
|
|
4348
|
+
}
|
|
4349
|
+
function renameSurfaceTitleCollisions() {
|
|
4350
|
+
const rows = db.query("SELECT id, title, kind, surface FROM api_topics ORDER BY created_at ASC, rowid ASC").all();
|
|
4351
|
+
const taken = new Set;
|
|
4352
|
+
const update = db.query("UPDATE api_topics SET title = ? WHERE id = ?");
|
|
4353
|
+
for (const row of rows) {
|
|
4354
|
+
const key = (title) => `${row.surface}\x00${row.kind}\x00${normalizedTitle(title)}`;
|
|
4355
|
+
if (!taken.has(key(row.title))) {
|
|
4356
|
+
taken.add(key(row.title));
|
|
4357
|
+
continue;
|
|
4358
|
+
}
|
|
4359
|
+
let suffix = 2;
|
|
4360
|
+
let candidate = `${row.title} (${suffix})`;
|
|
4361
|
+
while (taken.has(key(candidate))) {
|
|
4362
|
+
suffix += 1;
|
|
4363
|
+
candidate = `${row.title} (${suffix})`;
|
|
4364
|
+
}
|
|
4365
|
+
taken.add(key(candidate));
|
|
4366
|
+
update.run(candidate, row.id);
|
|
4367
|
+
logger.warn({ topicId: row.id, surface: row.surface, from: row.title, to: candidate }, "api_topics: renamed a duplicate title for surface-scoped uniqueness");
|
|
4368
|
+
}
|
|
4314
4369
|
}
|
|
4315
4370
|
function shortSessionId(sessionId) {
|
|
4316
4371
|
return sessionId ? sessionId.slice(0, 8) : null;
|
|
@@ -4370,12 +4425,9 @@ function rowToDto2(r, participants = getTopicParticipants(r.id), tellTargets) {
|
|
|
4370
4425
|
subagentReportMode: r.subagent_report_mode === "tell" || r.subagent_report_mode === "status-only" ? r.subagent_report_mode : "auto"
|
|
4371
4426
|
} : {},
|
|
4372
4427
|
visibility: normalizeTopicVisibility(r.visibility),
|
|
4373
|
-
|
|
4428
|
+
surface: normalizeTopicSurface(r.surface)
|
|
4374
4429
|
};
|
|
4375
4430
|
}
|
|
4376
|
-
function normalizeTopicAccessMode(value2) {
|
|
4377
|
-
return value2 === "shared" ? "shared" : "private";
|
|
4378
|
-
}
|
|
4379
4431
|
function normalizeTopicVisibility(value2) {
|
|
4380
4432
|
return value2 === "hidden" ? "hidden" : "visible";
|
|
4381
4433
|
}
|
|
@@ -4432,7 +4484,7 @@ function upsertTopic(t) {
|
|
|
4432
4484
|
db.transaction(() => {
|
|
4433
4485
|
db.query(`INSERT INTO api_topics
|
|
4434
4486
|
(id,title,kind,description,agent,base_model,base_effort,response_policy,
|
|
4435
|
-
created_at,last_message_at,parent_topic_id,memory_topic_id,memory_key,is_fork,is_subagent,visibility,
|
|
4487
|
+
created_at,last_message_at,parent_topic_id,memory_topic_id,memory_key,is_fork,is_subagent,visibility,surface,
|
|
4436
4488
|
subagent_report_mode)
|
|
4437
4489
|
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
|
4438
4490
|
ON CONFLICT(id) DO UPDATE SET
|
|
@@ -4451,8 +4503,8 @@ function upsertTopic(t) {
|
|
|
4451
4503
|
is_fork = excluded.is_fork,
|
|
4452
4504
|
is_subagent = excluded.is_subagent,
|
|
4453
4505
|
visibility = excluded.visibility,
|
|
4454
|
-
|
|
4455
|
-
subagent_report_mode = excluded.subagent_report_mode`).run(t.id, t.title, normalized.kind, t.description ?? null, normalized.agent ?? null, t.defaultModel ?? null, t.defaultEffort ?? null, normalized.aiMode, t.createdAt, t.lastMessageAt ?? null, t.parentTopicId ?? null, t.memoryTopicId ?? null, t.memoryKey ?? null, t.isFork ? 1 : 0, t.isSubagent ? 1 : 0, normalizeTopicVisibility(t.visibility),
|
|
4506
|
+
surface = excluded.surface,
|
|
4507
|
+
subagent_report_mode = excluded.subagent_report_mode`).run(t.id, t.title, normalized.kind, t.description ?? null, normalized.agent ?? null, t.defaultModel ?? null, t.defaultEffort ?? null, normalized.aiMode, t.createdAt, t.lastMessageAt ?? null, t.parentTopicId ?? null, t.memoryTopicId ?? null, t.memoryKey ?? null, t.isFork ? 1 : 0, t.isSubagent ? 1 : 0, normalizeTopicVisibility(t.visibility), normalizeTopicSurface(t.surface), t.subagentReportMode ?? "auto");
|
|
4456
4508
|
db.query("DELETE FROM topic_members WHERE topic_id = ?").run(t.id);
|
|
4457
4509
|
for (const participant of t.participants) {
|
|
4458
4510
|
db.query("INSERT INTO topic_members (topic_id,user_id,role) VALUES (?,?,?)").run(t.id, participant.userId, participant.role);
|
|
@@ -4465,8 +4517,8 @@ function upsertTopic(t) {
|
|
|
4465
4517
|
}
|
|
4466
4518
|
})();
|
|
4467
4519
|
}
|
|
4468
|
-
function listTopics() {
|
|
4469
|
-
const rows = db.query("SELECT * FROM api_topics ORDER BY last_message_at DESC").all();
|
|
4520
|
+
function listTopics(opts = {}) {
|
|
4521
|
+
const rows = opts.surface ? db.query("SELECT * FROM api_topics WHERE surface = ? ORDER BY last_message_at DESC").all(normalizeTopicSurface(opts.surface)) : db.query("SELECT * FROM api_topics ORDER BY last_message_at DESC").all();
|
|
4470
4522
|
const participants = getAllTopicParticipants();
|
|
4471
4523
|
const tellTargets = rows.some((row) => row.is_subagent !== 0) ? getAllSubagentTellTargets() : undefined;
|
|
4472
4524
|
return rows.map((row) => rowToDto2(row, participants.get(row.id) ?? [], tellTargets));
|
|
@@ -4513,14 +4565,15 @@ function getTopicByName(title) {
|
|
|
4513
4565
|
}
|
|
4514
4566
|
function findTopicTitleConflict(title, kind, opts = {}) {
|
|
4515
4567
|
const wanted = normalizedTitle(title);
|
|
4568
|
+
const surface = normalizeTopicSurface(opts.surface ?? defaultTopicSurface());
|
|
4516
4569
|
const generalTitleRequested = wanted === normalizedTitle(GENERAL_TOPIC_ID);
|
|
4517
4570
|
if (generalTitleRequested && opts.excludeTopicId !== GENERAL_TOPIC_ID) {
|
|
4518
4571
|
const general = db.query("SELECT * FROM api_topics WHERE id = ?").get(GENERAL_TOPIC_ID);
|
|
4519
4572
|
if (general)
|
|
4520
4573
|
return rowToDto2(general);
|
|
4521
4574
|
}
|
|
4522
|
-
const params = [wanted];
|
|
4523
|
-
let sql = "SELECT * FROM api_topics WHERE LOWER(TRIM(title)) = ?";
|
|
4575
|
+
const params = [wanted, surface];
|
|
4576
|
+
let sql = "SELECT * FROM api_topics WHERE LOWER(TRIM(title)) = ? AND surface = ?";
|
|
4524
4577
|
if (kind !== "manager") {
|
|
4525
4578
|
sql += " AND (kind = ? OR id = ?)";
|
|
4526
4579
|
params.push(kind, GENERAL_TOPIC_ID);
|
|
@@ -4605,7 +4658,7 @@ function reparentTopicChildren(deletedTopicId, replacementParentTopicId) {
|
|
|
4605
4658
|
}
|
|
4606
4659
|
return rows.map((row) => row.id);
|
|
4607
4660
|
}
|
|
4608
|
-
var DEFAULT_AGENT_ROOM_AGENT = "maestro";
|
|
4661
|
+
var DEFAULT_AGENT_ROOM_AGENT = "maestro", SURFACE_BACKFILL_MIGRATION = "api_topics_surface_backfill_20260808";
|
|
4609
4662
|
var init_api_topics = __esm(async () => {
|
|
4610
4663
|
init_constants();
|
|
4611
4664
|
init_logger();
|
|
@@ -11964,11 +12017,11 @@ __export(exports_derive, {
|
|
|
11964
12017
|
});
|
|
11965
12018
|
import { createHash as createHash4, randomUUID as randomUUID11 } from "crypto";
|
|
11966
12019
|
import { mkdirSync as mkdirSync14, rmSync as rmSync5, unlinkSync as unlinkSync14 } from "fs";
|
|
11967
|
-
function getTopics() {
|
|
11968
|
-
return listTopics().filter((topic) => !isLegacySharedGeneral(topic.id));
|
|
12020
|
+
function getTopics(opts = {}) {
|
|
12021
|
+
return listTopics(opts).filter((topic) => !isLegacySharedGeneral(topic.id));
|
|
11969
12022
|
}
|
|
11970
|
-
function getVisibleTopics() {
|
|
11971
|
-
return getTopics().filter(isTopicVisible).map((topic) => {
|
|
12023
|
+
function getVisibleTopics(opts = {}) {
|
|
12024
|
+
return getTopics(opts).filter(isTopicVisible).map((topic) => {
|
|
11972
12025
|
if (!topic.agent)
|
|
11973
12026
|
return topic;
|
|
11974
12027
|
const registry = getRegistry(topic.agent);
|
|
@@ -11993,8 +12046,8 @@ function updateTopic(topicId, patch) {
|
|
|
11993
12046
|
function isParticipant(topic, userId) {
|
|
11994
12047
|
return topic.participants.some((p) => p.userId === userId);
|
|
11995
12048
|
}
|
|
11996
|
-
function nextDerivedTopicTitle(sourceTitle, kind, suffix) {
|
|
11997
|
-
const visibleTitles = new Set(listTopics().filter((topic) => topic.kind === kind).map((topic) => topic.title.toLowerCase()));
|
|
12049
|
+
function nextDerivedTopicTitle(sourceTitle, kind, suffix, surface) {
|
|
12050
|
+
const visibleTitles = new Set(listTopics(surface ? { surface } : {}).filter((topic) => topic.kind === kind).map((topic) => topic.title.toLowerCase()));
|
|
11998
12051
|
let n = 1;
|
|
11999
12052
|
let title = `${sourceTitle}-${suffix}-${n}`;
|
|
12000
12053
|
while (visibleTitles.has(title.toLowerCase())) {
|
|
@@ -12058,8 +12111,9 @@ async function createDerivedTopicImpl(topic, sourceTopicId, userId, copyHistory,
|
|
|
12058
12111
|
{ userId, role: "owner" }
|
|
12059
12112
|
] : [{ userId, role: "owner" }];
|
|
12060
12113
|
const kind = topic.kind ?? inferTopicKind(topic);
|
|
12061
|
-
const
|
|
12062
|
-
const
|
|
12114
|
+
const surface = topic.surface ?? defaultTopicSurface();
|
|
12115
|
+
const title = opts?.name?.trim() || nextDerivedTopicTitle(topic.title, kind, suffix, surface);
|
|
12116
|
+
const conflict = findTopicTitleConflict(title, kind, { surface });
|
|
12063
12117
|
if (conflict) {
|
|
12064
12118
|
logger.info({ sourceTopicId, title, kind, conflictTopicId: conflict.id }, "createDerivedTopic: title conflict");
|
|
12065
12119
|
throw new TopicTitleConflictError(title);
|
|
@@ -12082,7 +12136,7 @@ async function createDerivedTopicImpl(topic, sourceTopicId, userId, copyHistory,
|
|
|
12082
12136
|
isFork: copyHistory,
|
|
12083
12137
|
...subagent ? { isSubagent: true } : {},
|
|
12084
12138
|
visibility: topic.visibility,
|
|
12085
|
-
|
|
12139
|
+
surface
|
|
12086
12140
|
};
|
|
12087
12141
|
let sessionId;
|
|
12088
12142
|
let rollbackHandle;
|
|
@@ -12190,7 +12244,7 @@ async function createDerivedTopicImpl(topic, sourceTopicId, userId, copyHistory,
|
|
|
12190
12244
|
if (!currentSource || currentSource.kind === "manager" || !isParticipant(currentSource, userId) || subagent && isRuntimeTopicMaintenance(sourceTopicId)) {
|
|
12191
12245
|
throw new TopicDeriveBusyError("Source topic changed while deriving; try again");
|
|
12192
12246
|
}
|
|
12193
|
-
const transactionalConflict = findTopicTitleConflict(title, kind);
|
|
12247
|
+
const transactionalConflict = findTopicTitleConflict(title, kind, { surface });
|
|
12194
12248
|
if (transactionalConflict)
|
|
12195
12249
|
throw new TopicTitleConflictError(title);
|
|
12196
12250
|
upsertTopic(derived);
|
|
@@ -17834,7 +17888,8 @@ function parseSessionCommContext(args, defaults) {
|
|
|
17834
17888
|
function createSessionTargetCatalog(host) {
|
|
17835
17889
|
const { currentTopicId, currentTopicName, isAgent, listRows } = host;
|
|
17836
17890
|
function listTargets() {
|
|
17837
|
-
const
|
|
17891
|
+
const currentSurface = host.currentSurface;
|
|
17892
|
+
const eligibleRows = listRows().filter((row) => row.kind !== "manager" && (!currentSurface || (row.surface ?? currentSurface) === currentSurface));
|
|
17838
17893
|
const titleCounts = new Map;
|
|
17839
17894
|
const qualifiedCounts = new Map;
|
|
17840
17895
|
for (const row of eligibleRows) {
|
|
@@ -21023,4 +21078,4 @@ export {
|
|
|
21023
21078
|
createAgentHealthMcpServer
|
|
21024
21079
|
};
|
|
21025
21080
|
|
|
21026
|
-
//# debugId=
|
|
21081
|
+
//# debugId=BFB111C75156DA0764756E2164756E21
|