@toolu/opencode 6.8.0
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/generated/GENERATED-NOTES.md +16 -0
- package/generated/agents/toolu--architect.md +52 -0
- package/generated/agents/toolu--deep-explore.md +65 -0
- package/generated/agents/toolu--implementer.md +50 -0
- package/generated/agents/toolu--quick-task.md +54 -0
- package/generated/agents/toolu--research-agent.md +101 -0
- package/generated/commands/toolu--commit.md +8 -0
- package/generated/commands/toolu--review-and-commit.md +8 -0
- package/generated/opencode.toolu.json +116 -0
- package/generated/skills/toolu--brainstorm/SKILL.md +57 -0
- package/generated/skills/toolu--brainstorm/references/design-questions.md +36 -0
- package/generated/skills/toolu--commit--skill/SKILL.md +11 -0
- package/generated/skills/toolu--debug/SKILL.md +54 -0
- package/generated/skills/toolu--deep-research/SKILL.md +51 -0
- package/generated/skills/toolu--execution/SKILL.md +77 -0
- package/generated/skills/toolu--orchestrator/SKILL.md +145 -0
- package/generated/skills/toolu--orchestrator/references/delegation-cost.md +104 -0
- package/generated/skills/toolu--orchestrator/references/model-routing.md +112 -0
- package/generated/skills/toolu--plan/SKILL.md +56 -0
- package/generated/skills/toolu--plan/references/ledger.md +18 -0
- package/generated/skills/toolu--plan-review/SKILL.md +48 -0
- package/generated/skills/toolu--review-and-commit--skill/SKILL.md +10 -0
- package/generated/skills/toolu--setup/SKILL.md +24 -0
- package/generated/skills/toolu--setup/scripts/setup.sh +206 -0
- package/generated/skills/toolu--spec/SKILL.md +67 -0
- package/generated/skills/toolu--spec-review/SKILL.md +50 -0
- package/generated/skills/toolu--test/SKILL.md +49 -0
- package/package.json +51 -0
- package/plugins/agent-browser/.claude-plugin/plugin.json +18 -0
- package/plugins/agent-browser/.codex-plugin/plugin.json +7 -0
- package/plugins/agent-browser/README.md +18 -0
- package/plugins/agent-browser/hooks/hooks.json +15 -0
- package/plugins/agent-browser/hooks/session-start.sh +42 -0
- package/plugins/agent-browser/skills/agent-browser/SKILL.md +77 -0
- package/plugins/agent-browser/skills/agent-browser/scripts/agent-browser.sh +80 -0
- package/plugins/ast-grep/.claude-plugin/plugin.json +18 -0
- package/plugins/ast-grep/.codex-plugin/plugin.json +7 -0
- package/plugins/ast-grep/README.md +21 -0
- package/plugins/ast-grep/hooks/hooks.json +15 -0
- package/plugins/ast-grep/hooks/post-tools.d/byte-savings.sh +67 -0
- package/plugins/ast-grep/hooks/pre-tools.d/search-nudge.sh +170 -0
- package/plugins/ast-grep/hooks/register.sh +68 -0
- package/plugins/ast-grep/scripts/byte-savings-report.sh +28 -0
- package/plugins/ast-grep/skills/ast-grep/SKILL.md +127 -0
- package/plugins/ast-grep/skills/ast-grep/references/ast-grep-advanced.md +44 -0
- package/plugins/ast-grep/skills/ast-grep/scripts/ast-grep.sh +103 -0
- package/plugins/context7/.claude-plugin/plugin.json +18 -0
- package/plugins/context7/.codex-plugin/plugin.json +7 -0
- package/plugins/context7/README.md +19 -0
- package/plugins/context7/hooks/hooks.json +15 -0
- package/plugins/context7/hooks/session-start.sh +42 -0
- package/plugins/context7/skills/context7/SKILL.md +64 -0
- package/plugins/context7/skills/context7/scripts/search.sh +151 -0
- package/plugins/exa-search/.claude-plugin/plugin.json +18 -0
- package/plugins/exa-search/.codex-plugin/plugin.json +7 -0
- package/plugins/exa-search/README.md +19 -0
- package/plugins/exa-search/hooks/hooks.json +15 -0
- package/plugins/exa-search/hooks/session-start.sh +34 -0
- package/plugins/exa-search/skills/exa-search/SKILL.md +91 -0
- package/plugins/exa-search/skills/exa-search/scripts/search.sh +221 -0
- package/plugins/jev/.claude-plugin/plugin.json +19 -0
- package/plugins/jev/.codex-plugin/plugin.json +7 -0
- package/plugins/jev/README.md +61 -0
- package/plugins/jev/hooks/hooks.json +25 -0
- package/plugins/jev/hooks/lib/common.sh +49 -0
- package/plugins/jev/hooks/session-start.sh +45 -0
- package/plugins/jev/hooks/user-prompt-submit.sh +41 -0
- package/plugins/jev/skills/jev/SKILL.md +81 -0
- package/plugins/jev/skills/jev/evals/README.md +98 -0
- package/plugins/jev/skills/jev/references/problem-solving.md +198 -0
- package/plugins/jev/skills/jev/scripts/jev.sh +405 -0
- package/plugins/jira/.claude-plugin/plugin.json +18 -0
- package/plugins/jira/.codex-plugin/plugin.json +7 -0
- package/plugins/jira/README.md +42 -0
- package/plugins/jira/hooks/hooks.json +15 -0
- package/plugins/jira/hooks/session-start.sh +34 -0
- package/plugins/jira/skills/jira/SKILL.md +123 -0
- package/plugins/jira/skills/jira/scripts/jira.sh +70 -0
- package/plugins/jira/skills/jira/scripts/lib/adf.sh +17 -0
- package/plugins/jira/skills/jira/scripts/lib/attachment.sh +94 -0
- package/plugins/jira/skills/jira/scripts/lib/board.sh +58 -0
- package/plugins/jira/skills/jira/scripts/lib/http.sh +184 -0
- package/plugins/jira/skills/jira/scripts/lib/issue.sh +159 -0
- package/plugins/jira/skills/jira/scripts/lib/paginate.sh +45 -0
- package/plugins/jira/skills/jira/scripts/lib/plan-parse.sh +70 -0
- package/plugins/jira/skills/jira/scripts/lib/plan-run.sh +115 -0
- package/plugins/jira/skills/jira/scripts/lib/plan-store.sh +168 -0
- package/plugins/jira/skills/jira/scripts/lib/plan.sh +108 -0
- package/plugins/jira/skills/jira/scripts/lib/project.sh +42 -0
- package/plugins/jira/skills/jira/scripts/lib/raw.sh +15 -0
- package/plugins/jira/skills/jira/scripts/lib/search.sh +41 -0
- package/plugins/jira/skills/jira/scripts/lib/sprint.sh +88 -0
- package/plugins/jira/skills/jira/scripts/lib/user.sh +45 -0
- package/plugins/jira/skills/jira/scripts/lib/worklog.sh +56 -0
- package/plugins/pr-babysit/.claude-plugin/plugin.json +25 -0
- package/plugins/pr-babysit/.codex-plugin/plugin.json +7 -0
- package/plugins/pr-babysit/README.md +38 -0
- package/plugins/pr-babysit/commands/babysit.md +13 -0
- package/plugins/pr-babysit/hooks/check-toolu.sh +20 -0
- package/plugins/pr-babysit/hooks/hooks.json +15 -0
- package/plugins/pr-babysit/scripts/babysit-tick.sh +133 -0
- package/plugins/pr-babysit/scripts/collect-pr.sh +224 -0
- package/plugins/pr-babysit/scripts/lib/common.sh +146 -0
- package/plugins/pr-babysit/scripts/lib/gh.sh +150 -0
- package/plugins/pr-babysit/scripts/lib/lock.sh +84 -0
- package/plugins/pr-babysit/scripts/lib/normalize.sh +98 -0
- package/plugins/pr-babysit/scripts/lib/state.sh +37 -0
- package/plugins/pr-babysit/scripts/parse-verdict.sh +171 -0
- package/plugins/pr-babysit/scripts/record.sh +69 -0
- package/plugins/pr-babysit/scripts/reduce-state.sh +245 -0
- package/plugins/pr-babysit/scripts/reply-thread.sh +90 -0
- package/plugins/pr-babysit/scripts/resolve-thread.sh +71 -0
- package/plugins/pr-babysit/skills/babysit/SKILL.md +31 -0
- package/plugins/pr-babysit/skills/babysit/references/helper.md +209 -0
- package/plugins/pr-babysit/workflows/babysit.md +722 -0
- package/plugins/python-quality/.claude-plugin/plugin.json +24 -0
- package/plugins/python-quality/.codex-plugin/plugin.json +6 -0
- package/plugins/python-quality/README.md +23 -0
- package/plugins/python-quality/hooks/check-toolu.sh +20 -0
- package/plugins/python-quality/hooks/concerns/00-preamble.sh +85 -0
- package/plugins/python-quality/hooks/concerns/10-size-file.sh +6 -0
- package/plugins/python-quality/hooks/concerns/20-tests.sh +37 -0
- package/plugins/python-quality/hooks/concerns/30-suppression.sh +33 -0
- package/plugins/python-quality/hooks/concerns/50-size-fn.sh +49 -0
- package/plugins/python-quality/hooks/concerns/70-no-mocks.sh +76 -0
- package/plugins/python-quality/hooks/concerns/90-docs.sh +52 -0
- package/plugins/python-quality/hooks/concerns/99-finalize.sh +36 -0
- package/plugins/python-quality/hooks/hooks.json +19 -0
- package/plugins/python-quality/hooks/register.sh +65 -0
- package/plugins/rust-quality/.claude-plugin/plugin.json +24 -0
- package/plugins/rust-quality/.codex-plugin/plugin.json +6 -0
- package/plugins/rust-quality/README.md +24 -0
- package/plugins/rust-quality/hooks/check-toolu.sh +20 -0
- package/plugins/rust-quality/hooks/concerns/00-preamble.sh +93 -0
- package/plugins/rust-quality/hooks/concerns/10-size-file.sh +10 -0
- package/plugins/rust-quality/hooks/concerns/20-tests.sh +84 -0
- package/plugins/rust-quality/hooks/concerns/30-suppression.sh +26 -0
- package/plugins/rust-quality/hooks/concerns/40-unsafe.sh +39 -0
- package/plugins/rust-quality/hooks/concerns/50-size-fn.sh +38 -0
- package/plugins/rust-quality/hooks/concerns/55-size-impl.sh +28 -0
- package/plugins/rust-quality/hooks/concerns/60-error-handling.sh +149 -0
- package/plugins/rust-quality/hooks/concerns/70-no-mocks.sh +139 -0
- package/plugins/rust-quality/hooks/concerns/90-docs.sh +32 -0
- package/plugins/rust-quality/hooks/concerns/99-finalize.sh +36 -0
- package/plugins/rust-quality/hooks/hooks.json +19 -0
- package/plugins/rust-quality/hooks/register.sh +65 -0
- package/plugins/statusline/.claude-plugin/plugin.json +19 -0
- package/plugins/statusline/.codex-plugin/plugin.json +7 -0
- package/plugins/statusline/README.md +108 -0
- package/plugins/statusline/commands/setup.md +30 -0
- package/plugins/statusline/hooks/hooks.json +15 -0
- package/plugins/statusline/hooks/session-start.sh +45 -0
- package/plugins/statusline/scripts/collect-status.sh +147 -0
- package/plugins/statusline/scripts/setup.sh +93 -0
- package/plugins/statusline/scripts/status.sh +55 -0
- package/plugins/statusline/skills/status/SKILL.md +13 -0
- package/plugins/statusline/statusline.sh +177 -0
- package/plugins/toolu/.claude-plugin/plugin.json +19 -0
- package/plugins/toolu/.codex-plugin/plugin.json +7 -0
- package/plugins/toolu/README.md +35 -0
- package/plugins/toolu/agents/.gitkeep +0 -0
- package/plugins/toolu/agents/architect.md +52 -0
- package/plugins/toolu/agents/deep-explore.md +65 -0
- package/plugins/toolu/agents/implementer.md +50 -0
- package/plugins/toolu/agents/quick-task.md +54 -0
- package/plugins/toolu/agents/research-agent.md +107 -0
- package/plugins/toolu/assets/agents/architect.toml +9 -0
- package/plugins/toolu/assets/agents/deep-explore.toml +9 -0
- package/plugins/toolu/assets/agents/implementer.toml +9 -0
- package/plugins/toolu/assets/agents/quick-task.toml +9 -0
- package/plugins/toolu/assets/agents/research-agent.toml +9 -0
- package/plugins/toolu/commands/.gitkeep +0 -0
- package/plugins/toolu/commands/commit.md +5 -0
- package/plugins/toolu/commands/review-and-commit.md +5 -0
- package/plugins/toolu/hooks/docs/gates.md +157 -0
- package/plugins/toolu/hooks/docs/model-routing.md +14 -0
- package/plugins/toolu/hooks/docs/post-compaction.md +3 -0
- package/plugins/toolu/hooks/docs/push-review.md +123 -0
- package/plugins/toolu/hooks/docs/session-start-python.md +3 -0
- package/plugins/toolu/hooks/docs/session-start-rust.md +4 -0
- package/plugins/toolu/hooks/docs/session-start-ts.md +3 -0
- package/plugins/toolu/hooks/docs/session-start.md +16 -0
- package/plugins/toolu/hooks/hooks.json +76 -0
- package/plugins/toolu/hooks/lib/config.sh +355 -0
- package/plugins/toolu/hooks/lib/detect.sh +929 -0
- package/plugins/toolu/hooks/lib/diff-sha.sh +32 -0
- package/plugins/toolu/hooks/lib/dispatch.sh +365 -0
- package/plugins/toolu/hooks/lib/docs-sync-config.sh +81 -0
- package/plugins/toolu/hooks/lib/edit-records.sh +157 -0
- package/plugins/toolu/hooks/lib/gate-file.sh +201 -0
- package/plugins/toolu/hooks/lib/gate-mode.sh +244 -0
- package/plugins/toolu/hooks/lib/host.sh +205 -0
- package/plugins/toolu/hooks/lib/permissions.sh +125 -0
- package/plugins/toolu/hooks/lib/plan-ledger-parse.sh +219 -0
- package/plugins/toolu/hooks/lib/plan-ledger-preflight.sh +137 -0
- package/plugins/toolu/hooks/lib/plan-ledger.sh +749 -0
- package/plugins/toolu/hooks/lib/push-waiver.sh +116 -0
- package/plugins/toolu/hooks/lib/quality-config.sh +184 -0
- package/plugins/toolu/hooks/lib/registry.sh +72 -0
- package/plugins/toolu/hooks/lib/state-sweeper.sh +194 -0
- package/plugins/toolu/hooks/lib/telemetry.sh +94 -0
- package/plugins/toolu/hooks/lib/verdict.sh +477 -0
- package/plugins/toolu/hooks/post-tools/mod.sh +42 -0
- package/plugins/toolu/hooks/post-tools/modules/gate-status.sh +140 -0
- package/plugins/toolu/hooks/post-tools/modules/push-waiver.sh +97 -0
- package/plugins/toolu/hooks/pre-compact.sh +18 -0
- package/plugins/toolu/hooks/pre-tools/agent-tier.sh +111 -0
- package/plugins/toolu/hooks/pre-tools/mod.sh +37 -0
- package/plugins/toolu/hooks/pre-tools/modules/bash-commands.sh +187 -0
- package/plugins/toolu/hooks/pre-tools/modules/code-edit-rules.sh +78 -0
- package/plugins/toolu/hooks/pre-tools/modules/commit-gate.sh +70 -0
- package/plugins/toolu/hooks/pre-tools/modules/docs-sync.sh +137 -0
- package/plugins/toolu/hooks/pre-tools/modules/mcp-blocker.sh +151 -0
- package/plugins/toolu/hooks/pre-tools/modules/plan-ledger.sh +201 -0
- package/plugins/toolu/hooks/pre-tools/modules/protected-files.sh +177 -0
- package/plugins/toolu/hooks/pre-tools/modules/push-review.sh +273 -0
- package/plugins/toolu/hooks/pre-tools/modules/quality-gate.sh +87 -0
- package/plugins/toolu/hooks/session-start.sh +379 -0
- package/plugins/toolu/hooks/user-prompt-submit.sh +197 -0
- package/plugins/toolu/scripts/context-budget.sh +111 -0
- package/plugins/toolu/scripts/debug-log.sh +98 -0
- package/plugins/toolu/scripts/debug-stack.sh +108 -0
- package/plugins/toolu/scripts/debug-testfail.sh +97 -0
- package/plugins/toolu/settings/.gitkeep +0 -0
- package/plugins/toolu/settings/README.md +127 -0
- package/plugins/toolu/settings/bash-allowlist.txt +12 -0
- package/plugins/toolu/settings/bash-denylist.txt +25 -0
- package/plugins/toolu/settings/code-edit-rules.json +67 -0
- package/plugins/toolu/settings/commit-prefixes.txt +12 -0
- package/plugins/toolu/settings/mcp-blocklist.txt +8 -0
- package/plugins/toolu/settings/permissions.fragment.json +36 -0
- package/plugins/toolu/settings/protected-files.txt +30 -0
- package/plugins/toolu/settings/rust-unsafe-exemptions.txt +5 -0
- package/plugins/toolu/settings/toolu.config.example.json +130 -0
- package/plugins/toolu/skills/.gitkeep +0 -0
- package/plugins/toolu/skills/brainstorm/SKILL.md +57 -0
- package/plugins/toolu/skills/brainstorm/references/design-questions.md +36 -0
- package/plugins/toolu/skills/commit/SKILL.md +11 -0
- package/plugins/toolu/skills/debug/SKILL.md +54 -0
- package/plugins/toolu/skills/debug/evals/README.md +17 -0
- package/plugins/toolu/skills/debug/evals/cases.json +24 -0
- package/plugins/toolu/skills/debug/evals/results.json +34 -0
- package/plugins/toolu/skills/deep-research/SKILL.md +51 -0
- package/plugins/toolu/skills/execution/SKILL.md +77 -0
- package/plugins/toolu/skills/orchestrator/SKILL.md +145 -0
- package/plugins/toolu/skills/orchestrator/references/delegation-cost.md +104 -0
- package/plugins/toolu/skills/orchestrator/references/model-routing.md +112 -0
- package/plugins/toolu/skills/plan/SKILL.md +56 -0
- package/plugins/toolu/skills/plan/references/ledger.md +18 -0
- package/plugins/toolu/skills/plan-review/SKILL.md +48 -0
- package/plugins/toolu/skills/review-and-commit/SKILL.md +10 -0
- package/plugins/toolu/skills/setup/SKILL.md +24 -0
- package/plugins/toolu/skills/setup/scripts/setup.sh +206 -0
- package/plugins/toolu/skills/spec/SKILL.md +67 -0
- package/plugins/toolu/skills/spec-review/SKILL.md +50 -0
- package/plugins/toolu/skills/test/SKILL.md +49 -0
- package/plugins/toolu/workflows/commit.md +21 -0
- package/plugins/toolu/workflows/host-mapping.md +22 -0
- package/plugins/toolu/workflows/review-and-commit.md +54 -0
- package/plugins/toolu/workflows/semantic-judgments.md +35 -0
- package/plugins/toolu-review/.claude-plugin/plugin.json +18 -0
- package/plugins/toolu-review/.codex-plugin/plugin.json +7 -0
- package/plugins/toolu-review/README.md +17 -0
- package/plugins/toolu-review/hooks/hooks.json +15 -0
- package/plugins/toolu-review/hooks/session-start.sh +34 -0
- package/plugins/toolu-review/skills/review/SKILL.md +90 -0
- package/plugins/toolu-review/skills/review/scripts/write-state.sh +189 -0
- package/plugins/ts-quality/.claude-plugin/plugin.json +24 -0
- package/plugins/ts-quality/.codex-plugin/plugin.json +6 -0
- package/plugins/ts-quality/README.md +24 -0
- package/plugins/ts-quality/hooks/check-toolu.sh +20 -0
- package/plugins/ts-quality/hooks/concerns/00-preamble.sh +123 -0
- package/plugins/ts-quality/hooks/concerns/10-imports.sh +33 -0
- package/plugins/ts-quality/hooks/concerns/15-type-as.sh +9 -0
- package/plugins/ts-quality/hooks/concerns/20-tests.sh +26 -0
- package/plugins/ts-quality/hooks/concerns/25-size-file.sh +40 -0
- package/plugins/ts-quality/hooks/concerns/30-size-fn.sh +53 -0
- package/plugins/ts-quality/hooks/concerns/35-react-hooks.sh +7 -0
- package/plugins/ts-quality/hooks/concerns/40-factory.sh +5 -0
- package/plugins/ts-quality/hooks/concerns/45-typeguard.sh +6 -0
- package/plugins/ts-quality/hooks/concerns/50-type-dup.sh +16 -0
- package/plugins/ts-quality/hooks/concerns/55-naming.sh +11 -0
- package/plugins/ts-quality/hooks/concerns/60-console.sh +6 -0
- package/plugins/ts-quality/hooks/concerns/65-suppression.sh +12 -0
- package/plugins/ts-quality/hooks/concerns/70-ui-confirm.sh +8 -0
- package/plugins/ts-quality/hooks/concerns/72-ui-radix.sh +12 -0
- package/plugins/ts-quality/hooks/concerns/74-react-props.sh +6 -0
- package/plugins/ts-quality/hooks/concerns/76-toast.sh +10 -0
- package/plugins/ts-quality/hooks/concerns/78-error-ast.sh +242 -0
- package/plugins/ts-quality/hooks/concerns/80-throw-literal.sh +23 -0
- package/plugins/ts-quality/hooks/concerns/85-no-mocks.sh +109 -0
- package/plugins/ts-quality/hooks/concerns/90-duplication.sh +30 -0
- package/plugins/ts-quality/hooks/concerns/92-docs.sh +36 -0
- package/plugins/ts-quality/hooks/concerns/94-handler.sh +15 -0
- package/plugins/ts-quality/hooks/concerns/99-finalize.sh +46 -0
- package/plugins/ts-quality/hooks/hooks.json +19 -0
- package/plugins/ts-quality/hooks/register.sh +65 -0
- package/src/adapter/__tests__/evaluate.test.ts +82 -0
- package/src/adapter/__tests__/permission-map.test.ts +91 -0
- package/src/adapter/evaluate.ts +54 -0
- package/src/adapter/permission-map.ts +177 -0
- package/src/bootstrap/__tests__/bootstrap.test.ts +148 -0
- package/src/bootstrap/entrypoint.ts +18 -0
- package/src/bootstrap/index.ts +5 -0
- package/src/bootstrap/readiness.ts +59 -0
- package/src/bootstrap/result.ts +21 -0
- package/src/bootstrap/runtime.ts +99 -0
- package/src/bootstrap/test-helpers.ts +25 -0
- package/src/host/__tests__/host.test.ts +37 -0
- package/src/host/detect.ts +46 -0
- package/src/host/index.ts +10 -0
- package/src/host/roots.ts +59 -0
- package/src/host/types.ts +14 -0
- package/src/inventory/__tests__/inventory.test.ts +69 -0
- package/src/inventory/index.ts +9 -0
- package/src/inventory/manifest.ts +46 -0
- package/src/inventory/scan.ts +66 -0
- package/src/inventory/selection.ts +92 -0
- package/src/inventory/types.ts +22 -0
- package/src/lifecycle/__tests__/lifecycle.test.ts +7 -0
- package/src/lifecycle/index.ts +2 -0
- package/src/lifecycle/table.ts +42 -0
- package/src/plugin/__tests__/plugin-stub.test.ts +6 -0
- package/src/plugin/plugin-stub.ts +7 -0
- package/src/plugin/toolu.ts +142 -0
- package/src/preflight/__tests__/preflight.test.ts +20 -0
- package/src/preflight/check.ts +75 -0
- package/src/preflight/index.ts +2 -0
- package/src/select/__tests__/select.test.ts +52 -0
- package/src/select/index.ts +2 -0
- package/src/select/resolve.ts +87 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# agent-browser wrapper — bakes token-lean defaults onto the read-heavy command
|
|
5
|
+
# family so the agent spends context on the accessibility tree, not raw HTML or
|
|
6
|
+
# screenshots. Injection is fail-open via a STATIC per-subcommand allow-map: a
|
|
7
|
+
# default flag is added ONLY where that subcommand accepts it, so shaping can
|
|
8
|
+
# never turn a working call into a usage error; every other subcommand passes
|
|
9
|
+
# through untouched. A leading `--raw` bypasses all shaping. The binary is never
|
|
10
|
+
# auto-installed — a missing one prints an install guide and exits non-zero.
|
|
11
|
+
#
|
|
12
|
+
# $AGENT_BROWSER_BIN overrides the binary (absolute path or PATH name), for
|
|
13
|
+
# pointing at a custom build or for tests.
|
|
14
|
+
|
|
15
|
+
BIN="${AGENT_BROWSER_BIN:-agent-browser}"
|
|
16
|
+
DEFAULT_MAX_OUTPUT=4000
|
|
17
|
+
|
|
18
|
+
install_guide() {
|
|
19
|
+
echo "agent-browser not found — install: npm i -g agent-browser && agent-browser install (or: brew install agent-browser / cargo install agent-browser)" >&2
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
require_bin() {
|
|
23
|
+
command -v "$BIN" >/dev/null 2>&1 || { install_guide; exit 127; }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
# Exact-token or --opt=value match against the remaining args.
|
|
27
|
+
has_flag() {
|
|
28
|
+
local needle="$1"; shift
|
|
29
|
+
local a
|
|
30
|
+
for a in "$@"; do
|
|
31
|
+
case "$a" in
|
|
32
|
+
"$needle" | "$needle="*) return 0 ;;
|
|
33
|
+
esac
|
|
34
|
+
done
|
|
35
|
+
return 1
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# --raw: total bypass, no shaping.
|
|
39
|
+
if [ "${1:-}" = "--raw" ]; then
|
|
40
|
+
shift
|
|
41
|
+
require_bin
|
|
42
|
+
exec "$BIN" "$@"
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
require_bin
|
|
46
|
+
|
|
47
|
+
# No subcommand — let agent-browser print its own help/usage.
|
|
48
|
+
if [ "$#" -eq 0 ]; then
|
|
49
|
+
exec "$BIN"
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
cmd="$1"; shift # remaining flags/args stay in "$@"
|
|
53
|
+
|
|
54
|
+
inject=()
|
|
55
|
+
case "$cmd" in
|
|
56
|
+
snapshot)
|
|
57
|
+
# -i (interactive-only compact tree) unless the caller already scoped it.
|
|
58
|
+
if ! has_flag -i "$@" && ! has_flag -a "$@" \
|
|
59
|
+
&& ! has_flag -s "$@" && ! has_flag -d "$@"; then
|
|
60
|
+
inject+=(-i)
|
|
61
|
+
fi
|
|
62
|
+
has_flag --json "$@" || inject+=(--json)
|
|
63
|
+
has_flag --max-output "$@" || inject+=(--max-output "$DEFAULT_MAX_OUTPUT")
|
|
64
|
+
has_flag --content-boundaries "$@" || inject+=(--content-boundaries)
|
|
65
|
+
;;
|
|
66
|
+
get)
|
|
67
|
+
has_flag --json "$@" || inject+=(--json)
|
|
68
|
+
has_flag --max-output "$@" || inject+=(--max-output "$DEFAULT_MAX_OUTPUT")
|
|
69
|
+
has_flag --content-boundaries "$@" || inject+=(--content-boundaries)
|
|
70
|
+
;;
|
|
71
|
+
find | diff)
|
|
72
|
+
has_flag --json "$@" || inject+=(--json)
|
|
73
|
+
has_flag --max-output "$@" || inject+=(--max-output "$DEFAULT_MAX_OUTPUT")
|
|
74
|
+
;;
|
|
75
|
+
*)
|
|
76
|
+
: # unknown/binary-output subcommand — inject nothing (fail-open passthrough)
|
|
77
|
+
;;
|
|
78
|
+
esac
|
|
79
|
+
|
|
80
|
+
exec "$BIN" "$cmd" "${inject[@]+"${inject[@]}"}" "$@"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ast-grep",
|
|
3
|
+
"version": "6.8.0",
|
|
4
|
+
"description": "Structural code search & rewrite (ast-grep): skill, wrapper, and a PreToolUse Grep→ast-grep nudge registered into the toolu hook engine.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Falconiere Barbosa",
|
|
7
|
+
"email": "hello@falconiere.io"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/falconiere/toolu",
|
|
10
|
+
"repository": "https://github.com/falconiere/toolu.git",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"claude-code",
|
|
14
|
+
"ast-grep",
|
|
15
|
+
"structural-search",
|
|
16
|
+
"hooks"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# ast-grep
|
|
2
|
+
|
|
3
|
+
Structural code search & rewrite (ast-grep): a skill, a wrapper, and a `PreToolUse` `Grep → ast-grep` nudge registered into the toolu hook engine.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
/plugin install ast-grep@toolu
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Standalone, no dependencies.
|
|
12
|
+
|
|
13
|
+
## What it provides
|
|
14
|
+
|
|
15
|
+
- **`ast-grep` skill** — an always-active protocol that mandates ast-grep (tree-sitter AST patterns) over Grep/sed for any find-or-rewrite-by-code-shape task, falling back to Grep only for exact literals.
|
|
16
|
+
- **`search-nudge` (`PreToolUse`)** — nudges Grep on code files, and `grep`/`rg` in Bash, toward the proper structural tool.
|
|
17
|
+
- **`byte-savings` (`PostToolUse`)** + `byte-savings-report.sh` — instrumentation for tokens saved by structural search.
|
|
18
|
+
|
|
19
|
+
## The ast-grep binary
|
|
20
|
+
|
|
21
|
+
The skill drives the `ast-grep` (a.k.a. `sg`) CLI — a tree-sitter AST pattern matcher and rewriter. Install it via `brew install ast-grep`, `cargo install ast-grep`, or `npm i -g @ast-grep/cli`. The plugin's hook modules register themselves into the core toolu dispatcher at `SessionStart` and run only while this plugin is installed.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PostToolUse instrumentation — measure how many bytes targeted/structural tools
|
|
3
|
+
# inject into context, so the "ast-grep returns far less than reading whole
|
|
4
|
+
# files" claim is MEASURED, not asserted.
|
|
5
|
+
#
|
|
6
|
+
# Honest by construction: it records the REAL byte count each tool returned. For
|
|
7
|
+
# a Read of a single on-disk file it also records that file's full size (the
|
|
8
|
+
# bytes a whole read costs), so a ranged Read shows a real saving. It does NOT
|
|
9
|
+
# fabricate a counterfactual for searches — it records what ast-grep/Grep
|
|
10
|
+
# actually returned, and the report aggregates per tool so the volume gap is
|
|
11
|
+
# visible. Append-only ledger; never blocks; emits nothing to context.
|
|
12
|
+
#
|
|
13
|
+
# Inputs (exported by post-tools/mod.sh): $tool_name $input $PROJECT_ROOT
|
|
14
|
+
: "${tool_name:=}"
|
|
15
|
+
: "${input:=}"
|
|
16
|
+
|
|
17
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
18
|
+
|
|
19
|
+
# Classify the tool; ignore everything we don't measure as cheaply as possible.
|
|
20
|
+
kind=""
|
|
21
|
+
case "$tool_name" in
|
|
22
|
+
Read) kind="read" ;;
|
|
23
|
+
Grep) kind="grep" ;;
|
|
24
|
+
Glob) kind="glob" ;;
|
|
25
|
+
Bash|Shell)
|
|
26
|
+
cmd=$(jq -r '.tool_input.command // ""' <<<"$input" 2>/dev/null)
|
|
27
|
+
# Matches `ast-grep …`, `sg …`, and piped forms (`… | ast-grep …`) — the
|
|
28
|
+
# leading-space alternative subsumes the pipe case, so no separate pattern.
|
|
29
|
+
case "$cmd" in
|
|
30
|
+
ast-grep*|sg\ *|*\ ast-grep\ *) kind="ast-grep" ;;
|
|
31
|
+
*) exit 0 ;;
|
|
32
|
+
esac
|
|
33
|
+
;;
|
|
34
|
+
*) exit 0 ;;
|
|
35
|
+
esac
|
|
36
|
+
|
|
37
|
+
# Returned bytes = byte length of the tool's textual response. tool_response may
|
|
38
|
+
# be a string (Read/Grep) or an object (Bash); coerce to text then measure.
|
|
39
|
+
resp=$(jq -r '
|
|
40
|
+
.tool_response
|
|
41
|
+
| if type == "string" then .
|
|
42
|
+
elif type == "object" then (.content? // .stdout? // .output? // tostring)
|
|
43
|
+
else tostring end' <<<"$input" 2>/dev/null)
|
|
44
|
+
[ -n "$resp" ] || exit 0
|
|
45
|
+
returned=$(printf '%s' "$resp" | wc -c | tr -d ' ')
|
|
46
|
+
[ -n "$returned" ] || exit 0
|
|
47
|
+
|
|
48
|
+
# Full-file bytes (single-file Read only): the cost a whole read would incur.
|
|
49
|
+
full=0
|
|
50
|
+
if [ "$kind" = "read" ]; then
|
|
51
|
+
fp=$(jq -r '.tool_input.file_path // ""' <<<"$input" 2>/dev/null)
|
|
52
|
+
if [ -n "$fp" ] && [ -f "$fp" ]; then
|
|
53
|
+
full=$(wc -c < "$fp" 2>/dev/null | tr -d ' ')
|
|
54
|
+
[ -n "$full" ] || full=0
|
|
55
|
+
fi
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Append one compact record to the per-session ledger. Session-scoped so a
|
|
59
|
+
# stale id can never grow unbounded; the report aggregates a single session.
|
|
60
|
+
sid=$(jq -r '.session_id // "unknown"' <<<"$input" 2>/dev/null | tr -cd 'A-Za-z0-9-')
|
|
61
|
+
[ -n "$sid" ] || sid="unknown"
|
|
62
|
+
ledger_dir="${TOOLU_CONFIG_DIR:-${CODEX_HOME:-${CLAUDE_CONFIG_DIR:-$HOME/.claude}}}/toolu/byte-savings"
|
|
63
|
+
mkdir -p "$ledger_dir" 2>/dev/null || exit 0
|
|
64
|
+
printf '{"kind":"%s","returned":%s,"full":%s}\n' "$kind" "$returned" "$full" \
|
|
65
|
+
>> "$ledger_dir/$sid.jsonl" 2>/dev/null
|
|
66
|
+
|
|
67
|
+
exit 0
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Pre-tool check: Enforce search hierarchy
|
|
3
|
+
# 1. ast-grep (structural / AST patterns) — first on code files
|
|
4
|
+
# 2. Grep (exact literals on non-code files, or after ast-grep returned nothing)
|
|
5
|
+
#
|
|
6
|
+
# Grep on code files is nudged toward ast-grep when patterns look structural.
|
|
7
|
+
# Bash grep/rg is always nudged toward proper tools.
|
|
8
|
+
#
|
|
9
|
+
# Inputs (from parent dispatcher pre-tools/mod.sh, via `export`):
|
|
10
|
+
# $tool_name - name of the tool being invoked
|
|
11
|
+
# $input - raw JSON payload on stdin
|
|
12
|
+
|
|
13
|
+
: "${tool_name:=}"
|
|
14
|
+
: "${input:=}"
|
|
15
|
+
|
|
16
|
+
# Core lib comes from the toolu dispatcher via TOOLU_LIB_DIR (set by
|
|
17
|
+
# plugins/toolu/hooks/pre-tools/mod.sh before registry dispatch). Outside
|
|
18
|
+
# that pipeline there is no relative path to it — fail SOFT: this module is
|
|
19
|
+
# an advisory extra and must never break tool calls by erroring.
|
|
20
|
+
[ -n "${TOOLU_LIB_DIR:-}" ] && [ -f "$TOOLU_LIB_DIR/detect.sh" ] && [ -f "$TOOLU_LIB_DIR/config.sh" ] || exit 0
|
|
21
|
+
# shellcheck source=../../../toolu/hooks/lib/detect.sh
|
|
22
|
+
. "$TOOLU_LIB_DIR/detect.sh"
|
|
23
|
+
# shellcheck source=../../../toolu/hooks/lib/config.sh
|
|
24
|
+
. "$TOOLU_LIB_DIR/config.sh"
|
|
25
|
+
|
|
26
|
+
# Decide ast-grep state lazily: config + CLI detection are only consulted when
|
|
27
|
+
# a structural pattern or grep/rg invocation is actually matched, so the
|
|
28
|
+
# common Bash/Grep tool call pays nothing.
|
|
29
|
+
ASTGREP_STATE=""
|
|
30
|
+
astgrep_state() {
|
|
31
|
+
if [ -z "$ASTGREP_STATE" ]; then
|
|
32
|
+
if ! toolu_enabled skills ast-grep; then
|
|
33
|
+
ASTGREP_STATE="opt-out"
|
|
34
|
+
elif [ "$(detect_ast_grep)" = "ast-grep" ]; then
|
|
35
|
+
ASTGREP_STATE="available"
|
|
36
|
+
else
|
|
37
|
+
ASTGREP_STATE="missing"
|
|
38
|
+
fi
|
|
39
|
+
fi
|
|
40
|
+
printf '%s' "$ASTGREP_STATE"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# ── Structural pattern keywords (shared) ────────────────────────────────────
|
|
44
|
+
STRUCT_RE='(^|\s)(fn |impl |async fn|async |class |function |struct |trait |interface |type |pub (fn|struct|enum|trait|mod|type|async)|export (function|class|interface|type|const|default)|enum |mod |const fn|#\[derive|#\[cfg|#\[test|@Component|@Injectable|@Module|=>|-> Result|-> impl|dyn |Box<|Arc<|Vec<|Option<|where |for .*in )'
|
|
45
|
+
|
|
46
|
+
# ── Non-code file globs (Grep is sole tool for these) ──────────────────────
|
|
47
|
+
NON_CODE_GLOB_RE='\*\.(toml|md|markdown|json|jsonc|yaml|yml|txt|env|sql|sh|bash|zsh|fish|lock|cfg|ini|conf|csv|xml|html|svg|css|graphql|gql|proto|makefile|dockerfile)'
|
|
48
|
+
NON_CODE_TYPE_RE='^(toml|json|yaml|md|markdown|html|css|sql|sh|bash|make|docker|config|xml|csv|graphql|proto)$'
|
|
49
|
+
|
|
50
|
+
# ── Non-code path segments (hooks, docs, config dirs) ──────────────────────
|
|
51
|
+
NON_CODE_PATH_RE='(\.claude/|docs/|\.github/|infra/|scripts/|\.config|Makefile|Dockerfile|Cargo\.toml|package\.json|tsconfig)'
|
|
52
|
+
|
|
53
|
+
# ── Grep tool ───────────────────────────────────────────────────────────────
|
|
54
|
+
if [[ "$tool_name" == "Grep" ]]; then
|
|
55
|
+
pattern=$(echo "$input" | jq -r '.tool_input.pattern // ""')
|
|
56
|
+
glob_filter=$(echo "$input" | jq -r '.tool_input.glob // ""')
|
|
57
|
+
type_filter=$(echo "$input" | jq -r '.tool_input.type // ""')
|
|
58
|
+
path_filter=$(echo "$input" | jq -r '.tool_input.path // ""')
|
|
59
|
+
|
|
60
|
+
# ── ALLOW: Non-code file types (Grep is sole tool — ast-grep can't do these)
|
|
61
|
+
if [[ -n "$glob_filter" ]] && echo "$glob_filter" | grep -qiE "$NON_CODE_GLOB_RE"; then
|
|
62
|
+
exit 0
|
|
63
|
+
fi
|
|
64
|
+
if [[ -n "$type_filter" ]] && echo "$type_filter" | grep -qiE "$NON_CODE_TYPE_RE"; then
|
|
65
|
+
exit 0
|
|
66
|
+
fi
|
|
67
|
+
if [[ -n "$path_filter" ]] && echo "$path_filter" | grep -qiE "$NON_CODE_PATH_RE"; then
|
|
68
|
+
exit 0
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# ── STOP: Structural code pattern → ast-grep (only when installed)
|
|
72
|
+
if echo "$pattern" | grep -qE "$STRUCT_RE"; then
|
|
73
|
+
case "$(astgrep_state)" in
|
|
74
|
+
available)
|
|
75
|
+
jq -n '{
|
|
76
|
+
"hookSpecificOutput": {
|
|
77
|
+
"hookEventName": "PreToolUse",
|
|
78
|
+
"additionalContext": "STOP: Structural code pattern detected. Use ast-grep: `ast-grep run --pattern \"your pattern\" --lang rust/typescript .` AST-aware matching is far more accurate. Grep is for exact literals on non-code files, or after ast-grep returned nothing."
|
|
79
|
+
}
|
|
80
|
+
}'
|
|
81
|
+
;;
|
|
82
|
+
missing)
|
|
83
|
+
jq -n '{
|
|
84
|
+
"hookSpecificOutput": {
|
|
85
|
+
"hookEventName": "PreToolUse",
|
|
86
|
+
"additionalContext": "WARN: structural code pattern detected but ast-grep is not installed. Falling back to Grep — expect false positives. Install ast-grep (`cargo install ast-grep` or `brew install ast-grep`) for AST-aware matching."
|
|
87
|
+
}
|
|
88
|
+
}'
|
|
89
|
+
;;
|
|
90
|
+
opt-out|*)
|
|
91
|
+
: # user opted out of ast-grep — no nudge, no install hint
|
|
92
|
+
;;
|
|
93
|
+
esac
|
|
94
|
+
exit 0
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
exit 0
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# ── Bash tool: catch grep/rg being used for code search ────────────────────
|
|
101
|
+
if [[ "$tool_name" == "Bash" || "$tool_name" == "Shell" ]]; then
|
|
102
|
+
command=$(echo "$input" | jq -r '.tool_input.command // ""')
|
|
103
|
+
|
|
104
|
+
# Strip heredoc bodies
|
|
105
|
+
cmd_only=$(printf '%s\n' "$command" | strip_heredocs)
|
|
106
|
+
|
|
107
|
+
# Catch grep/rg invocations
|
|
108
|
+
if echo "$cmd_only" | grep -qE '(^|\s|&&|\|\||;)(grep|rg|ripgrep)\s'; then
|
|
109
|
+
# Structural patterns → ast-grep (only when installed)
|
|
110
|
+
if echo "$cmd_only" | grep -qE "$STRUCT_RE"; then
|
|
111
|
+
case "$(astgrep_state)" in
|
|
112
|
+
available)
|
|
113
|
+
jq -n '{
|
|
114
|
+
"hookSpecificOutput": {
|
|
115
|
+
"hookEventName": "PreToolUse",
|
|
116
|
+
"additionalContext": "STOP: grep/rg for structural code search. Use ast-grep: `ast-grep run --pattern \"your pattern\" --lang rust/typescript .` grep/rg is for piping command output or non-code files."
|
|
117
|
+
}
|
|
118
|
+
}'
|
|
119
|
+
;;
|
|
120
|
+
missing)
|
|
121
|
+
jq -n '{
|
|
122
|
+
"hookSpecificOutput": {
|
|
123
|
+
"hookEventName": "PreToolUse",
|
|
124
|
+
"additionalContext": "WARN: structural grep/rg detected but ast-grep is not installed. Proceeding with grep/rg — expect false positives. Install ast-grep (`cargo install ast-grep` or `brew install ast-grep`) for AST-aware matching."
|
|
125
|
+
}
|
|
126
|
+
}'
|
|
127
|
+
;;
|
|
128
|
+
opt-out|*)
|
|
129
|
+
: # ast-grep opted out — no STOP/WARN
|
|
130
|
+
;;
|
|
131
|
+
esac
|
|
132
|
+
exit 0
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
# All other grep/rg → nudge toward proper tools.
|
|
136
|
+
# The Grep-tool-vs-bash-grep advice is independent of ast-grep, so this
|
|
137
|
+
# fires even when ast-grep is opted out; we just drop the ast-grep half.
|
|
138
|
+
case "$(astgrep_state)" in
|
|
139
|
+
available)
|
|
140
|
+
jq -n '{
|
|
141
|
+
"hookSpecificOutput": {
|
|
142
|
+
"hookEventName": "PreToolUse",
|
|
143
|
+
"additionalContext": "grep/rg in Bash detected. Use ast-grep for structural patterns on code files, Grep tool for exact literals on non-code files. Bash grep/rg only for piping command output."
|
|
144
|
+
}
|
|
145
|
+
}'
|
|
146
|
+
;;
|
|
147
|
+
missing)
|
|
148
|
+
jq -n '{
|
|
149
|
+
"hookSpecificOutput": {
|
|
150
|
+
"hookEventName": "PreToolUse",
|
|
151
|
+
"additionalContext": "grep/rg in Bash detected. Use Grep tool for exact literals on non-code files. Bash grep/rg only for piping command output. (ast-grep not installed — structural matching unavailable.)"
|
|
152
|
+
}
|
|
153
|
+
}'
|
|
154
|
+
;;
|
|
155
|
+
opt-out|*)
|
|
156
|
+
jq -n '{
|
|
157
|
+
"hookSpecificOutput": {
|
|
158
|
+
"hookEventName": "PreToolUse",
|
|
159
|
+
"additionalContext": "grep/rg in Bash detected. Use Grep tool for exact literals on non-code files. Bash grep/rg only for piping command output."
|
|
160
|
+
}
|
|
161
|
+
}'
|
|
162
|
+
;;
|
|
163
|
+
esac
|
|
164
|
+
exit 0
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
exit 0
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
exit 0
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SessionStart registry sync for the ast-grep plugin.
|
|
3
|
+
#
|
|
4
|
+
# Mirrors hooks/pre-tools.d/*.sh and hooks/post-tools.d/*.sh into the toolu
|
|
5
|
+
# runtime registry (${TOOLU_CONFIG_DIR:-${CLAUDE_CONFIG_DIR:-$HOME/.claude}}/toolu/{pre,post}-tools.d/)
|
|
6
|
+
# under the namespaced filename ast-grep@toolu__<name>.sh, and prunes entries
|
|
7
|
+
# bearing OUR prefix whose source module no longer exists. Other plugins'
|
|
8
|
+
# entries are never touched. The core toolu dispatcher executes the synced
|
|
9
|
+
# copies, gated on this plugin being installed.
|
|
10
|
+
#
|
|
11
|
+
# Silent on success (SessionStart stdout becomes context); errors are
|
|
12
|
+
# non-fatal — a failed sync means the registry copy is stale, not broken.
|
|
13
|
+
|
|
14
|
+
SPEC="ast-grep@toolu"
|
|
15
|
+
SELF_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
16
|
+
if [ -n "${TOOLU_CONFIG_DIR:-}" ]; then
|
|
17
|
+
CONFIG_ROOT="$TOOLU_CONFIG_DIR"
|
|
18
|
+
elif [ "${TOOLU_HOST_OVERRIDE:-}" = codex ] || { [ -z "${TOOLU_HOST_OVERRIDE:-}" ] && [ -n "${PLUGIN_ROOT:-}" ]; }; then
|
|
19
|
+
CONFIG_ROOT="${CODEX_HOME:-$HOME/.codex}"
|
|
20
|
+
else
|
|
21
|
+
CONFIG_ROOT="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
|
|
22
|
+
fi
|
|
23
|
+
REG_ROOT="$CONFIG_ROOT/toolu"
|
|
24
|
+
|
|
25
|
+
# Consume stdin so Claude Code's hook IPC never stalls.
|
|
26
|
+
cat > /dev/null 2>&1 || true
|
|
27
|
+
|
|
28
|
+
# Mirror one source dir into its matching registry dir (atomic, self-pruning).
|
|
29
|
+
sync_dir() {
|
|
30
|
+
local src_dir="$1" reg_dir="$2" src name dst tmp
|
|
31
|
+
[ -d "$src_dir" ] || return 0
|
|
32
|
+
mkdir -p "$reg_dir" 2>/dev/null || return 0
|
|
33
|
+
|
|
34
|
+
# Clear OUR orphaned atomic-write residue from prior crashed runs (a death
|
|
35
|
+
# between cp and mv leaves <spec>__<name>.sh.tmp.<pid>; nothing executes
|
|
36
|
+
# them, but nothing else cleans them either). Age-gated so a concurrent
|
|
37
|
+
# SessionStart's in-flight tmp (seconds old) is never clobbered.
|
|
38
|
+
find "$reg_dir" -maxdepth 1 -name "${SPEC}__*.sh.tmp.*" -mmin +1 -delete 2>/dev/null
|
|
39
|
+
|
|
40
|
+
# Sync: copy each source module if missing or changed (atomic tmp+mv).
|
|
41
|
+
for src in "$src_dir"/*.sh; do
|
|
42
|
+
[ -f "$src" ] || continue
|
|
43
|
+
name=$(basename "$src")
|
|
44
|
+
dst="$reg_dir/${SPEC}__${name}"
|
|
45
|
+
if [ ! -f "$dst" ] || ! cmp -s "$src" "$dst"; then
|
|
46
|
+
tmp="${dst}.tmp.$$"
|
|
47
|
+
if cp "$src" "$tmp" 2>/dev/null; then
|
|
48
|
+
mv "$tmp" "$dst" 2>/dev/null || rm -f "$tmp"
|
|
49
|
+
else
|
|
50
|
+
rm -f "$tmp" 2>/dev/null
|
|
51
|
+
fi
|
|
52
|
+
fi
|
|
53
|
+
done
|
|
54
|
+
|
|
55
|
+
# Prune: remove OUR entries whose source module is gone. Never glob outside
|
|
56
|
+
# our own spec prefix.
|
|
57
|
+
for dst in "$reg_dir/${SPEC}__"*.sh; do
|
|
58
|
+
[ -f "$dst" ] || continue
|
|
59
|
+
name=$(basename "$dst")
|
|
60
|
+
src="$src_dir/${name#"${SPEC}"__}"
|
|
61
|
+
[ -f "$src" ] || rm -f "$dst"
|
|
62
|
+
done
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
sync_dir "$SELF_DIR/pre-tools.d" "$REG_ROOT/pre-tools.d"
|
|
66
|
+
sync_dir "$SELF_DIR/post-tools.d" "$REG_ROOT/post-tools.d"
|
|
67
|
+
|
|
68
|
+
exit 0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# byte-savings-report.sh <ledger.jsonl>
|
|
3
|
+
#
|
|
4
|
+
# Aggregates a per-session byte-savings ledger (written by the post-tools
|
|
5
|
+
# byte-savings instrumentation module) into a per-kind summary: bytes each tool
|
|
6
|
+
# returned into context (with a ~token estimate at 4 bytes/token) and, for
|
|
7
|
+
# single-file Reads, the targeting saving vs reading the whole file. Read-only.
|
|
8
|
+
set -u
|
|
9
|
+
|
|
10
|
+
ledger="${1:-}"
|
|
11
|
+
command -v jq >/dev/null 2>&1 || { echo "byte-savings-report: jq required" >&2; exit 1; }
|
|
12
|
+
[ -n "$ledger" ] && [ -f "$ledger" ] || {
|
|
13
|
+
echo "usage: byte-savings-report.sh <ledger.jsonl>" >&2; exit 1; }
|
|
14
|
+
|
|
15
|
+
jq -rs '
|
|
16
|
+
group_by(.kind)
|
|
17
|
+
| map({ kind: .[0].kind,
|
|
18
|
+
n: length,
|
|
19
|
+
returned: (map(.returned) | add),
|
|
20
|
+
full: (map(.full) | add) }) as $g
|
|
21
|
+
| ($g | map(.returned) | add) as $tot
|
|
22
|
+
| ( $g[]
|
|
23
|
+
| if .kind == "read" and .full > 0
|
|
24
|
+
then "\(.kind): returned=\(.returned) full=\(.full) saved=\((((.full - .returned) * 100) / .full) | floor)% (n=\(.n))"
|
|
25
|
+
else "\(.kind): returned=\(.returned) (n=\(.n))"
|
|
26
|
+
end ),
|
|
27
|
+
"TOTAL returned: \($tot) bytes (~\(($tot / 4) | floor) tok)"
|
|
28
|
+
' "$ledger"
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ast-grep
|
|
3
|
+
description: "ALWAYS ACTIVE — Structural code search and rewrite protocol. You MUST use ast-grep instead of Grep/sed for any 'find/rewrite by code shape' task (AST patterns, not text). Falls back to Grep for exact literals only."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ast-grep Structural Search & Rewrite Protocol
|
|
7
|
+
|
|
8
|
+
You have ast-grep (tree-sitter AST pattern matcher + rewriter) via the `ast-grep` / `sg` CLI.
|
|
9
|
+
This protocol is **MANDATORY and ALWAYS ACTIVE**.
|
|
10
|
+
|
|
11
|
+
## Hard Constraints
|
|
12
|
+
|
|
13
|
+
- Use `ast-grep run -p '<pattern>'` BEFORE Grep when the query is about **code shape** (AST), not text.
|
|
14
|
+
- Use `ast-grep run -p '...' -r '...'` BEFORE sed/Edit-loops when rewriting many call sites.
|
|
15
|
+
- Always pass `-l <lang>` for clarity (`typescript`, `tsx`, `javascript`, `rust`, `python`, `go`, ...).
|
|
16
|
+
- Never edit hand-rolled regex over multi-line code — use ast-grep instead.
|
|
17
|
+
|
|
18
|
+
## Position in the Search Stack
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
comemory → "what was decided / where is X" (memory)
|
|
22
|
+
ast-grep → "find / rewrite this code shape" (AST structural) ← here
|
|
23
|
+
Grep → "find exact literal `FOO_BAR`" (text)
|
|
24
|
+
Glob → "list paths matching `**/*.test.ts`" (paths)
|
|
25
|
+
Read → "open known file" (verify)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## When to Use ast-grep
|
|
29
|
+
|
|
30
|
+
✓ "Find all `useState($X)` calls without initial value"
|
|
31
|
+
✓ "Find all `try` blocks without `catch`"
|
|
32
|
+
✓ "Replace `console.log($X)` with `logger.info($X)` repo-wide"
|
|
33
|
+
✓ "Find all functions returning `Promise<void>`"
|
|
34
|
+
✓ "Find all `export default function` declarations"
|
|
35
|
+
✓ "Find all `await fetch($URL)` without error handling"
|
|
36
|
+
✓ Bulk safe refactor across many files (AST-aware, comment-preserving)
|
|
37
|
+
|
|
38
|
+
## When NOT to Use ast-grep
|
|
39
|
+
|
|
40
|
+
✗ Semantic intent ("how does auth work") → check comemory memory, then Grep on keywords + Read on hits
|
|
41
|
+
✗ Exact literal in config files (`*.toml`, `*.md`, `*.json`) → Grep
|
|
42
|
+
✗ Path/filename patterns → Glob
|
|
43
|
+
✗ Single-file targeted edit → Read + Edit
|
|
44
|
+
|
|
45
|
+
## CLI Reference
|
|
46
|
+
|
|
47
|
+
### Search
|
|
48
|
+
```bash
|
|
49
|
+
ast-grep run -p '<pattern>' -l <lang> [paths...]
|
|
50
|
+
ast-grep run -p '<pattern>' -l typescript apps/api/src
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Rewrite (preview)
|
|
54
|
+
```bash
|
|
55
|
+
ast-grep run -p '<pattern>' -r '<replacement>' -l <lang> [paths...]
|
|
56
|
+
```
|
|
57
|
+
Shows diff. Add `-U` (or `--update-all`) to apply.
|
|
58
|
+
|
|
59
|
+
### Apply rewrite
|
|
60
|
+
```bash
|
|
61
|
+
ast-grep run -p '<pattern>' -r '<replacement>' -l <lang> -U [paths...]
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Inspect AST (debugging patterns)
|
|
65
|
+
```bash
|
|
66
|
+
ast-grep run -p '<pattern>' -l <lang> --debug-query=ast
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Strictness
|
|
70
|
+
```bash
|
|
71
|
+
--strictness smart # default — ignores trivia
|
|
72
|
+
--strictness relaxed # ignores comments
|
|
73
|
+
--strictness signature # ignores text — match by shape only
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Pattern Syntax (Quick)
|
|
77
|
+
|
|
78
|
+
- `$X` — single named metavariable (any node)
|
|
79
|
+
- `$$$ARGS` — multi-node metavariable (zero or more)
|
|
80
|
+
- `$_` — anonymous wildcard
|
|
81
|
+
- Same metavariable name = same content (linear pattern)
|
|
82
|
+
|
|
83
|
+
Examples:
|
|
84
|
+
| Want | Pattern |
|
|
85
|
+
|------|---------|
|
|
86
|
+
| any `console.log` call | `console.log($$$)` |
|
|
87
|
+
| `useState` with no arg | `useState()` |
|
|
88
|
+
| same var assigned to itself | `$X = $X` |
|
|
89
|
+
| arrow fn with single body expr | `($$$) => $BODY` |
|
|
90
|
+
| catch-all `try` no catch | `try { $$$ } finally { $$$ }` |
|
|
91
|
+
|
|
92
|
+
## Workflow — Search
|
|
93
|
+
|
|
94
|
+
1. Draft pattern. Run with `--debug-query=ast` once to verify shape.
|
|
95
|
+
2. Run real search: `ast-grep run -p '...' -l <lang> <paths>`.
|
|
96
|
+
3. If too many hits → narrow with `--strictness smart` or extra context nodes.
|
|
97
|
+
4. If zero hits → broaden to `$_` / `$$$`, recheck AST.
|
|
98
|
+
|
|
99
|
+
## Workflow — Rewrite
|
|
100
|
+
|
|
101
|
+
1. **Preview first**: never use `-U` until diff looks right.
|
|
102
|
+
2. Run preview: `ast-grep run -p '...' -r '...' -l <lang> <paths>`.
|
|
103
|
+
3. Read the diff. Confirm metavariables map correctly.
|
|
104
|
+
4. Apply: same command with `-U`.
|
|
105
|
+
5. Run your project's typecheck/lint (use the detected package manager — see `detect_node_pm` / `detect_rust` in `hooks/lib/detect.sh`) to verify zero regressions.
|
|
106
|
+
6. Save the pattern if reusable — when the `comemory` plugin is installed, persist it via its wrapper: `comemory.sh save "ast-grep <name> pattern" "<pattern + what it matches>" --kind pattern --tags "ast-grep"`.
|
|
107
|
+
|
|
108
|
+
## Self-Check Before Editing
|
|
109
|
+
|
|
110
|
+
> "Am I about to write a regex over multi-line code? → ast-grep instead."
|
|
111
|
+
> "Am I about to Edit-loop the same change across many files? → ast-grep rewrite instead."
|
|
112
|
+
> "Am I searching for code by shape (call form, signature, control flow)? → ast-grep, not Grep."
|
|
113
|
+
|
|
114
|
+
## Config (sgconfig.yml — optional, lazy)
|
|
115
|
+
|
|
116
|
+
If a recurring rule emerges (e.g. forbid `console.log` in apps/api), promote it to `sgconfig.yml`:
|
|
117
|
+
```bash
|
|
118
|
+
ast-grep new project # bootstrap config
|
|
119
|
+
ast-grep new rule # add reusable rule
|
|
120
|
+
ast-grep scan # run all configured rules
|
|
121
|
+
```
|
|
122
|
+
Hold off until pattern is proven across ≥3 files.
|
|
123
|
+
|
|
124
|
+
## Cross-Reference
|
|
125
|
+
|
|
126
|
+
- Memory: `skills/agent-memory/SKILL.md`
|
|
127
|
+
- Project rules: `AGENTS.md`, `CLAUDE.md`, and other host instruction files
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# ast-grep Advanced Usage
|
|
2
|
+
|
|
3
|
+
## Complex Rules (inline YAML)
|
|
4
|
+
|
|
5
|
+
For patterns beyond simple `--pattern`, use `scan` with inline YAML:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
mod.sh ast-grep scan 'id: find-async
|
|
9
|
+
language: rust
|
|
10
|
+
rule:
|
|
11
|
+
kind: function_item
|
|
12
|
+
has:
|
|
13
|
+
pattern: async fn \$NAME
|
|
14
|
+
stopBy: end'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Critical Rules
|
|
18
|
+
|
|
19
|
+
- `stopBy: end` required in `has`/`inside` for deep matching — without it, only direct children match
|
|
20
|
+
- `scan` rules require `kind` field
|
|
21
|
+
- `--max-results` only works in `scan` — use `| head -N` for `search`
|
|
22
|
+
- Escape `$` as `\$` in inline-rules strings (not needed in `--pattern` with single quotes)
|
|
23
|
+
|
|
24
|
+
## Common Patterns
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Rust: impl blocks for a trait
|
|
28
|
+
mod.sh ast-grep search 'impl $TRAIT for $TYPE { $$$BODY }' --lang rust
|
|
29
|
+
|
|
30
|
+
# Rust: async functions
|
|
31
|
+
mod.sh ast-grep search 'async fn $NAME($$$ARGS)' --lang rust
|
|
32
|
+
|
|
33
|
+
# Rust: functions returning Result
|
|
34
|
+
mod.sh ast-grep search 'fn $NAME($$$ARGS) -> Result<$$$>' --lang rust
|
|
35
|
+
|
|
36
|
+
# TypeScript: console.log calls
|
|
37
|
+
mod.sh ast-grep search 'console.log($$$ARGS)' --lang typescript
|
|
38
|
+
|
|
39
|
+
# File paths only (no content)
|
|
40
|
+
mod.sh ast-grep files 'impl $TRAIT for $TYPE { $$$BODY }' --lang rust
|
|
41
|
+
|
|
42
|
+
# Debug pattern parsing
|
|
43
|
+
mod.sh ast-grep debug 'fn $NAME($$$ARGS)' --lang rust
|
|
44
|
+
```
|