dsh-lowtide 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +141 -0
  2. package/cordis.patch.yml +39 -0
  3. package/lib/client.js +4793 -0
  4. package/lib/client.js.map +1 -0
  5. package/lib/index.js +7423 -0
  6. package/lib/types/client/api.d.ts +169 -0
  7. package/lib/types/client/components/CandidatesView.d.ts +8 -0
  8. package/lib/types/client/components/ConfirmGate.d.ts +6 -0
  9. package/lib/types/client/components/DroppedRow.d.ts +6 -0
  10. package/lib/types/client/components/InterceptCard.d.ts +17 -0
  11. package/lib/types/client/components/MorningReport.d.ts +6 -0
  12. package/lib/types/client/components/NewTaskModal.d.ts +9 -0
  13. package/lib/types/client/components/PriceBand.d.ts +17 -0
  14. package/lib/types/client/components/PricePill.d.ts +8 -0
  15. package/lib/types/client/components/QueueDock.d.ts +8 -0
  16. package/lib/types/client/components/TaskDetail.d.ts +7 -0
  17. package/lib/types/client/components/TaskForm.d.ts +85 -0
  18. package/lib/types/client/components/TaskRow.d.ts +7 -0
  19. package/lib/types/client/components/WindowEditorModal.d.ts +6 -0
  20. package/lib/types/client/components/atoms.d.ts +25 -0
  21. package/lib/types/client/hooks/useInterceptDraft.d.ts +13 -0
  22. package/lib/types/client/i18n.d.ts +348 -0
  23. package/lib/types/client/index.d.ts +15 -0
  24. package/lib/types/client/lib/taskMeta.d.ts +10 -0
  25. package/lib/types/client/settings.d.ts +5 -0
  26. package/lib/types/client/store.d.ts +188 -0
  27. package/lib/types/src/api-trust.d.ts +18 -0
  28. package/lib/types/src/git.d.ts +16 -0
  29. package/lib/types/src/index.d.ts +10 -0
  30. package/lib/types/src/intake.d.ts +54 -0
  31. package/lib/types/src/models.d.ts +38 -0
  32. package/lib/types/src/routes.d.ts +15 -0
  33. package/lib/types/src/runner.d.ts +89 -0
  34. package/lib/types/src/scheduler.d.ts +37 -0
  35. package/lib/types/src/session-picker.d.ts +14 -0
  36. package/lib/types/src/state-machine.d.ts +13 -0
  37. package/lib/types/src/store.d.ts +116 -0
  38. package/lib/types/src/strategies/review-dimensions.d.ts +14 -0
  39. package/lib/types/src/strategies/smart-iterative.d.ts +61 -0
  40. package/lib/types/src/turns.d.ts +97 -0
  41. package/package.json +105 -0
