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
14 changes: 13 additions & 1 deletion skills/ns-analyze-asset/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
---
name: ns-analyze-asset
description: >-
Analyzes an existing N|Solid diagnostic asset in N|Solid by asset ID or local asset path. Use when the user asks to inspect, review, summarize, or interpret an already-captured CPU profile, heap profile, heap sample, heap tracking file, or heap snapshot, including assets just produced by ns-generate-asset. Do not use to capture new profiles/snapshots.
Analyzes an existing N|Solid diagnostic asset in N|Solid by asset ID or local asset path. Use when the user asks to inspect, review, summarize, or interpret an already-captured CPU profile, heap profile, heap sample, heap tracking file, or heap snapshot, including assets just produced by ns-generate-asset. Also use when the user asks to restore a deleted diagnostic profile or snapshot. Do not use to capture new profiles/snapshots.
---

This skill reads assets through the N|Solid MCP server (`nsolid`) and bundled scripts. The scripts need the server's settings: `NSOLID_API_URL` and `NSOLID_API_TOKEN` in the environment, or `~/.agents/.nsolid-auth.json` with `apiUrl` and `token` (plus `tenant` when the token can use several tenants).

## Instructions

When the user asks to restore a deleted profile or snapshot, pick the tenant (step 1), then go straight to [Restoring a Deleted Asset](#restoring-a-deleted-asset) instead of steps 2–10. Every other request follows the steps below.

### 1. Pick the Tenant
- The N|Solid tools take a `tenant`. When the token can use one tenant it is the default; otherwise call `list_tenants` once and use the tenant the user names. Pass the same tenant to every call, and set `NSOLID_TENANT` for the scripts.

Expand Down Expand Up @@ -122,7 +124,17 @@ Rules:
node "<skill-dir>/fetch-nsolid-asset.cjs" <assetId> <appName>
```

## Restoring a Deleted Asset
Only when the user asks to bring back a deleted profile or snapshot. Never restore one in order to analyze it.
- `list_assets` with `status: "deleted"` (narrowed by `agentId` or `kind`) lists deleted assets. It returns one page (20 by default, `limit` up to 100), ordered by when files completed, not when they were deleted, so an asset missing from it is not proof that no restore is possible. Ask again with `limit: 100` and the narrowest `agentId` and `kind`. If it is still missing, tell the user that the MCP tool can't page further, and that they (or an API client they have already authenticated) can page `GET /v1/tenants/{tenant}/assets?status=deleted`, passing each response's `nextCursor` back as `cursor`, narrowed with the REST filters `agent` (not `agentId`) and `kind` as fits. Don't read credentials, build token-bearing requests yourself, or page the API without end. Never say the absence proves no restore is possible.
- `undoUntil` is the deadline; don't assume a fixed window. Only an asset whose `undoUntil` is still in the future can come back. Check it before offering a restore.
- `restore_asset` with the `assetId` needs the **Keeping files** permission (`nsolid:manage-assets`); without it the tool is missing.
- A file may have been deleted because of what it contains: a heap snapshot can hold secrets and personal data. Confirm with the user before restoring, unless they already explicitly asked to restore that asset.
- After `undoUntil` the API answers 410: the asset can't be restored. Say so; don't retry.
- Report the result as returned, `pinned` included: a pinned asset comes back unpinned when it would exceed the pinned budget, with at least a day before its file goes.

## Guardrails
- Never restore a deleted asset unless the user asked for it.
- Never analyze an asset that is not analyzed yet. Wait and ask again until the summary has real content, or say it isn't ready.
- Do not lie about findings. If the summary lacks detail, say so explicitly.
- Never read raw asset files or the HTML reports into context; download and render them only with the bundled `fetch-nsolid-asset.cjs` and `render-cpu-report.cjs`.
Expand Down
7 changes: 5 additions & 2 deletions skills/ns-analyze-event/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
---
name: ns-analyze-event
description: >-
Investigates an existing N|Solid event or N|Solid alert and correlates the relevant evidence from N|Solid. Use when the user provides or references an event or alert such as a blocked event loop, a process exit or crash, an uncaught exception, a new vulnerability, a new package behavior, a stack trace, or span data. Routes follow-up to CPU, memory, vulnerability, or tracing workflows when needed.
Investigates an existing N|Solid event or N|Solid alert and correlates the relevant evidence from N|Solid. Use when the user provides or references an event or alert such as a blocked event loop, a process exit or crash, an uncaught exception, a new vulnerability, a new package behavior, a stack trace, or span data. Also use when the user asks why an agent dropped, disconnected or reconnected, even without a specific event or alert. Routes follow-up to CPU, memory, vulnerability, or tracing workflows when needed.
---

This skill reads N|Solid data through the N|Solid MCP server (`nsolid`). The N|Solid tools take a `tenant`: when the token can use one tenant it is the default; otherwise call `list_tenants` once and use the tenant the event or user names.

**No event, just a drop or reconnect.** When the user asks why an app or process dropped, disconnected or reconnected without giving an event or alert, skip parsing: resolve the app or process they name with `find_agents` to get its actual `agentId` (ask only for the missing app or process when they named neither), then go straight to **Lifecycle** in step 2. Use the time window they gave for `list_events`, or say which recent window you used (such as `-1h`) when they gave none; `agent_sessions` takes no `from`/`to`.

### 1. Parse the Event
- Recognize the payload's shape before anything else:
- **An N|Solid alert notification** (a webhook body, or a Slack, Teams or PagerDuty message made from one): `event` (`firing`, `resolved`), `alert.rule`, `alert.severity`, `alert.summary`, `alert.group` (the `agentId` or `app`), `alert.value`, `alert.since`, `alert.fingerprint`, `alert.evidence`.
Expand All @@ -26,8 +28,9 @@ This skill reads N|Solid data through the N|Solid MCP server (`nsolid`). The N|S
- **New behavior** (a behavior alert: a package that newly runs programs, compiles code, uses the network, starts threads or touches files; a release regression; dependency drift):
- Call `list_behaviors` for the app. A regression's release comparison is in `compare_releases`; a new capability or drift in a dependency may be a supply-chain problem, so hand it to `ns-analyze-vulnerabilities`.
- **Lifecycle** (an exit, a disconnect, repeated restarts; console `agent-exit`):
- Call `list_events` with the same `app` or `agentId`, `types: ["exit", "lost", "disconnect"]` and `from`/`to` around the event.
- Call `list_events` with the same `app` or `agentId`, `types: ["exit", "lost", "disconnect", "connect"]` and `from`/`to` around the event (or the window chosen above).
- Call `list_ended_processes` with the `app`: how each process ended (an exit code and signal, an abort, or lost without a word), how long it lived, and its peaks. `get_agent` gives one process's exit error and stack.
- For drops and reconnects, `agent_sessions` with the `agentId`: its command-stream sessions, newest first (20, or `limit` up to 200), with connect and close times, the close reason, gateway, peer, host and N|Solid version. A session that closed and was followed by a new one is a reconnect; report the reason and gateway it shows. A closed session does not prove a crash: to learn how the process ended, inspect its `exit` or `lost` event or `list_ended_processes`, and do not treat a normal exit or a `lost` event alone as proof of a crash.
- For "how often", `event_histogram` with the `app` and `types: ["exit", "lost"]` counts them per bucket over a day or a month: one restart, or a crash loop.
- A lost process left no exit: look at its last minutes instead (`query_metric` for `rss` and `used_heap_size` with `agentIds: ["<agentId>"]`, up to its last report). Memory climbing to the end suggests the out-of-memory killer.
- Call `query_metric` with explicit metrics (`used_heap_size`, `rss`, `cpu_percent`) and `agentIds: ["<agentId>"]` before the event to spot resource spikes. Running out of memory shows as an abort (`SIGABRT`) with the heap at its limit.
Expand Down
1 change: 1 addition & 0 deletions skills/ns-analyze-release/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ When the user wants deploys recorded, or profiles of a bundled or minified app t
- `app` and `version` must be what the processes report: the app name (`NSOLID_APPNAME`, else `package.json`'s `name`) and `package.json`'s `version`.
- Add the steps to the workspace's CI configuration (GitHub Actions, GitLab CI, or the user's script) with the token as a secret and the API URL as a variable. Show the change and make it only with the user's approval.
- Afterwards, `list_sourcemaps` with the `app` shows the uploaded sets, and `list_releases` the marked deploys.
- `get_sourcemap_set` with a `setId` from `list_sourcemaps` describes that set, never with source contents: `maps` counts the whole set, and `entries` details at most 200 maps (generated path, size, original file count). `path` keeps the maps whose path contains that text: `mapsMatched` counts them all and `mapsOmitted` the ones left out of `entries`. To check that a bundle's map was uploaded, pass part of the bundle's path as `path`; a map missing from the first 200 entries is not proof that it wasn't uploaded. No MCP tool uploads maps: people upload them from CI or from a profile's page in the web UI. Deleting a set, which has no undo, is left to people in the web UI or API.

### 7. Present the Report
- `# Release Analysis — <app> <base> → <version>`
Expand Down
3 changes: 2 additions & 1 deletion skills/ns-configure-agents/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: ns-configure-agents
description: >-
Changes how N|Solid agents run, safely: tracing on or off, continuous CPU profiling, the metrics interval, the blocked-loop threshold, trace sampling, snapshot redaction, tags. Use when the user wants tracing turned on for an app, continuous profiling for a while, a different metrics interval, or asks why a process has a setting. Previews every change, prefers changes that expire, and explains where each running value came from.
Changes how N|Solid agents run, safely: tracing on or off, continuous CPU profiling, the metrics interval, the blocked-loop threshold, trace sampling, snapshot redaction, tags. Use when the user wants tracing turned on for an app, continuous profiling for a while, a different metrics interval, asks why a process has a setting, or asks for a named config's history: who changed it and what it held before. Previews every change, prefers changes that expire, and explains where each running value came from.
---

This skill works through the N|Solid MCP server (`nsolid`). The N|Solid tools take a `tenant`: when the token can use one tenant it is the default; otherwise call `list_tenants` once and use the tenant the user names. Changing configuration needs the `nsolid:dynamic-configuration` permission; without it the change tools are missing, and the skill can still explain and preview.
Expand All @@ -11,6 +11,7 @@ N|Solid keeps agents at **desired configs**: each targets processes by an expres
### 1. Understand What Runs Now
- `list_desired_configs`: the configs the tenant keeps, with their targets, settings and priority; ones with `expiresAt` are temporary overrides.
- `agent_config` with an `agentId`: what that process reports, what it should have and which config set each key, what is still to apply, and whether it has converged. Use it to answer "why does this process have that setting?"
- `desired_config_history` with a config's `name`: its 50 newest saves and deletes, each with the settings, target, priority, expiry, who made it and when. Deleted configs keep their history. Read it before changing or deleting a named config, to see who set it and what it held before. No tool restores an earlier version: to go back to one, make it a new change and preview and apply it as below.

### 2. Shape the Change
- Settings: `tracingEnabled`, `traceSampleRate` (0 to 1), `contCpuProfile` (continuous CPU profiling), `interval` (metrics, ms), `blockedLoopThreshold` (ms), `pauseMetrics`, `promiseTracking`, `redactSnapshots`, `assetsEnabled`, `tags`. Turning `contCpuProfile` on needs the tenant's continuous-profiling feature: where N|Solid has it off, the save is refused, and processes stay off whatever a config says.
Expand Down
7 changes: 4 additions & 3 deletions skills/ns-manage-alerts/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
name: ns-manage-alerts
description: >-
Defines, reviews, tunes and triages N|Solid alert rules and alerts. Use when the user wants to be alerted or paged on something (CPU, memory, event loop lag, latency, crashes or a crash loop, a process killed or lost, an app that stops reporting, blocked loops, new or known exploited vulnerabilities, a dependency's new behavior or a release regression), asks what alerts exist, which are firing or whether a rule is working, wants to acknowledge or silence an alert, switch a rule off, or wants a noisy rule fixed. Writes rules in N|Solid's expression language and checks what each would have caught before saving it.
Defines, reviews, tunes and triages N|Solid alert rules and alerts. Use when the user wants to be alerted or paged on something (CPU, memory, event loop lag, latency, crashes or a crash loop, a process killed or lost, an app that stops reporting, blocked loops, new or known exploited vulnerabilities, a dependency's new behavior or a release regression), asks what alerts exist, which are firing or whether a rule is working, wants to acknowledge or silence an alert or end a silence early, switch a rule off, or wants a noisy rule fixed. Writes rules in N|Solid's expression language and checks what each would have caught before saving it.
---

This skill works through the N|Solid MCP server (`nsolid`). The N|Solid tools take a `tenant`: when the token can use one tenant it is the default; otherwise call `list_tenants` once and use the tenant the user names. Saving rules and acknowledging or silencing alerts need the `nsolid:manage-alerts` permission; without it those tools are missing, and the skill can still review and draft.
This skill works through the N|Solid MCP server (`nsolid`). The N|Solid tools take a `tenant`: when the token can use one tenant it is the default; otherwise call `list_tenants` once and use the tenant the user names. Saving rules, acknowledging or silencing alerts and ending a silence need the `nsolid:manage-alerts` permission; without it those tools are missing, and the skill can still review and draft.

## Start a Newly Connected Service's Baseline

Expand Down Expand Up @@ -93,13 +93,14 @@ Before saving, show the user what the rule would have done:
- `get_alert` with the `fingerprint`: the event or value that fired it, the diagnostic its rule took (an `assetId`: read it with `profile_hotspots` or `heap_summary`), the continuous profiles kept from around it, its history and its notifications.
- Hand the investigation to the skill that fits: `ns-cpu-spike-analysis`, `ns-memory-spike-analysis`, `ns-analyze-event`, `ns-analyze-vulnerabilities` or `ns-analyze-behaviors`.
- `ack_alert` marks it acknowledged until it fires again; `silence_alert` with `minutes` stops its notifications for a while (it still changes state). Do either only when the user asks.
- `unsilence_alert` ends a silence early, only when the user asks. Read `get_alert` first for who silenced it (`silencedBy`) and until when (`silencedUntil`): none, or a time already past, means there is no silence to end, so say so instead. If `get_alert` is refused, say the silence's details are unavailable, and still get the same go-ahead. Confirm before ending it unless the user already explicitly asked to end that alert's silence. Ending a silence sends no notification and keeps the alert's state; its next firing or resolution may notify the rule's enabled channels again, PagerDuty included: tell the user.

## Present the Result
- For a new or changed rule: the rule as saved, what it would have caught (step 3), and where it notifies.
- For triage: what is firing, since when, what the evidence shows, and the next step.

## Guardrails
- Never save, change, switch off, delete, acknowledge or silence without the user's say-so; show the rule first.
- Never save, change, switch off, delete, acknowledge, silence or end a silence without the user's say-so. Show the rule first when creating or changing one; ending a silence the user explicitly asked to end needs no rule shown and no second confirmation.
- Never add `diagnose: "snapshot"` unasked: it pauses the application.
- Do not invent channels: use only names `list_alert_channels` returned.
- A rule on blocked loops shorter than the agents report makes N|Solid lower the `blockedLoopThreshold` of the processes in its scope to match (of every process, when the scope is on packages); mention it when saving one.
Loading