dsh-code 0.3.0 → 0.5.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 (46) hide show
  1. package/README.md +201 -55
  2. package/README.zh.md +204 -61
  3. package/bin/deepseek.mjs +70 -0
  4. package/cordis.patch.yml +62 -6
  5. package/lib/index.mjs +4073 -1802
  6. package/lib/startup.mjs +34 -17
  7. package/lib/types/app.d.ts +23 -22
  8. package/lib/types/commands.d.ts +2 -0
  9. package/lib/types/index.d.ts +5 -5
  10. package/lib/types/internals.d.ts +2 -0
  11. package/lib/types/kernel-panels.d.ts +23 -0
  12. package/lib/types/plugin-inventory.d.ts +11 -0
  13. package/lib/types/presets.d.ts +32 -0
  14. package/lib/types/render/export.d.ts +15 -0
  15. package/lib/types/render/inspector.d.ts +34 -0
  16. package/lib/types/render/lines.d.ts +31 -0
  17. package/lib/types/render/projection.d.ts +95 -3
  18. package/lib/types/render/status.d.ts +19 -0
  19. package/lib/types/render/text.d.ts +27 -0
  20. package/lib/types/render/tool-detail.d.ts +92 -0
  21. package/lib/types/session-directory.d.ts +54 -0
  22. package/lib/types/session-switch.d.ts +17 -0
  23. package/lib/types/skills.d.ts +2 -0
  24. package/lib/types/startup.d.ts +11 -1
  25. package/lib/types/store.d.ts +2 -0
  26. package/package.json +16 -1
  27. package/src/app.ts +1367 -277
  28. package/src/commands.ts +15 -1
  29. package/src/index.ts +373 -128
  30. package/src/internals.ts +5 -0
  31. package/src/kernel-panels.ts +254 -0
  32. package/src/plugin-inventory.ts +47 -0
  33. package/src/presets.ts +64 -0
  34. package/src/render/export.ts +81 -0
  35. package/src/render/inspector.ts +88 -0
  36. package/src/render/lines.ts +207 -0
  37. package/src/render/markdown.ts +15 -1
  38. package/src/render/projection.ts +279 -16
  39. package/src/render/status.ts +51 -1
  40. package/src/render/text.ts +107 -0
  41. package/src/render/tool-detail.ts +197 -0
  42. package/src/session-directory.ts +102 -0
  43. package/src/session-switch.ts +58 -0
  44. package/src/skills.ts +20 -7
  45. package/src/startup.ts +38 -20
  46. package/src/store.ts +8 -0
package/src/startup.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The interactive terminal app's command-line provider: parses `--resume`,
3
- * `--continue`, `--session`, and `--help`, then publishes
3
+ * `--continue`, `--session`, `--mode`, and `--help`, then publishes
4
4
  * {@link TUI_STARTUP_SERVICE} for the runner to consume lazily. Follows the
5
5
  * headless bundle's startup shape (a commander action publishing a service
6
6
  * through {@link parseCmdline}).
@@ -33,11 +33,37 @@ export const TUI_STARTUP_SERVICE = 'tuiStartup'
33
33
 
34
34
  /** How the runner obtains its session identity. */
35
35
  export type TuiStartup =
36
- | { readonly kind: 'fresh' }
37
- | { readonly kind: 'named'; readonly sessionId: string }
36
+ | { readonly kind: 'fresh'; readonly mode?: string }
37
+ | { readonly kind: 'named'; readonly sessionId: string; readonly mode?: string }
38
38
  | { readonly kind: 'resume'; readonly sessionId: string }
39
39
  | { readonly kind: 'latest' }
40
40
 
