dsh-claude-motion 0.0.1 → 2.8.0

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 (33) hide show
  1. package/LICENSE +26 -0
  2. package/NOTICE.md +59 -0
  3. package/README.md +37 -3
  4. package/cordis.patch.yml +7 -0
  5. package/docs/DETAIL.md +32 -0
  6. package/docs/DETAIL.zh.md +17 -0
  7. package/icon.svg +8 -0
  8. package/lib/client.js +826 -0
  9. package/lib/index.js +594 -0
  10. package/locale/en.json +7 -0
  11. package/locale/zh.json +7 -0
  12. package/package.json +60 -6
  13. package/skills/claude-motion/SKILL.md +685 -0
  14. package/skills/claude-motion/artifact-type/reference/by-hand.md +84 -0
  15. package/skills/claude-motion/artifact-type/reference/film-api.md +278 -0
  16. package/skills/claude-motion/artifact-type/reference/finalize.md +213 -0
  17. package/skills/claude-motion/artifact-type/reference/motion.md +260 -0
  18. package/skills/claude-motion/artifact-type/reference/plan.md +239 -0
  19. package/skills/claude-motion/artifact-type/reference/questions.md +240 -0
  20. package/skills/claude-motion/artifact-type/reference/recreate-ui.md +140 -0
  21. package/skills/claude-motion/artifact-type/reference/render-offline.md +126 -0
  22. package/skills/claude-motion/artifact-type/reference/rough-cut.md +251 -0
  23. package/skills/claude-motion/artifact-type/reference/sound.md +106 -0
  24. package/skills/claude-motion/artifact-type/reference/styles.md +230 -0
  25. package/skills/claude-motion/artifact-type/reference/walkthrough.md +83 -0
  26. package/skills/claude-motion/scripts/artifact.mjs +8368 -0
  27. package/skills/claude-motion/scripts/editor/artifact-type/anthropicons-fizzy-lake-DtzHkSJH.woff2 +0 -0
  28. package/skills/claude-motion/scripts/editor/artifact-type/app.css +1 -0
  29. package/skills/claude-motion/scripts/editor/artifact-type/app.js +17230 -0
  30. package/skills/claude-motion/scripts/editor/index.html +145 -0
  31. package/skills/claude-motion/scripts/editor/local-host.js +12 -0
  32. package/skills/claude-motion/scripts/editor/share-ui.js +208 -0
  33. package/skills/claude-motion/scripts/editor/third-party-licenses.txt +970 -0
