team 0.0.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +310 -0
  3. package/dist/approve/approval.d.ts +38 -0
  4. package/dist/approve/approval.js +78 -0
  5. package/dist/approve/diff.d.ts +13 -0
  6. package/dist/approve/diff.js +47 -0
  7. package/dist/approve/fingerprint.d.ts +44 -0
  8. package/dist/approve/fingerprint.js +109 -0
  9. package/dist/args.d.ts +7 -0
  10. package/dist/args.js +22 -0
  11. package/dist/budgets/checks.d.ts +35 -0
  12. package/dist/budgets/checks.js +77 -0
  13. package/dist/budgets/gate.d.ts +24 -0
  14. package/dist/budgets/gate.js +127 -0
  15. package/dist/budgets/readings.d.ts +69 -0
  16. package/dist/budgets/readings.js +156 -0
  17. package/dist/budgets/run.d.ts +66 -0
  18. package/dist/budgets/run.js +119 -0
  19. package/dist/budgets/table.d.ts +24 -0
  20. package/dist/budgets/table.js +90 -0
  21. package/dist/caller.d.ts +48 -0
  22. package/dist/caller.js +126 -0
  23. package/dist/check/config.d.ts +51 -0
  24. package/dist/check/config.js +50 -0
  25. package/dist/check/git.d.ts +27 -0
  26. package/dist/check/git.js +97 -0
  27. package/dist/check/message.d.ts +27 -0
  28. package/dist/check/message.js +101 -0
  29. package/dist/check/run.d.ts +31 -0
  30. package/dist/check/run.js +77 -0
  31. package/dist/check/signature.d.ts +10 -0
  32. package/dist/check/signature.js +22 -0
  33. package/dist/cli.d.ts +9 -0
  34. package/dist/cli.js +76 -0
  35. package/dist/clis.d.ts +7 -0
  36. package/dist/clis.js +9 -0
  37. package/dist/commands/add.d.ts +23 -0
  38. package/dist/commands/add.js +445 -0
  39. package/dist/commands/approve.d.ts +11 -0
  40. package/dist/commands/approve.js +146 -0
  41. package/dist/commands/check.d.ts +17 -0
  42. package/dist/commands/check.js +103 -0
  43. package/dist/commands/doctor.d.ts +38 -0
  44. package/dist/commands/doctor.js +232 -0
  45. package/dist/commands/down.d.ts +37 -0
  46. package/dist/commands/down.js +258 -0
  47. package/dist/commands/init.d.ts +9 -0
  48. package/dist/commands/init.js +138 -0
  49. package/dist/commands/remove.d.ts +23 -0
  50. package/dist/commands/remove.js +235 -0
  51. package/dist/commands/status.d.ts +41 -0
  52. package/dist/commands/status.js +147 -0
  53. package/dist/commands/up.d.ts +49 -0
  54. package/dist/commands/up.js +362 -0
  55. package/dist/commands/watch.d.ts +35 -0
  56. package/dist/commands/watch.js +324 -0
  57. package/dist/commands/worktree.d.ts +12 -0
  58. package/dist/commands/worktree.js +388 -0
  59. package/dist/end/condition.d.ts +28 -0
  60. package/dist/end/condition.js +77 -0
  61. package/dist/file/current.d.ts +13 -0
  62. package/dist/file/current.js +53 -0
  63. package/dist/file/lines.d.ts +25 -0
  64. package/dist/file/lines.js +277 -0
  65. package/dist/file/load.d.ts +7 -0
  66. package/dist/file/load.js +90 -0
  67. package/dist/file/paths.d.ts +6 -0
  68. package/dist/file/paths.js +77 -0
  69. package/dist/file/secrets.d.ts +6 -0
  70. package/dist/file/secrets.js +54 -0
  71. package/dist/file/signature.d.ts +13 -0
  72. package/dist/file/signature.js +36 -0
  73. package/dist/file/types.d.ts +130 -0
  74. package/dist/file/types.js +1 -0
  75. package/dist/file/validate.d.ts +13 -0
  76. package/dist/file/validate.js +702 -0
  77. package/dist/file/write.d.ts +11 -0
  78. package/dist/file/write.js +13 -0
  79. package/dist/herdr.d.ts +38 -0
  80. package/dist/herdr.js +227 -0
  81. package/dist/index.d.ts +10 -0
  82. package/dist/index.js +6 -0
  83. package/dist/io.d.ts +10 -0
  84. package/dist/io.js +1 -0
  85. package/dist/launch/deliver.d.ts +10 -0
  86. package/dist/launch/deliver.js +39 -0
  87. package/dist/launch/execute.d.ts +46 -0
  88. package/dist/launch/execute.js +284 -0
  89. package/dist/launch/plan.d.ts +185 -0
  90. package/dist/launch/plan.js +280 -0
  91. package/dist/launch/rules.d.ts +25 -0
  92. package/dist/launch/rules.js +36 -0
  93. package/dist/log.d.ts +1 -0
  94. package/dist/log.js +24 -0
  95. package/dist/profiles/antigravity.yaml +66 -0
  96. package/dist/profiles/claude-code.yaml +69 -0
  97. package/dist/profiles/codex.yaml +77 -0
  98. package/dist/profiles/cursor.yaml +68 -0
  99. package/dist/profiles/index.d.ts +1 -0
  100. package/dist/profiles/index.js +1 -0
  101. package/dist/profiles/profile.d.ts +60 -0
  102. package/dist/profiles/profile.js +313 -0
  103. package/dist/profiles/quota.d.ts +27 -0
  104. package/dist/profiles/quota.js +57 -0
  105. package/dist/state.d.ts +61 -0
  106. package/dist/state.js +127 -0
  107. package/dist/status/compare.d.ts +26 -0
  108. package/dist/status/compare.js +110 -0
  109. package/dist/status/statusline.d.ts +9 -0
  110. package/dist/status/statusline.js +26 -0
  111. package/dist/store/store.d.ts +62 -0
  112. package/dist/store/store.js +116 -0
  113. package/dist/watch/check.d.ts +82 -0
  114. package/dist/watch/check.js +29 -0
  115. package/dist/watch/checks/approval.d.ts +2 -0
  116. package/dist/watch/checks/approval.js +16 -0
  117. package/dist/watch/checks/attention.d.ts +2 -0
  118. package/dist/watch/checks/attention.js +23 -0
  119. package/dist/watch/checks/budget.d.ts +2 -0
  120. package/dist/watch/checks/budget.js +141 -0
  121. package/dist/watch/checks/disk.d.ts +2 -0
  122. package/dist/watch/checks/disk.js +13 -0
  123. package/dist/watch/checks/extra.d.ts +2 -0
  124. package/dist/watch/checks/extra.js +18 -0
  125. package/dist/watch/checks/idle.d.ts +2 -0
  126. package/dist/watch/checks/idle.js +32 -0
  127. package/dist/watch/checks/load.d.ts +2 -0
  128. package/dist/watch/checks/load.js +11 -0
  129. package/dist/watch/checks/memory.d.ts +2 -0
  130. package/dist/watch/checks/memory.js +11 -0
  131. package/dist/watch/checks/missing.d.ts +2 -0
  132. package/dist/watch/checks/missing.js +12 -0
  133. package/dist/watch/checks/model-drift.d.ts +2 -0
  134. package/dist/watch/checks/model-drift.js +14 -0
  135. package/dist/watch/checks/swap-free.d.ts +2 -0
  136. package/dist/watch/checks/swap-free.js +12 -0
  137. package/dist/watch/checks/swap-growth.d.ts +2 -0
  138. package/dist/watch/checks/swap-growth.js +18 -0
  139. package/dist/watch/checks/team-idle.d.ts +2 -0
  140. package/dist/watch/checks/team-idle.js +18 -0
  141. package/dist/watch/checks/unsent.d.ts +2 -0
  142. package/dist/watch/checks/unsent.js +18 -0
  143. package/dist/watch/close.d.ts +19 -0
  144. package/dist/watch/close.js +40 -0
  145. package/dist/watch/dialect.d.ts +5 -0
  146. package/dist/watch/dialect.js +430 -0
  147. package/dist/watch/end.d.ts +11 -0
  148. package/dist/watch/end.js +17 -0
  149. package/dist/watch/machine.d.ts +38 -0
  150. package/dist/watch/machine.js +137 -0
  151. package/dist/watch/notify.d.ts +1 -0
  152. package/dist/watch/notify.js +15 -0
  153. package/dist/watch/pass.d.ts +42 -0
  154. package/dist/watch/pass.js +242 -0
  155. package/dist/watch/screen-core.d.ts +20 -0
  156. package/dist/watch/screen-core.js +356 -0
  157. package/dist/watch/screen-data.d.ts +65 -0
  158. package/dist/watch/screen-data.js +1 -0
  159. package/dist/watch/screen-file.d.ts +2 -0
  160. package/dist/watch/screen-file.js +269 -0
  161. package/dist/watch/screen.d.ts +24 -0
  162. package/dist/watch/screen.js +47 -0
  163. package/dist/worktree/place.d.ts +18 -0
  164. package/dist/worktree/place.js +126 -0
  165. package/dist/yaml.d.ts +30 -0
  166. package/dist/yaml.js +380 -0
  167. package/examples/checks/codex-quota +217 -0
  168. package/examples/team.yaml +76 -0
  169. package/package.json +29 -10
