auto-mode 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -107
- package/dist/classify-locally-rTUwxBZi.js +6203 -0
- package/dist/cli.js +22 -31
- package/dist/index.d.ts +9 -135
- package/dist/index.js +2 -2
- package/package.json +51 -26
- package/dist/classify-locally-BHl0xiqa.js +0 -786
package/README.md
CHANGED
|
@@ -1,12 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>auto-mode</h1>
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
<p>
|
|
5
|
+
<a href="https://www.npmjs.com/package/auto-mode"><img src="https://img.shields.io/npm/v/auto-mode" alt="npm version"></a>
|
|
6
|
+
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license"></a>
|
|
7
|
+
</p>
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
<p>
|
|
10
|
+
<a href="./docs/README.md">Documentation</a> •
|
|
11
|
+
<a href="./docs/guides/configuration.md">Configuration</a> •
|
|
12
|
+
<a href="./policy/rules.md">The rules</a> •
|
|
13
|
+
<a href="./docs/architecture/overview.md">Architecture</a>
|
|
14
|
+
</p>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
**auto-mode** is a permission classifier that runs as a hook. It decides whether a coding agent's
|
|
18
|
+
next action should run.
|
|
19
|
+
|
|
20
|
+
Claude Code's built-in auto mode judges actions only for Claude. Point Claude Code at another model
|
|
21
|
+
through an Anthropic-compatible gateway — GLM, Kimi, Muse Spark — and that judging stops. Every
|
|
22
|
+
shell command, file write, and push needs your approval again.
|
|
23
|
+
|
|
24
|
+
auto-mode replaces it. The harness calls it before a tool runs, hands it the pending call, and reads
|
|
25
|
+
back allow, deny, or nothing. It works in Claude Code, Codex, and Muse Code, and behaves the same
|
|
26
|
+
whichever model drives them.
|
|
10
27
|
|
|
11
28
|
## Install
|
|
12
29
|
|
|
@@ -15,130 +32,97 @@ npm i -g auto-mode
|
|
|
15
32
|
auto-mode init claude # or codex, or muse
|
|
16
33
|
```
|
|
17
34
|
|
|
18
|
-
`init` prints the hook entry
|
|
19
|
-
|
|
20
|
-
can remove them.
|
|
21
|
-
|
|
22
|
-
## The two tiers
|
|
23
|
-
|
|
24
|
-
1. **Local rules.** Deterministic matching, no network call, well under a
|
|
25
|
-
millisecond. It answers **allow** or **escalate** and never denies — a wrong
|
|
26
|
-
local allow costs one unwatched action, a wrong local deny stops work you
|
|
27
|
-
asked for.
|
|
28
|
-
2. **The model.** Everything the first tier declines goes to a small reasoning
|
|
29
|
-
model with the policy as its system prompt. Measured at 13-24 seconds on a
|
|
30
|
-
hard case, which is why tier one has to catch the ordinary ones.
|
|
31
|
-
|
|
32
|
-
## The policy
|
|
33
|
-
|
|
34
|
-
Two files, and everything in them is what the model reads. Nothing there is
|
|
35
|
-
addressed to you.
|
|
35
|
+
`init` prints the hook entry, the file to paste it into, and the extra step that harness needs. It
|
|
36
|
+
does not write the file itself.
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|---|---|---|
|
|
39
|
-
| `policy/rules.md` | 22 rules, 7 exceptions | Change what is blocked |
|
|
40
|
-
| `policy/classifier.md` | Threat model, consent bar, evaluation rules, output contract | Change how judgement works |
|
|
38
|
+
The judging model needs a key. The default model is Muse Spark:
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
```sh
|
|
41
|
+
mkdir -p ~/.config/auto-mode
|
|
42
|
+
cat > ~/.config/auto-mode/config.json <<'JSON'
|
|
43
|
+
{ "preset": "spark", "provider": { "apiKeyEnv": "META_API_KEY" } }
|
|
44
|
+
JSON
|
|
45
|
+
```
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
change the rule.
|
|
47
|
+
Presets for `claude` and `glm` ship too. See [Configuration](./docs/guides/configuration.md).
|
|
48
48
|
|
|
49
|
-
##
|
|
49
|
+
## How it decides
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
optional.
|
|
51
|
+
Two tiers.
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
```
|
|
53
|
+
1. **Local rules.** Deterministic matching, no network call, under a millisecond. Answers allow or
|
|
54
|
+
escalate, never deny. Reads, listings, `git status`, and deleting build output are settled here
|
|
55
|
+
and never reach the model.
|
|
56
|
+
2. **The model.** Everything else goes to a small reasoning model with the policy as its system
|
|
57
|
+
prompt. A hard case takes 13 to 24 seconds.
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
Tier one never denies because the two errors cost differently. A wrong allow costs one unwatched
|
|
60
|
+
action. A wrong deny stops work you asked for, and the rules that deny are prose that needs a
|
|
61
|
+
reader.
|
|
65
62
|
|
|
66
|
-
|
|
67
|
-
|---|---|---|
|
|
68
|
-
| `preset` | `spark` | Which provider to start from |
|
|
69
|
-
| `provider.*` | from the preset | Override any single field |
|
|
70
|
-
| `classifierPath`, `rulesPath` | the shipped files | Use your own policy |
|
|
71
|
-
| `transcriptEntries` | `40` | How much history the model sees |
|
|
72
|
-
| `onFailure` | `defer` | `defer` writes nothing; `deny` fails closed |
|
|
63
|
+
## The policy
|
|
73
64
|
|
|
74
|
-
|
|
75
|
-
measured, and a contributor-tier call costs roughly a fortieth of the
|
|
76
|
-
alternatives. Its token budget is a floor, not a preference: below it, Spark
|
|
77
|
-
returns nothing at all.
|
|
65
|
+
Two files. Both are sent to the model verbatim, and neither addresses you.
|
|
78
66
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
67
|
+
| File | Holds | Edit it to |
|
|
68
|
+
| ------------------------------------------------ | ------------------------------------------------------------ | -------------------------- |
|
|
69
|
+
| [`policy/rules.md`](./policy/rules.md) | 22 rules, 7 exceptions | Change what is blocked |
|
|
70
|
+
| [`policy/classifier.md`](./policy/classifier.md) | Threat model, consent bar, evaluation rules, output contract | Change how judgement works |
|
|
82
71
|
|
|
83
|
-
|
|
72
|
+
`classifier.md` carries a `<rules>` marker on its own line. At run time auto-mode replaces it with
|
|
73
|
+
the whole of `rules.md`. `auto-mode print-prompt` writes the result, which is what the model reads.
|
|
84
74
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
75
|
+
Rules come in two tiers. A **hard block** takes no consent, because it creates a risk you cannot see
|
|
76
|
+
from inside the session. A **soft block** clears when you named the action and the detail that makes
|
|
77
|
+
it dangerous — "force push this branch", not "tidy up the repo". Seven exceptions cover work that
|
|
78
|
+
resembles a blocked action and is not: deleting `node_modules`, running a formatter, dropping a
|
|
79
|
+
local test database.
|
|
90
80
|
|
|
91
|
-
|
|
81
|
+
Read [`policy/rules.md`](./policy/rules.md) before turning this on. To change a rule, edit it;
|
|
82
|
+
`rulesPath` points at your own file and replaces the shipped one whole.
|
|
92
83
|
|
|
93
84
|
## Harnesses
|
|
94
85
|
|
|
95
|
-
|
|
96
|
-
three, and all three were verified end to end: the hook denied a real tool call
|
|
97
|
-
and each harness stopped it.
|
|
98
|
-
|
|
99
|
-
They differ in how the hook is registered, and each difference makes the hook
|
|
100
|
-
silently not run if you get it wrong. `auto-mode init` prints these.
|
|
86
|
+
All three were verified end to end: the hook denied a real tool call and the harness stopped it.
|
|
101
87
|
|
|
102
|
-
| Harness
|
|
103
|
-
|
|
104
|
-
| Claude | `"matcher": ".*"` | —
|
|
105
|
-
| Codex
|
|
106
|
-
| Muse | `"matcher": ""`
|
|
88
|
+
| Harness | Match every tool | Also needed |
|
|
89
|
+
| ----------- | ----------------- | --------------------------------------- |
|
|
90
|
+
| Claude Code | `"matcher": ".*"` | — |
|
|
91
|
+
| Codex | omit `matcher` | `hooks = true`, and trust the hook once |
|
|
92
|
+
| Muse Code | `"matcher": ""` | no `timeout_ms` key |
|
|
107
93
|
|
|
108
|
-
|
|
94
|
+
Each difference stops the hook running if you get it wrong, and none of them reports an error.
|
|
95
|
+
`init` prints the right one. Details in [Harnesses](./docs/guides/harnesses.md).
|
|
109
96
|
|
|
110
|
-
|
|
111
|
-
regex and `""` matches only a tool named empty; both leave the hook installed
|
|
112
|
-
and never firing. Muse reads `""` as every tool, so the same value means
|
|
113
|
-
opposite things in the two harnesses.
|
|
114
|
-
- Codex will not run an **untrusted** hook. It is skipped silently until you
|
|
115
|
-
trust it once; the answer is recorded under `[hooks.state]` in `config.toml`.
|
|
116
|
-
- Muse **rejects a handler carrying `timeout_ms`**, reporting an unknown field
|
|
117
|
-
and skipping the whole handler.
|
|
118
|
-
|
|
119
|
-
Detection order matters too. Muse is identified by `model_provider`, which the
|
|
120
|
-
others do not send. Claude sends `prompt_id`. Codex sends `turn_id` — and so
|
|
121
|
-
does Muse, so Muse has to be tested first.
|
|
97
|
+
## Writing nothing is an answer
|
|
122
98
|
|
|
123
|
-
|
|
99
|
+
It means auto-mode has no opinion, and the harness does what it would have done alone. That is the
|
|
100
|
+
output for an unknown harness, an event that is not a tool gate, malformed input, a missing key, and
|
|
101
|
+
a model that times out.
|
|
124
102
|
|
|
125
|
-
-
|
|
126
|
-
|
|
127
|
-
the process never runs.
|
|
128
|
-
- **It can only narrow what the harness already allows.** A tool your own
|
|
129
|
-
permission settings deny is refused before the hook sees it.
|
|
130
|
-
- **The agent's own judgement comes first.** A model that refuses to issue a
|
|
131
|
-
command means the hook is never consulted for it.
|
|
103
|
+
auto-mode can therefore only narrow what your harness already allows. It never removes a gate that
|
|
104
|
+
was there. Set `onFailure` to `deny` to fail closed instead.
|
|
132
105
|
|
|
133
106
|
## Commands
|
|
134
107
|
|
|
135
|
-
| Command
|
|
136
|
-
|
|
137
|
-
| `auto-mode run`
|
|
138
|
-
| `auto-mode run --explain`
|
|
139
|
-
| `auto-mode run --local-only` | Skip the model tier
|
|
140
|
-
| `auto-mode print-prompt`
|
|
141
|
-
| `auto-mode init <harness>`
|
|
108
|
+
| Command | What it does |
|
|
109
|
+
| ---------------------------- | -------------------------------------------------- |
|
|
110
|
+
| `auto-mode run` | Read a payload on stdin, write a verdict on stdout |
|
|
111
|
+
| `auto-mode run --explain` | Also write the reasoning to stderr |
|
|
112
|
+
| `auto-mode run --local-only` | Skip the model tier |
|
|
113
|
+
| `auto-mode print-prompt` | Print the assembled system prompt |
|
|
114
|
+
| `auto-mode init <harness>` | Print the hook entry to add |
|
|
115
|
+
|
|
116
|
+
## Documentation
|
|
117
|
+
|
|
118
|
+
- [Overview](./docs/architecture/overview.md) — the two tiers, harness detection, the verdict
|
|
119
|
+
contract, prompt caching, and the failure modes.
|
|
120
|
+
- [Configuration](./docs/guides/configuration.md) — every field, every preset, and how the key is
|
|
121
|
+
found.
|
|
122
|
+
- [Harnesses](./docs/guides/harnesses.md) — installing into Claude Code, Codex, and Muse Code, and
|
|
123
|
+
what each does differently.
|
|
124
|
+
- [Writing a policy](./docs/guides/policy.md) — the rule tiers, the consent bar, and how to change
|
|
125
|
+
or replace the shipped rules.
|
|
142
126
|
|
|
143
127
|
## Licence
|
|
144
128
|
|