dsh-code 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +9 -2
- package/README.md +9 -2
- package/lib/index.mjs +96 -23
- package/lib/types/render/animations.d.ts +14 -2
- package/package.json +25 -1
- package/src/app.ts +41 -28
- package/src/render/animations.ts +49 -5
package/README.en.md
CHANGED
|
@@ -39,10 +39,17 @@ Requires Node `^22.19 || >=24` and the preview `dsh` CLI. `DEEPSEEK_API_KEY` is
|
|
|
39
39
|
```sh
|
|
40
40
|
npm install -g @deepseek-ai/dsh dsh-code
|
|
41
41
|
npm install -g pnpm
|
|
42
|
-
dsh plugin --profile cli add dsh-code@0.9.
|
|
42
|
+
dsh plugin --profile cli add dsh-code@0.9.1
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
> Note: pnpm ignores packages published less than 24 hours ago, so pin `dsh-code@0.9.
|
|
45
|
+
> Note: pnpm ignores packages published less than 24 hours ago, so pin `dsh-code@0.9.1` on the release day; the version can be omitted afterwards. npm installs are not affected.
|
|
46
|
+
|
|
47
|
+
### Updating
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
npm install -g dsh-code@0.9.1
|
|
51
|
+
dsh plugin --profile cli add dsh-code@0.9.1
|
|
52
|
+
```
|
|
46
53
|
|
|
47
54
|
Available launch commands:
|
|
48
55
|
|
package/README.md
CHANGED
|
@@ -39,10 +39,17 @@ DSH-Code 保留这套结构,并补充适合编码任务的终端工作流。
|
|
|
39
39
|
```sh
|
|
40
40
|
npm install -g @deepseek-ai/dsh dsh-code
|
|
41
41
|
npm install -g pnpm
|
|
42
|
-
dsh plugin --profile cli add dsh-code@0.9.
|
|
42
|
+
dsh plugin --profile cli add dsh-code@0.9.1
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
> 提示:pnpm 会忽略发布不足 24 小时的包,因此发布首日请使用精确版本 `dsh-code@0.9.
|
|
45
|
+
> 提示:pnpm 会忽略发布不足 24 小时的包,因此发布首日请使用精确版本 `dsh-code@0.9.1`;24 小时后可省略版本号。npm 安装不受此限制。
|
|
46
|
+
|
|
47
|
+
### 更新版本
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
npm install -g dsh-code@0.9.1
|
|
51
|
+
dsh plugin --profile cli add dsh-code@0.9.1
|
|
52
|
+
```
|
|
46
53
|
|
|
47
54
|
可用的启动指令:
|
|
48
55
|
```sh
|
package/lib/index.mjs
CHANGED
|
@@ -26544,6 +26544,15 @@ const DEEPSEEK_WAVE_BANDS = {
|
|
|
26544
26544
|
.35,
|
|
26545
26545
|
.55,
|
|
26546
26546
|
1
|
|
26547
|
+
]],
|
|
26548
|
+
unknown: [[
|
|
26549
|
+
.1,
|
|
26550
|
+
.7,
|
|
26551
|
+
1
|
|
26552
|
+
], [
|
|
26553
|
+
.35,
|
|
26554
|
+
.55,
|
|
26555
|
+
1
|
|
26547
26556
|
]]
|
|
26548
26557
|
},
|
|
26549
26558
|
aurora: {
|
|
@@ -26572,6 +26581,23 @@ const DEEPSEEK_WAVE_BANDS = {
|
|
|
26572
26581
|
.35,
|
|
26573
26582
|
2
|
|
26574
26583
|
]
|
|
26584
|
+
],
|
|
26585
|
+
unknown: [
|
|
26586
|
+
[
|
|
26587
|
+
.35,
|
|
26588
|
+
.15,
|
|
26589
|
+
0
|
|
26590
|
+
],
|
|
26591
|
+
[
|
|
26592
|
+
-.5,
|
|
26593
|
+
.6,
|
|
26594
|
+
1
|
|
26595
|
+
],
|
|
26596
|
+
[
|
|
26597
|
+
.75,
|
|
26598
|
+
.35,
|
|
26599
|
+
2
|
|
26600
|
+
]
|
|
26575
26601
|
]
|
|
26576
26602
|
},
|
|
26577
26603
|
pulse: {
|
|
@@ -26588,15 +26614,25 @@ const DEEPSEEK_WAVE_BANDS = {
|
|
|
26588
26614
|
.45,
|
|
26589
26615
|
.55,
|
|
26590
26616
|
1.1
|
|
26617
|
+
]],
|
|
26618
|
+
unknown: [[
|
|
26619
|
+
.1,
|
|
26620
|
+
.55,
|
|
26621
|
+
.8
|
|
26622
|
+
], [
|
|
26623
|
+
.45,
|
|
26624
|
+
.55,
|
|
26625
|
+
1.1
|
|
26591
26626
|
]]
|
|
26592
26627
|
}
|
|
26593
26628
|
};
|
|
26594
26629
|
/** Original Codex duration used as the animation's sampling timeline. */
|
|
26595
26630
|
function deepseekWaveBaseDuration(tier, style) {
|
|
26631
|
+
const pro = tier === "deepseek" || tier === "unknown";
|
|
26596
26632
|
switch (style) {
|
|
26597
|
-
case "aurora": return
|
|
26598
|
-
case "pulse": return
|
|
26599
|
-
case "wave": return
|
|
26633
|
+
case "aurora": return pro ? 1600 : 1300;
|
|
26634
|
+
case "pulse": return pro ? 1250 : 900;
|
|
26635
|
+
case "wave": return pro ? 1300 : 1e3;
|
|
26600
26636
|
}
|
|
26601
26637
|
}
|
|
26602
26638
|
/**
|
|
@@ -26848,6 +26884,38 @@ function isOfficialDeepSeekLabel(label) {
|
|
|
26848
26884
|
const model = slash < 0 ? "" : label.slice(slash + 1);
|
|
26849
26885
|
return provider.toLowerCase().includes("deepseek") || model.toLowerCase().includes("deepseek");
|
|
26850
26886
|
}
|
|
26887
|
+
/**
|
|
26888
|
+
* Known reasoning-effort ranks in ascending order. Effort ids are opaque
|
|
26889
|
+
* adapter-owned strings, so the rank table covers the conventional names
|
|
26890
|
+
* (off → low → medium → high → xhigh → max/ultra); an unrecognized id
|
|
26891
|
+
* ranks as unknown (0), which never triggers the high-effort wave.
|
|
26892
|
+
*/
|
|
26893
|
+
const EFFORT_RANK = {
|
|
26894
|
+
off: 0,
|
|
26895
|
+
none: 0,
|
|
26896
|
+
low: 1,
|
|
26897
|
+
medium: 2,
|
|
26898
|
+
med: 2,
|
|
26899
|
+
high: 3,
|
|
26900
|
+
xhigh: 4,
|
|
26901
|
+
"x-high": 4,
|
|
26902
|
+
"very-high": 4,
|
|
26903
|
+
max: 5,
|
|
26904
|
+
maximum: 5,
|
|
26905
|
+
ultra: 5
|
|
26906
|
+
};
|
|
26907
|
+
/**
|
|
26908
|
+
* True when an effective reasoning effort is STRICTLY above `high` — the
|
|
26909
|
+
* trigger gate for the "Into the Unknown" wave on non-DeepSeek routes.
|
|
26910
|
+
* Absent efforts and unrecognized ids never qualify.
|
|
26911
|
+
* @param effort - the effective reasoning-effort id ('' or undefined when none).
|
|
26912
|
+
* @returns whether the effort ranks above high.
|
|
26913
|
+
*/
|
|
26914
|
+
function effortAboveHigh(effort) {
|
|
26915
|
+
if (effort === void 0 || effort === "") return false;
|
|
26916
|
+
const rank = EFFORT_RANK[effort.trim().toLowerCase()];
|
|
26917
|
+
return rank !== void 0 && rank > 3;
|
|
26918
|
+
}
|
|
26851
26919
|
//#endregion
|
|
26852
26920
|
//#region src/session-directory.ts
|
|
26853
26921
|
/** Lightweight session-directory projection for the /resume picker. */
|
|
@@ -29134,9 +29202,10 @@ function statusToneProps(tone) {
|
|
|
29134
29202
|
*/
|
|
29135
29203
|
/** Theme anchors for the one-shot composer wave, read from the active palette
|
|
29136
29204
|
* so the wave stays coordinated in both themes. The flash tier runs the
|
|
29137
|
-
* brand blues; the deepseek
|
|
29138
|
-
* richer mix
|
|
29139
|
-
*
|
|
29205
|
+
* brand blues; the deepseek AND unknown tiers swap in the code sky-blue for
|
|
29206
|
+
* a brighter, richer mix (the unknown tier reuses the pro palette). Codex's
|
|
29207
|
+
* Wave bands carry no hue index (only hues[0] tints the row), so the accent
|
|
29208
|
+
* the prompt keeps is always hues[0]. */
|
|
29140
29209
|
function deepseekWaveHues(tier) {
|
|
29141
29210
|
const palette = getPalette();
|
|
29142
29211
|
return tier === "flash" ? [
|
|
@@ -30957,17 +31026,17 @@ function Input({ active, frozen, busy, descriptors, skills, dispatch, steer, int
|
|
|
30957
31026
|
backgroundColor: waveBg(cells.length)
|
|
30958
31027
|
});
|
|
30959
31028
|
if (deepseekWaveWordVisible(waveTick, waveTier, style)) {
|
|
30960
|
-
const word = "deepseek";
|
|
30961
|
-
const start = Math.max(2, Math.floor((contentWidth -
|
|
31029
|
+
const word = waveTier === "unknown" ? "Into the Unknown" : "deepseek";
|
|
31030
|
+
const start = Math.max(2, Math.floor((contentWidth - word.length) / 2));
|
|
30962
31031
|
let clear = true;
|
|
30963
|
-
for (let at = 0; at <
|
|
31032
|
+
for (let at = 0; at < word.length; at += 1) {
|
|
30964
31033
|
const cell = cells[start + at];
|
|
30965
31034
|
if (cell === void 0 || cell.char !== " " && cell.dim !== true) {
|
|
30966
31035
|
clear = false;
|
|
30967
31036
|
break;
|
|
30968
31037
|
}
|
|
30969
31038
|
}
|
|
30970
|
-
if (clear) for (let at = 0; at <
|
|
31039
|
+
if (clear) for (let at = 0; at < word.length; at += 1) {
|
|
30971
31040
|
const cell = cells[start + at];
|
|
30972
31041
|
cell.char = word[at];
|
|
30973
31042
|
cell.color = inkColor(deepseekWaveWordHue(at, hues));
|
|
@@ -30975,7 +31044,7 @@ function Input({ active, frozen, busy, descriptors, skills, dispatch, steer, int
|
|
|
30975
31044
|
cell.dim = false;
|
|
30976
31045
|
}
|
|
30977
31046
|
}
|
|
30978
|
-
if (waveTier === "deepseek" && style === "wave") {
|
|
31047
|
+
if ((waveTier === "deepseek" || waveTier === "unknown") && style === "wave") {
|
|
30979
31048
|
const spark = deepseekWaveSpark(waveTick);
|
|
30980
31049
|
if (spark !== null) {
|
|
30981
31050
|
const last = cells[cells.length - 1];
|
|
@@ -31146,16 +31215,18 @@ function App(props) {
|
|
|
31146
31215
|
const [effortFor, setEffortFor] = (0, import_react.useState)(void 0);
|
|
31147
31216
|
/** Effective reasoning effort, shown in the /model picker and switch notice. */
|
|
31148
31217
|
const [effortLabel, setEffortLabel] = (0, import_react.useState)(props.effort);
|
|
31149
|
-
/** DeepSeek easter egg: switching INTO an official DeepSeek route
|
|
31150
|
-
*
|
|
31151
|
-
*
|
|
31152
|
-
*
|
|
31153
|
-
*
|
|
31154
|
-
*
|
|
31155
|
-
*
|
|
31156
|
-
*
|
|
31157
|
-
*
|
|
31158
|
-
*
|
|
31218
|
+
/** DeepSeek easter egg: switching INTO an official DeepSeek route — or
|
|
31219
|
+
* onto a NON-DeepSeek model running a reasoning effort strictly above
|
|
31220
|
+
* high — plays one of Codex's three ignition styles (Wave / Aurora /
|
|
31221
|
+
* Pulse, picked at random without repeating) across the composer's
|
|
31222
|
+
* padded band (33ms tick, per-style durations), then the band returns
|
|
31223
|
+
* to static while the prompt marker keeps the tier accent. The trigger
|
|
31224
|
+
* follows the applied model label (what the status bar actually shows),
|
|
31225
|
+
* never the initial paint, and the tier is derived from the label and
|
|
31226
|
+
* cached at the switch. The 33ms tick itself lives inside Input, so the
|
|
31227
|
+
* sweep re-renders only the composer row, not the whole tree, at 30fps;
|
|
31228
|
+
* App owns the rarely-changing tier/style and Input starts the sweep
|
|
31229
|
+
* whenever that pair changes. */
|
|
31159
31230
|
const [waveTier, setWaveTier] = (0, import_react.useState)(null);
|
|
31160
31231
|
const [waveStyle, setWaveStyle] = (0, import_react.useState)(null);
|
|
31161
31232
|
const previousModel = (0, import_react.useRef)(void 0);
|
|
@@ -31167,13 +31238,15 @@ function App(props) {
|
|
|
31167
31238
|
const effortChanged = previousEffort.current !== effortLabel;
|
|
31168
31239
|
previousEffort.current = effortLabel;
|
|
31169
31240
|
const modelChanged = previous !== void 0 && previous !== modelLabel;
|
|
31170
|
-
|
|
31241
|
+
const official = isOfficialDeepSeekLabel(modelLabel);
|
|
31242
|
+
const unknownTrigger = !official && effortAboveHigh(effortLabel);
|
|
31243
|
+
if (!official && !unknownTrigger) {
|
|
31171
31244
|
setWaveTier(null);
|
|
31172
31245
|
setWaveStyle(null);
|
|
31173
31246
|
return;
|
|
31174
31247
|
}
|
|
31175
31248
|
if (modelChanged || effortChanged) {
|
|
31176
|
-
setWaveTier(deepseekWaveTier(modelLabel));
|
|
31249
|
+
setWaveTier(official ? deepseekWaveTier(modelLabel) : "unknown");
|
|
31177
31250
|
const nextStyle = deepseekWaveStyleRandom(previousStyle.current);
|
|
31178
31251
|
previousStyle.current = nextStyle;
|
|
31179
31252
|
setWaveStyle(nextStyle);
|
|
@@ -44,11 +44,15 @@ export declare function caretVisible(tick: number): boolean;
|
|
|
44
44
|
/** Frame cadence of the DeepSeek wave: Codex's IGNITION_FRAME_TICK (33ms ≈ 30fps). */
|
|
45
45
|
export declare const DEEPSEEK_WAVE_TICK_MS = 33;
|
|
46
46
|
/**
|
|
47
|
-
* The
|
|
47
|
+
* The DeepSeek wave tiers. The concept maps Codex's reasoning tiers to
|
|
48
48
|
* model ids: `flash` runs the Max parameters, `deepseek` (pro models) runs
|
|
49
49
|
* the Ultra parameters (dual band + tail sparkles on the Wave style).
|
|
50
|
+
* `unknown` is the "Into the Unknown" variant: it reuses the deepseek tier's
|
|
51
|
+
* exact parameters (dual band, durations, sparkles) for NON-DeepSeek models
|
|
52
|
+
* running a reasoning effort above high — the wordmark renders differently
|
|
53
|
+
* but the motion is identical.
|
|
50
54
|
*/
|
|
51
|
-
export type DeepseekWaveTier = 'flash' | 'deepseek';
|
|
55
|
+
export type DeepseekWaveTier = 'flash' | 'deepseek' | 'unknown';
|
|
52
56
|
/**
|
|
53
57
|
* The three ignition styles — Codex `IgnitionStyle`: a traveling crest
|
|
54
58
|
* (Wave), a drifting multi-hue band (Aurora), and an expanding ring (Pulse).
|
|
@@ -197,3 +201,11 @@ export declare function deepseekWaveWordHue(index: number, hues: readonly [RgbTr
|
|
|
197
201
|
* @returns whether the label names an official DeepSeek model.
|
|
198
202
|
*/
|
|
199
203
|
export declare function isOfficialDeepSeekLabel(label: string): boolean;
|
|
204
|
+
/**
|
|
205
|
+
* True when an effective reasoning effort is STRICTLY above `high` — the
|
|
206
|
+
* trigger gate for the "Into the Unknown" wave on non-DeepSeek routes.
|
|
207
|
+
* Absent efforts and unrecognized ids never qualify.
|
|
208
|
+
* @param effort - the effective reasoning-effort id ('' or undefined when none).
|
|
209
|
+
* @returns whether the effort ranks above high.
|
|
210
|
+
*/
|
|
211
|
+
export declare function effortAboveHigh(effort: string | undefined): boolean;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-code",
|
|
3
3
|
"description": "Claude-Code-style interactive TUI bundle for DeepSeek Harness (dsh): DeepSeek-blue whale banner, live session transcript, and a blended status line",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"deepseek": "./bin/deepseek.mjs",
|
|
@@ -93,6 +93,30 @@
|
|
|
93
93
|
"@deepseek-ai/dsh-user-approval": "^0.1.0-rc.6",
|
|
94
94
|
"@deepseek-ai/dsh-user-questions": "^0.1.0-rc.6"
|
|
95
95
|
},
|
|
96
|
+
"peerDependenciesMeta": {
|
|
97
|
+
"@deepseek-ai/cordis": { "optional": true },
|
|
98
|
+
"@deepseek-ai/cordis-plugin-loader": { "optional": true },
|
|
99
|
+
"@deepseek-ai/dsh-agent": { "optional": true },
|
|
100
|
+
"@deepseek-ai/dsh-agent-default-model": { "optional": true },
|
|
101
|
+
"@deepseek-ai/dsh-cmdline": { "optional": true },
|
|
102
|
+
"@deepseek-ai/dsh-code-runtime-worker-thread": { "optional": true },
|
|
103
|
+
"@deepseek-ai/dsh-commands": { "optional": true },
|
|
104
|
+
"@deepseek-ai/dsh-compaction": { "optional": true },
|
|
105
|
+
"@deepseek-ai/dsh-goal": { "optional": true },
|
|
106
|
+
"@deepseek-ai/dsh-invariants": { "optional": true },
|
|
107
|
+
"@deepseek-ai/dsh-llm": { "optional": true },
|
|
108
|
+
"@deepseek-ai/dsh-llm-retry": { "optional": true },
|
|
109
|
+
"@deepseek-ai/dsh-permission-presets": { "optional": true },
|
|
110
|
+
"@deepseek-ai/dsh-plan-mode": { "optional": true },
|
|
111
|
+
"@deepseek-ai/dsh-sandbox-policy": { "optional": true },
|
|
112
|
+
"@deepseek-ai/dsh-session": { "optional": true },
|
|
113
|
+
"@deepseek-ai/dsh-session-persistence": { "optional": true },
|
|
114
|
+
"@deepseek-ai/dsh-session-reference": { "optional": true },
|
|
115
|
+
"@deepseek-ai/dsh-session-title": { "optional": true },
|
|
116
|
+
"@deepseek-ai/dsh-skill": { "optional": true },
|
|
117
|
+
"@deepseek-ai/dsh-user-approval": { "optional": true },
|
|
118
|
+
"@deepseek-ai/dsh-user-questions": { "optional": true }
|
|
119
|
+
},
|
|
96
120
|
"devDependencies": {
|
|
97
121
|
"@deepseek-ai/dsh-compaction": "^0.1.0-rc.6",
|
|
98
122
|
"@deepseek-ai/dsh-commands": "^0.1.0-rc.6",
|
package/src/app.ts
CHANGED
|
@@ -52,6 +52,7 @@ import {
|
|
|
52
52
|
deepseekWaveTier,
|
|
53
53
|
deepseekWaveWordHue,
|
|
54
54
|
deepseekWaveWordVisible,
|
|
55
|
+
effortAboveHigh,
|
|
55
56
|
isOfficialDeepSeekLabel,
|
|
56
57
|
pulseFrame,
|
|
57
58
|
WAVE_BASE_DARK,
|
|
@@ -817,9 +818,10 @@ function statusToneProps(tone: StatusTone): {
|
|
|
817
818
|
|
|
818
819
|
/** Theme anchors for the one-shot composer wave, read from the active palette
|
|
819
820
|
* so the wave stays coordinated in both themes. The flash tier runs the
|
|
820
|
-
* brand blues; the deepseek
|
|
821
|
-
* richer mix
|
|
822
|
-
*
|
|
821
|
+
* brand blues; the deepseek AND unknown tiers swap in the code sky-blue for
|
|
822
|
+
* a brighter, richer mix (the unknown tier reuses the pro palette). Codex's
|
|
823
|
+
* Wave bands carry no hue index (only hues[0] tints the row), so the accent
|
|
824
|
+
* the prompt keeps is always hues[0]. */
|
|
823
825
|
function deepseekWaveHues(tier: DeepseekWaveTier): readonly [RgbTriple, RgbTriple, RgbTriple] {
|
|
824
826
|
const palette = getPalette()
|
|
825
827
|
return tier === 'flash'
|
|
@@ -2307,9 +2309,11 @@ function Input({ active, frozen, busy, descriptors, skills, dispatch, steer, int
|
|
|
2307
2309
|
historyFill: { text: string; index: number } | undefined
|
|
2308
2310
|
/** Marks the accepted entry consumed (called after the fill is applied). */
|
|
2309
2311
|
historyConsumed(): void
|
|
2310
|
-
/** DeepSeek easter-egg wave tier of the applied
|
|
2311
|
-
*
|
|
2312
|
-
*
|
|
2312
|
+
/** DeepSeek easter-egg wave tier of the applied route (null otherwise):
|
|
2313
|
+
* official DeepSeek models drive their flash/pro tiers, non-DeepSeek
|
|
2314
|
+
* models running an effort above high drive the "Into the Unknown"
|
|
2315
|
+
* variant. Drives the persistent prompt glyph/accent and the sparkle
|
|
2316
|
+
* tier. */
|
|
2313
2317
|
waveTier: DeepseekWaveTier | null
|
|
2314
2318
|
/** The ignition style running, if any: Wave / Aurora / Pulse. */
|
|
2315
2319
|
waveStyle: DeepseekWaveStyle | null
|
|
@@ -2772,7 +2776,7 @@ function Input({ active, frozen, busy, descriptors, skills, dispatch, steer, int
|
|
|
2772
2776
|
// starts the sweep whenever that pair changes (App picks a NEW random style
|
|
2773
2777
|
// for every replay — including effort changes on the same route — so the
|
|
2774
2778
|
// pair always differs when a new wave should run) and stops it when the
|
|
2775
|
-
//
|
|
2779
|
+
// route leaves every wave tier (tier becomes null).
|
|
2776
2780
|
const [waveTick, setWaveTick] = useState<number | null>(null)
|
|
2777
2781
|
const wavePrevious = useRef<{ tier: DeepseekWaveTier | null; style: DeepseekWaveStyle | null }>({ tier: null, style: null })
|
|
2778
2782
|
useEffect(() => {
|
|
@@ -2904,11 +2908,12 @@ function Input({ active, frozen, busy, descriptors, skills, dispatch, steer, int
|
|
|
2904
2908
|
while (cells.length < contentWidth) {
|
|
2905
2909
|
cells.push({ char: ' ', backgroundColor: waveBg(cells.length) })
|
|
2906
2910
|
}
|
|
2907
|
-
// The
|
|
2908
|
-
//
|
|
2909
|
-
//
|
|
2911
|
+
// The wordmark rides the wave's middle: `deepseek` on the official
|
|
2912
|
+
// tiers, `Into the Unknown` on the non-DeepSeek high-effort variant —
|
|
2913
|
+
// in the tier's cycled hues, placed in the row's mid-section and only
|
|
2914
|
+
// over blank or placeholder cells — real draft text is never covered.
|
|
2910
2915
|
if (deepseekWaveWordVisible(waveTick!, waveTier!, style)) {
|
|
2911
|
-
const word = 'deepseek'
|
|
2916
|
+
const word = waveTier === 'unknown' ? 'Into the Unknown' : 'deepseek'
|
|
2912
2917
|
const start = Math.max(2, Math.floor((contentWidth - word.length) / 2))
|
|
2913
2918
|
let clear = true
|
|
2914
2919
|
for (let at = 0; at < word.length; at += 1) {
|
|
@@ -2925,9 +2930,10 @@ function Input({ active, frozen, busy, descriptors, skills, dispatch, steer, int
|
|
|
2925
2930
|
}
|
|
2926
2931
|
}
|
|
2927
2932
|
}
|
|
2928
|
-
// The tail sparkles belong to the Wave style's
|
|
2929
|
-
//
|
|
2930
|
-
|
|
2933
|
+
// The tail sparkles belong to the Wave style's pro tiers only (the
|
|
2934
|
+
// deepseek and unknown tiers share the Ultra parameters — Codex paints
|
|
2935
|
+
// spark_frame on Wave+Ultra).
|
|
2936
|
+
if ((waveTier === 'deepseek' || waveTier === 'unknown') && style === 'wave') {
|
|
2931
2937
|
const spark = deepseekWaveSpark(waveTick!)
|
|
2932
2938
|
if (spark !== null) {
|
|
2933
2939
|
const last = cells[cells.length - 1]
|
|
@@ -3141,16 +3147,18 @@ export function App(props: AppProps): ReactElement {
|
|
|
3141
3147
|
const [effortFor, setEffortFor] = useState<ModelRow | undefined>(undefined)
|
|
3142
3148
|
/** Effective reasoning effort, shown in the /model picker and switch notice. */
|
|
3143
3149
|
const [effortLabel, setEffortLabel] = useState<string | undefined>(props.effort)
|
|
3144
|
-
/** DeepSeek easter egg: switching INTO an official DeepSeek route
|
|
3145
|
-
*
|
|
3146
|
-
*
|
|
3147
|
-
*
|
|
3148
|
-
*
|
|
3149
|
-
*
|
|
3150
|
-
*
|
|
3151
|
-
*
|
|
3152
|
-
*
|
|
3153
|
-
*
|
|
3150
|
+
/** DeepSeek easter egg: switching INTO an official DeepSeek route — or
|
|
3151
|
+
* onto a NON-DeepSeek model running a reasoning effort strictly above
|
|
3152
|
+
* high — plays one of Codex's three ignition styles (Wave / Aurora /
|
|
3153
|
+
* Pulse, picked at random without repeating) across the composer's
|
|
3154
|
+
* padded band (33ms tick, per-style durations), then the band returns
|
|
3155
|
+
* to static while the prompt marker keeps the tier accent. The trigger
|
|
3156
|
+
* follows the applied model label (what the status bar actually shows),
|
|
3157
|
+
* never the initial paint, and the tier is derived from the label and
|
|
3158
|
+
* cached at the switch. The 33ms tick itself lives inside Input, so the
|
|
3159
|
+
* sweep re-renders only the composer row, not the whole tree, at 30fps;
|
|
3160
|
+
* App owns the rarely-changing tier/style and Input starts the sweep
|
|
3161
|
+
* whenever that pair changes. */
|
|
3154
3162
|
const [waveTier, setWaveTier] = useState<DeepseekWaveTier | null>(null)
|
|
3155
3163
|
const [waveStyle, setWaveStyle] = useState<DeepseekWaveStyle | null>(null)
|
|
3156
3164
|
const previousModel = useRef<string | undefined>(undefined)
|
|
@@ -3160,18 +3168,23 @@ export function App(props: AppProps): ReactElement {
|
|
|
3160
3168
|
const previous = previousModel.current
|
|
3161
3169
|
previousModel.current = modelLabel
|
|
3162
3170
|
// The wave replays when the applied model changes OR its effort level
|
|
3163
|
-
// changes
|
|
3164
|
-
//
|
|
3171
|
+
// changes (Codex replays the ignition on effort changes too). Official
|
|
3172
|
+
// DeepSeek routes run their flash/pro tiers; a NON-DeepSeek model
|
|
3173
|
+
// running a reasoning effort STRICTLY above high runs the "Into the
|
|
3174
|
+
// Unknown" variant — the deepseek tier's exact motion with a different
|
|
3175
|
+
// wordmark. Any other non-DeepSeek route stays static.
|
|
3165
3176
|
const effortChanged = previousEffort.current !== effortLabel
|
|
3166
3177
|
previousEffort.current = effortLabel
|
|
3167
3178
|
const modelChanged = previous !== undefined && previous !== modelLabel
|
|
3168
|
-
|
|
3179
|
+
const official = isOfficialDeepSeekLabel(modelLabel)
|
|
3180
|
+
const unknownTrigger = !official && effortAboveHigh(effortLabel)
|
|
3181
|
+
if (!official && !unknownTrigger) {
|
|
3169
3182
|
setWaveTier(null)
|
|
3170
3183
|
setWaveStyle(null)
|
|
3171
3184
|
return
|
|
3172
3185
|
}
|
|
3173
3186
|
if (modelChanged || effortChanged) {
|
|
3174
|
-
setWaveTier(deepseekWaveTier(modelLabel))
|
|
3187
|
+
setWaveTier(official ? deepseekWaveTier(modelLabel) : 'unknown')
|
|
3175
3188
|
const nextStyle = deepseekWaveStyleRandom(previousStyle.current)
|
|
3176
3189
|
previousStyle.current = nextStyle
|
|
3177
3190
|
setWaveStyle(nextStyle)
|
package/src/render/animations.ts
CHANGED
|
@@ -59,11 +59,15 @@ export function caretVisible(tick: number): boolean {
|
|
|
59
59
|
export const DEEPSEEK_WAVE_TICK_MS = 33
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
|
-
* The
|
|
62
|
+
* The DeepSeek wave tiers. The concept maps Codex's reasoning tiers to
|
|
63
63
|
* model ids: `flash` runs the Max parameters, `deepseek` (pro models) runs
|
|
64
64
|
* the Ultra parameters (dual band + tail sparkles on the Wave style).
|
|
65
|
+
* `unknown` is the "Into the Unknown" variant: it reuses the deepseek tier's
|
|
66
|
+
* exact parameters (dual band, durations, sparkles) for NON-DeepSeek models
|
|
67
|
+
* running a reasoning effort above high — the wordmark renders differently
|
|
68
|
+
* but the motion is identical.
|
|
65
69
|
*/
|
|
66
|
-
export type DeepseekWaveTier = 'flash' | 'deepseek'
|
|
70
|
+
export type DeepseekWaveTier = 'flash' | 'deepseek' | 'unknown'
|
|
67
71
|
|
|
68
72
|
/**
|
|
69
73
|
* The three ignition styles — Codex `IgnitionStyle`: a traveling crest
|
|
@@ -100,18 +104,22 @@ export const DEEPSEEK_WAVE_BANDS: Readonly<Record<DeepseekWaveStyle, Readonly<Re
|
|
|
100
104
|
flash: [[0.10, 0.75, 1.0]],
|
|
101
105
|
// Wave-Ultra: two offset bands for a richer crest.
|
|
102
106
|
deepseek: [[0.10, 0.70, 1.0], [0.35, 0.55, 1.0]],
|
|
107
|
+
// Into the Unknown reuses the Ultra parameters verbatim.
|
|
108
|
+
unknown: [[0.10, 0.70, 1.0], [0.35, 0.55, 1.0]],
|
|
103
109
|
},
|
|
104
110
|
aurora: {
|
|
105
111
|
// Aurora-Max: two drifting bands (hues 0 and 1).
|
|
106
112
|
flash: [[0.35, 0.15, 0.0], [-0.50, 0.60, 1.0]],
|
|
107
113
|
// Aurora-Ultra: a third band adds hue 2.
|
|
108
114
|
deepseek: [[0.35, 0.15, 0.0], [-0.50, 0.60, 1.0], [0.75, 0.35, 2.0]],
|
|
115
|
+
unknown: [[0.35, 0.15, 0.0], [-0.50, 0.60, 1.0], [0.75, 0.35, 2.0]],
|
|
109
116
|
},
|
|
110
117
|
pulse: {
|
|
111
118
|
// Pulse-Max: one expanding ring.
|
|
112
119
|
flash: [[0.10, 0.60, 1.0]],
|
|
113
120
|
// Pulse-Ultra: two rings (inner weaker, outer stronger).
|
|
114
121
|
deepseek: [[0.10, 0.55, 0.8], [0.45, 0.55, 1.1]],
|
|
122
|
+
unknown: [[0.10, 0.55, 0.8], [0.45, 0.55, 1.1]],
|
|
115
123
|
},
|
|
116
124
|
}
|
|
117
125
|
|
|
@@ -120,10 +128,12 @@ export const DEEPSEEK_WAVE_DURATION_EXTENSION_MS = 200
|
|
|
120
128
|
|
|
121
129
|
/** Original Codex duration used as the animation's sampling timeline. */
|
|
122
130
|
function deepseekWaveBaseDuration(tier: DeepseekWaveTier, style: DeepseekWaveStyle): number {
|
|
131
|
+
// The unknown tier reuses the deepseek (pro) durations exactly.
|
|
132
|
+
const pro = tier === 'deepseek' || tier === 'unknown'
|
|
123
133
|
switch (style) {
|
|
124
|
-
case 'aurora': return
|
|
125
|
-
case 'pulse': return
|
|
126
|
-
case 'wave': return
|
|
134
|
+
case 'aurora': return pro ? 1600 : 1300
|
|
135
|
+
case 'pulse': return pro ? 1250 : 900
|
|
136
|
+
case 'wave': return pro ? 1300 : 1000
|
|
127
137
|
}
|
|
128
138
|
}
|
|
129
139
|
|
|
@@ -404,3 +414,37 @@ export function isOfficialDeepSeekLabel(label: string): boolean {
|
|
|
404
414
|
const model = slash < 0 ? '' : label.slice(slash + 1)
|
|
405
415
|
return provider.toLowerCase().includes('deepseek') || model.toLowerCase().includes('deepseek')
|
|
406
416
|
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Known reasoning-effort ranks in ascending order. Effort ids are opaque
|
|
420
|
+
* adapter-owned strings, so the rank table covers the conventional names
|
|
421
|
+
* (off → low → medium → high → xhigh → max/ultra); an unrecognized id
|
|
422
|
+
* ranks as unknown (0), which never triggers the high-effort wave.
|
|
423
|
+
*/
|
|
424
|
+
const EFFORT_RANK: Readonly<Record<string, number>> = {
|
|
425
|
+
off: 0,
|
|
426
|
+
none: 0,
|
|
427
|
+
low: 1,
|
|
428
|
+
medium: 2,
|
|
429
|
+
med: 2,
|
|
430
|
+
high: 3,
|
|
431
|
+
xhigh: 4,
|
|
432
|
+
'x-high': 4,
|
|
433
|
+
'very-high': 4,
|
|
434
|
+
max: 5,
|
|
435
|
+
maximum: 5,
|
|
436
|
+
ultra: 5,
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* True when an effective reasoning effort is STRICTLY above `high` — the
|
|
441
|
+
* trigger gate for the "Into the Unknown" wave on non-DeepSeek routes.
|
|
442
|
+
* Absent efforts and unrecognized ids never qualify.
|
|
443
|
+
* @param effort - the effective reasoning-effort id ('' or undefined when none).
|
|
444
|
+
* @returns whether the effort ranks above high.
|
|
445
|
+
*/
|
|
446
|
+
export function effortAboveHigh(effort: string | undefined): boolean {
|
|
447
|
+
if (effort === undefined || effort === '') return false
|
|
448
|
+
const rank = EFFORT_RANK[effort.trim().toLowerCase()]
|
|
449
|
+
return rank !== undefined && rank > 3
|
|
450
|
+
}
|