@blxzer/cursor-trellis 0.2.9 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/README.md +85 -19
  3. package/README.zh-CN.md +60 -21
  4. package/bin/smart-search.js +1 -1
  5. package/dist/cli/index.d.ts.map +1 -1
  6. package/dist/cli/index.js +46 -18
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/commands/capability-smoke.d.ts +24 -0
  9. package/dist/commands/capability-smoke.d.ts.map +1 -0
  10. package/dist/commands/capability-smoke.js +83 -0
  11. package/dist/commands/capability-smoke.js.map +1 -0
  12. package/dist/commands/channel/agent-loader.d.ts +1 -1
  13. package/dist/commands/channel/agent-loader.js +4 -4
  14. package/dist/commands/channel/agent-loader.js.map +1 -1
  15. package/dist/commands/channel/guard.d.ts +2 -2
  16. package/dist/commands/channel/guard.js +3 -3
  17. package/dist/commands/channel/guard.js.map +1 -1
  18. package/dist/commands/channel/index.js +3 -3
  19. package/dist/commands/channel/index.js.map +1 -1
  20. package/dist/commands/channel/list.d.ts +1 -1
  21. package/dist/commands/channel/list.js +1 -1
  22. package/dist/commands/channel/rm.d.ts +1 -1
  23. package/dist/commands/channel/rm.js +1 -1
  24. package/dist/commands/channel/store/lock.d.ts +1 -1
  25. package/dist/commands/channel/store/lock.js +1 -1
  26. package/dist/commands/channel/store/paths.js +1 -1
  27. package/dist/commands/channel/store/paths.js.map +1 -1
  28. package/dist/commands/init.d.ts.map +1 -1
  29. package/dist/commands/init.js +197 -91
  30. package/dist/commands/init.js.map +1 -1
  31. package/dist/commands/uninstall.d.ts +4 -4
  32. package/dist/commands/uninstall.js +12 -12
  33. package/dist/commands/uninstall.js.map +1 -1
  34. package/dist/commands/update.d.ts +7 -2
  35. package/dist/commands/update.d.ts.map +1 -1
  36. package/dist/commands/update.js +161 -61
  37. package/dist/commands/update.js.map +1 -1
  38. package/dist/commands/upgrade.js +2 -2
  39. package/dist/commands/upgrade.js.map +1 -1
  40. package/dist/commands/workflow.d.ts +4 -4
  41. package/dist/commands/workflow.d.ts.map +1 -1
  42. package/dist/commands/workflow.js +10 -9
  43. package/dist/commands/workflow.js.map +1 -1
  44. package/dist/configurators/cursor.d.ts +2 -2
  45. package/dist/configurators/cursor.js +4 -4
  46. package/dist/configurators/cursor.js.map +1 -1
  47. package/dist/configurators/index.d.ts.map +1 -1
  48. package/dist/configurators/index.js +4 -4
  49. package/dist/configurators/index.js.map +1 -1
  50. package/dist/configurators/shared.d.ts +10 -10
  51. package/dist/configurators/shared.d.ts.map +1 -1
  52. package/dist/configurators/shared.js +32 -32
  53. package/dist/configurators/shared.js.map +1 -1
  54. package/dist/configurators/workflow.d.ts +6 -6
  55. package/dist/configurators/workflow.js +1 -1
  56. package/dist/constants/paths.d.ts +24 -24
  57. package/dist/constants/paths.d.ts.map +1 -1
  58. package/dist/constants/paths.js +16 -16
  59. package/dist/constants/paths.js.map +1 -1
  60. package/dist/migrations/manifests/0.2.10.json +374 -0
  61. package/dist/migrations/manifests/0.3.0.json +89 -0
  62. package/dist/migrations/manifests/0.3.1.json +32 -0
  63. package/dist/templates/common/bundled-skills/{trellis-cursor2plus-setup → cstl-cursor2plus-setup}/SKILL.md +15 -14
  64. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/SKILL.md +75 -75
  65. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/add-project-local-conventions.md +19 -19
  66. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-agents.md +8 -8
  67. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-context-loading.md +26 -26
  68. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-hooks.md +9 -9
  69. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-skills-or-commands.md +8 -8
  70. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-spec-structure.md +17 -17
  71. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-task-lifecycle.md +46 -46
  72. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-workflow.md +18 -18
  73. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/overview.md +55 -55
  74. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/local-architecture/context-injection.md +20 -20
  75. package/dist/templates/common/bundled-skills/cstl-meta/references/local-architecture/generated-files.md +83 -0
  76. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/local-architecture/overview.md +15 -15
  77. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/local-architecture/spec-system.md +12 -12
  78. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/local-architecture/task-system.md +34 -34
  79. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/local-architecture/workflow.md +8 -8
  80. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/local-architecture/workspace-memory.md +19 -19
  81. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/platform-files/agents.md +12 -12
  82. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/platform-files/hooks-and-settings.md +7 -7
  83. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/platform-files/overview.md +9 -9
  84. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/platform-files/platform-map.md +7 -7
  85. package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/platform-files/skills-and-commands.md +19 -19
  86. package/dist/templates/common/bundled-skills/{trellis-micro-grill → cstl-micro-grill}/SKILL.md +62 -47
  87. package/dist/templates/common/bundled-skills/{trellis-skill-creator → cstl-skill-creator}/SKILL.md +44 -44
  88. package/dist/templates/common/bundled-skills/{trellis-skill-creator → cstl-skill-creator}/references/authoring-rules.md +97 -97
  89. package/dist/templates/common/bundled-skills/{trellis-skill-creator/references/trellis-skill-locations.md → cstl-skill-creator/references/cstl-skill-locations.md} +52 -52
  90. package/dist/templates/common/bundled-skills/{trellis-skill-creator → cstl-skill-creator}/references/review-checklist.md +47 -47
  91. package/dist/templates/common/bundled-skills/{trellis-spec-bootstrap → cstl-spec-bootstrap}/SKILL.md +6 -6
  92. package/dist/templates/common/bundled-skills/{trellis-spec-bootstrap → cstl-spec-bootstrap}/references/repository-analysis.md +1 -1
  93. package/dist/templates/common/bundled-skills/{trellis-spec-bootstrap → cstl-spec-bootstrap}/references/spec-task-planning.md +3 -3
  94. package/dist/templates/common/bundled-skills/{trellis-spec-bootstrap → cstl-spec-bootstrap}/references/spec-writing.md +1 -1
  95. package/dist/templates/common/commands/continue.md +24 -24
  96. package/dist/templates/common/commands/finish-work.md +5 -5
  97. package/dist/templates/common/commands/start.md +20 -20
  98. package/dist/templates/common/index.d.ts +1 -1
  99. package/dist/templates/common/index.d.ts.map +1 -1
  100. package/dist/templates/common/skills/before-dev.md +4 -4
  101. package/dist/templates/common/skills/brainstorm.md +188 -164
  102. package/dist/templates/common/skills/break-loop.md +3 -3
  103. package/dist/templates/common/skills/check.md +5 -5
  104. package/dist/templates/common/skills/update-spec.md +4 -4
  105. package/dist/templates/cursor/agents/{trellis-check.md → cstl-check.md} +14 -14
  106. package/dist/templates/cursor/agents/{trellis-implement.md → cstl-implement.md} +14 -14
  107. package/dist/templates/cursor/agents/{trellis-research.md → cstl-research.md} +11 -11
  108. package/dist/templates/cursor/commands/cursor2plus-setup.md +15 -15
  109. package/dist/templates/cursor/fixtures/expected-rules.d.ts +1 -1
  110. package/dist/templates/cursor/fixtures/expected-rules.d.ts.map +1 -1
  111. package/dist/templates/cursor/fixtures/expected-rules.js +2 -2
  112. package/dist/templates/cursor/fixtures/expected-rules.js.map +1 -1
  113. package/dist/templates/cursor/rules/{trellis-subagent-dispatch.mdc → cstl-subagent-dispatch.mdc} +4 -4
  114. package/dist/templates/cursor/rules/{trellis-triage.mdc → cstl-triage.mdc} +3 -3
  115. package/dist/templates/cursor/rules/retrieval-routing.mdc +4 -4
  116. package/dist/templates/extract.d.ts +1 -1
  117. package/dist/templates/extract.js +1 -1
  118. package/dist/templates/markdown/agents.md +13 -13
  119. package/dist/templates/markdown/prompts/run-semantic-slice-12.md.txt +1 -1
  120. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +634 -634
  121. package/dist/templates/markdown/spec/guides/cursor-context-injection-guide.md.txt +5 -5
  122. package/dist/templates/markdown/spec/guides/cursor-semantic-compliance.md.txt +7 -1
  123. package/dist/templates/markdown/spec/guides/cursor-subagent-policy.md.txt +393 -391
  124. package/dist/templates/markdown/spec/guides/durable-learning-decision-guide.md.txt +14 -14
  125. package/dist/templates/markdown/spec/guides/execution-strategy.md.txt +5 -5
  126. package/dist/templates/markdown/spec/guides/index.md.txt +3 -2
  127. package/dist/templates/markdown/spec/guides/retrieval-daily-guide.md.txt +10 -10
  128. package/dist/templates/markdown/workspace-index.md +3 -3
  129. package/dist/templates/markdown/worktree.yaml.txt +1 -1
  130. package/dist/templates/shared-hooks/index.d.ts +2 -2
  131. package/dist/templates/shared-hooks/index.js +2 -2
  132. package/dist/templates/shared-hooks/inject-retrieval-plan.py +3 -3
  133. package/dist/templates/shared-hooks/inject-shell-session-context.py +7 -7
  134. package/dist/templates/shared-hooks/inject-subagent-context.py +4 -4
  135. package/dist/templates/shared-hooks/inject-workflow-state.py +37 -37
  136. package/dist/templates/shared-hooks/research-end-retrieval-pack.py +2 -2
  137. package/dist/templates/shared-hooks/session-start.py +16 -16
  138. package/dist/templates/trellis/config/execution-strategy-rules.json +1 -1
  139. package/dist/templates/trellis/config.yaml +5 -25
  140. package/dist/templates/trellis/index.d.ts +2 -2
  141. package/dist/templates/trellis/index.js +2 -2
  142. package/dist/templates/trellis/local/README.md +15 -13
  143. package/dist/templates/trellis/local/patch_wpelc8.py +7 -7
  144. package/dist/templates/trellis/local/subagent-models.json.example +1 -1
  145. package/dist/templates/trellis/local/trellis-task-models.json.example +3 -3
  146. package/dist/templates/trellis/local/trellis-task-models.json5.example +5 -5
  147. package/dist/templates/trellis/local/trellis_task_models_config.py +6 -6
  148. package/dist/templates/trellis/scripts/add_session.py +20 -20
  149. package/dist/templates/trellis/scripts/common/active_task.py +2 -2
  150. package/dist/templates/trellis/scripts/common/artifact_search.py +587 -587
  151. package/dist/templates/trellis/scripts/common/cli_adapter.py +3 -3
  152. package/dist/templates/trellis/scripts/common/codebase_retrieval_router.py +6 -6
  153. package/dist/templates/trellis/scripts/common/config.py +3 -3
  154. package/dist/templates/trellis/scripts/common/developer.py +2 -2
  155. package/dist/templates/trellis/scripts/common/execution_strategy.py +1 -1
  156. package/dist/templates/trellis/scripts/common/packages_context.py +23 -23
  157. package/dist/templates/trellis/scripts/common/parent_orchestration.py +702 -702
  158. package/dist/templates/trellis/scripts/common/paths.py +107 -107
  159. package/dist/templates/trellis/scripts/common/project_file_stats.py +1 -1
  160. package/dist/templates/trellis/scripts/common/retrieval_agent_instructions.py +1 -1
  161. package/dist/templates/trellis/scripts/common/safe_commit.py +31 -31
  162. package/dist/templates/trellis/scripts/common/session_context.py +1159 -1159
  163. package/dist/templates/trellis/scripts/common/session_memory.py +360 -360
  164. package/dist/templates/trellis/scripts/common/smart_search_evidence.py +514 -514
  165. package/dist/templates/trellis/scripts/common/smart_search_resolve.py +1 -1
  166. package/dist/templates/trellis/scripts/common/subagent_dispatch.py +7 -7
  167. package/dist/templates/trellis/scripts/common/task_context.py +1 -1
  168. package/dist/templates/trellis/scripts/common/task_dashboard.py +140 -140
  169. package/dist/templates/trellis/scripts/common/task_gates.py +2056 -2034
  170. package/dist/templates/trellis/scripts/common/task_store.py +1594 -1594
  171. package/dist/templates/trellis/scripts/common/task_utils.py +3 -3
  172. package/dist/templates/trellis/scripts/common/tasks.py +1 -1
  173. package/dist/templates/trellis/scripts/common/trellis_config.py +3 -3
  174. package/dist/templates/trellis/scripts/common/workflow_phase.py +1 -1
  175. package/dist/templates/trellis/scripts/cursor_retrieval_probe.py +3 -3
  176. package/dist/templates/trellis/scripts/cursor_retrieval_probe_prompt.md +11 -11
  177. package/dist/templates/trellis/scripts/hooks/linear_sync.py +8 -8
  178. package/dist/templates/trellis/scripts/init_developer.py +2 -2
  179. package/dist/templates/trellis/scripts/retrieval_probe_matrix_template.json +4 -4
  180. package/dist/templates/trellis/scripts/route_codebase_retrieval.py +1 -1
  181. package/dist/templates/trellis/scripts/task.py +918 -918
  182. package/dist/templates/trellis/tasks/templates/release-readiness/implement.md +2 -2
  183. package/dist/templates/trellis/workflow.md +805 -805
  184. package/dist/types/ai-tools.d.ts +1 -1
  185. package/dist/types/ai-tools.d.ts.map +1 -1
  186. package/dist/types/ai-tools.js +1 -1
  187. package/dist/types/ai-tools.js.map +1 -1
  188. package/dist/types/migration.d.ts +1 -1
  189. package/dist/types/migration.d.ts.map +1 -1
  190. package/dist/utils/agents-md.d.ts +37 -0
  191. package/dist/utils/agents-md.d.ts.map +1 -0
  192. package/dist/utils/agents-md.js +82 -0
  193. package/dist/utils/agents-md.js.map +1 -0
  194. package/dist/utils/codebase-retrieval-router.js +5 -5
  195. package/dist/utils/codebase-retrieval-router.js.map +1 -1
  196. package/dist/utils/manifest-prune.d.ts +2 -2
  197. package/dist/utils/manifest-prune.js +4 -4
  198. package/dist/utils/manifest-prune.js.map +1 -1
  199. package/dist/utils/mirror-check.d.ts +3 -1
  200. package/dist/utils/mirror-check.d.ts.map +1 -1
  201. package/dist/utils/mirror-check.js +22 -11
  202. package/dist/utils/mirror-check.js.map +1 -1
  203. package/dist/utils/project-capabilities.d.ts +14 -3
  204. package/dist/utils/project-capabilities.d.ts.map +1 -1
  205. package/dist/utils/project-capabilities.js +127 -17
  206. package/dist/utils/project-capabilities.js.map +1 -1
  207. package/dist/utils/readiness.d.ts +10 -0
  208. package/dist/utils/readiness.d.ts.map +1 -1
  209. package/dist/utils/readiness.js +6 -3
  210. package/dist/utils/readiness.js.map +1 -1
  211. package/dist/utils/retrieval-agent-instructions.js +1 -1
  212. package/dist/utils/retrieval-agent-instructions.js.map +1 -1
  213. package/dist/utils/retrieval-execution-telemetry.js +1 -1
  214. package/dist/utils/retrieval-execution-telemetry.js.map +1 -1
  215. package/dist/utils/template-fetcher.js +1 -1
  216. package/dist/utils/template-fetcher.js.map +1 -1
  217. package/dist/utils/template-hash.d.ts +2 -2
  218. package/dist/utils/template-hash.d.ts.map +1 -1
  219. package/dist/utils/template-hash.js +12 -10
  220. package/dist/utils/template-hash.js.map +1 -1
  221. package/dist/utils/workflow-dir.d.ts +13 -0
  222. package/dist/utils/workflow-dir.d.ts.map +1 -0
  223. package/dist/utils/workflow-dir.js +35 -0
  224. package/dist/utils/workflow-dir.js.map +1 -0
  225. package/dist/utils/workflow-ownership.d.ts +36 -0
  226. package/dist/utils/workflow-ownership.d.ts.map +1 -0
  227. package/dist/utils/workflow-ownership.js +137 -0
  228. package/dist/utils/workflow-ownership.js.map +1 -0
  229. package/dist/utils/workflow-resolver.d.ts +1 -1
  230. package/dist/utils/workflow-resolver.js +1 -1
  231. package/package.json +3 -4
  232. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +0 -83
  233. /package/bin/{trellis.js → cstl.js} +0 -0
  234. /package/dist/templates/common/bundled-skills/{trellis-spec-bootstrap → cstl-spec-bootstrap}/references/mcp-setup.md +0 -0
