@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,355 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Toolu runtime config loader.
|
|
3
|
+
#
|
|
4
|
+
# Reads two layers of JSON config and merges them (project override wins):
|
|
5
|
+
# 1. <agent-config-dir>/toolu.config.json
|
|
6
|
+
# 2. <project-root>/<project-config-dir>/toolu.config.json
|
|
7
|
+
#
|
|
8
|
+
# Defaults are Claude Code-compatible (~/.claude + .claude/); callers can point
|
|
9
|
+
# them elsewhere via TOOLU_CONFIG_DIR and TOOLU_PROJECT_CONFIG_DIRNAME.
|
|
10
|
+
#
|
|
11
|
+
# Public API:
|
|
12
|
+
# toolu_load_config - load + cache the merged config
|
|
13
|
+
# toolu_enabled CAT NAME - 0 if enabled (default), 1 if disabled
|
|
14
|
+
# toolu_config_exists - 0 if any config file is on disk (cheap stat-only check)
|
|
15
|
+
# toolu_model CLASS - print the model alias routed to a work class
|
|
16
|
+
# toolu_string PATH DEF A... - print a config string at dotted PATH if it's in A..., else DEF
|
|
17
|
+
#
|
|
18
|
+
# Defaults: missing key = enabled. Malformed JSON or missing jq = all enabled
|
|
19
|
+
# with a single stderr warning.
|
|
20
|
+
|
|
21
|
+
_TOOLU_CONFIG_LIB_DIR="$(cd "${BASH_SOURCE%/*}" && pwd)"
|
|
22
|
+
# shellcheck source=host.sh
|
|
23
|
+
. "$_TOOLU_CONFIG_LIB_DIR/host.sh"
|
|
24
|
+
|
|
25
|
+
# Merged config is held in memory, not a temp file: hooks are short-lived
|
|
26
|
+
# processes, and a per-PID cache file under $TMPDIR was never cleaned up —
|
|
27
|
+
# one leaked file per hook invocation. $(...) subshells inherit the variable
|
|
28
|
+
# exactly like they inherited the file path, so load-once semantics hold.
|
|
29
|
+
TOOLU_CFG_JSON='{}'
|
|
30
|
+
TOOLU_CFG_LOADED=0
|
|
31
|
+
_TOOLU_HAS_JQ=""
|
|
32
|
+
|
|
33
|
+
_toolu_warn() {
|
|
34
|
+
printf 'toolu-config: %s\n' "$1" >&2
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
_toolu_agent_dir() {
|
|
38
|
+
toolu_config_root | tr -d '\n'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
_toolu_project_cfg_dirname() {
|
|
42
|
+
toolu_project_dirname | tr -d '\n'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
_toolu_user_cfg() {
|
|
46
|
+
local agent_dir
|
|
47
|
+
agent_dir=$(_toolu_agent_dir)
|
|
48
|
+
printf '%s/toolu.config.json' "$agent_dir"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
_toolu_project_cfg() {
|
|
52
|
+
toolu_project_config | tr -d '\n'
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
toolu_load_config() {
|
|
56
|
+
[ "$TOOLU_CFG_LOADED" = "1" ] && return 0
|
|
57
|
+
TOOLU_CFG_LOADED=1
|
|
58
|
+
|
|
59
|
+
if command -v jq >/dev/null 2>&1; then
|
|
60
|
+
_TOOLU_HAS_JQ=1
|
|
61
|
+
else
|
|
62
|
+
_TOOLU_HAS_JQ=0
|
|
63
|
+
_toolu_warn "jq missing; all components enabled"
|
|
64
|
+
TOOLU_CFG_JSON='{}'
|
|
65
|
+
return 0
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
local user_cfg project_cfg user_json='{}' project_json='{}'
|
|
69
|
+
user_cfg=$(_toolu_user_cfg)
|
|
70
|
+
project_cfg=$(_toolu_project_cfg)
|
|
71
|
+
|
|
72
|
+
if [ -f "$user_cfg" ]; then
|
|
73
|
+
if ! user_json=$(jq -e . "$user_cfg" 2>/dev/null); then
|
|
74
|
+
_toolu_warn "malformed JSON in $user_cfg; ignoring"
|
|
75
|
+
user_json='{}'
|
|
76
|
+
fi
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
if [ -n "$project_cfg" ] && [ -f "$project_cfg" ]; then
|
|
80
|
+
if ! project_json=$(jq -e . "$project_cfg" 2>/dev/null); then
|
|
81
|
+
_toolu_warn "malformed JSON in $project_cfg; ignoring"
|
|
82
|
+
project_json='{}'
|
|
83
|
+
fi
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
TOOLU_CFG_JSON=$(jq -cn --argjson u "$user_json" --argjson p "$project_json" \
|
|
87
|
+
'$u * $p' 2>/dev/null) || TOOLU_CFG_JSON='{}'
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
toolu_enabled() {
|
|
91
|
+
local category="$1" name="$2"
|
|
92
|
+
toolu_load_config
|
|
93
|
+
[ "$_TOOLU_HAS_JQ" = "1" ] || return 0
|
|
94
|
+
local val
|
|
95
|
+
val=$(jq -r --arg c "$category" --arg n "$name" \
|
|
96
|
+
'if (.[$c]? // {}) | has($n) then .[$c][$n] | tostring else "missing" end' \
|
|
97
|
+
<<< "$TOOLU_CFG_JSON" 2>/dev/null)
|
|
98
|
+
[ "$val" = "false" ] && return 1
|
|
99
|
+
return 0
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
# Default-OFF inverse of toolu_enabled: 0 only when .<cat>.<name> is boolean
|
|
103
|
+
# `true`; absent/false/non-true/malformed/no-jq -> 1. Stricter than
|
|
104
|
+
# toolu_enabled_explicit below, which also accepts the string "true" — use this
|
|
105
|
+
# for machine-written markers (e.g. comemory.setup_done) where only the JSON
|
|
106
|
+
# boolean is ever valid.
|
|
107
|
+
toolu_flag_true() {
|
|
108
|
+
local category="$1" name="$2"
|
|
109
|
+
toolu_load_config
|
|
110
|
+
[ "$_TOOLU_HAS_JQ" = "1" ] || return 1
|
|
111
|
+
local val
|
|
112
|
+
val=$(jq -r --arg c "$category" --arg n "$name" \
|
|
113
|
+
'if (.[$c]? // {}) | has($n) then (.[$c][$n] == true) else false end' \
|
|
114
|
+
<<< "$TOOLU_CFG_JSON" 2>/dev/null)
|
|
115
|
+
[ "$val" = "true" ] && return 0
|
|
116
|
+
return 1
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
# Mirror of toolu_flag_true for explicit opt-outs: 0 only when .<cat>.<name>
|
|
120
|
+
# is boolean `false`; absent/true/non-false/malformed/no-jq -> 1. Separates
|
|
121
|
+
# "user explicitly said no" from "user never set the flag" — e.g. session-start
|
|
122
|
+
# suppresses the /comemory:setup nudge when setup_done is explicitly false.
|
|
123
|
+
toolu_flag_false() {
|
|
124
|
+
local category="$1" name="$2"
|
|
125
|
+
toolu_load_config
|
|
126
|
+
[ "$_TOOLU_HAS_JQ" = "1" ] || return 1
|
|
127
|
+
local val
|
|
128
|
+
val=$(jq -r --arg c "$category" --arg n "$name" \
|
|
129
|
+
'if (.[$c]? // {}) | has($n) then (.[$c][$n] == false) else false end' \
|
|
130
|
+
<<< "$TOOLU_CFG_JSON" 2>/dev/null)
|
|
131
|
+
[ "$val" = "true" ] && return 0
|
|
132
|
+
return 1
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# Like toolu_enabled but DEFAULT OFF: returns 0 only when the key is
|
|
136
|
+
# explicitly `true` (boolean, or the string "true" — laxer than
|
|
137
|
+
# toolu_flag_true above). For hand-edited opt-in components (e.g. the
|
|
138
|
+
# session-end comemory reminder) where the default-enabled opt-out semantics
|
|
139
|
+
# are wrong. Missing jq or a missing/non-true value -> 1 (disabled).
|
|
140
|
+
toolu_enabled_explicit() {
|
|
141
|
+
local category="$1" name="$2"
|
|
142
|
+
toolu_load_config
|
|
143
|
+
[ "$_TOOLU_HAS_JQ" = "1" ] || return 1
|
|
144
|
+
local val
|
|
145
|
+
val=$(jq -r --arg c "$category" --arg n "$name" \
|
|
146
|
+
'(.[$c]? // {})[$n]? | tostring' <<< "$TOOLU_CFG_JSON" 2>/dev/null)
|
|
147
|
+
[ "$val" = "true" ] && return 0
|
|
148
|
+
return 1
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
# ── Model-tier routing ──────────────────────────────────────────────────────
|
|
152
|
+
# Which model runs a delegated task is a function of the WORK CLASS, not of the
|
|
153
|
+
# task's prose. Callers name the class; this resolves it to a Claude Code model
|
|
154
|
+
# alias to hand the Agent tool's `model:` field.
|
|
155
|
+
#
|
|
156
|
+
# Aliases, not version ids, are the contract: `sonnet` keeps meaning "the
|
|
157
|
+
# current mid tier" across model releases, so routing survives a new model
|
|
158
|
+
# generation with zero edits. `inherit` is accepted as an override value and
|
|
159
|
+
# means "whatever the lead thread is running".
|
|
160
|
+
#
|
|
161
|
+
# Precedence: `.models.<class>` in config -> built-in default. An unrecognized
|
|
162
|
+
# value is REJECTED (warn + fall back to the default): routing must never emit
|
|
163
|
+
# a model name the Agent tool would refuse, which would fail the delegation
|
|
164
|
+
# instead of just mis-tiering it.
|
|
165
|
+
#
|
|
166
|
+
# The alias list is duplicated inside the plan-ledger step validator
|
|
167
|
+
# (hooks/lib/plan-ledger-parse.sh), which is a jq-only lib that must not drag
|
|
168
|
+
# the config loader in. Parity between the two is enforced by
|
|
169
|
+
# hooks/lib/__tests__/plan-ledger-model.bats.
|
|
170
|
+
TOOLU_MODEL_ALIASES="haiku sonnet opus fable inherit"
|
|
171
|
+
TOOLU_MODEL_CLASSES="mechanical exploration implementation review synthesis architecture"
|
|
172
|
+
|
|
173
|
+
# _toolu_model_default CLASS -> built-in alias for CLASS; returns 1 if unknown.
|
|
174
|
+
_toolu_model_default() {
|
|
175
|
+
case "$1" in
|
|
176
|
+
mechanical) printf 'haiku' ;;
|
|
177
|
+
exploration) printf 'sonnet' ;;
|
|
178
|
+
implementation) printf 'sonnet' ;;
|
|
179
|
+
review) printf 'sonnet' ;;
|
|
180
|
+
synthesis) printf 'opus' ;;
|
|
181
|
+
architecture) printf 'opus' ;;
|
|
182
|
+
*) return 1 ;;
|
|
183
|
+
esac
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
# toolu_model CLASS -> print the model alias for CLASS.
|
|
187
|
+
# Unknown class: warn, print nothing, return 1 (a caller typo must be loud, not
|
|
188
|
+
# silently routed to some default tier). Missing jq: the built-in default.
|
|
189
|
+
toolu_model() {
|
|
190
|
+
local class="$1" def val
|
|
191
|
+
if ! def=$(_toolu_model_default "$class"); then
|
|
192
|
+
_toolu_warn "unknown model class '$class' (known: $TOOLU_MODEL_CLASSES)"
|
|
193
|
+
return 1
|
|
194
|
+
fi
|
|
195
|
+
toolu_load_config
|
|
196
|
+
if [ "$_TOOLU_HAS_JQ" != "1" ]; then
|
|
197
|
+
printf '%s' "$def"
|
|
198
|
+
return 0
|
|
199
|
+
fi
|
|
200
|
+
val=$(jq -r --arg c "$class" \
|
|
201
|
+
'((.models? // {})[$c]? // "") | tostring' <<< "$TOOLU_CFG_JSON" 2>/dev/null)
|
|
202
|
+
[ -n "$val" ] || { printf '%s' "$def"; return 0; }
|
|
203
|
+
case " $TOOLU_MODEL_ALIASES " in
|
|
204
|
+
*" $val "*) printf '%s' "$val" ;;
|
|
205
|
+
*)
|
|
206
|
+
_toolu_warn "models.$class: '$val' is not a model alias ($TOOLU_MODEL_ALIASES); using $def"
|
|
207
|
+
printf '%s' "$def"
|
|
208
|
+
;;
|
|
209
|
+
esac
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
# ── Codex model + effort routing ───────────────────────────────────────────
|
|
213
|
+
# Claude keeps the long-standing `.models.<class>` alias contract above.
|
|
214
|
+
# Codex uses a separate nested namespace because its model slugs and reasoning
|
|
215
|
+
# effort are independent values:
|
|
216
|
+
# .models.codex.<class>.model
|
|
217
|
+
# .models.codex.<class>.reasoningEffort
|
|
218
|
+
#
|
|
219
|
+
# toolu_codex_model CLASS prints two tab-separated fields followed by a newline:
|
|
220
|
+
# `<model>\t<reasoning-effort>`. Callers can consume them safely with IFS/read.
|
|
221
|
+
TOOLU_CODEX_REASONING_EFFORTS="low medium high xhigh max ultra"
|
|
222
|
+
|
|
223
|
+
_toolu_codex_model_default() {
|
|
224
|
+
case "$1" in
|
|
225
|
+
mechanical) printf 'gpt-5.6-luna\tmedium' ;;
|
|
226
|
+
exploration) printf 'gpt-5.6-terra\tmedium' ;;
|
|
227
|
+
implementation) printf 'gpt-5.6-terra\tmedium' ;;
|
|
228
|
+
review) printf 'gpt-5.6-terra\thigh' ;;
|
|
229
|
+
synthesis) printf 'gpt-5.6-sol\thigh' ;;
|
|
230
|
+
architecture) printf 'gpt-5.6-sol\thigh' ;;
|
|
231
|
+
*) return 1 ;;
|
|
232
|
+
esac
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
toolu_codex_model() {
|
|
236
|
+
local class="$1" defaults def_model def_effort model_type model effort_type effort
|
|
237
|
+
if ! defaults=$(_toolu_codex_model_default "$class"); then
|
|
238
|
+
_toolu_warn "unknown model class '$class' (known: $TOOLU_MODEL_CLASSES)"
|
|
239
|
+
return 1
|
|
240
|
+
fi
|
|
241
|
+
IFS=$'\t' read -r def_model def_effort <<<"$defaults"
|
|
242
|
+
toolu_load_config
|
|
243
|
+
if [ "$_TOOLU_HAS_JQ" != 1 ]; then
|
|
244
|
+
printf '%s\t%s\n' "$def_model" "$def_effort"
|
|
245
|
+
return 0
|
|
246
|
+
fi
|
|
247
|
+
|
|
248
|
+
model_type=$(jq -r --arg c "$class" \
|
|
249
|
+
'((.models?.codex? // {})[$c]?.model? // null) | type' \
|
|
250
|
+
<<<"$TOOLU_CFG_JSON" 2>/dev/null)
|
|
251
|
+
model=$(jq -r --arg c "$class" \
|
|
252
|
+
'((.models?.codex? // {})[$c]?.model? // "") | if type == "string" then . else "" end' \
|
|
253
|
+
<<<"$TOOLU_CFG_JSON" 2>/dev/null)
|
|
254
|
+
case "$model_type" in
|
|
255
|
+
null) model="$def_model" ;;
|
|
256
|
+
string)
|
|
257
|
+
if [ -z "$model" ]; then
|
|
258
|
+
_toolu_warn "models.codex.$class.model: value is not a non-empty string; using $def_model"
|
|
259
|
+
model="$def_model"
|
|
260
|
+
fi
|
|
261
|
+
;;
|
|
262
|
+
*)
|
|
263
|
+
_toolu_warn "models.codex.$class.model: value is not a non-empty string; using $def_model"
|
|
264
|
+
model="$def_model"
|
|
265
|
+
;;
|
|
266
|
+
esac
|
|
267
|
+
|
|
268
|
+
effort_type=$(jq -r --arg c "$class" \
|
|
269
|
+
'((.models?.codex? // {})[$c]?.reasoningEffort? // null) | type' \
|
|
270
|
+
<<<"$TOOLU_CFG_JSON" 2>/dev/null)
|
|
271
|
+
effort=$(jq -r --arg c "$class" \
|
|
272
|
+
'((.models?.codex? // {})[$c]?.reasoningEffort? // "") | if type == "string" then . else "" end' \
|
|
273
|
+
<<<"$TOOLU_CFG_JSON" 2>/dev/null)
|
|
274
|
+
case "$effort_type" in
|
|
275
|
+
null) effort="$def_effort" ;;
|
|
276
|
+
string)
|
|
277
|
+
case " $TOOLU_CODEX_REASONING_EFFORTS " in
|
|
278
|
+
*" $effort "*) ;;
|
|
279
|
+
*)
|
|
280
|
+
_toolu_warn "models.codex.$class.reasoningEffort: '$effort' is not supported ($TOOLU_CODEX_REASONING_EFFORTS); using $def_effort"
|
|
281
|
+
effort="$def_effort"
|
|
282
|
+
;;
|
|
283
|
+
esac
|
|
284
|
+
;;
|
|
285
|
+
*)
|
|
286
|
+
_toolu_warn "models.codex.$class.reasoningEffort: value is not a string; using $def_effort"
|
|
287
|
+
effort="$def_effort"
|
|
288
|
+
;;
|
|
289
|
+
esac
|
|
290
|
+
|
|
291
|
+
printf '%s\t%s\n' "$model" "$effort"
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
# ── Generic string-enum reader ──────────────────────────────────────────────
|
|
295
|
+
# toolu_string PATH DEFAULT ALLOWED...
|
|
296
|
+
# PATH is a dotted jq path into the merged config (e.g. "agentTier.mode").
|
|
297
|
+
# Prints the value at PATH if it is a JSON string AND is one of ALLOWED;
|
|
298
|
+
# otherwise falls back to DEFAULT.
|
|
299
|
+
#
|
|
300
|
+
# Same warn-and-fall-back shape as toolu_model: a key that is simply absent
|
|
301
|
+
# falls back to DEFAULT silently (an unset key is not a mistake); a key that
|
|
302
|
+
# IS present but doesn't qualify (wrong type, or a string outside ALLOWED)
|
|
303
|
+
# warns once on stderr before falling back — that is very likely a typo the
|
|
304
|
+
# author should see.
|
|
305
|
+
toolu_string() {
|
|
306
|
+
local path="$1" def="$2"
|
|
307
|
+
shift 2
|
|
308
|
+
local allowed=("$@")
|
|
309
|
+
toolu_load_config
|
|
310
|
+
if [ "$_TOOLU_HAS_JQ" != "1" ]; then
|
|
311
|
+
printf '%s' "$def"
|
|
312
|
+
return 0
|
|
313
|
+
fi
|
|
314
|
+
local out vtype vval
|
|
315
|
+
out=$(jq -r --arg p "$path" '
|
|
316
|
+
($p | split(".")) as $ks
|
|
317
|
+
| (getpath($ks)) as $v
|
|
318
|
+
| [($v | type), (if ($v | type) == "string" then $v else "" end)]
|
|
319
|
+
| @tsv
|
|
320
|
+
' <<< "$TOOLU_CFG_JSON" 2>/dev/null)
|
|
321
|
+
IFS=$'\t' read -r vtype vval <<< "$out"
|
|
322
|
+
|
|
323
|
+
case "$vtype" in
|
|
324
|
+
null|'')
|
|
325
|
+
printf '%s' "$def"
|
|
326
|
+
;;
|
|
327
|
+
string)
|
|
328
|
+
local a
|
|
329
|
+
for a in "${allowed[@]}"; do
|
|
330
|
+
if [ "$vval" = "$a" ]; then
|
|
331
|
+
printf '%s' "$vval"
|
|
332
|
+
return 0
|
|
333
|
+
fi
|
|
334
|
+
done
|
|
335
|
+
_toolu_warn "$path: '$vval' is not an allowed value (${allowed[*]}); using $def"
|
|
336
|
+
printf '%s' "$def"
|
|
337
|
+
;;
|
|
338
|
+
*)
|
|
339
|
+
_toolu_warn "$path: value is not a string; using $def"
|
|
340
|
+
printf '%s' "$def"
|
|
341
|
+
;;
|
|
342
|
+
esac
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
# Return 0 if any config file is on disk. Stat-only; no jq, no load. Used by
|
|
346
|
+
# hot-path hooks (e.g. mcp-blocker) to skip config-load entirely when no
|
|
347
|
+
# user has opted in.
|
|
348
|
+
toolu_config_exists() {
|
|
349
|
+
local user_cfg project_cfg
|
|
350
|
+
user_cfg=$(_toolu_user_cfg)
|
|
351
|
+
[ -f "$user_cfg" ] && return 0
|
|
352
|
+
project_cfg=$(_toolu_project_cfg)
|
|
353
|
+
[ -n "$project_cfg" ] && [ -f "$project_cfg" ] && return 0
|
|
354
|
+
return 1
|
|
355
|
+
}
|