@moretea-labs/forge 1.8.1 → 1.8.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/AGENTS.md +5 -2
- package/CHANGELOG.md +20 -0
- package/README.en.md +24 -3
- package/README.md +10 -6
- package/README.zh-CN.md +5 -3
- package/THIRD_PARTY_NOTICES.md +1 -2
- package/adapters/chatgpt/browser-delivery-runtime.ts +5 -3
- package/adapters/chatgpt/provider-delivery.ts +1 -1
- package/adapters/chatgpt/work-conversation-binding-store.ts +20 -1
- package/adapters/computer/chatgpt-extension-target.ts +295 -50
- package/adapters/computer/chrome-extension/background.js +227 -71
- package/adapters/computer/chrome-extension/content.js +181 -157
- package/adapters/computer/chrome-extension/manifest.json +3 -1
- package/adapters/computer/desktop-operator-provider.ts +18 -6
- package/adapters/computer/interaction-target-authority.ts +39 -9
- package/adapters/mcp/access-mode.ts +18 -39
- package/adapters/mcp/auth.ts +2 -6
- package/adapters/mcp/instructions.ts +2 -2
- package/adapters/mcp/multi-repository.ts +7 -28
- package/adapters/mcp/runtime-gateway/context-adapter.ts +79 -40
- package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +7 -15
- package/adapters/mcp/runtime-gateway/execution-tools.ts +7 -13
- package/adapters/mcp/runtime-gateway/plugin-adapter.ts +16 -3
- package/adapters/mcp/runtime-gateway/process-tools.ts +3 -21
- package/adapters/mcp/runtime-gateway/router.ts +3 -5
- package/adapters/mcp/runtime-gateway/routing-policy.ts +17 -10
- package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +1 -1
- package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +14 -9
- package/adapters/mcp/runtime-gateway/runtime-tools.ts +1 -5
- package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +36 -1
- package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +58 -4
- package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +7 -3
- package/adapters/mcp/runtime-gateway/work-adapter.ts +16 -16
- package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +0 -17
- package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +69 -12
- package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +26 -2
- package/adapters/mcp/server.ts +24 -3
- package/adapters/mcp/setup.ts +4 -10
- package/adapters/mcp/tool-mapping/access-tools.ts +0 -6
- package/adapters/mcp/tool-mapping/legacy-tool-service.ts +672 -2935
- package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +1 -1
- package/adapters/mcp/tool-mapping/repository-tools.ts +52 -86
- package/adapters/mcp/toolset-names.ts +11 -42
- package/adapters/mcp/toolset.ts +16 -90
- package/{src/cli → adapters}/mcp/transports/AGENTS.md +5 -5
- package/{src/cli → adapters}/mcp/transports/CLAUDE.md +5 -5
- package/adapters/mcp/transports/http-observation.ts +18 -6
- package/adapters/mcp/transports/http-post-lifecycle.ts +19 -0
- package/adapters/mcp/transports/http.ts +54 -14
- package/adapters/mcp/types.ts +0 -6
- package/assets/hooks/lib/session-state.sh +0 -38
- package/assets/hooks/post-bash.sh +1 -1
- package/assets/hooks/post-tool-observer.sh +0 -5
- package/assets/hooks/prompt-guard.sh +0 -55
- package/assets/partials/04-project-structure.partial.md +1 -1
- package/assets/partials/07-footer.partial.md +1 -1
- package/assets/partials-agents/02-operating-mode.partial.md +1 -1
- package/assets/partials-agents/08-deep-docs.partial.md +1 -1
- package/assets/reference-configs/agentic-development-flow.md +1 -1
- package/assets/reference-configs/external-tooling.md +0 -76
- package/assets/reference-configs/release-deploy.md +1 -1
- package/assets/templates/helpers/architecture-queue.sh +1 -1
- package/assets/templates/helpers/check-agent-tooling.sh +1 -327
- package/assets/templates/helpers/check-task-workflow.sh +1 -1
- package/assets/templates/helpers/ensure-task-workflow.sh +0 -14
- package/assets/templates/helpers/migrate-project-template.sh +2 -2
- package/assets/workflow-contract.v1.json +0 -2
- package/docs/README.md +5 -2
- package/docs/architecture/CURRENT.md +114 -30
- package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +42 -0
- package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +15 -2
- package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +4 -2
- package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +109 -4
- package/docs/architecture/decisions/20261009-exact-code-context-discovery.md +19 -0
- package/docs/architecture/decisions/20261009-generated-xcode-cache-retention.md +37 -0
- package/docs/architecture/decisions/20261011-autonomous-continuation-convergence.md +597 -0
- package/docs/architecture/decisions/20261017-edit-session-finalization-reconciliation.md +17 -0
- package/docs/architecture/decisions/20261019-retire-host-skills.md +16 -0
- package/docs/architecture/diagrams/agentic-dev-plugin-architecture.html +1 -1
- package/docs/architecture/domains/public-surface.md +3 -5
- package/docs/architecture/domains/verification.md +5 -5
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +2 -2
- package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +4 -4
- package/docs/architecture/reviews/20261015-code-search-runtime-acceptance.md +75 -0
- package/docs/forge-plugin-management.md +14 -2
- package/docs/operations/controller-browser-plugin.md +23 -0
- package/docs/operations/features.md +6 -7
- package/docs/operations/features.zh-CN.md +1 -1
- package/docs/operations/github-repository.md +4 -4
- package/docs/operations/github-semantic-release-projection.md +20 -0
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/mcp-tool-exposure.md +13 -54
- package/docs/operations/runtime-performance-diagnostics.md +8 -0
- package/docs/operations/standalone-disaster-recovery.md +1 -1
- package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
- package/docs/tutorials/03-first-repository-task.md +2 -0
- package/docs/wiki/Computer-and-Plugins.md +78 -0
- package/docs/wiki/Computer-and-Plugins.zh-CN.md +88 -0
- package/docs/wiki/Home.md +16 -2
- package/docs/wiki/Implementation.md +24 -12
- package/docs/wiki/Installation.md +28 -32
- package/docs/wiki/Integrations.md +4 -0
- package/docs/wiki/Quick-Start.md +35 -22
- package/docs/wiki/Releases-and-Upgrades.md +15 -25
- package/docs/wiki/_Sidebar.md +5 -1
- package/package.json +1 -12
- package/packages/kernel/controller/infrastructure/controller-session-store.ts +63 -38
- package/packages/kernel/identity/infrastructure/activity-projection-store.ts +10 -0
- package/packages/kernel/scheduler/application/eligibility.ts +4 -1
- package/packages/kernel/scheduler/infrastructure/schedule-store.ts +13 -10
- package/packages/kernel/work/application/work-service.ts +1 -0
- package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
- package/packages/kernel/work/domain/state-machine.ts +9 -2
- package/packages/kernel/work/infrastructure/work-contract-store.ts +28 -1
- package/packages/plugin-runtime/browser/provider-registry.ts +12 -36
- package/packages/plugin-runtime/computer/conversation-target.ts +17 -7
- package/scripts/assemble-template.ts +11 -72
- package/scripts/check-mcp-compatibility.ts +55 -74
- package/scripts/check-package-identity.mjs +0 -5
- package/scripts/check-runtime-architecture.mjs +305 -28
- package/scripts/init-project.sh +0 -46
- package/scripts/install-ios-hid-toolchain.sh +60 -0
- package/scripts/install-standalone-recovery.ts +1 -1
- package/scripts/lib/project-init-lib.sh +3 -3
- package/scripts/migrate-windows-wsl-controller-home.ts +2 -0
- package/scripts/open-source-audit-allowlist.txt +0 -1
- package/scripts/run-governed-gate.ts +2 -0
- package/scripts/smoke-ios-physical-device.ts +38 -10
- package/scripts/smoke-mcp-http-runtime.ts +7 -8
- package/scripts/smoke-mcp-tool-surface.ts +27 -41
- package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +6 -3
- package/scripts/sync-generated-authority.mjs +0 -1
- package/src/cli/agent-jobs/executor-health.ts +1 -1
- package/src/cli/agent-jobs/integration.ts +2 -2
- package/src/cli/chatgpt-browser/file-policy.ts +2 -2
- package/src/cli/commands/doctor.ts +1 -143
- package/src/cli/commands/global-runtime.ts +3 -196
- package/src/cli/commands/init-hook.ts +6 -23
- package/src/cli/commands/init.ts +3 -252
- package/src/cli/commands/mcp.ts +0 -5
- package/src/cli/commands/prompt-guard-decision.ts +0 -2
- package/src/cli/commands/recovery.ts +2 -14
- package/src/cli/commands/repository.ts +17 -1
- package/src/cli/commands/setup-execution.ts +41 -0
- package/src/cli/controller/completion-orchestrator.ts +1 -1
- package/src/cli/controller/composite-operations.ts +1 -1
- package/src/cli/controller/context/instruction-context.ts +1 -1
- package/src/cli/controller/context/known-paths.ts +2 -2
- package/src/cli/controller/context/query-planning.ts +11 -4
- package/src/cli/controller/context/rule-resolution.ts +2 -2
- package/src/cli/controller/context/source-materializer.ts +2 -2
- package/src/cli/controller/context/structural-provider.ts +84 -0
- package/src/cli/controller/context/structural.ts +6 -6
- package/src/cli/controller/context/types.ts +8 -9
- package/src/cli/controller/context-pack.ts +97 -76
- package/src/cli/controller/operational-plan.ts +1 -1
- package/src/cli/controller/systemd-user.ts +4 -10
- package/src/cli/editing/edit-session.ts +17 -5
- package/src/cli/github/github.ts +4 -4
- package/src/cli/github/semantic-projection.ts +174 -0
- package/src/cli/hook/prompt-intents.ts +0 -9
- package/src/cli/index.ts +1 -43
- package/src/cli/local-bridge/connector-freshness.ts +1 -12
- package/src/cli/local-bridge/console-automations.ts +1 -1
- package/src/cli/local-bridge/console-view-models.ts +1 -1
- package/src/cli/local-bridge/facade-api.ts +0 -2
- package/src/cli/repositories/command-classifier.ts +0 -9
- package/src/cli/repositories/command-scope.ts +2 -2
- package/src/cli/repositories/locks.ts +20 -0
- package/src/cli/repositories/registry.ts +2 -1
- package/src/cli/repositories/safe-patch.ts +2 -12
- package/src/cli/repositories/structured-git.ts +39 -3
- package/src/cli/repository/inspector.ts +185 -343
- package/src/effects/process-runner.ts +17 -1
- package/src/runtime/context/generic-lsp-provider.ts +1 -1
- package/src/runtime/context/semantic-navigation-contract.ts +7 -0
- package/src/runtime/context/semantic-navigation.ts +1 -1
- package/src/runtime/control-plane/cleanup-artifact-retention.ts +4 -4
- package/src/runtime/control-plane/execution/work-delivery-service.ts +150 -31
- package/src/runtime/control-plane/execution/work-handle-authority.ts +12 -4
- package/src/runtime/control-plane/execution/work-handle-store.ts +53 -1
- package/src/runtime/control-plane/execution/work-operation-service.ts +20 -10
- package/src/runtime/control-plane/execution/work-preparation-service.ts +108 -4
- package/src/runtime/control-plane/execution/work-process-evidence.ts +2 -2
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +28 -13
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +5 -1
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +1 -1
- package/src/runtime/control-plane/facade/capability-registry.ts +2 -0
- package/src/runtime/control-plane/facade/work-continuation.ts +1 -1
- package/src/runtime/control-plane/generated-cache-retention.ts +114 -63
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +20 -8
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +1 -11
- package/src/runtime/control-plane/governance/external-effects.ts +1 -1
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +1 -0
- package/src/runtime/control-plane/runtime-cleanup.ts +12 -93
- package/src/runtime/evidence/sensitive-output.ts +22 -2
- package/src/runtime/execution/jobs/child-reference.ts +11 -0
- package/src/runtime/execution/jobs/receipt-recovery.ts +1 -11
- package/src/runtime/execution/process-runtime/command-facade.ts +3 -3
- package/src/runtime/execution/process-runtime/runtime.ts +20 -16
- package/src/runtime/execution/thin-harness/execution-router.ts +16 -16
- package/src/runtime/execution/thin-harness/fast-executor.ts +2 -2
- package/src/runtime/execution/thin-harness/search-worker.ts +2 -2
- package/src/runtime/execution/workers/executor.ts +1 -2
- package/src/runtime/maintenance/cleanup.ts +41 -5
- package/src/runtime/plugins/action-application.ts +12 -1
- package/src/runtime/plugins/app-store-connect-adapter.ts +252 -4
- package/src/runtime/plugins/browser-adapter.ts +381 -313
- package/src/runtime/plugins/browser-macos-bridge.ts +114 -112
- package/src/runtime/plugins/browser-manifest-surface.ts +2 -1
- package/src/runtime/plugins/browser-registration.ts +2 -0
- package/src/runtime/plugins/browser-runtime.ts +26 -35
- package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +11 -2
- package/src/runtime/plugins/computer-registration.ts +76 -9
- package/src/runtime/plugins/github-adapter.ts +30 -3
- package/src/runtime/plugins/gmail-adapter.ts +166 -1
- package/src/runtime/plugins/google-shared.ts +10 -5
- package/src/runtime/plugins/ios/remote-xpc-hid.ts +70 -30
- package/src/runtime/plugins/ios-adapter.ts +45 -40
- package/src/runtime/plugins/ios-agent-device.ts +54 -4
- package/src/runtime/plugins/ios-device-ownership.ts +103 -0
- package/src/runtime/plugins/ios-physical-device.ts +497 -79
- package/src/runtime/plugins/local-system-adapter.ts +1 -99
- package/src/runtime/plugins/store.ts +80 -7
- package/src/runtime/plugins/types.ts +4 -0
- package/src/runtime/projections/git-status-sampler.ts +2 -19
- package/src/runtime/recovery/actions.ts +1 -1
- package/src/runtime/recovery/lifecycle-inventory.ts +1 -11
- package/src/runtime/recovery/probe.ts +2 -2
- package/src/runtime/release/release-coordinator.ts +20 -4
- package/src/runtime/root/controller-progression-composition.ts +67 -5
- package/src/runtime/root/package-connector-service.ts +123 -11
- package/src/runtime/root/package-runtime-release.ts +6 -18
- package/src/runtime/root/package-runtime-service.ts +7 -13
- package/src/runtime/root/release-execution-canary.ts +18 -5
- package/src/runtime/root/release-manifest.ts +0 -34
- package/src/runtime/root/release-materialize.ts +0 -78
- package/src/runtime/root/runtime.ts +1 -2
- package/src/runtime/root/scheduled-controller-composition.ts +2 -1
- package/src/runtime/root/service.ts +90 -11
- package/src/runtime/root/types.ts +0 -6
- package/src/runtime/root/workflow-supervisor-composition.ts +207 -19
- package/src/runtime/root/workflow-supervisor-runtime.ts +365 -10
- package/src/runtime/safe-tooling/google-credential-store.ts +1 -11
- package/src/runtime/safe-tooling/ios-development.ts +22 -8
- package/src/runtime/safe-tooling/job-summary.ts +1 -1
- package/src/runtime/safe-tooling/workspace-auth.ts +4 -1
- package/src/runtime/shared/atomic-text-file.ts +21 -0
- package/src/runtime/shared/json-files.ts +8 -3
- package/src/runtime/standalone-recovery/core.ts +189 -174
- package/src/runtime/standalone-recovery/entry.ts +62 -30
- package/src/runtime/standalone-recovery/operation-lock.ts +11 -1
- package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +1 -0
- package/src/runtime/workflow/schedules/engine.ts +36 -14
- package/src/runtime/workflow/schedules/pending-activation.ts +11 -4
- package/src/runtime/workflow/schedules/work-continuation.ts +51 -6
- package/supervisor/client.ts +31 -14
- package/supervisor/control-plane.ts +210 -115
- package/supervisor/forge-validators.ts +88 -21
- package/supervisor/native-browser-adapter.ts +393 -28
- package/supervisor/native-messaging/host.ts +21 -2
- package/supervisor/protocol.ts +74 -26
- package/supervisor/server.ts +16 -8
- package/supervisor/store.ts +476 -57
- package/supervisor/types.ts +19 -13
- package/SKILL.md +0 -427
- package/adapters/computer/chatgpt-target-router.ts +0 -103
- package/adapters/mcp/runtime-gateway/automation-receipt-adapter.ts +0 -87
- package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +0 -1
- package/adapters/mcp/toolset-selection.ts +0 -41
- package/agents/openai.yaml +0 -4
- package/assets/skill-hooks.json +0 -41
- package/assets/skill-version.json +0 -189
- package/assets/skills/claude-review/SKILL.md +0 -231
- package/assets/skills/codex-review/SKILL.md +0 -103
- package/assets/templates/helpers/check-skill-version.ts +0 -193
- package/scripts/check-skill-version.ts +0 -5
- package/scripts/ensure-codegraph.sh +0 -16
- package/scripts/run-skill-hook.ts +0 -244
- package/scripts/sync-codex-installed-copies.sh +0 -182
- package/src/cli/commands/tools.ts +0 -167
- package/src/cli/mcp/access-mode.ts +0 -2
- package/src/cli/mcp/access-tools.ts +0 -2
- package/src/cli/mcp/audit.ts +0 -2
- package/src/cli/mcp/auth.ts +0 -2
- package/src/cli/mcp/instructions.ts +0 -2
- package/src/cli/mcp/legacy-context.ts +0 -2
- package/src/cli/mcp/legacy-tool-service.ts +0 -2
- package/src/cli/mcp/multi-repository.ts +0 -2
- package/src/cli/mcp/oauth.ts +0 -2
- package/src/cli/mcp/openai-secure-tunnel.ts +0 -2
- package/src/cli/mcp/paths.ts +0 -2
- package/src/cli/mcp/policy.ts +0 -2
- package/src/cli/mcp/post-finalize-work-attribution.ts +0 -2
- package/src/cli/mcp/proxy-env.ts +0 -2
- package/src/cli/mcp/readiness-projection.ts +0 -2
- package/src/cli/mcp/redaction.ts +0 -2
- package/src/cli/mcp/repo.ts +0 -2
- package/src/cli/mcp/repository-tools.ts +0 -2
- package/src/cli/mcp/server.ts +0 -2
- package/src/cli/mcp/setup.ts +0 -2
- package/src/cli/mcp/tool-capability-cache.ts +0 -2
- package/src/cli/mcp/tool-contract.ts +0 -2
- package/src/cli/mcp/tools.ts +0 -2
- package/src/cli/mcp/toolset-names.ts +0 -2
- package/src/cli/mcp/toolset-selection.ts +0 -2
- package/src/cli/mcp/toolset.ts +0 -2
- package/src/cli/mcp/transports/http.ts +0 -2
- package/src/cli/mcp/transports/session-registry.ts +0 -2
- package/src/cli/mcp/transports/stdio.ts +0 -2
- package/src/cli/mcp/types.ts +0 -2
- package/src/cli/mcp/umbrella-tools.ts +0 -2
- package/src/cli/tools/codegraph.ts +0 -695
- package/src/core/adoption/helper-wrapper-plan.ts +0 -159
- package/src/runtime/context/codegraph-cache-boundary.ts +0 -255
- package/src/runtime/context/codegraph-read-provider.ts +0 -611
- package/src/runtime/context/codegraph-sidecar.cjs +0 -248
- package/src/runtime/control-plane/codegraph-cache-retention.ts +0 -164
- package/src/runtime/gateway/mcp/execution-tools.ts +0 -2
- package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +0 -2
- package/src/runtime/gateway/mcp/persisted-check-process.ts +0 -2
- package/src/runtime/gateway/mcp/process-tools.ts +0 -2
- package/src/runtime/gateway/mcp/router.ts +0 -2
- package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +0 -2
- package/src/runtime/gateway/mcp/runtime-tools.ts +0 -2
- package/src/runtime/gateway/mcp/work-validation-reconciler.ts +0 -2
- package/src/runtime/plugins/browser-provider-registry.ts +0 -2
- package/src/runtime/plugins/computer-chatgpt-macos-target.ts +0 -891
|
@@ -48,7 +48,7 @@ export async function callPostFinalizeWorkReadOnlyCommand(
|
|
|
48
48
|
args: Record<string, unknown>,
|
|
49
49
|
caller?: RepositoryToolCallerContext,
|
|
50
50
|
): Promise<CallToolResult | undefined> {
|
|
51
|
-
if (name !== '
|
|
51
|
+
if (name !== 'execute_command') return undefined;
|
|
52
52
|
if (typeof args.workspace_root === 'string' && args.workspace_root.trim()) return undefined;
|
|
53
53
|
|
|
54
54
|
const requestedWorkId = typeof args.work_id === 'string' ? args.work_id.trim() : '';
|
|
@@ -4,7 +4,7 @@ import { resolveEphemeralWorkspaceTarget } from '../../../src/cli/repositories/e
|
|
|
4
4
|
import { commandExecutionScopeKey, type RepositoryCommandScopeTarget } from '../../../src/cli/repositories/command-scope';
|
|
5
5
|
import { executionIdentityForWork, type ResolvedExecutionIdentity } from '../../../src/runtime/control-plane/execution/execution-identity';
|
|
6
6
|
import { assertNoBoundExecutionSessionMutation, resolveClaimedRepositoryWorkId, resolveExplicitClaimedRepositoryWork, type RepositoryWorkAttributionCaller } from '../../../src/runtime/control-plane/execution/repository-work-attribution';
|
|
7
|
-
import { getWorkContract,
|
|
7
|
+
import { getWorkContract, semanticWorkState, type WorkContract } from '../../../packages/kernel/work/api';
|
|
8
8
|
import { assertCanonicalRepositoryMutationWorkHandleAvailable, ensureRepositoryMutationWorkHandle, markRepositoryMutationStarted } from '../../../src/runtime/control-plane/execution/work-handle-authority';
|
|
9
9
|
import { readWorkHandle } from '../../../src/runtime/control-plane/execution/work-handle-store';
|
|
10
10
|
import { ensureRunningRepositoryWorkCheckout } from '../../../src/runtime/control-plane/execution/retained-work-resume';
|
|
@@ -244,25 +244,23 @@ export const repositoryToolDefinitions: McpToolDefinition[] = [
|
|
|
244
244
|
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.' },
|
|
245
245
|
apply_mode: { type: 'string', enum: ['sync', 'async'], description: 'Defaults to sync for interactive development. Set async only for a separately durable operation.' },
|
|
246
246
|
}),
|
|
247
|
-
definition('
|
|
247
|
+
definition('execute_command', 'Single terminal entry. Repository and authorized workspace commands need no Work or Plan. Explicit scope=host uses the existing ForgeInstance process:exec Grant. Process Runtime owns execution, process handles and timeouts; Git ownership checks remain mechanical.', {
|
|
248
248
|
repo_id: repoId,
|
|
249
249
|
checkout_id: { type: 'string', description: 'Optional checkout identity for repositories with multiple local clones.' },
|
|
250
|
-
|
|
250
|
+
work_id: { type: 'string', description: 'Optional Work provenance; ordinary commands never require a Work. Work-attributed effects require a stable request_id.' },
|
|
251
|
+
scope: { type: 'string', enum: ['repository', 'host'], description: 'Defaults to repository; host requires an explicit process:exec ForgeInstance Grant.' },
|
|
252
|
+
command: { anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' }, minItems: 1 }], description: 'Repository: typed argv or shell string; host: typed argv only.' },
|
|
253
|
+
shell_command: { type: 'string', description: 'Host shell only; mutually exclusive with command and requires scope=host.' },
|
|
254
|
+
request_id: { type: 'string', description: 'Stable invocation id for reconnect without duplicate effects.' },
|
|
251
255
|
cwd: { type: 'string', description: 'Optional root-relative working directory.' },
|
|
252
256
|
workspace_root: { type: 'string', description: 'Absolute existing local directory used as an ephemeral execution root. Mutually exclusive with repo_id/checkout_id; does not register or initialize the directory.' },
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
repo_id: repoId,
|
|
256
|
-
checkout_id: { type: 'string', description: 'Optional checkout identity for repositories with multiple local clones.' },
|
|
257
|
-
work_id: { type: 'string', description: 'Optional durable Work identity. Workflow controllers should pass the exact claimed Work id so attribution survives transient MCP transport sessions.' },
|
|
258
|
-
command: { anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' }, minItems: 1 }], description: 'Legacy shell string or typed argv array. Typed argv executes without a shell.' },
|
|
259
|
-
cwd: { type: 'string', description: 'Optional root-relative working directory.' },
|
|
260
|
-
workspace_root: { type: 'string', description: 'Absolute existing local directory used as an ephemeral execution root. Mutually exclusive with repo_id/checkout_id; does not register or initialize the directory.' },
|
|
261
|
-
approval_token: { type: 'string', description: 'Exact approval token returned by repository_command_preview.' },
|
|
257
|
+
dry_run: { type: 'boolean', description: 'Preview without executing: returns command classification, approval token and Git snapshots for repository/workspace target.' },
|
|
258
|
+
approval_token: { type: 'string', description: 'Exact approval token returned by execute_command(dry_run=true).' },
|
|
262
259
|
approval_request_id: { type: 'string', description: 'Resolved approvalRequestId returned by approval_resolve.' },
|
|
263
260
|
timeout_ms: { type: 'number', description: 'Optional execution timeout in milliseconds.' },
|
|
264
|
-
max_output_bytes: { type: 'number', description: '
|
|
265
|
-
|
|
261
|
+
max_output_bytes: { type: 'number', minimum: 1024, maximum: 1048576, description: 'Captured output limit 1024–1048576 bytes.' },
|
|
262
|
+
interactive_wait_ms: { type: 'number', description: 'Optional short attachment window; long-running processes return a handle.' },
|
|
263
|
+
}),
|
|
266
264
|
|
|
267
265
|
// Thin Harness V1 is exposed through repository_workbench operations to keep the stable tool surface bounded.
|
|
268
266
|
];
|
|
@@ -357,11 +355,8 @@ function resolveRepositorySelectionForClaimedWork(
|
|
|
357
355
|
allowSoleRepository: true,
|
|
358
356
|
});
|
|
359
357
|
}
|
|
360
|
-
|
|
358
|
+
const work = resolveExplicitClaimedRepositoryWork(controllerHome, repository, caller, explicitWorkId);
|
|
361
359
|
if (!work) return repository;
|
|
362
|
-
if (work.workKind !== 'repository_change') {
|
|
363
|
-
work = promoteWorkToRepositoryChange({ controllerHome, repoId: repository.repoId }, work.workId);
|
|
364
|
-
}
|
|
365
360
|
const principalId = caller?.principalId?.trim();
|
|
366
361
|
const sessionId = caller?.sessionId?.trim();
|
|
367
362
|
const controllerInstanceId = caller?.controllerInstanceId?.trim();
|
|
@@ -591,33 +586,6 @@ function failure(error: unknown): RepositoryToolResult {
|
|
|
591
586
|
return { ...result({ error: { code, message, ...(compactDetails !== undefined ? { details: compactDetails } : {}) } }), isError: true };
|
|
592
587
|
}
|
|
593
588
|
|
|
594
|
-
interface RepositoryExplorationGuidance {
|
|
595
|
-
code: 'FRAGMENTED_REPOSITORY_EXPLORATION';
|
|
596
|
-
recommendedTool: 'rh_context';
|
|
597
|
-
recommendedOperation: 'search';
|
|
598
|
-
message: string;
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
function fragmentedRepositoryExplorationGuidance(command: unknown): RepositoryExplorationGuidance | undefined {
|
|
602
|
-
if (typeof command !== 'string') return undefined;
|
|
603
|
-
const segments = command.split(/(?:&&|\|\||[;|])/g);
|
|
604
|
-
const readPrograms = new Set<string>();
|
|
605
|
-
let readStepCount = 0;
|
|
606
|
-
for (const segment of segments) {
|
|
607
|
-
const match = segment.trim().match(/^(?:(?:command|env)\s+)?(?:[A-Za-z_][A-Za-z0-9_]*=[^\s]+\s+)*(rg|grep|sed|cat|head|tail)\b/i);
|
|
608
|
-
if (!match) continue;
|
|
609
|
-
readStepCount += 1;
|
|
610
|
-
readPrograms.add(match[1]!.toLowerCase());
|
|
611
|
-
}
|
|
612
|
-
if (readStepCount < 2) return undefined;
|
|
613
|
-
return {
|
|
614
|
-
code: 'FRAGMENTED_REPOSITORY_EXPLORATION',
|
|
615
|
-
recommendedTool: 'rh_context',
|
|
616
|
-
recommendedOperation: 'search',
|
|
617
|
-
message: `Detected ${readStepCount} chained repository read steps (${[...readPrograms].join(', ')}). Prefer a broad rh_context request first, then repeat rh_context with selected paths or relationships when more evidence can improve correctness; keep shell search as fallback when the Context Plane cannot supply the needed evidence.`,
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
|
|
621
589
|
function compactProcessCommandPayload(input: {
|
|
622
590
|
accepted?: boolean;
|
|
623
591
|
mode: string;
|
|
@@ -644,7 +612,6 @@ function compactProcessCommandPayload(input: {
|
|
|
644
612
|
/** summary (default) omits nested process / routing dumps; detail restores diagnostics. */
|
|
645
613
|
detailLevel?: 'summary' | 'detail';
|
|
646
614
|
includeFullProcess?: boolean;
|
|
647
|
-
guidance?: RepositoryExplorationGuidance;
|
|
648
615
|
}): Record<string, unknown> {
|
|
649
616
|
const output = compactCommandOutput(input.stdout, input.stderr, { ok: input.ok === true });
|
|
650
617
|
const detail = input.detailLevel === 'detail' || input.includeFullProcess === true;
|
|
@@ -680,7 +647,6 @@ function compactProcessCommandPayload(input: {
|
|
|
680
647
|
stderr: output.stderr ?? '',
|
|
681
648
|
...(output.stdoutTruncated ? { stdoutTruncated: true, stdoutBytes: output.stdoutBytes } : {}),
|
|
682
649
|
...(output.stderrTruncated ? { stderrTruncated: true, stderrBytes: output.stderrBytes } : {}),
|
|
683
|
-
...(input.guidance ? { guidance: input.guidance, suggestedOperation: 'rh_context' } : {}),
|
|
684
650
|
};
|
|
685
651
|
if (completed && !ok) {
|
|
686
652
|
payload.error = {
|
|
@@ -729,7 +695,6 @@ function compactProcessCommandPayload(input: {
|
|
|
729
695
|
}
|
|
730
696
|
: {}),
|
|
731
697
|
durableSideEffects: effects,
|
|
732
|
-
...(input.guidance ? { guidance: input.guidance, suggestedOperation: 'rh_context' } : {}),
|
|
733
698
|
next: input.next,
|
|
734
699
|
detailLevel: 'detail',
|
|
735
700
|
};
|
|
@@ -771,7 +736,7 @@ export async function callRepositoryTool(
|
|
|
771
736
|
args: Record<string, unknown>,
|
|
772
737
|
caller?: RepositoryToolCallerContext,
|
|
773
738
|
): Promise<RepositoryToolResult | undefined> {
|
|
774
|
-
if (!name.startsWith('repository_') && name !== 'read_repository_file') return undefined;
|
|
739
|
+
if (!name.startsWith('repository_') && name !== 'read_repository_file' && name !== 'execute_command') return undefined;
|
|
775
740
|
try {
|
|
776
741
|
const repoIdValue = typeof args.repo_id === 'string' ? args.repo_id.trim() : '';
|
|
777
742
|
switch (name) {
|
|
@@ -924,7 +889,7 @@ export async function callRepositoryTool(
|
|
|
924
889
|
case 'repository_git_status': {
|
|
925
890
|
const repository = resolveRepositorySelection({ repoId: repoIdValue || undefined, checkoutId: typeof args.checkout_id === 'string' ? args.checkout_id : undefined, controllerHome, allowSoleRepository: true });
|
|
926
891
|
const status = args.refresh === true
|
|
927
|
-
? writeRepositoryGitStatusSample(controllerHome, repository)
|
|
892
|
+
? await writeRepositoryGitStatusSample(controllerHome, repository)
|
|
928
893
|
: readRepositoryGitStatusSample(controllerHome, repository.repoId, repository.activeCheckoutId);
|
|
929
894
|
return result({
|
|
930
895
|
status: status ?? {
|
|
@@ -997,7 +962,9 @@ export async function callRepositoryTool(
|
|
|
997
962
|
workId: binding?.workId,
|
|
998
963
|
});
|
|
999
964
|
}
|
|
1000
|
-
|
|
965
|
+
// A validation-only reattachment is not repository mutation admission;
|
|
966
|
+
// it must never promote a thin investigation to repository_change.
|
|
967
|
+
const mutationAuthority = binding?.workId && args.validation_only !== true
|
|
1001
968
|
? ensureRepositoryMutationWorkHandle({
|
|
1002
969
|
controllerHome,
|
|
1003
970
|
repository,
|
|
@@ -1089,32 +1056,32 @@ export async function callRepositoryTool(
|
|
|
1089
1056
|
};
|
|
1090
1057
|
return ok ? result(payload) : { ...result(payload), isError: true };
|
|
1091
1058
|
}
|
|
1092
|
-
case '
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1059
|
+
case 'execute_command': {
|
|
1060
|
+
if (args.scope !== undefined && args.scope !== 'repository') throw new Error('COMMAND_SCOPE_INVALID: host scope uses the authorized host command lane');
|
|
1061
|
+
if (args.shell_command !== undefined) throw new Error('COMMAND_SCOPE_INVALID: shell_command requires scope=host');
|
|
1062
|
+
if (args.command === undefined) throw new Error('COMMAND_REQUIRED: repository commands require command');
|
|
1063
|
+
if (args.dry_run === true) {
|
|
1064
|
+
const target = resolveRepositoryCommandTarget(controllerHome, args, repoIdValue, caller);
|
|
1065
|
+
const { commandTarget } = target;
|
|
1066
|
+
const execution = withControllerLock(
|
|
1067
|
+
controllerHome,
|
|
1068
|
+
{ scope: 'repository', repoId: commandExecutionScopeKey(commandTarget) },
|
|
1069
|
+
'mcp:execute_command:preview',
|
|
1070
|
+
() => executeRepositoryCommand(controllerHome, commandTarget, {
|
|
1071
|
+
command: args.command as string | string[],
|
|
1072
|
+
cwd: typeof args.cwd === 'string' ? args.cwd : undefined,
|
|
1073
|
+
dryRun: true,
|
|
1074
|
+
allowNonGitWorkspace: target.workspace !== undefined,
|
|
1075
|
+
}),
|
|
1076
|
+
60_000,
|
|
1077
|
+
);
|
|
1078
|
+
const { repoId: _previewRepoId, checkoutId: _previewCheckoutId, ...workspacePreviewFields } = execution as unknown as Record<string, unknown>;
|
|
1079
|
+
return result({
|
|
1080
|
+
...(commandTarget.repoId ? execution as unknown as Record<string, unknown> : workspacePreviewFields),
|
|
1081
|
+
...(commandTarget.repoId ? {} : { scopeId: commandExecutionScopeKey(commandTarget) }),
|
|
1082
|
+
...(target.workspace ? { workspace: target.workspace } : {}),
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
1118
1085
|
let target = resolveRepositoryCommandTarget(controllerHome, args, repoIdValue, caller);
|
|
1119
1086
|
let { repository, commandTarget, executionIdentity, historicalWorkContext } = target;
|
|
1120
1087
|
// Repository targets keep their established identity fields. An arbitrary
|
|
@@ -1181,7 +1148,7 @@ export async function callRepositoryTool(
|
|
|
1181
1148
|
mutationAuthority = withControllerLock(
|
|
1182
1149
|
controllerHome,
|
|
1183
1150
|
{ scope: 'repository', repoId: commandExecutionScopeKey(commandTarget) },
|
|
1184
|
-
'mcp:
|
|
1151
|
+
'mcp:execute_command:mutation-authority',
|
|
1185
1152
|
() => ensureRepositoryMutationWorkHandle({
|
|
1186
1153
|
controllerHome,
|
|
1187
1154
|
repository: repository!,
|
|
@@ -1201,7 +1168,7 @@ export async function callRepositoryTool(
|
|
|
1201
1168
|
withControllerLock(
|
|
1202
1169
|
controllerHome,
|
|
1203
1170
|
{ scope: 'repository', repoId: commandExecutionScopeKey(commandTarget) },
|
|
1204
|
-
'mcp:
|
|
1171
|
+
'mcp:execute_command:unattributed-mutation-authority',
|
|
1205
1172
|
() => assertCanonicalRepositoryMutationWorkHandleAvailable({
|
|
1206
1173
|
controllerHome,
|
|
1207
1174
|
repositoryId: commandExecutionScopeKey(commandTarget),
|
|
@@ -1219,7 +1186,7 @@ export async function callRepositoryTool(
|
|
|
1219
1186
|
// external durable boundary, not as a second command classifier.
|
|
1220
1187
|
const routingDecision = forceDurable
|
|
1221
1188
|
? routeExecution({
|
|
1222
|
-
operation: '
|
|
1189
|
+
operation: 'execute_command',
|
|
1223
1190
|
mode: 'durable',
|
|
1224
1191
|
timeoutMs,
|
|
1225
1192
|
background: args.background === true || args.async === true,
|
|
@@ -1306,7 +1273,7 @@ export async function callRepositoryTool(
|
|
|
1306
1273
|
withControllerLock(
|
|
1307
1274
|
controllerHome,
|
|
1308
1275
|
{ scope: 'repository', repoId: commandExecutionScopeKey(commandTarget) },
|
|
1309
|
-
'mcp:
|
|
1276
|
+
'mcp:execute_command:mutation-started',
|
|
1310
1277
|
() => markRepositoryMutationStarted({
|
|
1311
1278
|
controllerHome,
|
|
1312
1279
|
repository,
|
|
@@ -1345,7 +1312,7 @@ export async function callRepositoryTool(
|
|
|
1345
1312
|
message: authorization.decision === 'user_confirmation_required'
|
|
1346
1313
|
? authorization.humanSummary
|
|
1347
1314
|
: authorization.reason,
|
|
1348
|
-
suggestedOperation: '
|
|
1315
|
+
suggestedOperation: 'execute_command(dry_run=true)',
|
|
1349
1316
|
});
|
|
1350
1317
|
}
|
|
1351
1318
|
const completed = directWithoutHandle || handle?.completed === true;
|
|
@@ -1374,7 +1341,6 @@ export async function callRepositoryTool(
|
|
|
1374
1341
|
stdout: processResult.stdout,
|
|
1375
1342
|
stderr: processResult.stderr,
|
|
1376
1343
|
durableSideEffects: processResult.durableSideEffects,
|
|
1377
|
-
guidance: explorationGuidance,
|
|
1378
1344
|
next: directWithoutHandle
|
|
1379
1345
|
? processResult.reason === 'readonly_fast_path'
|
|
1380
1346
|
? 'Bounded readonly execution completed without Process record / Lease / Local Job / ExecutionJob / Worker.'
|
|
@@ -1416,7 +1382,7 @@ export async function callRepositoryTool(
|
|
|
1416
1382
|
// Process Runtime is authoritative. Falling through could spawn the
|
|
1417
1383
|
// same command again through the legacy Fast/Local Job path.
|
|
1418
1384
|
if (process.env.FORGE_DEBUG_PROCESS_RUNTIME === '1') {
|
|
1419
|
-
console.error('[
|
|
1385
|
+
console.error('[execute_command] process runtime error', error);
|
|
1420
1386
|
}
|
|
1421
1387
|
return failure(error);
|
|
1422
1388
|
}
|
|
@@ -1486,7 +1452,7 @@ export async function callRepositoryTool(
|
|
|
1486
1452
|
}
|
|
1487
1453
|
} catch (error) {
|
|
1488
1454
|
if (process.env.FORGE_DEBUG_PROCESS_RUNTIME === '1') {
|
|
1489
|
-
console.error('[
|
|
1455
|
+
console.error('[execute_command] durable worker inline process runtime error', error);
|
|
1490
1456
|
}
|
|
1491
1457
|
}
|
|
1492
1458
|
}
|
|
@@ -1496,7 +1462,7 @@ export async function callRepositoryTool(
|
|
|
1496
1462
|
path: 'external_controller_required',
|
|
1497
1463
|
routing: compactRoutingSummary({ path: 'durable', mode: 'durable', reasons: [routingDecision.reasons.join(','), 'local_bridge_execution_retired'] }),
|
|
1498
1464
|
message: 'This command requires explicit external Controller handling; Local Bridge Jobs are retired for repository commands.',
|
|
1499
|
-
|
|
1465
|
+
next: 'This execution boundary requires separate external authority; the model chooses an authorized domain capability or alternative command based on the task.',
|
|
1500
1466
|
externalEffect: {
|
|
1501
1467
|
outcome: 'not_started',
|
|
1502
1468
|
ambiguousFailureOutcome: 'outcome_unknown',
|
|
@@ -4,12 +4,11 @@ import { FACADE_TOOLS } from '../../src/runtime/control-plane/facade/types';
|
|
|
4
4
|
export const PREFERRED_FACADE_TOOL_NAMES = [...FACADE_TOOLS] as const;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* tools remain registered and reachable through `toolset=full`.
|
|
7
|
+
* Preferred public tool names for model routing and connector freshness.
|
|
8
|
+
* Not an exposure profile: every registered MCP tool is always discoverable.
|
|
9
|
+
* Removal of an obsolete public handler is a source migration, not a toolset switch.
|
|
11
10
|
*/
|
|
12
|
-
export const
|
|
11
|
+
export const PREFERRED_CONTROLLER_TOOL_NAMES = [
|
|
13
12
|
...PREFERRED_FACADE_TOOL_NAMES,
|
|
14
13
|
|
|
15
14
|
// Repository selection / bootstrap.
|
|
@@ -17,11 +16,11 @@ export const DEFAULT_CONTROLLER_TOOL_NAMES = [
|
|
|
17
16
|
'repository_get',
|
|
18
17
|
'repository_register',
|
|
19
18
|
|
|
20
|
-
//
|
|
21
|
-
'
|
|
19
|
+
// Unified terminal entry; scope determines its authorized execution target.
|
|
20
|
+
'execute_command',
|
|
22
21
|
|
|
23
22
|
// Source inspection and bounded Direct Edit. Code location is routed through
|
|
24
|
-
// rh_context.search; the
|
|
23
|
+
// rh_context.search; the direct search_repository action remains available.
|
|
25
24
|
'read_repository_file',
|
|
26
25
|
'repository_safe_patch_apply',
|
|
27
26
|
|
|
@@ -29,51 +28,21 @@ export const DEFAULT_CONTROLLER_TOOL_NAMES = [
|
|
|
29
28
|
'run_check',
|
|
30
29
|
|
|
31
30
|
// Protected Computer preparation/input use typed direct-non-persistent actions
|
|
32
|
-
// behind the stable plugin dispatcher.
|
|
33
|
-
// registered only for compatibility clients and are not part of this frozen ABI.
|
|
31
|
+
// behind the stable plugin dispatcher. Distinct OS actions remain public.
|
|
34
32
|
|
|
35
33
|
// One typed plugin dispatcher. Plugin discovery/action schemas stay routed
|
|
36
34
|
// through rh_context(capability_id=plugin.<plugin>.<action>) to avoid widening
|
|
37
|
-
// the
|
|
35
|
+
// the preferred list with every plugin atomic.
|
|
38
36
|
'plugin_action_execute',
|
|
39
37
|
|
|
40
38
|
// Managed Process Runtime lifecycle (attach / poll / cancel — never re-exec).
|
|
41
|
-
//
|
|
42
|
-
// the target, cwd is an execution argument, and it is authorized by one
|
|
43
|
-
// explicit `process:exec` canonical Grant. repository_command_execute stays as
|
|
44
|
-
// translation-only compatibility over the repository target.
|
|
45
|
-
'process_exec',
|
|
39
|
+
// Host execution requires execute_command(scope=host) with explicit process:exec Grant.
|
|
46
40
|
'process_get',
|
|
47
41
|
'process_wait',
|
|
48
42
|
'process_logs',
|
|
49
43
|
'process_cancel',
|
|
50
44
|
|
|
51
|
-
// Evidence.
|
|
52
|
-
// the explicit full compatibility profile; it does not need a top-level
|
|
53
|
-
// default tool.
|
|
45
|
+
// Evidence. The complete registry also exposes exact typed approval actions.
|
|
54
46
|
'result_read',
|
|
55
47
|
'result_search',
|
|
56
48
|
] as const;
|
|
57
|
-
|
|
58
|
-
/** Minimal bootstrap subset retained for diagnostics and constrained clients. */
|
|
59
|
-
export const BOOTSTRAP_CONTROLLER_TOOL_NAMES = [
|
|
60
|
-
...PREFERRED_FACADE_TOOL_NAMES,
|
|
61
|
-
'repository_access_get',
|
|
62
|
-
'repository_list',
|
|
63
|
-
'repository_get',
|
|
64
|
-
'repository_register',
|
|
65
|
-
'repository_latest_source_diagnose',
|
|
66
|
-
'repository_bootstrap_local_project',
|
|
67
|
-
] as const;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Stable ChatGPT connector schema. Keep this identical to the bounded default
|
|
71
|
-
* Runtime surface so discovery never advertises atomic tools that the default
|
|
72
|
-
* Forge build will reject. The exhaustive `full` profile is assembled directly
|
|
73
|
-
* from registered definitions and remains available for explicit compatibility
|
|
74
|
-
* clients without widening the normal connector schema.
|
|
75
|
-
*/
|
|
76
|
-
export const STABLE_CONTROLLER_TOOL_NAMES = DEFAULT_CONTROLLER_TOOL_NAMES;
|
|
77
|
-
|
|
78
|
-
/** Core is a compatibility label for the bounded default Controller surface. */
|
|
79
|
-
export const CORE_CONTROLLER_TOOL_NAMES = DEFAULT_CONTROLLER_TOOL_NAMES;
|
package/adapters/mcp/toolset.ts
CHANGED
|
@@ -11,21 +11,18 @@ import { runtimeToolDefinitions } from './runtime-gateway/runtime-tool-definitio
|
|
|
11
11
|
import { executionToolDefinitions } from './runtime-gateway/execution-tools';
|
|
12
12
|
import { processToolDefinitions } from './runtime-gateway/process-tools';
|
|
13
13
|
import { injectDurableCommandFields } from './runtime-gateway/router';
|
|
14
|
-
import { injectAutomationEnvelopeFields } from './runtime-gateway/automation-receipt-adapter';
|
|
15
14
|
import { injectCognitionSettlementFields } from './runtime-gateway/cognition-settlement';
|
|
16
|
-
import {
|
|
17
|
-
export {
|
|
18
|
-
import type { McpToolset } from './types';
|
|
15
|
+
import { PREFERRED_FACADE_TOOL_NAMES } from './toolset-names';
|
|
16
|
+
export { PREFERRED_CONTROLLER_TOOL_NAMES, PREFERRED_FACADE_TOOL_NAMES } from './toolset-names';
|
|
19
17
|
import { forgeToolSurfaceFingerprint } from '../../src/cli/controller/runtime-config';
|
|
20
18
|
|
|
21
|
-
export type
|
|
22
|
-
export type ControllerToolProfile = 'facade' | 'core' | 'advanced' | 'full';
|
|
19
|
+
export type ControllerToolProfile = 'full';
|
|
23
20
|
|
|
24
21
|
export interface ControllerToolInventoryEntry {
|
|
25
22
|
name: string;
|
|
26
23
|
profile: ControllerToolProfile;
|
|
27
24
|
capability: string;
|
|
28
|
-
exposedVia: 'facade' | '
|
|
25
|
+
exposedVia: 'facade' | 'full';
|
|
29
26
|
}
|
|
30
27
|
|
|
31
28
|
/**
|
|
@@ -35,7 +32,7 @@ export interface ControllerToolInventoryEntry {
|
|
|
35
32
|
*/
|
|
36
33
|
export interface ControllerExposureSnapshot {
|
|
37
34
|
access: ControllerAccessState;
|
|
38
|
-
toolset:
|
|
35
|
+
toolset: 'full';
|
|
39
36
|
profile: ControllerToolProfile;
|
|
40
37
|
definitions: McpToolDefinition[];
|
|
41
38
|
toolNames: string[];
|
|
@@ -66,17 +63,6 @@ export interface ControllerToolSurfaceStatus {
|
|
|
66
63
|
ready: boolean;
|
|
67
64
|
}
|
|
68
65
|
|
|
69
|
-
/**
|
|
70
|
-
* Core and Advanced expose the same bounded default ChatGPT surface
|
|
71
|
-
* (DEFAULT_CONTROLLER_TOOL_NAMES). Full remains the exhaustive compatibility
|
|
72
|
-
* surface for legacy integrations; internal atomic handlers are never deleted.
|
|
73
|
-
*/
|
|
74
|
-
|
|
75
|
-
/** Historical Advanced name retained for compatibility. */
|
|
76
|
-
export const ADVANCED_CONTROLLER_TOOL_NAMES = DEFAULT_CONTROLLER_TOOL_NAMES;
|
|
77
|
-
|
|
78
|
-
const DEFAULT_CONTROLLER_TOOL_SET = new Set<string>(DEFAULT_CONTROLLER_TOOL_NAMES);
|
|
79
|
-
|
|
80
66
|
interface StaticControllerExposureSnapshot {
|
|
81
67
|
definitions: McpToolDefinition[];
|
|
82
68
|
toolNames: string[];
|
|
@@ -101,32 +87,12 @@ function pruneStaticExposureCache(): void {
|
|
|
101
87
|
}
|
|
102
88
|
}
|
|
103
89
|
|
|
104
|
-
export function normalizeMcpToolset(value: unknown): McpToolset {
|
|
105
|
-
if (value === 'full' || value === 'advanced' || value === 'core' || value === 'facade') return value;
|
|
106
|
-
return 'advanced';
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* null means expose every registered definition. Profile membership only
|
|
111
|
-
* changes schema discovery; authorization remains an independent policy.
|
|
112
|
-
*/
|
|
113
|
-
export function controllerToolNamesForToolset(
|
|
114
|
-
toolset: McpToolset,
|
|
115
|
-
_ctx?: MultiRepositoryMcpToolContext,
|
|
116
|
-
): readonly string[] | null {
|
|
117
|
-
if (toolset === 'full') return null;
|
|
118
|
-
if (toolset === 'facade') return PREFERRED_FACADE_TOOL_NAMES;
|
|
119
|
-
return DEFAULT_CONTROLLER_TOOL_NAMES;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
90
|
export function resolveControllerAccessStateForContext(
|
|
123
91
|
ctx: MultiRepositoryMcpToolContext,
|
|
124
92
|
): ControllerAccessState {
|
|
125
93
|
return resolveControllerAccessState({
|
|
126
94
|
controllerHome: ctx.controllerHome,
|
|
127
95
|
repoRoot: ctx.explicitRepository?.canonicalRoot,
|
|
128
|
-
toolsetOverride: ctx.toolset,
|
|
129
|
-
toolsetLocked: ctx.toolsetLocked ?? false,
|
|
130
96
|
});
|
|
131
97
|
}
|
|
132
98
|
|
|
@@ -164,7 +130,6 @@ function staticExposureCacheKey(ctx: MultiRepositoryMcpToolContext): string {
|
|
|
164
130
|
controllerHome: ctx.controllerHome,
|
|
165
131
|
repoRoot: ctx.repoRoot,
|
|
166
132
|
explicitRepositoryId: ctx.explicitRepository?.repoId,
|
|
167
|
-
toolset: ctx.toolset,
|
|
168
133
|
profile: ctx.policy.profile,
|
|
169
134
|
enableChatgptBrowser: ctx.enableChatgptBrowser === true,
|
|
170
135
|
devAgentRunner: ctx.policy.execution.agentRunner,
|
|
@@ -183,25 +148,20 @@ function buildStaticControllerExposureSnapshot(
|
|
|
183
148
|
accessToolDefinitions,
|
|
184
149
|
repositoryToolDefinitions,
|
|
185
150
|
);
|
|
186
|
-
const rawDefinitions =
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
)
|
|
192
|
-
: currentDefinitions;
|
|
151
|
+
const rawDefinitions = currentDefinitions.concat(
|
|
152
|
+
buildMultiRepositoryToolDefinitions(ctx).filter(
|
|
153
|
+
(legacy) => !currentDefinitions.some((current) => current.name === legacy.name),
|
|
154
|
+
),
|
|
155
|
+
);
|
|
193
156
|
const unique = uniqueDefinitions(rawDefinitions);
|
|
194
|
-
const
|
|
195
|
-
const expectedToolNames = allowed === null
|
|
196
|
-
? unique.definitions.map((tool) => tool.name)
|
|
197
|
-
: [...new Set(allowed)];
|
|
157
|
+
const expectedToolNames = unique.definitions.map((tool) => tool.name);
|
|
198
158
|
const definitionByName = new Map(unique.definitions.map((definition) => [definition.name, definition]));
|
|
199
159
|
const definitions = expectedToolNames
|
|
200
160
|
.map((name) => definitionByName.get(name))
|
|
201
161
|
.filter((definition): definition is McpToolDefinition => Boolean(definition))
|
|
202
162
|
// Fingerprint the exact definitions that ListTools returns. Shared transport
|
|
203
163
|
// contracts are injected here once rather than re-declared by domain registries.
|
|
204
|
-
.map((definition) => injectCognitionSettlementFields(
|
|
164
|
+
.map((definition) => injectCognitionSettlementFields(injectDurableCommandFields(definition)));
|
|
205
165
|
const actualToolNames = definitions.map((tool) => tool.name);
|
|
206
166
|
const actualSet = new Set(actualToolNames);
|
|
207
167
|
const expectedSet = new Set(expectedToolNames);
|
|
@@ -249,15 +209,10 @@ function capabilityForToolName(name: string): string {
|
|
|
249
209
|
return 'compatibility';
|
|
250
210
|
}
|
|
251
211
|
|
|
252
|
-
function profileForToolset(toolset: McpToolset): ControllerToolProfile {
|
|
253
|
-
return toolset === 'full' ? 'full' : toolset === 'facade' ? 'facade' : toolset === 'core' ? 'core' : 'advanced';
|
|
254
|
-
}
|
|
255
|
-
|
|
256
212
|
export function controllerToolInventory(
|
|
257
213
|
toolNames: readonly string[],
|
|
258
|
-
toolset: McpToolset,
|
|
259
214
|
): ControllerToolInventoryEntry[] {
|
|
260
|
-
const profile =
|
|
215
|
+
const profile = 'full' as const;
|
|
261
216
|
return toolNames.map((name) => ({
|
|
262
217
|
name,
|
|
263
218
|
profile,
|
|
@@ -270,19 +225,13 @@ export function clearControllerExposureCacheForTest(): void {
|
|
|
270
225
|
staticControllerExposureCache.clear();
|
|
271
226
|
}
|
|
272
227
|
|
|
273
|
-
export function allControllerToolDefinitions(ctx: MultiRepositoryMcpToolContext): McpToolDefinition[] {
|
|
274
|
-
return uniqueDefinitions(
|
|
275
|
-
runtimeToolDefinitions.concat(executionToolDefinitions, processToolDefinitions, accessToolDefinitions, repositoryToolDefinitions, buildMultiRepositoryToolDefinitions(ctx)),
|
|
276
|
-
).definitions.map((definition) => injectCognitionSettlementFields(injectAutomationEnvelopeFields(injectDurableCommandFields(definition))));
|
|
277
|
-
}
|
|
278
|
-
|
|
279
228
|
export function controllerExposureSnapshot(ctx: MultiRepositoryMcpToolContext): ControllerExposureSnapshot {
|
|
280
229
|
const staticSnapshot = staticControllerExposureSnapshot(ctx);
|
|
281
230
|
return {
|
|
282
231
|
access: resolveControllerAccessStateForContext(ctx),
|
|
283
|
-
toolset:
|
|
284
|
-
profile:
|
|
285
|
-
inventory: controllerToolInventory(staticSnapshot.actualToolNames
|
|
232
|
+
toolset: 'full',
|
|
233
|
+
profile: 'full',
|
|
234
|
+
inventory: controllerToolInventory(staticSnapshot.actualToolNames),
|
|
286
235
|
...staticSnapshot,
|
|
287
236
|
};
|
|
288
237
|
}
|
|
@@ -305,29 +254,6 @@ export function controllerExposedToolNames(ctx: MultiRepositoryMcpToolContext):
|
|
|
305
254
|
return controllerExposureSnapshot(ctx).actualToolNames;
|
|
306
255
|
}
|
|
307
256
|
|
|
308
|
-
export function classifyControllerToolExposure(toolName: string): ToolExposureClass {
|
|
309
|
-
if ((PREFERRED_FACADE_TOOL_NAMES as readonly string[]).includes(toolName)) return 'facade';
|
|
310
|
-
if (toolName.startsWith('rh_')) return 'facade';
|
|
311
|
-
if (DEFAULT_CONTROLLER_TOOL_SET.has(toolName)) return 'advanced';
|
|
312
|
-
return 'compatibility';
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
export function controllerToolExposureMetadata(toolNames: readonly string[]): {
|
|
316
|
-
preferredTools: string[];
|
|
317
|
-
advancedTools: string[];
|
|
318
|
-
compatibilityTools: string[];
|
|
319
|
-
classification: Record<string, ToolExposureClass>;
|
|
320
|
-
} {
|
|
321
|
-
const classification: Record<string, ToolExposureClass> = {};
|
|
322
|
-
for (const name of toolNames) classification[name] = classifyControllerToolExposure(name);
|
|
323
|
-
return {
|
|
324
|
-
preferredTools: toolNames.filter((name) => classification[name] === 'facade'),
|
|
325
|
-
advancedTools: toolNames.filter((name) => classification[name] === 'advanced'),
|
|
326
|
-
compatibilityTools: toolNames.filter((name) => classification[name] === 'compatibility'),
|
|
327
|
-
classification,
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
|
|
331
257
|
export function exposedControllerToolDefinitions(ctx: MultiRepositoryMcpToolContext): McpToolDefinition[] {
|
|
332
258
|
return controllerExposureSnapshot(ctx).definitions;
|
|
333
259
|
}
|
|
@@ -5,21 +5,21 @@ Keep this file focused on the local contract for this primary functional block.
|
|
|
5
5
|
<!-- BEGIN ARCHITECTURE CONTRACT -->
|
|
6
6
|
## Architecture Contract
|
|
7
7
|
|
|
8
|
-
- Functional block: `
|
|
8
|
+
- Functional block: `adapters/mcp/transports`
|
|
9
9
|
- Capability ID: `mcp-http-transport-lifecycle`
|
|
10
|
-
- Matched prefix: `
|
|
10
|
+
- Matched prefix: `adapters/mcp/transports`
|
|
11
11
|
- Architecture domain: `controller-runtime`
|
|
12
12
|
- Architecture capability: `transport-lifecycle`
|
|
13
13
|
- Architecture module: `docs/architecture/modules/controller-runtime/transport-lifecycle.md`
|
|
14
14
|
- Last architecture event: 2026-07-18T07:08:47.902Z
|
|
15
|
-
- Last changed path: `
|
|
15
|
+
- Last changed path: `adapters/mcp/transports`
|
|
16
16
|
- Severity: medium
|
|
17
17
|
- Change type: capability-config
|
|
18
18
|
- Module responsibility: Keep this block aligned with the local boundary described by surrounding human-owned context.
|
|
19
|
-
- Entrypoints: `
|
|
19
|
+
- Entrypoints: `adapters/mcp/transports`
|
|
20
20
|
- Allowed dependencies: Follow root `AGENTS.md` / `CLAUDE.md` and this local contract.
|
|
21
21
|
- Forbidden dependencies: Do not cross sibling app/service/package boundaries without an architecture snapshot or explicit plan.
|
|
22
|
-
- Runtime path: `
|
|
22
|
+
- Runtime path: `adapters/mcp/transports`
|
|
23
23
|
- LSP/tooling profile: `typescript-lsp`
|
|
24
24
|
- Verification: Use root required checks plus local commands recorded in this capability contract.
|
|
25
25
|
- Latest snapshot: `(none yet)`
|
|
@@ -5,21 +5,21 @@ Keep this file focused on the local contract for this primary functional block.
|
|
|
5
5
|
<!-- BEGIN ARCHITECTURE CONTRACT -->
|
|
6
6
|
## Architecture Contract
|
|
7
7
|
|
|
8
|
-
- Functional block: `
|
|
8
|
+
- Functional block: `adapters/mcp/transports`
|
|
9
9
|
- Capability ID: `mcp-http-transport-lifecycle`
|
|
10
|
-
- Matched prefix: `
|
|
10
|
+
- Matched prefix: `adapters/mcp/transports`
|
|
11
11
|
- Architecture domain: `controller-runtime`
|
|
12
12
|
- Architecture capability: `transport-lifecycle`
|
|
13
13
|
- Architecture module: `docs/architecture/modules/controller-runtime/transport-lifecycle.md`
|
|
14
14
|
- Last architecture event: 2026-07-18T07:08:47.902Z
|
|
15
|
-
- Last changed path: `
|
|
15
|
+
- Last changed path: `adapters/mcp/transports`
|
|
16
16
|
- Severity: medium
|
|
17
17
|
- Change type: capability-config
|
|
18
18
|
- Module responsibility: Keep this block aligned with the local boundary described by surrounding human-owned context.
|
|
19
|
-
- Entrypoints: `
|
|
19
|
+
- Entrypoints: `adapters/mcp/transports`
|
|
20
20
|
- Allowed dependencies: Follow root `AGENTS.md` / `CLAUDE.md` and this local contract.
|
|
21
21
|
- Forbidden dependencies: Do not cross sibling app/service/package boundaries without an architecture snapshot or explicit plan.
|
|
22
|
-
- Runtime path: `
|
|
22
|
+
- Runtime path: `adapters/mcp/transports`
|
|
23
23
|
- LSP/tooling profile: `typescript-lsp`
|
|
24
24
|
- Verification: Use root required checks plus local commands recorded in this capability contract.
|
|
25
25
|
- Latest snapshot: `(none yet)`
|