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.
Files changed (171) hide show
  1. package/CLAUDE.md +10 -13
  2. package/README.md +21 -15
  3. package/dashboard/dist/assets/index-BbR7zIdK.js.map +1 -1
  4. package/dashboard/package.json +1 -1
  5. package/dist/activities/hard-terminate.d.ts +2 -2
  6. package/dist/activities/hard-terminate.js +3 -9
  7. package/dist/activities/maestro.d.ts +8 -13
  8. package/dist/activities/maestro.js +3 -10
  9. package/dist/activities/outbox.js +16 -2
  10. package/dist/activities/resolve.d.ts +18 -7
  11. package/dist/activities/resolve.js +58 -46
  12. package/dist/adapters/base.js +3 -0
  13. package/dist/adapters/claude-code/adapter.js +7 -0
  14. package/dist/cli/command-center-command.js +15 -1
  15. package/dist/cli/commands.d.ts +8 -0
  16. package/dist/cli/commands.js +79 -11
  17. package/dist/cli/daemon-command.js +19 -33
  18. package/dist/cli/help-text.js +9 -7
  19. package/dist/cli/home-command.d.ts +26 -0
  20. package/dist/cli/home-command.js +156 -0
  21. package/dist/cli/removed-verbs.d.ts +0 -4
  22. package/dist/cli/removed-verbs.js +23 -12
  23. package/dist/cli/sa-preflight.d.ts +0 -14
  24. package/dist/cli/sa-preflight.js +1 -17
  25. package/dist/cli/startup.d.ts +1 -10
  26. package/dist/cli/startup.js +0 -40
  27. package/dist/cli.js +34 -80
  28. package/dist/client/core.js +13 -15
  29. package/dist/client/index.d.ts +2 -1
  30. package/dist/client/interface.d.ts +5 -14
  31. package/dist/client/with-spawn.d.ts +9 -4
  32. package/dist/client/with-spawn.js +7 -10
  33. package/dist/config.d.ts +14 -13
  34. package/dist/config.js +14 -0
  35. package/dist/constants.d.ts +50 -0
  36. package/dist/constants.js +60 -1
  37. package/dist/daemon.js +81 -0
  38. package/dist/http/auth.d.ts +3 -21
  39. package/dist/http/auth.js +10 -31
  40. package/dist/http/event-types.d.ts +38 -4
  41. package/dist/http/orphans.d.ts +3 -3
  42. package/dist/http/orphans.js +3 -3
  43. package/dist/http/server.d.ts +0 -5
  44. package/dist/http/server.js +79 -29
  45. package/dist/http/snapshot.js +3 -0
  46. package/dist/http/writes.d.ts +1 -1
  47. package/dist/http/writes.js +25 -2
  48. package/dist/observability/nondeterminism-alarm.d.ts +113 -0
  49. package/dist/observability/nondeterminism-alarm.js +162 -0
  50. package/dist/palette/index.d.ts +6 -7
  51. package/dist/palette/index.js +6 -7
  52. package/dist/pi/mission-control/actions.d.ts +67 -1
  53. package/dist/pi/mission-control/actions.js +61 -0
  54. package/dist/pi/mission-control/extension.d.ts +77 -0
  55. package/dist/pi/mission-control/extension.js +171 -0
  56. package/dist/pi/workflow-client.d.ts +14 -16
  57. package/dist/pi/workflow-client.js +18 -44
  58. package/dist/server-tools.js +30 -29
  59. package/dist/server.js +42 -0
  60. package/dist/tools/action-guard.d.ts +23 -0
  61. package/dist/tools/action-guard.js +33 -0
  62. package/dist/tools/coat-check.d.ts +20 -0
  63. package/dist/tools/coat-check.js +129 -0
  64. package/dist/tools/gate.d.ts +13 -0
  65. package/dist/tools/gate.js +88 -0
  66. package/dist/tools/schedule.d.ts +18 -0
  67. package/dist/tools/schedule.js +93 -1
  68. package/dist/tools/stage.d.ts +17 -0
  69. package/dist/tools/stage.js +85 -1
  70. package/dist/tools/state.d.ts +14 -0
  71. package/dist/tools/state.js +95 -0
  72. package/dist/types.d.ts +54 -7
  73. package/dist/upgrade/boot-guard.d.ts +95 -0
  74. package/dist/upgrade/boot-guard.js +88 -0
  75. package/dist/upgrade/from-upgrade.d.ts +95 -0
  76. package/dist/upgrade/from-upgrade.js +330 -0
  77. package/dist/upgrade/phase-engine.js +4 -1
  78. package/dist/utils/duration.d.ts +3 -6
  79. package/dist/utils/duration.js +3 -6
  80. package/dist/utils/format-hosts.d.ts +1 -1
  81. package/dist/utils/format-hosts.js +0 -2
  82. package/dist/utils/grpc-shutdown-guard.js +0 -4
  83. package/dist/utils/hosts.d.ts +4 -10
  84. package/dist/utils/hosts.js +12 -28
  85. package/dist/utils/orphan-guard.d.ts +37 -0
  86. package/dist/utils/orphan-guard.js +26 -0
  87. package/dist/utils/search-attributes.d.ts +28 -18
  88. package/dist/utils/search-attributes.js +48 -18
  89. package/dist/utils/visibility-deadline.d.ts +16 -0
  90. package/dist/utils/visibility-deadline.js +16 -0
  91. package/dist/workflows/maestro-signals.d.ts +0 -13
  92. package/dist/workflows/maestro-signals.js +6 -14
  93. package/dist/workflows/maestro.js +27 -32
  94. package/dist/workflows/scheduler.js +7 -1
  95. package/dist/workflows/session.js +237 -153
  96. package/dist/workflows/signals.d.ts +9 -1
  97. package/dist/workflows/signals.js +8 -6
  98. package/package.json +1 -6
  99. package/workflow-bundle.js +478 -225
  100. package/dist/cli/legacy-migration.d.ts +0 -35
  101. package/dist/cli/legacy-migration.js +0 -341
  102. package/dist/client/ensure-conductor-spawned.d.ts +0 -35
  103. package/dist/client/ensure-conductor-spawned.js +0 -48
  104. package/dist/tui/App.d.ts +0 -85
  105. package/dist/tui/App.js +0 -1791
  106. package/dist/tui/bootstrap-types.d.ts +0 -46
  107. package/dist/tui/bootstrap-types.js +0 -7
  108. package/dist/tui/commands.d.ts +0 -71
  109. package/dist/tui/commands.js +0 -1375
  110. package/dist/tui/components/ChatView.d.ts +0 -35
  111. package/dist/tui/components/ChatView.js +0 -54
  112. package/dist/tui/components/CommandPalette.d.ts +0 -21
  113. package/dist/tui/components/CommandPalette.js +0 -67
  114. package/dist/tui/components/ConversationStream.d.ts +0 -114
  115. package/dist/tui/components/ConversationStream.js +0 -307
  116. package/dist/tui/components/CreateEnsembleWizard.d.ts +0 -19
  117. package/dist/tui/components/CreateEnsembleWizard.js +0 -223
  118. package/dist/tui/components/DestroyConfirmModal.d.ts +0 -17
  119. package/dist/tui/components/DestroyConfirmModal.js +0 -62
  120. package/dist/tui/components/ErrorView.d.ts +0 -31
  121. package/dist/tui/components/ErrorView.js +0 -129
  122. package/dist/tui/components/HomeView.d.ts +0 -54
  123. package/dist/tui/components/HomeView.js +0 -306
  124. package/dist/tui/components/LoadLineupModal.d.ts +0 -18
  125. package/dist/tui/components/LoadLineupModal.js +0 -79
  126. package/dist/tui/components/MainView.d.ts +0 -21
  127. package/dist/tui/components/MainView.js +0 -107
  128. package/dist/tui/components/NewEnsembleModal.d.ts +0 -9
  129. package/dist/tui/components/NewEnsembleModal.js +0 -73
  130. package/dist/tui/components/Picker.d.ts +0 -23
  131. package/dist/tui/components/Picker.js +0 -70
  132. package/dist/tui/components/PlayerDetailView.d.ts +0 -26
  133. package/dist/tui/components/PlayerDetailView.js +0 -118
  134. package/dist/tui/components/PromptArea.d.ts +0 -50
  135. package/dist/tui/components/PromptArea.js +0 -303
  136. package/dist/tui/components/RecruitWizard.d.ts +0 -17
  137. package/dist/tui/components/RecruitWizard.js +0 -221
  138. package/dist/tui/components/RestoreConfirmModal.d.ts +0 -18
  139. package/dist/tui/components/RestoreConfirmModal.js +0 -71
  140. package/dist/tui/components/ScheduleWizard.d.ts +0 -19
  141. package/dist/tui/components/ScheduleWizard.js +0 -259
  142. package/dist/tui/components/Splash.d.ts +0 -23
  143. package/dist/tui/components/Splash.js +0 -221
  144. package/dist/tui/components/StatusBar.d.ts +0 -48
  145. package/dist/tui/components/StatusBar.js +0 -128
  146. package/dist/tui/components/StatusOverlay.d.ts +0 -15
  147. package/dist/tui/components/StatusOverlay.js +0 -76
  148. package/dist/tui/components/TitleBar.d.ts +0 -10
  149. package/dist/tui/components/TitleBar.js +0 -21
  150. package/dist/tui/index.d.ts +0 -15
  151. package/dist/tui/index.js +0 -162
  152. package/dist/tui/ink-context.d.ts +0 -18
  153. package/dist/tui/ink-context.js +0 -59
  154. package/dist/tui/ink-loader.d.ts +0 -26
  155. package/dist/tui/ink-loader.js +0 -42
  156. package/dist/tui/removed-commands.d.ts +0 -9
  157. package/dist/tui/removed-commands.js +0 -22
  158. package/dist/tui/sse-handler.d.ts +0 -52
  159. package/dist/tui/sse-handler.js +0 -157
  160. package/dist/tui/store.d.ts +0 -598
  161. package/dist/tui/store.js +0 -753
  162. package/dist/tui/utils/format.d.ts +0 -56
  163. package/dist/tui/utils/format.js +0 -155
  164. package/dist/tui/utils/fullscreen.d.ts +0 -23
  165. package/dist/tui/utils/fullscreen.js +0 -71
  166. package/dist/tui/utils/history.d.ts +0 -10
  167. package/dist/tui/utils/history.js +0 -85
  168. package/dist/tui/utils/platform.d.ts +0 -45
  169. package/dist/tui/utils/platform.js +0 -258
  170. package/dist/tui/utils/theme.d.ts +0 -21
  171. package/dist/tui/utils/theme.js +0 -24
