Skip to content

Commit 348610d

Browse files
authored
(feat) Add Cursor Marketplace plugin form (#119)
* feat(cursor): add Marketplace plugin form Ships .cursor-plugin/plugin.json + cursor/plugin-hooks.json so the repo is installable from the Cursor Marketplace, alongside the existing install-cursor.sh flow. The plugin form uses a relative ./scripts/cursor-on-event.sh path (resolved from the plugin root) instead of $HOME/.local/share/..., which let the existing bootstrap script stay unchanged. Adds commands/dash0-configure.md to replace the installer's interactive prompt: end users run /dash0-configure inside Cursor to write the OTLP URL + token to ~/.cursor/dash0-agent-plugin.local.md. release.sh now bumps .cursor-plugin/plugin.json alongside the others, and cursor/README.md documents both install paths. * build: resolve installer version from GitHub at runtime install-cursor.sh no longer carries a hardcoded VERSION. It queries the GitHub API for the latest release on each run, with DASH0_VERSION as an override for pinning. Removes the failure mode where a release that skipped scripts/release.sh would leave the installer pointing at the previous tag. release.sh and cursor/README.md updated to reflect that install-cursor.sh is no longer part of the version-bump set. * fix(cursor): expose configure step as a skill, not a command Cursor's user-invocable unit is a skill (SKILL.md with name + description frontmatter), surfaced to the agent semantically. The original commands/ path was a Claude Code shape that Cursor's plugin loader did not pick up during local sideload testing. Replaces commands/dash0-configure.md with skills/dash0-configure/SKILL.md and updates the manifest accordingly. Claude Code's commands/open-session.md and .claude-plugin/plugin.json are unchanged. * docs: split runtime READMEs by audience Root README is now a hub — it pitches the idea (connect coding agents to Dash0 for deep insight into AI usage) and points at the per-runtime docs. Claude Code docs move to .claude-plugin/README.md (unchanged content, just relocated). New .cursor-plugin/README.md holds end-user-facing Cursor docs: install via Marketplace or shell installer, configure via the dash0-configure skill, verify, uninstall. cursor/README.md becomes the developer reference (build, sideload local changes, cut releases, capture-mode fixtures), with a pointer to the user-facing README. Drops the stale cursor-source-handoff-brief.md — the research it captured has been folded into the integration. * Point consistency check to claude readme * build: add cursor plugin-template validate script Copied verbatim from cursor/plugin-template@main: scripts/validate-template.mjs Required for Cursor Marketplace submission. The script expects a multi-plugin .cursor-plugin/marketplace.json layout — since this repo is a single plugin, the validator early-returns "Validation passed" without actually checking the manifest. Present-in-repo is what the submission process appears to need; real validation would require either a marketplace-style restructure or a single-plugin validator.
1 parent a58add1 commit 348610d

12 files changed

Lines changed: 963 additions & 517 deletions

File tree

.claude-plugin/README.md

Lines changed: 363 additions & 0 deletions
Large diffs are not rendered by default.

.cursor-plugin/README.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Dash0 Agent Plugin — Cursor
2+
3+
Cursor plugin that emits agent activity as OpenTelemetry spans to your Dash0 endpoint — prompts and responses, tool calls, MCP calls, and sub-agent activity, with shared trace context across each turn.
4+
5+
## Installation
6+
7+
Two install paths. Both end up with the same on-device layout (`cursor-on-event` binary + bootstrap script + config file + hooks registration).
8+
9+
### Cursor Marketplace (recommended)
10+
11+
1. Install `dash0-agent-plugin` from the Cursor Marketplace. Cursor reads `.cursor-plugin/plugin.json` and registers the hooks declared in `cursor/plugin-hooks.json`.
12+
2. Ask the agent to *configure Dash0* — the `dash0-configure` skill walks you through writing `~/.cursor/dash0-agent-plugin.local.md` with your OTLP URL, auth token, and optional dataset / team / agent name.
13+
3. Quit and relaunch Cursor (Cmd+Q on macOS) — Cursor reads `hooks.json` only at startup.
14+
15+
The plugin ships no binary. The bootstrap script downloads `cursor-on-event-<os>-<arch>` from [GitHub Releases](https://github.com/dash0hq/dash0-agent-plugin/releases) on first hook fire and verifies the checksum.
16+
17+
### Shell installer
18+
19+
Non-interactive single-command install. Useful for CI, provisioning, or skipping the configure skill.
20+
21+
```bash
22+
curl -fsSL https://raw.githubusercontent.com/dash0hq/dash0-agent-plugin/main/install-cursor.sh | bash
23+
```
24+
25+
Pre-supply credentials via env vars to skip the prompts:
26+
27+
```bash
28+
DASH0_OTLP_URL=https://ingress.<region>.aws.dash0.com \
29+
DASH0_AUTH_TOKEN=<your-token> \
30+
DASH0_DATASET=default \
31+
curl -fsSL https://raw.githubusercontent.com/dash0hq/dash0-agent-plugin/main/install-cursor.sh | bash
32+
```
33+
34+
Optional env vars: `DASH0_DATASET`, `DASH0_AGENT_NAME`, `DASH0_TEAM_NAME`, `DASH0_VERSION` (pin a specific release; default: latest GitHub release).
35+
36+
After install, **quit and relaunch Cursor.**
37+
38+
## Configuration
39+
40+
The config file lives at `~/.cursor/dash0-agent-plugin.local.md` (chmod 600 — it holds your token in cleartext). YAML frontmatter:
41+
42+
```yaml
43+
---
44+
otlp_url: "https://ingress.<region>.aws.dash0.com"
45+
auth_token: "<your-dash0-auth-token>"
46+
dataset: "default" # optional
47+
agent_name: "cursor" # optional — used as service.name
48+
team_name: "<your-team>" # optional — tagged as dash0.team.name on every span
49+
omit_io: false # set true to redact prompts and tool input/output
50+
---
51+
```
52+
53+
To reconfigure later, re-run the `dash0-configure` skill in Cursor, or edit the file directly. Config changes take effect on the next hook fire — no restart needed. (Restart is only needed if `hooks.json` itself changes, since Cursor reads it at startup.)
54+
55+
## Verify
56+
57+
Send a prompt that uses a tool. In Dash0 you should see one trace per turn with:
58+
59+
- one `chat default` span at turn end carrying `gen_ai.usage.input_tokens`, `output_tokens`, and `cache_read.input_tokens`
60+
- one `execute_tool <Name>` span per tool call, with `parentSpanId` pointing at the chat span
61+
- the same `traceId` on every span in the turn
62+
63+
If nothing arrives, set `debug: true` and `debug_file: /tmp/dash0-cursor-debug.log` in the config. Every emitted span is also appended there as a `[dash0:trace] {...}` line:
64+
65+
```bash
66+
tail -F /tmp/dash0-cursor-debug.log
67+
```
68+
69+
## Uninstall
70+
71+
```bash
72+
rm -rf ~/.local/state/dash0-agent-plugin \
73+
~/.local/share/dash0-agent-plugin \
74+
~/.cursor/dash0-agent-plugin.local.md
75+
```
76+
77+
If you installed via `install-cursor.sh`, also remove `~/.cursor/hooks.json`. If you installed via the Marketplace, uninstall the plugin from Cursor's plugin UI.

.cursor-plugin/plugin.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "dash0-agent-plugin",
3+
"version": "0.1.10",
4+
"description": "OpenTelemetry observability for Cursor sessions. Captures prompts, tool calls, MCP calls, and subagent activity as OTel traces.",
5+
"author": {
6+
"name": "Dash0"
7+
},
8+
"homepage": "https://dash0.com",
9+
"repository": "https://github.com/dash0hq/dash0-agent-plugin",
10+
"license": "Apache-2.0",
11+
"keywords": ["observability", "tracing", "opentelemetry", "dash0", "otel"],
12+
"hooks": "cursor/plugin-hooks.json",
13+
"skills": "./skills/"
14+
}

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ jobs:
305305
DECLARED_KEYS=$(jq -r '.userConfig // {} | keys[]' .claude-plugin/plugin.json | sort -u)
306306
MISSING=""
307307
for key in $DECLARED_KEYS; do
308-
if ! grep -qF "| \`$key\`" README.md; then
308+
if ! grep -qF "| \`$key\`" .claude-plugin/README.md; then
309309
MISSING="$MISSING $key"
310310
fi
311311
done

0 commit comments

Comments
 (0)