dsh-plugin-deck-studio 0.2.2 → 0.2.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.
Files changed (64) hide show
  1. package/README.md +6 -1
  2. package/lib/config.js +14 -2
  3. package/package.json +12 -4
  4. package/seeds/docs/assets/screenshots/00-hero.png +0 -0
  5. package/seeds/docs/assets/screenshots/01-home.png +0 -0
  6. package/seeds/docs/assets/screenshots/02-deck-pages.png +0 -0
  7. package/seeds/docs/assets/screenshots/03-script.png +0 -0
  8. package/seeds/docs/assets/screenshots/04-design.png +0 -0
  9. package/seeds/docs/assets/screenshots/05-governance.png +0 -0
  10. package/seeds/docs/assets/screenshots/06-settings.png +0 -0
  11. package/seeds/docs/assets/screenshots/07-new-deck.png +0 -0
  12. package/seeds/docs/assets/screenshots/manual/01-home.png +0 -0
  13. package/seeds/docs/assets/screenshots/manual/02-deck-pages.png +0 -0
  14. package/seeds/docs/assets/screenshots/manual/03-script.png +0 -0
  15. package/seeds/docs/assets/screenshots/manual/04-design.png +0 -0
  16. package/seeds/docs/assets/screenshots/manual/05-governance.png +0 -0
  17. package/seeds/docs/assets/screenshots/manual/06-settings.png +0 -0
  18. package/seeds/docs/assets/screenshots/manual/07-new-deck.png +0 -0
  19. package/seeds/docs/assets/screenshots/manual/legend.json +12 -0
  20. package/seeds/docs/compat.md +127 -0
  21. package/seeds/docs/install.en.md +252 -0
  22. package/seeds/docs/install.md +338 -0
  23. package/seeds/docs/manual.en.md +294 -0
  24. package/seeds/docs/manual.md +258 -0
  25. package/seeds/docs/productization.en.md +212 -0
  26. package/seeds/docs/productization.md +193 -0
  27. package/seeds/docs/sample-deck.en.md +114 -0
  28. package/seeds/docs/sample-deck.md +104 -0
  29. package/seeds/docs/styles.en.md +112 -0
  30. package/seeds/docs/styles.md +100 -0
  31. package/seeds/samples/deckline-intro/README.md +41 -0
  32. package/seeds/samples/deckline-intro/assets/deckline-logo.png +0 -0
  33. package/seeds/samples/deckline-intro/assets/deckline-logo.svg +12 -0
  34. package/seeds/samples/deckline-intro/assets/deckline-mark.png +0 -0
  35. package/seeds/samples/deckline-intro/deckline-intro.pptx +0 -0
  36. package/seeds/samples/deckline-intro/intent.md +48 -0
  37. package/seeds/samples/deckline-intro/materials/project-summary.md +90 -0
  38. package/seeds/samples/deckline-intro/materials/screenshots/01-workbench-deck.png +0 -0
  39. package/seeds/samples/deckline-intro/materials/screenshots/02-home-decks.png +0 -0
  40. package/seeds/samples/deckline-intro/materials/screenshots/03-home-designs.png +0 -0
  41. package/seeds/samples/deckline-intro/materials/screenshots/04-new-deck-popup.png +0 -0
  42. package/seeds/samples/deckline-intro/materials.md +110 -0
  43. package/seeds/samples/deckline-intro/pages/p01.png +0 -0
  44. package/seeds/samples/deckline-intro/pages/p02.png +0 -0
  45. package/seeds/samples/deckline-intro/pages/p03.png +0 -0
  46. package/seeds/samples/deckline-intro/pages/p04.png +0 -0
  47. package/seeds/samples/deckline-intro/pages/p05.png +0 -0
  48. package/seeds/samples/deckline-intro/pages/p06.png +0 -0
  49. package/seeds/samples/deckline-intro/pages/p07.png +0 -0
  50. package/seeds/samples/deckline-intro/pages/p08.png +0 -0
  51. package/seeds/samples/deckline-intro/pages/p09.png +0 -0
  52. package/seeds/samples/deckline-intro/pages/p10.png +0 -0
  53. package/seeds/samples/deckline-intro/popup.md +87 -0
  54. package/seeds/samples/deckline-intro/prompts/p01.txt +4 -0
  55. package/seeds/samples/deckline-intro/prompts/p02.txt +6 -0
  56. package/seeds/samples/deckline-intro/prompts/p03.txt +6 -0
  57. package/seeds/samples/deckline-intro/prompts/p04.txt +6 -0
  58. package/seeds/samples/deckline-intro/prompts/p05.txt +6 -0
  59. package/seeds/samples/deckline-intro/prompts/p06.txt +6 -0
  60. package/seeds/samples/deckline-intro/prompts/p07.txt +6 -0
  61. package/seeds/samples/deckline-intro/prompts/p08.txt +6 -0
  62. package/seeds/samples/deckline-intro/prompts/p09.txt +6 -0
  63. package/seeds/samples/deckline-intro/prompts/p10.txt +6 -0
  64. package/seeds/samples/deckline-intro/script.md +88 -0
