@mindfoldhq/trellis 0.5.0-beta.9 → 0.5.0-rc.0

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 (192) hide show
  1. package/README.md +60 -95
  2. package/dist/cli/index.js +7 -0
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/commands/init.d.ts +3 -0
  5. package/dist/commands/init.d.ts.map +1 -1
  6. package/dist/commands/init.js +117 -117
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/update.d.ts.map +1 -1
  9. package/dist/commands/update.js +289 -33
  10. package/dist/commands/update.js.map +1 -1
  11. package/dist/configurators/antigravity.d.ts.map +1 -1
  12. package/dist/configurators/antigravity.js +2 -8
  13. package/dist/configurators/antigravity.js.map +1 -1
  14. package/dist/configurators/claude.d.ts.map +1 -1
  15. package/dist/configurators/claude.js +4 -10
  16. package/dist/configurators/claude.js.map +1 -1
  17. package/dist/configurators/codebuddy.d.ts.map +1 -1
  18. package/dist/configurators/codebuddy.js +3 -3
  19. package/dist/configurators/codebuddy.js.map +1 -1
  20. package/dist/configurators/codex.d.ts.map +1 -1
  21. package/dist/configurators/codex.js +5 -13
  22. package/dist/configurators/codex.js.map +1 -1
  23. package/dist/configurators/copilot.d.ts.map +1 -1
  24. package/dist/configurators/copilot.js +5 -19
  25. package/dist/configurators/copilot.js.map +1 -1
  26. package/dist/configurators/cursor.d.ts.map +1 -1
  27. package/dist/configurators/cursor.js +3 -3
  28. package/dist/configurators/cursor.js.map +1 -1
  29. package/dist/configurators/droid.d.ts.map +1 -1
  30. package/dist/configurators/droid.js +3 -3
  31. package/dist/configurators/droid.js.map +1 -1
  32. package/dist/configurators/gemini.d.ts.map +1 -1
  33. package/dist/configurators/gemini.js +3 -5
  34. package/dist/configurators/gemini.js.map +1 -1
  35. package/dist/configurators/index.d.ts.map +1 -1
  36. package/dist/configurators/index.js +37 -49
  37. package/dist/configurators/index.js.map +1 -1
  38. package/dist/configurators/kilo.d.ts.map +1 -1
  39. package/dist/configurators/kilo.js +2 -8
  40. package/dist/configurators/kilo.js.map +1 -1
  41. package/dist/configurators/kiro.d.ts.map +1 -1
  42. package/dist/configurators/kiro.js +3 -3
  43. package/dist/configurators/kiro.js.map +1 -1
  44. package/dist/configurators/opencode.d.ts.map +1 -1
  45. package/dist/configurators/opencode.js +7 -4
  46. package/dist/configurators/opencode.js.map +1 -1
  47. package/dist/configurators/pi.d.ts +3 -0
  48. package/dist/configurators/pi.d.ts.map +1 -0
  49. package/dist/configurators/pi.js +44 -0
  50. package/dist/configurators/pi.js.map +1 -0
  51. package/dist/configurators/qoder.d.ts.map +1 -1
  52. package/dist/configurators/qoder.js +3 -5
  53. package/dist/configurators/qoder.js.map +1 -1
  54. package/dist/configurators/shared.d.ts +28 -6
  55. package/dist/configurators/shared.d.ts.map +1 -1
  56. package/dist/configurators/shared.js +47 -15
  57. package/dist/configurators/shared.js.map +1 -1
  58. package/dist/configurators/windsurf.d.ts.map +1 -1
  59. package/dist/configurators/windsurf.js +2 -8
  60. package/dist/configurators/windsurf.js.map +1 -1
  61. package/dist/constants/paths.d.ts +2 -0
  62. package/dist/constants/paths.d.ts.map +1 -1
  63. package/dist/constants/paths.js +2 -0
  64. package/dist/constants/paths.js.map +1 -1
  65. package/dist/migrations/manifests/0.5.0-beta.0.json +2 -0
  66. package/dist/migrations/manifests/0.5.0-beta.10.json +9 -0
  67. package/dist/migrations/manifests/0.5.0-beta.11.json +9 -0
  68. package/dist/migrations/manifests/0.5.0-beta.12.json +9 -0
  69. package/dist/migrations/manifests/0.5.0-beta.13.json +9 -0
  70. package/dist/migrations/manifests/0.5.0-beta.14.json +9 -0
  71. package/dist/migrations/manifests/0.5.0-beta.15.json +116 -0
  72. package/dist/migrations/manifests/0.5.0-beta.16.json +9 -0
  73. package/dist/migrations/manifests/0.5.0-beta.17.json +9 -0
  74. package/dist/migrations/manifests/0.5.0-beta.18.json +9 -0
  75. package/dist/migrations/manifests/0.5.0-beta.19.json +9 -0
  76. package/dist/migrations/manifests/0.5.0-beta.5.json +2 -0
  77. package/dist/migrations/manifests/0.5.0-rc.0.json +9 -0
  78. package/dist/templates/claude/agents/trellis-research.md +1 -1
  79. package/dist/templates/claude/settings.json +0 -4
  80. package/dist/templates/codebuddy/agents/trellis-research.md +1 -1
  81. package/dist/templates/codex/agents/trellis-research.toml +3 -2
  82. package/dist/templates/codex/hooks/session-start.py +126 -26
  83. package/dist/templates/codex/skills/finish-work/SKILL.md +41 -109
  84. package/dist/templates/codex/skills/start/SKILL.md +12 -9
  85. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +73 -0
  86. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/add-project-local-conventions.md +83 -0
  87. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +54 -0
  88. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +81 -0
  89. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +57 -0
  90. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +78 -0
  91. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +83 -0
  92. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +90 -0
  93. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +64 -0
  94. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +55 -0
  95. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +68 -0
  96. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +80 -0
  97. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +51 -0
  98. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +102 -0
  99. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +101 -0
  100. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workflow.md +75 -0
  101. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workspace-memory.md +71 -0
  102. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +79 -0
  103. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +69 -0
  104. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +59 -0
  105. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +74 -0
  106. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +83 -0
  107. package/dist/templates/common/commands/continue.md +9 -5
  108. package/dist/templates/common/commands/finish-work.md +34 -10
  109. package/dist/templates/common/index.d.ts +22 -2
  110. package/dist/templates/common/index.d.ts.map +1 -1
  111. package/dist/templates/common/index.js +53 -4
  112. package/dist/templates/common/index.js.map +1 -1
  113. package/dist/templates/common/skills/brainstorm.md +3 -0
  114. package/dist/templates/copilot/hooks/session-start.py +127 -30
  115. package/dist/templates/copilot/prompts/finish-work.prompt.md +44 -112
  116. package/dist/templates/copilot/prompts/start.prompt.md +12 -9
  117. package/dist/templates/cursor/agents/trellis-check.md +1 -1
  118. package/dist/templates/cursor/agents/trellis-implement.md +1 -1
  119. package/dist/templates/cursor/agents/trellis-research.md +2 -2
  120. package/dist/templates/cursor/hooks.json +7 -1
  121. package/dist/templates/droid/droids/trellis-research.md +1 -1
  122. package/dist/templates/extract.d.ts +6 -0
  123. package/dist/templates/extract.d.ts.map +1 -1
  124. package/dist/templates/extract.js +14 -0
  125. package/dist/templates/extract.js.map +1 -1
  126. package/dist/templates/gemini/agents/trellis-research.md +1 -1
  127. package/dist/templates/kiro/agents/trellis-research.json +1 -1
  128. package/dist/templates/markdown/agents.md +19 -12
  129. package/dist/templates/markdown/gitignore.txt +3 -0
  130. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +24 -0
  131. package/dist/templates/opencode/agents/trellis-check.md +1 -1
  132. package/dist/templates/opencode/agents/trellis-implement.md +7 -4
  133. package/dist/templates/opencode/agents/trellis-research.md +2 -2
  134. package/dist/templates/opencode/lib/trellis-context.js +100 -13
  135. package/dist/templates/opencode/plugins/inject-subagent-context.js +70 -5
  136. package/dist/templates/opencode/plugins/inject-workflow-state.js +38 -58
  137. package/dist/templates/opencode/plugins/session-start.js +76 -31
  138. package/dist/templates/pi/agents/trellis-check.md +28 -0
  139. package/dist/templates/pi/agents/trellis-implement.md +33 -0
  140. package/dist/templates/pi/agents/trellis-research.md +25 -0
  141. package/dist/templates/pi/extensions/trellis/index.ts.txt +997 -0
  142. package/dist/templates/pi/index.d.ts +5 -0
  143. package/dist/templates/pi/index.d.ts.map +1 -0
  144. package/dist/templates/pi/index.js +12 -0
  145. package/dist/templates/pi/index.js.map +1 -0
  146. package/dist/templates/pi/settings.json +12 -0
  147. package/dist/templates/qoder/agents/trellis-research.md +1 -1
  148. package/dist/templates/shared-hooks/index.d.ts +31 -0
  149. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  150. package/dist/templates/shared-hooks/index.js +59 -0
  151. package/dist/templates/shared-hooks/index.js.map +1 -1
  152. package/dist/templates/shared-hooks/inject-shell-session-context.py +180 -0
  153. package/dist/templates/shared-hooks/inject-subagent-context.py +156 -27
  154. package/dist/templates/shared-hooks/inject-workflow-state.py +85 -105
  155. package/dist/templates/shared-hooks/session-start.py +222 -36
  156. package/dist/templates/trellis/gitignore.txt +3 -0
  157. package/dist/templates/trellis/index.d.ts +1 -0
  158. package/dist/templates/trellis/index.d.ts.map +1 -1
  159. package/dist/templates/trellis/index.js +2 -0
  160. package/dist/templates/trellis/index.js.map +1 -1
  161. package/dist/templates/trellis/scripts/common/__init__.py +8 -0
  162. package/dist/templates/trellis/scripts/common/active_task.py +593 -0
  163. package/dist/templates/trellis/scripts/common/cli_adapter.py +72 -14
  164. package/dist/templates/trellis/scripts/common/paths.py +61 -58
  165. package/dist/templates/trellis/scripts/common/session_context.py +12 -0
  166. package/dist/templates/trellis/scripts/common/task_context.py +27 -194
  167. package/dist/templates/trellis/scripts/common/task_store.py +102 -26
  168. package/dist/templates/trellis/scripts/common/tasks.py +4 -1
  169. package/dist/templates/trellis/scripts/common/workflow_phase.py +15 -3
  170. package/dist/templates/trellis/scripts/task.py +99 -34
  171. package/dist/templates/trellis/workflow.md +332 -69
  172. package/dist/types/ai-tools.d.ts +12 -3
  173. package/dist/types/ai-tools.d.ts.map +1 -1
  174. package/dist/types/ai-tools.js +29 -0
  175. package/dist/types/ai-tools.js.map +1 -1
  176. package/dist/utils/file-writer.d.ts.map +1 -1
  177. package/dist/utils/file-writer.js +7 -2
  178. package/dist/utils/file-writer.js.map +1 -1
  179. package/dist/utils/posix.d.ts +13 -0
  180. package/dist/utils/posix.d.ts.map +1 -0
  181. package/dist/utils/posix.js +15 -0
  182. package/dist/utils/posix.js.map +1 -0
  183. package/dist/utils/template-fetcher.d.ts +22 -6
  184. package/dist/utils/template-fetcher.d.ts.map +1 -1
  185. package/dist/utils/template-fetcher.js +405 -27
  186. package/dist/utils/template-fetcher.js.map +1 -1
  187. package/dist/utils/template-hash.d.ts +22 -3
  188. package/dist/utils/template-hash.d.ts.map +1 -1
  189. package/dist/utils/template-hash.js +99 -19
  190. package/dist/utils/template-hash.js.map +1 -1
  191. package/package.json +7 -7
  192. package/dist/templates/shared-hooks/statusline.py +0 -218
