Local-first tooling digest

Updated July 8, 2026

Watch where developers actually lose their mornings and the same shape keeps showing up: the terminal, the CLI, and the new AI tooling around them don't respect project boundaries, don't survive a handoff, and stop being helpful the moment the "fun" live part ends. A new hire runs tmux ls, gets nine cryptic session names, and burns an hour figuring out which one she's allowed to attach to. An oncall engineer shares a shell with gotty and unknowingly publishes a writable bash prompt to the public internet. A consultant opens a client repo and spends forty minutes re-auth'ing gh, gcloud, kubectl, and aws before running a single useful command — then does it again for the next client. An AI terminal agent cheerfully surfaces one client's context inside another client's session.

The common thread is local-first, per-project, lightweight tooling. The people hitting these walls hardest are multi-client consultants, async remote teams, and anyone running an AI-heavy workflow on one laptop. They don't want a bigger platform; they want their shell, their credentials, their session history, and their AI's memory to be scoped to the project in front of them, to hand off cleanly, and to stay out of the way. This page collects the recurring questions from that world and the concrete patterns people use to answer them — the ones you can adopt with a few shell hooks tonight, no product required.

I'm new on a team that shares a tmux box, and nobody can tell me which session I'm allowed to attach to. How do teams fix that?

The keybindings are the easy part — the wall is the session model: what exists, who owns it, what it's for, and whether it's safe to attach. tmux ls half-answers it with names like main, pair-1, dl, 0, 1, and the map only lives in the veterans' heads. Break "discoverability" into four sub-problems: inventory (what exists, for what), permission (which sessions may you attach to), state (active vs idle vs abandoned), and onboarding (learning all three without panicking).

The highest-leverage fix is a strict naming convention, e.g. {type}-{owner}-{purpose} where type is one of shared (anyone), pair (two-person, ask first), solo (do not attach), ops (deploys/migrations), bot (automated). Now ops-alex-deploy and solo-dan-scratch answer inventory, ownership, and permission at a glance. Add helper wrappers so the convention is the path of least resistance, and a tls listing wrapper that adds OWNER / TYPE / ATTACHED / IDLE / PURPOSE columns plus a "3 sessions attachable to you" line — backed by a purposes.txt checked into the repo.

Keep the inventory honest with a weekly "grim reaper" that kills sessions idle for 14 days (unless prefixed keep-) and a cron that auto-detaches zombie clients. Finally, adopt one rule with outsized payoff: attach read-only first (tmux a -r, aliased to tar) so you can orient — see whose session it is and what's running — before you ever send a keystroke into someone's live vim or psql.

Solution

