@blxzer/cursor-trellis 0.4.2 → 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 (315) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +23 -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 +137 -40
  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 +2 -4
  33. package/dist/configurators/workflow.js.map +1 -1
  34. package/dist/constants/paths.d.ts +9 -0
  35. package/dist/constants/paths.d.ts.map +1 -1
  36. package/dist/constants/paths.js +13 -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-meta/references/platform-files/skills-and-commands.md +2 -4
  40. package/dist/templates/common/bundled-skills/cstl-skill-creator/SKILL.md +10 -7
  41. package/dist/templates/common/bundled-skills/cstl-skill-creator/references/authoring-rules.md +93 -19
  42. package/dist/templates/common/bundled-skills/cstl-skill-creator/references/general-authoring.md +189 -0
  43. package/dist/templates/common/bundled-skills/cstl-skill-creator/references/review-checklist.md +10 -5
  44. package/dist/templates/common/commands/continue.md +5 -4
  45. package/dist/templates/common/index.d.ts +20 -0
  46. package/dist/templates/common/index.d.ts.map +1 -1
  47. package/dist/templates/common/index.js +21 -2
  48. package/dist/templates/common/index.js.map +1 -1
  49. package/dist/templates/common/optional-skills/chrome-cdp/SKILL.md +179 -0
  50. package/dist/templates/common/optional-skills/chrome-cdp/examples/fetch-hook-api-capture.md +149 -0
  51. package/dist/templates/common/optional-skills/chrome-cdp/scripts/cdp.mjs +903 -0
  52. package/dist/templates/cursor/agents/cstl-research.md +1 -1
  53. package/dist/templates/cursor/fixtures/expected-rules.d.ts +1 -1
  54. package/dist/templates/cursor/fixtures/expected-rules.d.ts.map +1 -1
  55. package/dist/templates/cursor/fixtures/expected-rules.js +7 -24
  56. package/dist/templates/cursor/fixtures/expected-rules.js.map +1 -1
  57. package/dist/templates/cursor/hooks.json +4 -0
  58. package/dist/templates/cursor/index.d.ts +1 -1
  59. package/dist/templates/cursor/index.js +1 -1
  60. package/dist/templates/cursor/rules/cstl-bootstrap.mdc +17 -0
  61. package/dist/templates/markdown/agents.md +15 -10
  62. package/dist/templates/markdown/framework/cursor-native-modes-guide.md.txt +12 -9
  63. package/dist/templates/markdown/framework/cursor-subagent-policy.md.txt +62 -126
  64. package/dist/templates/markdown/framework/dogfood-only-surfaces.md.txt +4 -6
  65. package/dist/templates/markdown/framework/execution-strategy.md.txt +2 -0
  66. package/dist/templates/markdown/framework/index.md.txt +4 -0
  67. package/dist/templates/markdown/framework/internal-skills-cursor-reachability.md.txt +4 -3
  68. package/dist/templates/markdown/framework/middleware-protocol.md.txt +83 -0
  69. package/dist/templates/markdown/framework/parallel-first-execution.md.txt +78 -0
  70. package/dist/templates/markdown/framework/release-boundary.md.txt +30 -0
  71. package/dist/templates/markdown/framework/retrieval-daily-guide.md.txt +1 -1
  72. package/dist/templates/markdown/framework/upgrade.md.txt +15 -0
  73. package/dist/templates/markdown/index.d.ts +4 -0
  74. package/dist/templates/markdown/index.d.ts.map +1 -1
  75. package/dist/templates/markdown/index.js +17 -0
  76. package/dist/templates/markdown/index.js.map +1 -1
  77. package/dist/templates/markdown/spec/guides/index.md.txt +0 -6
  78. package/dist/templates/shared-hooks/event-bridge.py +60 -0
  79. package/dist/templates/shared-hooks/index.d.ts +1 -1
  80. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  81. package/dist/templates/shared-hooks/index.js +1 -0
  82. package/dist/templates/shared-hooks/index.js.map +1 -1
  83. package/dist/templates/shared-hooks/session-start.py +18 -1
  84. package/dist/templates/trellis/CONTEXT.md +63 -3
  85. package/dist/templates/trellis/gitignore.txt +39 -39
  86. package/dist/templates/trellis/index.d.ts +12 -0
  87. package/dist/templates/trellis/index.d.ts.map +1 -1
  88. package/dist/templates/trellis/index.js +73 -15
  89. package/dist/templates/trellis/index.js.map +1 -1
  90. package/dist/templates/trellis/pool/README.md +12 -3
  91. package/dist/templates/trellis/pool/plan.md +24 -5
  92. package/dist/templates/trellis/scripts/common/adapter_middleware.py +158 -0
  93. package/dist/templates/trellis/scripts/common/artifact_locale.py +12 -3
  94. package/dist/templates/trellis/scripts/common/cursor_retrieval_env.py +5 -2
  95. package/dist/templates/trellis/scripts/common/full_quality.py +237 -0
  96. package/dist/templates/trellis/scripts/common/git.py +6 -0
  97. package/dist/templates/trellis/scripts/common/git_context.py +17 -5
  98. package/dist/templates/trellis/scripts/common/kernel_command.py +367 -0
  99. package/dist/templates/trellis/scripts/common/lite_context.py +280 -0
  100. package/dist/templates/trellis/scripts/common/ondemand_topology.py +225 -0
  101. package/dist/templates/trellis/scripts/common/parent_orchestration.py +1 -1
  102. package/dist/templates/trellis/scripts/common/pool_store.py +16 -4
  103. package/dist/templates/trellis/scripts/common/retrieval_agent_instructions.py +2 -2
  104. package/dist/templates/trellis/scripts/common/session_context.py +28 -2
  105. package/dist/templates/trellis/scripts/common/task_gates.py +73 -12
  106. package/dist/templates/trellis/scripts/common/task_map.py +42 -9
  107. package/dist/templates/trellis/scripts/common/task_store.py +286 -56
  108. package/dist/templates/trellis/scripts/common/test_adapter_middleware.py +56 -0
  109. package/dist/templates/trellis/scripts/common/test_depends_mode_block.py +9 -0
  110. package/dist/templates/trellis/scripts/common/test_full_quality.py +197 -0
  111. package/dist/templates/trellis/scripts/common/test_kernel_command.py +326 -0
  112. package/dist/templates/trellis/scripts/common/test_lite_path.py +190 -0
  113. package/dist/templates/trellis/scripts/common/test_ondemand_topology.py +122 -0
  114. package/dist/templates/trellis/scripts/common/test_pool_store.py +17 -0
  115. package/dist/templates/trellis/scripts/common/test_task_store_kernel_patch.py +163 -0
  116. package/dist/templates/trellis/scripts/common/workflow_phase.py +3 -0
  117. package/dist/templates/trellis/scripts/get_context.py +1 -0
  118. package/dist/templates/trellis/scripts/pool.py +5 -0
  119. package/dist/templates/trellis/scripts/task.py +83 -7
  120. package/dist/templates/trellis/workflow.md +100 -18
  121. package/dist/utils/cursor-retrieval-env.d.ts +2 -1
  122. package/dist/utils/cursor-retrieval-env.d.ts.map +1 -1
  123. package/dist/utils/cursor-retrieval-env.js +3 -2
  124. package/dist/utils/cursor-retrieval-env.js.map +1 -1
  125. package/dist/utils/cursor2plus-residue-cleanup.d.ts +38 -0
  126. package/dist/utils/cursor2plus-residue-cleanup.d.ts.map +1 -0
  127. package/dist/utils/cursor2plus-residue-cleanup.js +145 -0
  128. package/dist/utils/cursor2plus-residue-cleanup.js.map +1 -0
  129. package/dist/utils/manifest-prune.d.ts.map +1 -1
  130. package/dist/utils/manifest-prune.js +7 -2
  131. package/dist/utils/manifest-prune.js.map +1 -1
  132. package/dist/utils/p36-upgrade.d.ts +62 -0
  133. package/dist/utils/p36-upgrade.d.ts.map +1 -0
  134. package/dist/utils/p36-upgrade.js +160 -0
  135. package/dist/utils/p36-upgrade.js.map +1 -0
  136. package/dist/utils/project-capabilities.d.ts +1 -12
  137. package/dist/utils/project-capabilities.d.ts.map +1 -1
  138. package/dist/utils/project-capabilities.js +3 -100
  139. package/dist/utils/project-capabilities.js.map +1 -1
  140. package/dist/utils/readiness.d.ts +10 -0
  141. package/dist/utils/readiness.d.ts.map +1 -1
  142. package/dist/utils/readiness.js +58 -26
  143. package/dist/utils/readiness.js.map +1 -1
  144. package/dist/utils/retrieval-agent-instructions.js +1 -1
  145. package/dist/utils/retrieval-agent-instructions.js.map +1 -1
  146. package/dist/utils/template-hash.d.ts.map +1 -1
  147. package/dist/utils/template-hash.js +11 -1
  148. package/dist/utils/template-hash.js.map +1 -1
  149. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
  150. package/dist/utils/uninstall-scrubbers.js +52 -14
  151. package/dist/utils/uninstall-scrubbers.js.map +1 -1
  152. package/dist/utils/update-rollout-report.d.ts +14 -0
  153. package/dist/utils/update-rollout-report.d.ts.map +1 -1
  154. package/dist/utils/update-rollout-report.js +1 -0
  155. package/dist/utils/update-rollout-report.js.map +1 -1
  156. package/dist/utils/workflow-ownership.d.ts +1 -1
  157. package/dist/utils/workflow-ownership.js +4 -4
  158. package/dist/utils/workflow-ownership.js.map +1 -1
  159. package/package.json +5 -4
  160. package/scripts/postinstall.js +6 -7
  161. package/dist/commands/campaign/canvas-render.d.ts +0 -68
  162. package/dist/commands/campaign/canvas-render.d.ts.map +0 -1
  163. package/dist/commands/campaign/canvas-render.js +0 -414
  164. package/dist/commands/campaign/canvas-render.js.map +0 -1
  165. package/dist/commands/campaign/compose.d.ts +0 -15
  166. package/dist/commands/campaign/compose.d.ts.map +0 -1
  167. package/dist/commands/campaign/compose.js +0 -110
  168. package/dist/commands/campaign/compose.js.map +0 -1
  169. package/dist/commands/campaign/index.d.ts +0 -13
  170. package/dist/commands/campaign/index.d.ts.map +0 -1
  171. package/dist/commands/campaign/index.js +0 -134
  172. package/dist/commands/campaign/index.js.map +0 -1
  173. package/dist/commands/campaign/kind-map.d.ts +0 -6
  174. package/dist/commands/campaign/kind-map.d.ts.map +0 -1
  175. package/dist/commands/campaign/kind-map.js +0 -21
  176. package/dist/commands/campaign/kind-map.js.map +0 -1
  177. package/dist/commands/campaign/mcp-server.d.ts +0 -6
  178. package/dist/commands/campaign/mcp-server.d.ts.map +0 -1
  179. package/dist/commands/campaign/mcp-server.js +0 -167
  180. package/dist/commands/campaign/mcp-server.js.map +0 -1
  181. package/dist/commands/campaign/render.d.ts +0 -5
  182. package/dist/commands/campaign/render.d.ts.map +0 -1
  183. package/dist/commands/campaign/render.js +0 -103
  184. package/dist/commands/campaign/render.js.map +0 -1
  185. package/dist/commands/campaign/trellis-load.d.ts +0 -13
  186. package/dist/commands/campaign/trellis-load.d.ts.map +0 -1
  187. package/dist/commands/campaign/trellis-load.js +0 -122
  188. package/dist/commands/campaign/trellis-load.js.map +0 -1
  189. package/dist/commands/campaign/types.d.ts +0 -61
  190. package/dist/commands/campaign/types.d.ts.map +0 -1
  191. package/dist/commands/campaign/types.js +0 -3
  192. package/dist/commands/campaign/types.js.map +0 -1
  193. package/dist/commands/goal/index.d.ts +0 -3
  194. package/dist/commands/goal/index.d.ts.map +0 -1
  195. package/dist/commands/goal/index.js +0 -159
  196. package/dist/commands/goal/index.js.map +0 -1
  197. package/dist/commands/goal/review.d.ts +0 -6
  198. package/dist/commands/goal/review.d.ts.map +0 -1
  199. package/dist/commands/goal/review.js +0 -28
  200. package/dist/commands/goal/review.js.map +0 -1
  201. package/dist/commands/rpc/client.d.ts +0 -51
  202. package/dist/commands/rpc/client.d.ts.map +0 -1
  203. package/dist/commands/rpc/client.js +0 -147
  204. package/dist/commands/rpc/client.js.map +0 -1
  205. package/dist/commands/rpc/index.d.ts +0 -10
  206. package/dist/commands/rpc/index.d.ts.map +0 -1
  207. package/dist/commands/rpc/index.js +0 -157
  208. package/dist/commands/rpc/index.js.map +0 -1
  209. package/dist/commands/rpc/serve.d.ts +0 -23
  210. package/dist/commands/rpc/serve.d.ts.map +0 -1
  211. package/dist/commands/rpc/serve.js +0 -60
  212. package/dist/commands/rpc/serve.js.map +0 -1
  213. package/dist/commands/rpc/smoke.d.ts +0 -16
  214. package/dist/commands/rpc/smoke.d.ts.map +0 -1
  215. package/dist/commands/rpc/smoke.js +0 -92
  216. package/dist/commands/rpc/smoke.js.map +0 -1
  217. package/dist/commands/sdk/index.d.ts +0 -9
  218. package/dist/commands/sdk/index.d.ts.map +0 -1
  219. package/dist/commands/sdk/index.js +0 -58
  220. package/dist/commands/sdk/index.js.map +0 -1
  221. package/dist/commands/sdk/run.d.ts +0 -42
  222. package/dist/commands/sdk/run.d.ts.map +0 -1
  223. package/dist/commands/sdk/run.js +0 -220
  224. package/dist/commands/sdk/run.js.map +0 -1
  225. package/dist/commands/sdk/status.d.ts +0 -14
  226. package/dist/commands/sdk/status.d.ts.map +0 -1
  227. package/dist/commands/sdk/status.js +0 -69
  228. package/dist/commands/sdk/status.js.map +0 -1
  229. package/dist/configurators/cursor2plus-local.d.ts +0 -6
  230. package/dist/configurators/cursor2plus-local.d.ts.map +0 -1
  231. package/dist/configurators/cursor2plus-local.js +0 -21
  232. package/dist/configurators/cursor2plus-local.js.map +0 -1
  233. package/dist/goal/action-packet.d.ts +0 -89
  234. package/dist/goal/action-packet.d.ts.map +0 -1
  235. package/dist/goal/action-packet.js +0 -113
  236. package/dist/goal/action-packet.js.map +0 -1
  237. package/dist/goal/audit.d.ts +0 -14
  238. package/dist/goal/audit.d.ts.map +0 -1
  239. package/dist/goal/audit.js +0 -12
  240. package/dist/goal/audit.js.map +0 -1
  241. package/dist/goal/constants.d.ts +0 -26
  242. package/dist/goal/constants.d.ts.map +0 -1
  243. package/dist/goal/constants.js +0 -24
  244. package/dist/goal/constants.js.map +0 -1
  245. package/dist/goal/paths.d.ts +0 -8
  246. package/dist/goal/paths.d.ts.map +0 -1
  247. package/dist/goal/paths.js +0 -36
  248. package/dist/goal/paths.js.map +0 -1
  249. package/dist/goal/preflight.d.ts +0 -21
  250. package/dist/goal/preflight.d.ts.map +0 -1
  251. package/dist/goal/preflight.js +0 -97
  252. package/dist/goal/preflight.js.map +0 -1
  253. package/dist/goal/review-seam.d.ts +0 -44
  254. package/dist/goal/review-seam.d.ts.map +0 -1
  255. package/dist/goal/review-seam.js +0 -153
  256. package/dist/goal/review-seam.js.map +0 -1
  257. package/dist/goal/reviewer-rules.d.ts +0 -13
  258. package/dist/goal/reviewer-rules.d.ts.map +0 -1
  259. package/dist/goal/reviewer-rules.js +0 -153
  260. package/dist/goal/reviewer-rules.js.map +0 -1
  261. package/dist/goal/reviewer.d.ts +0 -9
  262. package/dist/goal/reviewer.d.ts.map +0 -1
  263. package/dist/goal/reviewer.js +0 -54
  264. package/dist/goal/reviewer.js.map +0 -1
  265. package/dist/goal/runtime.d.ts +0 -32
  266. package/dist/goal/runtime.d.ts.map +0 -1
  267. package/dist/goal/runtime.js +0 -242
  268. package/dist/goal/runtime.js.map +0 -1
  269. package/dist/goal/sdk-client.d.ts +0 -10
  270. package/dist/goal/sdk-client.d.ts.map +0 -1
  271. package/dist/goal/sdk-client.js +0 -34
  272. package/dist/goal/sdk-client.js.map +0 -1
  273. package/dist/goal/state.d.ts +0 -40
  274. package/dist/goal/state.d.ts.map +0 -1
  275. package/dist/goal/state.js +0 -37
  276. package/dist/goal/state.js.map +0 -1
  277. package/dist/goal/task-triggers.d.ts +0 -15
  278. package/dist/goal/task-triggers.d.ts.map +0 -1
  279. package/dist/goal/task-triggers.js +0 -23
  280. package/dist/goal/task-triggers.js.map +0 -1
  281. package/dist/goal/walls.d.ts +0 -12
  282. package/dist/goal/walls.d.ts.map +0 -1
  283. package/dist/goal/walls.js +0 -65
  284. package/dist/goal/walls.js.map +0 -1
  285. package/dist/goal/worker-prompt.d.ts +0 -13
  286. package/dist/goal/worker-prompt.d.ts.map +0 -1
  287. package/dist/goal/worker-prompt.js +0 -41
  288. package/dist/goal/worker-prompt.js.map +0 -1
  289. package/dist/goal/worker.d.ts +0 -42
  290. package/dist/goal/worker.d.ts.map +0 -1
  291. package/dist/goal/worker.js +0 -180
  292. package/dist/goal/worker.js.map +0 -1
  293. package/dist/templates/common/bundled-skills/cstl-cursor2plus-setup/SKILL.md +0 -63
  294. package/dist/templates/cursor/commands/cursor2plus-setup.md +0 -82
  295. package/dist/templates/cursor/rules/cstl-cursor-modes.mdc +0 -32
  296. package/dist/templates/cursor/rules/cstl-session-rename.mdc +0 -31
  297. package/dist/templates/cursor/rules/cstl-subagent-dispatch.mdc +0 -34
  298. package/dist/templates/cursor/rules/cstl-triage.mdc +0 -36
  299. package/dist/templates/cursor/rules/retrieval-routing.mdc +0 -78
  300. package/dist/templates/trellis/local/README.md +0 -85
  301. package/dist/templates/trellis/local/config.local.json.example +0 -6
  302. package/dist/templates/trellis/local/index.d.ts +0 -8
  303. package/dist/templates/trellis/local/index.d.ts.map +0 -1
  304. package/dist/templates/trellis/local/index.js +0 -15
  305. package/dist/templates/trellis/local/index.js.map +0 -1
  306. package/dist/templates/trellis/local/patch_wpelc8.py +0 -421
  307. package/dist/templates/trellis/local/smoke.py +0 -94
  308. package/dist/templates/trellis/local/subagent-models.json.example +0 -4
  309. package/dist/templates/trellis/local/trellis-task-models.json.example +0 -10
  310. package/dist/templates/trellis/local/trellis-task-models.json5.example +0 -45
  311. package/dist/templates/trellis/local/trellis_task_models_config.py +0 -200
  312. package/dist/utils/cursor-sdk-gate.d.ts +0 -10
  313. package/dist/utils/cursor-sdk-gate.d.ts.map +0 -1
  314. package/dist/utils/cursor-sdk-gate.js +0 -32
  315. package/dist/utils/cursor-sdk-gate.js.map +0 -1
