negotium 0.4.0 → 0.4.2
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 +179 -142
- package/dist/agent-helpers.js.map +7 -7
- package/dist/{chunk-zq2tcq4k.js → chunk-238qj1qy.js} +58 -22
- package/dist/{chunk-zq2tcq4k.js.map → chunk-238qj1qy.js.map} +5 -5
- package/dist/hosted-agent.js +89 -47
- package/dist/hosted-agent.js.map +8 -8
- package/dist/main.js +315 -278
- package/dist/main.js.map +7 -7
- package/dist/mcp-catalog.js +3 -2
- package/dist/mcp-catalog.js.map +3 -3
- package/dist/mcp-factories.js +161 -124
- package/dist/mcp-factories.js.map +7 -7
- package/dist/registry.js +3 -3
- package/dist/registry.js.map +2 -2
- package/dist/rollout.js +1 -1
- package/dist/runtime/src/agents/codex-provider.ts +7 -1
- package/dist/runtime/src/agents/codex-vault-hook-bridge.ts +14 -8
- package/dist/runtime/src/agents/codex-vault-hook.mjs +3 -1
- package/dist/runtime/src/platform/mcp-catalog-policy.ts +5 -0
- package/dist/runtime/src/platform/mcp-config.ts +81 -0
- package/dist/runtime/src/version.ts +1 -1
- package/dist/types/packages/core/src/agents/codex-vault-hook-bridge.d.ts +1 -0
- package/dist/types/packages/core/src/platform/mcp-catalog-policy.d.ts +4 -0
- package/dist/types/packages/core/src/platform/mcp-config.d.ts +19 -0
- package/dist/types/packages/core/src/version.d.ts +1 -1
- package/package.json +2 -2
package/dist/main.js
CHANGED
|
@@ -1869,7 +1869,7 @@ var exports_version = {};
|
|
|
1869
1869
|
__export(exports_version, {
|
|
1870
1870
|
NEGOTIUM_VERSION: () => NEGOTIUM_VERSION
|
|
1871
1871
|
});
|
|
1872
|
-
var NEGOTIUM_VERSION = "0.4.
|
|
1872
|
+
var NEGOTIUM_VERSION = "0.4.2";
|
|
1873
1873
|
|
|
1874
1874
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
1875
1875
|
import { spawn } from "child_process";
|
|
@@ -2654,7 +2654,8 @@ var init_mcp_catalog_policy = __esm(() => {
|
|
|
2654
2654
|
"system-health": { scopes: ["dm", "forum", "manager", "cron"], forumRequired: true },
|
|
2655
2655
|
"background-bash": { scopes: ["forum"], forumRequired: true },
|
|
2656
2656
|
"agent-health": { scopes: ["forum", "manager", "cron"], forumRequired: true },
|
|
2657
|
-
vault: { scopes: ["dm", "forum", "manager", "cron"], forumRequired: true }
|
|
2657
|
+
vault: { scopes: ["dm", "forum", "manager", "cron"], forumRequired: true },
|
|
2658
|
+
"cua-rs": { scopes: ["dm", "forum", "fork"], forumRequired: false }
|
|
2658
2659
|
};
|
|
2659
2660
|
});
|
|
2660
2661
|
|
|
@@ -2666,6 +2667,9 @@ function browserOwnerCapability(capability, owner) {
|
|
|
2666
2667
|
var init_capability = () => {};
|
|
2667
2668
|
|
|
2668
2669
|
// ../../packages/core/src/platform/mcp-config.ts
|
|
2670
|
+
import { accessSync as accessSync2, constants as fsConstants } from "fs";
|
|
2671
|
+
import { homedir as homedir6 } from "os";
|
|
2672
|
+
import { join as join8 } from "path";
|
|
2669
2673
|
function buildStdioMcpServer(agent, serverFile, serverArgs, env) {
|
|
2670
2674
|
if (agent === "codex") {
|
|
2671
2675
|
return {
|
|
@@ -2781,6 +2785,27 @@ function backgroundBashTransport(agent, port, userId, topic) {
|
|
|
2781
2785
|
}
|
|
2782
2786
|
return { type: "sse", url: `http://127.0.0.1:${port}/sse`, headers };
|
|
2783
2787
|
}
|
|
2788
|
+
function cuaRsArgs() {
|
|
2789
|
+
const raw = envText("NEGOTIUM_CUA_RS_ALLOW_HID")?.trim().toLowerCase();
|
|
2790
|
+
const on = raw === "1" || raw === "true" || raw === "yes";
|
|
2791
|
+
return on ? ["--allow-hid"] : [];
|
|
2792
|
+
}
|
|
2793
|
+
function resolveCuaRsBinary(platform2 = process.platform) {
|
|
2794
|
+
if (platform2 !== "darwin")
|
|
2795
|
+
return null;
|
|
2796
|
+
const candidates = [
|
|
2797
|
+
envText("NEGOTIUM_CUA_RS_BIN"),
|
|
2798
|
+
join8(homedir6(), ".local", "bin", "cua-rs"),
|
|
2799
|
+
"/usr/local/bin/cua-rs"
|
|
2800
|
+
].filter((p) => Boolean(p));
|
|
2801
|
+
for (const candidate of candidates) {
|
|
2802
|
+
try {
|
|
2803
|
+
accessSync2(candidate, fsConstants.X_OK);
|
|
2804
|
+
return candidate;
|
|
2805
|
+
} catch {}
|
|
2806
|
+
}
|
|
2807
|
+
return null;
|
|
2808
|
+
}
|
|
2784
2809
|
function refreshForumCatalogViews() {
|
|
2785
2810
|
const { all, required, optional } = classifyForumMcpServers(MCP_CATALOG);
|
|
2786
2811
|
allForumMcpServerNames.splice(0, allForumMcpServerNames.length, ...all);
|
|
@@ -3240,6 +3265,15 @@ var init_mcp_config = __esm(() => {
|
|
|
3240
3265
|
args.push("--list-only=true");
|
|
3241
3266
|
return buildBuiltinMcpServer("vault", { ...ctx, userId: vaultUserId ?? userId }, () => buildStdioMcpServer(agent, VAULT_SERVER, args));
|
|
3242
3267
|
}
|
|
3268
|
+
},
|
|
3269
|
+
"cua-rs": {
|
|
3270
|
+
...commonRuntimeMcpPolicy("cua-rs"),
|
|
3271
|
+
build() {
|
|
3272
|
+
const bin = resolveCuaRsBinary();
|
|
3273
|
+
if (!bin)
|
|
3274
|
+
return null;
|
|
3275
|
+
return { command: bin, args: cuaRsArgs() };
|
|
3276
|
+
}
|
|
3243
3277
|
}
|
|
3244
3278
|
};
|
|
3245
3279
|
allForumMcpServerNames = [];
|
|
@@ -3311,14 +3345,14 @@ var init_execution_host = __esm(async () => {
|
|
|
3311
3345
|
// ../../packages/core/src/agents/rollout/codex.ts
|
|
3312
3346
|
import { randomBytes as randomBytes4 } from "crypto";
|
|
3313
3347
|
import { existsSync as existsSync6, readFileSync as readFileSync5, realpathSync as realpathSync2, statSync as statSync2, unlinkSync as unlinkSync5 } from "fs";
|
|
3314
|
-
import { basename, dirname as dirname6, join as
|
|
3348
|
+
import { basename, dirname as dirname6, join as join9, resolve as resolve5 } from "path";
|
|
3315
3349
|
function codexSessionsDir() {
|
|
3316
|
-
return
|
|
3350
|
+
return join9(hostedCodexHomePath(), "sessions");
|
|
3317
3351
|
}
|
|
3318
3352
|
function loadCodexShell() {
|
|
3319
3353
|
if (_shellCache)
|
|
3320
3354
|
return _shellCache;
|
|
3321
|
-
const raw = readFileSync5(
|
|
3355
|
+
const raw = readFileSync5(join9(FIXTURES_DIR, "codex-shell.jsonl"), "utf8");
|
|
3322
3356
|
const lines = parseJsonlText(raw);
|
|
3323
3357
|
if (lines.length < 5) {
|
|
3324
3358
|
throw new Error(`loadCodexShell: expected >=5 entries in codex-shell.jsonl, got ${lines.length}`);
|
|
@@ -3385,8 +3419,8 @@ function codexRolloutPath(threadId, fallback) {
|
|
|
3385
3419
|
const hh = String(createdAt.getHours()).padStart(2, "0");
|
|
3386
3420
|
const min = String(createdAt.getMinutes()).padStart(2, "0");
|
|
3387
3421
|
const ss = String(createdAt.getSeconds()).padStart(2, "0");
|
|
3388
|
-
const dir =
|
|
3389
|
-
return
|
|
3422
|
+
const dir = join9(codexSessionsDir(), yyyy, mm, dd);
|
|
3423
|
+
return join9(dir, `rollout-${yyyy}-${mm}-${dd}T${hh}-${min}-${ss}-${threadId}.jsonl`);
|
|
3390
3424
|
}
|
|
3391
3425
|
function canonicalFilePath(path) {
|
|
3392
3426
|
const absolute = resolve5(path);
|
|
@@ -3394,7 +3428,7 @@ function canonicalFilePath(path) {
|
|
|
3394
3428
|
return realpathSync2(absolute);
|
|
3395
3429
|
} catch {
|
|
3396
3430
|
try {
|
|
3397
|
-
return
|
|
3431
|
+
return join9(realpathSync2(dirname6(absolute)), basename(absolute));
|
|
3398
3432
|
} catch {
|
|
3399
3433
|
return absolute;
|
|
3400
3434
|
}
|
|
@@ -3624,19 +3658,19 @@ function latestCodexRolloutPath(threadId) {
|
|
|
3624
3658
|
try {
|
|
3625
3659
|
if (buckets) {
|
|
3626
3660
|
for (const bucket of buckets) {
|
|
3627
|
-
const dir =
|
|
3661
|
+
const dir = join9(sessionsDir, bucket);
|
|
3628
3662
|
if (!existsSync6(dir))
|
|
3629
3663
|
continue;
|
|
3630
3664
|
const glob = new Bun.Glob(`rollout-*-${threadId}.jsonl`);
|
|
3631
3665
|
for (const rel of glob.scanSync({ cwd: dir, onlyFiles: true })) {
|
|
3632
|
-
candidates.push(
|
|
3666
|
+
candidates.push(join9(dir, rel));
|
|
3633
3667
|
}
|
|
3634
3668
|
}
|
|
3635
3669
|
}
|
|
3636
3670
|
if (candidates.length === 0) {
|
|
3637
3671
|
const glob = new Bun.Glob(`**/rollout-*-${threadId}.jsonl`);
|
|
3638
3672
|
for (const rel of glob.scanSync({ cwd: sessionsDir, onlyFiles: true })) {
|
|
3639
|
-
candidates.push(
|
|
3673
|
+
candidates.push(join9(sessionsDir, rel));
|
|
3640
3674
|
}
|
|
3641
3675
|
}
|
|
3642
3676
|
return candidates.sort((a, b) => statSync2(b).mtimeMs - statSync2(a).mtimeMs)[0];
|
|
@@ -3757,13 +3791,13 @@ function sweepPriorRolloutsForThread(threadId) {
|
|
|
3757
3791
|
return;
|
|
3758
3792
|
}
|
|
3759
3793
|
for (const bucket of buckets) {
|
|
3760
|
-
const dir =
|
|
3794
|
+
const dir = join9(sessionsDir, bucket);
|
|
3761
3795
|
if (!existsSync6(dir))
|
|
3762
3796
|
continue;
|
|
3763
3797
|
try {
|
|
3764
3798
|
const glob = new Bun.Glob(`rollout-*-${threadId}.jsonl`);
|
|
3765
3799
|
for (const rel of glob.scanSync({ cwd: dir, onlyFiles: true })) {
|
|
3766
|
-
const fullPath =
|
|
3800
|
+
const fullPath = join9(dir, rel);
|
|
3767
3801
|
try {
|
|
3768
3802
|
unlinkSync5(fullPath);
|
|
3769
3803
|
} catch (e) {
|
|
@@ -3781,7 +3815,7 @@ function sweepPriorRolloutsFullTree(threadId, sessionsDir) {
|
|
|
3781
3815
|
try {
|
|
3782
3816
|
const glob = new Bun.Glob(`**/rollout-*-${threadId}.jsonl`);
|
|
3783
3817
|
for (const rel of glob.scanSync({ cwd: sessionsDir, onlyFiles: true })) {
|
|
3784
|
-
const fullPath =
|
|
3818
|
+
const fullPath = join9(sessionsDir, rel);
|
|
3785
3819
|
try {
|
|
3786
3820
|
unlinkSync5(fullPath);
|
|
3787
3821
|
} catch (e) {
|
|
@@ -3959,7 +3993,7 @@ var init_codex_app_server = __esm(async () => {
|
|
|
3959
3993
|
|
|
3960
3994
|
// ../../packages/core/src/agents/codex-registry.ts
|
|
3961
3995
|
import { existsSync as existsSync7, unlinkSync as unlinkSync6 } from "fs";
|
|
3962
|
-
import { join as
|
|
3996
|
+
import { join as join10 } from "path";
|
|
3963
3997
|
var VALID_EFFORTS2, codexRegistry, codexRegistryOperations;
|
|
3964
3998
|
var init_codex_registry = __esm(async () => {
|
|
3965
3999
|
await init_codex_app_server();
|
|
@@ -4002,7 +4036,7 @@ var init_codex_registry = __esm(async () => {
|
|
|
4002
4036
|
async cleanupRollouts({ sessionIds }) {
|
|
4003
4037
|
if (sessionIds.length === 0)
|
|
4004
4038
|
return;
|
|
4005
|
-
const sessionsDir =
|
|
4039
|
+
const sessionsDir = join10(hostedCodexHomePath(), "sessions");
|
|
4006
4040
|
if (!existsSync7(sessionsDir))
|
|
4007
4041
|
return;
|
|
4008
4042
|
const failures = [];
|
|
@@ -4010,7 +4044,7 @@ var init_codex_registry = __esm(async () => {
|
|
|
4010
4044
|
try {
|
|
4011
4045
|
const glob = new Bun.Glob(`**/rollout-*-${tid}.jsonl`);
|
|
4012
4046
|
for await (const rel of glob.scan({ cwd: sessionsDir, onlyFiles: true })) {
|
|
4013
|
-
const path =
|
|
4047
|
+
const path = join10(sessionsDir, rel);
|
|
4014
4048
|
try {
|
|
4015
4049
|
unlinkSync6(path);
|
|
4016
4050
|
} catch (e) {
|
|
@@ -4035,16 +4069,16 @@ var init_codex_registry = __esm(async () => {
|
|
|
4035
4069
|
// ../../packages/core/src/agents/maestro-registry.ts
|
|
4036
4070
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
4037
4071
|
import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
|
|
4038
|
-
import { homedir as
|
|
4039
|
-
import { join as
|
|
4072
|
+
import { homedir as homedir7 } from "os";
|
|
4073
|
+
import { join as join11, resolve as resolve6 } from "path";
|
|
4040
4074
|
function maestroSessionsDir() {
|
|
4041
|
-
return
|
|
4075
|
+
return join11(process.env.MAESTRO_DATA_DIR ? resolve6(process.env.MAESTRO_DATA_DIR) : join11(homedir7(), ".maestro"), "sessions");
|
|
4042
4076
|
}
|
|
4043
4077
|
function maestroSessionPath(sessionId) {
|
|
4044
|
-
return
|
|
4078
|
+
return join11(maestroSessionsDir(), `${sessionId}.jsonl`);
|
|
4045
4079
|
}
|
|
4046
4080
|
function maestroActiveSessionPath(sessionId) {
|
|
4047
|
-
return
|
|
4081
|
+
return join11(maestroSessionsDir(), `${sessionId}.active.jsonl`);
|
|
4048
4082
|
}
|
|
4049
4083
|
function existingCreatedAt(path) {
|
|
4050
4084
|
if (!existsSync8(path))
|
|
@@ -4283,7 +4317,7 @@ __export(exports_tasks, {
|
|
|
4283
4317
|
TASK_STATUS_VALUES: () => TASK_STATUS_VALUES
|
|
4284
4318
|
});
|
|
4285
4319
|
import { existsSync as existsSync10, mkdirSync as mkdirSync8, readFileSync as readFileSync7, renameSync as renameSync4, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
|
|
4286
|
-
import { dirname as dirname7, join as
|
|
4320
|
+
import { dirname as dirname7, join as join12 } from "path";
|
|
4287
4321
|
function safeTaskScopeKey(scopeKey) {
|
|
4288
4322
|
const safe = sanitizeFileName(scopeKey);
|
|
4289
4323
|
if (!safe || safe === "." || safe === "..") {
|
|
@@ -4295,7 +4329,7 @@ function taskScopeKey(opts) {
|
|
|
4295
4329
|
return opts.topicId?.trim() || opts.session || "default";
|
|
4296
4330
|
}
|
|
4297
4331
|
function getTaskFilePath(userId, scopeKey) {
|
|
4298
|
-
return
|
|
4332
|
+
return join12(resolveStorageDataDir(), "tasks", `${safeTaskScopeKey(scopeKey)}.json`);
|
|
4299
4333
|
}
|
|
4300
4334
|
function readTasks(userId, scopeKey) {
|
|
4301
4335
|
const path = getTaskFilePath(userId, scopeKey);
|
|
@@ -4479,16 +4513,16 @@ import {
|
|
|
4479
4513
|
unlinkSync as unlinkSync8,
|
|
4480
4514
|
writeFileSync as writeFileSync7
|
|
4481
4515
|
} from "fs";
|
|
4482
|
-
import { dirname as dirname8, join as
|
|
4516
|
+
import { dirname as dirname8, join as join13 } from "path";
|
|
4483
4517
|
function conversationDir(_userId) {
|
|
4484
|
-
return
|
|
4518
|
+
return join13(resolveStorageDataDir(), "conversations");
|
|
4485
4519
|
}
|
|
4486
4520
|
function topicFilename(topicName) {
|
|
4487
4521
|
const t = sanitizeTopicName(topicName, true);
|
|
4488
4522
|
return `${t}.jsonl`;
|
|
4489
4523
|
}
|
|
4490
4524
|
function getConversationPath(userId, topicName) {
|
|
4491
|
-
return
|
|
4525
|
+
return join13(conversationDir(userId), topicFilename(topicName));
|
|
4492
4526
|
}
|
|
4493
4527
|
function getActiveConversationPath(userId, topicName) {
|
|
4494
4528
|
const rawPath = getConversationPath(userId, topicName);
|
|
@@ -5245,7 +5279,7 @@ import { existsSync as existsSync13 } from "fs";
|
|
|
5245
5279
|
import { chmod, mkdtemp, rm, writeFile } from "fs/promises";
|
|
5246
5280
|
import { createServer } from "net";
|
|
5247
5281
|
import { tmpdir as tmpdir2 } from "os";
|
|
5248
|
-
import { dirname as dirname9, join as
|
|
5282
|
+
import { dirname as dirname9, join as join14, resolve as resolve7 } from "path";
|
|
5249
5283
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
5250
5284
|
function evaluateCodexVaultPreToolUse(input, userId, operations) {
|
|
5251
5285
|
if (operations.referencesSensitiveStorage(input.tool_input)) {
|
|
@@ -5283,9 +5317,11 @@ function hookClientPath() {
|
|
|
5283
5317
|
return packaged;
|
|
5284
5318
|
throw new Error("Codex Vault hook client is missing from this installation");
|
|
5285
5319
|
}
|
|
5286
|
-
function privateCodexWrapper(codexScript) {
|
|
5320
|
+
function privateCodexWrapper(codexScript, socketPath, token) {
|
|
5287
5321
|
return [
|
|
5288
5322
|
"#!/bin/sh",
|
|
5323
|
+
`export ${HOOK_SOCKET_ENV}=${shellQuote(socketPath)}`,
|
|
5324
|
+
`export ${HOOK_TOKEN_ENV}=${shellQuote(token)}`,
|
|
5289
5325
|
'if [ "$1" = "exec" ]; then',
|
|
5290
5326
|
" shift",
|
|
5291
5327
|
` exec ${shellQuote(process.execPath)} ${shellQuote(codexScript)} exec --dangerously-bypass-hook-trust "$@"`,
|
|
@@ -5296,10 +5332,10 @@ function privateCodexWrapper(codexScript) {
|
|
|
5296
5332
|
`);
|
|
5297
5333
|
}
|
|
5298
5334
|
async function createCodexVaultHookBridge(userId) {
|
|
5299
|
-
const root = await mkdtemp(
|
|
5335
|
+
const root = await mkdtemp(join14(tmpdir2(), "negotium-codex-vault-"));
|
|
5300
5336
|
await chmod(root, 448);
|
|
5301
|
-
const socketPath =
|
|
5302
|
-
const wrapperPath =
|
|
5337
|
+
const socketPath = join14(root, "hook.sock");
|
|
5338
|
+
const wrapperPath = join14(root, "codex-with-hooks");
|
|
5303
5339
|
const token = randomBytes5(32).toString("hex");
|
|
5304
5340
|
const connections = new Set;
|
|
5305
5341
|
const server = createServer((socket) => {
|
|
@@ -5348,15 +5384,13 @@ async function createCodexVaultHookBridge(userId) {
|
|
|
5348
5384
|
});
|
|
5349
5385
|
});
|
|
5350
5386
|
await chmod(socketPath, 384);
|
|
5351
|
-
await writeFile(wrapperPath, privateCodexWrapper(codexCliScriptPath()), {
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
shellQuote(socketPath),
|
|
5356
|
-
shellQuote(token)
|
|
5357
|
-
].join(" ");
|
|
5387
|
+
await writeFile(wrapperPath, privateCodexWrapper(codexCliScriptPath(), socketPath, token), {
|
|
5388
|
+
mode: 448
|
|
5389
|
+
});
|
|
5390
|
+
const command = [shellQuote(process.execPath), shellQuote(hookClientPath())].join(" ");
|
|
5358
5391
|
return {
|
|
5359
5392
|
codexPathOverride: wrapperPath,
|
|
5393
|
+
environment: { [HOOK_SOCKET_ENV]: socketPath, [HOOK_TOKEN_ENV]: token },
|
|
5360
5394
|
hooks: {
|
|
5361
5395
|
PreToolUse: [
|
|
5362
5396
|
{
|
|
@@ -5385,7 +5419,7 @@ async function createCodexVaultHookBridge(userId) {
|
|
|
5385
5419
|
throw error;
|
|
5386
5420
|
}
|
|
5387
5421
|
}
|
|
5388
|
-
var MAX_HOOK_REQUEST_BYTES, SENSITIVE_STORAGE_DENIAL = "Runtime secret storage access is not permitted";
|
|
5422
|
+
var MAX_HOOK_REQUEST_BYTES, SENSITIVE_STORAGE_DENIAL = "Runtime secret storage access is not permitted", HOOK_SOCKET_ENV = "NEGOTIUM_CODEX_VAULT_HOOK_SOCKET", HOOK_TOKEN_ENV = "NEGOTIUM_CODEX_VAULT_HOOK_TOKEN";
|
|
5389
5423
|
var init_codex_vault_hook_bridge = __esm(async () => {
|
|
5390
5424
|
init_codex_native_multi_agent();
|
|
5391
5425
|
await init_execution_host();
|
|
@@ -5918,8 +5952,8 @@ __export(exports_codex_provider, {
|
|
|
5918
5952
|
});
|
|
5919
5953
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
5920
5954
|
import { existsSync as existsSync14, readFileSync as readFileSync11, realpathSync as realpathSync3, statSync as statSync5 } from "fs";
|
|
5921
|
-
import { homedir as
|
|
5922
|
-
import { dirname as dirname10, isAbsolute as isAbsolute2, join as
|
|
5955
|
+
import { homedir as homedir8 } from "os";
|
|
5956
|
+
import { dirname as dirname10, isAbsolute as isAbsolute2, join as join15, relative, resolve as resolve9 } from "path";
|
|
5923
5957
|
import { Codex } from "@openai/codex-sdk";
|
|
5924
5958
|
function sameCodexUsage(usage, total) {
|
|
5925
5959
|
return usage.input_tokens === total.inputTokens && usage.output_tokens === total.outputTokens && (usage.cached_input_tokens ?? 0) === total.cachedInputTokens && (usage.cache_write_input_tokens ?? 0) === total.cacheWriteInputTokens;
|
|
@@ -5947,7 +5981,7 @@ function codexMcpServerName(name) {
|
|
|
5947
5981
|
return CODEX_MCP_SERVER_NAME_OVERRIDES[name] ?? name;
|
|
5948
5982
|
}
|
|
5949
5983
|
function globalCodexMcpServerNames(authFilePath) {
|
|
5950
|
-
const configPath =
|
|
5984
|
+
const configPath = join15(dirname10(authFilePath), "config.toml");
|
|
5951
5985
|
if (!existsSync14(configPath))
|
|
5952
5986
|
return [];
|
|
5953
5987
|
try {
|
|
@@ -6305,7 +6339,7 @@ async function* codexProvider(opts) {
|
|
|
6305
6339
|
mcpServerCount: Object.keys(codexMcpServers).length
|
|
6306
6340
|
}, "codexProvider: starting turn");
|
|
6307
6341
|
const hostedCodexHome = hostedCodexHomePath();
|
|
6308
|
-
const inheritedCodexHome = process.env.CODEX_HOME ||
|
|
6342
|
+
const inheritedCodexHome = process.env.CODEX_HOME || join15(homedir8(), ".codex");
|
|
6309
6343
|
const codexEnvironment = scopedBrowserCapability || resolve9(hostedCodexHome) !== resolve9(inheritedCodexHome) ? {
|
|
6310
6344
|
...Object.fromEntries(Object.entries(process.env).filter((entry) => typeof entry[1] === "string")),
|
|
6311
6345
|
CODEX_HOME: hostedCodexHome,
|
|
@@ -6499,7 +6533,10 @@ async function* codexProvider(opts) {
|
|
|
6499
6533
|
yield fileEvent;
|
|
6500
6534
|
}
|
|
6501
6535
|
} else if (item.type === "error") {
|
|
6502
|
-
|
|
6536
|
+
const message = String(item.message ?? "");
|
|
6537
|
+
if (message !== CODEX_HOOK_TRUST_BYPASS_NOTICE) {
|
|
6538
|
+
yield { type: "error", content: message };
|
|
6539
|
+
}
|
|
6503
6540
|
}
|
|
6504
6541
|
break;
|
|
6505
6542
|
}
|
|
@@ -6590,7 +6627,7 @@ async function* codexProvider(opts) {
|
|
|
6590
6627
|
await vaultHook.close();
|
|
6591
6628
|
}
|
|
6592
6629
|
}
|
|
6593
|
-
var CODEX_MCP_SERVER_NAME_OVERRIDES, CODEX_DIFF_FILE_LIMIT, CODEX_DIFF_BASELINE_FILE_LIMIT = 200, CODEX_DIFF_BASELINE_BYTE_LIMIT, CODEX_STARTUP_TIMEOUT_MS = 90000;
|
|
6630
|
+
var CODEX_HOOK_TRUST_BYPASS_NOTICE = "`--dangerously-bypass-hook-trust` is enabled. Enabled hooks may run without review for this invocation.", CODEX_MCP_SERVER_NAME_OVERRIDES, CODEX_DIFF_FILE_LIMIT, CODEX_DIFF_BASELINE_FILE_LIMIT = 200, CODEX_DIFF_BASELINE_BYTE_LIMIT, CODEX_STARTUP_TIMEOUT_MS = 90000;
|
|
6594
6631
|
var init_codex_provider = __esm(async () => {
|
|
6595
6632
|
init_codex_native_multi_agent();
|
|
6596
6633
|
init_codex_tree_kill();
|
|
@@ -6756,8 +6793,8 @@ var init_maestro_provider = __esm(async () => {
|
|
|
6756
6793
|
|
|
6757
6794
|
// ../../packages/core/src/agents/index.ts
|
|
6758
6795
|
import { existsSync as existsSync15 } from "fs";
|
|
6759
|
-
import { homedir as
|
|
6760
|
-
import { join as
|
|
6796
|
+
import { homedir as homedir9 } from "os";
|
|
6797
|
+
import { join as join16 } from "path";
|
|
6761
6798
|
async function* dispatchAgent(opts) {
|
|
6762
6799
|
switch (opts.agent) {
|
|
6763
6800
|
case "claude": {
|
|
@@ -6791,11 +6828,11 @@ async function resolveSessionFileMissing(agent, sessionId, cwd) {
|
|
|
6791
6828
|
switch (agent) {
|
|
6792
6829
|
case "claude": {
|
|
6793
6830
|
const encodedCwd = encodeClaudeCwd(cwd);
|
|
6794
|
-
const path =
|
|
6831
|
+
const path = join16(homedir9(), ".claude", "projects", encodedCwd, `${sessionId}.jsonl`);
|
|
6795
6832
|
return !existsSync15(path);
|
|
6796
6833
|
}
|
|
6797
6834
|
case "codex": {
|
|
6798
|
-
const sessionsDir =
|
|
6835
|
+
const sessionsDir = join16(hostedCodexHomePath(), "sessions");
|
|
6799
6836
|
const glob = new Bun.Glob(`**/rollout-*-${sessionId}.jsonl`);
|
|
6800
6837
|
for await (const _rel of glob.scan({ cwd: sessionsDir, onlyFiles: true })) {
|
|
6801
6838
|
return false;
|
|
@@ -10124,13 +10161,13 @@ var init_browser_processes = __esm(async () => {
|
|
|
10124
10161
|
});
|
|
10125
10162
|
|
|
10126
10163
|
// ../../packages/core/src/platform/playwright/headed-launch.ts
|
|
10127
|
-
import { accessSync as
|
|
10164
|
+
import { accessSync as accessSync3, constants as constants2 } from "fs";
|
|
10128
10165
|
import { delimiter, isAbsolute as isAbsolute3, resolve as resolve12 } from "path";
|
|
10129
10166
|
function findExecutableOnPath(command, environment = process.env) {
|
|
10130
10167
|
const candidates = isAbsolute3(command) ? [command] : (environment.PATH ?? "").split(delimiter).filter(Boolean).map((directory) => resolve12(directory, command));
|
|
10131
10168
|
for (const candidate of candidates) {
|
|
10132
10169
|
try {
|
|
10133
|
-
|
|
10170
|
+
accessSync3(candidate, constants2.X_OK);
|
|
10134
10171
|
return candidate;
|
|
10135
10172
|
} catch {}
|
|
10136
10173
|
}
|
|
@@ -10252,7 +10289,7 @@ import { randomBytes as randomBytes6, timingSafeEqual as timingSafeEqual2 } from
|
|
|
10252
10289
|
import { chmodSync as chmodSync4 } from "fs";
|
|
10253
10290
|
import { createServer as createServer3 } from "net";
|
|
10254
10291
|
import { tmpdir as tmpdir3 } from "os";
|
|
10255
|
-
import { join as
|
|
10292
|
+
import { join as join17 } from "path";
|
|
10256
10293
|
function deepMapStrings2(value, transform) {
|
|
10257
10294
|
if (typeof value === "string")
|
|
10258
10295
|
return transform(value);
|
|
@@ -10339,7 +10376,7 @@ function authorized(actual, expected) {
|
|
|
10339
10376
|
}
|
|
10340
10377
|
async function createBrowserVaultBroker(userId) {
|
|
10341
10378
|
const token = randomBytes6(32).toString("hex");
|
|
10342
|
-
const socketPath =
|
|
10379
|
+
const socketPath = join17(process.platform === "win32" ? tmpdir3() : "/tmp", `negotium-browser-vault-${process.pid}-${randomBytes6(8).toString("hex")}.sock`);
|
|
10343
10380
|
const retainedForms = new Map;
|
|
10344
10381
|
const leases = new Map;
|
|
10345
10382
|
const sockets = new Set;
|
|
@@ -10605,7 +10642,7 @@ import {
|
|
|
10605
10642
|
unlinkSync as unlinkSync11,
|
|
10606
10643
|
writeFileSync as writeFileSync8
|
|
10607
10644
|
} from "fs";
|
|
10608
|
-
import { dirname as dirname11, join as
|
|
10645
|
+
import { dirname as dirname11, join as join18, resolve as resolve13 } from "path";
|
|
10609
10646
|
function removeDefaultProfileDataDir(userDataDir) {
|
|
10610
10647
|
const root = resolve13(BROWSER_PROFILES_DIR);
|
|
10611
10648
|
const target = resolve13(userDataDir);
|
|
@@ -10695,14 +10732,14 @@ function portFileName(instanceKey) {
|
|
|
10695
10732
|
function writePortFile(instanceKey, port) {
|
|
10696
10733
|
try {
|
|
10697
10734
|
mkdirSync10(managerHost.portsDir, { recursive: true });
|
|
10698
|
-
writeFileSync8(
|
|
10735
|
+
writeFileSync8(join18(managerHost.portsDir, portFileName(instanceKey)), String(port));
|
|
10699
10736
|
} catch (e) {
|
|
10700
10737
|
logger.warn({ err: e, instanceKey, port }, "Failed to save playwright port file");
|
|
10701
10738
|
}
|
|
10702
10739
|
}
|
|
10703
10740
|
function deletePortFile(instanceKey) {
|
|
10704
10741
|
try {
|
|
10705
|
-
unlinkSync11(
|
|
10742
|
+
unlinkSync11(join18(managerHost.portsDir, portFileName(instanceKey)));
|
|
10706
10743
|
} catch (e) {
|
|
10707
10744
|
if (e.code === "ENOENT")
|
|
10708
10745
|
return;
|
|
@@ -12248,32 +12285,32 @@ __export(exports_wiki, {
|
|
|
12248
12285
|
getSharedWikiDir: () => getSharedWikiDir
|
|
12249
12286
|
});
|
|
12250
12287
|
import { existsSync as existsSync17, readdirSync as readdirSync3, statSync as statSync6 } from "fs";
|
|
12251
|
-
import { basename as basename2, dirname as dirname12, join as
|
|
12288
|
+
import { basename as basename2, dirname as dirname12, join as join19 } from "path";
|
|
12252
12289
|
function getWikiDir(_userId, workspaceDir = resolveStorageWorkspaceDir()) {
|
|
12253
|
-
return
|
|
12290
|
+
return join19(workspaceDir, "wiki");
|
|
12254
12291
|
}
|
|
12255
12292
|
function getSharedWikiDir(workspaceDir = resolveStorageWorkspaceDir()) {
|
|
12256
|
-
return workspaceDir === resolveStorageWorkspaceDir() ? resolveStorageSharedWikiDir() :
|
|
12293
|
+
return workspaceDir === resolveStorageWorkspaceDir() ? resolveStorageSharedWikiDir() : join19(workspaceDir, "wiki");
|
|
12257
12294
|
}
|
|
12258
12295
|
function findLatestSummaryFile(wikiDir, safeTopic) {
|
|
12259
|
-
const summariesDir =
|
|
12296
|
+
const summariesDir = join19(wikiDir, "summaries");
|
|
12260
12297
|
if (!existsSync17(summariesDir))
|
|
12261
12298
|
return null;
|
|
12262
12299
|
const files = readdirSync3(summariesDir).filter((f) => f.endsWith(".md") && f.match(new RegExp(`^\\d{4}-\\d{2}-\\d{2}-${safeTopic}(\\.md|~\\d+\\.md)$`)) && !f.endsWith("-sent-files.md")).sort((left, right) => {
|
|
12263
|
-
const mtimeDelta = statSync6(
|
|
12300
|
+
const mtimeDelta = statSync6(join19(summariesDir, right)).mtimeMs - statSync6(join19(summariesDir, left)).mtimeMs;
|
|
12264
12301
|
return mtimeDelta || right.localeCompare(left, undefined, { numeric: true });
|
|
12265
12302
|
});
|
|
12266
|
-
return files.length > 0 ?
|
|
12303
|
+
return files.length > 0 ? join19(summariesDir, files[0]) : null;
|
|
12267
12304
|
}
|
|
12268
12305
|
function getTopicMemoryFilePaths(_userId, topicName, forkOrigin, workspaceDir = resolveStorageWorkspaceDir()) {
|
|
12269
12306
|
const wikiDir = getSharedWikiDir(workspaceDir);
|
|
12270
12307
|
const resolveBrief = (name) => {
|
|
12271
12308
|
const safe = sanitizeTopicName(name, true);
|
|
12272
|
-
const brief =
|
|
12309
|
+
const brief = join19(wikiDir, "topic", `${safe}.md`);
|
|
12273
12310
|
const latestSummary = findLatestSummaryFile(wikiDir, safe);
|
|
12274
12311
|
return { brief, latestSummary };
|
|
12275
12312
|
};
|
|
12276
|
-
const archiveDir =
|
|
12313
|
+
const archiveDir = join19(wikiDir, "archive");
|
|
12277
12314
|
const archiveExistsFor = (name) => {
|
|
12278
12315
|
const safe = sanitizeTopicName(name);
|
|
12279
12316
|
return existsSync17(archiveDir) && readdirSync3(archiveDir).some((f) => f.endsWith(".jsonl") && f.startsWith(`${safe}_`));
|
|
@@ -12290,7 +12327,7 @@ function getTopicMemoryFilePaths(_userId, topicName, forkOrigin, workspaceDir =
|
|
|
12290
12327
|
};
|
|
12291
12328
|
}
|
|
12292
12329
|
return {
|
|
12293
|
-
memoryDir:
|
|
12330
|
+
memoryDir: join19(wikiDir, "topic"),
|
|
12294
12331
|
memoryFiles: [],
|
|
12295
12332
|
...target.latestSummary ? { latestSummaryFile: target.latestSummary } : {},
|
|
12296
12333
|
...hasArchive ? { hasArchive: true } : {}
|
|
@@ -12303,7 +12340,7 @@ var init_wiki = __esm(async () => {
|
|
|
12303
12340
|
// ../../packages/core/src/agents/archiver.ts
|
|
12304
12341
|
import { randomUUID as randomUUID10 } from "crypto";
|
|
12305
12342
|
import { existsSync as existsSync18, readdirSync as readdirSync4, readFileSync as readFileSync14, statSync as statSync7 } from "fs";
|
|
12306
|
-
import { join as
|
|
12343
|
+
import { join as join20 } from "path";
|
|
12307
12344
|
function resolveMemoryLanguage() {
|
|
12308
12345
|
const override = process.env.NEGOTIUM_MEMORY_LANG?.trim();
|
|
12309
12346
|
return override && override.length > 0 ? override : resolveOutputLanguage();
|
|
@@ -12554,10 +12591,10 @@ function distillOneLine(summaryMd) {
|
|
|
12554
12591
|
return "";
|
|
12555
12592
|
}
|
|
12556
12593
|
function findSummaryFile(storage, topicTitle, date, sinceMs, topicId) {
|
|
12557
|
-
const dir =
|
|
12594
|
+
const dir = join20(storage.getWikiDir(), "summaries");
|
|
12558
12595
|
if (!storage.fileExists(dir))
|
|
12559
12596
|
return null;
|
|
12560
|
-
const predicted =
|
|
12597
|
+
const predicted = join20(dir, wikiSummaryFilename(date, topicTitle, topicId));
|
|
12561
12598
|
if (storage.fileExists(predicted) && storage.fileModifiedAt(predicted) >= sinceMs)
|
|
12562
12599
|
return predicted;
|
|
12563
12600
|
let best = null;
|
|
@@ -12565,7 +12602,7 @@ function findSummaryFile(storage, topicTitle, date, sinceMs, topicId) {
|
|
|
12565
12602
|
if (!f.startsWith(`${date}-`) || !isTopicSummaryFile(f, topicId ?? "", topicTitle)) {
|
|
12566
12603
|
continue;
|
|
12567
12604
|
}
|
|
12568
|
-
const p =
|
|
12605
|
+
const p = join20(dir, f);
|
|
12569
12606
|
try {
|
|
12570
12607
|
const m = storage.fileModifiedAt(p);
|
|
12571
12608
|
if (m >= sinceMs && (!best || m > best.mtime))
|
|
@@ -12781,13 +12818,13 @@ __export(exports_topic_archive, {
|
|
|
12781
12818
|
archiveConversationEvents: () => archiveConversationEvents
|
|
12782
12819
|
});
|
|
12783
12820
|
import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync9 } from "fs";
|
|
12784
|
-
import { join as
|
|
12821
|
+
import { join as join21 } from "path";
|
|
12785
12822
|
function archiveTopicMessages(topicId, topicTitle, options = {}) {
|
|
12786
12823
|
const rows = options.afterRowid !== undefined ? getMessagesForTopicAfterRowid(topicId, options.afterRowid) : getAllMessagesForTopic(topicId);
|
|
12787
12824
|
if (rows.length === 0)
|
|
12788
12825
|
return null;
|
|
12789
12826
|
const safeTopic = sanitizeTopicName(topicTitle, true);
|
|
12790
|
-
const archiveDir =
|
|
12827
|
+
const archiveDir = join21(getSharedWikiDir(), "archive");
|
|
12791
12828
|
mkdirSync11(archiveDir, { recursive: true });
|
|
12792
12829
|
const date = new Date().toISOString().slice(0, 10);
|
|
12793
12830
|
const reasonSuffix = options.reason && options.reason !== "delete" ? `_${options.reason}` : "";
|
|
@@ -12800,7 +12837,7 @@ function archiveTopicMessages(topicId, topicTitle, options = {}) {
|
|
|
12800
12837
|
let path;
|
|
12801
12838
|
while (true) {
|
|
12802
12839
|
filename = `${safeTopic}_${date}${reasonSuffix}${counter === 1 ? "" : `_${counter}`}.jsonl`;
|
|
12803
|
-
path =
|
|
12840
|
+
path = join21(archiveDir, filename);
|
|
12804
12841
|
try {
|
|
12805
12842
|
writeFileSync9(path, body, { flag: "wx" });
|
|
12806
12843
|
break;
|
|
@@ -12845,7 +12882,7 @@ function archiveConversationEvents(topicId, topicTitle, userId, options = {}) {
|
|
|
12845
12882
|
const entries = readRawConversation(userId, topicTitle);
|
|
12846
12883
|
if (entries.length === 0)
|
|
12847
12884
|
return null;
|
|
12848
|
-
const archiveDir =
|
|
12885
|
+
const archiveDir = join21(getSharedWikiDir(), "archive");
|
|
12849
12886
|
mkdirSync11(archiveDir, { recursive: true });
|
|
12850
12887
|
const safeTopic = sanitizeTopicName(topicTitle, true);
|
|
12851
12888
|
const date = new Date().toISOString().slice(0, 10);
|
|
@@ -12873,7 +12910,7 @@ function archiveConversationEvents(topicId, topicTitle, userId, options = {}) {
|
|
|
12873
12910
|
let counter = 1;
|
|
12874
12911
|
while (true) {
|
|
12875
12912
|
const suffix = counter === 1 ? "" : `_${counter}`;
|
|
12876
|
-
const path =
|
|
12913
|
+
const path = join21(archiveDir, `${safeTopic}_${date}${reasonSuffix}_events${suffix}.jsonl`);
|
|
12877
12914
|
try {
|
|
12878
12915
|
writeFileSync9(path, body, { flag: "wx" });
|
|
12879
12916
|
logger.info({ topicId, topicTitle, archive: path, eventCount: entries.length }, "archiveConversationEvents: archived raw conversation events");
|
|
@@ -13884,7 +13921,7 @@ var init_runtime_turn_requests = __esm(async () => {
|
|
|
13884
13921
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
13885
13922
|
import { mkdtempSync as mkdtempSync2, rmSync as rmSync4, writeFileSync as writeFileSync11 } from "fs";
|
|
13886
13923
|
import { tmpdir as tmpdir4 } from "os";
|
|
13887
|
-
import { join as
|
|
13924
|
+
import { join as join22 } from "path";
|
|
13888
13925
|
async function waitForMemoryArchive(settled, timeoutMs) {
|
|
13889
13926
|
let timer;
|
|
13890
13927
|
try {
|
|
@@ -14137,7 +14174,7 @@ function formatCompactElapsed(startedAt) {
|
|
|
14137
14174
|
async function summarizeTopicContext(request) {
|
|
14138
14175
|
const startedAt = Date.now();
|
|
14139
14176
|
const sessionIds = [];
|
|
14140
|
-
const compactCwd = mkdtempSync2(
|
|
14177
|
+
const compactCwd = mkdtempSync2(join22(tmpdir4(), "negotium-compact-"));
|
|
14141
14178
|
const abortController = new AbortController;
|
|
14142
14179
|
const relayAbort = () => abortController.abort(request.signal?.reason);
|
|
14143
14180
|
if (request.signal?.aborted)
|
|
@@ -14164,7 +14201,7 @@ async function summarizeTopicContext(request) {
|
|
|
14164
14201
|
let error = "";
|
|
14165
14202
|
let toolViolation = false;
|
|
14166
14203
|
let compactionLogCalls = 0;
|
|
14167
|
-
const compactionLogPath =
|
|
14204
|
+
const compactionLogPath = join22(compactCwd, "conversation.log");
|
|
14168
14205
|
try {
|
|
14169
14206
|
const compactionMcp = useCompactionLog ? {
|
|
14170
14207
|
compact_log: {
|
|
@@ -15485,14 +15522,14 @@ var init_self_config = __esm(async () => {
|
|
|
15485
15522
|
});
|
|
15486
15523
|
|
|
15487
15524
|
// ../../packages/core/src/query/session-inbox-path.ts
|
|
15488
|
-
import { join as
|
|
15525
|
+
import { join as join23 } from "path";
|
|
15489
15526
|
function sessionInboxPath(userId, topicId) {
|
|
15490
15527
|
const key = Buffer.from(topicId, "utf8").toString("base64url");
|
|
15491
|
-
return
|
|
15528
|
+
return join23(SESSION_INBOX_DIR, userId, `${TOPIC_ID_FILE_PREFIX}${key}${JSONL_SUFFIX}`);
|
|
15492
15529
|
}
|
|
15493
15530
|
function scheduledSessionInboxPath(userId, topicId) {
|
|
15494
15531
|
const key = Buffer.from(topicId, "utf8").toString("base64url");
|
|
15495
|
-
return
|
|
15532
|
+
return join23(SESSION_INBOX_DIR, userId, `${TOPIC_ID_FILE_PREFIX}${key}${SCHEDULE_SUFFIX}`);
|
|
15496
15533
|
}
|
|
15497
15534
|
function decodeTopicIdFileName(fileName, suffix) {
|
|
15498
15535
|
if (!fileName.startsWith(TOPIC_ID_FILE_PREFIX) || !fileName.endsWith(suffix))
|
|
@@ -15520,13 +15557,13 @@ var init_session_inbox_path = __esm(() => {
|
|
|
15520
15557
|
|
|
15521
15558
|
// ../../packages/core/src/query/session-inbox-cleanup.ts
|
|
15522
15559
|
import { unlinkSync as unlinkSync14 } from "fs";
|
|
15523
|
-
import { basename as basename3, join as
|
|
15560
|
+
import { basename as basename3, join as join24 } from "path";
|
|
15524
15561
|
function cleanupSessionInboxFiles(userId, topicId, legacyTopicTitle) {
|
|
15525
15562
|
const live = sessionInboxPath(userId, topicId);
|
|
15526
15563
|
const scheduled = scheduledSessionInboxPath(userId, topicId);
|
|
15527
15564
|
const candidates = new Set([live, `${live}.processing`, scheduled, `${scheduled}.processing`]);
|
|
15528
15565
|
if (legacyTopicTitle && legacyTopicTitle !== "." && legacyTopicTitle !== ".." && basename3(legacyTopicTitle) === legacyTopicTitle) {
|
|
15529
|
-
const legacyBase =
|
|
15566
|
+
const legacyBase = join24(SESSION_INBOX_DIR, userId, legacyTopicTitle);
|
|
15530
15567
|
for (const suffix of [".jsonl", ".jsonl.processing", ".schedule", ".schedule.processing"]) {
|
|
15531
15568
|
candidates.add(`${legacyBase}${suffix}`);
|
|
15532
15569
|
}
|
|
@@ -15552,16 +15589,16 @@ var init_session_inbox_cleanup = __esm(() => {
|
|
|
15552
15589
|
|
|
15553
15590
|
// ../../packages/core/src/query/state.ts
|
|
15554
15591
|
import { mkdirSync as mkdirSync14, renameSync as renameSync7, unlinkSync as unlinkSync15, writeFileSync as writeFileSync12 } from "fs";
|
|
15555
|
-
import { basename as basename4, join as
|
|
15592
|
+
import { basename as basename4, join as join25 } from "path";
|
|
15556
15593
|
function createQueryStateStore(options) {
|
|
15557
15594
|
const sanitize = options.sanitizeTopicId ?? sanitizeId;
|
|
15558
|
-
const queryStateDirPath = (userId) =>
|
|
15559
|
-
const queryStateFile = (userId, topicId) =>
|
|
15595
|
+
const queryStateDirPath = (userId) => join25(options.usersLogDir, String(userId), "active-queries");
|
|
15596
|
+
const queryStateFile = (userId, topicId) => join25(queryStateDirPath(userId), `${sanitize(topicId)}.json`);
|
|
15560
15597
|
const legacyQueryStateFile = (userId, topicName) => {
|
|
15561
15598
|
if (!topicName || topicName === "." || topicName === ".." || basename4(topicName) !== topicName) {
|
|
15562
15599
|
return null;
|
|
15563
15600
|
}
|
|
15564
|
-
return
|
|
15601
|
+
return join25(queryStateDirPath(userId), `${topicName}.json`);
|
|
15565
15602
|
};
|
|
15566
15603
|
return {
|
|
15567
15604
|
write(userId, topicId, topicName, task) {
|
|
@@ -15722,29 +15759,29 @@ import {
|
|
|
15722
15759
|
unlinkSync as unlinkSync16,
|
|
15723
15760
|
writeFileSync as writeFileSync13
|
|
15724
15761
|
} from "fs";
|
|
15725
|
-
import { dirname as dirname14, join as
|
|
15762
|
+
import { dirname as dirname14, join as join26 } from "path";
|
|
15726
15763
|
function pendingAskDir(userId) {
|
|
15727
15764
|
const rawUserId = String(userId);
|
|
15728
15765
|
const safeUserId = /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${createHash6("sha256").update(rawUserId).digest("hex")}`;
|
|
15729
|
-
return
|
|
15766
|
+
return join26(resolveStorageSessionAsksDir(), safeUserId);
|
|
15730
15767
|
}
|
|
15731
15768
|
function encodeAskKey(key) {
|
|
15732
15769
|
return JSON.stringify([key.from, key.to]);
|
|
15733
15770
|
}
|
|
15734
15771
|
function pendingAskPath(key) {
|
|
15735
15772
|
const digest = createHash6("sha256").update(encodeAskKey(key)).digest("hex");
|
|
15736
|
-
return
|
|
15773
|
+
return join26(pendingAskDir(key.userId), `${ASK_FILENAME_PREFIX}${digest}.pending`);
|
|
15737
15774
|
}
|
|
15738
15775
|
function v2PendingAskPath(key) {
|
|
15739
15776
|
const encoded = Buffer.from(encodeAskKey(key), "utf8").toString("base64url");
|
|
15740
|
-
return
|
|
15777
|
+
return join26(pendingAskDir(key.userId), `${V2_ASK_FILENAME_PREFIX}${encoded}.pending`);
|
|
15741
15778
|
}
|
|
15742
15779
|
function legacyPendingAskPath(key) {
|
|
15743
15780
|
if (key.from.includes("/") || key.from.includes("\\") || key.to.includes("/") || key.to.includes("\\") || key.from.includes("\x00") || key.to.includes("\x00")) {
|
|
15744
15781
|
return null;
|
|
15745
15782
|
}
|
|
15746
15783
|
const dir = pendingAskDir(key.userId);
|
|
15747
|
-
const candidate =
|
|
15784
|
+
const candidate = join26(dir, `${key.from}___${key.to}.pending`);
|
|
15748
15785
|
return dirname14(candidate) === dir ? candidate : null;
|
|
15749
15786
|
}
|
|
15750
15787
|
function parsePendingAskFilename(fileName) {
|
|
@@ -15985,7 +16022,7 @@ function listPendingAsksForCaller(args) {
|
|
|
15985
16022
|
const parsed = isV3 ? { from: args.from, to: "" } : parsePendingAskFilename(fileName);
|
|
15986
16023
|
if (!parsed)
|
|
15987
16024
|
continue;
|
|
15988
|
-
const path =
|
|
16025
|
+
const path = join26(dir, fileName);
|
|
15989
16026
|
const record = readPendingAskFile(path, {
|
|
15990
16027
|
userId: args.userId,
|
|
15991
16028
|
from: parsed.from,
|
|
@@ -16027,7 +16064,7 @@ function deletePendingAsksForTopic(args) {
|
|
|
16027
16064
|
}
|
|
16028
16065
|
let deleted = 0;
|
|
16029
16066
|
for (const fileName of files) {
|
|
16030
|
-
const path =
|
|
16067
|
+
const path = join26(dir, fileName);
|
|
16031
16068
|
const parsed = parsePendingAskFilename(fileName);
|
|
16032
16069
|
const record = readPendingAskFile(path, {
|
|
16033
16070
|
userId: args.userId,
|
|
@@ -16445,7 +16482,7 @@ __export(exports_token_stats, {
|
|
|
16445
16482
|
});
|
|
16446
16483
|
import { createHash as createHash7 } from "crypto";
|
|
16447
16484
|
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync14 } from "fs";
|
|
16448
|
-
import { join as
|
|
16485
|
+
import { join as join27 } from "path";
|
|
16449
16486
|
function emptyBucket() {
|
|
16450
16487
|
return {
|
|
16451
16488
|
inputTokens: 0,
|
|
@@ -16464,7 +16501,7 @@ function queriesPath(userId) {
|
|
|
16464
16501
|
const fileId = tokenStatsFileId(userId);
|
|
16465
16502
|
const logDir = resolveStorageLogDir();
|
|
16466
16503
|
mkdirSync16(logDir, { recursive: true });
|
|
16467
|
-
return
|
|
16504
|
+
return join27(logDir, `token-queries-${fileId}.jsonl`);
|
|
16468
16505
|
}
|
|
16469
16506
|
function loadRecords(userId) {
|
|
16470
16507
|
try {
|
|
@@ -16893,7 +16930,7 @@ var init_lifecycle = __esm(async () => {
|
|
|
16893
16930
|
// ../../packages/core/src/runtime/attachments.ts
|
|
16894
16931
|
import { randomUUID as randomUUID14 } from "crypto";
|
|
16895
16932
|
import { copyFileSync as copyFileSync2, mkdirSync as mkdirSync17, writeFileSync as writeFileSync15 } from "fs";
|
|
16896
|
-
import { basename as basename5, join as
|
|
16933
|
+
import { basename as basename5, join as join28 } from "path";
|
|
16897
16934
|
function workspaceCwdFor(topicId) {
|
|
16898
16935
|
return resolveTopicWorkspaceDir(topicId);
|
|
16899
16936
|
}
|
|
@@ -16906,7 +16943,7 @@ function materializePromptAttachments(topicId, queryId, attachmentIds) {
|
|
|
16906
16943
|
if (!attachmentIds?.length)
|
|
16907
16944
|
return [];
|
|
16908
16945
|
const out = [];
|
|
16909
|
-
const destDir =
|
|
16946
|
+
const destDir = join28(workspaceCwdFor(topicId), "attachments", queryId);
|
|
16910
16947
|
for (const rawId of attachmentIds) {
|
|
16911
16948
|
if (typeof rawId !== "string")
|
|
16912
16949
|
continue;
|
|
@@ -16923,7 +16960,7 @@ function materializePromptAttachments(topicId, queryId, attachmentIds) {
|
|
|
16923
16960
|
mkdirSync17(destDir, { recursive: true });
|
|
16924
16961
|
const index = String(out.length + 1).padStart(2, "0");
|
|
16925
16962
|
const safeName = safeAttachmentFilename(attachment.filename, fileId);
|
|
16926
|
-
const destPath =
|
|
16963
|
+
const destPath = join28(destDir, `${index}-${fileId.slice(0, 8)}-${safeName}`);
|
|
16927
16964
|
copyFileSync2(sourcePath, destPath);
|
|
16928
16965
|
out.push({
|
|
16929
16966
|
id: attachment.id,
|
|
@@ -16953,10 +16990,10 @@ function promptWithAttachments(prompt, attachments) {
|
|
|
16953
16990
|
return composeAttachmentPrompt(prompt, attachments.map(({ filename, path }) => attachmentPromptLine(filename, path)));
|
|
16954
16991
|
}
|
|
16955
16992
|
function ingestAttachment(args) {
|
|
16956
|
-
const destDir =
|
|
16993
|
+
const destDir = join28(UPLOADS_DIR, args.topicId);
|
|
16957
16994
|
mkdirSync17(destDir, { recursive: true });
|
|
16958
16995
|
const safeName = safeAttachmentFilename(args.filename, "upload");
|
|
16959
|
-
const destPath =
|
|
16996
|
+
const destPath = join28(destDir, `${Date.now()}-${randomUUID14().slice(0, 8)}-${safeName}`);
|
|
16960
16997
|
if (args.sourcePath !== undefined) {
|
|
16961
16998
|
copyFileSync2(args.sourcePath, destPath);
|
|
16962
16999
|
} else if (args.bytes !== undefined) {
|
|
@@ -18267,9 +18304,9 @@ __export(exports_app_settings, {
|
|
|
18267
18304
|
DEFAULT_AI_NAME: () => DEFAULT_AI_NAME
|
|
18268
18305
|
});
|
|
18269
18306
|
import { existsSync as existsSync19, mkdirSync as mkdirSync18, readFileSync as readFileSync16, writeFileSync as writeFileSync16 } from "fs";
|
|
18270
|
-
import { dirname as dirname15, join as
|
|
18307
|
+
import { dirname as dirname15, join as join29 } from "path";
|
|
18271
18308
|
function settingsFile() {
|
|
18272
|
-
return
|
|
18309
|
+
return join29(resolveStorageDataDir(), "otium-settings.json");
|
|
18273
18310
|
}
|
|
18274
18311
|
function getGlobalAiName() {
|
|
18275
18312
|
const path = settingsFile();
|
|
@@ -18373,7 +18410,7 @@ __export(exports_turn_runner, {
|
|
|
18373
18410
|
});
|
|
18374
18411
|
import { randomUUID as randomUUID16 } from "crypto";
|
|
18375
18412
|
import { existsSync as existsSync20, mkdirSync as mkdirSync19, readdirSync as readdirSync6, statSync as statSync10 } from "fs";
|
|
18376
|
-
import { join as
|
|
18413
|
+
import { join as join30 } from "path";
|
|
18377
18414
|
function withDefaultPlaywright(configuredMcp, isManager) {
|
|
18378
18415
|
if (isManager)
|
|
18379
18416
|
return configuredMcp;
|
|
@@ -18428,7 +18465,7 @@ function appendAskReplyMessage(topicId, text2, agentType) {
|
|
|
18428
18465
|
return message;
|
|
18429
18466
|
}
|
|
18430
18467
|
function resolveWikiMirrorPath(directory, preferredFilename, matchesLegacyId, matchesTitle, preferExact = true) {
|
|
18431
|
-
const preferred =
|
|
18468
|
+
const preferred = join30(directory, preferredFilename);
|
|
18432
18469
|
if (preferExact && existsSync20(preferred))
|
|
18433
18470
|
return preferred;
|
|
18434
18471
|
let newestLegacyId = null;
|
|
@@ -18439,7 +18476,7 @@ function resolveWikiMirrorPath(directory, preferredFilename, matchesLegacyId, ma
|
|
|
18439
18476
|
const legacyIdMatch = !titleMatch && matchesLegacyId(filename);
|
|
18440
18477
|
if (!titleMatch && !legacyIdMatch)
|
|
18441
18478
|
continue;
|
|
18442
|
-
const path =
|
|
18479
|
+
const path = join30(directory, filename);
|
|
18443
18480
|
const mtimeMs = statSync10(path).mtimeMs;
|
|
18444
18481
|
if (titleMatch) {
|
|
18445
18482
|
if (!newestTitle || mtimeMs > newestTitle.mtimeMs) {
|
|
@@ -18453,9 +18490,9 @@ function resolveWikiMirrorPath(directory, preferredFilename, matchesLegacyId, ma
|
|
|
18453
18490
|
return newestTitle?.path ?? newestLegacyId?.path ?? preferred;
|
|
18454
18491
|
}
|
|
18455
18492
|
function resolveWikiMemoryMirror(wikiDir, topicId, topicTitle) {
|
|
18456
|
-
const briefFile = resolveWikiMirrorPath(
|
|
18493
|
+
const briefFile = resolveWikiMirrorPath(join30(wikiDir, "topic"), `${wikiBriefStorageKey(topicTitle, topicId)}.md`, (filename) => isTopicBriefFile(filename, topicId), (filename) => isTopicBriefFile(filename, topicId, topicTitle));
|
|
18457
18494
|
const hasBriefFile = existsSync20(briefFile) && statSync10(briefFile).isFile();
|
|
18458
|
-
const latestSummaryCandidate = resolveWikiMirrorPath(
|
|
18495
|
+
const latestSummaryCandidate = resolveWikiMirrorPath(join30(wikiDir, "summaries"), `__missing__-${wikiSummaryFilename("0000-00-00", topicTitle, topicId)}`, (filename) => isTopicSummaryFile(filename, topicId), (filename) => isTopicSummaryFile(filename, topicId, topicTitle), false);
|
|
18459
18496
|
const latestSummaryFile = existsSync20(latestSummaryCandidate) && statSync10(latestSummaryCandidate).isFile() ? latestSummaryCandidate : null;
|
|
18460
18497
|
return { briefFile, hasBriefFile, latestSummaryFile };
|
|
18461
18498
|
}
|
|
@@ -21205,7 +21242,7 @@ var init_vault_command = __esm(async () => {
|
|
|
21205
21242
|
import { execFile } from "child_process";
|
|
21206
21243
|
import { existsSync as existsSync21, mkdirSync as mkdirSync21, readFileSync as readFileSync17, rmSync as rmSync7 } from "fs";
|
|
21207
21244
|
import { readFile } from "fs/promises";
|
|
21208
|
-
import { extname, join as
|
|
21245
|
+
import { extname, join as join31 } from "path";
|
|
21209
21246
|
import { promisify } from "util";
|
|
21210
21247
|
async function extractText(filePath) {
|
|
21211
21248
|
const ext = extname(filePath).toLowerCase();
|
|
@@ -21322,7 +21359,7 @@ async function extractFromAudio(filePath, opts = {}) {
|
|
|
21322
21359
|
const tmpDir = `${filePath}_whisper_tmp`;
|
|
21323
21360
|
try {
|
|
21324
21361
|
mkdirSync21(tmpDir, { recursive: true });
|
|
21325
|
-
const mp3Path =
|
|
21362
|
+
const mp3Path = join31(tmpDir, "audio.mp3");
|
|
21326
21363
|
await execFileAsync(opts.ffmpegBin ?? FFMPEG_BIN2, [
|
|
21327
21364
|
"-y",
|
|
21328
21365
|
"-i",
|
|
@@ -21349,7 +21386,7 @@ async function extractFromAudio(filePath, opts = {}) {
|
|
|
21349
21386
|
"--output-format",
|
|
21350
21387
|
"txt"
|
|
21351
21388
|
], { timeout: 120000 });
|
|
21352
|
-
const txtPath =
|
|
21389
|
+
const txtPath = join31(tmpDir, "audio.txt");
|
|
21353
21390
|
const text2 = existsSync21(txtPath) ? readFileSync17(txtPath, "utf-8").trim() : null;
|
|
21354
21391
|
if (!text2) {
|
|
21355
21392
|
return { text: null, method: "whisper", error: "Whisper produced no text" };
|
|
@@ -21522,7 +21559,7 @@ var init_lifecycle2 = __esm(() => {
|
|
|
21522
21559
|
|
|
21523
21560
|
// ../../packages/core/src/platform/log-rotation.ts
|
|
21524
21561
|
import { existsSync as existsSync22, renameSync as renameSync8, statSync as statSync11 } from "fs";
|
|
21525
|
-
import { join as
|
|
21562
|
+
import { join as join32 } from "path";
|
|
21526
21563
|
function rotateOversizedLog(logPath, maxBytes = DEFAULT_DAEMON_LOG_ROTATE_BYTES) {
|
|
21527
21564
|
try {
|
|
21528
21565
|
if (!existsSync22(logPath))
|
|
@@ -21531,9 +21568,9 @@ function rotateOversizedLog(logPath, maxBytes = DEFAULT_DAEMON_LOG_ROTATE_BYTES)
|
|
|
21531
21568
|
if (size < maxBytes)
|
|
21532
21569
|
return;
|
|
21533
21570
|
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
21534
|
-
const dir =
|
|
21571
|
+
const dir = join32(logPath, "..");
|
|
21535
21572
|
const base = logPath.slice(dir.length + 1);
|
|
21536
|
-
renameSync8(logPath,
|
|
21573
|
+
renameSync8(logPath, join32(dir, `${base}.${stamp}`));
|
|
21537
21574
|
} catch {}
|
|
21538
21575
|
}
|
|
21539
21576
|
var DEFAULT_DAEMON_LOG_ROTATE_BYTES;
|
|
@@ -21726,7 +21763,7 @@ import {
|
|
|
21726
21763
|
rmSync as rmSync8,
|
|
21727
21764
|
statSync as statSync12
|
|
21728
21765
|
} from "fs";
|
|
21729
|
-
import { join as
|
|
21766
|
+
import { join as join33 } from "path";
|
|
21730
21767
|
function setBashrsCompletionSink(sink) {
|
|
21731
21768
|
completionSink = sink ?? defaultSink;
|
|
21732
21769
|
}
|
|
@@ -21753,15 +21790,15 @@ function readTail(filePath) {
|
|
|
21753
21790
|
}
|
|
21754
21791
|
}
|
|
21755
21792
|
function buildMessage(dir, result) {
|
|
21756
|
-
const stdout = readTail(
|
|
21757
|
-
const stderr = readTail(
|
|
21793
|
+
const stdout = readTail(join33(dir, "stdout.log"));
|
|
21794
|
+
const stderr = readTail(join33(dir, "stderr.log"));
|
|
21758
21795
|
const parts = [];
|
|
21759
21796
|
if (stdout.text.trim() || stdout.truncated) {
|
|
21760
|
-
parts.push(`stdout${stdout.truncated ? ` (truncated, full output: ${
|
|
21797
|
+
parts.push(`stdout${stdout.truncated ? ` (truncated, full output: ${join33(dir, "stdout.log")})` : ""}:
|
|
21761
21798
|
${stdout.text.trim()}`);
|
|
21762
21799
|
}
|
|
21763
21800
|
if (stderr.text.trim() || stderr.truncated) {
|
|
21764
|
-
parts.push(`stderr${stderr.truncated ? ` (truncated, full output: ${
|
|
21801
|
+
parts.push(`stderr${stderr.truncated ? ` (truncated, full output: ${join33(dir, "stderr.log")})` : ""}:
|
|
21765
21802
|
${stderr.text.trim()}`);
|
|
21766
21803
|
}
|
|
21767
21804
|
const header = watchHeader(result) ?? `[background_bash ${result.bash_id} finished]`;
|
|
@@ -21795,7 +21832,7 @@ function parseOwner(owner) {
|
|
|
21795
21832
|
return { userId, topicId };
|
|
21796
21833
|
}
|
|
21797
21834
|
function injectedMarker(dir) {
|
|
21798
|
-
return
|
|
21835
|
+
return join33(dir, "result.json.injected");
|
|
21799
21836
|
}
|
|
21800
21837
|
async function flushBashrsCompletions() {
|
|
21801
21838
|
let entries;
|
|
@@ -21806,8 +21843,8 @@ async function flushBashrsCompletions() {
|
|
|
21806
21843
|
}
|
|
21807
21844
|
const now = Date.now();
|
|
21808
21845
|
for (const bashId of entries) {
|
|
21809
|
-
const dir =
|
|
21810
|
-
const resultPath =
|
|
21846
|
+
const dir = join33(BASHRS_SPILL_ROOT, bashId);
|
|
21847
|
+
const resultPath = join33(dir, "result.json");
|
|
21811
21848
|
const marker = injectedMarker(dir);
|
|
21812
21849
|
try {
|
|
21813
21850
|
const markerStat = statSync12(marker);
|
|
@@ -22105,7 +22142,7 @@ var init_file_ops = __esm(() => {
|
|
|
22105
22142
|
// ../../packages/core/src/runtime/inbox.ts
|
|
22106
22143
|
import { createHash as createHash9, randomUUID as randomUUID20 } from "crypto";
|
|
22107
22144
|
import { readdirSync as readdirSync8, statSync as statSync13, writeFileSync as writeFileSync17 } from "fs";
|
|
22108
|
-
import { join as
|
|
22145
|
+
import { join as join34 } from "path";
|
|
22109
22146
|
async function createAskForkPlan(options) {
|
|
22110
22147
|
const snapshot = structuredClone(options.entries);
|
|
22111
22148
|
const prepareSession = async () => options.synthesize(structuredClone(snapshot));
|
|
@@ -22245,7 +22282,7 @@ async function flushSessionInbox() {
|
|
|
22245
22282
|
return;
|
|
22246
22283
|
}
|
|
22247
22284
|
for (const uid of userDirs) {
|
|
22248
|
-
const userInboxDir =
|
|
22285
|
+
const userInboxDir = join34(SESSION_INBOX_DIR, uid);
|
|
22249
22286
|
let entries;
|
|
22250
22287
|
try {
|
|
22251
22288
|
entries = readdirSync8(userInboxDir);
|
|
@@ -22253,7 +22290,7 @@ async function flushSessionInbox() {
|
|
|
22253
22290
|
continue;
|
|
22254
22291
|
}
|
|
22255
22292
|
for (const entry of entries) {
|
|
22256
|
-
const entryPath =
|
|
22293
|
+
const entryPath = join34(userInboxDir, entry);
|
|
22257
22294
|
let isDir = false;
|
|
22258
22295
|
try {
|
|
22259
22296
|
isDir = statSync13(entryPath).isDirectory();
|
|
@@ -22343,7 +22380,7 @@ function sweepScheduledSessionInbox(nowMs = Date.now()) {
|
|
|
22343
22380
|
return;
|
|
22344
22381
|
}
|
|
22345
22382
|
for (const userId of userDirs) {
|
|
22346
|
-
const userInboxDir =
|
|
22383
|
+
const userInboxDir = join34(SESSION_INBOX_DIR, userId);
|
|
22347
22384
|
let files;
|
|
22348
22385
|
try {
|
|
22349
22386
|
files = readdirSync8(userInboxDir);
|
|
@@ -22355,7 +22392,7 @@ function sweepScheduledSessionInbox(nowMs = Date.now()) {
|
|
|
22355
22392
|
const topicId = topicIdFromScheduledSessionInboxFileName(file);
|
|
22356
22393
|
if (!topicId)
|
|
22357
22394
|
continue;
|
|
22358
|
-
const schedulePath =
|
|
22395
|
+
const schedulePath = join34(userInboxDir, file);
|
|
22359
22396
|
const hasProcessingClaim = files.includes(`${file}.processing`);
|
|
22360
22397
|
if (!hasProcessingClaim && !scheduledFileNeedsClaim(schedulePath, nowMs))
|
|
22361
22398
|
continue;
|
|
@@ -23192,7 +23229,7 @@ var init_src = __esm(async () => {
|
|
|
23192
23229
|
|
|
23193
23230
|
// ../../packages/core/src/storage/conversation-migration.ts
|
|
23194
23231
|
import { copyFileSync as copyFileSync3, existsSync as existsSync24, mkdirSync as mkdirSync23, readFileSync as readFileSync20 } from "fs";
|
|
23195
|
-
import { dirname as dirname16, join as
|
|
23232
|
+
import { dirname as dirname16, join as join35 } from "path";
|
|
23196
23233
|
function readEntries(path) {
|
|
23197
23234
|
const entries = [];
|
|
23198
23235
|
for (const [index, line] of readFileSync20(path, "utf8").split(`
|
|
@@ -23259,7 +23296,7 @@ function migrateLegacyCompactedConversations() {
|
|
|
23259
23296
|
result.skipped++;
|
|
23260
23297
|
continue;
|
|
23261
23298
|
}
|
|
23262
|
-
const backupPath =
|
|
23299
|
+
const backupPath = join35(resolveStorageDataDir(), "conversation-migration-backups", MIGRATION_NAME, userId, `${sanitizeTopicName(topic.title, true)}.jsonl`);
|
|
23263
23300
|
const sourcePath = existsSync24(backupPath) ? backupPath : rawPath;
|
|
23264
23301
|
const legacyEntries = readEntries(sourcePath);
|
|
23265
23302
|
const compactIndex = compactionEntryIndex(legacyEntries);
|
|
@@ -23319,7 +23356,7 @@ __export(exports_decisions, {
|
|
|
23319
23356
|
DECISION_STATUS_VALUES: () => DECISION_STATUS_VALUES
|
|
23320
23357
|
});
|
|
23321
23358
|
import { existsSync as existsSync25, mkdirSync as mkdirSync24, readFileSync as readFileSync21, renameSync as renameSync11, writeFileSync as writeFileSync18 } from "fs";
|
|
23322
|
-
import { dirname as dirname17, join as
|
|
23359
|
+
import { dirname as dirname17, join as join36 } from "path";
|
|
23323
23360
|
function safeDecisionScopeKey(scopeKey) {
|
|
23324
23361
|
const safe = sanitizeFileName(scopeKey);
|
|
23325
23362
|
if (!safe || safe === "." || safe === "..") {
|
|
@@ -23331,10 +23368,10 @@ function decisionScopeKey(opts) {
|
|
|
23331
23368
|
return opts.topicId?.trim() || opts.session || "default";
|
|
23332
23369
|
}
|
|
23333
23370
|
function getDecisionFilePath(userId, scopeKey) {
|
|
23334
|
-
return
|
|
23371
|
+
return join36(resolveStorageDataDir(), "decisions", `${safeDecisionScopeKey(scopeKey)}.json`);
|
|
23335
23372
|
}
|
|
23336
23373
|
function getDecisionGraphSvgPath(userId, scopeKey) {
|
|
23337
|
-
return
|
|
23374
|
+
return join36(resolveStorageDataDir(), "decision-renders", safeDecisionScopeKey(scopeKey), "latest.svg");
|
|
23338
23375
|
}
|
|
23339
23376
|
function writeDecisionGraphSvg(userId, scopeKey, svg) {
|
|
23340
23377
|
const path = getDecisionGraphSvgPath(userId, scopeKey);
|
|
@@ -24594,7 +24631,7 @@ __export(exports_agent_health, {
|
|
|
24594
24631
|
});
|
|
24595
24632
|
import { spawn as spawn6 } from "child_process";
|
|
24596
24633
|
import { existsSync as existsSync27, readdirSync as readdirSync9 } from "fs";
|
|
24597
|
-
import { join as
|
|
24634
|
+
import { join as join37 } from "path";
|
|
24598
24635
|
import { McpServer as McpServer5 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
24599
24636
|
import { z as z10 } from "zod";
|
|
24600
24637
|
function signalProcessTree2(child, signal) {
|
|
@@ -24838,7 +24875,7 @@ ${results.every((result) => result.ok) ? "All agents healthy" : "Some agents fai
|
|
|
24838
24875
|
server.tool("list_active_queries", "\uD604\uC7AC \uC0AC\uC6A9\uC790 \uBC94\uC704\uC5D0\uC11C \uC2E4\uD589 \uC911\uC778 \uD1A0\uD53D \uCFFC\uB9AC \uBAA9\uB85D\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4.", {}, async () => {
|
|
24839
24876
|
if (!context.userId)
|
|
24840
24877
|
return mcpOk("\uC2E4\uD589 \uC911\uC778 \uCFFC\uB9AC \uC870\uD68C \uBD88\uAC00 (user context \uC5C6\uC74C)");
|
|
24841
|
-
const stateDir =
|
|
24878
|
+
const stateDir = join37(USERS_LOG_DIR, context.userId, "active-queries");
|
|
24842
24879
|
if (!existsSync27(stateDir))
|
|
24843
24880
|
return mcpOk("\uC2E4\uD589 \uC911\uC778 \uCFFC\uB9AC \uC5C6\uC74C");
|
|
24844
24881
|
let files;
|
|
@@ -24851,7 +24888,7 @@ ${results.every((result) => result.ok) ? "All agents healthy" : "Some agents fai
|
|
|
24851
24888
|
const entries = files.flatMap((file) => {
|
|
24852
24889
|
if (!file.endsWith(".json"))
|
|
24853
24890
|
return [];
|
|
24854
|
-
const state = readJsonFile(
|
|
24891
|
+
const state = readJsonFile(join37(stateDir, file));
|
|
24855
24892
|
if (!state)
|
|
24856
24893
|
return [];
|
|
24857
24894
|
const sinceMs = new Date(state.since).getTime();
|
|
@@ -25084,7 +25121,7 @@ var exports_default_host = {};
|
|
|
25084
25121
|
__export(exports_default_host, {
|
|
25085
25122
|
createDefaultSessionCommMcpHost: () => createDefaultSessionCommMcpHost
|
|
25086
25123
|
});
|
|
25087
|
-
import { basename as basename6, join as
|
|
25124
|
+
import { basename as basename6, join as join38 } from "path";
|
|
25088
25125
|
function ok2(text2) {
|
|
25089
25126
|
return { content: [{ type: "text", text: text2 }] };
|
|
25090
25127
|
}
|
|
@@ -25131,10 +25168,10 @@ function remoteTarget(context, to) {
|
|
|
25131
25168
|
return { node: to.slice(0, slash), topic: to.slice(slash + 1) };
|
|
25132
25169
|
}
|
|
25133
25170
|
function activeQuery(context, topicId, title) {
|
|
25134
|
-
const dir =
|
|
25135
|
-
const candidates = [
|
|
25171
|
+
const dir = join38(USERS_LOG_DIR, context.userId, "active-queries");
|
|
25172
|
+
const candidates = [join38(dir, `${sanitizeId(topicId)}.json`)];
|
|
25136
25173
|
if (title && basename6(title) === title && title !== "." && title !== "..") {
|
|
25137
|
-
candidates.push(
|
|
25174
|
+
candidates.push(join38(dir, `${title}.json`));
|
|
25138
25175
|
}
|
|
25139
25176
|
for (const path of candidates) {
|
|
25140
25177
|
const state = readJsonFile(path);
|
|
@@ -25683,7 +25720,7 @@ import {
|
|
|
25683
25720
|
unlinkSync as unlinkSync19,
|
|
25684
25721
|
writeFileSync as writeFileSync19
|
|
25685
25722
|
} from "fs";
|
|
25686
|
-
import { basename as basename7, dirname as dirname18, join as
|
|
25723
|
+
import { basename as basename7, dirname as dirname18, join as join39, relative as relative2, resolve as resolve18 } from "path";
|
|
25687
25724
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
25688
25725
|
import { StdioServerTransport as StdioServerTransport2 } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
25689
25726
|
import {
|
|
@@ -26133,13 +26170,13 @@ function wikiQuery(args) {
|
|
|
26133
26170
|
try {
|
|
26134
26171
|
for (const entry of readdirSync10(dir, { withFileTypes: true })) {
|
|
26135
26172
|
if (entry.isDirectory()) {
|
|
26136
|
-
const sub =
|
|
26173
|
+
const sub = join39(dir, entry.name);
|
|
26137
26174
|
if (label === "articles" || label === "skills") {
|
|
26138
26175
|
try {
|
|
26139
26176
|
for (const f of readdirSync10(sub, { withFileTypes: true })) {
|
|
26140
26177
|
if (!f.isFile() || !f.name.endsWith(".md"))
|
|
26141
26178
|
continue;
|
|
26142
|
-
const fp =
|
|
26179
|
+
const fp = join39(sub, f.name);
|
|
26143
26180
|
try {
|
|
26144
26181
|
const text2 = readFileSync24(fp, "utf-8");
|
|
26145
26182
|
const key = `${entry.name}/${f.name.replace(/\.md$/i, "")}`;
|
|
@@ -26160,7 +26197,7 @@ function wikiQuery(args) {
|
|
|
26160
26197
|
if (label === "topic" && canReadTopicMemory && !canReadTopicMemory(entry.name.replace(/\.md$/i, ""), runtime().userId)) {
|
|
26161
26198
|
continue;
|
|
26162
26199
|
}
|
|
26163
|
-
const fp =
|
|
26200
|
+
const fp = join39(dir, entry.name);
|
|
26164
26201
|
try {
|
|
26165
26202
|
const text2 = readFileSync24(fp, "utf-8");
|
|
26166
26203
|
const key = entry.name.replace(/\.md$/i, "");
|
|
@@ -26881,21 +26918,21 @@ function collectIndexableDocuments() {
|
|
|
26881
26918
|
}
|
|
26882
26919
|
for (const entry of entries) {
|
|
26883
26920
|
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
26884
|
-
add(kind, entry.name.replace(/\.md$/i, ""),
|
|
26921
|
+
add(kind, entry.name.replace(/\.md$/i, ""), join39(root, entry.name));
|
|
26885
26922
|
continue;
|
|
26886
26923
|
}
|
|
26887
26924
|
if (!entry.isDirectory() || !allowSubdirectories)
|
|
26888
26925
|
continue;
|
|
26889
26926
|
let nested;
|
|
26890
26927
|
try {
|
|
26891
|
-
nested = readdirSync10(
|
|
26928
|
+
nested = readdirSync10(join39(root, entry.name), { withFileTypes: true });
|
|
26892
26929
|
} catch {
|
|
26893
26930
|
continue;
|
|
26894
26931
|
}
|
|
26895
26932
|
for (const file of nested) {
|
|
26896
26933
|
if (!file.isFile() || !file.name.endsWith(".md"))
|
|
26897
26934
|
continue;
|
|
26898
|
-
add(kind, `${entry.name}/${file.name.replace(/\.md$/i, "")}`,
|
|
26935
|
+
add(kind, `${entry.name}/${file.name.replace(/\.md$/i, "")}`, join39(root, entry.name, file.name));
|
|
26899
26936
|
}
|
|
26900
26937
|
}
|
|
26901
26938
|
}
|
|
@@ -27404,7 +27441,7 @@ import {
|
|
|
27404
27441
|
unlinkSync as unlinkSync20,
|
|
27405
27442
|
writeFileSync as writeFileSync20
|
|
27406
27443
|
} from "fs";
|
|
27407
|
-
import { basename as basename8, join as
|
|
27444
|
+
import { basename as basename8, join as join40 } from "path";
|
|
27408
27445
|
function startLogRotation() {
|
|
27409
27446
|
if (rotationTimer)
|
|
27410
27447
|
return;
|
|
@@ -27418,7 +27455,7 @@ function writeLog(entry) {
|
|
|
27418
27455
|
mkdirSync26(logDir, { recursive: true });
|
|
27419
27456
|
const safeSession = sanitizeTopicName(entry.session);
|
|
27420
27457
|
const sidShort = entry.sessionId ? entry.sessionId.slice(0, 8) : "new";
|
|
27421
|
-
const file =
|
|
27458
|
+
const file = join40(logDir, `${entry.userId}_${safeSession}_${sidShort}.jsonl`);
|
|
27422
27459
|
try {
|
|
27423
27460
|
const stat = statSync16(file);
|
|
27424
27461
|
if (stat.size >= MAX_FILE_SIZE) {
|
|
@@ -27438,7 +27475,7 @@ function rotateOldLogs() {
|
|
|
27438
27475
|
try {
|
|
27439
27476
|
const files = readdirSync11(logDir).filter((f) => f.endsWith(".jsonl")).map((f) => {
|
|
27440
27477
|
try {
|
|
27441
|
-
const stat = statSync16(
|
|
27478
|
+
const stat = statSync16(join40(logDir, f));
|
|
27442
27479
|
return { name: f, size: stat.size, mtimeMs: stat.mtimeMs };
|
|
27443
27480
|
} catch {
|
|
27444
27481
|
return null;
|
|
@@ -27454,7 +27491,7 @@ function rotateOldLogs() {
|
|
|
27454
27491
|
if (freed >= toFree)
|
|
27455
27492
|
break;
|
|
27456
27493
|
try {
|
|
27457
|
-
unlinkSync20(
|
|
27494
|
+
unlinkSync20(join40(logDir, file.name));
|
|
27458
27495
|
freed += file.size;
|
|
27459
27496
|
logger.info({ file: file.name, sizeKB: (file.size / 1024).toFixed(0) }, "Rotated out old log");
|
|
27460
27497
|
} catch (e) {
|
|
@@ -27466,9 +27503,9 @@ function rotateOldLogs() {
|
|
|
27466
27503
|
}
|
|
27467
27504
|
}
|
|
27468
27505
|
function writeSentFileLog(entry) {
|
|
27469
|
-
const dir =
|
|
27506
|
+
const dir = join40(resolveStorageUsersLogDir(), String(entry.userId));
|
|
27470
27507
|
mkdirSync26(dir, { recursive: true });
|
|
27471
|
-
const file =
|
|
27508
|
+
const file = join40(dir, "sent-files.jsonl");
|
|
27472
27509
|
try {
|
|
27473
27510
|
appendJsonlEntry(file, { ...entry, fileName: basename8(entry.filePath) });
|
|
27474
27511
|
} catch (e) {
|
|
@@ -27479,7 +27516,7 @@ function entryMatchesTopic(e, topicName) {
|
|
|
27479
27516
|
return e.topicName === topicName;
|
|
27480
27517
|
}
|
|
27481
27518
|
function readSentFilesForTopic(userId, topicName) {
|
|
27482
|
-
const file =
|
|
27519
|
+
const file = join40(resolveStorageUsersLogDir(), String(userId), "sent-files.jsonl");
|
|
27483
27520
|
if (!existsSync30(file))
|
|
27484
27521
|
return [];
|
|
27485
27522
|
try {
|
|
@@ -27490,7 +27527,7 @@ function readSentFilesForTopic(userId, topicName) {
|
|
|
27490
27527
|
}
|
|
27491
27528
|
}
|
|
27492
27529
|
function removeSentFilesForTopic(userId, topicName) {
|
|
27493
|
-
const file =
|
|
27530
|
+
const file = join40(resolveStorageUsersLogDir(), String(userId), "sent-files.jsonl");
|
|
27494
27531
|
if (!existsSync30(file))
|
|
27495
27532
|
return;
|
|
27496
27533
|
try {
|
|
@@ -28977,11 +29014,11 @@ var init_src2 = __esm(async () => {
|
|
|
28977
29014
|
});
|
|
28978
29015
|
|
|
28979
29016
|
// ../../packages/mcp-host/src/paths.ts
|
|
28980
|
-
import { homedir as
|
|
29017
|
+
import { homedir as homedir10 } from "os";
|
|
28981
29018
|
import { resolve as resolve21 } from "path";
|
|
28982
29019
|
function stateDir() {
|
|
28983
29020
|
const env = process.env.NEGOTIUM_STATE_DIR?.trim();
|
|
28984
|
-
return env ? resolve21(env) : resolve21(
|
|
29021
|
+
return env ? resolve21(env) : resolve21(homedir10(), ".negotium");
|
|
28985
29022
|
}
|
|
28986
29023
|
function defaultPortsDir() {
|
|
28987
29024
|
return resolve21(stateDir(), "run", "mcp-ports");
|
|
@@ -29134,7 +29171,7 @@ import {
|
|
|
29134
29171
|
writeFileSync as writeFileSync22
|
|
29135
29172
|
} from "fs";
|
|
29136
29173
|
import { connect, createServer as createServer4 } from "net";
|
|
29137
|
-
import { join as
|
|
29174
|
+
import { join as join41 } from "path";
|
|
29138
29175
|
function regKey(key, instanceKey) {
|
|
29139
29176
|
return `${key}\x00${instanceKey}`;
|
|
29140
29177
|
}
|
|
@@ -29436,7 +29473,7 @@ class McpHost {
|
|
|
29436
29473
|
if (file.includes(".tmp-"))
|
|
29437
29474
|
continue;
|
|
29438
29475
|
try {
|
|
29439
|
-
const port = Number.parseInt(readFileSync26(
|
|
29476
|
+
const port = Number.parseInt(readFileSync26(join41(this.portsDir, file), "utf8").trim(), 10);
|
|
29440
29477
|
if (!Number.isNaN(port))
|
|
29441
29478
|
claims.set(file, port);
|
|
29442
29479
|
} catch {}
|
|
@@ -29446,7 +29483,7 @@ class McpHost {
|
|
|
29446
29483
|
writePortFile(fileName, port) {
|
|
29447
29484
|
try {
|
|
29448
29485
|
mkdirSync28(this.portsDir, { recursive: true });
|
|
29449
|
-
const file =
|
|
29486
|
+
const file = join41(this.portsDir, fileName);
|
|
29450
29487
|
const tmp = `${file}.tmp-${process.pid}`;
|
|
29451
29488
|
writeFileSync22(tmp, String(port));
|
|
29452
29489
|
renameSync15(tmp, file);
|
|
@@ -29456,7 +29493,7 @@ class McpHost {
|
|
|
29456
29493
|
}
|
|
29457
29494
|
deletePortFile(fileName) {
|
|
29458
29495
|
try {
|
|
29459
|
-
unlinkSync21(
|
|
29496
|
+
unlinkSync21(join41(this.portsDir, fileName));
|
|
29460
29497
|
} catch {}
|
|
29461
29498
|
}
|
|
29462
29499
|
cleanupRunning(rkey, inst) {
|
|
@@ -29568,7 +29605,7 @@ import {
|
|
|
29568
29605
|
statSync as statSync18,
|
|
29569
29606
|
writeFileSync as writeFileSync23
|
|
29570
29607
|
} from "fs";
|
|
29571
|
-
import { basename as basename10, extname as extname4, join as
|
|
29608
|
+
import { basename as basename10, extname as extname4, join as join42 } from "path";
|
|
29572
29609
|
function safeExtension(filename) {
|
|
29573
29610
|
const extension = extname4(basename10(filename));
|
|
29574
29611
|
return /^\.[A-Za-z0-9]{1,16}$/.test(extension) ? extension.toLowerCase() : "";
|
|
@@ -29586,14 +29623,14 @@ function contentDisposition(filename) {
|
|
|
29586
29623
|
|
|
29587
29624
|
class NodeFileStore {
|
|
29588
29625
|
uploadDir;
|
|
29589
|
-
constructor(uploadDir =
|
|
29626
|
+
constructor(uploadDir = join42(DATA_DIR, "uploads")) {
|
|
29590
29627
|
this.uploadDir = uploadDir;
|
|
29591
29628
|
}
|
|
29592
29629
|
#ensureDir() {
|
|
29593
29630
|
mkdirSync29(this.uploadDir, { recursive: true });
|
|
29594
29631
|
}
|
|
29595
29632
|
#metadataPath(fileId) {
|
|
29596
|
-
return
|
|
29633
|
+
return join42(this.uploadDir, `${fileId}.meta.json`);
|
|
29597
29634
|
}
|
|
29598
29635
|
#metadata(fileId) {
|
|
29599
29636
|
if (!FILE_ID_RE.test(fileId))
|
|
@@ -29622,7 +29659,7 @@ class NodeFileStore {
|
|
|
29622
29659
|
hooks = {
|
|
29623
29660
|
resolveAttachmentByFileId: (fileId) => {
|
|
29624
29661
|
const metadata = this.#metadata(fileId);
|
|
29625
|
-
if (!metadata || !existsSync32(
|
|
29662
|
+
if (!metadata || !existsSync32(join42(this.uploadDir, metadata.savedName)))
|
|
29626
29663
|
return null;
|
|
29627
29664
|
return this.#attachment(fileId, metadata);
|
|
29628
29665
|
},
|
|
@@ -29630,7 +29667,7 @@ class NodeFileStore {
|
|
|
29630
29667
|
const metadata = this.#metadata(fileId);
|
|
29631
29668
|
if (!metadata)
|
|
29632
29669
|
return null;
|
|
29633
|
-
const path =
|
|
29670
|
+
const path = join42(this.uploadDir, metadata.savedName);
|
|
29634
29671
|
return existsSync32(path) ? path : null;
|
|
29635
29672
|
},
|
|
29636
29673
|
storeLocalFileAsUpload: (absPath, access = {}) => this.store(absPath, access),
|
|
@@ -29645,11 +29682,11 @@ class NodeFileStore {
|
|
|
29645
29682
|
const mimeType = file.type || MIME_BY_EXT2[extension] || "application/octet-stream";
|
|
29646
29683
|
const existing = this.#metadata(fileId);
|
|
29647
29684
|
if (existing) {
|
|
29648
|
-
const matches = existing.filename === filename && existing.mimeType === mimeType && existing.sizeBytes === file.size && existing.ownerUserId === access.ownerUserId && existing.topicId === access.topicId && existsSync32(
|
|
29685
|
+
const matches = existing.filename === filename && existing.mimeType === mimeType && existing.sizeBytes === file.size && existing.ownerUserId === access.ownerUserId && existing.topicId === access.topicId && existsSync32(join42(this.uploadDir, existing.savedName));
|
|
29649
29686
|
return matches ? this.#attachment(fileId, existing) : null;
|
|
29650
29687
|
}
|
|
29651
29688
|
const savedName = `${fileId}${extension}`;
|
|
29652
|
-
const savedPath =
|
|
29689
|
+
const savedPath = join42(this.uploadDir, savedName);
|
|
29653
29690
|
try {
|
|
29654
29691
|
const sizeBytes = await Bun.write(savedPath, file);
|
|
29655
29692
|
if (sizeBytes !== file.size)
|
|
@@ -29674,14 +29711,14 @@ class NodeFileStore {
|
|
|
29674
29711
|
}
|
|
29675
29712
|
allows(fileId, access) {
|
|
29676
29713
|
const metadata = this.#metadata(fileId);
|
|
29677
|
-
return Boolean(metadata && metadata.ownerUserId === access.ownerUserId && metadata.topicId === access.topicId && existsSync32(
|
|
29714
|
+
return Boolean(metadata && metadata.ownerUserId === access.ownerUserId && metadata.topicId === access.topicId && existsSync32(join42(this.uploadDir, metadata.savedName)));
|
|
29678
29715
|
}
|
|
29679
29716
|
store(absPath, access = {}) {
|
|
29680
29717
|
this.#ensureDir();
|
|
29681
29718
|
const fileId = randomUUID24();
|
|
29682
29719
|
const extension = safeExtension(absPath);
|
|
29683
29720
|
const savedName = `${fileId}${extension}`;
|
|
29684
|
-
const savedPath =
|
|
29721
|
+
const savedPath = join42(this.uploadDir, savedName);
|
|
29685
29722
|
try {
|
|
29686
29723
|
const stats = statSync18(absPath);
|
|
29687
29724
|
if (!stats.isFile() || stats.size > MAX_NODE_UPLOAD_BYTES)
|
|
@@ -29713,7 +29750,7 @@ class NodeFileStore {
|
|
|
29713
29750
|
const allowed = metadata.visibility === "workspace" || metadata.ownerUserId === userId || Boolean(topic && isParticipant(topic, userId));
|
|
29714
29751
|
if (!allowed)
|
|
29715
29752
|
return null;
|
|
29716
|
-
const path =
|
|
29753
|
+
const path = join42(this.uploadDir, metadata.savedName);
|
|
29717
29754
|
if (!existsSync32(path))
|
|
29718
29755
|
return null;
|
|
29719
29756
|
return new Response(Bun.file(path), {
|
|
@@ -29732,7 +29769,7 @@ class NodeFileStore {
|
|
|
29732
29769
|
const metadata = this.#metadata(fileId);
|
|
29733
29770
|
if (metadata?.topicId !== topicId)
|
|
29734
29771
|
continue;
|
|
29735
|
-
rmSync9(
|
|
29772
|
+
rmSync9(join42(this.uploadDir, metadata.savedName), { force: true });
|
|
29736
29773
|
rmSync9(this.#metadataPath(fileId), { force: true });
|
|
29737
29774
|
}
|
|
29738
29775
|
}
|
|
@@ -33855,8 +33892,8 @@ var init_context_usage = __esm(async () => {
|
|
|
33855
33892
|
// ../../adapters/terminal/src/path-suggest.ts
|
|
33856
33893
|
import { execFile as execFile3 } from "child_process";
|
|
33857
33894
|
import { existsSync as existsSync36, readdirSync as readdirSync14, statSync as statSync19 } from "fs";
|
|
33858
|
-
import { homedir as
|
|
33859
|
-
import { basename as basename11, dirname as dirname21, join as
|
|
33895
|
+
import { homedir as homedir11 } from "os";
|
|
33896
|
+
import { basename as basename11, dirname as dirname21, join as join43, sep as sep3 } from "path";
|
|
33860
33897
|
import { promisify as promisify3 } from "util";
|
|
33861
33898
|
function indexRecursivePaths(files) {
|
|
33862
33899
|
const paths = [];
|
|
@@ -33950,25 +33987,25 @@ function activeAtToken(lineText, col) {
|
|
|
33950
33987
|
return { start: col - frag.length - 1, frag };
|
|
33951
33988
|
}
|
|
33952
33989
|
function resolveFragment(frag) {
|
|
33953
|
-
const home =
|
|
33990
|
+
const home = homedir11();
|
|
33954
33991
|
let path;
|
|
33955
33992
|
if (frag === "" || frag === "~")
|
|
33956
33993
|
path = home;
|
|
33957
33994
|
else if (frag === "~/")
|
|
33958
33995
|
path = home;
|
|
33959
33996
|
else if (frag.startsWith("~/"))
|
|
33960
|
-
path =
|
|
33997
|
+
path = join43(home, frag.slice(2));
|
|
33961
33998
|
else if (frag.startsWith("/"))
|
|
33962
33999
|
path = frag;
|
|
33963
34000
|
else
|
|
33964
|
-
path =
|
|
34001
|
+
path = join43(home, frag);
|
|
33965
34002
|
if (frag.endsWith("/") || frag === "" || frag === "~") {
|
|
33966
34003
|
return { dir: path, prefix: "" };
|
|
33967
34004
|
}
|
|
33968
34005
|
return { dir: dirname21(path), prefix: basename11(path) };
|
|
33969
34006
|
}
|
|
33970
34007
|
function toToken(fullPath, isDir) {
|
|
33971
|
-
const home =
|
|
34008
|
+
const home = homedir11();
|
|
33972
34009
|
let shown = fullPath;
|
|
33973
34010
|
if (fullPath === home)
|
|
33974
34011
|
shown = "~";
|
|
@@ -33990,7 +34027,7 @@ function rankAndSlice(dir, candidates) {
|
|
|
33990
34027
|
});
|
|
33991
34028
|
return candidates.slice(0, MAX_SUGGESTIONS).map(({ relPath, isDir }) => ({
|
|
33992
34029
|
label: `${relPath}${isDir ? "/" : ""}`,
|
|
33993
|
-
value: toToken(
|
|
34030
|
+
value: toToken(join43(dir, relPath), isDir),
|
|
33994
34031
|
isDir
|
|
33995
34032
|
}));
|
|
33996
34033
|
}
|
|
@@ -34069,7 +34106,7 @@ function pathSuggestions(lineText, col) {
|
|
|
34069
34106
|
let isDir = entry.isDirectory();
|
|
34070
34107
|
if (!isDir && entry.isSymbolicLink()) {
|
|
34071
34108
|
try {
|
|
34072
|
-
isDir = statSync19(
|
|
34109
|
+
isDir = statSync19(join43(dir, entry.name)).isDirectory();
|
|
34073
34110
|
} catch {}
|
|
34074
34111
|
}
|
|
34075
34112
|
return {
|
|
@@ -34092,14 +34129,14 @@ function pathSuggestions(lineText, col) {
|
|
|
34092
34129
|
};
|
|
34093
34130
|
}
|
|
34094
34131
|
function fragmentToAbsolutePath(frag) {
|
|
34095
|
-
const home =
|
|
34132
|
+
const home = homedir11();
|
|
34096
34133
|
if (frag === "~" || frag === "~/")
|
|
34097
34134
|
return home;
|
|
34098
34135
|
if (frag.startsWith("~/"))
|
|
34099
|
-
return
|
|
34136
|
+
return join43(home, frag.slice(2));
|
|
34100
34137
|
if (frag.startsWith("/"))
|
|
34101
34138
|
return frag;
|
|
34102
|
-
return
|
|
34139
|
+
return join43(home, frag);
|
|
34103
34140
|
}
|
|
34104
34141
|
function fragmentResolves(frag) {
|
|
34105
34142
|
try {
|
|
@@ -40605,7 +40642,7 @@ var init_commands2 = __esm(async () => {
|
|
|
40605
40642
|
// ../../adapters/telegram/src/mapping-store.ts
|
|
40606
40643
|
import { Database as Database2 } from "bun:sqlite";
|
|
40607
40644
|
import { mkdirSync as mkdirSync32 } from "fs";
|
|
40608
|
-
import { dirname as dirname22, join as
|
|
40645
|
+
import { dirname as dirname22, join as join44 } from "path";
|
|
40609
40646
|
function outboxRowToEntry(row) {
|
|
40610
40647
|
return {
|
|
40611
40648
|
id: row.id,
|
|
@@ -40671,7 +40708,7 @@ function migrateOutboxSchema(db4) {
|
|
|
40671
40708
|
db4.run("CREATE INDEX IF NOT EXISTS idx_telegram_outbox_runtime_message ON outbox(runtime_message_id)");
|
|
40672
40709
|
}
|
|
40673
40710
|
function openMappingStore(path) {
|
|
40674
|
-
const dbPath = path ??
|
|
40711
|
+
const dbPath = path ?? join44(DATA_DIR, "adapter-telegram.db");
|
|
40675
40712
|
if (dbPath !== ":memory:")
|
|
40676
40713
|
mkdirSync32(dirname22(dbPath), { recursive: true });
|
|
40677
40714
|
const db4 = new Database2(dbPath);
|
|
@@ -42571,9 +42608,9 @@ function firstCell() {
|
|
|
42571
42608
|
return cell;
|
|
42572
42609
|
return null;
|
|
42573
42610
|
}
|
|
42574
|
-
function attachOtiumCentralCell(
|
|
42575
|
-
cells.set(
|
|
42576
|
-
join:
|
|
42611
|
+
function attachOtiumCentralCell(join45) {
|
|
42612
|
+
cells.set(join45.cellId, {
|
|
42613
|
+
join: join45,
|
|
42577
42614
|
nodesCache: null,
|
|
42578
42615
|
verifyCache: new Map,
|
|
42579
42616
|
tokenCache: new Map
|
|
@@ -42585,10 +42622,10 @@ function detachOtiumCentralCell(cellId) {
|
|
|
42585
42622
|
function attachedOtiumCells() {
|
|
42586
42623
|
return [...cells.values()].map((cell) => cell.join);
|
|
42587
42624
|
}
|
|
42588
|
-
function configureOtiumCentral(
|
|
42625
|
+
function configureOtiumCentral(join45) {
|
|
42589
42626
|
cells.clear();
|
|
42590
|
-
if (
|
|
42591
|
-
attachOtiumCentralCell(
|
|
42627
|
+
if (join45)
|
|
42628
|
+
attachOtiumCentralCell(join45);
|
|
42592
42629
|
}
|
|
42593
42630
|
function isOtiumCentralConfigured() {
|
|
42594
42631
|
return cells.size > 0;
|
|
@@ -43152,17 +43189,17 @@ function withJoinCredentialLock(operation) {
|
|
|
43152
43189
|
function joinsEqual(left, right) {
|
|
43153
43190
|
return left.central === right.central && left.relay === right.relay && left.cellId === right.cellId && left.secret === right.secret;
|
|
43154
43191
|
}
|
|
43155
|
-
function normalizedJoin(
|
|
43192
|
+
function normalizedJoin(join45) {
|
|
43156
43193
|
return normalizeJoin({
|
|
43157
|
-
v:
|
|
43158
|
-
central:
|
|
43159
|
-
relay:
|
|
43160
|
-
cellId:
|
|
43161
|
-
secret:
|
|
43194
|
+
v: join45.v,
|
|
43195
|
+
central: join45.central,
|
|
43196
|
+
relay: join45.relay,
|
|
43197
|
+
cellId: join45.cellId,
|
|
43198
|
+
secret: join45.secret
|
|
43162
43199
|
});
|
|
43163
43200
|
}
|
|
43164
|
-
function joinCredentialDigest(
|
|
43165
|
-
return createHash11("sha256").update(JSON.stringify(normalizedJoin(
|
|
43201
|
+
function joinCredentialDigest(join45) {
|
|
43202
|
+
return createHash11("sha256").update(JSON.stringify(normalizedJoin(join45))).digest("base64url");
|
|
43166
43203
|
}
|
|
43167
43204
|
function readPersistedJoins(path = joinFilePath()) {
|
|
43168
43205
|
if (!existsSync39(path))
|
|
@@ -43181,9 +43218,9 @@ function readPersistedJoins(path = joinFilePath()) {
|
|
|
43181
43218
|
return normalizeJoin(entry);
|
|
43182
43219
|
});
|
|
43183
43220
|
}
|
|
43184
|
-
function isJoinPersisted(
|
|
43221
|
+
function isJoinPersisted(join45) {
|
|
43185
43222
|
try {
|
|
43186
|
-
const normalized = normalizedJoin(
|
|
43223
|
+
const normalized = normalizedJoin(join45);
|
|
43187
43224
|
return readPersistedJoins().some((persisted) => joinsEqual(persisted, normalized));
|
|
43188
43225
|
} catch {
|
|
43189
43226
|
return false;
|
|
@@ -43227,10 +43264,10 @@ function writeJoins(joins, allowOverwrite) {
|
|
|
43227
43264
|
}
|
|
43228
43265
|
return path;
|
|
43229
43266
|
}
|
|
43230
|
-
function saveJoinWhileLocked(
|
|
43267
|
+
function saveJoinWhileLocked(join45, options = {}) {
|
|
43231
43268
|
const path = joinFilePath();
|
|
43232
43269
|
const directory = dirname23(path);
|
|
43233
|
-
const normalized = normalizedJoin(
|
|
43270
|
+
const normalized = normalizedJoin(join45);
|
|
43234
43271
|
mkdirSync33(directory, { recursive: true });
|
|
43235
43272
|
if (!existsSync39(path))
|
|
43236
43273
|
return writeJoins([normalized], false);
|
|
@@ -43260,8 +43297,8 @@ function saveJoinWhileLocked(join44, options = {}) {
|
|
|
43260
43297
|
const next = conflict ? existing.map((persisted) => persisted.cellId === normalized.cellId ? normalized : persisted) : [...existing, normalized];
|
|
43261
43298
|
return writeJoins(next, true);
|
|
43262
43299
|
}
|
|
43263
|
-
function saveJoin(
|
|
43264
|
-
return withJoinCredentialLock(() => saveJoinWhileLocked(
|
|
43300
|
+
function saveJoin(join45, options = {}) {
|
|
43301
|
+
return withJoinCredentialLock(() => saveJoinWhileLocked(join45, options));
|
|
43265
43302
|
}
|
|
43266
43303
|
function removeJoin(cellId) {
|
|
43267
43304
|
return withJoinCredentialLock(() => {
|
|
@@ -43274,7 +43311,7 @@ function removeJoin(cellId) {
|
|
|
43274
43311
|
if (cellId) {
|
|
43275
43312
|
let remaining;
|
|
43276
43313
|
try {
|
|
43277
|
-
remaining = readPersistedJoins(path).filter((
|
|
43314
|
+
remaining = readPersistedJoins(path).filter((join45) => join45.cellId !== cellId);
|
|
43278
43315
|
} catch {
|
|
43279
43316
|
return false;
|
|
43280
43317
|
}
|
|
@@ -43327,7 +43364,7 @@ var init_join = __esm(async () => {
|
|
|
43327
43364
|
// ../../adapters/otium/src/peer-files.ts
|
|
43328
43365
|
import { randomUUID as randomUUID29 } from "crypto";
|
|
43329
43366
|
import { copyFileSync as copyFileSync5, mkdirSync as mkdirSync34, rmSync as rmSync11, statSync as statSync21 } from "fs";
|
|
43330
|
-
import { basename as basename13, extname as extname6, join as
|
|
43367
|
+
import { basename as basename13, extname as extname6, join as join45 } from "path";
|
|
43331
43368
|
function fileType(mimeType) {
|
|
43332
43369
|
if (mimeType.startsWith("image/"))
|
|
43333
43370
|
return "image";
|
|
@@ -43393,7 +43430,7 @@ function recordFile(args) {
|
|
|
43393
43430
|
function insertLocalFile(args) {
|
|
43394
43431
|
const id = randomUUID29();
|
|
43395
43432
|
mkdirSync34(PEER_FILES_DIR, { recursive: true });
|
|
43396
|
-
const path =
|
|
43433
|
+
const path = join45(PEER_FILES_DIR, `${id}-${safeFilename(args.filename)}`);
|
|
43397
43434
|
copyFileSync5(args.sourcePath, path);
|
|
43398
43435
|
return recordFile({ id, path, sizeBytes: statSync21(path).size, ...args });
|
|
43399
43436
|
}
|
|
@@ -43439,7 +43476,7 @@ function installPeerFileHooks() {
|
|
|
43439
43476
|
var PEER_FILES_DIR;
|
|
43440
43477
|
var init_peer_files = __esm(async () => {
|
|
43441
43478
|
await init_src();
|
|
43442
|
-
PEER_FILES_DIR =
|
|
43479
|
+
PEER_FILES_DIR = join45(DATA_DIR, "otium-peer-files");
|
|
43443
43480
|
db.exec(`
|
|
43444
43481
|
CREATE TABLE IF NOT EXISTS otium_peer_files (
|
|
43445
43482
|
id TEXT PRIMARY KEY,
|
|
@@ -43851,19 +43888,19 @@ function readCache() {
|
|
|
43851
43888
|
return {};
|
|
43852
43889
|
}
|
|
43853
43890
|
}
|
|
43854
|
-
function cachedSurfaceScope(
|
|
43855
|
-
const record = readCache()[
|
|
43856
|
-
if (!record || record.central !==
|
|
43891
|
+
function cachedSurfaceScope(join46) {
|
|
43892
|
+
const record = readCache()[join46.cellId];
|
|
43893
|
+
if (!record || record.central !== join46.central || !record.workspaceId)
|
|
43857
43894
|
return null;
|
|
43858
43895
|
return surfaceScopeFor(record.central, record.workspaceId);
|
|
43859
43896
|
}
|
|
43860
|
-
function cacheSurfaceScope(
|
|
43861
|
-
const scope = surfaceScopeFor(
|
|
43897
|
+
function cacheSurfaceScope(join46, workspaceId) {
|
|
43898
|
+
const scope = surfaceScopeFor(join46.central, workspaceId);
|
|
43862
43899
|
const path = scopeCachePath();
|
|
43863
43900
|
try {
|
|
43864
43901
|
mkdirSync35(dirname24(path), { recursive: true });
|
|
43865
43902
|
const cache = readCache();
|
|
43866
|
-
cache[
|
|
43903
|
+
cache[join46.cellId] = { central: join46.central, workspaceId, scope };
|
|
43867
43904
|
writeFileSync26(path, `${JSON.stringify(cache, null, 2)}
|
|
43868
43905
|
`, { mode: 384 });
|
|
43869
43906
|
} catch (err2) {
|
|
@@ -43871,23 +43908,23 @@ function cacheSurfaceScope(join45, workspaceId) {
|
|
|
43871
43908
|
}
|
|
43872
43909
|
return scope;
|
|
43873
43910
|
}
|
|
43874
|
-
async function resolveSurfaceScope(
|
|
43875
|
-
const cached = cachedSurfaceScope(
|
|
43911
|
+
async function resolveSurfaceScope(join46) {
|
|
43912
|
+
const cached = cachedSurfaceScope(join46);
|
|
43876
43913
|
if (cached)
|
|
43877
43914
|
return cached;
|
|
43878
43915
|
try {
|
|
43879
|
-
const workspaceId = await peerWorkspaceIdForCell(
|
|
43916
|
+
const workspaceId = await peerWorkspaceIdForCell(join46.cellId);
|
|
43880
43917
|
if (!workspaceId)
|
|
43881
43918
|
return null;
|
|
43882
|
-
return cacheSurfaceScope(
|
|
43919
|
+
return cacheSurfaceScope(join46, workspaceId);
|
|
43883
43920
|
} catch (err2) {
|
|
43884
43921
|
logger.warn({ err: err2 }, "otium: workspace scope unresolved (will retry on the next contact)");
|
|
43885
43922
|
return null;
|
|
43886
43923
|
}
|
|
43887
43924
|
}
|
|
43888
43925
|
function surfaceScopeForCell(cellId) {
|
|
43889
|
-
const
|
|
43890
|
-
return
|
|
43926
|
+
const join46 = attachedOtiumCells().find((candidate) => candidate.cellId === cellId);
|
|
43927
|
+
return join46 ? cachedSurfaceScope(join46) : null;
|
|
43891
43928
|
}
|
|
43892
43929
|
function unscopedRoomsAddressable() {
|
|
43893
43930
|
return attachedOtiumCells().length < 2;
|
|
@@ -45020,13 +45057,13 @@ function replacePendingEnrollment(pending2) {
|
|
|
45020
45057
|
throw error2;
|
|
45021
45058
|
}
|
|
45022
45059
|
}
|
|
45023
|
-
function recordClaimedCredential(pending2,
|
|
45060
|
+
function recordClaimedCredential(pending2, join46) {
|
|
45024
45061
|
withJoinCredentialLock(() => {
|
|
45025
45062
|
const current3 = JSON.parse(readFileSync31(pendingEnrollmentPath(), "utf8"));
|
|
45026
45063
|
if (current3.central !== pending2.central || current3.token !== pending2.token || current3.idempotencyKey !== pending2.idempotencyKey || current3.publicKey !== pending2.publicKey) {
|
|
45027
45064
|
throw new Error("pending Otium enrollment changed while its claim was in flight");
|
|
45028
45065
|
}
|
|
45029
|
-
const claimed = { digest: joinCredentialDigest(
|
|
45066
|
+
const claimed = { digest: joinCredentialDigest(join46), cellId: join46.cellId };
|
|
45030
45067
|
if (current3.claimed && (current3.claimed.digest !== claimed.digest || current3.claimed.cellId !== claimed.cellId)) {
|
|
45031
45068
|
throw new Error("central returned different credentials for an idempotent enrollment claim");
|
|
45032
45069
|
}
|
|
@@ -45084,30 +45121,30 @@ async function claimEnrollment(invite, nodeName) {
|
|
|
45084
45121
|
const secret = openCredential(credential, pending2.privateKey);
|
|
45085
45122
|
if (!secret.startsWith("rcs_"))
|
|
45086
45123
|
throw new Error("central returned an invalid runtime credential");
|
|
45087
|
-
const
|
|
45124
|
+
const join46 = {
|
|
45088
45125
|
v: 2,
|
|
45089
45126
|
central: invite.central,
|
|
45090
45127
|
relay: String(response.relayUrl),
|
|
45091
45128
|
cellId: String(response.cell?.id),
|
|
45092
45129
|
secret
|
|
45093
45130
|
};
|
|
45094
|
-
if (!
|
|
45131
|
+
if (!join46.relay || !join46.cellId || join46.cellId === "undefined") {
|
|
45095
45132
|
throw new Error("central returned an incomplete enrollment response");
|
|
45096
45133
|
}
|
|
45097
|
-
assertSecureRelayUrl(
|
|
45098
|
-
recordClaimedCredential(pending2,
|
|
45099
|
-
return
|
|
45134
|
+
assertSecureRelayUrl(join46.relay);
|
|
45135
|
+
recordClaimedCredential(pending2, join46);
|
|
45136
|
+
return join46;
|
|
45100
45137
|
}
|
|
45101
|
-
function commitEnrollment(
|
|
45138
|
+
function commitEnrollment(join46, options = {}) {
|
|
45102
45139
|
return withJoinCredentialLock(() => {
|
|
45103
45140
|
const pendingPath = pendingEnrollmentPath();
|
|
45104
45141
|
const pending2 = existsSync40(pendingPath) ? JSON.parse(readFileSync31(pendingPath, "utf8")) : null;
|
|
45105
|
-
const digest = joinCredentialDigest(
|
|
45106
|
-
if (pending2 && (!pending2.claimed || pending2.claimed.digest !== digest || pending2.claimed.cellId !==
|
|
45142
|
+
const digest = joinCredentialDigest(join46);
|
|
45143
|
+
if (pending2 && (!pending2.claimed || pending2.claimed.digest !== digest || pending2.claimed.cellId !== join46.cellId)) {
|
|
45107
45144
|
throw new Error(`pending Otium enrollment at ${pendingPath} does not match these credentials`);
|
|
45108
45145
|
}
|
|
45109
|
-
const path = saveJoinWhileLocked(
|
|
45110
|
-
if (!isJoinPersisted(
|
|
45146
|
+
const path = saveJoinWhileLocked(join46, options);
|
|
45147
|
+
if (!isJoinPersisted(join46)) {
|
|
45111
45148
|
throw new Error("Otium join credentials were not durably persisted");
|
|
45112
45149
|
}
|
|
45113
45150
|
if (!pending2)
|
|
@@ -45701,24 +45738,24 @@ function refreshDefaultSurfaceScope() {
|
|
|
45701
45738
|
setSurfaceScopeRequired(scopes.length > 1);
|
|
45702
45739
|
}
|
|
45703
45740
|
function startOtiumNodeRuntime(options) {
|
|
45704
|
-
const { join:
|
|
45705
|
-
attachOtiumCentralCell(
|
|
45741
|
+
const { join: join46 } = options;
|
|
45742
|
+
attachOtiumCentralCell(join46);
|
|
45706
45743
|
const releaseGlobals = acquireGlobalOtiumServices();
|
|
45707
45744
|
let stopped = false;
|
|
45708
|
-
logger.info({ central:
|
|
45709
|
-
mountedScopes.set(
|
|
45745
|
+
logger.info({ central: join46.central, cellId: join46.cellId }, "otium: worker mode enabled");
|
|
45746
|
+
mountedScopes.set(join46.cellId, cachedSurfaceScope(join46));
|
|
45710
45747
|
refreshDefaultSurfaceScope();
|
|
45711
|
-
selfPeerNodeForCell(
|
|
45748
|
+
selfPeerNodeForCell(join46.cellId).then((self) => {
|
|
45712
45749
|
if (self) {
|
|
45713
45750
|
logger.info({ nodeName: self.nodeName, baseUrl: self.baseUrl }, "otium: attached to workspace");
|
|
45714
45751
|
}
|
|
45715
45752
|
}).catch((err2) => {
|
|
45716
45753
|
logger.warn({ err: err2 }, "otium: self check against central failed (will retry per request)");
|
|
45717
45754
|
});
|
|
45718
|
-
resolveSurfaceScope(
|
|
45755
|
+
resolveSurfaceScope(join46).then((scope) => {
|
|
45719
45756
|
if (!scope || stopped)
|
|
45720
45757
|
return;
|
|
45721
|
-
mountedScopes.set(
|
|
45758
|
+
mountedScopes.set(join46.cellId, scope);
|
|
45722
45759
|
refreshDefaultSurfaceScope();
|
|
45723
45760
|
if (mountedScopes.size === 1)
|
|
45724
45761
|
stampUnscopedOtiumTopics(scope);
|
|
@@ -45727,14 +45764,14 @@ function startOtiumNodeRuntime(options) {
|
|
|
45727
45764
|
});
|
|
45728
45765
|
return {
|
|
45729
45766
|
name: "otium",
|
|
45730
|
-
join:
|
|
45767
|
+
join: join46,
|
|
45731
45768
|
stop: () => {
|
|
45732
45769
|
if (stopped)
|
|
45733
45770
|
return;
|
|
45734
45771
|
stopped = true;
|
|
45735
|
-
mountedScopes.delete(
|
|
45772
|
+
mountedScopes.delete(join46.cellId);
|
|
45736
45773
|
refreshDefaultSurfaceScope();
|
|
45737
|
-
detachOtiumCentralCell(
|
|
45774
|
+
detachOtiumCentralCell(join46.cellId);
|
|
45738
45775
|
releaseGlobals();
|
|
45739
45776
|
}
|
|
45740
45777
|
};
|
|
@@ -45829,14 +45866,14 @@ __export(exports_node_runtime, {
|
|
|
45829
45866
|
function sameCredentials(left, right) {
|
|
45830
45867
|
return left.central === right.central && left.relay === right.relay && left.secret === right.secret;
|
|
45831
45868
|
}
|
|
45832
|
-
function attachOtiumWorkspace(
|
|
45833
|
-
const current3 = mounted.get(
|
|
45869
|
+
function attachOtiumWorkspace(join46) {
|
|
45870
|
+
const current3 = mounted.get(join46.cellId);
|
|
45834
45871
|
if (current3) {
|
|
45835
|
-
if (sameCredentials(current3.join,
|
|
45872
|
+
if (sameCredentials(current3.join, join46))
|
|
45836
45873
|
return false;
|
|
45837
|
-
detachOtiumWorkspace(
|
|
45874
|
+
detachOtiumWorkspace(join46.cellId);
|
|
45838
45875
|
}
|
|
45839
|
-
mounted.set(
|
|
45876
|
+
mounted.set(join46.cellId, startOtiumNodeRuntime({ join: join46 }));
|
|
45840
45877
|
return true;
|
|
45841
45878
|
}
|
|
45842
45879
|
function detachOtiumWorkspace(cellId) {
|
|
@@ -45851,7 +45888,7 @@ function mountedOtiumWorkspaces() {
|
|
|
45851
45888
|
return [...mounted.values()].map((runtime2) => runtime2.join);
|
|
45852
45889
|
}
|
|
45853
45890
|
function reconcileOtiumWorkspaces(joins = loadJoins()) {
|
|
45854
|
-
const wanted = new Map(joins.map((
|
|
45891
|
+
const wanted = new Map(joins.map((join46) => [join46.cellId, join46]));
|
|
45855
45892
|
const detached = [];
|
|
45856
45893
|
for (const cellId of [...mounted.keys()]) {
|
|
45857
45894
|
if (wanted.has(cellId))
|
|
@@ -45860,8 +45897,8 @@ function reconcileOtiumWorkspaces(joins = loadJoins()) {
|
|
|
45860
45897
|
detached.push(cellId);
|
|
45861
45898
|
}
|
|
45862
45899
|
const attached = [];
|
|
45863
|
-
for (const [cellId,
|
|
45864
|
-
if (attachOtiumWorkspace(
|
|
45900
|
+
for (const [cellId, join46] of wanted) {
|
|
45901
|
+
if (attachOtiumWorkspace(join46))
|
|
45865
45902
|
attached.push(cellId);
|
|
45866
45903
|
}
|
|
45867
45904
|
if (attached.length > 0 || detached.length > 0) {
|
|
@@ -45884,9 +45921,9 @@ async function handleOtiumAdapterControlRequest(req) {
|
|
|
45884
45921
|
if (req.method === "GET") {
|
|
45885
45922
|
return Response.json({
|
|
45886
45923
|
ok: true,
|
|
45887
|
-
workspaces: mountedOtiumWorkspaces().map((
|
|
45888
|
-
cellId:
|
|
45889
|
-
central:
|
|
45924
|
+
workspaces: mountedOtiumWorkspaces().map((join46) => ({
|
|
45925
|
+
cellId: join46.cellId,
|
|
45926
|
+
central: join46.central
|
|
45890
45927
|
}))
|
|
45891
45928
|
});
|
|
45892
45929
|
}
|
|
@@ -45907,8 +45944,8 @@ function mountConfiguredOtiumNodeRuntime() {
|
|
|
45907
45944
|
const joins = loadJoins();
|
|
45908
45945
|
if (joins.length === 0)
|
|
45909
45946
|
return null;
|
|
45910
|
-
for (const
|
|
45911
|
-
attachOtiumWorkspace(
|
|
45947
|
+
for (const join46 of joins)
|
|
45948
|
+
attachOtiumWorkspace(join46);
|
|
45912
45949
|
registerNodeRequestHandler("otium-adapter-control", handleOtiumAdapterControlRequest);
|
|
45913
45950
|
let stopped = false;
|
|
45914
45951
|
return {
|
|
@@ -46020,11 +46057,11 @@ async function joinCommand(args) {
|
|
|
46020
46057
|
process.exitCode = 1;
|
|
46021
46058
|
return;
|
|
46022
46059
|
}
|
|
46023
|
-
let
|
|
46060
|
+
let join46;
|
|
46024
46061
|
let productionEnrollment = false;
|
|
46025
46062
|
if (args.includes("--legacy")) {
|
|
46026
46063
|
try {
|
|
46027
|
-
|
|
46064
|
+
join46 = parseInviteCode(code);
|
|
46028
46065
|
} catch (err2) {
|
|
46029
46066
|
console.error(`invalid legacy invite code: ${err2 instanceof Error ? err2.message : err2}`);
|
|
46030
46067
|
process.exitCode = 1;
|
|
@@ -46050,7 +46087,7 @@ async function joinCommand(args) {
|
|
|
46050
46087
|
return;
|
|
46051
46088
|
}
|
|
46052
46089
|
}
|
|
46053
|
-
|
|
46090
|
+
join46 = await claimEnrollment(invite, nodeName);
|
|
46054
46091
|
productionEnrollment = true;
|
|
46055
46092
|
} catch (err2) {
|
|
46056
46093
|
console.error(`enrollment failed: ${err2 instanceof Error ? err2.message : err2}`);
|
|
@@ -46061,16 +46098,16 @@ async function joinCommand(args) {
|
|
|
46061
46098
|
let path;
|
|
46062
46099
|
try {
|
|
46063
46100
|
const saveOptions = { replaceExisting: args.includes("--replace") };
|
|
46064
|
-
path = productionEnrollment ? commitEnrollment(
|
|
46101
|
+
path = productionEnrollment ? commitEnrollment(join46, saveOptions) : saveJoin(join46, saveOptions);
|
|
46065
46102
|
} catch (err2) {
|
|
46066
46103
|
console.error(`could not save join credentials: ${err2 instanceof Error ? err2.message : err2}`);
|
|
46067
46104
|
process.exitCode = 1;
|
|
46068
46105
|
return;
|
|
46069
46106
|
}
|
|
46070
46107
|
console.log(`otium join credentials saved to ${path}`);
|
|
46071
|
-
console.log(` central: ${
|
|
46072
|
-
console.log(` cellId: ${
|
|
46073
|
-
configureOtiumCentral(
|
|
46108
|
+
console.log(` central: ${join46.central}`);
|
|
46109
|
+
console.log(` cellId: ${join46.cellId}`);
|
|
46110
|
+
configureOtiumCentral(join46);
|
|
46074
46111
|
try {
|
|
46075
46112
|
const self = await selfPeerNode();
|
|
46076
46113
|
if (self) {
|
|
@@ -46112,19 +46149,19 @@ async function statusCommand() {
|
|
|
46112
46149
|
return;
|
|
46113
46150
|
}
|
|
46114
46151
|
configureOtiumCentral(joins[0] ?? null);
|
|
46115
|
-
for (const
|
|
46116
|
-
attachOtiumCentralCell(
|
|
46117
|
-
for (const [index,
|
|
46152
|
+
for (const join46 of joins.slice(1))
|
|
46153
|
+
attachOtiumCentralCell(join46);
|
|
46154
|
+
for (const [index, join46] of joins.entries()) {
|
|
46118
46155
|
if (index > 0)
|
|
46119
46156
|
console.log("");
|
|
46120
|
-
console.log(`cellId: ${
|
|
46121
|
-
console.log(`central: ${
|
|
46122
|
-
if (
|
|
46123
|
-
console.log(`relay: ${
|
|
46157
|
+
console.log(`cellId: ${join46.cellId}`);
|
|
46158
|
+
console.log(`central: ${join46.central}`);
|
|
46159
|
+
if (join46.relay)
|
|
46160
|
+
console.log(`relay: ${join46.relay}`);
|
|
46124
46161
|
try {
|
|
46125
|
-
const self = await selfPeerNodeForCell(
|
|
46162
|
+
const self = await selfPeerNodeForCell(join46.cellId);
|
|
46126
46163
|
if (self) {
|
|
46127
|
-
console.log(`node: ${self.nodeName ??
|
|
46164
|
+
console.log(`node: ${self.nodeName ?? join46.cellId}${self.isPrimary ? " (primary)" : ""}`);
|
|
46128
46165
|
console.log(`baseUrl: ${self.baseUrl}`);
|
|
46129
46166
|
} else {
|
|
46130
46167
|
console.warn(" warning: central answered but this cell has no visible assignment yet \u2014 check the workspace assignment");
|
|
@@ -46160,13 +46197,13 @@ function resolveTunnelTargets(joins, relayOverride) {
|
|
|
46160
46197
|
const targets = [];
|
|
46161
46198
|
const skippedNoRelay = [];
|
|
46162
46199
|
const envRelay = process.env.OTIUM_RELAY_URL?.trim();
|
|
46163
|
-
for (const
|
|
46164
|
-
const relayUrl = relayOverride?.trim() ||
|
|
46200
|
+
for (const join46 of joins) {
|
|
46201
|
+
const relayUrl = relayOverride?.trim() || join46.relay || envRelay;
|
|
46165
46202
|
if (!relayUrl) {
|
|
46166
|
-
skippedNoRelay.push(
|
|
46203
|
+
skippedNoRelay.push(join46.cellId);
|
|
46167
46204
|
continue;
|
|
46168
46205
|
}
|
|
46169
|
-
targets.push({ cellId:
|
|
46206
|
+
targets.push({ cellId: join46.cellId, relayUrl, secret: join46.secret });
|
|
46170
46207
|
}
|
|
46171
46208
|
return { targets, skippedNoRelay };
|
|
46172
46209
|
}
|
|
@@ -46403,9 +46440,9 @@ async function runOtiumCli(args = process.argv.slice(2)) {
|
|
|
46403
46440
|
if (joins.length === 0)
|
|
46404
46441
|
throw new Error("not joined to an Otium workspace");
|
|
46405
46442
|
if (!targetCellId && joins.length > 1) {
|
|
46406
|
-
throw new Error(`this node is joined to ${joins.length} workspaces; name one to leave: ${joins.map((
|
|
46443
|
+
throw new Error(`this node is joined to ${joins.length} workspaces; name one to leave: ${joins.map((join46) => join46.cellId).join(", ")}`);
|
|
46407
46444
|
}
|
|
46408
|
-
if (targetCellId && !joins.some((
|
|
46445
|
+
if (targetCellId && !joins.some((join46) => join46.cellId === targetCellId)) {
|
|
46409
46446
|
throw new Error(`not joined as ${targetCellId}`);
|
|
46410
46447
|
}
|
|
46411
46448
|
removeJoin2(targetCellId);
|
|
@@ -47192,4 +47229,4 @@ switch (command) {
|
|
|
47192
47229
|
}
|
|
47193
47230
|
}
|
|
47194
47231
|
|
|
47195
|
-
//# debugId=
|
|
47232
|
+
//# debugId=805E32726887103964756E2164756E21
|