dsh-pause-session 0.0.0-stage → 0.1.0

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.
@@ -0,0 +1,324 @@
1
+ /**
2
+ * The identities both halves of dsh-pause-session name, the status encodings they
3
+ * share, and the one spelling a host log line gives a caught value.
4
+ *
5
+ * The browser bundle may value-import only the shell's baseline module table,
6
+ * so this module imports nothing: the client half reads command names and the
7
+ * decode functions from it directly, and the host half derives the branded
8
+ * identities from the same strings.
9
+ *
10
+ * A third-party plugin's only live channel to the browser is the command
11
+ * registry — it can add neither a `ctx.remote` namespace nor a forwarded event,
12
+ * both of which are compiled into the harness's own API assembly. A command
13
+ * descriptor's only free-form field is its `description`, and a command
14
+ * result's only free-form field is its `text`, so the park state travels as a
15
+ * prefix plus `;`-separated fields on one of those. The text stays
16
+ * human-readable: the same words are what the slash-command menu shows.
17
+ *
18
+ * Every value inside a field is escaped, so a decoded name is the exact name
19
+ * that was encoded. Session ids, tool names, and call ids are the host's own
20
+ * data and may contain the `;`, `,`, `/`, or newline a field is separated by; a
21
+ * folded spelling would decode as a different name — a different row, looked up
22
+ * again.
23
+ * @module dsh-pause-session/shared
24
+ */
25
+ /** Command that pauses the receiving session before its next model request. */
26
+ export declare const PAUSE_COMMAND = "pause";
27
+ /** Command that resumes the receiving session; registered only while that session is paused. */
28
+ export declare const RESUME_COMMAND = "pause-resume";
29
+ /** Command that resumes every parked session the registry remembers. */
30
+ export declare const RESUME_ALL_COMMAND = "pause-resume-all";
31
+ /** Command that registers and parks every running session tree in one action. */
32
+ export declare const PAUSE_ALL_COMMAND = "pause-all";
33
+ /** Command that reports the whole-app park state; registered globally, always. */
34
+ export declare const STATE_ALL_COMMAND = "pause-state-all";
35
+ /** Command that reports the receiving session's park state; registered only while it is paused. */
36
+ export declare const STATUS_COMMAND = "pause-state";
37
+ /** Command that turns the receiving session's own goal re-arm on or off; registered only while it is paused. */
38
+ export declare const GOAL_COMMAND = "pause-goal";
39
+ /** Command that reports every session that did not stop cleanly. */
40
+ export declare const TRIAGE_COMMAND = "pause-triage";
41
+ /** Command that resumes one session from the decision list exactly as the clean path would. */
42
+ export declare const TRIAGE_CONTINUE_COMMAND = "pause-triage-continue";
43
+ /** Command that resumes one session from the decision list with the unknown-outcome note. */
44
+ export declare const TRIAGE_NOTE_COMMAND = "pause-triage-note";
45
+ /** Command that opens one session from the decision list without spending a request. */
46
+ export declare const TRIAGE_REVIEW_COMMAND = "pause-triage-review";
47
+ /** Command that leaves one session from the decision list exactly as it is. */
48
+ export declare const TRIAGE_LEAVE_COMMAND = "pause-triage-leave";
49
+ /** Command that turns one listed session's goal re-arm on or off. */
50
+ export declare const TRIAGE_GOAL_COMMAND = "pause-triage-goal";
51
+ /** Stable definition id of the pause command, matched by identity rather than by copy. */
52
+ export declare const PAUSE_DEFINITION_ID = "dsh-pause-session/pause";
53
+ /** Stable definition id of the resume command: the host's own "this session is paused" fact. */
54
+ export declare const RESUME_DEFINITION_ID = "dsh-pause-session/resume";
55
+ /** Stable definition id of the global resume command, matched by identity rather than by copy. */
56
+ export declare const RESUME_ALL_DEFINITION_ID = "dsh-pause-session/resume-all";
57
+ /** Stable definition id of the whole-app pause command. */
58
+ export declare const PAUSE_ALL_DEFINITION_ID = "dsh-pause-session/pause-all";
59
+ /** Stable definition id of the whole-app status read. */
60
+ export declare const STATE_ALL_DEFINITION_ID = "dsh-pause-session/state-all";
61
+ /** Stable definition id of the status read, matched by identity rather than by copy. */
62
+ export declare const STATUS_DEFINITION_ID = "dsh-pause-session/status";
63
+ /** Stable definition id of the paused session's own goal re-arm toggle. */
64
+ export declare const GOAL_DEFINITION_ID = "dsh-pause-session/goal";
65
+ /** Stable definition id of the decision-list read. */
66
+ export declare const TRIAGE_DEFINITION_ID = "dsh-pause-session/triage";
67
+ /** Stable definition id of the decision-list "continue" verb. */
68
+ export declare const TRIAGE_CONTINUE_DEFINITION_ID = "dsh-pause-session/triage-continue";
69
+ /** Stable definition id of the decision-list "continue with the unknown-outcome note" verb. */
70
+ export declare const TRIAGE_NOTE_DEFINITION_ID = "dsh-pause-session/triage-note";
71
+ /** Stable definition id of the decision-list "open without activating" verb. */
72
+ export declare const TRIAGE_REVIEW_DEFINITION_ID = "dsh-pause-session/triage-review";
73
+ /** Stable definition id of the decision-list "leave it alone today" verb. */
74
+ export declare const TRIAGE_LEAVE_DEFINITION_ID = "dsh-pause-session/triage-leave";
75
+ /** Stable definition id of the decision-list goal re-arm toggle. */
76
+ export declare const TRIAGE_GOAL_DEFINITION_ID = "dsh-pause-session/triage-goal";
77
+ /** First token of every encoded status, so a descriptor is never parsed by accident. */
78
+ export declare const STATUS_PREFIX = "pause: ";
79
+ /**
80
+ * One log line's text for a caught value.
81
+ * @param error - the caught value.
82
+ * @returns the error's message, or the value's own spelling.
83
+ */
84
+ export declare function describeError(error: unknown): string;
85
+ /**
86
+ * The four park outcomes, listed in the order a park walks them — and the one
87
+ * vocabulary the live status, the durable registry, and the published words all
88
+ * derive from, so they cannot drift apart:
89
+ *
90
+ * - `draining`: paused, and the session is still working — a tool is running, or
91
+ * a turn is between steps.
92
+ * - `parking`: standing still at the park point; the session-level flush has
93
+ * not resolved yet.
94
+ * - `safe`: parked and flushed, so it is safe to walk away. The only clean one.
95
+ * - `flush-failed`: parked, but the flush failed — the durable promise is not
96
+ * kept, and it must never be read as clean.
97
+ */
98
+ export declare const PARK_PHASES: readonly ["draining", "parking", "safe", "flush-failed"];
99
+ /** One park outcome. */
100
+ export type ParkPhase = (typeof PARK_PHASES)[number];
101
+ /**
102
+ * Fold several records into the one verdict that speaks for all of them: the
103
+ * worst phase any of them reached, and whether every one of them is clean.
104
+ *
105
+ * This is how a session's control answers for its tree. "Safe to close" is a
106
+ * promise about everything the press registered, so it may be said only when
107
+ * every member reached the flushed park point; anything else is reported as the
108
+ * least-clean state in the set, never rounded up to the session's own.
109
+ * @param phases - the durable phases of the records being spoken for.
110
+ * @returns the worst phase, and whether that verdict is the clean one.
111
+ */
112
+ export declare function foldTreePhases(phases: Iterable<ParkPhase>): {
113
+ phase: ParkPhase;
114
+ safe: boolean;
115
+ };
116
+ /** Everything the browser is told about one paused session. */
117
+ export interface ParkStatus {
118
+ /**
119
+ * The phase of everything that session's press registered — the session and
120
+ * the subagent members under it, folded by {@link foldTreePhases}. A member
121
+ * still draining or stalled holds this at its own phase, because the control
122
+ * that owns the tree may not say "safe to close" while any member of it is
123
+ * not.
124
+ */
125
+ readonly phase: ParkPhase;
126
+ /** Whether the host commits to "you can close the lid now". */
127
+ readonly safe: boolean;
128
+ /** Tools in flight when the status was published; empty once parked. */
129
+ readonly runningTools: readonly string[];
130
+ /**
131
+ * Whether the resume that takes this pause back may re-open the session's
132
+ * goal — the durable record's own opt-out, which outlives this process. It is
133
+ * absent when this host could not read the record that holds it; a browser
134
+ * that is not told shows no switch rather than a state it would have to
135
+ * guess, and a guess here would tell the user their money is safe when
136
+ * nobody knows whether it is.
137
+ */
138
+ readonly rearmGoal?: boolean;
139
+ }
140
+ /**
141
+ * Encode one status for a command descriptor.
142
+ * @param status - the state to publish.
143
+ * @returns the descriptor text, e.g. `pause: draining; tools: edit, bash; goal: on`.
144
+ */
145
+ export declare function encodeParkStatus(status: ParkStatus): string;
146
+ /**
147
+ * Decode a status previously written by {@link encodeParkStatus}.
148
+ * @param text - a command descriptor's description.
149
+ * @returns the status, or `undefined` when this text carries none — a foreign
150
+ * command, or a reading taken before the host published anything.
151
+ */
152
+ export declare function decodeParkStatus(text: string): ParkStatus | undefined;
153
+ /**
154
+ * First token of every encoded whole-app status. A different prefix from the
155
+ * per-session status on purpose: one decoder must never read the other's text.
156
+ */
157
+ export declare const GLOBAL_STATUS_PREFIX = "pause all: ";
158
+ /** The whole-app answer to "can I close the lid?". */
159
+ export type GlobalVerdict = 'idle' | 'waiting' | 'safe';
160
+ /** A surface the whole-app report could not read at all. */
161
+ export type GlobalBlindSpot = 'trees' | 'jobs';
162
+ /**
163
+ * Everything the whole-app control publishes about the park as a whole.
164
+ *
165
+ * The counts and the names are one answer, not two: a report that says
166
+ * "3 registered, 1 safe" and then fails to say which two are missing is the
167
+ * kind of silence this control exists to prevent. The verdict is the only
168
+ * summary, and it is derived here so the host and the browser cannot disagree
169
+ * about it.
170
+ */
171
+ export interface GlobalStatus {
172
+ /** `idle` with nothing registered, `safe` only when every registered session is. */
173
+ readonly verdict: GlobalVerdict;
174
+ /** Sessions this park owns — the durable list plus anything pressed since. */
175
+ readonly registered: number;
176
+ /** How many of them reached the flushed park point. */
177
+ readonly safe: number;
178
+ /**
179
+ * The session this park belongs to — the first registered one this host can
180
+ * hold, whatever phase it reached, so a client can address its reads at the
181
+ * park instead of at whatever session the user happens to be looking at. A
182
+ * park whose every record is unreadable here names the first of those: the
183
+ * name is a fact about the park, and an address that cannot answer is the
184
+ * client's fallback to take.
185
+ *
186
+ * The buckets below name a session only while it has something left to do,
187
+ * and the clean case — every registered session `safe`, which is the ordinary
188
+ * one — leaves all of them empty: without this field a park that finished
189
+ * cleanly names no session at all. `undefined` when the park holds nothing,
190
+ * and absent from a reading written before this field existed; a client must
191
+ * not treat either absence as an address.
192
+ */
193
+ readonly parkedAt?: string;
194
+ /**
195
+ * Registered sessions still working: a tool is in flight or a turn is between
196
+ * steps. Their park point is announced by the marker commands the park
197
+ * registers, so a reader has nothing to watch here.
198
+ */
199
+ readonly draining: readonly string[];
200
+ /**
201
+ * How many registered sessions stand at the park point with their flush still
202
+ * pending — the host's `parking` phase. Nothing announces a flush resolving,
203
+ * so this is the one state a reader can only learn by asking again. A count
204
+ * rather than names: it says how long to keep watching, not which transcript
205
+ * a row belongs in, which is what `draining` is for.
206
+ */
207
+ readonly parking: number;
208
+ /**
209
+ * Registered sessions that will not reach the park point in this process: a
210
+ * flush that failed, a pause adopted from an earlier process, a press whose
211
+ * registry write failed, or a record whose session this host cannot read and
212
+ * therefore did not hold. Named, never folded into the count and forgotten.
213
+ */
214
+ readonly stalled: readonly string[];
215
+ /** Registered sessions whose tree contains a route a restart cannot resume. */
216
+ readonly unresumable: readonly string[];
217
+ /** Registered sessions whose subagent tree could not be read — unknown, not clean. */
218
+ readonly unreadTrees: readonly string[];
219
+ /** Live background jobs owned by the registered trees; nothing here can stop them. */
220
+ readonly jobs: readonly string[];
221
+ /** Whole surfaces the report could not read, so their emptiness is not a fact. */
222
+ readonly blind: readonly GlobalBlindSpot[];
223
+ }
224
+ /**
225
+ * Encode one whole-app status for a command result.
226
+ * @param status - the state to publish.
227
+ * @returns the result text, e.g.
228
+ * `pause all: waiting; registered: 3; safe: 1; parked-at: overnight; draining: overnight; parking: 1; stalled: -; unresumable: -; unread-trees: -; jobs: bash-1; blind: -`.
229
+ */
230
+ export declare function encodeGlobalStatus(status: GlobalStatus): string;
231
+ /**
232
+ * Decode a whole-app status previously written by {@link encodeGlobalStatus}.
233
+ * @param text - a command result's text.
234
+ * @returns the status, or `undefined` when this text carries none.
235
+ */
236
+ export declare function decodeGlobalStatus(text: string): GlobalStatus | undefined;
237
+ /**
238
+ * First token of every encoded decision list. Separate from the per-session and
239
+ * whole-app status prefixes on purpose, for the same reason those two are
240
+ * separate: one decoder must never read another's text.
241
+ */
242
+ export declare const TRIAGE_PREFIX = "pause triage: ";
243
+ /** How one decision-list row was read out of the session's own stored log. */
244
+ export type TriageReading = 'read' | 'unreadable';
245
+ /**
246
+ * What one stored log says about a tool call whose outcome was never recorded.
247
+ *
248
+ * The call event itself is durable; the harness turns every such call into a
249
+ * synthetic `TOOL_OUTCOME_UNKNOWN` error result when it next reads the log, and
250
+ * this is that same derivation taken without writing anything back. The marker
251
+ * itself is never in the stored log of a session still on the list: the resume
252
+ * that appends it is also the resume that drops the record putting it here.
253
+ */
254
+ export interface TriageTrace {
255
+ /** The tool's own name, from the call event the model produced. */
256
+ readonly tool: string;
257
+ /** The provider-issued id pairing the call with the result that never arrived. */
258
+ readonly callId: string;
259
+ }
260
+ /**
261
+ * One session that did not stop cleanly, as the decision list presents it.
262
+ *
263
+ * Every field is read from the session's own log or from the durable park
264
+ * record; nothing here is derived from the fact that the session is merely
265
+ * listed. `reading` is the honesty field: a log this host could not read says
266
+ * `unreadable` and carries no facts, rather than an empty row that would read
267
+ * as "no traces".
268
+ */
269
+ export interface TriageRow {
270
+ /** The parked session. */
271
+ readonly sessionId: string;
272
+ /** The durable park outcome; never `safe`, which is the clean path's business. */
273
+ readonly phase: Exclude<ParkPhase, 'safe'>;
274
+ /** When that outcome was last written. */
275
+ readonly updatedAt: number;
276
+ /** Whether the facts below came from the log. */
277
+ readonly reading: TriageReading;
278
+ /** What the stored log's last event was, with the step it belongs to when it has one. */
279
+ readonly lastEvent?: string;
280
+ /** The turn and step that last event belongs to. */
281
+ readonly turn?: number;
282
+ readonly step?: number;
283
+ /** Tools whose call event is durable and whose result is not — the unknown outcomes. */
284
+ readonly traces: readonly TriageTrace[];
285
+ /** Whether the stored log ends owing the model an answer. */
286
+ readonly owed: boolean;
287
+ /**
288
+ * Whether resuming this session may re-open its goal. Re-arming is what makes
289
+ * a resumed goal spend its owner's rounds, so it is a per-session choice the
290
+ * row shows and the list can flip.
291
+ */
292
+ readonly rearmGoal: boolean;
293
+ /**
294
+ * Whether the host could hand this session its owed request at all: a log it
295
+ * could not read, or one whose last request recorded no route, cannot be
296
+ * woken — which is a fact about the entry, not a refusal of the user's choice.
297
+ */
298
+ readonly wakeable: boolean;
299
+ }
300
+ /** The decision list: what did not stop cleanly, and each row's facts. */
301
+ export interface TriageList {
302
+ /** Every listed session, in registry order. */
303
+ readonly rows: readonly TriageRow[];
304
+ }
305
+ /**
306
+ * The decisions the list offers for one row. The first four carry the row out;
307
+ * `goal` changes what the next resume may spend without touching the park
308
+ * itself.
309
+ */
310
+ export declare const TRIAGE_ACTIONS: readonly ["continue", "note", "review", "leave", "goal"];
311
+ /** One decision the list offers. */
312
+ export type TriageAction = (typeof TRIAGE_ACTIONS)[number];
313
+ /**
314
+ * Encode one decision list for a command result.
315
+ * @param list - the rows to publish.
316
+ * @returns the result text, e.g. `pause triage: 1; row: overnight; phase: draining; stopped: tool/call/turn 1 step 1; tools: gated; wake: yes`.
317
+ */
318
+ export declare function encodeTriageList(list: TriageList): string;
319
+ /**
320
+ * Decode a decision list previously written by {@link encodeTriageList}.
321
+ * @param text - a command result's text.
322
+ * @returns the list, or `undefined` when this text carries none.
323
+ */
324
+ export declare function decodeTriageList(text: string): TriageList | undefined;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * One session's subagent tree, read from the parent catalogs.
3
+ *
4
+ * "This session's work" includes the subagents it delegated to, nested ones
5
+ * included, so the session-header press and the status the header shows both
6
+ * need the same answer to "which sessions hang under this one".
7
+ * `listDescendants` is the harness's own recursive walk of the parent-owned
8
+ * catalogs, and it is the only source: the tree is read from the parents that
9
+ * record it, never guessed from session ids.
10
+ *
11
+ * A walk is read, not remembered. The tree is a fact that grows — a delegation
12
+ * in flight publishes its child after the parent's catalog was read — so a
13
+ * press walks the tree at press time and a status read walks it at read time.
14
+ * `@module dsh-pause-session/tree`
15
+ */
16
+ import type { Context } from '@deepseek-ai/cordis';
17
+ import type { SessionId } from '@deepseek-ai/dsh-session';
18
+ /** One session a walk found under another, with the catalog's own mode for it. */
19
+ export interface TreeMember {
20
+ readonly id: SessionId;
21
+ /**
22
+ * The catalog's durable mode for this child. `external` is a child with no
23
+ * local session to park, and `unsupported` is a mode this build cannot read;
24
+ * the other two are the harness's own split between a route a restart can
25
+ * resume (`continuable`) and one it cannot.
26
+ */
27
+ readonly mode: 'one-shot' | 'external' | 'continuable' | 'unsupported';
28
+ }
29
+ /** One branch a walk reached and could not read. */
30
+ export interface UnreadBranch {
31
+ readonly id: SessionId;
32
+ /**
33
+ * `corrupt` and `unavailable` mean the branch's own catalog was not read, so
34
+ * the members under it are unknown. `unsupported` means the parent's catalog
35
+ * records a mode this build cannot read; that branch was still traversed, and
36
+ * what it holds is known — but no restart can resume through it.
37
+ */
38
+ readonly reason: 'corrupt' | 'unsupported' | 'unavailable';
39
+ }
40
+ /** What one session's tree walk found. */
41
+ export interface TreeWalk {
42
+ /**
43
+ * Catalog descendants in pre-order, direct children first and each child's
44
+ * own children after it. A missing subagent service leaves this empty.
45
+ */
46
+ readonly members: readonly TreeMember[];
47
+ /**
48
+ * Branches the walk reached and could not fully read. A branch named here may
49
+ * hold members nobody can see, so it is never read as "no members".
50
+ */
51
+ readonly unread: readonly UnreadBranch[];
52
+ /**
53
+ * Whether the walk itself failed, so even the branches are unknown. Named
54
+ * separately from {@link unread}, which lists the branches of a walk that ran.
55
+ */
56
+ readonly unreadWhole: boolean;
57
+ }
58
+ /**
59
+ * Read the subagent tree under one session.
60
+ *
61
+ * A failure to read a branch is reported as unread rather than as an empty
62
+ * tree: the difference is what keeps a press from claiming it registered a tree
63
+ * it never saw, and keeps a status answer from calling itself safe behind an
64
+ * unknown branch.
65
+ * @param ctx - host context carrying the optional subagent service.
66
+ * @param rootSessionId - the session whose descendants are requested.
67
+ * @param signal - cancellation for the catalog walk.
68
+ * @returns the descendants found and what of the walk could not be read.
69
+ * @throws the cancellation reason when `signal` aborts the walk.
70
+ */
71
+ export declare function walkDescendants(ctx: Context, rootSessionId: SessionId, signal?: AbortSignal): Promise<TreeWalk>;
@@ -0,0 +1,121 @@
1
+ /**
2
+ * The morning decision list: every session that did not stop cleanly, the facts
3
+ * its own log carries about where it stopped, and the listed verbs the user can
4
+ * take on it.
5
+ *
6
+ * A session gets here by NOT being on the clean path. A record whose phase is
7
+ * `safe` is woken silently by `./resume.ts` and never appears here; the other
8
+ * three phases describe work nobody can vouch for, and guessing on them would
9
+ * spend the owner's money on a guess. This module is the other half of that
10
+ * rule, not a second copy of it: the reading is taken from the session's own
11
+ * stored log through a read handle that claims no ownership and writes nothing,
12
+ * so asking what happened cannot itself change what happened.
13
+ *
14
+ * WHAT ONE READ COSTS. The list is read again on every command-registry change
15
+ * while the panel is open, and what it publishes is about the end of a log that
16
+ * only grows, so `./coldlog.ts` bounds each row's read to that end. A row whose
17
+ * facts the bound cannot hold reports itself unreadable rather than publishing
18
+ * a fragment.
19
+ *
20
+ * WHAT A ROW REPORTS. "Where it stopped" is the last event of the stored log
21
+ * with the turn and step it belongs to. "Which tool was in flight" is the
22
+ * `tool/call` events that no durable `tool/result` answers — a call event is
23
+ * only written once the loop reached the dispatch, so an unanswered one is
24
+ * exactly a tool the real world ran and the log never heard back from. The
25
+ * harness turns each of those into a synthetic `TOOL_OUTCOME_UNKNOWN` error
26
+ * result when it next reads the log; this module derives the same answer from
27
+ * the stored events instead of writing it back. Nothing here is inferred from
28
+ * the fact that the session is listed.
29
+ *
30
+ * WHAT THE ROW PROMISES. `wake` says the host can hand this session the request
31
+ * it owes, and the wake that keeps that promise is `./resume.ts`'s. Both read
32
+ * one rule from `./history.ts` over the same derivation the loop reads, so a
33
+ * promise this list publishes is a promise that wake keeps. When the log cannot
34
+ * be folded into that derivation, the promise is withheld and the reading is
35
+ * reported; a withheld promise costs a user nothing, a broken one spends their
36
+ * money.
37
+ *
38
+ * WHO MAY DECIDE. A decision names its target as command input, and the command
39
+ * channel carries no origin of its own, so this list acts only on rows its most
40
+ * recent read published to the calling session: the caller's own read is what
41
+ * makes a target actionable. Anything else is refused, not looked up.
42
+ *
43
+ * TWO OF THE FIVE VERBS PUT THE SESSION BACK ON THE CLEAN PATH. Continue and
44
+ * continue-with-the-note go through `ResumePath.decideUnclean`, which activates
45
+ * the session, wakes it and drops the durable record before the gate opens.
46
+ *
47
+ * THE OTHER THREE TOUCH NOTHING. Leave writes nothing at all: the record stays,
48
+ * the session stays held, and the row is still on tomorrow's list. Review
49
+ * answers without activating anything or writing anything — opening a session
50
+ * to read it is the user's own action in their session history, and starting an
51
+ * agent on their behalf is precisely what they declined. Goal flips the row's
52
+ * own re-arm opt-out: it is the user path for the one thing a resume can spend
53
+ * without the user watching it, and it takes effect on whatever resume comes
54
+ * next. All five carry the same binding — the row must be one this caller was
55
+ * shown — because each changes, or declines to change, durable state of a
56
+ * parked session.
57
+ * @module dsh-pause-session/triage
58
+ */
59
+ import type { Context } from '@deepseek-ai/cordis';
60
+ import type { SessionId } from '@deepseek-ai/dsh-session';
61
+ import type { CommandResult } from '@deepseek-ai/dsh-commands';
62
+ import type { ParkRegistry } from './registry.js';
63
+ import type { ResumePath } from './resume.js';
64
+ import type { TriageAction, TriageList } from './shared.js';
65
+ /** Result copy for a decision the list itself could not carry out. */
66
+ export declare const TRIAGE_FAILED_TEXT = "pause could not carry out that decision; the session is exactly as it was.";
67
+ /** Result copy for leaving one listed session alone. */
68
+ export declare const TRIAGE_LEFT_TEXT = "pause left this session paused; it is still on the list.";
69
+ /** Result copy for a decision aimed at a session that is not on the list. */
70
+ export declare const TRIAGE_NOT_LISTED_TEXT = "pause has no unfinished pause for this session.";
71
+ /**
72
+ * Result copy for a decision aimed at a row the calling session was not shown.
73
+ * The list is the only thing that legitimizes a target, so a target nobody read
74
+ * is refused rather than acted on.
75
+ */
76
+ export declare const TRIAGE_UNSHOWN_TEXT: string;
77
+ /**
78
+ * Model-facing text that goes with a wake when the user chooses to continue
79
+ * with a note.
80
+ *
81
+ * It is written the way the harness writes its own recovery text: the same two
82
+ * facts the synthetic tool result states (the call's outcome was never recorded;
83
+ * verify before retrying anything with side effects), in the same voice, with no
84
+ * mention of the stop mechanism. The harness's own version lives in the tool
85
+ * result for that call, which is why this one does not repeat the call's name —
86
+ * it warns about the step as a whole, and the specific result sits directly
87
+ * above it in the history.
88
+ */
89
+ export declare const UNKNOWN_OUTCOME_NOTE: string;
90
+ /** What mounting the decision list hands back. */
91
+ export interface TriageListService {
92
+ /**
93
+ * Read the list for one calling session, and record the rows it was shown.
94
+ * @param caller - the session the read was addressed to.
95
+ * @param signal - cancellation for the stored-log reads.
96
+ * @returns every session that did not stop cleanly, with the facts its own log carries.
97
+ */
98
+ read(caller: SessionId, signal?: AbortSignal): Promise<TriageList>;
99
+ /**
100
+ * Carry out one decision on one listed session, for the caller that read it.
101
+ * @param caller - the session the decision was addressed to.
102
+ * @param sessionId - the listed session to act on.
103
+ * @param action - which of the listed decisions was taken.
104
+ * @param signal - cancellation for the cold load and setup.
105
+ * @returns the outcome for whoever asked.
106
+ */
107
+ decide(caller: SessionId, sessionId: SessionId, action: TriageAction, signal?: AbortSignal): Promise<CommandResult>;
108
+ }
109
+ /**
110
+ * Mount the decision list over the durable registry and the clean resume path.
111
+ *
112
+ * The list is the registry's own complement: it asks for every record whose
113
+ * phase is not `safe`, so a session that cleaned up is off the list by the same
114
+ * fact that puts it on the silent path, and nothing has to be reconciled.
115
+ * @param ctx - host context carrying the optional persistence service.
116
+ * @param registry - the durable list of park outcomes.
117
+ * @param resumePath - the path all three resuming decisions go through.
118
+ * @param windowEvents - how many events of each stored log one read may fold.
119
+ * @returns the list read and the decision verbs.
120
+ */
121
+ export declare function mountTriageList(ctx: Context, registry: ParkRegistry, resumePath: ResumePath, windowEvents?: number): TriageListService;
package/locale/en.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "Pause Session",
4
+ "description": "Pause every running session and its subagents at a safe point, then resume them later without losing the work in flight."
5
+ }
6
+ }
package/locale/zh.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "\u6682\u505c\u4f1a\u8bdd",
4
+ "description": "\u5728\u5b89\u5168\u70b9\u6682\u505c\u6240\u6709\u8fd0\u884c\u4e2d\u7684\u4f1a\u8bdd\u53ca\u5176\u5b50\u4ee3\u7406\uff0c\u4e4b\u540e\u518d\u4ece\u4e2d\u65ad\u5904\u6062\u590d\uff0c\u4e0d\u4e22\u5931\u6b63\u5728\u6267\u884c\u7684\u5de5\u4f5c\u3002"
5
+ }
6
+ }