@pennixrv/trellis 0.6.45 → 0.7.0-beta.5

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 (79) hide show
  1. package/dist/cli/index.d.ts.map +1 -1
  2. package/dist/cli/index.js +21 -3
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/commands/mem.d.ts.map +1 -1
  5. package/dist/commands/mem.js +6 -13
  6. package/dist/commands/mem.js.map +1 -1
  7. package/dist/commands/workflow.d.ts +17 -0
  8. package/dist/commands/workflow.d.ts.map +1 -1
  9. package/dist/commands/workflow.js +222 -0
  10. package/dist/commands/workflow.js.map +1 -1
  11. package/dist/configurators/claude.d.ts.map +1 -1
  12. package/dist/configurators/claude.js.map +1 -1
  13. package/dist/configurators/dsh.d.ts +16 -19
  14. package/dist/configurators/dsh.d.ts.map +1 -1
  15. package/dist/configurators/dsh.js +38 -26
  16. package/dist/configurators/dsh.js.map +1 -1
  17. package/dist/configurators/gemini.d.ts.map +1 -1
  18. package/dist/configurators/gemini.js.map +1 -1
  19. package/dist/configurators/opencode.d.ts.map +1 -1
  20. package/dist/configurators/opencode.js +4 -0
  21. package/dist/configurators/opencode.js.map +1 -1
  22. package/dist/migrations/manifests/0.6.17.json +2 -2
  23. package/dist/migrations/manifests/0.7.0-beta.4.json +9 -0
  24. package/dist/migrations/manifests/0.7.0-beta.4.pennix.1.json +9 -0
  25. package/dist/migrations/manifests/0.7.0-beta.5.json +9 -0
  26. package/dist/templates/claude/hooks/statusline.py +7 -0
  27. package/dist/templates/claude/settings.json +22 -0
  28. package/dist/templates/codex/hooks/session-start.py +20 -1
  29. package/dist/templates/codex/hooks.json +25 -0
  30. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +2 -2
  31. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +2 -1
  32. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +3 -2
  33. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +1 -1
  34. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +5 -4
  35. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +1 -0
  36. package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +1 -1
  37. package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +2 -1
  38. package/dist/templates/copilot/hooks/session-start.py +20 -1
  39. package/dist/templates/dsh/DSH.md +61 -37
  40. package/dist/templates/dsh/agents/trellis-check.md +99 -0
  41. package/dist/templates/dsh/agents/trellis-implement.md +106 -0
  42. package/dist/templates/dsh/agents/trellis-research.md +134 -0
  43. package/dist/templates/dsh/index.d.ts +12 -11
  44. package/dist/templates/dsh/index.d.ts.map +1 -1
  45. package/dist/templates/dsh/index.js +14 -12
  46. package/dist/templates/dsh/index.js.map +1 -1
  47. package/dist/templates/opencode/plugins/inject-spec-context.js +121 -0
  48. package/dist/templates/opencode/plugins/inject-workflow-state.js +111 -10
  49. package/dist/templates/pi/extensions/trellis/index.ts.txt +164 -10
  50. package/dist/templates/shared-hooks/index.d.ts +8 -2
  51. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  52. package/dist/templates/shared-hooks/index.js +13 -1
  53. package/dist/templates/shared-hooks/index.js.map +1 -1
  54. package/dist/templates/shared-hooks/inject-spec-context.py +844 -0
  55. package/dist/templates/shared-hooks/inject-workflow-state.py +35 -9
  56. package/dist/templates/shared-hooks/session-start.py +22 -1
  57. package/dist/templates/trellis/config.yaml +47 -0
  58. package/dist/templates/trellis/index.d.ts +3 -0
  59. package/dist/templates/trellis/index.d.ts.map +1 -1
  60. package/dist/templates/trellis/index.js +6 -0
  61. package/dist/templates/trellis/index.js.map +1 -1
  62. package/dist/templates/trellis/scripts/common/active_task.py +24 -2
  63. package/dist/templates/trellis/scripts/common/cli_adapter.py +38 -6
  64. package/dist/templates/trellis/scripts/common/config.py +18 -0
  65. package/dist/templates/trellis/scripts/common/context_projection.py +2 -2
  66. package/dist/templates/trellis/scripts/common/git_context.py +34 -2
  67. package/dist/templates/trellis/scripts/common/paths.py +28 -0
  68. package/dist/templates/trellis/scripts/common/spec_inject.py +439 -0
  69. package/dist/templates/trellis/scripts/common/spec_match.py +395 -0
  70. package/dist/templates/trellis/scripts/common/task_store.py +88 -1
  71. package/dist/templates/trellis/scripts/common/trellis_config.py +46 -7
  72. package/dist/templates/trellis/scripts/common/workflow_phase.py +3 -2
  73. package/dist/templates/trellis/scripts/common/workflow_selection.py +177 -0
  74. package/dist/templates/trellis/scripts/task.py +83 -0
  75. package/dist/templates/trellis/workflow.md +35 -30
  76. package/dist/types/ai-tools.d.ts.map +1 -1
  77. package/dist/types/ai-tools.js +26 -13
  78. package/dist/types/ai-tools.js.map +1 -1
  79. package/package.json +2 -2
