@blxzer/cursor-trellis 0.3.0 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +51 -10
  3. package/README.zh-CN.md +21 -7
  4. package/bin/cstl.js +1 -1
  5. package/bin/smart-search.js +1 -1
  6. package/dist/cli/index.d.ts.map +1 -1
  7. package/dist/cli/index.js +17 -15
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/commands/capability-smoke.js +2 -2
  10. package/dist/commands/capability-smoke.js.map +1 -1
  11. package/dist/commands/channel/agent-loader.d.ts +1 -1
  12. package/dist/commands/channel/agent-loader.js +4 -4
  13. package/dist/commands/channel/agent-loader.js.map +1 -1
  14. package/dist/commands/channel/guard.d.ts +2 -2
  15. package/dist/commands/channel/guard.js +3 -3
  16. package/dist/commands/channel/guard.js.map +1 -1
  17. package/dist/commands/channel/index.js +3 -3
  18. package/dist/commands/channel/index.js.map +1 -1
  19. package/dist/commands/channel/list.d.ts +1 -1
  20. package/dist/commands/channel/list.js +1 -1
  21. package/dist/commands/channel/rm.d.ts +1 -1
  22. package/dist/commands/channel/rm.js +1 -1
  23. package/dist/commands/channel/store/lock.d.ts +1 -1
  24. package/dist/commands/channel/store/lock.js +1 -1
  25. package/dist/commands/channel/store/paths.js +1 -1
  26. package/dist/commands/channel/store/paths.js.map +1 -1
  27. package/dist/commands/init.d.ts.map +1 -1
  28. package/dist/commands/init.js +105 -59
  29. package/dist/commands/init.js.map +1 -1
  30. package/dist/commands/uninstall.d.ts +3 -3
  31. package/dist/commands/uninstall.d.ts.map +1 -1
  32. package/dist/commands/uninstall.js +69 -15
  33. package/dist/commands/uninstall.js.map +1 -1
  34. package/dist/commands/update.d.ts +6 -1
  35. package/dist/commands/update.d.ts.map +1 -1
  36. package/dist/commands/update.js +83 -28
  37. package/dist/commands/update.js.map +1 -1
  38. package/dist/commands/workflow.d.ts +4 -4
  39. package/dist/commands/workflow.d.ts.map +1 -1
  40. package/dist/commands/workflow.js +10 -9
  41. package/dist/commands/workflow.js.map +1 -1
  42. package/dist/configurators/index.d.ts.map +1 -1
  43. package/dist/configurators/index.js +1 -1
  44. package/dist/configurators/index.js.map +1 -1
  45. package/dist/configurators/shared.js +6 -6
  46. package/dist/configurators/shared.js.map +1 -1
  47. package/dist/configurators/workflow.d.ts +4 -4
  48. package/dist/configurators/workflow.js +1 -1
  49. package/dist/constants/paths.d.ts +24 -24
  50. package/dist/constants/paths.d.ts.map +1 -1
  51. package/dist/constants/paths.js +16 -16
  52. package/dist/constants/paths.js.map +1 -1
  53. package/dist/migrations/manifests/0.3.1.json +32 -0
  54. package/dist/templates/common/bundled-skills/cstl-cursor2plus-setup/SKILL.md +11 -11
  55. package/dist/templates/common/bundled-skills/cstl-meta/SKILL.md +15 -15
  56. package/dist/templates/common/bundled-skills/cstl-meta/references/customize-local/add-project-local-conventions.md +12 -12
  57. package/dist/templates/common/bundled-skills/cstl-meta/references/customize-local/change-agents.md +2 -2
  58. package/dist/templates/common/bundled-skills/cstl-meta/references/customize-local/change-context-loading.md +21 -21
  59. package/dist/templates/common/bundled-skills/cstl-meta/references/customize-local/change-hooks.md +9 -9
  60. package/dist/templates/common/bundled-skills/cstl-meta/references/customize-local/change-skills-or-commands.md +7 -7
  61. package/dist/templates/common/bundled-skills/cstl-meta/references/customize-local/change-spec-structure.md +15 -15
  62. package/dist/templates/common/bundled-skills/cstl-meta/references/customize-local/change-task-lifecycle.md +27 -27
  63. package/dist/templates/common/bundled-skills/cstl-meta/references/customize-local/change-workflow.md +7 -7
  64. package/dist/templates/common/bundled-skills/cstl-meta/references/customize-local/overview.md +11 -11
  65. package/dist/templates/common/bundled-skills/cstl-meta/references/local-architecture/context-injection.md +12 -12
  66. package/dist/templates/common/bundled-skills/cstl-meta/references/local-architecture/generated-files.md +21 -21
  67. package/dist/templates/common/bundled-skills/cstl-meta/references/local-architecture/overview.md +14 -14
  68. package/dist/templates/common/bundled-skills/cstl-meta/references/local-architecture/spec-system.md +12 -12
  69. package/dist/templates/common/bundled-skills/cstl-meta/references/local-architecture/task-system.md +23 -23
  70. package/dist/templates/common/bundled-skills/cstl-meta/references/local-architecture/workflow.md +3 -3
  71. package/dist/templates/common/bundled-skills/cstl-meta/references/local-architecture/workspace-memory.md +16 -16
  72. package/dist/templates/common/bundled-skills/cstl-meta/references/platform-files/agents.md +2 -2
  73. package/dist/templates/common/bundled-skills/cstl-meta/references/platform-files/hooks-and-settings.md +6 -6
  74. package/dist/templates/common/bundled-skills/cstl-meta/references/platform-files/overview.md +5 -5
  75. package/dist/templates/common/bundled-skills/cstl-meta/references/platform-files/platform-map.md +3 -3
  76. package/dist/templates/common/bundled-skills/cstl-meta/references/platform-files/skills-and-commands.md +5 -5
  77. package/dist/templates/common/bundled-skills/cstl-skill-creator/SKILL.md +2 -2
  78. package/dist/templates/common/bundled-skills/cstl-skill-creator/references/review-checklist.md +1 -1
  79. package/dist/templates/common/bundled-skills/cstl-spec-bootstrap/SKILL.md +5 -5
  80. package/dist/templates/common/bundled-skills/cstl-spec-bootstrap/references/repository-analysis.md +1 -1
  81. package/dist/templates/common/bundled-skills/cstl-spec-bootstrap/references/spec-task-planning.md +3 -3
  82. package/dist/templates/common/bundled-skills/cstl-spec-bootstrap/references/spec-writing.md +1 -1
  83. package/dist/templates/common/commands/continue.md +6 -6
  84. package/dist/templates/common/commands/finish-work.md +5 -5
  85. package/dist/templates/common/commands/start.md +8 -8
  86. package/dist/templates/common/skills/before-dev.md +4 -4
  87. package/dist/templates/common/skills/brainstorm.md +5 -5
  88. package/dist/templates/common/skills/break-loop.md +3 -3
  89. package/dist/templates/common/skills/check.md +5 -5
  90. package/dist/templates/common/skills/update-spec.md +4 -4
  91. package/dist/templates/cursor/agents/cstl-check.md +6 -6
  92. package/dist/templates/cursor/agents/cstl-implement.md +7 -7
  93. package/dist/templates/cursor/agents/cstl-research.md +9 -9
  94. package/dist/templates/cursor/commands/cursor2plus-setup.md +10 -10
  95. package/dist/templates/cursor/rules/cstl-subagent-dispatch.mdc +2 -2
  96. package/dist/templates/cursor/rules/cstl-triage.mdc +2 -2
  97. package/dist/templates/cursor/rules/retrieval-routing.mdc +4 -4
  98. package/dist/templates/extract.d.ts +1 -1
  99. package/dist/templates/extract.js +1 -1
  100. package/dist/templates/markdown/agents.md +11 -11
  101. package/dist/templates/markdown/prompts/run-semantic-slice-12.md.txt +1 -1
  102. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +5 -5
  103. package/dist/templates/markdown/spec/guides/cursor-context-injection-guide.md.txt +3 -3
  104. package/dist/templates/markdown/spec/guides/cursor-semantic-compliance.md.txt +1 -1
  105. package/dist/templates/markdown/spec/guides/cursor-subagent-policy.md.txt +11 -11
  106. package/dist/templates/markdown/spec/guides/cursor-trellis-release-coexistence-guide.md.txt +166 -0
  107. package/dist/templates/markdown/spec/guides/durable-learning-decision-guide.md.txt +8 -8
  108. package/dist/templates/markdown/spec/guides/execution-strategy.md.txt +3 -3
  109. package/dist/templates/markdown/spec/guides/index.md.txt +1 -0
  110. package/dist/templates/markdown/spec/guides/retrieval-daily-guide.md.txt +10 -10
  111. package/dist/templates/markdown/workspace-index.md +3 -3
  112. package/dist/templates/markdown/worktree.yaml.txt +1 -1
  113. package/dist/templates/shared-hooks/index.d.ts +1 -1
  114. package/dist/templates/shared-hooks/index.js +1 -1
  115. package/dist/templates/shared-hooks/inject-retrieval-plan.py +3 -3
  116. package/dist/templates/shared-hooks/inject-shell-session-context.py +7 -7
  117. package/dist/templates/shared-hooks/inject-subagent-context.py +1 -1
  118. package/dist/templates/shared-hooks/inject-workflow-state.py +11 -11
  119. package/dist/templates/shared-hooks/research-end-retrieval-pack.py +1 -1
  120. package/dist/templates/shared-hooks/session-start.py +13 -13
  121. package/dist/templates/trellis/config.yaml +2 -22
  122. package/dist/templates/trellis/index.d.ts +2 -2
  123. package/dist/templates/trellis/index.js +2 -2
  124. package/dist/templates/trellis/local/README.md +3 -3
  125. package/dist/templates/trellis/local/patch_wpelc8.py +4 -4
  126. package/dist/templates/trellis/scripts/add_session.py +20 -20
  127. package/dist/templates/trellis/scripts/common/active_task.py +2 -2
  128. package/dist/templates/trellis/scripts/common/artifact_search.py +587 -587
  129. package/dist/templates/trellis/scripts/common/codebase_retrieval_router.py +6 -6
  130. package/dist/templates/trellis/scripts/common/config.py +3 -3
  131. package/dist/templates/trellis/scripts/common/developer.py +2 -2
  132. package/dist/templates/trellis/scripts/common/packages_context.py +23 -23
  133. package/dist/templates/trellis/scripts/common/parent_orchestration.py +16 -16
  134. package/dist/templates/trellis/scripts/common/paths.py +107 -107
  135. package/dist/templates/trellis/scripts/common/project_file_stats.py +1 -1
  136. package/dist/templates/trellis/scripts/common/retrieval_agent_instructions.py +1 -1
  137. package/dist/templates/trellis/scripts/common/safe_commit.py +31 -31
  138. package/dist/templates/trellis/scripts/common/session_memory.py +360 -360
  139. package/dist/templates/trellis/scripts/common/smart_search_evidence.py +514 -514
  140. package/dist/templates/trellis/scripts/common/smart_search_resolve.py +1 -1
  141. package/dist/templates/trellis/scripts/common/subagent_dispatch.py +2 -2
  142. package/dist/templates/trellis/scripts/common/task_context.py +1 -1
  143. package/dist/templates/trellis/scripts/common/task_dashboard.py +140 -140
  144. package/dist/templates/trellis/scripts/common/task_gates.py +23 -23
  145. package/dist/templates/trellis/scripts/common/task_store.py +5 -5
  146. package/dist/templates/trellis/scripts/common/task_utils.py +3 -3
  147. package/dist/templates/trellis/scripts/common/tasks.py +1 -1
  148. package/dist/templates/trellis/scripts/common/trellis_config.py +3 -3
  149. package/dist/templates/trellis/scripts/common/workflow_phase.py +1 -1
  150. package/dist/templates/trellis/scripts/cursor_retrieval_probe.py +3 -3
  151. package/dist/templates/trellis/scripts/cursor_retrieval_probe_prompt.md +11 -11
  152. package/dist/templates/trellis/scripts/hooks/linear_sync.py +8 -8
  153. package/dist/templates/trellis/scripts/init_developer.py +2 -2
  154. package/dist/templates/trellis/scripts/retrieval_probe_matrix_template.json +4 -4
  155. package/dist/templates/trellis/scripts/route_codebase_retrieval.py +1 -1
  156. package/dist/templates/trellis/scripts/task.py +918 -918
  157. package/dist/templates/trellis/tasks/templates/release-readiness/implement.md +2 -2
  158. package/dist/templates/trellis/workflow.md +64 -64
  159. package/dist/types/migration.d.ts +1 -1
  160. package/dist/types/migration.d.ts.map +1 -1
  161. package/dist/utils/agents-md.d.ts +47 -0
  162. package/dist/utils/agents-md.d.ts.map +1 -0
  163. package/dist/utils/agents-md.js +107 -0
  164. package/dist/utils/agents-md.js.map +1 -0
  165. package/dist/utils/codebase-retrieval-router.js +5 -5
  166. package/dist/utils/codebase-retrieval-router.js.map +1 -1
  167. package/dist/utils/manifest-prune.d.ts +2 -2
  168. package/dist/utils/manifest-prune.js +4 -4
  169. package/dist/utils/manifest-prune.js.map +1 -1
  170. package/dist/utils/mirror-check.d.ts +3 -1
  171. package/dist/utils/mirror-check.d.ts.map +1 -1
  172. package/dist/utils/mirror-check.js +22 -11
  173. package/dist/utils/mirror-check.js.map +1 -1
  174. package/dist/utils/project-capabilities.js +5 -5
  175. package/dist/utils/project-capabilities.js.map +1 -1
  176. package/dist/utils/retrieval-agent-instructions.js +1 -1
  177. package/dist/utils/retrieval-agent-instructions.js.map +1 -1
  178. package/dist/utils/retrieval-execution-telemetry.js +1 -1
  179. package/dist/utils/retrieval-execution-telemetry.js.map +1 -1
  180. package/dist/utils/template-fetcher.js +1 -1
  181. package/dist/utils/template-fetcher.js.map +1 -1
  182. package/dist/utils/template-hash.d.ts +2 -2
  183. package/dist/utils/template-hash.d.ts.map +1 -1
  184. package/dist/utils/template-hash.js +51 -18
  185. package/dist/utils/template-hash.js.map +1 -1
  186. package/dist/utils/workflow-dir.d.ts +13 -0
  187. package/dist/utils/workflow-dir.d.ts.map +1 -0
  188. package/dist/utils/workflow-dir.js +35 -0
  189. package/dist/utils/workflow-dir.js.map +1 -0
  190. package/dist/utils/workflow-ownership.d.ts +36 -0
  191. package/dist/utils/workflow-ownership.d.ts.map +1 -0
  192. package/dist/utils/workflow-ownership.js +137 -0
  193. package/dist/utils/workflow-ownership.js.map +1 -0
  194. package/dist/utils/workflow-resolver.d.ts +1 -1
  195. package/dist/utils/workflow-resolver.js +1 -1
  196. package/package.json +2 -2
