@itookit/dsht 0.3.4 → 0.3.8

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 (42) hide show
  1. package/README.i18n.yaml +2 -2
  2. package/README.md +4 -3
  3. package/README.zh.md +4 -3
  4. package/dist/cli/dsht.js +5 -2
  5. package/dist/controller/controller.d.ts +113 -1
  6. package/dist/controller/controller.js +145 -2
  7. package/dist/cost/controller.d.ts +5 -0
  8. package/dist/cost/controller.js +2 -1
  9. package/dist/cost/scanner.d.ts +4 -2
  10. package/dist/cost/scanner.js +6 -3
  11. package/dist/session/controller.d.ts +150 -1
  12. package/dist/session/controller.js +388 -29
  13. package/dist/session/history.d.ts +21 -1
  14. package/dist/session/history.js +15 -0
  15. package/dist/session/index.d.ts +2 -0
  16. package/dist/session/index.js +1 -0
  17. package/dist/session/info.d.ts +262 -0
  18. package/dist/session/info.js +326 -0
  19. package/dist/session/transcript.d.ts +37 -1
  20. package/dist/session/transcript.js +73 -0
  21. package/dist/shell/controller.d.ts +67 -0
  22. package/dist/shell/controller.js +126 -0
  23. package/dist/shell/index.d.ts +5 -0
  24. package/dist/shell/index.js +3 -0
  25. package/dist/shell/runner.d.ts +28 -0
  26. package/dist/shell/runner.js +108 -0
  27. package/dist/state.d.ts +3 -2
  28. package/dist/state.js +2 -2
  29. package/dist/ui/app.js +206 -177
  30. package/dist/ui/chat/history-view.js +1 -1
  31. package/dist/ui/chat/shell-view.d.ts +34 -0
  32. package/dist/ui/chat/shell-view.js +111 -0
  33. package/dist/ui/chat/status.js +4 -4
  34. package/dist/ui/commands/parse.d.ts +5 -0
  35. package/dist/ui/commands/parse.js +9 -0
  36. package/dist/ui/dialogs/index.d.ts +3 -6
  37. package/dist/ui/theme/index.d.ts +5 -0
  38. package/dist/ui/theme/index.js +2 -1
  39. package/dsht-m.png +0 -0
  40. package/package.json +1 -1
  41. package/dist/ui/input/history.d.ts +0 -19
  42. package/dist/ui/input/history.js +0 -43
@@ -3,6 +3,8 @@ import { type Json, type ObjectValue } from '../transport/wire.ts';
3
3
  import type { ControllerStore, State } from '../state.ts';
4
4
  import type { HistoryLimits } from './memory.ts';
5
5
  import { type FileReference } from './references.ts';
6
+ import { type ComposerState, type InteractionState, type ModelState, type OptionState, type PanelState, type ReferenceState, type ViewState } from './info.ts';
7
+ import type { Reasoning } from './history.ts';
6
8
  import { Transcript } from './transcript.ts';
7
9
  import type { ConnectionView } from './connection-view.ts';
8
10
  import type { HistorySearch, RemovalTarget } from './types.ts';
