@mindfoldhq/trellis 0.6.2 → 0.6.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 (95) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/index.js +11 -2
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/commands/init.d.ts +5 -0
  5. package/dist/commands/init.d.ts.map +1 -1
  6. package/dist/commands/init.js +49 -2
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/mem.d.ts.map +1 -1
  9. package/dist/commands/mem.js +4 -3
  10. package/dist/commands/mem.js.map +1 -1
  11. package/dist/commands/update.d.ts.map +1 -1
  12. package/dist/commands/update.js +1 -2
  13. package/dist/commands/update.js.map +1 -1
  14. package/dist/configurators/antigravity.d.ts +1 -1
  15. package/dist/configurators/antigravity.js +1 -1
  16. package/dist/configurators/claude.d.ts +5 -2
  17. package/dist/configurators/claude.d.ts.map +1 -1
  18. package/dist/configurators/claude.js +37 -4
  19. package/dist/configurators/claude.js.map +1 -1
  20. package/dist/configurators/codebuddy.d.ts +1 -1
  21. package/dist/configurators/codebuddy.js +1 -1
  22. package/dist/configurators/codex.js +2 -2
  23. package/dist/configurators/codex.js.map +1 -1
  24. package/dist/configurators/copilot.d.ts +1 -1
  25. package/dist/configurators/copilot.js +1 -1
  26. package/dist/configurators/cursor.d.ts +1 -1
  27. package/dist/configurators/cursor.js +1 -1
  28. package/dist/configurators/devin.d.ts +7 -0
  29. package/dist/configurators/devin.d.ts.map +1 -0
  30. package/dist/configurators/{windsurf.js → devin.js} +7 -7
  31. package/dist/configurators/devin.js.map +1 -0
  32. package/dist/configurators/droid.d.ts +1 -1
  33. package/dist/configurators/droid.js +1 -1
  34. package/dist/configurators/gemini.d.ts +1 -1
  35. package/dist/configurators/gemini.js +1 -1
  36. package/dist/configurators/index.d.ts +2 -1
  37. package/dist/configurators/index.d.ts.map +1 -1
  38. package/dist/configurators/index.js +17 -6
  39. package/dist/configurators/index.js.map +1 -1
  40. package/dist/configurators/kilo.d.ts +1 -1
  41. package/dist/configurators/kilo.js +1 -1
  42. package/dist/configurators/shared.d.ts +18 -5
  43. package/dist/configurators/shared.d.ts.map +1 -1
  44. package/dist/configurators/shared.js +8 -8
  45. package/dist/configurators/shared.js.map +1 -1
  46. package/dist/configurators/zcode.d.ts +19 -0
  47. package/dist/configurators/zcode.d.ts.map +1 -0
  48. package/dist/configurators/zcode.js +54 -0
  49. package/dist/configurators/zcode.js.map +1 -0
  50. package/dist/migrations/manifests/0.6.3.json +24 -0
  51. package/dist/templates/claude/hooks/statusline.py +324 -0
  52. package/dist/templates/claude/index.d.ts +10 -1
  53. package/dist/templates/claude/index.d.ts.map +1 -1
  54. package/dist/templates/claude/index.js +12 -1
  55. package/dist/templates/claude/index.js.map +1 -1
  56. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +4 -4
  57. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +2 -0
  58. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +2 -1
  59. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +2 -2
  60. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/bundled-skills.md +3 -3
  61. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +2 -2
  62. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +1 -1
  63. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +3 -1
  64. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +2 -0
  65. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +2 -2
  66. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +4 -2
  67. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +3 -1
  68. package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +2 -2
  69. package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +23 -24
  70. package/dist/templates/common/skills/brainstorm.md +43 -0
  71. package/dist/templates/common/skills/break-loop.md +59 -0
  72. package/dist/templates/shared-hooks/index.d.ts +4 -2
  73. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  74. package/dist/templates/shared-hooks/index.js +4 -2
  75. package/dist/templates/shared-hooks/index.js.map +1 -1
  76. package/dist/templates/trellis/scripts/add_session.py +26 -6
  77. package/dist/templates/trellis/scripts/common/cli_adapter.py +46 -32
  78. package/dist/templates/trellis/scripts/common/safe_commit.py +46 -16
  79. package/dist/templates/trellis/scripts/common/task_store.py +2 -2
  80. package/dist/templates/trellis/scripts/common/workflow_phase.py +1 -1
  81. package/dist/templates/trellis/workflow.md +10 -10
  82. package/dist/templates/zcode/agents/trellis-check.md +102 -0
  83. package/dist/templates/zcode/agents/trellis-implement.md +102 -0
  84. package/dist/templates/zcode/index.d.ts +15 -0
  85. package/dist/templates/zcode/index.d.ts.map +1 -0
  86. package/dist/templates/zcode/index.js +18 -0
  87. package/dist/templates/zcode/index.js.map +1 -0
  88. package/dist/types/ai-tools.d.ts +4 -4
  89. package/dist/types/ai-tools.d.ts.map +1 -1
  90. package/dist/types/ai-tools.js +25 -7
  91. package/dist/types/ai-tools.js.map +1 -1
  92. package/package.json +2 -2
  93. package/dist/configurators/windsurf.d.ts +0 -7
  94. package/dist/configurators/windsurf.d.ts.map +0 -1
  95. package/dist/configurators/windsurf.js.map +0 -1
@@ -4,32 +4,31 @@ Full flag reference for the five subcommands. Pin this as the authoritative sour
4
4
 
