@xmoon76/dsh-pi-tui 0.4.7-alpha.1 → 0.4.8

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.
@@ -0,0 +1,289 @@
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.8",
22
+ "requires": "DeepSeek Harness 0.1.7-rc.1 or later",
23
+ "upgradeDsh": "0.1.7-rc.1",
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.7-rc.1",
25
+ "guidance": "This 0.4.8 line is validated with the published DeepSeek Harness 0.1.7-rc.1 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
+ "dshFrom": "0.1.7-rc.1",
91
+ "tui": "0.4.8",
92
+ "versions": ["0.1.7-rc.1"]
93
+ }
94
+ ]
95
+ };
96
+ //#endregion
97
+ //#region src/startup.ts
98
+ /**
99
+ * The TUI mode's command-line provider: parses the `dsh --profile pi-tui` flag
100
+ * family and provides the parsed values as {@link TUI_STARTUP_SERVICE}.
101
+ * Mirrors the web bundle's startup shape: an ordinary plugin injecting
102
+ * `cmdlineArgs`, providing a service that flag-configured rows inject.
103
+ * @module @xmoon76/dsh-pi-tui/startup
104
+ */
105
+ /** The installed dsh version, resolved from the launcher's real path. */
106
+ function installedDshVersion() {
107
+ const bin = process.argv[1];
108
+ if (bin === void 0) return void 0;
109
+ try {
110
+ let dir = dirname(realpathSync(bin));
111
+ for (let depth = 0; depth < 8; depth += 1) {
112
+ try {
113
+ const pkg = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
114
+ if (pkg.name === "@deepseek-ai/dsh" && typeof pkg.version === "string") return pkg.version;
115
+ } catch {}
116
+ const parent = dirname(dir);
117
+ if (parent === dir) return void 0;
118
+ dir = parent;
119
+ }
120
+ } catch {}
121
+ }
122
+ /** Prerelease-aware `a >= b` (semver ordering; mirrors src/dsh-version.ts). */
123
+ function versionAtLeast(version, minimum) {
124
+ const parse = (value) => {
125
+ const [core, prerelease = ""] = value.split("-");
126
+ return {
127
+ nums: core.split(".").map(Number),
128
+ pre: prerelease === "" ? [] : prerelease.split(".")
129
+ };
130
+ };
131
+ const a = parse(version);
132
+ const b = parse(minimum);
133
+ for (let i = 0; i < 3; i += 1) {
134
+ const pa = a.nums[i] ?? 0;
135
+ const pb = b.nums[i] ?? 0;
136
+ if (pa !== pb) return pa > pb;
137
+ }
138
+ if (a.pre.length === 0) return true;
139
+ if (b.pre.length === 0) return false;
140
+ const length = Math.max(a.pre.length, b.pre.length);
141
+ for (let i = 0; i < length; i += 1) {
142
+ const pa = a.pre[i];
143
+ const pb = b.pre[i];
144
+ if (pa === void 0) return false;
145
+ if (pb === void 0) return true;
146
+ if (pa === pb) continue;
147
+ const na = Number(pa);
148
+ const nb = Number(pb);
149
+ const naNumeric = !Number.isNaN(na);
150
+ const nbNumeric = !Number.isNaN(nb);
151
+ if (naNumeric && nbNumeric) return na > nb;
152
+ if (naNumeric !== nbNumeric) return !naNumeric;
153
+ return pa > pb;
154
+ }
155
+ return true;
156
+ }
157
+ /** Stable Cordis plugin name. */
158
+ const name = "tui-startup";
159
+ /** Services required before the flags can be resolved. */
160
+ const inject = ["cmdlineArgs"];
161
+ /** The shared matrix. The bundler inlines this JSON, so the startup island
162
+ * gains neither a runtime file read nor a dependency. */
163
+ const COMPAT = dsh_compat_matrix_default;
164
+ /** The floor this checkout imposes and the recovery guidance every
165
+ * incompatible range shows. */
166
+ const CURRENT_DSH_REQUIREMENT = {
167
+ since: COMPAT.current.since,
168
+ requires: COMPAT.current.requires,
169
+ upgradeDsh: COMPAT.current.upgradeDsh,
170
+ upgradeCommand: COMPAT.current.upgradeCommand,
171
+ guidance: COMPAT.current.guidance
172
+ };
173
+ /** The compatibility table, derived from the shared matrix and ordered from
174
+ * oldest to newest so `harnessCompatEntryFor()` can return the first matching
175
+ * range. The oldest entry is the catch-all floor; each matrix row contributes
176
+ * a range that ends at the NEXT row's lower bound (the last row is the current
177
+ * supported line and produces no incompatible entry).
178
+ *
179
+ * Two boundaries are worth keeping in mind: cross-core prereleases do not
180
+ * satisfy an older TUI package's semver peer range, and the official
181
+ * dsh-v0.1.5-alpha.1/.2 tags predate the setup contract required by the next
182
+ * supported TUI line, so they carry no fallback. */
183
+ const HARNESS_COMPAT = [{
184
+ ...CURRENT_DSH_REQUIREMENT,
185
+ max: COMPAT.floor.below
186
+ }, ...COMPAT.matrix.slice(0, -1).map((row, index) => ({
187
+ ...CURRENT_DSH_REQUIREMENT,
188
+ min: row.dshFrom,
189
+ max: COMPAT.matrix[index + 1].dshFrom,
190
+ ...row.tui === void 0 ? {} : { fallbackTui: row.tui }
191
+ }))];
192
+ /** The compat entry covering the installed dsh version, or undefined when
193
+ * the harness is supported. */
194
+ function harnessCompatEntryFor(installed) {
195
+ return HARNESS_COMPAT.find((entry) => (entry.min === void 0 || versionAtLeast(installed, entry.min)) && (entry.max === void 0 || !versionAtLeast(installed, entry.max)));
196
+ }
197
+ /** The bundle's own version label for the gate message, read from
198
+ * package.json at runtime (never hardcoded). Falls back to the release
199
+ * line that first imposed the requirement when unreadable. */
200
+ function bundleVersionLabel(since) {
201
+ try {
202
+ const pkg = JSON.parse(readFileSync(join(import.meta.dirname, "..", "package.json"), "utf8"));
203
+ return pkg.version === void 0 || pkg.version === "" ? `>= ${since}` : `v${pkg.version}`;
204
+ } catch {
205
+ return `>= ${since}`;
206
+ }
207
+ }
208
+ /** The actionable compatibility notice printed when the installed harness
209
+ * falls in an incompatible range. `entry` MUST be the entry
210
+ * {@link harnessCompatEntryFor} matched for `installed`. The notice is
211
+ * advisory: DSH Loader mounts profile entries concurrently, so this row cannot
212
+ * guarantee that its output precedes another row's import failure. */
213
+ function incompatibleHarnessMessage(installed, entry) {
214
+ const recovery = [];
215
+ if (entry.upgradeDsh !== void 0) recovery.push("Upgrade DeepSeek Harness:", ` ${entry.upgradeCommand ?? `npm install -g @deepseek-ai/dsh@${entry.upgradeDsh}`}`);
216
+ 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}`);
217
+ if (entry.guidance !== void 0) recovery.push(entry.guidance);
218
+ return [
219
+ `dsh-pi-tui ${bundleVersionLabel(entry.since)} requires ${entry.requires},`,
220
+ `but this installation is running dsh ${installed}.`,
221
+ "",
222
+ ...recovery.length === 0 ? [] : [
223
+ "Choose one:",
224
+ "",
225
+ ...recovery
226
+ ],
227
+ "Then re-run: dsh --profile pi-tui"
228
+ ].join("\n");
229
+ }
230
+ /** Service provided by this plugin and injected by the TUI runner row. */
231
+ const TUI_STARTUP_SERVICE = "tuiStartup";
232
+ /**
233
+ * The actionable error for a committed startup whose TUI surface never
234
+ * mounted. The launcher proved the tree booted, but `--profile pi-tui` asked
235
+ * for this surface, so the outcome is an error rather than an optional plugin
236
+ * warning.
237
+ */
238
+ function surfaceNotMountedMessage() {
239
+ return [
240
+ `dsh-pi-tui ${bundleVersionLabel(CURRENT_DSH_REQUIREMENT.since)} was invoked with --profile pi-tui, but the required TUI surface did not mount.`,
241
+ "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.",
242
+ "This installation cannot run the terminal UI; reinstall the profile or fix its composition, then re-run: dsh --profile pi-tui"
243
+ ].join("\n");
244
+ }
245
+ /** This app's command: its flags, its description, and its help text. */
246
+ function tuiCommand() {
247
+ 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", `
248
+ Examples:
249
+ dsh --profile pi-tui start the terminal UI
250
+ dsh --profile pi-tui --session <id> resume an existing session
251
+ dsh --profile pi-tui --preset minimal fresh session on the minimal preset
252
+ `);
253
+ }
254
+ /**
255
+ * Parse and provide the TUI invocation as an ordinary Cordis service. The
256
+ * command's action publishes the flags this invocation named; on `--help`
257
+ * nothing is provided, so no TUI row mounts.
258
+ * @param ctx - plugin context carrying the command line.
259
+ */
260
+ function apply(ctx) {
261
+ const program = tuiCommand();
262
+ program.action(() => {
263
+ const installed = installedDshVersion();
264
+ if (installed !== void 0) {
265
+ const entry = harnessCompatEntryFor(installed);
266
+ if (entry !== void 0) {
267
+ const message = incompatibleHarnessMessage(installed, entry);
268
+ process.stderr.write(`\n${message}\n\n`);
269
+ }
270
+ }
271
+ let surfaceMounted = false;
272
+ ctx.get("appReady")?.onReady(() => {
273
+ if (surfaceMounted) return;
274
+ process.stderr.write(`\n${surfaceNotMountedMessage()}\n\n`);
275
+ ctx.get("appExit")?.(1);
276
+ });
277
+ const options = program.opts();
278
+ ctx.provide(TUI_STARTUP_SERVICE, {
279
+ ...options.session !== void 0 ? { sessionId: options.session } : {},
280
+ ...options.preset !== void 0 ? { presetId: options.preset } : {},
281
+ markSurfaceMounted: () => {
282
+ surfaceMounted = true;
283
+ }
284
+ });
285
+ });
286
+ parseCmdline(ctx, program);
287
+ }
288
+ //#endregion
289
+ 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 };
@@ -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. Add a
9
- * new entry here whenever a future bundle release stops supporting an
10
- * older (or newer) harness line; entries are checked in ORDER and the
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,9 +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.7-alpha.1 line has a minimum of the published npm release
23
- * dsh-v0.1.6-alpha.1. The recovery guidance names the recommended published
24
- * upgrade target and allows its native install scripts.
21
+ * The 0.4.8 line has a minimum of the published npm release
22
+ * dsh-v0.1.7-rc.1. The recovery guidance names the recommended published
23
+ * upgrade target and allows its native install scripts. The already-published
24
+ * 0.4.7-alpha.2 line keeps its own alpha.2 contract and remains the compatible
25
+ * fallback for a dsh-v0.1.6-alpha.2 runtime.
25
26
  */
26
27
  interface HarnessCompatEntry {
27
28
  /** Inclusive lower bound of the incompatible range; absent = unbounded below. */
@@ -30,7 +31,7 @@ interface HarnessCompatEntry {
30
31
  max?: string;
31
32
  /** The bundle release line that first required this constraint. */
32
33
  since: string;
33
- /** Human-readable requirement, e.g. `DeepSeek Harness 0.1.6-alpha.1 or later`. */
34
+ /** Human-readable requirement, e.g. `DeepSeek Harness 0.1.7-alpha.2 or later`. */
34
35
  requires: string;
35
36
  /** The target DSH version to install when the current runtime is too old. */
36
37
  upgradeDsh?: string;
@@ -42,6 +43,16 @@ interface HarnessCompatEntry {
42
43
  * commands, such as an unvalidated future DSH line. */
43
44
  guidance?: string;
44
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. */
45
56
  declare const HARNESS_COMPAT: readonly HarnessCompatEntry[];
46
57
  /** The compat entry covering the installed dsh version, or undefined when
47
58
  * the harness is supported. */
package/dist/startup.mjs CHANGED
@@ -1,238 +1,2 @@
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/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.7-alpha.1",
73
- requires: "DeepSeek Harness 0.1.6-alpha.1 or later",
74
- upgradeDsh: "0.1.6-alpha.1",
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.6-alpha.1",
76
- guidance: "This 0.4.7-alpha.1 line is validated with the published DeepSeek Harness 0.1.6-alpha.1 distribution; 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
- ...CURRENT_DSH_REQUIREMENT,
136
- min: "0.1.5-rc.1",
137
- max: "0.1.6-alpha.1",
138
- fallbackTui: "0.4.6"
139
- }
140
- ];
141
- /** The compat entry covering the installed dsh version, or undefined when
142
- * the harness is supported. */
143
- function harnessCompatEntryFor(installed) {
144
- return HARNESS_COMPAT.find((entry) => (entry.min === void 0 || versionAtLeast(installed, entry.min)) && (entry.max === void 0 || !versionAtLeast(installed, entry.max)));
145
- }
146
- /** The bundle's own version label for the gate message, read from
147
- * package.json at runtime (never hardcoded). Falls back to the release
148
- * line that first imposed the requirement when unreadable. */
149
- function bundleVersionLabel(since) {
150
- try {
151
- const pkg = JSON.parse(readFileSync(join(import.meta.dirname, "..", "package.json"), "utf8"));
152
- return pkg.version === void 0 || pkg.version === "" ? `>= ${since}` : `v${pkg.version}`;
153
- } catch {
154
- return `>= ${since}`;
155
- }
156
- }
157
- /** The actionable compatibility notice printed when the installed harness
158
- * falls in an incompatible range. `entry` MUST be the entry
159
- * {@link harnessCompatEntryFor} matched for `installed`. The notice is
160
- * advisory: DSH Loader mounts profile entries concurrently, so this row cannot
161
- * guarantee that its output precedes another row's import failure. */
162
- function incompatibleHarnessMessage(installed, entry) {
163
- const recovery = [];
164
- if (entry.upgradeDsh !== void 0) recovery.push("Upgrade DeepSeek Harness:", ` ${entry.upgradeCommand ?? `npm install -g @deepseek-ai/dsh@${entry.upgradeDsh}`}`);
165
- 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}`);
166
- if (entry.guidance !== void 0) recovery.push(entry.guidance);
167
- return [
168
- `dsh-pi-tui ${bundleVersionLabel(entry.since)} requires ${entry.requires},`,
169
- `but this installation is running dsh ${installed}.`,
170
- "",
171
- ...recovery.length === 0 ? [] : [
172
- "Choose one:",
173
- "",
174
- ...recovery
175
- ],
176
- "Then re-run: dsh --profile pi-tui"
177
- ].join("\n");
178
- }
179
- /** Service provided by this plugin and injected by the TUI runner row. */
180
- const TUI_STARTUP_SERVICE = "tuiStartup";
181
- /**
182
- * The actionable error for a committed startup whose TUI surface never
183
- * mounted. The launcher proved the tree booted, but `--profile pi-tui` asked
184
- * for this surface, so the outcome is an error rather than an optional plugin
185
- * warning.
186
- */
187
- function surfaceNotMountedMessage() {
188
- return [
189
- `dsh-pi-tui ${bundleVersionLabel(CURRENT_DSH_REQUIREMENT.since)} was invoked with --profile pi-tui, but the required TUI surface did not mount.`,
190
- "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.",
191
- "This installation cannot run the terminal UI; reinstall the profile or fix its composition, then re-run: dsh --profile pi-tui"
192
- ].join("\n");
193
- }
194
- /** This app's command: its flags, its description, and its help text. */
195
- function tuiCommand() {
196
- 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", `
197
- Examples:
198
- dsh --profile pi-tui start the terminal UI
199
- dsh --profile pi-tui --session <id> resume an existing session
200
- dsh --profile pi-tui --preset minimal fresh session on the minimal preset
201
- `);
202
- }
203
- /**
204
- * Parse and provide the TUI invocation as an ordinary Cordis service. The
205
- * command's action publishes the flags this invocation named; on `--help`
206
- * nothing is provided, so no TUI row mounts.
207
- * @param ctx - plugin context carrying the command line.
208
- */
209
- function apply(ctx) {
210
- const program = tuiCommand();
211
- program.action(() => {
212
- const installed = installedDshVersion();
213
- if (installed !== void 0) {
214
- const entry = harnessCompatEntryFor(installed);
215
- if (entry !== void 0) {
216
- const message = incompatibleHarnessMessage(installed, entry);
217
- process.stderr.write(`\n${message}\n\n`);
218
- }
219
- }
220
- let surfaceMounted = false;
221
- ctx.get("appReady")?.onReady(() => {
222
- if (surfaceMounted) return;
223
- process.stderr.write(`\n${surfaceNotMountedMessage()}\n\n`);
224
- ctx.get("appExit")?.(1);
225
- });
226
- const options = program.opts();
227
- ctx.provide(TUI_STARTUP_SERVICE, {
228
- ...options.session !== void 0 ? { sessionId: options.session } : {},
229
- ...options.preset !== void 0 ? { presetId: options.preset } : {},
230
- markSurfaceMounted: () => {
231
- surfaceMounted = true;
232
- }
233
- });
234
- });
235
- parseCmdline(ctx, program);
236
- }
237
- //#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-Cd07dCyh.mjs";
238
2
  export { HARNESS_COMPAT, TUI_STARTUP_SERVICE, apply, bundleVersionLabel, harnessCompatEntryFor, incompatibleHarnessMessage, inject, name };
@@ -0,0 +1,15 @@
1
+ # Generated DSH preset mirror
2
+
3
+ The `*.patch.yml` files in this directory are GENERATED from the preset
4
+ patch assets exported by `@deepseek-ai/dsh-web-app` (see
5
+ `scripts/generate-dsh-presets.mjs`).
6
+
7
+ **DO NOT EDIT.** dsh-pi-tui does not own the shipped preset definitions:
8
+ `pnpm build` regenerates the mirror from the official package, and
9
+ `test/dsh-preset-parity.test.mjs` fails the suite on any byte drift.
10
+
11
+ This mirror exists only because DSH 0.1.7's (through 0.1.7-rc.1)
12
+ `dsh.bundle.patch` resolves bundle-package-relative paths and cannot
13
+ reference another package's exported assets. It is a recorded upstream
14
+ packaging gap — remove it when DSH ships a shared preset bundle or
15
+ cross-package patch references.