@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
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Per-task workflow selection.
4
+
5
+ Resolves which workflow markdown file consumers should read. A task may pin
6
+ a workflow variant by storing `"workflow": "<id>"` in its task.json; the
7
+ variant body lives at `.trellis/workflows/<id>.md` (user-managed library).
8
+
9
+ Resolution precedence (single source of truth for all consumers), highest
10
+ to lowest — each layer resolves an id to `.trellis/workflows/<id>.md` and
11
+ falls through when unset, invalid, or pointing at a missing file:
12
+ 1. Per-task pin - active task's task.json `workflow` (session-bound,
13
+ explicit; a bad id or missing file warns once on stderr, then falls
14
+ through rather than aborting).
15
+ 2. Personal - `.developer` `workflow=<id>` (gitignored, per-developer;
16
+ outranks the team default). Silent on miss.
17
+ 3. Team default - config.yaml `default_workflow` (git-tracked, shared).
18
+ Silent on miss.
19
+ 4. Global - `.trellis/workflow.md`.
20
+ With neither a per-task pin nor the personal/team keys set, this is identical
21
+ to reading the global `.trellis/workflow.md`. Never raises.
22
+
23
+ Provides:
24
+ workflow_md_for_task - Full precedence for an already-resolved task dir
25
+ resolve_workflow_md - Session-aware wrapper via the active task resolver
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ import json
31
+ import re
32
+ import sys
33
+ from pathlib import Path
34
+
35
+ from .paths import DIR_WORKFLOW, FILE_TASK_JSON
36
+
37
+ # Workflow variant library directory under .trellis/ (plural on purpose:
38
+ # `.trellis/workflow/` is reserved by the YAML-manifest migration).
39
+ DIR_WORKFLOWS = "workflows"
40
+
41
+ # Workflow ids must be plain slugs; anything else (path separators, dots)
42
+ # is rejected so a task.json value can never escape .trellis/workflows/.
43
+ WORKFLOW_ID_RE = re.compile(r"^[A-Za-z0-9_-]+$")
44
+
45
+
46
+ def _global_workflow_md(repo_root: Path) -> Path:
47
+ return repo_root / DIR_WORKFLOW / "workflow.md"
48
+
49
+
50
+ def _library_variant(repo_root: Path, workflow_id: str | None) -> Path | None:
51
+ """Map a workflow id to its library file if valid and present, else None.
52
+
53
+ Shared by every layer (per-task pin, personal, team). An id with path
54
+ separators/dots/blanks, or one whose `.trellis/workflows/<id>.md` file does
55
+ not exist, returns None so the caller falls through. Never raises.
56
+ """
57
+ if not isinstance(workflow_id, str) or not workflow_id:
58
+ return None
59
+ if not WORKFLOW_ID_RE.match(workflow_id):
60
+ return None
61
+ variant = repo_root / DIR_WORKFLOW / DIR_WORKFLOWS / f"{workflow_id}.md"
62
+ return variant if variant.is_file() else None
63
+
64
+
65
+ def _developer_workflow_id(repo_root: Path) -> str | None:
66
+ """Personal override id from the gitignored .developer file (fail-open)."""
67
+ try:
68
+ from .paths import get_developer_workflow
69
+
70
+ return get_developer_workflow(repo_root)
71
+ except Exception:
72
+ return None
73
+
74
+
75
+ def _config_default_id(repo_root: Path) -> str | None:
76
+ """Team-shared default id from config.yaml `default_workflow` (fail-open)."""
77
+ try:
78
+ from .config import get_default_workflow
79
+
80
+ return get_default_workflow(repo_root)
81
+ except Exception:
82
+ return None
83
+
84
+
85
+ def _default_workflow_md(repo_root: Path) -> Path:
86
+ """Resolve the non-per-task default: personal -> team -> global.
87
+
88
+ Personal (`.developer` `workflow=`) outranks the team-shared
89
+ (config.yaml `default_workflow`) layer; both fall through to the global
90
+ `.trellis/workflow.md` when unset, invalid, or naming a missing file. These
91
+ layers are silent on miss (they are defaults, not an explicit per-task
92
+ choice — a per-turn warning would be noise).
93
+ """
94
+ for get_id in (_developer_workflow_id, _config_default_id):
95
+ variant = _library_variant(repo_root, get_id(repo_root))
96
+ if variant is not None:
97
+ return variant
98
+ return _global_workflow_md(repo_root)
99
+
100
+
101
+ def _task_pin_variant(repo_root: Path, task_dir: Path | None) -> Path | None:
102
+ """Return the per-task pinned variant path, or None to fall through.
103
+
104
+ Emits a stderr warning on an invalid id or a missing variant file (an
105
+ explicit per-task choice that cannot be honored), then returns None so
106
+ resolution continues with the personal/team defaults. Never raises.
107
+ """
108
+ if task_dir is None:
109
+ return None
110
+
111
+ try:
112
+ raw = json.loads((task_dir / FILE_TASK_JSON).read_text(encoding="utf-8"))
113
+ if not isinstance(raw, dict):
114
+ return None
115
+
116
+ workflow_id = raw.get("workflow")
117
+ if not isinstance(workflow_id, str) or not workflow_id:
118
+ return None
119
+
120
+ if not WORKFLOW_ID_RE.match(workflow_id):
121
+ print(
122
+ f"Warning: task '{task_dir.name}' has invalid workflow id "
123
+ f"{workflow_id!r}; using default workflow resolution",
124
+ file=sys.stderr,
125
+ )
126
+ return None
127
+
128
+ variant = _library_variant(repo_root, workflow_id)
129
+ if variant is not None:
130
+ return variant
131
+
132
+ print(
133
+ f"Warning: task '{task_dir.name}' selects workflow '{workflow_id}' but "
134
+ f"{DIR_WORKFLOW}/{DIR_WORKFLOWS}/{workflow_id}.md is missing; "
135
+ f"using default workflow resolution",
136
+ file=sys.stderr,
137
+ )
138
+ return None
139
+ except Exception:
140
+ return None
141
+
142
+
143
+ def workflow_md_for_task(repo_root: Path, task_dir: Path | None) -> Path:
144
+ """Return the workflow.md path for an already-resolved task dir (or None).
145
+
146
+ Applies the full precedence documented in the module docstring:
147
+ per-task pin -> personal (.developer) -> team (config.yaml) -> global.
148
+ Never raises; any failure falls through toward the global workflow path.
149
+ """
150
+ pin = _task_pin_variant(repo_root, task_dir)
151
+ if pin is not None:
152
+ return pin
153
+ return _default_workflow_md(repo_root)
154
+
155
+
156
+ def resolve_workflow_md(
157
+ repo_root: Path,
158
+ input_data: dict | None = None,
159
+ platform: str | None = None,
160
+ ) -> Path:
161
+ """Resolve the session-aware active task, then apply the resolution rule.
162
+
163
+ ``input_data`` is the raw hook payload (session/conversation identity);
164
+ CLI callers may omit it — the active-task resolver then falls back to
165
+ environment context. Never raises; any failure resolves to the global
166
+ `.trellis/workflow.md`.
167
+ """
168
+ try:
169
+ from .active_task import resolve_active_task, resolve_task_ref
170
+
171
+ active = resolve_active_task(repo_root, input_data, platform)
172
+ task_dir: Path | None = None
173
+ if active.task_path:
174
+ task_dir = resolve_task_ref(active.task_path, repo_root)
175
+ return workflow_md_for_task(repo_root, task_dir)
176
+ except Exception:
177
+ return _global_workflow_md(repo_root)
@@ -12,6 +12,7 @@ Usage:
12
12
  python3 task.py current [--source] [--json] # Show active task