@@ -5,6 +5,8 @@ import inquirer from "inquirer";
5
5
  import { DIR_NAMES, FILE_NAMES, PATHS } from "../constants/paths.js";
6
6
  import { VERSION, PACKAGE_NAME } from "../constants/version.js";
7
7
  import { getMigrationsForVersion, getAllMigrations, getMigrationMetadata, getConfigSectionsAddedBetween, } from "../migrations/index.js";
8
+ import { assessCstlDirectoryMigrate } from "../utils/workflow-ownership.js";
9
+ import { isWorkflowInitialized, resolveWorkflowDirName, workflowPath, } from "../utils/workflow-dir.js";
8
10
  import { loadHashes, saveHashes, updateHashes, isTemplateModified, removeHash, renameHash, computeHash, } from "../utils/template-hash.js";
9
11
  import { compareVersions } from "../utils/compare-versions.js";
10
12
  import { toPosix } from "../utils/posix.js";
@@ -25,13 +27,18 @@ import { runPostUpdateSmoke } from "../utils/post-update-smoke.js";
25
27
  import { assertCursorRulesValid } from "../utils/validate-rules.js";
26
28
  import { buildFilePlanFromChanges, createBaseRolloutReport, emitRolloutReport, migrationResultToSummary, summarizeMigrationPlan, } from "../utils/update-rollout-report.js";