5
5
  ## Subcommands
6
6
 
7
- | Command | Purpose |
8
- |---|---|
9
- | `list` | List sessions. Default subcommand when none is given. |
10
- | `search <keyword>` | Find sessions whose contents match a keyword. |
11
- | `context <session-id>` | Drill into one session: top-N hit turns + surrounding context. Pair with `--grep` for keyword anchoring. |
12
- | `extract <session-id>` | Dump cleaned dialogue. Combine with `--phase` / `--grep` to slice. |
13
- | `projects` | List active project `cwd` values with session counts. Use this to discover which `--cwd` to pass to other subcommands. |
7
+ | Command | Purpose |
8
+ | ---------------------- | ---------------------------------------------------------------------------------------------------------------------- |
9
+ | `list` | List sessions. Default subcommand when none is given. |
10
+ | `search <keyword>` | Find sessions whose contents match a keyword. |
11
+ | `context <session-id>` | Drill into one session: top-N hit turns + surrounding context. Pair with `--grep` for keyword anchoring. |
12
+ | `extract <session-id>` | Dump cleaned dialogue. Combine with `--phase` / `--grep` to slice. |
13
+ | `projects` | List active project `cwd` values with session counts. Use this to discover which `--cwd` to pass to other subcommands. |
14
14
 
15
15
  ## Flags (apply where meaningful)
16
16
 
17
- | Flag | Subcommands | Meaning |
18
- |---|---|---|
19
- | `--platform claude\|codex\|opencode\|all` | all | Default `all`. OpenCode adapter is currently a stub on `0.6.0-beta.*` — see "Caveats" below. |
20
- | `--since YYYY-MM-DD` | list / search | Inclusive lower date bound. |
21
- | `--until YYYY-MM-DD` | list / search | Inclusive upper date bound. |
22
- | `--global` | list / search | Include sessions from every project on this machine. Default is the current project `cwd`. |
23
- | `--cwd <path>` | list / search | Force a specific project cwd instead of inferring from where you are. |
24
- | `--limit N` | list / search | Cap output rows. Default `50`. |
25
- | `--grep KW` | extract / context | Filter turns by keyword. Multi-token AND when whitespace-separated. |
26
- | `--phase brainstorm\|implement\|all` | extract | Slice session by Trellis task boundaries. `brainstorm` = `[task.py create, task.py start)`. `implement` = `[task.py start, task.py finish)` window. Default `all`. |
27
- | `--turns N` | context | Number of hit turns to return. Default `3`. |
28
- | `--around N` | context | Surrounding turns to include per hit. Default `1`. |
29
- | `--max-chars N` | context | Total character budget. Default `6000` (~1500 tokens). |
30
- | `--include-children` | search / context | Merge OpenCode sub-agent sessions into their parent session. |
31
- | `--json` | all | Emit machine-parseable JSON instead of human-readable output. |
32
- | `--task <task-dir>` | list | Narrow to sessions whose context-key resolved to a given task directory (uses `.trellis/.runtime/sessions/*.json`). |
17
+ | Flag | Subcommands | Meaning |
18
+ | --------------------------------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
19
+ | `--platform claude\|codex\|opencode\|pi\|all` | all | Default `all`. OpenCode adapter is currently a stub on `0.6.0-beta.*` — see "Caveats" below. |
20
+ | `--since YYYY-MM-DD` | list / search | Inclusive lower date bound. |
21
+ | `--until YYYY-MM-DD` | list / search | Inclusive upper date bound. |
22
+ | `--global` | list / search | Include sessions from every project on this machine. Default is the current project `cwd`. |
23
+ | `--cwd <path>` | list / search | Force a specific project cwd instead of inferring from where you are. |
24
+ | `--limit N` | list / search | Cap output rows. Default `50`. |
25
+ | `--grep KW` | extract / context | Filter turns by keyword. Multi-token AND when whitespace-separated. |
26
+ | `--phase brainstorm\|implement\|all` | extract | Slice session by Trellis task boundaries. `brainstorm` = `[task.py create, task.py start)`. `implement` = turns outside brainstorm windows. Default `all`. |
27
+ | `--turns N` | context | Number of hit turns to return. Default `3`. |
28
+ | `--around N` | context | Surrounding turns to include per hit. Default `1`. |
29
+ | `--max-chars N` | context | Total character budget. Default `6000` (~1500 tokens). |
30
+ | `--include-children` | search / context | Merge OpenCode sub-agent sessions into their parent session. |
31
+ | `--json` | all | Emit machine-parseable JSON instead of human-readable output. |
33
32
 
34
33
  ## Common one-liners
35
34
 
@@ -58,7 +57,7 @@ trellis mem projects
58
57
 
59
58
  - **OpenCode adapter is a stub on `0.6.0-beta.*`.** When `--platform` resolves to OpenCode (or `all` and OpenCode would be included), `mem` prints a one-line "reader unavailable" notice and continues with the other platforms. Don't promise OpenCode coverage in your reply until the adapter ships.
60
59
  - **`--phase` slicing depends on `task.py create` / `task.py start` invocations appearing in the recorded bash calls of the session.** Sessions where the user ran `task.py` from a different terminal — outside the recorded AI loop — will not have phase boundaries. `--phase all` is the safe fallback.