@@ -5,9 +5,10 @@ Use this checklist before handing off a new or modified skill.
5
5
  ## Frontmatter
6
6
 
7
7
  - [ ] `name` uses lowercase letters, numbers, and hyphens only.
8
- - [ ] `description` is third-person and trigger-rich.
9
- - [ ] `description` includes both what the skill does and when to use it.
8
+ - [ ] `description` is third-person, specific, and includes trigger terms.
9
+ - [ ] `description` includes both what the skill does (WHAT) and when to use it (WHEN).
10
10
  - [ ] The skill name does not collide with a platform built-in helper unless that is intentional.
11
+ - [ ] The skill name is specific (`processing-pdfs`), not vague (`helper`, `utils`, `tools`).
11
12
 
12
13
  ## Scope And Boundaries
13
14
 
@@ -15,14 +16,18 @@ Use this checklist before handing off a new or modified skill.
15
16
  - [ ] `When NOT To Use` or equivalent boundary guidance is present when triggers may overlap.
16
17
  - [ ] Project-private rules are in `.cstl/spec/` or a project-local skill, not in a public bundled skill.
17
18
  - [ ] The skill distinguishes local project customization from upstream Trellis source changes.
19
+ - [ ] Terminology is consistent throughout.
18
20
 
19
21
  ## Entry File
