forked from 27hrs/dsh-long-skin
Expand portrait progression
This commit is contained in:
12
README.md
12
README.md
@@ -2,6 +2,14 @@
|
|||||||
|
|
||||||
把 Harness 的推理等级改为紧凑滑块,并用滑动变祖原项目的 0–30 强度映射同步人物、背景与界面配色。
|
把 Harness 的推理等级改为紧凑滑块,并用滑动变祖原项目的 0–30 强度映射同步人物、背景与界面配色。
|
||||||
|
|
||||||
|
## 效果预览
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
拖动推理等级滑块时,人物形态与界面配色会同步变化:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## 交互规则
|
## 交互规则
|
||||||
|
|
||||||
- 档位直接读取当前模型的 `reasoning.efforts`,不写死数量或名称。
|
- 档位直接读取当前模型的 `reasoning.efforts`,不写死数量或名称。
|
||||||
@@ -24,7 +32,7 @@
|
|||||||
需要先安装 DeepSeek Harness CLI。发布到独立 GitHub 仓库后,可以直接从 Git 安装:
|
需要先安装 DeepSeek Harness CLI。发布到独立 GitHub 仓库后,可以直接从 Git 安装:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
dsh plugin --profile web add 'github:kingOfSoySauce/dsh-liang-skin#v0.1.0'
|
dsh plugin --profile web add 'github:kingOfSoySauce/dsh-liang-skin#v0.1.1'
|
||||||
dsh --profile web --dump-config
|
dsh --profile web --dump-config
|
||||||
dsh --profile web
|
dsh --profile web
|
||||||
```
|
```
|
||||||
@@ -73,4 +81,4 @@ npm run build
|
|||||||
|
|
||||||
## 素材
|
## 素材
|
||||||
|
|
||||||
插件包含运行时所需的图片和视频素材,安装后不需要额外下载。
|
插件包含运行时所需的图片和视频素材,安装后不需要额外下载。0–30 强度轴当前接入 24 张经过审核的人像锚点,滑动时直接切换最近锚点,不做图片交叉渐变。
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 52 KiB |
@@ -27,10 +27,12 @@ final result: passed
|
|||||||
- Tooltip may extend beyond the slider box at either endpoint so its center remains aligned with the thumb
|
- Tooltip may extend beyond the slider box at either endpoint so its center remains aligned with the thumb
|
||||||
- Tooltip now follows the active skin surface: light surface with dark text in the light shell, dark surface with light text in the dark shell
|
- Tooltip now follows the active skin surface: light surface with dark text in the light shell, dark surface with light text in the dark shell
|
||||||
- Light mode retains Harness blue accents and a black badge with light lettering
|
- Light mode retains Harness blue accents and a black badge with light lettering
|
||||||
- Dark mode uses the calibrator's `#c19a49` / `#d5b56e` gold for the badge, hero glow, effort label, slider, and send action
|
- Dark mode uses the calibrator's `#c19a49` / `#d5b56e` gold for the badge, hero glow, effort label, and send action
|
||||||
- Slider thumb, rail, and ticks use one subdued accent family; the send arrow is dark on gold
|
- Slider thumb, rail, and ticks always use the subdued secondary text color; the send arrow is dark on gold
|
||||||
- Light mode slider, rail, and ticks use the secondary text color; the send arrow remains white on blue
|
- Light mode slider, rail, and ticks use the secondary text color; the send arrow remains white on blue
|
||||||
- Portraits render without brightness, contrast, or saturation filters; source artwork supplies the intended tonal grade
|
- Portraits render without brightness, contrast, or saturation filters; source artwork supplies the intended tonal grade
|
||||||
|
- All 24 approved portrait anchors are registered by the host and selected by the client; no image crossfade is used
|
||||||
|
- The custom rail starts and ends at the endpoint ticks, producing terminal T caps instead of crossing past them
|
||||||
- Side-by-side reference comparison: `design-qa-comparison.png`
|
- Side-by-side reference comparison: `design-qa-comparison.png`
|
||||||
- Final implementation capture: `design-qa-final.png`
|
- Final implementation capture: `design-qa-final.png`
|
||||||
|
|
||||||
|
|||||||
BIN
docs/demo.gif
Normal file
BIN
docs/demo.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 MiB |
BIN
docs/preview.png
Normal file
BIN
docs/preview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 882 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "dsh-client-liang-intensity-skin",
|
"name": "dsh-client-liang-intensity-skin",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "dsh-client-liang-intensity-skin",
|
"name": "dsh-client-liang-intensity-skin",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "~18.3.1",
|
"@types/react": "~18.3.1",
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
|
|||||||
18
package.json
18
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "dsh-client-liang-intensity-skin",
|
"name": "dsh-client-liang-intensity-skin",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "滑动变祖:an opt-in adaptive reasoning slider skin for DeepSeek Harness",
|
"description": "滑动变祖:an opt-in adaptive reasoning slider skin for DeepSeek Harness",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -21,12 +21,28 @@
|
|||||||
"assets/liang-evolution.webm",
|
"assets/liang-evolution.webm",
|
||||||
"assets/liang-poster.png",
|
"assets/liang-poster.png",
|
||||||
"assets/portrait-source-v2/stage-00.png",
|
"assets/portrait-source-v2/stage-00.png",
|
||||||
|
"assets/portrait-source-v2/level-01.png",
|
||||||
|
"assets/portrait-source-v2/level-03.png",
|
||||||
|
"assets/portrait-source-v2/level-04.png",
|
||||||
"assets/portrait-source-v2/stage-06.png",
|
"assets/portrait-source-v2/stage-06.png",
|
||||||
|
"assets/portrait-source-v2/level-07.png",
|
||||||
|
"assets/portrait-source-v2/level-09.png",
|
||||||
|
"assets/portrait-source-v2/level-10.png",
|
||||||
"assets/portrait-source-v2/stage-12.png",
|
"assets/portrait-source-v2/stage-12.png",
|
||||||
|
"assets/portrait-source-v2/level-13.png",
|
||||||
|
"assets/portrait-source-v2/level-14.png",
|
||||||
"assets/portrait-source-v2/bridge-15.png",
|
"assets/portrait-source-v2/bridge-15.png",
|
||||||
|
"assets/portrait-source-v2/level-16.png",
|
||||||
|
"assets/portrait-source-v2/level-17.png",
|
||||||
"assets/portrait-source-v2/stage-18.png",
|
"assets/portrait-source-v2/stage-18.png",
|
||||||
|
"assets/portrait-source-v2/level-19.png",
|
||||||
|
"assets/portrait-source-v2/level-21.png",
|
||||||
|
"assets/portrait-source-v2/level-22.png",
|
||||||
"assets/portrait-source-v2/stage-24.png",
|
"assets/portrait-source-v2/stage-24.png",
|
||||||
|
"assets/portrait-source-v2/level-25.png",
|
||||||
"assets/portrait-source-v2/bridge-27.png",
|
"assets/portrait-source-v2/bridge-27.png",
|
||||||
|
"assets/portrait-source-v2/level-28.png",
|
||||||
|
"assets/portrait-source-v2/level-29.png",
|
||||||
"assets/portrait-source-v2/stage-30.png",
|
"assets/portrait-source-v2/stage-30.png",
|
||||||
"cordis.patch.yml",
|
"cordis.patch.yml",
|
||||||
"lib/client.js",
|
"lib/client.js",
|
||||||
|
|||||||
@@ -29,12 +29,28 @@ const PREFERENCE_KEY = "dsh-liang-intensity-skin.enabled";
|
|||||||
|
|
||||||
const PORTRAIT_ANCHORS = [
|
const PORTRAIT_ANCHORS = [
|
||||||
{ level: 0, file: "stage-00.png" },
|
{ level: 0, file: "stage-00.png" },
|
||||||
|
{ level: 1, file: "level-01.png" },
|
||||||
|
{ level: 3, file: "level-03.png" },
|
||||||
|
{ level: 4, file: "level-04.png" },
|
||||||
{ level: 6, file: "stage-06.png" },
|
{ level: 6, file: "stage-06.png" },
|
||||||
|
{ level: 7, file: "level-07.png" },
|
||||||
|
{ level: 9, file: "level-09.png" },
|
||||||
|
{ level: 10, file: "level-10.png" },
|
||||||
{ level: 12, file: "stage-12.png" },
|
{ level: 12, file: "stage-12.png" },
|
||||||
|
{ level: 13, file: "level-13.png" },
|
||||||
|
{ level: 14, file: "level-14.png" },
|
||||||
{ level: 15, file: "bridge-15.png" },
|
{ level: 15, file: "bridge-15.png" },
|
||||||
|
{ level: 16, file: "level-16.png" },
|
||||||
|
{ level: 17, file: "level-17.png" },
|
||||||
{ level: 18, file: "stage-18.png" },
|
{ level: 18, file: "stage-18.png" },
|
||||||
|
{ level: 19, file: "level-19.png" },
|
||||||
|
{ level: 21, file: "level-21.png" },
|
||||||
|
{ level: 22, file: "level-22.png" },
|
||||||
{ level: 24, file: "stage-24.png" },
|
{ level: 24, file: "stage-24.png" },
|
||||||
|
{ level: 25, file: "level-25.png" },
|
||||||
{ level: 27, file: "bridge-27.png" },
|
{ level: 27, file: "bridge-27.png" },
|
||||||
|
{ level: 28, file: "level-28.png" },
|
||||||
|
{ level: 29, file: "level-29.png" },
|
||||||
{ level: 30, file: "stage-30.png" },
|
{ level: 30, file: "stage-30.png" },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
@@ -347,7 +363,7 @@ function LiangEffortSlider({ directory, load, select, presenter, scope }: Slider
|
|||||||
|
|
||||||
const previewIndex = nearestEffortIndex(frame, efforts);
|
const previewIndex = nearestEffortIndex(frame, efforts);
|
||||||
const previewEffort = efforts[previewIndex];
|
const previewEffort = efforts[previewIndex];
|
||||||
const progress = `${(frame / PREVIEW_MAX_FRAME) * 100}%`;
|
const progressRatio = frame / PREVIEW_MAX_FRAME;
|
||||||
|
|
||||||
const commit = async (rawFrame: number) => {
|
const commit = async (rawFrame: number) => {
|
||||||
const targetIndex = nearestEffortIndex(rawFrame, efforts);
|
const targetIndex = nearestEffortIndex(rawFrame, efforts);
|
||||||
@@ -383,7 +399,7 @@ function LiangEffortSlider({ directory, load, select, presenter, scope }: Slider
|
|||||||
{interacting && (
|
{interacting && (
|
||||||
<output
|
<output
|
||||||
className="liang-effort-control__tooltip"
|
className="liang-effort-control__tooltip"
|
||||||
style={{ "--liang-tooltip-position": progress } as React.CSSProperties}
|
style={{ "--liang-slider-ratio": progressRatio } as React.CSSProperties}
|
||||||
>
|
>
|
||||||
{indicatorLabel(frame, efforts)}
|
{indicatorLabel(frame, efforts)}
|
||||||
</output>
|
</output>
|
||||||
@@ -407,7 +423,6 @@ function LiangEffortSlider({ directory, load, select, presenter, scope }: Slider
|
|||||||
disabled={pending || state.status === "selecting"}
|
disabled={pending || state.status === "selecting"}
|
||||||
aria-label="思考等级"
|
aria-label="思考等级"
|
||||||
aria-valuetext={previewEffort?.name ?? ""}
|
aria-valuetext={previewEffort?.name ?? ""}
|
||||||
style={{ "--liang-slider-progress": progress } as React.CSSProperties}
|
|
||||||
onPointerDown={() => {
|
onPointerDown={() => {
|
||||||
dragging.current = true;
|
dragging.current = true;
|
||||||
setInteracting(true);
|
setInteracting(true);
|
||||||
|
|||||||
@@ -267,16 +267,6 @@ body[data-liang-skin="on"]:is(
|
|||||||
}
|
}
|
||||||
|
|
||||||
body[data-liang-skin="on"] .liang-effort-control {
|
body[data-liang-skin="on"] .liang-effort-control {
|
||||||
--liang-control-accent: var(--liang-accent);
|
|
||||||
--liang-control-rail: color-mix(in srgb, var(--liang-accent) 34%, transparent);
|
|
||||||
}
|
|
||||||
|
|
||||||
body[data-liang-skin="on"]:is(
|
|
||||||
[data-liang-stage="0"],
|
|
||||||
[data-liang-stage="1"],
|
|
||||||
[data-liang-stage="2"],
|
|
||||||
[data-liang-stage="3"]
|
|
||||||
) .liang-effort-control {
|
|
||||||
--liang-control-accent: var(--liang-secondary);
|
--liang-control-accent: var(--liang-secondary);
|
||||||
--liang-control-rail: color-mix(in srgb, var(--liang-secondary) 28%, transparent);
|
--liang-control-rail: color-mix(in srgb, var(--liang-secondary) 28%, transparent);
|
||||||
}
|
}
|
||||||
@@ -288,11 +278,22 @@ body[data-liang-skin="on"]:is(
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.liang-effort-control__ticks::before {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 1px;
|
||||||
|
content: "";
|
||||||
|
background: var(--liang-control-rail);
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
.liang-effort-control__tooltip {
|
.liang-effort-control__tooltip {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 4;
|
z-index: 4;
|
||||||
bottom: calc(100% + 7px);
|
bottom: calc(100% + 7px);
|
||||||
left: var(--liang-tooltip-position);
|
left: calc(10px + (100% - 20px) * var(--liang-slider-ratio));
|
||||||
min-width: max-content;
|
min-width: max-content;
|
||||||
padding: 5px 8px;
|
padding: 5px 8px;
|
||||||
border: 1px solid var(--liang-border, rgb(0 0 0 / 12%));
|
border: 1px solid var(--liang-border, rgb(0 0 0 / 12%));
|
||||||
@@ -333,9 +334,9 @@ body[data-liang-skin="on"]:is(
|
|||||||
.liang-effort-control__range {
|
.liang-effort-control__range {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
width: 100%;
|
width: calc(100% - 7px);
|
||||||
height: 28px;
|
height: 28px;
|
||||||
margin: 0;
|
margin: 0 3.5px;
|
||||||
cursor: ew-resize;
|
cursor: ew-resize;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@@ -350,7 +351,7 @@ body[data-liang-skin="on"]:is(
|
|||||||
.liang-effort-control__range::-webkit-slider-runnable-track {
|
.liang-effort-control__range::-webkit-slider-runnable-track {
|
||||||
height: 1px;
|
height: 1px;
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
background: linear-gradient(90deg, var(--liang-control-accent) 0 var(--liang-slider-progress), var(--liang-control-rail) var(--liang-slider-progress) 100%);
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.liang-effort-control__range::-webkit-slider-thumb {
|
.liang-effort-control__range::-webkit-slider-thumb {
|
||||||
@@ -374,12 +375,12 @@ body[data-liang-skin="on"] .liang-effort-control__range::-webkit-slider-thumb {
|
|||||||
|
|
||||||
.liang-effort-control__range::-moz-range-track {
|
.liang-effort-control__range::-moz-range-track {
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background: var(--liang-control-rail);
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.liang-effort-control__range::-moz-range-progress {
|
.liang-effort-control__range::-moz-range-progress {
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background: var(--liang-control-accent);
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.liang-effort-control__range::-moz-range-thumb {
|
.liang-effort-control__range::-moz-range-thumb {
|
||||||
|
|||||||
16
src/index.js
16
src/index.js
@@ -13,12 +13,28 @@ const ASSET_SPECS = [
|
|||||||
["liang-evolution.mp4", "video/mp4"],
|
["liang-evolution.mp4", "video/mp4"],
|
||||||
["liang-poster.png", "image/png"],
|
["liang-poster.png", "image/png"],
|
||||||
["portrait-source-v2/stage-00.png", "image/png"],
|
["portrait-source-v2/stage-00.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-01.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-03.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-04.png", "image/png"],
|
||||||
["portrait-source-v2/stage-06.png", "image/png"],
|
["portrait-source-v2/stage-06.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-07.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-09.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-10.png", "image/png"],
|
||||||
["portrait-source-v2/stage-12.png", "image/png"],
|
["portrait-source-v2/stage-12.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-13.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-14.png", "image/png"],
|
||||||
["portrait-source-v2/bridge-15.png", "image/png"],
|
["portrait-source-v2/bridge-15.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-16.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-17.png", "image/png"],
|
||||||
["portrait-source-v2/stage-18.png", "image/png"],
|
["portrait-source-v2/stage-18.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-19.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-21.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-22.png", "image/png"],
|
||||||
["portrait-source-v2/stage-24.png", "image/png"],
|
["portrait-source-v2/stage-24.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-25.png", "image/png"],
|
||||||
["portrait-source-v2/bridge-27.png", "image/png"],
|
["portrait-source-v2/bridge-27.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-28.png", "image/png"],
|
||||||
|
["portrait-source-v2/level-29.png", "image/png"],
|
||||||
["portrait-source-v2/stage-30.png", "image/png"],
|
["portrait-source-v2/stage-30.png", "image/png"],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user