Commit Graph

22 Commits

Author SHA1 Message Date
Evan Purkhiser 89c55f0d3d ci(installer): publish @sentry/ai to npm via craft (#185)
Add the Craft release pipeline so packages/installer can be published to
npm as @sentry/ai.

- .craft.yml configures a single npm target (public scoped access) with a
  tarball-name guard. There is deliberately no github target, so a release
  creates no git tags and no GitHub releases -- nothing repo-wide implying
  the skills/plugins are versioned by it.
- The release branch is scoped to `release-installer/<version>` via
  releaseBranchPrefix, so it reads as a package release. craft creates it
  during prepare and deletes it after publish, so it is transient.
- changelogPolicy is `simple` (matching sentry-javascript) and the
  changelog lives with the package at packages/installer/CHANGELOG.md. The
  entry is written by hand before releasing; `auto` would sweep this repo's
  skill-drift and plugin churn into the installer changelog.
- release.yml runs `craft prepare` via the Sentry release bot App token.
  It must be an App token rather than GITHUB_TOKEN so the pushed release
  branch triggers release-build.yml, which packs the tarball and uploads
  it as the SHA-named artifact Craft's GitHub provider expects.
- The package gains `files: ["dist", "CHANGELOG.md"]`, publishConfig.access
  public, and an explicit LICENSE so the published tarball is complete
  without relying on pnpm copying the root LICENSE.

Publishing runs from getsentry/publish after a team lead approves the
release issue; this repo only prepares the release and builds the artifact.
2026-06-17 15:14:05 -04:00
Evan Purkhiser d86aedebf5 feat(installer): add CLI to install the Sentry plugin across AI agents (#180)
Add a pnpm workspace with a `packages/installer` package (`@sentry/ai`)
that provides a single CLI for installing the Sentry plugin into any
supported AI coding assistant: Claude Code, Codex, Cursor, and Grok.

The CLI (built on citty) exposes an `install` subcommand. By default it
shows an interactive selector pre-selecting the detected agents;
`--no-interactive`/`--yes` skips the prompt and installs every detected
agent — used for CI and unattended runs.

Each agent is a self-contained harness implementing a common strategy
interface — detect, isInstalled, canInstall, install — so adding a new
agent is just another module. System access (shell, fs, platform,
homedir) is injected through a SystemDeps seam, keeping every harness
unit-testable without side effects.

Behavior:
- Already-installed agents update in place rather than erroring or
  no-opping: Cursor pulls, Grok/Claude use their update commands, Codex
  re-adds (idempotent; it has no update command).
- Claude refreshes its marketplace index before installing, since a fresh
  CLI ships a stale index that cannot resolve the plugin.
- canInstall gates prerequisites (Cursor needs git) and reports a clear
  skip instead of a cryptic failure.
- One agent failing does not abort the rest, and the CLI exits non-zero
  if any selected agent failed or was blocked.
- Cross-platform: binary detection uses where/which per OS, Cursor is
  located via its per-OS install path, and git paths are quoted for
  Windows spaces.

Distribution:
- rolldown bundles the npm package (deps external).
- fossilize builds standalone Node SEA binaries; --hole-punch drops
  non-English ICU data to cut the download ~30%.

CI:
- A smoke-test matrix (Linux, macOS, Windows) installs the real agent
  CLIs and runs the installer non-interactively, asserting the plugin
  lands for every detected agent.

Instrumented with the Sentry Node SDK.
2026-06-17 13:09:44 -04:00
Michi Hoffmann e824014368 ci: Remove skill-drift reviewer assignment workflow (#182)
The hardcoded skill-to-team mapping in this workflow is now handled by
CODEOWNERS, which gives GitHub native reviewer assignment without a
separate Actions job.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-16 21:03:22 +02:00
Evan Purkhiser d65bd23b67 feat(dist): build and publish per-agent plugin distributions (#158)
This repository is the single source of truth for skills and routing metadata,
but it is not itself an installable plugin, and each assistant (Claude Code,
Cursor, Codex, Grok) expects the plugin in a different on-disk shape. No plugin
ecosystem can consume a zip or release asset; all install from a git ref. So a
GitHub Actions workflow builds each agent's distribution from this repository
and deploys it to a dedicated repository whose root is exactly that agent's
plugin, which a marketplace points at as getsentry/plugin-<agent>.

Each agent has a `plugin-src/<agent>/` dir with its manifests, README, and a
`build.sh` that assembles the dist tree from shared repo content. Claude, Cursor,
and Grok consume the plugin at the repo root; Codex requires it under
`plugins/sentry/` and rejects the `disable-model-invocation` field the skill
tree relies on, so its build strips that field and emits a per-skill
`agents/openai.yaml` (see `hide-skills.py`). MCP config is built from the repo's
`mcp.json` source of truth: inline in Claude's manifest, and a file for the
others.

Cross-repo writes use a short-lived token from a dedicated GitHub App scoped to
contents:write on the plugin repos; the default GITHUB_TOKEN cannot push to
other repositories.

The root `.claude-plugin/`, `.cursor-plugin/`, and `.mcp.json` are retained so
existing installs that consumed the plugin from this repo's root keep working;
their READMEs announce removal on or after 2026-07-11.
2026-06-12 13:39:38 -04:00
Michi Hoffmann cb4cc530d7 meta: Add CODEOWNERS for SDK skills (#165)
Map each SDK skill directory to the GitHub team that owns the
corresponding SDK repository. This ensures the right team gets
requested for review when skill content changes.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-12 15:31:36 +02:00
Daniel Griesser d6123be331 fix(skill-drift): add -n flag to argjson-only jq in plan job (#136)
The plan job's UNKNOWN-skill check used `jq --argjson ... --argjson ...
'$wanted | map(...)'` without `-n` and without stdin. jq waited for
stdin, got EOF, applied the filter zero times, and produced no output —
silently yielding UNKNOWN="" rather than UNKNOWN="[]".

Then `jq 'length' <<<""` also produced no output, so the comparison
`[[ "" != "0" ]]` evaluated true and the workflow died with a
false-positive "Unknown skill(s) in workflow_dispatch input: " error
on every dispatch (run 26625830364).

Add `-nc` so jq treats null as the input, applies the filter once,
and produces the expected empty array. Also guard the length check
with `${UNKNOWN:-[]}` so a future empty value can't trip the same
false positive.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 10:17:58 +02:00
Daniel Griesser 3c78b7064c feat(skill-drift): replace gh-aw workflow with matrix-fanout Claude runs (#135)
* feat(skill-drift): replace gh-aw workflow with matrix-fanout Claude runs

Replaces .github/workflows/skill-drift-check.{md,lock.yml} (single
sequential gh-aw run) with a plain GitHub Actions workflow that fans out
one Claude Sonnet session per SDK skill via matrix strategy.

Each per-skill job reads the last 7 days of merged PRs in the
corresponding SDK repo, opens the actually changed source files at the
merge SHA (not just the diff summary), compares against the local skill
bundle, and emits either a file diff under skills/<skill>/ or a
structured summary for the apply job to act on.

Security
- All actions pinned to a full commit SHA.
- permissions: {} at workflow root; each job grants only what it needs.
- The agent job (detect) runs with contents: read ONLY — no write tokens
  reachable from the LLM session.
- Agent tool allowlist restricts Bash to a handful of gh/jq/date
  subcommands; no git, curl, or arbitrary shell.
- The apply job is pure deterministic shell with a path allowlist
  (skills/<this-skill>/ only) enforced before any commit, push, or PR.
- Inline reviewer assignment in the apply job since PRs opened by
  GITHUB_TOKEN do not trigger downstream workflow_run events.
- Trigger surface is schedule + workflow_dispatch only.

Matrix lives in .github/skill-drift-matrix.json so adding a new SDK skill
is a one-line change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(skill-drift): address review feedback in apply job

Four issues flagged on PR #135:

1. (Cursor Bugbot, HIGH) The `artifacts/` directory placed by
   download-artifact was being picked up by `git ls-files --others
   --exclude-standard` in the apply job's path-allowlist check, which
   would have downgraded EVERY create_pr to an issue because no
   `artifacts/...` path matches the `^skills/<skill>/` regex. Scope
   both `git diff` and `git ls-files` to `-- skills/` so anything
   outside that subtree (artifacts/, dotfiles, etc.) is invisible to
   the allowlist scan.

2. (Sentry Bot, HIGH) On the path-allowlist and empty-diff bail-out
   paths the script switched branches but did not remove the untracked
   files left behind by `rsync`. The next iteration would then see
   those files via `git ls-files --others` and trigger a false-positive
   allowlist violation, cascading the failure across all remaining
   skills. Add `git clean -fd -- skills/` at the start of each
   create_pr iteration and on both bail-out paths.

3. (Cursor Bugbot, MEDIUM) `git diff --quiet HEAD` does not detect
   brand-new untracked files. If the agent's only change was adding a
   new `references/*.md`, the empty-diff guard would have silently
   skipped the PR. Replace with an `[[ -z "$TOUCHED" ]]` check, since
   TOUCHED already includes untracked files.

4. (Sentry Bot, MEDIUM) Parsing the PR number from `gh pr create`
   stdout via `basename` is fragile — extra text would corrupt it and
   the downstream JS reviewer-assignment step would silently skip.
   Look up the number via `gh pr view "$BRANCH" --json number --jq
   .number` instead, and log a `::warning::` (plus increment FAILED)
   if it still cannot be determined. Also add a warning log in the JS
   step when an invalid PR number is encountered.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(skill-drift): second review pass — length caps, retries, pagination, edge cases

Addresses the round of review comments left on commit fea5d4a:

1. (sentry-warden, security) Untrusted SDK PR content reaches issue/PR
   bodies via `gh issue create --body "$BODY"` and `gh pr create --body`.
   Add a 256-char cap on `title` and a 10000-char cap on `body`, enforced
   in both detect's validate step and apply's re-validation. Prepend a
   GitHub `> [!WARNING]` alert header to every issue/PR body the agent
   produces so human reviewers see "Auto-generated from external SDK
   content. Review all links and code suggestions before acting on
   them." before reading agent-authored text. Limits the blast radius
   of a successful prompt-injection from an SDK PR.

2. (sentry-bot, MEDIUM) Race condition between `gh pr create` and
   `gh pr view`. GitHub's API is eventually consistent — the immediate
   view can 404 and silently skip reviewer assignment. Retry up to 5
   times with a 1s sleep; warn (not silently skip) if all attempts fail.

3. (cursor-bot, MEDIUM) `actions/download-artifact@v4` fails the step
   when its pattern matches zero artifacts, before the apply script's
   graceful empty-artifact branch can run. Mark the download step
   `continue-on-error: true`. The apply script already handles a
   missing `artifacts/` directory and now also emits a complete set of
   step-outputs (prs/issues/no_drift/failed/opened_pr_nums) on the
   no-artifacts early-exit so downstream conditions see consistent
   values.

4. (cursor-bot, LOW) `github.rest.pulls.listFiles` in the inline
   reviewer-assignment step only returns the first page. Use
   `github.paginate(..., per_page: 100)` so PRs with many files don't
   miss teams. Matches the convention used by
   skill-drift-assign-reviewers.yml.

5. (cursor-bot, LOW) Trailing/leading/double commas in the
   `workflow_dispatch` `skills` input parsed as empty tokens, which
   then failed the unknown-skill check. Drop empty entries in the jq
   pipeline.

6. (cursor-bot, MEDIUM) `title` and `body` were validated as strings
   but empty strings passed, which would have broken `git commit -m ""`
   and yielded useless empty issues. Require non-empty values for
   `create_pr`/`create_issue` (still allowed for `no_drift`, which the
   apply job ignores entirely).

WONTFIX: the "hardcoded `main`" comment. This workflow is pinned to
`getsentry/sentry-for-ai` via `if: github.repository ==` guards on
every job; the default branch IS `main`. Parameterizing
`github.event.repository.default_branch` adds complexity for a
portability story we don't have.

Also: update the agent prompt with the new length caps and non-empty
requirement so the agent's output isn't silently rejected by
validation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 10:04:05 +02:00
Daniel Griesser fb398fdfff fix(skill-drift): remove add_reviewer step that fails on scheduled runs (#116)
The Weekly SDK Skill Drift Detector workflow runs on a `schedule:`
trigger, so there is no `pull_request` context. The agent's `add_reviewer`
safe output therefore failed every run with:

    add_reviewer: No pull_request_number provided and not in pull request context

turning the job red even when the PR and issues were created successfully
(see run https://github.com/getsentry/sentry-for-ai/actions/runs/25321035855).

The step was also redundant: `.github/workflows/skill-drift-assign-reviewers.yml`
already maps changed `skills/sentry-*-sdk/**` paths to the correct team and
requests review per skill (more granular than the agent's union-of-teams call).

Changes:
- Drop `add-reviewer:` from the `safe-outputs:` block.
- Remove Step 4a item 5 telling the agent to call `add_reviewer`.
- Add a short note pointing the agent at the dedicated reviewer-assignment
  workflow so it knows not to try to assign reviewers itself.
- Recompile `skill-drift-check.lock.yml` with gh-aw v0.71.1 (was v0.67.1) so
  CI uses the latest compiler and pinned actions.

Note: the assign-reviewers workflow does not currently fire for these PRs
because gh-aw opens them with `GITHUB_TOKEN`, which by design does not
trigger downstream `pull_request` events. That is a separate issue and is
not addressed here.

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-04 21:35:33 +02:00
Aditya Mathur 6bc9ab38b5 feat(sdk-setup): add TanStack Start and React Router framework skills (#103)
* feat(sdk-setup): add TanStack Start and React Router Framework skills

Add dedicated SDK setup bundles for TanStack Start React and React Router Framework mode so agents can apply package-correct integrations for each framework path. Update router discovery, indexes, and drift/reviewer mappings while clarifying that React Router v5/v6/v7 non-framework guidance remains in the React SDK skill.

Made-with: Cursor

* fix(skill-mappings): cover tanstack drift ownership and framework import path

Add TanStack Start SDK entries to drift/reviewer mappings so automation continues to route changes to the JS SDK team. Align React Router framework fallback docs to import instrument.server.mjs explicitly, matching the configured instrumentation filename.

Co-Authored-By: Codex 5.3 <codex@openai.com>
Made-with: Cursor

---------

Co-authored-by: Codex 5.3 <codex@openai.com>
2026-04-21 01:15:43 +08:00
Daniel Griesser 72aadac7a1 chore(ci): upgrade gh-aw from v0.64.2 to v0.67.1
Recompile the skill-drift-check workflow with the latest gh-aw CLI.

Key upgrades:
- gh-aw: v0.64.2 → v0.67.1
- AWF (firewall): v0.25.1 → v0.25.13
- MCP Gateway: v0.2.6 → v0.2.14

The previous run (#24033021813) failed because the apiKeyHelper script
was not accessible inside the AWF chroot jail, causing Claude Code to
immediately fail with 'authentication_failed'. The newer AWF version
includes 12 patch releases that address container/chroot reliability.

Closes #91
2026-04-09 09:52:28 +02:00
Daniel Griesser fdb4eeb234 feat: auto-assign SDK team reviewers on skill-drift PRs (#92)
* feat: skill drift workflow opens PRs with fixes and assigns SDK teams

Extend the weekly skill-drift-check workflow to directly fix straightforward
drift by opening PRs instead of only creating issues. The agent now:

- Prefers opening PRs for mechanical changes (new config options, version
  bumps, new integration entries) with the fix applied inline
- Falls back to issues for complex/risky drift (breaking API removals,
  ambiguous behavior, coordinated rewrites)
- Uses add_reviewer to assign the appropriate SDK team (from the mapping
  table) as reviewer on each PR
- PRs are opened as ready-for-review (not draft) with auto-labels and
  14-day expiry

Frontmatter changes:
- Added create-pull-request safe output (max 10, non-draft, protected
  supply-chain files fall back to issues)
- Added add-reviewer safe output restricted to the 5 SDK team slugs
- Recompiled lock.yml with gh-aw v0.64.2 (was v0.55.0)

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>

* feat: auto-assign SDK team reviewers on skill-drift PRs

Add a lightweight workflow that triggers on PR open for skill-drift labeled
PRs. It checks which skills/sentry-*-sdk/ directories were modified and
requests review from the corresponding SDK team via a hardcoded mapping.

This removes the dependency on the agentic workflow remembering to call
add_reviewer — team assignment happens deterministically based on file
paths regardless of how the PR was created.

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>

* fix: use org-prefixed team slugs for reviewer assignment

The requestReviewers API needs the full org/team-slug format
(e.g., getsentry/team-javascript-sdks) to resolve teams correctly.

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4 <noreply@anthropic.com>
2026-04-08 09:22:35 +02:00
Daniel Griesser 0c842c1eff feat: skill drift workflow opens PRs with fixes and assigns SDK teams (#82)
Extend the weekly skill-drift-check workflow to directly fix straightforward
drift by opening PRs instead of only creating issues. The agent now:

- Prefers opening PRs for mechanical changes (new config options, version
  bumps, new integration entries) with the fix applied inline
- Falls back to issues for complex/risky drift (breaking API removals,
  ambiguous behavior, coordinated rewrites)
- Uses add_reviewer to assign the appropriate SDK team (from the mapping
  table) as reviewer on each PR
- PRs are opened as ready-for-review (not draft) with auto-labels and
  14-day expiry

Frontmatter changes:
- Added create-pull-request safe output (max 10, non-draft, protected
  supply-chain files fall back to issues)
- Added add-reviewer safe output restricted to the 5 SDK team slugs
- Recompiled lock.yml with gh-aw v0.64.2 (was v0.55.0)

Co-authored-by: Claude Sonnet 4 <noreply@anthropic.com>
2026-03-27 15:15:57 +01:00
joshuarli 871db4ad41 chore: pin GitHub Actions to full-length commit SHAs (#76) 2026-03-24 21:20:22 -07:00
Daniel Griesser 571ac7966e feat: assign Copilot and notify SDK teams on skill drift issues (#48)
- Assign copilot to drift issues so the skill-updater agent picks them up
- Add team owner column to SDK-to-repo mapping table
- Include cc @team mention in issue body to notify the SDK team
- Teams: team-javascript-sdks, owners-python-sdk, team-web-sdk-backend,
  team-mobile, team-mobile-cross-platform

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 16:49:31 +01:00
Daniel Griesser dda4606e06 feat: add skill-creator agent for building new SDK skills (#49)
* feat: add skill-creator custom agent for GitHub Copilot

Adds a specialized agent that creates complete SDK skill bundles from
scratch. Key differentiator: it clones the SDK repo locally to verify
every API name, config option, and import path against actual source
code before writing anything.

Workflow: study existing skills -> research docs -> clone SDK repo ->
verify APIs against source -> write skill bundle -> run quality
checklist -> register in skill tree -> open PR.

References skill-creator files (philosophy.md, quality-checklist.md,
research-playbook.md) as source of truth rather than duplicating them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: run skill tree registration before validation

Swaps Steps 6 and 7 so the new skill is registered in the parent
router table before build-skill-tree.sh runs. The validator checks
that every skill with a parent field appears in its router — running
it before registration always fails.

Also switches to --check flag for the final validation to prevent
unintended SKILL_TREE.md modifications during verification.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:52:32 +01:00
Daniel Griesser 533dbc5ee3 feat: add skill-updater custom agent for GitHub Copilot (#44)
Adds a GitHub Copilot custom agent profile that specializes in creating
and updating Sentry SDK skill bundles. Instead of duplicating knowledge,
it references the skill-creator files (philosophy.md, quality-checklist.md,
research-playbook.md) as its source of truth — so it stays current as
those files evolve.

Designed to work with skill-drift issues from the weekly drift detector.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 22:28:02 +01:00
Copilot 877a8625ac fix: allow mcp.sentry.dev in SDK Skill Drift Detector firewall (#43)
* Initial plan

* fix: add mcp.sentry.dev to allowed domains in SDK Skill Drift Detector workflow

The workflow was failing because the project's .mcp.json configures a `sentry`
MCP server at https://mcp.sentry.dev/mcp. When Claude Code runs in the agentic
workflow, it reads the project-level .mcp.json and tries to connect to this
server. Since mcp.sentry.dev was not in the firewall's allowed domains list,
the connection was blocked and Claude Code reported:

  ERR_API: MCP server(s) failed to launch: sentry

The "Parse agent logs for step summary" step detected this error and marked the
job as failed — even though the actual work (creating skill drift issues) was
completed successfully.

Fix: Add mcp.sentry.dev to the allowed domains in both the workflow source file
(skill-drift-check.md) and the compiled lock file (skill-drift-check.lock.yml).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

Co-authored-by: HazAT <363802+HazAT@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: HazAT <363802+HazAT@users.noreply.github.com>
2026-03-07 22:26:01 +01:00
Daniel Griesser ff5353e170 feat: add weekly SDK skill drift detector (#37)
* feat: add weekly SDK skill drift detector agentic workflow

Adds a GitHub Agentic Workflow that runs weekly (Monday) using Claude
to detect when SDK skill files have fallen behind changes in Sentry
SDK repos. Monitors all 15 SDK skills across 10 GitHub repos, with
smart monorepo path filtering for sentry-javascript.

When drift is detected (new config options, deprecated APIs, new
framework integrations, feature changes, version bumps, or breaking
changes), it creates labeled issues in this repo with specific
gaps and links to the relevant PRs and skill files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: remove design doc from PR

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 21:55:51 +01:00
Greg Pstrucha 7498f3fb03 fix(ci): Pass WARDEN_SENTRY_DSN in warden workflow 2026-03-03 18:13:37 -08:00
Daniel Griesser 923a5f480f refactor(ci): move skill tree validation to its own workflow
Extract validate-skill-tree from the warden workflow into a dedicated
.github/workflows/validate-skill-tree.yml. Keeps concerns separate —
warden handles AI code review, skill tree validation handles structural
integrity. Both trigger on the same PR events but run independently.
2026-03-02 09:21:07 +01:00
Daniel Griesser 242fadbd19 ci(skill-tree): add validate-skill-tree job to warden workflow
Adds a parallel CI job that runs `./scripts/build-skill-tree.sh --check`
on every PR. The job checks out the repo with minimal permissions
(contents: read) and fails if SKILL_TREE.md is stale or any skill
frontmatter/breadcrumb/router-table validation errors are found.

Running it as a separate job (rather than a step in the warden review
job) keeps concerns isolated and lets both jobs run in parallel.

Co-Authored-By: Claude Sonnet 4.5 (Anthropic)
2026-03-02 09:21:07 +01:00
David Cramer ac175f503d Add warden GitHub Action and config
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 14:27:47 -08:00