20
22
 
21
23
  - [ ] `SKILL.md` is concise and under 500 lines.
24
+ - [ ] `SKILL.md` is written in English unless the target platform or user explicitly requires another language.
22
25
  - [ ] `SKILL.md` contains the minimum routing and workflow needed to start.
23
26
  - [ ] `## Hard Constraints` appears before `## Workflow` when constraints exist.
24
- - [ ] Hard constraints are imperative one-liners.
25
- - [ ] The same rule is not repeated in multiple sections.
27
+ - [ ] Hard constraints are imperative one-liners (`Always X. Never Y.`).
28
+ - [ ] The same rule is not repeated in multiple sections; Hard Constraints is the only rule list.
29
+ - [ ] Workflow has an explicit tool-call sequence and stop conditions.
30
+ - [ ] Tool usage limits are stated when applicable.
26
31
 
27
32
  ## References And Assets
28
33
 
@@ -36,7 +41,7 @@ Use this checklist before handing off a new or modified skill.
36
41
  - [ ] Scripts are necessary for determinism, not decorative.
37
42
  - [ ] Scripts expose only necessary parameters.
38
43
  - [ ] Scripts do not rely on shell variables or state from a previous tool call.
39
- - [ ] Scripts return structured JSON when they mutate files or provide machine-readable status.
44
+ - [ ] Scripts return structured JSON to stdout when they mutate files or provide machine-readable status.
40
45
  - [ ] Syntax checks were run for modified scripts when applicable.
