@brokkai/slopcop 0.0.4 → 0.0.6
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 +126 -23
- package/native/darwin_amd64/slopcop +0 -0
- package/native/darwin_arm64/slopcop +0 -0
- package/native/linux_amd64/slopcop +0 -0
- package/native/linux_arm64/slopcop +0 -0
- package/native/windows_amd64/slopcop.exe +0 -0
- package/native/windows_arm64/slopcop.exe +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -110,9 +110,12 @@ harness is present, and names what it did:
|
|
|
110
110
|
| `~/.claude/skills/slopcop/` | Claude Code, opencode |
|
|
111
111
|
| `$CODEX_HOME/skills/slopcop/`, or `~/.codex/skills/slopcop/` | Codex home |
|
|
112
112
|
|
|
113
|
-
A skill that is already there is left alone, so
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
A skill that is already there is left alone by init, so running it again is
|
|
114
|
+
safe. `slopcop login` and every check also install the skill in those
|
|
115
|
+
directories, rewriting one that differs from the skill bundled into the binary,
|
|
116
|
+
so an agent follows the instructions of the slopcop version it runs; local
|
|
117
|
+
edits to an installed skill do not survive them. `slopcop init --no-skill`
|
|
118
|
+
skips the install and any update of it.
|
|
116
119
|
|
|
117
120
|
## Sign in
|
|
118
121
|
|
|
@@ -135,6 +138,35 @@ Precedence:
|
|
|
135
138
|
| Service URL | `--service`, `$SLOPCOP_SERVICE`, stored by `slopcop login`, `https://slopcop.com` |
|
|
136
139
|
| Token | `$SLOPCOP_TOKEN`, stored value |
|
|
137
140
|
|
|
141
|
+
## Workspace and repositories
|
|
142
|
+
|
|
143
|
+
A login runs its checks and ignores in, and bills, one workspace: the one
|
|
144
|
+
active in the browser when the login was approved.
|
|
145
|
+
|
|
146
|
+
```console
|
|
147
|
+
slopcop whoami # account, this login's workspace, its plan, the service URL
|
|
148
|
+
slopcop workspace list # the account's workspaces; * marks this login's
|
|
149
|
+
slopcop workspace use "Acme team" # move this login (not the browser) to another, by name or id
|
|
150
|
+
slopcop repo list # the workspace's repositories: active, disabled, or over the limit
|
|
151
|
+
slopcop repo disable acme/widgets # stop checking and charging for one (owner only)
|
|
152
|
+
slopcop repo enable acme/widgets # turn it back on, within the workspace's active limit
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`whoami`, `workspace list` and `repo list` take `--format human|json`, as do
|
|
156
|
+
`workspace use` and `repo enable|disable` for their answer. Every active
|
|
157
|
+
repository after a workspace's first costs credits every 30 days; a disabled
|
|
158
|
+
one is not checked or charged and keeps its reports, findings and settings.
|
|
159
|
+
`repo enable` and `repo disable` ask you to type the repository's `owner/name`
|
|
160
|
+
and refuse when stdin is not a terminal: an agent or CI job runs with your
|
|
161
|
+
login, and the service cannot tell it from you, so changing what the workspace
|
|
162
|
+
pays stays a step you take yourself.
|
|
163
|
+
Names match without regard to case; when two workspaces share a name, or two
|
|
164
|
+
providers a repository name, pass the id the listing prints. There is no `repo
|
|
165
|
+
add`: a first check adds a repository. Deleting repositories, archiving
|
|
166
|
+
workspaces, members, credits and repository settings stay in the web app. The
|
|
167
|
+
commands exit `0` on success and `2` with the service's message and remedy
|
|
168
|
+
otherwise, as `ignore` does.
|
|
169
|
+
|
|
138
170
|
## Check
|
|
139
171
|
|
|
140
172
|
```console
|
|
@@ -160,7 +192,6 @@ Flags:
|
|
|
160
192
|
| `--base REV` | base commit or revision for the change |
|
|
161
193
|
| `--format human\|json\|sarif` | report format (default `human`) |
|
|
162
194
|
| `--fail-on never\|finding\|note\|warning\|error` | exit-1 threshold for new findings (default `finding`) |
|
|
163
|
-
| `--show-existing` | also list the findings that were already in the code |
|
|
164
195
|
| `--policy PATH` | repository-relative `.rqlp` file to evaluate (repeatable) |
|
|
165
196
|
| `--no-policy-discovery` | skip `.slopcop/policies` rules |
|
|
166
197
|
| `--timeout DURATION` | how long to wait for the result (default `10m`) |
|
|
@@ -175,6 +206,26 @@ changes, and binary content. Git-ignored files stay out, except selected
|
|
|
175
206
|
`.slopcop/policies` rules, which must travel because the service evaluates them
|
|
176
207
|
from the patched checkout.
|
|
177
208
|
|
|
209
|
+
A check run by a Claude Code or Codex agent also sends which models wrote the
|
|
210
|
+
change, so the service can tie each finding to the model that wrote its file.
|
|
211
|
+
The CLI finds the agent's session from its environment and reads that
|
|
212
|
+
session's own record:
|
|
213
|
+
|
|
214
|
+
- **Claude Code:** `CLAUDE_CODE_SESSION_ID` names the transcript under
|
|
215
|
+
`~/.claude/projects` (or `$CLAUDE_CONFIG_DIR/projects`), subagents included.
|
|
216
|
+
Each successful Write, Edit, MultiEdit or NotebookEdit gives a model, an
|
|
217
|
+
effort and a file.
|
|
218
|
+
- **Codex:** `CODEX_THREAD_ID` names the rollout under `~/.codex/sessions` (or
|
|
219
|
+
`$CODEX_HOME/sessions`). Each completed file change gives the files, and its
|
|
220
|
+
turn gives the model and effort. A move counts as writing its destination.
|
|
221
|
+
|
|
222
|
+
It reads only those fields, never the conversation, tool input or file
|
|
223
|
+
contents. What it sends is the harness, its version, the session id as an
|
|
224
|
+
opaque identifier, and each model and effort with the repository-relative
|
|
225
|
+
files it wrote. A check run outside an agent session sends none of this. It
|
|
226
|
+
is analytics only, asserted by the client, and never decides a check.
|
|
227
|
+
`--verbose` prints it.
|
|
228
|
+
|
|
178
229
|
The service owns the limits on what a check accepts. When a change is too
|
|
179
230
|
large or touches too many files, the service's `payload_too_large` response is
|
|
180
231
|
printed verbatim; the CLI does not impose its own limits.
|
|
@@ -188,22 +239,44 @@ Every check also runs the hosted catalog. Rules under
|
|
|
188
239
|
A check fails only on findings the change introduced or touched: the service
|
|
189
240
|
marks a finding new when it is in a file the change writes and its lines meet a
|
|
190
241
|
line the change added, or the line beside one it removed. Findings that were
|
|
191
|
-
already in the code are counted
|
|
192
|
-
|
|
193
|
-
findings the repository
|
|
242
|
+
already in the code are counted (`summary.existingFindings`, and `N already in
|
|
243
|
+
the code` in the human summary), never fail the check, and are not listed. A
|
|
244
|
+
change that introduces nothing exits `0`, however many findings the repository
|
|
245
|
+
already holds. `--show-existing` is deprecated and hidden: the service no longer
|
|
246
|
+
sends those findings, so against it the flag lists nothing (a service from
|
|
247
|
+
before that still gets them listed), and it stays so that scripts passing it
|
|
248
|
+
keep running.
|
|
249
|
+
|
|
250
|
+
### Ignore a false positive
|
|
251
|
+
|
|
252
|
+
Each finding a check reports carries an `id`. When a finding is a false
|
|
253
|
+
positive, ignore it:
|
|
254
|
+
|
|
255
|
+
```console
|
|
256
|
+
slopcop ignore 0f8fad5b-d9cb-469f-a165-70867728950e
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
That finding is not reported again for this repository. Ignoring covers that
|
|
260
|
+
one finding, its rule plus its place in the code, in its repository for your
|
|
261
|
+
workspace; the rule keeps reporting everything else. Ignoring a finding twice
|
|
262
|
+
is fine. `ignore` uses the same login and service URL as a check, exits `0`
|
|
263
|
+
with a one-line confirmation, and otherwise exits `2` with the service's
|
|
264
|
+
message and remedy; `finding_not_found` means the id is unknown or comes from a
|
|
265
|
+
check outside your workspace.
|
|
194
266
|
|
|
195
267
|
### Output and exit codes
|
|
196
268
|
|
|
197
269
|
The service answers structured data; the CLI renders it. `human` prints one
|
|
198
|
-
block per new finding,
|
|
199
|
-
summary line such as `1 new finding across 1 file(s); 72 already in the code
|
|
200
|
-
|
|
270
|
+
block per new finding, with an `ID:` line when the service names one, then a
|
|
271
|
+
summary line such as `1 new finding across 1 file(s); 72 already in the code |
|
|
272
|
+
Analysis complete`, and any omitted or
|
|
201
273
|
incomplete checks. `json` prints `status`, `baseCommit`, `summary`
|
|
202
274
|
(`newFindings` and `existingFindings` count the split), `findings` (each with
|
|
203
|
-
`new`), `incomplete`, and `failure` when the analysis did not
|
|
204
|
-
prints a SARIF 2.1.0 log whose results carry `baselineState`
|
|
205
|
-
`
|
|
206
|
-
the request, so the service answers the same check
|
|
275
|
+
`new` and its `id`), `incomplete`, and `failure` when the analysis did not
|
|
276
|
+
complete. `sarif` prints a SARIF 2.1.0 log whose results carry `baselineState`
|
|
277
|
+
`new` and the finding id in `properties["slopcop.findingId"]`. `--format` only
|
|
278
|
+
changes the rendering, never the request, so the service answers the same check
|
|
279
|
+
whichever is used.
|
|
207
280
|
|
|
208
281
|
| Exit | Meaning |
|
|
209
282
|
| --- | --- |
|
|
@@ -211,6 +284,13 @@ the request, so the service answers the same check whichever is used.
|
|
|
211
284
|
| `1` | A new finding crossed `--fail-on` |
|
|
212
285
|
| `2` | No new finding crossed `--fail-on`, but a check was incomplete; or the CLI or service failed |
|
|
213
286
|
| `3` | The check was still running when `--timeout` ran out |
|
|
287
|
+
| `130`, `143` | Interrupted before the check answered: `130` for Ctrl-C, `143` for SIGTERM |
|
|
288
|
+
|
|
289
|
+
Only `clean` exits `0`: a status this CLI does not know exits `2`, so a newer
|
|
290
|
+
service can never pass a check by accident, and stderr names the status. An
|
|
291
|
+
interrupted check prints no report. Interrupted before it was sent, nothing
|
|
292
|
+
reached the service; after, a service that received it keeps running it, and
|
|
293
|
+
running the same check again picks up its result.
|
|
214
294
|
|
|
215
295
|
An inconclusive check fails the check only when it concerns a file the
|
|
216
296
|
change writes. One about other files is listed on an `Inconclusive outside
|
|
@@ -239,13 +319,12 @@ again picks up the same analysis.
|
|
|
239
319
|
Service failures print the closed contract exactly: message, remedy, and any
|
|
240
320
|
install URL. The codes, messages, and remedies are defined by the service in
|
|
241
321
|
`server/src/check.rs` of `BrokkAi/bifrost-service`; the CLI does not
|
|
242
|
-
rewrite them. The remedies name no client, so
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
and exits `2` without waiting or retrying.
|
|
322
|
+
rewrite them. The remedies name no client, so the CLI adds its own command
|
|
323
|
+
after some: `slopcop login` when the remedy is to sign in, the listing to
|
|
324
|
+
choose from after `workspace_not_found` or `workspace_repository_not_found`,
|
|
325
|
+
and `slopcop whoami` after `repository_disabled`, since the workspace that
|
|
326
|
+
disabled it is the one this login is bound to. A failed request prints no
|
|
327
|
+
report on stdout.
|
|
249
328
|
|
|
250
329
|
## API
|
|
251
330
|
|
|
@@ -268,11 +347,35 @@ were marked `new`, the CLI treats every finding as new, as that service gated
|
|
|
268
347
|
on all of them. Non-2xx responses carry `code`, `message`,
|
|
269
348
|
`remedy`, `retryable`, and an optional `installUrl`.
|
|
270
349
|
|
|
350
|
+
Each finding in the response carries an `id`; a service from before findings
|
|
351
|
+
could be ignored omits it.
|
|
352
|
+
|
|
353
|
+
`slopcop ignore <id>` calls `POST <service>/v1/ignore` with the same bearer
|
|
354
|
+
token and `{"findingId": "<id>"}`, and gets back
|
|
355
|
+
`{"findingId": "<id>", "status": "ignored"}`. Failures use the same closed
|
|
356
|
+
contract, including `finding_not_found`.
|
|
357
|
+
|
|
358
|
+
The account commands use the same bearer token. `GET <service>/v1/whoami`
|
|
359
|
+
answers `account`, `workspace` (`id`, `name`, `kind`, `role`, `current`),
|
|
360
|
+
`plan` (`pro` or `free`) and `workspaces`. `POST <service>/v1/workspace` with
|
|
361
|
+
`{"workspaceId"}` rebinds the login. `GET <service>/v1/repositories` answers
|
|
362
|
+
`repositories` (`id`, `provider`, `fullName`, `enabled`, `active`) with
|
|
363
|
+
`activeRepositoryLimit`, `activeRepositories` and `canManageRepositories`, and
|
|
364
|
+
`POST <service>/v1/repositories/state` with `{"repositoryId", "enabled"}`
|
|
365
|
+
answers `{repositoryId, fullName, enabled, active}`. Their failure codes add
|
|
366
|
+
`account_required`, `workspace_not_found`, `workspace_repository_not_found`,
|
|
367
|
+
`owner_required` and `browser_required` (a private Bitbucket or GitLab
|
|
368
|
+
repository, which only the web app can change) to the check's.
|
|
369
|
+
|
|
271
370
|
`slopcop login` uses the device flow: `POST /api/device` returns a
|
|
272
371
|
`deviceCode`, `userCode`, `verificationUri`, `expiresIn`, and `interval`, and
|
|
273
372
|
`POST /api/token` returns `202` while pending or `200` with a `token` once
|
|
274
|
-
approved. The
|
|
275
|
-
`expired_token`, and `
|
|
373
|
+
approved. The failure codes are `slow_down`, which raises the polling interval,
|
|
374
|
+
`expired_token`, `access_denied`, and `device_flow_disabled`. A failure the
|
|
375
|
+
service marks `retryable`, such as `rate_limited` or `service_unavailable`,
|
|
376
|
+
keeps the code valid, and so do a dropped connection and a proxy's `429`,
|
|
377
|
+
`502`, `503` or `504` without a code: login waits the `Retry-After`, or the
|
|
378
|
+
interval if that is longer, and polls again until the code expires.
|
|
276
379
|
|
|
277
380
|
## Development
|
|
278
381
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|