@@ -10,9 +10,11 @@ The emitted ``hookEventName`` field is platform-aware: most hosts expect
10
10
  CodeBuddy / Droid / Codex / Copilot wiring), but Gemini CLI 0.40.x renamed
11
11
  its per-turn event to ``BeforeAgent`` and its schema validator rejects the
12
12
  legacy name. ``_detect_platform`` picks the right value at runtime.
13
- Breadcrumb text is pulled exclusively from workflow.md
14
- [workflow-state:STATUS] tag blocks — workflow.md is the single source of
15
- truth. There are no fallback dicts in this script: when workflow.md is
13
+ Breadcrumb text is pulled exclusively from the resolved workflow file's
14
+ [workflow-state:STATUS] tag blocks — the active task may select a
15
+ per-task variant (`.trellis/workflows/<id>.md` via task.json `workflow`),
16
+ otherwise personal, team, and global defaults are resolved in order.
17
+ There are no fallback dicts in this script: when the resolved workflow is
16
18
  missing or a tag is absent, the breadcrumb degrades to a generic
17
19
  "Refer to workflow.md for current step." line so users see (and fix)
18
20
  the broken state instead of the hook silently masking it.
@@ -211,16 +213,40 @@ _TAG_RE = re.compile(
211
213
  re.DOTALL,
212
214
  )
213
215
 
214
- def load_breadcrumbs(root: Path) -> dict[str, str]:
215
- """Parse workflow.md for [workflow-state:STATUS] blocks.
216
+ def _resolve_workflow_md(root: Path, input_data: dict) -> Path:
217
+ """Resolve the active task's workflow file, falling back to the global one.
216
218
 
217
- Returns {status: body_text}. workflow.md is the single source of
219
+ The per-task resolution rule lives in common.workflow_selection inside
220
+ .trellis/scripts. Older installed projects may not ship that module, and
221
+ hooks must never crash the session — ANY failure (import error, old
222
+ scripts tree, resolver bug) falls back to the global workflow.md.
223
+ """
224
+ try:
225
+ scripts_dir = root / ".trellis" / "scripts"
226
+ if str(scripts_dir) not in sys.path:
227
+ sys.path.insert(0, str(scripts_dir))
228
+ from common.workflow_selection import resolve_workflow_md # type: ignore[import-not-found]
229
+
230
+ return resolve_workflow_md(
231
+ root, input_data, platform=_detect_platform(input_data)
232
+ )
233
+ except Exception:
234
+ return root / ".trellis" / "workflow.md"
235
+
236
+
237
+ def load_breadcrumbs(root: Path, input_data: dict) -> dict[str, str]:
238
+ """Parse the resolved workflow file for [workflow-state:STATUS] blocks.
239
+
240
+ Returns {status: body_text}. The workflow file is the single source of
218
241
  truth — there are no fallback dicts in this script. Missing tags
219
- (or a missing/unreadable workflow.md) fall back to a generic line
242
+ (or a missing/unreadable workflow file) fall back to a generic line
220
243
  in build_breadcrumb so users see the broken state and fix
221
244
  workflow.md, rather than the hook silently masking the issue.
