@blxzer/cursor-trellis 0.1.0 → 0.1.1

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 (279) 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/templates/common/bundled-skills/smart-search-cli/SKILL.md +3 -3
  24. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +4 -2
  25. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +8 -15
  26. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +7 -7
  27. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +18 -21
  28. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +2 -2
  29. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +10 -7
  30. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +4 -4
  31. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +20 -31
  32. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +20 -31
  33. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +24 -40
  34. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +28 -59
  35. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +12 -28
  36. package/dist/templates/common/bundled-skills/trellis-skill-creator/references/trellis-skill-locations.md +2 -2
  37. package/dist/templates/cursor/hooks.json +6 -0
  38. package/dist/templates/cursor/rules/retrieval-routing.mdc +57 -0
  39. package/dist/templates/extract.d.ts +0 -14
  40. package/dist/templates/extract.d.ts.map +1 -1
  41. package/dist/templates/extract.js +0 -34
  42. package/dist/templates/extract.js.map +1 -1
  43. package/dist/templates/markdown/agents.md +2 -6
  44. package/dist/templates/markdown/index.d.ts +1 -0
  45. package/dist/templates/markdown/index.d.ts.map +1 -1
  46. package/dist/templates/markdown/index.js +1 -0
  47. package/dist/templates/markdown/index.js.map +1 -1
  48. package/dist/templates/markdown/prompts/run-semantic-slice-12.md.txt +41 -0
  49. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +14 -14
  50. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +8 -20
  51. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +15 -14
  52. package/dist/templates/markdown/spec/guides/cursor-context-injection-guide.md.txt +2 -1
  53. package/dist/templates/markdown/spec/guides/cursor-semantic-compliance.md.txt +49 -0
  54. package/dist/templates/markdown/spec/guides/cursor-subagent-policy.md.txt +2 -2
  55. package/dist/templates/markdown/spec/guides/retrieval-daily-guide.md.txt +68 -20
  56. package/dist/templates/shared-hooks/index.d.ts +1 -1
  57. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  58. package/dist/templates/shared-hooks/index.js +1 -0
  59. package/dist/templates/shared-hooks/index.js.map +1 -1
  60. package/dist/templates/shared-hooks/inject-retrieval-plan.py +163 -0
  61. package/dist/templates/shared-hooks/research-end-retrieval-pack.py +2 -11
  62. package/dist/templates/trellis/index.d.ts +11 -0
  63. package/dist/templates/trellis/index.d.ts.map +1 -1
  64. package/dist/templates/trellis/index.js +22 -0
  65. package/dist/templates/trellis/index.js.map +1 -1
  66. package/dist/templates/trellis/scripts/aggregate_retrieval_telemetry.py +342 -0
  67. package/dist/templates/trellis/scripts/batch_plan_envelope.py +105 -0
  68. package/dist/templates/trellis/scripts/codegraph_session_smoke.py +76 -0
  69. package/dist/templates/trellis/scripts/common/active_task.py +116 -147
  70. package/dist/templates/trellis/scripts/common/cli_adapter.py +34 -710
  71. package/dist/templates/trellis/scripts/common/codebase_retrieval_router.py +49 -106
  72. package/dist/templates/trellis/scripts/common/git_context.py +17 -2
  73. package/dist/templates/trellis/scripts/common/project_file_stats.py +91 -0
  74. package/dist/templates/trellis/scripts/common/retrieval_adapter_metadata.py +9 -11
  75. package/dist/templates/trellis/scripts/common/retrieval_agent_instructions.py +313 -0
  76. package/dist/templates/trellis/scripts/common/retrieval_pack.py +0 -6
  77. package/dist/templates/trellis/scripts/common/retrieval_pack_context.py +0 -4
  78. package/dist/templates/trellis/scripts/common/retrieval_plan_gate.py +76 -0
  79. package/dist/templates/trellis/scripts/common/retrieval_result_ranking.py +253 -0
  80. package/dist/templates/trellis/scripts/common/retrieval_tool_classification.py +157 -0
  81. package/dist/templates/trellis/scripts/common/semantic_plan_gate.py +52 -0
  82. package/dist/templates/trellis/scripts/common/workflow_phase.py +3 -24
  83. package/dist/templates/trellis/scripts/rank_retrieval_candidates.py +80 -0
  84. package/dist/templates/trellis/scripts/route_codebase_retrieval.py +38 -11
  85. package/dist/templates/trellis/scripts/score_evidence.py +112 -0
  86. package/dist/templates/trellis/workflow.md +861 -960
  87. package/dist/types/ai-tools.d.ts +13 -16
  88. package/dist/types/ai-tools.d.ts.map +1 -1
  89. package/dist/types/ai-tools.js +5 -238
  90. package/dist/types/ai-tools.js.map +1 -1
  91. package/dist/utils/codebase-retrieval-router.d.ts +1 -8
  92. package/dist/utils/codebase-retrieval-router.d.ts.map +1 -1
  93. package/dist/utils/codebase-retrieval-router.js +39 -180
  94. package/dist/utils/codebase-retrieval-router.js.map +1 -1
  95. package/dist/utils/project-capabilities.d.ts.map +1 -1
  96. package/dist/utils/project-capabilities.js +10 -24
  97. package/dist/utils/project-capabilities.js.map +1 -1
  98. package/dist/utils/retrieval-agent-instructions.d.ts +14 -0
  99. package/dist/utils/retrieval-agent-instructions.d.ts.map +1 -0
  100. package/dist/utils/retrieval-agent-instructions.js +221 -0
  101. package/dist/utils/retrieval-agent-instructions.js.map +1 -0
  102. package/dist/utils/retrieval-execution-telemetry.d.ts +43 -85
  103. package/dist/utils/retrieval-execution-telemetry.d.ts.map +1 -1
  104. package/dist/utils/retrieval-execution-telemetry.js +289 -22
  105. package/dist/utils/retrieval-execution-telemetry.js.map +1 -1
  106. package/dist/utils/retrieval-result-ranking.js +1 -1
  107. package/dist/utils/retrieval-result-ranking.js.map +1 -1
  108. package/dist/utils/retrieval-tool-classification.d.ts +32 -0
  109. package/dist/utils/retrieval-tool-classification.d.ts.map +1 -0
  110. package/dist/utils/retrieval-tool-classification.js +113 -0
  111. package/dist/utils/retrieval-tool-classification.js.map +1 -0
  112. package/dist/utils/uninstall-scrubbers.d.ts +0 -36
  113. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
  114. package/dist/utils/uninstall-scrubbers.js +0 -184
  115. package/dist/utils/uninstall-scrubbers.js.map +1 -1
  116. package/package.json +4 -2
  117. package/dist/commands/mem.d.ts +0 -30
  118. package/dist/commands/mem.d.ts.map +0 -1
  119. package/dist/commands/mem.js +0 -424
  120. package/dist/commands/mem.js.map +0 -1
  121. package/dist/configurators/antigravity.d.ts +0 -7
  122. package/dist/configurators/antigravity.d.ts.map +0 -1
  123. package/dist/configurators/antigravity.js +0 -19
  124. package/dist/configurators/antigravity.js.map +0 -1
  125. package/dist/configurators/claude.d.ts +0 -9
  126. package/dist/configurators/claude.d.ts.map +0 -1
  127. package/dist/configurators/claude.js +0 -72
  128. package/dist/configurators/claude.js.map +0 -1
  129. package/dist/configurators/codebuddy.d.ts +0 -10
  130. package/dist/configurators/codebuddy.d.ts.map +0 -1
  131. package/dist/configurators/codebuddy.js +0 -30
  132. package/dist/configurators/codebuddy.js.map +0 -1
  133. package/dist/configurators/codex.d.ts +0 -8
  134. package/dist/configurators/codex.d.ts.map +0 -1
  135. package/dist/configurators/codex.js +0 -87
  136. package/dist/configurators/codex.js.map +0 -1
  137. package/dist/configurators/copilot.d.ts +0 -10
  138. package/dist/configurators/copilot.d.ts.map +0 -1
  139. package/dist/configurators/copilot.js +0 -51
  140. package/dist/configurators/copilot.js.map +0 -1
  141. package/dist/configurators/droid.d.ts +0 -10
  142. package/dist/configurators/droid.d.ts.map +0 -1
  143. package/dist/configurators/droid.js +0 -30
  144. package/dist/configurators/droid.js.map +0 -1
  145. package/dist/configurators/gemini.d.ts +0 -16
  146. package/dist/configurators/gemini.d.ts.map +0 -1
  147. package/dist/configurators/gemini.js +0 -38
  148. package/dist/configurators/gemini.js.map +0 -1
  149. package/dist/configurators/kilo.d.ts +0 -7
  150. package/dist/configurators/kilo.d.ts.map +0 -1
  151. package/dist/configurators/kilo.js +0 -19
  152. package/dist/configurators/kilo.js.map +0 -1
  153. package/dist/configurators/kiro.d.ts +0 -8
  154. package/dist/configurators/kiro.d.ts.map +0 -1
  155. package/dist/configurators/kiro.js +0 -24
  156. package/dist/configurators/kiro.js.map +0 -1
  157. package/dist/configurators/opencode.d.ts +0 -14
  158. package/dist/configurators/opencode.d.ts.map +0 -1
  159. package/dist/configurators/opencode.js +0 -96
  160. package/dist/configurators/opencode.js.map +0 -1
  161. package/dist/configurators/pi.d.ts +0 -3
  162. package/dist/configurators/pi.d.ts.map +0 -1
  163. package/dist/configurators/pi.js +0 -45
  164. package/dist/configurators/pi.js.map +0 -1
  165. package/dist/configurators/qoder.d.ts +0 -11
  166. package/dist/configurators/qoder.d.ts.map +0 -1
  167. package/dist/configurators/qoder.js +0 -31
  168. package/dist/configurators/qoder.js.map +0 -1
  169. package/dist/configurators/windsurf.d.ts +0 -7
  170. package/dist/configurators/windsurf.d.ts.map +0 -1
  171. package/dist/configurators/windsurf.js +0 -19
  172. package/dist/configurators/windsurf.js.map +0 -1
  173. package/dist/templates/claude/agents/trellis-check.md +0 -124
  174. package/dist/templates/claude/agents/trellis-implement.md +0 -110
  175. package/dist/templates/claude/agents/trellis-research.md +0 -137
  176. package/dist/templates/claude/index.d.ts +0 -22
  177. package/dist/templates/claude/index.d.ts.map +0 -1
  178. package/dist/templates/claude/index.js +0 -46
  179. package/dist/templates/claude/index.js.map +0 -1
  180. package/dist/templates/claude/settings.json +0 -84
  181. package/dist/templates/codebuddy/agents/trellis-check.md +0 -115
  182. package/dist/templates/codebuddy/agents/trellis-implement.md +0 -110
  183. package/dist/templates/codebuddy/agents/trellis-research.md +0 -137
  184. package/dist/templates/codebuddy/index.d.ts +0 -15
  185. package/dist/templates/codebuddy/index.d.ts.map +0 -1
  186. package/dist/templates/codebuddy/index.js +0 -15
  187. package/dist/templates/codebuddy/index.js.map +0 -1
  188. package/dist/templates/codebuddy/settings.json +0 -70
  189. package/dist/templates/codex/agents/trellis-check.toml +0 -67
  190. package/dist/templates/codex/agents/trellis-implement.toml +0 -40
  191. package/dist/templates/codex/agents/trellis-research.toml +0 -73
  192. package/dist/templates/codex/config.toml +0 -28
  193. package/dist/templates/codex/hooks/session-start.py +0 -575
  194. package/dist/templates/codex/hooks.json +0 -15
  195. package/dist/templates/codex/index.d.ts +0 -39
  196. package/dist/templates/codex/index.d.ts.map +0 -1
  197. package/dist/templates/codex/index.js +0 -85
  198. package/dist/templates/codex/index.js.map +0 -1
  199. package/dist/templates/codex/skills/before-dev/SKILL.md +0 -40
  200. package/dist/templates/codex/skills/brainstorm/SKILL.md +0 -112
  201. package/dist/templates/codex/skills/break-loop/SKILL.md +0 -130
  202. package/dist/templates/codex/skills/check/SKILL.md +0 -98
  203. package/dist/templates/codex/skills/check-cross-layer/SKILL.md +0 -158
  204. package/dist/templates/codex/skills/create-command/SKILL.md +0 -101
  205. package/dist/templates/codex/skills/finish-work/SKILL.md +0 -90
  206. package/dist/templates/codex/skills/improve-ut/SKILL.md +0 -69
  207. package/dist/templates/codex/skills/integrate-skill/SKILL.md +0 -221
  208. package/dist/templates/codex/skills/onboard/SKILL.md +0 -363
  209. package/dist/templates/codex/skills/record-session/SKILL.md +0 -67
  210. package/dist/templates/codex/skills/start/SKILL.md +0 -66
  211. package/dist/templates/codex/skills/update-spec/SKILL.md +0 -335
  212. package/dist/templates/copilot/hooks/session-start.py +0 -557
  213. package/dist/templates/copilot/hooks.json +0 -19
  214. package/dist/templates/copilot/index.d.ts +0 -23
  215. package/dist/templates/copilot/index.d.ts.map +0 -1
  216. package/dist/templates/copilot/index.js +0 -54
  217. package/dist/templates/copilot/index.js.map +0 -1
  218. package/dist/templates/copilot/prompts/before-dev.prompt.md +0 -39
  219. package/dist/templates/copilot/prompts/brainstorm.prompt.md +0 -111
  220. package/dist/templates/copilot/prompts/break-loop.prompt.md +0 -129
  221. package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +0 -157
  222. package/dist/templates/copilot/prompts/check.prompt.md +0 -97
  223. package/dist/templates/copilot/prompts/create-command.prompt.md +0 -116
  224. package/dist/templates/copilot/prompts/finish-work.prompt.md +0 -99
  225. package/dist/templates/copilot/prompts/integrate-skill.prompt.md +0 -223
  226. package/dist/templates/copilot/prompts/onboard.prompt.md +0 -362
  227. package/dist/templates/copilot/prompts/parallel.prompt.md +0 -204
  228. package/dist/templates/copilot/prompts/record-session.prompt.md +0 -66
  229. package/dist/templates/copilot/prompts/start.prompt.md +0 -63
  230. package/dist/templates/copilot/prompts/update-spec.prompt.md +0 -358
  231. package/dist/templates/droid/droids/trellis-check.md +0 -107
  232. package/dist/templates/droid/droids/trellis-implement.md +0 -102
  233. package/dist/templates/droid/droids/trellis-research.md +0 -137
  234. package/dist/templates/droid/index.d.ts +0 -15
  235. package/dist/templates/droid/index.d.ts.map +0 -1
  236. package/dist/templates/droid/index.js +0 -15
  237. package/dist/templates/droid/index.js.map +0 -1
  238. package/dist/templates/droid/settings.json +0 -70
  239. package/dist/templates/gemini/agents/trellis-check.md +0 -107
  240. package/dist/templates/gemini/agents/trellis-implement.md +0 -102
  241. package/dist/templates/gemini/agents/trellis-research.md +0 -136
  242. package/dist/templates/gemini/index.d.ts +0 -13
  243. package/dist/templates/gemini/index.d.ts.map +0 -1
  244. package/dist/templates/gemini/index.js +0 -13
  245. package/dist/templates/gemini/index.js.map +0 -1
  246. package/dist/templates/gemini/settings.json +0 -28
  247. package/dist/templates/kiro/agents/trellis-check.json +0 -26
  248. package/dist/templates/kiro/agents/trellis-implement.json +0 -26
  249. package/dist/templates/kiro/agents/trellis-research.json +0 -30
  250. package/dist/templates/kiro/index.d.ts +0 -18
  251. package/dist/templates/kiro/index.d.ts.map +0 -1
  252. package/dist/templates/kiro/index.js +0 -18
  253. package/dist/templates/kiro/index.js.map +0 -1
  254. package/dist/templates/opencode/agents/trellis-check.md +0 -122
  255. package/dist/templates/opencode/agents/trellis-implement.md +0 -118
  256. package/dist/templates/opencode/agents/trellis-research.md +0 -145
  257. package/dist/templates/opencode/lib/session-utils.js +0 -667
  258. package/dist/templates/opencode/lib/trellis-context.js +0 -336
  259. package/dist/templates/opencode/package.json +0 -5
  260. package/dist/templates/opencode/plugins/inject-subagent-context.js +0 -495
  261. package/dist/templates/opencode/plugins/inject-workflow-state.js +0 -159
  262. package/dist/templates/opencode/plugins/session-start.js +0 -101
  263. package/dist/templates/pi/agents/trellis-check.md +0 -37
  264. package/dist/templates/pi/agents/trellis-implement.md +0 -42
  265. package/dist/templates/pi/agents/trellis-research.md +0 -25
  266. package/dist/templates/pi/extensions/trellis/index.ts.txt +0 -1600
  267. package/dist/templates/pi/index.d.ts +0 -5
  268. package/dist/templates/pi/index.d.ts.map +0 -1
  269. package/dist/templates/pi/index.js +0 -12
  270. package/dist/templates/pi/index.js.map +0 -1
  271. package/dist/templates/pi/settings.json +0 -12
  272. package/dist/templates/qoder/agents/trellis-check.md +0 -108
  273. package/dist/templates/qoder/agents/trellis-implement.md +0 -103
  274. package/dist/templates/qoder/agents/trellis-research.md +0 -137
  275. package/dist/templates/qoder/index.d.ts +0 -15
  276. package/dist/templates/qoder/index.d.ts.map +0 -1
  277. package/dist/templates/qoder/index.js +0 -15
  278. package/dist/templates/qoder/index.js.map +0 -1
  279. package/dist/templates/qoder/settings.json +0 -47
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env python3
2
- """Session-scoped selected task resolution.
3
-
4
- The user-facing concept is a live-session "selected task". Trellis stores that
5
- pointer per AI session/window under `.trellis/.runtime/sessions/`; without a
6
- stable session key there is no selected task.
7
- """
2
+ """Session-scoped selected task resolution.
3
+
4
+ The user-facing concept is a live-session "selected task". Trellis stores that
5
+ pointer per AI session/window under `.trellis/.runtime/sessions/`; without a
6
+ stable session key there is no selected task.
7
+ """
8
8
 