@@ -350,7 +350,7 @@ def _verification_for_intents(intents: list[dict[str, object]]) -> list[dict[str
350
350
  "id": "policy-doc-top1",
351
351
  "requirement": (
352
352
  "For policy/document intents, confirm Top-1 policy evidence from "
353
- "AGENTS.md or .trellis/spec before ranking implementation modules first."
353
+ "AGENTS.md or .cstl/spec before ranking implementation modules first."
354
354
  ),
355
355
  "appliesToRoles": ["exact", "semantic"],
356
356
  },
@@ -561,7 +561,7 @@ def _ordered_routes(
561
561
  "sourceFamily": "policy-docs",
562
562
  "commands": [
563
563
  'rg -i "storage default|sidecar|sqlite only" AGENTS.md "**/AGENTS.md" '
564
- "README.md CONTRIBUTING.md .trellis/spec"
564
+ "README.md CONTRIBUTING.md .cstl/spec"
565
565
  ],
566
566
  "rationale": "Policy/document intent: search instruction and spec docs first.",
567
567
  })
@@ -589,7 +589,7 @@ def _ordered_routes(
589
589
  "sourceFamily": "policy-docs",
590
590
  "commands": [
591
591
  'rg -i "storage default|sidecar|sqlite only" AGENTS.md "**/AGENTS.md" '
592
- "README.md CONTRIBUTING.md .trellis/spec"
592
+ "README.md CONTRIBUTING.md .cstl/spec"
593
593
  ],
594
594
  "rationale": "Policy/document intent: search instruction and spec docs first.",
595
595
  })