245
+ The active task's per-task workflow selection (task.json `workflow`
246
+ field) is honored via _resolve_workflow_md; without a selection this
247
+ reads the global .trellis/workflow.md exactly as before.
222
248
  """
223
- workflow = root / ".trellis" / "workflow.md"
249
+ workflow = _resolve_workflow_md(root, input_data)
224
250
  if not workflow.is_file():
225
251
  return {}
226
252
  try:
@@ -443,7 +469,7 @@ def main() -> int:
443
469
  if prompt_has_skip_keyword(data.get("prompt", ""), _resolve_skip_keyword(config)):
444
470
  return 0 # user opted out of the per-turn breadcrumb for this turn
445
471
 
446
- templates = load_breadcrumbs(root)
472
+ templates = load_breadcrumbs(root, data)
447
473
  platform = _detect_platform(data)
448
474
  task = get_active_task(root, data)
449
475
  if task is None:
@@ -800,6 +800,27 @@ def _strip_breadcrumb_tag_blocks(content: str) -> str:
800
800
  return re.sub(r"\n{3,}", "\n\n", stripped).strip()
801
801
 
802
802
 
803
+ def _resolve_workflow_md(root: Path, input_data: dict) -> Path:
804
+ """Resolve the active task's workflow file, falling back to the global one.
805
+
806
+ The per-task resolution rule lives in common.workflow_selection inside
807
+ .trellis/scripts. Older installed projects may not ship that module, and
808
+ hooks must never crash the session — ANY failure (import error, old
809
+ scripts tree, resolver bug) falls back to the global workflow.md.
810
+ """
811
+ try:
812
+ scripts_dir = root / ".trellis" / "scripts"
813
+ if str(scripts_dir) not in sys.path:
814
+ sys.path.insert(0, str(scripts_dir))
815
+ from common.workflow_selection import resolve_workflow_md # type: ignore[import-not-found]
816
+
817
+ return resolve_workflow_md(
818
+ root, input_data, platform=_detect_platform(input_data)
819
+ )
820
+ except Exception:
821
+ return root / ".trellis" / "workflow.md"
822
+
823
+
803
824
  def _build_workflow_overview(workflow_path: Path) -> str:
804
825
  """Inject only the compact Phase Index summary for SessionStart."""
805
826
  content = read_file(workflow_path)
@@ -885,7 +906,7 @@ Trellis compact SessionStart context. Use it to orient the session; load details
885
906
  output.write("\n</current-state>\n\n")
886
907
 
887
908
  output.write("<trellis-workflow>\n")
888
- output.write(_build_workflow_overview(trellis_dir / "workflow.md"))
909
+ output.write(_build_workflow_overview(_resolve_workflow_md(project_dir, hook_input)))
889
910
  output.write("\n</trellis-workflow>\n\n")
890
911
 
891
912
  output.write("<guidelines>\n")
@@ -76,6 +76,21 @@ max_journal_lines: 2000
76
76
  # Default package used when --package is not specified.
77
77
  # default_package: frontend
78
78
 
79
+ #-------------------------------------------------------------------------------
80
+ # Default workflow
81
+ #-------------------------------------------------------------------------------
82
+ # Team-shared default workflow for tasks that do not pin one. The id names a
83
+ # variant file in `.trellis/workflows/<id>.md` (populate it with
84
+ # `trellis workflow --save <id>`). This value is committed, so the whole team
85
+ # shares the same default. A per-developer override lives in the gitignored
86
+ # `.developer` file as a `workflow=<id>` line and takes precedence over this.
87
+ #
88
+ # Resolution precedence: per-task (task.json `workflow`) > personal
89
+ # (`.developer` `workflow=`) > this `default_workflow` > global
90
+ # `.trellis/workflow.md`.
91
+ #
92
+ # default_workflow: native
93
+
79
94
  #-------------------------------------------------------------------------------
80
95
  # Channel worker OOM guard
81
96
  #-------------------------------------------------------------------------------
@@ -153,6 +168,38 @@ channel:
153
168
  # max_artifact_bytes: 65536 # per task artifact (prd.md / design.md / implement.md)
154
169
  # max_total_bytes: 131072 # whole injected payload; overflow degrades to index lines
155
170
 
171
+ #-------------------------------------------------------------------------------
172
+ # Path-scoped spec injection
173
+ #-------------------------------------------------------------------------------
174
+ # When the agent touches a file (Read/Edit/Write/MultiEdit), spec .md files
175
+ # under .trellis/spec/ whose frontmatter `paths:` globs match the touched path
176
+ # are surfaced into the session right then. The first time a spec matches it is
177
+ # injected in full; while its content is unchanged and the refresh window has
178
+ # not elapsed it stays silent; once the window elapses a short `<spec-ticket>`
179
+ # reminder is emitted to counter recency decay. Editing the spec itself — or a
180
+ # SessionStart after /clear or /compact — re-injects the full text.
181
+ # Oversized specs are truncated with a notice; once the per-event payload cap
182
+ # is reached, remaining full bodies degrade to index lines (path + description)
183
+ # instead of being inlined.
184
+ #
185
+ # Character values: the ceiling this budget respects is Claude Code's
186
+ # documented 10,000-CHARACTER additionalContext limit, so the caps count
187
+ # characters too (byte caps made CJK specs pay 3x for the same text).
188
+ # `0` disables the corresponding limit.
189
+ # The refresh window uses wall-clock seconds. `0` disables time-based reminders;
190
+ # SessionStart resets after /clear or /compact still force a full re-injection.
191
+ #
192
+ # spec_injection:
193
+ # enabled: true # false disables injection entirely
194
+ # max_spec_chars: 9400 # per matched spec file
195
+ # max_total_chars: 9500 # whole per-event payload; overflow degrades to index lines
196
+ # refresh_window_seconds: 2700 # touches past this interval re-emit a ticket
197
+ # tools: # tool events that trigger injection
198
+ # - Read
199
+ # - Edit
200
+ # - Write
201
+ # - MultiEdit
202
+
156
203
  #-------------------------------------------------------------------------------
157
204
  # Per-turn prompt injection
158
205
  #-------------------------------------------------------------------------------
@@ -41,7 +41,10 @@ export declare const commonContinuationRecord: string;
41
41
  export declare const commonOwnershipRecord: string;
42
42
  export declare const commonPackagesContext: string;
43
43
  export declare const commonWorkflowPhase: string;
44
+ export declare const commonWorkflowSelection: string;
44
45
  export declare const commonTrellisConfig: string;
46
+ export declare const commonSpecMatch: string;
47
+ export declare const commonSpecInject: string;
45
48
  export declare const commonSafeCommit: string;
46
49
  export declare const getDeveloperScript: string;
47
50
  export declare const initDeveloperScript: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,uBAAuB,QAEnC,CAAC;AACF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,wBAAwB,QAEpC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAG9E,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAG7E,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAgC,CAAC;AAC/D,eAAO,MAAM,qBAAqB,QAAoC,CAAC;AAMvE,eAAO,MAAM,sBAAsB,QAAsC,CAAC;AAC1E,eAAO,MAAM,kBAAkB,QAAkC,CAAC;AAClE,eAAO,MAAM,oBAAoB,QAAoC,CAAC;AACtE,eAAO,MAAM,kBAAkB,QAAqC,CAAC;AAErE;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA0CnD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAOlD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,uBAAuB,QAEnC,CAAC;AACF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,wBAAwB,QAEpC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,uBAAuB,QAEnC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAG9E,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAG7E,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAgC,CAAC;AAC/D,eAAO,MAAM,qBAAqB,QAAoC,CAAC;AAMvE,eAAO,MAAM,sBAAsB,QAAsC,CAAC;AAC1E,eAAO,MAAM,kBAAkB,QAAkC,CAAC;AAClE,eAAO,MAAM,oBAAoB,QAAoC,CAAC;AACtE,eAAO,MAAM,kBAAkB,QAAqC,CAAC;AAErE;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA6CnD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAOlD"}
@@ -51,7 +51,10 @@ export const commonContinuationRecord = readTemplate("scripts/common/continuatio
51
51
  export const commonOwnershipRecord = readTemplate("scripts/common/ownership_record.py");
52
52
  export const commonPackagesContext = readTemplate("scripts/common/packages_context.py");
53
53
  export const commonWorkflowPhase = readTemplate("scripts/common/workflow_phase.py");
54
+ export const commonWorkflowSelection = readTemplate("scripts/common/workflow_selection.py");
54
55
  export const commonTrellisConfig = readTemplate("scripts/common/trellis_config.py");
56
+ export const commonSpecMatch = readTemplate("scripts/common/spec_match.py");
57
+ export const commonSpecInject = readTemplate("scripts/common/spec_inject.py");
55
58
  export const commonSafeCommit = readTemplate("scripts/common/safe_commit.py");
56
59
  // Python scripts - main
57
60
  export const getDeveloperScript = readTemplate("scripts/get_developer.py");
@@ -104,7 +107,10 @@ export function getAllScripts() {
104
107
  scripts.set("common/ownership_record.py", commonOwnershipRecord);
105
108
  scripts.set("common/packages_context.py", commonPackagesContext);
106
109
  scripts.set("common/workflow_phase.py", commonWorkflowPhase);
110
+ scripts.set("common/workflow_selection.py", commonWorkflowSelection);
107
111
  scripts.set("common/trellis_config.py", commonTrellisConfig);
112
+ scripts.set("common/spec_match.py", commonSpecMatch);
113
+ scripts.set("common/spec_inject.py", commonSpecInject);
108
114
  scripts.set("common/safe_commit.py", commonSafeCommit);
109
115
  // Main
110
116
  scripts.set("get_developer.py", getDeveloperScript);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"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"}
@@ -60,8 +60,8 @@ _KNOWN_PLATFORMS = {
60
60
  }
61
61
 
62
62
  # Every name below records how it was checked. Do NOT add a name by analogy
63
- # with a neighbour: a 2026-08-05 audit of all 21 platforms found 12 of the 21
64
- # declared names had never existed anywhere — they were pattern-guessed from a
63
+ # with a neighbour: a 2026-08-05 audit of the then-current 21 platforms found
64
+ # 12 declared names had never existed anywhere — they were pattern-guessed from
65
65
  # `<PLATFORM>_SESSION_ID` shape no vendor agreed to, and the uniformity was the
66
66
  # only "evidence" behind them. A platform with no verified name belongs in no
67
67
  # table; it resolves through TRELLIS_CONTEXT_ID or its hook/plugin bridge.
@@ -524,6 +524,28 @@ def resolve_context_key(
524
524
  scripts and subprocesses. It does not store the task itself.
525
525
  """