9
9
  from __future__ import annotations
10
10
 
@@ -25,74 +25,43 @@ DIR_RUNTIME = ".runtime"
25
25
  DIR_SESSIONS = "sessions"
26
26
  DIR_CURSOR_SHELL = "cursor-shell"
27
27
  CURSOR_SHELL_TICKET_TTL_SECONDS = 30
28
- TASK_SESSION_COMMANDS = {"select", "selected", "exit"}
28
+ TASK_SESSION_COMMANDS = {"select", "selected", "exit"}
29
29
 
30
30
  _SESSION_KEYS = ("session_id", "sessionId", "sessionID")
31
31
  _CONVERSATION_KEYS = ("conversation_id", "conversationId", "conversationID")
32
32
  _TRANSCRIPT_KEYS = ("transcript_path", "transcriptPath", "transcript")
33
33
  _NESTED_KEYS = ("input", "properties", "event", "hook_input", "hookInput")
34
34
  _KNOWN_PLATFORMS = {
35
- "claude",
36
- "codex",
37
35
  "cursor",
38
- "opencode",
39
- "gemini",
40
- "droid",
41
- "qoder",
42
- "codebuddy",
43
- "kiro",
44
- "copilot",
45
- "pi",
46
36
  }
47
37
 
48
38
  _ENV_SESSION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
