@xmoon76/dsh-pi-tui 0.4.7-alpha.1 → 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.
@@ -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 };
@@ -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.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.
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.6-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-CGeJ1k1B.mjs";
238
2
  export { HARNESS_COMPAT, TUI_STARTUP_SERVICE, apply, bundleVersionLabel, harnessCompatEntryFor, incompatibleHarnessMessage, inject, name };