@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
|
@@ -12,7 +12,7 @@ import { isTerminalSemanticWorkState } from '../facade/types';
|
|
|
12
12
|
import { updateExecutionSession, type ExecutionSessionContext } from './session-store';
|
|
13
13
|
import { currentPermissionSnapshotVersion, validateWorkHandle } from './validation';
|
|
14
14
|
import { withWorkPrepareRequest } from './work-prepare-request-store';
|
|
15
|
-
import { markWorkHandleFailed, newWorkId, readWorkHandle, writeWorkHandle, type WorkFinalizationStages, type WorkHandleState } from './work-handle-store';
|
|
15
|
+
import { markWorkHandleFailed, newWorkId, readWorkHandle, relocateWorkHandlePlacementAtomically, writeWorkHandle, type WorkFinalizationStages, type WorkHandleState } from './work-handle-store';
|
|
16
16
|
import { createGoalDelegation } from '../governance/authorization';
|
|
17
17
|
import { compactHandle, contractFor, findWorkHandle, gitHead, gitIsAncestor, identityFor, requireSession } from './work-execution-support';
|
|
18
18
|
|
|
@@ -42,6 +42,11 @@ function boundedStringArray(value: unknown, limit: number): string[] {
|
|
|
42
42
|
return Array.isArray(value) ? value.map(String).slice(0, limit) : [];
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
function requestedWorkPrepareIsolation(args: Record<string, unknown>): 'reuse' | 'new_worktree' | 'auto' | undefined {
|
|
46
|
+
if (!Object.prototype.hasOwnProperty.call(args, 'isolation')) return undefined;
|
|
47
|
+
return args.isolation === 'reuse' || args.isolation === 'new_worktree' || args.isolation === 'auto' ? args.isolation : 'auto';
|
|
48
|
+
}
|
|
49
|
+
|
|
45
50
|
function workPrepareFingerprint(input: {
|
|
46
51
|
repoId: string;
|
|
47
52
|
requestedCheckoutId?: string;
|
|
@@ -112,7 +117,12 @@ function adoptExplicitSuccessorHead(
|
|
|
112
117
|
if (!expectedPreviousHead || !adoptCandidateHead) {
|
|
113
118
|
throw new Error('WORK_HANDLE_SUCCESSOR_ADOPTION_PAIR_REQUIRED: expected_previous_head and adopt_candidate_head must be supplied together');
|
|
114
119
|
}
|
|
115
|
-
|
|
120
|
+
// A failed validation attempt may need an explicit, audited successor
|
|
121
|
+
// adoption before it can retry against the current checkout. Keep its
|
|
122
|
+
// failed state: only a fresh valid check may restore execution authority.
|
|
123
|
+
const retryableValidationFailure = existing.state === 'failed'
|
|
124
|
+
&& existing.finalization.validation === 'failed';
|
|
125
|
+
if (existing.state !== 'prepared' && existing.state !== 'editing' && !retryableValidationFailure) {
|
|
116
126
|
throw new Error(`WORK_HANDLE_SUCCESSOR_ADOPTION_STATE_INVALID: ${existing.state}`);
|
|
117
127
|
}
|
|
118
128
|
if (existing.expectedHead !== expectedPreviousHead) {
|
|
@@ -150,7 +160,8 @@ function adoptExplicitSuccessorHead(
|
|
|
150
160
|
}
|
|
151
161
|
const candidate: WorkHandleState = {
|
|
152
162
|
...existing,
|
|
153
|
-
|
|
163
|
+
// Successor adoption advances the Work candidate, not the delivery target.
|
|
164
|
+
// Preserve the canonical delivery base until authorized delivery or rebase.
|
|
154
165
|
expectedHead: adoptCandidateHead,
|
|
155
166
|
validationRun: undefined,
|
|
156
167
|
validatedInputFingerprint: undefined,
|
|
@@ -161,6 +172,86 @@ function adoptExplicitSuccessorHead(
|
|
|
161
172
|
return writeWorkHandle(ctx.controllerHome, candidate);
|
|
162
173
|
}
|
|
163
174
|
|
|
175
|
+
function relocateExistingWorkToManagedCheckout(
|
|
176
|
+
ctx: McpExecutionContext,
|
|
177
|
+
args: Record<string, unknown>,
|
|
178
|
+
session: ExecutionSessionContext,
|
|
179
|
+
repository: ReturnType<typeof selectedRepository>,
|
|
180
|
+
existing: WorkHandleState,
|
|
181
|
+
): Record<string, unknown> {
|
|
182
|
+
const prior = typeof args.expected_previous_head === 'string' ? args.expected_previous_head.trim() : '';
|
|
183
|
+
const candidate = typeof args.adopt_candidate_head === 'string' ? args.adopt_candidate_head.trim() : '';
|
|
184
|
+
const baseRef = typeof args.base_ref === 'string' ? args.base_ref.trim() : '';
|
|
185
|
+
if (!prior || !candidate || baseRef !== candidate || !/^[0-9a-f]{40}$/.test(candidate)) {
|
|
186
|
+
throw new Error('WORK_RELOCATION_EXACT_HEADS_REQUIRED: supply expected_previous_head and matching base_ref/adopt_candidate_head');
|
|
187
|
+
}
|
|
188
|
+
if (existing.principalId !== session.principalId) throw new Error('WORK_HANDLE_ACCESS_DENIED');
|
|
189
|
+
if (existing.expectedHead !== prior && !(existing.managedWorktree && existing.expectedHead === candidate)) {
|
|
190
|
+
throw new Error('WORK_RELOCATION_PREVIOUS_HEAD_MISMATCH');
|
|
191
|
+
}
|
|
192
|
+
if (existing.managedWorktree) {
|
|
193
|
+
if (existing.expectedHead !== candidate) throw new Error('WORK_RELOCATION_ALREADY_ISOLATED');
|
|
194
|
+
validateWorkHandle(ctx.controllerHome, existing, identityFor(ctx, args), 'cheap', 'inspect');
|
|
195
|
+
updateExecutionSession(ctx.controllerHome, identityFor(ctx, args), {
|
|
196
|
+
activeRepositoryId: existing.repositoryId, activeCheckoutId: existing.checkoutId,
|
|
197
|
+
activeWorkId: existing.workId, permissionSnapshotVersion: existing.permissionSnapshotVersion,
|
|
198
|
+
});
|
|
199
|
+
return { session: requireSession(ctx, args), work: compactHandle(existing), reused: true, relocated: true };
|
|
200
|
+
}
|
|
201
|
+
if (existing.state !== 'prepared' && existing.state !== 'editing') throw new Error('WORK_RELOCATION_STATE_INVALID');
|
|
202
|
+
if (existing.finalization.validation !== 'pending' || existing.finalization.commit !== 'pending' || existing.finalization.merge !== 'pending'
|
|
203
|
+
|| existing.finalization.worktreeCleanup !== 'pending' || existing.finalization.branchCleanup !== 'pending'
|
|
204
|
+
|| existing.cleanupReceipt || existing.validatedInputFingerprint || existing.validationRun) {
|
|
205
|
+
throw new Error('WORK_RELOCATION_FINALIZATION_IN_PROGRESS');
|
|
206
|
+
}
|
|
207
|
+
const contract = getWorkContract({ controllerHome: ctx.controllerHome, repoId: existing.repositoryId }, existing.workId);
|
|
208
|
+
if (!contract || contract.semanticState !== 'open' || contract.completionReceipt || contract.completionOutcome
|
|
209
|
+
|| contract.checkoutId !== existing.checkoutId) throw new Error('WORK_RELOCATION_CONTRACT_MISMATCH');
|
|
210
|
+
if (existing.checkoutId !== repository.activeCheckoutId || existing.worktreePath !== repository.canonicalRoot
|
|
211
|
+
|| existing.branch !== repositoryGitStatus(repository).branch) throw new Error('WORK_RELOCATION_SOURCE_MISMATCH');
|
|
212
|
+
if (!gitIsAncestor(existing.worktreePath, prior, candidate)) throw new Error('WORK_RELOCATION_NONLINEAR');
|
|
213
|
+
const changedPaths = gitPathSet(existing.worktreePath, ['diff', '--name-only', prior + '..' + candidate], 'WORK_RELOCATION_DIFF_UNAVAILABLE');
|
|
214
|
+
const dirtyPaths = currentDirtyPaths(existing.worktreePath);
|
|
215
|
+
const overlap = [...changedPaths].filter((path) => dirtyPaths.has(path));
|
|
216
|
+
if (overlap.length) throw new Error('WORK_RELOCATION_DIRTY_OVERLAP: ' + overlap.sort().join(','));
|
|
217
|
+
if (listRecoverableProcessRecords(ctx.controllerHome, existing.repositoryId).some((record) => record.workId === existing.workId)) {
|
|
218
|
+
throw new Error('WORK_RELOCATION_ACTIVE_PROCESS');
|
|
219
|
+
}
|
|
220
|
+
const requestId = typeof args.request_id === 'string' ? args.request_id.trim() : '';
|
|
221
|
+
if (!requestId) throw new Error('WORK_RELOCATION_REQUEST_ID_REQUIRED');
|
|
222
|
+
// A deterministic request identity makes physical worktree creation safe to
|
|
223
|
+
// resume after a process crash before the authoritative database transaction.
|
|
224
|
+
const workspace = ensureManagedWorkspace(ctx.controllerHome, repository, {
|
|
225
|
+
requestId: 'relocate:' + existing.workId + ':' + candidate,
|
|
226
|
+
title: 'Relocate existing Work to managed checkout',
|
|
227
|
+
associatedWorkId: existing.workId,
|
|
228
|
+
baseRef: candidate,
|
|
229
|
+
prepareDependencies: false,
|
|
230
|
+
});
|
|
231
|
+
if (!workspace.managed || !workspace.checkoutId || !workspace.root || !workspace.branch) {
|
|
232
|
+
throw new Error('WORK_RELOCATION_TARGET_NOT_MANAGED');
|
|
233
|
+
}
|
|
234
|
+
const selectedTarget = resolveRepositorySelection({
|
|
235
|
+
repoId: existing.repositoryId, checkoutId: workspace.checkoutId,
|
|
236
|
+
controllerHome: ctx.controllerHome, allowSoleRepository: false,
|
|
237
|
+
});
|
|
238
|
+
const targetStatus = repositoryGitStatus(selectedTarget);
|
|
239
|
+
if (!targetStatus.clean || targetStatus.head !== candidate || targetStatus.branch !== workspace.branch
|
|
240
|
+
|| workspace.checkoutId === existing.checkoutId || selectedTarget.canonicalRoot !== workspace.root) {
|
|
241
|
+
throw new Error('WORK_RELOCATION_TARGET_CHANGED');
|
|
242
|
+
}
|
|
243
|
+
const refreshed = relocateWorkHandlePlacementAtomically(ctx.controllerHome, existing, {
|
|
244
|
+
checkoutId: workspace.checkoutId, root: workspace.root,
|
|
245
|
+
branch: workspace.branch, head: candidate,
|
|
246
|
+
});
|
|
247
|
+
updateExecutionSession(ctx.controllerHome, identityFor(ctx, args), {
|
|
248
|
+
activeRepositoryId: refreshed.repositoryId, activeCheckoutId: refreshed.checkoutId,
|
|
249
|
+
activeWorkId: refreshed.workId, permissionSnapshotVersion: refreshed.permissionSnapshotVersion,
|
|
250
|
+
});
|
|
251
|
+
return { session: requireSession(ctx, args), work: compactHandle(refreshed), relocated: true,
|
|
252
|
+
previousCheckoutId: existing.checkoutId, previousHead: prior, currentHead: candidate };
|
|
253
|
+
}
|
|
254
|
+
|
|
164
255
|
export function prepareWork(ctx: McpExecutionContext, args: Record<string, unknown>): Record<string, unknown> {
|
|
165
256
|
const session = requireSession(ctx, args);
|
|
166
257
|
const repository = selectedRepository(ctx, session, args, true);
|
|
@@ -168,10 +259,23 @@ export function prepareWork(ctx: McpExecutionContext, args: Record<string, unkno
|
|
|
168
259
|
updateExecutionSession(ctx.controllerHome, identityFor(ctx, args), { activeRepositoryId: repository.repoId, activeCheckoutId: repository.activeCheckoutId, permissionSnapshotVersion: currentPermissionSnapshotVersion(ctx.controllerHome, repository.repoId) });
|
|
169
260
|
}
|
|
170
261
|
const existingId = typeof args.work_id === 'string' ? args.work_id.trim() : '';
|
|
262
|
+
if (args.relocate_to_new_worktree === true && !existingId) throw new Error('WORK_RELOCATION_EXISTING_WORK_ID_REQUIRED');
|
|
263
|
+
const requestedIsolation = requestedWorkPrepareIsolation(args);
|
|
171
264
|
if (existingId) {
|
|
172
265
|
const existing = readWorkHandle(ctx.controllerHome, repository.repoId, existingId)
|
|
173
266
|
?? findWorkHandle(ctx, session, { ...args, work_id: existingId, repo_id: repository.repoId });
|
|
174
267
|
if (existing.principalId !== session.principalId) throw new Error('WORK_HANDLE_ACCESS_DENIED');
|
|
268
|
+
if (args.relocate_to_new_worktree === true) {
|
|
269
|
+
if (requestedIsolation !== undefined) throw new Error('WORK_RELOCATION_ISOLATION_CONFLICT');
|
|
270
|
+
return relocateExistingWorkToManagedCheckout(ctx, args, session, repository, existing);
|
|
271
|
+
}
|
|
272
|
+
if (requestedIsolation !== undefined) {
|
|
273
|
+
const requestedWorkspaceMode = requestedIsolation === 'reuse' ? 'current' : 'isolated';
|
|
274
|
+
const existingWorkspaceMode = existing.managedWorktree ? 'isolated' : 'current';
|
|
275
|
+
if (requestedWorkspaceMode !== existingWorkspaceMode) {
|
|
276
|
+
throw new Error(`WORK_PREPARE_PLACEMENT_CONFLICT: ${existingId}; existing=${existingWorkspaceMode}; requested=${requestedWorkspaceMode}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
175
279
|
const adopted = adoptExplicitSuccessorHead(ctx, args, repository, existing);
|
|
176
280
|
const active = adopted ?? existing;
|
|
177
281
|
if (!adopted) validateWorkHandle(ctx.controllerHome, active, identityFor(ctx, args), 'cheap', 'inspect');
|
|
@@ -186,7 +290,7 @@ export function prepareWork(ctx: McpExecutionContext, args: Record<string, unkno
|
|
|
186
290
|
|
|
187
291
|
const requestId = typeof args.request_id === 'string' ? args.request_id.trim() : '';
|
|
188
292
|
if (!requestId) throw new Error('WORK_PREPARE_REQUEST_ID_REQUIRED: new work preparation requires request_id');
|
|
189
|
-
const isolation = args
|
|
293
|
+
const isolation = requestedWorkPrepareIsolation(args) ?? 'auto';
|
|
190
294
|
const objective = String(args.objective ?? 'Controller-managed repository work').trim().slice(0, 2_000);
|
|
191
295
|
const goalId = typeof args.goal_id === 'string' && args.goal_id.trim() ? args.goal_id.trim() : undefined;
|
|
192
296
|
const acceptanceCriteria = boundedStringArray(args.acceptance_criteria, 20);
|
|
@@ -27,7 +27,7 @@ function isSuccessfulWorkRepositoryProcess(
|
|
|
27
27
|
return record.workId === input.workId
|
|
28
28
|
&& record.checkoutId === input.checkoutId
|
|
29
29
|
&& record.origin?.surface === 'command'
|
|
30
|
-
&& record.origin.toolName === '
|
|
30
|
+
&& record.origin.toolName === 'execute_command'
|
|
31
31
|
&& record.origin.correlationId === input.workId
|
|
32
32
|
&& isManagedProcessTerminal(record)
|
|
33
33
|
&& record.terminalWritten === true
|
|
@@ -42,7 +42,7 @@ function isSuccessfulWorkRepositoryProcess(
|
|
|
42
42
|
* Re-derive bounded completion evidence from the canonical durable Process store.
|
|
43
43
|
*
|
|
44
44
|
* This deliberately does not create a second evidence authority. A qualifying
|
|
45
|
-
* record must be the terminal successful
|
|
45
|
+
* record must be the terminal successful execute_command Process for
|
|
46
46
|
* the exact Work + checkout, and the command-origin correlation must still name
|
|
47
47
|
* the same Work. Lightweight handles never enter listProcessRecords(), so they
|
|
48
48
|
* cannot satisfy this contract.
|
|
@@ -170,6 +170,11 @@ function createVerifiedBundle(controllerHome: string, handle: WorkHandleState, t
|
|
|
170
170
|
}
|
|
171
171
|
const verified = git(targetRoot, ['bundle', 'verify', path], 60_000);
|
|
172
172
|
if (!verified.ok) throw new Error(verified.stderr || 'git bundle verify failed');
|
|
173
|
+
const branchHead = git(targetRoot, ['rev-parse', '--verify', `refs/heads/${handle.branch}^{commit}`]);
|
|
174
|
+
const bundleHead = git(targetRoot, ['bundle', 'list-heads', path, `refs/heads/${handle.branch}`]);
|
|
175
|
+
if (!branchHead.ok || !bundleHead.ok || bundleHead.stdout !== `${branchHead.stdout} refs/heads/${handle.branch}`) {
|
|
176
|
+
throw new Error('BRANCH_BUNDLE_HEAD_MISMATCH: verified bundle does not preserve the current branch tip');
|
|
177
|
+
}
|
|
173
178
|
return { path, sha256: hashText(readFileSync(path)) };
|
|
174
179
|
}
|
|
175
180
|
|
|
@@ -489,9 +494,13 @@ function prepareManagedBranchPreservation(
|
|
|
489
494
|
current: WorkHandleState,
|
|
490
495
|
target: ReturnType<typeof getRepository>,
|
|
491
496
|
targetBranch: string,
|
|
492
|
-
): { uniqueCommits: number; branchPreserved: boolean } {
|
|
497
|
+
): { uniqueCommits: number; branchPreserved: boolean; branchHead?: string } {
|
|
493
498
|
let uniqueCommits = 0;
|
|
499
|
+
let branchHead: string | undefined;
|
|
494
500
|
if (branchExists(target.canonicalRoot, current.branch)) {
|
|
501
|
+
const observed = git(target.canonicalRoot, ['rev-parse', '--verify', `refs/heads/${current.branch}^{commit}`]);
|
|
502
|
+
if (!observed.ok || !observed.stdout) addBlocker(receipt, 'BRANCH_REVISION_UNKNOWN');
|
|
503
|
+
else branchHead = observed.stdout;
|
|
495
504
|
if (!branchExists(target.canonicalRoot, targetBranch)) {
|
|
496
505
|
addBlocker(receipt, `TARGET_BRANCH_MISSING: ${targetBranch}`);
|
|
497
506
|
} else {
|
|
@@ -502,11 +511,12 @@ function prepareManagedBranchPreservation(
|
|
|
502
511
|
}
|
|
503
512
|
receipt.branchCleanup.uniqueCommits = uniqueCommits;
|
|
504
513
|
|
|
514
|
+
const retirement = receipt.preservation.bundleRetirement;
|
|
505
515
|
let branchPreserved = Boolean(
|
|
506
|
-
|
|
507
|
-
||
|
|
516
|
+
branchHead && retirement?.protectedRevision === branchHead
|
|
517
|
+
&& (retirement.status === 'not_needed' || retirement.status === 'removed'),
|
|
508
518
|
);
|
|
509
|
-
if (receipt.preservation.bundlePath && !branchPreserved) {
|
|
519
|
+
if (branchHead && receipt.preservation.bundlePath && !branchPreserved) {
|
|
510
520
|
try {
|
|
511
521
|
const bundle = createVerifiedBundle(input.controllerHome, current, target.canonicalRoot);
|
|
512
522
|
if (receipt.preservation.bundleSha256 && receipt.preservation.bundleSha256 !== bundle.sha256) {
|
|
@@ -519,7 +529,7 @@ function prepareManagedBranchPreservation(
|
|
|
519
529
|
}
|
|
520
530
|
}
|
|
521
531
|
if (uniqueCommits > 0 && !branchPreserved && receipt.blockers.length === 0) {
|
|
522
|
-
const proof = proveWorkPreservationContained(target.canonicalRoot,
|
|
532
|
+
const proof = proveWorkPreservationContained(target.canonicalRoot, current, targetBranch, branchHead);
|
|
523
533
|
if (proof.contained) {
|
|
524
534
|
receipt.preservation.bundleRetirement = {
|
|
525
535
|
status: 'not_needed',
|
|
@@ -547,7 +557,7 @@ function prepareManagedBranchPreservation(
|
|
|
547
557
|
}
|
|
548
558
|
}
|
|
549
559
|
}
|
|
550
|
-
return { uniqueCommits, branchPreserved };
|
|
560
|
+
return { uniqueCommits, branchPreserved, branchHead };
|
|
551
561
|
}
|
|
552
562
|
|
|
553
563
|
function applyManagedBranchCleanup(
|
|
@@ -559,6 +569,7 @@ function applyManagedBranchCleanup(
|
|
|
559
569
|
receipt: WorkCleanupReceipt,
|
|
560
570
|
uniqueCommits: number,
|
|
561
571
|
branchPreserved: boolean,
|
|
572
|
+
expectedBranchHead: string | undefined,
|
|
562
573
|
): void {
|
|
563
574
|
if (!deleteBranch) {
|
|
564
575
|
receipt.branchCleanup.status = 'retained';
|
|
@@ -578,6 +589,10 @@ function applyManagedBranchCleanup(
|
|
|
578
589
|
receipt.branchCleanup.status = 'retained';
|
|
579
590
|
receipt.branchCleanup.reason = 'Unique commits are not archived.';
|
|
580
591
|
addBlocker(receipt, `BRANCH_UNPRESERVED: ${current.branch}`);
|
|
592
|
+
} else if (!expectedBranchHead) {
|
|
593
|
+
receipt.branchCleanup.status = 'retained';
|
|
594
|
+
receipt.branchCleanup.reason = 'Exact branch revision is unavailable.';
|
|
595
|
+
addBlocker(receipt, 'BRANCH_REVISION_UNKNOWN');
|
|
581
596
|
} else {
|
|
582
597
|
// Branch deletion requires the canonical OwnedResource witness in addition
|
|
583
598
|
// to Git relation checks. Repository/ref shape alone is not cleanup authority.
|
|
@@ -594,12 +609,10 @@ function applyManagedBranchCleanup(
|
|
|
594
609
|
addBlocker(receipt, `OWNED_BRANCH_CLEANUP_FENCED: ${receipt.branchCleanup.reason}`);
|
|
595
610
|
return;
|
|
596
611
|
}
|
|
597
|
-
//
|
|
598
|
-
//
|
|
599
|
-
//
|
|
600
|
-
|
|
601
|
-
// proof (or a verified archive for unique commits), delete the ref directly.
|
|
602
|
-
const deleted = git(target.canonicalRoot, ['branch', '-D', current.branch]);
|
|
612
|
+
// Delete only the exact tip whose containment or bundle was proved above.
|
|
613
|
+
// A concurrent successor must retain its ref rather than inherit an older
|
|
614
|
+
// WorkHandle or preservation receipt's deletion authority.
|
|
615
|
+
const deleted = git(target.canonicalRoot, ['update-ref', '-d', `refs/heads/${current.branch}`, expectedBranchHead]);
|
|
603
616
|
if (!deleted.ok && branchExists(target.canonicalRoot, current.branch)) {
|
|
604
617
|
receipt.branchCleanup.status = 'failed';
|
|
605
618
|
receipt.branchCleanup.reason = deleted.stderr || 'branch delete failed';
|
|
@@ -671,6 +684,7 @@ function reconcileCleanedManagedBranchRetirement(
|
|
|
671
684
|
receipt,
|
|
672
685
|
preservation.uniqueCommits,
|
|
673
686
|
preservation.branchPreserved,
|
|
687
|
+
preservation.branchHead,
|
|
674
688
|
);
|
|
675
689
|
} else if (receipt.branchCleanup.status === 'pending') {
|
|
676
690
|
receipt.branchCleanup.status = 'retained';
|
|
@@ -975,7 +989,7 @@ export async function cleanupTerminalWork(input: TerminalWorkCleanupInput): Prom
|
|
|
975
989
|
receipt.worktree.status = 'already_removed';
|
|
976
990
|
}
|
|
977
991
|
|
|
978
|
-
const { uniqueCommits, branchPreserved } = prepareManagedBranchPreservation(
|
|
992
|
+
const { uniqueCommits, branchPreserved, branchHead } = prepareManagedBranchPreservation(
|
|
979
993
|
input,
|
|
980
994
|
receipt,
|
|
981
995
|
current,
|
|
@@ -1049,6 +1063,7 @@ export async function cleanupTerminalWork(input: TerminalWorkCleanupInput): Prom
|
|
|
1049
1063
|
receipt,
|
|
1050
1064
|
uniqueCommits,
|
|
1051
1065
|
branchPreserved,
|
|
1066
|
+
branchHead,
|
|
1052
1067
|
);
|
|
1053
1068
|
|
|
1054
1069
|
const pruned = git(target.canonicalRoot, ['worktree', 'prune']);
|
|
@@ -120,9 +120,13 @@ function settleInfrastructureFailure(
|
|
|
120
120
|
handle: WorkHandleState,
|
|
121
121
|
summary: string,
|
|
122
122
|
): WorkValidationReconciliation {
|
|
123
|
-
|
|
123
|
+
// Infrastructure/receipt uncertainty invalidates validation authority,
|
|
124
|
+
// not the underlying Work. Resume the pre-validation state so the same Work
|
|
125
|
+
// can repair and retry without opening a replacement lifecycle.
|
|
126
|
+
const next = transitionWorkHandle(controllerHome, handle, handle.validationRun?.resumeState ?? 'editing', {
|
|
124
127
|
finalization: { ...handle.finalization, validation: 'failed', failureCode: undefined, lastError: summary },
|
|
125
128
|
validationRun: undefined,
|
|
129
|
+
validatedInputFingerprint: undefined,
|
|
126
130
|
failureReason: summary,
|
|
127
131
|
});
|
|
128
132
|
projectWorkValidationOutcome(controllerHome, next, 'infrastructure_failure', summary);
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
import { dirname, join, resolve, sep } from 'path';
|
|
19
19
|
import { spawnSync } from 'child_process';
|
|
20
20
|
import { repositoryControllerRoot } from '../../../cli/repositories/controller-home';
|
|
21
|
-
import { globMatches, normalizeMcpRelativePath } from '
|
|
21
|
+
import { globMatches, normalizeMcpRelativePath } from '../../../../adapters/mcp/paths';
|
|
22
22
|
import { sanitizeFileComponent } from '../../shared/json-files';
|
|
23
23
|
import { measureReclaimablePath, RUNTIME_LIFECYCLE_RETENTION_POLICY_VERSION } from '../lifecycle-retention-metrics';
|
|
24
24
|
|
|
@@ -647,6 +647,8 @@ export function getCoreCapabilityExecutionSchema(capabilityId: string): Record<s
|
|
|
647
647
|
session_id: { type: 'string', minLength: 1, maxLength: 256 },
|
|
648
648
|
work_id: { type: 'string', minLength: 1, maxLength: 256 },
|
|
649
649
|
target_branch: { type: 'string', minLength: 1, maxLength: 512 },
|
|
650
|
+
complete_work: { type: 'boolean' },
|
|
651
|
+
allow_merge_commit: { type: 'boolean' },
|
|
650
652
|
},
|
|
651
653
|
},
|
|
652
654
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { WorkContract, WorkReconciliationRecord } from './types';
|
|
2
|
-
import { redactMcpText } from '
|
|
2
|
+
import { redactMcpText } from '../../../../adapters/mcp/redaction';
|
|
3
3
|
|
|
4
4
|
export interface WorkContinuationSnapshot {
|
|
5
5
|
schemaVersion: 1;
|