526
526
  if allow_environment_context:
527
+ # The optional dsh-trellis plugin contributes this managed DSH_* value
528
+ # per shell execution from the current DSH session header. DSH scrubs
529
+ # ambient DSH_* values before rebuilding that namespace, so this value
530
+ # cannot be inherited from an outer Claude/Codex Trellis session. It
531
+ # must outrank the generic override below, which ordinary child
532
+ # processes inherit indiscriminately.
533
+ dsh_override = _string_value(os.environ.get("DSH_TRELLIS_CONTEXT_ID"))
534
+ if dsh_override:
535
+ return _sanitize_key(dsh_override) or _hash_value(dsh_override)
536
+
537
+ # A real DSH managed shell rebuilds the complete DSH_* namespace: the
538
+ # paired sentinel and session id cannot be inherited from an outer
539
+ # Trellis host. Prefer that canonical env-table identity over
540
+ # a generic override that ordinary process inheritance may carry in.
541
+ if (
542
+ _string_value(os.environ.get("DSH_SHELL")) == "1"
543
+ and _string_value(os.environ.get("DSH_SESSION_ID"))
544
+ ):
545
+ dsh_context_key = _lookup_env_context_key("dsh")
546
+ if dsh_context_key:
547
+ return dsh_context_key
548
+
527
549
  override = _string_value(os.environ.get("TRELLIS_CONTEXT_ID"))