@@ -3,6 +3,7 @@
3
3
  """
4
4
  Session Start Hook - Inject structured context
5
5
  """
6
+ from __future__ import annotations
6
7
 
7
8
  # IMPORTANT: Suppress all warnings FIRST
8
9
  import warnings
@@ -10,14 +11,22 @@ warnings.filterwarnings("ignore")
10
11
 
11
12
  import json
12
13
  import os
14
+ import re
15
+ import shlex
13
16
  import subprocess
14
17
  import sys
15
18
  from io import StringIO
16
19
  from pathlib import Path
17
20
 
21
+ FIRST_REPLY_NOTICE = """<first-reply-notice>
22
+ On the first visible assistant reply in this session, begin with exactly one short Chinese sentence:
23
+ Trellis SessionStart 已注入:workflow、当前任务状态、开发者身份、git 状态、active tasks、spec 索引已加载。
24
+ Then continue directly with the user's request. This notice is one-shot: do not repeat it after the first assistant reply in the same session.
25
+ </first-reply-notice>"""
26
+
18
27
  # IMPORTANT: Force stdout to use UTF-8 on Windows
19
28
  # This fixes UnicodeEncodeError when outputting non-ASCII characters
20
- if sys.platform == "win32":
29
+ if sys.platform.startswith("win"):
21
30
  import io as _io
