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.
- package/README.md +201 -55
- package/README.zh.md +204 -61
- package/bin/deepseek.mjs +70 -0
- package/cordis.patch.yml +62 -6
- package/lib/index.mjs +4073 -1802
- package/lib/startup.mjs +34 -17
- package/lib/types/app.d.ts +23 -22
- package/lib/types/commands.d.ts +2 -0
- package/lib/types/index.d.ts +5 -5
- package/lib/types/internals.d.ts +2 -0
- package/lib/types/kernel-panels.d.ts +23 -0
- package/lib/types/plugin-inventory.d.ts +11 -0
- package/lib/types/presets.d.ts +32 -0
- package/lib/types/render/export.d.ts +15 -0
- package/lib/types/render/inspector.d.ts +34 -0
- package/lib/types/render/lines.d.ts +31 -0
- package/lib/types/render/projection.d.ts +95 -3
- package/lib/types/render/status.d.ts +19 -0
- package/lib/types/render/text.d.ts +27 -0
- package/lib/types/render/tool-detail.d.ts +92 -0
- package/lib/types/session-directory.d.ts +54 -0
- package/lib/types/session-switch.d.ts +17 -0
- package/lib/types/skills.d.ts +2 -0
- package/lib/types/startup.d.ts +11 -1
- package/lib/types/store.d.ts +2 -0
- package/package.json +16 -1
- package/src/app.ts +1367 -277
- package/src/commands.ts +15 -1
- package/src/index.ts +373 -128
- package/src/internals.ts +5 -0
- package/src/kernel-panels.ts +254 -0
- package/src/plugin-inventory.ts +47 -0
- package/src/presets.ts +64 -0
- package/src/render/export.ts +81 -0
- package/src/render/inspector.ts +88 -0
- package/src/render/lines.ts +207 -0
- package/src/render/markdown.ts +15 -1
- package/src/render/projection.ts +279 -16
- package/src/render/status.ts +51 -1
- package/src/render/text.ts +107 -0
- package/src/render/tool-detail.ts +197 -0
- package/src/session-directory.ts +102 -0
- package/src/session-switch.ts +58 -0
- package/src/skills.ts +20 -7
- package/src/startup.ts +38 -20
- package/src/store.ts +8 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expansion payloads for tool cards (the Ctrl+O verbose transcript): the
|
|
3
|
+
* TUI-side consumption of the harness presentation contract. Mutation and
|
|
4
|
+
* read tools persist a structured `tool/result.meta` (`diffs`, read
|
|
5
|
+
* windows, web sources) exactly so a capable UI can replay richer cards than
|
|
6
|
+
* the model-facing text; this module narrows that opaque JSON defensively —
|
|
7
|
+
* mirroring the upstream validators — and pre-formats bounded, render-ready
|
|
8
|
+
* rows. Malformed or absent metadata always degrades to the bounded raw
|
|
9
|
+
* result text, never throws during replay.
|
|
10
|
+
*
|
|
11
|
+
* @module @deepseek-ai/dsh-code/render/tool-detail
|
|
12
|
+
*/
|
|
13
|
+
/** One rendered diff row: removed, added, or shared context. */
|
|
14
|
+
export interface DiffLine {
|
|
15
|
+
/** '-' removed, '+' added, ' ' context. */
|
|
16
|
+
mark: '-' | '+' | ' ';
|
|
17
|
+
/** The line text, truncated to the column budget. */
|
|
18
|
+
text: string;
|
|
19
|
+
}
|
|
20
|
+
/** One file's bounded inline diff. */
|
|
21
|
+
export interface ToolDiff {
|
|
22
|
+
/** File path the change belongs to. */
|
|
23
|
+
path: string;
|
|
24
|
+
/** Rendered rows in order; '-' block before the '+' block. */
|
|
25
|
+
lines: readonly DiffLine[];
|
|
26
|
+
/** True when the line budget cut the hunk. */
|
|
27
|
+
truncated: boolean;
|
|
28
|
+
}
|
|
29
|
+
/** One numbered line of a read window. */
|
|
30
|
+
export interface ToolReadLine {
|
|
31
|
+
/** 1-based file line number. */
|
|
32
|
+
number: number;
|
|
33
|
+
/** The line text, truncated to the column budget. */
|
|
34
|
+
text: string;
|
|
35
|
+
}
|
|
36
|
+
/** One web-search source row. */
|
|
37
|
+
export interface ToolWebSource {
|
|
38
|
+
/** Source URL. */
|
|
39
|
+
url: string;
|
|
40
|
+
/** Source title, when the provider returned one. */
|
|
41
|
+
title: string | undefined;
|
|
42
|
+
/** Short excerpt, truncated to the column budget. */
|
|
43
|
+
snippet: string;
|
|
44
|
+
}
|
|
45
|
+
/** The expansion payload a verbose tool card renders; a discriminated union. */
|
|
46
|
+
export type ToolDetail = {
|
|
47
|
+
kind: 'diff';
|
|
48
|
+
diffs: readonly ToolDiff[];
|
|
49
|
+
} | {
|
|
50
|
+
kind: 'read';
|
|
51
|
+
path: string;
|
|
52
|
+
offset: number;
|
|
53
|
+
lines: readonly ToolReadLine[];
|
|
54
|
+
totalLines: number;
|
|
55
|
+
truncated: boolean;
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'web-search';
|
|
58
|
+
sources: readonly ToolWebSource[];
|
|
59
|
+
truncated: boolean;
|
|
60
|
+
} | {
|
|
61
|
+
kind: 'web-fetch';
|
|
62
|
+
url: string;
|
|
63
|
+
statusCode: number;
|
|
64
|
+
} | {
|
|
65
|
+
kind: 'raw';
|
|
66
|
+
text: string;
|
|
67
|
+
truncated: boolean;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Render one change as removed-then-added rows, hunked by common prefix and
|
|
71
|
+
* suffix. A null before-image (file create) renders as pure additions. The
|
|
72
|
+
* budget caps emitted rows and reports the cut, so a whole-file overwrite
|
|
73
|
+
* never floods the transcript.
|
|
74
|
+
* @param oldText - prior content, or null for a create.
|
|
75
|
+
* @param newText - content after the change.
|
|
76
|
+
* @param budget - maximum rows to emit.
|
|
77
|
+
* @returns the bounded rows and whether they were cut.
|
|
78
|
+
*/
|
|
79
|
+
export declare function diffRows(oldText: string | null, newText: string, budget: number): {
|
|
80
|
+
lines: readonly DiffLine[];
|
|
81
|
+
truncated: boolean;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Narrow the opaque `tool/result.meta` into one bounded expansion payload,
|
|
85
|
+
* mirroring the upstream presenters' degradation ladder: diffs (write/edit),
|
|
86
|
+
* read windows (read), sources (web_search), fetch summaries (web_fetch), and
|
|
87
|
+
* the bounded raw result text as the universal fallback.
|
|
88
|
+
* @param meta - the persisted presentation metadata, when the tool attached one.
|
|
89
|
+
* @param rawText - the joined text blocks of the result message.
|
|
90
|
+
* @returns the expansion payload, or undefined when nothing renderable exists.
|
|
91
|
+
*/
|
|
92
|
+
export declare function toolResultDetail(meta: unknown, rawText: string): ToolDetail | undefined;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Lightweight session-directory projection for the /resume picker. */
|
|
2
|
+
import type { SessionEvent, SessionHeader } from '@deepseek-ai/dsh-session';
|
|
3
|
+
export interface SessionRecord {
|
|
4
|
+
readonly header: SessionHeader;
|
|
5
|
+
readonly live: boolean;
|
|
6
|
+
readonly persisted: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface TitleObservationResult {
|
|
9
|
+
readonly sessionId: string;
|
|
10
|
+
readonly status: 'fulfilled' | 'rejected';
|
|
11
|
+
readonly value?: {
|
|
12
|
+
readonly title?: {
|
|
13
|
+
readonly title?: string;
|
|
14
|
+
readonly text?: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export interface SessionLogSnapshot {
|
|
19
|
+
readonly session: SessionHeader;
|
|
20
|
+
readonly events: SessionEvent[];
|
|
21
|
+
}
|
|
22
|
+
/** Structural upstream SessionQuery surface used by the TUI. */
|
|
23
|
+
export interface SessionQueryService {
|
|
24
|
+
listSessions(signal?: AbortSignal): Promise<SessionRecord[]>;
|
|
25
|
+
readTitleSnapshots(ids: readonly string[], signal?: AbortSignal): Promise<TitleObservationResult[]>;
|
|
26
|
+
readSession(id: string, signal?: AbortSignal): Promise<SessionLogSnapshot>;
|
|
27
|
+
}
|
|
28
|
+
export type SessionScope = 'roots' | 'all';
|
|
29
|
+
export type CwdScope = 'all' | 'current';
|
|
30
|
+
export type SessionSort = 'newest' | 'oldest';
|
|
31
|
+
export interface SessionDirectoryOptions {
|
|
32
|
+
readonly sessions: SessionScope;
|
|
33
|
+
readonly cwd: CwdScope;
|
|
34
|
+
readonly sort: SessionSort;
|
|
35
|
+
readonly currentCwd: string;
|
|
36
|
+
readonly query: string;
|
|
37
|
+
}
|
|
38
|
+
export interface SessionRow {
|
|
39
|
+
readonly id: string;
|
|
40
|
+
readonly createdAt: number;
|
|
41
|
+
readonly cwd: string;
|
|
42
|
+
readonly workspace: string;
|
|
43
|
+
readonly parent?: string;
|
|
44
|
+
readonly subagent: boolean;
|
|
45
|
+
readonly resumable: boolean;
|
|
46
|
+
readonly live: boolean;
|
|
47
|
+
readonly persisted: boolean;
|
|
48
|
+
readonly preset: string;
|
|
49
|
+
readonly title?: string;
|
|
50
|
+
}
|
|
51
|
+
/** Filter/sort header-only records. No session log is loaded here. */
|
|
52
|
+
export declare function projectSessionRows(records: readonly SessionRecord[], options: SessionDirectoryOptions): SessionRow[];
|
|
53
|
+
/** Merge page-local title observations without disturbing directory order. */
|
|
54
|
+
export declare function mergeSessionTitles(rows: readonly SessionRow[], observations: readonly TitleObservationResult[]): SessionRow[];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Latest-wins, idle-bound queue for safe Agent session changes. */
|
|
2
|
+
export interface IdleActivity {
|
|
3
|
+
readonly status: 'idle' | 'running';
|
|
4
|
+
whenIdle(): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export declare class SessionSwitchQueue<T> {
|
|
7
|
+
private readonly execute;
|
|
8
|
+
private readonly failed;
|
|
9
|
+
private pending;
|
|
10
|
+
private pumping;
|
|
11
|
+
constructor(execute: (value: T) => Promise<void>, failed: (error: unknown) => void);
|
|
12
|
+
/** Queue a request; a later request replaces any request still waiting. */
|
|
13
|
+
request(activity: IdleActivity, value: T): 'queued' | 'started';
|
|
14
|
+
/** Cancel only work that has not begun activation. */
|
|
15
|
+
cancel(): boolean;
|
|
16
|
+
private pump;
|
|
17
|
+
}
|
package/lib/types/skills.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ export interface SkillRow {
|
|
|
23
23
|
export interface SkillsView {
|
|
24
24
|
/** Name-sorted user-invocable rows; empty until the first load lands. */
|
|
25
25
|
readonly rows: readonly SkillRow[];
|
|
26
|
+
/** Latest catalog-read failure; the help panel exposes it in place. */
|
|
27
|
+
readonly error?: string;
|
|
26
28
|
/** Subscribe to catalog changes; returns the unsubscribe function. */
|
|
27
29
|
subscribe(listener: () => void): () => void;
|
|
28
30
|
/** Retarget the agent whose workspace the catalog is read for. */
|
package/lib/types/startup.d.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}).
|
|
@@ -27,15 +27,25 @@ export declare const TUI_STARTUP_SERVICE = "tuiStartup";
|
|
|
27
27
|
/** How the runner obtains its session identity. */
|
|
28
28
|
export type TuiStartup = {
|
|
29
29
|
readonly kind: 'fresh';
|
|
30
|
+
readonly mode?: string;
|
|
30
31
|
} | {
|
|
31
32
|
readonly kind: 'named';
|
|
32
33
|
readonly sessionId: string;
|
|
34
|
+
readonly mode?: string;
|
|
33
35
|
} | {
|
|
34
36
|
readonly kind: 'resume';
|
|
35
37
|
readonly sessionId: string;
|
|
36
38
|
} | {
|
|
37
39
|
readonly kind: 'latest';
|
|
38
40
|
};
|
|
41
|
+
export interface TuiStartupOptions {
|
|
42
|
+
readonly resume?: string;
|
|
43
|
+
readonly continue?: boolean;
|
|
44
|
+
readonly session?: string;
|
|
45
|
+
readonly mode?: string;
|
|
46
|
+
}
|
|
47
|
+
/** Pure option policy shared by Commander and tests. */
|
|
48
|
+
export declare function resolveTuiStartup(options: TuiStartupOptions): TuiStartup;
|
|
39
49
|
/**
|
|
40
50
|
* Parse the invocation and publish the startup service. Mutual exclusions are
|
|
41
51
|
* usage errors rejected from the action before anything is provided.
|
package/lib/types/store.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export interface TranscriptStore {
|
|
|
16
16
|
subscribe(listener: () => void): () => void;
|
|
17
17
|
/** Fold one session event; ignored events change nothing and notify nobody. */
|
|
18
18
|
apply(event: SessionEvent): void;
|
|
19
|
+
/** Drop the folded view entirely (/clear): the next event starts a fresh one. */
|
|
20
|
+
reset(): void;
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* Create one transcript store, optionally seeded with replayed history. The
|
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-code",
|
|
3
3
|
"description": "Claude-Code-style interactive TUI bundle for DeepSeek Harness (dsh): DeepSeek-blue whale banner, live session transcript, and a blended status line",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"deepseek": "./bin/deepseek.mjs",
|
|
8
|
+
"dsh-code": "./bin/deepseek.mjs"
|
|
9
|
+
},
|
|
6
10
|
"main": "lib/index.mjs",
|
|
7
11
|
"types": "lib/types/index.d.ts",
|
|
8
12
|
"exports": {
|
|
@@ -52,6 +56,7 @@
|
|
|
52
56
|
"test": "vitest run",
|
|
53
57
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
54
58
|
"gen:whale": "tsx scripts/gen-whale-glyph.ts",
|
|
59
|
+
"prepare": "pnpm build",
|
|
55
60
|
"prepublishOnly": "pnpm typecheck && pnpm test && pnpm build"
|
|
56
61
|
},
|
|
57
62
|
"engines": {
|
|
@@ -72,23 +77,33 @@
|
|
|
72
77
|
"@deepseek-ai/dsh-cmdline": "^0.1.0-rc.6",
|
|
73
78
|
"@deepseek-ai/dsh-code-runtime-worker-thread": "^0.1.0-rc.6",
|
|
74
79
|
"@deepseek-ai/dsh-commands": "^0.1.0-rc.6",
|
|
80
|
+
"@deepseek-ai/dsh-compaction": "^0.1.0-rc.6",
|
|
81
|
+
"@deepseek-ai/dsh-goal": "^0.1.0-rc.6",
|
|
75
82
|
"@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
|
|
76
83
|
"@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
|
|
84
|
+
"@deepseek-ai/dsh-llm-retry": "^0.1.0-rc.6",
|
|
77
85
|
"@deepseek-ai/dsh-permission-presets": "^0.1.0-rc.6",
|
|
78
86
|
"@deepseek-ai/dsh-plan-mode": "^0.1.0-rc.6",
|
|
87
|
+
"@deepseek-ai/dsh-sandbox-policy": "^0.1.0-rc.6",
|
|
79
88
|
"@deepseek-ai/dsh-session": "^0.1.0-rc.6",
|
|
80
89
|
"@deepseek-ai/dsh-session-persistence": "^0.1.0-rc.6",
|
|
81
90
|
"@deepseek-ai/dsh-session-reference": "^0.1.0-rc.6",
|
|
91
|
+
"@deepseek-ai/dsh-session-title": "^0.1.0-rc.6",
|
|
82
92
|
"@deepseek-ai/dsh-skill": "^0.1.0-rc.6",
|
|
83
93
|
"@deepseek-ai/dsh-user-approval": "^0.1.0-rc.6",
|
|
84
94
|
"@deepseek-ai/dsh-user-questions": "^0.1.0-rc.6"
|
|
85
95
|
},
|
|
86
96
|
"devDependencies": {
|
|
97
|
+
"@deepseek-ai/dsh-compaction": "^0.1.0-rc.6",
|
|
87
98
|
"@deepseek-ai/dsh-commands": "^0.1.0-rc.6",
|
|
99
|
+
"@deepseek-ai/dsh-goal": "^0.1.0-rc.6",
|
|
100
|
+
"@deepseek-ai/dsh-llm-retry": "^0.1.0-rc.6",
|
|
88
101
|
"@deepseek-ai/dsh-permission-presets": "^0.1.0-rc.6",
|
|
89
102
|
"@deepseek-ai/dsh-plan-mode": "^0.1.0-rc.6",
|
|
103
|
+
"@deepseek-ai/dsh-sandbox-policy": "^0.1.0-rc.6",
|
|
90
104
|
"@deepseek-ai/dsh-session-persistence": "^0.1.0-rc.6",
|
|
91
105
|
"@deepseek-ai/dsh-session-reference": "^0.1.0-rc.6",
|
|
106
|
+
"@deepseek-ai/dsh-session-title": "^0.1.0-rc.6",
|
|
92
107
|
"@deepseek-ai/dsh-skill": "^0.1.0-rc.6",
|
|
93
108
|
"@deepseek-ai/dsh-user-approval": "^0.1.0-rc.6",
|
|
94
109
|
"@deepseek-ai/dsh-user-questions": "^0.1.0-rc.6",
|