@sentry/warden 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/find-bugs/SKILL.md +75 -0
- package/.agents/skills/vercel-react-best-practices/AGENTS.md +2934 -0
- package/.agents/skills/vercel-react-best-practices/SKILL.md +136 -0
- package/.agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/.agents/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
- package/.agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
- package/.agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/.agents/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
- package/.agents/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
- package/.agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/.agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/.agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/.agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/.agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
- package/.agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/.agents/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
- package/.claude/settings.json +57 -0
- package/.claude/settings.local.json +88 -0
- package/.claude/skills/agent-prompt/SKILL.md +54 -0
- package/.claude/skills/agent-prompt/references/agentic-patterns.md +94 -0
- package/.claude/skills/agent-prompt/references/anti-patterns.md +140 -0
- package/.claude/skills/agent-prompt/references/context-design.md +124 -0
- package/.claude/skills/agent-prompt/references/core-principles.md +75 -0
- package/.claude/skills/agent-prompt/references/model-guidance.md +118 -0
- package/.claude/skills/agent-prompt/references/output-formats.md +98 -0
- package/.claude/skills/agent-prompt/references/skill-structure.md +115 -0
- package/.claude/skills/agent-prompt/references/system-prompts.md +115 -0
- package/.claude/skills/notseer/SKILL.md +131 -0
- package/.claude/skills/skill-writer/SKILL.md +140 -0
- package/.claude/skills/testing-guidelines/SKILL.md +132 -0
- package/.claude/skills/warden-skill/SKILL.md +250 -0
- package/.claude/skills/warden-skill/references/config-schema.md +133 -0
- package/.dex/config.toml +2 -0
- package/.github/workflows/ci.yml +33 -0
- package/.github/workflows/release.yml +54 -0
- package/.github/workflows/warden.yml +40 -0
- package/AGENTS.md +89 -0
- package/CONTRIBUTING.md +60 -0
- package/LICENSE +105 -0
- package/README.md +43 -0
- package/SPEC.md +263 -0
- package/action.yml +87 -0
- package/assets/favicon.png +0 -0
- package/assets/warden-icon-bw.svg +5 -0
- package/assets/warden-icon-purple.png +0 -0
- package/assets/warden-icon-purple.svg +5 -0
- package/docs/.claude/settings.local.json +11 -0
- package/docs/astro.config.mjs +43 -0
- package/docs/package.json +19 -0
- package/docs/pnpm-lock.yaml +4000 -0
- package/docs/public/favicon.svg +5 -0
- package/docs/src/components/Code.astro +141 -0
- package/docs/src/components/PackageManagerTabs.astro +183 -0
- package/docs/src/components/Terminal.astro +212 -0
- package/docs/src/layouts/Base.astro +380 -0
- package/docs/src/pages/cli.astro +167 -0
- package/docs/src/pages/config.astro +394 -0
- package/docs/src/pages/guide.astro +449 -0
- package/docs/src/pages/index.astro +490 -0
- package/docs/src/styles/global.css +551 -0
- package/docs/tsconfig.json +3 -0
- package/docs/vercel.json +5 -0
- package/eslint.config.js +33 -0
- package/package.json +73 -0
- package/src/action/index.ts +1 -0
- package/src/action/main.ts +868 -0
- package/src/cli/args.test.ts +477 -0
- package/src/cli/args.ts +415 -0
- package/src/cli/commands/add.ts +447 -0
- package/src/cli/commands/init.test.ts +136 -0
- package/src/cli/commands/init.ts +132 -0
- package/src/cli/commands/setup-app/browser.ts +38 -0
- package/src/cli/commands/setup-app/credentials.ts +45 -0
- package/src/cli/commands/setup-app/manifest.ts +48 -0
- package/src/cli/commands/setup-app/server.ts +172 -0
- package/src/cli/commands/setup-app.ts +156 -0
- package/src/cli/commands/sync.ts +114 -0
- package/src/cli/context.ts +131 -0
- package/src/cli/files.test.ts +155 -0
- package/src/cli/files.ts +89 -0
- package/src/cli/fix.test.ts +310 -0
- package/src/cli/fix.ts +387 -0
- package/src/cli/git.test.ts +119 -0
- package/src/cli/git.ts +318 -0
- package/src/cli/index.ts +14 -0
- package/src/cli/main.ts +672 -0
- package/src/cli/output/box.ts +235 -0
- package/src/cli/output/formatters.test.ts +187 -0
- package/src/cli/output/formatters.ts +269 -0
- package/src/cli/output/icons.ts +13 -0
- package/src/cli/output/index.ts +44 -0
- package/src/cli/output/ink-runner.tsx +337 -0
- package/src/cli/output/jsonl.test.ts +347 -0
- package/src/cli/output/jsonl.ts +126 -0
- package/src/cli/output/reporter.ts +435 -0
- package/src/cli/output/tasks.ts +374 -0
- package/src/cli/output/tty.test.ts +117 -0
- package/src/cli/output/tty.ts +60 -0
- package/src/cli/output/verbosity.test.ts +40 -0
- package/src/cli/output/verbosity.ts +31 -0
- package/src/cli/terminal.test.ts +148 -0
- package/src/cli/terminal.ts +301 -0
- package/src/config/index.ts +3 -0
- package/src/config/loader.test.ts +313 -0
- package/src/config/loader.ts +103 -0
- package/src/config/schema.ts +168 -0
- package/src/config/writer.test.ts +119 -0
- package/src/config/writer.ts +84 -0
- package/src/diff/classify.test.ts +162 -0
- package/src/diff/classify.ts +92 -0
- package/src/diff/coalesce.test.ts +208 -0
- package/src/diff/coalesce.ts +133 -0
- package/src/diff/context.test.ts +226 -0
- package/src/diff/context.ts +201 -0
- package/src/diff/index.ts +4 -0
- package/src/diff/parser.test.ts +212 -0
- package/src/diff/parser.ts +149 -0
- package/src/event/context.ts +132 -0
- package/src/event/index.ts +2 -0
- package/src/event/schedule-context.ts +101 -0
- package/src/examples/examples.integration.test.ts +66 -0
- package/src/examples/index.test.ts +101 -0
- package/src/examples/index.ts +122 -0
- package/src/examples/setup.ts +25 -0
- package/src/index.ts +115 -0
- package/src/output/dedup.test.ts +419 -0
- package/src/output/dedup.ts +607 -0
- package/src/output/github-checks.test.ts +300 -0
- package/src/output/github-checks.ts +476 -0
- package/src/output/github-issues.ts +329 -0
- package/src/output/index.ts +5 -0
- package/src/output/issue-renderer.ts +197 -0
- package/src/output/renderer.test.ts +727 -0
- package/src/output/renderer.ts +217 -0
- package/src/output/stale.test.ts +375 -0
- package/src/output/stale.ts +155 -0
- package/src/output/types.ts +34 -0
- package/src/sdk/index.ts +1 -0
- package/src/sdk/runner.test.ts +806 -0
- package/src/sdk/runner.ts +1232 -0
- package/src/skills/index.ts +36 -0
- package/src/skills/loader.test.ts +300 -0
- package/src/skills/loader.ts +423 -0
- package/src/skills/remote.test.ts +704 -0
- package/src/skills/remote.ts +604 -0
- package/src/triggers/matcher.test.ts +277 -0
- package/src/triggers/matcher.ts +152 -0
- package/src/types/index.ts +194 -0
- package/src/utils/async.ts +18 -0
- package/src/utils/index.test.ts +84 -0
- package/src/utils/index.ts +50 -0
- package/tsconfig.json +25 -0
- package/vitest.config.ts +8 -0
- package/vitest.integration.config.ts +11 -0
- package/warden.toml +19 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Functional Source License, Version 1.1, ALv2 Future License
|
|
2
|
+
|
|
3
|
+
## Abbreviation
|
|
4
|
+
|
|
5
|
+
FSL-1.1-ALv2
|
|
6
|
+
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2025 Functional Software, Inc.
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
The party offering the Software under these Terms and Conditions.
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
The "Software" is each version of the software that we make available under
|
|
20
|
+
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
+
Conditions with the Software.
|
|
22
|
+
|
|
23
|
+
### License Grant
|
|
24
|
+
|
|
25
|
+
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
+
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
+
use, copy, modify, create derivative works, publicly perform, publicly display
|
|
28
|
+
and redistribute the Software for any Permitted Purpose identified below.
|
|
29
|
+
|
|
30
|
+
### Permitted Purpose
|
|
31
|
+
|
|
32
|
+
A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
|
|
33
|
+
means making the Software available to others in a commercial product or
|
|
34
|
+
service that:
|
|
35
|
+
|
|
36
|
+
1. substitutes for the Software;
|
|
37
|
+
|
|
38
|
+
2. substitutes for any other product or service we offer using the Software
|
|
39
|
+
that exists as of the date we make the Software available; or
|
|
40
|
+
|
|
41
|
+
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
+
|
|
43
|
+
Permitted Purposes specifically include using the Software:
|
|
44
|
+
|
|
45
|
+
1. for your internal use and access;
|
|
46
|
+
|
|
47
|
+
2. for non-commercial education;
|
|
48
|
+
|
|
49
|
+
3. for non-commercial research; and
|
|
50
|
+
|
|
51
|
+
4. in connection with professional services that you provide to a licensee
|
|
52
|
+
using the Software in accordance with these Terms and Conditions.
|
|
53
|
+
|
|
54
|
+
### Patents
|
|
55
|
+
|
|
56
|
+
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
+
patents, the license grant above includes a license under our patents. If you
|
|
58
|
+
make a claim against any party that the Software infringes or contributes to
|
|
59
|
+
the infringement of any patent, then your patent license to the Software ends
|
|
60
|
+
immediately.
|
|
61
|
+
|
|
62
|
+
### Redistribution
|
|
63
|
+
|
|
64
|
+
The Terms and Conditions apply to all copies, modifications and derivatives of
|
|
65
|
+
the Software.
|
|
66
|
+
|
|
67
|
+
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
+
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
+
remove any copyright notices provided in or with the Software.
|
|
70
|
+
|
|
71
|
+
### Disclaimer
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
|
|
74
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
|
|
75
|
+
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
+
|
|
77
|
+
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
|
|
78
|
+
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
|
|
79
|
+
EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
+
|
|
81
|
+
### Trademarks
|
|
82
|
+
|
|
83
|
+
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
+
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
+
trademarks, trade names, service marks or product names.
|
|
86
|
+
|
|
87
|
+
## Grant of Future License
|
|
88
|
+
|
|
89
|
+
We hereby irrevocably grant you an additional license to use the Software under
|
|
90
|
+
the Apache License, Version 2.0 that is effective on the second anniversary of
|
|
91
|
+
the date we make the Software available. On or after that date, you may use the
|
|
92
|
+
Software under the Apache License, Version 2.0, in which case the following
|
|
93
|
+
will apply:
|
|
94
|
+
|
|
95
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
96
|
+
this file except in compliance with the License.
|
|
97
|
+
|
|
98
|
+
You may obtain a copy of the License at
|
|
99
|
+
|
|
100
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
101
|
+
|
|
102
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
|
103
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
|
+
specific language governing permissions and limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/warden-icon-purple.svg" alt="Warden" width="128" height="128">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# warden
|
|
6
|
+
|
|
7
|
+
Your code is under new management. Agents that review your code - locally or on every PR - using the Skills you already know and love.
|
|
8
|
+
|
|
9
|
+
## Why Warden?
|
|
10
|
+
|
|
11
|
+
**Skills, not prompts.** Define analysis once, run it anywhere. Bootstrap your environment with skills from conventional directories (`.warden/skills/`, `.agents/skills/`, `.claude/skills/`).
|
|
12
|
+
|
|
13
|
+
**Two ways to run.** CLI catches issues before you push. GitHub Action reviews every PR automatically.
|
|
14
|
+
|
|
15
|
+
**GitHub-native.** Findings appear as inline PR comments with suggested fixes.
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Initialize warden in your repository
|
|
21
|
+
npx warden init
|
|
22
|
+
|
|
23
|
+
# Run on uncommitted changes
|
|
24
|
+
# Uses Claude Code subscription if logged in, or set WARDEN_ANTHROPIC_API_KEY
|
|
25
|
+
npx warden
|
|
26
|
+
|
|
27
|
+
# Fix issues automatically
|
|
28
|
+
npx warden --fix
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**[Read the full documentation →](https://warden.sentry.dev/)**
|
|
32
|
+
|
|
33
|
+
## Contributing
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git clone git@github.com:getsentry/warden.git
|
|
37
|
+
cd warden
|
|
38
|
+
pnpm install && pnpm build
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## License
|
|
42
|
+
|
|
43
|
+
FSL-1.1-ALv2
|
package/SPEC.md
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# Warden Spec
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Warden is an event-driven agent that reacts to GitHub events (Pull Requests, Issues, etc.) and executes configured skills using Claude Code SDK to produce structured reports. These reports are then translated into GitHub actions like inline comments, suggested changes, or status checks.
|
|
6
|
+
|
|
7
|
+
**Key Decisions:**
|
|
8
|
+
- **Runtime**: GitHub Action (primary), with Cloudflare/Vercel webhook option
|
|
9
|
+
- **LLM Execution**: Claude Code SDK (spawns agents per skill)
|
|
10
|
+
- **Configuration**: In-repo `warden.yaml` with optional central defaults
|
|
11
|
+
- **Tech Stack**: TypeScript/Node.js
|
|
12
|
+
|
|
13
|
+
## Core Architecture
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
┌─────────────┐ ┌──────────────┐ ┌─────────────┐ ┌──────────────┐
|
|
17
|
+
│ Trigger │────▶│ Config │────▶│ Claude │────▶│ Output │
|
|
18
|
+
│ (GH Action │ │ Resolver │ │ Code SDK │ │ Renderer │
|
|
19
|
+
│ or Webhook) │ │ │ │ Agent │ │ │
|
|
20
|
+
└─────────────┘ └──────────────┘ └─────────────┘ └──────────────┘
|
|
21
|
+
│ │ │
|
|
22
|
+
▼ ▼ ▼
|
|
23
|
+
┌──────────────┐ ┌─────────────┐ ┌──────────────┐
|
|
24
|
+
│ warden.yaml │ │ Skills │ │ GitHub │
|
|
25
|
+
│ (in-repo) │ │ (prompts) │ │ API │
|
|
26
|
+
└──────────────┘ └─────────────┘ └──────────────┘
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Components
|
|
30
|
+
|
|
31
|
+
### 1. Event Ingestion
|
|
32
|
+
|
|
33
|
+
Receives GitHub webhooks and normalizes them into internal event types.
|
|
34
|
+
|
|
35
|
+
**Supported Events:**
|
|
36
|
+
- `pull_request` (opened, synchronize, reopened, closed)
|
|
37
|
+
- `issues` (opened, edited, closed)
|
|
38
|
+
- `issue_comment` (created, edited)
|
|
39
|
+
- `pull_request_review` (submitted)
|
|
40
|
+
- `pull_request_review_comment` (created)
|
|
41
|
+
|
|
42
|
+
### 2. Configuration System
|
|
43
|
+
|
|
44
|
+
Maps events to skills via declarative configuration.
|
|
45
|
+
|
|
46
|
+
```yaml
|
|
47
|
+
# Example: warden.yaml
|
|
48
|
+
version: 1
|
|
49
|
+
|
|
50
|
+
triggers:
|
|
51
|
+
- name: "Security Review on PR"
|
|
52
|
+
event: pull_request
|
|
53
|
+
actions: [opened, synchronize]
|
|
54
|
+
skills:
|
|
55
|
+
- identify-security-vuln
|
|
56
|
+
- check-dependencies
|
|
57
|
+
|
|
58
|
+
- name: "Code Review"
|
|
59
|
+
event: pull_request
|
|
60
|
+
actions: [opened]
|
|
61
|
+
skills:
|
|
62
|
+
- code-review
|
|
63
|
+
filters:
|
|
64
|
+
paths:
|
|
65
|
+
- "src/**/*.ts"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 3. Skill System
|
|
69
|
+
|
|
70
|
+
Skills are defined as configurations that get executed via Claude Code SDK. Each skill is essentially:
|
|
71
|
+
- A system prompt defining the agent's purpose
|
|
72
|
+
- Tool restrictions (what the agent can/cannot do)
|
|
73
|
+
- Output schema for structured results
|
|
74
|
+
|
|
75
|
+
**Skill Definition:**
|
|
76
|
+
```yaml
|
|
77
|
+
# skills/security-review.yaml
|
|
78
|
+
name: security-review
|
|
79
|
+
description: Identify security vulnerabilities in code changes
|
|
80
|
+
|
|
81
|
+
prompt: |
|
|
82
|
+
You are a security reviewer. Analyze the PR diff for:
|
|
83
|
+
- Injection vulnerabilities (SQL, XSS, command injection)
|
|
84
|
+
- Authentication/authorization issues
|
|
85
|
+
- Secrets or credentials in code
|
|
86
|
+
- Insecure dependencies
|
|
87
|
+
|
|
88
|
+
Return findings in the specified JSON schema.
|
|
89
|
+
|
|
90
|
+
tools:
|
|
91
|
+
allowed:
|
|
92
|
+
- Read
|
|
93
|
+
- Grep
|
|
94
|
+
- Glob
|
|
95
|
+
- WebFetch # for checking CVE databases
|
|
96
|
+
denied:
|
|
97
|
+
- Write
|
|
98
|
+
- Edit
|
|
99
|
+
- Bash
|
|
100
|
+
|
|
101
|
+
output_schema: SkillReport # references shared schema
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Example Skills:**
|
|
105
|
+
- `security-review` - Scan for security vulnerabilities
|
|
106
|
+
- `code-review` - General code quality feedback
|
|
107
|
+
- `dependency-check` - Check for outdated/vulnerable deps
|
|
108
|
+
- `test-coverage` - Analyze if new code has tests
|
|
109
|
+
- `documentation-check` - Ensure public APIs are documented
|
|
110
|
+
|
|
111
|
+
**Skills:**
|
|
112
|
+
Users define skills in conventional directories: `.warden/skills/`, `.agents/skills/`, or `.claude/skills/`
|
|
113
|
+
|
|
114
|
+
### 3a. Internal Meta-Skills (for development)
|
|
115
|
+
|
|
116
|
+
Warden includes internal skills (in `.claude/skills/`) that help **design and validate new skills**. These are not user-facing skills that run on PRs - they're development aids.
|
|
117
|
+
|
|
118
|
+
**skill-writer** - Helps create correct skill definitions:
|
|
119
|
+
- Takes a natural language description of what the skill should do
|
|
120
|
+
- Generates a valid skill YAML with proper prompt engineering
|
|
121
|
+
- Ensures output schema compliance
|
|
122
|
+
- Suggests appropriate tool restrictions
|
|
123
|
+
|
|
124
|
+
This mirrors Claude's own skill-writer pattern and helps bootstrap new skills correctly.
|
|
125
|
+
|
|
126
|
+
### 4. Skill Report (Structured Output)
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
interface SkillReport {
|
|
130
|
+
skill: string;
|
|
131
|
+
summary: string;
|
|
132
|
+
findings: Finding[];
|
|
133
|
+
metadata?: Record<string, unknown>;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
interface Finding {
|
|
137
|
+
id: string;
|
|
138
|
+
severity: 'critical' | 'high' | 'medium' | 'low' | 'info';
|
|
139
|
+
title: string;
|
|
140
|
+
description: string;
|
|
141
|
+
location?: {
|
|
142
|
+
path: string;
|
|
143
|
+
startLine: number;
|
|
144
|
+
endLine?: number;
|
|
145
|
+
};
|
|
146
|
+
suggestedFix?: {
|
|
147
|
+
description: string;
|
|
148
|
+
diff: string; // unified diff format
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 5. Output Renderer
|
|
154
|
+
|
|
155
|
+
Translates SkillReport into GitHub API calls.
|
|
156
|
+
|
|
157
|
+
**Output Types:**
|
|
158
|
+
- **PR Review Comment**: Inline comment on specific lines
|
|
159
|
+
- **PR Review**: Overall review with approve/request-changes/comment
|
|
160
|
+
- **Suggested Change**: GitHub's suggestion block format
|
|
161
|
+
- **Issue Comment**: General comment on issue/PR
|
|
162
|
+
- **Status Check**: Pass/fail status with details URL
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Trigger Mechanisms
|
|
167
|
+
|
|
168
|
+
### Option A: GitHub Action (Recommended for MVP)
|
|
169
|
+
|
|
170
|
+
```yaml
|
|
171
|
+
# .github/workflows/warden.yml
|
|
172
|
+
name: Warden
|
|
173
|
+
on:
|
|
174
|
+
pull_request:
|
|
175
|
+
types: [opened, synchronize, reopened]
|
|
176
|
+
issues:
|
|
177
|
+
types: [opened]
|
|
178
|
+
|
|
179
|
+
jobs:
|
|
180
|
+
warden:
|
|
181
|
+
runs-on: ubuntu-latest
|
|
182
|
+
steps:
|
|
183
|
+
- uses: actions/checkout@v4
|
|
184
|
+
- uses: anthropics/warden-action@v1
|
|
185
|
+
with:
|
|
186
|
+
anthropic-api-key: ${{ secrets.WARDEN_ANTHROPIC_API_KEY }}
|
|
187
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Pros:** No infrastructure to maintain, familiar to users, runs in repo context
|
|
191
|
+
**Cons:** Cold start latency, limited to GitHub Action runtime constraints
|
|
192
|
+
|
|
193
|
+
### Option B: Webhook Service (Cloudflare/Vercel)
|
|
194
|
+
|
|
195
|
+
For orgs wanting faster response times or central management.
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
GitHub App webhook → Cloudflare Worker → Clone repo → Run Warden → Post results
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Claude Code SDK Integration
|
|
204
|
+
|
|
205
|
+
Warden uses the Claude Code SDK to spawn agents for each skill:
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
import { ClaudeCode } from '@anthropic-ai/claude-code';
|
|
209
|
+
|
|
210
|
+
async function runSkill(skill: SkillConfig, context: EventContext): Promise<SkillReport> {
|
|
211
|
+
const claude = new ClaudeCode({
|
|
212
|
+
apiKey: process.env.WARDEN_ANTHROPIC_API_KEY,
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
const session = await claude.createSession({
|
|
216
|
+
systemPrompt: skill.prompt,
|
|
217
|
+
tools: skill.tools,
|
|
218
|
+
workingDirectory: context.repoPath,
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// Provide context about the PR/issue
|
|
222
|
+
const result = await session.run(`
|
|
223
|
+
Analyze this pull request:
|
|
224
|
+
- Title: ${context.pr.title}
|
|
225
|
+
- Description: ${context.pr.body}
|
|
226
|
+
- Files changed: ${context.pr.files.map(f => f.filename).join(', ')}
|
|
227
|
+
|
|
228
|
+
The diff is available in the working directory.
|
|
229
|
+
Return your findings as JSON matching the SkillReport schema.
|
|
230
|
+
`);
|
|
231
|
+
|
|
232
|
+
return parseSkillReport(result);
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## MVP Scope
|
|
239
|
+
|
|
240
|
+
**In Scope:**
|
|
241
|
+
- GitHub Action trigger only (no webhook service yet)
|
|
242
|
+
- `pull_request` events (opened, synchronize)
|
|
243
|
+
- Skills from conventional directories (`.warden/skills/`, `.agents/skills/`, `.claude/skills/`)
|
|
244
|
+
- Internal meta-skill: `skill-writer` (to help design correct skills)
|
|
245
|
+
- Three output types: inline comments, suggested changes, summary comment
|
|
246
|
+
- In-repo `warden.yaml` configuration
|
|
247
|
+
- One-shot analysis (no conversation follow-ups)
|
|
248
|
+
|
|
249
|
+
**Out of Scope (Future):**
|
|
250
|
+
- Webhook service (Cloudflare/Vercel)
|
|
251
|
+
- Issue events
|
|
252
|
+
- Conversation mode (responding to replies)
|
|
253
|
+
- Additional built-in skills
|
|
254
|
+
- Central/org-level configuration
|
|
255
|
+
- Caching/incremental analysis
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Open Questions (for future consideration)
|
|
260
|
+
|
|
261
|
+
1. **Rate Limiting**: How to handle API rate limits when many PRs open simultaneously?
|
|
262
|
+
2. **Caching**: Should we cache analysis of unchanged files across PR updates?
|
|
263
|
+
3. **Incremental Analysis**: On `synchronize` events, only analyze new commits or full diff?
|
package/action.yml
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
name: 'Warden'
|
|
2
|
+
description: 'Event-driven agent that analyzes GitHub PRs using Claude Code SDK'
|
|
3
|
+
author: 'Functional Software, Inc.'
|
|
4
|
+
|
|
5
|
+
branding:
|
|
6
|
+
icon: 'shield'
|
|
7
|
+
color: 'purple'
|
|
8
|
+
|
|
9
|
+
inputs:
|
|
10
|
+
anthropic-api-key:
|
|
11
|
+
description: 'Anthropic API key for Claude Code SDK. Can also be provided via WARDEN_ANTHROPIC_API_KEY environment variable.'
|
|
12
|
+
required: false
|
|
13
|
+
github-token:
|
|
14
|
+
description: 'GitHub token for API access (defaults to GITHUB_TOKEN)'
|
|
15
|
+
required: false
|
|
16
|
+
default: ${{ github.token }}
|
|
17
|
+
config-path:
|
|
18
|
+
description: 'Path to warden.toml config file (relative to repo root)'
|
|
19
|
+
required: false
|
|
20
|
+
default: 'warden.toml'
|
|
21
|
+
fail-on:
|
|
22
|
+
description: 'Minimum severity level to fail the action (off, critical, high, medium, low, info). Use "off" to never fail.'
|
|
23
|
+
required: false
|
|
24
|
+
default: 'high'
|
|
25
|
+
comment-on:
|
|
26
|
+
description: 'Minimum severity level to show annotations in code review (off, critical, high, medium, low, info). Use "off" to disable comments.'
|
|
27
|
+
required: false
|
|
28
|
+
default: 'medium'
|
|
29
|
+
max-findings:
|
|
30
|
+
description: 'Maximum number of findings to report (0 for unlimited)'
|
|
31
|
+
required: false
|
|
32
|
+
default: '50'
|
|
33
|
+
parallel:
|
|
34
|
+
description: 'Maximum number of concurrent trigger executions'
|
|
35
|
+
required: false
|
|
36
|
+
default: '5'
|
|
37
|
+
|
|
38
|
+
outputs:
|
|
39
|
+
findings-count:
|
|
40
|
+
description: 'Total number of findings'
|
|
41
|
+
value: ${{ steps.warden.outputs.findings-count }}
|
|
42
|
+
critical-count:
|
|
43
|
+
description: 'Number of critical severity findings'
|
|
44
|
+
value: ${{ steps.warden.outputs.critical-count }}
|
|
45
|
+
high-count:
|
|
46
|
+
description: 'Number of high severity findings'
|
|
47
|
+
value: ${{ steps.warden.outputs.high-count }}
|
|
48
|
+
summary:
|
|
49
|
+
description: 'Summary of the analysis'
|
|
50
|
+
value: ${{ steps.warden.outputs.summary }}
|
|
51
|
+
|
|
52
|
+
runs:
|
|
53
|
+
using: 'composite'
|
|
54
|
+
steps:
|
|
55
|
+
- name: Install Claude Code CLI
|
|
56
|
+
shell: bash
|
|
57
|
+
run: |
|
|
58
|
+
CLAUDE_CODE_VERSION="2.1.23"
|
|
59
|
+
echo "Installing Claude Code v${CLAUDE_CODE_VERSION}..."
|
|
60
|
+
for attempt in 1 2 3; do
|
|
61
|
+
echo "Installation attempt $attempt..."
|
|
62
|
+
if curl -fsSL https://claude.ai/install.sh | bash -s -- "$CLAUDE_CODE_VERSION"; then
|
|
63
|
+
break
|
|
64
|
+
fi
|
|
65
|
+
if [ $attempt -eq 3 ]; then
|
|
66
|
+
echo "Failed to install Claude Code after 3 attempts"
|
|
67
|
+
exit 1
|
|
68
|
+
fi
|
|
69
|
+
echo "Installation failed, retrying..."
|
|
70
|
+
sleep 5
|
|
71
|
+
done
|
|
72
|
+
echo "Claude Code installed successfully"
|
|
73
|
+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
|
74
|
+
|
|
75
|
+
- name: Run Warden
|
|
76
|
+
id: warden
|
|
77
|
+
shell: bash
|
|
78
|
+
env:
|
|
79
|
+
INPUT_ANTHROPIC_API_KEY: ${{ inputs.anthropic-api-key }}
|
|
80
|
+
INPUT_GITHUB_TOKEN: ${{ inputs.github-token }}
|
|
81
|
+
INPUT_CONFIG_PATH: ${{ inputs.config-path }}
|
|
82
|
+
INPUT_FAIL_ON: ${{ inputs.fail-on }}
|
|
83
|
+
INPUT_COMMENT_ON: ${{ inputs.comment-on }}
|
|
84
|
+
INPUT_MAX_FINDINGS: ${{ inputs.max-findings }}
|
|
85
|
+
INPUT_PARALLEL: ${{ inputs.parallel }}
|
|
86
|
+
CLAUDE_CODE_PATH: ${{ env.HOME }}/.local/bin/claude
|
|
87
|
+
run: node ${{ github.action_path }}/dist/action/index.js
|
|
Binary file
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect width="24" height="24" fill="white"/>
|
|
3
|
+
<path d="M14.2666 4.9061C15.1564 4.09409 16.5921 4.60917 16.7627 5.80162L18.1123 15.2519C18.9476 14.5758 19.6675 14.156 20.2706 13.9423C20.9583 13.6988 21.61 13.6893 22.0606 14.0459C22.5331 14.4202 22.576 15.0232 22.4131 15.5224C22.2471 16.0308 21.8525 16.5326 21.2774 16.916C20.2382 17.6088 19.1848 18.1368 17.7432 18.4863C16.3131 18.833 14.518 19 12 19C9.48202 19 7.68685 18.833 6.25679 18.4863C4.81521 18.1368 3.76183 17.6088 2.72259 16.916C2.14753 16.5326 1.75289 16.0308 1.58684 15.5224C1.42401 15.0233 1.46701 14.4202 1.93938 14.0459C2.38997 13.6893 3.04168 13.6988 3.72943 13.9423C4.33238 14.1559 5.05163 14.5761 5.88667 15.2519L7.23727 5.80162C7.40784 4.60919 8.84362 4.09419 9.73338 4.9061L11.6631 6.66686C11.854 6.84121 12.146 6.84121 12.3369 6.66686L14.2666 4.9061Z" fill="#181225"/>
|
|
4
|
+
<path d="M12 8L13.1226 11.1094H16.7553L13.8164 13.0312L14.9389 16.1406L12 14.2188L9.06107 16.1406L10.1836 13.0312L7.24472 11.1094H10.8774L12 8Z" fill="white"/>
|
|
5
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect width="24" height="24" fill="#7553FF"/>
|
|
3
|
+
<path d="M14.2666 4.9061C15.1564 4.09409 16.5921 4.60917 16.7627 5.80162L18.1123 15.2519C18.9476 14.5758 19.6675 14.156 20.2706 13.9423C20.9583 13.6988 21.61 13.6893 22.0606 14.0459C22.5331 14.4202 22.576 15.0232 22.4131 15.5224C22.2471 16.0308 21.8525 16.5326 21.2774 16.916C20.2382 17.6088 19.1848 18.1368 17.7432 18.4863C16.3131 18.833 14.518 19 12 19C9.48202 19 7.68685 18.833 6.25679 18.4863C4.81521 18.1368 3.76183 17.6088 2.72259 16.916C2.14753 16.5326 1.75289 16.0308 1.58684 15.5224C1.42401 15.0233 1.46701 14.4202 1.93938 14.0459C2.38997 13.6893 3.04168 13.6988 3.72943 13.9423C4.33238 14.1559 5.05163 14.5761 5.88667 15.2519L7.23727 5.80162C7.40784 4.60919 8.84362 4.09419 9.73338 4.9061L11.6631 6.66686C11.854 6.84121 12.146 6.84121 12.3369 6.66686L14.2666 4.9061Z" fill="white"/>
|
|
4
|
+
<path d="M12 8L13.1226 11.1094H16.7553L13.8164 13.0312L14.9389 16.1406L12 14.2188L9.06107 16.1406L10.1836 13.0312L7.24472 11.1094H10.8774L12 8Z" fill="#7553FF"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(pnpm build:*)",
|
|
5
|
+
"Bash(git add:*)",
|
|
6
|
+
"Bash(git commit -m \"$\\(cat <<''EOF''\ndocs: Add remote skills docs, convert tables to definition lists\n\n- Document warden sync command and --repo flag for remote skills\n- Add skill references section explaining resolution order\n- Add --offline flag and WARDEN_SKILL_CACHE_TTL env var\n- Convert all field reference tables to definition lists\n- Update dl/dt/dd styling for monospace keys with purple color\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
7
|
+
"Bash(git commit -m \"$\\(cat <<''EOF''\ndocs\\(config\\): Remove absolute path example from skill references\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
8
|
+
"Bash(git commit -m \"$\\(cat <<''EOF''\ndocs: Use purple Warden icon for GitHub bot avatar\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")"
|
|
9
|
+
]
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { defineConfig, fontProviders } from 'astro/config';
|
|
2
|
+
import mdx from '@astrojs/mdx';
|
|
3
|
+
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
|
|
4
|
+
import rehypeSlug from 'rehype-slug';
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
site: 'https://warden.sentry.dev',
|
|
8
|
+
integrations: [mdx()],
|
|
9
|
+
markdown: {
|
|
10
|
+
shikiConfig: {
|
|
11
|
+
theme: 'vitesse-black',
|
|
12
|
+
},
|
|
13
|
+
rehypePlugins: [
|
|
14
|
+
rehypeSlug,
|
|
15
|
+
[rehypeAutolinkHeadings, {
|
|
16
|
+
behavior: 'prepend',
|
|
17
|
+
properties: { className: ['heading-anchor'] },
|
|
18
|
+
content: { type: 'text', value: '#' }
|
|
19
|
+
}],
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
experimental: {
|
|
23
|
+
fonts: [{
|
|
24
|
+
name: "Geist Mono",
|
|
25
|
+
provider: fontProviders.local(),
|
|
26
|
+
cssVariable: "--font-geist-mono",
|
|
27
|
+
options: {
|
|
28
|
+
variants: [
|
|
29
|
+
{
|
|
30
|
+
weight: 400,
|
|
31
|
+
style: "normal",
|
|
32
|
+
src: ["./node_modules/geist/dist/fonts/geist-mono/GeistMono-Regular.woff2"]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
weight: 600,
|
|
36
|
+
style: "normal",
|
|
37
|
+
src: ["./node_modules/geist/dist/fonts/geist-mono/GeistMono-SemiBold.woff2"]
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
}]
|
|
42
|
+
}
|
|
43
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dex-docs",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "astro dev",
|
|
7
|
+
"build": "astro build",
|
|
8
|
+
"preview": "astro preview"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@astrojs/mdx": "^4.0.0",
|
|
12
|
+
"astro": "^5.0.0",
|
|
13
|
+
"geist": "^1.5.1",
|
|
14
|
+
"rehype-autolink-headings": "^7.1.0",
|
|
15
|
+
"rehype-slug": "^6.0.0",
|
|
16
|
+
"shiki": "^1.0.0",
|
|
17
|
+
"unist-util-visit": "^5.1.0"
|
|
18
|
+
}
|
|
19
|
+
}
|