docks-kit 0.1.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/AGENTS.md +99 -0
- package/LICENSE +21 -0
- package/README.md +124 -0
- package/SoT/.agents/skills.txt +14 -0
- package/SoT/.claude/CLAUDE.md +146 -0
- package/SoT/.claude/fetch-usage.sh +66 -0
- package/SoT/.claude/hooks/notify.sh +14 -0
- package/SoT/.claude/mcp-servers.json +10 -0
- package/SoT/.claude/settings.json +258 -0
- package/SoT/.claude/statusline.sh +175 -0
- package/SoT/.codex/AGENTS.md +75 -0
- package/SoT/.codex/agents/.gitkeep +1 -0
- package/SoT/.codex/config.toml +45 -0
- package/SoT/.codex/plugins/marketplace.json +50 -0
- package/SoT/.codex/rules/docks.rules +116 -0
- package/SoT/models.json +28 -0
- package/SoT/toolchain.json +26 -0
- package/cli/docs/flags.md +48 -0
- package/cli/docs/install.md +56 -0
- package/cli/docs/models.md +42 -0
- package/cli/docs/modifiers.md +33 -0
- package/cli/docs/overview.md +37 -0
- package/cli/docs/platforms.md +31 -0
- package/cli/docs/plugins.md +44 -0
- package/cli/docs/sync-layers.md +43 -0
- package/cli/docs/toolchain.md +54 -0
- package/cli/src/commands/docs.ts +65 -0
- package/cli/src/commands/model.ts +60 -0
- package/cli/src/commands/models.ts +46 -0
- package/cli/src/commands/plugins.ts +34 -0
- package/cli/src/commands/skills.ts +37 -0
- package/cli/src/commands/status.ts +79 -0
- package/cli/src/commands/sync.ts +134 -0
- package/cli/src/commands/toolchain.ts +42 -0
- package/cli/src/engine.ts +36 -0
- package/cli/src/kitHome.ts +31 -0
- package/cli/src/main.ts +60 -0
- package/cli/src/manifests.ts +105 -0
- package/cli/src/md.d.ts +4 -0
- package/cli/tsconfig.json +14 -0
- package/docks-kit +61 -0
- package/lib/claude.sh +846 -0
- package/lib/codex.sh +518 -0
- package/lib/common.sh +229 -0
- package/lib/engine.sh +153 -0
- package/lib/skills.sh +373 -0
- package/lib/toolchain.sh +222 -0
- package/notification.mp3 +0 -0
- package/package.json +39 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Canonical instructions for coding agents working on this project. Compatible with OpenAI Codex, Claude Code (via `@AGENTS.md` import in `CLAUDE.md`), OpenCode, VS Code Copilot, and any other [agents.md](https://agents.md/)-aware tool.
|
|
4
|
+
|
|
5
|
+
## Repository purpose
|
|
6
|
+
|
|
7
|
+
Portable configuration kit for AI coding agents. Per-tool Single Source of Truth (SoT) directories get deployed to each tool's user-config location via `./docks-kit sync` — clone once, sync to your home directory, get a consistent AI-assisted dev environment everywhere. The kit focuses on **token efficiency without sacrificing quality**: every setting and hook is tuned to minimize token consumption while preserving rigorous output. When adding or editing anything, ask: *does this change reduce tokens without weakening correctness?*
|
|
8
|
+
|
|
9
|
+
Tool-specific instructions live alongside this file:
|
|
10
|
+
- **`CLAUDE.md`** — Claude Code SoT (`SoT/.claude/`), env vars, hooks, plugins, RTK, status line, session management, permission mode, open concerns.
|
|
11
|
+
- Codex uses this `AGENTS.md` file plus the Codex SoT under `SoT/.codex/`; no separate root `CODEX.md` is needed.
|
|
12
|
+
|
|
13
|
+
## Repository layout (cross-cutting)
|
|
14
|
+
|
|
15
|
+
| Path | Purpose |
|
|
16
|
+
|------|---------|
|
|
17
|
+
| `docks-kit` | CLI launcher: runs the compiled binary in `cli/dist/` when present, otherwise Bun-from-source (auto-installs Bun + `node_modules`). Front-end over the bash engine; idempotent, flag-gated for destructive reconciliation |
|
|
18
|
+
| `lib/engine.sh` | Engine entry — direct modes `sync` / `model` / `toolchain`; the zero-dependency escape hatch when Bun is unavailable: `bash lib/engine.sh <same args>` |
|
|
19
|
+
| `lib/toolchain.sh` | Verified-version floors for external tools (RTK, …) over `SoT/toolchain.json` |
|
|
20
|
+
| `lib/` | Shared sync helpers — `common.sh` for flag parsing/validation/preflight, plus per-tool `claude.sh` / `codex.sh` / `skills.sh` sync implementations |
|
|
21
|
+
| `cli/` | Effect-TS CLI (typed front-end over the engine) + bundled docs topics |
|
|
22
|
+
| `SoT/models.json` | Kit-verified model catalog |
|
|
23
|
+
| `SoT/toolchain.json` | Toolchain floors manifest (verified pins consumed by `lib/toolchain.sh`) |
|
|
24
|
+
| `install.sh` | Global installer |
|
|
25
|
+
| `.github/workflows/release-cli.yml` | `cli-v*` release binaries + npm publish |
|
|
26
|
+
| `README.md` | Front door |
|
|
27
|
+
| `package.json` / `bun.lock` | npm package: `bin` = `cli/src/main.ts`; bundles `lib/` + `SoT/` |
|
|
28
|
+
| `SoT/.agents/skills.txt` | Universal-skill manifest. One [agentskills.io](https://agentskills.io) slug per line; `lib/skills.sh` runs `npx skills add` for each missing entry into `~/.agents/skills/`, where Codex et al. discover it natively and Claude Code follows a symlink at `~/.claude/skills/` |
|
|
29
|
+
| `notification.mp3` | Audio asset for Notification hooks (consumed by Claude Code today; tool-agnostic file) |
|
|
30
|
+
| `docs/plans/` | Multi-commit work-item plans (`active/` with status in frontmatter, plus `finished/` archive). Convention: `docs/plans/AGENTS.md` |
|
|
31
|
+
| `CLAUDE.md` | Claude-specific instructions; imports this `AGENTS.md` |
|
|
32
|
+
| `AGENTS.md` | This file — tool-agnostic instructions |
|
|
33
|
+
|
|
34
|
+
Codex SoT notes:
|
|
35
|
+
- `SoT/.codex/AGENTS.md` deploys to `~/.codex/AGENTS.md` as global Codex instructions.
|
|
36
|
+
- `SoT/.codex/config.toml` pins Codex to `model = "gpt-5.5"`, sets reasoning effort/summaries (`xhigh` + `detailed`), `model_verbosity = "medium"` (Codex ships gpt-5.5 at `low`; medium restores the API default), `personality`, live top-level `web_search`, workspace-write sandboxing with sandboxed command network access, cross-session `memories` (+ dedicated note tools), `[agents]` subagent limits (`max_threads = 12`, `max_depth = 2` — intentionally above Codex defaults for broad parallel kit work; deeper recursion increases cost and predictability risk), a 128 KiB `project_doc_max_bytes` budget for the repo-side AGENTS.md chain (the global `~/.codex/AGENTS.md` is uncapped and not counted), and enables the Docks plugins as `docks@docks` + `session-relay@docks`.
|
|
37
|
+
- `SoT/.codex/rules/*.rules` deploys to `~/.codex/rules/` as kit-managed Codex command policy. This is Codex's equivalent of permission allow/prompt/block rules; user-learned approvals in `~/.codex/rules/default.rules` are preserved.
|
|
38
|
+
- `SoT/.codex/plugins/marketplace.json` deploys to Codex's personal marketplace path at `~/.agents/plugins/marketplace.json`; when the `codex` CLI is available, sync reruns `codex plugin add <plugin@marketplace>` for enabled SoT plugins so stale cached installs are refreshed.
|
|
39
|
+
- The `codex` CLI binary is upstream-owned, not kit-owned. The official standalone installer keeps package metadata under `$CODEX_HOME/packages/standalone` and places the `codex` symlink in `~/.local/bin` by default; sync only warns with a download-then-run installer command when the CLI is missing. Existing installs can self-update with `codex update`; npm and Homebrew remain upstream alternatives.
|
|
40
|
+
- `SoT/.codex/AGENTS.md` deliberately does not import `@RTK.md`: RTK's published Codex integration is prompt-file based rather than hook based, so importing it leaks implementation detail into agent-visible context. Use Codex hooks for RTK only after the kit installs a hook-backed Codex integration.
|
|
41
|
+
|
|
42
|
+
For per-tool SoT layouts (`SoT/.claude/`, `SoT/.codex/`), see the matching SoT directory.
|
|
43
|
+
|
|
44
|
+
## Engineering rules
|
|
45
|
+
|
|
46
|
+
- **Idempotent operations.** Every step in `lib/engine.sh` and `lib/*.sh` must be safe to re-run. Settings merges, plugin installs, and marketplace adds are all idempotent — re-running with no SoT changes is a no-op.
|
|
47
|
+
- **Targeted syncs.** `./docks-kit sync` accepts positional targets: `claude`, `codex`, and `agents`. Use the narrowest target that matches the SoT change (for example, `./docks-kit sync codex` for Codex-only config edits); targets can be combined with `--dry-run`, `--skip-rtk`, `--reconcile`, `--prune`, `--yes` (auto-accept toolchain prompts), and the deploy-time modifiers `--claude-compact-window=<tokens>` / `--claude-permissive` / `--claude-model=<m>` / `--codex-model=<m>` (see `CLAUDE.md` § Deploy-time modifiers).
|
|
48
|
+
- **Additive by default.** Keys present in deployed config but absent from SoT are preserved on default sync. This protects user-only additions, but means drift accumulates — neither flag-less reset can clean it up. The one exception is the Claude `removed` manifest (`claude::_removed_manifest`), a curated list of unambiguous kit-owned artifacts that `claude::sync_removals` force-prunes on every sync; see `CLAUDE.md` § Pruning stale artifacts.
|
|
49
|
+
- **`--reconcile` / `--prune` are the kit-owned reconcile flags.** Orthogonal — `--reconcile` reconciles the settings layer (SoT-declared keys/tables/arrays win; user-only keys and nested objects are preserved; permissions arrays are replaced wholesale by SoT). `--prune` uninstalls kit-managed installations not in the SoT (plugins, marketplaces, and `~/.agents/skills/*` entries tracked in `~/.agents/.kit-managed-skills`). Combine for a full reset to SoT's kit-managed scope. User-only additions outside the kit's scope (custom env vars, mcpServers, manually-installed skills, third-party plugins not declared in SoT) are always preserved. Each tool's per-tool file documents the specific paths and diff recipes.
|
|
50
|
+
- **SOLID-aligned libraries.** `lib/common.sh` owns shared primitives plus flag parsing/validation. `lib/toolchain.sh` owns the verified-version gate over `SoT/toolchain.json`. Each `lib/<tool>.sh` owns the tool-specific logic (plugin install passes, marketplace add) plus its toolchain install callbacks. `lib/engine.sh` is the thin orchestrator: source common → detect SoTs → dispatch. The TypeScript CLI (`cli/src/`) is a typed front-end whose single mutation seam is spawning `lib/engine.sh`.
|
|
51
|
+
- **Small, reviewable changes.** Bundled multi-concern PRs are harder to review and revert. Split an engine/CLI change and a per-tool config change unless the change requires atomicity.
|
|
52
|
+
- **Dry-run before destructive flags.** Always preview with `./docks-kit sync --dry-run` (or the relevant `diff <(jq -S …)` recipe in the per-tool file) before invoking `--reconcile` or `--prune`. User-added permissions / env vars / plugins absent from SoT will be discarded.
|
|
53
|
+
- **SoT prompt files are rules, not explanation.** `SoT/.claude/CLAUDE.md` and `SoT/.codex/AGENTS.md` are loaded into every agent session's prompt context — every line costs prompt tokens on every turn for every user. Restrict their content to rules, heuristics, and `<constraint>` blocks the agent must *act on* during a turn. Do NOT add inline source citations (`Source: …`, attributed quotes), "why this rule exists" preface text, version-watermarking trivia (e.g. "Distilled from X v2.0, captured 2025-11-07"), per-bug workarounds, or installation instructions. Provenance, motivation, and historical context belong in `CLAUDE.md` / `AGENTS.md` at the repo root (humans read once) or in commit messages — never in the SoT. For every line, apply the official test: would removing it cause the agent to make mistakes? If not, cut it — over-instruction degrades adherence on current frontier models.
|
|
54
|
+
- **Cache-invariance for kit-authored prompt surfaces.** Never put timestamps, counters, or mutable state into SoT prompt files, hook outputs that land in the cached prefix, or tool definitions — cache breaks force cold-start writes. Dynamic context belongs in runtime-injected messages (e.g. SessionStart hook output), which is exactly how the kit's date/config injection works.
|
|
55
|
+
|
|
56
|
+
## Code style
|
|
57
|
+
|
|
58
|
+
- Bash: `set -euo pipefail`, quoted variables, `[[ ]]` over `[ ]`, function-scoped `local`. Match `lib/engine.sh`.
|
|
59
|
+
- JSON config: edit the SoT (`SoT/<tool>/`) and run `./docks-kit sync`. Never edit deployed config (`~/.claude/`, `~/.codex/`) directly.
|
|
60
|
+
|
|
61
|
+
## Security
|
|
62
|
+
|
|
63
|
+
- No secrets in SoT. The kit's SoT directories are committed; treat them as declarative config only.
|
|
64
|
+
- Treat external installers (RTK, plugin marketplaces) as untrusted input. Prefer download-then-run over `curl … | bash` — stream truncation has bitten this kit before (see `CLAUDE.md` § RTK).
|
|
65
|
+
- **Pin, never float.** Every kit-driven install is pinned to a `SoT/toolchain.json` `verified` version or gated by one — no `@latest` npm/bun installs (Shai-Hulud-class worm surface), no mutable action tags in workflows (commit SHAs only), installer scripts fetched from version tags where upstream supports it. New install surface ⇒ manifest pin first. Details: the `toolchain-context` skill and `cli/docs/toolchain.md`.
|
|
66
|
+
|
|
67
|
+
## Testing
|
|
68
|
+
|
|
69
|
+
No automated tests yet. Verify changes via `./docks-kit sync --dry-run`, per-tool sanity (`/doctor`, `/plugin`, etc.), and `diff <(jq -S . <SoT>) <(jq -S . <deployed>)` recipes from the per-tool file. Shell-script tests are tracked in `docs/plans/`.
|
|
70
|
+
|
|
71
|
+
## Skills
|
|
72
|
+
|
|
73
|
+
This project ships **kit-mechanic skills** under `.claude/skills/` — narrowly-scoped references for how the sync engine (`lib/engine.sh`) itself works (settings merge, plugin bootstrap, universal-skill install, Codex TOML merge, sync orchestration). They cost prompt tokens only inside this repo's sessions and document regression-prone bash/awk/jq logic in `lib/*.sh`. **Pipeline content** (multi-agent slash commands, refactor/security/docs workflows, parallel-scanner agents) belongs in the separate [DocksDocks/docks](https://github.com/DocksDocks/docks) plugin — not here. Project-level agents under `.claude/agents/` follow the same rule: kit-mechanic agents that wrap kit-mechanic skills are permitted; pipeline agents live in the docks plugin.
|
|
74
|
+
|
|
75
|
+
<constraint>
|
|
76
|
+
When a kit-mechanic skill, its `references/`, or a wrapper agent (`.claude/agents/*.md` + its `.codex/agents/*.toml` twin) cites `lib/*.sh` / `lib/engine.sh` internals, name the **enclosing function + a semantic anchor** (e.g. `claude::_plugins_uninstall, the has($n) guard`) — never a raw `file:NNN` line number, which goes stale on every refactor. Keep exactly one coarse `metadata.source_files[].lines` range per skill file as the sole intentional line-number touchpoint.
|
|
77
|
+
</constraint>
|
|
78
|
+
|
|
79
|
+
**Universal-skill bootstrap.** `SoT/.agents/skills.txt` declares [agentskills.io](https://agentskills.io/specification) slugs the kit installs to `~/.agents/skills/` on every machine via `lib/skills.sh`. The bootstrap invokes `npx skills add <slug> -g -y -a claude-code codex` per missing skill — `<slug>` comes first because the CLI's `-a/--agent` flag is variadic and would otherwise swallow it. Naming **both** agents (`claude-code` + `codex`, the kit's support matrix) keeps the CLI in multi-agent mode: it writes the canonical `SKILL.md` to the universal `~/.agents/skills/<name>/` path — which Codex reads natively (per [OpenAI's Codex docs](https://developers.openai.com/codex/skills/), `$HOME/.agents/skills` is a user-level skill source) — and symlinks `~/.claude/skills/<name>` → it for Claude Code, which wants its own per-tool directory. A *single* `-a claude-code` would instead trigger a copy-direct shortcut (a real copy into `~/.claude/skills/`, no canonical path, Codex uncovered); `-a '*'` would over-reach into every AI tool the CLI can detect (~50). Add a new universal skill by appending one `<owner>/<repo>` line to `skills.txt` and re-running `./docks-kit sync` — idempotent: existing skills are skipped (`lib/skills.sh` pre-checks `~/.agents/skills/<name>`). Skills that depend on a separate CLI binary get an explicit auto-install helper in `lib/skills.sh` (e.g. `skills::sync_agent_browser_cli` runs `npm install -g agent-browser` + `agent-browser install --with-deps` on Linux; the `--with-deps` flag may prompt for sudo to install system libs). That helper also **self-upgrades** a present-but-stale binary: when `agent-browser`'s installed version is older than npm's `latest` it re-runs `npm install -g agent-browser` (the `skills::_agent_browser_newer_npm` numeric-sort compare never downgrades a locally-newer pre-release, and skips silently when npm is absent/offline); the Chrome download is not repeated on upgrade. A second such helper, `skills::sync_effect_solutions_cli`, installs the optional `effect-solutions` Effect-docs CLI used by the `effect-kit` plugin: gated on `effect-kit` being enabled in SoT, it auto-installs Bun when absent (download-then-run, never `curl | bash`) and symlinks **both** `bun` and the CLI into `~/.local/bin`. Linking bun too is mandatory — the CLI's `#!/usr/bin/env bun` shebang needs `bun` on PATH at run time — and `~/.local/bin` is the only dir reliably on the *non-interactive* agent PATH, since `~/.bashrc`'s "if not interactive, return" guard means rc PATH edits never reach agent shells (the same PATH reason the official Codex standalone installer targets `~/.local/bin`).
|
|
80
|
+
|
|
81
|
+
## Plans
|
|
82
|
+
|
|
83
|
+
<constraint>
|
|
84
|
+
Multi-commit work plans live in `docs/plans/active/` (status is a frontmatter field) and `docs/plans/finished/` (archive). Every plan file is a complete handoff document — `goal`, `Steps`, `Acceptance criteria`, `Review` — so any agent can pick one up cold. Skills handle every operation: `plan-init` (bootstrap/migrate), `plan-manager` (list/show/start/block/ship/new, auto-commit on transition, self-review on draft), `plan-review` (verification). Trigger by natural language or the matching `plan-*` skill. `active/` is multi-occupancy.
|
|
85
|
+
</constraint>
|
|
86
|
+
|
|
87
|
+
The full convention (frontmatter schema, body sections, self-review loop, open-questions, age tokens) lives in `docs/plans/AGENTS.md`. `docs/plans/CLAUDE.md` is a one-line `@AGENTS.md` import for Claude Code's nested discovery.
|
|
88
|
+
|
|
89
|
+
Distinct from per-tool **Open Concerns** sections (wait-on-upstream
|
|
90
|
+
blockers tied to a vendor shipping a fix — these live inside the per-tool
|
|
91
|
+
file): plans are kit-internal work we control; Open Concerns is
|
|
92
|
+
conditions-for-resolution.
|
|
93
|
+
|
|
94
|
+
Plugin-internal work (skills, commands, agents) belongs in each plugin's
|
|
95
|
+
own repo, not here.
|
|
96
|
+
|
|
97
|
+
## Notes for nested overrides
|
|
98
|
+
|
|
99
|
+
Per the agents.md open standard, place an `AGENTS.md` inside any subdirectory that needs different rules. The closest `AGENTS.md` to the file being edited wins; explicit user prompts override everything.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DocksDocks
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# docks-kit
|
|
2
|
+
|
|
3
|
+
Portable configuration kit for AI coding agents. Per-tool **Single Source of
|
|
4
|
+
Truth (SoT)** directories are deployed to each tool's user-config location —
|
|
5
|
+
clone once, sync everywhere, get a consistent AI-assisted dev environment on
|
|
6
|
+
every machine. Tuned for **token efficiency without sacrificing quality**.
|
|
7
|
+
|
|
8
|
+
Supported tools: **Claude Code**, **Codex**, and any agent consuming
|
|
9
|
+
[agentskills.io](https://agentskills.io) universal skills.
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
git clone https://github.com/DocksDocks/public.git ~/projects/public
|
|
15
|
+
cd ~/projects/public
|
|
16
|
+
./docks-kit sync # deploy everything (Claude Code + Codex + skills)
|
|
17
|
+
./docks-kit status # doctor view: drift, toolchain, plugins, skills
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The `./docks-kit` launcher prefers a compiled binary (`cli/dist/`), then runs
|
|
21
|
+
from source via Bun — auto-installing Bun and dependencies when missing.
|
|
22
|
+
|
|
23
|
+
Other install paths (global `bun add -g docks-kit`, curl installer) —
|
|
24
|
+
see `./docks-kit docs install`.
|
|
25
|
+
|
|
26
|
+
**Zero-dependency escape hatch** (no Bun, constrained sandboxes):
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
bash lib/engine.sh sync [targets] [flags] # same flags as the CLI
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Prerequisites: `bash`, `jq`, `curl` (Node/npm for npm-global tools).
|
|
33
|
+
|
|
34
|
+
## CLI
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
docks-kit sync [claude] [codex] [agents] deploy the SoT (default: all three)
|
|
38
|
+
docks-kit model <claude|codex> [value] get/set the DEPLOYED model (TTY picker)
|
|
39
|
+
docks-kit models [tool] [--json] kit-verified model catalog
|
|
40
|
+
docks-kit toolchain [check|ensure <tool>] verified-version floors for external tools
|
|
41
|
+
docks-kit status [--json] deployed-vs-SoT drift + toolchain + counts
|
|
42
|
+
docks-kit plugins list [--json] enabledPlugins tri-state vs installed
|
|
43
|
+
docks-kit skills list [--json] universal skills vs manifest
|
|
44
|
+
docks-kit docs [topic] self-documentation (9 topics)
|
|
45
|
+
--help --version --wizard --completions built-in
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The CLI is a typed front-end ([Effect-TS](https://effect.website) on Bun);
|
|
49
|
+
**all mutation runs through the bash engine** (`lib/*.sh`) — battle-tested,
|
|
50
|
+
idempotent, independently usable.
|
|
51
|
+
|
|
52
|
+
### Key flags (`docks-kit sync`)
|
|
53
|
+
|
|
54
|
+
| Flag | Effect |
|
|
55
|
+
|------|--------|
|
|
56
|
+
| `--dry-run` | Preview without applying |
|
|
57
|
+
| `--reconcile` | Reconcile kit-owned settings toward SoT (user-only keys preserved) |
|
|
58
|
+
| `--prune` | Uninstall kit-managed plugins/marketplaces/skills not in SoT |
|
|
59
|
+
| `--claude-model=<m>` | Deploy-time modifier: deployed Claude model |
|
|
60
|
+
| `--claude-compact-window=<n>` | Deploy-time modifier: autocompact window (`680k`) |
|
|
61
|
+
| `--claude-permissive` | Deploy-time modifier: empty ask/deny (sandboxes only) |
|
|
62
|
+
| `--claude-plugin=<name>` | Sticky opt-in plugin (supabase, n8n) |
|
|
63
|
+
| `--codex-model=<m>` | Deploy-time modifier: deployed Codex model |
|
|
64
|
+
| `--skip-rtk` | Skip optional tool bootstrap |
|
|
65
|
+
| `--yes` | Auto-accept toolchain prompts (CI/containers) |
|
|
66
|
+
|
|
67
|
+
**Deploy-time modifiers** change deployed config only — the SoT is untouched
|
|
68
|
+
and a later flag-less sync reverts them. Full reference: `docks-kit docs flags`
|
|
69
|
+
(includes the old→new rename table for the pre-CLI `sync.sh` flags).
|
|
70
|
+
|
|
71
|
+
## How syncing works
|
|
72
|
+
|
|
73
|
+
- **Additive by default** — user-only settings keys, plugins, and skills
|
|
74
|
+
survive a plain sync. Reconciliation toward the SoT is explicit
|
|
75
|
+
(`--reconcile` / `--prune`).
|
|
76
|
+
- **Idempotent** — every step is safe to re-run; no-change syncs are no-ops.
|
|
77
|
+
- **Toolchain floors** — external tools (RTK, bun, agent-browser,
|
|
78
|
+
effect-solutions, …) install/upgrade against `SoT/toolchain.json`:
|
|
79
|
+
versions above the kit-verified pin prompt before installing
|
|
80
|
+
(`--yes` accepts; non-TTY falls back to the pinned verified version
|
|
81
|
+
when possible). `docks-kit toolchain check` shows the full table.
|
|
82
|
+
- **Model catalog** — `SoT/models.json` is the research-verified source for
|
|
83
|
+
model validation, listings, and pickers.
|
|
84
|
+
|
|
85
|
+
## Repository map
|
|
86
|
+
|
|
87
|
+
| Path | Purpose |
|
|
88
|
+
|------|---------|
|
|
89
|
+
| `SoT/.claude/` | Claude Code SoT (settings, hooks, status line, CLAUDE.md) |
|
|
90
|
+
| `SoT/.codex/` | Codex SoT (config.toml, rules, AGENTS.md, marketplace) |
|
|
91
|
+
| `SoT/.agents/` | Universal-skill manifest |
|
|
92
|
+
| `SoT/models.json` | Kit-verified model catalog |
|
|
93
|
+
| `SoT/toolchain.json` | Verified-version floors |
|
|
94
|
+
| `lib/` | Bash engine: `common`, `toolchain`, `claude`, `codex`, `skills`, `engine` |
|
|
95
|
+
| `cli/` | docks-kit CLI (Effect-TS on Bun) + bundled docs topics |
|
|
96
|
+
| `docks-kit` | Launcher (binary → bun-from-source) |
|
|
97
|
+
| `install.sh` | Global installer (Bun bootstrap + `bun add -g`) |
|
|
98
|
+
| `docs/plans/` | Multi-commit work-item plans |
|
|
99
|
+
| `AGENTS.md` / `CLAUDE.md` | Agent-facing engineering rules / Claude Code specifics |
|
|
100
|
+
|
|
101
|
+
## Platform support
|
|
102
|
+
|
|
103
|
+
| Platform | CLI | Sync engine |
|
|
104
|
+
|----------|-----|-------------|
|
|
105
|
+
| Linux | ✅ native | ✅ native |
|
|
106
|
+
| macOS (x64/arm64) | ✅ native | ✅ native |
|
|
107
|
+
| Windows | ✅ native binary | ⚠️ experimental via Git Bash (present wherever Claude Code is); full RTK hooks need WSL |
|
|
108
|
+
|
|
109
|
+
Details: `docks-kit docs platforms`.
|
|
110
|
+
|
|
111
|
+
## Releases
|
|
112
|
+
|
|
113
|
+
Tagging `cli-v*` builds five standalone binaries (+ SHA256SUMS) and attaches
|
|
114
|
+
them to the GitHub release; npm publish runs when the `NPM_TOKEN` secret is
|
|
115
|
+
configured. Package bundles the engine + SoT, so npm releases are versioned
|
|
116
|
+
config snapshots.
|
|
117
|
+
|
|
118
|
+
## Deeper docs
|
|
119
|
+
|
|
120
|
+
- `docks-kit docs <topic>` — overview, sync-layers, flags, modifiers, models,
|
|
121
|
+
toolchain, plugins, install, platforms (works offline, bundled with the CLI)
|
|
122
|
+
- [`AGENTS.md`](AGENTS.md) — engineering rules for agents working on the kit
|
|
123
|
+
- [`CLAUDE.md`](CLAUDE.md) — Claude Code specifics: env vars, session
|
|
124
|
+
management, permission mode, open concerns
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Universal AI-agent skills (agentskills.io standard).
|
|
2
|
+
# Bootstrapped to ~/.agents/skills/ by lib/skills.sh during ./sync.sh.
|
|
3
|
+
# One slug per line: <owner>/<repo>. Lines starting with # are comments.
|
|
4
|
+
# Each skill's canonical SKILL.md lands in ~/.agents/skills/<name>/ — Codex
|
|
5
|
+
# reads that path natively; Claude Code gets a ~/.claude/skills/<name>
|
|
6
|
+
# symlink to it. lib/skills.sh names both agents the kit supports
|
|
7
|
+
# (-a claude-code codex) so the CLI keeps the shared canonical copy.
|
|
8
|
+
|
|
9
|
+
# Browser automation CLI — reaches JS-rendered, auth-walled, login-gated pages
|
|
10
|
+
# (x.com, LinkedIn, Confluence) that built-in WebFetch can't. `lib/skills.sh`
|
|
11
|
+
# auto-installs the `agent-browser` npm package + downloads Chrome for Testing
|
|
12
|
+
# (~175 MB) on first sync; Linux runs `agent-browser install --with-deps` which
|
|
13
|
+
# may prompt for sudo to install system libs (libnss3, libatk, ...).
|
|
14
|
+
vercel-labs/agent-browser
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
@RTK.md
|
|
2
|
+
|
|
3
|
+
## Research Before Implementation
|
|
4
|
+
|
|
5
|
+
Before writing or modifying code that uses an API, hook, method, or config surface you have not verified in this session, research current documentation first.
|
|
6
|
+
|
|
7
|
+
**Research workflow:**
|
|
8
|
+
1. Use `resolve-library-id` → `query-docs` (context7) to fetch up-to-date docs for the specific library/framework
|
|
9
|
+
2. If context7 doesn't cover it, read the official docs with `agent-browser` (it reaches JS-rendered, auth-walled, and login-gated pages); fall back to `WebFetch` for a simple static page
|
|
10
|
+
3. Only then proceed to implementation
|
|
11
|
+
|
|
12
|
+
**When to research:**
|
|
13
|
+
- Installing or configuring a dependency
|
|
14
|
+
- Using an API, hook, method, or pattern you haven't verified in this session
|
|
15
|
+
- Upgrading or migrating between versions
|
|
16
|
+
- Any task where you'd otherwise rely on training data for syntax/behavior
|
|
17
|
+
|
|
18
|
+
**Do NOT:**
|
|
19
|
+
- Assume API signatures, method names, or config options from memory
|
|
20
|
+
- Generate framework code without checking current docs first
|
|
21
|
+
- Skip research because the library "seems familiar"
|
|
22
|
+
|
|
23
|
+
<constraint>
|
|
24
|
+
Research the codebase before editing. Never change code you haven't read.
|
|
25
|
+
</constraint>
|
|
26
|
+
|
|
27
|
+
## Agentic Harness Heuristics
|
|
28
|
+
|
|
29
|
+
**1. Persistence.** Keep going until the user's query is completely resolved. Only yield when sure the problem is solved. Before ending a turn, check the last paragraph: if it is a plan, a question you can answer yourself, or a promise of work not done ("I'll…"), do that work now.
|
|
30
|
+
|
|
31
|
+
**2. Default to parallel.** Whenever you have multiple independent operations (reads, greps, web fetches, independent edits), invoke them in a single response with multiple tool-use blocks. Sequential calls only when output of one operation is required as input to the next.
|
|
32
|
+
|
|
33
|
+
**3. Multi-pass search.** First-pass search often misses — vary the wording (colleague-questions over keywords) before concluding something doesn't exist.
|
|
34
|
+
|
|
35
|
+
**4. Trace symbols.** Before modifying a symbol, trace it to its definitions and all usages. Don't assume a function's behavior or a type's shape from the call site alone.
|
|
36
|
+
|
|
37
|
+
**5. Linter-loop 3-strike rule.** Don't loop more than 3 times fixing linter errors on the same file. On the third attempt, stop and ask the user — repeated failure usually means the diagnosis is wrong, not the code.
|
|
38
|
+
|
|
39
|
+
**6. Read-before-Edit TTL.** If you haven't read a file with the Read tool in the last ~5 messages, re-read it before editing. Cached file content goes stale silently when the user edits between turns.
|
|
40
|
+
|
|
41
|
+
**7. Big-file rule.** For files >1000 lines, prefer Grep + scoped Read (`offset` + `limit`) over reading the entire file. Whole-file reads bloat context; targeted reads keep the working set small.
|
|
42
|
+
|
|
43
|
+
**8. Todo hygiene.** Use TaskCreate for items with meaningful outcome (≥5 min, distinct deliverable). Never include operational sub-actions (linting, testing, searching, examining the codebase) as their own todos — those are sub-steps in service of higher-level tasks. Mark complete immediately when done, never in batches.
|
|
44
|
+
|
|
45
|
+
**9. Literal-instruction rule.** Current frontier models follow instructions literally — they do not silently generalize from intent. Phrase requirements as explicit checklists with success criteria, not narrative.
|
|
46
|
+
|
|
47
|
+
**10. Context hygiene.** Prefer `/clear` at task boundaries and `/rewind` for wrong-path detours over carrying rot forward (corrections accumulate noise; rewinds preserve the prefix and discard the bad branch). On a continuing task, run `/compact` with steering before context quality degrades. Never stop, summarize, or suggest a new session on account of context limits.
|
|
48
|
+
|
|
49
|
+
**11. Autonomy calibration.** For minor choices (naming, formatting, default values, which of two equivalent approaches), pick a reasonable option and note it — don't ask. Ask first only for scope changes, destructive actions, or decisions that change the deliverable. When the user is describing a problem or asking a question rather than requesting a change, the deliverable is your assessment — report findings and stop; don't apply fixes until asked. Don't close a finished task with "Want me to also…?" — run the obvious verification, then stop cleanly.
|
|
50
|
+
|
|
51
|
+
**12. Capability triggering.** When the answer depends on current or version-specific information, search or fetch before answering — never answer from memory. When work fans out across independent items (many files to read, many tests to run, many candidates to check), delegate to parallel subagents; never spawn one for work you can complete directly. For verification, prefer a fresh-context subagent over self-critique. On tasks longer than a few turns, keep a running notes file and re-read it before each phase.
|
|
52
|
+
|
|
53
|
+
<constraint>
|
|
54
|
+
Treat the 12 heuristics above as protocol, not preference. If a turn ends without honoring an applicable one (e.g., lint-loop guard not respected, edit without re-read), self-correct in the next turn before continuing.
|
|
55
|
+
</constraint>
|
|
56
|
+
|
|
57
|
+
## Project Skills
|
|
58
|
+
|
|
59
|
+
Projects may have a `.claude/skills/` directory with Tool Wrapper skills managed by `/docs`. Claude Code auto-discovers these at session start — only descriptions are loaded, full content loads on demand via the Skill tool.
|
|
60
|
+
|
|
61
|
+
Skills follow the [agentskills.io](https://agentskills.io) open standard:
|
|
62
|
+
- **SKILL.md**: frontmatter (`name`, `description`, `user-invocable: false`, `metadata`) + body (≤500 lines)
|
|
63
|
+
- **references/**: on-demand detail files (30-150 lines each), loaded when the skill instructs Claude to read them
|
|
64
|
+
- **Discovery**: Claude Code scans `.claude/skills/*/SKILL.md` at session start, loads only `name` + `description` (~100 tokens per skill)
|
|
65
|
+
- **Triggering**: Claude semantically matches descriptions against user tasks, invokes via `Skill` tool — no `@import` or pointer tables needed
|
|
66
|
+
- **CSO (Claude Search Optimization)**: descriptions MUST start with "Use when..." and describe trigger conditions, not capabilities
|
|
67
|
+
- **Third-party / vendored skills**: add an `upstream:` frontmatter block (`source`, `license`, `vendored_at: "YYYY-MM-DD"`) when vendoring a skill from an external repo. The block marks the skill as vendored so kit-specific checks (CSO start-prefix, `user-invocable`, `metadata.updated`) are relaxed and the skill's body is preserved verbatim from upstream. Universal structural checks (fenced frontmatter, name matches directory, description length, 500-line body cap) still apply.
|
|
68
|
+
|
|
69
|
+
<constraint>
|
|
70
|
+
After any code change affecting documented patterns, update the relevant skill in `.claude/skills/` and its `metadata.updated` frontmatter field. When introducing something new, create a skill or add a `references/` file to an existing skill.
|
|
71
|
+
</constraint>
|
|
72
|
+
|
|
73
|
+
## Project Agents
|
|
74
|
+
|
|
75
|
+
Projects and the global kit may have a `.claude/agents/` directory containing subagent definitions. Each agent file declares its `model` (`sonnet`/`opus`/`haiku`/`inherit`/full model ID), `tools`, and system prompt. Claude Code auto-discovers them at session start and delegates when a `subagent_type` matches or when a slash command explicitly invokes them.
|
|
76
|
+
|
|
77
|
+
Agent files follow this structure:
|
|
78
|
+
- **Frontmatter**: `name` (kebab-case, matches filename), `description` (CSO — starts "Use when…" with a "Not for…" exclusion clause), `tools`, `model`
|
|
79
|
+
- **Body** (≤500 lines): `<constraint>` blocks for non-negotiable rules, `## Workflow` with context-acknowledgment as step 1, `## Output Format`, `## Anti-Hallucination Checks`, `## Success Criteria`
|
|
80
|
+
- **Model-selection resolution** (per Claude Code docs): `CLAUDE_CODE_SUBAGENT_MODEL` env var → per-invocation `model` param → agent frontmatter `model:` → parent conversation. The env var is NOT set in this kit, so per-agent frontmatter controls selection.
|
|
81
|
+
|
|
82
|
+
<constraint>
|
|
83
|
+
When adding a new agent: use kebab-case name matching filename, CSO-compliant description (starts "Use when…", contains a "Not" exclusion clause), explicit `model` and `tools`.
|
|
84
|
+
</constraint>
|
|
85
|
+
|
|
86
|
+
## Picking the right models for workflows and subagents
|
|
87
|
+
|
|
88
|
+
Rankings, higher = better. Intelligence is how hard a problem the model can be handed unsupervised. Taste covers UI/UX, code quality, API design, and copy. Cost is relative spend — a tie-breaker only.
|
|
89
|
+
|
|
90
|
+
| model | cost | intelligence | taste |
|
|
91
|
+
|----------|------|--------------|-------|
|
|
92
|
+
| gpt-5.5 | 9 | 8 | 5 |
|
|
93
|
+
| opus-4.8 | 4 | 7 | 8 |
|
|
94
|
+
| sonnet-5 | 5 | 5 | 7 |
|
|
95
|
+
|
|
96
|
+
Fable 5 outranks all three on intelligence and taste, but its limits are spent for now — treat opus-4.8 as the ceiling until Fable access returns, then Fable takes the top intelligence+taste slot.
|
|
97
|
+
|
|
98
|
+
How to apply:
|
|
99
|
+
- These are defaults, not limits. Standing permission to override: if a cheaper model's output misses the bar, rerun with a smarter one without asking. Judge the output, not the price tag — escalating costs less than shipping mediocre work.
|
|
100
|
+
- Cost is a tie-breaker only; when axes conflict for anything that ships, intelligence > taste > cost.
|
|
101
|
+
- Bulk/mechanical work (clear-spec implementation, data analysis, migrations): gpt-5.5.
|
|
102
|
+
- Anything user-facing (UI, copy, API design) needs taste ≥ 7 → opus-4.8 (sonnet-5 when Opus is saturated).
|
|
103
|
+
- Reviews of plans/implementations: opus-4.8, optionally gpt-5.5 as a second independent perspective.
|
|
104
|
+
- Never use Haiku.
|
|
105
|
+
- gpt-5.5 is reachable only through the Codex CLI (`~/.codex/config.toml` defaults to gpt-5.5): `codex exec` for headless implementation/analysis, `codex review` for diff review, `codex exec -s read-only` with a self-contained prompt for ad-hoc investigation, UI verification, or data analysis. Codex is more efficient than Claude on well-specced execution and stronger at computer-use and UI/UX verification — offload those and report results back.
|
|
106
|
+
- Claude models run via the Agent/Workflow `model` parameter (`opus`, `sonnet`).
|
|
107
|
+
|
|
108
|
+
Using gpt-5.5 inside workflows and subagents (the `model` parameter takes only Claude models, so wrap it):
|
|
109
|
+
- Spawn a thin Claude wrapper agent with `model: 'sonnet', effort: 'low'` whose prompt tells it to write a self-contained Codex prompt, run `codex exec` via Bash, and return Codex's output verbatim. The wrapper only shuttles the prompt and result — gpt-5.5 does the work.
|
|
110
|
+
|
|
111
|
+
Reaching gpt-5.5 (or a full-context worker in another project) as a persistent session — the `session-relay` skill (shared bus + `relay` CLI, Claude ⇄ Codex):
|
|
112
|
+
- `codex exec` is one-shot and stateless. When the offload must be resumable, span several turns, or run in another project with that project's own config, spawn a real session instead: `relay spawn <dir> --tool codex --model gpt-5.5 --effort xhigh` (or `--tool claude --model opus` for a Claude worker), then continue it with `send` / `wake`.
|
|
113
|
+
- Two independent perspectives on a plan = the red-team pair spawn: a gpt-5.5 worker and an opus worker debate over the bus, orchestrator writes the verdict — the concrete form of the "second independent perspective" review above.
|
|
114
|
+
- Pin `--model`/`--effort` on every spawn/wake; never leave an unattended relay child on a top interactive default (e.g. Fable). Each spawn/wake bills the target's subscription — spawn deliberately, never in loops.
|
|
115
|
+
|
|
116
|
+
## Agentic Engineering Discipline
|
|
117
|
+
|
|
118
|
+
1. **State assumptions; push back when warranted.** If a requirement is ambiguous in a way that changes the deliverable, surface the ambiguity and propose 1–2 concrete interpretations in your first message — do not silently pick one and run with it. Surface inconsistencies and confusion instead of guessing past them; present tradeoffs when approaches genuinely differ; push back when the request looks wrong. Agreeable-but-wrong is the failure mode, not disagreement.
|
|
119
|
+
2. **Minimum code that solves the stated problem.** Each named pattern below is a defect — catch it during generation, not after:
|
|
120
|
+
|
|
121
|
+
**Code slop**
|
|
122
|
+
- **Defensive guards** around internally-trusted calls (`try`, `if x != null`). Validate at system boundaries only.
|
|
123
|
+
- **Speculative abstraction.** No helper for one caller; no interface for one implementer. Three similar lines beats premature DRY.
|
|
124
|
+
- **Backwards-compat shims** without a caller — re-exports, deprecation aliases, untoggled feature flags. Just change the code.
|
|
125
|
+
- **Half-finished stubs.** `TODO handle later`, `throw new Error('not implemented')`. Implement or remove the path.
|
|
126
|
+
- **Underscore-rename of unused vars.** Delete the var.
|
|
127
|
+
- **Dead code left behind.** After a refactor, delete the paths, helpers, and imports the change made unreachable.
|
|
128
|
+
|
|
129
|
+
**Comment slop**
|
|
130
|
+
- **Restate-the-code.** `// increment i`. The identifier already says it.
|
|
131
|
+
- **Provenance.** `// added for ticket X`, `// used by Y`. Belongs in the PR description; rots in code.
|
|
132
|
+
- **Tombstones.** `// removed Z`, `// previously did W`. Git remembers.
|
|
133
|
+
- **Docstring bloat** on self-evident functions. One line, only when the WHY isn't obvious from the name.
|
|
134
|
+
|
|
135
|
+
**Output slop**
|
|
136
|
+
- **End-of-turn diff-restatement.** One or two sentences: what changed, what's next. Don't recap what's in the diff.
|
|
137
|
+
- **Narration tics.** "Now I'll…", "Let me check…", play-by-play between tool calls. Terse working shorthand between tool calls is fine; play-by-play is not — write a sentence when something load-bearing happens (a finding, a direction change, a blocker).
|
|
138
|
+
- **Compressed final summaries.** The final message is for a reader who didn't watch the work: outcome first, complete sentences. Shorten by dropping detail, never by compressing into fragments or arrow chains.
|
|
139
|
+
3. **Surgical changes only.** Do not modify code, comments, or formatting outside the explicit scope of the request. Surface unrelated issues as follow-ups — do not fix inline.
|
|
140
|
+
4. **State how success will be verified before implementing.** Name the test, build, smoke check, or diff inspection that will prove the change works. Prefer executable criteria — a test that fails before and passes after, a command with expected output — over judgment calls, and keep each change small enough that its diff is reviewable in one sitting.
|
|
141
|
+
5. **Review scope follows the pipeline.** In pipeline reviews with a downstream filter (multi-agent scans, verification phases), report every issue found with confidence and severity — filtering happens downstream. In ad-hoc reviews, flag only gaps that affect correctness or the stated requirements; treat the rest as optional.
|
|
142
|
+
6. **Ground every progress claim in evidence.** Before reporting progress or completion, audit each claim against a tool result from this session — show the test output, the command and what it returned. If something is unverified, say so explicitly; if tests fail, say so with the output.
|
|
143
|
+
|
|
144
|
+
<constraint>
|
|
145
|
+
Treat the six rules above as preventive (during generation), not remedial (after the fact). Self-correct if a turn drifts.
|
|
146
|
+
</constraint>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Async Stop hook: refreshes the /oauth/usage stats the statusline reads.
|
|
3
|
+
|
|
4
|
+
exec 2>/dev/null
|
|
5
|
+
|
|
6
|
+
CACHE_FILE="/tmp/.claude_usage_cache"
|
|
7
|
+
TOKEN_CACHE="/tmp/.claude_token_cache"
|
|
8
|
+
CREDS_FILE="$HOME/.claude/.credentials.json"
|
|
9
|
+
TOKEN_MAX_AGE=900 # 15 minutes
|
|
10
|
+
|
|
11
|
+
file_mtime() {
|
|
12
|
+
if [ "$(uname)" = "Darwin" ]; then
|
|
13
|
+
stat -f %m "$1" 2>/dev/null || echo 0
|
|
14
|
+
else
|
|
15
|
+
stat -c %Y "$1" 2>/dev/null || echo 0
|
|
16
|
+
fi
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
# Newer credentials than the usage cache => possible account switch; drop it to avoid showing the previous account.
|
|
20
|
+
if [ -f "$CACHE_FILE" ] && [ -f "$CREDS_FILE" ] \
|
|
21
|
+
&& [ "$(file_mtime "$CREDS_FILE")" -ge "$(file_mtime "$CACHE_FILE")" ]; then
|
|
22
|
+
rm -f "$CACHE_FILE"
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
token=""
|
|
26
|
+
if [ -f "$TOKEN_CACHE" ]; then
|
|
27
|
+
cache_mtime=$(file_mtime "$TOKEN_CACHE")
|
|
28
|
+
age=$(( $(date +%s) - cache_mtime ))
|
|
29
|
+
creds_mtime=0
|
|
30
|
+
[ -f "$CREDS_FILE" ] && creds_mtime=$(file_mtime "$CREDS_FILE")
|
|
31
|
+
if [ "$age" -lt "$TOKEN_MAX_AGE" ] && [ "$creds_mtime" -lt "$cache_mtime" ]; then
|
|
32
|
+
token=$(cat "$TOKEN_CACHE")
|
|
33
|
+
fi
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
if [ -z "$token" ]; then
|
|
37
|
+
if [ -f "$CREDS_FILE" ]; then
|
|
38
|
+
token=$(jq -r '.claudeAiOauth.accessToken // empty' "$CREDS_FILE")
|
|
39
|
+
fi
|
|
40
|
+
# macOS Keychain fallback
|
|
41
|
+
if [ -z "$token" ] && command -v security >/dev/null 2>&1; then
|
|
42
|
+
creds=$(security find-generic-password -s "Claude Code-credentials" -w 2>/dev/null)
|
|
43
|
+
[ -n "$creds" ] && token=$(echo "$creds" | jq -r '.claudeAiOauth.accessToken // empty')
|
|
44
|
+
fi
|
|
45
|
+
[ -z "$token" ] && exit 0
|
|
46
|
+
echo "$token" > "$TOKEN_CACHE"
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
response=$(curl -s --max-time 3 \
|
|
50
|
+
-H "Authorization: Bearer $token" \
|
|
51
|
+
-H "anthropic-beta: oauth-2025-04-20" \
|
|
52
|
+
"https://api.anthropic.com/oauth/usage")
|
|
53
|
+
|
|
54
|
+
[ -z "$response" ] && exit 0
|
|
55
|
+
|
|
56
|
+
five_h=$(echo "$response" | jq -r '.five_hour.utilization // empty' | awk '{printf "%.0f", $1}')
|
|
57
|
+
seven_d=$(echo "$response" | jq -r '.seven_day.utilization // empty' | awk '{printf "%.0f", $1}')
|
|
58
|
+
five_h_reset=$(echo "$response" | jq -r '.five_hour.resets_at // empty')
|
|
59
|
+
seven_d_reset=$(echo "$response" | jq -r '.seven_day.resets_at // empty')
|
|
60
|
+
|
|
61
|
+
# Numeric-range guard: a schema change would otherwise poison the cache silently.
|
|
62
|
+
if [ -n "$five_h" ] && [ -n "$seven_d" ] \
|
|
63
|
+
&& echo "$five_h" | grep -qE '^[0-9]+$' && [ "$five_h" -ge 0 ] && [ "$five_h" -le 100 ] 2>/dev/null \
|
|
64
|
+
&& echo "$seven_d" | grep -qE '^[0-9]+$' && [ "$seven_d" -ge 0 ] && [ "$seven_d" -le 100 ] 2>/dev/null; then
|
|
65
|
+
printf '%s\n%s\n%s\n%s\n' "$five_h" "$seven_d" "$five_h_reset" "$seven_d_reset" > "$CACHE_FILE"
|
|
66
|
+
fi
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SOUND="$HOME/.claude/notification.mp3"
|
|
5
|
+
[ -f "$SOUND" ] || exit 0
|
|
6
|
+
|
|
7
|
+
if [ "$(uname)" = "Darwin" ]; then
|
|
8
|
+
command -v afplay >/dev/null 2>&1 && exec afplay "$SOUND"
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
command -v ffplay >/dev/null 2>&1 && exec ffplay -nodisp -autoexit -loglevel quiet "$SOUND"
|
|
12
|
+
command -v paplay >/dev/null 2>&1 && exec paplay "$SOUND"
|
|
13
|
+
command -v aplay >/dev/null 2>&1 && exec aplay -q "$SOUND"
|
|
14
|
+
exit 0
|