@mindfoldhq/trellis 0.6.0-beta.2 → 0.6.0-beta.20
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.
- package/README.md +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +58 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/channel/adapters/claude.d.ts +29 -0
- package/dist/commands/channel/adapters/claude.d.ts.map +1 -0
- package/dist/commands/channel/adapters/claude.js +203 -0
- package/dist/commands/channel/adapters/claude.js.map +1 -0
- package/dist/commands/channel/adapters/codex.d.ts +85 -0
- package/dist/commands/channel/adapters/codex.d.ts.map +1 -0
- package/dist/commands/channel/adapters/codex.js +505 -0
- package/dist/commands/channel/adapters/codex.js.map +1 -0
- package/dist/commands/channel/adapters/index.d.ts +84 -0
- package/dist/commands/channel/adapters/index.d.ts.map +1 -0
- package/dist/commands/channel/adapters/index.js +115 -0
- package/dist/commands/channel/adapters/index.js.map +1 -0
- package/dist/commands/channel/adapters/types.d.ts +33 -0
- package/dist/commands/channel/adapters/types.d.ts.map +1 -0
- package/dist/commands/channel/adapters/types.js +2 -0
- package/dist/commands/channel/adapters/types.js.map +1 -0
- package/dist/commands/channel/agent-loader.d.ts +32 -0
- package/dist/commands/channel/agent-loader.d.ts.map +1 -0
- package/dist/commands/channel/agent-loader.js +154 -0
- package/dist/commands/channel/agent-loader.js.map +1 -0
- package/dist/commands/channel/context-loader.d.ts +26 -0
- package/dist/commands/channel/context-loader.d.ts.map +1 -0
- package/dist/commands/channel/context-loader.js +290 -0
- package/dist/commands/channel/context-loader.js.map +1 -0
- package/dist/commands/channel/context.d.ts +16 -0
- package/dist/commands/channel/context.d.ts.map +1 -0
- package/dist/commands/channel/context.js +83 -0
- package/dist/commands/channel/context.js.map +1 -0
- package/dist/commands/channel/create.d.ts +27 -0
- package/dist/commands/channel/create.d.ts.map +1 -0
- package/dist/commands/channel/create.js +39 -0
- package/dist/commands/channel/create.js.map +1 -0
- package/dist/commands/channel/dev-parse-trace.d.ts +14 -0
- package/dist/commands/channel/dev-parse-trace.d.ts.map +1 -0
- package/dist/commands/channel/dev-parse-trace.js +70 -0
- package/dist/commands/channel/dev-parse-trace.js.map +1 -0
- package/dist/commands/channel/guard.d.ts +150 -0
- package/dist/commands/channel/guard.d.ts.map +1 -0
- package/dist/commands/channel/guard.js +474 -0
- package/dist/commands/channel/guard.js.map +1 -0
- package/dist/commands/channel/index.d.ts +3 -0
- package/dist/commands/channel/index.d.ts.map +1 -0
- package/dist/commands/channel/index.js +531 -0
- package/dist/commands/channel/index.js.map +1 -0
- package/dist/commands/channel/interrupt.d.ts +10 -0
- package/dist/commands/channel/interrupt.d.ts.map +1 -0
- package/dist/commands/channel/interrupt.js +22 -0
- package/dist/commands/channel/interrupt.js.map +1 -0
- package/dist/commands/channel/kill.d.ts +7 -0
- package/dist/commands/channel/kill.d.ts.map +1 -0
- package/dist/commands/channel/kill.js +121 -0
- package/dist/commands/channel/kill.js.map +1 -0
- package/dist/commands/channel/list.d.ts +17 -0
- package/dist/commands/channel/list.d.ts.map +1 -0
- package/dist/commands/channel/list.js +233 -0
- package/dist/commands/channel/list.js.map +1 -0
- package/dist/commands/channel/messages.d.ts +15 -0
- package/dist/commands/channel/messages.d.ts.map +1 -0
- package/dist/commands/channel/messages.js +245 -0
- package/dist/commands/channel/messages.js.map +1 -0
- package/dist/commands/channel/rm.d.ts +27 -0
- package/dist/commands/channel/rm.d.ts.map +1 -0
- package/dist/commands/channel/rm.js +216 -0
- package/dist/commands/channel/rm.js.map +1 -0
- package/dist/commands/channel/run.d.ts +30 -0
- package/dist/commands/channel/run.d.ts.map +1 -0
- package/dist/commands/channel/run.js +130 -0
- package/dist/commands/channel/run.js.map +1 -0
- package/dist/commands/channel/send.d.ts +11 -0
- package/dist/commands/channel/send.d.ts.map +1 -0
- package/dist/commands/channel/send.js +24 -0
- package/dist/commands/channel/send.js.map +1 -0
- package/dist/commands/channel/spawn.d.ts +40 -0
- package/dist/commands/channel/spawn.d.ts.map +1 -0
- package/dist/commands/channel/spawn.js +244 -0
- package/dist/commands/channel/spawn.js.map +1 -0
- package/dist/commands/channel/store/events.d.ts +39 -0
- package/dist/commands/channel/store/events.d.ts.map +1 -0
- package/dist/commands/channel/store/events.js +87 -0
- package/dist/commands/channel/store/events.js.map +1 -0
- package/dist/commands/channel/store/filter.d.ts +3 -0
- package/dist/commands/channel/store/filter.d.ts.map +1 -0
- package/dist/commands/channel/store/filter.js +2 -0
- package/dist/commands/channel/store/filter.js.map +1 -0
- package/dist/commands/channel/store/lock.d.ts +23 -0
- package/dist/commands/channel/store/lock.d.ts.map +1 -0
- package/dist/commands/channel/store/lock.js +99 -0
- package/dist/commands/channel/store/lock.js.map +1 -0
- package/dist/commands/channel/store/paths.d.ts +63 -0
- package/dist/commands/channel/store/paths.d.ts.map +1 -0
- package/dist/commands/channel/store/paths.js +246 -0
- package/dist/commands/channel/store/paths.js.map +1 -0
- package/dist/commands/channel/store/schema.d.ts +27 -0
- package/dist/commands/channel/store/schema.d.ts.map +1 -0
- package/dist/commands/channel/store/schema.js +34 -0
- package/dist/commands/channel/store/schema.js.map +1 -0
- package/dist/commands/channel/store/thread-state.d.ts +5 -0
- package/dist/commands/channel/store/thread-state.d.ts.map +1 -0
- package/dist/commands/channel/store/thread-state.js +16 -0
- package/dist/commands/channel/store/thread-state.js.map +1 -0
- package/dist/commands/channel/store/watch.d.ts +19 -0
- package/dist/commands/channel/store/watch.d.ts.map +1 -0
- package/dist/commands/channel/store/watch.js +146 -0
- package/dist/commands/channel/store/watch.js.map +1 -0
- package/dist/commands/channel/supervisor/idle.d.ts +46 -0
- package/dist/commands/channel/supervisor/idle.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/idle.js +72 -0
- package/dist/commands/channel/supervisor/idle.js.map +1 -0
- package/dist/commands/channel/supervisor/inbox.d.ts +30 -0
- package/dist/commands/channel/supervisor/inbox.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/inbox.js +160 -0
- package/dist/commands/channel/supervisor/inbox.js.map +1 -0
- package/dist/commands/channel/supervisor/shutdown.d.ts +68 -0
- package/dist/commands/channel/supervisor/shutdown.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/shutdown.js +146 -0
- package/dist/commands/channel/supervisor/shutdown.js.map +1 -0
- package/dist/commands/channel/supervisor/stdout.d.ts +51 -0
- package/dist/commands/channel/supervisor/stdout.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/stdout.js +121 -0
- package/dist/commands/channel/supervisor/stdout.js.map +1 -0
- package/dist/commands/channel/supervisor/turns.d.ts +31 -0
- package/dist/commands/channel/supervisor/turns.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/turns.js +45 -0
- package/dist/commands/channel/supervisor/turns.js.map +1 -0
- package/dist/commands/channel/supervisor/warning.d.ts +48 -0
- package/dist/commands/channel/supervisor/warning.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/warning.js +77 -0
- package/dist/commands/channel/supervisor/warning.js.map +1 -0
- package/dist/commands/channel/supervisor.d.ts +59 -0
- package/dist/commands/channel/supervisor.d.ts.map +1 -0
- package/dist/commands/channel/supervisor.js +344 -0
- package/dist/commands/channel/supervisor.js.map +1 -0
- package/dist/commands/channel/text-body.d.ts +13 -0
- package/dist/commands/channel/text-body.d.ts.map +1 -0
- package/dist/commands/channel/text-body.js +47 -0
- package/dist/commands/channel/text-body.js.map +1 -0
- package/dist/commands/channel/threads.d.ts +39 -0
- package/dist/commands/channel/threads.d.ts.map +1 -0
- package/dist/commands/channel/threads.js +106 -0
- package/dist/commands/channel/threads.js.map +1 -0
- package/dist/commands/channel/title.d.ts +12 -0
- package/dist/commands/channel/title.d.ts.map +1 -0
- package/dist/commands/channel/title.js +24 -0
- package/dist/commands/channel/title.js.map +1 -0
- package/dist/commands/channel/wait.d.ts +17 -0
- package/dist/commands/channel/wait.d.ts.map +1 -0
- package/dist/commands/channel/wait.js +75 -0
- package/dist/commands/channel/wait.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +97 -42
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mem.d.ts +13 -117
- package/dist/commands/mem.d.ts.map +1 -1
- package/dist/commands/mem.js +168 -1074
- package/dist/commands/mem.js.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +28 -2
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +31 -111
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/upgrade.d.ts +28 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +84 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/workflow.d.ts +35 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +219 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/configurators/claude.d.ts.map +1 -1
- package/dist/configurators/claude.js +1 -0
- package/dist/configurators/claude.js.map +1 -1
- package/dist/configurators/codex.d.ts.map +1 -1
- package/dist/configurators/codex.js +5 -3
- package/dist/configurators/codex.js.map +1 -1
- package/dist/configurators/shared.js +4 -4
- package/dist/configurators/shared.js.map +1 -1
- package/dist/configurators/workflow.d.ts +8 -0
- package/dist/configurators/workflow.d.ts.map +1 -1
- package/dist/configurators/workflow.js +3 -2
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/migrations/manifests/0.5.10.json +9 -0
- package/dist/migrations/manifests/0.5.11.json +16 -0
- package/dist/migrations/manifests/0.5.12.json +9 -0
- package/dist/migrations/manifests/0.5.13.json +9 -0
- package/dist/migrations/manifests/0.5.14.json +9 -0
- package/dist/migrations/manifests/0.5.15.json +9 -0
- package/dist/migrations/manifests/0.5.16.json +9 -0
- package/dist/migrations/manifests/0.5.17.json +9 -0
- package/dist/migrations/manifests/0.5.18.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.15.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.17.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.18.json +16 -0
- package/dist/migrations/manifests/0.6.0-beta.19.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.20.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.5.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.6.json +16 -0
- package/dist/migrations/manifests/0.6.0-beta.7.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.8.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
- package/dist/templates/claude/agents/trellis-check.md +13 -7
- package/dist/templates/claude/agents/trellis-implement.md +8 -7
- package/dist/templates/claude/settings.json +4 -4
- package/dist/templates/codebuddy/agents/trellis-check.md +13 -7
- package/dist/templates/codebuddy/agents/trellis-implement.md +8 -7
- package/dist/templates/codebuddy/settings.json +4 -4
- package/dist/templates/codex/agents/trellis-check.toml +4 -4
- package/dist/templates/codex/agents/trellis-implement.toml +4 -4
- package/dist/templates/codex/config.toml +5 -3
- package/dist/templates/codex/hooks/session-start.py +205 -119
- package/dist/templates/codex/hooks.json +2 -2
- package/dist/templates/codex/skills/before-dev/SKILL.md +12 -6
- package/dist/templates/codex/skills/brainstorm/SKILL.md +69 -457
- package/dist/templates/codex/skills/check/SKILL.md +86 -18
- package/dist/templates/codex/skills/start/SKILL.md +33 -323
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +7 -4
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +3 -2
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +5 -5
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +35 -6
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +5 -4
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/SKILL.md +41 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/mcp-setup.md +90 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/repository-analysis.md +59 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-task-planning.md +61 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-writing.md +70 -0
- package/dist/templates/common/commands/continue.md +6 -5
- package/dist/templates/common/commands/start.md +9 -6
- package/dist/templates/common/skills/before-dev.md +12 -6
- package/dist/templates/common/skills/brainstorm.md +68 -504
- package/dist/templates/common/skills/check.md +7 -1
- package/dist/templates/copilot/hooks/session-start.py +219 -101
- package/dist/templates/copilot/hooks.json +2 -2
- package/dist/templates/copilot/prompts/before-dev.prompt.md +12 -6
- package/dist/templates/copilot/prompts/brainstorm.prompt.md +69 -457
- package/dist/templates/copilot/prompts/check.prompt.md +86 -18
- package/dist/templates/copilot/prompts/parallel.prompt.md +16 -8
- package/dist/templates/copilot/prompts/start.prompt.md +33 -367
- package/dist/templates/cursor/agents/trellis-check.md +13 -7
- package/dist/templates/cursor/agents/trellis-implement.md +8 -7
- package/dist/templates/cursor/hooks.json +1 -7
- package/dist/templates/droid/droids/trellis-check.md +13 -7
- package/dist/templates/droid/droids/trellis-implement.md +8 -7
- package/dist/templates/droid/settings.json +4 -4
- package/dist/templates/gemini/agents/trellis-check.md +11 -5
- package/dist/templates/gemini/agents/trellis-implement.md +7 -6
- package/dist/templates/gemini/settings.json +2 -2
- package/dist/templates/kiro/agents/trellis-check.json +1 -1
- package/dist/templates/kiro/agents/trellis-implement.json +1 -1
- package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +127 -9
- package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +171 -6
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +333 -43
- package/dist/templates/markdown/spec/guides/index.md.txt +18 -0
- package/dist/templates/opencode/agents/trellis-check.md +13 -7
- package/dist/templates/opencode/agents/trellis-implement.md +9 -8
- package/dist/templates/opencode/lib/session-utils.js +212 -123
- package/dist/templates/opencode/lib/trellis-context.js +73 -11
- package/dist/templates/opencode/plugins/inject-subagent-context.js +131 -29
- package/dist/templates/opencode/plugins/inject-workflow-state.js +9 -5
- package/dist/templates/opencode/plugins/session-start.js +9 -1
- package/dist/templates/pi/agents/trellis-check.md +5 -4
- package/dist/templates/pi/agents/trellis-implement.md +5 -4
- package/dist/templates/pi/extensions/trellis/index.ts.txt +1357 -754
- package/dist/templates/qoder/agents/trellis-check.md +11 -5
- package/dist/templates/qoder/agents/trellis-implement.md +7 -6
- package/dist/templates/qoder/settings.json +4 -4
- package/dist/templates/shared-hooks/index.d.ts.map +1 -1
- package/dist/templates/shared-hooks/index.js +0 -1
- package/dist/templates/shared-hooks/index.js.map +1 -1
- package/dist/templates/shared-hooks/inject-subagent-context.py +36 -14
- package/dist/templates/shared-hooks/inject-workflow-state.py +40 -42
- package/dist/templates/shared-hooks/session-start.py +222 -171
- package/dist/templates/trellis/config.yaml +38 -0
- package/dist/templates/trellis/index.d.ts +1 -0
- package/dist/templates/trellis/index.d.ts.map +1 -1
- package/dist/templates/trellis/index.js +2 -0
- package/dist/templates/trellis/index.js.map +1 -1
- package/dist/templates/trellis/scripts/add_session.py +50 -24
- package/dist/templates/trellis/scripts/common/config.py +57 -1
- package/dist/templates/trellis/scripts/common/safe_commit.py +285 -0
- package/dist/templates/trellis/scripts/common/session_context.py +384 -137
- package/dist/templates/trellis/scripts/common/task_context.py +3 -3
- package/dist/templates/trellis/scripts/common/task_store.py +161 -15
- package/dist/templates/trellis/scripts/common/workflow_phase.py +7 -10
- package/dist/templates/trellis/scripts/task.py +3 -3
- package/dist/templates/trellis/workflow.md +119 -98
- package/dist/utils/cwd-guard.d.ts +38 -0
- package/dist/utils/cwd-guard.d.ts.map +1 -0
- package/dist/utils/cwd-guard.js +62 -0
- package/dist/utils/cwd-guard.js.map +1 -0
- package/dist/utils/file-writer.d.ts +13 -0
- package/dist/utils/file-writer.d.ts.map +1 -1
- package/dist/utils/file-writer.js +59 -1
- package/dist/utils/file-writer.js.map +1 -1
- package/dist/utils/manifest-prune.d.ts +61 -0
- package/dist/utils/manifest-prune.d.ts.map +1 -0
- package/dist/utils/manifest-prune.js +136 -0
- package/dist/utils/manifest-prune.js.map +1 -0
- package/dist/utils/task-json.d.ts +9 -42
- package/dist/utils/task-json.d.ts.map +1 -1
- package/dist/utils/task-json.js +8 -45
- package/dist/utils/task-json.js.map +1 -1
- package/dist/utils/template-hash.d.ts +32 -6
- package/dist/utils/template-hash.d.ts.map +1 -1
- package/dist/utils/template-hash.js +53 -31
- package/dist/utils/template-hash.js.map +1 -1
- package/dist/utils/uninstall-scrubbers.d.ts +1 -0
- package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
- package/dist/utils/uninstall-scrubbers.js +21 -0
- package/dist/utils/uninstall-scrubbers.js.map +1 -1
- package/dist/utils/workflow-resolver.d.ts +86 -0
- package/dist/utils/workflow-resolver.d.ts.map +1 -0
- package/dist/utils/workflow-resolver.js +265 -0
- package/dist/utils/workflow-resolver.js.map +1 -0
- package/package.json +9 -8
|
@@ -1,17 +1,46 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
"""
|
|
4
|
-
Copilot Session Start Hook - Emit Trellis session-start
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
Copilot Session Start Hook - Emit Trellis session-start context.
|
|
5
|
+
|
|
6
|
+
Microsoft VS Code Agent hooks are in preview and have been documented since
|
|
7
|
+
VS Code 1.110 (February 2026). The official documentation
|
|
8
|
+
(https://code.visualstudio.com/docs/copilot/customization/hooks) defines
|
|
9
|
+
`SessionStart.hookSpecificOutput.additionalContext` as the field used to inject
|
|
10
|
+
additional context into the agent's conversation.
|
|
11
|
+
|
|
12
|
+
This script emits the spec-compliant SessionStart payload. Whether Copilot
|
|
13
|
+
actually consumes `additionalContext` depends on the user's installed VS Code
|
|
14
|
+
and Copilot versions, which is outside Trellis's control. UserPromptSubmit
|
|
15
|
+
breadcrumbs remain available as a per-turn complement.
|
|
11
16
|
"""
|
|
12
17
|
|
|
13
18
|
from __future__ import annotations
|
|
14
19
|
|
|
20
|
+
import sys
|
|
21
|
+
|
|
22
|
+
# Force UTF-8 on stdin/stdout/stderr on Windows. Default codepage there is
|
|
23
|
+
# cp936 / cp1252 / etc. — non-ASCII content (Chinese task names, prd snippets)
|
|
24
|
+
# both in stdin (hook payload from host CLI) and stdout (our emitted blocks)
|
|
25
|
+
# raises UnicodeDecodeError / UnicodeEncodeError. Equivalent to `python -X utf8`
|
|
26
|
+
# but applied per-stream so we don't depend on host CLI's command wiring.
|
|
27
|
+
if sys.platform.startswith("win"):
|
|
28
|
+
import io as _io
|
|
29
|
+
for _stream_name in ("stdin", "stdout", "stderr"):
|
|
30
|
+
_stream = getattr(sys, _stream_name, None)
|
|
31
|
+
if _stream is None:
|
|
32
|
+
continue
|
|
33
|
+
if hasattr(_stream, "reconfigure"):
|
|
34
|
+
try:
|
|
35
|
+
_stream.reconfigure(encoding="utf-8", errors="replace") # type: ignore[union-attr]
|
|
36
|
+
except Exception:
|
|
37
|
+
pass
|
|
38
|
+
elif hasattr(_stream, "detach"):
|
|
39
|
+
try:
|
|
40
|
+
setattr(sys, _stream_name, _io.TextIOWrapper(_stream.detach(), encoding="utf-8", errors="replace"))
|
|
41
|
+
except Exception:
|
|
42
|
+
pass
|
|
43
|
+
|
|
15
44
|
import json
|
|
16
45
|
import os
|
|
17
46
|
import re
|
|
@@ -199,12 +228,19 @@ def _resolve_task_dir(trellis_dir: Path, task_ref: str) -> Path:
|
|
|
199
228
|
def _get_task_status(trellis_dir: Path, hook_input: dict) -> str:
|
|
200
229
|
active = _resolve_active_task(trellis_dir, hook_input)
|
|
201
230
|
if not active.task_path:
|
|
202
|
-
return
|
|
231
|
+
return (
|
|
232
|
+
"Status: NO ACTIVE TASK\n"
|
|
233
|
+
"Next: Classify the current turn and ask for task-creation consent "
|
|
234
|
+
"before creating any Trellis task."
|
|
235
|
+
)
|
|
203
236
|
|
|
204
237
|
task_ref = active.task_path
|
|
205
238
|
task_dir = _resolve_task_dir(trellis_dir, task_ref)
|
|
206
239
|
if active.stale or not task_dir.is_dir():
|
|
207
|
-
return
|
|
240
|
+
return (
|
|
241
|
+
f"Status: STALE POINTER\nTask: {task_ref}\n"
|
|
242
|
+
"Next: Task directory not found. Run: python3 ./.trellis/scripts/task.py finish"
|
|
243
|
+
)
|
|
208
244
|
|
|
209
245
|
task_json_path = task_dir / "task.json"
|
|
210
246
|
task_data: dict = {}
|
|
@@ -218,36 +254,170 @@ def _get_task_status(trellis_dir: Path, hook_input: dict) -> str:
|
|
|
218
254
|
task_status = task_data.get("status", "unknown")
|
|
219
255
|
|
|
220
256
|
if task_status == "completed":
|
|
221
|
-
return
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if jsonl_path.is_file() and _has_curated_jsonl_entry(jsonl_path):
|
|
227
|
-
has_context = True
|
|
228
|
-
break
|
|
257
|
+
return (
|
|
258
|
+
f"Status: COMPLETED\nTask: {task_title}\n"
|
|
259
|
+
f"Next: Archive with `python3 ./.trellis/scripts/task.py archive {task_dir.name}` "
|
|
260
|
+
"or start a new task."
|
|
261
|
+
)
|
|
229
262
|
|
|
230
263
|
has_prd = (task_dir / "prd.md").is_file()
|
|
264
|
+
has_design = (task_dir / "design.md").is_file()
|
|
265
|
+
has_implement = (task_dir / "implement.md").is_file()
|
|
266
|
+
present = [
|
|
267
|
+
name
|
|
268
|
+
for name in ("prd.md", "design.md", "implement.md", "implement.jsonl", "check.jsonl")
|
|
269
|
+
if (task_dir / name).is_file()
|
|
270
|
+
]
|
|
271
|
+
present_line = ", ".join(present) if present else "none"
|
|
231
272
|
|
|
232
273
|
if not has_prd:
|
|
233
|
-
return
|
|
274
|
+
return (
|
|
275
|
+
f"Status: PLANNING\nTask: {task_title}\nPresent: {present_line}\n"
|
|
276
|
+
"Next: Load trellis-brainstorm and write prd.md. Stay in planning."
|
|
277
|
+
)
|
|
234
278
|
|
|
235
|
-
if
|
|
236
|
-
|
|
279
|
+
if task_status == "planning":
|
|
280
|
+
if has_design and has_implement:
|
|
281
|
+
next_action = "Review planning artifacts with the user before `task.py start`."
|
|
282
|
+
else:
|
|
283
|
+
next_action = (
|
|
284
|
+
"Lightweight task can ask for start review with PRD-only; "
|
|
285
|
+
"complex task must add design.md and implement.md before `task.py start`."
|
|
286
|
+
)
|
|
287
|
+
return (
|
|
288
|
+
f"Status: PLANNING\nTask: {task_title}\nPresent: {present_line}\n"
|
|
289
|
+
f"Next: {next_action}"
|
|
290
|
+
)
|
|
237
291
|
|
|
238
292
|
return (
|
|
239
|
-
f"Status:
|
|
240
|
-
|
|
241
|
-
"
|
|
242
|
-
"For agent-capable platforms, the default is to NOT edit code in the main session. "
|
|
243
|
-
"After implementation, dispatch `trellis-check` per Phase 2.2 before reporting completion.\n"
|
|
244
|
-
"User override (per-turn escape hatch): if the user's CURRENT message explicitly tells the "
|
|
245
|
-
"main session to handle it directly (\"你直接改\" / \"别派 sub-agent\" / \"main session 写就行\" / "
|
|
246
|
-
"\"do it inline\" / \"不用 sub-agent\"), honor it for this turn and edit code directly. "
|
|
247
|
-
"Per-turn only; do NOT invent an override the user did not say."
|
|
293
|
+
f"Status: {task_status.upper()}\nTask: {task_title}\nPresent: {present_line}\n"
|
|
294
|
+
"Next: Follow the matching per-turn workflow-state. Context order is jsonl entries, "
|
|
295
|
+
"prd.md, design.md if present, implement.md if present."
|
|
248
296
|
)
|
|
249
297
|
|
|
250
298
|
|
|
299
|
+
def _run_git(repo_root: Path, args: list[str]) -> str:
|
|
300
|
+
try:
|
|
301
|
+
result = subprocess.run(
|
|
302
|
+
["git", *args],
|
|
303
|
+
capture_output=True,
|
|
304
|
+
text=True,
|
|
305
|
+
encoding="utf-8",
|
|
306
|
+
errors="replace",
|
|
307
|
+
timeout=3,
|
|
308
|
+
cwd=str(repo_root),
|
|
309
|
+
)
|
|
310
|
+
except (subprocess.TimeoutExpired, FileNotFoundError, PermissionError):
|
|
311
|
+
return ""
|
|
312
|
+
if result.returncode != 0:
|
|
313
|
+
return ""
|
|
314
|
+
return result.stdout.strip()
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def _format_git_state(repo_root: Path) -> str:
|
|
318
|
+
branch = _run_git(repo_root, ["branch", "--show-current"]) or "(detached)"
|
|
319
|
+
dirty_lines = [
|
|
320
|
+
line for line in _run_git(repo_root, ["status", "--porcelain"]).splitlines()
|
|
321
|
+
if line.strip()
|
|
322
|
+
]
|
|
323
|
+
dirty_text = "clean" if not dirty_lines else f"dirty {len(dirty_lines)} paths"
|
|
324
|
+
return f"Git: branch {branch}; {dirty_text}."
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def _repo_relative(repo_root: Path, path: Path) -> str:
|
|
328
|
+
try:
|
|
329
|
+
return path.relative_to(repo_root).as_posix()
|
|
330
|
+
except ValueError:
|
|
331
|
+
return str(path)
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def _collect_spec_index_paths(trellis_dir: Path) -> list[str]:
|
|
335
|
+
paths: list[str] = []
|
|
336
|
+
guides_index = trellis_dir / "spec" / "guides" / "index.md"
|
|
337
|
+
if guides_index.is_file():
|
|
338
|
+
paths.append(".trellis/spec/guides/index.md")
|
|
339
|
+
|
|
340
|
+
spec_dir = trellis_dir / "spec"
|
|
341
|
+
if not spec_dir.is_dir():
|
|
342
|
+
return paths
|
|
343
|
+
|
|
344
|
+
for sub in sorted(spec_dir.iterdir()):
|
|
345
|
+
if not sub.is_dir() or sub.name.startswith(".") or sub.name == "guides":
|
|
346
|
+
continue
|
|
347
|
+
index_file = sub / "index.md"
|
|
348
|
+
if index_file.is_file():
|
|
349
|
+
paths.append(f".trellis/spec/{sub.name}/index.md")
|
|
350
|
+
continue
|
|
351
|
+
for nested in sorted(sub.iterdir()):
|
|
352
|
+
if not nested.is_dir():
|
|
353
|
+
continue
|
|
354
|
+
nested_index = nested / "index.md"
|
|
355
|
+
if nested_index.is_file():
|
|
356
|
+
paths.append(f".trellis/spec/{sub.name}/{nested.name}/index.md")
|
|
357
|
+
|
|
358
|
+
return paths
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def _build_compact_current_state(
|
|
362
|
+
trellis_dir: Path,
|
|
363
|
+
hook_input: dict,
|
|
364
|
+
spec_index_paths: list[str],
|
|
365
|
+
) -> str:
|
|
366
|
+
repo_root = trellis_dir.parent
|
|
367
|
+
lines: list[str] = []
|
|
368
|
+
|
|
369
|
+
try:
|
|
370
|
+
from common.paths import get_active_journal_file, get_developer, get_tasks_dir, count_lines # type: ignore[import-not-found]
|
|
371
|
+
from common.tasks import iter_active_tasks # type: ignore[import-not-found]
|
|
372
|
+
except Exception:
|
|
373
|
+
get_active_journal_file = None # type: ignore[assignment]
|
|
374
|
+
get_developer = None # type: ignore[assignment]
|
|
375
|
+
get_tasks_dir = None # type: ignore[assignment]
|
|
376
|
+
count_lines = None # type: ignore[assignment]
|
|
377
|
+
iter_active_tasks = None # type: ignore[assignment]
|
|
378
|
+
|
|
379
|
+
developer = get_developer(repo_root) if get_developer else None
|
|
380
|
+
lines.append(f"Developer: {developer or '(not initialized)'}")
|
|
381
|
+
lines.append(_format_git_state(repo_root))
|
|
382
|
+
|
|
383
|
+
active = _resolve_active_task(trellis_dir, hook_input)
|
|
384
|
+
if active.task_path:
|
|
385
|
+
task_dir = _resolve_task_dir(trellis_dir, active.task_path)
|
|
386
|
+
status = "unknown"
|
|
387
|
+
task_json = task_dir / "task.json"
|
|
388
|
+
if task_json.is_file():
|
|
389
|
+
try:
|
|
390
|
+
data = json.loads(task_json.read_text(encoding="utf-8"))
|
|
391
|
+
if isinstance(data, dict):
|
|
392
|
+
status = str(data.get("status") or "unknown")
|
|
393
|
+
except (json.JSONDecodeError, OSError):
|
|
394
|
+
pass
|
|
395
|
+
lines.append(f"Current task: {_repo_relative(repo_root, task_dir)}; status={status}.")
|
|
396
|
+
else:
|
|
397
|
+
lines.append("Current task: none.")
|
|
398
|
+
|
|
399
|
+
if get_tasks_dir and iter_active_tasks:
|
|
400
|
+
try:
|
|
401
|
+
task_count = sum(1 for _ in iter_active_tasks(get_tasks_dir(repo_root)))
|
|
402
|
+
lines.append(
|
|
403
|
+
f"Active tasks: {task_count} total. Use `python3 ./.trellis/scripts/task.py list --mine` only if needed."
|
|
404
|
+
)
|
|
405
|
+
except Exception:
|
|
406
|
+
pass
|
|
407
|
+
|
|
408
|
+
if get_active_journal_file and count_lines:
|
|
409
|
+
journal = get_active_journal_file(repo_root)
|
|
410
|
+
if journal:
|
|
411
|
+
lines.append(
|
|
412
|
+
f"Journal: {_repo_relative(repo_root, journal)}, {count_lines(journal)} / 2000 lines."
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
if spec_index_paths:
|
|
416
|
+
lines.append(f"Spec indexes: {len(spec_index_paths)} available.")
|
|
417
|
+
|
|
418
|
+
return "\n".join(lines)
|
|
419
|
+
|
|
420
|
+
|
|
251
421
|
def _extract_range(content: str, start_header: str, end_header: str) -> str:
|
|
252
422
|
"""Extract lines starting at `## start_header` up to (but excluding) `## end_header`."""
|
|
253
423
|
lines = content.splitlines()
|
|
@@ -275,32 +445,25 @@ _BREADCRUMB_TAG_RE = re.compile(
|
|
|
275
445
|
|
|
276
446
|
|
|
277
447
|
def _strip_breadcrumb_tag_blocks(content: str) -> str:
|
|
278
|
-
|
|
448
|
+
stripped = _BREADCRUMB_TAG_RE.sub("", content)
|
|
449
|
+
stripped = re.sub(r"<!--.*?-->", "", stripped, flags=re.DOTALL)
|
|
450
|
+
stripped = re.sub(r"^\[(?!/?workflow-state:)/?[^\]\n]+\]\s*\n?", "", stripped, flags=re.MULTILINE)
|
|
451
|
+
return re.sub(r"\n{3,}", "\n\n", stripped).strip()
|
|
279
452
|
|
|
280
453
|
|
|
281
454
|
def _build_workflow_toc(workflow_path: Path) -> str:
|
|
282
|
-
"""Inject
|
|
283
|
-
|
|
284
|
-
Since v0.5.0-rc.0 the [workflow-state:STATUS] breadcrumb tag blocks
|
|
285
|
-
live inside ## Phase Index. They're consumed by inject-workflow-state.py
|
|
286
|
-
on each UserPromptSubmit, so strip them from the session-start payload.
|
|
287
|
-
"""
|
|
455
|
+
"""Inject only the compact Phase Index summary for SessionStart."""
|
|
288
456
|
content = read_file(workflow_path)
|
|
289
457
|
if not content:
|
|
290
458
|
return "No workflow.md found"
|
|
291
459
|
|
|
292
460
|
out_lines = [
|
|
293
|
-
"# Development Workflow
|
|
294
|
-
"Full guide: .trellis/workflow.md
|
|
461
|
+
"# Development Workflow - Session Summary",
|
|
462
|
+
"Full guide: .trellis/workflow.md. Step detail: `python3 ./.trellis/scripts/get_context.py --mode phase --step <X.Y>`.",
|
|
295
463
|
"",
|
|
296
|
-
"## Table of Contents",
|
|
297
464
|
]
|
|
298
|
-
for line in content.splitlines():
|
|
299
|
-
if line.startswith("## "):
|
|
300
|
-
out_lines.append(line)
|
|
301
|
-
out_lines += ["", "---", ""]
|
|
302
465
|
|
|
303
|
-
phases = _extract_range(content, "Phase Index", "
|
|
466
|
+
phases = _extract_range(content, "Phase Index", "Phase 1: Plan")
|
|
304
467
|
if phases:
|
|
305
468
|
out_lines.append(_strip_breadcrumb_tag_blocks(phases).rstrip())
|
|
306
469
|
|
|
@@ -324,73 +487,34 @@ def main() -> None:
|
|
|
324
487
|
configure_project_encoding(project_dir)
|
|
325
488
|
|
|
326
489
|
trellis_dir = project_dir / ".trellis"
|
|
327
|
-
|
|
490
|
+
spec_index_paths = _collect_spec_index_paths(trellis_dir)
|
|
328
491
|
|
|
329
492
|
output = StringIO()
|
|
330
493
|
|
|
331
494
|
output.write("""<session-context>
|
|
332
|
-
|
|
333
|
-
Read and follow all instructions below carefully.
|
|
495
|
+
Trellis compact SessionStart context. Use it to orient the session; load details on demand.
|
|
334
496
|
</session-context>
|
|
335
497
|
|
|
336
498
|
""")
|
|
337
499
|
|
|
338
500
|
output.write("<current-state>\n")
|
|
339
|
-
|
|
340
|
-
output.write(run_script(context_script, context_key))
|
|
501
|
+
output.write(_build_compact_current_state(trellis_dir, hook_input, spec_index_paths))
|
|
341
502
|
output.write("\n</current-state>\n\n")
|
|
342
503
|
|
|
343
|
-
output.write("<workflow>\n")
|
|
504
|
+
output.write("<trellis-workflow>\n")
|
|
344
505
|
output.write(_build_workflow_toc(trellis_dir / "workflow.md"))
|
|
345
|
-
output.write("\n</workflow>\n\n")
|
|
506
|
+
output.write("\n</trellis-workflow>\n\n")
|
|
346
507
|
|
|
347
508
|
output.write("<guidelines>\n")
|
|
348
509
|
output.write(
|
|
349
|
-
"
|
|
350
|
-
"
|
|
351
|
-
"
|
|
352
|
-
"- If you're spawning an implement/check sub-agent, context is injected "
|
|
353
|
-
"automatically via `{task}/implement.jsonl` / `check.jsonl`. You do NOT "
|
|
354
|
-
"need to read these indexes yourself.\n"
|
|
355
|
-
"- For agent-capable platforms, the default is to dispatch "
|
|
356
|
-
"`trellis-implement` and `trellis-check` (so JSONL context is loaded by "
|
|
357
|
-
"the sub-agents) rather than editing code in the main session. "
|
|
358
|
-
"Honor a per-turn user override only if the user's current message "
|
|
359
|
-
"explicitly opts out (see <task-status> below for override phrases).\n\n"
|
|
510
|
+
"Task context order for implementation/check: jsonl entries -> `prd.md` -> "
|
|
511
|
+
"`design.md if present` -> `implement.md if present`. Missing optional artifacts "
|
|
512
|
+
"are skipped for lightweight tasks.\n\n"
|
|
360
513
|
)
|
|
361
514
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
output.write("## guides (inlined — cross-package thinking guides)\n")
|
|
366
|
-
output.write(read_file(guides_index))
|
|
367
|
-
output.write("\n\n")
|
|
368
|
-
|
|
369
|
-
# Other indexes — paths only
|
|
370
|
-
paths: list[str] = []
|
|
371
|
-
spec_dir = trellis_dir / "spec"
|
|
372
|
-
if spec_dir.is_dir():
|
|
373
|
-
for sub in sorted(spec_dir.iterdir()):
|
|
374
|
-
if not sub.is_dir() or sub.name.startswith("."):
|
|
375
|
-
continue
|
|
376
|
-
if sub.name == "guides":
|
|
377
|
-
continue
|
|
378
|
-
index_file = sub / "index.md"
|
|
379
|
-
if index_file.is_file():
|
|
380
|
-
paths.append(f".trellis/spec/{sub.name}/index.md")
|
|
381
|
-
else:
|
|
382
|
-
for nested in sorted(sub.iterdir()):
|
|
383
|
-
if not nested.is_dir():
|
|
384
|
-
continue
|
|
385
|
-
nested_index = nested / "index.md"
|
|
386
|
-
if nested_index.is_file():
|
|
387
|
-
paths.append(
|
|
388
|
-
f".trellis/spec/{sub.name}/{nested.name}/index.md"
|
|
389
|
-
)
|
|
390
|
-
|
|
391
|
-
if paths:
|
|
392
|
-
output.write("## Available spec indexes (read on demand)\n")
|
|
393
|
-
for p in paths:
|
|
515
|
+
if spec_index_paths:
|
|
516
|
+
output.write("## Available indexes (read on demand)\n")
|
|
517
|
+
for p in spec_index_paths:
|
|
394
518
|
output.write(f"- {p}\n")
|
|
395
519
|
output.write("\n")
|
|
396
520
|
|
|
@@ -404,18 +528,12 @@ Read and follow all instructions below carefully.
|
|
|
404
528
|
output.write(f"<task-status>\n{task_status}\n</task-status>\n\n")
|
|
405
529
|
|
|
406
530
|
output.write("""<ready>
|
|
407
|
-
Context loaded.
|
|
408
|
-
When the user sends the first message, follow <task-status> and the workflow guide.
|
|
409
|
-
If a task is READY, execute its Next required action without asking whether to continue.
|
|
531
|
+
Context loaded. Follow <task-status>. Load workflow/spec/task details only when needed.
|
|
410
532
|
</ready>""")
|
|
411
533
|
|
|
412
534
|
context = output.getvalue()
|
|
413
535
|
result = {
|
|
414
536
|
"suppressOutput": True,
|
|
415
|
-
"systemMessage": (
|
|
416
|
-
f"Trellis SessionStart diagnostics emitted ({len(context)} chars); "
|
|
417
|
-
"Copilot currently ignores sessionStart hook output."
|
|
418
|
-
),
|
|
419
537
|
"hookSpecificOutput": {
|
|
420
538
|
"hookEventName": "SessionStart",
|
|
421
539
|
"additionalContext": context,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
{
|
|
5
5
|
"type": "command",
|
|
6
6
|
"command": "{{PYTHON_CMD}} .github/copilot/hooks/session-start.py",
|
|
7
|
-
"timeout":
|
|
7
|
+
"timeout": 30
|
|
8
8
|
}
|
|
9
9
|
],
|
|
10
10
|
"userPromptSubmitted": [
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"type": "command",
|
|
13
13
|
"bash": "{{PYTHON_CMD}} .github/copilot/hooks/inject-workflow-state.py",
|
|
14
14
|
"powershell": "{{PYTHON_CMD}} .github/copilot/hooks/inject-workflow-state.py",
|
|
15
|
-
"timeoutSec":
|
|
15
|
+
"timeoutSec": 15
|
|
16
16
|
}
|
|
17
17
|
]
|
|
18
18
|
}
|
|
@@ -6,28 +6,34 @@ Read the relevant development guidelines before starting your task.
|
|
|
6
6
|
|
|
7
7
|
Execute these steps:
|
|
8
8
|
|
|
9
|
-
1. **
|
|
9
|
+
1. **Read current task artifacts**:
|
|
10
|
+
- `prd.md` for requirements and acceptance criteria
|
|
11
|
+
- `design.md` if present for technical design
|
|
12
|
+
- `implement.md` if present for execution order and validation plan
|
|
13
|
+
|
|
14
|
+
2. **Discover packages and their spec layers**:
|
|
10
15
|
```bash
|
|
11
16
|
python3 ./.trellis/scripts/get_context.py --mode packages
|
|
12
17
|
```
|
|
13
18
|
|
|
14
|
-
|
|
19
|
+
3. **Identify which specs apply** to your task based on:
|
|
15
20
|
- Which package you're modifying (e.g., `cli/`, `docs-site/`)
|
|
16
21
|
- What type of work (backend, frontend, unit-test, docs, etc.)
|
|
22
|
+
- Any spec/research paths referenced by the task artifacts
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
4. **Read the spec index** for each relevant module:
|
|
19
25
|
```bash
|
|
20
26
|
cat .trellis/spec/<package>/<layer>/index.md
|
|
21
27
|
```
|
|
22
28
|
Follow the **"Pre-Development Checklist"** section in the index.
|
|
23
29
|
|
|
24
|
-
|
|
30
|
+
5. **Read the specific guideline files** listed in the Pre-Development Checklist that are relevant to your task. The index is NOT the goal — it points you to the actual guideline files (e.g., `error-handling.md`, `conventions.md`, `mock-strategies.md`). Read those files to understand the coding standards and patterns.
|
|
25
31
|
|
|
26
|
-
|
|
32
|
+
6. **Always read shared guides**:
|
|
27
33
|
```bash
|
|
28
34
|
cat .trellis/spec/guides/index.md
|
|
29
35
|
```
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
7. Understand the coding standards and patterns you need to follow, then proceed with your development plan.
|
|
32
38
|
|
|
33
39
|
This step is **mandatory** before writing any code.
|