Skip to content

Commit 99931bf

Browse files
0xbeekeeperclaude
andcommitted
fix: checkup report i18n, Windows cmd, headless detection, dimension coverage
- Auto-detect Chinese from analysis content and apply zh locale on load (#12) - Fix Windows `start` command needing empty title to avoid cmd popup (#11, #14) - Skip browser open for headless/bot environments (Qclaw, OpenClaw, CI) (#14) - Increase process exit timeout from 2s to 3s for slower systems (#11) - Mark all 7 data collection checks as [REQUIRED] in SKILL.md (#10) - Add pre-Step-4 validation checklist to ensure all dimensions have data (#10) - Make Step 5 terminal summary mandatory with explicit instructions (#11) - Add dimension→check mapping so models understand the full pipeline (#10, #13) Closes #10, Closes #11, Closes #12, Closes #13, Closes #14 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent b982ee4 commit 99931bf

2 files changed

Lines changed: 51 additions & 15 deletions

File tree

skills/agentguard/SKILL.md

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -610,18 +610,20 @@ Run a comprehensive agent health checkup across 6 security dimensions. Generates
610610

611611
### Step 1: Data Collection
612612

613+
**IMPORTANT: You MUST run ALL 7 checks below — not just the skill scan. The checkup covers 5 security dimensions, not just code scanning. Do NOT skip checks 2–7.**
614+
613615
Run these checks in parallel where possible. These are **universal agent security checks** — they apply to any Claude Code or OpenClaw environment, regardless of whether AgentGuard is installed.
614616

615-
1. **Discover & scan installed skills**: Glob `~/.claude/skills/*/SKILL.md` and `~/.openclaw/skills/*/SKILL.md`. For each discovered skill, **run `/agentguard scan <skill_path>`** using the scan subcommand logic (24 detection rules). Collect the scan results (risk level, findings count, risk tags) for each skill.
616-
2. **Credential file permissions**: `stat` on `~/.ssh/`, `~/.gnupg/`, and if OpenClaw: `stat` on `$OC/openclaw.json`, `$OC/devices/paired.json`
617-
3. **Sensitive credential scan (DLP)**: Use Grep to scan workspace memory/logs directories for leaked secrets:
617+
1. **[REQUIRED] Discover & scan installed skills** (→ feeds Dimension 1: Code Safety): Glob `~/.claude/skills/*/SKILL.md` and `~/.openclaw/skills/*/SKILL.md`. For each discovered skill, **run `/agentguard scan <skill_path>`** using the scan subcommand logic (24 detection rules). Collect the scan results (risk level, findings count, risk tags) for each skill.
618+
2. **[REQUIRED] Credential file permissions** (→ feeds Dimension 2: Credential Safety): `stat -f '%Lp' <path> 2>/dev/null || stat -c '%a' <path> 2>/dev/null` on `~/.ssh/`, `~/.gnupg/`, and if OpenClaw: on `$OC/openclaw.json`, `$OC/devices/paired.json`
619+
3. **[REQUIRED] Sensitive credential scan / DLP** (→ feeds Dimension 2: Credential Safety): Use Grep to scan workspace memory/logs directories for leaked secrets:
618620
- Private keys: `0x[a-fA-F0-9]{64}`, `-----BEGIN.*PRIVATE KEY-----`
619621
- Mnemonics: sequences of 12+ BIP-39 words, `seed_phrase`, `mnemonic`
620622
- API keys/tokens: `AKIA[0-9A-Z]{16}`, `gh[pousr]_[A-Za-z0-9_]{36}`, plaintext passwords
621-
4. **Network exposure**: Run `lsof -i -P -n 2>/dev/null | grep LISTEN` or `ss -tlnp 2>/dev/null` to check for dangerous open ports (Redis 6379, Docker API 2375, MySQL 3306, MongoDB 27017 on 0.0.0.0)
622-
5. **Scheduled tasks audit**: Check `crontab -l 2>/dev/null` for suspicious entries containing `curl|bash`, `wget|sh`, or accessing `~/.ssh/`
623-
6. **Environment variable exposure**: Run `env` and check for sensitive variable names (`PRIVATE_KEY`, `MNEMONIC`, `SECRET`, `PASSWORD`) — detect presence only, mask values
624-
7. **Runtime protection check**: Check if security hooks exist in `~/.claude/settings.json`, check for audit logs at `~/.agentguard/audit.jsonl`
623+
4. **[REQUIRED] Network exposure** (→ feeds Dimension 3: Network & System): Run `lsof -i -P -n 2>/dev/null | grep LISTEN` or `ss -tlnp 2>/dev/null` to check for dangerous open ports (Redis 6379, Docker API 2375, MySQL 3306, MongoDB 27017 on 0.0.0.0)
624+
5. **[REQUIRED] Scheduled tasks audit** (→ feeds Dimension 3: Network & System): Check `crontab -l 2>/dev/null` for suspicious entries containing `curl|bash`, `wget|sh`, or accessing `~/.ssh/`
625+
6. **[REQUIRED] Environment variable exposure** (→ feeds Dimension 3: Network & System): Run `env` and check for sensitive variable names (`PRIVATE_KEY`, `MNEMONIC`, `SECRET`, `PASSWORD`) — detect presence only, mask values
626+
7. **[REQUIRED] Runtime protection check** (→ feeds Dimension 4: Runtime Protection): Check if security hooks exist in `~/.claude/settings.json` or `~/.openclaw/openclaw.json`, check for audit logs at `~/.agentguard/audit.jsonl`
625627

626628
### Step 2: Score Calculation
627629

@@ -709,6 +711,18 @@ This report goes into the `"analysis"` field of the JSON output.
709711

710712
Also generate a list of actionable recommendations as `{ "severity": "...", "text": "..." }` objects for the structured view.
711713

714+
### Pre-Step-4 Validation
715+
716+
**Before assembling the JSON, verify you have collected data for ALL 5 dimensions:**
717+
718+
- [ ] `code_safety` — from Step 1 check 1 (skill scanning)
719+
- [ ] `credential_safety` — from Step 1 checks 2 + 3 (permissions + DLP)
720+
- [ ] `network_exposure` — from Step 1 checks 4 + 5 + 6 (ports + cron + env vars)
721+
- [ ] `runtime_protection` — from Step 1 check 7 (hooks + audit log)
722+
- [ ] `web3_safety` — from Step 2 (only if Web3 detected, otherwise `{ "score": null, "na": true }`)
723+
724+
**If any dimension is missing data, go back and run the missing checks. Do NOT submit a report with only code_safety filled in.**
725+
712726
### Step 4: Generate Report
713727

714728
Assemble the results into a JSON object and pipe it to the report generator:
@@ -741,9 +755,9 @@ cd <skill_directory> && echo '<json>' | node scripts/checkup-report.js
741755

742756
The script outputs the HTML file path to stdout (e.g. `/tmp/agentguard-checkup-1234567890.html`). Capture this path — you will need it for delivery in Step 6.
743757

744-
### Step 5: Terminal Summary
758+
### Step 5: Terminal Summary (REQUIRED)
745759

746-
After the report generates, output a brief summary in the terminal:
760+
**You MUST output this summary after the report generates.** This is the primary output the user sees. Do NOT skip this step — always show the score, dimension table, and report path:
747761

748762
```
749763
## 🦞 GoPlus AgentGuard Health Checkup

skills/agentguard/scripts/checkup-report.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,7 +1036,7 @@ body{background:#0a0e14;color:#dfe2eb;font-family:'Inter',sans-serif}
10361036
i18n.zh.quote=quotes_zh['${tier.grade}']||quotes_zh.B;
10371037
i18n.en.quote='"${tier.quote.replace(/'/g,"\\'")}\"';
10381038
1039-
let curLang='en';
1039+
let curLang=(${JSON.stringify(analysis||'')}).match(/[\u4e00-\u9fff]/) ? 'zh' : 'en';
10401040
window.toggleLang=function(){
10411041
curLang=curLang==='en'?'zh':'en';
10421042
document.getElementById('langLabel').textContent=curLang==='en'?'中文':'EN';
@@ -1054,6 +1054,22 @@ body{background:#0a0e14;color:#dfe2eb;font-family:'Inter',sans-serif}
10541054
});
10551055
};
10561056
1057+
// Apply initial language on load (auto-detect Chinese from analysis content)
1058+
if(curLang==='zh'){
1059+
document.getElementById('langLabel').textContent='EN';
1060+
document.querySelectorAll('[data-i18n]').forEach(el=>{
1061+
const key=el.getAttribute('data-i18n');
1062+
if(key==='findings_range'){
1063+
const range=el.getAttribute('data-range'),total=el.getAttribute('data-total');
1064+
el.textContent='发现 — '+range+' / 共 '+total;
1065+
} else if(i18n.zh[key]!=null)el.textContent=i18n.zh[key];
1066+
});
1067+
document.querySelectorAll('.finding-dim,.finding-text,.clean-dims,.rec-text').forEach(el=>{
1068+
const t=el.getAttribute('data-zh');
1069+
if(t)el.textContent=t;
1070+
});
1071+
}
1072+
10571073
// Dimension data for share card (must be before shareReport)
10581074
const _dims=${JSON.stringify(Object.fromEntries(Object.entries(DIM_META).map(([k])=>[k,dimensions[k]||{score:null,na:false}])))};
10591075
@@ -1336,9 +1352,15 @@ body{background:#0a0e14;color:#dfe2eb;font-family:'Inter',sans-serif}
13361352
writeFileSync(outPath, html, 'utf8');
13371353
console.log(outPath);
13381354

1339-
const cmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
1340-
exec(`${cmd} "${outPath}"`, (err) => {
1341-
if (err) process.stderr.write(`Could not open browser: ${err.message}\n`);
1342-
});
1343-
setTimeout(() => process.exit(0), 2000);
1355+
// Skip browser open for headless/bot environments (Qclaw, OpenClaw, CI)
1356+
const isHeadless = process.env.OPENCLAW_STATE_DIR || process.env.QCLAW || process.env.CI || !process.stdout.isTTY;
1357+
if (!isHeadless) {
1358+
const cmd = process.platform === 'darwin' ? 'open'
1359+
: process.platform === 'win32' ? 'start ""'
1360+
: 'xdg-open';
1361+
exec(`${cmd} "${outPath}"`, (err) => {
1362+
if (err) process.stderr.write(`Could not open browser: ${err.message}\n`);
1363+
});
1364+
}
1365+
setTimeout(() => process.exit(0), 3000);
13441366
}

0 commit comments

Comments
 (0)