@linkdesk/plugin-sdk 0.1.2 → 0.1.6

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/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /** CDP reload 端口默认 9222(与壳 dev electron:dev 尾部 --remote-debugging-port=9222 对齐);LINKDESK_CDP_PORT 覆盖 */
2
+ export declare const CDP_PORT: number;
3
+ /** 作者当前平台 LinkDesk userData/plugins 代码根(Electron 默认 userData = appData/<appName>,dev/打包同名 "linkdesk")。
4
+ * LINKDESK_USER_PLUGINS_DIR 环境变量可覆盖(自定义安装布局 / CI 隔离 userData 的逃生门)。 */
5
+ export declare function resolveUserPluginsDir(): string;
6
+ /**
7
+ * 经 CDP 刷新「LinkDesk Pool」窗口——renderer 重 import = 直写产物生效。返回是否找到并刷新成功。
8
+ *
9
+ * E6#28.5 真机自验实证(2026-09-07):单发 Page.reload 不足——`protocol.handle` 的 linkdesk:// 响应
10
+ * 无 Cache-Control 头 → Chromium 同 URL 二次请求命中缓存,index.bundle.js 陈旧副本永远被喂(直写磁盘
11
+ * 被遮蔽,protocol-debug.log 无新 200 行可证)。修复 = reload 前 Network.enable + Network.clearBrowserCache,
12
+ * 清掉缓存让 reload 后重 import 落到磁盘逐请求 readFileSync(纯 CDP,壳零代码)。
13
+ */
14
+ export declare function cdpReloadPool(port?: number): Promise<boolean>;
15
+ export interface RealLoopHooks {
16
+ /** 每次成功 build+直写后回调(默认 = CDP reload;测试/工具可注入) */
17
+ onInstalled?: (pluginId: string, targetDir: string) => Promise<void>;
18
+ }
19
+ /**
20
+ * 跑真机环并挂起进程(Ctrl+C → 关 watcher + 退出)。每次源码变更:debounce → 全量单插件 build →
21
+ * 直写 {userData}/plugins/<id> → CDP reload「LinkDesk Pool」。
22
+ */
23
+ export declare function runPluginDevReal(root: string): Promise<void>;
24
+ //# sourceMappingURL=dev-real.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-real.d.ts","sourceRoot":"","sources":["../src/dev-real.ts"],"names":[],"mappings":"AA4BA,wGAAwG;AACxG,eAAO,MAAM,QAAQ,QAAgD,CAAC;AAEtE;wEACwE;AACxE,wBAAgB,qBAAqB,IAAI,MAAM,CAY9C;AAyED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,IAAI,SAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAgCrE;AAeD,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgIlE"}
@@ -0,0 +1,286 @@
1
+ /**
2
+ * `linkdesk-plugin-sdk dev --real`——E6#28.5 第三方作者真机调试环(生产 LinkDesk 秒级环,壳零新代码)。
3
+ *
4
+ * 作者在自己的插件工程根跑 `dev --real`:
5
+ * 1. 复用 E6#25/#15 SDK 单插件 build(defineLinkdeskPluginConfig({ real: true }))——产物 = 完整物化目录
6
+ * dist/<id>.linkdesk-plugin/(plugin.json + index.bundle.js + views/*.bundle.js + index.bundle.css +
7
+ * assets/ + i18n/ + icon…),与 .linkdesk-plugin zip 解包布局一致(壳 loader 发现 = 目录含 plugin.json)。
8
+ * 2. 物化目录**直写** {userData}/plugins/<id>(平台标准 %APPDATA% 等;LINKDESK_USER_PLUGINS_DIR 覆盖)
9
+ * ——不经 plugins:extract「存在即拒」、不碰 E6#15n boot 门禁:直写磁盘 + reload = dev 覆盖语义
10
+ * (生产 linkdesk:// 逐请求 readFileSync;但 protocol.handle 响应无 Cache-Control → 会被 Chromium 缓存,
11
+ * reload 前须清缓存才落盘生效——机制实锤 + 修正见 04-作者真机调试环.md §二/§六)。
12
+ * 3. watch 作者源码 → 变更自动 重建→直写→reload。作者以 `--remote-debugging-port=9222` 启动 LinkDesk
13
+ * (Chromium 原生 switch,壳零代码)→ SDK 经 CDP Network.clearBrowserCache + Page.reload 刷「LinkDesk Pool」窗口
14
+ * (清缓存后 reload 重 import 落到磁盘逐请求 readFileSync = 真机生效);
15
+ * 9222 同时是 CDP/AI 全自动调试入口(沿用 dev-fixtures/toast.mjs 连法)。
16
+ *
17
+ * 边界(04 档案 §六):作用域 = 作者自研 dev 插件——目标目录若已有同 id 安装(市场装发布版)会被**覆盖且不备份**;
18
+ * 多插件工程并行 dev 需各自独立工程;CSS 等热更走整窗口 reload(秒级,非亚秒 HMR——那是 E6#28.7 B 的候选卖点)。
19
+ * 作者仍不碰壳源码/构建(插件独立铁律),不造第二壳。
20
+ */
21
+ import { copyFileSync, existsSync, mkdirSync, readdirSync, rmSync, watch } from "node:fs";
22
+ import { dirname, join, resolve } from "node:path";
23
+ import { homedir } from "node:os";
24
+ import { get as httpGet } from "node:http";
25
+ import { build } from "vite";
26
+ import { defineLinkdeskPluginConfig } from "./vite-config.js";
27
+ import { derivePluginId, readPluginManifest } from "./validate.js";
28
+ /** CDP reload 端口默认 9222(与壳 dev electron:dev 尾部 --remote-debugging-port=9222 对齐);LINKDESK_CDP_PORT 覆盖 */
29
+ export const CDP_PORT = Number(process.env.LINKDESK_CDP_PORT ?? 9222);
30
+ /** 作者当前平台 LinkDesk userData/plugins 代码根(Electron 默认 userData = appData/<appName>,dev/打包同名 "linkdesk")。
31
+ * LINKDESK_USER_PLUGINS_DIR 环境变量可覆盖(自定义安装布局 / CI 隔离 userData 的逃生门)。 */
32
+ export function resolveUserPluginsDir() {
33
+ const override = process.env.LINKDESK_USER_PLUGINS_DIR;
34
+ if (override && override.trim())
35
+ return resolve(override.trim());
36
+ const home = homedir();
37
+ switch (process.platform) {
38
+ case "win32":
39
+ return join(process.env.APPDATA ?? join(home, "AppData", "Roaming"), "linkdesk", "plugins");
40
+ case "darwin":
41
+ return join(home, "Library", "Application Support", "linkdesk", "plugins");
42
+ default:
43
+ return join(process.env.XDG_CONFIG_HOME ?? join(home, ".config"), "linkdesk", "plugins");
44
+ }
45
+ }
46
+ /** 平台判定代码根目录是否已存在(首启时可能还没有——提示作者先跑一次 LinkDesk,或给 LINKDESK_USER_PLUGINS_DIR) */
47
+ function userPluginsDirExists() {
48
+ return existsSync(resolveUserPluginsDir());
49
+ }
50
+ /* ── 物化目录直写 ─────────────────────────────────────────────── */
51
+ /** 覆盖式深拷贝(dev 覆盖语义——rm 目标后再拷,不残留本 build 已不产出的陈旧文件)。
52
+ * 插件私有数据在 <appData>/linkdesk/plugins/<id>/data(另一根),删代码根不碰数据。 */
53
+ function copyTreeOverwrite(srcDir, destDir) {
54
+ mkdirSync(destDir, { recursive: true });
55
+ for (const e of readdirSync(srcDir, { withFileTypes: true })) {
56
+ const s = join(srcDir, e.name);
57
+ const d = join(destDir, e.name);
58
+ if (e.isDirectory())
59
+ copyTreeOverwrite(s, d);
60
+ else
61
+ copyFileSync(s, d);
62
+ }
63
+ }
64
+ /** 本 build 是否有可装产物——主入口 index.bundle.js 或任一 views/<X>.bundle.js(entry 缺失的纯 views 插件形态) */
65
+ function hasBuildOutput(pkgDir) {
66
+ if (existsSync(join(pkgDir, "index.bundle.js")))
67
+ return true;
68
+ const views = join(pkgDir, "views");
69
+ if (existsSync(views)) {
70
+ try {
71
+ return readdirSync(views).some((f) => f.endsWith(".bundle.js"));
72
+ }
73
+ catch {
74
+ return false;
75
+ }
76
+ }
77
+ return false;
78
+ }
79
+ /** GET http://127.0.0.1:<port>/json/list——node:http,避免依赖全局 fetch 类型 */
80
+ function cdpListTargets(port) {
81
+ return new Promise((resolveP, rejectP) => {
82
+ const req = httpGet({ host: "127.0.0.1", port, path: "/json/list", timeout: 1500 }, (res) => {
83
+ const chunks = [];
84
+ res.on("data", (c) => chunks.push(c));
85
+ res.on("end", () => {
86
+ try {
87
+ resolveP(JSON.parse(Buffer.concat(chunks).toString("utf8")));
88
+ }
89
+ catch (e) {
90
+ rejectP(e instanceof Error ? e : new Error(String(e)));
91
+ }
92
+ });
93
+ });
94
+ req.on("error", rejectP);
95
+ req.on("timeout", () => {
96
+ req.destroy(new Error("CDP /json/list 超时"));
97
+ });
98
+ });
99
+ }
100
+ /**
101
+ * 经 CDP 刷新「LinkDesk Pool」窗口——renderer 重 import = 直写产物生效。返回是否找到并刷新成功。
102
+ *
103
+ * E6#28.5 真机自验实证(2026-09-07):单发 Page.reload 不足——`protocol.handle` 的 linkdesk:// 响应
104
+ * 无 Cache-Control 头 → Chromium 同 URL 二次请求命中缓存,index.bundle.js 陈旧副本永远被喂(直写磁盘
105
+ * 被遮蔽,protocol-debug.log 无新 200 行可证)。修复 = reload 前 Network.enable + Network.clearBrowserCache,
106
+ * 清掉缓存让 reload 后重 import 落到磁盘逐请求 readFileSync(纯 CDP,壳零代码)。
107
+ */
108
+ export async function cdpReloadPool(port = CDP_PORT) {
109
+ let targets;
110
+ try {
111
+ targets = await cdpListTargets(port);
112
+ }
113
+ catch {
114
+ return false;
115
+ }
116
+ const pool = targets.find((t) => t.title === "LinkDesk Pool");
117
+ const url = pool?.webSocketDebuggerUrl;
118
+ if (!pool || !url)
119
+ return false;
120
+ const Ws = globalThis.WebSocket;
121
+ if (!Ws) {
122
+ return false; // 全局 WebSocket 不可用(Node 太旧)——视为找不到,调用方打指引
123
+ }
124
+ const ws = new Ws(url);
125
+ await new Promise((res, rej) => {
126
+ ws.onopen = () => res();
127
+ ws.onerror = () => rej(new Error("CDP WebSocket 连接失败"));
128
+ });
129
+ // 顺序发:enable → clearBrowserCache → reload;等 reload(id 3)的回复即代表前两步已完成。
130
+ const reply = new Promise((res) => {
131
+ ws.onmessage = (ev) => {
132
+ const m = JSON.parse(String(ev.data));
133
+ if (m.id === 3)
134
+ res(m);
135
+ };
136
+ });
137
+ ws.send(JSON.stringify({ id: 1, method: "Network.enable" }));
138
+ ws.send(JSON.stringify({ id: 2, method: "Network.clearBrowserCache" }));
139
+ ws.send(JSON.stringify({ id: 3, method: "Page.reload", params: { ignoreCache: true } }));
140
+ await reply;
141
+ ws.close();
142
+ return true;
143
+ }
144
+ /* ── watch → 重建 → 直写 → reload 循环 ─────────────────────────────── */
145
+ /** 该路径是否不该触发重建(build 输出/依赖/元目录)——任一目录段命中即忽略 */
146
+ function isIgnoredRel(abs, root) {
147
+ const rel = abs.slice(root.length).split(/[\\/]/).filter(Boolean);
148
+ for (const seg of rel) {
149
+ if (seg === "node_modules" || seg === ".git" || seg === "dist" || seg === ".linkdesk-real")
150
+ return true;
151
+ }
152
+ // 插件分发 zip(真实态不写,防御历史遗留触发重建)
153
+ if (abs.endsWith(".linkdesk-plugin"))
154
+ return true;
155
+ return false;
156
+ }
157
+ /**
158
+ * 跑真机环并挂起进程(Ctrl+C → 关 watcher + 退出)。每次源码变更:debounce → 全量单插件 build →
159
+ * 直写 {userData}/plugins/<id> → CDP reload「LinkDesk Pool」。
160
+ */
161
+ export async function runPluginDevReal(root) {
162
+ const pluginJson = join(root, "plugin.json");
163
+ if (!existsSync(pluginJson)) {
164
+ throw new Error(`当前目录不是插件工程——找不到 ${pluginJson}。请 cd 进插件项目根再跑 linkdesk-plugin-sdk dev --real`);
165
+ }
166
+ const manifest = readPluginManifest(pluginJson);
167
+ const pluginId = derivePluginId(manifest, dirname(pluginJson).split(/[\\/]/).pop() ?? "plugin");
168
+ const pluginsRoot = resolveUserPluginsDir();
169
+ const targetDir = join(pluginsRoot, pluginId);
170
+ const pkgDir = join(root, "dist", `${pluginId}.linkdesk-plugin`); // defineLinkdeskPluginConfig 默认 outDir="dist"
171
+ // 纯 manifest 无任何 js 表面(无 entry、无 contributes.views[].render)→ 无物化产物可直写,真机环无意义
172
+ const entry = manifest?.entry;
173
+ const contributes = manifest
174
+ ?.contributes;
175
+ const views = contributes?.views ?? {};
176
+ const hasView = Object.values(views).some((arr) => Array.isArray(arr) && arr.some((vd) => typeof vd?.render === "string"));
177
+ if (typeof entry !== "string" && !hasView) {
178
+ throw new Error(`「${pluginId}」无 js 表面(无 entry、无 contributes.views[].render)——dev --real 为代码迭代环,纯 manifest 插件无需直写。`);
179
+ }
180
+ console.log("");
181
+ console.log(` LinkDesk 真机环(E6#28.5)→ 插件「${pluginId}」`);
182
+ console.log(` 直写目标:${targetDir}`);
183
+ console.log(` ${userPluginsDirExists() ? "✓ 定位到运行中 LinkDesk 的插件目录" : "⚠ userData/plugins 尚不存在——先启动一次 LinkDesk(首次运行会建目录)"}`);
184
+ console.log(` 覆盖语义:目标已存在同名安装 → 被 dev 直写覆盖且不备份(作用域 = 自研 dev 插件)`);
185
+ console.log(` reload:需 LinkDesk 以 --remote-debugging-port=${CDP_PORT} 启动(CDP 连不上会跳过,改码后自动重试)`);
186
+ console.log(` 改码 → 自动 build → 直写 → reload;Ctrl+C 停止`);
187
+ console.log("");
188
+ let stopped = false;
189
+ const watchers = new Set();
190
+ let building = false;
191
+ let dirty = false;
192
+ let reloadWarned = false;
193
+ /** 单次完整 cycle:build → 有产物才直写 → 通知(默认 CDP reload) */
194
+ async function cycle(why) {
195
+ console.log(`[${new Date().toLocaleTimeString()}] ${why}`);
196
+ try {
197
+ await build(defineLinkdeskPluginConfig({ real: true }));
198
+ }
199
+ catch (e) {
200
+ // plugin.json 正在编辑/表面编译失败 → 保留旧产物继续监听(失败不阻断循环)
201
+ console.error(` ✗ build 失败(保持既有直写产物):${e instanceof Error ? e.message : String(e)}`);
202
+ return;
203
+ }
204
+ if (!hasBuildOutput(pkgDir)) {
205
+ console.error(` ✗ build 无产物(${pkgDir})——跳过直写`);
206
+ return;
207
+ }
208
+ rmSync(targetDir, { recursive: true, force: true });
209
+ copyTreeOverwrite(pkgDir, targetDir);
210
+ console.log(` ✓ 直写 ${targetDir}`);
211
+ const reloaded = await cdpReloadPool(CDP_PORT);
212
+ if (reloaded) {
213
+ console.log(` ✓ LinkDesk Pool 已刷新(CDP ${CDP_PORT})`);
214
+ }
215
+ else if (!reloadWarned) {
216
+ reloadWarned = true;
217
+ console.log(` ⚠ 未连上 CDP ${CDP_PORT}——LinkDesk 没开?或启动时加 --remote-debugging-port=${CDP_PORT}。` +
218
+ `(dev electron:dev 已内置;安装版/win-unpacked 手动加同参数)后续改码会自动重试。`);
219
+ }
220
+ }
221
+ /** debounce + 串行化(build 进行中再变更 → 记 dirty,结束后补一轮) */
222
+ let timer;
223
+ const schedule = (why) => {
224
+ if (stopped)
225
+ return;
226
+ if (timer)
227
+ clearTimeout(timer);
228
+ timer = setTimeout(() => {
229
+ timer = undefined;
230
+ void (async () => {
231
+ if (building) {
232
+ dirty = true;
233
+ return;
234
+ }
235
+ building = true;
236
+ try {
237
+ await cycle(why);
238
+ if (dirty) {
239
+ dirty = false;
240
+ await cycle("变更累积,补一轮");
241
+ }
242
+ }
243
+ finally {
244
+ building = false;
245
+ }
246
+ })();
247
+ }, 200);
248
+ };
249
+ // 首轮:初始 build → 直写 → reload(不依赖文件事件)
250
+ schedule("初始 build → 直写 → reload");
251
+ if (stopped)
252
+ return;
253
+ // 源码 watch(root 递归;node_modules/.git/dist 等事件按路径忽略——不触发自激重建)
254
+ try {
255
+ const w = watch(root, { recursive: true }, (_event, filename) => {
256
+ const abs = filename ? resolve(root, String(filename)) : root;
257
+ if (isIgnoredRel(abs, root))
258
+ return;
259
+ schedule(`文件变更 → 重建(${String(filename)})`);
260
+ });
261
+ watchers.add(w);
262
+ }
263
+ catch {
264
+ // recursive watch 不可用(罕见平台/权限)→ 降级不 watch(作者改码后手动 Ctrl+C 重启),不阻断已装产物
265
+ console.error(" ⚠ 递归文件监听不可用——dev --real 降级为一次性 build 直写;改码后重启本命令生效");
266
+ }
267
+ await new Promise((stop) => {
268
+ const shutdown = () => {
269
+ stopped = true;
270
+ if (timer)
271
+ clearTimeout(timer);
272
+ for (const w of watchers) {
273
+ try {
274
+ w.close();
275
+ }
276
+ catch {
277
+ // 忽略关闭失败
278
+ }
279
+ }
280
+ stop();
281
+ };
282
+ process.once("SIGINT", shutdown);
283
+ process.once("SIGTERM", shutdown);
284
+ });
285
+ }
286
+ //# sourceMappingURL=dev-real.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-real.js","sourceRoot":"","sources":["../src/dev-real.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare const DEV_PORT: number;
2
+ /** dev 宿主目录(SDK 包根 dev-host/,与 dist 平级)——供 bin/测试定位 */
3
+ export declare function devHostDir(): string;
4
+ /**
5
+ * 起 dev 宿主并挂起进程(Ctrl+C → server.close)。
6
+ * 设计要点:define 把 i18n resources + pluginId 作为「字面量表达式」注入宿主——
7
+ * 宿主 import 一个对象不是 URL,避免每插件一条虚拟模块路径维护。
8
+ */
9
+ export declare function runPluginDev(root: string): Promise<void>;
10
+ //# sourceMappingURL=dev-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../src/dev-server.ts"],"names":[],"mappings":"AAgCA,eAAO,MAAM,QAAQ,QAAgD,CAAC;AAEtE,uDAAuD;AACvD,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAgED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2C9D"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * `linkdesk-plugin-sdk dev`——E6#23.5/#24:SDK 自带独立宿主页,在作者自己的 Vite dev server 下
3
+ * 加载正在开发的插件源码 + HMR。纯浏览器预览,无 Electron、无 IPC。
4
+ *
5
+ * 形态(第 2.2 轮审视拍板,见 02-本地预览环境.md §九/§十;本模块 = 实装决策记录):
6
+ * - **宿主 = SDK 自带 dev-host/**(index.html + dev-main.tsx + mock.ts),随包 raw 资产,
7
+ * vite dev 现役转换 tsx——不预编译(precompile 到 js 会杀掉 HMR 所需的源码模块态)。
8
+ * - **root = dev-host 目录**;插件入口经 `resolve.alias` 把虚拟 id `__linkdesk_dev_entry__`
9
+ * 映射到插件根 plugin.json 声明的 entry **绝对路径** → 入口成为模块图常规成员 + 静态 import
10
+ * → HMR 走 vite 标准全链。比「浏览器端运行时 import('/@fs/…')」更稳——计算型动态 import 不在
11
+ * 静态图,HMR 会退化成整页刷新(`/@fs/` 语义由 alias 到绝对路径达成:vite 对 alias 解析出的
12
+ * 绝对路径文件同样按需转换 + 注入 HMR,等效于 /@fs/ 加载)。
13
+ * - **fs.allow 放行插件根**——root 在 node_modules 内(SDK 随装),vite 默认 allow 不含作者工程。
14
+ * - **react/react-dom/react-i18next/i18next = SDK dependencies**(非 devDep):dev 宿主渲染插件
15
+ * 需要它们;构建面仍 external 不打进 .linkdesk-plugin。作者零配置(npm i SDK 即达)。
16
+ * - **mock**:#23.5c 锚点 = dev-host/mock.ts 的 throw-on-call Proxy(未 mock 的 API 调用抛
17
+ * 「仅生产可用」而非静默 undefined,防 dev 正常/装机炸的反向落差)。真方法默认值表归 E6#27
18
+ * (generate-contract 第二输出目标,2.3 轮)——届时替换 mock.ts 注入体,锚点(injectDevMockApi)
19
+ * 不变。
20
+ *
21
+ * 端口 1421(对齐设计稿,避开壳 dev 1420)。`LINKDESK_DEV_PORT` 环境变量可覆盖(CI/占用冲突逃生门)。
22
+ */
23
+ import { existsSync, readFileSync } from "node:fs";
24
+ import { basename, dirname, join, resolve } from "node:path";
25
+ import { fileURLToPath } from "node:url";
26
+ import { spawn } from "node:child_process";
27
+ import { createServer } from "vite";
28
+ import react from "@vitejs/plugin-react";
29
+ import { collectI18nDecls, derivePluginId, readPluginManifest } from "./validate.js";
30
+ const DEV_HOST_DIR = join(dirname(fileURLToPath(import.meta.url)), "../dev-host");
31
+ export const DEV_PORT = Number(process.env.LINKDESK_DEV_PORT ?? 1421);
32
+ /** dev 宿主目录(SDK 包根 dev-host/,与 dist 平级)——供 bin/测试定位 */
33
+ export function devHostDir() {
34
+ return DEV_HOST_DIR;
35
+ }
36
+ /** 从插件根读 plugin.json → 定位 dev 目标(entry 必须存在——dev 宿主当前支持「entry 视图插件」形态) */
37
+ function loadPluginContext(root) {
38
+ const manifestPath = join(root, "plugin.json");
39
+ if (!existsSync(manifestPath)) {
40
+ throw new Error(`当前目录不是插件工程——找不到 ${manifestPath}。请 cd 进插件项目根再跑 linkdesk-plugin-sdk dev`);
41
+ }
42
+ const manifest = readPluginManifest(manifestPath);
43
+ const pluginId = derivePluginId(manifest, basename(root));
44
+ const entry = manifest?.entry;
45
+ if (typeof entry !== "string" || !entry.trim()) {
46
+ throw new Error(`「${pluginId}」plugin.json 缺 entry——dev 宿主当前支持带 entry 的视图插件(脚手架 tab 形态:` +
47
+ `src/index.tsx default 导出组件)。纯 contributes 分区视图插件的壳侧 dev 见 E6#28(02-本地预览环境.md §10.3)`);
48
+ }
49
+ const entryAbs = resolve(root, entry);
50
+ if (!existsSync(entryAbs)) {
51
+ throw new Error(`「${pluginId}」entry "${entry}" 不存在:${entryAbs}`);
52
+ }
53
+ // i18n resources——与 validate 同一读取面(collectI18nDecls),语言码 = 文件名去 .json
54
+ const resources = {};
55
+ for (const decl of collectI18nDecls(manifest)) {
56
+ const p = resolve(root, decl.rel);
57
+ if (!existsSync(p))
58
+ continue;
59
+ const lang = basename(decl.rel, ".json");
60
+ try {
61
+ resources[lang] = { translation: JSON.parse(readFileSync(p, "utf8")) };
62
+ }
63
+ catch {
64
+ // 单语言文件坏 → 跳过该语言(宿主仍起,validate 会报真错)——dev 不阻断
65
+ }
66
+ }
67
+ return { pluginId, entryAbs, resources };
68
+ }
69
+ /** 平台开浏览器(Vite 默认依赖 open 包,SDK 不想为此加 dep——3 行 spawn 足矣) */
70
+ function openBrowser(url) {
71
+ let cmd;
72
+ let args;
73
+ if (process.platform === "win32") {
74
+ cmd = "cmd";
75
+ args = ["/c", "start", "", url];
76
+ }
77
+ else if (process.platform === "darwin") {
78
+ cmd = "open";
79
+ args = [url];
80
+ }
81
+ else {
82
+ cmd = "xdg-open";
83
+ args = [url];
84
+ }
85
+ try {
86
+ spawn(cmd, args, { stdio: "ignore", detached: true }).unref();
87
+ }
88
+ catch {
89
+ // 开不了(无 GUI/沙箱)→ 用户手抄 URL,不阻断
90
+ }
91
+ }
92
+ /**
93
+ * 起 dev 宿主并挂起进程(Ctrl+C → server.close)。
94
+ * 设计要点:define 把 i18n resources + pluginId 作为「字面量表达式」注入宿主——
95
+ * 宿主 import 一个对象不是 URL,避免每插件一条虚拟模块路径维护。
96
+ */
97
+ export async function runPluginDev(root) {
98
+ const { pluginId, entryAbs, resources } = loadPluginContext(root);
99
+ const hostHtml = join(DEV_HOST_DIR, "index.html");
100
+ if (!existsSync(hostHtml)) {
101
+ throw new Error(`dev 宿主缺失:${hostHtml}——SDK 包损坏或安装不全?`);
102
+ }
103
+ const server = await createServer({
104
+ root: DEV_HOST_DIR,
105
+ server: {
106
+ port: DEV_PORT,
107
+ strictPort: true,
108
+ fs: { allow: [DEV_HOST_DIR, root] },
109
+ },
110
+ resolve: {
111
+ alias: [{ find: /^__linkdesk_dev_entry__$/, replacement: entryAbs }],
112
+ },
113
+ define: {
114
+ __LINKDESK_DEV_I18N__: JSON.stringify(resources),
115
+ __LINKDESK_DEV_PLUGIN_ID__: JSON.stringify(pluginId),
116
+ },
117
+ plugins: [react()],
118
+ });
119
+ await server.listen();
120
+ const url = `http://localhost:${DEV_PORT}/?pluginId=${encodeURIComponent(pluginId)}`;
121
+ // 宿主已起:URL 打印(Git Bash / CI 也看得到)+ 尽力开浏览器(开不了不阻断)
122
+ console.log("");
123
+ console.log(` LinkDesk dev 宿主 → ${url}`);
124
+ console.log(` 预览插件「${pluginId}」——改 src/ 下源码即 HMR;Ctrl+C 停止`);
125
+ console.log("");
126
+ openBrowser(url);
127
+ // 挂起直到 Ctrl+C——main() 的 process.exit 在 runPluginDev resolve 后才跑
128
+ await new Promise((stop) => {
129
+ const shutdown = () => {
130
+ server.close().then(stop).catch(stop);
131
+ };
132
+ process.once("SIGINT", shutdown);
133
+ process.once("SIGTERM", shutdown);
134
+ });
135
+ }
136
+ //# sourceMappingURL=dev-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-server.js","sourceRoot":"","sources":["../src/dev-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface GhHttpOptions {
2
+ /** classic PAT(repo scope)或 fine-grained token——调用方从 env/配置档/token 链路取 */
3
+ token: string;
4
+ method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
5
+ /** 目标主机:api = api.github.com(REST 面);uploads = uploads.github.com(asset 上传面) */
6
+ api: "api" | "uploads";
7
+ /** 路径,以 / 开头,如 "/repos/encaron/demo/releases" */
8
+ path: string;
9
+ /** 追加到 path 的原始 query 串(含 ? 或纯参数字符串,按原样拼) */
10
+ query?: string;
11
+ /** 附加 header(Content-Type 等);Authorization/User-Agent/Accept 由本模块统一注入 */
12
+ headers?: Record<string, string>;
13
+ /** 请求体:string = 自动置 Content-Type application/json;Buffer = 调用方自给 Content-Type */
14
+ body?: string | Buffer;
15
+ }
16
+ export interface GhHttpResult {
17
+ status: number;
18
+ ok: boolean;
19
+ text: string;
20
+ /** JSON.parse 成功则为解析值;非 JSON / 空体为 null */
21
+ json: unknown;
22
+ }
23
+ /**
24
+ * 单次 GitHub REST 请求。2xx 不抛(返回 ok:true);网络/超时抛错。
25
+ * 4xx/5xx 返回 ok:false + text/json 供调用方诊断(GitHub 错误体含 message 字段)。
26
+ */
27
+ export declare function ghHttp(opts: GhHttpOptions): Promise<GhHttpResult>;
28
+ /** 读错误体中文诊断——GitHub 标准错误体 { message, documentation_url, ... } */
29
+ export declare function ghErrorDetail(res: GhHttpResult): string;
30
+ //# sourceMappingURL=github-http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-http.d.ts","sourceRoot":"","sources":["../src/github-http.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,gFAAgF;IAChF,GAAG,EAAE,KAAK,GAAG,SAAS,CAAC;IACvB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,IAAI,EAAE,OAAO,CAAC;CACf;AAWD;;;GAGG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAgDvE;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAMvD"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * 极简 GitHub REST 客户端(E6#26b 自动发布链路底座)——`api.github.com` + `uploads.github.com`。
3
+ *
4
+ * 用 `node:https` 而非全局 fetch:SDK tsconfig `types: []` + `lib: ["ES2022"]` 无 dom/undici 类型,
5
+ * 全局 fetch 不可类型化——与 dev-real.ts 对 CDP 的处理同一取舍(dev-real.ts:99 注记)。Node >= 20
6
+ * 运行时无额外依赖。发布只走 REST:Repo 信息 / Releases(建 + 传 asset)/ Contents(读改 marketplace.json)。
7
+ *
8
+ * 失败语义:网络/超时 → throw;HTTP 非 2xx → 不抛,返回 { status, ok:false } 由调用方给中文诊断
9
+ * (401 token / 404 不存在 / 422 已存在等各自语义不同)。
10
+ */
11
+ import { request as httpsRequest } from "node:https";
12
+ const GITHUB_API_HOST = "api.github.com";
13
+ const GITHUB_UPLOAD_HOST = "uploads.github.com";
14
+ const USER_AGENT = "linkdesk-plugin-sdk";
15
+ const REQUEST_TIMEOUT_MS = 30_000;
16
+ function collectBody(res) {
17
+ return new Promise((resolve, reject) => {
18
+ const chunks = [];
19
+ res.on("data", (c) => chunks.push(c));
20
+ res.on("error", reject);
21
+ res.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
22
+ });
23
+ }
24
+ /**
25
+ * 单次 GitHub REST 请求。2xx 不抛(返回 ok:true);网络/超时抛错。
26
+ * 4xx/5xx 返回 ok:false + text/json 供调用方诊断(GitHub 错误体含 message 字段)。
27
+ */
28
+ export async function ghHttp(opts) {
29
+ const host = opts.api === "uploads" ? GITHUB_UPLOAD_HOST : GITHUB_API_HOST;
30
+ const headers = {
31
+ "User-Agent": USER_AGENT,
32
+ Accept: "application/vnd.github+json",
33
+ Authorization: `Bearer ${opts.token}`,
34
+ ...opts.headers,
35
+ };
36
+ if (typeof opts.body === "string" && !headers["Content-Type"]) {
37
+ headers["Content-Type"] = "application/json";
38
+ }
39
+ if (Buffer.isBuffer(opts.body) && !headers["Content-Length"]) {
40
+ headers["Content-Length"] = String(opts.body.length);
41
+ }
42
+ const query = opts.query ? (opts.query.startsWith("?") ? opts.query : `?${opts.query}`) : "";
43
+ return new Promise((resolve, reject) => {
44
+ const req = httpsRequest({
45
+ host,
46
+ path: `${opts.path}${query}`,
47
+ method: opts.method ?? "GET",
48
+ headers,
49
+ }, (res) => {
50
+ void (async () => {
51
+ try {
52
+ const text = await collectBody(res);
53
+ let json = null;
54
+ if (text.length > 0) {
55
+ try {
56
+ json = JSON.parse(text);
57
+ }
58
+ catch {
59
+ json = null; // 非 JSON(罕见),保持 text 可取
60
+ }
61
+ }
62
+ resolve({ status: res.statusCode ?? 0, ok: (res.statusCode ?? 0) >= 200 && (res.statusCode ?? 0) < 300, text, json });
63
+ }
64
+ catch (e) {
65
+ reject(e instanceof Error ? e : new Error(String(e)));
66
+ }
67
+ })();
68
+ });
69
+ req.on("error", (e) => reject(new Error(`GitHub 网络请求失败(${host}):${e.message}`)));
70
+ req.setTimeout(REQUEST_TIMEOUT_MS, () => req.destroy(new Error(`GitHub 请求超时(${REQUEST_TIMEOUT_MS}ms)`)));
71
+ if (opts.body)
72
+ req.write(opts.body);
73
+ req.end();
74
+ });
75
+ }
76
+ /** 读错误体中文诊断——GitHub 标准错误体 { message, documentation_url, ... } */
77
+ export function ghErrorDetail(res) {
78
+ if (res.json && typeof res.json === "object") {
79
+ const msg = res.json.message;
80
+ if (typeof msg === "string")
81
+ return msg;
82
+ }
83
+ return res.text.slice(0, 300);
84
+ }
85
+ //# sourceMappingURL=github-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-http.js","sourceRoot":"","sources":["../src/github-http.ts"],"names":[],"mappings":"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"}