27
29
  import { snapshotReadinessForRollout } from "../utils/readiness.js";
28
- const TRELLIS_BLOCK_START = "<!-- TRELLIS:START -->";
29
- const TRELLIS_BLOCK_END = "<!-- TRELLIS:END -->";
30
+ function logCursor2plusCompatHint(cwd) {
31
+ const bundleDir = path.join(cwd, DIR_NAMES.WORKFLOW, "local", "cursor2plus");
32
+ if (!fs.existsSync(bundleDir)) {
33
+ return;
34
+ }
35
+ console.log(chalk.gray("\nCursor++ BYOK: after Cursor/Cursor++ upgrades, run `python .cstl/local/cursor2plus/patch_wpelc8.py --check-compat` before re-applying Method 2.5."));
36
+ }
37
+ const CSTL_BLOCK_START = "<!-- CSTL:START -->";
38
+ const CSTL_BLOCK_END = "<!-- CSTL:END -->";
39
+ const LEGACY_TRELLIS_BLOCK_START = "<!-- TRELLIS:START -->";
40
+ const LEGACY_TRELLIS_BLOCK_END = "<!-- TRELLIS:END -->";
30
41
  const LEGACY_UNTRACKED_AGENTS_MD_BLOCK_HASHES = new Set([
31
- // v0.5.0-beta.17 and earlier wrote AGENTS.md but did not hash-track it.
32
- // This hash is the pristine Trellis-managed block before the Subagents
33
- // section was added, so old untouched projects can be updated without a
34
- // false "modified by you" conflict.
35
42
  "c1f511b1cfc1902f2147da159f09cc51f380b0c9e341cdb3ac5dea5233f3e307",
36
43
  ]);
