@blxzer/cursor-trellis 0.1.0 → 0.1.2
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 +124 -5
- package/README.zh-CN.md +170 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1 -33
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/init.d.ts +0 -13
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +7 -14
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +3 -32
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +7 -84
- package/dist/commands/update.js.map +1 -1
- package/dist/configurators/index.d.ts +7 -8
- package/dist/configurators/index.d.ts.map +1 -1
- package/dist/configurators/index.js +11 -236
- package/dist/configurators/index.js.map +1 -1
- package/dist/configurators/workflow.d.ts.map +1 -1
- package/dist/configurators/workflow.js +5 -1
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/migrations/manifests/0.1.1.json +9 -0
- package/dist/migrations/manifests/0.1.2.json +9 -0
- package/dist/templates/common/bundled-skills/smart-search-cli/SKILL.md +3 -3
- package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +4 -2
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +8 -15
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +7 -7
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +18 -21
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +2 -2
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +10 -7
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +4 -4
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +20 -31
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +20 -31
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +24 -40
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +28 -59
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +12 -28
- package/dist/templates/common/bundled-skills/trellis-skill-creator/references/trellis-skill-locations.md +2 -2
- package/dist/templates/cursor/hooks.json +6 -0
- package/dist/templates/cursor/rules/retrieval-routing.mdc +57 -0
- package/dist/templates/extract.d.ts +0 -14
- package/dist/templates/extract.d.ts.map +1 -1
- package/dist/templates/extract.js +0 -34
- package/dist/templates/extract.js.map +1 -1
- package/dist/templates/markdown/agents.md +2 -6
- package/dist/templates/markdown/index.d.ts +1 -0
- package/dist/templates/markdown/index.d.ts.map +1 -1
- package/dist/templates/markdown/index.js +1 -0
- package/dist/templates/markdown/index.js.map +1 -1
- package/dist/templates/markdown/prompts/run-semantic-slice-12.md.txt +41 -0
- package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +14 -14
- package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +8 -20
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +15 -14
- package/dist/templates/markdown/spec/guides/cursor-context-injection-guide.md.txt +4 -2
- package/dist/templates/markdown/spec/guides/cursor-semantic-compliance.md.txt +49 -0
- package/dist/templates/markdown/spec/guides/cursor-subagent-policy.md.txt +18 -5
- package/dist/templates/markdown/spec/guides/retrieval-daily-guide.md.txt +68 -20
- package/dist/templates/shared-hooks/index.d.ts +1 -1
- package/dist/templates/shared-hooks/index.d.ts.map +1 -1
- package/dist/templates/shared-hooks/index.js +1 -0
- package/dist/templates/shared-hooks/index.js.map +1 -1
- package/dist/templates/shared-hooks/inject-retrieval-plan.py +163 -0
- package/dist/templates/shared-hooks/inject-subagent-context.py +31 -567
- package/dist/templates/shared-hooks/research-end-retrieval-pack.py +2 -11
- package/dist/templates/trellis/index.d.ts +12 -0
- package/dist/templates/trellis/index.d.ts.map +1 -1
- package/dist/templates/trellis/index.js +24 -0
- package/dist/templates/trellis/index.js.map +1 -1
- package/dist/templates/trellis/scripts/aggregate_retrieval_telemetry.py +342 -0
- package/dist/templates/trellis/scripts/batch_plan_envelope.py +105 -0
- package/dist/templates/trellis/scripts/codegraph_session_smoke.py +76 -0
- package/dist/templates/trellis/scripts/common/active_task.py +116 -147
- package/dist/templates/trellis/scripts/common/cli_adapter.py +34 -710
- package/dist/templates/trellis/scripts/common/codebase_retrieval_router.py +49 -106
- package/dist/templates/trellis/scripts/common/git_context.py +17 -2
- package/dist/templates/trellis/scripts/common/project_file_stats.py +91 -0
- package/dist/templates/trellis/scripts/common/retrieval_adapter_metadata.py +9 -11
- package/dist/templates/trellis/scripts/common/retrieval_agent_instructions.py +313 -0
- package/dist/templates/trellis/scripts/common/retrieval_pack.py +0 -6
- package/dist/templates/trellis/scripts/common/retrieval_pack_context.py +0 -4
- package/dist/templates/trellis/scripts/common/retrieval_plan_gate.py +76 -0
- package/dist/templates/trellis/scripts/common/retrieval_result_ranking.py +253 -0
- package/dist/templates/trellis/scripts/common/retrieval_tool_classification.py +157 -0
- package/dist/templates/trellis/scripts/common/semantic_plan_gate.py +52 -0
- package/dist/templates/trellis/scripts/common/subagent_dispatch.py +527 -0
- package/dist/templates/trellis/scripts/common/task_store.py +32 -0
- package/dist/templates/trellis/scripts/common/workflow_phase.py +3 -24
- package/dist/templates/trellis/scripts/rank_retrieval_candidates.py +80 -0
- package/dist/templates/trellis/scripts/route_codebase_retrieval.py +38 -11
- package/dist/templates/trellis/scripts/score_evidence.py +112 -0
- package/dist/templates/trellis/scripts/task.py +26 -0
- package/dist/templates/trellis/workflow.md +844 -960
- package/dist/types/ai-tools.d.ts +13 -16
- package/dist/types/ai-tools.d.ts.map +1 -1
- package/dist/types/ai-tools.js +5 -238
- package/dist/types/ai-tools.js.map +1 -1
- package/dist/utils/codebase-retrieval-router.d.ts +1 -8
- package/dist/utils/codebase-retrieval-router.d.ts.map +1 -1
- package/dist/utils/codebase-retrieval-router.js +39 -180
- package/dist/utils/codebase-retrieval-router.js.map +1 -1
- package/dist/utils/project-capabilities.d.ts.map +1 -1
- package/dist/utils/project-capabilities.js +10 -24
- package/dist/utils/project-capabilities.js.map +1 -1
- package/dist/utils/retrieval-agent-instructions.d.ts +14 -0
- package/dist/utils/retrieval-agent-instructions.d.ts.map +1 -0
- package/dist/utils/retrieval-agent-instructions.js +221 -0
- package/dist/utils/retrieval-agent-instructions.js.map +1 -0
- package/dist/utils/retrieval-execution-telemetry.d.ts +43 -85
- package/dist/utils/retrieval-execution-telemetry.d.ts.map +1 -1
- package/dist/utils/retrieval-execution-telemetry.js +289 -22
- package/dist/utils/retrieval-execution-telemetry.js.map +1 -1
- package/dist/utils/retrieval-result-ranking.js +1 -1
- package/dist/utils/retrieval-result-ranking.js.map +1 -1
- package/dist/utils/retrieval-tool-classification.d.ts +32 -0
- package/dist/utils/retrieval-tool-classification.d.ts.map +1 -0
- package/dist/utils/retrieval-tool-classification.js +113 -0
- package/dist/utils/retrieval-tool-classification.js.map +1 -0
- package/dist/utils/uninstall-scrubbers.d.ts +0 -36
- package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
- package/dist/utils/uninstall-scrubbers.js +0 -184
- package/dist/utils/uninstall-scrubbers.js.map +1 -1
- package/package.json +4 -2
- package/dist/commands/mem.d.ts +0 -30
- package/dist/commands/mem.d.ts.map +0 -1
- package/dist/commands/mem.js +0 -424
- package/dist/commands/mem.js.map +0 -1
- package/dist/configurators/antigravity.d.ts +0 -7
- package/dist/configurators/antigravity.d.ts.map +0 -1
- package/dist/configurators/antigravity.js +0 -19
- package/dist/configurators/antigravity.js.map +0 -1
- package/dist/configurators/claude.d.ts +0 -9
- package/dist/configurators/claude.d.ts.map +0 -1
- package/dist/configurators/claude.js +0 -72
- package/dist/configurators/claude.js.map +0 -1
- package/dist/configurators/codebuddy.d.ts +0 -10
- package/dist/configurators/codebuddy.d.ts.map +0 -1
- package/dist/configurators/codebuddy.js +0 -30
- package/dist/configurators/codebuddy.js.map +0 -1
- package/dist/configurators/codex.d.ts +0 -8
- package/dist/configurators/codex.d.ts.map +0 -1
- package/dist/configurators/codex.js +0 -87
- package/dist/configurators/codex.js.map +0 -1
- package/dist/configurators/copilot.d.ts +0 -10
- package/dist/configurators/copilot.d.ts.map +0 -1
- package/dist/configurators/copilot.js +0 -51
- package/dist/configurators/copilot.js.map +0 -1
- package/dist/configurators/droid.d.ts +0 -10
- package/dist/configurators/droid.d.ts.map +0 -1
- package/dist/configurators/droid.js +0 -30
- package/dist/configurators/droid.js.map +0 -1
- package/dist/configurators/gemini.d.ts +0 -16
- package/dist/configurators/gemini.d.ts.map +0 -1
- package/dist/configurators/gemini.js +0 -38
- package/dist/configurators/gemini.js.map +0 -1
- package/dist/configurators/kilo.d.ts +0 -7
- package/dist/configurators/kilo.d.ts.map +0 -1
- package/dist/configurators/kilo.js +0 -19
- package/dist/configurators/kilo.js.map +0 -1
- package/dist/configurators/kiro.d.ts +0 -8
- package/dist/configurators/kiro.d.ts.map +0 -1
- package/dist/configurators/kiro.js +0 -24
- package/dist/configurators/kiro.js.map +0 -1
- package/dist/configurators/opencode.d.ts +0 -14
- package/dist/configurators/opencode.d.ts.map +0 -1
- package/dist/configurators/opencode.js +0 -96
- package/dist/configurators/opencode.js.map +0 -1
- package/dist/configurators/pi.d.ts +0 -3
- package/dist/configurators/pi.d.ts.map +0 -1
- package/dist/configurators/pi.js +0 -45
- package/dist/configurators/pi.js.map +0 -1
- package/dist/configurators/qoder.d.ts +0 -11
- package/dist/configurators/qoder.d.ts.map +0 -1
- package/dist/configurators/qoder.js +0 -31
- package/dist/configurators/qoder.js.map +0 -1
- package/dist/configurators/windsurf.d.ts +0 -7
- package/dist/configurators/windsurf.d.ts.map +0 -1
- package/dist/configurators/windsurf.js +0 -19
- package/dist/configurators/windsurf.js.map +0 -1
- package/dist/templates/claude/agents/trellis-check.md +0 -124
- package/dist/templates/claude/agents/trellis-implement.md +0 -110
- package/dist/templates/claude/agents/trellis-research.md +0 -137
- package/dist/templates/claude/index.d.ts +0 -22
- package/dist/templates/claude/index.d.ts.map +0 -1
- package/dist/templates/claude/index.js +0 -46
- package/dist/templates/claude/index.js.map +0 -1
- package/dist/templates/claude/settings.json +0 -84
- package/dist/templates/codebuddy/agents/trellis-check.md +0 -115
- package/dist/templates/codebuddy/agents/trellis-implement.md +0 -110
- package/dist/templates/codebuddy/agents/trellis-research.md +0 -137
- package/dist/templates/codebuddy/index.d.ts +0 -15
- package/dist/templates/codebuddy/index.d.ts.map +0 -1
- package/dist/templates/codebuddy/index.js +0 -15
- package/dist/templates/codebuddy/index.js.map +0 -1
- package/dist/templates/codebuddy/settings.json +0 -70
- package/dist/templates/codex/agents/trellis-check.toml +0 -67
- package/dist/templates/codex/agents/trellis-implement.toml +0 -40
- package/dist/templates/codex/agents/trellis-research.toml +0 -73
- package/dist/templates/codex/config.toml +0 -28
- package/dist/templates/codex/hooks/session-start.py +0 -575
- package/dist/templates/codex/hooks.json +0 -15
- package/dist/templates/codex/index.d.ts +0 -39
- package/dist/templates/codex/index.d.ts.map +0 -1
- package/dist/templates/codex/index.js +0 -85
- package/dist/templates/codex/index.js.map +0 -1
- package/dist/templates/codex/skills/before-dev/SKILL.md +0 -40
- package/dist/templates/codex/skills/brainstorm/SKILL.md +0 -112
- package/dist/templates/codex/skills/break-loop/SKILL.md +0 -130
- package/dist/templates/codex/skills/check/SKILL.md +0 -98
- package/dist/templates/codex/skills/check-cross-layer/SKILL.md +0 -158
- package/dist/templates/codex/skills/create-command/SKILL.md +0 -101
- package/dist/templates/codex/skills/finish-work/SKILL.md +0 -90
- package/dist/templates/codex/skills/improve-ut/SKILL.md +0 -69
- package/dist/templates/codex/skills/integrate-skill/SKILL.md +0 -221
- package/dist/templates/codex/skills/onboard/SKILL.md +0 -363
- package/dist/templates/codex/skills/record-session/SKILL.md +0 -67
- package/dist/templates/codex/skills/start/SKILL.md +0 -66
- package/dist/templates/codex/skills/update-spec/SKILL.md +0 -335
- package/dist/templates/copilot/hooks/session-start.py +0 -557
- package/dist/templates/copilot/hooks.json +0 -19
- package/dist/templates/copilot/index.d.ts +0 -23
- package/dist/templates/copilot/index.d.ts.map +0 -1
- package/dist/templates/copilot/index.js +0 -54
- package/dist/templates/copilot/index.js.map +0 -1
- package/dist/templates/copilot/prompts/before-dev.prompt.md +0 -39
- package/dist/templates/copilot/prompts/brainstorm.prompt.md +0 -111
- package/dist/templates/copilot/prompts/break-loop.prompt.md +0 -129
- package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +0 -157
- package/dist/templates/copilot/prompts/check.prompt.md +0 -97
- package/dist/templates/copilot/prompts/create-command.prompt.md +0 -116
- package/dist/templates/copilot/prompts/finish-work.prompt.md +0 -99
- package/dist/templates/copilot/prompts/integrate-skill.prompt.md +0 -223
- package/dist/templates/copilot/prompts/onboard.prompt.md +0 -362
- package/dist/templates/copilot/prompts/parallel.prompt.md +0 -204
- package/dist/templates/copilot/prompts/record-session.prompt.md +0 -66
- package/dist/templates/copilot/prompts/start.prompt.md +0 -63
- package/dist/templates/copilot/prompts/update-spec.prompt.md +0 -358
- package/dist/templates/droid/droids/trellis-check.md +0 -107
- package/dist/templates/droid/droids/trellis-implement.md +0 -102
- package/dist/templates/droid/droids/trellis-research.md +0 -137
- package/dist/templates/droid/index.d.ts +0 -15
- package/dist/templates/droid/index.d.ts.map +0 -1
- package/dist/templates/droid/index.js +0 -15
- package/dist/templates/droid/index.js.map +0 -1
- package/dist/templates/droid/settings.json +0 -70
- package/dist/templates/gemini/agents/trellis-check.md +0 -107
- package/dist/templates/gemini/agents/trellis-implement.md +0 -102
- package/dist/templates/gemini/agents/trellis-research.md +0 -136
- package/dist/templates/gemini/index.d.ts +0 -13
- package/dist/templates/gemini/index.d.ts.map +0 -1
- package/dist/templates/gemini/index.js +0 -13
- package/dist/templates/gemini/index.js.map +0 -1
- package/dist/templates/gemini/settings.json +0 -28
- package/dist/templates/kiro/agents/trellis-check.json +0 -26
- package/dist/templates/kiro/agents/trellis-implement.json +0 -26
- package/dist/templates/kiro/agents/trellis-research.json +0 -30
- package/dist/templates/kiro/index.d.ts +0 -18
- package/dist/templates/kiro/index.d.ts.map +0 -1
- package/dist/templates/kiro/index.js +0 -18
- package/dist/templates/kiro/index.js.map +0 -1
- package/dist/templates/opencode/agents/trellis-check.md +0 -122
- package/dist/templates/opencode/agents/trellis-implement.md +0 -118
- package/dist/templates/opencode/agents/trellis-research.md +0 -145
- package/dist/templates/opencode/lib/session-utils.js +0 -667
- package/dist/templates/opencode/lib/trellis-context.js +0 -336
- package/dist/templates/opencode/package.json +0 -5
- package/dist/templates/opencode/plugins/inject-subagent-context.js +0 -495
- package/dist/templates/opencode/plugins/inject-workflow-state.js +0 -159
- package/dist/templates/opencode/plugins/session-start.js +0 -101
- package/dist/templates/pi/agents/trellis-check.md +0 -37
- package/dist/templates/pi/agents/trellis-implement.md +0 -42
- package/dist/templates/pi/agents/trellis-research.md +0 -25
- package/dist/templates/pi/extensions/trellis/index.ts.txt +0 -1600
- package/dist/templates/pi/index.d.ts +0 -5
- package/dist/templates/pi/index.d.ts.map +0 -1
- package/dist/templates/pi/index.js +0 -12
- package/dist/templates/pi/index.js.map +0 -1
- package/dist/templates/pi/settings.json +0 -12
- package/dist/templates/qoder/agents/trellis-check.md +0 -108
- package/dist/templates/qoder/agents/trellis-implement.md +0 -103
- package/dist/templates/qoder/agents/trellis-research.md +0 -137
- package/dist/templates/qoder/index.d.ts +0 -15
- package/dist/templates/qoder/index.d.ts.map +0 -1
- package/dist/templates/qoder/index.js +0 -15
- package/dist/templates/qoder/index.js.map +0 -1
- package/dist/templates/qoder/settings.json +0 -47
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Pre-run checks for codegraph index presence (does not start MCP)."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
import json
|
|
8
|
+
import sys
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
from common.paths import get_repo_root
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _find_codegraph_dirs(root: Path) -> list[Path]:
|
|
16
|
+
found: list[Path] = []
|
|
17
|
+
direct = root / ".codegraph"
|
|
18
|
+
if direct.is_dir():
|
|
19
|
+
found.append(direct.resolve())
|
|
20
|
+
for child in sorted(root.iterdir()):
|
|
21
|
+
if not child.is_dir():
|
|
22
|
+
continue
|
|
23
|
+
nested = child / ".codegraph"
|
|
24
|
+
if nested.is_dir() and nested.resolve() not in found:
|
|
25
|
+
found.append(nested.resolve())
|
|
26
|
+
return found
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def main() -> int:
|
|
30
|
+
parser = argparse.ArgumentParser(description="Codegraph session smoke (index on disk)")
|
|
31
|
+
parser.add_argument(
|
|
32
|
+
"--root",
|
|
33
|
+
type=Path,
|
|
34
|
+
default=None,
|
|
35
|
+
help="Workspace root (default: Trellis repo root)",
|
|
36
|
+
)
|
|
37
|
+
parser.add_argument("--json", action="store_true", help="Machine-readable report")
|
|
38
|
+
args = parser.parse_args()
|
|
39
|
+
|
|
40
|
+
root = (args.root or get_repo_root()).resolve()
|
|
41
|
+
indexes = _find_codegraph_dirs(root)
|
|
42
|
+
ok = len(indexes) > 0
|
|
43
|
+
payload = {
|
|
44
|
+
"ok": ok,
|
|
45
|
+
"workspace_root": str(root),
|
|
46
|
+
"codegraph_index_paths": [str(p) for p in indexes],
|
|
47
|
+
"checked_at": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
|
|
48
|
+
"mcp_note": (
|
|
49
|
+
"Cursor: enable codegraph MCP in project settings; this script only checks "
|
|
50
|
+
"on-disk .codegraph/ directories."
|
|
51
|
+
),
|
|
52
|
+
"run_header_fields": {
|
|
53
|
+
"codegraph_mcp": "configured|unknown|off",
|
|
54
|
+
"codegraph_index_path": str(indexes[0]) if indexes else "",
|
|
55
|
+
"codegraph_smoke_at": "<iso8601>",
|
|
56
|
+
"codegraph_smoke_ok": ok,
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if args.json:
|
|
61
|
+
print(json.dumps(payload, indent=2))
|
|
62
|
+
else:
|
|
63
|
+
if ok:
|
|
64
|
+
print("Codegraph smoke: PASS")
|
|
65
|
+
for p in indexes:
|
|
66
|
+
print(f" index: {p}")
|
|
67
|
+
else:
|
|
68
|
+
print("Codegraph smoke: FAIL — no .codegraph/ under workspace root", file=sys.stderr)
|
|
69
|
+
print(f" root: {root}", file=sys.stderr)
|
|
70
|
+
print(payload["mcp_note"])
|
|
71
|
+
|
|
72
|
+
return 0 if ok else 1
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == "__main__":
|
|
76
|
+
raise SystemExit(main())
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""Session-scoped selected task resolution.
|
|
3
|
-
|
|
4
|
-
The user-facing concept is a live-session "selected task". Trellis stores that
|
|
5
|
-
pointer per AI session/window under `.trellis/.runtime/sessions/`; without a
|
|
6
|
-
stable session key there is no selected task.
|
|
7
|
-
"""
|
|
2
|
+
"""Session-scoped selected task resolution.
|
|
3
|
+
|
|
4
|
+
The user-facing concept is a live-session "selected task". Trellis stores that
|
|
5
|
+
pointer per AI session/window under `.trellis/.runtime/sessions/`; without a
|
|
6
|
+
stable session key there is no selected task.
|
|
7
|
+
"""
|
|
8
8
|
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
@@ -25,74 +25,43 @@ DIR_RUNTIME = ".runtime"
|
|
|
25
25
|
DIR_SESSIONS = "sessions"
|
|
26
26
|
DIR_CURSOR_SHELL = "cursor-shell"
|
|
27
27
|
CURSOR_SHELL_TICKET_TTL_SECONDS = 30
|
|
28
|
-
TASK_SESSION_COMMANDS = {"select", "selected", "exit"}
|
|
28
|
+
TASK_SESSION_COMMANDS = {"select", "selected", "exit"}
|
|
29
29
|
|
|
30
30
|
_SESSION_KEYS = ("session_id", "sessionId", "sessionID")
|
|
31
31
|
_CONVERSATION_KEYS = ("conversation_id", "conversationId", "conversationID")
|
|
32
32
|
_TRANSCRIPT_KEYS = ("transcript_path", "transcriptPath", "transcript")
|
|
33
33
|
_NESTED_KEYS = ("input", "properties", "event", "hook_input", "hookInput")
|
|
34
34
|
_KNOWN_PLATFORMS = {
|
|
35
|
-
"claude",
|
|
36
|
-
"codex",
|
|
37
35
|
"cursor",
|
|
38
|
-
"opencode",
|
|
39
|
-
"gemini",
|
|
40
|
-
"droid",
|
|
41
|
-
"qoder",
|
|
42
|
-
"codebuddy",
|
|
43
|
-
"kiro",
|
|
44
|
-
"copilot",
|
|
45
|
-
"pi",
|
|
46
36
|
}
|
|
47
37
|
|
|
48
38
|
_ENV_SESSION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
|
|
49
|
-
("claude", ("CLAUDE_SESSION_ID", "CLAUDE_CODE_SESSION_ID")),
|
|
50
|
-
("codex", ("CODEX_SESSION_ID", "CODEX_THREAD_ID")),
|
|
51
39
|
("cursor", ("CURSOR_SESSION_ID",)),
|
|
52
|
-
("opencode", ("OPENCODE_SESSION_ID", "OPENCODE_SESSIONID", "OPENCODE_RUN_ID")),
|
|
53
|
-
("gemini", ("GEMINI_SESSION_ID",)),
|
|
54
|
-
("droid", ("FACTORY_SESSION_ID", "DROID_SESSION_ID")),
|
|
55
|
-
("qoder", ("QODER_SESSION_ID",)),
|
|
56
|
-
("codebuddy", ("CODEBUDDY_SESSION_ID",)),
|
|
57
|
-
("kiro", ("KIRO_SESSION_ID",)),
|
|
58
|
-
("copilot", ("COPILOT_SESSION_ID", "COPILOT_SESSIONID")),
|
|
59
|
-
("pi", ("PI_SESSION_ID", "PI_SESSIONID")),
|
|
60
40
|
)
|
|
61
41
|
_ENV_CONVERSATION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
|
|
62
42
|
("cursor", ("CURSOR_CONVERSATION_ID", "CURSOR_CONVERSATIONID")),
|
|
63
43
|
)
|
|
64
44
|
_ENV_TRANSCRIPT_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
|
|
65
|
-
("claude", ("CLAUDE_TRANSCRIPT_PATH",)),
|
|
66
|
-
("codex", ("CODEX_TRANSCRIPT_PATH",)),
|
|
67
45
|
("cursor", ("CURSOR_TRANSCRIPT_PATH",)),
|
|
68
|
-
("gemini", ("GEMINI_TRANSCRIPT_PATH",)),
|
|
69
|
-
("droid", ("FACTORY_TRANSCRIPT_PATH", "DROID_TRANSCRIPT_PATH")),
|
|
70
|
-
("qoder", ("QODER_TRANSCRIPT_PATH",)),
|
|
71
|
-
("codebuddy", ("CODEBUDDY_TRANSCRIPT_PATH",)),
|
|
72
46
|
)
|
|
73
|
-
_ENV_PLATFORM_ALIASES = {
|
|
74
|
-
"claude-code": "claude",
|
|
75
|
-
"factory": "droid",
|
|
76
|
-
"factory-ai": "droid",
|
|
77
|
-
"github-copilot": "copilot",
|
|
78
|
-
}
|
|
47
|
+
_ENV_PLATFORM_ALIASES: dict[str, str] = {}
|
|
79
48
|
|
|
80
49
|
|
|
81
50
|
@dataclass(frozen=True)
|
|
82
|
-
class SelectedTask:
|
|
83
|
-
"""Resolved selected task state."""
|
|
51
|
+
class SelectedTask:
|
|
52
|
+
"""Resolved selected task state."""
|
|
84
53
|
|
|
85
54
|
task_path: str | None
|
|
86
55
|
source_type: str
|
|
87
56
|
context_key: str | None = None
|
|
88
57
|
stale: bool = False
|
|
89
58
|
|
|
90
|
-
@property
|
|
91
|
-
def source(self) -> str:
|
|
92
|
-
"""Human-readable source label."""
|
|
93
|
-
if self.source_type == "session" and self.context_key:
|
|
94
|
-
return f"session:{self.context_key}"
|
|
95
|
-
return self.source_type
|
|
59
|
+
@property
|
|
60
|
+
def source(self) -> str:
|
|
61
|
+
"""Human-readable source label."""
|
|
62
|
+
if self.source_type == "session" and self.context_key:
|
|
63
|
+
return f"session:{self.context_key}"
|
|
64
|
+
return self.source_type
|
|
96
65
|
|
|
97
66
|
|
|
98
67
|
def normalize_task_ref(task_ref: str) -> str:
|
|
@@ -217,7 +186,7 @@ def _lookup_env_context_key(platform_name: str | None) -> str | None:
|
|
|
217
186
|
Hooks pass `TRELLIS_CONTEXT_ID` to subprocesses they launch, but an AI-run
|
|
218
187
|
shell command can only see session identity if the host platform exports it
|
|
219
188
|
in the command environment. These names are best-effort adapters; if none
|
|
220
|
-
are present, there is no session-scoped selected task.
|
|
189
|
+
are present, there is no session-scoped selected task.
|
|
221
190
|
"""
|
|
222
191
|
env_platform_name = _env_platform_name(platform_name)
|
|
223
192
|
|
|
@@ -274,7 +243,7 @@ def _task_refs_match(left: str | None, right: str | None, repo_root: Path) -> bo
|
|
|
274
243
|
return normalize_task_ref(left) == normalize_task_ref(right)
|
|
275
244
|
|
|
276
245
|
|
|
277
|
-
def _pending_ticket_matches_args(ticket: dict[str, Any], repo_root: Path) -> bool:
|
|
246
|
+
def _pending_ticket_matches_args(ticket: dict[str, Any], repo_root: Path) -> bool:
|
|
278
247
|
if Path(sys.argv[0]).name != "task.py":
|
|
279
248
|
return False
|
|
280
249
|
args = tuple(sys.argv[1:])
|
|
@@ -294,11 +263,11 @@ def _pending_ticket_matches_args(ticket: dict[str, Any], repo_root: Path) -> boo
|
|
|
294
263
|
continue
|
|
295
264
|
if _string_value(subcommand.get("name")) != command_name:
|
|
296
265
|
continue
|
|
297
|
-
if command_name != "select":
|
|
298
|
-
return True
|
|
299
|
-
task_ref = args[1] if len(args) > 1 else None
|
|
300
|
-
if _task_refs_match(_string_value(subcommand.get("task_ref")), task_ref, repo_root):
|
|
301
|
-
return True
|
|
266
|
+
if command_name != "select":
|
|
267
|
+
return True
|
|
268
|
+
task_ref = args[1] if len(args) > 1 else None
|
|
269
|
+
if _task_refs_match(_string_value(subcommand.get("task_ref")), task_ref, repo_root):
|
|
270
|
+
return True
|
|
302
271
|
|
|
303
272
|
return False
|
|
304
273
|
|
|
@@ -446,44 +415,44 @@ def _canonical_task_ref(task_path: str, repo_root: Path) -> str | None:
|
|
|
446
415
|
return str(full_path)
|
|
447
416
|
|
|
448
417
|
|
|
449
|
-
def _selected_from_ref(
|
|
450
|
-
task_ref: str | None,
|
|
451
|
-
repo_root: Path,
|
|
452
|
-
source_type: str,
|
|
453
|
-
context_key: str | None = None,
|
|
454
|
-
) -> SelectedTask | None:
|
|
455
|
-
if not task_ref:
|
|
456
|
-
return None
|
|
457
|
-
resolved = resolve_task_ref(task_ref, repo_root)
|
|
458
|
-
stale = resolved is None or not resolved.is_dir()
|
|
459
|
-
return SelectedTask(task_ref, source_type, context_key, stale)
|
|
418
|
+
def _selected_from_ref(
|
|
419
|
+
task_ref: str | None,
|
|
420
|
+
repo_root: Path,
|
|
421
|
+
source_type: str,
|
|
422
|
+
context_key: str | None = None,
|
|
423
|
+
) -> SelectedTask | None:
|
|
424
|
+
if not task_ref:
|
|
425
|
+
return None
|
|
426
|
+
resolved = resolve_task_ref(task_ref, repo_root)
|
|
427
|
+
stale = resolved is None or not resolved.is_dir()
|
|
428
|
+
return SelectedTask(task_ref, source_type, context_key, stale)
|
|
460
429
|
|
|
461
430
|
|
|
462
431
|
def _context_path(repo_root: Path, context_key: str) -> Path:
|
|
463
432
|
return _runtime_sessions_dir(repo_root) / f"{context_key}.json"
|
|
464
433
|
|
|
465
434
|
|
|
466
|
-
def resolve_selected_task(
|
|
467
|
-
repo_root: Path,
|
|
468
|
-
platform_input: dict[str, Any] | None = None,
|
|
469
|
-
platform: str | None = None,
|
|
470
|
-
) -> SelectedTask:
|
|
471
|
-
"""Resolve the selected task from explicit session runtime state only.
|
|
472
|
-
|
|
473
|
-
A stale session task is returned as stale. Missing context identity or a
|
|
474
|
-
missing/empty session context returns no selected task. Trellis deliberately
|
|
475
|
-
does not infer selection from the existence of a single runtime session file;
|
|
476
|
-
every live session starts with no selected task until the user selects one.
|
|
477
|
-
"""
|
|
478
|
-
context_key = resolve_context_key(platform_input, platform)
|
|
479
|
-
if context_key:
|
|
480
|
-
context = _read_json(_context_path(repo_root, context_key)) or {}
|
|
481
|
-
task_ref = _string_value(context.get("selected_task"))
|
|
482
|
-
selected = _selected_from_ref(task_ref, repo_root, "session", context_key)
|
|
483
|
-
if selected:
|
|
484
|
-
return selected
|
|
485
|
-
|
|
486
|
-
return SelectedTask(None, "none", context_key)
|
|
435
|
+
def resolve_selected_task(
|
|
436
|
+
repo_root: Path,
|
|
437
|
+
platform_input: dict[str, Any] | None = None,
|
|
438
|
+
platform: str | None = None,
|
|
439
|
+
) -> SelectedTask:
|
|
440
|
+
"""Resolve the selected task from explicit session runtime state only.
|
|
441
|
+
|
|
442
|
+
A stale session task is returned as stale. Missing context identity or a
|
|
443
|
+
missing/empty session context returns no selected task. Trellis deliberately
|
|
444
|
+
does not infer selection from the existence of a single runtime session file;
|
|
445
|
+
every live session starts with no selected task until the user selects one.
|
|
446
|
+
"""
|
|
447
|
+
context_key = resolve_context_key(platform_input, platform)
|
|
448
|
+
if context_key:
|
|
449
|
+
context = _read_json(_context_path(repo_root, context_key)) or {}
|
|
450
|
+
task_ref = _string_value(context.get("selected_task"))
|
|
451
|
+
selected = _selected_from_ref(task_ref, repo_root, "session", context_key)
|
|
452
|
+
if selected:
|
|
453
|
+
return selected
|
|
454
|
+
|
|
455
|
+
return SelectedTask(None, "none", context_key)
|
|
487
456
|
|
|
488
457
|
|
|
489
458
|
def _utc_now() -> str:
|
|
@@ -512,17 +481,17 @@ def _context_metadata(
|
|
|
512
481
|
return metadata
|
|
513
482
|
|
|
514
483
|
|
|
515
|
-
def set_selected_task(
|
|
516
|
-
task_path: str,
|
|
517
|
-
repo_root: Path,
|
|
518
|
-
platform_input: dict[str, Any] | None = None,
|
|
519
|
-
platform: str | None = None,
|
|
520
|
-
) -> SelectedTask | None:
|
|
521
|
-
"""Set the selected task in session scope.
|
|
522
|
-
|
|
523
|
-
Returns None when no context key is available; callers should surface a
|
|
524
|
-
user-facing error that explains how to provide session identity.
|
|
525
|
-
"""
|
|
484
|
+
def set_selected_task(
|
|
485
|
+
task_path: str,
|
|
486
|
+
repo_root: Path,
|
|
487
|
+
platform_input: dict[str, Any] | None = None,
|
|
488
|
+
platform: str | None = None,
|
|
489
|
+
) -> SelectedTask | None:
|
|
490
|
+
"""Set the selected task in session scope.
|
|
491
|
+
|
|
492
|
+
Returns None when no context key is available; callers should surface a
|
|
493
|
+
user-facing error that explains how to provide session identity.
|
|
494
|
+
"""
|
|
526
495
|
canonical = _canonical_task_ref(task_path, repo_root)
|
|
527
496
|
if canonical is None:
|
|
528
497
|
return None
|
|
@@ -531,32 +500,32 @@ def set_selected_task(
|
|
|
531
500
|
if not context_key:
|
|
532
501
|
return None
|
|
533
502
|
|
|
534
|
-
context_path = _context_path(repo_root, context_key)
|
|
535
|
-
context = _read_json(context_path) or {}
|
|
536
|
-
context.update(_context_metadata(platform_input, platform, context_key))
|
|
537
|
-
context["selected_task"] = canonical
|
|
538
|
-
context.pop("current_task", None)
|
|
539
|
-
context.setdefault("current_run", None)
|
|
540
|
-
if not _write_json(context_path, context):
|
|
541
|
-
return None
|
|
542
|
-
return SelectedTask(canonical, "session", context_key)
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
def clear_selected_task(
|
|
546
|
-
repo_root: Path,
|
|
547
|
-
platform_input: dict[str, Any] | None = None,
|
|
548
|
-
platform: str | None = None,
|
|
549
|
-
) -> SelectedTask:
|
|
550
|
-
"""Clear the selected task by deleting the current session context file."""
|
|
551
|
-
context_key = resolve_context_key(platform_input, platform)
|
|
552
|
-
if not context_key:
|
|
553
|
-
return SelectedTask(None, "none")
|
|
554
|
-
|
|
555
|
-
previous = resolve_selected_task(repo_root, platform_input, platform)
|
|
556
|
-
context_path = _context_path(repo_root, context_key)
|
|
557
|
-
if context_path.is_file():
|
|
558
|
-
_remove_file(context_path)
|
|
559
|
-
return previous
|
|
503
|
+
context_path = _context_path(repo_root, context_key)
|
|
504
|
+
context = _read_json(context_path) or {}
|
|
505
|
+
context.update(_context_metadata(platform_input, platform, context_key))
|
|
506
|
+
context["selected_task"] = canonical
|
|
507
|
+
context.pop("current_task", None)
|
|
508
|
+
context.setdefault("current_run", None)
|
|
509
|
+
if not _write_json(context_path, context):
|
|
510
|
+
return None
|
|
511
|
+
return SelectedTask(canonical, "session", context_key)
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
def clear_selected_task(
|
|
515
|
+
repo_root: Path,
|
|
516
|
+
platform_input: dict[str, Any] | None = None,
|
|
517
|
+
platform: str | None = None,
|
|
518
|
+
) -> SelectedTask:
|
|
519
|
+
"""Clear the selected task by deleting the current session context file."""
|
|
520
|
+
context_key = resolve_context_key(platform_input, platform)
|
|
521
|
+
if not context_key:
|
|
522
|
+
return SelectedTask(None, "none")
|
|
523
|
+
|
|
524
|
+
previous = resolve_selected_task(repo_root, platform_input, platform)
|
|
525
|
+
context_path = _context_path(repo_root, context_key)
|
|
526
|
+
if context_path.is_file():
|
|
527
|
+
_remove_file(context_path)
|
|
528
|
+
return previous
|
|
560
529
|
|
|
561
530
|
|
|
562
531
|
def clear_task_from_sessions(task_path: str, repo_root: Path) -> int:
|
|
@@ -572,12 +541,12 @@ def clear_task_from_sessions(task_path: str, repo_root: Path) -> int:
|
|
|
572
541
|
|
|
573
542
|
for session_path in sessions_dir.glob("*.json"):
|
|
574
543
|
context = _read_json(session_path) or {}
|
|
575
|
-
current = (
|
|
576
|
-
_string_value(context.get("selected_task"))
|
|
577
|
-
or _string_value(context.get("current_task"))
|
|
578
|
-
)
|
|
579
|
-
if not current:
|
|
580
|
-
continue
|
|
544
|
+
current = (
|
|
545
|
+
_string_value(context.get("selected_task"))
|
|
546
|
+
or _string_value(context.get("current_task"))
|
|
547
|
+
)
|
|
548
|
+
if not current:
|
|
549
|
+
continue
|
|
581
550
|
current_ref = _canonical_task_ref(current, repo_root) or normalize_task_ref(current)
|
|
582
551
|
if current_ref != target:
|
|
583
552
|
continue
|
|
@@ -587,21 +556,21 @@ def clear_task_from_sessions(task_path: str, repo_root: Path) -> int:
|
|
|
587
556
|
return cleared
|
|
588
557
|
|
|
589
558
|
|
|
590
|
-
def get_selected_task_source(
|
|
591
|
-
repo_root: Path,
|
|
592
|
-
platform_input: dict[str, Any] | None = None,
|
|
593
|
-
platform: str | None = None,
|
|
594
|
-
) -> tuple[str, str | None, str | None]:
|
|
595
|
-
"""Return (`source_type`, `context_key`, `task_path`) for selected task."""
|
|
596
|
-
active = resolve_selected_task(repo_root, platform_input, platform)
|
|
597
|
-
return active.source_type, active.context_key, active.task_path
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
# Internal compatibility aliases. User-facing commands and generated guidance
|
|
601
|
-
# use selected-task wording, but keeping these names avoids a broad one-shot
|
|
602
|
-
# rewrite of imports that are not part of the public command surface.
|
|
603
|
-
ActiveTask = SelectedTask
|
|
604
|
-
resolve_active_task = resolve_selected_task
|
|
605
|
-
set_active_task = set_selected_task
|
|
606
|
-
clear_active_task = clear_selected_task
|
|
607
|
-
get_current_task_source = get_selected_task_source
|
|
559
|
+
def get_selected_task_source(
|
|
560
|
+
repo_root: Path,
|
|
561
|
+
platform_input: dict[str, Any] | None = None,
|
|
562
|
+
platform: str | None = None,
|
|
563
|
+
) -> tuple[str, str | None, str | None]:
|
|
564
|
+
"""Return (`source_type`, `context_key`, `task_path`) for selected task."""
|
|
565
|
+
active = resolve_selected_task(repo_root, platform_input, platform)
|
|
566
|
+
return active.source_type, active.context_key, active.task_path
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
# Internal compatibility aliases. User-facing commands and generated guidance
|
|
570
|
+
# use selected-task wording, but keeping these names avoids a broad one-shot
|
|
571
|
+
# rewrite of imports that are not part of the public command surface.
|
|
572
|
+
ActiveTask = SelectedTask
|
|
573
|
+
resolve_active_task = resolve_selected_task
|
|
574
|
+
set_active_task = set_selected_task
|
|
575
|
+
clear_active_task = clear_selected_task
|
|
576
|
+
get_current_task_source = get_selected_task_source
|