@skaleagents/swarm 0.7.0 → 0.7.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 +4 -2
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +36 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -21,6 +21,8 @@ the MCP tool for a structured review.
|
|
|
21
21
|
|
|
22
22
|
`npx -y @skaleagents/swarm scan [paths...]` scans IaC, CI, Dockerfile and package files on your machine. It needs no account and sends nothing over the network. Use `--changed` for files changed against HEAD, `--fail-on high` to exit 1, and `--json` for machine output.
|
|
23
23
|
|
|
24
|
+
Adopt it on an existing repo: `npx @skaleagents/swarm scan --write-baseline .skaleagents-baseline.json`, commit the file, and later scans (hook and Action included) show only new findings. Findings match on rule, file and resource, not line number.
|
|
25
|
+
|
|
24
26
|
Suppress an intended setting with a comment on the flagged line or the line above: `# skaleagents-ignore DATA001 public asset bucket`.
|
|
25
27
|
|
|
26
28
|
**Claude Code plugin.** It adds a stop hook that scans changed files and asks the agent to fix `high` and `critical` findings, plus a skill and the hosted MCP server:
|
|
@@ -33,7 +35,7 @@ Suppress an intended setting with a comment on the flagged line or the line abov
|
|
|
33
35
|
**Cursor.** Add `.cursor/hooks.json`:
|
|
34
36
|
|
|
35
37
|
```json
|
|
36
|
-
{ "version": 1, "hooks": { "stop": [{ "command": "npx -y --registry=https://registry.npmjs.org @skaleagents/swarm@0.7.
|
|
38
|
+
{ "version": 1, "hooks": { "stop": [{ "command": "npx -y --registry=https://registry.npmjs.org @skaleagents/swarm@0.7.1 scan --hook" }] } }
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
**GitHub Action.** It posts one PR comment and fails on `critical` by default:
|
|
@@ -47,7 +49,7 @@ jobs:
|
|
|
47
49
|
steps:
|
|
48
50
|
- uses: actions/checkout@v4
|
|
49
51
|
with: { fetch-depth: 0 }
|
|
50
|
-
- uses: SkaleAgents/mcp-server@v0.7.
|
|
52
|
+
- uses: SkaleAgents/mcp-server@v0.7.1
|
|
51
53
|
with: { fail-on: high }
|
|
52
54
|
```
|
|
53
55
|
|
package/dist/cli.d.ts
CHANGED
|
@@ -8,5 +8,7 @@ export declare function scanFiles(files: string[], minSeverity?: FindingSeverity
|
|
|
8
8
|
suppressed: number;
|
|
9
9
|
warnings: string[];
|
|
10
10
|
};
|
|
11
|
+
export declare const baselineKey: (f: FileFinding) => string;
|
|
12
|
+
export declare function readBaseline(path: string): Set<string>;
|
|
11
13
|
export declare function formatText(findings: FileFinding[], suppressed: number): string;
|
|
12
14
|
export declare function runScan(argv: string[]): Promise<number>;
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
|
-
import { existsSync, lstatSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { existsSync, lstatSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { basename, dirname, join, relative } from "node:path";
|
|
4
4
|
import { scanIac, severityRank } from "./iac/scan.js";
|
|
5
5
|
const usage = `Usage: skaleagents-swarm scan [paths...] [options]
|
|
@@ -9,6 +9,8 @@ Scans IaC, CI and package files locally. No account or network needed.
|
|
|
9
9
|
--changed Scan files changed against HEAD plus untracked files
|
|
10
10
|
--min-severity <s> Hide findings below info|low|medium|high|critical (default low)
|
|
11
11
|
--fail-on <s> Exit 1 when a finding is at or above this severity
|
|
12
|
+
--baseline <file> Hide findings already listed in this baseline file (.skaleagents-baseline.json is used automatically)
|
|
13
|
+
--write-baseline <file> Write current findings to a baseline file and exit 0
|
|
12
14
|
--json Print JSON instead of text
|
|
13
15
|
--hook Agent stop hook mode for Claude Code and Cursor (implies --changed)
|
|
14
16
|
|
|
@@ -91,6 +93,16 @@ export function scanFiles(files, minSeverity = "low") {
|
|
|
91
93
|
}
|
|
92
94
|
// Names come from scanned files, so they are flattened and capped before reaching an agent or PR comment.
|
|
93
95
|
const clean = (value, max = 160) => (value ?? "").replace(/[\x00-\x1f\x7f`]+/g, " ").slice(0, max);
|
|
96
|
+
// Line numbers are left out so unrelated edits above a finding do not make it look new.
|
|
97
|
+
export const baselineKey = (f) => `${f.ruleId}|${f.file.replaceAll("\\", "/")}|${f.resource ?? ""}`;
|
|
98
|
+
export function readBaseline(path) {
|
|
99
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
100
|
+
const keys = parsed?.findings;
|
|
101
|
+
if (!Array.isArray(keys) || keys.some((key) => typeof key !== "string")) {
|
|
102
|
+
throw new Error(`${path} is not a SkaleAgents baseline file`);
|
|
103
|
+
}
|
|
104
|
+
return new Set(keys);
|
|
105
|
+
}
|
|
94
106
|
export function formatText(findings, suppressed) {
|
|
95
107
|
if (findings.length === 0)
|
|
96
108
|
return `SkaleAgents: no findings${suppressed ? ` (${suppressed} suppressed)` : ""}.`;
|
|
@@ -110,6 +122,8 @@ export async function runScan(argv) {
|
|
|
110
122
|
let hook = false;
|
|
111
123
|
let minSeverity = "low";
|
|
112
124
|
let failOn;
|
|
125
|
+
let baselinePath;
|
|
126
|
+
let writeBaseline;
|
|
113
127
|
for (let i = 0; i < argv.length; i++) {
|
|
114
128
|
const arg = argv[i];
|
|
115
129
|
if (arg === "--") {
|
|
@@ -124,6 +138,15 @@ export async function runScan(argv) {
|
|
|
124
138
|
hook = changed = true;
|
|
125
139
|
else if (arg === "--min-severity")
|
|
126
140
|
minSeverity = severityArg(argv[++i], arg);
|
|
141
|
+
else if (arg === "--baseline" || arg === "--write-baseline") {
|
|
142
|
+
const value = argv[++i];
|
|
143
|
+
if (!value)
|
|
144
|
+
throw new Error(`${arg} needs a file path`);
|
|
145
|
+
if (arg === "--baseline")
|
|
146
|
+
baselinePath = value;
|
|
147
|
+
else
|
|
148
|
+
writeBaseline = value;
|
|
149
|
+
}
|
|
127
150
|
else if (arg === "--fail-on")
|
|
128
151
|
failOn = severityArg(argv[++i], arg);
|
|
129
152
|
else if (arg === "-h" || arg === "--help") {
|
|
@@ -149,7 +172,18 @@ export async function runScan(argv) {
|
|
|
149
172
|
}
|
|
150
173
|
for (const path of paths.length || changed ? paths : ["."])
|
|
151
174
|
walk(path, files);
|
|
152
|
-
const
|
|
175
|
+
const scanned = scanFiles([...new Set(files)], minSeverity);
|
|
176
|
+
const { suppressed, warnings } = scanned;
|
|
177
|
+
if (writeBaseline) {
|
|
178
|
+
const keys = [...new Set(scanned.findings.map(baselineKey))].sort();
|
|
179
|
+
writeFileSync(writeBaseline, `${JSON.stringify({ version: 1, findings: keys }, null, 2)}\n`);
|
|
180
|
+
console.log(`SkaleAgents: wrote ${keys.length} findings to ${writeBaseline}.`);
|
|
181
|
+
return 0;
|
|
182
|
+
}
|
|
183
|
+
// A committed baseline at the repo root applies automatically, so hooks and the Action need no flag.
|
|
184
|
+
baselinePath ??= existsSync(".skaleagents-baseline.json") ? ".skaleagents-baseline.json" : undefined;
|
|
185
|
+
const known = baselinePath ? readBaseline(baselinePath) : new Set();
|
|
186
|
+
const findings = scanned.findings.filter((f) => !known.has(baselineKey(f)));
|
|
153
187
|
const failing = failOn ? findings.filter((f) => severityRank[f.severity] >= severityRank[failOn]) : [];
|
|
154
188
|
if (hook) {
|
|
155
189
|
if (failing.length) {
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.7.
|
|
1
|
+
export declare const VERSION = "0.7.1";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "0.7.
|
|
1
|
+
export const VERSION = "0.7.1";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skaleagents/swarm",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -53,5 +53,6 @@
|
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/node": "^22.20.1",
|
|
55
55
|
"tsx": "^4.23.12"
|
|
56
|
-
}
|
|
56
|
+
},
|
|
57
|
+
"mcpName": "io.github.SkaleAgents/swarm"
|
|
57
58
|
}
|