Browse Source

chore: update Trellis workflow

lingfengQAQ 2 weeks ago
parent
commit
54346c3a5f

+ 19 - 54
.trellis/.template-hashes.json

@@ -1,56 +1,12 @@
 {
 {
   "__version": 2,
   "__version": 2,
   "hashes": {
   "hashes": {
-    ".claude/agents/trellis-check.md": "d1359521f7f3e9bbbf10e856a3e0912c423581a88ac188b1f0523d6357962909",
-    ".claude/agents/trellis-implement.md": "61155f06ccdd26e5aeb8171face2a029a8fb77a3d1a2b277442ded186853446c",
-    ".claude/agents/trellis-research.md": "f82244b2a88a1f77b09813f58a7fdf506f8e9603a5c34b3abe6e170f73ab68a8",
-    ".claude/settings.json": "d13cd05659281a287d7f50c7e25eb6a89c2a6597773511bd6885538acced2855",
-    ".claude/hooks/inject-subagent-context.py": "3f2bafe1af36803aba1ad50947104aed817d77918540a4025db73aa0b249e3a2",
-    ".claude/hooks/inject-workflow-state.py": "fe4cca4db7ca8c252f614efca16fa588009a4238542a2c9aa85167409f6f9a4c",
-    ".claude/hooks/session-start.py": "b905a58b2232284883623bf38567c8170eec2ab60e3ddfb89040078eafdd3317",
-    ".claude/commands/trellis/continue.md": "0683093a150d189af02c5de33afe01ebb740e940f9325f7ba7390906895661a1",
-    ".claude/commands/trellis/finish-work.md": "d6aa570ab684f57e4845de2d84a1ff6d9f0908e04c5a56e14fd70ae739c369fc",
-    ".claude/skills/trellis-before-dev/SKILL.md": "208ad3fd5131fa0da603d4bc354a29826967397f5aeef483fa0564113df13e9e",
-    ".claude/skills/trellis-brainstorm/SKILL.md": "ca6c0586f5150e22be0bf4c0341b49dd2c6da363e62839aaa33996c79bad2b7d",
-    ".claude/skills/trellis-break-loop/SKILL.md": "35afb53fef42cd494e566f1ef170dbf442ec2be7e19931f28a14079b4dda753f",
-    ".claude/skills/trellis-check/SKILL.md": "a3f17aef687aa3b475d12ee64c3293e5491bb7474336be2c0f9ec22042f13b6e",
-    ".claude/skills/trellis-update-spec/SKILL.md": "d975db7af166578488958751ae2c56edb827a68bddb569aa27acc3453f64e610",
-    ".claude/skills/trellis-meta/references/customize-local/add-project-local-conventions.md": "86009ccb5d0373f399582da0bc570c4e5c6053c3c764857424ff93384f0e04e5",
-    ".claude/skills/trellis-meta/references/customize-local/change-agents.md": "7f2982162463f107f8b1a4fa1a41fee2bc7dbd0cc8e90c48559aba30c3ea403c",
-    ".claude/skills/trellis-meta/references/customize-local/change-context-loading.md": "c7be53e038eac99ff4d0abb3fafc67cfdfd90352744ce09ad11e7ef5085cf933",
-    ".claude/skills/trellis-meta/references/customize-local/change-hooks.md": "91892f2cff53ae003736007e95172945acabf48b2fc889bd627cd2406ce449c4",
-    ".claude/skills/trellis-meta/references/customize-local/change-skills-or-commands.md": "b3009ef20a4f24e5d8b196109dc9bab6bd30fc030dbc4fb796afdd2ca912e1ea",
-    ".claude/skills/trellis-meta/references/customize-local/change-spec-structure.md": "a3fc9da294448b4a3525ae1ab7c8c9b895ef8f3b53bcf37a13ce6afbdc040fe6",
-    ".claude/skills/trellis-meta/references/customize-local/change-task-lifecycle.md": "60ff9efb93604b87a461a4af30322d76750402a51e40f31531a7ff88d309996d",
-    ".claude/skills/trellis-meta/references/customize-local/change-workflow.md": "6f1707a2cc032c50e41e5624cef46071dd53dc9810bc6b3cae66d86508dea1cb",
-    ".claude/skills/trellis-meta/references/customize-local/overview.md": "1a406c24b4c5737cf517ead5ecb0846c20b0648a117008d3f5a47614fc1793ca",
-    ".claude/skills/trellis-meta/references/local-architecture/context-injection.md": "31286b9c05e600db7d179100eca533f9b8a4aab3a9c255cb69e8dccacb4e8375",
-    ".claude/skills/trellis-meta/references/local-architecture/generated-files.md": "4356517517cef0ba7f3ba01965a4ba8953505702e4085f0797d3e36817c9669f",
-    ".claude/skills/trellis-meta/references/local-architecture/overview.md": "45ffd4ee95020f58201adc885f3dfc89b26483c2b350d96ca7f2f57f94d5ff5f",
-    ".claude/skills/trellis-meta/references/local-architecture/spec-system.md": "8996504201e2a5460516948fe29c4ce7ed6b960f15da8c514855d2d467046985",
-    ".claude/skills/trellis-meta/references/local-architecture/task-system.md": "a6f905e53fe5a7fa5be8a4bbe1d102bd90b69c6e63a1a3be51ac3f7f164f1d21",
-    ".claude/skills/trellis-meta/references/local-architecture/workflow.md": "cfcdc6e4468a5d9c816e929fcca01640cd41cfdaaa4824118b40a8e460c927b6",
-    ".claude/skills/trellis-meta/references/local-architecture/workspace-memory.md": "e6427b46aba744563c2444b30df4043cd856561b7709ec2dece26095416421fd",
-    ".claude/skills/trellis-meta/references/platform-files/agents.md": "ffee78fc3c29114c7409ca4805ebd51d44d8a6acb630e9f73d47013e10db5ac5",
-    ".claude/skills/trellis-meta/references/platform-files/hooks-and-settings.md": "6e2d6d88719c2779fe34004f63d36cff203d8f64e7fb620f7cb1cde15c37c462",
-    ".claude/skills/trellis-meta/references/platform-files/overview.md": "6479cd2393166b4b369b511c44b78cbc64975c8b1df96ee1d4d1bd06b75cd48d",
-    ".claude/skills/trellis-meta/references/platform-files/platform-map.md": "ded6751c06f31d0a701d33c9dd69c482a583539ad3ed464aaad9e705f793b212",
-    ".claude/skills/trellis-meta/references/platform-files/skills-and-commands.md": "85435eb8bb6921283575bca51268fc534c22fd3ca33782e841ee5c76140ae48f",
-    ".claude/skills/trellis-meta/SKILL.md": "942e898a6fd769a93a3ca6f43f9fe0412d0adae011654fd384e9cacbd2af4f34",
-    ".claude/skills/trellis-spec-bootstarp/references/mcp-setup.md": "df542fc8f279edd38046d26a7c8151804b708f57b24d4aa2733cea587a88c65e",
-    ".claude/skills/trellis-spec-bootstarp/references/repository-analysis.md": "0dae98d774f6e34559b9f3442888ac43e3a8af110c37cbefc49ce256986858b6",
-    ".claude/skills/trellis-spec-bootstarp/references/spec-task-planning.md": "ef493d028c3b0807a8a534bb71fb92a68129f273db763ad27ceb464a522e799d",
-    ".claude/skills/trellis-spec-bootstarp/references/spec-writing.md": "e9800fe9ed4a4cd87062ea1829cf2caa8d170ec15e141678a6a30e74c497f47d",
-    ".claude/skills/trellis-spec-bootstarp/SKILL.md": "81f400092b21392161e7d9dfa9111c9be36c81bc8641d252ed28e08373449ac0",
-    "AGENTS.md": "6cacfe99748b435d0660c2463c697bc323d53798aecf3492283ca8eac1b29682",
     ".trellis/config.yaml": "5c9207418cecc390e9d86d589b4183b831f76697d92fb42fefd5221cd8772e51",
     ".trellis/config.yaml": "5c9207418cecc390e9d86d589b4183b831f76697d92fb42fefd5221cd8772e51",
-    ".trellis/scripts/__init__.py": "1242be5b972094c2e141aecbe81a4efd478f6534e3d5e28306374e6a18fcf46c",
-    ".trellis/scripts/add_session.py": "6e406a0a9f32d4a50b1b5ca8115cbd06c359011f0e166c41dc5fab34698a4006",
-    ".trellis/scripts/common/__init__.py": "3d5e9347141f0296319a5beb29d69ae714c5a474b9078caeb3edd7c5f6562e22",
+    ".trellis/scripts/add_session.py": "f26b66a539d160c739d4b88fd926b3d7f6745be326cd57131e5ef17a7b011fbe",
     ".trellis/scripts/common/active_task.py": "6c88ed40ef7289bca0f6d2ecba0f8b8aef46cd58788080fbeeea88de138a431f",
     ".trellis/scripts/common/active_task.py": "6c88ed40ef7289bca0f6d2ecba0f8b8aef46cd58788080fbeeea88de138a431f",
     ".trellis/scripts/common/cli_adapter.py": "cd844d1e84b1a09b373b3a7609e4d5606ee9d4825154c002cc9bb3f54c8e2fb9",
     ".trellis/scripts/common/cli_adapter.py": "cd844d1e84b1a09b373b3a7609e4d5606ee9d4825154c002cc9bb3f54c8e2fb9",
     ".trellis/scripts/common/config.py": "25c5a53ad20d6909be5209222e4208a84528805316a4d78350529459a364edb1",
     ".trellis/scripts/common/config.py": "25c5a53ad20d6909be5209222e4208a84528805316a4d78350529459a364edb1",
-    ".trellis/scripts/common/developer.py": "f5f833123abe68890171b4da825a324216d24913f6b5ad9245afc556424ffd7b",
+    ".trellis/scripts/common/developer.py": "b2141b0145a41f8cedb4f9a24c925796edb2f0f6fde7c86b559513ec30499368",
     ".trellis/scripts/common/git.py": "e14817be7de122d3a106f509c2825aeb9669d962ba73ba241642d2931cfdf1d6",
     ".trellis/scripts/common/git.py": "e14817be7de122d3a106f509c2825aeb9669d962ba73ba241642d2931cfdf1d6",
     ".trellis/scripts/common/git_context.py": "fa30ced454f1a91ffc9f8b2abeb32225e3447cbdc90bad783797374eba07265d",
     ".trellis/scripts/common/git_context.py": "fa30ced454f1a91ffc9f8b2abeb32225e3447cbdc90bad783797374eba07265d",
     ".trellis/scripts/common/io.py": "6480b181f2bc505323b28ed7a66963d7b7edc96251e83b4c8e7a45907cc721c8",
     ".trellis/scripts/common/io.py": "6480b181f2bc505323b28ed7a66963d7b7edc96251e83b4c8e7a45907cc721c8",
@@ -58,20 +14,29 @@
     ".trellis/scripts/common/packages_context.py": "efe158d7c99c2268851d0216fbb08de22836e418a8dbeb73575b8cc249eed7b7",
     ".trellis/scripts/common/packages_context.py": "efe158d7c99c2268851d0216fbb08de22836e418a8dbeb73575b8cc249eed7b7",
     ".trellis/scripts/common/paths.py": "05898ef136cc7c4d861b05fbf2b16d53ddd3e6f311a231d4fcfcb81bde7c45ee",
     ".trellis/scripts/common/paths.py": "05898ef136cc7c4d861b05fbf2b16d53ddd3e6f311a231d4fcfcb81bde7c45ee",
     ".trellis/scripts/common/safe_commit.py": "8789bff4b30a9065469210f2efab3f59f03dddd77bef4e4b6a5bb641f93539f4",
     ".trellis/scripts/common/safe_commit.py": "8789bff4b30a9065469210f2efab3f59f03dddd77bef4e4b6a5bb641f93539f4",
-    ".trellis/scripts/common/session_context.py": "c91cf213025e5e4ad2f56bb6f570ef43d35430fc8a863be311d3e5f8f32ef652",
+    ".trellis/scripts/common/session_context.py": "d669b96fd7a608808695b9e82e9bfd1693a9ae98ade03cc8dce6c24487696793",
+    ".trellis/scripts/common/tasks.py": "4436a8b0b53c270a35989e26d9dbd92669408c6562d88c02083a404562da85fe",
     ".trellis/scripts/common/task_context.py": "1c16a7fa82d363010d0d0ebdc038296ae1552bf6e90214787d707f49567bc159",
     ".trellis/scripts/common/task_context.py": "1c16a7fa82d363010d0d0ebdc038296ae1552bf6e90214787d707f49567bc159",
     ".trellis/scripts/common/task_queue.py": "0be61f713462b1fe4574927c82fc4704e678afe72dcb9813543aedf2f9e9e0c5",
     ".trellis/scripts/common/task_queue.py": "0be61f713462b1fe4574927c82fc4704e678afe72dcb9813543aedf2f9e9e0c5",
-    ".trellis/scripts/common/task_store.py": "cca4851c948df4a7d8dac38c465dce0d6b15a171001adab8dfef011ad66e02e5",
+    ".trellis/scripts/common/task_store.py": "4a6ad7f15fd6fdca0da174804ee2d750919d42e46066a891c7525aa8d8a2c592",
     ".trellis/scripts/common/task_utils.py": "f5ef4af87ba3e11d8b19630c0c96d009de1811fc9be56c2027a9c96e21ed103e",
     ".trellis/scripts/common/task_utils.py": "f5ef4af87ba3e11d8b19630c0c96d009de1811fc9be56c2027a9c96e21ed103e",
-    ".trellis/scripts/common/tasks.py": "4436a8b0b53c270a35989e26d9dbd92669408c6562d88c02083a404562da85fe",
     ".trellis/scripts/common/trellis_config.py": "0839dcf90ebbd77712c276930a89335b3313927051650c91d220fb51ca2a6a3c",
     ".trellis/scripts/common/trellis_config.py": "0839dcf90ebbd77712c276930a89335b3313927051650c91d220fb51ca2a6a3c",
     ".trellis/scripts/common/types.py": "9962081cc2608fb9d1deb32c6880e336f62cdca6b338e7ae813304701e155ee9",
     ".trellis/scripts/common/types.py": "9962081cc2608fb9d1deb32c6880e336f62cdca6b338e7ae813304701e155ee9",
     ".trellis/scripts/common/workflow_phase.py": "2b260f4a7770e9c3223129836716bd8e2c0f0568acd682224a57415bc1dc726b",
     ".trellis/scripts/common/workflow_phase.py": "2b260f4a7770e9c3223129836716bd8e2c0f0568acd682224a57415bc1dc726b",
-    ".trellis/scripts/get_context.py": "ca5bf9e90bdb1d75d3de182b95f820f9d108ab28793d29097b24fd71315adcf5",
+    ".trellis/scripts/common/__init__.py": "3d5e9347141f0296319a5beb29d69ae714c5a474b9078caeb3edd7c5f6562e22",
+    ".trellis/scripts/get_context.py": "af3ea7cd563a453227cf2cb4ab04d667390046b7febfac2217348d0892781f4b",
     ".trellis/scripts/get_developer.py": "84c27076323c3e0f2c9c8ed16e8aa865e225d902a187c37e20ee1a46e7142d8f",
     ".trellis/scripts/get_developer.py": "84c27076323c3e0f2c9c8ed16e8aa865e225d902a187c37e20ee1a46e7142d8f",
-    ".trellis/scripts/hooks/linear_sync.py": "e09cc4ce4699aada908808718698f33f705a3edf55c4dcf8f777ad892f80ca79",
-    ".trellis/scripts/init_developer.py": "f9e6c0d882406e81c8cd6b1c5abb204b0befc0069ff89cf650cd536a80f8c60e",
-    ".trellis/scripts/task.py": "40abdd46f5c2b6837610429a38eef50f1fc783fb1852dc4f52a891205e42ab04",
-    ".trellis/workflow.md": "f4b8a6f89017f62071986d6d36cc32c4c7f01fe6f023f0fd9311eddc57d8c94f"
+    ".trellis/scripts/hooks/linear_sync.py": "cfc270b7ff775caa5b2434823c45414a3b37f9ba2aa1e293a26daef9fd2e577a",
+    ".trellis/scripts/init_developer.py": "0943f1c240993649ab89b91a2c5b379e84daa8c53b35f0490774bff05a552873",
+    ".trellis/scripts/task.py": "e2614fbfc1308c90c0708a11475ca6684ea0a1e2a845140300192229589a2f1f",
+    ".trellis/scripts/__init__.py": "1242be5b972094c2e141aecbe81a4efd478f6534e3d5e28306374e6a18fcf46c",
+    ".trellis/workflow.md": "94810f640dcfe6fdaebcf6e9d0d6cec554610192c4f953b288029570ba8bc89d",
+    "AGENTS.md": "6cacfe99748b435d0660c2463c697bc323d53798aecf3492283ca8eac1b29682",
+    ".claude/skills/trellis-spec-bootstarp/references/mcp-setup.md": "df542fc8f279edd38046d26a7c8151804b708f57b24d4aa2733cea587a88c65e",
+    ".claude/skills/trellis-spec-bootstarp/references/repository-analysis.md": "0dae98d774f6e34559b9f3442888ac43e3a8af110c37cbefc49ce256986858b6",
+    ".claude/skills/trellis-spec-bootstarp/references/spec-task-planning.md": "ef493d028c3b0807a8a534bb71fb92a68129f273db763ad27ceb464a522e799d",
+    ".claude/skills/trellis-spec-bootstarp/references/spec-writing.md": "e9800fe9ed4a4cd87062ea1829cf2caa8d170ec15e141678a6a30e74c497f47d",
+    ".claude/skills/trellis-spec-bootstarp/SKILL.md": "81f400092b21392161e7d9dfa9111c9be36c81bc8641d252ed28e08373449ac0",
+    ".trellis/.gitignore": "3bc42434cbe61c937a1c26ea3c880b496bfad4e7d683750169e27ade509aa798"
   }
   }
 }
 }