528
550
  if override:
529
551
  return _sanitize_key(override) or _hash_value(override)
@@ -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, Devin, 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, Pi Agent, and DeepSeek Harness interfaces.
5
5
 
6
6
  Supported platforms:
7
7
  - claude: Claude Code (default)
@@ -23,6 +23,7 @@ Supported platforms:
23
23
  - omp: Oh My Pi
24
24
  - grok: Grok Build (pull-based skills/agents; no hook context injection)
25
25
  - kimi: Kimi Code (pull-based skills; commands delivered as skills; no hook context injection)
26
+ - dsh: DeepSeek Harness (pull-based skills + native shell session identity)
26
27
 
27
28
  Usage:
28
29
  from common.cli_adapter import CLIAdapter
@@ -61,6 +62,7 @@ Platform = Literal[
61
62
  "omp",
62
63
  "grok",
63
64
  "kimi",
65
+ "dsh",
64
66
  ]
65
67
 
66
68
 
@@ -143,6 +145,8 @@ class CLIAdapter:
143
145
  return ".grok"
144
146
  elif self.platform == "kimi":
145
147
  return ".kimi-code"
148
+ elif self.platform == "dsh":
149
+ return ".dsh"
146
150
  else:
147
151
  return ".claude"
148
152
 
@@ -170,6 +174,14 @@ class CLIAdapter:
170
174
  mapped_name = self.get_agent_name(agent)