49
- ("claude", ("CLAUDE_SESSION_ID", "CLAUDE_CODE_SESSION_ID")),
50
- ("codex", ("CODEX_SESSION_ID", "CODEX_THREAD_ID")),
51
39
  ("cursor", ("CURSOR_SESSION_ID",)),
52
- ("opencode", ("OPENCODE_SESSION_ID", "OPENCODE_SESSIONID", "OPENCODE_RUN_ID")),
53
- ("gemini", ("GEMINI_SESSION_ID",)),
54
- ("droid", ("FACTORY_SESSION_ID", "DROID_SESSION_ID")),
55
- ("qoder", ("QODER_SESSION_ID",)),
56
- ("codebuddy", ("CODEBUDDY_SESSION_ID",)),
57
- ("kiro", ("KIRO_SESSION_ID",)),
58
- ("copilot", ("COPILOT_SESSION_ID", "COPILOT_SESSIONID")),
59
- ("pi", ("PI_SESSION_ID", "PI_SESSIONID")),
60
40
  )
61
41
  _ENV_CONVERSATION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
62
42
  ("cursor", ("CURSOR_CONVERSATION_ID", "CURSOR_CONVERSATIONID")),
63
43
  )
64
44
  _ENV_TRANSCRIPT_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
65
- ("claude", ("CLAUDE_TRANSCRIPT_PATH",)),
66
- ("codex", ("CODEX_TRANSCRIPT_PATH",)),
67
45
  ("cursor", ("CURSOR_TRANSCRIPT_PATH",)),
68
- ("gemini", ("GEMINI_TRANSCRIPT_PATH",)),
69
- ("droid", ("FACTORY_TRANSCRIPT_PATH", "DROID_TRANSCRIPT_PATH")),
70
- ("qoder", ("QODER_TRANSCRIPT_PATH",)),
71
- ("codebuddy", ("CODEBUDDY_TRANSCRIPT_PATH",)),
72
46
  )
73
- _ENV_PLATFORM_ALIASES = {
74
- "claude-code": "claude",
75
- "factory": "droid",
76
- "factory-ai": "droid",
77
- "github-copilot": "copilot",
78
- }
47
+ _ENV_PLATFORM_ALIASES: dict[str, str] = {}
79
48
 
80
49
 
81
50
  @dataclass(frozen=True)
82
- class SelectedTask:
83
- """Resolved selected task state."""
51
+ class SelectedTask:
52
+ """Resolved selected task state."""
84
53
 
85
54
  task_path: str | None
86
55
  source_type: str
87
56
  context_key: str | None = None
88
57
  stale: bool = False
89
58
 
90
- @property
91
- def source(self) -> str:
92
- """Human-readable source label."""
93
- if self.source_type == "session" and self.context_key:
94
- return f"session:{self.context_key}"
95
- return self.source_type
59
+ @property
60
+ def source(self) -> str:
61
+ """Human-readable source label."""
62
+ if self.source_type == "session" and self.context_key:
63
+ return f"session:{self.context_key}"
64
+ return self.source_type
96
65
 
