dsh-plugin-capabilities 0.3.5 → 0.3.7
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 +1 -1
- package/lib/index.js +9 -0
- package/lib/index.js.map +2 -2
- package/package.json +2 -2
- package/src/mcp.test.ts +17 -1
- package/src/mcp.ts +18 -0
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|

|
|
27
27
|
|
|
28
|
-
「MCP」页管理 profile patch 中的 MCP 服务器行,每行对应一个 `@deepseek-ai/dsh-mcp-client` 实例。stdio 服务器填写命令与参数,streamable-http 服务器填写 URL,编辑、停用、移除都在页面上完成。YAML 读写采用文档级 API,文件中的其他行与注释不受影响。新行写在一个 `- insert:` 块里——加载器只会挂载 insert 形式的行,裸的 `- id:` 条目是对已有行的覆盖,目标不存在时会被跳过;0.1.3 之前写入的裸行会在下一次保存时自动迁入 insert 块。
|
|
28
|
+
「MCP」页管理 profile patch 中的 MCP 服务器行,每行对应一个 `@deepseek-ai/dsh-mcp-client` 实例。stdio 服务器填写命令与参数,streamable-http 服务器填写 URL,编辑、停用、移除都在页面上完成。YAML 读写采用文档级 API,文件中的其他行与注释不受影响。新行写在一个 `- insert:` 块里——加载器只会挂载 insert 形式的行,裸的 `- id:` 条目是对已有行的覆盖,目标不存在时会被跳过;0.1.3 之前写入的裸行会在下一次保存时自动迁入 insert 块。0.3.7 起,若 `cordis.patch.yml` 本身存在语法错误(多见于手工编辑失误),页面会直接报出文件完整路径与出错行列,并且不写入任何内容;此前这种文件会在保存时抛出内部的 "Document with errors cannot be stringified",让人无从下手。
|
|
29
29
|
|
|
30
30
|
添加或编辑服务器时,表单下方有「完整格式与快速填充」区:一边是随表单实时更新的完整 YAML 行(和保存后落进 `cordis.patch.yml` 的一模一样),另一边是等价的 `mcpServers` JSON 写法,可以直接抄去别的工具。反过来也行——把 Claude Code 配置、官方文档或任意 JSON 粘进输入框,点「解析并填充」,服务器名、命令、参数、环境变量、URL、请求头都会自动填好,`{"mcpServers": {...}}` 包装、裸条目、dsh 行三种形状都认。
|
|
31
31
|
|
package/lib/index.js
CHANGED
|
@@ -1429,10 +1429,19 @@ import { join as join9 } from "node:path";
|
|
|
1429
1429
|
import { parseDocument, Document } from "yaml";
|
|
1430
1430
|
var MCP_PLUGIN = "@deepseek-ai/dsh-mcp-client";
|
|
1431
1431
|
var SERVER_NAME_RE = /^[A-Za-z0-9_-]{1,32}$/;
|
|
1432
|
+
function assertPatchParses(path, doc) {
|
|
1433
|
+
if (doc.errors.length === 0) return;
|
|
1434
|
+
const at = String(doc.errors[0].message).split("\n", 1)[0];
|
|
1435
|
+
const total = doc.errors.length > 1 ? `, +${doc.errors.length - 1} more` : "";
|
|
1436
|
+
throw new Error(
|
|
1437
|
+
`\u914D\u7F6E\u6587\u4EF6 ${path} \u5B58\u5728 YAML \u8BED\u6CD5\u9519\u8BEF\uFF08${at}${total}\uFF09\uFF0C\u672A\u5199\u5165\u4EFB\u4F55\u5185\u5BB9\uFF0C\u8BF7\u4FEE\u590D\u8BE5\u6587\u4EF6\u540E\u91CD\u8BD5 / YAML syntax error in the patch file (${at}${total}); nothing was written \u2014 fix it and retry`
|
|
1438
|
+
);
|
|
1439
|
+
}
|
|
1432
1440
|
function loadPatch(profileDirPath) {
|
|
1433
1441
|
const path = join9(profileDirPath, "cordis.patch.yml");
|
|
1434
1442
|
const text = existsSync6(path) ? readFileSync6(path, "utf8") : "[]";
|
|
1435
1443
|
const doc = parseDocument(text);
|
|
1444
|
+
assertPatchParses(path, doc);
|
|
1436
1445
|
const contents = doc.contents;
|
|
1437
1446
|
if (contents !== null && contents.flow === true && contents.items.length === 0) contents.flow = false;
|
|
1438
1447
|
return doc;
|
package/lib/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/agents.ts", "../node_modules/.pnpm/smol-toml@1.8.0/node_modules/smol-toml/dist/date.js", "../node_modules/.pnpm/smol-toml@1.8.0/node_modules/smol-toml/dist/error.js", "../node_modules/.pnpm/smol-toml@1.8.0/node_modules/smol-toml/dist/util.js", "../node_modules/.pnpm/smol-toml@1.8.0/node_modules/smol-toml/dist/primitive.js", "../node_modules/.pnpm/smol-toml@1.8.0/node_modules/smol-toml/dist/extract.js", "../node_modules/.pnpm/smol-toml@1.8.0/node_modules/smol-toml/dist/struct.js", "../node_modules/.pnpm/smol-toml@1.8.0/node_modules/smol-toml/dist/parse.js", "../src/profile.ts", "../src/routes.ts", "../src/http.ts", "../src/market.ts", "../src/opener.ts", "../src/repos.ts", "../src/rmtree.ts", "../src/state.ts", "../src/tar.ts", "../src/restart.ts", "../src/skills.ts", "../src/mcp.ts"],
|
|
4
|
-
"sourcesContent": ["/** dsh-plugin-capabilities host entry: mount the manager's HTTP routes once\n * the profile composes both the web server and the skill registry, and mount\n * a host-plane filesystem skill provider so the Settings page sees a live\n * catalog (the web composition deliberately leaves the host row to presets).\n * The provider's custom roots also take the user-registered skill\n * repositories from the plugin state file, and remount whenever those\n * change \u2014 the catalog follows without a dsh restart. */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport { existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { agentSkillRoots } from './agents.ts'\nimport { argvProfile, profileDir } from './profile.ts'\nimport { mountCapabilitiesRoutes } from './routes.ts'\nimport { loadState } from './state.ts'\nimport type { CapabilitiesHost } from './types.ts'\n\nexport const name = 'dsh-plugin-capabilities'\n\n/**\n * The package's own vendored skills (`skills/` at the package root \u2014 resolves\n * identically from src/ under vitest and from lib/ when installed). Scanned as\n * a custom root, so every session sees them through the registry's global\n * layer while the files stay zero-copy and travel with plugin installs.\n */\nexport function packagedSkillsDir(): string {\n return join(dirname(fileURLToPath(import.meta.url)), '..', 'skills')\n}\n\n/** Optional cordis.yml configuration; profile defaults to the booted one. */\nexport interface Config {\n /** Profile whose patch layer holds the MCP rows; defaults to argv or `web`. */\n profile?: string\n}\n\nexport const inject = ['webServer', 'skills']\n\n/** The provider plugin's structural shape (name/apply export). */\ninterface FilesystemSkillPlugin {\n name: string\n apply(context: Context, config?: unknown): void\n}\n\n/** The disposable fiber `ctx.plugin()` returns, as far as we use it. */\ninterface PluginFiber {\n dispose(): Promise<void>\n}\n\nexport function apply(ctx: Context, config?: Config): void {\n const profile = config?.profile ?? argvProfile() ?? 'web'\n ctx.inject(['webServer', 'skills'], (hostCtx: Context) => {\n // The web bundle disables the host-plane `skill-filesystem` row on\n // purpose (presets own per-session discovery). The Settings manager\n // mounts its own host-plane provider as a CHILD of this plugin: it dies\n // with us, registers into the registry's global layer (deployment-level\n // providers are exactly what that layer is for \u2014 agents read the merged\n // catalog), and preset layers keep their semantics (nearest layer still\n // wins duplicate names). Custom roots, in scan order: the package's own\n // vendored skills (read-only, update with the plugin), the user's\n // registered repositories (local paths and GitHub checkouts, managed\n // from the Settings page), then other agents' skill roots\n // (~/.claude/skills, ~/.codex/skills) \u2014 zero-copy, live-synced both\n // ways. Registering or removing a repository remounts the provider with\n // the new root set; a failed load only means an empty catalog \u2014 the\n // routes keep serving.\n let providerFiber: PluginFiber | undefined\n let disposed = false\n ctx.effect(() => {\n const disposer = (): void => { disposed = true }\n let chain: Promise<void> = Promise.resolve()\n const remountProvider = (): Promise<void> => {\n // Serialize remounts; concurrent add/remove requests must not\n // interleave dispose and re-plugin on the same provider.\n chain = chain.then(async () => {\n if (disposed) return\n const mod = (await import('@deepseek-ai/dsh-skill-filesystem')) as unknown as\n (FilesystemSkillPlugin & { default?: FilesystemSkillPlugin })\n const plugin = mod.default ?? mod\n if (providerFiber !== undefined) {\n const old = providerFiber\n providerFiber = undefined\n try { await old.dispose() } catch { /* unloading raced us */ }\n }\n if (disposed) return\n const roots = [\n packagedSkillsDir(),\n ...loadState().skillRoots.flatMap(entry => entry.roots),\n ...agentSkillRoots(),\n ].filter(dir => existsSync(dir))\n try {\n providerFiber = hostCtx.plugin(plugin, roots.length > 0 ? { customSkillDirs: roots } : {}) as PluginFiber\n } catch {\n // Context already disposed: nothing left to mount for.\n }\n })\n chain = chain.catch(() => undefined)\n return chain\n }\n void remountProvider()\n\n ctx.effect(\n () => mountCapabilitiesRoutes(hostCtx as unknown as CapabilitiesHost, {\n profileDirPath: profileDir(profile),\n remountProvider,\n }),\n 'dsh-plugin-capabilities: http routes',\n )\n return disposer\n }, 'dsh-plugin-capabilities: skill provider')\n })\n}\n", "/**\n * Foreign-agent config readers: MCP servers from Claude Code (~/.claude.json,\n * ~/.claude/settings.json) and Codex (~/.codex/config.toml). Pure reads of\n * well-known paths; anything missing or malformed yields an empty list.\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { parse as parseToml } from 'smol-toml'\nimport type { McpTransport } from './mcp.ts'\n\n/** One MCP server discovered in a foreign agent's config. */\nexport interface ImportedServer {\n agent: 'claude-code' | 'codex'\n name: string\n transport: McpTransport\n command?: string\n args?: string[]\n env?: Record<string, string>\n url?: string\n headers?: Record<string, string>\n}\n\n/** Keep only string-valued entries of a record (configs may hold numbers). */\nfunction stringEntries(value: unknown): Record<string, string> | undefined {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined\n const out: Record<string, string> = {}\n for (const [key, entry] of Object.entries(value)) {\n if (typeof entry === 'string') out[key] = entry\n }\n return Object.keys(out).length > 0 ? out : undefined\n}\n\nfunction stringArray(value: unknown): string[] | undefined {\n if (!Array.isArray(value)) return undefined\n const out = value.filter((entry): entry is string => typeof entry === 'string')\n return out.length > 0 ? out : undefined\n}\n\n/** Map one Claude mcpServers entry; returns null for unsupported shapes (sse). */\nfunction mapClaudeEntry(name: string, entry: unknown): ImportedServer | null {\n if (typeof entry !== 'object' || entry === null) return null\n const record = entry as Record<string, unknown>\n const type = typeof record.type === 'string' ? record.type : 'stdio'\n if (type === 'stdio' || (type === 'stdio' && record.command !== undefined)) {\n if (typeof record.command !== 'string' || record.command === '') return null\n return {\n agent: 'claude-code', name, transport: 'stdio',\n command: record.command,\n args: stringArray(record.args),\n env: stringEntries(record.env),\n }\n }\n if (type === 'http' || type === 'streamable-http') {\n if (typeof record.url !== 'string' || record.url === '') return null\n return {\n agent: 'claude-code', name, transport: 'streamable-http',\n url: record.url,\n headers: stringEntries(record.headers),\n }\n }\n // 'sse' and anything else: dsh's mcp-client speaks stdio + streamable-http only.\n return null\n}\n\n/** MCP servers from Claude Code's user-scope config files. */\nexport function scanClaudeMcp(home: string = homedir()): ImportedServer[] {\n const merged: Record<string, unknown> = {}\n for (const file of [join(home, '.claude', 'settings.json'), join(home, '.claude.json')]) {\n if (!existsSync(file)) continue\n try {\n const parsed = JSON.parse(readFileSync(file, 'utf8')) as { mcpServers?: unknown }\n if (typeof parsed.mcpServers === 'object' && parsed.mcpServers !== null) {\n Object.assign(merged, parsed.mcpServers)\n }\n } catch {\n // Broken or partial config: skip the file, keep earlier merges.\n }\n }\n const out: ImportedServer[] = []\n for (const [name, entry] of Object.entries(merged)) {\n const mapped = mapClaudeEntry(name, entry)\n if (mapped !== null) out.push(mapped)\n }\n return out\n}\n\n/** MCP servers from Codex's config.toml ([mcp_servers.<name>] tables). */\nexport function scanCodexMcp(home: string = homedir()): ImportedServer[] {\n const file = join(home, '.codex', 'config.toml')\n if (!existsSync(file)) return []\n let root: Record<string, unknown>\n try {\n root = parseToml(readFileSync(file, 'utf8')) as Record<string, unknown>\n } catch {\n return []\n }\n const table = root.mcp_servers\n if (typeof table !== 'object' || table === null) return []\n const out: ImportedServer[] = []\n for (const [name, entry] of Object.entries(table)) {\n if (typeof entry !== 'object' || entry === null) continue\n const record = entry as Record<string, unknown>\n if (typeof record.command === 'string' && record.command !== '') {\n out.push({\n agent: 'codex', name, transport: 'stdio',\n command: record.command,\n args: stringArray(record.args),\n env: stringEntries(record.env),\n })\n } else if (typeof record.url === 'string' && record.url !== '') {\n out.push({ agent: 'codex', name, transport: 'streamable-http', url: record.url })\n }\n }\n return out\n}\n\n/** All foreign-agent MCP servers, deduplicated by (agent, name). */\nexport function scanAllMcp(home: string = homedir()): ImportedServer[] {\n const seen = new Set<string>()\n return [...scanClaudeMcp(home), ...scanCodexMcp(home)]\n .filter(server => {\n const key = `${server.agent}/${server.name}`\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n}\n\n/** Other agents' skill roots that exist on this machine. */\nexport function agentSkillRoots(home: string = homedir()): string[] {\n return [join(home, '.claude', 'skills'), join(home, '.codex', 'skills')]\n .filter(path => existsSync(path))\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nlet DATE_TIME_RE = /^(\\d{4}-\\d{2}-\\d{2})?[T ]?(?:(\\d{2}):\\d{2}(?::\\d{2}(?:\\.\\d+)?)?)?(Z|[-+]\\d{2}:\\d{2})?$/i;\nexport class TomlDate extends Date {\n #hasDate = false;\n #hasTime = false;\n #offset = null;\n constructor(date) {\n let hasDate = true;\n let hasTime = true;\n let offset = 'Z';\n if (typeof date === 'string') {\n let match = date.match(DATE_TIME_RE);\n if (match) {\n if (!match[1]) {\n hasDate = false;\n date = `0000-01-01T${date}`;\n }\n hasTime = !!match[2];\n // Make sure to use T instead of a space. Breaks in case of extreme values otherwise.\n hasTime && date[10] === ' ' && (date = date.replace(' ', 'T'));\n // Do not allow rollover hours.\n if (match[2] && +match[2] > 23) {\n date = '';\n }\n else {\n offset = match[3] || null;\n date = date.toUpperCase();\n if (!offset && hasTime)\n date += 'Z';\n }\n }\n else {\n date = '';\n }\n }\n super(date);\n if (!isNaN(this.getTime())) {\n this.#hasDate = hasDate;\n this.#hasTime = hasTime;\n this.#offset = offset;\n }\n }\n isDateTime() {\n return this.#hasDate && this.#hasTime;\n }\n isLocal() {\n return !this.#hasDate || !this.#hasTime || !this.#offset;\n }\n isDate() {\n return this.#hasDate && !this.#hasTime;\n }\n isTime() {\n return this.#hasTime && !this.#hasDate;\n }\n isValid() {\n return this.#hasDate || this.#hasTime;\n }\n toISOString() {\n let iso = super.toISOString();\n // Local Date\n if (this.isDate())\n return iso.slice(0, 10);\n // Local Time\n if (this.isTime())\n return iso.slice(11, 23);\n // Local DateTime\n if (this.#offset === null)\n return iso.slice(0, -1);\n // Offset DateTime\n if (this.#offset === 'Z')\n return iso;\n // This part is quite annoying: JS strips the original timezone from the ISO string representation\n // Instead of using a \"modified\" date and \"Z\", we restore the representation \"as authored\"\n let offset = (+(this.#offset.slice(1, 3)) * 60) + +(this.#offset.slice(4, 6));\n offset = this.#offset[0] === '-' ? offset : -offset;\n let offsetDate = new Date(this.getTime() - (offset * 60e3));\n return offsetDate.toISOString().slice(0, -1) + this.#offset;\n }\n static wrapAsOffsetDateTime(jsDate, offset = 'Z') {\n let date = new TomlDate(jsDate);\n date.#offset = offset;\n return date;\n }\n static wrapAsLocalDateTime(jsDate) {\n let date = new TomlDate(jsDate);\n date.#offset = null;\n return date;\n }\n static wrapAsLocalDate(jsDate) {\n let date = new TomlDate(jsDate);\n date.#hasTime = false;\n date.#offset = null;\n return date;\n }\n static wrapAsLocalTime(jsDate) {\n let date = new TomlDate(jsDate);\n date.#hasDate = false;\n date.#offset = null;\n return date;\n }\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nfunction getLineColFromPtr(string, ptr) {\n let lines = string.slice(0, ptr).split(/\\r\\n|\\n|\\r/g);\n return [lines.length, lines.pop().length + 1];\n}\nfunction makeCodeBlock(string, line, column) {\n let lines = string.split(/\\r\\n|\\n|\\r/g);\n let codeblock = '';\n let numberLen = (Math.log10(line + 1) | 0) + 1;\n for (let i = line - 1; i <= line + 1; i++) {\n let l = lines[i - 1];\n if (!l)\n continue;\n codeblock += i.toString().padEnd(numberLen, ' ');\n codeblock += ': ';\n codeblock += l;\n codeblock += '\\n';\n if (i === line) {\n codeblock += ' '.repeat(numberLen + column + 2);\n codeblock += '^\\n';\n }\n }\n return codeblock;\n}\nexport class TomlError extends Error {\n line;\n column;\n codeblock;\n constructor(message, options) {\n const [line, column] = getLineColFromPtr(options.toml, options.ptr);\n const codeblock = makeCodeBlock(options.toml, line, column);\n super(`Invalid TOML document: ${message}\\n\\n${codeblock}`, options);\n this.line = line;\n this.column = column;\n this.codeblock = codeblock;\n }\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { TomlError } from './error.js';\n/** @internal */\nexport function indexOfNewline(str, start = 0) {\n let idx = str.indexOf('\\n', start);\n if (str.charCodeAt(idx - 1) === 0xd /* \\r */)\n idx--;\n return idx;\n}\n/** @internal */\nexport function skipComment(ctx) {\n for (; ctx.p < ctx.s.length; ctx.p++) {\n let c = ctx.s.charCodeAt(ctx.p);\n if (c === 0xa /* \\n */)\n break;\n if (c === 0xd /* \\r */ && ctx.s.charCodeAt(ctx.p + 1) === 0xa /* \\n */) {\n ctx.p++;\n break;\n }\n if ((c < 0x20 && c !== 0x9 /* \\t */) || c === 0x7f) {\n throw new TomlError('control characters are not allowed in comments', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n }\n}\n/** @internal */\nexport function skipVoid(ctx, banNewLines, banComments) {\n let c;\n while (1) {\n while ((c = ctx.s.charCodeAt(ctx.p)) === 0x20 ||\n c === 0x9 /* \\t */ ||\n (!banNewLines &&\n (c === 0xa /* \\n */ || (c === 0xd /* \\r */ && ctx.s.charCodeAt(ctx.p + 1) === 0xa /* \\n */))))\n ctx.p++;\n if (banComments || c !== 0x23 /* # */)\n break;\n skipComment(ctx);\n }\n}\n/** @internal */\nexport function skipUntil(ctx, sep, end) {\n let ptr = ctx.p;\n if (!end) {\n ptr = indexOfNewline(ctx.s, ptr);\n ctx.p = ptr < 0 ? ctx.s.length : ptr;\n return;\n }\n for (; ctx.p < ctx.s.length; ctx.p++) {\n let c = ctx.s.charCodeAt(ctx.p);\n if (c === 0x23 /* # */) {\n skipComment(ctx);\n }\n else if (c === end || c === sep) {\n return;\n }\n }\n throw new TomlError('cannot find end of structure', {\n toml: ctx.s,\n ptr,\n });\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { TomlDate } from './date.js';\nimport { TomlError } from './error.js';\nimport { skipComment, skipUntil } from './util.js';\n// let CTRL_REGEX = /[\\x00-\\x08\\x0f-\\x1f\\x7f]/\nlet INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\\d(_?\\d)*))$/;\nlet FLOAT_REGEX = /^[+-]?\\d(_?\\d)*(\\.\\d(_?\\d)*)?([eE][+-]?\\d(_?\\d)*)?$/;\nlet LEADING_ZERO = /^[+-]?0[0-9_]/;\n/** @internal */\nexport function parseString(ctx) {\n let start = ctx.p;\n let c = ctx.s.charCodeAt(ctx.p++);\n let first = c;\n let isLiteral = c === 0x27; /* ' */\n let isMultiline = c === ctx.s.charCodeAt(ctx.p) && c === ctx.s.charCodeAt(ctx.p + 1);\n if (isMultiline) {\n // Trim initial newline\n if ((c = ctx.s.charCodeAt(ctx.p += 2)) === 0xa /* \\n */)\n ctx.p++;\n else if (c === 0xd /* \\r */ && ctx.s.charCodeAt(ctx.p + 1) === 0xa /* \\n */)\n ctx.p += 2;\n }\n /*\n The fast path does not seem to bring significant performance gains, so it's commented out.\n Kept for reference and/or future fafoing.\n\n Without: spec 5.08 \u00B5s/iter 3.88 ipc (99.44% cache) 23.90 branch misses 28.61k cycles 111.01k instructions\n 5MB 115.73 ms/iter 2.51 ipc (98.36% cache) 3.12M branch misses 619.30M cycles 1.56G instructions\n\n With: spec 5.09 \u00B5s/iter 3.90 ipc (99.46% cache) 24.42 branch misses 28.57k cycles 111.49k instructions\n 5MB 113.89 ms/iter 2.47 ipc (98.38% cache) 3.12M branch misses 611.94M cycles 1.51G instructions\n\n if (c === \"'\") {\n // Literal strings fast path - no transform needs to occur; just grab the str and that's it\n let endPtr = str.indexOf(isMultiline ? \"'''\" : \"'\", ptr)\n if (endPtr < 0) {\n throw new TomlError(\"unfinished string literal\", { toml: str, ptr })\n }\n\n if (isMultiline) {\n // If the string ends with 4-5 quotes, then the first 1-2 are part of the string\n if (str[endPtr + 3] === \"'\") endPtr++\n if (str[endPtr + 3] === \"'\") endPtr++\n }\n\n let string = str.slice(ptr, endPtr)\n if (CTRL_REGEX.test(string)) {\n let match = string.match(CTRL_REGEX)!\n throw new TomlError('control characters are not allowed in strings', { toml: str, ptr: ptr + (match.index ?? 0) })\n }\n return [string, endPtr + (isMultiline ? 3 : 1)]\n }\n */\n let parsed = '';\n let sliceStart = ctx.p;\n // states:\n // 0 - decoding\n // 1 - decoding escape\n // 2 - whitespace escape (no newline encountered yet, must fail on non-whitespace)\n // 3 - whitespace escape (newline encountered, allowed to transition back to normal decode)\n let state = 0;\n for (; ctx.p < ctx.s.length; ctx.p++) {\n c = ctx.s.charCodeAt(ctx.p);\n // Deal with newlines first, since that simplifies control character checking and handling across all states\n if (isMultiline && (c === 0xa /* \\n */ || (c === 0xd /* \\r */ && ctx.s.charCodeAt(ctx.p + 1) === 0xa /* \\n */))) {\n state = state && 3;\n }\n // Control characters are banned in TOML, so we throw an error if we encounter them\n else if ((c < 0x20 && c !== 0x9 /* \\t */) || c === 0x7f) {\n throw new TomlError('control characters are not allowed in strings', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n // The string might terminate while we're parsing through a newline escape.\n // It must have encountered a newline; otherwise, it'll simply fail in another branch.\n else if ((!state || state === 3) && c === first && (!isMultiline || (ctx.s.charCodeAt(ctx.p + 1) === first && ctx.s.charCodeAt(ctx.p + 2) === first))) {\n if (isMultiline) {\n // If the string ends with 4-5 quotes, then the first 1-2 are part of the string\n if (ctx.s.charCodeAt(ctx.p + 3) === first)\n ctx.p++;\n if (ctx.s.charCodeAt(ctx.p + 3) === first)\n ctx.p++;\n }\n // If we're in a newline escape still, then there's nothing to add.\n if (!state)\n parsed += ctx.s.slice(sliceStart, ctx.p);\n ctx.p += isMultiline ? 3 : 1;\n return parsed;\n }\n else if (!state) {\n if (!isLiteral && c === 0x5c /* \\ */) {\n parsed += ctx.s.slice(sliceStart, (sliceStart = ctx.p));\n state = 1;\n }\n }\n else if (state === 1) {\n if (c === 0x78 /* x */ || c === 0x75 /* u */ || c === 0x55 /* U */) { // Unicode escape\n let value = 0;\n let len = c === 0x78 /* x */ ? 2 : c === 0x75 /* u */ ? 4 : 8;\n for (let j = 0; j < len; j++, ctx.p++) {\n let hex = ctx.s.charCodeAt(ctx.p + 1);\n let digit = \n /* 0-9 */ hex >= 0x30 && hex <= 0x39 ? hex - 0x30 :\n /* A-F */ hex >= 0x41 && hex <= 0x46 ? hex - 0x41 + 10 :\n /* a-f */ hex >= 0x61 && hex <= 0x66 ? hex - 0x61 + 10 : -1;\n if (digit < 0)\n throw new TomlError('invalid non-hex character in unicode escape', { toml: ctx.s, ptr: ctx.p + 1 });\n value = (value << 4) | digit;\n }\n // Because JS does bitwise on signed 32bit integers, all 0xfzzzzzzz values are actually seen as negative\n if (value < 0 || value > 0x10ffff || (value >= 0xd800 && value <= 0xdfff)) {\n throw new TomlError('invalid unicode escape', { toml: ctx.s, ptr: ctx.p });\n }\n parsed += String.fromCodePoint(value);\n sliceStart = ctx.p + 1;\n state = 0;\n }\n else if (c === 0x20 || c === 0x9 /* \\t */) { // If it was a newline, it'd have been handled earlier\n state = 2;\n }\n else {\n if (c === 0x62 /* b */)\n parsed += '\\b';\n else if (c === 0x74 /* t */)\n parsed += '\\t';\n else if (c === 0x6e /* n */)\n parsed += '\\n';\n else if (c === 0x66 /* f */)\n parsed += '\\f';\n else if (c === 0x72 /* r */)\n parsed += '\\r';\n else if (c === 0x65 /* e */)\n parsed += '\\x1b';\n else if (c === 0x22 /* \" */)\n parsed += '\"';\n else if (c === 0x5c /* \\ */)\n parsed += '\\\\';\n else\n throw new TomlError('unrecognized escape sequence', { toml: ctx.s, ptr: ctx.p });\n sliceStart = ctx.p + 1;\n state = 0;\n }\n }\n else if (c !== 0x20 && c !== 0x9 /* \\t */) {\n if (state === 2) {\n throw new TomlError('invalid escape: only line-ending whitespace may be escaped', {\n toml: ctx.s,\n ptr: sliceStart,\n });\n }\n // State cannot be zero, or we'd have branched earlier already.\n // If it's a backslash, immediately transition to the escape state so it can be processed.\n state = !isLiteral && c === 0x5c /* \\ */ ? 1 : 0;\n sliceStart = ctx.p;\n }\n }\n throw new TomlError('unfinished string', { toml: ctx.s, ptr: start });\n}\nfunction sliceAndTrimEndOf(ctx, start, end) {\n let value = ctx.s.slice(start, end);\n let commentIdx = value.indexOf('#');\n if (commentIdx > 0) {\n // The call to skipComment allows to \"validate\" the comment\n // (absence of control characters)\n skipComment({ s: value, p: commentIdx, d: 0 });\n value = value.slice(0, commentIdx);\n }\n return value.trimEnd();\n}\n/** @internal */\nexport function parseValue(ctx, integersAsBigInt, end) {\n let ptr = ctx.p;\n let err = { toml: ctx.s, ptr };\n skipUntil(ctx, 0x2c /* , */, end);\n let value = sliceAndTrimEndOf(ctx, ptr, ctx.p);\n if (!value)\n throw new TomlError('incomplete declaration: value expected', err);\n if (value === '-inf')\n return -Infinity;\n if (value === 'inf' || value === '+inf')\n return Infinity;\n if (value === 'nan' || value === '+nan' || value === '-nan')\n return NaN;\n // Avoid FP representation of -0\n if (value === '-0')\n return integersAsBigInt ? 0n : 0;\n // Numbers\n let isInt = INT_REGEX.test(value);\n if (isInt || FLOAT_REGEX.test(value)) {\n if (LEADING_ZERO.test(value)) {\n throw new TomlError('leading zeroes are not allowed', err);\n }\n value = value.replace(/_/g, '');\n let numeric = +value;\n if (isNaN(numeric)) {\n throw new TomlError('invalid number', err);\n }\n if (isInt) {\n if ((isInt = !Number.isSafeInteger(numeric)) && !integersAsBigInt) {\n throw new TomlError('integer value cannot be represented losslessly', err);\n }\n if (isInt || integersAsBigInt === true)\n numeric = BigInt(value);\n }\n return numeric;\n }\n const date = new TomlDate(value);\n if (!date.isValid())\n throw new TomlError('invalid value', err);\n return date;\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { parseString, parseValue } from './primitive.js';\nimport { parseArray, parseInlineTable } from './struct.js';\nimport { TomlError } from './error.js';\n/** @internal */\nexport function extractValue(ctx, end, integersAsBigInt) {\n let ptr = ctx.p;\n let c = ctx.s.charCodeAt(ptr);\n // Structs\n if (c === 0x5b /* [ */ || c === 0x7b /* { */) {\n if (!ctx.d--) {\n throw new TomlError('document contains excessively nested structures. aborting.', {\n toml: ctx.s,\n ptr,\n });\n }\n let value = c === 0x5b /* [ */\n ? parseArray(ctx, integersAsBigInt)\n : parseInlineTable(ctx, integersAsBigInt);\n ctx.d++;\n return value;\n }\n // Strings\n if (c === 0x22 /* \" */ || c === 0x27 /* ' */) {\n return parseString(ctx);\n }\n // Booleans\n // We can fast-path because the first character is enough to know the only possible value\n if (c === 0x74 /* t */) { // Only possible valid value is `true`\n if (ctx.s.charCodeAt(++ctx.p) !== 0x72 || ctx.s.charCodeAt(++ctx.p) !== 0x75 || ctx.s.charCodeAt(++ctx.p) !== 0x65)\n throw new TomlError('invalid value', { toml: ctx.s, ptr });\n ctx.p++;\n return true;\n }\n if (c === 0x66 /* f */) { // Only possible valid value is `false`\n if (ctx.s.charCodeAt(++ctx.p) !== 0x61 || ctx.s.charCodeAt(++ctx.p) !== 0x6c || ctx.s.charCodeAt(++ctx.p) !== 0x73 || ctx.s.charCodeAt(++ctx.p) !== 0x65)\n throw new TomlError('invalid value', { toml: ctx.s, ptr });\n ctx.p++;\n return false;\n }\n // Legacy logic for numbers and dates. Slow and needs to be rewritten.\n return parseValue(ctx, integersAsBigInt, end);\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { parseString } from './primitive.js';\nimport { extractValue } from './extract.js';\nimport { indexOfNewline, skipVoid } from './util.js';\nimport { TomlError } from './error.js';\nlet KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \\t]*$/;\n/** @internal */\nexport function parseKey(ctx, end = '=') {\n let start = ctx.p;\n let dot = start - 1;\n let parsed = [];\n let endPtr = ctx.s.indexOf(end, start);\n if (endPtr < 0) {\n throw new TomlError('incomplete key-value: cannot find end of key', {\n toml: ctx.s,\n ptr: start,\n });\n }\n do {\n let c = ctx.s.charCodeAt(ctx.p = ++dot);\n // If it's whitespace, ignore\n if (c !== 0x20 && c !== 0x9 /* \\t */) {\n // If it's a string\n if (c === 0x22 /* \" */ || c === 0x27 /* ' */) {\n if (c === ctx.s.charCodeAt(ctx.p + 1) && c === ctx.s.charCodeAt(ctx.p + 2)) {\n throw new TomlError('multiline strings are not allowed in keys', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n let part = parseString(ctx);\n dot = ctx.s.indexOf('.', ctx.p);\n let strEnd = ctx.s.slice(ctx.p, dot < 0 || dot > endPtr ? endPtr : dot);\n let newLine = indexOfNewline(strEnd);\n if (newLine > -1) {\n throw new TomlError('newlines are not allowed in keys', {\n toml: ctx.s,\n ptr: newLine,\n });\n }\n if (strEnd.trimStart()) {\n throw new TomlError('found extra tokens after the string part', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n if (endPtr < ctx.p) {\n endPtr = ctx.s.indexOf(end, ctx.p);\n if (endPtr < 0) {\n throw new TomlError('incomplete key-value: cannot find end of key', {\n toml: ctx.s,\n ptr: start,\n });\n }\n }\n parsed.push(part);\n }\n else {\n // Normal raw key part consumption and validation\n dot = ctx.s.indexOf('.', ctx.p);\n let part = ctx.s.slice(ctx.p, dot < 0 || dot > endPtr ? endPtr : dot);\n if (!KEY_PART_RE.test(part)) {\n throw new TomlError('only letter, numbers, dashes and underscores are allowed in keys', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n parsed.push(part.trimEnd());\n }\n }\n // Until there's no more dot\n } while (dot + 1 && dot < endPtr);\n ctx.p = endPtr + 1;\n skipVoid(ctx, true, true);\n return parsed;\n}\n/** @internal */\nexport function parseInlineTable(ctx, integersAsBigInt) {\n let res = {};\n let seen = new Set();\n let c;\n ctx.p++;\n while (ctx.p < ctx.s.length) {\n skipVoid(ctx);\n if ((c = ctx.s.charCodeAt(ctx.p)) === 0x7d /* } */) {\n ctx.p++;\n return res;\n }\n let k;\n let t = res;\n let hasOwn = false;\n let p = ctx.p;\n let key = parseKey(ctx);\n for (let i = 0; i < key.length; i++) {\n if (i)\n t = hasOwn ? t[k] : (t[k] = {});\n k = key[i];\n if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== 'object' || seen.has(t[k]))) {\n throw new TomlError('trying to redefine an already defined value', {\n toml: ctx.s,\n ptr: p,\n });\n }\n if (!hasOwn && k === '__proto__') {\n Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });\n }\n }\n if (hasOwn) {\n throw new TomlError('trying to redefine an already defined value', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n let value = extractValue(ctx, 0x7d /* } */, integersAsBigInt);\n seen.add(t[k] = value);\n skipVoid(ctx);\n if ((c = ctx.s.charCodeAt(ctx.p++)) === 0x7d /* } */) {\n return res;\n }\n if (c !== 0x2c /* , */) {\n throw new TomlError('expected comma or end of structure', { toml: ctx.s, ptr: ctx.p - 1 });\n }\n }\n throw new TomlError('unfinished table encountered', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n}\n/** @internal */\nexport function parseArray(ctx, integersAsBigInt) {\n let res = [];\n let c;\n ctx.p++;\n while (ctx.p < ctx.s.length) {\n skipVoid(ctx);\n if ((c = ctx.s.charCodeAt(ctx.p)) === 0x5d /* ] */) {\n ctx.p++;\n return res;\n }\n res.push(extractValue(ctx, 0x5d /* ] */, integersAsBigInt));\n skipVoid(ctx);\n if ((c = ctx.s.charCodeAt(ctx.p++)) === 0x5d /* ] */) {\n return res;\n }\n if (c !== 0x2c /* , */) {\n throw new TomlError('expected comma or end of structure', { toml: ctx.s, ptr: ctx.p - 1 });\n }\n }\n throw new TomlError('unfinished array encountered', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { parseKey } from './struct.js';\nimport { extractValue } from './extract.js';\nimport { skipVoid } from './util.js';\nimport { TomlError } from './error.js';\nfunction peekTable(key, table, meta, type) {\n let t = table;\n let m = meta;\n let k;\n let hasOwn = false;\n let state;\n for (let i = 0; i < key.length; i++) {\n if (i) {\n t = hasOwn ? t[k] : (t[k] = {});\n m = (state = m[k]).c;\n if (type === 0 /* Type.DOTTED */ && (state.t === 1 /* Type.EXPLICIT */ || state.t === 2 /* Type.ARRAY */)) {\n return null;\n }\n if (state.t === 2 /* Type.ARRAY */) {\n let l = t.length - 1;\n t = t[l];\n m = m[l].c;\n }\n }\n k = key[i];\n if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 /* Type.DOTTED */ && m[k]?.d) {\n return null;\n }\n if (!hasOwn) {\n if (k === '__proto__') {\n Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });\n Object.defineProperty(m, k, { enumerable: true, configurable: true, writable: true });\n }\n m[k] = {\n t: i < key.length - 1 && type === 2 /* Type.ARRAY */\n ? 3 /* Type.ARRAY_DOTTED */ : type,\n d: false,\n i: 0,\n c: {},\n };\n }\n }\n state = m[k];\n if (state.t !== type && !(type === 1 /* Type.EXPLICIT */ && state.t === 3 /* Type.ARRAY_DOTTED */)) {\n // Bad key type!\n return null;\n }\n if (type === 2 /* Type.ARRAY */) {\n if (!state.d) {\n state.d = true;\n t[k] = [];\n }\n t[k].push(t = {});\n state.c[state.i++] = (state = { t: 1 /* Type.EXPLICIT */, d: false, i: 0, c: {} });\n }\n if (state.d) {\n // Redefining a table!\n return null;\n }\n state.d = true;\n if (type === 1 /* Type.EXPLICIT */) {\n t = hasOwn ? t[k] : (t[k] = {});\n }\n else if (type === 0 /* Type.DOTTED */ && hasOwn) {\n return null;\n }\n return [k, t, state.c];\n}\nexport function parse(toml, { maxDepth = 1000, integersAsBigInt } = {}) {\n let ctx = { s: toml, p: 0, d: maxDepth };\n let res = {};\n let meta = {};\n let tmp;\n let tbl = res;\n let m = meta;\n skipVoid(ctx);\n while (ctx.p < toml.length) {\n if (toml.charCodeAt(ctx.p) === 0x5b /* [ */) {\n let isTableArray = toml.charCodeAt(++ctx.p) === 0x5b; /* [ */\n tmp = ctx.p += +isTableArray;\n let k = parseKey(ctx, ']');\n if (isTableArray) {\n if (toml.charCodeAt(ctx.p - 1) !== 0x5d /* ] */) {\n throw new TomlError('expected end of table declaration', {\n toml: toml,\n ptr: ctx.p - 1,\n });\n }\n ctx.p++;\n }\n let p = peekTable(k, res, meta, isTableArray ? 2 /* Type.ARRAY */ : 1 /* Type.EXPLICIT */);\n if (!p) {\n throw new TomlError('trying to redefine an already defined table or value', {\n toml: toml,\n ptr: tmp,\n });\n }\n m = p[2];\n tbl = p[1];\n }\n else {\n tmp = ctx.p;\n let k = parseKey(ctx);\n let p = peekTable(k, tbl, m, 0 /* Type.DOTTED */);\n if (!p) {\n throw new TomlError('trying to redefine an already defined table or value', {\n toml: toml,\n ptr: tmp,\n });\n }\n p[1][p[0]] = extractValue(ctx, void 0, integersAsBigInt);\n }\n skipVoid(ctx, true);\n if (ctx.p < toml.length && (tmp = toml.charCodeAt(ctx.p)) !== 0xa /* \\n */ && tmp !== 0xd /* \\r */) {\n throw new TomlError('each key-value declaration must be followed by an end-of-line', {\n toml: toml,\n ptr: ctx.p,\n });\n }\n skipVoid(ctx);\n }\n return res;\n}\n", "/** Profile discovery (pure reads; same contract as dsh-plugin-install). */\n\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\n/** Profile that boots this UI: `--profile <name>` on the CLI invocation. */\nexport function argvProfile(argv: readonly string[] = process.argv): string | undefined {\n const flag = argv.indexOf('--profile')\n if (flag !== -1 && flag + 1 < argv.length && !argv[flag + 1].startsWith('-')) return argv[flag + 1]\n return undefined\n}\n\n/** Directory of a profile under DSH_HOME (default `~/.dsh`). */\nexport function profileDir(profile: string, dshHome: string | undefined = process.env.DSH_HOME): string {\n const home = dshHome ?? join(homedir(), '.dsh')\n return join(home, 'profiles', profile)\n}\n", "/** HTTP routes bridging the Settings UI to the capabilities manager. */\n\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { mkdirSync } from 'node:fs'\nimport { join, sep } from 'node:path'\nimport { scanAllMcp } from './agents.ts'\nimport { readJsonBody, sameOrigin, sendJson } from './http.ts'\nimport { loadMarketIndex, type MarketMcpServer } from './market.ts'\nimport { openDirectory } from './opener.ts'\nimport { addGitRepo, addLocalRepo, rootExists } from './repos.ts'\nimport { dshLaunch, restartOwnedByShell, scheduleRestart, trustedRestartRequest } from './restart.ts'\nimport { deleteSkill, setSkillPolicy, updateSkillFile, userSkillsDir, validateSkillInput, writeSkill, type SkillInput } from './skills.ts'\nimport { findRootByUrl, loadState, pluginStateDir, removeSkillRoot, type SkillRootEntry } from './state.ts'\nimport { removeTree } from './rmtree.ts'\nimport { listMcp, removeMcp, setMcpDisabled, upsertMcp, validateMcpInput, type McpInput } from './mcp.ts'\nimport type { CapabilitiesHost, HostSkill } from './types.ts'\n\n/**\n * A 'custom' skill is writable only when its folder sits inside a root this\n * plugin manages: the materialized repositories under the plugin state dir,\n * or a registered local root. Vendored skills shipped inside the plugin\n * package (under node_modules) are custom-sourced too but stay read-only \u2014\n * edits there would die with the next plugin update.\n */\nfunction customSkillWritable(dir: string, dshHome: string | undefined): boolean {\n const state = pluginStateDir(dshHome)\n if (dir === state || dir.startsWith(state + sep)) return true\n return loadState(dshHome).skillRoots.some(entry =>\n entry.roots.some(root => dir === root || dir.startsWith(root + sep)))\n}\n\n/** Whether the save route may write this catalog row back to disk. */\nfunction skillWritable(skill: HostSkill, dir: string | undefined, dshHome: string | undefined): boolean {\n if (dir === undefined) return false\n if (skill.source === 'user-dsh') return true\n return skill.source === 'custom' && customSkillWritable(dir, dshHome)\n}\n\n/** One catalog skill as the browser sees it (editable/dir flags added). */\ntype SkillRow = HostSkill & { editable: boolean; removable: boolean; dir?: string; policyEditable: boolean }\n\nfunction toSkillRow(skill: HostSkill, dshHome: string | undefined): SkillRow {\n const dir = skill.resourceBase?.kind === 'directory' ? skill.resourceBase.path : undefined\n return {\n ...skill,\n editable: skillWritable(skill, dir, dshHome),\n removable: skill.source === 'user-dsh',\n ...(dir !== undefined ? { dir } : {}),\n policyEditable: dir !== undefined,\n }\n}\n\n/** One registered repository plus a liveness flag (roots can go stale). */\nfunction toRootView(entry: SkillRootEntry): SkillRootEntry & { live: boolean } {\n return { ...entry, live: entry.roots.every(root => rootExists(root)) }\n}\n\nexport interface CapabilitiesRoutesConfig {\n profileDirPath: string\n /** Remount the host-plane skill provider after root-set changes. */\n remountProvider: () => Promise<void>\n}\n\n/** Register the manager's routes; returns the disposer removing them all. */\nexport function mountCapabilitiesRoutes(host: CapabilitiesHost, config: CapabilitiesRoutesConfig): () => void {\n const disposers = [\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/skills',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n try {\n const skills = await host.skills.list()\n sendJson(response, 200, { skills: skills.map(skill => toSkillRow(skill, process.env.DSH_HOME)) })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/skill',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n const url = new URL(request.url ?? '/', 'http://localhost')\n const name = url.searchParams.get('name') ?? ''\n try {\n const definition = await host.skills.get(name)\n if (definition === undefined) {\n sendJson(response, 404, { error: 'skill not found' })\n return\n }\n sendJson(response, 200, { name: definition.name, content: definition.content })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/skill/save',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as Partial<SkillInput>\n const input: SkillInput = {\n name: typeof body.name === 'string' ? body.name : '',\n description: typeof body.description === 'string' ? body.description : '',\n whenToUse: typeof body.whenToUse === 'string' ? body.whenToUse : undefined,\n modelInvocable: body.modelInvocable !== false,\n userInvocable: body.userInvocable !== false,\n content: typeof body.content === 'string' ? body.content : '',\n }\n const invalid = validateSkillInput(input)\n if (invalid !== null) {\n sendJson(response, 400, { error: invalid })\n return\n }\n // An existing skill edits in place (its own folder, whichever\n // editable source it comes from \u2014 preserving frontmatter keys the\n // editor does not own); a new name creates in the user root. The\n // file location is resolved server-side from the catalog, never\n // taken from the request.\n const existing = (await host.skills.list()).find(skill => skill.name === input.name)\n if (existing !== undefined) {\n const dir = existing.resourceBase?.kind === 'directory' ? existing.resourceBase.path : undefined\n if (!skillWritable(existing, dir, process.env.DSH_HOME)) {\n sendJson(response, 403, { error: `skills from source '${existing.source}' are read-only` })\n return\n }\n updateSkillFile(join(dir as string, 'SKILL.md'), input)\n } else {\n writeSkill(input)\n }\n sendJson(response, 200, { ok: true, name: input.name })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/skill/delete',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { name?: unknown }\n const name = typeof body.name === 'string' ? body.name : ''\n const removed = deleteSkill(name)\n sendJson(response, removed ? 200 : 404, removed ? { ok: true, name } : { error: 'skill not found' })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/skill/policy',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { name?: unknown; enabled?: unknown }\n if (typeof body.name !== 'string' || typeof body.enabled !== 'boolean') {\n sendJson(response, 400, { error: 'name and enabled are required' })\n return\n }\n const definition = await host.skills.get(body.name)\n if (definition === undefined) {\n sendJson(response, 404, { error: 'skill not found' })\n return\n }\n if (definition.path === undefined) {\n sendJson(response, 422, { error: 'skill has no file on disk (runtime-registered)' })\n return\n }\n setSkillPolicy(definition.path, body.enabled)\n sendJson(response, 200, { ok: true })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/open',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { target?: unknown; name?: unknown; id?: unknown }\n if (typeof body.target !== 'string') {\n sendJson(response, 400, { error: 'target is required' })\n return\n }\n // Targets are resolved server-side; the browser never supplies a\n // raw path, so this cannot be turned into an arbitrary open.\n let dir: string | undefined\n if (body.target === 'user-skills') {\n dir = userSkillsDir()\n // \u7528\u6237\u8FD8\u6CA1\u5EFA\u8FC7\u4EFB\u4F55\u6280\u80FD\u65F6\u8BE5\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1B\u300C\u6253\u5F00\u6280\u80FD\u76EE\u5F55\u300D\u5E94\u6309\u9700\u521B\u5EFA\u800C\u975E\u62A5\u9519\u3002\n mkdirSync(dir, { recursive: true })\n } else if (body.target === 'plugin-state') {\n dir = pluginStateDir()\n mkdirSync(dir, { recursive: true })\n } else if (body.target === 'skill') {\n if (typeof body.name !== 'string') {\n sendJson(response, 400, { error: 'name is required' })\n return\n }\n const definition = await host.skills.get(body.name)\n if (definition === undefined) {\n sendJson(response, 404, { error: 'skill not found' })\n return\n }\n dir = definition.path !== undefined\n ? definition.path.replace(/[/\\\\]SKILL\\.md$/, '').replace(/[/\\\\][^/\\\\]+\\.md$/, '')\n : definition.resourceBase?.kind === 'directory' ? definition.resourceBase.path : undefined\n } else if (body.target === 'root') {\n if (typeof body.id !== 'string') {\n sendJson(response, 400, { error: 'id is required' })\n return\n }\n const entry = loadState().skillRoots.find(row => row.id === body.id)\n if (entry === undefined) {\n sendJson(response, 404, { error: 'repository not found' })\n return\n }\n dir = entry.materialDir ?? entry.path ?? entry.roots[0]\n } else {\n sendJson(response, 400, { error: 'unknown target' })\n return\n }\n if (dir === undefined || !openDirectory(dir)) {\n sendJson(response, 422, { error: 'directory is not available on disk' })\n return\n }\n sendJson(response, 200, { ok: true })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/roots',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n sendJson(response, 200, { roots: loadState().skillRoots.map(toRootView) })\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/roots/add',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { kind?: unknown; path?: unknown; url?: unknown }\n if (body.kind !== 'local' && body.kind !== 'git') {\n sendJson(response, 400, { error: 'kind must be local or git' })\n return\n }\n const entry = body.kind === 'local'\n ? typeof body.path === 'string' && body.path.trim() !== ''\n ? await addLocalRepo(body.path)\n : undefined\n : typeof body.url === 'string' && body.url.trim() !== ''\n ? await addGitRepo(body.url)\n : undefined\n if (entry === undefined) {\n sendJson(response, 400, { error: body.kind === 'local' ? 'path is required' : 'url is required' })\n return\n }\n await config.remountProvider()\n sendJson(response, 200, { ok: true, root: toRootView(entry) })\n } catch (error) {\n sendJson(response, 400, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/roots/remove',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { id?: unknown }\n if (typeof body.id !== 'string') {\n sendJson(response, 400, { error: 'id is required' })\n return\n }\n const removed = removeSkillRoot(body.id)\n if (removed === undefined) {\n sendJson(response, 404, { error: 'repository not found' })\n return\n }\n // Unwatch before unlink: the provider's directory watchers hold\n // handles on the material tree, and removing a watched tree on\n // Windows fails with EPERM (the state is already saved by then,\n // which is why the repo still disappears despite the error).\n await config.remountProvider()\n if (removed.materialDir !== undefined) removeTree(removed.materialDir)\n sendJson(response, 200, { ok: true })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/market/skills',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n const index = await loadMarketIndex('skills')\n if (index === null) {\n sendJson(response, 502, { error: 'market index unavailable (offline?)' })\n return\n }\n sendJson(response, 200, {\n source: index.source,\n repos: (index.skills ?? []).map(repo => ({ ...repo, installedId: findRootByUrl(repo.url)?.id ?? null })),\n })\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/market/mcp',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n const index = await loadMarketIndex('mcp')\n if (index === null) {\n sendJson(response, 502, { error: 'market index unavailable (offline?)' })\n return\n }\n const existing = new Set(listMcp(config.profileDirPath).map(row => row.serverName))\n sendJson(response, 200, {\n source: index.source,\n servers: (index.servers ?? []).map(server => ({ ...server, installed: existing.has(server.id) })),\n })\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/market/skills/install',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { url?: unknown }\n if (typeof body.url !== 'string') {\n sendJson(response, 400, { error: 'url is required' })\n return\n }\n const entry = await addGitRepo(body.url)\n await config.remountProvider()\n sendJson(response, 200, { ok: true, root: toRootView(entry) })\n } catch (error) {\n sendJson(response, 400, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/market/mcp/install',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { id?: unknown }\n if (typeof body.id !== 'string') {\n sendJson(response, 400, { error: 'id is required' })\n return\n }\n const index = await loadMarketIndex('mcp')\n const server = index?.servers?.find((row: MarketMcpServer) => row.id === body.id)\n if (server === undefined) {\n sendJson(response, 404, { error: 'server not found in the market index' })\n return\n }\n if (listMcp(config.profileDirPath).some(row => row.serverName === server.id)) {\n sendJson(response, 409, { error: 'already installed' })\n return\n }\n const input: McpInput = {\n id: '',\n serverName: server.id,\n transport: server.transport,\n ...(server.transport === 'stdio'\n ? { command: server.command, args: server.args, env: undefined }\n : { url: server.url }),\n }\n const invalid = validateMcpInput(input)\n if (invalid !== null) {\n sendJson(response, 400, { error: invalid })\n return\n }\n const id = upsertMcp(config.profileDirPath, input)\n sendJson(response, 200, { ok: true, id, restartNeeded: true })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/mcp',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n sendJson(response, 200, { servers: listMcp(config.profileDirPath), restartNeeded: true })\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/mcp/save',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const input = (await readJsonBody(request)) as McpInput\n const invalid = validateMcpInput(input)\n if (invalid !== null) {\n sendJson(response, 400, { error: invalid })\n return\n }\n const id = upsertMcp(config.profileDirPath, input)\n sendJson(response, 200, { ok: true, id, restartNeeded: true })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/mcp/toggle',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { id?: unknown; disabled?: unknown }\n if (typeof body.id !== 'string' || typeof body.disabled !== 'boolean') {\n sendJson(response, 400, { error: 'id and disabled are required' })\n return\n }\n const ok = setMcpDisabled(config.profileDirPath, body.id, body.disabled)\n sendJson(response, ok ? 200 : 404, ok ? { ok: true, restartNeeded: true } : { error: 'server row not found' })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/mcp/remove',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { id?: unknown }\n if (typeof body.id !== 'string') {\n sendJson(response, 400, { error: 'id is required' })\n return\n }\n const ok = removeMcp(config.profileDirPath, body.id)\n sendJson(response, ok ? 200 : 404, ok ? { ok: true, restartNeeded: true } : { error: 'server row not found' })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/import/scan',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n try {\n sendJson(response, 200, {\n servers: scanAllMcp(),\n // Profile serverNames, so the browser can grey out existing ones.\n existing: listMcp(config.profileDirPath).map(row => row.serverName),\n })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/import/apply',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { items?: unknown }\n const wanted = new Set(\n (Array.isArray(body.items) ? body.items : [])\n .filter((item): item is { agent: string; name: string } =>\n typeof item === 'object' && item !== null && typeof (item as { agent?: unknown }).agent === 'string' && typeof (item as { name?: unknown }).name === 'string')\n .map(item => `${item.agent}/${item.name}`),\n )\n const results: Array<{ name: string; ok: boolean; error?: string }> = []\n for (const server of scanAllMcp()) {\n if (!wanted.has(`${server.agent}/${server.name}`)) continue\n const existing = listMcp(config.profileDirPath).some(row => row.serverName === server.name)\n if (existing) {\n results.push({ name: server.name, ok: false, error: 'already in profile' })\n continue\n }\n const input: McpInput = {\n id: '',\n serverName: server.name,\n transport: server.transport,\n ...(server.transport === 'stdio'\n ? { command: server.command, args: server.args, env: server.env }\n : { url: server.url, headers: server.headers }),\n }\n const invalid = validateMcpInput(input)\n if (invalid !== null) {\n results.push({ name: server.name, ok: false, error: invalid })\n continue\n }\n upsertMcp(config.profileDirPath, input)\n results.push({ name: server.name, ok: true })\n }\n sendJson(response, 200, { ok: results.every(item => item.ok), results, restartNeeded: true })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/restart',\n handler: (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n // \u8FDB\u7A0B\u63A7\u5236\uFF1A\u4EC5\u76F4\u63A5\u7684\u540C\u6E90\u56DE\u73AF\u8BF7\u6C42\uFF1B\u684C\u9762\u6A21\u5F0F\u4E0B\u91CD\u542F\u5F52\u58F3\u5C42\u6240\u6709\u3002\n if (!trustedRestartRequest(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n if (restartOwnedByShell()) {\n sendJson(response, 409, { error: 'restart is owned by the desktop shell' })\n return\n }\n const { pid, replacementPid, logOut } = scheduleRestart(dshLaunch())\n sendJson(response, 200, { ok: true, pid, replacementPid, logOut })\n },\n }),\n ]\n\n return () => { for (const dispose of disposers) dispose() }\n}\n", "/** HTTP helpers: JSON body reading, same-origin check, JSON responses. */\n\nimport type { IncomingMessage, ServerResponse } from 'node:http'\n\n/** Read and JSON-parse a request body, bounded to 1 MiB (skill bodies live here). */\nexport async function readJsonBody(request: IncomingMessage): Promise<unknown> {\n const chunks: Buffer[] = []\n let received = 0\n for await (const chunk of request) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n received += buffer.length\n if (received > 1024 * 1024) throw new Error('request body too large')\n chunks.push(buffer)\n }\n return JSON.parse(Buffer.concat(chunks).toString('utf8'))\n}\n\n/**\n * True when the request is a same-origin POST a browser page could have made.\n * CSRF fence (the loopback server already trusts its local peer for reads).\n */\nexport function sameOrigin(request: IncomingMessage): boolean {\n const origin = request.headers.origin\n const host = request.headers.host\n if (origin === undefined || host === undefined) return false\n try {\n const parsed = new URL(origin)\n return (parsed.protocol === 'http:' || parsed.protocol === 'https:') && parsed.host === host\n } catch {\n return false\n }\n}\n\n/** Write a JSON response. */\nexport function sendJson(response: ServerResponse, status: number, body: unknown): void {\n const payload = JSON.stringify(body)\n response.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'cache-control': 'no-store',\n })\n response.end(payload)\n}\n", "/**\n * Market indexes for the Settings \u201C\u5E02\u573A\u201D tab: a remote JSON list per kind\n * (skills repositories, MCP servers) fetched from the plugin's GitHub repo,\n * with the copy bundled inside the package as an offline fallback. Entries\n * are validated before they reach the browser; a bad remote index degrades\n * to the bundled one instead of erroring the page.\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\n/** Which catalog a request wants. */\nexport type MarketKind = 'skills' | 'mcp'\n\n/** One skill inside a market repository's inventory. */\nexport interface MarketSkillItem {\n name: string\n description?: string\n descriptionZh?: string\n}\n\n/** One installable skill repository in the skills index. */\nexport interface MarketSkillRepo {\n id: string\n name: string\n nameZh?: string\n description: string\n descriptionZh?: string\n /** Long-form intro for the detail view (falls back to description). */\n detail?: string\n detailZh?: string\n url: string\n homepage?: string\n skillCount?: number\n /** Skill inventory for the market detail view. */\n skills?: MarketSkillItem[]\n}\n\n/** One installable server in the MCP index. */\nexport interface MarketMcpServer {\n id: string\n name: string\n nameZh?: string\n description: string\n descriptionZh?: string\n transport: 'stdio' | 'streamable-http'\n command?: string\n args?: string[]\n envKeys?: string[]\n url?: string\n homepage: string\n category?: string\n /** Runtime hint shown next to stdio commands (npx / uvx). */\n runtime?: string\n /** Tool names the server exposes, for the market detail view. */\n tools?: string[]\n /** Long-form intro for the detail view (falls back to description). */\n detail?: string\n detailZh?: string\n}\n\nexport interface MarketIndex {\n source: 'remote' | 'bundled'\n skills?: MarketSkillRepo[]\n servers?: MarketMcpServer[]\n}\n\n/** Remote source of truth, one file per kind under the plugin repo. */\nexport function marketIndexUrl(kind: MarketKind): string {\n return `https://raw.githubusercontent.com/qinyre/dsh-plugin-capabilities/main/market/${kind}.json`\n}\n\n/** The snapshot shipped inside the package (src/../market in tests, lib/../market installed). */\nexport function bundledMarketPath(kind: MarketKind): string {\n return join(dirname(fileURLToPath(import.meta.url)), '..', 'market', `${kind}.json`)\n}\n\nconst isString = (value: unknown): value is string => typeof value === 'string' && value !== ''\nconst isStringArray = (value: unknown): value is string[] => Array.isArray(value) && value.every(isString)\n\nfunction parseSkillItems(value: unknown): MarketSkillItem[] | null {\n if (!Array.isArray(value)) return null\n const out: MarketSkillItem[] = []\n for (const item of value) {\n if (typeof item !== 'object' || item === null) continue\n const record = item as Record<string, unknown>\n if (!isString(record.name)) continue\n out.push({\n name: record.name,\n ...isString(record.description) ? { description: record.description } : {},\n ...isString(record.descriptionZh) ? { descriptionZh: record.descriptionZh } : {},\n })\n }\n return out.length > 0 ? out : null\n}\n\nfunction parseSkillsIndex(parsed: unknown): MarketSkillRepo[] | null {\n if (typeof parsed !== 'object' || parsed === null) return null\n const repos = (parsed as { repos?: unknown }).repos\n if (!Array.isArray(repos)) return null\n const out: MarketSkillRepo[] = []\n for (const entry of repos) {\n if (typeof entry !== 'object' || entry === null) continue\n const record = entry as Record<string, unknown>\n if (!isString(record.id) || !isString(record.name) || !isString(record.description) || !isString(record.url)) continue\n const skills = parseSkillItems(record.skills)\n out.push({\n id: record.id,\n name: record.name,\n ...isString(record.nameZh) ? { nameZh: record.nameZh } : {},\n description: record.description,\n ...isString(record.descriptionZh) ? { descriptionZh: record.descriptionZh } : {},\n ...isString(record.detail) ? { detail: record.detail } : {},\n ...isString(record.detailZh) ? { detailZh: record.detailZh } : {},\n url: record.url,\n ...isString(record.homepage) ? { homepage: record.homepage } : {},\n ...(typeof record.skillCount === 'number' ? { skillCount: record.skillCount } : {}),\n ...(skills !== null ? { skills } : {}),\n })\n }\n return out.length > 0 ? out : null\n}\n\nfunction parseMcpIndex(parsed: unknown): MarketMcpServer[] | null {\n if (typeof parsed !== 'object' || parsed === null) return null\n const servers = (parsed as { servers?: unknown }).servers\n if (!Array.isArray(servers)) return null\n const out: MarketMcpServer[] = []\n for (const entry of servers) {\n if (typeof entry !== 'object' || entry === null) continue\n const record = entry as Record<string, unknown>\n if (!isString(record.id) || !isString(record.name) || !isString(record.description) || !isString(record.homepage)) continue\n const transport = record.transport === 'streamable-http' ? 'streamable-http' : 'stdio'\n if (transport === 'stdio' && !isString(record.command)) continue\n if (transport === 'streamable-http' && !isString(record.url)) continue\n out.push({\n id: record.id,\n name: record.name,\n ...isString(record.nameZh) ? { nameZh: record.nameZh } : {},\n description: record.description,\n ...isString(record.descriptionZh) ? { descriptionZh: record.descriptionZh } : {},\n transport,\n ...(isString(record.command) ? { command: record.command } : {}),\n ...(isStringArray(record.args) ? { args: record.args } : {}),\n ...(isStringArray(record.envKeys) ? { envKeys: record.envKeys } : {}),\n ...(isString(record.url) ? { url: record.url } : {}),\n homepage: record.homepage,\n ...isString(record.category) ? { category: record.category } : {},\n ...isString(record.runtime) ? { runtime: record.runtime } : {},\n ...isStringArray(record.tools) ? { tools: record.tools } : {},\n ...isString(record.detail) ? { detail: record.detail } : {},\n ...isString(record.detailZh) ? { detailZh: record.detailZh } : {},\n })\n }\n return out.length > 0 ? out : null\n}\n\nexport interface LoadMarketOptions {\n fetcher?: typeof fetch\n /** Remote fetch timeout; the bundled fallback has none. */\n timeoutMs?: number\n dshHome?: string\n}\n\n/** Load one market index: remote first, bundled snapshot as fallback. */\nexport async function loadMarketIndex(kind: MarketKind, options: LoadMarketOptions = {}): Promise<MarketIndex | null> {\n const doFetch = options.fetcher ?? fetch\n if (kind === 'skills') {\n const remote = await fetchIndex(doFetch, 'skills', parseSkillsIndex, options)\n if (remote !== null) return { source: 'remote', skills: remote }\n } else {\n const remote = await fetchIndex(doFetch, 'mcp', parseMcpIndex, options)\n if (remote !== null) return { source: 'remote', servers: remote }\n }\n const bundled = bundledMarketPath(kind)\n if (!existsSync(bundled)) return null\n try {\n const parsed: unknown = JSON.parse(readFileSync(bundled, 'utf8'))\n if (kind === 'skills') {\n const skills = parseSkillsIndex(parsed)\n return skills === null ? null : { source: 'bundled', skills }\n }\n const servers = parseMcpIndex(parsed)\n return servers === null ? null : { source: 'bundled', servers }\n } catch {\n return null\n }\n}\n\n/** Fetch and validate one remote index; null on any failure. */\nasync function fetchIndex<T>(\n doFetch: typeof fetch,\n kind: MarketKind,\n parse: (parsed: unknown) => T[] | null,\n options: LoadMarketOptions,\n): Promise<T[] | null> {\n try {\n const response = await doFetch(marketIndexUrl(kind), { signal: AbortSignal.timeout(options.timeoutMs ?? 8000) })\n if (!response.ok) return null\n return parse(await response.json())\n } catch {\n // Network unavailable or slow: the bundled snapshot takes over.\n return null\n }\n}\n", "/**\n * Open a directory in the OS file manager, from the dsh sidecar process.\n * Spawned detached with all stdio ignored \u2014 a GUI file manager needs no\n * pipes, and explorer.exe reports failure through exit codes we must not\n * await (it exits non-zero even on success in several Windows versions).\n */\n\nimport { spawn } from 'node:child_process'\nimport { statSync } from 'node:fs'\n\n/** Open one directory; resolves true when a launcher was started. */\nexport function openDirectory(dir: string): boolean {\n try {\n if (!statSync(dir).isDirectory()) return false\n } catch {\n return false\n }\n if (process.platform === 'win32') {\n // explorer \u5BF9\u6B63\u659C\u6760\u8DEF\u5F84\u4F1A\u9759\u9ED8\u56DE\u843D\u5230\u9ED8\u8BA4\u6587\u4EF6\u5939\uFF08\u5B9E\u6D4B\u6253\u5F00\u6210\u4E86\u300C\u6587\u6863\u300D\uFF09\uFF0C\u5FC5\u987B\u5582\u53CD\u659C\u6760\u3002\n dir = dir.split('/').join('\\\\')\n }\n const launcher = process.platform === 'win32' ? 'explorer' : process.platform === 'darwin' ? 'open' : 'xdg-open'\n try {\n // GUI \u542F\u52A8\u5668\u4E0D\u80FD\u5E26 windowsHide\uFF1A\u8BE5 flag \u628A SW_HIDE \u5199\u8FDB STARTUPINFO\uFF0Cexplorer \u7684\n // \u9996\u4E2A\u7A97\u53E3\u636E\u6B64\u521B\u5EFA\u4E3A\u9690\u85CF\u2014\u2014\u5B9E\u673A\u8868\u73B0\u662F\u300C\u6253\u5F00\u76EE\u5F55\u300D\u70B9\u4E86\u6CA1\u53CD\u5E94\uFF0C\u7A97\u53E3\u5176\u5B9E\u5F00\u4E86\u3002\n const child = spawn(launcher, [dir], { detached: true, stdio: 'ignore' })\n // \u542F\u52A8\u5668\u89E3\u6790\u5931\u8D25\u65F6 'error' \u5F02\u6B65\u5230\u8FBE\uFF1B\u6CA1\u6709\u76D1\u542C\u4F1A\u5347\u7EA7\u6210 uncaughtException \u70B8\u6389 sidecar\u3002\n child.once('error', () => {})\n child.unref()\n return true\n } catch {\n return false\n }\n}\n", "/**\n * Custom skill repositories the user registers from the Settings page:\n * a local directory (scanned in place, zero-copy) or a GitHub repo (tarball\n * download into the plugin's state dir, no git dependency). Detection adapts\n * to the three layouts skill collections actually use \u2014 one skill at the\n * repo root, skills as immediate children, or a nested `skills/`-style\n * folder \u2014 and registers the matching scan roots for the filesystem\n * provider.\n */\n\nimport { existsSync, mkdirSync, readFileSync, readdirSync, statSync, symlinkSync } from 'node:fs'\nimport { basename, join, resolve } from 'node:path'\nimport { removeTree } from './rmtree.ts'\nimport { addSkillRoot, findRootByUrl, materialDirFor, newEntryId, type SkillRootEntry } from './state.ts'\nimport { extractTarGz } from './tar.ts'\n\n/** One GitHub source, parsed from whatever URL shape the user pasted. */\nexport interface GitHubSource {\n owner: string\n repo: string\n ref?: string\n /** `owner/repo`, the display label and dedupe key. */\n label: string\n tarballUrl: string\n}\n\nconst GITHUB_URL_RE = /^(?:https?:\\/\\/)?github\\.com\\/([A-Za-z0-9_.-]+)\\/([A-Za-z0-9_.-]+?)(?:\\.git)?(?:\\/(?:tree|archive)\\/([^/#?]+?)(?:\\.tar\\.gz)?)?(?:#([^/?#]+))?(?:[/?#].*)?$/\nconst GITHUB_SHORT_RE = /^([A-Za-z0-9_.-]+)\\/([A-Za-z0-9_.-]+)$/\n\n/** Parse a GitHub reference; returns null for anything unrecognizable. */\nexport function parseGitHubSource(input: string): GitHubSource | null {\n const trimmed = input.trim()\n if (trimmed === '') return null\n let owner = ''\n let repo = ''\n let ref: string | undefined\n let match = GITHUB_URL_RE.exec(trimmed)\n if (match !== null) {\n // Capture order: owner, repo, /tree/<ref>, #<ref>.\n const treeRef = match[3] !== undefined ? match[3] : undefined\n const hashRef = match[4] !== undefined ? match[4] : undefined\n owner = match[1]\n repo = match[2]\n ref = treeRef ?? hashRef\n } else {\n match = GITHUB_SHORT_RE.exec(trimmed)\n if (match === null) return null\n ;[, owner, repo] = match\n ref = undefined\n }\n // `owner/repo/tree/<ref>` may URL-encode slashes in the ref \u2014 keep as-is;\n // codeload addresses refs by name, branches with slashes included.\n const decodedRef = ref !== undefined ? decodeURIComponent(ref) : undefined\n const label = `${owner}/${repo}`\n const tarballUrl = `https://codeload.github.com/${owner}/${repo}/tar.gz/${decodedRef ?? 'HEAD'}`\n return { owner, repo, ref: decodedRef, label, tarballUrl }\n}\n\n/** Where skill layouts were found inside one checkout. */\nexport interface DetectedRoots {\n /** Scan roots to register (empty + single=false means \u201Cno skills\u201D). */\n roots: string[]\n /** The checkout itself is one skill (SKILL.md at its root). */\n single: boolean\n}\n\n/** A plausible flat skill file: markdown with frontmatter. */\nfunction looksLikeSkillFile(file: string): boolean {\n try {\n return readFileSync(file, 'utf8').startsWith('---')\n } catch {\n return false\n }\n}\n\n/** Does one directory directly hold skills (bundle children or flat .md)? */\nfunction holdsSkills(dir: string): boolean {\n let entries: string[]\n try {\n entries = readdirSync(dir)\n } catch {\n return false\n }\n if (existsSync(join(dir, 'SKILL.md'))) return true\n for (const name of entries) {\n if (name.endsWith('.md') && looksLikeSkillFile(join(dir, name))) return true\n }\n for (const name of entries) {\n const child = join(dir, name)\n try {\n if (statSync(child).isDirectory() && existsSync(join(child, 'SKILL.md'))) return true\n } catch {\n // racing deletion or unreadable entry: ignore\n }\n }\n return false\n}\n\n/**\n * Find the scan roots for one checkout: the checkout itself when its\n * immediate children are skills, plus any child directory that only makes\n * sense as a collection wrapper (`skills/`, `document-skills/`, \u2026). A\n * checkout with SKILL.md at its own root is one single skill \u2014 the caller\n * must give the provider its PARENT as the scan root.\n */\nexport function detectSkillRoots(checkout: string): DetectedRoots {\n if (existsSync(join(checkout, 'SKILL.md'))) return { roots: [], single: true }\n const roots: string[] = []\n if (holdsSkills(checkout)) roots.push(checkout)\n let entries: string[]\n try {\n entries = readdirSync(checkout)\n } catch {\n return { roots, single: false }\n }\n for (const name of entries) {\n if (name.startsWith('.')) continue\n const child = join(checkout, name)\n try {\n if (!statSync(child).isDirectory()) continue\n } catch {\n continue\n }\n if (existsSync(join(child, 'SKILL.md'))) continue // already covered by the parent root\n if (holdsSkills(child)) roots.push(child)\n }\n return { roots, single: false }\n}\n\n/** Register a local directory as a skill repository. */\nexport async function addLocalRepo(path: string, dshHome?: string): Promise<SkillRootEntry> {\n const resolved = resolve(path.trim().replace(/^\"|\"$/g, ''))\n if (!existsSync(resolved) || !statSync(resolved).isDirectory()) {\n throw new Error(`not a directory: ${resolved}`)\n }\n const detected = detectSkillRoots(resolved)\n if (!detected.single && detected.roots.length === 0) {\n throw new Error('no SKILL.md found under that path (expected a skill folder or a folder of skill folders)')\n }\n if (detected.single) {\n // One skill living at the given path: the provider scans a ROOT, so wrap\n // the path in a dedicated directory holding a single link to it.\n const id = newEntryId('local')\n const material = materialDirFor(id, dshHome)\n removeTree(material)\n mkdirSync(material, { recursive: true })\n try {\n symlinkSync(resolved, join(material, 'skill'), process.platform === 'win32' ? 'junction' : 'dir')\n } catch {\n removeTree(material)\n throw new Error('single-skill local folders need a directory link; try adding their parent folder instead')\n }\n return addSkillRoot({ id, kind: 'local', label: basename(resolved), path: resolved, roots: [material], materialDir: material }, dshHome)\n }\n return addSkillRoot({ id: newEntryId('local'), kind: 'local', label: basename(resolved), path: resolved, roots: detected.roots }, dshHome)\n}\n\n/** Download cap for a repo tarball. */\nconst TARBALL_MAX_BYTES = 256 * 1024 * 1024\n\n/** Register a GitHub repo: tarball download \u2192 extract \u2192 detect \u2192 persist. */\nexport async function addGitRepo(\n url: string,\n options: { dshHome?: string; fetcher?: typeof fetch } = {},\n): Promise<SkillRootEntry> {\n const source = parseGitHubSource(url)\n if (source === null) throw new Error('expected a GitHub repository URL or owner/repo')\n const existing = findRootByUrl(source.label, options.dshHome)\n if (existing !== undefined) throw new Error(`${source.label} is already registered`)\n\n const doFetch = options.fetcher ?? fetch\n const response = await doFetch(source.tarballUrl, { signal: AbortSignal.timeout(60_000) })\n if (!response.ok) throw new Error(`download failed (HTTP ${response.status}) for ${source.tarballUrl}`)\n const archive = Buffer.from(await response.arrayBuffer())\n if (archive.byteLength > TARBALL_MAX_BYTES) throw new Error('repository tarball too large')\n\n const id = newEntryId('git')\n const material = materialDirFor(id, options.dshHome)\n removeTree(material)\n const checkout = join(material, 'repo')\n try {\n mkdirSync(checkout, { recursive: true })\n extractTarGz(archive, checkout, { stripComponents: 1 })\n const detected = detectSkillRoots(checkout)\n if (!detected.single && detected.roots.length === 0) {\n throw new Error('no SKILL.md found in that repository')\n }\n // A single-skill repo is discovered through the material dir itself; a\n // collection registers the checkout (plus nested collection wrappers).\n const roots = detected.single ? [material] : detected.roots\n return addSkillRoot(\n { id, kind: 'git', label: source.label, url: source.label, ref: source.ref, roots, materialDir: material },\n options.dshHome,\n )\n } catch (error) {\n removeTree(material)\n throw error\n }\n}\n\n/** Validate one scan root still exists; entries can go stale on disk. */\nexport function rootExists(path: string): boolean {\n try {\n return statSync(path).isDirectory()\n } catch {\n return false\n }\n}\n", "/**\n * Windows-hardened recursive delete for repository material. The skill\n * provider watches these trees live, and antivirus or search indexers\n * briefly hold handles onto freshly written files, so a plain rmSync\n * races open handles and dies with EPERM. Two mitigations: clear the\n * read-only attribute first (unlinking a read-only entry fails on\n * Windows), then retry the removal so short-lived locks run out.\n */\n\nimport { chmodSync, readdirSync, rmSync, type Dirent } from 'node:fs'\nimport { join } from 'node:path'\n\n/** Windows lock holders usually let go within a second or two. */\nconst RETRIES = { maxRetries: 10, retryDelay: 200 } as const\n\nfunction clearReadOnly(dir: string): void {\n let entries: Dirent[]\n try {\n entries = readdirSync(dir, { withFileTypes: true })\n } catch {\n return // unreadable: rmSync will surface the real error\n }\n for (const entry of entries) {\n const child = join(dir, entry.name)\n // Links read as neither file nor directory here; chmod would hit the\n // link TARGET (possibly the user's own folder), so they are skipped \u2014\n // rmSync removes the link itself without following it.\n if (entry.isDirectory()) {\n try { chmodSync(child, 0o777) } catch { /* racing delete */ }\n clearReadOnly(child)\n } else if (entry.isFile()) {\n try { chmodSync(child, 0o666) } catch { /* racing delete */ }\n }\n }\n try { chmodSync(dir, 0o777) } catch { /* racing delete */ }\n}\n\n/** Delete one directory tree (or lone file), tolerating Windows lock races. */\nexport function removeTree(path: string): void {\n try {\n clearReadOnly(path)\n } catch {\n // walk failure: rmSync reports the underlying error anyway\n }\n rmSync(path, { recursive: true, force: true, ...RETRIES })\n}\n", "/**\n * Plugin-owned state under `$DSH_HOME/dsh-plugin-capabilities/`: the custom\n * skill repositories the user registered from the Settings page. Everything\n * the provider mounts live (local paths, extracted GitHub checkouts) hangs\n * off this file, so it stays small, JSON, and hand-recoverable.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { randomBytes } from 'node:crypto'\n\n/** One user-registered custom skill repository. */\nexport interface SkillRootEntry {\n /** Stable id (used by the remove route and directory names). */\n id: string\n /** `local` \u2014 a path on this machine; `git` \u2014 extracted from a GitHub URL. */\n kind: 'local' | 'git'\n /** Display label (repo `owner/name` or the local path's basename). */\n label: string\n /** The source URL (git entries). */\n url?: string\n /** Branch/tag/ref the tarball was pulled from (git entries). */\n ref?: string\n /** Local path the user pointed at (local entries). */\n path?: string\n /** Scan roots this entry contributes (single-skill repos get a wrapper dir). */\n roots: string[]\n /** Where this entry's downloaded/junctioned material lives, if any. */\n materialDir?: string\n addedAt: number\n}\n\n/** On-disk state document. */\nexport interface PluginState {\n skillRoots: SkillRootEntry[]\n}\n\n/** The plugin's own directory under DSH_HOME (default `~/.dsh`). */\nexport function pluginStateDir(dshHome: string | undefined = process.env.DSH_HOME): string {\n return join(dshHome ?? join(homedir(), '.dsh'), 'dsh-plugin-capabilities')\n}\n\nfunction statePath(dshHome?: string): string {\n return join(pluginStateDir(dshHome), 'state.json')\n}\n\nfunction emptyState(): PluginState {\n return { skillRoots: [] }\n}\n\n/** Load the state document; missing/corrupt files yield empty state. */\nexport function loadState(dshHome?: string): PluginState {\n const path = statePath(dshHome)\n if (!existsSync(path)) return emptyState()\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf8')) as Partial<PluginState>\n if (!Array.isArray(parsed.skillRoots)) return emptyState()\n const roots = parsed.skillRoots.filter((entry): entry is SkillRootEntry =>\n typeof entry === 'object' && entry !== null && typeof entry.id === 'string' && Array.isArray(entry.roots))\n return { skillRoots: roots }\n } catch {\n return emptyState()\n }\n}\n\n/** Persist the state document (atomic-enough for a single-writer UI). */\nexport function saveState(state: PluginState, dshHome?: string): void {\n const dir = pluginStateDir(dshHome)\n mkdirSync(dir, { recursive: true })\n writeFileSync(statePath(dshHome), JSON.stringify(state, null, 2) + '\\n', 'utf8')\n}\n\n/** New unique entry id. */\nexport function newEntryId(kind: 'local' | 'git'): string {\n return `${kind}-${randomBytes(4).toString('hex')}`\n}\n\n/** One entry's downloaded material (git extraction, junction wrappers). */\nexport function materialDirFor(entryId: string, dshHome?: string): string {\n return join(pluginStateDir(dshHome), 'repos', entryId)\n}\n\n/** Append one entry and persist. Returns the stored entry. */\nexport function addSkillRoot(entry: Omit<SkillRootEntry, 'addedAt'>, dshHome?: string): SkillRootEntry {\n const state = loadState(dshHome)\n const stored: SkillRootEntry = { ...entry, addedAt: Date.now() }\n state.skillRoots.push(stored)\n saveState(state, dshHome)\n return stored\n}\n\n/**\n * Deregister one entry by id and persist immediately. The material dir is\n * deliberately NOT deleted here: the skill provider still watches it, and\n * removing a watched tree on Windows fails with EPERM even though the\n * state is already saved. The caller unmounts (remountProvider) first,\n * then runs removeTree over the returned entry's materialDir. Returns the\n * removed entry, or undefined when the id is unknown.\n */\nexport function removeSkillRoot(id: string, dshHome?: string): SkillRootEntry | undefined {\n const state = loadState(dshHome)\n const at = state.skillRoots.findIndex(entry => entry.id === id)\n if (at === -1) return undefined\n const [removed] = state.skillRoots.splice(at, 1)\n saveState(state, dshHome)\n return removed\n}\n\n/** Whether a git URL is already registered (market \u201Cinstalled\u201D state). */\nexport function findRootByUrl(url: string, dshHome?: string): SkillRootEntry | undefined {\n return loadState(dshHome).skillRoots.find(entry => entry.url === url)\n}\n", "/**\n * Minimal pure-JS tar.gz extraction (node zlib + a USTAR/GNU/PAX-path\n * reader). GitHub codeload tarballs are all we ever unpack \u2014 regular files\n * and directories, no links \u2014 so unsupported entry types are skipped rather\n * than rejected, and every name is checked against escape before it touches\n * the filesystem. No subprocess: the dsh sidecar must not spawn tar.\n */\n\nimport { gunzipSync } from 'node:zlib'\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\n\n/** Guard rails for untrusted archives. */\nconst LIMITS = {\n /** Per-entry cap (a skill repo holds markdown and small assets). */\n entryBytes: 64 * 1024 * 1024,\n /** Whole-archive content cap. */\n totalBytes: 256 * 1024 * 1024,\n /** Entry count cap (also bounds loop time on corrupt input). */\n entries: 20_000,\n} as const\n\nfunction octal(block: Buffer, offset: number, length: number): number {\n const raw = block.toString('utf8', offset, offset + length).replace(/[\\0 ]+$/, '')\n return raw === '' ? 0 : Number.parseInt(raw, 8)\n}\n\nfunction field(block: Buffer, offset: number, length: number): string {\n const at = block.indexOf(0, offset)\n return block.toString('utf8', offset, Math.min(at === -1 ? offset + length : at, offset + length))\n}\n\n/** One parsed tar header. */\ninterface TarHeader {\n name: string\n size: number\n type: string\n}\n\nfunction readHeader(block: Buffer): TarHeader | null {\n // A zeroed block ends the archive (the checksum of an empty block is 0).\n if (block.every(byte => byte === 0)) return null\n const checksum = octal(block, 148, 8)\n let sum = 0\n for (let at = 0; at < 512; at++) sum += at >= 148 && at < 156 ? 32 : block[at]\n if (sum !== checksum) return null\n const magic = block.toString('utf8', 257, 257 + 6)\n let name = field(block, 0, 100)\n if (magic.startsWith('ustar')) {\n const prefix = field(block, 345, 155)\n if (prefix !== '') name = `${prefix}/${name}`\n }\n return { name, size: octal(block, 124, 12), type: block.toString('utf8', 156, 157) }\n}\n\n/** Resolve one entry name under the target, rejecting escapes. */\nfunction safeJoin(target: string, name: string): string | null {\n const normalized = name.replace(/\\\\/g, '/')\n if (normalized.startsWith('/') || /^[A-Za-z]:/.test(normalized)) return null\n const parts: string[] = []\n for (const part of normalized.split('/')) {\n if (part === '' || part === '.') continue\n if (part === '..') return null\n parts.push(part)\n }\n if (parts.length === 0) return null\n return join(target, ...parts)\n}\n\n/** PAX extended header records (`<len> key=value\\n` lines) \u2192 key/value map. */\nfunction paxRecords(content: Buffer): Map<string, string> {\n const out = new Map<string, string>()\n let cursor = 0\n while (cursor < content.length) {\n const spaceAt = content.indexOf(' ', cursor)\n if (spaceAt === -1) break\n const length = Number.parseInt(content.toString('utf8', cursor, spaceAt), 10)\n if (!Number.isInteger(length) || length <= 0 || cursor + length > content.length) break\n const record = content.toString('utf8', spaceAt + 1, cursor + length).trimEnd()\n const eq = record.indexOf('=')\n if (eq > 0) out.set(record.slice(0, eq), record.slice(eq + 1))\n cursor += length\n }\n return out\n}\n\n/** Number of leading path components to drop (GitHub tarballs wrap one). */\nexport interface ExtractOptions {\n stripComponents?: number\n}\n\n/**\n * Extract a gzip'd tar buffer into `target` (created when absent). Returns\n * the entry count written. Throws on structure errors and oversize archives.\n */\nexport function extractTarGz(archive: Buffer, target: string, options: ExtractOptions = {}): number {\n const tar = gunzipSync(archive)\n const strip = options.stripComponents ?? 0\n let offset = 0\n let written = 0\n let total = 0\n let pendingLongName: string | undefined\n let pendingPath: string | undefined\n while (offset + 512 <= tar.length) {\n const header = readHeader(tar.subarray(offset, offset + 512))\n if (header === null) break\n offset += 512\n const contentEnd = offset + header.size\n if (contentEnd > tar.length) throw new Error('truncated tar entry')\n const content = tar.subarray(offset, contentEnd)\n offset += Math.ceil(header.size / 512) * 512\n if (header.size > LIMITS.entryBytes) throw new Error('tar entry too large')\n total += header.size\n if (total > LIMITS.totalBytes) throw new Error('tar archive too large')\n if (++written > LIMITS.entries) throw new Error('too many tar entries')\n\n // Metadata entries carry the name for the entry that follows.\n if (header.type === 'L') {\n pendingLongName = field(content, 0, content.length)\n continue\n }\n if (header.type === 'x' || header.type === 'X') {\n pendingPath = paxRecords(content).get('path')\n continue\n }\n if (header.type === 'g') continue // global pax: nothing we need\n\n let name = pendingLongName ?? pendingPath ?? header.name\n pendingLongName = undefined\n pendingPath = undefined\n\n const parts = name.split('/')\n if (parts.length <= strip) continue // nothing left after stripping\n name = parts.slice(strip).join('/')\n // The stripped top-level directory itself (\"pkg/\" \u2192 \"\") owns nothing.\n if (name === '' || name === '/') continue\n\n // Directories: type '5' or a trailing slash. Symlinks/hardlinks/other\n // types are skipped \u2014 skill repos that depend on them degrade loudly\n // elsewhere instead of planting links from untrusted input.\n const isDir = header.type === '5' || (header.type === '0' || header.type === '\\0') && name.endsWith('/')\n if (header.type !== '0' && header.type !== '\\0' && header.type !== '5') continue\n\n const resolved = safeJoin(target, name)\n if (resolved === null) throw new Error(`unsafe tar entry name: ${name}`)\n if (isDir) {\n mkdirSync(resolved, { recursive: true })\n continue\n }\n mkdirSync(dirname(resolved), { recursive: true })\n writeFileSync(resolved, content)\n }\n return written\n}\n", "/**\n * Self-restart for standalone `dsh web`: relaunch the exact invocation that\n * booted this host, then stop this process \u2014 so MCP row changes compose\n * without leaving the UI. The desktop shell owns restarts there\n * (DSH_DESKTOP=1 refuses this path \u2014 a supervised sidecar must never\n * replace itself, or the supervisor respawns a second process).\n *\n * The replacement is spawned directly with windowsHide: CREATE_NO_WINDOW\n * gives it a hidden console its own console children inherit (no popping\n * windows), unlike a DETACHED_PROCESS spawn which leaves children to create\n * visible consoles. No helper process and no powershell wrapper \u2014 on at\n * least one machine a node\u2192node\u2192powershell\u2192node chain was silently blocked\n * by host software before the inner node could even start, while direct\n * node\u2192node spawns are the most battle-tested pattern there is.\n */\n\nimport { spawn } from 'node:child_process'\nimport { openSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { dirname, resolve } from 'node:path'\nimport type { IncomingMessage } from 'node:http'\n\n/** The boot invocation to replay: entry from argv, execArgv preserved. */\nexport function dshLaunch(argv: readonly string[] = process.argv, execArgv: readonly string[] = process.execArgv): {\n file: string\n args: string[]\n cwd: string | undefined\n viaShell: boolean\n} {\n const entry = argv[1]\n if (entry !== undefined && /[\\\\/](?:bin\\.(?:js|ts)|dsh)$/.test(entry)) {\n // Source launches (`pnpm dsh`) pass a relative entry that the child would\n // resolve against its OWN cwd \u2014 absolutize, and keep cwd near the entry\n // so execArgv module hooks (tsx/esm) stay resolvable.\n const abs = resolve(entry)\n return { file: process.execPath, args: [...execArgv, abs, ...argv.slice(2)], cwd: dirname(abs), viaShell: false }\n }\n // Bare `dsh` on Windows is a .cmd shim only a shell can start.\n return { file: 'dsh', args: [...argv.slice(2)], cwd: undefined, viaShell: process.platform === 'win32' }\n}\n\n/**\n * Relaunch this exact dsh invocation, then stop this process. The replacement\n * boots slowly (module loading) while this process dies within 500 ms, so\n * port handover needs no delay even for fixed-port launches. Replacement\n * output is logged under tmpdir for post-mortem.\n */\nexport function scheduleRestart(launch: ReturnType<typeof dshLaunch>): {\n pid: number\n replacementPid: number | undefined\n logOut: string\n logErr: string\n} {\n const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19)\n const logOut = `${tmpdir()}${tmpdir().endsWith('/') ? '' : '\\\\'}dsh-plugin-capabilities-restart-${stamp}.out.log`\n const logErr = logOut.replace('.out.log', '.err.log')\n const child = spawn(launch.file, launch.args, {\n cwd: launch.cwd,\n stdio: ['ignore', openSync(logOut, 'a'), openSync(logErr, 'a')],\n env: process.env,\n shell: launch.viaShell,\n windowsHide: true,\n })\n child.unref()\n setTimeout(() => process.kill(process.pid, 'SIGTERM'), 500)\n return { pid: process.pid, replacementPid: child.pid, logOut, logErr }\n}\n\n/**\n * A restart request is process control: only a direct same-origin loopback\n * request qualifies. Any forwarding trace means the loopback peer is a\n * proxy, not the user's browser.\n */\nexport function trustedRestartRequest(request: IncomingMessage, socketAddress?: string): boolean {\n const address = socketAddress ?? (request.socket.remoteAddress ?? '')\n if (address !== '127.0.0.1' && address !== '::1' && address !== '::ffff:127.0.0.1') return false\n if (request.headers.forwarded !== undefined\n || request.headers['x-forwarded-for'] !== undefined\n || request.headers['x-real-ip'] !== undefined) return false\n const origin = request.headers.origin\n const host = request.headers.host\n if (origin === undefined || host === undefined) return false\n try {\n const parsed = new URL(origin)\n return (parsed.protocol === 'http:' || parsed.protocol === 'https:') && parsed.host === host\n } catch {\n return false\n }\n}\n\n/** Restart ownership: the desktop shell supervises the sidecar and restarts it. */\nexport function restartOwnedByShell(env: NodeJS.ProcessEnv = process.env): boolean {\n return env.DSH_DESKTOP === '1'\n}\n", "/**\n * Skill catalog plumbing: frontmatter serialization for user-root SKILL.md\n * files plus create/update/delete against `$DSH_HOME/skills`. Discovery is the\n * host's business \u2014 the filesystem provider watches the directory, so writes\n * land in the catalog without any restart.\n */\n\nimport { existsSync, mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\n/** Host skill name grammar (dsh-skill's SKILL_NAME). */\nexport const SKILL_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/\n\n/** One skill write request from the browser. */\nexport interface SkillInput {\n name: string\n description: string\n whenToUse?: string\n modelInvocable: boolean\n userInvocable: boolean\n content: string\n}\n\n/** The user-owned skill root this plugin writes into (provider rank 400). */\nexport function userSkillsDir(dshHome: string | undefined = process.env.DSH_HOME): string {\n return join(dshHome ?? join(homedir(), '.dsh'), 'skills')\n}\n\n/** YAML double-quoted scalar (JSON string syntax is valid YAML 1.2). */\nfunction quote(value: string): string {\n return JSON.stringify(value)\n}\n\n/** Frontmatter + body for one skill file. Policy keys only when non-default. */\nexport function serializeSkill(input: SkillInput): string {\n const lines = [\n `name: ${input.name}`,\n `description: ${quote(input.description)}`,\n ]\n if (input.whenToUse !== undefined && input.whenToUse !== '') lines.push(`whenToUse: ${quote(input.whenToUse)}`)\n if (!input.modelInvocable) lines.push('disable-model-invocation: true')\n if (!input.userInvocable) lines.push('user-invocable: false')\n const body = input.content.replace(/\\r\\n/g, '\\n').trim()\n return `---\\n${lines.join('\\n')}\\n---\\n\\n${body}\\n`\n}\n\n/** Validate one write request; returns the rejection reason or null. */\nexport function validateSkillInput(input: SkillInput): string | null {\n if (!SKILL_NAME_RE.test(input.name)) return 'name must be kebab-case (a-z, 0-9, dashes)'\n if (input.description.trim() === '') return 'description is required'\n if (input.description.length > 1024) return 'description too long (max 1024)'\n if (input.whenToUse !== undefined && input.whenToUse.length > 2048) return 'whenToUse too long (max 2048)'\n if (input.content.length > 256 * 1024) return 'content too large (max 256 KiB)'\n return null\n}\n\n/** Directory holding one user skill's SKILL.md; name grammar blocks traversal. */\nfunction skillDir(name: string, dshHome?: string): string {\n return join(userSkillsDir(dshHome), name)\n}\n\n/** Create or update a user skill. Returns the written path. */\nexport function writeSkill(input: SkillInput, dshHome?: string): string {\n const dir = skillDir(input.name, dshHome)\n mkdirSync(dir, { recursive: true })\n const file = join(dir, 'SKILL.md')\n writeFileSync(file, serializeSkill(input), 'utf8')\n return file\n}\n\n/** Delete a user skill directory. Returns false when it does not exist. */\nexport function deleteSkill(name: string, dshHome?: string): boolean {\n if (!SKILL_NAME_RE.test(name)) return false\n const dir = skillDir(name, dshHome)\n if (!existsSync(dir) || !statSync(dir).isDirectory()) return false\n // Only ever remove the exact directory this name resolves to under the\n // skills root; the regex already pins it to one safe path segment.\n rmSync(dir, { recursive: true, force: true })\n return true\n}\n\n/**\n * Flip one skill file's load policy by editing only the two invocation keys\n * in its frontmatter \u2014 `disable-model-invocation: true` plus\n * `user-invocable: false` together take the skill out of both the model and\n * the human catalogs on every standard-provider surface; enabling removes\n * both keys (defaults permit both surfaces). Works on any file-backed skill\n * (user, project, agent, bundled, custom); the rest of the file, including\n * custom keys, ordering, and body, survives byte-for-byte.\n */\nexport function setSkillPolicy(file: string, enabled: boolean): void {\n const text = readFileSync(file, 'utf8')\n const match = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/.exec(text)\n if (match === null) throw new Error('skill file has no frontmatter block')\n const newline = text.includes('\\r\\n---') ? '\\r\\n' : '\\n'\n const body = text.slice(match[0].length)\n const lines = match[1].split(/\\r?\\n/)\n const kept = lines.filter(line => !/^(disable-model-invocation|user-invocable):/.test(line))\n if (!enabled) kept.push('disable-model-invocation: true', 'user-invocable: false')\n writeFileSync(file, `---${newline}${kept.join(newline)}${newline}---${body}`, 'utf8')\n}\n\n/**\n * Edit an existing skill file in place \u2014 for skills that do not live in the\n * user root (market/custom repositories). Only the keys the editor owns\n * (name, description, whenToUse, the two invocation flags) are rewritten;\n * every other frontmatter key \u2014 license, allowed-tools, anything a\n * repository ships \u2014 survives in order, like setSkillPolicy. The body is\n * replaced by the editor's content.\n */\nexport function updateSkillFile(file: string, input: SkillInput): void {\n const text = readFileSync(file, 'utf8')\n const match = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/.exec(text)\n if (match === null) throw new Error('skill file has no frontmatter block')\n const newline = text.includes('\\r\\n---') ? '\\r\\n' : '\\n'\n const lines = match[1].split(/\\r?\\n/)\n const kept = lines.filter(line => !/^(name|description|whenToUse|disable-model-invocation|user-invocable):/.test(line))\n const head = [`name: ${input.name}`, `description: ${quote(input.description)}`]\n if (input.whenToUse !== undefined && input.whenToUse !== '') head.push(`whenToUse: ${quote(input.whenToUse)}`)\n if (!input.modelInvocable) kept.push('disable-model-invocation: true')\n if (!input.userInvocable) kept.push('user-invocable: false')\n const body = input.content.replace(/\\r\\n/g, '\\n').trim()\n writeFileSync(file, `---${newline}${[...head, ...kept].join(newline)}${newline}---${newline}${newline}${body}${newline}`, 'utf8')\n}\n", "/**\n * MCP server rows in the profile's own patch layer: one\n * `@deepseek-ai/dsh-mcp-client` row per server. The YAML document API keeps\n * foreign rows and comments intact across edits. Row changes need a dsh\n * restart to compose \u2014 callers surface that as a pending-restart notice.\n *\n * The loader's patch grammar distinguishes creates from overrides: a bare\n * `- id: \u2026` entry only overrides an existing row (target missing \u2192 skipped\n * with a warning), while new rows must live in an anonymous `- insert:`\n * list. Managed rows therefore always sit inside one insert entry, and any\n * legacy bare rows (written before this contract was understood) are\n * absorbed into it on the next write.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { parseDocument, Document, type YAMLMap, type YAMLSeq } from 'yaml'\n/** The plugin every managed row instantiates. */\nexport const MCP_PLUGIN = '@deepseek-ai/dsh-mcp-client'\n\n/** MCP serverName grammar (dsh-mcp-client's contract). */\nexport const SERVER_NAME_RE = /^[A-Za-z0-9_-]{1,32}$/\n\n/** Transport choices the client supports. */\nexport type McpTransport = 'stdio' | 'streamable-http'\n\n/** One managed row, as shown to the browser. */\nexport interface McpRow {\n id: string\n serverName: string\n transport: McpTransport\n disabled: boolean\n command?: string\n args?: string[]\n env?: Record<string, string>\n cwd?: string\n url?: string\n headers?: Record<string, string>\n}\n\n/** Write request for one server row (id empty = create). */\nexport type McpInput = Omit<McpRow, 'disabled'> & { disabled?: boolean }\n\n/** Load the profile patch as a YAML document; `[]` for a missing file. */\nfunction loadPatch(profileDirPath: string): Document {\n const path = join(profileDirPath, 'cordis.patch.yml')\n const text = existsSync(path) ? readFileSync(path, 'utf8') : '[]'\n const doc = parseDocument(text)\n const contents = doc.contents as YAMLSeq | null\n // The default-empty file parses as a flow `[]`; the patch layer is\n // human-edited block YAML, so flip the flag before anything appends.\n if (contents !== null && contents.flow === true && contents.items.length === 0) contents.flow = false\n return doc\n}\n\nfunction savePatch(profileDirPath: string, doc: Document): void {\n mkdirSync(profileDirPath, { recursive: true })\n writeFileSync(join(profileDirPath, 'cordis.patch.yml'), String(doc), 'utf8')\n}\n\n/** Wrap a plain value into a YAML node (yaml v2 exposes no standalone createNode). */\nfunction toNode<T>(value: unknown): T {\n return new Document(value as never).contents as T\n}\n\n/** The patch row sequence; an empty file's null root becomes an empty seq. */\nfunction rowSeq(doc: Document): YAMLSeq<YAMLMap> {\n if (doc.contents === null) {\n doc.contents = toNode<YAMLSeq<YAMLMap>>([])\n // An empty seq defaults to flow style (`[]`); the file must stay block.\n ;(doc.contents as YAMLSeq).flow = false\n }\n return doc.contents as YAMLSeq<YAMLMap>\n}\n\nfunction isSeqNode(value: unknown): value is YAMLSeq<YAMLMap> {\n return typeof value === 'object' && value !== null && Array.isArray((value as YAMLSeq).items)\n}\n\n/** A patch entry's insert list when it is the anonymous create form. */\nfunction insertListOf(item: YAMLMap): YAMLSeq<YAMLMap> | undefined {\n if (item.has('id')) return undefined\n const node = item.get('insert')\n return isSeqNode(node) ? node : undefined\n}\n\n/** Every managed row: legacy bare entries (no list) and insert-list rows. */\nfunction mcpRowItems(doc: Document): { node: YAMLMap, list?: YAMLSeq<YAMLMap> }[] {\n const found: { node: YAMLMap, list?: YAMLSeq<YAMLMap> }[] = []\n for (const item of rowSeq(doc).items ?? []) {\n if (item.get('name') === MCP_PLUGIN) found.push({ node: item })\n const list = insertListOf(item)\n for (const row of list?.items ?? []) {\n if (row.get('name') === MCP_PLUGIN) found.push({ node: row, list })\n }\n }\n return found\n}\n\n/** Map one row node to its browser-facing shape. */\nfunction rowToMcp(doc: Document, item: YAMLMap): McpRow {\n // config is a YAMLMap node \u2014 materialize it before property access.\n const configNode = item.get('config') as unknown\n const plain = (typeof configNode === 'object' && configNode !== null && typeof (configNode as { toJS?: unknown }).toJS === 'function'\n ? (configNode as { toJS(document: Document): unknown }).toJS(doc)\n : {}) as Record<string, unknown>\n return {\n id: String(item.get('id') ?? ''),\n serverName: String(plain.serverName ?? ''),\n transport: plain.transport === 'streamable-http' ? 'streamable-http' : 'stdio',\n disabled: item.get('disabled') === true,\n ...(typeof plain.command === 'string' && plain.command !== '' ? { command: plain.command } : {}),\n ...(Array.isArray(plain.args) ? { args: plain.args.map(String) } : {}),\n ...(isStringMap(plain.env) ? { env: plain.env } : {}),\n ...(typeof plain.cwd === 'string' && plain.cwd !== '' ? { cwd: plain.cwd } : {}),\n ...(typeof plain.url === 'string' && plain.url !== '' ? { url: plain.url } : {}),\n ...(isStringMap(plain.headers) ? { headers: plain.headers } : {}),\n }\n}\n\nfunction isStringMap(value: unknown): value is Record<string, string> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n return Object.values(value).every(entry => typeof entry === 'string')\n}\n\n/**\n * The insert list that owns managed rows, creating it when absent and\n * absorbing legacy bare rows into it. Absorbed rows were inert under the\n * loader's override-only reading of bare entries, so the move is not just\n * cosmetic \u2014 it is what makes them compose.\n */\nfunction managedInsert(doc: Document): YAMLSeq<YAMLMap> {\n const seq = rowSeq(doc)\n const bare: YAMLMap[] = []\n let target: YAMLSeq<YAMLMap> | undefined\n for (const item of seq.items ?? []) {\n if (item.get('name') === MCP_PLUGIN) bare.push(item)\n const list = insertListOf(item)\n if (list !== undefined && list.items.some(row => row.get('name') === MCP_PLUGIN)) target ??= list\n }\n if (target === undefined) {\n const entry = toNode<YAMLMap>({ insert: [] })\n seq.add(entry)\n target = entry.get('insert') as YAMLSeq<YAMLMap>\n target.flow = false\n }\n for (const row of bare) {\n seq.items.splice(seq.items.indexOf(row), 1)\n target.add(row)\n }\n return target\n}\n\n/** Every id in use: top-level patch entries and rows inside insert lists. */\nfunction takenIds(doc: Document): Set<string> {\n const taken = new Set<string>()\n for (const item of rowSeq(doc).items ?? []) {\n const id = String(item.get('id') ?? '')\n if (id !== '') taken.add(id)\n for (const row of insertListOf(item)?.items ?? []) {\n const rowId = String(row.get('id') ?? '')\n if (rowId !== '') taken.add(rowId)\n }\n }\n return taken\n}\n\n/** Read every mcp-client row in the profile layer. */\nexport function listMcp(profileDirPath: string): McpRow[] {\n const doc = loadPatch(profileDirPath)\n return mcpRowItems(doc).map(({ node }) => rowToMcp(doc, node))\n}\n\n/** Validate one write request; returns the rejection reason or null. */\nexport function validateMcpInput(input: McpInput): string | null {\n if (!SERVER_NAME_RE.test(input.serverName)) return 'serverName must be 1-32 chars of A-Z a-z 0-9 _ -'\n // The route casts raw JSON to McpInput; a create request may omit `id`.\n const id = input.id ?? ''\n if (id.includes('/') || id.includes('..')) return 'invalid id'\n if (input.transport === 'stdio') {\n if (input.command === undefined || input.command.trim() === '') return 'stdio transport requires a command'\n } else if (input.url === undefined || !/^https?:\\/\\//.test(input.url)) {\n return 'http transport requires an http(s) url'\n }\n return null\n}\n\n/** Add or replace one server row. Returns the (possibly deduplicated) id. */\nexport function upsertMcp(profileDirPath: string, input: McpInput): string {\n const inputId = input.id ?? ''\n const doc = loadPatch(profileDirPath)\n const list = managedInsert(doc)\n\n const existing = inputId !== ''\n ? mcpRowItems(doc).find(({ node }) => String(node.get('id') ?? '') === inputId)\n : undefined\n\n let id = inputId !== '' ? inputId : `mcp-${input.serverName}`\n if (existing === undefined) {\n const taken = takenIds(doc)\n let suffix = 2\n while (taken.has(id)) id = `mcp-${input.serverName}-${suffix++}`\n }\n\n const config: Record<string, unknown> = input.transport === 'stdio'\n ? {\n serverName: input.serverName,\n transport: input.transport,\n command: input.command,\n ...(input.args !== undefined && input.args.length > 0 ? { args: input.args } : {}),\n ...(input.env !== undefined && Object.keys(input.env).length > 0 ? { env: input.env } : {}),\n ...(input.cwd !== undefined && input.cwd !== '' ? { cwd: input.cwd } : {}),\n }\n : {\n serverName: input.serverName,\n transport: input.transport,\n url: input.url,\n ...(input.headers !== undefined && Object.keys(input.headers).length > 0 ? { headers: input.headers } : {}),\n }\n const row: Record<string, unknown> = { id, name: MCP_PLUGIN, config }\n if (input.disabled === true) row.disabled = true\n\n const node = toNode<YAMLMap>(row)\n if (existing === undefined) {\n list.add(node)\n } else if (existing.list !== undefined) {\n existing.list.items.splice(existing.list.items.indexOf(existing.node), 1, node)\n } else {\n // Bare rows were absorbed above; reaching here means a foreign-shaped row.\n rowSeq(doc).items.splice(rowSeq(doc).items.indexOf(existing.node), 1, node)\n }\n\n savePatch(profileDirPath, doc)\n return id\n}\n\n/** Flip one row's disabled flag (absent = enabled). Returns false when missing. */\nexport function setMcpDisabled(profileDirPath: string, id: string, disabled: boolean): boolean {\n const doc = loadPatch(profileDirPath)\n managedInsert(doc)\n const hit = mcpRowItems(doc).find(({ node }) => String(node.get('id') ?? '') === id)\n if (hit === undefined) return false\n if (disabled) hit.node.set('disabled', true)\n else hit.node.delete('disabled')\n savePatch(profileDirPath, doc)\n return true\n}\n\n/** Remove one server row. Returns false when missing. */\nexport function removeMcp(profileDirPath: string, id: string): boolean {\n const doc = loadPatch(profileDirPath)\n managedInsert(doc)\n const hit = mcpRowItems(doc).find(({ node }) => String(node.get('id') ?? '') === id)\n if (hit === undefined || hit.list === undefined) return false\n hit.list.items.splice(hit.list.items.indexOf(hit.node), 1)\n\n // An insert entry left with no rows is dead weight; drop it when the\n // insert list is all it holds.\n const seq = rowSeq(doc)\n const owner = (seq.items ?? []).find(item => insertListOf(item) === hit.list)\n if (owner !== undefined && hit.list.items.length === 0 && owner.items.length === 1) {\n seq.items.splice(seq.items.indexOf(owner), 1)\n }\n\n savePatch(profileDirPath, doc)\n return true\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/** dsh-plugin-capabilities host entry: mount the manager's HTTP routes once\n * the profile composes both the web server and the skill registry, and mount\n * a host-plane filesystem skill provider so the Settings page sees a live\n * catalog (the web composition deliberately leaves the host row to presets).\n * The provider's custom roots also take the user-registered skill\n * repositories from the plugin state file, and remount whenever those\n * change \u2014 the catalog follows without a dsh restart. */\n\nimport type { Context } from '@deepseek-ai/cordis'\nimport { existsSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { agentSkillRoots } from './agents.ts'\nimport { argvProfile, profileDir } from './profile.ts'\nimport { mountCapabilitiesRoutes } from './routes.ts'\nimport { loadState } from './state.ts'\nimport type { CapabilitiesHost } from './types.ts'\n\nexport const name = 'dsh-plugin-capabilities'\n\n/**\n * The package's own vendored skills (`skills/` at the package root \u2014 resolves\n * identically from src/ under vitest and from lib/ when installed). Scanned as\n * a custom root, so every session sees them through the registry's global\n * layer while the files stay zero-copy and travel with plugin installs.\n */\nexport function packagedSkillsDir(): string {\n return join(dirname(fileURLToPath(import.meta.url)), '..', 'skills')\n}\n\n/** Optional cordis.yml configuration; profile defaults to the booted one. */\nexport interface Config {\n /** Profile whose patch layer holds the MCP rows; defaults to argv or `web`. */\n profile?: string\n}\n\nexport const inject = ['webServer', 'skills']\n\n/** The provider plugin's structural shape (name/apply export). */\ninterface FilesystemSkillPlugin {\n name: string\n apply(context: Context, config?: unknown): void\n}\n\n/** The disposable fiber `ctx.plugin()` returns, as far as we use it. */\ninterface PluginFiber {\n dispose(): Promise<void>\n}\n\nexport function apply(ctx: Context, config?: Config): void {\n const profile = config?.profile ?? argvProfile() ?? 'web'\n ctx.inject(['webServer', 'skills'], (hostCtx: Context) => {\n // The web bundle disables the host-plane `skill-filesystem` row on\n // purpose (presets own per-session discovery). The Settings manager\n // mounts its own host-plane provider as a CHILD of this plugin: it dies\n // with us, registers into the registry's global layer (deployment-level\n // providers are exactly what that layer is for \u2014 agents read the merged\n // catalog), and preset layers keep their semantics (nearest layer still\n // wins duplicate names). Custom roots, in scan order: the package's own\n // vendored skills (read-only, update with the plugin), the user's\n // registered repositories (local paths and GitHub checkouts, managed\n // from the Settings page), then other agents' skill roots\n // (~/.claude/skills, ~/.codex/skills) \u2014 zero-copy, live-synced both\n // ways. Registering or removing a repository remounts the provider with\n // the new root set; a failed load only means an empty catalog \u2014 the\n // routes keep serving.\n let providerFiber: PluginFiber | undefined\n let disposed = false\n ctx.effect(() => {\n const disposer = (): void => { disposed = true }\n let chain: Promise<void> = Promise.resolve()\n const remountProvider = (): Promise<void> => {\n // Serialize remounts; concurrent add/remove requests must not\n // interleave dispose and re-plugin on the same provider.\n chain = chain.then(async () => {\n if (disposed) return\n const mod = (await import('@deepseek-ai/dsh-skill-filesystem')) as unknown as\n (FilesystemSkillPlugin & { default?: FilesystemSkillPlugin })\n const plugin = mod.default ?? mod\n if (providerFiber !== undefined) {\n const old = providerFiber\n providerFiber = undefined\n try { await old.dispose() } catch { /* unloading raced us */ }\n }\n if (disposed) return\n const roots = [\n packagedSkillsDir(),\n ...loadState().skillRoots.flatMap(entry => entry.roots),\n ...agentSkillRoots(),\n ].filter(dir => existsSync(dir))\n try {\n providerFiber = hostCtx.plugin(plugin, roots.length > 0 ? { customSkillDirs: roots } : {}) as PluginFiber\n } catch {\n // Context already disposed: nothing left to mount for.\n }\n })\n chain = chain.catch(() => undefined)\n return chain\n }\n void remountProvider()\n\n ctx.effect(\n () => mountCapabilitiesRoutes(hostCtx as unknown as CapabilitiesHost, {\n profileDirPath: profileDir(profile),\n remountProvider,\n }),\n 'dsh-plugin-capabilities: http routes',\n )\n return disposer\n }, 'dsh-plugin-capabilities: skill provider')\n })\n}\n", "/**\n * Foreign-agent config readers: MCP servers from Claude Code (~/.claude.json,\n * ~/.claude/settings.json) and Codex (~/.codex/config.toml). Pure reads of\n * well-known paths; anything missing or malformed yields an empty list.\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { parse as parseToml } from 'smol-toml'\nimport type { McpTransport } from './mcp.ts'\n\n/** One MCP server discovered in a foreign agent's config. */\nexport interface ImportedServer {\n agent: 'claude-code' | 'codex'\n name: string\n transport: McpTransport\n command?: string\n args?: string[]\n env?: Record<string, string>\n url?: string\n headers?: Record<string, string>\n}\n\n/** Keep only string-valued entries of a record (configs may hold numbers). */\nfunction stringEntries(value: unknown): Record<string, string> | undefined {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined\n const out: Record<string, string> = {}\n for (const [key, entry] of Object.entries(value)) {\n if (typeof entry === 'string') out[key] = entry\n }\n return Object.keys(out).length > 0 ? out : undefined\n}\n\nfunction stringArray(value: unknown): string[] | undefined {\n if (!Array.isArray(value)) return undefined\n const out = value.filter((entry): entry is string => typeof entry === 'string')\n return out.length > 0 ? out : undefined\n}\n\n/** Map one Claude mcpServers entry; returns null for unsupported shapes (sse). */\nfunction mapClaudeEntry(name: string, entry: unknown): ImportedServer | null {\n if (typeof entry !== 'object' || entry === null) return null\n const record = entry as Record<string, unknown>\n const type = typeof record.type === 'string' ? record.type : 'stdio'\n if (type === 'stdio' || (type === 'stdio' && record.command !== undefined)) {\n if (typeof record.command !== 'string' || record.command === '') return null\n return {\n agent: 'claude-code', name, transport: 'stdio',\n command: record.command,\n args: stringArray(record.args),\n env: stringEntries(record.env),\n }\n }\n if (type === 'http' || type === 'streamable-http') {\n if (typeof record.url !== 'string' || record.url === '') return null\n return {\n agent: 'claude-code', name, transport: 'streamable-http',\n url: record.url,\n headers: stringEntries(record.headers),\n }\n }\n // 'sse' and anything else: dsh's mcp-client speaks stdio + streamable-http only.\n return null\n}\n\n/** MCP servers from Claude Code's user-scope config files. */\nexport function scanClaudeMcp(home: string = homedir()): ImportedServer[] {\n const merged: Record<string, unknown> = {}\n for (const file of [join(home, '.claude', 'settings.json'), join(home, '.claude.json')]) {\n if (!existsSync(file)) continue\n try {\n const parsed = JSON.parse(readFileSync(file, 'utf8')) as { mcpServers?: unknown }\n if (typeof parsed.mcpServers === 'object' && parsed.mcpServers !== null) {\n Object.assign(merged, parsed.mcpServers)\n }\n } catch {\n // Broken or partial config: skip the file, keep earlier merges.\n }\n }\n const out: ImportedServer[] = []\n for (const [name, entry] of Object.entries(merged)) {\n const mapped = mapClaudeEntry(name, entry)\n if (mapped !== null) out.push(mapped)\n }\n return out\n}\n\n/** MCP servers from Codex's config.toml ([mcp_servers.<name>] tables). */\nexport function scanCodexMcp(home: string = homedir()): ImportedServer[] {\n const file = join(home, '.codex', 'config.toml')\n if (!existsSync(file)) return []\n let root: Record<string, unknown>\n try {\n root = parseToml(readFileSync(file, 'utf8')) as Record<string, unknown>\n } catch {\n return []\n }\n const table = root.mcp_servers\n if (typeof table !== 'object' || table === null) return []\n const out: ImportedServer[] = []\n for (const [name, entry] of Object.entries(table)) {\n if (typeof entry !== 'object' || entry === null) continue\n const record = entry as Record<string, unknown>\n if (typeof record.command === 'string' && record.command !== '') {\n out.push({\n agent: 'codex', name, transport: 'stdio',\n command: record.command,\n args: stringArray(record.args),\n env: stringEntries(record.env),\n })\n } else if (typeof record.url === 'string' && record.url !== '') {\n out.push({ agent: 'codex', name, transport: 'streamable-http', url: record.url })\n }\n }\n return out\n}\n\n/** All foreign-agent MCP servers, deduplicated by (agent, name). */\nexport function scanAllMcp(home: string = homedir()): ImportedServer[] {\n const seen = new Set<string>()\n return [...scanClaudeMcp(home), ...scanCodexMcp(home)]\n .filter(server => {\n const key = `${server.agent}/${server.name}`\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n}\n\n/** Other agents' skill roots that exist on this machine. */\nexport function agentSkillRoots(home: string = homedir()): string[] {\n return [join(home, '.claude', 'skills'), join(home, '.codex', 'skills')]\n .filter(path => existsSync(path))\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nlet DATE_TIME_RE = /^(\\d{4}-\\d{2}-\\d{2})?[T ]?(?:(\\d{2}):\\d{2}(?::\\d{2}(?:\\.\\d+)?)?)?(Z|[-+]\\d{2}:\\d{2})?$/i;\nexport class TomlDate extends Date {\n #hasDate = false;\n #hasTime = false;\n #offset = null;\n constructor(date) {\n let hasDate = true;\n let hasTime = true;\n let offset = 'Z';\n if (typeof date === 'string') {\n let match = date.match(DATE_TIME_RE);\n if (match) {\n if (!match[1]) {\n hasDate = false;\n date = `0000-01-01T${date}`;\n }\n hasTime = !!match[2];\n // Make sure to use T instead of a space. Breaks in case of extreme values otherwise.\n hasTime && date[10] === ' ' && (date = date.replace(' ', 'T'));\n // Do not allow rollover hours.\n if (match[2] && +match[2] > 23) {\n date = '';\n }\n else {\n offset = match[3] || null;\n date = date.toUpperCase();\n if (!offset && hasTime)\n date += 'Z';\n }\n }\n else {\n date = '';\n }\n }\n super(date);\n if (!isNaN(this.getTime())) {\n this.#hasDate = hasDate;\n this.#hasTime = hasTime;\n this.#offset = offset;\n }\n }\n isDateTime() {\n return this.#hasDate && this.#hasTime;\n }\n isLocal() {\n return !this.#hasDate || !this.#hasTime || !this.#offset;\n }\n isDate() {\n return this.#hasDate && !this.#hasTime;\n }\n isTime() {\n return this.#hasTime && !this.#hasDate;\n }\n isValid() {\n return this.#hasDate || this.#hasTime;\n }\n toISOString() {\n let iso = super.toISOString();\n // Local Date\n if (this.isDate())\n return iso.slice(0, 10);\n // Local Time\n if (this.isTime())\n return iso.slice(11, 23);\n // Local DateTime\n if (this.#offset === null)\n return iso.slice(0, -1);\n // Offset DateTime\n if (this.#offset === 'Z')\n return iso;\n // This part is quite annoying: JS strips the original timezone from the ISO string representation\n // Instead of using a \"modified\" date and \"Z\", we restore the representation \"as authored\"\n let offset = (+(this.#offset.slice(1, 3)) * 60) + +(this.#offset.slice(4, 6));\n offset = this.#offset[0] === '-' ? offset : -offset;\n let offsetDate = new Date(this.getTime() - (offset * 60e3));\n return offsetDate.toISOString().slice(0, -1) + this.#offset;\n }\n static wrapAsOffsetDateTime(jsDate, offset = 'Z') {\n let date = new TomlDate(jsDate);\n date.#offset = offset;\n return date;\n }\n static wrapAsLocalDateTime(jsDate) {\n let date = new TomlDate(jsDate);\n date.#offset = null;\n return date;\n }\n static wrapAsLocalDate(jsDate) {\n let date = new TomlDate(jsDate);\n date.#hasTime = false;\n date.#offset = null;\n return date;\n }\n static wrapAsLocalTime(jsDate) {\n let date = new TomlDate(jsDate);\n date.#hasDate = false;\n date.#offset = null;\n return date;\n }\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nfunction getLineColFromPtr(string, ptr) {\n let lines = string.slice(0, ptr).split(/\\r\\n|\\n|\\r/g);\n return [lines.length, lines.pop().length + 1];\n}\nfunction makeCodeBlock(string, line, column) {\n let lines = string.split(/\\r\\n|\\n|\\r/g);\n let codeblock = '';\n let numberLen = (Math.log10(line + 1) | 0) + 1;\n for (let i = line - 1; i <= line + 1; i++) {\n let l = lines[i - 1];\n if (!l)\n continue;\n codeblock += i.toString().padEnd(numberLen, ' ');\n codeblock += ': ';\n codeblock += l;\n codeblock += '\\n';\n if (i === line) {\n codeblock += ' '.repeat(numberLen + column + 2);\n codeblock += '^\\n';\n }\n }\n return codeblock;\n}\nexport class TomlError extends Error {\n line;\n column;\n codeblock;\n constructor(message, options) {\n const [line, column] = getLineColFromPtr(options.toml, options.ptr);\n const codeblock = makeCodeBlock(options.toml, line, column);\n super(`Invalid TOML document: ${message}\\n\\n${codeblock}`, options);\n this.line = line;\n this.column = column;\n this.codeblock = codeblock;\n }\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { TomlError } from './error.js';\n/** @internal */\nexport function indexOfNewline(str, start = 0) {\n let idx = str.indexOf('\\n', start);\n if (str.charCodeAt(idx - 1) === 0xd /* \\r */)\n idx--;\n return idx;\n}\n/** @internal */\nexport function skipComment(ctx) {\n for (; ctx.p < ctx.s.length; ctx.p++) {\n let c = ctx.s.charCodeAt(ctx.p);\n if (c === 0xa /* \\n */)\n break;\n if (c === 0xd /* \\r */ && ctx.s.charCodeAt(ctx.p + 1) === 0xa /* \\n */) {\n ctx.p++;\n break;\n }\n if ((c < 0x20 && c !== 0x9 /* \\t */) || c === 0x7f) {\n throw new TomlError('control characters are not allowed in comments', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n }\n}\n/** @internal */\nexport function skipVoid(ctx, banNewLines, banComments) {\n let c;\n while (1) {\n while ((c = ctx.s.charCodeAt(ctx.p)) === 0x20 ||\n c === 0x9 /* \\t */ ||\n (!banNewLines &&\n (c === 0xa /* \\n */ || (c === 0xd /* \\r */ && ctx.s.charCodeAt(ctx.p + 1) === 0xa /* \\n */))))\n ctx.p++;\n if (banComments || c !== 0x23 /* # */)\n break;\n skipComment(ctx);\n }\n}\n/** @internal */\nexport function skipUntil(ctx, sep, end) {\n let ptr = ctx.p;\n if (!end) {\n ptr = indexOfNewline(ctx.s, ptr);\n ctx.p = ptr < 0 ? ctx.s.length : ptr;\n return;\n }\n for (; ctx.p < ctx.s.length; ctx.p++) {\n let c = ctx.s.charCodeAt(ctx.p);\n if (c === 0x23 /* # */) {\n skipComment(ctx);\n }\n else if (c === end || c === sep) {\n return;\n }\n }\n throw new TomlError('cannot find end of structure', {\n toml: ctx.s,\n ptr,\n });\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { TomlDate } from './date.js';\nimport { TomlError } from './error.js';\nimport { skipComment, skipUntil } from './util.js';\n// let CTRL_REGEX = /[\\x00-\\x08\\x0f-\\x1f\\x7f]/\nlet INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\\d(_?\\d)*))$/;\nlet FLOAT_REGEX = /^[+-]?\\d(_?\\d)*(\\.\\d(_?\\d)*)?([eE][+-]?\\d(_?\\d)*)?$/;\nlet LEADING_ZERO = /^[+-]?0[0-9_]/;\n/** @internal */\nexport function parseString(ctx) {\n let start = ctx.p;\n let c = ctx.s.charCodeAt(ctx.p++);\n let first = c;\n let isLiteral = c === 0x27; /* ' */\n let isMultiline = c === ctx.s.charCodeAt(ctx.p) && c === ctx.s.charCodeAt(ctx.p + 1);\n if (isMultiline) {\n // Trim initial newline\n if ((c = ctx.s.charCodeAt(ctx.p += 2)) === 0xa /* \\n */)\n ctx.p++;\n else if (c === 0xd /* \\r */ && ctx.s.charCodeAt(ctx.p + 1) === 0xa /* \\n */)\n ctx.p += 2;\n }\n /*\n The fast path does not seem to bring significant performance gains, so it's commented out.\n Kept for reference and/or future fafoing.\n\n Without: spec 5.08 \u00B5s/iter 3.88 ipc (99.44% cache) 23.90 branch misses 28.61k cycles 111.01k instructions\n 5MB 115.73 ms/iter 2.51 ipc (98.36% cache) 3.12M branch misses 619.30M cycles 1.56G instructions\n\n With: spec 5.09 \u00B5s/iter 3.90 ipc (99.46% cache) 24.42 branch misses 28.57k cycles 111.49k instructions\n 5MB 113.89 ms/iter 2.47 ipc (98.38% cache) 3.12M branch misses 611.94M cycles 1.51G instructions\n\n if (c === \"'\") {\n // Literal strings fast path - no transform needs to occur; just grab the str and that's it\n let endPtr = str.indexOf(isMultiline ? \"'''\" : \"'\", ptr)\n if (endPtr < 0) {\n throw new TomlError(\"unfinished string literal\", { toml: str, ptr })\n }\n\n if (isMultiline) {\n // If the string ends with 4-5 quotes, then the first 1-2 are part of the string\n if (str[endPtr + 3] === \"'\") endPtr++\n if (str[endPtr + 3] === \"'\") endPtr++\n }\n\n let string = str.slice(ptr, endPtr)\n if (CTRL_REGEX.test(string)) {\n let match = string.match(CTRL_REGEX)!\n throw new TomlError('control characters are not allowed in strings', { toml: str, ptr: ptr + (match.index ?? 0) })\n }\n return [string, endPtr + (isMultiline ? 3 : 1)]\n }\n */\n let parsed = '';\n let sliceStart = ctx.p;\n // states:\n // 0 - decoding\n // 1 - decoding escape\n // 2 - whitespace escape (no newline encountered yet, must fail on non-whitespace)\n // 3 - whitespace escape (newline encountered, allowed to transition back to normal decode)\n let state = 0;\n for (; ctx.p < ctx.s.length; ctx.p++) {\n c = ctx.s.charCodeAt(ctx.p);\n // Deal with newlines first, since that simplifies control character checking and handling across all states\n if (isMultiline && (c === 0xa /* \\n */ || (c === 0xd /* \\r */ && ctx.s.charCodeAt(ctx.p + 1) === 0xa /* \\n */))) {\n state = state && 3;\n }\n // Control characters are banned in TOML, so we throw an error if we encounter them\n else if ((c < 0x20 && c !== 0x9 /* \\t */) || c === 0x7f) {\n throw new TomlError('control characters are not allowed in strings', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n // The string might terminate while we're parsing through a newline escape.\n // It must have encountered a newline; otherwise, it'll simply fail in another branch.\n else if ((!state || state === 3) && c === first && (!isMultiline || (ctx.s.charCodeAt(ctx.p + 1) === first && ctx.s.charCodeAt(ctx.p + 2) === first))) {\n if (isMultiline) {\n // If the string ends with 4-5 quotes, then the first 1-2 are part of the string\n if (ctx.s.charCodeAt(ctx.p + 3) === first)\n ctx.p++;\n if (ctx.s.charCodeAt(ctx.p + 3) === first)\n ctx.p++;\n }\n // If we're in a newline escape still, then there's nothing to add.\n if (!state)\n parsed += ctx.s.slice(sliceStart, ctx.p);\n ctx.p += isMultiline ? 3 : 1;\n return parsed;\n }\n else if (!state) {\n if (!isLiteral && c === 0x5c /* \\ */) {\n parsed += ctx.s.slice(sliceStart, (sliceStart = ctx.p));\n state = 1;\n }\n }\n else if (state === 1) {\n if (c === 0x78 /* x */ || c === 0x75 /* u */ || c === 0x55 /* U */) { // Unicode escape\n let value = 0;\n let len = c === 0x78 /* x */ ? 2 : c === 0x75 /* u */ ? 4 : 8;\n for (let j = 0; j < len; j++, ctx.p++) {\n let hex = ctx.s.charCodeAt(ctx.p + 1);\n let digit = \n /* 0-9 */ hex >= 0x30 && hex <= 0x39 ? hex - 0x30 :\n /* A-F */ hex >= 0x41 && hex <= 0x46 ? hex - 0x41 + 10 :\n /* a-f */ hex >= 0x61 && hex <= 0x66 ? hex - 0x61 + 10 : -1;\n if (digit < 0)\n throw new TomlError('invalid non-hex character in unicode escape', { toml: ctx.s, ptr: ctx.p + 1 });\n value = (value << 4) | digit;\n }\n // Because JS does bitwise on signed 32bit integers, all 0xfzzzzzzz values are actually seen as negative\n if (value < 0 || value > 0x10ffff || (value >= 0xd800 && value <= 0xdfff)) {\n throw new TomlError('invalid unicode escape', { toml: ctx.s, ptr: ctx.p });\n }\n parsed += String.fromCodePoint(value);\n sliceStart = ctx.p + 1;\n state = 0;\n }\n else if (c === 0x20 || c === 0x9 /* \\t */) { // If it was a newline, it'd have been handled earlier\n state = 2;\n }\n else {\n if (c === 0x62 /* b */)\n parsed += '\\b';\n else if (c === 0x74 /* t */)\n parsed += '\\t';\n else if (c === 0x6e /* n */)\n parsed += '\\n';\n else if (c === 0x66 /* f */)\n parsed += '\\f';\n else if (c === 0x72 /* r */)\n parsed += '\\r';\n else if (c === 0x65 /* e */)\n parsed += '\\x1b';\n else if (c === 0x22 /* \" */)\n parsed += '\"';\n else if (c === 0x5c /* \\ */)\n parsed += '\\\\';\n else\n throw new TomlError('unrecognized escape sequence', { toml: ctx.s, ptr: ctx.p });\n sliceStart = ctx.p + 1;\n state = 0;\n }\n }\n else if (c !== 0x20 && c !== 0x9 /* \\t */) {\n if (state === 2) {\n throw new TomlError('invalid escape: only line-ending whitespace may be escaped', {\n toml: ctx.s,\n ptr: sliceStart,\n });\n }\n // State cannot be zero, or we'd have branched earlier already.\n // If it's a backslash, immediately transition to the escape state so it can be processed.\n state = !isLiteral && c === 0x5c /* \\ */ ? 1 : 0;\n sliceStart = ctx.p;\n }\n }\n throw new TomlError('unfinished string', { toml: ctx.s, ptr: start });\n}\nfunction sliceAndTrimEndOf(ctx, start, end) {\n let value = ctx.s.slice(start, end);\n let commentIdx = value.indexOf('#');\n if (commentIdx > 0) {\n // The call to skipComment allows to \"validate\" the comment\n // (absence of control characters)\n skipComment({ s: value, p: commentIdx, d: 0 });\n value = value.slice(0, commentIdx);\n }\n return value.trimEnd();\n}\n/** @internal */\nexport function parseValue(ctx, integersAsBigInt, end) {\n let ptr = ctx.p;\n let err = { toml: ctx.s, ptr };\n skipUntil(ctx, 0x2c /* , */, end);\n let value = sliceAndTrimEndOf(ctx, ptr, ctx.p);\n if (!value)\n throw new TomlError('incomplete declaration: value expected', err);\n if (value === '-inf')\n return -Infinity;\n if (value === 'inf' || value === '+inf')\n return Infinity;\n if (value === 'nan' || value === '+nan' || value === '-nan')\n return NaN;\n // Avoid FP representation of -0\n if (value === '-0')\n return integersAsBigInt ? 0n : 0;\n // Numbers\n let isInt = INT_REGEX.test(value);\n if (isInt || FLOAT_REGEX.test(value)) {\n if (LEADING_ZERO.test(value)) {\n throw new TomlError('leading zeroes are not allowed', err);\n }\n value = value.replace(/_/g, '');\n let numeric = +value;\n if (isNaN(numeric)) {\n throw new TomlError('invalid number', err);\n }\n if (isInt) {\n if ((isInt = !Number.isSafeInteger(numeric)) && !integersAsBigInt) {\n throw new TomlError('integer value cannot be represented losslessly', err);\n }\n if (isInt || integersAsBigInt === true)\n numeric = BigInt(value);\n }\n return numeric;\n }\n const date = new TomlDate(value);\n if (!date.isValid())\n throw new TomlError('invalid value', err);\n return date;\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { parseString, parseValue } from './primitive.js';\nimport { parseArray, parseInlineTable } from './struct.js';\nimport { TomlError } from './error.js';\n/** @internal */\nexport function extractValue(ctx, end, integersAsBigInt) {\n let ptr = ctx.p;\n let c = ctx.s.charCodeAt(ptr);\n // Structs\n if (c === 0x5b /* [ */ || c === 0x7b /* { */) {\n if (!ctx.d--) {\n throw new TomlError('document contains excessively nested structures. aborting.', {\n toml: ctx.s,\n ptr,\n });\n }\n let value = c === 0x5b /* [ */\n ? parseArray(ctx, integersAsBigInt)\n : parseInlineTable(ctx, integersAsBigInt);\n ctx.d++;\n return value;\n }\n // Strings\n if (c === 0x22 /* \" */ || c === 0x27 /* ' */) {\n return parseString(ctx);\n }\n // Booleans\n // We can fast-path because the first character is enough to know the only possible value\n if (c === 0x74 /* t */) { // Only possible valid value is `true`\n if (ctx.s.charCodeAt(++ctx.p) !== 0x72 || ctx.s.charCodeAt(++ctx.p) !== 0x75 || ctx.s.charCodeAt(++ctx.p) !== 0x65)\n throw new TomlError('invalid value', { toml: ctx.s, ptr });\n ctx.p++;\n return true;\n }\n if (c === 0x66 /* f */) { // Only possible valid value is `false`\n if (ctx.s.charCodeAt(++ctx.p) !== 0x61 || ctx.s.charCodeAt(++ctx.p) !== 0x6c || ctx.s.charCodeAt(++ctx.p) !== 0x73 || ctx.s.charCodeAt(++ctx.p) !== 0x65)\n throw new TomlError('invalid value', { toml: ctx.s, ptr });\n ctx.p++;\n return false;\n }\n // Legacy logic for numbers and dates. Slow and needs to be rewritten.\n return parseValue(ctx, integersAsBigInt, end);\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { parseString } from './primitive.js';\nimport { extractValue } from './extract.js';\nimport { indexOfNewline, skipVoid } from './util.js';\nimport { TomlError } from './error.js';\nlet KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \\t]*$/;\n/** @internal */\nexport function parseKey(ctx, end = '=') {\n let start = ctx.p;\n let dot = start - 1;\n let parsed = [];\n let endPtr = ctx.s.indexOf(end, start);\n if (endPtr < 0) {\n throw new TomlError('incomplete key-value: cannot find end of key', {\n toml: ctx.s,\n ptr: start,\n });\n }\n do {\n let c = ctx.s.charCodeAt(ctx.p = ++dot);\n // If it's whitespace, ignore\n if (c !== 0x20 && c !== 0x9 /* \\t */) {\n // If it's a string\n if (c === 0x22 /* \" */ || c === 0x27 /* ' */) {\n if (c === ctx.s.charCodeAt(ctx.p + 1) && c === ctx.s.charCodeAt(ctx.p + 2)) {\n throw new TomlError('multiline strings are not allowed in keys', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n let part = parseString(ctx);\n dot = ctx.s.indexOf('.', ctx.p);\n let strEnd = ctx.s.slice(ctx.p, dot < 0 || dot > endPtr ? endPtr : dot);\n let newLine = indexOfNewline(strEnd);\n if (newLine > -1) {\n throw new TomlError('newlines are not allowed in keys', {\n toml: ctx.s,\n ptr: newLine,\n });\n }\n if (strEnd.trimStart()) {\n throw new TomlError('found extra tokens after the string part', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n if (endPtr < ctx.p) {\n endPtr = ctx.s.indexOf(end, ctx.p);\n if (endPtr < 0) {\n throw new TomlError('incomplete key-value: cannot find end of key', {\n toml: ctx.s,\n ptr: start,\n });\n }\n }\n parsed.push(part);\n }\n else {\n // Normal raw key part consumption and validation\n dot = ctx.s.indexOf('.', ctx.p);\n let part = ctx.s.slice(ctx.p, dot < 0 || dot > endPtr ? endPtr : dot);\n if (!KEY_PART_RE.test(part)) {\n throw new TomlError('only letter, numbers, dashes and underscores are allowed in keys', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n parsed.push(part.trimEnd());\n }\n }\n // Until there's no more dot\n } while (dot + 1 && dot < endPtr);\n ctx.p = endPtr + 1;\n skipVoid(ctx, true, true);\n return parsed;\n}\n/** @internal */\nexport function parseInlineTable(ctx, integersAsBigInt) {\n let res = {};\n let seen = new Set();\n let c;\n ctx.p++;\n while (ctx.p < ctx.s.length) {\n skipVoid(ctx);\n if ((c = ctx.s.charCodeAt(ctx.p)) === 0x7d /* } */) {\n ctx.p++;\n return res;\n }\n let k;\n let t = res;\n let hasOwn = false;\n let p = ctx.p;\n let key = parseKey(ctx);\n for (let i = 0; i < key.length; i++) {\n if (i)\n t = hasOwn ? t[k] : (t[k] = {});\n k = key[i];\n if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== 'object' || seen.has(t[k]))) {\n throw new TomlError('trying to redefine an already defined value', {\n toml: ctx.s,\n ptr: p,\n });\n }\n if (!hasOwn && k === '__proto__') {\n Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });\n }\n }\n if (hasOwn) {\n throw new TomlError('trying to redefine an already defined value', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n }\n let value = extractValue(ctx, 0x7d /* } */, integersAsBigInt);\n seen.add(t[k] = value);\n skipVoid(ctx);\n if ((c = ctx.s.charCodeAt(ctx.p++)) === 0x7d /* } */) {\n return res;\n }\n if (c !== 0x2c /* , */) {\n throw new TomlError('expected comma or end of structure', { toml: ctx.s, ptr: ctx.p - 1 });\n }\n }\n throw new TomlError('unfinished table encountered', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n}\n/** @internal */\nexport function parseArray(ctx, integersAsBigInt) {\n let res = [];\n let c;\n ctx.p++;\n while (ctx.p < ctx.s.length) {\n skipVoid(ctx);\n if ((c = ctx.s.charCodeAt(ctx.p)) === 0x5d /* ] */) {\n ctx.p++;\n return res;\n }\n res.push(extractValue(ctx, 0x5d /* ] */, integersAsBigInt));\n skipVoid(ctx);\n if ((c = ctx.s.charCodeAt(ctx.p++)) === 0x5d /* ] */) {\n return res;\n }\n if (c !== 0x2c /* , */) {\n throw new TomlError('expected comma or end of structure', { toml: ctx.s, ptr: ctx.p - 1 });\n }\n }\n throw new TomlError('unfinished array encountered', {\n toml: ctx.s,\n ptr: ctx.p,\n });\n}\n", "/*!\n * Copyright (c) Squirrel Chat et al., All rights reserved.\n * SPDX-License-Identifier: BSD-3-Clause\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors\n * may be used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\nimport { parseKey } from './struct.js';\nimport { extractValue } from './extract.js';\nimport { skipVoid } from './util.js';\nimport { TomlError } from './error.js';\nfunction peekTable(key, table, meta, type) {\n let t = table;\n let m = meta;\n let k;\n let hasOwn = false;\n let state;\n for (let i = 0; i < key.length; i++) {\n if (i) {\n t = hasOwn ? t[k] : (t[k] = {});\n m = (state = m[k]).c;\n if (type === 0 /* Type.DOTTED */ && (state.t === 1 /* Type.EXPLICIT */ || state.t === 2 /* Type.ARRAY */)) {\n return null;\n }\n if (state.t === 2 /* Type.ARRAY */) {\n let l = t.length - 1;\n t = t[l];\n m = m[l].c;\n }\n }\n k = key[i];\n if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 /* Type.DOTTED */ && m[k]?.d) {\n return null;\n }\n if (!hasOwn) {\n if (k === '__proto__') {\n Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });\n Object.defineProperty(m, k, { enumerable: true, configurable: true, writable: true });\n }\n m[k] = {\n t: i < key.length - 1 && type === 2 /* Type.ARRAY */\n ? 3 /* Type.ARRAY_DOTTED */ : type,\n d: false,\n i: 0,\n c: {},\n };\n }\n }\n state = m[k];\n if (state.t !== type && !(type === 1 /* Type.EXPLICIT */ && state.t === 3 /* Type.ARRAY_DOTTED */)) {\n // Bad key type!\n return null;\n }\n if (type === 2 /* Type.ARRAY */) {\n if (!state.d) {\n state.d = true;\n t[k] = [];\n }\n t[k].push(t = {});\n state.c[state.i++] = (state = { t: 1 /* Type.EXPLICIT */, d: false, i: 0, c: {} });\n }\n if (state.d) {\n // Redefining a table!\n return null;\n }\n state.d = true;\n if (type === 1 /* Type.EXPLICIT */) {\n t = hasOwn ? t[k] : (t[k] = {});\n }\n else if (type === 0 /* Type.DOTTED */ && hasOwn) {\n return null;\n }\n return [k, t, state.c];\n}\nexport function parse(toml, { maxDepth = 1000, integersAsBigInt } = {}) {\n let ctx = { s: toml, p: 0, d: maxDepth };\n let res = {};\n let meta = {};\n let tmp;\n let tbl = res;\n let m = meta;\n skipVoid(ctx);\n while (ctx.p < toml.length) {\n if (toml.charCodeAt(ctx.p) === 0x5b /* [ */) {\n let isTableArray = toml.charCodeAt(++ctx.p) === 0x5b; /* [ */\n tmp = ctx.p += +isTableArray;\n let k = parseKey(ctx, ']');\n if (isTableArray) {\n if (toml.charCodeAt(ctx.p - 1) !== 0x5d /* ] */) {\n throw new TomlError('expected end of table declaration', {\n toml: toml,\n ptr: ctx.p - 1,\n });\n }\n ctx.p++;\n }\n let p = peekTable(k, res, meta, isTableArray ? 2 /* Type.ARRAY */ : 1 /* Type.EXPLICIT */);\n if (!p) {\n throw new TomlError('trying to redefine an already defined table or value', {\n toml: toml,\n ptr: tmp,\n });\n }\n m = p[2];\n tbl = p[1];\n }\n else {\n tmp = ctx.p;\n let k = parseKey(ctx);\n let p = peekTable(k, tbl, m, 0 /* Type.DOTTED */);\n if (!p) {\n throw new TomlError('trying to redefine an already defined table or value', {\n toml: toml,\n ptr: tmp,\n });\n }\n p[1][p[0]] = extractValue(ctx, void 0, integersAsBigInt);\n }\n skipVoid(ctx, true);\n if (ctx.p < toml.length && (tmp = toml.charCodeAt(ctx.p)) !== 0xa /* \\n */ && tmp !== 0xd /* \\r */) {\n throw new TomlError('each key-value declaration must be followed by an end-of-line', {\n toml: toml,\n ptr: ctx.p,\n });\n }\n skipVoid(ctx);\n }\n return res;\n}\n", "/** Profile discovery (pure reads; same contract as dsh-plugin-install). */\n\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\n/** Profile that boots this UI: `--profile <name>` on the CLI invocation. */\nexport function argvProfile(argv: readonly string[] = process.argv): string | undefined {\n const flag = argv.indexOf('--profile')\n if (flag !== -1 && flag + 1 < argv.length && !argv[flag + 1].startsWith('-')) return argv[flag + 1]\n return undefined\n}\n\n/** Directory of a profile under DSH_HOME (default `~/.dsh`). */\nexport function profileDir(profile: string, dshHome: string | undefined = process.env.DSH_HOME): string {\n const home = dshHome ?? join(homedir(), '.dsh')\n return join(home, 'profiles', profile)\n}\n", "/** HTTP routes bridging the Settings UI to the capabilities manager. */\n\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { mkdirSync } from 'node:fs'\nimport { join, sep } from 'node:path'\nimport { scanAllMcp } from './agents.ts'\nimport { readJsonBody, sameOrigin, sendJson } from './http.ts'\nimport { loadMarketIndex, type MarketMcpServer } from './market.ts'\nimport { openDirectory } from './opener.ts'\nimport { addGitRepo, addLocalRepo, rootExists } from './repos.ts'\nimport { dshLaunch, restartOwnedByShell, scheduleRestart, trustedRestartRequest } from './restart.ts'\nimport { deleteSkill, setSkillPolicy, updateSkillFile, userSkillsDir, validateSkillInput, writeSkill, type SkillInput } from './skills.ts'\nimport { findRootByUrl, loadState, pluginStateDir, removeSkillRoot, type SkillRootEntry } from './state.ts'\nimport { removeTree } from './rmtree.ts'\nimport { listMcp, removeMcp, setMcpDisabled, upsertMcp, validateMcpInput, type McpInput } from './mcp.ts'\nimport type { CapabilitiesHost, HostSkill } from './types.ts'\n\n/**\n * A 'custom' skill is writable only when its folder sits inside a root this\n * plugin manages: the materialized repositories under the plugin state dir,\n * or a registered local root. Vendored skills shipped inside the plugin\n * package (under node_modules) are custom-sourced too but stay read-only \u2014\n * edits there would die with the next plugin update.\n */\nfunction customSkillWritable(dir: string, dshHome: string | undefined): boolean {\n const state = pluginStateDir(dshHome)\n if (dir === state || dir.startsWith(state + sep)) return true\n return loadState(dshHome).skillRoots.some(entry =>\n entry.roots.some(root => dir === root || dir.startsWith(root + sep)))\n}\n\n/** Whether the save route may write this catalog row back to disk. */\nfunction skillWritable(skill: HostSkill, dir: string | undefined, dshHome: string | undefined): boolean {\n if (dir === undefined) return false\n if (skill.source === 'user-dsh') return true\n return skill.source === 'custom' && customSkillWritable(dir, dshHome)\n}\n\n/** One catalog skill as the browser sees it (editable/dir flags added). */\ntype SkillRow = HostSkill & { editable: boolean; removable: boolean; dir?: string; policyEditable: boolean }\n\nfunction toSkillRow(skill: HostSkill, dshHome: string | undefined): SkillRow {\n const dir = skill.resourceBase?.kind === 'directory' ? skill.resourceBase.path : undefined\n return {\n ...skill,\n editable: skillWritable(skill, dir, dshHome),\n removable: skill.source === 'user-dsh',\n ...(dir !== undefined ? { dir } : {}),\n policyEditable: dir !== undefined,\n }\n}\n\n/** One registered repository plus a liveness flag (roots can go stale). */\nfunction toRootView(entry: SkillRootEntry): SkillRootEntry & { live: boolean } {\n return { ...entry, live: entry.roots.every(root => rootExists(root)) }\n}\n\nexport interface CapabilitiesRoutesConfig {\n profileDirPath: string\n /** Remount the host-plane skill provider after root-set changes. */\n remountProvider: () => Promise<void>\n}\n\n/** Register the manager's routes; returns the disposer removing them all. */\nexport function mountCapabilitiesRoutes(host: CapabilitiesHost, config: CapabilitiesRoutesConfig): () => void {\n const disposers = [\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/skills',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n try {\n const skills = await host.skills.list()\n sendJson(response, 200, { skills: skills.map(skill => toSkillRow(skill, process.env.DSH_HOME)) })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/skill',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n const url = new URL(request.url ?? '/', 'http://localhost')\n const name = url.searchParams.get('name') ?? ''\n try {\n const definition = await host.skills.get(name)\n if (definition === undefined) {\n sendJson(response, 404, { error: 'skill not found' })\n return\n }\n sendJson(response, 200, { name: definition.name, content: definition.content })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/skill/save',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as Partial<SkillInput>\n const input: SkillInput = {\n name: typeof body.name === 'string' ? body.name : '',\n description: typeof body.description === 'string' ? body.description : '',\n whenToUse: typeof body.whenToUse === 'string' ? body.whenToUse : undefined,\n modelInvocable: body.modelInvocable !== false,\n userInvocable: body.userInvocable !== false,\n content: typeof body.content === 'string' ? body.content : '',\n }\n const invalid = validateSkillInput(input)\n if (invalid !== null) {\n sendJson(response, 400, { error: invalid })\n return\n }\n // An existing skill edits in place (its own folder, whichever\n // editable source it comes from \u2014 preserving frontmatter keys the\n // editor does not own); a new name creates in the user root. The\n // file location is resolved server-side from the catalog, never\n // taken from the request.\n const existing = (await host.skills.list()).find(skill => skill.name === input.name)\n if (existing !== undefined) {\n const dir = existing.resourceBase?.kind === 'directory' ? existing.resourceBase.path : undefined\n if (!skillWritable(existing, dir, process.env.DSH_HOME)) {\n sendJson(response, 403, { error: `skills from source '${existing.source}' are read-only` })\n return\n }\n updateSkillFile(join(dir as string, 'SKILL.md'), input)\n } else {\n writeSkill(input)\n }\n sendJson(response, 200, { ok: true, name: input.name })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/skill/delete',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { name?: unknown }\n const name = typeof body.name === 'string' ? body.name : ''\n const removed = deleteSkill(name)\n sendJson(response, removed ? 200 : 404, removed ? { ok: true, name } : { error: 'skill not found' })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/skill/policy',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { name?: unknown; enabled?: unknown }\n if (typeof body.name !== 'string' || typeof body.enabled !== 'boolean') {\n sendJson(response, 400, { error: 'name and enabled are required' })\n return\n }\n const definition = await host.skills.get(body.name)\n if (definition === undefined) {\n sendJson(response, 404, { error: 'skill not found' })\n return\n }\n if (definition.path === undefined) {\n sendJson(response, 422, { error: 'skill has no file on disk (runtime-registered)' })\n return\n }\n setSkillPolicy(definition.path, body.enabled)\n sendJson(response, 200, { ok: true })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/open',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { target?: unknown; name?: unknown; id?: unknown }\n if (typeof body.target !== 'string') {\n sendJson(response, 400, { error: 'target is required' })\n return\n }\n // Targets are resolved server-side; the browser never supplies a\n // raw path, so this cannot be turned into an arbitrary open.\n let dir: string | undefined\n if (body.target === 'user-skills') {\n dir = userSkillsDir()\n // \u7528\u6237\u8FD8\u6CA1\u5EFA\u8FC7\u4EFB\u4F55\u6280\u80FD\u65F6\u8BE5\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1B\u300C\u6253\u5F00\u6280\u80FD\u76EE\u5F55\u300D\u5E94\u6309\u9700\u521B\u5EFA\u800C\u975E\u62A5\u9519\u3002\n mkdirSync(dir, { recursive: true })\n } else if (body.target === 'plugin-state') {\n dir = pluginStateDir()\n mkdirSync(dir, { recursive: true })\n } else if (body.target === 'skill') {\n if (typeof body.name !== 'string') {\n sendJson(response, 400, { error: 'name is required' })\n return\n }\n const definition = await host.skills.get(body.name)\n if (definition === undefined) {\n sendJson(response, 404, { error: 'skill not found' })\n return\n }\n dir = definition.path !== undefined\n ? definition.path.replace(/[/\\\\]SKILL\\.md$/, '').replace(/[/\\\\][^/\\\\]+\\.md$/, '')\n : definition.resourceBase?.kind === 'directory' ? definition.resourceBase.path : undefined\n } else if (body.target === 'root') {\n if (typeof body.id !== 'string') {\n sendJson(response, 400, { error: 'id is required' })\n return\n }\n const entry = loadState().skillRoots.find(row => row.id === body.id)\n if (entry === undefined) {\n sendJson(response, 404, { error: 'repository not found' })\n return\n }\n dir = entry.materialDir ?? entry.path ?? entry.roots[0]\n } else {\n sendJson(response, 400, { error: 'unknown target' })\n return\n }\n if (dir === undefined || !openDirectory(dir)) {\n sendJson(response, 422, { error: 'directory is not available on disk' })\n return\n }\n sendJson(response, 200, { ok: true })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/roots',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n sendJson(response, 200, { roots: loadState().skillRoots.map(toRootView) })\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/roots/add',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { kind?: unknown; path?: unknown; url?: unknown }\n if (body.kind !== 'local' && body.kind !== 'git') {\n sendJson(response, 400, { error: 'kind must be local or git' })\n return\n }\n const entry = body.kind === 'local'\n ? typeof body.path === 'string' && body.path.trim() !== ''\n ? await addLocalRepo(body.path)\n : undefined\n : typeof body.url === 'string' && body.url.trim() !== ''\n ? await addGitRepo(body.url)\n : undefined\n if (entry === undefined) {\n sendJson(response, 400, { error: body.kind === 'local' ? 'path is required' : 'url is required' })\n return\n }\n await config.remountProvider()\n sendJson(response, 200, { ok: true, root: toRootView(entry) })\n } catch (error) {\n sendJson(response, 400, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/roots/remove',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { id?: unknown }\n if (typeof body.id !== 'string') {\n sendJson(response, 400, { error: 'id is required' })\n return\n }\n const removed = removeSkillRoot(body.id)\n if (removed === undefined) {\n sendJson(response, 404, { error: 'repository not found' })\n return\n }\n // Unwatch before unlink: the provider's directory watchers hold\n // handles on the material tree, and removing a watched tree on\n // Windows fails with EPERM (the state is already saved by then,\n // which is why the repo still disappears despite the error).\n await config.remountProvider()\n if (removed.materialDir !== undefined) removeTree(removed.materialDir)\n sendJson(response, 200, { ok: true })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/market/skills',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n const index = await loadMarketIndex('skills')\n if (index === null) {\n sendJson(response, 502, { error: 'market index unavailable (offline?)' })\n return\n }\n sendJson(response, 200, {\n source: index.source,\n repos: (index.skills ?? []).map(repo => ({ ...repo, installedId: findRootByUrl(repo.url)?.id ?? null })),\n })\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/market/mcp',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n const index = await loadMarketIndex('mcp')\n if (index === null) {\n sendJson(response, 502, { error: 'market index unavailable (offline?)' })\n return\n }\n const existing = new Set(listMcp(config.profileDirPath).map(row => row.serverName))\n sendJson(response, 200, {\n source: index.source,\n servers: (index.servers ?? []).map(server => ({ ...server, installed: existing.has(server.id) })),\n })\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/market/skills/install',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { url?: unknown }\n if (typeof body.url !== 'string') {\n sendJson(response, 400, { error: 'url is required' })\n return\n }\n const entry = await addGitRepo(body.url)\n await config.remountProvider()\n sendJson(response, 200, { ok: true, root: toRootView(entry) })\n } catch (error) {\n sendJson(response, 400, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/market/mcp/install',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { id?: unknown }\n if (typeof body.id !== 'string') {\n sendJson(response, 400, { error: 'id is required' })\n return\n }\n const index = await loadMarketIndex('mcp')\n const server = index?.servers?.find((row: MarketMcpServer) => row.id === body.id)\n if (server === undefined) {\n sendJson(response, 404, { error: 'server not found in the market index' })\n return\n }\n if (listMcp(config.profileDirPath).some(row => row.serverName === server.id)) {\n sendJson(response, 409, { error: 'already installed' })\n return\n }\n const input: McpInput = {\n id: '',\n serverName: server.id,\n transport: server.transport,\n ...(server.transport === 'stdio'\n ? { command: server.command, args: server.args, env: undefined }\n : { url: server.url }),\n }\n const invalid = validateMcpInput(input)\n if (invalid !== null) {\n sendJson(response, 400, { error: invalid })\n return\n }\n const id = upsertMcp(config.profileDirPath, input)\n sendJson(response, 200, { ok: true, id, restartNeeded: true })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/mcp',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n sendJson(response, 200, { servers: listMcp(config.profileDirPath), restartNeeded: true })\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/mcp/save',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const input = (await readJsonBody(request)) as McpInput\n const invalid = validateMcpInput(input)\n if (invalid !== null) {\n sendJson(response, 400, { error: invalid })\n return\n }\n const id = upsertMcp(config.profileDirPath, input)\n sendJson(response, 200, { ok: true, id, restartNeeded: true })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/mcp/toggle',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { id?: unknown; disabled?: unknown }\n if (typeof body.id !== 'string' || typeof body.disabled !== 'boolean') {\n sendJson(response, 400, { error: 'id and disabled are required' })\n return\n }\n const ok = setMcpDisabled(config.profileDirPath, body.id, body.disabled)\n sendJson(response, ok ? 200 : 404, ok ? { ok: true, restartNeeded: true } : { error: 'server row not found' })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/mcp/remove',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { id?: unknown }\n if (typeof body.id !== 'string') {\n sendJson(response, 400, { error: 'id is required' })\n return\n }\n const ok = removeMcp(config.profileDirPath, body.id)\n sendJson(response, ok ? 200 : 404, ok ? { ok: true, restartNeeded: true } : { error: 'server row not found' })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/import/scan',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'GET') {\n response.writeHead(405, { allow: 'GET' })\n response.end()\n return\n }\n try {\n sendJson(response, 200, {\n servers: scanAllMcp(),\n // Profile serverNames, so the browser can grey out existing ones.\n existing: listMcp(config.profileDirPath).map(row => row.serverName),\n })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/import/apply',\n handler: async (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n if (!sameOrigin(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n try {\n const body = (await readJsonBody(request)) as { items?: unknown }\n const wanted = new Set(\n (Array.isArray(body.items) ? body.items : [])\n .filter((item): item is { agent: string; name: string } =>\n typeof item === 'object' && item !== null && typeof (item as { agent?: unknown }).agent === 'string' && typeof (item as { name?: unknown }).name === 'string')\n .map(item => `${item.agent}/${item.name}`),\n )\n const results: Array<{ name: string; ok: boolean; error?: string }> = []\n for (const server of scanAllMcp()) {\n if (!wanted.has(`${server.agent}/${server.name}`)) continue\n const existing = listMcp(config.profileDirPath).some(row => row.serverName === server.name)\n if (existing) {\n results.push({ name: server.name, ok: false, error: 'already in profile' })\n continue\n }\n const input: McpInput = {\n id: '',\n serverName: server.name,\n transport: server.transport,\n ...(server.transport === 'stdio'\n ? { command: server.command, args: server.args, env: server.env }\n : { url: server.url, headers: server.headers }),\n }\n const invalid = validateMcpInput(input)\n if (invalid !== null) {\n results.push({ name: server.name, ok: false, error: invalid })\n continue\n }\n upsertMcp(config.profileDirPath, input)\n results.push({ name: server.name, ok: true })\n }\n sendJson(response, 200, { ok: results.every(item => item.ok), results, restartNeeded: true })\n } catch (error) {\n sendJson(response, 500, { error: error instanceof Error ? error.message : String(error) })\n }\n },\n }),\n\n host.webServer.register({\n kind: 'exact',\n path: '/dsh-plugin-capabilities/restart',\n handler: (request: IncomingMessage, response: ServerResponse) => {\n if (request.method !== 'POST') {\n response.writeHead(405, { allow: 'POST' })\n response.end()\n return\n }\n // \u8FDB\u7A0B\u63A7\u5236\uFF1A\u4EC5\u76F4\u63A5\u7684\u540C\u6E90\u56DE\u73AF\u8BF7\u6C42\uFF1B\u684C\u9762\u6A21\u5F0F\u4E0B\u91CD\u542F\u5F52\u58F3\u5C42\u6240\u6709\u3002\n if (!trustedRestartRequest(request)) {\n sendJson(response, 403, { error: 'untrusted origin' })\n return\n }\n if (restartOwnedByShell()) {\n sendJson(response, 409, { error: 'restart is owned by the desktop shell' })\n return\n }\n const { pid, replacementPid, logOut } = scheduleRestart(dshLaunch())\n sendJson(response, 200, { ok: true, pid, replacementPid, logOut })\n },\n }),\n ]\n\n return () => { for (const dispose of disposers) dispose() }\n}\n", "/** HTTP helpers: JSON body reading, same-origin check, JSON responses. */\n\nimport type { IncomingMessage, ServerResponse } from 'node:http'\n\n/** Read and JSON-parse a request body, bounded to 1 MiB (skill bodies live here). */\nexport async function readJsonBody(request: IncomingMessage): Promise<unknown> {\n const chunks: Buffer[] = []\n let received = 0\n for await (const chunk of request) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n received += buffer.length\n if (received > 1024 * 1024) throw new Error('request body too large')\n chunks.push(buffer)\n }\n return JSON.parse(Buffer.concat(chunks).toString('utf8'))\n}\n\n/**\n * True when the request is a same-origin POST a browser page could have made.\n * CSRF fence (the loopback server already trusts its local peer for reads).\n */\nexport function sameOrigin(request: IncomingMessage): boolean {\n const origin = request.headers.origin\n const host = request.headers.host\n if (origin === undefined || host === undefined) return false\n try {\n const parsed = new URL(origin)\n return (parsed.protocol === 'http:' || parsed.protocol === 'https:') && parsed.host === host\n } catch {\n return false\n }\n}\n\n/** Write a JSON response. */\nexport function sendJson(response: ServerResponse, status: number, body: unknown): void {\n const payload = JSON.stringify(body)\n response.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'cache-control': 'no-store',\n })\n response.end(payload)\n}\n", "/**\n * Market indexes for the Settings \u201C\u5E02\u573A\u201D tab: a remote JSON list per kind\n * (skills repositories, MCP servers) fetched from the plugin's GitHub repo,\n * with the copy bundled inside the package as an offline fallback. Entries\n * are validated before they reach the browser; a bad remote index degrades\n * to the bundled one instead of erroring the page.\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\n/** Which catalog a request wants. */\nexport type MarketKind = 'skills' | 'mcp'\n\n/** One skill inside a market repository's inventory. */\nexport interface MarketSkillItem {\n name: string\n description?: string\n descriptionZh?: string\n}\n\n/** One installable skill repository in the skills index. */\nexport interface MarketSkillRepo {\n id: string\n name: string\n nameZh?: string\n description: string\n descriptionZh?: string\n /** Long-form intro for the detail view (falls back to description). */\n detail?: string\n detailZh?: string\n url: string\n homepage?: string\n skillCount?: number\n /** Skill inventory for the market detail view. */\n skills?: MarketSkillItem[]\n}\n\n/** One installable server in the MCP index. */\nexport interface MarketMcpServer {\n id: string\n name: string\n nameZh?: string\n description: string\n descriptionZh?: string\n transport: 'stdio' | 'streamable-http'\n command?: string\n args?: string[]\n envKeys?: string[]\n url?: string\n homepage: string\n category?: string\n /** Runtime hint shown next to stdio commands (npx / uvx). */\n runtime?: string\n /** Tool names the server exposes, for the market detail view. */\n tools?: string[]\n /** Long-form intro for the detail view (falls back to description). */\n detail?: string\n detailZh?: string\n}\n\nexport interface MarketIndex {\n source: 'remote' | 'bundled'\n skills?: MarketSkillRepo[]\n servers?: MarketMcpServer[]\n}\n\n/** Remote source of truth, one file per kind under the plugin repo. */\nexport function marketIndexUrl(kind: MarketKind): string {\n return `https://raw.githubusercontent.com/qinyre/dsh-plugin-capabilities/main/market/${kind}.json`\n}\n\n/** The snapshot shipped inside the package (src/../market in tests, lib/../market installed). */\nexport function bundledMarketPath(kind: MarketKind): string {\n return join(dirname(fileURLToPath(import.meta.url)), '..', 'market', `${kind}.json`)\n}\n\nconst isString = (value: unknown): value is string => typeof value === 'string' && value !== ''\nconst isStringArray = (value: unknown): value is string[] => Array.isArray(value) && value.every(isString)\n\nfunction parseSkillItems(value: unknown): MarketSkillItem[] | null {\n if (!Array.isArray(value)) return null\n const out: MarketSkillItem[] = []\n for (const item of value) {\n if (typeof item !== 'object' || item === null) continue\n const record = item as Record<string, unknown>\n if (!isString(record.name)) continue\n out.push({\n name: record.name,\n ...isString(record.description) ? { description: record.description } : {},\n ...isString(record.descriptionZh) ? { descriptionZh: record.descriptionZh } : {},\n })\n }\n return out.length > 0 ? out : null\n}\n\nfunction parseSkillsIndex(parsed: unknown): MarketSkillRepo[] | null {\n if (typeof parsed !== 'object' || parsed === null) return null\n const repos = (parsed as { repos?: unknown }).repos\n if (!Array.isArray(repos)) return null\n const out: MarketSkillRepo[] = []\n for (const entry of repos) {\n if (typeof entry !== 'object' || entry === null) continue\n const record = entry as Record<string, unknown>\n if (!isString(record.id) || !isString(record.name) || !isString(record.description) || !isString(record.url)) continue\n const skills = parseSkillItems(record.skills)\n out.push({\n id: record.id,\n name: record.name,\n ...isString(record.nameZh) ? { nameZh: record.nameZh } : {},\n description: record.description,\n ...isString(record.descriptionZh) ? { descriptionZh: record.descriptionZh } : {},\n ...isString(record.detail) ? { detail: record.detail } : {},\n ...isString(record.detailZh) ? { detailZh: record.detailZh } : {},\n url: record.url,\n ...isString(record.homepage) ? { homepage: record.homepage } : {},\n ...(typeof record.skillCount === 'number' ? { skillCount: record.skillCount } : {}),\n ...(skills !== null ? { skills } : {}),\n })\n }\n return out.length > 0 ? out : null\n}\n\nfunction parseMcpIndex(parsed: unknown): MarketMcpServer[] | null {\n if (typeof parsed !== 'object' || parsed === null) return null\n const servers = (parsed as { servers?: unknown }).servers\n if (!Array.isArray(servers)) return null\n const out: MarketMcpServer[] = []\n for (const entry of servers) {\n if (typeof entry !== 'object' || entry === null) continue\n const record = entry as Record<string, unknown>\n if (!isString(record.id) || !isString(record.name) || !isString(record.description) || !isString(record.homepage)) continue\n const transport = record.transport === 'streamable-http' ? 'streamable-http' : 'stdio'\n if (transport === 'stdio' && !isString(record.command)) continue\n if (transport === 'streamable-http' && !isString(record.url)) continue\n out.push({\n id: record.id,\n name: record.name,\n ...isString(record.nameZh) ? { nameZh: record.nameZh } : {},\n description: record.description,\n ...isString(record.descriptionZh) ? { descriptionZh: record.descriptionZh } : {},\n transport,\n ...(isString(record.command) ? { command: record.command } : {}),\n ...(isStringArray(record.args) ? { args: record.args } : {}),\n ...(isStringArray(record.envKeys) ? { envKeys: record.envKeys } : {}),\n ...(isString(record.url) ? { url: record.url } : {}),\n homepage: record.homepage,\n ...isString(record.category) ? { category: record.category } : {},\n ...isString(record.runtime) ? { runtime: record.runtime } : {},\n ...isStringArray(record.tools) ? { tools: record.tools } : {},\n ...isString(record.detail) ? { detail: record.detail } : {},\n ...isString(record.detailZh) ? { detailZh: record.detailZh } : {},\n })\n }\n return out.length > 0 ? out : null\n}\n\nexport interface LoadMarketOptions {\n fetcher?: typeof fetch\n /** Remote fetch timeout; the bundled fallback has none. */\n timeoutMs?: number\n dshHome?: string\n}\n\n/** Load one market index: remote first, bundled snapshot as fallback. */\nexport async function loadMarketIndex(kind: MarketKind, options: LoadMarketOptions = {}): Promise<MarketIndex | null> {\n const doFetch = options.fetcher ?? fetch\n if (kind === 'skills') {\n const remote = await fetchIndex(doFetch, 'skills', parseSkillsIndex, options)\n if (remote !== null) return { source: 'remote', skills: remote }\n } else {\n const remote = await fetchIndex(doFetch, 'mcp', parseMcpIndex, options)\n if (remote !== null) return { source: 'remote', servers: remote }\n }\n const bundled = bundledMarketPath(kind)\n if (!existsSync(bundled)) return null\n try {\n const parsed: unknown = JSON.parse(readFileSync(bundled, 'utf8'))\n if (kind === 'skills') {\n const skills = parseSkillsIndex(parsed)\n return skills === null ? null : { source: 'bundled', skills }\n }\n const servers = parseMcpIndex(parsed)\n return servers === null ? null : { source: 'bundled', servers }\n } catch {\n return null\n }\n}\n\n/** Fetch and validate one remote index; null on any failure. */\nasync function fetchIndex<T>(\n doFetch: typeof fetch,\n kind: MarketKind,\n parse: (parsed: unknown) => T[] | null,\n options: LoadMarketOptions,\n): Promise<T[] | null> {\n try {\n const response = await doFetch(marketIndexUrl(kind), { signal: AbortSignal.timeout(options.timeoutMs ?? 8000) })\n if (!response.ok) return null\n return parse(await response.json())\n } catch {\n // Network unavailable or slow: the bundled snapshot takes over.\n return null\n }\n}\n", "/**\n * Open a directory in the OS file manager, from the dsh sidecar process.\n * Spawned detached with all stdio ignored \u2014 a GUI file manager needs no\n * pipes, and explorer.exe reports failure through exit codes we must not\n * await (it exits non-zero even on success in several Windows versions).\n */\n\nimport { spawn } from 'node:child_process'\nimport { statSync } from 'node:fs'\n\n/** Open one directory; resolves true when a launcher was started. */\nexport function openDirectory(dir: string): boolean {\n try {\n if (!statSync(dir).isDirectory()) return false\n } catch {\n return false\n }\n if (process.platform === 'win32') {\n // explorer \u5BF9\u6B63\u659C\u6760\u8DEF\u5F84\u4F1A\u9759\u9ED8\u56DE\u843D\u5230\u9ED8\u8BA4\u6587\u4EF6\u5939\uFF08\u5B9E\u6D4B\u6253\u5F00\u6210\u4E86\u300C\u6587\u6863\u300D\uFF09\uFF0C\u5FC5\u987B\u5582\u53CD\u659C\u6760\u3002\n dir = dir.split('/').join('\\\\')\n }\n const launcher = process.platform === 'win32' ? 'explorer' : process.platform === 'darwin' ? 'open' : 'xdg-open'\n try {\n // GUI \u542F\u52A8\u5668\u4E0D\u80FD\u5E26 windowsHide\uFF1A\u8BE5 flag \u628A SW_HIDE \u5199\u8FDB STARTUPINFO\uFF0Cexplorer \u7684\n // \u9996\u4E2A\u7A97\u53E3\u636E\u6B64\u521B\u5EFA\u4E3A\u9690\u85CF\u2014\u2014\u5B9E\u673A\u8868\u73B0\u662F\u300C\u6253\u5F00\u76EE\u5F55\u300D\u70B9\u4E86\u6CA1\u53CD\u5E94\uFF0C\u7A97\u53E3\u5176\u5B9E\u5F00\u4E86\u3002\n const child = spawn(launcher, [dir], { detached: true, stdio: 'ignore' })\n // \u542F\u52A8\u5668\u89E3\u6790\u5931\u8D25\u65F6 'error' \u5F02\u6B65\u5230\u8FBE\uFF1B\u6CA1\u6709\u76D1\u542C\u4F1A\u5347\u7EA7\u6210 uncaughtException \u70B8\u6389 sidecar\u3002\n child.once('error', () => {})\n child.unref()\n return true\n } catch {\n return false\n }\n}\n", "/**\n * Custom skill repositories the user registers from the Settings page:\n * a local directory (scanned in place, zero-copy) or a GitHub repo (tarball\n * download into the plugin's state dir, no git dependency). Detection adapts\n * to the three layouts skill collections actually use \u2014 one skill at the\n * repo root, skills as immediate children, or a nested `skills/`-style\n * folder \u2014 and registers the matching scan roots for the filesystem\n * provider.\n */\n\nimport { existsSync, mkdirSync, readFileSync, readdirSync, statSync, symlinkSync } from 'node:fs'\nimport { basename, join, resolve } from 'node:path'\nimport { removeTree } from './rmtree.ts'\nimport { addSkillRoot, findRootByUrl, materialDirFor, newEntryId, type SkillRootEntry } from './state.ts'\nimport { extractTarGz } from './tar.ts'\n\n/** One GitHub source, parsed from whatever URL shape the user pasted. */\nexport interface GitHubSource {\n owner: string\n repo: string\n ref?: string\n /** `owner/repo`, the display label and dedupe key. */\n label: string\n tarballUrl: string\n}\n\nconst GITHUB_URL_RE = /^(?:https?:\\/\\/)?github\\.com\\/([A-Za-z0-9_.-]+)\\/([A-Za-z0-9_.-]+?)(?:\\.git)?(?:\\/(?:tree|archive)\\/([^/#?]+?)(?:\\.tar\\.gz)?)?(?:#([^/?#]+))?(?:[/?#].*)?$/\nconst GITHUB_SHORT_RE = /^([A-Za-z0-9_.-]+)\\/([A-Za-z0-9_.-]+)$/\n\n/** Parse a GitHub reference; returns null for anything unrecognizable. */\nexport function parseGitHubSource(input: string): GitHubSource | null {\n const trimmed = input.trim()\n if (trimmed === '') return null\n let owner = ''\n let repo = ''\n let ref: string | undefined\n let match = GITHUB_URL_RE.exec(trimmed)\n if (match !== null) {\n // Capture order: owner, repo, /tree/<ref>, #<ref>.\n const treeRef = match[3] !== undefined ? match[3] : undefined\n const hashRef = match[4] !== undefined ? match[4] : undefined\n owner = match[1]\n repo = match[2]\n ref = treeRef ?? hashRef\n } else {\n match = GITHUB_SHORT_RE.exec(trimmed)\n if (match === null) return null\n ;[, owner, repo] = match\n ref = undefined\n }\n // `owner/repo/tree/<ref>` may URL-encode slashes in the ref \u2014 keep as-is;\n // codeload addresses refs by name, branches with slashes included.\n const decodedRef = ref !== undefined ? decodeURIComponent(ref) : undefined\n const label = `${owner}/${repo}`\n const tarballUrl = `https://codeload.github.com/${owner}/${repo}/tar.gz/${decodedRef ?? 'HEAD'}`\n return { owner, repo, ref: decodedRef, label, tarballUrl }\n}\n\n/** Where skill layouts were found inside one checkout. */\nexport interface DetectedRoots {\n /** Scan roots to register (empty + single=false means \u201Cno skills\u201D). */\n roots: string[]\n /** The checkout itself is one skill (SKILL.md at its root). */\n single: boolean\n}\n\n/** A plausible flat skill file: markdown with frontmatter. */\nfunction looksLikeSkillFile(file: string): boolean {\n try {\n return readFileSync(file, 'utf8').startsWith('---')\n } catch {\n return false\n }\n}\n\n/** Does one directory directly hold skills (bundle children or flat .md)? */\nfunction holdsSkills(dir: string): boolean {\n let entries: string[]\n try {\n entries = readdirSync(dir)\n } catch {\n return false\n }\n if (existsSync(join(dir, 'SKILL.md'))) return true\n for (const name of entries) {\n if (name.endsWith('.md') && looksLikeSkillFile(join(dir, name))) return true\n }\n for (const name of entries) {\n const child = join(dir, name)\n try {\n if (statSync(child).isDirectory() && existsSync(join(child, 'SKILL.md'))) return true\n } catch {\n // racing deletion or unreadable entry: ignore\n }\n }\n return false\n}\n\n/**\n * Find the scan roots for one checkout: the checkout itself when its\n * immediate children are skills, plus any child directory that only makes\n * sense as a collection wrapper (`skills/`, `document-skills/`, \u2026). A\n * checkout with SKILL.md at its own root is one single skill \u2014 the caller\n * must give the provider its PARENT as the scan root.\n */\nexport function detectSkillRoots(checkout: string): DetectedRoots {\n if (existsSync(join(checkout, 'SKILL.md'))) return { roots: [], single: true }\n const roots: string[] = []\n if (holdsSkills(checkout)) roots.push(checkout)\n let entries: string[]\n try {\n entries = readdirSync(checkout)\n } catch {\n return { roots, single: false }\n }\n for (const name of entries) {\n if (name.startsWith('.')) continue\n const child = join(checkout, name)\n try {\n if (!statSync(child).isDirectory()) continue\n } catch {\n continue\n }\n if (existsSync(join(child, 'SKILL.md'))) continue // already covered by the parent root\n if (holdsSkills(child)) roots.push(child)\n }\n return { roots, single: false }\n}\n\n/** Register a local directory as a skill repository. */\nexport async function addLocalRepo(path: string, dshHome?: string): Promise<SkillRootEntry> {\n const resolved = resolve(path.trim().replace(/^\"|\"$/g, ''))\n if (!existsSync(resolved) || !statSync(resolved).isDirectory()) {\n throw new Error(`not a directory: ${resolved}`)\n }\n const detected = detectSkillRoots(resolved)\n if (!detected.single && detected.roots.length === 0) {\n throw new Error('no SKILL.md found under that path (expected a skill folder or a folder of skill folders)')\n }\n if (detected.single) {\n // One skill living at the given path: the provider scans a ROOT, so wrap\n // the path in a dedicated directory holding a single link to it.\n const id = newEntryId('local')\n const material = materialDirFor(id, dshHome)\n removeTree(material)\n mkdirSync(material, { recursive: true })\n try {\n symlinkSync(resolved, join(material, 'skill'), process.platform === 'win32' ? 'junction' : 'dir')\n } catch {\n removeTree(material)\n throw new Error('single-skill local folders need a directory link; try adding their parent folder instead')\n }\n return addSkillRoot({ id, kind: 'local', label: basename(resolved), path: resolved, roots: [material], materialDir: material }, dshHome)\n }\n return addSkillRoot({ id: newEntryId('local'), kind: 'local', label: basename(resolved), path: resolved, roots: detected.roots }, dshHome)\n}\n\n/** Download cap for a repo tarball. */\nconst TARBALL_MAX_BYTES = 256 * 1024 * 1024\n\n/** Register a GitHub repo: tarball download \u2192 extract \u2192 detect \u2192 persist. */\nexport async function addGitRepo(\n url: string,\n options: { dshHome?: string; fetcher?: typeof fetch } = {},\n): Promise<SkillRootEntry> {\n const source = parseGitHubSource(url)\n if (source === null) throw new Error('expected a GitHub repository URL or owner/repo')\n const existing = findRootByUrl(source.label, options.dshHome)\n if (existing !== undefined) throw new Error(`${source.label} is already registered`)\n\n const doFetch = options.fetcher ?? fetch\n const response = await doFetch(source.tarballUrl, { signal: AbortSignal.timeout(60_000) })\n if (!response.ok) throw new Error(`download failed (HTTP ${response.status}) for ${source.tarballUrl}`)\n const archive = Buffer.from(await response.arrayBuffer())\n if (archive.byteLength > TARBALL_MAX_BYTES) throw new Error('repository tarball too large')\n\n const id = newEntryId('git')\n const material = materialDirFor(id, options.dshHome)\n removeTree(material)\n const checkout = join(material, 'repo')\n try {\n mkdirSync(checkout, { recursive: true })\n extractTarGz(archive, checkout, { stripComponents: 1 })\n const detected = detectSkillRoots(checkout)\n if (!detected.single && detected.roots.length === 0) {\n throw new Error('no SKILL.md found in that repository')\n }\n // A single-skill repo is discovered through the material dir itself; a\n // collection registers the checkout (plus nested collection wrappers).\n const roots = detected.single ? [material] : detected.roots\n return addSkillRoot(\n { id, kind: 'git', label: source.label, url: source.label, ref: source.ref, roots, materialDir: material },\n options.dshHome,\n )\n } catch (error) {\n removeTree(material)\n throw error\n }\n}\n\n/** Validate one scan root still exists; entries can go stale on disk. */\nexport function rootExists(path: string): boolean {\n try {\n return statSync(path).isDirectory()\n } catch {\n return false\n }\n}\n", "/**\n * Windows-hardened recursive delete for repository material. The skill\n * provider watches these trees live, and antivirus or search indexers\n * briefly hold handles onto freshly written files, so a plain rmSync\n * races open handles and dies with EPERM. Two mitigations: clear the\n * read-only attribute first (unlinking a read-only entry fails on\n * Windows), then retry the removal so short-lived locks run out.\n */\n\nimport { chmodSync, readdirSync, rmSync, type Dirent } from 'node:fs'\nimport { join } from 'node:path'\n\n/** Windows lock holders usually let go within a second or two. */\nconst RETRIES = { maxRetries: 10, retryDelay: 200 } as const\n\nfunction clearReadOnly(dir: string): void {\n let entries: Dirent[]\n try {\n entries = readdirSync(dir, { withFileTypes: true })\n } catch {\n return // unreadable: rmSync will surface the real error\n }\n for (const entry of entries) {\n const child = join(dir, entry.name)\n // Links read as neither file nor directory here; chmod would hit the\n // link TARGET (possibly the user's own folder), so they are skipped \u2014\n // rmSync removes the link itself without following it.\n if (entry.isDirectory()) {\n try { chmodSync(child, 0o777) } catch { /* racing delete */ }\n clearReadOnly(child)\n } else if (entry.isFile()) {\n try { chmodSync(child, 0o666) } catch { /* racing delete */ }\n }\n }\n try { chmodSync(dir, 0o777) } catch { /* racing delete */ }\n}\n\n/** Delete one directory tree (or lone file), tolerating Windows lock races. */\nexport function removeTree(path: string): void {\n try {\n clearReadOnly(path)\n } catch {\n // walk failure: rmSync reports the underlying error anyway\n }\n rmSync(path, { recursive: true, force: true, ...RETRIES })\n}\n", "/**\n * Plugin-owned state under `$DSH_HOME/dsh-plugin-capabilities/`: the custom\n * skill repositories the user registered from the Settings page. Everything\n * the provider mounts live (local paths, extracted GitHub checkouts) hangs\n * off this file, so it stays small, JSON, and hand-recoverable.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { randomBytes } from 'node:crypto'\n\n/** One user-registered custom skill repository. */\nexport interface SkillRootEntry {\n /** Stable id (used by the remove route and directory names). */\n id: string\n /** `local` \u2014 a path on this machine; `git` \u2014 extracted from a GitHub URL. */\n kind: 'local' | 'git'\n /** Display label (repo `owner/name` or the local path's basename). */\n label: string\n /** The source URL (git entries). */\n url?: string\n /** Branch/tag/ref the tarball was pulled from (git entries). */\n ref?: string\n /** Local path the user pointed at (local entries). */\n path?: string\n /** Scan roots this entry contributes (single-skill repos get a wrapper dir). */\n roots: string[]\n /** Where this entry's downloaded/junctioned material lives, if any. */\n materialDir?: string\n addedAt: number\n}\n\n/** On-disk state document. */\nexport interface PluginState {\n skillRoots: SkillRootEntry[]\n}\n\n/** The plugin's own directory under DSH_HOME (default `~/.dsh`). */\nexport function pluginStateDir(dshHome: string | undefined = process.env.DSH_HOME): string {\n return join(dshHome ?? join(homedir(), '.dsh'), 'dsh-plugin-capabilities')\n}\n\nfunction statePath(dshHome?: string): string {\n return join(pluginStateDir(dshHome), 'state.json')\n}\n\nfunction emptyState(): PluginState {\n return { skillRoots: [] }\n}\n\n/** Load the state document; missing/corrupt files yield empty state. */\nexport function loadState(dshHome?: string): PluginState {\n const path = statePath(dshHome)\n if (!existsSync(path)) return emptyState()\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf8')) as Partial<PluginState>\n if (!Array.isArray(parsed.skillRoots)) return emptyState()\n const roots = parsed.skillRoots.filter((entry): entry is SkillRootEntry =>\n typeof entry === 'object' && entry !== null && typeof entry.id === 'string' && Array.isArray(entry.roots))\n return { skillRoots: roots }\n } catch {\n return emptyState()\n }\n}\n\n/** Persist the state document (atomic-enough for a single-writer UI). */\nexport function saveState(state: PluginState, dshHome?: string): void {\n const dir = pluginStateDir(dshHome)\n mkdirSync(dir, { recursive: true })\n writeFileSync(statePath(dshHome), JSON.stringify(state, null, 2) + '\\n', 'utf8')\n}\n\n/** New unique entry id. */\nexport function newEntryId(kind: 'local' | 'git'): string {\n return `${kind}-${randomBytes(4).toString('hex')}`\n}\n\n/** One entry's downloaded material (git extraction, junction wrappers). */\nexport function materialDirFor(entryId: string, dshHome?: string): string {\n return join(pluginStateDir(dshHome), 'repos', entryId)\n}\n\n/** Append one entry and persist. Returns the stored entry. */\nexport function addSkillRoot(entry: Omit<SkillRootEntry, 'addedAt'>, dshHome?: string): SkillRootEntry {\n const state = loadState(dshHome)\n const stored: SkillRootEntry = { ...entry, addedAt: Date.now() }\n state.skillRoots.push(stored)\n saveState(state, dshHome)\n return stored\n}\n\n/**\n * Deregister one entry by id and persist immediately. The material dir is\n * deliberately NOT deleted here: the skill provider still watches it, and\n * removing a watched tree on Windows fails with EPERM even though the\n * state is already saved. The caller unmounts (remountProvider) first,\n * then runs removeTree over the returned entry's materialDir. Returns the\n * removed entry, or undefined when the id is unknown.\n */\nexport function removeSkillRoot(id: string, dshHome?: string): SkillRootEntry | undefined {\n const state = loadState(dshHome)\n const at = state.skillRoots.findIndex(entry => entry.id === id)\n if (at === -1) return undefined\n const [removed] = state.skillRoots.splice(at, 1)\n saveState(state, dshHome)\n return removed\n}\n\n/** Whether a git URL is already registered (market \u201Cinstalled\u201D state). */\nexport function findRootByUrl(url: string, dshHome?: string): SkillRootEntry | undefined {\n return loadState(dshHome).skillRoots.find(entry => entry.url === url)\n}\n", "/**\n * Minimal pure-JS tar.gz extraction (node zlib + a USTAR/GNU/PAX-path\n * reader). GitHub codeload tarballs are all we ever unpack \u2014 regular files\n * and directories, no links \u2014 so unsupported entry types are skipped rather\n * than rejected, and every name is checked against escape before it touches\n * the filesystem. No subprocess: the dsh sidecar must not spawn tar.\n */\n\nimport { gunzipSync } from 'node:zlib'\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\n\n/** Guard rails for untrusted archives. */\nconst LIMITS = {\n /** Per-entry cap (a skill repo holds markdown and small assets). */\n entryBytes: 64 * 1024 * 1024,\n /** Whole-archive content cap. */\n totalBytes: 256 * 1024 * 1024,\n /** Entry count cap (also bounds loop time on corrupt input). */\n entries: 20_000,\n} as const\n\nfunction octal(block: Buffer, offset: number, length: number): number {\n const raw = block.toString('utf8', offset, offset + length).replace(/[\\0 ]+$/, '')\n return raw === '' ? 0 : Number.parseInt(raw, 8)\n}\n\nfunction field(block: Buffer, offset: number, length: number): string {\n const at = block.indexOf(0, offset)\n return block.toString('utf8', offset, Math.min(at === -1 ? offset + length : at, offset + length))\n}\n\n/** One parsed tar header. */\ninterface TarHeader {\n name: string\n size: number\n type: string\n}\n\nfunction readHeader(block: Buffer): TarHeader | null {\n // A zeroed block ends the archive (the checksum of an empty block is 0).\n if (block.every(byte => byte === 0)) return null\n const checksum = octal(block, 148, 8)\n let sum = 0\n for (let at = 0; at < 512; at++) sum += at >= 148 && at < 156 ? 32 : block[at]\n if (sum !== checksum) return null\n const magic = block.toString('utf8', 257, 257 + 6)\n let name = field(block, 0, 100)\n if (magic.startsWith('ustar')) {\n const prefix = field(block, 345, 155)\n if (prefix !== '') name = `${prefix}/${name}`\n }\n return { name, size: octal(block, 124, 12), type: block.toString('utf8', 156, 157) }\n}\n\n/** Resolve one entry name under the target, rejecting escapes. */\nfunction safeJoin(target: string, name: string): string | null {\n const normalized = name.replace(/\\\\/g, '/')\n if (normalized.startsWith('/') || /^[A-Za-z]:/.test(normalized)) return null\n const parts: string[] = []\n for (const part of normalized.split('/')) {\n if (part === '' || part === '.') continue\n if (part === '..') return null\n parts.push(part)\n }\n if (parts.length === 0) return null\n return join(target, ...parts)\n}\n\n/** PAX extended header records (`<len> key=value\\n` lines) \u2192 key/value map. */\nfunction paxRecords(content: Buffer): Map<string, string> {\n const out = new Map<string, string>()\n let cursor = 0\n while (cursor < content.length) {\n const spaceAt = content.indexOf(' ', cursor)\n if (spaceAt === -1) break\n const length = Number.parseInt(content.toString('utf8', cursor, spaceAt), 10)\n if (!Number.isInteger(length) || length <= 0 || cursor + length > content.length) break\n const record = content.toString('utf8', spaceAt + 1, cursor + length).trimEnd()\n const eq = record.indexOf('=')\n if (eq > 0) out.set(record.slice(0, eq), record.slice(eq + 1))\n cursor += length\n }\n return out\n}\n\n/** Number of leading path components to drop (GitHub tarballs wrap one). */\nexport interface ExtractOptions {\n stripComponents?: number\n}\n\n/**\n * Extract a gzip'd tar buffer into `target` (created when absent). Returns\n * the entry count written. Throws on structure errors and oversize archives.\n */\nexport function extractTarGz(archive: Buffer, target: string, options: ExtractOptions = {}): number {\n const tar = gunzipSync(archive)\n const strip = options.stripComponents ?? 0\n let offset = 0\n let written = 0\n let total = 0\n let pendingLongName: string | undefined\n let pendingPath: string | undefined\n while (offset + 512 <= tar.length) {\n const header = readHeader(tar.subarray(offset, offset + 512))\n if (header === null) break\n offset += 512\n const contentEnd = offset + header.size\n if (contentEnd > tar.length) throw new Error('truncated tar entry')\n const content = tar.subarray(offset, contentEnd)\n offset += Math.ceil(header.size / 512) * 512\n if (header.size > LIMITS.entryBytes) throw new Error('tar entry too large')\n total += header.size\n if (total > LIMITS.totalBytes) throw new Error('tar archive too large')\n if (++written > LIMITS.entries) throw new Error('too many tar entries')\n\n // Metadata entries carry the name for the entry that follows.\n if (header.type === 'L') {\n pendingLongName = field(content, 0, content.length)\n continue\n }\n if (header.type === 'x' || header.type === 'X') {\n pendingPath = paxRecords(content).get('path')\n continue\n }\n if (header.type === 'g') continue // global pax: nothing we need\n\n let name = pendingLongName ?? pendingPath ?? header.name\n pendingLongName = undefined\n pendingPath = undefined\n\n const parts = name.split('/')\n if (parts.length <= strip) continue // nothing left after stripping\n name = parts.slice(strip).join('/')\n // The stripped top-level directory itself (\"pkg/\" \u2192 \"\") owns nothing.\n if (name === '' || name === '/') continue\n\n // Directories: type '5' or a trailing slash. Symlinks/hardlinks/other\n // types are skipped \u2014 skill repos that depend on them degrade loudly\n // elsewhere instead of planting links from untrusted input.\n const isDir = header.type === '5' || (header.type === '0' || header.type === '\\0') && name.endsWith('/')\n if (header.type !== '0' && header.type !== '\\0' && header.type !== '5') continue\n\n const resolved = safeJoin(target, name)\n if (resolved === null) throw new Error(`unsafe tar entry name: ${name}`)\n if (isDir) {\n mkdirSync(resolved, { recursive: true })\n continue\n }\n mkdirSync(dirname(resolved), { recursive: true })\n writeFileSync(resolved, content)\n }\n return written\n}\n", "/**\n * Self-restart for standalone `dsh web`: relaunch the exact invocation that\n * booted this host, then stop this process \u2014 so MCP row changes compose\n * without leaving the UI. The desktop shell owns restarts there\n * (DSH_DESKTOP=1 refuses this path \u2014 a supervised sidecar must never\n * replace itself, or the supervisor respawns a second process).\n *\n * The replacement is spawned directly with windowsHide: CREATE_NO_WINDOW\n * gives it a hidden console its own console children inherit (no popping\n * windows), unlike a DETACHED_PROCESS spawn which leaves children to create\n * visible consoles. No helper process and no powershell wrapper \u2014 on at\n * least one machine a node\u2192node\u2192powershell\u2192node chain was silently blocked\n * by host software before the inner node could even start, while direct\n * node\u2192node spawns are the most battle-tested pattern there is.\n */\n\nimport { spawn } from 'node:child_process'\nimport { openSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { dirname, resolve } from 'node:path'\nimport type { IncomingMessage } from 'node:http'\n\n/** The boot invocation to replay: entry from argv, execArgv preserved. */\nexport function dshLaunch(argv: readonly string[] = process.argv, execArgv: readonly string[] = process.execArgv): {\n file: string\n args: string[]\n cwd: string | undefined\n viaShell: boolean\n} {\n const entry = argv[1]\n if (entry !== undefined && /[\\\\/](?:bin\\.(?:js|ts)|dsh)$/.test(entry)) {\n // Source launches (`pnpm dsh`) pass a relative entry that the child would\n // resolve against its OWN cwd \u2014 absolutize, and keep cwd near the entry\n // so execArgv module hooks (tsx/esm) stay resolvable.\n const abs = resolve(entry)\n return { file: process.execPath, args: [...execArgv, abs, ...argv.slice(2)], cwd: dirname(abs), viaShell: false }\n }\n // Bare `dsh` on Windows is a .cmd shim only a shell can start.\n return { file: 'dsh', args: [...argv.slice(2)], cwd: undefined, viaShell: process.platform === 'win32' }\n}\n\n/**\n * Relaunch this exact dsh invocation, then stop this process. The replacement\n * boots slowly (module loading) while this process dies within 500 ms, so\n * port handover needs no delay even for fixed-port launches. Replacement\n * output is logged under tmpdir for post-mortem.\n */\nexport function scheduleRestart(launch: ReturnType<typeof dshLaunch>): {\n pid: number\n replacementPid: number | undefined\n logOut: string\n logErr: string\n} {\n const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19)\n const logOut = `${tmpdir()}${tmpdir().endsWith('/') ? '' : '\\\\'}dsh-plugin-capabilities-restart-${stamp}.out.log`\n const logErr = logOut.replace('.out.log', '.err.log')\n const child = spawn(launch.file, launch.args, {\n cwd: launch.cwd,\n stdio: ['ignore', openSync(logOut, 'a'), openSync(logErr, 'a')],\n env: process.env,\n shell: launch.viaShell,\n windowsHide: true,\n })\n child.unref()\n setTimeout(() => process.kill(process.pid, 'SIGTERM'), 500)\n return { pid: process.pid, replacementPid: child.pid, logOut, logErr }\n}\n\n/**\n * A restart request is process control: only a direct same-origin loopback\n * request qualifies. Any forwarding trace means the loopback peer is a\n * proxy, not the user's browser.\n */\nexport function trustedRestartRequest(request: IncomingMessage, socketAddress?: string): boolean {\n const address = socketAddress ?? (request.socket.remoteAddress ?? '')\n if (address !== '127.0.0.1' && address !== '::1' && address !== '::ffff:127.0.0.1') return false\n if (request.headers.forwarded !== undefined\n || request.headers['x-forwarded-for'] !== undefined\n || request.headers['x-real-ip'] !== undefined) return false\n const origin = request.headers.origin\n const host = request.headers.host\n if (origin === undefined || host === undefined) return false\n try {\n const parsed = new URL(origin)\n return (parsed.protocol === 'http:' || parsed.protocol === 'https:') && parsed.host === host\n } catch {\n return false\n }\n}\n\n/** Restart ownership: the desktop shell supervises the sidecar and restarts it. */\nexport function restartOwnedByShell(env: NodeJS.ProcessEnv = process.env): boolean {\n return env.DSH_DESKTOP === '1'\n}\n", "/**\n * Skill catalog plumbing: frontmatter serialization for user-root SKILL.md\n * files plus create/update/delete against `$DSH_HOME/skills`. Discovery is the\n * host's business \u2014 the filesystem provider watches the directory, so writes\n * land in the catalog without any restart.\n */\n\nimport { existsSync, mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\n/** Host skill name grammar (dsh-skill's SKILL_NAME). */\nexport const SKILL_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/\n\n/** One skill write request from the browser. */\nexport interface SkillInput {\n name: string\n description: string\n whenToUse?: string\n modelInvocable: boolean\n userInvocable: boolean\n content: string\n}\n\n/** The user-owned skill root this plugin writes into (provider rank 400). */\nexport function userSkillsDir(dshHome: string | undefined = process.env.DSH_HOME): string {\n return join(dshHome ?? join(homedir(), '.dsh'), 'skills')\n}\n\n/** YAML double-quoted scalar (JSON string syntax is valid YAML 1.2). */\nfunction quote(value: string): string {\n return JSON.stringify(value)\n}\n\n/** Frontmatter + body for one skill file. Policy keys only when non-default. */\nexport function serializeSkill(input: SkillInput): string {\n const lines = [\n `name: ${input.name}`,\n `description: ${quote(input.description)}`,\n ]\n if (input.whenToUse !== undefined && input.whenToUse !== '') lines.push(`whenToUse: ${quote(input.whenToUse)}`)\n if (!input.modelInvocable) lines.push('disable-model-invocation: true')\n if (!input.userInvocable) lines.push('user-invocable: false')\n const body = input.content.replace(/\\r\\n/g, '\\n').trim()\n return `---\\n${lines.join('\\n')}\\n---\\n\\n${body}\\n`\n}\n\n/** Validate one write request; returns the rejection reason or null. */\nexport function validateSkillInput(input: SkillInput): string | null {\n if (!SKILL_NAME_RE.test(input.name)) return 'name must be kebab-case (a-z, 0-9, dashes)'\n if (input.description.trim() === '') return 'description is required'\n if (input.description.length > 1024) return 'description too long (max 1024)'\n if (input.whenToUse !== undefined && input.whenToUse.length > 2048) return 'whenToUse too long (max 2048)'\n if (input.content.length > 256 * 1024) return 'content too large (max 256 KiB)'\n return null\n}\n\n/** Directory holding one user skill's SKILL.md; name grammar blocks traversal. */\nfunction skillDir(name: string, dshHome?: string): string {\n return join(userSkillsDir(dshHome), name)\n}\n\n/** Create or update a user skill. Returns the written path. */\nexport function writeSkill(input: SkillInput, dshHome?: string): string {\n const dir = skillDir(input.name, dshHome)\n mkdirSync(dir, { recursive: true })\n const file = join(dir, 'SKILL.md')\n writeFileSync(file, serializeSkill(input), 'utf8')\n return file\n}\n\n/** Delete a user skill directory. Returns false when it does not exist. */\nexport function deleteSkill(name: string, dshHome?: string): boolean {\n if (!SKILL_NAME_RE.test(name)) return false\n const dir = skillDir(name, dshHome)\n if (!existsSync(dir) || !statSync(dir).isDirectory()) return false\n // Only ever remove the exact directory this name resolves to under the\n // skills root; the regex already pins it to one safe path segment.\n rmSync(dir, { recursive: true, force: true })\n return true\n}\n\n/**\n * Flip one skill file's load policy by editing only the two invocation keys\n * in its frontmatter \u2014 `disable-model-invocation: true` plus\n * `user-invocable: false` together take the skill out of both the model and\n * the human catalogs on every standard-provider surface; enabling removes\n * both keys (defaults permit both surfaces). Works on any file-backed skill\n * (user, project, agent, bundled, custom); the rest of the file, including\n * custom keys, ordering, and body, survives byte-for-byte.\n */\nexport function setSkillPolicy(file: string, enabled: boolean): void {\n const text = readFileSync(file, 'utf8')\n const match = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/.exec(text)\n if (match === null) throw new Error('skill file has no frontmatter block')\n const newline = text.includes('\\r\\n---') ? '\\r\\n' : '\\n'\n const body = text.slice(match[0].length)\n const lines = match[1].split(/\\r?\\n/)\n const kept = lines.filter(line => !/^(disable-model-invocation|user-invocable):/.test(line))\n if (!enabled) kept.push('disable-model-invocation: true', 'user-invocable: false')\n writeFileSync(file, `---${newline}${kept.join(newline)}${newline}---${body}`, 'utf8')\n}\n\n/**\n * Edit an existing skill file in place \u2014 for skills that do not live in the\n * user root (market/custom repositories). Only the keys the editor owns\n * (name, description, whenToUse, the two invocation flags) are rewritten;\n * every other frontmatter key \u2014 license, allowed-tools, anything a\n * repository ships \u2014 survives in order, like setSkillPolicy. The body is\n * replaced by the editor's content.\n */\nexport function updateSkillFile(file: string, input: SkillInput): void {\n const text = readFileSync(file, 'utf8')\n const match = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/.exec(text)\n if (match === null) throw new Error('skill file has no frontmatter block')\n const newline = text.includes('\\r\\n---') ? '\\r\\n' : '\\n'\n const lines = match[1].split(/\\r?\\n/)\n const kept = lines.filter(line => !/^(name|description|whenToUse|disable-model-invocation|user-invocable):/.test(line))\n const head = [`name: ${input.name}`, `description: ${quote(input.description)}`]\n if (input.whenToUse !== undefined && input.whenToUse !== '') head.push(`whenToUse: ${quote(input.whenToUse)}`)\n if (!input.modelInvocable) kept.push('disable-model-invocation: true')\n if (!input.userInvocable) kept.push('user-invocable: false')\n const body = input.content.replace(/\\r\\n/g, '\\n').trim()\n writeFileSync(file, `---${newline}${[...head, ...kept].join(newline)}${newline}---${newline}${newline}${body}${newline}`, 'utf8')\n}\n", "/**\n * MCP server rows in the profile's own patch layer: one\n * `@deepseek-ai/dsh-mcp-client` row per server. The YAML document API keeps\n * foreign rows and comments intact across edits. Row changes need a dsh\n * restart to compose \u2014 callers surface that as a pending-restart notice.\n *\n * The loader's patch grammar distinguishes creates from overrides: a bare\n * `- id: \u2026` entry only overrides an existing row (target missing \u2192 skipped\n * with a warning), while new rows must live in an anonymous `- insert:`\n * list. Managed rows therefore always sit inside one insert entry, and any\n * legacy bare rows (written before this contract was understood) are\n * absorbed into it on the next write.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { parseDocument, Document, type YAMLMap, type YAMLSeq } from 'yaml'\n/** The plugin every managed row instantiates. */\nexport const MCP_PLUGIN = '@deepseek-ai/dsh-mcp-client'\n\n/** MCP serverName grammar (dsh-mcp-client's contract). */\nexport const SERVER_NAME_RE = /^[A-Za-z0-9_-]{1,32}$/\n\n/** Transport choices the client supports. */\nexport type McpTransport = 'stdio' | 'streamable-http'\n\n/** One managed row, as shown to the browser. */\nexport interface McpRow {\n id: string\n serverName: string\n transport: McpTransport\n disabled: boolean\n command?: string\n args?: string[]\n env?: Record<string, string>\n cwd?: string\n url?: string\n headers?: Record<string, string>\n}\n\n/** Write request for one server row (id empty = create). */\nexport type McpInput = Omit<McpRow, 'disabled'> & { disabled?: boolean }\n\n/**\n * Refuse to touch a patch file the parser could not fully read. parseDocument\n * parks syntax errors in doc.errors (it does not throw), and the failure only\n * resurfaces at String(doc) as the internals-leaking \"Document with errors\n * cannot be stringified\". Nothing gets written either way, but the banner must\n * say what is actually wrong and which file to fix.\n */\nfunction assertPatchParses(path: string, doc: Document): void {\n if (doc.errors.length === 0) return\n const at = String(doc.errors[0].message).split('\\n', 1)[0]\n const total = doc.errors.length > 1 ? `, +${doc.errors.length - 1} more` : ''\n throw new Error(\n `\u914D\u7F6E\u6587\u4EF6 ${path} \u5B58\u5728 YAML \u8BED\u6CD5\u9519\u8BEF\uFF08${at}${total}\uFF09\uFF0C\u672A\u5199\u5165\u4EFB\u4F55\u5185\u5BB9\uFF0C\u8BF7\u4FEE\u590D\u8BE5\u6587\u4EF6\u540E\u91CD\u8BD5`\n + ` / YAML syntax error in the patch file (${at}${total}); nothing was written \u2014 fix it and retry`,\n )\n}\n\n/** Load the profile patch as a YAML document; `[]` for a missing file. */\nfunction loadPatch(profileDirPath: string): Document {\n const path = join(profileDirPath, 'cordis.patch.yml')\n const text = existsSync(path) ? readFileSync(path, 'utf8') : '[]'\n const doc = parseDocument(text)\n assertPatchParses(path, doc)\n const contents = doc.contents as YAMLSeq | null\n // The default-empty file parses as a flow `[]`; the patch layer is\n // human-edited block YAML, so flip the flag before anything appends.\n if (contents !== null && contents.flow === true && contents.items.length === 0) contents.flow = false\n return doc\n}\n\nfunction savePatch(profileDirPath: string, doc: Document): void {\n mkdirSync(profileDirPath, { recursive: true })\n writeFileSync(join(profileDirPath, 'cordis.patch.yml'), String(doc), 'utf8')\n}\n\n/** Wrap a plain value into a YAML node (yaml v2 exposes no standalone createNode). */\nfunction toNode<T>(value: unknown): T {\n return new Document(value as never).contents as T\n}\n\n/** The patch row sequence; an empty file's null root becomes an empty seq. */\nfunction rowSeq(doc: Document): YAMLSeq<YAMLMap> {\n if (doc.contents === null) {\n doc.contents = toNode<YAMLSeq<YAMLMap>>([])\n // An empty seq defaults to flow style (`[]`); the file must stay block.\n ;(doc.contents as YAMLSeq).flow = false\n }\n return doc.contents as YAMLSeq<YAMLMap>\n}\n\nfunction isSeqNode(value: unknown): value is YAMLSeq<YAMLMap> {\n return typeof value === 'object' && value !== null && Array.isArray((value as YAMLSeq).items)\n}\n\n/** A patch entry's insert list when it is the anonymous create form. */\nfunction insertListOf(item: YAMLMap): YAMLSeq<YAMLMap> | undefined {\n if (item.has('id')) return undefined\n const node = item.get('insert')\n return isSeqNode(node) ? node : undefined\n}\n\n/** Every managed row: legacy bare entries (no list) and insert-list rows. */\nfunction mcpRowItems(doc: Document): { node: YAMLMap, list?: YAMLSeq<YAMLMap> }[] {\n const found: { node: YAMLMap, list?: YAMLSeq<YAMLMap> }[] = []\n for (const item of rowSeq(doc).items ?? []) {\n if (item.get('name') === MCP_PLUGIN) found.push({ node: item })\n const list = insertListOf(item)\n for (const row of list?.items ?? []) {\n if (row.get('name') === MCP_PLUGIN) found.push({ node: row, list })\n }\n }\n return found\n}\n\n/** Map one row node to its browser-facing shape. */\nfunction rowToMcp(doc: Document, item: YAMLMap): McpRow {\n // config is a YAMLMap node \u2014 materialize it before property access.\n const configNode = item.get('config') as unknown\n const plain = (typeof configNode === 'object' && configNode !== null && typeof (configNode as { toJS?: unknown }).toJS === 'function'\n ? (configNode as { toJS(document: Document): unknown }).toJS(doc)\n : {}) as Record<string, unknown>\n return {\n id: String(item.get('id') ?? ''),\n serverName: String(plain.serverName ?? ''),\n transport: plain.transport === 'streamable-http' ? 'streamable-http' : 'stdio',\n disabled: item.get('disabled') === true,\n ...(typeof plain.command === 'string' && plain.command !== '' ? { command: plain.command } : {}),\n ...(Array.isArray(plain.args) ? { args: plain.args.map(String) } : {}),\n ...(isStringMap(plain.env) ? { env: plain.env } : {}),\n ...(typeof plain.cwd === 'string' && plain.cwd !== '' ? { cwd: plain.cwd } : {}),\n ...(typeof plain.url === 'string' && plain.url !== '' ? { url: plain.url } : {}),\n ...(isStringMap(plain.headers) ? { headers: plain.headers } : {}),\n }\n}\n\nfunction isStringMap(value: unknown): value is Record<string, string> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false\n return Object.values(value).every(entry => typeof entry === 'string')\n}\n\n/**\n * The insert list that owns managed rows, creating it when absent and\n * absorbing legacy bare rows into it. Absorbed rows were inert under the\n * loader's override-only reading of bare entries, so the move is not just\n * cosmetic \u2014 it is what makes them compose.\n */\nfunction managedInsert(doc: Document): YAMLSeq<YAMLMap> {\n const seq = rowSeq(doc)\n const bare: YAMLMap[] = []\n let target: YAMLSeq<YAMLMap> | undefined\n for (const item of seq.items ?? []) {\n if (item.get('name') === MCP_PLUGIN) bare.push(item)\n const list = insertListOf(item)\n if (list !== undefined && list.items.some(row => row.get('name') === MCP_PLUGIN)) target ??= list\n }\n if (target === undefined) {\n const entry = toNode<YAMLMap>({ insert: [] })\n seq.add(entry)\n target = entry.get('insert') as YAMLSeq<YAMLMap>\n target.flow = false\n }\n for (const row of bare) {\n seq.items.splice(seq.items.indexOf(row), 1)\n target.add(row)\n }\n return target\n}\n\n/** Every id in use: top-level patch entries and rows inside insert lists. */\nfunction takenIds(doc: Document): Set<string> {\n const taken = new Set<string>()\n for (const item of rowSeq(doc).items ?? []) {\n const id = String(item.get('id') ?? '')\n if (id !== '') taken.add(id)\n for (const row of insertListOf(item)?.items ?? []) {\n const rowId = String(row.get('id') ?? '')\n if (rowId !== '') taken.add(rowId)\n }\n }\n return taken\n}\n\n/** Read every mcp-client row in the profile layer. */\nexport function listMcp(profileDirPath: string): McpRow[] {\n const doc = loadPatch(profileDirPath)\n return mcpRowItems(doc).map(({ node }) => rowToMcp(doc, node))\n}\n\n/** Validate one write request; returns the rejection reason or null. */\nexport function validateMcpInput(input: McpInput): string | null {\n if (!SERVER_NAME_RE.test(input.serverName)) return 'serverName must be 1-32 chars of A-Z a-z 0-9 _ -'\n // The route casts raw JSON to McpInput; a create request may omit `id`.\n const id = input.id ?? ''\n if (id.includes('/') || id.includes('..')) return 'invalid id'\n if (input.transport === 'stdio') {\n if (input.command === undefined || input.command.trim() === '') return 'stdio transport requires a command'\n } else if (input.url === undefined || !/^https?:\\/\\//.test(input.url)) {\n return 'http transport requires an http(s) url'\n }\n return null\n}\n\n/** Add or replace one server row. Returns the (possibly deduplicated) id. */\nexport function upsertMcp(profileDirPath: string, input: McpInput): string {\n const inputId = input.id ?? ''\n const doc = loadPatch(profileDirPath)\n const list = managedInsert(doc)\n\n const existing = inputId !== ''\n ? mcpRowItems(doc).find(({ node }) => String(node.get('id') ?? '') === inputId)\n : undefined\n\n let id = inputId !== '' ? inputId : `mcp-${input.serverName}`\n if (existing === undefined) {\n const taken = takenIds(doc)\n let suffix = 2\n while (taken.has(id)) id = `mcp-${input.serverName}-${suffix++}`\n }\n\n const config: Record<string, unknown> = input.transport === 'stdio'\n ? {\n serverName: input.serverName,\n transport: input.transport,\n command: input.command,\n ...(input.args !== undefined && input.args.length > 0 ? { args: input.args } : {}),\n ...(input.env !== undefined && Object.keys(input.env).length > 0 ? { env: input.env } : {}),\n ...(input.cwd !== undefined && input.cwd !== '' ? { cwd: input.cwd } : {}),\n }\n : {\n serverName: input.serverName,\n transport: input.transport,\n url: input.url,\n ...(input.headers !== undefined && Object.keys(input.headers).length > 0 ? { headers: input.headers } : {}),\n }\n const row: Record<string, unknown> = { id, name: MCP_PLUGIN, config }\n if (input.disabled === true) row.disabled = true\n\n const node = toNode<YAMLMap>(row)\n if (existing === undefined) {\n list.add(node)\n } else if (existing.list !== undefined) {\n existing.list.items.splice(existing.list.items.indexOf(existing.node), 1, node)\n } else {\n // Bare rows were absorbed above; reaching here means a foreign-shaped row.\n rowSeq(doc).items.splice(rowSeq(doc).items.indexOf(existing.node), 1, node)\n }\n\n savePatch(profileDirPath, doc)\n return id\n}\n\n/** Flip one row's disabled flag (absent = enabled). Returns false when missing. */\nexport function setMcpDisabled(profileDirPath: string, id: string, disabled: boolean): boolean {\n const doc = loadPatch(profileDirPath)\n managedInsert(doc)\n const hit = mcpRowItems(doc).find(({ node }) => String(node.get('id') ?? '') === id)\n if (hit === undefined) return false\n if (disabled) hit.node.set('disabled', true)\n else hit.node.delete('disabled')\n savePatch(profileDirPath, doc)\n return true\n}\n\n/** Remove one server row. Returns false when missing. */\nexport function removeMcp(profileDirPath: string, id: string): boolean {\n const doc = loadPatch(profileDirPath)\n managedInsert(doc)\n const hit = mcpRowItems(doc).find(({ node }) => String(node.get('id') ?? '') === id)\n if (hit === undefined || hit.list === undefined) return false\n hit.list.items.splice(hit.list.items.indexOf(hit.node), 1)\n\n // An insert entry left with no rows is dead weight; drop it when the\n // insert list is all it holds.\n const seq = rowSeq(doc)\n const owner = (seq.items ?? []).find(item => insertListOf(item) === hit.list)\n if (owner !== undefined && hit.list.items.length === 0 && owner.items.length === 1) {\n seq.items.splice(seq.items.indexOf(owner), 1)\n }\n\n savePatch(profileDirPath, doc)\n return true\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["existsSync", "dirname", "join", "fileURLToPath", "sep", "name", "homedir", "join", "mkdirSync", "join", "existsSync", "readFileSync", "join", "parse", "existsSync", "mkdirSync", "readFileSync", "readdirSync", "statSync", "join", "join", "existsSync", "readFileSync", "homedir", "join", "mkdirSync", "writeFileSync", "dirname", "join", "name", "readFileSync", "readdirSync", "existsSync", "join", "name", "statSync", "mkdirSync", "spawn", "dirname", "resolve", "existsSync", "mkdirSync", "readFileSync", "rmSync", "statSync", "writeFileSync", "homedir", "join", "name", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "join", "node", "name", "join", "mkdirSync", "join", "dirname", "fileURLToPath", "existsSync"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-capabilities",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"description": "Manage skills and MCP servers from the Web UI Settings. 在设置页管理 dsh 的技能与 MCP 服务器。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"@deepseek-ai/cordis": "^4.0.1"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@deepseek-ai/dsh-skill-filesystem": "^0.1.
|
|
65
|
+
"@deepseek-ai/dsh-skill-filesystem": "^0.1.1-rc.1",
|
|
66
66
|
"dompurify": "^3.4.13",
|
|
67
67
|
"marked": "^18.0.10",
|
|
68
68
|
"smol-toml": "^1.3.1",
|
package/src/mcp.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
1
|
+
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
2
2
|
import { tmpdir } from 'node:os'
|
|
3
3
|
import { join } from 'node:path'
|
|
4
4
|
import { afterAll, describe, expect, it } from 'vitest'
|
|
@@ -133,3 +133,19 @@ describe('profile patch CRUD', () => {
|
|
|
133
133
|
expect(listMcp(profile)).toHaveLength(0)
|
|
134
134
|
})
|
|
135
135
|
})
|
|
136
|
+
|
|
137
|
+
describe('corrupt patch file', () => {
|
|
138
|
+
it('fails reads and writes with the file path and parser location, writing nothing', () => {
|
|
139
|
+
// GitHub issue #1: a malformed cordis.patch.yml surfaced as the raw
|
|
140
|
+
// "Document with errors cannot be stringified" when a write hit String(doc).
|
|
141
|
+
const brokenDir = join(root, 'profiles', 'broken')
|
|
142
|
+
mkdirSync(brokenDir, { recursive: true })
|
|
143
|
+
writeFileSync(join(brokenDir, 'cordis.patch.yml'), 'foo: 1\n bar: 2\n', 'utf8')
|
|
144
|
+
const before = readFileSync(join(brokenDir, 'cordis.patch.yml'), 'utf8')
|
|
145
|
+
|
|
146
|
+
expect(() => listMcp(brokenDir)).toThrow(/cordis\.patch\.yml/)
|
|
147
|
+
expect(() => listMcp(brokenDir)).toThrow(/line 1/)
|
|
148
|
+
expect(() => upsertMcp(brokenDir, stdio)).toThrow(/未写入任何内容/)
|
|
149
|
+
expect(readFileSync(join(brokenDir, 'cordis.patch.yml'), 'utf8')).toBe(before)
|
|
150
|
+
})
|
|
151
|
+
})
|
package/src/mcp.ts
CHANGED
|
@@ -41,11 +41,29 @@ export interface McpRow {
|
|
|
41
41
|
/** Write request for one server row (id empty = create). */
|
|
42
42
|
export type McpInput = Omit<McpRow, 'disabled'> & { disabled?: boolean }
|
|
43
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Refuse to touch a patch file the parser could not fully read. parseDocument
|
|
46
|
+
* parks syntax errors in doc.errors (it does not throw), and the failure only
|
|
47
|
+
* resurfaces at String(doc) as the internals-leaking "Document with errors
|
|
48
|
+
* cannot be stringified". Nothing gets written either way, but the banner must
|
|
49
|
+
* say what is actually wrong and which file to fix.
|
|
50
|
+
*/
|
|
51
|
+
function assertPatchParses(path: string, doc: Document): void {
|
|
52
|
+
if (doc.errors.length === 0) return
|
|
53
|
+
const at = String(doc.errors[0].message).split('\n', 1)[0]
|
|
54
|
+
const total = doc.errors.length > 1 ? `, +${doc.errors.length - 1} more` : ''
|
|
55
|
+
throw new Error(
|
|
56
|
+
`配置文件 ${path} 存在 YAML 语法错误(${at}${total}),未写入任何内容,请修复该文件后重试`
|
|
57
|
+
+ ` / YAML syntax error in the patch file (${at}${total}); nothing was written — fix it and retry`,
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
44
61
|
/** Load the profile patch as a YAML document; `[]` for a missing file. */
|
|
45
62
|
function loadPatch(profileDirPath: string): Document {
|
|
46
63
|
const path = join(profileDirPath, 'cordis.patch.yml')
|
|
47
64
|
const text = existsSync(path) ? readFileSync(path, 'utf8') : '[]'
|
|
48
65
|
const doc = parseDocument(text)
|
|
66
|
+
assertPatchParses(path, doc)
|
|
49
67
|
const contents = doc.contents as YAMLSeq | null
|
|
50
68
|
// The default-empty file parses as a flow `[]`; the patch layer is
|
|
51
69
|
// human-edited block YAML, so flip the flag before anything appends.
|