+ 3 - 3
.trellis/scripts/add_session.py

@@ -4,11 +4,11 @@
 Add a new session to journal file and update index.md.
 Add a new session to journal file and update index.md.
 
 
 Usage:
 Usage:
-    python3 add_session.py --title "Title" --commit "hash" --summary "Summary" [--package cli]
-    python3 add_session.py --title "Title" --branch "feat/my-branch"
+    python add_session.py --title "Title" --commit "hash" --summary "Summary" [--package cli]
+    python add_session.py --title "Title" --branch "feat/my-branch"
 
 
     # Pipe detailed content via stdin (use --stdin to opt in):
     # Pipe detailed content via stdin (use --stdin to opt in):
-    cat << 'EOF' | python3 add_session.py --stdin --title "Title" --summary "Summary"
+    cat << 'EOF' | python add_session.py --stdin --title "Title" --summary "Summary"
     <session content here>
     <session content here>
     EOF
     EOF
 
 

+ 1 - 1
.trellis/scripts/common/developer.py

@@ -159,7 +159,7 @@ def ensure_developer(repo_root: Path | None = None) -> None:
 
 
     if not check_developer(repo_root):
     if not check_developer(repo_root):
         print("Error: Developer not initialized.", file=sys.stderr)
         print("Error: Developer not initialized.", file=sys.stderr)