@@ -0,0 +1,284 @@
1
+ async function until(seconds, pace, host, ready) {
2
+ const deadline = host.now() + seconds * 1000;
3
+ for (;;) {
4
+ if (ready())
5
+ return true;
6
+ if (host.now() >= deadline)
7
+ return false;
8
+ const before = host.now();
9
+ await host.sleep(pace);
10
+ // A clock that does not move would spin. Treat that as the wait running out.
11
+ if (host.now() <= before)
12
+ return false;
13
+ }
14
+ }
15
+ /** Runs a plan. Steps carry the operation beside the command the dry run prints. */
16
+ export async function executePlan(steps, session, host) {
17
+ const places = new Map();
18
+ const dropped = new Set();
19
+ const logged = new Set();
20
+ const failedDirs = new Set();
21
+ let serverFailed = false;
22
+ let watchFailed = false;
23
+ let held = false;
24
+ let abort = false;
25
+ const finish = (seat, what) => {
26
+ if (logged.has(seat))
27
+ return;
28
+ logged.add(seat);
29
+ host.say(`${seat}: ${what}\n`);
30
+ host.log(seat, what);
31
+ };
32
+ const place = (label, pane, workspace) => {
33
+ const have = places.get(label);
34
+ if (have)
35
+ return have;
36
+ if (!pane)
37
+ return null;
38
+ const made = { pane, workspace };
39
+ places.set(label, made);
40
+ return made;
41
+ };
42
+ for (const step of steps) {
43
+ const op = step.do;
44
+ const seat = op && 'seat' in op ? op.seat : undefined;
45
+ if (abort)
46
+ continue;
47
+ if (seat && dropped.has(seat))
48
+ continue;
49
+ if (step.kind === 'skip') {
50
+ if (op?.do === 'ready' && op.seat) {
51
+ if (op.notice)
52
+ host.say(`${op.seat}: ${op.notice}\n`);
53
+ host.record(op.seat, { stage: 'ready', rules: op.rules });
54
+ finish(op.seat, 'ready');
55
+ }
56
+ else if (op?.do === 'refuse') {
57
+ finish(op.seat, `refused: ${op.why}`);
58
+ }
59
+ else
60
+ host.say(` skip ${step.text}\n`);
61
+ continue;
62
+ }
63
+ if (!op)
64
+ continue;
65
+ switch (op.do) {
66
+ case 'server': {
67
+ if (!host.startServer(op.session)) {
68
+ serverFailed = true;
69
+ abort = true;
70
+ host.say(`session ${op.session}: its server did not start\n`);
71
+ }
72
+ break;
73
+ }
74
+ case 'wait-session': {
75
+ const up = await until(op.seconds, 1000, host, () => host.sessionUp(op.session) === true);
76
+ if (!up) {
77
+ serverFailed = true;
78
+ abort = true;
79
+ host.say(`session ${op.session}: it was not running within ${op.seconds} s\n`);
80
+ }
81
+ break;
82
+ }
83
+ case 'lobby': {
84
+ // A seat whose lobby folder could not be made is left out at its create step.
85
+ if (!host.makeDir?.(op.path))
86
+ failedDirs.add(op.path);
87
+ break;
88
+ }
89
+ case 'create': {
90
+ if (op.seat && op.notice)
91
+ host.say(`${op.seat}: ${op.notice}\n`);
92
+ if (op.seat) {
93
+ const why = host.allow(op.seat);
94
+ if (why) {
95
+ dropped.add(op.seat);
96
+ finish(op.seat, why);
97
+ break;
98
+ }
99
+ if (failedDirs.has(op.cwd)) {
100
+ dropped.add(op.seat);
101
+ finish(op.seat, 'its lobby folder was not created; left out');
102
+ break;
103
+ }
104
+ host.record(op.seat, { stage: 'launched' });
105
+ }
106
+ const made = host.createWorkspace(session, op.cwd, op.label);
107
+ if (!made) {
108
+ if (op.seat) {
109
+ dropped.add(op.seat);
110
+ finish(op.seat, 'its workspace was not created; left at launched');
111
+ }
112
+ else {
113
+ watchFailed = true;
114
+ host.say('watch: its workspace was not created\n');
115
+ host.log('watch', 'its workspace was not created');
116
+ }
117
+ break;
118
+ }
119
+ places.set(op.label, made);
120
+ if (op.seat) {
121
+ host.record(op.seat, { stage: 'launched', pane: made.pane, workspace: made.workspace });
122
+ host.running(op.seat);
123
+ }
124
+ break;
125
+ }
126
+ case 'launch': {
127
+ if (op.notice)
128
+ host.say(`${op.seat}: ${op.notice}\n`);
129
+ const why = host.allow(op.seat);
130
+ if (why) {
131
+ dropped.add(op.seat);
132
+ finish(op.seat, why);
133
+ break;
134
+ }
135
+ const here = place(op.label, op.pane);
136
+ if (!here || !host.paneRun(session, here.pane, op.command)) {
137
+ dropped.add(op.seat);
138
+ finish(op.seat, 'its launch command did not run; left at launched');
139
+ break;
140
+ }
141
+ host.running(op.seat);
142
+ break;
143
+ }
144
+ case 'idle': {
145
+ if (op.notice)
146
+ host.say(`${op.seat}: ${op.notice}\n`);
147
+ const here = place(op.label, op.pane, op.workspace);
148
+ if (!here) {
149
+ dropped.add(op.seat);
150
+ finish(op.seat, 'has no pane to read; left at launched');
151
+ break;
152
+ }
153
+ const deadline = host.now() + op.seconds * 1000;
154
+ let outcome = 'timeout';
155
+ for (;;) {
156
+ const kind = host.classify(session, here.pane, op.cli);
157
+ if (kind === 'idle' || kind === 'permission' || kind === 'trust' || kind === 'question') {
158
+ outcome = kind;
159
+ break;
160
+ }
161
+ if (host.now() >= deadline)
162
+ break;
163
+ const before = host.now();
164
+ await host.sleep(2000);
165
+ if (host.now() <= before)
166
+ break;
167
+ }
168
+ if (outcome === 'idle')
169
+ break;
170
+ const workspace = here.workspace ?? places.get(op.label)?.workspace;
171
+ if (outcome === 'permission' || outcome === 'trust' || outcome === 'question') {
172
+ // A trust question is closed with no key and no text. The same for a permission or a question.
173
+ if (workspace)
174
+ host.closeWorkspace(session, workspace);
175
+ host.drop(op.seat);
176
+ dropped.add(op.seat);
177
+ const why = outcome === 'trust'
178
+ ? 'left out: trust question'
179
+ : `${outcome}; its workspace was closed without input and the seat left out`;
180
+ finish(op.seat, why);
181
+ break;
182
+ }
183
+ dropped.add(op.seat);
184
+ finish(op.seat, 'timed out waiting for its idle prompt; left at launched');
185
+ break;
186
+ }
187
+ case 'rename': {
188
+ const here = place(op.label, op.pane);
189
+ if (!here) {
190
+ dropped.add(op.seat);
191
+ finish(op.seat, 'has no pane to name; left at launched');
192
+ break;
193
+ }
194
+ const seen = await until(op.seconds, 2000, host, () => host.agentPanes(session)?.includes(here.pane) === true);
195
+ if (!seen || !host.renameAgent(session, here.pane, op.seat)) {
196
+ dropped.add(op.seat);
197
+ finish(op.seat, 'was not in the agent list in time; left at launched');
198
+ break;
199
+ }
200
+ host.record(op.seat, { stage: 'named', pane: here.pane, workspace: here.workspace });
201
+ if (op.rules === 'option') {
202
+ host.record(op.seat, { stage: 'ready', rules: 'option', pane: here.pane, workspace: here.workspace });
203
+ finish(op.seat, 'ready');
204
+ }
205
+ break;
206
+ }
207
+ case 'deliver': {
208
+ if (op.notice)
209
+ host.say(`${op.seat}: ${op.notice}\n`);
210
+ const here = place(op.label, op.pane);
211
+ if (!here || !await host.deliverRules?.(session, here.pane, op.cli, op.rules, op.seconds)) {
212
+ dropped.add(op.seat);
213
+ finish(op.seat, 'its rules were not delivered; left at named');
214
+ break;
215
+ }
216
+ host.record(op.seat, { stage: 'ready', rules: 'message', pane: here.pane });
217
+ finish(op.seat, 'ready');
218
+ break;
219
+ }
220
+ case 'watch': {
221
+ const here = places.get(op.label);
222
+ if (!here || !host.paneRun(session, here.pane, op.command)) {
223
+ watchFailed = true;
224
+ host.say('watch: it did not start\n');
225
+ host.log('watch', 'it did not start');
226
+ break;
227
+ }
228
+ host.say('watch: started\n');
229
+ host.log('watch', 'started');
230
+ break;
231
+ }
232
+ case 'type': {
233
+ if (!host.typeLine(session, op.pane, op.text)) {
234
+ held = true;
235
+ dropped.add(op.seat);
236
+ finish(op.seat, 'its exit was not typed; left as it is');
237
+ }
238
+ break;
239
+ }
240
+ case 'gone': {
241
+ const gone = await until(op.seconds, 2000, host, () => host.agentPanes(session)?.includes(op.pane) === false);
242
+ if (!gone) {
243
+ held = true;
244
+ dropped.add(op.seat);
245
+ finish(op.seat, 'timed out leaving its pane; left as it is');
246
+ }
247
+ break;
248
+ }
249
+ case 'close': {
250
+ if (!host.closeWorkspace(session, op.workspace)) {
251
+ held = true;
252
+ finish(op.seat, 'its workspace did not close');
253
+ break;
254
+ }
255
+ host.drop(op.seat);
256
+ finish(op.seat, 'stopped');
257
+ break;
258
+ }
259
+ case 'kill': {
260
+ if (!host.kill(op.pid)) {
261
+ held = true;
262
+ host.say(`watch: pid ${op.pid} did not stop\n`);
263
+ }
264
+ else
265
+ host.say('watch: stopped\n');
266
+ break;
267
+ }
268
+ case 'stop': {
269
+ if (held) {
270
+ host.say(`session ${op.session}: not stopped, something was left in it\n`);
271
+ break;
272
+ }
273
+ if (!host.stopSession(op.session))
274
+ host.say(`session ${op.session}: it did not stop\n`);
275
+ else
276
+ host.say(`session ${op.session}: stopped\n`);
277
+ break;
278
+ }
279
+ default:
280
+ break;
281
+ }
282
+ }
283
+ return { serverFailed, watchFailed, held };
284
+ }
@@ -0,0 +1,185 @@
1
+ /**
2
+ * What running a step does. The printed command stays in `argv`; this is how the live command
3
+ * performs that same step, so a dry run and a real run share one plan.
4
+ */
5
+ export type Op = {
6
+ do: 'server';
7
+ session: string;
8
+ } | {
9
+ do: 'wait-session';
10
+ session: string;
11
+ seconds: number;
12
+ } | {
13
+ do: 'lobby';
14
+ path: string;
15
+ } | {
16
+ do: 'create';
17
+ seat?: string;
18
+ label: string;
19
+ cwd: string;
20
+ notice?: string;
21
+ } | {
22
+ do: 'launch';
23
+ seat: string;
24
+ label: string;
25
+ command: string;
26
+ pane?: string;
27
+ notice?: string;
28
+ } | {
29
+ do: 'refuse';
30
+ seat: string;
31
+ why: string;
32
+ } | {
33
+ do: 'idle';
34
+ seat: string;
35
+ label: string;
36
+ cli: string;
37
+ seconds: number;
38
+ pane?: string;
39
+ workspace?: string;
40
+ notice?: string;
41
+ } | {
42
+ do: 'rename';
43
+ seat: string;
44
+ label: string;
45
+ seconds: number;
46
+ rules: 'option' | 'message';
47
+ pane?: string;
48
+ } | {
49
+ do: 'deliver';
50
+ seat: string;
51
+ label: string;
52
+ cli: string;
53
+ rules: string;
54
+ seconds: number;
55
+ pane?: string;
56
+ notice?: string;
57
+ } | {
58
+ do: 'ready';
59
+ seat: string;
60
+ rules: 'option' | 'message';
61
+ notice?: string;
62
+ } | {
63
+ do: 'watch';
64
+ label: string;
65
+ command: string;
66
+ } | {
67
+ do: 'type';
68
+ seat: string;
69
+ pane: string;
70
+ text: string;
71
+ } | {
72
+ do: 'gone';
73
+ seat: string;
74
+ pane: string;
75
+ seconds: number;
76
+ } | {
77
+ do: 'close';
78
+ seat: string;
79
+ workspace: string;
80
+ } | {
81
+ do: 'kill';
82
+ pid: number;
83
+ } | {
84
+ do: 'stop';
85
+ session: string;
86
+ };
87
+ /** One thing `up` or `down` does, in order. */
88
+ export type Step =
89
+ /** A command that is run. */
90
+ {
91
+ kind: 'run';
92
+ argv: string[];
93
+ note?: string;
94
+ do?: Op;
95
+ }
96
+ /** A wait, with its time limit. */
97
+ | {
98
+ kind: 'wait';
99
+ text: string;
100
+ note?: string;
101
+ do?: Op;
102
+ }
103
+ /** A seat that is left out, and why. */
104
+ | {
105
+ kind: 'skip';
106
+ text: string;
107
+ note?: string;
108
+ do?: Op;
109
+ };
110
+ export interface UpSeat {
111
+ name: string;
112
+ cli: string;
113
+ launch: string;
114
+ /** Relative to the root. */
115
+ cwd: string;
116
+ label: string;
117
+ stopped: boolean;
118
+ /** The seat's rules, as one text. */
119
+ rules: string;
120
+ /** Set when a running session is being resumed. Omitted: launch from the start. */
121
+ stage?: 'launched' | 'named' | 'ready';
122
+ pane?: string;
123
+ workspace?: string;
124
+ /** Herdr already lists an agent in the recorded pane. */
125
+ agentLive?: boolean;
126
+ /** The seat works in worktrees: it waits in the lobby until a brief names its worktree. */
127
+ lobby?: boolean;
128
+ /**
129
+ * Set when a counted reading is inside the reserve, or the figure is unknown
130
+ * or a first sight. A refusal stops the seat only when this plan would launch it.
131
+ */
132
+ budget?: {
133
+ kind: 'refuse';
134
+ why: string;
135
+ } | {
136
+ kind: 'unknown';
137
+ account: string;
138
+ text: string;
139
+ };
140
+ }
141
+ export interface UpInput {
142
+ /** The project root; seats start in it. */
143
+ root: string;
144
+ session: string;
145
+ /** Whether the herdr session is already running, empty. */
146
+ sessionRunning: boolean;
147
+ seats: readonly UpSeat[];
148
+ /** The watch's pid is alive, so no second watch is started. */
149
+ watchAlive?: boolean;
150
+ /** The command the watchdog pane runs. Defaults to `team watch`. */
151
+ watchLine?: string;
152
+ }
153
+ /** The variables a herdr server starts with: nothing else reaches a seat's pane. */
154
+ export declare const SERVER_ENVIRONMENT: readonly ["HOME", "USER", "LOGNAME", "PATH", "SHELL", "TERM", "LANG"];
155
+ /** `herdr` aimed at a session; herdr's default session takes no option. */
156
+ export declare function herdr(session: string, ...args: string[]): string[];
157
+ /** What stands for a pane id that only exists once its workspace is created. */
158
+ export declare function paneOf(label: string): string;
159
+ /** Every step of `team up`, in order. Nothing here runs anything. */
160
+ export declare function upPlan(input: UpInput): Step[];
161
+ export interface DownSeat {
162
+ name: string;
163
+ cli: string;
164
+ pane: string;
165
+ workspace: string;
166
+ /** What the watch's reading says of the seat: only a free seat is stopped. */
167
+ state: 'free' | 'working' | 'blocked' | 'unknown' | 'unsent';
168
+ }
169
+ export interface DownInput {
170
+ session: string;
171
+ /** The running seats the file and the state name; nothing else is closed. */
172
+ seats: readonly DownSeat[];
173
+ /** Agents in the session that the file and the state don't name. */
174
+ extra: number;
175
+ /** The watch's pid, when its state records one that is alive. */
176
+ watchPid: number | null;
177
+ /** The caller's own seat, and the coordinator's and operator's, when a seat calls. */
178
+ keep: readonly string[];
179
+ /** The owner is closing workspaces that are not free, without typing into them. */
180
+ abandon?: boolean;
181
+ }
182
+ /** Every step of `team down`, in order. Nothing here runs anything. */
183
+ export declare function downPlan(input: DownInput): Step[];
184
+ /** The plan as `--dry-run` prints it. */
185
+ export declare function formatPlan(steps: readonly Step[]): string;