dsh-claude-motion 2.11.0 → 2.11.1
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/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// dsh-claude-motion 2.11.
|
|
1
|
+
// dsh-claude-motion 2.11.1: built from baoyu-design.
|
|
2
2
|
var define_PLUGIN_default = { name: "claude-motion", provider: "dsh-claude-motion", skills: [{ name: "claude-motion", description: "Use this for a local Motion film: a short animated video (10–30 s unless asked for more, 900 s at most), such as an explainer, product walkthrough or UI demo, launch teaser, logo sting, social clip, animated chart or title sequence, that plays in the bundled Motion player and exports from there to MP4 or GIF. A narrated one carries a voice track: a take a scene, made here with a speech provider of the user's or recorded by them, spoken and captioned by the player, the motion timed to its words. Everything on screen is code, a pure function of time, written scene by scene into the film's own store with this skill's script while the user watches it fill in. Read it when creating, continuing, finalizing or revising one. Not for editing real footage, subtitles or audio (that is a video editor), a still picture, a slide deck or a static HTML page.", scriptAlias: "A", comments: true, requests: true }] };
|
|
3
3
|
|
|
4
4
|
import { readFile } from "node:fs/promises";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-claude-motion",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.1",
|
|
4
4
|
"description": "DeepSeek Harness plugin: the claude-motion skill from baoyu-design. The agent writes short animated films as code, scene by scene, and plays them in a local Motion player that exports MP4 or GIF.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|
|
@@ -24,6 +24,12 @@
|
|
|
24
24
|
"icon": "./icon.svg",
|
|
25
25
|
"baoyuDesign": {
|
|
26
26
|
"releaseNotes": [
|
|
27
|
+
{
|
|
28
|
+
"version": "2.11.1",
|
|
29
|
+
"date": "2026-11-05",
|
|
30
|
+
"en": "### Features\n- **DeepSeek Harness: the Artifacts page offers the plugins you haven't installed.** Beside the tiles for the skills you have, each other baoyu-design plugin gets a dimmed tile marked **Not installed**. Click it to see what the plugin makes and install it from there, at the same version as the ones you have, usually without a restart. Once it's in, **Start** opens a session with the skill. In an app that can't install from the page, the tile points you to the Plugins page. A plugin you installed and switched off still gets no tile.\n\n### Fixes\n- With `--agent-hook`, a comment could reach the agent twice: a second send could start the hook again after the first run had finished but before the comment was marked sent.",
|
|
31
|
+
"zh": "### 新功能\n- **DeepSeek Harness:「作品」页会列出你还没装的插件。** 已装技能的入口旁边,其他 baoyu-design 插件也各有一个入口,颜色淡一些,标着 **未安装**。点开会说明这个插件做什么,可以直接在这里安装,版本和你已装的一致,多数情况不用重启。装好后点 **新建** 就用这个技能开一个会话。应用不支持在页面里安装时,会引导你去插件页。装了但被你关掉的插件,仍然没有入口。\n\n### 修复\n- 用 `--agent-hook` 时,一条评论可能发给 agent 两次:第一次运行已经结束、评论还没标成已发送时,第二次发送会再启动一次 hook。"
|
|
32
|
+
},
|
|
27
33
|
{
|
|
28
34
|
"version": "2.11.0",
|
|
29
35
|
"date": "2026-11-05",
|
|
@@ -65,12 +71,6 @@
|
|
|
65
71
|
"date": "2026-11-02",
|
|
66
72
|
"en": "### Fixes\n- `claude-slides`: in a PowerPoint export, Chinese, Japanese or Korean text could show as boxes when its East Asian font was missing on the reader's computer or held none of those characters: Arial in the basic-fonts export, a Latin family, or an embedded subset that left characters out of a long deck. That text now names a font Windows and Office have instead (Microsoft YaHei, Microsoft JhengHei, Yu Gothic or Malgun Gothic). Text the embedded font holds, text without these characters and the Google Slides export are unchanged ([#29](https://github.com/JimLiu/baoyu-design/issues/29)).",
|
|
67
73
|
"zh": "### 修复\n- `claude-slides`:导出 PowerPoint 时,如果中日韩文字用的东亚字体在对方电脑上没有,或者这个字体本身不含这些字(basic 字体导出里的 Arial、拉丁字体、长 deck 里漏了字的内嵌子集),文字可能显示成方块。这类文字现在改用 Windows 和 Office 常见的字体(Microsoft YaHei、Microsoft JhengHei、Yu Gothic 或 Malgun Gothic)。内嵌字体装得下的文字、不含这些字的文字和 Google Slides 导出都不变([#29](https://github.com/JimLiu/baoyu-design/issues/29))。"
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
"version": "2.8.1",
|
|
71
|
-
"date": "2026-11-02",
|
|
72
|
-
"en": "### Fixes\n- `claude-slides`, `claude-design`, `claude-design-system`, `claude-dashboard`: their descriptions no longer send one-off HTML work to the `baoyu-design` skill, which is archived and no longer installed. They now only say what each skill is not for. The DeepSeek Harness plugins carry the same descriptions.",
|
|
73
|
-
"zh": "### 修复\n- `claude-slides`、`claude-design`、`claude-design-system`、`claude-dashboard`:说明里不再把一次性的 HTML 产出交给 `baoyu-design` 技能。这个技能已经归档,不再随仓库安装。现在只写各技能不适用于什么。DeepSeek Harness 插件里的说明也一样。"
|
|
74
74
|
}
|
|
75
75
|
]
|
|
76
76
|
},
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"dsh": ">=0.2.0-0"
|
|
97
97
|
},
|
|
98
98
|
"dependencies": {
|
|
99
|
-
"dsh-claude-artifacts": "^2.11.
|
|
99
|
+
"dsh-claude-artifacts": "^2.11.1"
|
|
100
100
|
},
|
|
101
101
|
"dsh": {
|
|
102
102
|
"bundle": {
|
|
@@ -1415,8 +1415,11 @@ var ShareHost = class {
|
|
|
1415
1415
|
* their own artifact; a guest comes over a LAN address (this computer's own included: that is how the owner sees
|
|
1416
1416
|
* what a role sees).
|
|
1417
1417
|
*/
|
|
1418
|
+
isLocal(request) {
|
|
1419
|
+
return this.options.local ? this.options.local(request) : isLoopback(request.socket.remoteAddress);
|
|
1420
|
+
}
|
|
1418
1421
|
viewerOf(request) {
|
|
1419
|
-
if (
|
|
1422
|
+
if (this.isLocal(request)) return { role: "owner", user: this.options.owner };
|
|
1420
1423
|
const guest = this.on ? this.sharing.guest(this.cookie(request)) : null;
|
|
1421
1424
|
if (!guest) return null;
|
|
1422
1425
|
this.sharing.seen(guest);
|
|
@@ -1548,7 +1551,7 @@ var ShareHost = class {
|
|
|
1548
1551
|
async join(request, response, method, token2) {
|
|
1549
1552
|
const t = this.words(request);
|
|
1550
1553
|
const role = this.sharing.linkRole(token2);
|
|
1551
|
-
const local =
|
|
1554
|
+
const local = this.isLocal(request);
|
|
1552
1555
|
const form = method === "POST" ? await readBody(request, 8 << 10).then((body) => body.toString("utf8"), () => "") : "";
|
|
1553
1556
|
const title = this.options.title();
|
|
1554
1557
|
if (!role || !local && !this.on) return this.sendPage(response, 404, t.linkGoneTitle, `<h1>${esc(t.linkGoneTitle)}</h1><p>${esc(t.linkGone)}</p>`);
|
|
@@ -3412,6 +3415,7 @@ data: ${JSON.stringify(snap)}
|
|
|
3412
3415
|
if (agentHook) await runHook(agentHook);
|
|
3413
3416
|
}
|
|
3414
3417
|
async function runHook(command2) {
|
|
3418
|
+
if (typeof command2 !== "string") return runHandler(command2);
|
|
3415
3419
|
const doc = await readComments(root);
|
|
3416
3420
|
for (const thread of pendingForAgent(doc)) {
|
|
3417
3421
|
if (hookRunning.has(thread.id)) continue;
|
|
@@ -3436,15 +3440,15 @@ data: ${JSON.stringify(snap)}
|
|
|
3436
3440
|
log3(`comments: the agent hook failed to start: ${error.message}`);
|
|
3437
3441
|
});
|
|
3438
3442
|
child.on("exit", (code) => {
|
|
3439
|
-
hookRunning.delete(thread.id);
|
|
3440
3443
|
if (code !== 0) {
|
|
3444
|
+
hookRunning.delete(thread.id);
|
|
3441
3445
|
log3(`comments: the agent hook exited with ${code} for ${thread.id}; the comment stays waiting${stderr ? `: ${stderr.trim()}` : ""}`);
|
|
3442
3446
|
return;
|
|
3443
3447
|
}
|
|
3444
3448
|
void updateComments(root, (d) => {
|
|
3445
3449
|
const t = d.threads.find((x) => x.id === thread.id);
|
|
3446
3450
|
if (t) markDelivered(t, now(), "hook");
|
|
3447
|
-
}).then(() => {
|
|
3451
|
+
}).finally(() => hookRunning.delete(thread.id)).then(() => {
|
|
3448
3452
|
log3(`comments: sent to the agent (hook): ${thread.id}`);
|
|
3449
3453
|
return broadcast();
|
|
3450
3454
|
}).catch((error) => log3(`comments: ${error.message}`));
|
|
@@ -3485,6 +3489,44 @@ data: ${JSON.stringify(snap)}
|
|
|
3485
3489
|
});
|
|
3486
3490
|
}
|
|
3487
3491
|
}
|
|
3492
|
+
async function runHandler(handler) {
|
|
3493
|
+
for (const { id } of pendingForAgent(await readComments(root))) {
|
|
3494
|
+
if (hookRunning.has(id)) continue;
|
|
3495
|
+
hookRunning.add(id);
|
|
3496
|
+
try {
|
|
3497
|
+
const doc = await readComments(root);
|
|
3498
|
+
const thread = pendingForAgent(doc).find((t) => t.id === id);
|
|
3499
|
+
if (!thread) continue;
|
|
3500
|
+
try {
|
|
3501
|
+
await handler.thread(agentViews(doc, [thread])[0]);
|
|
3502
|
+
} catch (error) {
|
|
3503
|
+
log3(`comments: the agent handler failed for ${id}; the comment stays waiting: ${error.message}`);
|
|
3504
|
+
continue;
|
|
3505
|
+
}
|
|
3506
|
+
await updateComments(root, (d) => {
|
|
3507
|
+
const t = d.threads.find((x) => x.id === id);
|
|
3508
|
+
if (t) markDelivered(t, now(), "hook");
|
|
3509
|
+
});
|
|
3510
|
+
log3(`comments: sent to the agent (handler): ${id}`);
|
|
3511
|
+
await broadcast();
|
|
3512
|
+
} finally {
|
|
3513
|
+
hookRunning.delete(id);
|
|
3514
|
+
}
|
|
3515
|
+
}
|
|
3516
|
+
const failed = [];
|
|
3517
|
+
for (const request of requests.splice(0)) {
|
|
3518
|
+
setRequestState(request.id, "working");
|
|
3519
|
+
try {
|
|
3520
|
+
await handler.request(request);
|
|
3521
|
+
log3(`comments: sent to the agent (handler): ${request.id}`);
|
|
3522
|
+
} catch (error) {
|
|
3523
|
+
failed.push(request);
|
|
3524
|
+
setRequestState(request.id, "queued");
|
|
3525
|
+
log3(`comments: the agent handler failed for ${request.id}; the request stays waiting: ${error.message}`);
|
|
3526
|
+
}
|
|
3527
|
+
}
|
|
3528
|
+
requests.unshift(...failed);
|
|
3529
|
+
}
|
|
3488
3530
|
let debounce;
|
|
3489
3531
|
const changed = () => {
|
|
3490
3532
|
clearTimeout(debounce);
|
|
@@ -85,7 +85,7 @@ h2 { flex: 1; min-width: 0; margin: 0; font-size: 17px; font-weight: 600; letter
|
|
|
85
85
|
.toast p { margin: 0; font-size: 13.5px; overflow-wrap: anywhere; }
|
|
86
86
|
.toast .path { margin-top: 4px; font: 12.5px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--fg); user-select: text; -webkit-user-select: text; overflow-wrap: anywhere; }
|
|
87
87
|
.toast.err p { color: var(--danger); }
|
|
88
|
-
`;function V(){if(/\bElectron\/\d/.test(navigator.userAgent))return!0;if(window.top===window)return!1;try{return window.top.location.origin!==location.origin}catch{return!0}}function F(t){let e=/filename\*=UTF-8''([^;]+)/i.exec(t??"");if(e)try{return decodeURIComponent(e[1])}catch{}return/filename="([^"]+)"/i.exec(t??"")?.[1]??""}async function q(t){let e=await t.json().catch(()=>null);if(!t.ok||!e||typeof e.path!="string")throw new Error(e?.message||`HTTP ${t.status}`);return e}var Y=class{layer=o("div",{"data-baoyu-save-layer":""});wrap=o("div",{class:"wrap"});node=null;timer;constructor(){this.layer.attachShadow({mode:"open"}).append(o("style",{},E+Ce),this.wrap)}saved(e,n=N.hint){this.show([o("p",{},N.saved(e.name)),o("div",{class:"path"},e.shown),o("div",{class:"hint"},n)],!1)}failed(e){this.show([o("p",{},e)],!0)}show(e,n){this.layer.isConnected||document.body.append(this.layer),window.clearTimeout(this.timer),this.node?.remove();let i=o("div",{class:`toast${n?" err":""}`,role:n?"alert":"status","data-baoyu-save-toast":""},...e);this.wrap.append(i),this.node=i,this.timer=window.setTimeout(()=>{i.remove(),this.node===i&&(this.node=null)},n?1e4:12e3)}},He=null;function U(){return He??=new Y}async function Ne(t,e){return q(await fetch(`${Oe}?name=${encodeURIComponent(e)}`,{method:"POST",body:t,headers:{"Content-Type":t.type||"application/octet-stream"}}))}function _e(t){for(let e of t.composedPath())if(e instanceof HTMLAnchorElement&&e.hasAttribute("download")&&e.href)return e;return null}function ze(t){try{let e=new URL(t.href,location.href);return e.protocol==="blob:"||e.protocol==="data:"||e.origin===location.origin}catch{return!1}}function ce(t){if(!V())return!1;let e=U(),n=async(a,c,u={})=>{try{let f=await Ne(a,c);return u.quiet||e.saved(f),f}catch(f){throw u.quiet||e.failed(N.failed(c,f instanceof Error?f.message:String(f))),f}},i=a=>{let c=a.getAttribute("download")??"",u=a.href,f=fetch(u,{cache:"no-store"});(async()=>{let h=c||"download",g;try{let m=await f;if(!m.ok)throw new Error(`HTTP ${m.status}`);h=c||F(m.headers.get("Content-Disposition"))||"download",g=await m.blob()}catch(m){return e.failed(N.failed(h,m instanceof Error?m.message:String(m)))}await n(g,h).catch(()=>{})})()},r=a=>a!==null&&(!t||ze(a)),s=a=>{t?i(a):e.failed(N.guest)};window.addEventListener("click",a=>{let c=_e(a);a.defaultPrevented||!r(c)||(a.preventDefault(),s(c))},!0);let p=HTMLAnchorElement.prototype.click;return HTMLAnchorElement.prototype.click=function(){if(!this.isConnected&&this.hasAttribute("download")&&this.href&&r(this))return s(this);p.call(this)},t&&(window.__baoyuSave=n),!0}var J="/__share/archive",je={label:"Whole folder (.zip)",description:"Everything here, to back up or move"},R=y?{started:t=>`\u5F00\u59CB\u4E0B\u8F7D ${t}`,hint:"\u6574\u4E2A\u6587\u4EF6\u5939\u6253\u6210\u4E86\u4E00\u4E2A zip\uFF0C\u53EF\u4EE5\u5907\u4EFD\u3001\u6362\u7535\u8111\u6216\u53D1\u7ED9\u522B\u4EBA\u3002\u89E3\u538B\u540E\u7528\u540C\u4E00\u4E2A skill \u6253\u5F00\u5C31\u80FD\u63A5\u7740\u7528\uFF1B\u5206\u4EAB\u94FE\u63A5\u548C\u8FD9\u53F0\u7535\u8111\u4E0A\u7684\u670D\u52A1\u5668\u72B6\u6001\u4E0D\u5728\u91CC\u9762\u3002",beside:"\u8FD9\u4E2A\u6D4F\u89C8\u5668\u4E0D\u80FD\u4E0B\u8F7D\u6587\u4EF6\uFF0Czip \u5B58\u5728\u4E86\u6587\u4EF6\u5939\u65C1\u8FB9\u3002\u89E3\u538B\u540E\u7528\u540C\u4E00\u4E2A skill \u6253\u5F00\u5C31\u80FD\u63A5\u7740\u7528\u3002",tooLarge:"\u6587\u4EF6\u5939\u8D85\u8FC7\u4E86 zip \u7684\u4E0A\u9650\uFF084 GiB \u6216 65535 \u4E2A\u6587\u4EF6\uFF09\uFF0C\u8BF7\u76F4\u63A5\u590D\u5236\u6587\u4EF6\u5939\u3002",failed:"\u6CA1\u80FD\u6253\u5305\uFF1A"}:{started:t=>`Downloading ${t}`,hint:"The whole folder in one zip, to back up, move to another computer or send to someone. Unzip it and open it with the same skill to carry on; share links and this computer's server state are left out.",beside:"This browser doesn't download files, so the zip went beside the folder. Unzip it and open it with the same skill to carry on.",tooLarge:"The folder is over what a zip holds (4 GiB or 65,535 files): copy the folder itself instead.",failed:"Could not zip the folder: "},Be=`
|
|
88
|
+
`;function V(){if(window.__baoyuNativeDownloads===!0)return!1;if(/\bElectron\/\d/.test(navigator.userAgent))return!0;if(window.top===window)return!1;try{return window.top.location.origin!==location.origin}catch{return!0}}function F(t){let e=/filename\*=UTF-8''([^;]+)/i.exec(t??"");if(e)try{return decodeURIComponent(e[1])}catch{}return/filename="([^"]+)"/i.exec(t??"")?.[1]??""}async function q(t){let e=await t.json().catch(()=>null);if(!t.ok||!e||typeof e.path!="string")throw new Error(e?.message||`HTTP ${t.status}`);return e}var Y=class{layer=o("div",{"data-baoyu-save-layer":""});wrap=o("div",{class:"wrap"});node=null;timer;constructor(){this.layer.attachShadow({mode:"open"}).append(o("style",{},E+Ce),this.wrap)}saved(e,n=N.hint){this.show([o("p",{},N.saved(e.name)),o("div",{class:"path"},e.shown),o("div",{class:"hint"},n)],!1)}failed(e){this.show([o("p",{},e)],!0)}show(e,n){this.layer.isConnected||document.body.append(this.layer),window.clearTimeout(this.timer),this.node?.remove();let i=o("div",{class:`toast${n?" err":""}`,role:n?"alert":"status","data-baoyu-save-toast":""},...e);this.wrap.append(i),this.node=i,this.timer=window.setTimeout(()=>{i.remove(),this.node===i&&(this.node=null)},n?1e4:12e3)}},He=null;function U(){return He??=new Y}async function Ne(t,e){return q(await fetch(`${Oe}?name=${encodeURIComponent(e)}`,{method:"POST",body:t,headers:{"Content-Type":t.type||"application/octet-stream"}}))}function _e(t){for(let e of t.composedPath())if(e instanceof HTMLAnchorElement&&e.hasAttribute("download")&&e.href)return e;return null}function ze(t){try{let e=new URL(t.href,location.href);return e.protocol==="blob:"||e.protocol==="data:"||e.origin===location.origin}catch{return!1}}function ce(t){if(!V())return!1;let e=U(),n=async(a,c,u={})=>{try{let f=await Ne(a,c);return u.quiet||e.saved(f),f}catch(f){throw u.quiet||e.failed(N.failed(c,f instanceof Error?f.message:String(f))),f}},i=a=>{let c=a.getAttribute("download")??"",u=a.href,f=fetch(u,{cache:"no-store"});(async()=>{let h=c||"download",g;try{let m=await f;if(!m.ok)throw new Error(`HTTP ${m.status}`);h=c||F(m.headers.get("Content-Disposition"))||"download",g=await m.blob()}catch(m){return e.failed(N.failed(h,m instanceof Error?m.message:String(m)))}await n(g,h).catch(()=>{})})()},r=a=>a!==null&&(!t||ze(a)),s=a=>{t?i(a):e.failed(N.guest)};window.addEventListener("click",a=>{let c=_e(a);a.defaultPrevented||!r(c)||(a.preventDefault(),s(c))},!0);let p=HTMLAnchorElement.prototype.click;return HTMLAnchorElement.prototype.click=function(){if(!this.isConnected&&this.hasAttribute("download")&&this.href&&r(this))return s(this);p.call(this)},t&&(window.__baoyuSave=n),!0}var J="/__share/archive",je={label:"Whole folder (.zip)",description:"Everything here, to back up or move"},R=y?{started:t=>`\u5F00\u59CB\u4E0B\u8F7D ${t}`,hint:"\u6574\u4E2A\u6587\u4EF6\u5939\u6253\u6210\u4E86\u4E00\u4E2A zip\uFF0C\u53EF\u4EE5\u5907\u4EFD\u3001\u6362\u7535\u8111\u6216\u53D1\u7ED9\u522B\u4EBA\u3002\u89E3\u538B\u540E\u7528\u540C\u4E00\u4E2A skill \u6253\u5F00\u5C31\u80FD\u63A5\u7740\u7528\uFF1B\u5206\u4EAB\u94FE\u63A5\u548C\u8FD9\u53F0\u7535\u8111\u4E0A\u7684\u670D\u52A1\u5668\u72B6\u6001\u4E0D\u5728\u91CC\u9762\u3002",beside:"\u8FD9\u4E2A\u6D4F\u89C8\u5668\u4E0D\u80FD\u4E0B\u8F7D\u6587\u4EF6\uFF0Czip \u5B58\u5728\u4E86\u6587\u4EF6\u5939\u65C1\u8FB9\u3002\u89E3\u538B\u540E\u7528\u540C\u4E00\u4E2A skill \u6253\u5F00\u5C31\u80FD\u63A5\u7740\u7528\u3002",tooLarge:"\u6587\u4EF6\u5939\u8D85\u8FC7\u4E86 zip \u7684\u4E0A\u9650\uFF084 GiB \u6216 65535 \u4E2A\u6587\u4EF6\uFF09\uFF0C\u8BF7\u76F4\u63A5\u590D\u5236\u6587\u4EF6\u5939\u3002",failed:"\u6CA1\u80FD\u6253\u5305\uFF1A"}:{started:t=>`Downloading ${t}`,hint:"The whole folder in one zip, to back up, move to another computer or send to someone. Unzip it and open it with the same skill to carry on; share links and this computer's server state are left out.",beside:"This browser doesn't download files, so the zip went beside the folder. Unzip it and open it with the same skill to carry on.",tooLarge:"The folder is over what a zip holds (4 GiB or 65,535 files): copy the folder itself instead.",failed:"Could not zip the folder: "},Be=`
|
|
89
89
|
.toast { position: fixed; right: 16px; bottom: 16px; z-index: 2147483003; width: min(380px, calc(100vw - 32px)); background: var(--bg); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow); padding: 12px 14px; }
|
|
90
90
|
.toast p { margin: 0; font-size: 13.5px; overflow-wrap: anywhere; }
|
|
91
91
|
.toast.err p { color: var(--danger); }
|