@@ -615,7 +615,7 @@ def _ordered_routes(
615
615
  "sourceFamily": "policy-docs",
616
616
  "commands": [
617
617
  'rg -i "storage default|sidecar|sqlite only" AGENTS.md "**/AGENTS.md" '
618
- "README.md CONTRIBUTING.md .trellis/spec"
618
+ "README.md CONTRIBUTING.md .cstl/spec"
619
619
  ],
620
620
  "rationale": "Policy/document branch after exact-primary when both intents match.",
621
621
  })
@@ -733,7 +733,7 @@ def _fallback_hints(
733
733
  if any(str(item["id"]) == INTENT_POLICY for item in intents):
734
734
  hints.append({
735
735
  "when": "semantic Top-1 is implementation-only for policy query",
736
- "action": "Fall back to policy-doc rg and AGENTS.md/.trellis/spec reads.",
736
+ "action": "Fall back to policy-doc rg and AGENTS.md/.cstl/spec reads.",
737
737
  "replacesRole": "semantic",
738
738
  })
739
739
  semantic_route = next(
@@ -861,7 +861,7 @@ def codebase_retrieval_selected_from_capabilities(
861
861
  def load_capabilities_json(repo_root: Path | None) -> dict[str, Any] | None:
862
862
  if repo_root is None:
863
863
  return None
864
- path = repo_root / ".trellis" / "capabilities.json"
864
+ path = repo_root / ".cstl" / "capabilities.json"
865
865
  if not path.is_file():
866
866
  return None
867
867
  try:
@@ -2,7 +2,7 @@
2
2
  """
3
3
  Trellis configuration reader.
4
4
 
5
- Reads settings from .trellis/config.yaml with sensible defaults.
5
+ Reads settings from .cstl/config.yaml with sensible defaults.
6
6
  """
7
7
 
8
8
  from __future__ import annotations
@@ -219,7 +219,7 @@ def get_session_auto_commit(repo_root: Path | None = None) -> bool:
219
219
  ``task_store.py:_auto_commit_archive``.
220
220
 
221
221
  Default: ``True`` (existing behavior — auto-stage + auto-commit).
222
- Set ``session_auto_commit: false`` in ``.trellis/config.yaml`` to skip
222
+ Set ``session_auto_commit: false`` in ``.cstl/config.yaml`` to skip
223
223
  auto-staging entirely; the journal/archive files are still written to
224
224
  disk, but the user manages ``git add`` / ``git commit`` themselves.
225
225
 
@@ -370,7 +370,7 @@ def is_monorepo(repo_root: Path | None = None) -> bool:
370
370
 
371
371
 
372
372
  def get_spec_base(package: str | None = None, repo_root: Path | None = None) -> str:
373
- """Get the spec directory base path relative to .trellis/.
373
+ """Get the spec directory base path relative to .cstl/.
374
374
 
375
375
  Single-repo: returns "spec"
376
376
  Monorepo with package: returns "spec/<package>"
@@ -34,8 +34,8 @@ def init_developer(name: str, repo_root: Path | None = None) -> bool:
34
34
  """Initialize developer.
35
35
 
36
36
  Creates:
37
- - .trellis/.developer file with developer info
38
- - .trellis/workspace/<name>/ directory structure
37
+ - .cstl/.developer file with developer info
38
+ - .cstl/workspace/<name>/ directory structure
39
39
  - Initial journal file and index.md
40
40
 
41
41
  Args:
@@ -14,12 +14,12 @@ from __future__ import annotations
14
14
  from pathlib import Path
15
15
 
16
16
  from .config import _is_true_config_value, get_default_package, get_packages, get_spec_scope
17
- from .paths import (
18
- DIR_SPEC,
19
- DIR_WORKFLOW,
20
- get_selected_task,
21
- get_repo_root,
22
- )
17
+ from .paths import (
18
+ DIR_SPEC,
19
+ DIR_WORKFLOW,
20
+ get_selected_task,
21
+ get_repo_root,
22
+ )
23
23
  from .tasks import load_task
24
24
 
25
25
 
@@ -41,13 +41,13 @@ def _scan_spec_layers(spec_dir: Path, package: str | None = None) -> list[str]:
41
41
  )
42
42
 
43
43
 
44
- def _get_selected_task_package(repo_root: Path) -> str | None:
45
- """Get the package field from the selected task's task.json."""
46
- selected = get_selected_task(repo_root)
47
- if not selected:
48
- return None
49
- ct = load_task(repo_root / selected)
50
- return ct.package if ct and ct.package else None
44
+ def _get_selected_task_package(repo_root: Path) -> str | None:
45
+ """Get the package field from the selected task's task.json."""
46
+ selected = get_selected_task(repo_root)
47
+ if not selected:
48
+ return None
49
+ ct = load_task(repo_root / selected)
50
+ return ct.package if ct and ct.package else None
51
51
 
52
52
 
53
53
  def _resolve_scope_set(
@@ -175,7 +175,7 @@ def get_context_packages_text(repo_root: Path | None = None) -> str:
175
175
  packages_dict = get_packages(repo_root) or {}
176
176
  default_pkg = get_default_package(repo_root)
177
177
  spec_scope = get_spec_scope(repo_root)
178
- task_pkg = _get_selected_task_package(repo_root)
178
+ task_pkg = _get_selected_task_package(repo_root)
179
179
  scope_set = _resolve_scope_set(packages_dict, spec_scope, task_pkg, default_pkg)
180
180
 
181
181
  lines.append("## PACKAGES")
@@ -195,7 +195,7 @@ def get_context_packages_text(repo_root: Path | None = None) -> str:
195
195
  if pkg["specLayers"]:
196
196
  lines.append(f"Spec layers: {', '.join(pkg['specLayers'])}")
197
197
  for layer in pkg["specLayers"]:
198
- lines.append(f" - .trellis/spec/{pkg['name']}/{layer}/index.md")
198
+ lines.append(f" - .cstl/spec/{pkg['name']}/{layer}/index.md")
199
199
  else:
200
200
  lines.append("Spec: not configured")
201
201
  lines.append("")
@@ -204,7 +204,7 @@ def get_context_packages_text(repo_root: Path | None = None) -> str:
204
204
  guides_dir = repo_root / DIR_WORKFLOW / DIR_SPEC / "guides"
205
205
  if guides_dir.is_dir():
206
206
  lines.append("### Shared Guides (always included)")
207
- lines.append("Path: .trellis/spec/guides/index.md")
207
+ lines.append("Path: .cstl/spec/guides/index.md")
208
208
  lines.append("")
209
209
 
210
210
  return "\n".join(lines)
@@ -230,10 +230,10 @@ def get_context_packages_json(repo_root: Path | None = None) -> dict:
230
230
  task_pkg = _get_active_task_package(repo_root)
231
231
 
232
232
  return {
233
- "mode": "monorepo",
234
- "packages": pkg_info,
235
- "defaultPackage": default_pkg,
236
- "specScope": spec_scope,
237
- "activeTaskPackage": task_pkg,
238
- "selectedTaskPackage": task_pkg,
239
- }
233
+ "mode": "monorepo",
234
+ "packages": pkg_info,
235
+ "defaultPackage": default_pkg,
236
+ "specScope": spec_scope,
237
+ "activeTaskPackage": task_pkg,
238
+ "selectedTaskPackage": task_pkg,
239
+ }
@@ -41,14 +41,14 @@ Validation baseline:
41
41
  - Run typecheck when touching TypeScript.
42
42
  - Run ESLint for changed TypeScript test/source files when applicable.
43
43
  - Run Python compile checks when touching Python scripts/templates.
44
- - Run `python ./.trellis/scripts/task.py validate <your-child-task>` before handoff."""
44
+ - Run `python ./.cstl/scripts/task.py validate <your-child-task>` before handoff."""
45
45
 
46
46
  _VALIDATION_BASELINE = """Validation baseline:
47
47
  - Run focused tests for touched behavior.
48
48
  - Run typecheck when touching TypeScript.
49
49
  - Run ESLint for changed TypeScript test/source files when applicable.
50
50
  - Run Python compile checks when touching Python scripts/templates.
51
- - Run `python ./.trellis/scripts/task.py validate <child-dir>` before handoff."""
51
+ - Run `python ./.cstl/scripts/task.py validate <child-dir>` before handoff."""
52
52
 
53
53
 
54
54
  def _utc_now() -> str:
@@ -141,13 +141,13 @@ def _child_prompt_section(
141
141
  lines.append("### Suggested child worker commands")
142
142
  lines.append("")
143
143
  lines.append("```bash")
144
- lines.append(f"python ./.trellis/scripts/task.py select {child_rel}")
144
+ lines.append(f"python ./.cstl/scripts/task.py select {child_rel}")
145
145
  lines.append(
146
- f"python ./.trellis/scripts/task.py set-child-state {parent_rel} {child_rel} working --evidence implement.md"
146
+ f"python ./.cstl/scripts/task.py set-child-state {parent_rel} {child_rel} working --evidence implement.md"
147
147
  )
148
148
  lines.append("# ... implement ...")
149
149
  lines.append(
150
- f"python ./.trellis/scripts/task.py set-child-state {parent_rel} {child_rel} review --evidence verify.md"
150
+ f"python ./.cstl/scripts/task.py set-child-state {parent_rel} {child_rel} review --evidence verify.md"
151
151
  )
152
152
  lines.append("```")
153
153
  lines.append("")
@@ -266,7 +266,7 @@ def build_child_prompt(
266
266
  f"Selected task: {child_rel}",
267
267
  "",
268
268
  "Delivery mode: subagent (Cursor)",
269
- "- **Default:** Parent session dispatches **Task** with `subagent_type=cstl-implement` and this prompt as the task description (writable sub-agent). Model under Cursor++ BYOK comes from `.trellis/local/cursor2plus/` routing (see `cursor-subagent-policy.md` Method 2.5/2.6).",
269
+ "- **Default:** Parent session dispatches **Task** with `subagent_type=cstl-implement` and this prompt as the task description (writable sub-agent). Model under Cursor++ BYOK comes from `.cstl/local/cursor2plus/` routing (see `cursor-subagent-policy.md` Method 2.5/2.6).",
270
270
  "- **Exception:** If parent `child-prompts.md` or the user names this child for a **separate writable Agent chat**, open a new Agent session, pick the model manually, paste this prompt — do not use Task from Parent.",
271
271
  "- Parent retains `review-child` / `integrate-child`. Child must not nest further `cstl-research` / `cstl-implement` / `cstl-check` Task dispatches.",
272
272
  f"- Parent orchestration: `execution_topology={topo}`, `merge_limit={merge_lim}`.",
@@ -353,11 +353,11 @@ def build_parent_status(parent_dir: Path) -> str:
353
353
  lines.append("## Suggested parent commands")
354
354
  lines.append("")
355
355
  lines.append("```bash")
356
- lines.append(f"python ./.trellis/scripts/task.py parent-status {parent_rel}")
357
- lines.append(f"python ./.trellis/scripts/task.py generate-child-prompt {parent_rel} <child> --mode subagent")
358
- lines.append(f"python ./.trellis/scripts/task.py generate-child-prompt {parent_rel} <child> --mode inline")
359
- lines.append(f"python ./.trellis/scripts/task.py review-child {parent_rel} <child> --check")
360
- lines.append(f"python ./.trellis/scripts/task.py review-child {parent_rel} <child> --decision accept --ref <ref>")
356
+ lines.append(f"python ./.cstl/scripts/task.py parent-status {parent_rel}")
357
+ lines.append(f"python ./.cstl/scripts/task.py generate-child-prompt {parent_rel} <child> --mode subagent")
358
+ lines.append(f"python ./.cstl/scripts/task.py generate-child-prompt {parent_rel} <child> --mode inline")
359
+ lines.append(f"python ./.cstl/scripts/task.py review-child {parent_rel} <child> --check")
360
+ lines.append(f"python ./.cstl/scripts/task.py review-child {parent_rel} <child> --decision accept --ref <ref>")
361
361
  lines.append("```")
362
362
  return "\n".join(lines)
363
363
 
@@ -421,10 +421,10 @@ def _learning_decision_review_lines(
421
421
  "Child verify.md has no grep-friendly durable-learning line yet. Pick one outcome:",
422
422
  "",
423
423
  "- `Durable learning decision: no durable learning` — routine scope, no reusable contract.",
424
- "- `Spec update evidence: .trellis/spec/<path>` — after `/cstl:update-spec` with reviewer confirmation.",
424
+ "- `Spec update evidence: .cstl/spec/<path>` — after `/cstl:update-spec` with reviewer confirmation.",
425
425
  f"- `Learning artifact: {child_rel}/handoff.md` — handoff already captures the insight.",
426
426
  "",
427
- f"Helper: `python ./.trellis/scripts/task.py prepare-archive-evidence {child_rel}`",
427
+ f"Helper: `python ./.cstl/scripts/task.py prepare-archive-evidence {child_rel}`",
428
428
  "",
429
429
  ]
430
430
 
@@ -524,7 +524,7 @@ def build_review_report(
524
524
  "transition": "parent-accepted",
525
525
  "optional": True,
526
526
  "hint": (
527
- f"Optional audit: python ./.trellis/scripts/task.py record-gate {parent_dir.name} "
527
+ f"Optional audit: python ./.cstl/scripts/task.py record-gate {parent_dir.name} "
528
528
  f"--transition parent-accepted --gate code-review --result PASS "
529
529
  f"--reviewer parent --evidence review-{child_name}.md"
530
530
  ),
@@ -538,7 +538,7 @@ def build_review_report(
538
538
  "transition": "child-review",
539
539
  "optional": False,
540
540
  "hint": (
541
- f"Required before accept: python ./.trellis/scripts/task.py record-gate {child_name} "
541
+ f"Required before accept: python ./.cstl/scripts/task.py record-gate {child_name} "
542
542
  f"--transition child-review --gate code-review --result PASS "
543
543
  f"--reviewer parent --evidence verify.md"
544
544
  ),
@@ -640,7 +640,7 @@ def build_review_report(
640
640
  "transition": "parent-integrated",
641
641
  "optional": False,
642
642
  "hint": (
643
- f"Required before parent archive: python ./.trellis/scripts/task.py record-gate {parent_dir.name} "
643
+ f"Required before parent archive: python ./.cstl/scripts/task.py record-gate {parent_dir.name} "
644
644
  f"--transition parent-integrated --gate integration-review --result PASS "
645
645
  f"--reviewer parent --evidence task-map.md"
646
646
  ),
@@ -22,7 +22,7 @@ from pathlib import Path
22
22
  # =============================================================================
23
23
 
24
24
  # Directory names
25
- DIR_WORKFLOW = ".trellis"
25
+ DIR_WORKFLOW = ".cstl"
26
26
  DIR_WORKSPACE = "workspace"
27
27
  DIR_TASKS = "tasks"
28
28
  DIR_ARCHIVE = "archive"
@@ -41,7 +41,7 @@ FILE_JOURNAL_PREFIX = "journal-"
41
41
  # =============================================================================
42
42
 
43
43
  def get_repo_root(start_path: Path | None = None) -> Path:
44
- """Find the nearest directory containing .trellis/ folder.
44
+ """Find the nearest directory containing .cstl/ folder.
45
45
 
46
46
  This handles nested git repos correctly (e.g., test project inside another repo).
47
47
 
@@ -49,7 +49,7 @@ def get_repo_root(start_path: Path | None = None) -> Path:
49
49
  start_path: Starting directory to search from. Defaults to current directory.
50
50
 
51
51
  Returns:
52
- Path to repository root, or current directory if no .trellis/ found.
52
+ Path to repository root, or current directory if no .cstl/ found.
53
53
  """
54
54
  current = (start_path or Path.cwd()).resolve()
55
55
 
@@ -58,7 +58,7 @@ def get_repo_root(start_path: Path | None = None) -> Path:
58
58
  return current
59
59
  current = current.parent
60
60
 
61
- # Fallback to current directory if no .trellis/ found
61
+ # Fallback to current directory if no .cstl/ found
62
62
  return Path.cwd().resolve()
63
63
 
64
64
 
@@ -204,14 +204,14 @@ def count_lines(file_path: Path) -> int:
204
204
 
205
205
 
206
206
  # =============================================================================
207
- # Selected Task Management
207
+ # Selected Task Management
208
208
  # =============================================================================
209
209
 
210
- def normalize_task_ref(task_ref: str) -> str:
210
+ def normalize_task_ref(task_ref: str) -> str:
211
211
  """Normalize a task ref for stable runtime storage.
212
212
 
213
213
  Stored refs should prefer repo-relative POSIX paths like
214
- `.trellis/tasks/03-27-my-task`, even on Windows. Absolute paths are preserved
214
+ `.cstl/tasks/03-27-my-task`, even on Windows. Absolute paths are preserved
215
215
  unless they can later be converted back to repo-relative form by callers.
216
216
  """
217
217
  normalized = task_ref.strip()
@@ -251,70 +251,70 @@ def resolve_task_ref(task_ref: str, repo_root: Path | None = None) -> Path | Non
251
251
  return repo_root / DIR_WORKFLOW / DIR_TASKS / path_obj
252
252
 
253
253
 
254
- def get_selected_task(
255
- repo_root: Path | None = None,
256
- platform_input: dict | None = None,
257
- platform: str | None = None,
258
- ) -> str | None:
259
- """Get selected task directory path (relative to repo_root).
260
-
261
- Args:
262
- repo_root: Repository root path. Defaults to auto-detected.
263
-
264
- Returns:
265
- Relative path to selected task directory or None.
266
- """
267
- if repo_root is None:
268
- repo_root = get_repo_root()
269
-
270
- from .active_task import resolve_selected_task
271
-
272
- return resolve_selected_task(repo_root, platform_input, platform).task_path
273
-
274
-
275
- def get_selected_task_abs(
276
- repo_root: Path | None = None,
277
- platform_input: dict | None = None,
278
- platform: str | None = None,
279
- ) -> Path | None:
280
- """Get selected task directory absolute path.
281
-
282
- Args:
283
- repo_root: Repository root path. Defaults to auto-detected.
284
-
285
- Returns:
286
- Absolute path to selected task directory or None.
287
- """
288
- if repo_root is None:
289
- repo_root = get_repo_root()
290
-
291
- relative = get_selected_task(repo_root, platform_input, platform)
292
- if relative:
293
- return resolve_task_ref(relative, repo_root)
294
- return None
295
-
296
-
297
- def get_selected_task_source(
298
- repo_root: Path | None = None,
299
- platform_input: dict | None = None,
300
- platform: str | None = None,
301
- ) -> tuple[str, str | None, str | None]:
302
- """Get selected task source as (`source`, `context_key`, `task_path`)."""
303
- if repo_root is None:
304
- repo_root = get_repo_root()
305
-
306
- from .active_task import get_selected_task_source as _get_source
307
-
308
- return _get_source(repo_root, platform_input, platform)
309
-
310
-
311
- def set_selected_task(
312
- task_path: str,
313
- repo_root: Path | None = None,
314
- platform_input: dict | None = None,
315
- platform: str | None = None,
316
- ) -> bool:
317
- """Set selected task in session scope.
254
+ def get_selected_task(
255
+ repo_root: Path | None = None,
256
+ platform_input: dict | None = None,
257
+ platform: str | None = None,
258
+ ) -> str | None:
259
+ """Get selected task directory path (relative to repo_root).
260
+
261
+ Args:
262
+ repo_root: Repository root path. Defaults to auto-detected.
263
+
264
+ Returns:
265
+ Relative path to selected task directory or None.
266
+ """
267
+ if repo_root is None:
268
+ repo_root = get_repo_root()
269
+
270
+ from .active_task import resolve_selected_task
271
+
272
+ return resolve_selected_task(repo_root, platform_input, platform).task_path
273
+
274
+
275
+ def get_selected_task_abs(
276
+ repo_root: Path | None = None,
277
+ platform_input: dict | None = None,
278
+ platform: str | None = None,
279
+ ) -> Path | None:
280
+ """Get selected task directory absolute path.
281
+
282
+ Args:
283
+ repo_root: Repository root path. Defaults to auto-detected.
284
+
285
+ Returns:
286
+ Absolute path to selected task directory or None.
287
+ """
288
+ if repo_root is None:
289
+ repo_root = get_repo_root()
290
+
291
+ relative = get_selected_task(repo_root, platform_input, platform)
292
+ if relative:
293
+ return resolve_task_ref(relative, repo_root)
294
+ return None
295
+
296
+
297
+ def get_selected_task_source(
298
+ repo_root: Path | None = None,
299
+ platform_input: dict | None = None,
300
+ platform: str | None = None,
301
+ ) -> tuple[str, str | None, str | None]:
302
+ """Get selected task source as (`source`, `context_key`, `task_path`)."""
303
+ if repo_root is None:
304
+ repo_root = get_repo_root()
305
+
306
+ from .active_task import get_selected_task_source as _get_source
307
+
308
+ return _get_source(repo_root, platform_input, platform)
309
+
310
+
311
+ def set_selected_task(
312
+ task_path: str,
313
+ repo_root: Path | None = None,
314
+ platform_input: dict | None = None,
315
+ platform: str | None = None,
316
+ ) -> bool:
317
+ """Set selected task in session scope.
318
318
 
319
319
  Args:
320
320
  task_path: Task directory path (relative to repo_root).
@@ -326,22 +326,22 @@ def set_selected_task(
326
326
  if repo_root is None:
327
327
  repo_root = get_repo_root()
328
328
 
329
- from .active_task import set_selected_task as _set_selected_task
330
-
331
- return _set_selected_task(
332
- task_path,
333
- repo_root,
334
- platform_input=platform_input,
329
+ from .active_task import set_selected_task as _set_selected_task
330
+
331
+ return _set_selected_task(
332
+ task_path,
333
+ repo_root,
334
+ platform_input=platform_input,
335
335
  platform=platform,
336
336
  ) is not None
337
337
 
338
338
 
339
- def clear_selected_task(
340
- repo_root: Path | None = None,
341
- platform_input: dict | None = None,
342
- platform: str | None = None,
343
- ) -> bool:
344
- """Clear selected task in session scope.
339
+ def clear_selected_task(
340
+ repo_root: Path | None = None,
341
+ platform_input: dict | None = None,
342
+ platform: str | None = None,
343
+ ) -> bool:
344
+ """Clear selected task in session scope.
345
345
 
346
346
  Args:
347
347
  repo_root: Repository root path. Defaults to auto-detected.
@@ -352,36 +352,36 @@ def clear_selected_task(
352
352
  if repo_root is None:
353
353
  repo_root = get_repo_root()
354
354
 
355
- from .active_task import clear_selected_task as _clear_selected_task
356
-
357
- _clear_selected_task(
358
- repo_root,
359
- platform_input=platform_input,
360
- platform=platform,
355
+ from .active_task import clear_selected_task as _clear_selected_task
356
+
357
+ _clear_selected_task(
358
+ repo_root,
359
+ platform_input=platform_input,
360
+ platform=platform,
361
361
  )
362
362
  return True
363
363
 
364
364
 
365
- def has_selected_task(repo_root: Path | None = None) -> bool:
366
- """Check if a selected task exists.
365
+ def has_selected_task(repo_root: Path | None = None) -> bool:
366
+ """Check if a selected task exists.
367
367
 
368
368
  Args:
369
369
  repo_root: Repository root path. Defaults to auto-detected.
370
370
 
371
371
  Returns:
372
- True if selected task is set.
373
- """
374
- return get_selected_task(repo_root) is not None
375
-
376
-
377
- # Internal compatibility aliases. New user-facing code should use selected-task
378
- # names; existing internal helpers can migrate incrementally.
379
- get_current_task = get_selected_task
380
- get_current_task_abs = get_selected_task_abs
381
- get_current_task_source = get_selected_task_source
382
- set_current_task = set_selected_task
383
- clear_current_task = clear_selected_task
384
- has_current_task = has_selected_task
372
+ True if selected task is set.
373
+ """
374
+ return get_selected_task(repo_root) is not None
375
+
376
+
377
+ # Internal compatibility aliases. New user-facing code should use selected-task
378
+ # names; existing internal helpers can migrate incrementally.
379
+ get_current_task = get_selected_task
380
+ get_current_task_abs = get_selected_task_abs
381
+ get_current_task_source = get_selected_task_source
382
+ set_current_task = set_selected_task
383
+ clear_current_task = clear_selected_task
384
+ has_current_task = has_selected_task
385
385
 
386
386
 
387
387
  # =============================================================================
@@ -405,8 +405,8 @@ def generate_task_date_prefix() -> str:
405
405
  def get_spec_dir(package: str | None = None, repo_root: Path | None = None) -> Path:
406
406
  """Get the spec directory path.
407
407
 
408
- Single-repo: .trellis/spec
409
- Monorepo with package: .trellis/spec/<package>
408
+ Single-repo: .cstl/spec
409
+ Monorepo with package: .cstl/spec/<package>
410
410
 
411
411
  Uses lazy import to avoid circular dependency with config.py.
412
412
  """
@@ -454,4 +454,4 @@ if __name__ == "__main__":
454
454
  print(f"Tasks dir: {get_tasks_dir(repo)}")
455
455
  print(f"Workspace dir: {get_workspace_dir(repo)}")
456
456
  print(f"Journal file: {get_active_journal_file(repo)}")
457
- print(f"Selected task: {get_selected_task(repo)}")
457
+ print(f"Selected task: {get_selected_task(repo)}")
@@ -12,7 +12,7 @@ DEFAULT_LARGE_PROJECT_THRESHOLD = 2000
12
12
  _SKIP_DIR_NAMES = frozenset(
13
13
  {
14
14
  ".git",
15
- ".trellis",
15
+ ".cstl",
16
16
  ".venv",
17
17
  "venv",
18
18
  "node_modules",
@@ -181,7 +181,7 @@ def _cursor_step_for_route(
181
181
 
182
182
  if route_id == "policy-docs-rg" or str(route.get("sourceFamily")) == "policy-docs":
183
183
  return (
184
- "使用 **Grep** 在 `AGENTS.md`、`**/AGENTS.md`、`.trellis/spec`、`README.md` "
184
+ "使用 **Grep** 在 `AGENTS.md`、`**/AGENTS.md`、`.cstl/spec`、`README.md` "
185
185
  "中搜索策略/边界关键词。"
186
186
  )
187
187