@akira-tl/forgerelay 0.8.7 → 0.8.9
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 +18 -0
- package/README.md +10 -18
- package/capabilities/host-integration/GUIDE.md +2 -2
- package/dist/activity/{audit-store.js → history/audit-store.js} +129 -21
- package/dist/activity/history/bash-output-store.js +250 -0
- package/dist/activity/{host-turn-store.js → history/host-turn-store.js} +4 -1
- package/dist/activity/{query-service.js → history/query-service.js} +13 -7
- package/dist/activity/{lifecycle.js → runtime/lifecycle.js} +1 -1
- package/dist/activity/{mcp-query-tools.js → runtime/mcp-query-tools.js} +3 -3
- package/dist/activity/storage/history.js +12 -0
- package/dist/activity/storage/paths.js +56 -0
- package/dist/activity/storage/segmented-log.js +149 -0
- package/dist/cli/setup-support.js +116 -0
- package/dist/cli.js +18 -126
- package/dist/lsp/code-intelligence.js +1 -1
- package/dist/lsp/test-support/server-fixture.js +9 -9
- package/dist/mcp/filesystem/filesystem-tools.js +245 -0
- package/dist/mcp/hooks/command-runner.js +79 -0
- package/dist/{hook-cli.js → mcp/hooks/hook-cli.js} +1 -1
- package/dist/{hooks.js → mcp/hooks/hooks.js} +3 -80
- package/dist/{oauth-provider.js → mcp/oauth/oauth-provider.js} +1 -1
- package/dist/{oauth-store.js → mcp/oauth/oauth-store.js} +5 -4
- package/dist/{operations → mcp/operations}/native-bulk-mutations.js +2 -2
- package/dist/mcp/panel/app.js +143 -0
- package/dist/{mcp-app-template.js → mcp/panel/mcp-app-template.js} +2 -38
- package/dist/mcp/process/runtime.js +257 -0
- package/dist/mcp/process/tools.js +346 -0
- package/dist/mcp/server/core/activity-support.js +70 -0
- package/dist/{capabilities.js → mcp/server/core/capabilities.js} +5 -3
- package/dist/{capability-registry.js → mcp/server/core/capability-registry.js} +2 -2
- package/dist/mcp/server/core/capability-support.js +90 -0
- package/dist/mcp/server/core/schemas.js +216 -0
- package/dist/mcp/server/core/tool-support.js +207 -0
- package/dist/mcp/server/core/version.js +9 -0
- package/dist/mcp/server/operations/runtime/filesystem-tools.js +400 -0
- package/dist/mcp/server/operations/runtime/operation-runtime.js +523 -0
- package/dist/mcp/server/transport/http-server.js +301 -0
- package/dist/mcp/server/transport/http-support.js +43 -0
- package/dist/mcp/server/workspace/runtime/workspace-open-presentation.js +222 -0
- package/dist/mcp/server/workspace/runtime/workspace-open-schema.js +187 -0
- package/dist/mcp/server/workspace/runtime/workspace-open.js +552 -0
- package/dist/mcp/server/workspace/runtime/workspace-tools.js +601 -0
- package/dist/{config.js → runtime/config/config.js} +3 -3
- package/dist/{user-config.js → runtime/config/user-config.js} +14 -54
- package/dist/{db → runtime/state/db}/client.js +1 -1
- package/dist/{db → runtime/state/db}/migrations.js +34 -3
- package/dist/runtime/state/lock/file-lock.js +130 -0
- package/dist/runtime/testing/server-fixture.js +190 -0
- package/dist/server.js +139 -4192
- package/dist/subagents/providers/adapters/claude.js +86 -52
- package/dist/subagents/providers/adapters/codex.js +103 -39
- package/dist/subagents/providers/adapters/opencode.js +114 -84
- package/dist/subagents/providers/adapters/pi.js +59 -8
- package/dist/subagents/providers/availability.js +15 -30
- package/dist/subagents/providers/runtime/external-command.js +56 -0
- package/dist/subagents/sessions/capability.js +1 -1
- package/dist/subagents/sessions/execution.js +1 -1
- package/dist/subagents/sessions/mcp/activity-audit-test-support.js +30 -0
- package/dist/subagents/sessions/store.js +1 -1
- package/dist/ui/.vite/manifest.json +342 -409
- package/dist/ui/activity-panel-app.html +2 -4
- package/dist/ui/assets/activity-panel-app-7Xe0alhm.css +1 -0
- package/dist/ui/assets/activity-panel-app-Sl1Jro8v.js +115 -0
- package/dist/ui/assets/angular-html-B_yn91wW.js +1 -0
- package/dist/ui/assets/{angular-ts-Bxh4-O1-.js → angular-ts-DSgtloKz.js} +1 -1
- package/dist/ui/assets/{apl-BmYHKQ6m.js → apl-NatWtF8X.js} +1 -1
- package/dist/ui/assets/{astro-C51vqDKq.js → astro-BYFEVBuN.js} +1 -1
- package/dist/ui/assets/{blade-CdhVsmwq.js → blade-DoO7yvMR.js} +1 -1
- package/dist/ui/assets/c-Rl2hMCcg.js +1 -0
- package/dist/ui/assets/{cobol-Cf6azoN_.js → cobol-ByC5mWiB.js} +1 -1
- package/dist/ui/assets/{coffee-vVdGzlmt.js → coffee-Dez77Qov.js} +1 -1
- package/dist/ui/assets/cpp-DtaAQT9h.js +1 -0
- package/dist/ui/assets/{crystal-5UZy6KIX.js → crystal-Bgmbf8ec.js} +1 -1
- package/dist/ui/assets/css-C1tjBtVN.js +1 -0
- package/dist/ui/assets/{edge-CESgo4ia.js → edge-DeH6u8Wg.js} +1 -1
- package/dist/ui/assets/{elixir-9FKfw4cJ.js → elixir-_H3KnmWT.js} +1 -1
- package/dist/ui/assets/{elm-Dv7A0aLa.js → elm-CsCe3U28.js} +1 -1
- package/dist/ui/assets/{erb-DHFmDvM0.js → erb-CbM-L2g8.js} +1 -1
- package/dist/ui/assets/{git-rebase-utbU6CzV.js → git-rebase-D0s5pDh9.js} +1 -1
- package/dist/ui/assets/{glimmer-js-t2kiCkyB.js → glimmer-js-BfOToq_A.js} +1 -1
- package/dist/ui/assets/{glimmer-ts-F0Jv5okV.js → glimmer-ts-CCUOkL2K.js} +1 -1
- package/dist/ui/assets/glsl-DH4ec9dE.js +1 -0
- package/dist/ui/assets/graphql-DilAMBoI.js +1 -0
- package/dist/ui/assets/{hack-8yjdbaSA.js → hack-BDkNDZlF.js} +1 -1
- package/dist/ui/assets/haml-D_QBp6K7.js +1 -0
- package/dist/ui/assets/{handlebars-BBFEg4Lo.js → handlebars-DePUrTpC.js} +1 -1
- package/dist/ui/assets/heavy-payload-DOwZpO6n.js +290 -0
- package/dist/ui/assets/html-By4dNnM4.js +1 -0
- package/dist/ui/assets/{html-derivative-DJAQcZyc.js → html-derivative-DDw9Ef4Q.js} +1 -1
- package/dist/ui/assets/{http-Dg5LSYRK.js → http-B0QxWc9M.js} +1 -1
- package/dist/ui/assets/{hurl-Y5uYzMZR.js → hurl-vMQ4lda1.js} +1 -1
- package/dist/ui/assets/java-DYRe2lWG.js +1 -0
- package/dist/ui/assets/javascript-CxyGqwcL.js +1 -0
- package/dist/ui/assets/{jinja-Bt30h8Ik.js → jinja-JUwV-fZt.js} +1 -1
- package/dist/ui/assets/{jison-D5uZ1Nyo.js → jison-7ZqCEvS8.js} +1 -1
- package/dist/ui/assets/json-dbltgiiA.js +1 -0
- package/dist/ui/assets/jsx-oDopT7YQ.js +1 -0
- package/dist/ui/assets/{julia-76hRaaGz.js → julia-CkKiNSav.js} +1 -1
- package/dist/ui/assets/{just-CDE7W0vW.js → just-DuqCAKJ3.js} +1 -1
- package/dist/ui/assets/{latex-CVO2Byab.js → latex-sudcRDSn.js} +1 -1
- package/dist/ui/assets/{liquid-CA-AS3EX.js → liquid-Di-08Js7.js} +1 -1
- package/dist/ui/assets/lua-YlqdMoV0.js +1 -0
- package/dist/ui/assets/{marko-_BWrPfny.js → marko-CJRNyJDb.js} +1 -1
- package/dist/ui/assets/{mdc-PyJv85eS.js → mdc-t12CzZHs.js} +1 -1
- package/dist/ui/assets/{nginx-DAWVw8yu.js → nginx-57-b4XwT.js} +1 -1
- package/dist/ui/assets/{nim-CKE1dzpU.js → nim-BzrswYQa.js} +1 -1
- package/dist/ui/assets/{perl-BBhWva19.js → perl-D9JR_iIh.js} +1 -1
- package/dist/ui/assets/{php-ChIeaAoF.js → php-Py2gFHil.js} +1 -1
- package/dist/ui/assets/{pug-CMgI5afi.js → pug-PzLLy0h1.js} +1 -1
- package/dist/ui/assets/{qml-CjxTkcFH.js → qml-By8fwgV4.js} +1 -1
- package/dist/ui/assets/r-CcezTbLq.js +1 -0
- package/dist/ui/assets/{razor-i4DbHr8p.js → razor-dG-vdhL_.js} +1 -1
- package/dist/ui/assets/regexp-BlsQ-N_8.js +1 -0
- package/dist/ui/assets/{rst-oy_97Kl4.js → rst-C2awDCat.js} +1 -1
- package/dist/ui/assets/{ruby-C5zYZIyl.js → ruby-zA2W_49d.js} +1 -1
- package/dist/ui/assets/{sas-BnMEh2S3.js → sas-D49bhyaN.js} +1 -1
- package/dist/ui/assets/scss-BQb-cp01.js +1 -0
- package/dist/ui/assets/shellscript-Dga4H_Ni.js +1 -0
- package/dist/ui/assets/{shellsession-BpE5o7_3.js → shellsession-n3-5CqcF.js} +1 -1
- package/dist/ui/assets/{soy-COesmhTY.js → soy-XYBOf_BA.js} +1 -1
- package/dist/ui/assets/sql-ET4u5Cpl.js +1 -0
- package/dist/ui/assets/{stata-CGQEuSZq.js → stata-CLHcJHO_.js} +1 -1
- package/dist/ui/assets/{surrealql-Bz4JbU-9.js → surrealql-BdjQ60T4.js} +1 -1
- package/dist/ui/assets/{svelte-1jM2ejXj.js → svelte-B2RPtKJe.js} +1 -1
- package/dist/ui/assets/{templ-C-VwELcp.js → templ-CrByPW_W.js} +1 -1
- package/dist/ui/assets/{tex-t1rUiQCm.js → tex-DZBkg363.js} +1 -1
- package/dist/ui/assets/{ts-tags-Bewoa6pS.js → ts-tags-DJR3Gphb.js} +1 -1
- package/dist/ui/assets/tsx-CajzROyy.js +1 -0
- package/dist/ui/assets/{twig-DVg-vELl.js → twig-BZjk5Zda.js} +1 -1
- package/dist/ui/assets/typescript-B-EWToLj.js +1 -0
- package/dist/ui/assets/{vue-wPQ7UlMy.js → vue-D_rHCCr8.js} +1 -1
- package/dist/ui/assets/{vue-html-BHtJ8geX.js → vue-html-CC4WlvVt.js} +1 -1
- package/dist/ui/assets/{vue-vine-CNSGAWwc.js → vue-vine-BgNMVgpk.js} +1 -1
- package/dist/ui/assets/xml-BI86-WbH.js +1 -0
- package/dist/ui/assets/{xsl-3_vJ27aE.js → xsl-DXeLZV4J.js} +1 -1
- package/dist/ui/assets/yaml-60_PFlWa.js +1 -0
- package/dist/workspaces/bootstrap.js +72 -0
- package/dist/workspaces/context.js +302 -0
- package/dist/workspaces/conversation-test-support.js +86 -0
- package/dist/{git-worktrees.js → workspaces/git/git-worktrees.js} +1 -1
- package/dist/workspaces/inventory.js +131 -0
- package/dist/workspaces/paths.js +55 -0
- package/dist/{remote-auth.js → workspaces/relay/auth/remote-auth.js} +2 -2
- package/dist/workspaces/relay/result-support.js +111 -0
- package/dist/workspaces/relay/tests/test-support.js +203 -0
- package/dist/{remote-mcp-connection-pool.js → workspaces/relay/transport/remote-mcp-connection-pool.js} +1 -1
- package/dist/workspaces/relay/types.js +1 -0
- package/dist/{remote-workspace-relay.js → workspaces/relay/workspace-relay.js} +23 -172
- package/dist/workspaces/resources/skills.js +285 -0
- package/dist/{review-checkpoints.js → workspaces/review/review-checkpoints.js} +2 -2
- package/dist/workspaces/sessions.js +457 -0
- package/dist/{workspace-store.js → workspaces/state/workspace-store.js} +2 -2
- package/dist/workspaces.js +69 -991
- package/docs/chatgpt-coding-workflow.md +3 -11
- package/docs/configuration.md +12 -25
- package/docs/gotchas.md +0 -30
- package/docs/roadmap.md +6 -10
- package/docs/security.md +1 -5
- package/docs/setup.md +0 -11
- package/package.json +6 -8
- package/scripts/ci/architecture.mjs +109 -0
- package/scripts/ci/verify.mjs +5 -0
- package/scripts/debug/accept/bootstrap.mjs +326 -0
- package/scripts/debug/accept/harness.mjs +76 -0
- package/scripts/debug/accept/support.mjs +432 -0
- package/scripts/debug/accept.mjs +43 -806
- package/scripts/debug/relay-accept/support.mjs +135 -0
- package/scripts/debug/relay-accept.mjs +26 -115
- package/scripts/debug/traffic/support.mjs +167 -0
- package/scripts/debug/traffic/traffic-audit.mjs +4 -161
- package/scripts/{lsp-interop-support.test.mjs → lsp/interop-support.test.mjs} +1 -1
- package/scripts/{lsp-interop.mjs → lsp/interop.mjs} +3 -3
- package/scripts/wiki/sync.mjs +21 -10
- package/dist/activity/bash-output-store.js +0 -127
- package/dist/pi-tools.js +0 -110
- package/dist/skills.js +0 -127
- package/dist/ui/assets/activity-panel-app-CUAN6zyW.js +0 -2
- package/dist/ui/assets/angular-html-BkgDQl-G.js +0 -1
- package/dist/ui/assets/c-IBzBpxAO.js +0 -1
- package/dist/ui/assets/chunk-EyZ2wyi3.js +0 -1
- package/dist/ui/assets/cpp-CVHeO-Jk.js +0 -1
- package/dist/ui/assets/css-DEfus9J5.js +0 -1
- package/dist/ui/assets/glsl-_ooCjaeB.js +0 -1
- package/dist/ui/assets/graphql-B9LqP-cY.js +0 -1
- package/dist/ui/assets/haml-BU5EoZBn.js +0 -1
- package/dist/ui/assets/heavy-payload-CgzrutLm.js +0 -4
- package/dist/ui/assets/html-D-C6YZk4.js +0 -1
- package/dist/ui/assets/java-ppHvycj5.js +0 -1
- package/dist/ui/assets/javascript-DDTjKLlQ.js +0 -1
- package/dist/ui/assets/json-Cw91r8h1.js +0 -1
- package/dist/ui/assets/jsx-04X2FT_1.js +0 -1
- package/dist/ui/assets/lua-CiyBp52Y.js +0 -1
- package/dist/ui/assets/r-DfFga4si.js +0 -1
- package/dist/ui/assets/regexp-iC9_nbSI.js +0 -1
- package/dist/ui/assets/review-payload-BrLbezbq.js +0 -1
- package/dist/ui/assets/scrollbar-CbhpdW05.js +0 -287
- package/dist/ui/assets/scss-BfZXsAWQ.js +0 -1
- package/dist/ui/assets/shellscript-BC2srNaB.js +0 -1
- package/dist/ui/assets/sql-Ccv_yeUm.js +0 -1
- package/dist/ui/assets/tsx-CTXzrBkN.js +0 -1
- package/dist/ui/assets/typescript--ElHoFkw.js +0 -1
- package/dist/ui/assets/workspace-app-Bhj96tsR.js +0 -1
- package/dist/ui/assets/workspace-app-CxwJuZyS.js +0 -111
- package/dist/ui/assets/workspace-app-D6UR0AFl.js +0 -5
- package/dist/ui/assets/workspace-app-ldjBmCJR.css +0 -1
- package/dist/ui/assets/workspace-lifecycle-app-Cqfhx9pV.js +0 -1
- package/dist/ui/assets/xml-JnmX6vyS.js +0 -1
- package/dist/ui/assets/yaml-OAcZkP-w.js +0 -1
- package/dist/ui/workspace-app.html +0 -18
- package/dist/ui/workspace-lifecycle-app.html +0 -18
- package/docs/agent-profile-schema.md +0 -114
- package/docs/artifact-exchange.md +0 -65
- package/docs/versioning.md +0 -205
- /package/capabilities/{managed-worktrees → workspace/managed-worktrees}/GUIDE.md +0 -0
- /package/capabilities/{workspace-tasks → workspace/workspace-tasks}/GUIDE.md +0 -0
- /package/dist/activity/{process-output-audit.js → runtime/process-output-audit.js} +0 -0
- /package/dist/{artifact-error.js → mcp/artifacts/artifact-error.js} +0 -0
- /package/dist/{artifact-tools.js → mcp/artifacts/artifact-tools.js} +0 -0
- /package/dist/{incoming-artifacts.js → mcp/artifacts/incoming-artifacts.js} +0 -0
- /package/dist/{advertised-files.js → mcp/filesystem/advertised-files.js} +0 -0
- /package/dist/{apply-patch.js → mcp/filesystem/apply-patch.js} +0 -0
- /package/dist/{file-mutations.js → mcp/filesystem/file-mutations.js} +0 -0
- /package/dist/{roots.js → mcp/filesystem/roots.js} +0 -0
- /package/dist/{oauth → mcp/oauth}/public-url.js +0 -0
- /package/dist/{oauth → mcp/oauth}/router.js +0 -0
- /package/dist/{operations → mcp/operations}/batch/executor.js +0 -0
- /package/dist/{operations → mcp/operations}/batch/scheduler.js +0 -0
- /package/dist/{operations → mcp/operations}/batch/types.js +0 -0
- /package/dist/{operations → mcp/operations}/bulk-mutation.js +0 -0
- /package/dist/{operations → mcp/operations}/bulk-read.js +0 -0
- /package/dist/{operations → mcp/operations}/core-operation-executor.js +0 -0
- /package/dist/{process-platform.js → mcp/process/process-platform.js} +0 -0
- /package/dist/{process-sessions.js → mcp/process/process-sessions.js} +0 -0
- /package/dist/{request-meta.js → mcp/request-meta.js} +0 -0
- /package/dist/{mcp-sessions.js → mcp/server/transport/mcp-sessions.js} +0 -0
- /package/dist/{server-shutdown.js → mcp/server/transport/server-shutdown.js} +0 -0
- /package/dist/{logger.js → runtime/logging/logger.js} +0 -0
- /package/dist/{db → runtime/state/db}/schema.js +0 -0
- /package/dist/{composite-activity.js → workspaces/composite/composite-activity.js} +0 -0
- /package/dist/{composite-workspaces.js → workspaces/composite/composite-workspaces.js} +0 -0
- /package/dist/{git.js → workspaces/git/git.js} +0 -0
- /package/dist/{workspace-presentation.js → workspaces/presentation/workspace-presentation.js} +0 -0
- /package/dist/{remote-transport.js → workspaces/relay/transport/remote-transport.js} +0 -0
- /package/dist/{workspace-task-reminders.js → workspaces/tasks/workspace-task-reminders.js} +0 -0
- /package/dist/{workspace-tasks.js → workspaces/tasks/workspace-tasks.js} +0 -0
- /package/scripts/{lsp-interop-support.mjs → lsp/interop-support.mjs} +0 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
4
|
+
import * as z from "zod/v4";
|
|
5
|
+
import { applyPatch } from "../../../filesystem/apply-patch.js";
|
|
6
|
+
import { toolNames } from "../../../server-instructions.js";
|
|
7
|
+
import { executeBulkRead } from "../../../operations/bulk-read.js";
|
|
8
|
+
import { formatPathForPrompt } from "../../../../workspaces/resources/skills.js";
|
|
9
|
+
import { activityRelationFor, activityRequestFor, runActivityTool, runActivityToolWithHooks, } from "../../core/activity-support.js";
|
|
10
|
+
import { workspaceHookInvocation } from "../../core/capability-support.js";
|
|
11
|
+
import { resultOutputSchema, workspaceAgentsFileOutputSchema } from "../../core/schemas.js";
|
|
12
|
+
import { contentText, logToolCall, textBlock, toolResultAgentsFiles, toolResultContent, toolResultIsError, toolResultText, workspaceLogContext, } from "../../core/tool-support.js";
|
|
13
|
+
const WRITE_TOOL_ANNOTATIONS = {
|
|
14
|
+
readOnlyHint: false,
|
|
15
|
+
destructiveHint: true,
|
|
16
|
+
idempotentHint: false,
|
|
17
|
+
openWorldHint: false,
|
|
18
|
+
};
|
|
19
|
+
const EDIT_TOOL_ANNOTATIONS = {
|
|
20
|
+
readOnlyHint: false,
|
|
21
|
+
destructiveHint: true,
|
|
22
|
+
idempotentHint: false,
|
|
23
|
+
openWorldHint: false,
|
|
24
|
+
};
|
|
25
|
+
export function registerFilesystemTools(options) {
|
|
26
|
+
const { server, config, workspaces, compositeWorkspaces, compositeTaskGuides, remoteWorkspaces, coreOperations, nativeBulkMutations, activityLifecycle, hooks, toolDescriptions, resolveExecutionTarget, prepareExecutionContext, presentSemanticWorkResult, hostScopeIdFor, } = options;
|
|
27
|
+
registerAppTool(server, toolNames.read, {
|
|
28
|
+
title: "Read file",
|
|
29
|
+
description: toolDescriptions.read,
|
|
30
|
+
inputSchema: {
|
|
31
|
+
workspaceId: z
|
|
32
|
+
.string()
|
|
33
|
+
.describe("Workspace identifier returned by open_workspace."),
|
|
34
|
+
member: z
|
|
35
|
+
.string()
|
|
36
|
+
.optional()
|
|
37
|
+
.describe("Required for Composite member-scoped file reads. Omit only when reading an advertised Composite-owned capability guide."),
|
|
38
|
+
path: z
|
|
39
|
+
.string()
|
|
40
|
+
.optional()
|
|
41
|
+
.describe(config.skillsEnabled
|
|
42
|
+
? "One file path to read, relative to the workspace root or absolute inside the OS temp directory. Load an available skill with skills://<name>; after loading it, read files in that skill with skills://<name>/<relative-path>. Advertised capability-guide paths from open_workspace are also readable. Use exactly one of path or paths."
|
|
43
|
+
: "One file path to read, relative to the workspace root or absolute inside the OS temp directory. May also be an advertised capability-guide path from open_workspace. Use exactly one of path or paths."),
|
|
44
|
+
paths: z
|
|
45
|
+
.array(z.string())
|
|
46
|
+
.min(1)
|
|
47
|
+
.max(100)
|
|
48
|
+
.optional()
|
|
49
|
+
.describe("Multiple file paths to read in one call. Uses the same offset/limit for every file. Use exactly one of path or paths."),
|
|
50
|
+
offset: z
|
|
51
|
+
.number()
|
|
52
|
+
.int()
|
|
53
|
+
.positive()
|
|
54
|
+
.optional()
|
|
55
|
+
.describe("1-indexed line number to start reading from."),
|
|
56
|
+
limit: z
|
|
57
|
+
.number()
|
|
58
|
+
.int()
|
|
59
|
+
.positive()
|
|
60
|
+
.optional()
|
|
61
|
+
.describe("Maximum number of lines to read."),
|
|
62
|
+
},
|
|
63
|
+
outputSchema: resultOutputSchema({
|
|
64
|
+
agentsFiles: z.array(workspaceAgentsFileOutputSchema).optional(),
|
|
65
|
+
results: z.array(z.object({
|
|
66
|
+
path: z.string(),
|
|
67
|
+
status: z.enum(["done", "error"]),
|
|
68
|
+
result: z.string(),
|
|
69
|
+
})).optional(),
|
|
70
|
+
files: z.number().int().nonnegative().optional(),
|
|
71
|
+
failed: z.number().int().nonnegative().optional(),
|
|
72
|
+
}),
|
|
73
|
+
_meta: {},
|
|
74
|
+
annotations: { readOnlyHint: true },
|
|
75
|
+
}, async ({ workspaceId, member, path, paths, offset, limit }, extra) => {
|
|
76
|
+
if ((path === undefined) === (paths === undefined)) {
|
|
77
|
+
throw new Error("read requires exactly one of path or paths.");
|
|
78
|
+
}
|
|
79
|
+
if (compositeWorkspaces.has(workspaceId) && member === undefined && path !== undefined) {
|
|
80
|
+
const guide = compositeTaskGuides.find((candidate) => formatPathForPrompt(candidate.filePath) === path || candidate.filePath === path);
|
|
81
|
+
if (guide) {
|
|
82
|
+
if (!compositeWorkspaces.isActive(workspaceId)) {
|
|
83
|
+
throw new Error(`Composite Workspace ${workspaceId} is closed. Reopen it with open_workspace before use.`);
|
|
84
|
+
}
|
|
85
|
+
const startedAt = performance.now();
|
|
86
|
+
const raw = readFileSync(guide.filePath, "utf8");
|
|
87
|
+
const start = (offset ?? 1) - 1;
|
|
88
|
+
const end = limit === undefined ? undefined : start + limit;
|
|
89
|
+
const result = raw.split("\n").slice(start, end).join("\n");
|
|
90
|
+
logToolCall(config, {
|
|
91
|
+
tool: toolNames.read,
|
|
92
|
+
path: formatPathForPrompt(guide.filePath),
|
|
93
|
+
success: true,
|
|
94
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
95
|
+
});
|
|
96
|
+
return {
|
|
97
|
+
content: [textBlock(result)],
|
|
98
|
+
structuredContent: { result },
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const target = resolveExecutionTarget(workspaceId, member);
|
|
103
|
+
const executionWorkspaceId = target.executionWorkspaceId;
|
|
104
|
+
const executionContext = await prepareExecutionContext(target, extra._meta, extra.signal, extra.sessionId);
|
|
105
|
+
if (remoteWorkspaces.has(executionWorkspaceId)) {
|
|
106
|
+
return presentSemanticWorkResult(await remoteWorkspaces.read(executionWorkspaceId, { path, paths, offset, limit }, hostScopeIdFor(extra._meta, extra.sessionId)), target);
|
|
107
|
+
}
|
|
108
|
+
if (path !== undefined) {
|
|
109
|
+
return presentSemanticWorkResult(await coreOperations.read({ workspaceId: executionWorkspaceId, path, offset, limit }, executionContext), target);
|
|
110
|
+
}
|
|
111
|
+
const workspace = workspaces.getWorkspace(executionWorkspaceId);
|
|
112
|
+
let response;
|
|
113
|
+
await runActivityTool(activityLifecycle, workspace, hostScopeIdFor(extra._meta, extra.sessionId), toolNames.read, activityRequestFor({ workspaceId: executionWorkspaceId, paths, offset, limit }, executionContext), async (parentContext) => {
|
|
114
|
+
const execution = await executeBulkRead({
|
|
115
|
+
paths: paths,
|
|
116
|
+
signal: extra.signal,
|
|
117
|
+
run: (childPath) => coreOperations.read({ workspaceId: executionWorkspaceId, path: childPath, offset, limit }, {
|
|
118
|
+
...executionContext,
|
|
119
|
+
parentActivityId: parentContext.activityId,
|
|
120
|
+
turnId: parentContext.turnId,
|
|
121
|
+
}),
|
|
122
|
+
isError: toolResultIsError,
|
|
123
|
+
resultText: toolResultText,
|
|
124
|
+
});
|
|
125
|
+
const content = execution.children.flatMap((child) => [
|
|
126
|
+
textBlock(`--- ${child.path} · ${child.status} ---`),
|
|
127
|
+
...(child.response
|
|
128
|
+
? toolResultContent(child.response)
|
|
129
|
+
: [textBlock(child.result)]),
|
|
130
|
+
]);
|
|
131
|
+
const seenAgentPaths = new Set();
|
|
132
|
+
const agentsFiles = execution.children.flatMap((child) => child.response ? toolResultAgentsFiles(child.response) : []).filter((file) => {
|
|
133
|
+
if (seenAgentPaths.has(file.path))
|
|
134
|
+
return false;
|
|
135
|
+
seenAgentPaths.add(file.path);
|
|
136
|
+
return true;
|
|
137
|
+
});
|
|
138
|
+
response = {
|
|
139
|
+
content,
|
|
140
|
+
structuredContent: {
|
|
141
|
+
result: contentText(content),
|
|
142
|
+
results: execution.children.map(({ path: childPath, status, result }) => ({
|
|
143
|
+
path: childPath,
|
|
144
|
+
status,
|
|
145
|
+
result,
|
|
146
|
+
})),
|
|
147
|
+
files: execution.children.length,
|
|
148
|
+
failed: execution.failed,
|
|
149
|
+
...(agentsFiles.length > 0 ? { agentsFiles } : {}),
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
return {
|
|
153
|
+
childCount: execution.children.length,
|
|
154
|
+
succeeded: execution.succeeded,
|
|
155
|
+
failed: execution.failed,
|
|
156
|
+
};
|
|
157
|
+
}, (summary) => summary.failed > 0
|
|
158
|
+
? { type: "failed", error: `${summary.failed} of ${summary.childCount} child Reads failed.` }
|
|
159
|
+
: { type: "succeeded" }, activityRelationFor(executionContext));
|
|
160
|
+
if (!response)
|
|
161
|
+
throw new Error("Bulk Read completed without a response.");
|
|
162
|
+
return presentSemanticWorkResult(response, target);
|
|
163
|
+
});
|
|
164
|
+
if (config.toolMode !== "codex") {
|
|
165
|
+
registerAppTool(server, toolNames.write, {
|
|
166
|
+
title: "Write file",
|
|
167
|
+
description: toolDescriptions.write,
|
|
168
|
+
inputSchema: {
|
|
169
|
+
workspaceId: z
|
|
170
|
+
.string()
|
|
171
|
+
.describe("Workspace identifier returned by open_workspace."),
|
|
172
|
+
member: z.string().optional().describe("Required for a Composite Workspace; explicit member name that owns this operation."),
|
|
173
|
+
path: z
|
|
174
|
+
.string()
|
|
175
|
+
.describe("File path to write, relative to the workspace root or absolute inside the OS temp directory."),
|
|
176
|
+
content: z.string().describe("Complete new file content."),
|
|
177
|
+
},
|
|
178
|
+
outputSchema: resultOutputSchema(),
|
|
179
|
+
_meta: {},
|
|
180
|
+
annotations: WRITE_TOOL_ANNOTATIONS,
|
|
181
|
+
}, async ({ workspaceId, member, ...input }, extra) => {
|
|
182
|
+
const target = resolveExecutionTarget(workspaceId, member);
|
|
183
|
+
const executionWorkspaceId = target.executionWorkspaceId;
|
|
184
|
+
const executionContext = await prepareExecutionContext(target, extra._meta, extra.signal, extra.sessionId);
|
|
185
|
+
if (remoteWorkspaces.has(executionWorkspaceId)) {
|
|
186
|
+
return presentSemanticWorkResult(await remoteWorkspaces.write(executionWorkspaceId, input, hostScopeIdFor(extra._meta, extra.sessionId)), target);
|
|
187
|
+
}
|
|
188
|
+
return presentSemanticWorkResult(await coreOperations.write({ workspaceId: executionWorkspaceId, ...input }, executionContext), target);
|
|
189
|
+
});
|
|
190
|
+
registerAppTool(server, toolNames.edit, {
|
|
191
|
+
title: "Edit file",
|
|
192
|
+
description: toolDescriptions.edit,
|
|
193
|
+
inputSchema: {
|
|
194
|
+
workspaceId: z
|
|
195
|
+
.string()
|
|
196
|
+
.describe("Workspace identifier returned by open_workspace."),
|
|
197
|
+
member: z.string().optional().describe("Required for a Composite Workspace; explicit member name that owns this operation."),
|
|
198
|
+
path: z
|
|
199
|
+
.string()
|
|
200
|
+
.optional()
|
|
201
|
+
.describe("One file path to edit. Use exactly one of path or paths."),
|
|
202
|
+
paths: z
|
|
203
|
+
.array(z.string())
|
|
204
|
+
.min(1)
|
|
205
|
+
.max(100)
|
|
206
|
+
.optional()
|
|
207
|
+
.describe("Multiple file paths to edit with the same edits. Use exactly one of path or paths."),
|
|
208
|
+
edits: z
|
|
209
|
+
.array(z.object({
|
|
210
|
+
oldText: z
|
|
211
|
+
.string()
|
|
212
|
+
.describe("Exact text to replace. Must match uniquely in the original file."),
|
|
213
|
+
newText: z.string().describe("Replacement text."),
|
|
214
|
+
}))
|
|
215
|
+
.min(1),
|
|
216
|
+
},
|
|
217
|
+
outputSchema: resultOutputSchema({
|
|
218
|
+
status: z.enum(["applied", "partial"]),
|
|
219
|
+
results: z.array(z.object({
|
|
220
|
+
path: z.string(),
|
|
221
|
+
status: z.enum(["done", "error", "unexecuted"]),
|
|
222
|
+
result: z.string().optional(),
|
|
223
|
+
})).optional(),
|
|
224
|
+
files: z.number().int().nonnegative().optional(),
|
|
225
|
+
completed: z.number().int().nonnegative().optional(),
|
|
226
|
+
failed: z.number().int().nonnegative().optional(),
|
|
227
|
+
unexecuted: z.number().int().nonnegative().optional(),
|
|
228
|
+
}),
|
|
229
|
+
_meta: {},
|
|
230
|
+
annotations: EDIT_TOOL_ANNOTATIONS,
|
|
231
|
+
}, async ({ workspaceId, member, path, paths, edits }, extra) => {
|
|
232
|
+
if ((path === undefined) === (paths === undefined)) {
|
|
233
|
+
throw new Error("edit requires exactly one of path or paths.");
|
|
234
|
+
}
|
|
235
|
+
const target = resolveExecutionTarget(workspaceId, member);
|
|
236
|
+
const executionWorkspaceId = target.executionWorkspaceId;
|
|
237
|
+
const executionContext = await prepareExecutionContext(target, extra._meta, extra.signal, extra.sessionId);
|
|
238
|
+
if (remoteWorkspaces.has(executionWorkspaceId)) {
|
|
239
|
+
return presentSemanticWorkResult(await remoteWorkspaces.edit(executionWorkspaceId, { path, paths, edits }, hostScopeIdFor(extra._meta, extra.sessionId)), target);
|
|
240
|
+
}
|
|
241
|
+
if (path !== undefined) {
|
|
242
|
+
return presentSemanticWorkResult(await coreOperations.edit({ workspaceId: executionWorkspaceId, path, edits }, executionContext), target);
|
|
243
|
+
}
|
|
244
|
+
return presentSemanticWorkResult(await nativeBulkMutations.edit({ workspaceId: executionWorkspaceId, paths: paths, edits }, executionContext), target);
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
registerAppTool(server, toolNames.rename, {
|
|
248
|
+
title: "Rename path",
|
|
249
|
+
description: toolDescriptions.rename,
|
|
250
|
+
inputSchema: {
|
|
251
|
+
workspaceId: z.string().describe("Workspace identifier returned by open_workspace."),
|
|
252
|
+
member: z.string().optional().describe("Required for a Composite Workspace; explicit member name that owns this operation."),
|
|
253
|
+
path: z.string().describe("Source file or directory path relative to the workspace root, or absolute inside the OS temp directory."),
|
|
254
|
+
newPath: z.string().describe("Destination path relative to the workspace root, or absolute inside the OS temp directory. The destination must not already exist."),
|
|
255
|
+
},
|
|
256
|
+
outputSchema: resultOutputSchema({
|
|
257
|
+
status: z.literal("renamed"),
|
|
258
|
+
path: z.string(),
|
|
259
|
+
newPath: z.string(),
|
|
260
|
+
}),
|
|
261
|
+
_meta: {},
|
|
262
|
+
annotations: EDIT_TOOL_ANNOTATIONS,
|
|
263
|
+
}, async ({ workspaceId, member, path, newPath }, extra) => {
|
|
264
|
+
const target = resolveExecutionTarget(workspaceId, member);
|
|
265
|
+
const executionWorkspaceId = target.executionWorkspaceId;
|
|
266
|
+
const executionContext = await prepareExecutionContext(target, extra._meta, extra.signal, extra.sessionId);
|
|
267
|
+
if (remoteWorkspaces.has(executionWorkspaceId)) {
|
|
268
|
+
return presentSemanticWorkResult(await remoteWorkspaces.rename(executionWorkspaceId, { path, newPath }, hostScopeIdFor(extra._meta, extra.sessionId)), target);
|
|
269
|
+
}
|
|
270
|
+
return presentSemanticWorkResult(await coreOperations.rename({ workspaceId: executionWorkspaceId, path, newPath }, executionContext), target);
|
|
271
|
+
});
|
|
272
|
+
registerAppTool(server, toolNames.delete, {
|
|
273
|
+
title: "Delete path",
|
|
274
|
+
description: toolDescriptions.delete,
|
|
275
|
+
inputSchema: {
|
|
276
|
+
workspaceId: z.string().describe("Workspace identifier returned by open_workspace."),
|
|
277
|
+
member: z.string().optional().describe("Required for a Composite Workspace; explicit member name that owns this operation."),
|
|
278
|
+
path: z.string().optional().describe("One file or directory path to delete. Use exactly one of path or paths."),
|
|
279
|
+
paths: z
|
|
280
|
+
.array(z.string())
|
|
281
|
+
.min(1)
|
|
282
|
+
.max(100)
|
|
283
|
+
.optional()
|
|
284
|
+
.describe("Multiple paths to delete in one call. Use exactly one of path or paths."),
|
|
285
|
+
recursive: z.boolean().optional().describe("Delete non-empty directory trees. Defaults to false and applies to every bulk target."),
|
|
286
|
+
},
|
|
287
|
+
outputSchema: resultOutputSchema({
|
|
288
|
+
status: z.enum(["deleted", "partial"]),
|
|
289
|
+
path: z.string().optional(),
|
|
290
|
+
recursive: z.boolean().optional(),
|
|
291
|
+
results: z.array(z.object({
|
|
292
|
+
path: z.string(),
|
|
293
|
+
status: z.enum(["done", "error", "unexecuted"]),
|
|
294
|
+
result: z.string().optional(),
|
|
295
|
+
})).optional(),
|
|
296
|
+
paths: z.number().int().nonnegative().optional(),
|
|
297
|
+
completed: z.number().int().nonnegative().optional(),
|
|
298
|
+
failed: z.number().int().nonnegative().optional(),
|
|
299
|
+
unexecuted: z.number().int().nonnegative().optional(),
|
|
300
|
+
}),
|
|
301
|
+
_meta: {},
|
|
302
|
+
annotations: EDIT_TOOL_ANNOTATIONS,
|
|
303
|
+
}, async ({ workspaceId, member, path, paths, recursive }, extra) => {
|
|
304
|
+
if ((path === undefined) === (paths === undefined)) {
|
|
305
|
+
throw new Error("delete requires exactly one of path or paths.");
|
|
306
|
+
}
|
|
307
|
+
const target = resolveExecutionTarget(workspaceId, member);
|
|
308
|
+
const executionWorkspaceId = target.executionWorkspaceId;
|
|
309
|
+
const executionContext = await prepareExecutionContext(target, extra._meta, extra.signal, extra.sessionId);
|
|
310
|
+
if (remoteWorkspaces.has(executionWorkspaceId)) {
|
|
311
|
+
return presentSemanticWorkResult(await remoteWorkspaces.delete(executionWorkspaceId, { path, paths, recursive }, hostScopeIdFor(extra._meta, extra.sessionId)), target);
|
|
312
|
+
}
|
|
313
|
+
if (path !== undefined) {
|
|
314
|
+
return presentSemanticWorkResult(await coreOperations.delete({ workspaceId: executionWorkspaceId, path, recursive }, executionContext), target);
|
|
315
|
+
}
|
|
316
|
+
return presentSemanticWorkResult(await nativeBulkMutations.delete({ workspaceId: executionWorkspaceId, paths: paths, recursive }, executionContext), target);
|
|
317
|
+
});
|
|
318
|
+
if (config.toolMode === "codex") {
|
|
319
|
+
registerAppTool(server, "apply_patch", {
|
|
320
|
+
title: "Apply patch",
|
|
321
|
+
description: toolDescriptions.applyPatch,
|
|
322
|
+
inputSchema: {
|
|
323
|
+
workspaceId: z
|
|
324
|
+
.string()
|
|
325
|
+
.describe("Workspace identifier returned by open_workspace."),
|
|
326
|
+
member: z.string().optional().describe("Required for a Composite Workspace; explicit member name that owns this patch."),
|
|
327
|
+
patch: z
|
|
328
|
+
.string()
|
|
329
|
+
.describe("Patch text enclosed by *** Begin Patch and *** End Patch markers."),
|
|
330
|
+
},
|
|
331
|
+
outputSchema: resultOutputSchema({
|
|
332
|
+
additions: z.number(),
|
|
333
|
+
removals: z.number(),
|
|
334
|
+
files: z.array(z.object({
|
|
335
|
+
path: z.string(),
|
|
336
|
+
previousPath: z.string().optional(),
|
|
337
|
+
operation: z.enum(["add", "update", "delete", "move"]),
|
|
338
|
+
})),
|
|
339
|
+
}),
|
|
340
|
+
_meta: {},
|
|
341
|
+
annotations: EDIT_TOOL_ANNOTATIONS,
|
|
342
|
+
}, async ({ workspaceId, member, patch }, extra) => {
|
|
343
|
+
const target = resolveExecutionTarget(workspaceId, member);
|
|
344
|
+
const executionWorkspaceId = target.executionWorkspaceId;
|
|
345
|
+
const executionContext = await prepareExecutionContext(target, extra._meta, extra.signal, extra.sessionId);
|
|
346
|
+
if (remoteWorkspaces.has(executionWorkspaceId)) {
|
|
347
|
+
return presentSemanticWorkResult(await remoteWorkspaces.applyPatch(executionWorkspaceId, { patch }, hostScopeIdFor(extra._meta, extra.sessionId)), target);
|
|
348
|
+
}
|
|
349
|
+
const workspace = workspaces.getWorkspace(executionWorkspaceId);
|
|
350
|
+
return runActivityToolWithHooks(activityLifecycle, hooks, workspace, hostScopeIdFor(extra._meta, extra.sessionId), activityRequestFor({ workspaceId: executionWorkspaceId, patch }, executionContext), {
|
|
351
|
+
signal: extra.signal,
|
|
352
|
+
tool: "apply_patch",
|
|
353
|
+
invocation: workspaceHookInvocation(workspace),
|
|
354
|
+
payload: { patchBytes: Buffer.byteLength(patch) },
|
|
355
|
+
changedPaths: (response) => Array.from(new Set(response.structuredContent.files.flatMap((file) => [file.previousPath, file.path])
|
|
356
|
+
.filter((path) => Boolean(path)))),
|
|
357
|
+
operation: async () => {
|
|
358
|
+
const startedAt = performance.now();
|
|
359
|
+
const applied = await applyPatch(workspace.root, patch, [tmpdir()]);
|
|
360
|
+
const paths = applied.files.map((file) => file.path).join(", ");
|
|
361
|
+
const result = `Applied patch to ${applied.files.length} file(s): ${paths}`;
|
|
362
|
+
const content = [textBlock(result)];
|
|
363
|
+
const displayPath = applied.files.length === 1
|
|
364
|
+
? applied.files[0]?.path
|
|
365
|
+
: `${applied.files.length} files`;
|
|
366
|
+
logToolCall(config, {
|
|
367
|
+
tool: "apply_patch",
|
|
368
|
+
...workspaceLogContext(workspace, extra.sessionId),
|
|
369
|
+
path: displayPath,
|
|
370
|
+
success: true,
|
|
371
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
372
|
+
});
|
|
373
|
+
return {
|
|
374
|
+
content,
|
|
375
|
+
_meta: {
|
|
376
|
+
tool: "apply_patch",
|
|
377
|
+
card: {
|
|
378
|
+
workspaceId: executionWorkspaceId,
|
|
379
|
+
path: displayPath,
|
|
380
|
+
summary: {
|
|
381
|
+
files: applied.files.length,
|
|
382
|
+
additions: applied.additions,
|
|
383
|
+
removals: applied.removals,
|
|
384
|
+
},
|
|
385
|
+
files: applied.files,
|
|
386
|
+
payload: { patch: applied.patch },
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
structuredContent: {
|
|
390
|
+
result,
|
|
391
|
+
additions: applied.additions,
|
|
392
|
+
removals: applied.removals,
|
|
393
|
+
files: applied.files,
|
|
394
|
+
},
|
|
395
|
+
};
|
|
396
|
+
},
|
|
397
|
+
}, activityRelationFor(executionContext)).then((result) => presentSemanticWorkResult(result, target));
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
}
|