@oh-story/dsh 0.1.0 → 0.1.2
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 +3 -3
- package/lib/client.js +610 -214
- package/lib/client.js.map +3 -3
- package/lib/index.js +190 -172
- package/lib/index.js.map +4 -4
- package/lib/types/client/file-activity.d.ts +11 -6
- package/lib/types/client/file-activity.d.ts.map +1 -1
- package/lib/types/client/index.d.ts +9 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/native-hooks.d.ts +4 -1
- package/lib/types/native-hooks.d.ts.map +1 -1
- package/lib/types/workspace-route.d.ts +1 -2
- package/lib/types/workspace-route.d.ts.map +1 -1
- package/package.json +14 -3
- package/lib/types/workspace-security.d.ts +0 -9
- package/lib/types/workspace-security.d.ts.map +0 -1
package/lib/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/skill-provider.ts", "../src/native-hooks.ts", "../src/role-tool.ts", "../src/role-provider.ts", "../src/workspace-route.ts", "../src/workspace-
|
|
4
|
-
"sourcesContent": ["import type { Context } from \"@deepseek-ai/cordis\";\nimport type {} from \"@deepseek-ai/dsh-host-webserver\";\nimport type {} from \"@deepseek-ai/dsh-session\";\nimport type {} from \"@deepseek-ai/dsh-skill\";\nimport type {} from \"@deepseek-ai/dsh-subagent\";\nimport type {} from \"@deepseek-ai/dsh-tools\";\nimport z from \"@deepseek-ai/schemastery\";\nimport { createDramaSkillProvider, createOhStorySkillProvider } from \"./skill-provider.js\";\nimport { registerOhStoryHooks } from \"./native-hooks.js\";\nimport { registerOhStoryRoleTool } from \"./role-tool.js\";\nimport { registerWorkspaceRoute } from \"./workspace-route.js\";\nimport { assertTrustedWorkspaceAuthority } from \"./workspace-request-trust.js\";\n\nexport { createDramaSkillProvider, createOhStorySkillProvider, parseBundledSkill } from \"./skill-provider.js\";\nexport { OH_STORY_ROLE_NAMES, loadBundledRole } from \"./role-provider.js\";\nexport { createOhStoryRoleTool, OH_STORY_ROLE_TOOL_NAME, registerOhStoryRoleTool, roleToolFilter } from \"./role-tool.js\";\nexport { registerWorkspaceRoute } from \"./workspace-route.js\";\nexport { registerOhStoryHooks } from \"./native-hooks.js\";\n\nexport const name = \"oh-story\";\nexport const inject = [\"sessions\", \"skills\", \"subagents\", \"tools\", \"webServer\"];\n\n/** DSH owns models, providers, presets, permissions, roots, runs, and sessions. */\nexport interface Config {\n readonly editorMaxBytes?: number;\n readonly trustedHosts?: string[];\n}\n\nexport const Config = z.object({\n editorMaxBytes: z.natural().min(65_536).max(8_388_608).default(2_097_152),\n trustedHosts: z.array(String).default([])\n}) as z<Config>;\n\n/** Mount only domain contributions into the current DSH process. */\nexport async function apply(context: Context, config: Config = {}): Promise<void> {\n const trustedHosts = config.trustedHosts ?? [];\n for (const entry of trustedHosts) assertTrustedWorkspaceAuthority(entry);\n context.skills.registerProvider(() => createOhStorySkillProvider());\n context.skills.registerProvider(() => createDramaSkillProvider());\n registerOhStoryHooks(context);\n await registerOhStoryRoleTool(context);\n registerWorkspaceRoute(context, { maxBytes: config.editorMaxBytes ?? 2_097_152, trustedHosts });\n}\n\nexport default { name, inject, Config, apply };\n", "import { readdir, readFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join, relative, resolve } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport {\n BUNDLED_SKILL_RANK,\n type SkillCandidate,\n type SkillDefinition,\n type SkillProvider\n} from \"@deepseek-ai/dsh-skill\";\n\nconst STORY_PROVIDER_NAME = \"oh-story\";\nconst DRAMA_PROVIDER_NAME = \"short-drama\";\nconst INVOCATION = { modelInvocable: true, userInvocable: true } as const;\nconst DSH_SKILL_BRIDGE = [\n \"<oh-story-dsh-integration>\",\n \"This Skill is a native contribution to the current DeepSeek Harness session.\",\n \"DSH owns the workspace, model, preset, permissions, Session Log, tools, subagents, cancellation, resume, and Agent UI.\",\n \"Never start another Agent runtime, session transport, Dashboard, SSE stream, polling loop, or model configuration.\",\n \"All seven upstream Oh Story specialist Roles are bundled. Invoke one with oh_story_role and a self-contained prompt.\",\n \"Never inspect .claude/agents, .codex/agents, .opencode/agents, or .story-deployed to decide whether a Role is available.\",\n \"Use only DSH-visible tools. DSH sandbox and permission policy remain authoritative.\",\n \"</oh-story-dsh-integration>\"\n].join(\"\\n\");\nconst DSH_SKILL_OVERRIDES: Readonly<Partial<Record<string, string>>> = {\n story: \"The \u5C0F\u8BF4 workspace is an official DSH conversation view. Never start or open a second web application.\",\n \"story-setup\": \"Initialize or validate novel project data only. DSH already supplies Skills, Roles, hooks, tools, permissions, sessions, and UI; never deploy Claude/OpenCode/Codex/ZCode/OpenClaw/Reasonix files or a .story-deployed marker.\",\n \"story-long-analyze\": \"Use oh_story_role for chapter extraction or specialist analysis. Never inspect platform agent directories or require a deployed external Agent definition.\",\n \"story-long-write\": \"All named Roles are provided through oh_story_role. Do not check platform agent files. Keep the upstream writing, Tracking, lint, outline, revision, and quality workflows.\",\n \"story-review\": \"All named reviewer Roles are provided through oh_story_role. Do not check platform agent files; full/lean review may use the bundled Roles directly.\",\n \"story-import\": \"All named Roles are provided through oh_story_role. Do not require story-setup to deploy them.\",\n \"story-deslop\": \"Use the bundled narrative-writer Role through oh_story_role when specialist review is useful. Never inspect platform agent directories.\",\n \"story-short-analyze\": \"Use oh_story_role for specialist analysis. Never inspect platform agent directories or require external Agent deployment.\",\n \"story-short-write\": \"All named Roles are provided through oh_story_role. Do not inspect platform agent files; preserve the upstream short-fiction workflow and quality gates.\",\n \"browser-cdp\": \"Use only browser or web capabilities visible in the current DSH preset. Do not start a parallel browser host; if no compatible capability is visible, explain the limitation.\",\n \"story-cover\": \"Use only image-generation or HTTP capabilities visible in the current DSH preset. Never assume a separate Codex or Claude runtime.\"\n};\nconst DSH_DRAMA_BRIDGE = [\n \"<short-drama-dsh-integration>\",\n \"This Skill is a native contribution to the current DeepSeek Harness session.\",\n \"DSH owns the workspace, model, preset, permissions, Session Log, tools, approvals, cancellation, resume, and Agent UI.\",\n \"The \u77ED\u5267 tab is the creator workspace. Never start dashboard_server.py, another web server, Dashboard, Agent runtime, session transport, or model configuration.\",\n \"Use only tools visible in the current DSH preset and preserve the upstream project ownership, freshness, review, and explicit production-confirmation contracts.\",\n \"Production credentials remain outside project files. Never treat a prior acceptance, preview, continuation request, or budget discussion as confirmation for a paid production run.\",\n \"</short-drama-dsh-integration>\"\n].join(\"\\n\");\nconst DSH_DRAMA_OVERRIDES: Readonly<Partial<Record<string, string>>> = {\n \"short-drama\": \"A dashboard request means focus or use the native \u77ED\u5267 tab in this DSH Session. Do not run the bundled standalone Dashboard script.\",\n \"short-drama-produce\": \"Use an upstream adapter only after the creator explicitly confirms the exact current job. DSH permissions and approval UI remain authoritative.\"\n};\n\nconst DSH_NATIVE_SKILLS: Readonly<Partial<Record<string, string>>> = {\n story: `# story \u2014 DSH \u5C0F\u8BF4\u6D41\u7A0B\u5165\u53E3\n\n\u5728\u5F53\u524D DSH Session \u5185\u5224\u65AD\u7528\u6237\u610F\u56FE\uFF0C\u5E76\u52A0\u8F7D\u6700\u5339\u914D\u7684 Oh Story Skill\uFF1A\n\n- \u65B0\u5EFA\u6216\u4FEE\u590D\u5C0F\u8BF4\u5DE5\u7A0B\uFF1Astory-setup\n- \u957F\u7BC7\u9009\u9898/\u626B\u699C/\u62C6\u6587/\u65E5\u66F4\uFF1Astory-long-scan\u3001story-long-analyze\u3001story-long-write\n- \u77ED\u7BC7\u9009\u9898/\u62C6\u6587/\u5199\u4F5C\uFF1Astory-short-scan\u3001story-short-analyze\u3001story-short-write\n- \u5BFC\u5165\u5DF2\u6709\u4F5C\u54C1\uFF1Astory-import\n- \u5BA1\u7A3F\u4E0E\u53BB AI \u5473\uFF1Astory-review\u3001story-deslop\n- \u5C01\u9762\uFF1Astory-cover\n\n\u610F\u56FE\u660E\u786E\u65F6\u76F4\u63A5\u8FDB\u5165\u5BF9\u5E94 Skill\uFF1B\u4E0D\u660E\u786E\u65F6\u53EA\u95EE\u4E00\u4E2A\u4F1A\u6539\u53D8\u6D41\u7A0B\u7684\u95EE\u9898\u3002\u9879\u76EE\u6587\u4EF6\u3001\nAgent\u3001\u6A21\u578B\u3001\u6743\u9650\u3001Session Log \u548C UI \u5747\u7531\u5F53\u524D DSH \u4F1A\u8BDD\u7BA1\u7406\u3002\u5C0F\u8BF4\u6587\u4EF6\u901A\u8FC7\u201C\u5C0F\u8BF4\u201D\n\u89C6\u56FE\u67E5\u770B\uFF0CAgent \u8FC7\u7A0B\u901A\u8FC7\u53F3\u4FA7\u52A8\u6001\u680F\u6216\u5B98\u65B9 Chat \u67E5\u770B\u3002\u7981\u6B62\u542F\u52A8\u72EC\u7ACB Dashboard\u3002`,\n \"story-setup\": `# story-setup \u2014 DSH \u539F\u751F\u5C0F\u8BF4\u5DE5\u7A0B\u521D\u59CB\u5316\n\n\u53EA\u521D\u59CB\u5316\u6216\u6821\u9A8C\u5F53\u524D DSH workspace \u4E2D\u7684\u5C0F\u8BF4\u6570\u636E\uFF0C\u4E0D\u90E8\u7F72\u4EFB\u4F55 Agent \u5E73\u53F0\u6587\u4EF6\u3002\n\n1. \u68C0\u67E5\u73B0\u6709\u6B63\u6587\u3001\u8BBE\u5B9A\u3001\u5927\u7EB2\u548C\u8FFD\u8E2A\u6587\u4EF6\uFF0C\u5DF2\u6709\u5185\u5BB9\u7EDD\u4E0D\u8986\u76D6\u3002\n2. \u6839\u636E\u7528\u6237\u58F0\u660E\u4E0E\u73B0\u6709\u7ED3\u6784\u5224\u65AD\u957F\u7BC7/\u77ED\u7BC7\uFF1B\u65E0\u6CD5\u53EF\u9760\u5224\u65AD\u65F6\u8BF7\u6C42\u786E\u8BA4\u3002\n3. \u957F\u7BC7\u6309\u9700\u5EFA\u7ACB \u6B63\u6587/\u3001\u8BBE\u5B9A/\u3001\u5927\u7EB2/\u3001\u8FFD\u8E2A/\uFF0C\u5E76\u51C6\u5907\u8FFD\u8E2A/_tracking-state.json\uFF1B\n \u7B2C\u4E00\u7AE0\u6B63\u6587\u843D\u76D8\u524D\u5FC5\u987B\u6709\u5BF9\u5E94\u7EC6\u7EB2\u3002\u77ED\u7BC7\u4FDD\u6301\u8F7B\u91CF\u7ED3\u6784\uFF0C\u4E0D\u5F3A\u52A0\u957F\u7BC7 Tracking\u3002\n4. \u9700\u8981\u67B6\u6784\u3001\u89D2\u8272\u6216\u7814\u7A76\u5DE5\u4F5C\u65F6\uFF0C\u901A\u8FC7 oh_story_role \u8C03\u7528\u5DF2\u6253\u5305 Role\uFF1B\u4E0D\u8981\u68C0\u67E5\u6216\n \u751F\u6210 .claude\u3001.codex\u3001.opencode\u3001.zcode\u3001AGENTS.md \u6216 .story-deployed\u3002\n5. \u590D\u8FF0\u521B\u5EFA\u3001\u4FDD\u7559\u548C\u5F85\u7528\u6237\u786E\u8BA4\u7684\u6587\u4EF6\u3002\u4E0D\u8981\u914D\u7F6E\u6A21\u578B\u3001\u6743\u9650\u3001Hooks \u6216 Session\u3002\n\n\u9898\u6750\u3001\u89D2\u8272\u3001\u8282\u594F\u3001\u51B2\u7A81\u3001\u5F00\u7BC7\u548C\u5199\u4F5C\u65B9\u6CD5\u8D44\u6599\u4F4D\u4E8E references/agent-references/\uFF1B\n\u53EA\u52A0\u8F7D\u5F53\u524D\u4EFB\u52A1\u9700\u8981\u7684\u6587\u4EF6\u3002`,\n \"browser-cdp\": `# browser-cdp \u2014 DSH \u6D4F\u89C8\u5668\u80FD\u529B\u9002\u914D\n\n\u672C Skill \u4E0D\u542F\u52A8 Chrome\u3001CDP \u7AEF\u53E3\u3001\u72EC\u7ACB\u6D4F\u89C8\u5668 Host \u6216 setup-cdp-chrome.js\u3002\n\u4EC5\u4F7F\u7528\u5F53\u524D DSH Preset \u5DF2\u66B4\u9732\u7684 web_search\u3001web_fetch \u6216\u6D4F\u89C8\u5668\u5DE5\u5177\u5B8C\u6210\u7F51\u9875\u8BFB\u53D6\u3001\n\u699C\u5355\u91C7\u96C6\u548C\u8D44\u6599\u6838\u9A8C\u3002\u4FDD\u6301\u4EE5\u4E0B\u539F\u5219\uFF1A\n\n1. \u4F18\u5148\u4F7F\u7528\u7ED3\u6784\u5316\u641C\u7D22/\u6293\u53D6\u5DE5\u5177\uFF1B\u9700\u8981\u767B\u5F55\u6001\u6216\u4EA4\u4E92\u9875\u9762\u65F6\u624D\u4F7F\u7528\u53EF\u89C1\u6D4F\u89C8\u5668\u80FD\u529B\u3002\n2. \u5C0A\u91CD\u7AD9\u70B9\u6761\u6B3E\u3001\u8BBF\u95EE\u9891\u7387\u4E0E\u7528\u6237\u6388\u6743\uFF1B\u4E0D\u7ED5\u8FC7\u9A8C\u8BC1\u7801\u3001\u4ED8\u8D39\u5899\u6216\u8BBF\u95EE\u63A7\u5236\u3002\n3. \u8BB0\u5F55\u6765\u6E90 URL\u3001\u91C7\u96C6\u65F6\u95F4\u3001\u5931\u8D25\u9879\u548C\u6570\u636E\u8D28\u91CF\uFF0C\u4E0D\u628A\u63A8\u65AD\u5199\u6210\u9875\u9762\u4E8B\u5B9E\u3002\n4. \u5F53\u524D Preset \u6CA1\u6709\u517C\u5BB9\u80FD\u529B\u65F6\uFF0C\u8BF4\u660E\u7F3A\u5931\u80FD\u529B\u548C\u53EF\u884C\u7684\u624B\u5DE5\u6B65\u9AA4\uFF0C\u4E0D\u53E6\u8D77\u8FD0\u884C\u65F6\u3002`,\n \"story-long-scan\": `# story-long-scan \u2014 DSH \u539F\u751F\u957F\u7BC7\u626B\u699C\n\n\u57FA\u4E8E\u53EF\u6838\u9A8C\u6837\u672C\u8BC6\u522B\u957F\u7BC7\u7F51\u6587\u8D8B\u52BF\uFF0C\u4E0D\u8FD0\u884C\u6253\u5305\u811A\u672C\u3001\u4E0D\u63D0\u53D6\u767B\u5F55\u51ED\u636E\uFF0C\u4E5F\u4E0D\u7ED5\u8FC7\u9A8C\u8BC1\u7801\u3001\n\u8BBF\u95EE\u63A7\u5236\u6216\u7AD9\u70B9\u9650\u5236\u3002\n\n1. \u660E\u786E\u5E73\u53F0\u3001\u9891\u9053\u548C\u9898\u6750\u65B9\u5411\uFF1B\u53EA\u6709\u7B54\u6848\u4F1A\u6539\u53D8\u91C7\u6837\u8303\u56F4\u65F6\u624D\u95EE\u4E00\u4E2A\u95EE\u9898\u3002\n2. \u6570\u636E\u6765\u6E90\u4F9D\u6B21\u4E3A\uFF1A\u7528\u6237\u63D0\u4F9B\u7684\u6570\u636E\u6216\u94FE\u63A5\u3001\u5F53\u524D DSH Preset \u53EF\u89C1\u7684\u7F51\u9875\u5DE5\u5177\u3001\n references/genre-trends.md \u4E2D\u7684\u5386\u53F2\u8D8B\u52BF\u3002\u65E0\u6CD5\u83B7\u53D6\u5B9E\u65F6\u6570\u636E\u65F6\u5FC5\u987B\u660E\u786E\u6807\u4E3A\u5386\u53F2\u5047\u8BBE\u3002\n3. \u6BCF\u4E2A\u6837\u672C\u8BB0\u5F55\u6765\u6E90 URL\u3001\u91C7\u96C6\u65E5\u671F\u3001\u699C\u5355\u53E3\u5F84\u3001\u6709\u6548\u6761\u76EE\u6570\u3001\u7F3A\u5931\u5B57\u6BB5\u548C\u5F02\u5E38\u9879\uFF1B\n \u4E0D\u628A\u641C\u7D22\u6458\u8981\u3001\u63A8\u65AD\u6216\u8FC7\u671F\u7F13\u5B58\u5199\u6210\u9875\u9762\u4E8B\u5B9E\u3002\n4. \u6309\u9898\u6750\u5206\u5E03\u3001\u65B0\u9898\u6750\u4FE1\u53F7\u3001\u7ECF\u5178\u9898\u6750\u53D8\u5316\u3001\u7BC7\u5E45\u4E0E\u66F4\u65B0\u3001\u4E66\u540D\u6A21\u5F0F\u3001\u5F00\u5934\u5356\u70B9\u548C\n \u5DEE\u5F02\u5316\u5143\u7D20\u5206\u6790\u3002\u9700\u8981\u51B3\u7B56\u95E8\u7981\u65F6\u4F7F\u7528 references/topic-decision.md\u3002\n5. \u8F93\u51FA\u5E02\u573A\u6982\u51B5\u3001\u9898\u6750\u70ED\u5EA6\u3001\u8BC1\u636E\u4E0E\u53EF\u4FE1\u5EA6\u3001\u98CE\u9669\u3001\u4E09\u9879\u53EF\u6267\u884C\u65B9\u5411\u548C\u4E0B\u6B21\u590D\u626B\u65F6\u95F4\u3002\n\n\u5F53\u524D Preset \u6CA1\u6709\u7F51\u9875\u80FD\u529B\u4E14\u7528\u6237\u4E5F\u672A\u63D0\u4F9B\u6837\u672C\u65F6\uFF0C\u4F7F\u7528\u5185\u7F6E\u53C2\u8003\u5B8C\u6210\u65B9\u6CD5\u8BBA\u5206\u6790\uFF0C\n\u5E76\u5217\u51FA\u4ECD\u9700\u6838\u9A8C\u7684\u699C\u5355\uFF1B\u4E0D\u8981\u542F\u52A8 CDP\u3001\u72EC\u7ACB\u6D4F\u89C8\u5668\u6216\u5E76\u884C\u8FD0\u884C\u65F6\u3002`,\n \"story-short-scan\": `# story-short-scan \u2014 DSH \u539F\u751F\u77ED\u7BC7\u626B\u699C\n\n\u57FA\u4E8E\u53EF\u6838\u9A8C\u6837\u672C\u8BC6\u522B\u77ED\u7BC7\u5E02\u573A\u7684\u60C5\u7EEA\u3001\u9898\u6750\u4E0E\u4F20\u64AD\u4FE1\u53F7\uFF0C\u4E0D\u8FD0\u884C\u6253\u5305\u811A\u672C\u3001\u4E0D\u8BFB\u53D6 Cookie\n\u6216 token\uFF0C\u4E5F\u4E0D\u7ED5\u8FC7\u9A8C\u8BC1\u7801\u3001\u767B\u5F55\u6216\u8BBF\u95EE\u63A7\u5236\u3002\n\n1. \u660E\u786E\u5E73\u53F0\u4E0E\u65B9\u5411\uFF1B\u53EA\u6709\u7B54\u6848\u4F1A\u6539\u53D8\u91C7\u6837\u8303\u56F4\u65F6\u624D\u95EE\u4E00\u4E2A\u95EE\u9898\u3002\n2. \u6570\u636E\u6765\u6E90\u4F9D\u6B21\u4E3A\uFF1A\u7528\u6237\u63D0\u4F9B\u7684\u6570\u636E\u6216\u94FE\u63A5\u3001\u5F53\u524D DSH Preset \u53EF\u89C1\u7684\u7F51\u9875\u5DE5\u5177\u3001\n references/real-market-data.md \u4E2D\u7684\u5386\u53F2\u8D44\u6599\u3002\u65E0\u6CD5\u8054\u7F51\u65F6\u5FC5\u987B\u628A\u7ED3\u8BBA\u6807\u4E3A\u5019\u9009\u5047\u8BBE\u3002\n3. \u8BB0\u5F55\u6765\u6E90 URL\u3001\u91C7\u96C6\u65E5\u671F\u3001\u699C\u5355\u53E3\u5F84\u3001\u6709\u6548\u6837\u672C\u6570\u3001\u7F3A\u5931\u5B57\u6BB5\u548C\u5F02\u5E38\u9879\u3002\n4. \u5206\u6790\u60C5\u7EEA\u7C7B\u578B\u3001\u9898\u6750\u70ED\u70B9\u3001\u7BC7\u5E45\u3001\u5F00\u5934\u3001\u7ED3\u5C3E\u3001\u6807\u9898\u3001\u4EBA\u8BBE\u4E0E\u4F20\u64AD\u89E6\u53D1\u70B9\uFF1B\n \u7ED9\u6BCF\u4E2A\u8D8B\u52BF\u6807\u6CE8\u8BC1\u636E\u5F3A\u5EA6\u3001\u9971\u548C\u98CE\u9669\u548C\u6709\u6548\u671F\u3002\n5. \u8F93\u51FA\u5E02\u573A\u6982\u51B5\u3001\u60C5\u7EEA\u70ED\u5EA6\u3001\u9898\u6750\u70ED\u70B9\u3001\u5173\u952E\u6570\u636E\u3001\u98CE\u53E3\u9884\u8B66\u3001\u4E09\u9879\u53EF\u5199\u65B9\u5411\u548C\u590D\u626B\u65F6\u95F4\u3002\n\n\u5F53\u524D Preset \u6CA1\u6709\u7F51\u9875\u80FD\u529B\u4E14\u7528\u6237\u4E5F\u672A\u63D0\u4F9B\u6837\u672C\u65F6\uFF0C\u53EA\u505A\u5386\u53F2\u8D44\u6599\u5206\u6790\u5E76\u5217\u51FA\u9A8C\u8BC1\u52A8\u4F5C\uFF1B\n\u4E0D\u8981\u542F\u52A8 CDP\u3001\u72EC\u7ACB\u6D4F\u89C8\u5668\u6216\u5E76\u884C\u8FD0\u884C\u65F6\u3002`\n};\n\ninterface ParsedSkill {\n readonly name: string;\n readonly description: string;\n readonly content: string;\n}\n\nfunction frontmatterValue(frontmatter: string, key: string): string | undefined {\n const match = new RegExp(`^${key}:\\\\s*(.+)$`, \"mu\").exec(frontmatter);\n const raw = match?.[1]?.trim();\n if (raw === undefined) return undefined;\n if (raw.startsWith(\"\\\"\") && raw.endsWith(\"\\\"\")) {\n try { return JSON.parse(raw) as string; }\n catch { return raw.slice(1, -1); }\n }\n return raw.replace(/^['\"]|['\"]$/gu, \"\");\n}\n\nexport function parseBundledSkill(source: string): ParsedSkill {\n const match = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?/u.exec(source);\n if (match?.[1] === undefined) throw new Error(\"Bundled skill is missing YAML frontmatter.\");\n const name = frontmatterValue(match[1], \"name\");\n const description = frontmatterValue(match[1], \"description\");\n if (!name || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(name)) throw new Error(\"Bundled skill has an invalid name.\");\n if (!description) throw new Error(`Bundled skill \"${name}\" has no description.`);\n return { name, description, content: source.slice(match[0].length) };\n}\n\nexport function dshSkillContent(name: string, content: string): string {\n const override = DSH_SKILL_OVERRIDES[name];\n const native = DSH_NATIVE_SKILLS[name];\n return `${DSH_SKILL_BRIDGE}${override === undefined ? \"\" : `\\n<skill-specific-dsh-override>${override}</skill-specific-dsh-override>`}\\n\\n${native ?? content}`;\n}\n\nexport function defaultBundledSkillRoot(): string {\n const current = dirname(fileURLToPath(import.meta.url));\n return basename(current) === \"src\"\n ? resolve(current, \"../../knowledge/oh-story/skills\")\n : resolve(current, \"oh-story/skills\");\n}\n\nexport function defaultDramaSkillRoot(): string {\n const current = dirname(fileURLToPath(import.meta.url));\n return basename(current) === \"src\"\n ? resolve(current, \"../../knowledge/drama/skills\")\n : resolve(current, \"drama/skills\");\n}\n\nfunction createBundledSkillProvider(\n providerName: string,\n skillRoot: string,\n content: (name: string, source: string) => string\n): SkillProvider {\n const root = resolve(skillRoot);\n return {\n name: providerName,\n async list(): Promise<readonly SkillCandidate[]> {\n const directories = (await readdir(root, { withFileTypes: true }))\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name)\n .sort();\n return Promise.all(directories.map(async (directory): Promise<SkillCandidate> => {\n const path = join(root, directory, \"SKILL.md\");\n const parsed = parseBundledSkill(await readFile(path, \"utf8\"));\n if (parsed.name !== directory) throw new Error(`Bundled skill directory \"${directory}\" does not match name \"${parsed.name}\".`);\n return {\n name: parsed.name,\n description: parsed.description,\n invocation: INVOCATION,\n provider: providerName,\n source: \"bundled\",\n resourceBase: { kind: \"directory\", path: join(root, directory) },\n rank: BUNDLED_SKILL_RANK,\n locator: pathToFileURL(path),\n path\n };\n }));\n },\n async get(candidate): Promise<SkillDefinition | undefined> {\n if (candidate.provider !== providerName || typeof candidate.path !== \"string\") return undefined;\n const path = resolve(candidate.path);\n const relativePath = relative(root, path);\n if (relativePath === \"\" || relativePath.startsWith(\"..\") || isAbsolute(relativePath)) {\n throw new Error(\"Bundled skill locator escaped the packaged skill root.\");\n }\n const parsed = parseBundledSkill(await readFile(path, \"utf8\"));\n if (parsed.name !== candidate.name) return undefined;\n return {\n name: parsed.name,\n description: parsed.description,\n invocation: INVOCATION,\n provider: providerName,\n source: \"bundled\",\n resourceBase: { kind: \"directory\", path: join(root, parsed.name) },\n path,\n content: content(parsed.name, parsed.content)\n };\n }\n };\n}\n\nexport function createOhStorySkillProvider(skillRoot = defaultBundledSkillRoot()): SkillProvider {\n return createBundledSkillProvider(STORY_PROVIDER_NAME, skillRoot, dshSkillContent);\n}\n\nexport function dshDramaSkillContent(name: string, content: string): string {\n const override = DSH_DRAMA_OVERRIDES[name];\n return `${DSH_DRAMA_BRIDGE}${override === undefined ? \"\" : `\\n<skill-specific-dsh-override>${override}</skill-specific-dsh-override>`}\\n\\n${content}`;\n}\n\nexport function createDramaSkillProvider(skillRoot = defaultDramaSkillRoot()): SkillProvider {\n return createBundledSkillProvider(DRAMA_PROVIDER_NAME, skillRoot, dshDramaSkillContent);\n}\n", "import { access, readdir } from \"node:fs/promises\";\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport type { Context } from \"@deepseek-ai/cordis\";\nimport { createUserMessage } from \"@deepseek-ai/dsh-llm\";\nimport type { PostToolDecision, PreToolDecision, ToolExecution } from \"@deepseek-ai/dsh-tools\";\n\nconst MUTATION_TOOLS = new Set([\"write\", \"edit\", \"str_replace_editor\"]);\n\nexport interface StoryMutation {\n readonly root: string;\n readonly path: string;\n readonly chapter?: number;\n}\n\nfunction mutationPath(name: string, args: unknown): string | undefined {\n if (!MUTATION_TOOLS.has(name) || typeof args !== \"object\" || args === null || Array.isArray(args)) return undefined;\n const record = args as Record<string, unknown>;\n if (name === \"str_replace_editor\") {\n if (!new Set([\"create\", \"str_replace\", \"insert\"]).has(String(record.command))) return undefined;\n return typeof record.path === \"string\" && record.path.trim() !== \"\" ? record.path : undefined;\n }\n return typeof record.file_path === \"string\" && record.file_path.trim() !== \"\" ? record.file_path : undefined;\n}\n\nexport function detectStoryMutation(name: string, args: unknown, cwd: string | undefined): StoryMutation | undefined {\n const path = mutationPath(name, args);\n if (cwd === undefined || path === undefined) return undefined;\n const root = resolve(cwd);\n const absolute = isAbsolute(path) ? resolve(path) : resolve(root, path);\n const offset = relative(root, absolute);\n if (offset === \"..\" || offset.startsWith(`..${sep}`) || isAbsolute(offset)) return undefined;\n const normalized = offset.replaceAll(\"\\\\\", \"/\");\n if (!normalized.startsWith(\"\u6B63\u6587/\")) return undefined;\n const chapterText = /\u7B2C0*(\\d+)\u7AE0/u.exec(normalized)?.[1];\n return { root, path: normalized, ...(chapterText === undefined ? {} : { chapter: Number(chapterText) }) };\n}\n\nfunction storyMutation(exec: ToolExecution): StoryMutation | undefined {\n return detectStoryMutation(exec.name, exec.arguments, exec.agent?.session.header.cwd);\n}\n\nasync function exists(path: string): Promise<boolean> {\n return access(path).then(() => true, () => false);\n}\n\nasync function hasChapterOutline(root: string, chapter: number): Promise<boolean> {\n const entries = await readdir(resolve(root, \"\u5927\u7EB2\"), { withFileTypes: true }).catch(() => []);\n return entries.some((entry) => entry.isFile()\n && Number(/^\u7EC6\u7EB2_\u7B2C0*(\\d+)\u7AE0.*\\.md$/u.exec(entry.name)?.[1]) === chapter);\n}\n\nexport async function validateStoryMutation(mutation: StoryMutation): Promise<string | undefined> {\n const hasLongFormLayout = await exists(resolve(mutation.root, \"\u5927\u7EB2\")) || await exists(resolve(mutation.root, \"\u8FFD\u8E2A\"));\n if (!hasLongFormLayout) return undefined;\n if (!(await exists(resolve(mutation.root, \"\u8FFD\u8E2A/_tracking-state.json\")))) {\n // Setup/import must be able to bootstrap an existing manuscript before the\n // canonical Tracking file exists. The Skill remains responsible for\n // creating it; hard guards begin once the project has committed Tracking.\n return undefined;\n }\n if (mutation.chapter !== undefined && !(await hasChapterOutline(mutation.root, mutation.chapter))) {\n return `Oh Story \u963B\u6B62\u5199\u5165\u7B2C ${String(mutation.chapter)} \u7AE0\uFF1A\u672A\u627E\u5230\u5BF9\u5E94\u7684 \u5927\u7EB2/\u7EC6\u7EB2_\u7B2CXXX\u7AE0*.md\u3002\u8BF7\u5148\u5B8C\u6210\u7EC6\u7EB2\u3002`;\n }\n return undefined;\n}\n\nexport async function decideStoryMutation(\n exec: ToolExecution,\n next: () => Promise<PreToolDecision>\n): Promise<PreToolDecision> {\n const mutation = storyMutation(exec);\n if (mutation === undefined) return next();\n const reason = await validateStoryMutation(mutation);\n if (reason !== undefined) return { kind: \"deny\", reason };\n return next();\n}\n\n/**\n * Native DSH equivalents of the upstream prose guards. They join DSH's typed\n * tool waterfall, so decisions remain visible in the official approval/tool UI.\n */\nexport function registerOhStoryHooks(context: Context): void {\n context.on(\"tools/pre-execute\", decideStoryMutation);\n\n context.on(\"tools/post-execute\", async (exec, result, next): Promise<PostToolDecision> => {\n const mutation = storyMutation(exec);\n const downstream = await next();\n if (mutation === undefined || result.isError || downstream.kind !== \"accept\") return downstream;\n const reminder = createUserMessage({\n source: { kind: \"plugin\", plugin: \"oh-story\" },\n content: [{\n type: \"text\",\n text: `<oh-story-post-write>\u6B63\u6587 ${mutation.path} \u5DF2\u53D8\u66F4\u3002\u7EE7\u7EED\u5F53\u524D\u6B65\u9AA4\u524D\u6838\u5BF9\u5E76\u66F4\u65B0 _tracking-state.json \u53CA\u5BF9\u5E94\u6D3E\u751F Tracking \u89C6\u56FE\uFF1B\u4E0D\u8981\u628A\u8FD9\u6761\u63D0\u9192\u5F53\u4F5C\u7528\u6237\u7684\u65B0\u5199\u4F5C\u8981\u6C42\u3002</oh-story-post-write>`\n }]\n });\n return {\n ...downstream,\n additionalContexts: [...downstream.additionalContexts ?? [], reminder]\n };\n });\n}\n", "import type { Context } from \"@deepseek-ai/cordis\";\nimport type { ContentBlock } from \"@deepseek-ai/dsh-llm\";\nimport type { JsonValue } from \"@deepseek-ai/dsh-session\";\nimport { defineTool, type ToolDefinition } from \"@deepseek-ai/dsh-tools\";\nimport { OH_STORY_ROLE_NAMES, loadBundledRole, type OhStoryRoleName } from \"./role-provider.js\";\n\nexport const OH_STORY_ROLE_TOOL_NAME = \"oh_story_role\";\n\nconst roleTools: Readonly<Record<OhStoryRoleName, readonly string[]>> = {\n \"chapter-extractor\": [\"read\", \"glob\", \"grep\"],\n \"character-designer\": [\"read\", \"glob\", \"grep\"],\n \"consistency-checker\": [\"read\", \"glob\", \"grep\"],\n \"narrative-writer\": [\"read\", \"glob\", \"grep\", \"bash\"],\n \"story-architect\": [\"read\", \"glob\", \"grep\"],\n \"story-explorer\": [\"read\", \"glob\", \"grep\"],\n \"story-researcher\": [\"read\", \"glob\", \"grep\", \"bash\", \"web_search\", \"web_fetch\"]\n};\n\nexport function roleToolFilter(role: OhStoryRoleName): { readonly allow: readonly string[] } {\n return { allow: roleTools[role] };\n}\n\nfunction resultText(output: readonly ContentBlock[]): string {\n return output.map((block) => block.type === \"text\" ? block.text : JSON.stringify(block)).join(\"\\n\");\n}\n\nexport async function createOhStoryRoleTool(): Promise<ToolDefinition> {\n const personas = new Map<OhStoryRoleName, string>();\n await Promise.all(OH_STORY_ROLE_NAMES.map(async (role) => {\n personas.set(role, await loadBundledRole(role, undefined, \"native-tools\"));\n }));\n return defineTool({\n name: OH_STORY_ROLE_TOOL_NAME,\n description: \"Run one focused Oh Story specialist as a child of the current DSH Agent. The child inherits DSH model, workspace, permissions, lifecycle, and UI.\",\n parameters: {\n role: {\n type: \"string\",\n required: true,\n enum: OH_STORY_ROLE_NAMES,\n description: \"The exact Oh Story Role to run.\"\n },\n prompt: {\n type: \"string\",\n required: true,\n description: \"A self-contained task. The child inherits the current DSH workspace but not the current in-flight turn.\"\n }\n },\n output: {\n schema: {\n type: \"object\",\n additionalProperties: false,\n properties: {\n role: { type: \"string\", required: true, enum: OH_STORY_ROLE_NAMES },\n runId: { type: \"string\", required: true },\n content: { type: \"array\", required: true, items: { type: \"json\" } }\n }\n },\n render: (_args, value) => [{ type: \"text\", text: resultText(value.content as unknown as ContentBlock[]) }]\n },\n isConcurrencySafe: () => true,\n async execute(args, exec) {\n if (exec.agent === undefined) throw new Error(\"oh_story_role requires a calling DSH Agent.\");\n const persona = personas.get(args.role);\n if (persona === undefined) throw new Error(`Oh Story Role ${args.role} is not bundled.`);\n const allowed = roleToolFilter(args.role).allow.filter((name) =>\n exec.agent?.ctx.tools.get(name, exec.agent) !== undefined);\n const run = await exec.agent.ctx.subagents.start(\"spawn\", {\n label: `oh-story:${args.role}`,\n prompt: [{ type: \"text\", text: args.prompt }],\n parent: exec.agent,\n persona,\n toolFilter: { allow: allowed },\n maxDepth: 1,\n signal: exec.signal\n });\n try {\n const result = await run.result;\n if (result.stopReason !== \"completed\") {\n throw new Error(`Oh Story Role ${args.role} ended with ${result.stopReason}${result.diagnostic === undefined ? \"\" : `: ${result.diagnostic}`}`);\n }\n return {\n role: args.role,\n runId: run.id,\n content: result.output as unknown as JsonValue[]\n };\n } finally {\n await run.dispose();\n }\n }\n });\n}\n\nexport async function registerOhStoryRoleTool(context: Context): Promise<void> {\n const definition = await createOhStoryRoleTool();\n let dispose: (() => void) | undefined;\n const mount = (): void => { dispose ??= context.tools.register(definition); };\n const unmount = (): void => { dispose?.(); dispose = undefined; };\n context.on(\"subagent/provider-added\", (provider) => { if (provider.name === \"spawn\") mount(); });\n context.on(\"subagent/provider-removed\", (name) => { if (name === \"spawn\") unmount(); });\n if (context.subagents.getProvider(\"spawn\") !== undefined) mount();\n}\n", "import { readFile } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport const OH_STORY_ROLE_NAMES = [\n \"chapter-extractor\",\n \"character-designer\",\n \"consistency-checker\",\n \"narrative-writer\",\n \"story-architect\",\n \"story-explorer\",\n \"story-researcher\"\n] as const;\n\nexport type OhStoryRoleName = typeof OH_STORY_ROLE_NAMES[number];\nexport type OhStoryRoleExecution = \"tool-free\" | \"native-tools\";\n\nfunction roleBody(source: string): string {\n const frontmatter = /^---\\r?\\n[\\s\\S]*?\\r?\\n---\\r?\\n?/u.exec(source);\n return source.slice(frontmatter?.[0].length ?? 0).trim();\n}\n\nexport function defaultBundledRoleRoot(): string {\n const current = dirname(fileURLToPath(import.meta.url));\n return basename(current) === \"src\"\n ? resolve(current, \"../../knowledge/oh-story/roles\")\n : resolve(current, \"oh-story/roles\");\n}\n\nexport async function loadBundledRole(\n name: OhStoryRoleName,\n roleRoot = defaultBundledRoleRoot(),\n execution: OhStoryRoleExecution = \"tool-free\"\n): Promise<string> {\n const body = roleBody(await readFile(join(resolve(roleRoot), `${name}.md`), \"utf8\"));\n if (body.length === 0) throw new Error(`Bundled role \"${name}\" is empty.`);\n const integration = execution === \"tool-free\"\n ? [\n \"You are running inside an Oh Story review-required DSH collaboration. The caller supplies every permitted input in the prompt.\",\n \"Do not read or write project files, do not call tools, and do not follow legacy .claude/.codex path or deployment instructions in the upstream role text.\",\n \"Return only the output contract requested by the caller; never claim to have changed the project.\"\n ]\n : [\n \"You are running as a native oh-story-dsh specialist. The current DSH workspace and visible tool set are your complete authority boundary.\",\n \"Never inspect or require legacy .claude/.opencode/.codex agent deployment files; this exact pinned Role is already active.\",\n \"Use only the tools actually visible to you. Mutate files only when the caller explicitly requests it and your visible DSH tools permit it; otherwise return findings to the caller.\"\n ];\n return [\n `OH_STORY_DSH_ROLE:${name}`,\n ...integration,\n \"\",\n body\n ].join(\"\\n\");\n}\n", "import { createHash, randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, readdir, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { dirname, extname, join, relative, resolve } from \"node:path\";\nimport type { Context } from \"@deepseek-ai/cordis\";\nimport type {} from \"@deepseek-ai/dsh-host-webserver\";\nimport { SessionId } from \"@deepseek-ai/dsh-session\";\nimport { canonicalWorkspaceRoot, resolveWorkspacePath } from \"./workspace-security.js\";\nimport { isTrustedWorkspaceRequest } from \"./workspace-request-trust.js\";\n\nconst STORY_DIRECTORIES = [\"\u6B63\u6587\", \"\u5927\u7EB2\", \"\u8BBE\u5B9A\", \"\u8FFD\u8E2A\", \"\u5BF9\u6807\", \"\u53C2\u8003\u8D44\u6599\"] as const;\nconst DRAMA_DIRECTORIES = [\"\u8F93\u5165\", \"\u9879\u76EE\u5F00\u53D1\", \"\u8BBE\u5B9A\u96C6\", \"\u5267\u96C6\", \"\u4EA4\u4ED8\", \"\u521B\u4F5C\u8005\u51B3\u7B56\", \"\u5BA1\u67E5\"] as const;\nconst CREATIVE_DIRECTORIES = [...STORY_DIRECTORIES, ...DRAMA_DIRECTORIES] as const;\nconst ROOT_FILES = new Set([\"short-drama.json\"]);\nconst EDITABLE_EXTENSIONS = new Set([\".md\", \".txt\", \".json\", \".jsonl\"]);\n\ninterface WorkspaceRouteOptions {\n readonly maxBytes: number;\n readonly trustedHosts?: readonly string[];\n}\ninterface WorkspaceFile { readonly path: string; readonly bytes: number }\n\nclass WorkspaceHttpError extends Error {\n constructor(readonly status: number, message: string) { super(message); }\n}\n\nfunction send(response: ServerResponse, status: number, value: unknown): void {\n const body = `${JSON.stringify(value)}\\n`;\n response.writeHead(status, {\n \"content-type\": \"application/json; charset=utf-8\",\n \"content-length\": Buffer.byteLength(body),\n \"cache-control\": \"no-store\",\n \"x-content-type-options\": \"nosniff\"\n });\n response.end(body);\n}\n\nexport function workspaceContentVersion(content: string | Buffer): string {\n return createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\nasync function jsonBody(request: IncomingMessage, maxBytes: number): Promise<Record<string, unknown>> {\n const chunks: Buffer[] = [];\n let size = 0;\n for await (const chunk of request as AsyncIterable<Uint8Array>) {\n const value = Buffer.from(chunk);\n size += value.byteLength;\n if (size > maxBytes) throw new WorkspaceHttpError(413, \"\u8BF7\u6C42\u5185\u5BB9\u8FC7\u5927\u3002\");\n chunks.push(value);\n }\n try {\n const value = JSON.parse(Buffer.concat(chunks).toString(\"utf8\")) as unknown;\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) throw new Error();\n return value as Record<string, unknown>;\n } catch {\n throw new WorkspaceHttpError(400, \"\u8BF7\u6C42\u5FC5\u987B\u662F JSON \u5BF9\u8C61\u3002\");\n }\n}\n\nfunction assertCreativePath(path: string): void {\n if (!EDITABLE_EXTENSIONS.has(extname(path).toLocaleLowerCase())) {\n throw new WorkspaceHttpError(415, \"\u5DE5\u4F5C\u53F0\u53EA\u7F16\u8F91 Markdown\u3001\u6587\u672C\u3001JSON \u548C JSONL \u6587\u4EF6\u3002\");\n }\n if (path.split(\"/\").some((segment) => segment === \"\" || segment === \"..\")) {\n throw new WorkspaceHttpError(403, \"\u6587\u4EF6\u8DEF\u5F84\u4E0D\u5728\u521B\u4F5C\u5DE5\u4F5C\u53F0\u4E2D\u3002\");\n }\n const root = path.split(\"/\", 1)[0];\n if (!CREATIVE_DIRECTORIES.some((directory) => directory === root) && !ROOT_FILES.has(path)) {\n throw new WorkspaceHttpError(403, \"\u6587\u4EF6\u8DEF\u5F84\u4E0D\u5728\u521B\u4F5C\u5DE5\u4F5C\u53F0\u4E2D\u3002\");\n }\n}\n\nasync function listFiles(root: string): Promise<WorkspaceFile[]> {\n const files: WorkspaceFile[] = [];\n const walk = async (directory: string): Promise<void> => {\n const absolute = await resolveWorkspacePath(root, directory, { expect: \"directory\" });\n for (const entry of await readdir(absolute, { withFileTypes: true })) {\n if (entry.isSymbolicLink() || entry.name.startsWith(\".\")) continue;\n const path = `${directory}/${entry.name}`;\n if (entry.isDirectory()) await walk(path);\n else if (entry.isFile() && EDITABLE_EXTENSIONS.has(extname(entry.name).toLocaleLowerCase())) {\n files.push({ path, bytes: (await stat(join(absolute, entry.name))).size });\n }\n if (files.length >= 1_000) return;\n }\n };\n for (const directory of CREATIVE_DIRECTORIES) await walk(directory).catch(() => undefined);\n for (const path of ROOT_FILES) {\n await resolveWorkspacePath(root, path, { expect: \"file\" })\n .then(async (absolute) => { files.push({ path, bytes: (await stat(absolute)).size }); })\n .catch(() => undefined);\n }\n return files.sort((left, right) => left.path.localeCompare(right.path, \"zh-Hans-CN\"));\n}\n\nfunction sessionRoot(context: Context, url: URL): Promise<string> {\n const id = url.searchParams.get(\"sessionId\");\n if (id === null || id === \"\") throw new WorkspaceHttpError(400, \"\u7F3A\u5C11 DSH sessionId\u3002\");\n const session = context.sessions.get(SessionId(id));\n if (session === undefined) throw new WorkspaceHttpError(404, \"DSH \u4F1A\u8BDD\u4E0D\u53EF\u7528\u3002\");\n if (session.header.parentSession !== undefined) throw new WorkspaceHttpError(403, \"\u5B50 Agent \u4F1A\u8BDD\u4E0D\u5F00\u653E\u5C0F\u8BF4\u7F16\u8F91\u5668\u3002\");\n const cwd = session.header.cwd;\n if (cwd === undefined) throw new WorkspaceHttpError(409, \"\u5F53\u524D DSH \u4F1A\u8BDD\u6CA1\u6709\u5DE5\u4F5C\u76EE\u5F55\u3002\");\n return canonicalWorkspaceRoot(cwd);\n}\n\nasync function handle(context: Context, request: IncomingMessage, response: ServerResponse, options: WorkspaceRouteOptions): Promise<void> {\n try {\n if (!isTrustedWorkspaceRequest(request, options.trustedHosts ?? [])) {\n throw new WorkspaceHttpError(403, \"\u8BF7\u6C42\u6765\u6E90\u4E0D\u53D7\u4FE1\u4EFB\u3002\");\n }\n const url = new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n if (url.pathname === \"/oh-story/workspace\" && request.method === \"GET\") {\n const root = await sessionRoot(context, url);\n const files = await listFiles(root);\n const trackingFile = files.find((file) => file.path === \"\u8FFD\u8E2A/_tracking-state.json\");\n const tracking: unknown = trackingFile === undefined\n ? null\n : JSON.parse(await readFile(await resolveWorkspacePath(root, trackingFile.path, { expect: \"file\" }), \"utf8\")) as unknown;\n const dramaFile = files.find((file) => file.path === \"short-drama.json\");\n const shortDrama: unknown = dramaFile === undefined\n ? null\n : JSON.parse(await readFile(await resolveWorkspacePath(root, dramaFile.path, { expect: \"file\" }), \"utf8\")) as unknown;\n send(response, 200, { cwd: root, files, tracking, shortDrama, mode: \"dsh-session\" });\n return;\n }\n if (url.pathname === \"/oh-story/file\" && request.method === \"GET\") {\n const root = await sessionRoot(context, url);\n const path = url.searchParams.get(\"path\");\n if (path === null) throw new WorkspaceHttpError(400, \"\u7F3A\u5C11\u6587\u4EF6\u8DEF\u5F84\u3002\");\n assertCreativePath(path);\n const absolute = await resolveWorkspacePath(root, path, { expect: \"file\" });\n const data = await readFile(absolute);\n if (data.byteLength > options.maxBytes) throw new WorkspaceHttpError(413, \"\u6587\u4EF6\u8D85\u8FC7\u5DE5\u4F5C\u53F0\u5927\u5C0F\u9650\u5236\u3002\");\n send(response, 200, {\n path,\n content: data.toString(\"utf8\"),\n bytes: data.byteLength,\n version: workspaceContentVersion(data)\n });\n return;\n }\n if (url.pathname === \"/oh-story/file\" && request.method === \"PUT\") {\n const root = await sessionRoot(context, url);\n const path = url.searchParams.get(\"path\");\n if (path === null) throw new WorkspaceHttpError(400, \"\u7F3A\u5C11\u6587\u4EF6\u8DEF\u5F84\u3002\");\n assertCreativePath(path);\n // A JSON string can expand control bytes up to sixfold (for example\n // `\\u0000`), so the transport cap must not reject otherwise valid files.\n const input = await jsonBody(request, options.maxBytes * 6 + 1_024);\n if (typeof input.content !== \"string\") throw new WorkspaceHttpError(400, \"content \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u3002\");\n if (typeof input.baseVersion !== \"string\") throw new WorkspaceHttpError(400, \"baseVersion \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u3002\");\n if (Buffer.byteLength(input.content) > options.maxBytes) throw new WorkspaceHttpError(413, \"\u6587\u4EF6\u8D85\u8FC7\u5DE5\u4F5C\u53F0\u5927\u5C0F\u9650\u5236\u3002\");\n // Human edits use this route directly. Model-facing prose policy belongs\n // to DSH's tool waterfall and must never be applied to the editor.\n const absolute = await resolveWorkspacePath(root, path, { expect: \"file\" });\n const current = await readFile(absolute);\n if (workspaceContentVersion(current) !== input.baseVersion) {\n throw new WorkspaceHttpError(412, \"\u6587\u4EF6\u5DF2\u5728\u78C1\u76D8\u4E0A\u66F4\u65B0\u3002\u8BF7\u5237\u65B0\u5E76\u5408\u5E76\u540E\u518D\u4FDD\u5B58\u3002\");\n }\n const parent = dirname(absolute);\n await mkdir(parent, { recursive: true });\n const rootReal = await canonicalWorkspaceRoot(root);\n const parentReal = await canonicalWorkspaceRoot(parent);\n const offset = relative(rootReal, parentReal);\n if (offset === \"..\" || offset.startsWith(\"../\")) throw new WorkspaceHttpError(403, \"\u6587\u4EF6\u8DEF\u5F84\u79BB\u5F00\u4E86 DSH \u5DE5\u4F5C\u76EE\u5F55\u3002\");\n const temporary = resolve(parent, `.${randomUUID()}.oh-story.tmp`);\n try {\n await writeFile(temporary, input.content, { encoding: \"utf8\", flag: \"wx\" });\n if (workspaceContentVersion(await readFile(absolute)) !== input.baseVersion) {\n throw new WorkspaceHttpError(412, \"\u6587\u4EF6\u5DF2\u5728\u78C1\u76D8\u4E0A\u66F4\u65B0\u3002\u8BF7\u5237\u65B0\u5E76\u5408\u5E76\u540E\u518D\u4FDD\u5B58\u3002\");\n }\n await rename(temporary, absolute);\n } finally {\n await rm(temporary, { force: true });\n }\n send(response, 200, {\n path,\n content: input.content,\n bytes: Buffer.byteLength(input.content),\n version: workspaceContentVersion(input.content)\n });\n return;\n }\n send(response, 404, { error: \"Oh Story route not found.\" });\n } catch (error) {\n if (error instanceof WorkspaceHttpError) send(response, error.status, { error: error.message });\n else send(response, 500, { error: error instanceof Error ? error.message : String(error) });\n }\n}\n\n/** This narrow route never starts agents, runs, streams, or models. */\nexport function registerWorkspaceRoute(context: Context, options: WorkspaceRouteOptions): void {\n context.effect(() => context.webServer.register({\n kind: \"prefix\",\n path: \"/oh-story\",\n handler: (request, response) => handle(context, request, response, options)\n }), \"oh-story: DSH-session workspace API\");\n}\n", "import { lstat, realpath } from \"node:fs/promises\";\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\n\nexport class PathSecurityError extends Error {\n public constructor(message: string) {\n super(message);\n this.name = \"PathSecurityError\";\n }\n}\n\nfunction isInside(root: string, candidate: string): boolean {\n const offset = relative(root, candidate);\n return offset === \"\" || (!offset.startsWith(`..${sep}`) && offset !== \"..\" && !isAbsolute(offset));\n}\n\nexport async function canonicalWorkspaceRoot(root: string): Promise<string> {\n const canonical = await realpath(root);\n const info = await lstat(canonical);\n if (!info.isDirectory()) throw new PathSecurityError(\"Workspace root must be a directory.\");\n return canonical;\n}\n\nexport async function resolveWorkspacePath(\n root: string,\n relativePath: string,\n options: { readonly allowMissing?: boolean; readonly expect?: \"file\" | \"directory\" } = {}\n): Promise<string> {\n if (relativePath.includes(\"\\0\") || isAbsolute(relativePath) || /^[A-Za-z]:[\\\\/]/u.test(relativePath)) {\n throw new PathSecurityError(\"Only workspace-relative paths are allowed.\");\n }\n const segments = relativePath.replaceAll(\"\\\\\", \"/\").split(\"/\");\n if (segments.some((segment) => segment === \"..\" || segment === \"\")) {\n throw new PathSecurityError(\"Path traversal and empty segments are not allowed.\");\n }\n const canonicalRoot = await canonicalWorkspaceRoot(root);\n const candidate = resolve(canonicalRoot, ...segments);\n if (!isInside(canonicalRoot, candidate)) throw new PathSecurityError(\"Path escapes the workspace.\");\n\n let cursor = canonicalRoot;\n for (let index = 0; index < segments.length; index += 1) {\n cursor = resolve(cursor, segments[index] ?? \"\");\n try {\n const info = await lstat(cursor);\n if (info.isSymbolicLink()) {\n const target = await realpath(cursor);\n if (!isInside(canonicalRoot, target)) throw new PathSecurityError(\"Symbolic link escapes the workspace.\");\n cursor = target;\n }\n if (index < segments.length - 1 && !info.isDirectory()) throw new PathSecurityError(\"A path parent is not a directory.\");\n if (index === segments.length - 1 && options.expect !== undefined) {\n if (options.expect === \"file\" && !info.isFile()) throw new PathSecurityError(\"Expected a regular file.\");\n if (options.expect === \"directory\" && !info.isDirectory()) throw new PathSecurityError(\"Expected a directory.\");\n }\n } catch (error: unknown) {\n if (error instanceof PathSecurityError) throw error;\n const code = error instanceof Error && \"code\" in error ? String(error.code) : \"\";\n if (code === \"ENOENT\" && options.allowMissing === true && index === segments.length - 1) return cursor;\n throw error;\n }\n }\n const finalPath = await realpath(cursor);\n if (!isInside(canonicalRoot, finalPath)) throw new PathSecurityError(\"Resolved path escapes the workspace.\");\n return finalPath;\n}\n", "import type { IncomingHttpHeaders } from \"node:http\";\n\ninterface WorkspaceTrustRequest {\n readonly headers: IncomingHttpHeaders | Headers;\n}\n\nfunction header(headers: IncomingHttpHeaders | Headers, name: string): string | undefined {\n if (headers instanceof Headers) return headers.get(name) ?? undefined;\n const value = headers[name];\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction parseAuthority(authority: string): URL | undefined {\n try { return new URL(`http://${authority}`); }\n catch { return undefined; }\n}\n\nfunction canonicalAuthority(entry: string, url: URL): string {\n const port = url.port !== \"\" ? url.port : new URL(`https://${entry}`).port;\n return port === \"\" ? url.hostname : `${url.hostname}:${port}`;\n}\n\nfunction isLoopbackHostname(hostname: string): boolean {\n if (hostname === \"localhost\" || hostname === \"[::1]\") return true;\n const parts = hostname.split(\".\");\n return parts.length === 4\n && parts[0] === \"127\"\n && parts.every((part) => /^\\d{1,3}$/u.test(part) && Number(part) <= 255);\n}\n\nfunction isTrustedAuthority(host: URL, trustedHosts: readonly string[]): boolean {\n return trustedHosts.some((entry) => {\n const candidate = parseAuthority(entry);\n if (candidate === undefined) return false;\n return canonicalAuthority(entry, candidate) === candidate.hostname\n ? candidate.hostname === host.hostname\n : candidate.host === host.host;\n });\n}\n\n/** Reject malformed declarations at plugin load instead of silently widening access. */\nexport function assertTrustedWorkspaceAuthority(entry: string): void {\n const url = parseAuthority(entry);\n if (url !== undefined && canonicalAuthority(entry, url) === entry.toLocaleLowerCase()) return;\n throw new Error(`oh-story: trustedHosts entry ${JSON.stringify(entry)} is not a bare host[:port] authority`);\n}\n\n/**\n * Same browser trust boundary as DSH's native API: every request must address a\n * loopback or explicitly trusted Host, and browser markers must be same-origin.\n */\nexport function isTrustedWorkspaceRequest(\n request: WorkspaceTrustRequest,\n trustedHosts: readonly string[]\n): boolean {\n const authority = header(request.headers, \"host\");\n if (authority === undefined) return false;\n const host = parseAuthority(authority);\n if (host === undefined) return false;\n if (!isLoopbackHostname(host.hostname) && !isTrustedAuthority(host, trustedHosts)) return false;\n if (header(request.headers, \"sec-fetch-site\") === \"cross-site\") return false;\n const origin = header(request.headers, \"origin\");\n if (origin === undefined) return true;\n try { return new URL(origin).host === host.host; }\n catch { return false; }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["name", "
|
|
3
|
+
"sources": ["../src/index.ts", "../src/skill-provider.ts", "../src/native-hooks.ts", "../src/role-tool.ts", "../src/role-provider.ts", "../src/workspace-route.ts", "../src/workspace-request-trust.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Context } from \"@deepseek-ai/cordis\";\nimport type {} from \"@deepseek-ai/dsh-host-webserver\";\nimport type {} from \"@deepseek-ai/dsh-skill\";\nimport type {} from \"@deepseek-ai/dsh-subagent\";\nimport type {} from \"@deepseek-ai/dsh-tools\";\nimport z from \"@deepseek-ai/schemastery\";\nimport { createDramaSkillProvider, createOhStorySkillProvider } from \"./skill-provider.js\";\nimport { registerOhStoryHooks } from \"./native-hooks.js\";\nimport { registerOhStoryRoleTool } from \"./role-tool.js\";\nimport { registerWorkspaceRoute } from \"./workspace-route.js\";\nimport { assertTrustedWorkspaceAuthority } from \"./workspace-request-trust.js\";\n\nexport { createDramaSkillProvider, createOhStorySkillProvider, parseBundledSkill } from \"./skill-provider.js\";\nexport { OH_STORY_ROLE_NAMES, loadBundledRole } from \"./role-provider.js\";\nexport { createOhStoryRoleTool, OH_STORY_ROLE_TOOL_NAME, registerOhStoryRoleTool, roleToolFilter } from \"./role-tool.js\";\nexport { registerWorkspaceRoute } from \"./workspace-route.js\";\nexport { registerOhStoryHooks } from \"./native-hooks.js\";\n\nexport const name = \"oh-story\";\nexport const inject = [\"skills\", \"subagents\", \"tools\", \"typert\", \"webServer\"];\n\n/** DSH owns models, providers, presets, permissions, roots, runs, and sessions. */\nexport interface Config {\n readonly editorMaxBytes?: number;\n readonly trustedHosts?: string[];\n}\n\nexport const Config = z.object({\n editorMaxBytes: z.natural().min(65_536).max(8_388_608).default(2_097_152),\n trustedHosts: z.array(String).default([])\n}) as z<Config>;\n\n/** Mount only domain contributions into the current DSH process. */\nexport async function apply(context: Context, config: Config = {}): Promise<void> {\n const trustedHosts = config.trustedHosts ?? [];\n for (const entry of trustedHosts) assertTrustedWorkspaceAuthority(entry);\n context.skills.registerProvider(() => createOhStorySkillProvider());\n context.skills.registerProvider(() => createDramaSkillProvider());\n registerOhStoryHooks(context);\n await registerOhStoryRoleTool(context);\n registerWorkspaceRoute(context, { maxBytes: config.editorMaxBytes ?? 2_097_152, trustedHosts });\n}\n\nexport default { name, inject, Config, apply };\n", "import { readdir, readFile } from \"node:fs/promises\";\nimport { basename, dirname, isAbsolute, join, relative, resolve } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport {\n BUNDLED_SKILL_RANK,\n type SkillCandidate,\n type SkillDefinition,\n type SkillProvider\n} from \"@deepseek-ai/dsh-skill\";\n\nconst STORY_PROVIDER_NAME = \"oh-story\";\nconst DRAMA_PROVIDER_NAME = \"short-drama\";\nconst INVOCATION = { modelInvocable: true, userInvocable: true } as const;\nconst DSH_SKILL_BRIDGE = [\n \"<oh-story-dsh-integration>\",\n \"This Skill is a native contribution to the current DeepSeek Harness session.\",\n \"DSH owns the workspace, model, preset, permissions, Session Log, tools, subagents, cancellation, resume, and Agent UI.\",\n \"Never start another Agent runtime, session transport, Dashboard, SSE stream, polling loop, or model configuration.\",\n \"All seven upstream Oh Story specialist Roles are bundled. Invoke one with oh_story_role and a self-contained prompt.\",\n \"Never inspect .claude/agents, .codex/agents, .opencode/agents, or .story-deployed to decide whether a Role is available.\",\n \"Use only DSH-visible tools. DSH sandbox and permission policy remain authoritative.\",\n \"</oh-story-dsh-integration>\"\n].join(\"\\n\");\nconst DSH_SKILL_OVERRIDES: Readonly<Partial<Record<string, string>>> = {\n story: \"The \u5C0F\u8BF4 workspace is an official DSH conversation view. Never start or open a second web application.\",\n \"story-setup\": \"Initialize or validate novel project data only. DSH already supplies Skills, Roles, hooks, tools, permissions, sessions, and UI; never deploy Claude/OpenCode/Codex/ZCode/OpenClaw/Reasonix files or a .story-deployed marker.\",\n \"story-long-analyze\": \"Use oh_story_role for chapter extraction or specialist analysis. Never inspect platform agent directories or require a deployed external Agent definition.\",\n \"story-long-write\": \"All named Roles are provided through oh_story_role. Do not check platform agent files. Keep the upstream writing, Tracking, lint, outline, revision, and quality workflows.\",\n \"story-review\": \"All named reviewer Roles are provided through oh_story_role. Do not check platform agent files; full/lean review may use the bundled Roles directly.\",\n \"story-import\": \"All named Roles are provided through oh_story_role. Do not require story-setup to deploy them.\",\n \"story-deslop\": \"Use the bundled narrative-writer Role through oh_story_role when specialist review is useful. Never inspect platform agent directories.\",\n \"story-short-analyze\": \"Use oh_story_role for specialist analysis. Never inspect platform agent directories or require external Agent deployment.\",\n \"story-short-write\": \"All named Roles are provided through oh_story_role. Do not inspect platform agent files; preserve the upstream short-fiction workflow and quality gates.\",\n \"browser-cdp\": \"Use only browser or web capabilities visible in the current DSH preset. Do not start a parallel browser host; if no compatible capability is visible, explain the limitation.\",\n \"story-cover\": \"Use only image-generation or HTTP capabilities visible in the current DSH preset. Never assume a separate Codex or Claude runtime.\"\n};\nconst DSH_DRAMA_BRIDGE = [\n \"<short-drama-dsh-integration>\",\n \"This Skill is a native contribution to the current DeepSeek Harness session.\",\n \"DSH owns the workspace, model, preset, permissions, Session Log, tools, approvals, cancellation, resume, and Agent UI.\",\n \"The \u77ED\u5267 tab is the creator workspace. Never start dashboard_server.py, another web server, Dashboard, Agent runtime, session transport, or model configuration.\",\n \"Use only tools visible in the current DSH preset and preserve the upstream project ownership, freshness, review, and explicit production-confirmation contracts.\",\n \"Production credentials remain outside project files. Never treat a prior acceptance, preview, continuation request, or budget discussion as confirmation for a paid production run.\",\n \"</short-drama-dsh-integration>\"\n].join(\"\\n\");\nconst DSH_DRAMA_OVERRIDES: Readonly<Partial<Record<string, string>>> = {\n \"short-drama\": \"A dashboard request means focus or use the native \u77ED\u5267 tab in this DSH Session. Do not run the bundled standalone Dashboard script.\",\n \"short-drama-produce\": \"Use an upstream adapter only after the creator explicitly confirms the exact current job. DSH permissions and approval UI remain authoritative.\"\n};\n\nconst DSH_NATIVE_SKILLS: Readonly<Partial<Record<string, string>>> = {\n story: `# story \u2014 DSH \u5C0F\u8BF4\u6D41\u7A0B\u5165\u53E3\n\n\u5728\u5F53\u524D DSH Session \u5185\u5224\u65AD\u7528\u6237\u610F\u56FE\uFF0C\u5E76\u52A0\u8F7D\u6700\u5339\u914D\u7684 Oh Story Skill\uFF1A\n\n- \u65B0\u5EFA\u6216\u4FEE\u590D\u5C0F\u8BF4\u5DE5\u7A0B\uFF1Astory-setup\n- \u957F\u7BC7\u9009\u9898/\u626B\u699C/\u62C6\u6587/\u65E5\u66F4\uFF1Astory-long-scan\u3001story-long-analyze\u3001story-long-write\n- \u77ED\u7BC7\u9009\u9898/\u62C6\u6587/\u5199\u4F5C\uFF1Astory-short-scan\u3001story-short-analyze\u3001story-short-write\n- \u5BFC\u5165\u5DF2\u6709\u4F5C\u54C1\uFF1Astory-import\n- \u5BA1\u7A3F\u4E0E\u53BB AI \u5473\uFF1Astory-review\u3001story-deslop\n- \u5C01\u9762\uFF1Astory-cover\n\n\u610F\u56FE\u660E\u786E\u65F6\u76F4\u63A5\u8FDB\u5165\u5BF9\u5E94 Skill\uFF1B\u4E0D\u660E\u786E\u65F6\u53EA\u95EE\u4E00\u4E2A\u4F1A\u6539\u53D8\u6D41\u7A0B\u7684\u95EE\u9898\u3002\u9879\u76EE\u6587\u4EF6\u3001\nAgent\u3001\u6A21\u578B\u3001\u6743\u9650\u3001Session Log \u548C UI \u5747\u7531\u5F53\u524D DSH \u4F1A\u8BDD\u7BA1\u7406\u3002\u5C0F\u8BF4\u6587\u4EF6\u901A\u8FC7\u201C\u5C0F\u8BF4\u201D\n\u89C6\u56FE\u67E5\u770B\uFF0CAgent \u8FC7\u7A0B\u901A\u8FC7\u53F3\u4FA7\u52A8\u6001\u680F\u6216\u5B98\u65B9 Chat \u67E5\u770B\u3002\u7981\u6B62\u542F\u52A8\u72EC\u7ACB Dashboard\u3002`,\n \"story-setup\": `# story-setup \u2014 DSH \u539F\u751F\u5C0F\u8BF4\u5DE5\u7A0B\u521D\u59CB\u5316\n\n\u53EA\u521D\u59CB\u5316\u6216\u6821\u9A8C\u5F53\u524D DSH workspace \u4E2D\u7684\u5C0F\u8BF4\u6570\u636E\uFF0C\u4E0D\u90E8\u7F72\u4EFB\u4F55 Agent \u5E73\u53F0\u6587\u4EF6\u3002\n\n1. \u68C0\u67E5\u73B0\u6709\u6B63\u6587\u3001\u8BBE\u5B9A\u3001\u5927\u7EB2\u548C\u8FFD\u8E2A\u6587\u4EF6\uFF0C\u5DF2\u6709\u5185\u5BB9\u7EDD\u4E0D\u8986\u76D6\u3002\n2. \u6839\u636E\u7528\u6237\u58F0\u660E\u4E0E\u73B0\u6709\u7ED3\u6784\u5224\u65AD\u957F\u7BC7/\u77ED\u7BC7\uFF1B\u65E0\u6CD5\u53EF\u9760\u5224\u65AD\u65F6\u8BF7\u6C42\u786E\u8BA4\u3002\n3. \u957F\u7BC7\u6309\u9700\u5EFA\u7ACB \u6B63\u6587/\u3001\u8BBE\u5B9A/\u3001\u5927\u7EB2/\u3001\u8FFD\u8E2A/\uFF0C\u5E76\u51C6\u5907\u8FFD\u8E2A/_tracking-state.json\uFF1B\n \u7B2C\u4E00\u7AE0\u6B63\u6587\u843D\u76D8\u524D\u5FC5\u987B\u6709\u5BF9\u5E94\u7EC6\u7EB2\u3002\u77ED\u7BC7\u4FDD\u6301\u8F7B\u91CF\u7ED3\u6784\uFF0C\u4E0D\u5F3A\u52A0\u957F\u7BC7 Tracking\u3002\n4. \u9700\u8981\u67B6\u6784\u3001\u89D2\u8272\u6216\u7814\u7A76\u5DE5\u4F5C\u65F6\uFF0C\u901A\u8FC7 oh_story_role \u8C03\u7528\u5DF2\u6253\u5305 Role\uFF1B\u4E0D\u8981\u68C0\u67E5\u6216\n \u751F\u6210 .claude\u3001.codex\u3001.opencode\u3001.zcode\u3001AGENTS.md \u6216 .story-deployed\u3002\n5. \u590D\u8FF0\u521B\u5EFA\u3001\u4FDD\u7559\u548C\u5F85\u7528\u6237\u786E\u8BA4\u7684\u6587\u4EF6\u3002\u4E0D\u8981\u914D\u7F6E\u6A21\u578B\u3001\u6743\u9650\u3001Hooks \u6216 Session\u3002\n\n\u9898\u6750\u3001\u89D2\u8272\u3001\u8282\u594F\u3001\u51B2\u7A81\u3001\u5F00\u7BC7\u548C\u5199\u4F5C\u65B9\u6CD5\u8D44\u6599\u4F4D\u4E8E references/agent-references/\uFF1B\n\u53EA\u52A0\u8F7D\u5F53\u524D\u4EFB\u52A1\u9700\u8981\u7684\u6587\u4EF6\u3002`,\n \"browser-cdp\": `# browser-cdp \u2014 DSH \u6D4F\u89C8\u5668\u80FD\u529B\u9002\u914D\n\n\u672C Skill \u4E0D\u542F\u52A8 Chrome\u3001CDP \u7AEF\u53E3\u3001\u72EC\u7ACB\u6D4F\u89C8\u5668 Host \u6216 setup-cdp-chrome.js\u3002\n\u4EC5\u4F7F\u7528\u5F53\u524D DSH Preset \u5DF2\u66B4\u9732\u7684 web_search\u3001web_fetch \u6216\u6D4F\u89C8\u5668\u5DE5\u5177\u5B8C\u6210\u7F51\u9875\u8BFB\u53D6\u3001\n\u699C\u5355\u91C7\u96C6\u548C\u8D44\u6599\u6838\u9A8C\u3002\u4FDD\u6301\u4EE5\u4E0B\u539F\u5219\uFF1A\n\n1. \u4F18\u5148\u4F7F\u7528\u7ED3\u6784\u5316\u641C\u7D22/\u6293\u53D6\u5DE5\u5177\uFF1B\u9700\u8981\u767B\u5F55\u6001\u6216\u4EA4\u4E92\u9875\u9762\u65F6\u624D\u4F7F\u7528\u53EF\u89C1\u6D4F\u89C8\u5668\u80FD\u529B\u3002\n2. \u5C0A\u91CD\u7AD9\u70B9\u6761\u6B3E\u3001\u8BBF\u95EE\u9891\u7387\u4E0E\u7528\u6237\u6388\u6743\uFF1B\u4E0D\u7ED5\u8FC7\u9A8C\u8BC1\u7801\u3001\u4ED8\u8D39\u5899\u6216\u8BBF\u95EE\u63A7\u5236\u3002\n3. \u8BB0\u5F55\u6765\u6E90 URL\u3001\u91C7\u96C6\u65F6\u95F4\u3001\u5931\u8D25\u9879\u548C\u6570\u636E\u8D28\u91CF\uFF0C\u4E0D\u628A\u63A8\u65AD\u5199\u6210\u9875\u9762\u4E8B\u5B9E\u3002\n4. \u5F53\u524D Preset \u6CA1\u6709\u517C\u5BB9\u80FD\u529B\u65F6\uFF0C\u8BF4\u660E\u7F3A\u5931\u80FD\u529B\u548C\u53EF\u884C\u7684\u624B\u5DE5\u6B65\u9AA4\uFF0C\u4E0D\u53E6\u8D77\u8FD0\u884C\u65F6\u3002`,\n \"story-long-scan\": `# story-long-scan \u2014 DSH \u539F\u751F\u957F\u7BC7\u626B\u699C\n\n\u57FA\u4E8E\u53EF\u6838\u9A8C\u6837\u672C\u8BC6\u522B\u957F\u7BC7\u7F51\u6587\u8D8B\u52BF\uFF0C\u4E0D\u8FD0\u884C\u6253\u5305\u811A\u672C\u3001\u4E0D\u63D0\u53D6\u767B\u5F55\u51ED\u636E\uFF0C\u4E5F\u4E0D\u7ED5\u8FC7\u9A8C\u8BC1\u7801\u3001\n\u8BBF\u95EE\u63A7\u5236\u6216\u7AD9\u70B9\u9650\u5236\u3002\n\n1. \u660E\u786E\u5E73\u53F0\u3001\u9891\u9053\u548C\u9898\u6750\u65B9\u5411\uFF1B\u53EA\u6709\u7B54\u6848\u4F1A\u6539\u53D8\u91C7\u6837\u8303\u56F4\u65F6\u624D\u95EE\u4E00\u4E2A\u95EE\u9898\u3002\n2. \u6570\u636E\u6765\u6E90\u4F9D\u6B21\u4E3A\uFF1A\u7528\u6237\u63D0\u4F9B\u7684\u6570\u636E\u6216\u94FE\u63A5\u3001\u5F53\u524D DSH Preset \u53EF\u89C1\u7684\u7F51\u9875\u5DE5\u5177\u3001\n references/genre-trends.md \u4E2D\u7684\u5386\u53F2\u8D8B\u52BF\u3002\u65E0\u6CD5\u83B7\u53D6\u5B9E\u65F6\u6570\u636E\u65F6\u5FC5\u987B\u660E\u786E\u6807\u4E3A\u5386\u53F2\u5047\u8BBE\u3002\n3. \u6BCF\u4E2A\u6837\u672C\u8BB0\u5F55\u6765\u6E90 URL\u3001\u91C7\u96C6\u65E5\u671F\u3001\u699C\u5355\u53E3\u5F84\u3001\u6709\u6548\u6761\u76EE\u6570\u3001\u7F3A\u5931\u5B57\u6BB5\u548C\u5F02\u5E38\u9879\uFF1B\n \u4E0D\u628A\u641C\u7D22\u6458\u8981\u3001\u63A8\u65AD\u6216\u8FC7\u671F\u7F13\u5B58\u5199\u6210\u9875\u9762\u4E8B\u5B9E\u3002\n4. \u6309\u9898\u6750\u5206\u5E03\u3001\u65B0\u9898\u6750\u4FE1\u53F7\u3001\u7ECF\u5178\u9898\u6750\u53D8\u5316\u3001\u7BC7\u5E45\u4E0E\u66F4\u65B0\u3001\u4E66\u540D\u6A21\u5F0F\u3001\u5F00\u5934\u5356\u70B9\u548C\n \u5DEE\u5F02\u5316\u5143\u7D20\u5206\u6790\u3002\u9700\u8981\u51B3\u7B56\u95E8\u7981\u65F6\u4F7F\u7528 references/topic-decision.md\u3002\n5. \u8F93\u51FA\u5E02\u573A\u6982\u51B5\u3001\u9898\u6750\u70ED\u5EA6\u3001\u8BC1\u636E\u4E0E\u53EF\u4FE1\u5EA6\u3001\u98CE\u9669\u3001\u4E09\u9879\u53EF\u6267\u884C\u65B9\u5411\u548C\u4E0B\u6B21\u590D\u626B\u65F6\u95F4\u3002\n\n\u5F53\u524D Preset \u6CA1\u6709\u7F51\u9875\u80FD\u529B\u4E14\u7528\u6237\u4E5F\u672A\u63D0\u4F9B\u6837\u672C\u65F6\uFF0C\u4F7F\u7528\u5185\u7F6E\u53C2\u8003\u5B8C\u6210\u65B9\u6CD5\u8BBA\u5206\u6790\uFF0C\n\u5E76\u5217\u51FA\u4ECD\u9700\u6838\u9A8C\u7684\u699C\u5355\uFF1B\u4E0D\u8981\u542F\u52A8 CDP\u3001\u72EC\u7ACB\u6D4F\u89C8\u5668\u6216\u5E76\u884C\u8FD0\u884C\u65F6\u3002`,\n \"story-short-scan\": `# story-short-scan \u2014 DSH \u539F\u751F\u77ED\u7BC7\u626B\u699C\n\n\u57FA\u4E8E\u53EF\u6838\u9A8C\u6837\u672C\u8BC6\u522B\u77ED\u7BC7\u5E02\u573A\u7684\u60C5\u7EEA\u3001\u9898\u6750\u4E0E\u4F20\u64AD\u4FE1\u53F7\uFF0C\u4E0D\u8FD0\u884C\u6253\u5305\u811A\u672C\u3001\u4E0D\u8BFB\u53D6 Cookie\n\u6216 token\uFF0C\u4E5F\u4E0D\u7ED5\u8FC7\u9A8C\u8BC1\u7801\u3001\u767B\u5F55\u6216\u8BBF\u95EE\u63A7\u5236\u3002\n\n1. \u660E\u786E\u5E73\u53F0\u4E0E\u65B9\u5411\uFF1B\u53EA\u6709\u7B54\u6848\u4F1A\u6539\u53D8\u91C7\u6837\u8303\u56F4\u65F6\u624D\u95EE\u4E00\u4E2A\u95EE\u9898\u3002\n2. \u6570\u636E\u6765\u6E90\u4F9D\u6B21\u4E3A\uFF1A\u7528\u6237\u63D0\u4F9B\u7684\u6570\u636E\u6216\u94FE\u63A5\u3001\u5F53\u524D DSH Preset \u53EF\u89C1\u7684\u7F51\u9875\u5DE5\u5177\u3001\n references/real-market-data.md \u4E2D\u7684\u5386\u53F2\u8D44\u6599\u3002\u65E0\u6CD5\u8054\u7F51\u65F6\u5FC5\u987B\u628A\u7ED3\u8BBA\u6807\u4E3A\u5019\u9009\u5047\u8BBE\u3002\n3. \u8BB0\u5F55\u6765\u6E90 URL\u3001\u91C7\u96C6\u65E5\u671F\u3001\u699C\u5355\u53E3\u5F84\u3001\u6709\u6548\u6837\u672C\u6570\u3001\u7F3A\u5931\u5B57\u6BB5\u548C\u5F02\u5E38\u9879\u3002\n4. \u5206\u6790\u60C5\u7EEA\u7C7B\u578B\u3001\u9898\u6750\u70ED\u70B9\u3001\u7BC7\u5E45\u3001\u5F00\u5934\u3001\u7ED3\u5C3E\u3001\u6807\u9898\u3001\u4EBA\u8BBE\u4E0E\u4F20\u64AD\u89E6\u53D1\u70B9\uFF1B\n \u7ED9\u6BCF\u4E2A\u8D8B\u52BF\u6807\u6CE8\u8BC1\u636E\u5F3A\u5EA6\u3001\u9971\u548C\u98CE\u9669\u548C\u6709\u6548\u671F\u3002\n5. \u8F93\u51FA\u5E02\u573A\u6982\u51B5\u3001\u60C5\u7EEA\u70ED\u5EA6\u3001\u9898\u6750\u70ED\u70B9\u3001\u5173\u952E\u6570\u636E\u3001\u98CE\u53E3\u9884\u8B66\u3001\u4E09\u9879\u53EF\u5199\u65B9\u5411\u548C\u590D\u626B\u65F6\u95F4\u3002\n\n\u5F53\u524D Preset \u6CA1\u6709\u7F51\u9875\u80FD\u529B\u4E14\u7528\u6237\u4E5F\u672A\u63D0\u4F9B\u6837\u672C\u65F6\uFF0C\u53EA\u505A\u5386\u53F2\u8D44\u6599\u5206\u6790\u5E76\u5217\u51FA\u9A8C\u8BC1\u52A8\u4F5C\uFF1B\n\u4E0D\u8981\u542F\u52A8 CDP\u3001\u72EC\u7ACB\u6D4F\u89C8\u5668\u6216\u5E76\u884C\u8FD0\u884C\u65F6\u3002`\n};\n\ninterface ParsedSkill {\n readonly name: string;\n readonly description: string;\n readonly content: string;\n}\n\nfunction frontmatterValue(frontmatter: string, key: string): string | undefined {\n const match = new RegExp(`^${key}:\\\\s*(.+)$`, \"mu\").exec(frontmatter);\n const raw = match?.[1]?.trim();\n if (raw === undefined) return undefined;\n if (raw.startsWith(\"\\\"\") && raw.endsWith(\"\\\"\")) {\n try { return JSON.parse(raw) as string; }\n catch { return raw.slice(1, -1); }\n }\n return raw.replace(/^['\"]|['\"]$/gu, \"\");\n}\n\nexport function parseBundledSkill(source: string): ParsedSkill {\n const match = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?/u.exec(source);\n if (match?.[1] === undefined) throw new Error(\"Bundled skill is missing YAML frontmatter.\");\n const name = frontmatterValue(match[1], \"name\");\n const description = frontmatterValue(match[1], \"description\");\n if (!name || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/u.test(name)) throw new Error(\"Bundled skill has an invalid name.\");\n if (!description) throw new Error(`Bundled skill \"${name}\" has no description.`);\n return { name, description, content: source.slice(match[0].length) };\n}\n\nexport function dshSkillContent(name: string, content: string): string {\n const override = DSH_SKILL_OVERRIDES[name];\n const native = DSH_NATIVE_SKILLS[name];\n return `${DSH_SKILL_BRIDGE}${override === undefined ? \"\" : `\\n<skill-specific-dsh-override>${override}</skill-specific-dsh-override>`}\\n\\n${native ?? content}`;\n}\n\nexport function defaultBundledSkillRoot(): string {\n const current = dirname(fileURLToPath(import.meta.url));\n return basename(current) === \"src\"\n ? resolve(current, \"../../knowledge/oh-story/skills\")\n : resolve(current, \"oh-story/skills\");\n}\n\nexport function defaultDramaSkillRoot(): string {\n const current = dirname(fileURLToPath(import.meta.url));\n return basename(current) === \"src\"\n ? resolve(current, \"../../knowledge/drama/skills\")\n : resolve(current, \"drama/skills\");\n}\n\nfunction createBundledSkillProvider(\n providerName: string,\n skillRoot: string,\n content: (name: string, source: string) => string\n): SkillProvider {\n const root = resolve(skillRoot);\n return {\n name: providerName,\n async list(): Promise<readonly SkillCandidate[]> {\n const directories = (await readdir(root, { withFileTypes: true }))\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name)\n .sort();\n return Promise.all(directories.map(async (directory): Promise<SkillCandidate> => {\n const path = join(root, directory, \"SKILL.md\");\n const parsed = parseBundledSkill(await readFile(path, \"utf8\"));\n if (parsed.name !== directory) throw new Error(`Bundled skill directory \"${directory}\" does not match name \"${parsed.name}\".`);\n return {\n name: parsed.name,\n description: parsed.description,\n invocation: INVOCATION,\n provider: providerName,\n source: \"bundled\",\n resourceBase: { kind: \"directory\", path: join(root, directory) },\n rank: BUNDLED_SKILL_RANK,\n locator: pathToFileURL(path),\n path\n };\n }));\n },\n async get(candidate): Promise<SkillDefinition | undefined> {\n if (candidate.provider !== providerName || typeof candidate.path !== \"string\") return undefined;\n const path = resolve(candidate.path);\n const relativePath = relative(root, path);\n if (relativePath === \"\" || relativePath.startsWith(\"..\") || isAbsolute(relativePath)) {\n throw new Error(\"Bundled skill locator escaped the packaged skill root.\");\n }\n const parsed = parseBundledSkill(await readFile(path, \"utf8\"));\n if (parsed.name !== candidate.name) return undefined;\n return {\n name: parsed.name,\n description: parsed.description,\n invocation: INVOCATION,\n provider: providerName,\n source: \"bundled\",\n resourceBase: { kind: \"directory\", path: join(root, parsed.name) },\n path,\n content: content(parsed.name, parsed.content)\n };\n }\n };\n}\n\nexport function createOhStorySkillProvider(skillRoot = defaultBundledSkillRoot()): SkillProvider {\n return createBundledSkillProvider(STORY_PROVIDER_NAME, skillRoot, dshSkillContent);\n}\n\nexport function dshDramaSkillContent(name: string, content: string): string {\n const override = DSH_DRAMA_OVERRIDES[name];\n return `${DSH_DRAMA_BRIDGE}${override === undefined ? \"\" : `\\n<skill-specific-dsh-override>${override}</skill-specific-dsh-override>`}\\n\\n${content}`;\n}\n\nexport function createDramaSkillProvider(skillRoot = defaultDramaSkillRoot()): SkillProvider {\n return createBundledSkillProvider(DRAMA_PROVIDER_NAME, skillRoot, dshDramaSkillContent);\n}\n", "import type { Context } from \"@deepseek-ai/cordis\";\nimport type { FileSystem, FsTarget } from \"@deepseek-ai/dsh-fs\";\nimport { createUserMessage } from \"@deepseek-ai/dsh-llm\";\nimport type { PostToolDecision, PreToolDecision, ToolExecution } from \"@deepseek-ai/dsh-tools\";\n\nconst MUTATION_TOOLS = new Set([\"write\", \"edit\", \"str_replace_editor\"]);\n\nexport interface StoryMutation {\n readonly root: string;\n readonly path: string;\n readonly chapter?: number;\n}\n\nfunction mutationPath(name: string, args: unknown): string | undefined {\n if (!MUTATION_TOOLS.has(name) || typeof args !== \"object\" || args === null || Array.isArray(args)) return undefined;\n const record = args as Record<string, unknown>;\n if (name === \"str_replace_editor\") {\n if (!new Set([\"create\", \"str_replace\", \"insert\"]).has(String(record.command))) return undefined;\n return typeof record.path === \"string\" && record.path.trim() !== \"\" ? record.path : undefined;\n }\n return typeof record.file_path === \"string\" && record.file_path.trim() !== \"\" ? record.file_path : undefined;\n}\n\nfunction normalizedRelativePath(path: string): string | undefined {\n const segments: string[] = [];\n for (const part of path.split(\"/\")) {\n if (part === \"\" || part === \".\") continue;\n if (part === \"..\") {\n if (segments.length === 0) return undefined;\n segments.pop();\n } else segments.push(part);\n }\n return segments.join(\"/\");\n}\n\nexport function detectStoryMutation(name: string, args: unknown, cwd: string | undefined): StoryMutation | undefined {\n const rawPath = mutationPath(name, args);\n if (cwd === undefined || rawPath === undefined) return undefined;\n const root = cwd.replaceAll(\"\\\\\", \"/\").replace(/\\/$/u, \"\");\n const candidate = rawPath.replaceAll(\"\\\\\", \"/\");\n const absolute = candidate.startsWith(\"/\") || /^[a-z]:\\//iu.test(candidate) || /^[a-z][a-z\\d+.-]*:\\/\\//iu.test(candidate);\n const insideRoot = /^[a-z]:\\//iu.test(root)\n ? candidate.toLowerCase().startsWith(`${root.toLowerCase()}/`)\n : candidate.startsWith(`${root}/`);\n if (absolute && !insideRoot) return undefined;\n const normalized = normalizedRelativePath(absolute ? candidate.slice(root.length + 1) : candidate);\n if (normalized === undefined) return undefined;\n if (!normalized.startsWith(\"\u6B63\u6587/\")) return undefined;\n const chapterText = /\u7B2C0*(\\d+)\u7AE0/u.exec(normalized)?.[1];\n return { root, path: normalized, ...(chapterText === undefined ? {} : { chapter: Number(chapterText) }) };\n}\n\ntype StoryFileSystem = Pick<FileSystem, \"resolve\" | \"contains\" | \"stat\" | \"listDir\">;\n\nasync function storyMutation(exec: ToolExecution, fs: StoryFileSystem): Promise<StoryMutation | undefined> {\n const cwd = exec.agent?.session.header.cwd;\n const path = mutationPath(exec.name, exec.arguments);\n if (cwd === undefined || path === undefined) return undefined;\n try {\n const [rootTarget, mutationTarget] = await Promise.all([\n fs.resolve(cwd, { signal: exec.signal }),\n fs.resolve(path, { cwd, signal: exec.signal })\n ]);\n if (!fs.contains(rootTarget, mutationTarget)) return undefined;\n } catch { return undefined; }\n return detectStoryMutation(exec.name, exec.arguments, cwd);\n}\n\nasync function target(fs: StoryFileSystem, root: string, path: string, signal?: AbortSignal): Promise<FsTarget> {\n return fs.resolve(path, { cwd: root, ...(signal === undefined ? {} : { signal }) });\n}\n\nasync function exists(fs: StoryFileSystem, root: string, path: string, signal?: AbortSignal): Promise<boolean> {\n return target(fs, root, path, signal)\n .then((value) => fs.stat(value, signal))\n .then((info) => info !== undefined, () => false);\n}\n\nasync function hasChapterOutline(fs: StoryFileSystem, root: string, chapter: number, signal?: AbortSignal): Promise<boolean> {\n const entries = await target(fs, root, \"\u5927\u7EB2\", signal)\n .then((directory) => fs.listDir(directory, signal))\n .catch(() => []);\n return entries.some((entry) => entry.type === \"file\"\n && Number(/^\u7EC6\u7EB2_\u7B2C0*(\\d+)\u7AE0.*\\.md$/u.exec(entry.name)?.[1]) === chapter);\n}\n\nexport async function validateStoryMutation(\n fs: StoryFileSystem,\n mutation: StoryMutation,\n signal?: AbortSignal\n): Promise<string | undefined> {\n const hasLongFormLayout = await exists(fs, mutation.root, \"\u5927\u7EB2\", signal)\n || await exists(fs, mutation.root, \"\u8FFD\u8E2A\", signal);\n if (!hasLongFormLayout) return undefined;\n if (!(await exists(fs, mutation.root, \"\u8FFD\u8E2A/_tracking-state.json\", signal))) {\n // Setup/import must be able to bootstrap an existing manuscript before the\n // canonical Tracking file exists. The Skill remains responsible for\n // creating it; hard guards begin once the project has committed Tracking.\n return undefined;\n }\n if (mutation.chapter !== undefined && !(await hasChapterOutline(fs, mutation.root, mutation.chapter, signal))) {\n return `Oh Story \u963B\u6B62\u5199\u5165\u7B2C ${String(mutation.chapter)} \u7AE0\uFF1A\u672A\u627E\u5230\u5BF9\u5E94\u7684 \u5927\u7EB2/\u7EC6\u7EB2_\u7B2CXXX\u7AE0*.md\u3002\u8BF7\u5148\u5B8C\u6210\u7EC6\u7EB2\u3002`;\n }\n return undefined;\n}\n\nexport async function decideStoryMutation(\n exec: ToolExecution,\n next: () => Promise<PreToolDecision>\n): Promise<PreToolDecision> {\n const fs = exec.agent?.ctx.get(\"fs\");\n if (fs === undefined) return next();\n const mutation = await storyMutation(exec, fs);\n if (mutation === undefined) return next();\n const reason = await validateStoryMutation(fs, mutation, exec.signal);\n if (reason !== undefined) return { kind: \"deny\", reason };\n return next();\n}\n\n/**\n * Native DSH equivalents of the upstream prose guards. They join DSH's typed\n * tool waterfall, so decisions remain visible in the official approval/tool UI.\n */\nexport function registerOhStoryHooks(context: Context): void {\n context.on(\"tools/pre-execute\", decideStoryMutation);\n\n context.on(\"tools/post-execute\", async (exec, result, next): Promise<PostToolDecision> => {\n const downstream = await next();\n if (result.isError || downstream.kind !== \"accept\") return downstream;\n const fs = exec.agent?.ctx.get(\"fs\");\n const mutation = fs === undefined ? undefined : await storyMutation(exec, fs);\n if (mutation === undefined) return downstream;\n const reminder = createUserMessage({\n source: { kind: \"plugin\", plugin: \"oh-story\" },\n content: [{\n type: \"text\",\n text: `<oh-story-post-write>\u6B63\u6587 ${mutation.path} \u5DF2\u53D8\u66F4\u3002\u7EE7\u7EED\u5F53\u524D\u6B65\u9AA4\u524D\u6838\u5BF9\u5E76\u66F4\u65B0 _tracking-state.json \u53CA\u5BF9\u5E94\u6D3E\u751F Tracking \u89C6\u56FE\uFF1B\u4E0D\u8981\u628A\u8FD9\u6761\u63D0\u9192\u5F53\u4F5C\u7528\u6237\u7684\u65B0\u5199\u4F5C\u8981\u6C42\u3002</oh-story-post-write>`\n }]\n });\n return {\n ...downstream,\n additionalContexts: [...downstream.additionalContexts ?? [], reminder]\n };\n });\n}\n", "import type { Context } from \"@deepseek-ai/cordis\";\nimport type { ContentBlock } from \"@deepseek-ai/dsh-llm\";\nimport type { JsonValue } from \"@deepseek-ai/dsh-session\";\nimport { defineTool, type ToolDefinition } from \"@deepseek-ai/dsh-tools\";\nimport { OH_STORY_ROLE_NAMES, loadBundledRole, type OhStoryRoleName } from \"./role-provider.js\";\n\nexport const OH_STORY_ROLE_TOOL_NAME = \"oh_story_role\";\n\nconst roleTools: Readonly<Record<OhStoryRoleName, readonly string[]>> = {\n \"chapter-extractor\": [\"read\", \"glob\", \"grep\"],\n \"character-designer\": [\"read\", \"glob\", \"grep\", \"write\", \"edit\"],\n \"consistency-checker\": [\"read\", \"glob\", \"grep\"],\n \"narrative-writer\": [\"read\", \"glob\", \"grep\", \"write\", \"edit\", \"bash\"],\n \"story-architect\": [\"read\", \"glob\", \"grep\", \"write\", \"edit\"],\n \"story-explorer\": [\"read\", \"glob\", \"grep\"],\n \"story-researcher\": [\"read\", \"glob\", \"grep\", \"bash\", \"write\", \"web_search\", \"web_fetch\"]\n};\n\nexport function roleToolFilter(role: OhStoryRoleName): { readonly allow: readonly string[] } {\n return { allow: roleTools[role] };\n}\n\nfunction resultText(output: readonly ContentBlock[]): string {\n return output.map((block) => block.type === \"text\" ? block.text : JSON.stringify(block)).join(\"\\n\");\n}\n\nexport async function createOhStoryRoleTool(): Promise<ToolDefinition> {\n const personas = new Map<OhStoryRoleName, string>();\n await Promise.all(OH_STORY_ROLE_NAMES.map(async (role) => {\n personas.set(role, await loadBundledRole(role, undefined, \"native-tools\"));\n }));\n return defineTool({\n name: OH_STORY_ROLE_TOOL_NAME,\n description: \"Run one focused Oh Story specialist as a child of the current DSH Agent. The child inherits DSH model, workspace, permissions, lifecycle, and UI.\",\n parameters: {\n role: {\n type: \"string\",\n required: true,\n enum: OH_STORY_ROLE_NAMES,\n description: \"The exact Oh Story Role to run.\"\n },\n prompt: {\n type: \"string\",\n required: true,\n description: \"A self-contained task. The child inherits the current DSH workspace but not the current in-flight turn.\"\n }\n },\n output: {\n schema: {\n type: \"object\",\n additionalProperties: false,\n properties: {\n role: { type: \"string\", required: true, enum: OH_STORY_ROLE_NAMES },\n runId: { type: \"string\", required: true },\n content: { type: \"array\", required: true, items: { type: \"json\" } }\n }\n },\n render: (_args, value) => [{ type: \"text\", text: resultText(value.content as unknown as ContentBlock[]) }]\n },\n isConcurrencySafe: () => true,\n async execute(args, exec) {\n if (exec.agent === undefined) throw new Error(\"oh_story_role requires a calling DSH Agent.\");\n const persona = personas.get(args.role);\n if (persona === undefined) throw new Error(`Oh Story Role ${args.role} is not bundled.`);\n const allowed = roleToolFilter(args.role).allow.filter((name) =>\n exec.agent?.ctx.tools.get(name, exec.agent) !== undefined);\n const run = await exec.agent.ctx.subagents.start(\"spawn\", {\n label: `oh-story:${args.role}`,\n prompt: [{ type: \"text\", text: args.prompt }],\n parent: exec.agent,\n persona,\n toolFilter: { allow: allowed },\n maxDepth: 1,\n signal: exec.signal\n });\n try {\n const result = await run.result;\n if (result.stopReason !== \"completed\") {\n throw new Error(`Oh Story Role ${args.role} ended with ${result.stopReason}${result.diagnostic === undefined ? \"\" : `: ${result.diagnostic}`}`);\n }\n return {\n role: args.role,\n runId: run.id,\n content: result.output as unknown as JsonValue[]\n };\n } finally {\n await run.dispose();\n }\n }\n });\n}\n\nexport async function registerOhStoryRoleTool(context: Context): Promise<void> {\n const definition = await createOhStoryRoleTool();\n let dispose: (() => void) | undefined;\n const mount = (): void => { dispose ??= context.tools.register(definition); };\n const unmount = (): void => { dispose?.(); dispose = undefined; };\n context.on(\"subagent/provider-added\", (provider) => { if (provider.name === \"spawn\") mount(); });\n context.on(\"subagent/provider-removed\", (name) => { if (name === \"spawn\") unmount(); });\n if (context.subagents.getProvider(\"spawn\") !== undefined) mount();\n}\n", "import { readFile } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport const OH_STORY_ROLE_NAMES = [\n \"chapter-extractor\",\n \"character-designer\",\n \"consistency-checker\",\n \"narrative-writer\",\n \"story-architect\",\n \"story-explorer\",\n \"story-researcher\"\n] as const;\n\nexport type OhStoryRoleName = typeof OH_STORY_ROLE_NAMES[number];\nexport type OhStoryRoleExecution = \"tool-free\" | \"native-tools\";\n\nfunction roleBody(source: string): string {\n const frontmatter = /^---\\r?\\n[\\s\\S]*?\\r?\\n---\\r?\\n?/u.exec(source);\n return source.slice(frontmatter?.[0].length ?? 0).trim();\n}\n\nexport function defaultBundledRoleRoot(): string {\n const current = dirname(fileURLToPath(import.meta.url));\n return basename(current) === \"src\"\n ? resolve(current, \"../../knowledge/oh-story/roles\")\n : resolve(current, \"oh-story/roles\");\n}\n\nexport async function loadBundledRole(\n name: OhStoryRoleName,\n roleRoot = defaultBundledRoleRoot(),\n execution: OhStoryRoleExecution = \"tool-free\"\n): Promise<string> {\n const body = roleBody(await readFile(join(resolve(roleRoot), `${name}.md`), \"utf8\"));\n if (body.length === 0) throw new Error(`Bundled role \"${name}\" is empty.`);\n const integration = execution === \"tool-free\"\n ? [\n \"You are running inside an Oh Story review-required DSH collaboration. The caller supplies every permitted input in the prompt.\",\n \"Do not read or write project files, do not call tools, and do not follow legacy .claude/.codex path or deployment instructions in the upstream role text.\",\n \"Return only the output contract requested by the caller; never claim to have changed the project.\"\n ]\n : [\n \"You are running as a native oh-story-dsh specialist. The current DSH workspace and visible tool set are your complete authority boundary.\",\n \"Never inspect or require legacy .claude/.opencode/.codex agent deployment files; this exact pinned Role is already active.\",\n \"Use only the tools actually visible to you. Mutate files only when the caller explicitly requests it and your visible DSH tools permit it; otherwise return findings to the caller.\"\n ];\n return [\n `OH_STORY_DSH_ROLE:${name}`,\n ...integration,\n \"\",\n body\n ].join(\"\\n\");\n}\n", "import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { extname } from \"node:path\";\nimport type { Context } from \"@deepseek-ai/cordis\";\nimport type { Agent } from \"@deepseek-ai/dsh-agent\";\nimport { FsError, type FileSystem, type FsInfo, type FsTarget, type FsVersion } from \"@deepseek-ai/dsh-fs\";\nimport type {} from \"@deepseek-ai/dsh-host-webserver\";\nimport type { SandboxPolicyService } from \"@deepseek-ai/dsh-sandbox-policy\";\nimport { SessionId } from \"@deepseek-ai/dsh-session\";\nimport type {} from \"@deepseek-ai/dsh-typert-registry\";\nimport { isTrustedWorkspaceRequest } from \"./workspace-request-trust.js\";\n\nconst STORY_DIRECTORIES = [\"\u6B63\u6587\", \"\u5927\u7EB2\", \"\u8BBE\u5B9A\", \"\u8FFD\u8E2A\", \"\u5BF9\u6807\", \"\u53C2\u8003\u8D44\u6599\"] as const;\nconst DRAMA_DIRECTORIES = [\"\u8F93\u5165\", \"\u9879\u76EE\u5F00\u53D1\", \"\u8BBE\u5B9A\u96C6\", \"\u5267\u96C6\", \"\u4EA4\u4ED8\", \"\u521B\u4F5C\u8005\u51B3\u7B56\", \"\u5BA1\u67E5\"] as const;\nconst CREATIVE_DIRECTORIES = [...STORY_DIRECTORIES, ...DRAMA_DIRECTORIES] as const;\nconst ROOT_FILES = new Set([\"short-drama.json\"]);\nconst EDITABLE_EXTENSIONS = new Set([\".md\", \".txt\", \".json\", \".jsonl\"]);\nconst FILE_LIMIT = 1_000;\n\ninterface WorkspaceRouteOptions {\n readonly maxBytes: number;\n readonly trustedHosts?: readonly string[];\n}\n\ninterface WorkspaceFile {\n readonly path: string;\n readonly bytes: number;\n readonly version: string;\n}\n\ninterface WorkspaceRealm {\n readonly agent: Agent;\n readonly fs: FileSystem;\n readonly sandboxPolicy: SandboxPolicyService;\n readonly cwd: string;\n readonly root: FsTarget;\n}\n\ninterface ReadFileResult {\n readonly content: string;\n readonly bytes: number;\n readonly version: FsVersion;\n}\n\nclass WorkspaceHttpError extends Error {\n constructor(readonly status: number, message: string) { super(message); }\n}\n\nfunction send(response: ServerResponse, status: number, value: unknown): void {\n const body = `${JSON.stringify(value)}\\n`;\n response.writeHead(status, {\n \"content-type\": \"application/json; charset=utf-8\",\n \"content-length\": Buffer.byteLength(body),\n \"cache-control\": \"no-store\",\n \"x-content-type-options\": \"nosniff\"\n });\n response.end(body);\n}\n\nasync function jsonBody(request: IncomingMessage, maxBytes: number): Promise<Record<string, unknown>> {\n const chunks: Buffer[] = [];\n let size = 0;\n for await (const chunk of request as AsyncIterable<Uint8Array>) {\n const value = Buffer.from(chunk);\n size += value.byteLength;\n if (size > maxBytes) throw new WorkspaceHttpError(413, \"\u8BF7\u6C42\u5185\u5BB9\u8FC7\u5927\u3002\");\n chunks.push(value);\n }\n try {\n const value = JSON.parse(Buffer.concat(chunks).toString(\"utf8\")) as unknown;\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) throw new Error();\n return value as Record<string, unknown>;\n } catch {\n throw new WorkspaceHttpError(400, \"\u8BF7\u6C42\u5FC5\u987B\u662F JSON \u5BF9\u8C61\u3002\");\n }\n}\n\nfunction assertCreativePath(path: string): void {\n if (!EDITABLE_EXTENSIONS.has(extname(path).toLocaleLowerCase())) {\n throw new WorkspaceHttpError(415, \"\u5DE5\u4F5C\u53F0\u53EA\u7F16\u8F91 Markdown\u3001\u6587\u672C\u3001JSON \u548C JSONL \u6587\u4EF6\u3002\");\n }\n if (path.startsWith(\"/\") || path.includes(\"\\\\\") || path.split(\"/\").some((segment) => segment === \"\" || segment === \".\" || segment === \"..\")) {\n throw new WorkspaceHttpError(403, \"\u6587\u4EF6\u8DEF\u5F84\u4E0D\u5728\u521B\u4F5C\u5DE5\u4F5C\u53F0\u4E2D\u3002\");\n }\n const root = path.split(\"/\", 1)[0];\n if (!CREATIVE_DIRECTORIES.some((directory) => directory === root) && !ROOT_FILES.has(path)) {\n throw new WorkspaceHttpError(403, \"\u6587\u4EF6\u8DEF\u5F84\u4E0D\u5728\u521B\u4F5C\u5DE5\u4F5C\u53F0\u4E2D\u3002\");\n }\n}\n\nasync function workspaceRealm(context: Context, url: URL): Promise<WorkspaceRealm> {\n const rawId = url.searchParams.get(\"sessionId\");\n if (rawId === null || rawId === \"\") throw new WorkspaceHttpError(400, \"\u7F3A\u5C11 DSH sessionId\u3002\");\n const lookup = context.typert.lookups.get(\"agent\");\n if (lookup === undefined) throw new WorkspaceHttpError(503, \"DSH Agent lookup \u5F53\u524D\u4E0D\u53EF\u7528\u3002\");\n let agent: Agent | undefined;\n try {\n agent = await lookup.resolve(SessionId(rawId)) as Agent | undefined;\n } catch {\n throw new WorkspaceHttpError(404, \"DSH \u4F1A\u8BDD\u4E0D\u53EF\u7528\u3002\");\n }\n if (agent === undefined) throw new WorkspaceHttpError(404, \"DSH \u4F1A\u8BDD\u4E0D\u53EF\u7528\u3002\");\n if (agent.session.header.parentSession !== undefined || agent.session.header.origin === \"subagent\") {\n throw new WorkspaceHttpError(403, \"\u5B50 Agent \u4F1A\u8BDD\u4E0D\u5F00\u653E\u521B\u4F5C\u7F16\u8F91\u5668\u3002\");\n }\n const cwd = agent.session.header.cwd;\n if (cwd === undefined) throw new WorkspaceHttpError(409, \"\u5F53\u524D DSH \u4F1A\u8BDD\u6CA1\u6709\u5DE5\u4F5C\u76EE\u5F55\u3002\");\n const fs = agent.ctx.get(\"fs\");\n const sandboxPolicy = agent.ctx.get(\"sandboxPolicy\");\n if (fs === undefined || sandboxPolicy === undefined) throw new WorkspaceHttpError(503, \"DSH \u6587\u4EF6\u7CFB\u7EDF\u5F53\u524D\u4E0D\u53EF\u7528\u3002\");\n return { agent, fs, sandboxPolicy, cwd, root: await fs.resolve(cwd) };\n}\n\nasync function creativeTarget(realm: WorkspaceRealm, path: string): Promise<FsTarget> {\n assertCreativePath(path);\n const target = await realm.fs.resolve(path, { cwd: realm.cwd });\n if (!realm.fs.contains(realm.root, target)) throw new WorkspaceHttpError(403, \"\u6587\u4EF6\u8DEF\u5F84\u79BB\u5F00\u4E86 DSH \u5DE5\u4F5C\u76EE\u5F55\u3002\");\n return target;\n}\n\nfunction requireRegularFile(info: FsInfo | undefined): FsInfo {\n if (info === undefined) throw new WorkspaceHttpError(404, \"\u6587\u4EF6\u4E0D\u5B58\u5728\u3002\");\n if (info.type !== \"file\") throw new WorkspaceHttpError(415, \"\u76EE\u6807\u4E0D\u662F\u53EF\u7F16\u8F91\u7684\u666E\u901A\u6587\u4EF6\u3002\");\n return info;\n}\n\n/** Read bytes and a matching opaque version, retrying if a writer wins the read window. */\nasync function readVersionedFile(fs: FileSystem, target: FsTarget, maxBytes: number): Promise<ReadFileResult> {\n for (let attempt = 0; attempt < 3; attempt += 1) {\n const before = requireRegularFile(await fs.stat(target));\n if (before.size !== undefined && before.size > maxBytes) throw new WorkspaceHttpError(413, \"\u6587\u4EF6\u8D85\u8FC7\u5DE5\u4F5C\u53F0\u5927\u5C0F\u9650\u5236\u3002\");\n const bytes = await fs.readBytes(target, undefined, maxBytes);\n const after = requireRegularFile(await fs.stat(target));\n if (before.version !== after.version) continue;\n let content: string;\n try {\n content = new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n } catch {\n throw new WorkspaceHttpError(415, \"\u6587\u4EF6\u4E0D\u662F\u6709\u6548\u7684 UTF-8 \u6587\u672C\u3002\");\n }\n return { content, bytes: bytes.byteLength, version: after.version };\n }\n throw new WorkspaceHttpError(409, \"\u6587\u4EF6\u6B63\u5728\u88AB\u4FEE\u6539\uFF0C\u8BF7\u91CD\u8BD5\u3002\");\n}\n\nasync function listFiles(realm: WorkspaceRealm): Promise<WorkspaceFile[]> {\n const files: WorkspaceFile[] = [];\n const walk = async (path: string, directory: FsTarget): Promise<void> => {\n for (const entry of await realm.fs.listDir(directory)) {\n if (entry.name.startsWith(\".\") || !realm.fs.contains(realm.root, entry.target)) continue;\n const childPath = `${path}/${entry.name}`;\n if (entry.type === \"directory\") await walk(childPath, entry.target);\n else if (entry.type === \"file\" && EDITABLE_EXTENSIONS.has(extname(entry.name).toLocaleLowerCase())) {\n const info = entry.version === undefined || entry.size === undefined ? await realm.fs.stat(entry.target) : undefined;\n const version = entry.version ?? info?.version;\n if (version !== undefined) files.push({ path: childPath, bytes: entry.size ?? info?.size ?? 0, version });\n }\n if (files.length >= FILE_LIMIT) return;\n }\n };\n for (const directory of CREATIVE_DIRECTORIES) {\n const target = await realm.fs.resolve(directory, { cwd: realm.cwd });\n if (!realm.fs.contains(realm.root, target)) continue;\n const info = await realm.fs.stat(target);\n if (info?.type === \"directory\") await walk(directory, target);\n if (files.length >= FILE_LIMIT) break;\n }\n for (const path of ROOT_FILES) {\n const target = await creativeTarget(realm, path);\n const info = await realm.fs.stat(target);\n if (info?.type === \"file\") files.push({ path, bytes: info.size ?? 0, version: info.version });\n }\n return files.sort((left, right) => left.path.localeCompare(right.path, \"zh-Hans-CN\"));\n}\n\nasync function metadata(realm: WorkspaceRealm, files: readonly WorkspaceFile[], path: string, maxBytes: number): Promise<{ readonly value: unknown; readonly error?: string }> {\n if (!files.some((file) => file.path === path)) return { value: null };\n try {\n const target = await creativeTarget(realm, path);\n return { value: JSON.parse((await readVersionedFile(realm.fs, target, maxBytes)).content) as unknown };\n } catch (error) {\n return { value: null, error: error instanceof SyntaxError ? `${path} \u4E0D\u662F\u6709\u6548\u7684 JSON\u3002` : `${path} \u6682\u65F6\u65E0\u6CD5\u8BFB\u53D6\u3002` };\n }\n}\n\nfunction mapFsError(error: unknown): WorkspaceHttpError | undefined {\n if (!(error instanceof FsError)) return undefined;\n switch (error.code) {\n case \"FS_NOT_FOUND\": return new WorkspaceHttpError(404, \"\u6587\u4EF6\u4E0D\u5B58\u5728\u3002\");\n case \"FS_TOO_LARGE\": return new WorkspaceHttpError(413, \"\u6587\u4EF6\u8D85\u8FC7\u5DE5\u4F5C\u53F0\u5927\u5C0F\u9650\u5236\u3002\");\n case \"FS_NOT_TEXT\":\n case \"FS_NOT_REGULAR_FILE\": return new WorkspaceHttpError(415, \"\u76EE\u6807\u4E0D\u662F\u53EF\u7F16\u8F91\u7684\u6587\u672C\u6587\u4EF6\u3002\");\n case \"FS_PERMISSION_DENIED\":\n case \"FS_SANDBOX_DENIED\": return new WorkspaceHttpError(403, \"\u5F53\u524D DSH \u6743\u9650\u4E0D\u5141\u8BB8\u4FEE\u6539\u8BE5\u6587\u4EF6\u3002\");\n case \"FS_STALE_VERSION\":\n case \"FS_NOT_OBSERVED\": return new WorkspaceHttpError(412, \"\u6587\u4EF6\u5DF2\u5728\u78C1\u76D8\u4E0A\u66F4\u65B0\u3002\u8BF7\u5904\u7406\u51B2\u7A81\u540E\u518D\u4FDD\u5B58\u3002\");\n case \"FS_ABORTED\": return new WorkspaceHttpError(409, \"\u6587\u4EF6\u64CD\u4F5C\u5DF2\u53D6\u6D88\u3002\");\n default: return new WorkspaceHttpError(500, \"DSH \u6587\u4EF6\u7CFB\u7EDF\u64CD\u4F5C\u5931\u8D25\u3002\");\n }\n}\n\nasync function handle(context: Context, request: IncomingMessage, response: ServerResponse, options: WorkspaceRouteOptions): Promise<void> {\n try {\n if (!isTrustedWorkspaceRequest(request, options.trustedHosts ?? [])) throw new WorkspaceHttpError(403, \"\u8BF7\u6C42\u6765\u6E90\u4E0D\u53D7\u4FE1\u4EFB\u3002\");\n const url = new URL(request.url ?? \"/\", \"http://127.0.0.1\");\n if (url.pathname === \"/oh-story/workspace\" && request.method === \"GET\") {\n const realm = await workspaceRealm(context, url);\n const files = await listFiles(realm);\n const tracking = await metadata(realm, files, \"\u8FFD\u8E2A/_tracking-state.json\", options.maxBytes);\n const shortDrama = await metadata(realm, files, \"short-drama.json\", options.maxBytes);\n const metadataErrors = [tracking.error, shortDrama.error].filter((value): value is string => value !== undefined);\n send(response, 200, { cwd: realm.cwd, files, tracking: tracking.value, shortDrama: shortDrama.value, metadataErrors, mode: \"dsh-session\" });\n return;\n }\n if (url.pathname === \"/oh-story/file\" && request.method === \"GET\") {\n const realm = await workspaceRealm(context, url);\n const path = url.searchParams.get(\"path\");\n if (path === null) throw new WorkspaceHttpError(400, \"\u7F3A\u5C11\u6587\u4EF6\u8DEF\u5F84\u3002\");\n const file = await readVersionedFile(realm.fs, await creativeTarget(realm, path), options.maxBytes);\n send(response, 200, { path, ...file });\n return;\n }\n if (url.pathname === \"/oh-story/file\" && request.method === \"PUT\") {\n const realm = await workspaceRealm(context, url);\n const path = url.searchParams.get(\"path\");\n if (path === null) throw new WorkspaceHttpError(400, \"\u7F3A\u5C11\u6587\u4EF6\u8DEF\u5F84\u3002\");\n const input = await jsonBody(request, options.maxBytes * 6 + 1_024);\n if (typeof input.content !== \"string\") throw new WorkspaceHttpError(400, \"content \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u3002\");\n if (typeof input.baseVersion !== \"string\" || input.baseVersion === \"\") throw new WorkspaceHttpError(400, \"baseVersion \u5FC5\u987B\u662F\u6709\u6548\u7248\u672C\u3002\");\n if (Buffer.byteLength(input.content) > options.maxBytes) throw new WorkspaceHttpError(413, \"\u6587\u4EF6\u8D85\u8FC7\u5DE5\u4F5C\u53F0\u5927\u5C0F\u9650\u5236\u3002\");\n const outcome = await realm.fs.writeText(\n await creativeTarget(realm, path),\n input.content,\n { kind: \"replaceIfVersion\", version: input.baseVersion as FsVersion },\n undefined,\n realm.sandboxPolicy.resolve({ session: realm.agent.session })\n );\n send(response, 200, { path, content: outcome.after, bytes: Buffer.byteLength(outcome.after), version: outcome.version });\n return;\n }\n send(response, 404, { error: \"Oh Story route not found.\" });\n } catch (error) {\n const mapped = error instanceof WorkspaceHttpError ? error : mapFsError(error);\n if (mapped === undefined) context.logger(\"oh-story\").error(\"workspace route failed\", error);\n send(response, mapped?.status ?? 500, { error: mapped?.message ?? \"Oh Story workspace operation failed.\" });\n }\n}\n\n/** Mount the narrow editor API on DSH's official web-server extension seam. */\nexport function registerWorkspaceRoute(context: Context, options: WorkspaceRouteOptions): void {\n context.effect(() => context.webServer.register({\n kind: \"prefix\",\n path: \"/oh-story\",\n handler: (request, response) => handle(context, request, response, options)\n }), \"oh-story: DSH-session workspace API\");\n}\n", "import type { IncomingHttpHeaders } from \"node:http\";\n\ninterface WorkspaceTrustRequest {\n readonly headers: IncomingHttpHeaders | Headers;\n}\n\nfunction header(headers: IncomingHttpHeaders | Headers, name: string): string | undefined {\n if (headers instanceof Headers) return headers.get(name) ?? undefined;\n const value = headers[name];\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction parseAuthority(authority: string): URL | undefined {\n try { return new URL(`http://${authority}`); }\n catch { return undefined; }\n}\n\nfunction canonicalAuthority(entry: string, url: URL): string {\n const port = url.port !== \"\" ? url.port : new URL(`https://${entry}`).port;\n return port === \"\" ? url.hostname : `${url.hostname}:${port}`;\n}\n\nfunction isLoopbackHostname(hostname: string): boolean {\n if (hostname === \"localhost\" || hostname === \"[::1]\") return true;\n const parts = hostname.split(\".\");\n return parts.length === 4\n && parts[0] === \"127\"\n && parts.every((part) => /^\\d{1,3}$/u.test(part) && Number(part) <= 255);\n}\n\nfunction isTrustedAuthority(host: URL, trustedHosts: readonly string[]): boolean {\n return trustedHosts.some((entry) => {\n const candidate = parseAuthority(entry);\n if (candidate === undefined) return false;\n return canonicalAuthority(entry, candidate) === candidate.hostname\n ? candidate.hostname === host.hostname\n : candidate.host === host.host;\n });\n}\n\n/** Reject malformed declarations at plugin load instead of silently widening access. */\nexport function assertTrustedWorkspaceAuthority(entry: string): void {\n const url = parseAuthority(entry);\n if (url !== undefined && canonicalAuthority(entry, url) === entry.toLocaleLowerCase()) return;\n throw new Error(`oh-story: trustedHosts entry ${JSON.stringify(entry)} is not a bare host[:port] authority`);\n}\n\n/**\n * Same browser trust boundary as DSH's native API: every request must address a\n * loopback or explicitly trusted Host, and browser markers must be same-origin.\n */\nexport function isTrustedWorkspaceRequest(\n request: WorkspaceTrustRequest,\n trustedHosts: readonly string[]\n): boolean {\n const authority = header(request.headers, \"host\");\n if (authority === undefined) return false;\n const host = parseAuthority(authority);\n if (host === undefined) return false;\n if (!isLoopbackHostname(host.hostname) && !isTrustedAuthority(host, trustedHosts)) return false;\n if (header(request.headers, \"sec-fetch-site\") === \"cross-site\") return false;\n const origin = header(request.headers, \"origin\");\n if (origin === undefined) return true;\n try { return new URL(origin).host === host.host; }\n catch { return false; }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["name", "name", "readFile", "basename", "dirname", "join", "resolve", "fileURLToPath", "name", "name", "name", "target"]
|
|
7
7
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ChatSnapshot, ConversationTimelineSnapshot, PartialAssistant, RunningToolCall } from "@deepseek-ai/dsh-client-runtime/client";
|
|
2
2
|
export type MutationToolName = "write" | "edit" | "str_replace_editor";
|
|
3
3
|
export interface FileMutationActivity {
|
|
4
4
|
readonly callId: string;
|
|
@@ -9,22 +9,27 @@ export interface FileMutationActivity {
|
|
|
9
9
|
readonly operation: "replace-file" | "replace-text" | "insert-text" | undefined;
|
|
10
10
|
readonly oldText: string | undefined;
|
|
11
11
|
readonly newText: string | undefined;
|
|
12
|
+
readonly replaceAll: boolean;
|
|
12
13
|
}
|
|
13
14
|
interface JsonStringPrefix {
|
|
14
15
|
readonly value: string;
|
|
15
16
|
readonly complete: boolean;
|
|
16
17
|
}
|
|
17
18
|
export type WorkbenchMode = "story" | "drama";
|
|
19
|
+
/** Read the latest running Assistant step, including tool-only steps hidden from the Chat list. */
|
|
20
|
+
export declare function streamingAssistant(timeline: ConversationTimelineSnapshot): PartialAssistant | null;
|
|
18
21
|
/** Read a JSON string even while the model is still streaming its closing quote. */
|
|
19
22
|
export declare function jsonStringPrefix(raw: string, key: string): JsonStringPrefix | undefined;
|
|
20
|
-
/**
|
|
21
|
-
export declare function
|
|
23
|
+
/** Return every active file mutation in official DSH dispatch order, including nested Code Mode calls. */
|
|
24
|
+
export declare function fileMutations(runningCalls: readonly RunningToolCall[], partial?: PartialAssistant | null): FileMutationActivity[];
|
|
25
|
+
/** Running calls whose settlement may have changed creative files. */
|
|
26
|
+
export declare function mutatingCallIds(runningCalls: readonly RunningToolCall[]): ReadonlySet<string>;
|
|
27
|
+
/** Latest durable successful mutation, used when a fast call skips the live render window. */
|
|
28
|
+
export declare function latestSettledMutation(chat: ChatSnapshot): string | undefined;
|
|
22
29
|
/** Convert a DSH tool path to the creative-relative path accepted by the narrow route. */
|
|
23
30
|
export declare function creativeRelativePath(path: string | undefined, cwd: string | undefined): string | undefined;
|
|
24
31
|
export declare function workbenchModeForPath(path: string | undefined): WorkbenchMode | undefined;
|
|
25
|
-
/**
|
|
26
|
-
export declare function storyRelativePath(path: string | undefined, cwd: string | undefined): string | undefined;
|
|
27
|
-
/** Project a streamed mutation over the last authoritative disk content. */
|
|
32
|
+
/** Project one streamed mutation over its immediate predecessor. */
|
|
28
33
|
export declare function previewMutation(activity: FileMutationActivity, base: string): string | undefined;
|
|
29
34
|
export {};
|
|
30
35
|
//# sourceMappingURL=file-activity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-activity.d.ts","sourceRoot":"","sources":["../../../src/client/file-activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"file-activity.d.ts","sourceRoot":"","sources":["../../../src/client/file-activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,4BAA4B,EAC5B,gBAAgB,EAChB,eAAe,EAEhB,MAAM,wCAAwC,CAAC;AAGhD,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,GAAG,oBAAoB,CAAC;AAEvE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,cAAc,GAAG,cAAc,GAAG,aAAa,GAAG,SAAS,CAAC;IAChF,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,UAAU,gBAAgB;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,OAAO,CAAC;AAO9C,mGAAmG;AACnG,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,4BAA4B,GAAG,gBAAgB,GAAG,IAAI,CAUlG;AAgBD,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAuBvF;AA4FD,0GAA0G;AAC1G,wBAAgB,aAAa,CAC3B,YAAY,EAAE,SAAS,eAAe,EAAE,EACxC,OAAO,GAAE,gBAAgB,GAAG,IAAW,GACtC,oBAAoB,EAAE,CASxB;AAED,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,YAAY,EAAE,SAAS,eAAe,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAI7F;AAiBD,8FAA8F;AAC9F,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAS5E;AAED,0FAA0F;AAC1F,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAY1G;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAMxF;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAmBhG"}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ClientContext } from "@deepseek-ai/dsh-client-runtime/client";
|
|
2
2
|
export declare const name = "oh-story";
|
|
3
3
|
export declare const inject: string[];
|
|
4
|
+
declare module "@deepseek-ai/dsh-client-ui-slots" {
|
|
5
|
+
interface SlotMap {
|
|
6
|
+
"oh-story.workspace": {
|
|
7
|
+
kind: "single";
|
|
8
|
+
scope: "session";
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
4
12
|
/** Register only official DSH surfaces; the split bridge never replaces Chat. */
|
|
5
13
|
export declare function apply(context: ClientContext): void;
|
|
6
14
|
declare const _default: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,aAAa,EAA+C,MAAM,wCAAwC,CAAC;AAqBtI,eAAO,MAAM,IAAI,aAAa,CAAC;AAC/B,eAAO,MAAM,MAAM,UAAY,CAAC;AAEhC,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,OAAO;QACf,oBAAoB,EAAE;YAAE,IAAI,EAAE,QAAQ,CAAC;YAAC,KAAK,EAAE,SAAS,CAAA;SAAE,CAAC;KAC5D;CACF;AA21BD,iFAAiF;AACjF,wBAAgB,KAAK,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAkBlD;;;;;;AAED,wBAAuC"}
|
package/lib/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAKnD,OAAO,CAAC,MAAM,0BAA0B,CAAC;AAOzC,OAAO,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC9G,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACzH,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,eAAO,MAAM,IAAI,aAAa,CAAC;AAC/B,eAAO,MAAM,MAAM,UAA0D,CAAC;AAE9E,mFAAmF;AACnF,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAED,eAAO,MAAM,MAAM,EAGb,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhB,oEAAoE;AACpE,wBAAsB,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,GAAE,MAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhF;;;;;;;AAED,wBAA+C"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Context } from "@deepseek-ai/cordis";
|
|
2
|
+
import type { FileSystem } from "@deepseek-ai/dsh-fs";
|
|
2
3
|
import type { PreToolDecision, ToolExecution } from "@deepseek-ai/dsh-tools";
|
|
3
4
|
export interface StoryMutation {
|
|
4
5
|
readonly root: string;
|
|
@@ -6,11 +7,13 @@ export interface StoryMutation {
|
|
|
6
7
|
readonly chapter?: number;
|
|
7
8
|
}
|
|
8
9
|
export declare function detectStoryMutation(name: string, args: unknown, cwd: string | undefined): StoryMutation | undefined;
|
|
9
|
-
|
|
10
|
+
type StoryFileSystem = Pick<FileSystem, "resolve" | "contains" | "stat" | "listDir">;
|
|
11
|
+
export declare function validateStoryMutation(fs: StoryFileSystem, mutation: StoryMutation, signal?: AbortSignal): Promise<string | undefined>;
|
|
10
12
|
export declare function decideStoryMutation(exec: ToolExecution, next: () => Promise<PreToolDecision>): Promise<PreToolDecision>;
|
|
11
13
|
/**
|
|
12
14
|
* Native DSH equivalents of the upstream prose guards. They join DSH's typed
|
|
13
15
|
* tool waterfall, so decisions remain visible in the official approval/tool UI.
|
|
14
16
|
*/
|
|
15
17
|
export declare function registerOhStoryHooks(context: Context): void;
|
|
18
|
+
export {};
|
|
16
19
|
//# sourceMappingURL=native-hooks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-hooks.d.ts","sourceRoot":"","sources":["../../src/native-hooks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"native-hooks.d.ts","sourceRoot":"","sources":["../../src/native-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,qBAAqB,CAAC;AAEhE,OAAO,KAAK,EAAoB,eAAe,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAI/F,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAwBD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,CAenH;AAED,KAAK,eAAe,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC;AAkCrF,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,eAAe,EACnB,QAAQ,EAAE,aAAa,EACvB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAc7B;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,GACnC,OAAO,CAAC,eAAe,CAAC,CAQ1B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqB3D"}
|
|
@@ -3,8 +3,7 @@ interface WorkspaceRouteOptions {
|
|
|
3
3
|
readonly maxBytes: number;
|
|
4
4
|
readonly trustedHosts?: readonly string[];
|
|
5
5
|
}
|
|
6
|
-
|
|
7
|
-
/** This narrow route never starts agents, runs, streams, or models. */
|
|
6
|
+
/** Mount the narrow editor API on DSH's official web-server extension seam. */
|
|
8
7
|
export declare function registerWorkspaceRoute(context: Context, options: WorkspaceRouteOptions): void;
|
|
9
8
|
export {};
|
|
10
9
|
//# sourceMappingURL=workspace-route.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-route.d.ts","sourceRoot":"","sources":["../../src/workspace-route.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"workspace-route.d.ts","sourceRoot":"","sources":["../../src/workspace-route.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAgBnD,UAAU,qBAAqB;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAkOD,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAM7F"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-story/dsh",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A DSH plugin for fiction and short-drama production",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"inject": [
|
|
51
51
|
"@deepseek-ai/dsh-client-runtime",
|
|
52
52
|
"@deepseek-ai/dsh-client-ui-conversation",
|
|
53
|
+
"@deepseek-ai/dsh-client-ui-layout",
|
|
53
54
|
"@deepseek-ai/dsh-client-ui-tool"
|
|
54
55
|
],
|
|
55
56
|
"platform": "web"
|
|
@@ -67,37 +68,47 @@
|
|
|
67
68
|
"@deepseek-ai/dsh-agent": "^0.1.1-rc.1",
|
|
68
69
|
"@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.1",
|
|
69
70
|
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.1-rc.1",
|
|
71
|
+
"@deepseek-ai/dsh-client-ui-layout": "^0.1.1-rc.1",
|
|
70
72
|
"@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.1",
|
|
71
73
|
"@deepseek-ai/dsh-client-ui-tool": "^0.1.1-rc.1",
|
|
74
|
+
"@deepseek-ai/dsh-fs": "^0.1.1-rc.1",
|
|
72
75
|
"@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.1",
|
|
73
76
|
"@deepseek-ai/dsh-llm": "^0.1.1-rc.1",
|
|
74
77
|
"@deepseek-ai/dsh-session": "^0.1.1-rc.1",
|
|
78
|
+
"@deepseek-ai/dsh-sandbox-policy": "^0.1.1-rc.1",
|
|
75
79
|
"@deepseek-ai/dsh-skill": "^0.1.1-rc.1",
|
|
76
80
|
"@deepseek-ai/dsh-subagent": "^0.1.1-rc.1",
|
|
77
81
|
"@deepseek-ai/dsh-tools": "^0.1.1-rc.1",
|
|
82
|
+
"@deepseek-ai/dsh-typert-registry": "^0.1.1-rc.1",
|
|
78
83
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
79
84
|
"react": "^18.3.1",
|
|
80
|
-
"react-dom": "^18.3.1"
|
|
85
|
+
"react-dom": "^18.3.1",
|
|
86
|
+
"zod": "^4.4.3"
|
|
81
87
|
},
|
|
82
88
|
"devDependencies": {
|
|
83
89
|
"@deepseek-ai/cordis": "4.0.1",
|
|
84
90
|
"@deepseek-ai/dsh-agent": "0.1.1-rc.1",
|
|
85
91
|
"@deepseek-ai/dsh-client-runtime": "0.1.1-rc.1",
|
|
86
92
|
"@deepseek-ai/dsh-client-ui-conversation": "0.1.1-rc.1",
|
|
93
|
+
"@deepseek-ai/dsh-client-ui-layout": "0.1.1-rc.1",
|
|
87
94
|
"@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.1",
|
|
88
95
|
"@deepseek-ai/dsh-client-ui-tool": "0.1.1-rc.1",
|
|
96
|
+
"@deepseek-ai/dsh-fs": "0.1.1-rc.1",
|
|
89
97
|
"@deepseek-ai/dsh-host-webserver": "0.1.1-rc.1",
|
|
90
98
|
"@deepseek-ai/dsh-llm": "0.1.1-rc.1",
|
|
91
99
|
"@deepseek-ai/dsh-session": "0.1.1-rc.1",
|
|
100
|
+
"@deepseek-ai/dsh-sandbox-policy": "0.1.1-rc.1",
|
|
92
101
|
"@deepseek-ai/dsh-skill": "0.1.1-rc.1",
|
|
93
102
|
"@deepseek-ai/dsh-subagent": "0.1.1-rc.1",
|
|
94
103
|
"@deepseek-ai/dsh-tools": "0.1.1-rc.1",
|
|
104
|
+
"@deepseek-ai/dsh-typert-registry": "0.1.1-rc.1",
|
|
95
105
|
"@deepseek-ai/schemastery": "3.18.1",
|
|
96
106
|
"@types/react": "18.3.28",
|
|
97
107
|
"@types/react-dom": "18.3.7",
|
|
98
108
|
"react": "18.3.1",
|
|
99
109
|
"react-dom": "18.3.1",
|
|
100
|
-
"typescript": "6.0.3"
|
|
110
|
+
"typescript": "6.0.3",
|
|
111
|
+
"zod": "4.4.3"
|
|
101
112
|
},
|
|
102
113
|
"scripts": {
|
|
103
114
|
"build": "tsx ../../scripts/build-dsh-plugin.ts && tsc -p tsconfig.build.json",
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export declare class PathSecurityError extends Error {
|
|
2
|
-
constructor(message: string);
|
|
3
|
-
}
|
|
4
|
-
export declare function canonicalWorkspaceRoot(root: string): Promise<string>;
|
|
5
|
-
export declare function resolveWorkspacePath(root: string, relativePath: string, options?: {
|
|
6
|
-
readonly allowMissing?: boolean;
|
|
7
|
-
readonly expect?: "file" | "directory";
|
|
8
|
-
}): Promise<string>;
|
|
9
|
-
//# sourceMappingURL=workspace-security.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-security.d.ts","sourceRoot":"","sources":["../../src/workspace-security.ts"],"names":[],"mappings":"AAGA,qBAAa,iBAAkB,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM;CAInC;AAOD,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAK1E;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE;IAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;CAAO,GACxF,OAAO,CAAC,MAAM,CAAC,CAqCjB"}
|