@blxzer/cursor-trellis 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/README.md +124 -5
  2. package/README.zh-CN.md +170 -0
  3. package/dist/cli/index.d.ts.map +1 -1
  4. package/dist/cli/index.js +1 -33
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/commands/init.d.ts +0 -13
  7. package/dist/commands/init.d.ts.map +1 -1
  8. package/dist/commands/init.js +7 -14
  9. package/dist/commands/init.js.map +1 -1
  10. package/dist/commands/uninstall.d.ts.map +1 -1
  11. package/dist/commands/uninstall.js +3 -32
  12. package/dist/commands/uninstall.js.map +1 -1
  13. package/dist/commands/update.d.ts.map +1 -1
  14. package/dist/commands/update.js +7 -84
  15. package/dist/commands/update.js.map +1 -1
  16. package/dist/configurators/index.d.ts +7 -8
  17. package/dist/configurators/index.d.ts.map +1 -1
  18. package/dist/configurators/index.js +11 -236
  19. package/dist/configurators/index.js.map +1 -1
  20. package/dist/configurators/workflow.d.ts.map +1 -1
  21. package/dist/configurators/workflow.js +5 -1
  22. package/dist/configurators/workflow.js.map +1 -1
  23. package/dist/migrations/manifests/0.1.1.json +9 -0
  24. package/dist/migrations/manifests/0.1.2.json +9 -0
  25. package/dist/templates/common/bundled-skills/smart-search-cli/SKILL.md +3 -3
  26. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +4 -2
  27. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +8 -15
  28. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +7 -7
  29. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +18 -21
  30. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +2 -2
  31. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +10 -7
  32. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +4 -4
  33. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +20 -31
  34. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +20 -31
  35. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +24 -40
  36. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +28 -59
  37. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +12 -28
  38. package/dist/templates/common/bundled-skills/trellis-skill-creator/references/trellis-skill-locations.md +2 -2
  39. package/dist/templates/cursor/hooks.json +6 -0
  40. package/dist/templates/cursor/rules/retrieval-routing.mdc +57 -0
  41. package/dist/templates/extract.d.ts +0 -14
  42. package/dist/templates/extract.d.ts.map +1 -1
  43. package/dist/templates/extract.js +0 -34
  44. package/dist/templates/extract.js.map +1 -1
  45. package/dist/templates/markdown/agents.md +2 -6
  46. package/dist/templates/markdown/index.d.ts +1 -0
  47. package/dist/templates/markdown/index.d.ts.map +1 -1
  48. package/dist/templates/markdown/index.js +1 -0
  49. package/dist/templates/markdown/index.js.map +1 -1
  50. package/dist/templates/markdown/prompts/run-semantic-slice-12.md.txt +41 -0
  51. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +14 -14
  52. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +8 -20
  53. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +15 -14
  54. package/dist/templates/markdown/spec/guides/cursor-context-injection-guide.md.txt +4 -2
  55. package/dist/templates/markdown/spec/guides/cursor-semantic-compliance.md.txt +49 -0
  56. package/dist/templates/markdown/spec/guides/cursor-subagent-policy.md.txt +18 -5
  57. package/dist/templates/markdown/spec/guides/retrieval-daily-guide.md.txt +68 -20
  58. package/dist/templates/shared-hooks/index.d.ts +1 -1
  59. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  60. package/dist/templates/shared-hooks/index.js +1 -0
  61. package/dist/templates/shared-hooks/index.js.map +1 -1
  62. package/dist/templates/shared-hooks/inject-retrieval-plan.py +163 -0
  63. package/dist/templates/shared-hooks/inject-subagent-context.py +31 -567
  64. package/dist/templates/shared-hooks/research-end-retrieval-pack.py +2 -11
  65. package/dist/templates/trellis/index.d.ts +12 -0
  66. package/dist/templates/trellis/index.d.ts.map +1 -1
  67. package/dist/templates/trellis/index.js +24 -0
  68. package/dist/templates/trellis/index.js.map +1 -1
  69. package/dist/templates/trellis/scripts/aggregate_retrieval_telemetry.py +342 -0
  70. package/dist/templates/trellis/scripts/batch_plan_envelope.py +105 -0
  71. package/dist/templates/trellis/scripts/codegraph_session_smoke.py +76 -0
  72. package/dist/templates/trellis/scripts/common/active_task.py +116 -147
  73. package/dist/templates/trellis/scripts/common/cli_adapter.py +34 -710
  74. package/dist/templates/trellis/scripts/common/codebase_retrieval_router.py +49 -106
  75. package/dist/templates/trellis/scripts/common/git_context.py +17 -2
  76. package/dist/templates/trellis/scripts/common/project_file_stats.py +91 -0
  77. package/dist/templates/trellis/scripts/common/retrieval_adapter_metadata.py +9 -11
  78. package/dist/templates/trellis/scripts/common/retrieval_agent_instructions.py +313 -0
  79. package/dist/templates/trellis/scripts/common/retrieval_pack.py +0 -6
  80. package/dist/templates/trellis/scripts/common/retrieval_pack_context.py +0 -4
  81. package/dist/templates/trellis/scripts/common/retrieval_plan_gate.py +76 -0
  82. package/dist/templates/trellis/scripts/common/retrieval_result_ranking.py +253 -0
  83. package/dist/templates/trellis/scripts/common/retrieval_tool_classification.py +157 -0
  84. package/dist/templates/trellis/scripts/common/semantic_plan_gate.py +52 -0
  85. package/dist/templates/trellis/scripts/common/subagent_dispatch.py +527 -0
  86. package/dist/templates/trellis/scripts/common/task_store.py +32 -0
  87. package/dist/templates/trellis/scripts/common/workflow_phase.py +3 -24
  88. package/dist/templates/trellis/scripts/rank_retrieval_candidates.py +80 -0
  89. package/dist/templates/trellis/scripts/route_codebase_retrieval.py +38 -11
  90. package/dist/templates/trellis/scripts/score_evidence.py +112 -0
  91. package/dist/templates/trellis/scripts/task.py +26 -0
  92. package/dist/templates/trellis/workflow.md +844 -960
  93. package/dist/types/ai-tools.d.ts +13 -16
  94. package/dist/types/ai-tools.d.ts.map +1 -1
  95. package/dist/types/ai-tools.js +5 -238
  96. package/dist/types/ai-tools.js.map +1 -1
  97. package/dist/utils/codebase-retrieval-router.d.ts +1 -8
  98. package/dist/utils/codebase-retrieval-router.d.ts.map +1 -1
  99. package/dist/utils/codebase-retrieval-router.js +39 -180
  100. package/dist/utils/codebase-retrieval-router.js.map +1 -1
  101. package/dist/utils/project-capabilities.d.ts.map +1 -1
  102. package/dist/utils/project-capabilities.js +10 -24
  103. package/dist/utils/project-capabilities.js.map +1 -1
  104. package/dist/utils/retrieval-agent-instructions.d.ts +14 -0
  105. package/dist/utils/retrieval-agent-instructions.d.ts.map +1 -0
  106. package/dist/utils/retrieval-agent-instructions.js +221 -0
  107. package/dist/utils/retrieval-agent-instructions.js.map +1 -0
  108. package/dist/utils/retrieval-execution-telemetry.d.ts +43 -85
  109. package/dist/utils/retrieval-execution-telemetry.d.ts.map +1 -1
  110. package/dist/utils/retrieval-execution-telemetry.js +289 -22
  111. package/dist/utils/retrieval-execution-telemetry.js.map +1 -1
  112. package/dist/utils/retrieval-result-ranking.js +1 -1
  113. package/dist/utils/retrieval-result-ranking.js.map +1 -1
  114. package/dist/utils/retrieval-tool-classification.d.ts +32 -0
  115. package/dist/utils/retrieval-tool-classification.d.ts.map +1 -0
  116. package/dist/utils/retrieval-tool-classification.js +113 -0
  117. package/dist/utils/retrieval-tool-classification.js.map +1 -0
  118. package/dist/utils/uninstall-scrubbers.d.ts +0 -36
  119. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
  120. package/dist/utils/uninstall-scrubbers.js +0 -184
  121. package/dist/utils/uninstall-scrubbers.js.map +1 -1
  122. package/package.json +4 -2
  123. package/dist/commands/mem.d.ts +0 -30
  124. package/dist/commands/mem.d.ts.map +0 -1
  125. package/dist/commands/mem.js +0 -424
  126. package/dist/commands/mem.js.map +0 -1
  127. package/dist/configurators/antigravity.d.ts +0 -7
  128. package/dist/configurators/antigravity.d.ts.map +0 -1
  129. package/dist/configurators/antigravity.js +0 -19
  130. package/dist/configurators/antigravity.js.map +0 -1
  131. package/dist/configurators/claude.d.ts +0 -9
  132. package/dist/configurators/claude.d.ts.map +0 -1
  133. package/dist/configurators/claude.js +0 -72
  134. package/dist/configurators/claude.js.map +0 -1
  135. package/dist/configurators/codebuddy.d.ts +0 -10
  136. package/dist/configurators/codebuddy.d.ts.map +0 -1
  137. package/dist/configurators/codebuddy.js +0 -30
  138. package/dist/configurators/codebuddy.js.map +0 -1
  139. package/dist/configurators/codex.d.ts +0 -8
  140. package/dist/configurators/codex.d.ts.map +0 -1
  141. package/dist/configurators/codex.js +0 -87
  142. package/dist/configurators/codex.js.map +0 -1
  143. package/dist/configurators/copilot.d.ts +0 -10
  144. package/dist/configurators/copilot.d.ts.map +0 -1
  145. package/dist/configurators/copilot.js +0 -51
  146. package/dist/configurators/copilot.js.map +0 -1
  147. package/dist/configurators/droid.d.ts +0 -10
  148. package/dist/configurators/droid.d.ts.map +0 -1
  149. package/dist/configurators/droid.js +0 -30
  150. package/dist/configurators/droid.js.map +0 -1
  151. package/dist/configurators/gemini.d.ts +0 -16
  152. package/dist/configurators/gemini.d.ts.map +0 -1
  153. package/dist/configurators/gemini.js +0 -38
  154. package/dist/configurators/gemini.js.map +0 -1
  155. package/dist/configurators/kilo.d.ts +0 -7
  156. package/dist/configurators/kilo.d.ts.map +0 -1
  157. package/dist/configurators/kilo.js +0 -19
  158. package/dist/configurators/kilo.js.map +0 -1
  159. package/dist/configurators/kiro.d.ts +0 -8
  160. package/dist/configurators/kiro.d.ts.map +0 -1
  161. package/dist/configurators/kiro.js +0 -24
  162. package/dist/configurators/kiro.js.map +0 -1
  163. package/dist/configurators/opencode.d.ts +0 -14
  164. package/dist/configurators/opencode.d.ts.map +0 -1
  165. package/dist/configurators/opencode.js +0 -96
  166. package/dist/configurators/opencode.js.map +0 -1
  167. package/dist/configurators/pi.d.ts +0 -3
  168. package/dist/configurators/pi.d.ts.map +0 -1
  169. package/dist/configurators/pi.js +0 -45
  170. package/dist/configurators/pi.js.map +0 -1
  171. package/dist/configurators/qoder.d.ts +0 -11
  172. package/dist/configurators/qoder.d.ts.map +0 -1
  173. package/dist/configurators/qoder.js +0 -31
  174. package/dist/configurators/qoder.js.map +0 -1
  175. package/dist/configurators/windsurf.d.ts +0 -7
  176. package/dist/configurators/windsurf.d.ts.map +0 -1
  177. package/dist/configurators/windsurf.js +0 -19
  178. package/dist/configurators/windsurf.js.map +0 -1
  179. package/dist/templates/claude/agents/trellis-check.md +0 -124
  180. package/dist/templates/claude/agents/trellis-implement.md +0 -110
  181. package/dist/templates/claude/agents/trellis-research.md +0 -137
  182. package/dist/templates/claude/index.d.ts +0 -22
  183. package/dist/templates/claude/index.d.ts.map +0 -1
  184. package/dist/templates/claude/index.js +0 -46
  185. package/dist/templates/claude/index.js.map +0 -1
  186. package/dist/templates/claude/settings.json +0 -84
  187. package/dist/templates/codebuddy/agents/trellis-check.md +0 -115
  188. package/dist/templates/codebuddy/agents/trellis-implement.md +0 -110
  189. package/dist/templates/codebuddy/agents/trellis-research.md +0 -137
  190. package/dist/templates/codebuddy/index.d.ts +0 -15
  191. package/dist/templates/codebuddy/index.d.ts.map +0 -1
  192. package/dist/templates/codebuddy/index.js +0 -15
  193. package/dist/templates/codebuddy/index.js.map +0 -1
  194. package/dist/templates/codebuddy/settings.json +0 -70
  195. package/dist/templates/codex/agents/trellis-check.toml +0 -67
  196. package/dist/templates/codex/agents/trellis-implement.toml +0 -40
  197. package/dist/templates/codex/agents/trellis-research.toml +0 -73
  198. package/dist/templates/codex/config.toml +0 -28
  199. package/dist/templates/codex/hooks/session-start.py +0 -575
  200. package/dist/templates/codex/hooks.json +0 -15
  201. package/dist/templates/codex/index.d.ts +0 -39
  202. package/dist/templates/codex/index.d.ts.map +0 -1
  203. package/dist/templates/codex/index.js +0 -85
  204. package/dist/templates/codex/index.js.map +0 -1
  205. package/dist/templates/codex/skills/before-dev/SKILL.md +0 -40
  206. package/dist/templates/codex/skills/brainstorm/SKILL.md +0 -112
  207. package/dist/templates/codex/skills/break-loop/SKILL.md +0 -130
  208. package/dist/templates/codex/skills/check/SKILL.md +0 -98
  209. package/dist/templates/codex/skills/check-cross-layer/SKILL.md +0 -158
  210. package/dist/templates/codex/skills/create-command/SKILL.md +0 -101
  211. package/dist/templates/codex/skills/finish-work/SKILL.md +0 -90
  212. package/dist/templates/codex/skills/improve-ut/SKILL.md +0 -69
  213. package/dist/templates/codex/skills/integrate-skill/SKILL.md +0 -221
  214. package/dist/templates/codex/skills/onboard/SKILL.md +0 -363
  215. package/dist/templates/codex/skills/record-session/SKILL.md +0 -67
  216. package/dist/templates/codex/skills/start/SKILL.md +0 -66
  217. package/dist/templates/codex/skills/update-spec/SKILL.md +0 -335
  218. package/dist/templates/copilot/hooks/session-start.py +0 -557
  219. package/dist/templates/copilot/hooks.json +0 -19
  220. package/dist/templates/copilot/index.d.ts +0 -23
  221. package/dist/templates/copilot/index.d.ts.map +0 -1
  222. package/dist/templates/copilot/index.js +0 -54
  223. package/dist/templates/copilot/index.js.map +0 -1
  224. package/dist/templates/copilot/prompts/before-dev.prompt.md +0 -39
  225. package/dist/templates/copilot/prompts/brainstorm.prompt.md +0 -111
  226. package/dist/templates/copilot/prompts/break-loop.prompt.md +0 -129
  227. package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +0 -157
  228. package/dist/templates/copilot/prompts/check.prompt.md +0 -97
  229. package/dist/templates/copilot/prompts/create-command.prompt.md +0 -116
  230. package/dist/templates/copilot/prompts/finish-work.prompt.md +0 -99
  231. package/dist/templates/copilot/prompts/integrate-skill.prompt.md +0 -223
  232. package/dist/templates/copilot/prompts/onboard.prompt.md +0 -362
  233. package/dist/templates/copilot/prompts/parallel.prompt.md +0 -204
  234. package/dist/templates/copilot/prompts/record-session.prompt.md +0 -66
  235. package/dist/templates/copilot/prompts/start.prompt.md +0 -63
  236. package/dist/templates/copilot/prompts/update-spec.prompt.md +0 -358
  237. package/dist/templates/droid/droids/trellis-check.md +0 -107
  238. package/dist/templates/droid/droids/trellis-implement.md +0 -102
  239. package/dist/templates/droid/droids/trellis-research.md +0 -137
  240. package/dist/templates/droid/index.d.ts +0 -15
  241. package/dist/templates/droid/index.d.ts.map +0 -1
  242. package/dist/templates/droid/index.js +0 -15
  243. package/dist/templates/droid/index.js.map +0 -1
  244. package/dist/templates/droid/settings.json +0 -70
  245. package/dist/templates/gemini/agents/trellis-check.md +0 -107
  246. package/dist/templates/gemini/agents/trellis-implement.md +0 -102
  247. package/dist/templates/gemini/agents/trellis-research.md +0 -136
  248. package/dist/templates/gemini/index.d.ts +0 -13
  249. package/dist/templates/gemini/index.d.ts.map +0 -1
  250. package/dist/templates/gemini/index.js +0 -13
  251. package/dist/templates/gemini/index.js.map +0 -1
  252. package/dist/templates/gemini/settings.json +0 -28
  253. package/dist/templates/kiro/agents/trellis-check.json +0 -26
  254. package/dist/templates/kiro/agents/trellis-implement.json +0 -26
  255. package/dist/templates/kiro/agents/trellis-research.json +0 -30
  256. package/dist/templates/kiro/index.d.ts +0 -18
  257. package/dist/templates/kiro/index.d.ts.map +0 -1
  258. package/dist/templates/kiro/index.js +0 -18
  259. package/dist/templates/kiro/index.js.map +0 -1
  260. package/dist/templates/opencode/agents/trellis-check.md +0 -122
  261. package/dist/templates/opencode/agents/trellis-implement.md +0 -118
  262. package/dist/templates/opencode/agents/trellis-research.md +0 -145
  263. package/dist/templates/opencode/lib/session-utils.js +0 -667
  264. package/dist/templates/opencode/lib/trellis-context.js +0 -336
  265. package/dist/templates/opencode/package.json +0 -5
  266. package/dist/templates/opencode/plugins/inject-subagent-context.js +0 -495
  267. package/dist/templates/opencode/plugins/inject-workflow-state.js +0 -159
  268. package/dist/templates/opencode/plugins/session-start.js +0 -101
  269. package/dist/templates/pi/agents/trellis-check.md +0 -37
  270. package/dist/templates/pi/agents/trellis-implement.md +0 -42
  271. package/dist/templates/pi/agents/trellis-research.md +0 -25
  272. package/dist/templates/pi/extensions/trellis/index.ts.txt +0 -1600
  273. package/dist/templates/pi/index.d.ts +0 -5
  274. package/dist/templates/pi/index.d.ts.map +0 -1
  275. package/dist/templates/pi/index.js +0 -12
  276. package/dist/templates/pi/index.js.map +0 -1
  277. package/dist/templates/pi/settings.json +0 -12
  278. package/dist/templates/qoder/agents/trellis-check.md +0 -108
  279. package/dist/templates/qoder/agents/trellis-implement.md +0 -103
  280. package/dist/templates/qoder/agents/trellis-research.md +0 -137
  281. package/dist/templates/qoder/index.d.ts +0 -15
  282. package/dist/templates/qoder/index.d.ts.map +0 -1
  283. package/dist/templates/qoder/index.js +0 -15
  284. package/dist/templates/qoder/index.js.map +0 -1
  285. package/dist/templates/qoder/settings.json +0 -47
