@buildautomaton/cli 0.1.48 → 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 +439 -10
- package/dist/cli.js.map +4 -4
- package/dist/index.js +439 -10
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -25174,7 +25174,7 @@ var {
|
|
|
25174
25174
|
} = import_index.default;
|
|
25175
25175
|
|
|
25176
25176
|
// src/cli-version.ts
|
|
25177
|
-
var CLI_VERSION = "0.1.
|
|
25177
|
+
var CLI_VERSION = "0.1.49".length > 0 ? "0.1.49" : "0.0.0-dev";
|
|
25178
25178
|
|
|
25179
25179
|
// src/cli/defaults.ts
|
|
25180
25180
|
var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
|
|
@@ -27678,6 +27678,238 @@ var WebSocketMessageSchema = external_exports.object({
|
|
|
27678
27678
|
error: external_exports.string().optional()
|
|
27679
27679
|
});
|
|
27680
27680
|
|
|
27681
|
+
// ../types/src/integrations/link-detection/linear.ts
|
|
27682
|
+
function detectLinearLink(url2) {
|
|
27683
|
+
const linearMatch = url2.match(
|
|
27684
|
+
/https?:\/\/(?:app\.)?linear\.app\/([^/]+)\/issue\/([A-Z]+-\d+)/i
|
|
27685
|
+
);
|
|
27686
|
+
if (linearMatch) {
|
|
27687
|
+
return {
|
|
27688
|
+
url: url2,
|
|
27689
|
+
integrationType: "linear",
|
|
27690
|
+
resourceType: "work-item",
|
|
27691
|
+
resourceId: linearMatch[2],
|
|
27692
|
+
workspaceId: linearMatch[1]
|
|
27693
|
+
};
|
|
27694
|
+
}
|
|
27695
|
+
return null;
|
|
27696
|
+
}
|
|
27697
|
+
|
|
27698
|
+
// ../types/src/integrations/link-detection/github.ts
|
|
27699
|
+
function detectGitHubLink(url2) {
|
|
27700
|
+
const githubIssueMatch = url2.match(
|
|
27701
|
+
/https?:\/\/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/i
|
|
27702
|
+
);
|
|
27703
|
+
if (githubIssueMatch) {
|
|
27704
|
+
return {
|
|
27705
|
+
url: url2,
|
|
27706
|
+
integrationType: "github",
|
|
27707
|
+
resourceType: "issue",
|
|
27708
|
+
resourceId: githubIssueMatch[3],
|
|
27709
|
+
owner: githubIssueMatch[1],
|
|
27710
|
+
repo: githubIssueMatch[2]
|
|
27711
|
+
};
|
|
27712
|
+
}
|
|
27713
|
+
const githubPRMatch = url2.match(
|
|
27714
|
+
/https?:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/(\d+)/i
|
|
27715
|
+
);
|
|
27716
|
+
if (githubPRMatch) {
|
|
27717
|
+
return {
|
|
27718
|
+
url: url2,
|
|
27719
|
+
integrationType: "github",
|
|
27720
|
+
resourceType: "pull-request",
|
|
27721
|
+
resourceId: githubPRMatch[3],
|
|
27722
|
+
owner: githubPRMatch[1],
|
|
27723
|
+
repo: githubPRMatch[2]
|
|
27724
|
+
};
|
|
27725
|
+
}
|
|
27726
|
+
return null;
|
|
27727
|
+
}
|
|
27728
|
+
|
|
27729
|
+
// ../types/src/integrations/link-detection/jira.ts
|
|
27730
|
+
function detectJIRALink(url2) {
|
|
27731
|
+
const jiraMatch = url2.match(
|
|
27732
|
+
/https?:\/\/([^/]+)\.atlassian\.net\/(?:browse|jira\/software\/projects\/[^/]+\/issues)\/([A-Z]+-\d+)/i
|
|
27733
|
+
);
|
|
27734
|
+
if (jiraMatch) {
|
|
27735
|
+
return {
|
|
27736
|
+
url: url2,
|
|
27737
|
+
integrationType: "jira",
|
|
27738
|
+
resourceType: "issue",
|
|
27739
|
+
resourceId: jiraMatch[2],
|
|
27740
|
+
projectKey: jiraMatch[2].split("-")[0]
|
|
27741
|
+
};
|
|
27742
|
+
}
|
|
27743
|
+
return null;
|
|
27744
|
+
}
|
|
27745
|
+
|
|
27746
|
+
// ../types/src/integrations/link-detection/notion.ts
|
|
27747
|
+
function formatNotionPageId(hex) {
|
|
27748
|
+
if (hex.length !== 32) return hex;
|
|
27749
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
27750
|
+
}
|
|
27751
|
+
function detectNotionLink(url2) {
|
|
27752
|
+
const standardMatch = url2.match(
|
|
27753
|
+
/https?:\/\/(?:www\.)?notion\.(?:so|site)\/(?:[^/#?]+\/)?(?:[^/#?-]+-)?([a-f0-9]{32})/i
|
|
27754
|
+
);
|
|
27755
|
+
if (standardMatch) {
|
|
27756
|
+
return {
|
|
27757
|
+
url: url2,
|
|
27758
|
+
integrationType: "notion",
|
|
27759
|
+
resourceType: "page",
|
|
27760
|
+
resourceId: formatNotionPageId(standardMatch[1])
|
|
27761
|
+
};
|
|
27762
|
+
}
|
|
27763
|
+
const siteMatch = url2.match(
|
|
27764
|
+
/https?:\/\/([^.]+)\.notion\.(?:so|site)\/(?:[^/#?-]+-)?([a-f0-9]{32})/i
|
|
27765
|
+
);
|
|
27766
|
+
if (siteMatch) {
|
|
27767
|
+
return {
|
|
27768
|
+
url: url2,
|
|
27769
|
+
integrationType: "notion",
|
|
27770
|
+
resourceType: "page",
|
|
27771
|
+
resourceId: formatNotionPageId(siteMatch[2]),
|
|
27772
|
+
notionWorkspaceId: siteMatch[1]
|
|
27773
|
+
};
|
|
27774
|
+
}
|
|
27775
|
+
return null;
|
|
27776
|
+
}
|
|
27777
|
+
|
|
27778
|
+
// ../types/src/integrations/link-detection/slack.ts
|
|
27779
|
+
function detectSlackLink(url2) {
|
|
27780
|
+
const archiveThreadMatch = url2.match(
|
|
27781
|
+
/https?:\/\/(?:([^./]+)\.)?slack\.com\/archives\/([A-Z0-9]+)\/p(\d+)(?:\?.*)?$/i
|
|
27782
|
+
);
|
|
27783
|
+
if (archiveThreadMatch) {
|
|
27784
|
+
return {
|
|
27785
|
+
url: url2,
|
|
27786
|
+
integrationType: "slack",
|
|
27787
|
+
resourceType: "thread",
|
|
27788
|
+
resourceId: `${archiveThreadMatch[2]}-${archiveThreadMatch[3]}`,
|
|
27789
|
+
isChannel: false
|
|
27790
|
+
};
|
|
27791
|
+
}
|
|
27792
|
+
const appThreadMatch = url2.match(
|
|
27793
|
+
/https?:\/\/app\.slack\.com\/client\/([^/]+)\/([A-Z0-9]+)\/thread\/[A-Z0-9]+-(\d+)/i
|
|
27794
|
+
);
|
|
27795
|
+
if (appThreadMatch) {
|
|
27796
|
+
return {
|
|
27797
|
+
url: url2,
|
|
27798
|
+
integrationType: "slack",
|
|
27799
|
+
resourceType: "thread",
|
|
27800
|
+
resourceId: `${appThreadMatch[2]}-${appThreadMatch[3]}`,
|
|
27801
|
+
isChannel: false
|
|
27802
|
+
};
|
|
27803
|
+
}
|
|
27804
|
+
const channelOnlyMatch = url2.match(
|
|
27805
|
+
/https?:\/\/(?:app\.)?(?:([^./]+)\.)?slack\.com\/archives\/([A-Z0-9]+)\/?(\?.*)?$/i
|
|
27806
|
+
);
|
|
27807
|
+
if (channelOnlyMatch && !url2.includes("/p")) {
|
|
27808
|
+
return {
|
|
27809
|
+
url: url2,
|
|
27810
|
+
integrationType: "slack",
|
|
27811
|
+
resourceType: "channel",
|
|
27812
|
+
resourceId: channelOnlyMatch[2],
|
|
27813
|
+
isChannel: true
|
|
27814
|
+
};
|
|
27815
|
+
}
|
|
27816
|
+
return null;
|
|
27817
|
+
}
|
|
27818
|
+
|
|
27819
|
+
// ../types/src/integrations/link-detection/zoom.ts
|
|
27820
|
+
function detectZoomLink(url2) {
|
|
27821
|
+
try {
|
|
27822
|
+
const u = new URL(url2);
|
|
27823
|
+
const host = u.hostname.toLowerCase();
|
|
27824
|
+
if (!host.endsWith("zoom.us") && !host.endsWith("zoom.com")) return null;
|
|
27825
|
+
const pathParts = u.pathname.split("/").filter(Boolean);
|
|
27826
|
+
if (pathParts.length >= 2 && (pathParts[0] === "j" || pathParts[0] === "s" || pathParts[0] === "my")) {
|
|
27827
|
+
const meetingId = pathParts[1].replace(/\s/g, "");
|
|
27828
|
+
if (meetingId.length >= 9) {
|
|
27829
|
+
return {
|
|
27830
|
+
url: url2,
|
|
27831
|
+
integrationType: "zoom",
|
|
27832
|
+
resourceType: "meeting",
|
|
27833
|
+
resourceId: meetingId,
|
|
27834
|
+
zoomMeetingId: meetingId
|
|
27835
|
+
};
|
|
27836
|
+
}
|
|
27837
|
+
}
|
|
27838
|
+
} catch {
|
|
27839
|
+
}
|
|
27840
|
+
return null;
|
|
27841
|
+
}
|
|
27842
|
+
|
|
27843
|
+
// ../types/src/integrations/link-detection/asana.ts
|
|
27844
|
+
var ASANA_TASK_GID = /\d{10,}/;
|
|
27845
|
+
function parseAsanaTaskGid(segment) {
|
|
27846
|
+
const trimmed2 = segment.trim();
|
|
27847
|
+
if (!ASANA_TASK_GID.test(trimmed2)) return null;
|
|
27848
|
+
return trimmed2;
|
|
27849
|
+
}
|
|
27850
|
+
function detectAsanaLink(url2) {
|
|
27851
|
+
const v1ProjectMatch = url2.match(
|
|
27852
|
+
/https?:\/\/app\.asana\.com\/1\/[^/]+\/project\/([^/?#]+)\/task\/([^/?#]+)/i
|
|
27853
|
+
);
|
|
27854
|
+
if (v1ProjectMatch) {
|
|
27855
|
+
const taskGid = parseAsanaTaskGid(v1ProjectMatch[2]);
|
|
27856
|
+
if (!taskGid) return null;
|
|
27857
|
+
return {
|
|
27858
|
+
url: url2,
|
|
27859
|
+
integrationType: "asana",
|
|
27860
|
+
resourceType: "task",
|
|
27861
|
+
resourceId: taskGid,
|
|
27862
|
+
asanaProjectGid: v1ProjectMatch[1]
|
|
27863
|
+
};
|
|
27864
|
+
}
|
|
27865
|
+
const v1TaskMatch = url2.match(/https?:\/\/app\.asana\.com\/1\/[^/]+(?:\/[^/]+)*\/task\/([^/?#]+)/i);
|
|
27866
|
+
if (v1TaskMatch) {
|
|
27867
|
+
const taskGid = parseAsanaTaskGid(v1TaskMatch[1]);
|
|
27868
|
+
if (!taskGid) return null;
|
|
27869
|
+
return {
|
|
27870
|
+
url: url2,
|
|
27871
|
+
integrationType: "asana",
|
|
27872
|
+
resourceType: "task",
|
|
27873
|
+
resourceId: taskGid
|
|
27874
|
+
};
|
|
27875
|
+
}
|
|
27876
|
+
const legacyMatch = url2.match(/https?:\/\/app\.asana\.com\/0\/([^/?#]+)\/([^/?#]+)/i);
|
|
27877
|
+
if (legacyMatch) {
|
|
27878
|
+
const projectGid = legacyMatch[1];
|
|
27879
|
+
const taskGid = parseAsanaTaskGid(legacyMatch[2]);
|
|
27880
|
+
if (!taskGid) return null;
|
|
27881
|
+
if (projectGid === "inbox" || projectGid === "my_tasks") {
|
|
27882
|
+
return null;
|
|
27883
|
+
}
|
|
27884
|
+
return {
|
|
27885
|
+
url: url2,
|
|
27886
|
+
integrationType: "asana",
|
|
27887
|
+
resourceType: "task",
|
|
27888
|
+
resourceId: taskGid,
|
|
27889
|
+
asanaProjectGid: projectGid === "0" ? void 0 : projectGid
|
|
27890
|
+
};
|
|
27891
|
+
}
|
|
27892
|
+
return null;
|
|
27893
|
+
}
|
|
27894
|
+
|
|
27895
|
+
// ../types/src/integrations/link-detection/index.ts
|
|
27896
|
+
function detectIntegrationLink(url2) {
|
|
27897
|
+
return detectLinearLink(url2) || detectGitHubLink(url2) || detectJIRALink(url2) || detectNotionLink(url2) || detectSlackLink(url2) || detectZoomLink(url2) || detectAsanaLink(url2);
|
|
27898
|
+
}
|
|
27899
|
+
function extractIntegrationLinks(text) {
|
|
27900
|
+
const urlRegex = /https?:\/\/[^\s<>"{}|\\^`[\]]+/gi;
|
|
27901
|
+
const urls = text.match(urlRegex) || [];
|
|
27902
|
+
const links = [];
|
|
27903
|
+
for (const url2 of urls) {
|
|
27904
|
+
const detected = detectIntegrationLink(url2);
|
|
27905
|
+
if (detected) links.push(detected);
|
|
27906
|
+
}
|
|
27907
|
+
return links;
|
|
27908
|
+
}
|
|
27909
|
+
function extractFetchableIntegrationLinks(text) {
|
|
27910
|
+
return extractIntegrationLinks(text).filter((link) => !(link.integrationType === "slack" && link.isChannel));
|
|
27911
|
+
}
|
|
27912
|
+
|
|
27681
27913
|
// ../types/src/checkpoints.ts
|
|
27682
27914
|
init_zod();
|
|
27683
27915
|
var CheckpointKindSchema = external_exports.enum(["daily", "weekly", "overall"]);
|
|
@@ -28105,6 +28337,16 @@ var GitRepoMetaSchema = external_exports.object({
|
|
|
28105
28337
|
updatedAt: external_exports.string()
|
|
28106
28338
|
});
|
|
28107
28339
|
|
|
28340
|
+
// ../types/src/bridge-mcp-tool-display.ts
|
|
28341
|
+
var GET_INTEGRATION_CONTENT_TOOL = "get_integration_content";
|
|
28342
|
+
var LIST_PARENT_SESSION_PROMPTS_TOOL = "list_parent_session_prompts";
|
|
28343
|
+
var GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL = "get_parent_session_turn_transcript";
|
|
28344
|
+
var BRIDGE_MCP_TOOL_LABELS = {
|
|
28345
|
+
[GET_INTEGRATION_CONTENT_TOOL]: "Fetch external ticket content",
|
|
28346
|
+
[LIST_PARENT_SESSION_PROMPTS_TOOL]: "List parent session prompts",
|
|
28347
|
+
[GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL]: "Read parent session transcript"
|
|
28348
|
+
};
|
|
28349
|
+
|
|
28108
28350
|
// ../types/src/claude-code-permission-mode.ts
|
|
28109
28351
|
var CLAUDE_CODE_PERMISSION_MODES = [
|
|
28110
28352
|
"default",
|
|
@@ -36155,7 +36397,15 @@ async function fetchInternalApiJson(params) {
|
|
|
36155
36397
|
const token = params.getCloudAccessToken();
|
|
36156
36398
|
if (!token) return { ok: false, error: "Missing cloud access token." };
|
|
36157
36399
|
const url2 = `${internalApiBase(params.cloudApiBaseUrl)}${params.path}`;
|
|
36158
|
-
const
|
|
36400
|
+
const method = params.method ?? "GET";
|
|
36401
|
+
const res = await fetch(url2, {
|
|
36402
|
+
method,
|
|
36403
|
+
headers: {
|
|
36404
|
+
Authorization: `Bearer ${token}`,
|
|
36405
|
+
...params.body != null ? { "Content-Type": "application/json" } : {}
|
|
36406
|
+
},
|
|
36407
|
+
...params.body != null ? { body: JSON.stringify(params.body) } : {}
|
|
36408
|
+
});
|
|
36159
36409
|
if (!res.ok) {
|
|
36160
36410
|
const t = await res.text().catch(() => "");
|
|
36161
36411
|
return { ok: false, error: `${params.errorLabel} (${res.status}): ${t.slice(0, 200)}` };
|
|
@@ -36272,6 +36522,39 @@ async function enrichForkedSessionPromptForAgent(params) {
|
|
|
36272
36522
|
return buildForkedSessionAgentPrompt(params.promptText, params.sessionId, parentSessionId);
|
|
36273
36523
|
}
|
|
36274
36524
|
|
|
36525
|
+
// src/agents/acp/build-integration-content-agent-prompt-note.ts
|
|
36526
|
+
function buildIntegrationContentAgentPromptNote(sessionId) {
|
|
36527
|
+
const sessionRef = sessionId.trim();
|
|
36528
|
+
return [
|
|
36529
|
+
"The user message includes link(s) to external integration resources (Linear, GitHub, Jira, Notion, Slack thread, Zoom, or Asana).",
|
|
36530
|
+
"Use the get_integration_content MCP tool on the buildautomaton-bridge server to fetch the full content of each link.",
|
|
36531
|
+
`When calling the tool, pass sessionId "${sessionRef}" and the URL as url.`,
|
|
36532
|
+
"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).",
|
|
36533
|
+
"If the tool reports unsupported_url, do not retry with the same URL. If it reports temporarily_unavailable, you may retry later."
|
|
36534
|
+
].join("\n");
|
|
36535
|
+
}
|
|
36536
|
+
function injectIntegrationContentAgentPromptNote(agentPrompt, sessionId) {
|
|
36537
|
+
const note = buildIntegrationContentAgentPromptNote(sessionId);
|
|
36538
|
+
const marker = "\nUser request:\n";
|
|
36539
|
+
const idx = agentPrompt.indexOf(marker);
|
|
36540
|
+
if (idx >= 0) {
|
|
36541
|
+
return `${agentPrompt.slice(0, idx)}
|
|
36542
|
+
${note}${agentPrompt.slice(idx)}`;
|
|
36543
|
+
}
|
|
36544
|
+
return `${note}
|
|
36545
|
+
|
|
36546
|
+
${agentPrompt.trim()}`;
|
|
36547
|
+
}
|
|
36548
|
+
|
|
36549
|
+
// src/agents/acp/enrich-integration-content-prompt-for-agent.ts
|
|
36550
|
+
function enrichIntegrationContentPromptForAgent(params) {
|
|
36551
|
+
if (!params.sessionId.trim()) return params.agentPromptText;
|
|
36552
|
+
if (extractFetchableIntegrationLinks(params.originalPromptText).length === 0) {
|
|
36553
|
+
return params.agentPromptText;
|
|
36554
|
+
}
|
|
36555
|
+
return injectIntegrationContentAgentPromptNote(params.agentPromptText, params.sessionId);
|
|
36556
|
+
}
|
|
36557
|
+
|
|
36275
36558
|
// src/agents/acp/send-prompt-to-agent.ts
|
|
36276
36559
|
async function sendPromptToAgent(options) {
|
|
36277
36560
|
const {
|
|
@@ -36302,6 +36585,13 @@ async function sendPromptToAgent(options) {
|
|
|
36302
36585
|
getCloudAccessToken
|
|
36303
36586
|
});
|
|
36304
36587
|
}
|
|
36588
|
+
if (sessionId) {
|
|
36589
|
+
agentPromptText = enrichIntegrationContentPromptForAgent({
|
|
36590
|
+
sessionId,
|
|
36591
|
+
originalPromptText: promptText,
|
|
36592
|
+
agentPromptText
|
|
36593
|
+
});
|
|
36594
|
+
}
|
|
36305
36595
|
let sendOpts = {};
|
|
36306
36596
|
if (attachments && attachments.length > 0) {
|
|
36307
36597
|
if (!sessionId || !cloudApiBaseUrl || !getCloudAccessToken) {
|
|
@@ -42576,8 +42866,8 @@ async function callListParentSessionPromptsTool(ctx, cloud, childSessionId, pare
|
|
|
42576
42866
|
}
|
|
42577
42867
|
|
|
42578
42868
|
// src/mcp/tools/session-history/fork/tool-names.ts
|
|
42579
|
-
var
|
|
42580
|
-
var
|
|
42869
|
+
var LIST_PARENT_SESSION_PROMPTS_TOOL2 = "list_parent_session_prompts";
|
|
42870
|
+
var GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL2 = "get_parent_session_turn_transcript";
|
|
42581
42871
|
|
|
42582
42872
|
// src/mcp/tools/session-history/fork/call-fork-session-mcp-tool.ts
|
|
42583
42873
|
async function callForkSessionMcpTool(ctx, cloud, name, args) {
|
|
@@ -42594,10 +42884,10 @@ async function callForkSessionMcpTool(ctx, cloud, name, args) {
|
|
|
42594
42884
|
return mcpTextResult(parentResolved.error, true);
|
|
42595
42885
|
}
|
|
42596
42886
|
const parentSessionId = parentResolved.parentSessionId;
|
|
42597
|
-
if (name ===
|
|
42887
|
+
if (name === LIST_PARENT_SESSION_PROMPTS_TOOL2) {
|
|
42598
42888
|
return callListParentSessionPromptsTool(ctx, cloud, childSessionId, parentSessionId);
|
|
42599
42889
|
}
|
|
42600
|
-
if (name ===
|
|
42890
|
+
if (name === GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL2) {
|
|
42601
42891
|
return callGetParentSessionTurnTranscriptTool(ctx, cloud, childSessionId, args);
|
|
42602
42892
|
}
|
|
42603
42893
|
return mcpTextResult(`Unknown fork session tool: ${name}`, true);
|
|
@@ -42610,7 +42900,7 @@ var SESSION_ID_SCHEMA = {
|
|
|
42610
42900
|
};
|
|
42611
42901
|
var FORK_SESSION_MCP_TOOL_DEFINITIONS = [
|
|
42612
42902
|
{
|
|
42613
|
-
name:
|
|
42903
|
+
name: LIST_PARENT_SESSION_PROMPTS_TOOL2,
|
|
42614
42904
|
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).",
|
|
42615
42905
|
inputSchema: {
|
|
42616
42906
|
type: "object",
|
|
@@ -42620,7 +42910,7 @@ var FORK_SESSION_MCP_TOOL_DEFINITIONS = [
|
|
|
42620
42910
|
}
|
|
42621
42911
|
},
|
|
42622
42912
|
{
|
|
42623
|
-
name:
|
|
42913
|
+
name: GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL2,
|
|
42624
42914
|
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).",
|
|
42625
42915
|
inputSchema: {
|
|
42626
42916
|
type: "object",
|
|
@@ -42636,7 +42926,130 @@ var FORK_SESSION_MCP_TOOL_DEFINITIONS = [
|
|
|
42636
42926
|
|
|
42637
42927
|
// src/mcp/tools/session-history/fork/is-fork-session-mcp-tool-name.ts
|
|
42638
42928
|
function isForkSessionMcpToolName(name) {
|
|
42639
|
-
return name ===
|
|
42929
|
+
return name === LIST_PARENT_SESSION_PROMPTS_TOOL2 || name === GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL2;
|
|
42930
|
+
}
|
|
42931
|
+
|
|
42932
|
+
// src/mcp/tools/integration-content/tool-names.ts
|
|
42933
|
+
var GET_INTEGRATION_CONTENT_TOOL2 = "get_integration_content";
|
|
42934
|
+
|
|
42935
|
+
// src/mcp/tools/integration-content/cloud/fetch-integration-content.ts
|
|
42936
|
+
async function fetchCloudIntegrationContent(params) {
|
|
42937
|
+
return fetchInternalApiJson({
|
|
42938
|
+
...params,
|
|
42939
|
+
path: `/internal/sessions/${encodeURIComponent(params.sessionId)}/integrations/content`,
|
|
42940
|
+
errorLabel: "Integration content fetch failed",
|
|
42941
|
+
method: "POST",
|
|
42942
|
+
body: {
|
|
42943
|
+
url: params.url,
|
|
42944
|
+
associateAsSessionTicket: params.associateAsSessionTicket !== false
|
|
42945
|
+
}
|
|
42946
|
+
});
|
|
42947
|
+
}
|
|
42948
|
+
|
|
42949
|
+
// src/mcp/tools/integration-content/format-integration-content-for-mcp.ts
|
|
42950
|
+
function formatIntegrationContentForMcp(result) {
|
|
42951
|
+
if (!result.ok) {
|
|
42952
|
+
const lines2 = [`status: ${result.code}`, `message: ${result.message}`];
|
|
42953
|
+
if (result.integrationType) lines2.push(`integrationType: ${result.integrationType}`);
|
|
42954
|
+
if (result.retryable) lines2.push("retryable: true");
|
|
42955
|
+
lines2.push(...formatSessionTicketAssociationLines(result.sessionTicketAssociation));
|
|
42956
|
+
return lines2.join("\n");
|
|
42957
|
+
}
|
|
42958
|
+
const lines = [
|
|
42959
|
+
formatIntegrationContentBody(result.integrationType, result.content),
|
|
42960
|
+
...formatSessionTicketAssociationLines(result.sessionTicketAssociation)
|
|
42961
|
+
];
|
|
42962
|
+
return lines.join("\n");
|
|
42963
|
+
}
|
|
42964
|
+
function formatSessionTicketAssociationLines(association) {
|
|
42965
|
+
if (association.status === "associated") {
|
|
42966
|
+
const title = association.externalTicket.displayTitle?.trim() || association.externalTicket.normalizedUrl;
|
|
42967
|
+
return ["", "--- session ticket ---", "status: associated", `displayTitle: ${title}`];
|
|
42968
|
+
}
|
|
42969
|
+
if (association.status === "failed") {
|
|
42970
|
+
return ["", "--- session ticket ---", "status: failed", `reason: ${association.reason}`];
|
|
42971
|
+
}
|
|
42972
|
+
return ["", "--- session ticket ---", `status: ${association.status}`, `reason: ${association.reason}`];
|
|
42973
|
+
}
|
|
42974
|
+
function formatIntegrationContentBody(integrationType, content) {
|
|
42975
|
+
const lines = [
|
|
42976
|
+
`integrationType: ${integrationType}`,
|
|
42977
|
+
`title: ${content.title}`,
|
|
42978
|
+
`url: ${content.url}`,
|
|
42979
|
+
"",
|
|
42980
|
+
"--- body ---",
|
|
42981
|
+
content.body
|
|
42982
|
+
];
|
|
42983
|
+
if (content.comments?.length) {
|
|
42984
|
+
lines.push("", "--- comments ---");
|
|
42985
|
+
for (const comment of content.comments) {
|
|
42986
|
+
lines.push(`[${comment.createdAt}] ${comment.author}:`, comment.body, "");
|
|
42987
|
+
}
|
|
42988
|
+
}
|
|
42989
|
+
const threadMessages = content.threadMessages;
|
|
42990
|
+
if (threadMessages?.length) {
|
|
42991
|
+
lines.push("", "--- thread messages ---");
|
|
42992
|
+
for (const msg of threadMessages) {
|
|
42993
|
+
lines.push(`[${msg.ts}] ${msg.displayName}: ${msg.text}`);
|
|
42994
|
+
}
|
|
42995
|
+
}
|
|
42996
|
+
if (content.metadata && Object.keys(content.metadata).length > 0) {
|
|
42997
|
+
lines.push("", "--- metadata ---", JSON.stringify(content.metadata, null, 2));
|
|
42998
|
+
}
|
|
42999
|
+
return lines.join("\n");
|
|
43000
|
+
}
|
|
43001
|
+
|
|
43002
|
+
// src/mcp/tools/integration-content/call-integration-content-mcp-tool.ts
|
|
43003
|
+
async function callIntegrationContentMcpTool(ctx, cloud, name, args) {
|
|
43004
|
+
if (name !== GET_INTEGRATION_CONTENT_TOOL2) {
|
|
43005
|
+
return mcpTextResult(`Unknown integration content tool: ${name}`, true);
|
|
43006
|
+
}
|
|
43007
|
+
const sessionId = ctx.sessionId.trim();
|
|
43008
|
+
if (!sessionId) return mcpTextResult("sessionId is required.", true);
|
|
43009
|
+
const url2 = typeof args.url === "string" ? args.url.trim() : "";
|
|
43010
|
+
if (!url2) return mcpTextResult("url is required.", true);
|
|
43011
|
+
const associateAsSessionTicket = args.associateAsSessionTicket !== false;
|
|
43012
|
+
const fetched = await fetchCloudIntegrationContent({
|
|
43013
|
+
sessionId,
|
|
43014
|
+
url: url2,
|
|
43015
|
+
associateAsSessionTicket,
|
|
43016
|
+
cloudApiBaseUrl: cloud.cloudApiBaseUrl,
|
|
43017
|
+
getCloudAccessToken: cloud.getCloudAccessToken
|
|
43018
|
+
});
|
|
43019
|
+
if (!fetched.ok) return mcpTextResult(fetched.error, true);
|
|
43020
|
+
const text = formatIntegrationContentForMcp(fetched.data);
|
|
43021
|
+
const isError = !fetched.data.ok;
|
|
43022
|
+
return mcpTextResult(text, isError);
|
|
43023
|
+
}
|
|
43024
|
+
|
|
43025
|
+
// src/mcp/tools/integration-content/tool-definitions.ts
|
|
43026
|
+
var SESSION_ID_SCHEMA2 = {
|
|
43027
|
+
type: "string",
|
|
43028
|
+
description: "Id of the current session. Required on every tool call so the workspace integration credentials can be resolved."
|
|
43029
|
+
};
|
|
43030
|
+
var INTEGRATION_CONTENT_MCP_TOOL_DEFINITIONS = [
|
|
43031
|
+
{
|
|
43032
|
+
name: GET_INTEGRATION_CONTENT_TOOL2,
|
|
43033
|
+
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).",
|
|
43034
|
+
inputSchema: {
|
|
43035
|
+
type: "object",
|
|
43036
|
+
properties: {
|
|
43037
|
+
sessionId: SESSION_ID_SCHEMA2,
|
|
43038
|
+
url: { type: "string", description: "External integration URL to fetch" },
|
|
43039
|
+
associateAsSessionTicket: {
|
|
43040
|
+
type: "boolean",
|
|
43041
|
+
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."
|
|
43042
|
+
}
|
|
43043
|
+
},
|
|
43044
|
+
required: ["sessionId", "url"],
|
|
43045
|
+
additionalProperties: false
|
|
43046
|
+
}
|
|
43047
|
+
}
|
|
43048
|
+
];
|
|
43049
|
+
|
|
43050
|
+
// src/mcp/tools/integration-content/index.ts
|
|
43051
|
+
function isIntegrationContentMcpToolName(name) {
|
|
43052
|
+
return name === GET_INTEGRATION_CONTENT_TOOL2;
|
|
42640
43053
|
}
|
|
42641
43054
|
|
|
42642
43055
|
// src/mcp/bridge-mcp-tools.ts
|
|
@@ -42649,7 +43062,7 @@ function requireCloud(shared) {
|
|
|
42649
43062
|
function createBridgeMcpToolRegistry(shared) {
|
|
42650
43063
|
const cloud = requireCloud(shared);
|
|
42651
43064
|
return {
|
|
42652
|
-
listTools: async () => [...FORK_SESSION_MCP_TOOL_DEFINITIONS],
|
|
43065
|
+
listTools: async () => [...FORK_SESSION_MCP_TOOL_DEFINITIONS, ...INTEGRATION_CONTENT_MCP_TOOL_DEFINITIONS],
|
|
42653
43066
|
callTool: async (name, args) => {
|
|
42654
43067
|
if (isForkSessionMcpToolName(name)) {
|
|
42655
43068
|
if (!cloud) {
|
|
@@ -42667,6 +43080,22 @@ function createBridgeMcpToolRegistry(shared) {
|
|
|
42667
43080
|
}
|
|
42668
43081
|
return callForkSessionMcpTool({ ...shared, sessionId }, cloud, name, args);
|
|
42669
43082
|
}
|
|
43083
|
+
if (isIntegrationContentMcpToolName(name)) {
|
|
43084
|
+
if (!cloud) {
|
|
43085
|
+
return {
|
|
43086
|
+
content: [{ type: "text", text: "Bridge MCP tools require cloud API credentials." }],
|
|
43087
|
+
isError: true
|
|
43088
|
+
};
|
|
43089
|
+
}
|
|
43090
|
+
const sessionId = typeof args.sessionId === "string" ? args.sessionId.trim() : "";
|
|
43091
|
+
if (!sessionId) {
|
|
43092
|
+
return {
|
|
43093
|
+
content: [{ type: "text", text: "sessionId is required." }],
|
|
43094
|
+
isError: true
|
|
43095
|
+
};
|
|
43096
|
+
}
|
|
43097
|
+
return callIntegrationContentMcpTool({ ...shared, sessionId }, cloud, name, args);
|
|
43098
|
+
}
|
|
42670
43099
|
throw new Error(`Unknown bridge MCP tool: ${name}`);
|
|
42671
43100
|
}
|
|
42672
43101
|
};
|