@askdkc/dsh-cli 0.13.2 → 0.13.4
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 +2 -2
- package/bin/dsh-tui.js +2 -2
- package/lib/types/components/LogoV2.d.ts +1 -5
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +3 -12
- package/lib/types/dsh-adapter/bundled-presets.d.ts.map +1 -1
- package/lib/types/dsh-adapter/bundled-presets.js +9 -0
- package/lib/types/dsh-adapter/contract.d.ts +6 -55
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +15 -129
- package/lib/types/dsh-adapter/index.d.ts +3 -3
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +6 -12
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +3 -1
- package/lib/types/dsh-adapter/recap.d.ts.map +1 -1
- package/lib/types/dsh-adapter/recap.js +5 -1
- package/lib/types/dsh-adapter/response-language.d.ts +6 -0
- package/lib/types/dsh-adapter/response-language.d.ts.map +1 -0
- package/lib/types/dsh-adapter/response-language.js +11 -0
- package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sideQuestion.js +3 -0
- package/lib/types/i18n.d.ts +5 -22
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +6 -25
- package/lib/types/update.d.ts +2 -2
- package/lib/types/update.js +2 -2
- package/node_modules/@askdkc/dsh-auth/package.json +29 -11
- package/node_modules/dsh-working-activity/lib/types/index.js +4 -6
- package/node_modules/dsh-working-activity/lib/types/lang.d.ts +10 -8
- package/node_modules/dsh-working-activity/lib/types/lang.js +11 -12
- package/node_modules/dsh-working-activity/package.json +27 -9
- package/node_modules/dsh-working-activity/src/index.ts +4 -6
- package/node_modules/dsh-working-activity/src/lang.ts +12 -13
- package/package.json +108 -95
- package/presets/liangshen/agent.cordis.yml +2 -1
- package/presets/response-language.txt +5 -0
package/README.md
CHANGED
|
@@ -42,8 +42,8 @@ This is dkc's independently developed fork of [dsh-TUI by chimney](https://githu
|
|
|
42
42
|
Requires [Node.js](https://nodejs.org/en) `^22.19 || >=24`, pnpm 11, a
|
|
43
43
|
[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) source
|
|
44
44
|
checkout with dependencies installed, and `DEEPSEEK_API_KEY`. We aim to support
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
current DSH APIs. Compatibility is checked against installed packages and the
|
|
46
|
+
upstream default branch, without a release allowlist; see [ADAPTER.md](ADAPTER.md).
|
|
47
47
|
|
|
48
48
|
Clone recursively to fetch submodules. In an existing checkout, run
|
|
49
49
|
`git submodule update --init --recursive` before installation.
|
package/bin/dsh-tui.js
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* 可用。shellQuote 等小工具在此内联。
|
|
26
26
|
*
|
|
27
27
|
* 面向用户的消息走 MSG 双语表:与 TUI 的语言契约一致——
|
|
28
|
-
* `DSH_TUI_LANG`
|
|
28
|
+
* `DSH_TUI_LANG` 显式指定时从其值,否则默认英文(同 src/i18n.ts 的缺省)。
|
|
29
29
|
*/
|
|
30
30
|
import { spawn, spawnSync } from 'node:child_process'
|
|
31
31
|
import { existsSync, readFileSync, readdirSync, realpathSync, rmSync } from 'node:fs'
|
|
@@ -133,7 +133,7 @@ const isVersionNewer = (a, b) => {
|
|
|
133
133
|
return false
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
const lang = process.env.DSH_TUI_LANG === '
|
|
136
|
+
const lang = process.env.DSH_TUI_LANG === 'zh' ? 'zh' : 'en'
|
|
137
137
|
const MSG = {
|
|
138
138
|
noDsh: {
|
|
139
139
|
en: '[dsh-cli] dsh CLI not found. Install it or set DSH_TUI_DSH_ROOT to a built Harness checkout:\n npm install -g @deepseek-ai/dsh',
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type Tip } from '../tips.js';
|
|
3
|
-
import { type UpstreamDriftSummary } from '../dsh-adapter/contract.js';
|
|
4
3
|
import { type WhaleIntroId } from './whaleFrames.js';
|
|
5
4
|
/**
|
|
6
5
|
* The header splash: one layout, two phases. The **opening** (~1.7–3.5s,
|
|
@@ -20,7 +19,7 @@ import { type WhaleIntroId } from './whaleFrames.js';
|
|
|
20
19
|
* blue. Narrow terminals show complete big text, then the whale alone,
|
|
21
20
|
* then a plain title as space runs out.
|
|
22
21
|
*/
|
|
23
|
-
export declare function LogoV2({ model, effort, cwd, skipIntro, intro, tip, whale, whaleIdle, working,
|
|
22
|
+
export declare function LogoV2({ model, effort, cwd, skipIntro, intro, tip, whale, whaleIdle, working, }: {
|
|
24
23
|
model: string;
|
|
25
24
|
effort?: string | undefined;
|
|
26
25
|
cwd: string;
|
|
@@ -42,8 +41,5 @@ export declare function LogoV2({ model, effort, cwd, skipIntro, intro, tip, whal
|
|
|
42
41
|
* click-hearts are welcome-phase features); sustained !working before
|
|
43
42
|
* that lets it fall asleep. */
|
|
44
43
|
working?: boolean;
|
|
45
|
-
/** Test seam: pin/suppress the upstream-drift notice (`null` forces it off;
|
|
46
|
-
* `undefined` — the production default — auto-detects the install). */
|
|
47
|
-
drift?: UpstreamDriftSummary | null;
|
|
48
44
|
}): React.ReactNode;
|
|
49
45
|
//# sourceMappingURL=LogoV2.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LogoV2.d.ts","sourceRoot":"","sources":["../../../src/components/LogoV2.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAiB,KAAK,GAAG,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"LogoV2.d.ts","sourceRoot":"","sources":["../../../src/components/LogoV2.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAiB,KAAK,GAAG,EAAE,MAAM,YAAY,CAAA;AAapD,OAAO,EAA+E,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAA;AA4CjI;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,MAAM,EACN,GAAG,EACH,SAAiB,EACjB,KAAK,EACL,GAAG,EACH,KAAY,EACZ,SAAgB,EAChB,OAAe,GAChB,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,iFAAiF;IACjF,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,YAAY,CAAA;IACpB,6EAA6E;IAC7E,GAAG,CAAC,EAAE,GAAG,CAAA;IACT,mFAAmF;IACnF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;4CAGwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;mCAG+B;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,GAAG,KAAK,CAAC,SAAS,CA+MlB"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { getLang, t as tr
|
|
3
|
+
import { getLang, t as tr } from '../i18n.js';
|
|
4
4
|
import { pickRandomTip } from '../tips.js';
|
|
5
|
-
import { upstreamDriftSummary, UPSTREAM_VALIDATED_VERSION } from '../dsh-adapter/contract.js';
|
|
6
5
|
import { readFileSync } from 'node:fs';
|
|
7
6
|
import { dirname, join } from 'node:path';
|
|
8
7
|
import { fileURLToPath } from 'node:url';
|
|
@@ -69,7 +68,7 @@ function capitalize(text) {
|
|
|
69
68
|
* blue. Narrow terminals show complete big text, then the whale alone,
|
|
70
69
|
* then a plain title as space runs out.
|
|
71
70
|
*/
|
|
72
|
-
export function LogoV2({ model, effort, cwd, skipIntro = false, intro, tip, whale = true, whaleIdle = true, working = false,
|
|
71
|
+
export function LogoV2({ model, effort, cwd, skipIntro = false, intro, tip, whale = true, whaleIdle = true, working = false, }) {
|
|
73
72
|
// One intro per logo mount: the production path rolls (startup splash
|
|
74
73
|
// and each /deepseek replay roll independently), the `intro` seam pins
|
|
75
74
|
// a specific animation for probes.
|
|
@@ -199,10 +198,6 @@ export function LogoV2({ model, effort, cwd, skipIntro = false, intro, tip, whal
|
|
|
199
198
|
// repaint (language switch, terminal resize), or the line would flicker.
|
|
200
199
|
// `tip` is a test seam; production always passes undefined and rolls.
|
|
201
200
|
const [randomTip] = React.useState(() => tip ?? pickRandomTip());
|
|
202
|
-
// Upstream-drift notice, merged to one line: computed once per mount from
|
|
203
|
-
// the same memoized contract data the adapter checks (undefined when the
|
|
204
|
-
// install matches). `drift` is a test seam to pin or suppress it.
|
|
205
|
-
const [driftLine] = React.useState(() => drift === undefined ? upstreamDriftSummary() : drift);
|
|
206
201
|
// Indent that centers the tagline under the whale art's bounding box.
|
|
207
202
|
const welcomePad = showWhale
|
|
208
203
|
? Math.max(0, Math.round(WHALE_CENTER - stringWidth(tagline) / 2))
|
|
@@ -225,9 +220,5 @@ export function LogoV2({ model, effort, cwd, skipIntro = false, intro, tip, whal
|
|
|
225
220
|
setHeartSeq(0);
|
|
226
221
|
setHeartKey(k => k + 1);
|
|
227
222
|
}
|
|
228
|
-
}, children: _jsx(WhaleArt, { frameIndex: frameIndex, pose: settled && whaleIdle && !whaleFrozen ? (idlePose ?? RESTING_POSE) : undefined, width: WHALE_BOX_WIDTH }) })), (showBigTitle || showPlainTitle) && _jsxs(Box, { flexDirection: "column", flexShrink: 1, children: [_jsxs(Text, { wrap: "truncate-end", children: [sweep('✦ dsh-CLI', t, wordmarkRGB, wordmarkShimmerRGB, 60), _jsx(Text, { dimColor: true, children: ' v' + VERSION })] }), showBigTitle ? _jsxs(_Fragment, { children: [bigDeepSeek.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `ds-${index}`))), bigHarness.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `h-${index}`)))] }) : _jsx(Text, { color: "accent", bold: true, wrap: "truncate-end", children: "DeepSeek Harness" }), _jsxs(Text, { wrap: "truncate-end", children: [model, effort !== undefined && _jsx(Text, { dimColor: true, children: ' · ' + capitalize(effort) + ' effort' })] }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: cwd }), _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { dimColor: true, children: tr('logo-tip-prefix') }), getLang() === 'zh' ? randomTip.zh : randomTip.en, _jsx(Text, { dimColor: true, children: ' · /tips ' + tr('logo-tip-more') })] })
|
|
229
|
-
installed: driftLine.versions.join(' / '),
|
|
230
|
-
validated: UPSTREAM_VALIDATED_VERSION,
|
|
231
|
-
primary: UPSTREAM_VALIDATED_VERSION,
|
|
232
|
-
})] }))] })] }), _jsx(Box, { marginTop: 1, paddingLeft: welcomePad, children: _jsx(Text, { children: sweep(tagline, t, taglineRGB, FLASH, 60) }) })] }));
|
|
223
|
+
}, children: _jsx(WhaleArt, { frameIndex: frameIndex, pose: settled && whaleIdle && !whaleFrozen ? (idlePose ?? RESTING_POSE) : undefined, width: WHALE_BOX_WIDTH }) })), (showBigTitle || showPlainTitle) && _jsxs(Box, { flexDirection: "column", flexShrink: 1, children: [_jsxs(Text, { wrap: "truncate-end", children: [sweep('✦ dsh-CLI', t, wordmarkRGB, wordmarkShimmerRGB, 60), _jsx(Text, { dimColor: true, children: ' v' + VERSION })] }), showBigTitle ? _jsxs(_Fragment, { children: [bigDeepSeek.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `ds-${index}`))), bigHarness.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `h-${index}`)))] }) : _jsx(Text, { color: "accent", bold: true, wrap: "truncate-end", children: "DeepSeek Harness" }), _jsxs(Text, { wrap: "truncate-end", children: [model, effort !== undefined && _jsx(Text, { dimColor: true, children: ' · ' + capitalize(effort) + ' effort' })] }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: cwd }), _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { dimColor: true, children: tr('logo-tip-prefix') }), getLang() === 'zh' ? randomTip.zh : randomTip.en, _jsx(Text, { dimColor: true, children: ' · /tips ' + tr('logo-tip-more') })] })] })] }), _jsx(Box, { marginTop: 1, paddingLeft: welcomePad, children: _jsx(Text, { children: sweep(tagline, t, taglineRGB, FLASH, 60) }) })] }));
|
|
233
224
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundled-presets.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/bundled-presets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bundled-presets.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/bundled-presets.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAoClD;qFACqF;AACrF,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCxE"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RESPONSE_LANGUAGE_POLICY } from './response-language.js';
|
|
1
2
|
import { readFileSync } from 'node:fs';
|
|
2
3
|
import { createRequire } from 'node:module';
|
|
3
4
|
import { join } from 'node:path';
|
|
@@ -13,6 +14,14 @@ function readPresetPatch(path) {
|
|
|
13
14
|
const row = patches[0]?.insert?.[0];
|
|
14
15
|
if (row?.name === '@deepseek-ai/dsh-agent-preset'
|
|
15
16
|
&& typeof row.config?.id === 'string' && Array.isArray(row.config.plugins)) {
|
|
17
|
+
// Only adapt our bundled complete persona; profile-owned declarations bypass this reader.
|
|
18
|
+
if (row.config.id === 'minimal') {
|
|
19
|
+
const persona = row.config.plugins.find((plugin) => plugin.id === 'persona');
|
|
20
|
+
if (persona?.config?.complete !== true || typeof persona.config.prefix !== 'string') {
|
|
21
|
+
throw new Error('dsh-tui: bundled Minimal complete persona is missing');
|
|
22
|
+
}
|
|
23
|
+
persona.config.prefix += `\n\n${RESPONSE_LANGUAGE_POLICY}`;
|
|
24
|
+
}
|
|
16
25
|
return row.config;
|
|
17
26
|
}
|
|
18
27
|
}
|
|
@@ -1,62 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export declare const UPSTREAM_VALIDATED_VERSION = "0.2.0-rc.2";
|
|
3
|
-
/** Update the baseline in place; older releases are unsupported. */
|
|
4
|
-
export declare const UPSTREAM_VALIDATED_VERSIONS: readonly ["0.2.0-rc.2"];
|
|
5
|
-
/**
|
|
6
|
-
* Framework packages version on their own lines; the contract validates
|
|
7
|
-
* their MAJOR (breaking surface), not the harness prerelease number.
|
|
8
|
-
*/
|
|
1
|
+
/** Frameworks have independent, breaking major versions. */
|
|
9
2
|
export declare const UPSTREAM_FRAMEWORK_MAJORS: Record<string, number>;
|
|
10
3
|
/** Official packages the adapter consumes at runtime or as types. */
|
|
11
4
|
export declare const UPSTREAM_BLESSED_PACKAGES: readonly ["@deepseek-ai/cordis", "@deepseek-ai/schemastery", "@deepseek-ai/dsh-invariants", "@deepseek-ai/dsh-agent", "@deepseek-ai/dsh-agent-instructions", "@deepseek-ai/dsh-agent-preset-registry", "@deepseek-ai/dsh-atomic-write", "@deepseek-ai/dsh-ptc-runtime-node", "@deepseek-ai/dsh-commands", "@deepseek-ai/dsh-cordis-host-runner", "@deepseek-ai/dsh-llm", "@deepseek-ai/dsh-llm-pi-ai", "@deepseek-ai/dsh-persona", "@deepseek-ai/dsh-session", "@deepseek-ai/dsh-settings", "@deepseek-ai/dsh-skill", "@deepseek-ai/dsh-storage", "@deepseek-ai/dsh-storage-domain", "@deepseek-ai/dsh-storage-json", "@deepseek-ai/dsh-workspace", "@deepseek-ai/dsh-web-app", "@deepseek-ai/dsh-system-prompt", "@deepseek-ai/dsh-terminal", "@deepseek-ai/dsh-terminal-bash", "@deepseek-ai/dsh-tool-ask-user", "@deepseek-ai/dsh-tool-bash-persistent", "@deepseek-ai/dsh-tool-cordis", "@deepseek-ai/dsh-tool-subagent", "@deepseek-ai/dsh-user-approval", "@deepseek-ai/dsh-user-questions"];
|
|
12
|
-
export
|
|
5
|
+
export declare function installedUpstreamVersions(): Record<string, string | undefined>;
|
|
6
|
+
export interface UpstreamDependencyIssue {
|
|
13
7
|
package: string;
|
|
14
8
|
installed: string | undefined;
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
/** Supported upstream prerelease channels in ascending precedence order. */
|
|
18
|
-
export type UpstreamPrereleaseChannel = 'alpha' | 'beta' | 'rc';
|
|
19
|
-
/** A parsed upstream prerelease version, e.g. `0.1.2-alpha.1` → `[0, 1, 2, 'alpha', 1]`. */
|
|
20
|
-
export type UpstreamVersionTuple = readonly [number, number, number, UpstreamPrereleaseChannel, number];
|
|
21
|
-
/** Parse an upstream prerelease version; undefined when unparseable. */
|
|
22
|
-
export declare function parseUpstreamVersion(version: string | undefined): UpstreamVersionTuple | undefined;
|
|
23
|
-
/** Order two parsed versions: negative/positive/zero as a `<`/`>`/`=`. */
|
|
24
|
-
export declare function compareVersions(a: UpstreamVersionTuple, b: UpstreamVersionTuple): number;
|
|
25
|
-
/** Human-readable supported release. */
|
|
26
|
-
export declare const UPSTREAM_VALIDATED_LABEL = "0.2.0-rc.2";
|
|
27
|
-
export declare function installedUpstreamVersions(): Record<string, string | undefined>;
|
|
28
|
-
/**
|
|
29
|
-
* The distinct installed prerelease versions across the blessed harness
|
|
30
|
-
* packages (framework packages excluded). One entry = coherent install;
|
|
31
|
-
* several = a mixed tree, which the per-package drift check cannot see.
|
|
32
|
-
* Empty when nothing (or no harness package) is installed.
|
|
33
|
-
*/
|
|
34
|
-
export declare function installedUpstreamLines(installedVersions?: Readonly<Record<string, string | undefined>>): string[];
|
|
35
|
-
/**
|
|
36
|
-
* Report every blessed package whose installed version is NOT one of the
|
|
37
|
-
* validated release lines. Empty array = the running install matches the
|
|
38
|
-
* contract.
|
|
39
|
-
*/
|
|
40
|
-
export declare function upstreamDrift(installedVersions?: Readonly<Record<string, string | undefined>>): UpstreamDriftEntry[];
|
|
41
|
-
/**
|
|
42
|
-
* Classification of a drifted install for the one-line boot notice:
|
|
43
|
-
* `newer` / `older` — every drifted harness package sits on a single
|
|
44
|
-
* parseable version off one end of the validated window; `mixed` — several
|
|
45
|
-
* distinct versions coexist (unstable tree); `broken` — something is
|
|
46
|
-
* missing or unparseable and wording cannot get more specific.
|
|
47
|
-
*/
|
|
48
|
-
export type UpstreamDriftKind = 'newer' | 'older' | 'mixed' | 'broken';
|
|
49
|
-
/** Merged drift verdict consumed by the logo header notice (LogoV2). */
|
|
50
|
-
export interface UpstreamDriftSummary {
|
|
51
|
-
kind: UpstreamDriftKind;
|
|
52
|
-
/** Distinct installed versions among drifted packages ('missing' for absent ones). */
|
|
53
|
-
versions: string[];
|
|
9
|
+
reason: string;
|
|
54
10
|
}
|
|
55
|
-
/**
|
|
56
|
-
|
|
57
|
-
* undefined when the install matches the contract. Only harness prerelease packages
|
|
58
|
-
* decide newer/older/mixed; a framework-only drift (e.g. a cordis major
|
|
59
|
-
* bump) reports `broken`, since its version line is not comparable.
|
|
60
|
-
*/
|
|
61
|
-
export declare function upstreamDriftSummary(installedVersions?: Readonly<Record<string, string | undefined>>): UpstreamDriftSummary | undefined;
|
|
11
|
+
/** Require the development dependency surface without restricting DSH releases. */
|
|
12
|
+
export declare function upstreamDependencyIssues(installedVersions?: Readonly<Record<string, string | undefined>>): UpstreamDependencyIssue[];
|
|
62
13
|
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/contract.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/contract.ts"],"names":[],"mappings":"AAIA,4DAA4D;AAC5D,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAG5D,CAAA;AAED,qEAAqE;AACrE,eAAO,MAAM,yBAAyB,o8BA+B5B,CAAA;AAYV,wBAAgB,yBAAyB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAqB9E;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,MAAM,EAAE,MAAM,CAAA;CACf;AAED,mFAAmF;AACnF,wBAAgB,wBAAwB,CACtC,iBAAiB,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAA+B,GAC5F,uBAAuB,EAAE,CAY3B"}
|
|
@@ -1,25 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Upstream compatibility contract.
|
|
3
|
-
*
|
|
4
|
-
* The TUI supports one validated upstream release: 0.2.0-rc.2.
|
|
5
|
-
* Every official package this adapter touches is blessed here; anything
|
|
6
|
-
* else must go through upstream channels or the adapter, never the UI.
|
|
7
|
-
*
|
|
8
|
-
* `upstreamDrift()` powers the CI gate (scripts/verify-upstream-contract.ts)
|
|
9
|
-
* so a mismatched install fails in CI before it fails on a user's machine.
|
|
10
|
-
* `upstreamDriftSummary()` collapses the per-package entries into the
|
|
11
|
-
* single natural-language boot notice the logo header shows (see LogoV2).
|
|
12
|
-
*/
|
|
1
|
+
/** Host dependency boundary. Release labels are diagnostic data, not an allowlist. */
|
|
13
2
|
import { readFileSync } from 'node:fs';
|
|
14
3
|
import { fileURLToPath } from 'node:url';
|
|
15
|
-
/**
|
|
16
|
-
export const UPSTREAM_VALIDATED_VERSION = '0.2.0-rc.2';
|
|
17
|
-
/** Update the baseline in place; older releases are unsupported. */
|
|
18
|
-
export const UPSTREAM_VALIDATED_VERSIONS = [UPSTREAM_VALIDATED_VERSION];
|
|
19
|
-
/**
|
|
20
|
-
* Framework packages version on their own lines; the contract validates
|
|
21
|
-
* their MAJOR (breaking surface), not the harness prerelease number.
|
|
22
|
-
*/
|
|
4
|
+
/** Frameworks have independent, breaking major versions. */
|
|
23
5
|
export const UPSTREAM_FRAMEWORK_MAJORS = {
|
|
24
6
|
'@deepseek-ai/cordis': 4,
|
|
25
7
|
'@deepseek-ai/schemastery': 3,
|
|
@@ -57,33 +39,6 @@ export const UPSTREAM_BLESSED_PACKAGES = [
|
|
|
57
39
|
'@deepseek-ai/dsh-user-approval',
|
|
58
40
|
'@deepseek-ai/dsh-user-questions',
|
|
59
41
|
];
|
|
60
|
-
// These capabilities are optional at runtime. CI requires the complete dev tree.
|
|
61
|
-
const OPTIONAL_RUNTIME_PACKAGES = new Set([
|
|
62
|
-
'@deepseek-ai/dsh-agent-preset-registry',
|
|
63
|
-
'@deepseek-ai/dsh-ptc-runtime-node',
|
|
64
|
-
'@deepseek-ai/dsh-web-app',
|
|
65
|
-
]);
|
|
66
|
-
/** Parse an upstream prerelease version; undefined when unparseable. */
|
|
67
|
-
export function parseUpstreamVersion(version) {
|
|
68
|
-
const match = /^(\d+)\.(\d+)\.(\d+)-(alpha|beta|rc)\.(\d+)$/u.exec(version ?? '');
|
|
69
|
-
return match === null
|
|
70
|
-
? undefined
|
|
71
|
-
: [Number(match[1]), Number(match[2]), Number(match[3]), match[4], Number(match[5])];
|
|
72
|
-
}
|
|
73
|
-
/** Order two parsed versions: negative/positive/zero as a `<`/`>`/`=`. */
|
|
74
|
-
export function compareVersions(a, b) {
|
|
75
|
-
for (const index of [0, 1, 2]) {
|
|
76
|
-
if (a[index] > b[index])
|
|
77
|
-
return 1;
|
|
78
|
-
if (a[index] < b[index])
|
|
79
|
-
return -1;
|
|
80
|
-
}
|
|
81
|
-
const channelRank = { alpha: 0, beta: 1, rc: 2 };
|
|
82
|
-
const channelOrder = channelRank[a[3]] - channelRank[b[3]];
|
|
83
|
-
return channelOrder !== 0 ? channelOrder : a[4] - b[4];
|
|
84
|
-
}
|
|
85
|
-
/** Human-readable supported release. */
|
|
86
|
-
export const UPSTREAM_VALIDATED_LABEL = UPSTREAM_VALIDATED_VERSION;
|
|
87
42
|
function resolvePackageJson(packageName) {
|
|
88
43
|
try {
|
|
89
44
|
const path = import.meta.resolve(`${packageName}/package.json`);
|
|
@@ -95,7 +50,7 @@ function resolvePackageJson(packageName) {
|
|
|
95
50
|
}
|
|
96
51
|
let cachedVersions;
|
|
97
52
|
export function installedUpstreamVersions() {
|
|
98
|
-
// Package manifests do not change
|
|
53
|
+
// Package manifests do not change during one verification process.
|
|
99
54
|
// Frozen so callers can
|
|
100
55
|
// never corrupt the shared cache.
|
|
101
56
|
if (cachedVersions !== undefined)
|
|
@@ -107,7 +62,7 @@ export function installedUpstreamVersions() {
|
|
|
107
62
|
if (path !== undefined) {
|
|
108
63
|
try {
|
|
109
64
|
const manifest = JSON.parse(readFileSync(path, 'utf8'));
|
|
110
|
-
version = manifest.version;
|
|
65
|
+
version = typeof manifest.version === 'string' ? manifest.version : undefined;
|
|
111
66
|
}
|
|
112
67
|
catch {
|
|
113
68
|
version = undefined;
|
|
@@ -118,87 +73,18 @@ export function installedUpstreamVersions() {
|
|
|
118
73
|
cachedVersions = Object.freeze(result);
|
|
119
74
|
return cachedVersions;
|
|
120
75
|
}
|
|
121
|
-
/**
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
for (const packageName of UPSTREAM_BLESSED_PACKAGES) {
|
|
130
|
-
if (UPSTREAM_FRAMEWORK_MAJORS[packageName] !== undefined)
|
|
131
|
-
continue;
|
|
132
|
-
const version = installedVersions[packageName];
|
|
133
|
-
if (version !== undefined && parseUpstreamVersion(version) !== undefined)
|
|
134
|
-
lines.add(version);
|
|
135
|
-
}
|
|
136
|
-
return [...lines].sort((a, b) => compareVersions(parseUpstreamVersion(a), parseUpstreamVersion(b)));
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Report every blessed package whose installed version is NOT one of the
|
|
140
|
-
* validated release lines. Empty array = the running install matches the
|
|
141
|
-
* contract.
|
|
142
|
-
*/
|
|
143
|
-
export function upstreamDrift(installedVersions = installedUpstreamVersions()) {
|
|
144
|
-
const validated = new Set(UPSTREAM_VALIDATED_VERSIONS);
|
|
145
|
-
const drift = [];
|
|
146
|
-
for (const [packageName, installed] of Object.entries(installedVersions)) {
|
|
147
|
-
const expected = UPSTREAM_BLESSED_PACKAGES.includes(packageName);
|
|
148
|
-
if (!expected)
|
|
149
|
-
continue;
|
|
150
|
-
let matches;
|
|
151
|
-
const frameworkMajor = UPSTREAM_FRAMEWORK_MAJORS[packageName];
|
|
152
|
-
if (frameworkMajor !== undefined) {
|
|
153
|
-
const installedMajor = Number((installed ?? '').split('.')[0]);
|
|
154
|
-
matches = installedMajor === frameworkMajor;
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
matches = installed !== undefined && validated.has(installed);
|
|
76
|
+
/** Require the development dependency surface without restricting DSH releases. */
|
|
77
|
+
export function upstreamDependencyIssues(installedVersions = installedUpstreamVersions()) {
|
|
78
|
+
const issues = [];
|
|
79
|
+
for (const name of UPSTREAM_BLESSED_PACKAGES) {
|
|
80
|
+
const installed = installedVersions[name];
|
|
81
|
+
const major = UPSTREAM_FRAMEWORK_MAJORS[name];
|
|
82
|
+
if (typeof installed !== 'string' || installed.trim() === '') {
|
|
83
|
+
issues.push({ package: name, installed, reason: 'package manifest or version is missing' });
|
|
158
84
|
}
|
|
159
|
-
if (!
|
|
160
|
-
|
|
161
|
-
package: packageName,
|
|
162
|
-
installed,
|
|
163
|
-
validated: frameworkMajor !== undefined ? `major ${frameworkMajor}` : UPSTREAM_VALIDATED_LABEL,
|
|
164
|
-
});
|
|
85
|
+
else if (major !== undefined && !installed.startsWith(`${major}.`)) {
|
|
86
|
+
issues.push({ package: name, installed, reason: `requires framework major ${major}` });
|
|
165
87
|
}
|
|
166
88
|
}
|
|
167
|
-
return
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Collapse {@link upstreamDrift} into a single summary for the boot notice:
|
|
171
|
-
* undefined when the install matches the contract. Only harness prerelease packages
|
|
172
|
-
* decide newer/older/mixed; a framework-only drift (e.g. a cordis major
|
|
173
|
-
* bump) reports `broken`, since its version line is not comparable.
|
|
174
|
-
*/
|
|
175
|
-
export function upstreamDriftSummary(installedVersions = installedUpstreamVersions()) {
|
|
176
|
-
const installedLines = installedUpstreamLines(installedVersions);
|
|
177
|
-
if (installedLines.length > 1)
|
|
178
|
-
return { kind: 'mixed', versions: installedLines };
|
|
179
|
-
const drift = upstreamDrift(installedVersions).filter(entry => entry.installed !== undefined || !OPTIONAL_RUNTIME_PACKAGES.has(entry.package));
|
|
180
|
-
if (drift.length === 0)
|
|
181
|
-
return undefined;
|
|
182
|
-
const harness = drift.filter(entry => UPSTREAM_FRAMEWORK_MAJORS[entry.package] === undefined);
|
|
183
|
-
const versions = [...new Set(drift.map(entry => entry.installed ?? 'missing'))];
|
|
184
|
-
if (harness.some(entry => entry.installed === undefined)) {
|
|
185
|
-
return { kind: 'broken', versions };
|
|
186
|
-
}
|
|
187
|
-
const harnessVersions = [...new Set(harness.map(entry => entry.installed))];
|
|
188
|
-
if (harnessVersions.length > 1) {
|
|
189
|
-
return { kind: 'mixed', versions };
|
|
190
|
-
}
|
|
191
|
-
const installed = parseUpstreamVersion(harnessVersions[0] ?? '');
|
|
192
|
-
const validated = parseUpstreamVersion(UPSTREAM_VALIDATED_VERSION);
|
|
193
|
-
if (installed === undefined) {
|
|
194
|
-
return { kind: 'broken', versions };
|
|
195
|
-
}
|
|
196
|
-
const order = compareVersions(installed, validated);
|
|
197
|
-
if (order > 0)
|
|
198
|
-
return { kind: 'newer', versions };
|
|
199
|
-
if (order < 0)
|
|
200
|
-
return { kind: 'older', versions };
|
|
201
|
-
// Identical to the primary validated version — cannot happen (it would
|
|
202
|
-
// not be drift); report broken rather than staying silent.
|
|
203
|
-
return { kind: 'broken', versions };
|
|
89
|
+
return issues;
|
|
204
90
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* dsh-tui plugin entry. The TUI implementation lives in `./plugin.
|
|
2
|
+
* dsh-tui plugin entry. The TUI implementation lives in `./plugin.ts` (its
|
|
3
3
|
* render path is JSX); this module owns the plugin surface (`name`/`inject`/
|
|
4
4
|
* `Config`/`apply`) at the package entry module and delegates
|
|
5
5
|
* `apply` through a dynamic import so entry-scanning tooling and the Loader
|
|
@@ -73,7 +73,7 @@ export interface Config {
|
|
|
73
73
|
* override DSH_TUI_DISABLE_TERMINAL_IMAGES can always force previews off. */
|
|
74
74
|
terminalImages?: boolean;
|
|
75
75
|
/** UI language: `en` / `zh`. When absent, the `DSH_TUI_LANG` env var wins,
|
|
76
|
-
* then the `/lang` choice persisted in `~/.dsh-tui/lang.json`, then `
|
|
76
|
+
* then the `/lang` choice persisted in `~/.dsh-tui/lang.json`, then the locale, falling back to `en`. */
|
|
77
77
|
lang?: string;
|
|
78
78
|
/** Agent preset id new sessions compose from (standard/ptc/minimal/
|
|
79
79
|
* cordis/… when the roster is mounted). When absent, the `/preset` choice
|
|
@@ -142,7 +142,7 @@ export interface Config {
|
|
|
142
142
|
export declare const Config: Schema<Config, RuntimeConfig<Config>>;
|
|
143
143
|
/**
|
|
144
144
|
* Start the interactive TUI front door, delegating to the JSX implementation
|
|
145
|
-
* in `./plugin.
|
|
145
|
+
* in `./plugin.ts` (see its module doc for the full contract).
|
|
146
146
|
* @param ctx - the plugin context.
|
|
147
147
|
* @param config - the validated dsh-tui configuration.
|
|
148
148
|
* @returns a promise settling when the Loader entry has scheduled its runtime.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,MAAM,MAAM,0BAA0B,CAAA;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAA2C,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACzK,OAAO,EAAoB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEzE,eAAO,MAAM,IAAI,YAAY,CAAA;AAU7B,eAAO,MAAM,MAAM,UAAa,CAAA;AAEhC;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;yEAKqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;gDAC4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;gFAE4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;oCACgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;sBAIkB;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,oDAAoD;IACpD,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,mDAAmD;IACnD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;2BAGuB;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;wDAEoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;+DAI2D;IAC3D,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;kFAE8E;IAC9E,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -86,26 +86,20 @@ export const Config = editableConfig(Schema.object({
|
|
|
86
86
|
]);
|
|
87
87
|
/**
|
|
88
88
|
* Start the interactive TUI front door, delegating to the JSX implementation
|
|
89
|
-
* in `./plugin.
|
|
89
|
+
* in `./plugin.ts` (see its module doc for the full contract).
|
|
90
90
|
* @param ctx - the plugin context.
|
|
91
91
|
* @param config - the validated dsh-tui configuration.
|
|
92
92
|
* @returns a promise settling when the Loader entry has scheduled its runtime.
|
|
93
93
|
*/
|
|
94
94
|
export async function apply(ctx, config) {
|
|
95
|
-
// Upstream drift is NO LONGER spammed to stderr here: per-package
|
|
96
|
-
// console.warn lines interleave with the TUI frame redraw and arrive
|
|
97
|
-
// garbled (typewriter animation repaints over them). The merged,
|
|
98
|
-
// natural-language notice now renders in the logo header under the
|
|
99
|
-
// startup tip (LogoV2 ← upstreamDriftSummary); CI keeps the hard gate
|
|
100
|
-
// via scripts/verify-upstream-contract.ts.
|
|
101
95
|
const { apply: tuiApply, handleStartupError } = await import('./plugin.js');
|
|
102
96
|
let disposed = false;
|
|
103
97
|
ctx.effect(() => () => { disposed = true; });
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
void
|
|
98
|
+
// Entry injection already orders the required Host services. Waiting on the
|
|
99
|
+
// whole Loader here can capture this entry's own activation and never start
|
|
100
|
+
// the frontend. Wait for our owner to settle, then start its Cordis-owned
|
|
101
|
+
// child; the original row continues to own volatile Config.
|
|
102
|
+
void ctx.fiber.await().then(() => {
|
|
109
103
|
if (disposed)
|
|
110
104
|
return;
|
|
111
105
|
return ctx.plugin({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,wBAAwB,CAAA;AAGhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACnC,OAAO,EAA+D,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAuDtH,OAAO,EAAE,MAAM,EAAkC,MAAM,UAAU,CAAA;AAgCjE;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,CAcxF;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,yBAAyB,GAAG,eAAe,CAAA;AAErF,wBAAgB,kBAAkB,CAChC,WAAW,UAAgC,EAC3C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,WAAW,CASb;AAED,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,WAAW,GAAE,OAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAs+CzH;AAmMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,GAAG;IACjF,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,YAAY,EAAE,MAAM,IAAI,CAAA;CACzB,CAcA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,KAAK,GAAG,SAAS,CAAA;IAC5B,YAAY,EAAE,KAAK,CAAA;CACpB,GAAG,OAAO,CAQV;AAgBD;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,GAAG,SAAS,EACxD,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,IAAI,EAAE,MAAM,IAAI,GACf,OAAO,CAAC,IAAI,CAAC,CAmFf;AA4HD,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAIrE"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { registerResponseLanguage } from './response-language.js';
|
|
1
2
|
import { randomUUID } from 'node:crypto';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import { SessionId } from '@deepseek-ai/dsh-session';
|
|
@@ -186,11 +187,12 @@ export async function apply(ctx, runtimeConfig, configOwner = ctx) {
|
|
|
186
187
|
}
|
|
187
188
|
// Validate settings before creating an agent or taking over the terminal.
|
|
188
189
|
const tuiSettingsNs = resolveSettingsNamespace(configOwner, Config);
|
|
190
|
+
registerResponseLanguage(ctx);
|
|
189
191
|
await registerBundledPresets(ctx);
|
|
190
192
|
// UI language resolution: DSH_TUI_LANG env var wins, then the
|
|
191
193
|
// active profile `dsh-tui.lang` configuration (applied once the settings
|
|
192
194
|
// namespace registers below), then cordis.yml `lang`, then the
|
|
193
|
-
// persisted `/lang` choice, then `
|
|
195
|
+
// persisted `/lang` choice, then the locale, falling back to `en`. Must settle before the first
|
|
194
196
|
// render so every module resolves strings in the same language.
|
|
195
197
|
const envLang = process.env.DSH_TUI_LANG;
|
|
196
198
|
setLang(isLang(envLang) ? envLang : isLang(config.lang) ? config.lang : resolveStartupLang());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recap.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/recap.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"recap.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/recap.ts"],"names":[],"mappings":"AAEA,YAAY,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAA;AACvE;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAE5D,0DAA0D;AAC1D,eAAO,MAAM,kBAAkB,OAAO,CAAA;AAkBtC;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAmCjG;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWxD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAyBnF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RESPONSE_LANGUAGE_POLICY } from './response-language.js';
|
|
1
2
|
/** Max chars of recent activity fed to the recap call. */
|
|
2
3
|
export const RECAP_RECENT_CHARS = 6000;
|
|
3
4
|
/** How many exchanges (user + assistant) the recap looks back. */
|
|
@@ -32,6 +33,8 @@ export function collectRecentActivity(events, limitChars) {
|
|
|
32
33
|
const record = event;
|
|
33
34
|
if (record['type'] === 'user/message') {
|
|
34
35
|
const data = record['data'];
|
|
36
|
+
if (data?.['source']?.kind !== 'user')
|
|
37
|
+
continue;
|
|
35
38
|
const text = textOfContent(data?.['content']);
|
|
36
39
|
if (text !== undefined)
|
|
37
40
|
entries.push({ role: 'user', text });
|
|
@@ -70,7 +73,8 @@ export function collectRecentActivity(events, limitChars) {
|
|
|
70
73
|
*/
|
|
71
74
|
export function wrapRecapPrompt(activity) {
|
|
72
75
|
return `Create a compact session recap from the activity excerpt below.
|
|
73
|
-
|
|
76
|
+
${RESPONSE_LANGUAGE_POLICY}
|
|
77
|
+
Determine the language from the latest user-authored request in the excerpt and any explicit continuing user preference. Assistant replies and this wrapper are not language signals. Describe the work and its current outcome accurately.
|
|
74
78
|
Return one JSON object with two string fields:
|
|
75
79
|
- "title": a descriptive title of about 2-6 words.
|
|
76
80
|
- "summary": one line of about 10-20 words covering the most recent progress.
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
/** One packaged policy for ordinary, complete-persona and auxiliary requests. */
|
|
3
|
+
export declare const RESPONSE_LANGUAGE_POLICY: string;
|
|
4
|
+
/** Register independently of the replaceable deployment persona. */
|
|
5
|
+
export declare function registerResponseLanguage(ctx: Context): void;
|
|
6
|
+
//# sourceMappingURL=response-language.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-language.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/response-language.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAIlD,iFAAiF;AACjF,eAAO,MAAM,wBAAwB,QAAmF,CAAA;AAExH,oEAAoE;AACpE,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAI3D"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { packagedPresetRoot } from './packaged-presets.js';
|
|
4
|
+
/** One packaged policy for ordinary, complete-persona and auxiliary requests. */
|
|
5
|
+
export const RESPONSE_LANGUAGE_POLICY = readFileSync(join(packagedPresetRoot(), 'response-language.txt'), 'utf8').trim();
|
|
6
|
+
/** Register independently of the replaceable deployment persona. */
|
|
7
|
+
export function registerResponseLanguage(ctx) {
|
|
8
|
+
ctx.inject(['systemPrompt'], ready => {
|
|
9
|
+
ready.systemPrompt.section({ name: 'dsh-cli:response-language', order: 10300, text: RESPONSE_LANGUAGE_POLICY, interpolate: false });
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sideQuestion.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/sideQuestion.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sideQuestion.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/sideQuestion.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAEvE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAazD;AAED,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,yEAAyE;IACzE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,aAAa,CAAC,WAAW,CAAC,CAAA;IACvD,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAA;IACf,iDAAiD;IACjD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,yEAAyE;IACzE,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAuB/B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RESPONSE_LANGUAGE_POLICY } from './response-language.js';
|
|
1
2
|
/**
|
|
2
3
|
* Side Question (`/btw`): a single-turn call without tools, replaying the
|
|
3
4
|
* live session's derived history (prompt-cache reuse, compaction-style
|
|
@@ -13,6 +14,8 @@ import { BlockAssembler } from '@deepseek-ai/dsh-llm';
|
|
|
13
14
|
*/
|
|
14
15
|
export function wrapSideQuestion(question) {
|
|
15
16
|
return `<side-question-context>
|
|
17
|
+
${RESPONSE_LANGUAGE_POLICY}
|
|
18
|
+
Determine the request language from the question after this wrapper, not from this wrapper.
|
|
16
19
|
Give one concise answer to the question below using the conversation already provided.
|
|
17
20
|
This auxiliary call runs alongside the main session. The main task continues independently;
|
|
18
21
|
do not describe it as interrupted, resumed, or as work performed by this call.
|