61
- - **`mem` indexes platform JSONL files directly.** If the user has cleared their Claude / Codex session storage, `mem` cannot recover what is no longer on disk.
60
+ - **`mem` indexes platform JSONL files directly.** If the user has cleared their Claude / Codex / Pi session storage, `mem` cannot recover what is no longer on disk.
62
61
  - **`mem` is read-only.** No remote sync, no edits to platform JSONL. Any write you do based on `mem` findings is your own follow-up call into the editing tools available to you.
63
62
 
64
63
  ## When you need more than this reference
@@ -64,6 +64,49 @@ Each question must include:
64
64
 
65
65
  Do not ask process questions such as whether to search, inspect files, or continue brainstorming. Do the evidence work directly. Ask the user only when the remaining issue is a product decision, preference, scope boundary, or risk tolerance choice.
66
66
 
67
+ ## Thinking Framework: First Principles Analysis
68
+
69
+ When requirements are vague, solutions feel over-engineered, or you're about to add complexity "because everyone does" — decompose to fundamental truths before reasoning upward.
70
+
71
+ ### Step 1: Restate the Problem
72
+
73
+ Strip away implementation details to one sentence.
74
+
75
+ > Bad: "We need to add Redis caching to the user profile endpoint"
76
+ > Good: "User profile data takes too long to load"
77
+
78
+ ### Step 2: List Fundamental Truths
79
+
80
+ What is absolutely true (not opinion or convention)?
81
+
82
+ | Category | Examples |
83
+ |----------|----------|
84
+ | **Physical constraints** | Network latency ≥ 0, disk I/O has limits |
85
+ | **Business rules** | "Users must see their own data" |
86
+ | **Technical invariants** | "Data must be consistent" |
87
+ | **User needs** | "The user wants X within Y seconds" |
88
+
89
+ ### Step 3: Challenge Assumptions
90
+
91
+ For each component of the current plan:
92
+
93
+ - **Fact or convention?** "We always use REST" — why?
94
+ - **What if we removed this?** If nothing breaks, it's unnecessary.
95
+ - **Solving the actual problem or a symptom?** Trace the causal chain.
96
+ - **Who benefits from this complexity?** If "nobody", simplify.
97
+
98
+ ### Step 4: Build Up from Truths
99
+
100
+ 1. Start with the minimum viable mechanism satisfying all truths
101
+ 2. Add complexity only when a specific truth demands it
102
+ 3. Each addition must answer: "Which truth requires this?"
103
+
104
+ ### Step 5: Validate
105
+
106
+ - Does the solution solve the original problem?
107
+ - What assumptions need verification?
108
+ - What's the simplest experiment to test this?
109
+
67
110
  ## Artifact Rules
68
111
 
69
112
  `prd.md` records requirements and acceptance:
@@ -106,6 +106,65 @@ Three levels of insight:
106
106
 
107
107
  30 minutes of analysis saves 30 hours of future debugging.
108
108
 
109
+
110
+ ## Thinking Framework: Bayesian Reasoning
111
+
112
+ When multiple root causes are plausible and evidence is incomplete, update your beliefs proportionally to new evidence rather than clinging to initial assumptions.
113
+
114
+ ### Step 1: Establish Priors
115
+
116
+ Before investigating, state what you believe and why:
117
+
118
+ | Hypothesis | Prior | Reasoning |
119
+ |------------|-------|-----------|
120
+ | H1: [cause A] | 40% | Most common for this pattern |
121
+ | H2: [cause B] | 30% | Plausible given environment |
122
+ | H3: [other] | 30% | Catch-all |
123
+
124
+ Priors must sum to 100%. If you can't assign probabilities, investigate first.
125
+
126
+ ### Step 2: Observe Evidence
127
+
128
+ Document what you found — be specific about reliability:
129
+
130
+ - What exactly did you observe?
131
+ - How reliable? (test output > log message > user report > hunch)
132
+ - Could multiple hypotheses explain this?
133
+
134
+ ### Step 3: Update Beliefs
135
+
136
+ For each hypothesis, ask: **How likely is this evidence if this hypothesis were true?**
137
+
138
+ Direction of update matters more than calculation:
139
+ - Evidence strongly predicted by H1 → H1 probability increases
140
+ - Evidence contradicts H2 → H2 probability decreases
141
+ - Evidence equally likely under all → no update
142
+
143
+ ### Step 4: Seek Discriminating Evidence
144
+
145
+ Don't gather more of the same. Find evidence that **differs strongly** between top hypotheses.
146
+
147
+ > If H1 and H3 are close: "What would I see if H1 is true but not if H3 is true?" Then check for that.
148
+
149
+ ### Step 5: State Confidence
150
+
151
+ | Confidence | Action |
152
+ |------------|--------|
153
+ | 90%+ | Proceed with fix, monitor |
154
+ | 70-90% | Proceed, add fallback check |
155
+ | 50-70% | Test hypothesis before committing |
156
+ | <50% | Need more evidence, don't guess |
157
+
158
+ Never express binary certainty when evidence is incomplete. Use "most likely", "plausible but unlikely", "worth investigating".
159
+
160
+ ### Common Fallacies
161
+
162
+ | Fallacy | Example | Correction |
163
+ |---------|---------|------------|
164
+ | **Base rate neglect** | "Test failed → code is broken" | How often do tests fail for other reasons? |
165
+ | **Confirmation bias** | "Must be a race condition, let me find race evidence" | Actively seek evidence AGAINST your top hypothesis |
166
+ | **Anchoring** | "Last time it was caching, probably caching again" | Establish priors from current context, not yesterday's bug |
167
+
109
168
  ---
