agent-tempo 1.7.0 → 2.0.0-beta.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/CLAUDE.md +10 -13
- package/README.md +21 -15
- package/dashboard/dist/assets/index-BbR7zIdK.js.map +1 -1
- package/dashboard/package.json +1 -1
- package/dist/activities/hard-terminate.d.ts +2 -2
- package/dist/activities/hard-terminate.js +3 -9
- package/dist/activities/maestro.d.ts +8 -13
- package/dist/activities/maestro.js +3 -10
- package/dist/activities/outbox.js +16 -2
- package/dist/activities/resolve.d.ts +18 -7
- package/dist/activities/resolve.js +58 -46
- package/dist/adapters/base.js +3 -0
- package/dist/adapters/claude-code/adapter.js +7 -0
- package/dist/cli/command-center-command.js +15 -1
- package/dist/cli/commands.d.ts +8 -0
- package/dist/cli/commands.js +79 -11
- package/dist/cli/daemon-command.js +19 -33
- package/dist/cli/help-text.js +9 -7
- package/dist/cli/home-command.d.ts +26 -0
- package/dist/cli/home-command.js +156 -0
- package/dist/cli/removed-verbs.d.ts +0 -4
- package/dist/cli/removed-verbs.js +23 -12
- package/dist/cli/sa-preflight.d.ts +0 -14
- package/dist/cli/sa-preflight.js +1 -17
- package/dist/cli/startup.d.ts +1 -10
- package/dist/cli/startup.js +0 -40
- package/dist/cli.js +34 -80
- package/dist/client/core.js +13 -15
- package/dist/client/index.d.ts +2 -1
- package/dist/client/interface.d.ts +5 -14
- package/dist/client/with-spawn.d.ts +9 -4
- package/dist/client/with-spawn.js +7 -10
- package/dist/config.d.ts +14 -13
- package/dist/config.js +14 -0
- package/dist/constants.d.ts +50 -0
- package/dist/constants.js +60 -1
- package/dist/daemon.js +81 -0
- package/dist/http/auth.d.ts +3 -21
- package/dist/http/auth.js +10 -31
- package/dist/http/event-types.d.ts +38 -4
- package/dist/http/orphans.d.ts +3 -3
- package/dist/http/orphans.js +3 -3
- package/dist/http/server.d.ts +0 -5
- package/dist/http/server.js +79 -29
- package/dist/http/snapshot.js +3 -0
- package/dist/http/writes.d.ts +1 -1
- package/dist/http/writes.js +25 -2
- package/dist/observability/nondeterminism-alarm.d.ts +113 -0
- package/dist/observability/nondeterminism-alarm.js +162 -0
- package/dist/palette/index.d.ts +6 -7
- package/dist/palette/index.js +6 -7
- package/dist/pi/mission-control/actions.d.ts +67 -1
- package/dist/pi/mission-control/actions.js +61 -0
- package/dist/pi/mission-control/extension.d.ts +77 -0
- package/dist/pi/mission-control/extension.js +171 -0
- package/dist/pi/workflow-client.d.ts +14 -16
- package/dist/pi/workflow-client.js +18 -44
- package/dist/server-tools.js +30 -29
- package/dist/server.js +42 -0
- package/dist/tools/action-guard.d.ts +23 -0
- package/dist/tools/action-guard.js +33 -0
- package/dist/tools/coat-check.d.ts +20 -0
- package/dist/tools/coat-check.js +129 -0
- package/dist/tools/gate.d.ts +13 -0
- package/dist/tools/gate.js +88 -0
- package/dist/tools/schedule.d.ts +18 -0
- package/dist/tools/schedule.js +93 -1
- package/dist/tools/stage.d.ts +17 -0
- package/dist/tools/stage.js +85 -1
- package/dist/tools/state.d.ts +14 -0
- package/dist/tools/state.js +95 -0
- package/dist/types.d.ts +54 -7
- package/dist/upgrade/boot-guard.d.ts +95 -0
- package/dist/upgrade/boot-guard.js +88 -0
- package/dist/upgrade/from-upgrade.d.ts +95 -0
- package/dist/upgrade/from-upgrade.js +330 -0
- package/dist/upgrade/phase-engine.js +4 -1
- package/dist/utils/duration.d.ts +3 -6
- package/dist/utils/duration.js +3 -6
- package/dist/utils/format-hosts.d.ts +1 -1
- package/dist/utils/format-hosts.js +0 -2
- package/dist/utils/grpc-shutdown-guard.js +0 -4
- package/dist/utils/hosts.d.ts +4 -10
- package/dist/utils/hosts.js +12 -28
- package/dist/utils/orphan-guard.d.ts +37 -0
- package/dist/utils/orphan-guard.js +26 -0
- package/dist/utils/search-attributes.d.ts +28 -18
- package/dist/utils/search-attributes.js +48 -18
- package/dist/utils/visibility-deadline.d.ts +16 -0
- package/dist/utils/visibility-deadline.js +16 -0
- package/dist/workflows/maestro-signals.d.ts +0 -13
- package/dist/workflows/maestro-signals.js +6 -14
- package/dist/workflows/maestro.js +27 -32
- package/dist/workflows/scheduler.js +7 -1
- package/dist/workflows/session.js +237 -153
- package/dist/workflows/signals.d.ts +9 -1
- package/dist/workflows/signals.js +8 -6
- package/package.json +1 -6
- package/workflow-bundle.js +478 -225
- package/dist/cli/legacy-migration.d.ts +0 -35
- package/dist/cli/legacy-migration.js +0 -341
- package/dist/client/ensure-conductor-spawned.d.ts +0 -35
- package/dist/client/ensure-conductor-spawned.js +0 -48
- package/dist/tui/App.d.ts +0 -85
- package/dist/tui/App.js +0 -1791
- package/dist/tui/bootstrap-types.d.ts +0 -46
- package/dist/tui/bootstrap-types.js +0 -7
- package/dist/tui/commands.d.ts +0 -71
- package/dist/tui/commands.js +0 -1375
- package/dist/tui/components/ChatView.d.ts +0 -35
- package/dist/tui/components/ChatView.js +0 -54
- package/dist/tui/components/CommandPalette.d.ts +0 -21
- package/dist/tui/components/CommandPalette.js +0 -67
- package/dist/tui/components/ConversationStream.d.ts +0 -114
- package/dist/tui/components/ConversationStream.js +0 -307
- package/dist/tui/components/CreateEnsembleWizard.d.ts +0 -19
- package/dist/tui/components/CreateEnsembleWizard.js +0 -223
- package/dist/tui/components/DestroyConfirmModal.d.ts +0 -17
- package/dist/tui/components/DestroyConfirmModal.js +0 -62
- package/dist/tui/components/ErrorView.d.ts +0 -31
- package/dist/tui/components/ErrorView.js +0 -129
- package/dist/tui/components/HomeView.d.ts +0 -54
- package/dist/tui/components/HomeView.js +0 -306
- package/dist/tui/components/LoadLineupModal.d.ts +0 -18
- package/dist/tui/components/LoadLineupModal.js +0 -79
- package/dist/tui/components/MainView.d.ts +0 -21
- package/dist/tui/components/MainView.js +0 -107
- package/dist/tui/components/NewEnsembleModal.d.ts +0 -9
- package/dist/tui/components/NewEnsembleModal.js +0 -73
- package/dist/tui/components/Picker.d.ts +0 -23
- package/dist/tui/components/Picker.js +0 -70
- package/dist/tui/components/PlayerDetailView.d.ts +0 -26
- package/dist/tui/components/PlayerDetailView.js +0 -118
- package/dist/tui/components/PromptArea.d.ts +0 -50
- package/dist/tui/components/PromptArea.js +0 -303
- package/dist/tui/components/RecruitWizard.d.ts +0 -17
- package/dist/tui/components/RecruitWizard.js +0 -221
- package/dist/tui/components/RestoreConfirmModal.d.ts +0 -18
- package/dist/tui/components/RestoreConfirmModal.js +0 -71
- package/dist/tui/components/ScheduleWizard.d.ts +0 -19
- package/dist/tui/components/ScheduleWizard.js +0 -259
- package/dist/tui/components/Splash.d.ts +0 -23
- package/dist/tui/components/Splash.js +0 -221
- package/dist/tui/components/StatusBar.d.ts +0 -48
- package/dist/tui/components/StatusBar.js +0 -128
- package/dist/tui/components/StatusOverlay.d.ts +0 -15
- package/dist/tui/components/StatusOverlay.js +0 -76
- package/dist/tui/components/TitleBar.d.ts +0 -10
- package/dist/tui/components/TitleBar.js +0 -21
- package/dist/tui/index.d.ts +0 -15
- package/dist/tui/index.js +0 -162
- package/dist/tui/ink-context.d.ts +0 -18
- package/dist/tui/ink-context.js +0 -59
- package/dist/tui/ink-loader.d.ts +0 -26
- package/dist/tui/ink-loader.js +0 -42
- package/dist/tui/removed-commands.d.ts +0 -9
- package/dist/tui/removed-commands.js +0 -22
- package/dist/tui/sse-handler.d.ts +0 -52
- package/dist/tui/sse-handler.js +0 -157
- package/dist/tui/store.d.ts +0 -598
- package/dist/tui/store.js +0 -753
- package/dist/tui/utils/format.d.ts +0 -56
- package/dist/tui/utils/format.js +0 -155
- package/dist/tui/utils/fullscreen.d.ts +0 -23
- package/dist/tui/utils/fullscreen.js +0 -71
- package/dist/tui/utils/history.d.ts +0 -10
- package/dist/tui/utils/history.js +0 -85
- package/dist/tui/utils/platform.d.ts +0 -45
- package/dist/tui/utils/platform.js +0 -258
- package/dist/tui/utils/theme.d.ts +0 -21
- package/dist/tui/utils/theme.js +0 -24
package/dist/tools/stage.js
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildStageTool = buildStageTool;
|
|
4
|
+
exports.buildStageAliasTools = buildStageAliasTools;
|
|
4
5
|
const zod_1 = require("zod");
|
|
5
6
|
const descriptor_1 = require("./descriptor");
|
|
7
|
+
const action_guard_1 = require("./action-guard");
|
|
8
|
+
const stages_1 = require("./stages");
|
|
9
|
+
const cancel_stage_1 = require("./cancel-stage");
|
|
6
10
|
const validation_1 = require("../utils/validation");
|
|
7
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Internal create-only descriptor (the legacy bare-`stage` behaviour). Its
|
|
13
|
+
* `.handler` is reused verbatim by the canonical {@link buildStageTool} under
|
|
14
|
+
* `action="create"`. Not exported — the canonical tool is the public surface.
|
|
15
|
+
*/
|
|
16
|
+
function buildStageCreateTool(handle, getPlayerId) {
|
|
8
17
|
return {
|
|
9
18
|
name: 'stage',
|
|
10
19
|
description: 'Create a pipeline stage tracking N players. When all players report, a completion message is auto-injected. Conductor only.',
|
|
@@ -31,3 +40,78 @@ function buildStageTool(handle, getPlayerId) {
|
|
|
31
40
|
},
|
|
32
41
|
};
|
|
33
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Canonical `stage` tool (#793 merge) — **reused** name, so `action` defaults to
|
|
45
|
+
* `'create'` for backward-compat. Actions: `create | list | cancel` (all CRUD
|
|
46
|
+
* peers on the same StageEntry — see #793 brief §4). Conductor-only (gated in
|
|
47
|
+
* server-tools.ts).
|
|
48
|
+
*
|
|
49
|
+
* The legacy `stages` / `cancel_stage` names stay registered as forwarding
|
|
50
|
+
* aliases ({@link buildStageAliasTools}); there is no alias for `create` — the
|
|
51
|
+
* bare `stage` IS create.
|
|
52
|
+
*/
|
|
53
|
+
function buildStageTool(handle, getPlayerId) {
|
|
54
|
+
const create = buildStageCreateTool(handle, getPlayerId);
|
|
55
|
+
const list = (0, stages_1.buildStagesTool)(handle);
|
|
56
|
+
const cancel = (0, cancel_stage_1.buildCancelStageTool)(handle);
|
|
57
|
+
return {
|
|
58
|
+
name: 'stage',
|
|
59
|
+
description: 'Track a fan-out/fan-in pipeline stage across N players (conductor only). ' +
|
|
60
|
+
'action="create" (default) opens a stage (name + players[, failurePolicy]); ' +
|
|
61
|
+
'action="list" shows all stages and per-player report status; ' +
|
|
62
|
+
'action="cancel" cancels a named stage.',
|
|
63
|
+
params: {
|
|
64
|
+
action: zod_1.z.enum(['create', 'list', 'cancel']).optional().describe('Which stage operation to perform (defaults to "create" when omitted)'),
|
|
65
|
+
// create / cancel:
|
|
66
|
+
name: zod_1.z.string().max(validation_1.STAGE_NAME_MAX).optional().describe('create/cancel: the stage name'),
|
|
67
|
+
// create:
|
|
68
|
+
players: zod_1.z.array(zod_1.z.string().regex(validation_1.PLAYER_NAME_REGEX)).min(1).max(validation_1.STAGE_PLAYERS_MAX).optional().describe('create: player names to track in this stage'),
|
|
69
|
+
failurePolicy: zod_1.z.enum(['halt', 'continue']).optional().describe('create: "halt" (default) fails the stage on a blocker; "continue" waits for all players.'),
|
|
70
|
+
},
|
|
71
|
+
handler: async (args) => {
|
|
72
|
+
const action = args.action ?? 'create';
|
|
73
|
+
switch (action) {
|
|
74
|
+
case 'create': {
|
|
75
|
+
const m = (0, action_guard_1.firstMissing)(args, ['name', 'players']);
|
|
76
|
+
if (m)
|
|
77
|
+
return (0, descriptor_1.fail)(`stage action="create" requires "${m}".`);
|
|
78
|
+
return create.handler(args);
|
|
79
|
+
}
|
|
80
|
+
case 'list':
|
|
81
|
+
return list.handler(args);
|
|
82
|
+
case 'cancel': {
|
|
83
|
+
const m = (0, action_guard_1.firstMissing)(args, ['name']);
|
|
84
|
+
if (m)
|
|
85
|
+
return (0, descriptor_1.fail)(`stage action="cancel" requires "${m}".`);
|
|
86
|
+
return cancel.handler(args);
|
|
87
|
+
}
|
|
88
|
+
default:
|
|
89
|
+
return (0, descriptor_1.fail)(`Unknown stage action: ${String(action)}. Expected create | list | cancel.`);
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Legacy forwarding aliases — `stages` → list, `cancel_stage` → cancel. Each
|
|
96
|
+
* keeps its exact original schema + handler; description gains a deprecation
|
|
97
|
+
* note. No alias for `create` — the bare `stage` IS create. Explicit object
|
|
98
|
+
* literals (see #793 brief §6 drift note).
|
|
99
|
+
*/
|
|
100
|
+
function buildStageAliasTools(handle) {
|
|
101
|
+
const list = (0, stages_1.buildStagesTool)(handle);
|
|
102
|
+
const cancel = (0, cancel_stage_1.buildCancelStageTool)(handle);
|
|
103
|
+
return [
|
|
104
|
+
{
|
|
105
|
+
name: 'stages',
|
|
106
|
+
description: 'DEPRECATED — use `stage` with action="list". ' + list.description,
|
|
107
|
+
params: list.params,
|
|
108
|
+
handler: list.handler,
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: 'cancel_stage',
|
|
112
|
+
description: 'DEPRECATED — use `stage` with action="cancel". ' + cancel.description,
|
|
113
|
+
params: cancel.params,
|
|
114
|
+
handler: cancel.handler,
|
|
115
|
+
},
|
|
116
|
+
];
|
|
117
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Client, WorkflowHandle } from '@temporalio/client';
|
|
2
|
+
import { Config } from '../config';
|
|
3
|
+
import { type TempoToolDescriptor } from './descriptor';
|
|
4
|
+
/**
|
|
5
|
+
* Canonical `state` tool. Dispatches on `action`; per-action required fields are
|
|
6
|
+
* runtime-guarded.
|
|
7
|
+
*/
|
|
8
|
+
export declare function buildStateTool(client: Client, config: Config, handle: WorkflowHandle, getPlayerId: () => string): TempoToolDescriptor;
|
|
9
|
+
/**
|
|
10
|
+
* Legacy forwarding aliases — `save_state` / `fetch_state` / `clear_state`.
|
|
11
|
+
* Each keeps its exact original schema + handler; description gains a
|
|
12
|
+
* deprecation note. Explicit object literals (see §6 drift note).
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildStateAliasTools(client: Client, config: Config, handle: WorkflowHandle, getPlayerId: () => string): TempoToolDescriptor[];
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildStateTool = buildStateTool;
|
|
4
|
+
exports.buildStateAliasTools = buildStateAliasTools;
|
|
5
|
+
/**
|
|
6
|
+
* `state` — canonical multi-action player saveable-state tool (#793 merge).
|
|
7
|
+
*
|
|
8
|
+
* Merges the three legacy tools (`save_state` / `fetch_state` / `clear_state`)
|
|
9
|
+
* into ONE canonical tool with a flat `{ action, ...optional fields }` shape
|
|
10
|
+
* (see docs/design/793-tool-family-merge-brief.md §2). The canonical name is
|
|
11
|
+
* **net-new**, so `action` is REQUIRED.
|
|
12
|
+
*
|
|
13
|
+
* Legacy tools stay registered as forwarding aliases
|
|
14
|
+
* ({@link buildStateAliasTools}); both paths reuse the legacy handler bodies, so
|
|
15
|
+
* behaviour (owner-only write, self-or-peer read, idempotent clear) is identical.
|
|
16
|
+
*/
|
|
17
|
+
const zod_1 = require("zod");
|
|
18
|
+
const descriptor_1 = require("./descriptor");
|
|
19
|
+
const action_guard_1 = require("./action-guard");
|
|
20
|
+
const validation_1 = require("../utils/validation");
|
|
21
|
+
const save_state_1 = require("./save-state");
|
|
22
|
+
const fetch_state_1 = require("./fetch-state");
|
|
23
|
+
const clear_state_1 = require("./clear-state");
|
|
24
|
+
/**
|
|
25
|
+
* Canonical `state` tool. Dispatches on `action`; per-action required fields are
|
|
26
|
+
* runtime-guarded.
|
|
27
|
+
*/
|
|
28
|
+
function buildStateTool(client, config, handle, getPlayerId) {
|
|
29
|
+
const save = (0, save_state_1.buildSaveStateTool)(handle, getPlayerId);
|
|
30
|
+
const fetch = (0, fetch_state_1.buildFetchStateTool)(client, config, handle, getPlayerId);
|
|
31
|
+
const clear = (0, clear_state_1.buildClearStateTool)(handle);
|
|
32
|
+
return {
|
|
33
|
+
name: 'state',
|
|
34
|
+
description: 'Curated per-player state slots that survive restart (you choose what context persists). ' +
|
|
35
|
+
'action="save" writes your own slot (content[, key]); ' +
|
|
36
|
+
'action="fetch" reads a slot for yourself or a peer (key/playerId, defaults to your own "main"); ' +
|
|
37
|
+
'action="clear" empties one of your slots. save/clear are owner-only.',
|
|
38
|
+
params: {
|
|
39
|
+
action: zod_1.z.enum(['save', 'fetch', 'clear']).describe('Which state operation to perform'),
|
|
40
|
+
// save:
|
|
41
|
+
content: zod_1.z.string().min(1).max(validation_1.PLAYER_STATE_CONTENT_MAX).optional().describe('save: the state body to store (≤32 KiB)'),
|
|
42
|
+
// save / fetch / clear:
|
|
43
|
+
key: zod_1.z.string().regex(validation_1.PLAYER_STATE_KEY_REGEX).max(validation_1.PLAYER_STATE_KEY_MAX).optional().describe('Slot key (defaults to "main")'),
|
|
44
|
+
// fetch:
|
|
45
|
+
playerId: zod_1.z.string().max(validation_1.PLAYER_NAME_MAX).optional().describe('fetch: peer to read from (defaults to yourself)'),
|
|
46
|
+
},
|
|
47
|
+
handler: async (args) => {
|
|
48
|
+
const action = args.action;
|
|
49
|
+
switch (action) {
|
|
50
|
+
case 'save': {
|
|
51
|
+
const m = (0, action_guard_1.firstMissing)(args, ['content']);
|
|
52
|
+
if (m)
|
|
53
|
+
return (0, descriptor_1.fail)(`state action="save" requires "${m}".`);
|
|
54
|
+
return save.handler(args);
|
|
55
|
+
}
|
|
56
|
+
case 'fetch':
|
|
57
|
+
return fetch.handler(args);
|
|
58
|
+
case 'clear':
|
|
59
|
+
return clear.handler(args);
|
|
60
|
+
default:
|
|
61
|
+
return (0, descriptor_1.fail)(`Unknown state action: ${String(action)}. Expected save | fetch | clear.`);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Legacy forwarding aliases — `save_state` / `fetch_state` / `clear_state`.
|
|
68
|
+
* Each keeps its exact original schema + handler; description gains a
|
|
69
|
+
* deprecation note. Explicit object literals (see §6 drift note).
|
|
70
|
+
*/
|
|
71
|
+
function buildStateAliasTools(client, config, handle, getPlayerId) {
|
|
72
|
+
const save = (0, save_state_1.buildSaveStateTool)(handle, getPlayerId);
|
|
73
|
+
const fetch = (0, fetch_state_1.buildFetchStateTool)(client, config, handle, getPlayerId);
|
|
74
|
+
const clear = (0, clear_state_1.buildClearStateTool)(handle);
|
|
75
|
+
return [
|
|
76
|
+
{
|
|
77
|
+
name: 'save_state',
|
|
78
|
+
description: 'DEPRECATED — use `state` with action="save". ' + save.description,
|
|
79
|
+
params: save.params,
|
|
80
|
+
handler: save.handler,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: 'fetch_state',
|
|
84
|
+
description: 'DEPRECATED — use `state` with action="fetch". ' + fetch.description,
|
|
85
|
+
params: fetch.params,
|
|
86
|
+
handler: fetch.handler,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'clear_state',
|
|
90
|
+
description: 'DEPRECATED — use `state` with action="clear". ' + clear.description,
|
|
91
|
+
params: clear.params,
|
|
92
|
+
handler: clear.handler,
|
|
93
|
+
},
|
|
94
|
+
];
|
|
95
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -57,6 +57,19 @@ export interface AdapterDescriptor {
|
|
|
57
57
|
blocksOnLLMTurn: boolean;
|
|
58
58
|
/** Heartbeat cadence in milliseconds. Interactive: 60_000; SDK: 30_000. */
|
|
59
59
|
heartbeatMs: number;
|
|
60
|
+
/**
|
|
61
|
+
* #704 — True iff the adapter can park pre-attach on a blocking launch-time
|
|
62
|
+
* dialog (the interactive `claude-code` dev-channels acknowledgment, which
|
|
63
|
+
* requires a human click). When true, the booting attach-timeout watchdog is
|
|
64
|
+
* DISARMED for this adapter: a recruit waiting on a human is not a hang the
|
|
65
|
+
* watchdog should false-kill (an operator-away false-kill is worse than the
|
|
66
|
+
* hang — see docs/design/704-is-demo-companion-brief.md). Headless adapters
|
|
67
|
+
* (no dialog) omit this / set false → the watchdog arms. The property is the
|
|
68
|
+
* contract, not the adapter name: a future interactive adapter inherits the
|
|
69
|
+
* disarm by setting it. Interactive arming returns once #890 dissolves the
|
|
70
|
+
* dialog. Optional; absent ⇒ falsy ⇒ armed.
|
|
71
|
+
*/
|
|
72
|
+
canBlockOnDialog?: boolean;
|
|
60
73
|
}
|
|
61
74
|
/**
|
|
62
75
|
* Reason an attachment detached or was detached. Used for audit and UX messaging.
|
|
@@ -85,7 +98,7 @@ export interface AdapterDescriptor {
|
|
|
85
98
|
* When not opted in, the base class fires the reason as terminal just like any
|
|
86
99
|
* other non-recoverable lease loss.
|
|
87
100
|
*/
|
|
88
|
-
export type DetachReason = 'user-stop' | 'restart' | 'heartbeat-timeout' | 'superseded' | 'agent-exited' | 'spawn-failed' | 'destroy' | 'force' | 'reconnect-exhausted' | 'continued-as-new';
|
|
101
|
+
export type DetachReason = 'user-stop' | 'restart' | 'heartbeat-timeout' | 'superseded' | 'agent-exited' | 'spawn-failed' | 'destroy' | 'force' | 'reconnect-exhausted' | 'continued-as-new' | 'boot-timeout';
|
|
89
102
|
/**
|
|
90
103
|
* Workflow-emitted directive to the attached adapter. Delivered via {@link AttachmentInfo}
|
|
91
104
|
* polling (no reverse-RPC surface in Temporal).
|
|
@@ -178,6 +191,23 @@ export interface SessionMetadata {
|
|
|
178
191
|
playerTypeDescription?: string;
|
|
179
192
|
/** Player ID of who recruited this player. */
|
|
180
193
|
recruitedBy?: string;
|
|
194
|
+
/**
|
|
195
|
+
* #704 — resolved at spawn time from the adapter descriptor's
|
|
196
|
+
* {@link AdapterDescriptor.canBlockOnDialog}. Threaded onto durable metadata
|
|
197
|
+
* (and carried across continueAsNew) so the session workflow can decide
|
|
198
|
+
* whether to ARM the booting attach-timeout watchdog WITHOUT importing the
|
|
199
|
+
* client-side adapter registry (workflows are sandboxed). True ⇒ interactive
|
|
200
|
+
* adapter that can park on a launch dialog ⇒ watchdog DISARMED. Absent/false
|
|
201
|
+
* ⇒ headless ⇒ ARMED.
|
|
202
|
+
*/
|
|
203
|
+
canBlockOnDialog?: boolean;
|
|
204
|
+
/**
|
|
205
|
+
* #704 — optional override (ms) for the booting attach-timeout deadline,
|
|
206
|
+
* resolved from `AGENT_TEMPO_BOOTING_DEADLINE_MS` at spawn time. Workflows
|
|
207
|
+
* can't read process.env, so the override rides durable metadata. Absent ⇒
|
|
208
|
+
* the workflow's 180s default applies.
|
|
209
|
+
*/
|
|
210
|
+
bootingDeadlineMs?: number;
|
|
181
211
|
/** Worktree path if this session was spawned in an isolated worktree. */
|
|
182
212
|
worktreePath?: string;
|
|
183
213
|
/**
|
|
@@ -290,7 +320,7 @@ export interface HostProfile {
|
|
|
290
320
|
*/
|
|
291
321
|
export interface InstanceInfo {
|
|
292
322
|
pid: number;
|
|
293
|
-
/** Parsed from
|
|
323
|
+
/** Parsed from the `agent-tempo:<hostname>:<pid>:<version>` worker identity. */
|
|
294
324
|
version: string;
|
|
295
325
|
/** Raw `poller.identity` as Temporal returned it. */
|
|
296
326
|
identity: string;
|
|
@@ -300,8 +330,6 @@ export interface InstanceInfo {
|
|
|
300
330
|
hasActivityWorker: boolean;
|
|
301
331
|
/** `true` when the per-host activity queue (`agent-tempo-<hostname>`) has a live poller. Controls `HostInfo.recruitReady`. */
|
|
302
332
|
hasHostQueueWorker: boolean;
|
|
303
|
-
/** Set only when identity was in the legacy `<pid>@<hostname>` form. */
|
|
304
|
-
legacy?: true;
|
|
305
333
|
}
|
|
306
334
|
/**
|
|
307
335
|
* Joined liveness + capability view returned by `src/utils/hosts.ts`.
|
|
@@ -346,6 +374,16 @@ export interface PlayerStateEntry {
|
|
|
346
374
|
}
|
|
347
375
|
export interface SessionInput {
|
|
348
376
|
metadata: SessionMetadata;
|
|
377
|
+
/**
|
|
378
|
+
* #786 — 2.0 cutover protocol stamp. Set to `PROTOCOL_VERSION` (2) at every
|
|
379
|
+
* 2.0 start site so it's in history from run 1 and survives `continueAsNew`
|
|
380
|
+
* (carried by the `...input` spread at the CAN site). The workflow ALSO upserts
|
|
381
|
+
* the `AgentTempoProtocol` memo authoritatively from the constant — a 2.0
|
|
382
|
+
* bundle always stamps 2 regardless of input — so a 1.x run (which never sets
|
|
383
|
+
* this) is detectable by the boot guard. Optional only for type back-compat
|
|
384
|
+
* across the cutover; 2.0 always sets it.
|
|
385
|
+
*/
|
|
386
|
+
protocol?: number;
|
|
349
387
|
/** Restored from continue-as-new */
|
|
350
388
|
part?: string;
|
|
351
389
|
/** Restored from continue-as-new (undelivered only) */
|
|
@@ -728,9 +766,10 @@ export interface ResetOutboxEntry extends OutboxEntryBase {
|
|
|
728
766
|
}
|
|
729
767
|
export type OutboxEntry = CueOutboxEntry | RecruitOutboxEntry | ReportOutboxEntry | StopOutboxEntry | ReleaseOutboxEntry | SpawnOutboxEntry | DetachOutboxEntry | DestroyOutboxEntry | RestartOutboxEntry | ResetOutboxEntry;
|
|
730
768
|
/**
|
|
731
|
-
* Pending reset flag set on a session workflow by `deliverReset`,
|
|
732
|
-
* Pi extension
|
|
733
|
-
* after the extension performs the wipe. Single-slot,
|
|
769
|
+
* Pending reset flag set on a session workflow by `deliverReset`, read by the
|
|
770
|
+
* Pi extension off the combined `pendingIntake` query and cleared via
|
|
771
|
+
* `ackResetSignal(resetId)` after the extension performs the wipe. Single-slot,
|
|
772
|
+
* latest-wins.
|
|
734
773
|
*/
|
|
735
774
|
export interface PendingReset {
|
|
736
775
|
/** Correlation id (the originating outbox entry id). Ack clears only on match. */
|
|
@@ -865,6 +904,14 @@ export interface MaestroPlayerInfo {
|
|
|
865
904
|
* surfaces that want to show "last active 12s ago" per player.
|
|
866
905
|
*/
|
|
867
906
|
lastActivityAt?: string;
|
|
907
|
+
/**
|
|
908
|
+
* #886 slice 2 — `true` when this row came from a DEGRADED observation scan
|
|
909
|
+
* (the workflow was listed but its metadata extraction failed, so non-identity
|
|
910
|
+
* fields are best-effort blanks). Surfaces to the dashboard/board so the
|
|
911
|
+
* player renders as "uncertain" rather than vanishing — preventing roster
|
|
912
|
+
* flapping (contra #777). Absent / `false` on healthy rows.
|
|
913
|
+
*/
|
|
914
|
+
degraded?: boolean;
|
|
868
915
|
}
|
|
869
916
|
/** A message relayed through the global Maestro for dashboard visibility. */
|
|
870
917
|
export interface MaestroRelayMessage {
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #786 — the 2.0 cutover BOOT GUARD (the keystone's centerpiece).
|
|
3
|
+
*
|
|
4
|
+
* A 2.0 Temporal worker can never deterministically replay a 1.x-recorded
|
|
5
|
+
* workflow history — the bundle's command stream has diverged, so a replay
|
|
6
|
+
* faults (or, worse, silently corrupts) deep inside a workflow task. The
|
|
7
|
+
* `upgrade-to-2` cutover (#785) exists to destroy every 1.x run before a 2.0
|
|
8
|
+
* daemon ever polls. This guard is the enforcement: a 2.0 daemon REFUSES to
|
|
9
|
+
* register workers if visibility still shows ANY Running agent-tempo workflow
|
|
10
|
+
* that lacks the protocol-2 stamp.
|
|
11
|
+
*
|
|
12
|
+
* **Stamp source of truth:** every 2.0 workflow upserts the
|
|
13
|
+
* `AgentTempoProtocol` memo = {@link PROTOCOL_VERSION} early + unconditionally
|
|
14
|
+
* on every run (incl. continueAsNew successors) — see `src/workflows/*` and
|
|
15
|
+
* `src/constants.ts`. The memo rides the visibility list result directly
|
|
16
|
+
* ({@link getWorkflowProtocol} reads it off the row), so the scan needs NO
|
|
17
|
+
* per-workflow query. A 1.x run never executes that upsert, so its memo is
|
|
18
|
+
* `undefined` → un-stamped → the guard refuses.
|
|
19
|
+
*
|
|
20
|
+
* **FAIL-CLOSED (the #845 partial-scan lesson):** the scan is bounded by the
|
|
21
|
+
* `protocolGuardBoot` visibility budget. A timeout or any scan error is NOT a
|
|
22
|
+
* best-effort partial — it means "couldn't prove the cutover is clean," and an
|
|
23
|
+
* unverified scan must NEVER be read as clean. Both refuse with
|
|
24
|
+
* {@link ProtocolGuardResult.reason} = `'scan-incomplete'`; the daemon retries
|
|
25
|
+
* on the next boot. The cost of a false-refuse (one retry) is trivial next to
|
|
26
|
+
* the cost of a false-proceed (deterministic history corruption).
|
|
27
|
+
*
|
|
28
|
+
* This module is daemon-side (it holds a Temporal client), distinct from the
|
|
29
|
+
* deliberately SDK-free `snapshot-v1.ts` cross-release contract.
|
|
30
|
+
*/
|
|
31
|
+
import type { Client, WorkflowExecutionInfo } from '@temporalio/client';
|
|
32
|
+
/**
|
|
33
|
+
* The four agent-tempo workflow types. A Running workflow of any of these is
|
|
34
|
+
* an agent-tempo coordination workflow that a 2.0 worker would have to replay
|
|
35
|
+
* — so all four must be protocol-2 stamped before boot.
|
|
36
|
+
*/
|
|
37
|
+
export declare const AGENT_TEMPO_WORKFLOW_TYPES: readonly ["agentSessionWorkflow", "agentMaestroWorkflow", "agentSchedulerWorkflow", "agentGlobalMaestroWorkflow"];
|
|
38
|
+
/** A Running workflow that failed the protocol-2 stamp check. */
|
|
39
|
+
export interface ProtocolOffender {
|
|
40
|
+
workflowId: string;
|
|
41
|
+
/** Workflow type name from the visibility row (best-effort). */
|
|
42
|
+
workflowType?: string;
|
|
43
|
+
/** The stamp read from the row's memo — `undefined` for an un-stamped 1.x run. */
|
|
44
|
+
protocol: number | undefined;
|
|
45
|
+
}
|
|
46
|
+
/** Outcome of {@link checkProtocolGuard}. */
|
|
47
|
+
export interface ProtocolGuardResult {
|
|
48
|
+
/** `true` → every Running agent-tempo workflow is protocol-2 stamped (or none exist). */
|
|
49
|
+
ok: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Why boot was refused. Only set when `ok` is `false`.
|
|
52
|
+
* - `'unstamped'` — at least one Running workflow lacks the protocol-2 stamp
|
|
53
|
+
* (a 1.x run survived the cutover). See {@link offenders}.
|
|
54
|
+
* - `'scan-incomplete'` — the visibility scan timed out or errored before
|
|
55
|
+
* completing, so cleanliness could not be PROVEN (fail-closed).
|
|
56
|
+
*/
|
|
57
|
+
reason?: 'unstamped' | 'scan-incomplete';
|
|
58
|
+
/** Number of Running agent-tempo workflows examined before the result. */
|
|
59
|
+
scanned: number;
|
|
60
|
+
/** Un-stamped offenders (only when `reason === 'unstamped'`). */
|
|
61
|
+
offenders: ProtocolOffender[];
|
|
62
|
+
/** Operator-facing explanation (always set on refusal). */
|
|
63
|
+
message?: string;
|
|
64
|
+
}
|
|
65
|
+
/** Injectable seams for {@link checkProtocolGuard} — production callers omit. */
|
|
66
|
+
export interface ProtocolGuardDeps {
|
|
67
|
+
/**
|
|
68
|
+
* Returns the visibility iterable for the guard query. Defaults to
|
|
69
|
+
* `client.workflow.list({ query })`. Tests inject a crafted async iterable
|
|
70
|
+
* of `WorkflowExecutionInfo`-shaped rows (only `workflowId`, `type`, `memo`
|
|
71
|
+
* are read) without a live Temporal connection.
|
|
72
|
+
*/
|
|
73
|
+
listWorkflows?: (query: string) => AsyncIterable<WorkflowExecutionInfo>;
|
|
74
|
+
/** Scan deadline. Default {@link VISIBILITY_DEADLINES_MS.protocolGuardBoot}. */
|
|
75
|
+
deadlineMs?: number;
|
|
76
|
+
/** Injectable clock — forwarded to {@link iterateWithDeadline}. Default `Date.now`. */
|
|
77
|
+
now?: () => number;
|
|
78
|
+
/** Log sink. Default no-op (the daemon caller logs the structured result). */
|
|
79
|
+
log?: (...args: unknown[]) => void;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Build the namespace-scoped visibility query for the guard. The client is
|
|
83
|
+
* already namespace-scoped, so no namespace clause is needed. Exposed for
|
|
84
|
+
* test introspection.
|
|
85
|
+
*/
|
|
86
|
+
export declare function buildProtocolGuardQuery(): string;
|
|
87
|
+
/**
|
|
88
|
+
* Scan every Running agent-tempo workflow and verify each carries the
|
|
89
|
+
* protocol-2 stamp. See the module header for the fail-closed contract.
|
|
90
|
+
*
|
|
91
|
+
* Never throws — every failure (un-stamped run, scan timeout, scan error) is
|
|
92
|
+
* returned as a structured `ok: false` result so the daemon caller decides how
|
|
93
|
+
* to surface it (it prints + `process.exit(1)`).
|
|
94
|
+
*/
|
|
95
|
+
export declare function checkProtocolGuard(client: Client, deps?: ProtocolGuardDeps): Promise<ProtocolGuardResult>;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AGENT_TEMPO_WORKFLOW_TYPES = void 0;
|
|
4
|
+
exports.buildProtocolGuardQuery = buildProtocolGuardQuery;
|
|
5
|
+
exports.checkProtocolGuard = checkProtocolGuard;
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
|
+
const search_attributes_1 = require("../utils/search-attributes");
|
|
8
|
+
const visibility_deadline_1 = require("../utils/visibility-deadline");
|
|
9
|
+
/**
|
|
10
|
+
* The four agent-tempo workflow types. A Running workflow of any of these is
|
|
11
|
+
* an agent-tempo coordination workflow that a 2.0 worker would have to replay
|
|
12
|
+
* — so all four must be protocol-2 stamped before boot.
|
|
13
|
+
*/
|
|
14
|
+
exports.AGENT_TEMPO_WORKFLOW_TYPES = [
|
|
15
|
+
'agentSessionWorkflow',
|
|
16
|
+
'agentMaestroWorkflow',
|
|
17
|
+
'agentSchedulerWorkflow',
|
|
18
|
+
'agentGlobalMaestroWorkflow',
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* Build the namespace-scoped visibility query for the guard. The client is
|
|
22
|
+
* already namespace-scoped, so no namespace clause is needed. Exposed for
|
|
23
|
+
* test introspection.
|
|
24
|
+
*/
|
|
25
|
+
function buildProtocolGuardQuery() {
|
|
26
|
+
const types = exports.AGENT_TEMPO_WORKFLOW_TYPES.map((t) => `"${t}"`).join(', ');
|
|
27
|
+
return `WorkflowType IN (${types}) AND ExecutionStatus = "Running"`;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Scan every Running agent-tempo workflow and verify each carries the
|
|
31
|
+
* protocol-2 stamp. See the module header for the fail-closed contract.
|
|
32
|
+
*
|
|
33
|
+
* Never throws — every failure (un-stamped run, scan timeout, scan error) is
|
|
34
|
+
* returned as a structured `ok: false` result so the daemon caller decides how
|
|
35
|
+
* to surface it (it prints + `process.exit(1)`).
|
|
36
|
+
*/
|
|
37
|
+
async function checkProtocolGuard(client, deps = {}) {
|
|
38
|
+
const log = deps.log ?? (() => { });
|
|
39
|
+
const deadlineMs = deps.deadlineMs ?? visibility_deadline_1.VISIBILITY_DEADLINES_MS.protocolGuardBoot;
|
|
40
|
+
const query = buildProtocolGuardQuery();
|
|
41
|
+
const listWorkflows = deps.listWorkflows ?? ((q) => client.workflow.list({ query: q }));
|
|
42
|
+
const offenders = [];
|
|
43
|
+
let scanned = 0;
|
|
44
|
+
try {
|
|
45
|
+
for await (const wf of (0, visibility_deadline_1.iterateWithDeadline)(listWorkflows(query), deadlineMs, 'protocolGuardBoot', deps.now)) {
|
|
46
|
+
scanned++;
|
|
47
|
+
const protocol = (0, search_attributes_1.getWorkflowProtocol)(wf);
|
|
48
|
+
if (protocol !== constants_1.PROTOCOL_VERSION) {
|
|
49
|
+
offenders.push({
|
|
50
|
+
workflowId: wf.workflowId,
|
|
51
|
+
// `WorkflowExecutionInfo.type` is the workflow type name string.
|
|
52
|
+
workflowType: wf.type,
|
|
53
|
+
protocol,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
// FAIL-CLOSED: a timeout OR any other scan error means we could not prove
|
|
60
|
+
// the namespace is clean. Refuse — never proceed on an unverified scan.
|
|
61
|
+
const kind = (0, visibility_deadline_1.isVisibilityTimeout)(err) ? 'timed out' : 'failed';
|
|
62
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
63
|
+
const message = `agent-tempo 2.0 boot guard could NOT verify a clean cutover — the ` +
|
|
64
|
+
`protocol scan ${kind} after ${scanned} workflow(s): ${detail}. ` +
|
|
65
|
+
`Refusing to boot (fail-closed): a 2.0 worker cannot safely replay a ` +
|
|
66
|
+
`1.x history. Retry once the Temporal namespace is responsive; if this ` +
|
|
67
|
+
`persists, run \`agent-tempo upgrade-to-2\` to complete the cutover.`;
|
|
68
|
+
log(`[boot-guard] scan-incomplete: ${message}`);
|
|
69
|
+
return { ok: false, reason: 'scan-incomplete', scanned, offenders, message };
|
|
70
|
+
}
|
|
71
|
+
if (offenders.length > 0) {
|
|
72
|
+
const sample = offenders
|
|
73
|
+
.slice(0, 5)
|
|
74
|
+
.map((o) => ` - ${o.workflowId} (protocol=${o.protocol ?? 'v1/unset'})`)
|
|
75
|
+
.join('\n');
|
|
76
|
+
const more = offenders.length > 5 ? `\n …and ${offenders.length - 5} more` : '';
|
|
77
|
+
const message = `agent-tempo 2.0 boot guard REFUSED to boot: ${offenders.length} of ` +
|
|
78
|
+
`${scanned} Running agent-tempo workflow(s) are not protocol-${constants_1.PROTOCOL_VERSION} ` +
|
|
79
|
+
`(2.0) stamped — these are pre-cutover 1.x runs that a 2.0 worker cannot ` +
|
|
80
|
+
`safely replay:\n${sample}${more}\n` +
|
|
81
|
+
`Complete the cutover with \`agent-tempo upgrade-to-2\` (it snapshots ` +
|
|
82
|
+
`continuity, then destroys the 1.x runs), then restart the daemon.`;
|
|
83
|
+
log(`[boot-guard] unstamped: refusing (${offenders.length}/${scanned} un-stamped)`);
|
|
84
|
+
return { ok: false, reason: 'unstamped', scanned, offenders, message };
|
|
85
|
+
}
|
|
86
|
+
log(`[boot-guard] clean: ${scanned} Running agent-tempo workflow(s), all protocol-${constants_1.PROTOCOL_VERSION} stamped`);
|
|
87
|
+
return { ok: true, scanned, offenders: [] };
|
|
88
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Client } from '@temporalio/client';
|
|
2
|
+
import type { ScheduleEntry, SessionInput } from '../types';
|
|
3
|
+
import { type UpgradeSnapshot } from './snapshot-v1';
|
|
4
|
+
/** Args shape for the recreated per-ensemble scheduler workflow. Mirrors
|
|
5
|
+
* `SchedulerInput` (declared in `../workflows/scheduler`, which we deliberately
|
|
6
|
+
* do NOT import here — it pulls `@temporalio/workflow` into the Node reader). */
|
|
7
|
+
interface SchedulerStartArgs {
|
|
8
|
+
ensemble: string;
|
|
9
|
+
entries: ScheduleEntry[];
|
|
10
|
+
}
|
|
11
|
+
/** Filename the consumed snapshot is archived to on success. */
|
|
12
|
+
export declare const CONSUMED_SNAPSHOT_FILENAME = "upgrade-snapshot-v1.consumed.json";
|
|
13
|
+
/** A single workflow to recreate — pure plan output (no Temporal I/O). */
|
|
14
|
+
export interface RecreateSpec {
|
|
15
|
+
workflowId: string;
|
|
16
|
+
workflowType: 'agentSessionWorkflow' | 'agentMaestroWorkflow' | 'agentSchedulerWorkflow';
|
|
17
|
+
ensemble: string;
|
|
18
|
+
/** Present for session workflows. */
|
|
19
|
+
playerId?: string;
|
|
20
|
+
/** `args[0]` for the workflow start call. */
|
|
21
|
+
args: [SessionInput] | [{
|
|
22
|
+
ensemble: string;
|
|
23
|
+
}] | [SchedulerStartArgs];
|
|
24
|
+
searchAttributes: Record<string, string[]>;
|
|
25
|
+
memo: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
/** An undelivered inbox cue, surfaced for operator review (never redelivered). */
|
|
28
|
+
export interface UndeliveredCueReview {
|
|
29
|
+
ensemble: string;
|
|
30
|
+
playerId: string;
|
|
31
|
+
from: string;
|
|
32
|
+
text: string;
|
|
33
|
+
timestamp: string;
|
|
34
|
+
}
|
|
35
|
+
/** Result of {@link runFromUpgrade}. */
|
|
36
|
+
export interface FromUpgradeResult {
|
|
37
|
+
/** `true` when a snapshot existed AND every workflow recreated cleanly. */
|
|
38
|
+
ok: boolean;
|
|
39
|
+
/** `false` when no `upgrade-snapshot-v1.json` was present (nothing to do). */
|
|
40
|
+
snapshotFound: boolean;
|
|
41
|
+
ensemblesRecreated: number;
|
|
42
|
+
workflowsCreated: number;
|
|
43
|
+
/** Per-workflow failures (empty on full success). */
|
|
44
|
+
failures: {
|
|
45
|
+
workflowId: string;
|
|
46
|
+
error: string;
|
|
47
|
+
}[];
|
|
48
|
+
/** Undelivered cues for operator review (surfaced, NOT redelivered). */
|
|
49
|
+
undeliveredCues: UndeliveredCueReview[];
|
|
50
|
+
/** `true` when the snapshot was archived to `.consumed.json` (success only). */
|
|
51
|
+
archived: boolean;
|
|
52
|
+
archivePath?: string;
|
|
53
|
+
}
|
|
54
|
+
/** Plan inputs — the Temporal coordinates the recreated workflows need. */
|
|
55
|
+
export interface PlanRecreationOpts {
|
|
56
|
+
hostname: string;
|
|
57
|
+
taskQueue: string;
|
|
58
|
+
temporalAddress: string;
|
|
59
|
+
temporalNamespace: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Pure planner: turn a snapshot into the list of protocol-2 workflows to
|
|
63
|
+
* recreate. One `agentMaestroWorkflow` per ensemble (so the ensemble is
|
|
64
|
+
* coordinated + discoverable) plus one `agentSessionWorkflow` per roster player
|
|
65
|
+
* (conductor via {@link conductorWorkflowId}, others via
|
|
66
|
+
* {@link sessionWorkflowId}). Structural essentials only — see the module
|
|
67
|
+
* header. Exported so the recreation set is unit-testable without Temporal.
|
|
68
|
+
*/
|
|
69
|
+
export declare function planRecreation(snapshot: UpgradeSnapshot, opts: PlanRecreationOpts): RecreateSpec[];
|
|
70
|
+
/** Collect every undelivered cue across the snapshot (review only). */
|
|
71
|
+
export declare function collectUndeliveredCues(snapshot: UpgradeSnapshot): UndeliveredCueReview[];
|
|
72
|
+
/**
|
|
73
|
+
* Archive the consumed snapshot: `upgrade-snapshot-v1.json` →
|
|
74
|
+
* `upgrade-snapshot-v1.consumed.json`. Overwrites a prior `.consumed.json`
|
|
75
|
+
* from an earlier run (rename is atomic on the same volume). Returns the
|
|
76
|
+
* archive path.
|
|
77
|
+
*/
|
|
78
|
+
export declare function archiveSnapshot(home: string): string;
|
|
79
|
+
/**
|
|
80
|
+
* Recreate protocol-2 workflows from the on-disk upgrade snapshot.
|
|
81
|
+
*
|
|
82
|
+
* Returns a structured result; never throws on a per-workflow failure (those
|
|
83
|
+
* are collected in {@link FromUpgradeResult.failures}). A malformed snapshot
|
|
84
|
+
* DOES throw (via `readSnapshot` → `SnapshotValidationError`) — a corrupt
|
|
85
|
+
* continuity file is a loud failure, never a silent skip.
|
|
86
|
+
*/
|
|
87
|
+
export declare function runFromUpgrade(client: Client, opts: {
|
|
88
|
+
home: string;
|
|
89
|
+
taskQueue: string;
|
|
90
|
+
temporalAddress: string;
|
|
91
|
+
temporalNamespace: string;
|
|
92
|
+
hostname?: string;
|
|
93
|
+
log?: (...args: unknown[]) => void;
|
|
94
|
+
}): Promise<FromUpgradeResult>;
|
|
95
|
+
export {};
|