@xmoon76/dsh-pi-tui 0.4.6 → 0.4.7-alpha.2
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 +17 -11
- package/README.md +10 -7
- package/cordis.patch.yml +25 -9
- package/dist/builtins.mjs +2 -2
- package/dist/extensions.mjs +1 -2
- package/dist/index.d.mts +79 -113
- package/dist/index.mjs +2 -3
- package/dist/{src-DNscMTdx.mjs → src-5aY9svZj.mjs} +7489 -2615
- package/dist/startup-CGeJ1k1B.mjs +284 -0
- package/dist/startup.d.mts +29 -9
- package/dist/startup.mjs +1 -209
- package/package.json +122 -91
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { readFileSync, realpathSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { parseCmdline } from "@deepseek-ai/dsh-cmdline";
|
|
5
|
+
//#region src/dsh-compat-matrix.json
|
|
6
|
+
var dsh_compat_matrix_default = {
|
|
7
|
+
$comment: [
|
|
8
|
+
"The single source of truth for the DSH Harness / dsh-pi-tui compatibility matrix.",
|
|
9
|
+
"One `matrix` row = one DSH range and the TUI line that is compatible with it;",
|
|
10
|
+
"`dshFrom` is the inclusive lower bound and the next row's `dshFrom` is the exclusive",
|
|
11
|
+
"upper bound, so the rows are contiguous by construction. A row without `tui` has no",
|
|
12
|
+
"released compatible TUI (the runtime notice offers the upgrade only). `versions`",
|
|
13
|
+
"lists the published DSH versions the row covers, oldest first.",
|
|
14
|
+
"`floor` is the catch-all below the oldest row. `current` describes the line this",
|
|
15
|
+
"checkout ships: the floor it imposes, the published DSH target and the recovery",
|
|
16
|
+
"wording. Consumed by src/startup.ts (inlined by the bundler) and, through",
|
|
17
|
+
"scripts/lib/dsh-compat.mjs, by the release tooling, the installation-doc gate and",
|
|
18
|
+
"the release-notes tests."
|
|
19
|
+
],
|
|
20
|
+
current: {
|
|
21
|
+
"since": "0.4.7-alpha.2",
|
|
22
|
+
"requires": "DeepSeek Harness 0.1.6-alpha.2 or later",
|
|
23
|
+
"upgradeDsh": "0.1.6-alpha.2",
|
|
24
|
+
"upgradeCommand": "npm install -g --allow-scripts=@deepseek-ai/dsh-subprocess-local,koffi,node-pty,@google/genai,protobufjs,fs-ext @deepseek-ai/dsh@0.1.6-alpha.2",
|
|
25
|
+
"guidance": "This 0.4.7-alpha.2 line is validated with the published DeepSeek Harness 0.1.6-alpha.2 distribution; see docs/dsh-compatibility.md."
|
|
26
|
+
},
|
|
27
|
+
floor: {
|
|
28
|
+
"below": "0.1.0-rc.8",
|
|
29
|
+
"versions": ["0.1.0-rc.7"]
|
|
30
|
+
},
|
|
31
|
+
matrix: [
|
|
32
|
+
{
|
|
33
|
+
"dshFrom": "0.1.0-rc.8",
|
|
34
|
+
"tui": "0.2",
|
|
35
|
+
"versions": ["0.1.0-rc.8"]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"dshFrom": "0.1.1-rc.1",
|
|
39
|
+
"tui": "0.3",
|
|
40
|
+
"versions": ["0.1.1-rc.1", "0.1.1-rc.2"]
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"dshFrom": "0.1.2-alpha.1",
|
|
44
|
+
"versions": ["0.1.2-alpha.1"]
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"dshFrom": "0.1.2-alpha.2",
|
|
48
|
+
"tui": "0.4.0-alpha.1",
|
|
49
|
+
"versions": ["0.1.2-alpha.2", "0.1.2-alpha.3"]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"dshFrom": "0.1.2-alpha.4",
|
|
53
|
+
"tui": "0.4.0-alpha.2",
|
|
54
|
+
"versions": ["0.1.2-alpha.4", "0.1.2-alpha.5"]
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"dshFrom": "0.1.2-rc.1",
|
|
58
|
+
"tui": "0.4.1",
|
|
59
|
+
"versions": ["0.1.2-rc.1"]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"dshFrom": "0.1.3-alpha.1",
|
|
63
|
+
"versions": ["0.1.3-alpha.1"]
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"dshFrom": "0.1.3-alpha.2",
|
|
67
|
+
"tui": "0.4.3-alpha.2",
|
|
68
|
+
"versions": ["0.1.3-alpha.2"]
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"dshFrom": "0.1.5-alpha.1",
|
|
72
|
+
"versions": ["0.1.5-alpha.1", "0.1.5-alpha.2"]
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"dshFrom": "0.1.5-rc.1",
|
|
76
|
+
"tui": "0.4.6",
|
|
77
|
+
"versions": ["0.1.5-rc.1", "0.1.5-rc.2"]
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"dshFrom": "0.1.6-alpha.1",
|
|
81
|
+
"tui": "0.4.7-alpha.1",
|
|
82
|
+
"versions": ["0.1.6-alpha.1"]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"dshFrom": "0.1.6-alpha.2",
|
|
86
|
+
"tui": "0.4.7-alpha.2",
|
|
87
|
+
"versions": ["0.1.6-alpha.2"]
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
};
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/startup.ts
|
|
93
|
+
/**
|
|
94
|
+
* The TUI mode's command-line provider: parses the `dsh --profile pi-tui` flag
|
|
95
|
+
* family and provides the parsed values as {@link TUI_STARTUP_SERVICE}.
|
|
96
|
+
* Mirrors the web bundle's startup shape: an ordinary plugin injecting
|
|
97
|
+
* `cmdlineArgs`, providing a service that flag-configured rows inject.
|
|
98
|
+
* @module @xmoon76/dsh-pi-tui/startup
|
|
99
|
+
*/
|
|
100
|
+
/** The installed dsh version, resolved from the launcher's real path. */
|
|
101
|
+
function installedDshVersion() {
|
|
102
|
+
const bin = process.argv[1];
|
|
103
|
+
if (bin === void 0) return void 0;
|
|
104
|
+
try {
|
|
105
|
+
let dir = dirname(realpathSync(bin));
|
|
106
|
+
for (let depth = 0; depth < 8; depth += 1) {
|
|
107
|
+
try {
|
|
108
|
+
const pkg = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
|
|
109
|
+
if (pkg.name === "@deepseek-ai/dsh" && typeof pkg.version === "string") return pkg.version;
|
|
110
|
+
} catch {}
|
|
111
|
+
const parent = dirname(dir);
|
|
112
|
+
if (parent === dir) return void 0;
|
|
113
|
+
dir = parent;
|
|
114
|
+
}
|
|
115
|
+
} catch {}
|
|
116
|
+
}
|
|
117
|
+
/** Prerelease-aware `a >= b` (semver ordering; mirrors src/dsh-version.ts). */
|
|
118
|
+
function versionAtLeast(version, minimum) {
|
|
119
|
+
const parse = (value) => {
|
|
120
|
+
const [core, prerelease = ""] = value.split("-");
|
|
121
|
+
return {
|
|
122
|
+
nums: core.split(".").map(Number),
|
|
123
|
+
pre: prerelease === "" ? [] : prerelease.split(".")
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
const a = parse(version);
|
|
127
|
+
const b = parse(minimum);
|
|
128
|
+
for (let i = 0; i < 3; i += 1) {
|
|
129
|
+
const pa = a.nums[i] ?? 0;
|
|
130
|
+
const pb = b.nums[i] ?? 0;
|
|
131
|
+
if (pa !== pb) return pa > pb;
|
|
132
|
+
}
|
|
133
|
+
if (a.pre.length === 0) return true;
|
|
134
|
+
if (b.pre.length === 0) return false;
|
|
135
|
+
const length = Math.max(a.pre.length, b.pre.length);
|
|
136
|
+
for (let i = 0; i < length; i += 1) {
|
|
137
|
+
const pa = a.pre[i];
|
|
138
|
+
const pb = b.pre[i];
|
|
139
|
+
if (pa === void 0) return false;
|
|
140
|
+
if (pb === void 0) return true;
|
|
141
|
+
if (pa === pb) continue;
|
|
142
|
+
const na = Number(pa);
|
|
143
|
+
const nb = Number(pb);
|
|
144
|
+
const naNumeric = !Number.isNaN(na);
|
|
145
|
+
const nbNumeric = !Number.isNaN(nb);
|
|
146
|
+
if (naNumeric && nbNumeric) return na > nb;
|
|
147
|
+
if (naNumeric !== nbNumeric) return !naNumeric;
|
|
148
|
+
return pa > pb;
|
|
149
|
+
}
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
/** Stable Cordis plugin name. */
|
|
153
|
+
const name = "tui-startup";
|
|
154
|
+
/** Services required before the flags can be resolved. */
|
|
155
|
+
const inject = ["cmdlineArgs"];
|
|
156
|
+
/** The shared matrix. The bundler inlines this JSON, so the startup island
|
|
157
|
+
* gains neither a runtime file read nor a dependency. */
|
|
158
|
+
const COMPAT = dsh_compat_matrix_default;
|
|
159
|
+
/** The floor this checkout imposes and the recovery guidance every
|
|
160
|
+
* incompatible range shows. */
|
|
161
|
+
const CURRENT_DSH_REQUIREMENT = {
|
|
162
|
+
since: COMPAT.current.since,
|
|
163
|
+
requires: COMPAT.current.requires,
|
|
164
|
+
upgradeDsh: COMPAT.current.upgradeDsh,
|
|
165
|
+
upgradeCommand: COMPAT.current.upgradeCommand,
|
|
166
|
+
guidance: COMPAT.current.guidance
|
|
167
|
+
};
|
|
168
|
+
/** The compatibility table, derived from the shared matrix and ordered from
|
|
169
|
+
* oldest to newest so `harnessCompatEntryFor()` can return the first matching
|
|
170
|
+
* range. The oldest entry is the catch-all floor; each matrix row contributes
|
|
171
|
+
* a range that ends at the NEXT row's lower bound (the last row is the current
|
|
172
|
+
* supported line and produces no incompatible entry).
|
|
173
|
+
*
|
|
174
|
+
* Two boundaries are worth keeping in mind: cross-core prereleases do not
|
|
175
|
+
* satisfy an older TUI package's semver peer range, and the official
|
|
176
|
+
* dsh-v0.1.5-alpha.1/.2 tags predate the setup contract required by the next
|
|
177
|
+
* supported TUI line, so they carry no fallback. */
|
|
178
|
+
const HARNESS_COMPAT = [{
|
|
179
|
+
...CURRENT_DSH_REQUIREMENT,
|
|
180
|
+
max: COMPAT.floor.below
|
|
181
|
+
}, ...COMPAT.matrix.slice(0, -1).map((row, index) => ({
|
|
182
|
+
...CURRENT_DSH_REQUIREMENT,
|
|
183
|
+
min: row.dshFrom,
|
|
184
|
+
max: COMPAT.matrix[index + 1].dshFrom,
|
|
185
|
+
...row.tui === void 0 ? {} : { fallbackTui: row.tui }
|
|
186
|
+
}))];
|
|
187
|
+
/** The compat entry covering the installed dsh version, or undefined when
|
|
188
|
+
* the harness is supported. */
|
|
189
|
+
function harnessCompatEntryFor(installed) {
|
|
190
|
+
return HARNESS_COMPAT.find((entry) => (entry.min === void 0 || versionAtLeast(installed, entry.min)) && (entry.max === void 0 || !versionAtLeast(installed, entry.max)));
|
|
191
|
+
}
|
|
192
|
+
/** The bundle's own version label for the gate message, read from
|
|
193
|
+
* package.json at runtime (never hardcoded). Falls back to the release
|
|
194
|
+
* line that first imposed the requirement when unreadable. */
|
|
195
|
+
function bundleVersionLabel(since) {
|
|
196
|
+
try {
|
|
197
|
+
const pkg = JSON.parse(readFileSync(join(import.meta.dirname, "..", "package.json"), "utf8"));
|
|
198
|
+
return pkg.version === void 0 || pkg.version === "" ? `>= ${since}` : `v${pkg.version}`;
|
|
199
|
+
} catch {
|
|
200
|
+
return `>= ${since}`;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/** The actionable compatibility notice printed when the installed harness
|
|
204
|
+
* falls in an incompatible range. `entry` MUST be the entry
|
|
205
|
+
* {@link harnessCompatEntryFor} matched for `installed`. The notice is
|
|
206
|
+
* advisory: DSH Loader mounts profile entries concurrently, so this row cannot
|
|
207
|
+
* guarantee that its output precedes another row's import failure. */
|
|
208
|
+
function incompatibleHarnessMessage(installed, entry) {
|
|
209
|
+
const recovery = [];
|
|
210
|
+
if (entry.upgradeDsh !== void 0) recovery.push("Upgrade DeepSeek Harness:", ` ${entry.upgradeCommand ?? `npm install -g @deepseek-ai/dsh@${entry.upgradeDsh}`}`);
|
|
211
|
+
if (entry.fallbackTui !== void 0) recovery.push("Or keep your current Harness and use the compatible TUI line:", ` dsh plugin --profile pi-tui -- add @xmoon76/dsh-pi-tui@${entry.fallbackTui}`);
|
|
212
|
+
if (entry.guidance !== void 0) recovery.push(entry.guidance);
|
|
213
|
+
return [
|
|
214
|
+
`dsh-pi-tui ${bundleVersionLabel(entry.since)} requires ${entry.requires},`,
|
|
215
|
+
`but this installation is running dsh ${installed}.`,
|
|
216
|
+
"",
|
|
217
|
+
...recovery.length === 0 ? [] : [
|
|
218
|
+
"Choose one:",
|
|
219
|
+
"",
|
|
220
|
+
...recovery
|
|
221
|
+
],
|
|
222
|
+
"Then re-run: dsh --profile pi-tui"
|
|
223
|
+
].join("\n");
|
|
224
|
+
}
|
|
225
|
+
/** Service provided by this plugin and injected by the TUI runner row. */
|
|
226
|
+
const TUI_STARTUP_SERVICE = "tuiStartup";
|
|
227
|
+
/**
|
|
228
|
+
* The actionable error for a committed startup whose TUI surface never
|
|
229
|
+
* mounted. The launcher proved the tree booted, but `--profile pi-tui` asked
|
|
230
|
+
* for this surface, so the outcome is an error rather than an optional plugin
|
|
231
|
+
* warning.
|
|
232
|
+
*/
|
|
233
|
+
function surfaceNotMountedMessage() {
|
|
234
|
+
return [
|
|
235
|
+
`dsh-pi-tui ${bundleVersionLabel(CURRENT_DSH_REQUIREMENT.since)} was invoked with --profile pi-tui, but the required TUI surface did not mount.`,
|
|
236
|
+
"The tui-app row failed to import/apply or stayed pending on a dependency (see the loader warnings above); DSH app-boot treats that as an optional plugin failure.",
|
|
237
|
+
"This installation cannot run the terminal UI; reinstall the profile or fix its composition, then re-run: dsh --profile pi-tui"
|
|
238
|
+
].join("\n");
|
|
239
|
+
}
|
|
240
|
+
/** This app's command: its flags, its description, and its help text. */
|
|
241
|
+
function tuiCommand() {
|
|
242
|
+
return new Command().name("dsh --profile pi-tui").description("Run the DeepSeek Harness terminal UI.").helpOption("-h, --help", "show this help").option("--session <id>", "resume an existing session instead of creating one").option("--preset <id>", "agent preset for a fresh session (falls back to $DSH_PI_TUI_PRESET, then the saved default)").addHelpText("after", `
|
|
243
|
+
Examples:
|
|
244
|
+
dsh --profile pi-tui start the terminal UI
|
|
245
|
+
dsh --profile pi-tui --session <id> resume an existing session
|
|
246
|
+
dsh --profile pi-tui --preset minimal fresh session on the minimal preset
|
|
247
|
+
`);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Parse and provide the TUI invocation as an ordinary Cordis service. The
|
|
251
|
+
* command's action publishes the flags this invocation named; on `--help`
|
|
252
|
+
* nothing is provided, so no TUI row mounts.
|
|
253
|
+
* @param ctx - plugin context carrying the command line.
|
|
254
|
+
*/
|
|
255
|
+
function apply(ctx) {
|
|
256
|
+
const program = tuiCommand();
|
|
257
|
+
program.action(() => {
|
|
258
|
+
const installed = installedDshVersion();
|
|
259
|
+
if (installed !== void 0) {
|
|
260
|
+
const entry = harnessCompatEntryFor(installed);
|
|
261
|
+
if (entry !== void 0) {
|
|
262
|
+
const message = incompatibleHarnessMessage(installed, entry);
|
|
263
|
+
process.stderr.write(`\n${message}\n\n`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
let surfaceMounted = false;
|
|
267
|
+
ctx.get("appReady")?.onReady(() => {
|
|
268
|
+
if (surfaceMounted) return;
|
|
269
|
+
process.stderr.write(`\n${surfaceNotMountedMessage()}\n\n`);
|
|
270
|
+
ctx.get("appExit")?.(1);
|
|
271
|
+
});
|
|
272
|
+
const options = program.opts();
|
|
273
|
+
ctx.provide(TUI_STARTUP_SERVICE, {
|
|
274
|
+
...options.session !== void 0 ? { sessionId: options.session } : {},
|
|
275
|
+
...options.preset !== void 0 ? { presetId: options.preset } : {},
|
|
276
|
+
markSurfaceMounted: () => {
|
|
277
|
+
surfaceMounted = true;
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
parseCmdline(ctx, program);
|
|
282
|
+
}
|
|
283
|
+
//#endregion
|
|
284
|
+
export { harnessCompatEntryFor as a, name as c, bundleVersionLabel as i, TUI_STARTUP_SERVICE as n, incompatibleHarnessMessage as o, apply as r, inject as s, HARNESS_COMPAT as t };
|
package/dist/startup.d.mts
CHANGED
|
@@ -5,10 +5,9 @@ import { Context } from "@deepseek-ai/cordis";
|
|
|
5
5
|
declare const name = "tui-startup";
|
|
6
6
|
/** Services required before the flags can be resolved. */
|
|
7
7
|
declare const inject: string[];
|
|
8
|
-
/** Incompatible dsh harness ranges and the guidance each deserves.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* first whose range covers the installed dsh version wins.
|
|
8
|
+
/** Incompatible dsh harness ranges and the guidance each deserves. Entries
|
|
9
|
+
* are checked in ORDER and the first whose range covers the installed dsh
|
|
10
|
+
* version wins.
|
|
12
11
|
*
|
|
13
12
|
* Range semantics: `min` is inclusive, `max` is EXCLUSIVE. An entry with
|
|
14
13
|
* only `max` covers everything below it (the common "too old" case); an
|
|
@@ -19,10 +18,11 @@ declare const inject: string[];
|
|
|
19
18
|
* it is shown as the fallback version label (`>= <since>`) when the
|
|
20
19
|
* bundle's own version cannot be read, so the message stays truthful.
|
|
21
20
|
*
|
|
22
|
-
* The 0.4.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
21
|
+
* The 0.4.7-alpha.2 line has a minimum of the published npm release
|
|
22
|
+
* dsh-v0.1.6-alpha.2. The recovery guidance names the recommended published
|
|
23
|
+
* upgrade target and allows its native install scripts. The already-published
|
|
24
|
+
* 0.4.7-alpha.1 line keeps its own alpha.1 contract and remains the compatible
|
|
25
|
+
* fallback for a dsh-v0.1.6-alpha.1 runtime.
|
|
26
26
|
*/
|
|
27
27
|
interface HarnessCompatEntry {
|
|
28
28
|
/** Inclusive lower bound of the incompatible range; absent = unbounded below. */
|
|
@@ -31,7 +31,7 @@ interface HarnessCompatEntry {
|
|
|
31
31
|
max?: string;
|
|
32
32
|
/** The bundle release line that first required this constraint. */
|
|
33
33
|
since: string;
|
|
34
|
-
/** Human-readable requirement, e.g. `DeepSeek Harness 0.1.
|
|
34
|
+
/** Human-readable requirement, e.g. `DeepSeek Harness 0.1.6-alpha.2 or later`. */
|
|
35
35
|
requires: string;
|
|
36
36
|
/** The target DSH version to install when the current runtime is too old. */
|
|
37
37
|
upgradeDsh?: string;
|
|
@@ -43,6 +43,16 @@ interface HarnessCompatEntry {
|
|
|
43
43
|
* commands, such as an unvalidated future DSH line. */
|
|
44
44
|
guidance?: string;
|
|
45
45
|
}
|
|
46
|
+
/** The compatibility table, derived from the shared matrix and ordered from
|
|
47
|
+
* oldest to newest so `harnessCompatEntryFor()` can return the first matching
|
|
48
|
+
* range. The oldest entry is the catch-all floor; each matrix row contributes
|
|
49
|
+
* a range that ends at the NEXT row's lower bound (the last row is the current
|
|
50
|
+
* supported line and produces no incompatible entry).
|
|
51
|
+
*
|
|
52
|
+
* Two boundaries are worth keeping in mind: cross-core prereleases do not
|
|
53
|
+
* satisfy an older TUI package's semver peer range, and the official
|
|
54
|
+
* dsh-v0.1.5-alpha.1/.2 tags predate the setup contract required by the next
|
|
55
|
+
* supported TUI line, so they carry no fallback. */
|
|
46
56
|
declare const HARNESS_COMPAT: readonly HarnessCompatEntry[];
|
|
47
57
|
/** The compat entry covering the installed dsh version, or undefined when
|
|
48
58
|
* the harness is supported. */
|
|
@@ -65,6 +75,16 @@ interface TuiStartupValues {
|
|
|
65
75
|
sessionId?: string;
|
|
66
76
|
/** `--preset`, the agent preset a fresh session starts on. */
|
|
67
77
|
presetId?: string;
|
|
78
|
+
/**
|
|
79
|
+
* Mark the TUI required surface as mounted. `src/index.ts` calls this once
|
|
80
|
+
* its synchronous initialization succeeded and its async startup root is
|
|
81
|
+
* established. The readiness handshake registered by this row exits nonzero
|
|
82
|
+
* when the launcher commits readiness without it: 0.1.6 app-boot treats a
|
|
83
|
+
* failed `tui-app` row as an OPTIONAL plugin failure, so without this the
|
|
84
|
+
* explicitly requested TUI could report a successful startup that never
|
|
85
|
+
* mounted. Optional so structural test providers can omit it.
|
|
86
|
+
*/
|
|
87
|
+
markSurfaceMounted?(): void;
|
|
68
88
|
}
|
|
69
89
|
/**
|
|
70
90
|
* Parse and provide the TUI invocation as an ordinary Cordis service. The
|
package/dist/startup.mjs
CHANGED
|
@@ -1,210 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
|
-
import { Command } from "commander";
|
|
4
|
-
import { parseCmdline } from "@deepseek-ai/dsh-cmdline";
|
|
5
|
-
//#region src/startup.ts
|
|
6
|
-
/**
|
|
7
|
-
* The TUI mode's command-line provider: parses the `dsh --profile pi-tui` flag
|
|
8
|
-
* family and provides the parsed values as {@link TUI_STARTUP_SERVICE}.
|
|
9
|
-
* Mirrors the web bundle's startup shape: an ordinary plugin injecting
|
|
10
|
-
* `cmdlineArgs`, providing a service that flag-configured rows inject.
|
|
11
|
-
* @module @xmoon76/dsh-pi-tui/startup
|
|
12
|
-
*/
|
|
13
|
-
/** The installed dsh version, resolved from the launcher's real path. */
|
|
14
|
-
function installedDshVersion() {
|
|
15
|
-
const bin = process.argv[1];
|
|
16
|
-
if (bin === void 0) return void 0;
|
|
17
|
-
try {
|
|
18
|
-
let dir = dirname(realpathSync(bin));
|
|
19
|
-
for (let depth = 0; depth < 8; depth += 1) {
|
|
20
|
-
try {
|
|
21
|
-
const pkg = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
|
|
22
|
-
if (pkg.name === "@deepseek-ai/dsh" && typeof pkg.version === "string") return pkg.version;
|
|
23
|
-
} catch {}
|
|
24
|
-
const parent = dirname(dir);
|
|
25
|
-
if (parent === dir) return void 0;
|
|
26
|
-
dir = parent;
|
|
27
|
-
}
|
|
28
|
-
} catch {}
|
|
29
|
-
}
|
|
30
|
-
/** Prerelease-aware `a >= b` (semver ordering; mirrors src/dsh-version.ts). */
|
|
31
|
-
function versionAtLeast(version, minimum) {
|
|
32
|
-
const parse = (value) => {
|
|
33
|
-
const [core, prerelease = ""] = value.split("-");
|
|
34
|
-
return {
|
|
35
|
-
nums: core.split(".").map(Number),
|
|
36
|
-
pre: prerelease === "" ? [] : prerelease.split(".")
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
const a = parse(version);
|
|
40
|
-
const b = parse(minimum);
|
|
41
|
-
for (let i = 0; i < 3; i += 1) {
|
|
42
|
-
const pa = a.nums[i] ?? 0;
|
|
43
|
-
const pb = b.nums[i] ?? 0;
|
|
44
|
-
if (pa !== pb) return pa > pb;
|
|
45
|
-
}
|
|
46
|
-
if (a.pre.length === 0) return true;
|
|
47
|
-
if (b.pre.length === 0) return false;
|
|
48
|
-
const length = Math.max(a.pre.length, b.pre.length);
|
|
49
|
-
for (let i = 0; i < length; i += 1) {
|
|
50
|
-
const pa = a.pre[i];
|
|
51
|
-
const pb = b.pre[i];
|
|
52
|
-
if (pa === void 0) return false;
|
|
53
|
-
if (pb === void 0) return true;
|
|
54
|
-
if (pa === pb) continue;
|
|
55
|
-
const na = Number(pa);
|
|
56
|
-
const nb = Number(pb);
|
|
57
|
-
const naNumeric = !Number.isNaN(na);
|
|
58
|
-
const nbNumeric = !Number.isNaN(nb);
|
|
59
|
-
if (naNumeric && nbNumeric) return na > nb;
|
|
60
|
-
if (naNumeric !== nbNumeric) return !naNumeric;
|
|
61
|
-
return pa > pb;
|
|
62
|
-
}
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
/** Stable Cordis plugin name. */
|
|
66
|
-
const name = "tui-startup";
|
|
67
|
-
/** Services required before the flags can be resolved. */
|
|
68
|
-
const inject = ["cmdlineArgs"];
|
|
69
|
-
/** The compatibility table. Entries are ordered from oldest to newest so
|
|
70
|
-
* `harnessCompatEntryFor()` can return the first matching historical range. */
|
|
71
|
-
const CURRENT_DSH_REQUIREMENT = {
|
|
72
|
-
since: "0.4.5",
|
|
73
|
-
requires: "DeepSeek Harness 0.1.5-rc.1 or later",
|
|
74
|
-
upgradeDsh: "0.1.5-rc.2",
|
|
75
|
-
upgradeCommand: "npm install -g --allow-scripts=@deepseek-ai/dsh-subprocess-local,koffi,node-pty,@google/genai,protobufjs,fs-ext @deepseek-ai/dsh@0.1.5-rc.2",
|
|
76
|
-
guidance: "This 0.4.5 release is validated with the published DeepSeek Harness 0.1.5-rc.1 distribution and is also compatible with 0.1.5-rc.2; see docs/dsh-compatibility.md."
|
|
77
|
-
};
|
|
78
|
-
const HARNESS_COMPAT = [
|
|
79
|
-
{
|
|
80
|
-
...CURRENT_DSH_REQUIREMENT,
|
|
81
|
-
max: "0.1.0-rc.8"
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
...CURRENT_DSH_REQUIREMENT,
|
|
85
|
-
min: "0.1.0-rc.8",
|
|
86
|
-
max: "0.1.1-rc.1",
|
|
87
|
-
fallbackTui: "0.2"
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
...CURRENT_DSH_REQUIREMENT,
|
|
91
|
-
min: "0.1.1-rc.1",
|
|
92
|
-
max: "0.1.2-alpha.1",
|
|
93
|
-
fallbackTui: "0.3"
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
...CURRENT_DSH_REQUIREMENT,
|
|
97
|
-
min: "0.1.2-alpha.1",
|
|
98
|
-
max: "0.1.2-alpha.2"
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
...CURRENT_DSH_REQUIREMENT,
|
|
102
|
-
min: "0.1.2-alpha.2",
|
|
103
|
-
max: "0.1.2-alpha.4",
|
|
104
|
-
fallbackTui: "0.4.0-alpha.1"
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
...CURRENT_DSH_REQUIREMENT,
|
|
108
|
-
min: "0.1.2-alpha.4",
|
|
109
|
-
max: "0.1.2-rc.1",
|
|
110
|
-
fallbackTui: "0.4.0-alpha.2"
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
...CURRENT_DSH_REQUIREMENT,
|
|
114
|
-
min: "0.1.2-rc.1",
|
|
115
|
-
max: "0.1.3-alpha.1",
|
|
116
|
-
fallbackTui: "0.4.1"
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
...CURRENT_DSH_REQUIREMENT,
|
|
120
|
-
min: "0.1.3-alpha.1",
|
|
121
|
-
max: "0.1.3-alpha.2"
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
...CURRENT_DSH_REQUIREMENT,
|
|
125
|
-
min: "0.1.3-alpha.2",
|
|
126
|
-
max: "0.1.5-alpha.1",
|
|
127
|
-
fallbackTui: "0.4.3-alpha.2"
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
...CURRENT_DSH_REQUIREMENT,
|
|
131
|
-
min: "0.1.5-alpha.1",
|
|
132
|
-
max: "0.1.5-rc.1"
|
|
133
|
-
}
|
|
134
|
-
];
|
|
135
|
-
/** The compat entry covering the installed dsh version, or undefined when
|
|
136
|
-
* the harness is supported. */
|
|
137
|
-
function harnessCompatEntryFor(installed) {
|
|
138
|
-
return HARNESS_COMPAT.find((entry) => (entry.min === void 0 || versionAtLeast(installed, entry.min)) && (entry.max === void 0 || !versionAtLeast(installed, entry.max)));
|
|
139
|
-
}
|
|
140
|
-
/** The bundle's own version label for the gate message, read from
|
|
141
|
-
* package.json at runtime (never hardcoded). Falls back to the release
|
|
142
|
-
* line that first imposed the requirement when unreadable. */
|
|
143
|
-
function bundleVersionLabel(since) {
|
|
144
|
-
try {
|
|
145
|
-
const pkg = JSON.parse(readFileSync(join(import.meta.dirname, "..", "package.json"), "utf8"));
|
|
146
|
-
return pkg.version === void 0 || pkg.version === "" ? `>= ${since}` : `v${pkg.version}`;
|
|
147
|
-
} catch {
|
|
148
|
-
return `>= ${since}`;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
/** The actionable compatibility notice printed when the installed harness
|
|
152
|
-
* falls in an incompatible range. `entry` MUST be the entry
|
|
153
|
-
* {@link harnessCompatEntryFor} matched for `installed`. The notice is
|
|
154
|
-
* advisory: DSH Loader mounts profile entries concurrently, so this row cannot
|
|
155
|
-
* guarantee that its output precedes another row's import failure. */
|
|
156
|
-
function incompatibleHarnessMessage(installed, entry) {
|
|
157
|
-
const recovery = [];
|
|
158
|
-
if (entry.upgradeDsh !== void 0) recovery.push("Upgrade DeepSeek Harness:", ` ${entry.upgradeCommand ?? `npm install -g @deepseek-ai/dsh@${entry.upgradeDsh}`}`);
|
|
159
|
-
if (entry.fallbackTui !== void 0) recovery.push("Or keep your current Harness and use the compatible TUI line:", ` dsh plugin --profile pi-tui -- add @xmoon76/dsh-pi-tui@${entry.fallbackTui}`);
|
|
160
|
-
if (entry.guidance !== void 0) recovery.push(entry.guidance);
|
|
161
|
-
return [
|
|
162
|
-
`dsh-pi-tui ${bundleVersionLabel(entry.since)} requires ${entry.requires},`,
|
|
163
|
-
`but this installation is running dsh ${installed}.`,
|
|
164
|
-
"",
|
|
165
|
-
...recovery.length === 0 ? [] : [
|
|
166
|
-
"Choose one:",
|
|
167
|
-
"",
|
|
168
|
-
...recovery
|
|
169
|
-
],
|
|
170
|
-
"Then re-run: dsh --profile pi-tui"
|
|
171
|
-
].join("\n");
|
|
172
|
-
}
|
|
173
|
-
/** Service provided by this plugin and injected by the TUI runner row. */
|
|
174
|
-
const TUI_STARTUP_SERVICE = "tuiStartup";
|
|
175
|
-
/** This app's command: its flags, its description, and its help text. */
|
|
176
|
-
function tuiCommand() {
|
|
177
|
-
return new Command().name("dsh --profile pi-tui").description("Run the DeepSeek Harness terminal UI.").helpOption("-h, --help", "show this help").option("--session <id>", "resume an existing session instead of creating one").option("--preset <id>", "agent preset for a fresh session (falls back to $DSH_PI_TUI_PRESET, then the saved default)").addHelpText("after", `
|
|
178
|
-
Examples:
|
|
179
|
-
dsh --profile pi-tui start the terminal UI
|
|
180
|
-
dsh --profile pi-tui --session <id> resume an existing session
|
|
181
|
-
dsh --profile pi-tui --preset minimal fresh session on the minimal preset
|
|
182
|
-
`);
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Parse and provide the TUI invocation as an ordinary Cordis service. The
|
|
186
|
-
* command's action publishes the flags this invocation named; on `--help`
|
|
187
|
-
* nothing is provided, so no TUI row mounts.
|
|
188
|
-
* @param ctx - plugin context carrying the command line.
|
|
189
|
-
*/
|
|
190
|
-
function apply(ctx) {
|
|
191
|
-
const program = tuiCommand();
|
|
192
|
-
program.action(() => {
|
|
193
|
-
const installed = installedDshVersion();
|
|
194
|
-
if (installed !== void 0) {
|
|
195
|
-
const entry = harnessCompatEntryFor(installed);
|
|
196
|
-
if (entry !== void 0) {
|
|
197
|
-
const message = incompatibleHarnessMessage(installed, entry);
|
|
198
|
-
process.stderr.write(`\n${message}\n\n`);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
const options = program.opts();
|
|
202
|
-
ctx.provide(TUI_STARTUP_SERVICE, {
|
|
203
|
-
...options.session !== void 0 ? { sessionId: options.session } : {},
|
|
204
|
-
...options.preset !== void 0 ? { presetId: options.preset } : {}
|
|
205
|
-
});
|
|
206
|
-
});
|
|
207
|
-
parseCmdline(ctx, program);
|
|
208
|
-
}
|
|
209
|
-
//#endregion
|
|
1
|
+
import { a as harnessCompatEntryFor, c as name, i as bundleVersionLabel, n as TUI_STARTUP_SERVICE, o as incompatibleHarnessMessage, r as apply, s as inject, t as HARNESS_COMPAT } from "./startup-CGeJ1k1B.mjs";
|
|
210
2
|
export { HARNESS_COMPAT, TUI_STARTUP_SERVICE, apply, bundleVersionLabel, harnessCompatEntryFor, incompatibleHarnessMessage, inject, name };
|