Skip to content

release: v0.4.0 - #9

Merged
lorem-dev merged 28 commits into
mainfrom
develop
May 24, 2026
Merged

release: v0.4.0#9
lorem-dev merged 28 commits into
mainfrom
develop

Conversation

@lorem-dev

Copy link
Copy Markdown
Owner

Summary

Release v0.4.0 — adds the 1Password vault plugin, the locksmith restart command, full Gemini CLI / OpenCode / Codex agent integration with per-agent templates, and the native locksmith session ensure --hook (replacing the legacy agent-hook.sh).

Features

  • locksmith mcp run --url now resolves templated headers on JSON-RPC error or tool-level result.isError, not only on HTTP 401/403; one retry per session, structural-only detection (no keyword matching on result.content[].text)
  • add 1Password vault plugin (backed by the op CLI; auto-detected when op is installed)
  • add vaults.<name>.vault config field, delivered to plugins as opts["vault"]; used by the 1Password plugin to qualify non-op:// paths
  • add locksmith restart command with --timeout / --no-start (see docs/restart.md)
  • per-agent installer logic moved into internal/initflow/agents/<name>/ subpackages; Gemini CLI is now actually detected and dispatched (previously dead code)
  • agent instruction templates are wrapped with <!-- LOCKSMITH_START --> / <!-- LOCKSMITH_END --> markers so the managed block can be located and updated reliably
  • agent instruction templates are now agent-specific: per-agent session protocol (Claude via UserPromptSubmit hook; Codex / Gemini / OpenCode / generic via export LOCKSMITH_SESSION=\$(locksmith session ensure --quiet)) and usage examples for gopass, keychain, 1password
  • agent templates document an MCP-wrapper fallback: when a wrapped MCP server fails, the agent resolves --header / --env templates via locksmith get and runs the server directly
  • agent templates document an external HTTP API auth-failure recovery prompt: on the first 401/403 for a hostname, the agent offers Skip / locksmith key or vault+path / paste-token; resolved tokens are cached per hostname for the session
  • `locksmith init` adds `Bash(locksmith:*)` to `permissions.allow` in `~/.claude/settings.json` so the agent can call `locksmith` directly (idempotent)
  • `locksmith init` appends an idempotent PATH-augmentation block to `/.zshrc` / `/.bashrc` / `~/.config/fish/config.fish` when the locksmith binary directory is not already on `$PATH` (never creates new rc files)
  • `locksmith init` now auto-restarts the running daemon at the end of its run so plugin/config changes take effect immediately
  • `locksmith init` installs a Codex `SessionStart` hook in `~/.codex/hooks.json` when Codex is detected; the hook pre-warms the daemon so vault unlock fires before the agent's first secret request (best-effort; failures swallowed)
  • Claude Code `UserPromptSubmit` hook switched to the native `locksmith session ensure --hook` invocation (JSON env block via `encoding/json`, no shell script); existing installs are auto-migrated on next `locksmith init` (legacy `agent-hook.sh` references rewritten in place, matching `Bash(.../agent-hook.sh)` permission rule dropped, on-disk script removed)

Test plan

  • `make verify` green (lint, race, coverage >= 90%, build, GPG, docs, CHANGES.md)
  • `make test-integration` green with running daemon + plugins
  • After merge: tag the merge commit on main as `v0.4.0` and push the tag; release workflow builds darwin/linux artefacts

lorem-dev and others added 28 commits May 20, 2026 20:13
Touch ID is just one of the auth methods the macOS Keychain may use;
the plugin does not control which one. Replace explicit Touch ID
mentions in CLI help, README, configuration and architecture docs,
and plugin READMEs with neutral wording about OS-delegated Keychain
authorization. The gopass plugin no longer mentions Touch ID either,
keeping only the GPG passphrase / smartcard story.
Commits the CodeGraph project config (.codegraph/config.json with its
local .gitignore for DB/cache artifacts) and the matching Cursor rule
describing when to prefer codegraph_* MCP tools over native search.
LICENSE's Third-Party Notices section is for libraries linked into
the shipped locksmith binary. Move build tools (buf, golangci-lint)
out of it into the new docs/development-tools.md, and add entries
for external AI agent tooling that maintainers use locally - the
CodeGraph MCP server and the obra/superpowers skill pack. Update
the check-licenses skill to route Makefile build tools to the new
file, and refresh CONTRIBUTING.md to point readers at the right
place when adding or removing such tools.
Add MCP server entries for the CodeGraph CLI in .claude.json, .cursor/
(via .cursor/rules/codegraph.mdc previously committed), and
opencode.jsonc, plus the per-tool agent prompt snippets in .claude/
CLAUDE.md and AGENTS.md describing when to prefer codegraph_* tools
over native search. .claude/settings.json whitelists the read-only
codegraph_* tool calls.