13
13
  python3 task.py ownership <operation> ... # Manage formal handoff task ownership
14
14
  python3 task.py finish # Clear active task
15
+ python3 task.py workflow <id>|--clear # Set/clear per-task workflow selection
15
16
  python3 task.py set-branch <dir> <branch> # Set git branch
16
17
  python3 task.py set-base-branch <dir> <branch> # Set PR target branch
17
18
  python3 task.py set-scope <dir> <scope> # Set scope for PR title
@@ -51,11 +52,13 @@ from common.active_task import (
51
52
  from common.git import current_branch_name
52
53
  from common.io import (
53
54
  describe_json_read_failure,
55
+ read_json,
54
56
  read_json_checked,
55
57
  write_json,
56
58
  )
57
59
  from common.task_utils import resolve_task_dir, run_task_hooks
58
60
  from common.tasks import iter_active_tasks, children_progress
61
+ from common.workflow_selection import WORKFLOW_ID_RE, workflow_md_for_task
59
62
 
60
63
  # Import command handlers from split modules (also re-exports for plan.py compatibility)
61
64
  from common.task_store import (
@@ -483,6 +486,72 @@ def cmd_ownership(args: argparse.Namespace) -> int:
483
486
  return 2
484
487
 
485
488
 
489
+ # =============================================================================
490
+ # Command: workflow
491
+ # =============================================================================
492
+
493
+ def cmd_workflow(args: argparse.Namespace) -> int:
494
+ """Set or clear the workflow selection on the current session's active task."""
495
+ repo_root = get_repo_root()
496
+
497
+ if args.clear and args.id:
498
+ print(colored("Error: pass either <id> or --clear, not both", Colors.RED))
499
+ return 1
500
+ if not args.clear and not args.id:
501
+ print(colored("Error: workflow id required (or --clear)", Colors.RED))
502
+ print("Usage: python3 task.py workflow <id> | --clear")
503
+ return 1
504
+
505
+ active = resolve_active_task(repo_root)
506
+ if not active.task_path:
507
+ print(colored("Error: No current task set", Colors.RED))
508
+ print("Hint: run task.py start <dir> first")
509
+ return 1
510
+
511
+ task_dir = repo_root / active.task_path
512
+ task_json_path = task_dir / FILE_TASK_JSON
513
+ if not task_json_path.is_file():
514
+ print(colored(f"Error: task.json not found at {task_dir}", Colors.RED))
515
+ return 1
516
+
517
+ data = read_json(task_json_path)
518
+ if not data:
519
+ print(colored(f"Error: failed to read {task_json_path}", Colors.RED))
520
+ return 1
521
+
522
+ if args.clear:
523
+ if data.pop("workflow", None) is None:
524
+ print(colored("No workflow selection set on this task", Colors.YELLOW))
525
+ else:
526
+ if not write_json(task_json_path, data):
527
+ print(colored("Error: failed to update task.json", Colors.RED))
528
+ return 1
529
+ print(colored("✓ Workflow selection cleared", Colors.GREEN))
530
+ else:
531
+ workflow_id = args.id
532
+ if not WORKFLOW_ID_RE.match(workflow_id):
533
+ print(colored(
534
+ f"Error: invalid workflow id '{workflow_id}' (allowed: letters, digits, '-', '_')",
535
+ Colors.RED,
536
+ ))
537
+ return 1
538
+ data["workflow"] = workflow_id
539
+ if not write_json(task_json_path, data):
540
+ print(colored("Error: failed to update task.json", Colors.RED))
541
+ return 1
542
+ print(colored(f"✓ Workflow set to: {workflow_id}", Colors.GREEN))
543
+
544
+ # workflow_md_for_task warns on stderr itself when the selected variant
545
+ # file is missing (it can be saved later via `trellis workflow --save`).
546
+ effective = workflow_md_for_task(repo_root, task_dir)
547
+ try:
548
+ effective_display = effective.relative_to(repo_root).as_posix()
549
+ except ValueError:
550
+ effective_display = str(effective)
551
+ print(f"Effective workflow: {effective_display}")
552
+ return 0
553
+
554
+
486
555
  # =============================================================================
487
556
  # Command: list
488
557
  # =============================================================================
@@ -665,12 +734,15 @@ Usage:
665
734
  python3 task.py create <title> --description <desc> --package <pkg> Create task for a specific package
666
735
  python3 task.py create <title> --description <desc> --parent <dir> Create task as child of parent
667
736
  python3 task.py create <title> --description <desc> --no-start Create without making it active in this session
737
+ python3 task.py create <title> --description <desc> --workflow <id> Create task pinned to a workflow variant
668
738
  python3 task.py add-context <dir> <jsonl> <path> [reason] Add entry to jsonl
669
739
  python3 task.py validate <dir> Validate jsonl files
670
740
  python3 task.py list-context <dir> List jsonl entries
671
741
  python3 task.py start <dir> Set active task; records the checked-out branch when unset
672
742
  python3 task.py current [--source] Show active task
673
743
  python3 task.py finish Clear active task
744
+ python3 task.py workflow <id> Select workflow variant for active task
745
+ python3 task.py workflow --clear Clear selection (use default resolution)
674
746
  python3 task.py set-branch <dir> <branch> Set git branch
675
747
  python3 task.py set-base-branch <dir> <branch> Set PR target branch
676
748
  python3 task.py set-scope <dir> <scope> Set scope for PR title
@@ -794,6 +866,10 @@ def main() -> int:
794
866
  action="store_true",
795
867
  help="Create the task without making it active in this session",
796
868
  )
869
+ p_create.add_argument(
870
+ "--workflow",
871
+ help="Workflow variant id for this task (.trellis/workflows/<id>.md)",
872
+ )
797
873
  p_create.add_argument(
798
874
  "--force",
799
875
  action="store_true",
@@ -889,6 +965,12 @@ def main() -> int:
889
965
  # finish
890
966
  subparsers.add_parser("finish", help="Clear active task")
891
967
 
968
+ # workflow
969
+ p_workflow = subparsers.add_parser("workflow", help="Set/clear per-task workflow selection")
970
+ p_workflow.add_argument("id", nargs="?", help="Workflow id (.trellis/workflows/<id>.md)")
971
+ p_workflow.add_argument("--clear", action="store_true",
972
+ help="Remove the workflow selection (use default resolution)")
973
+
892
974
  # set-branch
893
975
  p_branch = subparsers.add_parser("set-branch", help="Set git branch")
894
976
  p_branch.add_argument("dir", help="Task directory")
@@ -969,6 +1051,7 @@ def main() -> int:
969
1051
  "continuity": cmd_continuity,
970
1052
  "ownership": cmd_ownership,
971
1053
  "finish": cmd_finish,
1054
+ "workflow": cmd_workflow,
972
1055
  "set-branch": cmd_set_branch,
973
1056
  "set-base-branch": cmd_set_base_branch,
974
1057
  "set-scope": cmd_set_scope,
@@ -151,14 +151,14 @@ python3 ./.trellis/scripts/get_context.py --mode phase --step <X.Y> # detailed
151
151
  ## Phase Index
152
152
 
153
153
  ```
154
- Phase 1: Plan → classify, get task-creation consent, then write planning artifacts
154
+ Phase 1: Plan → classify, then create planning artifacts for work that needs a task
155
155
  Phase 2: Execute → implement only after task status is in_progress
156
156
  Phase 3: Finish → verify, update spec, commit, and wrap up
157
157
  ```
158
158
 
159
159
  ### Request Triage
160
160
 
161
- - Simple conversation or small task: ask only whether this turn should create a Trellis task. If the user says no, skip Trellis for this session.
161
+ - Direct small work: for a clearly bounded, single-surface operation with an immediate verification path, proceed without creating a Trellis task. Apply normal safety rules. If discovery expands the scope or reveals a design, ownership, release, or durable-record need, stop and create a task before continuing.
162
162
  - Complex task: ask whether you may create a Trellis task and enter planning. If the user says no, do not do broad inline implementation; explain, clarify scope, or suggest a smaller split.
163
163
  - User approval to create a task is not approval to start implementation. Planning still happens first.
164
164
 
@@ -187,8 +187,8 @@ Create new children with `task.py create "<title>" --slug <name> --parent <paren
187
187
  <!-- Per-turn breadcrumb: shown when there is no active task (before Phase 1) -->
188
188
 
189
189
  [workflow-state:no_task]
190
- No active task. First classify the current turn and ask for task-creation consent before creating any Trellis task.
191
- Simple conversation / small task: ask only whether this turn should create a Trellis task. If the user says no, skip Trellis for this session.
190
+ No active task. First classify the current turn. Direct small work with a clear single owner and immediate verification may proceed without a Trellis task under normal safety rules.
191
+ If scope expands or requires design, ownership, release, credentials, or a durable record, create a Trellis task before continuing.
192
192
  Complex task: ask the user if you can create a Trellis task and enter the planning phase. If the user says no, explain, clarify scope, or suggest a smaller split.
193
193
  [/workflow-state:no_task]
194
194
 
@@ -259,10 +259,11 @@ Inline mode: skip jsonl curation; Phase 2 reads artifacts/specs via `trellis-bef
259
259
  therefore must cover every required step from implementation through
260
260
  commit, including Phase 3.3 spec update and Phase 3.4 commit. -->
261
261
 
262
- Sub-agent dispatch protocol applies to all platforms and all sub-agents, including native Codex `SubagentStart` context injection with child-side pull fallback, class-2 Gemini/Qoder/Copilot/Reasonix/Trae/Grok/Kimi Code, hook-backed ZCode/Snow, and `trellis-research`: every dispatch prompt starts with `Active task: <task path from task.py current>` before role-specific instructions. On Grok Build, use `spawn_subagent` with `subagent_type` set to the Trellis agent name (e.g. `trellis-implement`). On Kimi Code, dispatch the built-in `coder` / `explore` sub-agent with the matching `.kimi-code/skills/trellis-<role>/SKILL.md` instructions.
262
+ Sub-agent dispatch protocol applies to all platforms and all sub-agents, including native Codex `SubagentStart` context injection with child-side pull fallback, class-2 Gemini/Qoder/Copilot/Reasonix/Trae/Grok/Kimi Code/DeepSeek Harness, hook-backed ZCode/Snow, and `trellis-research`: every dispatch prompt starts with `Active task: <task path from task.py current>` before role-specific instructions. On Grok Build, use `spawn_subagent` with `subagent_type` set to the Trellis agent name (e.g. `trellis-implement`). On Kimi Code, dispatch the built-in `coder` / `explore` sub-agent with the matching `.kimi-code/skills/trellis-<role>/SKILL.md` instructions. On DeepSeek Harness, tell the child to load the matching `.dsh/skills/trellis-agent-<role>/SKILL.md` exactly once, then choose the synchronization path by capability. If the optional companion plugin exposes `trellis_wait`, dispatch `subagent` in its default continuable background mode, continue independent work, and call `trellis_wait` once per dependent child id when a dependent gate is next; each call returns only after DSH has queued that child's native settlement notice. Without `trellis_wait`, dispatch each child with `run_in_background: false` from the outset so no dependent gate can overtake it. Never simulate waiting with shell sleep, polling loops, `job_output`, repeated `list_agents`, or another long-running command, and never leave a background child without an event-driven wait path.
263
263
 
264
264
  [workflow-state:in_progress]
265
- Tools: `trellis-implement` / `trellis-research` are sub-agent types only (Task/Agent tool, NOT Skill; there is no skill by these names). `trellis-update-spec` is a skill. `trellis-check` exists as both; prefer the Agent form when verifying after code changes.
265
+ Tools: `trellis-implement` / `trellis-research` name sub-agent roles dispatched through your platform's sub-agent mechanism, not skills the main session loads itself (on Claude Code: use the Task/Agent tool, never the Skill tool). `trellis-update-spec` is a skill. `trellis-check` exists as both; prefer the Agent/role form when verifying after code changes.
266
+ On DeepSeek Harness, role instructions ship as collision-free `trellis-agent-implement` / `trellis-agent-check` / `trellis-agent-research` skills under `.dsh/skills/`. The main session must not load them itself: tell the child to load the matching role skill exactly once. If `trellis_wait` is available, use the default background mode, do independent work, then call `trellis_wait` once per dependent child id and consume each native settlement notice before entering the dependent gate. If it is unavailable, dispatch every child with `run_in_background: false` from the outset. Do not poll, sleep, or start a background child without an event-driven wait path.
266
267
  Flow: `trellis-implement` -> `trellis-check` -> `trellis-update-spec` -> commit (Phase 3.4) -> `/trellis:finish-work`.
267
268
  Use this block only when `codex.dispatch_mode: auto` is explicitly selected. Sub-agent self-exemption: if already running as `trellis-implement`, do NOT spawn another `trellis-implement` or `trellis-check`; if already running as `trellis-check`, do NOT spawn another `trellis-check` or `trellis-implement`. Dispatch is main session only.
268
269
  Dispatch prompt starts with `Active task: <task path from task.py current>`. Read context: jsonl entries -> `prd.md` -> `design.md if present` -> `implement.md if present`.
@@ -311,23 +312,23 @@ Code committed. Run `/trellis:finish-work`; if dirty, return to Phase 3.4 first.
311
312
 
312
313
  When a user request matches one of these intents inside an active task, route first, then load the detailed phase step if needed.
313
314
 
314
- [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code]
315
+ [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code, DeepSeek Harness]
315
316
 
316
317
  - Planning or unclear requirements -> `trellis-brainstorm`.
317
318
  - Explicit eligible `analysis_only` -> complete evidence in planning, then commit artifacts and archive directly.
318
319
  - `in_progress` implementation/check -> dispatch `trellis-implement` / `trellis-check`.
319
320
  - Repeated debugging -> `trellis-break-loop`; spec updates -> `trellis-update-spec`.
320
321
 
321
- [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code]
322
+ [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code, DeepSeek Harness]
322
323
 
323
- [codex-inline, Kilo, Antigravity, Devin, DeepSeek Harness]
324
+ [codex-inline, Kilo, Antigravity, Devin]
324
325
 
325
326
  - Planning or unclear requirements -> `trellis-brainstorm`.
326
327
  - Explicit eligible `analysis_only` -> complete evidence in planning, then commit artifacts and archive directly.
327
328
  - Before editing -> `trellis-before-dev`; after editing -> `trellis-check`.
328
329
  - Repeated debugging -> `trellis-break-loop`; spec updates -> `trellis-update-spec`.
329
330
 
330
- [/codex-inline, Kilo, Antigravity, Devin, DeepSeek Harness]
331
+ [/codex-inline, Kilo, Antigravity, Devin]
331
332
 
332
333
  ### Guardrails
333
334
 
@@ -349,7 +350,7 @@ python3 ./.trellis/scripts/get_context.py --mode phase --step <step>
349
350
 
350
351
  ## Phase 1: Plan
351
352
 
352
- Goal: classify the request, get task-creation consent when a task is needed, and produce the planning artifacts required before implementation.
353
+ Goal: classify the request, perform only eligible direct small work without a task, and create planning artifacts when a task is needed.
353
354
 
354
355
  #### 1.0 Create task `[required · once]`
355
356
 
@@ -399,21 +400,22 @@ Return to this step whenever requirements change and revise the relevant artifac
399
400
 
400
401
  Research can happen at any time during requirement exploration. It isn't limited to local code — you can use any available tool (MCP servers, skills, web search, etc.) to look up external information, including third-party library docs, industry practices, API references, etc.
401
402
 
402
- [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code]
403
+ [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code, DeepSeek Harness]
403
404
 
404
405
  Spawn the research sub-agent:
405
406
 
406
407
  - **Agent type**: `trellis-research`
407
408
  - **Task description**: Research <specific question>
408
409
  - **Key requirement**: Research output MUST be persisted to `{TASK_DIR}/research/`
410
+ - **DeepSeek Harness**: tell the child to load `trellis-agent-research` exactly once. If `trellis_wait` is available, use the default continuable background mode, dispatch independent questions concurrently when useful, continue unrelated work, then call `trellis_wait` once per child id and consume each settlement notice before advancing. Without `trellis_wait`, dispatch each required child with `run_in_background: false`; do not poll or sleep.
409
411
 
410
- [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code]
412
+ [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code, DeepSeek Harness]
411
413
 
412
- [codex-inline, Kilo, Antigravity, Devin, DeepSeek Harness]
414
+ [codex-inline, Kilo, Antigravity, Devin]
413
415
 
414
416
  Do the research in the main session directly and write findings into `{TASK_DIR}/research/`. `codex-inline` is the explicit mode that keeps work in the main session.
415
417
 
416
- [/codex-inline, Kilo, Antigravity, Devin, DeepSeek Harness]
418
+ [/codex-inline, Kilo, Antigravity, Devin]
417
419
 
418
420
  **Research artifact conventions**:
419
421
  - One file per research topic (e.g. `research/auth-library-comparison.md`)
@@ -428,7 +430,7 @@ Brainstorm and research can interleave freely — pause to research a technical
428
430
 
429
431
  Eligible analysis-only tasks skip this step because they never enter Phase 2 or dispatch implementation/check agents.
430
432
 
431
- [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code]
433
+ [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code, DeepSeek Harness]
432
434
 
433
435
  Curate `implement.jsonl` and `check.jsonl` so the Phase 2 sub-agents get the right spec/research context. These files were seeded on `task create` with a single self-describing `_example` line; your job here is to fill in real entries.
434
436
 
@@ -473,13 +475,13 @@ Ready gate: both `implement.jsonl` and `check.jsonl` must contain at least one r
473
475
 
474
476
  Skip this step only when both files already have real curated entries.
475
477
 
476
- [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code]
478
+ [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code, DeepSeek Harness]
477
479
 
478
- [codex-inline, Kilo, Antigravity, Devin, DeepSeek Harness]
480
+ [codex-inline, Kilo, Antigravity, Devin]
479
481
 
480
482
  Skip this step. Context is loaded directly by the `trellis-before-dev` skill in Phase 2.
481
483
 
482
- [/codex-inline, Kilo, Antigravity, Devin, DeepSeek Harness]
484
+ [/codex-inline, Kilo, Antigravity, Devin]
483
485
 
484
486
  #### 1.4 Activate task `[required · once]`
485
487
 
@@ -509,11 +511,11 @@ If `task.py start` errors with a session-identity message (no context key from h
509
511
  | `design.md` exists (complex tasks) | ✅ |
510
512
  | `implement.md` exists (complex tasks) | ✅ |
511
513
 
512
- [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code]
514
+ [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code, DeepSeek Harness]
513
515
 
514
516
  | Change-bearing task: `implement.jsonl` and `check.jsonl` each contain at least one real curated entry (seed row does not count) | ✅ |
515
517
 
516
- [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code]
518
+ [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code, DeepSeek Harness]
517
519
 
518
520
  ---
519
521
 
@@ -538,19 +540,20 @@ The platform hook/plugin auto-handles:
538
540
 
539
541
  [/Claude Code, Cursor, OpenCode, codex-sub-agent, CodeBuddy, Droid, Pi, ZCode, Snow, Oh My Pi]
540
542
 
541
- [Gemini, Qoder, Copilot, Reasonix, Trae, Grok, Kimi Code]
543
+ [Gemini, Qoder, Copilot, Reasonix, Trae, Grok, Kimi Code, DeepSeek Harness]
542
544
 
543
545
  Spawn the implement sub-agent:
544
546
 
545
547
  - **Agent type**: `trellis-implement`
546
548
  - **Task description**: Implement the reviewed task artifacts, consulting materials under `{TASK_DIR}/research/`; finish by running project lint and type-check
547
549
  - **Dispatch prompt guard**: The prompt MUST start with `Active task: <task path>`, then explicitly say the spawned agent is already `trellis-implement` and must implement directly without spawning another `trellis-implement` / `trellis-check`.
550
+ - **DeepSeek Harness**: tell the child to load `trellis-agent-implement` exactly once. If `trellis_wait` is available, use the default background mode, continue independent work, then wait once for that child id and consume its successful native settlement notice before Phase 2.2. Without `trellis_wait`, dispatch that child with `run_in_background: false`. Do not poll or sleep.
548
551
 
549
552
  The pull-based sub-agent definition auto-handles the context load requirement:
550
553
  - Resolves the active task with `task.py current --source`, then reads `prd.md`, `design.md` if present, and `implement.md` if present
551
554
  - Reads `implement.jsonl` and requires the agent to load each referenced spec/research file before coding
552
555
 
553
- [/Gemini, Qoder, Copilot, Reasonix, Trae, Grok, Kimi Code]
556
+ [/Gemini, Qoder, Copilot, Reasonix, Trae, Grok, Kimi Code, DeepSeek Harness]
554
557
 
555
558
  [Kiro]
556
559
 
@@ -566,7 +569,7 @@ The platform prelude auto-handles the context load requirement:
566
569
 
567
570
  [/Kiro]
568
571
 
569
- [codex-inline, Kilo, Antigravity, Devin, DeepSeek Harness]
572
+ [codex-inline, Kilo, Antigravity, Devin]
570
573
 
571
574
  1. Load the `trellis-before-dev` skill to read project guidelines
572
575
  2. Read `{TASK_DIR}/prd.md`, then `design.md` if present, then `implement.md` if present
@@ -574,27 +577,29 @@ The platform prelude auto-handles the context load requirement:
574
577
  4. Implement the code per reviewed artifacts
575
578
  5. Run project lint and type-check
576
579
 
577
- [/codex-inline, Kilo, Antigravity, Devin, DeepSeek Harness]
580
+ [/codex-inline, Kilo, Antigravity, Devin]
578
581
 
579
582
  #### 2.2 Quality check `[required · repeatable]`
580
583
 
581
- [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code]
584
+ [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code, DeepSeek Harness]
582
585
 
583
586
  Spawn the check sub-agent:
584
587
 
585
588
  - **Agent type**: `trellis-check`
586
589
  - **Task description**: Review all code changes against specs and task artifacts; fix any findings directly; ensure lint and type-check pass
587
590
  - **Dispatch prompt guard**: The prompt MUST start with `Active task: <task path>`, then tell the spawned agent it is already the `trellis-check` sub-agent and must review/fix directly, not spawn another `trellis-check` / `trellis-implement`.
591
+ - **DeepSeek Harness**: tell the child to load `trellis-agent-check` exactly once. If `trellis_wait` is available, use the default background mode, continue independent work, then wait once for that child id and consume its successful native settlement notice before Phase 3. Without `trellis_wait`, dispatch that child with `run_in_background: false`. Do not poll or sleep.
588
592
 
589
593
  The check agent's job:
590
594
  - Review code changes against specs
591
595
  - Review code changes against `prd.md`, `design.md` if present, and `implement.md` if present
592
596
  - Auto-fix issues it finds
593
597
  - Run lint and typecheck to verify
598
+ - A required check that cannot run, is skipped, or exits non-zero is blocked/failed, never passed. Do not weaken or rewrite acceptance criteria to advance the workflow.
594
599
 
595
- [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code]
600
+ [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code, DeepSeek Harness]
596
601
 
597
- [codex-inline, Kilo, Antigravity, Devin, DeepSeek Harness]
602
+ [codex-inline, Kilo, Antigravity, Devin]
598
603
 
599
604
  Load the `trellis-check` skill and verify the code per its guidance:
600
605
  - Spec compliance
@@ -603,7 +608,7 @@ Load the `trellis-check` skill and verify the code per its guidance:
603
608
 
604
609
  If issues are found → fix → re-check, until green.
605
610
 
606
- [/codex-inline, Kilo, Antigravity, Devin, DeepSeek Harness]
611
+ [/codex-inline, Kilo, Antigravity, Devin]
607
612
 
608
613
  **Final pass (before Phase 3.4 commit)**: the last 2.2 of a task must run full-scope, not just on the latest implement chunk. List all affected packages with `python3 ./.trellis/scripts/get_context.py --mode packages`, then load each package's spec index Quality Check section. This catches cross-layer / multi-package issues a mid-iteration local 2.2 cannot.
609
614
 
@@ -704,7 +709,7 @@ This section is for developers who want to modify the Trellis workflow itself. A
704
709
  ### Changing what a step means
705
710
 
706
711
  Edit the corresponding step's walkthrough body in the Phase 1 / 2 / 3 sections above. Critical invariants:
707
- - No active task must triage first and ask for task-creation consent before creating a Trellis task.
712
+ - No active task must triage first; direct small work may proceed only when bounded, single-surface, and immediately verifiable, otherwise create a Trellis task first.
708
713
  - Planning must distinguish lightweight PRD-only tasks from complex tasks that require `prd.md`, `design.md`, and `implement.md` before start.
709
714
  - Every required execution path must keep the Phase 3.4 commit reminder reachable before `/trellis:finish-work`.
710
715
 
@@ -1 +1 @@
1
- {"version":3,"file":"ai-tools.d.ts","sourceRoot":"","sources":["../../src/types/ai-tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ai-tools.d.ts","sourceRoot":"","sources":["../../src/types/ai-tools.ts"],"names":[],"mappings":"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"}
@@ -241,15 +241,30 @@ export const AI_TOOLS = {
241
241
  cliFlag: "droid",
242
242
  },
243
243
  },
244
+ /**
245
+ * DeepSeek Harness (dsh) — class-2 pull-based platform.
246
+ *
247
+ * DSH discovers skills from `<projectRoot>/.agents/skills/` (shared root,
248
+ * rank 200) and `<projectRoot>/.dsh/skills/` (DSH-private root, rank 100),
249
+ * plus user roots under `$DSH_HOME/skills` / `$DSH_AGENTS_HOME/skills`.
250
+ * SKILL.md frontmatter uses `name` (kebab-case) + `description`, matching
251
+ * Trellis's skill rendering. The model loads skills via the `skill` tool;
252
+ * users can load entry points by their `trellis-<name>` skill names. DSH
253
+ * surfaces that expose the slash pipeline may also accept `/trellis-<name>`.
254
+ *
255
+ * DSH injects project `AGENTS.md` at session start (workspace instructions)
256
+ * and supports isolated sub-agents through the `subagent` tool, so Trellis
257
+ * ships as class-2: workflow/bundled skills go to the shared `.agents/skills/`
258
+ * root via the neutral resolver (byte-identical to Codex/Gemini/Pi/Kimi
259
+ * writes), while DSH-private entry points (trellis-start / trellis-continue /
260
+ * trellis-finish-work) and collision-free role skills
261
+ * (trellis-agent-implement / trellis-agent-check / trellis-agent-research)
262
+ * live under `.dsh/skills/` with the pull-based prelude on implement/check.
263
+ *
264
+ * DSH has no project-level hooks/settings file Trellis may write, so
265
+ * hasHooks/hasPythonHooks stay false and no hook assets are emitted.
266
+ */
244
267
  dsh: {
245
- // DeepSeek Harness (dsh) is a skills-first pull-based host: it reads
246
- // `.agents/skills/` (agentskills.io, rank-200 project root) and its own
247
- // `.dsh/skills/` (rank-100 project root) natively and the agent loads
248
- // skills by name through its skill-loader tool. No session-start hook
249
- // ships in the default web/headless profiles, so `hasHooks: false` and
250
- // `trellis-start` stays as a user-invocable skill. Entry skills reference
251
- // other skills by bare name (`trellis-<name>`), hence `cmdRefPrefix:
252
- // "trellis-"`.
253
268
  name: "DeepSeek Harness (dsh)",
254
269
  templateDirs: ["common", "dsh"],
255
270
  configDir: ".dsh",
@@ -411,11 +426,9 @@ export const AI_TOOLS = {
411
426
  * `.kimi-code/skills/`.
412
427
  *
413
428
  * Kimi has no project-level hooks/settings file Trellis may write (hooks are
414
- * user-level `~/.kimi-code/config.toml` only), so the Trellis agent prompts
415
- * keep the pull-based prelude. They ship both as skills and as project-level
416
- * custom sub-agent definitions under `.kimi-code/agents/` (Claude
417
- * Code-compatible frontmatter), so the main session can dispatch
418
- * `trellis-<name>` sub-agents directly.
429
+ * user-level `~/.kimi-code/config.toml` only) and no project-level custom
430
+ * sub-agent definitions (only the built-in coder/explore/plan sub-agents), so
431
+ * the Trellis agent prompts ship as skills with the pull-based prelude.
419
432
  */
420
433
  kimi: {
421
434
  name: "Kimi Code",