110
169
 
111
170
  ## After Analysis: Immediate Actions
@@ -32,8 +32,10 @@ export type SharedHookPlatform = "claude" | "cursor" | "codex" | "gemini" | "qod
32
32
  * - Kiro supports only `agentSpawn` (no SessionStart / UserPromptSubmit
33
33
  * event), so it takes just `inject-subagent-context.py`.
34
34
  * - Claude Code `statusLine` is intentionally not installed by default.
35
- * Users can add their own statusLine command in `.claude/settings.json`
36
- * without Trellis owning a generated hook file.
35
+ * Users can add their own statusLine command in `.claude/settings.json`,
36
+ * or opt in to the Trellis one via `trellis init --with-statusline`
37
+ * (installed from `templates/claude/hooks/`, not from this table — no
38
+ * other platform has a statusLine event).
37
39
  */
38
40
  export declare const SHARED_HOOKS_BY_PLATFORM: Record<SharedHookPlatform, readonly SharedHookName[]>;
39
41
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/shared-hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GACtB,kBAAkB,GAClB,iCAAiC,GACjC,0BAA0B,GAC1B,4BAA4B,CAAC;AAEjC,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,OAAO,GACP,SAAS,GACT,WAAW,GACX,OAAO,GACP,MAAM,CAAC;AAEX;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAC3C,kBAAkB,EAClB,SAAS,cAAc,EAAE,CA2B1B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,UAAU,EAAE,CAWnD;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,kBAAkB,GAC3B,UAAU,EAAE,CAGd"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/shared-hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GACtB,kBAAkB,GAClB,iCAAiC,GACjC,0BAA0B,GAC1B,4BAA4B,CAAC;AAEjC,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,OAAO,GACP,SAAS,GACT,WAAW,GACX,OAAO,GACP,MAAM,CAAC;AAEX;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAC3C,kBAAkB,EAClB,SAAS,cAAc,EAAE,CA2B1B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,UAAU,EAAE,CAWnD;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,kBAAkB,GAC3B,UAAU,EAAE,CAGd"}
@@ -32,8 +32,10 @@ function readTemplate(relativePath) {
32
32
  * - Kiro supports only `agentSpawn` (no SessionStart / UserPromptSubmit
33
33
  * event), so it takes just `inject-subagent-context.py`.
34
34
  * - Claude Code `statusLine` is intentionally not installed by default.
35
- * Users can add their own statusLine command in `.claude/settings.json`
36
- * without Trellis owning a generated hook file.
35
+ * Users can add their own statusLine command in `.claude/settings.json`,
36
+ * or opt in to the Trellis one via `trellis init --with-statusline`
37
+ * (installed from `templates/claude/hooks/`, not from this table — no
38
+ * other platform has a statusLine event).
37
39
  */
38
40
  export const SHARED_HOOKS_BY_PLATFORM = {
39
41
  claude: [
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/shared-hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,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;AA0BD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAGjC;IACF,MAAM,EAAE;QACN,kBAAkB;QAClB,0BAA0B;QAC1B,4BAA4B;KAC7B;IACD,MAAM,EAAE;QACN,kBAAkB;QAClB,iCAAiC;QACjC,4BAA4B;KAC7B;IACD,KAAK,EAAE,CAAC,0BAA0B,CAAC;IACnC,MAAM,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;IACxD,KAAK,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;IACvD,OAAO,EAAE,CAAC,0BAA0B,CAAC;IACrC,SAAS,EAAE;QACT,kBAAkB;QAClB,0BAA0B;QAC1B,4BAA4B;KAC7B;IACD,KAAK,EAAE;QACL,kBAAkB;QAClB,0BAA0B;QAC1B,4BAA4B;KAC7B;IACD,IAAI,EAAE,CAAC,4BAA4B,CAAC;CACrC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC;SACjC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SAChC,IAAI,EAAE,CAAC;IAEV,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,+BAA+B,CAC7C,QAA4B;IAE5B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,wBAAwB,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpE,OAAO,oBAAoB,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/shared-hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,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;AA0BD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAGjC;IACF,MAAM,EAAE;QACN,kBAAkB;QAClB,0BAA0B;QAC1B,4BAA4B;KAC7B;IACD,MAAM,EAAE;QACN,kBAAkB;QAClB,iCAAiC;QACjC,4BAA4B;KAC7B;IACD,KAAK,EAAE,CAAC,0BAA0B,CAAC;IACnC,MAAM,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;IACxD,KAAK,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;IACvD,OAAO,EAAE,CAAC,0BAA0B,CAAC;IACrC,SAAS,EAAE;QACT,kBAAkB;QAClB,0BAA0B;QAC1B,4BAA4B;KAC7B;IACD,KAAK,EAAE;QACL,kBAAkB;QAClB,0BAA0B;QAC1B,4BAA4B;KAC7B;IACD,IAAI,EAAE,CAAC,4BAA4B,CAAC;CACrC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC;SACjC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SAChC,IAAI,EAAE,CAAC;IAEV,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,+BAA+B,CAC7C,QAA4B;IAE5B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,wBAAwB,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpE,OAAO,oBAAoB,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACnE,CAAC"}
@@ -28,6 +28,8 @@ from datetime import datetime
28
28
  from pathlib import Path
29
29
 
30
30
  from common.paths import (
31
+ DIR_TASKS,
32
+ DIR_WORKFLOW,
31
33
  FILE_JOURNAL_PREFIX,
32
34
  get_repo_root,
33
35
  get_current_task,
@@ -319,12 +321,14 @@ def update_index(
319
321
  # =============================================================================
320
322
 
321
323
  def _auto_commit_workspace(repo_root: Path) -> None:
322
- """Stage Trellis-owned workspace + task paths and commit.
324
+ """Stage Trellis-owned workspace + current-task paths and commit.
323
325
 
324
- Path scope is restricted to specific products (journal files, index.md,
325
- active task dirs, the archive subtree). We never `git add` the whole
326
- `.trellis/` tree, and if `.gitignore` blocks the specific paths we
327
- warn + skip never retry with ``-f``.
326
+ Path scope is restricted to specific products: the current developer's
327
+ journal files + index.md, and ONLY the current task directory (resolved
328
+ via ``get_current_task``). We never `git add` the whole `.trellis/` tree
329
+ or iterate over all active task dirs (#303: parallel-window dirty task
330
+ dirs must not be bundled into the session auto-commit). If `.gitignore`
331
+ blocks the specific paths we warn + skip — never retry with ``-f``.
328
332
 
329
333
  Honors ``session_auto_commit`` in ``.trellis/config.yaml``: when set to
330
334
  ``false``, this function returns immediately without touching git
@@ -338,7 +342,23 @@ def _auto_commit_workspace(repo_root: Path) -> None:
338
342
  return
339
343
 
340
344
  commit_msg = get_session_commit_message(repo_root)
341
- paths = safe_trellis_paths_to_add(repo_root)
345
+ # Resolve the current task so staging is scoped to its dir only. The ref
346
+ # is ``.trellis/tasks/<name>`` (or under archive/) — pass the bare name.
347
+ current = get_current_task(repo_root)
348
+ if current:
349
+ task_name = Path(current).name
350
+ paths = safe_trellis_paths_to_add(repo_root, task_name=task_name)
351
+ else:
352
+ # Current task unknown (0 or >=2 parallel sessions — exactly the
353
+ # parallel-window case #303 is about). Do NOT fall back to the wide
354
+ # `tasks_dir.iterdir()` scan; that would re-leak other tasks' dirty
355
+ # dirs into the session commit. Stage only the developer's journal/
356
+ # index and skip every task dir.
357
+ paths = [
358
+ p
359
+ for p in safe_trellis_paths_to_add(repo_root, task_name=None)
360
+ if not p.startswith(f"{DIR_WORKFLOW}/{DIR_TASKS}/")
361
+ ]
342
362
  if not paths:
343
363
  print("[OK] No workspace changes to commit.", file=sys.stderr)
344
364
  return
@@ -1,7 +1,7 @@
1
1
  """
2
2
  CLI Adapter for Multi-Platform Support.
3
3
 
4
- Abstracts differences between Claude Code, OpenCode, Cursor, iFlow, Codex, Kilo, Kiro Code, Gemini CLI, Antigravity, Windsurf, Qoder, CodeBuddy, GitHub Copilot, Factory Droid, and Pi Agent interfaces.
4
+ Abstracts differences between Claude Code, OpenCode, Cursor, iFlow, Codex, Kilo, Kiro Code, Gemini CLI, Antigravity, Devin, Qoder, CodeBuddy, GitHub Copilot, Factory Droid, and Pi Agent interfaces.
5
5
 
6
6
  Supported platforms:
7
7
  - claude: Claude Code (default)
@@ -13,7 +13,7 @@ Supported platforms:
13
13
  - kiro: Kiro Code (skills-based)
14
14
  - gemini: Gemini CLI
15
15
  - antigravity: Antigravity (workflow-based)
16
- - windsurf: Windsurf (workflow-based)
16
+ - devin: Devin (formerly Windsurf; workflow-based)
17
17
  - qoder: Qoder
18
18
  - codebuddy: CodeBuddy
19
19
  - copilot: GitHub Copilot (VS Code)
@@ -47,7 +47,7 @@ Platform = Literal[
47
47
  "kiro",
48
48
  "gemini",
49
49
  "antigravity",
50
- "windsurf",
50
+ "devin",
51
51
  "qoder",
52
52
  "codebuddy",
53
53
  "copilot",
@@ -97,7 +97,7 @@ class CLIAdapter:
97
97
  """Get platform-specific config directory name.
98
98
 
99
99
  Returns:
100
- Directory name ('.claude', '.opencode', '.cursor', '.iflow', '.codex', '.kilocode', '.kiro', '.gemini', '.agent', '.windsurf', '.qoder', '.codebuddy', '.github/copilot', '.factory', or '.pi')
100
+ Directory name ('.claude', '.opencode', '.cursor', '.iflow', '.codex', '.kilocode', '.kiro', '.gemini', '.agent', '.devin', '.qoder', '.codebuddy', '.github/copilot', '.factory', or '.pi')
101
101
  """
102
102
  if self.platform == "opencode":
103
103
  return ".opencode"
@@ -115,8 +115,8 @@ class CLIAdapter:
115
115
  return ".gemini"
116
116
  elif self.platform == "antigravity":
117
117
  return ".agent"
118
- elif self.platform == "windsurf":
119
- return ".windsurf"
118
+ elif self.platform == "devin":
119
+ return ".devin"
120
120
  elif self.platform == "qoder":
121
121
  return ".qoder"
122
122
  elif self.platform == "codebuddy":
@@ -137,7 +137,7 @@ class CLIAdapter:
137
137
  project_root: Project root directory
138
138
 
139
139
  Returns:
140
- Path to config directory (.claude, .opencode, .cursor, .iflow, .codex, .kilocode, .kiro, .gemini, .agent, .windsurf, .qoder, .codebuddy, .github/copilot, .factory, or .pi)
140
+ Path to config directory (.claude, .opencode, .cursor, .iflow, .codex, .kilocode, .kiro, .gemini, .agent, .devin, .qoder, .codebuddy, .github/copilot, .factory, or .pi)
141
141
  """
142
142
  return project_root / self.config_dir_name
143
143
 
@@ -169,7 +169,7 @@ class CLIAdapter:
169
169
  Note:
170
170
  Cursor uses prefix naming: .cursor/commands/trellis-<name>.md
171
171
  Antigravity uses workflow directory: .agent/workflows/<name>.md
172
- Windsurf uses workflow directory: .windsurf/workflows/trellis-<name>.md
172
+ Devin uses workflow directory: .devin/workflows/trellis-<name>.md
173
173
  Copilot uses prompt files: .github/prompts/<name>.prompt.md
174
174
  Pi uses prompt templates: .pi/prompts/trellis-<name>.md
175
175
  Claude/OpenCode use subdirectory: .claude/commands/trellis/<name>.md
@@ -185,7 +185,7 @@ class CLIAdapter:
185
185
  return prompts_dir / f"trellis-{filename}.md"
186
186
  return prompts_dir / Path(*parts)
187
187
 
188
- if self.platform == "windsurf":
188
+ if self.platform == "devin":
189
189
  workflow_dir = self.get_config_dir(project_root) / "workflows"
190
190
  if not parts:
191
191
  return workflow_dir
@@ -242,7 +242,7 @@ class CLIAdapter:
242
242
  Kiro: .kiro/skills/trellis-<name>/SKILL.md
243
243
  Gemini: .gemini/commands/trellis/<name>.toml
244
244
  Antigravity: .agent/workflows/<name>.md
245
- Windsurf: .windsurf/workflows/trellis-<name>.md
245
+ Devin: .devin/workflows/trellis-<name>.md
246
246
  Pi: .pi/prompts/trellis-<name>.md
247
247
  Others: .{platform}/commands/trellis/<name>.md
248
248
  """
@@ -258,8 +258,8 @@ class CLIAdapter:
258
258
  return f".gemini/commands/trellis/{name}.toml"
259
259
  elif self.platform == "antigravity":
260
260
  return f".agent/workflows/{name}.md"
261
- elif self.platform == "windsurf":
262
- return f".windsurf/workflows/trellis-{name}.md"
261
+ elif self.platform == "devin":
262
+ return f".devin/workflows/trellis-{name}.md"
263
263
  elif self.platform == "kilo":
264
264
  return f".kilocode/workflows/{name}.md"
265
265
  elif self.platform == "copilot":
@@ -293,7 +293,7 @@ class CLIAdapter:
293
293
  return {} # Gemini CLI doesn't have a non-interactive env var
294
294
  elif self.platform == "antigravity":
295
295
  return {}
296
- elif self.platform == "windsurf":
296
+ elif self.platform == "devin":
297
297
  return {}
298
298
  elif self.platform == "qoder":
299
299
  return {}
@@ -370,9 +370,9 @@ class CLIAdapter:
370
370
  raise ValueError(
371
371
  "Antigravity workflows are UI slash commands; CLI agent run is not supported."
372
372
  )
373
- elif self.platform == "windsurf":
373
+ elif self.platform == "devin":
374
374
  raise ValueError(
375
- "Windsurf workflows are UI slash commands; CLI agent run is not supported."
375
+ "Devin workflows are UI slash commands; CLI agent run is not supported."
376
376
  )
377
377
  elif self.platform == "qoder":
378
378
  cmd = ["qodercli", "-p", prompt]
@@ -436,9 +436,9 @@ class CLIAdapter:
436
436
  raise ValueError(
437
437
  "Antigravity workflows are UI slash commands; CLI resume is not supported."
438
438
  )
439
- elif self.platform == "windsurf":
439
+ elif self.platform == "devin":
440
440
  raise ValueError(
441
- "Windsurf workflows are UI slash commands; CLI resume is not supported."
441
+ "Devin workflows are UI slash commands; CLI resume is not supported."
442
442
  )
443
443
  elif self.platform == "qoder":
444
444
  return ["qodercli", "--resume", session_id]
@@ -518,8 +518,8 @@ class CLIAdapter:
518
518
  return "gemini"
519
519
  elif self.platform == "antigravity":
520
520
  return "agy"
521
- elif self.platform == "windsurf":
522
- return "windsurf"
521
+ elif self.platform == "devin":
522
+ return "devin"
523
523
  elif self.platform == "qoder":
524
524
  return "qodercli"
525
525
  elif self.platform == "codebuddy":
@@ -594,14 +594,21 @@ def get_cli_adapter(platform: str = "claude") -> CLIAdapter:
594
594
  """Get CLI adapter for the specified platform.
595
595
 
596
596
  Args:
597
- platform: Platform name ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'windsurf', 'qoder', 'codebuddy', 'copilot', 'droid', or 'pi')
597
+ platform: Platform name ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'devin', 'qoder', 'codebuddy', 'copilot', 'droid', or 'pi')
598
598
 
599
599
  Returns:
600
600
  CLIAdapter instance
601
601
 
602
602
  Raises:
603
603
  ValueError: If platform is not supported
604
+
605
+ Note:
606
+ 'windsurf' is accepted as a deprecated alias for 'devin' (Windsurf was
607
+ renamed to Devin) and normalized before validation.
604
608
  """
609
+ # Deprecated alias: Windsurf was renamed to Devin.
610
+ if platform == "windsurf":
611
+ platform = "devin"
605
612
  if platform not in (
606
613
  "claude",
607
614
  "opencode",
@@ -612,7 +619,7 @@ def get_cli_adapter(platform: str = "claude") -> CLIAdapter:
612
619
  "kiro",
613
620
  "gemini",
614
621
  "antigravity",
615
- "windsurf",
622
+ "devin",
616
623
  "qoder",
617
624
  "codebuddy",
618
625
  "copilot",
@@ -620,7 +627,7 @@ def get_cli_adapter(platform: str = "claude") -> CLIAdapter:
620
627
  "pi",
621
628
  ):
622
629
  raise ValueError(
623
- f"Unsupported platform: {platform} (must be 'claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'windsurf', 'qoder', 'codebuddy', 'copilot', 'droid', or 'pi')"
630
+ f"Unsupported platform: {platform} (must be 'claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'devin', 'qoder', 'codebuddy', 'copilot', 'droid', or 'pi')"
624
631
  )
625
632
 
626
633
  return CLIAdapter(platform=platform) # type: ignore
@@ -636,7 +643,8 @@ _ALL_PLATFORM_CONFIG_DIRS = (
636
643
  ".kiro",
637
644
  ".gemini",
638
645
  ".agent",
639
- ".windsurf",
646
+ ".devin",
647
+ ".windsurf", # deprecated: pre-rename Devin config dir (still a platform signal)
640
648
  ".qoder",
641
649
  ".codebuddy",
642
650
  ".github/copilot",
@@ -647,7 +655,7 @@ _ALL_PLATFORM_CONFIG_DIRS = (
647
655
  checks. `.agents/skills/` is NOT listed here: it is a shared cross-platform
648
656
  layer (written by Codex, also consumed by Amp/Cline/Warp/etc. via the
649
657
  agentskills.io standard), not a single-platform signal. Its presence must not
650
- block detection of Kiro, Antigravity, Windsurf, or other platforms."""
658
+ block detection of Kiro, Antigravity, Devin, or other platforms."""
651
659
 
652
660
 
653
661
  def _has_other_platform_dir(project_root: Path, exclude: set[str]) -> bool:
@@ -672,7 +680,7 @@ def detect_platform(project_root: Path) -> Platform:
672
680
  7. .kiro/skills exists and no other platform dirs → kiro
673
681
  8. .gemini directory exists → gemini
674
682
  9. .agent/workflows exists and no other platform dirs → antigravity
675
- 10. .windsurf/workflows exists and no other platform dirs → windsurf
683
+ 10. .devin/workflows (or legacy .windsurf/workflows) exists and no other platform dirs → devin
676
684
  11. .codebuddy directory exists → codebuddy
677
685
  12. .qoder directory exists → qoder
678
686
  13. .pi directory exists → pi
@@ -682,12 +690,15 @@ def detect_platform(project_root: Path) -> Platform:
682
690
  project_root: Project root directory
683
691
 
684
692
  Returns:
685
- Detected platform ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'windsurf', 'qoder', 'codebuddy', 'copilot', 'droid', 'pi', or default 'claude')
693
+ Detected platform ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'devin', 'qoder', 'codebuddy', 'copilot', 'droid', 'pi', or default 'claude')
686
694
  """
687
695
  import os
688
696
 
689
697
  # Check environment variable first
690
698
  env_platform = os.environ.get("TRELLIS_PLATFORM", "").lower()
699
+ # Deprecated alias: Windsurf was renamed to Devin.
700
+ if env_platform == "windsurf":
701
+ env_platform = "devin"
691
702
  if env_platform in (
692
703
  "claude",
693
704
  "opencode",
@@ -698,7 +709,7 @@ def detect_platform(project_root: Path) -> Platform:
698
709
  "kiro",
699
710
  "gemini",
700
711
  "antigravity",
701
- "windsurf",
712
+ "devin",
702
713
  "qoder",
703
714
  "codebuddy",
704
715
  "copilot",
@@ -749,13 +760,16 @@ def detect_platform(project_root: Path) -> Platform:
749
760
  ):
750
761
  return "antigravity"
751
762
 
752
- # Check for Windsurf workflow directory only when no other platform config exists
763
+ # Check for Devin workflow directory only when no other platform config
764
+ # exists. `.windsurf/workflows` is the legacy pre-rename path (still detected
765
+ # as devin for back-compat until users migrate via `trellis update --migrate`).
753
766
  if (
754
- project_root / ".windsurf" / "workflows"
755
- ).is_dir() and not _has_other_platform_dir(
756
- project_root, {".windsurf"}
767
+ (project_root / ".devin" / "workflows").is_dir()
768
+ or (project_root / ".windsurf" / "workflows").is_dir()
769
+ ) and not _has_other_platform_dir(
770
+ project_root, {".devin", ".windsurf"}
757
771
  ):
758
- return "windsurf"
772
+ return "devin"
759
773
 
760
774
  # Check for .codebuddy directory (CodeBuddy-specific)
761
775
  if (project_root / ".codebuddy").is_dir():
@@ -58,7 +58,10 @@ TRELLIS_IGNORED_SUBPATHS = (
58
58
  )
59
59
 
60
60
 
61
- def safe_trellis_paths_to_add(repo_root: Path) -> list[str]:
61
+ def safe_trellis_paths_to_add(
62
+ repo_root: Path,
63
+ task_name: str | None = None,
64
+ ) -> list[str]:
62
65
  """Return the list of repo-relative paths the auto-commit should stage.
63
66
 
64
67
  Only includes paths that exist on disk so callers don't pass non-existent
@@ -68,12 +71,23 @@ def safe_trellis_paths_to_add(repo_root: Path) -> list[str]:
68
71
  Included:
69
72
  - .trellis/workspace/<developer>/journal-*.md
70
73
  - .trellis/workspace/<developer>/index.md
71
- - .trellis/tasks/<task-dir>/ (every active task directory)
72
- - .trellis/tasks/archive/ (whole archive subtree, if present)
74
+ - .trellis/tasks/<task_name>/ (ONLY the current task dir when
75
+ ``task_name`` is passed; plus its archive location if the task
76
+ already lives under archive/)
73
77
 
74
78
  Excluded (intentionally — these must not be staged):
75
79
  - .trellis/.backup-*, .trellis/worktrees/,
76
80
  .trellis/.template-hashes.json, .trellis/.runtime/, .trellis/.cache/
81
+
82
+ Scope contract (see #303 / break-loop analysis): when ``task_name`` is
83
+ passed, the task segment stages ONLY that task directory — it never walks
84
+ ``tasks_dir.iterdir()`` over all active tasks. This mirrors
85
+ :func:`safe_archive_paths_to_add` and prevents dirty changes in OTHER
86
+ parallel-window task dirs from being bundled into the session auto-commit.
87
+
88
+ Backwards-compat: with no ``task_name``, the function walks every active
89
+ task directory (+ the archive subtree) the old wide way. New callers
90
+ should always pass ``task_name``.
77
91
  """
78
92
  paths: list[str] = []
79
93
 
@@ -93,20 +107,36 @@ def safe_trellis_paths_to_add(repo_root: Path) -> list[str]:
93
107
  f"{DIR_WORKFLOW}/{DIR_WORKSPACE}/{developer}/index.md"
94
108
  )
95
109
 
96
- # Active tasks: each direct child of tasks/ that is a directory and not
97
- # the archive root. The archive subtree is added as a single path below.
98
110
  tasks_dir = repo_root / DIR_WORKFLOW / DIR_TASKS
99
- if tasks_dir.is_dir():
100
- for child in sorted(tasks_dir.iterdir()):
101
- if not child.is_dir():
102
- continue
103
- if child.name == DIR_ARCHIVE:
104
- continue
105
- paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{child.name}")
106
-
107
- archive_dir = tasks_dir / DIR_ARCHIVE
108
- if archive_dir.is_dir():
109
- paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}")
111
+ if not tasks_dir.is_dir():
112
+ return paths
113
+
114
+ if task_name is not None:
115
+ # Narrow scope — ONLY the current task directory (active or archived).
116
+ # Never iterdir() all tasks: parallel-window dirty task dirs must not
117
+ # leak into the session auto-commit.
118
+ active_task = tasks_dir / task_name
119
+ if active_task.is_dir():
120
+ paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{task_name}")
121
+ archived_task = tasks_dir / DIR_ARCHIVE / task_name
122
+ if archived_task.is_dir():
123
+ paths.append(
124
+ f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}/{task_name}"
125
+ )
126
+ return paths
127
+
128
+ # Legacy wide scope (no task_name): each direct child of tasks/ that is a
129
+ # directory and not the archive root, plus the whole archive subtree.
130
+ for child in sorted(tasks_dir.iterdir()):
131
+ if not child.is_dir():
132
+ continue
133
+ if child.name == DIR_ARCHIVE:
134
+ continue
135
+ paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{child.name}")
136
+
137
+ archive_dir = tasks_dir / DIR_ARCHIVE
138
+ if archive_dir.is_dir():
139
+ paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}")
110
140
 
