@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
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { writeAtomicTextFile } from '../shared/atomic-text-file';
|
|
1
2
|
import { createHash } from 'crypto';
|
|
2
|
-
import { chmodSync, copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, renameSync, rmSync, statSync
|
|
3
|
+
import { chmodSync, copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, renameSync, rmSync, statSync } from 'fs';
|
|
3
4
|
import { homedir } from 'os';
|
|
4
5
|
import { basename, dirname, join, resolve } from 'path';
|
|
5
|
-
import { loadMcpServiceLocalConfig } from '
|
|
6
|
+
import { loadMcpServiceLocalConfig } from '../../../adapters/mcp/auth';
|
|
6
7
|
import { runtimeAuthorityFreeEnvironment } from '../shared/process-environment';
|
|
7
8
|
import type { PackageRuntimeRelease } from './package-runtime-release';
|
|
8
9
|
import { createPlatformServiceManagerHost, platformLaunchdInstalledPath, type PlatformServiceManagerHost, type SystemdUserUnitInput } from '../platform/service-manager';
|
|
@@ -49,19 +50,22 @@ export interface PackageConnectorServiceResult {
|
|
|
49
50
|
releaseRoot?: string;
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
export interface PackageConnectorCutoverDrainMarker {
|
|
54
|
+
schemaVersion: 1;
|
|
55
|
+
sessionId: string;
|
|
56
|
+
stableReleaseId: string;
|
|
57
|
+
connectorEndpoint: string;
|
|
58
|
+
connectorInstalledAt: string;
|
|
59
|
+
ownerPid: number;
|
|
60
|
+
armedAt: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
52
63
|
export type PackageConnectorAuthMode = 'oauth' | 'none';
|
|
53
64
|
|
|
54
65
|
function xml(value: string): string {
|
|
55
66
|
return value.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"');
|
|
56
67
|
}
|
|
57
68
|
|
|
58
|
-
function atomicWrite(path: string, content: string, mode = 0o600): void {
|
|
59
|
-
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
60
|
-
const temporary = `${path}.${process.pid}.tmp`;
|
|
61
|
-
writeFileSync(temporary, content, { encoding: 'utf8', mode });
|
|
62
|
-
renameSync(temporary, path);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
69
|
export function packageConnectorServicePaths(controllerHome: string, accountHome = process.env.HOME ?? homedir()): PackageConnectorServicePaths {
|
|
66
70
|
const home = resolve(controllerHome);
|
|
67
71
|
const label = forgeConnectorPersistentServiceLabel(home);
|
|
@@ -78,6 +82,114 @@ export function packageConnectorServicePaths(controllerHome: string, accountHome
|
|
|
78
82
|
};
|
|
79
83
|
}
|
|
80
84
|
|
|
85
|
+
const PACKAGE_CONNECTOR_CUTOVER_DRAIN_TTL_MS = 10 * 60_000;
|
|
86
|
+
|
|
87
|
+
export function packageConnectorCutoverDrainMarkerPath(controllerHome: string): string {
|
|
88
|
+
return join(packageConnectorServicePaths(controllerHome).serviceRoot, 'cutover-draining.json');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function removePackageConnectorCutoverDrainMarker(controllerHome: string): void {
|
|
92
|
+
rmSync(packageConnectorCutoverDrainMarkerPath(controllerHome), { force: true });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function livePackageConnectorCutoverDrainMarker(
|
|
96
|
+
controllerHome: string,
|
|
97
|
+
now = Date.now(),
|
|
98
|
+
): PackageConnectorCutoverDrainMarker | undefined {
|
|
99
|
+
const path = packageConnectorCutoverDrainMarkerPath(controllerHome);
|
|
100
|
+
if (!existsSync(path)) return undefined;
|
|
101
|
+
try {
|
|
102
|
+
const marker = JSON.parse(readFileSync(path, 'utf8')) as Partial<PackageConnectorCutoverDrainMarker>;
|
|
103
|
+
const armedAt = typeof marker.armedAt === 'string' ? Date.parse(marker.armedAt) : Number.NaN;
|
|
104
|
+
if (
|
|
105
|
+
marker.schemaVersion !== 1
|
|
106
|
+
|| typeof marker.sessionId !== 'string'
|
|
107
|
+
|| !marker.sessionId.trim()
|
|
108
|
+
|| typeof marker.stableReleaseId !== 'string'
|
|
109
|
+
|| !marker.stableReleaseId.trim()
|
|
110
|
+
|| typeof marker.connectorEndpoint !== 'string'
|
|
111
|
+
|| !marker.connectorEndpoint.trim()
|
|
112
|
+
|| typeof marker.connectorInstalledAt !== 'string'
|
|
113
|
+
|| !marker.connectorInstalledAt.trim()
|
|
114
|
+
|| !Number.isInteger(marker.ownerPid)
|
|
115
|
+
|| Number(marker.ownerPid) <= 0
|
|
116
|
+
|| !Number.isFinite(armedAt)
|
|
117
|
+
|| now - armedAt > PACKAGE_CONNECTOR_CUTOVER_DRAIN_TTL_MS
|
|
118
|
+
) {
|
|
119
|
+
removePackageConnectorCutoverDrainMarker(controllerHome);
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
process.kill(Number(marker.ownerPid), 0);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if ((error as NodeJS.ErrnoException).code !== 'EPERM') {
|
|
126
|
+
removePackageConnectorCutoverDrainMarker(controllerHome);
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return marker as PackageConnectorCutoverDrainMarker;
|
|
131
|
+
} catch {
|
|
132
|
+
removePackageConnectorCutoverDrainMarker(controllerHome);
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function armPackageConnectorCutoverDrain(input: {
|
|
138
|
+
controllerHome: string;
|
|
139
|
+
sessionId: string;
|
|
140
|
+
stableReleaseId: string;
|
|
141
|
+
connectorAuthority: PackageConnectorServiceAuthority;
|
|
142
|
+
}): PackageConnectorCutoverDrainMarker {
|
|
143
|
+
if (input.connectorAuthority.releaseId !== input.stableReleaseId) {
|
|
144
|
+
throw new Error(`PACKAGE_CONNECTOR_CUTOVER_DRAIN_STABLE_MISMATCH: expected ${input.stableReleaseId}, observed ${input.connectorAuthority.releaseId}`);
|
|
145
|
+
}
|
|
146
|
+
const currentAuthority = readPackageConnectorServiceAuthority(input.controllerHome);
|
|
147
|
+
if (
|
|
148
|
+
!currentAuthority
|
|
149
|
+
|| currentAuthority.releaseId !== input.connectorAuthority.releaseId
|
|
150
|
+
|| currentAuthority.endpoint !== input.connectorAuthority.endpoint
|
|
151
|
+
|| currentAuthority.installedAt !== input.connectorAuthority.installedAt
|
|
152
|
+
) {
|
|
153
|
+
throw new Error('PACKAGE_CONNECTOR_CUTOVER_DRAIN_AUTHORITY_CHANGED');
|
|
154
|
+
}
|
|
155
|
+
const marker: PackageConnectorCutoverDrainMarker = {
|
|
156
|
+
schemaVersion: 1,
|
|
157
|
+
sessionId: input.sessionId,
|
|
158
|
+
stableReleaseId: input.stableReleaseId,
|
|
159
|
+
connectorEndpoint: input.connectorAuthority.endpoint,
|
|
160
|
+
connectorInstalledAt: input.connectorAuthority.installedAt,
|
|
161
|
+
ownerPid: process.pid,
|
|
162
|
+
armedAt: new Date().toISOString(),
|
|
163
|
+
};
|
|
164
|
+
const path = packageConnectorCutoverDrainMarkerPath(input.controllerHome);
|
|
165
|
+
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
166
|
+
writeAtomicTextFile(path, `${JSON.stringify(marker, null, 2)}\n`, 0o600);
|
|
167
|
+
return marker;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function clearPackageConnectorCutoverDrain(controllerHome: string): void {
|
|
171
|
+
removePackageConnectorCutoverDrainMarker(controllerHome);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function packageConnectorCutoverDrainIsActive(
|
|
175
|
+
controllerHome: string,
|
|
176
|
+
connectorEndpoint: string,
|
|
177
|
+
now = Date.now(),
|
|
178
|
+
): boolean {
|
|
179
|
+
const marker = livePackageConnectorCutoverDrainMarker(controllerHome, now);
|
|
180
|
+
if (!marker || marker.connectorEndpoint !== connectorEndpoint) return false;
|
|
181
|
+
let authority: PackageConnectorServiceAuthority | undefined;
|
|
182
|
+
try {
|
|
183
|
+
authority = readPackageConnectorServiceAuthority(controllerHome);
|
|
184
|
+
} catch {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
if (!authority) return true;
|
|
188
|
+
return authority.releaseId === marker.stableReleaseId
|
|
189
|
+
&& authority.endpoint === marker.connectorEndpoint
|
|
190
|
+
&& authority.installedAt === marker.connectorInstalledAt;
|
|
191
|
+
}
|
|
192
|
+
|
|
81
193
|
export function readPackageConnectorServiceAuthority(controllerHome: string): PackageConnectorServiceAuthority | undefined {
|
|
82
194
|
const path = packageConnectorServicePaths(controllerHome).authorityPath;
|
|
83
195
|
if (!existsSync(path)) return undefined;
|
|
@@ -111,7 +223,7 @@ function writePackageConnectorServiceAuthority(input: { release: PackageConnecto
|
|
|
111
223
|
...(artifact ? { connectorArtifactIdentity: artifact.identity } : {}),
|
|
112
224
|
installedAt: input.installedAt ?? new Date().toISOString(),
|
|
113
225
|
};
|
|
114
|
-
|
|
226
|
+
writeAtomicTextFile(paths.authorityPath, `${JSON.stringify(authority, null, 2)}\n`);
|
|
115
227
|
}
|
|
116
228
|
|
|
117
229
|
export function packageConnectorEndpointStatusHealthy(status: number, authMode: PackageConnectorAuthMode = 'oauth'): boolean {
|
|
@@ -403,7 +515,7 @@ export async function installPackageConnectorService(input: { release: PackageCo
|
|
|
403
515
|
port: launch.port,
|
|
404
516
|
requiredArguments: ['mcp', 'serve', '--auth', launch.authMode],
|
|
405
517
|
});
|
|
406
|
-
|
|
518
|
+
writeAtomicTextFile(paths.sourcePlistPath, renderPackageConnectorLaunchAgent({ paths, launch }), 0o600);
|
|
407
519
|
serviceHost.installLaunchd(paths.sourcePlistPath, paths.label);
|
|
408
520
|
const result = await serviceHost.bootstrapLaunchd({ label: paths.label, plistPath: paths.installedPlistPath });
|
|
409
521
|
if (!result.ok) throw new Error(`FORGE_PACKAGE_CONNECTOR_LAUNCHD_INSTALL_FAILED: ${result.diagnostics.join('; ')}`);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { writeAtomicTextFile } from '../shared/atomic-text-file';
|
|
1
2
|
import { createHash, randomUUID } from 'crypto';
|
|
2
3
|
import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from 'fs';
|
|
3
4
|
import { dirname, join, relative, resolve } from 'path';
|
|
@@ -10,7 +11,6 @@ import { assertRuntimeReleaseExecutionSurface } from './release-manifest';
|
|
|
10
11
|
import { assertRuntimeReleaseExecutionCanaries } from './release-execution-canary';
|
|
11
12
|
import type { RuntimeReleaseManifest } from './types';
|
|
12
13
|
import { assertStorageHeadroom } from '../shared/storage-capacity';
|
|
13
|
-
import { PROCESS_RUNTIME_RELEASE_CANARY_ARG } from '../execution/process-runtime/canary';
|
|
14
14
|
|
|
15
15
|
export interface PackageRuntimeFileRecord {
|
|
16
16
|
path: string;
|
|
@@ -67,13 +67,6 @@ function sha256(value: Buffer | string): string {
|
|
|
67
67
|
return createHash('sha256').update(value).digest('hex');
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
function atomicWrite(path: string, content: string, mode = 0o600): void {
|
|
71
|
-
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
72
|
-
const temporary = `${path}.${process.pid}.${randomUUID().slice(0, 8)}.tmp`;
|
|
73
|
-
writeFileSync(temporary, content, { encoding: 'utf8', mode });
|
|
74
|
-
renameSync(temporary, path);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
70
|
function walkRegularFiles(root: string, current: string, output: string[], prefix = ''): void {
|
|
78
71
|
if (!existsSync(current)) return;
|
|
79
72
|
const stat = lstatSync(current);
|
|
@@ -226,7 +219,6 @@ function launcherSource(input: {
|
|
|
226
219
|
indexSha256: string;
|
|
227
220
|
entryRelativePath?: string;
|
|
228
221
|
managerSignalsProcessGroup?: boolean;
|
|
229
|
-
ownsProcessRuntimeCanary?: boolean;
|
|
230
222
|
}): string {
|
|
231
223
|
const entryRelativePath = input.entryRelativePath ?? 'src/runtime/root/entry.ts';
|
|
232
224
|
return `#!${process.execPath}\n`
|
|
@@ -249,8 +241,6 @@ function launcherSource(input: {
|
|
|
249
241
|
+ `if(digest(raw)!==expectedIndex){console.error('FORGE_PACKAGE_RUNTIME_INDEX_CHANGED');process.exit(78);}\n`
|
|
250
242
|
+ `let records; try { records=JSON.parse(raw.toString('utf8')).files; } catch { console.error('FORGE_PACKAGE_RUNTIME_INDEX_INVALID'); process.exit(78); }\n`
|
|
251
243
|
+ `for(const record of records){const path=join(packageRoot,record.path);if(!existsSync(path)||digest(readFileSync(path))!==record.sha256){console.error('FORGE_PACKAGE_RUNTIME_SOURCE_CHANGED: '+record.path);process.exit(78);}}\n`
|
|
252
|
-
+ `const ownsProcessRuntimeCanary=${input.ownsProcessRuntimeCanary === true ? 'true' : 'false'};\n`
|
|
253
|
-
+ `if(ownsProcessRuntimeCanary&&process.argv.length===3&&process.argv[2]===${JSON.stringify(PROCESS_RUNTIME_RELEASE_CANARY_ARG)})process.exit(0);\n`
|
|
254
244
|
+ `const entry=join(packageRoot,...${JSON.stringify(entryRelativePath.split('/'))});\n`
|
|
255
245
|
+ `const loader=join(packageRoot,'src','runtime','shared','node-ts-loader.mjs');\n`
|
|
256
246
|
+ `const args=process.versions?.bun?[entry,...process.argv.slice(2)]:['--loader',loader,entry,...process.argv.slice(2)];\n`
|
|
@@ -357,7 +347,6 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
357
347
|
const processRunnerLauncher = launcherSource({
|
|
358
348
|
indexSha256,
|
|
359
349
|
entryRelativePath: 'src/runtime/execution/process-runtime/process-runner-entry.ts',
|
|
360
|
-
ownsProcessRuntimeCanary: true,
|
|
361
350
|
});
|
|
362
351
|
const processRunnerArtifactIdentity = `sha256:${sha256(Buffer.from(processRunnerLauncher))}`;
|
|
363
352
|
const checkRunnerEntrypoint = 'forge-check-runner' as const;
|
|
@@ -365,7 +354,6 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
365
354
|
const checkRunnerLauncher = launcherSource({
|
|
366
355
|
indexSha256,
|
|
367
356
|
entryRelativePath: 'src/runtime/execution/process-runtime/check-runner-sidecar.ts',
|
|
368
|
-
ownsProcessRuntimeCanary: true,
|
|
369
357
|
});
|
|
370
358
|
const checkRunnerArtifactIdentity = `sha256:${sha256(Buffer.from(checkRunnerLauncher))}`;
|
|
371
359
|
const expectedManifest: Omit<RuntimeReleaseManifest, 'createdAt'> = {
|
|
@@ -413,16 +401,16 @@ export function materializePackageRuntimeRelease(input: {
|
|
|
413
401
|
try {
|
|
414
402
|
mkdirSync(stagingRoot, { recursive: false, mode: 0o700 });
|
|
415
403
|
stagePackageRuntimeSnapshot(sourcePackageRoot, join(stagingRoot, 'package'), records);
|
|
416
|
-
|
|
417
|
-
|
|
404
|
+
writeAtomicTextFile(join(stagingRoot, 'package-files.json'), indexJson);
|
|
405
|
+
writeAtomicTextFile(join(stagingRoot, 'forge-runtime'), launcher, 0o700);
|
|
418
406
|
chmodSync(join(stagingRoot, 'forge-runtime'), 0o700);
|
|
419
|
-
|
|
407
|
+
writeAtomicTextFile(join(stagingRoot, processRunnerEntrypoint), processRunnerLauncher, 0o700);
|
|
420
408
|
chmodSync(join(stagingRoot, processRunnerEntrypoint), 0o700);
|
|
421
|
-
|
|
409
|
+
writeAtomicTextFile(join(stagingRoot, checkRunnerEntrypoint), checkRunnerLauncher, 0o700);
|
|
422
410
|
chmodSync(join(stagingRoot, checkRunnerEntrypoint), 0o700);
|
|
423
411
|
const manifest: RuntimeReleaseManifest = { ...expectedManifest, createdAt: new Date().toISOString() };
|
|
424
412
|
const stagingManifestPath = join(stagingRoot, 'manifest.json');
|
|
425
|
-
|
|
413
|
+
writeAtomicTextFile(stagingManifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
426
414
|
// A failed execution surface is still a staging failure. Do not promote an
|
|
427
415
|
// immutable release directory until both manifest-owned runners execute
|
|
428
416
|
// their bounded no-op canary successfully.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { writeAtomicTextFile } from '../shared/atomic-text-file';
|
|
1
2
|
import { randomUUID } from 'crypto';
|
|
2
|
-
import { existsSync,
|
|
3
|
+
import { existsSync, readFileSync, rmSync } from 'fs';
|
|
3
4
|
import { setTimeout as sleep } from 'timers/promises';
|
|
4
5
|
import { dirname, join, resolve } from 'path';
|
|
5
6
|
import { resolveControllerHome } from '../../cli/repositories/controller-home';
|
|
@@ -114,13 +115,6 @@ export interface PackageRuntimeActivationDependencies {
|
|
|
114
115
|
cleanupActivationHelper?: (request: PackageRuntimeActivationRequest) => Promise<void>;
|
|
115
116
|
}
|
|
116
117
|
|
|
117
|
-
function atomicWrite(path: string, content: string, mode = 0o600): void {
|
|
118
|
-
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
119
|
-
const temporary = `${path}.${process.pid}.tmp`;
|
|
120
|
-
writeFileSync(temporary, content, { encoding: 'utf8', mode });
|
|
121
|
-
renameSync(temporary, path);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
118
|
export function renderForgeRuntimeSystemdUserUnit(input: {
|
|
125
119
|
description?: string;
|
|
126
120
|
executable: string;
|
|
@@ -189,7 +183,7 @@ function startPortableRuntime(controllerHome: string, env: NodeJS.ProcessEnv, ho
|
|
|
189
183
|
stderrPath: paths.stderrPath,
|
|
190
184
|
errorCode: 'FORGE_PORTABLE_RUNTIME_START_FAILED',
|
|
191
185
|
});
|
|
192
|
-
|
|
186
|
+
writeAtomicTextFile(join(paths.serviceRoot, 'portable.json'), `${JSON.stringify({ schemaVersion: 1, pid, startedAt: new Date().toISOString() }, null, 2)}\n`);
|
|
193
187
|
return pid;
|
|
194
188
|
}
|
|
195
189
|
|
|
@@ -208,7 +202,7 @@ function activationPaths(controllerHome: string, operationId: string): { request
|
|
|
208
202
|
}
|
|
209
203
|
|
|
210
204
|
function writeActivationRequest(request: PackageRuntimeActivationRequest): void {
|
|
211
|
-
|
|
205
|
+
writeAtomicTextFile(request.requestPath, `${JSON.stringify(request, null, 2)}\n`);
|
|
212
206
|
}
|
|
213
207
|
|
|
214
208
|
function writeActivationReceipt(
|
|
@@ -232,7 +226,7 @@ function writeActivationReceipt(
|
|
|
232
226
|
helperLabel: request.helperLabel,
|
|
233
227
|
...extra,
|
|
234
228
|
};
|
|
235
|
-
|
|
229
|
+
writeAtomicTextFile(request.receiptPath, `${JSON.stringify(receipt, null, 2)}\n`);
|
|
236
230
|
return receipt;
|
|
237
231
|
}
|
|
238
232
|
|
|
@@ -299,7 +293,7 @@ export function renderPackageRuntimeActivationLaunchAgent(request: PackageRuntim
|
|
|
299
293
|
async function scheduleDarwinPackageRuntimeActivation(request: PackageRuntimeActivationRequest): Promise<{ label: string; servicePath: string }> {
|
|
300
294
|
if (process.platform !== 'darwin') throw new Error('FORGE_PACKAGE_RUNTIME_ACTIVATION_HELPER_PLATFORM_UNSUPPORTED');
|
|
301
295
|
const host = createPlatformServiceManagerHost({ platform: 'darwin' });
|
|
302
|
-
|
|
296
|
+
writeAtomicTextFile(request.helperSourcePlistPath, renderPackageRuntimeActivationLaunchAgent(request), 0o600);
|
|
303
297
|
host.installLaunchd(request.helperSourcePlistPath, request.helperLabel);
|
|
304
298
|
const result = await host.bootstrapLaunchd({ label: request.helperLabel, plistPath: request.helperInstalledPlistPath });
|
|
305
299
|
if (!result.ok) throw new Error(`FORGE_PACKAGE_RUNTIME_ACTIVATION_HELPER_BOOTSTRAP_FAILED: ${result.diagnostics.join('; ')}`);
|
|
@@ -351,7 +345,7 @@ async function rollbackPackageRuntimeActivation(
|
|
|
351
345
|
}
|
|
352
346
|
try {
|
|
353
347
|
if (request.priorConfigBytes === undefined) rmSync(servicePaths.configPath, { force: true });
|
|
354
|
-
else
|
|
348
|
+
else writeAtomicTextFile(servicePaths.configPath, request.priorConfigBytes);
|
|
355
349
|
syncForgeRuntimeActiveEntrypoint(request.controllerHome);
|
|
356
350
|
} catch (error) {
|
|
357
351
|
errors.push(error instanceof Error ? error.message : String(error));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
1
2
|
import { join } from 'path';
|
|
2
3
|
import { runProcess } from '../../effects/process-runner';
|
|
3
4
|
import { PROCESS_RUNTIME_RELEASE_CANARY_ARG } from '../execution/process-runtime/canary';
|
|
@@ -25,9 +26,9 @@ export interface RuntimeReleaseExecutionCanaryDependencies {
|
|
|
25
26
|
/**
|
|
26
27
|
* Release execution canaries deliberately do not inherit developer-tool PATH
|
|
27
28
|
* entries. Standalone-binary artifacts must execute without Homebrew, Bun, nvm,
|
|
28
|
-
* or similar PATH dependencies. Legacy
|
|
29
|
-
*
|
|
30
|
-
* executable
|
|
29
|
+
* or similar PATH dependencies. Legacy source scripts are probed through the
|
|
30
|
+
* same explicitly resolved Bun executable that their Process Runtime uses in
|
|
31
|
+
* production, while executable shebangs remain the artifact's own launch contract.
|
|
31
32
|
*/
|
|
32
33
|
export function runtimeReleaseCanaryEnvironment(
|
|
33
34
|
env: NodeJS.ProcessEnv = process.env,
|
|
@@ -43,6 +44,17 @@ export function runtimeReleaseCanaryEnvironment(
|
|
|
43
44
|
return { ...env, PATH: '/usr/bin:/bin:/usr/sbin:/sbin' };
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Execute legacy JavaScript/TypeScript through the resolved Bun runtime only
|
|
49
|
+
* when the artifact does not declare a different executable shebang.
|
|
50
|
+
*/
|
|
51
|
+
function releaseScriptRequiresBun(entryPath: string): boolean {
|
|
52
|
+
const firstLine = readFileSync(entryPath, 'utf8').split(/\r?\n/, 1)[0]?.trim() ?? '';
|
|
53
|
+
if (!firstLine.startsWith('#!')) return true;
|
|
54
|
+
const shebangTokens = firstLine.slice(2).trim().split(/\s+/).filter(Boolean);
|
|
55
|
+
return shebangTokens.some((token) => /(?:^|\/)bun(?:\.exe)?$/i.test(token));
|
|
56
|
+
}
|
|
57
|
+
|
|
46
58
|
/**
|
|
47
59
|
* Execute the minimum immutable Runtime execution surface plus the package
|
|
48
60
|
* Connector CLI import graph. The latter is intentionally a help-only command:
|
|
@@ -81,10 +93,11 @@ export function assertRuntimeReleaseExecutionCanaries(
|
|
|
81
93
|
const args = entry.canary === 'runtime_interpreter' ? ['--version'] : [PROCESS_RUNTIME_RELEASE_CANARY_ARG];
|
|
82
94
|
const legacyScript = surface.manifest.executionMode !== 'standalone-binary'
|
|
83
95
|
&& /\.(?:[cm]?js|tsx?)$/i.test(entry.path);
|
|
96
|
+
const usesExplicitBun = legacyScript && releaseScriptRequiresBun(entry.path);
|
|
84
97
|
assertCanary({
|
|
85
98
|
name: entry.name,
|
|
86
|
-
executable:
|
|
87
|
-
args:
|
|
99
|
+
executable: usesExplicitBun ? resolveBunExecutable(process.execPath, process.env) : entry.path,
|
|
100
|
+
args: usesExplicitBun ? [entry.path, ...args] : args,
|
|
88
101
|
});
|
|
89
102
|
}
|
|
90
103
|
|
|
@@ -65,9 +65,6 @@ export const COMPILED_RUNTIME_RELEASE_COMPONENT_FIELDS = [
|
|
|
65
65
|
'periodicCleanupEntrypoint', 'periodicCleanupArtifactIdentity',
|
|
66
66
|
'pluginActionSidecarEntrypoint', 'pluginActionSidecarArtifactIdentity',
|
|
67
67
|
'externalPluginProbeEntrypoint', 'externalPluginProbeArtifactIdentity',
|
|
68
|
-
'codeGraphNodeEntrypoint', 'codeGraphNodeArtifactIdentity',
|
|
69
|
-
'codeGraphSidecarEntrypoint', 'codeGraphSidecarArtifactIdentity',
|
|
70
|
-
'codeGraphLibraryRoot', 'codeGraphLibraryArtifactIdentity',
|
|
71
68
|
'packageRoot', 'packageArtifactIdentity',
|
|
72
69
|
] as const satisfies readonly (keyof RuntimeReleaseManifest)[];
|
|
73
70
|
|
|
@@ -278,36 +275,6 @@ export function loadRuntimeReleaseManifest(
|
|
|
278
275
|
};
|
|
279
276
|
}
|
|
280
277
|
|
|
281
|
-
const codeGraphFields = [
|
|
282
|
-
value.codeGraphNodeEntrypoint,
|
|
283
|
-
value.codeGraphNodeArtifactIdentity,
|
|
284
|
-
value.codeGraphSidecarEntrypoint,
|
|
285
|
-
value.codeGraphSidecarArtifactIdentity,
|
|
286
|
-
value.codeGraphLibraryRoot,
|
|
287
|
-
value.codeGraphLibraryArtifactIdentity,
|
|
288
|
-
];
|
|
289
|
-
const hasCodeGraphRuntime = codeGraphFields.some((entry) => entry !== undefined);
|
|
290
|
-
let codeGraphRuntime: Pick<RuntimeReleaseManifest,
|
|
291
|
-
'codeGraphNodeEntrypoint' | 'codeGraphNodeArtifactIdentity'
|
|
292
|
-
| 'codeGraphSidecarEntrypoint' | 'codeGraphSidecarArtifactIdentity'
|
|
293
|
-
| 'codeGraphLibraryRoot' | 'codeGraphLibraryArtifactIdentity'> | undefined;
|
|
294
|
-
if (hasCodeGraphRuntime) {
|
|
295
|
-
const nodeEntrypoint = requireString(value.codeGraphNodeEntrypoint, 'codeGraphNodeEntrypoint');
|
|
296
|
-
const sidecarEntrypoint = requireString(value.codeGraphSidecarEntrypoint, 'codeGraphSidecarEntrypoint');
|
|
297
|
-
const libraryRoot = requireString(value.codeGraphLibraryRoot, 'codeGraphLibraryRoot');
|
|
298
|
-
if (nodeEntrypoint !== 'codegraph-node' || sidecarEntrypoint !== 'codegraph-sidecar.cjs' || libraryRoot !== 'codegraph-lib') {
|
|
299
|
-
throw new Error('RELEASE_MANIFEST_INVALID: CodeGraph release paths must use the canonical co-located names');
|
|
300
|
-
}
|
|
301
|
-
codeGraphRuntime = {
|
|
302
|
-
codeGraphNodeEntrypoint: 'codegraph-node',
|
|
303
|
-
codeGraphNodeArtifactIdentity: requireSha256Identity(value.codeGraphNodeArtifactIdentity, 'codeGraphNodeArtifactIdentity'),
|
|
304
|
-
codeGraphSidecarEntrypoint: 'codegraph-sidecar.cjs',
|
|
305
|
-
codeGraphSidecarArtifactIdentity: requireSha256Identity(value.codeGraphSidecarArtifactIdentity, 'codeGraphSidecarArtifactIdentity'),
|
|
306
|
-
codeGraphLibraryRoot: 'codegraph-lib',
|
|
307
|
-
codeGraphLibraryArtifactIdentity: requireSha256Identity(value.codeGraphLibraryArtifactIdentity, 'codeGraphLibraryArtifactIdentity'),
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
|
|
311
278
|
const argumentsValue = value.arguments;
|
|
312
279
|
if (!Array.isArray(argumentsValue) || argumentsValue.some((item) => typeof item !== 'string')) {
|
|
313
280
|
throw new Error('RELEASE_MANIFEST_INVALID: arguments must be a string array');
|
|
@@ -341,7 +308,6 @@ export function loadRuntimeReleaseManifest(
|
|
|
341
308
|
...(pluginActionSidecar ?? {}),
|
|
342
309
|
...(externalPluginProbe ?? {}),
|
|
343
310
|
...(browserAutomationHelper ?? {}),
|
|
344
|
-
...(codeGraphRuntime ?? {}),
|
|
345
311
|
...(packageSnapshot ?? {}),
|
|
346
312
|
...(controllerUi ?? {}),
|
|
347
313
|
arguments: argumentsValue as string[],
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'crypto';
|
|
2
|
-
import { createRequire } from 'module';
|
|
3
2
|
import { chmodSync, copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync } from 'fs';
|
|
4
3
|
import { tmpdir } from 'os';
|
|
5
4
|
import { dirname, join, relative, resolve } from 'path';
|
|
@@ -50,9 +49,6 @@ export interface StagedRuntimeRelease {
|
|
|
50
49
|
periodicCleanupArtifactIdentity?: string;
|
|
51
50
|
pluginActionSidecarArtifactIdentity?: string;
|
|
52
51
|
externalPluginProbeArtifactIdentity?: string;
|
|
53
|
-
codeGraphNodeArtifactIdentity?: string;
|
|
54
|
-
codeGraphSidecarArtifactIdentity?: string;
|
|
55
|
-
codeGraphLibraryArtifactIdentity?: string;
|
|
56
52
|
packageArtifactIdentity?: string;
|
|
57
53
|
controllerUiArtifactIdentity?: string;
|
|
58
54
|
macosCodeSigning?: MacOSRuntimeCodeSigning;
|
|
@@ -71,12 +67,6 @@ export interface RuntimeReleaseMaterializerDependencies {
|
|
|
71
67
|
materializeRuntimeInterpreter?: (input: { sourceRoot: string; outputPath: string }) => { ok: boolean; stderr?: string; stdout?: string; error?: string };
|
|
72
68
|
bundleNodeHost?: (input: { sourceRoot: string; outputPath: string; entryPath: string }) => { ok: boolean; stderr?: string; stdout?: string; error?: string };
|
|
73
69
|
bundleProcessRunner?: (input: { sourceRoot: string; outputPath: string; entryPath: string }) => { ok: boolean; stderr?: string; stdout?: string; error?: string };
|
|
74
|
-
materializeCodeGraphRuntime?: (input: {
|
|
75
|
-
sourceRoot: string;
|
|
76
|
-
nodeOutputPath: string;
|
|
77
|
-
sidecarOutputPath: string;
|
|
78
|
-
libraryOutputPath: string;
|
|
79
|
-
}) => { ok: boolean; stderr?: string; stdout?: string; error?: string };
|
|
80
70
|
}
|
|
81
71
|
|
|
82
72
|
export interface CandidateRuntimeStageReceiptV1 {
|
|
@@ -450,9 +440,6 @@ export function stageRuntimeReleaseFromCandidateSource(input: {
|
|
|
450
440
|
periodicCleanupArtifactIdentity: manifest.periodicCleanupArtifactIdentity,
|
|
451
441
|
pluginActionSidecarArtifactIdentity: manifest.pluginActionSidecarArtifactIdentity,
|
|
452
442
|
externalPluginProbeArtifactIdentity: manifest.externalPluginProbeArtifactIdentity,
|
|
453
|
-
codeGraphNodeArtifactIdentity: manifest.codeGraphNodeArtifactIdentity,
|
|
454
|
-
codeGraphSidecarArtifactIdentity: manifest.codeGraphSidecarArtifactIdentity,
|
|
455
|
-
codeGraphLibraryArtifactIdentity: manifest.codeGraphLibraryArtifactIdentity,
|
|
456
443
|
packageArtifactIdentity: manifest.packageArtifactIdentity,
|
|
457
444
|
controllerUiArtifactIdentity: manifest.controllerUiArtifactIdentity,
|
|
458
445
|
...(macosCodeSigning ? { macosCodeSigning } : {}),
|
|
@@ -526,32 +513,6 @@ function defaultBundleNodeScript(input: { sourceRoot: string; outputPath: string
|
|
|
526
513
|
], { cwd: input.sourceRoot, timeoutMs: 300_000, maxOutputBytes: 512 * 1024 });
|
|
527
514
|
}
|
|
528
515
|
|
|
529
|
-
function defaultMaterializeCodeGraphRuntime(input: {
|
|
530
|
-
sourceRoot: string;
|
|
531
|
-
nodeOutputPath: string;
|
|
532
|
-
sidecarOutputPath: string;
|
|
533
|
-
libraryOutputPath: string;
|
|
534
|
-
}): { ok: boolean; stderr?: string; stdout?: string; error?: string } {
|
|
535
|
-
try {
|
|
536
|
-
const sourceRequire = createRequire(join(input.sourceRoot, 'package.json'));
|
|
537
|
-
const platformPackage = `@colbymchenry/codegraph-${process.platform}-${process.arch}`;
|
|
538
|
-
const packageJson = sourceRequire.resolve(`${platformPackage}/package.json`);
|
|
539
|
-
const packageRoot = dirname(packageJson);
|
|
540
|
-
const nodeSource = join(packageRoot, process.platform === 'win32' ? 'node.exe' : 'node');
|
|
541
|
-
const librarySource = join(packageRoot, 'lib');
|
|
542
|
-
const sidecarSource = join(input.sourceRoot, 'src', 'runtime', 'context', 'codegraph-sidecar.cjs');
|
|
543
|
-
if (!existsSync(nodeSource) || !statSync(nodeSource).isFile()) throw new Error(`${platformPackage} Node runtime is missing`);
|
|
544
|
-
if (!existsSync(librarySource) || !statSync(librarySource).isDirectory()) throw new Error(`${platformPackage} library is missing`);
|
|
545
|
-
if (!existsSync(sidecarSource)) throw new Error('CodeGraph sidecar source is missing');
|
|
546
|
-
copyFileSync(nodeSource, input.nodeOutputPath);
|
|
547
|
-
copyFileSync(sidecarSource, input.sidecarOutputPath);
|
|
548
|
-
cpSync(librarySource, input.libraryOutputPath, { recursive: true, force: false });
|
|
549
|
-
return { ok: true };
|
|
550
|
-
} catch (error) {
|
|
551
|
-
return { ok: false, error: error instanceof Error ? error.message : String(error) };
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
|
|
555
516
|
export function stageRuntimeRelease(input: {
|
|
556
517
|
controllerHome: string;
|
|
557
518
|
sourceRoot: string;
|
|
@@ -799,27 +760,6 @@ export function stageRuntimeRelease(input: {
|
|
|
799
760
|
chmodSync(externalPluginProbePath, 0o700);
|
|
800
761
|
const externalPluginProbeArtifactIdentity = `sha256:${sha256(externalPluginProbePath)}`;
|
|
801
762
|
|
|
802
|
-
const codeGraphNodeEntrypoint = 'codegraph-node' as const;
|
|
803
|
-
const codeGraphSidecarEntrypoint = 'codegraph-sidecar.cjs' as const;
|
|
804
|
-
const codeGraphLibraryRoot = 'codegraph-lib' as const;
|
|
805
|
-
const codeGraphNodePath = join(staging, codeGraphNodeEntrypoint);
|
|
806
|
-
const codeGraphSidecarPath = join(staging, codeGraphSidecarEntrypoint);
|
|
807
|
-
const codeGraphLibraryPath = join(staging, codeGraphLibraryRoot);
|
|
808
|
-
const codeGraphRuntime = (dependencies.materializeCodeGraphRuntime ?? defaultMaterializeCodeGraphRuntime)({
|
|
809
|
-
sourceRoot,
|
|
810
|
-
nodeOutputPath: codeGraphNodePath,
|
|
811
|
-
sidecarOutputPath: codeGraphSidecarPath,
|
|
812
|
-
libraryOutputPath: codeGraphLibraryPath,
|
|
813
|
-
});
|
|
814
|
-
if (!codeGraphRuntime.ok) {
|
|
815
|
-
throw new Error(`RUNTIME_RELEASE_CODEGRAPH_BUILD_FAILED: ${codeGraphRuntime.stderr || codeGraphRuntime.stdout || codeGraphRuntime.error}`.slice(0, 2_000));
|
|
816
|
-
}
|
|
817
|
-
chmodSync(codeGraphNodePath, 0o700);
|
|
818
|
-
chmodSync(codeGraphSidecarPath, 0o700);
|
|
819
|
-
const codeGraphNodeArtifactIdentity = `sha256:${sha256(codeGraphNodePath)}`;
|
|
820
|
-
const codeGraphSidecarArtifactIdentity = `sha256:${sha256(codeGraphSidecarPath)}`;
|
|
821
|
-
const codeGraphLibraryArtifactIdentity = `sha256:${sha256Directory(codeGraphLibraryPath)}`;
|
|
822
|
-
|
|
823
763
|
// Keep the source-backed package projection during the Recovery migration.
|
|
824
764
|
// The active standalone Recovery release can predate the compiled Connector
|
|
825
765
|
// sidecar and still rebind the primary Connector through package/src/cli.
|
|
@@ -870,12 +810,6 @@ export function stageRuntimeRelease(input: {
|
|
|
870
810
|
pluginActionSidecarArtifactIdentity,
|
|
871
811
|
externalPluginProbeEntrypoint,
|
|
872
812
|
externalPluginProbeArtifactIdentity,
|
|
873
|
-
codeGraphNodeEntrypoint,
|
|
874
|
-
codeGraphNodeArtifactIdentity,
|
|
875
|
-
codeGraphSidecarEntrypoint,
|
|
876
|
-
codeGraphSidecarArtifactIdentity,
|
|
877
|
-
codeGraphLibraryRoot,
|
|
878
|
-
codeGraphLibraryArtifactIdentity,
|
|
879
813
|
packageRoot,
|
|
880
814
|
packageArtifactIdentity,
|
|
881
815
|
arguments: [],
|
|
@@ -917,9 +851,6 @@ export function stageRuntimeRelease(input: {
|
|
|
917
851
|
periodicCleanupArtifactIdentity,
|
|
918
852
|
pluginActionSidecarArtifactIdentity,
|
|
919
853
|
externalPluginProbeArtifactIdentity,
|
|
920
|
-
codeGraphNodeArtifactIdentity,
|
|
921
|
-
codeGraphSidecarArtifactIdentity,
|
|
922
|
-
codeGraphLibraryArtifactIdentity,
|
|
923
854
|
packageArtifactIdentity,
|
|
924
855
|
manifestSha256: createHash('sha256').update(`${JSON.stringify(manifest, null, 2)}\n`).digest('hex'),
|
|
925
856
|
sourceCommit,
|
|
@@ -1165,15 +1096,6 @@ export function assertRuntimeReleaseFiles(release: StagedRuntimeRelease, depende
|
|
|
1165
1096
|
assertComponentFile({ path: join(release.releasePath, 'forge-periodic-cleanup'), identity: release.periodicCleanupArtifactIdentity, missingCode: 'RUNTIME_RELEASE_PERIODIC_CLEANUP_MISSING', executable: true });
|
|
1166
1097
|
assertComponentFile({ path: join(release.releasePath, 'forge-plugin-action-sidecar'), identity: release.pluginActionSidecarArtifactIdentity, missingCode: 'RUNTIME_RELEASE_PLUGIN_ACTION_SIDECAR_MISSING', executable: true });
|
|
1167
1098
|
assertComponentFile({ path: join(release.releasePath, 'external-unix-socket-probe.cjs'), identity: release.externalPluginProbeArtifactIdentity, missingCode: 'RUNTIME_RELEASE_EXTERNAL_PLUGIN_PROBE_MISSING', executable: true });
|
|
1168
|
-
assertComponentFile({ path: join(release.releasePath, 'codegraph-node'), identity: release.codeGraphNodeArtifactIdentity, missingCode: 'RUNTIME_RELEASE_CODEGRAPH_NODE_MISSING', executable: true });
|
|
1169
|
-
assertComponentFile({ path: join(release.releasePath, 'codegraph-sidecar.cjs'), identity: release.codeGraphSidecarArtifactIdentity, missingCode: 'RUNTIME_RELEASE_CODEGRAPH_SIDECAR_MISSING', executable: true });
|
|
1170
|
-
if (release.codeGraphLibraryArtifactIdentity) {
|
|
1171
|
-
const libraryRoot = join(release.releasePath, 'codegraph-lib');
|
|
1172
|
-
if (!existsSync(join(libraryRoot, 'dist', 'index.js'))) {
|
|
1173
|
-
throw new Error(`RUNTIME_RELEASE_CODEGRAPH_LIBRARY_MISSING: ${join(libraryRoot, 'dist', 'index.js')}`);
|
|
1174
|
-
}
|
|
1175
|
-
assertDirectoryIdentity(libraryRoot, release.codeGraphLibraryArtifactIdentity);
|
|
1176
|
-
}
|
|
1177
1099
|
if (release.packageArtifactIdentity) {
|
|
1178
1100
|
const packageRoot = join(release.releasePath, 'package');
|
|
1179
1101
|
assertDirectoryIdentity(packageRoot, release.packageArtifactIdentity);
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
enableControlPlaneReadConnectionReuse,
|
|
11
11
|
inspectControlPlaneDatabase,
|
|
12
12
|
} from '../control-plane/persistence/sqlite-store';
|
|
13
|
-
import { closeCodeGraphReadProviderSessions } from '../context/codegraph-read-provider';
|
|
14
13
|
import { cancelAllLightweightProcesses } from '../execution/process-runtime/lightweight-managed';
|
|
15
14
|
import {
|
|
16
15
|
collectRuntimeSourceIdentity,
|
|
@@ -196,7 +195,7 @@ const DEFAULT_DEPENDENCIES: CanonicalRuntimeDependencies = {
|
|
|
196
195
|
collectRuntimeSourceIdentity,
|
|
197
196
|
rotateRuntimeGeneration,
|
|
198
197
|
stopLightweightProcesses: cancelAllLightweightProcesses,
|
|
199
|
-
stopContextReadHelpers:
|
|
198
|
+
stopContextReadHelpers: async () => {},
|
|
200
199
|
computeToolSurfaceFingerprint: runtimeGatewayToolSurfaceFingerprint,
|
|
201
200
|
ensureForgeInstanceIdentity,
|
|
202
201
|
captureJscSamplingProfile: captureDefaultJscSamplingProfile,
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type ControllerSession,
|
|
7
7
|
} from '../../../packages/kernel/controller/api/index';
|
|
8
8
|
import { upsertChatgptControllerBinding } from '../../../adapters/chatgpt/controller-binding-store';
|
|
9
|
+
import { DEFAULT_CHATGPT_AUTOMATION_REASONING } from '../../../adapters/chatgpt/provider-delivery';
|
|
9
10
|
import { getWorkContract } from '../../../packages/kernel/work/api/index';
|
|
10
11
|
import { inheritWorkflowSupervisorConversationBinding } from './workflow-supervisor-composition';
|
|
11
12
|
import { getChatgptWorkConversationBinding } from '../../../adapters/chatgpt/work-conversation-binding-store';
|
|
@@ -30,7 +31,7 @@ export function ensureScheduledControllerBinding(
|
|
|
30
31
|
].map(value => value.trim()).filter(Boolean).filter((value, index, values) => values.indexOf(value) === index),
|
|
31
32
|
title: input.scheduleName,
|
|
32
33
|
model: typeof input.args.model === 'string' ? input.args.model : 'gpt-5.6',
|
|
33
|
-
reasoning: input.args.reasoning === 'medium' || input.args.reasoning === 'high' || input.args.reasoning === 'xhigh' ? input.args.reasoning :
|
|
34
|
+
reasoning: input.args.reasoning === 'medium' || input.args.reasoning === 'high' || input.args.reasoning === 'xhigh' ? input.args.reasoning : DEFAULT_CHATGPT_AUTOMATION_REASONING,
|
|
34
35
|
tabPolicy: input.args.tab_policy === 'reuse' || input.args.tab_policy === 'new' ? input.args.tab_policy : 'auto',
|
|
35
36
|
timeoutMs: typeof input.args.timeout_ms === 'number' ? input.args.timeout_ms : undefined,
|
|
36
37
|
}).binding;
|