{"id":"f26cbe2c-a94f-4b89-b326-e4f69b220e2d","entityType":"agent","slug":"clawhub-beep879-shareone","name":"ShareOne HTML & Document Share Links","canonicalUrl":"https://www.xpersona.co/agent/clawhub-beep879-shareone","canonicalPath":"/agent/clawhub-beep879-shareone","generatedAt":"2026-10-10T03:52:37.545Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T15:59:39.752Z","emptyReason":null},"description":"Host HTML pages and share PDF/Word/PPT","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 2.4K downloads reported by the source. Last updated 10/9/2026.","installCommand":"clawhub skill install s1738e1h5cmvnpnk4hnwhy9aa588xxxz:shareone","sourceUrl":"https://clawhub.ai/beep879/shareone","homepage":"https://clawhub.ai/beep879/skills/shareone","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/beep879/shareone","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/beep879/skills/shareone","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":67,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"ShareOne HTML & Document Share Links technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-09T15:59:39.752Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T15:59:39.752Z","emptyReason":null},"stars":null,"forks":null,"downloads":2352,"packageName":null,"latestVersion":"1.6.0","tractionLabel":"2.4K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T15:59:39.752Z","emptyReason":null},"lastUpdatedAt":"2026-10-09T15:59:39.752Z","lastCrawledAt":"2026-10-09T15:59:39.752Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-10T15:59:39.752Z","lastVerifiedAt":null,"highlights":[{"version":"1.6.0","createdAt":"2026-10-09T15:39:24.919Z","changelog":"ShareOne skill 1.6.0 - Updated SKILL.md to clarify workflows and ensure up-to-date usage documentation. - Improved/expanded documentation on routing logic and workflow file referencing. - Updated explanations for comment and publish workflows. - Removed outdated file: skill-card.md.","fileCount":56,"zipByteSize":148836},{"version":"1.5.0","createdAt":"2026-10-08T12:35:01.704Z","changelog":"ShareOne skill 1.5.0 – Adds Git-backed sources, notifications, and API improvements - Added support for GitHub/GitLab-backed content versioning and remote source workflows (see git-backed-versions.md). - Introduced agent notification/long-polling workflow and scripts (agent_watch.js) for real-time comment and scode handling. - Enhanced API handling and contracts with new test coverage and JSON contracts files. - Updated and refactored multiple workflow and script files for clarity and extended features. - Removed legacy/incomplete scripts and deprecated files.","fileCount":57,"zipByteSize":149019},{"version":"1.3.6","createdAt":"2026-09-29T05:54:50.878Z","changelog":"ShareOne v1.3.6 - Added canvas comments HTML template and related test for improved comment display and interaction. - Updated documentation in SKILL.md to match new version and reflect recent changes. - Removed obsolete skill-card.md file.","fileCount":50,"zipByteSize":126311},{"version":"1.3.5","createdAt":"2026-09-29T05:28:52.154Z","changelog":"- Version updated to 1.3.5. - Updated SKILL.md metadata to reflect new version. - Removed redundant skill-card.md file for a cleaner repository.","fileCount":48,"zipByteSize":119454},{"version":"1.3.4","createdAt":"2026-09-28T07:32:41.855Z","changelog":"**No user-facing functionality changes in this release.** - SKILL.md version updated to 1.3.4 (metadata only). - Internal documentation now reflects the new version. - Obsolete skill-card.md file removed.","fileCount":48,"zipByteSize":118952},{"version":"1.3.3","createdAt":"2026-09-27T10:49:00.258Z","changelog":"ShareOne Skill 1.3.3 - Updated version metadata in SKILL.md to 1.3.3. - Removed the redundant skill-card.md file.","fileCount":48,"zipByteSize":118458},{"version":"1.3.2","createdAt":"2026-09-23T04:36:48.554Z","changelog":"ShareOne skill v1.3.2 - Updated version metadata to 1.3.2. - Improved scripts/download_share.js for enhanced functionality or fixes. - Removed legacy documentation file skill-card.md.","fileCount":48,"zipByteSize":118224},{"version":"1.3.1","createdAt":"2026-09-23T03:39:35.125Z","changelog":"ShareOne Skill v1.3.1 - Updated documentation to increment version to 1.3.1. - Improved workflows for deleting shares and related scripts. - Removed redundant or outdated documentation file (skill-card.md).","fileCount":48,"zipByteSize":118190}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s1738e1h5cmvnpnk4hnwhy9aa588xxxz:shareone","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s1738e1h5cmvnpnk4hnwhy9aa588xxxz:shareone` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/beep879/shareone before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-beep879-shareone/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-beep879-shareone/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-beep879-shareone/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-beep879-shareone/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-beep879-shareone/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-beep879-shareone/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T03:52:37.542Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-beep879-shareone/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-beep879-shareone/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-beep879-shareone/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-beep879-shareone/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T15:59:39.752Z","emptyReason":null},"readme":"Skill: ShareOne HTML & Document Share Links\n\nOwner: beep879\n\nSummary: Host HTML pages and share PDF/Word/PPT\n\nTags: latest:1.6.0\n\nVersion history:\n\nv1.6.0 | 2026-10-09T15:39:24.919Z | auto\n\nShareOne skill 1.6.0\n\n- Updated SKILL.md to clarify workflows and ensure up-to-date usage documentation.\n- Improved/expanded documentation on routing logic and workflow file referencing.\n- Updated explanations for comment and publish workflows.\n- Removed outdated file: skill-card.md.\n\nv1.5.0 | 2026-10-08T12:35:01.704Z | auto\n\nShareOne skill 1.5.0 – Adds Git-backed sources, notifications, and API improvements\n\n- Added support for GitHub/GitLab-backed content versioning and remote source workflows (see git-backed-versions.md).\n- Introduced agent notification/long-polling workflow and scripts (agent_watch.js) for real-time comment and scode handling.\n- Enhanced API handling and contracts with new test coverage and JSON contracts files.\n- Updated and refactored multiple workflow and script files for clarity and extended features.\n- Removed legacy/incomplete scripts and deprecated files.\n\nv1.3.6 | 2026-09-29T05:54:50.878Z | auto\n\nShareOne v1.3.6\n\n- Added canvas comments HTML template and related test for improved comment display and interaction.\n- Updated documentation in SKILL.md to match new version and reflect recent changes.\n- Removed obsolete skill-card.md file.\n\nv1.3.5 | 2026-09-29T05:28:52.154Z | auto\n\n- Version updated to 1.3.5.\n- Updated SKILL.md metadata to reflect new version.\n- Removed redundant skill-card.md file for a cleaner repository.\n\nv1.3.4 | 2026-09-28T07:32:41.855Z | auto\n\n**No user-facing functionality changes in this release.**\n\n- SKILL.md version updated to 1.3.4 (metadata only).\n- Internal documentation now reflects the new version.\n- Obsolete skill-card.md file removed.\n\nv1.3.3 | 2026-09-27T10:49:00.258Z | auto\n\nShareOne Skill 1.3.3\n\n- Updated version metadata in SKILL.md to 1.3.3.\n- Removed the redundant skill-card.md file.\n\nv1.3.2 | 2026-09-23T04:36:48.554Z | auto\n\nShareOne skill v1.3.2\n\n- Updated version metadata to 1.3.2.\n- Improved scripts/download_share.js for enhanced functionality or fixes.\n- Removed legacy documentation file skill-card.md.\n\nv1.3.1 | 2026-09-23T03:39:35.125Z | auto\n\nShareOne Skill v1.3.1\n\n- Updated documentation to increment version to 1.3.1.\n- Improved workflows for deleting shares and related scripts.\n- Removed redundant or outdated documentation file (skill-card.md).\n\nv1.3.0 | 2026-09-22T17:59:21.144Z | auto\n\nShareOne skill 1.3.0\n\n- Added support for QR code generation via scripts/make_qr.js (outputs SVG path or full SVG as needed).\n- Included a new business card page template (templates/business-card.html).\n- Added automatic and manual test scripts (tests/test_business_card_template.js, tests/test_make_qr.js) to improve reliability.\n- Updated documentation with a new README.md and revised SKILL.md to document QR code usage in published pages.\n- Removed obsolete skill-card.md file.\n\nv1.2.12 | 2026-08-17T16:08:44.413Z | auto\n\n- Added account binding and registration workflow, including scripts for bind_account and corresponding documentation.\n- Introduced support for live tests of account binding and credential protection.\n- Updated workflow routing: handling of account binding and collaborator management is now separated from general settings.\n- Improved credential checking and guest key creation process.\n- Expanded usage documentation and refined publish/update workflows.\n- Removed obsolete skill-card.md.\n\nv1.2.11 | 2026-08-17T13:32:04.230Z | auto\n\n- Updated retention policy: clarified that shared links remain valid as long as they are accessed at least once every 90 days (not a strict 90-day deletion).\n- Updated all version references in SKILL.md to 1.2.11.\n- Removed the obsolete skill-card.md file.\n- Minor text clarifications for retention, public square, and remote_url content.\n- No functional changes to workflows or user experience.\n\nv1.2.10 | 2026-08-16T05:37:00.453Z | auto\n\n- Added new template: client-side-inference.html, showcasing local-only user data and inference usage.\n- Updated SKILL.md documentation to reference the new template and clarify local data storage flows.\n- Improved instructions for enabling per-page data, including usage of the injected window.__SHAREONE__ SDK and new local computation capability.\n- Removed obsolete skill-card.md.\n\nv1.2.9 | 2026-08-15T14:41:49.728Z | auto\n\n**Minor update with metadata/version bump and documentation cleanup.**\n\n- Updated version to 1.2.9 in SKILL.md and metadata.\n- Removed obsolete skill-card.md file.\n- No user-facing workflow or runtime changes.\n\nv1.2.8 | 2026-08-14T15:35:50.585Z | auto\n\n- Added support for \"页面持久化数据\" (persistent page data); users can now enable share-level data storage via `--allow-data true` setting.\n- Updated the global rules and workflows to clarify when and how to enable persistent server-side storage, with clear division between shared and private data.\n- Included a reference implementation page: `templates/page-storage-dropzone.html` for drag-and-drop public vs. sensitive file storage.\n- Revised comment workflow to require explicit state replies (`resolved-agree`, `open-disagree`, `open-need-input`) and prohibit silent dismissals for unresolved differences.\n- Minor documentation corrections and examples to match new features and usage patterns.\n\nv1.2.7 | 2026-07-25T08:19:43.290Z | auto\n\n**Adds support for deleting shares and refreshing remote-bound shares. Updates core workflows and routing logic.**\n\n- Added support for deleting ShareOne links (soft delete for any share type).\n- Added support for refreshing remote-url auto-follow shares explicitly.\n- Introduced new scripts: `delete_share.js`, `refresh_share.js`, and improved comment retrieval with `comment_list.js`.\n- Updated core workflows and routing order to include deletion and refresh operations.\n- Documentation and workflow files revised to reflect new features and usage patterns.\n- Removed outdated `skill-card.md`.\n\nv1.2.6 | 2026-07-23T06:39:49.812Z | auto\n\nVersion 1.2.6\n\n- Refined the SKILL.md metadata: added new top-level keys (slug, displayName, version, summary, tags) for improved clarity and compatibility.\n- Updated description and summary formatting in SKILL.md.\n- Changed the pre-publish policy from requiring explicit user consent to a non-blocking automatic content safety self-check; removed the need to prompt for user agreement before publishing.\n- Clarified that self-check is lightweight and applied only before first publish, not for subsequent updates or metadata changes.\n- Removed outdated file: skill-card.md.\n- Minor workflow documentation updates for comments-process, publish-binary-file, publish-text-page, and update-share-settings.\n\nv1.2.5 | 2026-07-15T10:49:28.478Z | auto\n\n- Added support for publishing from remote and GitHub URLs.\n- Introduced collaborator management (see new scripts and workflow).\n- Internal: metadata structure in SKILL.md updated and English summary expanded.\n- Documentation, workflows, and scripts updated for clarity and new routes.\n- Removed deprecated skill-card.md.\n\nv1.2.3 | 2026-06-30T01:10:35.346Z | auto\n\n- Updated documentation in SKILL.md to clarify usage, routing logic, and global constraints.\n- Removed the file skill-card.md.\n- No changes to core logic or functionality.\n\nv1.2.2 | 2026-06-23T09:18:33.183Z | auto\n\nshareone 1.2.2\n\n- 添加 slug、displayName、summary、tags、license 等元数据字段，增强 skill 的可发现性和描述性\n- 明确 description 及使用场景，优化对“下载”、“修改”、“评论”相关场景的说明\n- 修改样例链接的主域名（如 https://shareone.app → https://s.shareone.vip）以反映最新实际地址\n- 移除 skill-card.md，简化项目结构\n- workflows/result-and-errors.md、小脚本细节同步调整以配合新版规范\n- SKILL.md 细节统一及内容简化，提升维护一致性\n\nv1.2.1 | 2026-06-18T08:16:06.513Z | auto\n\nshareone 1.2.1\n\n- 增加 LICENSE 文件，完善开源合规性。\n- 新增 `scripts/publish.js`，统一处理文本和二进制文件的内容发布。\n- 新增 `scripts/ensure_credentials.js` 和 `scripts/comment_resolve.js`，加强凭据自动管理和评论处理流程。\n- 移除 skill-card.md，文档结构调整。\n- SKILL.md 与工作流文档全面更新，进一步明确脚本调用规则、流程路由顺序及安全确认场景，提升多场景适配能力。\n- 多处脚本功能完善和 bugfix，增强环境和凭据自动检测。\n\nv1.2.0 | 2026-06-11T02:54:29.725Z | user\n\nshareone 1.2.0\n\n- 更新 Sudowork 环境与 API Key 检测流程，细化多种 Sudowork/普通环境下凭据与认证状态的判断。\n- 规定所有非 Sudowork secrets 的本地凭据都仅读写于 skill 安装目录下的 `.shareone_credentials` 文件，统一不同 Agent 产品的本地密钥路径。\n- 明确 Sudowork 环境失效时自动回退为普通 AI Agent 认证流程，并允许本地/环境变量密钥。\n- 调整并补充凭据、环境识别和技能入口路由的详细规则描述。\n- 移除冗余 skill-card.md 文件。\n\nv1.1.8 | 2026-06-09T02:16:22.706Z | user\n\n**Major update: Expanded skill from publish-only to full ShareOne link/file/comment management. Task routing and workflows modularized.**\n\n- Added script and workflow support for downloading ShareOne links, updating file/page settings, viewing and processing comments, and deleting API keys.\n- Separated workflows by typical task (publish, download, update settings, comments, etc.) and strictly routed main logic to only read needed workflow at runtime.\n- Updated publish triggers and user intent detection to include not only content publishing, but also downloading files, editing shared content, and comment handling.\n- Strengthened environment and credential handling (now distinguishes between Sudowork/auth proxy and standard agent flows).\n- Added clear blocking step guidance: API key/consent/user prompt notifications now must be surfaced where relevant before task execution.\n- Rewrote and expanded constraints to avoid running local shareone CLI, enforce security prompts, and ensure modular, futureproof skill behavior.\n\nv1.0.3 | 2026-04-10T03:30:56.038Z | user\n\nshareone 1.0.3\n\n- 新增详细 SKILL.md，全面梳理 ShareOne 平台一键分享流程。\n- 规范了 API Key 检查、保存及自动申请流程，并增加相关用户提示。\n- 完善使用说明及适用场景，支持 HTML、PDF、PPTX 文件的上传与在线获取短链。\n- 引入用户同意机制与安全提示，确保合法合规内容发布。\n- 明确文本类与二进制文件两类上传接口的操作区分及异常处理方式。\n- 优化分享成功后的人性化功能提示，提高用户对高级特性的知晓度。\n\nArchive index:\n\nArchive v1.6.0: 56 files, 148836 bytes\n\nFiles: agents/openai.yaml (238b), LICENSE (1068b), README.md (5303b), scripts/agent_watch.js (8577b), scripts/api_contract.json (7185b), scripts/bind_account.js (3464b), scripts/check_api_key.js (1912b), scripts/comment_list.js (1627b), scripts/comment_reply.js (1715b), scripts/create_guest_key.js (3000b), scripts/delete_api_key.js (1259b), scripts/delete_share.js (2657b), scripts/download_share.js (6206b), scripts/ensure_credentials.js (9279b), scripts/make_qr.js (23390b), scripts/manage_collaborators.js (4031b), scripts/proxy_support.test.cjs (4862b), scripts/publish.js (4790b), scripts/refresh_share.js (2253b), scripts/save_api_key.js (1461b), scripts/scode_receive.js (4752b), scripts/shareone_api_request.js (3522b), scripts/shareone_client.js (30721b), scripts/shareone_upload.js (8446b), scripts/update_share_settings.js (6140b), scripts/upload_page.js (8460b), SKILL.md (19591b), templates/business-card.html (22681b), templates/canvas-comments.html (11050b), templates/client-side-inference.html (5542b), templates/page-storage-dropzone.html (5476b), test/redirect_follow.test.js (4236b), tests/test_agent_watch.js (5305b), tests/test_api_contracts.js (8698b), tests/test_bind_account_live.js (8564b), tests/test_business_card_template.js (5020b), tests/test_canvas_comments_template.js (4801b), tests/test_credential_guard.js (5745b), tests/test_make_qr.js (6656b), tests/test_scode_receive.js (1942b), workflows/agent-notifications.md (5688b), workflows/bind-account.md (2782b), workflows/comments-process.md (11333b), workflows/comments-view.md (3984b), workflows/delete-api-key.md (1084b), workflows/delete-share.md (2211b), workflows/download-file.md (3715b), workflows/environment-and-credentials.md (3589b), workflows/git-backed-versions.md (6447b), workflows/manage-collaborators.md (3688b), workflows/publish-binary-file.md (3645b), workflows/publish-text-page.md (19077b), workflows/refresh-remote.md (2067b), workflows/result-and-errors.md (7542b), workflows/update-share-settings.md (2729b), _meta.json (127b)\n\nFile v1.6.0:SKILL.md\n\n---\nname: shareone\ndescription: Host HTML/Markdown pages and share PDF, Word, or PowerPoint docs as ShareOne short links. Use for publishing, passwords/watermarks, comments, downloads, updates, or Git-backed remote sources for ShareOne content.\nlicense: MIT\nmetadata:\n  slug: shareone\n  display-name: ShareOne\n  version: 1.6.0\n  summary: Host HTML pages and share PDF/Word/PPT docs with short links\n  tags:\n    - shareone\n    - publish\n    - sharing\n    - hosting\n    - html\n    - upload\n---\n\n# AI Agent 技能：发布到 ShareOne (shareone)\n\nHost HTML/Markdown pages and share PDF, Word, and PowerPoint documents with ShareOne public short links. Covers page publishing, document sharing, password protection, watermarks, review comments, downloads, and updates to existing shares.\n\n这个 Skill 允许 AI Agent 将当前生成的历史会话以及 HTML/Markdown/TXT/PDF/PPT 等文件发布到 ShareOne 线上托管服务，并为用户生成一个持久化的公网分享链接；也可以对已有 ShareOne 链接执行下载、内容更新、设置修改和评论处理。\n\n## 内容版本管理决策\n\nShareOne 复用 **GitHub / GitLab 的内容版本管理**：历史、diff、分支、评审和回退在源仓库完成，ShareOne 负责展示、分享、访问控制和评论协作。`remote_url` 的 snapshot 是当前缓存，ShareOne 不维护独立的文件版本库。\n\n涉及 ShareOne 内容的 Git 源、版本选择、历史或回退时，先读 [workflows/git-backed-versions.md](workflows/git-backed-versions.md)，再按下方路由执行发布、刷新或评论处理。该工作流包含跟随分支、固定 commit、切换版本与验收命令。**当前可直接使用公开 GitHub 文本文件；GitLab 和私有仓库认证仍需接入，不能把产品方向当作已支持能力。** 普通本地文件上传仍按原流程执行，不自行迁移到 Git。\n\n## 脚本执行基准\n\n本文档中所有 `node scripts/xxx.js` 命令的路径都以 **本 skill 的安装目录**（即本 `SKILL.md` 所在目录）为基准。当前工作目录通常是用户的项目目录，直接执行相对路径会失败。执行前先确定 skill 目录，使用绝对路径或先 `cd` 到 skill 目录，例如：\n\n```bash\nnode /path/to/shareone-skill/scripts/ensure_credentials.js\n```\n\n## 入口隔离规则\n\n本 skill 和用户本机可能安装的 `shareone` CLI 是两个独立入口。除非用户明确要求”使用 CLI”或指定执行 `shareone ...` 命令，否则不要调用系统 PATH 中的 `shareone` 命令。即使 `which shareone` 能找到 CLI，也不要把自然语言的发布、下载、评论处理任务改走 CLI。所有 ShareOne 操作都必须调用本 skill 目录内 `scripts/` 下的脚本。\n\n## 使用说明与触发条件\n\n当用户表达出以下意图时，应主动使用此技能：\n\n- \"帮我把 `index.html` 发布到 ShareOne\"\n- \"把我刚才生成的网页发布，给我个链接\"\n- \"生成一个可分享的链接给我的团队看\"\n- \"Upload this presentation to ShareOne and protect it with password 'secret'\"\n- \"发布这个 PDF 到 ShareOne，并加上密码 1234\"\n- \"把这个网页发布到 ShareOne，加上水印 '内部绝密'\"\n- \"把这个网页发布到 ShareOne，链接叫 product-demo\"\n- \"发布这份设计稿并开启协同评论模式\"\n- \"用 shareone 分享上一轮对话\"\n- \"把我刚才写的代码/大段文字分享出去\"\n- \"Share your last response as a note\"\n- \"帮我下载这个 ShareOne 链接的文件：https://s.shareone.vip/s/xxx\"\n- \"拉取一下这个链接的评论：https://s.shareone.vip/s/xxx\"\n- \"删掉/删除这个 ShareOne 链接：https://s.shareone.vip/s/xxx\"\n- \"我 push 了，刷新一下这个 ShareOne 远程链接的内容：https://s.shareone.vip/s/xxx\"\n- \"给这个 ShareOne 链接加水印：https://s.shareone.vip/s/xxx\"\n- \"根据这个链接的评论修改页面：https://s.shareone.vip/s/xxx\"\n- \"修改这个 ShareOne 链接的内容：https://s.shareone.vip/s/xxx\"\n- \"把这个 GitHub 文件发布到 ShareOne：https://github.com/org/repo/blob/main/report.html\"\n- \"用远程 URL 发布这个页面\"\n- \"Publish this GitHub raw URL to ShareOne\"\n\n## 路由判定顺序（唯一路由依据）\n\n入口文件只负责判断用户意图、选择需要阅读的 workflow。不要一次性读取所有 `workflows/*.md`；只读取当前任务命中的子文件。\n\n持续监听评论、接收持久通知或唤醒 scode / 其他 Agent：先读 `workflows/environment-and-credentials.md`，再读 `workflows/agent-notifications.md`，使用 `scripts/agent_watch.js`。普通评论查看和单次处理按以下路由执行，不启动常驻监听。\n\n按以下顺序从上到下判断，**命中第一条即停止**，按该条给出的阅读顺序执行：\n\n1. **删除/清除/移除/重置 ShareOne API Key**\n   → 读 `workflows/delete-api-key.md`。无需凭据检查。\n\n2. **删除/移除 ShareOne 分享链接本身（用户明确要求“删掉/删除/移除”某个 share_id、slug 或链接）**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/delete-share.md`。删除是 owner-only 操作，执行前须与用户确认（软删除后公开链接立即失效）。对 HTML/文本页和二进制文件链接（`/pdf/`、`/ppt/`、`/word/`）通用。注意与第 6 条区分：本条是删除整个 share，不是改设置。\n\n3. **刷新 remote-url auto-follow 分享的源内容（用户说“我 push 了”“拉一下最新源”“刷新这个远程链接”）**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/refresh-remote.md`。remote 页面刷新是懒的、只在打开渲染页时触发，下载/`/file` 只服务缓存；本条用 `refresh_share.js` 显式强制 refetch。仅对绑定了远程 URL 的分享有效；非 remote-bound 返回 `NOT_REMOTE_BOUND`，此时应改走第 6 或第 10 条（改设置 / 重新发布内容）。\n\n4. **绑定账号、注册、升级 guest、绑定邮箱**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/bind-account.md`。\n\n5. **让别人一起编辑、分享编辑权限、添加/移除/查看协作者、对方怎么拿 API Key**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/manage-collaborators.md`，最后读 `workflows/result-and-errors.md`。\n\n6. **用户提供已有 ShareOne 链接、`share_id` 或 slug，且只要求修改水印、访问密码、自定义短链接、评论开关或数据存储开关（不改内容本身）**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/update-share-settings.md`，最后读 `workflows/result-and-errors.md`。\n   这是元数据更新：不要按文件类型路由，不要下载源文件，不要使用 `publish.js`，不要重新上传内容。对二进制文件链接（`/pdf/`、`/ppt/`、`/word/`）同样适用本条。\n\n7. **下载 ShareOne 链接的文件或取回源内容**\n   → 读 `workflows/download-file.md`。下载脚本会在已有凭据时优先尝试 owner 下载，没有凭据时自动走公开下载；不要为了普通下载强制配置 API Key。\n\n8. **只查看、拉取、总结 ShareOne 链接评论（用户没有要求修改）**\n   → 读 `workflows/comments-view.md`。单次查看用 `comment_list.js`，走公开接口，无需凭据检查；维护评论缓存时使用该 workflow 的增量查询步骤。\n\n9. **处理评论、根据评论修改页面、修复 ShareOne 链接内容**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/comments-process.md`（其中的重新发布步骤会引用 `workflows/publish-text-page.md`），最后读 `workflows/result-and-errors.md`。\n\n10. **发布、分享、生成链接、上线（创建新链接或更新已有链接的内容）**\n   → 先读 `workflows/environment-and-credentials.md`，再按目标文件类型二选一，最后读 `workflows/result-and-errors.md`：\n   - `.ppt`、`.pptx`、`.pdf`、`.doc`、`.docx` → `workflows/publish-binary-file.md`\n   - `.html`、`.md`、`.txt`、对话内容、大段文本、代码块、已包装成 HTML 的内容 → `workflows/publish-text-page.md`。注意：`.md`/`.txt` 一律按原格式发布，不要因为内容包含图表就转成 HTML；只有目标本来就是 HTML 页面时才参考其中的 Mermaid.js 章节。\n\n所有需要 ShareOne API 的操作（上面第 2、3、4、5、6、7、9、10 条），都先运行 `node scripts/ensure_credentials.js`，输出 token 含义与处理流程见 `workflows/environment-and-credentials.md`，这里不重复。\n\n## ShareOne 链接与 share_id\n\n- 用户提供的目标可以是完整链接、`/s/<ref>` 等路径、裸 `share_id`（16 位字符串）或自定义短链 slug。服务端接口同时接受 `share_id` 和 slug，无需自行区分两者。\n- `/s/<share_id>` 是最终给用户访问的分享链接，**不是上传 API endpoint**。不要把 `/s/<share_id>` 当作发布地址，也不要直接向 `/s/<share_id>` PUT/POST 文件。\n- 路径前缀与内容类型的对应关系：`/s/`、`/md/` 是文本/HTML/Markdown 页面；`/pdf/`、`/ppt/`、`/word/` 是二进制文件。元数据更新时 `update_share_settings.js` 会按此前缀自动选择 endpoint，裸 `share_id` 或 slug 由脚本先试页面 endpoint、必要时回退文件 endpoint，整个过程不下载源文件。\n- 文本页里 `/s/<ref>` 与 `/md/<ref>` **等价**：前缀不绑定、也不校验内容类型，浏览路由一律按 ref 解析 share、按 share 真实 content-type 渲染。因此文本页可以就地把 content-type 从 md 升级成 html（`.md → .html`，如把 ASCII 图升级成 Mermaid），URL（含老的 `/md/<slug>`）一字不变、评论保留——见 `workflows/publish-text-page.md` §6b。升级用 `--share-id` 更新，**绝不 `--force-new`**。\n- 本地文件发布与更新统一使用 `publish.js`，脚本按文件类型自动分发（stderr 输出 `INFO:CHANNEL:text|binary`）。远程源例外：使用 `upload_page.js --remote-url` 创建或更换源 URL，`refresh_share.js` 刷新已有源。不要因为会话里存在旧的 `/s/<share_id>` 就把二进制文件改走文本页面 PUT；二进制文件传 `--share-id` 会被脚本拒绝（`ERROR:BINARY_NO_SHARE_ID`）。\n- 如果当前会话中已经为同一个文本/HTML 文件生成过 ShareOne 链接，可复用之前的 `share_id` 执行文本页面 PUT 更新；否则执行首次创建。\n- 非 owner 下载要求链接已开启允许下载；若脚本输出 `ERROR:DOWNLOAD_NOT_ALLOWED`，直接提示用户让链接 owner 先开启允许下载。\n\n## 发布前安全自检（非阻塞）\n\n- 创建新分享链接（首次 POST 新页面或首次上传新文件）前，Agent 必须自行做内容安全自检：不得发布明显反动、涉政、暴力、色情、侵权或恶意代码内容。\n- 链接保留规则：普通链接在**最后活跃时间**超过 90 天后会被清理（最后活跃 = 创建时间或最后一次被访问时间的较晚者，持续有效访问会一直保持有效，不是发布后 90 天硬删除）；发布到 Explore 公开广场、被知识库引用、或设了 `remote_url` 的内容不参与此无活跃自动清理。\n- 自检通过后直接继续发布，不要向用户展示安全提示，也不要等待用户回复“同意”或 `agree`。\n- 自检必须轻量：对文本/HTML/Markdown/TXT，只基于当前已知内容或发布所需读取的文本内容判断；对 PDF/PPT/Word 等二进制文件，只基于用户请求、文件名、扩展名和显式参数判断，不要为了自检提取正文、OCR、转换格式或解析文件内部内容。\n- 如果内容明显违反上述规则，停止发布并简要说明原因。\n- 对已有链接执行后续操作时——包括内容 PUT 更新、评论处理闭环中的重新发布、水印/密码/短链/评论开关等元数据修改——按对应 workflow 直接执行。\n- 下载、查看评论、删除 API Key 等不发布内容的操作无需安全自检。\n\n## 不可跳过的阻塞步骤\n\n以下步骤是阻塞性用户通知，不是可选说明。触发后必须先发给用户，再继续后续操作。\n\n- 如果 `ensure_credentials.js --create-guest` 或底层 `create_guest_key.js` 输出 `GUEST_KEY_CREATED:<api_key>`，必须立即向用户发送临时 API Key、绑定账号链接和保存提醒（话术见 `workflows/environment-and-credentials.md`）。即使 key 已经自动保存，也不能省略该通知；发送前不得继续执行原任务的上传、下载、评论处理命令。\n- 本会话首次向用户展示生成的 `share_url` 时，必须按 `workflows/result-and-errors.md` 提示所有未使用的高级功能：自定义短链接名称、访问密码、水印。已使用的能力不再提示；三项都已使用则不提示。\n\n## 全局约束\n\n- 发布前必须完成凭据检查和必要的凭据配置。\n- 发布成功后必须直接使用脚本返回的 `share_url`，不要自行拼接分享链接；不要展示备用链接。\n- 只有当用户明确要求开启评论、允许讨论或协同模式时，才添加 `--allow-comments true`。默认不开启评论。\n- 只有当用户明确要求页面持久化数据（如保存游戏分数、表单状态）时，才添加 `--allow-data true`。默认不开启数据存储。\n- 页面持久化数据时，页面代码用自动注入的 `window.__SHAREONE__` SDK，**必须按敏感度二选一、无默认**：`putShared(key, value|File)` 存服务器·所有访客可读·跨设备（大文件自动走 blob，≤8MB）；`putPrivate(key, value|File)` 只存这台设备·私有·不上传。命名即风险（Shared=别人能看），敏感/隐私数据一律 `putPrivate`。现成的“公开 vs 敏感”拖拽上传参考页：`templates/page-storage-dropzone.html`；私有数据可留在本机就地推理（模型公开＋数据 `putPrivate`＋页面内计算，字节不出设备）的参考页：`templates/client-side-inference.html`；完整 SDK 见后端 `agent.md` §14。发布时若带 `--allow-data true`，命令行会在成功后打印一行 `HINT:PAGE_DATA_ENABLED` 提示该二选一与本地推理用法。\n- 自定义短链接（slug）：服务端会根据文件名自动生成可读的 slug（如 `quarterly-report`），客户端无需额外操作。只有用户明确要求“链接叫 xxx”、“自定义短链接 xxx”、“URL 后缀 xxx”时，才在发布命令添加 `--slug xxx` 覆盖自动生成；slug 冲突时把服务端提示反馈给用户，不要静默改名。\n- 页面需要二维码时用 `node scripts/make_qr.js --text \"<内容>\" --format path`（零依赖，直出 SVG path，贴进页面的 `<path d=\"...\">`；`--format svg` 给完整 `<svg>`，`--ecc L|M|Q|H` 默认 Q）。**不要**引入外部二维码库或 `<img src=\"https://...qrserver...\">` 之类的在线生成服务——发布出去的页面在别人的浏览器里打开，外链会失效、泄露访问者，也印不进 PDF。二维码指向本次发布的链接时，先用 `--slug` 定好链接再生成二维码，顺序反了码会指向不存在的页面。\n- 名片/电子名片：用 `templates/business-card.html`（双面设计，一份 HTML 同时产出可发的图片、可扫的链接、90×54mm 印刷 PDF）。改 `data-field=\"...\"` 的文字即可，vCard 和 tel:/mailto: 由页面脚本从卡面读取，不要另写一份联系方式。二维码指向名片页本身而不是公司官网：扫码的人当场要的是把人存进通讯录，名片页能一键存 vCard，且印出去的卡改不了、名片页能随时更新。\n- 开启评论的页面**不要用 MutationObserver 监听自己的输出来触发重绘**。ShareOne 会往页面里注入评论桥（样式、覆盖层、高亮包裹），这本身就是 DOM 变化；页面若据此重绘、重绘又改 DOM，会自持成无限循环，页面直接跑飞（实测：关评论 render 1 次，开评论 502 次）。确实需要按变化重绘时，用内容签名门控：先算出这一帧该画什么，和上一帧比，一样就不画。同理，**不要在 `pointerdown` 里无条件 `setPointerCapture`** —— 指针被容器捕获后，`click` 会派发给捕获者而不是被点的元素，页面里所有节点都点不动，而元素还在、`elementFromPoint` 也正常，很难查；平移交互应等 `pointermove` 超过 3–5px 再捕获。\n- 评论需要跨折叠、分页、语言或呈现方式追踪命名对象时，用 `window.__SHAREONE__.anchors` 声明稳定 ID，按 [动态页面与文字评论](workflows/publish-text-page.md#动态页面与文字评论) 接入选择、位置报告和恢复；canvas/地图/3D 等没有独立 DOM 的目标也使用它。`hidden` 表示目标确实存在但当前视图没画；`missing` 仅表示当前完整模型确认目标已不存在；未确定时报告 `pending`，不回答的 ID 也处于等待状态。侧栏区分这三种状态、旧文字无法定位和区域部分可用，并保留原文、回复和部分目标的状态。锚点只存稳定 ID 与阅读上下文，坐标和当前状态不落库。参考 `templates/canvas-comments.html`；完整接口见后端 `agent.md` §14b。\n- 开启评论且页面会自己重绘（图表、流程图、看板、任何切换视图就重建 DOM 的页面）时，给每个可评论元素加一个稳定的 `data-*` id，例如 `<g class=\"node\" data-node-id=\"委外cap\">`。ShareOne 的区域评论以应用自己给的这个 id 作锚，重绘后评论自动跟回同一个元素；没有 id 时只能退回\"第几个同名标签\"的结构路径，重绘可能使它失效。id 在同一页内必须唯一（命中多个元素的 id 会被拒绝），且在重绘前后保持不变——用业务含义命名，别用渲染顺序生成。\n- 生成或修改启用评论的动态 HTML 时，按 [publish-text-page.md 的动态页面要求](workflows/publish-text-page.md#动态页面与文字评论) 保留可阅读文本与稳定身份。文字锚点不索引 SCRIPT/STYLE/NOSCRIPT/TEMPLATE 或标注浮层；大体积数据保留完整，可放在 head 的非执行数据脚本中。性能验收保留评论，实际展开、缩放和拖动；文本定位失败只表示锚点不可用，不代表评论或原文已删除。\n- 评论处理必须形成闭环：认领、修改源内容、同步原分享并验证，然后用 `comment_reply.js --state`（`--state` 必填）**明确表态**——`resolved-agree`（同意收敛）/ `open-disagree`（有异议但保持 open）/ `open-need-input`（需人类澄清）。绑定 Git 源的页面修改仓库后刷新，具体见 `comments-process.md` 和 `git-backed-versions.md`。AI **永不**单方面 dismiss 一条分歧：不同意用 `open-disagree`，`dismiss` 仅用于 owner 确认的无关或垃圾评论；定位失败、权限不足或等待同步时用 `open-need-input`。\n\n## 最终回复前检查清单\n\n在回复用户前，逐项检查：\n\n- 如果本轮创建了临时 API Key，是否已经把 API Key、绑定账号链接和保存提醒发给用户。\n- 如果本轮**创建了新分享链接**，是否已完成发布前安全自检；如果内容明显违规，是否已停止发布。\n- 如果发布成功，是否直接展示返回的 `share_url`，没有自行拼接链接。\n- 如果返回中包含 `custom_slug_warning` 或 `custom_slug_suggestions`，是否展示给用户。\n- 如果这是本会话首次展示生成的 `share_url`，是否提示所有未使用的高级功能。\n\nFile v1.6.0:README.md\n\n# ShareOne Skill：AI Agent 发布与文档分享工具\n\n<p align=\"center\">\n  <strong>把 AI 生成的网页、Markdown、PDF、Word 和 PowerPoint 文档发布为 ShareOne 短链接。</strong>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://shareone.vip\"><img alt=\"Website\" src=\"https://img.shields.io/badge/website-shareone.vip-0f766e\"></a>\n  <img alt=\"ShareOne\" src=\"https://img.shields.io/badge/ShareOne-skill-2563eb\">\n  <img alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-64748b\">\n</p>\n\n官网：https://shareone.vip\n\n\n\n本仓库包含 ShareOne Agent Skill。它让 Codex、Claude Code、OpenAI Agent、Dify、工作流自动化工具等 AI Agent 可以把本地生成的内容快速发布到 ShareOne，并生成可访问、可转发、可更新的公网分享链接。\n\nShareOne 适合用于发布 AI 生成页面、分享 Markdown 在线文档、托管 HTML 演示页、上传 PDF/Word/PPT 文件、生成团队评审链接，以及为文档添加访问密码、水印和评论协作能力。\n\n## 关键词\n\nShareOne 覆盖以下搜索场景：AI Agent 发布工具、HTML 页面托管、Markdown 在线分享、PDF 短链接分享、Word 文档分享、PPT 在线分享、文档水印、访问密码分享链接、AI 生成网页发布、Codex Skill 文档发布、Agent workflow publishing。\n\n## ShareOne 是什么\n\nShareOne 是一个面向 AI Agent 和开发者的轻量级内容发布服务。它可以把 HTML、Markdown、TXT、PDF、Word、PowerPoint 等文件发布为短链接，方便用户在聊天、项目协作、客户沟通、产品演示和内容交付场景中快速分享。\n\n通过 ShareOne Skill，AI Agent 不需要让用户手动上传文件，也不需要额外搭建静态站点。Agent 可以直接调用 Skill 脚本完成发布、更新、下载、评论读取和设置修改。\n\n## 免费托管\n\nShareOne 提供免费的页面与文档托管能力，适合临时演示、项目评审、AI 生成内容分享、客户预览和团队协作。\n\n普通分享链接会按最后活跃时间保留：只要链接持续有有效访问，就会继续保持可用；当距离最后一次有效访问超过 90 天后，链接才可能被自动清理。也就是说，链接不是从发布时间开始固定 90 天过期，而是每次有效访问都会延续它的活跃状态。\n\n发布到 Explore 公开广场、被知识库引用，或绑定了远程 URL 的内容，不参与普通链接的无活跃自动清理。\n\n## 能力地图\n\n| 文件类型 | 分享链接生成 | 密码访问 | 水印 | 自定义短链接 | 评论反馈 | 更新同一链接 |\n| --- | --- | --- | --- | --- | --- | --- |\n| TXT | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| Markdown | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| HTML | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| PDF | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n| Word | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n| PowerPoint | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n\n## 核心能力\n\n- **HTML 页面发布**：将 AI 生成的网页、报告、原型页面或数据看板发布为在线链接。\n- **Markdown 在线分享**：直接发布 `.md` 或 `.txt` 内容，适合笔记、方案、会议纪要和技术文档。\n- **文档文件分享**：支持 PDF、Word、PowerPoint 文件上传与分享。\n- **短链接访问**：生成 ShareOne 公网短链接，便于在微信、邮件、飞书、Slack、Notion、GitHub Issue 等渠道传播。\n- **访问密码**：为敏感文档或内部材料设置访问密码。\n- **水印保护**：给页面或文档增加水印，降低外泄和二次传播风险。\n- **原链接更新**：在保留同一个分享链接的情况下更新内容，适合反复修改的方案、演示稿和评审页面。\n- **评论协作**：文本页面可开启评论，方便团队直接围绕页面内容反馈和修改。\n- **文件下载控制**：支持下载公开文件，也能在权限允许时取回源内容。\n\n## 适用场景\n\n- AI Agent 生成一个 HTML 页面后，需要立即发布给用户预览。\n- 把 Markdown 报告、技术方案、产品说明发布成可分享链接。\n- 将 PDF、Word、PPT 文件分享给客户、同事或外部协作者。\n- 给内部资料添加访问密码或水印。\n- 把已有 ShareOne 链接内容更新为最新版本。\n- 根据 ShareOne 页面评论修改内容，并重新发布到原链接。\n- 把 GitHub 上的远程 HTML 或文档 URL 发布为 ShareOne 链接。\n\n## Agent 使用方式\n\nAgent 在识别到“发布到 ShareOne”“生成分享链接”“分享这个 PDF”“更新这个 ShareOne 链接”“拉取评论”等意图时，会读取 [SKILL.md](./SKILL.md) 中的完整工作流，并调用本 Skill 的 `scripts/` 脚本完成操作。\n\n常见自然语言指令：\n\n```txt\n把 index.html 发布到 ShareOne，给我一个链接\n把这份 PDF 上传到 ShareOne，并设置访问密码 1234\n把刚才生成的 Markdown 报告分享出去\n更新这个 ShareOne 链接的内容：https://s.shareone.vip/s/xxx\n读取这个 ShareOne 页面上的评论并处理\n给这个链接加上水印“内部资料”\n```\n\n## 链接与文档\n\n- ShareOne 官网：https://shareone.vip\n- Skill 完整说明：[SKILL.md](./SKILL.md)\n\nFile v1.6.0:_meta.json\n\n{\n  \"ownerId\": \"kn73tjvxf6qkw5beygj5y939n988wsag\",\n  \"slug\": \"shareone\",\n  \"version\": \"1.6.0\",\n  \"publishedAt\": 1791560364919\n}\n\nFile v1.6.0:scripts/api_contract.json\n\n{\n  \"errors\": {\n    \"BAD_REQUEST\": {\n      \"status\": 400,\n      \"category\": \"validation\",\n      \"hint\": \"Correct the request using the operation's input schema.\",\n      \"retryable\": false\n    },\n    \"AUTH_REQUIRED\": {\n      \"status\": 401,\n      \"category\": \"auth_failed\",\n      \"hint\": \"Sign in or provide the existing account's X-API-Key.\",\n      \"retryable\": false\n    },\n    \"INVALID_API_KEY\": {\n      \"status\": 401,\n      \"category\": \"auth_failed\",\n      \"hint\": \"Check or update this account's API key; retain the identity that owns the share.\",\n      \"retryable\": false\n    },\n    \"FORBIDDEN\": {\n      \"status\": 403,\n      \"category\": \"permission\",\n      \"hint\": \"Use an identity authorized for this resource and operation.\",\n      \"retryable\": false\n    },\n    \"NOT_FOUND\": {\n      \"status\": 404,\n      \"category\": \"not_found\",\n      \"hint\": \"Check the resource reference and the current account's access.\",\n      \"retryable\": false\n    },\n    \"METHOD_NOT_ALLOWED\": {\n      \"status\": 405,\n      \"category\": \"validation\",\n      \"hint\": \"Use the HTTP method declared for this operation.\",\n      \"retryable\": false\n    },\n    \"PAYLOAD_TOO_LARGE\": {\n      \"status\": 413,\n      \"category\": \"validation\",\n      \"hint\": \"Reduce the request to the operation's size limit.\",\n      \"retryable\": false\n    },\n    \"UNSUPPORTED_MEDIA_TYPE\": {\n      \"status\": 415,\n      \"category\": \"validation\",\n      \"hint\": \"Use the operation's declared request content type.\",\n      \"retryable\": false\n    },\n    \"CONFLICT\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Read the reported precondition and correct it before retrying.\",\n      \"retryable\": false\n    },\n    \"VALIDATION_ERROR\": {\n      \"status\": 422,\n      \"category\": \"validation\",\n      \"hint\": \"Correct the fields listed in detail using the operation's input schema.\",\n      \"retryable\": false\n    },\n    \"RATE_LIMIT_EXCEEDED\": {\n      \"status\": 429,\n      \"category\": \"rate_limited\",\n      \"hint\": \"Wait for Retry-After, then retry the same operation.\",\n      \"retryable\": true\n    },\n    \"SERVER_ERROR\": {\n      \"status\": 500,\n      \"category\": \"transient\",\n      \"hint\": \"Back off. Replay writes only with a supported idempotency key or an idempotent operation.\",\n      \"retryable\": true\n    },\n    \"PASSWORD_REQUIRED\": {\n      \"status\": 401,\n      \"category\": \"access_gate\",\n      \"hint\": \"Supply the share password or its verified viewer cookie; keep the current API key.\",\n      \"retryable\": false\n    },\n    \"PASSWORD_INVALID\": {\n      \"status\": 401,\n      \"category\": \"access_gate\",\n      \"hint\": \"Correct the share password; keep the current API key.\",\n      \"retryable\": false\n    },\n    \"EMAIL_GATE_REQUIRED\": {\n      \"status\": 401,\n      \"category\": \"access_gate\",\n      \"hint\": \"Sign in as a viewer or use the owner's/collaborator's API key.\",\n      \"retryable\": false\n    },\n    \"COMMENTS_DISABLED\": {\n      \"status\": 403,\n      \"category\": \"permission\",\n      \"hint\": \"The owner must enable comments before this action is available.\",\n      \"retryable\": false\n    },\n    \"AGENT_OWNER_REQUIRED\": {\n      \"status\": 403,\n      \"category\": \"permission\",\n      \"hint\": \"Agent replies require the share owner's key. A collaborator can manage status but cannot impersonate the owner's agent.\",\n      \"retryable\": false\n    },\n    \"SHARE_SETTINGS_FORBIDDEN\": {\n      \"status\": 403,\n      \"category\": \"permission\",\n      \"hint\": \"Collaborators can update content or filenames; share settings require the owner's key.\",\n      \"retryable\": false\n    },\n    \"AGENT_STATE_REQUIRED\": {\n      \"status\": 422,\n      \"category\": \"validation\",\n      \"hint\": \"Set state to resolved-agree, open-disagree or open-need-input.\",\n      \"retryable\": false\n    },\n    \"COMMENT_ANCHOR_REQUIRED\": {\n      \"status\": 422,\n      \"category\": \"validation\",\n      \"hint\": \"Supply quote and highlighter_data for a root comment; replies inherit them from parent_id.\",\n      \"retryable\": false\n    },\n    \"IS_REPLY\": {\n      \"status\": 422,\n      \"category\": \"validation\",\n      \"hint\": \"Reply to the top-level thread ID returned in detail.parent_id.\",\n      \"retryable\": false\n    },\n    \"COMMENT_THREAD_INVALID\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Ask the share owner to repair this comment's parent references.\",\n      \"retryable\": false\n    },\n    \"INVALID_COMMENT_CURSOR\": {\n      \"status\": 400,\n      \"category\": \"validation\",\n      \"hint\": \"Request a new snapshot without cursor, then save its next_cursor.\",\n      \"retryable\": false\n    },\n    \"CONSUMER_LEASE_BUSY\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Wait for Retry-After before polling this consumer again.\",\n      \"retryable\": true\n    },\n    \"CONSUMER_LEASE_EXPIRED\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Poll again for a new batch and lease token; do not reuse this token.\",\n      \"retryable\": false\n    },\n    \"CONSUMER_SCOPE_CONFLICT\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Use another consumer name for the requested scope.\",\n      \"retryable\": false\n    },\n    \"NOT_REMOTE_BOUND\": {\n      \"status\": 400,\n      \"category\": \"validation\",\n      \"hint\": \"Update this static share's content; refresh applies only to a bound remote source.\",\n      \"retryable\": false\n    },\n    \"REMOTE_SOURCE_BOUND\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Edit at remote_url and refresh the original share. Unbind only when explicitly replacing the source.\",\n      \"retryable\": false\n    },\n    \"CUSTOM_SLUG_TAKEN\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Choose an available slug using the returned suggestions.\",\n      \"retryable\": false\n    },\n    \"IDEMPOTENCY_CONFLICT\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Reuse a key only with the same operation and payload; use a new key for a new intent.\",\n      \"retryable\": false\n    },\n    \"IDEMPOTENCY_BUSY\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Wait for Retry-After, then replay with the same idempotency key and payload.\",\n      \"retryable\": true\n    },\n    \"OPERATION_RESOURCE_GONE\": {\n      \"status\": 410,\n      \"category\": \"not_found\",\n      \"hint\": \"The original operation committed, but its resource was deleted. Use a new key only for an intentional new creation.\",\n      \"retryable\": false\n    }\n  },\n  \"agent_reply_states\": {\n    \"resolved-agree\": {\n      \"parent_status\": \"resolved\",\n      \"parent_agent_stance\": \"agree\"\n    },\n    \"open-disagree\": {\n      \"parent_status\": \"open\",\n      \"parent_agent_stance\": \"disagree\"\n    },\n    \"open-need-input\": {\n      \"parent_status\": \"open\",\n      \"parent_agent_stance\": \"need-input\"\n    }\n  },\n  \"comment_filters\": [\n    \"all\",\n    \"unresolved\",\n    \"open\",\n    \"in_progress\",\n    \"resolved\",\n    \"dismissed\"\n  ],\n  \"idempotency_operations\": [\n    {\n      \"method\": \"POST\",\n      \"path\": \"/api/v1/pages\"\n    },\n    {\n      \"method\": \"POST\",\n      \"path\": \"/api/v1/files\"\n    },\n    {\n      \"method\": \"POST\",\n      \"path\": \"/api/v1/files/confirm\"\n    },\n    {\n      \"method\": \"POST\",\n      \"path\": \"/api/v1/shares/{share_id}/comments\"\n    }\n  ]\n}\n\nFile v1.6.0:workflows/agent-notifications.md\n\n# 持久评论通知与 Agent 唤醒\n\n当用户要求持续监听评论、通知 scode 或其他 Agent 时使用本工作流。先完成 `environment-and-credentials.md`，使用页面 owner 的凭据。接收器不创建新账号。\n\n## 接到现有 Agent\n\n通用接收器运行在 Agent 所在机器，无需公网 webhook。服务端持久保存事件和每个消费者的确认位置；即使接收器离线，回来后仍会收到未确认的批次。\n\n```bash\nnode scripts/agent_watch.js --consumer review-agent --share '<分享链接>' \\\n  --cwd '<项目目录>' --command-json '[\"node\",\"receive-shareone.js\"]'\n```\n\n`--command-json` 是可执行文件和参数的 JSON 数组，不经过 shell。接收命令从 stdin 读取一行 JSON：\n\n```json\n{\"source\":\"shareone\",\"consumer\":\"review-agent\",\"events\":[{\"id\":\"事件UUID\",\"sequence\":1,\"event_type\":\"comment.created\",\"share_id\":\"稳定分享ID\",\"comment_id\":\"评论UUID\",\"parent_id\":null,\"actor_role\":\"visitor\",\"status\":\"open\",\"created_at\":\"UTC时间\"}]}\n```\n\n接收命令必须在**处理完成或可靠写入自己的持久收件箱后**才返回退出码 0。失败返回非零；不能先启动一个易丢失的后台任务就报告成功。事件只带引用，不含评论正文、截图、API Key 或确认令牌。处理前调用评论 API 读最新线程，按 `comments-process.md` 的认领、修改、同链接更新和明确回复流程执行。分享或评论已删除时跳过失效引用。\n\n## 恢复 scode 会话\n\n```bash\nnode scripts/agent_watch.js --consumer scode-review --share '<分享链接>' \\\n  --cwd '<项目目录>' --scode-session '<已有会话路径>'\n```\n\n接收器启动 `scode acp`，通过 ACP 的 `session/load` 加载指定会话，再用 `session/prompt` 交付事件。只有会话返回 `end_turn` 才确认；交互权限请求会被取消并保留未确认批次。需要机器已安装并配置 scode，且该会话的权限适合任务。请使用专供监听的会话；不要同时在另一个进程操作同一会话。接收器不会增加 scode 权限。不要猜会话路径或自动选择最近一次会话。\n\n默认使用 scode 配置；需要指定模型或认证模式时，可加 `--scode-args-json '[\"--auth\",\"api-key\",\"--model\",\"sonnet\"]'`。这里只放 scode 参数，API Key 仍保存在 scode 的凭据配置里。\n\n## 可靠性与运行方式\n\n- 默认消费上线后记录的全部历史事件；`--start now` 仅在首次注册时从当前位置开始。重复启动同名消费者不会清空进度。上线前已有评论仍需先用 `comment_list.js` 做一次基线检查。\n- `--share` 可省略（接收该 owner 全部分享）；使用者确定范围后再开启。消费者名称和范围固定；更换范围使用新名称。\n- 默认只把访客变化交给命令，避免 Agent 的回复唤醒自己；其他事件也会正常推进确认位置。`--all-actors` 明确开启全部作者事件。\n- 持续长轮询，断网或命令失败后退避重试，最长间隔 60 秒。一个消费者同一时刻只有一个有效批次租约；处理时自动续租。进程崩溃后，5 分钟租约到期即可重领。\n- 语义为**至少一次**。处理完成但确认前崩溃可能重复送达；以事件 `id` 去重，并检查当前评论状态，不能假定恰好一次。\n- `--timeout-seconds` 默认 1800，超时终止本接收器启动的命令进程树，保留未确认事件。`--once` 只检查并处理一个批次，适合排障和验收。\n- 常驻运行由机器的服务管理器监督：Linux 可用 systemd，Windows 可用任务计划程序（登录启动、失败重启、禁止重叠实例）。工作目录指向项目；命令指向安装目录内本脚本。把 API Key 放凭据文件或安全环境配置，不放命令行或任务参数。机器休眠或接收器停止时不会立即唤醒；恢复后补发。\n- 启动常驻监听前确定接收项目、消费者范围和具体会话/命令。只完成脚本安装不表示已开始后台监听。\n\n## HTTP 接口\n\n均需 owner 鉴权，路径前缀 `/api/v1/agent-consumers`：\n\n| 请求 | 含义 |\n|---|---|\n| `PUT /<name>`，`{\"share_id\":null,\"start\":\"beginning\"}` | 幂等注册；可传稳定 ID 或 slug |\n| `GET /`（实际不带尾斜杠） | 列出自己的消费者和游标 |\n| `GET /<name>` | 查看游标和租约到期时间 |\n| `POST /<name>/poll`，`{\"limit\":50,\"wait_seconds\":20}` | 最多 100 条、最多等 25 秒；空批次无令牌 |\n| `POST /<name>/renew`，`{\"lease_token\":\"...\"}` | 将当前租约续到 5 分钟后 |\n| `POST /<name>/ack`，`{\"lease_token\":\"...\"}` | 确认整个已交付批次；重试同一确认幂等 |\n| `POST /<name>/release`，`{\"lease_token\":\"...\"}` | 处理失败后释放，不推进游标 |\n| `DELETE /<name>` | 删除消费者；需要重置进度时明确执行再注册 |\n\n读取不会确认。`ack` 不接受任意目标游标，过期/被替换的令牌返回 409。每个 owner 的事件有独立递增序号；不同 Agent 使用不同消费者名。当前事件不自动过期，删除消费者不会删事件；不承诺无限保存评论正文，事件中的引用可能已失效。\n\n## 防止重投产生重复写入\n\n事件按至少一次投递：处理成功后才 ACK。发布新页面、上传文件或回复评论时，使用稳定的 `--idempotency-key`，例如 `<event.id>.reply`；重试必须保留同一键和同一请求内容。回复脚本返回实际 `parent_status` / `parent_agent_stance`。幂等冲突时先检查原操作与资源状态，不要换键绕过冲突后重复创建；操作返回 409 busy 时按 `Retry-After` 等待。直接上传确认重试应保留原 `share_id`。\n\nFile v1.6.0:workflows/bind-account.md\n\n# 绑定账号（Guest → 注册用户升级）\n\n当用户表达\"绑定账号\"、\"注册\"、\"升级 guest\"、\"绑定邮箱\"等意图时读取本文件。执行前必须已经完成 `environment-and-credentials.md`（确保有可用的 API Key）。\n\n## 核心概念\n\n- Guest 用户通过 `POST /api/v1/agent-guest-key` 获取的临时 API Key，绑定邮箱后升级为注册用户\n- **API Key 不变**：绑定只是在同一个 user record 上添加 email，`user.id` 和 `api_key` 都保持不变\n- 绑定后用户可以用邮箱登录 ShareOne 网站 dashboard 管理文件\n- 整个流程由 agent 代劳，用户不需要打开浏览器\n\n## 流程\n\n### 1. 获取用户邮箱\n\n如果用户还没有提供邮箱，询问：\n\n> 请提供您的邮箱地址，我来帮您绑定账号。绑定后您的 API Key 不变，还可以用邮箱登录 ShareOne 网站管理文件。\n\n### 2. 发送验证码\n\n```bash\nnode scripts/bind_account.js --send --email <用户邮箱>\n```\n\n按输出 token 处理：\n\n- `CODE_SENT`：通知用户查看邮箱：\n  > 验证码已发送到 `<邮箱>`，请查看邮箱（含垃圾箱），告诉我 6 位数字验证码。\n- `ERROR:EMAIL_ALREADY_LINKED`：该邮箱已被其他账号使用。告知用户并建议使用其他邮箱，或直接用该邮箱登录网站。\n- `ERROR:COOLDOWN`：发送冷却中，请等待 30 秒后重试。\n- `ERROR:RATE_LIMIT`：频率限制，稍后再试。\n- `ERROR:KEY_NOT_FOUND`：API Key 不存在，需要先通过 `ensure_credentials.js` 获取凭据。\n\n### 3. 等待用户回复验证码\n\n暂停操作，等待用户告知 6 位验证码。\n\n### 4. 验证并绑定\n\n```bash\nnode scripts/bind_account.js --verify --email <用户邮箱> --code <验证码>\n```\n\n按输出 token 处理：\n\n- `BIND_SUCCESS`：绑定成功。向用户确认：\n  > 账号绑定成功！您的邮箱 `<邮箱>` 已与当前 API Key 关联。API Key 不变，您现在可以用这个邮箱登录 ShareOne 网站管理分享的文件。\n- `ERROR:INVALID_CODE`：验证码错误，请用户检查后重新输入。不需要重新发送验证码。\n- `ERROR:CODE_EXPIRED`：验证码已过期（5 分钟有效），需要重新发送。回到第 2 步。\n- `ERROR:TOO_MANY_ATTEMPTS`：验证码尝试次数过多（最多 5 次），需要重新发送。回到第 2 步。\n- `ERROR:EMAIL_ALREADY_LINKED`：邮箱已被其他账号使用。建议使用其他邮箱。\n- `ERROR:KEY_NOT_FOUND`：API Key 无效或 guest 账号不存在。\n\n## 不要做的事\n\n- 不要让用户打开浏览器去网站绑定——整个流程在对话中完成。\n- 不要在绑定后生成新的 API Key——绑定不改变 key。\n- 不要在用户没有明确要求时主动发起绑定流程（但在首次创建 guest key 后可以简短提示）。\n\nFile v1.6.0:workflows/comments-process.md\n\n# 处理 ShareOne 评论\n\n当用户明确要求“处理这些评论”、“根据评论改一下页面”、“修改这个 ShareOne 链接的内容”时读取本文件。只查看评论时不要读取本文件。\n\nShareOne 页面评论包含状态机字段 `status`：`open` / `in_progress` / `resolved` / `dismissed`，以及作者字段 `author_role`：`visitor` / `owner` / `agent`。\n\n处理评论需要 owner 的 API Key（认领状态、发 agent 回复都要求 owner 鉴权），执行前必须已经完成 `environment-and-credentials.md`。\n\n## 1. 获取 ref 与评论\n\n用户提供的目标可以是完整链接、`/s/<ref>` 或 `/md/<ref>` 路径、裸 `share_id` 或自定义短链 slug。取路径最后一段作为 `<REF>` 即可，接口同时接受 `share_id` 和 slug。\n\n本 workflow 只适用于可编辑的文本/HTML/Markdown 页面评论处理。若目标链接路径明确是 `/pdf/`、`/ppt/`、`/word/`，或下载后的 `INFO:CONTENT_TYPE`/文件扩展名显示为 PDF/PPT/Word 等二进制文档，不要为处理评论解析、转换或修改二进制正文；停止内容修改流程，并告知用户当前 skill 只支持处理页面源码评论，二进制文档只能查看/总结评论或更新元数据设置。\n\n任务锚点：步骤 2 的下载命令（`--task-anchor`）会自动把 `<REF>` 写入当前目录的 `.shareone_active_task` 文件，把目标 share 固定到磁盘上（防止长时间编辑文件后上下文丢失，误把更新发成新链接）。后续所有步骤中的 `<REF>` 都以该文件内容为准；任何时候不确定目标 share 是哪个，读取该文件，**不要凭记忆，更不要新建链接**。\n\n先获取未处理评论：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments?status=unresolved\"\n```\n\n评论数据中可能包含 `replies`。必须将父评论及其所有回复作为一个 thread 整体阅读，综合理解最终共识。回复不需要单独走流程，只对父评论操作状态。\n\n“当前视图隐藏”表示页面确认目标存在；“等待页面定位目标”表示尚无当前证据；“目标在当前版本中已不存在”只用于页面完整模型明确报告缺失的 ID；“文字无法定位，内容可能已变化”仍是旧文字匹配失败。区域评论同时保留各部分数量。不要从显示名猜测稳定 ID，不自动把旧文字评论改绑到对象。评论仍可阅读和回复；定位状态不能替代用户对反馈的判断，也不能自动 dismiss 或关闭评论。动态 HTML 的接入与性能验收见 `publish-text-page.md` 的“动态页面与文字评论”。\n\n## 2. 标准闭环流程\n\n对每条要处理的父评论，严格按以下顺序执行。\n\n### 步骤 1：认领\n\n必须在动手之前做：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/<COMMENT_ID>/status\" \\\n  --method PUT \\\n  --data '{\"status\": \"in_progress\"}'\n```\n\n访问者会立刻在页面侧栏看到“处理中”徽标和顶部“AI 正在处理 N 条评论...”横幅。跳过这一步会让用户感受不到 AI 在干活。\n\n### 步骤 2：取源（自动写锚点）\n\n```bash\nnode scripts/download_share.js \"<REF>\" --task-anchor\n```\n\n`--task-anchor` 会自动完成三件事：写入 `.shareone_active_task` 锚点（stderr 输出 `ANCHOR_WRITTEN:`）、按服务端文件名的扩展名把源内容保存为 `shareone_<REF>_source.<ext>`（stdout 输出 `SAVED:<本地文件名>`）、在 stderr 输出 `INFO:FILENAME:`（原始文件名，步骤 4 要用）和 `INFO:CONTENT_TYPE:`。文件名携带目标 share，即使对话上下文丢失也能恢复 `<REF>`。已配置 owner API Key 时脚本自动走 owner 下载接口，不受密码和下载开关限制。\n\n**根据下载信息选择修改位置：**\n\n- 未绑定远程源：编辑 `SAVED:` 给出的本地文件，按步骤 4A 更新原分享。\n- 出现 `INFO:REMOTE_SOURCE` / `HINT:EDIT_AT_SOURCE`：下载的是远程源的缓存副本。先读 [git-backed-versions.md](git-backed-versions.md)，在对应 Git 仓库修改，按步骤 4B 同步原分享。若源是另一个 ShareOne 分享，则修改那个源 share 后刷新当前分享；保留当前 `.shareone_active_task` 作为回复目标，不用它替代源 share 的 ID。\n\n### 步骤 3：精准应用修改\n\n- 综合理解整个 thread（父评论 + 所有 replies）的最终意图，必要时先和用户确认。\n- 绝对不要用全局 `replace()` 或正则批量替换，会误伤其他同名文案。\n- 基于 DOM 结构精确定位：利用 `highlighter_data.startMeta.parentTagName`、`parentIndex`、`textOffset`，结合 `quote`（被选中原文）定位准确节点。\n- 理解结构性意图：评论可能是“把这部分挪到底部 / 删掉这个区块 / 加个图标”，先定位再做结构变更。\n- 如果无法定位原文，先保留评论与原文，用 `comment_reply.js --state open-need-input` 说明缺少的信息并等待澄清。定位失败不能证明内容不存在，也不能成为 dismiss 的依据。\n\n### 步骤 4：更新并验收原分享（保留目标 ID）\n\n#### 4A. 未绑定远程源：PUT 上传正文\n\n脚本选择说明：更新**内容**只能用 `publish.js --share-id`（带 `--share-id` 时执行的是 PUT 内容更新，不是创建）；`update_share_settings.js` 只能改密码/水印/短链/评论开关等元数据，**无法替换页面内容**，本步骤不要使用它。\n\n直接执行以下命令更新原链接。`<REF>` 与步骤 1、2、5 是同一个值，即 `.shareone_active_task` 文件的内容：\n\n```bash\nnode scripts/publish.js \"<步骤 2 SAVED: 给出的本地文件>\" --filename \"<INFO:FILENAME 给出的原文件名>\" --share-id <REF>\n```\n\n硬规则：\n\n- 评论处理流程中**禁止**不带 `--share-id` 执行发布命令——那会 POST 创建一个全新链接，原链接和上面已认领的评论都不会得到任何更新。\n- 不要跳读 `publish-text-page.md` 的“判断创建还是更新”一节，评论场景永远是更新，没有“首次创建”分支。\n- 如果此刻想不起 `share_id`，读取 `.shareone_active_task` 文件或源文件名中的 `shareone_<REF>_` 前缀，绝不新建。\n- 如果脚本输出 `ERROR:ACTIVE_SHARE_TASK`，说明漏传了 `--share-id`，按错误提示补上后重试。\n\n评论闭环中的重新发布属于对已有链接的更新，**不需要**向用户展示发布前安全提示或等待确认（规则见入口 `SKILL.md`）。\n\n#### 4B. 绑定远程源：修改源头后刷新\n\nGit 源按仓库现有流程提交、评审和合并到绑定分支，然后执行 `node scripts/refresh_share.js \"<REF>\"`。固定 commit 的分享，先按 `git-backed-versions.md` 用原 `--share-id` 换成已选定的新 commit URL。ShareOne 内链则更新源 share 后刷新当前分享。\n\n核对 `remote_last_error` 并下载确认预期修改已进入原分享，再执行步骤 5。不要对远程源页面用 `publish.js` 上传缓存副本；遇到 `REMOTE_SOURCE_BOUND` 不自动解绑。没有源仓库权限、PR 尚待合并或同步失败时，说明剩余步骤，用 `open-need-input` 保持待处理。可附修复 commit/PR 链接，但当前评论没有自动绑定创建时的 commit。\n\n### 步骤 5：回复评论并**强制表态**（一条命令，`--state` 必填）\n\n每次回复评论都**必须**用 `comment_reply.js` 并声明一个 `--state`——这是硬性要求（缺省即报错），目的是杜绝“只回复不收敛 / 有分歧却没 signal 出来 / 不确定却没保持 open”这三种失败模式：\n\n```bash\n# 同意并已按建议修改 → 评论收敛为 resolved\nnode scripts/comment_reply.js \"<REF>\" <COMMENT_ID> --content \"已按你的建议把标题改成 ...，并调整了 ...\" --state resolved-agree\n```\n\n`--state` 三选一（无默认）：\n\n| state | 含义 | 对父评论的作用 |\n|---|---|---|\n| `resolved-agree` | 充分理解且同意，已处理 | 置 `resolved` |\n| `open-disagree` | 不同意（在 `--content` 里写清理由） | **保持 `open`**，标记“AI 有异议”，把是否关闭交回给提出者 |\n| `open-need-input` | 需要人类进一步澄清/输入 | 保持 `open` |\n\n脚本会自动从父评论继承 `quote`/`highlighter_data`、以 `author_role=agent` 发一条回复（输出 `REPLY_POSTED:<id>` 和 `COMMENT_STATE:<state>`），后端据 `--state` 原子地设置父评论状态与 AI 立场。不要手工拼接含 `highlighter_data` 的 JSON。\n\n**关键原则：AI 永不单方面关闭一条分歧。** 不同意时用 `open-disagree`（保持 open、让提出者决定），**绝不**用 dismiss 把别人的评论关掉——关闭/重开一条评论的权力属于提出评论的人（以及页面 owner）。\n\n- 输出 `ERROR:STATE_REQUIRED` / `ERROR:INVALID_STATE`：必须补上合法的 `--state`。\n- 输出 `ERROR:IS_REPLY:<parent_id>`：传入的是回复 ID，改用父评论 ID 重试。\n- 输出 `ERROR:AUTH_FAILED`（403）：先查该链接评论是否被关闭（`allow_comments=false`），可经 `update-share-settings.md` 重新开启后重试。\n\n如果误发了一条回复，可以删除（仅作者本人、且父评论仍为 `open` 时可删，会级联删除其回复）：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<SHARE_ID>/comments/<COMMENT_ID>\" --method DELETE\n```\n\n## 3. 无关或垃圾评论\n\n**注意区分“不同意”与“无关”**：对你有异议但属于合理讨论的评论，用步骤 5 的 `--state open-disagree`（保持 open），**不要** dismiss。`dismiss` 只用于**owner 确认的无关或垃圾评论**的评论（例如指向了另一份分享、垃圾评论）——这是 owner 的否决动作：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/<COMMENT_ID>/status\" --method PUT --data '{\"status\":\"dismissed\",\"note\":\"owner 确认这是垃圾评论\"}'\n```\n\n确认返回 JSON 的 `status` 为 `dismissed`。无法定位、权限不足、源 PR 待合并或刷新失败时，用 `open-need-input` 并说明原因。\n\n## 4. 收尾：删除任务锚点\n\n所有目标评论都已 `resolved` 或 `dismissed`、且重新发布完成后，删除任务锚点文件：\n\n```bash\nrm -f .shareone_active_task\n```\n\n不删除的话，之后正常的新页面发布会被发布脚本拦截（`ERROR:ACTIVE_SHARE_TASK`）。\n\n## 5. 兼容旧接口\n\n旧接口仍然可用，但新代码不要使用：\n\n```http\nPUT /api/v1/shares/<REF>/comments/<COMMENT_ID>/resolve\n{ \"resolved\": true/false }\n```\n\n它等价于把 `status` 切到 `resolved` 或 `open`，但不会附带 `note`，访问者拿不到 AI 的解释。新代码一律使用 `/status` 接口。\n\n## 6. 关键准则速查\n\n| 准则 | 为什么 |\n| --- | --- |\n| 动手前先 `in_progress` | 让访问者看到“AI 在干活” |\n| 改完一定要 `POST` 一条 `author_role=agent` 的回复 | 闭环的“答复”部分，没有它就只是状态变化、不是对话 |\n| `note` 要写人话 | “已把按钮改成主色” 比 “Applied.” 有用 |\n| 信息或权限不足时 `open-need-input` | 保留待办并说明需要的人类输入 |\n| 只对父评论改状态，回复不单独操作 | 状态语义属于 thread 整体 |\n| `unresolved` = `open + in_progress` | 拉单子默认用 `?status=unresolved` |\n\nFile v1.6.0:workflows/comments-view.md\n\n# 查看 ShareOne 评论\n\n当用户只是要求查看、拉取、总结评论时读取本文件。不要修改源文件，不要认领评论，不要关闭评论。\n\n开放分享允许匿名读取。完整列表、摘要、增量查询和截图均遵守密码、登录与评论开关；owner/协作者可用已有 API Key 跳过访问者门禁。`comment_list.js` 会使用已有凭据，也允许开放分享的匿名读取；不需要为查看评论新建身份。\n\n## 1. 获取 ref\n\n用户提供的目标可以是完整链接、`/s/<ref>` 或 `/md/<ref>` 路径、裸 `share_id` 或自定义短链 slug。取路径最后一段作为 `<REF>` 即可，接口同时接受 `share_id` 和 slug。\n\n## 2. 查看评论\n\n优先用 `comment_list.js`——它输出干净的 UTF-8 JSON（`{ share, status, count, comments:[{ id, status, author_role, quote, content, created_at, updated_at, screenshot_url, agent_stance, viewer_can_manage, resolution_note, reply_count, replies:[...] }] }`），省去手工拼接 endpoint 和解析原始响应，也规避控制台非 ASCII 乱码：\n\n```bash\nnode scripts/comment_list.js <REF>                 # 默认 --status all\nnode scripts/comment_list.js <REF> --status open   # 只看未处理\nnode scripts/comment_list.js <REF> --json compact  # 单行 JSON，便于管道解析\n```\n\n`--status` 可选值：\n\n- `all`（默认）\n- `open`\n- `in_progress`\n- `resolved`\n- `dismissed`\n- `unresolved`，等价于 `open + in_progress`\n\n受限分享需要授权。密码门禁返回 `PASSWORD_REQUIRED`，登录门禁返回 `EMAIL_GATE_REQUIRED`；按 hint 完成访问授权，保持当前账号 Key。\n\n截图路径以 `/comment-screenshots/` 开头时，相对正在访问的 ShareOne origin 解析，发送同一 origin 的已验证 Cookie 或 owner/协作者凭据。\n\n## 3. 评论理解规则\n\n- 只展示评论内容，绝对不要自作主张开始修改源文件。\n- 等用户明确要求“处理这些评论”、“根据评论改一下页面”等，再进入 `comments-process.md`。\n- 评论数据中可能包含 `replies`。必须将父评论及其所有回复作为一个 thread 整体阅读，综合理解最终共识。\n- 不要把每条回复当成独立修改指令。\n- 所有回复继承父评论的锚点，也就是 `highlighter_data` 和 `quote`。\n\n## 4. 轻量摘要\n\n如果只想看“现在还有没有未处理的事”，用摘要接口：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/summary\" --public\n# -> { total, open, in_progress, resolved, dismissed, last_activity_at }\n```\n\n返回 `open + in_progress == 0` 时没有待处理线程；需要阅读历史内容时仍可拉取列表。\n\n## 5. 增量维护评论缓存\n\n需要持续更新一个评论视图时，可以复用通用请求脚本：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/changes\" --public\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/changes?cursor=<URL_ENCODED_CURSOR>&limit=100\" --public\n```\n\n首次省略 `cursor`，用 `reset=true` 的 `comments` 替换缓存；包括上线前已有的评论。后续按顶层 ID 替换返回的完整线程（含回复），删除 `deleted_ids`，应用成功后保存 `next_cursor`。`has_more=true` 时立即继续；`limit` 是事件数，默认 100、最大 200。线程反映当前状态，同一批可幂等重放。400 表示游标无效，应重新获取快照。游标只对原分享有效。\n\n此接口每次检查页面密码/登录要求。`--public` 适用于没有访问门槛的分享；有 owner/协作者凭据时省略 `--public`。浏览器访问者使用页面授权 Cookie；本脚本不会代填页面密码。`comment_list.js` 保留截图、AI 立场、更新时间、权限字段和嵌套回复，只省略较大的 `highlighter_data`。\n\n该接口只读，不注册消费者或确认事件。需要可靠接收通知并唤醒 Agent 时，使用 `agent-notifications.md` 的持久消费者流程。\n\nFile v1.6.0:workflows/delete-api-key.md\n\n# 删除 ShareOne API Key\n\n当用户明确要求删除、清除、移除或重置 ShareOne API Key 时读取本文件。\n\n## 1. 执行删除\n\n执行：\n\n```bash\nnode scripts/delete_api_key.js\n```\n\n## 2. 根据输出回复\n\n- `SUDOWORK_KEY_DELETED`：告诉用户 Sudowork 中保存的 ShareOne API Key 已删除（如有本地 fallback 凭证也已一并清理）。\n- `SUDOWORK_FALLBACK_KEY_DELETED`：告诉用户 Sudowork 当前凭证环境不可用，已删除 ShareOne fallback 本地凭证。\n- `KEY_DELETED`：告诉用户本地保存的 ShareOne API Key 已删除。\n- `KEY_NOT_FOUND`：告诉用户当前没有找到已保存的 ShareOne API Key，无需删除。\n- `ERROR:<message>`：删除 Sudowork secret 时出现异常（例如 Auth Proxy 故障）。把错误信息告知用户，建议稍后重试或在 Sudowork 密钥管理中手动删除。\n\n## 3. 删除后的规则\n\n删除后，如果用户再次要求发布、查看评论、处理评论或执行任何 ShareOne API 操作，必须重新读取 `environment-and-credentials.md` 并完成凭据检查和配置。\n\nFile v1.6.0:workflows/delete-share.md\n\n# 删除 ShareOne 分享链接\n\n当用户明确要求“删除/删掉/移除”某个已有 ShareOne 分享链接本身时读取本文件。这是 owner-only 操作，删除后公开链接立即失效（软删除）。\n\n不要把“删除链接”和“修改设置”（水印/密码/短链/评论开关，见 `update-share-settings.md`）混淆；本流程销毁整个 share。\n\n## 0. 删除前确认（阻塞）\n\n执行删除命令前，必须先向用户复述要删除的目标（链接/`share_id`/slug）并获得明确确认。用户确认前不要调用 `delete_share.js`。\n\n## 1. 凭据\n\n删除需要 owner 的 API Key。先运行 `node scripts/ensure_credentials.js`（含义见 `workflows/environment-and-credentials.md`）。没有可用凭据时不要继续。\n\n## 2. 获取 ref\n\n目标可以是完整链接、`/s/<ref>` 等路径、裸 `share_id` 或自定义 slug。脚本会自行取末段并同时接受 `share_id` 与 slug；HTML/文本页和二进制文件（`/pdf/`、`/ppt/`、`/word/`）通用。\n\n## 3. 执行删除\n\n```bash\nnode scripts/delete_share.js <REF>\n```\n\n成功输出 `SHARE_DELETED:<ref>`。删除是幂等的：对已删除的链接重复执行仍返回 `SHARE_DELETED`。\n\n### 连带失效的指针（必须转达给用户）\n\n如果有别的 ShareOne 分享把这条链接当作内容源（remote-url **指针**），它们会**一并失效**，每条打印一行：\n\n```\nPOINTER_INVALIDATED:https://s.shareone.vip/s/xxx\nHINT:POINTERS_INVALIDATED:2\n```\n\n出现这些行时，**必须把每条失效链接原样列给用户**，不要只说\"已删除\"。指针不持有内容、只缓存源的内容，源撤了它们就没有可指的东西；但**指针可能属于别人**，用户需要知道自己刚刚让哪些链接失效了，才能去知会对方。没有这些行就表示没有任何指针受影响。\n\n## 4. 错误处理\n\n- `ERROR:KEY_NOT_FOUND`：没有可用凭据，先按 `environment-and-credentials.md` 配置或创建 guest key。\n- `HTTP 404`：链接不存在，或不属于当前 API Key（IDOR 保护）。据此提示用户核对链接归属。\n- 其他 `ERROR:*` / `AUTH_FAILED`：把服务端返回的原因反馈给用户，不要静默重试。\n\nFile v1.6.0:workflows/download-file.md\n\n# 下载 ShareOne 链接文件\n\n当用户要求“下载这个 ShareOne 链接的文件”或“取回这个链接的源内容”时读取本文件。普通下载不需要先配置 API Key：脚本会在已有凭据时优先尝试 owner 下载，没有凭据时自动退回公开下载。只有用户明确要求用 owner 身份下载、或公开下载失败后需要 owner 权限时，才回到 `environment-and-credentials.md` 完成凭据配置。\n\n## 1. 获取链接或 ref\n\n用户可以提供完整链接、`share_id`、自定义短链 slug，或 `/s/<share_id>` 这类路径。把用户原始输入直接作为参数传给下载脚本即可，脚本会自行解析；不需要自行判断 slug 和 share_id。\n\n## 2. 下载内容\n\n使用 `--save`，脚本会按服务端返回的文件名自动保存到当前目录；如果同名文件已存在，会自动添加数字后缀避免覆盖。成功后在 stdout 输出 `SAVED:<本地文件名>`：\n\n```bash\nnode scripts/download_share.js \"<LINK_OR_ID>\" --save\n```\n\n同时 stderr 会输出文件信息：\n\n```text\nINFO:FILENAME:<原始文件名>\nINFO:CONTENT_TYPE:<mime 类型>\nINFO:REMOTE_SOURCE:<remote_url>      # 仅当该 share 的内容来自远程 URL 时出现\nHINT:EDIT_AT_SOURCE                  # 伴随 REMOTE_SOURCE 出现\n```\n\n如果出现 `INFO:REMOTE_SOURCE` 和 `HINT:EDIT_AT_SOURCE`，说明这个 share 的内容来源是远程 URL（如 GitHub 仓库文件或另一个 ShareOne 链接）。提示用户：如果要修改内容，建议直接去源头修改（如在 GitHub 上编辑原文件），这样所有引用该源的分享链接都会自动同步更新。\n\n用户进一步要求修改 Git 源或管理版本时，读 [git-backed-versions.md](git-backed-versions.md)。跟随分支的源可拉取后续提交；固定 commit 的源需要显式换 URL 才会换版。单纯下载不修改仓库或分享绑定。\n\n脚本会在已配置 ShareOne API Key 时先尝试 owner 下载接口；owner 下载不受访问密码和 `allow_download` 限制。如果当前 API Key 不是 owner 或没有 API Key，脚本会自动退回公开下载。\n\n如果用户提供了访问密码，必须通过 `--password` 传入（脚本用 POST body 发送密码），不要把密码拼进 URL：\n\n```bash\nnode scripts/download_share.js \"<LINK_OR_ID>\" --password \"<PASSWORD>\" --save\n```\n\n如需把内容输出到 stdout 自行处理（例如管道），去掉 `--save` 即可，此时 stdout 是原始文件内容（不是 JSON）。\n\n## 3. 错误处理\n\n下载失败时脚本向 stderr 输出 `ERROR:<code>`，按 code 处理：\n\n| 脚本输出 | 含义与应对 |\n| --- | --- |\n| `ERROR:PASSWORD_REQUIRED` | 该链接需要访问密码才能下载。告诉用户请提供密码后再下载。 |\n| `ERROR:PASSWORD_INVALID` | 用户提供的访问密码不正确。告诉用户密码错误，请确认后重新提供。 |\n| `ERROR:DOWNLOAD_NOT_ALLOWED` | 链接没有开启允许下载。告诉用户需要链接 owner 在文件管理中开启“允许下载”后才能下载。 |\n| `ERROR:SHARE_NOT_FOUND` | 链接不存在或已失效。请用户确认链接是否正确、是否已过期删除。 |\n| 其他 `ERROR:<HTTP ...>` | 按 `result-and-errors.md` 的通用错误规则处理。 |\n\n不要在收到错误后重试同一请求；先按上表与用户沟通缺失的信息。\n\n## 4. 后续处理\n\n- 如果用户只是要求下载或查看，展示下载结果摘要，并按 stderr 中 `INFO:FILENAME` / `INFO:CONTENT_TYPE` 说明文件名和内容类型。\n- 如果用户要求修改下载到的内容，直接编辑 `SAVED:` 给出的本地文件，再根据文件类型读取 `publish-text-page.md` 或 `publish-binary-file.md` 执行更新。\n\nFile v1.6.0:workflows/environment-and-credentials.md\n\n# 环境判断与 API Key 凭据流程\n\n只在需要 ShareOne API 的操作前读取本文件。凭据状态机（检查 → 保存 → 复查 → 核对）全部由 `ensure_credentials.js` 脚本执行；你只需要按输出 token 行动，并把脚本在分隔线 `--- 请将以下内容原样发给用户 ---` 之后输出的话术**原样转发给用户**。不要凭 `SUDOWORK_AUTH_PROXY_URL` 等环境变量自行推断环境。\n\n## 1. 检查凭据\n\n```bash\nnode scripts/ensure_credentials.js\n```\n\n按输出处理：\n\n- `READY`：凭据就绪，直接继续原操作。同时输出的 `MODE:` 行说明当前环境（见第 3 节后续命令规则）。\n- `NEED_USER_INPUT`：凭据缺失。把分隔线之后的提问话术原样转发给用户，**暂停当前操作**，等待用户回复。\n- `ERROR:...`：见第 4 节。\n\n## 2. 用户回复后\n\n- 用户提供了 API Key（例如 `sk-xxx`）：\n\n```bash\nnode scripts/ensure_credentials.js --key <用户提供的KEY>\n```\n\n- 用户回复“没有”或“创建”：\n\n```bash\nnode scripts/ensure_credentials.js --create-guest\n```\n\n两个命令都会自动完成保存、复查和核对，按输出处理：\n\n- `READY`：继续原操作。\n- `GUEST_KEY_CREATED:<api_key>`：**阻塞性用户通知**。分隔线之后是需要原样转发给用户的完整通知文本（含临时 API Key、绑定账号链接和保存提醒）。必须先把该通知发给用户，才能继续原任务的任何上传、下载、评论处理命令；即使 key 已自动保存也不能省略。转发完通知后，追加一句引导：\n  > 如果您希望绑定邮箱以便后续在网站管理文件，请告诉我您的邮箱地址，我可以帮您完成绑定（API Key 不变）。\n  这只是轻提示，不阻塞后续操作。如果用户回复了邮箱，按 `workflows/bind-account.md` 执行绑定流程。\n- `NOTE:SUDOWORK_FALLBACK_KEY_SAVED`：附加信息，表示 key 保存到了 skill 安装目录下的本地 fallback 凭证（`.shareone_credentials`），不是 Sudowork Secret Store。脚本输出的说明文字一并转发给用户即可。\n\n## 3. 后续命令规则\n\n- `MODE:sudowork`：后续所有命令**不要传 `--api-key`**，凭证由 Auth Proxy 自动注入。\n- `MODE:sudowork_fallback` / `MODE:direct`：脚本会自动读取环境变量 `SHAREONE_API_KEY` 或本地凭证文件，**无需显式传 `--api-key`**；仅当用户临时指定其他 key 时才传。\n- 所有非 Sudowork secrets 的本地凭据都只读写 ShareOne skill 安装目录下的 `.shareone_credentials`，不读写用户 home。\n- 如果后续操作中服务返回 401（脚本输出 `ERROR:AUTH_FAILED`），提示用户“API Key 无效或权限不足”。\n\n## 4. 错误处理\n\n- `ERROR:RATE_LIMIT_EXCEEDED`：创建临时 API Key 触发频率限制（每小时 20 次、每天 200 次）。把分隔线之后的提示转发给用户，暂停操作。\n- `ERROR:SUDOWORK_WRITE_BROKEN`：Sudowork 凭证环境可读但写入失败。**不要循环重试保存**；把分隔线之后的说明转发给用户并停止当前操作。\n- 其他 `ERROR:<message>`：把错误信息告知用户，暂停操作。\n\n## 5. 底层脚本（一般不需要直接使用）\n\n`check_api_key.js`、`save_api_key.js`、`create_guest_key.js` 是 `ensure_credentials.js` 的底层组件，仍然可用（输出 `SUDOWORK_ENV_OK_KEY_FOUND` / `KEY_FOUND:<key>` / `SUDOWORK_KEY_SAVED` / `KEY_SAVED` 等细粒度 token），仅用于调试或用户明确指定时；正常流程一律使用 `ensure_credentials.js`。删除凭据见 `delete-api-key.md`。\n\nArchive v1.5.0: 57 files, 149019 bytes\n\nFiles: agents/openai.yaml (238b), LICENSE (1068b), README.md (5303b), scripts/agent_watch.js (8577b), scripts/api_contract.json (7185b), scripts/bind_account.js (3464b), scripts/check_api_key.js (1912b), scripts/comment_list.js (1627b), scripts/comment_reply.js (1715b), scripts/create_guest_key.js (3000b), scripts/delete_api_key.js (1259b), scripts/delete_share.js (2657b), scripts/download_share.js (6206b), scripts/ensure_credentials.js (9279b), scripts/make_qr.js (23390b), scripts/manage_collaborators.js (4031b), scripts/proxy_support.test.cjs (4862b), scripts/publish.js (4790b), scripts/refresh_share.js (2253b), scripts/save_api_key.js (1461b), scripts/scode_receive.js (4752b), scripts/shareone_api_request.js (3522b), scripts/shareone_client.js (30721b), scripts/shareone_upload.js (8446b), scripts/update_share_settings.js (6140b), scripts/upload_page.js (8460b), skill-card.md (1915b), SKILL.md (19769b), templates/business-card.html (22681b), templates/canvas-comments.html (11050b), templates/client-side-inference.html (5542b), templates/page-storage-dropzone.html (5476b), test/redirect_follow.test.js (4236b), tests/test_agent_watch.js (5305b), tests/test_api_contracts.js (8698b), tests/test_bind_account_live.js (8564b), tests/test_business_card_template.js (5020b), tests/test_canvas_comments_template.js (4801b), tests/test_credential_guard.js (5745b), tests/test_make_qr.js (6656b), tests/test_scode_receive.js (1942b), workflows/agent-notifications.md (5688b), workflows/bind-account.md (2782b), workflows/comments-process.md (11120b), workflows/comments-view.md (3984b), workflows/delete-api-key.md (1084b), workflows/delete-share.md (2211b), workflows/download-file.md (3715b), workflows/environment-and-credentials.md (3589b), workflows/git-backed-versions.md (6447b), workflows/manage-collaborators.md (3688b), workflows/publish-binary-file.md (3645b), workflows/publish-text-page.md (17000b), workflows/refresh-remote.md (2067b), workflows/result-and-errors.md (7542b), workflows/update-share-settings.md (2729b), _meta.json (127b)\n\nFile v1.5.0:SKILL.md\n\n---\nname: shareone\ndescription: Host HTML/Markdown pages and share PDF, Word, or PowerPoint docs as ShareOne short links. Use for publishing, passwords/watermarks, comments, downloads, updates, or Git-backed remote sources for ShareOne content.\nlicense: MIT\nmetadata:\n  slug: shareone\n  display-name: ShareOne\n  version: 1.5.0\n  summary: Host HTML pages and share PDF/Word/PPT docs with short links\n  tags:\n    - shareone\n    - publish\n    - sharing\n    - hosting\n    - html\n    - upload\n---\n\n# AI Agent 技能：发布到 ShareOne (shareone)\n\nHost HTML/Markdown pages and share PDF, Word, and PowerPoint documents with ShareOne public short links. Covers page publishing, document sharing, password protection, watermarks, review comments, downloads, and updates to existing shares.\n\n这个 Skill 允许 AI Agent 将当前生成的历史会话以及 HTML/Markdown/TXT/PDF/PPT 等文件发布到 ShareOne 线上托管服务，并为用户生成一个持久化的公网分享链接；也可以对已有 ShareOne 链接执行下载、内容更新、设置修改和评论处理。\n\n## 内容版本管理决策\n\nShareOne 复用 **GitHub / GitLab 的内容版本管理**：历史、diff、分支、评审和回退在源仓库完成，ShareOne 负责展示、分享、访问控制和评论协作。`remote_url` 的 snapshot 是当前缓存，ShareOne 不维护独立的文件版本库。\n\n涉及 ShareOne 内容的 Git 源、版本选择、历史或回退时，先读 [workflows/git-backed-versions.md](workflows/git-backed-versions.md)，再按下方路由执行发布、刷新或评论处理。该工作流包含跟随分支、固定 commit、切换版本与验收命令。**当前可直接使用公开 GitHub 文本文件；GitLab 和私有仓库认证仍需接入，不能把产品方向当作已支持能力。** 普通本地文件上传仍按原流程执行，不自行迁移到 Git。\n\n## 脚本执行基准\n\n本文档中所有 `node scripts/xxx.js` 命令的路径都以 **本 skill 的安装目录**（即本 `SKILL.md` 所在目录）为基准。当前工作目录通常是用户的项目目录，直接执行相对路径会失败。执行前先确定 skill 目录，使用绝对路径或先 `cd` 到 skill 目录，例如：\n\n```bash\nnode /path/to/shareone-skill/scripts/ensure_credentials.js\n```\n\n## 入口隔离规则\n\n本 skill 和用户本机可能安装的 `shareone` CLI 是两个独立入口。除非用户明确要求”使用 CLI”或指定执行 `shareone ...` 命令，否则不要调用系统 PATH 中的 `shareone` 命令。即使 `which shareone` 能找到 CLI，也不要把自然语言的发布、下载、评论处理任务改走 CLI。所有 ShareOne 操作都必须调用本 skill 目录内 `scripts/` 下的脚本。\n\n## 使用说明与触发条件\n\n当用户表达出以下意图时，应主动使用此技能：\n\n- \"帮我把 `index.html` 发布到 ShareOne\"\n- \"把我刚才生成的网页发布，给我个链接\"\n- \"生成一个可分享的链接给我的团队看\"\n- \"Upload this presentation to ShareOne and protect it with password 'secret'\"\n- \"发布这个 PDF 到 ShareOne，并加上密码 1234\"\n- \"把这个网页发布到 ShareOne，加上水印 '内部绝密'\"\n- \"把这个网页发布到 ShareOne，链接叫 product-demo\"\n- \"发布这份设计稿并开启协同评论模式\"\n- \"用 shareone 分享上一轮对话\"\n- \"把我刚才写的代码/大段文字分享出去\"\n- \"Share your last response as a note\"\n- \"帮我下载这个 ShareOne 链接的文件：https://s.shareone.vip/s/xxx\"\n- \"拉取一下这个链接的评论：https://s.shareone.vip/s/xxx\"\n- \"删掉/删除这个 ShareOne 链接：https://s.shareone.vip/s/xxx\"\n- \"我 push 了，刷新一下这个 ShareOne 远程链接的内容：https://s.shareone.vip/s/xxx\"\n- \"给这个 ShareOne 链接加水印：https://s.shareone.vip/s/xxx\"\n- \"根据这个链接的评论修改页面：https://s.shareone.vip/s/xxx\"\n- \"修改这个 ShareOne 链接的内容：https://s.shareone.vip/s/xxx\"\n- \"把这个 GitHub 文件发布到 ShareOne：https://github.com/org/repo/blob/main/report.html\"\n- \"用远程 URL 发布这个页面\"\n- \"Publish this GitHub raw URL to ShareOne\"\n\n## 路由判定顺序（唯一路由依据）\n\n入口文件只负责判断用户意图、选择需要阅读的 workflow。不要一次性读取所有 `workflows/*.md`；只读取当前任务命中的子文件。\n\n持续监听评论、接收持久通知或唤醒 scode / 其他 Agent：先读 `workflows/environment-and-credentials.md`，再读 `workflows/agent-notifications.md`，使用 `scripts/agent_watch.js`。普通评论查看和单次处理按以下路由执行，不启动常驻监听。\n\n按以下顺序从上到下判断，**命中第一条即停止**，按该条给出的阅读顺序执行：\n\n1. **删除/清除/移除/重置 ShareOne API Key**\n   → 读 `workflows/delete-api-key.md`。无需凭据检查。\n\n2. **删除/移除 ShareOne 分享链接本身（用户明确要求“删掉/删除/移除”某个 share_id、slug 或链接）**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/delete-share.md`。删除是 owner-only 操作，执行前须与用户确认（软删除后公开链接立即失效）。对 HTML/文本页和二进制文件链接（`/pdf/`、`/ppt/`、`/word/`）通用。注意与第 6 条区分：本条是删除整个 share，不是改设置。\n\n3. **刷新 remote-url auto-follow 分享的源内容（用户说“我 push 了”“拉一下最新源”“刷新这个远程链接”）**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/refresh-remote.md`。remote 页面刷新是懒的、只在打开渲染页时触发，下载/`/file` 只服务缓存；本条用 `refresh_share.js` 显式强制 refetch。仅对绑定了远程 URL 的分享有效；非 remote-bound 返回 `NOT_REMOTE_BOUND`，此时应改走第 6 或第 10 条（改设置 / 重新发布内容）。\n\n4. **绑定账号、注册、升级 guest、绑定邮箱**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/bind-account.md`。\n\n5. **让别人一起编辑、分享编辑权限、添加/移除/查看协作者、对方怎么拿 API Key**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/manage-collaborators.md`，最后读 `workflows/result-and-errors.md`。\n\n6. **用户提供已有 ShareOne 链接、`share_id` 或 slug，且只要求修改水印、访问密码、自定义短链接、评论开关或数据存储开关（不改内容本身）**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/update-share-settings.md`，最后读 `workflows/result-and-errors.md`。\n   这是元数据更新：不要按文件类型路由，不要下载源文件，不要使用 `publish.js`，不要重新上传内容。对二进制文件链接（`/pdf/`、`/ppt/`、`/word/`）同样适用本条。\n\n7. **下载 ShareOne 链接的文件或取回源内容**\n   → 读 `workflows/download-file.md`。下载脚本会在已有凭据时优先尝试 owner 下载，没有凭据时自动走公开下载；不要为了普通下载强制配置 API Key。\n\n8. **只查看、拉取、总结 ShareOne 链接评论（用户没有要求修改）**\n   → 读 `workflows/comments-view.md`。单次查看用 `comment_list.js`，走公开接口，无需凭据检查；维护评论缓存时使用该 workflow 的增量查询步骤。\n\n9. **处理评论、根据评论修改页面、修复 ShareOne 链接内容**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/comments-process.md`（其中的重新发布步骤会引用 `workflows/publish-text-page.md`），最后读 `workflows/result-and-errors.md`。\n\n10. **发布、分享、生成链接、上线（创建新链接或更新已有链接的内容）**\n   → 先读 `workflows/environment-and-credentials.md`，再按目标文件类型二选一，最后读 `workflows/result-and-errors.md`：\n   - `.ppt`、`.pptx`、`.pdf`、`.doc`、`.docx` → `workflows/publish-binary-file.md`\n   - `.html`、`.md`、`.txt`、对话内容、大段文本、代码块、已包装成 HTML 的内容 → `workflows/publish-text-page.md`。注意：`.md`/`.txt` 一律按原格式发布，不要因为内容包含图表就转成 HTML；只有目标本来就是 HTML 页面时才参考其中的 Mermaid.js 章节。\n\n所有需要 ShareOne API 的操作（上面第 2、3、4、5、6、7、9、10 条），都先运行 `node scripts/ensure_credentials.js`，输出 token 含义与处理流程见 `workflows/environment-and-credentials.md`，这里不重复。\n\n## ShareOne 链接与 share_id\n\n- 用户提供的目标可以是完整链接、`/s/<ref>` 等路径、裸 `share_id`（16 位字符串）或自定义短链 slug。服务端接口同时接受 `share_id` 和 slug，无需自行区分两者。\n- `/s/<share_id>` 是最终给用户访问的分享链接，**不是上传 API endpoint**。不要把 `/s/<share_id>` 当作发布地址，也不要直接向 `/s/<share_id>` PUT/POST 文件。\n- 路径前缀与内容类型的对应关系：`/s/`、`/md/` 是文本/HTML/Markdown 页面；`/pdf/`、`/ppt/`、`/word/` 是二进制文件。元数据更新时 `update_share_settings.js` 会按此前缀自动选择 endpoint，裸 `share_id` 或 slug 由脚本先试页面 endpoint、必要时回退文件 endpoint，整个过程不下载源文件。\n- 文本页里 `/s/<ref>` 与 `/md/<ref>` **等价**：前缀不绑定、也不校验内容类型，浏览路由一律按 ref 解析 share、按 share 真实 content-type 渲染。因此文本页可以就地把 content-type 从 md 升级成 html（`.md → .html`，如把 ASCII 图升级成 Mermaid），URL（含老的 `/md/<slug>`）一字不变、评论保留——见 `workflows/publish-text-page.md` §6b。升级用 `--share-id` 更新，**绝不 `--force-new`**。\n- 本地文件发布与更新统一使用 `publish.js`，脚本按文件类型自动分发（stderr 输出 `INFO:CHANNEL:text|binary`）。远程源例外：使用 `upload_page.js --remote-url` 创建或更换源 URL，`refresh_share.js` 刷新已有源。不要因为会话里存在旧的 `/s/<share_id>` 就把二进制文件改走文本页面 PUT；二进制文件传 `--share-id` 会被脚本拒绝（`ERROR:BINARY_NO_SHARE_ID`）。\n- 如果当前会话中已经为同一个文本/HTML 文件生成过 ShareOne 链接，可复用之前的 `share_id` 执行文本页面 PUT 更新；否则执行首次创建。\n- 非 owner 下载要求链接已开启允许下载；若脚本输出 `ERROR:DOWNLOAD_NOT_ALLOWED`，直接提示用户让链接 owner 先开启允许下载。\n\n## 发布前安全自检（非阻塞）\n\n- 创建新分享链接（首次 POST 新页面或首次上传新文件）前，Agent 必须自行做内容安全自检：不得发布明显反动、涉政、暴力、色情、侵权或恶意代码内容。\n- 链接保留规则：普通链接在**最后活跃时间**超过 90 天后会被清理（最后活跃 = 创建时间或最后一次被访问时间的较晚者，持续有效访问会一直保持有效，不是发布后 90 天硬删除）；发布到 Explore 公开广场、被知识库引用、或设了 `remote_url` 的内容不参与此无活跃自动清理。\n- 自检通过后直接继续发布，不要向用户展示安全提示，也不要等待用户回复“同意”或 `agree`。\n- 自检必须轻量：对文本/HTML/Markdown/TXT，只基于当前已知内容或发布所需读取的文本内容判断；对 PDF/PPT/Word 等二进制文件，只基于用户请求、文件名、扩展名和显式参数判断，不要为了自检提取正文、OCR、转换格式或解析文件内部内容。\n- 如果内容明显违反上述规则，停止发布并简要说明原因。\n- 对已有链接执行后续操作时——包括内容 PUT 更新、评论处理闭环中的重新发布、水印/密码/短链/评论开关等元数据修改——按对应 workflow 直接执行。\n- 下载、查看评论、删除 API Key 等不发布内容的操作无需安全自检。\n\n## 不可跳过的阻塞步骤\n\n以下步骤是阻塞性用户通知，不是可选说明。触发后必须先发给用户，再继续后续操作。\n\n- 如果 `ensure_credentials.js --create-guest` 或底层 `create_guest_key.js` 输出 `GUEST_KEY_CREATED:<api_key>`，必须立即向用户发送临时 API Key、绑定账号链接和保存提醒（话术见 `workflows/environment-and-credentials.md`）。即使 key 已经自动保存，也不能省略该通知；发送前不得继续执行原任务的上传、下载、评论处理命令。\n- 本会话首次向用户展示生成的 `share_url` 时，必须按 `workflows/result-and-errors.md` 提示所有未使用的高级功能：自定义短链接名称、访问密码、水印。已使用的能力不再提示；三项都已使用则不提示。\n\n## 全局约束\n\n- 发布前必须完成凭据检查和必要的凭据配置。\n- 发布成功后必须直接使用脚本返回的 `share_url`，不要自行拼接分享链接；不要展示备用链接。\n- 只有当用户明确要求开启评论、允许讨论或协同模式时，才添加 `--allow-comments true`。默认不开启评论。\n- 只有当用户明确要求页面持久化数据（如保存游戏分数、表单状态）时，才添加 `--allow-data true`。默认不开启数据存储。\n- 页面持久化数据时，页面代码用自动注入的 `window.__SHAREONE__` SDK，**必须按敏感度二选一、无默认**：`putShared(key, value|File)` 存服务器·所有访客可读·跨设备（大文件自动走 blob，≤8MB）；`putPrivate(key, value|File)` 只存这台设备·私有·不上传。命名即风险（Shared=别人能看），敏感/隐私数据一律 `putPrivate`。现成的“公开 vs 敏感”拖拽上传参考页：`templates/page-storage-dropzone.html`；私有数据可留在本机就地推理（模型公开＋数据 `putPrivate`＋页面内计算，字节不出设备）的参考页：`templates/client-side-inference.html`；完整 SDK 见后端 `agent.md` §14。发布时若带 `--allow-data true`，命令行会在成功后打印一行 `HINT:PAGE_DATA_ENABLED` 提示该二选一与本地推理用法。\n- 自定义短链接（slug）：服务端会根据文件名自动生成可读的 slug（如 `quarterly-report`），客户端无需额外操作。只有用户明确要求“链接叫 xxx”、“自定义短链接 xxx”、“URL 后缀 xxx”时，才在发布命令添加 `--slug xxx` 覆盖自动生成；slug 冲突时把服务端提示反馈给用户，不要静默改名。\n- 页面需要二维码时用 `node scripts/make_qr.js --text \"<内容>\" --format path`（零依赖，直出 SVG path，贴进页面的 `<path d=\"...\">`；`--format svg` 给完整 `<svg>`，`--ecc L|M|Q|H` 默认 Q）。**不要**引入外部二维码库或 `<img src=\"https://...qrserver...\">` 之类的在线生成服务——发布出去的页面在别人的浏览器里打开，外链会失效、泄露访问者，也印不进 PDF。二维码指向本次发布的链接时，先用 `--slug` 定好链接再生成二维码，顺序反了码会指向不存在的页面。\n- 名片/电子名片：用 `templates/business-card.html`（双面设计，一份 HTML 同时产出可发的图片、可扫的链接、90×54mm 印刷 PDF）。改 `data-field=\"...\"` 的文字即可，vCard 和 tel:/mailto: 由页面脚本从卡面读取，不要另写一份联系方式。二维码指向名片页本身而不是公司官网：扫码的人当场要的是把人存进通讯录，名片页能一键存 vCard，且印出去的卡改不了、名片页能随时更新。\n- 开启评论的页面**不要用 MutationObserver 监听自己的输出来触发重绘**。ShareOne 会往页面里注入评论桥（样式、覆盖层、高亮包裹），这本身就是 DOM 变化；页面若据此重绘、重绘又改 DOM，会自持成无限循环，页面直接跑飞（实测：关评论 render 1 次，开评论 502 次）。确实需要按变化重绘时，用内容签名门控：先算出这一帧该画什么，和上一帧比，一样就不画。同理，**不要在 `pointerdown` 里无条件 `setPointerCapture`** —— 指针被容器捕获后，`click` 会派发给捕获者而不是被点的元素，页面里所有节点都点不动，而元素还在、`elementFromPoint` 也正常，很难查；平移交互应等 `pointermove` 超过 3–5px 再捕获。\n- 开启评论、而**可评论的东西不是 DOM 元素**时（canvas 图、地图、3D 视图、虚拟滚动大表格），用 `window.__SHAREONE__.anchors`：页面声明可评论的稳定身份及其当前位置。最小用法：`anchors.select({id, label}, rect)` 报告用户选择；`anchors.report([{id, state:\"visible\", rect} | {id, state:\"hidden\"} | {id, state:\"missing\"}])` 在布局变化时报告位置；`anchors.on(\"resync\"|\"reveal\"|\"hittest\", fn)` 应答询问。仅在目标存在但当前视图没画时报告 `hidden`；页面无法定位该 id 时报告 `missing`。侧栏分别显示“当前视图隐藏”和“无法定位”，评论仍可阅读、回复；位置恢复后提示消失。文本定位失败或 `resync` 未应答不能推断内容已删除。锚点是一组稳定 id，坐标只用于当前显示，不落库。参考 `templates/canvas-comments.html` 实现点选、框选和视图恢复；完整接口与约束见后端 `agent.md` §14b。\n- 开启评论且页面会自己重绘（图表、流程图、看板、任何切换视图就重建 DOM 的页面）时，给每个可评论元素加一个稳定的 `data-*` id，例如 `<g class=\"node\" data-node-id=\"委外cap\">`。ShareOne 的区域评论以应用自己给的这个 id 作锚，重绘后评论自动跟回同一个元素；没有 id 时只能退回\"第几个同名标签\"的结构路径，重绘可能使它失效。id 在同一页内必须唯一（命中多个元素的 id 会被拒绝），且在重绘前后保持不变——用业务含义命名，别用渲染顺序生成。\n- 生成或修改启用评论的动态 HTML 时，按 [publish-text-page.md 的动态页面要求](workflows/publish-text-page.md#动态页面与文字评论) 保留可阅读文本与稳定身份。文字锚点不索引 SCRIPT/STYLE/NOSCRIPT/TEMPLATE 或标注浮层；大体积数据保留完整，可放在 head 的非执行数据脚本中。性能验收保留评论，实际展开、缩放和拖动；文本定位失败只表示锚点不可用，不代表评论或原文已删除。\n- 评论处理必须形成闭环：认领、修改源内容、同步原分享并验证，然后用 `comment_reply.js --state`（`--state` 必填）**明确表态**——`resolved-agree`（同意收敛）/ `open-disagree`（有异议但保持 open）/ `open-need-input`（需人类澄清）。绑定 Git 源的页面修改仓库后刷新，具体见 `comments-process.md` 和 `git-backed-versions.md`。AI **永不**单方面 dismiss 一条分歧：不同意用 `open-disagree`，`dismiss` 仅用于 owner 确认的无关或垃圾评论；定位失败、权限不足或等待同步时用 `open-need-input`。\n\n## 最终回复前检查清单\n\n在回复用户前，逐项检查：\n\n- 如果本轮创建了临时 API Key，是否已经把 API Key、绑定账号链接和保存提醒发给用户。\n- 如果本轮**创建了新分享链接**，是否已完成发布前安全自检；如果内容明显违规，是否已停止发布。\n- 如果发布成功，是否直接展示返回的 `share_url`，没有自行拼接链接。\n- 如果返回中包含 `custom_slug_warning` 或 `custom_slug_suggestions`，是否展示给用户。\n- 如果这是本会话首次展示生成的 `share_url`，是否提示所有未使用的高级功能。\n\nFile v1.5.0:README.md\n\n# ShareOne Skill：AI Agent 发布与文档分享工具\n\n<p align=\"center\">\n  <strong>把 AI 生成的网页、Markdown、PDF、Word 和 PowerPoint 文档发布为 ShareOne 短链接。</strong>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://shareone.vip\"><img alt=\"Website\" src=\"https://img.shields.io/badge/website-shareone.vip-0f766e\"></a>\n  <img alt=\"ShareOne\" src=\"https://img.shields.io/badge/ShareOne-skill-2563eb\">\n  <img alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-64748b\">\n</p>\n\n官网：https://shareone.vip\n\n\n\n本仓库包含 ShareOne Agent Skill。它让 Codex、Claude Code、OpenAI Agent、Dify、工作流自动化工具等 AI Agent 可以把本地生成的内容快速发布到 ShareOne，并生成可访问、可转发、可更新的公网分享链接。\n\nShareOne 适合用于发布 AI 生成页面、分享 Markdown 在线文档、托管 HTML 演示页、上传 PDF/Word/PPT 文件、生成团队评审链接，以及为文档添加访问密码、水印和评论协作能力。\n\n## 关键词\n\nShareOne 覆盖以下搜索场景：AI Agent 发布工具、HTML 页面托管、Markdown 在线分享、PDF 短链接分享、Word 文档分享、PPT 在线分享、文档水印、访问密码分享链接、AI 生成网页发布、Codex Skill 文档发布、Agent workflow publishing。\n\n## ShareOne 是什么\n\nShareOne 是一个面向 AI Agent 和开发者的轻量级内容发布服务。它可以把 HTML、Markdown、TXT、PDF、Word、PowerPoint 等文件发布为短链接，方便用户在聊天、项目协作、客户沟通、产品演示和内容交付场景中快速分享。\n\n通过 ShareOne Skill，AI Agent 不需要让用户手动上传文件，也不需要额外搭建静态站点。Agent 可以直接调用 Skill 脚本完成发布、更新、下载、评论读取和设置修改。\n\n## 免费托管\n\nShareOne 提供免费的页面与文档托管能力，适合临时演示、项目评审、AI 生成内容分享、客户预览和团队协作。\n\n普通分享链接会按最后活跃时间保留：只要链接持续有有效访问，就会继续保持可用；当距离最后一次有效访问超过 90 天后，链接才可能被自动清理。也就是说，链接不是从发布时间开始固定 90 天过期，而是每次有效访问都会延续它的活跃状态。\n\n发布到 Explore 公开广场、被知识库引用，或绑定了远程 URL 的内容，不参与普通链接的无活跃自动清理。\n\n## 能力地图\n\n| 文件类型 | 分享链接生成 | 密码访问 | 水印 | 自定义短链接 | 评论反馈 | 更新同一链接 |\n| --- | --- | --- | --- | --- | --- | --- |\n| TXT | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| Markdown | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| HTML | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| PDF | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n| Word | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n| PowerPoint | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n\n## 核心能力\n\n- **HTML 页面发布**：将 AI 生成的网页、报告、原型页面或数据看板发布为在线链接。\n- **Markdown 在线分享**：直接发布 `.md` 或 `.txt` 内容，适合笔记、方案、会议纪要和技术文档。\n- **文档文件分享**：支持 PDF、Word、PowerPoint 文件上传与分享。\n- **短链接访问**：生成 ShareOne 公网短链接，便于在微信、邮件、飞书、Slack、Notion、GitHub Issue 等渠道传播。\n- **访问密码**：为敏感文档或内部材料设置访问密码。\n- **水印保护**：给页面或文档增加水印，降低外泄和二次传播风险。\n- **原链接更新**：在保留同一个分享链接的情况下更新内容，适合反复修改的方案、演示稿和评审页面。\n- **评论协作**：文本页面可开启评论，方便团队直接围绕页面内容反馈和修改。\n- **文件下载控制**：支持下载公开文件，也能在权限允许时取回源内容。\n\n## 适用场景\n\n- AI Agent 生成一个 HTML 页面后，需要立即发布给用户预览。\n- 把 Markdown 报告、技术方案、产品说明发布成可分享链接。\n- 将 PDF、Word、PPT 文件分享给客户、同事或外部协作者。\n- 给内部资料添加访问密码或水印。\n- 把已有 ShareOne 链接内容更新为最新版本。\n- 根据 ShareOne 页面评论修改内容，并重新发布到原链接。\n- 把 GitHub 上的远程 HTML 或文档 URL 发布为 ShareOne 链接。\n\n## Agent 使用方式\n\nAgent 在识别到“发布到 ShareOne”“生成分享链接”“分享这个 PDF”“更新这个 ShareOne 链接”“拉取评论”等意图时，会读取 [SKILL.md](./SKILL.md) 中的完整工作流，并调用本 Skill 的 `scripts/` 脚本完成操作。\n\n常见自然语言指令：\n\n```txt\n把 index.html 发布到 ShareOne，给我一个链接\n把这份 PDF 上传到 ShareOne，并设置访问密码 1234\n把刚才生成的 Markdown 报告分享出去\n更新这个 ShareOne 链接的内容：https://s.shareone.vip/s/xxx\n读取这个 ShareOne 页面上的评论并处理\n给这个链接加上水印“内部资料”\n```\n\n## 链接与文档\n\n- ShareOne 官网：https://shareone.vip\n- Skill 完整说明：[SKILL.md](./SKILL.md)\n\nFile v1.5.0:_meta.json\n\n{\n  \"ownerId\": \"kn73tjvxf6qkw5beygj5y939n988wsag\",\n  \"slug\": \"shareone\",\n  \"version\": \"1.5.0\",\n  \"publishedAt\": 1791462901704\n}\n\nFile v1.5.0:scripts/api_contract.json\n\n{\n  \"errors\": {\n    \"BAD_REQUEST\": {\n      \"status\": 400,\n      \"category\": \"validation\",\n      \"hint\": \"Correct the request using the operation's input schema.\",\n      \"retryable\": false\n    },\n    \"AUTH_REQUIRED\": {\n      \"status\": 401,\n      \"category\": \"auth_failed\",\n      \"hint\": \"Sign in or provide the existing account's X-API-Key.\",\n      \"retryable\": false\n    },\n    \"INVALID_API_KEY\": {\n      \"status\": 401,\n      \"category\": \"auth_failed\",\n      \"hint\": \"Check or update this account's API key; retain the identity that owns the share.\",\n      \"retryable\": false\n    },\n    \"FORBIDDEN\": {\n      \"status\": 403,\n      \"category\": \"permission\",\n      \"hint\": \"Use an identity authorized for this resource and operation.\",\n      \"retryable\": false\n    },\n    \"NOT_FOUND\": {\n      \"status\": 404,\n      \"category\": \"not_found\",\n      \"hint\": \"Check the resource reference and the current account's access.\",\n      \"retryable\": false\n    },\n    \"METHOD_NOT_ALLOWED\": {\n      \"status\": 405,\n      \"category\": \"validation\",\n      \"hint\": \"Use the HTTP method declared for this operation.\",\n      \"retryable\": false\n    },\n    \"PAYLOAD_TOO_LARGE\": {\n      \"status\": 413,\n      \"category\": \"validation\",\n      \"hint\": \"Reduce the request to the operation's size limit.\",\n      \"retryable\": false\n    },\n    \"UNSUPPORTED_MEDIA_TYPE\": {\n      \"status\": 415,\n      \"category\": \"validation\",\n      \"hint\": \"Use the operation's declared request content type.\",\n      \"retryable\": false\n    },\n    \"CONFLICT\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Read the reported precondition and correct it before retrying.\",\n      \"retryable\": false\n    },\n    \"VALIDATION_ERROR\": {\n      \"status\": 422,\n      \"category\": \"validation\",\n      \"hint\": \"Correct the fields listed in detail using the operation's input schema.\",\n      \"retryable\": false\n    },\n    \"RATE_LIMIT_EXCEEDED\": {\n      \"status\": 429,\n      \"category\": \"rate_limited\",\n      \"hint\": \"Wait for Retry-After, then retry the same operation.\",\n      \"retryable\": true\n    },\n    \"SERVER_ERROR\": {\n      \"status\": 500,\n      \"category\": \"transient\",\n      \"hint\": \"Back off. Replay writes only with a supported idempotency key or an idempotent operation.\",\n      \"retryable\": true\n    },\n    \"PASSWORD_REQUIRED\": {\n      \"status\": 401,\n      \"category\": \"access_gate\",\n      \"hint\": \"Supply the share password or its verified viewer cookie; keep the current API key.\",\n      \"retryable\": false\n    },\n    \"PASSWORD_INVALID\": {\n      \"status\": 401,\n      \"category\": \"access_gate\",\n      \"hint\": \"Correct the share password; keep the current API key.\",\n      \"retryable\": false\n    },\n    \"EMAIL_GATE_REQUIRED\": {\n      \"status\": 401,\n      \"category\": \"access_gate\",\n      \"hint\": \"Sign in as a viewer or use the owner's/collaborator's API key.\",\n      \"retryable\": false\n    },\n    \"COMMENTS_DISABLED\": {\n      \"status\": 403,\n      \"category\": \"permission\",\n      \"hint\": \"The owner must enable comments before this action is available.\",\n      \"retryable\": false\n    },\n    \"AGENT_OWNER_REQUIRED\": {\n      \"status\": 403,\n      \"category\": \"permission\",\n      \"hint\": \"Agent replies require the share owner's key. A collaborator can manage status but cannot impersonate the owner's agent.\",\n      \"retryable\": false\n    },\n    \"SHARE_SETTINGS_FORBIDDEN\": {\n      \"status\": 403,\n      \"category\": \"permission\",\n      \"hint\": \"Collaborators can update content or filenames; share settings require the owner's key.\",\n      \"retryable\": false\n    },\n    \"AGENT_STATE_REQUIRED\": {\n      \"status\": 422,\n      \"category\": \"validation\",\n      \"hint\": \"Set state to resolved-agree, open-disagree or open-need-input.\",\n      \"retryable\": false\n    },\n    \"COMMENT_ANCHOR_REQUIRED\": {\n      \"status\": 422,\n      \"category\": \"validation\",\n      \"hint\": \"Supply quote and highlighter_data for a root comment; replies inherit them from parent_id.\",\n      \"retryable\": false\n    },\n    \"IS_REPLY\": {\n      \"status\": 422,\n      \"category\": \"validation\",\n      \"hint\": \"Reply to the top-level thread ID returned in detail.parent_id.\",\n      \"retryable\": false\n    },\n    \"COMMENT_THREAD_INVALID\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Ask the share owner to repair this comment's parent references.\",\n      \"retryable\": false\n    },\n    \"INVALID_COMMENT_CURSOR\": {\n      \"status\": 400,\n      \"category\": \"validation\",\n      \"hint\": \"Request a new snapshot without cursor, then save its next_cursor.\",\n      \"retryable\": false\n    },\n    \"CONSUMER_LEASE_BUSY\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Wait for Retry-After before polling this consumer again.\",\n      \"retryable\": true\n    },\n    \"CONSUMER_LEASE_EXPIRED\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Poll again for a new batch and lease token; do not reuse this token.\",\n      \"retryable\": false\n    },\n    \"CONSUMER_SCOPE_CONFLICT\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Use another consumer name for the requested scope.\",\n      \"retryable\": false\n    },\n    \"NOT_REMOTE_BOUND\": {\n      \"status\": 400,\n      \"category\": \"validation\",\n      \"hint\": \"Update this static share's content; refresh applies only to a bound remote source.\",\n      \"retryable\": false\n    },\n    \"REMOTE_SOURCE_BOUND\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Edit at remote_url and refresh the original share. Unbind only when explicitly replacing the source.\",\n      \"retryable\": false\n    },\n    \"CUSTOM_SLUG_TAKEN\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Choose an available slug using the returned suggestions.\",\n      \"retryable\": false\n    },\n    \"IDEMPOTENCY_CONFLICT\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Reuse a key only with the same operation and payload; use a new key for a new intent.\",\n      \"retryable\": false\n    },\n    \"IDEMPOTENCY_BUSY\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Wait for Retry-After, then replay with the same idempotency key and payload.\",\n      \"retryable\": true\n    },\n    \"OPERATION_RESOURCE_GONE\": {\n      \"status\": 410,\n      \"category\": \"not_found\",\n      \"hint\": \"The original operation committed, but its resource was deleted. Use a new key only for an intentional new creation.\",\n      \"retryable\": false\n    }\n  },\n  \"agent_reply_states\": {\n    \"resolved-agree\": {\n      \"parent_status\": \"resolved\",\n      \"parent_agent_stance\": \"agree\"\n    },\n    \"open-disagree\": {\n      \"parent_status\": \"open\",\n      \"parent_agent_stance\": \"disagree\"\n    },\n    \"open-need-input\": {\n      \"parent_status\": \"open\",\n      \"parent_agent_stance\": \"need-input\"\n    }\n  },\n  \"comment_filters\": [\n    \"all\",\n    \"unresolved\",\n    \"open\",\n    \"in_progress\",\n    \"resolved\",\n    \"dismissed\"\n  ],\n  \"idempotency_operations\": [\n    {\n      \"method\": \"POST\",\n      \"path\": \"/api/v1/pages\"\n    },\n    {\n      \"method\": \"POST\",\n      \"path\": \"/api/v1/files\"\n    },\n    {\n      \"method\": \"POST\",\n      \"path\": \"/api/v1/files/confirm\"\n    },\n    {\n      \"method\": \"POST\",\n      \"path\": \"/api/v1/shares/{share_id}/comments\"\n    }\n  ]\n}\n\nFile v1.5.0:skill-card.md\n\n## Description:\n\nPublishes HTML and Markdown pages or PDF, Word, and PowerPoint documents as ShareOne short links, with options to manage access, updates, downloads, and comments.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[beep879](https://clawhub.ai/user/beep879)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nDevelopers and other ShareOne users can publish agent-generated pages and documents for external sharing or team review, then manage links, access settings, downloads, and comments.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Authenticated collaborator or settings operations can be steered to an untrusted URL origin.\n\nMitigation: Use only trusted ShareOne domains; do not pass attacker-supplied full URLs to these commands, and fix origin handling before using saved API keys with untrusted links.\n\nRisk: Publishing private conversation content or deleting a share may disclose information or invalidate a link without a runtime confirmation gate.\n\nMitigation: Require explicit user confirmation before publishing private conversations or deleting any share.\n\n## Reference(s):\n\n- [ShareOne skill release on ClawHub](https://clawhub.ai/beep879/skills/shareone)\n- [ShareOne website](https://shareone.vip)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Guidance]\n\n**Output Format:** [Markdown or text with ShareOne links and operation results]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May create publicly accessible links to uploaded content.]\n\n## Skill Version(s):\n\n1.5.0 (source: server release metadata and skill frontmatter)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.5.0:workflows/agent-notifications.md\n\n# 持久评论通知与 Agent 唤醒\n\n当用户要求持续监听评论、通知 scode 或其他 Agent 时使用本工作流。先完成 `environment-and-credentials.md`，使用页面 owner 的凭据。接收器不创建新账号。\n\n## 接到现有 Agent\n\n通用接收器运行在 Agent 所在机器，无需公网 webhook。服务端持久保存事件和每个消费者的确认位置；即使接收器离线，回来后仍会收到未确认的批次。\n\n```bash\nnode scripts/agent_watch.js --consumer review-agent --share '<分享链接>' \\\n  --cwd '<项目目录>' --command-json '[\"node\",\"receive-shareone.js\"]'\n```\n\n`--command-json` 是可执行文件和参数的 JSON 数组，不经过 shell。接收命令从 stdin 读取一行 JSON：\n\n```json\n{\"source\":\"shareone\",\"consumer\":\"review-agent\",\"events\":[{\"id\":\"事件UUID\",\"sequence\":1,\"event_type\":\"comment.created\",\"share_id\":\"稳定分享ID\",\"comment_id\":\"评论UUID\",\"parent_id\":null,\"actor_role\":\"visitor\",\"status\":\"open\",\"created_at\":\"UTC时间\"}]}\n```\n\n接收命令必须在**处理完成或可靠写入自己的持久收件箱后**才返回退出码 0。失败返回非零；不能先启动一个易丢失的后台任务就报告成功。事件只带引用，不含评论正文、截图、API Key 或确认令牌。处理前调用评论 API 读最新线程，按 `comments-process.md` 的认领、修改、同链接更新和明确回复流程执行。分享或评论已删除时跳过失效引用。\n\n## 恢复 scode 会话\n\n```bash\nnode scripts/agent_watch.js --consumer scode-review --share '<分享链接>' \\\n  --cwd '<项目目录>' --scode-session '<已有会话路径>'\n```\n\n接收器启动 `scode acp`，通过 ACP 的 `session/load` 加载指定会话，再用 `session/prompt` 交付事件。只有会话返回 `end_turn` 才确认；交互权限请求会被取消并保留未确认批次。需要机器已安装并配置 scode，且该会话的权限适合任务。请使用专供监听的会话；不要同时在另一个进程操作同一会话。接收器不会增加 scode 权限。不要猜会话路径或自动选择最近一次会话。\n\n默认使用 scode 配置；需要指定模型或认证模式时，可加 `--scode-args-json '[\"--auth\",\"api-key\",\"--model\",\"sonnet\"]'`。这里只放 scode 参数，API Key 仍保存在 scode 的凭据配置里。\n\n## 可靠性与运行方式\n\n- 默认消费上线后记录的全部历史事件；`--start now` 仅在首次注册时从当前位置开始。重复启动同名消费者不会清空进度。上线前已有评论仍需先用 `comment_list.js` 做一次基线检查。\n- `--share` 可省略（接收该 owner 全部分享）；使用者确定范围后再开启。消费者名称和范围固定；更换范围使用新名称。\n- 默认只把访客变化交给命令，避免 Agent 的回复唤醒自己；其他事件也会正常推进确认位置。`--all-actors` 明确开启全部作者事件。\n- 持续长轮询，断网或命令失败后退避重试，最长间隔 60 秒。一个消费者同一时刻只有一个有效批次租约；处理时自动续租。进程崩溃后，5 分钟租约到期即可重领。\n- 语义为**至少一次**。处理完成但确认前崩溃可能重复送达；以事件 `id` 去重，并检查当前评论状态，不能假定恰好一次。\n- `--timeout-seconds` 默认 1800，超时终止本接收器启动的命令进程树，保留未确认事件。`--once` 只检查并处理一个批次，适合排障和验收。\n- 常驻运行由机器的服务管理器监督：Linux 可用 systemd，Windows 可用任务计划程序（登录启动、失败重启、禁止重叠实例）。工作目录指向项目；命令指向安装目录内本脚本。把 API Key 放凭据文件或安全环境配置，不放命令行或任务参数。机器休眠或接收器停止时不会立即唤醒；恢复后补发。\n- 启动常驻监听前确定接收项目、消费者范围和具体会话/命令。只完成脚本安装不表示已开始后台监听。\n\n## HTTP 接口\n\n均需 owner 鉴权，路径前缀 `/api/v1/agent-consumers`：\n\n| 请求 | 含义 |\n|---|---|\n| `PUT /<name>`，`{\"share_id\":null,\"start\":\"beginning\"}` | 幂等注册；可传稳定 ID 或 slug |\n| `GET /`（实际不带尾斜杠） | 列出自己的消费者和游标 |\n| `GET /<name>` | 查看游标和租约到期时间 |\n| `POST /<name>/poll`，`{\"limit\":50,\"wait_seconds\":20}` | 最多 100 条、最多等 25 秒；空批次无令牌 |\n| `POST /<name>/renew`，`{\"lease_token\":\"...\"}` | 将当前租约续到 5 分钟后 |\n| `POST /<name>/ack`，`{\"lease_token\":\"...\"}` | 确认整个已交付批次；重试同一确认幂等 |\n| `POST /<name>/release`，`{\"lease_token\":\"...\"}` | 处理失败后释放，不推进游标 |\n| `DELETE /<name>` | 删除消费者；需要重置进度时明确执行再注册 |\n\n读取不会确认。`ack` 不接受任意目标游标，过期/被替换的令牌返回 409。每个 owner 的事件有独立递增序号；不同 Agent 使用不同消费者名。当前事件不自动过期，删除消费者不会删事件；不承诺无限保存评论正文，事件中的引用可能已失效。\n\n## 防止重投产生重复写入\n\n事件按至少一次投递：处理成功后才 ACK。发布新页面、上传文件或回复评论时，使用稳定的 `--idempotency-key`，例如 `<event.id>.reply`；重试必须保留同一键和同一请求内容。回复脚本返回实际 `parent_status` / `parent_agent_stance`。幂等冲突时先检查原操作与资源状态，不要换键绕过冲突后重复创建；操作返回 409 busy 时按 `Retry-After` 等待。直接上传确认重试应保留原 `share_id`。\n\nFile v1.5.0:workflows/bind-account.md\n\n# 绑定账号（Guest → 注册用户升级）\n\n当用户表达\"绑定账号\"、\"注册\"、\"升级 guest\"、\"绑定邮箱\"等意图时读取本文件。执行前必须已经完成 `environment-and-credentials.md`（确保有可用的 API Key）。\n\n## 核心概念\n\n- Guest 用户通过 `POST /api/v1/agent-guest-key` 获取的临时 API Key，绑定邮箱后升级为注册用户\n- **API Key 不变**：绑定只是在同一个 user record 上添加 email，`user.id` 和 `api_key` 都保持不变\n- 绑定后用户可以用邮箱登录 ShareOne 网站 dashboard 管理文件\n- 整个流程由 agent 代劳，用户不需要打开浏览器\n\n## 流程\n\n### 1. 获取用户邮箱\n\n如果用户还没有提供邮箱，询问：\n\n> 请提供您的邮箱地址，我来帮您绑定账号。绑定后您的 API Key 不变，还可以用邮箱登录 ShareOne 网站管理文件。\n\n### 2. 发送验证码\n\n```bash\nnode scripts/bind_account.js --send --email <用户邮箱>\n```\n\n按输出 token 处理：\n\n- `CODE_SENT`：通知用户查看邮箱：\n  > 验证码已发送到 `<邮箱>`，请查看邮箱（含垃圾箱），告诉我 6 位数字验证码。\n- `ERROR:EMAIL_ALREADY_LINKED`：该邮箱已被其他账号使用。告知用户并建议使用其他邮箱，或直接用该邮箱登录网站。\n- `ERROR:COOLDOWN`：发送冷却中，请等待 30 秒后重试。\n- `ERROR:RATE_LIMIT`：频率限制，稍后再试。\n- `ERROR:KEY_NOT_FOUND`：API Key 不存在，需要先通过 `ensure_credentials.js` 获取凭据。\n\n### 3. 等待用户回复验证码\n\n暂停操作，等待用户告知 6 位验证码。\n\n### 4. 验证并绑定\n\n```bash\nnode scripts/bind_account.js --verify --email <用户邮箱> --code <验证码>\n```\n\n按输出 token 处理：\n\n- `BIND_SUCCESS`：绑定成功。向用户确认：\n  > 账号绑定成功！您的邮箱 `<邮箱>` 已与当前 API Key 关联。API Key 不变，您现在可以用这个邮箱登录 ShareOne 网站管理分享的文件。\n- `ERROR:INVALID_CODE`：验证码错误，请用户检查后重新输入。不需要重新发送验证码。\n- `ERROR:CODE_EXPIRED`：验证码已过期（5 分钟有效），需要重新发送。回到第 2 步。\n- `ERROR:TOO_MANY_ATTEMPTS`：验证码尝试次数过多（最多 5 次），需要重新发送。回到第 2 步。\n- `ERROR:EMAIL_ALREADY_LINKED`：邮箱已被其他账号使用。建议使用其他邮箱。\n- `ERROR:KEY_NOT_FOUND`：API Key 无效或 guest 账号不存在。\n\n## 不要做的事\n\n- 不要让用户打开浏览器去网站绑定——整个流程在对话中完成。\n- 不要在绑定后生成新的 API Key——绑定不改变 key。\n- 不要在用户没有明确要求时主动发起绑定流程（但在首次创建 guest key 后可以简短提示）。\n\nFile v1.5.0:workflows/comments-process.md\n\n# 处理 ShareOne 评论\n\n当用户明确要求“处理这些评论”、“根据评论改一下页面”、“修改这个 ShareOne 链接的内容”时读取本文件。只查看评论时不要读取本文件。\n\nShareOne 页面评论包含状态机字段 `status`：`open` / `in_progress` / `resolved` / `dismissed`，以及作者字段 `author_role`：`visitor` / `owner` / `agent`。\n\n处理评论需要 owner 的 API Key（认领状态、发 agent 回复都要求 owner 鉴权），执行前必须已经完成 `environment-and-credentials.md`。\n\n## 1. 获取 ref 与评论\n\n用户提供的目标可以是完整链接、`/s/<ref>` 或 `/md/<ref>` 路径、裸 `share_id` 或自定义短链 slug。取路径最后一段作为 `<REF>` 即可，接口同时接受 `share_id` 和 slug。\n\n本 workflow 只适用于可编辑的文本/HTML/Markdown 页面评论处理。若目标链接路径明确是 `/pdf/`、`/ppt/`、`/word/`，或下载后的 `INFO:CONTENT_TYPE`/文件扩展名显示为 PDF/PPT/Word 等二进制文档，不要为处理评论解析、转换或修改二进制正文；停止内容修改流程，并告知用户当前 skill 只支持处理页面源码评论，二进制文档只能查看/总结评论或更新元数据设置。\n\n任务锚点：步骤 2 的下载命令（`--task-anchor`）会自动把 `<REF>` 写入当前目录的 `.shareone_active_task` 文件，把目标 share 固定到磁盘上（防止长时间编辑文件后上下文丢失，误把更新发成新链接）。后续所有步骤中的 `<REF>` 都以该文件内容为准；任何时候不确定目标 share 是哪个，读取该文件，**不要凭记忆，更不要新建链接**。\n\n先获取未处理评论：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments?status=unresolved\"\n```\n\n评论数据中可能包含 `replies`。必须将父评论及其所有回复作为一个 thread 整体阅读，综合理解最终共识。回复不需要单独走流程，只对父评论操作状态。\n\n“当前视图隐藏”是页面明确报告的可见性；“无法定位”也可能来自旧文字位置、文字修改或页面未应答。评论卡片仍保留，不能据定位失败推断内容已删除、自动 dismiss 或关闭评论。若反馈涉及动态 HTML 性能，按 `publish-text-page.md` 的“动态页面与文字评论”要求保留数据和评论，并验证展开、缩放、拖动与重定位。\n\n## 2. 标准闭环流程\n\n对每条要处理的父评论，严格按以下顺序执行。\n\n### 步骤 1：认领\n\n必须在动手之前做：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/<COMMENT_ID>/status\" \\\n  --method PUT \\\n  --data '{\"status\": \"in_progress\"}'\n```\n\n访问者会立刻在页面侧栏看到“处理中”徽标和顶部“AI 正在处理 N 条评论...”横幅。跳过这一步会让用户感受不到 AI 在干活。\n\n### 步骤 2：取源（自动写锚点）\n\n```bash\nnode scripts/download_share.js \"<REF>\" --task-anchor\n```\n\n`--task-anchor` 会自动完成三件事：写入 `.shareone_active_task` 锚点（stderr 输出 `ANCHOR_WRITTEN:`）、按服务端文件名的扩展名把源内容保存为 `shareone_<REF>_source.<ext>`（stdout 输出 `SAVED:<本地文件名>`）、在 stderr 输出 `INFO:FILENAME:`（原始文件名，步骤 4 要用）和 `INFO:CONTENT_TYPE:`。文件名携带目标 share，即使对话上下文丢失也能恢复 `<REF>`。已配置 owner API Key 时脚本自动走 owner 下载接口，不受密码和下载开关限制。\n\n**根据下载信息选择修改位置：**\n\n- 未绑定远程源：编辑 `SAVED:` 给出的本地文件，按步骤 4A 更新原分享。\n- 出现 `INFO:REMOTE_SOURCE` / `HINT:EDIT_AT_SOURCE`：下载的是远程源的缓存副本。先读 [git-backed-versions.md](git-backed-versions.md)，在对应 Git 仓库修改，按步骤 4B 同步原分享。若源是另一个 ShareOne 分享，则修改那个源 share 后刷新当前分享；保留当前 `.shareone_active_task` 作为回复目标，不用它替代源 share 的 ID。\n\n### 步骤 3：精准应用修改\n\n- 综合理解整个 thread（父评论 + 所有 replies）的最终意图，必要时先和用户确认。\n- 绝对不要用全局 `replace()` 或正则批量替换，会误伤其他同名文案。\n- 基于 DOM 结构精确定位：利用 `highlighter_data.startMeta.parentTagName`、`parentIndex`、`textOffset`，结合 `quote`（被选中原文）定位准确节点。\n- 理解结构性意图：评论可能是“把这部分挪到底部 / 删掉这个区块 / 加个图标”，先定位再做结构变更。\n- 如果无法定位原文，先保留评论与原文，用 `comment_reply.js --state open-need-input` 说明缺少的信息并等待澄清。定位失败不能证明内容不存在，也不能成为 dismiss 的依据。\n\n### 步骤 4：更新并验收原分享（保留目标 ID）\n\n#### 4A. 未绑定远程源：PUT 上传正文\n\n脚本选择说明：更新**内容**只能用 `publish.js --share-id`（带 `--share-id` 时执行的是 PUT 内容更新，不是创建）；`update_share_settings.js` 只能改密码/水印/短链/评论开关等元数据，**无法替换页面内容**，本步骤不要使用它。\n\n直接执行以下命令更新原链接。`<REF>` 与步骤 1、2、5 是同一个值，即 `.shareone_active_task` 文件的内容：\n\n```bash\nnode scripts/publish.js \"<步骤 2 SAVED: 给出的本地文件>\" --filename \"<INFO:FILENAME 给出的原文件名>\" --share-id <REF>\n```\n\n硬规则：\n\n- 评论处理流程中**禁止**不带 `--share-id` 执行发布命令——那会 POST 创建一个全新链接，原链接和上面已认领的评论都不会得到任何更新。\n- 不要跳读 `publish-text-page.md` 的“判断创建还是更新”一节，评论场景永远是更新，没有“首次创建”分支。\n- 如果此刻想不起 `share_id`，读取 `.shareone_active_task` 文件或源文件名中的 `shareone_<REF>_` 前缀，绝不新建。\n- 如果脚本输出 `ERROR:ACTIVE_SHARE_TASK`，说明漏传了 `--share-id`，按错误提示补上后重试。\n\n评论闭环中的重新发布属于对已有链接的更新，**不需要**向用户展示发布前安全提示或等待确认（规则见入口 `SKILL.md`）。\n\n#### 4B. 绑定远程源：修改源头后刷新\n\nGit 源按仓库现有流程提交、评审和合并到绑定分支，然后执行 `node scripts/refresh_share.js \"<REF>\"`。固定 commit 的分享，先按 `git-backed-versions.md` 用原 `--share-id` 换成已选定的新 commit URL。ShareOne 内链则更新源 share 后刷新当前分享。\n\n核对 `remote_last_error` 并下载确认预期修改已进入原分享，再执行步骤 5。不要对远程源页面用 `publish.js` 上传缓存副本；遇到 `REMOTE_SOURCE_BOUND` 不自动解绑。没有源仓库权限、PR 尚待合并或同步失败时，说明剩余步骤，用 `open-need-input` 保持待处理。可附修复 commit/PR 链接，但当前评论没有自动绑定创建时的 commit。\n\n### 步骤 5：回复评论并**强制表态**（一条命令，`--state` 必填）\n\n每次回复评论都**必须**用 `comment_reply.js` 并声明一个 `--state`——这是硬性要求（缺省即报错），目的是杜绝“只回复不收敛 / 有分歧却没 signal 出来 / 不确定却没保持 open”这三种失败模式：\n\n```bash\n# 同意并已按建议修改 → 评论收敛为 resolved\nnode scripts/comment_reply.js \"<REF>\" <COMMENT_ID> --content \"已按你的建议把标题改成 ...，并调整了 ...\" --state resolved-agree\n```\n\n`--state` 三选一（无默认）：\n\n| state | 含义 | 对父评论的作用 |\n|---|---|---|\n| `resolved-agree` | 充分理解且同意，已处理 | 置 `resolved` |\n| `open-disagree` | 不同意（在 `--content` 里写清理由） | **保持 `open`**，标记“AI 有异议”，把是否关闭交回给提出者 |\n| `open-need-input` | 需要人类进一步澄清/输入 | 保持 `open` |\n\n脚本会自动从父评论继承 `quote`/`highlighter_data`、以 `author_role=agent` 发一条回复（输出 `REPLY_POSTED:<id>` 和 `COMMENT_STATE:<state>`），后端据 `--state` 原子地设置父评论状态与 AI 立场。不要手工拼接含 `highlighter_data` 的 JSON。\n\n**关键原则：AI 永不单方面关闭一条分歧。** 不同意时用 `open-disagree`（保持 open、让提出者决定），**绝不**用 dismiss 把别人的评论关掉——关闭/重开一条评论的权力属于提出评论的人（以及页面 owner）。\n\n- 输出 `ERROR:STATE_REQUIRED` / `ERROR:INVALID_STATE`：必须补上合法的 `--state`。\n- 输出 `ERROR:IS_REPLY:<parent_id>`：传入的是回复 ID，改用父评论 ID 重试。\n- 输出 `ERROR:AUTH_FAILED`（403）：先查该链接评论是否被关闭（`allow_comments=false`），可经 `update-share-settings.md` 重新开启后重试。\n\n如果误发了一条回复，可以删除（仅作者本人、且父评论仍为 `open` 时可删，会级联删除其回复）：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<SHARE_ID>/comments/<COMMENT_ID>\" --method DELETE\n```\n\n## 3. 无关或垃圾评论\n\n**注意区分“不同意”与“无关”**：对你有异议但属于合理讨论的评论，用步骤 5 的 `--state open-disagree`（保持 open），**不要** dismiss。`dismiss` 只用于**owner 确认的无关或垃圾评论**的评论（例如指向了另一份分享、垃圾评论）——这是 owner 的否决动作：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/<COMMENT_ID>/status\" --method PUT --data '{\"status\":\"dismissed\",\"note\":\"owner 确认这是垃圾评论\"}'\n```\n\n确认返回 JSON 的 `status` 为 `dismissed`。无法定位、权限不足、源 PR 待合并或刷新失败时，用 `open-need-input` 并说明原因。\n\n## 4. 收尾：删除任务锚点\n\n所有目标评论都已 `resolved` 或 `dismissed`、且重新发布完成后，删除任务锚点文件：\n\n```bash\nrm -f .shareone_active_task\n```\n\n不删除的话，之后正常的新页面发布会被发布脚本拦截（`ERROR:ACTIVE_SHARE_TASK`）。\n\n## 5. 兼容旧接口\n\n旧接口仍然可用，但新代码不要使用：\n\n```http\nPUT /api/v1/shares/<REF>/comments/<COMMENT_ID>/resolve\n{ \"resolved\": true/false }\n```\n\n它等价于把 `status` 切到 `resolved` 或 `open`，但不会附带 `note`，访问者拿不到 AI 的解释。新代码一律使用 `/status` 接口。\n\n## 6. 关键准则速查\n\n| 准则 | 为什么 |\n| --- | --- |\n| 动手前先 `in_progress` | 让访问者看到“AI 在干活” |\n| 改完一定要 `POST` 一条 `author_role=agent` 的回复 | 闭环的“答复”部分，没有它就只是状态变化、不是对话 |\n| `note` 要写人话 | “已把按钮改成主色” 比 “Applied.” 有用 |\n| 信息或权限不足时 `open-need-input` | 保留待办并说明需要的人类输入 |\n| 只对父评论改状态，回复不单独操作 | 状态语义属于 thread 整体 |\n| `unresolved` = `open + in_progress` | 拉单子默认用 `?status=unresolved` |\n\nFile v1.5.0:workflows/comments-view.md\n\n# 查看 ShareOne 评论\n\n当用户只是要求查看、拉取、总结评论时读取本文件。不要修改源文件，不要认领评论，不要关闭评论。\n\n开放分享允许匿名读取。完整列表、摘要、增量查询和截图均遵守密码、登录与评论开关；owner/协作者可用已有 API Key 跳过访问者门禁。`comment_list.js` 会使用已有凭据，也允许开放分享的匿名读取；不需要为查看评论新建身份。\n\n## 1. 获取 ref\n\n用户提供的目标可以是完整链接、`/s/<ref>` 或 `/md/<ref>` 路径、裸 `share_id` 或自定义短链 slug。取路径最后一段作为 `<REF>` 即可，接口同时接受 `share_id` 和 slug。\n\n## 2. 查看评论\n\n优先用 `comment_list.js`——它输出干净的 UTF-8 JSON（`{ share, status, count, comments:[{ id, status, author_role, quote, content, created_at, updated_at, screenshot_url, agent_stance, viewer_can_manage, resolution_note, reply_count, replies:[...] }] }`），省去手工拼接 endpoint 和解析原始响应，也规避控制台非 ASCII 乱码：\n\n```bash\nnode scripts/comment_list.js <REF>                 # 默认 --status all\nnode scripts/comment_list.js <REF> --status open   # 只看未处理\nnode scripts/comment_list.js <REF> --json compact  # 单行 JSON，便于管道解析\n```\n\n`--status` 可选值：\n\n- `all`（默认）\n- `open`\n- `in_progress`\n- `resolved`\n- `dismissed`\n- `unresolved`，等价于 `open + in_progress`\n\n受限分享需要授权。密码门禁返回 `PASSWORD_REQUIRED`，登录门禁返回 `EMAIL_GATE_REQUIRED`；按 hint 完成访问授权，保持当前账号 Key。\n\n截图路径以 `/comment-screenshots/` 开头时，相对正在访问的 ShareOne origin 解析，发送同一 origin 的已验证 Cookie 或 owner/协作者凭据。\n\n## 3. 评论理解规则\n\n- 只展示评论内容，绝对不要自作主张开始修改源文件。\n- 等用户明确要求“处理这些评论”、“根据评论改一下页面”等，再进入 `comments-process.md`。\n- 评论数据中可能包含 `replies`。必须将父评论及其所有回复作为一个 thread 整体阅读，综合理解最终共识。\n- 不要把每条回复当成独立修改指令。\n- 所有回复继承父评论的锚点，也就是 `highlighter_data` 和 `quote`。\n\n## 4. 轻量摘要\n\n如果只想看“现在还有没有未处理的事”，用摘要接口：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/summary\" --public\n# -> { total, open, in_progress, resolved, dismissed, last_activity_at }\n```\n\n返回 `open + in_progress == 0` 时没有待处理线程；需要阅读历史内容时仍可拉取列表。\n\n## 5. 增量维护评论缓存\n\n需要持续更新一个评论视图时，可以复用通用请求脚本：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/changes\" --public\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/changes?cursor=<URL_ENCODED_CURSOR>&limit=100\" --public\n```\n\n首次省略 `cursor`，用 `reset=true` 的 `comments` 替换缓存；包括上线前已有的评论。后续按顶层 ID 替换返回的完整线程（含回复），删除 `deleted_ids`，应用成功后保存 `next_cursor`。`has_more=true` 时立即继续；`limit` 是事件数，默认 100、最大 200。线程反映当前状态，同一批可幂等重放。400 表示游标无效，应重新获取快照。游标只对原分享有效。\n\n此接口每次检查页面密码/登录要求。`--public` 适用于没有访问门槛的分享；有 owner/协作者凭据时省略 `--public`。浏览器访问者使用页面授权 Cookie；本脚本不会代填页面密码。`comment_list.js` 保留截图、AI 立场、更新时间、权限字段和嵌套回复，只省略较大的 `highlighter_data`。\n\n该接口只读，不注册消费者或确认事件。需要可靠接收通知并唤醒 Agent 时，使用 `agent-notifications.md` 的持久消费者流程。\n\nFile v1.5.0:workflows/delete-api-key.md\n\n# 删除 ShareOne API Key\n\n当用户明确要求删除、清除、移除或重置 ShareOne API Key 时读取本文件。\n\n## 1. 执行删除\n\n执行：\n\n```bash\nnode scripts/delete_api_key.js\n```\n\n## 2. 根据输出回复\n\n- `SUDOWORK_KEY_DELETED`：告诉用户 Sudowork 中保存的 ShareOne API Key 已删除（如有本地 fallback 凭证也已一并清理）。\n- `SUDOWORK_FALLBACK_KEY_DELETED`：告诉用户 Sudowork 当前凭证环境不可用，已删除 ShareOne fallback 本地凭证。\n- `KEY_DELETED`：告诉用户本地保存的 ShareOne API Key 已删除。\n- `KEY_NOT_FOUND`：告诉用户当前没有找到已保存的 ShareOne API Key，无需删除。\n- `ERROR:<message>`：删除 Sudowork secret 时出现异常（例如 Auth Proxy 故障）。把错误信息告知用户，建议稍后重试或在 Sudowork 密钥管理中手动删除。\n\n## 3. 删除后的规则\n\n删除后，如果用户再次要求发布、查看评论、处理评论或执行任何 ShareOne API 操作，必须重新读取 `environment-and-credentials.md` 并完成凭据检查和配置。\n\nFile v1.5.0:workflows/delete-share.md\n\n# 删除 ShareOne 分享链接\n\n当用户明确要求“删除/删掉/移除”某个已有 ShareOne 分享链接本身时读取本文件。这是 owner-only 操作，删除后公开链接立即失效（软删除）。\n\n不要把“删除链接”和“修改设置”（水印/密码/短链/评论开关，见 `update-share-settings.md`）混淆；本流程销毁整个 share。\n\n## 0. 删除前确认（阻塞）\n\n执行删除命令前，必须先向用户复述要删除的目标（链接/`share_id`/slug）并获得明确确认。用户确认前不要调用 `delete_share.js`。\n\n## 1. 凭据\n\n删除需要 owner 的 API Key。先运行 `node scripts/ensure_credentials.js`（含义见 `workflows/environment-and-credentials.md`）。没有可用凭据时不要继续。\n\n## 2. 获取 ref\n\n目标可以是完整链接、`/s/<ref>` 等路径、裸 `share_id` 或自定义 slug。脚本会自行取末段并同时接受 `share_id` 与 slug；HTML/文本页和二进制文件（`/pdf/`、`/ppt/`、`/word/`）通用。\n\n## 3. 执行删除\n\n```bash\nnode scripts/delete_share.js <REF>\n```\n\n成功输出 `SHARE_DELETED:<ref>`。删除是幂等的：对已删除的链接重复执行仍返回 `SHARE_DELETED`。\n\n### 连带失效的指针（必须转达给用户）\n\n如果有别的 ShareOne 分享把这条链接当作内容源（remote-url **指针**），它们会**一并失效**，每条打印一行：\n\n```\nPOINTER_INVALIDATED:https://s.shareone.vip/s/xxx\nHINT:POINTERS_INVALIDATED:2\n```\n\n出现这些行时，**必须把每条失效链接原样列给用户**，不要只说\"已删除\"。指针不持有内容、只缓存源的内容，源撤了它们就没有可指的东西；但**指针可能属于别人**，用户需要知道自己刚刚让哪些链接失效了，才能去知会对方。没有这些行就表示没有任何指针受影响。\n\n## 4. 错误处理\n\n- `ERROR:KEY_NOT_FOUND`：没有可用凭据，先按 `environment-and-credentials.md` 配置或创建 guest key。\n- `HTTP 404`：链接不存在，或不属于当前 API Key（IDOR 保护）。据此提示用户核对链接归属。\n- 其他 `ERROR:*` / `AUTH_FAILED`：把服务端返回的原因反馈给用户，不要静默重试。\n\nFile v1.5.0:workflows/download-file.md\n\n# 下载 ShareOne 链接文件\n\n当用户要求“下载这个 ShareOne 链接的文件”或“取回这个链接的源内容”时读取本文件。普通下载不需要先配置 API Key：脚本会在已有凭据时优先尝试 owner 下载，没有凭据时自动退回公开下载。只有用户明确要求用 owner 身份下载、或公开下载失败后需要 owner 权限时，才回到 `environment-and-credentials.md` 完成凭据配置。\n\n## 1. 获取链接或 ref\n\n用户可以提供完整链接、`share_id`、自定义短链 slug，或 `/s/<share_id>` 这类路径。把用户原始输入直接作为参数传给下载脚本即可，脚本会自行解析；不需要自行判断 slug 和 share_id。\n\n## 2. 下载内容\n\n使用 `--save`，脚本会按服务端返回的文件名自动保存到当前目录；如果同名文件已存在，会自动添加数字后缀避免覆盖。成功后在 stdout 输出 `SAVED:<本地文件名>`：\n\n```bash\nnode scripts/download_share.js \"<LINK_OR_ID>\" --save\n```\n\n同时 stderr 会输出文件信息：\n\n```text\nINFO:FILENAME:<原始文件名>\nINFO:CONTENT_TYPE:<mime 类型>\nINFO:REMOTE_SOURCE:<remote_url>      # 仅当该 share 的内容来自远程 URL 时出现\nHINT:EDIT_AT_SOURCE                  # 伴随 REMOTE_SOURCE 出现\n```\n\n如果出现 `INFO:REMOTE_SOURCE` 和 `HINT:EDIT_AT_SOURCE`，说明这个 share 的内容来源是远程 URL（如 GitHub 仓库文件或另一个 ShareOne 链接）。提示用户：如果要修改内容，建议直接去源头修改（如在 GitHub 上编辑原文件），这样所有引用该源的分享链接都会自动同步更新。\n\n用户进一步要求修改 Git 源或管理版本时，读 [git-backed-versions.md](git-backed-versions.md)。跟随分支的源可拉取后续提交；固定 commit 的源需要显式换 URL 才会换版。单纯下载不修改仓库或分享绑定。\n\n脚本会在已配置 ShareOne API Key 时先尝试 owner 下载接口；owner 下载不受访问密码和 `allow_download` 限制。如果当前 API Key 不是 owner 或没有 API Key，脚本会自动退回公开下载。\n\n如果用户提供了访问密码，必须通过 `--password` 传入（脚本用 POST body 发送密码），不要把密码拼进 URL：\n\n```bash\nnode scripts/download_share.js \"<LINK_OR_ID>\" --password \"<PASSWORD>\" --save\n```\n\n如需把内容输出到 stdout 自行处理（例如管道），去掉 `--save` 即可，此时 stdout 是原始文件内容（不是 JSON）。\n\n## 3. 错误处理\n\n下载失败时脚本向 stderr 输出 `ERROR:<code>`，按 code 处理：\n\n| 脚本输出 | 含义与应对 |\n| --- | --- |\n| `ERROR:PASSWORD_REQUIRED` | 该链接需要访问密码才能下载。告诉用户请提供密码后再下载。 |\n| `ERROR:PASSWORD_INVALID` | 用户提供的访问密码不正确。告诉用户密码错误，请确认后重新提供。 |\n| `ERROR:DOWNLOAD_NOT_ALLOWED` | 链接没有开启允许下载。告诉用户需要链接 owner 在文件管理中开启“允许下载”后才能下载。 |\n| `ERROR:SHARE_NOT_FOUND` | 链接不存在或已失效。请用户确认链接是否正确、是否已过期删除。 |\n| 其他 `ERROR:<HTTP ...>` | 按 `result-and-errors.md` 的通用错误规则处理。 |\n\n不要在收到错误后重试同一请求；先按上表与用户沟通缺失的信息。\n\n## 4. 后续处理\n\n- 如果用户只是要求下载或查看，展示下载结果摘要，并按 stderr 中 `INFO:FILENAME` / `INFO:CONTENT_TYPE` 说明文件名和内容类型。\n- 如果用户要求修改下载到的内容，直接编辑 `SAVED:` 给出的本地文件，再根据文件类型读取 `publish-text-page.md` 或 `publish-binary-file.md` 执行更新。\n\nArchive v1.3.6: 50 files, 126311 bytes\n\nFiles: agents/openai.yaml (238b), LICENSE (1068b), README.md (5303b), scripts/bind_account.js (6804b), scripts/check_api_key.js (1921b), scripts/comment_list.js (2996b), scripts/comment_reply.js (4575b), scripts/comment_resolve.js (4942b), scripts/create_guest_key.js (3089b), scripts/delete_api_key.js (1260b), scripts/delete_share.js (2715b), scripts/download_share.js (6605b), scripts/ensure_credentials.js (10111b), scripts/make_qr.js (23390b), scripts/manage_collaborators.js (4307b), scripts/proxy_support.test.cjs (4862b), scripts/publish.js (4926b), scripts/refresh_share.js (2311b), scripts/save_api_key.js (1489b), scripts/shareone_api_request.js (3425b), scripts/shareone_client.js (26267b), scripts/shareone_upload.js (8011b), scripts/update_share_settings.js (6306b), scripts/upload_page.js (8152b), skill-card.md (1876b), SKILL.md (18544b), templates/business-card.html (22681b), templates/canvas-comments.html (11050b), templates/client-side-inference.html (5542b), templates/page-storage-dropzone.html (5476b), test/redirect_follow.test.js (4236b), tests/test_bind_account_live.js (8564b), tests/test_business_card_template.js (5020b), tests/test_canvas_comments_template.js (4801b), tests/test_credential_guard.js (5745b), tests/test_make_qr.js (6656b), workflows/bind-account.md (2782b), workflows/comments-process.md (9372b), workflows/comments-view.md (2289b), workflows/delete-api-key.md (1084b), workflows/delete-share.md (2211b), workflows/download-file.md (3460b), workflows/environment-and-credentials.md (3589b), workflows/manage-collaborators.md (3688b), workflows/publish-binary-file.md (3645b), workflows/publish-text-page.md (11898b), workflows/refresh-remote.md (1732b), workflows/result-and-errors.md (6129b), workflows/update-share-settings.md (2729b), _meta.json (127b)\n\nFile v1.3.6:SKILL.md\n\n---\nname: shareone\nslug: shareone\ndisplayName: ShareOne\nversion: 1.3.6\nsummary: Host HTML pages and share PDF/Word/PPT docs with short links\ntags: [shareone, publish, sharing, hosting, html, upload]\ndescription: Host HTML/Markdown pages and share PDF, Word, or PowerPoint docs as ShareOne short links. Use when publishing pages/docs, adding passwords/watermarks, comments, downloads, or updates.\nlicense: MIT\nmetadata:\n  slug: shareone\n  display-name: ShareOne\n  version: 1.3.6\n  summary: Host HTML pages and share PDF/Word/PPT docs with short links\n  tags:\n    - shareone\n    - publish\n    - sharing\n    - hosting\n    - html\n    - upload\n---\n\n# AI Agent 技能：发布到 ShareOne (shareone)\n\nHost HTML/Markdown pages and share PDF, Word, and PowerPoint documents with ShareOne public short links. Covers page publishing, document sharing, password protection, watermarks, review comments, downloads, and updates to existing shares.\n\n这个 Skill 允许 AI Agent 将当前生成的历史会话以及 HTML/Markdown/TXT/PDF/PPT 等文件发布到 ShareOne 线上托管服务，并为用户生成一个持久化的公网分享链接；也可以对已有 ShareOne 链接执行下载、内容更新、设置修改和评论处理。\n\n## 脚本执行基准\n\n本文档中所有 `node scripts/xxx.js` 命令的路径都以 **本 skill 的安装目录**（即本 `SKILL.md` 所在目录）为基准。当前工作目录通常是用户的项目目录，直接执行相对路径会失败。执行前先确定 skill 目录，使用绝对路径或先 `cd` 到 skill 目录，例如：\n\n```bash\nnode /path/to/shareone-skill/scripts/ensure_credentials.js\n```\n\n## 入口隔离规则\n\n本 skill 和用户本机可能安装的 `shareone` CLI 是两个独立入口。除非用户明确要求”使用 CLI”或指定执行 `shareone ...` 命令，否则不要调用系统 PATH 中的 `shareone` 命令。即使 `which shareone` 能找到 CLI，也不要把自然语言的发布、下载、评论处理任务改走 CLI。所有 ShareOne 操作都必须调用本 skill 目录内 `scripts/` 下的脚本。\n\n## 使用说明与触发条件\n\n当用户表达出以下意图时，应主动使用此技能：\n\n- \"帮我把 `index.html` 发布到 ShareOne\"\n- \"把我刚才生成的网页发布，给我个链接\"\n- \"生成一个可分享的链接给我的团队看\"\n- \"Upload this presentation to ShareOne and protect it with password 'secret'\"\n- \"发布这个 PDF 到 ShareOne，并加上密码 1234\"\n- \"把这个网页发布到 ShareOne，加上水印 '内部绝密'\"\n- \"把这个网页发布到 ShareOne，链接叫 product-demo\"\n- \"发布这份设计稿并开启协同评论模式\"\n- \"用 shareone 分享上一轮对话\"\n- \"把我刚才写的代码/大段文字分享出去\"\n- \"Share your last response as a note\"\n- \"帮我下载这个 ShareOne 链接的文件：https://s.shareone.vip/s/xxx\"\n- \"拉取一下这个链接的评论：https://s.shareone.vip/s/xxx\"\n- \"删掉/删除这个 ShareOne 链接：https://s.shareone.vip/s/xxx\"\n- \"我 push 了，刷新一下这个 ShareOne 远程链接的内容：https://s.shareone.vip/s/xxx\"\n- \"给这个 ShareOne 链接加水印：https://s.shareone.vip/s/xxx\"\n- \"根据这个链接的评论修改页面：https://s.shareone.vip/s/xxx\"\n- \"修改这个 ShareOne 链接的内容：https://s.shareone.vip/s/xxx\"\n- \"把这个 GitHub 文件发布到 ShareOne：https://github.com/org/repo/blob/main/report.html\"\n- \"用远程 URL 发布这个页面\"\n- \"Publish this GitHub raw URL to ShareOne\"\n\n## 路由判定顺序（唯一路由依据）\n\n入口文件只负责判断用户意图、选择需要阅读的 workflow。不要一次性读取所有 `workflows/*.md`；只读取当前任务命中的子文件。\n\n按以下顺序从上到下判断，**命中第一条即停止**，按该条给出的阅读顺序执行：\n\n1. **删除/清除/移除/重置 ShareOne API Key**\n   → 读 `workflows/delete-api-key.md`。无需凭据检查。\n\n2. **删除/移除 ShareOne 分享链接本身（用户明确要求“删掉/删除/移除”某个 share_id、slug 或链接）**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/delete-share.md`。删除是 owner-only 操作，执行前须与用户确认（软删除后公开链接立即失效）。对 HTML/文本页和二进制文件链接（`/pdf/`、`/ppt/`、`/word/`）通用。注意与第 6 条区分：本条是删除整个 share，不是改设置。\n\n3. **刷新 remote-url auto-follow 分享的源内容（用户说“我 push 了”“拉一下最新源”“刷新这个远程链接”）**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/refresh-remote.md`。remote 页面刷新是懒的、只在打开渲染页时触发，下载/`/file` 只服务缓存；本条用 `refresh_share.js` 显式强制 refetch。仅对绑定了远程 URL 的分享有效；非 remote-bound 返回 `NOT_REMOTE_BOUND`，此时应改走第 6 或第 10 条（改设置 / 重新发布内容）。\n\n4. **绑定账号、注册、升级 guest、绑定邮箱**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/bind-account.md`。\n\n5. **让别人一起编辑、分享编辑权限、添加/移除/查看协作者、对方怎么拿 API Key**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/manage-collaborators.md`，最后读 `workflows/result-and-errors.md`。\n\n6. **用户提供已有 ShareOne 链接、`share_id` 或 slug，且只要求修改水印、访问密码、自定义短链接、评论开关或数据存储开关（不改内容本身）**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/update-share-settings.md`，最后读 `workflows/result-and-errors.md`。\n   这是元数据更新：不要按文件类型路由，不要下载源文件，不要使用 `publish.js`，不要重新上传内容。对二进制文件链接（`/pdf/`、`/ppt/`、`/word/`）同样适用本条。\n\n7. **下载 ShareOne 链接的文件或取回源内容**\n   → 读 `workflows/download-file.md`。下载脚本会在已有凭据时优先尝试 owner 下载，没有凭据时自动走公开下载；不要为了普通下载强制配置 API Key。\n\n8. **只查看、拉取、总结 ShareOne 链接评论（用户没有要求修改）**\n   → 读 `workflows/comments-view.md`。查看评论用 `comment_list.js`，走公开接口，无需凭据检查。\n\n9. **处理评论、根据评论修改页面、修复 ShareOne 链接内容**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/comments-process.md`（其中的重新发布步骤会引用 `workflows/publish-text-page.md`），最后读 `workflows/result-and-errors.md`。\n\n10. **发布、分享、生成链接、上线（创建新链接或更新已有链接的内容）**\n   → 先读 `workflows/environment-and-credentials.md`，再按目标文件类型二选一，最后读 `workflows/result-and-errors.md`：\n   - `.ppt`、`.pptx`、`.pdf`、`.doc`、`.docx` → `workflows/publish-binary-file.md`\n   - `.html`、`.md`、`.txt`、对话内容、大段文本、代码块、已包装成 HTML 的内容 → `workflows/publish-text-page.md`。注意：`.md`/`.txt` 一律按原格式发布，不要因为内容包含图表就转成 HTML；只有目标本来就是 HTML 页面时才参考其中的 Mermaid.js 章节。\n\n所有需要 ShareOne API 的操作（上面第 2、3、4、5、6、7、9、10 条），都先运行 `node scripts/ensure_credentials.js`，输出 token 含义与处理流程见 `workflows/environment-and-credentials.md`，这里不重复。\n\n## ShareOne 链接与 share_id\n\n- 用户提供的目标可以是完整链接、`/s/<ref>` 等路径、裸 `share_id`（16 位字符串）或自定义短链 slug。服务端接口同时接受 `share_id` 和 slug，无需自行区分两者。\n- `/s/<share_id>` 是最终给用户访问的分享链接，**不是上传 API endpoint**。不要把 `/s/<share_id>` 当作发布地址，也不要直接向 `/s/<share_id>` PUT/POST 文件。\n- 路径前缀与内容类型的对应关系：`/s/`、`/md/` 是文本/HTML/Markdown 页面；`/pdf/`、`/ppt/`、`/word/` 是二进制文件。元数据更新时 `update_share_settings.js` 会按此前缀自动选择 endpoint，裸 `share_id` 或 slug 由脚本先试页面 endpoint、必要时回退文件 endpoint，整个过程不下载源文件。\n- 文本页里 `/s/<ref>` 与 `/md/<ref>` **等价**：前缀不绑定、也不校验内容类型，浏览路由一律按 ref 解析 share、按 share 真实 content-type 渲染。因此文本页可以就地把 content-type 从 md 升级成 html（`.md → .html`，如把 ASCII 图升级成 Mermaid），URL（含老的 `/md/<slug>`）一字不变、评论保留——见 `workflows/publish-text-page.md` §6b。升级用 `--share-id` 更新，**绝不 `--force-new`**。\n- 内容发布与更新统一使用 `publish.js`，脚本会按文件类型自动分发到文本通道或二进制直传通道（stderr 输出 `INFO:CHANNEL:text|binary`），不需要也不应该自行选择底层上传脚本。不要因为会话里存在旧的 `/s/<share_id>` 就把二进制文件改走文本页面 PUT；二进制文件传 `--share-id` 会被脚本拒绝（`ERROR:BINARY_NO_SHARE_ID`）。\n- 如果当前会话中已经为同一个文本/HTML 文件生成过 ShareOne 链接，可复用之前的 `share_id` 执行文本页面 PUT 更新；否则执行首次创建。\n- 非 owner 下载要求链接已开启允许下载；若脚本输出 `ERROR:DOWNLOAD_NOT_ALLOWED`，直接提示用户让链接 owner 先开启允许下载。\n\n## 发布前安全自检（非阻塞）\n\n- 创建新分享链接（首次 POST 新页面或首次上传新文件）前，Agent 必须自行做内容安全自检：不得发布明显反动、涉政、暴力、色情、侵权或恶意代码内容。\n- 链接保留规则：普通链接在**最后活跃时间**超过 90 天后会被清理（最后活跃 = 创建时间或最后一次被访问时间的较晚者，持续有效访问会一直保持有效，不是发布后 90 天硬删除）；发布到 Explore 公开广场、被知识库引用、或设了 `remote_url` 的内容不参与此无活跃自动清理。\n- 自检通过后直接继续发布，不要向用户展示安全提示，也不要等待用户回复“同意”或 `agree`。\n- 自检必须轻量：对文本/HTML/Markdown/TXT，只基于当前已知内容或发布所需读取的文本内容判断；对 PDF/PPT/Word 等二进制文件，只基于用户请求、文件名、扩展名和显式参数判断，不要为了自检提取正文、OCR、转换格式或解析文件内部内容。\n- 如果内容明显违反上述规则，停止发布并简要说明原因。\n- 对已有链接执行后续操作时——包括内容 PUT 更新、评论处理闭环中的重新发布、水印/密码/短链/评论开关等元数据修改——按对应 workflow 直接执行。\n- 下载、查看评论、删除 API Key 等不发布内容的操作无需安全自检。\n\n## 不可跳过的阻塞步骤\n\n以下步骤是阻塞性用户通知，不是可选说明。触发后必须先发给用户，再继续后续操作。\n\n- 如果 `ensure_credentials.js --create-guest` 或底层 `create_guest_key.js` 输出 `GUEST_KEY_CREATED:<api_key>`，必须立即向用户发送临时 API Key、绑定账号链接和保存提醒（话术见 `workflows/environment-and-credentials.md`）。即使 key 已经自动保存，也不能省略该通知；发送前不得继续执行原任务的上传、下载、评论处理命令。\n- 本会话首次向用户展示生成的 `share_url` 时，必须按 `workflows/result-and-errors.md` 提示所有未使用的高级功能：自定义短链接名称、访问密码、水印。已使用的能力不再提示；三项都已使用则不提示。\n\n## 全局约束\n\n- 发布前必须完成凭据检查和必要的凭据配置。\n- 发布成功后必须直接使用脚本返回的 `share_url`，不要自行拼接分享链接；不要展示备用链接。\n- 只有当用户明确要求开启评论、允许讨论或协同模式时，才添加 `--allow-comments true`。默认不开启评论。\n- 只有当用户明确要求页面持久化数据（如保存游戏分数、表单状态）时，才添加 `--allow-data true`。默认不开启数据存储。\n- 页面持久化数据时，页面代码用自动注入的 `window.__SHAREONE__` SDK，**必须按敏感度二选一、无默认**：`putShared(key, value|File)` 存服务器·所有访客可读·跨设备（大文件自动走 blob，≤8MB）；`putPrivate(key, value|File)` 只存这台设备·私有·不上传。命名即风险（Shared=别人能看），敏感/隐私数据一律 `putPrivate`。现成的“公开 vs 敏感”拖拽上传参考页：`templates/page-storage-dropzone.html`；私有数据可留在本机就地推理（模型公开＋数据 `putPrivate`＋页面内计算，字节不出设备）的参考页：`templates/client-side-inference.html`；完整 SDK 见后端 `agent.md` §14。发布时若带 `--allow-data true`，命令行会在成功后打印一行 `HINT:PAGE_DATA_ENABLED` 提示该二选一与本地推理用法。\n- 自定义短链接（slug）：服务端会根据文件名自动生成可读的 slug（如 `quarterly-report`），客户端无需额外操作。只有用户明确要求“链接叫 xxx”、“自定义短链接 xxx”、“URL 后缀 xxx”时，才在发布命令添加 `--slug xxx` 覆盖自动生成；slug 冲突时把服务端提示反馈给用户，不要静默改名。\n- 页面需要二维码时用 `node scripts/make_qr.js --text \"<内容>\" --format path`（零依赖，直出 SVG path，贴进页面的 `<path d=\"...\">`；`--format svg` 给完整 `<svg>`，`--ecc L|M|Q|H` 默认 Q）。**不要**引入外部二维码库或 `<img src=\"https://...qrserver...\">` 之类的在线生成服务——发布出去的页面在别人的浏览器里打开，外链会失效、泄露访问者，也印不进 PDF。二维码指向本次发布的链接时，先用 `--slug` 定好链接再生成二维码，顺序反了码会指向不存在的页面。\n- 名片/电子名片：用 `templates/business-card.html`（双面设计，一份 HTML 同时产出可发的图片、可扫的链接、90×54mm 印刷 PDF）。改 `data-field=\"...\"` 的文字即可，vCard 和 tel:/mailto: 由页面脚本从卡面读取，不要另写一份联系方式。二维码指向名片页本身而不是公司官网：扫码的人当场要的是把人存进通讯录，名片页能一键存 vCard，且印出去的卡改不了、名片页能随时更新。\n- 开启评论的页面**不要用 MutationObserver 监听自己的输出来触发重绘**。ShareOne 会往页面里注入评论桥（样式、覆盖层、高亮包裹），这本身就是 DOM 变化；页面若据此重绘、重绘又改 DOM，会自持成无限循环，页面直接跑飞（实测：关评论 render 1 次，开评论 502 次）。确实需要按变化重绘时，用内容签名门控：先算出这一帧该画什么，和上一帧比，一样就不画。同理，**不要在 `pointerdown` 里无条件 `setPointerCapture`** —— 指针被容器捕获后，`click` 会派发给捕获者而不是被点的元素，页面里所有节点都点不动，而元素还在、`elementFromPoint` 也正常，很难查；平移交互应等 `pointermove` 超过 3–5px 再捕获。\n- 开启评论、而**可评论的东西不是 DOM 元素**时（canvas 图、地图、3D 视图、虚拟滚动大表格——一千个节点就一个 `<canvas>`），用 `window.__SHAREONE__.anchors`：页面自己声明什么可评论、以及它现在在哪，ShareOne 不解析。不用它的话，所有评论都会锚到那一个 `<canvas>` 上、标签一律 `\"canvas\"`、而且因为那个元素永远解析得到，\"锚点丢失\"一次都不会提示——看起来成功而实际全错。最小用法：`anchors.select({id, label}, rect)` 报告用户选中了什么；`anchors.report([{id, state:\"visible\", rect} | {id, state:\"hidden\"} | {id, state:\"missing\"}])` 在自己布局变化时推位置；`anchors.on(\"resync\"|\"reveal\"|\"hittest\", fn)` 应答 ShareOne 的询问。`hidden`（当前视图没画，读者可换视图）和 `missing`（内容真没了）**必须分开**，合并等于让页面替 ShareOne 宣称内容被删了。锚点是**一组 id 不是矩形**（矩形重排后指向另一批东西，而且永远\"解析得到\"）。现成参考页：`templates/canvas-comments.html`（一个 canvas 图，点节点评论、框选一片评论、收起明细时评论显示为\"不在当前视图\"、点评论卡片会让页面自己展开回来）——照着改节点和绘制即可，别动那几处带注释的契约代码。完整接口与全部约束见后端 `agent.md` §14b。\n- 开启评论且页面会自己重绘（图表、流程图、看板、任何切换视图就重建 DOM 的页面）时，给每个可评论元素加一个稳定的 `data-*` id，例如 `<g class=\"node\" data-node-id=\"委外cap\">`。ShareOne 的区域评论以应用自己给的这个 id 作锚，重绘后评论自动跟回同一个元素；没有 id 时只能退回\"第几个同名标签\"的结构路径，而重绘必然让它失效，评论会变成\"锚点丢失\"。id 在同一页内必须唯一（命中多个元素的 id 会被拒绝，宁可报丢失也不锚错元素），且在重绘前后保持不变——用业务含义命名，别用渲染顺序生成。\n- 评论处理必须形成闭环：认领、修改、重新发布，然后用 `comment_reply.js --state`（`--state` 必填）**明确表态**——`resolved-agree`（同意收敛）/ `open-disagree`（有异议但保持 open）/ `open-need-input`（需人类澄清）。AI **永不**单方面 dismiss 一条分歧：不同意用 `open-disagree`，`dismiss` 仅用于真正无关/无法处理的评论。\n\n## 最终回复前检查清单\n\n在回复用户前，逐项检查：\n\n- 如果本轮创建了临时 API Key，是否已经把 API Key、绑定账号链接和保存提醒发给用户。\n- 如果本轮**创建了新分享链接**，是否已完成发布前安全自检；如果内容明显违规，是否已停止发布。\n- 如果发布成功，是否直接展示返回的 `share_url`，没有自行拼接链接。\n- 如果返回中包含 `custom_slug_warning` 或 `custom_slug_suggestions`，是否展示给用户。\n- 如果这是本会话首次展示生成的 `share_url`，是否提示所有未使用的高级功能。\n\nFile v1.3.6:README.md\n\n# ShareOne Skill：AI Agent 发布与文档分享工具\n\n<p align=\"center\">\n  <strong>把 AI 生成的网页、Markdown、PDF、Word 和 PowerPoint 文档发布为 ShareOne 短链接。</strong>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://shareone.vip\"><img alt=\"Website\" src=\"https://img.shields.io/badge/website-shareone.vip-0f766e\"></a>\n  <img alt=\"ShareOne\" src=\"https://img.shields.io/badge/ShareOne-skill-2563eb\">\n  <img alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-64748b\">\n</p>\n\n官网：https://shareone.vip\n\n\n\n本仓库包含 ShareOne Agent Skill。它让 Codex、Claude Code、OpenAI Agent、Dify、工作流自动化工具等 AI Agent 可以把本地生成的内容快速发布到 ShareOne，并生成可访问、可转发、可更新的公网分享链接。\n\nShareOne 适合用于发布 AI 生成页面、分享 Markdown 在线文档、托管 HTML 演示页、上传 PDF/Word/PPT 文件、生成团队评审链接，以及为文档添加访问密码、水印和评论协作能力。\n\n## 关键词\n\nShareOne 覆盖以下搜索场景：AI Agent 发布工具、HTML 页面托管、Markdown 在线分享、PDF 短链接分享、Word 文档分享、PPT 在线分享、文档水印、访问密码分享链接、AI 生成网页发布、Codex Skill 文档发布、Agent workflow publishing。\n\n## ShareOne 是什么\n\nShareOne 是一个面向 AI Agent 和开发者的轻量级内容发布服务。它可以把 HTML、Markdown、TXT、PDF、Word、PowerPoint 等文件发布为短链接，方便用户在聊天、项目协作、客户沟通、产品演示和内容交付场景中快速分享。\n\n通过 ShareOne Skill，AI Agent 不需要让用户手动上传文件，也不需要额外搭建静态站点。Agent 可以直接调用 Skill 脚本完成发布、更新、下载、评论读取和设置修改。\n\n## 免费托管\n\nShareOne 提供免费的页面与文档托管能力，适合临时演示、项目评审、AI 生成内容分享、客户预览和团队协作。\n\n普通分享链接会按最后活跃时间保留：只要链接持续有有效访问，就会继续保持可用；当距离最后一次有效访问超过 90 天后，链接才可能被自动清理。也就是说，链接不是从发布时间开始固定 90 天过期，而是每次有效访问都会延续它的活跃状态。\n\n发布到 Explore 公开广场、被知识库引用，或绑定了远程 URL 的内容，不参与普通链接的无活跃自动清理。\n\n## 能力地图\n\n| 文件类型 | 分享链接生成 | 密码访问 | 水印 | 自定义短链接 | 评论反馈 | 更新同一链接 |\n| --- | --- | --- | --- | --- | --- | --- |\n| TXT | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| Markdown | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| HTML | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| PDF | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n| Word | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n| PowerPoint | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n\n## 核心能力\n\n- **HTML 页面发布**：将 AI 生成的网页、报告、原型页面或数据看板发布为在线链接。\n- **Markdown 在线分享**：直接发布 `.md` 或 `.txt` 内容，适合笔记、方案、会议纪要和技术文档。\n- **文档文件分享**：支持 PDF、Word、PowerPoint 文件上传与分享。\n- **短链接访问**：生成 ShareOne 公网短链接，便于在微信、邮件、飞书、Slack、Notion、GitHub Issue 等渠道传播。\n- **访问密码**：为敏感文档或内部材料设置访问密码。\n- **水印保护**：给页面或文档增加水印，降低外泄和二次传播风险。\n- **原链接更新**：在保留同一个分享链接的情况下更新内容，适合反复修改的方案、演示稿和评审页面。\n- **评论协作**：文本页面可开启评论，方便团队直接围绕页面内容反馈和修改。\n- **文件下载控制**：支持下载公开文件，也能在权限允许时取回源内容。\n\n## 适用场景\n\n- AI Agent 生成一个 HTML 页面后，需要立即发布给用户预览。\n- 把 Markdown 报告、技术方案、产品说明发布成可分享链接。\n- 将 PDF、Word、PPT 文件分享给客户、同事或外部协作者。\n- 给内部资料添加访问密码或水印。\n- 把已有 ShareOne 链接内容更新为最新版本。\n- 根据 ShareOne 页面评论修改内容，并重新发布到原链接。\n- 把 GitHub 上的远程 HTML 或文档 URL 发布为 ShareOne 链接。\n\n## Agent 使用方式\n\nAgent 在识别到“发布到 ShareOne”“生成分享链接”“分享这个 PDF”“更新这个 ShareOne 链接”“拉取评论”等意图时，会读取 [SKILL.md](./SKILL.md) 中的完整工作流，并调用本 Skill 的 `scripts/` 脚本完成操作。\n\n常见自然语言指令：\n\n```txt\n把 index.html 发布到 ShareOne，给我一个链接\n把这份 PDF 上传到 ShareOne，并设置访问密码 1234\n把刚才生成的 Markdown 报告分享出去\n更新这个 ShareOne 链接的内容：https://s.shareone.vip/s/xxx\n读取这个 ShareOne 页面上的评论并处理\n给这个链接加上水印“内部资料”\n```\n\n## 链接与文档\n\n- ShareOne 官网：https://shareone.vip\n- Skill 完整说明：[SKILL.md](./SKILL.md)\n\nFile v1.3.6:_meta.json\n\n{\n  \"ownerId\": \"kn73tjvxf6qkw5beygj5y939n988wsag\",\n  \"slug\": \"shareone\",\n  \"version\": \"1.3.6\",\n  \"publishedAt\": 1790661290878\n}\n\nFile v1.3.6:skill-card.md\n\n## Description:\n\nPublishes HTML and Markdown pages and shares PDF, Word, and PowerPoint documents through ShareOne links, with options for access controls, comments, and updates.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[beep879](https://clawhub.ai/user/beep879)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nDevelopers and other agent users can publish pages and documents as shareable links, manage access settings, and handle feedback on supported pages.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Authenticated requests may be redirected to untrusted destinations.\n\nMitigation: Use links from known ShareOne domains and avoid settings or collaborator actions on arbitrary URLs.\n\nRisk: An API key can grant owner-level access to published content and settings.\n\nMitigation: Install only if you trust the publisher; prefer limited or revocable ShareOne API keys.\n\nRisk: Destructive delete actions lack enforced confirmation.\n\nMitigation: Manually confirm each delete request before allowing the agent to proceed.\n\n## Reference(s):\n\n- [ShareOne website](https://shareone.vip)\n- [ShareOne ClawHub release](https://clawhub.ai/beep879/skills/shareone)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Shell commands, Guidance]\n\n**Output Format:** [Text or Markdown with share links and operation results]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May include a public share URL, access settings, and status or error details.]\n\n## Skill Version(s):\n\n1.3.6 (source: skill frontmatter and ClawHub release)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.3.6:workflows/bind-account.md\n\n# 绑定账号（Guest → 注册用户升级）\n\n当用户表达\"绑定账号\"、\"注册\"、\"升级 guest\"、\"绑定邮箱\"等意图时读取本文件。执行前必须已经完成 `environment-and-credentials.md`（确保有可用的 API Key）。\n\n## 核心概念\n\n- Guest 用户通过 `POST /api/v1/agent-guest-key` 获取的临时 API Key，绑定邮箱后升级为注册用户\n- **API Key 不变**：绑定只是在同一个 user record 上添加 email，`user.id` 和 `api_key` 都保持不变\n- 绑定后用户可以用邮箱登录 ShareOne 网站 dashboard 管理文件\n- 整个流程由 agent 代劳，用户不需要打开浏览器\n\n## 流程\n\n### 1. 获取用户邮箱\n\n如果用户还没有提供邮箱，询问：\n\n> 请提供您的邮箱地址，我来帮您绑定账号。绑定后您的 API Key 不变，还可以用邮箱登录 ShareOne 网站管理文件。\n\n### 2. 发送验证码\n\n```bash\nnode scripts/bind_account.js --send --email <用户邮箱>\n```\n\n按输出 token 处理：\n\n- `CODE_SENT`：通知用户查看邮箱：\n  > 验证码已发送到 `<邮箱>`，请查看邮箱（含垃圾箱），告诉我 6 位数字验证码。\n- `ERROR:EMAIL_ALREADY_LINKED`：该邮箱已被其他账号使用。告知用户并建议使用其他邮箱，或直接用该邮箱登录网站。\n- `ERROR:COOLDOWN`：发送冷却中，请等待 30 秒后重试。\n- `ERROR:RATE_LIMIT`：频率限制，稍后再试。\n- `ERROR:KEY_NOT_FOUND`：API Key 不存在，需要先通过 `ensure_credentials.js` 获取凭据。\n\n### 3. 等待用户回复验证码\n\n暂停操作，等待用户告知 6 位验证码。\n\n### 4. 验证并绑定\n\n```bash\nnode scripts/bind_account.js --verify --email <用户邮箱> --code <验证码>\n```\n\n按输出 token 处理：\n\n- `BIND_SUCCESS`：绑定成功。向用户确认：\n  > 账号绑定成功！您的邮箱 `<邮箱>` 已与当前 API Key 关联。API Key 不变，您现在可以用这个邮箱登录 ShareOne 网站管理分享的文件。\n- `ERROR:INVALID_CODE`：验证码错误，请用户检查后重新输入。不需要重新发送验证码。\n- `ERROR:CODE_EXPIRED`：验证码已过期（5 分钟有效），需要重新发送。回到第 2 步。\n- `ERROR:TOO_MANY_ATTEMPTS`：验证码尝试次数过多（最多 5 次），需要重新发送。回到第 2 步。\n- `ERROR:EMAIL_ALREADY_LINKED`：邮箱已被其他账号使用。建议使用其他邮箱。\n- `ERROR:KEY_NOT_FOUND`：API Key 无效或 guest 账号不存在。\n\n## 不要做的事\n\n- 不要让用户打开浏览器去网站绑定——整个流程在对话中完成。\n- 不要在绑定后生成新的 API Key——绑定不改变 key。\n- 不要在用户没有明确要求时主动发起绑定流程（但在首次创建 guest key 后可以简短提示）。\n\nFile v1.3.6:workflows/comments-process.md\n\n# 处理 ShareOne 评论\n\n当用户明确要求“处理这些评论”、“根据评论改一下页面”、“修改这个 ShareOne 链接的内容”时读取本文件。只查看评论时不要读取本文件。\n\nShareOne 页面评论包含状态机字段 `status`：`open` / `in_progress` / `resolved` / `dismissed`，以及作者字段 `author_role`：`visitor` / `owner` / `agent`。\n\n处理评论需要 owner 的 API Key（认领状态、发 agent 回复都要求 owner 鉴权），执行前必须已经完成 `environment-and-credentials.md`。\n\n## 1. 获取 ref 与评论\n\n用户提供的目标可以是完整链接、`/s/<ref>` 或 `/md/<ref>` 路径、裸 `share_id` 或自定义短链 slug。取路径最后一段作为 `<REF>` 即可，接口同时接受 `share_id` 和 slug。\n\n本 workflow 只适用于可编辑的文本/HTML/Markdown 页面评论处理。若目标链接路径明确是 `/pdf/`、`/ppt/`、`/word/`，或下载后的 `INFO:CONTENT_TYPE`/文件扩展名显示为 PDF/PPT/Word 等二进制文档，不要为处理评论解析、转换或修改二进制正文；停止内容修改流程，并告知用户当前 skill 只支持处理页面源码评论，二进制文档只能查看/总结评论或更新元数据设置。\n\n任务锚点：步骤 2 的下载命令（`--task-anchor`）会自动把 `<REF>` 写入当前目录的 `.shareone_active_task` 文件，把目标 share 固定到磁盘上（防止长时间编辑文件后上下文丢失，误把更新发成新链接）。后续所有步骤中的 `<REF>` 都以该文件内容为准；任何时候不确定目标 share 是哪个，读取该文件，**不要凭记忆，更不要新建链接**。\n\n先获取未处理评论：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments?status=unresolved\"\n```\n\n评论数据中可能包含 `replies`。必须将父评论及其所有回复作为一个 thread 整体阅读，综合理解最终共识。回复不需要单独走流程，只对父评论操作状态。\n\n## 2. 标准闭环流程\n\n对每条要处理的父评论，严格按以下顺序执行。\n\n### 步骤 1：认领\n\n必须在动手之前做：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/<COMMENT_ID>/status\" \\\n  --method PUT \\\n  --data '{\"status\": \"in_progress\"}'\n```\n\n访问者会立刻在页面侧栏看到“处理中”徽标和顶部“AI 正在处理 N 条评论...”横幅。跳过这一步会让用户感受不到 AI 在干活。\n\n### 步骤 2：取源（自动写锚点）\n\n```bash\nnode scripts/download_share.js \"<REF>\" --task-anchor\n```\n\n`--task-anchor` 会自动完成三件事：写入 `.shareone_active_task` 锚点（stderr 输出 `ANCHOR_WRITTEN:`）、按服务端文件名的扩展名把源内容保存为 `shareone_<REF>_source.<ext>`（stdout 输出 `SAVED:<本地文件名>`）、在 stderr 输出 `INFO:FILENAME:`（原始文件名，步骤 4 要用）和 `INFO:CONTENT_TYPE:`。后续编辑就改 `SAVED:` 给出的这个本地文件——文件名本身携带目标 share，即使对话上下文丢失也能从文件名恢复 `<REF>`。已配置 owner API Key 时脚本自动走 owner 下载接口，不受密码和下载开关限制。\n\n### 步骤 3：精准应用修改\n\n- 综合理解整个 thread（父评论 + 所有 replies）的最终意图，必要时先和用户确认。\n- 绝对不要用全局 `replace()` 或正则批量替换，会误伤其他同名文案。\n- 基于 DOM 结构精确定位：利用 `highlighter_data.startMeta.parentTagName`、`parentIndex`、`textOffset`，结合 `quote`（被选中原文）定位准确节点。\n- 理解结构性意图：评论可能是“把这部分挪到底部 / 删掉这个区块 / 加个图标”，先定位再做结构变更。\n- 如果在当前源文件里无论如何都找不到对应位置，不要瞎改，直接走 dismissed 流程，并用 note 告诉用户：“源文件结构已变更，无法定位你这条关于 XXX 的评论”。\n\n### 步骤 4：重新发布（必须 PUT 更新，禁止新建链接）\n\n脚本选择说明：更新**内容**只能用 `publish.js --share-id`（带 `--share-id` 时执行的是 PUT 内容更新，不是创建）；`update_share_settings.js` 只能改密码/水印/短链/评论开关等元数据，**无法替换页面内容**，本步骤不要使用它。\n\n直接执行以下命令更新原链接。`<REF>` 与步骤 1、2、5 是同一个值，即 `.shareone_active_task` 文件的内容：\n\n```bash\nnode scripts/publish.js \"<步骤 2 SAVED: 给出的本地文件>\" --filename \"<INFO:FILENAME 给出的原文件名>\" --share-id <REF>\n```\n\n硬规则：\n\n- 评论处理流程中**禁止**不带 `--share-id` 执行发布命令——那会 POST 创建一个全新链接，原链接和上面已认领的评论都不会得到任何更新。\n- 不要跳读 `publish-text-page.md` 的“判断创建还是更新”一节，评论场景永远是更新，没有“首次创建”分支。\n- 如果此刻想不起 `share_id`，读取 `.shareone_active_task` 文件或源文件名中的 `shareone_<REF>_` 前缀，绝不新建。\n- 如果脚本输出 `ERROR:ACTIVE_SHARE_TASK`，说明漏传了 `--share-id`，按错误提示补上后重试。\n\n评论闭环中的重新发布属于对已有链接的更新，**不需要**向用户展示发布前安全提示或等待确认（规则见入口 `SKILL.md`）。\n\n### 步骤 5：回复评论并**强制表态**（一条命令，`--state` 必填）\n\n每次回复评论都**必须**用 `comment_reply.js` 并声明一个 `--state`——这是硬性要求（缺省即报错），目的是杜绝“只回复不收敛 / 有分歧却没 signal 出来 / 不确定却没保持 open”这三种失败模式：\n\n```bash\n# 同意并已按建议修改 → 评论收敛为 resolved\nnode scripts/comment_reply.js \"<REF>\" <COMMENT_ID> --content \"已按你的建议把标题改成 ...，并调整了 ...\" --state resolved-agree\n```\n\n`--state` 三选一（无默认）：\n\n| state | 含义 | 对父评论的作用 |\n|---|---|---|\n| `resolved-agree` | 充分理解且同意，已处理 | 置 `resolved` |\n| `open-disagree` | 不同意（在 `--content` 里写清理由） | **保持 `open`**，标记“AI 有异议”，把是否关闭交回给提出者 |\n| `open-need-input` | 需要人类进一步澄清/输入 | 保持 `open` |\n\n脚本会自动从父评论继承 `quote`/`highlighter_data`、以 `author_role=agent` 发一条回复（输出 `REPLY_POSTED:<id>` 和 `COMMENT_STATE:<state>`），后端据 `--state` 原子地设置父评论状态与 AI 立场。不要手工拼接含 `highlighter_data` 的 JSON。\n\n**关键原则：AI 永不单方面关闭一条分歧。** 不同意时用 `open-disagree`（保持 open、让提出者决定），**绝不**用 dismiss 把别人的评论关掉——关闭/重开一条评论的权力属于提出评论的人（以及页面 owner）。\n\n- 输出 `ERROR:STATE_REQUIRED` / `ERROR:INVALID_STATE`：必须补上合法的 `--state`。\n- 输出 `ERROR:IS_REPLY:<parent_id>`：传入的是回复 ID，改用父评论 ID 重试。\n- 输出 `ERROR:AUTH_FAILED`（403）：先查该链接评论是否被关闭（`allow_comments=false`），可经 `update-share-settings.md` 重新开启后重试。\n\n如果误发了一条回复，可以删除（仅作者本人、且父评论仍为 `open` 时可删，会级联删除其回复）：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<SHARE_ID>/comments/<COMMENT_ID>\" --method DELETE\n```\n\n## 3. 无法处理或与页面无关的评论\n\n**注意区分“不同意”与“无关”**：对你有异议但属于合理讨论的评论，用步骤 5 的 `--state open-disagree`（保持 open），**不要** dismiss。`dismiss` 只用于**真正无关/无法处理**的评论（例如指向了另一份分享、垃圾评论）——这是 owner 的否决动作：\n\n```bash\nnode scripts/comment_resolve.js \"<REF>\" <COMMENT_ID> --dismiss --note \"页面中没有此元素，可能指的是另一份分享\"\n```\n\n输出 `COMMENT_DISMISSED:<id>` 即完成。（`comment_resolve.js` 为兼容保留；日常回复请优先用 `comment_reply.js --state`。）\n\n## 4. 收尾：删除任务锚点\n\n所有目标评论都已 `resolved` 或 `dismissed`、且重新发布完成后，删除任务锚点文件：\n\n```bash\nrm -f .shareone_active_task\n```\n\n不删除的话，之后正常的新页面发布会被发布脚本拦截（`ERROR:ACTIVE_SHARE_TASK`）。\n\n## 5. 兼容旧接口\n\n旧接口仍然可用，但新代码不要使用：\n\n```http\nPUT /api/v1/shares/<REF>/comments/<COMMENT_ID>/resolve\n{ \"resolved\": true/false }\n```\n\n它等价于把 `status` 切到 `resolved` 或 `open`，但不会附带 `note`，访问者拿不到 AI 的解释。新代码一律使用 `/status` 接口。\n\n## 6. 关键准则速查\n\n| 准则 | 为什么 |\n| --- | --- |\n| 动手前先 `in_progress` | 让访问者看到“AI 在干活” |\n| 改完一定要 `POST` 一条 `author_role=agent` 的回复 | 闭环的“答复”部分，没有它就只是状态变化、不是对话 |\n| `note` 要写人话 | “已把按钮改成主色” 比 “Applied.” 有用 |\n| 不能处理就 `dismissed` + note | 不要让评论永远卡在 `open` |\n| 只对父评论改状态，回复不单独操作 | 状态语义属于 thread 整体 |\n| `unresolved` = `open + in_progress` | 拉单子默认用 `?status=unresolved` |\n\nFile v1.3.6:workflows/comments-view.md\n\n# 查看 ShareOne 评论\n\n当用户只是要求查看、拉取、总结评论时读取本文件。不要修改源文件，不要认领评论，不要关闭评论。\n\n查看评论走公开接口，**不需要 API Key**（`comment_list.js` 本身即公开读取；若改用 `shareone_api_request.js` 直连则加 `--public`）；只有进入处理评论流程（`comments-process.md`）时才需要凭据。\n\n## 1. 获取 ref\n\n用户提供的目标可以是完整链接、`/s/<ref>` 或 `/md/<ref>` 路径、裸 `share_id` 或自定义短链 slug。取路径最后一段作为 `<REF>` 即可，接口同时接受 `share_id` 和 slug。\n\n## 2. 查看评论\n\n优先用 `comment_list.js`——它输出干净的 UTF-8 JSON（`{ share, status, count, comments:[{ id, status, author_role, quote, content, created_at, resolution_note, reply_count, replies:[...] }] }`），省去手工拼接 endpoint 和解析原始响应，也规避控制台非 ASCII 乱码：\n\n```bash\nnode scripts/comment_list.js <REF>                 # 默认 --status all\nnode scripts/comment_list.js <REF> --status open   # 只看未处理\nnode scripts/comment_list.js <REF> --json compact  # 单行 JSON，便于管道解析\n```\n\n`--status` 可选值：\n\n- `all`（默认）\n- `open`\n- `in_progress`\n- `resolved`\n- `dismissed`\n- `unresolved`，等价于 `open + in_progress`\n\n查看评论无需凭据（公开接口）。只有进入处理评论流程（`comments-process.md`）时才需要 API Key。\n\n## 3. 评论理解规则\n\n- 只展示评论内容，绝对不要自作主张开始修改源文件。\n- 等用户明确要求“处理这些评论”、“根据评论改一下页面”等，再进入 `comments-process.md`。\n- 评论数据中可能包含 `replies`。必须将父评论及其所有回复作为一个 thread 整体阅读，综合理解最终共识。\n- 不要把每条回复当成独立修改指令。\n- 所有回复继承父评论的锚点，也就是 `highlighter_data` 和 `quote`。\n\n## 4. 轻量摘要\n\n如果只想看“现在还有没有未处理的事”，用摘要接口：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/summary\" --public\n# -> { total, open, in_progress, resolved, dismissed, last_activity_at }\n```\n\n返回 `open == 0` 时无需拉全量评论。\n\nFile v1.3.6:workflows/delete-api-key.md\n\n# 删除 ShareOne API Key\n\n当用户明确要求删除、清除、移除或重置 ShareOne API Key 时读取本文件。\n\n## 1. 执行删除\n\n执行：\n\n```bash\nnode scripts/delete_api_key.js\n```\n\n## 2. 根据输出回复\n\n- `SUDOWORK_KEY_DELETED`：告诉用户 Sudowork 中保存的 ShareOne API Key 已删除（如有本地 fallback 凭证也已一并清理）。\n- `SUDOWORK_FALLBACK_KEY_DELETED`：告诉用户 Sudowork 当前凭证环境不可用，已删除 ShareOne fallback 本地凭证。\n- `KEY_DELETED`：告诉用户本地保存的 ShareOne API Key 已删除。\n- `KEY_NOT_FOUND`：告诉用户当前没有找到已保存的 ShareOne API Key，无需删除。\n- `ERROR:<message>`：删除 Sudowork secret 时出现异常（例如 Auth Proxy 故障）。把错误信息告知用户，建议稍后重试或在 Sudowork 密钥管理中手动删除。\n\n## 3. 删除后的规则\n\n删除后，如果用户再次要求发布、查看评论、处理评论或执行任何 ShareOne API 操作，必须重新读取 `environment-and-credentials.md` 并完成凭据检查和配置。\n\nFile v1.3.6:workflows/delete-share.md\n\n# 删除 ShareOne 分享链接\n\n当用户明确要求“删除/删掉/移除”某个已有 ShareOne 分享链接本身时读取本文件。这是 owner-only 操作，删除后公开链接立即失效（软删除）。\n\n不要把“删除链接”和“修改设置”（水印/密码/短链/评论开关，见 `update-share-settings.md`）混淆；本流程销毁整个 share。\n\n## 0. 删除前确认（阻塞）\n\n执行删除命令前，必须先向用户复述要删除的目标（链接/`share_id`/slug）并获得明确确认。用户确认前不要调用 `delete_share.js`。\n\n## 1. 凭据\n\n删除需要 owner 的 API Key。先运行 `node scripts/ensure_credentials.js`（含义见 `workflows/environment-and-credentials.md`）。没有可用凭据时不要继续。\n\n## 2. 获取 ref\n\n目标可以是完整链接、`/s/<ref>` 等路径、裸 `share_id` 或自定义 slug。脚本会自行取末段并同时接受 `share_id` 与 slug；HTML/文本页和二进制文件（`/pdf/`、`/ppt/`、`/word/`）通用。\n\n## 3. 执行删除\n\n```bash\nnode scripts/delete_share.js <REF>\n```\n\n成功输出 `SHARE_DELETED:<ref>`。删除是幂等的：对已删除的链接重复执行仍返回 `SHARE_DELETED`。\n\n### 连带失效的指针（必须转达给用户）\n\n如果有别的 ShareOne 分享把这条链接当作内容源（remote-url **指针**），它们会**一并失效**，每条打印一行：\n\n```\nPOINTER_INVALIDATED:https://s.shareone.vip/s/xxx\nHINT:POINTERS_INVALIDATED:2\n```\n\n出现这些行时，**必须把每条失效链接原样列给用户**，不要只说\"已删除\"。指针不持有内容、只缓存源的内容，源撤了它们就没有可指的东西；但**指针可能属于别人**，用户需要知道自己刚刚让哪些链接失效了，才能去知会对方。没有这些行就表示没有任何指针受影响。\n\n## 4. 错误处理\n\n- `ERROR:KEY_NOT_FOUND`：没有可用凭据，先按 `environment-and-credentials.md` 配置或创建 guest key。\n- `HTTP 404`：链接不存在，或不属于当前 API Key（IDOR 保护）。据此提示用户核对链接归属。\n- 其他 `ERROR:*` / `AUTH_FAILED`：把服务端返回的原因反馈给用户，不要静默重试。\n\nFile v1.3.6:workflows/download-file.md\n\n# 下载 ShareOne 链接文件\n\n当用户要求“下载这个 ShareOne 链接的文件”或“取回这个链接的源内容”时读取本文件。普通下载不需要先配置 API Key：脚本会在已有凭据时优先尝试 owner 下载，没有凭据时自动退回公开下载。只有用户明确要求用 owner 身份下载、或公开下载失败后需要 owner 权限时，才回到 `environment-and-credentials.md` 完成凭据配置。\n\n## 1. 获取链接或 ref\n\n用户可以提供完整链接、`share_id`、自定义短链 slug，或 `/s/<share_id>` 这类路径。把用户原始输入直接作为参数传给下载脚本即可，脚本会自行解析；不需要自行判断 slug 和 share_id。\n\n## 2. 下载内容\n\n使用 `--save`，脚本会按服务端返回的文件名自动保存到当前目录；如果同名文件已存在，会自动添加数字后缀避免覆盖。成功后在 stdout 输出 `SAVED:<本地文件名>`：\n\n```bash\nnode scripts/download_share.js \"<LINK_OR_ID>\" --save\n```\n\n同时 stderr 会输出文件信息：\n\n```text\nINFO:FILENAME:<原始文件名>\nINFO:CONTENT_TYPE:<mime 类型>\nINFO:REMOTE_SOURCE:<remote_url>      # 仅当该 share 的内容来自远程 URL 时出现\nHINT:EDIT_AT_SOURCE                  # 伴随 REMOTE_SOURCE 出现\n```\n\n如果出现 `INFO:REMOTE_SOURCE` 和 `HINT:EDIT_AT_SOURCE`，说明这个 share 的内容来源是远程 URL（如 GitHub 仓库文件或另一个 ShareOne 链接）。提示用户：如果要修改内容，建议直接去源头修改（如在 GitHub 上编辑原文件），这样所有引用该源的分享链接都会自动同步更新。\n\n脚本会在已配置 ShareOne API Key 时先尝试 owner 下载接口；owner 下载不受访问密码和 `allow_download` 限制。如果当前 API Key 不是 owner 或没有 API Key，脚本会自动退回公开下载。\n\n如果用户提供了访问密码，必须通过 `--password` 传入（脚本用 POST body 发送密码），不要把密码拼进 URL：\n\n```bash\nnode scripts/download_share.js \"<LINK_OR_ID>\" --password \"<PASSWORD>\" --save\n```\n\n如需把内容输出到 stdout 自行处理（例如管道），去掉 `--save` 即可，此时 stdout 是原始文件内容（不是 JSON）。\n\n## 3. 错误处理\n\n下载失败时脚本向 stderr 输出 `ERROR:<code>`，按 code 处理：\n\n| 脚本输出 | 含义与应对 |\n| --- | --- |\n| `ERROR:PASSWORD_REQUIRED` | 该链接需要访问密码才能下载。告诉用户请提供密码后再下载。 |\n| `ERROR:PASSWORD_INVALID` | 用户提供的访问密码不正确。告诉用户密码错误，请确认后重新提供。 |\n| `ERROR:DOWNLOAD_NOT_ALLOWED` | 链接没有开启允许下载。告诉用户需要链接 owner 在文件管理中开启“允许下载”后才能下载。 |\n| `ERROR:SHARE_NOT_FOUND` | 链接不存在或已失效。请用户确认链接是否正确、是否已过期删除。 |\n| 其他 `ERROR:<HTTP ...>` | 按 `result-and-errors.md` 的通用错误规则处理。 |\n\n不要在收到错误后重试同一请求；先按上表与用户沟通缺失的信息。\n\n## 4. 后续处理\n\n- 如果用户只是要求下载或查看，展示下载结果摘要，并按 stderr 中 `INFO:FILENAME` / `INFO:CONTENT_TYPE` 说明文件名和内容类型。\n- 如果用户要求修改下载到的内容，直接编辑 `SAVED:` 给出的本地文件，再根据文件类型读取 `publish-text-page.md` 或 `publish-binary-file.md` 执行更新。\n\nFile v1.3.6:workflows/environment-and-credentials.md\n\n# 环境判断与 API Key 凭据流程\n\n只在需要 ShareOne API 的操作前读取本文件。凭据状态机（检查 → 保存 → 复查 → 核对）全部由 `ensure_credentials.js` 脚本执行；你只需要按输出 token 行动，并把脚本在分隔线 `--- 请将以下内容原样发给用户 ---` 之后输出的话术**原样转发给用户**。不要凭 `SUDOWORK_AUTH_PROXY_URL` 等环境变量自行推断环境。\n\n## 1. 检查凭据\n\n```bash\nnode scripts/ensure_credentials.js\n```\n\n按输出处理：\n\n- `READY`：凭据就绪，直接继续原操作。同时输出的 `MODE:` 行说明当前环境（见第 3 节后续命令规则）。\n- `NEED_USER_INPUT`：凭据缺失。把分隔线之后的提问话术原样转发给用户，**暂停当前操作**，等待用户回复。\n- `ERROR:...`：见第 4 节。\n\n## 2. 用户回复后\n\n- 用户提供了 API Key（例如 `sk-xxx`）：\n\n```bash\nnode scripts/ensure_credentials.js --key <用户提供的KEY>\n```\n\n- 用户回复“没有”或“创建”：\n\n```bash\nnode scripts/ensure_credentials.js --create-guest\n```\n\n两个命令都会自动完成保存、复查和核对，按输出处理：\n\n- `READY`：继续原操作。\n- `GUEST_KEY_CREATED:<api_key>`：**阻塞性用户通知**。分隔线之后是需要原样转发给用户的完整通知文本（含临时 API Key、绑定账号链接和保存提醒）。必须先把该通知发给用户，才能继续原任务的任何上传、下载、评论处理命令；即使 key 已自动保存也不能省略。转发完通知后，追加一句引导：\n  > 如果您希望绑定邮箱以便后续在网站管理文件，请告诉我您的邮箱地址，我可以帮您完成绑定（API Key 不变）。\n  这只是轻提示，不阻塞后续操作。如果用户回复了邮箱，按 `workflows/bind-account.md` 执行绑定流程。\n- `NOTE:SUDOWORK_FALLBACK_KEY_SAVED`：附加信息，表示 key 保存到了 skill 安装目录下的本地 fallback 凭证（`.shareone_credentials`），不是 Sudowork Secret Store。脚本输出的说明文字一并转发给用户即可。\n\n## 3. 后续命令规则\n\n- `MODE:sudowork`：后续所有命令**不要传 `--api-key`**，凭证由 Auth Proxy 自动注入。\n- `MODE:sudowork_fallback` / `MODE:direct`：脚本会自动读取环境变量 `SHAREONE_API_KEY` 或本地凭证文件，**无需显式传 `--api-key`**；仅当用户临时指定其他 key 时才传。\n- 所有非 Sudowork secrets 的本地凭据都只读写 ShareOne skill 安装目录下的 `.shareone_credentials`，不读写用户 home。\n- 如果后续操作中服务返回 401（脚本输出 `ERROR:AUTH_FAILED`），提示用户“API Key 无效或权限不足”。\n\n## 4. 错误处理\n\n- `ERROR:RATE_LIMIT_EXCEEDED`：创建临时 API Key 触发频率限制（每小时 20 次、每天 200 次）。把分隔线之后的提示转发给用户，暂停操作。\n- `ERROR:SUDOWORK_WRITE_BROKEN`：Sudowork 凭证环境可读但写入失败。**不要循环重试保存**；把分隔线之后的说明转发给用户并停止当前操作。\n- 其他 `ERROR:<message>`：把错误信息告知用户，暂停操作。\n\n## 5. 底层脚本（一般不需要直接使用）\n\n`check_api_key.js`、`save_api_key.js`、`create_guest_key.js` 是 `ensure_credentials.js` 的底层组件，仍然可用（输出 `SUDOWORK_ENV_OK_KEY_FOUND` / `KEY_FOUND:<key>` / `SUDOWORK_KEY_SAVED` / `KEY_SAVED` 等细粒度 token），仅用于调试或用户明确指定时；正常流程一律使用 `ensure_credentials.js`。删除凭据见 `delete-api-key.md`。\n\nFile v1.3.6:workflows/manage-collaborators.md\n\n# 管理 ShareOne 链接的协作者\n\n当用户要求添加或移除协作者、查看协作者列表或检查谁有权限访问某个 ShareOne 链接时读取本文件。执行前必须已经完成 `environment-and-credentials.md`。\n\n本 workflow 只管理协作者权限，不修改内容、水印、密码等元数据。\n\n## 1. 判断是否适用\n\n适用示例：\n\n- \"给这个 ShareOne 链接添加协作者：https://shareone.app/s/xxx\"\n- \"Add a collaborator to this share\"\n- \"列出这个分享链接的协作者\"\n- \"移除这个链接的某个协作者\"\n- \"谁有权限访问这个分享链接？\"\n- \"让别人一起编辑这个页面\"\n- \"分享编辑权限给同事\"\n- \"对方怎么拿 API Key？\"\n\n协作者按 ShareOne **用户名**标识（不是 API Key）——这是安全设计，避免在协作管理里传递密钥。如果用户要求添加或移除协作者但没有提供协作者的用户名，先询问协作者的用户名。协作者可在自己的设置页或通过 `GET /api/v1/me` 查到自己的用户名；对方不知道怎么获取时，按第 6 节引导。\n\n## 2. 不要做的事\n\n- 不要下载源文件。\n- 不要修改页面内容或元数据（水印、密码等）。\n- 不要使用 `upload_page.js` 或 `update_share_settings.js`。\n\n## 3. 管理命令\n\n### 列出协作者\n\n```bash\nnode scripts/manage_collaborators.js \"<SHARE_LINK_OR_ID>\" --action list\n```\n\n### 添加协作者\n\n```bash\nnode scripts/manage_collaborators.js \"<SHARE_LINK_OR_ID>\" --action add --usernames \"alice,bob\"\n```\n\n### 移除协作者\n\n```bash\nnode scripts/manage_collaborators.js \"<SHARE_LINK_OR_ID>\" --action remove --usernames \"alice,bob\"\n```\n\n规则：\n\n- Sudowork 环境不要传 `--api-key`。\n- 普通 AI Agent 环境可传 `--api-key`，也可以依赖 `SHAREONE_API_KEY` 或本地凭证。\n- `--usernames` 参数为要添加或移除的协作者的 ShareOne 用户名，多个用逗号分隔。\n- 脚本会自动从完整 URL、`/s/<ref>` 路径、裸 `share_id` 或 slug 中解析目标。\n\n## 4. 结果解读\n\n- `--action list`：返回当前协作者列表的 JSON。\n- `--action add`：返回添加后的结果 JSON，确认哪些协作者已成功添加。\n- `--action remove`：返回移除后的结果 JSON，确认哪些协作者已成功移除。\n\n## 5. 下一步\n\n执行完成后读取 `result-and-errors.md`，按返回 JSON 展示结果或错误。\n\n## 6. 协作者如何提供 username\n\n添加协作者只需要对方的 **username**（公开标识），不需要 API Key（私密凭证）。\n\n### 对方有 AI Agent\n\n让对方的 agent 调用 `GET /api/v1/me`（需要凭据）查看自己的 username，然后把 username 告诉 owner。\n\n### 对方没有 AI Agent\n\nOwner 的 agent 可以代替对方创建 guest 账号。**必须使用 `--no-save`**，否则会覆盖 owner 自己的 API Key：\n\n```bash\nnode scripts/create_guest_key.js --no-save\n```\n\n将返回的 key 发给对方保存。guest 用户的 username 是自动生成的（如 `guest_e7ead86a`），owner 需要知道这个 username 才能添加协作者。对方的 agent 用该 key 调 `GET /api/v1/me` 获取 username 后告知 owner。\n\n### 协作者拿到权限后能做什么\n\n- **下载**：用自己的 API Key 调用 `GET /api/v1/shares/{share_id}/download` 下载源内容\n- **编辑更新**：修改内容后用 `PUT /api/v1/pages/{share_id}` 上传更新（只能改内容，不能改密码、水印等设置）\n- **处理评论**：可以解决或关闭评论\n\n### 建议对方绑定邮箱\n\n添加协作者成功后，如果对方使用的是 guest key，建议提醒对方绑定邮箱（按 `workflows/bind-account.md` 流程），以便后续在网站上管理文件。\n\nArchive v1.3.5: 48 files, 119454 bytes\n\nFiles: agents/openai.yaml (238b), LICENSE (1068b), README.md (5303b), scripts/bind_account.js (6804b), scripts/check_api_key.js (1921b), scripts/comment_list.js (2996b), scripts/comment_reply.js (4575b), scripts/comment_resolve.js (4942b), scripts/create_guest_key.js (3089b), scripts/delete_api_key.js (1260b), scripts/delete_share.js (2715b), scripts/download_share.js (6605b), scripts/ensure_credentials.js (10111b), scripts/make_qr.js (23390b), scripts/manage_collaborators.js (4307b), scripts/proxy_support.test.cjs (4862b), scripts/publish.js (4926b), scripts/refresh_share.js (2311b), scripts/save_api_key.js (1489b), scripts/shareone_api_request.js (3425b), scripts/shareone_client.js (26267b), scripts/shareone_upload.js (8011b), scripts/update_share_settings.js (6306b), scripts/upload_page.js (8152b), skill-card.md (1809b), SKILL.md (18250b), templates/business-card.html (22681b), templates/client-side-inference.html (5542b), templates/page-storage-dropzone.html (5476b), test/redirect_follow.test.js (4236b), tests/test_bind_account_live.js (8564b), tests/test_business_card_template.js (5020b), tests/test_credential_guard.js (5745b), tests/test_make_qr.js (6656b), workflows/bind-account.md (2782b), workflows/comments-process.md (9372b), workflows/comments-view.md (2289b), workflows/delete-api-key.md (1084b), workflows/delete-share.md (2211b), workflows/download-file.md (3460b), workflows/environment-and-credentials.md (3589b), workflows/manage-collaborators.md (3688b), workflows/publish-binary-file.md (3645b), workflows/publish-text-page.md (11898b), workflows/refresh-remote.md (1732b), workflows/result-and-errors.md (6129b), workflows/update-share-settings.md (2729b), _meta.json (127b)\n\nFile v1.3.5:SKILL.md\n\n---\nname: shareone\nslug: shareone\ndisplayName: ShareOne\nversion: 1.3.5\nsummary: Host HTML pages and share PDF/Word/PPT docs with short links\ntags: [shareone, publish, sharing, hosting, html, upload]\ndescription: Host HTML/Markdown pages and share PDF, Word, or PowerPoint docs as ShareOne short links. Use when publishing pages/docs, adding passwords/watermarks, comments, downloads, or updates.\nlicense: MIT\nmetadata:\n  slug: shareone\n  display-name: ShareOne\n  version: 1.3.5\n  summary: Host HTML pages and share PDF/Word/PPT docs with short links\n  tags:\n    - shareone\n    - publish\n    - sharing\n    - hosting\n    - html\n    - upload\n---\n\n# AI Agent 技能：发布到 ShareOne (shareone)\n\nHost HTML/Markdown pages and share PDF, Word, and PowerPoint documents with ShareOne public short links. Covers page publishing, document sharing, password protection, watermarks, review comments, downloads, and updates to existing shares.\n\n这个 Skill 允许 AI Agent 将当前生成的历史会话以及 HTML/Markdown/TXT/PDF/PPT 等文件发布到 ShareOne 线上托管服务，并为用户生成一个持久化的公网分享链接；也可以对已有 ShareOne 链接执行下载、内容更新、设置修改和评论处理。\n\n## 脚本执行基准\n\n本文档中所有 `node scripts/xxx.js` 命令的路径都以 **本 skill 的安装目录**（即本 `SKILL.md` 所在目录）为基准。当前工作目录通常是用户的项目目录，直接执行相对路径会失败。执行前先确定 skill 目录，使用绝对路径或先 `cd` 到 skill 目录，例如：\n\n```bash\nnode /path/to/shareone-skill/scripts/ensure_credentials.js\n```\n\n## 入口隔离规则\n\n本 skill 和用户本机可能安装的 `shareone` CLI 是两个独立入口。除非用户明确要求”使用 CLI”或指定执行 `shareone ...` 命令，否则不要调用系统 PATH 中的 `shareone` 命令。即使 `which shareone` 能找到 CLI，也不要把自然语言的发布、下载、评论处理任务改走 CLI。所有 ShareOne 操作都必须调用本 skill 目录内 `scripts/` 下的脚本。\n\n## 使用说明与触发条件\n\n当用户表达出以下意图时，应主动使用此技能：\n\n- \"帮我把 `index.html` 发布到 ShareOne\"\n- \"把我刚才生成的网页发布，给我个链接\"\n- \"生成一个可分享的链接给我的团队看\"\n- \"Upload this presentation to ShareOne and protect it with password 'secret'\"\n- \"发布这个 PDF 到 ShareOne，并加上密码 1234\"\n- \"把这个网页发布到 ShareOne，加上水印 '内部绝密'\"\n- \"把这个网页发布到 ShareOne，链接叫 product-demo\"\n- \"发布这份设计稿并开启协同评论模式\"\n- \"用 shareone 分享上一轮对话\"\n- \"把我刚才写的代码/大段文字分享出去\"\n- \"Share your last response as a note\"\n- \"帮我下载这个 ShareOne 链接的文件：https://s.shareone.vip/s/xxx\"\n- \"拉取一下这个链接的评论：https://s.shareone.vip/s/xxx\"\n- \"删掉/删除这个 ShareOne 链接：https://s.shareone.vip/s/xxx\"\n- \"我 push 了，刷新一下这个 ShareOne 远程链接的内容：https://s.shareone.vip/s/xxx\"\n- \"给这个 ShareOne 链接加水印：https://s.shareone.vip/s/xxx\"\n- \"根据这个链接的评论修改页面：https://s.shareone.vip/s/xxx\"\n- \"修改这个 ShareOne 链接的内容：https://s.shareone.vip/s/xxx\"\n- \"把这个 GitHub 文件发布到 ShareOne：https://github.com/org/repo/blob/main/report.html\"\n- \"用远程 URL 发布这个页面\"\n- \"Publish this GitHub raw URL to ShareOne\"\n\n## 路由判定顺序（唯一路由依据）\n\n入口文件只负责判断用户意图、选择需要阅读的 workflow。不要一次性读取所有 `workflows/*.md`；只读取当前任务命中的子文件。\n\n按以下顺序从上到下判断，**命中第一条即停止**，按该条给出的阅读顺序执行：\n\n1. **删除/清除/移除/重置 ShareOne API Key**\n   → 读 `workflows/delete-api-key.md`。无需凭据检查。\n\n2. **删除/移除 ShareOne 分享链接本身（用户明确要求“删掉/删除/移除”某个 share_id、slug 或链接）**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/delete-share.md`。删除是 owner-only 操作，执行前须与用户确认（软删除后公开链接立即失效）。对 HTML/文本页和二进制文件链接（`/pdf/`、`/ppt/`、`/word/`）通用。注意与第 6 条区分：本条是删除整个 share，不是改设置。\n\n3. **刷新 remote-url auto-follow 分享的源内容（用户说“我 push 了”“拉一下最新源”“刷新这个远程链接”）**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/refresh-remote.md`。remote 页面刷新是懒的、只在打开渲染页时触发，下载/`/file` 只服务缓存；本条用 `refresh_share.js` 显式强制 refetch。仅对绑定了远程 URL 的分享有效；非 remote-bound 返回 `NOT_REMOTE_BOUND`，此时应改走第 6 或第 10 条（改设置 / 重新发布内容）。\n\n4. **绑定账号、注册、升级 guest、绑定邮箱**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/bind-account.md`。\n\n5. **让别人一起编辑、分享编辑权限、添加/移除/查看协作者、对方怎么拿 API Key**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/manage-collaborators.md`，最后读 `workflows/result-and-errors.md`。\n\n6. **用户提供已有 ShareOne 链接、`share_id` 或 slug，且只要求修改水印、访问密码、自定义短链接、评论开关或数据存储开关（不改内容本身）**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/update-share-settings.md`，最后读 `workflows/result-and-errors.md`。\n   这是元数据更新：不要按文件类型路由，不要下载源文件，不要使用 `publish.js`，不要重新上传内容。对二进制文件链接（`/pdf/`、`/ppt/`、`/word/`）同样适用本条。\n\n7. **下载 ShareOne 链接的文件或取回源内容**\n   → 读 `workflows/download-file.md`。下载脚本会在已有凭据时优先尝试 owner 下载，没有凭据时自动走公开下载；不要为了普通下载强制配置 API Key。\n\n8. **只查看、拉取、总结 ShareOne 链接评论（用户没有要求修改）**\n   → 读 `workflows/comments-view.md`。查看评论用 `comment_list.js`，走公开接口，无需凭据检查。\n\n9. **处理评论、根据评论修改页面、修复 ShareOne 链接内容**\n   → 先读 `workflows/environment-and-credentials.md`，再读 `workflows/comments-process.md`（其中的重新发布步骤会引用 `workflows/publish-text-page.md`），最后读 `workflows/result-and-errors.md`。\n\n10. **发布、分享、生成链接、上线（创建新链接或更新已有链接的内容）**\n   → 先读 `workflows/environment-and-credentials.md`，再按目标文件类型二选一，最后读 `workflows/result-and-errors.md`：\n   - `.ppt`、`.pptx`、`.pdf`、`.doc`、`.docx` → `workflows/publish-binary-file.md`\n   - `.html`、`.md`、`.txt`、对话内容、大段文本、代码块、已包装成 HTML 的内容 → `workflows/publish-text-page.md`。注意：`.md`/`.txt` 一律按原格式发布，不要因为内容包含图表就转成 HTML；只有目标本来就是 HTML 页面时才参考其中的 Mermaid.js 章节。\n\n所有需要 ShareOne API 的操作（上面第 2、3、4、5、6、7、9、10 条），都先运行 `node scripts/ensure_credentials.js`，输出 token 含义与处理流程见 `workflows/environment-and-credentials.md`，这里不重复。\n\n## ShareOne 链接与 share_id\n\n- 用户提供的目标可以是完整链接、`/s/<ref>` 等路径、裸 `share_id`（16 位字符串）或自定义短链 slug。服务端接口同时接受 `share_id` 和 slug，无需自行区分两者。\n- `/s/<share_id>` 是最终给用户访问的分享链接，**不是上传 API endpoint**。不要把 `/s/<share_id>` 当作发布地址，也不要直接向 `/s/<share_id>` PUT/POST 文件。\n- 路径前缀与内容类型的对应关系：`/s/`、`/md/` 是文本/HTML/Markdown 页面；`/pdf/`、`/ppt/`、`/word/` 是二进制文件。元数据更新时 `update_share_settings.js` 会按此前缀自动选择 endpoint，裸 `share_id` 或 slug 由脚本先试页面 endpoint、必要时回退文件 endpoint，整个过程不下载源文件。\n- 文本页里 `/s/<ref>` 与 `/md/<ref>` **等价**：前缀不绑定、也不校验内容类型，浏览路由一律按 ref 解析 share、按 share 真实 content-type 渲染。因此文本页可以就地把 content-type 从 md 升级成 html（`.md → .html`，如把 ASCII 图升级成 Mermaid），URL（含老的 `/md/<slug>`）一字不变、评论保留——见 `workflows/publish-text-page.md` §6b。升级用 `--share-id` 更新，**绝不 `--force-new`**。\n- 内容发布与更新统一使用 `publish.js`，脚本会按文件类型自动分发到文本通道或二进制直传通道（stderr 输出 `INFO:CHANNEL:text|binary`），不需要也不应该自行选择底层上传脚本。不要因为会话里存在旧的 `/s/<share_id>` 就把二进制文件改走文本页面 PUT；二进制文件传 `--share-id` 会被脚本拒绝（`ERROR:BINARY_NO_SHARE_ID`）。\n- 如果当前会话中已经为同一个文本/HTML 文件生成过 ShareOne 链接，可复用之前的 `share_id` 执行文本页面 PUT 更新；否则执行首次创建。\n- 非 owner 下载要求链接已开启允许下载；若脚本输出 `ERROR:DOWNLOAD_NOT_ALLOWED`，直接提示用户让链接 owner 先开启允许下载。\n\n## 发布前安全自检（非阻塞）\n\n- 创建新分享链接（首次 POST 新页面或首次上传新文件）前，Agent 必须自行做内容安全自检：不得发布明显反动、涉政、暴力、色情、侵权或恶意代码内容。\n- 链接保留规则：普通链接在**最后活跃时间**超过 90 天后会被清理（最后活跃 = 创建时间或最后一次被访问时间的较晚者，持续有效访问会一直保持有效，不是发布后 90 天硬删除）；发布到 Explore 公开广场、被知识库引用、或设了 `remote_url` 的内容不参与此无活跃自动清理。\n- 自检通过后直接继续发布，不要向用户展示安全提示，也不要等待用户回复“同意”或 `agree`。\n- 自检必须轻量：对文本/HTML/Markdown/TXT，只基于当前已知内容或发布所需读取的文本内容判断；对 PDF/PPT/Word 等二进制文件，只基于用户请求、文件名、扩展名和显式参数判断，不要为了自检提取正文、OCR、转换格式或解析文件内部内容。\n- 如果内容明显违反上述规则，停止发布并简要说明原因。\n- 对已有链接执行后续操作时——包括内容 PUT 更新、评论处理闭环中的重新发布、水印/密码/短链/评论开关等元数据修改——按对应 workflow 直接执行。\n- 下载、查看评论、删除 API Key 等不发布内容的操作无需安全自检。\n\n## 不可跳过的阻塞步骤\n\n以下步骤是阻塞性用户通知，不是可选说明。触发后必须先发给用户，再继续后续操作。\n\n- 如果 `ensure_credentials.js --create-guest` 或底层 `create_guest_key.js` 输出 `GUEST_KEY_CREATED:<api_key>`，必须立即向用户发送临时 API Key、绑定账号链接和保存提醒（话术见 `workflows/environment-and-credentials.md`）。即使 key 已经自动保存，也不能省略该通知；发送前不得继续执行原任务的上传、下载、评论处理命令。\n- 本会话首次向用户展示生成的 `share_url` 时，必须按 `workflows/result-and-errors.md` 提示所有未使用的高级功能：自定义短链接名称、访问密码、水印。已使用的能力不再提示；三项都已使用则不提示。\n\n## 全局约束\n\n- 发布前必须完成凭据检查和必要的凭据配置。\n- 发布成功后必须直接使用脚本返回的 `share_url`，不要自行拼接分享链接；不要展示备用链接。\n- 只有当用户明确要求开启评论、允许讨论或协同模式时，才添加 `--allow-comments true`。默认不开启评论。\n- 只有当用户明确要求页面持久化数据（如保存游戏分数、表单状态）时，才添加 `--allow-data true`。默认不开启数据存储。\n- 页面持久化数据时，页面代码用自动注入的 `window.__SHAREONE__` SDK，**必须按敏感度二选一、无默认**：`putShared(key, value|File)` 存服务器·所有访客可读·跨设备（大文件自动走 blob，≤8MB）；`putPrivate(key, value|File)` 只存这台设备·私有·不上传。命名即风险（Shared=别人能看），敏感/隐私数据一律 `putPrivate`。现成的“公开 vs 敏感”拖拽上传参考页：`templates/page-storage-dropzone.html`；私有数据可留在本机就地推理（模型公开＋数据 `putPrivate`＋页面内计算，字节不出设备）的参考页：`templates/client-side-inference.html`；完整 SDK 见后端 `agent.md` §14。发布时若带 `--allow-data true`，命令行会在成功后打印一行 `HINT:PAGE_DATA_ENABLED` 提示该二选一与本地推理用法。\n- 自定义短链接（slug）：服务端会根据文件名自动生成可读的 slug（如 `quarterly-report`），客户端无需额外操作。只有用户明确要求“链接叫 xxx”、“自定义短链接 xxx”、“URL 后缀 xxx”时，才在发布命令添加 `--slug xxx` 覆盖自动生成；slug 冲突时把服务端提示反馈给用户，不要静默改名。\n- 页面需要二维码时用 `node scripts/make_qr.js --text \"<内容>\" --format path`（零依赖，直出 SVG path，贴进页面的 `<path d=\"...\">`；`--format svg` 给完整 `<svg>`，`--ecc L|M|Q|H` 默认 Q）。**不要**引入外部二维码库或 `<img src=\"https://...qrserver...\">` 之类的在线生成服务——发布出去的页面在别人的浏览器里打开，外链会失效、泄露访问者，也印不进 PDF。二维码指向本次发布的链接时，先用 `--slug` 定好链接再生成二维码，顺序反了码会指向不存在的页面。\n- 名片/电子名片：用 `templates/business-card.html`（双面设计，一份 HTML 同时产出可发的图片、可扫的链接、90×54mm 印刷 PDF）。改 `data-field=\"...\"` 的文字即可，vCard 和 tel:/mailto: 由页面脚本从卡面读取，不要另写一份联系方式。二维码指向名片页本身而不是公司官网：扫码的人当场要的是把人存进通讯录，名片页能一键存 vCard，且印出去的卡改不了、名片页能随时更新。\n- 开启评论的页面**不要用 MutationObserver 监听自己的输出来触发重绘**。ShareOne 会往页面里注入评论桥（样式、覆盖层、高亮包裹），这本身就是 DOM 变化；页面若据此重绘、重绘又改 DOM，会自持成无限循环，页面直接跑飞（实测：关评论 render 1 次，开评论 502 次）。确实需要按变化重绘时，用内容签名门控：先算出这一帧该画什么，和上一帧比，一样就不画。同理，**不要在 `pointerdown` 里无条件 `setPointerCapture`** —— 指针被容器捕获后，`click` 会派发给捕获者而不是被点的元素，页面里所有节点都点不动，而元素还在、`elementFromPoint` 也正常，很难查；平移交互应等 `pointermove` 超过 3–5px 再捕获。\n- 开启评论、而**可评论的东西不是 DOM 元素**时（canvas 图、地图、3D 视图、虚拟滚动大表格——一千个节点就一个 `<canvas>`），用 `window.__SHAREONE__.anchors`：页面自己声明什么可评论、以及它现在在哪，ShareOne 不解析。不用它的话，所有评论都会锚到那一个 `<canvas>` 上、标签一律 `\"canvas\"`、而且因为那个元素永远解析得到，\"锚点丢失\"一次都不会提示——看起来成功而实际全错。最小用法：`anchors.select({id, label}, rect)` 报告用户选中了什么；`anchors.report([{id, state:\"visible\", rect} | {id, state:\"hidden\"} | {id, state:\"missing\"}])` 在自己布局变化时推位置；`anchors.on(\"resync\"|\"reveal\"|\"hittest\", fn)` 应答 ShareOne 的询问。`hidden`（当前视图没画，读者可换视图）和 `missing`（内容真没了）**必须分开**，合并等于让页面替 ShareOne 宣称内容被删了。锚点是**一组 id 不是矩形**（矩形重排后指向另一批东西，而且永远\"解析得到\"）。完整接口与全部约束见后端 `agent.md` §14b。\n- 开启评论且页面会自己重绘（图表、流程图、看板、任何切换视图就重建 DOM 的页面）时，给每个可评论元素加一个稳定的 `data-*` id，例如 `<g class=\"node\" data-node-id=\"委外cap\">`。ShareOne 的区域评论以应用自己给的这个 id 作锚，重绘后评论自动跟回同一个元素；没有 id 时只能退回\"第几个同名标签\"的结构路径，而重绘必然让它失效，评论会变成\"锚点丢失\"。id 在同一页内必须唯一（命中多个元素的 id 会被拒绝，宁可报丢失也不锚错元素），且在重绘前后保持不变——用业务含义命名，别用渲染顺序生成。\n- 评论处理必须形成闭环：认领、修改、重新发布，然后用 `comment_reply.js --state`（`--state` 必填）**明确表态**——`resolved-agree`（同意收敛）/ `open-disagree`（有异议但保持 open）/ `open-need-input`（需人类澄清）。AI **永不**单方面 dismiss 一条分歧：不同意用 `open-disagree`，`dismiss` 仅用于真正无关/无法处理的评论。\n\n## 最终回复前检查清单\n\n在回复用户前，逐项检查：\n\n- 如果本轮创建了临时 API Key，是否已经把 API Key、绑定账号链接和保存提醒发给用户。\n- 如果本轮**创建了新分享链接**，是否已完成发布前安全自检；如果内容明显违规，是否已停止发布。\n- 如果发布成功，是否直接展示返回的 `share_url`，没有自行拼接链接。\n- 如果返回中包含 `custom_slug_warning` 或 `custom_slug_suggestions`，是否展示给用户。\n- 如果这是本会话首次展示生成的 `share_url`，是否提示所有未使用的高级功能。\n\nFile v1.3.5:README.md\n\n# ShareOne Skill：AI Agent 发布与文档分享工具\n\n<p align=\"center\">\n  <strong>把 AI 生成的网页、Markdown、PDF、Word 和 PowerPoint 文档发布为 ShareOne 短链接。</strong>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://shareone.vip\"><img alt=\"Website\" src=\"https://img.shields.io/badge/website-shareone.vip-0f766e\"></a>\n  <img alt=\"ShareOne\" src=\"https://img.shields.io/badge/ShareOne-skill-2563eb\">\n  <img alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-64748b\">\n</p>\n\n官网：https://shareone.vip\n\n\n\n本仓库包含 ShareOne Agent Skill。它让 Codex、Claude Code、OpenAI Agent、Dify、工作流自动化工具等 AI Agent 可以把本地生成的内容快速发布到 ShareOne，并生成可访问、可转发、可更新的公网分享链接。\n\nShareOne 适合用于发布 AI 生成页面、分享 Markdown 在线文档、托管 HTML 演示页、上传 PDF/Word/PPT 文件、生成团队评审链接，以及为文档添加访问密码、水印和评论协作能力。\n\n## 关键词\n\nShareOne 覆盖以下搜索场景：AI Agent 发布工具、HTML 页面托管、Markdown 在线分享、PDF 短链接分享、Word 文档分享、PPT 在线分享、文档水印、访问密码分享链接、AI 生成网页发布、Codex Skill 文档发布、Agent workflow publishing。\n\n## ShareOne 是什么\n\nShareOne 是一个面向 AI Agent 和开发者的轻量级内容发布服务。它可以把 HTML、Markdown、TXT、PDF、Word、PowerPoint 等文件发布为短链接，方便用户在聊天、项目协作、客户沟通、产品演示和内容交付场景中快速分享。\n\n通过 ShareOne Skill，AI Agent 不需要让用户手动上传文件，也不需要额外搭建静态站点。Agent 可以直接调用 Skill 脚本完成发布、更新、下载、评论读取和设置修改。\n\n## 免费托管\n\nShareOne 提供免费的页面与文档托管能力，适合临时演示、项目评审、AI 生成内容分享、客户预览和团队协作。\n\n普通分享链接会按最后活跃时间保留：只要链接持续有有效访问，就会继续保持可用；当距离最后一次有效访问超过 90 天后，链接才可能被自动清理。也就是说，链接不是从发布时间开始固定 90 天过期，而是每次有效访问都会延续它的活跃状态。\n\n发布到 Explore 公开广场、被知识库引用，或绑定了远程 URL 的内容，不参与普通链接的无活跃自动清理。\n\n## 能力地图\n\n| 文件类型 | 分享链接生成 | 密码访问 | 水印 | 自定义短链接 | 评论反馈 | 更新同一链接 |\n| --- | --- | --- | --- | --- | --- | --- |\n| TXT | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| Markdown | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| HTML | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| PDF | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n| Word | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n| PowerPoint | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n\n## 核心能力\n\n- **HTML 页面发布**：将 AI 生成的网页、报告、原型页面或数据看板发布为在线链接。\n- **Markdown 在线分享**：直接发布 `.md` 或 `.txt` 内容，适合笔记、方案、会议纪要和技术文档。\n- **文档文件分享**：支持 PDF、Word、PowerPoint 文件上传与分享。\n- **短链接访问**：生成 ShareOne 公网短链接，便于在微信、邮件、飞书、Slack、Notion、GitHub Issue 等渠道传播。\n- **访问密码**：为敏感文档或内部材料设置访问密码。\n- **水印保护**：给页面或文档增加水印，降低外泄和二次传播风险。\n- **原链接更新**：在保留同一个分享链接的情况下更新内容，适合反复修改的方案、演示稿和评审页面。\n- **评论协作**：文本页面可开启评论，方便团队直接围绕页面内容反馈和修改。\n- **文件下载控制**：支持下载公开文件，也能在权限允许时取回源内容。\n\n## 适用场景\n\n- AI Agent 生成一个 HTML 页面后，需要立即发布给用户预览。\n- 把 Markdown 报告、技术方案、产品说明发布成可分享链接。\n- 将 PDF、Word、PPT 文件分享给客户、同事或外部协作者。\n- 给内部资料添加访问密码或水印。\n- 把已有 ShareOne 链接内容更新为最新版本。\n- 根据 ShareOne 页面评论修改内容，并重新发布到原链接。\n- 把 GitHub 上的远程 HTML 或文档 URL 发布为 ShareOne 链接。\n\n## Agent 使用方式\n\nAgent 在识别到“发布到 ShareOne”“生成分享链接”“分享这个 PDF”“更新这个 ShareOne 链接”“拉取评论”等意图时，会读取 [SKILL.md](./SKILL.md) 中的完整工作流，并调用本 Skill 的 `scripts/` 脚本完成操作。\n\n常见自然语言指令：\n\n```txt\n把 index.html 发布到 ShareOne，给我一个链接\n把这份 PDF 上传到 ShareOne，并设置访问密码 1234\n把刚才生成的 Markdown 报告分享出去\n更新这个 ShareOne 链接的内容：https://s.shareone.vip/s/xxx\n读取这个 ShareOne 页面上的评论并处理\n给这个链接加上水印“内部资料”\n```\n\n## 链接与文档\n\n- ShareOne 官网：https://shareone.vip\n- Skill 完整说明：[SKILL.md](./SKILL.md)\n\nFile v1.3.5:_meta.json\n\n{\n  \"ownerId\": \"kn73tjvxf6qkw5beygj5y939n988wsag\",\n  \"slug\": \"shareone\",\n  \"version\": \"1.3.5\",\n  \"publishedAt\": 1790659732154\n}\n\nFile v1.3.5:skill-card.md\n\n## Description:\n\nPublishes HTML and Markdown pages and shares PDF, Word, and PowerPoint documents through ShareOne short links, with options for access controls, comments, and updates.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[beep879](https://clawhub.ai/user/beep879)\n\n### License/Terms of Use:\n\nMIT\n\n## Use Case:\n\nDevelopers and other users can publish agent-generated pages or documents as ShareOne links, manage access settings, and collaborate on shared content.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Published chats or files may expose secrets through shareable links.\n\nMitigation: Review content before publishing; do not publish secrets unless they are intended to be shared.\n\nRisk: An included authenticated API helper can perform actions beyond the named workflows.\n\nMitigation: Review the skill before installation, use a limited ShareOne account or API key, and approve authenticated actions explicitly.\n\n## Reference(s):\n\n- [ShareOne skill release](https://clawhub.ai/beep879/skills/shareone)\n- [ShareOne website](https://shareone.vip)\n- [Skill instructions](artifact/SKILL.md)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Shell commands, Guidance]\n\n**Output Format:** [Markdown with share links and command snippets]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Can report published link details, access settings, and comment outcomes.]\n\n## Skill Version(s):\n\n1.3.5 (source: release metadata and skill frontmatter)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.3.5:workflows/bind-account.md\n\n# 绑定账号（Guest → 注册用户升级）\n\n当用户表达\"绑定账号\"、\"注册\"、\"升级 guest\"、\"绑定邮箱\"等意图时读取本文件。执行前必须已经完成 `environment-and-credentials.md`（确保有可用的 API Key）。\n\n## 核心概念\n\n- Guest 用户通过 `POST /api/v1/agent-guest-key` 获取的临时 API Key，绑定邮箱后升级为注册用户\n- **API Key 不变**：绑定只是在同一个 user record 上添加 email，`user.id` 和 `api_key` 都保持不变\n- 绑定后用户可以用邮箱登录 ShareOne 网站 dashboard 管理文件\n- 整个流程由 agent 代劳，用户不需要打开浏览器\n\n## 流程\n\n### 1. 获取用户邮箱\n\n如果用户还没有提供邮箱，询问：\n\n> 请提供您的邮箱地址，我来帮您绑定账号。绑定后您的 API Key 不变，还可以用邮箱登录 ShareOne 网站管理文件。\n\n### 2. 发送验证码\n\n```bash\nnode scripts/bind_account.js --send --email <用户邮箱>\n```\n\n按输出 token 处理：\n\n- `CODE_SENT`：通知用户查看邮箱：\n  > 验证码已发送到 `<邮箱>`，请查看邮箱（含垃圾箱），告诉我 6 位数字验证码。\n- `ERROR:EMAIL_ALREADY_LINKED`：该邮箱已被其他账号使用。告知用户并建议使用其他邮箱，或直接用该邮箱登录网站。\n- `ERROR:COOLDOWN`：发送冷却中，请等待 30 秒后重试。\n- `ERROR:RATE_LIMIT`：频率限制，稍后再试。\n- `ERROR:KEY_NOT_FOUND`：API Key 不存在，需要先通过 `ensure_credentials.js` 获取凭据。\n\n### 3. 等待用户回复验证码\n\n暂停操作，等待用户告知 6 位验证码。\n\n### 4. 验证并绑定\n\n```bash\nnode scripts/bind_account.js --verify --email <用户邮箱> --code <验证码>\n```\n\n按输出 token 处理：\n\n- `BIND_SUCCESS`：绑定成功。向用户确认：\n  > 账号绑定成功！您的邮箱 `<邮箱>` 已与当前 API Key 关联。API Key 不变，您现在可以用这个邮箱登录 ShareOne 网站管理分享的文件。\n- `ERROR:INVALID_CODE`：验证码错误，请用户检查后重新输入。不需要重新发送验证码。\n- `ERROR:CODE_EXPIRED`：验证码已过期（5 分钟有效），需要重新发送。回到第 2 步。\n- `ERROR:TOO_MANY_ATTEMPTS`：验证码尝试次数过多（最多 5 次），需要重新发送。回到第 2 步。\n- `ERROR:EMAIL_ALREADY_LINKED`：邮箱已被其他账号使用。建议使用其他邮箱。\n- `ERROR:KEY_NOT_FOUND`：API Key 无效或 guest 账号不存在。\n\n## 不要做的事\n\n- 不要让用户打开浏览器去网站绑定——整个流程在对话中完成。\n- 不要在绑定后生成新的 API Key——绑定不改变 key。\n- 不要在用户没有明确要求时主动发起绑定流程（但在首次创建 guest key 后可以简短提示）。\n\nFile v1.3.5:workflows/comments-process.md\n\n# 处理 ShareOne 评论\n\n当用户明确要求“处理这些评论”、“根据评论改一下页面”、“修改这个 ShareOne 链接的内容”时读取本文件。只查看评论时不要读取本文件。\n\nShareOne 页面评论包含状态机字段 `status`：`open` / `in_progress` / `resolved` / `dismissed`，以及作者字段 `author_role`：`visitor` / `owner` / `agent`。\n\n处理评论需要 owner 的 API Key（认领状态、发 agent 回复都要求 owner 鉴权），执行前必须已经完成 `environment-and-credentials.md`。\n\n## 1. 获取 ref 与评论\n\n用户提供的目标可以是完整链接、`/s/<ref>` 或 `/md/<ref>` 路径、裸 `share_id` 或自定义短链 slug。取路径最后一段作为 `<REF>` 即可，接口同时接受 `share_id` 和 slug。\n\n本 workflow 只适用于可编辑的文本/HTML/Markdown 页面评论处理。若目标链接路径明确是 `/pdf/`、`/ppt/`、`/word/`，或下载后的 `INFO:CONTENT_TYPE`/文件扩展名显示为 PDF/PPT/Word 等二进制文档，不要为处理评论解析、转换或修改二进制正文；停止内容修改流程，并告知用户当前 skill 只支持处理页面源码评论，二进制文档只能查看/总结评论或更新元数据设置。\n\n任务锚点：步骤 2 的下载命令（`--task-anchor`）会自动把 `<REF>` 写入当前目录的 `.shareone_active_task` 文件，把目标 share 固定到磁盘上（防止长时间编辑文件后上下文丢失，误把更新发成新链接）。后续所有步骤中的 `<REF>` 都以该文件内容为准；任何时候不确定目标 share 是哪个，读取该文件，**不要凭记忆，更不要新建链接**。\n\n先获取未处理评论：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments?status=unresolved\"\n```\n\n评论数据中可能包含 `replies`。必须将父评论及其所有回复作为一个 thread 整体阅读，综合理解最终共识。回复不需要单独走流程，只对父评论操作状态。\n\n## 2. 标准闭环流程\n\n对每条要处理的父评论，严格按以下顺序执行。\n\n### 步骤 1：认领\n\n必须在动手之前做：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/<COMMENT_ID>/status\" \\\n  --method PUT \\\n  --data '{\"status\": \"in_progress\"}'\n```\n\n访问者会立刻在页面侧栏看到“处理中”徽标和顶部“AI 正在处理 N 条评论...”横幅。跳过这一步会让用户感受不到 AI 在干活。\n\n### 步骤 2：取源（自动写锚点）\n\n```bash\nnode scripts/download_share.js \"<REF>\" --task-anchor\n```\n\n`--task-anchor` 会自动完成三件事：写入 `.shareone_active_task` 锚点（stderr 输出 `ANCHOR_WRITTEN:`）、按服务端文件名的扩展名把源内容保存为 `shareone_<REF>_source.<ext>`（stdout 输出 `SAVED:<本地文件名>`）、在 stderr 输出 `INFO:FILENAME:`（原始文件名，步骤 4 要用）和 `INFO:CONTENT_TYPE:`。后续编辑就改 `SAVED:` 给出的这个本地文件——文件名本身携带目标 share，即使对话上下文丢失也能从文件名恢复 `<REF>`。已配置 owner API Key 时脚本自动走 owner 下载接口，不受密码和下载开关限制。\n\n### 步骤 3：精准应用修改\n\n- 综合理解整个 thread（父评论 + 所有 replies）的最终意图，必要时先和用户确认。\n- 绝对不要用全局 `replace()` 或正则批量替换，会误伤其他同名文案。\n- 基于 DOM 结构精确定位：利用 `highlighter_data.startMeta.parentTagName`、`parentIndex`、`textOffset`，结合 `quote`（被选中原文）定位准确节点。\n- 理解结构性意图：评论可能是“把这部分挪到底部 / 删掉这个区块 / 加个图标”，先定位再做结构变更。\n- 如果在当前源文件里无论如何都找不到对应位置，不要瞎改，直接走 dismissed 流程，并用 note 告诉用户：“源文件结构已变更，无法定位你这条关于 XXX 的评论”。\n\n### 步骤 4：重新发布（必须 PUT 更新，禁止新建链接）\n\n脚本选择说明：更新**内容**只能用 `publish.js --share-id`（带 `--share-id` 时执行的是 PUT 内容更新，不是创建）；`update_share_settings.js` 只能改密码/水印/短链/评论开关等元数据，**无法替换页面内容**，本步骤不要使用它。\n\n直接执行以下命令更新原链接。`<REF>` 与步骤 1、2、5 是同一个值，即 `.shareone_active_task` 文件的内容：\n\n```bash\nnode scripts/publish.js \"<步骤 2 SAVED: 给出的本地文件>\" --filename \"<INFO:FILENAME 给出的原文件名>\" --share-id <REF>\n```\n\n硬规则：\n\n- 评论处理流程中**禁止**不带 `--share-id` 执行发布命令——那会 POST 创建一个全新链接，原链接和上面已认领的评论都不会得到任何更新。\n- 不要跳读 `publish-text-page.md` 的“判断创建还是更新”一节，评论场景永远是更新，没有“首次创建”分支。\n- 如果此刻想不起 `share_id`，读取 `.shareone_active_task` 文件或源文件名中的 `shareone_<REF>_` 前缀，绝不新建。\n- 如果脚本输出 `ERROR:ACTIVE_SHARE_TASK`，说明漏传了 `--share-id`，按错误提示补上后重试。\n\n评论闭环中的重新发布属于对已有链接的更新，**不需要**向用户展示发布前安全提示或等待确认（规则见入口 `SKILL.md`）。\n\n### 步骤 5：回复评论并**强制表态**（一条命令，`--state` 必填）\n\n每次回复评论都**必须**用 `comment_reply.js` 并声明一个 `--state`——这是硬性要求（缺省即报错），目的是杜绝“只回复不收敛 / 有分歧却没 signal 出来 / 不确定却没保持 open”这三种失败模式：\n\n```bash\n# 同意并已按建议修改 → 评论收敛为 resolved\nnode scripts/comment_reply.js \"<REF>\" <COMMENT_ID> --content \"已按你的建议把标题改成 ...，并调整了 ...\" --state resolved-agree\n```\n\n`--state` 三选一（无默认）：\n\n| state | 含义 | 对父评论的作用 |\n|---|---|---|\n| `resolved-agree` | 充分理解且同意，已处理 | 置 `resolved` |\n| `open-disagree` | 不同意（在 `--content` 里写清理由） | **保持 `open`**，标记“AI 有异议”，把是否关闭交回给提出者 |\n| `open-need-input` | 需要人类进一步澄清/输入 | 保持 `open` |\n\n脚本会自动从父评论继承 `quote`/`highlighter_data`、以 `author_role=agent` 发一条回复（输出 `REPLY_POSTED:<id>` 和 `COMMENT_STATE:<state>`），后端据 `--state` 原子地设置父评论状态与 AI 立场。不要手工拼接含 `highlighter_data` 的 JSON。\n\n**关键原则：AI 永不单方面关闭一条分歧。** 不同意时用 `open-disagree`（保持 open、让提出者决定），**绝不**用 dismiss 把别人的评论关掉——关闭/重开一条评论的权力属于提出评论的人（以及页面 owner）。\n\n- 输出 `ERROR:STATE_REQUIRED` / `ERROR:INVALID_STATE`：必须补上合法的 `--state`。\n- 输出 `ERROR:IS_REPLY:<parent_id>`：传入的是回复 ID，改用父评论 ID 重试。\n- 输出 `ERROR:AUTH_FAILED`（403）：先查该链接评论是否被关闭（`allow_comments=false`），可经 `update-share-settings.md` 重新开启后重试。\n\n如果误发了一条回复，可以删除（仅作者本人、且父评论仍为 `open` 时可删，会级联删除其回复）：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<SHARE_ID>/comments/<COMMENT_ID>\" --method DELETE\n```\n\n## 3. 无法处理或与页面无关的评论\n\n**注意区分“不同意”与“无关”**：对你有异议但属于合理讨论的评论，用步骤 5 的 `--state open-disagree`（保持 open），**不要** dismiss。`dismiss` 只用于**真正无关/无法处理**的评论（例如指向了另一份分享、垃圾评论）——这是 owner 的否决动作：\n\n```bash\nnode scripts/comment_resolve.js \"<REF>\" <COMMENT_ID> --dismiss --note \"页面中没有此元素，可能指的是另一份分享\"\n```\n\n输出 `COMMENT_DISMISSED:<id>` 即完成。（`comment_resolve.js` 为兼容保留；日常回复请优先用 `comment_reply.js --state`。）\n\n## 4. 收尾：删除任务锚点\n\n所有目标评论都已 `resolved` 或 `dismissed`、且重新发布完成后，删除任务锚点文件：\n\n```bash\nrm -f .shareone_active_task\n```\n\n不删除的话，之后正常的新页面发布会被发布脚本拦截（`ERROR:ACTIVE_SHARE_TASK`）。\n\n## 5. 兼容旧接口\n\n旧接口仍然可用，但新代码不要使用：\n\n```http\nPUT /api/v1/shares/<REF>/comments/<COMMENT_ID>/resolve\n{ \"resolved\": true/false }\n```\n\n它等价于把 `status` 切到 `resolved` 或 `open`，但不会附带 `note`，访问者拿不到 AI 的解释。新代码一律使用 `/status` 接口。\n\n## 6. 关键准则速查\n\n| 准则 | 为什么 |\n| --- | --- |\n| 动手前先 `in_progress` | 让访问者看到“AI 在干活” |\n| 改完一定要 `POST` 一条 `author_role=agent` 的回复 | 闭环的“答复”部分，没有它就只是状态变化、不是对话 |\n| `note` 要写人话 | “已把按钮改成主色” 比 “Applied.” 有用 |\n| 不能处理就 `dismissed` + note | 不要让评论永远卡在 `open` |\n| 只对父评论改状态，回复不单独操作 | 状态语义属于 thread 整体 |\n| `unresolved` = `open + in_progress` | 拉单子默认用 `?status=unresolved` |\n\nFile v1.3.5:workflows/comments-view.md\n\n# 查看 ShareOne 评论\n\n当用户只是要求查看、拉取、总结评论时读取本文件。不要修改源文件，不要认领评论，不要关闭评论。\n\n查看评论走公开接口，**不需要 API Key**（`comment_list.js` 本身即公开读取；若改用 `shareone_api_request.js` 直连则加 `--public`）；只有进入处理评论流程（`comments-process.md`）时才需要凭据。\n\n## 1. 获取 ref\n\n用户提供的目标可以是完整链接、`/s/<ref>` 或 `/md/<ref>` 路径、裸 `share_id` 或自定义短链 slug。取路径最后一段作为 `<REF>` 即可，接口同时接受 `share_id` 和 slug。\n\n## 2. 查看评论\n\n优先用 `comment_list.js`——它输出干净的 UTF-8 JSON（`{ share, status, count, comments:[{ id, status, author_role, quote, content, created_at, resolution_note, reply_count, replies:[...] }] }`），省去手工拼接 endpoint 和解析原始响应，也规避控制台非 ASCII 乱码：\n\n```bash\nnode scripts/comment_list.js <REF>                 # 默认 --status all\nnode scripts/comment_list.js <REF> --status open   # 只看未处理\nnode scripts/comment_list.js <REF> --json compact  # 单行 JSON，便于管道解析\n```\n\n`--status` 可选值：\n\n- `all`（默认）\n- `open`\n- `in_progress`\n- `resolved`\n- `dismissed`\n- `unresolved`，等价于 `open + in_progress`\n\n查看评论无需凭据（公开接口）。只有进入处理评论流程（`comments-process.md`）时才需要 API Key。\n\n## 3. 评论理解规则\n\n- 只展示评论内容，绝对不要自作主张开始修改源文件。\n- 等用户明确要求“处理这些评论”、“根据评论改一下页面”等，再进入 `comments-process.md`。\n- 评论数据中可能包含 `replies`。必须将父评论及其所有回复作为一个 thread 整体阅读，综合理解最终共识。\n- 不要把每条回复当成独立修改指令。\n- 所有回复继承父评论的锚点，也就是 `highlighter_data` 和 `quote`。\n\n## 4. 轻量摘要\n\n如果只想看“现在还有没有未处理的事”，用摘要接口：\n\n```bash\nnode scripts/shareone_api_request.js \"/api/v1/shares/<REF>/comments/summary\" --public\n# -> { total, open, in_progress, resolved, dismissed, last_activity_at }\n```\n\n返回 `open == 0` 时无需拉全量评论。\n\nFile v1.3.5:workflows/delete-api-key.md\n\n# 删除 ShareOne API Key\n\n当用户明确要求删除、清除、移除或重置 ShareOne API Key 时读取本文件。\n\n## 1. 执行删除\n\n执行：\n\n```bash\nnode scripts/delete_api_key.js\n```\n\n## 2. 根据输出回复\n\n- `SUDOWORK_KEY_DELETED`：告诉用户 Sudowork 中保存的 ShareOne API Key 已删除（如有本地 fallback 凭证也已一并清理）。\n- `SUDOWORK_FALLBACK_KEY_DELETED`：告诉用户 Sudowork 当前凭证环境不可用，已删除 ShareOne fallback 本地凭证。\n- `KEY_DELETED`：告诉用户本地保存的 ShareOne API Key 已删除。\n- `KEY_NOT_FOUND`：告诉用户当前没有找到已保存的 ShareOne API Key，无需删除。\n- `ERROR:<message>`：删除 Sudowork secret 时出现异常（例如 Auth Proxy 故障）。把错误信息告知用户，建议稍后重试或在 Sudowork 密钥管理中手动删除。\n\n## 3. 删除后的规则\n\n删除后，如果用户再次要求发布、查看评论、处理评论或执行任何 ShareOne API 操作，必须重新读取 `environment-and-credentials.md` 并完成凭据检查和配置。\n\nFile v1.3.5:workflows/delete-share.md\n\n# 删除 ShareOne 分享链接\n\n当用户明确要求“删除/删掉/移除”某个已有 ShareOne 分享链接本身时读取本文件。这是 owner-only 操作，删除后公开链接立即失效（软删除）。\n\n不要把“删除链接”和“修改设置”（水印/密码/短链/评论开关，见 `update-share-settings.md`）混淆；本流程销毁整个 share。\n\n## 0. 删除前确认（阻塞）\n\n执行删除命令前，必须先向用户复述要删除的目标（链接/`share_id`/slug）并获得明确确认。用户确认前不要调用 `delete_share.js`。\n\n## 1. 凭据\n\n删除需要 owner 的 API Key。先运行 `node scripts/ensure_credentials.js`（含义见 `workflows/environment-and-credentials.md`）。没有可用凭据时不要继续。\n\n## 2. 获取 ref\n\n目标可以是完整链接、`/s/<ref>` 等路径、裸 `share_id` 或自定义 slug。脚本会自行取末段并同时接受 `share_id` 与 slug；HTML/文本页和二进制文件（`/pdf/`、`/ppt/`、`/word/`）通用。\n\n## 3. 执行删除\n\n```bash\nnode scripts/delete_share.js <REF>\n```\n\n成功输出 `SHARE_DELETED:<ref>`。删除是幂等的：对已删除的链接重复执行仍返回 `SHARE_DELETED`。\n\n### 连带失效的指针（必须转达给用户）\n\n如果有别的 ShareOne 分享把这条链接当作内容源（remote-url **指针**），它们会**一并失效**，每条打印一行：\n\n```\nPOINTER_INVALIDATED:https://s.shareone.vip/s/xxx\nHINT:POINTERS_INVALIDATED:2\n```\n\n出现这些行时，**必须把每条失效链接原样列给用户**，不要只说\"已删除\"。指针不持有内容、只缓存源的内容，源撤了它们就没有可指的东西；但**指针可能属于别人**，用户需要知道自己刚刚让哪些链接失效了，才能去知会对方。没有这些行就表示没有任何指针受影响。\n\n## 4. 错误处理\n\n- `ERROR:KEY_NOT_FOUND`：没有可用凭据，先按 `environment-and-credentials.md` 配置或创建 guest key。\n- `HTTP 404`：链接不存在，或不属于当前 API Key（IDOR 保护）。据此提示用户核对链接归属。\n- 其他 `ERROR:*` / `AUTH_FAILED`：把服务端返回的原因反馈给用户，不要静默重试。\n\nFile v1.3.5:workflows/download-file.md\n\n# 下载 ShareOne 链接文件\n\n当用户要求“下载这个 ShareOne 链接的文件”或“取回这个链接的源内容”时读取本文件。普通下载不需要先配置 API Key：脚本会在已有凭据时优先尝试 owner 下载，没有凭据时自动退回公开下载。只有用户明确要求用 owner 身份下载、或公开下载失败后需要 owner 权限时，才回到 `environment-and-credentials.md` 完成凭据配置。\n\n## 1. 获取链接或 ref\n\n用户可以提供完整链接、`share_id`、自定义短链 slug，或 `/s/<share_id>` 这类路径。把用户原始输入直接作为参数传给下载脚本即可，脚本会自行解析；不需要自行判断 slug 和 share_id。\n\n## 2. 下载内容\n\n使用 `--save`，脚本会按服务端返回的文件名自动保存到当前目录；如果同名文件已存在，会自动添加数字后缀避免覆盖。成功后在 stdout 输出 `SAVED:<本地文件名>`：\n\n```bash\nnode scripts/download_share.js \"<LINK_OR_ID>\" --save\n```\n\n同时 stderr 会输出文件信息：\n\n```text\nINFO:FILENAME:<原始文件名>\nINFO:CONTENT_TYPE:<mime 类型>\nINFO:REMOTE_SOURCE:<remote_url>      # 仅当该 share 的内容来自远程 URL 时出现\nHINT:EDIT_AT_SOURCE                  # 伴随 REMOTE_SOURCE 出现\n```\n\n如果出现 `INFO:REMOTE_SOURCE` 和 `HINT:EDIT_AT_SOURCE`，说明这个 share 的内容来源是远程 URL（如 GitHub 仓库文件或另一个 ShareOne 链接）。提示用户：如果要修改内容，建议直接去源头修改（如在 GitHub 上编辑原文件），这样所有引用该源的分享链接都会自动同步更新。\n\n脚本会在已配置 ShareOne API Key 时先尝试 owner 下载接口；owner 下载不受访问密码和 `allow_download` 限制。如果当前 API Key 不是 owner 或没有 API Key，脚本会自动退回公开下载。\n\n如果用户提供了访问密码，必须通过 `--password` 传入（脚本用 POST body 发送密码），不要把密码拼进 URL：\n\n```bash\nnode scripts/download_share.js \"<LINK_OR_ID>\" --password \"<PASSWORD>\" --save\n```\n\n如需把内容输出到 stdout 自行处理（例如管道），去掉 `--save` 即可，此时 stdout 是原始文件内容（不是 JSON）。\n\n## 3. 错误处理\n\n下载失败时脚本向 stderr 输出 `ERROR:<code>`，按 code 处理：\n\n| 脚本输出 | 含义与应对 |\n| --- | --- |\n| `ERROR:PASSWORD_REQUIRED` | 该链接需要访问密码才能下载。告诉用户请提供密码后再下载。 |\n| `ERROR:PASSWORD_INVALID` | 用户提供的访问密码不正确。告诉用户密码错误，请确认后重新提供。 |\n| `ERROR:DOWNLOAD_NOT_ALLOWED` | 链接没有开启允许下载。告诉用户需要链接 owner 在文件管理中开启“允许下载”后才能下载。 |\n| `ERROR:SHARE_NOT_FOUND` | 链接不存在或已失效。请用户确认链接是否正确、是否已过期删除。 |\n| 其他 `ERROR:<HTTP ...>` | 按 `result-and-errors.md` 的通用错误规则处理。 |\n\n不要在收到错误后重试同一请求；先按上表与用户沟通缺失的信息。\n\n## 4. 后续处理\n\n- 如果用户只是要求下载或查看，展示下载结果摘要，并按 stderr 中 `INFO:FILENAME` / `INFO:CONTENT_TYPE` 说明文件名和内容类型。\n- 如果用户要求修改下载到的内容，直接编辑 `SAVED:` 给出的本地文件，再根据文件类型读取 `publish-text-page.md` 或 `publish-binary-file.md` 执行更新。\n\nFile v1.3.5:workflows/environment-and-credentials.md\n\n# 环境判断与 API Key 凭据流程\n\n只在需要 ShareOne API 的操作前读取本文件。凭据状态机（检查 → 保存 → 复查 → 核对）全部由 `ensure_credentials.js` 脚本执行；你只需要按输出 token 行动，并把脚本在分隔线 `--- 请将以下内容原样发给用户 ---` 之后输出的话术**原样转发给用户**。不要凭 `SUDOWORK_AUTH_PROXY_URL` 等环境变量自行推断环境。\n\n## 1. 检查凭据\n\n```bash\nnode scripts/ensure_credentials.js\n```\n\n按输出处理：\n\n- `READY`：凭据就绪，直接继续原操作。同时输出的 `MODE:` 行说明当前环境（见第 3 节后续命令规则）。\n- `NEED_USER_INPUT`：凭据缺失。把分隔线之后的提问话术原样转发给用户，**暂停当前操作**，等待用户回复。\n- `ERROR:...`：见第 4 节。\n\n## 2. 用户回复后\n\n- 用户提供了 API Key（例如 `sk-xxx`）：\n\n```bash\nnode scripts/ensure_credentials.js --key <用户提供的KEY>\n```\n\n- 用户回复“没有”或“创建”：\n\n```bash\nnode scripts/ensure_credentials.js --create-guest\n```\n\n两个命令都会自动完成保存、复查和核对，按输出处理：\n\n- `READY`：继续原操作。\n- `GUEST_KEY_CREATED:<api_key>`：**阻塞性用户通知**。分隔线之后是需要原样转发给用户的完整通知文本（含临时 API Key、绑定账号链接和保存提醒）。必须先把该通知发给用户，才能继续原任务的任何上传、下载、评论处理命令；即使 key 已自动保存也不能省略。转发完通知后，追加一句引导：\n  > 如果您希望绑定邮箱以便后续在网站管理文件，请告诉我您的邮箱地址，我可以帮您完成绑定（API Key 不变）。\n  这只是轻提示，不阻塞后续操作。如果用户回复了邮箱，按 `workflows/bind-account.md` 执行绑定流程。\n- `NOTE:SUDOWORK_FALLBACK_KEY_SAVED`：附加信息，表示 key 保存到了 skill 安装目录下的本地 fallback 凭证（`.shareone_credentials`），不是 Sudowork Secret Store。脚本输出的说明文字一并转发给用户即可。\n\n## 3. 后续命令规则\n\n- `MODE:sudowork`：后续所有命令**不要传 `--api-key`**，凭证由 Auth Proxy 自动注入。\n- `MODE:sudowork_fallback` / `MODE:direct`：脚本会自动读取环境变量 `SHAREONE_API_KEY` 或本地凭证文件，**无需显式传 `--api-key`**；仅当用户临时指定其他 key 时才传。\n- 所有非 Sudowork secrets 的本地凭据都只读写 ShareOne skill 安装目录下的 `.shareone_credentials`，不读写用户 home。\n- 如果后续操作中服务返回 401（脚本输出 `ERROR:AUTH_FAILED`），提示用户“API Key 无效或权限不足”。\n\n## 4. 错误处理\n\n- `ERROR:RATE_LIMIT_EXCEEDED`：创建临时 API Key 触发频率限制（每小时 20 次、每天 200 次）。把分隔线之后的提示转发给用户，暂停操作。\n- `ERROR:SUDOWORK_WRITE_BROKEN`：Sudowork 凭证环境可读但写入失败。**不要循环重试保存**；把分隔线之后的说明转发给用户并停止当前操作。\n- 其他 `ERROR:<message>`：把错误信息告知用户，暂停操作。\n\n## 5. 底层脚本（一般不需要直接使用）\n\n`check_api_key.js`、`save_api_key.js`、`create_guest_key.js` 是 `ensure_credentials.js` 的底层组件，仍然可用（输出 `SUDOWORK_ENV_OK_KEY_FOUND` / `KEY_FOUND:<key>` / `SUDOWORK_KEY_SAVED` / `KEY_SAVED` 等细粒度 token），仅用于调试或用户明确指定时；正常流程一律使用 `ensure_credentials.js`。删除凭据见 `delete-api-key.md`。\n\nFile v1.3.5:workflows/manage-collaborators.md\n\n# 管理 ShareOne 链接的协作者\n\n当用户要求添加或移除协作者、查看协作者列表或检查谁有权限访问某个 ShareOne 链接时读取本文件。执行前必须已经完成 `environment-and-credentials.md`。\n\n本 workflow 只管理协作者权限，不修改内容、水印、密码等元数据。\n\n## 1. 判断是否适用\n\n适用示例：\n\n- \"给这个 ShareOne 链接添加协作者：https://shareone.app/s/xxx\"\n- \"Add a collaborator to this share\"\n- \"列出这个分享链接的协作者\"\n- \"移除这个链接的某个协作者\"\n- \"谁有权限访问这个分享链接？\"\n- \"让别人一起编辑这个页面\"\n- \"分享编辑权限给同事\"\n- \"对方怎么拿 API Key？\"\n\n协作者按 ShareOne **用户名**标识（不是 API Key）——这是安全设计，避免在协作管理里传递密钥。如果用户要求添加或移除协作者但没有提供协作者的用户名，先询问协作者的\n\nArchive v1.3.4: 48 files, 118952 bytes\n\nFiles: agents/openai.yaml (238b), LICENSE (1068b), README.md (5303b), scripts/bind_account.js (6804b), scripts/check_api_key.js (1921b), scripts/comment_list.js (2996b), scripts/comment_reply.js (4575b), scripts/comment_resolve.js (4942b), scripts/create_guest_key.js (3089b), scripts/delete_api_key.js (1260b), scripts/delete_share.js (2715b), scripts/download_share.js (6605b), scripts/ensure_credentials.js (10111b), scripts/make_qr.js (23390b), scripts/manage_collaborators.js (4307b), scripts/proxy_support.test.cjs (4862b), scripts/publish.js (4926b), scripts/refresh_share.js (2311b), scripts/save_api_key.js (...","readmeExcerpt":"Skill: ShareOne HTML & Document Share Links Owner: beep879 Summary: Host HTML pages and share PDF/Word/PPT Tags: latest:1.6.0 Version history: v1.6.0 | 2026-10-09T15:39:24.919Z | auto ShareOne skill 1.6.0 - Updated SKILL.md to clarify workflows and ensure up-to-date usage documentation. - Improved/expanded documentation on routing logic and workflow file referencing. - Updated explanations for comment and publish wor","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"node /path/to/shareone-skill/scripts/ensure_credentials.js"},{"language":"txt","snippet":"把 index.html 发布到 ShareOne，给我一个链接\n把这份 PDF 上传到 ShareOne，并设置访问密码 1234\n把刚才生成的 Markdown 报告分享出去\n更新这个 ShareOne 链接的内容：https://s.shareone.vip/s/xxx\n读取这个 ShareOne 页面上的评论并处理\n给这个链接加上水印“内部资料”"},{"language":"bash","snippet":"node scripts/agent_watch.js --consumer review-agent --share '<分享链接>' \\\n  --cwd '<项目目录>' --command-json '[\"node\",\"receive-shareone.js\"]'"},{"language":"json","snippet":"{\"source\":\"shareone\",\"consumer\":\"review-agent\",\"events\":[{\"id\":\"事件UUID\",\"sequence\":1,\"event_type\":\"comment.created\",\"share_id\":\"稳定分享ID\",\"comment_id\":\"评论UUID\",\"parent_id\":null,\"actor_role\":\"visitor\",\"status\":\"open\",\"created_at\":\"UTC时间\"}]}"},{"language":"bash","snippet":"node scripts/agent_watch.js --consumer scode-review --share '<分享链接>' \\\n  --cwd '<项目目录>' --scode-session '<已有会话路径>'"},{"language":"bash","snippet":"node scripts/bind_account.js --send --email <用户邮箱>"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: shareone\ndescription: Host HTML/Markdown pages and share PDF, Word, or PowerPoint docs as ShareOne short links. Use for publishing, passwords/watermarks, comments, downloads, updates, or Git-backed remote sources for ShareOne content.\nlicense: MIT\nmetadata:\n  slug: shareone\n  display-name: ShareOne\n  version: 1.6.0\n  summary: Host HTML pages and share PDF/Word/PPT docs with short links\n  tags:\n    - shareone\n    - publish\n    - sharing\n    - hosting\n    - html\n    - upload\n---\n\n# AI Agent 技能：发布到 ShareOne (shareone)\n\nHost HTML/Markdown pages and share PDF, Word, and PowerPoint documents with ShareOne public short links. Covers page publishing, document sharing, password protection, watermarks, review comments, downloads, and updates to existing shares.\n\n这个 Skill 允许 AI Agent 将当前生成的历史会话以及 HTML/Markdown/TXT/PDF/PPT 等文件发布到 ShareOne 线上托管服务，并为用户生成一个持久化的公网分享链接；也可以对已有 ShareOne 链接执行下载、内容更新、设置修改和评论处理。\n\n## 内容版本管理决策\n\nShareOne 复用 **GitHub / GitLab 的内容版本管理**：历史、diff、分支、评审和回退在源仓库完成，ShareOne 负责展示、分享、访问控制和评论协作。`remote_url` 的 snapshot 是当前缓存，ShareOne 不维护独立的文件版本库。\n\n涉及 ShareOne 内容的 Git 源、版本选择、历史或回退时，先读 [workflows/git-backed-versions.md](workflows/git-backed-versions.md)，再按下方路由执行发布、刷新或评论处理。该工作流包含跟随分支、固定 commit、切换版本与验收命令。**当前可直接使用公开 GitHub 文本文件；GitLab 和私有仓库认证仍需接入，不能把产品方向当作已支持能力。** 普通本地文件上传仍按原流程执行，不自行迁移到 Git。\n\n## 脚本执行基准\n\n本文档中所有 `node scripts/xxx.js` 命令的路径都以 **本 skill 的安装目录**（即本 `SKILL.md` 所在目录）为基准。当前工作目录通常是用户的项目目录，直接执行相对路径会失败。执行前先确定 skill 目录，使用绝对路径或先 `cd` 到 skill 目录，例如：\n\n```bash\nnode /path/to/shareone-skill/scripts/ensure_credentials.js\n```\n\n## 入口隔离规则\n\n本 skill 和用户本机可能安装的 `shareone` CLI 是两个独立入口。除非用户明确要求”使用 CLI”或指定执行 `shareone ...` 命令，否则不要调用系统 PATH 中的 `shareone` 命令。即使 `which shareone` 能找到 CLI，也不要把自然语言的发布、下载、评论处理任务改走 CLI。所有 ShareOne 操作都必须调用本 skill 目录内 `scripts/` 下的脚本。\n\n## 使用说明与触发条件\n\n当用户表达出以下意图时，应主动使用此技能：\n\n- \"帮我把 `index.html` 发布到 ShareOne\"\n- \"把我刚才生成的网页发布，给我个链接\"\n- \"生成一个可分享的链接给我的团队看\"\n- \"Upload this presentation to ShareOne and protect it with password 'secret'\"\n- \"发布这个 PDF 到 ShareOne，并加上密码 1234\"\n- \"把这个网页发布到 ShareOne，加上水印 '内部绝密'\"\n- \"把这个网页发布到 ShareOne，链接叫 product-demo\"\n- \"发布这份设计稿并开启协同评论模式\"\n- \"用 shareone 分享上一轮对话\"\n- \"把我刚才写的代码/大段文字分享出去\"\n- \"Share your last response as a note\"\n- \"帮我下载这个 ShareOne 链接的文件：https://s.shareone.vip/s/xxx\"\n- \"拉取一下这个链接的评论：https://s.shareone.vip/s/xxx\"\n- \"删掉/删除这个 ShareOne 链接：https://s.shareone.vip/s/xxx\"\n- \"我 push 了，刷新一下这个 ShareOne 远程链接的内容：https://s.shareone.vip/s/xxx\"\n- \"给这个 ShareOne 链接加水印：https://s.shareone.vip/s/xxx\"\n- \"根据这个链接的评论修改页面：https://s.shareone.vip/s/xxx\"\n- \"修改这个 ShareOne 链接的内容：https://s.shareone.vip/s/xxx\"\n- \"把这个 GitHub 文件发布到 ShareOne：https://github.com/org/repo/blob/main/report.html\"\n- \"用远程 URL 发布这个页面\"\n- \"Publish this GitHub raw URL to ShareOne\"\n\n## 路由判定顺序（唯一路由依据）\n\n入口文件只负责判断用户意图、选择需要阅读的 workflow。不要一次性读取所有 `workflows/*.md`；只读取当前任务命中的子文件。\n\n持续监听评论、接收持久通知或唤醒 scode / 其他 Agent：先读 `workflows/environment-and-credentials.md`，再读 `workflows/agent-notifications.md`，使用 `scripts/agent_watch.js`。普通评论查看和单次处理按以下路由执行，不启动常驻监听。\n\n按以下顺序从上到下判断，**命中第一条即停止**，按该条给"},{"path":"README.md","content":"# ShareOne Skill：AI Agent 发布与文档分享工具\n\n<p align=\"center\">\n  <strong>把 AI 生成的网页、Markdown、PDF、Word 和 PowerPoint 文档发布为 ShareOne 短链接。</strong>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://shareone.vip\"><img alt=\"Website\" src=\"https://img.shields.io/badge/website-shareone.vip-0f766e\"></a>\n  <img alt=\"ShareOne\" src=\"https://img.shields.io/badge/ShareOne-skill-2563eb\">\n  <img alt=\"License\" src=\"https://img.shields.io/badge/license-MIT-64748b\">\n</p>\n\n官网：https://shareone.vip\n\n\n\n本仓库包含 ShareOne Agent Skill。它让 Codex、Claude Code、OpenAI Agent、Dify、工作流自动化工具等 AI Agent 可以把本地生成的内容快速发布到 ShareOne，并生成可访问、可转发、可更新的公网分享链接。\n\nShareOne 适合用于发布 AI 生成页面、分享 Markdown 在线文档、托管 HTML 演示页、上传 PDF/Word/PPT 文件、生成团队评审链接，以及为文档添加访问密码、水印和评论协作能力。\n\n## 关键词\n\nShareOne 覆盖以下搜索场景：AI Agent 发布工具、HTML 页面托管、Markdown 在线分享、PDF 短链接分享、Word 文档分享、PPT 在线分享、文档水印、访问密码分享链接、AI 生成网页发布、Codex Skill 文档发布、Agent workflow publishing。\n\n## ShareOne 是什么\n\nShareOne 是一个面向 AI Agent 和开发者的轻量级内容发布服务。它可以把 HTML、Markdown、TXT、PDF、Word、PowerPoint 等文件发布为短链接，方便用户在聊天、项目协作、客户沟通、产品演示和内容交付场景中快速分享。\n\n通过 ShareOne Skill，AI Agent 不需要让用户手动上传文件，也不需要额外搭建静态站点。Agent 可以直接调用 Skill 脚本完成发布、更新、下载、评论读取和设置修改。\n\n## 免费托管\n\nShareOne 提供免费的页面与文档托管能力，适合临时演示、项目评审、AI 生成内容分享、客户预览和团队协作。\n\n普通分享链接会按最后活跃时间保留：只要链接持续有有效访问，就会继续保持可用；当距离最后一次有效访问超过 90 天后，链接才可能被自动清理。也就是说，链接不是从发布时间开始固定 90 天过期，而是每次有效访问都会延续它的活跃状态。\n\n发布到 Explore 公开广场、被知识库引用，或绑定了远程 URL 的内容，不参与普通链接的无活跃自动清理。\n\n## 能力地图\n\n| 文件类型 | 分享链接生成 | 密码访问 | 水印 | 自定义短链接 | 评论反馈 | 更新同一链接 |\n| --- | --- | --- | --- | --- | --- | --- |\n| TXT | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| Markdown | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| HTML | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |\n| PDF | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n| Word | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n| PowerPoint | 支持 | 支持 | 支持 | 支持 | 不支持 | 不支持 |\n\n## 核心能力\n\n- **HTML 页面发布**：将 AI 生成的网页、报告、原型页面或数据看板发布为在线链接。\n- **Markdown 在线分享**：直接发布 `.md` 或 `.txt` 内容，适合笔记、方案、会议纪要和技术文档。\n- **文档文件分享**：支持 PDF、Word、PowerPoint 文件上传与分享。\n- **短链接访问**：生成 ShareOne 公网短链接，便于在微信、邮件、飞书、Slack、Notion、GitHub Issue 等渠道传播。\n- **访问密码**：为敏感文档或内部材料设置访问密码。\n- **水印保护**：给页面或文档增加水印，降低外泄和二次传播风险。\n- **原链接更新**：在保留同一个分享链接的情况下更新内容，适合反复修改的方案、演示稿和评审页面。\n- **评论协作**：文本页面可开启评论，方便团队直接围绕页面内容反馈和修改。\n- **文件下载控制**：支持下载公开文件，也能在权限允许时取回源内容。\n\n## 适用场景\n\n- AI Agent 生成一个 HTML 页面后，需要立即发布给用户预览。\n- 把 Markdown 报告、技术方案、产品说明发布成可分享链接。\n- 将 PDF、Word、PPT 文件分享给客户、同事或外部协作者。\n- 给内部资料添加访问密码或水印。\n- 把已有 ShareOne 链接内容更新为最新版本。\n- 根据 ShareOne 页面评论修改内容，并重新发布到原链接。\n- 把 GitHub 上的远程 HTML 或文档 URL 发布为 ShareOne 链接。\n\n## Agent 使用方式\n\nAgent 在识别到“发布到 ShareOne”“生成分享链接”“分享这个 PDF”“更新这个 ShareOne 链接”“拉取评论”等意图时，会读取 [SKILL.md](./SKILL.md) 中的完整工作流，并调用本 Skill 的 `scripts/` 脚本完成操作。\n\n常见自然语言指令：\n\n```txt\n把 index.html 发布到 ShareOne，给我一个链接\n把这份 PDF 上传到 ShareOne，并设置访问密码 1234\n把刚才生成的 Markdown 报告分享出去\n更新这个 ShareOne 链接的内容：https://s.shareone.vip/s/xxx\n读取这个 ShareOne 页面上的评论并处理\n给这个链接加上水印“内部资料”\n```\n\n## 链接与文档\n\n- ShareOne 官网：https://shareone.vip\n- Skill 完整说明：[SKILL.md](./SKILL.md)"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn73tjvxf6qkw5beygj5y939n988wsag\",\n  \"slug\": \"shareone\",\n  \"version\": \"1.6.0\",\n  \"publishedAt\": 1791560364919\n}"},{"path":"scripts/api_contract.json","content":"{\n  \"errors\": {\n    \"BAD_REQUEST\": {\n      \"status\": 400,\n      \"category\": \"validation\",\n      \"hint\": \"Correct the request using the operation's input schema.\",\n      \"retryable\": false\n    },\n    \"AUTH_REQUIRED\": {\n      \"status\": 401,\n      \"category\": \"auth_failed\",\n      \"hint\": \"Sign in or provide the existing account's X-API-Key.\",\n      \"retryable\": false\n    },\n    \"INVALID_API_KEY\": {\n      \"status\": 401,\n      \"category\": \"auth_failed\",\n      \"hint\": \"Check or update this account's API key; retain the identity that owns the share.\",\n      \"retryable\": false\n    },\n    \"FORBIDDEN\": {\n      \"status\": 403,\n      \"category\": \"permission\",\n      \"hint\": \"Use an identity authorized for this resource and operation.\",\n      \"retryable\": false\n    },\n    \"NOT_FOUND\": {\n      \"status\": 404,\n      \"category\": \"not_found\",\n      \"hint\": \"Check the resource reference and the current account's access.\",\n      \"retryable\": false\n    },\n    \"METHOD_NOT_ALLOWED\": {\n      \"status\": 405,\n      \"category\": \"validation\",\n      \"hint\": \"Use the HTTP method declared for this operation.\",\n      \"retryable\": false\n    },\n    \"PAYLOAD_TOO_LARGE\": {\n      \"status\": 413,\n      \"category\": \"validation\",\n      \"hint\": \"Reduce the request to the operation's size limit.\",\n      \"retryable\": false\n    },\n    \"UNSUPPORTED_MEDIA_TYPE\": {\n      \"status\": 415,\n      \"category\": \"validation\",\n      \"hint\": \"Use the operation's declared request content type.\",\n      \"retryable\": false\n    },\n    \"CONFLICT\": {\n      \"status\": 409,\n      \"category\": \"conflict\",\n      \"hint\": \"Read the reported precondition and correct it before retrying.\",\n      \"retryable\": false\n    },\n    \"VALIDATION_ERROR\": {\n      \"status\": 422,\n      \"category\": \"validation\",\n      \"hint\": \"Correct the fields listed in detail using the operation's input schema.\",\n      \"retryable\": false\n    },\n    \"RATE_LIMIT_EXCEEDED\": {\n      \"status\": 429,\n      \"category\": \"rate_limited\",\n      \"hint\": \"Wait for Retry-After, then retry the same operation.\",\n      \"retryable\": true\n    },\n    \"SERVER_ERROR\": {\n      \"status\": 500,\n      \"category\": \"transient\",\n      \"hint\": \"Back off. Replay writes only with a supported idempotency key or an idempotent operation.\",\n      \"retryable\": true\n    },\n    \"PASSWORD_REQUIRED\": {\n      \"status\": 401,\n      \"category\": \"access_gate\",\n      \"hint\": \"Supply the share password or its verified viewer cookie; keep the current API key.\",\n      \"retryable\": false\n    },\n    \"PASSWORD_INVALID\": {\n      \"status\": 401,\n      \"category\": \"access_gate\",\n      \"hint\": \"Correct the share password; keep the current API key.\",\n      \"retryable\": false\n    },\n    \"EMAIL_GATE_REQUIRED\": {\n      \"status\": 401,\n      \"category\": \"access_gate\",\n      \"hint\": \"Sign in as a viewer or use the owner's/collaborator's API key.\",\n      \"retryable\": false\n    },\n    \"COMMENTS_DISABLED\": {\n      \"status\": 403,\n      \"category\": \"permission\",\n      \"hint\": \"The owner must enable comments before this act"},{"path":"workflows/agent-notifications.md","content":"# 持久评论通知与 Agent 唤醒\n\n当用户要求持续监听评论、通知 scode 或其他 Agent 时使用本工作流。先完成 `environment-and-credentials.md`，使用页面 owner 的凭据。接收器不创建新账号。\n\n## 接到现有 Agent\n\n通用接收器运行在 Agent 所在机器，无需公网 webhook。服务端持久保存事件和每个消费者的确认位置；即使接收器离线，回来后仍会收到未确认的批次。\n\n```bash\nnode scripts/agent_watch.js --consumer review-agent --share '<分享链接>' \\\n  --cwd '<项目目录>' --command-json '[\"node\",\"receive-shareone.js\"]'\n```\n\n`--command-json` 是可执行文件和参数的 JSON 数组，不经过 shell。接收命令从 stdin 读取一行 JSON：\n\n```json\n{\"source\":\"shareone\",\"consumer\":\"review-agent\",\"events\":[{\"id\":\"事件UUID\",\"sequence\":1,\"event_type\":\"comment.created\",\"share_id\":\"稳定分享ID\",\"comment_id\":\"评论UUID\",\"parent_id\":null,\"actor_role\":\"visitor\",\"status\":\"open\",\"created_at\":\"UTC时间\"}]}\n```\n\n接收命令必须在**处理完成或可靠写入自己的持久收件箱后**才返回退出码 0。失败返回非零；不能先启动一个易丢失的后台任务就报告成功。事件只带引用，不含评论正文、截图、API Key 或确认令牌。处理前调用评论 API 读最新线程，按 `comments-process.md` 的认领、修改、同链接更新和明确回复流程执行。分享或评论已删除时跳过失效引用。\n\n## 恢复 scode 会话\n\n```bash\nnode scripts/agent_watch.js --consumer scode-review --share '<分享链接>' \\\n  --cwd '<项目目录>' --scode-session '<已有会话路径>'\n```\n\n接收器启动 `scode acp`，通过 ACP 的 `session/load` 加载指定会话，再用 `session/prompt` 交付事件。只有会话返回 `end_turn` 才确认；交互权限请求会被取消并保留未确认批次。需要机器已安装并配置 scode，且该会话的权限适合任务。请使用专供监听的会话；不要同时在另一个进程操作同一会话。接收器不会增加 scode 权限。不要猜会话路径或自动选择最近一次会话。\n\n默认使用 scode 配置；需要指定模型或认证模式时，可加 `--scode-args-json '[\"--auth\",\"api-key\",\"--model\",\"sonnet\"]'`。这里只放 scode 参数，API Key 仍保存在 scode 的凭据配置里。\n\n## 可靠性与运行方式\n\n- 默认消费上线后记录的全部历史事件；`--start now` 仅在首次注册时从当前位置开始。重复启动同名消费者不会清空进度。上线前已有评论仍需先用 `comment_list.js` 做一次基线检查。\n- `--share` 可省略（接收该 owner 全部分享）；使用者确定范围后再开启。消费者名称和范围固定；更换范围使用新名称。\n- 默认只把访客变化交给命令，避免 Agent 的回复唤醒自己；其他事件也会正常推进确认位置。`--all-actors` 明确开启全部作者事件。\n- 持续长轮询，断网或命令失败后退避重试，最长间隔 60 秒。一个消费者同一时刻只有一个有效批次租约；处理时自动续租。进程崩溃后，5 分钟租约到期即可重领。\n- 语义为**至少一次**。处理完成但确认前崩溃可能重复送达；以事件 `id` 去重，并检查当前评论状态，不能假定恰好一次。\n- `--timeout-seconds` 默认 1800，超时终止本接收器启动的命令进程树，保留未确认事件。`--once` 只检查并处理一个批次，适合排障和验收。\n- 常驻运行由机器的服务管理器监督：Linux 可用 systemd，Windows 可用任务计划程序（登录启动、失败重启、禁止重叠实例）。工作目录指向项目；命令指向安装目录内本脚本。把 API Key 放凭据文件或安全环境配置，不放命令行或任务参数。机器休眠或接收器停止时不会立即唤醒；恢复后补发。\n- 启动常驻监听前确定接收项目、消费者范围和具体会话/命令。只完成脚本安装不表示已开始后台监听。\n\n## HTTP 接口\n\n均需 owner 鉴权，路径前缀 `/api/v1/agent-consumers`：\n\n| 请求 | 含义 |\n|---|---|\n| `PUT /<name>`，`{\"share_id\":null,\"start\":\"beginning\"}` | 幂等注册；可传稳定 ID 或 slug |\n| `GET /`（实际不带尾斜杠） | 列出自己的消费者和游标 |\n| `GET /<name>` | 查看游标和租约到期时间 |\n| `POST /<name>/poll`，`{\"limit\":50,\"wait_seconds\":20}` | 最多 100 条、最多等 25 秒；空批次无令牌 |\n| `POST /<name>/renew`，`{\"lease_token\":\"...\"}` | 将当前租约续到 5 分钟后 |\n| `POST /<name>/ack`，`{\"lease_token\":\"...\"}` | 确认整个已交付批次；重试同一确认幂等 |\n| `POST /<name>/release`，`{\"lease_token\":\"...\"}` | 处理失败后释放，不推进游标 |\n| `DELETE /<name>` | 删除消费者；需要重置进度时明确执行再注册 |\n\n读取不会确认。`ack` 不接受任意目标游标，过期/被替换的令牌返回 409。每个 owner 的事件有独立递增序号；不同 Agent 使用不同消费者名。当前事件不自动过期，删除消费者不会删事件；不承诺无限保存评论正文，事件中的引用可能已失效。\n\n## 防止重投产生重复写入\n\n事件按至少一次投递：处理成功后才 ACK。发布新页面、上传文件或回复评论时，使用稳定的 `--idempotency-key`，例如 `<event.id>.reply`；重试必须保留同一键和同一请求内容。回复脚本返回实际 `parent_status` / `parent_agent_stance`。幂等冲突时先检查原操作与资源状态，不要换键绕过冲突后重复创建；操作返回 409 busy 时按 `Retry-After` 等待。直接上传确认重试应保留原 `share_id`。"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1546,"uniquenessScore":40,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-09T15:59:39.752Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-09T15:59:39.752Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T03:52:37.545Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}