@lovelybunch/api 1.0.76-alpha.7 → 1.0.76-alpha.8
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/lib/mcp-client.d.ts +39 -0
- package/dist/lib/mcp-client.js +131 -0
- package/dist/lib/terminal/terminal-manager.js +31 -0
- package/dist/routes/api/v1/ai/tools.d.ts +17 -0
- package/dist/routes/api/v1/ai/tools.js +931 -0
- package/dist/routes/api/v1/context/knowledge/[filename]/index.d.ts +1 -0
- package/dist/routes/api/v1/context/knowledge/[filename]/index.js +1 -0
- package/dist/routes/api/v1/context/knowledge/[filename]/route.d.ts +3 -0
- package/dist/routes/api/v1/context/knowledge/[filename]/route.js +254 -0
- package/dist/routes/api/v1/context/knowledge/index.d.ts +1 -0
- package/dist/routes/api/v1/context/knowledge/index.js +1 -0
- package/dist/routes/api/v1/context/knowledge/route.d.ts +3 -0
- package/dist/routes/api/v1/context/knowledge/route.js +176 -0
- package/dist/routes/api/v1/proposals/[id]/route.d.ts +337 -0
- package/dist/routes/api/v1/proposals/[id]/route.js +165 -0
- package/dist/routes/api/v1/proposals/index.d.ts +3 -0
- package/dist/routes/api/v1/proposals/index.js +10 -0
- package/dist/routes/api/v1/proposals/route.d.ts +315 -0
- package/dist/routes/api/v1/proposals/route.js +129 -0
- package/dist/routes/api/v1/terminal/[proposalId]/create/index.d.ts +3 -0
- package/dist/routes/api/v1/terminal/[proposalId]/create/index.js +5 -0
- package/dist/routes/api/v1/terminal/[proposalId]/create/route.d.ts +10 -0
- package/dist/routes/api/v1/terminal/[proposalId]/create/route.js +27 -0
- package/dist/routes/api/v1/terminal/[proposalId]/destroy/index.d.ts +3 -0
- package/dist/routes/api/v1/terminal/[proposalId]/destroy/index.js +5 -0
- package/dist/routes/api/v1/terminal/[proposalId]/destroy/route.d.ts +10 -0
- package/dist/routes/api/v1/terminal/[proposalId]/destroy/route.js +21 -0
- package/dist/routes/api/v1/terminal/[proposalId]/resize/index.d.ts +3 -0
- package/dist/routes/api/v1/terminal/[proposalId]/resize/index.js +5 -0
- package/dist/routes/api/v1/terminal/[proposalId]/resize/route.d.ts +10 -0
- package/dist/routes/api/v1/terminal/[proposalId]/resize/route.js +21 -0
- package/dist/routes/api/v1/terminal/code/route.js +9 -16
- package/package.json +4 -4
- package/static/assets/{ActivityPage-Dmuu0c1r.js → ActivityPage-uL-Qknui.js} +1 -1
- package/static/assets/{ApiKeysSettingsPage-BtpcHzBO.js → ApiKeysSettingsPage-BhaH6ZYP.js} +1 -1
- package/static/assets/{ArchitectureEditPage-CRK7l_pP.js → ArchitectureEditPage-BWKyKi3T.js} +1 -1
- package/static/assets/{ArchitecturePage-Bb3Mr04V.js → ArchitecturePage-Dtm0OAac.js} +1 -1
- package/static/assets/{AuthSettingsPage-BmcnjO0-.js → AuthSettingsPage-D0MQlHyh.js} +1 -1
- package/static/assets/{CallbackPage-hQdlfqNL.js → CallbackPage-Bz4m3_W8.js} +1 -1
- package/static/assets/{CodePage-BlGRZW1v.js → CodePage-BuO2K_xx.js} +1 -1
- package/static/assets/{CollapsibleSection-dXTDG5xK.js → CollapsibleSection-CxX11hr-.js} +1 -1
- package/static/assets/{DashboardPage-SNgPwXuZ.js → DashboardPage-B3HR1UM7.js} +1 -1
- package/static/assets/{GitPage-CmRS64Yi.js → GitPage-Dm36PRw_.js} +1 -1
- package/static/assets/{GitSettingsPage-2sLN6YTn.js → GitSettingsPage-CRWcjgVI.js} +1 -1
- package/static/assets/{IdentityPage-Ce9aNd67.js → IdentityPage-YCkmdyzR.js} +1 -1
- package/static/assets/{ImplementationStepsEditor-BCw5WEo-.js → ImplementationStepsEditor-u3dPxmKW.js} +1 -1
- package/static/assets/{IntegrationsSettingsPage-CNhL2RAP.js → IntegrationsSettingsPage-Z8xCUmX9.js} +1 -1
- package/static/assets/{JobDetailPage-B1QoqEIg.js → JobDetailPage-B8Za82RA.js} +1 -1
- package/static/assets/{KnowledgeDetailPage-D6E4oPnB.js → KnowledgeDetailPage-CR9c4_WD.js} +1 -1
- package/static/assets/{KnowledgeEditPage-Cx0I6UOP.js → KnowledgeEditPage-DhrF6UPg.js} +1 -1
- package/static/assets/{KnowledgePage-CtwNzWrO.js → KnowledgePage-_gZhpTe3.js} +1 -1
- package/static/assets/{LoginPage-wCy6_Zm7.js → LoginPage-Cc1Ac2j4.js} +1 -1
- package/static/assets/{MailInboxPage-PlwJvbyZ.js → MailInboxPage-B_h1Kz4D.js} +1 -1
- package/static/assets/{MailProcessingModal-D7Ql9vO7.js → MailProcessingModal-D_qEwqmL.js} +1 -1
- package/static/assets/{MailReadPage-BIs7cMX8.js → MailReadPage-_q-xk_cX.js} +1 -1
- package/static/assets/{MailSentPage-Bb0xtmoP.js → MailSentPage-Dj63oQ5D.js} +1 -1
- package/static/assets/{McpSettingsPage-CgxAuTpL.js → McpSettingsPage-DYZ0QNbp.js} +1 -1
- package/static/assets/{NewKnowledgePage-ByxAeT6H.js → NewKnowledgePage-BEVMYnKG.js} +1 -1
- package/static/assets/{NewSkillPage-OYWMDDx4.js → NewSkillPage-BEn18f2A.js} +1 -1
- package/static/assets/{NewTaskPage-BtQDlqV4.js → NewTaskPage-CSlncpI5.js} +1 -1
- package/static/assets/{NotFoundPage-C6Y7qVDZ.js → NotFoundPage-C4x0lGai.js} +1 -1
- package/static/assets/{NotificationsSettingsPage-D7Ov-sWC.js → NotificationsSettingsPage-C9YnfRlj.js} +1 -1
- package/static/assets/{ProjectEditPage-DathnxH1.js → ProjectEditPage-X0-4mEAS.js} +1 -1
- package/static/assets/{ProjectPage-Cqhn6x5U.js → ProjectPage-D8OX1GKt.js} +1 -1
- package/static/assets/{PromptsSettingsPage-YUM57KBW.js → PromptsSettingsPage-Chc4da1S.js} +1 -1
- package/static/assets/{ResourceDetailPage-DHjIUpZA.js → ResourceDetailPage-DDYKQxpM.js} +1 -1
- package/static/assets/{ResourcesPage-D6JnktN5.js → ResourcesPage-BmOpgt3L.js} +1 -1
- package/static/assets/{RoleEditPage-BkcUVWeb.js → RoleEditPage-Ccfu1tn1.js} +1 -1
- package/static/assets/{RolePage-BvbK5LV5.js → RolePage-CcdEUjSm.js} +1 -1
- package/static/assets/{RulesSettingsPage-0FLxp6EA.js → RulesSettingsPage-Cz1g_eAj.js} +1 -1
- package/static/assets/{SchedulePage-DedzsT29.js → SchedulePage-CGxZHEL-.js} +1 -1
- package/static/assets/{SkillDetailPage-tQFvdVX0.js → SkillDetailPage-sJg-L8A8.js} +1 -1
- package/static/assets/{SkillEditPage-DqNB953S.js → SkillEditPage-BksV7GmD.js} +1 -1
- package/static/assets/{SkillsPage-BjQJQ5dJ.js → SkillsPage-CwarkJmZ.js} +1 -1
- package/static/assets/{SkillsSettingsPage-CVXd-umU.js → SkillsSettingsPage-DTnBlBdE.js} +1 -1
- package/static/assets/{SourceInput-8t5lHb_p.js → SourceInput-CWazIr6v.js} +1 -1
- package/static/assets/{TagInput-BSvCOVlX.js → TagInput-Bgyxb_JU.js} +1 -1
- package/static/assets/{TaskDetailPage-mr6xlhU3.js → TaskDetailPage-DlmG1kZR.js} +1 -1
- package/static/assets/{TaskEditPage-BPFpzGZd.js → TaskEditPage-BnpNeed_.js} +1 -1
- package/static/assets/{TasksPage-DHhsW-6_.js → TasksPage-CXeTMpgy.js} +1 -1
- package/static/assets/{TerminalPage-BoULMlvX.js → TerminalPage-BLcPt381.js} +1 -1
- package/static/assets/{TerminalSessionPage-BUFKA_ff.js → TerminalSessionPage-CeAd8IAy.js} +1 -1
- package/static/assets/{UserPreferencesPage-CG8d6Etn.js → UserPreferencesPage-BNwEqlRW.js} +1 -1
- package/static/assets/{UserSettingsPage-xPNj059t.js → UserSettingsPage-BRafqkiD.js} +1 -1
- package/static/assets/{UtilitiesPage-1-65_2Xp.js → UtilitiesPage-BPX_Unxu.js} +1 -1
- package/static/assets/{alert-EL2xlTrX.js → alert-Ci2-OWZ_.js} +1 -1
- package/static/assets/{arrow-down-C4aI3BzN.js → arrow-down-C6Flf0DF.js} +1 -1
- package/static/assets/{arrow-left-D1gRXqBK.js → arrow-left-7TCkaJlN.js} +1 -1
- package/static/assets/{arrow-up-DAYHG9Lx.js → arrow-up-DeQAxOPq.js} +1 -1
- package/static/assets/{arrow-up-down-CHPybwd-.js → arrow-up-down-tqbfiBy6.js} +1 -1
- package/static/assets/{badge-WU4FRCeV.js → badge-D4vHU_w_.js} +1 -1
- package/static/assets/{browser-modal-B41s3tKa.js → browser-modal-BiaqhKHm.js} +1 -1
- package/static/assets/{card-BHJKBprp.js → card-xkODbJy-.js} +1 -1
- package/static/assets/{chevron-left-BJKLaytG.js → chevron-left-CvpfJBPQ.js} +1 -1
- package/static/assets/{chevron-up-BkAwyb-e.js → chevron-up-BB-6OS4z.js} +1 -1
- package/static/assets/{chevrons-up-DLVKnDAn.js → chevrons-up-CLKrQHMU.js} +1 -1
- package/static/assets/{circle-alert-Z70KQUGE.js → circle-alert-lnP0-w3N.js} +1 -1
- package/static/assets/{circle-check-BADr-KOf.js → circle-check-BPkEav83.js} +1 -1
- package/static/assets/{circle-check-big-D34PB5x-.js → circle-check-big-Dbo-OmWQ.js} +1 -1
- package/static/assets/{circle-play-BfLMQvSH.js → circle-play-BbtBIeo3.js} +1 -1
- package/static/assets/{circle-x-Bn4fyYbB.js → circle-x-BBwi8e5G.js} +1 -1
- package/static/assets/{clipboard-DFI4a7LI.js → clipboard-Ce816tAO.js} +1 -1
- package/static/assets/{clock-BwcvObAc.js → clock-BIeoO5Mt.js} +1 -1
- package/static/assets/{code-DXA16K3p.js → code-DTW3giBe.js} +1 -1
- package/static/assets/{download-Cb08Pn1l.js → download-BgKxfry9.js} +1 -1
- package/static/assets/{external-link-BbPHlMU6.js → external-link--RjKXREe.js} +1 -1
- package/static/assets/{eye-DKuTxsEz.js → eye--K-OgK7L.js} +1 -1
- package/static/assets/{folder-git-2-CLjnVj8p.js → folder-git-2-Bgv7r0zC.js} +1 -1
- package/static/assets/{index-MT7xy-5k.js → index-4RuWYO4M.js} +1 -1
- package/static/assets/{index-97wNbZjB.js → index-BD9UBXsr.js} +1 -1
- package/static/assets/{index-DauoTeMC.js → index-BQYB8kWb.js} +1 -1
- package/static/assets/{index-DDaqus6Y.js → index-BbrX1XcC.js} +1 -1
- package/static/assets/{index-KMYFtqs_.js → index-BkEdELOI.js} +1 -1
- package/static/assets/{index-Cp2t41gG.js → index-BteQHbZ1.js} +1 -1
- package/static/assets/{index-CHImvyA8.js → index-CW9pK_cZ.js} +1 -1
- package/static/assets/{index-DNQq4O0F.js → index-Cd5hBt4x.js} +1 -1
- package/static/assets/{index-9hNdrzuJ.js → index-Ch4GVR8L.js} +1 -1
- package/static/assets/{index-BBUGa7c5.js → index-D9xZafJb.js} +1 -1
- package/static/assets/{index-DO6rNgzu.js → index-DF_KNbKf.js} +1 -1
- package/static/assets/{index-DysiQsZ5.js → index-Db5-BoCU.js} +1 -1
- package/static/assets/{index-B-VC5GM7.js → index-Di7xMYoG.js} +1 -1
- package/static/assets/{index-DE9Jes-V.js → index-Do92mBFr.js} +1 -1
- package/static/assets/{index-DxQLy6Gv.js → index-Dt_WtbUU.js} +1 -1
- package/static/assets/{index-BShpFXJb.js → index-LMsLdXw_.js} +1 -1
- package/static/assets/{index-C5Azpb6Z.js → index-PyVlsLW8.js} +3 -3
- package/static/assets/{index-Bd8VZDeR.js → index-R44k73Ca.js} +1 -1
- package/static/assets/{index-BjpC9OGL.js → index-iIFwHD3L.js} +1 -1
- package/static/assets/{info-CwUnqjYK.js → info-DgZN3xWF.js} +1 -1
- package/static/assets/{label-Dk87UyXm.js → label-DvPENm3h.js} +1 -1
- package/static/assets/{markdown-editor-D0KOANlZ.js → markdown-editor-DpZxV-fa.js} +3 -3
- package/static/assets/{message-square-qlP-j05_.js → message-square-CoaQYehb.js} +1 -1
- package/static/assets/{paperclip-C7-B8_IK.js → paperclip-ChugoOAp.js} +1 -1
- package/static/assets/{pause-DE1VFlNp.js → pause-m9YcgxdE.js} +1 -1
- package/static/assets/{play-D8sJDiBu.js → play-DtFz_MLh.js} +1 -1
- package/static/assets/{radio-group-C8YR94gC.js → radio-group-C5Te9bVb.js} +1 -1
- package/static/assets/{refresh-cw-CIEDgKUC.js → refresh-cw-B1bWW9Rg.js} +1 -1
- package/static/assets/{search-BGxb6jwl.js → search-CPOHeeUa.js} +1 -1
- package/static/assets/{select-CpKkFDbr.js → select-B1v2u6hQ.js} +1 -1
- package/static/assets/{switch-BZ6eSoPj.js → switch-Bf1Cq3P6.js} +1 -1
- package/static/assets/{tabs-HysYyLO3.js → tabs-DAbCZiFC.js} +1 -1
- package/static/assets/{tag-D2TG8w6l.js → tag-Cz4z82t0.js} +1 -1
- package/static/assets/{terminal-preview-Cgpwpsv9.js → terminal-preview-DTUohQ5b.js} +1 -1
- package/static/assets/{use-terminal-Bf1hClFd.js → use-terminal-CFbQv1ie.js} +1 -1
- package/static/assets/{video-D0tTpDVb.js → video-B6ZJ-Epb.js} +1 -1
- package/static/index.html +1 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Client helper for connecting to HTTP/SSE MCP servers
|
|
3
|
+
* Provides tool discovery and execution proxying
|
|
4
|
+
*/
|
|
5
|
+
export interface McpServerConfig {
|
|
6
|
+
name?: string;
|
|
7
|
+
type?: 'http' | 'sse' | 'stdio';
|
|
8
|
+
url?: string;
|
|
9
|
+
enabled?: boolean;
|
|
10
|
+
env?: Record<string, string>;
|
|
11
|
+
}
|
|
12
|
+
export interface DiscoveredTool {
|
|
13
|
+
name: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
inputSchema?: object;
|
|
16
|
+
serverName: string;
|
|
17
|
+
serverUrl: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ToolCallResult {
|
|
20
|
+
content: Array<{
|
|
21
|
+
type: string;
|
|
22
|
+
text?: string;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}>;
|
|
25
|
+
isError?: boolean;
|
|
26
|
+
structuredContent?: unknown;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Connect to an HTTP/SSE MCP server and discover its available tools
|
|
30
|
+
*/
|
|
31
|
+
export declare function discoverToolsFromServer(serverName: string, config: McpServerConfig): Promise<DiscoveredTool[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Execute a tool on an HTTP/SSE MCP server
|
|
34
|
+
*/
|
|
35
|
+
export declare function executeToolOnServer(serverName: string, config: McpServerConfig, toolName: string, args: Record<string, unknown>): Promise<ToolCallResult>;
|
|
36
|
+
/**
|
|
37
|
+
* Close all cached client connections (for cleanup)
|
|
38
|
+
*/
|
|
39
|
+
export declare function closeAllConnections(): void;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Client helper for connecting to HTTP/SSE MCP servers
|
|
3
|
+
* Provides tool discovery and execution proxying
|
|
4
|
+
*/
|
|
5
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
6
|
+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
7
|
+
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
8
|
+
// Cache for active client connections
|
|
9
|
+
const clientCache = new Map();
|
|
10
|
+
// Clean up stale connections after 5 minutes
|
|
11
|
+
const CONNECTION_TTL_MS = 5 * 60 * 1000;
|
|
12
|
+
/**
|
|
13
|
+
* Get or create a client connection to an MCP server
|
|
14
|
+
*/
|
|
15
|
+
async function getOrCreateClient(serverName, config) {
|
|
16
|
+
const cacheKey = `${serverName}:${config.url}`;
|
|
17
|
+
const cached = clientCache.get(cacheKey);
|
|
18
|
+
if (cached) {
|
|
19
|
+
cached.lastUsed = Date.now();
|
|
20
|
+
return cached.client;
|
|
21
|
+
}
|
|
22
|
+
const client = new Client({
|
|
23
|
+
name: 'coconut-api',
|
|
24
|
+
version: '1.0.0'
|
|
25
|
+
});
|
|
26
|
+
const url = new URL(config.url);
|
|
27
|
+
// Try StreamableHTTP first (newer), fall back to SSE (legacy)
|
|
28
|
+
let transport;
|
|
29
|
+
if (config.type === 'sse') {
|
|
30
|
+
// Explicitly SSE
|
|
31
|
+
transport = new SSEClientTransport(url);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// Default to StreamableHTTP for 'http' type or unspecified
|
|
35
|
+
transport = new StreamableHTTPClientTransport(url);
|
|
36
|
+
}
|
|
37
|
+
await client.connect(transport);
|
|
38
|
+
clientCache.set(cacheKey, { client, lastUsed: Date.now() });
|
|
39
|
+
// Schedule cleanup
|
|
40
|
+
scheduleCleanup();
|
|
41
|
+
return client;
|
|
42
|
+
}
|
|
43
|
+
let cleanupScheduled = false;
|
|
44
|
+
function scheduleCleanup() {
|
|
45
|
+
if (cleanupScheduled)
|
|
46
|
+
return;
|
|
47
|
+
cleanupScheduled = true;
|
|
48
|
+
setTimeout(() => {
|
|
49
|
+
cleanupScheduled = false;
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
for (const [key, entry] of clientCache.entries()) {
|
|
52
|
+
if (now - entry.lastUsed > CONNECTION_TTL_MS) {
|
|
53
|
+
try {
|
|
54
|
+
entry.client.close();
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
// Ignore close errors
|
|
58
|
+
}
|
|
59
|
+
clientCache.delete(key);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Reschedule if there are still cached connections
|
|
63
|
+
if (clientCache.size > 0) {
|
|
64
|
+
scheduleCleanup();
|
|
65
|
+
}
|
|
66
|
+
}, CONNECTION_TTL_MS);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Connect to an HTTP/SSE MCP server and discover its available tools
|
|
70
|
+
*/
|
|
71
|
+
export async function discoverToolsFromServer(serverName, config) {
|
|
72
|
+
if (!config.url) {
|
|
73
|
+
throw new Error(`Server ${serverName} has no URL configured`);
|
|
74
|
+
}
|
|
75
|
+
if (config.enabled === false) {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
const client = await getOrCreateClient(serverName, config);
|
|
80
|
+
const toolsResult = await client.listTools();
|
|
81
|
+
return toolsResult.tools.map(tool => ({
|
|
82
|
+
name: tool.name,
|
|
83
|
+
description: tool.description,
|
|
84
|
+
inputSchema: tool.inputSchema,
|
|
85
|
+
serverName,
|
|
86
|
+
serverUrl: config.url
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
console.error(`Failed to discover tools from ${serverName}:`, error);
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Execute a tool on an HTTP/SSE MCP server
|
|
96
|
+
*/
|
|
97
|
+
export async function executeToolOnServer(serverName, config, toolName, args) {
|
|
98
|
+
if (!config.url) {
|
|
99
|
+
throw new Error(`Server ${serverName} has no URL configured`);
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
const client = await getOrCreateClient(serverName, config);
|
|
103
|
+
const result = await client.callTool({
|
|
104
|
+
name: toolName,
|
|
105
|
+
arguments: args
|
|
106
|
+
});
|
|
107
|
+
return {
|
|
108
|
+
content: result.content,
|
|
109
|
+
isError: result.isError,
|
|
110
|
+
structuredContent: result.structuredContent
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
console.error(`Failed to execute tool ${toolName} on ${serverName}:`, error);
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Close all cached client connections (for cleanup)
|
|
120
|
+
*/
|
|
121
|
+
export function closeAllConnections() {
|
|
122
|
+
for (const [key, entry] of clientCache.entries()) {
|
|
123
|
+
try {
|
|
124
|
+
entry.client.close();
|
|
125
|
+
}
|
|
126
|
+
catch (e) {
|
|
127
|
+
// Ignore close errors
|
|
128
|
+
}
|
|
129
|
+
clientCache.delete(key);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -2,10 +2,37 @@ import * as pty from 'node-pty';
|
|
|
2
2
|
import { WebSocket } from 'ws';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import fs from 'fs';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
5
6
|
import { createInitScript } from './context-helper.js';
|
|
6
7
|
import { getShellPath, getShellArgs, prepareShellInit } from './shell-utils.js';
|
|
7
8
|
import { getLogger, AgentKinds } from '@lovelybunch/core/logging';
|
|
8
9
|
import { getInjectedEnv } from '../env-injection.js';
|
|
10
|
+
/**
|
|
11
|
+
* Workaround for node-pty#850: macOS prebuilds (v1.1.0+) ship spawn-helper
|
|
12
|
+
* without the execute bit, causing posix_spawnp to fail.
|
|
13
|
+
* https://github.com/microsoft/node-pty/issues/850
|
|
14
|
+
*/
|
|
15
|
+
function ensureSpawnHelperPermissions() {
|
|
16
|
+
if (process.platform !== 'darwin')
|
|
17
|
+
return;
|
|
18
|
+
try {
|
|
19
|
+
const nodePtyEntry = import.meta.resolve('node-pty');
|
|
20
|
+
const nodePtyDir = path.resolve(fileURLToPath(nodePtyEntry), '..', '..');
|
|
21
|
+
for (const arch of ['darwin-arm64', 'darwin-x64']) {
|
|
22
|
+
const helperPath = path.join(nodePtyDir, 'prebuilds', arch, 'spawn-helper');
|
|
23
|
+
if (fs.existsSync(helperPath)) {
|
|
24
|
+
const stats = fs.statSync(helperPath);
|
|
25
|
+
if (!(stats.mode & 0o111)) {
|
|
26
|
+
fs.chmodSync(helperPath, 0o755);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Best-effort; node-pty 1.0.0 has no prebuilds dir and this is a no-op
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
let spawnHelperFixed = false;
|
|
9
36
|
export class TerminalManager {
|
|
10
37
|
sessions = new Map();
|
|
11
38
|
cleanupInterval;
|
|
@@ -17,6 +44,10 @@ export class TerminalManager {
|
|
|
17
44
|
}, 5 * 60 * 1000);
|
|
18
45
|
}
|
|
19
46
|
async createSession(taskId, shellPreference = 'bash', startupCommand) {
|
|
47
|
+
if (!spawnHelperFixed) {
|
|
48
|
+
ensureSpawnHelperPermissions();
|
|
49
|
+
spawnHelperFixed = true;
|
|
50
|
+
}
|
|
20
51
|
const sessionId = `${taskId}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
21
52
|
// Get the project root directory
|
|
22
53
|
let projectRoot;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Context } from 'hono';
|
|
2
|
+
/**
|
|
3
|
+
* POST /api/v1/ai/tools
|
|
4
|
+
* Execute tool calls that were detected during streaming
|
|
5
|
+
*/
|
|
6
|
+
export declare function POST(c: Context): Promise<(Response & import("hono").TypedResponse<{
|
|
7
|
+
error: string;
|
|
8
|
+
}, 400, "json">) | (Response & import("hono").TypedResponse<{
|
|
9
|
+
error: string;
|
|
10
|
+
}, 500, "json">) | (Response & import("hono").TypedResponse<{
|
|
11
|
+
response: string;
|
|
12
|
+
toolCalls: any[];
|
|
13
|
+
toolResults: {
|
|
14
|
+
tool_call_id: string;
|
|
15
|
+
content: string;
|
|
16
|
+
}[];
|
|
17
|
+
}, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
|