37
44
  // Paths that should never be touched (true user data)
@@ -43,23 +50,37 @@ const PROTECTED_PATHS = [
43
50
  `${DIR_NAMES.WORKFLOW}/.developer`,
44
51
  `${DIR_NAMES.WORKFLOW}/.current-task`,
45
52
  ];
53
+ function getAgentsBlockMarkers(content) {
54
+ if (content.includes(CSTL_BLOCK_START)) {
55
+ return { start: CSTL_BLOCK_START, end: CSTL_BLOCK_END };
56
+ }
57
+ if (content.includes(LEGACY_TRELLIS_BLOCK_START)) {
58
+ return {
59
+ start: LEGACY_TRELLIS_BLOCK_START,
60
+ end: LEGACY_TRELLIS_BLOCK_END,
61
+ };
62
+ }
63
+ return null;
64
+ }
46
65
  function getTrellisManagedBlock(content) {
47
- const start = content.indexOf(TRELLIS_BLOCK_START);
48
- if (start === -1) {
66
+ const markers = getAgentsBlockMarkers(content);
67
+ if (!markers) {
49
68
  return null;
50
69
  }
51
- const end = content.indexOf(TRELLIS_BLOCK_END, start);
70
+ const start = content.indexOf(markers.start);
71
+ const end = content.indexOf(markers.end, start);
52
72
  if (end === -1) {
53
73
  return null;
54
74
  }
55
- return content.slice(start, end + TRELLIS_BLOCK_END.length);
75
+ return content.slice(start, end + markers.end.length);
56
76
  }
57
77
  function replaceTrellisManagedBlock(existingContent, templateContent) {
58
- const existingStart = existingContent.indexOf(TRELLIS_BLOCK_START);
59
- if (existingStart === -1) {
78
+ const existingMarkers = getAgentsBlockMarkers(existingContent);
79
+ if (!existingMarkers) {
60
80
  return null;
61
81
  }
62
- const existingEnd = existingContent.indexOf(TRELLIS_BLOCK_END, existingStart);
82
+ const existingStart = existingContent.indexOf(existingMarkers.start);
83
+ const existingEnd = existingContent.indexOf(existingMarkers.end, existingStart);
63
84
  if (existingEnd === -1) {
64
85
  return null;
65
86
  }
@@ -69,7 +90,28 @@ function replaceTrellisManagedBlock(existingContent, templateContent) {
69
90
  }
70
91
  return (existingContent.slice(0, existingStart) +
71
92
  templateBlock +
72
- existingContent.slice(existingEnd + TRELLIS_BLOCK_END.length));
93
+ existingContent.slice(existingEnd + existingMarkers.end.length));
94
+ }
95
+ function includesCstlRuntimeDirRename(migrations) {
96
+ return migrations.some((item) => item.type === "rename-dir" &&
97
+ item.from === ".trellis" &&
98
+ item.to === ".cstl");
99
+ }
100
+ function upgradeAgentsMdToCstlMarkers(cwd) {
101
+ const agentsPath = path.join(cwd, FILE_NAMES.AGENTS);
102
+ if (!fs.existsSync(agentsPath)) {
103
+ return;
104
+ }
105
+ const content = fs.readFileSync(agentsPath, "utf-8");
106
+ if (!content.includes(LEGACY_TRELLIS_BLOCK_START)) {
107
+ return;
108
+ }
109
+ const upgraded = content
110
+ .replace(LEGACY_TRELLIS_BLOCK_START, CSTL_BLOCK_START)
111
+ .replace(LEGACY_TRELLIS_BLOCK_END, CSTL_BLOCK_END)
112
+ .replace(/\.\/\.trellis\//g, "./.cstl/")
113
+ .replace(/(?<![A-Za-z0-9_])\.trellis\//g, ".cstl/");
114
+ fs.writeFileSync(agentsPath, upgraded, "utf-8");
73
115
  }
74
116
  function buildAgentsMdTemplate(cwd) {
75
117
  const fullPath = path.join(cwd, FILE_NAMES.AGENTS);
@@ -201,27 +243,64 @@ function printSafeFileDeleteSummary(classified) {
201
243
  console.log("");
202
244
  }
203
245
  /**
204
- * Cursor now prefers Agent Skills for manual Trellis entrypoints. Existing
205
- * legacy `.cursor/commands` files are user-visible duplicates, but update must
206
- * not delete them silently; surface guidance and leave cleanup explicit.
246
+ * Commands-only policy residue notice. Cursor's configurator stopped shipping
247
+ * `.cursor/skills/` (commit acd41a92, v0.2.8); projects initialized before
248
+ * that carry stale skill directories that pollute the `/` palette with
249
+ * internal auto-triggered skills and create command+skill double entries for
250
+ * `finish-work`.
251
+ *
252
+ * Safe-file-delete migrations (added in v0.2.10) remove pristine copies
253
+ * automatically; this notice surfaces residue that survives (user-modified
254
+ * files, or dry-run preview) so the user knows what remains and why.
207
255
  */
208
- function printCursorCommandSurfaceNotice(cwd) {
209
- const legacyCommands = [
210
- ".cursor/commands/trellis-continue.md",
211
- ".cursor/commands/trellis-finish-work.md",
212
- ];
213
- const skillEntrypoints = [
214
- ".cursor/skills/trellis-continue/SKILL.md",
215
- ".cursor/skills/trellis-finish-work/SKILL.md",
216
- ];
217
- const hasLegacyCommand = legacyCommands.some((relativePath) => fs.existsSync(path.join(cwd, relativePath)));
218
- const hasSkillEntrypoint = skillEntrypoints.some((relativePath) => fs.existsSync(path.join(cwd, relativePath)));
219
- if (!hasLegacyCommand || !hasSkillEntrypoint)
256
+ const CURSOR_SKILL_RESIDUE_DIRS = [
257
+ // Current cstl-* names (post-0.3.0)
258
+ "cstl-brainstorm",
259
+ "cstl-before-dev",
260
+ "cstl-check",
261
+ "cstl-break-loop",
262
+ "cstl-update-spec",
263
+ "cstl-finish-work",
264
+ "cstl-micro-grill",
265
+ "cstl-meta",
266
+ "cstl-skill-creator",
267
+ "cstl-spec-bootstrap",
268
+ "cstl-cursor2plus-setup",
269
+ "smart-search-cli",
270
+ // Legacy trellis-* names also checked for residue detection (pre-0.3.0 projects)
271
+ "trellis-brainstorm",
272
+ "trellis-before-dev",
273
+ "trellis-check",
274
+ "trellis-break-loop",
275
+ "trellis-update-spec",
276
+ "trellis-finish-work",
277
+ "trellis-micro-grill",
278
+ "trellis-meta",
279
+ "trellis-skill-creator",
280
+ "trellis-spec-bootstrap",
281
+ "trellis-cursor2plus-setup",
282
+ ];
283
+ function printCursorSkillResidueNotice(cwd) {
284
+ const skillsRoot = path.join(cwd, ".cursor", "skills");
285
+ if (!fs.existsSync(skillsRoot))
286
+ return;
287
+ const foundResidues = [];
288
+ for (const dir of CURSOR_SKILL_RESIDUE_DIRS) {
289
+ if (fs.existsSync(path.join(skillsRoot, dir))) {
290
+ foundResidues.push(dir);
291
+ }
292
+ }
293
+ if (foundResidues.length === 0)
220
294
  return;
221
- console.log(chalk.cyan(" Cursor command surface notice:"));
222
- console.log(chalk.yellow(" Agent Skills are the preferred current Cursor entrypoint surface; " +
223
- "legacy .cursor/commands files are compatibility-only and were left untouched."));
224
- console.log(chalk.gray(" To remove duplicate Cursor UI entries, delete the legacy command files explicitly after confirming you do not need them."));
295
+ const hasFinishWorkCmd = fs.existsSync(path.join(cwd, ".cursor", "commands", "cstl-finish-work.md"));
296
+ const hasFinishWorkSkill = foundResidues.includes("cstl-finish-work") ||
297
+ foundResidues.includes("trellis-finish-work");
298
+ console.log(chalk.cyan(" Cursor commands-only skill residue notice:"));
299
+ console.log(chalk.yellow(` Found ${foundResidues.length} stale skill director${foundResidues.length === 1 ? "y" : "ies"} under .cursor/skills/ from before the commands-only policy.`));
300
+ console.log(chalk.gray(` Pristine copies are auto-removed by safe-file-delete; user-modified files are kept (review manually).`));
301
+ if (hasFinishWorkCmd && hasFinishWorkSkill) {
302
+ console.log(chalk.gray(" trellis-finish-work appears as BOTH command and skill — safe-file-delete resolves the duplicate when the skill copy is pristine."));
303
+ }
225
304
  console.log("");
226
305
  }
227
306
  /**
@@ -245,7 +324,7 @@ function executeSafeFileDeletes(classified, cwd) {
245
324
  return deleted;
246
325
  }
247
326
  /**
248
- * Load update.skip paths from .trellis/config.yaml
327
+ * Load update.skip paths from .cstl/config.yaml
249
328
  *
250
329
  * Parses simple YAML structure:
251
330
  * update:
@@ -256,8 +335,8 @@ function executeSafeFileDeletes(classified, cwd) {
256
335
  * @internal Exported for testing only
257
336
  */
258
337
  export function loadUpdateSkipPaths(cwd) {
259
- const configPath = path.join(cwd, DIR_NAMES.WORKFLOW, "config.yaml");
260
- if (!fs.existsSync(configPath))
338
+ const configPath = workflowPath(cwd, "config.yaml");
339
+ if (!configPath || !fs.existsSync(configPath))
261
340
  return [];
262
341
  try {
263
342
  const content = fs.readFileSync(configPath, "utf-8");
@@ -671,7 +750,9 @@ async function promptConflictResolution(file, options, applyToAll) {
671
750
  */
672
751
  function createBackupDirPath(cwd) {
673
752
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
674
- return path.join(cwd, DIR_NAMES.WORKFLOW, `.backup-${timestamp}`);
753
+ const workflowRoot = workflowPath(cwd, `.backup-${timestamp}`) ??
754
+ path.join(cwd, DIR_NAMES.WORKFLOW, `.backup-${timestamp}`);
755
+ return workflowRoot;
675
756
  }
676
757
  /**
677
758
  * Backup a single file to the backup directory
@@ -773,15 +854,16 @@ function createFullBackup(cwd) {
773
854
  * Update version file
774
855
  */
775
856
  function updateVersionFile(cwd) {
776
- const versionPath = path.join(cwd, DIR_NAMES.WORKFLOW, ".version");
857
+ const dirName = resolveWorkflowDirName(cwd) ?? DIR_NAMES.WORKFLOW;
858
+ const versionPath = path.join(cwd, dirName, ".version");
777
859
  fs.writeFileSync(versionPath, VERSION);
778
860
  }
779
861
  /**
780
862
  * Get current installed version
781
863
  */
782
864
  function getInstalledVersion(cwd) {
783
- const versionPath = path.join(cwd, DIR_NAMES.WORKFLOW, ".version");
784
- if (fs.existsSync(versionPath)) {
865
+ const versionPath = workflowPath(cwd, ".version");
866
+ if (versionPath && fs.existsSync(versionPath)) {
785
867
  return fs.readFileSync(versionPath, "utf-8").trim();
786
868
  }
787
869
  return "unknown";
@@ -913,7 +995,7 @@ function classifyMigrations(migrations, cwd, hashes, templates) {
913
995
  continue;
914
996
  }
915
997
  // For non-rename types, also block writing TO protected paths
916
- // rename/rename-dir are allowed to target protected paths (e.g., 0.2.0 renames into .trellis/workspace)
998
+ // rename/rename-dir are allowed to target protected paths (e.g., 0.2.0 renames into .cstl/workspace)
917
999
  if (item.to &&
918
1000
  isProtectedPath(item.to) &&
919
1001
  item.type !== "rename" &&
@@ -1266,7 +1348,7 @@ async function executeMigrations(classified, cwd, options) {
1266
1348
  }
1267
1349
  // For `backup-rename`, leave an inline .backup copy of the user's modified
1268
1350
  // original next to the new location (for rename) or in place (for delete).
1269
- // This is in addition to the full project snapshot at .trellis/.backup-*/;
1351
+ // This is in addition to the full project snapshot at .cstl/.backup-*/;
1270
1352
  // the inline copy is more discoverable when the user wants to diff or merge
1271
1353
  // their customizations against the new template.
1272
1354
  if (item.type === "rename" && item.to) {
@@ -1291,7 +1373,7 @@ async function executeMigrations(classified, cwd, options) {
1291
1373
  const filePath = path.join(cwd, item.from);
1292
1374
  if (action === "backup-rename") {
1293
1375
  // Keep a .backup copy in place before deletion so the user can recover
1294
- // inline without digging through .trellis/.backup-*/.
1376
+ // inline without digging through .cstl/.backup-*/.
1295
1377
  fs.copyFileSync(filePath, filePath + ".backup");
1296
1378
  }
1297
1379
  fs.unlinkSync(filePath);
@@ -1352,7 +1434,7 @@ function releaseBlockersFromReadiness(readiness, cliBehindNpm, cliVersion, lates
1352
1434
  blockers.push({
1353
1435
  code: "cli_behind_npm",
1354
1436
  message: `CLI ${cliVersion} is behind npm ${latestNpmVersion}`,
1355
- recovery: ["trellis upgrade"],
1437
+ recovery: ["cstl upgrade"],
1356
1438
  });
1357
1439
  }
1358
1440
  if (!readiness.skipped && !readiness.smartSearch.ok) {
@@ -1361,7 +1443,7 @@ function releaseBlockersFromReadiness(readiness, cliBehindNpm, cliVersion, lates
1361
1443
  message: "Smart Search readiness did not pass",
1362
1444
  recovery: [
1363
1445
  "smart-search doctor --format json",
1364
- "trellis update --skip-readiness",
1446
+ "cstl update --skip-readiness",
1365
1447
  ],
1366
1448
  });
1367
1449
  }
@@ -1370,7 +1452,7 @@ function releaseBlockersFromReadiness(readiness, cliBehindNpm, cliVersion, lates
1370
1452
  blockers.push({
1371
1453
  code: `capability_${cap.id}`,
1372
1454
  message: `Capability ${cap.id} readiness failed`,
1373
- recovery: ["trellis update --skip-readiness"],
1455
+ recovery: ["cstl update --skip-readiness"],
1374
1456
  });
1375
1457
  }
1376
1458
  }
@@ -1428,10 +1510,10 @@ export async function update(options) {
1428
1510
  });
1429
1511
  finishRollout(options, report);
1430
1512
  };
1431
- // Check if Trellis is initialized
1432
- if (!fs.existsSync(path.join(cwd, DIR_NAMES.WORKFLOW))) {
1513
+ // Check if cursor-trellis is initialized (.cstl/ or legacy .trellis/)
1514
+ if (!isWorkflowInitialized(cwd)) {
1433
1515
  console.log(chalk.red("Error: Trellis not initialized in this directory."));
1434
- console.log(chalk.gray("Run 'trellis init' first."));
1516
+ console.log(chalk.gray("Run 'cstl init' first."));
1435
1517
  emitEarly("blocked_not_initialized");
1436
1518
  return;
1437
1519
  }
@@ -1441,13 +1523,13 @@ export async function update(options) {
1441
1523
  setupProxy();
1442
1524
  checkSmartSearchReadiness({
1443
1525
  skipReadiness: options.skipReadiness,
1444
- skipReadinessCommand: "trellis update --skip-readiness",
1526
+ skipReadinessCommand: "cstl update --skip-readiness",
1445
1527
  });
1446
1528
  checkProjectCapabilityReadiness({
1447
1529
  cwd,
1448
1530
  selected: loadProjectCapabilities(cwd),
1449
1531
  skipReadiness: options.skipReadiness,
1450
- skipReadinessCommand: "trellis update --skip-readiness",
1532
+ skipReadinessCommand: "cstl update --skip-readiness",
1451
1533
  });
1452
1534
  readinessSnapshot = snapshotReadinessForRollout({
1453
1535
  cwd,
@@ -1476,7 +1558,7 @@ export async function update(options) {
1476
1558
  // Check if CLI is outdated compared to npm
1477
1559
  if (cliVsNpm < 0 && latestNpmVersion) {
1478
1560
  console.log(chalk.yellow(`⚠️ Your CLI (${cliVersion}) is behind npm (${latestNpmVersion}).`));
1479
- console.log(chalk.yellow(` Run: trellis upgrade\n`));
1561
+ console.log(chalk.yellow(` Run: cstl upgrade\n`));
1480
1562
  }
1481
1563
  // Check for downgrade situation
1482
1564
  if (cliVsProject < 0) {
@@ -1484,8 +1566,8 @@ export async function update(options) {
1484
1566
  console.log(chalk.red(` This would DOWNGRADE your project!\n`));
1485
1567
  if (!options.allowDowngrade) {
1486
1568
  console.log(chalk.gray("Solutions:"));
1487
- console.log(chalk.gray(` 1. Update your CLI: trellis upgrade`));
1488
- console.log(chalk.gray(` 2. Force downgrade: trellis update --allow-downgrade\n`));
1569
+ console.log(chalk.gray(` 1. Update your CLI: cstl upgrade`));
1570
+ console.log(chalk.gray(` 2. Force downgrade: cstl update --allow-downgrade\n`));
1489
1571
  emitEarly("blocked_downgrade");
1490
1572
  return;
1491
1573
  }
@@ -1498,13 +1580,13 @@ export async function update(options) {
1498
1580
  // Handle unknown version - skip regular migrations but safe-file-delete still runs
1499
1581
  const isUnknownVersion = projectVersion === "unknown";
1500
1582
  if (isUnknownVersion) {
1501
- console.log(chalk.yellow("⚠️ No version file found. Skipping migrations — run trellis init to fix."));
1583
+ console.log(chalk.yellow("⚠️ No version file found. Skipping migrations — run cstl init to fix."));
1502
1584
  console.log(chalk.gray(" Template updates will still be applied."));
1503
1585
  console.log(chalk.gray(" Safe file cleanup will still run (hash-verified).\n"));
1504
1586
  }
1505
1587
  // Self-heal poisoned manifests: prune entries that no current platform
1506
1588
  // configurator owns. This silently removes user-owned paths that early
1507
- // buggy versions of `trellis init` over-hashed (e.g. legacy session dirs).
1589
+ // buggy versions of `cstl init` over-hashed (e.g. legacy session dirs).
1508
1590
  {
1509
1591
  const configuredPlatforms = new Set(getConfiguredPlatforms(cwd));
1510
1592
  const prune = pruneOrphanManifestKeys(cwd, [...configuredPlatforms], hashes);
@@ -1530,7 +1612,7 @@ export async function update(options) {
1530
1612
  })();
1531
1613
  // Collect templates (used for both migration classification and change analysis)
1532
1614
  const templates = collectTemplateFiles(cwd, breakingBypass);
1533
- printCursorCommandSurfaceNotice(cwd);
1615
+ printCursorSkillResidueNotice(cwd);
1534
1616
  // Load update.skip paths (used for both safe-file-delete and template collection)
1535
1617
  const skipPaths = loadUpdateSkipPaths(cwd);
1536
1618
  // Collect safe-file-delete items from ALL manifests (hash match is the safety net)
@@ -1592,7 +1674,7 @@ export async function update(options) {
1592
1674
  console.log(chalk.bgRed.white.bold(" ✖ MIGRATION REQUIRED ") +
1593
1675
  chalk.red(` Breaking changes between ${projectVersion} → ${cliVersion} require --migrate.`));
1594
1676
  console.log("");
1595
- console.log(chalk.yellow(` Run: trellis update --migrate`));
1677
+ console.log(chalk.yellow(` Run: cstl update --migrate`));
1596
1678
  console.log("");
1597
1679
  console.log(chalk.gray(" Without --migrate, renamed/relocated files from breaking releases aren't moved,\n" +
1598
1680
  " leaving your project with stale paths alongside new templates.\n" +
@@ -1770,7 +1852,7 @@ export async function update(options) {
1770
1852
  // pipeline, or any redirected-stdin context). Guide the operator toward an
1771
1853
  // explicit consent flag or a dry-run first.
1772
1854
  if (!process.stdin.isTTY) {
1773
- throw new Error("Non-interactive `trellis update` requires an explicit consent flag. " +
1855
+ throw new Error("Non-interactive `cstl update` requires an explicit consent flag. " +
1774
1856
  "Re-run with --force (apply all), --skip-all (preserve modified), --create-new (.new copies), or --dry-run (preview only).");
1775
1857
  }
1776
1858
  const { proceed } = await inquirer.prompt([
@@ -1795,14 +1877,31 @@ export async function update(options) {
1795
1877
  }
1796
1878
  // Execute migrations if --migrate flag is set
1797
1879
  if (options.migrate && classifiedMigrations) {
1880
+ const pendingRenameItems = [
1881
+ ...classifiedMigrations.auto,
1882
+ ...classifiedMigrations.confirm,
1883
+ ...classifiedMigrations.conflict,
1884
+ ];
1885
+ if (includesCstlRuntimeDirRename(pendingRenameItems)) {
1886
+ const assessment = assessCstlDirectoryMigrate(cwd, {
1887
+ forceCstlMigrate: options.forceCstlMigrate,
1888
+ });
1889
+ if (!assessment.ok) {
1890
+ console.error(chalk.red("Error:"), assessment.reason);
1891
+ process.exit(1);
1892
+ }
1893
+ }
1798
1894
  migrationApplyResult = await executeMigrations(classifiedMigrations, cwd, {
1799
1895
  force: options.force,
1800
1896
  skipAll: options.skipAll,
1801
1897
  });
1802
1898
  printMigrationResult(migrationApplyResult);
1899
+ if (includesCstlRuntimeDirRename(pendingRenameItems)) {
1900
+ upgradeAgentsMdToCstlMarkers(cwd);
1901
+ }
1803
1902
  // Hardcoded: Rename traces-*.md to journal-*.md in workspace directories
1804
1903
  // Why hardcoded: The migration system only supports fixed path renames, not pattern-based.
1805
- // traces-*.md files are in .trellis/workspace/{developer}/ with variable developer names
1904
+ // traces-*.md files are in .cstl/workspace/{developer}/ with variable developer names
1806
1905
  // and variable file numbers (traces-1.md, traces-2.md, etc.), so we can't enumerate them
1807
1906
  // in the migration manifest. This is a one-time migration for the 0.2.0 naming redesign.
1808
1907
  const workspaceDir = path.join(cwd, PATHS.WORKSPACE);
@@ -1969,6 +2068,7 @@ export async function update(options) {
1969
2068
  }
1970
2069
  const actionWord = isDowngrade ? "Downgrade" : "Update";
1971
2070
  console.log(chalk.green(`\n✅ ${actionWord} complete! (${projectVersion} → ${cliVersion})`));
2071
+ logCursor2plusCompatHint(cwd);
1972
2072
  if (createdNew > 0) {
1973
2073
  console.log(chalk.gray("\nTip: Review .new files and merge changes manually if needed."));
1974
2074
  }
@@ -2028,7 +2128,7 @@ export async function update(options) {
2028
2128
  prdContent += `**From Version**: ${projectVersion}\n`;
2029
2129
  prdContent += `**To Version**: ${cliVersion}\n`;
2030
2130
  prdContent += `**Assignee**: ${currentDeveloper}\n\n`;
2031
- prdContent += `## Status\n\n- [ ] Review migration guide\n- [ ] Update custom files\n- [ ] Run \`trellis update --migrate\`\n- [ ] Test workflows\n\n`;
2131
+ prdContent += `## Status\n\n- [ ] Review migration guide\n- [ ] Update custom files\n- [ ] Run \`cstl update --migrate\`\n- [ ] Test workflows\n\n`;
2032
2132
  for (const { version, guide, aiInstructions, } of metadata.migrationGuides) {
2033
2133
  prdContent += `---\n\n## v${version} Migration Guide\n\n`;
2034
2134
  prdContent += guide;