negotium 0.4.4 → 0.4.6
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 +12 -7
- package/dist/agent-helpers.js.map +4 -4
- package/dist/{chunk-dttcv3n7.js → chunk-bzbxgbgg.js} +11 -5
- package/dist/{chunk-dttcv3n7.js.map → chunk-bzbxgbgg.js.map} +3 -3
- package/dist/hosted-agent.js +12 -6
- package/dist/hosted-agent.js.map +4 -4
- package/dist/main.js +78 -31
- package/dist/main.js.map +5 -5
- package/dist/mcp-factories.js +12 -7
- package/dist/mcp-factories.js.map +4 -4
- package/dist/registry.js +3 -3
- package/dist/registry.js.map +2 -2
- package/dist/rollout.js +1 -1
- package/dist/runtime/src/platform/mcp-config.ts +22 -5
- package/dist/runtime/src/version.ts +1 -1
- package/dist/types/packages/core/src/platform/mcp-config.d.ts +1 -1
- 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.6";
|
|
1873
1873
|
|
|
1874
1874
|
// ../../packages/core/src/agents/codex-native-multi-agent.ts
|
|
1875
1875
|
import { spawn } from "child_process";
|
|
@@ -2770,14 +2770,20 @@ function playwrightTransport(port, owner, capability, agent) {
|
|
|
2770
2770
|
function longLivedHttpMcp(agent, port) {
|
|
2771
2771
|
return agent === "codex" ? { url: `http://127.0.0.1:${port}/mcp` } : { type: "sse", url: `http://127.0.0.1:${port}/sse` };
|
|
2772
2772
|
}
|
|
2773
|
-
function setCuaRsMcpPort(port) {
|
|
2773
|
+
function setCuaRsMcpPort(port, token) {
|
|
2774
2774
|
if (port !== undefined && (!Number.isInteger(port) || port < 1 || port > 65535)) {
|
|
2775
2775
|
throw new Error(`invalid cua-rs MCP port: ${port}`);
|
|
2776
2776
|
}
|
|
2777
2777
|
cuaRsMcpPort = port;
|
|
2778
|
+
cuaRsMcpToken = port === undefined ? undefined : token;
|
|
2778
2779
|
}
|
|
2779
|
-
function cuaRsHttpMcp(port) {
|
|
2780
|
-
|
|
2780
|
+
function cuaRsHttpMcp(agent, port, token) {
|
|
2781
|
+
const url = `http://127.0.0.1:${port}/mcp`;
|
|
2782
|
+
const headers = token ? { Authorization: `Bearer ${token}` } : undefined;
|
|
2783
|
+
const base = { type: "http", url };
|
|
2784
|
+
if (!headers)
|
|
2785
|
+
return base;
|
|
2786
|
+
return agent === "codex" ? { ...base, http_headers: headers } : { ...base, headers };
|
|
2781
2787
|
}
|
|
2782
2788
|
function backgroundBashTransport(agent, port, userId, topic) {
|
|
2783
2789
|
const capability = bgBashContextCapability(userId, topic);
|
|
@@ -3054,7 +3060,7 @@ function getMcpServersForQuery(opts) {
|
|
|
3054
3060
|
peerBridge: opts.peerBridge
|
|
3055
3061
|
});
|
|
3056
3062
|
}
|
|
3057
|
-
var _playwrightUnavailableNotifier, _playwrightUnavailableLastNotifiedAt, _PLAYWRIGHT_UNAVAILABLE_COOLDOWN_MS, _playwrightUnavailableThisTurn, CODEX_BROWSER_CAPABILITY_ENV = "NEGOTIUM_BROWSER_CAPABILITY", cuaRsMcpPort, MCP_CATALOG, allForumMcpServerNames, requiredForumMcpServers, REQUIRED_FORUM_MCP_SERVERS, optionalForumMcpServers, OPTIONAL_FORUM_MCP_SERVERS, nodeMcpEntries;
|
|
3063
|
+
var _playwrightUnavailableNotifier, _playwrightUnavailableLastNotifiedAt, _PLAYWRIGHT_UNAVAILABLE_COOLDOWN_MS, _playwrightUnavailableThisTurn, CODEX_BROWSER_CAPABILITY_ENV = "NEGOTIUM_BROWSER_CAPABILITY", cuaRsMcpPort, cuaRsMcpToken, MCP_CATALOG, allForumMcpServerNames, requiredForumMcpServers, REQUIRED_FORUM_MCP_SERVERS, optionalForumMcpServers, OPTIONAL_FORUM_MCP_SERVERS, nodeMcpEntries;
|
|
3058
3064
|
var init_mcp_config = __esm(() => {
|
|
3059
3065
|
init_canonical_bridge_config();
|
|
3060
3066
|
init_runtime_spec();
|
|
@@ -3272,8 +3278,8 @@ var init_mcp_config = __esm(() => {
|
|
|
3272
3278
|
},
|
|
3273
3279
|
"cua-rs": {
|
|
3274
3280
|
...commonRuntimeMcpPolicy("cua-rs"),
|
|
3275
|
-
build() {
|
|
3276
|
-
return cuaRsMcpPort ? cuaRsHttpMcp(cuaRsMcpPort) : null;
|
|
3281
|
+
build({ agent }) {
|
|
3282
|
+
return cuaRsMcpPort ? cuaRsHttpMcp(agent, cuaRsMcpPort, cuaRsMcpToken) : null;
|
|
3277
3283
|
}
|
|
3278
3284
|
}
|
|
3279
3285
|
};
|
|
@@ -32618,7 +32624,8 @@ __export(exports_src3, {
|
|
|
32618
32624
|
NODE_CONTROL_PROTOCOL_VERSION: () => NODE_CONTROL_PROTOCOL_VERSION,
|
|
32619
32625
|
NODE_CONTROL_BASE_PATH: () => NODE_CONTROL_BASE_PATH
|
|
32620
32626
|
});
|
|
32621
|
-
import {
|
|
32627
|
+
import { randomBytes as randomBytes8 } from "crypto";
|
|
32628
|
+
import { readFileSync as readFileSync29, rmSync as rmSync10, writeFileSync as writeFileSync25 } from "fs";
|
|
32622
32629
|
import { createServer as createServer5 } from "net";
|
|
32623
32630
|
import { join as join43 } from "path";
|
|
32624
32631
|
async function availableLoopbackPort() {
|
|
@@ -32676,6 +32683,34 @@ async function wireNodeMcps(host2, manifest) {
|
|
|
32676
32683
|
logger.info({ keys: entries.map((e) => e.key) }, "node mcp: manifest servers installed");
|
|
32677
32684
|
}
|
|
32678
32685
|
}
|
|
32686
|
+
function cuaRsToken() {
|
|
32687
|
+
const file = join43(RUN_DIR, CUA_RS_MCP_TOKEN_FILE);
|
|
32688
|
+
try {
|
|
32689
|
+
const existing = readFileSync29(file, "utf8").trim();
|
|
32690
|
+
if (/^[0-9a-f]{64}$/.test(existing))
|
|
32691
|
+
return existing;
|
|
32692
|
+
} catch {}
|
|
32693
|
+
const token = randomBytes8(32).toString("hex");
|
|
32694
|
+
writeFileSync25(file, token, { mode: 384 });
|
|
32695
|
+
return token;
|
|
32696
|
+
}
|
|
32697
|
+
async function cuaRsAuthOk(port, token) {
|
|
32698
|
+
try {
|
|
32699
|
+
const res = await fetch(`http://127.0.0.1:${port}/mcp`, {
|
|
32700
|
+
method: "POST",
|
|
32701
|
+
headers: {
|
|
32702
|
+
Authorization: `Bearer ${token}`,
|
|
32703
|
+
"Content-Type": "application/json",
|
|
32704
|
+
Accept: "application/json, text/event-stream"
|
|
32705
|
+
},
|
|
32706
|
+
body: "{}",
|
|
32707
|
+
signal: AbortSignal.timeout(2000)
|
|
32708
|
+
});
|
|
32709
|
+
return res.status !== 401;
|
|
32710
|
+
} catch {
|
|
32711
|
+
return true;
|
|
32712
|
+
}
|
|
32713
|
+
}
|
|
32679
32714
|
async function wireCuaRsMcp() {
|
|
32680
32715
|
setCuaRsMcpPort(undefined);
|
|
32681
32716
|
const binary = resolveCuaRsBinary();
|
|
@@ -32684,11 +32719,13 @@ async function wireCuaRsMcp() {
|
|
|
32684
32719
|
const manifestFile = join43(RUN_DIR, CUA_RS_MCP_MANIFEST_FILE);
|
|
32685
32720
|
rmSync10(manifestFile, { force: true });
|
|
32686
32721
|
const manifest = new McpManifest({ file: manifestFile });
|
|
32722
|
+
const token = cuaRsToken();
|
|
32687
32723
|
const spec = {
|
|
32688
32724
|
key: CUA_RS_MCP_KEY,
|
|
32689
32725
|
transport: "http",
|
|
32690
32726
|
command: binary,
|
|
32691
32727
|
args: ["{port}"],
|
|
32728
|
+
env: { CUA_HTTP_TOKEN: token },
|
|
32692
32729
|
portRange: CUA_RS_MCP_PORT_RANGE,
|
|
32693
32730
|
scope: "node",
|
|
32694
32731
|
healthIntervalMs: 15000
|
|
@@ -32697,10 +32734,20 @@ async function wireCuaRsMcp() {
|
|
|
32697
32734
|
const host2 = new McpHost({ manifest });
|
|
32698
32735
|
const stopSweeper = host2.startSweeper();
|
|
32699
32736
|
try {
|
|
32700
|
-
|
|
32737
|
+
let instance = await host2.ensure(CUA_RS_MCP_KEY);
|
|
32701
32738
|
if (!instance.port)
|
|
32702
32739
|
throw new Error("cua-rs started without an HTTP port");
|
|
32703
|
-
|
|
32740
|
+
if (!await cuaRsAuthOk(instance.port, token)) {
|
|
32741
|
+
logger.warn({ port: instance.port }, "cua-rs rejected the node's token; restarting it");
|
|
32742
|
+
await host2.stop(CUA_RS_MCP_KEY);
|
|
32743
|
+
instance = await host2.ensure(CUA_RS_MCP_KEY);
|
|
32744
|
+
if (!instance.port)
|
|
32745
|
+
throw new Error("cua-rs restarted without an HTTP port");
|
|
32746
|
+
if (!await cuaRsAuthOk(instance.port, token)) {
|
|
32747
|
+
throw new Error("cua-rs will not accept the node's bearer token");
|
|
32748
|
+
}
|
|
32749
|
+
}
|
|
32750
|
+
setCuaRsMcpPort(instance.port, token);
|
|
32704
32751
|
logger.info({ pid: instance.pid, port: instance.port }, "cua-rs MCP server ready");
|
|
32705
32752
|
return { host: host2, stopSweeper };
|
|
32706
32753
|
} catch (error2) {
|
|
@@ -32909,7 +32956,7 @@ async function runNodeDaemon(opts = {}) {
|
|
|
32909
32956
|
await new Promise((resolve24) => setImmediate(resolve24));
|
|
32910
32957
|
process.exit(0);
|
|
32911
32958
|
}
|
|
32912
|
-
var CUA_RS_MCP_KEY = "cua-rs", CUA_RS_MCP_MANIFEST_FILE = "cua-rs-mcp-manifest.json", CUA_RS_MCP_PORT_RANGE;
|
|
32959
|
+
var CUA_RS_MCP_KEY = "cua-rs", CUA_RS_MCP_MANIFEST_FILE = "cua-rs-mcp-manifest.json", CUA_RS_MCP_TOKEN_FILE = "cua-rs-mcp.token", CUA_RS_MCP_PORT_RANGE;
|
|
32913
32960
|
var init_src5 = __esm(async () => {
|
|
32914
32961
|
await init_conversation_migration();
|
|
32915
32962
|
await init_node_host();
|
|
@@ -43108,12 +43155,12 @@ import {
|
|
|
43108
43155
|
lstatSync,
|
|
43109
43156
|
mkdirSync as mkdirSync33,
|
|
43110
43157
|
openSync as openSync5,
|
|
43111
|
-
readFileSync as
|
|
43158
|
+
readFileSync as readFileSync30,
|
|
43112
43159
|
renameSync as renameSync17,
|
|
43113
43160
|
rmSync as rmSync11,
|
|
43114
43161
|
statSync as statSync20,
|
|
43115
43162
|
unlinkSync as unlinkSync23,
|
|
43116
|
-
writeFileSync as
|
|
43163
|
+
writeFileSync as writeFileSync26
|
|
43117
43164
|
} from "fs";
|
|
43118
43165
|
import { dirname as dirname23, resolve as resolve25 } from "path";
|
|
43119
43166
|
function joinFilePath() {
|
|
@@ -43194,7 +43241,7 @@ function withJoinCredentialLock(operation) {
|
|
|
43194
43241
|
try {
|
|
43195
43242
|
mkdirSync33(lockPath, { mode: 448 });
|
|
43196
43243
|
created = true;
|
|
43197
|
-
|
|
43244
|
+
writeFileSync26(ownerPath, `${JSON.stringify(owner)}
|
|
43198
43245
|
`, { mode: 384 });
|
|
43199
43246
|
const ownerFd = openSync5(ownerPath, "r");
|
|
43200
43247
|
try {
|
|
@@ -43212,7 +43259,7 @@ function withJoinCredentialLock(operation) {
|
|
|
43212
43259
|
throw error2;
|
|
43213
43260
|
let current3 = null;
|
|
43214
43261
|
try {
|
|
43215
|
-
current3 = JSON.parse(
|
|
43262
|
+
current3 = JSON.parse(readFileSync30(ownerPath, "utf8"));
|
|
43216
43263
|
} catch {}
|
|
43217
43264
|
let ageMs;
|
|
43218
43265
|
try {
|
|
@@ -43242,7 +43289,7 @@ function withJoinCredentialLock(operation) {
|
|
|
43242
43289
|
return operation();
|
|
43243
43290
|
} finally {
|
|
43244
43291
|
try {
|
|
43245
|
-
const current3 = JSON.parse(
|
|
43292
|
+
const current3 = JSON.parse(readFileSync30(ownerPath, "utf8"));
|
|
43246
43293
|
if (current3.pid === owner.pid && current3.token === owner.token) {
|
|
43247
43294
|
rmSync11(lockPath, { recursive: true, force: true });
|
|
43248
43295
|
}
|
|
@@ -43267,7 +43314,7 @@ function joinCredentialDigest(join46) {
|
|
|
43267
43314
|
function readPersistedJoins(path = joinFilePath()) {
|
|
43268
43315
|
if (!existsSync39(path))
|
|
43269
43316
|
return [];
|
|
43270
|
-
const parsed = JSON.parse(
|
|
43317
|
+
const parsed = JSON.parse(readFileSync30(path, "utf-8"));
|
|
43271
43318
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
43272
43319
|
throw new Error("persisted join credentials are not a JSON object");
|
|
43273
43320
|
}
|
|
@@ -43305,7 +43352,7 @@ function writeJoins(joins, allowOverwrite) {
|
|
|
43305
43352
|
let fd;
|
|
43306
43353
|
try {
|
|
43307
43354
|
fd = openSync5(temporaryPath, "wx", 384);
|
|
43308
|
-
|
|
43355
|
+
writeFileSync26(fd, `${JSON.stringify(payload, null, 2)}
|
|
43309
43356
|
`, "utf8");
|
|
43310
43357
|
fsyncSync2(fd);
|
|
43311
43358
|
closeSync5(fd);
|
|
@@ -43931,7 +43978,7 @@ var init_store2 = __esm(async () => {
|
|
|
43931
43978
|
|
|
43932
43979
|
// ../../adapters/otium/src/workspace-scope.ts
|
|
43933
43980
|
import { createHash as createHash13 } from "crypto";
|
|
43934
|
-
import { mkdirSync as mkdirSync35, readFileSync as
|
|
43981
|
+
import { mkdirSync as mkdirSync35, readFileSync as readFileSync31, writeFileSync as writeFileSync27 } from "fs";
|
|
43935
43982
|
import { dirname as dirname24, resolve as resolve26 } from "path";
|
|
43936
43983
|
function surfaceScopeFor(central, workspaceId) {
|
|
43937
43984
|
const digest = createHash13("sha256").update(`${central.trim().replace(/\/+$/, "")}
|
|
@@ -43943,7 +43990,7 @@ function scopeCachePath() {
|
|
|
43943
43990
|
}
|
|
43944
43991
|
function readCache() {
|
|
43945
43992
|
try {
|
|
43946
|
-
const parsed = JSON.parse(
|
|
43993
|
+
const parsed = JSON.parse(readFileSync31(scopeCachePath(), "utf-8"));
|
|
43947
43994
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
43948
43995
|
return {};
|
|
43949
43996
|
return parsed;
|
|
@@ -43964,7 +44011,7 @@ function cacheSurfaceScope(join47, workspaceId) {
|
|
|
43964
44011
|
mkdirSync35(dirname24(path), { recursive: true });
|
|
43965
44012
|
const cache = readCache();
|
|
43966
44013
|
cache[join47.cellId] = { central: join47.central, workspaceId, scope };
|
|
43967
|
-
|
|
44014
|
+
writeFileSync27(path, `${JSON.stringify(cache, null, 2)}
|
|
43968
44015
|
`, { mode: 384 });
|
|
43969
44016
|
} catch (err2) {
|
|
43970
44017
|
logger.warn({ err: err2, path }, "otium: could not cache the workspace scope");
|
|
@@ -45005,10 +45052,10 @@ import {
|
|
|
45005
45052
|
linkSync as linkSync2,
|
|
45006
45053
|
mkdirSync as mkdirSync36,
|
|
45007
45054
|
openSync as openSync6,
|
|
45008
|
-
readFileSync as
|
|
45055
|
+
readFileSync as readFileSync32,
|
|
45009
45056
|
renameSync as renameSync18,
|
|
45010
45057
|
unlinkSync as unlinkSync24,
|
|
45011
|
-
writeFileSync as
|
|
45058
|
+
writeFileSync as writeFileSync28
|
|
45012
45059
|
} from "fs";
|
|
45013
45060
|
import { dirname as dirname25, resolve as resolve27 } from "path";
|
|
45014
45061
|
function parseEnrollmentInvite(code) {
|
|
@@ -45038,7 +45085,7 @@ function isEnrollmentPending(invite) {
|
|
|
45038
45085
|
if (!existsSync40(path))
|
|
45039
45086
|
return false;
|
|
45040
45087
|
try {
|
|
45041
|
-
const saved = JSON.parse(
|
|
45088
|
+
const saved = JSON.parse(readFileSync32(path, "utf8"));
|
|
45042
45089
|
return saved.central === invite.central && saved.token === invite.token;
|
|
45043
45090
|
} catch {
|
|
45044
45091
|
return false;
|
|
@@ -45047,7 +45094,7 @@ function isEnrollmentPending(invite) {
|
|
|
45047
45094
|
function loadOrCreatePending(invite, nodeName) {
|
|
45048
45095
|
const path = pendingEnrollmentPath();
|
|
45049
45096
|
if (existsSync40(path)) {
|
|
45050
|
-
const saved = JSON.parse(
|
|
45097
|
+
const saved = JSON.parse(readFileSync32(path, "utf8"));
|
|
45051
45098
|
if (saved.central === invite.central && saved.token === invite.token)
|
|
45052
45099
|
return saved;
|
|
45053
45100
|
throw new Error(`another Otium enrollment is pending at ${path}`);
|
|
@@ -45065,7 +45112,7 @@ function loadOrCreatePending(invite, nodeName) {
|
|
|
45065
45112
|
let fd;
|
|
45066
45113
|
try {
|
|
45067
45114
|
fd = openSync6(temporaryPath, "wx", 384);
|
|
45068
|
-
|
|
45115
|
+
writeFileSync28(fd, `${JSON.stringify(pending2, null, 2)}
|
|
45069
45116
|
`, "utf8");
|
|
45070
45117
|
fsyncSync3(fd);
|
|
45071
45118
|
closeSync6(fd);
|
|
@@ -45085,7 +45132,7 @@ function loadOrCreatePending(invite, nodeName) {
|
|
|
45085
45132
|
if (existsSync40(temporaryPath))
|
|
45086
45133
|
unlinkSync24(temporaryPath);
|
|
45087
45134
|
if (error2.code === "EEXIST" && existsSync40(path)) {
|
|
45088
|
-
const saved = JSON.parse(
|
|
45135
|
+
const saved = JSON.parse(readFileSync32(path, "utf8"));
|
|
45089
45136
|
if (saved.central === invite.central && saved.token === invite.token)
|
|
45090
45137
|
return saved;
|
|
45091
45138
|
}
|
|
@@ -45100,7 +45147,7 @@ function replacePendingEnrollment(pending2) {
|
|
|
45100
45147
|
let fd;
|
|
45101
45148
|
try {
|
|
45102
45149
|
fd = openSync6(temporaryPath, "wx", 384);
|
|
45103
|
-
|
|
45150
|
+
writeFileSync28(fd, `${JSON.stringify(pending2, null, 2)}
|
|
45104
45151
|
`, "utf8");
|
|
45105
45152
|
fsyncSync3(fd);
|
|
45106
45153
|
closeSync6(fd);
|
|
@@ -45122,7 +45169,7 @@ function replacePendingEnrollment(pending2) {
|
|
|
45122
45169
|
}
|
|
45123
45170
|
function recordClaimedCredential(pending2, join47) {
|
|
45124
45171
|
withJoinCredentialLock(() => {
|
|
45125
|
-
const current3 = JSON.parse(
|
|
45172
|
+
const current3 = JSON.parse(readFileSync32(pendingEnrollmentPath(), "utf8"));
|
|
45126
45173
|
if (current3.central !== pending2.central || current3.token !== pending2.token || current3.idempotencyKey !== pending2.idempotencyKey || current3.publicKey !== pending2.publicKey) {
|
|
45127
45174
|
throw new Error("pending Otium enrollment changed while its claim was in flight");
|
|
45128
45175
|
}
|
|
@@ -45201,7 +45248,7 @@ async function claimEnrollment(invite, nodeName) {
|
|
|
45201
45248
|
function commitEnrollment(join47, options = {}) {
|
|
45202
45249
|
return withJoinCredentialLock(() => {
|
|
45203
45250
|
const pendingPath = pendingEnrollmentPath();
|
|
45204
|
-
const pending2 = existsSync40(pendingPath) ? JSON.parse(
|
|
45251
|
+
const pending2 = existsSync40(pendingPath) ? JSON.parse(readFileSync32(pendingPath, "utf8")) : null;
|
|
45205
45252
|
const digest = joinCredentialDigest(join47);
|
|
45206
45253
|
if (pending2 && (!pending2.claimed || pending2.claimed.digest !== digest || pending2.claimed.cellId !== join47.cellId)) {
|
|
45207
45254
|
throw new Error(`pending Otium enrollment at ${pendingPath} does not match these credentials`);
|
|
@@ -47292,4 +47339,4 @@ switch (command) {
|
|
|
47292
47339
|
}
|
|
47293
47340
|
}
|
|
47294
47341
|
|
|
47295
|
-
//# debugId=
|
|
47342
|
+
//# debugId=C1F343985A31393664756E2164756E21
|