@sideboard-ai/core 0.1.311 → 0.1.313
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/{agents-QIIZYNOM.js → agents-OHIE3Z7L.js} +3 -3
- package/dist/{agents-XXXRQJJO.js → agents-PSNWJMEC.js} +3 -3
- package/dist/{chunk-GQJOLTZU.js → chunk-2JOBQUUS.js} +622 -20
- package/dist/{chunk-7ORMOP3D.js → chunk-E2NJ6RH7.js} +12 -2
- package/dist/{chunk-PXMLMBMI.js → chunk-E63AM3PW.js} +29 -6
- package/dist/{chunk-VEVFHO6K.js → chunk-HH3VVTEC.js} +43 -11
- package/dist/{chunk-33KDPEK4.js → chunk-RSA47QYR.js} +29 -6
- package/dist/{chunk-4YBQBVYL.js → chunk-TDXORDN6.js} +516 -24
- package/dist/{chunk-2ER7DQJP.js → chunk-U3J2YY4T.js} +19 -3
- package/dist/{chunk-42JGPPVS.js → chunk-V5BTGQ6M.js} +38 -6
- package/dist/{connected-teams-WLWIVYGD.js → connected-teams-IFW3NQ6G.js} +4 -2
- package/dist/{connected-teams-BBNYTR3I.js → connected-teams-IHK2WXUI.js} +4 -2
- package/dist/index.cjs +807 -393
- package/dist/index.d.cts +42 -8
- package/dist/index.d.ts +42 -8
- package/dist/index.js +29 -218
- package/dist/mcp/run-stdio.cjs +822 -125
- package/dist/mcp/run-stdio.js +4 -4
- package/dist/{oauth-WCUZ6Z5G.js → oauth-CI3U5ZAA.js} +1 -1
- package/dist/{oauth-DP4ZV2M2.js → oauth-CR5FY4CJ.js} +1 -1
- package/dist/{orchestrator-2CCFGYAA.js → orchestrator-BF7TKSA2.js} +4 -4
- package/dist/{orchestrator-3W5S6TNP.js → orchestrator-RRHB7RNN.js} +4 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -12769,24 +12769,47 @@ var init_turn_trace = __esm({
|
|
|
12769
12769
|
});
|
|
12770
12770
|
|
|
12771
12771
|
// src/brightsy/config.ts
|
|
12772
|
+
function resolveBrightsyConfigFile(path2) {
|
|
12773
|
+
try {
|
|
12774
|
+
if ((0, import_node_fs27.existsSync)(path2) && (0, import_node_fs27.statSync)(path2).isDirectory()) {
|
|
12775
|
+
return (0, import_node_path31.join)(path2, "config.json");
|
|
12776
|
+
}
|
|
12777
|
+
} catch {
|
|
12778
|
+
}
|
|
12779
|
+
return path2;
|
|
12780
|
+
}
|
|
12772
12781
|
function brightsyConfigPath() {
|
|
12773
12782
|
const override = process.env.BRIGHTSY_CONFIG?.trim();
|
|
12774
|
-
|
|
12775
|
-
return (
|
|
12783
|
+
const raw = override || (0, import_node_path31.join)((0, import_node_os10.homedir)(), ".brightsy", "config.json");
|
|
12784
|
+
return resolveBrightsyConfigFile(raw);
|
|
12776
12785
|
}
|
|
12777
12786
|
function loadBrightsyConfig() {
|
|
12778
12787
|
const path2 = brightsyConfigPath();
|
|
12779
12788
|
if (!(0, import_node_fs27.existsSync)(path2)) {
|
|
12780
12789
|
throw new Error("Brightsy not logged in \u2014 run `brightsy login` first");
|
|
12781
12790
|
}
|
|
12782
|
-
|
|
12791
|
+
let text7;
|
|
12792
|
+
try {
|
|
12793
|
+
text7 = (0, import_node_fs27.readFileSync)(path2, "utf8");
|
|
12794
|
+
} catch (err) {
|
|
12795
|
+
const code = err && typeof err === "object" && "code" in err ? String(err.code) : "";
|
|
12796
|
+
if (code === "EISDIR") {
|
|
12797
|
+
throw new Error(
|
|
12798
|
+
`Brightsy config is a directory (${path2}) \u2014 expected ~/.brightsy/config.json`
|
|
12799
|
+
);
|
|
12800
|
+
}
|
|
12801
|
+
throw err;
|
|
12802
|
+
}
|
|
12803
|
+
const raw = JSON.parse(text7);
|
|
12783
12804
|
if (!raw.access_token || !raw.account_id) {
|
|
12784
12805
|
throw new Error("Brightsy config incomplete \u2014 run `brightsy login`");
|
|
12785
12806
|
}
|
|
12786
12807
|
return raw;
|
|
12787
12808
|
}
|
|
12788
12809
|
function saveBrightsyConfig(cfg) {
|
|
12789
|
-
|
|
12810
|
+
const path2 = brightsyConfigPath();
|
|
12811
|
+
(0, import_node_fs27.mkdirSync)((0, import_node_path31.dirname)(path2), { recursive: true });
|
|
12812
|
+
(0, import_node_fs27.writeFileSync)(path2, `${JSON.stringify(cfg, null, 2)}
|
|
12790
12813
|
`, {
|
|
12791
12814
|
mode: 384
|
|
12792
12815
|
});
|
|
@@ -13110,6 +13133,7 @@ var connected_teams_exports = {};
|
|
|
13110
13133
|
__export(connected_teams_exports, {
|
|
13111
13134
|
applyConnectedTeamToCli: () => applyConnectedTeamToCli,
|
|
13112
13135
|
brightsyMcpServerName: () => brightsyMcpServerName,
|
|
13136
|
+
brightsySessionShouldReplace: () => brightsySessionShouldReplace,
|
|
13113
13137
|
connectBrightsyTeam: () => connectBrightsyTeam,
|
|
13114
13138
|
disconnectBrightsyTeam: () => disconnectBrightsyTeam,
|
|
13115
13139
|
ensureCliTeamTracked: () => ensureCliTeamTracked,
|
|
@@ -13150,6 +13174,25 @@ function listConnectedBrightsyTeams() {
|
|
|
13150
13174
|
function getConnectedBrightsyTeamsRaw() {
|
|
13151
13175
|
return readStore();
|
|
13152
13176
|
}
|
|
13177
|
+
function teamFromCliSession(cfg, current) {
|
|
13178
|
+
return {
|
|
13179
|
+
...current,
|
|
13180
|
+
access_token: cfg.access_token,
|
|
13181
|
+
refresh_token: cfg.refresh_token ?? current.refresh_token,
|
|
13182
|
+
expires_at: cfg.expires_at ?? current.expires_at,
|
|
13183
|
+
endpoint: cfg.endpoint ?? current.endpoint,
|
|
13184
|
+
oauth_client_id: cfg.oauth_client_id ?? current.oauth_client_id,
|
|
13185
|
+
slug: cfg.account_slug || current.slug
|
|
13186
|
+
};
|
|
13187
|
+
}
|
|
13188
|
+
function brightsySessionShouldReplace(a, b) {
|
|
13189
|
+
if (!a.access_token) return false;
|
|
13190
|
+
const aStale = brightsyAccessTokenNeedsRefresh(a.expires_at);
|
|
13191
|
+
const bStale = !b.access_token || brightsyAccessTokenNeedsRefresh(b.expires_at);
|
|
13192
|
+
if (!aStale && bStale) return true;
|
|
13193
|
+
if (aStale) return false;
|
|
13194
|
+
return (a.expires_at ?? 0) > (b.expires_at ?? 0);
|
|
13195
|
+
}
|
|
13153
13196
|
function applyConnectedTeamToCli(team) {
|
|
13154
13197
|
let base = {};
|
|
13155
13198
|
try {
|
|
@@ -13236,22 +13279,34 @@ async function ensureConnectedBrightsyTeamTokens(opts) {
|
|
|
13236
13279
|
}
|
|
13237
13280
|
next.push(refreshed);
|
|
13238
13281
|
}
|
|
13239
|
-
if (changed) writeStore(next);
|
|
13240
13282
|
try {
|
|
13241
13283
|
const cfg2 = loadBrightsyConfig();
|
|
13242
|
-
const
|
|
13243
|
-
if (
|
|
13244
|
-
|
|
13284
|
+
const idx = next.findIndex((t) => t.id === cfg2.account_id);
|
|
13285
|
+
if (idx >= 0) {
|
|
13286
|
+
const active = next[idx];
|
|
13287
|
+
if (brightsySessionShouldReplace(cfg2, active)) {
|
|
13288
|
+
next[idx] = teamFromCliSession(cfg2, active);
|
|
13289
|
+
changed = true;
|
|
13290
|
+
} else if (active.access_token !== cfg2.access_token) {
|
|
13291
|
+
applyConnectedTeamToCli(active);
|
|
13292
|
+
}
|
|
13245
13293
|
}
|
|
13246
13294
|
} catch {
|
|
13247
13295
|
}
|
|
13296
|
+
if (changed) writeStore(next);
|
|
13248
13297
|
return next;
|
|
13249
13298
|
}
|
|
13250
13299
|
function ensureCliTeamTracked(meta) {
|
|
13251
13300
|
try {
|
|
13252
13301
|
const cfg = loadBrightsyConfig();
|
|
13253
13302
|
const existing = readStore();
|
|
13254
|
-
|
|
13303
|
+
const idx = existing.findIndex((t) => t.id === cfg.account_id);
|
|
13304
|
+
if (idx >= 0) {
|
|
13305
|
+
const current = existing[idx];
|
|
13306
|
+
if (brightsySessionShouldReplace(cfg, current)) {
|
|
13307
|
+
existing[idx] = teamFromCliSession(cfg, current);
|
|
13308
|
+
writeStore(existing);
|
|
13309
|
+
}
|
|
13255
13310
|
return listConnectedBrightsyTeams();
|
|
13256
13311
|
}
|
|
13257
13312
|
const team = {
|
|
@@ -13869,18 +13924,18 @@ function mcpUiContentSecurityPolicy(csp) {
|
|
|
13869
13924
|
const connect = (csp?.connectDomains ?? []).join(" ");
|
|
13870
13925
|
const frames = csp?.frameDomains?.length ? csp.frameDomains.join(" ") : "'none'";
|
|
13871
13926
|
const base = csp?.baseUriDomains?.length ? csp.baseUriDomains.join(" ") : "'none'";
|
|
13927
|
+
const connectSrc = connect ? `'self' ${connect}`.trim() : "'none'";
|
|
13872
13928
|
return [
|
|
13873
13929
|
"default-src 'none'",
|
|
13874
|
-
`script-src 'self' 'unsafe-inline'
|
|
13930
|
+
`script-src 'self' 'unsafe-inline' ${resource}`.trim(),
|
|
13875
13931
|
`style-src 'self' 'unsafe-inline' ${resource}`.trim(),
|
|
13876
|
-
`img-src 'self' data:
|
|
13877
|
-
`font-src 'self'
|
|
13878
|
-
`connect-src
|
|
13879
|
-
`media-src 'self' data:
|
|
13932
|
+
`img-src 'self' data: ${resource}`.trim(),
|
|
13933
|
+
`font-src 'self' ${resource}`.trim(),
|
|
13934
|
+
`connect-src ${connectSrc}`,
|
|
13935
|
+
`media-src 'self' data: ${resource}`.trim(),
|
|
13880
13936
|
`frame-src ${frames}`,
|
|
13881
13937
|
`base-uri ${base}`,
|
|
13882
|
-
"object-src 'none'"
|
|
13883
|
-
"form-action 'self'"
|
|
13938
|
+
"object-src 'none'"
|
|
13884
13939
|
].join("; ");
|
|
13885
13940
|
}
|
|
13886
13941
|
function htmlText(text7, blob) {
|
|
@@ -13917,8 +13972,10 @@ function originList(value) {
|
|
|
13917
13972
|
return out;
|
|
13918
13973
|
}
|
|
13919
13974
|
function originToken(value) {
|
|
13975
|
+
const trimmed = value.trim();
|
|
13976
|
+
if (/^(https?|wss?):\/\/\*\.[a-z0-9.-]+(?::\d+)?$/i.test(trimmed)) return trimmed;
|
|
13920
13977
|
try {
|
|
13921
|
-
const url = new URL(
|
|
13978
|
+
const url = new URL(trimmed);
|
|
13922
13979
|
if (url.protocol !== "https:" && url.protocol !== "http:" && url.protocol !== "wss:" && url.protocol !== "ws:") {
|
|
13923
13980
|
return null;
|
|
13924
13981
|
}
|
|
@@ -15279,6 +15336,524 @@ var init_orch_mcp_isolation = __esm({
|
|
|
15279
15336
|
}
|
|
15280
15337
|
});
|
|
15281
15338
|
|
|
15339
|
+
// src/mcp-ui/visibility.ts
|
|
15340
|
+
function visibilityFromMeta(meta) {
|
|
15341
|
+
const rec = asRecord4(meta);
|
|
15342
|
+
const ui = asRecord4(rec.ui);
|
|
15343
|
+
const raw = ui.visibility;
|
|
15344
|
+
if (!Array.isArray(raw)) return ["model", "app"];
|
|
15345
|
+
const out = [];
|
|
15346
|
+
for (const item of raw) {
|
|
15347
|
+
if (item !== "model" && item !== "app") continue;
|
|
15348
|
+
if (!out.includes(item)) out.push(item);
|
|
15349
|
+
}
|
|
15350
|
+
return out.length ? out : ["model", "app"];
|
|
15351
|
+
}
|
|
15352
|
+
function toolVisibleTo(visibility, audience) {
|
|
15353
|
+
const vis = visibility?.length ? visibility : ["model", "app"];
|
|
15354
|
+
return vis.includes(audience);
|
|
15355
|
+
}
|
|
15356
|
+
function asRecord4(value) {
|
|
15357
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
15358
|
+
return value;
|
|
15359
|
+
}
|
|
15360
|
+
var init_visibility = __esm({
|
|
15361
|
+
"src/mcp-ui/visibility.ts"() {
|
|
15362
|
+
"use strict";
|
|
15363
|
+
}
|
|
15364
|
+
});
|
|
15365
|
+
|
|
15366
|
+
// src/mcp-ui/proxy-server.ts
|
|
15367
|
+
function attachMcpUiProxyHandlers(server, session) {
|
|
15368
|
+
server.setRequestHandler(import_types.ListToolsRequestSchema, async () => {
|
|
15369
|
+
const tools = await session.listTools();
|
|
15370
|
+
return { tools: tools.filter((tool) => toolVisibleTo(tool.visibility, "model")).map(listedTool) };
|
|
15371
|
+
});
|
|
15372
|
+
server.setRequestHandler(import_types.CallToolRequestSchema, async (request) => {
|
|
15373
|
+
const name = request.params.name;
|
|
15374
|
+
const tools = await session.listTools();
|
|
15375
|
+
const tool = tools.find((item) => item.name === name);
|
|
15376
|
+
if (!tool || !toolVisibleTo(tool.visibility, "model")) {
|
|
15377
|
+
throw new Error(`Tool ${name} is not available to the model`);
|
|
15378
|
+
}
|
|
15379
|
+
return await session.callTool(name, request.params.arguments ?? {});
|
|
15380
|
+
});
|
|
15381
|
+
server.setRequestHandler(import_types.ReadResourceRequestSchema, async (request) => {
|
|
15382
|
+
const resource = await session.readResource(request.params.uri);
|
|
15383
|
+
if (!resource) throw new Error(`Resource ${request.params.uri} was empty`);
|
|
15384
|
+
return {
|
|
15385
|
+
contents: [
|
|
15386
|
+
{
|
|
15387
|
+
uri: resource.uri,
|
|
15388
|
+
...resource.mimeType ? { mimeType: resource.mimeType } : {},
|
|
15389
|
+
...resource.text != null ? { text: resource.text } : {},
|
|
15390
|
+
...resource.blob != null ? { blob: resource.blob } : {}
|
|
15391
|
+
}
|
|
15392
|
+
]
|
|
15393
|
+
};
|
|
15394
|
+
});
|
|
15395
|
+
server.setRequestHandler(import_types.ListResourcesRequestSchema, async () => session.listResources());
|
|
15396
|
+
server.setRequestHandler(
|
|
15397
|
+
import_types.ListResourceTemplatesRequestSchema,
|
|
15398
|
+
async () => session.listResourceTemplates()
|
|
15399
|
+
);
|
|
15400
|
+
server.setRequestHandler(import_types.ListPromptsRequestSchema, async () => session.listPrompts());
|
|
15401
|
+
server.setRequestHandler(import_types.GetPromptRequestSchema, async (request) => {
|
|
15402
|
+
return await session.getPrompt(request.params.name, request.params.arguments);
|
|
15403
|
+
});
|
|
15404
|
+
server.fallbackRequestHandler = async (request) => {
|
|
15405
|
+
return await session.forward(request.method, request.params);
|
|
15406
|
+
};
|
|
15407
|
+
}
|
|
15408
|
+
function listedTool(tool) {
|
|
15409
|
+
return {
|
|
15410
|
+
name: tool.name,
|
|
15411
|
+
...tool.description ? { description: tool.description } : {},
|
|
15412
|
+
inputSchema: tool.inputSchema ?? { type: "object", properties: {} },
|
|
15413
|
+
_meta: {
|
|
15414
|
+
ui: {
|
|
15415
|
+
...tool.resourceUri ? { resourceUri: tool.resourceUri } : {},
|
|
15416
|
+
visibility: tool.visibility
|
|
15417
|
+
}
|
|
15418
|
+
}
|
|
15419
|
+
};
|
|
15420
|
+
}
|
|
15421
|
+
var import_server, import_types;
|
|
15422
|
+
var init_proxy_server = __esm({
|
|
15423
|
+
"src/mcp-ui/proxy-server.ts"() {
|
|
15424
|
+
"use strict";
|
|
15425
|
+
import_server = require("@modelcontextprotocol/sdk/server/index.js");
|
|
15426
|
+
import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
15427
|
+
init_visibility();
|
|
15428
|
+
}
|
|
15429
|
+
});
|
|
15430
|
+
|
|
15431
|
+
// src/mcp-ui/proxy-http.ts
|
|
15432
|
+
async function listenMcpUiProxy(opts) {
|
|
15433
|
+
const token = (0, import_node_crypto11.randomBytes)(24).toString("hex");
|
|
15434
|
+
const transports = /* @__PURE__ */ new Map();
|
|
15435
|
+
const httpServer = (0, import_node_http.createServer)((req, res) => {
|
|
15436
|
+
void handle(req, res);
|
|
15437
|
+
});
|
|
15438
|
+
await new Promise((resolve3, reject) => {
|
|
15439
|
+
httpServer.once("error", reject);
|
|
15440
|
+
httpServer.listen(0, "127.0.0.1", () => resolve3());
|
|
15441
|
+
});
|
|
15442
|
+
const addr = httpServer.address();
|
|
15443
|
+
if (!addr || typeof addr === "string") throw new Error("mcp-ui proxy failed to bind");
|
|
15444
|
+
const origin = `http://127.0.0.1:${addr.port}`;
|
|
15445
|
+
async function handle(req, res) {
|
|
15446
|
+
if (req.headers.authorization !== `Bearer ${token}`) {
|
|
15447
|
+
res.writeHead(401).end();
|
|
15448
|
+
return;
|
|
15449
|
+
}
|
|
15450
|
+
const target = parseMcpUiProxyPath(req.url);
|
|
15451
|
+
if (!target) {
|
|
15452
|
+
res.writeHead(404).end();
|
|
15453
|
+
return;
|
|
15454
|
+
}
|
|
15455
|
+
try {
|
|
15456
|
+
const session = await opts.sessionFor(target.server, target.dirsKey);
|
|
15457
|
+
if (!session) {
|
|
15458
|
+
res.writeHead(404).end();
|
|
15459
|
+
return;
|
|
15460
|
+
}
|
|
15461
|
+
const header = req.headers["mcp-session-id"];
|
|
15462
|
+
const sid = typeof header === "string" ? header : "";
|
|
15463
|
+
const sessionKey = `${target.server}:${target.dirsKey}`;
|
|
15464
|
+
let transport = sid ? transports.get(`${sessionKey}:${sid}`) : void 0;
|
|
15465
|
+
if (!transport) {
|
|
15466
|
+
if (req.method !== "POST") {
|
|
15467
|
+
res.writeHead(400).end();
|
|
15468
|
+
return;
|
|
15469
|
+
}
|
|
15470
|
+
const created = new import_streamableHttp.StreamableHTTPServerTransport({
|
|
15471
|
+
sessionIdGenerator: () => (0, import_node_crypto11.randomUUID)(),
|
|
15472
|
+
allowedHosts: ["127.0.0.1", "localhost"],
|
|
15473
|
+
onsessioninitialized: (id) => {
|
|
15474
|
+
transports.set(`${sessionKey}:${id}`, created);
|
|
15475
|
+
},
|
|
15476
|
+
onsessionclosed: (id) => {
|
|
15477
|
+
transports.delete(`${sessionKey}:${id}`);
|
|
15478
|
+
}
|
|
15479
|
+
});
|
|
15480
|
+
transport = created;
|
|
15481
|
+
const mcp = new import_server2.Server(
|
|
15482
|
+
{ name: `sideboard-ui-proxy-${target.server}`, version: "1.0.0" },
|
|
15483
|
+
{ capabilities: session.capabilities() }
|
|
15484
|
+
);
|
|
15485
|
+
attachMcpUiProxyHandlers(mcp, session);
|
|
15486
|
+
await mcp.connect(created);
|
|
15487
|
+
}
|
|
15488
|
+
await transport.handleRequest(req, res);
|
|
15489
|
+
} catch {
|
|
15490
|
+
if (!res.headersSent) res.writeHead(500).end();
|
|
15491
|
+
}
|
|
15492
|
+
}
|
|
15493
|
+
return {
|
|
15494
|
+
urlFor(server, dirsKey) {
|
|
15495
|
+
const base = `${origin}/s/${encodeURIComponent(server)}`;
|
|
15496
|
+
return dirsKey ? `${base}/d/${dirsKey}` : base;
|
|
15497
|
+
},
|
|
15498
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
15499
|
+
async close() {
|
|
15500
|
+
await Promise.all([...transports.values()].map((item) => item.close().catch(() => void 0)));
|
|
15501
|
+
transports.clear();
|
|
15502
|
+
await new Promise((resolve3) => httpServer.close(() => resolve3()));
|
|
15503
|
+
}
|
|
15504
|
+
};
|
|
15505
|
+
}
|
|
15506
|
+
function parseMcpUiProxyPath(url) {
|
|
15507
|
+
const path2 = (url ?? "").split("?")[0] ?? "";
|
|
15508
|
+
if (!path2.startsWith("/s/")) return null;
|
|
15509
|
+
const rest = path2.slice(3).replace(/\/$/, "");
|
|
15510
|
+
const split = rest.indexOf("/d/");
|
|
15511
|
+
try {
|
|
15512
|
+
if (split < 0) {
|
|
15513
|
+
const server2 = decodeURIComponent(rest).trim();
|
|
15514
|
+
return server2 ? { server: server2, dirsKey: "" } : null;
|
|
15515
|
+
}
|
|
15516
|
+
const server = decodeURIComponent(rest.slice(0, split)).trim();
|
|
15517
|
+
const dirsKey = rest.slice(split + 3);
|
|
15518
|
+
if (!server || !/^[a-f0-9]{16}$/.test(dirsKey)) return null;
|
|
15519
|
+
return { server, dirsKey };
|
|
15520
|
+
} catch {
|
|
15521
|
+
return null;
|
|
15522
|
+
}
|
|
15523
|
+
}
|
|
15524
|
+
var import_node_crypto11, import_node_http, import_server2, import_streamableHttp;
|
|
15525
|
+
var init_proxy_http = __esm({
|
|
15526
|
+
"src/mcp-ui/proxy-http.ts"() {
|
|
15527
|
+
"use strict";
|
|
15528
|
+
import_node_crypto11 = require("crypto");
|
|
15529
|
+
import_node_http = require("http");
|
|
15530
|
+
import_server2 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
15531
|
+
import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
15532
|
+
init_proxy_server();
|
|
15533
|
+
}
|
|
15534
|
+
});
|
|
15535
|
+
|
|
15536
|
+
// src/mcp-ui/session.ts
|
|
15537
|
+
async function orEmpty(run2, fallback) {
|
|
15538
|
+
try {
|
|
15539
|
+
return await run2();
|
|
15540
|
+
} catch {
|
|
15541
|
+
return fallback;
|
|
15542
|
+
}
|
|
15543
|
+
}
|
|
15544
|
+
async function openMcpUiSession(launch) {
|
|
15545
|
+
return openMcpUiSessionFromTransport(transportForLaunch(launch));
|
|
15546
|
+
}
|
|
15547
|
+
async function openMcpUiSessionFromTransport(transport) {
|
|
15548
|
+
const client = new import_client.Client(
|
|
15549
|
+
{ name: "sideboard", version: "1.0.0" },
|
|
15550
|
+
{ capabilities: UI_CAPABILITIES }
|
|
15551
|
+
);
|
|
15552
|
+
await client.connect(transport, { timeout: REQUEST_TIMEOUT_MS });
|
|
15553
|
+
return {
|
|
15554
|
+
async listTools() {
|
|
15555
|
+
const listed = await client.listTools(void 0, { timeout: REQUEST_TIMEOUT_MS });
|
|
15556
|
+
return listed.tools.map((tool) => {
|
|
15557
|
+
const meta = tool._meta;
|
|
15558
|
+
return {
|
|
15559
|
+
name: tool.name,
|
|
15560
|
+
...tool.description ? { description: tool.description } : {},
|
|
15561
|
+
...tool.inputSchema ? { inputSchema: tool.inputSchema } : {},
|
|
15562
|
+
resourceUri: uiResourceUriFromMeta(meta),
|
|
15563
|
+
visibility: visibilityFromMeta(meta),
|
|
15564
|
+
...cspFromMeta(meta) ? { csp: cspFromMeta(meta) } : {}
|
|
15565
|
+
};
|
|
15566
|
+
});
|
|
15567
|
+
},
|
|
15568
|
+
listResources: () => orEmpty(
|
|
15569
|
+
() => client.listResources(void 0, { timeout: REQUEST_TIMEOUT_MS }),
|
|
15570
|
+
{ resources: [] }
|
|
15571
|
+
),
|
|
15572
|
+
listResourceTemplates: () => orEmpty(
|
|
15573
|
+
() => client.listResourceTemplates(void 0, { timeout: REQUEST_TIMEOUT_MS }),
|
|
15574
|
+
{ resourceTemplates: [] }
|
|
15575
|
+
),
|
|
15576
|
+
listPrompts: () => orEmpty(
|
|
15577
|
+
() => client.listPrompts(void 0, { timeout: REQUEST_TIMEOUT_MS }),
|
|
15578
|
+
{ prompts: [] }
|
|
15579
|
+
),
|
|
15580
|
+
getPrompt(name, args) {
|
|
15581
|
+
return client.getPrompt({ name, arguments: args }, { timeout: REQUEST_TIMEOUT_MS });
|
|
15582
|
+
},
|
|
15583
|
+
async readResource(uri) {
|
|
15584
|
+
const result = await client.readResource({ uri }, { timeout: REQUEST_TIMEOUT_MS });
|
|
15585
|
+
const content = result.contents?.[0];
|
|
15586
|
+
if (!content) return null;
|
|
15587
|
+
const text7 = "text" in content && typeof content.text === "string" ? content.text : void 0;
|
|
15588
|
+
const blob = "blob" in content && typeof content.blob === "string" ? content.blob : void 0;
|
|
15589
|
+
return {
|
|
15590
|
+
uri: content.uri,
|
|
15591
|
+
...content.mimeType ? { mimeType: content.mimeType } : {},
|
|
15592
|
+
...text7 != null ? { text: text7 } : {},
|
|
15593
|
+
...blob != null ? { blob } : {},
|
|
15594
|
+
...cspFromMeta(content._meta) ? { csp: cspFromMeta(content._meta) } : {}
|
|
15595
|
+
};
|
|
15596
|
+
},
|
|
15597
|
+
async callTool(name, args) {
|
|
15598
|
+
return client.callTool({ name, arguments: args }, void 0, { timeout: REQUEST_TIMEOUT_MS });
|
|
15599
|
+
},
|
|
15600
|
+
capabilities() {
|
|
15601
|
+
const caps = client.getServerCapabilities() ?? {};
|
|
15602
|
+
return {
|
|
15603
|
+
tools: caps.tools ?? {},
|
|
15604
|
+
resources: caps.resources ?? {},
|
|
15605
|
+
prompts: caps.prompts ?? {},
|
|
15606
|
+
completions: caps.completions ?? {},
|
|
15607
|
+
...caps.logging ? { logging: caps.logging } : {}
|
|
15608
|
+
};
|
|
15609
|
+
},
|
|
15610
|
+
forward(method, params) {
|
|
15611
|
+
return client.request(
|
|
15612
|
+
{ method, params },
|
|
15613
|
+
import_types2.ResultSchema,
|
|
15614
|
+
{ timeout: REQUEST_TIMEOUT_MS }
|
|
15615
|
+
);
|
|
15616
|
+
},
|
|
15617
|
+
async close() {
|
|
15618
|
+
await client.close();
|
|
15619
|
+
}
|
|
15620
|
+
};
|
|
15621
|
+
}
|
|
15622
|
+
function transportForLaunch(launch) {
|
|
15623
|
+
if (launch.kind === "stdio") {
|
|
15624
|
+
return new import_stdio.StdioClientTransport({
|
|
15625
|
+
command: launch.command,
|
|
15626
|
+
args: launch.args,
|
|
15627
|
+
env: { ...(0, import_stdio.getDefaultEnvironment)(), ...launch.env },
|
|
15628
|
+
stderr: "ignore",
|
|
15629
|
+
...launch.cwd ? { cwd: launch.cwd } : {}
|
|
15630
|
+
});
|
|
15631
|
+
}
|
|
15632
|
+
const url = new URL(launch.url);
|
|
15633
|
+
const requestInit = launch.headers ? { headers: launch.headers } : void 0;
|
|
15634
|
+
if (launch.kind === "sse") {
|
|
15635
|
+
return new import_sse.SSEClientTransport(url, requestInit ? { requestInit } : void 0);
|
|
15636
|
+
}
|
|
15637
|
+
return new import_streamableHttp2.StreamableHTTPClientTransport(url, requestInit ? { requestInit } : void 0);
|
|
15638
|
+
}
|
|
15639
|
+
var import_client, import_sse, import_stdio, import_streamableHttp2, import_types2, REQUEST_TIMEOUT_MS, UI_CAPABILITIES;
|
|
15640
|
+
var init_session = __esm({
|
|
15641
|
+
"src/mcp-ui/session.ts"() {
|
|
15642
|
+
"use strict";
|
|
15643
|
+
import_client = require("@modelcontextprotocol/sdk/client/index.js");
|
|
15644
|
+
import_sse = require("@modelcontextprotocol/sdk/client/sse.js");
|
|
15645
|
+
import_stdio = require("@modelcontextprotocol/sdk/client/stdio.js");
|
|
15646
|
+
import_streamableHttp2 = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
15647
|
+
import_types2 = require("@modelcontextprotocol/sdk/types.js");
|
|
15648
|
+
init_meta();
|
|
15649
|
+
init_visibility();
|
|
15650
|
+
REQUEST_TIMEOUT_MS = 2e4;
|
|
15651
|
+
UI_CAPABILITIES = {
|
|
15652
|
+
extensions: {
|
|
15653
|
+
"io.modelcontextprotocol/ui": {
|
|
15654
|
+
mimeTypes: ["text/html;profile=mcp-app"]
|
|
15655
|
+
}
|
|
15656
|
+
}
|
|
15657
|
+
};
|
|
15658
|
+
}
|
|
15659
|
+
});
|
|
15660
|
+
|
|
15661
|
+
// src/mcp-ui/host.ts
|
|
15662
|
+
function getMcpUiHost() {
|
|
15663
|
+
if (!singleton) {
|
|
15664
|
+
singleton = new McpUiHost({
|
|
15665
|
+
entries: (projectDirs) => listUserClaudeMcpServerEntries((0, import_node_os16.homedir)(), projectDirs)
|
|
15666
|
+
});
|
|
15667
|
+
}
|
|
15668
|
+
return singleton;
|
|
15669
|
+
}
|
|
15670
|
+
async function proxyClaudeUserMcp(orchestrator, projectDirs) {
|
|
15671
|
+
if (orchestrator) return {};
|
|
15672
|
+
const dirs = projectDirs.filter((d) => typeof d === "string" && d.length > 0);
|
|
15673
|
+
return getMcpUiHost().proxyEntries(listUserClaudeMcpServerEntries((0, import_node_os16.homedir)(), dirs), dirs);
|
|
15674
|
+
}
|
|
15675
|
+
function closeMcpUiHost() {
|
|
15676
|
+
const host = singleton;
|
|
15677
|
+
singleton = void 0;
|
|
15678
|
+
if (host) void host.closeAll();
|
|
15679
|
+
}
|
|
15680
|
+
function dirsKeyFor(projectDirs) {
|
|
15681
|
+
if (!projectDirs?.length) return "";
|
|
15682
|
+
return (0, import_node_crypto12.createHash)("sha256").update(projectDirs.join("\0")).digest("hex").slice(0, 16);
|
|
15683
|
+
}
|
|
15684
|
+
var import_node_crypto12, import_node_os16, TOOL_TTL_MS, McpUiHost, singleton;
|
|
15685
|
+
var init_host = __esm({
|
|
15686
|
+
"src/mcp-ui/host.ts"() {
|
|
15687
|
+
"use strict";
|
|
15688
|
+
import_node_crypto12 = require("crypto");
|
|
15689
|
+
import_node_os16 = require("os");
|
|
15690
|
+
init_orch_mcp_isolation();
|
|
15691
|
+
init_meta();
|
|
15692
|
+
init_proxy_http();
|
|
15693
|
+
init_session();
|
|
15694
|
+
init_visibility();
|
|
15695
|
+
TOOL_TTL_MS = 5 * 60 * 1e3;
|
|
15696
|
+
McpUiHost = class {
|
|
15697
|
+
constructor(opts) {
|
|
15698
|
+
this.opts = opts;
|
|
15699
|
+
}
|
|
15700
|
+
opts;
|
|
15701
|
+
sessions = /* @__PURE__ */ new Map();
|
|
15702
|
+
toolLists = /* @__PURE__ */ new Map();
|
|
15703
|
+
proxy;
|
|
15704
|
+
proxyDirs = /* @__PURE__ */ new Map();
|
|
15705
|
+
async viewForClaudeTool(toolName, projectDirs) {
|
|
15706
|
+
const entries = this.userEntries(projectDirs);
|
|
15707
|
+
const match = matchClaudeMcpTool(toolName, Object.keys(entries));
|
|
15708
|
+
if (!match) return null;
|
|
15709
|
+
const launch = parseMcpServerLaunch(entries[match.server] ?? {});
|
|
15710
|
+
if (!launch) return null;
|
|
15711
|
+
try {
|
|
15712
|
+
const session = await this.sessionFor(match.server, launch);
|
|
15713
|
+
const tools = await this.toolsFor(match.server, launch, session);
|
|
15714
|
+
const tool = tools.find((item) => item.name === match.tool);
|
|
15715
|
+
if (!tool?.resourceUri) return null;
|
|
15716
|
+
const resource = await session.readResource(tool.resourceUri);
|
|
15717
|
+
if (!resource) return null;
|
|
15718
|
+
const html = htmlFromResourceContent(resource);
|
|
15719
|
+
if (!html) return null;
|
|
15720
|
+
const csp = resource.csp ?? tool.csp;
|
|
15721
|
+
return {
|
|
15722
|
+
server: match.server,
|
|
15723
|
+
tool: match.tool,
|
|
15724
|
+
uri: html.uri,
|
|
15725
|
+
mimeType: html.mimeType,
|
|
15726
|
+
html: html.html,
|
|
15727
|
+
csp: mcpUiContentSecurityPolicy(csp)
|
|
15728
|
+
};
|
|
15729
|
+
} catch (err) {
|
|
15730
|
+
console.error(
|
|
15731
|
+
`[mcp-ui] ${match.server}/${match.tool}:`,
|
|
15732
|
+
err instanceof Error ? err.message : err
|
|
15733
|
+
);
|
|
15734
|
+
return null;
|
|
15735
|
+
}
|
|
15736
|
+
}
|
|
15737
|
+
/**
|
|
15738
|
+
* Point Claude at loopback HTTP so it shares this host's upstream session
|
|
15739
|
+
* and never sees `visibility: ["app"]` tools.
|
|
15740
|
+
*/
|
|
15741
|
+
async proxyEntries(entries, projectDirs) {
|
|
15742
|
+
const names = Object.keys(entries).filter((name) => name.trim());
|
|
15743
|
+
if (names.length === 0) return {};
|
|
15744
|
+
const dirsKey = dirsKeyFor(projectDirs);
|
|
15745
|
+
this.proxyDirs.set(dirsKey, projectDirs);
|
|
15746
|
+
try {
|
|
15747
|
+
const listen = await this.ensureProxy();
|
|
15748
|
+
const out = {};
|
|
15749
|
+
for (const name of names) {
|
|
15750
|
+
out[name] = {
|
|
15751
|
+
type: "http",
|
|
15752
|
+
url: listen.urlFor(name, dirsKey),
|
|
15753
|
+
headers: listen.headers
|
|
15754
|
+
};
|
|
15755
|
+
}
|
|
15756
|
+
return out;
|
|
15757
|
+
} catch (err) {
|
|
15758
|
+
console.error("[mcp-ui] proxy:", err instanceof Error ? err.message : err);
|
|
15759
|
+
return { ...entries };
|
|
15760
|
+
}
|
|
15761
|
+
}
|
|
15762
|
+
async callTool(server, tool, args, projectDirs) {
|
|
15763
|
+
const entry = this.userEntries(projectDirs)[server];
|
|
15764
|
+
if (!entry) throw new Error(`MCP server ${server} is not available`);
|
|
15765
|
+
const launch = parseMcpServerLaunch(entry);
|
|
15766
|
+
if (!launch) throw new Error(`MCP server ${server} is not available`);
|
|
15767
|
+
const session = await this.sessionFor(server, launch);
|
|
15768
|
+
const tools = await this.toolsFor(server, launch, session);
|
|
15769
|
+
const info = tools.find((item) => item.name === tool);
|
|
15770
|
+
if (!info || !toolVisibleTo(info.visibility, "app")) {
|
|
15771
|
+
throw new Error(`Tool ${tool} is not available to the app`);
|
|
15772
|
+
}
|
|
15773
|
+
return session.callTool(tool, args);
|
|
15774
|
+
}
|
|
15775
|
+
async readResource(server, uri, projectDirs) {
|
|
15776
|
+
const session = await this.sessionForName(server, projectDirs);
|
|
15777
|
+
if (!session) throw new Error(`MCP server ${server} is not available`);
|
|
15778
|
+
const resource = await session.readResource(uri);
|
|
15779
|
+
if (!resource) throw new Error(`Resource ${uri} was empty`);
|
|
15780
|
+
return {
|
|
15781
|
+
contents: [
|
|
15782
|
+
{
|
|
15783
|
+
uri: resource.uri,
|
|
15784
|
+
...resource.mimeType ? { mimeType: resource.mimeType } : {},
|
|
15785
|
+
...resource.text != null ? { text: resource.text } : {},
|
|
15786
|
+
...resource.blob != null ? { blob: resource.blob } : {}
|
|
15787
|
+
}
|
|
15788
|
+
]
|
|
15789
|
+
};
|
|
15790
|
+
}
|
|
15791
|
+
async closeAll() {
|
|
15792
|
+
const pending = [...this.sessions.values()];
|
|
15793
|
+
const proxy = this.proxy;
|
|
15794
|
+
this.sessions.clear();
|
|
15795
|
+
this.toolLists.clear();
|
|
15796
|
+
this.proxyDirs.clear();
|
|
15797
|
+
this.proxy = void 0;
|
|
15798
|
+
await Promise.all([
|
|
15799
|
+
...pending.map((session) => session.then((open) => open.close()).catch(() => void 0)),
|
|
15800
|
+
proxy ? proxy.then((listen) => listen.close()).catch(() => void 0) : Promise.resolve()
|
|
15801
|
+
]);
|
|
15802
|
+
}
|
|
15803
|
+
ensureProxy() {
|
|
15804
|
+
if (this.proxy) return this.proxy;
|
|
15805
|
+
this.proxy = listenMcpUiProxy({
|
|
15806
|
+
sessionFor: (server, dirsKey) => {
|
|
15807
|
+
if (dirsKey && !this.proxyDirs.has(dirsKey)) return Promise.resolve(null);
|
|
15808
|
+
return this.sessionForName(server, this.proxyDirs.get(dirsKey));
|
|
15809
|
+
}
|
|
15810
|
+
}).catch((err) => {
|
|
15811
|
+
this.proxy = void 0;
|
|
15812
|
+
throw err;
|
|
15813
|
+
});
|
|
15814
|
+
return this.proxy;
|
|
15815
|
+
}
|
|
15816
|
+
userEntries(projectDirs) {
|
|
15817
|
+
const out = {};
|
|
15818
|
+
for (const [name, entry] of Object.entries(this.opts.entries(projectDirs))) {
|
|
15819
|
+
if (!name.trim() || isInjectedOrchMcpName(name) || !entry) continue;
|
|
15820
|
+
out[name] = entry;
|
|
15821
|
+
}
|
|
15822
|
+
return out;
|
|
15823
|
+
}
|
|
15824
|
+
async sessionForName(server, projectDirs) {
|
|
15825
|
+
const entry = this.userEntries(projectDirs)[server];
|
|
15826
|
+
if (!entry) return null;
|
|
15827
|
+
const launch = parseMcpServerLaunch(entry);
|
|
15828
|
+
if (!launch) return null;
|
|
15829
|
+
return this.sessionFor(server, launch);
|
|
15830
|
+
}
|
|
15831
|
+
sessionFor(server, launch) {
|
|
15832
|
+
const key = `${server}
|
|
15833
|
+
${JSON.stringify(launch)}`;
|
|
15834
|
+
const existing = this.sessions.get(key);
|
|
15835
|
+
if (existing) return existing;
|
|
15836
|
+
const open = this.opts.openSession ?? openMcpUiSession;
|
|
15837
|
+
const pending = open(launch).catch((err) => {
|
|
15838
|
+
this.sessions.delete(key);
|
|
15839
|
+
throw err;
|
|
15840
|
+
});
|
|
15841
|
+
this.sessions.set(key, pending);
|
|
15842
|
+
return pending;
|
|
15843
|
+
}
|
|
15844
|
+
async toolsFor(server, launch, session) {
|
|
15845
|
+
const key = `${server}
|
|
15846
|
+
${JSON.stringify(launch)}`;
|
|
15847
|
+
const cached2 = this.toolLists.get(key);
|
|
15848
|
+
if (cached2 && cached2.key === key && Date.now() - cached2.at < TOOL_TTL_MS) return cached2.tools;
|
|
15849
|
+
const tools = await session.listTools();
|
|
15850
|
+
this.toolLists.set(key, { at: Date.now(), key, tools });
|
|
15851
|
+
return tools;
|
|
15852
|
+
}
|
|
15853
|
+
};
|
|
15854
|
+
}
|
|
15855
|
+
});
|
|
15856
|
+
|
|
15282
15857
|
// src/agents/types.ts
|
|
15283
15858
|
function planModeTurnInstruction(planMode) {
|
|
15284
15859
|
return planMode ? PLAN_MODE_INSTRUCTION : PLAN_MODE_OFF_INSTRUCTION;
|
|
@@ -15474,7 +16049,7 @@ function entryDir() {
|
|
|
15474
16049
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
15475
16050
|
if (cjsDir) return cjsDir;
|
|
15476
16051
|
try {
|
|
15477
|
-
return (0, import_node_path41.dirname)((0, import_node_url2.fileURLToPath)(
|
|
16052
|
+
return (0, import_node_path41.dirname)((0, import_node_url2.fileURLToPath)(import_meta5.url));
|
|
15478
16053
|
} catch {
|
|
15479
16054
|
try {
|
|
15480
16055
|
const req = (0, import_node_module2.createRequire)(process.cwd() + "/");
|
|
@@ -15524,7 +16099,7 @@ async function buildClaudeRpcTurnCommand(req) {
|
|
|
15524
16099
|
}
|
|
15525
16100
|
};
|
|
15526
16101
|
}
|
|
15527
|
-
var import_node_fs38, import_node_module2, import_node_path41, import_node_url2,
|
|
16102
|
+
var import_node_fs38, import_node_module2, import_node_path41, import_node_url2, import_meta5;
|
|
15528
16103
|
var init_claude_host = __esm({
|
|
15529
16104
|
"src/agents/claude-host.ts"() {
|
|
15530
16105
|
"use strict";
|
|
@@ -15536,7 +16111,7 @@ var init_claude_host = __esm({
|
|
|
15536
16111
|
init_pilot_tools();
|
|
15537
16112
|
init_node_launch();
|
|
15538
16113
|
init_packaged_runtime();
|
|
15539
|
-
|
|
16114
|
+
import_meta5 = {};
|
|
15540
16115
|
}
|
|
15541
16116
|
});
|
|
15542
16117
|
|
|
@@ -15939,16 +16514,15 @@ function parseIssuesJson(raw) {
|
|
|
15939
16514
|
}
|
|
15940
16515
|
return [];
|
|
15941
16516
|
}
|
|
15942
|
-
var import_node_fs39,
|
|
16517
|
+
var import_node_fs39, CLAUDE_PROMPT_ARG_MAX, claudeAdapter;
|
|
15943
16518
|
var init_claude = __esm({
|
|
15944
16519
|
"src/agents/claude.ts"() {
|
|
15945
16520
|
"use strict";
|
|
15946
16521
|
import_node_fs39 = require("fs");
|
|
15947
|
-
import_node_os16 = require("os");
|
|
15948
16522
|
init_run();
|
|
15949
16523
|
init_app_settings();
|
|
15950
16524
|
init_claude_mcp();
|
|
15951
|
-
|
|
16525
|
+
init_host();
|
|
15952
16526
|
init_error_detail();
|
|
15953
16527
|
init_message_parts();
|
|
15954
16528
|
init_injected_mcp();
|
|
@@ -16025,7 +16599,7 @@ var init_claude = __esm({
|
|
|
16025
16599
|
});
|
|
16026
16600
|
const injectedBrightsyNames = injectedServers.filter((s) => s.name === "brightsy" || s.name.startsWith("brightsy_")).map((s) => s.name);
|
|
16027
16601
|
const chromeOn = claudeChromeEnabled();
|
|
16028
|
-
const userMcpEntries =
|
|
16602
|
+
const userMcpEntries = await proxyClaudeUserMcp(isOrchestrator, [thread.repoPath, thread.worktreePath]);
|
|
16029
16603
|
let allowedTools;
|
|
16030
16604
|
if (isOrchestrator) {
|
|
16031
16605
|
allowedTools = [
|
|
@@ -16327,7 +16901,7 @@ function unwrapCodexMcpResult(result) {
|
|
|
16327
16901
|
return String(result);
|
|
16328
16902
|
}
|
|
16329
16903
|
}
|
|
16330
|
-
function
|
|
16904
|
+
function asRecord5(value) {
|
|
16331
16905
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
16332
16906
|
return value;
|
|
16333
16907
|
}
|
|
@@ -16507,7 +17081,7 @@ var init_codex = __esm({
|
|
|
16507
17081
|
}
|
|
16508
17082
|
if (itemType === "mcp_tool_call" && item.id && item.server && item.tool) {
|
|
16509
17083
|
const name = `mcp__${item.server}__${item.tool}`;
|
|
16510
|
-
const input =
|
|
17084
|
+
const input = asRecord5(item.arguments);
|
|
16511
17085
|
const events = [
|
|
16512
17086
|
{ type: "tool_use", id: item.id, name, input }
|
|
16513
17087
|
];
|
|
@@ -16654,7 +17228,7 @@ function thisModuleFile() {
|
|
|
16654
17228
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
16655
17229
|
if (cjsDir) return (0, import_node_path43.join)(cjsDir, "cursor-sdk-resolve.js");
|
|
16656
17230
|
try {
|
|
16657
|
-
return (0, import_node_url3.fileURLToPath)(
|
|
17231
|
+
return (0, import_node_url3.fileURLToPath)(import_meta6.url);
|
|
16658
17232
|
} catch {
|
|
16659
17233
|
return (0, import_node_path43.join)(process.cwd(), "package.json");
|
|
16660
17234
|
}
|
|
@@ -16753,7 +17327,7 @@ function cursorSdkRipgrepCandidate(opts) {
|
|
|
16753
17327
|
const nested = (0, import_node_path43.join)(root, "node_modules", pkg, "bin", bin);
|
|
16754
17328
|
return (0, import_node_fs41.existsSync)(nested) ? nested : null;
|
|
16755
17329
|
}
|
|
16756
|
-
var import_node_fs41, import_node_module3, import_node_path43, import_node_url3,
|
|
17330
|
+
var import_node_fs41, import_node_module3, import_node_path43, import_node_url3, import_meta6, CURSOR_SDK_INSTALL_HINT;
|
|
16757
17331
|
var init_cursor_sdk_resolve = __esm({
|
|
16758
17332
|
"src/agents/cursor-sdk-resolve.ts"() {
|
|
16759
17333
|
"use strict";
|
|
@@ -16762,7 +17336,7 @@ var init_cursor_sdk_resolve = __esm({
|
|
|
16762
17336
|
import_node_path43 = require("path");
|
|
16763
17337
|
import_node_url3 = require("url");
|
|
16764
17338
|
init_path();
|
|
16765
|
-
|
|
17339
|
+
import_meta6 = {};
|
|
16766
17340
|
CURSOR_SDK_INSTALL_HINT = "Cursor SDK is not installed. Settings \u2192 Agents \u2192 Cursor \u2192 Install (`npm i -g @cursor/sdk`). Sideboard does not ship the SDK \u2014 update it anytime without a new Sideboard build.";
|
|
16767
17341
|
}
|
|
16768
17342
|
});
|
|
@@ -16812,20 +17386,20 @@ function turnCostUsdFromCursorUsage(before, after) {
|
|
|
16812
17386
|
if (!(delta >= 0) || !Number.isFinite(delta)) return void 0;
|
|
16813
17387
|
return delta / 100;
|
|
16814
17388
|
}
|
|
16815
|
-
function
|
|
17389
|
+
function asRecord6(value) {
|
|
16816
17390
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
16817
17391
|
return value;
|
|
16818
17392
|
}
|
|
16819
17393
|
return void 0;
|
|
16820
17394
|
}
|
|
16821
17395
|
function normalizeCursorToolCall(name, args) {
|
|
16822
|
-
const raw =
|
|
17396
|
+
const raw = asRecord6(args);
|
|
16823
17397
|
const toolName = typeof raw?.toolName === "string" && raw.toolName.trim() ? raw.toolName.trim() : null;
|
|
16824
|
-
const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" ||
|
|
17398
|
+
const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" || asRecord6(raw?.args) != null);
|
|
16825
17399
|
if (looksLikeMcp && toolName) {
|
|
16826
17400
|
const providerRaw = typeof raw.providerIdentifier === "string" && raw.providerIdentifier.trim() ? raw.providerIdentifier.trim() : "sideboard";
|
|
16827
17401
|
const provider = providerRaw.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
16828
|
-
const nested =
|
|
17402
|
+
const nested = asRecord6(raw.args);
|
|
16829
17403
|
return {
|
|
16830
17404
|
name: `mcp__${provider}__${toolName}`,
|
|
16831
17405
|
input: nested ?? { toolName }
|
|
@@ -16836,7 +17410,7 @@ function normalizeCursorToolCall(name, args) {
|
|
|
16836
17410
|
function unwrapCursorToolResult(result) {
|
|
16837
17411
|
if (result == null) return void 0;
|
|
16838
17412
|
if (typeof result === "string") return result;
|
|
16839
|
-
const rec =
|
|
17413
|
+
const rec = asRecord6(result);
|
|
16840
17414
|
if (!rec) {
|
|
16841
17415
|
try {
|
|
16842
17416
|
return JSON.stringify(result);
|
|
@@ -16847,18 +17421,18 @@ function unwrapCursorToolResult(result) {
|
|
|
16847
17421
|
const collectTexts = (items) => {
|
|
16848
17422
|
const texts = [];
|
|
16849
17423
|
for (const item of items) {
|
|
16850
|
-
const row2 =
|
|
17424
|
+
const row2 = asRecord6(item);
|
|
16851
17425
|
if (!row2) continue;
|
|
16852
17426
|
if (typeof row2.text === "string") {
|
|
16853
17427
|
texts.push(row2.text);
|
|
16854
17428
|
continue;
|
|
16855
17429
|
}
|
|
16856
|
-
const nested =
|
|
17430
|
+
const nested = asRecord6(row2.text);
|
|
16857
17431
|
if (typeof nested?.text === "string") texts.push(nested.text);
|
|
16858
17432
|
}
|
|
16859
17433
|
return texts;
|
|
16860
17434
|
};
|
|
16861
|
-
const value =
|
|
17435
|
+
const value = asRecord6(rec.value);
|
|
16862
17436
|
if (value && Array.isArray(value.content)) {
|
|
16863
17437
|
const texts = collectTexts(value.content);
|
|
16864
17438
|
if (texts.length) return texts.join("\n");
|
|
@@ -16875,10 +17449,10 @@ function unwrapCursorToolResult(result) {
|
|
|
16875
17449
|
}
|
|
16876
17450
|
function cursorToolResultIsError(status, result) {
|
|
16877
17451
|
if (status === "error") return true;
|
|
16878
|
-
const rec =
|
|
17452
|
+
const rec = asRecord6(result);
|
|
16879
17453
|
if (!rec) return false;
|
|
16880
17454
|
if (rec.status === "error") return true;
|
|
16881
|
-
const value =
|
|
17455
|
+
const value = asRecord6(rec.value);
|
|
16882
17456
|
return value?.isError === true;
|
|
16883
17457
|
}
|
|
16884
17458
|
function cursorSdkMessageToEvents(msg) {
|
|
@@ -17097,7 +17671,7 @@ function entryDir2() {
|
|
|
17097
17671
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
17098
17672
|
if (cjsDir) return cjsDir;
|
|
17099
17673
|
try {
|
|
17100
|
-
return (0, import_node_path45.dirname)((0, import_node_url4.fileURLToPath)(
|
|
17674
|
+
return (0, import_node_path45.dirname)((0, import_node_url4.fileURLToPath)(import_meta7.url));
|
|
17101
17675
|
} catch {
|
|
17102
17676
|
try {
|
|
17103
17677
|
const req = (0, import_node_module5.createRequire)(process.cwd() + "/");
|
|
@@ -17126,7 +17700,7 @@ function cursorRunnerPath() {
|
|
|
17126
17700
|
}
|
|
17127
17701
|
return candidates[0];
|
|
17128
17702
|
}
|
|
17129
|
-
var import_node_fs43, import_node_module5, import_node_path45, import_node_url4,
|
|
17703
|
+
var import_node_fs43, import_node_module5, import_node_path45, import_node_url4, import_meta7, FALLBACK_CURSOR_MODELS, cachedModels, MODEL_CACHE_MS, cursorAdapter;
|
|
17130
17704
|
var init_cursor = __esm({
|
|
17131
17705
|
"src/agents/cursor.ts"() {
|
|
17132
17706
|
"use strict";
|
|
@@ -17146,7 +17720,7 @@ var init_cursor = __esm({
|
|
|
17146
17720
|
init_packaged_runtime();
|
|
17147
17721
|
init_turn_input();
|
|
17148
17722
|
init_cursor_events();
|
|
17149
|
-
|
|
17723
|
+
import_meta7 = {};
|
|
17150
17724
|
FALLBACK_CURSOR_MODELS = [
|
|
17151
17725
|
{ id: "default", displayName: "Auto" },
|
|
17152
17726
|
{ id: "composer-2.5", displayName: "Composer 2.5" },
|
|
@@ -17420,7 +17994,7 @@ var init_opencode_host = __esm({
|
|
|
17420
17994
|
});
|
|
17421
17995
|
|
|
17422
17996
|
// src/agents/opencode.ts
|
|
17423
|
-
function
|
|
17997
|
+
function asRecord7(value) {
|
|
17424
17998
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
17425
17999
|
return value;
|
|
17426
18000
|
}
|
|
@@ -17616,7 +18190,7 @@ var init_opencode = __esm({
|
|
|
17616
18190
|
const name = part?.tool ?? part?.name ?? obj.tool ?? obj.name ?? "tool";
|
|
17617
18191
|
const state = part?.state;
|
|
17618
18192
|
const input = (state?.input && typeof state.input === "object" ? state.input : void 0) ?? part?.input ?? obj.input;
|
|
17619
|
-
const metadata =
|
|
18193
|
+
const metadata = asRecord7(state?.metadata);
|
|
17620
18194
|
const id = opencodeToolId(
|
|
17621
18195
|
name,
|
|
17622
18196
|
part?.callID ?? part?.id ?? obj.id,
|
|
@@ -17651,7 +18225,7 @@ var init_opencode = __esm({
|
|
|
17651
18225
|
}
|
|
17652
18226
|
if (obj.type === "subtask_event") {
|
|
17653
18227
|
const parentId = str4(obj.childSessionID) ?? str4(obj.childSessionId);
|
|
17654
|
-
const part =
|
|
18228
|
+
const part = asRecord7(obj.part);
|
|
17655
18229
|
if (!parentId || !part) return null;
|
|
17656
18230
|
if (part.type === "text" && str4(part.text)) {
|
|
17657
18231
|
return withTaskParent(
|
|
@@ -17662,8 +18236,8 @@ var init_opencode = __esm({
|
|
|
17662
18236
|
if (part.type === "tool" || str4(part.tool)) {
|
|
17663
18237
|
const name = str4(part.tool) ?? str4(part.name) ?? "tool";
|
|
17664
18238
|
const id = str4(part.callID) ?? str4(part.id) ?? `${parentId}-${name}`;
|
|
17665
|
-
const state =
|
|
17666
|
-
const input =
|
|
18239
|
+
const state = asRecord7(part.state);
|
|
18240
|
+
const input = asRecord7(state?.input) ?? asRecord7(part.input);
|
|
17667
18241
|
const nested = [
|
|
17668
18242
|
withEventParentId({ type: "tool_use", id, name, input }, parentId)
|
|
17669
18243
|
];
|
|
@@ -20081,7 +20655,7 @@ function forkMessageSlice(from, throughIndex) {
|
|
|
20081
20655
|
function buildForkTranscriptAttachment(baseTitle, messages) {
|
|
20082
20656
|
const title = baseTitle || "Chat";
|
|
20083
20657
|
return {
|
|
20084
|
-
id: (0,
|
|
20658
|
+
id: (0, import_node_crypto13.randomUUID)(),
|
|
20085
20659
|
name: `Transcript of ${title}.md`,
|
|
20086
20660
|
kind: "transcript",
|
|
20087
20661
|
content: formatTranscriptMarkdown(title, messages)
|
|
@@ -20140,11 +20714,11 @@ function forkChatTab(input) {
|
|
|
20140
20714
|
}
|
|
20141
20715
|
return tab;
|
|
20142
20716
|
}
|
|
20143
|
-
var
|
|
20717
|
+
var import_node_crypto13;
|
|
20144
20718
|
var init_chat_tabs = __esm({
|
|
20145
20719
|
"src/threads/chat-tabs.ts"() {
|
|
20146
20720
|
"use strict";
|
|
20147
|
-
|
|
20721
|
+
import_node_crypto13 = require("crypto");
|
|
20148
20722
|
init_context_compact();
|
|
20149
20723
|
init_teams();
|
|
20150
20724
|
init_worktree_labels();
|
|
@@ -20443,7 +21017,7 @@ function buildReviewRequestAttachment(content, opts) {
|
|
|
20443
21017
|
const path2 = opts?.path ?? REVIEW_SKILL_PATH;
|
|
20444
21018
|
const name = opts?.name ?? (path2 === REVIEW_SKILL_PATH ? REVIEW_SKILL_NAME : path2 === REPO_REVIEW_PATH || path2 === CONTEXT_REVIEW_PATH ? REPO_REVIEW_NAME : REVIEW_REQUEST_NAME);
|
|
20445
21019
|
return {
|
|
20446
|
-
id: (0,
|
|
21020
|
+
id: (0, import_node_crypto14.randomUUID)(),
|
|
20447
21021
|
name,
|
|
20448
21022
|
kind: "file",
|
|
20449
21023
|
path: path2,
|
|
@@ -20499,11 +21073,11 @@ async function requestReview(threadRef, send3) {
|
|
|
20499
21073
|
const started = await send3(tab.id, REVIEW_REQUEST_PREFILL);
|
|
20500
21074
|
return { tab: started, from };
|
|
20501
21075
|
}
|
|
20502
|
-
var
|
|
21076
|
+
var import_node_crypto14, import_node_fs49, import_node_path50, REPO_REVIEW_PATH, REPO_REVIEW_NAME, CONTEXT_REVIEW_PATH, REVIEW_REQUEST_PATH, LEGACY_REVIEW_REQUEST_PATH, REVIEW_REQUEST_NAME, REVIEW_REQUEST_PREFILL, LEGACY_REVIEW_TEMPLATE_MARKERS;
|
|
20503
21077
|
var init_request_review = __esm({
|
|
20504
21078
|
"src/review/request-review.ts"() {
|
|
20505
21079
|
"use strict";
|
|
20506
|
-
|
|
21080
|
+
import_node_crypto14 = require("crypto");
|
|
20507
21081
|
import_node_fs49 = require("fs");
|
|
20508
21082
|
import_node_path50 = require("path");
|
|
20509
21083
|
init_global_workspace();
|
|
@@ -22052,8 +22626,28 @@ var init_clone_repo = __esm({
|
|
|
22052
22626
|
}
|
|
22053
22627
|
});
|
|
22054
22628
|
|
|
22629
|
+
// src/mcp-ui/model-context.ts
|
|
22630
|
+
function stashMcpAppModelContext(threadId, text7) {
|
|
22631
|
+
const body = text7.trim().slice(0, 8e3);
|
|
22632
|
+
if (!body) return;
|
|
22633
|
+
updateThread(threadId, { mcpAppModelContext: body });
|
|
22634
|
+
}
|
|
22635
|
+
function takeMcpAppModelContext(threadId) {
|
|
22636
|
+
const thread = readThread(threadId);
|
|
22637
|
+
const text7 = thread?.mcpAppModelContext?.trim();
|
|
22638
|
+
if (!text7) return void 0;
|
|
22639
|
+
updateThread(threadId, { mcpAppModelContext: null });
|
|
22640
|
+
return text7;
|
|
22641
|
+
}
|
|
22642
|
+
var init_model_context = __esm({
|
|
22643
|
+
"src/mcp-ui/model-context.ts"() {
|
|
22644
|
+
"use strict";
|
|
22645
|
+
init_thread_store();
|
|
22646
|
+
}
|
|
22647
|
+
});
|
|
22648
|
+
|
|
22055
22649
|
// src/plan/plan-present.ts
|
|
22056
|
-
function
|
|
22650
|
+
function asRecord8(v) {
|
|
22057
22651
|
return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
22058
22652
|
}
|
|
22059
22653
|
function isPresentPlanToolName(name) {
|
|
@@ -22072,7 +22666,7 @@ function extractPresentedPlan(parts) {
|
|
|
22072
22666
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
22073
22667
|
const p = parts[i];
|
|
22074
22668
|
if (p.type !== "tool" || !isPresentPlanToolName(p.name)) continue;
|
|
22075
|
-
const input =
|
|
22669
|
+
const input = asRecord8(p.input) ?? {};
|
|
22076
22670
|
const content = typeof input.content === "string" ? input.content : typeof input.plan === "string" ? input.plan : typeof input.markdown === "string" ? input.markdown : "";
|
|
22077
22671
|
if (!content.trim()) continue;
|
|
22078
22672
|
const title = typeof input.title === "string" && input.title.trim() ? input.title.trim() : "Plan";
|
|
@@ -22527,7 +23121,7 @@ function isUnclaimedSteerRequest(req) {
|
|
|
22527
23121
|
}
|
|
22528
23122
|
function nextSteerRequest(existing) {
|
|
22529
23123
|
if (existing?.requestId && !existing.claimedAt) return existing;
|
|
22530
|
-
return { requestId: (0,
|
|
23124
|
+
return { requestId: (0, import_node_crypto15.randomUUID)(), requestedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
22531
23125
|
}
|
|
22532
23126
|
function claimSteerRequest(threadId) {
|
|
22533
23127
|
const pending = readThread(threadId)?.steerRequest;
|
|
@@ -22536,11 +23130,11 @@ function claimSteerRequest(threadId) {
|
|
|
22536
23130
|
steerRequest: { ...pending, claimedAt: (/* @__PURE__ */ new Date()).toISOString() }
|
|
22537
23131
|
});
|
|
22538
23132
|
}
|
|
22539
|
-
var
|
|
23133
|
+
var import_node_crypto15;
|
|
22540
23134
|
var init_steer_request = __esm({
|
|
22541
23135
|
"src/orchestrator/steer-request.ts"() {
|
|
22542
23136
|
"use strict";
|
|
22543
|
-
|
|
23137
|
+
import_node_crypto15 = require("crypto");
|
|
22544
23138
|
init_thread_store();
|
|
22545
23139
|
}
|
|
22546
23140
|
});
|
|
@@ -22785,8 +23379,8 @@ function resolveAbleTimeOAuthHost(requested, saved) {
|
|
|
22785
23379
|
return fromSaved || void 0;
|
|
22786
23380
|
}
|
|
22787
23381
|
function createAbleTimePkce() {
|
|
22788
|
-
const verifier = (0,
|
|
22789
|
-
const challenge = (0,
|
|
23382
|
+
const verifier = (0, import_node_crypto16.randomBytes)(32).toString("base64url");
|
|
23383
|
+
const challenge = (0, import_node_crypto16.createHash)("sha256").update(verifier).digest("base64url");
|
|
22790
23384
|
return { verifier, challenge };
|
|
22791
23385
|
}
|
|
22792
23386
|
function ableTimeOAuthAuthorizeUrl(clientId, state, codeChallenge, host) {
|
|
@@ -22891,7 +23485,7 @@ async function startAbleTimeOAuth(opts) {
|
|
|
22891
23485
|
opts?.host,
|
|
22892
23486
|
loadAppSettings().integrations.abletimeHost
|
|
22893
23487
|
);
|
|
22894
|
-
const state = (0,
|
|
23488
|
+
const state = (0, import_node_crypto16.randomBytes)(16).toString("hex");
|
|
22895
23489
|
const pkce = createAbleTimePkce();
|
|
22896
23490
|
const authorizeUrl = ableTimeOAuthAuthorizeUrl(clientId, state, pkce.challenge, host);
|
|
22897
23491
|
const timeoutMs = opts?.timeoutMs ?? 5 * 6e4;
|
|
@@ -22904,7 +23498,7 @@ async function startAbleTimeOAuth(opts) {
|
|
|
22904
23498
|
if (err) reject(err);
|
|
22905
23499
|
else resolve3(value);
|
|
22906
23500
|
};
|
|
22907
|
-
const server = (0,
|
|
23501
|
+
const server = (0, import_node_http2.createServer)((req, res) => {
|
|
22908
23502
|
try {
|
|
22909
23503
|
const url = new URL(req.url || "/", `http://127.0.0.1:${ABLETIME_OAUTH_PORT}`);
|
|
22910
23504
|
if (url.pathname !== "/callback") {
|
|
@@ -22991,12 +23585,12 @@ async function startAbleTimeOAuth(opts) {
|
|
|
22991
23585
|
return loadAppSettings();
|
|
22992
23586
|
}
|
|
22993
23587
|
}
|
|
22994
|
-
var
|
|
23588
|
+
var import_node_crypto16, import_node_http2, ABLETIME_OAUTH_CALLBACK_PATH, ABLETIME_OAUTH_PORT, ABLETIME_OAUTH_LOCAL_CALLBACK, ABLETIME_OAUTH_REDIRECT, BOUNCE_QUERY_KEYS, BAKED_ABLETIME_OAUTH_CLIENT_ID, ABLETIME_OAUTH_RESOURCE, REFRESH_SKEW_MS2, refreshInFlight2, ABLETIME_OAUTH_CANCELLED, AbleTimeOAuthCancelledError;
|
|
22995
23589
|
var init_abletime_oauth = __esm({
|
|
22996
23590
|
"src/integrations/abletime-oauth.ts"() {
|
|
22997
23591
|
"use strict";
|
|
22998
|
-
|
|
22999
|
-
|
|
23592
|
+
import_node_crypto16 = require("crypto");
|
|
23593
|
+
import_node_http2 = require("http");
|
|
23000
23594
|
init_fetch();
|
|
23001
23595
|
init_app_settings();
|
|
23002
23596
|
init_abletime_mcp();
|
|
@@ -23029,7 +23623,7 @@ __export(abletime_rest_exports, {
|
|
|
23029
23623
|
looksLikeAbleTimeUlid: () => looksLikeAbleTimeUlid,
|
|
23030
23624
|
textFromAbleTimeDoc: () => textFromAbleTimeDoc
|
|
23031
23625
|
});
|
|
23032
|
-
function
|
|
23626
|
+
function asRecord9(value) {
|
|
23033
23627
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
23034
23628
|
}
|
|
23035
23629
|
function asString(value) {
|
|
@@ -23037,7 +23631,7 @@ function asString(value) {
|
|
|
23037
23631
|
}
|
|
23038
23632
|
function asList(value) {
|
|
23039
23633
|
if (Array.isArray(value)) return value;
|
|
23040
|
-
const record =
|
|
23634
|
+
const record = asRecord9(value);
|
|
23041
23635
|
if (!record) return [];
|
|
23042
23636
|
for (const key of ["data", "tasks", "projects", "users", "items", "results"]) {
|
|
23043
23637
|
if (Array.isArray(record[key])) return record[key];
|
|
@@ -23054,12 +23648,12 @@ function ableTimeDocFromText(text7) {
|
|
|
23054
23648
|
}
|
|
23055
23649
|
function textFromAbleTimeDoc(value) {
|
|
23056
23650
|
if (typeof value === "string") return value.trim();
|
|
23057
|
-
const record =
|
|
23651
|
+
const record = asRecord9(value);
|
|
23058
23652
|
if (!record) return "";
|
|
23059
23653
|
if (typeof record.text === "string" && record.text.trim()) return record.text.trim();
|
|
23060
23654
|
const chunks = [];
|
|
23061
23655
|
const walk = (node) => {
|
|
23062
|
-
const rec =
|
|
23656
|
+
const rec = asRecord9(node);
|
|
23063
23657
|
if (!rec) return;
|
|
23064
23658
|
if (typeof rec.text === "string" && rec.text) chunks.push(rec.text);
|
|
23065
23659
|
if (Array.isArray(rec.content)) rec.content.forEach(walk);
|
|
@@ -23121,7 +23715,7 @@ async function restPages(path2, opts, maxPages = 20) {
|
|
|
23121
23715
|
query: { ...opts.query, ...cursor ? { cursor } : {} }
|
|
23122
23716
|
});
|
|
23123
23717
|
items.push(...asList(raw));
|
|
23124
|
-
const page =
|
|
23718
|
+
const page = asRecord9(asRecord9(raw)?.page);
|
|
23125
23719
|
const next = page ? asString(page.nextCursor) : "";
|
|
23126
23720
|
if (!next) break;
|
|
23127
23721
|
cursor = next;
|
|
@@ -23129,7 +23723,7 @@ async function restPages(path2, opts, maxPages = 20) {
|
|
|
23129
23723
|
return items;
|
|
23130
23724
|
}
|
|
23131
23725
|
function userDisplayName(raw) {
|
|
23132
|
-
const rec =
|
|
23726
|
+
const rec = asRecord9(raw);
|
|
23133
23727
|
if (!rec) return null;
|
|
23134
23728
|
const id = asString(rec.userId) || asString(rec.id);
|
|
23135
23729
|
const name = [asString(rec.firstName), asString(rec.lastName)].filter(Boolean).join(" ") || asString(rec.username) || asString(rec.email) || asString(rec.name);
|
|
@@ -23137,7 +23731,7 @@ function userDisplayName(raw) {
|
|
|
23137
23731
|
return { id: id || void 0, name };
|
|
23138
23732
|
}
|
|
23139
23733
|
function restTaskToRaw(raw, users) {
|
|
23140
|
-
const rec =
|
|
23734
|
+
const rec = asRecord9(raw);
|
|
23141
23735
|
if (!rec) return null;
|
|
23142
23736
|
const id = asString(rec.timeflowTaskId) || asString(rec.taskId) || asString(rec.id);
|
|
23143
23737
|
const identifier = asString(rec.taskRef) || asString(rec.reference) || id;
|
|
@@ -23145,7 +23739,7 @@ function restTaskToRaw(raw, users) {
|
|
|
23145
23739
|
if (!id && !identifier && !title) return null;
|
|
23146
23740
|
const assignee = users.get(asString(rec.assignedUserId));
|
|
23147
23741
|
const comments = asList(rec.comments).map((item) => {
|
|
23148
|
-
const comment =
|
|
23742
|
+
const comment = asRecord9(item) ?? {};
|
|
23149
23743
|
const user = userDisplayName(comment);
|
|
23150
23744
|
return {
|
|
23151
23745
|
id: asString(comment.commentId) || asString(comment.id),
|
|
@@ -23175,13 +23769,13 @@ function restTaskToRaw(raw, users) {
|
|
|
23175
23769
|
};
|
|
23176
23770
|
}
|
|
23177
23771
|
function restProjectToRaw(raw) {
|
|
23178
|
-
const rec =
|
|
23772
|
+
const rec = asRecord9(raw);
|
|
23179
23773
|
if (!rec) return null;
|
|
23180
23774
|
const id = asString(rec.projectId) || asString(rec.id);
|
|
23181
23775
|
const name = asString(rec.projectName) || asString(rec.name);
|
|
23182
23776
|
if (!id && !name) return null;
|
|
23183
23777
|
const categories = asList(rec.categories).map((item) => {
|
|
23184
|
-
const cat =
|
|
23778
|
+
const cat = asRecord9(item) ?? {};
|
|
23185
23779
|
return {
|
|
23186
23780
|
id: asString(cat.projectCategoryId) || asString(cat.categoryId) || asString(cat.id),
|
|
23187
23781
|
name: asString(cat.categoryName) || asString(cat.name)
|
|
@@ -23193,7 +23787,7 @@ async function listUsers(opts) {
|
|
|
23193
23787
|
const users = /* @__PURE__ */ new Map();
|
|
23194
23788
|
for (const item of await restPages("/users", opts).catch(() => [])) {
|
|
23195
23789
|
const user = userDisplayName(item);
|
|
23196
|
-
const rec =
|
|
23790
|
+
const rec = asRecord9(item);
|
|
23197
23791
|
const id = user?.id || (rec ? asString(rec.userId) : "");
|
|
23198
23792
|
if (user && id) users.set(id, user);
|
|
23199
23793
|
}
|
|
@@ -23319,10 +23913,10 @@ async function callAbleTimeRestTool(name, args = {}, opts) {
|
|
|
23319
23913
|
if (!project) throw new Error("AbleTime has no projects to create a task in");
|
|
23320
23914
|
const categories = asList(project.categories);
|
|
23321
23915
|
const wantedCategory = firstStringArg(args, ["category_id", "categoryId", "category"]);
|
|
23322
|
-
const category = categories.map((item) =>
|
|
23916
|
+
const category = categories.map((item) => asRecord9(item)).find((item) => {
|
|
23323
23917
|
if (!item || !wantedCategory) return false;
|
|
23324
23918
|
return asString(item.id).toLowerCase() === wantedCategory.toLowerCase() || asString(item.name).toLowerCase() === wantedCategory.toLowerCase();
|
|
23325
|
-
}) ??
|
|
23919
|
+
}) ?? asRecord9(categories[0]);
|
|
23326
23920
|
const parentArg = firstStringArg(args, ["parent", "parent_id", "parentId", "related_task_id"]);
|
|
23327
23921
|
const parentTaskId = parentArg ? await resolveRestParentTaskId(parentArg, requestOpts) : void 0;
|
|
23328
23922
|
const created = await abletimeRestRequest("/tasks", {
|
|
@@ -23336,7 +23930,7 @@ async function callAbleTimeRestTool(name, args = {}, opts) {
|
|
|
23336
23930
|
}
|
|
23337
23931
|
});
|
|
23338
23932
|
const state = firstStringArg(args, ["state"]);
|
|
23339
|
-
const createdId = asString(
|
|
23933
|
+
const createdId = asString(asRecord9(created)?.timeflowTaskId);
|
|
23340
23934
|
const description = asString(args.description);
|
|
23341
23935
|
if (createdId && description) {
|
|
23342
23936
|
await abletimeRestRequest(`/tasks/${encodeURIComponent(createdId)}`, {
|
|
@@ -23409,7 +24003,7 @@ async function callAbleTimeRestTool(name, args = {}, opts) {
|
|
|
23409
24003
|
method: "POST",
|
|
23410
24004
|
body: { content: ableTimeDocFromText(body) }
|
|
23411
24005
|
});
|
|
23412
|
-
const rec =
|
|
24006
|
+
const rec = asRecord9(created) ?? {};
|
|
23413
24007
|
return {
|
|
23414
24008
|
id: asString(rec.commentId) || void 0,
|
|
23415
24009
|
body: textFromAbleTimeDoc(rec.content) || body
|
|
@@ -23504,7 +24098,7 @@ function rewriteAbleTimeError(message) {
|
|
|
23504
24098
|
}
|
|
23505
24099
|
return message;
|
|
23506
24100
|
}
|
|
23507
|
-
function
|
|
24101
|
+
function asRecord10(value) {
|
|
23508
24102
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
23509
24103
|
}
|
|
23510
24104
|
function parseSseJson(body) {
|
|
@@ -23526,12 +24120,12 @@ function parseSseJson(body) {
|
|
|
23526
24120
|
}
|
|
23527
24121
|
}
|
|
23528
24122
|
function unwrapToolResult(result) {
|
|
23529
|
-
const record =
|
|
24123
|
+
const record = asRecord10(result);
|
|
23530
24124
|
if (!record) return result;
|
|
23531
24125
|
const content = record.content;
|
|
23532
24126
|
if (Array.isArray(content)) {
|
|
23533
24127
|
const texts = content.map((part) => {
|
|
23534
|
-
const item =
|
|
24128
|
+
const item = asRecord10(part);
|
|
23535
24129
|
if (!item) return "";
|
|
23536
24130
|
return typeof item.text === "string" ? item.text : "";
|
|
23537
24131
|
}).filter(Boolean);
|
|
@@ -23553,7 +24147,7 @@ function unwrapToolResult(result) {
|
|
|
23553
24147
|
return result;
|
|
23554
24148
|
}
|
|
23555
24149
|
function textsFromUnknown(value) {
|
|
23556
|
-
const record =
|
|
24150
|
+
const record = asRecord10(value);
|
|
23557
24151
|
if (!record) return "";
|
|
23558
24152
|
if (typeof record.message === "string") return record.message;
|
|
23559
24153
|
if (typeof record.error === "string") return record.error;
|
|
@@ -23600,7 +24194,7 @@ async function abletimeMcpRequest(method, params, opts) {
|
|
|
23600
24194
|
return parseSseJson(body);
|
|
23601
24195
|
}
|
|
23602
24196
|
})();
|
|
23603
|
-
const rpc =
|
|
24197
|
+
const rpc = asRecord10(parsed);
|
|
23604
24198
|
if (rpc?.error) {
|
|
23605
24199
|
const detail = typeof rpc.error.message === "string" && rpc.error.message.trim() ? rpc.error.message : `AbleTime MCP error ${rpc.error.code ?? ""}`.trim();
|
|
23606
24200
|
throw new Error(rewriteAbleTimeError(detail));
|
|
@@ -23755,7 +24349,7 @@ function uniqueAttachmentFileName(dir, originalName) {
|
|
|
23755
24349
|
const candidate = `${stem}-${i}${ext}`;
|
|
23756
24350
|
if (!(0, import_node_fs55.existsSync)((0, import_node_path56.join)(dir, candidate))) return candidate;
|
|
23757
24351
|
}
|
|
23758
|
-
return `${stem}-${(0,
|
|
24352
|
+
return `${stem}-${(0, import_node_crypto17.randomUUID)()}${ext}`;
|
|
23759
24353
|
}
|
|
23760
24354
|
function extractHttpUrls(markdown) {
|
|
23761
24355
|
const text7 = markdown ?? "";
|
|
@@ -23861,13 +24455,13 @@ async function downloadAuthenticatedFile(opts) {
|
|
|
23861
24455
|
...contentType ? { contentType } : {}
|
|
23862
24456
|
};
|
|
23863
24457
|
}
|
|
23864
|
-
var import_node_fs55, import_node_path56,
|
|
24458
|
+
var import_node_fs55, import_node_path56, import_node_crypto17, ISSUE_ATTACHMENT_MAX_BYTES, MARKDOWN_IMAGE_RE, MARKDOWN_LINK_RE, HTML_SRC_RE, BARE_URL_RE, EXT_BY_MIME;
|
|
23865
24459
|
var init_issue_attachments = __esm({
|
|
23866
24460
|
"src/integrations/issue-attachments.ts"() {
|
|
23867
24461
|
"use strict";
|
|
23868
24462
|
import_node_fs55 = require("fs");
|
|
23869
24463
|
import_node_path56 = require("path");
|
|
23870
|
-
|
|
24464
|
+
import_node_crypto17 = require("crypto");
|
|
23871
24465
|
init_fetch();
|
|
23872
24466
|
init_workspace_scratch();
|
|
23873
24467
|
ISSUE_ATTACHMENT_MAX_BYTES = 25 * 1024 * 1024;
|
|
@@ -23892,7 +24486,7 @@ var init_issue_attachments = __esm({
|
|
|
23892
24486
|
});
|
|
23893
24487
|
|
|
23894
24488
|
// src/integrations/abletime-attachments.ts
|
|
23895
|
-
function
|
|
24489
|
+
function asRecord11(value) {
|
|
23896
24490
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
23897
24491
|
}
|
|
23898
24492
|
function asString2(value) {
|
|
@@ -23900,7 +24494,7 @@ function asString2(value) {
|
|
|
23900
24494
|
}
|
|
23901
24495
|
function asList2(value) {
|
|
23902
24496
|
if (Array.isArray(value)) return value;
|
|
23903
|
-
const record =
|
|
24497
|
+
const record = asRecord11(value);
|
|
23904
24498
|
if (!record) return [];
|
|
23905
24499
|
for (const key of ["data", "tasks", "projects", "items", "results", "nodes"]) {
|
|
23906
24500
|
if (Array.isArray(record[key])) return record[key];
|
|
@@ -23919,9 +24513,9 @@ function filesFromAbleTimeDoc(value) {
|
|
|
23919
24513
|
const out = [];
|
|
23920
24514
|
const seen = /* @__PURE__ */ new Set();
|
|
23921
24515
|
const walk = (node) => {
|
|
23922
|
-
const rec =
|
|
24516
|
+
const rec = asRecord11(node);
|
|
23923
24517
|
if (!rec) return;
|
|
23924
|
-
const attrs =
|
|
24518
|
+
const attrs = asRecord11(rec.attrs) ?? rec;
|
|
23925
24519
|
const url = asString2(attrs.src) || asString2(attrs.href) || asString2(attrs.url) || asString2(attrs.fileUrl) || asString2(attrs.downloadUrl);
|
|
23926
24520
|
if (url && !seen.has(url)) {
|
|
23927
24521
|
seen.add(url);
|
|
@@ -23939,7 +24533,7 @@ function filesFromAbleTimeDoc(value) {
|
|
|
23939
24533
|
function listedAbleTimeFiles(raw) {
|
|
23940
24534
|
const out = [];
|
|
23941
24535
|
for (const item of asList2(raw)) {
|
|
23942
|
-
const rec =
|
|
24536
|
+
const rec = asRecord11(item);
|
|
23943
24537
|
if (!rec) continue;
|
|
23944
24538
|
const url = firstString(rec, ["url", "href", "src", "fileUrl", "downloadUrl", "permalink"]);
|
|
23945
24539
|
if (!url) continue;
|
|
@@ -23959,7 +24553,7 @@ function mapAbleTimeAttachments(record) {
|
|
|
23959
24553
|
...filesFromAbleTimeDoc(record.description),
|
|
23960
24554
|
...filesFromAbleTimeDoc(record.content),
|
|
23961
24555
|
...asList2(record.comments).flatMap((item) => {
|
|
23962
|
-
const rec =
|
|
24556
|
+
const rec = asRecord11(item);
|
|
23963
24557
|
return rec ? filesFromAbleTimeDoc(rec.content ?? rec.body) : [];
|
|
23964
24558
|
})
|
|
23965
24559
|
].map((file) => ({
|
|
@@ -24001,7 +24595,7 @@ async function resolveAbleTimeAttachmentUrl(id, opts) {
|
|
|
24001
24595
|
const json = await res.json().catch(() => null);
|
|
24002
24596
|
const rec = json && typeof json === "object" && !Array.isArray(json) ? json.data && typeof json.data === "object" ? json.data : json : null;
|
|
24003
24597
|
if (!rec) continue;
|
|
24004
|
-
const url = firstString(rec, ["url", "href", "src", "fileUrl", "downloadUrl"]) || firstString(
|
|
24598
|
+
const url = firstString(rec, ["url", "href", "src", "fileUrl", "downloadUrl"]) || firstString(asRecord11(rec.file), ["url", "href"]);
|
|
24005
24599
|
if (url) {
|
|
24006
24600
|
return {
|
|
24007
24601
|
url,
|
|
@@ -24043,7 +24637,7 @@ var init_abletime_attachments = __esm({
|
|
|
24043
24637
|
});
|
|
24044
24638
|
|
|
24045
24639
|
// src/integrations/abletime-projects.ts
|
|
24046
|
-
function
|
|
24640
|
+
function asRecord12(value) {
|
|
24047
24641
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
24048
24642
|
}
|
|
24049
24643
|
function firstString2(record, keys) {
|
|
@@ -24056,7 +24650,7 @@ function firstString2(record, keys) {
|
|
|
24056
24650
|
}
|
|
24057
24651
|
function asList3(value) {
|
|
24058
24652
|
if (Array.isArray(value)) return value;
|
|
24059
|
-
const record =
|
|
24653
|
+
const record = asRecord12(value);
|
|
24060
24654
|
if (!record) return [];
|
|
24061
24655
|
for (const key of ["data", "tasks", "projects", "items", "results", "nodes"]) {
|
|
24062
24656
|
if (Array.isArray(record[key])) return record[key];
|
|
@@ -24064,7 +24658,7 @@ function asList3(value) {
|
|
|
24064
24658
|
return [];
|
|
24065
24659
|
}
|
|
24066
24660
|
function ableTimeProjectFields(nested) {
|
|
24067
|
-
const projectRecord =
|
|
24661
|
+
const projectRecord = asRecord12(nested.project);
|
|
24068
24662
|
const projectId = firstString2(nested, ["project_id", "projectId"]) || firstString2(projectRecord, ["id"]) || void 0;
|
|
24069
24663
|
const projectName = firstString2(nested, ["project_name", "projectName"]) || firstString2(projectRecord, ["name", "title"]) || void 0;
|
|
24070
24664
|
if (!projectId && !projectName) return {};
|
|
@@ -24077,13 +24671,13 @@ function ableTimeProjectFields(nested) {
|
|
|
24077
24671
|
};
|
|
24078
24672
|
}
|
|
24079
24673
|
function mapAbleTimeProject(raw) {
|
|
24080
|
-
const record =
|
|
24674
|
+
const record = asRecord12(raw);
|
|
24081
24675
|
if (!record) return null;
|
|
24082
24676
|
const id = firstString2(record, ["id", "project_id", "projectId"]);
|
|
24083
24677
|
const name = firstString2(record, ["name", "title", "projectName"]);
|
|
24084
24678
|
if (!id && !name) return null;
|
|
24085
24679
|
const categories = asList3(record.categories ?? record.category).map((item) => {
|
|
24086
|
-
const rec =
|
|
24680
|
+
const rec = asRecord12(item);
|
|
24087
24681
|
if (!rec) return null;
|
|
24088
24682
|
const categoryId = firstString2(rec, ["id", "category_id", "projectCategoryId", "categoryId"]);
|
|
24089
24683
|
const categoryName = firstString2(rec, ["name", "title", "categoryName"]);
|
|
@@ -24119,7 +24713,7 @@ __export(abletime_exports, {
|
|
|
24119
24713
|
updateAbleTimeTask: () => updateAbleTimeTask,
|
|
24120
24714
|
verifyAbleTimeConnection: () => verifyAbleTimeConnection
|
|
24121
24715
|
});
|
|
24122
|
-
function
|
|
24716
|
+
function asRecord13(value) {
|
|
24123
24717
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
24124
24718
|
}
|
|
24125
24719
|
function asString3(value) {
|
|
@@ -24136,14 +24730,14 @@ function firstString3(record, keys) {
|
|
|
24136
24730
|
function firstRecord(record, keys) {
|
|
24137
24731
|
if (!record) return null;
|
|
24138
24732
|
for (const key of keys) {
|
|
24139
|
-
const value =
|
|
24733
|
+
const value = asRecord13(record[key]);
|
|
24140
24734
|
if (value) return value;
|
|
24141
24735
|
}
|
|
24142
24736
|
return null;
|
|
24143
24737
|
}
|
|
24144
24738
|
function asList4(value) {
|
|
24145
24739
|
if (Array.isArray(value)) return value;
|
|
24146
|
-
const record =
|
|
24740
|
+
const record = asRecord13(value);
|
|
24147
24741
|
if (!record) return [];
|
|
24148
24742
|
for (const key of ["data", "tasks", "projects", "items", "results", "nodes"]) {
|
|
24149
24743
|
if (Array.isArray(record[key])) return record[key];
|
|
@@ -24155,18 +24749,18 @@ function labelsOf(record) {
|
|
|
24155
24749
|
if (!Array.isArray(raw)) return [];
|
|
24156
24750
|
return raw.map((item) => {
|
|
24157
24751
|
if (typeof item === "string") return item.trim();
|
|
24158
|
-
const rec =
|
|
24752
|
+
const rec = asRecord13(item);
|
|
24159
24753
|
return rec ? firstString3(rec, ["name", "title", "label"]) : "";
|
|
24160
24754
|
}).filter(Boolean);
|
|
24161
24755
|
}
|
|
24162
24756
|
function commentsOf(record) {
|
|
24163
24757
|
const out = [];
|
|
24164
24758
|
for (const item of asList4(record.comments ?? record.notes ?? record.discussion)) {
|
|
24165
|
-
const rec =
|
|
24759
|
+
const rec = asRecord13(item);
|
|
24166
24760
|
if (!rec) continue;
|
|
24167
24761
|
const body = firstString3(rec, ["body", "text", "comment", "message", "contentSanitized"]) || textFromAbleTimeDoc(rec.content);
|
|
24168
24762
|
if (!body) continue;
|
|
24169
|
-
const user = firstString3(
|
|
24763
|
+
const user = firstString3(asRecord13(rec.user) ?? asRecord13(rec.author), ["name", "display_name", "username"]) || firstString3(rec, ["user_name", "author", "username"]);
|
|
24170
24764
|
const id = firstString3(rec, ["id", "comment_id", "commentId"]);
|
|
24171
24765
|
const url = firstString3(rec, ["url", "permalink"]);
|
|
24172
24766
|
const createdAt = firstString3(rec, ["created_at", "createdAt", "created"]);
|
|
@@ -24193,7 +24787,7 @@ function taskUrl(task, host) {
|
|
|
24193
24787
|
return `${base}/tasks/${slug}`;
|
|
24194
24788
|
}
|
|
24195
24789
|
function mapAbleTimeTask(raw, host) {
|
|
24196
|
-
const record =
|
|
24790
|
+
const record = asRecord13(raw);
|
|
24197
24791
|
if (!record) return null;
|
|
24198
24792
|
const nested = firstRecord(record, ["task", "data"]) ?? record;
|
|
24199
24793
|
const id = firstString3(nested, ["id", "task_id", "taskId", "timeflowTaskId"]);
|
|
@@ -24211,7 +24805,7 @@ function mapAbleTimeTask(raw, host) {
|
|
|
24211
24805
|
description: firstString3(nested, ["description", "body", "details", "descriptionSanitized"]) || textFromAbleTimeDoc(nested.description) || void 0,
|
|
24212
24806
|
state: firstString3(nested, ["state", "board_state", "boardState", "status", "taskState"]) || void 0,
|
|
24213
24807
|
...ableTimeProjectFields(nested),
|
|
24214
|
-
categoryId: firstString3(nested, ["category_id", "categoryId", "projectCategoryId"]) || firstString3(
|
|
24808
|
+
categoryId: firstString3(nested, ["category_id", "categoryId", "projectCategoryId"]) || firstString3(asRecord13(nested.category), ["id"]) || void 0,
|
|
24215
24809
|
assignee: assigneeOf(nested),
|
|
24216
24810
|
labels: labelsOf(nested),
|
|
24217
24811
|
comments: commentsOf(nested),
|
|
@@ -24261,7 +24855,7 @@ function isOpenTask(task) {
|
|
|
24261
24855
|
}
|
|
24262
24856
|
async function getAbleTimeOrientation(opts) {
|
|
24263
24857
|
const raw = await callAbleTimeTool("orientation", {}, opts);
|
|
24264
|
-
const record =
|
|
24858
|
+
const record = asRecord13(raw);
|
|
24265
24859
|
const viewerRec = firstRecord(record, ["viewer", "principal", "user", "actor", "me", "person"]) ?? record;
|
|
24266
24860
|
const viewer = {
|
|
24267
24861
|
id: firstString3(viewerRec, ["id", "user_id"]) || void 0,
|
|
@@ -24340,7 +24934,7 @@ async function commentAbleTimeTask(input, opts) {
|
|
|
24340
24934
|
{ id, task_id: id, task: id, body, comment: body, text: body },
|
|
24341
24935
|
opts
|
|
24342
24936
|
);
|
|
24343
|
-
const rec =
|
|
24937
|
+
const rec = asRecord13(raw);
|
|
24344
24938
|
return {
|
|
24345
24939
|
id: rec ? firstString3(rec, ["id", "comment_id"]) || void 0 : void 0,
|
|
24346
24940
|
body: rec ? firstString3(rec, ["body", "text", "comment"]) || body : body
|
|
@@ -25493,7 +26087,7 @@ function buildQuotaHandoffAttachment(from, limitText, fallbackAgent) {
|
|
|
25493
26087
|
...instructions
|
|
25494
26088
|
].join("\n");
|
|
25495
26089
|
return {
|
|
25496
|
-
id: (0,
|
|
26090
|
+
id: (0, import_node_crypto18.randomUUID)(),
|
|
25497
26091
|
name: orch ? "Orchestration quota handoff.md" : "Quota handoff.md",
|
|
25498
26092
|
kind: "transcript",
|
|
25499
26093
|
content: body
|
|
@@ -25525,11 +26119,11 @@ function createQuotaFailoverChat(from, fallbackAgent, limitText, opts) {
|
|
|
25525
26119
|
}
|
|
25526
26120
|
return updateThread(tab.id, patch);
|
|
25527
26121
|
}
|
|
25528
|
-
var
|
|
26122
|
+
var import_node_crypto18, QUOTA_CONTINUE_PROMPT, QUOTA_CONTINUE_ACCOUNT_PROMPT, QUOTA_RESUME_PROMPT;
|
|
25529
26123
|
var init_quota_failover = __esm({
|
|
25530
26124
|
"src/orchestrator/quota-failover.ts"() {
|
|
25531
26125
|
"use strict";
|
|
25532
|
-
|
|
26126
|
+
import_node_crypto18 = require("crypto");
|
|
25533
26127
|
init_session_quota();
|
|
25534
26128
|
init_app_settings();
|
|
25535
26129
|
init_managed_accounts();
|
|
@@ -27605,7 +28199,7 @@ function compiledModuleDir() {
|
|
|
27605
28199
|
const cjsDir = typeof __dirname !== "undefined" ? __dirname : "";
|
|
27606
28200
|
if (cjsDir) return cjsDir;
|
|
27607
28201
|
try {
|
|
27608
|
-
const url =
|
|
28202
|
+
const url = import_meta8.url;
|
|
27609
28203
|
if (typeof url === "string" && url.length > 0) {
|
|
27610
28204
|
return (0, import_node_path62.dirname)((0, import_node_url5.fileURLToPath)(url));
|
|
27611
28205
|
}
|
|
@@ -27644,7 +28238,7 @@ function formatDetachedJobInvoke(scriptPath) {
|
|
|
27644
28238
|
if (resolved) return `node ${JSON.stringify(resolved)}`;
|
|
27645
28239
|
return "node scripts/detached-job.cjs";
|
|
27646
28240
|
}
|
|
27647
|
-
var import_node_fs63, import_node_path62, import_node_url5,
|
|
28241
|
+
var import_node_fs63, import_node_path62, import_node_url5, import_meta8, DETACHED_JOB_FILENAMES;
|
|
27648
28242
|
var init_detached_job_path = __esm({
|
|
27649
28243
|
"src/skills/detached-job-path.ts"() {
|
|
27650
28244
|
"use strict";
|
|
@@ -27652,7 +28246,7 @@ var init_detached_job_path = __esm({
|
|
|
27652
28246
|
import_node_path62 = require("path");
|
|
27653
28247
|
import_node_url5 = require("url");
|
|
27654
28248
|
init_packaged_runtime();
|
|
27655
|
-
|
|
28249
|
+
import_meta8 = {};
|
|
27656
28250
|
DETACHED_JOB_FILENAMES = ["detached-job.cjs", "detached-job.js"];
|
|
27657
28251
|
}
|
|
27658
28252
|
});
|
|
@@ -28052,7 +28646,7 @@ function normalizeServiceOrigin(raw, fallback) {
|
|
|
28052
28646
|
return fallback;
|
|
28053
28647
|
}
|
|
28054
28648
|
}
|
|
28055
|
-
function
|
|
28649
|
+
function asRecord14(value) {
|
|
28056
28650
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
28057
28651
|
}
|
|
28058
28652
|
function asString4(value) {
|
|
@@ -28085,7 +28679,7 @@ async function authorizedGet(url, token) {
|
|
|
28085
28679
|
});
|
|
28086
28680
|
const body = await readJson2(res);
|
|
28087
28681
|
if (!res.ok) {
|
|
28088
|
-
const record =
|
|
28682
|
+
const record = asRecord14(body);
|
|
28089
28683
|
const message = firstString4(record, ["message", "error", "error_description", "detail"]) || (typeof body === "string" ? body.trim().slice(0, 160) : "");
|
|
28090
28684
|
throw new Error(
|
|
28091
28685
|
message ? `${res.status}: ${message}` : `Request failed (${res.status})`
|
|
@@ -28099,28 +28693,28 @@ async function verifyOptionalService(input) {
|
|
|
28099
28693
|
const spec = optionalServiceSpec(input.id);
|
|
28100
28694
|
try {
|
|
28101
28695
|
if (input.id === "vercel") {
|
|
28102
|
-
const body2 =
|
|
28103
|
-
const user =
|
|
28696
|
+
const body2 = asRecord14(await authorizedGet("https://api.vercel.com/v2/user", token));
|
|
28697
|
+
const user = asRecord14(body2?.user) ?? body2;
|
|
28104
28698
|
const name2 = firstString4(user, ["username", "name", "email"]) || "Vercel user";
|
|
28105
28699
|
return { viewerName: name2 };
|
|
28106
28700
|
}
|
|
28107
28701
|
if (input.id === "supabase") {
|
|
28108
28702
|
const body2 = await authorizedGet("https://api.supabase.com/v1/organizations", token);
|
|
28109
28703
|
const list2 = Array.isArray(body2) ? body2 : [];
|
|
28110
|
-
const first2 =
|
|
28704
|
+
const first2 = asRecord14(list2[0]);
|
|
28111
28705
|
const name2 = firstString4(first2, ["name", "slug"]) || "Supabase";
|
|
28112
28706
|
return { viewerName: list2.length > 1 ? `${name2} +${list2.length - 1}` : name2 };
|
|
28113
28707
|
}
|
|
28114
28708
|
if (input.id === "posthog") {
|
|
28115
28709
|
const host2 = normalizeServiceOrigin(input.host, spec.defaultHost ?? "https://us.posthog.com");
|
|
28116
|
-
const body2 =
|
|
28710
|
+
const body2 = asRecord14(await authorizedGet(`${host2}/api/users/@me/`, token));
|
|
28117
28711
|
const name2 = firstString4(body2, ["email", "distinct_id"]) || [firstString4(body2, ["first_name"]), firstString4(body2, ["last_name"])].filter(Boolean).join(" ") || "PostHog user";
|
|
28118
28712
|
return { viewerName: name2, host: host2 };
|
|
28119
28713
|
}
|
|
28120
28714
|
const host = normalizeServiceOrigin(input.host, spec.defaultHost ?? "https://sentry.io");
|
|
28121
28715
|
const body = await authorizedGet(`${host}/api/0/organizations/`, token);
|
|
28122
28716
|
const list = Array.isArray(body) ? body : [];
|
|
28123
|
-
const first =
|
|
28717
|
+
const first = asRecord14(list[0]);
|
|
28124
28718
|
const name = firstString4(first, ["slug", "name"]) || "Sentry";
|
|
28125
28719
|
return { viewerName: list.length > 1 ? `${name} +${list.length - 1}` : name, host };
|
|
28126
28720
|
} catch (err) {
|
|
@@ -28994,10 +29588,10 @@ function collectActiveRunPorts(runs) {
|
|
|
28994
29588
|
return [...ports];
|
|
28995
29589
|
}
|
|
28996
29590
|
function getOrchestrator() {
|
|
28997
|
-
if (!
|
|
28998
|
-
|
|
29591
|
+
if (!singleton2) {
|
|
29592
|
+
singleton2 = new Orchestrator();
|
|
28999
29593
|
}
|
|
29000
|
-
return
|
|
29594
|
+
return singleton2;
|
|
29001
29595
|
}
|
|
29002
29596
|
async function startOrchestration(opts) {
|
|
29003
29597
|
const repoPath = opts.repoPath?.trim();
|
|
@@ -29057,7 +29651,7 @@ async function startOrchestration(opts) {
|
|
|
29057
29651
|
}
|
|
29058
29652
|
return updated;
|
|
29059
29653
|
}
|
|
29060
|
-
var import_node_events,
|
|
29654
|
+
var import_node_events, import_node_crypto19, import_node_fs67, LIVE_TURN_SPAWN_GRACE_MS, RUN_SCRIPT_DESKTOP_ADOPT_MS, STALE_AGENT_PID_WAIT_MS, LIGHT_RECONCILE_THROTTLE_MS, Orchestrator, singleton2;
|
|
29061
29655
|
var init_orchestrator = __esm({
|
|
29062
29656
|
"src/orchestrator/orchestrator.ts"() {
|
|
29063
29657
|
"use strict";
|
|
@@ -29065,7 +29659,7 @@ var init_orchestrator = __esm({
|
|
|
29065
29659
|
init_injected_notices();
|
|
29066
29660
|
init_task_state();
|
|
29067
29661
|
init_wait_for_turn();
|
|
29068
|
-
|
|
29662
|
+
import_node_crypto19 = require("crypto");
|
|
29069
29663
|
import_node_fs67 = require("fs");
|
|
29070
29664
|
init_error_detail();
|
|
29071
29665
|
init_run();
|
|
@@ -29091,6 +29685,7 @@ var init_orchestrator = __esm({
|
|
|
29091
29685
|
init_usage();
|
|
29092
29686
|
init_thread_store();
|
|
29093
29687
|
init_desktop_host();
|
|
29688
|
+
init_model_context();
|
|
29094
29689
|
init_agent_block();
|
|
29095
29690
|
init_child_halt();
|
|
29096
29691
|
init_stop_reason();
|
|
@@ -30089,6 +30684,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
30089
30684
|
orchestrationReminder,
|
|
30090
30685
|
prGateDirective,
|
|
30091
30686
|
injectedNoticeContext,
|
|
30687
|
+
takeMcpAppModelContext(threadId),
|
|
30092
30688
|
expandedPrompt
|
|
30093
30689
|
].filter(Boolean).join("\n\n");
|
|
30094
30690
|
if (!autoContinue && sentAttachments) {
|
|
@@ -30717,7 +31313,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
30717
31313
|
const request = sameIntent ? pending : {
|
|
30718
31314
|
op,
|
|
30719
31315
|
scriptName: scriptName ?? null,
|
|
30720
|
-
requestId: (0,
|
|
31316
|
+
requestId: (0, import_node_crypto19.randomUUID)(),
|
|
30721
31317
|
requestedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
30722
31318
|
};
|
|
30723
31319
|
if (!sameIntent) {
|
|
@@ -31838,7 +32434,7 @@ ${formatEnvReminder(projectNameForRepoPath(thread.repoPath || thread.worktreePat
|
|
|
31838
32434
|
return thread;
|
|
31839
32435
|
}
|
|
31840
32436
|
};
|
|
31841
|
-
|
|
32437
|
+
singleton2 = null;
|
|
31842
32438
|
}
|
|
31843
32439
|
});
|
|
31844
32440
|
|
|
@@ -32955,6 +33551,7 @@ __export(index_exports, {
|
|
|
32955
33551
|
startRelayServer: () => startRelayServer,
|
|
32956
33552
|
startRemoteAccountLogin: () => startRemoteAccountLogin,
|
|
32957
33553
|
startSlackOAuth: () => startSlackOAuth,
|
|
33554
|
+
stashMcpAppModelContext: () => stashMcpAppModelContext,
|
|
32958
33555
|
statWorktreePath: () => statWorktreePath,
|
|
32959
33556
|
stopAgentRpcServer: () => stopAgentRpcServer,
|
|
32960
33557
|
stripBrightsyNdjsonNoise: () => stripBrightsyNdjsonNoise,
|
|
@@ -33521,7 +34118,7 @@ init_schedule_runner();
|
|
|
33521
34118
|
|
|
33522
34119
|
// src/host/serve.ts
|
|
33523
34120
|
var import_node_child_process7 = require("child_process");
|
|
33524
|
-
var
|
|
34121
|
+
var import_node_os21 = require("os");
|
|
33525
34122
|
init_system_ca();
|
|
33526
34123
|
init_app_settings();
|
|
33527
34124
|
init_desktop_host();
|
|
@@ -33534,7 +34131,7 @@ init_system_ca();
|
|
|
33534
34131
|
|
|
33535
34132
|
// src/slack/public-dns.ts
|
|
33536
34133
|
var import_node_dns = require("dns");
|
|
33537
|
-
var
|
|
34134
|
+
var import_node_http3 = require("http");
|
|
33538
34135
|
var import_node_https = require("https");
|
|
33539
34136
|
var PUBLIC_DNS = ["1.1.1.1", "8.8.8.8"];
|
|
33540
34137
|
function finishLookup(options, callback, address, family) {
|
|
@@ -33664,213 +34261,12 @@ function buildPathRefAttachment(input) {
|
|
|
33664
34261
|
init_stage_files();
|
|
33665
34262
|
init_orchestrator();
|
|
33666
34263
|
|
|
33667
|
-
// src/mcp-ui
|
|
33668
|
-
|
|
33669
|
-
|
|
33670
|
-
init_meta();
|
|
33671
|
-
|
|
33672
|
-
// src/mcp-ui/session.ts
|
|
33673
|
-
var import_client2 = require("@modelcontextprotocol/sdk/client/index.js");
|
|
33674
|
-
var import_sse = require("@modelcontextprotocol/sdk/client/sse.js");
|
|
33675
|
-
var import_stdio = require("@modelcontextprotocol/sdk/client/stdio.js");
|
|
33676
|
-
var import_streamableHttp = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
33677
|
-
init_meta();
|
|
33678
|
-
var REQUEST_TIMEOUT_MS = 2e4;
|
|
33679
|
-
var UI_CAPABILITIES = {
|
|
33680
|
-
extensions: {
|
|
33681
|
-
"io.modelcontextprotocol/ui": {
|
|
33682
|
-
mimeTypes: ["text/html;profile=mcp-app"]
|
|
33683
|
-
}
|
|
33684
|
-
}
|
|
33685
|
-
};
|
|
33686
|
-
async function openMcpUiSession(launch) {
|
|
33687
|
-
return openMcpUiSessionFromTransport(transportForLaunch(launch));
|
|
33688
|
-
}
|
|
33689
|
-
async function openMcpUiSessionFromTransport(transport) {
|
|
33690
|
-
const client = new import_client2.Client(
|
|
33691
|
-
{ name: "sideboard", version: "1.0.0" },
|
|
33692
|
-
{ capabilities: UI_CAPABILITIES }
|
|
33693
|
-
);
|
|
33694
|
-
await client.connect(transport, { timeout: REQUEST_TIMEOUT_MS });
|
|
33695
|
-
return {
|
|
33696
|
-
async listTools() {
|
|
33697
|
-
const listed = await client.listTools(void 0, { timeout: REQUEST_TIMEOUT_MS });
|
|
33698
|
-
return listed.tools.map((tool) => {
|
|
33699
|
-
const meta = tool._meta;
|
|
33700
|
-
return {
|
|
33701
|
-
name: tool.name,
|
|
33702
|
-
...tool.description ? { description: tool.description } : {},
|
|
33703
|
-
...tool.inputSchema ? { inputSchema: tool.inputSchema } : {},
|
|
33704
|
-
resourceUri: uiResourceUriFromMeta(meta),
|
|
33705
|
-
...cspFromMeta(meta) ? { csp: cspFromMeta(meta) } : {}
|
|
33706
|
-
};
|
|
33707
|
-
});
|
|
33708
|
-
},
|
|
33709
|
-
async readResource(uri) {
|
|
33710
|
-
const result = await client.readResource({ uri }, { timeout: REQUEST_TIMEOUT_MS });
|
|
33711
|
-
const content = result.contents?.[0];
|
|
33712
|
-
if (!content) return null;
|
|
33713
|
-
const text7 = "text" in content && typeof content.text === "string" ? content.text : void 0;
|
|
33714
|
-
const blob = "blob" in content && typeof content.blob === "string" ? content.blob : void 0;
|
|
33715
|
-
return {
|
|
33716
|
-
uri: content.uri,
|
|
33717
|
-
...content.mimeType ? { mimeType: content.mimeType } : {},
|
|
33718
|
-
...text7 != null ? { text: text7 } : {},
|
|
33719
|
-
...blob != null ? { blob } : {},
|
|
33720
|
-
...cspFromMeta(content._meta) ? { csp: cspFromMeta(content._meta) } : {}
|
|
33721
|
-
};
|
|
33722
|
-
},
|
|
33723
|
-
async callTool(name, args) {
|
|
33724
|
-
return client.callTool({ name, arguments: args }, void 0, { timeout: REQUEST_TIMEOUT_MS });
|
|
33725
|
-
},
|
|
33726
|
-
async close() {
|
|
33727
|
-
await client.close();
|
|
33728
|
-
}
|
|
33729
|
-
};
|
|
33730
|
-
}
|
|
33731
|
-
function transportForLaunch(launch) {
|
|
33732
|
-
if (launch.kind === "stdio") {
|
|
33733
|
-
return new import_stdio.StdioClientTransport({
|
|
33734
|
-
command: launch.command,
|
|
33735
|
-
args: launch.args,
|
|
33736
|
-
env: { ...(0, import_stdio.getDefaultEnvironment)(), ...launch.env },
|
|
33737
|
-
stderr: "ignore",
|
|
33738
|
-
...launch.cwd ? { cwd: launch.cwd } : {}
|
|
33739
|
-
});
|
|
33740
|
-
}
|
|
33741
|
-
const url = new URL(launch.url);
|
|
33742
|
-
const requestInit = launch.headers ? { headers: launch.headers } : void 0;
|
|
33743
|
-
if (launch.kind === "sse") {
|
|
33744
|
-
return new import_sse.SSEClientTransport(url, requestInit ? { requestInit } : void 0);
|
|
33745
|
-
}
|
|
33746
|
-
return new import_streamableHttp.StreamableHTTPClientTransport(url, requestInit ? { requestInit } : void 0);
|
|
33747
|
-
}
|
|
33748
|
-
|
|
33749
|
-
// src/mcp-ui/host.ts
|
|
33750
|
-
var TOOL_TTL_MS = 5 * 60 * 1e3;
|
|
33751
|
-
var McpUiHost = class {
|
|
33752
|
-
constructor(opts) {
|
|
33753
|
-
this.opts = opts;
|
|
33754
|
-
}
|
|
33755
|
-
opts;
|
|
33756
|
-
sessions = /* @__PURE__ */ new Map();
|
|
33757
|
-
toolLists = /* @__PURE__ */ new Map();
|
|
33758
|
-
async viewForClaudeTool(toolName, projectDirs) {
|
|
33759
|
-
const entries = this.userEntries(projectDirs);
|
|
33760
|
-
const match = matchClaudeMcpTool(toolName, Object.keys(entries));
|
|
33761
|
-
if (!match) return null;
|
|
33762
|
-
const launch = parseMcpServerLaunch(entries[match.server] ?? {});
|
|
33763
|
-
if (!launch) return null;
|
|
33764
|
-
try {
|
|
33765
|
-
const session = await this.sessionFor(match.server, launch);
|
|
33766
|
-
const tools = await this.toolsFor(match.server, launch, session);
|
|
33767
|
-
const tool = tools.find((item) => item.name === match.tool);
|
|
33768
|
-
if (!tool?.resourceUri) return null;
|
|
33769
|
-
const resource = await session.readResource(tool.resourceUri);
|
|
33770
|
-
if (!resource) return null;
|
|
33771
|
-
const html = htmlFromResourceContent(resource);
|
|
33772
|
-
if (!html) return null;
|
|
33773
|
-
const csp = resource.csp ?? tool.csp;
|
|
33774
|
-
return {
|
|
33775
|
-
server: match.server,
|
|
33776
|
-
tool: match.tool,
|
|
33777
|
-
uri: html.uri,
|
|
33778
|
-
mimeType: html.mimeType,
|
|
33779
|
-
html: html.html,
|
|
33780
|
-
csp: mcpUiContentSecurityPolicy(csp)
|
|
33781
|
-
};
|
|
33782
|
-
} catch (err) {
|
|
33783
|
-
console.error(
|
|
33784
|
-
`[mcp-ui] ${match.server}/${match.tool}:`,
|
|
33785
|
-
err instanceof Error ? err.message : err
|
|
33786
|
-
);
|
|
33787
|
-
return null;
|
|
33788
|
-
}
|
|
33789
|
-
}
|
|
33790
|
-
async callTool(server, tool, args, projectDirs) {
|
|
33791
|
-
const session = await this.sessionForName(server, projectDirs);
|
|
33792
|
-
if (!session) throw new Error(`MCP server ${server} is not available`);
|
|
33793
|
-
return session.callTool(tool, args);
|
|
33794
|
-
}
|
|
33795
|
-
async readResource(server, uri, projectDirs) {
|
|
33796
|
-
const session = await this.sessionForName(server, projectDirs);
|
|
33797
|
-
if (!session) throw new Error(`MCP server ${server} is not available`);
|
|
33798
|
-
const resource = await session.readResource(uri);
|
|
33799
|
-
if (!resource) throw new Error(`Resource ${uri} was empty`);
|
|
33800
|
-
return {
|
|
33801
|
-
contents: [
|
|
33802
|
-
{
|
|
33803
|
-
uri: resource.uri,
|
|
33804
|
-
...resource.mimeType ? { mimeType: resource.mimeType } : {},
|
|
33805
|
-
...resource.text != null ? { text: resource.text } : {},
|
|
33806
|
-
...resource.blob != null ? { blob: resource.blob } : {}
|
|
33807
|
-
}
|
|
33808
|
-
]
|
|
33809
|
-
};
|
|
33810
|
-
}
|
|
33811
|
-
async closeAll() {
|
|
33812
|
-
const pending = [...this.sessions.values()];
|
|
33813
|
-
this.sessions.clear();
|
|
33814
|
-
this.toolLists.clear();
|
|
33815
|
-
await Promise.all(
|
|
33816
|
-
pending.map((session) => session.then((open) => open.close()).catch(() => void 0))
|
|
33817
|
-
);
|
|
33818
|
-
}
|
|
33819
|
-
userEntries(projectDirs) {
|
|
33820
|
-
const out = {};
|
|
33821
|
-
for (const [name, entry] of Object.entries(this.opts.entries(projectDirs))) {
|
|
33822
|
-
if (!name.trim() || isInjectedOrchMcpName(name) || !entry) continue;
|
|
33823
|
-
out[name] = entry;
|
|
33824
|
-
}
|
|
33825
|
-
return out;
|
|
33826
|
-
}
|
|
33827
|
-
async sessionForName(server, projectDirs) {
|
|
33828
|
-
const entry = this.userEntries(projectDirs)[server];
|
|
33829
|
-
if (!entry) return null;
|
|
33830
|
-
const launch = parseMcpServerLaunch(entry);
|
|
33831
|
-
if (!launch) return null;
|
|
33832
|
-
return this.sessionFor(server, launch);
|
|
33833
|
-
}
|
|
33834
|
-
sessionFor(server, launch) {
|
|
33835
|
-
const key = `${server}
|
|
33836
|
-
${JSON.stringify(launch)}`;
|
|
33837
|
-
const existing = this.sessions.get(key);
|
|
33838
|
-
if (existing) return existing;
|
|
33839
|
-
const open = this.opts.openSession ?? openMcpUiSession;
|
|
33840
|
-
const pending = open(launch).catch((err) => {
|
|
33841
|
-
this.sessions.delete(key);
|
|
33842
|
-
throw err;
|
|
33843
|
-
});
|
|
33844
|
-
this.sessions.set(key, pending);
|
|
33845
|
-
return pending;
|
|
33846
|
-
}
|
|
33847
|
-
async toolsFor(server, launch, session) {
|
|
33848
|
-
const key = `${server}
|
|
33849
|
-
${JSON.stringify(launch)}`;
|
|
33850
|
-
const cached2 = this.toolLists.get(key);
|
|
33851
|
-
if (cached2 && cached2.key === key && Date.now() - cached2.at < TOOL_TTL_MS) return cached2.tools;
|
|
33852
|
-
const tools = await session.listTools();
|
|
33853
|
-
this.toolLists.set(key, { at: Date.now(), key, tools });
|
|
33854
|
-
return tools;
|
|
33855
|
-
}
|
|
33856
|
-
};
|
|
33857
|
-
var singleton2;
|
|
33858
|
-
function getMcpUiHost() {
|
|
33859
|
-
if (!singleton2) {
|
|
33860
|
-
singleton2 = new McpUiHost({
|
|
33861
|
-
entries: (projectDirs) => listUserClaudeMcpServerEntries((0, import_node_os21.homedir)(), projectDirs)
|
|
33862
|
-
});
|
|
33863
|
-
}
|
|
33864
|
-
return singleton2;
|
|
33865
|
-
}
|
|
33866
|
-
function closeMcpUiHost() {
|
|
33867
|
-
const host = singleton2;
|
|
33868
|
-
singleton2 = void 0;
|
|
33869
|
-
if (host) void host.closeAll();
|
|
33870
|
-
}
|
|
34264
|
+
// src/remote/phone-mcp-ui-listen.ts
|
|
34265
|
+
init_host();
|
|
34266
|
+
init_model_context();
|
|
33871
34267
|
|
|
33872
34268
|
// src/remote/phone-chats.ts
|
|
33873
|
-
var
|
|
34269
|
+
var import_node_crypto20 = require("crypto");
|
|
33874
34270
|
init_list_models();
|
|
33875
34271
|
init_home_board();
|
|
33876
34272
|
init_stage_files();
|
|
@@ -33892,10 +34288,10 @@ var MIN_MD_CHARS = 120;
|
|
|
33892
34288
|
function oneLine2(value, max) {
|
|
33893
34289
|
return value.replace(/[`\r\n]/g, " ").replace(/\s+/g, " ").trim().slice(0, max);
|
|
33894
34290
|
}
|
|
33895
|
-
function
|
|
34291
|
+
function asRecord15(value) {
|
|
33896
34292
|
if (typeof value === "string") {
|
|
33897
34293
|
try {
|
|
33898
|
-
return
|
|
34294
|
+
return asRecord15(JSON.parse(value));
|
|
33899
34295
|
} catch {
|
|
33900
34296
|
return void 0;
|
|
33901
34297
|
}
|
|
@@ -33970,7 +34366,7 @@ function toolContent(input) {
|
|
|
33970
34366
|
if (!input) return "";
|
|
33971
34367
|
const direct = input.content;
|
|
33972
34368
|
if (typeof direct === "string") return direct;
|
|
33973
|
-
const nested =
|
|
34369
|
+
const nested = asRecord15(direct);
|
|
33974
34370
|
if (!nested) return "";
|
|
33975
34371
|
for (const key of ["html", "markup", "text", "source", "content", "code"]) {
|
|
33976
34372
|
if (typeof nested[key] === "string") return nested[key];
|
|
@@ -33993,7 +34389,7 @@ function phoneArtifactText(text7, parts, limit = Number.POSITIVE_INFINITY) {
|
|
|
33993
34389
|
const extras = [];
|
|
33994
34390
|
for (const part of parts ?? []) {
|
|
33995
34391
|
if (part.type !== "tool" || part.parentId || !isArtifactTool(part.name)) continue;
|
|
33996
|
-
const input =
|
|
34392
|
+
const input = asRecord15(part.input);
|
|
33997
34393
|
const content = toolContent(input);
|
|
33998
34394
|
const hint = artifactHint(content);
|
|
33999
34395
|
if (hint && hints.has(hint)) continue;
|
|
@@ -34012,7 +34408,7 @@ function phoneArtifactText(text7, parts, limit = Number.POSITIVE_INFINITY) {
|
|
|
34012
34408
|
${tail}` : tail;
|
|
34013
34409
|
}
|
|
34014
34410
|
function parseOpenArtifact(value, chatId) {
|
|
34015
|
-
const record =
|
|
34411
|
+
const record = asRecord15(value);
|
|
34016
34412
|
if (!record) return "invalid";
|
|
34017
34413
|
const title = oneLine2(str5(record.title), 200);
|
|
34018
34414
|
if (!title) return "invalid";
|
|
@@ -34035,7 +34431,7 @@ function phoneArtifactDocuments(sources) {
|
|
|
34035
34431
|
}
|
|
34036
34432
|
for (const part of source.parts ?? []) {
|
|
34037
34433
|
if (part.type !== "tool" || part.parentId || !isArtifactTool(part.name)) continue;
|
|
34038
|
-
const input =
|
|
34434
|
+
const input = asRecord15(part.input);
|
|
34039
34435
|
const content = toolContent(input);
|
|
34040
34436
|
const hint = artifactHint(content);
|
|
34041
34437
|
if (hint && hints.has(hint)) continue;
|
|
@@ -34480,13 +34876,21 @@ function parsePhoneMcpUi(value, op, chatId) {
|
|
|
34480
34876
|
}
|
|
34481
34877
|
return { op: "mcp-ui", chatId, tool: tool2, callId, reqId: reqId2 };
|
|
34482
34878
|
}
|
|
34879
|
+
if (op === "mcp-ui-context") {
|
|
34880
|
+
const reqId2 = controlText(value, "reqId");
|
|
34881
|
+
const text7 = controlText(value, "text");
|
|
34882
|
+
if (!reqId2 || reqId2.length > 40 || !text7 || text7.length > 8e3) return "invalid";
|
|
34883
|
+
return { op, chatId, reqId: reqId2, text: text7 };
|
|
34884
|
+
}
|
|
34483
34885
|
if (op !== "mcp-ui-call" && op !== "mcp-ui-read") return "invalid";
|
|
34484
34886
|
const reqId = controlText(value, "reqId");
|
|
34485
34887
|
const server = controlText(value, "server");
|
|
34486
34888
|
if (!reqId || reqId.length > 40 || !server || server.length > 120) return "invalid";
|
|
34487
34889
|
if (op === "mcp-ui-read") {
|
|
34488
34890
|
const uri = controlText(value, "uri");
|
|
34489
|
-
if (!uri
|
|
34891
|
+
if (!uri || uri.length > 500 || /\s/.test(uri) || /^(javascript|data):/i.test(uri)) {
|
|
34892
|
+
return "invalid";
|
|
34893
|
+
}
|
|
34490
34894
|
return { op, chatId, reqId, server, uri };
|
|
34491
34895
|
}
|
|
34492
34896
|
const tool = controlText(value, "tool");
|
|
@@ -34708,7 +35112,7 @@ function parsePhoneControl(value) {
|
|
|
34708
35112
|
}
|
|
34709
35113
|
if (op === "pane") return parsePhonePane(value, chatId);
|
|
34710
35114
|
if (op === "open-artifact") return parseOpenArtifact(value, chatId);
|
|
34711
|
-
if (op === "mcp-ui" || op === "mcp-ui-call" || op === "mcp-ui-read") return parsePhoneMcpUi(value, op, chatId);
|
|
35115
|
+
if (op === "mcp-ui" || op === "mcp-ui-call" || op === "mcp-ui-read" || op === "mcp-ui-context") return parsePhoneMcpUi(value, op, chatId);
|
|
34712
35116
|
if (op === "open-file" || op === "media") {
|
|
34713
35117
|
const path2 = textField(value, "path");
|
|
34714
35118
|
if (!path2 || path2.length > 2e3) return "invalid";
|
|
@@ -34975,13 +35379,13 @@ function phoneComposerOptions(thread) {
|
|
|
34975
35379
|
}
|
|
34976
35380
|
function phoneTurnAttachments(draft) {
|
|
34977
35381
|
const links = (draft.links ?? []).map((link) => ({
|
|
34978
|
-
id: (0,
|
|
35382
|
+
id: (0, import_node_crypto20.randomUUID)(),
|
|
34979
35383
|
name: link.ref,
|
|
34980
35384
|
kind: "issue",
|
|
34981
35385
|
content: [`Linked issue: ${link.ref} \u2014 ${link.title}`, link.url ? `URL: ${link.url}` : null].filter(Boolean).join("\n")
|
|
34982
35386
|
}));
|
|
34983
35387
|
const files = (draft.files ?? []).map((file) => ({
|
|
34984
|
-
id: (0,
|
|
35388
|
+
id: (0, import_node_crypto20.randomUUID)(),
|
|
34985
35389
|
name: file.name,
|
|
34986
35390
|
kind: "file",
|
|
34987
35391
|
previewDataUrl: `data:application/octet-stream;base64,${file.dataBase64}`,
|
|
@@ -35317,7 +35721,9 @@ function deliverPhoneTurn(opts, chatId) {
|
|
|
35317
35721
|
// src/remote/phone-mcp-ui-listen.ts
|
|
35318
35722
|
var PHONE_HTML_CAP = 7e5;
|
|
35319
35723
|
function dispatchPhoneMcpUi(cmd, opts) {
|
|
35320
|
-
if (cmd.op !== "mcp-ui" && cmd.op !== "mcp-ui-call" && cmd.op !== "mcp-ui-read")
|
|
35724
|
+
if (cmd.op !== "mcp-ui" && cmd.op !== "mcp-ui-call" && cmd.op !== "mcp-ui-read" && cmd.op !== "mcp-ui-context") {
|
|
35725
|
+
return false;
|
|
35726
|
+
}
|
|
35321
35727
|
const thread = readPhoneThread(cmd.chatId);
|
|
35322
35728
|
const reqId = cmd.reqId;
|
|
35323
35729
|
const chatId = cmd.chatId;
|
|
@@ -35327,6 +35733,11 @@ function dispatchPhoneMcpUi(cmd, opts) {
|
|
|
35327
35733
|
return true;
|
|
35328
35734
|
}
|
|
35329
35735
|
const projectDirs = [thread.repoPath, thread.worktreePath];
|
|
35736
|
+
if (cmd.op === "mcp-ui-context") {
|
|
35737
|
+
stashMcpAppModelContext(thread.id, cmd.text);
|
|
35738
|
+
emitControl(opts, { op: "mcp-ui-context", chatId, reqId, result: {} });
|
|
35739
|
+
return true;
|
|
35740
|
+
}
|
|
35330
35741
|
if (cmd.op === "mcp-ui-call") {
|
|
35331
35742
|
void getMcpUiHost().callTool(cmd.server, cmd.tool, cmd.args, projectDirs).then((result) => emitControl(opts, { op: "mcp-ui-call", chatId, reqId, result })).catch(
|
|
35332
35743
|
(err) => emitControl(opts, { op: "mcp-ui-call", chatId, reqId, error: phoneError(err) })
|
|
@@ -36163,8 +36574,8 @@ init_fetch();
|
|
|
36163
36574
|
init_issue_attachments();
|
|
36164
36575
|
|
|
36165
36576
|
// src/integrations/linear-oauth.ts
|
|
36166
|
-
var
|
|
36167
|
-
var
|
|
36577
|
+
var import_node_crypto21 = require("crypto");
|
|
36578
|
+
var import_node_http4 = require("http");
|
|
36168
36579
|
init_app_settings();
|
|
36169
36580
|
init_fetch();
|
|
36170
36581
|
|
|
@@ -36195,8 +36606,8 @@ function linearOAuthCredentials() {
|
|
|
36195
36606
|
return { clientId, clientSecret };
|
|
36196
36607
|
}
|
|
36197
36608
|
function createLinearPkce() {
|
|
36198
|
-
const verifier = (0,
|
|
36199
|
-
const challenge = (0,
|
|
36609
|
+
const verifier = (0, import_node_crypto21.randomBytes)(32).toString("base64url");
|
|
36610
|
+
const challenge = (0, import_node_crypto21.createHash)("sha256").update(verifier).digest("base64url");
|
|
36200
36611
|
return { verifier, challenge };
|
|
36201
36612
|
}
|
|
36202
36613
|
function linearOAuthAuthorizeUrl(clientId, state, codeChallenge) {
|
|
@@ -36327,7 +36738,7 @@ async function startLinearOAuth(opts) {
|
|
|
36327
36738
|
throw new LinearOAuthCancelledError();
|
|
36328
36739
|
}
|
|
36329
36740
|
const { clientId, clientSecret } = linearOAuthCredentials();
|
|
36330
|
-
const state = (0,
|
|
36741
|
+
const state = (0, import_node_crypto21.randomBytes)(16).toString("hex");
|
|
36331
36742
|
const pkce = createLinearPkce();
|
|
36332
36743
|
const authorizeUrl = linearOAuthAuthorizeUrl(clientId, state, pkce.challenge);
|
|
36333
36744
|
const timeoutMs = opts?.timeoutMs ?? 5 * 6e4;
|
|
@@ -36340,7 +36751,7 @@ async function startLinearOAuth(opts) {
|
|
|
36340
36751
|
if (err) reject(err);
|
|
36341
36752
|
else resolve3(value);
|
|
36342
36753
|
};
|
|
36343
|
-
const server = (0,
|
|
36754
|
+
const server = (0, import_node_http4.createServer)((req, res) => {
|
|
36344
36755
|
try {
|
|
36345
36756
|
const url = new URL(req.url || "/", `http://127.0.0.1:${LINEAR_OAUTH_PORT}`);
|
|
36346
36757
|
if (url.pathname !== "/callback") {
|
|
@@ -38753,7 +39164,7 @@ function runRemoteHost(opts) {
|
|
|
38753
39164
|
init_protocol();
|
|
38754
39165
|
|
|
38755
39166
|
// src/relay/server.ts
|
|
38756
|
-
var
|
|
39167
|
+
var import_node_http5 = require("http");
|
|
38757
39168
|
var import_ws4 = require("ws");
|
|
38758
39169
|
|
|
38759
39170
|
// src/slack/oauth-redirect.ts
|
|
@@ -39162,7 +39573,7 @@ function connectSession(ws, opts, log) {
|
|
|
39162
39573
|
}
|
|
39163
39574
|
|
|
39164
39575
|
// src/slack/relay-protocol.ts
|
|
39165
|
-
var
|
|
39576
|
+
var import_node_crypto22 = require("crypto");
|
|
39166
39577
|
var SLACK_RELAY_PING_INTERVAL_MS = 2e4;
|
|
39167
39578
|
var SLACK_RELAY_PONG_TIMEOUT_MS = 15e3;
|
|
39168
39579
|
function slackRelaySessionKey(teamId, userId, deviceId) {
|
|
@@ -39172,7 +39583,7 @@ function slackRelayUserKey(teamId, userId) {
|
|
|
39172
39583
|
return `${teamId.trim()}:${userId.trim()}`;
|
|
39173
39584
|
}
|
|
39174
39585
|
function newSlackRelayEventId() {
|
|
39175
|
-
return (0,
|
|
39586
|
+
return (0, import_node_crypto22.randomBytes)(12).toString("hex");
|
|
39176
39587
|
}
|
|
39177
39588
|
function parseSlackRelayClientMessage(raw) {
|
|
39178
39589
|
try {
|
|
@@ -39700,7 +40111,7 @@ async function tryServeStatic(req, res, root) {
|
|
|
39700
40111
|
}
|
|
39701
40112
|
|
|
39702
40113
|
// src/remote/hub.ts
|
|
39703
|
-
var
|
|
40114
|
+
var import_node_crypto23 = require("crypto");
|
|
39704
40115
|
init_protocol();
|
|
39705
40116
|
var CODE_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
|
39706
40117
|
var CODE_TTL_MS = 10 * 60 * 1e3;
|
|
@@ -39711,7 +40122,7 @@ function send(socket, msg) {
|
|
|
39711
40122
|
}
|
|
39712
40123
|
}
|
|
39713
40124
|
function newCode() {
|
|
39714
|
-
const bytes = (0,
|
|
40125
|
+
const bytes = (0, import_node_crypto23.randomBytes)(6);
|
|
39715
40126
|
let code = "";
|
|
39716
40127
|
for (let i = 0; i < 6; i++) code += CODE_ALPHABET[bytes[i] % CODE_ALPHABET.length];
|
|
39717
40128
|
return code;
|
|
@@ -39970,7 +40381,7 @@ var RemoteHub = class {
|
|
|
39970
40381
|
host.phone = null;
|
|
39971
40382
|
}
|
|
39972
40383
|
const created = sessionToken == null;
|
|
39973
|
-
const token = sessionToken ?? (0,
|
|
40384
|
+
const token = sessionToken ?? (0, import_node_crypto23.randomBytes)(24).toString("hex");
|
|
39974
40385
|
if (host.sessionToken && host.sessionToken !== token) {
|
|
39975
40386
|
this.phonesByToken.delete(host.sessionToken);
|
|
39976
40387
|
}
|
|
@@ -40022,7 +40433,7 @@ var RemoteHub = class {
|
|
|
40022
40433
|
init_protocol();
|
|
40023
40434
|
|
|
40024
40435
|
// src/relay/accounts.ts
|
|
40025
|
-
var
|
|
40436
|
+
var import_node_crypto24 = require("crypto");
|
|
40026
40437
|
var import_node_fs70 = require("fs");
|
|
40027
40438
|
var import_node_module7 = require("module");
|
|
40028
40439
|
var import_node_path68 = require("path");
|
|
@@ -40041,12 +40452,12 @@ function openDatabase(filePath) {
|
|
|
40041
40452
|
return db;
|
|
40042
40453
|
}
|
|
40043
40454
|
function sha2562(value) {
|
|
40044
|
-
return (0,
|
|
40455
|
+
return (0, import_node_crypto24.createHash)("sha256").update(value).digest("hex");
|
|
40045
40456
|
}
|
|
40046
40457
|
function sameHash(a, b) {
|
|
40047
40458
|
const left = Buffer.from(a);
|
|
40048
40459
|
const right = Buffer.from(b);
|
|
40049
|
-
return left.length === right.length && (0,
|
|
40460
|
+
return left.length === right.length && (0, import_node_crypto24.timingSafeEqual)(left, right);
|
|
40050
40461
|
}
|
|
40051
40462
|
function normalizeEmail(email) {
|
|
40052
40463
|
const trimmed = email?.trim().toLowerCase() ?? "";
|
|
@@ -40151,7 +40562,7 @@ var RelayAccountStore = class {
|
|
|
40151
40562
|
this.insertIdentity(issuer, subject, accountId, email, verified);
|
|
40152
40563
|
} else {
|
|
40153
40564
|
const byEmail = verified ? this.accountIdForVerifiedEmail(email) : void 0;
|
|
40154
|
-
accountId = byEmail ?? (0,
|
|
40565
|
+
accountId = byEmail ?? (0, import_node_crypto24.randomUUID)();
|
|
40155
40566
|
if (!byEmail) {
|
|
40156
40567
|
this.db.prepare("INSERT INTO accounts (id, created_at, device_cap) VALUES (?, ?, ?)").run(accountId, Date.now(), RELAY_DEVICE_CAP);
|
|
40157
40568
|
}
|
|
@@ -40273,7 +40684,7 @@ var RelayAccountStore = class {
|
|
|
40273
40684
|
).run(issuer, subject, accountId, email, verified ? 1 : 0);
|
|
40274
40685
|
}
|
|
40275
40686
|
mintCredential(accountId) {
|
|
40276
|
-
const credential = (0,
|
|
40687
|
+
const credential = (0, import_node_crypto24.randomBytes)(32).toString("hex");
|
|
40277
40688
|
this.db.prepare("INSERT INTO credentials (token_hash, account_id, created_at) VALUES (?, ?, ?)").run(sha2562(credential), accountId, Date.now());
|
|
40278
40689
|
return credential;
|
|
40279
40690
|
}
|
|
@@ -40748,7 +41159,7 @@ async function startRelayServer(opts) {
|
|
|
40748
41159
|
sendJson2(res, 200, { ok: true, ...value.payload });
|
|
40749
41160
|
return true;
|
|
40750
41161
|
};
|
|
40751
|
-
const httpServer = (0,
|
|
41162
|
+
const httpServer = (0, import_node_http5.createServer)((req, res) => {
|
|
40752
41163
|
void (async () => {
|
|
40753
41164
|
const reqUrl = req.url || "/";
|
|
40754
41165
|
if (accountStore && await handleRelayAccountHttp({
|
|
@@ -41085,7 +41496,7 @@ async function bindAbort(signal, stop) {
|
|
|
41085
41496
|
}
|
|
41086
41497
|
function flatInterfaces() {
|
|
41087
41498
|
const out = [];
|
|
41088
|
-
for (const rows of Object.values((0,
|
|
41499
|
+
for (const rows of Object.values((0, import_node_os21.networkInterfaces)())) {
|
|
41089
41500
|
if (!rows) continue;
|
|
41090
41501
|
out.push(...rows);
|
|
41091
41502
|
}
|
|
@@ -41182,7 +41593,7 @@ init_stage_files();
|
|
|
41182
41593
|
init_consume_attachments();
|
|
41183
41594
|
|
|
41184
41595
|
// src/composer/pasted-text.ts
|
|
41185
|
-
var
|
|
41596
|
+
var import_node_crypto25 = require("crypto");
|
|
41186
41597
|
var PASTE_ATTACH_MIN_CHARS = 1200;
|
|
41187
41598
|
var PASTE_ATTACH_MIN_LINES = 15;
|
|
41188
41599
|
var PASTED_NAME_RE = /^Pasted text #(\d+)\.txt$/i;
|
|
@@ -41209,7 +41620,7 @@ function nextPastedTextName(existing) {
|
|
|
41209
41620
|
}
|
|
41210
41621
|
function buildPastedTextAttachment(text7, opts) {
|
|
41211
41622
|
return {
|
|
41212
|
-
id: opts?.id ?? (0,
|
|
41623
|
+
id: opts?.id ?? (0, import_node_crypto25.randomUUID)(),
|
|
41213
41624
|
name: opts?.name ?? "Pasted text #1.txt",
|
|
41214
41625
|
kind: "file",
|
|
41215
41626
|
path: opts?.path,
|
|
@@ -41385,7 +41796,7 @@ function createClippedMcpServer() {
|
|
|
41385
41796
|
|
|
41386
41797
|
// src/mcp/server.ts
|
|
41387
41798
|
var import_zod11 = require("zod");
|
|
41388
|
-
var
|
|
41799
|
+
var import_node_crypto28 = require("crypto");
|
|
41389
41800
|
var import_node_path73 = require("path");
|
|
41390
41801
|
init_orchestrator();
|
|
41391
41802
|
init_task_state();
|
|
@@ -42977,7 +43388,7 @@ function registerScheduleTools(server) {
|
|
|
42977
43388
|
}
|
|
42978
43389
|
|
|
42979
43390
|
// src/agent-rpc/handlers.ts
|
|
42980
|
-
var
|
|
43391
|
+
var import_node_crypto26 = require("crypto");
|
|
42981
43392
|
var import_node_path70 = require("path");
|
|
42982
43393
|
init_wait_for_job();
|
|
42983
43394
|
init_wait_for_turn();
|
|
@@ -43008,7 +43419,7 @@ setToolPermissionPublisher({
|
|
|
43008
43419
|
}
|
|
43009
43420
|
}
|
|
43010
43421
|
});
|
|
43011
|
-
function
|
|
43422
|
+
function asRecord16(value) {
|
|
43012
43423
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
43013
43424
|
return value;
|
|
43014
43425
|
}
|
|
@@ -43019,12 +43430,12 @@ function invalidParams(message) {
|
|
|
43019
43430
|
return Object.assign(new Error(message), { rpcCode: -32602 });
|
|
43020
43431
|
}
|
|
43021
43432
|
var handlePermissionAsk = async (params, _ctx) => {
|
|
43022
|
-
const rec =
|
|
43433
|
+
const rec = asRecord16(params);
|
|
43023
43434
|
const threadId = str6(rec.threadId).trim();
|
|
43024
43435
|
const toolName = str6(rec.toolName).trim();
|
|
43025
43436
|
if (!threadId) throw invalidParams("threadId is required");
|
|
43026
43437
|
if (!toolName) throw invalidParams("toolName is required");
|
|
43027
|
-
const input =
|
|
43438
|
+
const input = asRecord16(rec.input);
|
|
43028
43439
|
const ask = {
|
|
43029
43440
|
threadId,
|
|
43030
43441
|
toolName,
|
|
@@ -43060,7 +43471,7 @@ var handlePermissionAsk = async (params, _ctx) => {
|
|
|
43060
43471
|
// src/agent-rpc/handlers.ts
|
|
43061
43472
|
init_protocol2();
|
|
43062
43473
|
function presentArtifactResult(input) {
|
|
43063
|
-
const id = input.artifact_id?.trim() || `artifact_${Date.now().toString(36)}_${(0,
|
|
43474
|
+
const id = input.artifact_id?.trim() || `artifact_${Date.now().toString(36)}_${(0, import_node_crypto26.randomUUID)().slice(0, 8)}`;
|
|
43064
43475
|
return {
|
|
43065
43476
|
ok: true,
|
|
43066
43477
|
artifact_id: id,
|
|
@@ -43072,7 +43483,7 @@ function presentArtifactResult(input) {
|
|
|
43072
43483
|
message: input.type === "log" ? "Log accepted. Same artifact_id appends; send only new lines next time." : "Artifact accepted. Sideboard desktop opens it in the side column beside chat."
|
|
43073
43484
|
};
|
|
43074
43485
|
}
|
|
43075
|
-
function
|
|
43486
|
+
function asRecord17(value) {
|
|
43076
43487
|
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
43077
43488
|
return value;
|
|
43078
43489
|
}
|
|
@@ -43096,7 +43507,7 @@ async function handleRuntimePing(_params, _ctx) {
|
|
|
43096
43507
|
};
|
|
43097
43508
|
}
|
|
43098
43509
|
async function handlePresentArtifact(params, _ctx) {
|
|
43099
|
-
const rec =
|
|
43510
|
+
const rec = asRecord17(params);
|
|
43100
43511
|
const title = str7(rec.title).trim();
|
|
43101
43512
|
const type = str7(rec.type).trim();
|
|
43102
43513
|
const allowed = ["html", "svg", "markdown", "react", "log"];
|
|
@@ -43120,7 +43531,7 @@ async function handlePresentArtifact(params, _ctx) {
|
|
|
43120
43531
|
});
|
|
43121
43532
|
}
|
|
43122
43533
|
async function handleJobWait(params, ctx, waitFn = waitForDetachedJob) {
|
|
43123
|
-
const rec =
|
|
43534
|
+
const rec = asRecord17(params);
|
|
43124
43535
|
const id = str7(rec.id).trim();
|
|
43125
43536
|
if (!id) throw invalidParams2("id is required");
|
|
43126
43537
|
const cwd = jobCwd(rec);
|
|
@@ -43144,7 +43555,7 @@ async function handleJobWait(params, ctx, waitFn = waitForDetachedJob) {
|
|
|
43144
43555
|
};
|
|
43145
43556
|
}
|
|
43146
43557
|
async function handleJobStop(params, _ctx) {
|
|
43147
|
-
const rec =
|
|
43558
|
+
const rec = asRecord17(params);
|
|
43148
43559
|
const id = str7(rec.id).trim();
|
|
43149
43560
|
if (!id) throw invalidParams2("id is required");
|
|
43150
43561
|
const reason = str7(rec.reason).trim() || void 0;
|
|
@@ -43172,7 +43583,7 @@ async function defaultTurnWait(ref, timeoutMs) {
|
|
|
43172
43583
|
});
|
|
43173
43584
|
}
|
|
43174
43585
|
async function handleTurnWait(params, ctx, waitFn = defaultTurnWait) {
|
|
43175
|
-
const rec =
|
|
43586
|
+
const rec = asRecord17(params);
|
|
43176
43587
|
const ref = str7(rec.ref).trim();
|
|
43177
43588
|
if (!ref) throw invalidParams2("ref is required");
|
|
43178
43589
|
const requested = typeof rec.timeoutMs === "number" && Number.isFinite(rec.timeoutMs) ? rec.timeoutMs : void 0;
|
|
@@ -43224,7 +43635,7 @@ init_worktree();
|
|
|
43224
43635
|
init_paths();
|
|
43225
43636
|
|
|
43226
43637
|
// src/board/board-pins.ts
|
|
43227
|
-
var
|
|
43638
|
+
var import_node_crypto27 = require("crypto");
|
|
43228
43639
|
var import_node_fs72 = require("fs");
|
|
43229
43640
|
var import_node_path71 = require("path");
|
|
43230
43641
|
init_paths();
|
|
@@ -43256,7 +43667,7 @@ function addBoardPin(input) {
|
|
|
43256
43667
|
const ref = input.ref.trim();
|
|
43257
43668
|
if (!ref) throw new Error("Board item needs a ref");
|
|
43258
43669
|
const pin = {
|
|
43259
|
-
id: (0,
|
|
43670
|
+
id: (0, import_node_crypto27.randomUUID)(),
|
|
43260
43671
|
kind: input.kind,
|
|
43261
43672
|
ref,
|
|
43262
43673
|
repoPath: input.repoPath.trim(),
|
|
@@ -44189,7 +44600,7 @@ async function startMcpServer() {
|
|
|
44189
44600
|
const ident = issue?.identifier ?? ref.trim();
|
|
44190
44601
|
const attachments = issue ? [
|
|
44191
44602
|
{
|
|
44192
|
-
id: (0,
|
|
44603
|
+
id: (0, import_node_crypto28.randomUUID)(),
|
|
44193
44604
|
name: issue.identifier,
|
|
44194
44605
|
kind: "issue",
|
|
44195
44606
|
content: [
|
|
@@ -44751,8 +45162,8 @@ init_protocol2();
|
|
|
44751
45162
|
init_metadata();
|
|
44752
45163
|
|
|
44753
45164
|
// src/agent-rpc/server.ts
|
|
44754
|
-
var
|
|
44755
|
-
var
|
|
45165
|
+
var import_node_crypto29 = require("crypto");
|
|
45166
|
+
var import_node_http6 = require("http");
|
|
44756
45167
|
var import_ws5 = require("ws");
|
|
44757
45168
|
init_protocol2();
|
|
44758
45169
|
init_metadata();
|
|
@@ -44760,7 +45171,7 @@ function tokensEqual(a, b) {
|
|
|
44760
45171
|
const left = Buffer.from(a);
|
|
44761
45172
|
const right = Buffer.from(b);
|
|
44762
45173
|
if (left.length !== right.length) return false;
|
|
44763
|
-
return (0,
|
|
45174
|
+
return (0, import_node_crypto29.timingSafeEqual)(left, right);
|
|
44764
45175
|
}
|
|
44765
45176
|
function authTokenFromUpgrade(req) {
|
|
44766
45177
|
try {
|
|
@@ -44793,16 +45204,16 @@ var AgentRpcServer = class {
|
|
|
44793
45204
|
async listen(opts = {}) {
|
|
44794
45205
|
const host = opts.host ?? "127.0.0.1";
|
|
44795
45206
|
const port = opts.port ?? 0;
|
|
44796
|
-
const authToken = (0,
|
|
45207
|
+
const authToken = (0, import_node_crypto29.randomBytes)(24).toString("base64url");
|
|
44797
45208
|
this.meta = {
|
|
44798
|
-
runtimeId: (0,
|
|
45209
|
+
runtimeId: (0, import_node_crypto29.randomUUID)(),
|
|
44799
45210
|
pid: process.pid,
|
|
44800
45211
|
protocolVersion: AGENT_RPC_PROTOCOL_VERSION,
|
|
44801
45212
|
authToken,
|
|
44802
45213
|
startedAt: Date.now(),
|
|
44803
45214
|
transports: []
|
|
44804
45215
|
};
|
|
44805
|
-
const http = (0,
|
|
45216
|
+
const http = (0, import_node_http6.createServer)((_req, res) => {
|
|
44806
45217
|
res.statusCode = 404;
|
|
44807
45218
|
res.end();
|
|
44808
45219
|
});
|
|
@@ -45288,6 +45699,8 @@ init_oauth();
|
|
|
45288
45699
|
init_injected_mcp();
|
|
45289
45700
|
init_user_mcp_config();
|
|
45290
45701
|
init_orch_mcp_isolation();
|
|
45702
|
+
init_host();
|
|
45703
|
+
init_model_context();
|
|
45291
45704
|
init_meta();
|
|
45292
45705
|
|
|
45293
45706
|
// src/slack/workspaces.ts
|
|
@@ -45386,7 +45799,7 @@ function slackTokenFor(ws, kind = "read") {
|
|
|
45386
45799
|
}
|
|
45387
45800
|
|
|
45388
45801
|
// src/slack/oauth.ts
|
|
45389
|
-
var
|
|
45802
|
+
var import_node_crypto30 = require("crypto");
|
|
45390
45803
|
init_app_settings();
|
|
45391
45804
|
var SLACK_BOT_SCOPES = [
|
|
45392
45805
|
"app_mentions:read",
|
|
@@ -45480,7 +45893,7 @@ async function startSlackOAuth(opts) {
|
|
|
45480
45893
|
throw new SlackOAuthCancelledError();
|
|
45481
45894
|
}
|
|
45482
45895
|
const { clientId } = slackOAuthCredentials();
|
|
45483
|
-
const state = (0,
|
|
45896
|
+
const state = (0, import_node_crypto30.randomBytes)(16).toString("hex");
|
|
45484
45897
|
const authorizeUrl = slackOAuthAuthorizeUrl(clientId, state);
|
|
45485
45898
|
const timeoutMs = opts?.timeoutMs ?? 5 * 6e4;
|
|
45486
45899
|
const pollIntervalMs = opts?.pollIntervalMs ?? 400;
|
|
@@ -46389,7 +46802,7 @@ function resolveSlackListenMode(opts) {
|
|
|
46389
46802
|
init_protocol();
|
|
46390
46803
|
|
|
46391
46804
|
// src/relay/account-login.ts
|
|
46392
|
-
var
|
|
46805
|
+
var import_node_crypto31 = require("crypto");
|
|
46393
46806
|
init_fetch();
|
|
46394
46807
|
init_protocol();
|
|
46395
46808
|
var RemoteAccountLoginCancelled = class extends Error {
|
|
@@ -46457,7 +46870,7 @@ async function readJson4(res, url) {
|
|
|
46457
46870
|
async function startRemoteAccountLogin(opts) {
|
|
46458
46871
|
if (opts.signal?.aborted) throw new RemoteAccountLoginCancelled();
|
|
46459
46872
|
const origin = (opts.origin ?? remoteAccountHttpOrigin()).replace(/\/+$/, "");
|
|
46460
|
-
const state = (0,
|
|
46873
|
+
const state = (0, import_node_crypto31.randomBytes)(16).toString("hex");
|
|
46461
46874
|
const timeoutMs = opts.timeoutMs ?? 5 * 6e4;
|
|
46462
46875
|
const pollIntervalMs = opts.pollIntervalMs ?? 400;
|
|
46463
46876
|
const linkToken = opts.linkToken?.trim() ?? "";
|
|
@@ -47853,6 +48266,7 @@ async function pollSlackOutboundWatches(opts) {
|
|
|
47853
48266
|
startRelayServer,
|
|
47854
48267
|
startRemoteAccountLogin,
|
|
47855
48268
|
startSlackOAuth,
|
|
48269
|
+
stashMcpAppModelContext,
|
|
47856
48270
|
statWorktreePath,
|
|
47857
48271
|
stopAgentRpcServer,
|
|
47858
48272
|
stripBrightsyNdjsonNoise,
|