feat(trellis): enhance bundled skills and workflow integration

- Updated bundled skills documentation to clarify the structure and usage across all platforms, ensuring consistency in skill root paths.
- Introduced a new `inject-spec-context.py` hook for path-scoped spec context injection, improving the relevance of injected specs during file interactions.
- Enhanced existing hooks to support workflow resolution, allowing for dynamic selection of workflows based on task context.
- Added a command to manage workflow selections for active tasks, enabling better task management and workflow adherence.
- Updated configuration options for spec injection, including character limits and refresh windows, to optimize performance and usability.
This commit is contained in:
yuxuanhui
2026-09-07 11:23:15 +08:00
parent ca3bd7a4b1
commit e567e5f717
23 changed files with 2525 additions and 130 deletions
+34 -2
View File
@@ -27,6 +27,8 @@ from .packages_context import (
get_context_packages_text,
get_context_packages_json,
)
from .paths import get_repo_root
from .spec_match import match_specs_for_file
from .trellis_config import read_trellis_config
from .workflow_phase import (
filter_platform,
@@ -57,9 +59,9 @@ def main() -> None:
parser.add_argument(
"--mode",
"-m",
choices=["default", "record", "packages", "phase"],
choices=["default", "record", "packages", "phase", "spec"],
default="default",
help="Output mode: default (full context), record (for record-session), packages (package info only), phase (workflow step extraction)",
help="Output mode: default (full context), record (for record-session), packages (package info only), phase (workflow step extraction), spec (specs governing a file)",
)
parser.add_argument(
"--step",
@@ -69,6 +71,10 @@ def main() -> None:
"--platform",
help="Platform name for --mode phase, e.g. cursor, claude-code. Filters platform-tagged blocks.",
)
parser.add_argument(
"--file",
help="File path (absolute or repo-relative) for --mode spec. Lists spec files whose frontmatter paths match it.",
)
args = parser.parse_args()
@@ -95,6 +101,32 @@ def main() -> None:
)
content = filter_platform(content, effective)
print(content, end="")
elif args.mode == "spec":
if not args.file:
parser.error("--file is required with --mode spec")
matches = match_specs_for_file(get_repo_root(), args.file)
if args.json:
print(
json.dumps(
{
"file": args.file,
"matches": [
{
"path": match.rel_path,
"description": match.description,
}
for match in matches
],
},
indent=2,
ensure_ascii=False,
)
)
elif matches:
for match in matches:
print(f"{match.rel_path} — {match.description or '(no description)'}")
else:
print(f"No spec files declare paths matching {args.file}.")
else:
if args.json:
output_json()