-        print(f"Run: python3 ./{DIR_WORKFLOW}/scripts/init_developer.py <your-name>", file=sys.stderr)
+        print(f"Run: python ./{DIR_WORKFLOW}/scripts/init_developer.py <your-name>", file=sys.stderr)
         sys.exit(1)
         sys.exit(1)
 
 
 
 

+ 2 - 2
.trellis/scripts/common/session_context.py

@@ -528,7 +528,7 @@ def get_context_text(repo_root: Path | None = None) -> str:
     lines.append("## DEVELOPER")
     lines.append("## DEVELOPER")
     if not developer:
     if not developer:
         lines.append(
         lines.append(
-            f"ERROR: Not initialized. Run: python3 ./{DIR_WORKFLOW}/{DIR_SCRIPTS}/init_developer.py <name>"
+            f"ERROR: Not initialized. Run: python ./{DIR_WORKFLOW}/{DIR_SCRIPTS}/init_developer.py <name>"
         )
         )
         return "\n".join(lines)
         return "\n".join(lines)
 
 
@@ -747,7 +747,7 @@ def get_context_text_record(repo_root: Path | None = None) -> str:
     developer = get_developer(repo_root)
     developer = get_developer(repo_root)
     if not developer:
     if not developer:
         lines.append(
         lines.append(
-            f"ERROR: Not initialized. Run: python3 ./{DIR_WORKFLOW}/{DIR_SCRIPTS}/init_developer.py <name>"
+            f"ERROR: Not initialized. Run: python ./{DIR_WORKFLOW}/{DIR_SCRIPTS}/init_developer.py <name>"
         )
         )
         return "\n".join(lines)
         return "\n".join(lines)
 
 