97
66
 
98
67
  def normalize_task_ref(task_ref: str) -> str:
@@ -217,7 +186,7 @@ def _lookup_env_context_key(platform_name: str | None) -> str | None:
217
186
  Hooks pass `TRELLIS_CONTEXT_ID` to subprocesses they launch, but an AI-run
218
187
  shell command can only see session identity if the host platform exports it
219
188
  in the command environment. These names are best-effort adapters; if none
220
- are present, there is no session-scoped selected task.
189
+ are present, there is no session-scoped selected task.
221
190
  """
222
191
  env_platform_name = _env_platform_name(platform_name)
223
192
 
@@ -274,7 +243,7 @@ def _task_refs_match(left: str | None, right: str | None, repo_root: Path) -> bo
274
243
  return normalize_task_ref(left) == normalize_task_ref(right)
275
244
 
276
245
 
277
- def _pending_ticket_matches_args(ticket: dict[str, Any], repo_root: Path) -> bool:
246
+ def _pending_ticket_matches_args(ticket: dict[str, Any], repo_root: Path) -> bool:
278
247
  if Path(sys.argv[0]).name != "task.py":
279
248
  return False
280
249
  args = tuple(sys.argv[1:])
@@ -294,11 +263,11 @@ def _pending_ticket_matches_args(ticket: dict[str, Any], repo_root: Path) -> boo
294
263
  continue
295
264
  if _string_value(subcommand.get("name")) != command_name:
296
265
  continue
297
- if command_name != "select":
298
- return True
299
- task_ref = args[1] if len(args) > 1 else None
300
- if _task_refs_match(_string_value(subcommand.get("task_ref")), task_ref, repo_root):
301
- return True
266
+ if command_name != "select":
267
+ return True
268
+ task_ref = args[1] if len(args) > 1 else None
269
+ if _task_refs_match(_string_value(subcommand.get("task_ref")), task_ref, repo_root):
270
+ return True
302
271
 
303
272
  return False
304
273
 
@@ -446,44 +415,44 @@ def _canonical_task_ref(task_path: str, repo_root: Path) -> str | None:
446
415
  return str(full_path)
447
416
 
448
417
 
449
- def _selected_from_ref(
450
- task_ref: str | None,
451
- repo_root: Path,
452
- source_type: str,
453
- context_key: str | None = None,
454
- ) -> SelectedTask | None:
455
- if not task_ref:
456
- return None
457
- resolved = resolve_task_ref(task_ref, repo_root)
458
- stale = resolved is None or not resolved.is_dir()
459
- return SelectedTask(task_ref, source_type, context_key, stale)
418
+ def _selected_from_ref(
419
+ task_ref: str | None,
420
+ repo_root: Path,
421
+ source_type: str,
422
+ context_key: str | None = None,
423
+ ) -> SelectedTask | None:
424
+ if not task_ref:
425
+ return None
426
+ resolved = resolve_task_ref(task_ref, repo_root)
427
+ stale = resolved is None or not resolved.is_dir()
428
+ return SelectedTask(task_ref, source_type, context_key, stale)
460
429
 
461
430
 
462
431
  def _context_path(repo_root: Path, context_key: str) -> Path:
463
432
  return _runtime_sessions_dir(repo_root) / f"{context_key}.json"
464
433
 
465
434
 
466
- def resolve_selected_task(
467
- repo_root: Path,
468
- platform_input: dict[str, Any] | None = None,
469
- platform: str | None = None,
470
- ) -> SelectedTask:
471
- """Resolve the selected task from explicit session runtime state only.
472
-
473
- A stale session task is returned as stale. Missing context identity or a
474
- missing/empty session context returns no selected task. Trellis deliberately
475
- does not infer selection from the existence of a single runtime session file;
476
- every live session starts with no selected task until the user selects one.
477
- """
478
- context_key = resolve_context_key(platform_input, platform)
479
- if context_key:
480
- context = _read_json(_context_path(repo_root, context_key)) or {}
481
- task_ref = _string_value(context.get("selected_task"))
482
- selected = _selected_from_ref(task_ref, repo_root, "session", context_key)
483
- if selected:
484
- return selected
485
-
486
- return SelectedTask(None, "none", context_key)
435
+ def resolve_selected_task(
436
+ repo_root: Path,
437
+ platform_input: dict[str, Any] | None = None,
438
+ platform: str | None = None,
439
+ ) -> SelectedTask:
440
+ """Resolve the selected task from explicit session runtime state only.
441
+
442
+ A stale session task is returned as stale. Missing context identity or a
443
+ missing/empty session context returns no selected task. Trellis deliberately
444
+ does not infer selection from the existence of a single runtime session file;
445
+ every live session starts with no selected task until the user selects one.
446
+ """
447
+ context_key = resolve_context_key(platform_input, platform)
448
+ if context_key:
449
+ context = _read_json(_context_path(repo_root, context_key)) or {}
450
+ task_ref = _string_value(context.get("selected_task"))
451
+ selected = _selected_from_ref(task_ref, repo_root, "session", context_key)
452
+ if selected:
453
+ return selected
454
+
455
+ return SelectedTask(None, "none", context_key)
487
456
 
488
457
 
489
458
  def _utc_now() -> str:
@@ -512,17 +481,17 @@ def _context_metadata(
512
481
  return metadata
513
482
 
514
483
 
515
- def set_selected_task(
516
- task_path: str,
517
- repo_root: Path,
518
- platform_input: dict[str, Any] | None = None,
519
- platform: str | None = None,
520
- ) -> SelectedTask | None:
521
- """Set the selected task in session scope.
522
-
523
- Returns None when no context key is available; callers should surface a
524
- user-facing error that explains how to provide session identity.
525
- """
484
+ def set_selected_task(
485
+ task_path: str,
486
+ repo_root: Path,
487
+ platform_input: dict[str, Any] | None = None,
488
+ platform: str | None = None,
489
+ ) -> SelectedTask | None:
490
+ """Set the selected task in session scope.
491
+
492
+ Returns None when no context key is available; callers should surface a
493
+ user-facing error that explains how to provide session identity.
494
+ """
526
495
  canonical = _canonical_task_ref(task_path, repo_root)
527
496
  if canonical is None:
528
497
  return None
@@ -531,32 +500,32 @@ def set_selected_task(
531
500
  if not context_key:
532
501
  return None
533
502
 
534
- context_path = _context_path(repo_root, context_key)
535
- context = _read_json(context_path) or {}
536
- context.update(_context_metadata(platform_input, platform, context_key))
537
- context["selected_task"] = canonical
538
- context.pop("current_task", None)
539
- context.setdefault("current_run", None)
540
- if not _write_json(context_path, context):
541
- return None
542
- return SelectedTask(canonical, "session", context_key)
543
-
544
-
545
- def clear_selected_task(
546
- repo_root: Path,
547
- platform_input: dict[str, Any] | None = None,
548
- platform: str | None = None,
549
- ) -> SelectedTask:
550
- """Clear the selected task by deleting the current session context file."""
551
- context_key = resolve_context_key(platform_input, platform)
552
- if not context_key:
553
- return SelectedTask(None, "none")
554
-
555
- previous = resolve_selected_task(repo_root, platform_input, platform)
556
- context_path = _context_path(repo_root, context_key)
557
- if context_path.is_file():
558
- _remove_file(context_path)
559
- return previous
503
+ context_path = _context_path(repo_root, context_key)
504
+ context = _read_json(context_path) or {}
505
+ context.update(_context_metadata(platform_input, platform, context_key))
506
+ context["selected_task"] = canonical
507
+ context.pop("current_task", None)
508
+ context.setdefault("current_run", None)
509
+ if not _write_json(context_path, context):
510
+ return None
511
+ return SelectedTask(canonical, "session", context_key)
512
+
513
+
514
+ def clear_selected_task(
515
+ repo_root: Path,
516
+ platform_input: dict[str, Any] | None = None,
517
+ platform: str | None = None,
518
+ ) -> SelectedTask:
519
+ """Clear the selected task by deleting the current session context file."""
520
+ context_key = resolve_context_key(platform_input, platform)
521
+ if not context_key:
522
+ return SelectedTask(None, "none")
523
+
524
+ previous = resolve_selected_task(repo_root, platform_input, platform)
525
+ context_path = _context_path(repo_root, context_key)
526
+ if context_path.is_file():
527
+ _remove_file(context_path)
528
+ return previous
560
529
 
561
530
 
562
531
  def clear_task_from_sessions(task_path: str, repo_root: Path) -> int:
@@ -572,12 +541,12 @@ def clear_task_from_sessions(task_path: str, repo_root: Path) -> int:
572
541
 
573
542
  for session_path in sessions_dir.glob("*.json"):
574
543
  context = _read_json(session_path) or {}
575
- current = (
576
- _string_value(context.get("selected_task"))
577
- or _string_value(context.get("current_task"))
578
- )
579
- if not current:
580
- continue
544
+ current = (
545
+ _string_value(context.get("selected_task"))
546
+ or _string_value(context.get("current_task"))
547
+ )
548
+ if not current:
549
+ continue
581
550
  current_ref = _canonical_task_ref(current, repo_root) or normalize_task_ref(current)
582
551
  if current_ref != target:
583
552
  continue
@@ -587,21 +556,21 @@ def clear_task_from_sessions(task_path: str, repo_root: Path) -> int:
587
556
  return cleared
588
557
 
589
558
 
590
- def get_selected_task_source(
591
- repo_root: Path,
592
- platform_input: dict[str, Any] | None = None,
593
- platform: str | None = None,
594
- ) -> tuple[str, str | None, str | None]:
595
- """Return (`source_type`, `context_key`, `task_path`) for selected task."""
596
- active = resolve_selected_task(repo_root, platform_input, platform)
597
- return active.source_type, active.context_key, active.task_path
598
-
599
-
600
- # Internal compatibility aliases. User-facing commands and generated guidance
601
- # use selected-task wording, but keeping these names avoids a broad one-shot
602
- # rewrite of imports that are not part of the public command surface.
603
- ActiveTask = SelectedTask
604
- resolve_active_task = resolve_selected_task
605
- set_active_task = set_selected_task
606
- clear_active_task = clear_selected_task
607
- get_current_task_source = get_selected_task_source
559
+ def get_selected_task_source(
560
+ repo_root: Path,
561
+ platform_input: dict[str, Any] | None = None,
562
+ platform: str | None = None,
563
+ ) -> tuple[str, str | None, str | None]:
564
+ """Return (`source_type`, `context_key`, `task_path`) for selected task."""
565
+ active = resolve_selected_task(repo_root, platform_input, platform)
566
+ return active.source_type, active.context_key, active.task_path
567
+
568
+
569
+ # Internal compatibility aliases. User-facing commands and generated guidance
570
+ # use selected-task wording, but keeping these names avoids a broad one-shot
571
+ # rewrite of imports that are not part of the public command surface.
572
+ ActiveTask = SelectedTask
573
+ resolve_active_task = resolve_selected_task
574
+ set_active_task = set_selected_task
575
+ clear_active_task = clear_selected_task
576
+ get_current_task_source = get_selected_task_source