dsh-code 0.9.0 → 1.0.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.
- package/README.en.md +31 -8
- package/README.md +264 -241
- package/bin/deepseek.mjs +100 -6
- package/cordis.patch.yml +29 -1
- package/lib/index.mjs +2317 -708
- package/lib/startup.mjs +21 -11
- package/lib/{theme-BEi4i_aN.mjs → theme-DCT8Y2xf.mjs} +13 -9
- package/lib/types/app.d.ts +66 -14
- package/lib/types/attachments.d.ts +7 -0
- package/lib/types/editor.d.ts +6 -0
- package/lib/types/fork.d.ts +8 -0
- package/lib/types/git-workflow.d.ts +23 -0
- package/lib/types/index.d.ts +6 -0
- package/lib/types/kernel-panels.d.ts +39 -0
- package/lib/types/keyboard.d.ts +43 -0
- package/lib/types/mentions.d.ts +28 -38
- package/lib/types/presets.d.ts +1 -3
- package/lib/types/provider-settings.d.ts +16 -0
- package/lib/types/render/animations.d.ts +24 -41
- package/lib/types/render/editor.d.ts +137 -0
- package/lib/types/render/export.d.ts +1 -1
- package/lib/types/render/lines.d.ts +6 -2
- package/lib/types/render/markdown.d.ts +3 -1
- package/lib/types/render/projection.d.ts +29 -3
- package/lib/types/render/status.d.ts +5 -12
- package/lib/types/session-directory.d.ts +1 -3
- package/lib/types/startup.d.ts +14 -11
- package/lib/types/store.d.ts +11 -9
- package/lib/types/subagents.d.ts +3 -3
- package/lib/types/theme.d.ts +14 -1
- package/lib/types/version.d.ts +15 -2
- package/package.json +153 -117
- package/src/app.ts +4455 -3904
- package/src/attachments.ts +44 -0
- package/src/editor.ts +51 -0
- package/src/fork.ts +31 -0
- package/src/git-workflow.ts +87 -0
- package/src/index.ts +1510 -1374
- package/src/internals.ts +14 -1
- package/src/kernel-panels.ts +914 -798
- package/src/keyboard.ts +125 -0
- package/src/mentions.ts +72 -117
- package/src/presets.ts +1 -4
- package/src/provider-settings.ts +94 -0
- package/src/render/animations.ts +74 -60
- package/src/render/editor.ts +398 -0
- package/src/render/export.ts +79 -79
- package/src/render/lines.ts +342 -236
- package/src/render/markdown.ts +99 -26
- package/src/render/projection.ts +102 -19
- package/src/render/status.ts +713 -650
- package/src/render/text.ts +150 -150
- package/src/render/tool-detail.ts +3 -1
- package/src/session-directory.ts +3 -3
- package/src/startup.ts +136 -119
- package/src/store.ts +23 -11
- package/src/subagents.ts +13 -5
- package/src/theme.ts +214 -206
- package/src/version.ts +58 -1
package/src/render/export.ts
CHANGED
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Markdown export of one transcript view: the /export command's pure
|
|
3
|
-
* formatter. Deterministic and side-effect free — the runner owns the file
|
|
4
|
-
* write, so tests drive the builder with folded views directly.
|
|
5
|
-
*
|
|
6
|
-
* @module @deepseek-ai/dsh-code/render/export
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { assertNever } from '@deepseek-ai/dsh-llm'
|
|
10
|
-
import type
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Render the transcript as a standalone markdown document.
|
|
14
|
-
* @param view - the folded transcript view to export.
|
|
15
|
-
* @param sessionId - the full session identity for the header.
|
|
16
|
-
* @returns the complete markdown text.
|
|
17
|
-
*/
|
|
18
|
-
export function buildExportMarkdown(view: TranscriptView, sessionId: string): string {
|
|
19
|
-
const out: string[] = [
|
|
20
|
-
view.title === ''
|
|
21
|
-
? `# dsh session ${sessionId}`
|
|
22
|
-
: `# ${view.title}`,
|
|
23
|
-
`> session ${sessionId}`,
|
|
24
|
-
'',
|
|
25
|
-
]
|
|
26
|
-
for (const entry of view.entries) {
|
|
27
|
-
switch (entry.kind) {
|
|
28
|
-
case 'user':
|
|
29
|
-
if (entry.notice) {
|
|
30
|
-
out.push(`> ⤷ context: ${entry.text}`, '')
|
|
31
|
-
} else {
|
|
32
|
-
out.push('## user', '', entry.text, '')
|
|
33
|
-
}
|
|
34
|
-
break
|
|
1
|
+
/**
|
|
2
|
+
* Markdown export of one transcript view: the /export command's pure
|
|
3
|
+
* formatter. Deterministic and side-effect free — the runner owns the file
|
|
4
|
+
* write, so tests drive the builder with folded views directly.
|
|
5
|
+
*
|
|
6
|
+
* @module @deepseek-ai/dsh-code/render/export
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { assertNever } from '@deepseek-ai/dsh-llm'
|
|
10
|
+
import { imageLabels, type TranscriptView } from './projection.ts'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Render the transcript as a standalone markdown document.
|
|
14
|
+
* @param view - the folded transcript view to export.
|
|
15
|
+
* @param sessionId - the full session identity for the header.
|
|
16
|
+
* @returns the complete markdown text.
|
|
17
|
+
*/
|
|
18
|
+
export function buildExportMarkdown(view: TranscriptView, sessionId: string): string {
|
|
19
|
+
const out: string[] = [
|
|
20
|
+
view.title === ''
|
|
21
|
+
? `# dsh session ${sessionId}`
|
|
22
|
+
: `# ${view.title}`,
|
|
23
|
+
`> session ${sessionId}`,
|
|
24
|
+
'',
|
|
25
|
+
]
|
|
26
|
+
for (const entry of view.entries) {
|
|
27
|
+
switch (entry.kind) {
|
|
28
|
+
case 'user':
|
|
29
|
+
if (entry.notice) {
|
|
30
|
+
out.push(`> ⤷ context: ${entry.text}`, '')
|
|
31
|
+
} else {
|
|
32
|
+
out.push('## user', '', entry.text, ...(imageLabels(entry.images) === '' ? [] : [imageLabels(entry.images)]), '')
|
|
33
|
+
}
|
|
34
|
+
break
|
|
35
35
|
case 'assistant':
|
|
36
36
|
if (entry.reasoning !== '') {
|
|
37
37
|
out.push('<details><summary>thinking</summary>', '', entry.reasoning, '', '</details>', '')
|
|
38
38
|
}
|
|
39
39
|
out.push('## assistant', '', entry.text, '')
|
|
40
40
|
break
|
|
41
|
-
case 'tool':
|
|
42
|
-
out.push(`### tool \`${entry.name}\``, '')
|
|
43
|
-
if (entry.preview !== '') out.push(`- args: ${entry.preview}`)
|
|
44
|
-
if (entry.summary !== '') out.push(`- ${entry.state === 'error' ? 'error' : 'result'}: ${entry.summary}`)
|
|
45
|
-
out.push('')
|
|
46
|
-
break
|
|
47
|
-
case 'command':
|
|
48
|
-
out.push(`### /${entry.name}${entry.args === '' ? '' : ` ${entry.args}`}`, '')
|
|
49
|
-
if (entry.summary !== '') out.push(`- ${entry.state === 'error' ? 'error' : 'result'}: ${entry.summary}`)
|
|
50
|
-
out.push('')
|
|
51
|
-
break
|
|
52
|
-
case 'error':
|
|
53
|
-
out.push(`> ⨯ ${entry.text}`, '')
|
|
54
|
-
break
|
|
55
|
-
case 'turn-marker':
|
|
56
|
-
out.push(`> ${entry.text}`, '')
|
|
57
|
-
break
|
|
58
|
-
case 'compaction':
|
|
59
|
-
out.push(entry.ok
|
|
60
|
-
? `> compacted ~${entry.tokens} tokens`
|
|
61
|
-
: `> compaction failed: ${entry.error}`, '')
|
|
62
|
-
break
|
|
63
|
-
case 'retry':
|
|
64
|
-
out.push(`> retry ${entry.attempt}/${entry.max} (${entry.code})`, '')
|
|
65
|
-
break
|
|
66
|
-
case 'files':
|
|
67
|
-
out.push(`> files changed: ${entry.paths.join(', ')}`, '')
|
|
68
|
-
break
|
|
69
|
-
case 'pending':
|
|
70
|
-
// Codex PendingSteer: queued prompts export like ordinary user rows.
|
|
71
|
-
out.push('## user', '', entry.text, '')
|
|
72
|
-
break
|
|
73
|
-
default:
|
|
74
|
-
assertNever(entry, 'transcript entry kind')
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
if (view.streaming !== '') out.push('## assistant (streaming)', '', view.streaming, '')
|
|
78
|
-
const { stats } = view
|
|
79
|
-
out.push('---', '')
|
|
80
|
-
out.push(`- model: ${view.model === '' ? '(none yet)' : view.model}`)
|
|
81
|
-
out.push(`- turns: ${stats.turns} · steps: ${stats.steps}`)
|
|
82
|
-
out.push(`- tokens: ↑${stats.usage.inputTokens} ↓${stats.usage.outputTokens} · cache read ${stats.usage.cacheReadTokens}`)
|
|
83
|
-
out.push(`- todos: ${view.todos.length}`)
|
|
84
|
-
return out.join('\n')
|
|
85
|
-
}
|
|
41
|
+
case 'tool':
|
|
42
|
+
out.push(`### tool \`${entry.name}\``, '')
|
|
43
|
+
if (entry.preview !== '') out.push(`- args: ${entry.preview}`)
|
|
44
|
+
if (entry.summary !== '') out.push(`- ${entry.state === 'error' ? 'error' : 'result'}: ${entry.summary}`)
|
|
45
|
+
out.push('')
|
|
46
|
+
break
|
|
47
|
+
case 'command':
|
|
48
|
+
out.push(`### /${entry.name}${entry.args === '' ? '' : ` ${entry.args}`}`, '')
|
|
49
|
+
if (entry.summary !== '') out.push(`- ${entry.state === 'error' ? 'error' : 'result'}: ${entry.summary}`)
|
|
50
|
+
out.push('')
|
|
51
|
+
break
|
|
52
|
+
case 'error':
|
|
53
|
+
out.push(`> ⨯ ${entry.text}`, '')
|
|
54
|
+
break
|
|
55
|
+
case 'turn-marker':
|
|
56
|
+
out.push(`> ${entry.text}`, '')
|
|
57
|
+
break
|
|
58
|
+
case 'compaction':
|
|
59
|
+
out.push(entry.ok
|
|
60
|
+
? `> compacted ~${entry.tokens} tokens`
|
|
61
|
+
: `> compaction failed: ${entry.error}`, '')
|
|
62
|
+
break
|
|
63
|
+
case 'retry':
|
|
64
|
+
out.push(`> retry ${entry.attempt}/${entry.max} (${entry.code})`, '')
|
|
65
|
+
break
|
|
66
|
+
case 'files':
|
|
67
|
+
out.push(`> files changed: ${entry.paths.join(', ')}`, '')
|
|
68
|
+
break
|
|
69
|
+
case 'pending':
|
|
70
|
+
// Codex PendingSteer: queued prompts export like ordinary user rows.
|
|
71
|
+
out.push('## user', '', entry.text, ...(imageLabels(entry.images) === '' ? [] : [imageLabels(entry.images)]), '')
|
|
72
|
+
break
|
|
73
|
+
default:
|
|
74
|
+
assertNever(entry, 'transcript entry kind')
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (view.streaming !== '') out.push('## assistant (streaming)', '', view.streaming, '')
|
|
78
|
+
const { stats } = view
|
|
79
|
+
out.push('---', '')
|
|
80
|
+
out.push(`- model: ${view.model === '' ? '(none yet)' : view.model}`)
|
|
81
|
+
out.push(`- turns: ${stats.turns} · steps: ${stats.steps}`)
|
|
82
|
+
out.push(`- tokens: ↑${stats.usage.inputTokens} ↓${stats.usage.outputTokens} · cache read ${stats.usage.cacheReadTokens}`)
|
|
83
|
+
out.push(`- todos: ${view.todos.length}`)
|
|
84
|
+
return out.join('\n')
|
|
85
|
+
}
|