From e1e0c05d3a3493059366d395b78aabae86aa8e78 Mon Sep 17 00:00:00 2001 From: "sanze.li" Date: Sat, 29 Aug 2026 23:04:10 +0800 Subject: [PATCH 1/3] feat: add Cursor Agent CLI managed entry --- .sopify/blueprint/README.md | 3 +- .sopify/blueprint/design.md | 4 +- .../20260828_cursor_agent_cli_entry/plan.md | 79 +++++++++++++++++++ .../receipts/exec_001.json | 18 +++++ .../receipts/exec_002.json | 25 ++++++ .../receipts/exec_003.json | 41 ++++++++++ .../receipts/exec_004.json | 39 +++++++++ .../receipts/exec_005.json | 21 +++++ .../receipts/verify_001.json | 40 ++++++++++ .../receipts/verify_002.json | 31 ++++++++ .../receipts/verify_003.json | 45 +++++++++++ .../20260828_cursor_agent_cli_entry/tasks.md | 32 ++++++++ CHANGELOG.md | 13 +++ README.md | 2 +- README.zh-CN.md | 2 +- docs/cursor-host.md | 15 ++-- docs/getting-started.md | 17 ++-- docs/how-sopify-works.en.md | 2 +- docs/how-sopify-works.md | 2 +- index.html | 2 +- installer/cursor_plugin.py | 9 +++ installer/hosts/base.py | 1 + installer/inspection.py | 4 +- skills/en/cursor-cli-skill.md.template | 23 ++++++ skills/en/cursor-plugin-readme.md.template | 9 ++- skills/en/cursor-plugin-rule.mdc.template | 7 +- skills/zh/cursor-cli-skill.md.template | 23 ++++++ skills/zh/cursor-plugin-readme.md.template | 9 ++- skills/zh/cursor-plugin-rule.mdc.template | 7 +- tests/test_installer_status_doctor.py | 57 ++++++++++++- tests/test_plan_contract_assets.py | 4 +- zh-CN.html | 2 +- 32 files changed, 546 insertions(+), 42 deletions(-) create mode 100644 .sopify/plan/20260828_cursor_agent_cli_entry/plan.md create mode 100644 .sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_001.json create mode 100644 .sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_002.json create mode 100644 .sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_003.json create mode 100644 .sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_004.json create mode 100644 .sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_005.json create mode 100644 .sopify/plan/20260828_cursor_agent_cli_entry/receipts/verify_001.json create mode 100644 .sopify/plan/20260828_cursor_agent_cli_entry/receipts/verify_002.json create mode 100644 .sopify/plan/20260828_cursor_agent_cli_entry/receipts/verify_003.json create mode 100644 .sopify/plan/20260828_cursor_agent_cli_entry/tasks.md create mode 100644 skills/en/cursor-cli-skill.md.template create mode 100644 skills/zh/cursor-cli-skill.md.template diff --git a/.sopify/blueprint/README.md b/.sopify/blueprint/README.md index 0b50622..0fe07a5 100644 --- a/.sopify/blueprint/README.md +++ b/.sopify/blueprint/README.md @@ -13,7 +13,7 @@ ## 当前焦点 -- 当前活动 plan:无;`20260720_plain_language_output` 已完成 Skill 表达、产品页和图文收口,并通过 Sopify `2026-07-21` Release 与 `main / root` GitHub Pages 完成公开交付。 +- 当前活动 plan:`../plan/20260828_cursor_agent_cli_entry` 已完成 Cursor Agent CLI managed-first 顶层入口与一次安装产品化,本机安装和两轮 Cursor 独立审计通过,状态为 `ready_to_archive`;feat 分支 commit/push 已获授权,尚未 finalize、合并或发布。 - MCP tool plane 已完成 Codex-first 持久注册验证和 Claude 会话级只读调用验证,Qoder / Claude / Copilot 的后续持久注册仍按证据推进。 - P8 Protocol Kernel & Runtime Retirement 已归档至 `../history/2026-06/20260605_p8_protocol_kernel_runtime_retirement`。 - history 归档:已可用;最近归档:`../history/2026-07/20260720_plain_language_output`。 @@ -28,6 +28,7 @@ - [蓝图任务](./tasks.md) - [Sopify 宿主接入规范 (Protocol v0)](./protocol.md) - [Skill 标准对齐蓝图](./skill-standards-refactor.md) +- [Cursor Agent CLI 一次安装方案](../plan/20260828_cursor_agent_cli_entry/plan.md) - [变更历史](../history/index.md) - 最近归档:`../history/2026-07/20260720_plain_language_output` diff --git a/.sopify/blueprint/design.md b/.sopify/blueprint/design.md index 4541384..e7c4e2b 100644 --- a/.sopify/blueprint/design.md +++ b/.sopify/blueprint/design.md @@ -441,7 +441,7 @@ P4b 减重和 P4c 宿主消费治理的红线边界。只冻结 artifact / schem > **未列入面默认可删**:`state/sessions/*`、`state/last_route.json`、runtime 内部模块边界、route name 全集、output 渲染文案措辞均为 runtime 内部实现,不在 keep-list 内。P4b 减重时可自由处置。 -`host_support` 只声明官方适配器能把 Skill 语义交付到对应宿主的支持界面并由宿主消费。它不等同于原生 Skill discovery,也不证明该宿主已经完成 E2E;支持等级、已验证能力和入口形态继续由 `HostCapability` 表达。当前五个内置 Skill 面向 `codex / claude / qoder / copilot / cursor`,其中 Copilot 通过单文件展开消费,Cursor IDE 通过用户 Plugin Rule 与全局 Skill 树拆分消费;Agent CLI 只保留手工 Skill 与用户 Hook 兼容面。 +`host_support` 只声明官方适配器能把 Skill 语义交付到对应宿主的支持界面并由宿主消费。它不等同于原生 Skill discovery,也不证明该宿主已经完成 E2E;支持等级、已验证能力和入口形态继续由 `HostCapability` 表达。当前五个内置阶段 Skill 面向 `codex / claude / qoder / copilot / cursor`,其中 Copilot 通过单文件展开消费;Cursor IDE 通过用户 Plugin Rule 进入,本地 Agent CLI 默认安装 managed-first 顶层 Skill,选中后读取同一 Rule,并与 IDE 共用阶段 Skill 树、payload 与用户 Hooks。CLI 模型选择属于 best-effort,安装事实不替代行为证据。 ## Output Rendering Audit — *[pre-P8 legacy reference]* @@ -504,7 +504,7 @@ output.py 渲染层逐字段分类。只做分类,不做改造决策(改造 | Claude | `protocol_verified` | `install.sh --target claude:zh-CN` | CONTINUATION + INTERACTION + AUDIT | 已验证 | | Qoder | `protocol_verified` | `install.sh --target qoder` | CONTINUATION + INTERACTION + AUDIT | W3.1-W3.3 已验证 | | Copilot | `baseline_supported` | `install.sh --target copilot` | PROMPT_ONLY | Prompt-only | -| Cursor | `baseline_supported` | `install.sh --target cursor` | PROMPT_ONLY + HOOKS | IDE user Plugin Rule + global Skills/payload + user-level `~/.cursor/hooks.json`; observable IDE baseline evidence, CLI manual Skills only | +| Cursor | `baseline_supported` | `install.sh --target cursor` | PROMPT_ONLY + HOOKS | IDE user Plugin Rule + managed-first CLI entry + shared Skills/payload + user-level `~/.cursor/hooks.json`; IDE/CLI behavior evidence remains separate | ### 契约消费矩阵(P8 2-file state model) diff --git a/.sopify/plan/20260828_cursor_agent_cli_entry/plan.md b/.sopify/plan/20260828_cursor_agent_cli_entry/plan.md new file mode 100644 index 0000000..c2ea567 --- /dev/null +++ b/.sopify/plan/20260828_cursor_agent_cli_entry/plan.md @@ -0,0 +1,79 @@ +--- +title: Cursor Agent CLI 顶层入口与一次安装产品化 +plan_id: 20260828_cursor_agent_cli_entry +status: done +lifecycle_state: ready_to_archive +level: standard +created: 2026-08-28 +updated: 2026-08-29 +archive_ready: true +--- + +# Cursor Agent CLI 顶层入口与一次安装产品化 + +就绪状态: Ready +依据: 用户已确认 managed-first 口径,并授权先优化本机 CLI 顶层 Skill、安装最新版、经 Cursor 独立审计后,再纳入现有 Cursor 一次安装产品链;不新增 launcher、项目 Rule、runtime 或独立 CLI target。 + +## Context / Why + +Cursor IDE 已通过用户级 Always Plugin Rule 获得 Sopify 顶层协议。2026-08-28 的本机实验进一步证明 `agent` CLI 可以发现 `~/.cursor/skills/sopify/SKILL.md`,并通过该薄入口读取已安装 Plugin Rule、路由五个阶段 Skill。 + +受控实验不等于稳定产品能力。安装后的三个真实用户会话中,顶层 Skill 只自动命中一次;命中会话还出现了入口 Skill 与业务素材并行读取,以及 quick-fix 从默认应用修改扩展到缓存删除和 Helper App 持久化、未重新停车的问题。当前顶层 Skill 只有用户目录单份副本,仓库安装源、升级保护、Doctor、双语文档与产品声明均未纳入;重新运行现有 Cursor 安装会删除这份本机入口。 + +## Scope + +- 第一层:按真实使用证据优化本机中文 CLI 顶层 Skill,清理旧副本并安装唯一最新版;保持入口短小、结构清晰、语言通顺。 +- 第一层验证:校验 Skill 结构与安装哈希,完成 managed 请求前向测试,然后交给 Cursor 在独立标签审计;不认可则按审计结论做最小修正并复验。 +- 第二层:将中英文 CLI 顶层 Skill 纳入 canonical source,使现有 `cursor:zh-CN` / `cursor:en-US` 一次安装默认同时覆盖 IDE 与本地 Agent CLI。 +- 第二层验证:补安装完整性、升级/重装、Doctor、IDE 回归和 CLI managed 流程证据;实现完成后再次交给 Cursor 独立审计。 +- 同步受影响的 Cursor 接入文档、双语产品说明、Changelog 与稳定 blueprint 事实;保持支持档位和未验证边界准确。 + +## Approach + +保留“薄 CLI 入口 → 读取已安装 Plugin Rule → 路由现有阶段 Skills”的结构。顶层 Skill 的 description 从“任何软件请求”收窄为 managed-first 高信号触发,突出 `.sopify`、`~go`、分析/设计/开发、继续/接续/恢复和 finalize/收口;普通咨询不强制触发,也不据此声称已进入 Sopify。 + +Plugin Rule 只补一个共享边界:当已授权动作扩展为新的用户级或系统级持久化、删除操作时重新停车确认。产品化复用现有 Cursor 用户级安装与 `copytree`,把顶层 Skill 加入 canonical 双语源和安装必需路径,不增加新 target、安装参数、能力枚举或运行时组件。 + +## Waves / Steps + +- [x] W1:完成本机中文顶层 Skill 受控实验,并保存旧版本 receipts。 +- [x] W2:根据近期真实会话优化本机 Skill,安装唯一最新版并完成 Cursor 独立审计。 +- [x] W3:把中英文入口纳入一次安装、Doctor/测试和用户文档,保持 IDE/CLI 证据分离。 +- [x] W4:执行目标测试、全量回归、CLI managed 前向观察和第二次 Cursor 独立审计;IDE/CLI 行为证据继续分开。 +- [x] W5:按验证结论同步稳定知识并更新为 `ready_to_archive`;不自动 finalize、commit、push 或发布。 + +## Key Decisions + +- 采用 managed-first:只保证 Sopify/managed 请求的顶层入口,大部分相关场景应自然触发;普通咨询不强制。 +- 用户仍只运行一次 `--target cursor:`;IDE 与本地 CLI 共用阶段 Skills、payload 与 Hooks,但入口机制和行为证据分开声明。 +- 本机 Skill 与产品源使用同一正文,不保留旧版、兼容副本或额外路由文件。 +- 自动 Skill 选择按 best-effort 声明;安装存在、用户已读已用和模型自述均不单独证明稳定行为。 +- Cursor 保持 `BASELINE_SUPPORTED`;Cloud Agent、跨模型一致性和 `PROTOCOL_VERIFIED` 升级不在本轮承诺内。 + +## Constraints / Not-in-scope + +- 不新增 `cursor-cli` target、`--with-cursor-cli`、launcher、项目 `.cursor/rules`、`AGENTS.md`、Custom Mode、MCP 或 runtime。 +- 不修改 Cursor settings、CLI config、代理、模型、账号、API Key、钥匙串或 Cloud Agent。 +- 不重构五项阶段 Skill、writer、state schema、Hook 体系或 HostCapability 架构。 +- 不把通用问答未命中视为失败;只对 managed 触发、读取顺序、协议消费和副作用边界做验收。 +- 不保存含敏感内容的完整 transcript;正式证据记录 session id、受限 tool trace 摘要、用户观察和 digest。 + +knowledge_sync: + project: skip + background: skip + design: required + tasks: skip + +## Status / Progress + +- [x] 本机旧 Skill、受控 receipts、真实会话命中率和现有安装覆盖行为已完成批判审计。 +- [x] 用户确认 managed-first、一次安装默认支持 IDE + CLI、不过度设计,并要求两阶段均经 Cursor 独立审计。 +- [x] 第一层本机 Skill 优化与审计:当前唯一 Skill SHA-256 为 `d892a90fdb7c455367d870e5b47f454a422d578109919d93c9a68eb5fd0beee9`;Cursor 首审不认可读取顺序只在正文,修正 description 后复审认可。 +- [x] 第二层产品化实现:中英文顶层 Skill、一次安装内容校验、旧入口清理、Doctor 必需路径、共享 Rule 边界和用户文档已完成;目标测试与全量 `312 passed / 78 subtests` 通过。 +- [x] 跨宿主污染审计与修正:Cursor 首审不认可专用入口进入共享 Skill 树;现已改为 host-specific 双语模板,补 Codex/Claude/Qoder 负向测试并恢复 shared-tree golden。 +- [x] 第二层 Cursor 最终复审认可,无待修项;最终全量回归为 `313 passed / 81 subtests`。 +- [x] 用户已授权在 `feat/cursor-agent-cli-entry` 本地 commit 并 push 同名 feat 分支;不包含 finalize、合并或发布。 + +## Next + +实现与独立审计均已完成。按用户授权将当前结果 commit 并 push 到 `feat/cursor-agent-cli-entry`;只有显式 `~go finalize` 才归档,合并与发布继续需要单独授权。 diff --git a/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_001.json b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_001.json new file mode 100644 index 0000000..94f0075 --- /dev/null +++ b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_001.json @@ -0,0 +1,18 @@ +{ + "evidence": { + "baseline_greeting_sha256": "5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03", + "demo_root": "/private/tmp/sopify-cursor-cli-entry-demo-20260828", + "installed_skill_sha256": "bbec80a93fd1acf049e7a5539930d7c93337e60dbfb97ce356f48fd4e9ffdafd", + "product_source_diff": "none", + "repository_regression": "311 passed, 78 subtests" + }, + "provenance": { + "plan_id": "20260828_cursor_agent_cli_entry", + "plan_version": "sha256:576bf51018ab71222cacb7e8e4d7b048afa04eb3c6ba60908be4b33a3fce4b8b", + "receipt_id": "exec_001", + "scope": "local Cursor Agent CLI entry probe", + "writer": "sopify_writer" + }, + "timestamp": "2026-08-28T13:39:48+00:00", + "verdict": "local_probe_ready" +} diff --git a/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_002.json b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_002.json new file mode 100644 index 0000000..74a1aee --- /dev/null +++ b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_002.json @@ -0,0 +1,25 @@ +{ + "evidence": { + "cli_config_note": "Cursor Agent later refreshed its own dynamic CLI cache; this is not attributed to the Sopify installer.", + "cli_config_sha256_before_and_immediately_after_installer": "406ef6519b0fbd8bca8f8e36ea334c171833f91a7cd36aa6a31c0227b7ec496e", + "cursor_install_checks": { + "cursor_hooks_present": "pass", + "cursor_plugin_present": "pass", + "global_skill_tree_present": "pass", + "payload_present": "pass" + }, + "installed_skill_sha256": "d892a90fdb7c455367d870e5b47f454a422d578109919d93c9a68eb5fd0beee9", + "installed_sopify_version": "2026-08-22.134737", + "skill_validation": "passed", + "stale_top_level_skill_copies": 0 + }, + "provenance": { + "host": "codex", + "plan_id": "20260828_cursor_agent_cli_entry", + "plan_version": "sha256:11479834b277811893455f73d63e30144d99ac34a9ec0e7bfa5a012ef0052208", + "receipt_id": "exec_002", + "scope": "local Cursor CLI Skill update" + }, + "timestamp": "2026-08-29T14:30:38+00:00", + "verdict": "local_cli_skill_updated" +} diff --git a/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_003.json b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_003.json new file mode 100644 index 0000000..eb75256 --- /dev/null +++ b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_003.json @@ -0,0 +1,41 @@ +{ + "evidence": { + "canonical_entry_paths": [ + "skills/zh/skills/sopify/SKILL.md", + "skills/en/skills/sopify/SKILL.md" + ], + "cli_config_installer_observation": "unchanged across the final product install; Cursor Agent itself updates dynamic cache fields during sessions", + "installed_cursor_checks": { + "cursor_cli_behavior": "BLACK_BOX_NOT_VERIFIED", + "cursor_hooks_present": "pass", + "cursor_ide_behavior": "BLACK_BOX_NOT_VERIFIED", + "cursor_plugin_present": "pass", + "global_skill_tree_present": "pass", + "payload_present": "pass" + }, + "installed_skill_sha256": "d892a90fdb7c455367d870e5b47f454a422d578109919d93c9a68eb5fd0beee9", + "installer_contract": { + "new_target_or_flag": false, + "repeat_install_action": "skipped", + "root_skill_content_verified": true, + "stale_local_entry_replaced": true, + "target": "cursor:" + }, + "tests": { + "full": "312 passed, 78 subtests", + "git_diff_check": "passed", + "golden_snapshots": "24 passed", + "targeted": "93 passed, 27 subtests", + "version_consistency": "passed" + } + }, + "provenance": { + "host": "codex", + "plan_id": "20260828_cursor_agent_cli_entry", + "plan_version": "sha256:1dd10d17b6cba52a06ae75d3709e34103b25b187a46107e00b3372495cd3a592", + "receipt_id": "exec_003", + "scope": "Cursor IDE and local Agent CLI one-install productization" + }, + "timestamp": "2026-08-29T14:38:42+00:00", + "verdict": "cursor_cli_one_install_productized" +} diff --git a/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_004.json b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_004.json new file mode 100644 index 0000000..4a20f43 --- /dev/null +++ b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_004.json @@ -0,0 +1,39 @@ +{ + "evidence": { + "correction": { + "cursor_installer_writes_root_skill_separately": true, + "en_source": "skills/en/cursor-cli-skill.md.template", + "non_cursor_negative_hosts": [ + "codex", + "claude", + "qoder" + ], + "shared_tree_golden_restored": true, + "shared_tree_root_skill_present": false, + "zh_source": "skills/zh/cursor-cli-skill.md.template" + }, + "cursor_audit": { + "dispatch_id": "ctx_750e36ccddfc", + "finding": "Cursor-only root Skill was placed in the shared host Skill tree", + "message_id": "msg_63e9bc828252", + "verdict": "not_accepted" + }, + "installed_skill_sha256": "d892a90fdb7c455367d870e5b47f454a422d578109919d93c9a68eb5fd0beee9", + "repeat_install_action": "skipped", + "tests": { + "focused": "73 passed, 30 subtests", + "full": "313 passed, 81 subtests", + "git_diff_check": "passed" + } + }, + "provenance": { + "host": "codex", + "plan_id": "20260828_cursor_agent_cli_entry", + "plan_version": "sha256:1dd10d17b6cba52a06ae75d3709e34103b25b187a46107e00b3372495cd3a592", + "receipt_id": "exec_004", + "scope": "cross-host isolation correction", + "verifier_host": "cursor" + }, + "timestamp": "2026-08-29T14:49:30+00:00", + "verdict": "cursor_cli_entry_isolated_from_shared_host_tree" +} diff --git a/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_005.json b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_005.json new file mode 100644 index 0000000..3c0854f --- /dev/null +++ b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/exec_005.json @@ -0,0 +1,21 @@ +{ + "evidence": { + "branch": "feat/cursor-agent-cli-entry", + "commit_authorized": true, + "cursor_final_review": "accepted with no remaining findings", + "finalize_authorized": false, + "last_full_test_result": "313 passed, 81 subtests", + "merge_authorized": false, + "push_authorized": true, + "release_authorized": false + }, + "provenance": { + "host": "codex", + "plan_id": "20260828_cursor_agent_cli_entry", + "plan_version": "sha256:9a481e9161773c7d3ccb43aba20c0242e7e6dc85fc9a1861d93abdaf8746bf40", + "receipt_id": "exec_005", + "scope": "local commit and feature-branch push authorization" + }, + "timestamp": "2026-08-29T15:03:13+00:00", + "verdict": "feature_branch_delivery_authorized" +} diff --git a/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/verify_001.json b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/verify_001.json new file mode 100644 index 0000000..a18fc06 --- /dev/null +++ b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/verify_001.json @@ -0,0 +1,40 @@ +{ + "evidence": { + "cases": { + "analyze_design": "pass", + "consult": "pass", + "develop": "pass" + }, + "installed_skill_sha256": "bbec80a93fd1acf049e7a5539930d7c93337e60dbfb97ce356f48fd4e9ffdafd", + "product_source_diff": "none", + "repository_regression": "311 passed, 78 subtests", + "transcript_sha256": { + "analyze_design": "26b0f7c2c1765f4714fc543c9f01cf2c2461861db97cfd9b2b44a786cdb1a293", + "consult": "a7eb73fa5db21e7fcd3c3ea31e86e590e684dd66093964328ab7cbe9a371e5d2", + "develop": "e7932475f303926bdaf88c5191f2c24396896abd05cec825aff294f238c73bec" + }, + "unverified_boundaries": [ + "Cursor IDE behavior after local root Skill install", + "cross-model stability", + "bilingual product installation" + ], + "verified_boundaries": [ + "automatic root Skill selection in three fresh Cursor CLI sessions", + "consult read-only", + "Analyze score and Design level scripts", + "four-step continuation", + "sopify_writer state/handoff/receipts", + "state ignore", + "ready_to_archive without commit/finalize" + ] + }, + "provenance": { + "host": "codex", + "plan_id": "20260828_cursor_agent_cli_entry", + "plan_version": "sha256:6060df26c8bfdae38577e4020d234a36dac2f1544b86f20e6e4639503608220b", + "receipt_id": "verify_001", + "scope": "local Cursor Agent CLI entry experiment" + }, + "timestamp": "2026-08-28T14:46:07+00:00", + "verdict": "accept_local_cli_entry" +} diff --git a/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/verify_002.json b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/verify_002.json new file mode 100644 index 0000000..ead010e --- /dev/null +++ b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/verify_002.json @@ -0,0 +1,31 @@ +{ + "evidence": { + "correction": "moved the Skill and Plugin Rule first-read constraint into the frontmatter description", + "first_cursor_audit": { + "dispatch_id": "ctx_2ffacf6dfec5", + "finding": "initial read-order constraint was absent from description", + "verdict": "not_accepted" + }, + "forward_observation": [ + "Cursor selected the sopify root Skill for the managed audit request", + "the installed Plugin Rule was read before business execution", + "the reviewing Cursor worker made no task-file mutations" + ], + "installed_skill_sha256": "d892a90fdb7c455367d870e5b47f454a422d578109919d93c9a68eb5fd0beee9", + "second_cursor_audit": { + "dispatch_id": "ctx_138ea9a1430b", + "message_id": "msg_d5529bd8e813", + "verdict": "accepted" + } + }, + "provenance": { + "host": "codex", + "plan_id": "20260828_cursor_agent_cli_entry", + "plan_version": "sha256:11479834b277811893455f73d63e30144d99ac34a9ec0e7bfa5a012ef0052208", + "receipt_id": "verify_002", + "scope": "local Cursor CLI Skill independent review", + "verifier_host": "cursor" + }, + "timestamp": "2026-08-29T14:30:38+00:00", + "verdict": "accept_local_cli_skill_after_cursor_review" +} diff --git a/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/verify_003.json b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/verify_003.json new file mode 100644 index 0000000..bb834cf --- /dev/null +++ b/.sopify/plan/20260828_cursor_agent_cli_entry/receipts/verify_003.json @@ -0,0 +1,45 @@ +{ + "evidence": { + "code_quality": "passed: host-specific source, content-aware reinstall, minimal negative coverage, no new target or runtime surface", + "cursor_reviews": [ + { + "dispatch_id": "ctx_750e36ccddfc", + "finding": "Cursor-only root Skill polluted the shared host tree", + "verdict": "not_accepted" + }, + { + "dispatch_id": "ctx_d2cb261a215a", + "finding": "cross-host isolation, minimal tests, and documentation are closed", + "message_id": "msg_ca3e063cf5bd", + "verdict": "accepted" + } + ], + "final_architecture": { + "cursor_only_sources": [ + "skills/zh/cursor-cli-skill.md.template", + "skills/en/cursor-cli-skill.md.template" + ], + "installed_path": "~/.cursor/skills/sopify/SKILL.md", + "shared_host_tree_pollution": false, + "single_target": "cursor:", + "support_tier": "BASELINE_SUPPORTED" + }, + "final_tests": "313 passed, 81 subtests", + "remaining_boundaries": [ + "IDE and CLI behavior checks remain BLACK_BOX_NOT_VERIFIED", + "Cloud Agent excluded", + "cross-model selection not promised" + ], + "spec_compliance": "passed: managed-first, one install, local latest, stale cleanup, independent Cursor acceptance, no finalize" + }, + "provenance": { + "host": "codex", + "plan_id": "20260828_cursor_agent_cli_entry", + "plan_version": "sha256:26d94ce48ae59cb572a5f3bc67a234a99a681786a49fda072a989b18059d77a6", + "receipt_id": "verify_003", + "scope": "final Cursor CLI productization review", + "verifier_host": "cursor" + }, + "timestamp": "2026-08-29T14:57:12+00:00", + "verdict": "accept_cursor_cli_one_install_productization" +} diff --git a/.sopify/plan/20260828_cursor_agent_cli_entry/tasks.md b/.sopify/plan/20260828_cursor_agent_cli_entry/tasks.md new file mode 100644 index 0000000..f97401f --- /dev/null +++ b/.sopify/plan/20260828_cursor_agent_cli_entry/tasks.md @@ -0,0 +1,32 @@ +# 任务清单: Cursor Agent CLI 顶层入口与一次安装产品化 + +目录: `.sopify/plan/20260828_cursor_agent_cli_entry/` + +## 1. 本机 CLI Skill 优化 + +- [x] 1.1 根据近期真实会话收窄 managed-first description,保持薄入口结构并补充必要读取顺序。 +- [x] 1.2 校验 Skill 结构、语言和行为边界,清理旧副本并把唯一最新版安装到 `~/.cursor/skills/sopify/SKILL.md`。 +- [x] 1.3 执行 managed 请求前向验证,记录可复核的本机证据。 + +## 2. 第一轮 Cursor 独立审计 + +- [x] 2.1 将当前 Skill、证据与审计要求放入 worktree 可读 handoff。 +- [x] 2.2 启动 Cursor 独立审计;收回认可/不认可结论并释放 worker 资源。 +- [x] 2.3 对不认可项做最小修正并复验,直到本机 Skill 获得认可。 + +## 3. 一次安装产品化 + +- [x] 3.1 将中英文顶层 Skill 纳入 canonical source,并让 Cursor 安装完整性包含该入口。 +- [x] 3.2 补最小共享副作用边界、升级/重装与 Doctor 测试;不新增 target、launcher 或能力框架。 +- [x] 3.3 同步 Cursor Plugin 说明、接入文档、双语 README、Changelog 与 blueprint 稳定事实。 + +## 4. 产品化验证与独立审计 + +- [x] 4.1 运行目标测试、全量回归、Git diff 检查以及安装前后受保护文件哈希检查。 +- [x] 4.2 执行 CLI managed 前向观察并保留可复核证据;IDE/CLI 行为项继续明确为独立 `BLACK_BOX_NOT_VERIFIED`,不以静态安装冒充行为证明。 +- [x] 4.3 交给 Cursor 独立审计完整实现;修正跨宿主污染后复审获得认可。 + +## 5. 收尾 + +- [x] 5.1 完成 spec compliance 与 code quality 两阶段复审,更新方案和任务状态。 +- [x] 5.2 将方案更新为 `ready_to_archive` 并保留在 `plan/`;不自动 finalize、commit、push 或发布。 diff --git a/CHANGELOG.md b/CHANGELOG.md index 13302a2..7db1764 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,19 @@ Format: Summary → Changed → Plan Packages. File-level details live in `git l ## [Unreleased] +### Summary + +Extended the existing Cursor user-scope installation with a managed-first entry for local Agent CLI. + +### Changed + +- **Cursor Agent CLI**: Added bilingual top-level Skills that read the installed Plugin Rule for managed requests, kept automatic model selection best-effort, and preserved separate IDE/CLI behavior evidence. +- **Cursor installation**: The existing `cursor:` target now installs and verifies the CLI entry, replaces stale local copies on reinstall, and keeps settings, proxy, model, account, and Cloud Agent out of scope. + +### Plan Packages + +- `20260828_cursor_agent_cli_entry` → implementation and independent Cursor review complete; explicit finalize remains separate. + ## [2026-08-22.134737] - 2026-08-22 ### Summary diff --git a/README.md b/README.md index f23f0ac..07769ad 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,7 @@ Host support: | Claude | PROTOCOL_VERIFIED | `claude:en-US` / `claude:zh-CN` | Full capability continuation | | Qoder | PROTOCOL_VERIFIED | `qoder` | Validated on Qoder CLI | | Copilot | BASELINE_SUPPORTED | `copilot:en-US` / `copilot:zh-CN` | Prompt-only; payload uplift planned | -| [Cursor](docs/cursor-host.md) | BASELINE_SUPPORTED | `cursor:en-US` / `cursor:zh-CN` | IDE user Plugin + global Skills/payload + user hooks | +| [Cursor](docs/cursor-host.md) | BASELINE_SUPPORTED | `cursor:en-US` / `cursor:zh-CN` | IDE user Plugin + managed-first CLI entry + shared Skills/payload/hooks | Pass `--workspace ` to target another repo for workspace-scope or prewarm installs; Cursor installs once at user scope and does not require it. Use `--language ` to control output language. diff --git a/README.zh-CN.md b/README.zh-CN.md index bba8fed..8b94efa 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -137,7 +137,7 @@ Get-Content sopify-install.ps1 | more | Claude | PROTOCOL_VERIFIED | `claude:zh-CN` / `claude:en-US` | 全能力接续 | | Qoder | PROTOCOL_VERIFIED | `qoder` | 已在 Qoder CLI 验证 | | Copilot | BASELINE_SUPPORTED | `copilot:zh-CN` / `copilot:en-US` | 仅 prompt;payload 升级计划中 | -| [Cursor](docs/cursor-host.md) | BASELINE_SUPPORTED | `cursor:zh-CN` / `cursor:en-US` | IDE 用户 Plugin + 全局 Skills/payload + 用户 Hooks | +| [Cursor](docs/cursor-host.md) | BASELINE_SUPPORTED | `cursor:zh-CN` / `cursor:en-US` | IDE 用户 Plugin + managed-first CLI 入口 + 共享 Skills/payload/Hooks | 可用 `--workspace ` 指定目标仓库,`--language ` 控制输出语言;Cursor 为用户级一次安装,不需要 `--workspace`。 diff --git a/docs/cursor-host.md b/docs/cursor-host.md index 5cde51f..b099f25 100644 --- a/docs/cursor-host.md +++ b/docs/cursor-host.md @@ -1,6 +1,6 @@ # Cursor 宿主接入 -主要支持本地 Cursor IDE。Cursor Agent CLI 不提供自动 Plugin Rule 入口,Cloud Agent 不在本期范围。支持档位保持 `BASELINE_SUPPORTED`。真实 IDE 已观察到 Plugin Rule 路由、Analyze 评分、AskQuestion 调用尝试与文本回退、managed develop、writer 写回和 Hook 拒绝明显直写;这些证据不代表跨模型稳定性或完整协议认证。本期不为 CLI 增加 launcher、项目 Rule 或 runtime。 +支持本地 Cursor IDE 与 Agent CLI,Cloud Agent 不在本期范围。IDE 通过用户级 Always Plugin Rule 进入;Agent CLI 默认安装 managed-first 顶层 Skill,被模型选中后实际读取同一 Rule。CLI 自动选择属于 best-effort,支持档位保持 `BASELINE_SUPPORTED`;本期不增加 launcher、项目 Rule 或 runtime,也不把安装存在外推为跨模型稳定性或完整协议认证。 ## 安装面 @@ -13,7 +13,7 @@ curl -fsSL https://github.com/evidentloop/sopify/releases/latest/download/instal 安装一次,管理四个用户级落点: - Plugin:`~/.cursor/plugins/local/sopify/.cursor-plugin/plugin.json`、`README.md` 与 `rules/sopify.mdc`。README 渐进介绍用途与边界;薄 Always Rule 是 IDE 的语义入口。 -- Skills:`~/.cursor/skills/sopify/` 下的 `analyze`、`design`、`develop`、`kb`、`templates` 和共享 references。 +- Skills:`~/.cursor/skills/sopify/SKILL.md` 是 Agent CLI 的 managed-first 顶层入口;同目录下的 `analyze`、`design`、`develop`、`kb`、`templates` 和共享 references 由 IDE 与 CLI 共用。 - Payload:`~/.cursor/sopify/`,包含版本化 bundle 与 Hook helper。 - Hooks:合并到 `~/.cursor/hooks.json`;不写仓库级 hooks。 @@ -23,10 +23,11 @@ Cursor 不需要 `--workspace`,安装器不在目标仓库创建 `.cursor/rule ## 语义与 Hook 边界 -IDE Plugin Rule 负责意图分类与 Skill 路由: +IDE 直接加载 Plugin Rule;Agent CLI 的顶层 Skill 被选中后先读取同一 Rule。Rule 负责意图分类与 Skill 路由: - `consult_readonly` 直接只读回答,不自动恢复 active plan; - `quick_fix` 可修改用户授权的产品代码,但不直接写协议 state、handoff、receipt 或知识库; +- 已授权动作若扩大为新的用户级或系统级持久化、删除操作,先说明新增影响并重新等待确认; - `new_plan`、`continue_plan`、`finalize` 和明确的 managed develop 才进入对应 Skill 与四步协议入口; - Analyze 必须实际执行 Skill 中的评分脚本,machine truth 只经 `sopify_writer` 库 API 写入。 @@ -47,7 +48,7 @@ python3 scripts/sopify_doctor.py --format json --home-root "$HOME" Cursor 分开报告: - `cursor_plugin_present`:Plugin manifest 与 Rule 是否存在;README 是包内说明,不作为行为或安装健康硬门槛; -- `global_skill_tree_present`:五项 Skills、共享写作/输出契约与 Analyze 评分脚本是否存在; +- `global_skill_tree_present`:CLI 顶层 Skill、五项阶段 Skills、共享写作/输出契约与 Analyze 评分脚本是否存在; - `payload_present`:payload/bundle 是否结构完整; - `cursor_hooks_present`:用户 hooks 与 helper 是否安全、完整; - `cursor_ide_behavior`、`cursor_cli_behavior`:真实宿主黑盒,默认 `skip (BLACK_BOX_NOT_VERIFIED)`。 @@ -60,10 +61,10 @@ IDE 与 CLI 分开记录,不互相外推: 1. IDE baseline 已有可观察证据:已安装 Rule 含 `alwaysApply: true`,consult 实际读取 Cursor 写作规范并保持只读;Analyze 读取 Cursor Skill 并执行评分脚本;有限选项澄清留下 AskQuestion tool use 与 `Tool not found` 文本回退,结构化问卷 UI 仅作为人工观察,transcript 不含 tool result 或选项回传;managed 场景按 Analyze → Design → Develop 推进,经 `sopify_writer` 写 state、handoff 与 receipts;明显 Shell 直写 machine truth 被 Hook 拒绝且文件哈希不变。 2. IDE 未验证边界:AskQuestion 是否跨模型稳定提供、独立 `sessionStart` 行为与显式 finalize。本期依赖文本追问回退和现有协议边界,不把这些项目作为 baseline 发布阻塞。 -3. CLI 未验证自动语义入口。CLI 的结果不能用于证明 IDE 行为,IDE 的结果也不能用于证明 CLI 行为。 +3. CLI 已观察到 managed 审计请求自动选择顶层 Skill、读取 Plugin Rule,并在修正 description 读取顺序后通过独立 Cursor 复审。该证据只证明当前本机路径,不承诺每个普通请求、所有模型或所有机器都会自动选择。 -Cursor 官方 CLI 文档明确项目 Rules,但没有把用户 Plugin Rule 写成 CLI 加载契约。2026-08-20 的真实会话也未读取 Cursor Plugin Rule 指定的共享规范,显式 `--plugin-dir` 唯一标记探针同样未生效。因此 CLI 自动入口明确不支持,也不阻塞本次 IDE baseline 发布。 +Cursor CLI 不会自行加载用户 Plugin Rule;Sopify 通过默认安装的顶层 Skill 显式读取该 Rule,不依赖 `--plugin-dir`、项目 Rule 或 prompt injector。Skill 发现和模型选择仍是宿主行为,因此 Doctor 继续把安装事实与 `cursor_cli_behavior` 黑盒证据分开。 -一次临时仓库黑盒已观察到四步读链、managed develop 与 `sopify_writer` 写回;显式 finalize 仍按用户命令触发,未纳入本次 baseline 黑盒。Doctor 的行为项继续保持静态 `BLACK_BOX_NOT_VERIFIED`,不把某台机器上的临时 transcript 写成可移植产品认证。 +一次临时仓库黑盒已观察到四步读链、managed develop 与 `sopify_writer` 写回;本机顶层 Skill 复审又观察到 managed 请求自动选择和 Rule 消费。显式 finalize、跨模型一致性与可移植黑盒仍未完整认证;Doctor 的行为项继续保持静态 `BLACK_BOX_NOT_VERIFIED`。 官方依据:[`Cursor Plugins`](https://cursor.com/docs/plugins)、[`Plugin format`](https://cursor.com/docs/reference/plugins)、[`Cursor Rules`](https://cursor.com/docs/rules)、[`Cursor Agent Skills`](https://cursor.com/docs/skills)、[`Cursor Hooks`](https://cursor.com/docs/hooks)、[`Cursor CLI`](https://cursor.com/docs/cli/using)。 diff --git a/docs/getting-started.md b/docs/getting-started.md index eac68a8..74b6eb7 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -139,11 +139,11 @@ Copilot reads project-level instruction files across its supported surfaces Full trigger wiring (equivalent to Codex/Claude `~go`) is coming in a future release. -### Cursor IDE (optional Agent CLI) +### Cursor IDE and local Agent CLI Cursor IDE uses one user-level Plugin rule. The same installation provides a -global Skill/payload tree under `~/.cursor/` and user-level hooks in -`~/.cursor/hooks.json`: +managed-first Agent CLI entry, the shared Skill/payload tree under `~/.cursor/`, +and user-level hooks in `~/.cursor/hooks.json`: ```bash curl -fsSL https://github.com/evidentloop/sopify/releases/latest/download/install.sh | bash -s -- --target cursor:en-US @@ -157,11 +157,12 @@ created during install. `--with-evidentloop` is not supported for Cursor in this release. The Plugin Rule uses valid `.mdc` frontmatter with `alwaysApply: true` and routes to `~/.cursor/skills/sopify`. -The tested Agent CLI does not automatically load this user Plugin Rule. -Automatic entry for Agent CLI and Cloud Agent is outside this release. No -launcher, project Rule, prompt injector, or runtime is added. See -[Cursor host acceptance](./cursor-host.md). The current tier remains -`BASELINE_SUPPORTED`. +Agent CLI does not load the user Plugin Rule by itself. The installed top-level +`~/.cursor/skills/sopify/SKILL.md` is a managed-first, model-selected entry that +reads the Rule before routing phase Skills. Selection is best-effort; ordinary +questions do not have to trigger it, and Cloud Agent remains outside this +release. No launcher, project Rule, prompt injector, or runtime is added. See +[Cursor host acceptance](./cursor-host.md). The tier remains `BASELINE_SUPPORTED`. ## Verify Setup diff --git a/docs/how-sopify-works.en.md b/docs/how-sopify-works.en.md index eb20d54..c7969b0 100644 --- a/docs/how-sopify-works.en.md +++ b/docs/how-sopify-works.en.md @@ -109,7 +109,7 @@ Layer notes: | Claude | PROTOCOL_VERIFIED | `install.sh --target claude:en-US` | Full capability continuation | | Qoder | PROTOCOL_VERIFIED | `install.sh --target qoder` | Validated on Qoder CLI | | Copilot | BASELINE_SUPPORTED | `install.sh --target copilot` | Prompt-only; payload uplift planned | -| Cursor | BASELINE_SUPPORTED | `install.sh --target cursor:en-US` | IDE user Plugin + global Skills/payload + user hooks | +| Cursor | BASELINE_SUPPORTED | `install.sh --target cursor:en-US` | IDE user Plugin + managed-first CLI entry + shared Skills/payload/hooks | ## Appendix: Plan Lifecycle diff --git a/docs/how-sopify-works.md b/docs/how-sopify-works.md index 337376d..e187b06 100644 --- a/docs/how-sopify-works.md +++ b/docs/how-sopify-works.md @@ -109,7 +109,7 @@ Sopify 不默认安装或运行验证器。只用 Sopify、使用其他 Verifier | Claude | PROTOCOL_VERIFIED | `install.sh --target claude:zh-CN` | 全能力接续 | | Qoder | PROTOCOL_VERIFIED | `install.sh --target qoder` | 已在 Qoder CLI 验证 | | Copilot | BASELINE_SUPPORTED | `install.sh --target copilot` | 仅 prompt;payload 升级计划中 | -| Cursor | BASELINE_SUPPORTED | `install.sh --target cursor:zh-CN` | IDE 用户 Plugin + 全局 Skills/payload + 用户 Hooks | +| Cursor | BASELINE_SUPPORTED | `install.sh --target cursor:zh-CN` | IDE 用户 Plugin + managed-first CLI 入口 + 共享 Skills/payload/Hooks | ## 附录:Plan 生命周期 diff --git a/index.html b/index.html index a0a66d9..4ebb905 100644 --- a/index.html +++ b/index.html @@ -252,7 +252,7 @@