package/lib/client.js ADDED
@@ -0,0 +1,826 @@
1
+ // dsh-claude-motion 2.8.0: built from baoyu-design.
2
+ window.__ModuleLoader__.load({
3
+ id: "dsh-claude-motion",
4
+ factory: (require) => {
5
+ var module = { exports: {} };
6
+ var exports = module.exports;
7
+ "use strict";
8
+ var __defProp = Object.defineProperty;
9
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
+ var __getOwnPropNames = Object.getOwnPropertyNames;
11
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
12
+ var __export = (target, all) => {
13
+ for (var name in all)
14
+ __defProp(target, name, { get: all[name], enumerable: true });
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from))
19
+ if (!__hasOwnProp.call(to, key) && key !== except)
20
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
+ }
22
+ return to;
23
+ };
24
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
+
26
+ var client_exports = {};
27
+ __export(client_exports, {
28
+ apply: () => apply,
29
+ inject: () => inject
30
+ });
31
+ module.exports = __toCommonJS(client_exports);
32
+
33
+ var define_CLIENT_default = { plugin: "dsh-claude-motion", skill: "claude-motion", key: "dsh-claude-motion", simple: false };
34
+
35
+ var import_react2 = require("react");
36
+
37
+ var import_react = require("react");
38
+
39
+ var listPath = (skill) => `/api/baoyu-design.${skill}.artifacts`;
40
+ var openPath = (skill) => `/api/baoyu-design.${skill}.artifacts.open`;
41
+
42
+ var import_jsx_runtime = require("react/jsx-runtime");
43
+ var PAGE_VERSION = 1;
44
+ var PANEL_ID = "baoyu-design.artifacts";
45
+ var NS = "baoyu-design-artifacts";
46
+ var HUB = Symbol.for("baoyu-design/dsh-artifacts-page");
47
+ function hub() {
48
+ const g = globalThis;
49
+ return g[HUB] ??= { members: /* @__PURE__ */ new Map(), owner: null, listeners: /* @__PURE__ */ new Set() };
50
+ }
51
+ function newest(h) {
52
+ let best;
53
+ for (const m of h.members.values()) if (best === void 0 || m.version > best.version) best = m;
54
+ return best;
55
+ }
56
+ function settle(h) {
57
+ const next = newest(h);
58
+ if (h.owner !== null && h.members.has(h.owner.plugin) && (next === void 0 || next.version <= h.owner.version)) return;
59
+ if (h.owner !== null) {
60
+ const old = h.owner;
61
+ h.owner = null;
62
+ old.dispose();
63
+ }
64
+ if (next === void 0) return;
65
+ try {
66
+ h.owner = { plugin: next.plugin, version: next.version, dispose: next.mount() };
67
+ } catch (error) {
68
+ console.error(`${next.plugin}: the Artifacts page did not register:`, error);
69
+ }
70
+ }
71
+ function changed(h) {
72
+ for (const listener of [...h.listeners]) {
73
+ try {
74
+ listener();
75
+ } catch (error) {
76
+ console.error("baoyu-design Artifacts page listener failed:", error);
77
+ }
78
+ }
79
+ }
80
+ function createStore(initial) {
81
+ let state = initial;
82
+ const listeners = /* @__PURE__ */ new Set();
83
+ return {
84
+ getSnapshot: () => state,
85
+ subscribe(listener) {
86
+ listeners.add(listener);
87
+ return () => listeners.delete(listener);
88
+ },
89
+ set(patch) {
90
+ state = { ...state, ...patch };
91
+ for (const listener of [...listeners]) listener();
92
+ }
93
+ };
94
+ }
95
+ var EMPTY_SESSIONS = { getSnapshot: () => ({}), subscribe: () => () => {
96
+ } };
97
+ function isStore(value) {
98
+ const v = value;
99
+ return typeof v?.getSnapshot === "function" && typeof v.subscribe === "function";
100
+ }
101
+ function linkState(id, sessions, workspaces) {
102
+ if (sessions === void 0) return "unavailable";
103
+ if (workspaces?.state === "error") return "unavailable";
104
+ if (sessions.phase === "pending" || workspaces?.phase === "pending") return "loading";
105
+ if (workspaces?.archivedSessionIds?.includes(id)) return "archived";
106
+ if (!sessions.ids?.includes(id)) return "unavailable";
107
+ return "available";
108
+ }
109
+ var zh = {
110
+ panel: "作品",
111
+ title: "作品",
112
+ "time.locale": "zh-CN",
113
+ search: "搜索作品",
114
+ "search.clear": "清除搜索",
115
+ "filter.all": "全部",
116
+ "type.claude-slides": "幻灯片",
117
+ "type.claude-design": "设计",
118
+ "type.claude-design-system": "设计系统",
119
+ "type.claude-dashboard": "仪表盘",
120
+ "type.claude-docs": "文档",
121
+ "type.claude-motion": "动画",
122
+ "card.opened": "{time}打开",
123
+ "card.justNow": "刚刚打开",
124
+ "card.opening": "正在打开…",
125
+ "card.in": "在“{title}”中",
126
+ "empty.title": "还没有作品",
127
+ "empty.body": "Agent 用 baoyu-design 的技能打开幻灯片、设计稿、设计系统、仪表盘、文档或动画以后,会出现在这里。",
128
+ "empty.noMatches": "没有符合条件的作品",
129
+ "load.error": "读取作品列表失败:{message}",
130
+ "load.retry": "重试",
131
+ "open.pluginOff": "{plugin} 插件没有开启,打不开这个作品。",
132
+ "open.failed": "打不开:{message}",
133
+ "open.noSession": "原来的对话已不在,编辑器在新窗口里打开了。"
134
+ };
135
+ var en = {
136
+ panel: "Artifacts",
137
+ title: "Artifacts",
138
+ "time.locale": "en",
139
+ search: "Search artifacts",
140
+ "search.clear": "Clear search",
141
+ "filter.all": "All",
142
+ "type.claude-slides": "Slides",
143
+ "type.claude-design": "Design",
144
+ "type.claude-design-system": "Design systems",
145
+ "type.claude-dashboard": "Dashboards",
146
+ "type.claude-docs": "Docs",
147
+ "type.claude-motion": "Motion",
148
+ "card.opened": "Opened {time}",
149
+ "card.justNow": "Opened just now",
150
+ "card.opening": "Opening…",
151
+ "card.in": "In “{title}”",
152
+ "empty.title": "No artifacts yet",
153
+ "empty.body": "Slide decks, canvases, design systems, dashboards, docs and films the agent opens with a baoyu-design skill show up here.",
154
+ "empty.noMatches": "No artifacts match",
155
+ "load.error": "Could not read the artifacts: {message}",
156
+ "load.retry": "Try again",
157
+ "open.pluginOff": "The {plugin} plugin is off, so this artifact cannot open.",
158
+ "open.failed": "Could not open it: {message}",
159
+ "open.noSession": "The conversation is gone, so the editor opened in a new window."
160
+ };
161
+ var SKILLS = ["claude-slides", "claude-design", "claude-design-system", "claude-dashboard", "claude-docs", "claude-motion"];
162
+ var isSkill = (s) => SKILLS.includes(s);
163
+ var CSS = `
164
+ .bda-page{width:100%;min-width:0;height:100%;min-height:0;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-base);font-size:14px;line-height:1.6;display:flex;flex-direction:column;overflow:hidden}
165
+ .bda-scroll{flex:1;min-height:0;overflow:auto;scrollbar-gutter:stable}
166
+ .bda-content{max-width:1080px;margin:0 auto;padding:0 clamp(24px,4vw,48px) 48px}
167
+ .bda-heading{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:16px;padding-top:28px;margin-bottom:20px}
168
+ [data-platform=darwin] .bda-heading{padding-top:calc(28px + var(--dsh-frame-top-clearance,0px))}
169
+ .bda-heading h1{margin:0;font-size:20px;font-weight:500;line-height:28px}
170
+ .bda-search{display:flex;align-items:center;gap:6px;width:min(260px,100%);height:34px;padding:0 10px;border:.5px solid var(--dsw-alias-border-l3);border-radius:12px;color:var(--dsw-alias-label-tertiary);transition:border-color .15s}
171
+ .bda-search:hover{border-color:var(--dsw-alias-border-l2)}
172
+ .bda-search:focus-within{border-color:var(--dsw-alias-state-business-primary)}
173
+ .bda-search input{flex:1;min-width:0;height:100%;border:0;padding:0;background:none;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;outline:none}
174
+ .bda-search input::placeholder{color:var(--dsw-alias-label-caption)}
175
+ .bda-search input::-webkit-search-cancel-button{display:none}
176
+ .bda-search button{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;margin-right:-4px;padding:0;border:0;border-radius:6px;background:none;color:inherit;cursor:pointer}
177
+ .bda-search button:hover{background:var(--dsw-alias-interactive-bg-hover)}
178
+ .bda-filters{display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;margin-bottom:20px}
179
+ .bda-tab{display:inline-flex;align-items:center;height:28px;padding:0 10px;border:0;border-radius:14px;background:none;color:var(--dsw-alias-label-tertiary);font:inherit;font-size:14px;line-height:22px;white-space:nowrap;cursor:pointer}
180
+ .bda-tab:hover{background:var(--dsw-alias-interactive-bg-hover)}
181
+ .bda-tab[aria-pressed=true]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
182
+ .bda-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:28px 20px;margin:0;padding:0;list-style:none}
183
+ .bda-card{display:flex;flex-direction:column;gap:10px;width:100%;padding:0;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}
184
+ .bda-card:disabled{cursor:progress}
185
+ .bda-card:focus-visible{outline:none}
186
+ .bda-card:focus-visible .bda-preview{outline:var(--dsw-focus-ring-width,2px) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:2px}
187
+ .bda-preview{position:relative;aspect-ratio:16/10;border-radius:12px;overflow:hidden;background:color-mix(in srgb,var(--bda-tint) 14%,var(--dsw-alias-bg-base));transition:background-color .15s}
188
+ .bda-card:hover .bda-preview{background:color-mix(in srgb,var(--bda-tint) 22%,var(--dsw-alias-bg-base))}
189
+ .bda-paper{position:absolute;left:14%;right:14%;top:14%;bottom:-6%;border-radius:6px 6px 0 0;background:var(--dsw-alias-bg-base);box-shadow:0 0 0 .5px var(--dsw-alias-border-l2),0 6px 18px -8px rgba(0,0,0,.25);padding:9% 9% 0;display:flex;flex-direction:column;gap:6px;overflow:hidden;transition:transform .2s}
190
+ .bda-card:hover .bda-paper{transform:translateY(-3px)}
191
+ .bda-paper-title{font-size:11px;line-height:1.35;font-weight:600;color:var(--dsw-alias-label-primary);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}
192
+ .bda-line{height:5px;border-radius:3px;background:var(--dsw-alias-border-l2)}
193
+ .bda-slide{position:absolute;left:12%;right:12%;top:16%;aspect-ratio:16/9;border-radius:5px;background:var(--dsw-alias-bg-base);box-shadow:0 0 0 .5px var(--dsw-alias-border-l2),0 6px 18px -8px rgba(0,0,0,.25);display:flex;flex-direction:column;justify-content:center;gap:6px;padding:0 9%;transition:transform .2s}
194
+ .bda-card:hover .bda-slide{transform:translateY(-3px)}
195
+ .bda-slide .bda-paper-title{font-size:12px}
196
+ .bda-slide .bda-line{width:40%;background:var(--bda-tint);opacity:.55}
197
+ .bda-boards{display:flex;gap:6px;flex:1;margin-top:2px}
198
+ .bda-board{flex:1;border-radius:3px;background:color-mix(in srgb,var(--bda-tint) 18%,var(--dsw-alias-bg-base));box-shadow:0 0 0 .5px var(--dsw-alias-border-l2)}
199
+ .bda-board:nth-child(2){flex:.7;margin-top:10%}
200
+ .bda-swatches{display:flex;gap:4px}
201
+ .bda-swatch{width:16px;height:16px;border-radius:50%;background:var(--bda-tint)}
202
+ .bda-swatch:nth-child(2){opacity:.7}.bda-swatch:nth-child(3){opacity:.45}.bda-swatch:nth-child(4){opacity:.25}
203
+ .bda-specimen{font-size:20px;line-height:1;font-weight:600;color:var(--dsw-alias-label-secondary)}
204
+ .bda-kpis{display:flex;gap:5px}
205
+ .bda-kpi{flex:1;height:16px;border-radius:3px;box-shadow:0 0 0 .5px var(--dsw-alias-border-l2)}
206
+ .bda-bars{display:flex;align-items:flex-end;gap:5px;height:34%;margin-top:2px}
207
+ .bda-bar{flex:1;border-radius:2px 2px 0 0;background:var(--bda-tint);opacity:.7}
208
+ .bda-film{position:absolute;left:12%;right:12%;top:16%;aspect-ratio:16/9;border-radius:5px;background:#1d1d1f;box-shadow:0 6px 18px -8px rgba(0,0,0,.35);display:flex;align-items:center;justify-content:center;transition:transform .2s;color:#fff}
209
+ .bda-card:hover .bda-film{transform:translateY(-3px)}
210
+ .bda-film-bar{position:absolute;left:8%;right:8%;bottom:10%;height:3px;border-radius:2px;background:rgba(255,255,255,.25)}
211
+ .bda-film-bar::after{content:"";position:absolute;left:0;top:0;bottom:0;width:38%;border-radius:2px;background:var(--bda-tint)}
212
+ .bda-film-title{position:absolute;left:8%;right:8%;top:10%;font-size:10px;font-weight:600;color:rgba(255,255,255,.85);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
213
+ .bda-busy{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;gap:8px;background:color-mix(in srgb,var(--dsw-alias-bg-base) 70%,transparent);color:var(--dsw-alias-label-secondary);font-size:13px}
214
+ .bda-spinner{width:14px;height:14px;border-radius:50%;border:1.5px solid currentColor;border-right-color:transparent;animation:bda-spin .8s linear infinite}
215
+ @keyframes bda-spin{to{transform:rotate(360deg)}}
216
+ .bda-info{display:flex;align-items:flex-start;gap:10px;min-width:0}
217
+ .bda-glyph{flex:none;display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:8px;background:color-mix(in srgb,var(--bda-tint) 16%,var(--dsw-alias-bg-base));color:color-mix(in srgb,var(--bda-tint) 80%,var(--dsw-alias-label-primary))}
218
+ .bda-text{display:flex;flex-direction:column;min-width:0;flex:1}
219
+ .bda-name{font-weight:500;line-height:20px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
220
+ .bda-meta{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
221
+ .bda-note{margin-top:2px;font-size:12px;line-height:18px;color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere}
222
+ .bda-note[data-kind=error]{color:var(--dsw-alias-state-error-primary)}
223
+ .bda-empty{display:flex;flex-direction:column;align-items:center;gap:8px;padding:72px 20px;text-align:center;color:var(--dsw-alias-label-tertiary)}
224
+ .bda-empty svg{color:var(--dsw-alias-label-caption);margin-bottom:4px}
225
+ .bda-empty h2{margin:0;font-size:14px;font-weight:500;color:var(--dsw-alias-label-secondary)}
226
+ .bda-empty p{margin:0;max-width:420px;font-size:13px;line-height:1.6}
227
+ .bda-retry{margin-top:8px;height:30px;padding:0 12px;border:.5px solid var(--dsw-alias-border-l2);border-radius:15px;background:none;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;cursor:pointer}
228
+ .bda-retry:hover{background:var(--dsw-alias-interactive-bg-hover)}
229
+ .bda-skeleton .bda-preview{background:var(--dsw-alias-bg-skeleton,var(--dsw-alias-interactive-bg-hover))}
230
+ .bda-skeleton .bda-line{width:60%;height:10px;margin-top:4px}
231
+ @media (prefers-reduced-motion:reduce){.bda-paper,.bda-slide,.bda-film{transition:none}.bda-spinner{animation-duration:2s}}
232
+ `;
233
+ var TINTS = {
234
+ "claude-slides": "#e8865a",
235
+ "claude-design": "#8b7cf0",
236
+ "claude-design-system": "#2fa98c",
237
+ "claude-dashboard": "#3f8ef0",
238
+ "claude-docs": "#4a90e2",
239
+ "claude-motion": "#e2557a"
240
+ };
241
+ var svg = (size) => ({ display: "block", width: size, height: size, flex: "none" });
242
+ function ArtifactsIcon({ size = 16 }) {
243
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", style: svg(size), children: [
244
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "3", y: "6", width: "8.5", height: "11", rx: "2", stroke: "currentColor", strokeWidth: "1.5" }),
245
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8.5 6V5a2 2 0 0 1 2-2h4.5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-3.5", stroke: "currentColor", strokeWidth: "1.5" })
246
+ ] });
247
+ }
248
+ function TypeIcon({ skill, size = 16 }) {
249
+ const p = { stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round" };
250
+ const body = (() => {
251
+ switch (skill) {
252
+ case "claude-slides":
253
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
254
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "2.75", y: "4", width: "14.5", height: "9.5", rx: "1.5", ...p }),
255
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 13.5V16.5M7 16.5h6", ...p })
256
+ ] });
257
+ case "claude-design":
258
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
259
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "2.75", y: "2.75", width: "8", height: "10", rx: "1.25", ...p }),
260
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "12.75", y: "6", width: "4.5", height: "11.25", rx: "1.25", ...p }),
261
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2.75 16.25h8", ...p })
262
+ ] });
263
+ case "claude-design-system":
264
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
265
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "6.5", cy: "6.5", r: "3.25", ...p }),
266
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "13.5", cy: "6.5", r: "3.25", ...p }),
267
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "10", cy: "13", r: "3.25", ...p })
268
+ ] });
269
+ case "claude-dashboard":
270
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
271
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "2.75", y: "2.75", width: "14.5", height: "14.5", rx: "2", ...p }),
272
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6.5 13.5V10M10 13.5V6.5M13.5 13.5V9", ...p })
273
+ ] });
274
+ case "claude-docs":
275
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
276
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5 2.75h6.5l3.5 3.5v10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-12.5a1 1 0 0 1 1-1Z", ...p }),
277
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M7 10h6M7 13h4.5", ...p })
278
+ ] });
279
+ case "claude-motion":
280
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
281
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "2.75", y: "4", width: "14.5", height: "12", rx: "2", ...p }),
282
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m8.5 7.75 4 2.25-4 2.25v-4.5Z", ...p })
283
+ ] });
284
+ default:
285
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "3", y: "3", width: "14", height: "14", rx: "2", ...p });
286
+ }
287
+ })();
288
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", style: svg(size), children: body });
289
+ }
290
+ function SearchIcon() {
291
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", style: svg(14), children: [
292
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "7", cy: "7", r: "4.5", stroke: "currentColor", strokeWidth: "1.3" }),
293
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m10.5 10.5 3 3", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round" })
294
+ ] });
295
+ }
296
+ function ClearIcon() {
297
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", style: svg(12), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m4.5 4.5 7 7m0-7-7 7", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round" }) });
298
+ }
299
+ function Preview({ skill, title }) {
300
+ const name = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-paper-title", children: title });
301
+ switch (skill) {
302
+ case "claude-slides":
303
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-slide", children: [
304
+ name,
305
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-line" })
306
+ ] });
307
+ case "claude-motion":
308
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-film", children: [
309
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-film-title", children: title }),
310
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 20 20", "aria-hidden": "true", style: svg(22), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M7 5.5v9l7.5-4.5L7 5.5Z", fill: "currentColor" }) }),
311
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-film-bar" })
312
+ ] });
313
+ case "claude-design":
314
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-paper", children: [
315
+ name,
316
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-boards", children: [
317
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-board" }),
318
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-board" })
319
+ ] })
320
+ ] });
321
+ case "claude-design-system":
322
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-paper", children: [
323
+ name,
324
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-swatches", children: [
325
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-swatch" }),
326
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-swatch" }),
327
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-swatch" }),
328
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-swatch" })
329
+ ] }),
330
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-specimen", children: "Aa" })
331
+ ] });
332
+ case "claude-dashboard":
333
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-paper", children: [
334
+ name,
335
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-kpis", children: [
336
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-kpi" }),
337
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-kpi" }),
338
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-kpi" })
339
+ ] }),
340
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-bars", children: [45, 70, 55, 90, 65, 80].map((h, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-bar", style: { height: `${h}%` } }, i)) })
341
+ ] });
342
+ default:
343
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-paper", children: [
344
+ name,
345
+ [92, 100, 84, 96, 70].map((w, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-line", style: { width: `${w}%` } }, i))
346
+ ] });
347
+ }
348
+ }
349
+ function ago(iso, now, t) {
350
+ const then = Date.parse(iso);
351
+ if (!Number.isFinite(then)) return "";
352
+ const seconds = Math.round((then - now) / 1e3);
353
+ if (seconds > -60) return t("card.justNow");
354
+ const steps = [["minute", 60], ["hour", 3600], ["day", 86400], ["week", 604800], ["month", 2629800], ["year", 31557600]];
355
+ let unit = "minute";
356
+ let size = 60;
357
+ for (const [u, s] of steps) if (-seconds >= s) [unit, size] = [u, s];
358
+ let format;
359
+ try {
360
+ format = new Intl.RelativeTimeFormat(t("time.locale"), { numeric: "auto" });
361
+ } catch {
362
+ format = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
363
+ }
364
+ return t("card.opened", { time: format.format(Math.round(seconds / size), unit) });
365
+ }
366
+ function useNow() {
367
+ const [now, setNow] = (0, import_react.useState)(() => Date.now());
368
+ (0, import_react.useEffect)(() => {
369
+ const timer = setInterval(() => setNow(Date.now()), 6e4);
370
+ return () => clearInterval(timer);
371
+ }, []);
372
+ return now;
373
+ }
374
+ function Card({ view, state, conversation, now, t, onOpen }) {
375
+ const opening = state.opening === view.root;
376
+ const failure = state.failure?.root === view.root ? state.failure.message : "";
377
+ const notice = state.notice?.root === view.root ? state.notice.message : "";
378
+ const tint = isSkill(view.skill) ? TINTS[view.skill] : "#8a8a8a";
379
+ const when = ago(view.openedAt, now, t);
380
+ const meta = conversation ? `${when} · ${t("card.in", { title: conversation })}` : when;
381
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
382
+ "button",
383
+ {
384
+ type: "button",
385
+ className: "bda-card",
386
+ style: { "--bda-tint": tint },
387
+ disabled: state.opening !== null,
388
+ "aria-busy": opening,
389
+ title: view.root,
390
+ onClick: () => onOpen(view),
391
+ "data-skill": view.skill,
392
+ children: [
393
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-preview", children: [
394
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Preview, { skill: view.skill, title: view.title }),
395
+ opening && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-busy", children: [
396
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-spinner" }),
397
+ t("card.opening")
398
+ ] })
399
+ ] }),
400
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-info", children: [
401
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-glyph", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TypeIcon, { skill: view.skill }) }),
402
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "bda-text", children: [
403
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-name", children: view.title }),
404
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-meta", children: meta }),
405
+ failure && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-note", "data-kind": "error", children: failure }),
406
+ notice && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "bda-note", children: notice })
407
+ ] })
408
+ ] })
409
+ ]
410
+ }
411
+ ) });
412
+ }
413
+ function ArtifactsPage({ t, artifactsStore, sessionsStore, reloadArtifacts, openArtifact }) {
414
+ const state = (0, import_react.useSyncExternalStore)(artifactsStore.subscribe, artifactsStore.getSnapshot);
415
+ const sessions = (0, import_react.useSyncExternalStore)(sessionsStore.subscribe, sessionsStore.getSnapshot);
416
+ const [query, setQuery] = (0, import_react.useState)("");
417
+ const [skill, setSkill] = (0, import_react.useState)("all");
418
+ const now = useNow();
419
+ (0, import_react.useEffect)(() => {
420
+ reloadArtifacts();
421
+ const again = () => {
422
+ if (document.visibilityState === "visible") reloadArtifacts();
423
+ };
424
+ document.addEventListener("visibilitychange", again);
425
+ return () => document.removeEventListener("visibilitychange", again);
426
+ }, [reloadArtifacts]);
427
+ const present = (0, import_react.useMemo)(() => SKILLS.filter((s) => state.artifacts.some((a) => a.skill === s)), [state.artifacts]);
428
+ const shown = (0, import_react.useMemo)(() => {
429
+ const q = query.trim().toLowerCase();
430
+ return state.artifacts.filter((a) => {
431
+ if (skill !== "all" && a.skill !== skill) return false;
432
+ if (!q) return true;
433
+ const conversation = sessions.byId?.[a.sessionId]?.title ?? "";
434
+ return a.title.toLowerCase().includes(q) || conversation.toLowerCase().includes(q) || a.root.toLowerCase().includes(q);
435
+ });
436
+ }, [state.artifacts, skill, query, sessions]);
437
+ (0, import_react.useEffect)(() => {
438
+ if (skill !== "all" && state.status === "ready" && !present.includes(skill)) setSkill("all");
439
+ }, [skill, present, state.status]);
440
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("section", { className: "bda-page", "aria-label": t("title"), "data-testid": "baoyu-design-artifacts", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-content", children: [
441
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-heading", children: [
442
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { children: t("title") }),
443
+ state.artifacts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "bda-search", children: [
444
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SearchIcon, {}),
445
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "search", value: query, placeholder: t("search"), "aria-label": t("search"), onChange: (e) => setQuery(e.target.value) }),
446
+ query && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", "aria-label": t("search.clear"), onClick: () => setQuery(""), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ClearIcon, {}) })
447
+ ] })
448
+ ] }),
449
+ present.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-filters", role: "toolbar", children: ["all", ...present].map((s) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "bda-tab", "aria-pressed": skill === s, onClick: () => setSkill(s), children: s === "all" ? t("filter.all") : t(`type.${s}`) }, s)) }),
450
+ state.status === "loading" && state.artifacts.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "bda-grid bda-skeleton", "aria-hidden": "true", children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-card", children: [
451
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-preview" }),
452
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-line" })
453
+ ] }) }, i)) }) : state.status === "error" && state.artifacts.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-empty", role: "alert", children: [
454
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: t("load.error", { message: state.error }) }),
455
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "bda-retry", onClick: reloadArtifacts, children: t("load.retry") })
456
+ ] }) : state.artifacts.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bda-empty", children: [
457
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ArtifactsIcon, { size: 28 }),
458
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: t("empty.title") }),
459
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: t("empty.body") })
460
+ ] }) : shown.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "bda-empty", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: t("empty.noMatches") }) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "bda-grid", children: shown.map((view) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
461
+ Card,
462
+ {
463
+ view,
464
+ state,
465
+ conversation: sessions.byId?.[view.sessionId]?.title?.trim() ?? "",
466
+ now,
467
+ t,
468
+ onOpen: openArtifact
469
+ },
470
+ view.root
471
+ )) })
472
+ ] }) }) });
473
+ }
474
+ var SIDEBAR_WAIT_MS = 5e3;
475
+ async function openInSidebar(sidebar, sessionId, url) {
476
+ if (typeof sidebar.tabsIn !== "function") {
477
+ sidebar.openTabIn(sessionId, "browser", { params: { url } });
478
+ return true;
479
+ }
480
+ const browsers = () => sidebar.tabsIn(sessionId).filter((tab) => tab.kind === "browser").length;
481
+ const deadline = Date.now() + SIDEBAR_WAIT_MS;
482
+ for (; ; ) {
483
+ const before = browsers();
484
+ sidebar.openTabIn(sessionId, "browser", { params: { url } });
485
+ if (browsers() > before) return true;
486
+ if (Date.now() >= deadline) return false;
487
+ await new Promise((resolve) => setTimeout(resolve, 100));
488
+ }
489
+ }
490
+ var route = (path) => path.slice(1);
491
+ function mountPage(ctx, h, self) {
492
+ const disposers = [];
493
+ const style = typeof document === "undefined" ? null : document.createElement("style");
494
+ if (style) {
495
+ style.dataset.pluginCss = "baoyu-design/artifacts-page.css";
496
+ style.textContent = CSS;
497
+ document.head.appendChild(style);
498
+ disposers.push(() => style.remove());
499
+ }
500
+ disposers.push(ctx.locale.register(NS, { zh, en }));
501
+ const t = ctx.locale.bind?.(NS) ?? ((key) => en[key] ?? key);
502
+ const skillsOn = () => [...new Set([...h.members.values()].map((m) => m.skill))];
503
+ const store = createStore({ status: "loading", artifacts: [], error: "", skills: skillsOn(), opening: null, failure: null, notice: null });
504
+ const onMembers = () => store.set({ skills: skillsOn() });
505
+ h.listeners.add(onMembers);
506
+ disposers.push(() => h.listeners.delete(onMembers));
507
+ let loading = null;
508
+ const reload = () => {
509
+ if (loading) return;
510
+ if (store.getSnapshot().artifacts.length === 0) store.set({ status: "loading" });
511
+ const order = [self, ...skillsOn().filter((s) => s !== self)];
512
+ loading = (async () => {
513
+ let message = "";
514
+ for (const skill of order) {
515
+ try {
516
+ const response = await fetch(route(listPath(skill)), { cache: "no-store" });
517
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
518
+ const body = await response.json();
519
+ const artifacts = Array.isArray(body.artifacts) ? body.artifacts.filter((a) => a && typeof a.root === "string") : [];
520
+ store.set({ status: "ready", artifacts, error: "" });
521
+ return;
522
+ } catch (error) {
523
+ message ||= error.message;
524
+ }
525
+ }
526
+ store.set({ status: "error", error: message });
527
+ })().finally(() => {
528
+ loading = null;
529
+ });
530
+ };
531
+ const open = (view) => {
532
+ if (store.getSnapshot().opening !== null) return;
533
+ if (!skillsOn().includes(view.skill)) {
534
+ store.set({ failure: { root: view.root, message: t("open.pluginOff", { plugin: view.plugin }) }, notice: null });
535
+ return;
536
+ }
537
+ store.set({ opening: view.root, failure: null, notice: null });
538
+ void (async () => {
539
+ try {
540
+ const response = await fetch(`${route(openPath(view.skill))}?${new URLSearchParams({ root: view.root })}`, { method: "POST" });
541
+ const body = await response.json().catch(() => ({}));
542
+ if (!response.ok || typeof body.url !== "string") throw new Error(typeof body.error === "string" ? body.error : `HTTP ${response.status}`);
543
+ const url = body.url;
544
+ const sessionId = typeof body.sessionId === "string" ? body.sessionId : view.sessionId;
545
+ const sessions = ctx.get("sessions");
546
+ const workspaces = ctx.get("workspaces");
547
+ const workspace = ctx.get("uiWorkspace");
548
+ const sidebar = ctx.get("sidebarRight");
549
+ const tabs = ctx.get("sidebarRightTabs");
550
+ const reachable = workspace !== void 0 && linkState(sessionId, sessions?.list?.getSnapshot(), workspaces?.list?.getSnapshot()) === "available";
551
+ if (reachable) {
552
+ workspace.openSession(sessionId);
553
+ const shown = sidebar !== void 0 && tabs?.get("browser") !== void 0 && await openInSidebar(sidebar, sessionId, url);
554
+ if (!shown) window.open(url, "_blank", "noopener,noreferrer");
555
+ store.set({ opening: null });
556
+ } else {
557
+ window.open(url, "_blank", "noopener,noreferrer");
558
+ store.set({ opening: null, notice: { root: view.root, message: t("open.noSession") } });
559
+ }
560
+ reload();
561
+ } catch (error) {
562
+ store.set({ opening: null, failure: { root: view.root, message: t("open.failed", { message: error.message }) } });
563
+ }
564
+ })();
565
+ };
566
+ const sessionsStore = () => {
567
+ const list = ctx.get("sessions")?.list;
568
+ return isStore(list) ? list : EMPTY_SESSIONS;
569
+ };
570
+ disposers.push(toDisposer(ctx.slots.inject(
571
+ "main",
572
+ () => ctx.slots.register(
573
+ {
574
+ name: "main",
575
+ key: PANEL_ID,
576
+ locale: NS,
577
+ inject: () => ({ artifactsStore: store, sessionsStore: sessionsStore(), reloadArtifacts: reload, openArtifact: open })
578
+ },
579
+ ArtifactsPage
580
+ )
581
+ )));
582
+ disposers.push(toDisposer(ctx.slots.inject(
583
+ "sidebar.panellist",
584
+ () => ctx.slots.register(
585
+ { name: "sidebar.panellist", id: PANEL_ID, order: 20, locale: NS, label: () => t("panel") },
586
+ ArtifactsIcon
587
+ )
588
+ )));
589
+ return () => {
590
+ for (const dispose of disposers.splice(0).reverse()) {
591
+ try {
592
+ dispose();
593
+ } catch (error) {
594
+ console.error("baoyu-design Artifacts page: unregistering failed:", error);
595
+ }
596
+ }
597
+ };
598
+ }
599
+ function toDisposer(value) {
600
+ return typeof value === "function" ? value : () => {
601
+ };
602
+ }
603
+ function joinArtifactsPage(ctx, plugin, skill) {
604
+ const h = hub();
605
+ h.members.set(plugin, { plugin, skill, version: PAGE_VERSION, mount: () => mountPage(ctx, h, skill) });
606
+ settle(h);
607
+ changed(h);
608
+ ctx.effect(() => () => {
609
+ h.members.delete(plugin);
610
+ if (h.owner?.plugin === plugin) {
611
+ const old = h.owner;
612
+ h.owner = null;
613
+ old.dispose();
614
+ }
615
+ settle(h);
616
+ changed(h);
617
+ }, `${plugin}: Artifacts page`);
618
+ }
619
+
620
+ var import_jsx_runtime2 = require("react/jsx-runtime");
621
+ var CLIENT = define_CLIENT_default;
622
+ var COMMENT_SOURCE = "baoyu-design-comment";
623
+ var KIND = `${CLIENT.key}:comment`;
624
+ var NS2 = CLIENT.key;
625
+ var zh2 = {
626
+ "card.title": "已将对“{title}”的评论发给 Agent",
627
+ "card.request": "已将“{title}”上的 {label} 发给 Agent",
628
+ "card.view": "查看评论",
629
+ "card.more": "显示位置",
630
+ "card.less": "收起位置"
631
+ };
632
+ var en2 = {
633
+ "card.title": "Comment on “{title}” sent to agent",
634
+ "card.request": "{label} on “{title}” sent to agent",
635
+ "card.view": "View thread",
636
+ "card.more": "Show where",
637
+ "card.less": "Hide where"
638
+ };
639
+ var str = (value) => typeof value === "string" ? value : "";
640
+ function ours(event) {
641
+ if (event.type !== "user/message" || event.surfaceOp !== "append") return false;
642
+ const source = event.data?.source;
643
+ return source?.kind === COMMENT_SOURCE && source.plugin === CLIENT.plugin;
644
+ }
645
+ function cardData(event) {
646
+ const source = event.data?.source ?? {};
647
+ const threads = Array.isArray(source.threads) ? source.threads : [];
648
+ const requests = Array.isArray(source.requests) ? source.requests : [];
649
+ return {
650
+ title: str(source.title),
651
+ url: str(source.url),
652
+ threads: threads.map((t) => ({ id: str(t.id), where: str(t.where), text: str(t.text) })).filter((t) => t.id),
653
+ requests: requests.map((r) => ({ id: str(r.id), label: str(r.label), text: str(r.text) })).filter((r) => r.id && r.text),
654
+ seq: event.seq
655
+ };
656
+ }
657
+ var definition = {
658
+ kind: KIND,
659
+ target: "chat",
660
+ match: (event) => (
661
+ // Claimed: the built-in input-message Definition would draw it as a context row.
662
+ ours(event) ? { id: String(event.data?.id), role: "start", exclusive: true } : null
663
+ ),
664
+ start: (_context, match) => cardData(match.event),
665
+ update: (context) => context.state,
666
+ buildViewNode: (context) => {
667
+ if (context.state === void 0) return null;
668
+ return {
669
+ key: context.key,
670
+ kind: KIND,
671
+ id: context.id,
672
+ target: "chat",
673
+ anchorSeq: context.state.seq,
674
+ location: context.start?.location ?? context.matches[0]?.location ?? { kind: "unresolved" },
675
+ visibility: "visible",
676
+ // A person's input, as a user message: it opens the agent's reply below it.
677
+ groupTree: "input",
678
+ data: context.state
679
+ };
680
+ }
681
+ };
682
+ var CSS2 = `
683
+ .bdc-row{display:flex;flex-direction:column;align-items:flex-end;gap:8px;width:100%}
684
+ .bdc-card{box-sizing:border-box;max-width:min(calc(var(--dsh-chat-content-width, 748px) * 0.702), 82%);min-width:min(320px, 82%);
685
+ border:0.5px solid var(--dsw-alias-border-l1);border-radius:var(--dsw-radius-xl, 12px);background:var(--dsw-alias-markdown-code-block);
686
+ color:var(--dsw-alias-label-primary);padding:10px 14px 12px;display:flex;flex-direction:column;gap:6px}
687
+ .bdc-head{display:flex;align-items:center;gap:6px;color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xxs-12, 12px/18px sans-serif)}
688
+ .bdc-head svg{flex:none}
689
+ .bdc-head-text{flex:1;min-width:0;display:flex;white-space:nowrap;overflow:hidden}
690
+ .bdc-head-text>span{flex:none}
691
+ .bdc-head-text>.bdc-head-title{flex:0 1 auto;min-width:1.5em;overflow:hidden;text-overflow:ellipsis}
692
+ .bdc-toggle{flex:none;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin:-2px -4px -2px 0;
693
+ border:0;border-radius:var(--dsw-radius-sm, 6px);background:none;color:inherit;cursor:pointer;padding:0}
694
+ .bdc-toggle:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}
695
+ .bdc-toggle svg{transition:transform .15s}
696
+ .bdc-toggle[aria-expanded=false] svg{transform:rotate(-90deg)}
697
+ .bdc-body{font-size:var(--dsh-content-font-size, 14px);line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere}
698
+ .bdc-meta{display:flex;flex-direction:column;gap:6px;padding-top:6px;border-top:0.5px solid var(--dsw-alias-border-l1)}
699
+ .bdc-where{color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xxs-12, 12px/18px sans-serif);overflow-wrap:anywhere}
700
+ .bdc-view{align-self:flex-start;display:inline-flex;align-items:center;gap:2px;height:24px;margin-left:-6px;padding:0 6px;border:0;
701
+ border-radius:var(--dsw-radius-sm, 6px);background:none;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-xxs-12, 12px/18px sans-serif);cursor:pointer}
702
+ .bdc-view:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}
703
+ .bdc-view:focus-visible,.bdc-toggle:focus-visible{outline:var(--dsw-focus-ring-width, 2px) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));outline-offset:1px}
704
+ @media (prefers-reduced-motion:reduce){.bdc-toggle svg{transition:none}}
705
+ `;
706
+ var iconStyle = { display: "block" };
707
+ var TITLE_MARK = "";
708
+ function CommentIcon() {
709
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", style: iconStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
710
+ "path",
711
+ {
712
+ d: "M3 3.5h10a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H8.2L5.4 13.8a.3.3 0 0 1-.5-.23V11.5H3a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1Z",
713
+ stroke: "currentColor",
714
+ strokeWidth: "1.2",
715
+ strokeLinejoin: "round"
716
+ }
717
+ ) });
718
+ }
719
+ function RequestIcon() {
720
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", style: iconStyle, children: [
721
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "2", y: "4", width: "12", height: "7", rx: "2", stroke: "currentColor", strokeWidth: "1.2" }),
722
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M8.5 8.5 11 14l.9-2.1L14 11l-5.5-2.5Z", fill: "currentColor", stroke: "var(--dsw-alias-markdown-code-block, #fff)", strokeWidth: "0.8", strokeLinejoin: "round" })
723
+ ] });
724
+ }
725
+ function ChevronDown() {
726
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", style: iconStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M3 4.5 6 7.5l3-3", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round" }) });
727
+ }
728
+ function ChevronRight() {
729
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", style: iconStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M4.5 3 7.5 6l-3 3", stroke: "currentColor", strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round" }) });
730
+ }
731
+ function Card2({ title, thread, url, t, openThread }) {
732
+ const [open, setOpen] = (0, import_react2.useState)(true);
733
+ const heading = t("card.title", { title });
734
+ const meta = !CLIENT.simple && (thread.where || url);
735
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "bdc-card", "data-comment-id": thread.id, children: [
736
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "bdc-head", children: [
737
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CommentIcon, {}),
738
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Heading, { text: heading, title, parts: t("card.title", { title: TITLE_MARK }).split(TITLE_MARK) }),
739
+ meta && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "bdc-toggle", "aria-expanded": open, "aria-label": t(open ? "card.less" : "card.more"), onClick: () => setOpen(!open), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChevronDown, {}) })
740
+ ] }),
741
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "bdc-body", children: thread.text }),
742
+ meta && open && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "bdc-meta", children: [
743
+ thread.where && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "bdc-where", children: thread.where }),
744
+ url && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "bdc-view", onClick: () => openThread(url, thread.id), children: [
745
+ t("card.view"),
746
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChevronRight, {})
747
+ ] })
748
+ ] })
749
+ ] });
750
+ }
751
+ function Heading({ text, title, parts }) {
752
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "bdc-head-text", title: text, children: parts.length === 2 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
753
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: parts[0] }),
754
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "bdc-head-title", children: title }),
755
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: parts[1] })
756
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "bdc-head-title", children: text }) });
757
+ }
758
+ function RequestCardView({ title, request, t }) {
759
+ const label = request.label || "Request";
760
+ const heading = t("card.request", { title, label });
761
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "bdc-card", "data-request-id": request.id, children: [
762
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "bdc-head", children: [
763
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RequestIcon, {}),
764
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Heading, { text: heading, title, parts: t("card.request", { title: TITLE_MARK, label }).split(TITLE_MARK) })
765
+ ] }),
766
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "bdc-body", children: request.text })
767
+ ] });
768
+ }
769
+ function CommentCards({ node, t, openThread }) {
770
+ const { title, url, threads, requests } = node.data;
771
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "bdc-row", children: [
772
+ threads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Card2, { title, thread, url, t, openThread }, thread.id)),
773
+ (requests ?? []).map((request) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RequestCardView, { title, request, t }, request.id))
774
+ ] });
775
+ }
776
+ var inject = ["slots", "locale", "uiConversation"];
777
+ function threadUrl(url, id) {
778
+ try {
779
+ const at = new URL(url);
780
+ at.searchParams.set("comment", id);
781
+ return at.href;
782
+ } catch {
783
+ return url;
784
+ }
785
+ }
786
+ function apply(ctx) {
787
+ ctx.effect(() => {
788
+ if (typeof document === "undefined") return () => {
789
+ };
790
+ const id = `${CLIENT.plugin}/comment-card.css`;
791
+ if (document.querySelector(`style[data-plugin-css=${JSON.stringify(id)}]`)) return () => {
792
+ };
793
+ const tag = document.createElement("style");
794
+ tag.dataset.plugin = CLIENT.plugin;
795
+ tag.dataset.pluginCss = id;
796
+ tag.textContent = CSS2;
797
+ document.head.appendChild(tag);
798
+ return () => tag.remove();
799
+ }, `${CLIENT.plugin}: comment card styles`);
800
+ ctx.effect(() => ctx.locale.register(NS2, { zh: zh2, en: en2 }), `${CLIENT.plugin}: dictionaries`);
801
+ ctx.uiConversation.events.register(definition);
802
+ ctx.slots.inject(
803
+ "conversation.chat.node",
804
+ () => ctx.slots.register(
805
+ {
806
+ name: "conversation.chat.node",
807
+ key: KIND,
808
+ locale: NS2,
809
+ inject: (sessionId) => ({
810
+ openThread: (url, threadId) => {
811
+ const target = threadUrl(url, threadId);
812
+ const sidebar = ctx.get("sidebarRight");
813
+ const tabs = ctx.get("sidebarRightTabs");
814
+ if (sidebar && tabs?.get("browser") !== void 0) sidebar.openTabIn(sessionId, "browser", { params: { url: target } });
815
+ else window.open(target, "_blank", "noopener,noreferrer");
816
+ }
817
+ })
818
+ },
819
+ CommentCards
820
+ )
821
+ );
822
+ joinArtifactsPage(ctx, CLIENT.plugin, CLIENT.skill);
823
+ }
824
+ return module.exports;
825
+ }
826
+ });