111
141
  return paths
112
142
 
@@ -115,7 +115,7 @@ def _repo_relative_path(path: Path, repo_root: Path) -> str:
115
115
  # Keep in sync with src/types/ai-tools.ts AI_TOOLS entries — these are the
116
116
  # platforms listed in workflow.md's "agent-capable" Skill Routing block
117
117
  # (Class-1 hook-inject + Class-2 pull-based preludes). Kilo / Antigravity /
118
- # Windsurf are NOT in this list: they do not consume JSONL.
118
+ # Devin are NOT in this list: they do not consume JSONL.
119
119
  _SUBAGENT_CONFIG_DIRS: tuple[str, ...] = (
120
120
  ".claude",
121
121
  ".cursor",
@@ -299,7 +299,7 @@ def cmd_create(args: argparse.Namespace) -> int:
299
299
 
300
300
  # Seed implement.jsonl / check.jsonl for sub-agent-capable platforms.
301
301
  # Agent curates real entries during planning when the task needs them.
302
- # Agent-less platforms (Kilo / Antigravity / Windsurf) skip this — they
302
+ # Agent-less platforms (Kilo / Antigravity / Devin) skip this — they
303
303
  # load specs via the trellis-before-dev skill instead of JSONL.
304
304
  seeded_jsonl = False
305
305
  if _has_subagent_platform(repo_root):