dsh-code 0.4.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 -61
- package/README.zh.md +204 -65
- package/bin/deepseek.mjs +70 -0
- package/cordis.patch.yml +62 -6
- package/lib/index.mjs +1108 -250
- package/lib/startup.mjs +34 -17
- package/lib/types/app.d.ts +19 -1
- 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/inspector.d.ts +4 -0
- package/lib/types/render/status.d.ts +2 -0
- package/lib/types/render/text.d.ts +9 -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/package.json +6 -1
- package/src/app.ts +311 -75
- package/src/commands.ts +15 -1
- package/src/index.ts +332 -133
- 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/inspector.ts +13 -4
- package/src/render/markdown.ts +15 -1
- package/src/render/status.ts +3 -0
- package/src/render/text.ts +34 -6
- 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/pictures/1.png +0 -0
package/lib/startup.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { parseCmdline } from "@deepseek-ai/dsh-cmdline";
|
|
|
3
3
|
//#region src/startup.ts
|
|
4
4
|
/**
|
|
5
5
|
* The interactive terminal app's command-line provider: parses `--resume`,
|
|
6
|
-
* `--continue`, `--session`, and `--help`, then publishes
|
|
6
|
+
* `--continue`, `--session`, `--mode`, and `--help`, then publishes
|
|
7
7
|
* {@link TUI_STARTUP_SERVICE} for the runner to consume lazily. Follows the
|
|
8
8
|
* headless bundle's startup shape (a commander action publishing a service
|
|
9
9
|
* through {@link parseCmdline}).
|
|
@@ -26,17 +26,41 @@ const name = "tui-startup";
|
|
|
26
26
|
const inject = ["cmdlineArgs"];
|
|
27
27
|
/** Service provided by this plugin and injected by the terminal runner. */
|
|
28
28
|
const TUI_STARTUP_SERVICE = "tuiStartup";
|
|
29
|
+
/** Pure option policy shared by Commander and tests. */
|
|
30
|
+
function resolveTuiStartup(options) {
|
|
31
|
+
if ([
|
|
32
|
+
options.resume !== void 0,
|
|
33
|
+
options.continue === true,
|
|
34
|
+
options.session !== void 0
|
|
35
|
+
].filter(Boolean).length > 1) throw new Error("--resume, --continue, and --session are mutually exclusive");
|
|
36
|
+
if (options.session === "") throw new Error("--session needs an id");
|
|
37
|
+
if (options.resume === "") throw new Error("--resume needs a session id or id prefix");
|
|
38
|
+
if (options.mode === "") throw new Error("--mode needs a preset id");
|
|
39
|
+
if (options.mode !== void 0 && (options.resume !== void 0 || options.continue === true)) throw new Error("--mode applies only to a new session; it cannot be combined with --resume or --continue");
|
|
40
|
+
return options.resume !== void 0 ? {
|
|
41
|
+
kind: "resume",
|
|
42
|
+
sessionId: options.resume
|
|
43
|
+
} : options.continue === true ? { kind: "latest" } : options.session !== void 0 ? {
|
|
44
|
+
kind: "named",
|
|
45
|
+
sessionId: options.session,
|
|
46
|
+
...options.mode === void 0 ? {} : { mode: options.mode }
|
|
47
|
+
} : {
|
|
48
|
+
kind: "fresh",
|
|
49
|
+
...options.mode === void 0 ? {} : { mode: options.mode }
|
|
50
|
+
};
|
|
51
|
+
}
|
|
29
52
|
/**
|
|
30
53
|
* This app's command: the launcher's flags this app owns, its description,
|
|
31
54
|
* and its help text.
|
|
32
55
|
* @returns a fresh program, so one process can parse more than once (tests).
|
|
33
56
|
*/
|
|
34
57
|
function tuiCommand() {
|
|
35
|
-
return new Command().name("dsh --profile cli").description("Claude-Code-style interactive terminal for DeepSeek Harness.").helpOption("-h, --help", "show this help").option("-r, --resume <session>", "resume the persisted session with this id (or unique id prefix)").option("-c, --continue", "resume the most recent persisted session for this working directory").option("--session <id>", "create a new session under this explicit id").addHelpText("after", `
|
|
58
|
+
return new Command().name("dsh --profile cli").description("Claude-Code-style interactive terminal for DeepSeek Harness.").helpOption("-h, --help", "show this help").option("-r, --resume <session>", "resume the persisted session with this id (or unique id prefix)").option("-c, --continue", "resume the most recent persisted session for this working directory").option("--session <id>", "create a new session under this explicit id").option("--mode <preset>", "agent preset for a newly created session").addHelpText("after", `
|
|
36
59
|
Examples:
|
|
37
60
|
dsh --profile cli fresh session, minted id
|
|
38
61
|
dsh --profile cli --resume abc123 resume session by id prefix
|
|
39
62
|
dsh --profile cli --continue resume the latest local session
|
|
63
|
+
dsh --profile cli --mode minimal fresh session using the minimal preset
|
|
40
64
|
`);
|
|
41
65
|
}
|
|
42
66
|
/**
|
|
@@ -48,23 +72,16 @@ function apply(ctx) {
|
|
|
48
72
|
const program = tuiCommand();
|
|
49
73
|
program.action(() => {
|
|
50
74
|
const options = program.opts();
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (
|
|
58
|
-
const startup = options.resume !== void 0 ? {
|
|
59
|
-
kind: "resume",
|
|
60
|
-
sessionId: options.resume
|
|
61
|
-
} : options.continue === true ? { kind: "latest" } : options.session !== void 0 ? {
|
|
62
|
-
kind: "named",
|
|
63
|
-
sessionId: options.session
|
|
64
|
-
} : { kind: "fresh" };
|
|
75
|
+
let startup;
|
|
76
|
+
try {
|
|
77
|
+
startup = resolveTuiStartup(options);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
program.error(`error: ${error instanceof Error ? error.message : String(error)}`);
|
|
80
|
+
}
|
|
81
|
+
if (startup === void 0) return;
|
|
65
82
|
ctx.provide(TUI_STARTUP_SERVICE, { startup });
|
|
66
83
|
});
|
|
67
84
|
parseCmdline(ctx, program);
|
|
68
85
|
}
|
|
69
86
|
//#endregion
|
|
70
|
-
export { TUI_STARTUP_SERVICE, apply, inject, name };
|
|
87
|
+
export { TUI_STARTUP_SERVICE, apply, inject, name, resolveTuiStartup };
|
package/lib/types/app.d.ts
CHANGED
|
@@ -21,6 +21,11 @@ import type { ModelDirectory, ModelRow } from './models.ts';
|
|
|
21
21
|
import type { QuestionStore } from './questions.ts';
|
|
22
22
|
import type { SkillsView } from './skills.ts';
|
|
23
23
|
import type { MentionCandidate } from './mentions.ts';
|
|
24
|
+
import type { PresetRow } from './presets.ts';
|
|
25
|
+
import type { PluginRow } from './plugin-inventory.ts';
|
|
26
|
+
import type { SessionDirectoryOptions, SessionRow } from './session-directory.ts';
|
|
27
|
+
/** Visual priority for one bounded local notice. */
|
|
28
|
+
export type NoticeTone = 'info' | 'warning' | 'error';
|
|
24
29
|
/** Props the runner hands the app; callbacks stay owned by the runner. */
|
|
25
30
|
export interface AppProps {
|
|
26
31
|
/** Event-fed transcript store for the live session. */
|
|
@@ -37,12 +42,16 @@ export interface AppProps {
|
|
|
37
42
|
model: string;
|
|
38
43
|
/** Working-directory basename the session serves. */
|
|
39
44
|
cwd: string;
|
|
45
|
+
/** Absolute working directory used by session filters and references. */
|
|
46
|
+
workspaceRoot: string;
|
|
40
47
|
/** Git branch name, empty outside a repository. */
|
|
41
48
|
branch: string;
|
|
42
49
|
/** Short session identifier. */
|
|
43
50
|
sessionId: string;
|
|
44
51
|
/** Whether this session was resumed from persistence. */
|
|
45
52
|
resumed: boolean;
|
|
53
|
+
/** Agent preset currently composing the session. */
|
|
54
|
+
mode: string;
|
|
46
55
|
/** Submit one line: slash commands to the registry, other text to the agent. */
|
|
47
56
|
dispatch(text: string): void;
|
|
48
57
|
/** Submit steering: consumed at the running turn's next step boundary. */
|
|
@@ -63,9 +72,18 @@ export interface AppProps {
|
|
|
63
72
|
exportTranscript(argument: string): Promise<void>;
|
|
64
73
|
/** Rename the session (/title <text>); returns the outcome line for the notice. */
|
|
65
74
|
renameTitle(argument: string): string;
|
|
75
|
+
/** Preset/session/plugin kernel operations. */
|
|
76
|
+
loadPresets(): Promise<readonly PresetRow[]>;
|
|
77
|
+
switchMode(id: string): Promise<string>;
|
|
78
|
+
createSession(mode?: string): void;
|
|
79
|
+
loadSessions(options: SessionDirectoryOptions, signal?: AbortSignal): Promise<readonly SessionRow[]>;
|
|
80
|
+
loadSessionTranscript(id: string, signal?: AbortSignal): Promise<string>;
|
|
81
|
+
switchSession(row: SessionRow): void;
|
|
82
|
+
cancelSessionSwitch(): boolean;
|
|
83
|
+
loadPlugins(): readonly PluginRow[];
|
|
66
84
|
/** Registers the app's notice channel with the runner (called once on mount). */
|
|
67
85
|
onBridgeReady(bridge: {
|
|
68
|
-
notify(text: string): void;
|
|
86
|
+
notify(text: string, tone?: NoticeTone): void;
|
|
69
87
|
}): void;
|
|
70
88
|
}
|
|
71
89
|
/** The whole terminal app; state arrives via the store, output via Ink. */
|
package/lib/types/commands.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ import type { CommandDescriptor } from '@deepseek-ai/dsh-commands';
|
|
|
14
14
|
export interface CommandsView {
|
|
15
15
|
/** Name-sorted descriptors after scoped shadowing. */
|
|
16
16
|
readonly descriptors: readonly CommandDescriptor[];
|
|
17
|
+
/** Latest descriptor-read failure; the help panel exposes it in place. */
|
|
18
|
+
readonly error?: string;
|
|
17
19
|
/** Subscribe to list changes (`commands/change`); returns the unsubscribe function. */
|
|
18
20
|
subscribe(listener: () => void): () => void;
|
|
19
21
|
/** Retarget the agent whose scoped view the list is read through. */
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @deepseek-ai/dsh-code — the interactive terminal driver. The bundle patch
|
|
3
3
|
* rides over dsh-base without Host, HTTP, or browser plugins; this runner
|
|
4
|
-
* creates
|
|
5
|
-
*
|
|
6
|
-
* durable session, answers approval asks with a y/n bar,
|
|
7
|
-
*
|
|
8
|
-
* process exit.
|
|
4
|
+
* creates or resumes preset-composed Agents through the core registry, keeps
|
|
5
|
+
* one Ink owner while the active session changes, folds submitted prompts
|
|
6
|
+
* into the selected durable session, answers approval asks with a y/n bar,
|
|
7
|
+
* dispatches slash commands, and on quit flushes and requests process exit.
|
|
9
8
|
*
|
|
10
9
|
* @module @deepseek-ai/dsh-code
|
|
11
10
|
*/
|
|
@@ -21,6 +20,7 @@ export interface Config {
|
|
|
21
20
|
startup: {
|
|
22
21
|
kind: string;
|
|
23
22
|
sessionId?: string;
|
|
23
|
+
mode?: string;
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
export declare const Config: z<Config>;
|
package/lib/types/internals.d.ts
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
import type { ReactElement } from 'react';
|
|
9
9
|
/** A mounted terminal app instance; the runner owns unmount ordering. */
|
|
10
10
|
export interface TuiMount {
|
|
11
|
+
/** Replace the root element while preserving Ink's single terminal owner. */
|
|
12
|
+
rerender(element: ReactElement): void;
|
|
11
13
|
/** Tear the terminal app down before flush and exit. */
|
|
12
14
|
unmount(): void;
|
|
13
15
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Bounded, composer-safe panels for preset, session, and plugin kernel views. */
|
|
2
|
+
import { type ReactElement } from 'react';
|
|
3
|
+
import type { PresetRow } from './presets.ts';
|
|
4
|
+
import type { PluginRow } from './plugin-inventory.ts';
|
|
5
|
+
import type { SessionDirectoryOptions, SessionRow } from './session-directory.ts';
|
|
6
|
+
export declare function ModePanel({ current, load, select, close }: {
|
|
7
|
+
current: string;
|
|
8
|
+
load(): Promise<readonly PresetRow[]>;
|
|
9
|
+
select(id: string): void;
|
|
10
|
+
close(): void;
|
|
11
|
+
}): ReactElement;
|
|
12
|
+
export declare function PluginPanel({ load, close, initialQuery }: {
|
|
13
|
+
load(): readonly PluginRow[];
|
|
14
|
+
close(): void;
|
|
15
|
+
initialQuery?: string;
|
|
16
|
+
}): ReactElement;
|
|
17
|
+
export declare function ResumePanel({ currentCwd, load, readTranscript, select, close }: {
|
|
18
|
+
currentCwd: string;
|
|
19
|
+
load(options: SessionDirectoryOptions, signal?: AbortSignal): Promise<readonly SessionRow[]>;
|
|
20
|
+
readTranscript(id: string, signal?: AbortSignal): Promise<string>;
|
|
21
|
+
select(row: SessionRow): void;
|
|
22
|
+
close(): void;
|
|
23
|
+
}): ReactElement;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Read-only projection of Cordis Loader entries for /plugin. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
export type PluginPhase = 'pending' | 'loading' | 'active' | 'failed' | 'unloading' | null;
|
|
4
|
+
export interface PluginRow {
|
|
5
|
+
readonly entryId: string;
|
|
6
|
+
readonly moduleName: string;
|
|
7
|
+
readonly enabled: boolean;
|
|
8
|
+
readonly phase: PluginPhase;
|
|
9
|
+
}
|
|
10
|
+
/** Snapshot the live Loader; group-only rows are composition containers, not plugins. */
|
|
11
|
+
export declare function listPluginRows(ctx: Context): PluginRow[];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Agent-preset policy kept independent from the Ink surface. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { Agent, AgentHandle } from '@deepseek-ai/dsh-agent';
|
|
4
|
+
import type { Session, SessionEvent } from '@deepseek-ai/dsh-session';
|
|
5
|
+
/** One discoverable agent composition. */
|
|
6
|
+
export interface PresetRow {
|
|
7
|
+
readonly id: string;
|
|
8
|
+
readonly trust: 'system' | 'user';
|
|
9
|
+
readonly name?: string;
|
|
10
|
+
readonly description?: string;
|
|
11
|
+
readonly order?: number;
|
|
12
|
+
readonly broken?: string;
|
|
13
|
+
}
|
|
14
|
+
/** Structural boundary for the optional upstream AgentPresets service. */
|
|
15
|
+
export interface AgentPresetsService {
|
|
16
|
+
readonly defaultId: string;
|
|
17
|
+
list(): Promise<PresetRow[]>;
|
|
18
|
+
resolve(id?: string): Promise<PresetRow>;
|
|
19
|
+
mount(agentCtx: Context, id?: string): Promise<PresetRow>;
|
|
20
|
+
recompose(agentCtx: Context, id: string): Promise<PresetRow>;
|
|
21
|
+
composedPreset(agentCtx: Context): string | undefined;
|
|
22
|
+
}
|
|
23
|
+
/** Read an optional Cordis service without requiring its package at build time. */
|
|
24
|
+
export declare function agentPresetsFrom(ctx: Context): AgentPresetsService | undefined;
|
|
25
|
+
/** A preset may change only before the first durable turn begins. */
|
|
26
|
+
export declare function isBlankSession(events: readonly SessionEvent[]): boolean;
|
|
27
|
+
/** Latest logged selection wins; legacy sessions deliberately fall back to standard. */
|
|
28
|
+
export declare function resolvePreset(session: Pick<Session, 'header' | 'events'>): string;
|
|
29
|
+
/** Recompose atomically from the caller's perspective, logging only success. */
|
|
30
|
+
export declare function switchPreset(service: AgentPresetsService, agent: Agent, presetId: string): Promise<PresetRow>;
|
|
31
|
+
/** Minimal handle shape used by lifecycle tests without exposing Agent internals. */
|
|
32
|
+
export type OwnedAgent = Pick<AgentHandle, 'agent' | 'dispose'>;
|
|
@@ -5,11 +5,15 @@ export interface InspectorViewport {
|
|
|
5
5
|
maxHeight: number;
|
|
6
6
|
/** Rows available to the selected entry after border, title, and footer. */
|
|
7
7
|
bodyRows: number;
|
|
8
|
+
/** Optional blank rows separating title/body/footer on roomy terminals. */
|
|
9
|
+
gapRows: 0 | 2;
|
|
8
10
|
/** Columns available inside the horizontal border and padding. */
|
|
9
11
|
contentColumns: number;
|
|
10
12
|
/** Tiny terminals use a borderless one-line close hint. */
|
|
11
13
|
compact: boolean;
|
|
12
14
|
}
|
|
15
|
+
/** One transcript-to-composer gutter, collapsed on short terminals. */
|
|
16
|
+
export declare function layoutGutterRows(rows: number): 0 | 1;
|
|
13
17
|
/**
|
|
14
18
|
* Keep the inspector plus its persistent status/composer chrome below
|
|
15
19
|
* `stdout.rows`: at equality Ink clears the terminal and rewrites all
|
|
@@ -38,6 +38,8 @@ export declare function cacheHitPercent(usage: TranscriptStats['usage']): number
|
|
|
38
38
|
export interface StatusFacts {
|
|
39
39
|
/** `provider/model` selection serving this session. */
|
|
40
40
|
model: string;
|
|
41
|
+
/** Agent preset composing this session. */
|
|
42
|
+
mode?: string;
|
|
41
43
|
/** Working-directory basename the session serves. */
|
|
42
44
|
cwd: string;
|
|
43
45
|
/** Git branch name, empty outside a repository or on a detached HEAD file. */
|
|
@@ -16,6 +16,15 @@
|
|
|
16
16
|
* as a literal `\xNN` escape.
|
|
17
17
|
*/
|
|
18
18
|
export declare function displayText(text: string): string;
|
|
19
|
+
/** Collapse external text to one terminal-safe logical row. */
|
|
20
|
+
export declare function singleLineText(text: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Truncate one display-safe row without ever exceeding its physical-column
|
|
23
|
+
* budget. The ellipsis is included inside the budget, matching Codex's popup
|
|
24
|
+
* truncation contract; the previous app-local helper appended it after the
|
|
25
|
+
* row was already full and could force an extra terminal wrap.
|
|
26
|
+
*/
|
|
27
|
+
export declare function truncateColumns(text: string, columns: number): string;
|
|
19
28
|
/** A display-safe suffix bounded by terminal rows and columns. */
|
|
20
29
|
export interface DisplayTail {
|
|
21
30
|
/** Sanitized suffix suitable for direct terminal rendering. */
|
|
@@ -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/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": {
|