package/README.md CHANGED
@@ -10,7 +10,10 @@ DSH(DeepSeek Harness)的 **image deck 工作台插件**:左侧原生 Chat
10
10
  dsh --profile deckline --from-default-profile web
11
11
 
12
12
  # 2) 安装本插件(安装后会自动注册 bundle,无需手动改配置文件)
13
- dsh plugin --profile deckline add dsh-plugin-deck-studio@0.2.2
13
+ dsh plugin --profile deckline add dsh-plugin-deck-studio@0.2.4
14
+
15
+ # 国内网络建议走镜像(否则从 npmjs.org 拉 20 MB 包可能很慢)
16
+ npm_config_registry=https://registry.npmmirror.com dsh plugin --profile deckline add dsh-plugin-deck-studio@0.2.4
14
17
 
15
18
  # 3) 启动,浏览器打开终端打印的带 token 链接
16
19
  dsh --profile deckline --port 13090
@@ -22,6 +25,8 @@ dsh --profile deckline --port 13090
22
25
  dsh --profile deckline --dump-config | grep -c "preset-deck-critic"
23
26
  ```
24
27
 
28
+ 在 npmjs.com 搜 `deckline` 或 `ppt dsh` 也能找到。也可以在 DSH「插件 → 发现」里加索引源 `https://cdn.jsdelivr.net/gh/yuna78/dsh-deck-studio@main/market-index.json` 后点安装。
29
+
25
30
  从源码 / Git 安装、Windows、以及完整配置(数据目录 / deck 源 / 出图节点 / key)见仓库文档:
26
31
 