The short version

Does switching hosts give every host identical capabilities? -

Codex, Claude, and Qoder have protocol-verified paths. Copilot and Cursor are baseline-supported. Cursor's automatic Plugin Rule entry applies to the local IDE, not Agent CLI or Cloud Agent.

+

Codex, Claude, and Qoder have protocol-verified paths. Copilot and Cursor are baseline-supported. One Cursor install provides the IDE Plugin Rule and a best-effort managed entry for local Agent CLI; Cloud Agent remains out of scope.

Is EvidentLoop required? diff --git a/installer/cursor_plugin.py b/installer/cursor_plugin.py index 97ba657..816b86e 100644 --- a/installer/cursor_plugin.py +++ b/installer/cursor_plugin.py @@ -11,6 +11,7 @@ _IGNORE_PATTERNS = shutil.ignore_patterns(".DS_Store", "Thumbs.db", "__pycache__") _README_TEMPLATE_NAME = "cursor-plugin-readme.md.template" +_CLI_SKILL_TEMPLATE_NAME = "cursor-cli-skill.md.template" def install_cursor_user_plugin_assets( @@ -26,11 +27,14 @@ def install_cursor_user_plugin_assets( rule_source = adapter.instruction_source(repo_root, language_directory) readme_source = rule_source.with_name(_README_TEMPLATE_NAME) + root_skill_source = rule_source.with_name(_CLI_SKILL_TEMPLATE_NAME) skills_source = adapter.source_root(repo_root, language_directory) / "skills" / "sopify" if not rule_source.is_file(): raise InstallError(f"Missing source Cursor Plugin rule: {rule_source}") if not readme_source.is_file(): raise InstallError(f"Missing source Cursor Plugin README: {readme_source}") + if not root_skill_source.is_file(): + raise InstallError(f"Missing source Cursor CLI Skill: {root_skill_source}") if not skills_source.is_dir(): raise InstallError(f"Missing source skills directory: {skills_source}") @@ -38,9 +42,11 @@ def install_cursor_user_plugin_assets( readme_path = adapter.user_plugin_readme_path(home_root) plugin_root = rule_path.parent.parent skills_destination = adapter.destination_root(home_root) / "skills" / "sopify" + root_skill_destination = skills_destination / "SKILL.md" manifest = _manifest_text() rule = render_user_plugin_rule(rule_source, adapter) readme = readme_source.read_text(encoding="utf-8").rstrip("\n") + "\n" + root_skill = root_skill_source.read_text(encoding="utf-8").rstrip("\n") + "\n" expected_paths = adapter.expected_paths(home_root) if ( manifest_path.is_file() @@ -49,6 +55,8 @@ def install_cursor_user_plugin_assets( and rule_path.read_text(encoding="utf-8") == rule and readme_path.is_file() and readme_path.read_text(encoding="utf-8") == readme + and root_skill_destination.is_file() + and root_skill_destination.read_text(encoding="utf-8") == root_skill and all(path.exists() for path in adapter.global_skill_paths(home_root)) ): return InstallPhaseResult( @@ -71,6 +79,7 @@ def install_cursor_user_plugin_assets( shutil.rmtree(skills_destination) skills_destination.parent.mkdir(parents=True, exist_ok=True) shutil.copytree(skills_source, skills_destination, ignore=_IGNORE_PATTERNS) + root_skill_destination.write_text(root_skill, encoding="utf-8") return InstallPhaseResult( action=action, diff --git a/installer/hosts/base.py b/installer/hosts/base.py index 44dcc0c..dec2b62 100644 --- a/installer/hosts/base.py +++ b/installer/hosts/base.py @@ -91,6 +91,7 @@ def workspace_expected_paths(self, workspace_root: Path) -> tuple[Path, ...]: def global_skill_paths(self, home_root: Path) -> tuple[Path, ...]: skills_root = self.destination_root(home_root) / "skills" / "sopify" return ( + skills_root / "SKILL.md", skills_root / "analyze" / "SKILL.md", skills_root / "design" / "SKILL.md", skills_root / "develop" / "SKILL.md", diff --git a/installer/inspection.py b/installer/inspection.py index 195f406..123c289 100644 --- a/installer/inspection.py +++ b/installer/inspection.py @@ -840,8 +840,8 @@ def _cursor_behavior_check(*, capability: HostCapability, check_id: str) -> Insp ) else: recommendation = ( - "Optionally run the Cursor Agent CLI manual-Skill and Hook black-box flow. " - "Automatic loading of the user Plugin Rule is not a supported CLI entry." + "Run the Cursor Agent CLI managed-entry and Hook black-box flow. " + "Top-level Skill selection is best-effort and remains separate from file installation evidence." ) return _cursor_not_verified_check( capability=capability, diff --git a/skills/en/cursor-cli-skill.md.template b/skills/en/cursor-cli-skill.md.template new file mode 100644 index 0000000..5c022db --- /dev/null +++ b/skills/en/cursor-cli-skill.md.template @@ -0,0 +1,23 @@ +--- +name: sopify +description: Top-level entry for Sopify managed workflows in Cursor Agent CLI. Use it for .sopify, ~go, requirements analysis, solution design, development, plan continuation or resumption, and finalize or closeout requests; once selected, first load only this Skill and the installed Plugin Rule without parallel business reads or other tools. Ordinary software questions and unmanaged quick fixes do not require it. +--- + +# Sopify CLI Top-Level Entry + +This Skill adds a managed-first entry for Cursor Agent CLI. It only loads the installed Sopify protocol and routes phase Skills; it does not copy the protocol or replace a Plugin Rule already loaded by Cursor IDE. + +## Entry steps + +1. If the current context already contains the `Sopify Cursor IDE Entry` heading and the five intents `consult_readonly`, `quick_fix`, `new_plan`, `continue_plan`, and `finalize`, follow that protocol without reading it again. +2. Otherwise, after loading this Skill, read only `~/.cursor/plugins/local/sopify/rules/sopify.mdc` next. Do not read business files or call other tools in parallel. Read the file for real rather than merely claiming to reference it; treat its frontmatter as Cursor metadata and its body as the top-level Sopify protocol for this conversation. +3. Classify the current request using that protocol, then read the relevant phase Skill, knowledge-base guidance, shared writing guidance, and output contract under `~/.cursor/skills/sopify/` only as needed. +4. If the Plugin Rule is missing or unreadable, stop Sopify routing and ask the user to rerun the Cursor installer for the current language. Do not substitute a same-named Skill from `~/.claude`, `~/.codex`, or the project. + +## Boundaries + +- Automatic selection is model-driven and best-effort. Claim that Sopify was entered only after this Skill or the Plugin Rule was actually read. +- Ordinary software questions and unmanaged quick fixes do not have to trigger this Skill. Never pretend that an unmatched managed request consumed Sopify. +- Intent classification, scoring, the four-step protocol, knowledge-base policy, output, and writer boundaries remain authoritative in the installed Plugin Rule and phase Skills; this file does not duplicate them. +- If an authorized action expands into new user-level or system-level persistence or deletion, explain the added impact and wait for confirmation again. +- Do not modify the Cursor Plugin Rule, Hooks, settings, CLI configuration, proxy, model, account, API key, keychain, or MCP. diff --git a/skills/en/cursor-plugin-readme.md.template b/skills/en/cursor-plugin-readme.md.template index 4c52abd..cb045af 100644 --- a/skills/en/cursor-plugin-readme.md.template +++ b/skills/en/cursor-plugin-readme.md.template @@ -1,6 +1,6 @@ # Sopify -Sopify is an adaptive workflow layer for Cursor IDE. It routes each request to the smallest appropriate path—read-only consultation, quick fix, analysis, design, or managed development—while keeping evidence and project-state boundaries explicit. +Sopify is an adaptive workflow layer for Cursor IDE and local Agent CLI. It routes each request to the smallest appropriate path—read-only consultation, quick fix, analysis, design, or managed development—while keeping evidence and project-state boundaries explicit. ## Use Sopify @@ -8,12 +8,13 @@ Describe the goal naturally. Sopify uses the current repository's instructions a ## How it works -- **Always Rule** classifies intent and routes the request. +- **IDE Always Rule** classifies intent and routes requests in Cursor IDE. +- **CLI top-level Skill** reads the same Rule for managed requests in local Agent CLI; model selection is best-effort. - **Skills** provide the phase-specific procedures. - **User Hooks** guard protocol state and receipt files against obvious direct writes; they are not a security sandbox. ## Support boundary -- Cursor IDE is the automatic semantic entry. Cursor Agent CLI uses the installed Skills manually. -- Support remains `BASELINE_SUPPORTED`: the primary IDE path has observable evidence, but automatic CLI entry, Cloud Agents, and identical behavior across models are not promised. +- Cursor IDE uses the Always Rule. Cursor Agent CLI installs a managed-first top-level Skill by default and reuses the same phase Skills, payload, and user Hooks. +- Support remains `BASELINE_SUPPORTED`: IDE and CLI evidence stay separate, and Sopify does not promise that every ordinary request selects the top-level Skill, Cloud Agents, or identical behavior across models. - Sopify does not modify Cursor settings, proxy, model, account, API keys, keychain, or MCP configuration. Cloud Agents are out of scope. diff --git a/skills/en/cursor-plugin-rule.mdc.template b/skills/en/cursor-plugin-rule.mdc.template index e7d4b14..20b20d0 100644 --- a/skills/en/cursor-plugin-rule.mdc.template +++ b/skills/en/cursor-plugin-rule.mdc.template @@ -6,7 +6,7 @@ alwaysApply: true # Sopify Cursor IDE Entry -This is the user-level Cursor Plugin rule for the IDE. When the IDE loads it, it is the Sopify semantic entry. It governs intent routing, protocol boundaries, and output; the installed Sopify Skills retain the phase procedures. The Agent CLI does not automatically load this Rule in the validated release and is outside this automatic-entry contract. +This is the user-level Cursor Plugin rule for the IDE. When the IDE loads it, it is the Sopify semantic entry. It governs intent routing, protocol boundaries, and output; the installed Sopify Skills retain the phase procedures. Agent CLI does not load a Plugin Rule by itself; when the default top-level `sopify` Skill is selected, it reads this Rule and reuses the same protocol. ## Entry for every Agent request @@ -14,7 +14,8 @@ This is the user-level Cursor Plugin rule for the IDE. When the IDE loads it, it 2. Classify intent first: `consult_readonly`, `quick_fix`, `new_plan`, `continue_plan`, or `finalize`. Never resume merely because an active plan exists. 3. Treat `AGENTS.md`, `CLAUDE.md`, project Rules, and `.sopify/` in the current target repository as project facts. A multi-repository parent directory is not automatically the target repository. 4. Answer `consult_readonly` directly and read-only without loading a phase Skill. `quick_fix` may modify user-authorized product code, but neither mode resumes an old plan or directly writes state, handoff, receipts, or the knowledge base. -5. For workflow work, read and execute the exact `~/.cursor` path listed below. Do not substitute a same-named Skill from `~/.claude`, `~/.codex`, or another compatibility directory: +5. If an authorized action expands into new user-level or system-level persistence or deletion, explain the added impact and wait for confirmation again. +6. For workflow work, read and execute the exact `~/.cursor` path listed below. Do not substitute a same-named Skill from `~/.claude`, `~/.codex`, or another compatibility directory: - Requirements analysis: `{{skills_root}}/analyze/SKILL.md` - Solution design: `{{skills_root}}/design/SKILL.md` - Development: `{{skills_root}}/develop/SKILL.md` @@ -32,6 +33,6 @@ This is the user-level Cursor Plugin rule for the IDE. When the IDE loads it, it ## Support boundary and output - Cursor remains `BASELINE_SUPPORTED`: file presence or a single model claim is not protocol-level verification; support conclusions require observable host evidence. -- Agent CLI users may invoke the installed Skills manually; user Hooks remain available where Cursor loads them. Sopify does not claim automatic CLI routing through this Plugin Rule. +- Agent CLI installs a managed-first top-level Skill by default. Model selection is best-effort, and Sopify is entered only after the top-level Skill and this Rule were actually read. User Hooks remain available where Cursor loads them. - Follow the already-read `{{skills_root}}/references/shared-writing-dna.md`. After entering a phase Skill, read `{{skills_root}}/references/output-contract.md`. For consult, give only the conclusion and necessary evidence; do not add a banner, `Changes`, or `Next` to fill a template. - Do not modify Cursor settings, proxy, model, account, API key, keychain, or MCP. Cloud Agents are out of scope. diff --git a/skills/zh/cursor-cli-skill.md.template b/skills/zh/cursor-cli-skill.md.template new file mode 100644 index 0000000..ad538a7 --- /dev/null +++ b/skills/zh/cursor-cli-skill.md.template @@ -0,0 +1,23 @@ +--- +name: sopify +description: Cursor Agent CLI 中 Sopify 托管工作流的顶层入口。请求涉及 .sopify、~go、需求分析、方案设计、开发实施、继续、接续、恢复方案或 finalize、收口时优先使用;命中后第一步只加载本 Skill 和已安装 Plugin Rule,不与业务读取或其他工具并行。普通软件咨询和非托管 quick fix 不强制触发。 +--- + +# Sopify CLI 顶层入口 + +此 Skill 为 Cursor Agent CLI 补充 managed-first 入口。它只负责加载当前安装的 Sopify 协议并路由阶段 Skill,不复制协议正文,也不替换 Cursor IDE 已加载的 Plugin Rule。 + +## 入口步骤 + +1. 如果当前上下文已包含标题 `Sopify Cursor IDE 入口`,以及 `consult_readonly`、`quick_fix`、`new_plan`、`continue_plan`、`finalize` 五类意图,直接遵循该协议,不重复读取。 +2. 否则,加载本 Skill 后的下一步只读取 `~/.cursor/plugins/local/sopify/rules/sopify.mdc`;不要并行读取业务文件或调用其他工具。必须实际读取,不得只声称已参考;frontmatter 是 Cursor 元数据,正文是当前会话的顶层 Sopify 协议。 +3. 先按该协议分类本轮意图,再按需读取 `~/.cursor/skills/sopify/` 下对应的阶段 Skill、KB、共享写作规范与输出契约。 +4. Plugin Rule 缺失或不可读时停止 Sopify 路由,提示用户重新运行当前语言的 Cursor 安装;不得用 `~/.claude`、`~/.codex` 或项目中的同名 Skill 顶替。 + +## 边界 + +- 自动选择由 Cursor 模型决定,属于 best-effort。只有实际读取本 Skill 或 Plugin Rule 后,才可以声称本轮已进入 Sopify。 +- 普通软件咨询和非托管 quick fix 不强制触发;managed 请求未命中时,不得伪装成已消费 Sopify。 +- 意图分类、评分门、四步协议、KB、输出和 writer 边界均以已安装 Plugin Rule 与阶段 Skills 为准,本文件不重复定义。 +- 如果已授权动作扩大为新的用户级或系统级持久化、删除操作,先说明新增影响并重新等待确认。 +- 不修改 Cursor Plugin Rule、Hooks、settings、CLI config、代理、模型、账号、API Key、钥匙串或 MCP。 diff --git a/skills/zh/cursor-plugin-readme.md.template b/skills/zh/cursor-plugin-readme.md.template index 50b974f..2d8a024 100644 --- a/skills/zh/cursor-plugin-readme.md.template +++ b/skills/zh/cursor-plugin-readme.md.template @@ -1,6 +1,6 @@ # Sopify -Sopify 是 Cursor IDE 的自适应工作流层。它先把请求路由到最小适用路径——只读咨询、快速修复、需求分析、方案设计或受管开发——并明确约束证据和项目状态边界。 +Sopify 是 Cursor IDE 与本地 Agent CLI 的自适应工作流层。它先把请求路由到最小适用路径——只读咨询、快速修复、需求分析、方案设计或受管开发——并明确约束证据和项目状态边界。 ## 使用方式 @@ -8,12 +8,13 @@ Sopify 是 Cursor IDE 的自适应工作流层。它先把请求路由到最小 ## 工作方式 -- **Always Rule**:分类意图并路由请求。 +- **IDE Always Rule**:在 Cursor IDE 中分类意图并路由请求。 +- **CLI 顶层 Skill**:在本地 Agent CLI 中为 managed 请求读取同一 Rule;模型选择属于 best-effort。 - **Skills**:提供各阶段的执行细则。 - **用户级 Hooks**:对协议 state、handoff 与 receipt 提供明显直写保护;它们不是安全沙箱。 ## 支持边界 -- Cursor IDE 是自动语义入口;Cursor Agent CLI 手工使用已安装 Skills。 -- 当前支持档位为 `BASELINE_SUPPORTED`;IDE 主路径已有可观察证据,但不承诺 CLI 自动入口、Cloud Agent 或跨模型完全一致。 +- Cursor IDE 使用 Always Rule;Cursor Agent CLI 默认安装 managed-first 顶层 Skill,并复用同一阶段 Skills、payload 与用户 Hooks。 +- 当前支持档位为 `BASELINE_SUPPORTED`;IDE 与 CLI 证据分开记录,不承诺每个普通请求都选择顶层 Skill、Cloud Agent 或跨模型完全一致。 - Sopify 不修改 Cursor settings、代理、模型、账号、API Key、钥匙串或 MCP 配置;不支持 Cloud Agent。 diff --git a/skills/zh/cursor-plugin-rule.mdc.template b/skills/zh/cursor-plugin-rule.mdc.template index 151e15b..265aea5 100644 --- a/skills/zh/cursor-plugin-rule.mdc.template +++ b/skills/zh/cursor-plugin-rule.mdc.template @@ -6,7 +6,7 @@ alwaysApply: true # Sopify Cursor IDE 入口 -这是 Cursor IDE 的用户级 Plugin Rule;IDE 实际加载它时,它作为 Sopify 语义入口。它只负责意图路由、协议边界和输出治理;阶段细则仍由已安装的 Sopify Skills 提供。已验证版本的 Agent CLI 不会自动加载此 Rule,因此不属于本自动入口契约。 +这是 Cursor IDE 的用户级 Plugin Rule;IDE 实际加载它时,它作为 Sopify 语义入口。它只负责意图路由、协议边界和输出治理;阶段细则仍由已安装的 Sopify Skills 提供。Agent CLI 不会自行加载 Plugin Rule;默认安装的顶层 `sopify` Skill 被模型选中后,会实际读取本 Rule 并复用同一协议。 ## 每次 Agent 请求的入口 @@ -14,7 +14,8 @@ alwaysApply: true 2. 先分类意图:`consult_readonly`、`quick_fix`、`new_plan`、`continue_plan` 或 `finalize`。不得因存在 active plan 就自动恢复。 3. 当前目标仓库中的 `AGENTS.md`、`CLAUDE.md`、项目 Rules 和 `.sopify/` 都是项目事实;多仓父目录不自动等同于目标仓库。 4. `consult_readonly` 直接只读回答,不加载阶段 Skill;`quick_fix` 可以修改用户授权的产品代码,但两者都不自动接续旧方案,也不直接写 state、handoff、receipt 或知识库。 -5. 需要进入工作流时,读取并执行下面列出的 `~/.cursor` 精确路径;不得替换为 `~/.claude`、`~/.codex` 或其他兼容目录中的同名 Skill: +5. 如果已授权动作扩大为新的用户级或系统级持久化、删除操作,先说明新增影响并重新等待确认。 +6. 需要进入工作流时,读取并执行下面列出的 `~/.cursor` 精确路径;不得替换为 `~/.claude`、`~/.codex` 或其他兼容目录中的同名 Skill: - 需求分析:`{{skills_root}}/analyze/SKILL.md` - 方案设计:`{{skills_root}}/design/SKILL.md` - 开发实施:`{{skills_root}}/develop/SKILL.md` @@ -32,6 +33,6 @@ alwaysApply: true ## 支持边界与输出 - Cursor 首发保持 `BASELINE_SUPPORTED`:文件存在或单次模型自述不等于协议级验证;支持结论以可观察宿主证据为准。 -- Agent CLI 可按需手工调用已安装的 Skills;Cursor 加载用户 Hooks 时继续保留写保护。Sopify 不宣称此 Plugin Rule 能为 CLI 提供自动路由。 +- Agent CLI 默认安装 managed-first 顶层 Skill;模型自动选择属于 best-effort,只有实际读取顶层 Skill 与本 Rule 后才算进入 Sopify。Cursor 加载用户 Hooks 时继续保留写保护。 - 表达遵循已读的 `{{skills_root}}/references/shared-writing-dna.md`。进入阶段 Skill 后再读 `{{skills_root}}/references/output-contract.md`;咨询只给结论和必要证据,不要为凑模板添加标题、`Changes` 或 `Next`。 - 不修改 Cursor settings、代理、模型、账号、API Key、钥匙串或 MCP;不启用 Cloud Agent。 diff --git a/tests/test_installer_status_doctor.py b/tests/test_installer_status_doctor.py index f68d536..3f859e1 100644 --- a/tests/test_installer_status_doctor.py +++ b/tests/test_installer_status_doctor.py @@ -19,6 +19,7 @@ from installer.hosts.claude import CLAUDE_ADAPTER from installer.hosts.codex import CODEX_ADAPTER from installer.hosts.cursor import CURSOR_ADAPTER +from installer.hosts.qoder import QODER_ADAPTER from installer.inspection import build_doctor_payload, build_status_payload, render_doctor_text, render_status_text from installer.models import InstallError from installer.payload import _REQUIRED_BUNDLE_CAPABILITIES, install_global_payload, run_workspace_bootstrap @@ -135,6 +136,7 @@ def test_cursor_install_proves_split_paths_without_touching_settings(self) -> No self.assertNotIn("rules", manifest_payload) self.assertIn("adaptive workflow layer", readme.read_text(encoding="utf-8")) self.assertIn("BASELINE_SUPPORTED", readme.read_text(encoding="utf-8")) + self.assertTrue((skill_root / "SKILL.md").is_file()) self.assertTrue((skill_root / "analyze" / "SKILL.md").is_file()) self.assertTrue((skill_root / "design" / "SKILL.md").is_file()) self.assertTrue((skill_root / "develop" / "SKILL.md").is_file()) @@ -156,7 +158,7 @@ def test_cursor_install_proves_split_paths_without_touching_settings(self) -> No self.assertIn("alwaysApply: true", rule.read_text(encoding="utf-8")) self.assertIn("~/.cursor/skills/sopify/references/shared-writing-dna.md", rule.read_text(encoding="utf-8")) self.assertIn("Cursor IDE", rule.read_text(encoding="utf-8")) - self.assertIn("does not automatically load", rule.read_text(encoding="utf-8")) + self.assertIn("does not load a Plugin Rule by itself", rule.read_text(encoding="utf-8")) self.assertNotIn(str(skill_root), rule.read_text(encoding="utf-8")) self.assertIsNone(result.workspace_bootstrap) self.assertEqual(result.target.host, "cursor") @@ -216,6 +218,59 @@ def test_cursor_install_proves_split_paths_without_touching_settings(self) -> No self.assertEqual(repair_result.host_install.action, "updated") self.assertTrue(readme.is_file()) + def test_cursor_reinstall_replaces_stale_cli_entry_and_cleans_backup(self) -> None: + with tempfile.TemporaryDirectory() as home_dir: + home_root = Path(home_dir) + run_install( + target_value="cursor:zh-CN", + workspace_value=None, + repo_root=REPO_ROOT, + home_root=home_root, + ) + + skill_root = home_root / ".cursor" / "skills" / "sopify" + root_skill = skill_root / "SKILL.md" + stale_backup = skill_root / "SKILL.md.old" + root_skill.write_text("old local probe\n", encoding="utf-8") + stale_backup.write_text("stale backup\n", encoding="utf-8") + + updated = run_install( + target_value="cursor:zh-CN", + workspace_value=None, + repo_root=REPO_ROOT, + home_root=home_root, + ) + canonical = ( + REPO_ROOT / "skills" / "zh" / "cursor-cli-skill.md.template" + ).read_text(encoding="utf-8") + + self.assertEqual(updated.host_install.action, "updated") + self.assertEqual(root_skill.read_text(encoding="utf-8"), canonical) + self.assertFalse(stale_backup.exists()) + + repeated = run_install( + target_value="cursor:zh-CN", + workspace_value=None, + repo_root=REPO_ROOT, + home_root=home_root, + ) + self.assertEqual(repeated.host_install.action, "skipped") + + def test_cursor_cli_entry_is_not_installed_for_other_home_hosts(self) -> None: + for adapter in (CODEX_ADAPTER, CLAUDE_ADAPTER, QODER_ADAPTER): + with self.subTest(host=adapter.host_name), tempfile.TemporaryDirectory() as home_dir: + home_root = Path(home_dir) + install_host_assets( + adapter, + repo_root=REPO_ROOT, + home_root=home_root, + language_directory="CN", + ) + cursor_only_entry = ( + adapter.destination_root(home_root) / "skills" / "sopify" / "SKILL.md" + ) + self.assertFalse(cursor_only_entry.exists()) + def test_cursor_install_preflights_invalid_hooks_before_any_product_write(self) -> None: with tempfile.TemporaryDirectory() as home_dir, tempfile.TemporaryDirectory() as workspace_dir: home_root = Path(home_dir) diff --git a/tests/test_plan_contract_assets.py b/tests/test_plan_contract_assets.py index 617de36..0eadf36 100644 --- a/tests/test_plan_contract_assets.py +++ b/tests/test_plan_contract_assets.py @@ -160,7 +160,9 @@ def test_cursor_plugin_rule_uses_legal_frontmatter_and_thin_routing_contract(sel self.assertIn("consult_readonly", rendered) self.assertIn("IDE Entry" if language == "en" else "IDE 入口", rendered) self.assertIn( - "does not automatically load" if language == "en" else "不会自动加载", + "does not load a Plugin Rule by itself" + if language == "en" + else "不会自行加载 Plugin Rule", rendered, ) self.assertIn("~/.claude", rendered) diff --git a/zh-CN.html b/zh-CN.html index 000668e..9cedca9 100644 --- a/zh-CN.html +++ b/zh-CN.html @@ -245,7 +245,7 @@

先说最重要的

换宿主后能力完全一样吗? -

Codex、Claude 和 Qoder 已通过协议路径验证。Copilot 和 Cursor 为基线支持;Cursor 的 Plugin Rule 自动入口只适用于本地 IDE,不覆盖 Agent CLI 或 Cloud Agent。

+

Codex、Claude 和 Qoder 已通过协议路径验证。Copilot 和 Cursor 为基线支持;一次 Cursor 安装同时提供 IDE Plugin Rule 与本地 Agent CLI 的 best-effort managed 入口,Cloud Agent 仍不在范围内。

必须安装 EvidentLoop 吗? From bb645d1441b681f21bbd0ff1a0a1af7e6307b1b9 Mon Sep 17 00:00:00 2001 From: "sanze.li" Date: Sat, 29 Aug 2026 23:46:46 +0800 Subject: [PATCH 2/3] docs: clarify Cursor IDE and CLI support --- .sopify/blueprint/README.md | 2 +- CHANGELOG.md | 4 ++-- README.md | 2 +- README.zh-CN.md | 2 +- docs/cursor-host.md | 8 ++++---- docs/getting-started.md | 20 +++++++++++--------- docs/how-sopify-works.en.md | 2 +- docs/how-sopify-works.md | 2 +- index.html | 2 +- skills/en/cursor-plugin-readme.md.template | 20 ++++++++++---------- skills/zh/cursor-plugin-readme.md.template | 20 ++++++++++---------- tests/test_installer_status_doctor.py | 5 +++-- zh-CN.html | 2 +- 13 files changed, 47 insertions(+), 44 deletions(-) diff --git a/.sopify/blueprint/README.md b/.sopify/blueprint/README.md index 0fe07a5..7189453 100644 --- a/.sopify/blueprint/README.md +++ b/.sopify/blueprint/README.md @@ -13,7 +13,7 @@ ## 当前焦点 -- 当前活动 plan:`../plan/20260828_cursor_agent_cli_entry` 已完成 Cursor Agent CLI managed-first 顶层入口与一次安装产品化,本机安装和两轮 Cursor 独立审计通过,状态为 `ready_to_archive`;feat 分支 commit/push 已获授权,尚未 finalize、合并或发布。 +- 当前活动 plan:`../plan/20260828_cursor_agent_cli_entry` 已完成 Cursor IDE + 本地 CLI 一次安装,以及 CLI 方案/开发/接续入口;本机安装和两轮 Cursor 独立审计通过,状态为 `ready_to_archive`。feat 分支已提交并 push,PR #73 已创建;尚未 finalize、合并或发布。 - MCP tool plane 已完成 Codex-first 持久注册验证和 Claude 会话级只读调用验证,Qoder / Claude / Copilot 的后续持久注册仍按证据推进。 - P8 Protocol Kernel & Runtime Retirement 已归档至 `../history/2026-06/20260605_p8_protocol_kernel_runtime_retirement`。 - history 归档:已可用;最近归档:`../history/2026-07/20260720_plain_language_output`。 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7db1764..e86edb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,11 @@ Format: Summary → Changed → Plan Packages. File-level details live in `git l ### Summary -Extended the existing Cursor user-scope installation with a managed-first entry for local Agent CLI. +Extended the existing Cursor user-scope installation so one install covers the IDE and local Agent CLI. ### Changed -- **Cursor Agent CLI**: Added bilingual top-level Skills that read the installed Plugin Rule for managed requests, kept automatic model selection best-effort, and preserved separate IDE/CLI behavior evidence. +- **Cursor Agent CLI**: Added bilingual top-level Skills for plan, development, and resume requests. The CLI selects the entry when relevant, reads the installed Plugin Rule, and keeps IDE/CLI behavior evidence separate. - **Cursor installation**: The existing `cursor:` target now installs and verifies the CLI entry, replaces stale local copies on reinstall, and keeps settings, proxy, model, account, and Cloud Agent out of scope. ### Plan Packages diff --git a/README.md b/README.md index 07769ad..1589833 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,7 @@ Host support: | Claude | PROTOCOL_VERIFIED | `claude:en-US` / `claude:zh-CN` | Full capability continuation | | Qoder | PROTOCOL_VERIFIED | `qoder` | Validated on Qoder CLI | | Copilot | BASELINE_SUPPORTED | `copilot:en-US` / `copilot:zh-CN` | Prompt-only; payload uplift planned | -| [Cursor](docs/cursor-host.md) | BASELINE_SUPPORTED | `cursor:en-US` / `cursor:zh-CN` | IDE user Plugin + managed-first CLI entry + shared Skills/payload/hooks | +| [Cursor](docs/cursor-host.md) | BASELINE_SUPPORTED | `cursor:en-US` / `cursor:zh-CN` | One install for IDE and local CLI; plan/development/resume/closeout entry is model-selected | Pass `--workspace ` to target another repo for workspace-scope or prewarm installs; Cursor installs once at user scope and does not require it. Use `--language ` to control output language. diff --git a/README.zh-CN.md b/README.zh-CN.md index 8b94efa..80afdf7 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -137,7 +137,7 @@ Get-Content sopify-install.ps1 | more | Claude | PROTOCOL_VERIFIED | `claude:zh-CN` / `claude:en-US` | 全能力接续 | | Qoder | PROTOCOL_VERIFIED | `qoder` | 已在 Qoder CLI 验证 | | Copilot | BASELINE_SUPPORTED | `copilot:zh-CN` / `copilot:en-US` | 仅 prompt;payload 升级计划中 | -| [Cursor](docs/cursor-host.md) | BASELINE_SUPPORTED | `cursor:zh-CN` / `cursor:en-US` | IDE 用户 Plugin + managed-first CLI 入口 + 共享 Skills/payload/Hooks | +| [Cursor](docs/cursor-host.md) | BASELINE_SUPPORTED | `cursor:zh-CN` / `cursor:en-US` | 一次安装支持 IDE 与本地 CLI;CLI 方案/开发/接续/收口入口按需触发 | 可用 `--workspace ` 指定目标仓库,`--language ` 控制输出语言;Cursor 为用户级一次安装,不需要 `--workspace`。 diff --git a/docs/cursor-host.md b/docs/cursor-host.md index b099f25..dcdcd33 100644 --- a/docs/cursor-host.md +++ b/docs/cursor-host.md @@ -1,6 +1,6 @@ # Cursor 宿主接入 -支持本地 Cursor IDE 与 Agent CLI,Cloud Agent 不在本期范围。IDE 通过用户级 Always Plugin Rule 进入;Agent CLI 默认安装 managed-first 顶层 Skill,被模型选中后实际读取同一 Rule。CLI 自动选择属于 best-effort,支持档位保持 `BASELINE_SUPPORTED`;本期不增加 launcher、项目 Rule 或 runtime,也不把安装存在外推为跨模型稳定性或完整协议认证。 +Cursor 安装一次即可支持本地 IDE 与 Agent CLI,Cloud Agent 不在本期范围。IDE 始终通过用户级 Plugin Rule 进入;CLI 在方案、开发、继续和收口等 Sopify 请求中按需选择顶层 Skill,再读取同一 Rule。普通问答不强制经过该入口。支持档位保持 `BASELINE_SUPPORTED`;本期不增加 launcher、项目 Rule 或 runtime,也不把安装成功外推为跨模型稳定性或完整协议认证。 ## 安装面 @@ -13,7 +13,7 @@ curl -fsSL https://github.com/evidentloop/sopify/releases/latest/download/instal 安装一次,管理四个用户级落点: - Plugin:`~/.cursor/plugins/local/sopify/.cursor-plugin/plugin.json`、`README.md` 与 `rules/sopify.mdc`。README 渐进介绍用途与边界;薄 Always Rule 是 IDE 的语义入口。 -- Skills:`~/.cursor/skills/sopify/SKILL.md` 是 Agent CLI 的 managed-first 顶层入口;同目录下的 `analyze`、`design`、`develop`、`kb`、`templates` 和共享 references 由 IDE 与 CLI 共用。 +- Skills:`~/.cursor/skills/sopify/SKILL.md` 是 Agent CLI 的方案/开发/接续入口;同目录下的 `analyze`、`design`、`develop`、`kb`、`templates` 和共享 references 由 IDE 与 CLI 共用。 - Payload:`~/.cursor/sopify/`,包含版本化 bundle 与 Hook helper。 - Hooks:合并到 `~/.cursor/hooks.json`;不写仓库级 hooks。 @@ -61,10 +61,10 @@ IDE 与 CLI 分开记录,不互相外推: 1. IDE baseline 已有可观察证据:已安装 Rule 含 `alwaysApply: true`,consult 实际读取 Cursor 写作规范并保持只读;Analyze 读取 Cursor Skill 并执行评分脚本;有限选项澄清留下 AskQuestion tool use 与 `Tool not found` 文本回退,结构化问卷 UI 仅作为人工观察,transcript 不含 tool result 或选项回传;managed 场景按 Analyze → Design → Develop 推进,经 `sopify_writer` 写 state、handoff 与 receipts;明显 Shell 直写 machine truth 被 Hook 拒绝且文件哈希不变。 2. IDE 未验证边界:AskQuestion 是否跨模型稳定提供、独立 `sessionStart` 行为与显式 finalize。本期依赖文本追问回退和现有协议边界,不把这些项目作为 baseline 发布阻塞。 -3. CLI 已观察到 managed 审计请求自动选择顶层 Skill、读取 Plugin Rule,并在修正 description 读取顺序后通过独立 Cursor 复审。该证据只证明当前本机路径,不承诺每个普通请求、所有模型或所有机器都会自动选择。 +3. CLI 已观察到方案审计请求自动选择顶层 Skill、读取 Plugin Rule,并在修正 description 读取顺序后通过独立 Cursor 复审。该证据只证明当前本机路径,不承诺每个普通请求、所有模型或所有机器都会自动选择。 Cursor CLI 不会自行加载用户 Plugin Rule;Sopify 通过默认安装的顶层 Skill 显式读取该 Rule,不依赖 `--plugin-dir`、项目 Rule 或 prompt injector。Skill 发现和模型选择仍是宿主行为,因此 Doctor 继续把安装事实与 `cursor_cli_behavior` 黑盒证据分开。 -一次临时仓库黑盒已观察到四步读链、managed develop 与 `sopify_writer` 写回;本机顶层 Skill 复审又观察到 managed 请求自动选择和 Rule 消费。显式 finalize、跨模型一致性与可移植黑盒仍未完整认证;Doctor 的行为项继续保持静态 `BLACK_BOX_NOT_VERIFIED`。 +一次临时仓库黑盒已观察到四步读链、受管开发与 `sopify_writer` 写回;本机顶层 Skill 复审又观察到方案类请求按需选择入口并读取 Rule。显式 finalize、跨模型一致性与可移植黑盒仍未完整认证;Doctor 的行为项继续保持静态 `BLACK_BOX_NOT_VERIFIED`。 官方依据:[`Cursor Plugins`](https://cursor.com/docs/plugins)、[`Plugin format`](https://cursor.com/docs/reference/plugins)、[`Cursor Rules`](https://cursor.com/docs/rules)、[`Cursor Agent Skills`](https://cursor.com/docs/skills)、[`Cursor Hooks`](https://cursor.com/docs/hooks)、[`Cursor CLI`](https://cursor.com/docs/cli/using)。 diff --git a/docs/getting-started.md b/docs/getting-started.md index 74b6eb7..68010a4 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -141,9 +141,10 @@ release. ### Cursor IDE and local Agent CLI -Cursor IDE uses one user-level Plugin rule. The same installation provides a -managed-first Agent CLI entry, the shared Skill/payload tree under `~/.cursor/`, -and user-level hooks in `~/.cursor/hooks.json`: +One Cursor installation configures both local surfaces: the IDE gets a +user-level Plugin Rule, while Agent CLI gets a top-level Skill for plan, +development, resume, and closeout requests. Both share the phase Skills, +payload under `~/.cursor/`, and user Hooks in `~/.cursor/hooks.json`: ```bash curl -fsSL https://github.com/evidentloop/sopify/releases/latest/download/install.sh | bash -s -- --target cursor:en-US @@ -157,12 +158,13 @@ created during install. `--with-evidentloop` is not supported for Cursor in this release. The Plugin Rule uses valid `.mdc` frontmatter with `alwaysApply: true` and routes to `~/.cursor/skills/sopify`. -Agent CLI does not load the user Plugin Rule by itself. The installed top-level -`~/.cursor/skills/sopify/SKILL.md` is a managed-first, model-selected entry that -reads the Rule before routing phase Skills. Selection is best-effort; ordinary -questions do not have to trigger it, and Cloud Agent remains outside this -release. No launcher, project Rule, prompt injector, or runtime is added. See -[Cursor host acceptance](./cursor-host.md). The tier remains `BASELINE_SUPPORTED`. +Agent CLI does not load the user Plugin Rule by itself. For a Sopify workflow +request, Cursor may select `~/.cursor/skills/sopify/SKILL.md`; that entry reads +the Rule before routing phase Skills. Ordinary questions do not have to use +this path, and selection is not promised to behave identically across models. +Cloud Agent remains outside this release. No launcher, project Rule, prompt +injector, or runtime is added. See [Cursor host acceptance](./cursor-host.md). +The tier remains `BASELINE_SUPPORTED`. ## Verify Setup diff --git a/docs/how-sopify-works.en.md b/docs/how-sopify-works.en.md index c7969b0..078f51e 100644 --- a/docs/how-sopify-works.en.md +++ b/docs/how-sopify-works.en.md @@ -109,7 +109,7 @@ Layer notes: | Claude | PROTOCOL_VERIFIED | `install.sh --target claude:en-US` | Full capability continuation | | Qoder | PROTOCOL_VERIFIED | `install.sh --target qoder` | Validated on Qoder CLI | | Copilot | BASELINE_SUPPORTED | `install.sh --target copilot` | Prompt-only; payload uplift planned | -| Cursor | BASELINE_SUPPORTED | `install.sh --target cursor:en-US` | IDE user Plugin + managed-first CLI entry + shared Skills/payload/hooks | +| Cursor | BASELINE_SUPPORTED | `install.sh --target cursor:en-US` | One install for IDE and local CLI; plan/development/resume/closeout entry is model-selected | ## Appendix: Plan Lifecycle diff --git a/docs/how-sopify-works.md b/docs/how-sopify-works.md index e187b06..ae97b63 100644 --- a/docs/how-sopify-works.md +++ b/docs/how-sopify-works.md @@ -109,7 +109,7 @@ Sopify 不默认安装或运行验证器。只用 Sopify、使用其他 Verifier | Claude | PROTOCOL_VERIFIED | `install.sh --target claude:zh-CN` | 全能力接续 | | Qoder | PROTOCOL_VERIFIED | `install.sh --target qoder` | 已在 Qoder CLI 验证 | | Copilot | BASELINE_SUPPORTED | `install.sh --target copilot` | 仅 prompt;payload 升级计划中 | -| Cursor | BASELINE_SUPPORTED | `install.sh --target cursor:zh-CN` | IDE 用户 Plugin + managed-first CLI 入口 + 共享 Skills/payload/Hooks | +| Cursor | BASELINE_SUPPORTED | `install.sh --target cursor:zh-CN` | 一次安装支持 IDE 与本地 CLI;CLI 方案/开发/接续/收口入口按需触发 | ## 附录:Plan 生命周期 diff --git a/index.html b/index.html index 4ebb905..49c3b29 100644 --- a/index.html +++ b/index.html @@ -252,7 +252,7 @@

The short version

Does switching hosts give every host identical capabilities? -

Codex, Claude, and Qoder have protocol-verified paths. Copilot and Cursor are baseline-supported. One Cursor install provides the IDE Plugin Rule and a best-effort managed entry for local Agent CLI; Cloud Agent remains out of scope.

+

Codex, Claude, and Qoder have protocol-verified paths. Copilot and Cursor are baseline-supported. One Cursor install covers the IDE and local CLI; the CLI selects the plan, development, resume, and closeout entry when the request calls for it. Cloud Agent remains out of scope.

Is EvidentLoop required? diff --git a/skills/en/cursor-plugin-readme.md.template b/skills/en/cursor-plugin-readme.md.template index cb045af..c484ba7 100644 --- a/skills/en/cursor-plugin-readme.md.template +++ b/skills/en/cursor-plugin-readme.md.template @@ -1,20 +1,20 @@ # Sopify -Sopify is an adaptive workflow layer for Cursor IDE and local Agent CLI. It routes each request to the smallest appropriate path—read-only consultation, quick fix, analysis, design, or managed development—while keeping evidence and project-state boundaries explicit. +One installation lets Sopify serve both Cursor IDE and local Agent CLI. The IDE loads the user-level Rule automatically; the CLI selects a top-level Skill for plan, development, resume, and closeout requests, then reads the same Rule. ## Use Sopify -Describe the goal naturally. Sopify uses the current repository's instructions and `.sopify/` context, then loads only the relevant Skill. For explicit phase control, invoke the installed `/analyze`, `/design`, or `/develop` Skill. +- **In the IDE**: describe the goal naturally. The Always Rule classifies intent and loads the phase Skills that are needed. +- **In the CLI**: describe a plan, development, or resume goal directly. Ordinary questions do not have to enter Sopify; for explicit phase control, `/analyze`, `/design`, and `/develop` remain available. -## How it works +## Shared capabilities -- **IDE Always Rule** classifies intent and routes requests in Cursor IDE. -- **CLI top-level Skill** reads the same Rule for managed requests in local Agent CLI; model selection is best-effort. -- **Skills** provide the phase-specific procedures. -- **User Hooks** guard protocol state and receipt files against obvious direct writes; they are not a security sandbox. +- **Phase Skills** provide analysis, design, development, knowledge-base, and template procedures. +- **Payload** provides the versioned protocol and `sopify_writer`. +- **User Hooks** reject obvious direct writes to protocol state, handoff, and receipt files; they are not a security sandbox. ## Support boundary -- Cursor IDE uses the Always Rule. Cursor Agent CLI installs a managed-first top-level Skill by default and reuses the same phase Skills, payload, and user Hooks. -- Support remains `BASELINE_SUPPORTED`: IDE and CLI evidence stay separate, and Sopify does not promise that every ordinary request selects the top-level Skill, Cloud Agents, or identical behavior across models. -- Sopify does not modify Cursor settings, proxy, model, account, API keys, keychain, or MCP configuration. Cloud Agents are out of scope. +- Support remains `BASELINE_SUPPORTED`; IDE and CLI behavior evidence stays separate. +- The model selects the CLI entry based on the request. Identical behavior is not promised for ordinary questions, every model, or every machine. +- Sopify does not modify Cursor settings, proxy, model, account, API keys, keychain, or MCP. Cloud Agents are out of scope. diff --git a/skills/zh/cursor-plugin-readme.md.template b/skills/zh/cursor-plugin-readme.md.template index 2d8a024..d085eb4 100644 --- a/skills/zh/cursor-plugin-readme.md.template +++ b/skills/zh/cursor-plugin-readme.md.template @@ -1,20 +1,20 @@ # Sopify -Sopify 是 Cursor IDE 与本地 Agent CLI 的自适应工作流层。它先把请求路由到最小适用路径——只读咨询、快速修复、需求分析、方案设计或受管开发——并明确约束证据和项目状态边界。 +一次安装即可让 Sopify 同时服务于 Cursor IDE 与本地 Agent CLI。IDE 会自动加载用户级 Rule;CLI 会在方案、开发、继续和收口等请求中按需选择顶层 Skill,再读取同一 Rule。 ## 使用方式 -直接用自然语言说明目标。Sopify 会结合当前仓库的项目指令与 `.sopify/` 上下文,只加载相关 Skill。需要明确指定阶段时,可以调用已安装的 `/analyze`、`/design` 或 `/develop` Skill。 +- **在 IDE 中**:直接用自然语言说明目标,Always Rule 会分类意图并加载需要的阶段 Skill。 +- **在 CLI 中**:直接描述方案、开发或接续目标。普通问答不强制进入 Sopify;需要明确指定阶段时,仍可调用 `/analyze`、`/design` 或 `/develop`。 -## 工作方式 +## 共用能力 -- **IDE Always Rule**:在 Cursor IDE 中分类意图并路由请求。 -- **CLI 顶层 Skill**:在本地 Agent CLI 中为 managed 请求读取同一 Rule;模型选择属于 best-effort。 -- **Skills**:提供各阶段的执行细则。 -- **用户级 Hooks**:对协议 state、handoff 与 receipt 提供明显直写保护;它们不是安全沙箱。 +- **阶段 Skills**:提供分析、设计、开发、知识库和模板细则。 +- **Payload**:提供版本化协议与 `sopify_writer`。 +- **用户级 Hooks**:拒绝对协议 state、handoff 与 receipt 的明显直接写入;它们不是安全沙箱。 ## 支持边界 -- Cursor IDE 使用 Always Rule;Cursor Agent CLI 默认安装 managed-first 顶层 Skill,并复用同一阶段 Skills、payload 与用户 Hooks。 -- 当前支持档位为 `BASELINE_SUPPORTED`;IDE 与 CLI 证据分开记录,不承诺每个普通请求都选择顶层 Skill、Cloud Agent 或跨模型完全一致。 -- Sopify 不修改 Cursor settings、代理、模型、账号、API Key、钥匙串或 MCP 配置;不支持 Cloud Agent。 +- 当前支持档位为 `BASELINE_SUPPORTED`;IDE 与 CLI 的行为证据分开记录。 +- CLI 入口由模型按请求选择,不保证普通问答、所有模型或所有机器表现完全一致。 +- Sopify 不修改 Cursor settings、代理、模型、账号、API Key、钥匙串或 MCP;不支持 Cloud Agent。 diff --git a/tests/test_installer_status_doctor.py b/tests/test_installer_status_doctor.py index 3f859e1..6745bae 100644 --- a/tests/test_installer_status_doctor.py +++ b/tests/test_installer_status_doctor.py @@ -134,8 +134,9 @@ def test_cursor_install_proves_split_paths_without_touching_settings(self) -> No self.assertTrue(readme.is_file()) manifest_payload = json.loads(manifest.read_text(encoding="utf-8")) self.assertNotIn("rules", manifest_payload) - self.assertIn("adaptive workflow layer", readme.read_text(encoding="utf-8")) - self.assertIn("BASELINE_SUPPORTED", readme.read_text(encoding="utf-8")) + readme_text = readme.read_text(encoding="utf-8") + self.assertIn("Cursor IDE and local Agent CLI", readme_text) + self.assertIn("BASELINE_SUPPORTED", readme_text) self.assertTrue((skill_root / "SKILL.md").is_file()) self.assertTrue((skill_root / "analyze" / "SKILL.md").is_file()) self.assertTrue((skill_root / "design" / "SKILL.md").is_file()) diff --git a/zh-CN.html b/zh-CN.html index 9cedca9..e9f5cbf 100644 --- a/zh-CN.html +++ b/zh-CN.html @@ -245,7 +245,7 @@

先说最重要的

换宿主后能力完全一样吗? -

Codex、Claude 和 Qoder 已通过协议路径验证。Copilot 和 Cursor 为基线支持;一次 Cursor 安装同时提供 IDE Plugin Rule 与本地 Agent CLI 的 best-effort managed 入口,Cloud Agent 仍不在范围内。

+

Codex、Claude 和 Qoder 已通过协议路径验证。Copilot 和 Cursor 为基线支持;Cursor 安装一次即可覆盖 IDE 与本地 CLI,CLI 会在方案、开发、接续和收口类请求中按需选择入口。Cloud Agent 仍不在范围内。

必须安装 EvidentLoop 吗? From e1a91a360d0c0a76b54d147fdf5e0316812e75df Mon Sep 17 00:00:00 2001 From: "sanze.li" Date: Sat, 29 Aug 2026 23:51:43 +0800 Subject: [PATCH 3/3] test: align Cursor README contract --- tests/test_distribution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_distribution.py b/tests/test_distribution.py index 4403922..9e2a9b6 100644 --- a/tests/test_distribution.py +++ b/tests/test_distribution.py @@ -249,7 +249,7 @@ def test_cursor_distribution_reports_user_plugin_without_project_write(self) -> readme_path = rule_path.parent.parent / "README.md" self.assertIn(f"用户 Plugin 规则:{rule_path}", rendered) self.assertTrue(readme_path.is_file()) - self.assertIn("自适应工作流层", readme_path.read_text(encoding="utf-8")) + self.assertIn("Cursor IDE 与本地 Agent CLI", readme_path.read_text(encoding="utf-8")) self.assertIn("未修改任何项目目录", rendered) self.assertIn("Developer: Reload Window", rendered) self.assertIn("确认 Sopify Plugin 及其 Always Rule 已启用", rendered)