22
31
  if hasattr(sys.stdout, "reconfigure"):
23
32
  sys.stdout.reconfigure(encoding="utf-8", errors="replace") # type: ignore[union-attr]
@@ -26,6 +35,30 @@ if sys.platform == "win32":
26
35
 
27
36
 
28
37
 
38
+ def _has_curated_jsonl_entry(jsonl_path: Path) -> bool:
39
+ """Return True iff jsonl has at least one row with a ``file`` field.
40
+
41
+ A freshly seeded jsonl only contains a ``{"_example": ...}`` row (no
42
+ ``file`` key) — that is NOT "ready". Readiness requires at least one
43
+ curated entry. Matches the contract used by hook-inject and pull-based
44
+ sub-agent context loaders.
45
+ """
46
+ try:
47
+ for line in jsonl_path.read_text(encoding="utf-8").splitlines():
48
+ line = line.strip()
49
+ if not line:
50
+ continue
51
+ try:
52
+ row = json.loads(line)
53
+ except json.JSONDecodeError:
54
+ continue
55
+ if isinstance(row, dict) and row.get("file"):
56
+ return True
57
+ except (OSError, UnicodeDecodeError):
58
+ return False
59
+ return False
60
+
61
+
29
62
  def should_skip_injection() -> bool:
30
63
  """Check if any platform's non-interactive flag is set."""
