Skip to content

feat(agent): let enable run outside an Atomic repository - #272

Merged
geekgonecrazy merged 5 commits into
devfrom
fix/agent-enable-without-repo
Oct 17, 2026
Merged

geekgonecrazy merged 5 commits into
devfrom
fix/agent-enable-without-repo

Conversation

@geekgonecrazy

@geekgonecrazy geekgonecrazy commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

What

atomic agent enable used to fail with RepositoryNotFound outside an Atomic repository. Nothing about enabling needs a repo, though: every installed hook command is guarded by test -d .atomic || test -f .atomic-sandbox && ..., so hooks stay dormant until they fire inside an Atomic repository. This PR removes the requirement.

What enabling actually does (and why the fallback targets home)

Every registry agent resolves to an integration package, and the packages install entirely into the home directory per their manifests — ~/.claude/settings.json, ~/.config/opencode/opencode.json, ~/.claude/skills/..., ~/.config/opencode/plugins/atomic-hooks.ts, agent prompt slots — never the repo. The repo root only feeds:

  • agent auto-detection (registry.detect, when no --agent)
  • .atomic/sessions/ creation
  • [[repo-file]] entries (e.g. AGENTS.md), and only with --agents-md

The repo-relative AgentHook::install path in run() is a degraded fallback for when the package cannot be fetched. This PR makes that fallback degrade to the home directory (where the packages install anyway) instead of failing:

  • run — find_repository_root()? falls back to the home directory as the install base when no repo is found, printing warnings that turns are only recorded in projects with a .atomic/ directory.
  • .atomic/sessions/ — only created when a repo was found, so the fallback path never touches ~/.atomic/ (global config).
  • --agents-md — the second find_repository_root()? (in install_integration, for [[repo-file]] entries) now skips those entries with a warning instead of failing the whole install. InstallOptions.repo_root was already Option<PathBuf>, so None slots in cleanly.
  • Docs corrected in enable.rs and agent/mod.rs to state all of the above.

Inside a repository, behavior is unchanged: same base directory, same sessions directory, no fallback warnings.

Verification

All e2e runs used a HOME override so the real ~/.claude/settings.json was untouched.

  • cargo check -p atomic-cli — clean
  • All 103 commands::agent tests pass
  • E2E outside any repo: hooks install into $HOME/.claude/settings.json, nothing in cwd, no .atomic/sessions anywhere
  • E2E inside a fresh atomic init repo: no fallback warnings, .atomic/sessions/ created, 8 hooks in the repo's .claude/settings.json (via the built-in fallback — see note), nothing in $HOME

Note

While testing I hit a pre-existing failure unrelated to this change: the claude-code integration package install exits non-zero ("partial install") because the cloned atomic-skills release view is missing atomic-integration.toml and AGENTS.md at its root (they exist in the local checkout at ~/code/work/atomic-skills, which is pushed, so the storage release view looks stale). It reproduces identically inside and outside a repo, so it predates this PR — happy to dig into it separately.

@geekgonecrazy

Copy link
Copy Markdown
Contributor Author

Follow-up: removed the redundant --global path entirely.

Why: the integration packages (the normal enable path for every registry agent) install entirely into the home directory and never the repo. The pre-package --global path was a parallel, worse model — bare hooks only, no skills, no prompts, no receipt. With plain enable now falling back to the home directory outside a repository, one install model remains and --global only added confusion.

Removed:

  • --global flag from agent enable and agent disable (clap now rejects it on both)
  • both run_global() implementations
  • orphaned install_global/uninstall_global on claude/gemini/codex hooks and claude/gemini global_settings_path in atomic-agent (codex keeps global_hooks_path/is_installed_global — its trait is_installed and the receipt-repair path still use them)

disable got simpler and more complete:

  • same outside-repo fallback as enable (home directory, with a warning)
  • one disable now cleans both scopes — the uninstall base and the home config — so legacy global installs that predate receipts are also removed
  • agents_with_installs unions repo-base, home, and receipt-discovered agents

Net: 6 files, +72/−555. Marked refactor! with a BREAKING CHANGE note for the flag removal.