Update .gitignore to track .claude/CLAUDE.md and .claude/settings.json
alongside .claude/skills/, and to ignore the rest of .cursor/ except
the codegraph rule.
feat(mcp): trigger lazy auth on JSON-RPC body errors
Built-in 1Password vault plugin that retrieves secrets through the
op CLI. Detected by locksmith init when op is on PATH; falls back to
manual selection otherwise. Includes parsePath for three reference
forms (op://full, item/field, item with default field), op-stderr
error classification into typed SDK errors (NotFound,
PermissionDenied, Unauthenticated, InvalidArgument), explicit
env allowlist that excludes OP_SERVICE_ACCOUNT_TOKEN, HealthCheck
via 'op --version' + 'op vault list', and >=90% test coverage with
no real-op shellouts.

Adds the vaults.<name>.vault config field, delivered to plugins as
opts["vault"], so paths like "Item/field" can be qualified against
a default 1Password vault.

Docs: new plugins/onepassword/README.md, 1password section in
docs/configuration.md, vault row in README.md.
…smith:*)

Two coupled changes to make locksmith init re-runnable and friendly
to Claude Code's Bash-permission UX:

- Every agent template (Claude/Codex/Gemini/OpenCode and the generic
  agent file) is wrapped in <!-- LOCKSMITH_START --> /
  <!-- LOCKSMITH_END --> markers. The init wizard upserts the
  locksmith-managed block in place on every run, preserving any
  user content outside the markers.
- locksmith init now adds Bash(locksmith:*) to permissions.allow in
  ~/.claude/settings.json so the agent can call locksmith directly
  without per-call approval. Idempotent: re-running does not
  duplicate the rule.

The two were originally split across two commits (template-marker
support + permission wiring); they ship together so an upgrade gets
both behaviours in one go.
…strap

Three coupled additions building the daemon-management surface:

- internal/daemon: lifecycle helpers (IsRunning, Start, Stop,
  Restart, DefaultSocketPath) plus per-platform peerPID via
  SO_PEERCRED on Linux and LOCAL_PEERPID on darwin. _autostart now
  delegates to these helpers; the cli has no inline probe/spawn
  logic left.
- internal/cli/restart_cmd.go: public 'locksmith restart' command
  with --timeout (5s default) and --no-start flags. Stops the
  running daemon (SIGTERM, escalates to SIGKILL after grace) and
  starts a fresh one. See docs/restart.md.
- internal/shellhook/pathhook.go: per-shell PATH-snippet helpers
  (bash/zsh/ash/posix use case-style; fish uses 'not contains').
  internal/initflow/flow.go::applyPathHook wires it in so init
  appends the snippet to the user's rc file when the locksmith
  binary directory is not already on PATH. Never creates a missing
  rc file.
…emon auto-restart

Replace the shell-script Claude Code UserPromptSubmit hook with a
native subcommand and migrate existing installs.