31
64
  non_interactive_vars = [
@@ -48,15 +81,97 @@ def read_file(path: Path, fallback: str = "") -> str:
48
81
  return fallback
49
82
 
50
83
 
51
- def run_script(script_path: Path) -> str:
84
+ def _detect_platform(input_data: dict) -> str | None:
85
+ if isinstance(input_data.get("cursor_version"), str):
86
+ return "cursor"
87
+ env_map = {
88
+ "CLAUDE_PROJECT_DIR": "claude",
89
+ "CURSOR_PROJECT_DIR": "cursor",
90
+ "CODEBUDDY_PROJECT_DIR": "codebuddy",
91
+ "FACTORY_PROJECT_DIR": "droid",
92
+ "GEMINI_PROJECT_DIR": "gemini",
93
+ "QODER_PROJECT_DIR": "qoder",
94
+ "KIRO_PROJECT_DIR": "kiro",
95
+ "COPILOT_PROJECT_DIR": "copilot",
96
+ }
97
+ for env_name, platform in env_map.items():
98
+ if os.environ.get(env_name):
99
+ return platform
100
+ script_parts = set(Path(sys.argv[0]).parts)
101
+ if ".claude" in script_parts:
102
+ return "claude"
103
+ if ".cursor" in script_parts:
104
+ return "cursor"
105
+ if ".codex" in script_parts:
106
+ return "codex"
107
+ if ".gemini" in script_parts:
108
+ return "gemini"
109
+ if ".qoder" in script_parts:
110
+ return "qoder"
111
+ if ".codebuddy" in script_parts:
112
+ return "codebuddy"
113
+ if ".factory" in script_parts:
114
+ return "droid"
115
+ if ".kiro" in script_parts:
116
+ return "kiro"
117
+ return None
118
+
119
+
120
+ def _resolve_context_key(trellis_dir: Path, input_data: dict) -> str | None:
121
+ scripts_dir = trellis_dir / "scripts"
122
+ if str(scripts_dir) not in sys.path:
123
+ sys.path.insert(0, str(scripts_dir))
124
+ from common.active_task import resolve_context_key # type: ignore[import-not-found]
125
+
126
+ return resolve_context_key(input_data, platform=_detect_platform(input_data))
127
+
128
+
129
+ def _persist_context_key_for_bash(context_key: str | None) -> None:
130
+ """Expose Trellis session identity to later Claude Code Bash commands.
131
+
132
+ Claude Code SessionStart hooks can append exports to CLAUDE_ENV_FILE; those
133
+ variables are then available to Bash tools in the same conversation. Without
134
+ this bridge, `task.py start` has hook stdin during SessionStart but no
135
+ session identity when the AI later runs it as a normal shell command.
136
+ """
137
+ if not context_key:
138
+ return
139
+ env_file = os.environ.get("CLAUDE_ENV_FILE")
140
+ if not env_file:
141
+ return
142
+ try:
143
+ with open(env_file, "a", encoding="utf-8") as handle:
144
+ handle.write(f"export TRELLIS_CONTEXT_ID={shlex.quote(context_key)}\n")
145
+ except OSError:
146
+ pass
147
+
148
+
149
+ def _resolve_active_task(trellis_dir: Path, input_data: dict):
150
+ scripts_dir = trellis_dir / "scripts"
151
+ if str(scripts_dir) not in sys.path:
152
+ sys.path.insert(0, str(scripts_dir))
153
+ from common.active_task import resolve_active_task # type: ignore[import-not-found]
154
+
155
+ return resolve_active_task(
156
+ trellis_dir.parent,
157
+ input_data,
158
+ platform=_detect_platform(input_data),
159
+ )
160
+
161
+
162
+ def run_script(script_path: Path, context_key: str | None = None) -> str:
52
163
  try:
53
164
  if script_path.suffix == ".py":
54
165
  # Add PYTHONIOENCODING to force UTF-8 in subprocess
55
166
  env = os.environ.copy()
56
167
  env["PYTHONIOENCODING"] = "utf-8"
168
+ if context_key:
169
+ env["TRELLIS_CONTEXT_ID"] = context_key
57
170
  cmd = [sys.executable, "-W", "ignore", str(script_path)]
58
171
  else:
59
- env = os.environ
172
+ env = os.environ.copy()
173
+ if context_key:
174
+ env["TRELLIS_CONTEXT_ID"] = context_key
60
175
  cmd = [str(script_path)]
61
176
 
62
177
  result = subprocess.run(
@@ -103,7 +218,7 @@ def _resolve_task_dir(trellis_dir: Path, task_ref: str) -> Path:
103
218
  return trellis_dir / "tasks" / path_obj
104
219
 
105
220
 
106
- def _get_task_status(trellis_dir: Path) -> str:
221
+ def _get_task_status(trellis_dir: Path, input_data: dict) -> str:
107
222
  """Check current task status and return structured status string with explicit next action.
108
223
 
109
224
  Returns a block with three fields:
@@ -111,27 +226,32 @@ def _get_task_status(trellis_dir: Path) -> str:
111
226
  - Task: task identifier (when applicable)
112
227
  - Next-Action: explicit skill/command/tool call the AI should invoke
113
228
  """
114
- current_task_file = trellis_dir / ".current-task"
229
+ active = _resolve_active_task(trellis_dir, input_data)
115
230
 
116
231
  # Case 1: No active task — waiting for user to describe intent
117
- if not current_task_file.is_file() or not current_task_file.read_text(encoding="utf-8").strip():
232
+ if not active.task_path:
118
233
  return (
119
234
  "Status: NO ACTIVE TASK\n"
235
+ f"Source: {active.source}\n"
120
236
  "Next-Action: After the user describes their intent, load skill `trellis-brainstorm` "
121
237
  "to clarify requirements and create a task via `python3 ./.trellis/scripts/task.py create`.\n"
122
238
  "Research reminder: for research-heavy tasks (comparing tools, reading external docs, "
123
239
  "cross-platform surveys), spawn `trellis-research` sub-agents via the Task tool — "
124
240
  "they persist findings to `{TASK_DIR}/research/*.md` and keep main context clean. "
125
- "Do NOT do 10+ inline WebFetch/WebSearch in the main conversation."
241
+ "Do NOT do 10+ inline WebFetch/WebSearch in the main conversation.\n"
242
+ "User override (per-turn escape hatch): if the user's first message explicitly opts "
243
+ "out of the workflow (\"跳过 trellis\" / \"别走流程\" / \"小修一下\" / \"直接改\" / "
244
+ "\"skip trellis\" / \"no task\" / \"just do it\"), honor it for this turn — "
245
+ "acknowledge briefly and proceed without creating a task. Per-turn only."
126
246
  )
127
247
 
128
- task_ref = _normalize_task_ref(current_task_file.read_text(encoding="utf-8").strip())
129
-
130
248
  # Case 2: Stale pointer — task dir was deleted
249
+ task_ref = active.task_path
131
250
  task_dir = _resolve_task_dir(trellis_dir, task_ref)
132
- if not task_dir.is_dir():
251
+ if active.stale or not task_dir.is_dir():
133
252
  return (
134
253
  f"Status: STALE POINTER\nTask: {task_ref}\n"
254
+ f"Source: {active.source}\n"
135
255
  f"Next-Action: Run `python3 ./.trellis/scripts/task.py finish` to clear the stale pointer, "
136
256
  "then ask the user what to work on next."
137
257
  )
@@ -152,6 +272,7 @@ def _get_task_status(trellis_dir: Path) -> str:
152
272
  if task_status == "completed":
153
273
  return (
154
274
  f"Status: COMPLETED\nTask: {task_title}\n"
275
+ f"Source: {active.source}\n"
155
276
  f"Next-Action: Load skill `trellis-update-spec` to capture learnings, "
156
277
  f"then archive with `python3 ./.trellis/scripts/task.py archive {task_dir.name}`."
157
278
  )
@@ -162,6 +283,7 @@ def _get_task_status(trellis_dir: Path) -> str:
162
283
  if not has_prd:
163
284
  return (
164
285
  f"Status: PLANNING\nTask: {task_title}\n"
286
+ f"Source: {active.source}\n"
165
287
  "Next-Action: Load skill `trellis-brainstorm` to clarify requirements with the user "
166
288
  "and produce prd.md in the task directory.\n"
167
289
  "Research reminder: when the task needs external research (tool comparison, docs, "
@@ -169,19 +291,38 @@ def _get_task_status(trellis_dir: Path) -> str:
169
291
  "inline in the main session. Findings go to `{task_dir}/research/*.md`; PRD only links to them."
170
292
  )
171
293
 
172
- # Case 5: PRD readyenter Execute phase
294
+ # Case 4b: PRD exists but implement.jsonl has only seed (no curated entries) Phase 1.3 gate
295
+ implement_jsonl = task_dir / "implement.jsonl"
296
+ if implement_jsonl.is_file() and not _has_curated_jsonl_entry(implement_jsonl):
297
+ return (
298
+ f"Status: PLANNING (Phase 1.3)\nTask: {task_title}\n"
299
+ f"Source: {active.source}\n"
300
+ "Next-Action: Curate `implement.jsonl` and `check.jsonl` with the spec + research files "
301
+ "the Phase 2 sub-agents will need. Only spec paths (`.trellis/spec/**/*.md`) and research "
302
+ "files (`{TASK_DIR}/research/*.md`) — no code paths. Run "
303
+ "`python3 ./.trellis/scripts/get_context.py --mode packages` to list available specs, "
304
+ "then edit the jsonl files or use `python3 ./.trellis/scripts/task.py add-context`. "
305
+ "See `.trellis/workflow.md` Phase 1.3 for details."
306
+ )
307
+
308
+ # Case 5: PRD + curated jsonl (or agent-less platform with no jsonl) — enter Execute phase
173
309
  return (
174
310
  f"Status: READY\nTask: {task_title}\n"
175
- "Next-Action: Load skill `trellis-before-dev` to read relevant specs, "
176
- "then spawn `trellis-implement` sub-agent via the Task tool. "
177
- "After implementation, spawn `trellis-check` sub-agent for quality verification.\n"
311
+ f"Source: {active.source}\n"
312
+ "Next required action: dispatch `trellis-implement` per Phase 2.1. "
313
+ "For agent-capable platforms, the default is to NOT edit code in the main session. "
314
+ "After implementation, dispatch `trellis-check` per Phase 2.2 before reporting completion.\n"
178
315
  "Sub-agent roster: `trellis-implement` (writes code), `trellis-check` (verifies + self-fixes), "
179
316
  "`trellis-research` (persists findings to `research/*.md` — use when you'd otherwise do "
180
- "multiple WebFetch/WebSearch inline)."
317
+ "multiple WebFetch/WebSearch inline).\n"
318
+ "User override (per-turn escape hatch): if the user's CURRENT message explicitly tells the "
319
+ "main session to handle it directly (\"你直接改\" / \"别派 sub-agent\" / \"main session 写就行\" / "
320
+ "\"do it inline\" / \"不用 sub-agent\"), honor it for this turn and edit code directly. "
321
+ "Per-turn only; do NOT invent an override the user did not say."
181
322
  )
182
323
 
183
324
 
184
- def _load_trellis_config(trellis_dir: Path) -> tuple:
325
+ def _load_trellis_config(trellis_dir: Path, input_data: dict) -> tuple:
185
326
  """Load Trellis config for session-start decisions.
186
327
 
187
328
  Returns:
@@ -202,7 +343,11 @@ def _load_trellis_config(trellis_dir: Path) -> tuple:
202
343
 
203
344
  # Get active task's package
204
345
  task_pkg = None
205
- current = get_current_task(repo_root)
346
+ current = get_current_task(
347
+ repo_root,
348
+ input_data,
349
+ platform=_detect_platform(input_data),
350
+ )
206
351
  if current:
207
352
  task_json = repo_root / current / "task.json"
208
353
  if task_json.is_file():
@@ -351,6 +496,24 @@ def _extract_range(content: str, start_header: str, end_header: str) -> str:
351
496
  return "\n".join(lines[start:end]).rstrip()
352
497
 
353
498
 
499
+ _BREADCRUMB_TAG_RE = re.compile(
500
+ r"\[workflow-state:([A-Za-z0-9_-]+)\]\s*\n.*?\n\s*\[/workflow-state:\1\]",
501
+ re.DOTALL,
502
+ )
503
+
504
+
505
+ def _strip_breadcrumb_tag_blocks(content: str) -> str:
506
+ """Remove `[workflow-state:STATUS]...[/workflow-state:STATUS]` blocks.
507
+
508
+ The tag blocks live inside `## Phase Index` (since v0.5.0-rc.0, when
509
+ they were colocated with their phase summaries) and are consumed by the
510
+ UserPromptSubmit hook (`inject-workflow-state.py`). The session-start
511
+ payload already covers the full step bodies, so re-inlining the
512
+ breadcrumbs here would just duplicate context.
513
+ """
514
+ return _BREADCRUMB_TAG_RE.sub("", content)
515
+
516
+
354
517
  def _build_workflow_overview(workflow_path: Path) -> str:
355
518
  """Inject the workflow guide for the session.
356
519
 
@@ -359,10 +522,13 @@ def _build_workflow_overview(workflow_path: Path) -> str:
359
522
  2. Phase Index section (rules, skill routing table, anti-rationalization table)
360
523
  3. Phase 1/2/3 step-level details (the actual how-to for each step)
361
524
 
362
- The meta sections (Core Principles / Trellis System / Workflow State
363
- Breadcrumbs) are NOT injected — Core Principles is short prose the AI can
525
+ The meta sections (Core Principles / Trellis System / Customizing
526
+ Trellis) are NOT injected — Core Principles is short prose the AI can
364
527
  Read on demand; Trellis System lists reference commands duplicated in
365
- step bodies; Breadcrumbs are consumed by the UserPromptSubmit hook.
528
+ step bodies; Customizing Trellis is for forks. Workflow-state breadcrumb
529
+ tag blocks (which now live inside Phase Index since v0.5.0-rc.0) are
530
+ stripped from the extracted range — they're consumed by the
531
+ UserPromptSubmit hook, not the session-start preamble.
366
532
 
367
533
  Total budget: Phase Index ~2 KB + Phase 1/2/3 ~7 KB = ~9 KB.
368
534
  """
@@ -381,14 +547,17 @@ def _build_workflow_overview(workflow_path: Path) -> str:
381
547
  out_lines.append(line)
382
548
  out_lines += ["", "---", ""]
383
549
 
384
- # Extract Phase Index through the end of Phase 3 (before Breadcrumbs).
385
- # Since sections appear in order Phase Index Phase 1 → Phase 2 → Phase 3
386
- # → Workflow State Breadcrumbs, a single range grab captures all four.
550
+ # Extract Phase Index through the end of Phase 3 (before "Customizing
551
+ # Trellis" the docs-for-forks footer added in v0.5.0-rc.0). Since
552
+ # sections appear in order Phase Index Phase 1 Phase 2 Phase 3
553
+ # Customizing Trellis, a single range grab captures all four. The
554
+ # breadcrumb tag blocks now embedded inside Phase Index are stripped so
555
+ # they don't duplicate the per-turn UserPromptSubmit injection.
387
556
  phases = _extract_range(
388
- content, "Phase Index", "Workflow State Breadcrumbs"
557
+ content, "Phase Index", "Customizing Trellis (for forks)"
389
558
  )
390
559
  if phases:
391
- out_lines.append(phases)
560
+ out_lines.append(_strip_breadcrumb_tag_blocks(phases).rstrip())
392
561
 
393
562
  return "\n".join(out_lines).rstrip()
394
563
 
@@ -397,7 +566,14 @@ def main():
397
566
  if should_skip_injection():
398
567
  sys.exit(0)
399
568
 
400
- # Try platform-specific env vars, fallback to cwd
569
+ try:
570
+ hook_input = json.loads(sys.stdin.read())
571
+ if not isinstance(hook_input, dict):
572
+ hook_input = {}
573
+ except (json.JSONDecodeError, ValueError):
574
+ hook_input = {}
575
+
576
+ # Try platform-specific env vars, hook cwd, fallback to cwd
401
577
  project_dir_env_vars = [
402
578
  "CLAUDE_PROJECT_DIR",
403
579
  "QODER_PROJECT_DIR",
@@ -415,12 +591,17 @@ def main():
415
591
  project_dir = Path(val).resolve()
416
592
  break
417
593
  if project_dir is None:
418
- project_dir = Path(".").resolve()
594
+ project_dir = Path(hook_input.get("cwd", ".")).resolve()
419
595
 
420
596
  trellis_dir = project_dir / ".trellis"
597
+ context_key = _resolve_context_key(trellis_dir, hook_input)
598
+ _persist_context_key_for_bash(context_key)
421
599
 
422
600
  # Load config for scope filtering and legacy detection
423
- is_mono, packages, scope_config, task_pkg, default_pkg = _load_trellis_config(trellis_dir)
601
+ is_mono, packages, scope_config, task_pkg, default_pkg = _load_trellis_config(
602
+ trellis_dir,
603
+ hook_input,
604
+ )
424
605
  allowed_pkgs = _resolve_spec_scope(is_mono, packages, scope_config, task_pkg, default_pkg)
425
606
 
426
607
  output = StringIO()
@@ -431,6 +612,8 @@ Read and follow all instructions below carefully.
431
612
  </session-context>
432
613
 
433
614
  """)
615
+ output.write(FIRST_REPLY_NOTICE)
616
+ output.write("\n\n")
434
617
 
435
618
  # Legacy migration warning
436
619
  legacy_warning = _check_legacy_spec(trellis_dir, is_mono, packages)
@@ -439,7 +622,7 @@ Read and follow all instructions below carefully.
439
622
 
440
623
  output.write("<current-state>\n")
441
624
  context_script = trellis_dir / "scripts" / "get_context.py"
442
- output.write(run_script(context_script))
625
+ output.write(run_script(context_script, context_key))
443
626
  output.write("\n</current-state>\n\n")
444
627
 
445
628
  output.write("<workflow>\n")
@@ -452,10 +635,13 @@ Read and follow all instructions below carefully.
452
635
  "**Pre-Development Checklist** listing the specific guideline files to "
453
636
  "read before coding.\n\n"
454
637
  "- If you're spawning an implement/check sub-agent, context is injected "
455
- "automatically via `{task}/implement.jsonl` / `check.jsonl`. You do NOT "
456
- "need to read these indexes yourself.\n"
457
- "- If you're editing code directly in the main session, Read the relevant "
458
- "index(es) on-demand and follow their Pre-Dev Checklist.\n\n"
638
+ "or loaded by the sub-agent via `{task}/implement.jsonl` / `check.jsonl`. "
639
+ "You do NOT need to read these indexes yourself.\n"
640
+ "- For agent-capable platforms, the default is to dispatch "
641
+ "`trellis-implement` and `trellis-check` (so JSONL context is loaded by "
642
+ "the sub-agents) rather than editing code in the main session. "
643
+ "Honor a per-turn user override only if the user's current message "
644
+ "explicitly opts out (see <task-status> below for override phrases).\n\n"
459
645
  )