package/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # dsh-lowtide
2
+
3
+ 忙时投递、人工裁定、闲时低价执行、次日执行报告 —— 面向 DeepSeek 峰谷定价(2026-08-17 生效,2026-08-23 起周末全天低谷)的错峰批量任务流水线插件。
4
+
5
+ > **注意**:本包为发布候选状态(v0.1.1)——构建与全部单测已验证通过(core 44 + dsh 124),e2e 需真实 dsh web 实例运行。文档描述的是已实现的能力。
6
+
7
+ ## 一句话
8
+
9
+ 忙时把任务**投递**到队列,**你亲自裁定**哪些任务值得在低价闲时段自动执行,执行完交回一份**执行报告**(结果 + 花费 + 省了多少钱)。
10
+
11
+ ## 四种执行方式
12
+
13
+ | 方式 | 说明 | 费用 |
14
+ |---|---|---|
15
+ | **单次** | 一次完成,等价于普通 harness 提示词+任务 | 单次 |
16
+ | **智能迭代** | 同一会话按轮执行:每轮先做**结构化维度审查**(按任务类型自动选择审查维度,输出问题清单 JSON),再**逐条修复**;无高危问题或修复无明显变化即提前结束。生成 1 轮 + 每轮审查+修复 | 约 1 + (N-1)×2 次调用 |
17
+ | **采样** | N 个独立会话(2–5 可选)各跑一遍同一指令,闲时只**生成** N 份候选结果;之后由**你**挑选最满意的一份(机器不做自动择优) | 约 N 倍 |
18
+ | **复核** | 执行一份结果后,再开一个独立会话以挑剔眼光复核,附审查意见 | 约 2 倍 |
19
+
20
+ - 新建工单时选择执行方式与轮数;迭代/采样/复核旁有 ⓘ 悬停说明。
21
+ - 新建工单时可选**运行模式**(L1 逐条确认 / L2 批次确认 / L3 全自动,按钮组,默认跟随设置页的全局自治级别、可逐任务覆盖);每个按钮都有悬停一句话 + 选中后的详细效果说明。任务统一按「标准开发」权限档执行(投递 UI 不再暴露权限档选择)。
22
+ - 智能迭代的审查历史(每轮评分与问题清单)写入任务详情与执行报告的「审查意见」。
23
+ - 采样任务的候选在任务详情与执行报告中并列呈现(含每份花费),可点击「选这份」记录你的选择。
24
+ - 报告明示「迭代 3 轮 / 采样 3 份 / 已复核 · 实花 ¥X」。
25
+
26
+ ## 峰谷定价与时间语义
27
+
28
+ **DeepSeek 的峰谷定价是什么**:DeepSeek 自 **2026-08-17** 起对 API 实行峰谷分时定价([调价公告 2026-08-13](https://finance.eastmoney.com/a/202608133840616378.html),[生效报道](https://www.dzwww.com/news/ssnews/202608/t20260817_18025522.htm)),自 **2026-08-23** 起**周末全天低谷**([周末调价公告](https://www.ithome.com/0/993/095.htm)):**工作日** 09:00–12:00、14:00–18:00(北京时间)为高峰时段,其余时间为非高峰时段;**周末(周六、周日)全天为非高峰**。非高峰价格约为高峰的一半;部分模型涨幅最高达 1100%。
29
+
30
+ **术语映射**:官方公告里的「高峰 / 非高峰」就是本插件的「忙时 / 闲时」。
31
+
32
+ **时间语义(三种时间,请分清)**:
33
+
34
+ | 时间 | 判定时区 | 说明 |
35
+ |---|---|---|
36
+ | 官方忙时段(默认) | **北京时间**(`Asia/Shanghai`) | 计费正确性要求:DeepSeek 按北京时间收费,插件的省/花账目必须与官方一致,因此未配置自定义窗口时永远按北京时间判定 |
37
+ | 你自定义的忙时/闲时窗口 | **你的本地时间** | 设置页里填的起止时间一律按你机器的本地时区判定(含跨零点窗口) |
38
+ | 闲时运行窗口(批处理) | **你的本地时间** | 未填时区则跟随系统本地时区 |
39
+
40
+ **看官方时段在你本地长什么样**:设置页的「官方定价说明」卡片会显示你当前的系统时区,并把官方忙时段换算成你的本地钟点(跨时区可能出现"前一天/后一天、跨零点"的形态);点「一键采用官方忙时(换算到我的时区)」可直接把换算结果填入自定义窗口。若 DeepSeek 将来调整时段或价目,在设置页修改窗口或价目表覆盖即可,无需改代码。
41
+
42
+ ## 能力(当前已实现)
43
+
44
+ | 界面 | 槽位 | 说明 |
45
+ |---|---|---|
46
+ | ① 价格状态胶囊 | `conversation.session.header.utilities` | 状态点 + 闲时/忙时/执行中 · 待办时显示开跑倒计时 · 队列数(价格明细移入悬停提示);**点击即可编辑闲时/忙时时段**(本地时间 · 多段 · 实时色带预览) |
47
+ | ② 忙时拦截卡 | `conversation.composer`(chain 槽) | 忙时输入时接管 composer:现在就跑 vs 投递闲时队列,草稿保留 |
48
+ | ③ 队列面板 | `conversation.input.dock` | 分组队列 · 行内裁定(✓ 批准 / ⏸ 顺延 / ✕ 放弃)· 已放弃可恢复 · 立即开跑 · 执行中独立分组 |
49
+ | ④ 批次确认卡 | `shell.overlay` | 批次窗口前 T-30min 出现,未放行不执行(fail-safe) |
50
+ | ⑤ 执行报告 | `shell.overlay` | 结论先行:本次已省 ¥X · 异常置顶 · 采样候选择优 · 智能迭代审查意见 · 历史报告 |
51
+ | ⑥ 设置页 | `settings.section` | 官方定价说明(本地时区换算+一键采用)/ 闲时运行窗口(含最大并发)/ 忙时闲时窗口 / 24h 本地时间价格带预览 / 价目表覆盖 / 自治三档 |
52
+
53
+ **核心语义**:只有 `queued` 状态的任务会被闲时 runner 拾取;`pending-review` 是人与机器之间的海关——机器永远不能自己把任务推过这道关(采样模式的"选哪份"也是人的事)。
54
+
55
+ ## 安装(开发)
56
+
57
+ ```powershell
58
+ # 前置:Node ^22.19 / >=24,pnpm 11.7
59
+ pnpm.cmd install
60
+ pnpm.cmd --filter lowtide-core bundle # core 构建产物要先于 dsh 测试
61
+ pnpm.cmd --filter dsh-lowtide bundle # 构建 dsh 宿主半 + 客户端 bundle
62
+
63
+ # 首次:把插件 link 进 profile(client 半按包名从 profile 目录 resolve)
64
+ # 桌面端与网页端通用同一份产物,按需要装入对应 profile:
65
+ npx.cmd --yes @deepseek-ai/dsh@0.1.0-rc.7 plugin --profile desktop add ./packages/dsh # 桌面端
66
+ npx.cmd --yes @deepseek-ai/dsh@0.1.0-rc.7 plugin --profile web add ./packages/dsh # 网页端
67
+
68
+ # 启动(本地源码 checkout 或 npx 均可)
69
+ pnpm.cmd dev # = dsh web --patch ./cordis.dev.yml
70
+ ```
71
+
72
+ ## 数据模型
73
+
74
+ - **状态文件**:`$DSH_HOME/lowtide.json`(`$DSH_HOME` 默认 `~/.dsh`)。若进程暴露 `DSH_PROFILE` 环境变量,则按 profile 隔离为 `$DSH_HOME/profiles/<profile>/lowtide.json`,避免并行实例互相覆盖。**同一时刻只应运行一个写入该文件的实例**(dev 与 desktop profile 分属不同文件的前提是 `DSH_PROFILE` 被正确设置)。
75
+ - **任务生命周期**:`draft → pending-review → queued → preflight → running → done/failed/stale/timeout`,加 `deferred`(顺延)与 `dropped`(软删,可恢复)。
76
+
77
+ ## HTTP API(前缀 `/ds-lowtide/`,同源 + loopback 信任围栏)
78
+
79
+ | 方法 | 路径 | 用途 |
80
+ |---|---|---|
81
+ | GET | `/state` | 聚合状态(窗口/当前价/倒计时/队列/最新报告) |
82
+ | GET | `/events` | SSE 增量推送(客户端降级 4s 轮询) |
83
+ | GET/PUT | `/config` | 读/写配置(窗口、价目、自治档) |
84
+ | POST | `/tasks` | 投递工单(落 pending-review;支持 strategy/rounds) |
85
+ | POST | `/tasks/:id/approve \| defer \| drop \| cancel \| retry \| restore \| delete \| choose-candidate` | 裁定与管理(状态机守卫;choose-candidate 记录采样择优) |
86
+ | POST | `/tasks/approve-all` | 全部放行 |
87
+ | POST | `/estimate` | 测算:峰价(当前模型)vs 谷价(批量模型) |
88
+ | POST | `/batch/run-now` | 立即开跑(测试/手动) |
89
+ | POST | `/dismiss` | 今日不再拦截 |
90
+ | GET | `/health` | 心跳 |
91
+
92
+ ## 执行引擎
93
+
94
+ - **并发调度**:同一批内按工作区分组——同工作区任务串行(git 索引锁安全),不同工作区并行,全局并发上限 `batch.maxConcurrency`(默认 3,设置页可调 1–8)。
95
+ - 每任务独立会话(失败隔离);`agents.create` + `followup` + `whenIdle`;超时/重试一次;迭代(智能迭代)/采样按轮次执行并累加成本。
96
+ - **智能迭代**(iterative):按任务类型自动选择审查维度(代码/文档/测试/重构/通用),每轮输出结构化问题清单并逐条修复;无高危问题或修复无实质变化即提前结束;审查历史进入执行报告的「审查意见」。费用约为生成 1 次 + 每轮(审查+修复)2 次调用。
97
+ - **模型**:默认批量模型 `deepseek-official` / `deepseek-v4-flash`;新建工单「高级设置」里可从**本机 Harness 已接入的任意模型**中选择(含 llm-pi-ai / 自定义 OpenAI 兼容 provider),投递时携带 `model` + `modelProvider`,执行时以该 provider+model 真实运行。选「跟随全局」则使用界面当前选中的模型。非 deepseek 模型无官方价目 → 记账显示「价格未知」(可在设置页 `prices[model]` 手动补价目)。老任务(有 model 无 modelProvider)执行时自动按模型目录推断 provider。
98
+ - **预检**:文件 sha256/size 快照、git HEAD、工作区存在性、窗口适配、预算——任一不符 → stale/deferred,绝不盲跑。
99
+ - **顺延恢复**:窗口开始时 preflight-deferred 任务自动重新入队(`deferCount` ≥3 标失败);用户手动顺延的回到待裁定。
100
+ - 每个窗口只跑一批(跨零点安全);空队列不产生执行报告。
101
+
102
+ ## 权限档(cordis.patch.yml 自带)
103
+
104
+ | preset | sandbox | approval |
105
+ |---|---|---|
106
+ | `lt-readonly` | read-only | never |
107
+ | `lt-standard` | workspace-write | never |
108
+ | `lt-trusted` | danger-full-access | never |
109
+
110
+ 闲时无人值守执行 = 沙箱 + 零审批(fail-closed),任务级权限档由用户在投递时选择。
111
+
112
+ ## 测试
113
+
114
+ ```powershell
115
+ pnpm.cmd --filter lowtide-core test # core 纯函数 44 测试
116
+ pnpm.cmd --filter dsh-lowtide test # dsh 单测 124 测试
117
+ pnpm.cmd --filter dsh-lowtide exec playwright test # e2e(需 dsh web 在 3080 运行)
118
+ ```
119
+
120
+ e2e(10 个 spec,串行执行):`smoke`(双面加载)、`css-vars`(CSS 变量在宿主主题全部可解析)、
121
+ `g1-screens`(六界面明暗截图)、`g2-modal`(新建工单弹窗)、`g3-settings`(设置页)、
122
+ `g4-window-editor`(胶囊窗口编辑器回读)、`g5-concurrency`(跨工作区并发/同工作区串行)、
123
+ `dock-new`(收起/展开态新建弹窗回归)、`full-loop`(投递→裁定→run-now→done→执行报告全闭环,
124
+ 真实 API 执行)、`strategies`(迭代收敛/采样候选+择优/复核审查意见/清空已完成)。
125
+
126
+ ## 安全
127
+
128
+ - 路由带 Host/Origin 信任围栏(loopback + 同源 + `sec-fetch-site` 跨站拒绝);**不要将 3080 直接暴露公网**,远程部署走 SSH 隧道或鉴权反代。
129
+ - Windows 端沙箱为"缓解级"(partial),Linux/macOS 为完整强制;无人值守场景建议叠加任务级文件白名单与预算兜底。
130
+
131
+ ### 威胁模型说明(安全审查结论)
132
+
133
+ - **工作区/文件路径不做"必须位于某目录之下"的限制**:任意绝对路径的工作区是本插件的核心能力(你要在自己的项目目录跑任务)。API 只监听 loopback 且有 Host/Origin 信任围栏,攻击面是本机进程/页面;恶意网页无法直接调用(跨站拒绝)。任务 ID 与文件路径从不参与任何"按路径删除文件"的操作——`delete` 只删除任务记录,不触碰磁盘文件。
134
+ - **状态文件为明文**(任务 prompt、路径、git sha):`lowtide.json` 的读取权限等同于本机用户权限,注意备份与机器安全。
135
+ - **同一时刻只应运行一个写入同一状态文件的实例**:dev 与桌面端请用 `DSH_PROFILE` 隔离(见数据模型节),否则多进程写盘可能相互覆盖。
136
+ - **配置输入已加固**:PUT /config 拒绝非法时区与非法 HH:MM 窗口(400),持久化加载对旧文件保持宽松(升级不丢数据)。
137
+ - 无人值守执行使用沙箱 + 零审批(fail-closed):`lt-readonly` / `lt-standard` / `lt-trusted` 三档按任务选择;L3 全自动会跳过人工确认,切换前有二次确认。
138
+
139
+ ## 许可
140
+
141
+ MIT
@@ -0,0 +1,39 @@
1
+ # dsh-lowtide bundle layer.
2
+ # Applied when a profile lists dsh-lowtide among dsh.profile.bundles
3
+ # (installed via `dsh plugin --profile <name> add dsh-lowtide`).
4
+
5
+ - insert:
6
+ - id: lowtide
7
+ name: dsh-lowtide
8
+
9
+ # Permission presets: a row patch REPLACES the targeted row's whole config,
10
+ # so restate the dsh base table verbatim and append the lowtide presets
11
+ # (read/standard/trusted, all approval=never — night runs are unattended by
12
+ # design).
13
+ - id: permission
14
+ config:
15
+ presets:
16
+ read-only:
17
+ sandbox: read-only
18
+ approval: ask
19
+ workspace-write:
20
+ sandbox: workspace-write
21
+ approval: ask
22
+ danger-full-access:
23
+ sandbox: danger-full-access
24
+ approval: never
25
+ lt-readonly:
26
+ sandbox: read-only
27
+ approval: never
28
+ name: Lowtide read-only
29
+ description: Read-only analysis without approval prompts (lowtide).
30
+ lt-standard:
31
+ sandbox: workspace-write
32
+ approval: never
33
+ name: Lowtide standard
34
+ description: Workspace writes without approval prompts (lowtide).
35
+ lt-trusted:
36
+ sandbox: danger-full-access
37
+ approval: never
38
+ name: Lowtide trusted
39
+ description: Full file access without approval prompts (lowtide).