41
46
 
42
47
  ## Trellis Template Integration
@@ -41,21 +41,22 @@ Shows the Phase Index (Plan / Execute / Finish) with routing + skill mapping.
41
41
 
42
42
  ## Step 4: Decide Where You Are
43
43
 
44
- When a task is selected, `get_context.py` shows the selected task's `status` field. Route by `status` + artifact presence. This command replaces the user needing to remember the Trellis flow; it does not itself approve implementation.
44
+ When a task is selected, `get_context.py` shows the selected task. Route by Kernel / persisted `required_controls.rigor` and `topology.kind`, not by whether `design.md` or `implement.md` exist. `status` is a projection, not the sole truth. This command replaces the user needing to remember the Trellis flow; it does not itself approve implementation.
45
45
 
46
46
  - `status=planning` + no `prd.md` → **1.1** (Read `.cstl/framework/prd-grill-frontier.md` for PRD Grill discipline)
47
- - `status=planning` + `prd.md` only decide whether the task is lightweight or complex. Lightweight can move to **1.4** review; complex returns to **1.1** to add `design.md` + `implement.md`.
48
- - `status=planning` + complex artifacts complete + sub-agent jsonl not curated (only the seed `_example` row) → **1.3**
47
+ - `status=planning` + `prd.md` + rigor is lite (or missing contract = explicit Lite) **1.4** review / execution gate
48
+ - `status=planning` + rigor is full + required planning artifacts not complete → stay in planning (`design.md` / `implement.md` only when `required_controls` says so)
49
49
  - `status=planning` + required artifacts complete + required jsonl curated or inline mode → execution gate (run `task.py start-execution <task> --check`, report PASS, ask for explicit execution approval, then run `task.py start-execution <task> --approved`)