- locksmith session ensure --hook emits {\"env\":{\"LOCKSMITH_SESSION\":\"...\"}}
  on stdout via encoding/json. No printf, no \$(...) - eliminates
  the quoting drift that surfaced as Bash(export LOCKSMITH...) lines
  in agent logs. Exits 0 silently when the daemon is unreachable so
  the hook never blocks a prompt; mutually exclusive with --quiet.
- ClaudeHookInstaller switches the registered command to
  'locksmith session ensure --hook'. The previously added
  Bash(<hookCmd>) permission rule is gone; hooks run through
  Claude's hook subsystem, not Bash, so the rule was redundant.
- Legacy installs with command pointing at the deprecated
  ~/.config/locksmith/agent-hook.sh script are migrated
  transparently: the command is rewritten, the matching
  Bash(.../agent-hook.sh) permission rule is dropped, and the
  on-disk script is removed.
- applyDaemonRestart at end of applyInit restarts a running daemon
  so plugin/config changes take effect immediately. Best-effort:
  warning on failure, init does not fail.
- Cross-package lint fixes from the new wiring.

The earlier '_agent-hook' subcommand attempt was discarded; this
flag-on-existing-subcommand approach uses the existing 'session
ensure' surface and is cleaner.
…ame> subpackages

Split internal/initflow/flow.go (1002 lines) into focused files in
the same package and move per-agent / per-hook logic into
subpackages.

Top-level initflow files:
- flow.go (now ~170 lines, just RunInit + applyInit)
- types.go (InitOptions, InitResult, Prompter)
- prompter.go (huhPrompter implementation)
- apply.go (applyXxx helpers)
- select.go (selectXxx + consent helpers)
- agents.go (AgentWriter dispatcher)

New subpackages:
- internal/initflow/agents/marker - LOCKSMITH_START/END constants
  and Upsert helper.
- internal/initflow/agents/{claude,codex,gemini,opencode,generic} -
  per-agent install logic with embedded templates. Each exports
  Install(homeDir, configDir) and ReadTemplateForTest. Gemini was
  dead code (template existed, no dispatch); now wired up.
- internal/initflow/hooks - shared JSON-settings helpers
  (ReadSettings, WriteSettings, FindStringInAllow, ErrMalformed).
- internal/initflow/hooks/claude - ClaudeHookInstaller moved here
  and renamed to Installer + New constructor.

No behaviour change. Pure structural refactor that prepares the
codebase for the Codex hook installer added in the next commit.

CLAUDE.md gains a 'CodeGraph MCP guidance' section copied from
AGENTS.md to give Claude Code the same code-navigation defaults.
…ith 3 vaults

- New internal/initflow/hooks/codex.Installer registers a Codex
  SessionStart hook in ~/.codex/hooks.json. The hook command is
  'locksmith session ensure --quiet >/dev/null 2>&1 || true' with a
  10s timeout. Best-effort: any failure is swallowed so Codex
  startup is never blocked. Codex hooks cannot inject env vars, so
  the agent still has to 'export LOCKSMITH_SESSION=\$(locksmith
  session ensure --quiet)' in shell; the hook just removes the
  vault-unlock latency spike on the first secret request.
- locksmith init detects Codex and (with --auto or user consent)
  installs the hook via the new applyCodexHook step. Adds
  Prompter.CodexHook to the interface.
- Per-agent templates rewritten to:
  - mention only their own agent (no cross-agent text)
  - show usage examples for all three shipped vault types: gopass,
    keychain, and op (1Password)
  - include the export LOCKSMITH_SESSION=\$(locksmith session
    ensure --quiet) instruction for Codex / Gemini / OpenCode /
    generic (no env-injection hook); claude templates omit it
    (their hook handles env).
- CLAUDE.md gets an 'Adding a new vault plugin' checklist that
  enumerates every doc + every template that must be updated when
  shipping a new vault.
- Docs sweep: agent-integration.md gains Codex Hook Setup,
  CHANGES.md adds the missing bullets (restart command, PATH
  bootstrap, Codex hook, per-agent templates) and drops stale ones,
  README and CONTRIBUTING list onepassword consistently, PLUGINS.md
  links the onepassword plugin README, verification.md anchor
  fixed.
feat: 1Password vault plugin, Codex hook, native session-ensure --hook, initflow decomposition
GitHub's "Merge pull request" commits are signed by the web-flow key,
which is often expired (E) or untrusted locally. Re-signing them is
impossible without diverging from the remote, so filter them out of
the unsigned-commits report and document the rule in the skill.
Shorten the runtime-whitelist, MCP-fallback, and external-API
auth-failure sections by ~45% with the same semantics. Add an
explicit "execute these steps; do not ask clarifying questions"
directive to the MCP fallback so smaller models commit to the
recovery path instead of pausing for confirmation.
feat(initflow): MCP fallback, external-API token prompt, and verification gate tweak
@lorem-dev
lorem-dev merged commit 93723ff into main May 24, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant