@moretea-labs/forge 1.5.0-rc.1 → 1.5.1
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/AGENTS.md +9 -11
- package/CHANGELOG.md +27 -1
- package/CLAUDE.md +8 -10
- package/DESIGN.md +278 -0
- package/README.md +70 -90
- package/README.zh-CN.md +52 -55
- package/SKILL.md +8 -11
- package/THIRD_PARTY_NOTICES.md +9 -3
- package/assets/branding/README.md +4 -2
- package/assets/hooks/lib/workflow-state.sh +19 -18
- package/assets/hooks/post-edit-guard.sh +6 -75
- package/assets/hooks/prompt-guard.sh +24 -12
- package/assets/hooks/session-start-context.sh +17 -17
- package/assets/hooks/stop-orchestrator.sh +2 -2
- package/assets/partials/04-project-structure.partial.md +6 -6
- package/assets/partials/05-workflow.partial.md +6 -6
- package/assets/partials/07-footer.partial.md +1 -1
- package/assets/partials/08-orchestration.partial.md +2 -2
- package/assets/partials-agents/02-operating-mode.partial.md +5 -5
- package/assets/partials-agents/03-orchestration.partial.md +3 -3
- package/assets/partials-agents/04-task-protocol.partial.md +3 -3
- package/assets/partials-agents/08-deep-docs.partial.md +1 -1
- package/assets/reference-configs/agentic-development-flow.md +49 -86
- package/assets/reference-configs/external-tooling.md +21 -61
- package/assets/reference-configs/handoff-protocol.md +25 -20
- package/assets/reference-configs/harness-overview.md +8 -8
- package/assets/skill-version.json +2 -2
- package/assets/templates/helpers/archive-workflow.sh +0 -1
- package/assets/templates/helpers/capture-plan.sh +3 -3
- package/assets/templates/helpers/check-task-workflow.sh +2 -2
- package/assets/templates/helpers/codex-handoff-resume.sh +5 -5
- package/assets/templates/helpers/ensure-task-workflow.sh +37 -35
- package/assets/templates/helpers/new-plan.sh +1 -1
- package/assets/templates/helpers/plan-to-todo.sh +2 -2
- package/assets/templates/helpers/prepare-codex-handoff.sh +2 -2
- package/assets/templates/helpers/prepare-handoff.sh +9 -9
- package/assets/templates/helpers/refresh-current-status.sh +2 -2
- package/assets/templates/helpers/ship-worktrees.sh +1 -1
- package/assets/templates/helpers/sprint-backlog.sh +1 -1
- package/assets/templates/helpers/verify-sprint.sh +7 -7
- package/assets/templates/helpers/workstream-sync.sh +1 -1
- package/assets/templates/plan.template.md +1 -1
- package/assets/workflow-contract.v1.json +6 -3
- package/docs/architecture/current/README.md +10 -9
- package/docs/architecture/current/approved-target-architecture.zh-CN.md +2 -2
- package/docs/architecture/current/architecture-invariants.md +2 -2
- package/docs/architecture/current/automation-and-schedule-engine.md +15 -15
- package/docs/architecture/current/codegraph-context-provider.md +2 -2
- package/docs/architecture/current/control-plane-authority-inventory.md +12 -0
- package/docs/architecture/current/dispatch-and-agent-strategy.md +11 -11
- package/docs/architecture/current/entity-model.md +0 -27
- package/docs/architecture/current/failure-recovery.md +0 -24
- package/docs/architecture/current/governance.md +1 -1
- package/docs/architecture/current/implementation-status.md +1 -1
- package/docs/architecture/current/legacy-governance.md +58 -0
- package/docs/architecture/current/multi-repository-execution.md +1 -1
- package/docs/architecture/current/peer-supercontroller-runtime.md +1 -1
- package/docs/architecture/current/personal-assistant-plugin-baseline.md +4 -5
- package/docs/architecture/current/scheduler-and-resource-claims.md +0 -10
- package/docs/architecture/current/target-requirements-traceability.md +2 -2
- package/docs/architecture/current/thin-harness-governance-policy.md +1 -1
- package/docs/architecture/current/thin-harness-v1.md +9 -11
- package/docs/architecture/domains/runtime-harness.md +1 -1
- package/docs/forge-autonomous-goal-loop.md +3 -1
- package/docs/forge-chatgpt-mcp-setup.md +67 -176
- package/docs/images/forge-banner-cn.svg +26 -1
- package/docs/images/forge-banner.svg +26 -1
- package/docs/operations/features.md +1 -1
- package/docs/operations/homebrew.md +3 -3
- package/docs/operations/mcp-tool-exposure.md +5 -5
- package/docs/operations/platform-support.md +45 -37
- package/docs/operations/platform-support.zh-CN.md +40 -38
- package/docs/operations/releasing.md +3 -3
- package/docs/operations/releasing.zh-CN.md +3 -3
- package/docs/operations/troubleshooting.md +11 -6
- package/docs/operations/troubleshooting.zh-CN.md +11 -6
- package/docs/public-usage-guide.md +28 -21
- package/docs/public-usage-guide.zh-CN.md +28 -21
- package/docs/tutorials/01-install-and-start.md +58 -35
- package/docs/tutorials/01-install-and-start.zh-CN.md +58 -35
- package/docs/tutorials/02-connect-chatgpt.md +118 -46
- package/docs/tutorials/02-connect-chatgpt.zh-CN.md +119 -45
- package/docs/wiki/Architecture.md +1 -1
- package/docs/wiki/Installation.md +2 -2
- package/docs/wiki/Quick-Start.md +1 -1
- package/docs/wiki/Work-Lifecycle.md +1 -1
- package/install.ps1 +4 -5
- package/install.sh +4 -6
- package/package.json +15 -5
- package/scripts/archive-workflow.sh +0 -1
- package/scripts/benchmark-thin-harness-mcp-e2e.ts +27 -14
- package/scripts/build-controller-ui.ts +28 -0
- package/scripts/capture-plan.sh +4 -4
- package/scripts/check-agent-tooling.sh +12 -1
- package/scripts/check-platform-support.mjs +2 -2
- package/scripts/check-public-docs.sh +16 -5
- package/scripts/check-release-readiness.sh +5 -11
- package/scripts/check-runtime-architecture.mjs +14 -22
- package/scripts/check-tarball-install-smoke.sh +3 -2
- package/scripts/check-task-workflow.sh +2 -2
- package/scripts/codex-handoff-resume.sh +5 -5
- package/scripts/create-project-dirs.sh +3 -3
- package/scripts/ensure-task-workflow.sh +45 -35
- package/scripts/init-project.sh +4 -4
- package/scripts/install-desktop-operator-registration.ts +2 -2
- package/scripts/lib/project-init-lib.sh +46 -44
- package/scripts/migrate-project-template.sh +7 -4
- package/scripts/new-plan.sh +1 -1
- package/scripts/plan-to-todo.sh +2 -2
- package/scripts/prepare-codex-handoff.sh +2 -2
- package/scripts/prepare-handoff.sh +9 -9
- package/scripts/refresh-current-status.sh +2 -2
- package/scripts/setup-plugins.sh +3 -3
- package/scripts/ship-worktrees.sh +1 -1
- package/scripts/sprint-backlog.sh +5 -5
- package/scripts/sync-codex-installed-copies.sh +2 -3
- package/scripts/verify-sprint.sh +7 -7
- package/scripts/workstream-sync.sh +1 -1
- package/src/cli/chatgpt-browser/bridge-extension.ts +1 -1
- package/src/cli/chatgpt-browser/bridge-provider.ts +29 -0
- package/src/cli/chatgpt-browser/file-policy.ts +3 -1
- package/src/cli/commands/chatgpt.ts +51 -0
- package/src/cli/commands/doctor.ts +1 -1
- package/src/cli/commands/init-hook.ts +213 -70
- package/src/cli/commands/init.ts +5 -6
- package/src/cli/commands/mcp.ts +31 -5
- package/src/cli/commands/runtime.ts +61 -8
- package/src/cli/commands/setup-profile.ts +472 -0
- package/src/cli/controller/check-runner.ts +20 -3
- package/src/cli/controller/codex-continuation.ts +4 -7
- package/src/cli/controller/context-pack.ts +118 -14
- package/src/cli/controller/operational-plan.ts +4 -4
- package/src/cli/controller/task-ledger.ts +10 -10
- package/src/cli/controller/work-mode.ts +6 -13
- package/src/cli/index.ts +14 -35
- package/src/cli/local-bridge/connector-freshness.ts +1 -1
- package/src/cli/local-bridge/console-assets.ts +17 -0
- package/src/cli/local-bridge/console-automations.ts +160 -0
- package/src/cli/local-bridge/dashboard.ts +8 -1303
- package/src/cli/local-bridge/facade-api.ts +16 -7
- package/src/cli/local-bridge/frontend/src/App.tsx +10 -0
- package/src/cli/local-bridge/frontend/src/components/Button.tsx +1 -0
- package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +3 -0
- package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +1 -0
- package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +1 -0
- package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +1 -0
- package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +3 -0
- package/src/cli/local-bridge/frontend/src/design/icons.tsx +11 -0
- package/src/cli/local-bridge/frontend/src/design/tokens.css +8 -0
- package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +3 -0
- package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +4 -0
- package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +3 -0
- package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +2 -0
- package/src/cli/local-bridge/frontend/src/features/settings/SettingsView.tsx +2 -0
- package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +2 -0
- package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +3 -0
- package/src/cli/local-bridge/frontend/src/lib/api.ts +23 -0
- package/src/cli/local-bridge/frontend/src/lib/format.ts +4 -0
- package/src/cli/local-bridge/frontend/src/lib/routes.ts +7 -0
- package/src/cli/local-bridge/frontend/src/main.tsx +1 -0
- package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +1 -0
- package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +2 -0
- package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +3 -0
- package/src/cli/local-bridge/frontend/src/styles.css +12 -0
- package/src/cli/local-bridge/frontend/src/types.ts +14 -0
- package/src/cli/local-bridge/frontend/src/vite-env.d.ts +1 -0
- package/src/cli/local-bridge/frontend/vite.config.ts +27 -0
- package/src/cli/local-bridge/server.ts +45 -0
- package/src/cli/local-bridge/ui-dist/app.css +1 -0
- package/src/cli/local-bridge/ui-dist/app.js +11094 -0
- package/src/cli/mcp/auth.ts +2 -0
- package/src/cli/mcp/instructions.ts +3 -3
- package/src/cli/mcp/legacy-tool-service.ts +27 -23
- package/src/cli/mcp/multi-repository.ts +2 -0
- package/src/cli/mcp/policy.ts +7 -5
- package/src/cli/mcp/repository-tools.ts +53 -14
- package/src/cli/mcp/server.ts +5 -10
- package/src/cli/mcp/setup.ts +220 -276
- package/src/cli/mcp/tool-capability-cache.ts +1 -1
- package/src/cli/mcp/toolset-names.ts +1 -1
- package/src/cli/mcp/toolset.ts +0 -1
- package/src/cli/mcp/transports/http.ts +51 -4
- package/src/cli/repositories/branch-name-policy.ts +0 -7
- package/src/cli/repositories/controller-home.ts +110 -3
- package/src/cli/repositories/safe-patch.ts +1 -1
- package/src/cli/repositories/selected-path-actions.ts +26 -24
- package/src/core/adoption/gitignore-plan.ts +2 -3
- package/src/core/adoption/plan.ts +4 -1
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +556 -0
- package/src/runtime/control-plane/execution/work-handle-store.ts +128 -1
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +277 -0
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +169 -0
- package/src/runtime/control-plane/facade/capability-registry.ts +0 -10
- package/src/runtime/control-plane/facade/handoff-inbox-store.ts +44 -25
- package/src/runtime/control-plane/facade/suggested-actions.ts +7 -1
- package/src/runtime/control-plane/facade/types.ts +0 -1
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +30 -8
- package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +114 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +175 -0
- package/src/runtime/control-plane/launcher/launch-reservation-store.ts +161 -0
- package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +64 -0
- package/src/runtime/control-plane/launcher/thin-launcher.ts +117 -24
- package/src/runtime/control-plane/routing/route-policy.ts +14 -14
- package/src/runtime/control-plane/runtime-cleanup.ts +0 -1
- package/src/runtime/evidence/event-ledger.ts +1 -1
- package/src/runtime/{workflow/campaigns/workspace.ts → execution/managed-workspace.ts} +41 -43
- package/src/runtime/execution/process-runtime/check-facade.ts +6 -0
- package/src/runtime/execution/process-runtime/check-result.ts +45 -0
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +42 -16
- package/src/runtime/execution/process-runtime/command-facade.ts +4 -2
- package/src/runtime/execution/process-runtime/gc.ts +1 -1
- package/src/runtime/execution/process-runtime/index.ts +3 -0
- package/src/runtime/execution/process-runtime/interactive-admission.ts +14 -5
- package/src/runtime/execution/process-runtime/persisted-check.ts +285 -0
- package/src/runtime/execution/process-runtime/resource-claims.ts +30 -0
- package/src/runtime/execution/process-runtime/runtime.ts +18 -1
- package/src/runtime/execution/process-runtime/store.ts +1 -19
- package/src/runtime/execution/process-runtime/types.ts +4 -0
- package/src/runtime/execution/thin-harness/execution-router.ts +0 -1
- package/src/runtime/execution/thin-harness/fast-executor.ts +1 -1
- package/src/runtime/execution/thin-harness/lightweight-lanes.ts +1 -2
- package/src/runtime/execution/thin-harness/types.ts +0 -1
- package/src/runtime/execution/workers/executor.ts +1 -1
- package/src/runtime/gateway/mcp/execution-tools.ts +1 -1
- package/src/runtime/gateway/mcp/persisted-check-process.ts +3 -255
- package/src/runtime/gateway/mcp/process-tools.ts +16 -3
- package/src/runtime/gateway/mcp/resource-policy.ts +0 -9
- package/src/runtime/gateway/mcp/router.ts +117 -182
- package/src/runtime/gateway/mcp/runtime-tools.ts +331 -409
- package/src/runtime/gateway/mcp/work-validation-reconciler.ts +1 -219
- package/src/runtime/plugins/browser-adapter.ts +5 -0
- package/src/runtime/plugins/desktop-operator-registration.ts +1 -1
- package/src/runtime/plugins/store.ts +14 -6
- package/src/runtime/plugins/types.ts +1 -1
- package/src/runtime/projections/materialized-view.ts +1 -23
- package/src/runtime/recovery/maintenance-executor.ts +9 -0
- package/src/runtime/resources/ownership.ts +0 -1
- package/src/runtime/root/gateway-adapter.ts +2 -0
- package/src/runtime/root/mcp-transport.ts +10 -2
- package/src/runtime/root/package-connector-service.ts +136 -0
- package/src/runtime/root/package-runtime-release.ts +161 -0
- package/src/runtime/root/package-runtime-service.ts +185 -0
- package/src/runtime/root/release-materialize.ts +19 -0
- package/src/runtime/root/runtime.ts +2 -1
- package/src/runtime/root/scheduler.ts +5 -0
- package/src/runtime/root/service.ts +18 -5
- package/src/runtime/standalone-recovery/core.ts +65 -16
- package/src/runtime/workflow/findings/store.ts +145 -106
- package/src/runtime/workflow/findings/types.ts +22 -0
- package/src/runtime/workflow/schedules/engine.ts +132 -2
- package/src/runtime/workflow/schedules/pending-activation.ts +139 -0
- package/src/runtime/workflow/schedules/work-continuation.ts +218 -0
- package/docs/CHANGELOG.md +0 -978
- package/docs/README.zh-CN.md +0 -58
- package/scripts/smoke-chatgpt-supervised-automation.ts +0 -208
- package/src/cli/commands/controller.ts +0 -680
- package/src/runtime/workflow/campaigns/cleanup.ts +0 -263
- package/src/runtime/workflow/campaigns/engine.ts +0 -112
- package/src/runtime/workflow/campaigns/normalize.ts +0 -100
- package/src/runtime/workflow/campaigns/review.ts +0 -315
- package/src/runtime/workflow/campaigns/store.ts +0 -526
- package/src/runtime/workflow/campaigns/supervisor.ts +0 -112
- package/src/runtime/workflow/campaigns/types.ts +0 -290
- /package/src/runtime/{workflow/campaigns → execution}/workspace-agent.ts +0 -0
package/src/cli/mcp/auth.ts
CHANGED
|
@@ -21,6 +21,8 @@ export interface McpLocalConfig {
|
|
|
21
21
|
chatgpt?: {
|
|
22
22
|
serverName?: string;
|
|
23
23
|
endpoint?: string;
|
|
24
|
+
/** Loopback OAuth MCP endpoint used by ChatGPT tunnels/connectors. */
|
|
25
|
+
localEndpoint?: string;
|
|
24
26
|
};
|
|
25
27
|
profile?: string;
|
|
26
28
|
toolset?: 'core' | 'advanced' | 'full';
|
|
@@ -10,11 +10,11 @@ export function mcpServerInstructions(profile: McpProfileName): string {
|
|
|
10
10
|
return [
|
|
11
11
|
...common,
|
|
12
12
|
'Use the shortest valid execution path. Investigation or parallelism alone must not create durable Work, Issues, Plans, Agents, isolation, or worktrees; escalate only for actual recovery, dependency, risk, scope, external-effect, or long-running requirements.',
|
|
13
|
-
'For bounded
|
|
13
|
+
'For bounded implementation, use rh_context(operation=search, retrieval_mode=implementation) once as the default code retrieval router when the exact path is unknown. Its current raw snippets and file SHA identities are valid implementation evidence; ChatGPT decides semantic sufficiency and should request wider exact ranges only when impact ambiguity, truncation, drift, or an expansion signal can materially change the edit. For cross-cutting state/time/schema/cache/API/event/concurrency changes, ChatGPT should select relevant impact_domains in that first search so Forge expands those evidence dimensions mechanically in the same call; Forge never infers that the selected domains are semantically complete. Use retrieval_mode=plan|debug|review when the task intentionally needs a broader evidence surface. Do not fall back to shell grep unless retrieval is unavailable or raw Git semantics are explicitly needed. The low-level search_repository handler is compatibility/internal surface, not a second default search path. Prefer repository_command_execute for ordinary local Git and shell operations, repository_safe_patch_apply for bounded source changes, and rh_work only when the task genuinely requires durable orchestration.',
|
|
14
14
|
'Do not preflight unrelated Git history, prior Work, plugins, permissions, TCC, browser mode, maintenance, or recovery state. Inspect them only when the requested operation depends on them or a real failure points there.',
|
|
15
15
|
'Run independent reads, searches, diagnostics, checks, repositories, checkouts, and tasks concurrently by default. Serialize only on a real dependency or Resource Claim conflict, and reuse existing projections, process handles, and check evidence instead of repeating successful observations.',
|
|
16
|
-
'Validation must be proportional to the change:
|
|
17
|
-
'After a bounded successful change, finish the requested delivery directly. Avoid additional investigation whose result cannot change implementation or acceptance, and do not invoke hidden atomic compatibility tools merely because they exist in the full profile.',
|
|
16
|
+
'Validation must be proportional to the change: cheap patch-safety checks belong to every coherent edit batch, focused tests run after that batch is stable, and expensive full-suite checks belong at candidate/release or explicitly high-risk boundaries. When a Direct Edit batch is stable, repository_safe_patch_apply may receive explicit check_ids to start revision-bound validation; omit check_ids during intermediate edits. Long checks return managed Processes: continue independent read/review work, then use validation_only with the returned edit-session/validation ids as the synchronization join instead of polling repeatedly. Do not perform maintenance or deep runtime diagnosis before ordinary work unless execution is actually blocked.',
|
|
17
|
+
'repository_safe_patch_apply returns bounded edit-session diff evidence for semantic review. Review that evidence directly instead of issuing a mandatory follow-up diff/status call; expand it only when truncated or semantically ambiguous. After a bounded successful change, finish the requested delivery directly. Avoid additional investigation whose result cannot change implementation or acceptance, and do not invoke hidden atomic compatibility tools merely because they exist in the full profile.',
|
|
18
18
|
].join(' ');
|
|
19
19
|
}
|
|
20
20
|
if (profile === 'orchestrator') {
|
|
@@ -164,6 +164,8 @@ export interface McpToolContext {
|
|
|
164
164
|
sessionId?: string;
|
|
165
165
|
/** Authenticated or controller-issued principal used to scope session state. */
|
|
166
166
|
principalId?: string;
|
|
167
|
+
/** Authenticated transport controller/provider type. */
|
|
168
|
+
controllerType?: 'chatgpt' | 'codex' | 'claude' | 'grok' | 'human';
|
|
167
169
|
controllerInstanceId?: string;
|
|
168
170
|
/** Bound repository identity for session cache keys. */
|
|
169
171
|
repoId?: string;
|
|
@@ -790,7 +792,9 @@ function workflowFileCandidates(repoRoot: string): string[] {
|
|
|
790
792
|
"plans",
|
|
791
793
|
"tasks",
|
|
792
794
|
".ai/context",
|
|
793
|
-
".ai/harness/
|
|
795
|
+
".ai/harness/session",
|
|
796
|
+
".ai/harness/controller/packets",
|
|
797
|
+
".ai/harness/projections",
|
|
794
798
|
".ai/harness/checks",
|
|
795
799
|
];
|
|
796
800
|
const files: string[] = [];
|
|
@@ -1466,8 +1470,8 @@ export function buildMcpToolDefinitions(
|
|
|
1466
1470
|
annotations: readOnly,
|
|
1467
1471
|
},
|
|
1468
1472
|
{
|
|
1469
|
-
name: "
|
|
1470
|
-
description: "Return latest
|
|
1473
|
+
name: "latest_session_context",
|
|
1474
|
+
description: "Return the latest rebuildable Forge session continuation context.",
|
|
1471
1475
|
inputSchema: EMPTY_SCHEMA,
|
|
1472
1476
|
annotations: readOnly,
|
|
1473
1477
|
},
|
|
@@ -1530,14 +1534,14 @@ export function buildMcpToolDefinitions(
|
|
|
1530
1534
|
{
|
|
1531
1535
|
name: "prepare_codex_goal_from_sprint",
|
|
1532
1536
|
description:
|
|
1533
|
-
"Prepare .ai/harness/
|
|
1537
|
+
"Prepare .ai/harness/controller/packets/codex-goal.md and a host-native /goal prompt from PRD + checklist Sprint.",
|
|
1534
1538
|
inputSchema: goalFromSprintSchema,
|
|
1535
1539
|
annotations: write,
|
|
1536
1540
|
},
|
|
1537
1541
|
{
|
|
1538
1542
|
name: "write_codex_goal",
|
|
1539
1543
|
description:
|
|
1540
|
-
"Write .ai/harness/
|
|
1544
|
+
"Write .ai/harness/controller/packets/codex-goal.md after required section validation.",
|
|
1541
1545
|
inputSchema: {
|
|
1542
1546
|
type: "object",
|
|
1543
1547
|
properties: {
|
|
@@ -1550,8 +1554,8 @@ export function buildMcpToolDefinitions(
|
|
|
1550
1554
|
annotations: write,
|
|
1551
1555
|
},
|
|
1552
1556
|
{
|
|
1553
|
-
name: "
|
|
1554
|
-
description: "Append a timestamped
|
|
1557
|
+
name: "append_controller_plan_note",
|
|
1558
|
+
description: "Append a timestamped ChatGPT planning note to the controller packet cache.",
|
|
1555
1559
|
inputSchema: {
|
|
1556
1560
|
type: "object",
|
|
1557
1561
|
properties: { actor: { type: "string" }, body: { type: "string" } },
|
|
@@ -1616,7 +1620,7 @@ export function buildMcpToolDefinitions(
|
|
|
1616
1620
|
type: "object",
|
|
1617
1621
|
properties: {
|
|
1618
1622
|
description: { type: "string" },
|
|
1619
|
-
mode: { type: "string", enum: ["direct", "plan", "debug", "review", "
|
|
1623
|
+
mode: { type: "string", enum: ["direct", "plan", "debug", "review", "release", "scale", "-direct", "-plan", "-debug", "-review", "-release", "-scale"] },
|
|
1620
1624
|
known_paths: { type: "array", items: { type: "string" } },
|
|
1621
1625
|
expected_files: { type: "number" },
|
|
1622
1626
|
expected_changed_lines: { type: "number" },
|
|
@@ -2147,7 +2151,7 @@ export function buildMcpToolDefinitions(
|
|
|
2147
2151
|
type: "object",
|
|
2148
2152
|
properties: {
|
|
2149
2153
|
description: { type: "string" },
|
|
2150
|
-
mode: { type: "string", enum: ["direct", "plan", "debug", "review", "
|
|
2154
|
+
mode: { type: "string", enum: ["direct", "plan", "debug", "review", "release", "scale", "-direct", "-plan", "-debug", "-review", "-release", "-scale"] },
|
|
2151
2155
|
known_paths: { type: "array", items: { type: "string" } },
|
|
2152
2156
|
expected_files: { type: "number" },
|
|
2153
2157
|
expected_changed_lines: { type: "number" },
|
|
@@ -2996,7 +3000,9 @@ export async function callMcpTool(
|
|
|
2996
3000
|
"docs/spec.md",
|
|
2997
3001
|
"plans",
|
|
2998
3002
|
"tasks/current.md",
|
|
2999
|
-
".ai/harness/
|
|
3003
|
+
".ai/harness/session",
|
|
3004
|
+
".ai/harness/controller/packets",
|
|
3005
|
+
".ai/harness/projections",
|
|
3000
3006
|
".ai/harness/checks",
|
|
3001
3007
|
];
|
|
3002
3008
|
audit(ctx, name, "ok", args);
|
|
@@ -3174,7 +3180,7 @@ export async function callMcpTool(
|
|
|
3174
3180
|
},
|
|
3175
3181
|
toolExposure: {
|
|
3176
3182
|
preferred: preferredTools,
|
|
3177
|
-
note: "Prefer the five rh_* workflow facades for orchestration. Typed repository, Git, Issue/Task,
|
|
3183
|
+
note: "Prefer the five rh_* workflow facades for orchestration. Typed repository, Git, Issue/Task, plugin, browser, iOS, artifact, and recovery tools remain available because the current MCP transport cannot load domain schemas per conversation.",
|
|
3178
3184
|
advanced: expectedTools.filter((tool) => !preferredTools.includes(tool)).slice(0, 40),
|
|
3179
3185
|
compatibilityRetained: true,
|
|
3180
3186
|
},
|
|
@@ -5055,12 +5061,10 @@ export async function callMcpTool(
|
|
|
5055
5061
|
redactions: payload.redactions,
|
|
5056
5062
|
});
|
|
5057
5063
|
}
|
|
5058
|
-
case "
|
|
5064
|
+
case "latest_session_context": {
|
|
5059
5065
|
const paths = [
|
|
5060
|
-
".ai/harness/
|
|
5061
|
-
".ai/harness/
|
|
5062
|
-
".ai/harness/handoff/codex-goal.md",
|
|
5063
|
-
".ai/harness/handoff/chatgpt-plan.md",
|
|
5066
|
+
".ai/harness/session/resume.md",
|
|
5067
|
+
".ai/harness/session/continuation.md",
|
|
5064
5068
|
];
|
|
5065
5069
|
const handoff = paths.map((path) => {
|
|
5066
5070
|
const decision = resolveMcpPath(
|
|
@@ -5085,7 +5089,7 @@ export async function callMcpTool(
|
|
|
5085
5089
|
};
|
|
5086
5090
|
});
|
|
5087
5091
|
audit(ctx, name, "ok", args);
|
|
5088
|
-
return textResult({ handoff });
|
|
5092
|
+
return textResult({ sessionContext: handoff });
|
|
5089
5093
|
}
|
|
5090
5094
|
case "latest_checks": {
|
|
5091
5095
|
const files = workflowFileCandidates(ctx.repoRoot)
|
|
@@ -5269,7 +5273,7 @@ export async function callMcpTool(
|
|
|
5269
5273
|
name,
|
|
5270
5274
|
"blocked",
|
|
5271
5275
|
args,
|
|
5272
|
-
".ai/harness/
|
|
5276
|
+
".ai/harness/controller/packets/codex-goal.md",
|
|
5273
5277
|
`missing required goal sections: ${missing.join(", ")}`,
|
|
5274
5278
|
);
|
|
5275
5279
|
return errorResult(
|
|
@@ -5281,7 +5285,7 @@ export async function callMcpTool(
|
|
|
5281
5285
|
return writeMarkdownArtifact(
|
|
5282
5286
|
ctx,
|
|
5283
5287
|
name,
|
|
5284
|
-
".ai/harness/
|
|
5288
|
+
".ai/harness/controller/packets/codex-goal.md",
|
|
5285
5289
|
"Codex Goal",
|
|
5286
5290
|
"codex-goal",
|
|
5287
5291
|
goal.body,
|
|
@@ -5301,7 +5305,7 @@ export async function callMcpTool(
|
|
|
5301
5305
|
name,
|
|
5302
5306
|
"blocked",
|
|
5303
5307
|
args,
|
|
5304
|
-
".ai/harness/
|
|
5308
|
+
".ai/harness/controller/packets/codex-goal.md",
|
|
5305
5309
|
`missing required goal sections: ${missing.join(", ")}`,
|
|
5306
5310
|
);
|
|
5307
5311
|
return errorResult(
|
|
@@ -5313,7 +5317,7 @@ export async function callMcpTool(
|
|
|
5313
5317
|
return writeMarkdownArtifact(
|
|
5314
5318
|
ctx,
|
|
5315
5319
|
name,
|
|
5316
|
-
".ai/harness/
|
|
5320
|
+
".ai/harness/controller/packets/codex-goal.md",
|
|
5317
5321
|
"Codex Goal",
|
|
5318
5322
|
"codex-goal",
|
|
5319
5323
|
body,
|
|
@@ -5321,8 +5325,8 @@ export async function callMcpTool(
|
|
|
5321
5325
|
args,
|
|
5322
5326
|
);
|
|
5323
5327
|
}
|
|
5324
|
-
case "
|
|
5325
|
-
const path = ".ai/harness/
|
|
5328
|
+
case "append_controller_plan_note": {
|
|
5329
|
+
const path = ".ai/harness/controller/packets/chatgpt-plan.md";
|
|
5326
5330
|
const decision = resolveMcpPath(
|
|
5327
5331
|
ctx.repoRoot,
|
|
5328
5332
|
path,
|
|
@@ -31,6 +31,7 @@ export interface McpServerOptions {
|
|
|
31
31
|
toolset?: McpToolset | string;
|
|
32
32
|
sessionId?: string;
|
|
33
33
|
principalId?: string;
|
|
34
|
+
controllerType?: McpToolContext['controllerType'];
|
|
34
35
|
controllerInstanceId?: string;
|
|
35
36
|
/** Canonical Runtime source authority. Internal Runtime MCP only; never an execution repository. */
|
|
36
37
|
runtimeSourceRoot?: string;
|
|
@@ -359,6 +360,7 @@ export function createMcpToolContext(opts: McpServerOptions): MultiRepositoryMcp
|
|
|
359
360
|
enableChatgptBrowser: opts.enableChatgptBrowser === true,
|
|
360
361
|
sessionId: opts.sessionId,
|
|
361
362
|
principalId: opts.principalId,
|
|
363
|
+
controllerType: opts.controllerType,
|
|
362
364
|
controllerInstanceId: opts.controllerInstanceId,
|
|
363
365
|
runtimeSourceRoot: opts.runtimeSourceRoot,
|
|
364
366
|
};
|
package/src/cli/mcp/policy.ts
CHANGED
|
@@ -35,7 +35,9 @@ export const PLANNER_READ_GLOBS = [
|
|
|
35
35
|
'tasks/reviews/**',
|
|
36
36
|
'tasks/notes/**',
|
|
37
37
|
'.ai/context/**',
|
|
38
|
-
'.ai/harness/
|
|
38
|
+
'.ai/harness/session/**',
|
|
39
|
+
'.ai/harness/controller/packets/**',
|
|
40
|
+
'.ai/harness/projections/**',
|
|
39
41
|
'.ai/harness/checks/**',
|
|
40
42
|
];
|
|
41
43
|
|
|
@@ -43,8 +45,8 @@ export const PLANNER_WRITE_GLOBS = [
|
|
|
43
45
|
'plans/prds/**',
|
|
44
46
|
'plans/sprints/**',
|
|
45
47
|
'plans/plan-*.md',
|
|
46
|
-
'.ai/harness/
|
|
47
|
-
'.ai/harness/
|
|
48
|
+
'.ai/harness/controller/packets/codex-goal.md',
|
|
49
|
+
'.ai/harness/controller/packets/chatgpt-plan.md',
|
|
48
50
|
];
|
|
49
51
|
|
|
50
52
|
export interface McpPolicyOptions {
|
|
@@ -164,7 +166,7 @@ export function getMcpPolicy(profile: McpProfileName, opts: McpPolicyOptions = {
|
|
|
164
166
|
return applyPolicyOverrides({
|
|
165
167
|
profile,
|
|
166
168
|
readGlobs: ['plans/**', 'tasks/**', 'docs/spec.md', '.ai/context/**', '.ai/harness/**'],
|
|
167
|
-
writeGlobs: ['tasks/reviews/**', '.ai/harness/checks/**', '.ai/harness/
|
|
169
|
+
writeGlobs: ['tasks/reviews/**', '.ai/harness/checks/**', '.ai/harness/session/**', '.ai/harness/controller/packets/**'],
|
|
168
170
|
denyGlobs: COMMON_DENY_GLOBS,
|
|
169
171
|
maxFileBytes: 512 * 1024,
|
|
170
172
|
execution: executionPolicy({
|
|
@@ -207,7 +209,7 @@ export function getMcpPolicy(profile: McpProfileName, opts: McpPolicyOptions = {
|
|
|
207
209
|
const devRunner = opts.devAgentRunner === true;
|
|
208
210
|
return applyPolicyOverrides({
|
|
209
211
|
profile,
|
|
210
|
-
readGlobs: devRunner ? ['.ai/harness/
|
|
212
|
+
readGlobs: devRunner ? ['.ai/harness/controller/packets/codex-goal.md'] : [],
|
|
211
213
|
writeGlobs: [],
|
|
212
214
|
denyGlobs: devRunner ? COMMON_DENY_GLOBS : ['**'],
|
|
213
215
|
maxFileBytes: devRunner ? 512 * 1024 : 0,
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from '../repositories/registry';
|
|
20
20
|
import { buildControllerWorkbench } from '../repositories/workbench';
|
|
21
21
|
import { applySafePatch, buildSafePatchPlan } from '../repositories/safe-patch';
|
|
22
|
+
import { getEditSessionDiff } from '../editing/edit-session';
|
|
22
23
|
import { buildSyncOperationDigest, classifyUserFacingError } from '../../runtime/control-plane/facade/operation-digest';
|
|
23
24
|
import { diagnoseRepositoryStuckState, listRepositoryGoalRuns, readRepositoryGoalRegistry, runRepositoryGoal, upsertRepositoryGoal } from '../repositories/goal-registry';
|
|
24
25
|
import {
|
|
@@ -50,6 +51,7 @@ import {
|
|
|
50
51
|
import { assessWorkMode, parseExplicitTaskMode } from '../controller/work-mode';
|
|
51
52
|
import type { CallToolResult, McpToolDefinition } from './tools';
|
|
52
53
|
import {
|
|
54
|
+
boundUtf8,
|
|
53
55
|
compactCommandOutput,
|
|
54
56
|
compactErrorMessage,
|
|
55
57
|
compactRoutingSummary,
|
|
@@ -136,7 +138,7 @@ export const repositoryToolDefinitions: McpToolDefinition[] = [
|
|
|
136
138
|
operation: {
|
|
137
139
|
type: 'string',
|
|
138
140
|
enum: ['summary', 'batch_execute', 'lanes_execute', 'lanes_integrate', 'fast_receipt_get', 'fast_receipt_list', 'execution_route', 'assess_work_mode'],
|
|
139
|
-
description: 'Defaults to summary. Use batch_execute for multi-step Fast Path (one parent receipt). Use lanes_execute for limited parallel reads. Use assess_work_mode for Fast/Durable
|
|
141
|
+
description: 'Defaults to summary. Use batch_execute for multi-step Fast Path (one parent receipt). Use lanes_execute for limited parallel reads. Use assess_work_mode for Fast/Durable routing advice.',
|
|
140
142
|
},
|
|
141
143
|
payload: {
|
|
142
144
|
type: 'object',
|
|
@@ -235,20 +237,25 @@ export const repositoryToolDefinitions: McpToolDefinition[] = [
|
|
|
235
237
|
operations: { type: 'array', items: { type: 'object' }, description: 'Edit operations using the same shape as apply_patch.' },
|
|
236
238
|
chunk_size: { type: 'number', description: 'Maximum operations per deterministic chunk. Capped at 100.' },
|
|
237
239
|
}, ['operations'], true),
|
|
238
|
-
definition('repository_safe_patch_apply', 'Apply
|
|
240
|
+
definition('repository_safe_patch_apply', 'Apply one coherent deterministic edit batch and return bounded review evidence. Checks are opt-in: pass check_ids only when the batch is stable. Long checks return managed Process handles instead of blocking the MCP call; use validation_only with the returned session/request ids to join later without replaying the patch.', {
|
|
239
241
|
repo_id: repoId,
|
|
240
242
|
checkout_id: { type: 'string', description: 'Optional checkout identity for repositories with multiple local clones.' },
|
|
241
|
-
session_id: { type: 'string', description: 'Existing edit session id.
|
|
243
|
+
session_id: { type: 'string', description: 'Existing edit session id. Required for validation_only; otherwise omit to create one.' },
|
|
242
244
|
purpose: { type: 'string', description: 'Purpose for a newly created edit session.' },
|
|
243
|
-
operations: { type: 'array', items: { type: 'object' }, description: 'Edit operations using the same shape as apply_patch.
|
|
245
|
+
operations: { type: 'array', items: { type: 'object' }, description: 'Edit operations using the same shape as apply_patch. Required unless validation_only=true.' },
|
|
244
246
|
chunk_size: { type: 'number', description: 'Maximum operations per deterministic chunk. Capped at 100.' },
|
|
245
247
|
expected_revision: { type: 'number', description: 'Expected starting edit-session revision.' },
|
|
246
248
|
allowed_paths: { type: 'array', items: { type: 'string' }, description: 'Optional allowed path globs for a newly created session.' },
|
|
247
249
|
continue_on_error: { type: 'boolean', description: 'Continue applying later independent chunks after a failed chunk. Defaults to false.' },
|
|
248
250
|
refresh_fingerprints: { type: 'boolean', description: 'Refresh file fingerprints before every chunk. Defaults to true.' },
|
|
249
251
|
recover_stale_session: { type: 'boolean', description: 'For new sessions, recover stale edit-session fingerprints into a fresh session. Defaults to true.' },
|
|
250
|
-
|
|
251
|
-
|
|
252
|
+
check_ids: { type: 'array', items: { type: 'string' }, description: 'Optional focused validation for this stable coherent edit batch. Omit to edit without running tests.' },
|
|
253
|
+
check_timeout_ms: { type: 'number', description: 'Per-check execution budget. Long checks still return managed handles immediately.' },
|
|
254
|
+
lease_wait_ms: { type: 'number', description: 'Bounded resource-lease wait for conflicting validation lanes.' },
|
|
255
|
+
validation_request_id: { type: 'string', description: 'Stable validation identity returned by a prior edit+validation call; reuse with validation_only to join without replaying edits.' },
|
|
256
|
+
validation_only: { type: 'boolean', description: 'When true, do not edit. Reconcile/reuse the existing session validation Processes identified by session_id/check_ids/validation_request_id.' },
|
|
257
|
+
apply_mode: { type: 'string', enum: ['sync', 'async'], description: 'Defaults to sync for interactive development. Set async only for a separately durable operation.' },
|
|
258
|
+
}),
|
|
252
259
|
definition('repository_command_preview', 'Preview one repository-scoped local command with classification, approval token, and Git snapshots.', {
|
|
253
260
|
repo_id: repoId,
|
|
254
261
|
checkout_id: { type: 'string', description: 'Optional checkout identity for repositories with multiple local clones.' },
|
|
@@ -688,7 +695,6 @@ export async function callRepositoryTool(
|
|
|
688
695
|
reasons: assessment.reasons,
|
|
689
696
|
recommendedMode: assessment.recommendedMode,
|
|
690
697
|
issueRequired: assessment.issueRequired,
|
|
691
|
-
campaignRequired: assessment.campaignRequired,
|
|
692
698
|
},
|
|
693
699
|
nextTools: assessment.nextTools,
|
|
694
700
|
});
|
|
@@ -833,6 +839,27 @@ export async function callRepositoryTool(
|
|
|
833
839
|
];
|
|
834
840
|
const ok = applied.status === 'applied';
|
|
835
841
|
const firstFailure = applied.failures?.[0];
|
|
842
|
+
const editDiff = applied.appliedChunks.length > 0
|
|
843
|
+
? getEditSessionDiff(repository.canonicalRoot, applied.session.sessionId)
|
|
844
|
+
: undefined;
|
|
845
|
+
const boundedEditDiff = editDiff
|
|
846
|
+
? boundUtf8(editDiff.patch, RESPONSE_BUDGET.inlineOutputBytes)
|
|
847
|
+
: undefined;
|
|
848
|
+
const reviewEvidence = editDiff && boundedEditDiff
|
|
849
|
+
? {
|
|
850
|
+
source: 'edit_session' as const,
|
|
851
|
+
sessionId: editDiff.sessionId,
|
|
852
|
+
revision: editDiff.revision,
|
|
853
|
+
sha256: editDiff.sha256,
|
|
854
|
+
patchPreview: boundedEditDiff.text,
|
|
855
|
+
truncated: boundedEditDiff.truncated,
|
|
856
|
+
byteLength: boundedEditDiff.byteLength,
|
|
857
|
+
semanticReviewAuthority: 'chatgpt' as const,
|
|
858
|
+
next: boundedEditDiff.truncated
|
|
859
|
+
? 'The edit diff exceeds the inline budget. Expand only the affected ranges or diff needed for semantic review.'
|
|
860
|
+
: 'Review this exact edit-session diff before deciding whether more edits or focused validation are needed.',
|
|
861
|
+
}
|
|
862
|
+
: undefined;
|
|
836
863
|
const digest = buildSyncOperationDigest({
|
|
837
864
|
ok,
|
|
838
865
|
operation: 'repository_safe_patch_apply',
|
|
@@ -859,6 +886,7 @@ export async function callRepositoryTool(
|
|
|
859
886
|
terminal: true,
|
|
860
887
|
applyMode: 'sync',
|
|
861
888
|
digest,
|
|
889
|
+
...(reviewEvidence ? { reviewEvidence } : {}),
|
|
862
890
|
suggestedNextActions: digest.suggestedNextActions,
|
|
863
891
|
};
|
|
864
892
|
return ok ? result(payload) : { ...result(payload), isError: true };
|
|
@@ -900,24 +928,31 @@ export async function callRepositoryTool(
|
|
|
900
928
|
// nested ExecutionJob. Local Job remains the worker settlement surface.
|
|
901
929
|
const fromDurableWorker = args.__from_durable_worker === true
|
|
902
930
|
|| typeof args.__execution_job_id === 'string';
|
|
903
|
-
//
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
931
|
+
// Process Runtime owns local async execution. apply_mode=async means
|
|
932
|
+
// return its Process handle immediately; it must not promote a local
|
|
933
|
+
// command into the retired ExecutionJob path. Explicit mode=durable
|
|
934
|
+
// remains a separate external-Controller boundary.
|
|
935
|
+
const returnHandleImmediately = args.apply_mode === 'async'
|
|
936
|
+
|| args.mode === 'async'
|
|
907
937
|
|| args.async === true
|
|
908
938
|
|| args.background === true;
|
|
939
|
+
const forceDurable = fromDurableWorker
|
|
940
|
+
|| args.mode === 'durable'
|
|
941
|
+
|| args.force_durable === true;
|
|
909
942
|
const routingDecision = routeExecution({
|
|
910
943
|
operation: 'repository_command_execute',
|
|
911
944
|
mode: forceDurable ? 'durable' : args.mode === 'fast' ? 'fast' : 'auto',
|
|
912
945
|
command: args.command as string | string[] | undefined,
|
|
913
946
|
timeoutMs,
|
|
914
|
-
background: args.background === true || args.async === true,
|
|
947
|
+
background: forceDurable && (args.background === true || args.async === true),
|
|
915
948
|
defaultBranch: repository.defaultBranch,
|
|
916
949
|
approvalContinuation: typeof args.approval_request_id === 'string'
|
|
917
950
|
|| typeof args.approval_token === 'string',
|
|
918
951
|
});
|
|
919
952
|
// Unified Process Runtime for local commands (Direct/Managed) when not forced durable.
|
|
920
|
-
|
|
953
|
+
// Ephemeral workspaces cannot persist a recoverable async Process handle,
|
|
954
|
+
// so their async requests remain promotion-required below.
|
|
955
|
+
if (!forceDurable && !fromDurableWorker && !(target.workspace && returnHandleImmediately)) {
|
|
921
956
|
try {
|
|
922
957
|
const routeClass = classifyRepositoryCommandRoute(args.command as string | string[], {
|
|
923
958
|
forceDurable: false,
|
|
@@ -931,7 +966,11 @@ export async function callRepositoryTool(
|
|
|
931
966
|
command: args.command as string | string[],
|
|
932
967
|
cwd: typeof args.cwd === 'string' ? args.cwd : undefined,
|
|
933
968
|
timeoutMs,
|
|
969
|
+
interactiveWaitMs: returnHandleImmediately
|
|
970
|
+
? 0
|
|
971
|
+
: typeof args.interactive_wait_ms === 'number' ? args.interactive_wait_ms : undefined,
|
|
934
972
|
maxOutputBytes,
|
|
973
|
+
returnHandleImmediately,
|
|
935
974
|
requestId: typeof args.request_id === 'string' ? args.request_id : undefined,
|
|
936
975
|
executionIdentity,
|
|
937
976
|
allowNonGitWorkspace: target.workspace !== undefined,
|
|
@@ -1040,7 +1079,7 @@ export async function callRepositoryTool(
|
|
|
1040
1079
|
return failure(error);
|
|
1041
1080
|
}
|
|
1042
1081
|
}
|
|
1043
|
-
if (target.workspace && forceDurable) {
|
|
1082
|
+
if (target.workspace && (forceDurable || returnHandleImmediately)) {
|
|
1044
1083
|
return result({
|
|
1045
1084
|
accepted: false,
|
|
1046
1085
|
mode: 'durable',
|
package/src/cli/mcp/server.ts
CHANGED
|
@@ -219,17 +219,12 @@ async function proxyRuntimeToolCall(
|
|
|
219
219
|
ctx: MultiRepositoryMcpToolContext,
|
|
220
220
|
name: string,
|
|
221
221
|
args: Record<string, unknown>,
|
|
222
|
-
expectedSchema?: CanonicalRuntimeToolSchema,
|
|
223
222
|
): Promise<CallToolResult> {
|
|
224
223
|
return withCanonicalRuntimeClient(ctx, async (client) => {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
if (fingerprint !== expectedSchema.fingerprint || !definitions.some((tool) => tool.name === name)) {
|
|
230
|
-
return toolSurfaceMismatchResult();
|
|
231
|
-
}
|
|
232
|
-
}
|
|
224
|
+
// The outer Connector session is already bound to the Canonical Runtime
|
|
225
|
+
// schema and fenced by the Runtime-published fingerprint before dispatch.
|
|
226
|
+
// Re-listing tools here creates a second discovery round trip for every
|
|
227
|
+
// tool call without strengthening that fence.
|
|
233
228
|
const response = await client.callTool({ name, arguments: args });
|
|
234
229
|
return response as unknown as CallToolResult;
|
|
235
230
|
});
|
|
@@ -309,7 +304,7 @@ export function createForgeMcpServerFromContext(
|
|
|
309
304
|
// Gateway processes from acquiring Process Runtime leases or evaluating
|
|
310
305
|
// Runtime source coherence against their own checkout.
|
|
311
306
|
if (!getRuntimeWriteClaim()) {
|
|
312
|
-
if (runtimeSchema) return proxyRuntimeToolCall(ctx, name, args
|
|
307
|
+
if (runtimeSchema) return proxyRuntimeToolCall(ctx, name, args);
|
|
313
308
|
if (observeRuntimeStatus(ctx.controllerHome).ready) return proxyRuntimeToolCall(ctx, name, args);
|
|
314
309
|
}
|
|
315
310
|
const accessResult = callAccessTool(ctx, name, args);
|