41
+ export interface TuiStartupOptions {
42
+ readonly resume?: string
43
+ readonly continue?: boolean
44
+ readonly session?: string
45
+ readonly mode?: string
46
+ }
47
+
48
+ /** Pure option policy shared by Commander and tests. */
49
+ export function resolveTuiStartup(options: TuiStartupOptions): TuiStartup {
50
+ const selected = [options.resume !== undefined, options.continue === true, options.session !== undefined]
51
+ if (selected.filter(Boolean).length > 1) throw new Error('--resume, --continue, and --session are mutually exclusive')
52
+ if (options.session === '') throw new Error('--session needs an id')
53
+ if (options.resume === '') throw new Error('--resume needs a session id or id prefix')
54
+ if (options.mode === '') throw new Error('--mode needs a preset id')
55
+ if (options.mode !== undefined && (options.resume !== undefined || options.continue === true)) {
56
+ throw new Error('--mode applies only to a new session; it cannot be combined with --resume or --continue')
57
+ }
58
+ return options.resume !== undefined
59
+ ? { kind: 'resume', sessionId: options.resume }
60
+ : options.continue === true
61
+ ? { kind: 'latest' }
62
+ : options.session !== undefined
63
+ ? { kind: 'named', sessionId: options.session, ...options.mode === undefined ? {} : { mode: options.mode } }
64
+ : { kind: 'fresh', ...options.mode === undefined ? {} : { mode: options.mode } }
65
+ }
66
+
41
67
  /**
42
68
  * This app's command: the launcher's flags this app owns, its description,
43
69
  * and its help text.
@@ -51,11 +77,13 @@ function tuiCommand(): Command {
51
77
  .option('-r, --resume <session>', 'resume the persisted session with this id (or unique id prefix)')
52
78
  .option('-c, --continue', 'resume the most recent persisted session for this working directory')
53
79
  .option('--session <id>', 'create a new session under this explicit id')
80
+ .option('--mode <preset>', 'agent preset for a newly created session')
54
81
  .addHelpText('after', `
55
82
  Examples:
56
83
  dsh --profile cli fresh session, minted id
57
84
  dsh --profile cli --resume abc123 resume session by id prefix
58
85
  dsh --profile cli --continue resume the latest local session
86
+ dsh --profile cli --mode minimal fresh session using the minimal preset
59
87
  `)
60
88
  }
61
89
 
@@ -67,24 +95,14 @@ Examples:
67
95
  export function apply(ctx: Context): void {
68
96
  const program = tuiCommand()
69
97
  program.action(() => {
70
- const options = program.opts<{ resume?: string; continue?: boolean; session?: string }>()
71
- const selected = [options.resume !== undefined, options.continue === true, options.session !== undefined]
72
- if (selected.filter(Boolean).length > 1) {
73
- program.error('error: --resume, --continue, and --session are mutually exclusive')
74
- }
75
- if (options.session !== undefined && options.session === '') {
76
- program.error('error: --session needs an id')
77
- }
78
- if (options.resume !== undefined && options.resume === '') {
79
- program.error('error: --resume needs a session id or id prefix')
98
+ const options = program.opts<TuiStartupOptions>()
99
+ let startup: TuiStartup | undefined
100
+ try {
101
+ startup = resolveTuiStartup(options)
102
+ } catch (error: unknown) {
103
+ program.error(`error: ${error instanceof Error ? error.message : String(error)}`)
80
104
  }
81
- const startup: TuiStartup = options.resume !== undefined
82
- ? { kind: 'resume', sessionId: options.resume }
83
- : options.continue === true
84
- ? { kind: 'latest' }
85
- : options.session !== undefined
86
- ? { kind: 'named', sessionId: options.session }
87
- : { kind: 'fresh' }
105
+ if (startup === undefined) return
88
106
  ctx.provide(TUI_STARTUP_SERVICE, { startup } satisfies { startup: TuiStartup })
89
107
  })
90
108
  parseCmdline(ctx, program)
package/src/store.ts CHANGED
@@ -18,6 +18,8 @@ export interface TranscriptStore {
18
18
  subscribe(listener: () => void): () => void
19
19
  /** Fold one session event; ignored events change nothing and notify nobody. */
20
20
  apply(event: SessionEvent): void
21
+ /** Drop the folded view entirely (/clear): the next event starts a fresh one. */
22
+ reset(): void
21
23
  }
22
24
 
23
25
  /**
@@ -49,5 +51,11 @@ export function createTranscriptStore(replay?: readonly SessionEvent[]): Transcr
49
51
  listener()
50
52
  }
51
53
  },
54
+ reset(): void {
55
+ view = createTranscriptView()
56
+ for (const listener of listeners) {
57
+ listener()
58
+ }
59
+ },
52
60
  }
53
61
  }