airlok 0.2.2 → 0.3.1
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/CHANGELOG.md +20 -0
- package/README.md +45 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to airlok. The format follows Keep a Changelog; versions follow SemVer.
|
|
4
4
|
|
|
5
|
+
## [0.3.1] - 2026-09-11
|
|
6
|
+
|
|
7
|
+
### Security
|
|
8
|
+
|
|
9
|
+
- The provider API key could be shown in the terminal: it was an ordinary redaction entry, so when the model echoed its placeholder the display path rehydrated it. Redaction entries now have a class. `rehydrate` entries (secrets found in files and tool output) are restored into files and commands and shown masked in the terminal, with `[redact] show_secrets_in_output = true` to opt into full display. `redact-only` entries, the provider API key, are never restored anywhere: the terminal shows `[redacted: the provider API key]` and a tool call carrying the placeholder is refused. `airlok redactions` lists kinds and classes; `--show-redactions` now shows the class.
|
|
10
|
+
|
|
11
|
+
## [0.3.0] - 2026-09-11
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Context injection (#5). The system prompt carries a block with the working directory, OS, shell, git branch, status and last five commits, a gitignore-aware file tree, and project instructions from `AIRLOK.md` (or `CLAUDE.md` / `AGENTS.md`) plus `~/.config/airlok/AIRLOK.md`. `[context] max_bytes` caps it; `airlok context` prints it after redaction.
|
|
16
|
+
- Tools `glob`, `grep`, and `list_dir`, read-only and never prompting; `read_file` paging with `offset` and `limit` and binary refusal; tool results over 50 KiB are cut with a paging hint (#5).
|
|
17
|
+
- Markdown rendering in the terminal with highlighted code, buffered per block; plain output when stdout is not a terminal or `NO_COLOR` is set; dimmed, collapsing tool-call lines (#5).
|
|
18
|
+
- Confirmation prompt `[y]es / [n]o / [a]ll / [q]uit` with a one-time hint; `q` aborts the run with a non-zero exit (#5).
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- `edit_file` takes `old` and `new` and reports the match count when it cannot apply (#5).
|
|
23
|
+
- The system prompt tells the model to search with grep and glob before reading files and to prefer `edit_file` over `write_file` for existing files (#5).
|
|
24
|
+
|
|
5
25
|
## [0.2.2] - 2026-09-11
|
|
6
26
|
|
|
7
27
|
### Fixed
|
package/README.md
CHANGED
|
@@ -22,9 +22,43 @@ airlok --provider openai --model gpt-5.5 "..." # override the provider and model
|
|
|
22
22
|
airlok --show-redactions "..." # list what was redacted (kind and length only)
|
|
23
23
|
airlok config init # write a commented config to the user path
|
|
24
24
|
airlok config show # print the effective config and the key source
|
|
25
|
+
airlok context # print the context block sent with the system prompt, after redaction
|
|
26
|
+
airlok redactions # list what the redactor detects and how each kind is treated
|
|
25
27
|
```
|
|
26
28
|
|
|
27
|
-
Every `write_file` and `edit_file` call shows a unified diff and asks `Apply? [y/
|
|
29
|
+
Every `write_file` and `edit_file` call shows a unified diff and asks `Apply? [y]es / [n]o / [a]ll / [q]uit`. Every `bash` call that is not on the allow list shows the command and asks the same way. `y` applies this one, `n` sends a rejection back to the model so it can adapt, `a` approves the rest of that kind for the run, and `q` aborts the run with a non-zero exit. Prompts are read from the terminal, not stdin, so piped input still works; without a terminal, pass `--yes` or turn the confirmations off in the config.
|
|
30
|
+
|
|
31
|
+
Model output is rendered as markdown (headings, emphasis, lists, tables, highlighted code) when stdout is a terminal; set `NO_COLOR` or redirect stdout for plain text. Runs of read-only tool calls collapse to one `reading N files...` line; `-v` shows every call.
|
|
32
|
+
|
|
33
|
+
## Tools
|
|
34
|
+
|
|
35
|
+
| Tool | Asks? | What it does |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `read_file(path, offset?, limit?)` | no | Read a text file, optionally a window of lines. Binary files are refused. |
|
|
38
|
+
| `glob(pattern, path?)` | no | List files matching a glob, gitignore-aware, at most 500. |
|
|
39
|
+
| `grep(pattern, path?, include?)` | no | Regex search returning `file:line:text`, gitignore-aware, at most 200 lines. |
|
|
40
|
+
| `list_dir(path)` | no | Entries with type and size. |
|
|
41
|
+
| `edit_file(path, old, new)` | diff | Replace `old` with `new`; `old` must occur exactly once, otherwise the model is told how many matches there were. |
|
|
42
|
+
| `write_file(path, content)` | diff | Create or overwrite a file. |
|
|
43
|
+
| `bash(command)` | unless allow-listed | Run a shell command in the working directory. |
|
|
44
|
+
|
|
45
|
+
Tool results over 50 KiB are cut with a marker telling the model to page with `read_file`'s `offset` and `limit`.
|
|
46
|
+
|
|
47
|
+
## Context and AIRLOK.md
|
|
48
|
+
|
|
49
|
+
Every run starts with a context block in the system prompt: the working directory, OS and shell, the git branch with `git status --short` and the last five commit subjects, a gitignore-aware file tree (four levels, at most 200 entries), and project instructions. Instructions come from `AIRLOK.md` in the repository root, or `CLAUDE.md` or `AGENTS.md` if there is no `AIRLOK.md`, followed by `~/.config/airlok/AIRLOK.md`. The block goes through the redactor like everything else, and `airlok context` prints exactly what would be sent.
|
|
50
|
+
|
|
51
|
+
A short `AIRLOK.md`:
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
# airlok instructions
|
|
55
|
+
|
|
56
|
+
- Run `cargo test --workspace` before saying a change is done.
|
|
57
|
+
- Never touch files under `vendor/`.
|
|
58
|
+
- Commit messages: imperative subject, no trailing period.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`[context] max_bytes` (default 32768) caps the block; the tree is cut to top-level directories first, then the instructions are truncated.
|
|
28
62
|
|
|
29
63
|
## Configuration
|
|
30
64
|
|
|
@@ -50,10 +84,20 @@ confirm_writes = true # show a diff and ask before write_file / edit_file
|
|
|
50
84
|
confirm_bash = true # ask before running a command that is not allow-listed
|
|
51
85
|
bash_allowlist = ["git status", "git diff", "ls", "cat", "pwd", "find", "grep", "rg", "cargo check", "cargo test", "cargo build"]
|
|
52
86
|
bash_denylist = ["rm -rf", "git push --force", "sudo"]
|
|
87
|
+
|
|
88
|
+
[context]
|
|
89
|
+
max_bytes = 32768 # cap on the context block; tree is cut first, then instructions
|
|
90
|
+
|
|
91
|
+
[redact]
|
|
92
|
+
show_secrets_in_output = false # show secrets from files in full in the terminal instead of masked
|
|
53
93
|
```
|
|
54
94
|
|
|
55
95
|
For openai, `base_url` falls back to the `OPENAI_BASE_URL` environment variable when the config does not set it.
|
|
56
96
|
|
|
97
|
+
### What comes back, and what never does
|
|
98
|
+
|
|
99
|
+
Every placeholder belongs to one of two classes, listed by `airlok redactions`. Secrets found in your files and in tool output are `rehydrate`: the real value is restored into files and commands, so edits keep working, and shown masked in the terminal (first four characters and the length) unless `[redact] show_secrets_in_output = true`. The provider API key is `redact-only`: it is never restored anywhere. If the model echoes its placeholder it prints as `[redacted: the provider API key]`, and a tool call carrying it is refused with a message to the model. `--show-redactions` lists each placeholder's kind, length, and class, never the value.
|
|
100
|
+
|
|
57
101
|
The key is read from exactly one place. `api_key_cmd` wins if set, then `api_key_env`, then the provider default: `ANTHROPIC_API_KEY` for anthropic, and `AZURE_OPENAI_API_KEY` then `OPENAI_API_KEY` for openai. A command runs once per process and its output is never logged. `airlok config show` prints the env var name or the command, never the value. Whatever key is in use is also added to the redactor, so it can never leave the machine inside a file or command output either.
|
|
58
102
|
|
|
59
103
|
Allow-list entries match on leading tokens (`git status` allows `git status --short`, not `git push`). Deny-list entries match anywhere, in every part of a chained command, and win over the allow list. Flags are parsed rather than compared as text: the `rm -rf` entry also catches `rm -fr`, `rm -r -f`, `rm -Rf`, and `rm --recursive --force`, and `git push --force` also catches `git push -f`. A command with shell operators (`;`, `&&`, `|`, `>`, `$(`, and so on) always asks, whatever its first word.
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"hasInstallScript": true,
|
|
20
20
|
"license": "MIT OR Apache-2.0",
|
|
21
21
|
"name": "airlok",
|
|
22
|
-
"version": "0.
|
|
22
|
+
"version": "0.3.1"
|
|
23
23
|
},
|
|
24
24
|
"node_modules/detect-libc": {
|
|
25
25
|
"engines": {
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"requires": true,
|
|
51
|
-
"version": "0.
|
|
51
|
+
"version": "0.3.1"
|
|
52
52
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"artifactDownloadUrls": [
|
|
3
|
-
"https://github.com/airlok-dev/airlok/releases/download/v0.
|
|
3
|
+
"https://github.com/airlok-dev/airlok/releases/download/v0.3.1"
|
|
4
4
|
],
|
|
5
5
|
"bin": {
|
|
6
6
|
"airlok": "run-airlok.js"
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"zipExt": ".tar.xz"
|
|
61
61
|
}
|
|
62
62
|
},
|
|
63
|
-
"version": "0.
|
|
63
|
+
"version": "0.3.1",
|
|
64
64
|
"volta": {
|
|
65
65
|
"node": "18.14.1",
|
|
66
66
|
"npm": "9.5.0"
|