@@ -16,10 +16,6 @@ from typing import Any
16
16
  ROUTER_VERSION = 2
17
17
 
18
18
  PLATFORM_CURSOR = "cursor"
19
- PLATFORM_CLAUDE_CODE = "claude-code"
20
- PLATFORM_CODEX = "codex"
21
- PLATFORM_GENERIC = "generic"
22
- KNOWN_PLATFORMS = {PLATFORM_CURSOR, PLATFORM_CLAUDE_CODE, PLATFORM_CODEX, PLATFORM_GENERIC}
23
19
 
24
20
  MODALITY_LEXICAL = "lexical"
25
21
  MODALITY_STRUCTURAL = "structural"
@@ -193,6 +189,11 @@ def _intent(
193
189
  }
194
190
 
195
191
 
192
+ def classify_codebase_retrieval_intents(query: str) -> list[dict[str, object]]:
193
+ """Public intent classifier for hooks and dogfood scripts."""
194
+ return _classify_intents(query)
195
+
196
+
196
197
  def _classify_intents(query: str) -> list[dict[str, object]]:
197
198
  intents: list[dict[str, object]] = []
198
199
 
@@ -418,7 +419,7 @@ def _modality_for_intent(
418
419
  return [MODALITY_LEXICAL, MODALITY_STRUCTURAL, MODALITY_SEMANTIC]
419
420
 
420
421
 
421
- def _token_economy_for_route(route_id: str, platform: str) -> str:
422
+ def _token_economy_for_route(route_id: str) -> str:
422
423
  """Return a token-economy label for a given route ID."""
423
424
  high_economy = {
424
425
  "caller-chain-ast",
@@ -429,9 +430,6 @@ def _token_economy_for_route(route_id: str, platform: str) -> str:
429
430
  }
430
431
  if route_id in high_economy:
431
432
  return TOKEN_ECONOMY_HIGH
432
- low_economy = {"exact-rg-primary"}
433
- if route_id in low_economy and platform != PLATFORM_CURSOR:
434
- return TOKEN_ECONOMY_LOW
435
433
  return TOKEN_ECONOMY_MEDIUM
436
434
 
437
435
 
@@ -445,7 +443,6 @@ def _ordered_routes(
445
443
  intents: list[dict[str, object]],
446
444
  include_optional_adapters: bool,
447
445
  *,
448
- platform: str = PLATFORM_GENERIC,
449
446
  project_file_count: int | None = None,
450
447
  ) -> list[dict[str, object]]:
451
448
  ids = {str(item["id"]) for item in intents}
@@ -460,7 +457,6 @@ def _ordered_routes(
460
457
  conceptual = INTENT_CONCEPTUAL in ids
461
458
  exact_primary_first = preserve or exact
462
459
  conceptual_primary = conceptual and not preserve and not exact_primary_first
463
- is_cursor = platform == PLATFORM_CURSOR
464
460
  large = _large_project(project_file_count)
465
461
  semantic_promoted = False
466
462
 
@@ -472,7 +468,7 @@ def _ordered_routes(
472
468
  **route,
473
469
  "order": len(routes) + 1,
474
470
  "intentIds": active,
475
- "tokenEconomy": _token_economy_for_route(route_id, platform),
471
+ "tokenEconomy": _token_economy_for_route(route_id),
476
472
  "platformNative": route.get("platformNative", False),
477
473
  })
478
474
 
@@ -546,23 +542,14 @@ def _ordered_routes(
546
542
  if policy
547
543
  else "Conceptual query without exact signals; semantic recall before exact rg narrowing."
548
544
  )
549
- if is_cursor:
550
- append({
551
- "id": "platform-semantic",
552
- "role": "semantic",
553
- "sourceFamily": "platform-semantic",
554
- "commands": ["cursor @codebase or built-in semantic search"],
555
- "rationale": semantic_rationale + " (platform-native on Cursor)",
556
- "platformNative": True,
557
- })
558
- else:
559
- append({
560
- "id": "semantic-fast-context",
561
- "role": "semantic",
562
- "sourceFamily": "fast-context",
563
- "commands": ["fast_context_search query=<question> project_path=<root>"],
564
- "rationale": semantic_rationale,
565
- })
545
+ append({
546
+ "id": "platform-semantic",
547
+ "role": "semantic",
548
+ "sourceFamily": "platform-semantic",
549
+ "commands": ["cursor @codebase or built-in semantic search"],
550
+ "rationale": semantic_rationale + " (Cursor built-in semantic search)",
551
+ "platformNative": True,
552
+ })
566
553
  semantic_promoted = True
567
554
  append({
568
555
  "id": "exact-rg-primary",
@@ -649,41 +636,26 @@ def _ordered_routes(
649
636
  ],
650
637
  "rationale": cg_rationale,
651
638
  })
652
- if is_cursor:
639
+ append({
640
+ "id": "lsp-navigation",
641
+ "role": "lsp",
642
+ "sourceFamily": "language-server",
643
+ "commands": ["definition", "references", "hover"],
644
+ "rationale": (
645
+ "Optional editor/LSP navigation when exposed; "
646
+ "not guaranteed in Agent tool telemetry — prefer Read/Grep/codegraph after candidates exist."
647
+ ),
648
+ "platformNative": True,
649
+ })
650
+ if not semantic_promoted:
653
651
  append({
654
- "id": "lsp-navigation",
655
- "role": "lsp",
656
- "sourceFamily": "language-server",
657
- "commands": ["definition", "references", "hover"],
658
- "rationale": "LSP via platform-native Cursor features.",
652
+ "id": "platform-semantic",
653
+ "role": "semantic",
654
+ "sourceFamily": "platform-semantic",
655
+ "commands": ["cursor @codebase or built-in semantic search"],
656
+ "rationale": "Semantic recall via Cursor built-in codebase search.",
659
657
  "platformNative": True,
660
658
  })
661
- else:
662
- append({
663
- "id": "lsp-navigation",
664
- "role": "lsp",
665
- "sourceFamily": "language-server",
666
- "commands": ["definition", "references", "hover"],
667
- "rationale": "LSP after candidate symbols exist.",
668
- })
669
- if not semantic_promoted:
670
- if is_cursor:
671
- append({
672
- "id": "platform-semantic",
673
- "role": "semantic",
674
- "sourceFamily": "platform-semantic",
675
- "commands": ["cursor @codebase or built-in semantic search"],
676
- "rationale": "Semantic recall via platform-native Cursor search.",
677
- "platformNative": True,
678
- })
679
- else:
680
- append({
681
- "id": "semantic-fast-context",
682
- "role": "semantic",
683
- "sourceFamily": "fast-context",
684
- "commands": ["fast_context_search query=<question> project_path=<root>"],
685
- "rationale": "Semantic recall last; convert to exact rg follow-ups.",
686
- })
687
659
 
688
660
  append({
689
661
  "id": "verification-source-git-tests",
@@ -706,8 +678,6 @@ def _fallback_hints(
706
678
  intents: list[dict[str, object]],
707
679
  include_optional_adapters: bool,
708
680
  routes: list[dict[str, object]],
709
- *,
710
- platform: str = PLATFORM_GENERIC,
711
681
  ) -> list[dict[str, object]]:
712
682
  hints: list[dict[str, object]] = [
713
683
  {
@@ -715,7 +685,6 @@ def _fallback_hints(
715
685
  "action": "Codebase retrieval readiness fails; install or expose rg.",
716
686
  }
717
687
  ]
718
- is_cursor = platform == PLATFORM_CURSOR
719
688
  if not include_optional_adapters:
720
689
  hints.append({
721
690
  "when": "codebase-retrieval not selected",
@@ -741,38 +710,22 @@ def _fallback_hints(
741
710
  if include_optional_adapters and semantic_route and (
742
711
  has_conceptual or int(semantic_route.get("order", 99)) >= 3 or exact_primary
743
712
  ):
744
- if is_cursor:
745
- hints.append({
746
- "when": (
747
- "exact rg returns no corroborated file/range candidates "
748
- "(or only trap hits) before final Top-1"
749
- ),
750
- "action": (
751
- "Use Cursor @codebase or built-in semantic search per platform-semantic route, "
752
- "then narrow with rg on returned keywords and paths."
753
- ),
754
- "replacesRole": "semantic",
755
- })
756
- else:
757
- hints.append({
758
- "when": (
759
- "exact rg returns no corroborated file/range candidates "
760
- "(or only trap hits) before final Top-1"
761
- ),
762
- "action": (
763
- "Invoke fast_context_search per semantic-fast-context route, then narrow "
764
- "with rg on returned keywords and paths; semantic output remains recall-only "
765
- "until source reads confirm."
766
- ),
767
- "replacesRole": "semantic",
768
- })
713
+ hints.append({
714
+ "when": (
715
+ "exact rg returns no corroborated file/range candidates "
716
+ "(or only trap hits) before final Top-1"
717
+ ),
718
+ "action": (
719
+ "Use Cursor @codebase or built-in semantic search per platform-semantic route, "
720
+ "then narrow with rg on returned keywords and paths."
721
+ ),
722
+ "replacesRole": "semantic",
723
+ })
769
724
  return hints
770
725
 
771
726
 
772
727
  def _warnings(
773
728
  intents: list[dict[str, object]],
774
- *,
775
- platform: str = PLATFORM_GENERIC,
776
729
  ) -> list[str]:
777
730
  warnings: list[str] = []
778
731
  low = [str(item["id"]) for item in intents if item.get("confidence") == "low"]
@@ -788,9 +741,7 @@ def _warnings(
788
741
  and INTENT_EXACT not in ids
789
742
  and INTENT_PRESERVE not in ids
790
743
  ):
791
- semantic_hint = (
792
- "platform-semantic" if platform == PLATFORM_CURSOR else "semantic-fast-context"
793
- )
744
+ semantic_hint = "platform-semantic"
794
745
  warnings.append(
795
746
  f"Conceptual intent without exact signals; {semantic_hint} route promoted in plan. "
796
747
  "Convert semantic hits to exact rg follow-ups before final claims."
@@ -802,21 +753,18 @@ def route_codebase_retrieval(
802
753
  query: str,
803
754
  *,
804
755
  codebase_retrieval_selected: bool = True,
805
- platform: str = PLATFORM_GENERIC,
806
756
  project_file_count: int | None = None,
807
757
  ) -> dict[str, object]:
808
758
  """Return the shared evidence envelope with router-owned fields populated."""
809
759
  normalized = _normalize_query(query)
810
760
  include_optional = codebase_retrieval_selected
811
- normalized_platform = platform if platform in KNOWN_PLATFORMS else PLATFORM_GENERIC
812
-
813
761
  if not normalized:
814
762
  intents = [
815
763
  _intent(INTENT_EXACT, "General codebase (exact baseline)", ["empty-query"], "low", True)
816
764
  ]
817
765
  empty_routes = _ordered_routes(
818
766
  intents, include_optional,
819
- platform=normalized_platform, project_file_count=project_file_count,
767
+ project_file_count=project_file_count,
820
768
  )
821
769
  return {
822
770
  "version": ROUTER_VERSION,
@@ -825,17 +773,16 @@ def route_codebase_retrieval(
825
773
  "routes": empty_routes,
826
774
  "adapterState": [],
827
775
  "freshness": [],
828
- "fallback": _fallback_hints(intents, include_optional, empty_routes, platform=normalized_platform),
776
+ "fallback": _fallback_hints(intents, include_optional, empty_routes),
829
777
  "warnings": ["Empty query; only baseline exact route is emitted."],
830
778
  "verification": _base_verification(),
831
- "platform": normalized_platform,
832
779
  "projectFileCount": project_file_count,
833
780
  }
834
781
 
835
782
  intents = _classify_intents(normalized)
836
783
  routes = _ordered_routes(
837
784
  intents, include_optional,
838
- platform=normalized_platform, project_file_count=project_file_count,
785
+ project_file_count=project_file_count,
839
786
  )
840
787
  return {
841
788
  "version": ROUTER_VERSION,
@@ -844,10 +791,9 @@ def route_codebase_retrieval(
844
791
  "routes": routes,
845
792
  "adapterState": [],
846
793
  "freshness": [],
847
- "fallback": _fallback_hints(intents, include_optional, routes, platform=normalized_platform),
848
- "warnings": _warnings(intents, platform=normalized_platform),
794
+ "fallback": _fallback_hints(intents, include_optional, routes),
795
+ "warnings": _warnings(intents),
849
796
  "verification": _verification_for_intents(intents),
850
- "platform": normalized_platform,
851
797
  "projectFileCount": project_file_count,
852
798
  }
853
799
 
@@ -882,7 +828,6 @@ def resolve_router_envelope(
882
828
  *,
883
829
  explicit_router: dict[str, Any] | None = None,
884
830
  query: str | None = None,
885
- platform: str | None = None,
886
831
  project_file_count: int | None = None,
887
832
  ) -> dict[str, object] | None:
888
833
  """Prefer explicit routerEnvelope; otherwise route from query when present."""
@@ -893,10 +838,8 @@ def resolve_router_envelope(
893
838
  return None
894
839
  caps = load_capabilities_json(repo_root)
895
840
  selected = codebase_retrieval_selected_from_capabilities(caps)
896
- resolved_platform = platform if platform in KNOWN_PLATFORMS else PLATFORM_GENERIC
897
841
  return route_codebase_retrieval(
898
842
  normalized,
899
843
  codebase_retrieval_selected=selected,
900
- platform=resolved_platform,
901
844
  project_file_count=project_file_count,
902
845
  )
@@ -27,6 +27,8 @@ from .packages_context import (
27
27
  get_context_packages_text,
28
28
  get_context_packages_json,
29
29
  )
30
+ from .paths import get_repo_root
31
+ from .project_file_stats import resolve_project_file_count_arg
30
32
  from .retrieval_pack_context import output_retrieval_pack_json, read_evidence_input
31
33
  from .trellis_config import read_trellis_config
32
34
  from .workflow_phase import (
@@ -73,7 +75,7 @@ def main() -> None:
73
75
  )
74
76
  parser.add_argument(
75
77
  "--platform",
76
- help="Platform name for --mode phase, e.g. cursor, claude-code. Filters platform-tagged blocks.",
78
+ help="Platform name for --mode phase, e.g. cursor. Filters platform-tagged blocks.",
77
79
  )
78
80
  parser.add_argument(
79
81
  "--input",
@@ -99,6 +101,15 @@ def main() -> None:
99
101
  action="store_true",
100
102
  help="Include failed/unavailable evidence in retrieval-pack output when budget allows.",
101
103
  )
104
+ parser.add_argument(
105
+ "--project-file-count",
106
+ default="auto",
107
+ metavar="N|auto",
108
+ help=(
109
+ "For --mode retrieval-pack: file count when resolving router envelope "
110
+ "(default auto from repo root)."
111
+ ),
112
+ )
102
113
 
103
114
  args = parser.parse_args()
104
115
 
@@ -128,6 +139,10 @@ def main() -> None:
128
139
  elif args.mode == "retrieval-pack":
129
140
  try:
130
141
  evidence = read_evidence_input(args.input)
142
+ project_file_count = resolve_project_file_count_arg(
143
+ args.project_file_count,
144
+ repo_root=get_repo_root(),
145
+ )
131
146
  except (OSError, json.JSONDecodeError, ValueError) as error:
132
147
  parser.exit(1, f"retrieval pack error: {error}\n")
133
148
  output_retrieval_pack_json(
@@ -136,7 +151,7 @@ def main() -> None:
136
151
  max_estimated_tokens=args.max_estimated_tokens,
137
152
  include_diagnostics=args.include_diagnostics,
138
153
  pretty=args.json,
139
- platform=args.platform,
154
+ project_file_count=project_file_count,
140
155
  )
141
156
  else:
142
157
  if args.json:
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env python3
2
+ """Estimate project file counts for router large-repo heuristics (R-CR-013)."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import subprocess
7
+ from pathlib import Path
8
+
9
+ DEFAULT_LARGE_PROJECT_THRESHOLD = 2000
10
+
11
+ # Directories skipped when walking without git (aligned with common VCS ignore patterns).
12
+ _SKIP_DIR_NAMES = frozenset(
13
+ {
14
+ ".git",
15
+ ".trellis",
16
+ ".venv",
17
+ "venv",
18
+ "node_modules",
19
+ "dist",
20
+ "build",
21
+ "out",
22
+ ".next",
23
+ "coverage",
24
+ "__pycache__",
25
+ ".pytest_cache",
26
+ ".mypy_cache",
27
+ ".turbo",
28
+ ".codegraph",
29
+ ".cursor",
30
+ }
31
+ )
32
+
33
+
34
+ def count_project_files(repo_root: Path) -> int:
35
+ """Count tracked + untracked-but-not-ignored files under repo_root (best effort)."""
36
+ root = repo_root.resolve()
37
+ git_count = _count_via_git(root)
38
+ if git_count is not None:
39
+ return git_count
40
+ return _count_via_walk(root)
41
+
42
+
43
+ def _count_via_git(root: Path) -> int | None:
44
+ if not (root / ".git").exists():
45
+ return None
46
+ try:
47
+ proc = subprocess.run(
48
+ ["git", "-C", str(root), "ls-files", "-co", "--exclude-standard"],
49
+ capture_output=True,
50
+ text=True,
51
+ check=False,
52
+ timeout=120,
53
+ )
54
+ except (OSError, subprocess.TimeoutExpired):
55
+ return None
56
+ if proc.returncode != 0:
57
+ return None
58
+ lines = [line for line in proc.stdout.splitlines() if line.strip()]
59
+ return len(lines)
60
+
61
+
62
+ def _count_via_walk(root: Path) -> int:
63
+ total = 0
64
+ for path in root.rglob("*"):
65
+ if not path.is_file():
66
+ continue
67
+ if any(part in _SKIP_DIR_NAMES for part in path.relative_to(root).parts):
68
+ continue
69
+ total += 1
70
+ return total
71
+
72
+
73
+ def resolve_project_file_count_arg(
74
+ raw: str | int | None,
75
+ *,
76
+ repo_root: Path,
77
+ ) -> int | None:
78
+ """Parse CLI `--project-file-count` (int, `auto`, or omit → auto)."""
79
+ if raw is None:
80
+ return count_project_files(repo_root)
81
+ if isinstance(raw, int):
82
+ return raw
83
+ text = str(raw).strip().lower()
84
+ if text in {"", "auto"}:
85
+ return count_project_files(repo_root)
86
+ try:
87
+ return int(text)
88
+ except ValueError as error:
89
+ raise ValueError(
90
+ f"invalid --project-file-count {raw!r}; use a positive integer or 'auto'"
91
+ ) from error
@@ -236,18 +236,16 @@ def build_adapter_states(
236
236
  optional_integration_adapter_state(adapter=adapter, hints=hints)
237
237
  )
238
238
 
239
- # Platform-semantic: replaces fast-context on Cursor
240
- platform = string_value(router.get("platform")) if router else None
241
- if platform == "cursor":
242
- states.append(
243
- adapter_state_entry(
244
- adapter=ADAPTER_PLATFORM_SEMANTIC,
245
- state=STATE_AVAILABLE,
246
- required=False,
247
- invoked=False,
248
- reason="Platform-native semantic search on Cursor (e.g. @codebase); supersedes fast-context",
249
- )
239
+ # Platform-semantic: Cursor built-in semantic search (replaces fast-context)
240
+ states.append(
241
+ adapter_state_entry(
242
+ adapter=ADAPTER_PLATFORM_SEMANTIC,
243
+ state=STATE_AVAILABLE,
244
+ required=False,
245
+ invoked=False,
246
+ reason="Platform-native semantic search on Cursor (e.g. @codebase); supersedes fast-context",
250
247
  )
248
+ )
251
249
 
252
250
  states.append(
253
251
  adapter_state_entry(