460
646
 
461
647
  # guides/ is cross-package thinking — always include inline (small, broadly useful)
@@ -507,13 +693,13 @@ Read and follow all instructions below carefully.
507
693
  output.write("</guidelines>\n\n")
508
694
 
509
695
  # Check task status and inject structured tag
510
- task_status = _get_task_status(trellis_dir)
696
+ task_status = _get_task_status(trellis_dir, hook_input)
511
697
  output.write(f"<task-status>\n{task_status}\n</task-status>\n\n")
512
698
 
513
699
  output.write("""<ready>
514
700
  Context loaded. Workflow index, project state, and guidelines are already injected above — do NOT re-read them.
515
- Wait for the user's first message, then handle it following the workflow guide.
516
- If there is an active task, ask whether to continue it.
701
+ When the user sends the first message, follow <task-status> and the workflow guide.
702
+ If a task is READY, execute its Next required action without asking whether to continue.
517
703
  </ready>""")
518
704
 
519
705
  result = {
@@ -4,6 +4,9 @@
4
4
  # Current task pointer (each dev works on different task)
5
5
  .current-task
6
6
 
7
+ # Session/window scoped runtime state
8
+ .runtime/
9
+
7
10
  # Ralph Loop state file
8
11
  .ralph-state.json
9
12
 
@@ -22,6 +22,7 @@ export declare const commonDeveloper: string;
22
22
  export declare const commonGitContext: string;
23
23
  export declare const commonTaskQueue: string;
24
24
  export declare const commonTaskUtils: string;
25
+ export declare const commonActiveTask: string;
25
26
  export declare const commonCliAdapter: string;
26
27
  export declare const commonConfig: string;
27
28
  export declare const commonIo: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AAGF,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AAGvE,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAgC,CAAC;AAE/D;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAkCnD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AAGF,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AAGvE,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAgC,CAAC;AAE/D;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAmCnD"}
@@ -32,6 +32,7 @@ export const commonDeveloper = readTemplate("scripts/common/developer.py");
32
32
  export const commonGitContext = readTemplate("scripts/common/git_context.py");
33
33
  export const commonTaskQueue = readTemplate("scripts/common/task_queue.py");
34
34
  export const commonTaskUtils = readTemplate("scripts/common/task_utils.py");
35
+ export const commonActiveTask = readTemplate("scripts/common/active_task.py");
35
36
  export const commonCliAdapter = readTemplate("scripts/common/cli_adapter.py");
36
37
  export const commonConfig = readTemplate("scripts/common/config.py");
37
38
  export const commonIo = readTemplate("scripts/common/io.py");
@@ -68,6 +69,7 @@ export function getAllScripts() {
68
69
  scripts.set("common/git_context.py", commonGitContext);
69
70
  scripts.set("common/task_queue.py", commonTaskQueue);
70
71
  scripts.set("common/task_utils.py", commonTaskUtils);
72
+ scripts.set("common/active_task.py", commonActiveTask);
71
73
  scripts.set("common/cli_adapter.py", commonCliAdapter);
72
74
  scripts.set("common/config.py", commonConfig);
73
75
  scripts.set("common/io.py", commonIo);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,SAAS,YAAY,CAAC,YAAoB;IACxC,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED,gCAAgC;AAChC,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC,qBAAqB,CAAC,CAAC;AAE/D,0BAA0B;AAC1B,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC,4BAA4B,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC,yBAAyB,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,eAAe,GAAG,YAAY,CAAC,6BAA6B,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,+BAA+B,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,eAAe,GAAG,YAAY,CAAC,8BAA8B,CAAC,CAAC;AAC5E,MAAM,CAAC,MAAM,eAAe,GAAG,YAAY,CAAC,8BAA8B,CAAC,CAAC;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,+BAA+B,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,+BAA+B,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAC,0BAA0B,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,QAAQ,GAAG,YAAY,CAAC,sBAAsB,CAAC,CAAC;AAC7D,MAAM,CAAC,MAAM,SAAS,GAAG,YAAY,CAAC,uBAAuB,CAAC,CAAC;AAC/D,MAAM,CAAC,MAAM,SAAS,GAAG,YAAY,CAAC,uBAAuB,CAAC,CAAC;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC,yBAAyB,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC,yBAAyB,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,iBAAiB,GAAG,YAAY,CAAC,gCAAgC,CAAC,CAAC;AAChF,MAAM,CAAC,MAAM,eAAe,GAAG,YAAY,CAAC,8BAA8B,CAAC,CAAC;AAC5E,MAAM,CAAC,MAAM,oBAAoB,GAAG,YAAY,CAC9C,mCAAmC,CACpC,CAAC;AACF,MAAM,CAAC,MAAM,qBAAqB,GAAG,YAAY,CAC/C,oCAAoC,CACrC,CAAC;AACF,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAC7C,kCAAkC,CACnC,CAAC;AAEF,wBAAwB;AACxB,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC,0BAA0B,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAC,2BAA2B,CAAC,CAAC;AAC7E,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC,iBAAiB,CAAC,CAAC;AAC1D,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,wBAAwB,CAAC,CAAC;AACvE,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,wBAAwB,CAAC,CAAC;AAEvE,sBAAsB;AACtB,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;AAC9D,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;AAC9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;AAE/D;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE1C,eAAe;IACf,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IAExC,SAAS;IACT,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,eAAe,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,iBAAiB,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,oBAAoB,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,qBAAqB,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,mBAAmB,CAAC,CAAC;IAE7D,OAAO;IACP,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IAEhD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -82,3 +82,11 @@ from .paths import (
82
82
  has_current_task,
83
83
  generate_task_date_prefix,
84
84
  )
85
+
86
+ from .active_task import (
87
+ ActiveTask,
88
+ clear_active_task,
89
+ resolve_active_task,
90
+ resolve_context_key,
91
+ set_active_task,
92
+ )