Revive the Atomic Forge as a shadcn-style tool registry - #271
Open
Eigenwise wants to merge 27 commits into
Open
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
The three symlink tests build their fixtures with Path.symlink_to, which fails at setup with WinError 1314 on Windows unless the shell holds SeCreateSymbolicLinkPrivilege. CI runs ubuntu-latest so it never saw this, but the suite hard-failed for Windows contributors. Probe symlink support once at import and skip those tests when the platform refuses, so the rest of the suite still runs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The map still described atomic-assembler as a TUI-only installer and atomic-forge as a plain tool folder, which is no longer what either is. Update the affected docs for the noninteractive atomic CLI, the Git source model, the generated index, the conformance contract, and the CI coverage. structure.md lands here too because .map-state.json records its hash. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Nobody uses the Atomic Forge. That's not because the tools are bad, it's because the Forge was never actually distributable.
Before this PR, the only way to get a tool out of the Forge was to launch a Textual TUI and click through it. That means:
pyproject.tomlandrequirements.txt, so you got source code with no dependency metadata and had to reverse-engineer the imports.The original idea was for Forge to work like shadcn: a registry that hands you source code you then own. This PR builds that.
What Forge is now
A shadcn-style vendored-code registry, not a hosted runtime or a package you depend on.
You point
atomicat one or more Git repositories, list what's in them, and copy a complete tool package into your project. From that moment the code is yours: in your repo, in your review, in your version control, editable without asking anyone.Deliberately out of scope: MCP/server interoperability. Forge is a distribution path. Git is the source of truth.
How it works
The CLI
atomicwith no subcommand still opens the TUI. Everything below is new.atomic listatomic downloadatomic sources~/.atomic-assembler/sources.json.Usage recipes
Start with the official Forge
Install into an application folder
Use a private company Forge
# Git auth already works through SSH or your credential helper atomic sources add company \ git@git.example.com:platform/forge.git \ --branch main --tools-path tools atomic list atomic download company/internal_searchResolve a naming collision
Manage sources cleanly
Author and publish a Forge tool
Private Forges: authentication stays outside Forge
This is the design decision I most want reviewed, because it's the one that keeps the feature safe.
Forge never handles credentials. It clones with plain Git and lets your existing setup do the authenticating: SSH keys, a credential helper, whatever your enterprise Git already uses.
..traversal, and escaping symlinks from an untrusted Forge are rejected.A configured Forge source is untrusted input. Its index can name anything it likes, and the code that reads it treats every string as hostile until proven otherwise.
Keeping the registry honest
Forge package contract (enforced by
atomic-forge/conformance/):pyproject.toml, andrequirements.txtBaseTool[Input, Output]BaseIOSchemadocstringsAutomation around it:
atomic-forge/index.jsondeterministically (with explicit LF output, so it doesn't churn on Windows)Security review trail
The functional work was done first, then audited. Every finding below was found by review, fixed, and re-reviewed. Four audit rounds, three fix rounds.
Reject credential-bearing Forge source URLsContain Forge index tool pathsatomic listreturned success when every source failedFail list when every Forge source failsHarden Forge source and index handlingcopytreedereferenced symlinks, so a hostile tool could exfiltrate~/.ssh/id_rsaname/descriptionprinted raw, allowing ANSI/OSC terminal injectionFix Forge source and output hardening regressionsssh://git@host/...URLs were wrongly rejectedSanitize Forge source terminal outputFinal release-gate audit over the whole diff: no confirmed findings.
Also fixed along the way
GithubRepoCloneraccepted abranchargument and then ignored itpyproject.tomlandrequirements.txtatomic download <name>without--destcompared astragainst aPath, so its existence check never firedsearxng_search/requirements.txtdeclaredsympyinstead ofaiohttpbocha_searchtests required a realBOCHA_API_KEYyoutube_transcript_scrapertests mocked an API shape the library no longer hasatomic-forge/atomic_tools/tavily_search/tree removed;test_tavily_seach.pytypo renameddocs/contributing.mddocumented a nonexistentatomic-assembler create-toolcommand and a staleBaseToolexampleVerification
Two things I want to be straight about:
The 3 skips are new and intentional. Those are the symlink-escape tests. They build fixtures with
Path.symlink_to, which fails at setup withWinError 1314on Windows unless the shell holdsSeCreateSymbolicLinkPrivilege. CI isubuntu-latestso it always ran them, but the suite hard-failed for Windows contributors. The last commit probes symlink support and skips rather than failing. They do run in CI.14 conformance warnings are known and deliberate, not silent failures: 13 tools have no
uv.lock(optional), andtavily_searchhas a legacyrequirements.txt/pyproject.tomlmismatch onsympy. Warnings, so they're visible without blocking.One pre-existing failure on
main, untouched by this PR:atomic-agents/tests/context/test_chat_history.py::test_get_class_from_string. This branch changes no files underatomic-agents/.Review notes
Worth a careful look:
atomic-assembler/atomic_assembler/constants.py— URL validation and the display-safety policy. This is the security boundary.atomic-assembler/atomic_assembler/utils.py— index path containment and symlink handling during copy.🤖 Generated with Claude Code