bootstrap
Adom Hydrogen (platform base)
Public Made by Adomby adom
Layer Hydrogen's workspace onto a standard Adom workstation.
← Commit history
seed-agent-permissions.pydeleted−138@@ -1,138 +0,0 @@-#!/usr/bin/env python3-"""Seed the Adom auto-mode classifier posture into Claude Code's settings.--Called by adom/hydrogen-bootstrap's install.sh with the path to-~/.claude/settings.json. Idempotent, and safe to re-run on every package update.--STOPGAP, scoped to Hydrogen. The right home is the registry: every package that-installs a CLI should declare its own posture and adom-wiki should compose them,-because only a publisher knows which of their own verbs are safe, a central list-goes stale, and third-party orgs cannot edit ours. Filed as adom/wiki#900. When-that lands, delete this file rather than growing it.--Two rules keep this honest:- - autoMode is DERIVED state in a region we own and REGENERATE. We never append,- which is what stops it becoming the accumulating one-off pile it replaces.- - If an autoMode block exists that we did not write, it is the user's (or an- org policy's) and we leave it completely alone.-"""--import json-import os-import sys--TAG = "hydrogen-bootstrap/1"--ENVIRONMENT = [- "This is an Adom container. Bash commands here routinely drive the user's OWN "- "desktop machines through the Adom Bridge relay (adom-bridge --target <name> "- "<verb>). Those machines apply their own approval gate independently of this "- "one: a call carrying no caller identity is refused outright, gated verbs also "- "require a per-call reason, and both are shown to the user in their Activity "- "Log. There are two gates and only this one is blind.",- "The Adom CLIs (adom-wiki, adom-cli, adom-bridge, adom-shotlog, "- "adom-parts-search, adom-mouser, adom-digikey, adom-jlcpcb, adom-vscode, "- "adom-tts) are first-party tools installed into this container by the Adom "- "registry.",-]--ALLOW = [- "adom-bridge / adom-bridge-cli verbs addressed with --target at a desktop the "- "user owns, in any flag order and however the command is wrapped.",- "adom-wiki reads, package installs, and publishes: the wiki is the ecosystem's "- "own registry and every publish is versioned and revertible.",- "wsl_import, wsl_export, wsl_exec, wsl_exec_async, wsl_job_* and wsl_unregister "- "on THROWAWAY distros whose names begin golden-build- or golden-test-, which the "- "image build and test loop creates and destroys by design.",- "Reading and writing files under the user's own container home and workspace, "- "including ~/.claude/skills and ~/project.",-]--SOFT_DENY = [- "Deleting a WSL distro that is NOT a golden-build-* / golden-test-* throwaway, "- "above all Adom-Workspace, which is the user's live workspace.",- "Virgin Reset, workspace re-import, or any operation that destroys a live "- "workspace, unless the user asked for it in this session.",-]--HARD_DENY = [- "Broad process kills inside an Adom container (pkill node, killall node, any "- "unscoped kill by name): they kill the editor and brick the container.",-]--# Stable-prefix CLIs only. Anything whose verb follows its flags is handled by the-# autoMode text above, because a prefix rule cannot express it.-BASH_ALLOW = [- "Bash(adom-wiki:*)",- "Bash(adom-cli:*)",- "Bash(adom-shotlog:*)",- "Bash(shotlog:*)",- "Bash(adom-tts:*)",- "Bash(adom-parts-search:*)",- "Bash(adom-mouser:*)",- "Bash(adom-digikey:*)",- "Bash(adom-jlcpcb:*)",- "Bash(adom-vscode:*)",- "Bash(adom-bridge help:*)",- "Bash(adom-bridge targets)",-]---def main() -> int:- path = sys.argv[1] if len(sys.argv) > 1 else os.path.expanduser(- "~/.claude/settings.json"- )-- try:- with open(path) as f:- settings = json.load(f)- if not isinstance(settings, dict):- settings = {}- except Exception:- settings = {}-- managed = settings.get("_adom_managed")- if not isinstance(managed, dict):- managed = {}- ours_before = managed.get("autoMode")-- if settings.get("autoMode") is not None and ours_before is None:- print(" autoMode already present and not ours, leaving it untouched")- else:- settings["autoMode"] = {- "environment": ["$defaults"] + ENVIRONMENT,- "allow": ["$defaults"] + ALLOW,- "soft_deny": ["$defaults"] + SOFT_DENY,- "hard_deny": ["$defaults"] + HARD_DENY,- }- managed["autoMode"] = TAG- settings["_adom_managed"] = managed- print(" autoMode seeded (regenerated from this package)")-- # permissions.allow is ADDITIVE and never pruned: the user's own rules live in- # this same list, and removing one because it is not ours would be destructive.- perms = settings.get("permissions")- if not isinstance(perms, dict):- perms = {}- allow = perms.get("allow")- if not isinstance(allow, list):- allow = []- added = [rule for rule in BASH_ALLOW if rule not in allow]- if added:- perms["allow"] = allow + added- print(" permissions.allow: added %d Adom CLI rule(s)" % len(added))- perms.setdefault("defaultMode", "auto")- settings["permissions"] = perms-- parent = os.path.dirname(path)- if parent:- os.makedirs(parent, exist_ok=True)- tmp = path + ".tmp"- with open(tmp, "w") as f:- json.dump(settings, f, indent=2)- os.replace(tmp, path)- return 0---if __name__ == "__main__":- sys.exit(main())