@brokkai/slopcop 0.0.9 → 0.0.11
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 +94 -33
- 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
|
@@ -145,9 +145,22 @@ present, and names what it did:
|
|
|
145
145
|
A skill that is already there is left alone by init, so running it again is
|
|
146
146
|
safe. `slopcop login` and every check also install the skill in those
|
|
147
147
|
directories, rewriting one that differs from the skill bundled into the binary,
|
|
148
|
-
so an agent follows the instructions of the slopcop version it runs
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
so an agent follows the instructions of the slopcop version it runs. Each
|
|
149
|
+
install records the version that wrote it, and what each file held, in
|
|
150
|
+
`.slopcop-skill.json` in the skill folder. An update names the version it
|
|
151
|
+
replaces, the new one and the files that changed, for example:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
slopcop: updated the slopcop skill at ~/.claude/skills/slopcop from v0.0.9 to v0.0.10 (changed: SKILL.md). Reread it if you loaded the old one.
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
It removes the files the new skill no longer has. A skill with local edits,
|
|
158
|
+
one that matches neither its record nor any release, is copied first to
|
|
159
|
+
`skill-backups/<harness>-<time>` next to the slopcop configuration, outside
|
|
160
|
+
every skills directory so no harness loads it as a second skill, and the
|
|
161
|
+
notice says where. A check's `json` and `sarif` reports carry the same update
|
|
162
|
+
(see below). `slopcop init --no-skill` skips the install and any update of
|
|
163
|
+
it.
|
|
151
164
|
|
|
152
165
|
Init also adds a `Stop` hook for each harness installed here, and leaves
|
|
153
166
|
everything else in the file as it was:
|
|
@@ -166,13 +179,28 @@ When the agent stops, the hook checks the working tree through the same
|
|
|
166
179
|
hosted API, but only when all of these hold:
|
|
167
180
|
|
|
168
181
|
- the session wrote files in the repository with its edit tools (a Codex
|
|
169
|
-
session's subagents included)
|
|
182
|
+
session's subagents included), or the working tree has a changed
|
|
183
|
+
dependency manifest or lockfile (see below);
|
|
170
184
|
- slopcop is signed in, and the workspace a check would use
|
|
171
185
|
(`$SLOPCOP_WORKSPACE`, or the login's) has the repository active
|
|
172
186
|
(`slopcop repo list`), so nothing is sent from other repositories;
|
|
173
187
|
- the tree differs from the last check in the session, including a check the
|
|
174
188
|
agent ran by hand.
|
|
175
189
|
|
|
190
|
+
An agent often adds a dependency through its shell, with `npm install`,
|
|
191
|
+
`pnpm add`, `cargo add` or `uv add`, which no edit tool records. So the hook
|
|
192
|
+
also checks when git shows one of these files changed, added or untracked in
|
|
193
|
+
any directory of the repository: `package.json`, `package-lock.json`,
|
|
194
|
+
`npm-shrinkwrap.json`, `pnpm-lock.yaml`, `yarn.lock`, `Cargo.toml`,
|
|
195
|
+
`Cargo.lock`, `pyproject.toml`, `uv.lock`, `poetry.lock`, `requirements*.txt`,
|
|
196
|
+
`go.mod` and `go.sum`. Files git ignores and those under `node_modules` do
|
|
197
|
+
not count. The hook recognises these files by name only: it never reads
|
|
198
|
+
them, runs a package manager or asks an advisory database; the hosted check
|
|
199
|
+
reads them like any other file in the change. A changed dependency file
|
|
200
|
+
counts as one the session wrote, since the hook cannot tell which command
|
|
201
|
+
changed it, so its new findings are handed to the agent like those in files
|
|
202
|
+
it edited, even if the file was already changed when the session began.
|
|
203
|
+
|
|
176
204
|
New findings in files the session wrote are handed to the agent to fix, once
|
|
177
205
|
for a given tree and at most twice in a row; then the agent is let go and you
|
|
178
206
|
are told what remains. A finding ignored with `slopcop ignore` is not handed
|
|
@@ -197,8 +225,10 @@ slopcop login # browser device flow
|
|
|
197
225
|
slopcop login --token "$SLOPCOP_TOKEN" # existing credential, for CI and agents
|
|
198
226
|
```
|
|
199
227
|
|
|
200
|
-
The browser flow prints a
|
|
201
|
-
|
|
228
|
+
The browser flow prints a link that opens the approval page with the code
|
|
229
|
+
filled in, plus the page and code to type in instead, and stores the token once
|
|
230
|
+
the login is approved. Approve only if the page shows the code your terminal
|
|
231
|
+
printed. The service URL defaults to `https://slopcop.com`; `--service`,
|
|
202
232
|
`$SLOPCOP_SERVICE`, or a stored value override it.
|
|
203
233
|
|
|
204
234
|
The credential lives in `slopcop/config.json` under the user config directory
|
|
@@ -248,29 +278,43 @@ add`: a first check adds a repository. When the workspace would then pay for
|
|
|
248
278
|
it (it already has an active repository and is charged), the service refuses
|
|
249
279
|
the check with `repository_add_unconfirmed` until a person confirms: at a
|
|
250
280
|
terminal `check` prints what it costs, asks `Add owner/name to "Workspace"?
|
|
251
|
-
[y/N]`, and on a yes sends the check again
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
281
|
+
[y/N]`, and on a yes sends the check again and says `added owner/name to
|
|
282
|
+
"Workspace"` on stderr. With no terminal, as for an agent or CI (a pipe or the
|
|
283
|
+
null device is not one), nothing is asked: the check exits `4` with the
|
|
284
|
+
service's remedy, a line naming the command that confirms it, and, in `json`,
|
|
285
|
+
a `failed` report naming the code. A no at the terminal ends the same way.
|
|
286
|
+
Once the person has approved it, `check --add-repository --workspace
|
|
287
|
+
<name|id>` confirms without a terminal; the flag needs `--workspace` (the
|
|
288
|
+
flag itself, not `$SLOPCOP_WORKSPACE`), so an approval given for one
|
|
289
|
+
workspace cannot add the repository to the one the login happens to point at.
|
|
290
|
+
The flag changes nothing for a repository already in that workspace. A
|
|
291
|
+
workspace's first repository is added without asking. Deleting repositories,
|
|
292
|
+
archiving workspaces, members, credits and repository settings stay in the web
|
|
293
|
+
app. The commands exit `0` on success and `2` with the service's message and
|
|
294
|
+
remedy otherwise, as `ignore` does.
|
|
258
295
|
|
|
259
296
|
## Check
|
|
260
297
|
|
|
261
298
|
```console
|
|
262
299
|
slopcop # check the change in the current checkout
|
|
263
300
|
slopcop check --format json # same, machine-readable
|
|
264
|
-
slopcop --root ../repo --base
|
|
301
|
+
slopcop --root ../repo --base origin/main
|
|
265
302
|
```
|
|
266
303
|
|
|
267
304
|
The base commit defaults to the merge base with the branch upstream, then the
|
|
268
305
|
merge base with `origin/HEAD`, then `HEAD` when neither is known. When the
|
|
269
306
|
upstream merge base yields an empty patch, as on a branch whose commits are all
|
|
270
307
|
pushed, the CLI uses the merge base with `origin/HEAD` instead, so a check
|
|
271
|
-
right after a push still covers the branch.
|
|
272
|
-
|
|
273
|
-
`
|
|
308
|
+
right after a push still covers the branch. `--base REV` names the branch the
|
|
309
|
+
change started from and, like `git diff REV...HEAD`, uses the merge base of
|
|
310
|
+
`REV` and `HEAD`, so commits that landed on `REV` after the branch point are not
|
|
311
|
+
sent as reverse edits. `--base-exact REV` diffs against `REV` itself. The
|
|
312
|
+
service must already have the base commit in its clone; a missing one comes back as the service's
|
|
313
|
+
`base_not_found` message and remedy. The CLI then asks origin for its default
|
|
314
|
+
branch (`git ls-remote`, no prompt, 10 second limit) and adds a line when the
|
|
315
|
+
clone explains the failure: origin's default branch was renamed and
|
|
316
|
+
`origin/HEAD` still names the old one, or the base is not on origin's default
|
|
317
|
+
branch.
|
|
274
318
|
|
|
275
319
|
Every run sends one check request, even when the working tree matches the base
|
|
276
320
|
and the patch is empty. A clean result or a failure always comes from the
|
|
@@ -284,14 +328,16 @@ Flags:
|
|
|
284
328
|
| Flag | Meaning |
|
|
285
329
|
| --- | --- |
|
|
286
330
|
| `--root PATH` | repository to check (default `.`) |
|
|
287
|
-
| `--base REV` |
|
|
331
|
+
| `--base REV` | branch or revision the change started from; the base is its merge base with `HEAD` |
|
|
332
|
+
| `--base-exact REV` | exact base commit or revision, without a merge base |
|
|
288
333
|
| `--format human\|json\|sarif` | report format (default `human`) |
|
|
289
334
|
| `--fail-on never\|finding\|note\|warning\|error` | exit-1 threshold for new findings (default `finding`) |
|
|
290
335
|
| `--policy PATH` | repository-relative `.rqlp` file to evaluate (repeatable) |
|
|
291
336
|
| `--no-policy-discovery` | skip `.slopcop/policies` rules |
|
|
292
337
|
| `--timeout DURATION` | how long to wait for the result (default `10m`) |
|
|
293
338
|
| `-w`, `--workspace NAME\|ID` | check in, and bill, this workspace of the account instead of the login's |
|
|
294
|
-
| `--
|
|
339
|
+
| `--add-repository` | add the repository to the workspace `--workspace` names, which then pays for it, without asking at a terminal; for after the user approved it |
|
|
340
|
+
| `--verbose` | print the resolved request to stderr, and name each inconclusive check in `human` |
|
|
295
341
|
|
|
296
342
|
### What is sent
|
|
297
343
|
|
|
@@ -368,8 +414,13 @@ summary line such as `1 new finding across 1 file(s); 72 already in the code |
|
|
|
368
414
|
Analysis complete`, and any omitted new findings or
|
|
369
415
|
incomplete checks. `json` prints `status`, `baseCommit`, `summary`
|
|
370
416
|
(`newFindings` and `existingFindings` count the split), `findings` (each with
|
|
371
|
-
`new` and its `id`), `incomplete`, `failure` when the analysis did not
|
|
372
|
-
complete, and `emptyChange` when the patch was empty.
|
|
417
|
+
`new` and its `id`), `incomplete`, `inconclusive`, `failure` when the analysis did not
|
|
418
|
+
complete, and `emptyChange` when the patch was empty. When the check
|
|
419
|
+
installed or updated the skill, `skillUpdated` lists each skill directory it
|
|
420
|
+
wrote: `dir`, `from` (a release, `unknown`, or absent for a fresh install),
|
|
421
|
+
`to`, `changed` and, for a skill with local edits, `backup`; the failed and
|
|
422
|
+
pending reports carry it too, and `sarif` puts it in
|
|
423
|
+
`properties["slopcop.skillUpdated"]`. `sarif` prints a SARIF 2.1.0 log whose results carry `baselineState`
|
|
373
424
|
`new` and the finding id in `properties["slopcop.findingId"]`. `--format` only
|
|
374
425
|
changes the rendering, never the request, so the service answers the same check
|
|
375
426
|
whichever is used.
|
|
@@ -390,10 +441,18 @@ reached the service; after, a service that received it keeps running it, and
|
|
|
390
441
|
running the same check again picks up its result.
|
|
391
442
|
|
|
392
443
|
An inconclusive check, one that ran but could not prove there is nothing
|
|
393
|
-
more to find, never changes the exit code
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
444
|
+
more to find, never changes the exit code or the status. Complete proof is
|
|
445
|
+
rare in static analysis, typically at a library boundary, so this is the norm
|
|
446
|
+
rather than a gap. Each report still says where they are, so a reviewer can
|
|
447
|
+
judge what a `clean` result is worth: `human` prints one `Inconclusive:` line
|
|
448
|
+
with the count and how many concern only files the change does not write, and
|
|
449
|
+
`--verbose` names each check. `json` lists them in `inconclusive`, each with
|
|
450
|
+
`policyId`, `reason` and `elsewhere` (true when it concerns only files the
|
|
451
|
+
change does not write), beside the `summary.inconclusive` count. `sarif` adds
|
|
452
|
+
a `note` notification per check with `slopcop.inconclusive` and
|
|
453
|
+
`slopcop.elsewhere` properties. The service names at most 50; the counts
|
|
454
|
+
cover the rest. It does not yet say which files or lines each one concerns,
|
|
455
|
+
or what evidence was missing. A check that timed out or
|
|
397
456
|
that Bifrost judged unreliable is incomplete and counts wherever it is.
|
|
398
457
|
|
|
399
458
|
The service applies `--fail-on` and sets the status; the exit code follows it.
|
|
@@ -420,9 +479,11 @@ rewrite them. The remedies name no client, so the CLI adds its own command
|
|
|
420
479
|
after some: `slopcop login` when the remedy is to sign in, the listing to
|
|
421
480
|
choose from after `workspace_not_found` or `workspace_repository_not_found`,
|
|
422
481
|
and `slopcop whoami` after `repository_disabled`, since the workspace that
|
|
423
|
-
disabled it is the one this login is bound to,
|
|
424
|
-
`owner_required
|
|
425
|
-
|
|
482
|
+
disabled it is the one this login is bound to, `--workspace` after
|
|
483
|
+
`owner_required`, and `--add-repository --workspace "Name"`, with the
|
|
484
|
+
workspace the check would have added the repository to, after
|
|
485
|
+
`repository_add_unconfirmed`. A failed check exits `4` when only a person can
|
|
486
|
+
clear the refusal (`auth_required`, `auth_expired`, `account_required`,
|
|
426
487
|
`repo_not_indexed`, `app_not_installed`, `app_no_repo_access`,
|
|
427
488
|
`gitlab_not_connected`, `no_access`, `insufficient_credits`,
|
|
428
489
|
`repository_disabled`, `repository_add_unconfirmed`,
|
|
@@ -451,11 +512,11 @@ The CLI calls `POST <service>/v1/check` with a bearer token:
|
|
|
451
512
|
}
|
|
452
513
|
```
|
|
453
514
|
|
|
454
|
-
`addRepository` is sent only after a person confirms adding the repository
|
|
455
|
-
service rejects any other field.
|
|
456
|
-
check's, the ignore's and the account
|
|
457
|
-
the `SlopCop-Workspace` header; a name
|
|
458
|
-
`GET <service>/v1/whoami`. The response carries `status`,
|
|
515
|
+
`addRepository` is sent only after a person confirms adding the repository, at
|
|
516
|
+
the terminal or with `--add-repository`. The service rejects any other field.
|
|
517
|
+
With `--workspace`, every request, the check's, the ignore's and the account
|
|
518
|
+
routes', carries the workspace's id in the `SlopCop-Workspace` header; a name
|
|
519
|
+
is first looked up with `GET <service>/v1/whoami`. The response carries `status`,
|
|
459
520
|
`baseCommit`, `applied`, `summary`, `findings`, `incomplete`, and `failure`
|
|
460
521
|
when the analysis did not complete. Against a service from before findings
|
|
461
522
|
were marked `new`, the CLI treats every finding as new, as that service gated
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|