+ 7 - 7
.trellis/scripts/common/task_store.py

@@ -133,7 +133,7 @@ _SUBAGENT_CONFIG_DIRS: tuple[str, ...] = (
 _SEED_EXAMPLE = (
 _SEED_EXAMPLE = (
     "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. "
     "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. "
     "Put spec/research files only — no code paths. "
     "Put spec/research files only — no code paths. "
-    "Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. "
+    "Run `python .trellis/scripts/get_context.py --mode packages` to list available specs. "
     "Delete this line once real entries are added."
     "Delete this line once real entries are added."
 )
 )
 
 
@@ -324,9 +324,9 @@ def cmd_create(args: argparse.Namespace) -> int:
             "see .trellis/workflow.md Phase 1.3)",
             "see .trellis/workflow.md Phase 1.3)",
             file=sys.stderr,
             file=sys.stderr,
         )
         )
-        print("  3. Run: python3 task.py start <dir>", file=sys.stderr)
+        print("  3. Run: python task.py start <dir>", file=sys.stderr)
     else:
     else:
-        print("  2. Run: python3 task.py start <dir>", file=sys.stderr)
+        print("  2. Run: python task.py start <dir>", file=sys.stderr)
     print("", file=sys.stderr)
     print("", file=sys.stderr)
 
 
     # Output relative path for script chaining
     # Output relative path for script chaining
@@ -612,7 +612,7 @@ def cmd_set_branch(args: argparse.Namespace) -> int:
 
 
     if not branch:
     if not branch:
         print(colored("Error: Missing arguments", Colors.RED))
         print(colored("Error: Missing arguments", Colors.RED))
-        print("Usage: python3 task.py set-branch <task-dir> <branch-name>")
+        print("Usage: python task.py set-branch <task-dir> <branch-name>")
         return 1
         return 1
 
 
     task_json = target_dir / FILE_TASK_JSON
     task_json = target_dir / FILE_TASK_JSON
@@ -643,8 +643,8 @@ def cmd_set_base_branch(args: argparse.Namespace) -> int:
 
 
     if not base_branch:
     if not base_branch:
         print(colored("Error: Missing arguments", Colors.RED))
         print(colored("Error: Missing arguments", Colors.RED))
-        print("Usage: python3 task.py set-base-branch <task-dir> <base-branch>")
-        print("Example: python3 task.py set-base-branch <dir> develop")
+        print("Usage: python task.py set-base-branch <task-dir> <base-branch>")
+        print("Example: python task.py set-base-branch <dir> develop")
         print()
         print()
         print("This sets the target branch for PR (the branch your feature will merge into).")
         print("This sets the target branch for PR (the branch your feature will merge into).")
         return 1
         return 1
@@ -678,7 +678,7 @@ def cmd_set_scope(args: argparse.Namespace) -> int:
 
 
     if not scope:
     if not scope:
         print(colored("Error: Missing arguments", Colors.RED))
         print(colored("Error: Missing arguments", Colors.RED))
-        print("Usage: python3 task.py set-scope <task-dir> <scope>")
+        print("Usage: python task.py set-scope <task-dir> <scope>")
         return 1
         return 1
 
 
     task_json = target_dir / FILE_TASK_JSON
     task_json = target_dir / FILE_TASK_JSON

+ 2 - 2
.trellis/scripts/get_context.py

@@ -3,8 +3,8 @@
 Get Session Context for AI Agent.
 Get Session Context for AI Agent.
 
 
 Usage:
 Usage:
-    python3 get_context.py           Output context in text format
-    python3 get_context.py --json    Output context in JSON format
+    python get_context.py           Output context in text format
+    python get_context.py --json    Output context in JSON format
 """
 """
 
 
 from __future__ import annotations
 from __future__ import annotations

+ 4 - 4
.trellis/scripts/hooks/linear_sync.py

@@ -4,12 +4,12 @@
 Syncs task events to Linear via the `linearis` CLI.
 Syncs task events to Linear via the `linearis` CLI.
 
 
 Usage (called automatically by task.py hooks):
 Usage (called automatically by task.py hooks):
-    python3 .trellis/scripts/hooks/linear_sync.py create
-    python3 .trellis/scripts/hooks/linear_sync.py start
-    python3 .trellis/scripts/hooks/linear_sync.py archive
+    python .trellis/scripts/hooks/linear_sync.py create
+    python .trellis/scripts/hooks/linear_sync.py start
+    python .trellis/scripts/hooks/linear_sync.py archive
 
 
 Manual usage:
 Manual usage:
-    TASK_JSON_PATH=.trellis/tasks/<name>/task.json python3 .trellis/scripts/hooks/linear_sync.py sync
+    TASK_JSON_PATH=.trellis/tasks/<name>/task.json python .trellis/scripts/hooks/linear_sync.py sync
 
 
 Environment:
 Environment:
     TASK_JSON_PATH  - Absolute path to task.json (set by task.py)
     TASK_JSON_PATH  - Absolute path to task.json (set by task.py)

+ 1 - 1
.trellis/scripts/init_developer.py

@@ -3,7 +3,7 @@
 Initialize developer for workflow.
 Initialize developer for workflow.
 
 
 Usage:
 Usage:
-    python3 init_developer.py <developer-name>
+    python init_developer.py <developer-name>
 
 
 This creates:
 This creates:
     - .trellis/.developer file with developer info
     - .trellis/.developer file with developer info

+ 47 - 47
.trellis/scripts/task.py

@@ -4,21 +4,21 @@
 Task Management Script.
 Task Management Script.
 
 
 Usage:
 Usage:
-    python3 task.py create "<title>" [--slug <name>] [--assignee <dev>] [--priority P0|P1|P2|P3] [--parent <dir>] [--package <pkg>]
-    python3 task.py add-context <dir> <file> <path> [reason] # Add jsonl entry
-    python3 task.py validate <dir>              # Validate jsonl files
-    python3 task.py list-context <dir>          # List jsonl entries
-    python3 task.py start <dir>                 # Set active task
-    python3 task.py current [--source]          # Show active task
-    python3 task.py finish                      # Clear active task
-    python3 task.py set-branch <dir> <branch>   # Set git branch
-    python3 task.py set-base-branch <dir> <branch>  # Set PR target branch
-    python3 task.py set-scope <dir> <scope>     # Set scope for PR title
-    python3 task.py archive <task-dir>          # Archive completed task
-    python3 task.py list                        # List active tasks
-    python3 task.py list-archive [month]        # List archived tasks
-    python3 task.py add-subtask <parent-dir> <child-dir>     # Link child to parent
-    python3 task.py remove-subtask <parent-dir> <child-dir>  # Unlink child from parent
+    python task.py create "<title>" [--slug <name>] [--assignee <dev>] [--priority P0|P1|P2|P3] [--parent <dir>] [--package <pkg>]
+    python task.py add-context <dir> <file> <path> [reason] # Add jsonl entry
+    python task.py validate <dir>              # Validate jsonl files
+    python task.py list-context <dir>          # List jsonl entries
+    python task.py start <dir>                 # Set active task
+    python task.py current [--source]          # Show active task
+    python task.py finish                      # Clear active task
+    python task.py set-branch <dir> <branch>   # Set git branch
+    python task.py set-base-branch <dir> <branch>  # Set PR target branch
+    python task.py set-scope <dir> <scope>     # Set scope for PR title
+    python task.py archive <task-dir>          # Archive completed task
+    python task.py list                        # List active tasks
+    python task.py list-archive [month]        # List archived tasks
+    python task.py add-subtask <parent-dir> <child-dir>     # Link child to parent
+    python task.py remove-subtask <parent-dir> <child-dir>  # Unlink child from parent
 """
 """
 
 
 from __future__ import annotations
 from __future__ import annotations