171
175
  if self.platform == "codex":
172
176
  return self.get_config_dir(project_root) / "agents" / f"{mapped_name}.toml"
177
+ if self.platform == "dsh":
178
+ role = mapped_name.removeprefix("trellis-").removeprefix("agent-")
179
+ return (
180
+ self.get_config_dir(project_root)
181
+ / "skills"
182
+ / f"trellis-agent-{role}"
183
+ / "SKILL.md"
184
+ )
173
185
  return self.get_config_dir(project_root) / "agents" / f"{mapped_name}.md"
174
186
 
175
187
  def get_commands_path(self, project_root: Path, *parts: str) -> Path:
@@ -212,8 +224,8 @@ class CLIAdapter:
212
224
  return commands_dir / f"trellis-{filename}.md"
213
225
  return commands_dir / Path(*parts)
214
226
 
215
- # Kimi: commands are skills under .kimi-code/skills/trellis-<name>/SKILL.md
216
- if self.platform == "kimi":
227
+ # Kimi and DSH: commands are skills under the platform-private skill root.
228
+ if self.platform in ("kimi", "dsh"):
217
229
  skills_dir = self.get_config_dir(project_root) / "skills"
218
230
  if not parts:
219
231
  return skills_dir
@@ -311,6 +323,8 @@ class CLIAdapter:
311
323
  return f"{self.config_dir_name}/commands/trellis-{name}.md"
312
324
  elif self.platform == "kimi":
313
325
  return f".kimi-code/skills/trellis-{name}/SKILL.md"
326
+ elif self.platform == "dsh":
327
+ return f".dsh/skills/trellis-{name}/SKILL.md"
314
328
  else:
315
329
  return f"{self.config_dir_name}/commands/trellis/{name}.md"
316
330
 
@@ -356,6 +370,8 @@ class CLIAdapter:
356
370
  return {}
357
371
  elif self.platform == "kimi":
358
372
  return {}
373
+ elif self.platform == "dsh":
374
+ return {}
359
375
  else:
360
376
  return {"CLAUDE_NON_INTERACTIVE": "1"}
361
377
 
@@ -456,6 +472,10 @@ class CLIAdapter:
456
472
  # Headless single-prompt with auto-approval; sub-agents are the
457
473
  # built-in coder/explore/plan agents dispatched in-session.
458
474
  cmd = ["kimi", "-p", prompt, "--yolo"]
475
+ elif self.platform == "dsh":
476
+ # The headless profile accepts one prompt and exits. Trellis roles
477
+ # are loaded as skills by in-session sub-agents, not CLI agent ids.
478
+ cmd = ["dsh", "--profile", "headless", prompt]
459
479
 
460
480
  else: # claude
461
481
  cmd = ["claude", "-p"]
@@ -534,6 +554,8 @@ class CLIAdapter:
534
554
  return ["grok", "-c"]
535
555
  elif self.platform == "kimi":
536
556
  return ["kimi", "--session", session_id]
557
+ elif self.platform == "dsh":
558
+ return ["dsh", "--profile", "tui", "--resume", session_id]
537
559
  else:
538
560
  return ["claude", "--resume", session_id]
539
561
 
@@ -616,6 +638,8 @@ class CLIAdapter:
616
638
  return "grok"
617
639
  elif self.platform == "kimi":
618
640
  return "kimi"
641
+ elif self.platform == "dsh":
642
+ return "dsh"
619
643
  else:
620
644
  return "claude"
621
645
 
@@ -634,6 +658,7 @@ class CLIAdapter:
634
658
  "pi",
635
659
  "grok",
636
660
  "kimi",
661
+ "dsh",
637
662
  )
638
663
 
639
664
  @property