@@ -14,7 +16,13 @@ export declare class SessionController {
14
16
  private readonly historyLimits;
15
17
  private follow;
16
18
  private interactions;
17
- private historyPinned;
19
+ /** Cancels the background prompt backfill of the previous selection. */
20
+ private promptBackfill?;
21
+ /** Prompts of sessions this process has already read, so re-opening one costs no page request. */
22
+ private readonly promptCache;
23
+ /** Prompt index, composer and reading view of the selected session; the instance `State.session` exposes. */
24
+ private get info();
25
+ private get prompts();
18
26
  private stoppingSession?;
19
27
  private interruptTask;
20
28
  private admission;
@@ -113,6 +121,15 @@ export declare class SessionController {
113
121
  switchSession(query?: string): Promise<void>;
114
122
  /** Prompt for a host path without starting a local agent. */
115
123
  enterPath(): void;
124
+ /** Adopt the workspace whose registered path contains the directory this client runs in.
125
+ *
126
+ * Longest path wins, so a workspace nested in another is preferred, and the comparison is on whole
127
+ * path segments so `/srv/app-old` cannot match `/srv/app`. A remote host's paths usually differ
128
+ * from the client's, in which case nothing matches and the picker stays exactly as before.
129
+ * @param directory - Directory this client was started in.
130
+ * @returns The adopted workspace's id, or undefined when none matches.
131
+ */
132
+ adoptLocalWorkspace(directory: string): string | undefined;
116
133
  /** Register a host directory and move to its session picker.
117
134
  * @param path - Absolute directory path on the host.
118
135
  */
@@ -185,10 +202,142 @@ export declare class SessionController {
185
202
  */
186
203
  dismissQuestion(): Promise<void>;
187
204
  /** Add a page before the retained window using its fixed opening cut.
205
+ *
206
+ * Reclamation is deliberately not pinned here. Every caller that needs the fetched page to
207
+ * survive is already covered by the view: scrolling back sets a scroll position, `/think` opens a
208
+ * panel, and a recall page folds its prompts into the index before this resolves. A pin set here
209
+ * had no clearing edge, so after one recall page the history budget silently stopped applying for
210
+ * the rest of the session while every following page kept adding records.
188
211
  * @param signal - Cancels local paging without interrupting the remote agent.
189
212
  * @param transcript - Transcript to extend; defaults to the live one.
190
213
  */
191
214
  older(signal?: AbortSignal, transcript?: Transcript): Promise<void>;
215
+ /** Recall one step through the session's prompt index; navigation never touches the network.
216
+ * @param direction - Negative for older input, positive for newer input.
217
+ * @param current - Composer content before recall began, restored at the newest position.
218
+ * @returns The recalled prompt, or the unsent draft.
219
+ */
220
+ recall(direction: -1 | 1, current: string): string;
221
+ /** Composer draft, caret and parked draft, as the selected session holds them. */
222
+ get composer(): ComposerState;
223
+ /** Replace the composer text and caret, publishing only when either actually changed. */
224
+ setComposer(draft: string, cursor?: number): void;
225
+ /** Move the caret without changing the text. */
226
+ setComposerCursor(cursor: number): void;
227
+ /** Move a non-empty draft aside while a dialog owns the keyboard. */
228
+ parkComposer(): void;
229
+ /** Give a parked draft back once no dialog needs the keyboard. */
230
+ restoreComposer(): void;
231
+ /** How the selected session's record is being read right now. */
232
+ get view(): ViewState;
233
+ /** Show a detached history window, releasing the one it replaces.
234
+ * @param window - Record to display, or undefined to return to the live transcript.
235
+ */
236
+ setViewWindow(window?: Transcript): void;
237
+ /** Move the reader's position inside the displayed record.
238
+ * @param scroll - Rows scrolled back from the live end.
239
+ */
240
+ setScroll(scroll: number): void;
241
+ /** Replace the set of expanded reasoning blocks, keyed by message sequence.
242
+ * @param folds - Sequences to expand beyond the default fold.
243
+ */
244
+ setFolds(folds: ReadonlySet<number>): void;
245
+ /** Set the fold mode of the live attempt's completed reasoning.
246
+ * @param reasoning - `row` to fold, `full` to keep the streamed text.
247
+ */
248
+ setLiveReasoning(reasoning: Reasoning): void;
249
+ /** Local answer state for the selected session's pending waterfalls. */
250
+ get interaction(): InteractionState;
251
+ /** Replace the partly collected answers, keyed by the waterfall event id.
252
+ * @param answers - Answers collected so far, by event id.
253
+ */
254
+ setAnswers(answers: Record<string, ObjectValue[]>): void;
255
+ /** Replace the pending question's option keyboard state.
256
+ * @param option - Highlighted option, toggled labels and free-text mode; undefined clears it.
257
+ */
258
+ setOption(option?: OptionState): void;
259
+ /** Replace the pending approval's selected row.
260
+ * @param approval - Selected approval row; undefined clears the highlight.
261
+ */
262
+ setApproval(approval?: InteractionState['approval']): void;
263
+ /** Composer-adjacent `@` reference menu state. */
264
+ get reference(): ReferenceState;
265
+ /** Highlight one row of the open reference menu.
266
+ * @param index - Row index into the current matches.
267
+ */
268
+ setReferenceIndex(index: number): void;
269
+ /** Remember the draft that dismissed the reference menu, so it does not reopen while it stands.
270
+ * @param draft - Composer text at dismissal, or undefined to allow the menu again.
271
+ */
272
+ setReferenceDismissed(draft?: string): void;
273
+ /** Panels the selected session has open. */
274
+ get panels(): PanelState;
275
+ /** Show or hide the reasoning panel.
276
+ * @param open - Whether `/think` is open.
277
+ */
278
+ openThoughts(open: boolean): void;
279
+ /** Show or hide the pending-input panel.
280
+ * @param open - Whether `/queue` is open.
281
+ */
282
+ openQueue(open: boolean): void;
283
+ /** Show the model dialog at one step, or close it.
284
+ * @param model - Catalog plus the provider or model being inspected; undefined closes the dialog.
285
+ */
286
+ setModelPanel(model?: ModelState): void;
287
+ /** Show the history or content-search dialog, or close it.
288
+ * @param history - Query, content-search mode and matches; undefined closes the dialog.
289
+ */
290
+ setHistoryPanel(history?: PanelState['history']): void;
291
+ /** Show the host session-search results, or close them.
292
+ * @param search - Query, results and truncation flag; undefined closes the dialog.
293
+ */
294
+ setSearchPanel(search?: PanelState['search']): void;
295
+ /** Remember a locally submitted command, which never becomes a durable session record. */
296
+ recordRecall(value: string): void;
297
+ /** Leave recall navigation because the composer was edited or replaced. */
298
+ resetRecall(): void;
299
+ /** Whether recall is parked on the oldest prompt it retains in memory. */
300
+ get recallAtOldest(): boolean;
301
+ /** How many prompts the session retains for recall. */
302
+ get recallLength(): number;
303
+ /** Whether an older prompt is reachable at all: shed from the window, or still on the host. */
304
+ get recallHasOlder(): boolean;
305
+ /** Recover older prompts from the loaded window before spending a page request.
306
+ *
307
+ * The transcript window can still hold prompts the index's budgets evicted, so a backward step
308
+ * refills from memory first and only then asks the caller to page. That is what keeps recall
309
+ * complete across submissions, where the previous buffer lost them at the eviction boundary.
310
+ * @returns Whether any older prompt was recovered.
311
+ */
312
+ refillRecall(): boolean;
313
+ /** Seed recall from a complete cached entry, so an open that follows a scan costs no request.
314
+ * @param sessionId - Session being opened.
315
+ * @returns Whether the cache covered this session.
316
+ */
317
+ private adoptCachedPrompts;
318
+ /** Fold one history page the cost scan already read into the prompt cache.
319
+ *
320
+ * The scan reads every session's whole history on connect, so this is where two readers stop
321
+ * paying twice: it hands over pages it already has, and an open that follows reads the cache.
322
+ * @param sessionId - Session the page belongs to.
323
+ * @param records - Raw records of one scanned page.
324
+ */
325
+ rememberScanPage(sessionId: string, records: readonly Json[]): void;
326
+ /** Report that the scanned session's history was read to its beginning.
327
+ * @param sessionId - Session the scan finished.
328
+ */
329
+ rememberScanDone(sessionId: string): void;
330
+ /** Fold every prompt the host still holds into the recall index, in the background.
331
+ *
332
+ * Session start delivers only the newest window, so without this the arrows could reach older
333
+ * prompts but not show them without paging first. Each page is parsed into a temporary transcript
334
+ * and only its prompts are kept, so the live record, its memory window and the row cache never
335
+ * grow. The walk is bounded and the next selection cancels it; anything past the bound is still
336
+ * reachable through the lazy backward step.
337
+ * @param sessionId - Session being opened.
338
+ * @param selection - Selector generation that must still be current.
339
+ */
340
+ private backfillPrompts;
192
341
  /** Search one page at a time, preserving only the first 200 matches and releasing temporary content.
193
342
  * @param query - Literal, case-insensitive text including folded reasoning.
194
343
  * @param signal - Cancels HTTP and processing without cancelling the agent.