writedock-mcp 0.4.7 → 0.4.8
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/README.md +6 -2
- package/extension/assets/editor-DSj8NlXD.js +76 -0
- package/extension/assets/index.ts-CrE-nH9x.js +42 -0
- package/extension/manifest.json +1 -1
- package/extension/service-worker-loader.js +1 -1
- package/extension/src/editor/index.html +1 -1
- package/extension//345/256/211/350/243/205/344/270/216/346/233/264/346/226/260.txt +4 -3
- package/index.cjs +20 -17
- package/package.json +1 -1
- package/source/package.json +1 -1
- package/source/src/__tests__/setup.test.ts +19 -0
- package/source/src/bridge.ts +1 -1
- package/source/src/server.ts +3 -3
- package/source/src/setup.ts +22 -12
- package/source/tsup.config.ts +2 -0
- package/extension/assets/editor-ClIT9WYa.js +0 -76
- package/extension/assets/index.ts-BEVXnN62.js +0 -42
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ MCP 运行在你自己的电脑上,只监听 `127.0.0.1`。平台 Cookie 留
|
|
|
6
6
|
|
|
7
7
|
## 安装
|
|
8
8
|
|
|
9
|
-
需要 Node.js 22+ 和 Chrome 或 Edge
|
|
9
|
+
需要 Node.js 22+ 和 Chrome 或 Edge。没有 Node.js 时,agent 应先帮用户安装(nodejs.org 的 LTS 版,或系统的包管理器),需要用户操作时告诉用户,装好后可能要重启 agent 才找得到 `npx`。然后运行:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
12
|
npx -y writedock-mcp@latest setup
|
|
@@ -32,6 +32,8 @@ npx -y writedock-mcp@latest setup
|
|
|
32
32
|
}
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
Windows 上要写成 `"command": "cmd"`、`"args": ["/c", "npx", "-y", "--prefer-online", "writedock-mcp@latest"]`,`setup` 会自动处理。如果 PowerShell 提示禁止运行脚本,把安装命令换成 `cmd /c npx -y writedock-mcp@latest setup`。
|
|
36
|
+
|
|
35
37
|
首次下载较慢,请把启动超时设为 120 秒。启动后调用 `get_connection_status`;未连接时,让用户打开扩展点「连接」。
|
|
36
38
|
|
|
37
39
|
## 发布
|
|
@@ -79,10 +81,12 @@ npx -y writedock-mcp@latest setup
|
|
|
79
81
|
| `not_logged_in` | 未登录,未执行 | 请用户登录后,用新 `request_id` 只重发这些平台 |
|
|
80
82
|
| `login_unconfirmed` | 无法确认登录状态,未执行 | 请用户检查后再提交 |
|
|
81
83
|
| `waiting_verification` | 正在等用户完成验证码 | 立即转告 `user_actions` 的提示和链接,继续查询 |
|
|
82
|
-
| `needs_user_action` | 需要用户在页面上处理 |
|
|
84
|
+
| `needs_user_action` | 需要用户在页面上处理 | 转告原因和链接,不重发;`type` 为 `old_draft` 时见下方 |
|
|
83
85
|
| `unknown` | 结果未确认,可能已经发布 | 让用户核对,**不要重发** |
|
|
84
86
|
| `failed` | 未能完成 | 汇报 `error`,必要时提供 `diagnostics` |
|
|
85
87
|
|
|
88
|
+
抖音有上次没发完的内容时,这篇不会上传,`user_actions` 的 `type` 是 `old_draft`。agent 必须先问用户是否放弃旧内容,放弃后无法恢复。用户同意后,用新的 `request_id` 只对抖音再调用 `publish`,并传 `"discard_old_drafts": ["douyin"]`;用户不同意就保留旧内容,抖音不发。
|
|
89
|
+
|
|
86
90
|
验证码由用户手动完成,agent 和扩展都不代做。用户完成后任务会自动更新,不需要重新提交。
|
|
87
91
|
|
|
88
92
|
相同 `request_id` 和相同内容不会重复提交;内容变化必须换新 ID。部分平台失败时,只针对失败的平台用新 ID 重发,`unknown` 的平台不要重发。
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import{p as oe}from"./purify.es-1yEQDPgc.js";import{r as i,j as e,c as de}from"./react-vendor-BrXlnJmF.js";import{S as B,s as P,e as he}from"./task-utils-DwzGcJkm.js";/**
|
|
2
|
+
* @license lucide-react v0.303.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/var ue={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};/**
|
|
7
|
+
* @license lucide-react v0.303.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const xe=t=>t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase().trim(),m=(t,d)=>{const l=i.forwardRef(({color:g="currentColor",size:o=24,strokeWidth:j=2,absoluteStrokeWidth:x,className:y="",children:u,...N},c)=>i.createElement("svg",{ref:c,...ue,width:o,height:o,stroke:g,strokeWidth:x?Number(j)*24/Number(o):j,className:["lucide",`lucide-${xe(t)}`,y].join(" "),...N},[...d.map(([v,k])=>i.createElement(v,k)),...Array.isArray(u)?u:[u]]));return l.displayName=`${t}`,l};/**
|
|
12
|
+
* @license lucide-react v0.303.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const Z=m("Check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);/**
|
|
17
|
+
* @license lucide-react v0.303.0 - ISC
|
|
18
|
+
*
|
|
19
|
+
* This source code is licensed under the ISC license.
|
|
20
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
21
|
+
*/const pe=m("Copy",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]]);/**
|
|
22
|
+
* @license lucide-react v0.303.0 - ISC
|
|
23
|
+
*
|
|
24
|
+
* This source code is licensed under the ISC license.
|
|
25
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
26
|
+
*/const q=m("ExternalLink",[["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}],["polyline",{points:"15 3 21 3 21 9",key:"mznyad"}],["line",{x1:"10",x2:"21",y1:"14",y2:"3",key:"18c3s4"}]]);/**
|
|
27
|
+
* @license lucide-react v0.303.0 - ISC
|
|
28
|
+
*
|
|
29
|
+
* This source code is licensed under the ISC license.
|
|
30
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
31
|
+
*/const me=m("Eye",[["path",{d:"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z",key:"rwhkz3"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);/**
|
|
32
|
+
* @license lucide-react v0.303.0 - ISC
|
|
33
|
+
*
|
|
34
|
+
* This source code is licensed under the ISC license.
|
|
35
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
36
|
+
*/const U=m("FileText",[["path",{d:"M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z",key:"1nnpy2"}],["polyline",{points:"14 2 14 8 20 8",key:"1ew0cm"}],["line",{x1:"16",x2:"8",y1:"13",y2:"13",key:"14keom"}],["line",{x1:"16",x2:"8",y1:"17",y2:"17",key:"17nazh"}],["line",{x1:"10",x2:"8",y1:"9",y2:"9",key:"1a5vjj"}]]);/**
|
|
37
|
+
* @license lucide-react v0.303.0 - ISC
|
|
38
|
+
*
|
|
39
|
+
* This source code is licensed under the ISC license.
|
|
40
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
41
|
+
*/const O=m("History",[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}],["path",{d:"M12 7v5l4 2",key:"1fdv2h"}]]);/**
|
|
42
|
+
* @license lucide-react v0.303.0 - ISC
|
|
43
|
+
*
|
|
44
|
+
* This source code is licensed under the ISC license.
|
|
45
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
46
|
+
*/const fe=m("Info",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]]);/**
|
|
47
|
+
* @license lucide-react v0.303.0 - ISC
|
|
48
|
+
*
|
|
49
|
+
* This source code is licensed under the ISC license.
|
|
50
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
51
|
+
*/const G=m("Link2",[["path",{d:"M9 17H7A5 5 0 0 1 7 7h2",key:"8i5ue5"}],["path",{d:"M15 7h2a5 5 0 1 1 0 10h-2",key:"1b9ql8"}],["line",{x1:"8",x2:"16",y1:"12",y2:"12",key:"1jonct"}]]);/**
|
|
52
|
+
* @license lucide-react v0.303.0 - ISC
|
|
53
|
+
*
|
|
54
|
+
* This source code is licensed under the ISC license.
|
|
55
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
56
|
+
*/const W=m("Loader2",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);/**
|
|
57
|
+
* @license lucide-react v0.303.0 - ISC
|
|
58
|
+
*
|
|
59
|
+
* This source code is licensed under the ISC license.
|
|
60
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
61
|
+
*/const K=m("RefreshCw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);/**
|
|
62
|
+
* @license lucide-react v0.303.0 - ISC
|
|
63
|
+
*
|
|
64
|
+
* This source code is licensed under the ISC license.
|
|
65
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
66
|
+
*/const je=m("Trash2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]]);/**
|
|
67
|
+
* @license lucide-react v0.303.0 - ISC
|
|
68
|
+
*
|
|
69
|
+
* This source code is licensed under the ISC license.
|
|
70
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
71
|
+
*/const ye=m("Users",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["path",{d:"M16 3.13a4 4 0 0 1 0 7.75",key:"1da9ce"}]]);/**
|
|
72
|
+
* @license lucide-react v0.303.0 - ISC
|
|
73
|
+
*
|
|
74
|
+
* This source code is licensed under the ISC license.
|
|
75
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
76
|
+
*/const J=m("X",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);async function ke(){return(await chrome.storage.local.get(B.draftIndex))[B.draftIndex]||[]}async function ve(t){const d=`writedockDraft:${t}`;return(await chrome.storage.local.get(d))[d]||null}async function Ne(t){return E("DELETE_DRAFT",{draftId:t})}async function E(t,d={}){const l=await chrome.runtime.sendMessage({type:t,...d});if(l!=null&&l.error)throw new Error(l.error);if(!l||!("data"in l))throw new Error("扩展后台未响应,请在扩展管理页重新加载 WriteDock");return l.data}function ge({bridge:t,busy:d,syncing:l,update:g,connect:o,updateExtension:j,copy:x}){const[y,u]=i.useState(String(t.port));i.useEffect(()=>u(String(t.port)),[t.port]);const N="帮我安装 WriteDock:先检查电脑上有没有 Node.js 22 或更高版本,没有就帮我安装,需要我操作时告诉我;然后运行 npx -y writedock-mcp@latest setup,最后告诉我怎么重启你。",c=[t.mcpVersion?`服务版本 v${t.mcpVersion}`:"",t.connected&&t.mcpLatestVersion?`最新 v${t.mcpLatestVersion}`:""].filter(Boolean).join(" · ");return e.jsxs("div",{className:"connection-page",children:[t.connected?e.jsxs("section",{className:"panel",children:[e.jsx("div",{className:"panel-heading",children:e.jsxs("div",{children:[e.jsxs("h2",{children:[e.jsx(Z,{size:16})," 已连接"]}),e.jsxs("p",{children:["告诉你的 agent 要写什么、发到哪些平台就行。",c&&` ${c}`]})]})}),t.mcpUpdateAvailable&&e.jsx("p",{className:"help-text",role:"status",children:"有新版本。等发布结束后重启你的 agent 就会更新,不用重新连接。"})]}):t.mcpFound?e.jsxs("section",{className:"panel",children:[e.jsx("h2",{children:"发现本机的 WriteDock 服务"}),e.jsxs("p",{className:"help-text",children:[t.mcpFoundVersion?`服务版本 v${t.mcpFoundVersion}。`:"","点一下就能连上,以后会自动连接。"]}),e.jsx("div",{className:"settings-actions",children:e.jsx("button",{className:"primary-button",disabled:d||l,onClick:()=>void o(),children:d?"正在连接…":"连接"})})]}):e.jsxs("section",{className:"panel",children:[e.jsx("h2",{children:"把这句话发给你的 agent"}),e.jsx("p",{className:"help-text",children:"它会帮你装好,需要你操作时会告诉你。"}),e.jsx("pre",{tabIndex:0,className:"setup-sentence",children:N}),e.jsx("div",{className:"settings-actions",children:e.jsxs("button",{className:"primary-button",onClick:()=>void x(N),children:[e.jsx(pe,{size:14}),"复制这句话"]})}),e.jsx("p",{className:"help-text",children:"agent 重启后,这里会出现“连接”按钮。"})]}),t.connected&&t.extensionUpdateVersion&&e.jsxs("section",{className:"panel",children:[e.jsxs("h2",{children:["扩展有新版本 v",t.extensionUpdateVersion]}),e.jsx("p",{className:"help-text",children:"点一下就能更新,连接和稿件都会保留。"}),e.jsx("div",{className:"settings-actions",children:e.jsx("button",{className:"primary-button",disabled:d||l,onClick:()=>void j(),children:d?"正在更新…":"更新扩展"})}),l&&e.jsx("p",{className:"help-text",children:"发布结束后才能更新。"})]}),e.jsxs("section",{className:"panel compact",children:[e.jsx("h2",{children:"怎么用"}),e.jsxs("ol",{children:[e.jsx("li",{children:"在「平台登录」里确认要发布的平台已登录。"}),e.jsx("li",{children:"告诉 agent 写什么、发到哪些平台。"}),e.jsx("li",{children:"遇到验证码时,agent 会告诉你去哪个页面完成。"})]})]}),e.jsxs("details",{className:"panel developer-settings",children:[e.jsx("summary",{children:"高级设置"}),e.jsx("p",{className:"help-text",children:"通常不需要动这里。"}),e.jsxs("label",{children:["启用自动连接",e.jsx("button",{role:"switch","aria-label":"启用 MCP 连接","aria-checked":t.enabled,className:`switch ${t.enabled?"on":""}`,disabled:d||l,onClick:()=>g({enabled:!t.enabled}),children:e.jsx("span",{})})]}),e.jsx("div",{className:"settings-grid",children:e.jsxs("label",{children:["连接端口",e.jsx("input",{"aria-label":"连接端口",inputMode:"numeric",value:y,onChange:v=>u(v.target.value)})]})}),e.jsx("div",{className:"settings-actions",children:e.jsx("button",{className:"secondary-button",disabled:d||l||y===String(t.port),onClick:()=>g({port:Number(y)}),children:"保存端口"})})]})]})}const X=t=>new Intl.DateTimeFormat("zh-CN",{month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1}).format(t),M=t=>t.trim()||"未命名稿件",we={syncing:"正在保存",completed:"已保存草稿",partial:"部分成功",failed:"失败",interrupted:"中断了",unknown:"请去平台确认",needs_user_action:"需要你处理",rehearsed:"演练完成"},Q={syncing:"正在发布",completed:"已发布",partial:"部分成功",failed:"发布失败",interrupted:"中断了",unknown:"请去平台确认",needs_user_action:"需要你处理",rehearsed:"演练完成"},be={...Q,syncing:"正在演练",completed:"演练完成",partial:"部分通过",failed:"演练失败"},Ee={pending:"排队中",checking_auth:"检查登录",uploading_images:"上传图片",transferring_media:"读取素材",uploading_media:"上传素材",preparing_article:"准备内容",publishing:"发布中",verifying:"等待平台确认",saving:"保存草稿",completed:"完成",failed:"失败",unknown:"请去平台确认",needs_user_action:"需要你处理",waiting_verification:"等你完成验证"},Te=t=>(t.videos||[]).reduce((d,l)=>d.replace(l.marker,`视频:${he(l.asset.name)}`),t.html),Ce=t=>t.publicationState==="rehearsed"?"演练通过,未发布":t.errorCode==="not_logged_in"?"未登录,已跳过":t.publicationState==="needs_user_action"?"需要你处理":t.publicationState==="unknown"?"请去平台确认":t.success?t.draftOnly===!1?"已发布":"已保存草稿":"失败";function Y({title:t,children:d,close:l,wide:g=!1}){const o=i.useRef(null),j=i.useRef(l);return j.current=l,i.useEffect(()=>{var u,N;const x=document.activeElement;(N=(u=o.current)==null?void 0:u.querySelector("button"))==null||N.focus();const y=c=>{var w;if(c.key==="Escape"){c.preventDefault(),j.current();return}if(c.key!=="Tab")return;const v=Array.from(((w=o.current)==null?void 0:w.querySelectorAll('button:not(:disabled), a[href], input, [tabindex="0"]'))||[]),k=v[0],T=v.at(-1);c.shiftKey&&document.activeElement===k?(c.preventDefault(),T==null||T.focus()):!c.shiftKey&&document.activeElement===T&&(c.preventDefault(),k==null||k.focus())};return document.addEventListener("keydown",y),()=>{document.removeEventListener("keydown",y),x==null||x.focus()}},[]),e.jsx("div",{className:"modal-backdrop",onMouseDown:x=>{x.target===x.currentTarget&&l()},children:e.jsxs("section",{className:`modal ${g?"wide":""}`,ref:o,role:"dialog","aria-modal":"true","aria-label":t,children:[e.jsxs("header",{children:[e.jsx("h2",{children:t}),e.jsx("button",{className:"icon-button","aria-label":"关闭弹窗",onClick:l,children:e.jsx(J,{size:18})})]}),d]})})}function _e(){const[t,d]=i.useState("tasks"),[l,g]=i.useState([]),[o,j]=i.useState(null),[x,y]=i.useState([]),[u,N]=i.useState([]),[c,v]=i.useState(null),[k,T]=i.useState(!1),[w,b]=i.useState(!1),[_,ee]=i.useState(!1),[L,p]=i.useState(""),[S,I]=i.useState(null),[F,z]=i.useState(null),R=i.useRef(!1),C=i.useCallback(async()=>{const[s,r,n]=await Promise.all([ke(),E("GET_SYNC_STATE"),E("GET_SYNC_HISTORY")]);g(s),j(r),y(n)},[]),A=i.useCallback(async()=>{const s=await E("GET_BRIDGE_STATE");return v(s),s},[]),$=i.useCallback(async(s=!1)=>{T(!0);try{N(await E("CHECK_ALL_AUTH",{forceRefresh:s}))}catch(r){p(r instanceof Error?r.message:"登录检测失败")}finally{T(!1)}},[]);i.useEffect(()=>{let s=!1;Promise.all([C(),A()]).then(([,a])=>{s||(a.connected||d("connection"),ee(!0),$())}).catch(a=>p(String(a.message||a)));const r=a=>(a.type==="TASK_UPDATED"&&a.task&&(j(a.task),a.task.status!=="syncing"&&C().catch(()=>{})),["DRAFT_SAVED","DRAFT_DELETED"].includes(a.type)&&(a.type==="DRAFT_DELETED"&&(I(h=>(h==null?void 0:h.id)===a.draftId?null:h),j(h=>(h==null?void 0:h.draftId)===a.draftId?null:h),y(h=>h.filter(f=>f.draftId!==a.draftId))),C().catch(()=>{})),a.type==="BRIDGE_STATUS_UPDATED"&&A().catch(()=>{}),!1);chrome.runtime.onMessage.addListener(r);const n=()=>{R.current&&(R.current=!1,$(!0))};return window.addEventListener("focus",n),()=>{s=!0,chrome.runtime.onMessage.removeListener(r),window.removeEventListener("focus",n)}},[C,A,$]),i.useEffect(()=>{if(t!=="connection"||c!=null&&c.connected)return;const s=setInterval(()=>{A().catch(()=>{})},3e3);return()=>clearInterval(s)},[t,c==null?void 0:c.connected,A]),i.useEffect(()=>{if(!L)return;const s=setTimeout(()=>p(""),7e3);return()=>clearTimeout(s)},[L]);const se=async s=>{b(!0);try{v(await E("SET_BRIDGE_CONFIG",{payload:s}))}catch(r){p(r instanceof Error?r.message:"连接设置保存失败")}finally{b(!1)}},te=async()=>{b(!0);try{return v(await E("CONNECT_BRIDGE")),!0}catch(s){return p(s instanceof Error?s.message:"连接失败"),!1}finally{b(!1)}},ae=async()=>{b(!0);try{await E("UPDATE_EXTENSION"),p("更新完成,正在重新加载")}catch(s){p(s instanceof Error?s.message:"更新失败")}finally{b(!1)}},H=(s,r=!1)=>{const n=P(s);n&&(async()=>{if(r){const a=new URL(n),f=(await chrome.tabs.query({})).find(le=>{try{const D=new URL(le.url||"");return D.origin===a.origin&&D.pathname===a.pathname&&(a.searchParams.has("article_id")?D.searchParams.get("article_id")===a.searchParams.get("article_id"):a.hash?D.hash===a.hash:D.href===a.href)}catch{return!1}});if(f!=null&&f.id){await chrome.tabs.update(f.id,{active:!0}),await chrome.windows.update(f.windowId,{focused:!0});return}}await chrome.tabs.create({url:n})})().catch(a=>p(a instanceof Error?a.message:"无法打开稿件页"))},ne=async s=>{try{await navigator.clipboard.writeText(s),p("已复制")}catch{p("复制失败,请选中文字后复制")}},V=o?[o,...x.filter(s=>s.id!==o.id)]:x,ce=s=>{var r;return((r=u.find(n=>n.id===s))==null?void 0:r.name)||s},re=u.filter(s=>s.isAuthenticated).length,ie=s=>e.jsxs("section",{className:"task-card","aria-label":`任务:${s.title}`,children:[e.jsxs("div",{className:"task-title",children:[e.jsxs("div",{children:[e.jsx("h3",{children:M(s.title)}),e.jsx("span",{children:X(s.startedAt)})]}),e.jsxs("span",{className:`task-status ${s.status}`,children:[s.status==="syncing"&&e.jsx(W,{size:13,className:"spin"}),(s.action==="rehearsal"?be:s.action==="publish"?Q:we)[s.status]]})]}),e.jsx("div",{className:"task-result-list",children:s.platforms.map(r=>{var h;const n=s.results.find(f=>f.platform===r),a=s.progress[r];return e.jsxs("div",{className:"task-result",children:[e.jsxs("div",{children:[e.jsx("strong",{children:ce(r)}),e.jsxs("span",{className:(n==null?void 0:n.publicationState)==="needs_user_action"||(a==null?void 0:a.stage)==="waiting_verification"?"manual-text":n!=null&&n.success||(n==null?void 0:n.publicationState)==="rehearsed"?"success-text":n?"error-text":"",children:[n?Ce(n):Ee[(a==null?void 0:a.stage)||"pending"],(a==null?void 0:a.stage)==="uploading_images"&&a.total?` ${a.current}/${a.total}`:"",(a==null?void 0:a.stage)==="transferring_media"&&a.total?` ${((a.current||0)/1048576).toFixed(1)} / ${(a.total/1048576).toFixed(1)} MB`:""]}),n&&(n.success||n.draftOnly===!1)&&P(((h=n.userAction)==null?void 0:h.url)||n.postUrl)&&e.jsxs("button",{className:"link-button",onClick:()=>{var f;return H(((f=n.userAction)==null?void 0:f.url)||n.postUrl,n.requiresUserAction===!0)},children:[n.requiresUserAction?"去页面处理":n.publicationState==="unknown"?"去平台确认":n.publicationState==="rehearsed"?"查看页面":n.draftOnly===!1?"查看":"打开草稿",e.jsx(q,{size:12})]})]}),(n==null?void 0:n.error)&&e.jsx("p",{className:"error-text",children:n.error}),(n==null?void 0:n.message)&&!n.success&&e.jsx("p",{children:n.message}),!n&&(a==null?void 0:a.message)&&e.jsx("p",{children:a.message})]},r)})}),s.error&&e.jsx("p",{className:"error-text task-error",children:s.error}),e.jsx("footer",{children:s.action==="rehearsal"?`演练 ${s.results.filter(r=>r.publicationState==="rehearsed").length} / ${s.platforms.length} 个平台通过`:`${s.results.filter(r=>r.success).length} / ${s.platforms.length} 个平台成功`})]},s.id);return e.jsxs("div",{className:"console-shell",children:[e.jsxs("header",{className:"app-header",children:[e.jsxs("div",{className:"brand",children:[e.jsx("img",{src:"/assets/icon-48.png",width:"26",height:"26",alt:""}),e.jsx("strong",{children:"WriteDock"})]}),e.jsxs("button",{className:`connection-indicator ${c!=null&&c.connected?"online":""}`,onClick:()=>d("connection"),children:[e.jsx("span",{}),c!=null&&c.connected?"已连接":"未连接"]})]}),e.jsxs("aside",{className:"navigation",children:[e.jsx("nav",{"aria-label":"控制台导航",children:[["tasks",O,"发布记录"],["accounts",ye,"平台登录"],["articles",U,"稿件"],["connection",G,"连接 agent"]].map(([s,r,n])=>e.jsxs("button",{className:t===s?"selected":"",onClick:()=>d(s),children:[e.jsx(r,{size:17}),n,s==="tasks"&&(o==null?void 0:o.status)==="syncing"&&e.jsx("span",{className:"nav-dot"}),s==="connection"&&((c==null?void 0:c.mcpUpdateAvailable)||(c==null?void 0:c.extensionUpdateVersion))&&e.jsx("span",{className:"nav-dot",title:"有新版本"})]},s))}),e.jsxs("footer",{children:[e.jsx(fe,{size:13}),e.jsxs("span",{children:["v",chrome.runtime.getManifest().version]})]})]}),e.jsxs("main",{className:"console-main",children:[e.jsxs("div",{className:"page-heading",children:[e.jsxs("div",{children:[e.jsx("h1",{children:{articles:"稿件",tasks:"发布记录",accounts:"平台登录",connection:"连接 agent"}[t]}),e.jsx("p",{children:{articles:"agent 写好的内容,可以在这里预览。",tasks:"每次发布到各平台的结果。",accounts:"在这个浏览器里登录要发布的平台。",connection:"连上后,你的 agent 就能把内容发到这个浏览器。"}[t]})]}),t==="articles"&&e.jsxs("button",{className:"secondary-button",onClick:()=>void C().catch(s=>p(s.message)),children:[e.jsx(K,{size:14}),"刷新"]}),t==="accounts"&&e.jsxs("button",{className:"secondary-button",disabled:k,onClick:()=>$(!0),children:[e.jsx(K,{size:14,className:k?"spin":""}),"重新检查"]})]}),!_&&e.jsxs("div",{className:"empty-state",children:[e.jsx(W,{className:"spin",size:24}),e.jsx("p",{children:"正在加载…"})]}),_&&t==="articles"&&e.jsxs(e.Fragment,{children:[!(c!=null&&c.connected)&&e.jsxs("div",{className:"connection-banner",children:[e.jsx(G,{size:17}),e.jsx("span",{children:c!=null&&c.mcpFound?"发现本机的 WriteDock 服务,点一下就能连接。":"还没有连接到你的 agent。"}),e.jsx("button",{className:"link-button",onClick:()=>d("connection"),children:"去连接"})]}),l.length===0?e.jsxs("div",{className:"empty-state bordered",children:[e.jsx(U,{size:30}),e.jsx("h2",{children:"还没有稿件"}),e.jsx("p",{children:"告诉你的 agent 要写什么,内容会出现在这里。"})]}):e.jsx("div",{className:"article-list",children:l.map(s=>e.jsxs("article",{className:"article-row",children:[e.jsx(U,{size:19}),e.jsxs("div",{children:[e.jsx("h2",{children:M(s.title)}),e.jsx("p",{children:X(s.updatedAt)})]}),e.jsxs("button",{className:"secondary-button","aria-label":`预览稿件:${M(s.title)}`,onClick:()=>void ve(s.id).then(r=>r&&I(r)),children:[e.jsx(me,{size:14}),"预览"]}),e.jsx("button",{className:"icon-button","aria-label":`删除稿件:${M(s.title)}`,disabled:(o==null?void 0:o.status)==="syncing"&&o.draftId===s.id,onClick:()=>z(s),children:e.jsx(je,{size:15})})]},s.id))}),e.jsx("p",{className:"footnote",children:"稿件只保存在这台电脑上。"})]}),_&&t==="tasks"&&(V.length?e.jsx("div",{className:"task-list",children:V.map(ie)}):e.jsxs("div",{className:"empty-state bordered",children:[e.jsx(O,{size:30}),e.jsx("h2",{children:"还没有发布记录"}),e.jsx("p",{children:"让 agent 发布后,这里会显示每个平台的结果。"})]})),_&&t==="accounts"&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"section-summary",children:["已登录 ",re," / ",u.length," 个平台",e.jsx("span",{children:k?"正在检查…":""})]}),e.jsx("div",{className:"account-grid",children:u.map(s=>e.jsxs("section",{className:"account-card",children:[e.jsxs("div",{children:[e.jsx("h2",{children:s.name}),e.jsx("span",{className:s.isAuthenticated?"success-text":"",children:s.isAuthenticated?s.username||"已登录":k&&!s.checked?"检查中…":s.error?"暂时查不到":"未登录"})]}),e.jsx("div",{children:e.jsxs("button",{className:"secondary-button","aria-label":`打开${s.name}`,onClick:()=>{R.current=!0,H(s.homepage)},children:[s.isAuthenticated?"打开":"去登录",e.jsx(q,{size:12})]})})]},s.id))}),e.jsx("p",{className:"footnote",children:"登录后回到这里会自动更新。显示“暂时查不到”时,可以打开平台确认后点“重新检查”。"})]}),_&&t==="connection"&&c&&e.jsx(ge,{bridge:c,busy:w,syncing:(o==null?void 0:o.status)==="syncing",update:se,connect:te,updateExtension:ae,copy:ne})]}),L&&e.jsxs("div",{className:"toast",role:"status",children:[e.jsx(Z,{size:16}),e.jsx("span",{children:L}),e.jsx("button",{className:"icon-button","aria-label":"关闭提示",onClick:()=>p(""),children:e.jsx(J,{size:15})})]}),S&&e.jsx(Y,{title:"稿件预览",close:()=>I(null),wide:!0,children:e.jsxs("div",{className:"preview-content",children:[S.cover&&e.jsx("img",{className:"preview-cover",src:S.cover,alt:"文章封面"}),e.jsx("h1",{children:M(S.title)}),e.jsx("div",{className:"article-content",dangerouslySetInnerHTML:{__html:oe.sanitize(Te(S))}})]})}),F&&e.jsx(Y,{title:"删除这篇稿件?",close:()=>{w||z(null)},children:e.jsxs("div",{className:"modal-content",children:[e.jsx("p",{children:"只删除这台电脑上的稿件和记录,已发到平台的内容不受影响。"}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"secondary-button",disabled:w,onClick:()=>z(null),children:"保留稿件"}),e.jsx("button",{className:"danger-button",disabled:w,onClick:async()=>{b(!0);try{await Ne(F.id),z(null),await C()}catch(s){p(s instanceof Error?s.message:"删除失败")}finally{b(!1)}},children:w?"正在删除…":"删除稿件"})]})]})})]})}de(document.getElementById("root")).render(e.jsx(i.StrictMode,{children:e.jsx(_e,{})}));
|