dsh-pause-session 0.1.0 → 0.2.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,67 @@
1
+ /**
2
+ * User-facing copy and result shapes for the clean resume and tree release.
3
+ * @module dsh-pause-session/resume-text
4
+ */
5
+ import type { SessionId } from '@deepseek-ai/dsh-session';
6
+ import type { PauseAnswer } from './shared.js';
7
+ /** Route knowledge the clean resume path needs. */
8
+ export interface ResumeOptions {
9
+ /** Provider routes whose request conversion drops an empty user message. */
10
+ readonly silentWakeRoutes: readonly string[];
11
+ }
12
+ /**
13
+ * The one wake content a route that keeps an empty user message is given.
14
+ */
15
+ export declare const WAKE_MARKER = "[pause: resumed from a pause]";
16
+ /** How one resume asks the loop for the request it owes the session. */
17
+ export type WakeRequest = {
18
+ readonly kind: 'silent';
19
+ } | {
20
+ readonly kind: 'message';
21
+ readonly text: string;
22
+ } | {
23
+ readonly kind: 'none';
24
+ };
25
+ /** Result copy for a resumed session; the model never sees it. */
26
+ export declare const RESUMED_TEXT = "This session resumed from where it paused.";
27
+ /** Result copy for a registered session whose park did not finish cleanly. */
28
+ export declare const UNCLEAN_TEXT: string;
29
+ /** Result copy when nothing is parked under that session. */
30
+ export declare const NOT_PARKED_TEXT = "pause has no pause recorded for this session.";
31
+ /** Result copy for a session that is parked but could not be loaded back. */
32
+ export declare const ACTIVATION_FAILED_TEXT = "pause could not reopen this session, so it stayed paused.";
33
+ /** Result copy for a one-shot subagent route. */
34
+ export declare const UNRESUMABLE_TEXT = "pause did not resume this session: it is a one-shot subagent route and cannot be resumed.";
35
+ /** Result copy for the review decision. */
36
+ export declare const REVIEW_TEXT: string;
37
+ /** Copy for one goal opt-out change. */
38
+ export declare const REARM_GOAL_ON_TEXT = "pause will re-open this session's goal when it resumes it.";
39
+ export declare const REARM_GOAL_OFF_TEXT = "pause will leave this session's goal closed when it resumes it.";
40
+ /** Why one record did not produce a running session. */
41
+ export type ResumeRefusal = 'not-parked' | 'not-clean' | 'activation-failed' | 'unrecorded' | 'not-activated' | 'unresumable';
42
+ /** What one resume attempt did. */
43
+ export interface ResumeOutcome {
44
+ readonly sessionId: SessionId;
45
+ readonly resumed: boolean;
46
+ readonly refusal?: ResumeRefusal;
47
+ }
48
+ /** One resume attempt plus the answer the caller receives. */
49
+ export interface ResumeAttempt extends ResumeOutcome {
50
+ readonly answer: PauseAnswer;
51
+ }
52
+ /** What releasing one session's registered tree did. */
53
+ export interface ReleaseTreeOutcome {
54
+ readonly members: number;
55
+ readonly resumed: number;
56
+ readonly refusals: readonly {
57
+ readonly sessionId: SessionId;
58
+ readonly refusal: ResumeRefusal;
59
+ }[];
60
+ readonly answer: PauseAnswer;
61
+ }
62
+ /**
63
+ * How one tree-wide release answers the person who pressed it.
64
+ * @param released - the sessions this release covered, in release order.
65
+ * @returns one sentence about what came back and what did not.
66
+ */
67
+ export declare function summarizeTreeRelease(released: readonly ResumeAttempt[]): string;
@@ -32,10 +32,12 @@
32
32
  * @module dsh-pause-session/resume
33
33
  */
34
34
  import type { Context } from '@deepseek-ai/cordis';
35
- import type { CommandResult } from '@deepseek-ai/dsh-commands';
36
35
  import type { SessionId } from '@deepseek-ai/dsh-session';
37
36
  import type { PauseGate } from './gate.js';
38
37
  import type { ParkRegistry } from './registry.js';
