@akira-tl/forgerelay 0.2.0 → 0.2.2
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/CHANGELOG.md +24 -0
- package/dist/apply-patch.js +21 -6
- package/dist/artifact-tools.js +9 -4
- package/dist/config.js +8 -6
- package/dist/file-mutations.js +50 -0
- package/dist/hooks.js +4 -1
- package/dist/logger.js +157 -15
- package/dist/mcp/server-instructions.js +13 -9
- package/dist/pi-tools.js +14 -13
- package/dist/roots.js +30 -1
- package/dist/server.js +210 -54
- package/dist/ui/.vite/manifest.json +280 -280
- package/dist/ui/assets/{angular-html-CovppXt5.js → angular-html-CQmCUfkv.js} +1 -1
- package/dist/ui/assets/{angular-ts-0Y9l6YXu.js → angular-ts-BSbfxpMS.js} +1 -1
- package/dist/ui/assets/{apl-BmBhiklA.js → apl-CWCaH-E3.js} +1 -1
- package/dist/ui/assets/{astro-BAmqcqyV.js → astro-R_p4G0xA.js} +1 -1
- package/dist/ui/assets/{blade-BjFcmRJo.js → blade-irHensDY.js} +1 -1
- package/dist/ui/assets/{c-CaOJn4x0.js → c-_XEQUoq6.js} +1 -1
- package/dist/ui/assets/{cobol-DR4zWFMt.js → cobol-Css6VQjJ.js} +1 -1
- package/dist/ui/assets/{coffee-ReGSThmM.js → coffee-CpXUkyDm.js} +1 -1
- package/dist/ui/assets/{cpp-CnlQh6MO.js → cpp-BQHsPWwI.js} +1 -1
- package/dist/ui/assets/{crystal-BrpPbH1U.js → crystal-Cbv8J9Fm.js} +1 -1
- package/dist/ui/assets/{css-DRBEvyPU.js → css-D8DkrS3U.js} +1 -1
- package/dist/ui/assets/{edge-cfwpdvl9.js → edge-bBL_XDAG.js} +1 -1
- package/dist/ui/assets/{elixir-7owrJxb6.js → elixir-CQjsM9sA.js} +1 -1
- package/dist/ui/assets/{elm-udiOjODk.js → elm-DLFl-jEZ.js} +1 -1
- package/dist/ui/assets/{erb-8ctXHMkS.js → erb-BJjsdB_Q.js} +1 -1
- package/dist/ui/assets/{git-rebase-P0V_qK1w.js → git-rebase-CqP5A2s0.js} +1 -1
- package/dist/ui/assets/{glimmer-js-CZ14ED7U.js → glimmer-js-B5Hh_7xe.js} +1 -1
- package/dist/ui/assets/{glimmer-ts-DtBSFP-o.js → glimmer-ts-oaeSAC8s.js} +1 -1
- package/dist/ui/assets/{glsl-BX2BkZJK.js → glsl-BylkOpcF.js} +1 -1
- package/dist/ui/assets/{graphql-Dj_cPv4w.js → graphql-DsVRvP6S.js} +1 -1
- package/dist/ui/assets/{hack-DGRkd8xn.js → hack-D4N5abT_.js} +1 -1
- package/dist/ui/assets/{haml-BAPSvujW.js → haml-CIAJQIox.js} +1 -1
- package/dist/ui/assets/{handlebars-PYksdULG.js → handlebars-DDEZyNXR.js} +1 -1
- package/dist/ui/assets/{heavy-payload-BjE0LSUi.js → heavy-payload-DafM8yjB.js} +1 -1
- package/dist/ui/assets/{html-derivative-C6q86ZrS.js → html-derivative-CZ91Y2d5.js} +1 -1
- package/dist/ui/assets/{html-DloAPGZ1.js → html-zDy-3lvy.js} +1 -1
- package/dist/ui/assets/{http-fPvYDvHA.js → http-ezaodZRf.js} +1 -1
- package/dist/ui/assets/{hurl-Dbir4WvE.js → hurl-BmL0o7TO.js} +1 -1
- package/dist/ui/assets/{java-DvkqXg3z.js → java-Q2C0vwbH.js} +1 -1
- package/dist/ui/assets/{javascript-TONTV6Ty.js → javascript-UDhBkHE3.js} +1 -1
- package/dist/ui/assets/{jinja-OM1F5Gct.js → jinja-BWRskcYS.js} +1 -1
- package/dist/ui/assets/{jison-CBttugts.js → jison-B18BY9Ds.js} +1 -1
- package/dist/ui/assets/{json-Db5oY-7J.js → json-DNj7MpRr.js} +1 -1
- package/dist/ui/assets/{jsx-DKeJCgsc.js → jsx-CVpHJ6cr.js} +1 -1
- package/dist/ui/assets/{julia-NlIPhXaL.js → julia-CJBNBS9c.js} +1 -1
- package/dist/ui/assets/{just-BXBJB-mX.js → just-Bmu2JCQT.js} +1 -1
- package/dist/ui/assets/{latex-CGK-6yDy.js → latex-BB7F93KY.js} +1 -1
- package/dist/ui/assets/{liquid-D7waQ0MY.js → liquid-Btnomc6E.js} +1 -1
- package/dist/ui/assets/{lua-C_kkt4h1.js → lua-D0FYT9Vo.js} +1 -1
- package/dist/ui/assets/{marko-BokXuCts.js → marko-MHLw0ZlK.js} +1 -1
- package/dist/ui/assets/{mdc-Bk0nnUJA.js → mdc-CSr-suGy.js} +1 -1
- package/dist/ui/assets/{nginx-jM6NF9TV.js → nginx-ur1l6E-g.js} +1 -1
- package/dist/ui/assets/{nim-hYsL-WKb.js → nim-B2k0IugA.js} +1 -1
- package/dist/ui/assets/{perl-DBI_cUHJ.js → perl-BqOHxFDn.js} +1 -1
- package/dist/ui/assets/{php-BX_aQhFl.js → php-DzPK6O1_.js} +1 -1
- package/dist/ui/assets/{pug-DwFAYy1e.js → pug-D169OZkr.js} +1 -1
- package/dist/ui/assets/{qml-eLSwQUKt.js → qml-BtemJTC4.js} +1 -1
- package/dist/ui/assets/{r-BMnQsMLf.js → r-BGVHu0bd.js} +1 -1
- package/dist/ui/assets/{razor-CgciiMyw.js → razor-Diisjg1d.js} +1 -1
- package/dist/ui/assets/{regexp-ZrURNrn5.js → regexp-B2F5vMZ6.js} +1 -1
- package/dist/ui/assets/{review-payload-HGkpJjjm.js → review-payload-B-3I3Oj_.js} +1 -1
- package/dist/ui/assets/{rst-EoAOr3M6.js → rst-BxpeZwuT.js} +1 -1
- package/dist/ui/assets/{ruby-Dqx5_Rqw.js → ruby-DrCq4riN.js} +1 -1
- package/dist/ui/assets/{sas-Bf6xPLSX.js → sas-CI_2W-1n.js} +1 -1
- package/dist/ui/assets/{scrollbar-DX4Ujotb.js → scrollbar-DHsDF5w-.js} +3 -3
- package/dist/ui/assets/{scss-DDpW3yTd.js → scss-BxtyHZ1p.js} +1 -1
- package/dist/ui/assets/{shellscript-DayAQ-W9.js → shellscript-BY_YYrHT.js} +1 -1
- package/dist/ui/assets/{shellsession-jPr_lSnA.js → shellsession-C6uBrLmA.js} +1 -1
- package/dist/ui/assets/{soy-X9adks8G.js → soy-BHM9gdPh.js} +1 -1
- package/dist/ui/assets/{sql-Bmt09AIR.js → sql-XmhfEGz_.js} +1 -1
- package/dist/ui/assets/{stata-DVkNpH8r.js → stata-BbHY7NEo.js} +1 -1
- package/dist/ui/assets/{surrealql-eEXzMb8j.js → surrealql-CD49DZ3E.js} +1 -1
- package/dist/ui/assets/{svelte-CFoBxZF3.js → svelte-CbYsEYJY.js} +1 -1
- package/dist/ui/assets/{templ-Da_324JF.js → templ-B5JoUxEB.js} +1 -1
- package/dist/ui/assets/{tex-HAzlmKJ0.js → tex-DZcOfTZK.js} +1 -1
- package/dist/ui/assets/{ts-tags-7iLrNH8p.js → ts-tags-BeU-xqc0.js} +1 -1
- package/dist/ui/assets/{tsx-gZaXf8PJ.js → tsx-V7W1xGl3.js} +1 -1
- package/dist/ui/assets/{twig-CLpQ7p1N.js → twig-MIaJo5BU.js} +1 -1
- package/dist/ui/assets/{typescript-B2WWCRI2.js → typescript-C0WESuVc.js} +1 -1
- package/dist/ui/assets/{vue-No_8Jygd.js → vue-eJHwc9ra.js} +1 -1
- package/dist/ui/assets/{vue-html-kHJg98Kk.js → vue-html-CLmBujTU.js} +1 -1
- package/dist/ui/assets/{vue-vine-Df4cEYaN.js → vue-vine-BP5kjIGb.js} +1 -1
- package/dist/ui/assets/{workspace-app-C_wsC6VL.js → workspace-app-C1qR5cAY.js} +3 -3
- package/dist/ui/assets/{xml-DUZ05dpG.js → xml-j7pmyP48.js} +1 -1
- package/dist/ui/assets/{xsl-Bwp3w2OF.js → xsl-5VFHbg6o.js} +1 -1
- package/dist/ui/assets/{yaml-IA_-TEM1.js → yaml-DxFAt-KU.js} +1 -1
- package/dist/ui/workspace-app.html +1 -1
- package/dist/workspaces.js +19 -6
- package/docs/chatgpt-coding-workflow.md +4 -1
- package/docs/configuration.md +16 -8
- package/docs/debugging.md +6 -5
- package/docs/security.md +18 -7
- package/package.json +2 -2
- package/scripts/debug/accept.mjs +65 -1
package/dist/server.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { access, realpath } from "node:fs/promises";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
5
6
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
7
|
import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
|
|
@@ -13,12 +14,13 @@ import { registerAppResource, registerAppTool, RESOURCE_MIME_TYPE, } from "@mode
|
|
|
13
14
|
import express from "express";
|
|
14
15
|
import * as z from "zod/v4";
|
|
15
16
|
import { applyPatch } from "./apply-patch.js";
|
|
17
|
+
import { deletePath, renamePath } from "./file-mutations.js";
|
|
16
18
|
import { isArtifactDownloadSupportedPlatform, registerArtifactTools, } from "./artifact-tools.js";
|
|
17
19
|
import { loadConfig } from "./config.js";
|
|
18
20
|
import { attachHookReports, HookRunner, runToolWithHooks } from "./hooks.js";
|
|
19
21
|
import { buildServerInstructions, buildToolDescriptions, toolNames, } from "./mcp/server-instructions.js";
|
|
20
22
|
import { createOpenAIIncomingArtifactAdapter, } from "./incoming-artifacts.js";
|
|
21
|
-
import { logEvent, requestIp, requestPath, commandPreview, sessionIdPrefix, } from "./logger.js";
|
|
23
|
+
import { logEvent, requestIp, requestPath, commandPreview, sessionIdPrefix, workspaceLogLabel, } from "./logger.js";
|
|
22
24
|
import { editFileTool, findFilesTool, grepFilesTool, listDirectoryTool, readFileTool, runShellTool, writeFileTool, } from "./pi-tools.js";
|
|
23
25
|
import { SingleUserOAuthProvider } from "./oauth-provider.js";
|
|
24
26
|
import { McpSessionRegistry, } from "./mcp-sessions.js";
|
|
@@ -78,6 +80,13 @@ function toolWidgetDescriptorMeta(config, kind) {
|
|
|
78
80
|
},
|
|
79
81
|
};
|
|
80
82
|
}
|
|
83
|
+
function workspaceLogContext(workspace, sessionId) {
|
|
84
|
+
return {
|
|
85
|
+
workspaceId: workspace.id,
|
|
86
|
+
workspace: workspaceLogLabel(workspace.root, workspace.id),
|
|
87
|
+
session: sessionIdPrefix(sessionId),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
81
90
|
function formatVisibleAgent(agent) {
|
|
82
91
|
const model = agent.model ? `, model ${agent.model}` : "";
|
|
83
92
|
const thinking = agent.thinking ? `, thinking ${agent.thinking}` : "";
|
|
@@ -393,7 +402,7 @@ function registerCodexProcessTools(server, config, workspaces, processSessions,
|
|
|
393
402
|
outputSchema: processOutputSchema(),
|
|
394
403
|
...toolWidgetDescriptorMeta(config, "shell"),
|
|
395
404
|
annotations: SHELL_TOOL_ANNOTATIONS,
|
|
396
|
-
}, async ({ workspaceId, cmd, tty, columns, rows, workingDirectory, yieldTimeMs, maxOutputTokens }) => {
|
|
405
|
+
}, async ({ workspaceId, cmd, tty, columns, rows, workingDirectory, yieldTimeMs, maxOutputTokens }, extra) => {
|
|
397
406
|
const workspace = workspaces.getWorkspace(workspaceId);
|
|
398
407
|
return runToolWithHooks(hooks, {
|
|
399
408
|
tool: "exec_command",
|
|
@@ -415,11 +424,14 @@ function registerCodexProcessTools(server, config, workspaces, processSessions,
|
|
|
415
424
|
});
|
|
416
425
|
logToolCall(config, {
|
|
417
426
|
tool: "exec_command",
|
|
418
|
-
|
|
427
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
419
428
|
workingDirectory: workingDirectory ?? ".",
|
|
420
429
|
command: cmd,
|
|
421
430
|
commandLength: cmd.length,
|
|
422
|
-
|
|
431
|
+
exitCode: snapshot.exitCode,
|
|
432
|
+
running: snapshot.running,
|
|
433
|
+
processSessionId: snapshot.sessionId,
|
|
434
|
+
success: snapshot.running || snapshot.exitCode === 0,
|
|
423
435
|
durationMs: Math.round(performance.now() - startedAt),
|
|
424
436
|
});
|
|
425
437
|
return processToolResponse("exec_command", workspaceId, snapshot, {
|
|
@@ -459,7 +471,7 @@ function registerCodexProcessTools(server, config, workspaces, processSessions,
|
|
|
459
471
|
outputSchema: processOutputSchema(),
|
|
460
472
|
...toolWidgetDescriptorMeta(config, "shell"),
|
|
461
473
|
annotations: SHELL_TOOL_ANNOTATIONS,
|
|
462
|
-
}, async ({ workspaceId, sessionId, chars, columns, rows, yieldTimeMs, maxOutputTokens }) => {
|
|
474
|
+
}, async ({ workspaceId, sessionId, chars, columns, rows, yieldTimeMs, maxOutputTokens }, extra) => {
|
|
463
475
|
const workspace = workspaces.getWorkspace(workspaceId);
|
|
464
476
|
return runToolWithHooks(hooks, {
|
|
465
477
|
tool: "write_stdin",
|
|
@@ -483,8 +495,11 @@ function registerCodexProcessTools(server, config, workspaces, processSessions,
|
|
|
483
495
|
});
|
|
484
496
|
logToolCall(config, {
|
|
485
497
|
tool: "write_stdin",
|
|
486
|
-
|
|
487
|
-
|
|
498
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
499
|
+
exitCode: snapshot.exitCode,
|
|
500
|
+
running: snapshot.running,
|
|
501
|
+
processSessionId: snapshot.sessionId,
|
|
502
|
+
success: snapshot.running || snapshot.exitCode === 0,
|
|
488
503
|
durationMs: Math.round(performance.now() - startedAt),
|
|
489
504
|
});
|
|
490
505
|
return processToolResponse("write_stdin", workspaceId, snapshot, {
|
|
@@ -597,7 +612,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
597
612
|
idempotentHint: false,
|
|
598
613
|
openWorldHint: false,
|
|
599
614
|
},
|
|
600
|
-
}, async ({ path, mode, baseRef, newWorktree }, { _meta }) => {
|
|
615
|
+
}, async ({ path, mode, baseRef, newWorktree }, { _meta, sessionId }) => {
|
|
601
616
|
const startedAt = performance.now();
|
|
602
617
|
const { workspace, agentsFiles, availableAgentsFiles, hookReports, workspaceReused, includeBootstrapContext, } = await workspaces.openWorkspace({ path, mode, baseRef, newWorktree }, { conversationScopeId: openAiConversationScopeId(_meta) });
|
|
603
618
|
const knownWorktrees = await workspaces.listKnownWorktrees(workspace);
|
|
@@ -692,7 +707,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
692
707
|
];
|
|
693
708
|
logToolCall(config, {
|
|
694
709
|
tool: "open_workspace",
|
|
695
|
-
|
|
710
|
+
...workspaceLogContext(workspace, sessionId),
|
|
696
711
|
path: workspace.root,
|
|
697
712
|
success: true,
|
|
698
713
|
durationMs: Math.round(performance.now() - startedAt),
|
|
@@ -772,7 +787,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
772
787
|
}),
|
|
773
788
|
_meta: {},
|
|
774
789
|
annotations: WRITE_TOOL_ANNOTATIONS,
|
|
775
|
-
}, async ({ workspaceId, commitMessage }) => {
|
|
790
|
+
}, async ({ workspaceId, commitMessage }, extra) => {
|
|
776
791
|
const workspace = workspaces.getWorkspace(workspaceId);
|
|
777
792
|
return runToolWithHooks(hooks, {
|
|
778
793
|
tool: toolNames.closeWorktree,
|
|
@@ -793,7 +808,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
793
808
|
].join("\n");
|
|
794
809
|
logToolCall(config, {
|
|
795
810
|
tool: toolNames.closeWorktree,
|
|
796
|
-
|
|
811
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
797
812
|
path: closed.sourceRoot,
|
|
798
813
|
success: true,
|
|
799
814
|
durationMs: Math.round(performance.now() - startedAt),
|
|
@@ -825,8 +840,8 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
825
840
|
path: z
|
|
826
841
|
.string()
|
|
827
842
|
.describe(config.skillsEnabled
|
|
828
|
-
? "File path to read, relative to the workspace root. May also be an advertised skill path from open_workspace skills."
|
|
829
|
-
: "File path to read, relative to the workspace root."),
|
|
843
|
+
? "File path to read, relative to the workspace root or absolute inside the OS temp directory. May also be an advertised skill path from open_workspace skills."
|
|
844
|
+
: "File path to read, relative to the workspace root or absolute inside the OS temp directory."),
|
|
830
845
|
offset: z
|
|
831
846
|
.number()
|
|
832
847
|
.int()
|
|
@@ -843,7 +858,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
843
858
|
outputSchema: resultOutputSchema(),
|
|
844
859
|
...toolWidgetDescriptorMeta(config, "read"),
|
|
845
860
|
annotations: { readOnlyHint: true },
|
|
846
|
-
}, async ({ workspaceId, ...input }) => {
|
|
861
|
+
}, async ({ workspaceId, ...input }, extra) => {
|
|
847
862
|
const workspace = workspaces.getWorkspace(workspaceId);
|
|
848
863
|
return runToolWithHooks(hooks, {
|
|
849
864
|
tool: toolNames.read,
|
|
@@ -861,7 +876,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
861
876
|
if (response.isError) {
|
|
862
877
|
logFailedToolResponse(config, {
|
|
863
878
|
tool: toolNames.read,
|
|
864
|
-
|
|
879
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
865
880
|
path: input.path,
|
|
866
881
|
}, response.content, startedAt);
|
|
867
882
|
return response;
|
|
@@ -874,7 +889,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
874
889
|
};
|
|
875
890
|
logToolCall(config, {
|
|
876
891
|
tool: toolNames.read,
|
|
877
|
-
|
|
892
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
878
893
|
path: input.path,
|
|
879
894
|
success: true,
|
|
880
895
|
durationMs: Math.round(performance.now() - startedAt),
|
|
@@ -907,13 +922,13 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
907
922
|
.describe("Workspace identifier returned by open_workspace."),
|
|
908
923
|
path: z
|
|
909
924
|
.string()
|
|
910
|
-
.describe("File path to write, relative to the workspace root."),
|
|
925
|
+
.describe("File path to write, relative to the workspace root or absolute inside the OS temp directory."),
|
|
911
926
|
content: z.string().describe("Complete new file content."),
|
|
912
927
|
},
|
|
913
928
|
outputSchema: resultOutputSchema(),
|
|
914
929
|
...toolWidgetDescriptorMeta(config, "write"),
|
|
915
930
|
annotations: WRITE_TOOL_ANNOTATIONS,
|
|
916
|
-
}, async ({ workspaceId, ...input }) => {
|
|
931
|
+
}, async ({ workspaceId, ...input }, extra) => {
|
|
917
932
|
const workspace = workspaces.getWorkspace(workspaceId);
|
|
918
933
|
return runToolWithHooks(hooks, {
|
|
919
934
|
tool: toolNames.write,
|
|
@@ -923,15 +938,15 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
923
938
|
changedPaths: (result) => toolResultIsError(result) ? [] : [input.path],
|
|
924
939
|
operation: async () => {
|
|
925
940
|
const startedAt = performance.now();
|
|
926
|
-
workspaces.resolvePath(workspace, input.path);
|
|
927
941
|
const response = await writeFileTool(input, {
|
|
928
942
|
cwd: workspace.root,
|
|
929
943
|
root: workspace.root,
|
|
944
|
+
fileRoots: workspaces.fileToolRoots(workspace),
|
|
930
945
|
});
|
|
931
946
|
if (response.isError) {
|
|
932
947
|
logFailedToolResponse(config, {
|
|
933
948
|
tool: toolNames.write,
|
|
934
|
-
|
|
949
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
935
950
|
path: input.path,
|
|
936
951
|
}, response.content, startedAt);
|
|
937
952
|
return response;
|
|
@@ -945,7 +960,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
945
960
|
};
|
|
946
961
|
logToolCall(config, {
|
|
947
962
|
tool: toolNames.write,
|
|
948
|
-
|
|
963
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
949
964
|
path: input.path,
|
|
950
965
|
success: true,
|
|
951
966
|
durationMs: Math.round(performance.now() - startedAt),
|
|
@@ -980,7 +995,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
980
995
|
.describe("Workspace identifier returned by open_workspace."),
|
|
981
996
|
path: z
|
|
982
997
|
.string()
|
|
983
|
-
.describe("File path to edit, relative to the workspace root."),
|
|
998
|
+
.describe("File path to edit, relative to the workspace root or absolute inside the OS temp directory."),
|
|
984
999
|
edits: z
|
|
985
1000
|
.array(z.object({
|
|
986
1001
|
oldText: z
|
|
@@ -995,7 +1010,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
995
1010
|
}),
|
|
996
1011
|
...toolWidgetDescriptorMeta(config, "edit"),
|
|
997
1012
|
annotations: EDIT_TOOL_ANNOTATIONS,
|
|
998
|
-
}, async ({ workspaceId, ...input }) => {
|
|
1013
|
+
}, async ({ workspaceId, ...input }, extra) => {
|
|
999
1014
|
const workspace = workspaces.getWorkspace(workspaceId);
|
|
1000
1015
|
return runToolWithHooks(hooks, {
|
|
1001
1016
|
tool: toolNames.edit,
|
|
@@ -1005,15 +1020,15 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1005
1020
|
changedPaths: (result) => toolResultIsError(result) ? [] : [input.path],
|
|
1006
1021
|
operation: async () => {
|
|
1007
1022
|
const startedAt = performance.now();
|
|
1008
|
-
workspaces.resolvePath(workspace, input.path);
|
|
1009
1023
|
const response = await editFileTool(input, {
|
|
1010
1024
|
cwd: workspace.root,
|
|
1011
1025
|
root: workspace.root,
|
|
1026
|
+
fileRoots: workspaces.fileToolRoots(workspace),
|
|
1012
1027
|
});
|
|
1013
1028
|
if (response.isError) {
|
|
1014
1029
|
logFailedToolResponse(config, {
|
|
1015
1030
|
tool: toolNames.edit,
|
|
1016
|
-
|
|
1031
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1017
1032
|
path: input.path,
|
|
1018
1033
|
}, response.content, startedAt);
|
|
1019
1034
|
return response;
|
|
@@ -1027,7 +1042,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1027
1042
|
const editContent = [textBlock(editResultText)];
|
|
1028
1043
|
logToolCall(config, {
|
|
1029
1044
|
tool: toolNames.edit,
|
|
1030
|
-
|
|
1045
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1031
1046
|
path: input.path,
|
|
1032
1047
|
success: true,
|
|
1033
1048
|
durationMs: Math.round(performance.now() - startedAt),
|
|
@@ -1055,6 +1070,148 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1055
1070
|
});
|
|
1056
1071
|
});
|
|
1057
1072
|
}
|
|
1073
|
+
registerAppTool(server, toolNames.rename, {
|
|
1074
|
+
title: "Rename path",
|
|
1075
|
+
description: toolDescriptions.rename,
|
|
1076
|
+
inputSchema: {
|
|
1077
|
+
workspaceId: z.string().describe("Workspace identifier returned by open_workspace."),
|
|
1078
|
+
path: z.string().describe("Source file or directory path relative to the workspace root, or absolute inside the OS temp directory."),
|
|
1079
|
+
newPath: z.string().describe("Destination path relative to the workspace root, or absolute inside the OS temp directory. The destination must not already exist."),
|
|
1080
|
+
},
|
|
1081
|
+
outputSchema: resultOutputSchema({
|
|
1082
|
+
status: z.literal("renamed"),
|
|
1083
|
+
path: z.string(),
|
|
1084
|
+
newPath: z.string(),
|
|
1085
|
+
}),
|
|
1086
|
+
...toolWidgetDescriptorMeta(config, "edit"),
|
|
1087
|
+
annotations: EDIT_TOOL_ANNOTATIONS,
|
|
1088
|
+
}, async ({ workspaceId, path, newPath }, extra) => {
|
|
1089
|
+
const workspace = workspaces.getWorkspace(workspaceId);
|
|
1090
|
+
return runToolWithHooks(hooks, {
|
|
1091
|
+
tool: toolNames.rename,
|
|
1092
|
+
invocation: workspaceHookInvocation(workspace),
|
|
1093
|
+
payload: { path, newPath, paths: [path, newPath] },
|
|
1094
|
+
changedPaths: () => [path, newPath],
|
|
1095
|
+
operation: async () => {
|
|
1096
|
+
const startedAt = performance.now();
|
|
1097
|
+
try {
|
|
1098
|
+
await renamePath({ path, newPath }, {
|
|
1099
|
+
cwd: workspace.root,
|
|
1100
|
+
allowedRoots: workspaces.fileToolRoots(workspace),
|
|
1101
|
+
});
|
|
1102
|
+
const result = `Renamed ${path} to ${newPath}.`;
|
|
1103
|
+
const content = [textBlock(result)];
|
|
1104
|
+
logToolCall(config, {
|
|
1105
|
+
tool: toolNames.rename,
|
|
1106
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1107
|
+
path: `${path} -> ${newPath}`,
|
|
1108
|
+
success: true,
|
|
1109
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
1110
|
+
});
|
|
1111
|
+
return {
|
|
1112
|
+
content,
|
|
1113
|
+
_meta: {
|
|
1114
|
+
tool: toolNames.rename,
|
|
1115
|
+
card: {
|
|
1116
|
+
workspaceId,
|
|
1117
|
+
path: newPath,
|
|
1118
|
+
summary: { previousPath: path },
|
|
1119
|
+
payload: { content },
|
|
1120
|
+
},
|
|
1121
|
+
},
|
|
1122
|
+
structuredContent: {
|
|
1123
|
+
result,
|
|
1124
|
+
status: "renamed",
|
|
1125
|
+
path,
|
|
1126
|
+
newPath,
|
|
1127
|
+
},
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
catch (error) {
|
|
1131
|
+
logToolCall(config, {
|
|
1132
|
+
tool: toolNames.rename,
|
|
1133
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1134
|
+
path: `${path} -> ${newPath}`,
|
|
1135
|
+
success: false,
|
|
1136
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
1137
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1138
|
+
});
|
|
1139
|
+
throw error;
|
|
1140
|
+
}
|
|
1141
|
+
},
|
|
1142
|
+
});
|
|
1143
|
+
});
|
|
1144
|
+
registerAppTool(server, toolNames.delete, {
|
|
1145
|
+
title: "Delete path",
|
|
1146
|
+
description: toolDescriptions.delete,
|
|
1147
|
+
inputSchema: {
|
|
1148
|
+
workspaceId: z.string().describe("Workspace identifier returned by open_workspace."),
|
|
1149
|
+
path: z.string().describe("File or directory path relative to the workspace root, or absolute inside the OS temp directory."),
|
|
1150
|
+
recursive: z.boolean().optional().describe("Delete a non-empty directory tree. Defaults to false."),
|
|
1151
|
+
},
|
|
1152
|
+
outputSchema: resultOutputSchema({
|
|
1153
|
+
status: z.literal("deleted"),
|
|
1154
|
+
path: z.string(),
|
|
1155
|
+
recursive: z.boolean(),
|
|
1156
|
+
}),
|
|
1157
|
+
...toolWidgetDescriptorMeta(config, "edit"),
|
|
1158
|
+
annotations: EDIT_TOOL_ANNOTATIONS,
|
|
1159
|
+
}, async ({ workspaceId, path, recursive }, extra) => {
|
|
1160
|
+
const workspace = workspaces.getWorkspace(workspaceId);
|
|
1161
|
+
return runToolWithHooks(hooks, {
|
|
1162
|
+
tool: toolNames.delete,
|
|
1163
|
+
invocation: workspaceHookInvocation(workspace),
|
|
1164
|
+
payload: { path, recursive: recursive ?? false },
|
|
1165
|
+
changedPaths: () => [path],
|
|
1166
|
+
operation: async () => {
|
|
1167
|
+
const startedAt = performance.now();
|
|
1168
|
+
try {
|
|
1169
|
+
const deleted = await deletePath({ path, recursive }, {
|
|
1170
|
+
cwd: workspace.root,
|
|
1171
|
+
allowedRoots: workspaces.fileToolRoots(workspace),
|
|
1172
|
+
});
|
|
1173
|
+
const result = `Deleted ${path}${deleted.recursive ? " recursively" : ""}.`;
|
|
1174
|
+
const content = [textBlock(result)];
|
|
1175
|
+
logToolCall(config, {
|
|
1176
|
+
tool: toolNames.delete,
|
|
1177
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1178
|
+
path,
|
|
1179
|
+
success: true,
|
|
1180
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
1181
|
+
});
|
|
1182
|
+
return {
|
|
1183
|
+
content,
|
|
1184
|
+
_meta: {
|
|
1185
|
+
tool: toolNames.delete,
|
|
1186
|
+
card: {
|
|
1187
|
+
workspaceId,
|
|
1188
|
+
path,
|
|
1189
|
+
summary: { recursive: deleted.recursive },
|
|
1190
|
+
payload: { content },
|
|
1191
|
+
},
|
|
1192
|
+
},
|
|
1193
|
+
structuredContent: {
|
|
1194
|
+
result,
|
|
1195
|
+
status: "deleted",
|
|
1196
|
+
path,
|
|
1197
|
+
recursive: deleted.recursive,
|
|
1198
|
+
},
|
|
1199
|
+
};
|
|
1200
|
+
}
|
|
1201
|
+
catch (error) {
|
|
1202
|
+
logToolCall(config, {
|
|
1203
|
+
tool: toolNames.delete,
|
|
1204
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1205
|
+
path,
|
|
1206
|
+
success: false,
|
|
1207
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
1208
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1209
|
+
});
|
|
1210
|
+
throw error;
|
|
1211
|
+
}
|
|
1212
|
+
},
|
|
1213
|
+
});
|
|
1214
|
+
});
|
|
1058
1215
|
if (config.toolMode === "codex") {
|
|
1059
1216
|
registerAppTool(server, "apply_patch", {
|
|
1060
1217
|
title: "Apply patch",
|
|
@@ -1078,7 +1235,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1078
1235
|
}),
|
|
1079
1236
|
...toolWidgetDescriptorMeta(config, "edit"),
|
|
1080
1237
|
annotations: EDIT_TOOL_ANNOTATIONS,
|
|
1081
|
-
}, async ({ workspaceId, patch }) => {
|
|
1238
|
+
}, async ({ workspaceId, patch }, extra) => {
|
|
1082
1239
|
const workspace = workspaces.getWorkspace(workspaceId);
|
|
1083
1240
|
return runToolWithHooks(hooks, {
|
|
1084
1241
|
tool: "apply_patch",
|
|
@@ -1088,7 +1245,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1088
1245
|
.filter((path) => Boolean(path)))),
|
|
1089
1246
|
operation: async () => {
|
|
1090
1247
|
const startedAt = performance.now();
|
|
1091
|
-
const applied = await applyPatch(workspace.root, patch);
|
|
1248
|
+
const applied = await applyPatch(workspace.root, patch, [tmpdir()]);
|
|
1092
1249
|
const paths = applied.files.map((file) => file.path).join(", ");
|
|
1093
1250
|
const result = `Applied patch to ${applied.files.length} file(s): ${paths}`;
|
|
1094
1251
|
const content = [textBlock(result)];
|
|
@@ -1097,7 +1254,8 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1097
1254
|
: `${applied.files.length} files`;
|
|
1098
1255
|
logToolCall(config, {
|
|
1099
1256
|
tool: "apply_patch",
|
|
1100
|
-
|
|
1257
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1258
|
+
path: displayPath,
|
|
1101
1259
|
success: true,
|
|
1102
1260
|
durationMs: Math.round(performance.now() - startedAt),
|
|
1103
1261
|
});
|
|
@@ -1140,7 +1298,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1140
1298
|
outputSchema: resultOutputSchema(),
|
|
1141
1299
|
...toolWidgetDescriptorMeta(config, "show_changes"),
|
|
1142
1300
|
annotations: { readOnlyHint: true },
|
|
1143
|
-
}, async ({ workspaceId }) => {
|
|
1301
|
+
}, async ({ workspaceId }, extra) => {
|
|
1144
1302
|
const workspace = workspaces.getWorkspace(workspaceId);
|
|
1145
1303
|
return runToolWithHooks(hooks, {
|
|
1146
1304
|
tool: "show_changes",
|
|
@@ -1155,7 +1313,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1155
1313
|
const content = [textBlock(review.result)];
|
|
1156
1314
|
logToolCall(config, {
|
|
1157
1315
|
tool: "show_changes",
|
|
1158
|
-
|
|
1316
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1159
1317
|
success: true,
|
|
1160
1318
|
durationMs: Math.round(performance.now() - startedAt),
|
|
1161
1319
|
});
|
|
@@ -1183,7 +1341,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1183
1341
|
if (config.toolMode === "full") {
|
|
1184
1342
|
registerAppTool(server, toolNames.grep, {
|
|
1185
1343
|
title: "Grep",
|
|
1186
|
-
description: "Search file contents inside an open workspace. Use this before broad reads when looking for symbols, text, or usage sites. Respects project ignore rules. Call open_workspace first and pass workspaceId.",
|
|
1344
|
+
description: "Search file contents inside an open workspace or the OS temp directory. Use this before broad reads when looking for symbols, text, or usage sites. Respects project ignore rules. Call open_workspace first and pass workspaceId.",
|
|
1187
1345
|
inputSchema: {
|
|
1188
1346
|
workspaceId: z
|
|
1189
1347
|
.string()
|
|
@@ -1192,13 +1350,13 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1192
1350
|
path: z
|
|
1193
1351
|
.string()
|
|
1194
1352
|
.optional()
|
|
1195
|
-
.describe("Optional path or glob scope relative to the workspace root."),
|
|
1353
|
+
.describe("Optional path or glob scope relative to the workspace root, or an absolute path inside the OS temp directory."),
|
|
1196
1354
|
include: z.string().optional().describe("Optional include glob."),
|
|
1197
1355
|
},
|
|
1198
1356
|
outputSchema: resultOutputSchema(),
|
|
1199
1357
|
...toolWidgetDescriptorMeta(config, "search"),
|
|
1200
1358
|
annotations: { readOnlyHint: true },
|
|
1201
|
-
}, async ({ workspaceId, ...input }) => {
|
|
1359
|
+
}, async ({ workspaceId, ...input }, extra) => {
|
|
1202
1360
|
const workspace = workspaces.getWorkspace(workspaceId);
|
|
1203
1361
|
return runToolWithHooks(hooks, {
|
|
1204
1362
|
tool: toolNames.grep,
|
|
@@ -1207,16 +1365,15 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1207
1365
|
isFailure: toolResultIsError,
|
|
1208
1366
|
operation: async () => {
|
|
1209
1367
|
const startedAt = performance.now();
|
|
1210
|
-
if (input.path)
|
|
1211
|
-
workspaces.resolvePath(workspace, input.path);
|
|
1212
1368
|
const response = await grepFilesTool(input, {
|
|
1213
1369
|
cwd: workspace.root,
|
|
1214
1370
|
root: workspace.root,
|
|
1371
|
+
fileRoots: workspaces.fileToolRoots(workspace),
|
|
1215
1372
|
});
|
|
1216
1373
|
if (response.isError) {
|
|
1217
1374
|
logFailedToolResponse(config, {
|
|
1218
1375
|
tool: toolNames.grep,
|
|
1219
|
-
|
|
1376
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1220
1377
|
path: input.path,
|
|
1221
1378
|
}, response.content, startedAt);
|
|
1222
1379
|
return response;
|
|
@@ -1228,7 +1385,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1228
1385
|
};
|
|
1229
1386
|
logToolCall(config, {
|
|
1230
1387
|
tool: toolNames.grep,
|
|
1231
|
-
|
|
1388
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1232
1389
|
path: input.path,
|
|
1233
1390
|
success: true,
|
|
1234
1391
|
durationMs: Math.round(performance.now() - startedAt),
|
|
@@ -1253,7 +1410,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1253
1410
|
});
|
|
1254
1411
|
registerAppTool(server, toolNames.glob, {
|
|
1255
1412
|
title: "Glob",
|
|
1256
|
-
description: "Find files by glob pattern inside an open workspace. Use this to discover filenames or narrow file sets before reading. Respects project ignore rules. Call open_workspace first and pass workspaceId.",
|
|
1413
|
+
description: "Find files by glob pattern inside an open workspace or the OS temp directory. Use this to discover filenames or narrow file sets before reading. Respects project ignore rules. Call open_workspace first and pass workspaceId.",
|
|
1257
1414
|
inputSchema: {
|
|
1258
1415
|
workspaceId: z
|
|
1259
1416
|
.string()
|
|
@@ -1262,12 +1419,12 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1262
1419
|
path: z
|
|
1263
1420
|
.string()
|
|
1264
1421
|
.optional()
|
|
1265
|
-
.describe("Optional path scope relative to the workspace root."),
|
|
1422
|
+
.describe("Optional path scope relative to the workspace root, or an absolute path inside the OS temp directory."),
|
|
1266
1423
|
},
|
|
1267
1424
|
outputSchema: resultOutputSchema(),
|
|
1268
1425
|
...toolWidgetDescriptorMeta(config, "search"),
|
|
1269
1426
|
annotations: { readOnlyHint: true },
|
|
1270
|
-
}, async ({ workspaceId, ...input }) => {
|
|
1427
|
+
}, async ({ workspaceId, ...input }, extra) => {
|
|
1271
1428
|
const workspace = workspaces.getWorkspace(workspaceId);
|
|
1272
1429
|
return runToolWithHooks(hooks, {
|
|
1273
1430
|
tool: toolNames.glob,
|
|
@@ -1276,16 +1433,15 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1276
1433
|
isFailure: toolResultIsError,
|
|
1277
1434
|
operation: async () => {
|
|
1278
1435
|
const startedAt = performance.now();
|
|
1279
|
-
if (input.path)
|
|
1280
|
-
workspaces.resolvePath(workspace, input.path);
|
|
1281
1436
|
const response = await findFilesTool(input, {
|
|
1282
1437
|
cwd: workspace.root,
|
|
1283
1438
|
root: workspace.root,
|
|
1439
|
+
fileRoots: workspaces.fileToolRoots(workspace),
|
|
1284
1440
|
});
|
|
1285
1441
|
if (response.isError) {
|
|
1286
1442
|
logFailedToolResponse(config, {
|
|
1287
1443
|
tool: toolNames.glob,
|
|
1288
|
-
|
|
1444
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1289
1445
|
path: input.path,
|
|
1290
1446
|
}, response.content, startedAt);
|
|
1291
1447
|
return response;
|
|
@@ -1297,7 +1453,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1297
1453
|
};
|
|
1298
1454
|
logToolCall(config, {
|
|
1299
1455
|
tool: toolNames.glob,
|
|
1300
|
-
|
|
1456
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1301
1457
|
path: input.path,
|
|
1302
1458
|
success: true,
|
|
1303
1459
|
durationMs: Math.round(performance.now() - startedAt),
|
|
@@ -1322,19 +1478,19 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1322
1478
|
});
|
|
1323
1479
|
registerAppTool(server, toolNames.ls, {
|
|
1324
1480
|
title: "Ls",
|
|
1325
|
-
description: "List a directory inside an open workspace. Use this for directory inspection before reading files. Call open_workspace first and pass workspaceId.",
|
|
1481
|
+
description: "List a directory inside an open workspace or the OS temp directory. Use this for directory inspection before reading files. Call open_workspace first and pass workspaceId.",
|
|
1326
1482
|
inputSchema: {
|
|
1327
1483
|
workspaceId: z
|
|
1328
1484
|
.string()
|
|
1329
1485
|
.describe("Workspace identifier returned by open_workspace."),
|
|
1330
1486
|
path: z
|
|
1331
1487
|
.string()
|
|
1332
|
-
.describe("Directory path to list, relative to the workspace root."),
|
|
1488
|
+
.describe("Directory path to list, relative to the workspace root or absolute inside the OS temp directory."),
|
|
1333
1489
|
},
|
|
1334
1490
|
outputSchema: resultOutputSchema(),
|
|
1335
1491
|
...toolWidgetDescriptorMeta(config, "directory"),
|
|
1336
1492
|
annotations: { readOnlyHint: true },
|
|
1337
|
-
}, async ({ workspaceId, ...input }) => {
|
|
1493
|
+
}, async ({ workspaceId, ...input }, extra) => {
|
|
1338
1494
|
const workspace = workspaces.getWorkspace(workspaceId);
|
|
1339
1495
|
return runToolWithHooks(hooks, {
|
|
1340
1496
|
tool: toolNames.ls,
|
|
@@ -1343,15 +1499,15 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1343
1499
|
isFailure: toolResultIsError,
|
|
1344
1500
|
operation: async () => {
|
|
1345
1501
|
const startedAt = performance.now();
|
|
1346
|
-
workspaces.resolvePath(workspace, input.path);
|
|
1347
1502
|
const response = await listDirectoryTool(input, {
|
|
1348
1503
|
cwd: workspace.root,
|
|
1349
1504
|
root: workspace.root,
|
|
1505
|
+
fileRoots: workspaces.fileToolRoots(workspace),
|
|
1350
1506
|
});
|
|
1351
1507
|
if (response.isError) {
|
|
1352
1508
|
logFailedToolResponse(config, {
|
|
1353
1509
|
tool: toolNames.ls,
|
|
1354
|
-
|
|
1510
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1355
1511
|
path: input.path,
|
|
1356
1512
|
}, response.content, startedAt);
|
|
1357
1513
|
return response;
|
|
@@ -1359,7 +1515,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1359
1515
|
const summary = textSummary(response.content);
|
|
1360
1516
|
logToolCall(config, {
|
|
1361
1517
|
tool: toolNames.ls,
|
|
1362
|
-
|
|
1518
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1363
1519
|
path: input.path,
|
|
1364
1520
|
success: true,
|
|
1365
1521
|
durationMs: Math.round(performance.now() - startedAt),
|
|
@@ -1408,7 +1564,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1408
1564
|
outputSchema: resultOutputSchema(),
|
|
1409
1565
|
...toolWidgetDescriptorMeta(config, "shell"),
|
|
1410
1566
|
annotations: SHELL_TOOL_ANNOTATIONS,
|
|
1411
|
-
}, async ({ workspaceId, workingDirectory, ...input }) => {
|
|
1567
|
+
}, async ({ workspaceId, workingDirectory, ...input }, extra) => {
|
|
1412
1568
|
const workspace = workspaces.getWorkspace(workspaceId);
|
|
1413
1569
|
return runToolWithHooks(hooks, {
|
|
1414
1570
|
tool: toolNames.shell,
|
|
@@ -1429,7 +1585,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1429
1585
|
if (response.isError) {
|
|
1430
1586
|
logFailedToolResponse(config, {
|
|
1431
1587
|
tool: toolNames.shell,
|
|
1432
|
-
|
|
1588
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1433
1589
|
workingDirectory: workingDirectory ?? ".",
|
|
1434
1590
|
command: input.command,
|
|
1435
1591
|
commandLength: input.command.length,
|
|
@@ -1443,7 +1599,7 @@ export function createMcpServer(config, workspaces, reviewCheckpoints, processSe
|
|
|
1443
1599
|
};
|
|
1444
1600
|
logToolCall(config, {
|
|
1445
1601
|
tool: toolNames.shell,
|
|
1446
|
-
|
|
1602
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
1447
1603
|
workingDirectory: workingDirectory ?? ".",
|
|
1448
1604
|
command: input.command,
|
|
1449
1605
|
commandLength: input.command.length,
|