Skip to main content
Beta.15 updates task runtime state, platform session identity propagation, Pi Agent integration, and beta documentation. It also keeps the shared-hook cleanup manifest entries from the pending beta.15 release.

Behavior Changes

Session-scoped active task runtime

Active task state now uses a per-session runtime file:
.trellis/.runtime/sessions/<session-key>.json
.trellis/.current-task is no longer used as the active-task fallback.
CommandBehavior
task.py start <task>Writes the current task into the resolved session file
task.py current --sourceReads the current task from the resolved session file
task.py finishDeletes the resolved session file
task.py archive <task>Deletes session files that still point at the archived task before moving it
Session file shape:
{
  "platform": "session",
  "last_seen_at": "2026-04-27T01:43:24Z",
  "current_task": ".trellis/tasks/04-21-session-scoped-task-state",
  "current_run": null
}
task.py start exits with code 1 when no session identity is available:
Error: Cannot set active task without a session identity.
Hint: run inside an AI IDE/session that exposes session identity, or set TRELLIS_CONTEXT_ID before running task.py start.

Bootstrap and joiner tasks

trellis init still creates bootstrap and joiner task directories, but it no longer writes .trellis/.current-task. The generated PRDs now tell the AI to start the task from a session that exposes Trellis session identity.

Workflow task-creation policy

workflow.md and hook fallback breadcrumbs now use a softer task-creation policy.
AreaPrevious behaviorbeta.15 behavior
no_task trigger wordsTreat matching words as requiring task creationTreat matching words as task-creation signals
Simple turnsNo explicit exemptionTask not required when all three hold: zero file writes, one-reply answer, no research beyond reading 1-2 repo files
User opt-outNot documented in the hook promptCurrent-turn phrases such as skip trellis, no task, just do it, 跳过 trellis, 别走流程, 先别建任务 skip task creation for that turn
in_progress implementationMain session was told not to edit codeSub-agent dispatch remains the default; explicit current-turn requests such as do it inline, main session 写就行, 不用 sub-agent allow main-session implementation

Platform Integration

Shell session identity handling

Several hosts expose session identity differently. beta.15 adds host-specific handling for task.py start/current/finish.
PlatformChange
Claude Codesession-start.py writes TRELLIS_CONTEXT_ID through CLAUDE_ENV_FILE
Codextask.py resolves native command env such as CODEX_SESSION_ID and Codex Desktop CODEX_THREAD_ID
CursorbeforeShellExecution writes short-lived .trellis/.runtime/cursor-shell/*.json tickets for matching task.py commands
OpenCodeBash tool commands are prefixed with TRELLIS_CONTEXT_ID
PiBash tool calls and nested pi --mode json sub-agent runs receive TRELLIS_CONTEXT_ID
Other platforms use the same .trellis/.runtime/sessions/ storage, but beta.15 does not add new shell-command handling for them.
Platform groupbeta.15 status
GitHub CopilotThe platform-specific SessionStart hook resolves session identity for context injection. task.py can use exported COPILOT_* session env vars when the host provides them; otherwise use TRELLIS_CONTEXT_ID for manual shell starts.
Gemini CLI, Qoder, CodeBuddy, Droid, KiroShared hooks resolve session identity from hook input or platform env vars. No new shell-command bridge was added in beta.15. Manual shell starts still use TRELLIS_CONTEXT_ID when the host does not export a session id.
Kilo, Antigravity, WindsurfNo hook integration. Use their workflow/command files plus explicit TRELLIS_CONTEXT_ID when running task.py start manually.
.agents/skills consumersNo Trellis-managed hook layer. They use the .trellis/ core and whatever prelude or env injection the host provides.

Cursor sub-agent hook matching

Cursor hooks.json now matches both tool names:
{
  "matcher": "Task|Subagent"
}
inject-subagent-context.py also parses Cursor custom-agent payloads in these shapes:
{ "custom": { "name": "trellis-implement" } }
{ "type": { "case": "custom", "value": { "name": "trellis-implement" } } }

Pi Agent session runtime

Pi Agent now reads active task state from .trellis/.runtime/sessions/. Context key sources, in priority order:
SourceExample
Explicit envTRELLIS_CONTEXT_ID
Pi session managersessionManager.getSessionId()
Pi envPI_SESSION_ID, PI_SESSIONID
Transcript pathtranscript_path / transcriptPath
Process fallbackpi_process_<hash>
Nested Pi sub-agent runs receive the same TRELLIS_CONTEXT_ID.

Workflow-state override copy

workflow-state breadcrumbs now use exact Trellis agent names:
trellis-implement
trellis-check
trellis-research
The breadcrumbs also document explicit per-turn override phrases for skipping task creation or allowing main-session implementation.

Bug Fixes

OpenCode sub-agent name normalization

OpenCode now:
  • recognizes OPENCODE_RUN_ID as session identity
  • strips the trellis- prefix before matching sub-agent names
  • keeps implement.jsonl / check.jsonl injection working with renamed agents

Git-backed private registries

Template registry downloads now support private Git-backed registries. When a registry source requires local Git credentials, Trellis uses Git to read index.json and copy template directories instead of relying on anonymous raw HTTP. This applies to self-hosted GitLab / GitHub Enterprise sources and SSH registry URLs. Registry errors are classified separately for authentication failures, missing refs, missing paths, invalid index.json, and network failures, so trellis init --registry no longer misclassifies those cases as direct-download mode.

Shared-hook cleanup

writeSharedHooks and collectSharedHooks now use the same platform capability table:
SHARED_HOOKS_BY_PLATFORM
Claude Code statusLine is no longer installed by default. New installs do not write .claude/hooks/statusline.py or configure statusLine in .claude/settings.json. The manifest includes 11 hash-verified safe-file-delete entries for hooks that were written to projects but are now orphaned or disabled by default.
Removed pathReason
.claude/hooks/statusline.pyClaude Code statusLine is disabled by default
.cursor/hooks/statusline.pyCursor has no statusLine event
.codex/hooks/statusline.pyCodex has no statusLine event
.gemini/hooks/statusline.pyGemini has no statusLine event
.qoder/hooks/statusline.pyQoder has no statusLine event
.github/copilot/hooks/statusline.pyCopilot has no statusLine event
.codebuddy/hooks/statusline.pyCodeBuddy has no statusLine event
.factory/hooks/statusline.pyFactory Droid has no statusLine event
.kiro/hooks/statusline.pyKiro has no statusLine event
.kiro/hooks/session-start.pyKiro exposes only agentSpawn
.kiro/hooks/inject-workflow-state.pyKiro exposes only agentSpawn
Modified local files are preserved with a warning.

Docs

Beta task docs

Updated beta docs now describe:
  • current task state under .trellis/.runtime/sessions/<session-key>.json
  • session-scoped task ownership instead of a global project pointer
  • continue / finish-work as the primary user-facing task commands
  • task.py start as a session-bound operation
  • Cursor, Codex, Claude Code, OpenCode, and Pi hook/sub-agent behavior

Multi-agent docs

The beta multi-agent docs now describe native Git worktrees plus Trellis tasks. Removed references to Trellis-managed /trellis:parallel and worktree.yaml.

Upgrade

Existing projects:
trellis update
No --migrate gate is required for beta.15. Existing task directories and jsonl files remain valid. Existing .trellis/.current-task files are preserved but ignored by the new active-task resolver. Manual shell usage requires an explicit context id:
TRELLIS_CONTEXT_ID=my-session python3 .trellis/scripts/task.py start .trellis/tasks/<task>
Fresh install:
npm i -g @mindfoldhq/[email protected]