@moretea-labs/forge 1.6.0 → 1.7.0
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 +2 -0
- package/CHANGELOG.md +26 -0
- package/CLAUDE.md +2 -0
- package/README.md +2 -2
- package/README.zh-CN.md +1 -1
- package/SKILL.md +2 -2
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/agents/openai.yaml +1 -1
- package/assets/hooks/hook-input.sh +11 -8
- package/assets/hooks/lib/session-state.sh +10 -7
- package/assets/hooks/lib/workflow-state.sh +13 -177
- package/assets/hooks/post-tool-observer.sh +8 -2
- package/assets/hooks/prompt-guard.sh +5 -81
- package/assets/hooks/session-start-context.sh +56 -1
- package/assets/partials/05-workflow.partial.md +1 -1
- package/assets/partials-agents/03-orchestration.partial.md +1 -1
- package/assets/plugin-registry.v1.json +1 -1
- package/assets/reference-configs/document-generation.md +1 -1
- package/assets/reference-configs/harness-overview.md +1 -1
- package/assets/reference-configs/sprint-contracts.md +3 -3
- package/assets/skill-version.json +2 -2
- package/assets/templates/contract.template.md +2 -7
- package/assets/templates/helpers/capture-plan.sh +2 -2
- package/assets/templates/helpers/check-task-workflow.sh +4 -4
- package/assets/templates/helpers/contract-worktree.sh +1 -21
- package/assets/templates/helpers/ensure-task-workflow.sh +11 -36
- package/assets/templates/helpers/migrate-project-template.sh +22 -45
- package/assets/templates/helpers/new-plan.sh +1 -1
- package/assets/templates/helpers/plan-to-todo.sh +12 -37
- package/assets/templates/helpers/ship-worktrees.sh +2 -29
- package/assets/templates/helpers/verify-contract.sh +1 -111
- package/assets/templates/helpers/verify-sprint.sh +3 -180
- package/assets/templates/plan.template.md +1 -1
- package/assets/templates/review.template.md +9 -34
- package/assets/workflow-contract.v1.json +10 -19
- package/docs/README.md +10 -10
- package/docs/architecture/CURRENT.md +170 -0
- package/docs/architecture/EVOLUTION.md +42 -0
- package/docs/architecture/current/README.md +4 -156
- package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +2 -2
- package/docs/architecture/decisions/20260823-immediate-controller-relay.md +53 -0
- package/docs/architecture/decisions/20260826-browser-runtime-v2.md +73 -0
- package/docs/architecture/history/README.md +7 -0
- package/docs/architecture/{chatgpt-handoff-facade.md → history/chatgpt-handoff-facade.md} +4 -0
- package/docs/architecture/{global-hook-runtime.md → history/global-hook-runtime.md} +7 -3
- package/docs/architecture/{ios-semantic-automation-provider-v2.md → history/ios-semantic-automation-provider-v2.md} +6 -2
- package/docs/architecture/history.md +3 -34
- package/docs/architecture/index.md +15 -98
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +1 -1
- package/docs/architecture/reviews/2026-08-22-semantic-harness-convergence-acceptance.md +39 -0
- package/docs/architecture/versions/1.6.md +38 -0
- package/docs/architecture/versions/1.7.md +41 -0
- package/docs/forge-chatgpt-browser-engine.md +2 -2
- package/docs/forge-chatgpt-mcp-setup.md +4 -28
- package/docs/forge-chatgpt-supervised-automation.md +3 -3
- package/docs/forge-github-issue-launcher.md +1 -1
- package/docs/forge-runtime-self-healing-loop.md +1 -1
- package/docs/operations/controller-browser-plugin.md +26 -6
- package/docs/operations/controller-performance-and-502.md +124 -0
- package/docs/operations/controller-reliability-runbook.md +1 -1
- package/docs/operations/features.md +2 -2
- package/docs/operations/github-repository.md +1 -1
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/mcp-tool-exposure.md +5 -3
- package/docs/wiki/Architecture.md +6 -6
- package/docs/wiki/Implementation.md +2 -2
- package/docs/wiki/Integrations.md +2 -2
- package/docs/wiki/Work-Lifecycle.md +1 -1
- package/package.json +29 -10
- package/scripts/activate-source-baseline.ts +17 -13
- package/scripts/benchmark-background-check-overlap.ts +228 -0
- package/scripts/benchmark-mcp-host.sh +117 -0
- package/scripts/benchmark-mcp-transport.ts +170 -0
- package/scripts/benchmark-quality-harness.ts +146 -0
- package/scripts/benchmark-route-session-concurrency.ts +207 -6
- package/scripts/benchmark-thin-harness-mcp-e2e.ts +7 -1
- package/scripts/benchmark-typescript-navigation.ts +186 -0
- package/scripts/benchmark-work-efficiency.ts +334 -0
- package/scripts/capture-plan.sh +3 -3
- package/scripts/check-agent-tooling.sh +8 -35
- package/scripts/check-architecture-sync.sh +17 -86
- package/scripts/check-mcp-compatibility.ts +14 -0
- package/scripts/check-runtime-architecture.mjs +107 -64
- package/scripts/check-stable-baseline.ts +92 -0
- package/scripts/check-task-workflow.sh +4 -4
- package/scripts/contract-worktree.sh +1 -21
- package/scripts/ensure-task-workflow.sh +22 -55
- package/scripts/host-temporary-cloud-mcp-e2e.sh +265 -0
- package/scripts/install-standalone-recovery.ts +24 -0
- package/scripts/lib/project-init-lib.sh +15 -44
- package/scripts/migrate-project-template.sh +23 -1179
- package/scripts/new-plan.sh +1 -1
- package/scripts/plan-to-todo.sh +11 -36
- package/scripts/run-governed-gate.ts +2 -1
- package/scripts/ship-worktrees.sh +2 -29
- package/scripts/smoke-ios-physical-device.ts +4 -2
- package/scripts/smoke-runtime-recovery.ts +1 -35
- package/scripts/smoke-schedule-engine.ts +1 -20
- package/scripts/verify-contract.sh +1 -111
- package/scripts/verify-forge-runtime.sh +0 -1
- package/scripts/verify-sprint.sh +3 -180
- package/scripts/workflow-contract.ts +1 -5
- package/src/cli/commands/init-hook.ts +3 -3
- package/src/cli/commands/mcp.ts +9 -5
- package/src/cli/commands/plugin.ts +1 -1
- package/src/cli/commands/recovery.ts +25 -3
- package/src/cli/commands/runtime.ts +55 -3
- package/src/cli/commands/security.ts +12 -1
- package/src/cli/commands/setup-profile.ts +31 -21
- package/src/cli/controller/check-runner.ts +106 -3
- package/src/cli/controller/composite-result.ts +1 -1
- package/src/cli/controller/context/focus.ts +51 -0
- package/src/cli/controller/context/instruction-context.ts +114 -0
- package/src/cli/controller/context/known-paths.ts +76 -0
- package/src/cli/controller/context/query-planning.ts +110 -0
- package/src/cli/controller/context/rule-resolution.ts +532 -0
- package/src/cli/controller/context/source-materializer.ts +278 -0
- package/src/cli/controller/context/structural.ts +16 -0
- package/src/cli/controller/context/types.ts +286 -0
- package/src/cli/controller/context-pack.ts +785 -469
- package/src/cli/controller/launch-agents.ts +77 -2
- package/src/cli/controller/operational-plan.ts +2 -2
- package/src/cli/controller/work-mode.ts +6 -4
- package/src/cli/editing/edit-session.ts +60 -7
- package/src/cli/github/github.ts +133 -0
- package/src/cli/installer/managed-entries.ts +15 -1
- package/src/cli/local-bridge/console-automations.ts +54 -78
- package/src/cli/local-bridge/console-view-models.ts +1 -35
- package/src/cli/local-bridge/facade-api.ts +0 -217
- package/src/cli/local-bridge/frontend/src/App.tsx +3 -3
- package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +23 -13
- package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +37 -4
- package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +6 -4
- package/src/cli/local-bridge/frontend/src/lib/api.ts +1 -6
- package/src/cli/local-bridge/frontend/src/lib/routes.ts +1 -1
- package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +2 -2
- package/src/cli/local-bridge/frontend/src/styles.css +1 -1
- package/src/cli/local-bridge/frontend/src/types.ts +5 -8
- package/src/cli/local-bridge/job-store.ts +1 -490
- package/src/cli/local-bridge/server.ts +0 -513
- package/src/cli/local-bridge/ui-dist/app.css +1 -1
- package/src/cli/local-bridge/ui-dist/app.js +3703 -3757
- package/src/cli/mcp/auth.ts +5 -5
- package/src/cli/mcp/instructions.ts +3 -2
- package/src/cli/mcp/legacy-tool-service.ts +0 -189
- package/src/cli/mcp/multi-repository.ts +16 -5
- package/src/cli/mcp/oauth.ts +175 -26
- package/src/cli/mcp/repository-tools.ts +247 -107
- package/src/cli/mcp/server.ts +537 -111
- package/src/cli/mcp/tool-capability-cache.ts +1 -1
- package/src/cli/mcp/toolset-selection.ts +1 -1
- package/src/cli/mcp/toolset.ts +42 -5
- package/src/cli/mcp/transports/http.ts +101 -14
- package/src/cli/mcp/transports/session-registry.ts +43 -5
- package/src/cli/mcp/types.ts +3 -3
- package/src/cli/repositories/command-classifier.ts +101 -19
- package/src/cli/repositories/command-executor.ts +55 -521
- package/src/cli/repositories/command-process.ts +108 -0
- package/src/cli/repositories/command-scope.ts +99 -41
- package/src/cli/repositories/controller-home.ts +7 -8
- package/src/cli/repositories/git-command-executor.ts +2 -0
- package/src/cli/repositories/locks.ts +53 -16
- package/src/cli/repositories/repository-snapshot.ts +121 -0
- package/src/cli/repositories/selected-path-actions.ts +17 -9
- package/src/cli/repositories/structured-git.ts +61 -3
- package/src/cli/repository/inspector.ts +553 -63
- package/src/cli/repository/session-cache.ts +58 -17
- package/src/cli/v81-entry.ts +1 -4
- package/src/effects/fs-transaction.ts +85 -17
- package/src/runtime/context/codegraph-read-provider.ts +233 -2
- package/src/runtime/context/codegraph-sidecar.cjs +74 -40
- package/src/runtime/context/generic-lsp-provider.ts +355 -0
- package/src/runtime/context/lsp-client.ts +283 -0
- package/src/runtime/context/semantic-navigation.ts +275 -0
- package/src/runtime/context/swift-navigation.ts +565 -0
- package/src/runtime/context/typescript-navigation.ts +226 -0
- package/src/runtime/control-plane/dispatch-priority.ts +28 -0
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +47 -8
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +86 -24
- package/src/runtime/control-plane/execution/session-store.ts +18 -0
- package/src/runtime/control-plane/execution/verification-evidence.ts +58 -3
- package/src/runtime/control-plane/execution/work-handle-store.ts +27 -2
- package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +258 -0
- package/src/runtime/control-plane/execution/work-remote-delivery.ts +215 -0
- package/src/runtime/control-plane/execution/work-task-receipt.ts +54 -11
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +143 -8
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +22 -14
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +85 -8
- package/src/runtime/control-plane/facade/capability-registry.ts +129 -25
- package/src/runtime/control-plane/facade/controller-round-relay.ts +991 -0
- package/src/runtime/control-plane/facade/controller-session-store.ts +132 -1
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +2 -0
- package/src/runtime/control-plane/facade/goal-workloop.ts +686 -129
- package/src/runtime/control-plane/facade/index.ts +1 -0
- package/src/runtime/control-plane/facade/plan-contract-store.ts +185 -20
- package/src/runtime/control-plane/facade/semantic-admission.ts +205 -0
- package/src/runtime/control-plane/facade/suggested-actions.ts +5 -1
- package/src/runtime/control-plane/facade/types.ts +22 -5
- package/src/runtime/control-plane/facade/work-contract-store.ts +175 -73
- package/src/runtime/control-plane/generated-cache-retention.ts +271 -0
- package/src/runtime/control-plane/global-scheduler/config.ts +44 -0
- package/src/runtime/control-plane/global-scheduler/dispatch-capacity.ts +80 -0
- package/src/runtime/control-plane/global-scheduler/durable-admission.ts +46 -0
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +145 -0
- package/src/runtime/control-plane/global-scheduler/projection-refresh.ts +84 -0
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -3
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +273 -542
- package/src/runtime/control-plane/global-scheduler/source-scan.ts +59 -0
- package/src/runtime/control-plane/global-scheduler/state.ts +88 -0
- package/src/runtime/control-plane/global-scheduler/worker-attachment.ts +57 -0
- package/src/runtime/control-plane/global-scheduler/worker-exit-decision.ts +38 -0
- package/src/runtime/control-plane/global-scheduler/worker-exit-reconciler.ts +175 -0
- package/src/runtime/control-plane/global-scheduler/worker-launch.ts +111 -0
- package/src/runtime/control-plane/global-scheduler/worker-lifecycle-store.ts +64 -0
- package/src/runtime/control-plane/global-scheduler/worker-lifecycle.ts +150 -0
- package/src/runtime/control-plane/global-scheduler/worker-process.ts +119 -0
- package/src/runtime/control-plane/global-scheduler/worker-stderr.ts +60 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +50 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +355 -116
- package/src/runtime/control-plane/launcher/launch-reservation-store.ts +40 -0
- package/src/runtime/control-plane/launcher/thin-launcher.ts +194 -10
- package/src/runtime/control-plane/persistence/controller-home-migration.ts +487 -0
- package/src/runtime/control-plane/persistence/sqlite-store.ts +33 -2
- package/src/runtime/control-plane/release-retention.ts +62 -2
- package/src/runtime/control-plane/routing/route-policy.ts +7 -16
- package/src/runtime/control-plane/runtime-status-client.ts +0 -2
- package/src/runtime/diagnostics/mcp-timing.ts +13 -0
- package/src/runtime/diagnostics/mcp-transport-benchmark.ts +129 -0
- package/src/runtime/diagnostics/performance.ts +24 -1
- package/src/runtime/evidence/event-ledger.ts +1 -1
- package/src/runtime/execution/jobs/store.ts +58 -4
- package/src/runtime/execution/jobs/types.ts +1 -1
- package/src/runtime/execution/managed-workspace.ts +203 -1
- package/src/runtime/execution/process-runtime/check-facade.ts +51 -4
- package/src/runtime/execution/process-runtime/check-result.ts +53 -0
- package/src/runtime/execution/process-runtime/check-scheduling.ts +114 -0
- package/src/runtime/execution/process-runtime/command-facade.ts +345 -40
- package/src/runtime/execution/process-runtime/gc.ts +38 -6
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +1184 -0
- package/src/runtime/execution/process-runtime/persisted-check.ts +47 -4
- package/src/runtime/execution/process-runtime/resource-claims.ts +10 -6
- package/src/runtime/execution/process-runtime/runtime.ts +43 -3
- package/src/runtime/execution/process-runtime/store.ts +1 -0
- package/src/runtime/execution/process-runtime/types.ts +2 -0
- package/src/runtime/execution/thin-harness/async-process.ts +12 -2
- package/src/runtime/execution/thin-harness/search-worker.ts +54 -5
- package/src/runtime/execution/workers/executor.ts +0 -48
- package/src/runtime/gateway/mcp/execution-tools.ts +1192 -114
- package/src/runtime/gateway/mcp/process-tools.ts +83 -37
- package/src/runtime/gateway/mcp/router.ts +184 -82
- package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +546 -0
- package/src/runtime/gateway/mcp/runtime-tools.ts +2224 -1589
- package/src/runtime/plugins/app-store-connect-adapter.ts +123 -19
- package/src/runtime/plugins/browser-adapter.ts +2901 -241
- package/src/runtime/plugins/browser-automation-service.ts +10 -0
- package/src/runtime/plugins/browser-handoff.ts +92 -2
- package/src/runtime/plugins/browser-macos-bridge.ts +582 -49
- package/src/runtime/plugins/browser-node-bridge.ts +6 -34
- package/src/runtime/plugins/browser-provider-registry.ts +109 -0
- package/src/runtime/plugins/browser-runtime-contract.ts +152 -0
- package/src/runtime/plugins/browser-runtime.ts +183 -0
- package/src/runtime/plugins/browser-session-authority.ts +332 -0
- package/src/runtime/plugins/capability-authorization-grants.ts +354 -0
- package/src/runtime/plugins/desktop-operator-registration.ts +8 -2
- package/src/runtime/plugins/external-adapter.ts +324 -3
- package/src/runtime/plugins/external-unix-socket.ts +7 -1
- package/src/runtime/plugins/first-party-registry.ts +2 -0
- package/src/runtime/plugins/github-adapter.ts +125 -0
- package/src/runtime/plugins/ios/agent-device-provider.ts +1 -1
- package/src/runtime/plugins/ios/agent-device-typed-provider.ts +52 -9
- package/src/runtime/plugins/ios/remote-xpc-hid.ts +1171 -0
- package/src/runtime/plugins/ios-adapter.ts +106 -16
- package/src/runtime/plugins/ios-agent-device.ts +234 -64
- package/src/runtime/plugins/ios-physical-device.ts +1143 -392
- package/src/runtime/plugins/lightweight-action.ts +153 -0
- package/src/runtime/plugins/local-system-adapter.ts +123 -6
- package/src/runtime/plugins/macos-capability-broker.ts +55 -9
- package/src/runtime/plugins/plugin-action-sidecar.ts +59 -0
- package/src/runtime/plugins/plugin-management-adapter.ts +49 -8
- package/src/runtime/plugins/resend-adapter.ts +1 -1
- package/src/runtime/plugins/store.ts +269 -29
- package/src/runtime/plugins/types.ts +35 -2
- package/src/runtime/plugins/xiaohongshu-publish.ts +515 -0
- package/src/runtime/projections/git-status-sampler.ts +16 -16
- package/src/runtime/projections/materialized-view.ts +28 -10
- package/src/runtime/recovery/maintenance-executor.ts +393 -28
- package/src/runtime/root/mcp-transport.ts +180 -10
- package/src/runtime/root/package-connector-service.ts +186 -8
- package/src/runtime/root/package-runtime-release.ts +143 -17
- package/src/runtime/root/package-runtime-service.ts +430 -22
- package/src/runtime/root/release-manifest.ts +7 -2
- package/src/runtime/root/release-materialize.ts +19 -0
- package/src/runtime/root/release-store.ts +48 -11
- package/src/runtime/root/runtime.ts +23 -5
- package/src/runtime/root/service.ts +100 -29
- package/src/runtime/root/types.ts +2 -0
- package/src/runtime/safe-tooling/ios-development.ts +321 -63
- package/src/runtime/shared/trusted-executable.ts +62 -0
- package/src/runtime/shared/trusted-node-executable.ts +48 -0
- package/src/runtime/standalone-recovery/core.ts +700 -92
- package/src/runtime/standalone-recovery/entry.ts +99 -23
- package/src/runtime/standalone-recovery/installer.ts +19 -3
- package/src/runtime/standalone-recovery/service-labels.ts +2 -0
- package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +160 -0
- package/src/runtime/workflow/schedules/browser-probe.ts +81 -3
- package/src/runtime/workflow/schedules/engine.ts +287 -151
- package/src/runtime/workflow/schedules/github-issue-watch.ts +158 -0
- package/src/runtime/workflow/schedules/settlement.ts +48 -4
- package/src/runtime/workflow/schedules/store.ts +131 -10
- package/src/runtime/workflow/schedules/types.ts +2 -4
- package/src/runtime/workflow/schedules/work-continuation.ts +26 -13
- package/src/testing/test-governance.ts +8 -40
- package/assets/reference-configs/heartbeat-triage.md +0 -57
- package/assets/templates/helpers/harness-trace-grade.sh +0 -150
- package/assets/templates/helpers/heartbeat-triage.sh +0 -361
- package/assets/templates/helpers/maintenance-triage.sh +0 -167
- package/docs/architecture/current/approved-target-architecture.zh-CN.md +0 -1501
- package/docs/architecture/current/architecture-invariants.md +0 -331
- package/docs/architecture/current/automation-and-schedule-engine.md +0 -459
- package/docs/architecture/current/codegraph-context-provider.md +0 -238
- package/docs/architecture/current/control-plane-authority-inventory.md +0 -94
- package/docs/architecture/current/controller-repository-decoupling.md +0 -148
- package/docs/architecture/current/dispatch-and-agent-strategy.md +0 -373
- package/docs/architecture/current/entity-model.md +0 -612
- package/docs/architecture/current/external-plugin-governance.md +0 -396
- package/docs/architecture/current/failure-recovery.md +0 -447
- package/docs/architecture/current/governance.md +0 -213
- package/docs/architecture/current/human-interaction-plane.md +0 -87
- package/docs/architecture/current/implementation-status.md +0 -128
- package/docs/architecture/current/job-and-run-lifecycle.md +0 -413
- package/docs/architecture/current/legacy-governance.md +0 -58
- package/docs/architecture/current/local-workspace-target-grants.md +0 -70
- package/docs/architecture/current/migration-roadmap.md +0 -105
- package/docs/architecture/current/multi-repository-execution.md +0 -371
- package/docs/architecture/current/operations-runbook.md +0 -45
- package/docs/architecture/current/peer-supercontroller-runtime.md +0 -32
- package/docs/architecture/current/personal-assistant-plugin-baseline.md +0 -206
- package/docs/architecture/current/repository-access-modes.md +0 -102
- package/docs/architecture/current/route-policy.md +0 -15
- package/docs/architecture/current/route-session-concurrency.md +0 -85
- package/docs/architecture/current/runtime-architecture-simplification.md +0 -214
- package/docs/architecture/current/runtime-directory-map.md +0 -49
- package/docs/architecture/current/runtime-health-and-resource-lifecycle.md +0 -85
- package/docs/architecture/current/scheduler-and-resource-claims.md +0 -422
- package/docs/architecture/current/session-aware-execution-and-authorization.md +0 -77
- package/docs/architecture/current/system-overview.md +0 -169
- package/docs/architecture/current/target-requirements-traceability.md +0 -202
- package/docs/architecture/current/thin-harness-governance-policy.md +0 -32
- package/docs/architecture/current/thin-harness-v1.md +0 -321
- package/docs/architecture/current/verification-and-release-gates.md +0 -391
- package/docs/forge-autonomous-goal-loop.md +0 -9
- package/docs/forge-provider-configuration.md +0 -7
- package/docs/operations/chatgpt-personal-assistant-runtime.md +0 -93
- package/docs/operations/gmail-assistant-routines.md +0 -186
- package/docs/operations/personal-assistant-operator-guide.md +0 -61
- package/docs/operations/provider-configuration.md +0 -31
- package/scripts/harness-trace-grade.sh +0 -150
- package/scripts/heartbeat-triage.sh +0 -361
- package/scripts/maintenance-triage.sh +0 -167
- package/src/cli/local-bridge/frontend/src/features/settings/SettingsView.tsx +0 -2
- package/src/cli/repositories/goal-registry.ts +0 -239
- package/src/runtime/assistant/action-proposals.ts +0 -279
- package/src/runtime/assistant/intent.ts +0 -395
- package/src/runtime/assistant/model-provider.ts +0 -460
- package/src/runtime/assistant/openapi.ts +0 -223
- package/src/runtime/assistant/policy.ts +0 -89
- package/src/runtime/assistant/readiness.ts +0 -258
- package/src/runtime/assistant/routine-runtime.ts +0 -477
- package/src/runtime/assistant/schedule-binding.ts +0 -171
- package/src/runtime/assistant/standing-grants.ts +0 -375
- package/src/runtime/assistant/store.ts +0 -243
- package/src/runtime/assistant/types.ts +0 -135
- package/src/runtime/control-plane/goal-loop/config-facade.ts +0 -700
- package/src/runtime/control-plane/goal-loop/config-store.ts +0 -570
- package/src/runtime/control-plane/goal-loop/config-types.ts +0 -213
- package/src/runtime/control-plane/goal-loop/executor-router.ts +0 -109
- package/src/runtime/control-plane/goal-loop/failure-taxonomy.ts +0 -149
- package/src/runtime/control-plane/goal-loop/goal-contract-store.ts +0 -304
- package/src/runtime/control-plane/goal-loop/goal-loop-engine.ts +0 -1001
- package/src/runtime/control-plane/goal-loop/handoff-packet.ts +0 -160
- package/src/runtime/control-plane/goal-loop/index.ts +0 -13
- package/src/runtime/control-plane/goal-loop/local-tools.ts +0 -290
- package/src/runtime/control-plane/goal-loop/policy-gates.ts +0 -203
- package/src/runtime/control-plane/goal-loop/provider-dispatch.ts +0 -93
- package/src/runtime/control-plane/goal-loop/provider-registry.ts +0 -545
- package/src/runtime/control-plane/goal-loop/types.ts +0 -378
- package/src/runtime/control-plane/startup-recovery.ts +0 -198
- package/src/runtime/gateway/mcp/resource-policy.ts +0 -186
- package/src/runtime/personal-assistant/gmail-triage-manager.ts +0 -231
- package/src/runtime/personal-assistant/reporting-runtime.ts +0 -344
- package/src/runtime/personal-assistant/triage-runtime.ts +0 -748
- package/src/runtime/workflow/findings/store.ts +0 -204
- package/src/runtime/workflow/findings/types.ts +0 -58
- package/src/runtime/workflow/portfolio/engine.ts +0 -20
- package/src/runtime/workflow/portfolio/store.ts +0 -185
- package/src/runtime/workflow/portfolio/types.ts +0 -29
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { randomUUID } from 'crypto';
|
|
1
2
|
import { spawn, spawnSync, type SpawnSyncReturns } from 'child_process';
|
|
2
|
-
import { closeSync, mkdirSync, openSync, renameSync, writeFileSync } from 'fs';
|
|
3
|
+
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeFileSync } from 'fs';
|
|
3
4
|
import { homedir } from 'os';
|
|
5
|
+
import { setTimeout as sleep } from 'timers/promises';
|
|
4
6
|
import { dirname, join, resolve } from 'path';
|
|
5
7
|
import { resolveControllerHome } from '../../cli/repositories/controller-home';
|
|
6
8
|
import { RUNTIME_WRITE_CLAIM_ENV } from './write-fence';
|
|
@@ -9,18 +11,68 @@ import {
|
|
|
9
11
|
activeRuntimeLaunchSpec,
|
|
10
12
|
forgeRuntimeServicePaths,
|
|
11
13
|
installForgeRuntimeService,
|
|
14
|
+
readForgeRuntimeServiceConfig,
|
|
12
15
|
syncForgeRuntimeActiveEntrypoint,
|
|
13
16
|
writeForgeRuntimeServiceConfig,
|
|
14
17
|
type ForgeRuntimeServiceConfig,
|
|
15
18
|
} from './service';
|
|
16
19
|
import { materializePackageRuntimeRelease, type PackageRuntimeRelease } from './package-runtime-release';
|
|
20
|
+
import { readRuntimeReleaseAuthority, revertInitialRuntimeReleasePublication, rollbackRuntimeRelease } from './release-store';
|
|
17
21
|
import { loadMcpServiceLocalConfig } from '../../cli/mcp/auth';
|
|
18
|
-
import {
|
|
22
|
+
import { ensurePackageConnectorService, type PackageConnectorServiceResult } from './package-connector-service';
|
|
23
|
+
import {
|
|
24
|
+
bootstrapLaunchAgentWithRetryV2,
|
|
25
|
+
currentUserLaunchdDomain,
|
|
26
|
+
installLaunchAgent,
|
|
27
|
+
launchAgentPath,
|
|
28
|
+
} from '../../cli/controller/launch-agents';
|
|
19
29
|
|
|
20
30
|
export type PackageRuntimeServiceMode = 'launchd' | 'systemd-user' | 'portable';
|
|
21
31
|
|
|
32
|
+
export type PackageRuntimeActivationStatus = 'activation_scheduled' | 'activated' | 'failed+rollback';
|
|
33
|
+
|
|
34
|
+
export interface PackageRuntimeActivationReceipt {
|
|
35
|
+
schemaVersion: 1;
|
|
36
|
+
operationId: string;
|
|
37
|
+
status: PackageRuntimeActivationStatus;
|
|
38
|
+
controllerHome: string;
|
|
39
|
+
releaseId: string;
|
|
40
|
+
packageFingerprint: string;
|
|
41
|
+
mode: 'launchd';
|
|
42
|
+
receiptPath: string;
|
|
43
|
+
createdAt: string;
|
|
44
|
+
updatedAt: string;
|
|
45
|
+
servicePath?: string;
|
|
46
|
+
helperLabel?: string;
|
|
47
|
+
error?: string;
|
|
48
|
+
rollbackSucceeded?: boolean;
|
|
49
|
+
rollbackErrors?: string[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface PackageRuntimeActivationRequest {
|
|
53
|
+
schemaVersion: 1;
|
|
54
|
+
operationId: string;
|
|
55
|
+
controllerHome: string;
|
|
56
|
+
installerPid: number;
|
|
57
|
+
release: PackageRuntimeRelease;
|
|
58
|
+
config: ForgeRuntimeServiceConfig;
|
|
59
|
+
connectorEndpoint?: string;
|
|
60
|
+
refreshConnector?: boolean;
|
|
61
|
+
priorAuthorityPresent: boolean;
|
|
62
|
+
priorConfigBytes?: string;
|
|
63
|
+
publicationChanged: boolean;
|
|
64
|
+
runnerPath: string;
|
|
65
|
+
nodeExecutable: string;
|
|
66
|
+
requestPath: string;
|
|
67
|
+
receiptPath: string;
|
|
68
|
+
helperLabel: string;
|
|
69
|
+
helperSourcePlistPath: string;
|
|
70
|
+
helperInstalledPlistPath: string;
|
|
71
|
+
createdAt: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
22
74
|
export interface PackageRuntimeServiceInstallResult {
|
|
23
|
-
status: '
|
|
75
|
+
status: 'activation_scheduled' | 'activated';
|
|
24
76
|
mode: PackageRuntimeServiceMode;
|
|
25
77
|
persistent: boolean;
|
|
26
78
|
controllerHome: string;
|
|
@@ -29,6 +81,13 @@ export interface PackageRuntimeServiceInstallResult {
|
|
|
29
81
|
pid?: number;
|
|
30
82
|
warnings: string[];
|
|
31
83
|
connector?: PackageConnectorServiceResult;
|
|
84
|
+
activation?: {
|
|
85
|
+
operationId: string;
|
|
86
|
+
status: 'activation_scheduled';
|
|
87
|
+
receiptPath: string;
|
|
88
|
+
helperLabel: string;
|
|
89
|
+
helperServicePath: string;
|
|
90
|
+
};
|
|
32
91
|
}
|
|
33
92
|
|
|
34
93
|
export interface PackageRuntimeServiceOptions {
|
|
@@ -41,6 +100,21 @@ export interface PackageRuntimeServiceOptions {
|
|
|
41
100
|
platform?: NodeJS.Platform;
|
|
42
101
|
env?: NodeJS.ProcessEnv;
|
|
43
102
|
forcePortable?: boolean;
|
|
103
|
+
refreshConnector?: boolean;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface PackageRuntimeServiceDependencies {
|
|
107
|
+
installDarwinService?: typeof installForgeRuntimeService;
|
|
108
|
+
ensureConnectorService?: typeof ensurePackageConnectorService;
|
|
109
|
+
scheduleDarwinActivation?: (request: PackageRuntimeActivationRequest) => Promise<{ label: string; servicePath: string }>;
|
|
110
|
+
activationMode?: 'detached' | 'inline';
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface PackageRuntimeActivationDependencies {
|
|
114
|
+
installDarwinService?: typeof installForgeRuntimeService;
|
|
115
|
+
ensureConnectorService?: typeof ensurePackageConnectorService;
|
|
116
|
+
waitForInstallerExit?: (pid: number) => Promise<void>;
|
|
117
|
+
cleanupActivationHelper?: (request: PackageRuntimeActivationRequest) => Promise<void>;
|
|
44
118
|
}
|
|
45
119
|
|
|
46
120
|
function atomicWrite(path: string, content: string, mode = 0o600): void {
|
|
@@ -141,9 +215,249 @@ function startPortableRuntime(controllerHome: string, env: NodeJS.ProcessEnv): n
|
|
|
141
215
|
}
|
|
142
216
|
}
|
|
143
217
|
|
|
144
|
-
|
|
218
|
+
|
|
219
|
+
function activationRoot(controllerHome: string): string {
|
|
220
|
+
return join(forgeRuntimeServicePaths(controllerHome).serviceRoot, 'activations');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function activationPaths(controllerHome: string, operationId: string): { requestPath: string; receiptPath: string; helperSourcePlistPath: string } {
|
|
224
|
+
const root = activationRoot(controllerHome);
|
|
225
|
+
return {
|
|
226
|
+
requestPath: join(root, `${operationId}.request.json`),
|
|
227
|
+
receiptPath: join(root, `${operationId}.receipt.json`),
|
|
228
|
+
helperSourcePlistPath: join(root, `${operationId}.plist`),
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function writeActivationRequest(request: PackageRuntimeActivationRequest): void {
|
|
233
|
+
atomicWrite(request.requestPath, `${JSON.stringify(request, null, 2)}\n`);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function writeActivationReceipt(
|
|
237
|
+
request: PackageRuntimeActivationRequest,
|
|
238
|
+
status: PackageRuntimeActivationStatus,
|
|
239
|
+
extra: Partial<Pick<PackageRuntimeActivationReceipt, 'servicePath' | 'error' | 'rollbackSucceeded' | 'rollbackErrors'>> = {},
|
|
240
|
+
): PackageRuntimeActivationReceipt {
|
|
241
|
+
const previous = readPackageRuntimeActivationReceipt(request.receiptPath);
|
|
242
|
+
const now = new Date().toISOString();
|
|
243
|
+
const receipt: PackageRuntimeActivationReceipt = {
|
|
244
|
+
schemaVersion: 1,
|
|
245
|
+
operationId: request.operationId,
|
|
246
|
+
status,
|
|
247
|
+
controllerHome: request.controllerHome,
|
|
248
|
+
releaseId: request.release.releaseId,
|
|
249
|
+
packageFingerprint: request.release.packageFingerprint,
|
|
250
|
+
mode: 'launchd',
|
|
251
|
+
receiptPath: request.receiptPath,
|
|
252
|
+
createdAt: previous?.createdAt ?? request.createdAt,
|
|
253
|
+
updatedAt: now,
|
|
254
|
+
helperLabel: request.helperLabel,
|
|
255
|
+
...extra,
|
|
256
|
+
};
|
|
257
|
+
atomicWrite(request.receiptPath, `${JSON.stringify(receipt, null, 2)}\n`);
|
|
258
|
+
return receipt;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export function readPackageRuntimeActivationReceipt(path: string): PackageRuntimeActivationReceipt | undefined {
|
|
262
|
+
if (!existsSync(path)) return undefined;
|
|
263
|
+
const value = JSON.parse(readFileSync(path, 'utf8')) as Partial<PackageRuntimeActivationReceipt>;
|
|
264
|
+
if (
|
|
265
|
+
value.schemaVersion !== 1
|
|
266
|
+
|| typeof value.operationId !== 'string'
|
|
267
|
+
|| !['activation_scheduled', 'activated', 'failed+rollback'].includes(String(value.status))
|
|
268
|
+
|| typeof value.controllerHome !== 'string'
|
|
269
|
+
|| typeof value.releaseId !== 'string'
|
|
270
|
+
|| typeof value.packageFingerprint !== 'string'
|
|
271
|
+
|| value.mode !== 'launchd'
|
|
272
|
+
|| typeof value.receiptPath !== 'string'
|
|
273
|
+
|| typeof value.createdAt !== 'string'
|
|
274
|
+
|| typeof value.updatedAt !== 'string'
|
|
275
|
+
) throw new Error('FORGE_PACKAGE_RUNTIME_ACTIVATION_RECEIPT_INVALID');
|
|
276
|
+
return value as PackageRuntimeActivationReceipt;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export function readPackageRuntimeActivationRequest(path: string): PackageRuntimeActivationRequest {
|
|
280
|
+
const resolvedPath = resolve(path);
|
|
281
|
+
const value = JSON.parse(readFileSync(resolvedPath, 'utf8')) as Partial<PackageRuntimeActivationRequest>;
|
|
282
|
+
if (
|
|
283
|
+
value.schemaVersion !== 1
|
|
284
|
+
|| typeof value.operationId !== 'string'
|
|
285
|
+
|| typeof value.controllerHome !== 'string'
|
|
286
|
+
|| !Number.isInteger(value.installerPid) || Number(value.installerPid) < 1
|
|
287
|
+
|| !value.release || typeof value.release !== 'object'
|
|
288
|
+
|| !value.config || typeof value.config !== 'object'
|
|
289
|
+
|| (value.connectorEndpoint !== undefined && typeof value.connectorEndpoint !== 'string')
|
|
290
|
+
|| (value.refreshConnector !== undefined && typeof value.refreshConnector !== 'boolean')
|
|
291
|
+
|| typeof value.priorAuthorityPresent !== 'boolean'
|
|
292
|
+
|| typeof value.publicationChanged !== 'boolean'
|
|
293
|
+
|| typeof value.runnerPath !== 'string'
|
|
294
|
+
|| typeof value.nodeExecutable !== 'string'
|
|
295
|
+
|| typeof value.requestPath !== 'string'
|
|
296
|
+
|| typeof value.receiptPath !== 'string'
|
|
297
|
+
|| typeof value.helperLabel !== 'string'
|
|
298
|
+
|| typeof value.helperSourcePlistPath !== 'string'
|
|
299
|
+
|| typeof value.helperInstalledPlistPath !== 'string'
|
|
300
|
+
|| typeof value.createdAt !== 'string'
|
|
301
|
+
) throw new Error('FORGE_PACKAGE_RUNTIME_ACTIVATION_REQUEST_INVALID');
|
|
302
|
+
const request = value as PackageRuntimeActivationRequest;
|
|
303
|
+
if (resolve(request.requestPath) !== resolvedPath) throw new Error('FORGE_PACKAGE_RUNTIME_ACTIVATION_REQUEST_PATH_MISMATCH');
|
|
304
|
+
if (resolve(request.controllerHome) !== resolve(request.config.controllerHome)) throw new Error('FORGE_PACKAGE_RUNTIME_ACTIVATION_HOME_MISMATCH');
|
|
305
|
+
return request;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function activationXml(value: string): string {
|
|
309
|
+
return value.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll("'", ''');
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export function renderPackageRuntimeActivationLaunchAgent(request: PackageRuntimeActivationRequest): string {
|
|
313
|
+
const executable = resolve(request.nodeExecutable);
|
|
314
|
+
const cliEntry = join(request.release.packageRoot, 'src', 'cli', 'index.ts');
|
|
315
|
+
const args = [executable, cliEntry, 'runtime', 'service', 'activate-package', '--request', request.requestPath];
|
|
316
|
+
const stdoutPath = join(activationRoot(request.controllerHome), `${request.operationId}.stdout.log`);
|
|
317
|
+
const stderrPath = join(activationRoot(request.controllerHome), `${request.operationId}.stderr.log`);
|
|
318
|
+
return `<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist version="1.0">\n<dict>\n <key>Label</key>\n <string>${activationXml(request.helperLabel)}</string>\n <key>ProgramArguments</key>\n <array>\n${args.map((arg) => ` <string>${activationXml(arg)}</string>`).join('\n')}\n </array>\n <key>EnvironmentVariables</key>\n <dict>\n <key>PATH</key>\n <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>\n </dict>\n <key>RunAtLoad</key>\n <true/>\n <key>ProcessType</key>\n <string>Background</string>\n <key>StandardOutPath</key>\n <string>${activationXml(stdoutPath)}</string>\n <key>StandardErrorPath</key>\n <string>${activationXml(stderrPath)}</string>\n</dict>\n</plist>\n`;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
async function scheduleDarwinPackageRuntimeActivation(request: PackageRuntimeActivationRequest): Promise<{ label: string; servicePath: string }> {
|
|
322
|
+
if (process.platform !== 'darwin') throw new Error('FORGE_PACKAGE_RUNTIME_ACTIVATION_HELPER_PLATFORM_UNSUPPORTED');
|
|
323
|
+
atomicWrite(request.helperSourcePlistPath, renderPackageRuntimeActivationLaunchAgent(request), 0o600);
|
|
324
|
+
installLaunchAgent(request.helperSourcePlistPath, request.helperLabel);
|
|
325
|
+
const result = await bootstrapLaunchAgentWithRetryV2({ label: request.helperLabel, plistPath: request.helperInstalledPlistPath });
|
|
326
|
+
if (!result.ok) throw new Error(`FORGE_PACKAGE_RUNTIME_ACTIVATION_HELPER_BOOTSTRAP_FAILED: ${result.diagnostics.join('; ')}`);
|
|
327
|
+
return { label: request.helperLabel, servicePath: request.helperInstalledPlistPath };
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
async function waitForInstallerExit(pid: number): Promise<void> {
|
|
331
|
+
const deadline = Date.now() + 60_000;
|
|
332
|
+
while (Date.now() < deadline) {
|
|
333
|
+
try {
|
|
334
|
+
process.kill(pid, 0);
|
|
335
|
+
} catch (error) {
|
|
336
|
+
const code = (error as NodeJS.ErrnoException).code;
|
|
337
|
+
if (code === 'ESRCH') return;
|
|
338
|
+
if (code !== 'EPERM') throw error;
|
|
339
|
+
}
|
|
340
|
+
await sleep(50);
|
|
341
|
+
}
|
|
342
|
+
throw new Error(`FORGE_PACKAGE_RUNTIME_ACTIVATION_INSTALLER_STILL_RUNNING: pid=${pid}`);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
async function cleanupActivationHelper(request: PackageRuntimeActivationRequest): Promise<void> {
|
|
346
|
+
rmSync(request.helperSourcePlistPath, { force: true });
|
|
347
|
+
rmSync(request.helperInstalledPlistPath, { force: true });
|
|
348
|
+
if (process.platform !== 'darwin') return;
|
|
349
|
+
const child = spawn('/bin/launchctl', ['bootout', `${currentUserLaunchdDomain()}/${request.helperLabel}`], {
|
|
350
|
+
detached: true,
|
|
351
|
+
stdio: 'ignore',
|
|
352
|
+
env: { PATH: '/usr/bin:/bin:/usr/sbin:/sbin' },
|
|
353
|
+
});
|
|
354
|
+
child.unref();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
async function rollbackPackageRuntimeActivation(
|
|
358
|
+
request: PackageRuntimeActivationRequest,
|
|
359
|
+
installDarwinService: typeof installForgeRuntimeService,
|
|
360
|
+
): Promise<string[]> {
|
|
361
|
+
const errors: string[] = [];
|
|
362
|
+
const servicePaths = forgeRuntimeServicePaths(request.controllerHome);
|
|
363
|
+
try {
|
|
364
|
+
if (request.publicationChanged) {
|
|
365
|
+
const current = readRuntimeReleaseAuthority(request.controllerHome);
|
|
366
|
+
if (!current || current.active.releaseId !== request.release.releaseId || current.operationId !== request.operationId) {
|
|
367
|
+
throw new Error('FORGE_PACKAGE_RUNTIME_ACTIVATION_ROLLBACK_FENCE_MISMATCH');
|
|
368
|
+
}
|
|
369
|
+
if (request.priorAuthorityPresent) rollbackRuntimeRelease(request.controllerHome, `${request.operationId}-rollback`);
|
|
370
|
+
else revertInitialRuntimeReleasePublication(request.controllerHome, request.operationId);
|
|
371
|
+
}
|
|
372
|
+
} catch (error) {
|
|
373
|
+
errors.push(error instanceof Error ? error.message : String(error));
|
|
374
|
+
}
|
|
375
|
+
try {
|
|
376
|
+
if (request.priorConfigBytes === undefined) rmSync(servicePaths.configPath, { force: true });
|
|
377
|
+
else atomicWrite(servicePaths.configPath, request.priorConfigBytes);
|
|
378
|
+
syncForgeRuntimeActiveEntrypoint(request.controllerHome);
|
|
379
|
+
} catch (error) {
|
|
380
|
+
errors.push(error instanceof Error ? error.message : String(error));
|
|
381
|
+
}
|
|
382
|
+
if (request.priorAuthorityPresent && request.priorConfigBytes !== undefined) {
|
|
383
|
+
try {
|
|
384
|
+
const priorConfig = readForgeRuntimeServiceConfig(servicePaths.configPath);
|
|
385
|
+
await installDarwinService({
|
|
386
|
+
config: priorConfig,
|
|
387
|
+
runnerPath: join(priorConfig.repositoryRoot, 'bin', 'forge-runtime-service.mjs'),
|
|
388
|
+
nodeExecutable: request.nodeExecutable,
|
|
389
|
+
});
|
|
390
|
+
} catch (error) {
|
|
391
|
+
errors.push(error instanceof Error ? error.message : String(error));
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return errors;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
export async function activateScheduledPackageRuntimeService(
|
|
398
|
+
request: PackageRuntimeActivationRequest,
|
|
399
|
+
dependencies: PackageRuntimeActivationDependencies = {},
|
|
400
|
+
): Promise<PackageRuntimeActivationReceipt> {
|
|
401
|
+
const installDarwinService = dependencies.installDarwinService ?? installForgeRuntimeService;
|
|
402
|
+
const ensureConnectorService = dependencies.ensureConnectorService ?? ensurePackageConnectorService;
|
|
403
|
+
const wait = dependencies.waitForInstallerExit ?? waitForInstallerExit;
|
|
404
|
+
const cleanup = dependencies.cleanupActivationHelper ?? cleanupActivationHelper;
|
|
405
|
+
try {
|
|
406
|
+
await wait(request.installerPid);
|
|
407
|
+
const authority = readRuntimeReleaseAuthority(request.controllerHome);
|
|
408
|
+
if (!authority || authority.active.releaseId !== request.release.releaseId) {
|
|
409
|
+
throw new Error('FORGE_PACKAGE_RUNTIME_ACTIVATION_AUTHORITY_MISMATCH');
|
|
410
|
+
}
|
|
411
|
+
if (request.publicationChanged && authority.operationId !== request.operationId) {
|
|
412
|
+
throw new Error('FORGE_PACKAGE_RUNTIME_ACTIVATION_FENCE_MISMATCH');
|
|
413
|
+
}
|
|
414
|
+
const paths = await installDarwinService({
|
|
415
|
+
config: request.config,
|
|
416
|
+
runnerPath: request.runnerPath,
|
|
417
|
+
nodeExecutable: request.nodeExecutable,
|
|
418
|
+
});
|
|
419
|
+
if (request.connectorEndpoint) {
|
|
420
|
+
await ensureConnectorService({
|
|
421
|
+
release: request.release,
|
|
422
|
+
controllerHome: request.controllerHome,
|
|
423
|
+
endpoint: request.connectorEndpoint,
|
|
424
|
+
platform: 'darwin',
|
|
425
|
+
refresh: request.refreshConnector === true,
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
return writeActivationReceipt(request, 'activated', { servicePath: paths.installedPlistPath });
|
|
429
|
+
} catch (error) {
|
|
430
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
431
|
+
const rollbackErrors = await rollbackPackageRuntimeActivation(request, installDarwinService);
|
|
432
|
+
writeActivationReceipt(request, 'failed+rollback', {
|
|
433
|
+
error: detail,
|
|
434
|
+
rollbackSucceeded: rollbackErrors.length === 0,
|
|
435
|
+
...(rollbackErrors.length ? { rollbackErrors } : {}),
|
|
436
|
+
});
|
|
437
|
+
if (rollbackErrors.length > 0) {
|
|
438
|
+
throw new Error(`FORGE_PACKAGE_RUNTIME_ACTIVATION_FAILED_AND_ROLLBACK_FAILED: ${detail}; rollback: ${rollbackErrors.join('; ')}`);
|
|
439
|
+
}
|
|
440
|
+
throw new Error(`FORGE_PACKAGE_RUNTIME_ACTIVATION_FAILED_ROLLED_BACK: ${detail}`);
|
|
441
|
+
} finally {
|
|
442
|
+
await cleanup(request);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
export async function activateScheduledPackageRuntimeServiceFromPath(requestPath: string): Promise<PackageRuntimeActivationReceipt> {
|
|
447
|
+
return activateScheduledPackageRuntimeService(readPackageRuntimeActivationRequest(requestPath));
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
export async function installPackageRuntimeService(
|
|
451
|
+
options: PackageRuntimeServiceOptions,
|
|
452
|
+
dependencies: PackageRuntimeServiceDependencies = {},
|
|
453
|
+
): Promise<PackageRuntimeServiceInstallResult> {
|
|
145
454
|
const controllerHome = resolveControllerHome(options.controllerHome);
|
|
146
|
-
const
|
|
455
|
+
const servicePaths = forgeRuntimeServicePaths(controllerHome);
|
|
456
|
+
const priorAuthority = readRuntimeReleaseAuthority(controllerHome);
|
|
457
|
+
const priorConfigBytes = existsSync(servicePaths.configPath) ? readFileSync(servicePaths.configPath, 'utf8') : undefined;
|
|
458
|
+
const operationId = `package-runtime-install-${randomUUID()}`;
|
|
459
|
+
const release = materializePackageRuntimeRelease({ controllerHome, packageRoot: options.packageRoot, operationId });
|
|
460
|
+
const publicationChanged = release.authority.operationId === operationId;
|
|
147
461
|
const config: ForgeRuntimeServiceConfig = {
|
|
148
462
|
schemaVersion: 1,
|
|
149
463
|
controllerHome,
|
|
@@ -157,29 +471,123 @@ export async function installPackageRuntimeService(options: PackageRuntimeServic
|
|
|
157
471
|
syncForgeRuntimeActiveEntrypoint(controllerHome);
|
|
158
472
|
const platform = options.platform ?? process.platform;
|
|
159
473
|
const env = options.env ?? process.env;
|
|
474
|
+
const installDarwinService = dependencies.installDarwinService ?? installForgeRuntimeService;
|
|
475
|
+
const explicitInjectedInline = Boolean(dependencies.installDarwinService && !dependencies.scheduleDarwinActivation && !dependencies.activationMode);
|
|
476
|
+
const activationMode = dependencies.activationMode ?? (explicitInjectedInline ? 'inline' : 'detached');
|
|
477
|
+
const connectorEndpoint = loadMcpServiceLocalConfig(controllerHome)?.chatgpt?.localEndpoint;
|
|
160
478
|
|
|
161
479
|
let base: PackageRuntimeServiceInstallResult;
|
|
162
|
-
if (!options.forcePortable && platform === 'darwin') {
|
|
163
|
-
const paths =
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
480
|
+
if (!options.forcePortable && platform === 'darwin' && activationMode === 'detached') {
|
|
481
|
+
const paths = activationPaths(controllerHome, operationId);
|
|
482
|
+
const helperLabel = `com.moretea.forge.runtime-activation.${operationId.replace(/[^A-Za-z0-9.-]+/g, '-').slice(-48)}`;
|
|
483
|
+
const createdAt = new Date().toISOString();
|
|
484
|
+
const request: PackageRuntimeActivationRequest = {
|
|
485
|
+
schemaVersion: 1,
|
|
486
|
+
operationId,
|
|
487
|
+
controllerHome,
|
|
488
|
+
installerPid: process.pid,
|
|
489
|
+
release,
|
|
490
|
+
config,
|
|
491
|
+
...(connectorEndpoint ? { connectorEndpoint } : {}),
|
|
492
|
+
...(options.refreshConnector !== undefined ? { refreshConnector: options.refreshConnector === true } : {}),
|
|
493
|
+
priorAuthorityPresent: Boolean(priorAuthority),
|
|
494
|
+
...(priorConfigBytes !== undefined ? { priorConfigBytes } : {}),
|
|
495
|
+
publicationChanged,
|
|
496
|
+
runnerPath: join(release.packageRoot, 'bin', 'forge-runtime-service.mjs'),
|
|
497
|
+
nodeExecutable: process.execPath,
|
|
498
|
+
requestPath: paths.requestPath,
|
|
499
|
+
receiptPath: paths.receiptPath,
|
|
500
|
+
helperLabel,
|
|
501
|
+
helperSourcePlistPath: paths.helperSourcePlistPath,
|
|
502
|
+
helperInstalledPlistPath: launchAgentPath(helperLabel),
|
|
503
|
+
createdAt,
|
|
504
|
+
};
|
|
505
|
+
writeActivationRequest(request);
|
|
506
|
+
writeActivationReceipt(request, 'activation_scheduled');
|
|
507
|
+
const schedule = dependencies.scheduleDarwinActivation ?? scheduleDarwinPackageRuntimeActivation;
|
|
508
|
+
let helper: { label: string; servicePath: string };
|
|
509
|
+
try {
|
|
510
|
+
helper = await schedule(request);
|
|
511
|
+
} catch (scheduleError) {
|
|
512
|
+
const detail = scheduleError instanceof Error ? scheduleError.message : String(scheduleError);
|
|
513
|
+
const rollbackErrors = await rollbackPackageRuntimeActivation(request, installDarwinService);
|
|
514
|
+
writeActivationReceipt(request, 'failed+rollback', {
|
|
515
|
+
error: detail,
|
|
516
|
+
rollbackSucceeded: rollbackErrors.length === 0,
|
|
517
|
+
...(rollbackErrors.length ? { rollbackErrors } : {}),
|
|
518
|
+
});
|
|
519
|
+
if (rollbackErrors.length > 0) {
|
|
520
|
+
throw new Error(`FORGE_PACKAGE_RUNTIME_ACTIVATION_SCHEDULE_FAILED_AND_ROLLBACK_FAILED: ${detail}; rollback: ${rollbackErrors.join('; ')}`);
|
|
521
|
+
}
|
|
522
|
+
throw scheduleError;
|
|
523
|
+
}
|
|
170
524
|
base = {
|
|
171
|
-
status: '
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
525
|
+
status: 'activation_scheduled',
|
|
526
|
+
mode: 'launchd',
|
|
527
|
+
persistent: true,
|
|
528
|
+
controllerHome,
|
|
529
|
+
release,
|
|
530
|
+
servicePath: servicePaths.installedPlistPath,
|
|
531
|
+
warnings: [],
|
|
532
|
+
activation: {
|
|
533
|
+
operationId,
|
|
534
|
+
status: 'activation_scheduled',
|
|
535
|
+
receiptPath: request.receiptPath,
|
|
536
|
+
helperLabel: helper.label,
|
|
537
|
+
helperServicePath: helper.servicePath,
|
|
538
|
+
},
|
|
175
539
|
};
|
|
540
|
+
} else {
|
|
541
|
+
try {
|
|
542
|
+
if (!options.forcePortable && platform === 'darwin') {
|
|
543
|
+
const paths = await installDarwinService({ config, runnerPath: join(release.packageRoot, 'bin', 'forge-runtime-service.mjs'), nodeExecutable: process.execPath });
|
|
544
|
+
base = { status: 'activated', mode: 'launchd', persistent: true, controllerHome, release, servicePath: paths.installedPlistPath, warnings: [] };
|
|
545
|
+
} else if (!options.forcePortable && platform === 'linux' && systemdUserAvailable(env)) {
|
|
546
|
+
const unitPath = installSystemdUserService(controllerHome, env);
|
|
547
|
+
base = { status: 'activated', mode: 'systemd-user', persistent: true, controllerHome, release, servicePath: unitPath, warnings: [] };
|
|
548
|
+
} else {
|
|
549
|
+
const pid = startPortableRuntime(controllerHome, env);
|
|
550
|
+
base = {
|
|
551
|
+
status: 'activated', mode: 'portable', persistent: false, controllerHome, release, pid,
|
|
552
|
+
warnings: [platform === 'win32'
|
|
553
|
+
? 'Native Windows is preview: Forge started detached Runtime and OAuth Gateway processes for this session; automatic login/reboot persistence is not yet claimed.'
|
|
554
|
+
: 'systemd --user is unavailable: Forge started detached Runtime and OAuth Gateway processes; enable a user service manager for reboot persistence.'],
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
} catch (installError) {
|
|
558
|
+
const requestPaths = activationPaths(controllerHome, operationId);
|
|
559
|
+
const rollbackRequest: PackageRuntimeActivationRequest = {
|
|
560
|
+
schemaVersion: 1,
|
|
561
|
+
operationId,
|
|
562
|
+
controllerHome,
|
|
563
|
+
installerPid: process.pid,
|
|
564
|
+
release,
|
|
565
|
+
config,
|
|
566
|
+
priorAuthorityPresent: Boolean(priorAuthority),
|
|
567
|
+
...(priorConfigBytes !== undefined ? { priorConfigBytes } : {}),
|
|
568
|
+
publicationChanged,
|
|
569
|
+
runnerPath: join(release.packageRoot, 'bin', 'forge-runtime-service.mjs'),
|
|
570
|
+
nodeExecutable: process.execPath,
|
|
571
|
+
requestPath: requestPaths.requestPath,
|
|
572
|
+
receiptPath: requestPaths.receiptPath,
|
|
573
|
+
helperLabel: 'inline',
|
|
574
|
+
helperSourcePlistPath: requestPaths.helperSourcePlistPath,
|
|
575
|
+
helperInstalledPlistPath: requestPaths.helperSourcePlistPath,
|
|
576
|
+
createdAt: new Date().toISOString(),
|
|
577
|
+
};
|
|
578
|
+
const recoveryErrors = await rollbackPackageRuntimeActivation(rollbackRequest, installDarwinService);
|
|
579
|
+
const detail = installError instanceof Error ? installError.message : String(installError);
|
|
580
|
+
if (recoveryErrors.length > 0) {
|
|
581
|
+
throw new Error(`FORGE_PACKAGE_RUNTIME_INSTALL_FAILED_AND_RECOVERY_FAILED: ${detail}; recovery: ${recoveryErrors.join('; ')}`);
|
|
582
|
+
}
|
|
583
|
+
throw installError;
|
|
584
|
+
}
|
|
176
585
|
}
|
|
177
586
|
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
release, controllerHome, endpoint: connectorEndpoint, platform, env, forcePortable: options.forcePortable === true,
|
|
587
|
+
if (!connectorEndpoint || base.status === 'activation_scheduled') return base;
|
|
588
|
+
const ensureConnectorService = dependencies.ensureConnectorService ?? ensurePackageConnectorService;
|
|
589
|
+
const connector = await ensureConnectorService({
|
|
590
|
+
release, controllerHome, endpoint: connectorEndpoint, platform, env, forcePortable: options.forcePortable === true, refresh: options.refreshConnector === true,
|
|
183
591
|
});
|
|
184
592
|
return { ...base, connector };
|
|
185
593
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFileSync } from 'fs';
|
|
1
|
+
import { existsSync, readFileSync, realpathSync } from 'fs';
|
|
2
2
|
import { resolve } from 'path';
|
|
3
3
|
import { CONTROL_PLANE_SCHEMA_VERSION } from '../control-plane/persistence/sqlite-store';
|
|
4
4
|
import type { RuntimeReleaseManifest } from './types';
|
|
@@ -8,6 +8,11 @@ function requireString(value: unknown, field: string): string {
|
|
|
8
8
|
return value.trim();
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
function canonicalExistingPathIdentity(path: string): string {
|
|
12
|
+
const resolved = resolve(path);
|
|
13
|
+
return existsSync(resolved) ? realpathSync(resolved) : resolved;
|
|
14
|
+
}
|
|
15
|
+
|
|
11
16
|
export function loadRuntimeReleaseManifest(
|
|
12
17
|
path: string,
|
|
13
18
|
expectedControllerHome: string,
|
|
@@ -31,7 +36,7 @@ export function loadRuntimeReleaseManifest(
|
|
|
31
36
|
throw new Error('RELEASE_MANIFEST_INVALID: configurationSchemaVersion must be 1');
|
|
32
37
|
}
|
|
33
38
|
const controllerHome = resolve(requireString(value.controllerHome, 'controllerHome'));
|
|
34
|
-
if (controllerHome !==
|
|
39
|
+
if (canonicalExistingPathIdentity(controllerHome) !== canonicalExistingPathIdentity(expectedControllerHome)) {
|
|
35
40
|
throw new Error('RELEASE_MANIFEST_CONTROLLER_HOME_MISMATCH');
|
|
36
41
|
}
|
|
37
42
|
const compatibility = value.databaseSchemaCompatibility as Record<string, unknown> | undefined;
|
|
@@ -33,6 +33,7 @@ export interface StagedRuntimeRelease {
|
|
|
33
33
|
browserHandoffArtifactIdentity?: string;
|
|
34
34
|
processRunnerArtifactIdentity?: string;
|
|
35
35
|
checkRunnerArtifactIdentity?: string;
|
|
36
|
+
pluginActionSidecarArtifactIdentity?: string;
|
|
36
37
|
externalPluginProbeArtifactIdentity?: string;
|
|
37
38
|
codeGraphNodeArtifactIdentity?: string;
|
|
38
39
|
codeGraphSidecarArtifactIdentity?: string;
|
|
@@ -491,6 +492,19 @@ export function stageRuntimeRelease(input: {
|
|
|
491
492
|
chmodSync(checkRunnerPath, 0o700);
|
|
492
493
|
const checkRunnerArtifactIdentity = `sha256:${sha256(checkRunnerPath)}`;
|
|
493
494
|
|
|
495
|
+
const pluginActionSidecarEntrypoint = 'forge-plugin-action-sidecar' as const;
|
|
496
|
+
const pluginActionSidecarPath = join(staging, pluginActionSidecarEntrypoint);
|
|
497
|
+
const pluginActionSidecarCompile = compileBinary({
|
|
498
|
+
sourceRoot,
|
|
499
|
+
outputPath: pluginActionSidecarPath,
|
|
500
|
+
entryPath: join(sourceRoot, 'src/runtime/plugins/plugin-action-sidecar.ts'),
|
|
501
|
+
});
|
|
502
|
+
if (!pluginActionSidecarCompile.ok) {
|
|
503
|
+
throw new Error(`RUNTIME_RELEASE_PLUGIN_ACTION_SIDECAR_BUILD_FAILED: ${pluginActionSidecarCompile.stderr || pluginActionSidecarCompile.stdout || pluginActionSidecarCompile.error}`.slice(0, 2_000));
|
|
504
|
+
}
|
|
505
|
+
chmodSync(pluginActionSidecarPath, 0o700);
|
|
506
|
+
const pluginActionSidecarArtifactIdentity = `sha256:${sha256(pluginActionSidecarPath)}`;
|
|
507
|
+
|
|
494
508
|
const externalPluginProbeEntrypoint = 'external-unix-socket-probe.cjs' as const;
|
|
495
509
|
const sourceExternalPluginProbePath = join(sourceRoot, 'src', 'runtime', 'plugins', externalPluginProbeEntrypoint);
|
|
496
510
|
if (!existsSync(sourceExternalPluginProbePath)) {
|
|
@@ -549,6 +563,8 @@ export function stageRuntimeRelease(input: {
|
|
|
549
563
|
processRunnerArtifactIdentity,
|
|
550
564
|
checkRunnerEntrypoint,
|
|
551
565
|
checkRunnerArtifactIdentity,
|
|
566
|
+
pluginActionSidecarEntrypoint,
|
|
567
|
+
pluginActionSidecarArtifactIdentity,
|
|
552
568
|
externalPluginProbeEntrypoint,
|
|
553
569
|
externalPluginProbeArtifactIdentity,
|
|
554
570
|
codeGraphNodeEntrypoint,
|
|
@@ -633,6 +649,9 @@ export function assertRuntimeReleaseFiles(release: StagedRuntimeRelease, depende
|
|
|
633
649
|
if (release.checkRunnerArtifactIdentity && !existsSync(join(release.releasePath, 'forge-check-runner'))) {
|
|
634
650
|
throw new Error(`RUNTIME_RELEASE_CHECK_RUNNER_MISSING: ${join(release.releasePath, 'forge-check-runner')}`);
|
|
635
651
|
}
|
|
652
|
+
if (release.pluginActionSidecarArtifactIdentity && !existsSync(join(release.releasePath, 'forge-plugin-action-sidecar'))) {
|
|
653
|
+
throw new Error(`RUNTIME_RELEASE_PLUGIN_ACTION_SIDECAR_MISSING: ${join(release.releasePath, 'forge-plugin-action-sidecar')}`);
|
|
654
|
+
}
|
|
636
655
|
if (release.externalPluginProbeArtifactIdentity && !existsSync(join(release.releasePath, 'external-unix-socket-probe.cjs'))) {
|
|
637
656
|
throw new Error(`RUNTIME_RELEASE_EXTERNAL_PLUGIN_PROBE_MISSING: ${join(release.releasePath, 'external-unix-socket-probe.cjs')}`);
|
|
638
657
|
}
|