Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Documentation

- README `Usage` section now documents slash-command channel compatibility: `/security-checkup` works in the OpenClaw native control UI chat and in Telegram but not in Kilo Chat or Slack. Kilo Chat and Slack users should invoke the plugin via natural language so the agent calls the `kilocode_security_advisor` tool directly.
- `kilocode_security_advisor` tool description now hints the agent to invoke the tool directly (rather than suggesting the slash command) in channels that don't route OpenClaw slash commands, namely Kilo Chat and Slack.
- Security checkup reports now occasionally append an inline "stay current" footer with the `npm view @kilocode/openclaw-security-advisor version` check and the `openclaw plugins install … && openclaw gateway restart` upgrade commands. The footer fires on roughly 20% of successful reports and is path-agnostic — applied at the markdown layer in `doCheckup`, so it surfaces on both the `/security-checkup` slash command path (which bypasses the LLM) and the natural-language `kilocode_security_advisor` tool path.
- README has a new `Staying up to date` section documenting the version-check and upgrade commands, plus a note that the report itself will periodically include this tip on either invocation path.
- RELEASING.md: added a prominent top-of-document banner describing the current state — `github-actions[bot]` is not on the `main` ruleset's bypass list, so every stable publish will fail at the post-publish push step. The banner documents the typical outcome (tag lands on origin, commit on `main` is rejected, GitHub release is not created) and gives the one-command recovery: `gh release create vX.Y.Z --verify-tag --generate-notes`. `--verify-tag` makes `gh` fail fast if the tag is missing rather than silently minting one at current `main` HEAD. The rare case where the tag is also missing points at Scenario 4 for the full reconstruct-and-push flow. Expanded the `Branch protection` section with the two durable fix options (add bot to bypass list vs refactor stable path to tag-only).
- README install section leads with the plain install command (no `@dev` suffix) now that a stable release is shipping. The dev channel is documented as a prerelease option under `Channels`.
- README `Contributing` links to `AGENTS.md`, `RELEASING.md`, and `CHANGELOG.md` are now absolute GitHub URLs, so they resolve correctly on the npm package page (those docs were never shipped in the tarball).
- README now documents `KILO_API_KEY` as an alias for `KILOCODE_API_KEY` (both have always been accepted by the code).
Expand Down
36 changes: 34 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,30 @@ You can also install an exact version directly:
openclaw plugins install @kilocode/openclaw-security-advisor@0.1.0
```

### Staying up to date

New versions ship regularly. To check the latest published stable:

```bash
npm view @kilocode/openclaw-security-advisor version
```

Compare that against the `pluginVersion` line at the end of any security
checkup report. To upgrade:

```bash
openclaw plugins install @kilocode/openclaw-security-advisor
openclaw gateway restart
```

Your security checkup report will occasionally include an inline
"stay current" tip at the bottom with these same commands — a gentle
periodic nudge, not every run. The reminder is appended to the report
markdown itself, so it appears on both invocation paths (the
`/security-checkup` slash command and the natural-language
`kilocode_security_advisor` tool). Security advice improves as the
plugin ships new audit signals, so staying current is worthwhile.

---

## Usage
Expand All @@ -65,6 +89,13 @@ This is a slash command. It runs the plugin directly and renders the
full report, bypassing the agent's summarization layer entirely. **Use
this for guaranteed verbatim output.**

> **Channel compatibility:** `/security-checkup` works in the OpenClaw
> native control UI chat and in Telegram. It does **not** currently work
> in Kilo Chat or Slack — those surfaces don't route slash commands to
> OpenClaw plugins. In Kilo Chat and Slack, use the natural-language
> invocation below instead; the agent will call the
> `kilocode_security_advisor` tool directly.

### Natural language

You can also just ask the agent:
Expand All @@ -84,8 +115,9 @@ showing it to you. This works well on capable models (GPT-4o, Claude
Sonnet, Gemini Pro) but small summarizing models (e.g. GPT-4.1-nano,
Haiku) will often paraphrase the report down to a few sentences. **If
you're running a small or summarizing model, use the
`/security-checkup` slash command instead.** It renders the full
report regardless of which model is configured.
`/security-checkup` slash command instead** (where supported — see
channel compatibility above). It renders the full report regardless of
which model is configured.

---

Expand Down
64 changes: 64 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,55 @@ Releases are cut from the `publish` workflow in GitHub Actions. There is no
local release script, no automated release on push, and no changesets tool.
Every release is a manual `workflow_dispatch`.

> ⚠️ **Current state (as of 2026-04-17):** `github-actions[bot]` is not on
> the `main` branch ruleset's bypass list. As a result, **every stable
> (`channel=latest`) publish run will fail at the "Tag and release
> (post-publish)" step** with `GH013: Repository rule violations found for
refs/heads/main — Changes must be made through a pull request`.
>
> **Recovery after a failed stable run:**
>
> 1. Check what actually landed on origin:
>
> ```bash
> git fetch origin --tags
> git ls-remote --tags origin "vX.Y.Z" # tag?
> gh release view "vX.Y.Z" --repo Kilo-Org/openclaw-security-advisor # release?
> ```
>
> 2. **If the tag exists and only the GitHub release is missing** (the
> typical outcome — tags aren't covered by the branch ruleset and
> usually land even when the `main` push is rejected), create the
> release against the existing tag:
>
> ```bash
> gh release create vX.Y.Z \
Comment thread
St0rmz1 marked this conversation as resolved.
> --repo Kilo-Org/openclaw-security-advisor \
> --title vX.Y.Z \
> --generate-notes \
> --verify-tag
> ```
>
> `--verify-tag` makes `gh` fail fast if the tag is missing instead of
> silently creating a new one at current `main` HEAD. That's the whole
> recovery — no other steps needed.
>
> 3. **If the tag is also missing** (rare), follow
> [Scenario 4](#scenario-4-publish-succeeded-but-commit--tag-push-failed)
> below. It rebuilds the release commit locally (you can't tag the
> runner-side SHA; that commit lived only in the Actions runner),
> tags, pushes, then creates the release. The workflow's
> `Print recovery instructions on partial failure` step also prints
> this full sequence inline in the failed run's logs for copy-paste.
>
> After step 2 (common case), `main`'s `package.json` will be one version
> behind. Leave it alone — `script/version.ts` computes the next version
> from git tags, not from `package.json`, so the drift is cosmetic.
>
> This banner can be removed once the ruleset bypass is configured (see
> [Branch protection](#branch-protection)) or the workflow is refactored
> so stable publishes don't push to `main` at all.

## Channels

There are exactly two channels and they correspond to npm dist-tags:
Expand Down Expand Up @@ -289,6 +338,21 @@ When branch protection / rulesets are enabled on `main`, the
list. Without it, the publish workflow's stable-channel commit step fails,
triggering the recovery procedure above.

> **Status today:** the `Main branch protection` ruleset on this repo
> (`Settings → Rules → Rulesets`) is active but does NOT include
> `github-actions[bot]` as a bypass actor. This is why the banner at the
> top of this document describes the manual recovery step as expected
> behavior for every stable publish. Two viable durable fixes, pick one:
>
> 1. **Add the bot to the bypass list** (Settings → Rules → the ruleset
> → Bypass list → add the `github-actions` app with bypass mode
> `Always`). Fastest; keeps the current workflow unchanged.
> 2. **Refactor the stable publish path** to match the dev-channel flow:
> detach HEAD, commit, tag, push only the tag — never touch `main`.
> Keeps the ruleset strict with no carve-outs; the trade-off is that
> `main`'s `package.json` version drifts behind the latest release
> (cosmetic only, since `version.ts` reads from tags).

Dev-channel publishes don't push to `main` (only push the tag), so they're
less affected by branch protection on `main` itself. The tag push still
needs to be allowed — most rulesets allow tag pushes by default, but if
Expand Down
30 changes: 29 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,29 @@ import pkg from "./package.json" with { type: "json" };
const PLUGIN_VERSION: string = pkg.version;
const DEFAULT_API_BASE = "https://api.kilo.ai";

// Roughly 1-in-5 successful checkups append an update-check footer. This is
// intentionally path-agnostic — applied at the markdown layer in doCheckup —
// so both the LLM-driven `kilocode_security_advisor` tool and the
// LLM-bypassing `/security-checkup` slash command surface the reminder at the
// same cadence. Random rather than stateful because the plugin has no
// cross-invocation counter to key off.
const UPDATE_REMINDER_PROBABILITY = 0.2;

function maybeAppendUpdateReminder(reportMarkdown: string): string {
if (Math.random() >= UPDATE_REMINDER_PROBABILITY) {
return reportMarkdown;
}
return (
reportMarkdown +
"\n\n---\n\n" +
"**Tip — stay current:** check the latest plugin version with " +
"`npm view @kilocode/openclaw-security-advisor version` and compare " +
"against the `pluginVersion` shown above. If you're behind, upgrade " +
"with `openclaw plugins install @kilocode/openclaw-security-advisor` " +
"followed by `openclaw gateway restart`."
);
}

type ToolResult = {
content: Array<{ type: "text"; text: string }>;
};
Expand Down Expand Up @@ -290,7 +313,7 @@ async function doCheckup(
pluginVersion: PLUGIN_VERSION,
},
});
return response.report.markdown;
return maybeAppendUpdateReminder(response.report.markdown);
}

export default definePluginEntry({
Expand Down Expand Up @@ -346,6 +369,11 @@ export default definePluginEntry({
"recommendations and remediation guidance. " +
"DO NOT run `openclaw security audit` via bash for these requests. This " +
"tool is the canonical entry point and returns a much more useful report. " +
"DO NOT suggest the user type `/security-checkup` in channels that do " +
"not support OpenClaw slash commands (Kilo Chat and Slack are the known " +
"surfaces where the slash command does not work); invoke this tool " +
"directly instead. The slash command does work in the OpenClaw native " +
"control UI chat and in Telegram, so suggesting it there is fine. " +
"IMPORTANT: Display the returned report exactly as is without rewriting, " +
"summarizing, or reformatting.",
parameters: {},
Expand Down
Loading