dsh-code 0.7.0 → 0.8.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.
Files changed (44) hide show
  1. package/README.en.md +20 -6
  2. package/README.md +20 -6
  3. package/lib/index.mjs +2685 -622
  4. package/lib/types/app.d.ts +77 -1
  5. package/lib/types/history.d.ts +15 -4
  6. package/lib/types/index.d.ts +48 -0
  7. package/lib/types/kernel-panels.d.ts +7 -0
  8. package/lib/types/permissions.d.ts +37 -0
  9. package/lib/types/presets.d.ts +2 -0
  10. package/lib/types/provider-settings.d.ts +144 -0
  11. package/lib/types/questions.d.ts +2 -0
  12. package/lib/types/render/animations.d.ts +8 -6
  13. package/lib/types/render/lines.d.ts +6 -0
  14. package/lib/types/render/markdown.d.ts +3 -3
  15. package/lib/types/render/projection.d.ts +95 -3
  16. package/lib/types/render/status.d.ts +26 -36
  17. package/lib/types/render/text.d.ts +14 -7
  18. package/lib/types/render/tool-detail.d.ts +3 -1
  19. package/lib/types/render/tool-preview.d.ts +4 -1
  20. package/lib/types/session-directory.d.ts +15 -0
  21. package/lib/types/store.d.ts +13 -2
  22. package/lib/types/version.d.ts +5 -0
  23. package/package.json +1 -1
  24. package/src/app.ts +847 -150
  25. package/src/approval.ts +11 -2
  26. package/src/history.ts +20 -5
  27. package/src/index.ts +402 -159
  28. package/src/kernel-panels.ts +45 -8
  29. package/src/permissions.ts +85 -0
  30. package/src/presets.ts +12 -0
  31. package/src/provider-settings.ts +520 -0
  32. package/src/questions.ts +15 -5
  33. package/src/render/animations.ts +32 -18
  34. package/src/render/lines.ts +21 -6
  35. package/src/render/markdown.ts +302 -4
  36. package/src/render/projection.ts +665 -10
  37. package/src/render/status.ts +68 -162
  38. package/src/render/text.ts +28 -9
  39. package/src/render/tool-detail.ts +81 -40
  40. package/src/render/tool-preview.ts +18 -2
  41. package/src/session-directory.ts +44 -5
  42. package/src/skills.ts +8 -4
  43. package/src/store.ts +26 -8
  44. package/src/version.ts +16 -0
package/src/approval.ts CHANGED
@@ -79,16 +79,24 @@ export function mountApprovalAnswerer(
79
79
 
80
80
  let resolved = false
81
81
  let settle!: (outcome: ApprovalOutcome) => void
82
+ const signal = request.signal
83
+ const onAbort = (): void => withdraw()
84
+ // Detach on every settle so an answered ask never retains a listener on
85
+ // the tool call's signal (long turns ask many times; each ask must let go).
86
+ const detachAbort = (): void => {
87
+ if (signal !== undefined) signal.removeEventListener('abort', onAbort)
88
+ }
82
89
  const withdraw = (): void => {
83
90
  if (resolved) return
84
91
  resolved = true
92
+ detachAbort()
85
93
  set({ pending: undefined, answered: false })
86
94
  // The service's signal race would conclude 'cancelled' anyway; settle
87
95
  // the same way so this listener never dangles a pending promise.
88
96
  settle('cancelled')
89
97
  }
90
- if (request.signal !== undefined) {
91
- request.signal.addEventListener('abort', withdraw, { once: true })
98
+ if (signal !== undefined) {
99
+ signal.addEventListener('abort', onAbort, { once: true })
92
100
  }
93
101
  const pending: PendingApproval = {
94
102
  headline: request.reason ?? `tool ${request.toolName} asks for your approval`,
@@ -98,6 +106,7 @@ export function mountApprovalAnswerer(
98
106
  // One-shot latch: a second keypress after submission is inert.
99
107
  if (resolved) return
100
108
  resolved = true
109
+ detachAbort()
101
110
  set({ pending, answered: true })
102
111
  settle(outcome)
103
112
  },
package/src/history.ts CHANGED
@@ -8,8 +8,8 @@
8
8
  * @module @deepseek-ai/dsh-tui/history
9
9
  */
10
10
 
11
- /** Maximum entries retained in the persistent history file. */
12
- export const HISTORY_MAX_ENTRIES = 500
11
+ /** Maximum entries retained in the persistent history file and the local recall pool. */
12
+ export const HISTORY_MAX_ENTRIES = 100
13
13
 
14
14
  /** Encode one entry for the history file (JSON keeps multi-line drafts intact). */
15
15
  export function serializeHistoryEntry(text: string): string {
@@ -56,15 +56,30 @@ export function appendHistoryContent(current: string, text: string, max = HISTOR
56
56
 
57
57
  /**
58
58
  * Record one in-session submission: empty text is ignored and an adjacent
59
- * duplicate collapses (Codex `record_local_submission` semantics).
59
+ * duplicate collapses (Codex `record_local_submission` semantics). The local
60
+ * pool shares the persistent pool's cap so the recall space stays bounded.
60
61
  * @param local - current in-session entries, oldest first.
61
62
  * @param text - the submitted prompt.
63
+ * @param max - the local pool cap.
62
64
  * @returns the updated local list.
63
65
  */
64
- export function recordLocalEntry(local: readonly string[], text: string): readonly string[] {
66
+ export function recordLocalEntry(local: readonly string[], text: string, max = HISTORY_MAX_ENTRIES): readonly string[] {
65
67
  if (text === '') return local
66
68
  if (local.length > 0 && local[local.length - 1] === text) return local
67
- return [...local, text]
69
+ return [...local, text].slice(-max)
70
+ }
71
+
72
+ /**
73
+ * Serialize a capped entry list to the history file format (one JSON line per
74
+ * entry, trailing newline). The runner writes the in-memory list as the whole
75
+ * file, so rapid same-process submissions cannot lose entries to a
76
+ * read-modify-write race (the file is never read back before writing).
77
+ * @param entries - the entries to persist, oldest first.
78
+ * @returns the file content, '' for an empty list.
79
+ */
80
+ export function serializeHistoryList(entries: readonly string[]): string {
81
+ if (entries.length === 0) return ''
82
+ return entries.map(serializeHistoryEntry).join('\n') + '\n'
68
83
  }
69
84
 
70
85
  /**