swarmdo 1.58.6 → 1.58.15
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/.claude/commands/sDo/security.md +44 -0
- package/.claude/helpers/statusline.cjs +139 -3
- package/README.md +3 -2
- package/package.json +1 -1
- package/v3/@swarmdo/cli/.claude/commands/sDo/agents/README.md +1 -1
- package/v3/@swarmdo/cli/.claude/commands/sDo/agents/agent-capabilities.md +1 -1
- package/v3/@swarmdo/cli/.claude/commands/sDo/agents/agent-types.md +2 -2
- package/v3/@swarmdo/cli/.claude/commands/sDo/security.md +44 -0
- package/v3/@swarmdo/cli/.claude/commands/sDo/swarm/swarm.md +1 -1
- package/v3/@swarmdo/cli/.claude/helpers/statusline.cjs +770 -498
- package/v3/@swarmdo/cli/.claude/skills/sdo-agentic-jujutsu/SKILL.md +645 -0
- package/v3/@swarmdo/cli/.claude/skills/sdo-hive-mind-advanced/SKILL.md +709 -0
- package/v3/@swarmdo/cli/.claude/skills/sdo-performance-analysis/SKILL.md +560 -0
- package/v3/@swarmdo/cli/dist/src/commands/integrations.js +185 -2
- package/v3/@swarmdo/cli/dist/src/commands/statusline.d.ts +22 -1
- package/v3/@swarmdo/cli/dist/src/commands/statusline.js +84 -3
- package/v3/@swarmdo/cli/dist/src/init/statusline-generator.js +138 -2
- package/v3/@swarmdo/cli/dist/src/integrations/skills-sync.d.ts +120 -0
- package/v3/@swarmdo/cli/dist/src/integrations/skills-sync.js +180 -0
- package/v3/@swarmdo/cli/dist/src/usage/account-plan.d.ts +48 -0
- package/v3/@swarmdo/cli/dist/src/usage/account-plan.js +71 -0
- package/v3/@swarmdo/cli/package.json +1 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Scan this project's security and refresh the statusline Security segment
|
|
3
|
+
argument-hint: "[scan|full|cve|audit|report] (default: scan)"
|
|
4
|
+
allowed-tools: Bash(npx swarmdo security:*), Bash(node v3/@swarmdo/cli/bin/cli.js security:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /security — scan security posture + refresh the statusline
|
|
8
|
+
|
|
9
|
+
Run the swarmdo security scanner and refresh the `Security` element of the
|
|
10
|
+
statusline. The statusline reads the cached result from
|
|
11
|
+
`.swarmdo/security/last-scan.json`; a scan rewrites it with a fresh `scannedAt`
|
|
12
|
+
plus current counts, so the `Security ●…` indicator stops showing `STALE` and
|
|
13
|
+
reflects reality (`●CLEAN` when clean, `●VULN` when critical/high are present).
|
|
14
|
+
|
|
15
|
+
Resolve the swarmdo CLI as `npx swarmdo` if installed, else
|
|
16
|
+
`node v3/@swarmdo/cli/bin/cli.js` (this repo). Call it `$CLI` below.
|
|
17
|
+
|
|
18
|
+
## Input
|
|
19
|
+
|
|
20
|
+
`$ARGUMENTS`
|
|
21
|
+
|
|
22
|
+
## Behavior
|
|
23
|
+
|
|
24
|
+
Pick the mode from the first argument (default `scan` when empty):
|
|
25
|
+
|
|
26
|
+
- `scan` (default) — run `$CLI security scan` (standard depth).
|
|
27
|
+
- `full` — run `$CLI security scan --depth full` for the complete finding list.
|
|
28
|
+
- `cve` — run `$CLI security cve` (dependency-CVE audit only).
|
|
29
|
+
- `audit` — run `$CLI security audit`.
|
|
30
|
+
- `report` — run `$CLI security report` (summarize the last scan, no re-scan).
|
|
31
|
+
|
|
32
|
+
Then:
|
|
33
|
+
|
|
34
|
+
1. Report the summary counts — critical / high / medium / total — from the
|
|
35
|
+
scanner output.
|
|
36
|
+
2. Confirm the statusline `Security` element refreshed: it now shows `●CLEAN`
|
|
37
|
+
(no critical/high) or `●VULN` (critical/high present) and no longer `●STALE`.
|
|
38
|
+
The change lands on the next statusline render — no regeneration needed.
|
|
39
|
+
3. If any critical or high findings exist, list the top few (severity, package,
|
|
40
|
+
short description) and point at `$CLI security scan --depth full` for the rest.
|
|
41
|
+
|
|
42
|
+
`.swarmdo/security/last-scan.json` is per-project, so run this in each project
|
|
43
|
+
whose statusline you want current. This command only scans and reports — it does
|
|
44
|
+
not modify code or dependencies.
|
|
@@ -84,6 +84,43 @@ function resolveSegments() {
|
|
|
84
84
|
const SEGMENTS = resolveSegments();
|
|
85
85
|
function seg(name) { return SEGMENTS.has(name); }
|
|
86
86
|
|
|
87
|
+
// ─── Cost slot: plan-aware mode + account display ────────────────────────────
|
|
88
|
+
// Resolution mirrors resolveSegments: env → project config → global config →
|
|
89
|
+
// default. mode: auto|dollars|limits|off (auto → limits for a subscription
|
|
90
|
+
// account, dollars otherwise); showAccount prefixes the account label.
|
|
91
|
+
function resolveCostOptions() {
|
|
92
|
+
let mode = null;
|
|
93
|
+
let showAccount = null;
|
|
94
|
+
const envMode = (process.env.SWARMDO_STATUSLINE_COST_MODE || '').trim().toLowerCase();
|
|
95
|
+
if (envMode === 'auto' || envMode === 'dollars' || envMode === 'limits' || envMode === 'off') mode = envMode;
|
|
96
|
+
const envShow = (process.env.SWARMDO_STATUSLINE_SHOW_ACCOUNT || '').trim();
|
|
97
|
+
if (/^(1|true|yes|on)$/i.test(envShow)) showAccount = true;
|
|
98
|
+
else if (/^(0|false|no|off)$/i.test(envShow)) showAccount = false;
|
|
99
|
+
if (mode === null || showAccount === null) {
|
|
100
|
+
const files = [
|
|
101
|
+
path.join(CWD, '.swarmdo', 'statusline.json'),
|
|
102
|
+
path.join(os.homedir(), '.swarmdo', 'statusline.json'),
|
|
103
|
+
];
|
|
104
|
+
for (const f of files) {
|
|
105
|
+
try {
|
|
106
|
+
const j = JSON.parse(fs.readFileSync(f, 'utf8'));
|
|
107
|
+
const cost = j && j.cost;
|
|
108
|
+
if (cost && typeof cost === 'object') {
|
|
109
|
+
if (mode === null && typeof cost.mode === 'string') {
|
|
110
|
+
const m = cost.mode.trim().toLowerCase();
|
|
111
|
+
if (m === 'auto' || m === 'dollars' || m === 'limits' || m === 'off') mode = m;
|
|
112
|
+
}
|
|
113
|
+
if (showAccount === null && typeof cost.showAccount === 'boolean') showAccount = cost.showAccount;
|
|
114
|
+
}
|
|
115
|
+
} catch (e) { /* absent/invalid — keep looking */ }
|
|
116
|
+
if (mode !== null && showAccount !== null) break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (CONFIG.hideCost) mode = 'off'; // legacy SWARMDO_STATUSLINE_HIDE_COST
|
|
120
|
+
return { mode: mode || 'auto', showAccount: showAccount === true };
|
|
121
|
+
}
|
|
122
|
+
const COST_OPTS = resolveCostOptions();
|
|
123
|
+
|
|
87
124
|
// #2337: resolve an already-installed @swarmdo/cli (or swarmdo) bin so we
|
|
88
125
|
// can invoke it directly via `node`. The previous version called
|
|
89
126
|
// `npx --yes @swarmdo/cli@latest` on every uncached render, which forces
|
|
@@ -516,13 +553,96 @@ function getCostFromStdin() {
|
|
|
516
553
|
return null;
|
|
517
554
|
}
|
|
518
555
|
|
|
556
|
+
// ── Account plan + rate-limit windows (for the plan-aware cost slot) ──────────
|
|
557
|
+
// ~/.claude.json holds only the CURRENTLY active account (overwritten on switch),
|
|
558
|
+
// so we read it live each render — that makes the slot correct across account
|
|
559
|
+
// switches without any stored state. We read a few plan fields, never tokens.
|
|
560
|
+
function readClaudeAccount() {
|
|
561
|
+
try {
|
|
562
|
+
const j = JSON.parse(fs.readFileSync(path.join(os.homedir(), '.claude.json'), 'utf8'));
|
|
563
|
+
const a = j && j.oauthAccount;
|
|
564
|
+
if (a && typeof a === 'object') {
|
|
565
|
+
return { billingType: a.billingType, organizationType: a.organizationType, displayName: a.displayName, organizationName: a.organizationName };
|
|
566
|
+
}
|
|
567
|
+
} catch (e) { /* not logged in / unreadable */ }
|
|
568
|
+
return null;
|
|
569
|
+
}
|
|
570
|
+
function detectPlan(a) {
|
|
571
|
+
if (!a || typeof a !== 'object') return 'unknown';
|
|
572
|
+
const b = typeof a.billingType === 'string' ? a.billingType : '';
|
|
573
|
+
const o = typeof a.organizationType === 'string' ? a.organizationType : '';
|
|
574
|
+
if (/subscription/i.test(b) || /claude_(max|team|enterprise|pro)/i.test(o)) return 'subscription';
|
|
575
|
+
if (b) return 'payg';
|
|
576
|
+
return 'unknown';
|
|
577
|
+
}
|
|
578
|
+
function accountLabel(a) {
|
|
579
|
+
if (!a) return '';
|
|
580
|
+
let raw = (typeof a.displayName === 'string' && a.displayName) || (typeof a.organizationName === 'string' && a.organizationName) || '';
|
|
581
|
+
raw = String(raw).trim();
|
|
582
|
+
if (!raw) return '';
|
|
583
|
+
return raw.length > 16 ? raw.slice(0, 15) + '…' : raw;
|
|
584
|
+
}
|
|
585
|
+
function rlToEpochMs(v) {
|
|
586
|
+
if (typeof v === 'number' && isFinite(v)) return v < 1e12 ? v * 1000 : v;
|
|
587
|
+
if (typeof v === 'string') { const t = Date.parse(v); return isNaN(t) ? null : t; }
|
|
588
|
+
return null;
|
|
589
|
+
}
|
|
590
|
+
function rlPickWindow(obj, windowMs, label) {
|
|
591
|
+
if (!obj || typeof obj !== 'object') return null;
|
|
592
|
+
const used = (obj.used_percentage != null ? obj.used_percentage : obj.usedPercentage);
|
|
593
|
+
const resetsAtMs = rlToEpochMs(obj.resets_at != null ? obj.resets_at : obj.resetsAt);
|
|
594
|
+
if (typeof used !== 'number' || !isFinite(used) || resetsAtMs === null) return null;
|
|
595
|
+
return { label: label, used: Math.max(0, Math.min(100, used)), windowMs: windowMs, resetsAtMs: resetsAtMs };
|
|
596
|
+
}
|
|
597
|
+
function getRateLimitWindows() {
|
|
598
|
+
const data = getStdinData();
|
|
599
|
+
if (!data) return [];
|
|
600
|
+
const rl = data.rate_limits || data.rateLimits || data;
|
|
601
|
+
if (!rl || typeof rl !== 'object') return [];
|
|
602
|
+
const out = [];
|
|
603
|
+
const w5 = rlPickWindow(rl.five_hour || rl.fiveHour, 5 * 60 * 60 * 1000, '5h');
|
|
604
|
+
const w7 = rlPickWindow(rl.seven_day || rl.sevenDay, 7 * 24 * 60 * 60 * 1000, '7d');
|
|
605
|
+
if (w5) out.push(w5);
|
|
606
|
+
if (w7) out.push(w7);
|
|
607
|
+
return out;
|
|
608
|
+
}
|
|
609
|
+
function rlWindowStatus(w, nowMs) {
|
|
610
|
+
if (w.used >= 100) return 'over';
|
|
611
|
+
const windowStart = w.resetsAtMs - w.windowMs;
|
|
612
|
+
const elapsed = nowMs - windowStart;
|
|
613
|
+
let willExhaust = false;
|
|
614
|
+
if (w.used > 0 && elapsed > 0) {
|
|
615
|
+
const msTo100 = ((100 - w.used) * elapsed) / w.used;
|
|
616
|
+
willExhaust = (nowMs + msTo100) <= w.resetsAtMs;
|
|
617
|
+
}
|
|
618
|
+
return (willExhaust || w.used >= 80) ? 'warn' : 'ok';
|
|
619
|
+
}
|
|
620
|
+
// { text, color } for the rate-limit cost slot, or null when Claude Code sent
|
|
621
|
+
// no rate_limits payload (older CC / non-subscription session).
|
|
622
|
+
function renderRateLimitSlot() {
|
|
623
|
+
const wins = getRateLimitWindows();
|
|
624
|
+
if (wins.length === 0) return null;
|
|
625
|
+
const now = Date.now();
|
|
626
|
+
let worst = 'ok';
|
|
627
|
+
const parts = [];
|
|
628
|
+
for (const w of wins) {
|
|
629
|
+
const st = rlWindowStatus(w, now);
|
|
630
|
+
if (st === 'over') worst = 'over';
|
|
631
|
+
else if (st === 'warn' && worst !== 'over') worst = 'warn';
|
|
632
|
+
const mark = st === 'over' ? '!' : st === 'warn' ? '⚠' : '';
|
|
633
|
+
parts.push(w.label + ' ' + Math.round(w.used) + '%' + mark);
|
|
634
|
+
}
|
|
635
|
+
const color = worst === 'over' ? c.brightRed : worst === 'warn' ? c.brightYellow : c.brightGreen;
|
|
636
|
+
return { text: parts.join(' · '), color: color };
|
|
637
|
+
}
|
|
638
|
+
|
|
519
639
|
// Read package version from the first package.json we find. The fallback
|
|
520
640
|
// (`BAKED_CLI_VERSION`) is the version of @swarmdo/cli that generated THIS
|
|
521
641
|
// statusline.cjs at `swarmdo init` time — so even when every probe below
|
|
522
642
|
// misses, the displayed version is meaningful (matches what the user
|
|
523
643
|
// installed), not a stale hard-coded string.
|
|
524
644
|
function getPkgVersion() {
|
|
525
|
-
let ver = '1.58.
|
|
645
|
+
let ver = '1.58.9';
|
|
526
646
|
try {
|
|
527
647
|
const home = os.homedir();
|
|
528
648
|
const pkgPaths = [
|
|
@@ -636,8 +756,24 @@ function generateStatusline() {
|
|
|
636
756
|
const ctxColor = ctxInfo.usedPct >= 90 ? c.brightRed : ctxInfo.usedPct >= 70 ? c.brightYellow : c.brightGreen;
|
|
637
757
|
header += ' ' + c.dim + '│' + c.reset + ' ' + ctxColor + '● ' + ctxInfo.usedPct + '% ctx' + c.reset;
|
|
638
758
|
}
|
|
639
|
-
if (seg('cost') &&
|
|
640
|
-
|
|
759
|
+
if (seg('cost') && COST_OPTS.mode !== 'off') {
|
|
760
|
+
const acct = readClaudeAccount();
|
|
761
|
+
let eff = COST_OPTS.mode;
|
|
762
|
+
if (eff === 'auto') eff = detectPlan(acct) === 'subscription' ? 'limits' : 'dollars';
|
|
763
|
+
let slotText = null;
|
|
764
|
+
let slotColor = c.brightYellow;
|
|
765
|
+
if (eff === 'limits') {
|
|
766
|
+
const rl = renderRateLimitSlot();
|
|
767
|
+
if (rl) { slotText = rl.text; slotColor = rl.color; }
|
|
768
|
+
else if (costInfo && costInfo.costUsd > 0) { slotText = CONFIG.costSymbol + costInfo.costUsd.toFixed(2); } // no payload → $ fallback
|
|
769
|
+
} else if (costInfo && costInfo.costUsd > 0) {
|
|
770
|
+
slotText = CONFIG.costSymbol + costInfo.costUsd.toFixed(2);
|
|
771
|
+
}
|
|
772
|
+
if (slotText) {
|
|
773
|
+
let prefix = '';
|
|
774
|
+
if (COST_OPTS.showAccount) { const lbl = accountLabel(acct); if (lbl) prefix = c.dim + lbl + ' · ' + c.reset; }
|
|
775
|
+
header += ' ' + c.dim + '│' + c.reset + ' ' + prefix + slotColor + slotText + c.reset;
|
|
776
|
+
}
|
|
641
777
|
}
|
|
642
778
|
if (header) lines.push(header);
|
|
643
779
|
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://swarmdo.com)
|
|
4
4
|
|
|
5
|
-
[](https://img.shields.io/badge/npx%20swarmdo-v1.58.15-cb3837?style=for-the-badge&logo=npm&logoColor=white)](https://github.com/SwarmDo/swarmdo/releases)
|
|
6
6
|
[](https://github.com/SwarmDo/swarmdo/blob/main/LICENSE)
|
|
7
7
|
[](https://swarmdo.com)
|
|
8
8
|
[](https://github.com/SwarmDo/swarmdo)
|
|
@@ -476,7 +476,7 @@ Four docs for four audiences:
|
|
|
476
476
|
| **[Status](docs/STATUS.md)** | See what currently works — capability counts, test baselines, recent fixes, what's next. The *is-it-ready* doc. |
|
|
477
477
|
| **[User Guide](docs/USERGUIDE.md)** | Daily reference — every command, every config flag, every plugin. The *how-do-I* doc. |
|
|
478
478
|
| **[MetaHarness Guide](docs/metaharness-user-guide.md)** | How to grade your agent setup, scan tool configs for security, detect changes between runs, and eject a project into a standalone agent toolkit. The *audit-my-setup* doc. |
|
|
479
|
-
| **[Benchmarks](https://gist.the upstream project (see NOTICE))** |
|
|
479
|
+
| **[Benchmarks](https://gist.the upstream project (see NOTICE))** | SOTA matrix vs LangGraph / AutoGen / CrewAI on darwin-arm64 + linux-x64. swarmdo wins cold start, single turn, RSS by 1.3×–1953×. The *is-it-fast* doc. |
|
|
480
480
|
| **[Verification](verification.md)** | Cryptographically prove your installed bytes match the signed witness — `swarmdo verify`. The *trust-but-verify* doc. |
|
|
481
481
|
| **[Team Gateway Checklist](docs/TEAM-GATEWAY-CHECKLIST.md)** | Before-merge gates, dual-mode handoff, memory namespace sharing, and witness manifest entry per merge. The *safer-team-workflows* doc. |
|
|
482
482
|
|
|
@@ -493,6 +493,7 @@ User Guide section index:
|
|
|
493
493
|
| [Security](docs/USERGUIDE.md#%EF%B8%8F-security) | AIDefence, CVE remediation, validation |
|
|
494
494
|
| [Ecosystem](docs/USERGUIDE.md#-ecosystem--integrations) | SwarmVector, agentic-flow, Flow Nexus |
|
|
495
495
|
| [Configuration](docs/USERGUIDE.md#%EF%B8%8F-configuration--reference) | Environment variables, config schema |
|
|
496
|
+
| [Slash Commands & Statusline](docs/USERGUIDE.md#-slash-command-reference) | Every `/sDo:` command + `/sdo-` skill, and every statusline item ([live on swarmdo.com](https://swarmdo.com/#commands)) |
|
|
496
497
|
| [Plugin Marketplace](https://upstream.github.io/swarmdo) | Browse and install plugins |
|
|
497
498
|
|
|
498
499
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swarmdo",
|
|
3
|
-
"version": "1.58.
|
|
3
|
+
"version": "1.58.15",
|
|
4
4
|
"description": "Swarmdo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent-types
|
|
3
|
-
description: Complete guide to all 87 available agent types in Swarmdo
|
|
3
|
+
description: Complete guide to all 87 available agent types in Swarmdo
|
|
4
4
|
type: reference
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Agent Types Reference
|
|
8
8
|
|
|
9
|
-
Complete guide to all 87 available agent types in Swarmdo
|
|
9
|
+
Complete guide to all 87 available agent types in Swarmdo.
|
|
10
10
|
|
|
11
11
|
## Core Development (5)
|
|
12
12
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Scan this project's security and refresh the statusline Security segment
|
|
3
|
+
argument-hint: "[scan|full|cve|audit|report] (default: scan)"
|
|
4
|
+
allowed-tools: Bash(npx swarmdo security:*), Bash(node v3/@swarmdo/cli/bin/cli.js security:*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /security — scan security posture + refresh the statusline
|
|
8
|
+
|
|
9
|
+
Run the swarmdo security scanner and refresh the `Security` element of the
|
|
10
|
+
statusline. The statusline reads the cached result from
|
|
11
|
+
`.swarmdo/security/last-scan.json`; a scan rewrites it with a fresh `scannedAt`
|
|
12
|
+
plus current counts, so the `Security ●…` indicator stops showing `STALE` and
|
|
13
|
+
reflects reality (`●CLEAN` when clean, `●VULN` when critical/high are present).
|
|
14
|
+
|
|
15
|
+
Resolve the swarmdo CLI as `npx swarmdo` if installed, else
|
|
16
|
+
`node v3/@swarmdo/cli/bin/cli.js` (this repo). Call it `$CLI` below.
|
|
17
|
+
|
|
18
|
+
## Input
|
|
19
|
+
|
|
20
|
+
`$ARGUMENTS`
|
|
21
|
+
|
|
22
|
+
## Behavior
|
|
23
|
+
|
|
24
|
+
Pick the mode from the first argument (default `scan` when empty):
|
|
25
|
+
|
|
26
|
+
- `scan` (default) — run `$CLI security scan` (standard depth).
|
|
27
|
+
- `full` — run `$CLI security scan --depth full` for the complete finding list.
|
|
28
|
+
- `cve` — run `$CLI security cve` (dependency-CVE audit only).
|
|
29
|
+
- `audit` — run `$CLI security audit`.
|
|
30
|
+
- `report` — run `$CLI security report` (summarize the last scan, no re-scan).
|
|
31
|
+
|
|
32
|
+
Then:
|
|
33
|
+
|
|
34
|
+
1. Report the summary counts — critical / high / medium / total — from the
|
|
35
|
+
scanner output.
|
|
36
|
+
2. Confirm the statusline `Security` element refreshed: it now shows `●CLEAN`
|
|
37
|
+
(no critical/high) or `●VULN` (critical/high present) and no longer `●STALE`.
|
|
38
|
+
The change lands on the next statusline render — no regeneration needed.
|
|
39
|
+
3. If any critical or high findings exist, list the top few (severity, package,
|
|
40
|
+
short description) and point at `$CLI security scan --depth full` for the rest.
|
|
41
|
+
|
|
42
|
+
`.swarmdo/security/last-scan.json` is per-project, so run this in each project
|
|
43
|
+
whose statusline you want current. This command only scans and reports — it does
|
|
44
|
+
not modify code or dependencies.
|