27
32
  - [docs/install.md](https://github.com/yuna78/dsh-deck-studio/blob/main/docs/install.md)(中文)
package/lib/config.js CHANGED
@@ -9,6 +9,7 @@
9
9
  * @module dsh-plugin-deck-studio/config
10
10
  */
11
11
 
12
+ import { existsSync } from "node:fs";
12
13
  import { dirname, join, resolve } from "node:path";
13
14
  import { DEFAULT_MAX_REVIEWERS, HARD_MAX_REVIEWERS } from "./review-personas.js";
14
15
  import { fileURLToPath } from "node:url";
@@ -16,9 +17,20 @@ import { fileURLToPath } from "node:url";
16
17
  /** 插件包根目录(lib/ 的上一级——本文件住在 lib/ 里)。 */
17
18
  export const PLUGIN_DIR = dirname(dirname(fileURLToPath(import.meta.url)));
18
19
 
19
- /** 仓库根:插件住在 `<repo>/plugin/deck-studio/`。 */
20
+ /**
21
+ * 资产根:开发仓库根 `<repo>/plugin/deck-studio/` 的上一级。
22
+ *
23
+ * npm 安装时插件在 `<profile>/node_modules/dsh-plugin-deck-studio`,上两级是 node_modules,
24
+ * 那里没有 samples / docs;公开包把手册与示例 deck 一起打进包内 `seeds/`(prepack 生成),
25
+ * 这种情况回退到 `seeds/`,否则「使用手册」和首次启动的示例 deck 在 npm 安装下是空的。
26
+ */
20
27
  export function repoRootFrom(pluginDir = PLUGIN_DIR) {
21
- return resolve(pluginDir, "..", "..");
28
+ const repo = resolve(pluginDir, "..", "..");
29
+ const looksLikeRepo = existsSync(join(repo, "samples", "deckline-intro", "script.md")) || existsSync(join(repo, "docs", "manual.md"));
30
+ if (looksLikeRepo) return repo;
31
+ const bundled = join(pluginDir, "seeds");
32
+ if (existsSync(join(bundled, "docs", "manual.md"))) return bundled;
33
+ return repo;
22
34
  }
23
35
 
24
36
  /**
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "dsh-plugin-deck-studio",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "private": false,
5
- "description": "Deckline:DSH image deck 工作台插件 —— 原生 Chat + 整页图片 deck 工作区 + 设计风格(design)库;出图按页留痕、可点名批量连出,产物本地可追踪。",
5
+ "description": "Deckline:DSH 的 image deck / PPT 工作台插件——原生 Chat + 整页图片 deck 工作区 + 设计风格库;用对话做 PPT、按页出图、版本可追踪、导出 PDF/PPTX。",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "main": "./index.js",
@@ -19,7 +19,14 @@
19
19
  "image-deck",
20
20
  "presentation",
21
21
  "slides",
22
- "deckline"
22
+ "ppt",
23
+ "pptx",
24
+ "powerpoint",
25
+ "ai-ppt",
26
+ "slide-deck",
27
+ "deckline",
28
+ "幻灯片",
29
+ "演示文稿"
23
30
  ],
24
31
  "engines": {
25
32
  "node": "^22.19.0 || >=24.0.0",
@@ -27,7 +34,8 @@
27
34
  },
28
35
  "scripts": {
29
36
  "verify": "node verify/smoke.mjs",
30
- "prepublishOnly": "node verify/smoke.mjs"
37
+ "prepublishOnly": "node verify/smoke.mjs",
38
+ "prepack": "node scripts/prepack-assets.mjs"
31
39
  },
32
40
  "dsh": {
33
41
  "bundle": {
@@ -0,0 +1,12 @@
1
+ {
2
+ "02-deck-pages": {
3
+ "1": "脚本 tab",
4
+ "2": "出图节点 / 模型",
5
+ "3": "内容密度",
6
+ "4": "添加页面",
7
+ "5": "全屏演示",
8
+ "6": "导出",
9
+ "7": "微调 script",
10
+ "8": "重新出图"
11
+ }
12
+ }
@@ -0,0 +1,127 @@
1
+ # DSH 兼容矩阵(定期回归记录)
2
+
3
+ > 口径:DSH 处于 prerelease 阶段,没有 stable 线;本项目**定期批次**回归,不逐 rc 跟。
4
+ > 每个批次记录:证实的版本、验证范围、断点、复现方式。已知限制与路线见 [productization.md](productization.md) 与 [install.md](install.md)。
5
+
6
+ ## 当前支持声明
7
+
8
+ | 项 | 值 | 说明 |
9
+ |---|---|---|
10
+ | `peerDependencies["@deepseek-ai/dsh"]` | `>=0.1.7-0 <0.2.0 \|\| >=0.2.0-0 <0.3.0 \|\| >=0.2.1-0 <0.3.0` | 装到 0.3+ 会被 DSH 的 peer 检查拦下 |
11
+ | `engines.dsh` | `>=0.1.7-0 <0.3.0` | 元数据口径,同 peer |
12
+ | `engines.node` | `^22.19.0 \|\| >=24.0.0` | 与 DSH 运行时要求一致;**Node 23 不在范围内** |
13
+ | 已验证版本 | `0.1.7-rc.2`(旧基线)· `0.2.1-rc.2`(2026-10-21:隔离环境 + 本地全局升级后真机回归) | 见下表 |
14
+
15
+ ## 回归记录
16
+
17
+ ### 批次 1 · 2026-10-21 · DSH `0.2.1-rc.2`
18
+
19
+ 隔离环境,不动本机 `0.1.7-rc.2` 与运行中的 deck-studio profile:
20
+
21
+ ```bash
22
+ # 临时安装(Node 必须 ^22.19 || >=24;本机默认 Node 23.11 不满足,用 nvm v24.21.0)
23
+ npm i --prefix /tmp/dsh02 @deepseek-ai/dsh@0.2.1-rc.2
24
+ export DSH_HOME=/tmp/dsh02-home PATH="$HOME/.nvm/versions/node/v24.21.0/bin:$PATH"
25
+ dsh --profile deckline-02 --from-default-profile web --dump-config
26
+ dsh plugin --profile deckline-02 add <repo>/plugin/deck-studio
27
+ dsh --profile deckline-02 --port 13290
28
+ ```
29
+
30
+ | 检查项 | 结果 | 证据 |
31
+ |---|---|---|
32
+ | `dsh -V` / CLI 启动 | ✅ `0.2.1-rc.2` | 需 Node 24(0.2.x 的 `bin.js` 用 `import.meta.main`,Node 23 会静默不执行) |
33
+ | 插件安装(本地 link) | ✅ 无 peer 冲突,进入 `dsh.profile.bundles` | `dsh plugin add` 输出 `+ dsh-plugin-deck-studio link:…` |
34
+ | 组合配置(根 mount / preset / tools) | ✅ `deck-studio`、`preset-deck-studio`、`deck-studio-tools` 均在 `--dump-config` 中 | 无组合报错 |
35
+ | Web 启动 + 插件装载 | ✅ 侧栏出现「Deckline」,`/api/deck-studio.app` iframe 加载 | 截图 `/tmp/f86-02-home.png` |
36
+ | Deckline 首页 | ✅ Decks / Designs / 资源库 / Conversations + 数据(designs 11) | `/tmp/f86-02-app-home.png` |
37
+ | Designs 列表 + 预设风格 | ✅ 11 个风格(含 8 个预设),「导入预设风格」入口在 | `/tmp/f86-02-designs.png` |
38
+ | Design 详情(BIZ / PCL) | ✅ 3/4 张样张、风格定义、样张墙 | `/tmp/f86-02-design-biz.png` |
39
+ | 样张媒体 GET | ✅ 200 / 1,383,788 bytes | `/api/deck-studio.media?…designs%2FBIZ%2Fsample-v001.png` |
40
+ | 设置面板(节点自配口径) | ✅ 显示「生图配置未就绪 / 未配置 endpoint / key 未配置」+ docs 指引 | `/tmp/f86-02-settings.png` |
41
+ | 控制台 / 页面异常 | ✅ 0 console error、0 pageerror | 同上脚本输出 |
42
+ | Agent 工具链路 | ⏭ 未验证(隔离 home 无 LLM key) | 下批用真 key 跑 `S01/S02` + `--only` |
43
+ | 真出图(real render) | ⏭ 未验证 | 需本机节点/key;fake 模式已验证 |
44
+
45
+ **观察项(不阻塞)**:iframe 内导航时 `/plugins/events`(DSH 的插件事件 SSE)报 `ERR_ABORTED`,
46
+ 页面功能与数据均正常,判断为导航时主动中断连接,记录待后续批次复核。
47
+
48
+ **结论**:`0.2.1-rc.2` 在「插件安装 → 组合 → Web 加载 → Deckline 应用/样张/设置」链路上可用;
49
+ agent 工具链路与真出图待下批补验。支持声明暂不收紧到 0.2.x-only,保持 `0.1.7–0.2.x` 区间。
50
+
51
+ ## 下批要做(每月 / 或 DSH 0.3 发布前)
52
+
53
+ 1. 真出图探活 1 页(0.2.1 上,确认 image adapter 无破坏);
54
+ 2. 合并评估脚本修复:S11「读到的原文含报错字样」误报、S13 台账表解析口径;
55
+ 3. 复核 `/plugins/events` ERR_ABORTED;
56
+ 4. 若 DSH 发布 0.3.x:先按本表跑一遍,再更新 `peerDependencies` / 本文件 / README 支持声明。
57
+
58
+ ### 批次 2 · 2026-10-21 · DSH `0.2.1-rc.2` 真机 + Agent 链路(本地全局升级后)
59
+
60
+ 批次 1 的隔离环境没有 LLM key,Agent 链路未验证;本机升级到 `0.2.1-rc.2` 后用真 key 补验,同时发现一个
61
+ 0.2.x 的破坏性差异并已修复。
62
+
63
+ | 检查项 | 结果 | 证据 |
64
+ |---|---|---|
65
+ | 真机数据迁移 | ✅ decks 5→7 / designs 11 / conversations 20 均保留 | 升级回归(见下节「本地环境升级记录」) |
66
+ | persona 提示词变量 | ❌→✅ 0.2.x 只注册 `provider` / `model` 两个变量;插件 persona suffix 里的 `{{cwd}}` 使每个 Agent 回合直接 `turn/end` 报 `unknown prompt variable "{{cwd}}"`,Chat 完全不回话 | 会话 `session.v4.jsonl.zstd` 的 `turn/end` error;修复 commit `1dd8695`(改成静态「工作目录是本 deck 仓库根目录,以工具返回路径为准」)+ smoke 增加禁 `{{cwd}}` 断言 |
67
+ | Agent 全场景评估 | ✅ 16 场景中 15 通过(S01–S16) | `.deck/eval/run-20261021-000149/report.md` |
68
+ | S11 假失败 | ✅ 复跑 PASS(eval 误报:`deck_file_read` 读到 `smoke.mjs` 原文里含「未知 deck」字样被当成工具报错) | 临时补丁复跑 `.deck/eval/run-20261021-001453/report.md`;正式修复待评估脚本合并 |
69
+ | S13 新增场景 | ⏭ 非 0.2.1 回归:检查器按标准台账表解析,agent 用自定义台账表 → 解析 0 条 | 同 report.md;属 WIP 场景口径问题 |
70
+ | 工具链路 | ✅ 真实调用 overview / 读文件 / 读文档 / 文档更新 / script 提案 / note_change / style_update | eval 每回合工具序列 |
71
+ | real 出图探活(adapter) | ✅ 2026-10-21 在 DSH 0.2.1 的 Node 24 上跑 `createRealRenderer`:POST 200 / 18.5s,1024×1024 PNG 1.3MB,图片内容与 prompt 一致 | `/tmp/f94-probe/out5/image.png`;探针脚本一次性放 /tmp,不入库 |
72
+ | CDN 下载抖动 | ⚠️→✅ 中转返回 `data[0].url` 走 Cloudflare CDN,本网络下连续 4 次 `ETIMEDOUT` 后第 5 次成功;插件已加**5 次指数退避重试**(`lib/render.js`) | probe 日志 `fetch#2–#6`;smoke 新增重试测试 |
73
+ | smoke / 公开包 | ✅ 47/47;96 文件 / 5.87 MB(含 4 份英文文档) | `smoke.mjs` / `build-public-bundle.mjs` |
74
+
75
+ **结论**:`0.2.1-rc.2` 上插件与 Agent 链路可用,但 **persona 提示词变量只能用 `provider` / `model`**;
76
+ 本仓已修复并加 smoke 防回归;real 出图 adapter 已在 0.2.1 的 Node 24 上以一页 1024×1024 探活通过。
77
+
78
+ **操作观察(不阻塞)**:13090 重启后约 1 分钟内,`/api/deck-studio.app` 可能还没把 `STATE.data.active`
79
+ 挂好(脚本直接 `goto` 会误判「工作台没加载」);等插件 patch 应用完成或先 warm-up 一次再跑自动化。
80
+ `/plugins/events` 仍是导航时 `ERR_ABORTED`,功能正常。
81
+
82
+ ## 升级记录(0.2.1-rc.2,验证机)
83
+
84
+ **升级前**:全局 `@deepseek-ai/dsh@0.1.7-rc.2`;**升级后**:`0.2.1-rc.2`(npm `latest`)。
85
+
86
+ ```bash
87
+ # 建议先备份 profile(仓库外)
88
+ tar -czf ~/dsh-profiles-backup.tgz -C ~/.dsh profiles
89
+ # 升级全局包(Node 需 ^22.19 || >=24)
90
+ npm i -g @deepseek-ai/dsh@0.2.1-rc.2
91
+ # 重启 profile
92
+ dsh --profile deckline --no-open
93
+ ```
94
+
95
+ **回归结果**:
96
+
97
+ | 检查项 | 结果 |
98
+ |---|---|
99
+ | `dsh --version` | ✅ `0.2.1-rc.2` |
100
+ | `--dump-config` | ✅ 0 stderr,插件 / 预设 / tools 条目不丢 |
101
+ | 启动 13090 | ✅ 正常打印 token,无迁移报错 |
102
+ | 既有数据 | ✅ 升级后 decks / designs / 资源库 / Conversations / 治理数据都在 |
103
+ | Deckline 应用 | ✅ 首页 / Design 列表 / Deck 工作台(意图 / 脚本 / Design / 日志… + image storyboard) |
104
+ | 出图节点 | ✅ 节点 `/v1/models` 探活 200 |
105
+ | 页面异常 | ✅ 0 pageerror |
106
+
107
+ **运行要求**:LLM 与出图节点的 key 由 profile / 环境变量提供(出图节点见 `apiKeyEnv`)。不带 key 时服务能起,
108
+ 但 chat / 出图会失败;fake 模式下不配 key 也能走完整流程。
109
+
110
+ **回滚**:`npm i -g @deepseek-ai/dsh@0.1.7-rc.2` → 解压备份的 `profiles` 覆盖 `~/.dsh/profiles` → 重启。
111
+
112
+ ## 已知安装失败:缺 DSH 内置包
113
+
114
+ - 症状:`dsh --profile <your> --port 13090` 启动时报
115
+ `failed to import loader entry preset-deck-studio (@deepseek-ai/dsh-agent-preset): Cannot find package '@deepseek-ai/dsh-agent-preset'`。
116
+ - 原因:当前 `dsh` 不是完整 npm 发行版(常见于从源码 checkout / 自编译,或 PATH 里指向了旧安装)。
117
+ - 处理:`which -a dsh` 确认实际路径 → 用 `npm i -g @deepseek-ai/dsh@0.2.1-rc.2` 的发行版启动;
118
+ 已在本机验证 0.2.1-rc.2 正常。详见 [install.md](install.md) §4.3。
119
+
120
+ ## 最低版本与 0.1.5
121
+
122
+ - Deckline 要求 **DSH ≥ 0.1.7 < 0.3**;**0.1.5 及更早不支持**(没有 preset 需要的
123
+ `@deepseek-ai/dsh-agent-preset` 等内置包,启动会直接报 `Cannot find package`)。
124
+ - 用 `dsh --version` 确认;是 0.1.x 旧安装(常见于源码 checkout / 旧 PATH)时,改用
125
+ `npm i -g @deepseek-ai/dsh@0.2.1-rc.2` 的发行版,并确认 `which -a dsh` 第一个是它。
126
+ - 升级后建议重建 deckline profile(`dsh --profile deckline --from-default-profile web --dump-config` 后再
127
+ `dsh plugin --profile deckline add ...`),避免沿用旧版本的 profile 模板。
@@ -0,0 +1,252 @@
1
+ # Install & configure (Deckline · DSH plugin)
2
+
3
+ Deckline (`dsh-plugin-deck-studio`) is an **image-deck workbench plugin** for DeepSeek Harness (DSH):
4
+ native DSH chat on the left, a full-page image-deck workspace in the middle, and library / Designs /
5
+ assets / conversations on the right. It is not a standalone app — it runs on a DSH profile.
6
+
7
+ > Target users: people who build content and presentations with DSH. After setup you can edit a deck
8
+ > from its script, render slide images on request (single page or a named batch), manage governance documents, register your own
9
+ > design styles (with sample images) and start from 8 preset styles.
10
+
11
+ ## 0. Prerequisites
12
+
13
+ | Dependency | Version | Notes |
14
+ |---|---|---|
15
+ | Node.js | `^22.19` or `≥ 24` | Same as the DSH runtime; Node 23 is not supported |
16
+ | pnpm | 10+ | DSH uses pnpm to manage profile dependencies |
17
+ | DSH | `≥ 0.1.7 < 0.3` | `npm i -g @deepseek-ai/dsh`; verified on 0.1.7-rc.2 / 0.2.1-rc.2, see [compat.md](compat.md) |
18
+ | An LLM provider key | — | e.g. `DEEPSEEK_API_KEY` / `OPENAI_API_KEY` (configured in the profile, see DSH docs) |
19
+ | An image node key | — | For real renders; the fake mode lets you try the flow first (section 4) |
20
+
21
+ ```sh
22
+ node -v && pnpm -v && dsh --version
23
+ ```
24
+
25
+ ## 1. Installation (pick one of three)
26
+
27
+ ### A. From npm (recommended once published)
28
+
29
+ ```sh
30
+ # 1) create a deckline profile (based on the web template shipped with DSH)
31
+ dsh --profile deckline --from-default-profile web
32
+
33
+ # 2) install the plugin; dsh plugin add adds the bundle to the profile and enables it
34
+ dsh plugin --profile deckline add dsh-plugin-deck-studio
35
+ ```
36
+
37
+ ### B. From the Git repository (public repo, no npm account needed)
38
+
39
+ ```sh
40
+ dsh --profile deckline --from-default-profile web
41
+ dsh plugin --profile deckline add "github:<your-account>/dsh-deck-studio#path:/plugin/deck-studio"
42
+ ```
43
+
44
+ > pnpm's support for git subdirectories varies by version; if `#path:` fails, use C (clone + local install).
45
+
46
+ ### C. Local clone (recommended for development / debugging)
47
+
48
+ ```sh
49
+ git clone https://github.com/<your-account>/dsh-deck-studio.git
50
+ cd dsh-deck-studio
51
+ pnpm install --ignore-scripts # optional: skip if you only run the plugin
52
+
53
+ dsh --profile deckline --from-default-profile web
54
+ dsh plugin --profile deckline add "$PWD/plugin/deck-studio"
55
+ ```
56
+
57
+ Verify the installation:
58
+
59
+ ```sh
60
+ dsh --profile deckline --dump-config | grep -n "deck-studio" | head
61
+ ```
62
+
63
+ Seeing both `deck-studio` and `preset-deck-studio` means the install succeeded.
64
+
65
+ ## 2. First configuration: decks / workspace / port
66
+
67
+ All Deckline configuration lives in the **profile patch**: `~/.dsh/profiles/deckline/cordis.patch.yml`.
68
+ The repository ships a copy-paste example:
69
+ [`plugin/deck-studio/cordis.example.yml`](../plugin/deck-studio/cordis.example.yml).
70
+
71
+ The minimum (append to the profile's `cordis.patch.yml`):
72
+
73
+ ```yaml
74
+ # your deck source directory (read-only; any existing deck directory works)
75
+ - id: deck-studio
76
+ name: 'dsh-plugin-deck-studio'
77
+ config:
78
+ displayName: 'Deckline'
79
+ userName: 'Yuna'
80
+ # where new decks are created; empty = the plugin's internal .deck/projects/<id>/source
81
+ projectsRoot: '/absolute/path/to/your/sharing'
82
+ decks:
83
+ - id: my-deck
84
+ label: 'My deck'
85
+ sourceRoot: '/absolute/path/to/my-deck'
86
+ ```
87
+
88
+ > `decks[].sourceRoot` is read-only: Deckline never writes to the source directory; all edits and
89
+ > revisions live in `.deck/`. You can also start with **+ New Deck** if you have no deck yet.
90
+
91
+ ### Per-deck project rules (optional)
92
+
93
+ Drop a `deck.rules.md` at the root of a deck project to describe the creative constraints for that deck
94
+ (audience, taboos, brand, facts that must be respected). The Deck Agent reads and follows it on every
95
+ `deck_source_overview`:
96
+
97
+ ```md
98
+ # Project rules
99
+ - Audience: internal business and IT, no technical background assumed
100
+ - Taboos: no unverified efficiency numbers; never name real customers
101
+ - Visual: cream paper + colored pencil, no 3D
102
+ ```
103
+
104
+ - It only constrains **that one deck** and does not affect other decks; without the file there are no rules.
105
+ - It **cannot override** the product's hard rules (read-only source decks / QA gates / no fabrication /
106
+ user confirmation). In a conflict the hard rules win and the agent says so.
107
+ - Max 8 KB; it is never written back and never triggers any automatic action.
108
+ - Do not name it `AGENTS.md`: that belongs to DSH workspace instructions and Deckline does not depend on it
109
+ (see `docs/adr/0020` in the development repo).
110
+
111
+ ## 2.5 Where the data lives: source deck / documents / images / exports
112
+
113
+ Deckline keeps data in two places: **your deck source** (`projectsRoot`, plain markdown + source images)
114
+ and **runtime data** (`dataRoot`: working copies / renders / events). If you cannot find files after
115
+ creating a deck, check this table first.
116
+
117
+ | Content | Location | Notes |
118
+ |---|---|---|
119
+ | New deck source documents | `<projectsRoot>/<dir>/` | `intent.md` / `script.md` / `style-reference.md`; confirmed `docs/*.md` are written back here; `prompts/`, `pages/`, `outputs/` sit alongside |
120
+ | Working copies + governance docs | `<dataRoot>/decks/<deckId>/docs/` | changelog / feedback / research / materials / review / fact-check…; stay here until confirmed |
121
+ | Script revisions | `<dataRoot>/decks/<deckId>/script/revisions/vNNN.md` | copy-on-write; `current.md` is always latest |
122
+ | Rendered page images | `<dataRoot>/decks/<deckId>/slides/<pageId>/versions/<vNNN>/image.png` | one directory per revision, with `prompt.txt` / `content.json` / `qa.json`; old revisions are never overwritten |
123
+ | Style samples | `<dataRoot>/projects/<canvasDeckId>/source/designs/<ABBR>/sample-vNNN.png` (or your own `designs/<ABBR>/`) | samples imported / pasted in the UI |
124
+ | Exports | your browser's download folder | zips from "Export" (PDF / PPTX / handoff package) |
125
+
126
+ - **`dataRoot` defaults to `$DSH_HOME/deckline`** (usually `~/.dsh/deckline`) — never inside the plugin
127
+ package, so plugin upgrades do not touch it. Override with `dataRoot: '/your/path'` in the profile patch,
128
+ or the `DSH_DECK_DATA_ROOT` env var.
129
+ - **`projectsRoot`** decides where new decks are created; if unset they go to `<dataRoot>/projects/<deckId>/source`.
130
+ - **Managed source decks are read-only**: Deckline never writes to a deck registered via `decks[].sourceRoot`.
131
+ - **Backup**: archive `dataRoot` and `projectsRoot` together (documents + images + events):
132
+ ```sh
133
+ tar czf deckline-backup-$(date +%Y%m%d).tgz "$DSH_HOME/deckline" "<your projectsRoot>"
134
+ ```
135
+ - The workbench **Settings** panel shows the current data directory; in the development repo the data root
136
+ is the repo's `.deck/` (configured explicitly in the profile).
137
+
138
+ ## 3. Start
139
+
140
+ ```sh
141
+ dsh --profile deckline --port 13090
142
+ ```
143
+
144
+ Open the `http://127.0.0.1:13090/?token=…` URL printed in the terminal.
145
+ `--port` is optional; the default is 13090 to avoid colliding with DSH's web profile on 3080.
146
+
147
+ ## 4. Configure the image key (required for real renders)
148
+
149
+ Deckline supports:
150
+
151
+ - **fake mode** (default, offline): renders placeholder SVGs, enough to try the whole flow;
152
+ - **real mode**: calls an OpenAI-compatible `/v1/images/generations` node for real images.
153
+
154
+ > The plugin **ships no image node address** (provider-neutral): real mode requires your own endpoint
155
+ > and key. Otherwise the Settings panel says "no endpoint / key configured" and rendering fails loudly
156
+ > instead of silently hitting a default node.
157
+
158
+ ### 4.1 Environment variables (simplest)
159
+
160
+ ```sh
161
+ # image node (any OpenAI-compatible relay works)
162
+ export DSH_DECK_IMAGE_ENDPOINT="https://your-image-relay.example.com/v1/images/generations"
163
+ export DSH_DECK_IMAGE_MODEL="your-image-model"
164
+ export DSH_DECK_IMAGE_API_KEY="sk-…" # shell / secret manager only
165
+ ```
166
+
167
+ ### 4.2 Profile patch (recommended: multiple nodes + team-shared config)
168
+
169
+ Override the `deck-studio` render config in `~/.dsh/profiles/deckline/cordis.patch.yml`:
170
+
171
+ ```yaml
172
+ - id: deck-studio
173
+ name: 'dsh-plugin-deck-studio'
174
+ config:
175
+ # …keep the displayName / decks from above
176
+ render:
177
+ mode: real
178
+ size: '2560x1440'
179
+ default: 'main/gpt-image-2.5-sunburst'
180
+ nodes:
181
+ - id: main
182
+ name: 'Main node'
183
+ endpoint: 'https://your-image-relay.example.com/v1/images/generations'
184
+ # choose one: the environment variable name, or a local key file (KEY=VALUE, chmod 600, never in git)
185
+ apiKeyEnv: 'DSH_DECK_IMAGE_API_KEY'
186
+ apiKeyFile: '~/.config/image-relay.env'
187
+ models:
188
+ - 'gpt-image-2.5-sunburst'
189
+ - 'gpt-image-2'
190
+ ```
191
+
192
+ Key points:
193
+
194
+ - **Keys never go into the repo or into plain-text profile config**: the config only holds `apiKeyEnv`
195
+ (environment variable name) or `apiKeyFile` (local file path).
196
+ - The workbench **Settings** panel shows whether each node's key is configured (boolean + source only,
197
+ never the key itself).
198
+ - When no key is configured or the mode is still fake, the Settings panel shows a hint.
199
+ - Model names must match what your relay actually serves; for OpenAI-compatible `gpt-image-2`-series ids,
200
+ consult the node's `/v1/models`.
201
+
202
+ ## 5. Adding your own designs (two ways)
203
+
204
+ ### Way 1: in the UI (recommended, supports pasting images)
205
+
206
+ 1. Home → **Designs** → **+ Add style**;
207
+ 2. Fill in name / abbreviation / visual description (used as the prompt);
208
+ 3. In the "sample images" area **paste with ⌘V, drag and drop, or pick files** (png/jpg/webp, multiple,
209
+ ≤12 MB each);
210
+ 4. Creating it also creates the style, a 0-page canvas and a design conversation; the samples appear
211
+ immediately on the Designs card and in the preview.
212
+
213
+ To add samples to an existing style: click the **eye** icon on the style card → "+ Add sample" at the
214
+ bottom of the preview (paste / pick files work the same way).
215
+
216
+ ### Way 2: drop files on disk
217
+
218
+ Samples live under `designs/<ABBR>/` (ABBR is your style abbreviation):
219
+
220
+ - canvas directory (recommended): `.deck/projects/<canvasDeckId>/source/designs/<ABBR>/`;
221
+ - or `designs/<ABBR>/` inside any managed deck source (Deckline scans and merges them).
222
+
223
+ Refresh the page afterwards. png / jpg / webp are supported; names are free-form
224
+ (`sample-01.jpg` and similar keep them ordered).
225
+
226
+ ### Use preset styles (no prompt writing needed)
227
+
228
+ **+ Import preset styles** on the Designs page imports all 8 bundled styles (business consulting /
229
+ premium dark / Japanese minimal / magazine editorial / tech blueprint / hand-drawn whiteboard /
230
+ Swiss minimal / aurora gradient), each with samples. See [styles.md](styles.md).
231
+
232
+ ## 6. Troubleshooting
233
+
234
+ | Symptom | What to do |
235
+ |---|---|
236
+ | Port already in use | `dsh --profile deckline --port 13100`; or kill the old process with `lsof -tiTCP:13090 -sTCP:LISTEN` |
237
+ | Page 404 / blank | Make sure the plugin bundle is enabled: `dsh --profile deckline --dump-config \| grep deck-studio` |
238
+ | No "render" button / render fails | Check the key state in Settings; confirm `render.mode: real`; `curl` the node endpoint |
239
+ | New decks land in the wrong place | Set `projectsRoot`; otherwise they go to the plugin data directory `.deck/projects/` |
240
+ | Where are data / samples | See section 2.5: source decks in `projectsRoot`, working copies / renders in `dataRoot` (default `~/.dsh/deckline`) |
241
+ | Upgrading the plugin | `dsh plugin --profile deckline install <spec>`, or `add` the new version again |
242
+
243
+ ## 7. Developers: local verification
244
+
245
+ ```sh
246
+ node plugin/deck-studio/verify/smoke.mjs # 46 contract tests (no network or key needed)
247
+ node scripts/harness-check.mjs # instruction-chain / link / redaction / ledger gate
248
+ dsh --profile deck-studio --no-open # development profile (port configured locally)
249
+ ```
250
+
251
+ The plugin has no third-party runtime dependencies (Node built-ins only). Changes to
252
+ `plugin/deck-studio/index.js` require a profile restart; changes to `ui/` html/css hot-reload.