@moretea-labs/forge 1.7.0 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -0
- package/CHANGELOG.md +13 -0
- package/CLAUDE.md +2 -0
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/agents/openai.yaml +1 -1
- package/assets/partials-agents/02-operating-mode.partial.md +2 -0
- package/assets/plugin-registry.v1.json +3 -3
- package/assets/skill-version.json +2 -2
- package/assets/templates/helpers/check-architecture-sync.sh +17 -0
- package/assets/templates/helpers/inspect-project-state.ts +8 -6
- package/assets/templates/helpers/migrate-workflow-docs.ts +9 -7
- package/assets/templates/helpers/workflow-contract.ts +5 -1
- package/docs/architecture/CURRENT.md +12 -4
- package/docs/forge-plugin-management.md +1 -1
- package/docs/operations/controller-performance-and-502.md +19 -0
- package/docs/operations/homebrew.md +2 -2
- package/package.json +5 -2
- package/scripts/architecture-event.ts +2 -820
- package/scripts/architecture-queue.sh +2 -645
- package/scripts/archive-architecture-request.sh +2 -242
- package/scripts/archive-workflow.sh +1 -291
- package/scripts/benchmark-work-efficiency.ts +0 -0
- package/scripts/capability-config.ts +2 -392
- package/scripts/capability-resolver.ts +2 -503
- package/scripts/capture-plan.sh +1 -332
- package/scripts/check-agent-tooling.sh +2 -1531
- package/scripts/check-architecture-sync.sh +2 -302
- package/scripts/check-brain-manifest.sh +2 -253
- package/scripts/check-context-files.sh +2 -47
- package/scripts/check-deploy-sql-order.sh +2 -115
- package/scripts/check-runtime-architecture.mjs +243 -16
- package/scripts/check-skill-version.ts +3 -191
- package/scripts/check-source-duplication.mjs +61 -0
- package/scripts/check-stable-baseline.ts +0 -0
- package/scripts/check-task-sync.sh +2 -63
- package/scripts/check-task-workflow.sh +2 -1000
- package/scripts/codex-handoff-resume.sh +2 -267
- package/scripts/context-contract-sync.sh +2 -514
- package/scripts/contract-run.ts +2 -463
- package/scripts/contract-worktree.sh +1 -702
- package/scripts/ensure-task-workflow.sh +1 -1192
- package/scripts/inspect-project-state.ts +4 -279
- package/scripts/lib/project-init-lib.sh +7 -2
- package/scripts/lib/run-forge-helper.sh +19 -0
- package/scripts/lib/run-forge-helper.ts +26 -0
- package/scripts/migrate-project-template.sh +1 -33
- package/scripts/migrate-workflow-docs.ts +4 -412
- package/scripts/new-plan.sh +1 -180
- package/scripts/new-spec.sh +1 -47
- package/scripts/new-sprint.sh +1 -46
- package/scripts/plan-to-todo.sh +1 -771
- package/scripts/prepare-codex-handoff.sh +2 -201
- package/scripts/prepare-handoff.sh +1 -78
- package/scripts/refresh-current-status.sh +2 -467
- package/scripts/run-governed-gate.ts +3 -0
- package/scripts/select-agent-context-blocks.sh +2 -64
- package/scripts/ship-worktrees.sh +1 -531
- package/scripts/sprint-backlog.sh +1 -834
- package/scripts/stage-runtime-release.ts +2 -1
- package/scripts/summarize-failures.sh +2 -123
- package/scripts/switch-plan.sh +1 -150
- package/scripts/sync-brain-docs.sh +2 -379
- package/scripts/sync-generated-authority.mjs +175 -0
- package/scripts/verify-contract.sh +2 -593
- package/scripts/verify-sprint.sh +1 -500
- package/scripts/workflow-contract.ts +4 -201
- package/scripts/workstream-sync.sh +2 -261
- package/src/cli/agent-jobs/executor-health.ts +1 -1
- package/src/cli/commands/plugin.ts +12 -3
- package/src/cli/controller/check-runner.ts +7 -2
- package/src/cli/controller/context-pack.ts +46 -21
- package/src/cli/github/contracts.ts +16 -0
- package/src/cli/github/github.ts +2 -16
- package/src/cli/github/session.ts +2 -1
- package/src/cli/local-bridge/facade-api.ts +37 -47
- package/src/cli/local-bridge/server.ts +2 -2
- package/src/cli/mcp/legacy-tool-service.ts +10 -33
- package/src/cli/mcp/post-finalize-work-attribution.ts +150 -0
- package/src/cli/mcp/repository-tools.ts +85 -89
- package/src/cli/mcp/server.ts +57 -13
- package/src/cli/mcp/tool-contract.ts +14 -0
- package/src/cli/mcp/toolset.ts +2 -2
- package/src/cli/mcp/transports/http.ts +23 -0
- package/src/cli/repositories/command-classifier.ts +2 -2
- package/src/cli/repositories/command-executor.ts +24 -6
- package/src/cli/repositories/repository-snapshot.ts +5 -2
- package/src/cli/repositories/structured-git.ts +57 -3
- package/src/cli/repository/inspector.ts +11 -3
- package/src/runtime/context/generic-lsp-provider.ts +1 -1
- package/src/runtime/context/semantic-navigation-contract.ts +61 -0
- package/src/runtime/context/semantic-navigation.ts +9 -61
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +18 -25
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +106 -0
- package/src/runtime/control-plane/execution/retained-work-resume.ts +203 -0
- package/src/runtime/control-plane/execution/work-completion-authority.ts +58 -0
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +200 -0
- package/src/runtime/control-plane/execution/work-execution-support.ts +386 -0
- package/src/runtime/control-plane/execution/work-finalization-service.ts +1913 -0
- package/src/runtime/control-plane/execution/work-handle-authority.ts +96 -0
- package/src/runtime/control-plane/execution/work-handle-store.ts +1 -1
- package/src/runtime/control-plane/execution/work-operation-service.ts +468 -0
- package/src/runtime/control-plane/execution/work-path-scope.ts +37 -0
- package/src/runtime/control-plane/execution/work-preparation-service.ts +479 -0
- package/src/runtime/control-plane/execution/work-process-evidence.ts +129 -0
- package/src/runtime/control-plane/execution/work-task-receipt.ts +4 -43
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +13 -3
- package/src/runtime/control-plane/execution/work-verification-context.ts +56 -0
- package/src/runtime/control-plane/execution/work-verification-service.ts +388 -0
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +5 -1
- package/src/runtime/control-plane/facade/controller-round-relay.ts +164 -37
- package/src/runtime/control-plane/facade/controller-session-store.ts +183 -24
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +15 -1
- package/src/runtime/control-plane/facade/goal-workloop.ts +329 -148
- package/src/runtime/control-plane/facade/index.ts +2 -0
- package/src/runtime/control-plane/facade/plan-contract-store.ts +90 -22
- package/src/runtime/control-plane/facade/repository-work-admission.ts +147 -0
- package/src/runtime/control-plane/facade/requirement-authority.ts +83 -0
- package/src/runtime/control-plane/facade/types.ts +68 -5
- package/src/runtime/control-plane/facade/work-contract-store.ts +3 -209
- package/src/runtime/control-plane/facade/work-state-machine.ts +250 -0
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +14 -7
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +5 -1
- package/src/runtime/control-plane/launcher/chatgpt-work-binding-store.ts +13 -0
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +15 -6
- package/src/runtime/control-plane/launcher/launch-reservation-store.ts +54 -5
- package/src/runtime/control-plane/launcher/thin-launcher.ts +56 -7
- package/src/runtime/control-plane/persistence/requirement-store.ts +0 -12
- package/src/runtime/control-plane/repo-actor/registry.ts +4 -2
- package/src/runtime/control-plane/routing/route-policy.ts +18 -6
- package/src/runtime/control-plane/routing/workspace-admission.ts +70 -0
- package/src/runtime/evidence/process-check-execution.ts +18 -0
- package/src/runtime/execution/jobs/child-reference.ts +6 -2
- package/src/runtime/execution/process-runtime/check-result.ts +53 -18
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +7 -1
- package/src/runtime/execution/process-runtime/command-facade.ts +39 -17
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +20 -3
- package/src/runtime/execution/process-runtime/persisted-check.ts +4 -1
- package/src/runtime/execution/process-runtime/runtime.ts +10 -0
- package/src/runtime/execution/process-runtime/types.ts +2 -12
- package/src/runtime/execution/work-activity.ts +21 -0
- package/src/runtime/execution/workers/executor.ts +18 -13
- package/src/runtime/gateway/mcp/execution-tools.ts +35 -2930
- package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +61 -0
- package/src/runtime/gateway/mcp/router.ts +2 -2
- package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +21 -2
- package/src/runtime/gateway/mcp/runtime-tools.ts +805 -1009
- package/src/runtime/plugins/app-store-connect-adapter.ts +93 -28
- package/src/runtime/plugins/browser-adapter.ts +256 -1083
- package/src/runtime/plugins/browser-handoff-host.ts +2 -25
- package/src/runtime/plugins/browser-handoff.ts +18 -3
- package/src/runtime/plugins/browser-macos-bridge.ts +121 -16
- package/src/runtime/plugins/browser-manifest-surface.ts +603 -0
- package/src/runtime/plugins/browser-native-session-service.ts +222 -0
- package/src/runtime/plugins/browser-runtime-contract.ts +2 -0
- package/src/runtime/plugins/browser-runtime.ts +10 -0
- package/src/runtime/plugins/browser-session-store.ts +121 -0
- package/src/runtime/plugins/browser-session-types.ts +98 -0
- package/src/runtime/plugins/desktop-operator-registration.ts +4 -4
- package/src/runtime/plugins/external-adapter.ts +92 -58
- package/src/runtime/plugins/macos-capability-broker.ts +0 -8
- package/src/runtime/plugins/store.ts +66 -9
- package/src/runtime/plugins/types.ts +3 -1
- package/src/runtime/recovery/maintenance-executor.ts +61 -25
- package/src/runtime/root/package-connector-service.ts +46 -4
- package/src/runtime/root/package-runtime-release.ts +1 -1
- package/src/runtime/root/package-runtime-service.ts +33 -2
- package/src/runtime/root/release-manifest.ts +137 -16
- package/src/runtime/root/release-materialize.ts +109 -35
- package/src/runtime/root/types.ts +10 -0
- package/src/runtime/standalone-recovery/core.ts +425 -194
- package/src/runtime/standalone-recovery/entry.ts +1 -1
- package/src/runtime/standalone-recovery/installer.ts +1 -1
- package/src/runtime/workflow/schedules/engine.ts +113 -87
- package/src/runtime/workflow/schedules/settlement.ts +26 -23
- package/src/runtime/workflow/schedules/store.ts +79 -10
|
@@ -107,7 +107,7 @@ function assertPackageRuntimeSnapshot(snapshotRoot: string, records: PackageRunt
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
function stagePackageRuntimeSnapshot(sourceRoot: string, snapshotRoot: string, records: PackageRuntimeFileRecord[]): void {
|
|
110
|
+
export function stagePackageRuntimeSnapshot(sourceRoot: string, snapshotRoot: string, records: PackageRuntimeFileRecord[]): void {
|
|
111
111
|
mkdirSync(snapshotRoot, { recursive: false, mode: 0o700 });
|
|
112
112
|
for (const record of records) {
|
|
113
113
|
const source = join(sourceRoot, record.path);
|
|
@@ -357,6 +357,10 @@ async function cleanupActivationHelper(request: PackageRuntimeActivationRequest)
|
|
|
357
357
|
async function rollbackPackageRuntimeActivation(
|
|
358
358
|
request: PackageRuntimeActivationRequest,
|
|
359
359
|
installDarwinService: typeof installForgeRuntimeService,
|
|
360
|
+
options: {
|
|
361
|
+
restoreConnector?: boolean;
|
|
362
|
+
ensureConnectorService?: typeof ensurePackageConnectorService;
|
|
363
|
+
} = {},
|
|
360
364
|
): Promise<string[]> {
|
|
361
365
|
const errors: string[] = [];
|
|
362
366
|
const servicePaths = forgeRuntimeServicePaths(request.controllerHome);
|
|
@@ -391,6 +395,29 @@ async function rollbackPackageRuntimeActivation(
|
|
|
391
395
|
errors.push(error instanceof Error ? error.message : String(error));
|
|
392
396
|
}
|
|
393
397
|
}
|
|
398
|
+
if (options.restoreConnector && request.connectorEndpoint && request.priorAuthorityPresent) {
|
|
399
|
+
try {
|
|
400
|
+
const restored = readRuntimeReleaseAuthority(request.controllerHome);
|
|
401
|
+
if (!restored) throw new Error('FORGE_PACKAGE_CONNECTOR_ROLLBACK_AUTHORITY_MISSING');
|
|
402
|
+
const releaseRoot = dirname(resolve(restored.active.manifestPath));
|
|
403
|
+
const packageRoot = join(releaseRoot, 'package');
|
|
404
|
+
const ensureConnectorService = options.ensureConnectorService ?? ensurePackageConnectorService;
|
|
405
|
+
await ensureConnectorService({
|
|
406
|
+
release: {
|
|
407
|
+
releaseId: restored.active.releaseId,
|
|
408
|
+
releaseRoot,
|
|
409
|
+
packageRoot,
|
|
410
|
+
},
|
|
411
|
+
controllerHome: request.controllerHome,
|
|
412
|
+
endpoint: request.connectorEndpoint,
|
|
413
|
+
executable: request.nodeExecutable,
|
|
414
|
+
platform: 'darwin',
|
|
415
|
+
refresh: true,
|
|
416
|
+
});
|
|
417
|
+
} catch (error) {
|
|
418
|
+
errors.push(`primary Connector rollback failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
394
421
|
return errors;
|
|
395
422
|
}
|
|
396
423
|
|
|
@@ -421,6 +448,7 @@ export async function activateScheduledPackageRuntimeService(
|
|
|
421
448
|
release: request.release,
|
|
422
449
|
controllerHome: request.controllerHome,
|
|
423
450
|
endpoint: request.connectorEndpoint,
|
|
451
|
+
executable: request.nodeExecutable,
|
|
424
452
|
platform: 'darwin',
|
|
425
453
|
refresh: request.refreshConnector === true,
|
|
426
454
|
});
|
|
@@ -428,7 +456,10 @@ export async function activateScheduledPackageRuntimeService(
|
|
|
428
456
|
return writeActivationReceipt(request, 'activated', { servicePath: paths.installedPlistPath });
|
|
429
457
|
} catch (error) {
|
|
430
458
|
const detail = error instanceof Error ? error.message : String(error);
|
|
431
|
-
const rollbackErrors = await rollbackPackageRuntimeActivation(request, installDarwinService
|
|
459
|
+
const rollbackErrors = await rollbackPackageRuntimeActivation(request, installDarwinService, {
|
|
460
|
+
restoreConnector: Boolean(request.connectorEndpoint),
|
|
461
|
+
ensureConnectorService,
|
|
462
|
+
});
|
|
432
463
|
writeActivationReceipt(request, 'failed+rollback', {
|
|
433
464
|
error: detail,
|
|
434
465
|
rollbackSucceeded: rollbackErrors.length === 0,
|
|
@@ -587,7 +618,7 @@ export async function installPackageRuntimeService(
|
|
|
587
618
|
if (!connectorEndpoint || base.status === 'activation_scheduled') return base;
|
|
588
619
|
const ensureConnectorService = dependencies.ensureConnectorService ?? ensurePackageConnectorService;
|
|
589
620
|
const connector = await ensureConnectorService({
|
|
590
|
-
release, controllerHome, endpoint: connectorEndpoint, platform, env, forcePortable: options.forcePortable === true, refresh: options.refreshConnector === true,
|
|
621
|
+
release, controllerHome, endpoint: connectorEndpoint, executable: process.execPath, platform, env, forcePortable: options.forcePortable === true, refresh: options.refreshConnector === true,
|
|
591
622
|
});
|
|
592
623
|
return { ...base, connector };
|
|
593
624
|
}
|
|
@@ -13,6 +13,77 @@ function canonicalExistingPathIdentity(path: string): string {
|
|
|
13
13
|
return existsSync(resolved) ? realpathSync(resolved) : resolved;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
function requireSha256Identity(value: unknown, field: string): string {
|
|
17
|
+
const identity = requireString(value, field);
|
|
18
|
+
if (!/^sha256:[a-f0-9]{64}$/i.test(identity)) {
|
|
19
|
+
throw new Error(`RELEASE_MANIFEST_INVALID: ${field} must be sha256:<64 hex>`);
|
|
20
|
+
}
|
|
21
|
+
return identity;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type RuntimeComponentPair<KEntry extends keyof RuntimeReleaseManifest, KIdentity extends keyof RuntimeReleaseManifest> = Pick<
|
|
25
|
+
RuntimeReleaseManifest,
|
|
26
|
+
KEntry | KIdentity
|
|
27
|
+
>;
|
|
28
|
+
|
|
29
|
+
function optionalRuntimeComponent<
|
|
30
|
+
KEntry extends keyof RuntimeReleaseManifest,
|
|
31
|
+
KIdentity extends keyof RuntimeReleaseManifest,
|
|
32
|
+
>(input: {
|
|
33
|
+
value: Record<string, unknown>;
|
|
34
|
+
entryField: KEntry;
|
|
35
|
+
identityField: KIdentity;
|
|
36
|
+
canonicalEntry: RuntimeReleaseManifest[KEntry];
|
|
37
|
+
}): RuntimeComponentPair<KEntry, KIdentity> | undefined {
|
|
38
|
+
const rawEntry = input.value[input.entryField as string];
|
|
39
|
+
const rawIdentity = input.value[input.identityField as string];
|
|
40
|
+
if (rawEntry === undefined && rawIdentity === undefined) return undefined;
|
|
41
|
+
const entry = requireString(rawEntry, input.entryField as string);
|
|
42
|
+
if (entry !== input.canonicalEntry) {
|
|
43
|
+
throw new Error(`RELEASE_MANIFEST_INVALID: ${String(input.entryField)} must be ${String(input.canonicalEntry)}, got ${entry}`);
|
|
44
|
+
}
|
|
45
|
+
const identity = requireSha256Identity(rawIdentity, input.identityField as string);
|
|
46
|
+
return {
|
|
47
|
+
[input.entryField]: input.canonicalEntry,
|
|
48
|
+
[input.identityField]: identity,
|
|
49
|
+
} as RuntimeComponentPair<KEntry, KIdentity>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const COMPILED_RUNTIME_RELEASE_COMPONENT_FIELDS = [
|
|
53
|
+
'diagnosticEntrypoint', 'diagnosticArtifactIdentity',
|
|
54
|
+
'browserNodeBridgeEntrypoint', 'browserNodeBridgeArtifactIdentity',
|
|
55
|
+
'browserHandoffEntrypoint', 'browserHandoffArtifactIdentity',
|
|
56
|
+
'processRunnerEntrypoint', 'processRunnerArtifactIdentity',
|
|
57
|
+
'checkRunnerEntrypoint', 'checkRunnerArtifactIdentity',
|
|
58
|
+
'pluginActionSidecarEntrypoint', 'pluginActionSidecarArtifactIdentity',
|
|
59
|
+
'externalPluginProbeEntrypoint', 'externalPluginProbeArtifactIdentity',
|
|
60
|
+
'codeGraphNodeEntrypoint', 'codeGraphNodeArtifactIdentity',
|
|
61
|
+
'codeGraphSidecarEntrypoint', 'codeGraphSidecarArtifactIdentity',
|
|
62
|
+
'codeGraphLibraryRoot', 'codeGraphLibraryArtifactIdentity',
|
|
63
|
+
'packageRoot', 'packageArtifactIdentity',
|
|
64
|
+
'controllerUiRoot', 'controllerUiArtifactIdentity',
|
|
65
|
+
] as const satisfies readonly (keyof RuntimeReleaseManifest)[];
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Compiled self-host candidates have a closed execution surface. Package
|
|
69
|
+
* launcher releases are a separate source-backed release form and therefore
|
|
70
|
+
* intentionally do not satisfy this contract.
|
|
71
|
+
*/
|
|
72
|
+
export type CompleteCompiledRuntimeReleaseManifest = RuntimeReleaseManifest & Required<Pick<
|
|
73
|
+
RuntimeReleaseManifest,
|
|
74
|
+
typeof COMPILED_RUNTIME_RELEASE_COMPONENT_FIELDS[number]
|
|
75
|
+
>>;
|
|
76
|
+
|
|
77
|
+
export function requireCompleteCompiledRuntimeReleaseManifest(
|
|
78
|
+
manifest: RuntimeReleaseManifest,
|
|
79
|
+
): asserts manifest is CompleteCompiledRuntimeReleaseManifest {
|
|
80
|
+
for (const field of COMPILED_RUNTIME_RELEASE_COMPONENT_FIELDS) {
|
|
81
|
+
if (manifest[field] === undefined) {
|
|
82
|
+
throw new Error(`RUNTIME_RELEASE_COMPILED_COMPONENT_MISSING: ${field}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
16
87
|
export function loadRuntimeReleaseManifest(
|
|
17
88
|
path: string,
|
|
18
89
|
expectedControllerHome: string,
|
|
@@ -50,18 +121,60 @@ export function loadRuntimeReleaseManifest(
|
|
|
50
121
|
`RELEASE_DATABASE_SCHEMA_INCOMPATIBLE: runtime=${CONTROL_PLANE_SCHEMA_VERSION} supported=${minimum}-${maximum}`,
|
|
51
122
|
);
|
|
52
123
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
124
|
+
const diagnostic = optionalRuntimeComponent({
|
|
125
|
+
value,
|
|
126
|
+
entryField: 'diagnosticEntrypoint',
|
|
127
|
+
identityField: 'diagnosticArtifactIdentity',
|
|
128
|
+
canonicalEntry: 'forge-cli',
|
|
129
|
+
});
|
|
130
|
+
const browserNodeBridge = optionalRuntimeComponent({
|
|
131
|
+
value,
|
|
132
|
+
entryField: 'browserNodeBridgeEntrypoint',
|
|
133
|
+
identityField: 'browserNodeBridgeArtifactIdentity',
|
|
134
|
+
canonicalEntry: 'browser-node-bridge-host.js',
|
|
135
|
+
});
|
|
136
|
+
const browserHandoff = optionalRuntimeComponent({
|
|
137
|
+
value,
|
|
138
|
+
entryField: 'browserHandoffEntrypoint',
|
|
139
|
+
identityField: 'browserHandoffArtifactIdentity',
|
|
140
|
+
canonicalEntry: 'browser-handoff-host.js',
|
|
141
|
+
});
|
|
142
|
+
const processRunner = optionalRuntimeComponent({
|
|
143
|
+
value,
|
|
144
|
+
entryField: 'processRunnerEntrypoint',
|
|
145
|
+
identityField: 'processRunnerArtifactIdentity',
|
|
146
|
+
canonicalEntry: 'process-runner.js',
|
|
147
|
+
});
|
|
148
|
+
const checkRunner = optionalRuntimeComponent({
|
|
149
|
+
value,
|
|
150
|
+
entryField: 'checkRunnerEntrypoint',
|
|
151
|
+
identityField: 'checkRunnerArtifactIdentity',
|
|
152
|
+
canonicalEntry: 'forge-check-runner',
|
|
153
|
+
});
|
|
154
|
+
const pluginActionSidecar = optionalRuntimeComponent({
|
|
155
|
+
value,
|
|
156
|
+
entryField: 'pluginActionSidecarEntrypoint',
|
|
157
|
+
identityField: 'pluginActionSidecarArtifactIdentity',
|
|
158
|
+
canonicalEntry: 'forge-plugin-action-sidecar',
|
|
159
|
+
});
|
|
160
|
+
const externalPluginProbe = optionalRuntimeComponent({
|
|
161
|
+
value,
|
|
162
|
+
entryField: 'externalPluginProbeEntrypoint',
|
|
163
|
+
identityField: 'externalPluginProbeArtifactIdentity',
|
|
164
|
+
canonicalEntry: 'external-unix-socket-probe.cjs',
|
|
165
|
+
});
|
|
166
|
+
const packageSnapshot = optionalRuntimeComponent({
|
|
167
|
+
value,
|
|
168
|
+
entryField: 'packageRoot',
|
|
169
|
+
identityField: 'packageArtifactIdentity',
|
|
170
|
+
canonicalEntry: 'package',
|
|
171
|
+
});
|
|
172
|
+
const controllerUi = optionalRuntimeComponent({
|
|
173
|
+
value,
|
|
174
|
+
entryField: 'controllerUiRoot',
|
|
175
|
+
identityField: 'controllerUiArtifactIdentity',
|
|
176
|
+
canonicalEntry: 'ui-dist',
|
|
177
|
+
});
|
|
65
178
|
const browserAutomationHelperFields = [
|
|
66
179
|
value.browserAutomationHelperEntrypoint,
|
|
67
180
|
value.browserAutomationHelperArtifactIdentity,
|
|
@@ -112,11 +225,11 @@ export function loadRuntimeReleaseManifest(
|
|
|
112
225
|
}
|
|
113
226
|
codeGraphRuntime = {
|
|
114
227
|
codeGraphNodeEntrypoint: 'codegraph-node',
|
|
115
|
-
codeGraphNodeArtifactIdentity:
|
|
228
|
+
codeGraphNodeArtifactIdentity: requireSha256Identity(value.codeGraphNodeArtifactIdentity, 'codeGraphNodeArtifactIdentity'),
|
|
116
229
|
codeGraphSidecarEntrypoint: 'codegraph-sidecar.cjs',
|
|
117
|
-
codeGraphSidecarArtifactIdentity:
|
|
230
|
+
codeGraphSidecarArtifactIdentity: requireSha256Identity(value.codeGraphSidecarArtifactIdentity, 'codeGraphSidecarArtifactIdentity'),
|
|
118
231
|
codeGraphLibraryRoot: 'codegraph-lib',
|
|
119
|
-
codeGraphLibraryArtifactIdentity:
|
|
232
|
+
codeGraphLibraryArtifactIdentity: requireSha256Identity(value.codeGraphLibraryArtifactIdentity, 'codeGraphLibraryArtifactIdentity'),
|
|
120
233
|
};
|
|
121
234
|
}
|
|
122
235
|
|
|
@@ -136,9 +249,17 @@ export function loadRuntimeReleaseManifest(
|
|
|
136
249
|
releaseId: requireString(value.releaseId, 'releaseId'),
|
|
137
250
|
artifactIdentity: requireString(value.artifactIdentity, 'artifactIdentity'),
|
|
138
251
|
entrypoint: 'forge-runtime',
|
|
139
|
-
...(
|
|
252
|
+
...(diagnostic ?? {}),
|
|
253
|
+
...(browserNodeBridge ?? {}),
|
|
254
|
+
...(browserHandoff ?? {}),
|
|
255
|
+
...(processRunner ?? {}),
|
|
256
|
+
...(checkRunner ?? {}),
|
|
257
|
+
...(pluginActionSidecar ?? {}),
|
|
258
|
+
...(externalPluginProbe ?? {}),
|
|
140
259
|
...(browserAutomationHelper ?? {}),
|
|
141
260
|
...(codeGraphRuntime ?? {}),
|
|
261
|
+
...(packageSnapshot ?? {}),
|
|
262
|
+
...(controllerUi ?? {}),
|
|
142
263
|
arguments: argumentsValue as string[],
|
|
143
264
|
configurationSchemaVersion: 1,
|
|
144
265
|
controllerHome,
|
|
@@ -5,6 +5,8 @@ import { dirname, join, relative, resolve } from 'path';
|
|
|
5
5
|
import { runProcess } from '../../effects/process-runner';
|
|
6
6
|
import { resolveBunExecutable } from '../shared/process-environment';
|
|
7
7
|
import { CONTROL_PLANE_SCHEMA_VERSION } from '../control-plane/persistence/sqlite-store';
|
|
8
|
+
import { loadRuntimeReleaseManifest, requireCompleteCompiledRuntimeReleaseManifest } from './release-manifest';
|
|
9
|
+
import { packageRuntimeFileIndex, stagePackageRuntimeSnapshot } from './package-runtime-release';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Stage one immutable Forge Runtime release below Controller Home. The staged
|
|
@@ -24,6 +26,7 @@ export interface MacOSRuntimeCodeSigning {
|
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
export interface StagedRuntimeRelease {
|
|
29
|
+
controllerHome: string;
|
|
27
30
|
releasePath: string;
|
|
28
31
|
manifestPath: string;
|
|
29
32
|
releaseId: string;
|
|
@@ -38,6 +41,7 @@ export interface StagedRuntimeRelease {
|
|
|
38
41
|
codeGraphNodeArtifactIdentity?: string;
|
|
39
42
|
codeGraphSidecarArtifactIdentity?: string;
|
|
40
43
|
codeGraphLibraryArtifactIdentity?: string;
|
|
44
|
+
packageArtifactIdentity?: string;
|
|
41
45
|
controllerUiArtifactIdentity?: string;
|
|
42
46
|
macosCodeSigning?: MacOSRuntimeCodeSigning;
|
|
43
47
|
manifestSha256: string;
|
|
@@ -309,6 +313,13 @@ export function stageRuntimeReleaseFromCandidateSource(input: {
|
|
|
309
313
|
let rawManifest: Record<string, unknown>;
|
|
310
314
|
try { rawManifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as Record<string, unknown>; }
|
|
311
315
|
catch (error) { throw new Error(`RUNTIME_RELEASE_CANDIDATE_MANIFEST_INVALID: ${error instanceof Error ? error.message : String(error)}`); }
|
|
316
|
+
const manifest = loadRuntimeReleaseManifest(manifestPath, controllerHome);
|
|
317
|
+
requireCompleteCompiledRuntimeReleaseManifest(manifest);
|
|
318
|
+
if (manifest.releaseId !== receipt.releaseId
|
|
319
|
+
|| manifest.artifactIdentity !== receipt.artifactIdentity
|
|
320
|
+
|| manifest.sourceCommit !== receipt.sourceCommit) {
|
|
321
|
+
throw new Error('RUNTIME_RELEASE_CANDIDATE_MANIFEST_RECEIPT_MISMATCH');
|
|
322
|
+
}
|
|
312
323
|
const platform = dependencies.platform ?? process.platform;
|
|
313
324
|
const macosCodeSigning = parseMacOSRuntimeCodeSigning(rawManifest.macosCodeSigning, 'RUNTIME_RELEASE_CANDIDATE_SIGNING_INVALID');
|
|
314
325
|
if (platform === 'darwin') {
|
|
@@ -322,15 +333,30 @@ export function stageRuntimeReleaseFromCandidateSource(input: {
|
|
|
322
333
|
}
|
|
323
334
|
}
|
|
324
335
|
|
|
325
|
-
|
|
336
|
+
const staged: StagedRuntimeRelease = {
|
|
337
|
+
controllerHome,
|
|
326
338
|
releasePath,
|
|
327
339
|
manifestPath,
|
|
328
340
|
releaseId: receipt.releaseId,
|
|
329
341
|
artifactIdentity: receipt.artifactIdentity,
|
|
342
|
+
diagnosticArtifactIdentity: manifest.diagnosticArtifactIdentity,
|
|
343
|
+
browserNodeBridgeArtifactIdentity: manifest.browserNodeBridgeArtifactIdentity,
|
|
344
|
+
browserHandoffArtifactIdentity: manifest.browserHandoffArtifactIdentity,
|
|
345
|
+
processRunnerArtifactIdentity: manifest.processRunnerArtifactIdentity,
|
|
346
|
+
checkRunnerArtifactIdentity: manifest.checkRunnerArtifactIdentity,
|
|
347
|
+
pluginActionSidecarArtifactIdentity: manifest.pluginActionSidecarArtifactIdentity,
|
|
348
|
+
externalPluginProbeArtifactIdentity: manifest.externalPluginProbeArtifactIdentity,
|
|
349
|
+
codeGraphNodeArtifactIdentity: manifest.codeGraphNodeArtifactIdentity,
|
|
350
|
+
codeGraphSidecarArtifactIdentity: manifest.codeGraphSidecarArtifactIdentity,
|
|
351
|
+
codeGraphLibraryArtifactIdentity: manifest.codeGraphLibraryArtifactIdentity,
|
|
352
|
+
packageArtifactIdentity: manifest.packageArtifactIdentity,
|
|
353
|
+
controllerUiArtifactIdentity: manifest.controllerUiArtifactIdentity,
|
|
330
354
|
...(macosCodeSigning ? { macosCodeSigning } : {}),
|
|
331
355
|
manifestSha256: receipt.manifestSha256,
|
|
332
356
|
sourceCommit: receipt.sourceCommit,
|
|
333
357
|
};
|
|
358
|
+
assertRuntimeReleaseFiles(staged, dependencies);
|
|
359
|
+
return staged;
|
|
334
360
|
}
|
|
335
361
|
|
|
336
362
|
function defaultCompileBinary(input: { sourceRoot: string; outputPath: string; entryPath?: string }): { ok: boolean; stderr?: string; stdout?: string; error?: string } {
|
|
@@ -547,6 +573,16 @@ export function stageRuntimeRelease(input: {
|
|
|
547
573
|
cpSync(sourceControllerUiPath, controllerUiPath, { recursive: true, force: false });
|
|
548
574
|
const controllerUiArtifactIdentity = `sha256:${sha256Directory(controllerUiPath)}`;
|
|
549
575
|
|
|
576
|
+
// The persistent OAuth/Connector is source-backed even when the primary
|
|
577
|
+
// Runtime itself is compiled. Co-locate one immutable package snapshot in
|
|
578
|
+
// the same release so standalone Recovery can bind the Connector to the
|
|
579
|
+
// exact active release instead of retaining an older package release.
|
|
580
|
+
const packageRoot = 'package' as const;
|
|
581
|
+
const packagePath = join(staging, packageRoot);
|
|
582
|
+
const packageRecords = packageRuntimeFileIndex(sourceRoot);
|
|
583
|
+
stagePackageRuntimeSnapshot(sourceRoot, packagePath, packageRecords);
|
|
584
|
+
const packageArtifactIdentity = `sha256:${sha256Directory(packagePath)}`;
|
|
585
|
+
|
|
550
586
|
const manifest = {
|
|
551
587
|
schemaVersion: 1,
|
|
552
588
|
releaseId,
|
|
@@ -573,6 +609,8 @@ export function stageRuntimeRelease(input: {
|
|
|
573
609
|
codeGraphSidecarArtifactIdentity,
|
|
574
610
|
codeGraphLibraryRoot,
|
|
575
611
|
codeGraphLibraryArtifactIdentity,
|
|
612
|
+
packageRoot,
|
|
613
|
+
packageArtifactIdentity,
|
|
576
614
|
controllerUiRoot,
|
|
577
615
|
controllerUiArtifactIdentity,
|
|
578
616
|
arguments: [],
|
|
@@ -592,6 +630,7 @@ export function stageRuntimeRelease(input: {
|
|
|
592
630
|
writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, { mode: 0o600 });
|
|
593
631
|
renameSync(staging, releasePath);
|
|
594
632
|
return {
|
|
633
|
+
controllerHome: resolve(input.controllerHome),
|
|
595
634
|
releasePath,
|
|
596
635
|
manifestPath: join(releasePath, 'manifest.json'),
|
|
597
636
|
releaseId,
|
|
@@ -602,10 +641,12 @@ export function stageRuntimeRelease(input: {
|
|
|
602
641
|
browserHandoffArtifactIdentity,
|
|
603
642
|
processRunnerArtifactIdentity,
|
|
604
643
|
checkRunnerArtifactIdentity,
|
|
644
|
+
pluginActionSidecarArtifactIdentity,
|
|
605
645
|
externalPluginProbeArtifactIdentity,
|
|
606
646
|
codeGraphNodeArtifactIdentity,
|
|
607
647
|
codeGraphSidecarArtifactIdentity,
|
|
608
648
|
codeGraphLibraryArtifactIdentity,
|
|
649
|
+
packageArtifactIdentity,
|
|
609
650
|
controllerUiArtifactIdentity,
|
|
610
651
|
manifestSha256: createHash('sha256').update(`${JSON.stringify(manifest, null, 2)}\n`).digest('hex'),
|
|
611
652
|
sourceCommit,
|
|
@@ -617,13 +658,53 @@ export function stageRuntimeRelease(input: {
|
|
|
617
658
|
}
|
|
618
659
|
|
|
619
660
|
export function assertRuntimeReleaseFiles(release: StagedRuntimeRelease, dependencies: { platform?: NodeJS.Platform; inspectMacOSRuntime?: (executable: string) => MacOSRuntimeCodeSigning } = {}): void {
|
|
661
|
+
const assertRegularFile = (path: string, missingCode: string): void => {
|
|
662
|
+
if (!existsSync(path)) throw new Error(`${missingCode}: ${path}`);
|
|
663
|
+
const status = lstatSync(path);
|
|
664
|
+
if (status.isSymbolicLink() || !status.isFile()) throw new Error(`RUNTIME_RELEASE_PATH_NOT_REGULAR_FILE: ${path}`);
|
|
665
|
+
};
|
|
666
|
+
const assertExecutable = (path: string): void => {
|
|
667
|
+
if ((statSync(path).mode & 0o111) === 0) throw new Error(`RUNTIME_RELEASE_ENTRYPOINT_NOT_EXECUTABLE: ${path}`);
|
|
668
|
+
};
|
|
669
|
+
const assertFileIdentity = (path: string, expected: string): void => {
|
|
670
|
+
const actual = `sha256:${sha256(path)}`;
|
|
671
|
+
if (actual !== expected) throw new Error(`RUNTIME_RELEASE_ARTIFACT_IDENTITY_MISMATCH: ${path}`);
|
|
672
|
+
};
|
|
673
|
+
const assertDirectoryIdentity = (path: string, expected: string): void => {
|
|
674
|
+
if (!existsSync(path)) throw new Error(`RUNTIME_RELEASE_DIRECTORY_MISSING: ${path}`);
|
|
675
|
+
const status = lstatSync(path);
|
|
676
|
+
if (status.isSymbolicLink() || !status.isDirectory()) throw new Error(`RUNTIME_RELEASE_PATH_NOT_DIRECTORY: ${path}`);
|
|
677
|
+
const actual = `sha256:${sha256Directory(path)}`;
|
|
678
|
+
if (actual !== expected) throw new Error(`RUNTIME_RELEASE_ARTIFACT_IDENTITY_MISMATCH: ${path}`);
|
|
679
|
+
};
|
|
680
|
+
const assertComponentFile = (input: { path: string; identity?: string; missingCode: string; executable?: boolean }): void => {
|
|
681
|
+
if (!input.identity) return;
|
|
682
|
+
assertRegularFile(input.path, input.missingCode);
|
|
683
|
+
assertFileIdentity(input.path, input.identity);
|
|
684
|
+
if (input.executable) assertExecutable(input.path);
|
|
685
|
+
};
|
|
686
|
+
|
|
620
687
|
if (!existsSync(release.releasePath) || !existsSync(release.manifestPath)) {
|
|
621
688
|
throw new Error(`RUNTIME_RELEASE_FILES_MISSING: ${release.releasePath}`);
|
|
622
689
|
}
|
|
623
|
-
const
|
|
624
|
-
if (
|
|
625
|
-
|
|
690
|
+
const releasesRoot = join(resolve(release.controllerHome), 'runtime', 'releases');
|
|
691
|
+
if (resolve(release.releasePath) !== join(releasesRoot, release.releaseId)
|
|
692
|
+
|| resolve(release.manifestPath) !== join(release.releasePath, 'manifest.json')) {
|
|
693
|
+
throw new Error('RUNTIME_RELEASE_PATH_OUTSIDE_CONTROLLER_HOME');
|
|
694
|
+
}
|
|
695
|
+
const releaseStatus = lstatSync(release.releasePath);
|
|
696
|
+
const manifestStatus = lstatSync(release.manifestPath);
|
|
697
|
+
if (releaseStatus.isSymbolicLink() || !releaseStatus.isDirectory()
|
|
698
|
+
|| manifestStatus.isSymbolicLink() || !manifestStatus.isFile()) {
|
|
699
|
+
throw new Error(`RUNTIME_RELEASE_PATH_NOT_PHYSICAL: ${release.releasePath}`);
|
|
626
700
|
}
|
|
701
|
+
if (sha256(release.manifestPath) !== release.manifestSha256) {
|
|
702
|
+
throw new Error('RUNTIME_RELEASE_MANIFEST_IDENTITY_MISMATCH');
|
|
703
|
+
}
|
|
704
|
+
const runtimePath = join(release.releasePath, 'forge-runtime');
|
|
705
|
+
assertRegularFile(runtimePath, 'RUNTIME_RELEASE_ENTRYPOINT_MISSING');
|
|
706
|
+
assertExecutable(runtimePath);
|
|
707
|
+
assertFileIdentity(runtimePath, release.artifactIdentity);
|
|
627
708
|
const platform = dependencies.platform ?? process.platform;
|
|
628
709
|
if (platform === 'darwin' && release.macosCodeSigning) {
|
|
629
710
|
const actual = (dependencies.inspectMacOSRuntime ?? inspectMacOSRuntimeCodeSigning)(runtimePath);
|
|
@@ -634,38 +715,31 @@ export function assertRuntimeReleaseFiles(release: StagedRuntimeRelease, depende
|
|
|
634
715
|
throw new Error('RUNTIME_RELEASE_MACOS_SIGNING_MISMATCH');
|
|
635
716
|
}
|
|
636
717
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
}
|
|
646
|
-
if (release.
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
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
|
-
}
|
|
655
|
-
if (release.externalPluginProbeArtifactIdentity && !existsSync(join(release.releasePath, 'external-unix-socket-probe.cjs'))) {
|
|
656
|
-
throw new Error(`RUNTIME_RELEASE_EXTERNAL_PLUGIN_PROBE_MISSING: ${join(release.releasePath, 'external-unix-socket-probe.cjs')}`);
|
|
657
|
-
}
|
|
658
|
-
if (release.codeGraphNodeArtifactIdentity && !existsSync(join(release.releasePath, 'codegraph-node'))) {
|
|
659
|
-
throw new Error(`RUNTIME_RELEASE_CODEGRAPH_NODE_MISSING: ${join(release.releasePath, 'codegraph-node')}`);
|
|
660
|
-
}
|
|
661
|
-
if (release.codeGraphSidecarArtifactIdentity && !existsSync(join(release.releasePath, 'codegraph-sidecar.cjs'))) {
|
|
662
|
-
throw new Error(`RUNTIME_RELEASE_CODEGRAPH_SIDECAR_MISSING: ${join(release.releasePath, 'codegraph-sidecar.cjs')}`);
|
|
718
|
+
assertComponentFile({ path: join(release.releasePath, 'forge-cli'), identity: release.diagnosticArtifactIdentity, missingCode: 'RUNTIME_RELEASE_DIAGNOSTIC_ENTRYPOINT_MISSING', executable: true });
|
|
719
|
+
assertComponentFile({ path: join(release.releasePath, 'browser-node-bridge-host.js'), identity: release.browserNodeBridgeArtifactIdentity, missingCode: 'RUNTIME_RELEASE_BROWSER_NODE_HOST_MISSING', executable: true });
|
|
720
|
+
assertComponentFile({ path: join(release.releasePath, 'browser-handoff-host.js'), identity: release.browserHandoffArtifactIdentity, missingCode: 'RUNTIME_RELEASE_BROWSER_HANDOFF_HOST_MISSING', executable: true });
|
|
721
|
+
assertComponentFile({ path: join(release.releasePath, 'process-runner.js'), identity: release.processRunnerArtifactIdentity, missingCode: 'RUNTIME_RELEASE_PROCESS_RUNNER_MISSING', executable: true });
|
|
722
|
+
assertComponentFile({ path: join(release.releasePath, 'forge-check-runner'), identity: release.checkRunnerArtifactIdentity, missingCode: 'RUNTIME_RELEASE_CHECK_RUNNER_MISSING', executable: true });
|
|
723
|
+
assertComponentFile({ path: join(release.releasePath, 'forge-plugin-action-sidecar'), identity: release.pluginActionSidecarArtifactIdentity, missingCode: 'RUNTIME_RELEASE_PLUGIN_ACTION_SIDECAR_MISSING', executable: true });
|
|
724
|
+
assertComponentFile({ path: join(release.releasePath, 'external-unix-socket-probe.cjs'), identity: release.externalPluginProbeArtifactIdentity, missingCode: 'RUNTIME_RELEASE_EXTERNAL_PLUGIN_PROBE_MISSING', executable: true });
|
|
725
|
+
assertComponentFile({ path: join(release.releasePath, 'codegraph-node'), identity: release.codeGraphNodeArtifactIdentity, missingCode: 'RUNTIME_RELEASE_CODEGRAPH_NODE_MISSING', executable: true });
|
|
726
|
+
assertComponentFile({ path: join(release.releasePath, 'codegraph-sidecar.cjs'), identity: release.codeGraphSidecarArtifactIdentity, missingCode: 'RUNTIME_RELEASE_CODEGRAPH_SIDECAR_MISSING', executable: true });
|
|
727
|
+
if (release.codeGraphLibraryArtifactIdentity) {
|
|
728
|
+
const libraryRoot = join(release.releasePath, 'codegraph-lib');
|
|
729
|
+
if (!existsSync(join(libraryRoot, 'dist', 'index.js'))) {
|
|
730
|
+
throw new Error(`RUNTIME_RELEASE_CODEGRAPH_LIBRARY_MISSING: ${join(libraryRoot, 'dist', 'index.js')}`);
|
|
731
|
+
}
|
|
732
|
+
assertDirectoryIdentity(libraryRoot, release.codeGraphLibraryArtifactIdentity);
|
|
663
733
|
}
|
|
664
|
-
if (release.
|
|
665
|
-
|
|
734
|
+
if (release.packageArtifactIdentity) {
|
|
735
|
+
const packageRoot = join(release.releasePath, 'package');
|
|
736
|
+
assertDirectoryIdentity(packageRoot, release.packageArtifactIdentity);
|
|
666
737
|
}
|
|
667
|
-
if (release.controllerUiArtifactIdentity
|
|
668
|
-
|
|
669
|
-
|
|
738
|
+
if (release.controllerUiArtifactIdentity) {
|
|
739
|
+
const uiRoot = join(release.releasePath, 'ui-dist');
|
|
740
|
+
if (!existsSync(join(uiRoot, 'app.js')) || !existsSync(join(uiRoot, 'app.css'))) {
|
|
741
|
+
throw new Error(`RUNTIME_RELEASE_CONTROLLER_UI_MISSING: ${uiRoot}`);
|
|
742
|
+
}
|
|
743
|
+
assertDirectoryIdentity(uiRoot, release.controllerUiArtifactIdentity);
|
|
670
744
|
}
|
|
671
745
|
}
|
|
@@ -39,8 +39,14 @@ export interface RuntimeReleaseManifest {
|
|
|
39
39
|
browserNodeBridgeArtifactIdentity?: string;
|
|
40
40
|
browserHandoffEntrypoint?: 'browser-handoff-host.js';
|
|
41
41
|
browserHandoffArtifactIdentity?: string;
|
|
42
|
+
processRunnerEntrypoint?: 'process-runner.js';
|
|
43
|
+
processRunnerArtifactIdentity?: string;
|
|
44
|
+
checkRunnerEntrypoint?: 'forge-check-runner';
|
|
45
|
+
checkRunnerArtifactIdentity?: string;
|
|
42
46
|
pluginActionSidecarEntrypoint?: 'forge-plugin-action-sidecar';
|
|
43
47
|
pluginActionSidecarArtifactIdentity?: string;
|
|
48
|
+
externalPluginProbeEntrypoint?: 'external-unix-socket-probe.cjs';
|
|
49
|
+
externalPluginProbeArtifactIdentity?: string;
|
|
44
50
|
browserAutomationHelperEntrypoint?: 'browser-automation-helper';
|
|
45
51
|
browserAutomationHelperArtifactIdentity?: string;
|
|
46
52
|
browserAutomationHelperContractIdentity?: string;
|
|
@@ -50,6 +56,10 @@ export interface RuntimeReleaseManifest {
|
|
|
50
56
|
codeGraphSidecarArtifactIdentity?: string;
|
|
51
57
|
codeGraphLibraryRoot?: 'codegraph-lib';
|
|
52
58
|
codeGraphLibraryArtifactIdentity?: string;
|
|
59
|
+
packageRoot?: 'package';
|
|
60
|
+
packageArtifactIdentity?: string;
|
|
61
|
+
controllerUiRoot?: 'ui-dist';
|
|
62
|
+
controllerUiArtifactIdentity?: string;
|
|
53
63
|
arguments: string[];
|
|
54
64
|
configurationSchemaVersion: 1;
|
|
55
65
|
controllerHome: string;
|