awsettings
Your agent's permissions and config, following you to the next machine.
pip install git+https://github.com/Aitherium/awsettings.git
awsettings hook install # and never think about it again
Installed from git until the first PyPI release — pip install awsettings is
not live yet, and advertising an install that 404s is worse than a longer one.
This line goes when the release does.
Your coding agent keeps its permission allowlist, its enabled tool servers and its hooks in a local file. Open a session on a second machine — a laptop, a shell on a server, a dev container your phone just spun up — and none of it is there.
So you approve the same action again. By hand. Once per surface. Forever. And the copies drift apart while every one of them looks perfectly correct.
What you get
$ awsettings status
local: /home/you/project/.claude/settings.local.json (present)
remote: file:/home/you/.awsettings/profile.json
hooks: PostToolUse, SessionStart
a pull would apply 2 change(s):
+ permissions.allow: Bash(python tools/deploy.py:*)
+ enabledMcpjsonServers: my-server
$ awsettings pull
applied 2 change(s) to /home/you/project/.claude/settings.local.json:
+ permissions.allow: Bash(python tools/deploy.py:*)
+ enabledMcpjsonServers: my-server
Three rules it will not break
Credentials never travel — and they are dropped by name, not by inspecting
the value. A "does this look like a token" heuristic passes every secret that does
not look like one, and that failure is invisible until the secret is already
published. env, apiKeyHelper, awsCredentialExport, sandbox.credentials and
their kin stay on the machine they were typed on. awsettings push --dry-run
prints exactly what would leave.
Arrays union; they are never replaced. Two machines both edit this file. With replace semantics, machine B silently loses the rule machine A never had — and neither of them can tell. Every list here merges.
A deny is one-way. A sync may add a deny or ask rule. It may never drop one.
A lost allow rule costs you a prompt; a lost deny rule costs you the thing the deny
existed to prevent, quietly, on a machine whose owner still believes it is there.
If you genuinely want to remove one everywhere, --prune-denies says so out loud.
It writes the personal file, not the shared one
Only .claude/settings.local.json — gitignored, yours. Never the committed
.claude/settings.json, because syncing your permission allowlist into a file
your team reviews as policy hands everyone rules they never approved.
Autonomy is a hook, not a daemon
awsettings hook install
- SessionStart → pull. A new machine is stale before its first tool call, so that is when it catches up.
- A settings write → push, debounced. A rule you approve here is on its way to the others before you have finished the thought.
No background process. A daemon is a second thing to keep alive on every surface
this exists to stop hand-maintaining — and when it dies, it dies quietly, which is
the same failure as the drift it was meant to fix. Both hooks end in || true:
a settings sync must never be able to fail a session open, because offline is the
normal state of a laptop and the correct behaviour offline is to carry on.
Where the profile lives
No account required. The default is a plain JSON file in a folder you already sync — a git repo, a drive folder, a USB stick:
export AWSETTINGS_PROFILE=~/Dropbox/awsettings.json
Or point it at any endpoint that serves a JSON object on GET and merges one on
PUT:
export AWSETTINGS_URL=https://example.com/api/settings/preferences
export AWSETTINGS_TOKEN=... # environment only — never a command-line flag,
# which lands in shell history and the process list
A transport failure is never read as "no settings": both backends raise, and the CLI exits 2 rather than merging nothing and reporting success.
Exit codes
| code | meaning |
|---|---|
| 0 | did the thing (or there was nothing to do — it says which) |
| 1 | a rule refused it |
| 2 | could not judge: profile unreachable, or a settings file would not parse |
Prove it before you trust it
awsettings --self-test
Runs offline. Asserts that credentials neither leave nor arrive, that arrays union instead of replacing, that a deny is never dropped by default, that installing the hooks twice leaves one hook and does not clobber somebody else's, that a malformed settings file refuses rather than reading as empty, and that writes are atomic.
Licence
Apache-2.0.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file awsettings-0.1.0.tar.gz.
File metadata
- Download URL: awsettings-0.1.0.tar.gz
- Upload date:
- Size: 27.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
228fcc1dbdb6774cd28052b9e0a6eb791ba6b57c43618d90261588fdd9d9bfb5
|
|
| MD5 |
c12df63c8bbacc79806a0f98a398444f
|
|
| BLAKE2b-256 |
07463abc1c0b47496dc12fb44d53555105b82a74bdbe645deddf9ad26cb8007e
|
File details
Details for the file awsettings-0.1.0-py3-none-any.whl.
File metadata
- Download URL: awsettings-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23693315146bab7d683bef5338bbe46a768d8c8597adf3aa2c51a6abe9d1f2b7
|
|
| MD5 |
76312b330f65f83ff440c18bb0b0fbc2
|
|
| BLAKE2b-256 |
3f4faed75838f90ae3439eba9c69ac084d5f9d32a576b63e4af7f84a87926ad8
|