@@ -61,14 +61,15 @@ function printHelp() {
61
61
  ${out.bold('agent-tempo')} — Multi-session Claude Code coordination via Temporal
62
62
 
63
63
  ${out.bold('Getting started:')}
64
- ${out.cyan('agent-tempo up')} Start infrastructure, then launch the TUI with ${out.dim('agent-tempo')}
64
+ ${out.cyan('agent-tempo up')} Start infrastructure, then run ${out.dim('agent-tempo')} for status + operator hints
65
65
 
66
66
  ${out.bold('Usage:')}
67
- agent-tempo Launch the TUI (auto-provisions + opens home view)
68
- agent-tempo <ensemble> Launch the TUI directly into an ensemble view
67
+ agent-tempo Auto-provision, show status, and print operator hints
68
+ agent-tempo <ensemble> Same, scoped to one ensemble's status
69
69
  agent-tempo <command> [options]
70
70
 
71
71
  ${out.bold('Commands:')}
72
+ ${out.cyan('home')} Bare landing (default): auto-provision, show status, print operator hints
72
73
  ${out.cyan('up')} Start infrastructure only — Temporal, daemon, MCP registration
73
74
  ${out.cyan('down')} Stop infrastructure; workflows stay parked for the next ${out.dim('up')}
74
75
  ${out.cyan('down --destroy [-y]')} Terminate every workflow across every ensemble, then stop infrastructure
@@ -93,12 +94,13 @@ ${out.bold('Commands:')}
93
94
  ${out.cyan('init')} Register MCP server globally (or --project for .mcp.json)
94
95
  ${out.cyan('install-pi')} Install the Pi extensions into Pi settings (or --project for .pi/settings.json)
95
96
  ${out.cyan('preflight')} Run preflight checks only
97
+ ${out.cyan('version')} Print the installed version (alias: --version, -v)
96
98
  ${out.cyan('help')} Show this help message
97
99
 
98
- ${out.bold('Removed — use the TUI:')}
99
- ${out.dim('stop / restart / detach / migrate')} → ${out.dim('/destroy · /restart · /shutdown')}
100
- ${out.dim('conduct / start / recruit / disband')} → ${out.dim('launch `agent-tempo` · /recruit · /destroy')}
101
- ${out.dim('resume')} → ${out.dim('/play')}
100
+ ${out.bold('Removed — use the command-center board')} ${out.dim('(agent-tempo command-center)')}:
101
+ ${out.dim('stop / restart / detach / migrate')} → ${out.dim('/destroy · /restart · /shutdown · /migrate')}
102
+ ${out.dim('conduct / start / recruit / disband')} → ${out.dim('agent-tempo up · /recruit · /destroy')}
103
+ ${out.dim('resume / tui')} → ${out.dim('/play · run `agent-tempo` (status) or `command-center` (board)')}
102
104
  See https://github.com/vinceblank/agent-tempo/issues/285 for the full migration table.
103
105
 
104
106
  ${out.bold('Connection options (all commands):')}
@@ -0,0 +1,26 @@
1
+ import type { BootstrapResult } from './startup';
2
+ export interface RenderHomeOpts {
3
+ /** Whether the Pi operator seat is installed (drives the command-center hint). */
4
+ piAvailable: boolean;
5
+ /** This binary's version (header line). */
6
+ version: string;
7
+ /** Hostname for the header (injectable for tests). */
8
+ hostname?: string;
9
+ }
10
+ /**
11
+ * Pure renderer: BootstrapResult → status lines + next-step hints. `result`
12
+ * may be undefined when bootstrap threw outside its step boundaries — the
13
+ * home still renders with a degraded note (mirrors the old TUI's tolerance).
14
+ */
15
+ export declare function renderHome(result: BootstrapResult | undefined, opts: RenderHomeOpts): string[];
16
+ /**
17
+ * The `home` (bare-command) handler: bootstrap → render → exit. Bootstrap is
18
+ * best-effort exactly as the TUI treated it — a throw outside step
19
+ * boundaries degrades to the no-result rendering, never a crash.
20
+ */
21
+ export declare function runHome(opts: {
22
+ /** `null` = bootstrap skipped (`--skip-preflight`) — render the degraded home. */
23
+ bootstrap: (() => Promise<BootstrapResult>) | null;
24
+ piAvailable: boolean;
25
+ version: string;
26
+ }): Promise<void>;
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.renderHome = renderHome;
37
+ exports.runHome = runHome;
38
+ /**
39
+ * Bare-command home (E.8, #789) — what `agent-tempo` with no verb does now
40
+ * that the Ink TUI is gone: run the #289 six-step auto-provisioning
41
+ * bootstrap, then print a STATUS snapshot + contextual next-step hints and
42
+ * exit. No alternate screen, no event loop — the live operator surfaces are
43
+ * mission-control (`agent-tempo command-center`, when the Pi seat is
44
+ * available) and the zero-dependency web dashboard.
45
+ *
46
+ * `renderHome` is PURE (BootstrapResult + flags → lines) so the hint logic
47
+ * unit-tests without a daemon, npm, or Pi install.
48
+ */
49
+ const os = __importStar(require("os"));
50
+ const out = __importStar(require("./output"));
51
+ const probe_1 = require("../pi/probe");
52
+ /** Friendly labels for the bootstrap steps. */
53
+ const STEP_LABELS = {
54
+ preflight: 'preflight',
55
+ mcpConfig: 'MCP registration',
56
+ temporalReach: 'Temporal reachability',
57
+ searchAttrs: 'search attributes',
58
+ daemonBoot: 'daemon',
59
+ badgeCollection: 'badges',
60
+ };
61
+ const STEP_GLYPH = {
62
+ ok: '✓',
63
+ skipped: '·',
64
+ 'action-taken': '+',
65
+ failed: '✗',
66
+ };
67
+ /**
68
+ * Pure renderer: BootstrapResult → status lines + next-step hints. `result`
69
+ * may be undefined when bootstrap threw outside its step boundaries — the
70
+ * home still renders with a degraded note (mirrors the old TUI's tolerance).
71
+ */
72
+ function renderHome(result, opts) {
73
+ const lines = [];
74
+ const host = opts.hostname ?? os.hostname();
75
+ lines.push(`agent-tempo v${opts.version} — ${host}`);
76
+ lines.push('');
77
+ // ── Bootstrap status (one line per non-quiet step) ──
78
+ if (result) {
79
+ const parts = [];
80
+ for (const [step, outcome] of Object.entries(result.steps)) {
81
+ if (outcome.status === 'skipped' || outcome.status === 'ok')
82
+ continue; // quiet steady state
83
+ parts.push(`${STEP_GLYPH[outcome.status]} ${STEP_LABELS[step]}${outcome.detail ? ` (${outcome.detail})` : ''}`);
84
+ }
85
+ lines.push(parts.length === 0
86
+ ? `bootstrap ✓ all steps healthy (${result.durationMs}ms)`
87
+ : `bootstrap: ${parts.join(' · ')}`);
88
+ // ── Badges ──
89
+ const b = result.badges;
90
+ if (b.orphanCount > 0) {
91
+ lines.push(`⚠ ${b.orphanCount} orphaned session${b.orphanCount === 1 ? '' : 's'} on this host — \`agent-tempo restore\` to re-attach`);
92
+ }
93
+ if (b.daemonLogErrors) {
94
+ lines.push(`⚠ ${b.daemonLogErrors.count} recent daemon-log error${b.daemonLogErrors.count === 1 ? '' : 's'} — see ${b.daemonLogErrors.logPath}`);
95
+ }
96
+ if (b.outdatedVersion) {
97
+ lines.push(`↑ v${b.outdatedVersion.latest} available (${b.outdatedVersion.severity}) — \`agent-tempo upgrade\``);
98
+ }
99
+ // ── Ensembles ──
100
+ lines.push('');
101
+ if (result.ensembles.length === 0) {
102
+ lines.push('No ensembles running.');
103
+ }
104
+ else {
105
+ lines.push(`Ensembles (${result.ensembles.length}):`);
106
+ for (const e of result.ensembles) {
107
+ const state = e.state ? ` — ${e.state}` : '';
108
+ lines.push(` ${e.name}: ${e.playerCount} player${e.playerCount === 1 ? '' : 's'}${e.hasConductor ? '' : ', no conductor'}${state}`);
109
+ }
110
+ }
111
+ }
112
+ else {
113
+ lines.push('bootstrap unavailable — run `agent-tempo daemon status` to diagnose.');
114
+ lines.push('');
115
+ }
116
+ // ── Next steps (contextual) ──
117
+ lines.push('');
118
+ lines.push('Next steps:');
119
+ const hasEnsembles = (result?.ensembles.length ?? 0) > 0;
120
+ if (!hasEnsembles) {
121
+ lines.push(' agent-tempo up start an ensemble here (--lineup <name> for a preset)');
122
+ }
123
+ if (opts.piAvailable) {
124
+ const desc = hasEnsembles
125
+ ? 'live board + operator seat (Pi)'
126
+ : 'operator seat once an ensemble is up (Pi)';
127
+ lines.push(` agent-tempo command-center ${desc}`);
128
+ }
129
+ lines.push(' agent-tempo dashboard web dashboard (zero-dependency fallback)');
130
+ if (hasEnsembles) {
131
+ lines.push(' agent-tempo status <ensemble> one-shot ensemble detail');
132
+ }
133
+ if (!opts.piAvailable) {
134
+ lines.push(` npm install -g ${probe_1.PI_PACKAGE} unlock the command-center seat (Node ≥ ${probe_1.PI_NODE_FLOOR})`);
135
+ }
136
+ return lines;
137
+ }
138
+ /**
139
+ * The `home` (bare-command) handler: bootstrap → render → exit. Bootstrap is
140
+ * best-effort exactly as the TUI treated it — a throw outside step
141
+ * boundaries degrades to the no-result rendering, never a crash.
142
+ */
143
+ async function runHome(opts) {
144
+ let result;
145
+ if (opts.bootstrap) {
146
+ try {
147
+ result = await opts.bootstrap();
148
+ }
149
+ catch (err) {
150
+ out.warn(`Bootstrap hit an unexpected error: ${err instanceof Error ? err.message : String(err)}`);
151
+ }
152
+ }
153
+ for (const line of renderHome(result, { piAvailable: opts.piAvailable, version: opts.version })) {
154
+ out.log(line);
155
+ }
156
+ }
@@ -1,7 +1,3 @@
1
- /**
2
- * Short hints completing "Use the TUI: agent-tempo → …". Keys are the
3
- * removed CLI verbs; values name the TUI equivalent.
4
- */
5
1
  export declare const REMOVED_VERBS: Record<string, string>;
6
2
  /** Format the error message for a single removed verb. */
7
3
  export declare function removedVerbMessage(verb: string): string;
@@ -53,24 +53,35 @@ exports.printRemovedVerbMessage = printRemovedVerbMessage;
53
53
  */
54
54
  const out = __importStar(require("./output"));
55
55
  /**
56
- * Short hints completing "Use the TUI: agent-tempo …". Keys are the
57
- * removed CLI verbs; values name the TUI equivalent.
56
+ * Hints for removed CLI verbs. Keys are the removed verbs; values complete
57
+ * the "Use …" sentence in {@link removedVerbMessage}.
58
+ *
59
+ * #789 (E.8): the Ink TUI is gone, so the #288-era "Use the TUI: …" hints
60
+ * were rewritten against the surviving operator surfaces — mission-control
61
+ * (`agent-tempo command-center`, slash commands) with the web dashboard as
62
+ * the zero-dependency fallback. Per the v2 scoping plan (§C.3), this WHOLE
63
+ * file — every entry including the new `tui` one — ships for one 2.0
64
+ * release as migration hints and is then deleted as a unit.
58
65
  */
66
+ const CC = 'the command-center: agent-tempo command-center → ';
59
67
  exports.REMOVED_VERBS = {
60
- stop: '/destroy',
61
- conduct: 'launch directly (the TUI auto-provisions the conductor)',
62
- start: '/recruit <name>',
63
- disband: '/destroy',
64
- detach: '/shutdown (ensemble-wide) detach is no longer a user-facing verb',
65
- restart: '/restart <player>',
66
- recruit: '/recruit <name>',
67
- migrate: '/migrate <player> <host>',
68
- resume: '/play',
68
+ stop: `${CC}/destroy <player>`,
69
+ conduct: '`agent-tempo up` (auto-provisions the conductor), then `agent-tempo command-center`',
70
+ start: `${CC}/recruit <name>`,
71
+ disband: `${CC}/destroy <player> (or /ensemble-down)`,
72
+ detach: `${CC}/ensemble-down (detach is no longer a user-facing verb)`,
73
+ restart: `${CC}/restart <player>`,
74
+ recruit: `${CC}/recruit <name>`,
75
+ migrate: `${CC}/migrate <player> <host>`,
76
+ resume: `${CC}/play`,
77
+ // #789 — the TUI launch verb itself. Bare `agent-tempo` is now the status
78
+ // home; the live surfaces are the command-center and the web dashboard.
79
+ tui: 'bare `agent-tempo` for status, `agent-tempo command-center` for the live board (Pi seat), or `agent-tempo dashboard`',
69
80
  };
70
81
  /** Format the error message for a single removed verb. */
71
82
  function removedVerbMessage(verb) {
72
83
  const hint = exports.REMOVED_VERBS[verb];
73
- return `"${verb}" is no longer a CLI verb. Use the TUI: agent-tempo → ${hint}. See https://github.com/vinceblank/agent-tempo/issues/285 for details.`;
84
+ return `"${verb}" is no longer a CLI verb. Use ${hint}. See https://github.com/vinceblank/agent-tempo/issues/285 for details.`;
74
85
  }
75
86
  /** Print the removed-verb error to stderr via the shared output helpers. */
76
87
  function printRemovedVerbMessage(verb) {
@@ -15,20 +15,6 @@ export declare const REQUIRED_SEARCH_ATTRIBUTES: ReadonlyArray<{
15
15
  name: string;
16
16
  type: 'Keyword' | 'Bool';
17
17
  }>;
18
- /**
19
- * T0.5 (#747) — legacy attributes that pre-v1.8 deployments registered and
20
- * pre-v1.8 workflow runs still carry. NEVER auto-unregistered (dropping a
21
- * search attribute is a privileged, operator-only action — see
22
- * `docs/ops/sa-diet-migration.md`); fresh namespaces simply don't register
23
- * them. Kept here so tooling can name them in diagnostics and so the
24
- * dual-read fallback window (memo preferred, SA fallback in
25
- * `utils/search-attributes.ts`) is documented next to the list it falls
26
- * back to. Dual-read fallback may be removed at the next major.
27
- */
28
- export declare const LEGACY_SEARCH_ATTRIBUTES: ReadonlyArray<{
29
- name: string;
30
- type: 'Keyword' | 'Bool';
31
- }>;
32
18
  export interface SearchAttributePreflightOpts {
33
19
  temporalAddress: string;
34
20
  temporalNamespace: string;
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.LEGACY_SEARCH_ATTRIBUTES = exports.REQUIRED_SEARCH_ATTRIBUTES = void 0;
36
+ exports.REQUIRED_SEARCH_ATTRIBUTES = void 0;
37
37
  exports.defaultProbeRegisteredAttributes = defaultProbeRegisteredAttributes;
38
38
  exports.isTemporalCloud = isTemporalCloud;
39
39
  exports.sdkProbeRegisteredAttributes = sdkProbeRegisteredAttributes;
@@ -97,22 +97,6 @@ exports.REQUIRED_SEARCH_ATTRIBUTES = Object.freeze([
97
97
  { name: 'AgentTempoAttachedHost', type: 'Keyword' },
98
98
  { name: 'AgentTempoAttachmentState', type: 'Keyword' },
99
99
  ]);
100
- /**
101
- * T0.5 (#747) — legacy attributes that pre-v1.8 deployments registered and
102
- * pre-v1.8 workflow runs still carry. NEVER auto-unregistered (dropping a
103
- * search attribute is a privileged, operator-only action — see
104
- * `docs/ops/sa-diet-migration.md`); fresh namespaces simply don't register
105
- * them. Kept here so tooling can name them in diagnostics and so the
106
- * dual-read fallback window (memo preferred, SA fallback in
107
- * `utils/search-attributes.ts`) is documented next to the list it falls
108
- * back to. Dual-read fallback may be removed at the next major.
109
- */
110
- exports.LEGACY_SEARCH_ATTRIBUTES = Object.freeze([
111
- { name: 'AgentTempoGitRoot', type: 'Keyword' },
112
- { name: 'AgentTempoPlayerType', type: 'Keyword' },
113
- { name: 'AgentTempoIsConductor', type: 'Bool' },
114
- { name: 'AgentTempoAttachmentId', type: 'Keyword' },
115
- ]);
116
100
  /**
117
101
  * Default probe — shells out to `temporal operator search-attribute list`.
118
102
  * Returns an empty set on any error so callers fall through to the
@@ -1,6 +1,6 @@
1
1
  import { Config } from '../config';
2
2
  import type { EnsembleSummary } from '../client/interface';
3
- export type StepName = 'legacyHomeMigration' | 'preflight' | 'mcpConfig' | 'temporalReach' | 'searchAttrs' | 'daemonBoot' | 'badgeCollection';
3
+ export type StepName = 'preflight' | 'mcpConfig' | 'temporalReach' | 'searchAttrs' | 'daemonBoot' | 'badgeCollection';
4
4
  /** Structured per-step result. `ok` = ran successfully; `skipped` = cache hit;
5
5
  * `action-taken` = needed repair (e.g. started daemon, registered MCP);
6
6
  * `failed` = non-fatal failure recorded for the TUI to surface. */
@@ -55,15 +55,6 @@ export interface BootstrapArgs {
55
55
  * simulates a successful start; `'failed'` + `detail` simulates failure.
56
56
  */
57
57
  daemonBoot?: (config: Config) => Promise<StepOutcome>;
58
- /**
59
- * PR-2 of the v1.0 rebrand — one-shot copy of `~/.agent-tempo/` →
60
- * `~/.agent-tempo/`. Runs once on first boot of the new binary; idempotent
61
- * thereafter. Tests should override to avoid touching real $HOME.
62
- *
63
- * Failure here MUST NOT block the boot path — record `'failed'` with a
64
- * detail string and let the rest of bootstrap proceed.
65
- */
66
- legacyHomeMigration?: () => Promise<StepOutcome>;
67
58
  /**
68
59
  * Inject the Temporal reachability probe (steps 3 + 6). Tests override
69
60
  * to avoid real network I/O — default performs `createTemporalConnection`
@@ -73,7 +73,6 @@ const orphans_1 = require("../reconcile/orphans");
73
73
  const client_2 = require("../client");
74
74
  const os_1 = require("os");
75
75
  const git_info_1 = require("../git-info");
76
- const legacy_migration_1 = require("./legacy-migration");
77
76
  // ─────────────────────────────────────────────────────────────────────────
78
77
  // Cache (schema v1)
79
78
  // ─────────────────────────────────────────────────────────────────────────
@@ -241,38 +240,6 @@ function daemonLogErrorTail(logPath) {
241
240
  // ─────────────────────────────────────────────────────────────────────────
242
241
  // Individual steps
243
242
  // ─────────────────────────────────────────────────────────────────────────
244
- /**
245
- * Default step-0 implementation — invokes the one-shot legacy home migration
246
- * (`~/.agent-tempo/` → `~/.agent-tempo/`). Idempotent: re-runs are
247
- * `'skipped'` once the marker is in place. Failure is recorded but never
248
- * blocks bootstrap (PR-2 brief).
249
- */
250
- async function defaultLegacyHomeMigrationStep() {
251
- const t0 = perf_hooks_1.performance.now();
252
- try {
253
- const result = await (0, legacy_migration_1.migrateLegacyHome)();
254
- const durationMs = perf_hooks_1.performance.now() - t0;
255
- const detail = (0, legacy_migration_1.formatMigrationResult)(result);
256
- switch (result.status) {
257
- case 'no-legacy':
258
- case 'already-migrated':
259
- return { status: 'skipped', durationMs, detail };
260
- case 'migrated':
261
- return { status: 'action-taken', durationMs, detail };
262
- case 'skipped':
263
- return { status: 'skipped', durationMs, detail };
264
- case 'failed':
265
- return { status: 'failed', durationMs, detail };
266
- }
267
- }
268
- catch (err) {
269
- return {
270
- status: 'failed',
271
- durationMs: perf_hooks_1.performance.now() - t0,
272
- detail: `legacy-migration crashed: ${err.message}`,
273
- };
274
- }
275
- }
276
243
  async function stepPreflight(cache, now) {
277
244
  if (isCacheFresh(cache.steps.preflight, TTL_24H, now)) {
278
245
  return { status: 'skipped', durationMs: 0 };
@@ -622,12 +589,6 @@ async function bootstrap(args) {
622
589
  const fetchLatest = args.fetchLatestVersion ?? defaultFetchLatestVersion;
623
590
  const cache = readCache(cacheDir, binaryVersion);
624
591
  const reachableProbe = args.isTemporalReachable ?? ((c) => isTemporalReachable(c, 3000));
625
- // Step 0: legacy home migration (`~/.agent-tempo/` → `~/.agent-tempo/`)
626
- // — PR-2 of the v1.0 rebrand. Runs before preflight so subsequent steps
627
- // (cache read, MCP config write, daemon boot) all see the new home.
628
- // MUST NOT block bootstrap — failure becomes a `'failed'` step with
629
- // `detail`, and we keep going.
630
- const legacyHomeMigration = await (args.legacyHomeMigration ?? defaultLegacyHomeMigrationStep)();
631
592
  // Steps 1–5: fail-fast on step 1 so we don't try to register MCP on an
632
593
  // incompatible Node. Each step mutates the cache in-place.
633
594
  const preflight = await stepPreflight(cache, now);
@@ -668,7 +629,6 @@ async function bootstrap(args) {
668
629
  return {
669
630
  durationMs: perf_hooks_1.performance.now() - start,
670
631
  steps: {
671
- legacyHomeMigration,
672
632
  preflight,
673
633
  mcpConfig,
674
634
  temporalReach,
package/dist/cli.js CHANGED
@@ -60,7 +60,6 @@ const out = __importStar(require("./cli/output"));
60
60
  const dev_banner_1 = require("./cli/dev-banner");
61
61
  const types_1 = require("./types");
62
62
  const config_1 = require("./config");
63
- const legacy_migration_1 = require("./cli/legacy-migration");
64
63
  const global_wrapper_1 = require("./cli/global-wrapper");
65
64
  const resolve_ensemble_1 = require("./cli/resolve-ensemble");
66
65
  const grpc_shutdown_guard_1 = require("./utils/grpc-shutdown-guard");
@@ -68,7 +67,9 @@ const grpc_shutdown_guard_1 = require("./utils/grpc-shutdown-guard");
68
67
  const PACKAGE_ROOT = (0, path_1.resolve)(__dirname, '..');
69
68
  function parseArgs(argv) {
70
69
  const result = {
71
- command: 'tui',
70
+ // #789 — the TUI is deleted; a bare `agent-tempo` now resolves to the
71
+ // `home` command (bootstrap + status + hints), NOT a terminal UI launch.
72
+ command: 'home',
72
73
  positional: [],
73
74
  dir: process.cwd(),
74
75
  skipPreflight: false,
@@ -145,6 +146,11 @@ function parseArgs(argv) {
145
146
  else if (arg === '--no-hold') {
146
147
  result.noHold = true;
147
148
  }
149
+ else if (arg === '--from-upgrade') {
150
+ // `up --from-upgrade` (#786) — recreate protocol-2 workflows from the
151
+ // upgrade snapshot left by `upgrade-to-2`.
152
+ result.fromUpgrade = true;
153
+ }
148
154
  else if (arg === '--destroy') {
149
155
  result.destroy = true;
150
156
  }
@@ -168,12 +174,10 @@ function parseArgs(argv) {
168
174
  result.host = argv[++i];
169
175
  }
170
176
  else if (arg === '--force') {
171
- // Consumed by `daemon start --force` (bypass stale-PID guard) and by
172
- // `migrate-from-claude-tempo --force` (bypass conflict + volatile-state guards).
177
+ // Consumed by `daemon start --force` (bypass stale-PID guard).
173
178
  result.force = true;
174
179
  }
175
180
  else if (arg === '--dry-run') {
176
- // `migrate-from-claude-tempo --dry-run` — print the plan, write nothing.
177
181
  // `upgrade-to-2 --dry-run` — print snapshot + destroy list, change nothing.
178
182
  result.dryRun = true;
179
183
  }
@@ -302,39 +306,6 @@ function cliOverrides(args) {
302
306
  temporalTlsKeyPath: args.temporalTlsKeyPath,
303
307
  };
304
308
  }
305
- /**
306
- * Format + print a {@link LegacyMigrationResult} from
307
- * `migrate-from-claude-tempo`. Extracted to module scope (an if/else cascade
308
- * rather than a nested switch) so the body doesn't trip the CLI surface-drift
309
- * detector, which scans top-level `case '...':` labels in this file.
310
- */
311
- function reportMigrationResult(result) {
312
- const msg = (0, legacy_migration_1.formatMigrationResult)(result);
313
- if (result.status === 'no-legacy' || result.status === 'already-migrated') {
314
- out.success(msg);
315
- return;
316
- }
317
- if (result.status === 'migrated') {
318
- out.success(msg);
319
- if (result.copiedFiles?.length) {
320
- for (const f of result.copiedFiles)
321
- out.log(` ${out.dim('+')} ${f}`);
322
- }
323
- if (result.errors?.length) {
324
- for (const e of result.errors)
325
- out.warn(e);
326
- }
327
- return;
328
- }
329
- if (result.status === 'skipped') {
330
- out.warn(msg);
331
- process.exitCode = 1;
332
- return;
333
- }
334
- // 'failed'
335
- out.error(msg);
336
- process.exitCode = 1;
337
- }
338
309
  async function main() {
339
310
  // Neutralize the Temporal/grpc-js "Channel has been shut down" retry-after-
340
311
  // close race before any Temporal-touching command runs. See
@@ -519,6 +490,7 @@ async function main() {
519
490
  noHold: args.noHold,
520
491
  agent: resolvedAgent(),
521
492
  ...(args.scenario ? { scenario: args.scenario } : {}),
493
+ ...(args.fromUpgrade ? { fromUpgrade: true } : {}),
522
494
  ...overrides,
523
495
  });
524
496
  break;
@@ -687,20 +659,6 @@ async function main() {
687
659
  out.log(out.dim(' A bare `pi` stays a plain coding session (neither extension activates).'));
688
660
  break;
689
661
  }
690
- case 'migrate-from-claude-tempo': {
691
- // PR-2 of the v1.0 rebrand — one-shot copy of `~/.agent-tempo/` →
692
- // `~/.agent-tempo/`. Crash-proof (no Temporal deps). The `--dev`
693
- // top-level flag selects the dev profile (`~/.agent-tempo-dev/` →
694
- // `~/.agent-tempo-dev/`) via {@link isDevMode}.
695
- const { migrateLegacyHome } = await Promise.resolve().then(() => __importStar(require('./cli/legacy-migration')));
696
- const result = await migrateLegacyHome({
697
- dryRun: !!args.dryRun,
698
- force: !!args.force,
699
- profile: (0, config_1.isDevMode)() ? 'dev' : 'prod',
700
- });
701
- reportMigrationResult(result);
702
- break;
703
- }
704
662
  case 'preflight': {
705
663
  // Preflight legitimately requires Temporal (that's what it tests), so
706
664
  // it's NOT in the crash-proof module set. Dynamic-imported here so its
@@ -721,35 +679,31 @@ async function main() {
721
679
  out.success('All checks passed');
722
680
  break;
723
681
  }
724
- case 'tui': {
682
+ case 'home': {
683
+ // E.8 / D2 (#789) — bare `agent-tempo`: the #289 six-step auto-provisioning
684
+ // bootstrap (MCP registration, Temporal reachability, daemon boot,
685
+ // badges + ensembles prefetch), then a status snapshot + next-step hints.
686
+ // One-shot; the live operator surfaces are mission-control
687
+ // (`command-center`, when the Pi seat is installed) and the web dashboard.
688
+ // `--skip-preflight` renders the degraded no-result home. The rich,
689
+ // unit-tested render lives in the crash-proof `home-command` module.
725
690
  const config = (0, config_1.getConfig)(overrides);
726
- // If --ensemble or positional arg given, start in single-ensemble view.
727
- // Otherwise, start in multi-ensemble home view.
728
- const tuiEnsemble = args.ensemble || args.positional[1] || undefined;
729
- // #289 / S7: run the auto-provisioning bootstrap before handing off
730
- // to the TUI. Steps 1–6 register MCP, ensure Temporal reachability,
731
- // boot the daemon, and prefetch badges + ensembles so the TUI home
732
- // view renders instantly. `skipPreflight` bypass: power users can
733
- // opt out if the cache / disk-probe cost ever regresses (no current
734
- // way to trigger, but the flag is already on the parser).
735
- let bootstrapResult;
736
- if (!args.skipPreflight) {
737
- const { bootstrap } = await Promise.resolve().then(() => __importStar(require('./cli/startup')));
738
- try {
739
- bootstrapResult = await bootstrap({ config });
740
- }
741
- catch (err) {
742
- // Bootstrap is best-effort — per-step failures degrade into
743
- // `StepOutcome.status: 'failed'` and a usable result. A thrown
744
- // error means something outside the step boundaries broke
745
- // (e.g. cache-dir creation). Log + continue with an undefined
746
- // bootstrap payload so the TUI still launches.
747
- out.warn(`Bootstrap hit an unexpected error: ${err instanceof Error ? err.message : String(err)}`);
748
- }
749
- }
750
- // Dynamic import — TUI module uses ESM ink
751
- const { run: runTui } = await Promise.resolve().then(() => __importStar(require('./tui/index')));
752
- await runTui({ config, ensemble: tuiEnsemble, ...(bootstrapResult ? { bootstrap: bootstrapResult } : {}) });
691
+ const { runHome } = await Promise.resolve().then(() => __importStar(require('./cli/home-command')));
692
+ const { probePi, checkPiNodeFloor } = await Promise.resolve().then(() => __importStar(require('./pi/probe')));
693
+ const pkgVersion = require('../package.json').version;
694
+ await runHome({
695
+ bootstrap: args.skipPreflight
696
+ ? null
697
+ : async () => {
698
+ const { bootstrap } = await Promise.resolve().then(() => __importStar(require('./cli/startup')));
699
+ return bootstrap({ config });
700
+ },
701
+ // The command-center seat needs BOTH the Pi package and the Node floor
702
+ // (the same pair command-center-command itself enforces) suggesting
703
+ // it on an old Node would dead-end the user.
704
+ piAvailable: probePi().available && checkPiNodeFloor().ok,
705
+ version: pkgVersion,
706
+ });
753
707
  break;
754
708
  }
755
709
  // `version`, `help`, `upgrade`, `config`, `daemon`, and removed-verb