@mohammadhprp/system-prompt 0.11.1 → 0.11.2
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/framework/agents/backend-architect.md +1 -1
- package/framework/mcps/figma-mcp-go/README.md +0 -1
- package/framework/mcps/gitlab-mcp/README.md +0 -1
- package/framework/mcps/jira-mcp/README.md +0 -1
- package/framework/mcps/laravel-boost/README.md +0 -1
- package/framework/mcps/notion-mcp/README.md +0 -1
- package/framework/mcps/supabase-mcp/README.md +0 -1
- package/framework/plugins/opencode-goal-plugin/README.md +0 -1
- package/framework/references/standards/api.md +0 -1
- package/framework/references/standards/architecture.md +0 -1
- package/framework/references/standards/database.md +0 -1
- package/framework/references/standards/debugging.md +0 -1
- package/framework/references/standards/documentation.md +0 -2
- package/framework/references/standards/logging.md +0 -1
- package/framework/references/standards/naming.md +0 -1
- package/framework/references/standards/observability.md +0 -1
- package/framework/references/standards/performance.md +0 -1
- package/framework/references/standards/pull-requests.md +0 -1
- package/framework/references/standards/security.md +0 -1
- package/framework/references/standards/testing.md +0 -1
- package/framework/skills/README.md +15 -3
- package/framework/skills/codenavi/SKILL.md +306 -0
- package/framework/skills/codenavi/examples.md +33 -0
- package/framework/skills/codenavi/references/coding-principles.md +143 -0
- package/framework/skills/codenavi/references/notebook-spec.md +171 -0
- package/framework/skills/create-adr/SKILL.md +429 -0
- package/framework/skills/create-adr/examples.md +35 -0
- package/framework/skills/docs-writer/SKILL.md +39 -0
- package/framework/skills/docs-writer/examples.md +34 -0
- package/framework/skills/docs-writer/references/style-guide.md +72 -0
- package/framework/skills/frontend-design/SKILL.md +55 -0
- package/framework/skills/frontend-design/examples.md +45 -0
- package/framework/skills/humanizer/SKILL.md +412 -0
- package/framework/skills/humanizer/examples.md +46 -0
- package/framework/skills/learning-opportunities/SKILL.md +140 -0
- package/framework/skills/learning-opportunities/examples.md +34 -0
- package/framework/skills/learning-opportunities/references/PRINCIPLES.md +42 -0
- package/framework/skills/perf-web-optimization/SKILL.md +163 -0
- package/framework/skills/perf-web-optimization/examples.md +35 -0
- package/framework/skills/perf-web-optimization/references/bundle-optimization.md +180 -0
- package/framework/skills/perf-web-optimization/references/core-web-vitals.md +154 -0
- package/framework/skills/perf-web-optimization/references/image-optimization.md +170 -0
- package/framework/skills/security-best-practices/LICENSE.txt +201 -0
- package/framework/skills/security-best-practices/SKILL.md +89 -0
- package/framework/skills/security-best-practices/examples.md +35 -0
- package/framework/skills/security-best-practices/references/golang-general-backend-security.md +988 -0
- package/framework/skills/security-best-practices/references/javascript-express-web-server-security.md +1151 -0
- package/framework/skills/security-best-practices/references/javascript-general-web-frontend-security.md +725 -0
- package/framework/skills/security-best-practices/references/javascript-jquery-web-frontend-security.md +672 -0
- package/framework/skills/security-best-practices/references/javascript-typescript-nextjs-web-server-security.md +1138 -0
- package/framework/skills/security-best-practices/references/javascript-typescript-react-web-frontend-security.md +975 -0
- package/framework/skills/security-best-practices/references/javascript-typescript-vue-web-frontend-security.md +789 -0
- package/framework/skills/security-best-practices/references/python-django-web-server-security.md +880 -0
- package/framework/skills/security-best-practices/references/python-fastapi-web-server-security.md +1030 -0
- package/framework/skills/security-best-practices/references/python-flask-web-server-security.md +835 -0
- package/framework/skills/sentry/SKILL.md +127 -0
- package/framework/skills/sentry/examples.md +34 -0
- package/framework/skills/sentry/scripts/sentry_api.py +238 -0
- package/framework/skills/show-me/SKILL.md +127 -0
- package/framework/skills/show-me/examples.md +78 -0
- package/framework/skills/spec-driven-eval/SKILL.md +341 -0
- package/framework/skills/spec-driven-eval/examples.md +35 -0
- package/framework/skills/spec-driven-eval/references/quickstart.md +118 -0
- package/framework/skills/spec-driven-eval/references/reference.md +295 -0
- package/framework/skills/technical-design-doc-creator/README.md +411 -0
- package/framework/skills/technical-design-doc-creator/SKILL.md +1484 -0
- package/framework/skills/technical-design-doc-creator/examples.md +35 -0
- package/framework/skills/tlc-spec-driven/SKILL.md +184 -0
- package/framework/skills/tlc-spec-driven/examples.md +34 -0
- package/framework/skills/tlc-spec-driven/references/code-analysis.md +98 -0
- package/framework/skills/tlc-spec-driven/references/coding-principles.md +72 -0
- package/framework/skills/tlc-spec-driven/references/context-limits.md +31 -0
- package/framework/skills/tlc-spec-driven/references/design.md +199 -0
- package/framework/skills/tlc-spec-driven/references/discuss.md +159 -0
- package/framework/skills/tlc-spec-driven/references/implement.md +436 -0
- package/framework/skills/tlc-spec-driven/references/lessons.md +115 -0
- package/framework/skills/tlc-spec-driven/references/memory.md +144 -0
- package/framework/skills/tlc-spec-driven/references/specify.md +228 -0
- package/framework/skills/tlc-spec-driven/references/sub-agents.md +147 -0
- package/framework/skills/tlc-spec-driven/references/tasks.md +451 -0
- package/framework/skills/tlc-spec-driven/references/validate.md +355 -0
- package/framework/skills/tlc-spec-driven/scripts/check_commit.py +115 -0
- package/framework/skills/tlc-spec-driven/scripts/lessons.py +412 -0
- package/framework/skills/tlc-spec-driven/scripts/validate_spec.py +260 -0
- package/framework/skills/tlc-spec-driven/scripts/validate_state.py +162 -0
- package/framework/skills/tlc-spec-driven/scripts/validate_tasks.py +251 -0
- package/framework/skills/web-design-guidelines/SKILL.md +65 -0
- package/framework/skills/web-design-guidelines/examples.md +32 -0
- package/framework/skills/web-design-guidelines/references/guideline.md +174 -0
- package/package.json +1 -1
- package/src/catalog.js +15 -3
- package/framework/skills/backend-engineer/SKILL.md +0 -76
- package/framework/skills/backend-engineer/examples.md +0 -31
- package/framework/skills/documentation/SKILL.md +0 -74
- package/framework/skills/documentation/examples.md +0 -31
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sentry
|
|
3
|
+
description: Inspect Sentry issues, summarize production errors, and pull health data via the Sentry API (read-only). Use when user says "check Sentry", "what errors in production?", "summarize Sentry issues", "recent crashes", or "production error report". Requires SENTRY_AUTH_TOKEN. Do NOT use for setting up Sentry SDK, configuring alerts, or non-Sentry error monitoring.
|
|
4
|
+
metadata:
|
|
5
|
+
author: github.com/openai/skills
|
|
6
|
+
version: '1.0.0'
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Sentry (Read-only Observability)
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
- If not already authenticated, ask the user to provide a valid `SENTRY_AUTH_TOKEN` (read-only scopes such as `project:read`, `event:read`) or to log in and create one before running commands.
|
|
14
|
+
- Set `SENTRY_AUTH_TOKEN` as an env var.
|
|
15
|
+
- Optional defaults: `SENTRY_ORG`, `SENTRY_PROJECT`, `SENTRY_BASE_URL`.
|
|
16
|
+
- Defaults: org/project `{your-org}`/`{your-project}`, time range `24h`, environment `prod`, limit 20 (max 50).
|
|
17
|
+
- Always call the Sentry API (no heuristics, no caching).
|
|
18
|
+
|
|
19
|
+
If the token is missing, give the user these steps:
|
|
20
|
+
|
|
21
|
+
1. Create a Sentry auth token: <https://sentry.io/settings/account/api/auth-tokens/>
|
|
22
|
+
2. Create a token with read-only scopes such as `project:read`, `event:read`, and `org:read`.
|
|
23
|
+
3. Set `SENTRY_AUTH_TOKEN` as an environment variable in their system.
|
|
24
|
+
4. Offer to guide them through setting the environment variable for their OS/shell if needed.
|
|
25
|
+
|
|
26
|
+
- Never ask the user to paste the full token in chat. Ask them to set it locally and confirm when ready.
|
|
27
|
+
|
|
28
|
+
## Core tasks (use bundled script)
|
|
29
|
+
|
|
30
|
+
Use `scripts/sentry_api.py` for deterministic API calls. It handles pagination and retries once on transient errors.
|
|
31
|
+
|
|
32
|
+
## Skill path (set once)
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
export AGENT_SKILLS_HOME="${AGENT_SKILLS_HOME:-$HOME/.agent-skills}"
|
|
36
|
+
export SENTRY_API="$AGENT_SKILLS_HOME/skills/sentry/scripts/sentry_api.py"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
User-scoped skills install under `$AGENT_SKILLS_HOME/skills` (default: `~/.agent-skills/skills`).
|
|
40
|
+
|
|
41
|
+
### 1) List issues (ordered by most recent)
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
python3 "$SENTRY_API" \
|
|
45
|
+
list-issues \
|
|
46
|
+
--org {your-org} \
|
|
47
|
+
--project {your-project} \
|
|
48
|
+
--environment prod \
|
|
49
|
+
--time-range 24h \
|
|
50
|
+
--limit 20 \
|
|
51
|
+
--query "is:unresolved"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2) Resolve an issue short ID to issue ID
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
python3 "$SENTRY_API" \
|
|
58
|
+
list-issues \
|
|
59
|
+
--org {your-org} \
|
|
60
|
+
--project {your-project} \
|
|
61
|
+
--query "ABC-123" \
|
|
62
|
+
--limit 1
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Use the returned `id` for issue detail or events.
|
|
66
|
+
|
|
67
|
+
### 3) Issue detail
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
python3 "$SENTRY_API" \
|
|
71
|
+
issue-detail \
|
|
72
|
+
1234567890
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 4) Issue events
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
python3 "$SENTRY_API" \
|
|
79
|
+
issue-events \
|
|
80
|
+
1234567890 \
|
|
81
|
+
--limit 20
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 5) Event detail (no stack traces by default)
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
python3 "$SENTRY_API" \
|
|
88
|
+
event-detail \
|
|
89
|
+
--org {your-org} \
|
|
90
|
+
--project {your-project} \
|
|
91
|
+
abcdef1234567890
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## API requirements
|
|
95
|
+
|
|
96
|
+
Always use these endpoints (GET only):
|
|
97
|
+
|
|
98
|
+
- List issues: `/api/0/projects/{org_slug}/{project_slug}/issues/`
|
|
99
|
+
- Issue detail: `/api/0/issues/{issue_id}/`
|
|
100
|
+
- Events for issue: `/api/0/issues/{issue_id}/events/`
|
|
101
|
+
- Event detail: `/api/0/projects/{org_slug}/{project_slug}/events/{event_id}/`
|
|
102
|
+
|
|
103
|
+
## Inputs and defaults
|
|
104
|
+
|
|
105
|
+
- `org_slug`, `project_slug`: default to `{your-org}`/`{your-project}` (avoid non-prod orgs).
|
|
106
|
+
- `time_range`: default `24h` (pass as `statsPeriod`).
|
|
107
|
+
- `environment`: default `prod`.
|
|
108
|
+
- `limit`: default 20, max 50 (paginate until limit reached).
|
|
109
|
+
- `search_query`: optional `query` parameter.
|
|
110
|
+
- `issue_short_id`: resolve via list-issues query first.
|
|
111
|
+
|
|
112
|
+
## Output formatting rules
|
|
113
|
+
|
|
114
|
+
- Issue list: show title, short_id, status, first_seen, last_seen, count, environments, top_tags; order by most recent.
|
|
115
|
+
- Event detail: include culprit, timestamp, environment, release, url.
|
|
116
|
+
- If no results, state explicitly.
|
|
117
|
+
- Redact PII in output (emails, IPs). Do not print raw stack traces.
|
|
118
|
+
- Never echo auth tokens.
|
|
119
|
+
|
|
120
|
+
## Golden test inputs
|
|
121
|
+
|
|
122
|
+
- Org: `{your-org}`
|
|
123
|
+
- Project: `{your-project}`
|
|
124
|
+
- Issue short ID: `{ABC-123}`
|
|
125
|
+
|
|
126
|
+
Example prompt: “List the top 10 open issues for prod in the last 24h.”
|
|
127
|
+
Expected: ordered list with titles, short IDs, counts, last seen.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Sentry Examples
|
|
2
|
+
|
|
3
|
+
## List recent production errors
|
|
4
|
+
|
|
5
|
+
User: "Check Sentry for what's broken in prod right now."
|
|
6
|
+
|
|
7
|
+
Good agent behavior:
|
|
8
|
+
|
|
9
|
+
- Confirm `SENTRY_AUTH_TOKEN` is set, and if missing, guide the user to create a read-only token without asking them to paste it in chat.
|
|
10
|
+
- Call the Sentry API using the bundled `sentry_api.py` script with the production environment and a 24h window.
|
|
11
|
+
- Return an ordered list with title, short ID, status, counts, and last-seen time.
|
|
12
|
+
- State explicitly when there are no results rather than padding the output.
|
|
13
|
+
|
|
14
|
+
## Summarize a specific issue
|
|
15
|
+
|
|
16
|
+
User: "What's going on with error ABC-123?"
|
|
17
|
+
|
|
18
|
+
Good agent behavior:
|
|
19
|
+
|
|
20
|
+
- Resolve the short ID to a numeric issue ID via the list endpoint, then fetch issue detail and events.
|
|
21
|
+
- Summarize the culprit, timestamp, environment, release, and URL without dumping raw stack traces.
|
|
22
|
+
- Redact PII such as emails and IPs from the output.
|
|
23
|
+
- Note that the API is called directly each time rather than cached.
|
|
24
|
+
|
|
25
|
+
## Production error report
|
|
26
|
+
|
|
27
|
+
User: "Give me a production error report for the last 24 hours."
|
|
28
|
+
|
|
29
|
+
Good agent behavior:
|
|
30
|
+
|
|
31
|
+
- Pull the top unresolved issues with default prod environment and 24h time range, limiting to a reasonable count.
|
|
32
|
+
- Order by most recent activity and group the highest-count errors first.
|
|
33
|
+
- Include the error title, short ID, event count, and affected environments for each.
|
|
34
|
+
- Flag anything needing immediate attention and offer to pull event details for the worst offenders.
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import argparse
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import re
|
|
6
|
+
import sys
|
|
7
|
+
import time
|
|
8
|
+
from urllib.error import HTTPError, URLError
|
|
9
|
+
from urllib.parse import urlencode
|
|
10
|
+
from urllib.request import Request, urlopen
|
|
11
|
+
|
|
12
|
+
DEFAULT_BASE_URL = "https://sentry.io"
|
|
13
|
+
DEFAULT_ORG = "your-org"
|
|
14
|
+
DEFAULT_PROJECT = "your-project"
|
|
15
|
+
MAX_LIMIT = 50
|
|
16
|
+
|
|
17
|
+
EMAIL_RE = re.compile(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}")
|
|
18
|
+
IP_RE = re.compile(r"\b(?:\d{1,3}\.){3}\d{1,3}\b")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def redact_string(value):
|
|
22
|
+
value = EMAIL_RE.sub("[REDACTED_EMAIL]", value)
|
|
23
|
+
value = IP_RE.sub("[REDACTED_IP]", value)
|
|
24
|
+
return value
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def redact_data(value):
|
|
28
|
+
if isinstance(value, str):
|
|
29
|
+
return redact_string(value)
|
|
30
|
+
if isinstance(value, list):
|
|
31
|
+
return [redact_data(item) for item in value]
|
|
32
|
+
if isinstance(value, dict):
|
|
33
|
+
redacted = {}
|
|
34
|
+
for key, item in value.items():
|
|
35
|
+
if key.lower() in {"email", "ip", "ip_address"}:
|
|
36
|
+
redacted[key] = "[REDACTED]"
|
|
37
|
+
else:
|
|
38
|
+
redacted[key] = redact_data(item)
|
|
39
|
+
return redacted
|
|
40
|
+
return value
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def next_cursor(link_header):
|
|
44
|
+
if not link_header:
|
|
45
|
+
return None
|
|
46
|
+
for part in link_header.split(","):
|
|
47
|
+
if 'rel="next"' in part and 'results="true"' in part:
|
|
48
|
+
match = re.search(r'cursor="([^"]+)"', part)
|
|
49
|
+
if match:
|
|
50
|
+
return match.group(1)
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def request_json(url, token, retries=1):
|
|
55
|
+
req = Request(url)
|
|
56
|
+
req.add_header("Authorization", f"Bearer {token}")
|
|
57
|
+
req.add_header("Accept", "application/json")
|
|
58
|
+
|
|
59
|
+
attempt = 0
|
|
60
|
+
while True:
|
|
61
|
+
try:
|
|
62
|
+
with urlopen(req) as resp:
|
|
63
|
+
body = resp.read().decode("utf-8")
|
|
64
|
+
data = json.loads(body) if body else None
|
|
65
|
+
return data, resp.headers
|
|
66
|
+
except HTTPError as err:
|
|
67
|
+
body = err.read().decode("utf-8", "ignore")
|
|
68
|
+
if attempt < retries and (err.code >= 500 or err.code == 429):
|
|
69
|
+
attempt += 1
|
|
70
|
+
time.sleep(1)
|
|
71
|
+
continue
|
|
72
|
+
raise RuntimeError(f"HTTP {err.code} for {url}: {body or 'request failed'}") from err
|
|
73
|
+
except URLError as err:
|
|
74
|
+
if attempt < retries:
|
|
75
|
+
attempt += 1
|
|
76
|
+
time.sleep(1)
|
|
77
|
+
continue
|
|
78
|
+
raise RuntimeError(f"Network error for {url}: {err.reason}") from err
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def build_url(base_url, path, params=None):
|
|
82
|
+
base = base_url.rstrip("/")
|
|
83
|
+
url = f"{base}{path}"
|
|
84
|
+
if params:
|
|
85
|
+
url = f"{url}?{urlencode(params, doseq=True)}"
|
|
86
|
+
return url
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def paged_get(base_url, path, params, token, limit):
|
|
90
|
+
results = []
|
|
91
|
+
cursor = None
|
|
92
|
+
while len(results) < limit:
|
|
93
|
+
page_params = dict(params)
|
|
94
|
+
page_params["per_page"] = min(MAX_LIMIT, limit - len(results))
|
|
95
|
+
if cursor:
|
|
96
|
+
page_params["cursor"] = cursor
|
|
97
|
+
url = build_url(base_url, path, page_params)
|
|
98
|
+
data, headers = request_json(url, token)
|
|
99
|
+
if not data:
|
|
100
|
+
break
|
|
101
|
+
results.extend(data)
|
|
102
|
+
cursor = next_cursor(headers.get("Link"))
|
|
103
|
+
if not cursor:
|
|
104
|
+
break
|
|
105
|
+
return results[:limit]
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def require_org_project(org, project):
|
|
109
|
+
if org == DEFAULT_ORG or project == DEFAULT_PROJECT:
|
|
110
|
+
raise RuntimeError(
|
|
111
|
+
"Missing org/project. Set SENTRY_ORG and SENTRY_PROJECT or pass --org/--project."
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def handle_list_issues(args, token, base_url):
|
|
116
|
+
require_org_project(args.org, args.project)
|
|
117
|
+
limit = min(args.limit, MAX_LIMIT)
|
|
118
|
+
params = {
|
|
119
|
+
"statsPeriod": args.time_range,
|
|
120
|
+
"environment": args.environment,
|
|
121
|
+
}
|
|
122
|
+
if args.query:
|
|
123
|
+
params["query"] = args.query
|
|
124
|
+
|
|
125
|
+
path = f"/api/0/projects/{args.org}/{args.project}/issues/"
|
|
126
|
+
issues = paged_get(base_url, path, params, token, limit)
|
|
127
|
+
return issues
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def handle_issue_detail(args, token, base_url):
|
|
131
|
+
path = f"/api/0/issues/{args.issue_id}/"
|
|
132
|
+
url = build_url(base_url, path)
|
|
133
|
+
data, _ = request_json(url, token)
|
|
134
|
+
return data
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def handle_issue_events(args, token, base_url):
|
|
138
|
+
limit = min(args.limit, MAX_LIMIT)
|
|
139
|
+
path = f"/api/0/issues/{args.issue_id}/events/"
|
|
140
|
+
events = paged_get(base_url, path, {}, token, limit)
|
|
141
|
+
return events
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def handle_event_detail(args, token, base_url):
|
|
145
|
+
require_org_project(args.org, args.project)
|
|
146
|
+
path = f"/api/0/projects/{args.org}/{args.project}/events/{args.event_id}/"
|
|
147
|
+
url = build_url(base_url, path)
|
|
148
|
+
data, _ = request_json(url, token)
|
|
149
|
+
if data and not args.include_entries:
|
|
150
|
+
data = dict(data)
|
|
151
|
+
data.pop("entries", None)
|
|
152
|
+
return data
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def build_parser():
|
|
156
|
+
parser = argparse.ArgumentParser(
|
|
157
|
+
description="Read-only Sentry API helper for issues and events"
|
|
158
|
+
)
|
|
159
|
+
parser.add_argument(
|
|
160
|
+
"--base-url",
|
|
161
|
+
default=os.environ.get("SENTRY_BASE_URL", DEFAULT_BASE_URL),
|
|
162
|
+
help="Sentry base URL (default: https://sentry.io)",
|
|
163
|
+
)
|
|
164
|
+
parser.add_argument(
|
|
165
|
+
"--org",
|
|
166
|
+
default=os.environ.get("SENTRY_ORG", DEFAULT_ORG),
|
|
167
|
+
help="Sentry org slug",
|
|
168
|
+
)
|
|
169
|
+
parser.add_argument(
|
|
170
|
+
"--project",
|
|
171
|
+
default=os.environ.get("SENTRY_PROJECT", DEFAULT_PROJECT),
|
|
172
|
+
help="Sentry project slug",
|
|
173
|
+
)
|
|
174
|
+
parser.add_argument(
|
|
175
|
+
"--no-redact",
|
|
176
|
+
action="store_true",
|
|
177
|
+
help="Do not redact PII in output",
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
181
|
+
|
|
182
|
+
list_issues = subparsers.add_parser("list-issues", help="List issues")
|
|
183
|
+
list_issues.add_argument("--time-range", default="24h")
|
|
184
|
+
list_issues.add_argument("--environment", default="prod")
|
|
185
|
+
list_issues.add_argument("--query", default="")
|
|
186
|
+
list_issues.add_argument("--limit", type=int, default=20)
|
|
187
|
+
|
|
188
|
+
issue_detail = subparsers.add_parser("issue-detail", help="Issue detail")
|
|
189
|
+
issue_detail.add_argument("issue_id")
|
|
190
|
+
|
|
191
|
+
issue_events = subparsers.add_parser("issue-events", help="Issue events")
|
|
192
|
+
issue_events.add_argument("issue_id")
|
|
193
|
+
issue_events.add_argument("--limit", type=int, default=20)
|
|
194
|
+
|
|
195
|
+
event_detail = subparsers.add_parser("event-detail", help="Event detail")
|
|
196
|
+
event_detail.add_argument("event_id")
|
|
197
|
+
event_detail.add_argument(
|
|
198
|
+
"--include-entries",
|
|
199
|
+
action="store_true",
|
|
200
|
+
help="Include event entries (may contain stack traces)",
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
return parser
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def main():
|
|
207
|
+
parser = build_parser()
|
|
208
|
+
args = parser.parse_args()
|
|
209
|
+
|
|
210
|
+
token = os.environ.get("SENTRY_AUTH_TOKEN")
|
|
211
|
+
if not token:
|
|
212
|
+
raise RuntimeError("Missing SENTRY_AUTH_TOKEN env var.")
|
|
213
|
+
|
|
214
|
+
base_url = args.base_url
|
|
215
|
+
|
|
216
|
+
if args.command == "list-issues":
|
|
217
|
+
data = handle_list_issues(args, token, base_url)
|
|
218
|
+
elif args.command == "issue-detail":
|
|
219
|
+
data = handle_issue_detail(args, token, base_url)
|
|
220
|
+
elif args.command == "issue-events":
|
|
221
|
+
data = handle_issue_events(args, token, base_url)
|
|
222
|
+
elif args.command == "event-detail":
|
|
223
|
+
data = handle_event_detail(args, token, base_url)
|
|
224
|
+
else:
|
|
225
|
+
raise RuntimeError(f"Unknown command: {args.command}")
|
|
226
|
+
|
|
227
|
+
if not args.no_redact:
|
|
228
|
+
data = redact_data(data)
|
|
229
|
+
|
|
230
|
+
print(json.dumps(data, indent=2, sort_keys=True))
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
if __name__ == "__main__":
|
|
234
|
+
try:
|
|
235
|
+
main()
|
|
236
|
+
except RuntimeError as exc:
|
|
237
|
+
print(f"Error: {exc}", file=sys.stderr)
|
|
238
|
+
sys.exit(1)
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: show-me
|
|
3
|
+
description: Help the user understand the current topic visually with concise diagrams, code-shape sketches, and focused HTML artifacts.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Help the user understand the current topic of conversation visually. Skip the preamble and keep prose brief. Pick the smallest view that makes the key point clear.
|
|
7
|
+
|
|
8
|
+
- Show logic or an algorithm as pseudocode:
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
on(save)
|
|
12
|
+
if content is unchanged
|
|
13
|
+
return cached result
|
|
14
|
+
write new content
|
|
15
|
+
return fresh result
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- Show runtime control flow as a call tree:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
submitForm
|
|
22
|
+
createSession
|
|
23
|
+
persistPrompt
|
|
24
|
+
launchAgent
|
|
25
|
+
navigateToSession
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- Show UI structure as a component tree, including state and module boundaries that matter:
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
<SessionPage> (apps/example/src/routes/session.tsx)
|
|
32
|
+
useSessionEvents()
|
|
33
|
+
<SessionToolbar>
|
|
34
|
+
<RunSkillButton> (packages/ui)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- Show file responsibility or a broad refactor as a shallow file tree:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
src/
|
|
41
|
+
├── commands/ # parses user actions
|
|
42
|
+
├── sessions/ # owns session state
|
|
43
|
+
└── transport/ # sends API requests
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- Show component interaction, control flow, or data flow with Mermaid:
|
|
47
|
+
|
|
48
|
+
```mermaid
|
|
49
|
+
sequenceDiagram
|
|
50
|
+
participant User
|
|
51
|
+
participant UI
|
|
52
|
+
participant Daemon
|
|
53
|
+
User->>UI: choose command
|
|
54
|
+
UI->>Daemon: send expanded prompt
|
|
55
|
+
Daemon-->>UI: stream result
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- Use `diff` when the point is what changes and the surrounding shape already exists. Match the diff shape to the topic.
|
|
59
|
+
|
|
60
|
+
For a component change:
|
|
61
|
+
|
|
62
|
+
```diff
|
|
63
|
+
<SessionPage>
|
|
64
|
+
useSessionEvents()
|
|
65
|
+
<SessionToolbar>
|
|
66
|
+
+ <RunSkillButton />
|
|
67
|
+
<SessionTimeline>
|
|
68
|
+
+ <SkillResultCard />
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
For a file-layout change:
|
|
72
|
+
|
|
73
|
+
```diff
|
|
74
|
+
src/
|
|
75
|
+
├── commands/
|
|
76
|
+
+│ └── show-me.ts # expands the slash command
|
|
77
|
+
├── sessions/
|
|
78
|
+
-└── transport.ts
|
|
79
|
+
+└── transport/
|
|
80
|
+
+ ├── client.ts
|
|
81
|
+
+ └── stream.ts
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
For a call-tree or call-stack change:
|
|
85
|
+
|
|
86
|
+
```diff
|
|
87
|
+
submitForm
|
|
88
|
+
createSession
|
|
89
|
+
persistPrompt
|
|
90
|
+
+ expandSkillMention
|
|
91
|
+
launchAgent
|
|
92
|
+
- navigateToSession
|
|
93
|
+
+ navigateToSession
|
|
94
|
+
+ subscribeToEvents
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
For a state or control-flow change:
|
|
98
|
+
|
|
99
|
+
```diff
|
|
100
|
+
on(save)
|
|
101
|
+
- write content
|
|
102
|
+
+ if content is unchanged
|
|
103
|
+
+ return cached result
|
|
104
|
+
+ write new content
|
|
105
|
+
+ invalidate cache
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- Show the whole block when most of it is new, when omitted context would hide ownership or order, or when the user needs a copyable target shape:
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
function expandSkill(command: string): string {
|
|
112
|
+
const skillName = command.slice(1)
|
|
113
|
+
return `use the ${skillName} skill`
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
- For a visual UI, layout, state comparison, or concept too dense for Mermaid, write one focused HTML file — a diagram, an infographic, or a short slide deck, whichever fits the point. Match the product's colors, type, spacing, and components; use real labels and data; support desktop and mobile. Then open it for the user:
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
Bash(open path/to/show-me-{description}.html)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### guidance
|
|
124
|
+
|
|
125
|
+
Place each visual next to the short text it supports. Keep only the calls, files, props, states, and boundaries needed to answer the user's current question or the options to resolve the current discussion point.
|
|
126
|
+
|
|
127
|
+
You may use one of these, you may use several, it is unlikely you will use all of them. Use your judgement and don't overwhelm the user.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Show Me Examples
|
|
2
|
+
|
|
3
|
+
## Explain a login flow
|
|
4
|
+
|
|
5
|
+
User: "How does login actually work here?"
|
|
6
|
+
|
|
7
|
+
Good agent behavior:
|
|
8
|
+
|
|
9
|
+
- Recognize this is a control-flow question and show a call tree of the involved functions.
|
|
10
|
+
- Keep the diagram to the calls that matter for the question.
|
|
11
|
+
- Place a one-line summary above the tree and skip the preamble.
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
handleLogin
|
|
15
|
+
validateCredentials
|
|
16
|
+
hashPassword
|
|
17
|
+
lookupUser
|
|
18
|
+
createSession
|
|
19
|
+
persistSession
|
|
20
|
+
navigateToDashboard
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Clarify a file-layout change
|
|
24
|
+
|
|
25
|
+
User: "What would moving the API client out of `transport.ts` into its own folder change?"
|
|
26
|
+
|
|
27
|
+
Good agent behavior:
|
|
28
|
+
|
|
29
|
+
- Use a `diff` of the shallow file tree so the shape that already exists stays visible.
|
|
30
|
+
- Highlight only the moved and added files.
|
|
31
|
+
|
|
32
|
+
```diff
|
|
33
|
+
src/
|
|
34
|
+
├── commands/
|
|
35
|
+
+│ └── show-me.ts # expands the slash command
|
|
36
|
+
├── sessions/
|
|
37
|
+
-└── transport.ts
|
|
38
|
+
+└── transport/
|
|
39
|
+
+ ├── client.ts
|
|
40
|
+
+ └── stream.ts
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Compare two approaches to caching
|
|
44
|
+
|
|
45
|
+
User: "Should we cache the result on every save?"
|
|
46
|
+
|
|
47
|
+
Good agent behavior:
|
|
48
|
+
|
|
49
|
+
- Show the state change as a `diff` of the logic, contrasting the current write path with the proposed cache.
|
|
50
|
+
- Keep prose brief and end with the trade-off in one sentence.
|
|
51
|
+
|
|
52
|
+
```diff
|
|
53
|
+
on(save)
|
|
54
|
+
- write content
|
|
55
|
+
+ if content is unchanged
|
|
56
|
+
+ return cached result
|
|
57
|
+
+ write new content
|
|
58
|
+
+ invalidate cache
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Show component interaction for a dense UI
|
|
62
|
+
|
|
63
|
+
User: "Walk me through what happens when the user picks a command in the TUI."
|
|
64
|
+
|
|
65
|
+
Good agent behavior:
|
|
66
|
+
|
|
67
|
+
- Use a Mermaid sequence diagram because the interaction crosses UI and daemon boundaries.
|
|
68
|
+
- Include only the participants needed to answer the question.
|
|
69
|
+
|
|
70
|
+
```mermaid
|
|
71
|
+
sequenceDiagram
|
|
72
|
+
participant User
|
|
73
|
+
participant UI
|
|
74
|
+
participant Daemon
|
|
75
|
+
User->>UI: choose command
|
|
76
|
+
UI->>Daemon: send expanded prompt
|
|
77
|
+
Daemon-->>UI: stream result
|
|
78
|
+
```
|