@@ -304,23 +304,23 @@ def show_usage() -> None:
     print("""Task Management Script
     print("""Task Management Script
 
 
 Usage:
 Usage:
-  python3 task.py create <title>                     Create new task directory
-  python3 task.py create <title> --package <pkg>     Create task for a specific package
-  python3 task.py create <title> --parent <dir>      Create task as child of parent
-  python3 task.py add-context <dir> <jsonl> <path> [reason]  Add entry to jsonl
-  python3 task.py validate <dir>                     Validate jsonl files
-  python3 task.py list-context <dir>                 List jsonl entries
-  python3 task.py start <dir>                        Set active task
-  python3 task.py current [--source]                 Show active task
-  python3 task.py finish                             Clear active task
-  python3 task.py set-branch <dir> <branch>          Set git branch
-  python3 task.py set-base-branch <dir> <branch>     Set PR target branch
-  python3 task.py set-scope <dir> <scope>            Set scope for PR title
-  python3 task.py archive <task-dir>                 Archive completed task
-  python3 task.py add-subtask <parent> <child>       Link child task to parent
-  python3 task.py remove-subtask <parent> <child>    Unlink child from parent
-  python3 task.py list [--mine] [--status <status>]  List tasks
-  python3 task.py list-archive [YYYY-MM]             List archived tasks
+  python task.py create <title>                     Create new task directory
+  python task.py create <title> --package <pkg>     Create task for a specific package
+  python task.py create <title> --parent <dir>      Create task as child of parent
+  python task.py add-context <dir> <jsonl> <path> [reason]  Add entry to jsonl
+  python task.py validate <dir>                     Validate jsonl files
+  python task.py list-context <dir>                 List jsonl entries
+  python task.py start <dir>                        Set active task
+  python task.py current [--source]                 Show active task
+  python task.py finish                             Clear active task
+  python task.py set-branch <dir> <branch>          Set git branch
+  python task.py set-base-branch <dir> <branch>     Set PR target branch
+  python task.py set-scope <dir> <scope>            Set scope for PR title
+  python task.py archive <task-dir>                 Archive completed task
+  python task.py add-subtask <parent> <child>       Link child task to parent
+  python task.py remove-subtask <parent> <child>    Unlink child from parent
+  python task.py list [--mine] [--status <status>]  List tasks
+  python task.py list-archive [YYYY-MM]             List archived tasks
 
 
 Monorepo options:
 Monorepo options:
   --package <pkg>      Package name (validated against config.yaml packages)
   --package <pkg>      Package name (validated against config.yaml packages)
@@ -330,20 +330,20 @@ List options:
   --status, -s <s>     Filter by status (planning, in_progress, review, completed)
   --status, -s <s>     Filter by status (planning, in_progress, review, completed)
 
 
 Examples:
 Examples:
-  python3 task.py create "Add login feature" --slug add-login
-  python3 task.py create "Add login feature" --slug add-login --package cli
-  python3 task.py create "Child task" --slug child --parent .trellis/tasks/01-21-parent
-  python3 task.py add-context <dir> implement .trellis/spec/cli/backend/auth.md "Auth guidelines"
-  python3 task.py set-branch <dir> task/add-login
-  python3 task.py start .trellis/tasks/01-21-add-login
-  python3 task.py current --source
-  python3 task.py finish
-  python3 task.py archive add-login
-  python3 task.py add-subtask parent-task child-task  # Link existing tasks
-  python3 task.py remove-subtask parent-task child-task
-  python3 task.py list                               # List all active tasks
-  python3 task.py list --mine                        # List my tasks only
-  python3 task.py list --mine --status in_progress   # List my in-progress tasks
+  python task.py create "Add login feature" --slug add-login
+  python task.py create "Add login feature" --slug add-login --package cli
+  python task.py create "Child task" --slug child --parent .trellis/tasks/01-21-parent
+  python task.py add-context <dir> implement .trellis/spec/cli/backend/auth.md "Auth guidelines"
+  python task.py set-branch <dir> task/add-login
+  python task.py start .trellis/tasks/01-21-add-login
+  python task.py current --source
+  python task.py finish
+  python task.py archive add-login
+  python task.py add-subtask parent-task child-task  # Link existing tasks
+  python task.py remove-subtask parent-task child-task
+  python task.py list                               # List all active tasks
+  python task.py list --mine                        # List my tasks only
+  python task.py list --mine --status in_progress   # List my in-progress tasks
 """)
 """)
 
 
 
 