How 1devtool handles this: 1devtool gives every project and session a visual home instead of a raw tmux ls — a terminal dashboard with color-coded projects, so which session belongs to which project (and whether it's live) is obvious on day one rather than tribal knowledge.

I share my terminal in the browser with gotty during incidents. Is that actually safe, and what am I missing?

gotty -w bash is twenty seconds of setup and a genuine liability: it publishes a writable shell at a URL with no auth, no audit log, no expiry, on a production-adjacent box. The incident ends, the process keeps running, and the next morning a Shodan scan finds an open WebSocket serving bash. The fix isn't abandoning gotty — it's wrapping it against the five concerns its defaults all get wrong: authentication (who can attach), authorization scope (read-only view vs full shell), audit (who typed what), lifecycle (when it ends on its own), and network exposure (where it's reachable from).

The single most important architectural rule: bind gotty to 127.0.0.1 and put a separate, auth-aware tunnel in front (Cloudflare Access, Tailscale Funnel with ACLs, an SSH -L forward, or nginx behind oauth2-proxy). gotty is the terminal layer; the tunnel is the access-control layer. Then match the scaffolding to the scenario: for over-the-shoulder pairing, skip gotty entirely and use tmux attach -r over SSH; for an external partner at 2 AM, run gotty with --credential, --permit-write=false, --max-connection 1, --timeout 1800, IP-restricted, plus a script-level auto-kill; for a teammate taking over, pass the tmux session between two SSH logins under their own accounts.

For real audit, wrap the inner command in script -f /var/log/sessions/... so every byte lands in a log you ship off-box on close. Fifty lines of shell gets all five right — cheaper than evaluating an enterprise product.

Solution

How 1devtool handles this: Sharing a terminal safely is exactly the gap 1devtool is built for — its remote terminal gives you authenticated, access-controlled shared sessions instead of a naked public WebSocket, so you get the convenience of browser sharing without hand-rolling auth, scope, and teardown around gotty.

We pair-debugged an incident for three hours and now I can't reconstruct which commands we ran, in what order, for the postmortem. How do people record this?

The live half of pair-debugging is solved — tmux+ssh, tmate, VSCode Live Share, Warp session sharing all let two people drive one terminal. What none ship by default is the half that pays off after the session: a faithful, replayable, attributed record. That's why the postmortem becomes archaeology ("I think I ran the kubectl logs, then Sam ran the migration — or was it the other way?"). Byte-stream recorders like asciinema are faithful but anonymous; tmux can't tell which TCP connection a keystroke came from once it's in the tty. Attribution has to live one layer above tmux, at the input router, before bytes hit the shared pty.

Three primitives get you there: a per-participant input router that tags each input line with a participant id; a structured command log (timestamp, participant, cwd, redacted env, command, exit code, duration, capped output) that you can actually query — "every command run against prod-west-2," "everything Sam ran in the last 30 minutes," "all non-zero exits"; and a replay UI with a command-level timeline plus filters, where clicking a row jumps the byte-stream playback to that moment. Shell preexec/precmd hooks give you most of the structured log for free.

Design the privacy in from day one: recording is opt-in and announced in-band, secrets are redacted at the log layer, logs have a retention policy and a one-command destroy, and a participant can redact their own last ten minutes if they fat-finger a password. Start small (script(1) + a timing file), graduate to asciinema + a manifest, then a real router when you know which filters you actually use.

Solution

How 1devtool handles this: The replay-and-blame layer is one 1devtool ships so you don't have to build it — terminal recording captures sessions for playback and review, turning "we fixed the thing" into "we fixed the thing and the team can read exactly what happened next quarter."

I bounce across four repos a day, and when someone asks at 6pm 'what's the state of the billing-svc work?' my honest answer is 'let me scroll up in my terminal.' What's the missing piece?

Raw shell history is not a handoff. gh pr view, git log --oneline, kubectl get pods don't tell the next person which project you were in, what you were trying to do, or what's blocking forward motion — and by the time you reconstruct it, the timezone window has closed and the work waits twelve hours. The missing layer is per-project handoff notes: not session transcripts (too noisy), not standup blurbs (too coarse), but one time-bounded summary per repo per work session. If you spent 40 minutes in billing-svc and 20 in auth-svc, that's two notes, because the receiver cares about one of them.

Derive the skeleton automatically — it covers ~80% of what a teammate needs and it's exactly the part humans forget: branch deltas (git log --since="this morning" --oneline), PRs touched (gh pr list --author @me), failing commands (history lines with non-zero exit), and open // TODO(handoff): markers. Hand-write only the remaining 20% — the rationale, why option A over B, what staging's current weirdness hides — in three or four sentences, prefixed // because. Total write cost: five minutes a day.

Then close the loop on the receiving end: a cd hook that prints "last handoff: 14h ago by jess — see ~/.handoff/billing-svc/2026-05-22.md" surfaces the note where the work is, not buried in Slack. The asymmetry is the whole point — without this layer the cost of forgetting is total; with it, the floor is "skeleton from git history," which still beats nothing. It pays off most for async teams spanning timezones, solo consultants juggling three or four clients, and anyone whose AI agent did work in the repo today that they need to read before re-engaging.

Solution

How 1devtool handles this: 1devtool keeps the handoff next to the work — session continuity preserves where each project left off, and notes directly on terminals let the "why" live on the session itself instead of a cloud doc nobody reopens.

Every time I switch to a different client repo I lose half an hour re-auth'ing every CLI and resetting my shell. How do I make switching projects instant?

The tax is real and invisible: gh auth status shows the wrong account, gcloud config list the last client, kubectl current-context a cluster you lost access to, aws a missing profile, ssh-agent offering the wrong key. Thirty to sixty minutes per switch, and across four clients a week it's roughly a hundred unbillable hours a year. Two complementary patterns kill it.

Boot packs treat your CLI environment like application code — something you stamp from a template, not rebuild by hand. The key is that a boot pack is applyable, not a doc: boot apply <client> sets AWS_PROFILE/KUBECONFIG/GH_HOST, sources project aliases, and prints the three things you always forget (staging URL, deploy command, on-call channel). Split the small project pack (~30 lines: client name, secret references, repo aliases, "things that are weird about this codebase") from a reusable stack pack (100–300 lines of terraform/aws-vault/kubectl/helm conventions shared across clients).

Scoped credentials fix the re-auth half. Stop treating CLIs as machine-global: every major CLI can redirect its config dir via an env var — GH_CONFIG_DIR, KUBECONFIG, AWS_CONFIG_FILE, GOOGLE_APPLICATION_CREDENTIALS, and one ssh-agent per project via a scoped SSH_AUTH_SOCK. A per-repo direnv .envrc sets them on cd, so gh pr list in two repos talks to two accounts with no manual switch — and wandering into the wrong repo can't hit the wrong cluster, because the credential isn't loaded. Always reference secrets (aws-vault exec, op://...), never embed them. Both patterns migrate incrementally: start with the one project that bites you most, and the hour you get back on day one pays for the setup.

Solution

How 1devtool handles this: This is 1devtool's model of a project — project configuration folders and a per-project env manager mean each repo carries its own scoped environment, so cd-ing between clients switches context automatically instead of triggering a CLI-by-CLI re-auth scramble.

My terminal AI agent remembers a fact from one client and surfaces it in another client's session. As a consultant, how do I keep the contexts from bleeding together?

For a consultant, one shared CLI memory is worse than no memory — it generates false confidence. The agent acts like it knows what it's doing; it just knows the wrong project. The failure modes are consistent: naming collisions (client A's deploy does something client B's deploy must never do), convention bleed (it saw tabs in one repo, writes tabs into the other), confidentiality leakage ("last week we discussed the Acme project" appearing in Beta's session — a conversation you now have to explain to a real human), and stale decisions surfacing where they no longer apply. No amount of "please be careful" prompting fixes this; the fix has to be structural.

That structure is per-project terminal identity: the agent treats each project as its own world. Memory is scoped and tagged to the client and doesn't surface elsewhere; conventions are project-local; tools are project-aware so the word "deploy" resolves to the right action per repo; continuity and credentials are project-bound. cd ~/clients/acme loads Acme's scope; cd ~/clients/beta switches, and Acme's memory is no longer visible — same shell, same agent, different identity, driven by location.

Building it with current tools takes an afternoon: use a vault that supports scopes (tag memories, prompts, and credentials per client), add a .agent config folder per repo, define project-local tools in a Makefile/justfile, wire credentials through direnv, and end each session with a scope-tagged "where I left off" note. The requirements underneath are just disciplined defaults — project detection from cwd + git remote, scoped retrieval, default-scoped writes, cross-scope access only on explicit request. This is a trust feature, and it's what lets you use one AI agent across every client without a near-miss on confidentiality.

Solution

How 1AIVault handles this: Scoped memory is exactly 1AIVault's job — project-scoped injection keeps each client's context tagged to its own scope so it never leaks into another session, and a portable local vault keeps that memory on your machine and under your control across every AI tool you use.

Why do I keep reaching for a tiny CLI or single-page tool instead of the big platform we already pay for?

Because when you reach for a tool at 11pm suspecting an endpoint is slow, your job isn't to build performance-testing infrastructure — it's to answer the question now. The real metric is setup speed: the felt time from "need" to "answer." Tiny tools win that structurally by sharing a few properties — single-purpose (the README's first line is the whole pitch), zero-config (reasonable defaults that work the first try), composable output (text or JSON you pipe into the next step; the tool doesn't try to own your workflow), no account required, and one-command install. None is individually impressive, but together they produce the felt sense of "this is fast," which is the only thing that matters in that moment.

Platforms fail here not because they're weak but because they treat every user as investing in a long-term relationship: create an account, verify an email, choose a plan, create a workspace, configure integrations, finish the wizard — then start. By step three you've lost interest in the original question and are wondering whether this is even the right vendor. The platform optimized for the relationship and lost the use — and the use is what would have built the relationship anyway.

If you're choosing tools, run four tests: can you get a useful result in the first ten seconds after install? does the first interaction demand signup or config? if you stop using it, what do you lose? if you outgrow it, what's the upgrade path? The healthy answers are yes / no / little / clear. This doesn't rule out platforms — it says the ones that win ship a tiny, fast, standalone slice alongside the big surface. The ones that don't get quietly bypassed by whatever answers the question in twenty seconds.

Solution

How StoicSoft handles this: This is the whole design philosophy of the StoicSoft network — a set of small, single-purpose tools (1DevTool for terminal work, 1FileTool for local files, 1AIVault for AI memory) each built to be useful in the first ten seconds, self-hostable, and honest about doing one job well instead of asking for the relationship up front.

My AI-first IDE plus Docker plus a browser plus a database GUI brings my laptop to its knees. Is there a lighter way to work with AI without giving up the assistant?

The bloat is really an ownership problem. A heavy AI IDE wants to own the code view, the terminal session, the browser preview, the project memory, the task plan, the agent conversation, the run history, and the design loop — all inside one process and one window. Each surface is useful; the mistake is assuming they must all live in the editor when you already have mature tools for most of them. Docker, the browser, and your terminal workflow aren't going away just because the editor wants them as tabs.

And the performance hit isn't just discomfort — it changes behavior. If the IDE is slow you avoid opening a second repo; if the built-in terminal lags during a Docker build you move to a separate shell and the AI loses the terminal state; if the browser preview is flaky you open Chrome and now screenshots, console errors, and DOM state live outside the tool. At that point the "single AI workspace" is an illusion and you're back to copying snippets between windows — with a heavier editor than before.

The lighter architecture flips the assumption: the editor is one participant, not the container. Keep editing in the editor, long-running commands in a real terminal, browser debugging in the browser, Docker in its native tooling — and put an AI coordination layer around them. The deliverable that layer produces is portable context, not embedded context: a task packet (goal, changed files, relevant commands, screenshots, links, decisions) that can move between Claude, Codex, the shell, the browser, and human review; that survives tool changes, gets archived, and reopens next week. The right test isn't "does it replace my IDE" but "does it reduce re-explaining." AI IDEs still win at tight local edits, navigation, and inline refactors — the error is treating that integration as the whole workflow when a modern app is built across services, browsers, terminals, databases, and review tools.

Solution

How 1devtool handles this: 1devtool is built as that lighter coordination layer — its multi-project workspace wraps the editor, terminal, browser, and Docker you already use and shares task context across them, so the heavy surfaces stay native and fast instead of being swallowed into one giant editor process.