diff --git a/README.md b/README.md index 0ce7125..3118011 100644 --- a/README.md +++ b/README.md @@ -304,12 +304,12 @@ sources the tracked profile + an untracked `profile.local.ps1` seam. These config files apply to every Claude Code session regardless of project directory. -**Stage 1 — Plugins:** After Claude Code installs (via the always-on -vendor installer), the script registers the -[caveman](https://github.com/JuliusBrussee/caveman) plugin — an -ultra-compressed communication mode that reduces token usage while -keeping full technical accuracy. It activates automatically via -SessionStart hooks. +**Stage 1 — Plugins:** The caveman and ponytail plugins are retired +(operator ruling 2026-08-31). Their terse-prose and lazy-engineering +modes are merged into the always-on `umbrella-operating-model` skill, +injected via the `umbrella-operating-model.sh` hook on SessionStart, +SubagentStart, and UserPromptSubmit. The Stage-1 script now uninstalls +the plugins on any already-provisioned host. **Stage 2 — HARNESS (optional):** Selecting `HARNESS` in the menu deploys the workspace repo — `~/COWORK/` (private, if your gh auth @@ -444,7 +444,7 @@ Set-ExecutionPolicy Bypass -Scope Process -Force | SSHKEY | GitHub SSH + gh auth + key upload | OFF | | COWORK | Multi-Agent Coordination (needs SSH) | OFF | -**Always runs (no menu toggle):** Claude Code plugin installation (caveman) after CONFIGS deploys `settings.json`. +**Always runs (no menu toggle):** Claude Code plugin retirement (caveman + ponytail uninstall) after CONFIGS deploys `settings.json`. ### Key differences from Linux @@ -463,7 +463,7 @@ Set-ExecutionPolicy Bypass -Scope Process -Force `shellSetup.sh` and `winSetup.ps1` are maintained in parallel. When adding a feature to one, check whether the other needs a matching change. The menu items should stay aligned — same names, same defaults, same order where practical. -**What to sync:** Tool installations, config file deployments, Level 1 Claude Code setup (CLAUDE.md + settings.json + statusline.sh + caveman plugin), AI tool management (install, legacy cleanup), menu structure. Stage 2 content (skills, commands, WORKFORCE, ac-memory-init) is NOT this repo's responsibility — Stage 2 owns it. +**What to sync:** Tool installations, config file deployments, Level 1 Claude Code setup (CLAUDE.md + settings.json + statusline.sh), AI tool management (install, legacy cleanup), menu structure. Stage 2 content (skills, commands, WORKFORCE, ac-memory-init) is NOT this repo's responsibility — Stage 2 owns it. **What diverges by design:** Platform-specific tools (tmux vs WezTerm, stow vs Deploy-Symlink, apt vs winget), root/sudo handling (Linux-only), Docker setup (different install paths), swap management (Linux-only). diff --git a/bash/.bashrc b/bash/.bashrc index 726219b..f376f48 100644 --- a/bash/.bashrc +++ b/bash/.bashrc @@ -123,7 +123,7 @@ case ":$PATH:" in esac # --- Tmux session picker on SSH login --- -if [[ -z "$TMUX" && -n "$SSH_CONNECTION" ]] && command -v tmux >/dev/null 2>&1; then +if [[ $- == *i* && -t 0 && -z "$TMUX" && -n "$SSH_CONNECTION" ]] && command -v tmux >/dev/null 2>&1; then _tmux_sessions=() while IFS= read -r line; do [[ -n "$line" ]] && _tmux_sessions+=("$line") diff --git a/claude/.claude/CLAUDE.md b/claude/.claude/CLAUDE.md index bc35843..4007136 100644 --- a/claude/.claude/CLAUDE.md +++ b/claude/.claude/CLAUDE.md @@ -1,172 +1,59 @@ -# Global Claude Code Instructions - -These rules apply to every Claude Code session on this machine, regardless of project. Project-level CLAUDE.md files add context on top of these defaults. - - - -## Harness Context Awareness - -If `~/COWORK/CONTEXT/` exists on this machine — or, failing that, `~/OPS/CONTEXT/` — read `about-me.md`, `brand-voice.md`, and `working-preferences.md` from it at the start of every session. These files define who the operator is, how they communicate, and how you should behave. This applies even when working outside the harness directory -- the context files are always relevant to how you should operate. - -If `~/COWORK/CLAUDE.md` (or `~/OPS/CLAUDE.md`) exists, treat it as the primary global instruction layer. Its activation triggers (`ACTIVATE AGENT`, `ACTIVATE COORDINATOR`) take precedence over anything below. This file is the host-specific fallback for systems where no harness is deployed. When a harness is present, the rules below still apply but the harness's rules layer on top -- its instructions are a superset. - -## Behavioral Rules - -- Answer the question first, then elaborate only if needed. -- No sycophantic openers: never start with "Certainly!", "Absolutely!", "Great question!", "I'd be happy to...", or "Let me unpack that." -- No hedging: never say "it might be worth considering" — say it directly. -- No over-qualifying: never say "while there are many approaches" — pick the best one and lead with it. -- Match the user's language level and tone. Casual prompt gets casual response. Technical prompt gets technical response. -- Challenge assumptions, flag contradictions, push back when needed. Don't build an echo chamber. -- If confidence is low, say so plainly. -- No emojis unless explicitly requested. -- No bullet lists or headers in casual conversation; save structure for documents and deliverables. -- No bold emphasis spam. If everything is bold, nothing is. - -## Compaction is a pause, not death - -Stock Claude Code auto-compacts around ~75% context by default — but that default is turned off here. `settings.json` sets `DISABLE_AUTO_COMPACT: "1"` and `autoCompactEnabled: false`, so nothing compacts automatically on this machine. Compaction only happens when someone triggers it on purpose: the user runs `/compact`, or the `pre-compact-synthesis` skill decides the session is wrapping up and fires its proactive wrap-up. Either way, once a compact does run, the summary that comes out preserves the conversation arc while fine-grained context dies — so durable state has to be on disk *before* that compact runs, manual or not. - -Two layers are configured at this level: - -- **`PreCompact` hook** (`~/COWORK/.claude-config/hooks/pre-compact.sh`, registered in `settings.json`) — fires automatically on every compaction that does happen, which here always means a manual `/compact` or a skill-triggered one. Pure shell. Captures git state + branch + recent commits to `~/.claude/projects//pre-compact-.md`. Safety net; runs always. -- **`pre-compact-synthesis` skill** — invoke when the user signals wrap-up ("compact", "pre-compact", "wrap up", "do the thing"), or proactively at ~65% context if the session is closing. AI-driven thoughtful synthesis: verifies git committed + pushed, walks task list, saves pending feedback memories, updates the project's durable narrative anchor (fleet journal or `SESSION_HANDOFF.md`). Auto-detects fleet vs solo. - -Both implement the four-artifact rule (git commits, auto-memory, TaskCreate state, durable anchor) that lets post-compact-you self-recover via files alone. Reference: COWORK's `CONTEXT/operating-doctrine.md` Principle 2 when present. - -## Conversational Compression (always on) - -When responding in chat or conversation — not deliverables, not emails, not code — apply these compression rules by default: - -**Drop filler words:** just, really, basically, actually, simply, essentially, generally, certainly, definitely, obviously, clearly. -**Drop hedging:** "it might be worth considering," "you could consider," "it would be good to," "I think it's fair to say." -**Drop connective fluff:** however, furthermore, additionally, moreover, in addition, that being said. -**Shorten redundant phrasing:** "in order to" becomes "to." "Make sure to" becomes "ensure." "The reason is because" becomes "because." "At this point in time" becomes "now." -**Use short synonyms** where meaning holds: "use" not "utilize," "fix" not "implement a solution for," "big" not "extensive," "show" not "demonstrate." - -Keep articles (a/an/the). Keep full sentences. Keep professional register. This is compression, not caveman-speak — the goal is tight, direct prose that still reads naturally. - -**Exempt from compression:** deliverable-mode documents, professional emails, code output, and any content written on the user's behalf. These follow their own quality standards. - -**Suspend compression when:** issuing security warnings, confirming irreversible actions, clarifying something the user asked about twice, or any situation where brevity risks misreading. - -## Code & Commit Standards - -- Code blocks unchanged — never compress code output. -- Conventional Commits format for commit messages: `(): `. -- Subject line 50 chars when possible, hard cap 72. No trailing period. -- Commit body only when the "why" isn't obvious from the subject. -- No AI attribution in commits. - -## Model roles (Fable-primary — applies to BOTH profiles) - -**Operator directive 2026-07-28, amended 2026-08-20.** Four models, four -jobs — and **Opus 5 is now banned** (see below; observed usage data retired -it). The distinction that matters most: the foreman tier and the worker tier -are different models, and nothing is allowed to blur them. - -| role | model | how it's reached | -|---|---|---| -| **Primary foreman** (main session) | Fable 5 — `claude-fable-5[1m]` | the top-level `"model"` pin in `settings.json`; what you boot into | -| **Fallback foreman** | Opus 4.8 — `claude-opus-4-8[1m]` | `/model` → the Opus entry (`ANTHROPIC_DEFAULT_OPUS_MODEL`) | -| **Default build/review/audit worker** | Opus 4.8 — `claude-opus-4-8[1m]` | the `cowork-worker` / `cowork-reviewer` / `cowork-auditor` agent types (hard-pinned in their frontmatter), or `model: "claude-opus-4-8[1m]"` in a Workflow lane | -| **Light/routine worker** | Sonnet 5 — `claude-sonnet-5[1m]` | `model: "sonnet"` | -| **Banned** | Haiku (any version) · **Opus 5** (`claude-opus-5`) | Haiku → `ANTHROPIC_DEFAULT_HAIKU_MODEL` tripwire; Opus 5 → nothing pins it any more + drift-gate grep, see below | - -**Fable 5 is the foreman because it reads context and nuance best** — it -follows instructions closely, holds the big picture, and orchestrates well. -It is also usage-capped at roughly half the subscription allowance, which -makes it the scarce tier and forces thrift: **Fable orchestrates ONLY.** It -writes briefs, delegates, decides, and reviews worker output — all in the -main thread. It does not read, build, or verify inline beyond a handful of -tool calls; that work goes to workers. **Never spawn Fable as a subagent** -except in rare absolute-need cases — a Fable subagent burns the capped tier -on work Opus 4.8 does fine, and reviewing worker output is the Fable main -thread's job, not a Fable subagent's. There is no `model: "fable"` worker -alias wired for subagent spawns; passing one fails. - -**Opus 4.8 is the fallback foreman.** Use it when Fable usage is exhausted, -or when the task isn't complex and the decisions are already planned. Its -known limitation versus Fable is weaker big-picture judgment and fewer -proactive "there's a better way" suggestions — compensate with explicit -written plans and mandatory review of every worker lane. It is reliable at -fan-out, follow-through, and review. As of 2026-08-20 it is **also the -default build/review/audit worker** — the `cowork-*` agent types pin it — so -the same model backstops the foreman and does the delegated labor. -Foreman switch: `/model` → the Opus entry to drop back; -`/model claude-fable-5[1m]` (or just restart, since the settings pin is -Fable) to return. - -**Opus 5 is BANNED harness-wide (operator directive 2026-08-20).** It was -the default worker until then; observed usage data retired it. Against -Opus 4.8 on identical fan-out work, Opus 5 churns roughly **6–7× more -cache-write per output token** and many times the message round-trips — it -self-checks redundantly against a harness that already runs its own -review/verify lanes, runs output-token-heavy, and takes longer to reach -done. Net: it burned a disproportionate share of the weekly limit for no -quality edge the review workflow wasn't already supplying. **Do not pin -`claude-opus-5`** in any agent frontmatter, Workflow lane, spawn override, -config, doc, or script. The fanout worker tier IS Opus 4.8: the -`cowork-worker` / `cowork-reviewer` / `cowork-auditor` types and the -`harness-audit.js` lanes now pin `claude-opus-4-8[1m]` (needs the `[1m]` -suffix — unlike Opus 5, 1M is not Opus 4.8's default). Enforcement mirrors -the Haiku tripwire: nothing in config references `claude-opus-5` any more, -and the drift-gate greps for it (a reappearance fails the gate). Effort -defaults to `xhigh`; drop it only on operator request. Don't pass alias -model overrides on `cowork-*` spawns, with one exception: a deliberate -`model: "sonnet"` downshift for a light lane. - -**Sonnet 5 takes the light and routine lanes** — investigation, mechanical -edits, doc sweeps, anything where top-tier judgment isn't the constraint. -Foremen rotate Opus 4.8 ↔ Sonnet 5 autonomously by job complexity; that call -doesn't need the operator. - -**Haiku is banned harness-wide** — no Haiku model may run anywhere. -`ANTHROPIC_DEFAULT_HAIKU_MODEL` stays pinned to `claude-sonnet-5` as a -TRIPWIRE: anything that asks for haiku (a third-party plugin, a stray -`model: "haiku"`) silently gets Sonnet 5 instead. Never reference the haiku -alias in our own configs, docs, or scripts, and **never remove that env -key** — removing it resurrects real Haiku 4.5. - -**1M fan-out works on both profiles.** `claude`/`~/.claude` (work) and -`clawd`/`~/.claude-personal` (personal) both run 1M-context subagents. The -pay-as-you-go credit gate that **used to** kill `[1m]`-context subagents on -the personal profile (`API Error: Usage credits required for 1M context`) -**no longer fires as of 2026-06-30**, verified live: 10/10 Opus-1M *and* -Sonnet-1M subagents booted clean on `clawd` via both the Agent tool and the -Workflow tool — while `oauthAccount.hasExtraUsageEnabled` is still `false` -(`cachedExtraUsageDisabledReason: "org_level_disabled"`). So this is a -**platform change, NOT a credit flip**. (Conditional: if 1M spawns ever -start failing again with the credit error, the old cap is back — re-point -the `ANTHROPIC_DEFAULT_*_MODEL` aliases to non-`[1m]` models until it's -resolved.) The old folklore blaming the `Explore` agent type for "forcing -1M" is wrong — agent type is irrelevant; the model id is the only lever. - -> General fallback wisdom (any model): if a top-level `"model"` pin in -> `settings.json` ever names a model that has genuinely gone unavailable, -> remove the key so Claude Code falls back to the -> `ANTHROPIC_DEFAULT_*_MODEL` aliases — don't guess a replacement. -> First-launch gotcha: the first boot on a newly-pinned model can reset -> effort to default once despite the settings pin — re-pin with -> `/effort xhigh` if the statusline shows a downgrade. That rule covers -> FIRST BOOT after a model swap only: an operator-chosen `/effort` -> decrease mid-session is a deliberate token-saving move — never -> "correct" it back up; `xhigh` returns on its own at next boot via the -> settings default (`effortLevel: "xhigh"`). - -To change tiers, re-point the `ANTHROPIC_DEFAULT_*_MODEL` env keys in the -shared `settings.json`. +# Global Claude Code instructions + +These apply to every Claude Code session on this machine. A project's own +CLAUDE.md adds to them. + +## Harness context + +If `~/COWORK/` (or `~/OPS/`) exists, its `CLAUDE.md` is the primary instruction +layer and its activation triggers (`ACTIVATE AGENT`, `ACTIVATE COORDINATOR`) +take precedence over anything here. Its foreman charter, identity digest, and +operating model ride your system prompt on every launch path; the session +briefing prints a `Boot:` line with the content sha, and `sha unset` means the +launch bypassed that surface, so read `CONTEXT/foreman-charter.md` and +`CONTEXT/boot-digest.md` yourself. This file is the fallback for a host with +no harness deployed. + +## How to work + +- Answer first, then elaborate only if needed. +- No sycophantic openers, no hedging, no over-qualifying. Pick the best option + and lead with it; say plainly when confidence is low. +- Match the user's register: casual prompt, casual reply; technical prompt, + technical reply. No emojis unless asked. +- Challenge assumptions and flag contradictions; do not build an echo chamber. +- Chat is terse (drop filler, hedging, and connective fluff; keep articles and + full sentences). Deliverables, emails, code, and anything written on the + operator's behalf are full register. Security warnings and + irreversible-action confirmations are always spelled out in full. The + `umbrella-operating-model` skill carries the writing rules. + +## Compaction + +Auto-compaction is off on this machine (`DISABLE_AUTO_COMPACT=1`, +`autoCompactEnabled: false`). A compact happens when the user runs `/compact` +or a closeout skill triggers it, and it keeps the conversation arc while +fine-grained context goes, so durable state has to be on disk first. The +`PreCompact` hook (`~/COWORK/.claude-config/hooks/pre-compact.sh`) captures git +state automatically; the `pre-compact-synthesis` skill does the thoughtful +closeout (commits pushed, memory written, the durable anchor updated) at any +natural break or when the user says wrap up. + +## Code and commits + +- Never compress code output. +- Conventional Commits: `(): `, subject 50 + characters when possible, 72 at most, no trailing period, body only when the + why is not obvious, no AI attribution. + +## Models + +- Primary foreman: Fable 5.1 (`claude-fable-5-1[1m]`, the settings pin). +- Fallback foreman: Opus 4.8 (`claude-opus-4-8[1m]`) when Fable usage is out. +- Default build, review, and audit worker: Opus 4.8. Light lanes: Sonnet 5 + (`model: "sonnet"`). +- Banned everywhere: Opus 5 (`claude-opus-5`) and Haiku (any version). + `ANTHROPIC_DEFAULT_HAIKU_MODEL` stays pinned to `claude-sonnet-5` as the + tripwire; removing it brings real Haiku back. + +Full tiers, ids, and rationale: `~/COWORK/CONTEXT/model-roles.md`. diff --git a/claude/.claude/settings.json b/claude/.claude/settings.json index 43174b9..59cba8c 100644 --- a/claude/.claude/settings.json +++ b/claude/.claude/settings.json @@ -6,8 +6,7 @@ "CLAUDE_CODE_EFFORT_LEVEL": "xhigh", "ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-opus-4-8[1m]", "ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-5[1m]", - "ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-sonnet-5", - "PONYTAIL_DEFAULT_MODE": "full" + "ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-sonnet-5" }, "attribution": { "commit": "", @@ -16,16 +15,12 @@ "permissions": { "defaultMode": "bypassPermissions" }, - "model": "claude-fable-5[1m]", + "model": "claude-fable-5-1[1m]", "hooks": { "SessionStart": [ { - "matcher": ".*", + "matcher": "startup|clear", "hooks": [ - { - "type": "command", - "command": "H=$HOME/COWORK; [ -d $H ] || H=$HOME/OPS; test -x $H/.claude-config/hooks/foreman-charter.sh && $H/.claude-config/hooks/foreman-charter.sh 2>/dev/null || true" - }, { "type": "command", "command": "H=$HOME/COWORK; [ -d $H ] || H=$HOME/OPS; test -x $H/.claude-config/hooks/session-briefing.sh && $H/.claude-config/hooks/session-briefing.sh 2>/dev/null || true" @@ -59,6 +54,45 @@ "command": "H=$HOME/COWORK; [ -d $H ] || H=$HOME/OPS; test -x $H/.claude-config/hooks/session-work-init.sh && $H/.claude-config/hooks/session-work-init.sh 2>/dev/null || true" } ] + }, + { + "matcher": "resume|compact", + "hooks": [ + { + "type": "command", + "command": "H=$HOME/COWORK; [ -d $H ] || H=$HOME/OPS; test -x $H/.claude-config/hooks/post-compact-resume.sh && $H/.claude-config/hooks/post-compact-resume.sh 2>/dev/null || true" + }, + { + "type": "command", + "command": "H=$HOME/COWORK; [ -d $H ] || H=$HOME/OPS; test -x $H/.claude-config/hooks/handoff-check.sh && $H/.claude-config/hooks/handoff-check.sh 2>/dev/null || true" + }, + { + "type": "command", + "command": "H=$HOME/COWORK; [ -d $H ] || H=$HOME/OPS; test -x $H/.claude-config/hooks/session-briefing.sh && $H/.claude-config/hooks/session-briefing.sh 2>/dev/null || true" + }, + { + "type": "command", + "command": "H=$HOME/COWORK; [ -d $H ] || H=$HOME/OPS; test -x $H/.claude-config/hooks/remote-session-register.sh && $H/.claude-config/hooks/remote-session-register.sh 2>/dev/null || true" + }, + { + "type": "command", + "command": "H=$HOME/COWORK; [ -d $H ] || H=$HOME/OPS; test -x $H/WORKFORCE/bin/ac-reorient && $H/WORKFORCE/bin/ac-reorient 2>/dev/null || true" + }, + { + "type": "command", + "command": "H=$HOME/COWORK; [ -d $H ] || H=$HOME/OPS; test -x $H/.claude-config/hooks/session-work-init.sh && $H/.claude-config/hooks/session-work-init.sh 2>/dev/null || true" + } + ] + }, + { + "matcher": "*", + "hooks": [ + { + "type": "command", + "command": "test -x $HOME/.claude/hooks/herdr-agent-state.sh && bash $HOME/.claude/hooks/herdr-agent-state.sh session || true", + "timeout": 10 + } + ] } ], "PreCompact": [ @@ -90,6 +124,15 @@ "command": "H=$HOME/COWORK; [ -d $H ] || H=$HOME/OPS; [ ! -x $H/.claude-config/hooks/git-guard.sh ] || $H/.claude-config/hooks/git-guard.sh" } ] + }, + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "command -v rtk >/dev/null 2>&1 && exec rtk hook claude; [ -x \"$HOME/.local/bin/rtk\" ] && exec \"$HOME/.local/bin/rtk\" hook claude; exit 0" + } + ] } ], "PostToolUse": [ @@ -123,6 +166,17 @@ ] } ], + "SubagentStart": [ + { + "matcher": ".*", + "hooks": [ + { + "type": "command", + "command": "H=$HOME/COWORK; [ -d $H ] || H=$HOME/OPS; test -x $H/.claude-config/hooks/umbrella-operating-model.sh && $H/.claude-config/hooks/umbrella-operating-model.sh 2>/dev/null || true" + } + ] + } + ], "UserPromptSubmit": [ { "matcher": ".*", @@ -150,24 +204,7 @@ "command": "bash \"$HOME/.claude/statusline.sh\"", "refreshInterval": 5 }, - "enabledPlugins": { - "caveman@caveman": true, - "ponytail@ponytail": true - }, - "extraKnownMarketplaces": { - "caveman": { - "source": { - "source": "github", - "repo": "JuliusBrussee/caveman" - } - }, - "ponytail": { - "source": { - "source": "github", - "repo": "DietrichGebert/ponytail" - } - } - }, + "enabledPlugins": {}, "spinnerTipsEnabled": false, "effortLevel": "xhigh", "tui": "fullscreen", diff --git a/claude/.claude/statusline.sh b/claude/.claude/statusline.sh index 7e75424..8654c85 100755 --- a/claude/.claude/statusline.sh +++ b/claude/.claude/statusline.sh @@ -193,30 +193,11 @@ else CACHE_C=$RED; fi TOTAL_TIME=$(fmt_time "$TOTAL_MS") API_TIME=$(fmt_time "$API_MS") -# Caveman badge — stable marketplace path first; fall back to versioned cache. -# Cache dir hash changes on plugin update, so hardcoding it drifts and badge disappears. -CAVEMAN="" -CS="$HOME/.claude/plugins/marketplaces/caveman/src/hooks/caveman-statusline.sh" -if [ ! -e "$CS" ]; then - CS=$(ls -1 "$HOME/.claude/plugins/cache/caveman/caveman/"*/src/hooks/caveman-statusline.sh 2>/dev/null | head -1) -fi -if [ -n "$CS" ] && [ -r "$CS" ]; then - CAVEMAN=$(bash "$CS" 2>/dev/null) - [ -n "$CAVEMAN" ] && CAVEMAN=" $CAVEMAN" -fi - -# Ponytail badge — same pattern as caveman. Marketplace path first, fall back -# to versioned cache (cache hash changes on update). The script self-resolves -# its .ponytail-active flag via CLAUDE_CONFIG_DIR, so it prints per-profile. -PONYTAIL="" -PS="$HOME/.claude/plugins/marketplaces/ponytail/hooks/ponytail-statusline.sh" -if [ ! -e "$PS" ]; then - PS=$(ls -1 "$HOME/.claude/plugins/cache/ponytail/ponytail/"*/hooks/ponytail-statusline.sh 2>/dev/null | head -1) -fi -if [ -n "$PS" ] && [ -r "$PS" ]; then - PONYTAIL=$(bash "$PS" 2>/dev/null) - [ -n "$PONYTAIL" ] && PONYTAIL=" $PONYTAIL" -fi +# Umbrella operating-model badge — the model is unconditionally on via the +# SessionStart/SubagentStart/UserPromptSubmit hooks, so this is a static pin +# with no plugin state file to resolve. Replaces the retired caveman + ponytail +# badges (operator ruling 2026-08-31). +UMB=" ${B}${GRN}[Umbrella]${RST}" # Formatted cost COST_FMT=$(printf '%.2f' "$COST") @@ -232,7 +213,7 @@ case "${_ccd//\\//}" in esac # Row 1: profile+model+badges │ context bar │ time -R1_C1="${PROFILE}${B}${PUR}${MODEL}${RST}${CAVEMAN}${PONYTAIL}" +R1_C1="${PROFILE}${B}${PUR}${MODEL}${RST}${UMB}" R1_C2="${CTX_C}${CTX_BAR} ${ctx_pct}%${RST} ${D}/ ${CTX_L}${RST}${POSTURE}" R1_C3="${WHT}${TOTAL_TIME}${RST} ${D}total${RST} ${GRY}${API_TIME}${RST} ${D}api${RST}" diff --git a/omarchy/omarchySetup.sh b/omarchy/omarchySetup.sh index 6f8676f..f6883d6 100755 --- a/omarchy/omarchySetup.sh +++ b/omarchy/omarchySetup.sh @@ -386,6 +386,55 @@ sed -i -e ':a' -e '/^[[:space:]]*$/{$d;N;ba' -e '}' "$BASHRC" } >> "$BASHRC" msg_success "managed block wired at bottom of ~/.bashrc." +# --------------------------------------------------------------------------- +# 7b. Stage-1 Claude files + tailscaled. +# The generic shellSetup.sh lays down the Level-1 Claude files +# (deploy_claude_config); this Omarchy variant originally skipped them, so +# `claude`/`clawd` booted on Claude's onboarding stub (model:sonnet, no +# hooks/statusline/model-pins). deploy.sh (Stage-2) MIRRORS these to the +# personal profile but does NOT lay down the Level-1 files — that is +# Stage-1's job. Gap found + fixed on t2omarchy 2026-08-25. The caveman + +# ponytail plugins this section used to install are retired (operator ruling +# 2026-08-31, merged into the umbrella-operating-model skill); Stage-2 +# deploy.sh now uninstalls any leftovers. Runs before section 8 so deploy.sh +# has the files to mirror. +# --------------------------------------------------------------------------- +msg_header "7b. Claude Stage-1 files + tailscaled" + +# Level-1 Claude config: symlink from the repo (Stage-1-owned), back up real files. +CLAUDE_SRC="$LPX_DIR/claude/.claude" +CLAUDE_DIR="$HOME/.claude" +if [ -d "$CLAUDE_SRC" ]; then + mkdir -p "$CLAUDE_DIR" + for src in "$CLAUDE_SRC"/settings.json "$CLAUDE_SRC"/statusline.sh "$CLAUDE_SRC"/CLAUDE.md; do + [ -f "$src" ] || continue + tgt="$CLAUDE_DIR/$(basename "$src")" + if [ -L "$tgt" ] && [ "$(readlink -f "$tgt")" = "$(readlink -f "$src")" ]; then + msg_info "Already linked: $tgt"; continue + fi + if [ -e "$tgt" ] && [ ! -L "$tgt" ]; then + mv "$tgt" "${tgt}.backup_$(date +%Y%m%d_%H%M%S)" + msg_warn "Backed up existing $(basename "$src")" + fi + [ -L "$tgt" ] && rm -f "$tgt" + ln -s "$src" "$tgt" && msg_success "Linked: $tgt -> $src" + done +else + msg_warn "$CLAUDE_SRC not found — skipping Level-1 Claude files." +fi + +# Enable tailscaled so remote access survives a reboot (`tailscale up` alone does +# not persist — a t2omarchy reboot dropped the tailnet until this was set 2026-08-25). +if command -v tailscale >/dev/null 2>&1 && systemctl list-unit-files tailscaled.service >/dev/null 2>&1; then + if sudo -n systemctl enable --now tailscaled >/dev/null 2>&1; then + msg_success "tailscaled enabled + started (survives reboot)." + else + msg_warn "Could not enable tailscaled — run: sudo systemctl enable --now tailscaled" + fi +else + msg_info "tailscale not installed — skipping tailscaled enable." +fi + # --------------------------------------------------------------------------- # 8. Stage-2: COWORK deploy.sh (skills/commands symlinks, WORKFORCE PATH, # ultracode + clawd .env + CLAUDE_CODE_TMPDIR + workspace alias into @@ -405,9 +454,9 @@ else fi # --------------------------------------------------------------------------- -# 9. Optionals: cloudflared, NordVPN, superfile (guard, warn-don't-abort) +# 9. Optionals: cloudflared, NordVPN, superfile, T3 Code desktop (guard, warn-don't-abort) # --------------------------------------------------------------------------- -msg_header "9. Optionals (cloudflared, NordVPN, superfile)" +msg_header "9. Optionals (cloudflared, NordVPN, superfile, T3 Code desktop)" # Try official repos first, then AUR fallbacks (yay). $1 = pacman name; the rest # = AUR candidate package names. @@ -486,6 +535,26 @@ else msg_warn "superfile not installable from repos/AUR — skipping." fi +# T3 Code desktop client: the Electron app that pairs with the harness's +# t3code server over the tailnet (same role as the Windows/phone clients). +# Same package name in the [omarchy] repo and the AUR; repo first. The omarchy +# repo rotates package files quickly, so a STALE sync DB makes the download +# 404 (2026-09-08: the DB offered 0.0.33-2, the repo only had 0.0.39-1). On +# failure refresh the sync DBs (-Sy alone: still no -u, no system upgrade) and +# retry once. Verify with pacman -Q (rule: a failed transaction is silent). +if pacman -Q t3code-bin >/dev/null 2>&1; then + msg_info "T3 Code desktop already installed: $(pacman -Q t3code-bin)" +elif install_from_repo_or_aur t3code-bin t3code-bin \ + || { sudo pacman -Sy >/dev/null 2>&1 && install_from_repo_or_aur t3code-bin t3code-bin; }; then + if pacman -Q t3code-bin >/dev/null 2>&1; then + msg_info "Pair it: on the t3code server box run 't3 pair --tailscale --ttl 1h --label $(hostname)', open T3 Code here, paste the link." + else + msg_warn "t3code-bin install reported success but pacman -Q cannot see it — check /var/log/pacman.log." + fi +else + msg_warn "T3 Code desktop (t3code-bin) not installable from the omarchy repo/AUR — skipping." +fi + # --------------------------------------------------------------------------- # 10. Summary # --------------------------------------------------------------------------- @@ -500,7 +569,7 @@ cat < ~/.config/lpx/bashrc-overlay.sh - managed block in ~/.bashrc (overlay + Claude wrapper + ~/.bashrc.local) - Stage-2 harness via COWORK deploy.sh - - Optionals attempted: cloudflared, NordVPN (nordvpn-bin), superfile + - Optionals attempted: cloudflared, NordVPN (nordvpn-bin), superfile, T3 Code desktop (t3code-bin) Next: - Open a NEW shell, or run: source ~/.bashrc (to pick up the overlay) diff --git a/shellSetup.sh b/shellSetup.sh index a921857..c99b1d3 100755 --- a/shellSetup.sh +++ b/shellSetup.sh @@ -2083,46 +2083,33 @@ EOF # settings.json, statusline.sh). See the harness DEPLOYMENT.md. } - # --- CLAUDE CODE PLUGINS (runs after config so settings.json exists) --- - - install_claude_plugins() { + # --- CLAUDE CODE PLUGINS: retirement (runs after config so settings.json exists) --- + # Operator ruling 2026-08-31: the caveman + ponytail modes are merged into the + # always-on umbrella-operating-model skill (injected via the + # umbrella-operating-model.sh hook), so the third-party plugins are retired. + # This function used to INSTALL them; it now UNINSTALLS any left on an + # already-provisioned host, and is a no-op once they are gone (idempotent). + + retire_claude_plugins() { if ! command -v claude &> /dev/null; then - msg_warn "Claude CLI not found in PATH. Skipping plugin install." + msg_warn "Claude CLI not found in PATH. Skipping caveman/ponytail plugin retirement." return fi - msg_header "Installing Claude Code Plugins" + msg_header "Retiring caveman + ponytail plugins" - msg_info "Registering caveman plugin marketplace..." - if claude plugin marketplace add JuliusBrussee/caveman; then - msg_success "Marketplace registered." - msg_info "Installing caveman plugin..." - if claude plugin install caveman@caveman; then - msg_success "Caveman plugin installed." - else - msg_warn "Caveman plugin install failed. Run manually: claude plugin install caveman@caveman" + for plg in caveman ponytail; do + if claude plugin uninstall "${plg}@${plg}" >/dev/null 2>&1; then + msg_success "Removed retired plugin: ${plg}" fi - else - msg_warn "Marketplace registration failed. Run manually: claude plugin marketplace add JuliusBrussee/caveman" - fi - - # Ponytail — anti-over-engineering ruleset (operator directive 2026-08-20). - # Orthogonal to caveman (caveman shrinks what the agent SAYS; ponytail - # shrinks what it BUILDS). Default mode pinned to `full` via - # PONYTAIL_DEFAULT_MODE in settings.json env; statusline badge wired in - # statusline.sh alongside caveman. - msg_info "Registering ponytail plugin marketplace..." - if claude plugin marketplace add DietrichGebert/ponytail; then - msg_success "Marketplace registered." - msg_info "Installing ponytail plugin..." - if claude plugin install ponytail@ponytail; then - msg_success "Ponytail plugin installed." - else - msg_warn "Ponytail plugin install failed. Run manually: claude plugin install ponytail@ponytail" + claude plugin marketplace remove "$plg" >/dev/null 2>&1 || true + # Belt-and-suspenders: drop the marketplace dir directly. Guarded so only + # this exact path is ever removed, never a broader tree. + mkt_dir="$HOME/.claude/plugins/marketplaces/${plg}" + if [ -d "$mkt_dir" ]; then + rm -rf "$mkt_dir" && msg_success "Removed retired marketplace dir: ${plg}" fi - else - msg_warn "Marketplace registration failed. Run manually: claude plugin marketplace add DietrichGebert/ponytail" - fi + done } # --- AI HARNESS: COWORK (private) / OPS (public template) --- @@ -2552,7 +2539,7 @@ EOF install_ai_tools # Claude plugins: self-gates if claude CLI or settings are missing - install_claude_plugins + retire_claude_plugins if [[ $CHOICES == *"SWAP"* ]]; then setup_swapfile; fi if [[ $CHOICES == *"DOCKER"* ]]; then install_docker; fi diff --git a/winSetup.ps1 b/winSetup.ps1 index 9d0aa45..1747c87 100644 --- a/winSetup.ps1 +++ b/winSetup.ps1 @@ -1428,27 +1428,19 @@ if ($Selected -contains 'HARNESS') { } # ═══════════════════════════════════════════════════════════════════════════════ -# CLAUDE PLUGINS -- Install after CONFIGS deploys settings.json +# CLAUDE PLUGINS -- retire caveman + ponytail after CONFIGS deploys settings.json # ═══════════════════════════════════════════════════════════════════════════════ -# Unconditional -- runs whenever claude is in PATH (matches shellSetup.sh behavior). -# settings.json (deployed above) contains extraKnownMarketplaces for caveman. +# Operator ruling 2026-08-31: the caveman + ponytail modes are merged into the +# always-on umbrella-operating-model skill (injected via umbrella-operating-model.sh). +# This block used to INSTALL caveman; it now UNINSTALLS any caveman/ponytail left on +# an already-provisioned host. Idempotent no-op once they are gone. if (Get-Command claude -ErrorAction SilentlyContinue) { - Write-Header 'Claude Code Plugins' - Write-Info 'Registering caveman plugin marketplace...' - $marketplaceOut = & claude plugin marketplace add JuliusBrussee/caveman 2>&1 - if ($LASTEXITCODE -eq 0) { - Write-Success 'Marketplace registered.' - Write-Info 'Installing caveman plugin...' - $pluginOut = & claude plugin install caveman@caveman 2>&1 - if ($LASTEXITCODE -eq 0) { - Write-Success 'Caveman plugin installed.' - } else { - Write-Warn "Plugin install returned: $pluginOut" - Write-Warn 'Run manually: claude plugin install caveman@caveman' - } - } else { - Write-Warn "Marketplace add returned: $marketplaceOut" + Write-Header 'Retiring caveman + ponytail plugins' + foreach ($plg in @('caveman', 'ponytail')) { + & claude plugin uninstall "${plg}@${plg}" 2>&1 | Out-Null + & claude plugin marketplace remove $plg 2>&1 | Out-Null + Write-Success "Ensured retired plugin removed: $plg" } } diff --git a/zsh/.zshrc b/zsh/.zshrc index e5ebb48..e238565 100644 --- a/zsh/.zshrc +++ b/zsh/.zshrc @@ -171,7 +171,7 @@ esac # an SSH shell that is neither already inside tmux ($TMUX) nor inside a herdr # pane ($HERDR_ENV), so it fires once per fresh login and never nests. Degrades # to pure-tmux behaviour on fleet boxes without herdr (or jq) installed. -if [[ -z "$TMUX" && -z "$HERDR_ENV" && -n "$SSH_CONNECTION" ]] && { command -v tmux >/dev/null 2>&1 || command -v herdr >/dev/null 2>&1 }; then +if [[ -o interactive && -t 0 && -z "$TMUX" && -z "$HERDR_ENV" && -n "$SSH_CONNECTION" ]] && { command -v tmux >/dev/null 2>&1 || command -v herdr >/dev/null 2>&1 }; then # An optional session console may front this picker. When present + executable it # fully replaces the generic picker below (same gating: interactive SSH login, # outside any multiplexer); otherwise the generic picker runs unchanged as the