@@ -374,7 +374,7 @@ def main() -> int:
         )
         )
         print("See .trellis/workflow.md Phase 1.3 or run:", file=sys.stderr)
         print("See .trellis/workflow.md Phase 1.3 or run:", file=sys.stderr)
         print(
         print(
-            "  python3 ./.trellis/scripts/get_context.py --mode phase --step 1.3",
+            "  python ./.trellis/scripts/get_context.py --mode phase --step 1.3",
             file=sys.stderr,
             file=sys.stderr,
         )
         )
         print(
         print(

+ 32 - 32
.trellis/workflow.md

@@ -19,7 +19,7 @@
 On first use, initialize your identity:
 On first use, initialize your identity:
 
 
 ```bash
 ```bash
-python3 ./.trellis/scripts/init_developer.py <your-name>
+python ./.trellis/scripts/init_developer.py <your-name>
 ```
 ```
 
 
 Creates `.trellis/.developer` (gitignored) + `.trellis/workspace/<your-name>/`.
 Creates `.trellis/.developer` (gitignored) + `.trellis/workspace/<your-name>/`.
@@ -32,7 +32,7 @@ Creates `.trellis/.developer` (gitignored) + `.trellis/workspace/<your-name>/`.
 - `.trellis/spec/guides/index.md` — cross-package thinking guides.
 - `.trellis/spec/guides/index.md` — cross-package thinking guides.
 
 
 ```bash
 ```bash
-python3 ./.trellis/scripts/get_context.py --mode packages   # list packages / layers
+python ./.trellis/scripts/get_context.py --mode packages   # list packages / layers
 ```
 ```
 
 
 **When to update spec**: new pattern/convention found · bug-fix prevention to codify · new technical decision.
 **When to update spec**: new pattern/convention found · bug-fix prevention to codify · new technical decision.
@@ -43,35 +43,35 @@ Every task has its own directory under `.trellis/tasks/{MM-DD-name}/` holding `p
 
 
 ```bash
 ```bash
 # Task lifecycle
 # Task lifecycle
-python3 ./.trellis/scripts/task.py create "<title>" [--slug <name>] [--parent <dir>]
-python3 ./.trellis/scripts/task.py start <name>          # set active task (session-scoped when available)
-python3 ./.trellis/scripts/task.py current --source      # show active task and source
-python3 ./.trellis/scripts/task.py finish                # clear active task (triggers after_finish hooks)
-python3 ./.trellis/scripts/task.py archive <name>        # move to archive/{year-month}/
-python3 ./.trellis/scripts/task.py list [--mine] [--status <s>]
-python3 ./.trellis/scripts/task.py list-archive
+python ./.trellis/scripts/task.py create "<title>" [--slug <name>] [--parent <dir>]
+python ./.trellis/scripts/task.py start <name>          # set active task (session-scoped when available)
+python ./.trellis/scripts/task.py current --source      # show active task and source
+python ./.trellis/scripts/task.py finish                # clear active task (triggers after_finish hooks)
+python ./.trellis/scripts/task.py archive <name>        # move to archive/{year-month}/
+python ./.trellis/scripts/task.py list [--mine] [--status <s>]
+python ./.trellis/scripts/task.py list-archive
 
 
 # Code-spec context (injected into implement/check agents via JSONL).
 # Code-spec context (injected into implement/check agents via JSONL).
 # `implement.jsonl` / `check.jsonl` are seeded on `task create` for sub-agent-capable
 # `implement.jsonl` / `check.jsonl` are seeded on `task create` for sub-agent-capable
 # platforms; the AI curates real spec + research entries during Phase 1.3.
 # platforms; the AI curates real spec + research entries during Phase 1.3.
-python3 ./.trellis/scripts/task.py add-context <name> <action> <file> <reason>
-python3 ./.trellis/scripts/task.py list-context <name> [action]
-python3 ./.trellis/scripts/task.py validate <name>
+python ./.trellis/scripts/task.py add-context <name> <action> <file> <reason>
+python ./.trellis/scripts/task.py list-context <name> [action]
+python ./.trellis/scripts/task.py validate <name>
 
 
 # Task metadata
 # Task metadata
-python3 ./.trellis/scripts/task.py set-branch <name> <branch>
-python3 ./.trellis/scripts/task.py set-base-branch <name> <branch>    # PR target
-python3 ./.trellis/scripts/task.py set-scope <name> <scope>
+python ./.trellis/scripts/task.py set-branch <name> <branch>
+python ./.trellis/scripts/task.py set-base-branch <name> <branch>    # PR target
+python ./.trellis/scripts/task.py set-scope <name> <scope>
 
 
 # Hierarchy (parent/child)
 # Hierarchy (parent/child)
-python3 ./.trellis/scripts/task.py add-subtask <parent> <child>
-python3 ./.trellis/scripts/task.py remove-subtask <parent> <child>
+python ./.trellis/scripts/task.py add-subtask <parent> <child>
+python ./.trellis/scripts/task.py remove-subtask <parent> <child>
 
 
 # PR creation
 # PR creation
-python3 ./.trellis/scripts/task.py create-pr [name] [--dry-run]
+python ./.trellis/scripts/task.py create-pr [name] [--dry-run]
 ```
 ```
 
 
-> Run `python3 ./.trellis/scripts/task.py --help` to see the authoritative, up-to-date list.
+> Run `python ./.trellis/scripts/task.py --help` to see the authoritative, up-to-date list.
 
 
 **Current-task mechanism**: `task.py create` creates the task directory and (when session identity is available) auto-sets the per-session active-task pointer so the planning breadcrumb fires immediately. `task.py start` writes the same pointer (idempotent if already set) and flips `task.json.status` from `planning` to `in_progress`. State is stored under `.trellis/.runtime/sessions/`. If no context key is available from hook input, `TRELLIS_CONTEXT_ID`, or a platform-native session environment variable, there is no active task and `task.py start` fails with a session identity hint. `task.py finish` deletes the current session file (status unchanged). `task.py archive <task>` writes `status=completed`, moves the directory to `archive/`, and deletes any runtime session files that still point at the archived task.
 **Current-task mechanism**: `task.py create` creates the task directory and (when session identity is available) auto-sets the per-session active-task pointer so the planning breadcrumb fires immediately. `task.py start` writes the same pointer (idempotent if already set) and flips `task.json.status` from `planning` to `in_progress`. State is stored under `.trellis/.runtime/sessions/`. If no context key is available from hook input, `TRELLIS_CONTEXT_ID`, or a platform-native session environment variable, there is no active task and `task.py start` fails with a session identity hint. `task.py finish` deletes the current session file (status unchanged). `task.py archive <task>` writes `status=completed`, moves the directory to `archive/`, and deletes any runtime session files that still point at the archived task.
 
 
@@ -83,15 +83,15 @@ Records every AI session for cross-session tracking under `.trellis/workspace/<d
 - `index.md` — personal index (total sessions, last active).
 - `index.md` — personal index (total sessions, last active).
 
 
 ```bash
 ```bash
-python3 ./.trellis/scripts/add_session.py --title "Title" --commit "hash" --summary "Summary"
+python ./.trellis/scripts/add_session.py --title "Title" --commit "hash" --summary "Summary"
 ```
 ```
 
 
 ### Context Script
 ### Context Script
 
 
 ```bash
 ```bash
-python3 ./.trellis/scripts/get_context.py                            # full session runtime
-python3 ./.trellis/scripts/get_context.py --mode packages            # available packages + spec layers
-python3 ./.trellis/scripts/get_context.py --mode phase --step <X.Y>  # detailed guide for a workflow step
+python ./.trellis/scripts/get_context.py                            # full session runtime
+python ./.trellis/scripts/get_context.py --mode packages            # available packages + spec layers
+python ./.trellis/scripts/get_context.py --mode phase --step <X.Y>  # detailed guide for a workflow step
 ```
 ```
 
 
 ---
 ---
@@ -151,7 +151,7 @@ Phase 3: Finish  → distill lessons + wrap-up
 
 
 [workflow-state:no_task]
 [workflow-state:no_task]
 No active task. **A Direct answer** — pure Q&A / explanation / lookup / chat; no file writes + one-line answer + repo reads ≤ 2 files → AI judges, no override needed.
 No active task. **A Direct answer** — pure Q&A / explanation / lookup / chat; no file writes + one-line answer + repo reads ≤ 2 files → AI judges, no override needed.
-**B Create a task** — any implementation / code change / build / refactor work. Entry sequence: (1) `python3 ./.trellis/scripts/task.py create "<title>"` to create the task (status=planning, breadcrumb switches to [workflow-state:planning] for brainstorm + jsonl phase guidance) → (2) load `trellis-brainstorm` skill to discuss requirements with the user and iterate on prd.md → (3) once prd is done and jsonl is curated, run `task.py start <task-dir>` to enter [workflow-state:in_progress] for the implementation skeleton. **"It looks small" is NOT grounds for downgrading B to A or C**.
+**B Create a task** — any implementation / code change / build / refactor work. Entry sequence: (1) `python ./.trellis/scripts/task.py create "<title>"` to create the task (status=planning, breadcrumb switches to [workflow-state:planning] for brainstorm + jsonl phase guidance) → (2) load `trellis-brainstorm` skill to discuss requirements with the user and iterate on prd.md → (3) once prd is done and jsonl is curated, run `task.py start <task-dir>` to enter [workflow-state:in_progress] for the implementation skeleton. **"It looks small" is NOT grounds for downgrading B to A or C**.
 **C Inline change** (per-turn only, escape hatch for B) — the user's CURRENT message MUST contain one of: "skip trellis" / "no task" / "just do it" / "don't create a task" / "跳过 trellis" / "别走流程" / "小修一下" / "直接改" / "先别建任务" → briefly acknowledge ("ok, skipping trellis flow this turn"), then inline. **Without seeing one of these phrases you must NOT inline on your own**; do not invent an override the user never said.
 **C Inline change** (per-turn only, escape hatch for B) — the user's CURRENT message MUST contain one of: "skip trellis" / "no task" / "just do it" / "don't create a task" / "跳过 trellis" / "别走流程" / "小修一下" / "直接改" / "先别建任务" → briefly acknowledge ("ok, skipping trellis flow this turn"), then inline. **Without seeing one of these phrases you must NOT inline on your own**; do not invent an override the user never said.
 [/workflow-state:no_task]
 [/workflow-state:no_task]
 
 
@@ -301,8 +301,8 @@ When a user request matches one of these intents, load the corresponding skill (
 At each step, run this to fetch detailed guidance:
 At each step, run this to fetch detailed guidance:
 
 
 ```bash
 ```bash
-python3 ./.trellis/scripts/get_context.py --mode phase --step <step>
-# e.g. python3 ./.trellis/scripts/get_context.py --mode phase --step 1.1
+python ./.trellis/scripts/get_context.py --mode phase --step <step>
+# e.g. python ./.trellis/scripts/get_context.py --mode phase --step 1.1
 ```
 ```
 
 
 ---
 ---
@@ -316,7 +316,7 @@ Goal: figure out what to build, produce a clear requirements doc and the context
 Create the task directory (status enters `planning`, the session active-task pointer auto-targets the new task when session identity is available):
 Create the task directory (status enters `planning`, the session active-task pointer auto-targets the new task when session identity is available):
 
 
 ```bash
 ```bash
-python3 ./.trellis/scripts/task.py create "<task title>" --slug <name>
+python ./.trellis/scripts/task.py create "<task title>" --slug <name>
 ```
 ```
 
 
 `--slug` is the human-readable name only. Do **not** include the `MM-DD-` date prefix; `task.py create` adds that prefix automatically.
 `--slug` is the human-readable name only. Do **not** include the `MM-DD-` date prefix; `task.py create` adds that prefix automatically.
@@ -325,7 +325,7 @@ After this command succeeds, the per-turn breadcrumb auto-switches to `[workflow
 
 
 ⚠️ **Run only `create` here — do not also run `start`**. `start` flips status to `in_progress`, which switches the breadcrumb to the implementation phase before brainstorm + jsonl are done — the AI will silently skip them. Save `start` for step 1.4, after jsonl curation is complete.
 ⚠️ **Run only `create` here — do not also run `start`**. `start` flips status to `in_progress`, which switches the breadcrumb to the implementation phase before brainstorm + jsonl are done — the AI will silently skip them. Save `start` for step 1.4, after jsonl curation is complete.
 
 
-Skip when `python3 ./.trellis/scripts/task.py current --source` already points to a task.
+Skip when `python ./.trellis/scripts/task.py current --source` already points to a task.
 
 
 #### 1.1 Requirement exploration `[required · repeatable]`
 #### 1.1 Requirement exploration `[required · repeatable]`
 
 
@@ -393,7 +393,7 @@ Curate `implement.jsonl` and `check.jsonl` so the Phase 2 sub-agents get the rig
 **How to discover relevant specs**:
 **How to discover relevant specs**:
 
 
 ```bash
 ```bash
-python3 ./.trellis/scripts/get_context.py --mode packages
+python ./.trellis/scripts/get_context.py --mode packages
 ```
 ```
 
 
 Lists every package + its spec layers with paths. Pick the entries that match this task's domain.
 Lists every package + its spec layers with paths. Pick the entries that match this task's domain.
@@ -403,8 +403,8 @@ Lists every package + its spec layers with paths. Pick the entries that match th
 Either edit the jsonl file directly in your editor, or use:
 Either edit the jsonl file directly in your editor, or use:
 
 
 ```bash
 ```bash
-python3 ./.trellis/scripts/task.py add-context "$TASK_DIR" implement "<path>" "<reason>"
-python3 ./.trellis/scripts/task.py add-context "$TASK_DIR" check "<path>" "<reason>"
+python ./.trellis/scripts/task.py add-context "$TASK_DIR" implement "<path>" "<reason>"
+python ./.trellis/scripts/task.py add-context "$TASK_DIR" check "<path>" "<reason>"
 ```
 ```
 
 
 Delete the seed `_example` line once real entries exist (optional — it's skipped automatically by consumers).
 Delete the seed `_example` line once real entries exist (optional — it's skipped automatically by consumers).
@@ -424,7 +424,7 @@ Skip this step. Context is loaded directly by the `trellis-before-dev` skill in
 Once prd.md is complete and 1.3 jsonl curation is done, flip the task status to `in_progress`:
 Once prd.md is complete and 1.3 jsonl curation is done, flip the task status to `in_progress`:
 
 
 ```bash
 ```bash
-python3 ./.trellis/scripts/task.py start <task-dir>
+python ./.trellis/scripts/task.py start <task-dir>
 ```
 ```
 
 
 After this command succeeds, the breadcrumb auto-switches to `[workflow-state:in_progress]`, and the rest of Phase 2 / 3 follows.
 After this command succeeds, the breadcrumb auto-switches to `[workflow-state:in_progress]`, and the rest of Phase 2 / 3 follows.

+ 3 - 3
.trellis/workspace/index.md

@@ -38,7 +38,7 @@ workspace/
 Run the initialization script:
 Run the initialization script:
 
 
 ```bash
 ```bash
-python3 ./.trellis/scripts/init_developer.py <your-name>
+python ./.trellis/scripts/init_developer.py <your-name>
 ```
 ```
 
 
 This will:
 This will:
@@ -51,12 +51,12 @@ This will:
 
 
 1. Get your developer name:
 1. Get your developer name:
    ```bash
    ```bash
-   python3 ./.trellis/scripts/get_developer.py
+   python ./.trellis/scripts/get_developer.py
    ```
    ```
 
 
 2. Read your personal index:
 2. Read your personal index:
    ```bash
    ```bash
-   cat .trellis/workspace/$(python3 ./.trellis/scripts/get_developer.py)/index.md
+   cat .trellis/workspace/$(python ./.trellis/scripts/get_developer.py)/index.md
    ```
    ```
 
 
 ---
 ---