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.
- package/LICENSE +26 -0
- package/NOTICE.md +59 -0
- package/README.md +37 -3
- package/cordis.patch.yml +7 -0
- package/docs/DETAIL.md +32 -0
- package/docs/DETAIL.zh.md +17 -0
- package/icon.svg +8 -0
- package/lib/client.js +826 -0
- package/lib/index.js +594 -0
- package/locale/en.json +7 -0
- package/locale/zh.json +7 -0
- package/package.json +60 -6
- package/skills/claude-motion/SKILL.md +685 -0
- package/skills/claude-motion/artifact-type/reference/by-hand.md +84 -0
- package/skills/claude-motion/artifact-type/reference/film-api.md +278 -0
- package/skills/claude-motion/artifact-type/reference/finalize.md +213 -0
- package/skills/claude-motion/artifact-type/reference/motion.md +260 -0
- package/skills/claude-motion/artifact-type/reference/plan.md +239 -0
- package/skills/claude-motion/artifact-type/reference/questions.md +240 -0
- package/skills/claude-motion/artifact-type/reference/recreate-ui.md +140 -0
- package/skills/claude-motion/artifact-type/reference/render-offline.md +126 -0
- package/skills/claude-motion/artifact-type/reference/rough-cut.md +251 -0
- package/skills/claude-motion/artifact-type/reference/sound.md +106 -0
- package/skills/claude-motion/artifact-type/reference/styles.md +230 -0
- package/skills/claude-motion/artifact-type/reference/walkthrough.md +83 -0
- package/skills/claude-motion/scripts/artifact.mjs +8368 -0
- package/skills/claude-motion/scripts/editor/artifact-type/anthropicons-fizzy-lake-DtzHkSJH.woff2 +0 -0
- package/skills/claude-motion/scripts/editor/artifact-type/app.css +1 -0
- package/skills/claude-motion/scripts/editor/artifact-type/app.js +17230 -0
- package/skills/claude-motion/scripts/editor/index.html +145 -0
- package/skills/claude-motion/scripts/editor/local-host.js +12 -0
- package/skills/claude-motion/scripts/editor/share-ui.js +208 -0
- 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
|
+
});
|