@@ -688,7 +713,7 @@ def get_cli_adapter(platform: str = "claude") -> CLIAdapter:
688
713
  """Get CLI adapter for the specified platform.
689
714
 
690
715
  Args:
691
- platform: Platform name ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'devin', 'qoder', 'codebuddy', 'copilot', 'droid', 'pi', or 'trae')
716
+ platform: Platform name ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'devin', 'qoder', 'codebuddy', 'copilot', 'droid', 'pi', 'trae', 'omp', 'grok', 'kimi', or 'dsh')
692
717
 
693
718
  Returns:
694
719
  CLIAdapter instance
@@ -723,9 +748,10 @@ def get_cli_adapter(platform: str = "claude") -> CLIAdapter:
723
748
  "omp",
724
749
  "grok",
725
750
  "kimi",
751
+ "dsh",
726
752
  ):
727
753
  raise ValueError(
728
- f"Unsupported platform: {platform} (must be 'claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'devin', 'qoder', 'codebuddy', 'copilot', 'droid', 'pi', 'trae', 'omp', 'grok', or 'kimi')"
754
+ f"Unsupported platform: {platform} (must be 'claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'devin', 'qoder', 'codebuddy', 'copilot', 'droid', 'pi', 'trae', 'omp', 'grok', 'kimi', or 'dsh')"
729
755
  )
730
756
 
731
757
  return CLIAdapter(platform=platform) # type: ignore
@@ -752,6 +778,7 @@ _ALL_PLATFORM_CONFIG_DIRS = (
752
778
  ".omp",
753
779
  ".grok",
754
780
  ".kimi-code",
781
+ ".dsh",
755
782
  )
756
783
  """Platform-specific config directory names used by detect_platform exclusion
757
784
  checks. `.agents/skills/` is NOT listed here: it is a shared cross-platform
@@ -795,7 +822,7 @@ def detect_platform(project_root: Path) -> Platform:
795
822
  project_root: Project root directory
796
823
 
797
824
  Returns:
798
- Detected platform ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'devin', 'qoder', 'codebuddy', 'copilot', 'droid', 'pi', 'trae', or default 'claude')
825
+ Detected platform ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'devin', 'qoder', 'codebuddy', 'copilot', 'droid', 'pi', 'trae', 'omp', 'grok', 'kimi', 'dsh', or default 'claude')
799
826
  """
800
827
  import os
801
828
 
@@ -824,6 +851,7 @@ def detect_platform(project_root: Path) -> Platform:
824
851
  "omp",
825
852
  "grok",
826
853
  "kimi",
854
+ "dsh",
827
855
  ):
828
856
  return env_platform # type: ignore
829
857
 
@@ -916,6 +944,10 @@ def detect_platform(project_root: Path) -> Platform:
916
944
  if (project_root / ".kimi-code").is_dir():
917
945
  return "kimi"
918
946
 
947
+ # Check for .dsh directory (DeepSeek Harness-specific)
948
+ if (project_root / ".dsh").is_dir():
949
+ return "dsh"
950
+
919
951
  # Fallback: checkout only has the Codex shared-skills layer
920
952
  # (.agents/skills/trellis-* dirs) and no explicit platform config dir.
921
953
  # Happens on fresh clones where .codex/ is gitignored/absent but the
@@ -174,6 +174,24 @@ def get_codex_dispatch_mode(repo_root: Path | None = None) -> str:
174
174
  return "inline"
175
175
 
176
176
 
177
+ def get_default_workflow(repo_root: Path | None = None) -> str | None:
178
+ """Return the team-shared default workflow id from config.yaml.
179
+
180
+ Reads the top-level ``default_workflow`` key — a slug naming a variant in
181
+ ``.trellis/workflows/<id>.md``. Returns None when unset or blank. This is
182
+ the git-tracked, team-shared default; a per-developer override lives in the
183
+ gitignored ``.developer`` file (``workflow=<id>``, see
184
+ ``paths.get_developer_workflow``) and outranks it. Fail-open: a missing or
185
+ non-string value simply means "no team default" — no warning (this is read
186
+ on every turn by hooks and must not add per-turn noise).
187
+ """
188
+ config = _load_config(repo_root)
189
+ raw = config.get("default_workflow")
190
+ if not isinstance(raw, str):
191
+ return None
192
+ return raw.strip() or None
193
+
194
+
177
195
  DEFAULT_CONTEXT_INJECTION_MAX_FILE_BYTES = 32768
178
196
  DEFAULT_CONTEXT_INJECTION_MAX_ARTIFACT_BYTES = 65536
179
197
  DEFAULT_CONTEXT_INJECTION_MAX_TOTAL_BYTES = 131072
@@ -95,8 +95,8 @@ def truncate_utf8(data: bytes, cap: int) -> bytes:
95
95
  else:
96
96
  sequence_length = 1
97
97
  if (index - 1) + sequence_length > len(truncated):
98
- index -= 1
99
- return truncated[:index]
98
+ return truncated[: index - 1]
99
+ return truncated
100
100
 
101
101
 
102
102
  def is_binary_content(data: bytes) -> bool:
@@ -27,6 +27,8 @@ from .packages_context import (
27
27
  get_context_packages_text,
28
28
  get_context_packages_json,
29
29
  )
30
+ from .paths import get_repo_root
31
+ from .spec_match import match_specs_for_file
30
32
  from .trellis_config import read_trellis_config
31
33
  from .workflow_phase import (
32
34
  filter_platform,
@@ -57,9 +59,9 @@ def main() -> None:
57
59
  parser.add_argument(
58
60
  "--mode",
59
61
  "-m",
60
- choices=["default", "record", "packages", "phase"],
62
+ choices=["default", "record", "packages", "phase", "spec"],
61
63
  default="default",
62
- help="Output mode: default (full context), record (for record-session), packages (package info only), phase (workflow step extraction)",
64
+ help="Output mode: default (full context), record (for record-session), packages (package info only), phase (workflow step extraction), spec (specs governing a file)",
63
65
  )
64
66
  parser.add_argument(
65
67
  "--step",
@@ -69,6 +71,10 @@ def main() -> None:
69
71
  "--platform",
70
72
  help="Platform name for --mode phase, e.g. cursor, claude-code. Filters platform-tagged blocks.",
71
73
  )
74
+ parser.add_argument(
75
+ "--file",
76
+ help="File path (absolute or repo-relative) for --mode spec. Lists spec files whose frontmatter paths match it.",
77
+ )
72
78
 
73
79
  args = parser.parse_args()
74
80
 
@@ -95,6 +101,32 @@ def main() -> None:
95
101
  )
96
102
  content = filter_platform(content, effective)
97
103
  print(content, end="")
104
+ elif args.mode == "spec":
105
+ if not args.file:
106
+ parser.error("--file is required with --mode spec")
107
+ matches = match_specs_for_file(get_repo_root(), args.file)
108
+ if args.json:
109
+ print(
110
+ json.dumps(
111
+ {
112
+ "file": args.file,
113
+ "matches": [
114
+ {
115
+ "path": match.rel_path,
116
+ "description": match.description,
117
+ }
118
+ for match in matches
119
+ ],
120
+ },
121
+ indent=2,
122
+ ensure_ascii=False,
123
+ )
124
+ )
125
+ elif matches:
126
+ for match in matches:
127
+ print(f"{match.rel_path} — {match.description or '(no description)'}")
128
+ else:
129
+ print(f"No spec files declare paths matching {args.file}.")
98
130
  else:
99
131
  if args.json:
100
132
  output_json()
@@ -139,6 +139,34 @@ def get_developer(repo_root: Path | None = None) -> str | None:
139
139
  return _read_developer_file(main_root / DIR_WORKFLOW / FILE_DEVELOPER)
140
140
 
141
141
 
142
+ def get_developer_workflow(repo_root: Path | None = None) -> str | None:
143
+ """Get the personal workflow override from the .developer file.
144
+
145
+ Reads an optional ``workflow=<id>`` line from the gitignored ``.developer``
146
+ file — the per-developer, git-excluded override that outranks the
147
+ team-shared ``default_workflow`` in config.yaml. Returns None when the file
148
+ or the line is absent/blank. Never raises. Additive to ``get_developer``:
149
+ the ``name=`` reader ignores this line and vice versa.
150
+ """
151
+ if repo_root is None:
152
+ repo_root = get_repo_root()
153
+
154
+ dev_file = repo_root / DIR_WORKFLOW / FILE_DEVELOPER
155
+
156
+ if not dev_file.is_file():
157
+ return None
158
+
159
+ try:
160
+ content = dev_file.read_text(encoding="utf-8")
161
+ for line in content.splitlines():
162
+ if line.startswith("workflow="):
163
+ return line.split("=", 1)[1].strip() or None
164
+ except (OSError, IOError):
165
+ pass
166
+
167
+ return None
168
+
169
+
142
170
  def check_developer(repo_root: Path | None = None) -> bool:
143
171
  """Check if developer is initialized.
144
172