@deepseek-harness-tui/dsh-tui 0.9.1 → 0.9.3
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 +14 -4
- package/bin/dsh-tui.js +26 -4
- package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -13
- package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -59
- package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -15
- package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -32
- package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -59
- package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -166
- package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -42
- package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -143
- package/dsh-ecosystem-spec/registry/README.md +14 -14
- package/dsh-ecosystem-spec/registry/host-descriptor.tui.example.json +56 -56
- package/dsh-ecosystem-spec/registry/permissions-0.1.json +13 -13
- package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -149
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +7 -8
- package/lib/types/components/BalanceReportRow.d.ts +24 -0
- package/lib/types/components/BalanceReportRow.d.ts.map +1 -0
- package/lib/types/components/BalanceReportRow.js +87 -0
- package/lib/types/components/HistorySearchDialog.js +1 -1
- package/lib/types/components/MessageList.d.ts +3 -1
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +11 -7
- package/lib/types/components/PluginSceneBoundary.d.ts +1 -1
- package/lib/types/components/PluginSceneBoundary.js +1 -1
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +16 -0
- package/lib/types/components/Whale.d.ts +15 -4
- package/lib/types/components/Whale.d.ts.map +1 -1
- package/lib/types/components/Whale.js +9 -8
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +7 -1
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +34 -4
- package/lib/types/deepseekBalance.d.ts +53 -0
- package/lib/types/deepseekBalance.d.ts.map +1 -0
- package/lib/types/deepseekBalance.js +86 -0
- package/lib/types/deepseekPricing.d.ts +82 -0
- package/lib/types/deepseekPricing.d.ts.map +1 -0
- package/lib/types/deepseekPricing.js +133 -0
- package/lib/types/dsh-adapter/channel.d.ts +46 -1
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +84 -10
- package/lib/types/dsh-adapter/index.d.ts +5 -0
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +1 -0
- package/lib/types/dsh-adapter/packaged-skills.d.ts +9 -0
- package/lib/types/dsh-adapter/packaged-skills.d.ts.map +1 -1
- package/lib/types/dsh-adapter/packaged-skills.js +19 -4
- package/lib/types/dsh-adapter/plugin.d.ts +6 -0
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +122 -18
- package/lib/types/dsh-adapter/settings-sections.d.ts +1 -0
- package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
- package/lib/types/dsh-adapter/settings-sections.js +35 -2
- package/lib/types/history.d.ts +4 -3
- package/lib/types/history.d.ts.map +1 -1
- package/lib/types/history.js +66 -18
- package/lib/types/i18n.d.ts +122 -55
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +39 -18
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +67 -17
- package/lib/types/ink/root.d.ts +16 -0
- package/lib/types/ink/root.d.ts.map +1 -1
- package/lib/types/ink/root.js +2 -0
- package/lib/types/ink/terminal-querier.d.ts +8 -0
- package/lib/types/ink/terminal-querier.d.ts.map +1 -1
- package/lib/types/ink/terminal-querier.js +13 -0
- package/lib/types/ink/terminal.d.ts +42 -0
- package/lib/types/ink/terminal.d.ts.map +1 -1
- package/lib/types/ink/terminal.js +52 -2
- package/lib/types/plugin-spec/registry.d.ts +1 -1
- package/lib/types/plugin-spec/registry.js +1 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +72 -37
- package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
- package/lib/types/screens/SessionBrowser.js +28 -13
- package/lib/types/screens/SessionTree.d.ts.map +1 -1
- package/lib/types/screens/SessionTree.js +33 -9
- package/lib/types/screens/Settings.d.ts +7 -5
- package/lib/types/screens/Settings.d.ts.map +1 -1
- package/lib/types/screens/Settings.js +206 -99
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +32 -1
- package/lib/types/sessionHistory.d.ts +11 -0
- package/lib/types/sessionHistory.d.ts.map +1 -1
- package/lib/types/sessionHistory.js +29 -0
- package/lib/types/sessions/format.d.ts.map +1 -1
- package/lib/types/sessions/format.js +14 -4
- package/lib/types/tips.js +2 -2
- package/lib/types/tuiDisplayPrefs.d.ts +3 -0
- package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
- package/lib/types/tuiDisplayPrefs.js +1 -0
- package/lib/types/update.d.ts +66 -0
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +346 -3
- package/node_modules/@deepseek-harness-tui/dsh-auth/LICENSE +21 -21
- package/node_modules/@deepseek-harness-tui/dsh-auth/dsh-plugin.json +44 -44
- package/node_modules/@dsh-std/command/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/command/LICENSE +21 -21
- package/node_modules/@dsh-std/command/README.md +26 -26
- package/node_modules/@dsh-std/command/README.zh.md +28 -28
- package/node_modules/@dsh-std/command/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/command/package.json +22 -22
- package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/connection/LICENSE +21 -21
- package/node_modules/@dsh-std/connection/README.md +42 -42
- package/node_modules/@dsh-std/connection/README.zh.md +42 -42
- package/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
- package/node_modules/@dsh-std/connection/package.json +20 -20
- package/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/core/LICENSE +21 -21
- package/node_modules/@dsh-std/core/README.md +13 -13
- package/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/core/package.json +21 -21
- package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
- package/node_modules/@dsh-std/manifest/LICENSE +21 -21
- package/node_modules/@dsh-std/manifest/README.md +5 -5
- package/node_modules/@dsh-std/manifest/README.zh.md +5 -5
- package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/manifest/package.json +20 -20
- package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
- package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/messages/LICENSE +21 -21
- package/node_modules/@dsh-std/messages/README.md +5 -5
- package/node_modules/@dsh-std/messages/README.zh.md +7 -7
- package/node_modules/@dsh-std/messages/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/messages/package.json +20 -20
- package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -54
- package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
- package/node_modules/@dsh-std/presentation/LICENSE +21 -21
- package/node_modules/@dsh-std/presentation/README.md +27 -27
- package/node_modules/@dsh-std/presentation/README.zh.md +29 -29
- package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
- package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/presentation/package.json +25 -25
- package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/storage/LICENSE +21 -21
- package/node_modules/@dsh-std/storage/README.md +5 -5
- package/node_modules/@dsh-std/storage/README.zh.md +7 -7
- package/node_modules/@dsh-std/storage/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/storage/package.json +20 -20
- package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -56
- package/package.json +95 -5
- package/skills/pr-comments/SKILL.md +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -42
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -42
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -20
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -5
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -5
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -20
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +27 -27
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +29 -29
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +25 -25
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -21
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -42
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -42
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -20
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -21
package/lib/types/update.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process';
|
|
2
|
-
import { appendFileSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
1
|
+
import { execFileSync, spawn } from 'node:child_process';
|
|
2
|
+
import { appendFileSync, chmodSync, copyFileSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { dirname, join, resolve } from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
@@ -11,7 +11,9 @@ import { DATA_DIR } from './utils/paths.js';
|
|
|
11
11
|
export { shellQuote };
|
|
12
12
|
const PACKAGE_NAME = '@deepseek-harness-tui/dsh-tui';
|
|
13
13
|
const DEFAULT_REGISTRY = 'https://registry.npmjs.org';
|
|
14
|
+
const GITHUB_REPO = 'ccch1mneyyy/dsh-TUI';
|
|
14
15
|
const UPDATE_CHECK_TIMEOUT_MS = 4000;
|
|
16
|
+
const STANDALONE_DOWNLOAD_TIMEOUT_MS = 300000;
|
|
15
17
|
/** env marker set on the /update restart; the new process verifies it at boot. */
|
|
16
18
|
const UPDATED_FROM_ENV = 'DSH_TUI_UPDATED_FROM';
|
|
17
19
|
/**
|
|
@@ -189,6 +191,189 @@ async function fetchLatestVersion(registryBase) {
|
|
|
189
191
|
clearTimeout(timeout);
|
|
190
192
|
}
|
|
191
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Detect whether the current process is running in standalone / portable package mode.
|
|
196
|
+
*
|
|
197
|
+
* @returns `true` when running inside a standalone binary distribution, `false` otherwise.
|
|
198
|
+
*/
|
|
199
|
+
export function isStandaloneRuntime() {
|
|
200
|
+
return (process.env.DSH_TUI_STANDALONE === '1' ||
|
|
201
|
+
process.env.DSH_TUI_STANDALONE_BINARY !== undefined ||
|
|
202
|
+
(typeof process.env.DSH_HOME === 'string' && process.env.DSH_HOME.includes('dsh-tui-standalone')));
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Get the path to the current standalone executable binary.
|
|
206
|
+
*
|
|
207
|
+
* @returns The resolved executable path from environment or `process.execPath`.
|
|
208
|
+
*/
|
|
209
|
+
export function getStandaloneBinaryPath() {
|
|
210
|
+
return process.env.DSH_TUI_STANDALONE_BINARY ?? process.execPath;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Get the expected release asset file name for the current platform and architecture.
|
|
214
|
+
*
|
|
215
|
+
* @param platform - Node.js platform identifier (e.g. `'linux'`, `'win32'`, `'darwin'`).
|
|
216
|
+
* @param arch - Node.js architecture identifier (e.g. `'x64'`, `'arm64'`).
|
|
217
|
+
* @returns The archive file name matching the target platform.
|
|
218
|
+
*/
|
|
219
|
+
export function getStandaloneAssetName(platform = process.platform, arch = process.arch) {
|
|
220
|
+
if (platform === 'win32') {
|
|
221
|
+
return 'dsh-tui-standalone-win-x64.zip';
|
|
222
|
+
}
|
|
223
|
+
if (platform === 'darwin') {
|
|
224
|
+
return arch === 'arm64'
|
|
225
|
+
? 'dsh-tui-standalone-darwin-arm64.tar.gz'
|
|
226
|
+
: 'dsh-tui-standalone-darwin-x64.tar.gz';
|
|
227
|
+
}
|
|
228
|
+
return arch === 'arm64'
|
|
229
|
+
? 'dsh-tui-standalone-linux-arm64.tar.gz'
|
|
230
|
+
: 'dsh-tui-standalone-linux-x64.tar.gz';
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Fetch latest release info from GitHub Releases API for the standalone asset.
|
|
234
|
+
*
|
|
235
|
+
* @returns Release version tag and matching asset download URL, or `undefined` on any failure.
|
|
236
|
+
*/
|
|
237
|
+
export async function fetchGithubLatestRelease() {
|
|
238
|
+
const controller = new AbortController();
|
|
239
|
+
const timeout = setTimeout(() => controller.abort(), UPDATE_CHECK_TIMEOUT_MS);
|
|
240
|
+
try {
|
|
241
|
+
const response = await fetch(`https://api.github.com/repos/${GITHUB_REPO}/releases/latest`, {
|
|
242
|
+
headers: { accept: 'application/vnd.github.v3+json', 'user-agent': 'dsh-tui-updater' },
|
|
243
|
+
signal: controller.signal,
|
|
244
|
+
});
|
|
245
|
+
if (!response.ok)
|
|
246
|
+
return undefined;
|
|
247
|
+
const payload = await response.json();
|
|
248
|
+
if (!isRecord(payload) || typeof payload.tag_name !== 'string')
|
|
249
|
+
return undefined;
|
|
250
|
+
const rawTag = payload.tag_name.replace(/^v/, '');
|
|
251
|
+
const version = valid(rawTag);
|
|
252
|
+
if (version === null)
|
|
253
|
+
return undefined;
|
|
254
|
+
const assetName = getStandaloneAssetName();
|
|
255
|
+
let downloadUrl;
|
|
256
|
+
if (Array.isArray(payload.assets)) {
|
|
257
|
+
const asset = payload.assets.find((a) => isRecord(a) && a.name === assetName && typeof a.browser_download_url === 'string');
|
|
258
|
+
if (asset !== undefined && typeof asset.browser_download_url === 'string') {
|
|
259
|
+
downloadUrl = asset.browser_download_url;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (downloadUrl === undefined) {
|
|
263
|
+
downloadUrl = `https://github.com/${GITHUB_REPO}/releases/download/v${version}/${assetName}`;
|
|
264
|
+
}
|
|
265
|
+
return { version, downloadUrl };
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
270
|
+
finally {
|
|
271
|
+
clearTimeout(timeout);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Download the new standalone release binary package and atomically replace the running binary.
|
|
276
|
+
*
|
|
277
|
+
* @param downloadUrl - Direct URL to download the release archive.
|
|
278
|
+
* @param onProgress - Optional callback invoked with progress status strings.
|
|
279
|
+
* @returns Object indicating success or an error message on failure.
|
|
280
|
+
*/
|
|
281
|
+
export async function downloadAndReplaceStandaloneBinary(downloadUrl, onProgress) {
|
|
282
|
+
const tempDir = join(process.env.DSH_TUI_STANDALONE_CACHE ?? join(homedir(), '.cache', 'dsh-tui-standalone'), `.update-${Date.now()}-${process.pid}`);
|
|
283
|
+
try {
|
|
284
|
+
const currentBinary = getStandaloneBinaryPath();
|
|
285
|
+
const targetDir = dirname(currentBinary);
|
|
286
|
+
const assetName = getStandaloneAssetName();
|
|
287
|
+
const isZip = assetName.endsWith('.zip');
|
|
288
|
+
mkdirSync(tempDir, { recursive: true });
|
|
289
|
+
const downloadPath = join(tempDir, assetName);
|
|
290
|
+
onProgress?.(`downloading: ${downloadUrl}`);
|
|
291
|
+
const controller = new AbortController();
|
|
292
|
+
const timeout = setTimeout(() => controller.abort(), STANDALONE_DOWNLOAD_TIMEOUT_MS);
|
|
293
|
+
let response;
|
|
294
|
+
try {
|
|
295
|
+
response = await fetch(downloadUrl, {
|
|
296
|
+
headers: { 'user-agent': 'dsh-tui-updater' },
|
|
297
|
+
redirect: 'follow',
|
|
298
|
+
signal: controller.signal,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
finally {
|
|
302
|
+
clearTimeout(timeout);
|
|
303
|
+
}
|
|
304
|
+
if (!response.ok) {
|
|
305
|
+
throw new Error(`HTTP ${response.status} ${response.statusText}`);
|
|
306
|
+
}
|
|
307
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
308
|
+
writeFileSync(downloadPath, buffer);
|
|
309
|
+
onProgress?.('extracting…');
|
|
310
|
+
const extractDir = join(tempDir, 'extracted');
|
|
311
|
+
mkdirSync(extractDir, { recursive: true });
|
|
312
|
+
if (isZip) {
|
|
313
|
+
if (process.platform === 'win32') {
|
|
314
|
+
execFileSync('powershell', [
|
|
315
|
+
'-NoProfile', '-Command',
|
|
316
|
+
`Expand-Archive -Path '${downloadPath}' -DestinationPath '${extractDir}' -Force`,
|
|
317
|
+
]);
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
execFileSync('unzip', ['-o', downloadPath, '-d', extractDir]);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
execFileSync('tar', ['-xzf', downloadPath, '-C', extractDir]);
|
|
325
|
+
}
|
|
326
|
+
const binaryName = process.platform === 'win32' ? 'dsh-tui.exe' : 'dsh-tui';
|
|
327
|
+
const newBinaryPath = join(extractDir, binaryName);
|
|
328
|
+
if (!existsSync(newBinaryPath)) {
|
|
329
|
+
throw new Error('No executable binary found in release archive');
|
|
330
|
+
}
|
|
331
|
+
onProgress?.('replacing binary…');
|
|
332
|
+
if (process.platform !== 'win32') {
|
|
333
|
+
try {
|
|
334
|
+
chmodSync(newBinaryPath, 0o755);
|
|
335
|
+
}
|
|
336
|
+
catch { }
|
|
337
|
+
}
|
|
338
|
+
if (process.platform === 'win32') {
|
|
339
|
+
const oldBinary = `${currentBinary}.old`;
|
|
340
|
+
try {
|
|
341
|
+
rmSync(oldBinary, { force: true });
|
|
342
|
+
}
|
|
343
|
+
catch { }
|
|
344
|
+
renameSync(currentBinary, oldBinary);
|
|
345
|
+
try {
|
|
346
|
+
copyFileSync(newBinaryPath, currentBinary);
|
|
347
|
+
}
|
|
348
|
+
catch (copyError) {
|
|
349
|
+
// Restore the original executable if copying the new binary failed.
|
|
350
|
+
try {
|
|
351
|
+
renameSync(oldBinary, currentBinary);
|
|
352
|
+
}
|
|
353
|
+
catch { }
|
|
354
|
+
throw copyError;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
const stagedTarget = join(targetDir, `.dsh-tui-new-${process.pid}`);
|
|
359
|
+
copyFileSync(newBinaryPath, stagedTarget);
|
|
360
|
+
chmodSync(stagedTarget, 0o755);
|
|
361
|
+
renameSync(stagedTarget, currentBinary);
|
|
362
|
+
}
|
|
363
|
+
try {
|
|
364
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
365
|
+
}
|
|
366
|
+
catch { }
|
|
367
|
+
return { success: true };
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
try {
|
|
371
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
372
|
+
}
|
|
373
|
+
catch { }
|
|
374
|
+
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
375
|
+
}
|
|
376
|
+
}
|
|
192
377
|
/**
|
|
193
378
|
* Classify this install against a fresh registry lookup: an update is
|
|
194
379
|
* available, the install is already latest, or the answer is unknown
|
|
@@ -207,6 +392,16 @@ export async function resolveTuiUpdateTarget() {
|
|
|
207
392
|
const currentVersion = current === undefined ? null : valid(current);
|
|
208
393
|
if (currentVersion === null)
|
|
209
394
|
return { kind: 'unknown' };
|
|
395
|
+
if (isStandaloneRuntime()) {
|
|
396
|
+
const ghRelease = await fetchGithubLatestRelease();
|
|
397
|
+
const latest = ghRelease?.version ?? (await fetchLatestVersion(resolveRegistryBase()));
|
|
398
|
+
if (latest === undefined)
|
|
399
|
+
return { kind: 'unknown' };
|
|
400
|
+
if (!gt(latest, currentVersion))
|
|
401
|
+
return { kind: 'latest', current: currentVersion, isStandalone: true };
|
|
402
|
+
const downloadUrl = ghRelease?.downloadUrl ?? `https://github.com/${GITHUB_REPO}/releases/download/v${latest}/${getStandaloneAssetName()}`;
|
|
403
|
+
return { kind: 'update', current: currentVersion, latest, isStandalone: true, downloadUrl };
|
|
404
|
+
}
|
|
210
405
|
const registryBase = resolveRegistryBase();
|
|
211
406
|
const [latest, official] = await Promise.all([
|
|
212
407
|
fetchLatestVersion(registryBase),
|
|
@@ -226,7 +421,9 @@ export async function resolveTuiUpdateTarget() {
|
|
|
226
421
|
*/
|
|
227
422
|
export async function checkForTuiUpdate() {
|
|
228
423
|
const target = await resolveTuiUpdateTarget();
|
|
229
|
-
return target.kind === 'update'
|
|
424
|
+
return target.kind === 'update'
|
|
425
|
+
? { current: target.current, latest: target.latest, isStandalone: target.isStandalone, downloadUrl: target.downloadUrl }
|
|
426
|
+
: undefined;
|
|
230
427
|
}
|
|
231
428
|
/**
|
|
232
429
|
* Run a child process with its output attached to the user's terminal. The
|
|
@@ -279,6 +476,111 @@ export function tuiUpdatePluginArgs(profile, targetVersion) {
|
|
|
279
476
|
? ['plugin', '--profile', profile, 'update', '--latest', PACKAGE_NAME]
|
|
280
477
|
: ['plugin', '--profile', profile, 'update', `${PACKAGE_NAME}@${targetVersion}`];
|
|
281
478
|
}
|
|
479
|
+
/**
|
|
480
|
+
* Postinstall-only transitive dependencies of the dsh-tui chain
|
|
481
|
+
* (dsh-auth → @earendil-works/pi-ai → @google/genai + protobufjs, plus the
|
|
482
|
+
* esbuild/koffi peers of that chain): pnpm ≥11 refuses to run their build
|
|
483
|
+
* scripts unless the workspace allowlists them, and a profile that never
|
|
484
|
+
* opted in fails the WHOLE install with ERR_PNPM_IGNORED_BUILDS. None of
|
|
485
|
+
* these scripts is needed at runtime (the repo root allowBuilds them all to
|
|
486
|
+
* `false`), so the update flow pre-seeds the profile's pnpm-workspace.yaml
|
|
487
|
+
* with explicit `false` entries — an explicit decision pnpm honors silently.
|
|
488
|
+
*/
|
|
489
|
+
const PROFILE_ALLOW_BUILDS = {
|
|
490
|
+
'@google/genai': false,
|
|
491
|
+
esbuild: false,
|
|
492
|
+
koffi: false,
|
|
493
|
+
protobufjs: false,
|
|
494
|
+
};
|
|
495
|
+
/** The profile's pnpm-workspace.yaml (`$DSH_HOME ?? ~/.dsh` layout). */
|
|
496
|
+
export function profileWorkspaceYamlPath(profile) {
|
|
497
|
+
const dshHome = process.env.DSH_HOME ?? join(homedir(), '.dsh');
|
|
498
|
+
return join(dshHome, 'profiles', profile, 'pnpm-workspace.yaml');
|
|
499
|
+
}
|
|
500
|
+
/** YAML key spelling for an allowBuilds entry (scoped names need quotes). */
|
|
501
|
+
function allowBuildsKeyLine(key) {
|
|
502
|
+
const needsQuotes = key.includes('@') || key.includes('/');
|
|
503
|
+
return ` ${needsQuotes ? `'${key}'` : key}: false`;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Make sure the profile's pnpm-workspace.yaml carries explicit `false`
|
|
507
|
+
* allowBuilds entries for the dsh-tui chain's postinstall-only deps, so a
|
|
508
|
+
* pnpm ≥11 update is not killed by ERR_PNPM_IGNORED_BUILDS. Best effort and
|
|
509
|
+
* idempotent: existing entries are never overwritten (an explicit user
|
|
510
|
+
* decision wins), a missing `allowBuilds:` block is appended, and a missing
|
|
511
|
+
* file is created. Returns undefined when the profile directory is absent or
|
|
512
|
+
* the file could not be updated — the caller still runs pnpm, whose own
|
|
513
|
+
* ERR_PNPM_IGNORED_BUILDS diagnostic stays the visible fallback.
|
|
514
|
+
*/
|
|
515
|
+
export function ensureProfileAllowBuilds(profile) {
|
|
516
|
+
const yamlPath = profileWorkspaceYamlPath(profile);
|
|
517
|
+
try {
|
|
518
|
+
if (!existsSafe(dirname(yamlPath)))
|
|
519
|
+
return undefined;
|
|
520
|
+
let text = '';
|
|
521
|
+
try {
|
|
522
|
+
text = readFileSync(yamlPath, 'utf8');
|
|
523
|
+
}
|
|
524
|
+
catch {
|
|
525
|
+
// Missing file — start from an empty document; writeFileSync creates it.
|
|
526
|
+
}
|
|
527
|
+
const lines = text.split(/\r?\n/u);
|
|
528
|
+
let blockStart = -1;
|
|
529
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
530
|
+
const line = lines[i];
|
|
531
|
+
if (line !== '' && line === line.trimStart() && /^allowBuilds:/u.test(line)) {
|
|
532
|
+
blockStart = i;
|
|
533
|
+
break;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
const present = new Set();
|
|
537
|
+
if (blockStart !== -1) {
|
|
538
|
+
for (let i = blockStart + 1; i < lines.length; i += 1) {
|
|
539
|
+
const line = lines[i];
|
|
540
|
+
if (line === '' || line === line.trimStart())
|
|
541
|
+
break; // dedent = block ends
|
|
542
|
+
const keyMatch = /^\s+('?)(.+?)\1:\s/u.exec(line);
|
|
543
|
+
if (keyMatch !== null)
|
|
544
|
+
present.add(keyMatch[2]);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
const added = Object.keys(PROFILE_ALLOW_BUILDS).filter(key => !present.has(key));
|
|
548
|
+
if (added.length === 0)
|
|
549
|
+
return { existing: [...present], added };
|
|
550
|
+
const insert = added.map(allowBuildsKeyLine);
|
|
551
|
+
if (blockStart !== -1) {
|
|
552
|
+
// Append after the block's last existing entry (before the next
|
|
553
|
+
// top-level key), so existing entries keep their position.
|
|
554
|
+
let blockEnd = blockStart + 1;
|
|
555
|
+
for (let i = blockStart + 1; i < lines.length; i += 1) {
|
|
556
|
+
const line = lines[i];
|
|
557
|
+
if (line === '' || line === line.trimStart())
|
|
558
|
+
break;
|
|
559
|
+
blockEnd = i + 1;
|
|
560
|
+
}
|
|
561
|
+
lines.splice(blockEnd, 0, ...insert);
|
|
562
|
+
}
|
|
563
|
+
else {
|
|
564
|
+
if (lines.length > 0 && lines[lines.length - 1] !== '')
|
|
565
|
+
lines.push('');
|
|
566
|
+
lines.push('allowBuilds:', ...insert);
|
|
567
|
+
}
|
|
568
|
+
writeFileSync(yamlPath, `${lines.join('\n')}\n`);
|
|
569
|
+
return { existing: [...present], added };
|
|
570
|
+
}
|
|
571
|
+
catch {
|
|
572
|
+
return undefined;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
function existsSafe(path) {
|
|
576
|
+
try {
|
|
577
|
+
statSync(path);
|
|
578
|
+
return true;
|
|
579
|
+
}
|
|
580
|
+
catch {
|
|
581
|
+
return false;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
282
584
|
/**
|
|
283
585
|
* The pnpm Windows tmp-rename race signature (issue #225): pnpm swaps a
|
|
284
586
|
* package directory via a `<name>_tmp_<pid>` staging dir, and a file lock or
|
|
@@ -447,8 +749,37 @@ export async function updateTui(profile, targetVersion) {
|
|
|
447
749
|
// process then compares new-vs-new and false-alarms "version did not
|
|
448
750
|
// advance" on every successful update (issue #307's screenshots).
|
|
449
751
|
const updatedFrom = installedTuiVersion() ?? '';
|
|
752
|
+
if (isStandaloneRuntime()) {
|
|
753
|
+
const target = await resolveTuiUpdateTarget();
|
|
754
|
+
const latestVersion = targetVersion ?? (target.kind === 'update' ? target.latest : undefined);
|
|
755
|
+
const downloadUrl = (target.kind === 'update' && target.downloadUrl)
|
|
756
|
+
? target.downloadUrl
|
|
757
|
+
: (latestVersion ? `https://github.com/${GITHUB_REPO}/releases/download/v${latestVersion}/${getStandaloneAssetName()}` : undefined);
|
|
758
|
+
if (downloadUrl === undefined || latestVersion === undefined) {
|
|
759
|
+
process.stderr.write('dsh-tui: 无法解析便携包更新下载地址\n');
|
|
760
|
+
return { code: 1, updatedFrom };
|
|
761
|
+
}
|
|
762
|
+
process.stderr.write(`dsh-tui: 正在更新便携包 (${updatedFrom || 'current'} → ${latestVersion})…\n`);
|
|
763
|
+
const result = await downloadAndReplaceStandaloneBinary(downloadUrl, msg => {
|
|
764
|
+
process.stderr.write(`dsh-tui: ${msg}\n`);
|
|
765
|
+
});
|
|
766
|
+
if (!result.success) {
|
|
767
|
+
process.stderr.write(`dsh-tui: 便携包更新失败: ${result.error ?? '未知错误'}\n`);
|
|
768
|
+
return { code: 1, updatedFrom };
|
|
769
|
+
}
|
|
770
|
+
return { code: 0, updatedFrom, installed: latestVersion };
|
|
771
|
+
}
|
|
450
772
|
const dsh = process.platform === 'win32' ? 'dsh.cmd' : 'dsh';
|
|
451
773
|
const updateArgs = tuiUpdatePluginArgs(profile, targetVersion);
|
|
774
|
+
// pnpm ≥11 hard-fails installs whose dependency tree carries un-allowlisted
|
|
775
|
+
// build scripts (ERR_PNPM_IGNORED_BUILDS). The dsh-auth chain pulls in
|
|
776
|
+
// postinstall-only deps (@google/genai/protobufjs via pi-ai), so pre-seed
|
|
777
|
+
// the profile workspace with explicit `false` entries before pnpm runs.
|
|
778
|
+
const allowBuilds = ensureProfileAllowBuilds(profile);
|
|
779
|
+
if (allowBuilds !== undefined && allowBuilds.added.length > 0) {
|
|
780
|
+
process.stderr.write(`dsh-tui: pre-seeded profile pnpm allowBuilds (${allowBuilds.added.join(', ')}) — ` +
|
|
781
|
+
'postinstall-only deps are explicitly ignored\n');
|
|
782
|
+
}
|
|
452
783
|
let updateStderr = '';
|
|
453
784
|
const capture = (chunk) => { updateStderr += chunk; };
|
|
454
785
|
let updateCode = await runProcess(dsh, updateArgs, { shell: true, onStderr: capture });
|
|
@@ -569,6 +900,18 @@ export async function cliUpdate(profile) {
|
|
|
569
900
|
process.stdout.write(`dsh-tui: already the latest version (${target.current}).\n`);
|
|
570
901
|
return 0;
|
|
571
902
|
}
|
|
903
|
+
if (isStandaloneRuntime()) {
|
|
904
|
+
if (target.kind === 'update') {
|
|
905
|
+
process.stdout.write(`dsh-tui: updating standalone binary ${target.current} → ${target.latest}…\n`);
|
|
906
|
+
const outcome = await updateTui(profile, target.latest);
|
|
907
|
+
if (outcome.code === 0) {
|
|
908
|
+
process.stdout.write(`dsh-tui: standalone binary updated successfully (${outcome.updatedFrom || target.current} → ${outcome.installed}).\n`);
|
|
909
|
+
}
|
|
910
|
+
return outcome.code;
|
|
911
|
+
}
|
|
912
|
+
process.stderr.write('dsh-tui: version check failed (offline or unreachable registry).\n');
|
|
913
|
+
return 1;
|
|
914
|
+
}
|
|
572
915
|
let targetVersion;
|
|
573
916
|
if (target.kind === 'update') {
|
|
574
917
|
// Mirror the /update flow exactly: refuse the 0.7.0–0.7.1 hard-inject
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 ccch1mneyyy
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ccch1mneyyy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://dsh.community/schemas/dsh-plugin-0.15.json",
|
|
3
|
-
"id": "com.dsh-tui.dsh-auth",
|
|
4
|
-
"name": "dsh-auth",
|
|
5
|
-
"version": "0.1.0",
|
|
6
|
-
"manifestVersion": "0.15",
|
|
7
|
-
"description": "Subscription OAuth sign-in (ChatGPT/Codex, Claude Pro/Max, SuperGrok) as LLM provider routes for DeepSeek Harness. Registers llm adapter routes through the cordis llm registry; interactive login runs over the user-questions seam and degrades to a clear refusal when no interactive surface is present.",
|
|
8
|
-
"facets": {
|
|
9
|
-
"host": {
|
|
10
|
-
"entry": "lib/index.js",
|
|
11
|
-
"apiVersion": "v1alpha1"
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"requires": {
|
|
15
|
-
"contracts": [
|
|
16
|
-
{
|
|
17
|
-
"apiVersion": "commands.dsh/v1alpha1",
|
|
18
|
-
"kind": "Command"
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"apiVersion": "user-questions.dsh/v1alpha1",
|
|
22
|
-
"kind": "UserQuestions",
|
|
23
|
-
"optional": true,
|
|
24
|
-
"fallback": "login refuses with guidance instead of assuming a browser or GUI is present (TUI-RUN-001)"
|
|
25
|
-
}
|
|
26
|
-
]
|
|
27
|
-
},
|
|
28
|
-
"contributes": {
|
|
29
|
-
"commands": [
|
|
30
|
-
{
|
|
31
|
-
"id": "dsh.auth",
|
|
32
|
-
"title": "Sign in with a provider subscription (OAuth)"
|
|
33
|
-
}
|
|
34
|
-
]
|
|
35
|
-
},
|
|
36
|
-
"permissions": [
|
|
37
|
-
{
|
|
38
|
-
"name": "commands.invoke",
|
|
39
|
-
"scope": "dsh.auth",
|
|
40
|
-
"reason": "run /auth status|login|logout from any composed command surface"
|
|
41
|
-
}
|
|
42
|
-
],
|
|
43
|
-
"license": "MIT"
|
|
44
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://dsh.community/schemas/dsh-plugin-0.15.json",
|
|
3
|
+
"id": "com.dsh-tui.dsh-auth",
|
|
4
|
+
"name": "dsh-auth",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"manifestVersion": "0.15",
|
|
7
|
+
"description": "Subscription OAuth sign-in (ChatGPT/Codex, Claude Pro/Max, SuperGrok) as LLM provider routes for DeepSeek Harness. Registers llm adapter routes through the cordis llm registry; interactive login runs over the user-questions seam and degrades to a clear refusal when no interactive surface is present.",
|
|
8
|
+
"facets": {
|
|
9
|
+
"host": {
|
|
10
|
+
"entry": "lib/index.js",
|
|
11
|
+
"apiVersion": "v1alpha1"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"requires": {
|
|
15
|
+
"contracts": [
|
|
16
|
+
{
|
|
17
|
+
"apiVersion": "commands.dsh/v1alpha1",
|
|
18
|
+
"kind": "Command"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"apiVersion": "user-questions.dsh/v1alpha1",
|
|
22
|
+
"kind": "UserQuestions",
|
|
23
|
+
"optional": true,
|
|
24
|
+
"fallback": "login refuses with guidance instead of assuming a browser or GUI is present (TUI-RUN-001)"
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
"contributes": {
|
|
29
|
+
"commands": [
|
|
30
|
+
{
|
|
31
|
+
"id": "dsh.auth",
|
|
32
|
+
"title": "Sign in with a provider subscription (OAuth)"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"permissions": [
|
|
37
|
+
{
|
|
38
|
+
"name": "commands.invoke",
|
|
39
|
+
"scope": "dsh.auth",
|
|
40
|
+
"reason": "run /auth status|login|logout from any composed command surface"
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"license": "MIT"
|
|
44
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
Changes to `@dsh-std/command` are recorded here.
|
|
4
|
-
|
|
5
|
-
## 0.1.0 (draft)
|
|
6
|
-
|
|
7
|
-
- Defined portable command trees, arguments, options, catalogs, and invocation.
|
|
8
|
-
- Added owner-aware command resource and runtime capability definitions.
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Changes to `@dsh-std/command` are recorded here.
|
|
4
|
+
|
|
5
|
+
## 0.1.0 (draft)
|
|
6
|
+
|
|
7
|
+
- Defined portable command trees, arguments, options, catalogs, and invocation.
|
|
8
|
+
- Added owner-aware command resource and runtime capability definitions.
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 DSH Standard contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DSH Standard contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
# @dsh-std/command
|
|
2
|
-
|
|
3
|
-
English | [中文](README.zh.md)
|
|
4
|
-
|
|
5
|
-
Named human-command resources and their shared callable Runtime dispatcher.
|
|
6
|
-
|
|
7
|
-
## Contract
|
|
8
|
-
|
|
9
|
-
A `Command` resource describes one root command and its nested subcommands. Nodes provide a title, localized titles, description, aliases, positional arguments, options, and child nodes. Arguments may be required, variadic, or restricted to documented values. Options declare every literal spelling and may accept one value.
|
|
10
|
-
|
|
11
|
-
`CommandRuntime` defines the generic `catalog` and `execute` operations once for every command extension. A runtime adapter joins extensions published by active facets with its authoritative command registry and implements that capability. The execution context id remains opaque to the standard; a DSH adapter maps it to a session. Results contain only the command outcome. Invocation-scoped UI work uses typed clients from `@dsh-std/presentation`.
|
|
12
|
-
|
|
13
|
-
`commandRuntime()` wraps a consumer-scoped `CapabilityClient` with typed methods, and `commandRuntimeImplementation()` builds the operation dispatcher for an adapter. Consumers and adapters do not repeat operation strings or payload validation.
|
|
14
|
-
|
|
15
|
-
Presentation clients can build completion trees and forms without importing the owning component. A component such as dsh-codex declares `Command/codex`; its selected facet publishes the handler in its local runtime and never defines a connection-specific method.
|
|
16
|
-
|
|
17
|
-
Names and aliases are single tokens. Sibling names and aliases, argument names, option spellings, and enumerated values must be unique. A variadic argument must be last.
|
|
18
|
-
|
|
19
|
-
## Extension points
|
|
20
|
-
|
|
21
|
-
Fields prefixed with `x-` may carry experimental metadata. Portable clients ignore extensions they do not understand. Incompatible command semantics require a new contract major version rather than redefining an existing field.
|
|
22
|
-
|
|
23
|
-
## Known Limitations and Deferred Work
|
|
24
|
-
|
|
25
|
-
- The contract does not define a command-line parser or quoting rules.
|
|
26
|
-
- Dynamic completion is not part of `v1alpha1`; declared values are static.
|
|
1
|
+
# @dsh-std/command
|
|
2
|
+
|
|
3
|
+
English | [中文](README.zh.md)
|
|
4
|
+
|
|
5
|
+
Named human-command resources and their shared callable Runtime dispatcher.
|
|
6
|
+
|
|
7
|
+
## Contract
|
|
8
|
+
|
|
9
|
+
A `Command` resource describes one root command and its nested subcommands. Nodes provide a title, localized titles, description, aliases, positional arguments, options, and child nodes. Arguments may be required, variadic, or restricted to documented values. Options declare every literal spelling and may accept one value.
|
|
10
|
+
|
|
11
|
+
`CommandRuntime` defines the generic `catalog` and `execute` operations once for every command extension. A runtime adapter joins extensions published by active facets with its authoritative command registry and implements that capability. The execution context id remains opaque to the standard; a DSH adapter maps it to a session. Results contain only the command outcome. Invocation-scoped UI work uses typed clients from `@dsh-std/presentation`.
|
|
12
|
+
|
|
13
|
+
`commandRuntime()` wraps a consumer-scoped `CapabilityClient` with typed methods, and `commandRuntimeImplementation()` builds the operation dispatcher for an adapter. Consumers and adapters do not repeat operation strings or payload validation.
|
|
14
|
+
|
|
15
|
+
Presentation clients can build completion trees and forms without importing the owning component. A component such as dsh-codex declares `Command/codex`; its selected facet publishes the handler in its local runtime and never defines a connection-specific method.
|
|
16
|
+
|
|
17
|
+
Names and aliases are single tokens. Sibling names and aliases, argument names, option spellings, and enumerated values must be unique. A variadic argument must be last.
|
|
18
|
+
|
|
19
|
+
## Extension points
|
|
20
|
+
|
|
21
|
+
Fields prefixed with `x-` may carry experimental metadata. Portable clients ignore extensions they do not understand. Incompatible command semantics require a new contract major version rather than redefining an existing field.
|
|
22
|
+
|
|
23
|
+
## Known Limitations and Deferred Work
|
|
24
|
+
|
|
25
|
+
- The contract does not define a command-line parser or quoting rules.
|
|
26
|
+
- Dynamic completion is not part of `v1alpha1`; declared values are static.
|