50
50
  - `status=in_progress` + implementation not started → **2.1**
51
51
  - `status=in_progress` + implementation done, not yet checked → **2.2**
52
52
  - `status=in_progress` + check passed → **3.1**
53
53
  - `status=completed` (rare; usually archived immediately) → archive flow
54
+ - `topology.kind=parent-child` → Parent integration path, not ordinary Child closeout. `parent_id` alone does **not** make a Child a Parent.
54
55
 
55
56
  Phase rules (full detail in `.cstl/workflow.md`):
56
57
 
57
58
  1. Run steps **in order** within a phase — `[required]` steps must not be skipped
58
- 2. `[once]` steps are already done if the required output exists. `prd.md` alone can be enough only for lightweight tasks; complex tasks also need `design.md` and `implement.md`.
59
+ 2. `[once]` steps are already done if the required output exists. `prd.md` alone can be enough when rigor is Lite; Full follows `required_controls`, not file presence.
59
60
  3. You may go back to an earlier phase if discoveries require it
60
61
 
61
62
  ## Step 5: Load the Specific Step
@@ -28,6 +28,17 @@ export interface CommonBundledSkill {
28
28
  /** Files that must be written under the skill directory */
29
29
  files: CommonBundledSkillFile[];
30
30
  }
31
+ /**
32
+ * Optional/experimental skill — same shape as bundled skills, but lives under
33
+ * `optional-skills/` which `getBundledSkillTemplates()` does NOT scan.
34
+ * Installed only via `cstl init --with-optional <name>` (default off).
35
+ */
36
+ export interface CommonOptionalSkill {
37
+ /** Skill directory name, e.g. "chrome-cdp" */
38
+ name: string;
39
+ /** Files that must be written under the skill directory */
40
+ files: CommonBundledSkillFile[];
41
+ }
31
42
  /**
32
43
  * Get all command templates (stay as slash commands on all platforms).
33
44
  * Results are cached after first call.
@@ -45,4 +56,13 @@ export declare function getSkillTemplates(): CommonTemplate[];
45
56
  * lazy-loadable instead of being flattened into one oversized SKILL.md.
46
57
  */
47
58
  export declare function getBundledSkillTemplates(): CommonBundledSkill[];
59
+ /**
60
+ * Get all optional/experimental skills (e.g. `optional-skills/chrome-cdp/`).
61
+ *
62
+ * Deliberately separate from {@link getBundledSkillTemplates}: `optional-skills/`
63
+ * is NOT scanned by the bundled pipeline, so default `cstl init` never installs
64
+ * these. They are installed only through `cstl init --with-optional <name>`.
65
+ * Results are cached after first call.
66
+ */
67
+ export declare function getOptionalSkillTemplates(): CommonOptionalSkill[];
48
68
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/common/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAuBH,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,KAAK,EAAE,sBAAsB,EAAE,CAAC;CACjC;AAOD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,EAAE,CAMtD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,EAAE,CAMpD;AAuCD;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,kBAAkB,EAAE,CAM/D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/common/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAuBH,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,KAAK,EAAE,sBAAsB,EAAE,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,KAAK,EAAE,sBAAsB,EAAE,CAAC;CACjC;AAQD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,EAAE,CAMtD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,EAAE,CAMpD;AA2CD;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,kBAAkB,EAAE,CAM/D;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,IAAI,mBAAmB,EAAE,CAMjE"}
@@ -32,6 +32,7 @@ function listMarkdownFiles(dir) {
32
32
  let cachedCommands;
33
33
  let cachedSkills;
34
34
  let cachedBundledSkills;
35
+ let cachedOptionalSkills;
35
36
  /**
36
37
  * Get all command templates (stay as slash commands on all platforms).
37
38
  * Results are cached after first call.
@@ -67,8 +68,8 @@ function listDirectories(dir) {
67
68
  function toPosixRelativePath(root, filePath) {
68
69
  return relative(root, filePath).split(sep).join("/");
69
70
  }
70
- function listBundledSkillFiles(skillDir) {
71
- const root = join(__dirname, "bundled-skills", skillDir);
71
+ function listSkillFiles(rootDir, skillDir) {
72
+ const root = join(__dirname, rootDir, skillDir);
72
73
  const files = [];
73
74
  function walk(dir) {
74
75
  for (const entry of readdirSync(dir)) {
@@ -88,6 +89,9 @@ function listBundledSkillFiles(skillDir) {
88
89
  walk(root);
89
90
  return files.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
90
91
  }
92
+ function listBundledSkillFiles(skillDir) {
93
+ return listSkillFiles("bundled-skills", skillDir);
94
+ }
91
95
  /**
92
96
  * Get all multi-file built-in skills.
93
97
  *
@@ -101,4 +105,19 @@ export function getBundledSkillTemplates() {
101
105
  }));
102
106
  return cachedBundledSkills;
103
107
  }
108
+ /**
109
+ * Get all optional/experimental skills (e.g. `optional-skills/chrome-cdp/`).
110
+ *
111
+ * Deliberately separate from {@link getBundledSkillTemplates}: `optional-skills/`
112
+ * is NOT scanned by the bundled pipeline, so default `cstl init` never installs
113
+ * these. They are installed only through `cstl init --with-optional <name>`.
114
+ * Results are cached after first call.
115
+ */
116
+ export function getOptionalSkillTemplates() {
117
+ cachedOptionalSkills ??= listDirectories("optional-skills").map((name) => ({
118
+ name,
119
+ files: listSkillFiles("optional-skills", name),
120
+ }));
121
+ return cachedOptionalSkills;
122
+ }
104
123
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/common/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/common/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,179 @@
1
+ ---
2
+ name: chrome-cdp
3
+ description: Interact with local Chrome browser session (only on explicit user approval after being asked to inspect, debug, or interact with a page open in Chrome)
4
+ ---
5
+
6
+ > **experimental** — optional skill, installed on explicit request only (`cstl init --with-optional chrome-cdp`). Not a default Trellis capability.
7
+ >
8
+ > vendored from `blaze-skills/chrome-cdp@4ed61ff`(源 commit);同步机制:改源 → 拷副本 → 更新本标记。不要直接在本副本上分叉内容。
9
+
10
+ # Chrome CDP
11
+
12
+ Lightweight Chrome DevTools Protocol CLI. Connects directly via WebSocket — no Puppeteer, works with 100+ tabs, instant connection.
13
+
14
+ ## Required Safety Wording
15
+
16
+ > Use Chrome CDP only after the user explicitly approves interacting with their existing local Chrome browser session for this task. This skill can reveal open tabs, page content, authenticated data, screenshots, profile state, and extension-influenced behavior, and it can mutate real browser state through navigation, clicks, typing, new tabs, or arbitrary CDP commands. Prefer Playwright MCP for reproducible browser automation and UI verification. Ask before `list`; ask again before inspecting content, taking screenshots, evaluating JavaScript, navigating, clicking, typing, opening tabs, or using raw CDP commands. Never use this skill for routine browser tests or when a controlled Playwright/sessionless check is sufficient.
17
+
18
+ ## Channel Selection (three-way)
19
+
20
+ | Channel | Status | Use for |
21
+ | --- | --- | --- |
22
+ | Playwright MCP | **default** | Reproducible browser automation, rendered UI evidence, screenshots, UI smoke verification |
23
+ | `cursor-ide-browser` (IDE preview) | IDE 预览 | Page inspection/preview inside the IDE without touching the user's real Chrome profile |
24
+ | `chrome-cdp` (this skill) | real Chrome, attach-only on approval | Inspect/debug/interact with the user's **already-open local Chrome session** (login state, cookies, tabs) — only after explicit user approval |
25
+
26
+ - If a `mcp__chrome-devtools__*` server is present in the environment, ask the user which channel they want: the chrome-devtools MCP server and this CDP CLI are **mutually exclusive** for a given interaction — never run both against the same tab.
27
+ - Never switch to MCP when the user explicitly requires CDP. CDP may have login state that MCP does not.
28
+
29
+ ## Prerequisites
30
+
31
+ - Chrome (or Chromium, Brave, Edge, Vivaldi) with remote debugging enabled: open `chrome://inspect/#remote-debugging` and toggle the switch
32
+ - Node.js 22+ (uses built-in WebSocket)
33
+ - If your browser's `DevToolsActivePort` is in a non-standard location, set `CDP_PORT_FILE` to its full path
34
+
35
+ ## Hard Constraints
36
+
37
+ - Never use `shot` to read page content. Use it only for visual debugging as a last resort.
38
+ - Always prefer `eval` plus `getBoundingClientRect()` over `shot` to find element coordinates.
39
+ - Always prefer `clickxy` over `click <selector>` unless you have a specific reason to use DOM click.
40
+ - Always check `window.location.href` and `list` after clicking.
41
+ - Always collect volatile page data in one `eval` call when possible.
42
+ - Never switch to MCP when the user explicitly requires CDP. CDP may have login state that MCP does not.
43
+
44
+ ## Commands
45
+
46
+ All commands use `scripts/cdp.mjs`. The `<target>` is a **unique** targetId prefix from `list`.
47
+
48
+ ```bash
49
+ scripts/cdp.mjs list # list all open tabs (* marks current active tab)
50
+ scripts/cdp.mjs eval <target> <expr> # run JS in page context
51
+ scripts/cdp.mjs clickxy <target> <x> <y> # real mouse click at CSS px coords (preferred)
52
+ scripts/cdp.mjs click <target> <selector> # DOM click by CSS selector (SPA-unreliable)
53
+ scripts/cdp.mjs nav <target> <url> # navigate and wait for load
54
+ scripts/cdp.mjs snap <target> # accessibility tree (token-light alternative to shot)
55
+ scripts/cdp.mjs type <target> <text> # insert text at current focus
56
+ scripts/cdp.mjs html <target> [selector] # full page or element HTML
57
+ scripts/cdp.mjs shot <target> [file] # screenshot (last resort, very token-heavy)
58
+ scripts/cdp.mjs net <target> # network performance entries (resource timing)
59
+ scripts/cdp.mjs loadall <target> <selector> [ms] # [exceptional] repeatedly click a "load more" button until it disappears
60
+ scripts/cdp.mjs evalraw <target> <method> [json] # [exceptional] send a raw CDP command; returns JSON result
61
+ scripts/cdp.mjs open [url] # open new tab
62
+ scripts/cdp.mjs stop [target] # stop daemon(s)
63
+ ```
64
+
65
+ - `net` is safe, read-only (resource timing entries).
66
+ - `loadall` is **exceptional**: it mutates the real page repeatedly; ask for explicit approval before using it.
67
+ - `evalraw` is **exceptional**: it exposes arbitrary CDP methods beyond the curated command list; require exceptional approval before using it.
68
+
69
+ ## Active Tab Detection (macOS)
70
+
71
+ `list` automatically marks the currently focused Chrome tab with `*` using AppleScript:
72
+
73
+ ```
74
+ (* = current active tab in Chrome)
75
+ * B5404DDD MiMo-V2-Pro & Omni & TTS ... https://www.reddit.com/...
76
+ 5BE8FE3C Google 新聞 https://news.google.com/...
77
+ ```
78
+
79
+ - On first run, macOS may show an automation permission dialog — click Allow once.
80
+ - Only works on macOS; silently skipped on other platforms.
81
+ - Reflects the real Chrome foreground tab, updates on every `list` call.
82
+ - **Use this to quickly identify the target without manually matching URLs.**
83
+
84
+ ## Windows
85
+
86
+ - Windows uses a **named pipe** per tab (`\\.\pipe\cdp-<targetId>`) instead of a Unix socket; runtime files live under `%LOCALAPPDATA%\cdp\`.
87
+ - Chrome may show an **"Allow debugging?"** popup once per tab daemon — click Allow once. If the daemon fails to start, the error message explicitly asks whether you clicked Allow in Chrome.
88
+ - Remote debugging must be enabled at `chrome://inspect/#remote-debugging` (Windows supported; `DevToolsActivePort` is discovered under `%LOCALAPPDATA%\<browser>\User Data\`).
89
+
90
+ ## Coordinates
91
+
92
+ `shot` saves at native resolution: image pixels = CSS pixels × DPR. `clickxy` takes **CSS pixels**.
93
+ Use this conversion only if you already have a screenshot for visual debugging. Do not take a screenshot just to compute click coordinates.
94
+
95
+ ```
96
+ CSS px = screenshot px / DPR
97
+ ```
98
+
99
+ ## Workflow
100
+
101
+ ### Identify the right target quickly
102
+
103
+ ```bash
104
+ # Run list — the * tab is what the user currently has open in Chrome
105
+ scripts/cdp.mjs list
106
+ # → use the * prefix directly as <target>
107
+ ```
108
+
109
+ ### Click a JS-driven link (SPA / Google News / React apps)
110
+
111
+ ```bash
112
+ # 1. Get element center in CSS px via JS (no screenshot needed)
113
+ eval <target> "var el=document.querySelector('a[href*=\"keyword\"]'); var r=el.getBoundingClientRect(); ((r.left+r.right)/2)+','+((r.top+r.bottom)/2)"
114
+ # → "908,555"
115
+
116
+ # 2. Click using real mouse input
117
+ clickxy <target> 908 555
118
+
119
+ # 3a. Check if current tab navigated
120
+ eval <target> "window.location.href"
121
+
122
+ # 3b. Check if a new tab opened (compare before/after)
123
+ list
124
+ ```
125
+
126
+ ### Detect new tab after click
127
+
128
+ ```bash
129
+ # Before click — note existing targetIds
130
+ list
131
+ # Click ...
132
+ # After click — new entry = new tab
133
+ list
134
+ # Inspect the new tab
135
+ eval <new-target-prefix> "window.location.href"
136
+ eval <new-target-prefix> "document.title"
137
+ ```
138
+
139
+ ### Inspect page content efficiently
140
+
141
+ ```bash
142
+ # Preferred: JS query (near-zero tokens)
143
+ eval <target> "document.title"
144
+ eval <target> "Array.from(document.querySelectorAll('a[href*=\"/news/\"]')).map(a=>a.innerText+' | '+a.href).join('\n')"
145
+
146
+ # Alternative: accessibility tree (compact, structured)
147
+ snap <target>
148
+
149
+ # Avoid: screenshot (only when visual layout truly needed)
150
+ shot <target>
151
+ ```
152
+
153
+ ## Token Cost Guide
154
+
155
+ | Command | Relative cost | Use when |
156
+ |---------|--------------|----------|
157
+ | `eval` | Very low | Reading text, coords, URLs, DOM state |
158
+ | `snap` | Low–Medium | Need page structure overview |
159
+ | `html` | Medium | Need raw HTML of a section |
160
+ | `shot` | Very high | Visual debugging only (last resort) |
161
+
162
+ ## Examples
163
+
164
+ | Example | Description |
165
+ |---------|-------------|
166
+ | [`examples/fetch-hook-api-capture.md`](examples/fetch-hook-api-capture.md) | Intercept SPA API responses by injecting a fetch/XHR hook via `eval` — covers inject → trigger → read → paginate workflow |
167
+
168
+ ## Runtime Artifacts & Cleanup
169
+
170
+ - Each tab runs a per-tab daemon (holds the CDP session; auto-exits after 20 min idle or when the tab closes).
171
+ - `pages.json` cache + screenshots live in the runtime dir: `%LOCALAPPDATA%\cdp\` (Windows), `$XDG_RUNTIME_DIR/cdp` or `~/.cache/cdp` (Linux), `~/Library/Caches`-adjacent `~/.cache/cdp` (macOS).
172
+ - Stop daemons explicitly when done: `scripts/cdp.mjs stop` (all) or `scripts/cdp.mjs stop <target>` (one).
173
+ - Screenshots saved without an explicit path land in the runtime dir (`screenshot-<target>.png`) — delete them after use; they are local residual artifacts, not evidence for task verification.
174
+
175
+ ## When NOT to use this skill
176
+
177
+ - Page content can be fetched statically (use `WebFetch` instead).
178
+ - User has not explicitly asked to interact with Chrome.
179
+ - A controlled Playwright/sessionless check is sufficient.
@@ -0,0 +1,149 @@
1
+ # Fetch Hook — Intercept SPA API Responses
2
+
3
+ The CDP skill does not support `Network` domain event listening (`cdp.mjs` uses a request/response architecture and cannot receive push events like `Network.responseReceived`). Injecting a fetch hook via `eval` is the best alternative for capturing API data from SPA pages.
4
+
5
+ ## When to Use
6
+
7
+ - Page loads data via `fetch` / `XMLHttpRequest` from a backend API (SPA, Next.js, Convex, etc.)
8
+ - You need raw JSON responses rather than reverse-parsing from the DOM
9
+ - You need request parameters for replay or pagination
10
+
11
+ ## Workflow
12
+
13
+ ### Step 1: Inject Hook
14
+
15
+ Inject **after the page has finished loading**. The hook is lost on navigation/refresh, so it must be injected after `nav`.
16
+
17
+ ```bash
18
+ scripts/cdp.mjs eval <target> "
19
+ window.__captured = [];
20
+ var _origFetch = window.fetch;
21
+ window.fetch = async function() {
22
+ var url = typeof arguments[0] === 'string' ? arguments[0] : (arguments[0] && arguments[0].url || '');
23
+ var opts = arguments[1] || {};
24
+ var reqBody = '';
25
+ if (opts.body) { try { reqBody = typeof opts.body === 'string' ? opts.body : JSON.stringify(opts.body); } catch(e) {} }
26
+ var resp = await _origFetch.apply(this, arguments);
27
+ try {
28
+ var clone = resp.clone();
29
+ var text = await clone.text();
30
+ window.__captured.push({ url: url, method: opts.method || 'GET', reqBody: reqBody, resBody: text, len: text.length });
31
+ } catch(e) {}
32
+ return resp;
33
+ };
34
+ 'hook installed'
35
+ "
36
+ ```
37
+
38
+ **Key points:**
39
+ - Must `clone()` the response before reading the body — otherwise the original response stream is consumed and the page breaks
40
+ - Data is stored in `window.__captured` array, read later via `eval`
41
+ - The hook only captures requests made **after** injection — it cannot retroactively capture requests that already completed during page load
42
+
43
+ ### Step 2: Trigger API Calls
44
+
45
+ After injecting the hook, interact with the page to trigger new API requests:
46
+
47
+ ```bash
48
+ # Option A: scroll to trigger infinite scroll
49
+ scripts/cdp.mjs eval <target> "window.scrollTo(0, document.body.scrollHeight); 'scrolled'"
50
+
51
+ # Option B: click a "Load More" button
52
+ scripts/cdp.mjs click <target> "button.load-more"
53
+
54
+ # Option C: change sort/filter to trigger a new request
55
+ scripts/cdp.mjs click <target> "select#sort-by"
56
+ ```
57
+
58
+ Wait 1-2 seconds for requests to complete before reading.
59
+
60
+ ### Step 3: Read Captured Data
61
+
62
+ ```bash
63
+ # Overview of captured requests
64
+ scripts/cdp.mjs eval <target> "
65
+ var c = window.__captured || [];
66
+ 'Captured: ' + c.length + ' requests\n' + c.map(function(r,i) {
67
+ return i + ': ' + r.method + ' ' + r.url.substring(0,80) + ' (' + r.len + ' bytes)';
68
+ }).join('\n');
69
+ "
70
+
71
+ # Read a specific response body (truncate to avoid token explosion)
72
+ scripts/cdp.mjs eval <target> "window.__captured[0].resBody.substring(0, 2000)"
73
+
74
+ # Read request parameters (to understand API format, pagination cursor, etc.)
75
+ scripts/cdp.mjs eval <target> "window.__captured[0].reqBody"
76
+ ```
77
+
78
+ ### Step 4: Replay API with Pagination
79
+
80
+ Once you understand the API format, replay calls directly in the page context to fetch all data automatically:
81
+
82
+ ```bash
83
+ scripts/cdp.mjs eval <target> "
84
+ (async function() {
85
+ var allItems = [];
86
+ var cursor = null;
87
+ var hasMore = true;
88
+ while (hasMore) {
89
+ var resp = await fetch('https://example.com/api/query', {
90
+ method: 'POST',
91
+ headers: { 'Content-Type': 'application/json' },
92
+ body: JSON.stringify({
93
+ path: 'items:list',
94
+ args: [{ cursor: cursor, numItems: 100 }]
95
+ })
96
+ });
97
+ var data = await resp.json();
98
+ allItems = allItems.concat(data.value.page);
99
+ hasMore = data.value.hasMore;
100
+ cursor = data.value.nextCursor;
101
+ }
102
+ window.__allItems = allItems;
103
+ return 'Total: ' + allItems.length;
104
+ })()
105
+ "
106
+ ```
107
+
108
+ Then read results in batches to avoid oversized output:
109
+
110
+ ```bash
111
+ # Read first 50
112
+ scripts/cdp.mjs eval <target> "JSON.stringify(window.__allItems.slice(0, 50).map(function(it) { return { name: it.name, author: it.author }; }))"
113
+
114
+ # Read 50-100
115
+ scripts/cdp.mjs eval <target> "JSON.stringify(window.__allItems.slice(50, 100).map(function(it) { return { name: it.name, author: it.author }; }))"
116
+ ```
117
+
118
+ ## Caveats
119
+
120
+ | Limitation | Details |
121
+ |------------|---------|
122
+ | **Lost on navigation** | `nav` / page refresh clears the hook and `window.__captured` — re-inject after each navigation |
123
+ | **fetch only** | Does not intercept `XMLHttpRequest` by default; see XHR hook below if needed |
124
+ | **Memory growth** | `__captured` array grows indefinitely during long sessions — periodically clear with `window.__captured = []` |
125
+ | **CORS** | Step 4 API replay runs in the page's origin context and is subject to same-origin policy; this is fine if the original request was made by the page itself |
126
+ | **Large responses** | Returning large data via `eval` is token-expensive — use `.substring()` to truncate or `.map()` to extract only the fields you need |
127
+
128
+ ## XMLHttpRequest Hook (Optional)
129
+
130
+ If the page uses `XMLHttpRequest` instead of `fetch`:
131
+
132
+ ```bash
133
+ scripts/cdp.mjs eval <target> "
134
+ var _origOpen = XMLHttpRequest.prototype.open;
135
+ var _origSend = XMLHttpRequest.prototype.send;
136
+ XMLHttpRequest.prototype.open = function(method, url) {
137
+ this.__method = method;
138
+ this.__url = url;
139
+ return _origOpen.apply(this, arguments);
140
+ };
141
+ XMLHttpRequest.prototype.send = function(body) {
142
+ this.addEventListener('load', function() {
143
+ window.__captured.push({ url: this.__url, method: this.__method, reqBody: body || '', resBody: this.responseText, len: this.responseText.length });
144
+ });
145
+ return _origSend.apply(this, arguments);
146
+ };
147
+ 'xhr hook installed'
148
+ "
149
+ ```