@bilalimamoglu/sift 0.1.0 → 0.2.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/README.md +93 -145
- package/dist/cli.js +481 -30
- package/dist/index.d.ts +9 -3
- package/dist/index.js +392 -21
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -1,38 +1,18 @@
|
|
|
1
1
|
# sift
|
|
2
2
|
|
|
3
|
-
`sift` is a small
|
|
3
|
+
`sift` is a small command-output reducer for agent workflows.
|
|
4
4
|
|
|
5
|
-
Instead of
|
|
5
|
+
Instead of feeding a model the full output of `pytest`, `git diff`, `npm audit`, `tsc --noEmit`, `eslint .`, or `terraform plan`, you run the command through `sift`. It captures the output, trims the noise, and returns a much smaller answer.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Best fit:
|
|
8
|
+
- non-interactive shell commands
|
|
9
|
+
- agents that need short answers instead of full logs
|
|
10
|
+
- CI checks where a command may succeed but still produce a blocking result
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
- designed for non-interactive shell commands
|
|
14
|
-
- compatible with OpenAI-style APIs
|
|
15
|
-
|
|
16
|
-
## What it is not
|
|
17
|
-
|
|
18
|
-
- not a native Codex tool
|
|
19
|
-
- not an MCP server
|
|
20
|
-
- not a replacement for raw shell output when exact logs matter
|
|
21
|
-
- not meant for TUI or interactive password/confirmation flows
|
|
22
|
-
|
|
23
|
-
## Why use it
|
|
24
|
-
|
|
25
|
-
Large shell output is expensive and noisy.
|
|
26
|
-
|
|
27
|
-
If an agent only needs to know:
|
|
28
|
-
- did tests pass
|
|
29
|
-
- what changed
|
|
30
|
-
- are there critical vulnerabilities
|
|
31
|
-
- is this infra plan risky
|
|
32
|
-
|
|
33
|
-
then sending the full raw output to a large model is wasteful.
|
|
34
|
-
|
|
35
|
-
`sift` keeps the shell command, but shrinks what the model has to read.
|
|
12
|
+
Not a fit:
|
|
13
|
+
- exact raw log inspection
|
|
14
|
+
- TUI tools
|
|
15
|
+
- password/confirmation prompts
|
|
36
16
|
|
|
37
17
|
## Installation
|
|
38
18
|
|
|
@@ -44,70 +24,84 @@ npm install -g @bilalimamoglu/sift
|
|
|
44
24
|
|
|
45
25
|
## One-time setup
|
|
46
26
|
|
|
47
|
-
|
|
27
|
+
For OpenAI-hosted models:
|
|
48
28
|
|
|
49
29
|
```bash
|
|
30
|
+
export SIFT_PROVIDER=openai
|
|
50
31
|
export SIFT_BASE_URL=https://api.openai.com/v1
|
|
51
|
-
export
|
|
52
|
-
export
|
|
32
|
+
export SIFT_MODEL=gpt-5-nano
|
|
33
|
+
export OPENAI_API_KEY=your_openai_api_key
|
|
53
34
|
```
|
|
54
35
|
|
|
55
|
-
Or
|
|
36
|
+
Or generate a config file:
|
|
56
37
|
|
|
57
38
|
```bash
|
|
58
39
|
sift config init
|
|
59
40
|
```
|
|
60
41
|
|
|
61
|
-
|
|
42
|
+
If you use a different OpenAI-compatible endpoint, switch to `provider: openai-compatible` and use either the endpoint's native API key env var or the generic fallback:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
export SIFT_PROVIDER_API_KEY=your_provider_api_key
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Common compatible env fallbacks:
|
|
49
|
+
- `OPENROUTER_API_KEY`
|
|
50
|
+
- `TOGETHER_API_KEY`
|
|
51
|
+
- `GROQ_API_KEY`
|
|
62
52
|
|
|
63
53
|
## Quick start
|
|
64
54
|
|
|
65
55
|
```bash
|
|
66
56
|
sift exec "what changed?" -- git diff
|
|
67
57
|
sift exec --preset test-status -- pytest
|
|
58
|
+
sift exec --preset typecheck-summary -- tsc --noEmit
|
|
59
|
+
sift exec --preset lint-failures -- eslint .
|
|
68
60
|
sift exec --preset audit-critical -- npm audit
|
|
69
61
|
sift exec --preset infra-risk -- terraform plan
|
|
62
|
+
sift exec --preset audit-critical --fail-on -- npm audit
|
|
63
|
+
sift exec --preset infra-risk --fail-on -- terraform plan
|
|
70
64
|
```
|
|
71
65
|
|
|
72
66
|
## Main workflow
|
|
73
67
|
|
|
74
|
-
`sift exec` is the
|
|
68
|
+
`sift exec` is the default path:
|
|
75
69
|
|
|
76
70
|
```bash
|
|
77
71
|
sift exec "did tests pass?" -- pytest
|
|
78
|
-
sift exec "what changed?" -- git diff
|
|
79
|
-
sift exec --preset infra-risk -- terraform plan
|
|
72
|
+
sift exec --dry-run "what changed?" -- git diff
|
|
80
73
|
```
|
|
81
74
|
|
|
82
|
-
What
|
|
75
|
+
What it does:
|
|
76
|
+
1. runs the command
|
|
77
|
+
2. captures `stdout` and `stderr`
|
|
78
|
+
3. sanitizes, optionally redacts, and truncates the output
|
|
79
|
+
4. sends the reduced input to a smaller model
|
|
80
|
+
5. prints a short answer or JSON
|
|
81
|
+
6. preserves the wrapped command's exit code
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
2. It captures `stdout` and `stderr`.
|
|
86
|
-
3. It sanitizes, optionally redacts, and truncates the result.
|
|
87
|
-
4. It sends the reduced input to a smaller model.
|
|
88
|
-
5. It prints a short answer or JSON.
|
|
89
|
-
6. It preserves the wrapped command's exit code.
|
|
83
|
+
Use `--dry-run` to inspect the reduced input and prompt without calling the provider.
|
|
90
84
|
|
|
91
|
-
|
|
85
|
+
Use `--fail-on` when a built-in semantic preset should turn a technically successful command into a CI failure. Supported presets:
|
|
86
|
+
- `infra-risk`
|
|
87
|
+
- `audit-critical`
|
|
92
88
|
|
|
93
|
-
|
|
89
|
+
Pipe mode still works when output already exists:
|
|
94
90
|
|
|
95
91
|
```bash
|
|
96
92
|
git diff 2>&1 | sift "what changed?"
|
|
97
93
|
```
|
|
98
94
|
|
|
99
|
-
|
|
95
|
+
## Built-in presets
|
|
100
96
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
- `
|
|
106
|
-
- `
|
|
107
|
-
- `
|
|
108
|
-
- `
|
|
109
|
-
- `log-errors`
|
|
110
|
-
- `infra-risk`
|
|
97
|
+
- `test-status`: summarize test results
|
|
98
|
+
- `typecheck-summary`: group blocking type errors by root cause
|
|
99
|
+
- `lint-failures`: group repeated lint violations and highlight the files or rules that matter
|
|
100
|
+
- `audit-critical`: extract only high and critical vulnerabilities
|
|
101
|
+
- `infra-risk`: return a safety verdict for infra changes
|
|
102
|
+
- `diff-summary`: summarize code changes and risks
|
|
103
|
+
- `build-failure`: explain the most likely build failure
|
|
104
|
+
- `log-errors`: extract the most relevant error signals
|
|
111
105
|
|
|
112
106
|
Inspect them with:
|
|
113
107
|
|
|
@@ -118,135 +112,89 @@ sift presets show audit-critical
|
|
|
118
112
|
|
|
119
113
|
## Output modes
|
|
120
114
|
|
|
121
|
-
- `brief
|
|
122
|
-
- `bullets
|
|
123
|
-
- `json
|
|
124
|
-
- `verdict
|
|
115
|
+
- `brief`
|
|
116
|
+
- `bullets`
|
|
117
|
+
- `json`
|
|
118
|
+
- `verdict`
|
|
125
119
|
|
|
126
|
-
|
|
120
|
+
Built-in JSON and verdict flows return strict error objects on provider or model failure.
|
|
127
121
|
|
|
128
122
|
## Config
|
|
129
123
|
|
|
130
|
-
|
|
124
|
+
Useful commands:
|
|
131
125
|
|
|
132
126
|
```bash
|
|
133
127
|
sift config init
|
|
128
|
+
sift config show
|
|
129
|
+
sift config validate
|
|
130
|
+
sift doctor
|
|
134
131
|
```
|
|
135
132
|
|
|
136
|
-
`sift config show` masks
|
|
133
|
+
`sift config show` masks secrets by default. Use `--show-secrets` only when you explicitly need raw values.
|
|
137
134
|
|
|
138
135
|
Resolution order:
|
|
139
|
-
|
|
140
136
|
1. CLI flags
|
|
141
137
|
2. environment variables
|
|
142
138
|
3. `sift.config.yaml` or `sift.config.yml`
|
|
143
139
|
4. `~/.config/sift/config.yaml` or `~/.config/sift/config.yml`
|
|
144
140
|
5. built-in defaults
|
|
145
141
|
|
|
146
|
-
If you pass `--config <path>`, that path is
|
|
147
|
-
|
|
148
|
-
Supported environment variables:
|
|
149
|
-
|
|
150
|
-
- `SIFT_PROVIDER`
|
|
151
|
-
- `SIFT_MODEL`
|
|
152
|
-
- `SIFT_BASE_URL`
|
|
153
|
-
- `SIFT_API_KEY`
|
|
154
|
-
- `SIFT_MAX_CAPTURE_CHARS`
|
|
155
|
-
- `SIFT_TIMEOUT_MS`
|
|
156
|
-
- `SIFT_MAX_INPUT_CHARS`
|
|
142
|
+
If you pass `--config <path>`, that path is strict. Missing explicit config paths are errors.
|
|
157
143
|
|
|
158
|
-
|
|
144
|
+
Minimal example:
|
|
159
145
|
|
|
160
146
|
```yaml
|
|
161
147
|
provider:
|
|
162
|
-
provider: openai
|
|
163
|
-
model: gpt-
|
|
148
|
+
provider: openai
|
|
149
|
+
model: gpt-5-nano
|
|
164
150
|
baseUrl: https://api.openai.com/v1
|
|
165
151
|
apiKey: YOUR_API_KEY
|
|
166
|
-
timeoutMs: 20000
|
|
167
|
-
temperature: 0.1
|
|
168
|
-
maxOutputTokens: 220
|
|
169
152
|
|
|
170
153
|
input:
|
|
171
154
|
stripAnsi: true
|
|
172
|
-
redact:
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
maxInputChars: 20000
|
|
176
|
-
headChars: 6000
|
|
177
|
-
tailChars: 6000
|
|
155
|
+
redact: false
|
|
156
|
+
maxCaptureChars: 400000
|
|
157
|
+
maxInputChars: 60000
|
|
178
158
|
|
|
179
159
|
runtime:
|
|
180
160
|
rawFallback: true
|
|
181
|
-
verbose: false
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
## Commands
|
|
185
|
-
|
|
186
|
-
```bash
|
|
187
|
-
sift [question]
|
|
188
|
-
sift preset <name>
|
|
189
|
-
sift exec [question] -- <program> [args...]
|
|
190
|
-
sift exec --preset <name> -- <program> [args...]
|
|
191
|
-
sift exec [question] --shell "<command string>"
|
|
192
|
-
sift exec --preset <name> --shell "<command string>"
|
|
193
|
-
sift config init
|
|
194
|
-
sift config show
|
|
195
|
-
sift config validate
|
|
196
|
-
sift doctor
|
|
197
|
-
sift presets list
|
|
198
|
-
sift presets show <name>
|
|
199
161
|
```
|
|
200
162
|
|
|
201
|
-
##
|
|
202
|
-
|
|
203
|
-
`sift` does not install itself into Codex. The normal setup is:
|
|
163
|
+
## Agent usage
|
|
204
164
|
|
|
205
|
-
|
|
206
|
-
2. add a short rule to `~/.codex/AGENTS.md`
|
|
165
|
+
For Claude Code, add a short rule to `CLAUDE.md`.
|
|
207
166
|
|
|
208
|
-
|
|
167
|
+
For Codex, add the same rule to `~/.codex/AGENTS.md`.
|
|
209
168
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
Use pipe mode only when the output already exists from another pipeline.
|
|
215
|
-
Do not use `sift` when exact raw output is required.
|
|
216
|
-
Do not use `sift` for interactive or TUI workflows.
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
That gives the agent a simple habit:
|
|
220
|
-
|
|
221
|
-
- run command through `sift exec` when a summary is enough
|
|
222
|
-
- skip `sift` when exact output matters
|
|
169
|
+
The important part is simple:
|
|
170
|
+
- prefer `sift exec` for noisy shell commands
|
|
171
|
+
- skip `sift` when exact raw output matters
|
|
172
|
+
- keep credentials in your shell env or `sift.config.yaml`, never inline in prompts or agent instructions
|
|
223
173
|
|
|
224
174
|
## Safety and limits
|
|
225
175
|
|
|
226
|
-
-
|
|
227
|
-
-
|
|
228
|
-
-
|
|
229
|
-
-
|
|
230
|
-
- Pipe mode does not preserve upstream shell pipeline failures; use `set -o pipefail` if you need that behavior.
|
|
231
|
-
- `sift exec` mirrors the wrapped command's exit code.
|
|
232
|
-
- `sift doctor` is a conservative local config check. For the default OpenAI-compatible path it requires `baseUrl`, `model`, and `apiKey`.
|
|
176
|
+
- redaction is optional and regex-based
|
|
177
|
+
- retriable provider failures such as `429`, timeouts, and `5xx` are retried once
|
|
178
|
+
- `sift exec` detects simple prompt-like output such as `[y/N]` or `password:` and skips reduction
|
|
179
|
+
- pipe mode does not preserve upstream shell pipeline failures; use `set -o pipefail` if you need that behavior
|
|
233
180
|
|
|
234
|
-
##
|
|
181
|
+
## Releasing
|
|
235
182
|
|
|
236
|
-
|
|
183
|
+
This repo uses a manual GitHub Actions release workflow with npm trusted publishing.
|
|
237
184
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
- presets
|
|
243
|
-
- local redaction and truncation
|
|
244
|
-
- strict JSON/verdict fallbacks
|
|
185
|
+
Release flow:
|
|
186
|
+
1. bump `package.json`
|
|
187
|
+
2. merge to `main`
|
|
188
|
+
3. run the `release` workflow manually
|
|
245
189
|
|
|
246
|
-
|
|
190
|
+
The workflow:
|
|
191
|
+
1. installs dependencies
|
|
192
|
+
2. runs typecheck, tests, and build
|
|
193
|
+
3. packs and smoke-tests the tarball
|
|
194
|
+
4. publishes to npm
|
|
195
|
+
5. creates and pushes the `vX.Y.Z` tag
|
|
196
|
+
6. creates a GitHub Release
|
|
247
197
|
|
|
248
198
|
## License
|
|
249
199
|
|
|
250
200
|
MIT
|
|
251
|
-
|
|
252
|
-
The top-level MIT license is the licensing surface for this repo. Per-file license headers are not required unless code is copied or adapted from another source that needs separate notice or attribution.
|