@buildautomaton/cli 0.1.47 → 0.1.49
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/cli.js +640 -79
- package/dist/cli.js.map +4 -4
- package/dist/index.js +640 -79
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22733,6 +22733,238 @@ var WebSocketMessageSchema = external_exports.object({
|
|
|
22733
22733
|
error: external_exports.string().optional()
|
|
22734
22734
|
});
|
|
22735
22735
|
|
|
22736
|
+
// ../types/src/integrations/link-detection/linear.ts
|
|
22737
|
+
function detectLinearLink(url2) {
|
|
22738
|
+
const linearMatch = url2.match(
|
|
22739
|
+
/https?:\/\/(?:app\.)?linear\.app\/([^/]+)\/issue\/([A-Z]+-\d+)/i
|
|
22740
|
+
);
|
|
22741
|
+
if (linearMatch) {
|
|
22742
|
+
return {
|
|
22743
|
+
url: url2,
|
|
22744
|
+
integrationType: "linear",
|
|
22745
|
+
resourceType: "work-item",
|
|
22746
|
+
resourceId: linearMatch[2],
|
|
22747
|
+
workspaceId: linearMatch[1]
|
|
22748
|
+
};
|
|
22749
|
+
}
|
|
22750
|
+
return null;
|
|
22751
|
+
}
|
|
22752
|
+
|
|
22753
|
+
// ../types/src/integrations/link-detection/github.ts
|
|
22754
|
+
function detectGitHubLink(url2) {
|
|
22755
|
+
const githubIssueMatch = url2.match(
|
|
22756
|
+
/https?:\/\/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/i
|
|
22757
|
+
);
|
|
22758
|
+
if (githubIssueMatch) {
|
|
22759
|
+
return {
|
|
22760
|
+
url: url2,
|
|
22761
|
+
integrationType: "github",
|
|
22762
|
+
resourceType: "issue",
|
|
22763
|
+
resourceId: githubIssueMatch[3],
|
|
22764
|
+
owner: githubIssueMatch[1],
|
|
22765
|
+
repo: githubIssueMatch[2]
|
|
22766
|
+
};
|
|
22767
|
+
}
|
|
22768
|
+
const githubPRMatch = url2.match(
|
|
22769
|
+
/https?:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/(\d+)/i
|
|
22770
|
+
);
|
|
22771
|
+
if (githubPRMatch) {
|
|
22772
|
+
return {
|
|
22773
|
+
url: url2,
|
|
22774
|
+
integrationType: "github",
|
|
22775
|
+
resourceType: "pull-request",
|
|
22776
|
+
resourceId: githubPRMatch[3],
|
|
22777
|
+
owner: githubPRMatch[1],
|
|
22778
|
+
repo: githubPRMatch[2]
|
|
22779
|
+
};
|
|
22780
|
+
}
|
|
22781
|
+
return null;
|
|
22782
|
+
}
|
|
22783
|
+
|
|
22784
|
+
// ../types/src/integrations/link-detection/jira.ts
|
|
22785
|
+
function detectJIRALink(url2) {
|
|
22786
|
+
const jiraMatch = url2.match(
|
|
22787
|
+
/https?:\/\/([^/]+)\.atlassian\.net\/(?:browse|jira\/software\/projects\/[^/]+\/issues)\/([A-Z]+-\d+)/i
|
|
22788
|
+
);
|
|
22789
|
+
if (jiraMatch) {
|
|
22790
|
+
return {
|
|
22791
|
+
url: url2,
|
|
22792
|
+
integrationType: "jira",
|
|
22793
|
+
resourceType: "issue",
|
|
22794
|
+
resourceId: jiraMatch[2],
|
|
22795
|
+
projectKey: jiraMatch[2].split("-")[0]
|
|
22796
|
+
};
|
|
22797
|
+
}
|
|
22798
|
+
return null;
|
|
22799
|
+
}
|
|
22800
|
+
|
|
22801
|
+
// ../types/src/integrations/link-detection/notion.ts
|
|
22802
|
+
function formatNotionPageId(hex) {
|
|
22803
|
+
if (hex.length !== 32) return hex;
|
|
22804
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
22805
|
+
}
|
|
22806
|
+
function detectNotionLink(url2) {
|
|
22807
|
+
const standardMatch = url2.match(
|
|
22808
|
+
/https?:\/\/(?:www\.)?notion\.(?:so|site)\/(?:[^/#?]+\/)?(?:[^/#?-]+-)?([a-f0-9]{32})/i
|
|
22809
|
+
);
|
|
22810
|
+
if (standardMatch) {
|
|
22811
|
+
return {
|
|
22812
|
+
url: url2,
|
|
22813
|
+
integrationType: "notion",
|
|
22814
|
+
resourceType: "page",
|
|
22815
|
+
resourceId: formatNotionPageId(standardMatch[1])
|
|
22816
|
+
};
|
|
22817
|
+
}
|
|
22818
|
+
const siteMatch = url2.match(
|
|
22819
|
+
/https?:\/\/([^.]+)\.notion\.(?:so|site)\/(?:[^/#?-]+-)?([a-f0-9]{32})/i
|
|
22820
|
+
);
|
|
22821
|
+
if (siteMatch) {
|
|
22822
|
+
return {
|
|
22823
|
+
url: url2,
|
|
22824
|
+
integrationType: "notion",
|
|
22825
|
+
resourceType: "page",
|
|
22826
|
+
resourceId: formatNotionPageId(siteMatch[2]),
|
|
22827
|
+
notionWorkspaceId: siteMatch[1]
|
|
22828
|
+
};
|
|
22829
|
+
}
|
|
22830
|
+
return null;
|
|
22831
|
+
}
|
|
22832
|
+
|
|
22833
|
+
// ../types/src/integrations/link-detection/slack.ts
|
|
22834
|
+
function detectSlackLink(url2) {
|
|
22835
|
+
const archiveThreadMatch = url2.match(
|
|
22836
|
+
/https?:\/\/(?:([^./]+)\.)?slack\.com\/archives\/([A-Z0-9]+)\/p(\d+)(?:\?.*)?$/i
|
|
22837
|
+
);
|
|
22838
|
+
if (archiveThreadMatch) {
|
|
22839
|
+
return {
|
|
22840
|
+
url: url2,
|
|
22841
|
+
integrationType: "slack",
|
|
22842
|
+
resourceType: "thread",
|
|
22843
|
+
resourceId: `${archiveThreadMatch[2]}-${archiveThreadMatch[3]}`,
|
|
22844
|
+
isChannel: false
|
|
22845
|
+
};
|
|
22846
|
+
}
|
|
22847
|
+
const appThreadMatch = url2.match(
|
|
22848
|
+
/https?:\/\/app\.slack\.com\/client\/([^/]+)\/([A-Z0-9]+)\/thread\/[A-Z0-9]+-(\d+)/i
|
|
22849
|
+
);
|
|
22850
|
+
if (appThreadMatch) {
|
|
22851
|
+
return {
|
|
22852
|
+
url: url2,
|
|
22853
|
+
integrationType: "slack",
|
|
22854
|
+
resourceType: "thread",
|
|
22855
|
+
resourceId: `${appThreadMatch[2]}-${appThreadMatch[3]}`,
|
|
22856
|
+
isChannel: false
|
|
22857
|
+
};
|
|
22858
|
+
}
|
|
22859
|
+
const channelOnlyMatch = url2.match(
|
|
22860
|
+
/https?:\/\/(?:app\.)?(?:([^./]+)\.)?slack\.com\/archives\/([A-Z0-9]+)\/?(\?.*)?$/i
|
|
22861
|
+
);
|
|
22862
|
+
if (channelOnlyMatch && !url2.includes("/p")) {
|
|
22863
|
+
return {
|
|
22864
|
+
url: url2,
|
|
22865
|
+
integrationType: "slack",
|
|
22866
|
+
resourceType: "channel",
|
|
22867
|
+
resourceId: channelOnlyMatch[2],
|
|
22868
|
+
isChannel: true
|
|
22869
|
+
};
|
|
22870
|
+
}
|
|
22871
|
+
return null;
|
|
22872
|
+
}
|
|
22873
|
+
|
|
22874
|
+
// ../types/src/integrations/link-detection/zoom.ts
|
|
22875
|
+
function detectZoomLink(url2) {
|
|
22876
|
+
try {
|
|
22877
|
+
const u = new URL(url2);
|
|
22878
|
+
const host = u.hostname.toLowerCase();
|
|
22879
|
+
if (!host.endsWith("zoom.us") && !host.endsWith("zoom.com")) return null;
|
|
22880
|
+
const pathParts = u.pathname.split("/").filter(Boolean);
|
|
22881
|
+
if (pathParts.length >= 2 && (pathParts[0] === "j" || pathParts[0] === "s" || pathParts[0] === "my")) {
|
|
22882
|
+
const meetingId = pathParts[1].replace(/\s/g, "");
|
|
22883
|
+
if (meetingId.length >= 9) {
|
|
22884
|
+
return {
|
|
22885
|
+
url: url2,
|
|
22886
|
+
integrationType: "zoom",
|
|
22887
|
+
resourceType: "meeting",
|
|
22888
|
+
resourceId: meetingId,
|
|
22889
|
+
zoomMeetingId: meetingId
|
|
22890
|
+
};
|
|
22891
|
+
}
|
|
22892
|
+
}
|
|
22893
|
+
} catch {
|
|
22894
|
+
}
|
|
22895
|
+
return null;
|
|
22896
|
+
}
|
|
22897
|
+
|
|
22898
|
+
// ../types/src/integrations/link-detection/asana.ts
|
|
22899
|
+
var ASANA_TASK_GID = /\d{10,}/;
|
|
22900
|
+
function parseAsanaTaskGid(segment) {
|
|
22901
|
+
const trimmed2 = segment.trim();
|
|
22902
|
+
if (!ASANA_TASK_GID.test(trimmed2)) return null;
|
|
22903
|
+
return trimmed2;
|
|
22904
|
+
}
|
|
22905
|
+
function detectAsanaLink(url2) {
|
|
22906
|
+
const v1ProjectMatch = url2.match(
|
|
22907
|
+
/https?:\/\/app\.asana\.com\/1\/[^/]+\/project\/([^/?#]+)\/task\/([^/?#]+)/i
|
|
22908
|
+
);
|
|
22909
|
+
if (v1ProjectMatch) {
|
|
22910
|
+
const taskGid = parseAsanaTaskGid(v1ProjectMatch[2]);
|
|
22911
|
+
if (!taskGid) return null;
|
|
22912
|
+
return {
|
|
22913
|
+
url: url2,
|
|
22914
|
+
integrationType: "asana",
|
|
22915
|
+
resourceType: "task",
|
|
22916
|
+
resourceId: taskGid,
|
|
22917
|
+
asanaProjectGid: v1ProjectMatch[1]
|
|
22918
|
+
};
|
|
22919
|
+
}
|
|
22920
|
+
const v1TaskMatch = url2.match(/https?:\/\/app\.asana\.com\/1\/[^/]+(?:\/[^/]+)*\/task\/([^/?#]+)/i);
|
|
22921
|
+
if (v1TaskMatch) {
|
|
22922
|
+
const taskGid = parseAsanaTaskGid(v1TaskMatch[1]);
|
|
22923
|
+
if (!taskGid) return null;
|
|
22924
|
+
return {
|
|
22925
|
+
url: url2,
|
|
22926
|
+
integrationType: "asana",
|
|
22927
|
+
resourceType: "task",
|
|
22928
|
+
resourceId: taskGid
|
|
22929
|
+
};
|
|
22930
|
+
}
|
|
22931
|
+
const legacyMatch = url2.match(/https?:\/\/app\.asana\.com\/0\/([^/?#]+)\/([^/?#]+)/i);
|
|
22932
|
+
if (legacyMatch) {
|
|
22933
|
+
const projectGid = legacyMatch[1];
|
|
22934
|
+
const taskGid = parseAsanaTaskGid(legacyMatch[2]);
|
|
22935
|
+
if (!taskGid) return null;
|
|
22936
|
+
if (projectGid === "inbox" || projectGid === "my_tasks") {
|
|
22937
|
+
return null;
|
|
22938
|
+
}
|
|
22939
|
+
return {
|
|
22940
|
+
url: url2,
|
|
22941
|
+
integrationType: "asana",
|
|
22942
|
+
resourceType: "task",
|
|
22943
|
+
resourceId: taskGid,
|
|
22944
|
+
asanaProjectGid: projectGid === "0" ? void 0 : projectGid
|
|
22945
|
+
};
|
|
22946
|
+
}
|
|
22947
|
+
return null;
|
|
22948
|
+
}
|
|
22949
|
+
|
|
22950
|
+
// ../types/src/integrations/link-detection/index.ts
|
|
22951
|
+
function detectIntegrationLink(url2) {
|
|
22952
|
+
return detectLinearLink(url2) || detectGitHubLink(url2) || detectJIRALink(url2) || detectNotionLink(url2) || detectSlackLink(url2) || detectZoomLink(url2) || detectAsanaLink(url2);
|
|
22953
|
+
}
|
|
22954
|
+
function extractIntegrationLinks(text) {
|
|
22955
|
+
const urlRegex = /https?:\/\/[^\s<>"{}|\\^`[\]]+/gi;
|
|
22956
|
+
const urls = text.match(urlRegex) || [];
|
|
22957
|
+
const links = [];
|
|
22958
|
+
for (const url2 of urls) {
|
|
22959
|
+
const detected = detectIntegrationLink(url2);
|
|
22960
|
+
if (detected) links.push(detected);
|
|
22961
|
+
}
|
|
22962
|
+
return links;
|
|
22963
|
+
}
|
|
22964
|
+
function extractFetchableIntegrationLinks(text) {
|
|
22965
|
+
return extractIntegrationLinks(text).filter((link) => !(link.integrationType === "slack" && link.isChannel));
|
|
22966
|
+
}
|
|
22967
|
+
|
|
22736
22968
|
// ../types/src/checkpoints.ts
|
|
22737
22969
|
init_zod();
|
|
22738
22970
|
var CheckpointKindSchema = external_exports.enum(["daily", "weekly", "overall"]);
|
|
@@ -23160,6 +23392,16 @@ var GitRepoMetaSchema = external_exports.object({
|
|
|
23160
23392
|
updatedAt: external_exports.string()
|
|
23161
23393
|
});
|
|
23162
23394
|
|
|
23395
|
+
// ../types/src/bridge-mcp-tool-display.ts
|
|
23396
|
+
var GET_INTEGRATION_CONTENT_TOOL = "get_integration_content";
|
|
23397
|
+
var LIST_PARENT_SESSION_PROMPTS_TOOL = "list_parent_session_prompts";
|
|
23398
|
+
var GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL = "get_parent_session_turn_transcript";
|
|
23399
|
+
var BRIDGE_MCP_TOOL_LABELS = {
|
|
23400
|
+
[GET_INTEGRATION_CONTENT_TOOL]: "Fetch external ticket content",
|
|
23401
|
+
[LIST_PARENT_SESSION_PROMPTS_TOOL]: "List parent session prompts",
|
|
23402
|
+
[GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL]: "Read parent session transcript"
|
|
23403
|
+
};
|
|
23404
|
+
|
|
23163
23405
|
// ../types/src/claude-code-permission-mode.ts
|
|
23164
23406
|
var CLAUDE_CODE_PERMISSION_MODES = [
|
|
23165
23407
|
"default",
|
|
@@ -24469,7 +24711,7 @@ function installBridgeProcessResilience() {
|
|
|
24469
24711
|
}
|
|
24470
24712
|
|
|
24471
24713
|
// src/cli-version.ts
|
|
24472
|
-
var CLI_VERSION = "0.1.
|
|
24714
|
+
var CLI_VERSION = "0.1.49".length > 0 ? "0.1.49" : "0.0.0-dev";
|
|
24473
24715
|
|
|
24474
24716
|
// src/connection/heartbeat/constants.ts
|
|
24475
24717
|
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
@@ -33121,54 +33363,175 @@ function buildForkedSessionAgentPrompt(userPrompt, childSessionId, parentSession
|
|
|
33121
33363
|
].join("\n");
|
|
33122
33364
|
}
|
|
33123
33365
|
|
|
33124
|
-
// src/mcp/tools/session-history/
|
|
33366
|
+
// src/mcp/tools/session-history/cloud/internal-api.ts
|
|
33125
33367
|
function internalApiBase(cloudApiBaseUrl) {
|
|
33126
33368
|
return cloudApiBaseUrl.replace(/\/+$/, "");
|
|
33127
33369
|
}
|
|
33128
|
-
async function
|
|
33370
|
+
async function fetchInternalApiJson(params) {
|
|
33129
33371
|
const token = params.getCloudAccessToken();
|
|
33130
33372
|
if (!token) return { ok: false, error: "Missing cloud access token." };
|
|
33131
|
-
const url2 = `${internalApiBase(params.cloudApiBaseUrl)}
|
|
33132
|
-
const
|
|
33373
|
+
const url2 = `${internalApiBase(params.cloudApiBaseUrl)}${params.path}`;
|
|
33374
|
+
const method = params.method ?? "GET";
|
|
33375
|
+
const res = await fetch(url2, {
|
|
33376
|
+
method,
|
|
33377
|
+
headers: {
|
|
33378
|
+
Authorization: `Bearer ${token}`,
|
|
33379
|
+
...params.body != null ? { "Content-Type": "application/json" } : {}
|
|
33380
|
+
},
|
|
33381
|
+
...params.body != null ? { body: JSON.stringify(params.body) } : {}
|
|
33382
|
+
});
|
|
33133
33383
|
if (!res.ok) {
|
|
33134
33384
|
const t = await res.text().catch(() => "");
|
|
33135
|
-
return { ok: false, error:
|
|
33385
|
+
return { ok: false, error: `${params.errorLabel} (${res.status}): ${t.slice(0, 200)}` };
|
|
33136
33386
|
}
|
|
33137
33387
|
const data = await res.json().catch(() => null);
|
|
33138
|
-
if (!data) return { ok: false, error:
|
|
33388
|
+
if (!data) return { ok: false, error: `Invalid ${params.errorLabel.toLowerCase()} response.` };
|
|
33139
33389
|
return { ok: true, data };
|
|
33140
33390
|
}
|
|
33141
|
-
|
|
33142
|
-
|
|
33143
|
-
|
|
33144
|
-
|
|
33145
|
-
|
|
33146
|
-
|
|
33147
|
-
|
|
33148
|
-
|
|
33391
|
+
|
|
33392
|
+
// src/mcp/tools/session-history/cloud/fetch-session-meta.ts
|
|
33393
|
+
async function fetchCloudSessionMeta(params) {
|
|
33394
|
+
return fetchInternalApiJson({
|
|
33395
|
+
...params,
|
|
33396
|
+
path: `/internal/sessions/${encodeURIComponent(params.sessionId)}/meta`,
|
|
33397
|
+
errorLabel: "Session meta fetch failed"
|
|
33398
|
+
});
|
|
33399
|
+
}
|
|
33400
|
+
|
|
33401
|
+
// src/lib/e2ee/decrypt-stored-e2ee-content.ts
|
|
33402
|
+
function parseJsonObject(raw) {
|
|
33403
|
+
try {
|
|
33404
|
+
const parsed = JSON.parse(raw);
|
|
33405
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
33406
|
+
return parsed;
|
|
33407
|
+
}
|
|
33408
|
+
} catch {
|
|
33409
|
+
return null;
|
|
33149
33410
|
}
|
|
33150
|
-
|
|
33151
|
-
if (!data) return { ok: false, error: "Invalid parent prompts response." };
|
|
33152
|
-
return { ok: true, data };
|
|
33411
|
+
return null;
|
|
33153
33412
|
}
|
|
33154
|
-
|
|
33155
|
-
const
|
|
33156
|
-
|
|
33157
|
-
|
|
33158
|
-
|
|
33159
|
-
|
|
33160
|
-
|
|
33161
|
-
|
|
33413
|
+
function storedStringHasE2eeEnvelope(raw) {
|
|
33414
|
+
const record2 = parseJsonObject(raw);
|
|
33415
|
+
return record2 != null && isE2eeEnvelope(record2.ee);
|
|
33416
|
+
}
|
|
33417
|
+
function e2eeKeyIdFromStoredString(raw) {
|
|
33418
|
+
const record2 = parseJsonObject(raw);
|
|
33419
|
+
if (record2 != null && isE2eeEnvelope(record2.ee)) return record2.ee.k;
|
|
33420
|
+
return null;
|
|
33421
|
+
}
|
|
33422
|
+
function decryptStoredE2eeRecord(record2, e2ee) {
|
|
33423
|
+
if (!isE2eeEnvelope(record2.ee)) return record2;
|
|
33424
|
+
if (!e2ee) {
|
|
33425
|
+
throw new Error(`E2EE_REQUIRED:${record2.ee.k}`);
|
|
33426
|
+
}
|
|
33427
|
+
if (record2.ee.k !== e2ee.keyId) {
|
|
33428
|
+
throw new Error(`E2EE_KEY_MISMATCH:encrypted=${record2.ee.k}:cli=${e2ee.keyId}`);
|
|
33429
|
+
}
|
|
33430
|
+
return e2ee.decryptMessage(record2);
|
|
33431
|
+
}
|
|
33432
|
+
function formatCliE2eeDecryptError(error40, e2ee) {
|
|
33433
|
+
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
33434
|
+
const required2 = /^E2EE_REQUIRED:(.+)$/.exec(message.trim());
|
|
33435
|
+
if (required2) {
|
|
33436
|
+
const keyId = required2[1]?.trim() || "unknown";
|
|
33437
|
+
return `Parent session content is encrypted (key ${keyId}) but this bridge was not started with E2EE certificates. Restart the CLI with your E2EE certificate to read fork parent history.`;
|
|
33438
|
+
}
|
|
33439
|
+
const mismatch = /^E2EE_KEY_MISMATCH:encrypted=(.+):cli=(.*)$/.exec(message.trim());
|
|
33440
|
+
if (mismatch) {
|
|
33441
|
+
const encryptedKeyId = mismatch[1]?.trim() || "unknown";
|
|
33442
|
+
const cliKeyId = mismatch[2]?.trim() || e2ee?.keyId || "none";
|
|
33443
|
+
return `Parent session content is encrypted with key ${encryptedKeyId}, but this bridge certificate key is ${cliKeyId}. Use the same E2EE certificate that was used for the parent session.`;
|
|
33444
|
+
}
|
|
33445
|
+
if (message.includes("E2EE key mismatch")) {
|
|
33446
|
+
return `Parent session content could not be decrypted: ${message}`;
|
|
33447
|
+
}
|
|
33448
|
+
return `Parent session content could not be decrypted: ${message}`;
|
|
33449
|
+
}
|
|
33450
|
+
function decryptCliE2eeTranscriptPayload(payload, e2ee) {
|
|
33451
|
+
const record2 = parseJsonObject(payload);
|
|
33452
|
+
if (!record2 || !isE2eeEnvelope(record2.ee)) return payload;
|
|
33453
|
+
const decrypted = decryptStoredE2eeRecord(record2, e2ee);
|
|
33454
|
+
if (typeof decrypted.payload === "string") return decrypted.payload;
|
|
33455
|
+
return JSON.stringify(decrypted.payload ?? decrypted);
|
|
33456
|
+
}
|
|
33457
|
+
function decryptCliE2eeMessageField(payload, field, e2ee) {
|
|
33458
|
+
if (payload == null) return null;
|
|
33459
|
+
const record2 = parseJsonObject(payload);
|
|
33460
|
+
if (!record2 || !isE2eeEnvelope(record2.ee)) return payload;
|
|
33461
|
+
const decrypted = decryptStoredE2eeRecord(record2, e2ee);
|
|
33462
|
+
const value = decrypted[field];
|
|
33463
|
+
if (value == null) return null;
|
|
33464
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
33465
|
+
}
|
|
33466
|
+
|
|
33467
|
+
// src/mcp/tools/session-history/cloud/decrypt-parent-prompt-turns.ts
|
|
33468
|
+
function assertE2eeRuntimeForEnvelope(raw, e2ee) {
|
|
33469
|
+
if (storedStringHasE2eeEnvelope(raw) && !e2ee) {
|
|
33470
|
+
throw new Error(`E2EE_REQUIRED:${e2eeKeyIdFromStoredString(raw) ?? "unknown"}`);
|
|
33471
|
+
}
|
|
33472
|
+
}
|
|
33473
|
+
function decryptParentPromptTurns(turns, e2ee) {
|
|
33474
|
+
return turns.map((turn) => {
|
|
33475
|
+
const promptRaw = typeof turn.promptText === "string" ? turn.promptText : null;
|
|
33476
|
+
const titleRaw = typeof turn.title === "string" ? turn.title : null;
|
|
33477
|
+
if (promptRaw) assertE2eeRuntimeForEnvelope(promptRaw, e2ee);
|
|
33478
|
+
if (titleRaw) assertE2eeRuntimeForEnvelope(titleRaw, e2ee);
|
|
33479
|
+
return {
|
|
33480
|
+
...turn,
|
|
33481
|
+
promptText: decryptCliE2eeMessageField(promptRaw, "prompt", e2ee),
|
|
33482
|
+
title: decryptCliE2eeMessageField(titleRaw, "title", e2ee)
|
|
33483
|
+
};
|
|
33484
|
+
});
|
|
33485
|
+
}
|
|
33486
|
+
|
|
33487
|
+
// src/mcp/tools/session-history/cloud/fetch-parent-prompts.ts
|
|
33488
|
+
async function fetchCloudParentSessionPrompts(params) {
|
|
33489
|
+
const fetched = await fetchInternalApiJson({
|
|
33490
|
+
...params,
|
|
33491
|
+
path: `/internal/sessions/${encodeURIComponent(params.childSessionId)}/parent/prompts`,
|
|
33492
|
+
errorLabel: "Parent prompts fetch failed"
|
|
33493
|
+
});
|
|
33494
|
+
if (!fetched.ok) return fetched;
|
|
33495
|
+
const turns = Array.isArray(fetched.data.turns) ? fetched.data.turns : [];
|
|
33496
|
+
try {
|
|
33497
|
+
const decryptedTurns = decryptParentPromptTurns(turns, params.e2ee);
|
|
33498
|
+
return { ok: true, data: { ...fetched.data, turns: decryptedTurns } };
|
|
33499
|
+
} catch (error40) {
|
|
33500
|
+
return { ok: false, error: formatCliE2eeDecryptError(error40, params.e2ee) };
|
|
33162
33501
|
}
|
|
33163
|
-
|
|
33164
|
-
|
|
33502
|
+
}
|
|
33503
|
+
|
|
33504
|
+
// src/mcp/tools/session-history/cloud/format-parent-transcript-text.ts
|
|
33505
|
+
function formatParentTranscriptText(rows, e2ee) {
|
|
33165
33506
|
const lines = rows.map((row) => {
|
|
33166
33507
|
const kind = typeof row.kind === "string" ? row.kind : "event";
|
|
33167
|
-
const
|
|
33508
|
+
const rawPayload = typeof row.payload === "string" ? row.payload : JSON.stringify(row.payload ?? "");
|
|
33509
|
+
if (storedStringHasE2eeEnvelope(rawPayload) && !e2ee) {
|
|
33510
|
+
throw new Error(`E2EE_REQUIRED:${e2eeKeyIdFromStoredString(rawPayload) ?? "unknown"}`);
|
|
33511
|
+
}
|
|
33512
|
+
const payload = decryptCliE2eeTranscriptPayload(rawPayload, e2ee);
|
|
33168
33513
|
return `[${kind}] ${payload}`;
|
|
33169
33514
|
});
|
|
33170
|
-
return
|
|
33515
|
+
return lines.join("\n");
|
|
33516
|
+
}
|
|
33517
|
+
|
|
33518
|
+
// src/mcp/tools/session-history/cloud/fetch-parent-transcript.ts
|
|
33519
|
+
async function fetchCloudParentTurnTranscript(params) {
|
|
33520
|
+
const fetched = await fetchInternalApiJson({
|
|
33521
|
+
...params,
|
|
33522
|
+
path: `/internal/sessions/${encodeURIComponent(params.childSessionId)}/parent/turns/${encodeURIComponent(params.turnId)}/transcript`,
|
|
33523
|
+
errorLabel: "Transcript fetch failed"
|
|
33524
|
+
});
|
|
33525
|
+
if (!fetched.ok) return fetched;
|
|
33526
|
+
const rows = Array.isArray(fetched.data.transcript) ? fetched.data.transcript : [];
|
|
33527
|
+
try {
|
|
33528
|
+
return { ok: true, text: formatParentTranscriptText(rows, params.e2ee) };
|
|
33529
|
+
} catch (error40) {
|
|
33530
|
+
return { ok: false, error: formatCliE2eeDecryptError(error40, params.e2ee) };
|
|
33531
|
+
}
|
|
33171
33532
|
}
|
|
33533
|
+
|
|
33534
|
+
// src/mcp/tools/session-history/cloud/resolve-parent-session-id.ts
|
|
33172
33535
|
async function resolveParentSessionIdForChild(params) {
|
|
33173
33536
|
const meta = await fetchCloudSessionMeta({
|
|
33174
33537
|
sessionId: params.childSessionId,
|
|
@@ -33199,6 +33562,39 @@ async function enrichForkedSessionPromptForAgent(params) {
|
|
|
33199
33562
|
return buildForkedSessionAgentPrompt(params.promptText, params.sessionId, parentSessionId);
|
|
33200
33563
|
}
|
|
33201
33564
|
|
|
33565
|
+
// src/agents/acp/build-integration-content-agent-prompt-note.ts
|
|
33566
|
+
function buildIntegrationContentAgentPromptNote(sessionId) {
|
|
33567
|
+
const sessionRef = sessionId.trim();
|
|
33568
|
+
return [
|
|
33569
|
+
"The user message includes link(s) to external integration resources (Linear, GitHub, Jira, Notion, Slack thread, Zoom, or Asana).",
|
|
33570
|
+
"Use the get_integration_content MCP tool on the buildautomaton-bridge server to fetch the full content of each link.",
|
|
33571
|
+
`When calling the tool, pass sessionId "${sessionRef}" and the URL as url.`,
|
|
33572
|
+
"By default the tool links the fetched URL as this session external ticket when the session has none yet. Pass associateAsSessionTicket: false when fetching additional links for context only (after the primary ticket is linked, or when you do not want association).",
|
|
33573
|
+
"If the tool reports unsupported_url, do not retry with the same URL. If it reports temporarily_unavailable, you may retry later."
|
|
33574
|
+
].join("\n");
|
|
33575
|
+
}
|
|
33576
|
+
function injectIntegrationContentAgentPromptNote(agentPrompt, sessionId) {
|
|
33577
|
+
const note = buildIntegrationContentAgentPromptNote(sessionId);
|
|
33578
|
+
const marker = "\nUser request:\n";
|
|
33579
|
+
const idx = agentPrompt.indexOf(marker);
|
|
33580
|
+
if (idx >= 0) {
|
|
33581
|
+
return `${agentPrompt.slice(0, idx)}
|
|
33582
|
+
${note}${agentPrompt.slice(idx)}`;
|
|
33583
|
+
}
|
|
33584
|
+
return `${note}
|
|
33585
|
+
|
|
33586
|
+
${agentPrompt.trim()}`;
|
|
33587
|
+
}
|
|
33588
|
+
|
|
33589
|
+
// src/agents/acp/enrich-integration-content-prompt-for-agent.ts
|
|
33590
|
+
function enrichIntegrationContentPromptForAgent(params) {
|
|
33591
|
+
if (!params.sessionId.trim()) return params.agentPromptText;
|
|
33592
|
+
if (extractFetchableIntegrationLinks(params.originalPromptText).length === 0) {
|
|
33593
|
+
return params.agentPromptText;
|
|
33594
|
+
}
|
|
33595
|
+
return injectIntegrationContentAgentPromptNote(params.agentPromptText, params.sessionId);
|
|
33596
|
+
}
|
|
33597
|
+
|
|
33202
33598
|
// src/agents/acp/send-prompt-to-agent.ts
|
|
33203
33599
|
async function sendPromptToAgent(options) {
|
|
33204
33600
|
const {
|
|
@@ -33229,6 +33625,13 @@ async function sendPromptToAgent(options) {
|
|
|
33229
33625
|
getCloudAccessToken
|
|
33230
33626
|
});
|
|
33231
33627
|
}
|
|
33628
|
+
if (sessionId) {
|
|
33629
|
+
agentPromptText = enrichIntegrationContentPromptForAgent({
|
|
33630
|
+
sessionId,
|
|
33631
|
+
originalPromptText: promptText,
|
|
33632
|
+
agentPromptText
|
|
33633
|
+
});
|
|
33634
|
+
}
|
|
33232
33635
|
let sendOpts = {};
|
|
33233
33636
|
if (attachments && attachments.length > 0) {
|
|
33234
33637
|
if (!sessionId || !cloudApiBaseUrl || !getCloudAccessToken) {
|
|
@@ -39200,16 +39603,81 @@ async function warmupAgentCapabilitiesOnConnect(params) {
|
|
|
39200
39603
|
})();
|
|
39201
39604
|
}
|
|
39202
39605
|
|
|
39203
|
-
// src/mcp/tools/session-history/fork-
|
|
39204
|
-
|
|
39205
|
-
|
|
39606
|
+
// src/mcp/tools/session-history/fork/mcp-text-result.ts
|
|
39607
|
+
function mcpTextResult(text, isError = false) {
|
|
39608
|
+
return { content: [{ type: "text", text }], ...isError ? { isError: true } : {} };
|
|
39609
|
+
}
|
|
39610
|
+
|
|
39611
|
+
// src/mcp/tools/session-history/fork/call-get-parent-session-turn-transcript.ts
|
|
39612
|
+
async function callGetParentSessionTurnTranscriptTool(ctx, cloud, childSessionId, args) {
|
|
39613
|
+
const turnId = typeof args.turnId === "string" ? args.turnId.trim() : "";
|
|
39614
|
+
if (!turnId) return mcpTextResult("turnId is required.", true);
|
|
39615
|
+
const transcript = await fetchCloudParentTurnTranscript({
|
|
39616
|
+
childSessionId,
|
|
39617
|
+
turnId,
|
|
39618
|
+
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
39619
|
+
getCloudAccessToken: cloud.getCloudAccessToken,
|
|
39620
|
+
e2ee: ctx.e2ee
|
|
39621
|
+
});
|
|
39622
|
+
if (!transcript.ok) return mcpTextResult(transcript.error, true);
|
|
39623
|
+
return mcpTextResult(transcript.text);
|
|
39624
|
+
}
|
|
39625
|
+
|
|
39626
|
+
// src/mcp/tools/session-history/fork/call-list-parent-session-prompts.ts
|
|
39627
|
+
async function callListParentSessionPromptsTool(ctx, cloud, childSessionId, parentSessionId) {
|
|
39628
|
+
const detail = await fetchCloudParentSessionPrompts({
|
|
39629
|
+
childSessionId,
|
|
39630
|
+
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
39631
|
+
getCloudAccessToken: cloud.getCloudAccessToken,
|
|
39632
|
+
e2ee: ctx.e2ee
|
|
39633
|
+
});
|
|
39634
|
+
if (!detail.ok) return mcpTextResult(detail.error, true);
|
|
39635
|
+
const turns = Array.isArray(detail.data.turns) ? detail.data.turns : [];
|
|
39636
|
+
const payload = turns.map((t) => ({
|
|
39637
|
+
turnId: typeof t.turnId === "string" ? t.turnId : "",
|
|
39638
|
+
title: typeof t.title === "string" ? t.title : null,
|
|
39639
|
+
status: typeof t.status === "string" ? t.status : null,
|
|
39640
|
+
promptText: typeof t.promptText === "string" ? t.promptText : null
|
|
39641
|
+
}));
|
|
39642
|
+
return mcpTextResult(JSON.stringify({ parentSessionId, turns: payload }, null, 2));
|
|
39643
|
+
}
|
|
39644
|
+
|
|
39645
|
+
// src/mcp/tools/session-history/fork/tool-names.ts
|
|
39646
|
+
var LIST_PARENT_SESSION_PROMPTS_TOOL2 = "list_parent_session_prompts";
|
|
39647
|
+
var GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL2 = "get_parent_session_turn_transcript";
|
|
39648
|
+
|
|
39649
|
+
// src/mcp/tools/session-history/fork/call-fork-session-mcp-tool.ts
|
|
39650
|
+
async function callForkSessionMcpTool(ctx, cloud, name, args) {
|
|
39651
|
+
const childSessionId = ctx.sessionId.trim();
|
|
39652
|
+
if (!childSessionId) {
|
|
39653
|
+
return mcpTextResult("sessionId is required.", true);
|
|
39654
|
+
}
|
|
39655
|
+
const parentResolved = await resolveParentSessionIdForChild({
|
|
39656
|
+
childSessionId,
|
|
39657
|
+
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
39658
|
+
getCloudAccessToken: cloud.getCloudAccessToken
|
|
39659
|
+
});
|
|
39660
|
+
if (!parentResolved.ok) {
|
|
39661
|
+
return mcpTextResult(parentResolved.error, true);
|
|
39662
|
+
}
|
|
39663
|
+
const parentSessionId = parentResolved.parentSessionId;
|
|
39664
|
+
if (name === LIST_PARENT_SESSION_PROMPTS_TOOL2) {
|
|
39665
|
+
return callListParentSessionPromptsTool(ctx, cloud, childSessionId, parentSessionId);
|
|
39666
|
+
}
|
|
39667
|
+
if (name === GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL2) {
|
|
39668
|
+
return callGetParentSessionTurnTranscriptTool(ctx, cloud, childSessionId, args);
|
|
39669
|
+
}
|
|
39670
|
+
return mcpTextResult(`Unknown fork session tool: ${name}`, true);
|
|
39671
|
+
}
|
|
39672
|
+
|
|
39673
|
+
// src/mcp/tools/session-history/fork/tool-definitions.ts
|
|
39206
39674
|
var SESSION_ID_SCHEMA = {
|
|
39207
39675
|
type: "string",
|
|
39208
39676
|
description: "Id of this forked (child) session \u2014 not the parent session id. Required on every tool call."
|
|
39209
39677
|
};
|
|
39210
39678
|
var FORK_SESSION_MCP_TOOL_DEFINITIONS = [
|
|
39211
39679
|
{
|
|
39212
|
-
name:
|
|
39680
|
+
name: LIST_PARENT_SESSION_PROMPTS_TOOL2,
|
|
39213
39681
|
description: "List user prompts (main turns) from the parent session a fork was created from. Requires sessionId. Returns an error if the session has no parent history (not a fork).",
|
|
39214
39682
|
inputSchema: {
|
|
39215
39683
|
type: "object",
|
|
@@ -39219,7 +39687,7 @@ var FORK_SESSION_MCP_TOOL_DEFINITIONS = [
|
|
|
39219
39687
|
}
|
|
39220
39688
|
},
|
|
39221
39689
|
{
|
|
39222
|
-
name:
|
|
39690
|
+
name: GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL2,
|
|
39223
39691
|
description: "Full transcript for one parent-session turn, including tool calls and agent messages. Requires sessionId and turnId. Returns an error if the session has no parent history (not a fork).",
|
|
39224
39692
|
inputSchema: {
|
|
39225
39693
|
type: "object",
|
|
@@ -39232,56 +39700,133 @@ var FORK_SESSION_MCP_TOOL_DEFINITIONS = [
|
|
|
39232
39700
|
}
|
|
39233
39701
|
}
|
|
39234
39702
|
];
|
|
39235
|
-
|
|
39236
|
-
|
|
39237
|
-
}
|
|
39703
|
+
|
|
39704
|
+
// src/mcp/tools/session-history/fork/is-fork-session-mcp-tool-name.ts
|
|
39238
39705
|
function isForkSessionMcpToolName(name) {
|
|
39239
|
-
return name ===
|
|
39706
|
+
return name === LIST_PARENT_SESSION_PROMPTS_TOOL2 || name === GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL2;
|
|
39240
39707
|
}
|
|
39241
|
-
|
|
39242
|
-
|
|
39243
|
-
|
|
39244
|
-
|
|
39708
|
+
|
|
39709
|
+
// src/mcp/tools/integration-content/tool-names.ts
|
|
39710
|
+
var GET_INTEGRATION_CONTENT_TOOL2 = "get_integration_content";
|
|
39711
|
+
|
|
39712
|
+
// src/mcp/tools/integration-content/cloud/fetch-integration-content.ts
|
|
39713
|
+
async function fetchCloudIntegrationContent(params) {
|
|
39714
|
+
return fetchInternalApiJson({
|
|
39715
|
+
...params,
|
|
39716
|
+
path: `/internal/sessions/${encodeURIComponent(params.sessionId)}/integrations/content`,
|
|
39717
|
+
errorLabel: "Integration content fetch failed",
|
|
39718
|
+
method: "POST",
|
|
39719
|
+
body: {
|
|
39720
|
+
url: params.url,
|
|
39721
|
+
associateAsSessionTicket: params.associateAsSessionTicket !== false
|
|
39722
|
+
}
|
|
39723
|
+
});
|
|
39724
|
+
}
|
|
39725
|
+
|
|
39726
|
+
// src/mcp/tools/integration-content/format-integration-content-for-mcp.ts
|
|
39727
|
+
function formatIntegrationContentForMcp(result) {
|
|
39728
|
+
if (!result.ok) {
|
|
39729
|
+
const lines2 = [`status: ${result.code}`, `message: ${result.message}`];
|
|
39730
|
+
if (result.integrationType) lines2.push(`integrationType: ${result.integrationType}`);
|
|
39731
|
+
if (result.retryable) lines2.push("retryable: true");
|
|
39732
|
+
lines2.push(...formatSessionTicketAssociationLines(result.sessionTicketAssociation));
|
|
39733
|
+
return lines2.join("\n");
|
|
39245
39734
|
}
|
|
39246
|
-
const
|
|
39247
|
-
|
|
39735
|
+
const lines = [
|
|
39736
|
+
formatIntegrationContentBody(result.integrationType, result.content),
|
|
39737
|
+
...formatSessionTicketAssociationLines(result.sessionTicketAssociation)
|
|
39738
|
+
];
|
|
39739
|
+
return lines.join("\n");
|
|
39740
|
+
}
|
|
39741
|
+
function formatSessionTicketAssociationLines(association) {
|
|
39742
|
+
if (association.status === "associated") {
|
|
39743
|
+
const title = association.externalTicket.displayTitle?.trim() || association.externalTicket.normalizedUrl;
|
|
39744
|
+
return ["", "--- session ticket ---", "status: associated", `displayTitle: ${title}`];
|
|
39745
|
+
}
|
|
39746
|
+
if (association.status === "failed") {
|
|
39747
|
+
return ["", "--- session ticket ---", "status: failed", `reason: ${association.reason}`];
|
|
39748
|
+
}
|
|
39749
|
+
return ["", "--- session ticket ---", `status: ${association.status}`, `reason: ${association.reason}`];
|
|
39750
|
+
}
|
|
39751
|
+
function formatIntegrationContentBody(integrationType, content) {
|
|
39752
|
+
const lines = [
|
|
39753
|
+
`integrationType: ${integrationType}`,
|
|
39754
|
+
`title: ${content.title}`,
|
|
39755
|
+
`url: ${content.url}`,
|
|
39756
|
+
"",
|
|
39757
|
+
"--- body ---",
|
|
39758
|
+
content.body
|
|
39759
|
+
];
|
|
39760
|
+
if (content.comments?.length) {
|
|
39761
|
+
lines.push("", "--- comments ---");
|
|
39762
|
+
for (const comment of content.comments) {
|
|
39763
|
+
lines.push(`[${comment.createdAt}] ${comment.author}:`, comment.body, "");
|
|
39764
|
+
}
|
|
39765
|
+
}
|
|
39766
|
+
const threadMessages = content.threadMessages;
|
|
39767
|
+
if (threadMessages?.length) {
|
|
39768
|
+
lines.push("", "--- thread messages ---");
|
|
39769
|
+
for (const msg of threadMessages) {
|
|
39770
|
+
lines.push(`[${msg.ts}] ${msg.displayName}: ${msg.text}`);
|
|
39771
|
+
}
|
|
39772
|
+
}
|
|
39773
|
+
if (content.metadata && Object.keys(content.metadata).length > 0) {
|
|
39774
|
+
lines.push("", "--- metadata ---", JSON.stringify(content.metadata, null, 2));
|
|
39775
|
+
}
|
|
39776
|
+
return lines.join("\n");
|
|
39777
|
+
}
|
|
39778
|
+
|
|
39779
|
+
// src/mcp/tools/integration-content/call-integration-content-mcp-tool.ts
|
|
39780
|
+
async function callIntegrationContentMcpTool(ctx, cloud, name, args) {
|
|
39781
|
+
if (name !== GET_INTEGRATION_CONTENT_TOOL2) {
|
|
39782
|
+
return mcpTextResult(`Unknown integration content tool: ${name}`, true);
|
|
39783
|
+
}
|
|
39784
|
+
const sessionId = ctx.sessionId.trim();
|
|
39785
|
+
if (!sessionId) return mcpTextResult("sessionId is required.", true);
|
|
39786
|
+
const url2 = typeof args.url === "string" ? args.url.trim() : "";
|
|
39787
|
+
if (!url2) return mcpTextResult("url is required.", true);
|
|
39788
|
+
const associateAsSessionTicket = args.associateAsSessionTicket !== false;
|
|
39789
|
+
const fetched = await fetchCloudIntegrationContent({
|
|
39790
|
+
sessionId,
|
|
39791
|
+
url: url2,
|
|
39792
|
+
associateAsSessionTicket,
|
|
39248
39793
|
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
39249
39794
|
getCloudAccessToken: cloud.getCloudAccessToken
|
|
39250
39795
|
});
|
|
39251
|
-
if (!
|
|
39252
|
-
|
|
39253
|
-
|
|
39254
|
-
|
|
39255
|
-
|
|
39256
|
-
|
|
39257
|
-
|
|
39258
|
-
|
|
39259
|
-
|
|
39260
|
-
|
|
39261
|
-
|
|
39262
|
-
|
|
39263
|
-
|
|
39264
|
-
|
|
39265
|
-
|
|
39266
|
-
|
|
39267
|
-
|
|
39268
|
-
|
|
39269
|
-
|
|
39270
|
-
|
|
39271
|
-
|
|
39272
|
-
|
|
39273
|
-
|
|
39274
|
-
|
|
39275
|
-
|
|
39276
|
-
|
|
39277
|
-
|
|
39278
|
-
|
|
39279
|
-
e2ee: ctx.e2ee
|
|
39280
|
-
});
|
|
39281
|
-
if (!transcript.ok) return textResult(transcript.error, true);
|
|
39282
|
-
return textResult(transcript.text);
|
|
39796
|
+
if (!fetched.ok) return mcpTextResult(fetched.error, true);
|
|
39797
|
+
const text = formatIntegrationContentForMcp(fetched.data);
|
|
39798
|
+
const isError = !fetched.data.ok;
|
|
39799
|
+
return mcpTextResult(text, isError);
|
|
39800
|
+
}
|
|
39801
|
+
|
|
39802
|
+
// src/mcp/tools/integration-content/tool-definitions.ts
|
|
39803
|
+
var SESSION_ID_SCHEMA2 = {
|
|
39804
|
+
type: "string",
|
|
39805
|
+
description: "Id of the current session. Required on every tool call so the workspace integration credentials can be resolved."
|
|
39806
|
+
};
|
|
39807
|
+
var INTEGRATION_CONTENT_MCP_TOOL_DEFINITIONS = [
|
|
39808
|
+
{
|
|
39809
|
+
name: GET_INTEGRATION_CONTENT_TOOL2,
|
|
39810
|
+
description: "Fetch the full content of a supported external integration link (Linear, GitHub, Jira, Notion, Slack thread, Zoom meeting, Asana). Requires sessionId and url. By default, links the URL as this session external ticket when the session has none yet. Pass associateAsSessionTicket: false to fetch content only (e.g. additional context links). Returns an error when the URL is unsupported, the integration is not connected, or content is temporarily unavailable (retry may succeed).",
|
|
39811
|
+
inputSchema: {
|
|
39812
|
+
type: "object",
|
|
39813
|
+
properties: {
|
|
39814
|
+
sessionId: SESSION_ID_SCHEMA2,
|
|
39815
|
+
url: { type: "string", description: "External integration URL to fetch" },
|
|
39816
|
+
associateAsSessionTicket: {
|
|
39817
|
+
type: "boolean",
|
|
39818
|
+
description: "Defaults to true. When true and the session has no linked external ticket yet, links this URL as the session external ticket. Pass false when fetching additional links for context only."
|
|
39819
|
+
}
|
|
39820
|
+
},
|
|
39821
|
+
required: ["sessionId", "url"],
|
|
39822
|
+
additionalProperties: false
|
|
39823
|
+
}
|
|
39283
39824
|
}
|
|
39284
|
-
|
|
39825
|
+
];
|
|
39826
|
+
|
|
39827
|
+
// src/mcp/tools/integration-content/index.ts
|
|
39828
|
+
function isIntegrationContentMcpToolName(name) {
|
|
39829
|
+
return name === GET_INTEGRATION_CONTENT_TOOL2;
|
|
39285
39830
|
}
|
|
39286
39831
|
|
|
39287
39832
|
// src/mcp/bridge-mcp-tools.ts
|
|
@@ -39294,7 +39839,7 @@ function requireCloud(shared) {
|
|
|
39294
39839
|
function createBridgeMcpToolRegistry(shared) {
|
|
39295
39840
|
const cloud = requireCloud(shared);
|
|
39296
39841
|
return {
|
|
39297
|
-
listTools: async () => [...FORK_SESSION_MCP_TOOL_DEFINITIONS],
|
|
39842
|
+
listTools: async () => [...FORK_SESSION_MCP_TOOL_DEFINITIONS, ...INTEGRATION_CONTENT_MCP_TOOL_DEFINITIONS],
|
|
39298
39843
|
callTool: async (name, args) => {
|
|
39299
39844
|
if (isForkSessionMcpToolName(name)) {
|
|
39300
39845
|
if (!cloud) {
|
|
@@ -39312,6 +39857,22 @@ function createBridgeMcpToolRegistry(shared) {
|
|
|
39312
39857
|
}
|
|
39313
39858
|
return callForkSessionMcpTool({ ...shared, sessionId }, cloud, name, args);
|
|
39314
39859
|
}
|
|
39860
|
+
if (isIntegrationContentMcpToolName(name)) {
|
|
39861
|
+
if (!cloud) {
|
|
39862
|
+
return {
|
|
39863
|
+
content: [{ type: "text", text: "Bridge MCP tools require cloud API credentials." }],
|
|
39864
|
+
isError: true
|
|
39865
|
+
};
|
|
39866
|
+
}
|
|
39867
|
+
const sessionId = typeof args.sessionId === "string" ? args.sessionId.trim() : "";
|
|
39868
|
+
if (!sessionId) {
|
|
39869
|
+
return {
|
|
39870
|
+
content: [{ type: "text", text: "sessionId is required." }],
|
|
39871
|
+
isError: true
|
|
39872
|
+
};
|
|
39873
|
+
}
|
|
39874
|
+
return callIntegrationContentMcpTool({ ...shared, sessionId }, cloud, name, args);
|
|
39875
|
+
}
|
|
39315
39876
|
throw new Error(`Unknown bridge MCP tool: ${name}`);
|
|
39316
39877
|
}
|
|
39317
39878
|
};
|