38
+ import type { PauseAnswer } from './shared.js';
39
+ export * from './resume-text.js';
40
+ import type { ReleaseTreeOutcome, ResumeAttempt, ResumeOptions, WakeRequest } from './resume-text.js';
39
41
  declare module '@deepseek-ai/dsh-llm' {
40
42
  interface MessageSourceMap {
41
43
  /**
@@ -49,78 +51,13 @@ declare module '@deepseek-ai/dsh-llm' {
49
51
  };
50
52
  }
51
53
  }
52
- /**
53
- * The one wake content a route that keeps an empty user message is given. It
54
- * names its producer, because it lands in the same user turn as the input the
55
- * model owes an answer to and must not read as part of it.
56
- */
57
- export declare const WAKE_MARKER = "[pause: resumed from a pause]";
58
- /**
59
- * How one resume asks the loop for the request it owes the session:
60
- *
61
- * - `silent`: the clean path's wake — an empty input on a route the
62
- * composition declared silent, and the visible marker on any other route.
63
- * - `message`: the decision list's "continue, and say the tool outcome is
64
- * unknown" — user-visible text on the wire by construction, and the only
65
- * resume that is not invisible.
66
- * - `none`: no wake at all. This is what "leave it for me to read" costs: the
67
- * session is not activated, nothing is asked of the model, and the park is
68
- * exactly as it was.
69
- */
70
- export type WakeRequest = {
71
- readonly kind: 'silent';
72
- } | {
73
- readonly kind: 'message';
74
- readonly text: string;
75
- } | {
76
- readonly kind: 'none';
77
- };
78
- /** Result copy for a resumed session; the model never sees it. */
79
- export declare const RESUMED_TEXT = "This session resumed from where it paused.";
80
- /**
81
- * Result copy for a registered session this path refuses: its durable state is
82
- * not the outcome of a completed park, so waking it would be a guess.
83
- */
84
- export declare const UNCLEAN_TEXT: string;
85
- /** Result copy when nothing is parked under that session. */
86
- export declare const NOT_PARKED_TEXT = "pause has no pause recorded for this session.";
87
- /** Result copy for a session that is parked but could not be loaded back. */
88
- export declare const ACTIVATION_FAILED_TEXT = "pause could not reopen this session, so it stayed paused.";
89
- /** Result copy for a one-shot subagent route: its Session exists, but no resume may reactivate it. */
90
- export declare const UNRESUMABLE_TEXT = "pause did not resume this session: it is a one-shot subagent route and cannot be resumed.";
91
- /**
92
- * Result copy for the review decision. It is the one answer that promises
93
- * nothing happened, because opening a session to read it is the user's own
94
- * action in their session list — and activating its agent here would start a
95
- * session they asked only to look at.
96
- */
97
- export declare const REVIEW_TEXT: string;
98
- /** Result copy for a change the durable registry refused to record. */
99
- export declare const UNRECORDED_TEXT = "pause could not write the pause registry, so it did not change the pause state.";
100
- /** Copy for one goal opt-out change. */
101
- export declare const REARM_GOAL_ON_TEXT = "pause will re-open this session's goal when it resumes it.";
102
- export declare const REARM_GOAL_OFF_TEXT = "pause will leave this session's goal closed when it resumes it.";
103
- /** Why one record did not produce a running session. */
104
- export type ResumeRefusal = 'not-parked' | 'not-clean' | 'activation-failed' | 'unrecorded' | 'not-activated' | 'unresumable';
105
- /** What one resume attempt did. */
106
- export interface ResumeOutcome {
107
- readonly sessionId: SessionId;
108
- /** Whether the session is now running from the point it stopped. */
109
- readonly resumed: boolean;
110
- /** Present exactly when `resumed` is false. */
111
- readonly refusal?: ResumeRefusal;
112
- }
113
- /** One resume attempt plus the answer the command that asked for it receives. */
114
- export interface ResumeAttempt extends ResumeOutcome {
115
- readonly answer: CommandResult;
116
- }
117
54
  /** How this path is wired into the session control that owns the pause state. */
118
55
  export interface ResumeDeps {
119
56
  /**
120
57
  * Take a live session's pause back: the durable record goes first, then the
121
58
  * gate. Owned by the session control so there is one release order.
122
59
  */
123
- release(sessionId: SessionId, text: string): Promise<CommandResult>;
60
+ release(sessionId: SessionId, text: string): Promise<PauseAnswer>;
124
61
  /**
125
62
  * Whether the pause this process holds was adopted from the registry rather
126
63
  * than pressed here. Only an adopted pause is a restart: a press this process
@@ -128,16 +65,6 @@ export interface ResumeDeps {
128
65
  */
129
66
  adopted(sessionId: SessionId): boolean;
130
67
  }
131
- /** Route knowledge this path needs from the composition. */
132
- export interface ResumeOptions {
133
- /**
134
- * Provider routes whose request conversion drops an empty user message, so an
135
- * empty wake never reaches the model. Deployment-owned because it is a
136
- * property of the adapter behind each route, and a third-party plugin cannot
137
- * introspect an adapter.
138
- */
139
- readonly silentWakeRoutes: readonly string[];
140
- }
141
68
  /** The clean resume path, as the session control drives it. */
142
69
  export interface ResumePath {
143
70
  /**
@@ -177,7 +104,7 @@ export interface ResumePath {
177
104
  * @param rearmGoal - whether the clean resume path may re-arm its goal.
178
105
  * @returns the copy for whoever asked.
179
106
  */
180
- setRearmGoal(sessionId: SessionId, rearmGoal: boolean): Promise<CommandResult>;
107
+ setRearmGoal(sessionId: SessionId, rearmGoal: boolean): Promise<PauseAnswer>;
181
108
  /**
182
109
  * Release one parked session and the registered members of its tree: the
183
110
  * counterpart of a press that registered a whole tree.
@@ -187,28 +114,6 @@ export interface ResumePath {
187
114
  */
188
115
  releaseTree(sessionId: SessionId, signal?: AbortSignal): Promise<ReleaseTreeOutcome>;
189
116
  }
190
- /** What releasing one session's registered tree did. */
191
- export interface ReleaseTreeOutcome {
192
- /** How many sessions this release covered: the session plus its registered descendants. */
193
- readonly members: number;
194
- /** How many of them are running again. */
195
- readonly resumed: number;
196
- /** How many could not be resumed, and why the release did not take them back. */
197
- readonly refusals: readonly {
198
- readonly sessionId: SessionId;
199
- readonly refusal: ResumeRefusal;
200
- }[];
201
- /** The copy for whoever pressed the release. */
202
- readonly answer: CommandResult;
203
- }
204
- /**
205
- * How one tree-wide release answers the person who pressed it. One release, one
206
- * sentence about all of it: what came back, and — by name, because those rows
207
- * are what the morning list is for — what did not.
208
- * @param released - the sessions this release covered, in release order.
209
- * @returns the result text, e.g. `pause resumed 2 sessions from where they stopped; "child" did not pause completely`.
210
- */
211
- export declare function summarizeTreeRelease(released: readonly ResumeAttempt[]): string;
212
117
  /**
213
118
  * Build the clean resume path.
214
119
  * @param ctx - host context carrying the agent store, the session store, and the goal service when one is mounted.
@@ -1,81 +1,22 @@
1
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.
2
+ * The identities both halves of dsh-pause-session name, the phase vocabulary
3
+ * they share, and the one spelling a host log line gives a caught value.
4
4
  *
5
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.
6
+ * so this module imports nothing. The native Remote payloads are the live
7
+ * vocabulary; there is no command encoding or slash-command surface here.
23
8
  * @module dsh-pause-session/shared
24
9
  */
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: ";
10
+ /** Result copy for a press or a release the durable registry refused to record. */
11
+ export declare const UNRECORDED_TEXT = "pause could not write the pause registry, so it did not change the pause state.";
12
+ /**
13
+ * One user-facing answer from an action. The controls render `text` verbatim;
14
+ * `kind` only says whether the press succeeded.
15
+ */
16
+ export interface PauseAnswer {
17
+ readonly kind: 'success' | 'error';
18
+ readonly text: string;
19
+ }
79
20
  /**
80
21
  * One log line's text for a caught value.
81
22
  * @param error - the caught value.
@@ -137,24 +78,11 @@ export interface ParkStatus {
137
78
  */
138
79
  readonly rearmGoal?: boolean;
139
80
  }
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: ";
81
+ /** One JSON snapshot: the whole-app verdict plus every live paused session. */
82
+ export interface PauseSnapshot {
83
+ readonly global: GlobalStatus;
84
+ readonly sessions: Readonly<Record<string, ParkStatus>>;
85
+ }
158
86
  /** The whole-app answer to "can I close the lid?". */
159
87
  export type GlobalVerdict = 'idle' | 'waiting' | 'safe';
160
88
  /** A surface the whole-app report could not read at all. */
@@ -193,7 +121,7 @@ export interface GlobalStatus {
193
121
  readonly parkedAt?: string;
194
122
  /**
195
123
  * 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
124
+ * steps. Their park point is announced on the native stream the park
197
125
  * registers, so a reader has nothing to watch here.
198
126
  */
199
127
  readonly draining: readonly string[];
@@ -221,25 +149,6 @@ export interface GlobalStatus {
221
149
  /** Whole surfaces the report could not read, so their emptiness is not a fact. */
222
150
  readonly blind: readonly GlobalBlindSpot[];
223
151
  }
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
152
  /** How one decision-list row was read out of the session's own stored log. */
244
153
  export type TriageReading = 'read' | 'unreadable';
245
154
  /**
@@ -310,15 +219,3 @@ export interface TriageList {
310
219
  export declare const TRIAGE_ACTIONS: readonly ["continue", "note", "review", "leave", "goal"];
311
220
  /** One decision the list offers. */
312
221
  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,29 @@
1
+ /**
2
+ * Pure projection of the durable park and each live tree into the native
3
+ * snapshot. This module owns the phase fold and the goal opt-out; it does not
4
+ * press, release, or decide anything.
5
+ * @module dsh-pause-session/snapshot
6
+ */
7
+ import type { Context } from '@deepseek-ai/cordis';
8
+ import type { SessionId } from '@deepseek-ai/dsh-session';
9
+ import type { ParkWatch } from './park.js';
10
+ import type { ParkRegistry } from './registry.js';
11
+ import type { TreeWalk } from './tree.js';
12
+ import type { ParkMark } from './park-state.js';
13
+ import type { GlobalStatus, PauseSnapshot } from './shared.js';
14
+ /** What the snapshot projection needs from the control. */
15
+ export interface SnapshotDeps {
16
+ readonly ctx: Context;
17
+ readonly marks: ReadonlyMap<SessionId, ParkMark>;
18
+ readonly watch: ParkWatch;
19
+ readonly registry: ParkRegistry;
20
+ /** Read the whole-app aggregate, reusing the walks this projection already paid for. */
21
+ readGlobal(signal?: AbortSignal, walks?: ReadonlyMap<SessionId, TreeWalk>): Promise<GlobalStatus>;
22
+ }
23
+ /**
24
+ * Read every live mark and the whole-app aggregate in one pass.
25
+ * @param deps - the control-owned marks, watch, registry, and aggregate reader.
26
+ * @param signal - cancellation for the tree walks and aggregate.
27
+ * @returns the native snapshot.
28
+ */
29
+ export declare function readSnapshot(deps: SnapshotDeps, signal?: AbortSignal): Promise<PauseSnapshot>;
@@ -11,8 +11,8 @@
11
11
  * stored log through a read handle that claims no ownership and writes nothing,
12
12
  * so asking what happened cannot itself change what happened.
13
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
14
+ * WHAT ONE READ COSTS. The list is read when the panel opens and when a native
15
+ * action changes the park, and what it publishes is about the end of a log that
16
16
  * only grows, so `./coldlog.ts` bounds each row's read to that end. A row whose
17
17
  * facts the bound cannot hold reports itself unreadable rather than publishing
18
18
  * a fragment.
@@ -35,10 +35,10 @@
35
35
  * reported; a withheld promise costs a user nothing, a broken one spends their
36
36
  * money.
37
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.
38
+ * WHO MAY DECIDE. A decision carries the calling session and its target as wire
39
+ * input, so this list acts only on rows its most recent read published to the
40
+ * calling session: the caller's own read is what makes a target actionable.
41
+ * Anything else is refused, not looked up.
42
42
  *
43
43
  * TWO OF THE FIVE VERBS PUT THE SESSION BACK ON THE CLEAN PATH. Continue and
44
44
  * continue-with-the-note go through `ResumePath.decideUnclean`, which activates
@@ -58,12 +58,11 @@
58
58
  */
59
59
  import type { Context } from '@deepseek-ai/cordis';
60
60
  import type { SessionId } from '@deepseek-ai/dsh-session';
61
- import type { CommandResult } from '@deepseek-ai/dsh-commands';
62
61
  import type { ParkRegistry } from './registry.js';
63
62
  import type { ResumePath } from './resume.js';
64
63
  import type { TriageAction, TriageList } from './shared.js';
64
+ import type { PauseAnswer } from './shared.js';
65
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
66
  /** Result copy for leaving one listed session alone. */
68
67
  export declare const TRIAGE_LEFT_TEXT = "pause left this session paused; it is still on the list.";
69
68
  /** Result copy for a decision aimed at a session that is not on the list. */
@@ -104,7 +103,7 @@ export interface TriageListService {
104
103
  * @param signal - cancellation for the cold load and setup.
105
104
  * @returns the outcome for whoever asked.
106
105
  */
107
- decide(caller: SessionId, sessionId: SessionId, action: TriageAction, signal?: AbortSignal): Promise<CommandResult>;
106
+ decide(caller: SessionId, sessionId: SessionId, action: TriageAction, signal?: AbortSignal): Promise<PauseAnswer>;
108
107
  }
109
108
  /**
110
109
  * Mount the decision list over the durable registry and the clean resume path.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-pause-session",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "DSH plugin: pause every running session (and its subagents) at a safe point before you leave, then resume them the next morning as if nothing was interrupted.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -17,7 +17,19 @@
17
17
  "./cordis.patch.yml": "./cordis.patch.yml",
18
18
  "./package.json": "./package.json",
19
19
  "./locale/*.json": "./locale/*.json",
20
- "./icon": "./icon.svg"
20
+ "./icon": "./icon.svg",
21
+ "./typert": {
22
+ "types": "./lib/typert.host.d.ts",
23
+ "default": "./lib/typert.host.js"
24
+ },
25
+ "./remote": {
26
+ "types": "./lib/typert.remote-client.d.ts",
27
+ "default": "./lib/typert.remote-client.js"
28
+ },
29
+ "./types": {
30
+ "types": "./lib/types/remote.d.ts",
31
+ "default": "./lib/types/remote.js"
32
+ }
21
33
  },
22
34
  "files": [
23
35
  "lib/index.js",
@@ -34,16 +46,13 @@
34
46
  "cordis.patch.yml",
35
47
  "locale/*.json",
36
48
  "icon.svg",
37
- "docs/images/pause-controls.webp"
49
+ "docs/images/pause-controls.webp",
50
+ "lib/typert.host.js",
51
+ "lib/typert.host.d.ts",
52
+ "lib/typert.remote-client.js",
53
+ "lib/typert.remote-client.d.ts",
54
+ "lib/typert.remote-client.d.ts.map"
38
55
  ],
39
- "scripts": {
40
- "build:host": "tsc -p tsconfig.json",
41
- "build:client": "tsc -p tsconfig.client.json && tsdown",
42
- "build": "npm run build:host && npm run build:client && node scripts/trim-build-whitespace.mjs",
43
- "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.client.json --noEmit",
44
- "test": "vitest run",
45
- "verify": "npm run typecheck && npm run build && npm run test"
46
- },
47
56
  "dsh": {
48
57
  "bundle": {
49
58
  "patch": "./cordis.patch.yml"
@@ -66,7 +75,6 @@
66
75
  "@deepseek-ai/dsh-client-ui-conversation": "*",
67
76
  "@deepseek-ai/dsh-client-ui-renderer": "*",
68
77
  "@deepseek-ai/dsh-client-ui-session": "*",
69
- "@deepseek-ai/dsh-commands": "*",
70
78
  "@deepseek-ai/dsh-goal": "*",
71
79
  "@deepseek-ai/dsh-jobs": "*",
72
80
  "@deepseek-ai/dsh-llm": "*",
@@ -74,15 +82,16 @@
74
82
  "@deepseek-ai/dsh-subagent": "*",
75
83
  "@deepseek-ai/dsh-session": "*",
76
84
  "@deepseek-ai/dsh-session-query": "*",
77
- "@deepseek-ai/dsh-agent-preset-registry": "*"
85
+ "@deepseek-ai/dsh-agent-preset-registry": "*",
86
+ "@deepseek-ai/dsh-typert-protocol": "*"
78
87
  },
79
88
  "dependencies": {
80
89
  "zod": "4.4.3"
81
90
  },
82
91
  "devDependencies": {
83
92
  "@deepseek-ai/cordis": "link:../../deepseek-harness/vendor/cordis",
84
- "@deepseek-ai/cordis-plugin-include": "1.0.6",
85
- "@deepseek-ai/cordis-plugin-loader": "1.0.2",
93
+ "@deepseek-ai/cordis-plugin-include": "1.1.0",
94
+ "@deepseek-ai/cordis-plugin-loader": "1.1.0",
86
95
  "@deepseek-ai/dsh-agent": "link:../../deepseek-harness/packages/core/agent",
87
96
  "@deepseek-ai/dsh-agent-loop": "link:../../deepseek-harness/packages/core/agent-loop",
88
97
  "@deepseek-ai/dsh-agent-loop-testkit": "link:../../deepseek-harness/packages/test-support/agent-loop-testkit",
@@ -94,7 +103,6 @@
94
103
  "@deepseek-ai/dsh-client-ui-renderer": "link:../../deepseek-harness/packages/client/ui-renderer",
95
104
  "@deepseek-ai/dsh-client-ui-session": "link:../../deepseek-harness/packages/client/ui-session",
96
105
  "@deepseek-ai/dsh-client-ui-slots": "link:../../deepseek-harness/packages/client/ui-slots",
97
- "@deepseek-ai/dsh-commands": "link:../../deepseek-harness/packages/interaction/commands",
98
106
  "@deepseek-ai/dsh-goal": "link:../../deepseek-harness/packages/goal/goal",
99
107
  "@deepseek-ai/dsh-goal-round-driver": "link:../../deepseek-harness/packages/goal/goal-round-driver",
100
108
  "@deepseek-ai/dsh-jobs": "link:../../deepseek-harness/packages/jobs/jobs",
@@ -122,7 +130,9 @@
122
130
  "react": "^18.2.0",
123
131
  "tsdown": "0.22.2",
124
132
  "typescript": "^5.7.0",
125
- "vitest": "^3.0.0"
133
+ "vitest": "^3.0.0",
134
+ "@deepseek-ai/dsh-typert-protocol": "link:../../deepseek-harness/packages/typert/protocol",
135
+ "@deepseek-ai/dsh-typert-generator": "link:../../deepseek-harness/packages/typert/generator"
126
136
  },
127
137
  "license": "MIT",
128
138
  "engines": {
@@ -146,5 +156,14 @@
146
156
  ],
147
157
  "publishConfig": {
148
158
  "access": "public"
159
+ },
160
+ "scripts": {
161
+ "build:host": "tsc -p tsconfig.json",
162
+ "build:client": "tsc -p tsconfig.client.json && tsdown",
163
+ "build": "npm run generate:typert && npm run build:host && npm run build:client && node scripts/trim-build-whitespace.mjs",
164
+ "typecheck": "npm run generate:typert && tsc -p tsconfig.json --noEmit && tsc -p tsconfig.client.json --noEmit",
165
+ "test": "vitest run",
166
+ "verify": "npm run typecheck && npm run build && npm run test",
167
+ "generate:typert": "node scripts/generate-typert.mjs"
149
168
  }
150
- }
169
+ }