maka-agent 0.2.0-dev.26.20260909 → 0.2.0-dev.28.20260911
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/LICENSE +106 -0
- package/dist/cli-core.js +28 -0
- package/dist/runtime-host-cli.js +43 -3
- package/dist/runtime-host-handoff-surface.js +10 -8
- package/dist/runtime-host-lifecycle-transaction.js +28 -3
- package/dist/runtime-host-local-source-retirement.js +1 -1
- package/dist/runtime-host-run-command.js +15 -7
- package/dist/runtime-host-setup-command.js +29 -6
- package/dist/runtime-host-update-command.js +49 -5
- package/dist/session-export-command.js +72 -0
- package/dist/session-import-command.js +69 -0
- package/native/runtime-host-peer/prebuilds/darwin-arm64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/linux-arm64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/linux-x64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/win32-x64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +9 -4
- package/node_modules/@maka/core/dist/diagnostic-log.js +18 -7
- package/node_modules/@maka/core/dist/text-sanitize.js +8 -2
- package/node_modules/@maka/core/dist/usage-stats/types.js +2 -0
- package/node_modules/@maka/core/dist/workhub-routing.js +126 -0
- package/node_modules/@maka/core/package.json +2 -1
- package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +15 -11
- package/node_modules/@maka/runtime/dist/archive-read-tool.js +3 -1
- package/node_modules/@maka/runtime/dist/bots/bot-test.js +2 -1
- package/node_modules/@maka/runtime/dist/bots/feishu-bridge.js +24 -20
- package/node_modules/@maka/runtime/dist/bots/slack-bridge.js +5 -3
- package/node_modules/@maka/runtime/dist/bots/wechat-bridge.js +87 -29
- package/node_modules/@maka/runtime/dist/bots/wecom-bridge.js +40 -36
- package/node_modules/@maka/runtime/dist/builtin-tools.js +21 -2
- package/node_modules/@maka/runtime/dist/computer-use-tools.js +4 -1
- package/node_modules/@maka/runtime/dist/deep-research-tools.js +11 -5
- package/node_modules/@maka/runtime/dist/edit-replace.js +2 -2
- package/node_modules/@maka/runtime/dist/filesystem-worker/operations.js +5 -6
- package/node_modules/@maka/runtime/dist/memory-extraction-evidence.js +7 -1
- package/node_modules/@maka/runtime/dist/memory-extraction.js +12 -7
- package/node_modules/@maka/runtime/dist/openai-responses-websocket.js +2 -5
- package/node_modules/@maka/runtime/dist/plugin-agent-service.js +131 -0
- package/node_modules/@maka/runtime/dist/plugin-approval-service.js +33 -0
- package/node_modules/@maka/runtime/dist/plugin-attachment-service.js +53 -0
- package/node_modules/@maka/runtime/dist/plugin-command-service.js +100 -0
- package/node_modules/@maka/runtime/dist/plugin-composition-loader.js +11 -2
- package/node_modules/@maka/runtime/dist/plugin-data-services.js +332 -0
- package/node_modules/@maka/runtime/dist/plugin-fs-service.js +62 -0
- package/node_modules/@maka/runtime/dist/plugin-goal-service.js +61 -0
- package/node_modules/@maka/runtime/dist/plugin-invocation-signal.js +24 -0
- package/node_modules/@maka/runtime/dist/plugin-llm-service.js +85 -0
- package/node_modules/@maka/runtime/dist/plugin-lsp-service.js +94 -0
- package/node_modules/@maka/runtime/dist/plugin-scope-registry.js +91 -0
- package/node_modules/@maka/runtime/dist/plugin-session-query-service.js +71 -0
- package/node_modules/@maka/runtime/dist/plugin-shell-env-service.js +87 -0
- package/node_modules/@maka/runtime/dist/plugin-shell-service.js +74 -0
- package/node_modules/@maka/runtime/dist/plugin-skill-service.js +93 -0
- package/node_modules/@maka/runtime/dist/plugin-system-prompt-service.js +346 -0
- package/node_modules/@maka/runtime/dist/plugin-tool-service.js +18 -52
- package/node_modules/@maka/runtime/dist/plugin-user-question-service.js +43 -0
- package/node_modules/@maka/runtime/dist/plugin-web-service.js +69 -0
- package/node_modules/@maka/runtime/dist/request-customization-fetch.js +14 -7
- package/node_modules/@maka/runtime/dist/session-export.js +178 -0
- package/node_modules/@maka/runtime/dist/session-import.js +100 -0
- package/node_modules/@maka/runtime/dist/session-manager.js +6 -1
- package/node_modules/@maka/runtime/dist/shell-run-manager.js +9 -6
- package/node_modules/@maka/runtime/dist/shell-run-tool-result.js +13 -6
- package/node_modules/@maka/runtime/dist/stream-graph-coordinator.js +43 -10
- package/node_modules/@maka/runtime/dist/stream-graph-handoff.js +6 -1
- package/node_modules/@maka/runtime/dist/subscription-model-fetch.js +1 -4
- package/node_modules/@maka/runtime/dist/system-prompt/workspace-instructions.js +11 -6
- package/node_modules/@maka/runtime/dist/tavily-search.js +8 -2
- package/node_modules/@maka/runtime/dist/text-line-window.js +49 -0
- package/node_modules/@maka/runtime/dist/tool-output.js +35 -12
- package/node_modules/@maka/runtime/dist/unified-diff.js +40 -10
- package/node_modules/@maka/runtime/dist/web-fetch-tool.js +4 -2
- package/node_modules/@maka/runtime/dist/workers/filesystem-worker.js +82 -33
- package/node_modules/@maka/runtime/dist/workspace-executor.js +2 -6
- package/node_modules/@maka/runtime/package.json +20 -1
- package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +73 -24
- package/node_modules/@maka/runtime-host/dist/client/host-handoff.js +46 -12
- package/node_modules/@maka/runtime-host/dist/operator/setup-frame.js +31 -21
- package/node_modules/@maka/runtime-host/dist/peer-mesh/node.js +7 -4
- package/node_modules/@maka/runtime-host/dist/protocol/artifact.js +2 -2
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +10 -1
- package/node_modules/@maka/runtime-host/dist/protocol/plugin-platform.js +30 -5
- package/node_modules/@maka/runtime-host/dist/protocol/session-transcript.js +3 -2
- package/node_modules/@maka/runtime-host/dist/protocol/skill-catalog.js +2 -1
- package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +25 -23
- package/node_modules/@maka/runtime-host/dist/server/artifact-coordinator.js +2 -0
- package/node_modules/@maka/runtime-host/dist/server/client-capability-coordinator.js +62 -4
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +481 -11
- package/node_modules/@maka/runtime-host/dist/server/execution-model-authority.js +74 -0
- package/node_modules/@maka/runtime-host/dist/server/goal-coordinator.js +6 -1
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-recovery.js +2 -2
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +30 -0
- package/node_modules/@maka/runtime-host/dist/server/interactive-run-composer.js +114 -20
- package/node_modules/@maka/runtime-host/dist/server/message-coordinator.js +49 -12
- package/node_modules/@maka/runtime-host/dist/server/plugin-data-runtime.js +234 -0
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform-coordinator.js +6 -0
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform.js +12 -0
- package/node_modules/@maka/runtime-host/dist/server/root-admission-owner.js +17 -8
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +189 -92
- package/node_modules/@maka/runtime-host/dist/server/runtime-resource-projection.js +3 -9
- package/node_modules/@maka/runtime-host/dist/server/session-continuity-coordinator.js +20 -21
- package/node_modules/@maka/runtime-host/dist/server/session-transcript-pager.js +24 -2
- package/node_modules/@maka/runtime-host/dist/server/skill-catalog-coordinator.js +18 -2
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +44 -35
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +92 -10
- package/node_modules/@maka/runtime-host/dist/transport/framed-byte-stream-transport.js +4 -1
- package/node_modules/@maka/runtime-host/dist/transport/local-ipc-framing.js +4 -2
- package/node_modules/@maka/runtime-host/dist/transport/peer-native.js +9 -8
- package/node_modules/@maka/runtime-host/dist/transport/resumable-peer-stream.js +14 -9
- package/node_modules/@maka/storage/dist/agent-run-store.js +54 -10
- package/node_modules/@maka/storage/dist/context-offload-snapshot.js +32 -10
- package/node_modules/@maka/storage/dist/context-value-mutation-gate.js +59 -0
- package/node_modules/@maka/storage/dist/execution-stores.js +1 -1
- package/node_modules/@maka/storage/dist/session-bundle-policy.js +909 -34
- package/node_modules/@maka/storage/dist/session-message-projection.js +8 -4
- package/node_modules/@maka/storage/dist/session-store.js +2 -2
- package/node_modules/@maka/storage/dist/sqlite-context-offload-store.js +18 -4
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-store.js +12 -5
- package/node_modules/@maka/storage/dist/stable-storage.js +2 -1
- package/node_modules/@maka/storage/package.json +2 -0
- package/node_modules/@modelcontextprotocol/client/dist/src-D_zzAWoS.mjs +22 -5
- package/node_modules/@modelcontextprotocol/client/dist/src-NAgB4Mp8.cjs +22 -5
- package/node_modules/zod/v4/core/memoizer.cjs +12 -16
- package/node_modules/zod/v4/core/memoizer.js +12 -16
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -261,6 +261,112 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
261
261
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
262
262
|
SOFTWARE.
|
|
263
263
|
|
|
264
|
+
Pi TUI dependency patch
|
|
265
|
+
|
|
266
|
+
Source: https://www.npmjs.com/package/@earendil-works/pi-tui/v/0.84.4
|
|
267
|
+
Repository: https://github.com/earendil-works/pi/tree/v0.84.4/packages/tui
|
|
268
|
+
Version: 0.84.4
|
|
269
|
+
Dependency patch: patches/@earendil-works+pi-tui+0.84.4.patch
|
|
270
|
+
Copyright (c) 2025 Mario Zechner
|
|
271
|
+
License: MIT
|
|
272
|
+
|
|
273
|
+
Maka redistributes a source patch that copies mutable editor undo state while
|
|
274
|
+
sharing immutable pasted strings. The following MIT License applies to that
|
|
275
|
+
material:
|
|
276
|
+
|
|
277
|
+
MIT License
|
|
278
|
+
|
|
279
|
+
Copyright (c) 2025 Mario Zechner
|
|
280
|
+
|
|
281
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
282
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
283
|
+
in the Software without restriction, including without limitation the rights
|
|
284
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
285
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
286
|
+
furnished to do so, subject to the following conditions:
|
|
287
|
+
|
|
288
|
+
The above copyright notice and this permission notice shall be included in all
|
|
289
|
+
copies or substantial portions of the Software.
|
|
290
|
+
|
|
291
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
292
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
293
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
294
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
295
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
296
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
297
|
+
SOFTWARE.
|
|
298
|
+
|
|
299
|
+
Zod dependency patch
|
|
300
|
+
|
|
301
|
+
Source: https://www.npmjs.com/package/zod/v/4.5.4
|
|
302
|
+
Repository: https://github.com/colinhacks/zod
|
|
303
|
+
Version: 4.5.4
|
|
304
|
+
Dependency patch: patches/zod+4.5.4.patch
|
|
305
|
+
Copyright (c) 2025 Colin McDonnell
|
|
306
|
+
License: MIT
|
|
307
|
+
|
|
308
|
+
Maka redistributes a source patch that releases recursive parse state after
|
|
309
|
+
completion or failure. The following MIT License applies to that material:
|
|
310
|
+
|
|
311
|
+
MIT License
|
|
312
|
+
|
|
313
|
+
Copyright (c) 2025 Colin McDonnell
|
|
314
|
+
|
|
315
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
316
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
317
|
+
in the Software without restriction, including without limitation the rights
|
|
318
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
319
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
320
|
+
furnished to do so, subject to the following conditions:
|
|
321
|
+
|
|
322
|
+
The above copyright notice and this permission notice shall be included in all
|
|
323
|
+
copies or substantial portions of the Software.
|
|
324
|
+
|
|
325
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
326
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
327
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
328
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
329
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
330
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
331
|
+
SOFTWARE.
|
|
332
|
+
|
|
333
|
+
Model Context Protocol client dependency patch
|
|
334
|
+
|
|
335
|
+
Source: https://www.npmjs.com/package/@modelcontextprotocol/client/v/2.0.0
|
|
336
|
+
Repository: https://github.com/modelcontextprotocol/typescript-sdk
|
|
337
|
+
Version: 2.0.0
|
|
338
|
+
Dependency patch: patches/@modelcontextprotocol+client+2.0.0.patch
|
|
339
|
+
Copyright (c) 2024-2025 Model Context Protocol a Series of LF Projects, LLC.
|
|
340
|
+
Declared package license: MIT
|
|
341
|
+
|
|
342
|
+
Maka redistributes a source patch that releases settled request observers under
|
|
343
|
+
transport backpressure. The upstream package's LICENSE describes a transition
|
|
344
|
+
from MIT to Apache-2.0: contributions with relicensing consent use Apache-2.0,
|
|
345
|
+
while contributions without that consent retain their original MIT license.
|
|
346
|
+
The Apache License, Version 2.0 is reproduced above. The upstream MIT notice is:
|
|
347
|
+
|
|
348
|
+
MIT License
|
|
349
|
+
|
|
350
|
+
Copyright (c) 2024-2025 Model Context Protocol a Series of LF Projects, LLC.
|
|
351
|
+
|
|
352
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
353
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
354
|
+
in the Software without restriction, including without limitation the rights
|
|
355
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
356
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
357
|
+
furnished to do so, subject to the following conditions:
|
|
358
|
+
|
|
359
|
+
The above copyright notice and this permission notice shall be included in all
|
|
360
|
+
copies or substantial portions of the Software.
|
|
361
|
+
|
|
362
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
363
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
364
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
365
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
366
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
367
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
368
|
+
SOFTWARE.
|
|
369
|
+
|
|
264
370
|
Sigstore dependency patch
|
|
265
371
|
|
|
266
372
|
Source: https://www.npmjs.com/package/@sigstore/core/v/4.0.1
|
package/dist/cli-core.js
CHANGED
|
@@ -52,6 +52,10 @@ export function parseMakaCliArgs(argv, version, cliCommand = RELEASE_MAKA_CLI_LA
|
|
|
52
52
|
return { kind: 'run', args: argv.slice(1) };
|
|
53
53
|
if (first === 'activate')
|
|
54
54
|
return { kind: 'activate', args: argv.slice(1) };
|
|
55
|
+
if (first === 'session-export')
|
|
56
|
+
return { kind: 'session-export', args: argv.slice(1) };
|
|
57
|
+
if (first === 'session-import')
|
|
58
|
+
return { kind: 'session-import', args: argv.slice(1) };
|
|
55
59
|
if (first === 'eval')
|
|
56
60
|
return { kind: 'eval', args: argv.slice(1) };
|
|
57
61
|
if (first === 'update')
|
|
@@ -97,6 +101,8 @@ function helpText(cliCommand) {
|
|
|
97
101
|
` ${cliCommand} --acp Serve ACP v1 over stdio (initialize, session/new, session/list)`,
|
|
98
102
|
` ${cliCommand} run ... Run one non-interactive model turn`,
|
|
99
103
|
` ${cliCommand} activate ... Run one Cloud Session activation and emit JSONL`,
|
|
104
|
+
` ${cliCommand} session-export --workspace-root <dir> --session <id> --out <file.maka-session>`,
|
|
105
|
+
` ${cliCommand} session-import --workspace-root <dir> --bundle <file.maka-session>`,
|
|
100
106
|
` ${cliCommand} -p ... Alias for ${cliCommand} run`,
|
|
101
107
|
` ${cliCommand} eval ... Run one declarative multi-arm experiment`,
|
|
102
108
|
` ${cliCommand} update --target <latest|next|version> Update this npm-global CLI and its local Runtime Host`,
|
|
@@ -243,6 +249,14 @@ export async function runMakaCli(argv = process.argv.slice(2), options = RELEASE
|
|
|
243
249
|
const { runMakaActivationCli } = await import('./activation-command.js');
|
|
244
250
|
return runMakaActivationCli(command.args);
|
|
245
251
|
}
|
|
252
|
+
case 'session-export': {
|
|
253
|
+
const { runMakaSessionExportCli } = await import('./session-export-command.js');
|
|
254
|
+
return runMakaSessionExportCli(command.args);
|
|
255
|
+
}
|
|
256
|
+
case 'session-import': {
|
|
257
|
+
const { runMakaSessionImportCli } = await import('./session-import-command.js');
|
|
258
|
+
return runMakaSessionImportCli(command.args);
|
|
259
|
+
}
|
|
246
260
|
case 'eval': {
|
|
247
261
|
const { configureInstalledEvalBundle } = await import('./eval-bundle-path.js');
|
|
248
262
|
configureInstalledEvalBundle();
|
|
@@ -386,6 +400,8 @@ export async function runMakaCli(argv = process.argv.slice(2), options = RELEASE
|
|
|
386
400
|
bindPairingToClient: command.bindPairingToClient,
|
|
387
401
|
...(command.repairRootAfterRemount ? { repairRootAfterRemount: true } : {}),
|
|
388
402
|
updateExisting: command.updateExisting,
|
|
403
|
+
reuseExistingEnvironment: command.reuseExistingEnvironment,
|
|
404
|
+
allowInterruptActiveTasks: command.allowInterruptActiveTasks,
|
|
389
405
|
...(command.rootPath ? { rootPath: command.rootPath } : {}),
|
|
390
406
|
...(command.projectDirectoryRoots
|
|
391
407
|
? { projectDirectoryRoots: command.projectDirectoryRoots }
|
|
@@ -485,7 +501,13 @@ export async function runMakaCli(argv = process.argv.slice(2), options = RELEASE
|
|
|
485
501
|
defaultRootPath: serviceDataRoots.workspaceRoot,
|
|
486
502
|
selector: command.selector,
|
|
487
503
|
expectedTarget: command.expectedTarget,
|
|
504
|
+
...(command.expectedSourceVersion
|
|
505
|
+
? { expectedSourceVersion: command.expectedSourceVersion }
|
|
506
|
+
: {}),
|
|
488
507
|
...(command.expectedHost ? { expectedHost: command.expectedHost } : {}),
|
|
508
|
+
...(command.expectedConfigFingerprint
|
|
509
|
+
? { expectedConfigFingerprint: command.expectedConfigFingerprint }
|
|
510
|
+
: {}),
|
|
489
511
|
...(command.managedRootId ? { managedRootId: command.managedRootId } : {}),
|
|
490
512
|
...(command.operatorDeploymentId
|
|
491
513
|
? { operatorDeploymentId: command.operatorDeploymentId }
|
|
@@ -503,7 +525,13 @@ export async function runMakaCli(argv = process.argv.slice(2), options = RELEASE
|
|
|
503
525
|
...(sourcePackageIntegrity ? { sourcePackageIntegrity } : {}),
|
|
504
526
|
version,
|
|
505
527
|
expectedTarget: command.expectedTarget,
|
|
528
|
+
...(command.expectedSourceVersion
|
|
529
|
+
? { expectedSourceVersion: command.expectedSourceVersion }
|
|
530
|
+
: {}),
|
|
506
531
|
...(command.expectedHost ? { expectedHost: command.expectedHost } : {}),
|
|
532
|
+
...(command.expectedConfigFingerprint
|
|
533
|
+
? { expectedConfigFingerprint: command.expectedConfigFingerprint }
|
|
534
|
+
: {}),
|
|
507
535
|
...(command.managedRootId ? { managedRootId: command.managedRootId } : {}),
|
|
508
536
|
...(command.operatorDeploymentId
|
|
509
537
|
? { operatorDeploymentId: command.operatorDeploymentId }
|
package/dist/runtime-host-cli.js
CHANGED
|
@@ -363,6 +363,8 @@ function parseSetupCommand(argv) {
|
|
|
363
363
|
let bindPairingToClient = false;
|
|
364
364
|
let repairRootAfterRemount = false;
|
|
365
365
|
let updateExisting = false;
|
|
366
|
+
let reuseExistingEnvironment = false;
|
|
367
|
+
let allowInterruptActiveTasks = false;
|
|
366
368
|
let clientDataRoot;
|
|
367
369
|
let enableDirectPeer = false;
|
|
368
370
|
const coordinationRelays = [];
|
|
@@ -418,6 +420,16 @@ function parseSetupCommand(argv) {
|
|
|
418
420
|
return error('Duplicate --repair-root-after-remount');
|
|
419
421
|
repairRootAfterRemount = true;
|
|
420
422
|
},
|
|
423
|
+
'--allow-interrupt-active-tasks': () => {
|
|
424
|
+
if (allowInterruptActiveTasks)
|
|
425
|
+
return error('Duplicate --allow-interrupt-active-tasks');
|
|
426
|
+
allowInterruptActiveTasks = true;
|
|
427
|
+
},
|
|
428
|
+
'--reuse-existing-environment': () => {
|
|
429
|
+
if (reuseExistingEnvironment)
|
|
430
|
+
return error('Duplicate --reuse-existing-environment');
|
|
431
|
+
reuseExistingEnvironment = true;
|
|
432
|
+
},
|
|
421
433
|
'--update-existing': () => {
|
|
422
434
|
if (updateExisting)
|
|
423
435
|
return error('Duplicate --update-existing');
|
|
@@ -427,6 +439,17 @@ function parseSetupCommand(argv) {
|
|
|
427
439
|
});
|
|
428
440
|
if ('kind' in options)
|
|
429
441
|
return options;
|
|
442
|
+
if (reuseExistingEnvironment &&
|
|
443
|
+
(lifecycle !== 'on_demand' ||
|
|
444
|
+
updateExisting ||
|
|
445
|
+
enableDirectPeer ||
|
|
446
|
+
deferPairingCommit ||
|
|
447
|
+
bindPairingToClient)) {
|
|
448
|
+
return error('--reuse-existing-environment requires on-demand local setup without update or remote pairing options');
|
|
449
|
+
}
|
|
450
|
+
if (allowInterruptActiveTasks && !updateExisting) {
|
|
451
|
+
return error('--allow-interrupt-active-tasks requires --update-existing');
|
|
452
|
+
}
|
|
430
453
|
if (!principalId || !/^[A-Za-z0-9_.:-]{1,128}$/u.test(principalId)) {
|
|
431
454
|
return error('runtime-host setup requires a valid --principal');
|
|
432
455
|
}
|
|
@@ -448,6 +471,8 @@ function parseSetupCommand(argv) {
|
|
|
448
471
|
...(bindPairingToClient ? { bindPairingToClient: true } : {}),
|
|
449
472
|
...(repairRootAfterRemount ? { repairRootAfterRemount: true } : {}),
|
|
450
473
|
...(updateExisting ? { updateExisting: true } : {}),
|
|
474
|
+
...(reuseExistingEnvironment ? { reuseExistingEnvironment: true } : {}),
|
|
475
|
+
...(allowInterruptActiveTasks ? { allowInterruptActiveTasks: true } : {}),
|
|
451
476
|
...(clientDataRoot ? { clientDataRoot } : {}),
|
|
452
477
|
...(enableDirectPeer ? { directPeer: { coordinationRelays } } : {}),
|
|
453
478
|
};
|
|
@@ -522,6 +547,7 @@ function parseServiceManagementCommand(argv) {
|
|
|
522
547
|
let updateTarget;
|
|
523
548
|
let expectedHost;
|
|
524
549
|
let expectedConfigFingerprint;
|
|
550
|
+
let expectedSourceVersion;
|
|
525
551
|
const flagOptions = action === 'uninstall'
|
|
526
552
|
? {
|
|
527
553
|
'--retain-managed-deployment': () => {
|
|
@@ -580,6 +606,17 @@ function parseServiceManagementCommand(argv) {
|
|
|
580
606
|
},
|
|
581
607
|
}
|
|
582
608
|
: {}),
|
|
609
|
+
...(action === 'update'
|
|
610
|
+
? {
|
|
611
|
+
'--expected-source-version': (value) => {
|
|
612
|
+
if (expectedSourceVersion !== undefined)
|
|
613
|
+
return error('Duplicate --expected-source-version');
|
|
614
|
+
if (!isProductReleaseVersion(value))
|
|
615
|
+
return error('--expected-source-version must be an exact package version');
|
|
616
|
+
expectedSourceVersion = value;
|
|
617
|
+
},
|
|
618
|
+
}
|
|
619
|
+
: {}),
|
|
583
620
|
...(action === 'update' || action === 'restart'
|
|
584
621
|
? {
|
|
585
622
|
'--expected-host-json': (value) => {
|
|
@@ -592,7 +629,7 @@ function parseServiceManagementCommand(argv) {
|
|
|
592
629
|
},
|
|
593
630
|
}
|
|
594
631
|
: {}),
|
|
595
|
-
...(action === 'configure'
|
|
632
|
+
...(action === 'configure' || action === 'update'
|
|
596
633
|
? {
|
|
597
634
|
'--expected-config-fingerprint': (value) => {
|
|
598
635
|
if (expectedConfigFingerprint !== undefined) {
|
|
@@ -674,8 +711,9 @@ function parseServiceManagementCommand(argv) {
|
|
|
674
711
|
};
|
|
675
712
|
}
|
|
676
713
|
if (action === 'update') {
|
|
677
|
-
if (expectedHost
|
|
678
|
-
|
|
714
|
+
if ((expectedHost || expectedSourceVersion || expectedConfigFingerprint) &&
|
|
715
|
+
!options.managedRootId) {
|
|
716
|
+
return error('Observed Host and deployment fences require --managed-root-id');
|
|
679
717
|
}
|
|
680
718
|
const selector = updateTarget === undefined ? undefined : parseUpdateSelector(updateTarget, 'update');
|
|
681
719
|
if (selector && 'kind' in selector && selector.kind === 'error')
|
|
@@ -697,6 +735,8 @@ function parseServiceManagementCommand(argv) {
|
|
|
697
735
|
: {}),
|
|
698
736
|
expectedTarget: options.expectedTarget,
|
|
699
737
|
...(expectedHost ? { expectedHost } : {}),
|
|
738
|
+
...(expectedConfigFingerprint ? { expectedConfigFingerprint } : {}),
|
|
739
|
+
...(expectedSourceVersion ? { expectedSourceVersion } : {}),
|
|
700
740
|
...(selector ? { selector } : {}),
|
|
701
741
|
...(allowManualUpdate ? { allowManualUpdate: true } : {}),
|
|
702
742
|
...(allowInterruptActiveTasks ? { allowInterruptActiveTasks: true } : {}),
|
|
@@ -60,7 +60,7 @@ export function createCliHostHandoffSurface(locale, input = process.stdin, outpu
|
|
|
60
60
|
'\n');
|
|
61
61
|
if (view.actions.length === 0)
|
|
62
62
|
return;
|
|
63
|
-
const options = copy.actions.map(({ action, label }) => `${action === 'interrupt' ? 'stop' : action === 'retry' ? 'r' : 'Enter'}: ${label}`);
|
|
63
|
+
const options = copy.actions.map(({ action, label }) => `${action === 'interrupt' ? 'stop' : action === 'retry' ? 'r' : action === 'replace' ? 'update' : 'Enter'}: ${label}`);
|
|
64
64
|
// Create the reader only after the explanation is visible, with the
|
|
65
65
|
// final action prompt already installed. Never draw readline's default >.
|
|
66
66
|
const reader = createInterface({
|
|
@@ -82,13 +82,15 @@ export function createCliHostHandoffSurface(locale, input = process.stdin, outpu
|
|
|
82
82
|
if (readline !== reader || current?.revision !== view.revision)
|
|
83
83
|
return;
|
|
84
84
|
const answer = line.trim().toLowerCase();
|
|
85
|
-
const action = answer === '
|
|
86
|
-
? '
|
|
87
|
-
: answer === '
|
|
88
|
-
? '
|
|
89
|
-
: answer === ''
|
|
90
|
-
? '
|
|
91
|
-
:
|
|
85
|
+
const action = answer === 'update'
|
|
86
|
+
? 'replace'
|
|
87
|
+
: answer === 'r'
|
|
88
|
+
? 'retry'
|
|
89
|
+
: answer === 'stop'
|
|
90
|
+
? 'interrupt'
|
|
91
|
+
: answer === ''
|
|
92
|
+
? 'cancel'
|
|
93
|
+
: undefined;
|
|
92
94
|
if (!action || !view.actions.includes(action)) {
|
|
93
95
|
reader.prompt();
|
|
94
96
|
return;
|
|
@@ -178,9 +178,6 @@ export async function retireRuntimeHostLifecycleOwner(input) {
|
|
|
178
178
|
}
|
|
179
179
|
async function retireRuntimeHostLifecycleOwnerWithSignal(input, signal) {
|
|
180
180
|
signal?.throwIfAborted();
|
|
181
|
-
if (input.expectedOwner && !input.supervisor) {
|
|
182
|
-
throw new RuntimeHostLifecycleTransactionError('owner_changed', 'A Runtime Host identity fence requires a supervised deployment');
|
|
183
|
-
}
|
|
184
181
|
const capability = await resolveExistingStorageRoot({
|
|
185
182
|
path: input.rootPath,
|
|
186
183
|
kind: 'interactive',
|
|
@@ -189,6 +186,9 @@ async function retireRuntimeHostLifecycleOwnerWithSignal(input, signal) {
|
|
|
189
186
|
const idleOwner = await tryAcquireStateRootOwner(capability);
|
|
190
187
|
if (idleOwner) {
|
|
191
188
|
try {
|
|
189
|
+
if (input.expectedOwner && !input.supervisor) {
|
|
190
|
+
throw new RuntimeHostLifecycleTransactionError('owner_changed', 'The observed Runtime Host has exited');
|
|
191
|
+
}
|
|
192
192
|
if (input.expectedOwner && input.supervisor) {
|
|
193
193
|
const status = await input.supervisor.status();
|
|
194
194
|
assertExpectedSupervisorOwner(input.expectedOwner, status);
|
|
@@ -212,6 +212,21 @@ async function retireRuntimeHostLifecycleOwnerWithSignal(input, signal) {
|
|
|
212
212
|
});
|
|
213
213
|
assertExpectedRuntimeHostOwner(input.expectedOwner, 'registration' in connected ? connected.registration : undefined);
|
|
214
214
|
if (connected.kind !== 'connected') {
|
|
215
|
+
if (connected.kind === 'incompatible' &&
|
|
216
|
+
connected.registration?.rootId === input.rootId &&
|
|
217
|
+
connected.registration.lifecycleMode === 'ephemeral' &&
|
|
218
|
+
input.expectedOwner &&
|
|
219
|
+
!input.supervisor &&
|
|
220
|
+
input.prepareSourceRetirement) {
|
|
221
|
+
signal?.throwIfAborted();
|
|
222
|
+
const prepared = await input.prepareSourceRetirement(signal);
|
|
223
|
+
if (prepared === 'active_work')
|
|
224
|
+
return { kind: 'active_tasks' };
|
|
225
|
+
if (prepared === 'prepared') {
|
|
226
|
+
return waitForRuntimeHostLifecycleOwner(capability, input.timeoutMs ?? 45_000);
|
|
227
|
+
}
|
|
228
|
+
throw new RuntimeHostLifecycleTransactionError('transition_failed', 'The installed source package cannot retire this Runtime Host');
|
|
229
|
+
}
|
|
215
230
|
if (input.supervisor) {
|
|
216
231
|
const status = await input.supervisor.status();
|
|
217
232
|
assertExpectedSupervisorOwner(input.expectedOwner, status);
|
|
@@ -316,6 +331,10 @@ export async function replaceRuntimeHostLifecycle(input) {
|
|
|
316
331
|
const retirement = await retireRuntimeHostLifecycleOwner({
|
|
317
332
|
rootPath: desired.root.path,
|
|
318
333
|
rootId: desired.root.id,
|
|
334
|
+
...(input.deps.connectExisting ? { connectExisting: input.deps.connectExisting } : {}),
|
|
335
|
+
...(input.prepareSourceRetirement
|
|
336
|
+
? { prepareSourceRetirement: input.prepareSourceRetirement }
|
|
337
|
+
: {}),
|
|
319
338
|
...(input.retirementSupervisor
|
|
320
339
|
? { supervisor: input.retirementSupervisor }
|
|
321
340
|
: currentProvider
|
|
@@ -345,6 +364,12 @@ export async function replaceRuntimeHostLifecycle(input) {
|
|
|
345
364
|
}
|
|
346
365
|
}
|
|
347
366
|
catch (activationError) {
|
|
367
|
+
// An on-demand update may have allowed its successor to open the State Root
|
|
368
|
+
// before readiness failed. Keep that successor authoritative; configuring an
|
|
369
|
+
// existing package and supervised updates retain their rollback behavior.
|
|
370
|
+
if (input.operation === 'update' && desired.lifecycle.mode === 'on_demand') {
|
|
371
|
+
throw new RuntimeHostLifecycleTransactionError('recovery_failed', 'The updated Runtime Host could not become ready. Its deployment is retained; retry activation or repair it without restoring older code.', { cause: activationError });
|
|
372
|
+
}
|
|
348
373
|
const rollback = current
|
|
349
374
|
? {
|
|
350
375
|
...current,
|
|
@@ -74,7 +74,7 @@ export function launchRuntimeHostLocalSourceRetirement(input) {
|
|
|
74
74
|
: []),
|
|
75
75
|
];
|
|
76
76
|
return new Promise((resolve, reject) => {
|
|
77
|
-
const child = spawn(process.execPath, args, {
|
|
77
|
+
const child = spawn(input.sourceNodePath ?? process.execPath, args, {
|
|
78
78
|
// fd 4 inherits the existing owner-authority lease. The source helper
|
|
79
79
|
// holds it only while the authenticated retirement request is in flight.
|
|
80
80
|
stdio: ['ignore', 'ignore', 'inherit', 'ignore', input.inheritableAuthorityLeaseFd],
|
|
@@ -569,19 +569,25 @@ class NonInteractiveInteractionController {
|
|
|
569
569
|
#tasks = new Set();
|
|
570
570
|
#unsubscribe;
|
|
571
571
|
#failure;
|
|
572
|
-
#
|
|
573
|
-
#publishFailure;
|
|
572
|
+
#failureWaiters = new Set();
|
|
574
573
|
constructor(driver, stop) {
|
|
575
574
|
this.#driver = driver;
|
|
576
575
|
this.#stop = stop;
|
|
577
|
-
this.#failureSignal = new Promise((resolve) => {
|
|
578
|
-
this.#publishFailure = resolve;
|
|
579
|
-
});
|
|
580
576
|
this.#unsubscribe = driver.subscribePendingInteractions((pending) => this.#accept(pending));
|
|
581
577
|
}
|
|
582
578
|
race(operation) {
|
|
583
579
|
this.throwIfFailed();
|
|
584
|
-
return Promise
|
|
580
|
+
return new Promise((resolve, reject) => {
|
|
581
|
+
this.#failureWaiters.add(reject);
|
|
582
|
+
// Detach completed waits so the controller does not retain consumed event payloads.
|
|
583
|
+
operation.then((value) => {
|
|
584
|
+
this.#failureWaiters.delete(reject);
|
|
585
|
+
resolve(value);
|
|
586
|
+
}, (error) => {
|
|
587
|
+
this.#failureWaiters.delete(reject);
|
|
588
|
+
reject(error);
|
|
589
|
+
});
|
|
590
|
+
});
|
|
585
591
|
}
|
|
586
592
|
async settle() {
|
|
587
593
|
await Promise.all([...this.#tasks]);
|
|
@@ -623,7 +629,9 @@ class NonInteractiveInteractionController {
|
|
|
623
629
|
if (this.#failure)
|
|
624
630
|
return;
|
|
625
631
|
this.#failure = error;
|
|
626
|
-
this.#
|
|
632
|
+
for (const reject of this.#failureWaiters)
|
|
633
|
+
reject(error);
|
|
634
|
+
this.#failureWaiters.clear();
|
|
627
635
|
}
|
|
628
636
|
}
|
|
629
637
|
function delay(ms) {
|
|
@@ -23,7 +23,7 @@ import { isDeepStrictEqual } from 'node:util';
|
|
|
23
23
|
import { truncateUtf8 } from '@maka/core/diagnostic-log';
|
|
24
24
|
import { generalizedErrorMessage } from '@maka/core/redaction';
|
|
25
25
|
import { activateRuntimeHostManagedDeployment, connectRemoteRuntimeHost, ensureRuntimeHostPeerIdentity, RuntimeHostOperationError, } from '@maka/runtime-host/client';
|
|
26
|
-
import { RuntimeHostManagedDeploymentError as RuntimeHostDeploymentAuthorityError, encodeRuntimeHostSetupFrame, isSha512PackageIntegrity, resolveRuntimeHostManagedDeployment, runtimeHostManagedOperatorCommand, RUNTIME_HOST_SETUP_ERROR_CODE_MAX_BYTES, RUNTIME_HOST_SETUP_ERROR_MESSAGE_MAX_BYTES, } from '@maka/runtime-host/operator';
|
|
26
|
+
import { RuntimeHostManagedDeploymentError as RuntimeHostDeploymentAuthorityError, encodeRuntimeHostSetupFrame, isSha512PackageIntegrity, resolveRuntimeHostManagedDeployment, resolveRuntimeHostManagedDeploymentAuthority, runtimeHostManagedOperatorCommand, RUNTIME_HOST_SETUP_ERROR_CODE_MAX_BYTES, RUNTIME_HOST_SETUP_ERROR_MESSAGE_MAX_BYTES, } from '@maka/runtime-host/operator';
|
|
27
27
|
import { INTERACTIVE_RUNTIME_HOST_COMPOSITION_ID, RUNTIME_HOST_PROTOCOL_VERSION, } from '@maka/runtime-host/protocol';
|
|
28
28
|
import { prepareRuntimeHostAccessCredential, replaceRuntimeHostAccessCredential, revokeRuntimeHostAccessCredential, RuntimeHostAccessUnavailableError, } from './runtime-host-access-command.js';
|
|
29
29
|
import { convergeRuntimeHostManagedOperator, verifyRuntimeHostManagedOperator, isRuntimeHostDevelopmentPackageVersion, openRuntimeHostManagedPackageDeployment, prepareRuntimeHostManagedPackageDeployment, pruneRuntimeHostManagedPackages, removeRuntimeHostManagedDeployment, resolveRuntimeHostManagedPackageCliPath, resolveRuntimeHostManagedControlRoot, resolveRuntimeHostManagedDeploymentRoot, restoreRuntimeHostLegacyManagedOperator, RuntimeHostManagedDeploymentError, } from './runtime-host-managed-deployment.js';
|
|
@@ -107,7 +107,7 @@ export async function runRuntimeHostSetupCli(options, overrides = {}) {
|
|
|
107
107
|
try {
|
|
108
108
|
const rootId = await resolveRuntimeHostSetupRootId(options);
|
|
109
109
|
const controlRoot = resolveRuntimeHostManagedControlRoot(rootId);
|
|
110
|
-
await withRuntimeHostManagedServiceDeploymentLock(options.clientDataRoot, () => withRuntimeHostManagedServiceLifecycleLock(options.clientDataRoot, () => withRuntimeHostManagedServiceDeploymentLock(controlRoot, () => withRuntimeHostManagedServiceLifecycleLock(controlRoot, () => runRuntimeHostSetupLocked(options, deps, emit), SETUP_LOCK_TIMEOUT_MS), SETUP_LOCK_TIMEOUT_MS), SETUP_LOCK_TIMEOUT_MS), SETUP_LOCK_TIMEOUT_MS);
|
|
110
|
+
await withRuntimeHostManagedServiceDeploymentLock(options.clientDataRoot, () => withRuntimeHostManagedServiceLifecycleLock(options.clientDataRoot, () => withRuntimeHostManagedServiceDeploymentLock(controlRoot, () => withRuntimeHostManagedServiceLifecycleLock(controlRoot, () => runRuntimeHostSetupLocked(options, deps, emit, rootId), SETUP_LOCK_TIMEOUT_MS), SETUP_LOCK_TIMEOUT_MS), SETUP_LOCK_TIMEOUT_MS), SETUP_LOCK_TIMEOUT_MS);
|
|
111
111
|
return 0;
|
|
112
112
|
}
|
|
113
113
|
catch (error) {
|
|
@@ -138,7 +138,30 @@ async function readOptionalLegacyServiceConfig(clientDataRoot) {
|
|
|
138
138
|
throw error;
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
-
async function runRuntimeHostSetupLocked(options, deps, emit) {
|
|
141
|
+
async function runRuntimeHostSetupLocked(options, deps, emit, rootId) {
|
|
142
|
+
if (options.reuseExistingEnvironment) {
|
|
143
|
+
if (options.lifecycle !== 'on_demand' || options.updateExisting) {
|
|
144
|
+
throw new RuntimeHostSetupError('invalid_setup', 'Environment discovery cannot replace a deployment');
|
|
145
|
+
}
|
|
146
|
+
const existing = await resolveRuntimeHostManagedDeploymentAuthority(rootId);
|
|
147
|
+
if (existing) {
|
|
148
|
+
const { config, capability } = await resolveRuntimeHostManagedDeployment(rootId);
|
|
149
|
+
assertCanonicalSetupTarget(options.expectedTarget, rootId, capability.canonicalPath);
|
|
150
|
+
assertExpectedDeploymentGeneration(options.expectedTarget, config);
|
|
151
|
+
// The binding comes from canonical authority. The installed operator validates
|
|
152
|
+
// its own projection when connected; discovery must not rewrite an older launcher.
|
|
153
|
+
emit({
|
|
154
|
+
kind: 'existing_environment',
|
|
155
|
+
version: config.launch.package.version,
|
|
156
|
+
serviceId: rootId,
|
|
157
|
+
deploymentId: config.deploymentId,
|
|
158
|
+
rootId,
|
|
159
|
+
rootPath: capability.canonicalPath,
|
|
160
|
+
operator: runtimeHostManagedOperatorCommand(config, process.platform === 'win32' ? 'win32' : 'posix'),
|
|
161
|
+
});
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
142
165
|
if (options.lifecycle === 'on_demand') {
|
|
143
166
|
await runRuntimeHostOnDemandSetupLocked(options, deps, emit);
|
|
144
167
|
return;
|
|
@@ -260,7 +283,7 @@ async function runRuntimeHostSupervisedSetupLocked(options, deps, emit) {
|
|
|
260
283
|
.then(() => undefined),
|
|
261
284
|
}
|
|
262
285
|
: {}),
|
|
263
|
-
allowInterruptActiveTasks:
|
|
286
|
+
allowInterruptActiveTasks: options.allowInterruptActiveTasks === true,
|
|
264
287
|
deps: lifecycleDeps,
|
|
265
288
|
});
|
|
266
289
|
if (replacement.kind === 'active_tasks') {
|
|
@@ -561,7 +584,7 @@ async function runRuntimeHostOnDemandSetupLocked(options, deps, emit) {
|
|
|
561
584
|
activateDesired: async () => {
|
|
562
585
|
await deps.activateDesired({ rootId: capability.rootId });
|
|
563
586
|
},
|
|
564
|
-
allowInterruptActiveTasks:
|
|
587
|
+
allowInterruptActiveTasks: options.allowInterruptActiveTasks === true,
|
|
565
588
|
deps: lifecycleDeps,
|
|
566
589
|
});
|
|
567
590
|
if (replacement.kind === 'active_tasks') {
|
|
@@ -826,7 +849,7 @@ function createEmitter(json, deps) {
|
|
|
826
849
|
if (frame.kind === 'progress') {
|
|
827
850
|
deps.writeOutput(`${humanPhase(frame.phase)}\n`);
|
|
828
851
|
}
|
|
829
|
-
else if (frame.kind === 'complete') {
|
|
852
|
+
else if (frame.kind === 'complete' || frame.kind === 'existing_environment') {
|
|
830
853
|
deps.writeOutput(`${JSON.stringify(frame, null, 2)}\n`);
|
|
831
854
|
}
|
|
832
855
|
else {
|
|
@@ -20,13 +20,14 @@ import { spawn } from 'node:child_process';
|
|
|
20
20
|
import { dirname, join, resolve } from 'node:path';
|
|
21
21
|
import { truncateUtf8 } from '@maka/core/diagnostic-log';
|
|
22
22
|
import { activateRuntimeHostManagedDeployment } from '@maka/runtime-host/client';
|
|
23
|
-
import { createRuntimeHostLegacyPosixOperatorCommand, decodeRuntimeHostServiceManagementFrame, encodeRuntimeHostServiceManagementFrame, RUNTIME_HOST_SERVICE_ERROR_CODE_MAX_BYTES, RUNTIME_HOST_SERVICE_ERROR_MESSAGE_MAX_BYTES, RUNTIME_HOST_OPERATOR_ACCESS_MANAGEMENT_CAPABILITY, RUNTIME_HOST_OPERATOR_CAPABILITY_REQUEST_ENV, RUNTIME_HOST_OPERATOR_PROCESS_LIFETIME_LOCK_CAPABILITY, runtimeHostOperatorInvocation, RuntimeHostManagedDeploymentError as RuntimeHostDeploymentAuthorityError, } from '@maka/runtime-host/operator';
|
|
24
|
-
import { assertRuntimeHostManagedOperatorConfig, assertRuntimeHostManagedOperatorDeployment, convergeRuntimeHostManagedOperator, verifyRuntimeHostManagedOperator, openRuntimeHostManagedPackageDeployment, prepareRuntimeHostManagedPackageDeployment, pruneRuntimeHostManagedPackages, resolveRuntimeHostManagedControlRoot, resolveRuntimeHostManagedPackageCliPath, RuntimeHostManagedDeploymentError, } from './runtime-host-managed-deployment.js';
|
|
25
|
-
import { manageRuntimeHostService, replaceRuntimeHostManagedService, resolveRuntimeHostManagedServiceId, RuntimeHostServiceManagerError, verifyRuntimeHostManagedServiceReady, withRuntimeHostManagedServiceDeploymentLock, withRuntimeHostManagedServiceLegacyOperatorLeases, withRuntimeHostManagedServiceLifecycleLock, } from './runtime-host-service-manager.js';
|
|
23
|
+
import { compareProductReleaseVersions, createRuntimeHostLegacyPosixOperatorCommand, decodeRuntimeHostServiceManagementFrame, encodeRuntimeHostServiceManagementFrame, RUNTIME_HOST_SERVICE_ERROR_CODE_MAX_BYTES, RUNTIME_HOST_SERVICE_ERROR_MESSAGE_MAX_BYTES, RUNTIME_HOST_OPERATOR_ACCESS_MANAGEMENT_CAPABILITY, RUNTIME_HOST_OPERATOR_CAPABILITY_REQUEST_ENV, RUNTIME_HOST_OPERATOR_PROCESS_LIFETIME_LOCK_CAPABILITY, runtimeHostOperatorInvocation, RuntimeHostManagedDeploymentError as RuntimeHostDeploymentAuthorityError, } from '@maka/runtime-host/operator';
|
|
24
|
+
import { isRuntimeHostDevelopmentPackageVersion, assertRuntimeHostManagedOperatorConfig, assertRuntimeHostManagedOperatorDeployment, convergeRuntimeHostManagedOperator, verifyRuntimeHostManagedOperator, openRuntimeHostManagedPackageDeployment, prepareRuntimeHostManagedPackageDeployment, pruneRuntimeHostManagedPackages, resolveRuntimeHostManagedControlRoot, resolveRuntimeHostManagedPackageCliPath, RuntimeHostManagedDeploymentError, } from './runtime-host-managed-deployment.js';
|
|
25
|
+
import { runtimeHostManagedServiceConfigFingerprint, manageRuntimeHostService, replaceRuntimeHostManagedService, resolveRuntimeHostManagedServiceId, RuntimeHostServiceManagerError, verifyRuntimeHostManagedServiceReady, withRuntimeHostManagedServiceDeploymentLock, withRuntimeHostManagedServiceLegacyOperatorLeases, withRuntimeHostManagedServiceLifecycleLock, } from './runtime-host-service-manager.js';
|
|
26
26
|
import { createPlatformRuntimeHostServiceBackend, resolveRuntimeHostLifecycleProvider, runtimeHostServiceSummary, } from './runtime-host-service-management-command.js';
|
|
27
27
|
import { resolveManagedRuntimeHostUpdateSelection, RuntimeHostUpdateDiscoveryError, } from './runtime-host-update-discovery.js';
|
|
28
28
|
import { RuntimeHostUpdatePackageError, withRuntimeHostRegistryUpdatePackage, } from './runtime-host-update-package.js';
|
|
29
29
|
import { canDiscardRuntimeHostLifecycleDesiredArtifacts, convergeRuntimeHostLifecycleControlProjection, replaceRuntimeHostLifecycle, resolveRecoverableRuntimeHostManagedDeployment, RuntimeHostLifecycleTransactionError, verifyRuntimeHostLifecycleProjection, } from './runtime-host-lifecycle-transaction.js';
|
|
30
|
+
import { launchRuntimeHostLocalSourceRetirement } from './runtime-host-local-source-retirement.js';
|
|
30
31
|
import { manageRuntimeHostManagedLifecycle } from './runtime-host-managed-lifecycle-manager.js';
|
|
31
32
|
const OPERATOR_TIMEOUT_MS = 2 * 60_000;
|
|
32
33
|
const OPERATOR_OUTPUT_MAX_BYTES = 256 * 1024;
|
|
@@ -53,6 +54,7 @@ export async function runManagedRuntimeHostUpdateCli(options, overrides = {}, fr
|
|
|
53
54
|
openDeployment: openRuntimeHostManagedPackageDeployment,
|
|
54
55
|
prepareDeployment: prepareRuntimeHostManagedPackageDeployment,
|
|
55
56
|
prunePackages: pruneRuntimeHostManagedPackages,
|
|
57
|
+
retireSource: launchRuntimeHostLocalSourceRetirement,
|
|
56
58
|
activateDesired: (input) => activateRuntimeHostManagedDeployment(input, {
|
|
57
59
|
reconcileActivation: async () => undefined,
|
|
58
60
|
}),
|
|
@@ -379,7 +381,7 @@ export async function runManagedRuntimeHostUpdateCli(options, overrides = {}, fr
|
|
|
379
381
|
async function runCanonicalRuntimeHostUpdate(options, deps, emit) {
|
|
380
382
|
let staged;
|
|
381
383
|
try {
|
|
382
|
-
return await deps.withDeploymentLock(resolveRuntimeHostManagedControlRoot(options.managedRootId), async () => {
|
|
384
|
+
return await deps.withDeploymentLock(resolveRuntimeHostManagedControlRoot(options.managedRootId), async (inheritableAuthorityLeaseFd) => {
|
|
383
385
|
await deps.canonical.assertOperatorDeployment(options.managedRootId, options.operatorDeploymentId, process.argv[1] ?? '');
|
|
384
386
|
const rejection = await deps.revalidateSelection();
|
|
385
387
|
if (rejection) {
|
|
@@ -395,6 +397,10 @@ async function runCanonicalRuntimeHostUpdate(options, deps, emit) {
|
|
|
395
397
|
throw new RuntimeHostServiceManagerError('not_installed', 'The managed Runtime Host deployment is not installed');
|
|
396
398
|
}
|
|
397
399
|
const current = recovered.config;
|
|
400
|
+
if (options.expectedSourceVersion &&
|
|
401
|
+
current.launch.package.version !== options.expectedSourceVersion) {
|
|
402
|
+
throw new RuntimeHostServiceManagerError('target_mismatch', 'The installed Runtime Host package changed; check it again before updating');
|
|
403
|
+
}
|
|
398
404
|
await deps.canonical.convergeControlProjection(current, lifecycleDeps);
|
|
399
405
|
await deps.canonical.verifyProjection(current, lifecycleDeps);
|
|
400
406
|
deps.canonical.assertOperatorConfig(current, options.operatorDeploymentId, process.argv[1] ?? '');
|
|
@@ -406,6 +412,21 @@ async function runCanonicalRuntimeHostUpdate(options, deps, emit) {
|
|
|
406
412
|
cliPath: process.argv[1] ?? '',
|
|
407
413
|
expectedTarget: options.expectedTarget,
|
|
408
414
|
}, { resolveProvider: resolveRuntimeHostLifecycleProvider });
|
|
415
|
+
if (options.expectedConfigFingerprint &&
|
|
416
|
+
(!currentStatus.service.config ||
|
|
417
|
+
runtimeHostManagedServiceConfigFingerprint(currentStatus.service.config) !==
|
|
418
|
+
options.expectedConfigFingerprint)) {
|
|
419
|
+
throw new RuntimeHostServiceManagerError('target_mismatch', 'The managed Runtime Host configuration changed; check it again before updating');
|
|
420
|
+
}
|
|
421
|
+
const developmentArtifact = isRuntimeHostDevelopmentPackageVersion(options.version) ||
|
|
422
|
+
isRuntimeHostDevelopmentPackageVersion(current.launch.package.version);
|
|
423
|
+
if (developmentArtifact && !options.sourcePackageIntegrity) {
|
|
424
|
+
throw new RuntimeHostServiceManagerError('target_mismatch', 'Development deployments require an explicitly selected source artifact; source hashes do not establish release order');
|
|
425
|
+
}
|
|
426
|
+
if (!developmentArtifact &&
|
|
427
|
+
compareProductReleaseVersions(options.version, current.launch.package.version) < 0) {
|
|
428
|
+
throw new RuntimeHostServiceManagerError('target_mismatch', 'This update would downgrade the shared Runtime Host. Update the Client instead.');
|
|
429
|
+
}
|
|
409
430
|
const targetIntegrity = options.sourcePackageIntegrity ??
|
|
410
431
|
options.registrySelection?.integrity ??
|
|
411
432
|
(options.version === current.launch.package.version
|
|
@@ -468,15 +489,38 @@ async function runCanonicalRuntimeHostUpdate(options, deps, emit) {
|
|
|
468
489
|
},
|
|
469
490
|
};
|
|
470
491
|
emit(progress('retiring', current.launch.package.version, options.version));
|
|
471
|
-
emit(progress('replacing', current.launch.package.version, options.version));
|
|
472
492
|
const replacement = await deps.canonical.replaceLifecycle({
|
|
473
493
|
operation: 'update',
|
|
494
|
+
validateRetiredState: async () => {
|
|
495
|
+
emit(progress('replacing', current.launch.package.version, options.version));
|
|
496
|
+
},
|
|
474
497
|
current,
|
|
475
498
|
desired,
|
|
476
499
|
allowInterruptActiveTasks: options.allowInterruptActiveTasks ?? false,
|
|
477
500
|
...(options.expectedHost ? { expectedOwner: options.expectedHost } : {}),
|
|
478
501
|
...(desired.lifecycle.mode === 'on_demand'
|
|
479
502
|
? {
|
|
503
|
+
...(options.expectedHost
|
|
504
|
+
? {
|
|
505
|
+
prepareSourceRetirement: (signal) => {
|
|
506
|
+
if (inheritableAuthorityLeaseFd === undefined) {
|
|
507
|
+
throw new RuntimeHostServiceManagerError('target_mismatch', 'Source-package retirement requires the deployment authority lease');
|
|
508
|
+
}
|
|
509
|
+
return deps.retireSource({
|
|
510
|
+
sourceCliPath: currentCliPath,
|
|
511
|
+
sourceNodePath: current.launch.nodePath,
|
|
512
|
+
rootPath: current.root.path,
|
|
513
|
+
expectedRootId: current.root.id,
|
|
514
|
+
expectedHostEpoch: options.expectedHost.hostEpoch,
|
|
515
|
+
activeWorkPolicy: options.allowInterruptActiveTasks
|
|
516
|
+
? 'interrupt_active_work'
|
|
517
|
+
: 'refuse_active_work',
|
|
518
|
+
inheritableAuthorityLeaseFd,
|
|
519
|
+
...(signal ? { signal } : {}),
|
|
520
|
+
});
|
|
521
|
+
},
|
|
522
|
+
}
|
|
523
|
+
: {}),
|
|
480
524
|
activateDesired: async () => {
|
|
481
525
|
await deps.activateDesired({ rootId: options.managedRootId });
|
|
482
526
|
},
|