@complexthings/superpowers-agent 9.2.1 → 10.0.1
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/.agents/skills/claude-handoff/SKILL.md +18 -0
- package/.agents/skills/code-review/SKILL.md +89 -0
- package/.agents/skills/{improve-codebase-architecture → codebase-design}/DEEPENING.md +1 -1
- package/.agents/skills/{improve-codebase-architecture/INTERFACE-DESIGN.md → codebase-design/DESIGN-IT-TWICE.md} +3 -3
- package/.agents/skills/codebase-design/SKILL.md +114 -0
- package/.agents/skills/design-an-interface/SKILL.md +94 -0
- package/.agents/skills/{diagnose → diagnosing-bugs}/SKILL.md +29 -12
- package/.agents/skills/{grill-with-docs → domain-modeling}/CONTEXT-FORMAT.md +1 -4
- package/.agents/skills/domain-modeling/SKILL.md +74 -0
- package/.agents/skills/fable-mode/SKILL.md +95 -0
- package/.agents/skills/git-guardrails-claude-code/SKILL.md +95 -0
- package/.agents/skills/git-guardrails-claude-code/scripts/block-dangerous-git.sh +25 -0
- package/.agents/skills/grill-me/SKILL.md +7 -0
- package/.agents/skills/grill-with-docs/SKILL.md +3 -86
- package/.agents/skills/grilling/SKILL.md +14 -0
- package/.agents/skills/handoff/SKILL.md +2 -1
- package/.agents/skills/i-have-adhd/SKILL.md +120 -0
- package/.agents/skills/implement/SKILL.md +11 -0
- package/.agents/skills/improve-codebase-architecture/HTML-REPORT.md +3 -3
- package/.agents/skills/improve-codebase-architecture/SKILL.md +13 -28
- package/.agents/skills/loop-me/SKILL.md +32 -0
- package/.agents/skills/prototype/SKILL.md +1 -1
- package/.agents/skills/qa/SKILL.md +130 -0
- package/.agents/skills/request-refactor-plan/SKILL.md +68 -0
- package/.agents/skills/research/SKILL.md +12 -0
- package/.agents/skills/resolving-merge-conflicts/SKILL.md +14 -0
- package/.agents/skills/scaffold-exercises/SKILL.md +106 -0
- package/.agents/skills/setup-matt-pocock-skills/SKILL.md +11 -9
- package/.agents/skills/setup-matt-pocock-skills/domain.md +2 -2
- package/.agents/skills/setup-matt-pocock-skills/issue-tracker-github.md +23 -0
- package/.agents/skills/setup-matt-pocock-skills/issue-tracker-gitlab.md +23 -0
- package/.agents/skills/setup-matt-pocock-skills/issue-tracker-local.md +11 -0
- package/.agents/skills/skill-creator/LICENSE.txt +202 -0
- package/.agents/skills/skill-creator/SKILL.md +485 -0
- package/.agents/skills/skill-creator/agents/analyzer.md +274 -0
- package/.agents/skills/skill-creator/agents/comparator.md +202 -0
- package/.agents/skills/skill-creator/agents/grader.md +223 -0
- package/.agents/skills/skill-creator/assets/eval_review.html +146 -0
- package/.agents/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/.agents/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.agents/skills/skill-creator/references/schemas.md +430 -0
- package/.agents/skills/skill-creator/scripts/__init__.py +0 -0
- package/.agents/skills/skill-creator/scripts/__pycache__/__init__.cpython-314.pyc +0 -0
- package/.agents/skills/skill-creator/scripts/__pycache__/run_eval.cpython-314.pyc +0 -0
- package/.agents/skills/skill-creator/scripts/__pycache__/utils.cpython-314.pyc +0 -0
- package/.agents/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/.agents/skills/skill-creator/scripts/generate_report.py +326 -0
- package/.agents/skills/skill-creator/scripts/improve_description.py +247 -0
- package/.agents/skills/skill-creator/scripts/package_skill.py +136 -0
- package/.agents/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/.agents/skills/skill-creator/scripts/run_eval.py +310 -0
- package/.agents/skills/skill-creator/scripts/run_loop.py +328 -0
- package/.agents/skills/skill-creator/scripts/utils.py +47 -0
- package/.agents/skills/tdd/SKILL.md +17 -90
- package/.agents/skills/tdd/tests.md +16 -0
- package/.agents/skills/teach/GLOSSARY-FORMAT.md +35 -0
- package/.agents/skills/teach/LEARNING-RECORD-FORMAT.md +46 -0
- package/.agents/skills/teach/MISSION-FORMAT.md +31 -0
- package/.agents/skills/teach/RESOURCES-FORMAT.md +32 -0
- package/.agents/skills/teach/SKILL.md +140 -0
- package/.agents/skills/{to-prd → to-spec}/SKILL.md +11 -12
- package/.agents/skills/to-tickets/SKILL.md +114 -0
- package/.agents/skills/triage/AGENT-BRIEF.md +40 -1
- package/.agents/skills/triage/OUT-OF-SCOPE.md +5 -1
- package/.agents/skills/triage/SKILL.md +20 -11
- package/.agents/skills/wayfinder/SKILL.md +127 -0
- package/.agents/skills/writing-great-skills/GLOSSARY.md +201 -0
- package/.agents/skills/writing-great-skills/SKILL.md +83 -0
- package/.agents/superpowers-agent +103 -222
- package/.agents/superpowers-bootstrap.md +3 -3
- package/.agents/templates/AGENTS.md.template +11 -34
- package/.agents/templates/SUPERPOWERS.md.template +4 -4
- package/.github/copilot-instructions.md +23 -99
- package/.github/hooks/rtk-rewrite.json +22 -0
- package/AGENTS.md +7 -6
- package/README.md +53 -174
- package/package.json +2 -2
- package/skills/collaboration/brainstorming/SKILL.md +39 -139
- package/skills/collaboration/brainstorming/skill.json +2 -2
- package/skills/collaboration/leveraging-cli-tools/SKILL.md +70 -71
- package/skills/collaboration/leveraging-cli-tools/references/copilot-instructions.md +30 -0
- package/skills/collaboration/leveraging-cli-tools/scripts/setup-ponytail.sh +185 -0
- package/skills/collaboration/leveraging-cli-tools/scripts/setup-rtk.sh +217 -0
- package/skills/collaboration/leveraging-cli-tools/skill.json +1 -1
- package/skills/meta/create-skill-json/SKILL.md +4 -4
- package/skills/meta/create-skill-json/skill.json +1 -1
- package/skills/meta/create-skill-json/test-scenarios.md +1 -1
- package/skills/setup-skills/SKILL.md +18 -11
- package/skills/setup-skills/skill.json +8 -0
- package/.agents/skills/caveman/SKILL.md +0 -49
- package/.agents/skills/improve-codebase-architecture/LANGUAGE.md +0 -53
- package/.agents/skills/karpathy-guidelines/SKILL.md +0 -75
- package/.agents/skills/review/SKILL.md +0 -78
- package/.agents/skills/tdd/deep-modules.md +0 -33
- package/.agents/skills/tdd/interface-design.md +0 -31
- package/.agents/skills/tdd/refactoring.md +0 -10
- package/.agents/skills/to-issues/SKILL.md +0 -83
- package/.agents/skills/zoom-out/SKILL.md +0 -7
- package/skills/architecture/ABOUT.md +0 -20
- package/skills/architecture/preserving-productive-tensions/SKILL.md +0 -146
- package/skills/architecture/preserving-productive-tensions/skill.json +0 -9
- package/skills/collaboration/brainstorming/spec-document-reviewer-prompt.md +0 -50
- package/skills/collaboration/brainstorming/visual-companion.md +0 -277
- package/skills/collaboration/dispatching-parallel-agents/SKILL.md +0 -174
- package/skills/collaboration/dispatching-parallel-agents/skill.json +0 -9
- package/skills/collaboration/executing-plans/SKILL.md +0 -130
- package/skills/collaboration/executing-plans/skill.json +0 -9
- package/skills/collaboration/finishing-a-development-branch/SKILL.md +0 -261
- package/skills/collaboration/finishing-a-development-branch/skill.json +0 -9
- package/skills/collaboration/leveraging-cli-tools/scripts/slim.py +0 -167
- package/skills/collaboration/receiving-code-review/SKILL.md +0 -233
- package/skills/collaboration/receiving-code-review/skill.json +0 -9
- package/skills/collaboration/requesting-code-review/SKILL.md +0 -110
- package/skills/collaboration/requesting-code-review/code-reviewer.md +0 -146
- package/skills/collaboration/requesting-code-review/skill.json +0 -12
- package/skills/collaboration/subagent-driven-development/SKILL.md +0 -255
- package/skills/collaboration/subagent-driven-development/code-quality-reviewer-prompt.md +0 -26
- package/skills/collaboration/subagent-driven-development/implementer-prompt.md +0 -113
- package/skills/collaboration/subagent-driven-development/skill.json +0 -15
- package/skills/collaboration/subagent-driven-development/spec-reviewer-prompt.md +0 -61
- package/skills/collaboration/using-git-worktrees/SKILL.md +0 -366
- package/skills/collaboration/using-git-worktrees/skill.json +0 -9
- package/skills/collaboration/writing-plans/SKILL.md +0 -121
- package/skills/collaboration/writing-plans/plan-document-reviewer-prompt.md +0 -52
- package/skills/collaboration/writing-plans/skill.json +0 -9
- package/skills/debugging/defense-in-depth/SKILL.md +0 -380
- package/skills/debugging/defense-in-depth/skill.json +0 -9
- package/skills/debugging/root-cause-tracing/SKILL.md +0 -361
- package/skills/debugging/root-cause-tracing/find-polluter.sh +0 -63
- package/skills/debugging/root-cause-tracing/skill.json +0 -12
- package/skills/debugging/systematic-debugging/SKILL.md +0 -299
- package/skills/debugging/systematic-debugging/condition-based-waiting-example.ts +0 -158
- package/skills/debugging/systematic-debugging/condition-based-waiting.md +0 -115
- package/skills/debugging/systematic-debugging/defense-in-depth.md +0 -122
- package/skills/debugging/systematic-debugging/find-polluter.sh +0 -63
- package/skills/debugging/systematic-debugging/root-cause-tracing.md +0 -169
- package/skills/debugging/systematic-debugging/skill.json +0 -9
- package/skills/debugging/systematic-debugging/test-academic.md +0 -14
- package/skills/debugging/systematic-debugging/test-pressure-1.md +0 -58
- package/skills/debugging/systematic-debugging/test-pressure-2.md +0 -68
- package/skills/debugging/systematic-debugging/test-pressure-3.md +0 -69
- package/skills/debugging/verification-before-completion/SKILL.md +0 -143
- package/skills/debugging/verification-before-completion/skill.json +0 -9
- package/skills/finding-skills/SKILL.md +0 -101
- package/skills/finding-skills/skill.json +0 -8
- package/skills/meta/create-agents-md/SKILL.md +0 -182
- package/skills/meta/create-agents-md/skill.json +0 -9
- package/skills/meta/creating-prompts/SKILL.md +0 -349
- package/skills/meta/creating-prompts/examples/do-example.md +0 -65
- package/skills/meta/creating-prompts/examples/plan-example.md +0 -75
- package/skills/meta/creating-prompts/examples/refine-example.md +0 -65
- package/skills/meta/creating-prompts/examples/research-example.md +0 -63
- package/skills/meta/creating-prompts/scripts/get-next-number.sh +0 -27
- package/skills/meta/creating-prompts/skill.json +0 -20
- package/skills/meta/creating-prompts/templates/do-template.md +0 -59
- package/skills/meta/creating-prompts/templates/plan-template.md +0 -58
- package/skills/meta/creating-prompts/templates/refine-template.md +0 -54
- package/skills/meta/creating-prompts/templates/research-template.md +0 -56
- package/skills/meta/using-superpowers/SKILL.md +0 -108
- package/skills/meta/using-superpowers/skill.json +0 -5
- package/skills/meta/writing-prompts/SKILL.md +0 -122
- package/skills/meta/writing-prompts/references/platforms.md +0 -114
- package/skills/meta/writing-prompts/skill.json +0 -9
- package/skills/problem-solving/ABOUT.md +0 -40
- package/skills/problem-solving/collision-zone-thinking/SKILL.md +0 -188
- package/skills/problem-solving/collision-zone-thinking/references/historical-examples.md +0 -393
- package/skills/problem-solving/collision-zone-thinking/skill.json +0 -9
- package/skills/problem-solving/inversion-exercise/SKILL.md +0 -174
- package/skills/problem-solving/inversion-exercise/skill.json +0 -9
- package/skills/problem-solving/meta-pattern-recognition/SKILL.md +0 -116
- package/skills/problem-solving/meta-pattern-recognition/skill.json +0 -9
- package/skills/problem-solving/scale-game/SKILL.md +0 -222
- package/skills/problem-solving/scale-game/skill.json +0 -9
- package/skills/problem-solving/simplification-cascades/SKILL.md +0 -113
- package/skills/problem-solving/simplification-cascades/skill.json +0 -9
- package/skills/problem-solving/when-stuck/SKILL.md +0 -69
- package/skills/problem-solving/when-stuck/skill.json +0 -9
- package/skills/research/ABOUT.md +0 -20
- package/skills/research/tracing-knowledge-lineages/SKILL.md +0 -241
- package/skills/research/tracing-knowledge-lineages/skill.json +0 -9
- package/skills/testing/condition-based-waiting/SKILL.md +0 -359
- package/skills/testing/condition-based-waiting/example.ts +0 -158
- package/skills/testing/condition-based-waiting/skill.json +0 -12
- package/skills/testing/test-driven-development/SKILL.md +0 -434
- package/skills/testing/test-driven-development/skill.json +0 -9
- package/skills/testing/testing-anti-patterns/SKILL.md +0 -298
- package/skills/testing/testing-anti-patterns/skill.json +0 -9
- package/skills/testing/verification-before-completion/SKILL.md +0 -246
- package/skills/testing/verification-before-completion/skill.json +0 -10
- package/skills/using-a-skill/SKILL.md +0 -101
- package/skills/using-a-skill/skill.json +0 -8
- /package/.agents/skills/{diagnose → diagnosing-bugs}/scripts/hitl-loop.template.sh +0 -0
- /package/.agents/skills/{grill-with-docs → domain-modeling}/ADR-FORMAT.md +0 -0
|
@@ -1,111 +1,110 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: leveraging-cli-tools
|
|
3
|
-
description: Use when performing code searches, JSON/YAML parsing, file finding, structural refactors, or data wrangling, or when a command
|
|
4
|
-
compatibility: The bundled scripts/slim.py needs python3 (standard on macOS/Linux). The CLI tools install via the system package manager.
|
|
3
|
+
description: Use when performing code searches, JSON/YAML parsing, file finding, structural refactors, or data wrangling, or when a command could flood context with verbose output like logs, CI runs, test output, or git/docker status dumps. Routes agents to `rtk` (Rust Token Killer), a token-optimized CLI proxy that wraps ripgrep, jq, git, gh, test runners, and more, and to `ponytail` for lazy-solution discipline — instead of reaching for raw grep/find/sed/awk or a per-tool checklist. Also sets up rtk and ponytail for the current harness if either isn't configured yet.
|
|
5
4
|
---
|
|
6
5
|
|
|
7
6
|
# Leveraging CLI Tools
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
The leverage is filtering and transforming with the right tool **before reading**, so tokens and time go to the answer, not the search. `rtk` is the single entry point for that: it wraps the high-performance CLI tools (ripgrep, jq, git, gh, test runners, and more) and returns token-optimized output automatically, and `rtk proxy` reaches anything it doesn't wrap. `ponytail` supplies the "laziest solution that works" discipline alongside it.
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
**This supersedes the old approach of memorizing a table of ~16 individual tools (`rg`, `jq`, `fd`, `yq`, `ast-grep`, `sd`, …) and reaching for each one raw.** If you find yourself reconstructing that table from memory, stop — reach for `rtk <tool>` instead, and `rtk proxy <tool>` for anything `rtk` doesn't wrap directly.
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
## Setup rtk
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
Before relying on `rtk`, verify it's configured for the current harness:
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
```bash
|
|
17
|
+
bash scripts/setup-rtk.sh
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
(relative to this skill directory — use the absolute path if you're working elsewhere). This script only **checks and reports**; it never changes anything by itself. It:
|
|
21
|
+
|
|
22
|
+
1. Detects the current harness (Claude Code, OpenCode, pi, codex, GitHub Copilot).
|
|
23
|
+
2. Checks whether `rtk` is installed and wired into that harness's config (e.g. `rtk init --show` for Claude Code; the harness-specific config file for others).
|
|
24
|
+
3. If everything is already `[ok]`, does nothing further — you're set, move on.
|
|
25
|
+
4. If something's missing, prints the exact command(s) it would run to fix it (e.g. `rtk init --auto-patch`, `rtk init -g --auto-patch`, `rtk init -g --opencode`, `rtk init --codex`).
|
|
26
|
+
|
|
27
|
+
Anything the script reports missing is a **global or repo-config change** — never run the fix command on your own initiative. Surface the report and the exact command(s) to the user and get their confirmation first (see "Ask before you act" below). If the fix touches Claude Code's own config, tell the user to restart Claude Code afterward so the new config is picked up.
|
|
20
28
|
|
|
21
|
-
|
|
29
|
+
## Setup ponytail
|
|
30
|
+
|
|
31
|
+
Same check → report → confirm pattern, for the `ponytail` discipline skill:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bash scripts/setup-ponytail.sh
|
|
35
|
+
```
|
|
22
36
|
|
|
23
|
-
|
|
37
|
+
It checks that `ponytail` is installed for the current harness (marketplace/plugin/package presence) and that `~/.config/ponytail/config.json` exists. If the config is missing, it offers to create it with `defaultMode: full` — it only ever creates an absent file, it never edits or overwrites one that already exists. Confirm the offered command with the user, same as rtk setup, before it runs.
|
|
24
38
|
|
|
25
|
-
|
|
26
|
-
|:------:|------|----------|-----|---------|
|
|
27
|
-
| 10 | `rg` (ripgrep) | `grep`, `grep -r`, `ack` | Code/text search. Respects `.gitignore`, 10-50x faster than `grep` — the highest-leverage tool; filter before reading. | `brew install ripgrep` |
|
|
28
|
-
| 10 | `jq` | `grep`/`sed`/`awk` on JSON | JSON query/transform. Turns API responses and config into exactly the fields you need; the pipe target for JSON. | `brew install jq` |
|
|
29
|
-
| 9 | `fd` | `find` | File finding. Faster, saner syntax, parallel traversal, `.gitignore`-aware. | `brew install fd` |
|
|
30
|
-
| 8 | `yq` | `grep`/`sed`/`awk` on YAML | `jq` for YAML/TOML/XML. Reads CI files, `docker-compose`, k8s manifests, frontmatter. | `brew install yq` |
|
|
31
|
-
| 8 | `ast-grep` (`sg`) | `sed`/`grep` for refactors | Structural search/rewrite by AST, not regex. Safe codebase-wide refactors that `sed` would mangle. | `brew install ast-grep` |
|
|
32
|
-
| 8 | `gh` | `curl` + GitHub API + tokens | GitHub from the shell — PRs, issues, CI, API. No hand-rolled `curl` + token juggling. | `brew install gh` |
|
|
33
|
-
| 7 | `sd` | `sed -i`, `perl -pe` | Find/replace. Literal-string-safe, no regex-escaping footguns. | `brew install sd` |
|
|
34
|
-
| 6 | `dasel` | `jq`+`yq`+`xq` (mixed formats) | Query *and modify* JSON/YAML/TOML/XML/CSV through one selector. Use when format is mixed or unknown. | `brew install dasel` |
|
|
35
|
-
| 6 | `htmlq` | `grep`/`sed` on HTML | `jq` for HTML — CSS-selector extraction from fetched pages. | `brew install htmlq` |
|
|
36
|
-
| 6 | `miller` (`mlr`) | `awk`/`cut`/`join`/`sort` on CSV/TSV | `awk`/`cut`/`join`/`sort` for CSV/TSV/JSON with *named* fields — no brittle column counting. | `brew install miller` |
|
|
37
|
-
| 5 | `qsv` | `awk`/`cut`/`sort -u` on CSV, `csvkit` | High-perf CSV toolkit (maintained `xsv` successor). Stats, slice, join, dedup on big CSVs. | `brew install qsv` |
|
|
38
|
-
| 5 | `hyperfine` | `time`, `for`-loop timing | Statistical benchmarking with warmups. Real before/after numbers, not `time` guesses. | `brew install hyperfine` |
|
|
39
|
-
| 5 | `tokei` | `wc -l`, `find … \| wc`, `cloc` | Instant LOC/language breakdown. Orient in an unfamiliar repo before exploring. | `brew install tokei` |
|
|
40
|
-
| 5 | `fzf` (`-f`) | manual fuzzy filtering | Non-interactive `-f`/`--filter` mode: fuzzy-rank a candidate list piped from `fd`/`rg`. | `brew install fzf` |
|
|
41
|
-
| 4 | `watchexec` | `while`+`sleep`, `entr` | Run a command on file change. Useful in build/test loops; non-interactive unlike most watchers. | `brew install watchexec` |
|
|
39
|
+
On GitHub Copilot, also check whether this repo's `.github/copilot-instructions.md` already carries the rtk + ponytail instructions. If not, `references/copilot-instructions.md` (bundled with this skill) is the source of truth to append — offer that too, and confirm before writing.
|
|
42
40
|
|
|
43
|
-
|
|
41
|
+
### Ask before you act
|
|
44
42
|
|
|
45
|
-
|
|
43
|
+
Any setup step that touches global or machine state — installing a package, writing outside this task's working files, editing a config in `$HOME` — gets surfaced and confirmed, never run silently. Ask with whichever question tool your harness exposes: `askUserQuestion`, `ask_user_question`, `askQuestions`, or `question`. Same rule elsewhere in this skill: when you're unsure whether a change is welcome, ask instead of guessing.
|
|
46
44
|
|
|
47
|
-
|
|
45
|
+
## Use rtk with discipline
|
|
46
|
+
|
|
47
|
+
Picking `rtk` is only half of it. The other half is using it with discipline — the same habits that used to be spread across a dozen raw tools, now aimed at `rtk`'s subcommands.
|
|
48
|
+
|
|
49
|
+
**1 — Reach for `rtk <tool>` for the data's shape, not a raw tool from muscle memory.** Code/text search → `rtk rg`, JSON → `rtk jq`, git/gh → `rtk git` / `rtk gh`, verbose command output (tests, CI, builds) → the matching `rtk` wrapper (`rtk cargo test`, `rtk playwright test`, `rtk jest`, …). The reflex to resist is reaching for `grep`/`sed`/`awk` on structured data, or a raw tool `rtk` already wraps — both throw away the reduction `rtk` gives you for free.
|
|
50
|
+
|
|
51
|
+
**Prefer `rtk rg` over `rtk grep`.** They cover the same ground, but `rtk rg` runs ripgrep underneath and is faster and more efficient — use it as the default for code/text search.
|
|
52
|
+
|
|
53
|
+
**This includes interpreters and runners you'd otherwise call bare.** Run scripts through `rtk` too — `rtk python script.py`, `rtk python -c '...'` (and likewise `rtk node …`) — so their output stays inside the same token-optimized, usage-tracked invocation instead of dropping to raw `python3`/`node`.
|
|
48
54
|
|
|
49
55
|
**2 — Ask for less: use the flag or selector that returns the answer's _shape_.** The biggest single win is never pulling raw output into context. Match the request to the question:
|
|
50
56
|
|
|
51
|
-
| Question |
|
|
52
|
-
|
|
53
|
-
| Which files match? | `rg -l` | paths only, no lines |
|
|
54
|
-
| How many files? | `rg -l \| wc -l` | a file count, not a line count |
|
|
55
|
-
| How many hits? | `rg -c` (lines/file) / `rg --count-matches` (matches/file) | counts only |
|
|
56
|
-
| Just the matched bit? | `rg -o` | the substring, not the whole line |
|
|
57
|
-
| Enough to judge a hit? | `rg -A/-B/-C N`, `rg -m N` (cap per file) | bounded context |
|
|
58
|
-
| Only certain fields? | `jq -r '.a, .b'
|
|
59
|
-
|
|
|
57
|
+
| Question | Command | Returns |
|
|
58
|
+
|----------|---------|---------|
|
|
59
|
+
| Which files match? | `rtk rg -l` | paths only, no lines |
|
|
60
|
+
| How many files? | `rtk rg -l \| wc -l` | a file count, not a line count |
|
|
61
|
+
| How many hits? | `rtk rg -c` (lines/file) / `rtk rg --count-matches` (matches/file) | counts only |
|
|
62
|
+
| Just the matched bit? | `rtk rg -o` | the substring, not the whole line |
|
|
63
|
+
| Enough to judge a hit? | `rtk rg -A/-B/-C N`, `rtk rg -m N` (cap per file) | bounded context |
|
|
64
|
+
| Only certain fields? | `rtk jq -r '.a, .b'` | projected values, not the whole doc |
|
|
65
|
+
| Which files, by dir? | `rtk find <pattern>` | paths grouped by directory |
|
|
66
|
+
| Only the errors? | `rtk err <cmd>` | filtered stderr/error lines |
|
|
60
67
|
|
|
61
|
-
|
|
68
|
+
Shape output at the selector; never pull the whole thing into context and filter it by eye.
|
|
62
69
|
|
|
63
70
|
**3 — Compose so only the answer comes back.** Do the counting, dedup, and projection *in the pipeline*, not by reading raw output and reasoning over it. One pass keeps every intermediate result out of context:
|
|
64
71
|
```bash
|
|
65
|
-
rg -l '"error"' logs/ --type json | xargs jq -r 'select(.level=="error") | .code' | sort -u
|
|
66
|
-
```
|
|
67
|
-
This is the lesson of programmatic tool calling (Amazon's PTC benchmarks: ~87-92% fewer tokens): when a task needs several tool calls plus processing, write **one** pipeline or script that does it all and returns only the result — the intermediate data never touches your context. So: filter before reading, and refactor by AST, not regex:
|
|
68
|
-
```bash
|
|
69
|
-
rg -l "password.*hash" src/auth/ --type ts | xargs rg "TODO"
|
|
70
|
-
sg --pattern 'console.log($$$A)' --rewrite 'logger.debug($$$A)' --lang ts
|
|
72
|
+
rtk rg -l '"error"' logs/ --type json | xargs rtk jq -r 'select(.level=="error") | .code' | sort -u
|
|
71
73
|
```
|
|
74
|
+
When a task needs several tool calls plus processing, write **one** pipeline that does it all and returns only the result — the intermediate data never touches your context.
|
|
72
75
|
|
|
73
|
-
**4 —
|
|
74
|
-
```bash
|
|
75
|
-
gh run view --log | python3 scripts/slim.py --errors --uniq --max-line 200
|
|
76
|
-
cargo test 2>&1 | python3 scripts/slim.py --errors --dedup
|
|
77
|
-
rg -n TODO --no-ignore | python3 scripts/slim.py --group-dir
|
|
78
|
-
```
|
|
79
|
-
It does dedup (`--dedup`/`--uniq`, repeats collapse to `(xN)`), grouping (`--group-dir` → per-directory counts), truncation (`--head/--tail/--middle/--max-line`), and noise-stripping (`--comments/--errors/--grep`). On a real 1,236-line CI log, `rg` error-filtering alone cut 91% but left ~6,700 tokens; adding `slim` reached 97% — a third the residual. Run `python3 scripts/slim.py -h` for all modes. The cuts are **lossy and opt-in**: ask for what you need, know what you're discarding, and don't reach for it when a projection tool's own selector would do the job.
|
|
76
|
+
**4 — When `rtk` has no wrapper for a tool, use `rtk proxy <cmd>` instead of the raw command.** `rtk proxy` runs anything raw while keeping it inside the same invocation pattern — e.g. `rtk proxy ast-grep --pattern '...' --lang ts`, `rtk proxy yq '.services' docker-compose.yml`, `rtk proxy sd 'old' 'new' file.ts`. Reach for `rtk <tool>` first; fall back to `rtk proxy <tool>` only when `rtk` doesn't wrap it.
|
|
80
77
|
|
|
81
|
-
**5 — Read the output critically — it's a claim, not a fact.** A zero or suspiciously low result is the one to distrust: `rg`
|
|
78
|
+
**5 — Read the output critically — it's a claim, not a fact.** A zero or suspiciously low result is the one to distrust: `rtk rg` respects `.gitignore`/`.ignore` by default, so a real match in `node_modules/`, `dist/`, or a dotfile is silently absent. Before concluding "no matches," re-run with `--no-ignore` (or `-u`/`-uu`/`--hidden`) — then decide whether those ignored hits (vendored deps, build output, generated mirrors) actually belong in the answer; surfacing them is the check, keeping them is a judgment call. Mind case (`-i`) and word boundaries (`-w`) so you neither miss a hit nor over-match a common word.
|
|
82
79
|
|
|
83
|
-
In Claude Code the `Grep` and `Glob` tools are themselves built on ripgrep — prefer them for in-context searches, and reach for the
|
|
80
|
+
In Claude Code the `Grep` and `Glob` tools are themselves built on ripgrep — prefer them for in-context searches, and reach for `rtk` on the command line when you need piping, transforms, rewrites, or output reduction.
|
|
84
81
|
|
|
85
82
|
## Red flags
|
|
86
83
|
|
|
87
|
-
- Parsing JSON/YAML with `awk`/`sed`/`grep` instead of `jq
|
|
88
|
-
- Reading files before filtering them with `rg`.
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
84
|
+
- Parsing JSON/YAML with `awk`/`sed`/`grep` instead of `rtk jq` / `rtk proxy yq`.
|
|
85
|
+
- Reading files before filtering them with `rtk rg`.
|
|
86
|
+
- Reaching for `rtk grep` by habit when `rtk rg` covers the same ground faster.
|
|
87
|
+
- Running a tool raw (`ast-grep`, `yq`, `sd`, …) when `rtk proxy <tool>` would give the same result inside the standard invocation pattern.
|
|
88
|
+
- Running an interpreter raw (`python3`, `node`, …) when `rtk python` / `rtk node` would keep it inside rtk's optimized invocation.
|
|
89
|
+
- Piping a command's full output into context to eyeball it, when `-l`/`-c`/`-o` or a `rtk jq` projection would return just the answer.
|
|
90
|
+
- Concluding "no matches" from a default `rtk rg` run without re-checking `--no-ignore`/`--hidden` — the hit may be sitting in an ignored directory.
|
|
91
|
+
- Hand-rolling `curl` against the GitHub API instead of `rtk gh`.
|
|
92
|
+
- Reconstructing the old 16-tool table from memory instead of reaching for `rtk`.
|
|
93
|
+
- Running a setup fix (`rtk init --auto-patch`, creating `~/.config/ponytail/config.json`, etc.) without confirming with the user first.
|
|
95
94
|
|
|
96
95
|
## Common rationalizations
|
|
97
96
|
|
|
98
97
|
| Excuse | Reality |
|
|
99
98
|
|--------|---------|
|
|
100
|
-
| "grep works fine" | On a big tree it's 10-50x slower and floods context with noise `rg` would have filtered out. |
|
|
101
|
-
| "I don't know if
|
|
102
|
-
| "Not worth the setup" | One
|
|
103
|
-
| "The test/CI output is just long, I'll scroll it" |
|
|
99
|
+
| "grep works fine" | On a big tree it's 10-50x slower and floods context with noise `rtk rg` would have filtered out. |
|
|
100
|
+
| "I don't know if rtk is set up" | `bash scripts/setup-rtk.sh` answers it in one check; fixing it pays back across the whole session. |
|
|
101
|
+
| "Not worth the setup" | One confirmed fix = a speedup on every future task, not just this one. |
|
|
102
|
+
| "The test/CI output is just long, I'll scroll it" | `rtk`'s wrappers (`rtk cargo test`, `rtk playwright test`, …) cut that noise automatically — scrolling raw output throws that away. |
|
|
103
|
+
| "This tool isn't in rtk's table, I'll just run it raw" | `rtk proxy <tool>` runs it inside the same pattern — no need to drop back to the bare command. |
|
|
104
104
|
| "User didn't ask for optimization" | Faster, lower-noise completion *is* better completion. |
|
|
105
105
|
|
|
106
106
|
## When NOT to use
|
|
107
107
|
|
|
108
|
-
-
|
|
109
|
-
- The user declined the install — note the cost once, then use the fallback.
|
|
108
|
+
- The user declined an rtk/ponytail setup fix — note it once, then fall back to the raw tool and move on.
|
|
110
109
|
- A teaching context where the standard tool is the point.
|
|
111
|
-
- Output you already shaped with a selector — don't add
|
|
110
|
+
- Output you already shaped with a selector — don't add another reduction pass for its own sake.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Ponytail, lazy senior dev mode
|
|
2
|
+
|
|
3
|
+
You are a lazy senior developer. Lazy means efficient, not careless. The best code is the code never written.
|
|
4
|
+
|
|
5
|
+
Before writing any code, stop at the first rung that holds:
|
|
6
|
+
|
|
7
|
+
1. Does this need to be built at all? (YAGNI)
|
|
8
|
+
2. Does it already exist in this codebase? Reuse the helper, util, or pattern that's already here, don't re-write it.
|
|
9
|
+
3. Does the standard library already do this? Use it.
|
|
10
|
+
4. Does a native platform feature cover it? Use it.
|
|
11
|
+
5. Does an already-installed dependency solve it? Use it.
|
|
12
|
+
6. Can this be one line? Make it one line.
|
|
13
|
+
7. Only then: write the minimum code that works.
|
|
14
|
+
|
|
15
|
+
The ladder runs after you understand the problem, not instead of it: read the task and the code it touches, trace the real flow end to end, then climb.
|
|
16
|
+
|
|
17
|
+
Bug fix = root cause, not symptom: a report names a symptom. Grep every caller of the function you touch and fix the shared function once — one guard there is a smaller diff than one per caller, and patching only the path the ticket names leaves a sibling caller still broken.
|
|
18
|
+
|
|
19
|
+
Rules:
|
|
20
|
+
|
|
21
|
+
- No abstractions that weren't explicitly requested.
|
|
22
|
+
- No new dependency if it can be avoided.
|
|
23
|
+
- No boilerplate nobody asked for.
|
|
24
|
+
- Deletion over addition. Boring over clever. Fewest files possible.
|
|
25
|
+
- Shortest working diff wins, but only once you understand the problem. The smallest change in the wrong place isn't lazy, it's a second bug.
|
|
26
|
+
- Question complex requests: "Do you actually need X, or does Y cover it?"
|
|
27
|
+
- Pick the edge-case-correct option when two stdlib approaches are the same size, lazy means less code, not the flimsier algorithm.
|
|
28
|
+
- Mark deliberate simplifications that cut a real corner with a known ceiling (global lock, O(n²) scan, naive heuristic) with a `ponytail:` comment naming the ceiling and upgrade path.
|
|
29
|
+
|
|
30
|
+
Not lazy about: understanding the problem (read it fully and trace the real flow before picking a rung, a small diff you don't understand is just laziness dressed up as efficiency), input validation at trust boundaries, error handling that prevents data loss, security, accessibility, the calibration real hardware needs (the platform is never the spec ideal, a clock drifts, a sensor reads off), anything explicitly requested. Lazy code without its check is unfinished: non-trivial logic leaves ONE runnable check behind, the smallest thing that fails if the logic breaks (an assert-based demo/self-check or one small test file; no frameworks, no fixtures). Trivial one-liners need no test.
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# setup-ponytail.sh — verify (and optionally install) the ponytail plugin for
|
|
3
|
+
# whichever agent harness is currently running this script.
|
|
4
|
+
#
|
|
5
|
+
# Contract (same as setup-rtk.sh):
|
|
6
|
+
# - Default (no flags): CHECK + REPORT ONLY. Detects the current harness,
|
|
7
|
+
# prints what's installed/missing and the exact command(s) that WOULD
|
|
8
|
+
# run. Changes nothing on disk or in any plugin registry.
|
|
9
|
+
# - `--apply`: actually runs the planned install commands / writes the
|
|
10
|
+
# planned files.
|
|
11
|
+
# - Idempotent, create-if-absent only. Never overwrites an existing file
|
|
12
|
+
# (in particular ~/.config/ponytail/config.json is left untouched once
|
|
13
|
+
# it exists).
|
|
14
|
+
#
|
|
15
|
+
# Usage:
|
|
16
|
+
# scripts/setup-ponytail.sh # check only, changes nothing
|
|
17
|
+
# scripts/setup-ponytail.sh --apply # apply the plan reported above
|
|
18
|
+
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
APPLY=0
|
|
22
|
+
[[ "${1:-}" == "--apply" ]] && APPLY=1
|
|
23
|
+
|
|
24
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
25
|
+
COPILOT_ASSET="$SCRIPT_DIR/../references/copilot-instructions.md"
|
|
26
|
+
GAPS=0
|
|
27
|
+
|
|
28
|
+
ok() { printf ' [ok] %s\n' "$*"; }
|
|
29
|
+
gap() { printf ' [MISSING] %s\n' "$*"; GAPS=$((GAPS + 1)); }
|
|
30
|
+
plan() { printf ' would run: %s\n' "$*"; }
|
|
31
|
+
|
|
32
|
+
# --- detect harness ---------------------------------------------------------
|
|
33
|
+
# Lazy heuristic: env vars first (cheapest, most specific), config dir
|
|
34
|
+
# presence as fallback. Claude Code is checked first since it sets an
|
|
35
|
+
# unambiguous env var even when other harnesses' dirs also exist.
|
|
36
|
+
harness=""
|
|
37
|
+
if [[ -n "${CLAUDECODE:-}" || -n "${CLAUDE_CODE_ENTRYPOINT:-}" ]]; then
|
|
38
|
+
harness="claude"
|
|
39
|
+
elif [[ -n "${CODEX_HOME:-}" || -d "$HOME/.codex" ]]; then
|
|
40
|
+
harness="codex"
|
|
41
|
+
elif [[ -n "${GITHUB_COPILOT_CLI:-}" || -d "$HOME/.copilot" ]]; then
|
|
42
|
+
harness="copilot"
|
|
43
|
+
elif [[ -n "${OPENCODE_MODEL:-}" || -d "$HOME/.config/opencode" ]]; then
|
|
44
|
+
harness="opencode"
|
|
45
|
+
elif [[ -d "$HOME/.pi" ]]; then
|
|
46
|
+
harness="pi"
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
if [[ -z "$harness" ]]; then
|
|
50
|
+
echo "Could not detect a known agent harness (Claude Code, OpenCode, pi, codex, Copilot). Nothing to check."
|
|
51
|
+
exit 0
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
echo "Detected harness: $harness"
|
|
55
|
+
echo
|
|
56
|
+
|
|
57
|
+
case "$harness" in
|
|
58
|
+
claude)
|
|
59
|
+
dir="$HOME/.claude/plugins/marketplaces/ponytail"
|
|
60
|
+
if [[ -d "$dir" ]]; then
|
|
61
|
+
ok "ponytail marketplace present ($dir)"
|
|
62
|
+
else
|
|
63
|
+
gap "ponytail marketplace not found ($dir)"
|
|
64
|
+
plan "claude plugin marketplace add DietrichGebert/ponytail && claude plugin install ponytail@ponytail"
|
|
65
|
+
if [[ $APPLY -eq 1 ]]; then
|
|
66
|
+
claude plugin marketplace add DietrichGebert/ponytail
|
|
67
|
+
claude plugin install ponytail@ponytail
|
|
68
|
+
echo " -> installed. Run /reload-plugins in Claude Code to pick it up."
|
|
69
|
+
fi
|
|
70
|
+
fi
|
|
71
|
+
;;
|
|
72
|
+
|
|
73
|
+
opencode)
|
|
74
|
+
cfg="$HOME/.config/opencode/opencode.json"
|
|
75
|
+
if [[ -f "$cfg" ]] && grep -q '@dietrichgebert/ponytail' "$cfg"; then
|
|
76
|
+
ok "ponytail listed in $cfg"
|
|
77
|
+
else
|
|
78
|
+
gap "ponytail not listed in $cfg"
|
|
79
|
+
plan "add \"@dietrichgebert/ponytail\" to the \"plugins\" array in $cfg"
|
|
80
|
+
if [[ $APPLY -eq 1 ]]; then
|
|
81
|
+
if command -v jq >/dev/null 2>&1 && [[ -f "$cfg" ]]; then
|
|
82
|
+
tmp="$(mktemp)"
|
|
83
|
+
jq '.plugins = ((.plugins // []) + ["@dietrichgebert/ponytail"] | unique)' "$cfg" > "$tmp" && mv "$tmp" "$cfg"
|
|
84
|
+
elif command -v jq >/dev/null 2>&1; then
|
|
85
|
+
mkdir -p "$(dirname "$cfg")"
|
|
86
|
+
printf '{"plugins":["@dietrichgebert/ponytail"]}\n' > "$cfg"
|
|
87
|
+
else
|
|
88
|
+
echo " -> jq not found; edit $cfg manually and add \"@dietrichgebert/ponytail\" to \"plugins\"." >&2
|
|
89
|
+
fi
|
|
90
|
+
echo " -> restart opencode."
|
|
91
|
+
fi
|
|
92
|
+
fi
|
|
93
|
+
;;
|
|
94
|
+
|
|
95
|
+
pi)
|
|
96
|
+
cfg="$HOME/.pi/agent/settings.json"
|
|
97
|
+
if [[ -f "$cfg" ]] && grep -q 'git:github.com/DietrichGebert/ponytail' "$cfg"; then
|
|
98
|
+
ok "ponytail listed in $cfg"
|
|
99
|
+
else
|
|
100
|
+
gap "ponytail not listed in $cfg"
|
|
101
|
+
plan "pi install git:github.com/DietrichGebert/ponytail"
|
|
102
|
+
if [[ $APPLY -eq 1 ]]; then
|
|
103
|
+
pi install git:github.com/DietrichGebert/ponytail
|
|
104
|
+
echo " -> restart pi."
|
|
105
|
+
fi
|
|
106
|
+
fi
|
|
107
|
+
;;
|
|
108
|
+
|
|
109
|
+
codex)
|
|
110
|
+
dir="$HOME/.codex/plugins/cache/ponytail"
|
|
111
|
+
if [[ -d "$dir" ]]; then
|
|
112
|
+
ok "ponytail plugin cache present ($dir)"
|
|
113
|
+
else
|
|
114
|
+
gap "ponytail plugin cache not found ($dir)"
|
|
115
|
+
plan "codex plugin marketplace add DietrichGebert/ponytail && codex plugin add ponytail@ponytail"
|
|
116
|
+
if [[ $APPLY -eq 1 ]]; then
|
|
117
|
+
codex plugin marketplace add DietrichGebert/ponytail
|
|
118
|
+
codex plugin add ponytail@ponytail
|
|
119
|
+
echo " -> restart codex."
|
|
120
|
+
fi
|
|
121
|
+
fi
|
|
122
|
+
;;
|
|
123
|
+
|
|
124
|
+
copilot)
|
|
125
|
+
dir="$HOME/.copilot/installed-plugins/ponytail"
|
|
126
|
+
if [[ -d "$dir" ]]; then
|
|
127
|
+
ok "ponytail plugin present ($dir)"
|
|
128
|
+
else
|
|
129
|
+
gap "ponytail plugin not found ($dir)"
|
|
130
|
+
plan "copilot plugin marketplace add DietrichGebert/ponytail && copilot plugin install ponytail@ponytail"
|
|
131
|
+
if [[ $APPLY -eq 1 ]]; then
|
|
132
|
+
copilot plugin marketplace add DietrichGebert/ponytail
|
|
133
|
+
copilot plugin install ponytail@ponytail
|
|
134
|
+
echo " -> restart copilot."
|
|
135
|
+
fi
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
repo_asset="./.github/copilot-instructions.md"
|
|
139
|
+
if [[ -f "$repo_asset" ]] && grep -q 'Ponytail, lazy senior dev mode' "$repo_asset"; then
|
|
140
|
+
ok "$repo_asset already has ponytail instructions"
|
|
141
|
+
elif [[ -f "$repo_asset" ]]; then
|
|
142
|
+
gap "$repo_asset exists but lacks ponytail instructions"
|
|
143
|
+
plan "append $COPILOT_ASSET to $repo_asset"
|
|
144
|
+
if [[ $APPLY -eq 1 ]]; then
|
|
145
|
+
{ echo; cat "$COPILOT_ASSET"; } >> "$repo_asset"
|
|
146
|
+
fi
|
|
147
|
+
else
|
|
148
|
+
gap "$repo_asset not found"
|
|
149
|
+
plan "create $repo_asset from $COPILOT_ASSET"
|
|
150
|
+
if [[ $APPLY -eq 1 ]]; then
|
|
151
|
+
mkdir -p "$(dirname "$repo_asset")"
|
|
152
|
+
cp "$COPILOT_ASSET" "$repo_asset"
|
|
153
|
+
fi
|
|
154
|
+
fi
|
|
155
|
+
;;
|
|
156
|
+
esac
|
|
157
|
+
|
|
158
|
+
# --- all harnesses: global ponytail config, create-if-absent only ----------
|
|
159
|
+
if [[ -n "${APPDATA:-}" ]]; then
|
|
160
|
+
ponytail_cfg="$APPDATA/ponytail/config.json"
|
|
161
|
+
else
|
|
162
|
+
ponytail_cfg="$HOME/.config/ponytail/config.json"
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
echo
|
|
166
|
+
if [[ -f "$ponytail_cfg" ]]; then
|
|
167
|
+
ok "$ponytail_cfg already exists (left untouched)"
|
|
168
|
+
else
|
|
169
|
+
gap "$ponytail_cfg not found"
|
|
170
|
+
plan "create $ponytail_cfg with {\"defaultMode\":\"full\"}"
|
|
171
|
+
if [[ $APPLY -eq 1 ]]; then
|
|
172
|
+
mkdir -p "$(dirname "$ponytail_cfg")"
|
|
173
|
+
printf '{"defaultMode":"full"}\n' > "$ponytail_cfg"
|
|
174
|
+
echo " -> created $ponytail_cfg"
|
|
175
|
+
fi
|
|
176
|
+
fi
|
|
177
|
+
|
|
178
|
+
echo
|
|
179
|
+
if [[ $GAPS -eq 0 ]]; then
|
|
180
|
+
echo "All ponytail checks passed for harness: $harness."
|
|
181
|
+
elif [[ $APPLY -eq 1 ]]; then
|
|
182
|
+
echo "Applied plan for $GAPS gap(s)."
|
|
183
|
+
else
|
|
184
|
+
echo "$GAPS gap(s) found. Re-run with --apply to fix."
|
|
185
|
+
fi
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# setup-rtk.sh — verify rtk is configured for the current agentic harness.
|
|
3
|
+
#
|
|
4
|
+
# Contract:
|
|
5
|
+
# - Default (no args): CHECK + REPORT only. Detects the harness, prints
|
|
6
|
+
# config status per-check ([ok]/[missing]), and prints the EXACT rtk
|
|
7
|
+
# commands that would fix any gap. Changes NOTHING.
|
|
8
|
+
# - `--apply`: runs the planned fix commands for the DETECTED harness only.
|
|
9
|
+
# Every fix is a call to `rtk init ...`, which is itself create-if-absent
|
|
10
|
+
# and never overwrites existing config, so re-running is always safe.
|
|
11
|
+
# - If the harness can't be determined, every harness is checked read-only
|
|
12
|
+
# and nothing is ever applied (there's no single harness to act on).
|
|
13
|
+
#
|
|
14
|
+
# Usage:
|
|
15
|
+
# scripts/setup-rtk.sh # check + report (safe, default)
|
|
16
|
+
# scripts/setup-rtk.sh --apply # run the planned fix commands
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
APPLY=false
|
|
21
|
+
if [ "${1:-}" = "--apply" ]; then
|
|
22
|
+
APPLY=true
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
if ! command -v rtk >/dev/null 2>&1; then
|
|
26
|
+
echo "[--] rtk is not installed or not on PATH — nothing to check."
|
|
27
|
+
echo " Install rtk first, then re-run this script."
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
32
|
+
PLANNED=()
|
|
33
|
+
|
|
34
|
+
plan() {
|
|
35
|
+
PLANNED+=("$1")
|
|
36
|
+
echo " planned: $1"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
run_planned() {
|
|
40
|
+
for cmd in "${PLANNED[@]}"; do
|
|
41
|
+
echo " running: $cmd"
|
|
42
|
+
eval "$cmd"
|
|
43
|
+
done
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# --- Harness detection -------------------------------------------------
|
|
47
|
+
# Sensible, lazy heuristic: harness-specific env vars first, then config
|
|
48
|
+
# dirs. Order matters — check the most specific/reliable signal first.
|
|
49
|
+
detect_harness() {
|
|
50
|
+
if [ -n "${CLAUDECODE:-}" ] || [ -n "${CLAUDE_CODE_ENTRYPOINT:-}" ]; then
|
|
51
|
+
echo claude; return
|
|
52
|
+
fi
|
|
53
|
+
if [ -n "${CODEX_SANDBOX:-}" ] || [ -n "${CODEX_HOME:-}" ]; then
|
|
54
|
+
echo codex; return
|
|
55
|
+
fi
|
|
56
|
+
if [ -n "${OPENCODE_MODEL:-}" ] || [ -d "$HOME/.config/opencode" ] && [ -n "${OPENCODE_EXPERIMENTAL_MARKDOWN:-}${OPENCODE_BIN_PATH:-}" ]; then
|
|
57
|
+
echo opencode; return
|
|
58
|
+
fi
|
|
59
|
+
if [ -n "${PI_AGENT:-}" ] || [ -n "${PI_HOME:-}" ]; then
|
|
60
|
+
echo pi; return
|
|
61
|
+
fi
|
|
62
|
+
if [ -n "${GITHUB_COPILOT_CLI:-}" ] || [ -n "${COPILOT_AGENT:-}" ]; then
|
|
63
|
+
echo copilot; return
|
|
64
|
+
fi
|
|
65
|
+
echo unknown
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
# --- Per-harness checks -------------------------------------------------
|
|
69
|
+
# Each check prints [ok]/[missing] status lines and calls `plan` for any
|
|
70
|
+
# gap. None of these mutate anything by themselves.
|
|
71
|
+
|
|
72
|
+
check_claude() {
|
|
73
|
+
echo "Claude Code:"
|
|
74
|
+
local show
|
|
75
|
+
show="$(rtk init --show 2>&1)"
|
|
76
|
+
local core global_bad local_bad
|
|
77
|
+
core="$(printf '%s\n' "$show" | grep -E '(Hook:|RTK\.md:|Global \(|Local \(|settings\.json:)' || true)"
|
|
78
|
+
global_bad="$(printf '%s\n' "$core" | grep -v 'Local (' | grep -v '^\[ok\]' || true)"
|
|
79
|
+
local_bad="$(printf '%s\n' "$core" | grep 'Local (' | grep -v '^\[ok\]' || true)"
|
|
80
|
+
|
|
81
|
+
if [ -z "$global_bad" ] && [ -z "$local_bad" ]; then
|
|
82
|
+
echo "$core" | sed 's/^/ /'
|
|
83
|
+
echo " [ok] rtk fully configured for Claude Code"
|
|
84
|
+
return
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
echo "$core" | sed 's/^/ /'
|
|
88
|
+
if [ -n "$global_bad" ]; then
|
|
89
|
+
plan "rtk init -g --auto-patch"
|
|
90
|
+
fi
|
|
91
|
+
if [ -n "$local_bad" ]; then
|
|
92
|
+
plan "rtk init --auto-patch"
|
|
93
|
+
fi
|
|
94
|
+
CLAUDE_NEEDS_RESTART=true
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
check_opencode() {
|
|
98
|
+
echo "OpenCode:"
|
|
99
|
+
local plugin="$HOME/.config/opencode/plugins/rtk.ts"
|
|
100
|
+
if [ -f "$plugin" ]; then
|
|
101
|
+
echo " [ok] plugin installed ($plugin)"
|
|
102
|
+
else
|
|
103
|
+
echo " [missing] plugin not found ($plugin)"
|
|
104
|
+
plan "rtk init -g --opencode"
|
|
105
|
+
fi
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
check_pi() {
|
|
109
|
+
echo "pi:"
|
|
110
|
+
local ext="$HOME/.pi/agent/extensions/rtk.ts"
|
|
111
|
+
local repo_rtk="$REPO_ROOT/RTK.md"
|
|
112
|
+
if [ -f "$ext" ]; then
|
|
113
|
+
echo " [ok] extension installed ($ext)"
|
|
114
|
+
else
|
|
115
|
+
echo " [missing] extension not found ($ext)"
|
|
116
|
+
plan "rtk init -g --agent pi"
|
|
117
|
+
fi
|
|
118
|
+
if [ -f "$repo_rtk" ]; then
|
|
119
|
+
echo " [ok] repo RTK.md present ($repo_rtk)"
|
|
120
|
+
else
|
|
121
|
+
echo " [missing] repo RTK.md not found ($repo_rtk)"
|
|
122
|
+
plan "rtk init --codex"
|
|
123
|
+
fi
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
check_codex() {
|
|
127
|
+
echo "codex:"
|
|
128
|
+
local codex_home="${CODEX_HOME:-$HOME/.codex}"
|
|
129
|
+
local global_rtk="$codex_home/RTK.md"
|
|
130
|
+
local repo_rtk="$REPO_ROOT/RTK.md"
|
|
131
|
+
if [ -f "$global_rtk" ]; then
|
|
132
|
+
echo " [ok] global RTK.md present ($global_rtk)"
|
|
133
|
+
else
|
|
134
|
+
echo " [missing] global RTK.md not found ($global_rtk)"
|
|
135
|
+
plan "rtk init -g --codex"
|
|
136
|
+
fi
|
|
137
|
+
if [ -f "$repo_rtk" ]; then
|
|
138
|
+
echo " [ok] repo RTK.md present ($repo_rtk)"
|
|
139
|
+
else
|
|
140
|
+
echo " [missing] repo RTK.md not found ($repo_rtk)"
|
|
141
|
+
plan "rtk init --codex"
|
|
142
|
+
fi
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
check_copilot() {
|
|
146
|
+
echo "GitHub Copilot:"
|
|
147
|
+
local global_hook="$HOME/.copilot/hooks/rtk-rewrite.json"
|
|
148
|
+
local repo_hook="$REPO_ROOT/.github/hooks/rtk-rewrite.json"
|
|
149
|
+
if [ -f "$global_hook" ]; then
|
|
150
|
+
echo " [ok] global hook present ($global_hook)"
|
|
151
|
+
else
|
|
152
|
+
echo " [missing] global hook not found ($global_hook)"
|
|
153
|
+
plan "rtk init -g --copilot"
|
|
154
|
+
fi
|
|
155
|
+
if [ -f "$repo_hook" ]; then
|
|
156
|
+
echo " [ok] repo hook present ($repo_hook)"
|
|
157
|
+
else
|
|
158
|
+
echo " [missing] repo hook not found ($repo_hook)"
|
|
159
|
+
plan "rtk init --copilot"
|
|
160
|
+
fi
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# --- Main ----------------------------------------------------------------
|
|
164
|
+
CLAUDE_NEEDS_RESTART=false
|
|
165
|
+
HARNESS="$(detect_harness)"
|
|
166
|
+
|
|
167
|
+
case "$HARNESS" in
|
|
168
|
+
claude)
|
|
169
|
+
echo "Detected harness: Claude Code"
|
|
170
|
+
check_claude
|
|
171
|
+
;;
|
|
172
|
+
opencode)
|
|
173
|
+
echo "Detected harness: OpenCode"
|
|
174
|
+
check_opencode
|
|
175
|
+
;;
|
|
176
|
+
pi)
|
|
177
|
+
echo "Detected harness: pi"
|
|
178
|
+
check_pi
|
|
179
|
+
;;
|
|
180
|
+
codex)
|
|
181
|
+
echo "Detected harness: codex"
|
|
182
|
+
check_codex
|
|
183
|
+
;;
|
|
184
|
+
copilot)
|
|
185
|
+
echo "Detected harness: GitHub Copilot"
|
|
186
|
+
check_copilot
|
|
187
|
+
;;
|
|
188
|
+
unknown)
|
|
189
|
+
echo "Harness could not be determined — checking all harnesses read-only."
|
|
190
|
+
check_claude
|
|
191
|
+
check_opencode
|
|
192
|
+
check_pi
|
|
193
|
+
check_codex
|
|
194
|
+
check_copilot
|
|
195
|
+
echo
|
|
196
|
+
echo "No single harness detected, so nothing can be applied automatically."
|
|
197
|
+
echo "Re-run on the target machine/agent, or configure manually with the commands above."
|
|
198
|
+
exit 0
|
|
199
|
+
;;
|
|
200
|
+
esac
|
|
201
|
+
|
|
202
|
+
echo
|
|
203
|
+
if [ "${#PLANNED[@]}" -eq 0 ]; then
|
|
204
|
+
echo "rtk is already configured for $HARNESS. Nothing to do."
|
|
205
|
+
exit 0
|
|
206
|
+
fi
|
|
207
|
+
|
|
208
|
+
if [ "$APPLY" = true ]; then
|
|
209
|
+
echo "Applying fixes for $HARNESS..."
|
|
210
|
+
run_planned
|
|
211
|
+
if [ "$HARNESS" = "claude" ] && [ "$CLAUDE_NEEDS_RESTART" = true ]; then
|
|
212
|
+
echo
|
|
213
|
+
echo "rtk config changed for Claude Code — please restart Claude Code to pick it up."
|
|
214
|
+
fi
|
|
215
|
+
else
|
|
216
|
+
echo "Run again with --apply to execute the planned command(s) above."
|
|
217
|
+
fi
|