Verified:

  • --global rejected by clap on both commands (exit 2)
  • outside a repo: enable puts 8 hooks in $HOME/.claude/settings.json; plain disable removes all of them (reports the base path per agent)
  • inside a repo with hooks in both repo and home config: one disable reports both removals and leaves zero hooks in either
  • 101 CLI agent tests + 28 atomic-agent tests pass; clippy and fmt clean (all e2e against a HOME override — real ~/.claude untouched)

geekgonecrazy and others added 5 commits October 16, 2026 22:08
`atomic agent enable` failed with RepositoryNotFound outside a repo, but
nothing about hook installation needs one: every installed hook command
is guarded by `test -d .atomic || test -f .atomic-sandbox && ...`, so
hooks stay dormant until they fire inside an Atomic repository.

Soften both `find_repository_root()?` calls in the enable path:

- `run` now falls back to the current directory as the install base,
  with warnings that turns are only recorded in Atomic projects.
- `.atomic/sessions/` is only created when `.atomic/` already exists, so
  enabling outside a repo never leaves a stray directory behind.
- the `--agents-md` path in `install_integration` skips `[[repo-file]]`
  entries with a warning instead of failing the whole install
  (`InstallOptions.repo_root` was already optional).

Inside a repository behavior is unchanged: same base directory, same
sessions directory, no fallback warnings.
The previous fallback used the current directory as the install base,
which wrote hooks into an arbitrary ./.claude/settings.json no agent
session would ever read. Outside a repository the correct target is the
home directory — the same one --global uses.

- Rename repo_root → install_base in run(); outside a repo it is the
  home directory (via dirs::home_dir, an existing dependency).
- Gate .atomic/sessions creation behind in_repo so the home .atomic/
  (global config) is never touched by the fallback path.
- Update the module and subcommand docs to match.
…where

Every registry agent is packaged, and the packages install entirely into
the home directory per their manifests (~/.claude/settings.json,
~/.config/opencode/opencode.json, skills, prompts) — never the repo. The
repo root only feeds agent auto-detection, .atomic/sessions/, and
--agents-md [[repo-file]] entries; the repo-relative AgentHook::install
path is a degraded fallback for when the package cannot be fetched.

State that plainly in the module and subcommand docs so the fallback is
not mistaken for the primary behavior.
The integration packages (the normal enable path for every registry
agent) install entirely into the home directory — ~/.claude/settings.json,
~/.config/opencode/opencode.json, skills, prompts — and never the repo.
The pre-package `--global` path was a parallel, worse model: bare hooks
only, no skills, no prompts, no receipt. With plain `enable` now falling
back to the home directory outside a repository, there is one install
model and `--global` only added confusion.

- Remove the `--global` flag from `agent enable` and `agent disable`,
  along with both `run_global()` implementations.
- `agent disable` gains the same outside-repo fallback (home directory)
  and always cleans both scopes — the uninstall base and the home
  config — so one command removes Atomic's hooks wherever they live,
  including legacy global installs that predate receipts.
- Delete the now-orphaned install_global/uninstall_global methods and
  claude/gemini global_settings_path from atomic-agent; codex keeps
  global_hooks_path/is_installed_global, which its trait is_installed
  and the receipt-repair path still use.

BREAKING CHANGE: `atomic agent enable --global` and
`atomic agent disable --global` no longer exist; plain `enable`/
`disable` install and remove the same global hooks.
find_repository_root_from() walked up to filesystem root when run from
/Users/bradleyhilton, skipping ~/.atomic (global config, no database) and returning a
cryptic RepositoryNotFound. Stop at $HOME and surface a message pointing
users to 'atomic init' or cd-ing into a real repository. Home is never
treated as a valid repo root: .atomic/ still requires atomic.redb.
@geekgonecrazy
geekgonecrazy force-pushed the fix/agent-enable-without-repo branch from b09537f to e5b45b9 Compare October 17, 2026 03:13
@geekgonecrazy
geekgonecrazy merged commit 091ce93 into dev Oct 17, 2026
8 checks passed
@geekgonecrazy
geekgonecrazy deleted the fix/agent-enable-without-repo branch October 17, 2026 03:59
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.

2 participants