@blxzer/cursor-trellis 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +25 -14
  3. package/README.zh-CN.md +14 -10
  4. package/bin/smart-search.js +10 -2
  5. package/dist/cli/index.d.ts.map +1 -1
  6. package/dist/cli/index.js +36 -15
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/commands/init.d.ts +1 -1
  9. package/dist/commands/init.d.ts.map +1 -1
  10. package/dist/commands/init.js +42 -153
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/migrate.d.ts +10 -0
  13. package/dist/commands/migrate.d.ts.map +1 -0
  14. package/dist/commands/migrate.js +38 -0
  15. package/dist/commands/migrate.js.map +1 -0
  16. package/dist/commands/update.d.ts +5 -0
  17. package/dist/commands/update.d.ts.map +1 -1
  18. package/dist/commands/update.js +144 -41
  19. package/dist/commands/update.js.map +1 -1
  20. package/dist/configurators/cursor.d.ts +2 -1
  21. package/dist/configurators/cursor.d.ts.map +1 -1
  22. package/dist/configurators/cursor.js +4 -2
  23. package/dist/configurators/cursor.js.map +1 -1
  24. package/dist/configurators/index.js +4 -4
  25. package/dist/configurators/index.js.map +1 -1
  26. package/dist/configurators/shared.d.ts +8 -0
  27. package/dist/configurators/shared.d.ts.map +1 -1
  28. package/dist/configurators/shared.js +27 -1
  29. package/dist/configurators/shared.js.map +1 -1
  30. package/dist/configurators/workflow.d.ts +0 -9
  31. package/dist/configurators/workflow.d.ts.map +1 -1
  32. package/dist/configurators/workflow.js +12 -45
  33. package/dist/configurators/workflow.js.map +1 -1
  34. package/dist/constants/paths.d.ts +13 -0
  35. package/dist/constants/paths.d.ts.map +1 -1
  36. package/dist/constants/paths.js +17 -0
  37. package/dist/constants/paths.js.map +1 -1
  38. package/dist/migrations/manifests/0.3.0.json +1 -1
  39. package/dist/templates/common/bundled-skills/cstl-check/SKILL.md +1 -1
  40. package/dist/templates/common/bundled-skills/cstl-meta/references/platform-files/hooks-and-settings.md +2 -2
  41. package/dist/templates/common/bundled-skills/cstl-meta/references/platform-files/overview.md +1 -1
  42. package/dist/templates/common/bundled-skills/cstl-meta/references/platform-files/skills-and-commands.md +2 -4
  43. package/dist/templates/common/bundled-skills/cstl-skill-creator/SKILL.md +10 -7
  44. package/dist/templates/common/bundled-skills/cstl-skill-creator/references/authoring-rules.md +93 -19
  45. package/dist/templates/common/bundled-skills/cstl-skill-creator/references/general-authoring.md +189 -0
  46. package/dist/templates/common/bundled-skills/cstl-skill-creator/references/review-checklist.md +10 -5
  47. package/dist/templates/common/commands/continue.md +6 -5
  48. package/dist/templates/common/index.d.ts +20 -0
  49. package/dist/templates/common/index.d.ts.map +1 -1
  50. package/dist/templates/common/index.js +21 -2
  51. package/dist/templates/common/index.js.map +1 -1
  52. package/dist/templates/common/optional-skills/chrome-cdp/SKILL.md +179 -0
  53. package/dist/templates/common/optional-skills/chrome-cdp/examples/fetch-hook-api-capture.md +149 -0
  54. package/dist/templates/common/optional-skills/chrome-cdp/scripts/cdp.mjs +903 -0
  55. package/dist/templates/common/skills/brainstorm.md +2 -2
  56. package/dist/templates/cursor/agents/cstl-check.md +2 -2
  57. package/dist/templates/cursor/agents/cstl-implement.md +1 -1
  58. package/dist/templates/cursor/agents/cstl-research.md +2 -2
  59. package/dist/templates/cursor/fixtures/expected-rules.d.ts +1 -1
  60. package/dist/templates/cursor/fixtures/expected-rules.d.ts.map +1 -1
  61. package/dist/templates/cursor/fixtures/expected-rules.js +7 -24
  62. package/dist/templates/cursor/fixtures/expected-rules.js.map +1 -1
  63. package/dist/templates/cursor/hooks.json +4 -0
  64. package/dist/templates/cursor/index.d.ts +1 -1
  65. package/dist/templates/cursor/index.js +1 -1
  66. package/dist/templates/cursor/rules/cstl-bootstrap.mdc +17 -0
  67. package/dist/templates/markdown/agents.md +36 -3
  68. package/dist/templates/markdown/{spec/guides → framework}/cursor-native-modes-guide.md.txt +13 -10
  69. package/dist/templates/markdown/{spec/guides → framework}/cursor-subagent-policy.md.txt +63 -127
  70. package/dist/templates/markdown/framework/dogfood-only-surfaces.md.txt +29 -0
  71. package/dist/templates/markdown/{spec/guides → framework}/execution-strategy.md.txt +2 -0
  72. package/dist/templates/markdown/framework/index.md.txt +31 -0
  73. package/dist/templates/markdown/framework/internal-skills-cursor-reachability.md.txt +45 -0
  74. package/dist/templates/markdown/framework/middleware-protocol.md.txt +83 -0
  75. package/dist/templates/markdown/framework/parallel-first-execution.md.txt +78 -0
  76. package/dist/templates/markdown/framework/prd-grill-frontier.md.txt +83 -0
  77. package/dist/templates/markdown/framework/release-boundary.md.txt +30 -0
  78. package/dist/templates/markdown/{spec/guides → framework}/retrieval-daily-guide.md.txt +1 -1
  79. package/dist/templates/markdown/framework/upgrade.md.txt +15 -0
  80. package/dist/templates/markdown/{spec/guides → framework}/verification-strength-guide.md.txt +2 -2
  81. package/dist/templates/markdown/index.d.ts +26 -10
  82. package/dist/templates/markdown/index.d.ts.map +1 -1
  83. package/dist/templates/markdown/index.js +87 -11
  84. package/dist/templates/markdown/index.js.map +1 -1
  85. package/dist/templates/markdown/prompts/run-semantic-slice-12.md.txt +1 -1
  86. package/dist/templates/markdown/spec/guides/index.md.txt +5 -19
  87. package/dist/templates/markdown/spec/guides/prototype-guide.md.txt +10 -10
  88. package/dist/templates/markdown/spec/guides/test-discipline-guide.md.txt +1 -1
  89. package/dist/templates/shared-hooks/event-bridge.py +60 -0
  90. package/dist/templates/shared-hooks/index.d.ts +1 -1
  91. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  92. package/dist/templates/shared-hooks/index.js +1 -0
  93. package/dist/templates/shared-hooks/index.js.map +1 -1
  94. package/dist/templates/shared-hooks/session-start.py +19 -2
  95. package/dist/templates/trellis/CONTEXT.md +63 -3
  96. package/dist/templates/trellis/config.yaml +1 -1
  97. package/dist/templates/trellis/gitignore.txt +39 -39
  98. package/dist/templates/trellis/index.d.ts +12 -0
  99. package/dist/templates/trellis/index.d.ts.map +1 -1
  100. package/dist/templates/trellis/index.js +73 -15
  101. package/dist/templates/trellis/index.js.map +1 -1
  102. package/dist/templates/trellis/pool/README.md +12 -3
  103. package/dist/templates/trellis/pool/plan.md +24 -5
  104. package/dist/templates/trellis/scripts/common/adapter_middleware.py +158 -0
  105. package/dist/templates/trellis/scripts/common/artifact_locale.py +12 -3
  106. package/dist/templates/trellis/scripts/common/cursor_retrieval_env.py +5 -2
  107. package/dist/templates/trellis/scripts/common/full_quality.py +237 -0
  108. package/dist/templates/trellis/scripts/common/git.py +6 -0
  109. package/dist/templates/trellis/scripts/common/git_context.py +17 -5
  110. package/dist/templates/trellis/scripts/common/kernel_command.py +367 -0
  111. package/dist/templates/trellis/scripts/common/lite_context.py +280 -0
  112. package/dist/templates/trellis/scripts/common/ondemand_topology.py +225 -0
  113. package/dist/templates/trellis/scripts/common/parent_orchestration.py +1 -1
  114. package/dist/templates/trellis/scripts/common/pool_store.py +16 -4
  115. package/dist/templates/trellis/scripts/common/retrieval_agent_instructions.py +2 -2
  116. package/dist/templates/trellis/scripts/common/session_context.py +28 -2
  117. package/dist/templates/trellis/scripts/common/task_gates.py +73 -12
  118. package/dist/templates/trellis/scripts/common/task_map.py +42 -9
  119. package/dist/templates/trellis/scripts/common/task_store.py +293 -61
  120. package/dist/templates/trellis/scripts/common/test_adapter_middleware.py +56 -0
  121. package/dist/templates/trellis/scripts/common/test_depends_mode_block.py +9 -0
  122. package/dist/templates/trellis/scripts/common/test_full_quality.py +197 -0
  123. package/dist/templates/trellis/scripts/common/test_kernel_command.py +326 -0
  124. package/dist/templates/trellis/scripts/common/test_lite_path.py +190 -0
  125. package/dist/templates/trellis/scripts/common/test_observable_defaults.py +10 -4
  126. package/dist/templates/trellis/scripts/common/test_ondemand_topology.py +122 -0
  127. package/dist/templates/trellis/scripts/common/test_pool_store.py +17 -0
  128. package/dist/templates/trellis/scripts/common/test_task_store_kernel_patch.py +163 -0
  129. package/dist/templates/trellis/scripts/common/workflow_phase.py +3 -0
  130. package/dist/templates/trellis/scripts/cursor_retrieval_probe_prompt.md +4 -5
  131. package/dist/templates/trellis/scripts/get_context.py +1 -0
  132. package/dist/templates/trellis/scripts/pool.py +5 -0
  133. package/dist/templates/trellis/scripts/task.py +83 -7
  134. package/dist/templates/trellis/workflow.md +109 -23
  135. package/dist/utils/cursor-retrieval-env.d.ts +2 -1
  136. package/dist/utils/cursor-retrieval-env.d.ts.map +1 -1
  137. package/dist/utils/cursor-retrieval-env.js +3 -2
  138. package/dist/utils/cursor-retrieval-env.js.map +1 -1
  139. package/dist/utils/cursor2plus-residue-cleanup.d.ts +38 -0
  140. package/dist/utils/cursor2plus-residue-cleanup.d.ts.map +1 -0
  141. package/dist/utils/cursor2plus-residue-cleanup.js +145 -0
  142. package/dist/utils/cursor2plus-residue-cleanup.js.map +1 -0
  143. package/dist/utils/manifest-prune.d.ts.map +1 -1
  144. package/dist/utils/manifest-prune.js +7 -2
  145. package/dist/utils/manifest-prune.js.map +1 -1
  146. package/dist/utils/p36-upgrade.d.ts +62 -0
  147. package/dist/utils/p36-upgrade.d.ts.map +1 -0
  148. package/dist/utils/p36-upgrade.js +160 -0
  149. package/dist/utils/p36-upgrade.js.map +1 -0
  150. package/dist/utils/project-capabilities.d.ts +1 -12
  151. package/dist/utils/project-capabilities.d.ts.map +1 -1
  152. package/dist/utils/project-capabilities.js +3 -100
  153. package/dist/utils/project-capabilities.js.map +1 -1
  154. package/dist/utils/readiness.d.ts +10 -0
  155. package/dist/utils/readiness.d.ts.map +1 -1
  156. package/dist/utils/readiness.js +58 -26
  157. package/dist/utils/readiness.js.map +1 -1
  158. package/dist/utils/retrieval-agent-instructions.js +1 -1
  159. package/dist/utils/retrieval-agent-instructions.js.map +1 -1
  160. package/dist/utils/retrieval-execution-telemetry.js +1 -1
  161. package/dist/utils/retrieval-execution-telemetry.js.map +1 -1
  162. package/dist/utils/template-hash.d.ts.map +1 -1
  163. package/dist/utils/template-hash.js +11 -1
  164. package/dist/utils/template-hash.js.map +1 -1
  165. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
  166. package/dist/utils/uninstall-scrubbers.js +52 -14
  167. package/dist/utils/uninstall-scrubbers.js.map +1 -1
  168. package/dist/utils/update-rollout-report.d.ts +14 -0
  169. package/dist/utils/update-rollout-report.d.ts.map +1 -1
  170. package/dist/utils/update-rollout-report.js +1 -0
  171. package/dist/utils/update-rollout-report.js.map +1 -1
  172. package/dist/utils/workflow-ownership.d.ts +1 -1
  173. package/dist/utils/workflow-ownership.js +4 -4
  174. package/dist/utils/workflow-ownership.js.map +1 -1
  175. package/package.json +5 -4
  176. package/scripts/postinstall.js +6 -7
  177. package/dist/commands/campaign/canvas-render.d.ts +0 -68
  178. package/dist/commands/campaign/canvas-render.d.ts.map +0 -1
  179. package/dist/commands/campaign/canvas-render.js +0 -414
  180. package/dist/commands/campaign/canvas-render.js.map +0 -1
  181. package/dist/commands/campaign/compose.d.ts +0 -15
  182. package/dist/commands/campaign/compose.d.ts.map +0 -1
  183. package/dist/commands/campaign/compose.js +0 -110
  184. package/dist/commands/campaign/compose.js.map +0 -1
  185. package/dist/commands/campaign/index.d.ts +0 -13
  186. package/dist/commands/campaign/index.d.ts.map +0 -1
  187. package/dist/commands/campaign/index.js +0 -134
  188. package/dist/commands/campaign/index.js.map +0 -1
  189. package/dist/commands/campaign/kind-map.d.ts +0 -6
  190. package/dist/commands/campaign/kind-map.d.ts.map +0 -1
  191. package/dist/commands/campaign/kind-map.js +0 -21
  192. package/dist/commands/campaign/kind-map.js.map +0 -1
  193. package/dist/commands/campaign/mcp-server.d.ts +0 -6
  194. package/dist/commands/campaign/mcp-server.d.ts.map +0 -1
  195. package/dist/commands/campaign/mcp-server.js +0 -167
  196. package/dist/commands/campaign/mcp-server.js.map +0 -1
  197. package/dist/commands/campaign/render.d.ts +0 -5
  198. package/dist/commands/campaign/render.d.ts.map +0 -1
  199. package/dist/commands/campaign/render.js +0 -103
  200. package/dist/commands/campaign/render.js.map +0 -1
  201. package/dist/commands/campaign/trellis-load.d.ts +0 -13
  202. package/dist/commands/campaign/trellis-load.d.ts.map +0 -1
  203. package/dist/commands/campaign/trellis-load.js +0 -122
  204. package/dist/commands/campaign/trellis-load.js.map +0 -1
  205. package/dist/commands/campaign/types.d.ts +0 -61
  206. package/dist/commands/campaign/types.d.ts.map +0 -1
  207. package/dist/commands/campaign/types.js +0 -3
  208. package/dist/commands/campaign/types.js.map +0 -1
  209. package/dist/commands/goal/index.d.ts +0 -3
  210. package/dist/commands/goal/index.d.ts.map +0 -1
  211. package/dist/commands/goal/index.js +0 -159
  212. package/dist/commands/goal/index.js.map +0 -1
  213. package/dist/commands/goal/review.d.ts +0 -6
  214. package/dist/commands/goal/review.d.ts.map +0 -1
  215. package/dist/commands/goal/review.js +0 -28
  216. package/dist/commands/goal/review.js.map +0 -1
  217. package/dist/commands/rpc/client.d.ts +0 -51
  218. package/dist/commands/rpc/client.d.ts.map +0 -1
  219. package/dist/commands/rpc/client.js +0 -147
  220. package/dist/commands/rpc/client.js.map +0 -1
  221. package/dist/commands/rpc/index.d.ts +0 -10
  222. package/dist/commands/rpc/index.d.ts.map +0 -1
  223. package/dist/commands/rpc/index.js +0 -157
  224. package/dist/commands/rpc/index.js.map +0 -1
  225. package/dist/commands/rpc/serve.d.ts +0 -23
  226. package/dist/commands/rpc/serve.d.ts.map +0 -1
  227. package/dist/commands/rpc/serve.js +0 -60
  228. package/dist/commands/rpc/serve.js.map +0 -1
  229. package/dist/commands/rpc/smoke.d.ts +0 -16
  230. package/dist/commands/rpc/smoke.d.ts.map +0 -1
  231. package/dist/commands/rpc/smoke.js +0 -92
  232. package/dist/commands/rpc/smoke.js.map +0 -1
  233. package/dist/commands/sdk/index.d.ts +0 -9
  234. package/dist/commands/sdk/index.d.ts.map +0 -1
  235. package/dist/commands/sdk/index.js +0 -58
  236. package/dist/commands/sdk/index.js.map +0 -1
  237. package/dist/commands/sdk/run.d.ts +0 -42
  238. package/dist/commands/sdk/run.d.ts.map +0 -1
  239. package/dist/commands/sdk/run.js +0 -220
  240. package/dist/commands/sdk/run.js.map +0 -1
  241. package/dist/commands/sdk/status.d.ts +0 -14
  242. package/dist/commands/sdk/status.d.ts.map +0 -1
  243. package/dist/commands/sdk/status.js +0 -69
  244. package/dist/commands/sdk/status.js.map +0 -1
  245. package/dist/configurators/cursor2plus-local.d.ts +0 -6
  246. package/dist/configurators/cursor2plus-local.d.ts.map +0 -1
  247. package/dist/configurators/cursor2plus-local.js +0 -21
  248. package/dist/configurators/cursor2plus-local.js.map +0 -1
  249. package/dist/goal/action-packet.d.ts +0 -89
  250. package/dist/goal/action-packet.d.ts.map +0 -1
  251. package/dist/goal/action-packet.js +0 -113
  252. package/dist/goal/action-packet.js.map +0 -1
  253. package/dist/goal/audit.d.ts +0 -14
  254. package/dist/goal/audit.d.ts.map +0 -1
  255. package/dist/goal/audit.js +0 -12
  256. package/dist/goal/audit.js.map +0 -1
  257. package/dist/goal/constants.d.ts +0 -26
  258. package/dist/goal/constants.d.ts.map +0 -1
  259. package/dist/goal/constants.js +0 -24
  260. package/dist/goal/constants.js.map +0 -1
  261. package/dist/goal/paths.d.ts +0 -8
  262. package/dist/goal/paths.d.ts.map +0 -1
  263. package/dist/goal/paths.js +0 -36
  264. package/dist/goal/paths.js.map +0 -1
  265. package/dist/goal/preflight.d.ts +0 -21
  266. package/dist/goal/preflight.d.ts.map +0 -1
  267. package/dist/goal/preflight.js +0 -97
  268. package/dist/goal/preflight.js.map +0 -1
  269. package/dist/goal/review-seam.d.ts +0 -44
  270. package/dist/goal/review-seam.d.ts.map +0 -1
  271. package/dist/goal/review-seam.js +0 -153
  272. package/dist/goal/review-seam.js.map +0 -1
  273. package/dist/goal/reviewer-rules.d.ts +0 -13
  274. package/dist/goal/reviewer-rules.d.ts.map +0 -1
  275. package/dist/goal/reviewer-rules.js +0 -153
  276. package/dist/goal/reviewer-rules.js.map +0 -1
  277. package/dist/goal/reviewer.d.ts +0 -9
  278. package/dist/goal/reviewer.d.ts.map +0 -1
  279. package/dist/goal/reviewer.js +0 -54
  280. package/dist/goal/reviewer.js.map +0 -1
  281. package/dist/goal/runtime.d.ts +0 -32
  282. package/dist/goal/runtime.d.ts.map +0 -1
  283. package/dist/goal/runtime.js +0 -242
  284. package/dist/goal/runtime.js.map +0 -1
  285. package/dist/goal/sdk-client.d.ts +0 -10
  286. package/dist/goal/sdk-client.d.ts.map +0 -1
  287. package/dist/goal/sdk-client.js +0 -34
  288. package/dist/goal/sdk-client.js.map +0 -1
  289. package/dist/goal/state.d.ts +0 -40
  290. package/dist/goal/state.d.ts.map +0 -1
  291. package/dist/goal/state.js +0 -37
  292. package/dist/goal/state.js.map +0 -1
  293. package/dist/goal/task-triggers.d.ts +0 -15
  294. package/dist/goal/task-triggers.d.ts.map +0 -1
  295. package/dist/goal/task-triggers.js +0 -23
  296. package/dist/goal/task-triggers.js.map +0 -1
  297. package/dist/goal/walls.d.ts +0 -12
  298. package/dist/goal/walls.d.ts.map +0 -1
  299. package/dist/goal/walls.js +0 -65
  300. package/dist/goal/walls.js.map +0 -1
  301. package/dist/goal/worker-prompt.d.ts +0 -13
  302. package/dist/goal/worker-prompt.d.ts.map +0 -1
  303. package/dist/goal/worker-prompt.js +0 -41
  304. package/dist/goal/worker-prompt.js.map +0 -1
  305. package/dist/goal/worker.d.ts +0 -42
  306. package/dist/goal/worker.d.ts.map +0 -1
  307. package/dist/goal/worker.js +0 -180
  308. package/dist/goal/worker.js.map +0 -1
  309. package/dist/templates/common/bundled-skills/cstl-cursor2plus-setup/SKILL.md +0 -63
  310. package/dist/templates/cursor/commands/cursor2plus-setup.md +0 -82
  311. package/dist/templates/cursor/rules/cstl-cursor-modes.mdc +0 -32
  312. package/dist/templates/cursor/rules/cstl-session-rename.mdc +0 -31
  313. package/dist/templates/cursor/rules/cstl-subagent-dispatch.mdc +0 -34
  314. package/dist/templates/cursor/rules/cstl-triage.mdc +0 -36
  315. package/dist/templates/cursor/rules/retrieval-routing.mdc +0 -78
  316. package/dist/templates/markdown/spec/guides/cursor-trellis-release-coexistence-guide.md.txt +0 -166
  317. package/dist/templates/markdown/spec/guides/goal-release-regression-runbook.md.txt +0 -132
  318. package/dist/templates/trellis/local/README.md +0 -85
  319. package/dist/templates/trellis/local/config.local.json.example +0 -6
  320. package/dist/templates/trellis/local/index.d.ts +0 -8
  321. package/dist/templates/trellis/local/index.d.ts.map +0 -1
  322. package/dist/templates/trellis/local/index.js +0 -15
  323. package/dist/templates/trellis/local/index.js.map +0 -1
  324. package/dist/templates/trellis/local/patch_wpelc8.py +0 -421
  325. package/dist/templates/trellis/local/smoke.py +0 -94
  326. package/dist/templates/trellis/local/subagent-models.json.example +0 -4
  327. package/dist/templates/trellis/local/trellis-task-models.json.example +0 -10
  328. package/dist/templates/trellis/local/trellis-task-models.json5.example +0 -45
  329. package/dist/templates/trellis/local/trellis_task_models_config.py +0 -200
  330. package/dist/utils/cursor-sdk-gate.d.ts +0 -10
  331. package/dist/utils/cursor-sdk-gate.d.ts.map +0 -1
  332. package/dist/utils/cursor-sdk-gate.js +0 -32
  333. package/dist/utils/cursor-sdk-gate.js.map +0 -1
  334. /package/dist/templates/markdown/{spec/guides → framework}/artifact-locale-guide.md.txt +0 -0
  335. /package/dist/templates/markdown/{spec/guides → framework}/cursor-context-injection-guide.md.txt +0 -0
  336. /package/dist/templates/markdown/{spec/guides → framework}/cursor-semantic-compliance.md.txt +0 -0
  337. /package/dist/templates/markdown/{spec/guides → framework}/injection-budget-guide.md.txt +0 -0
@@ -1,421 +0,0 @@
1
- """Trellis: reversible Cursor++ WPeLc8 subagent model map (BYOK). See README.md."""
2
- from __future__ import annotations
3
-
4
- import argparse
5
- import json
6
- import os
7
- import sys
8
- from pathlib import Path
9
-
10
- from trellis_task_models_config import (
11
- KNOWN_SUBAGENT_TYPES,
12
- SUBAGENT_TYPE_HELP,
13
- extract_raw_slots,
14
- load_providers_catalog,
15
- load_task_models_document,
16
- resolve_slots_to_slugs,
17
- )
18
-
19
- MARKER = "/*TRELLIS_B2_WPeLc8*/"
20
- INJECT_NEEDLE = "});return!UbAQWn||"
21
-
22
-
23
- def _repo_root(start: Path) -> Path:
24
- cur = start.resolve()
25
- for _ in range(12):
26
- if (cur / ".cstl").is_dir():
27
- return cur
28
- if cur.parent == cur:
29
- break
30
- cur = cur.parent
31
- return start.resolve()
32
-
33
-
34
- def _merge_slot_maps(*layers: dict[str, list[str]]) -> dict[str, list[str]]:
35
- merged: dict[str, list[str]] = {}
36
- for layer in layers:
37
- for k, v in layer.items():
38
- merged[k] = list(v)
39
- return merged
40
-
41
-
42
- def _ccursor_home(config: dict) -> Path:
43
- for key in ("ccursorHome", "ccursor_home"):
44
- if isinstance(config.get(key), str) and config[key].strip():
45
- return Path(config[key].strip()).expanduser()
46
- env = os.environ.get("TRELLIS_CCURSOR_HOME", "").strip()
47
- if env:
48
- return Path(env).expanduser()
49
- return Path.home() / ".ccursor"
50
-
51
-
52
- def _load_config(bundle_dir: Path) -> dict:
53
- cfg_path = bundle_dir / "config.local.json"
54
- if not cfg_path.is_file():
55
- return {}
56
- try:
57
- data = json.loads(cfg_path.read_text(encoding="utf-8"))
58
- return data if isinstance(data, dict) else {}
59
- except (OSError, json.JSONDecodeError):
60
- return {}
61
-
62
-
63
- def resolve_providers_json(config: dict) -> Path:
64
- for key in ("providersJson", "providers_json"):
65
- if isinstance(config.get(key), str) and config[key].strip():
66
- return Path(config[key].strip()).expanduser()
67
- env = os.environ.get("TRELLIS_CCURSOR_PROVIDERS", "").strip()
68
- if env:
69
- return Path(env).expanduser()
70
- return _ccursor_home(config) / "providers.json"
71
-
72
-
73
- def _first_existing(*paths: Path) -> Path | None:
74
- for p in paths:
75
- if p.is_file():
76
- return p
77
- return None
78
-
79
-
80
- def resolve_user_models_path(config: dict) -> Path:
81
- ccursor = _ccursor_home(config)
82
- if isinstance(config.get("userModelsJson"), str) and config["userModelsJson"].strip():
83
- return Path(config["userModelsJson"].strip()).expanduser()
84
- found = _first_existing(
85
- ccursor / "trellis-task-models.json5",
86
- ccursor / "trellis-task-models.json",
87
- )
88
- return found or (ccursor / "trellis-task-models.json5")
89
-
90
-
91
- def resolve_project_models_path(bundle_dir: Path, config: dict) -> Path | None:
92
- root = _repo_root(bundle_dir)
93
- if isinstance(config.get("projectModelsJson"), str) and config["projectModelsJson"].strip():
94
- p = Path(config["projectModelsJson"].strip()).expanduser()
95
- return p if p.is_file() else None
96
- return _first_existing(
97
- root / ".cstl" / "local" / "subagent-models.json5",
98
- root / ".cstl" / "local" / "subagent-models.json",
99
- )
100
-
101
-
102
- def resolve_model_layers(bundle_dir: Path, config: dict, providers_path: Path) -> tuple[dict[str, str], list[str]]:
103
- user_path = resolve_user_models_path(config)
104
- project_path = resolve_project_models_path(bundle_dir, config)
105
- user_slots = extract_raw_slots(load_task_models_document(user_path))
106
- project_slots = (
107
- extract_raw_slots(load_task_models_document(project_path))
108
- if project_path
109
- else {}
110
- )
111
- merged = _merge_slot_maps(user_slots, project_slots)
112
- return resolve_slots_to_slugs(merged, providers_path)
113
-
114
-
115
- def configured_slot_map(bundle_dir: Path, config: dict) -> dict[str, list[str]]:
116
- """Non-secret role → [primary, fallback, …] from JSON5 only (no providers.json read)."""
117
- user_path = resolve_user_models_path(config)
118
- project_path = resolve_project_models_path(bundle_dir, config)
119
- user_slots = extract_raw_slots(load_task_models_document(user_path))
120
- project_slots = (
121
- extract_raw_slots(load_task_models_document(project_path))
122
- if project_path
123
- else {}
124
- )
125
- return _merge_slot_maps(user_slots, project_slots)
126
-
127
-
128
- def _extension_candidates(config: dict) -> list[Path]:
129
- for key in ("extensionJs", "extension_js"):
130
- if isinstance(config.get(key), str) and config[key].strip():
131
- return [Path(config[key].strip()).expanduser()]
132
- env = os.environ.get("TRELLIS_CURSOR2PLUS_EXTENSION", "").strip()
133
- if env:
134
- return [Path(env).expanduser()]
135
- if sys.platform == "win32":
136
- local = os.environ.get("LOCALAPPDATA", "")
137
- return [
138
- Path(local) / "Programs" / "cursor" / "resources" / "app" / "extensions" / "cursor2plus" / "dist" / "extension.js",
139
- Path(r"D:\cursor\resources\app\extensions\cursor2plus\dist\extension.js"),
140
- ]
141
- if sys.platform == "darwin":
142
- return [
143
- Path("/Applications/Cursor.app/Contents/Resources/app/extensions/cursor2plus/dist/extension.js"),
144
- ]
145
- return [
146
- Path.home() / ".local" / "share" / "cursor" / "resources" / "app" / "extensions" / "cursor2plus" / "dist" / "extension.js",
147
- ]
148
-
149
-
150
- def resolve_extension_js(bundle_dir: Path, config: dict) -> Path:
151
- for c in _extension_candidates(config):
152
- if c.is_file():
153
- return c
154
- raise SystemExit(
155
- "extension.js not found. Set extensionJs in config.local.json or run --bootstrap"
156
- )
157
-
158
-
159
- def try_resolve_extension_js(bundle_dir: Path, config: dict) -> Path | None:
160
- for c in _extension_candidates(config):
161
- if c.is_file():
162
- return c
163
- return None
164
-
165
-
166
- def build_inject_block(model_map: dict[str, str]) -> str:
167
- if not model_map:
168
- raise SystemExit(
169
- "model map empty — use skill cstl-cursor2plus-setup or write "
170
- "~/.ccursor/trellis-task-models.json5 (see .cstl/local/trellis-task-models.json5.example)"
171
- )
172
- pairs = ",".join(f'"{k}":"{v}"' for k, v in sorted(model_map.items()))
173
- return (
174
- f"{MARKER}{{const __T={{{pairs}}};const __m=__T[fQ4YPip];"
175
- "if(__m&&(!UbAQWn||UbAQWn[Vyazt1(gvQ2P56[0x24a3])][Vyazt1(gvQ2P56[0x204e])]"
176
- "===Vyazt1(gvQ2P56[0x2cda])))return __m;}"
177
- )
178
-
179
-
180
- def find_wpelc8_body(source: str) -> tuple[int, int]:
181
- start = source.find("function WPeLc8(")
182
- if start < 0:
183
- raise SystemExit("WPeLc8 not found — Cursor++/extension version mismatch?")
184
- end = source.find("async function*o4ZNpa", start)
185
- if end < 0:
186
- raise SystemExit("WPeLc8 end anchor not found")
187
- return start, end
188
-
189
-
190
- def probe_wpelc8_compat(source: str) -> dict[str, str]:
191
- """Non-exiting WPeLc8 / inject-anchor probe for --check-compat and smoke."""
192
- start = source.find("function WPeLc8(")
193
- if start < 0:
194
- return {"wpelc8": "not_locatable", "inject_anchor": "unknown", "end_anchor": "unknown"}
195
- end = source.find("async function*o4ZNpa", start)
196
- if end < 0:
197
- return {"wpelc8": "locatable", "inject_anchor": "unknown", "end_anchor": "missing"}
198
- fn = source[start:end]
199
- anchor = "present" if INJECT_NEEDLE in fn else "missing"
200
- return {"wpelc8": "locatable", "inject_anchor": anchor, "end_anchor": "present"}
201
-
202
-
203
- def apply_patch(source: str, inject: str) -> str:
204
- start, end = find_wpelc8_body(source)
205
- fn = source[start:end]
206
- if MARKER in fn:
207
- fn = remove_patch_from_fn(fn)
208
- if INJECT_NEEDLE not in fn:
209
- raise SystemExit(f"inject anchor missing: {INJECT_NEEDLE!r}")
210
- fn_new = fn.replace(INJECT_NEEDLE, f"}});{inject}return!UbAQWn||", 1)
211
- return source[:start] + fn_new + source[end:]
212
-
213
-
214
- def remove_patch_from_fn(fn: str) -> str:
215
- import re
216
-
217
- return re.sub(
218
- re.escape(MARKER) + r"\{const __T=\{[^}]+\};const __m=__T\[fQ4YPip\];"
219
- r"if\(__m&&\(!UbAQWn\|\|UbAQWn\[Vyazt1\(gvQ2P56\[0x24a3\]\)\]\[Vyazt1\(gvQ2P56\[0x204e\]\)\]"
220
- r"===Vyazt1\(gvQ2P56\[0x2cda\]\)\)\)return __m;\}",
221
- "",
222
- fn,
223
- count=1,
224
- )
225
-
226
-
227
- def remove_patch(source: str) -> str:
228
- if MARKER not in source:
229
- raise SystemExit("marker not found — not patched?")
230
- start, end = find_wpelc8_body(source)
231
- fn = remove_patch_from_fn(source[start:end])
232
- return source[:start] + fn + source[end:]
233
-
234
-
235
- def cmd_explain() -> None:
236
- print("trellis-task-models.json5 — Agent 协助填写;用户只选模型名")
237
- print("每项: { primary, fallback } — 首选不可用则自动备选 (WARN)")
238
- print()
239
- for key in KNOWN_SUBAGENT_TYPES:
240
- print(f" {key}")
241
- print(f" → {SUBAGENT_TYPE_HELP.get(key, '')}")
242
- print()
243
- print("Skill: cstl-cursor2plus-setup (init 后与大模型交互完成配置)")
244
-
245
-
246
- def cmd_list_models(providers_path: Path) -> None:
247
- by_slug, _ = load_providers_catalog(providers_path)
248
- if not by_slug:
249
- raise SystemExit(f"no models in {providers_path}")
250
- print(f"# {providers_path}")
251
- print("# 给用户选 primary/fallback 时引用 apiModel 或 displayName")
252
- print()
253
- rows = sorted(by_slug.values(), key=lambda r: (str(r.get("provider")), str(r.get("displayName"))))
254
- for r in rows:
255
- print(
256
- f" {r.get('displayName')!r:28} apiModel={r.get('apiModel')!r:32} "
257
- f"slug={r.get('slug')} provider={r.get('provider')}"
258
- )
259
-
260
-
261
- def cmd_bootstrap(bundle_dir: Path) -> None:
262
- config = _load_config(bundle_dir)
263
- cfg_out = bundle_dir / "config.local.json"
264
- if not cfg_out.is_file():
265
- config = {}
266
- try:
267
- resolve_extension_js(bundle_dir, config)
268
- print("extension.js auto-detected", file=sys.stderr)
269
- except SystemExit:
270
- path = input("Paste full path to cursor2plus/dist/extension.js: ").strip()
271
- if path:
272
- config["extensionJs"] = path
273
- cfg_out.write_text(json.dumps(config, indent=2) + "\n", encoding="utf-8")
274
- print("wrote", cfg_out)
275
- print("Next: in Cursor Agent, run skill cstl-cursor2plus-setup", file=sys.stderr)
276
-
277
-
278
- def cmd_check_compat(bundle_dir: Path, config: dict) -> int:
279
- extension = try_resolve_extension_js(bundle_dir, config)
280
- result: dict[str, object] = {
281
- "extension": str(extension) if extension else None,
282
- "patch_marker_present": False,
283
- "wpelc8": "unknown",
284
- "inject_anchor": "unknown",
285
- "end_anchor": "unknown",
286
- }
287
- if extension is None:
288
- result["status"] = "unknown"
289
- result["hint"] = (
290
- "extension.js not found — set extensionJs in config.local.json or run --bootstrap; "
291
- "manual verification required"
292
- )
293
- print(json.dumps(result, indent=2, sort_keys=True))
294
- return 2
295
-
296
- source = extension.read_text(encoding="utf-8", errors="ignore")
297
- result["patch_marker_present"] = MARKER in source
298
- probe = probe_wpelc8_compat(source)
299
- result.update(probe)
300
-
301
- wpelc8 = probe["wpelc8"]
302
- anchor = probe["inject_anchor"]
303
- end_anchor = probe.get("end_anchor", "unknown")
304
-
305
- if wpelc8 == "not_locatable" or anchor == "missing":
306
- result["status"] = "fail"
307
- result["hint"] = (
308
- "WPeLc8 or inject anchor not found after Cursor/Cursor++ upgrade — "
309
- "re-run patch with --apply --approve or revert to inherit-parent"
310
- )
311
- elif wpelc8 == "unknown" or anchor == "unknown" or end_anchor == "unknown":
312
- result["status"] = "unknown"
313
- result["hint"] = "Locator uncertain — manually verify extension.js after any upgrade"
314
- else:
315
- result["status"] = "ok"
316
- result["hint"] = "WPeLc8 and inject anchor locatable"
317
-
318
- print(json.dumps(result, indent=2, sort_keys=True))
319
- return 0 if result["status"] == "ok" else (1 if result["status"] == "fail" else 2)
320
-
321
-
322
- def main() -> None:
323
- ap = argparse.ArgumentParser(
324
- description="Trellis Cursor++ WPeLc8 model map (Method 2.5)",
325
- epilog=(
326
- "Read-only: --print-map, --check-compat. "
327
- "Write: --apply --approve (or --revert). "
328
- "Never runs in CI by default."
329
- ),
330
- )
331
- ap.add_argument("--revert", action="store_true", help="Remove Trellis patch from extension.js")
332
- ap.add_argument("--apply", action="store_true", help="Apply patch to extension.js")
333
- ap.add_argument(
334
- "--approve",
335
- action="store_true",
336
- help="Explicit operator approval (required for --apply writes)",
337
- )
338
- ap.add_argument(
339
- "--dry-run",
340
- action="store_true",
341
- help="With --apply: validate patch without writing extension.js",
342
- )
343
- ap.add_argument("--bootstrap", action="store_true", help="Create config.local.json with extension path")
344
- ap.add_argument("--explain", action="store_true", help="Explain trellis-task-models.json5 keys")
345
- ap.add_argument("--list-models", action="store_true", help="List models from providers.json catalog")
346
- ap.add_argument("--print-map", action="store_true", help="Dry-run: print resolved slug map (no file writes)")
347
- ap.add_argument(
348
- "--check-compat",
349
- action="store_true",
350
- help="Check WPeLc8 locatability in current extension.js (no file writes)",
351
- )
352
- args = ap.parse_args()
353
-
354
- bundle_dir = Path(__file__).resolve().parent
355
- if args.explain:
356
- cmd_explain()
357
- return
358
- if args.bootstrap:
359
- cmd_bootstrap(bundle_dir)
360
- return
361
-
362
- config = _load_config(bundle_dir)
363
-
364
- if args.check_compat:
365
- raise SystemExit(cmd_check_compat(bundle_dir, config))
366
-
367
- providers_path = resolve_providers_json(config)
368
-
369
- if args.list_models:
370
- cmd_list_models(providers_path)
371
- return
372
-
373
- needs_map = args.print_map or args.apply or args.revert
374
- model_map: dict[str, str] = {}
375
- notes: list[str] = []
376
- if needs_map and not args.revert:
377
- model_map, notes = resolve_model_layers(bundle_dir, config, providers_path)
378
- if notes:
379
- print("resolve:", file=sys.stderr)
380
- for line in notes:
381
- print(line, file=sys.stderr)
382
- if any("ERROR" in line for line in notes):
383
- raise SystemExit(1)
384
-
385
- if args.print_map:
386
- print(json.dumps(model_map, indent=2, sort_keys=True))
387
- return
388
-
389
- if args.revert:
390
- extension = resolve_extension_js(bundle_dir, config)
391
- source = extension.read_text(encoding="utf-8", errors="ignore")
392
- new = remove_patch(source)
393
- extension.write_text(new, encoding="utf-8", newline="\n")
394
- print("wrote", extension)
395
- return
396
-
397
- if args.apply:
398
- if not args.approve and not args.dry_run:
399
- print(
400
- "refused: --apply writes extension.js and requires explicit --approve "
401
- "(use --dry-run to validate without writing)",
402
- file=sys.stderr,
403
- )
404
- raise SystemExit(1)
405
- extension = resolve_extension_js(bundle_dir, config)
406
- source = extension.read_text(encoding="utf-8", errors="ignore")
407
- inject = build_inject_block(model_map)
408
- new = apply_patch(source, inject)
409
- if args.dry_run:
410
- print("ok patch delta", len(new) - len(source))
411
- return
412
- extension.write_text(new, encoding="utf-8", newline="\n")
413
- print("wrote", extension)
414
- return
415
-
416
- ap.print_help()
417
- raise SystemExit(2)
418
-
419
-
420
- if __name__ == "__main__":
421
- main()
@@ -1,94 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Cursor++ local bundle smoke check — whitelist metadata only, no secret reads."""
3
- from __future__ import annotations
4
-
5
- import json
6
- import os
7
- import sys
8
- from pathlib import Path
9
-
10
- from patch_wpelc8 import (
11
- MARKER,
12
- _load_config,
13
- configured_slot_map,
14
- probe_wpelc8_compat,
15
- try_resolve_extension_js,
16
- )
17
-
18
- CAVEATS = [
19
- "Cursor++ is third-party; reverse-engineering is version-bound",
20
- "Never reads BYOK provider catalog file contents",
21
- "Patch is operator-only; not part of CI or default Trellis workflow",
22
- "Re-verify after any Cursor or Cursor++ upgrade",
23
- ]
24
-
25
-
26
- def detect_env() -> tuple[str, str | None]:
27
- env_flag = os.environ.get("TRELLIS_CURSOR_BYOK", "").strip()
28
- if env_flag == "1":
29
- return "byok", "TRELLIS_CURSOR_BYOK=1"
30
- if env_flag == "0":
31
- return "native", "TRELLIS_CURSOR_BYOK=0"
32
-
33
- routes = Path.home() / ".ccursor" / "routes.json"
34
- if routes.is_file():
35
- try:
36
- data = json.loads(routes.read_text(encoding="utf-8"))
37
- byok = data.get("byokMode")
38
- if byok in (1, "1", True):
39
- return "byok", "routes.json:byokMode"
40
- if byok in (0, "0", False):
41
- return "native", "routes.json:byokMode"
42
- except (OSError, json.JSONDecodeError, TypeError):
43
- pass
44
- return "unknown", None
45
-
46
-
47
- def detect_patch_status(bundle_dir: Path, config: dict) -> tuple[str, dict[str, object]]:
48
- extension = try_resolve_extension_js(bundle_dir, config)
49
- meta: dict[str, object] = {"extension": str(extension) if extension else None}
50
- if extension is None:
51
- return "not-applied", meta
52
-
53
- source = extension.read_text(encoding="utf-8", errors="ignore")
54
- marker_present = MARKER in source
55
- meta["patch_marker_present"] = marker_present
56
- probe = probe_wpelc8_compat(source)
57
- meta.update(probe)
58
-
59
- if not marker_present:
60
- return "not-applied", meta
61
-
62
- if probe["wpelc8"] == "not_locatable" or probe["inject_anchor"] == "missing":
63
- return "stale", meta
64
- if probe["wpelc8"] == "unknown" or probe["inject_anchor"] == "unknown":
65
- return "stale", meta
66
- return "applied", meta
67
-
68
-
69
- def main() -> int:
70
- bundle_dir = Path(__file__).resolve().parent
71
- config = _load_config(bundle_dir)
72
- env, env_source = detect_env()
73
- patch_status, patch_meta = detect_patch_status(bundle_dir, config)
74
- slots = configured_slot_map(bundle_dir, config)
75
-
76
- report = {
77
- "env": env,
78
- "env_source": env_source,
79
- "patch_status": patch_status,
80
- "patch_meta": patch_meta,
81
- "current_map": {
82
- "configured_roles": {
83
- role: {"candidates": names} for role, names in sorted(slots.items())
84
- },
85
- "note": "Role names from user JSON5 config only; slugs not resolved (no provider catalog read)",
86
- },
87
- "caveats": CAVEATS,
88
- }
89
- print(json.dumps(report, indent=2, sort_keys=True))
90
- return 0
91
-
92
-
93
- if __name__ == "__main__":
94
- raise SystemExit(main())
@@ -1,4 +0,0 @@
1
- {
2
- "_comment": "Optional repo overrides (~/.ccursor/trellis-task-models.json is user-wide). Same value rules: apiModel, displayName, or model-xxxxx slug. Project wins on same key.",
3
- "cstl-implement": "qwen3.6-plus"
4
- }
@@ -1,10 +0,0 @@
1
- {
2
- "_comment": "Copy to ~/.ccursor/trellis-task-models.json (Windows: %USERPROFILE%\\.ccursor\\). Values: use apiModel or displayName from Cursor++ — patch_wpelc8.py resolves to slug at patch time. Optional keys: omit types you do not use.",
3
- "_when_providers_change": "Run: python patch_wpelc8.py --list-models then fix this file and patch again.",
4
- "cstl-research": "glm-5.1",
5
- "cstl-implement": "qwen3.6-plus",
6
- "cstl-check": "qwen3.7-max",
7
- "generalPurpose": "gpt-5.5",
8
- "shell": "grok-composer-2.5-fast",
9
- "best-of-n-runner": "kimi-k2.7-code"
10
- }
@@ -1,45 +0,0 @@
1
- // Trellis + Cursor++ BYOK — Task 子代理模型路由(由 Agent 在 init 时协助填写)
2
- // 复制到: Windows %USERPROFILE%\.ccursor\trellis-task-models.json5
3
- // Linux/macOS ~/.ccursor/trellis-task-models.json5
4
- //
5
- // 用户:只说明「每个场景想用哪个模型」(Cursor++ 里显示的名字即可)
6
- // Agent:运行 list-models → 写入本文件(保留注释)→ patch_wpelc8.py
7
- //
8
- // primary / fallback:providers.json 变更时,首选解析失败会自动用备选(WARN,不中断)
9
- // Explore 子代理不在此文件 — 用 Cursor++ 面板单独选
10
-
11
- {
12
- "models": {
13
- // Trellis 调研(Task cstl-research)
14
- "cstl-research": {
15
- "primary": "glm-5.1",
16
- "fallback": "qwen3.7-max"
17
- },
18
-
19
- // Trellis 实现;Parent generate-child-prompt --mode subagent 默认派发此类型
20
- "cstl-implement": {
21
- "primary": "qwen3.6-plus",
22
- "fallback": "kimi-k2.7-code"
23
- },
24
-
25
- // Trellis 验收(Task cstl-check)
26
- "cstl-check": {
27
- "primary": "qwen3.7-max",
28
- "fallback": "glm-5.1"
29
- },
30
-
31
- // Cursor 内置 Task(可按需删掉不用的项)
32
- "generalPurpose": {
33
- "primary": "gpt-5.5",
34
- "fallback": "glm-5.1"
35
- },
36
- "shell": {
37
- "primary": "grok-composer-2.5-fast",
38
- "fallback": "gpt-5.5"
39
- },
40
- "best-of-n-runner": {
41
- "primary": "kimi-k2.7-code",
42
- "fallback": "qwen3.6-plus"
43
- }
44
- }
45
- }