pi-agent-toolkit 0.1.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.
Files changed (53) hide show
  1. package/dist/dotfiles/AGENTS.md +197 -0
  2. package/dist/dotfiles/APPEND_SYSTEM.md +78 -0
  3. package/dist/dotfiles/agent-modes.json +12 -0
  4. package/dist/dotfiles/agent-skills/exa-search/.env.example +4 -0
  5. package/dist/dotfiles/agent-skills/exa-search/SKILL.md +234 -0
  6. package/dist/dotfiles/agent-skills/exa-search/scripts/exa-api.cjs +197 -0
  7. package/dist/dotfiles/auth.json.template +5 -0
  8. package/dist/dotfiles/damage-control-rules.yaml +318 -0
  9. package/dist/dotfiles/extensions/btw.ts +1031 -0
  10. package/dist/dotfiles/extensions/commit-approval.ts +590 -0
  11. package/dist/dotfiles/extensions/context.ts +578 -0
  12. package/dist/dotfiles/extensions/control.ts +1748 -0
  13. package/dist/dotfiles/extensions/damage-control/index.ts +543 -0
  14. package/dist/dotfiles/extensions/damage-control/node_modules/.package-lock.json +22 -0
  15. package/dist/dotfiles/extensions/damage-control/package-lock.json +28 -0
  16. package/dist/dotfiles/extensions/damage-control/package.json +7 -0
  17. package/dist/dotfiles/extensions/dirty-repo-guard.ts +56 -0
  18. package/dist/dotfiles/extensions/exa-enforce.ts +51 -0
  19. package/dist/dotfiles/extensions/exa-search-tool.ts +384 -0
  20. package/dist/dotfiles/extensions/execute-command/index.ts +82 -0
  21. package/dist/dotfiles/extensions/files.ts +1112 -0
  22. package/dist/dotfiles/extensions/loop.ts +446 -0
  23. package/dist/dotfiles/extensions/pr-approval.ts +730 -0
  24. package/dist/dotfiles/extensions/qna-interactive.ts +532 -0
  25. package/dist/dotfiles/extensions/question-mode.ts +242 -0
  26. package/dist/dotfiles/extensions/require-session-name-on-exit.ts +141 -0
  27. package/dist/dotfiles/extensions/review.ts +2091 -0
  28. package/dist/dotfiles/extensions/session-breakdown.ts +1629 -0
  29. package/dist/dotfiles/extensions/term-notify.ts +150 -0
  30. package/dist/dotfiles/extensions/tilldone.ts +527 -0
  31. package/dist/dotfiles/extensions/todos.ts +2082 -0
  32. package/dist/dotfiles/extensions/tools.ts +146 -0
  33. package/dist/dotfiles/extensions/uv.ts +123 -0
  34. package/dist/dotfiles/global-skills/brainstorm/SKILL.md +10 -0
  35. package/dist/dotfiles/global-skills/cli-detector/SKILL.md +192 -0
  36. package/dist/dotfiles/global-skills/gh-issue-creator/SKILL.md +173 -0
  37. package/dist/dotfiles/global-skills/google-chat-cards-v2/SKILL.md +237 -0
  38. package/dist/dotfiles/global-skills/google-chat-cards-v2/references/bridge_tap_implementation.md +466 -0
  39. package/dist/dotfiles/global-skills/technical-docs/SKILL.md +204 -0
  40. package/dist/dotfiles/global-skills/technical-docs/references/diagrams.md +168 -0
  41. package/dist/dotfiles/global-skills/technical-docs/references/examples.md +449 -0
  42. package/dist/dotfiles/global-skills/technical-docs/scripts/validate_docs.py +352 -0
  43. package/dist/dotfiles/global-skills/whats-new/SKILL.md +159 -0
  44. package/dist/dotfiles/intercepted-commands/pip +7 -0
  45. package/dist/dotfiles/intercepted-commands/pip3 +7 -0
  46. package/dist/dotfiles/intercepted-commands/poetry +10 -0
  47. package/dist/dotfiles/intercepted-commands/python +104 -0
  48. package/dist/dotfiles/intercepted-commands/python3 +104 -0
  49. package/dist/dotfiles/mcp.json.template +32 -0
  50. package/dist/dotfiles/models.json +27 -0
  51. package/dist/dotfiles/settings.json +25 -0
  52. package/dist/index.js +1344 -0
  53. package/package.json +34 -0
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Tools Extension
3
+ *
4
+ * Provides a /tools command to enable/disable tools interactively.
5
+ * Tool selection persists across session reloads and respects branch navigation.
6
+ *
7
+ * Usage:
8
+ * 1. Copy this file to ~/.pi/agent/extensions/ or your project's .pi/extensions/
9
+ * 2. Use /tools to open the tool selector
10
+ */
11
+
12
+ import type { ExtensionAPI, ExtensionContext, ToolInfo } from "@mariozechner/pi-coding-agent";
13
+ import { getSettingsListTheme } from "@mariozechner/pi-coding-agent";
14
+ import { Container, type SettingItem, SettingsList } from "@mariozechner/pi-tui";
15
+
16
+ // State persisted to session
17
+ interface ToolsState {
18
+ enabledTools: string[];
19
+ }
20
+
21
+ export default function toolsExtension(pi: ExtensionAPI) {
22
+ // Track enabled tools
23
+ let enabledTools: Set<string> = new Set();
24
+ let allTools: ToolInfo[] = [];
25
+
26
+ // Persist current state
27
+ function persistState() {
28
+ pi.appendEntry<ToolsState>("tools-config", {
29
+ enabledTools: Array.from(enabledTools),
30
+ });
31
+ }
32
+
33
+ // Apply current tool selection
34
+ function applyTools() {
35
+ pi.setActiveTools(Array.from(enabledTools));
36
+ }
37
+
38
+ // Find the last tools-config entry in the current branch
39
+ function restoreFromBranch(ctx: ExtensionContext) {
40
+ allTools = pi.getAllTools();
41
+
42
+ // Get entries in current branch only
43
+ const branchEntries = ctx.sessionManager.getBranch();
44
+ let savedTools: string[] | undefined;
45
+
46
+ for (const entry of branchEntries) {
47
+ if (entry.type === "custom" && entry.customType === "tools-config") {
48
+ const data = entry.data as ToolsState | undefined;
49
+ if (data?.enabledTools) {
50
+ savedTools = data.enabledTools;
51
+ }
52
+ }
53
+ }
54
+
55
+ if (savedTools) {
56
+ // Restore saved tool selection (filter to only tools that still exist)
57
+ const allToolNames = allTools.map((t) => t.name);
58
+ enabledTools = new Set(savedTools.filter((t: string) => allToolNames.includes(t)));
59
+ applyTools();
60
+ } else {
61
+ // No saved state - sync with currently active tools
62
+ enabledTools = new Set(pi.getActiveTools());
63
+ }
64
+ }
65
+
66
+ // Register /tools command
67
+ pi.registerCommand("tools", {
68
+ description: "Enable/disable tools",
69
+ handler: async (_args, ctx) => {
70
+ // Refresh tool list
71
+ allTools = pi.getAllTools();
72
+
73
+ await ctx.ui.custom((tui, theme, _kb, done) => {
74
+ // Build settings items for each tool
75
+ const items: SettingItem[] = allTools.map((tool) => ({
76
+ id: tool.name,
77
+ label: tool.name,
78
+ currentValue: enabledTools.has(tool.name) ? "enabled" : "disabled",
79
+ values: ["enabled", "disabled"],
80
+ }));
81
+
82
+ const container = new Container();
83
+ container.addChild(
84
+ new (class {
85
+ render(_width: number) {
86
+ return [theme.fg("accent", theme.bold("Tool Configuration")), ""];
87
+ }
88
+ invalidate() {}
89
+ })(),
90
+ );
91
+
92
+ const settingsList = new SettingsList(
93
+ items,
94
+ Math.min(items.length + 2, 15),
95
+ getSettingsListTheme(),
96
+ (id, newValue) => {
97
+ // Update enabled state and apply immediately
98
+ if (newValue === "enabled") {
99
+ enabledTools.add(id);
100
+ } else {
101
+ enabledTools.delete(id);
102
+ }
103
+ applyTools();
104
+ persistState();
105
+ },
106
+ () => {
107
+ // Close dialog
108
+ done(undefined);
109
+ },
110
+ );
111
+
112
+ container.addChild(settingsList);
113
+
114
+ const component = {
115
+ render(width: number) {
116
+ return container.render(width);
117
+ },
118
+ invalidate() {
119
+ container.invalidate();
120
+ },
121
+ handleInput(data: string) {
122
+ settingsList.handleInput?.(data);
123
+ tui.requestRender();
124
+ },
125
+ };
126
+
127
+ return component;
128
+ });
129
+ },
130
+ });
131
+
132
+ // Restore state on session start
133
+ pi.on("session_start", async (_event, ctx) => {
134
+ restoreFromBranch(ctx);
135
+ });
136
+
137
+ // Restore state when navigating the session tree
138
+ pi.on("session_tree", async (_event, ctx) => {
139
+ restoreFromBranch(ctx);
140
+ });
141
+
142
+ // Restore state after forking
143
+ pi.on("session_fork", async (_event, ctx) => {
144
+ restoreFromBranch(ctx);
145
+ });
146
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * UV Extension - Redirects Python tooling to uv equivalents
3
+ *
4
+ * This extension wraps the bash tool to prepend intercepted-commands to PATH,
5
+ * which contains shim scripts that intercept common Python tooling commands
6
+ * and redirect agents to use uv instead.
7
+ *
8
+ * Intercepted commands:
9
+ * - pip/pip3: Blocked with suggestions to use `uv add` or `uv run --with`
10
+ * - poetry: Blocked with uv equivalents (uv init, uv add, uv sync, uv run)
11
+ * - python/python3: Redirected through `uv run` to a real interpreter path,
12
+ * with special handling to block `python -m pip`, `python -m venv`, and
13
+ * `python -m py_compile`
14
+ *
15
+ * The shim scripts are located in the intercepted-commands directory and
16
+ * provide helpful error messages with the equivalent uv commands.
17
+ *
18
+ * Note: PATH shims are bypassable via explicit interpreter paths
19
+ * (for example `.venv/bin/python`). To close that gap, this extension also
20
+ * blocks disallowed invocations at bash spawn time.
21
+ */
22
+
23
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
24
+ import { createBashTool } from "@mariozechner/pi-coding-agent";
25
+ import { dirname, join } from "path";
26
+ import { fileURLToPath } from "url";
27
+
28
+ const __dirname = dirname(fileURLToPath(import.meta.url));
29
+ const interceptedCommandsPath = join(__dirname, "..", "intercepted-commands");
30
+
31
+ function getBlockedCommandMessage(command: string): string | null {
32
+ // Match commands at the start of a shell segment (start/newline/; /&& /|| /|)
33
+ const pipCommandPattern = /(?:^|\n|[;|&]{1,2})\s*(?:\S+\/)?pip\s*(?:$|\s)/m;
34
+ const pip3CommandPattern = /(?:^|\n|[;|&]{1,2})\s*(?:\S+\/)?pip3\s*(?:$|\s)/m;
35
+ const poetryCommandPattern = /(?:^|\n|[;|&]{1,2})\s*(?:\S+\/)?poetry\s*(?:$|\s)/m;
36
+
37
+ // Match python invocations including explicit paths like .venv/bin/python
38
+ // and .venv/bin/python3.12.
39
+ const pythonPipPattern =
40
+ /(?:^|\n|[;|&]{1,2})\s*(?:\S+\/)?python(?:3(?:\.\d+)?)?\b[^\n;|&]*(?:\s-m\s*pip\b|\s-mpip\b)/m;
41
+ const pythonVenvPattern =
42
+ /(?:^|\n|[;|&]{1,2})\s*(?:\S+\/)?python(?:3(?:\.\d+)?)?\b[^\n;|&]*(?:\s-m\s*venv\b|\s-mvenv\b)/m;
43
+ const pythonPyCompilePattern =
44
+ /(?:^|\n|[;|&]{1,2})\s*(?:\S+\/)?python(?:3(?:\.\d+)?)?\b[^\n;|&]*(?:\s-m\s*py_compile\b|\s-mpy_compile\b)/m;
45
+
46
+ if (pipCommandPattern.test(command)) {
47
+ return [
48
+ "Error: pip is disabled. Use uv instead:",
49
+ "",
50
+ " To install a package for a script: uv run --with PACKAGE python script.py",
51
+ " To add a dependency to the project: uv add PACKAGE",
52
+ "",
53
+ ].join("\n");
54
+ }
55
+
56
+ if (pip3CommandPattern.test(command)) {
57
+ return [
58
+ "Error: pip3 is disabled. Use uv instead:",
59
+ "",
60
+ " To install a package for a script: uv run --with PACKAGE python script.py",
61
+ " To add a dependency to the project: uv add PACKAGE",
62
+ "",
63
+ ].join("\n");
64
+ }
65
+
66
+ if (poetryCommandPattern.test(command)) {
67
+ return [
68
+ "Error: poetry is disabled. Use uv instead:",
69
+ "",
70
+ " To initialize a project: uv init",
71
+ " To add a dependency: uv add PACKAGE",
72
+ " To sync dependencies: uv sync",
73
+ " To run commands: uv run COMMAND",
74
+ "",
75
+ ].join("\n");
76
+ }
77
+
78
+ if (pythonPipPattern.test(command)) {
79
+ return [
80
+ "Error: 'python -m pip' is disabled. Use uv instead:",
81
+ "",
82
+ " To install a package for a script: uv run --with PACKAGE python script.py",
83
+ " To add a dependency to the project: uv add PACKAGE",
84
+ "",
85
+ ].join("\n");
86
+ }
87
+
88
+ if (pythonVenvPattern.test(command)) {
89
+ return [
90
+ "Error: 'python -m venv' is disabled. Use uv instead:",
91
+ "",
92
+ " To create a virtual environment: uv venv",
93
+ "",
94
+ ].join("\n");
95
+ }
96
+
97
+ if (pythonPyCompilePattern.test(command)) {
98
+ return [
99
+ "Error: 'python -m py_compile' is disabled because it writes .pyc files to __pycache__.",
100
+ "",
101
+ " To verify syntax without bytecode output: uv run python -m ast path/to/file.py >/dev/null",
102
+ "",
103
+ ].join("\n");
104
+ }
105
+
106
+ return null;
107
+ }
108
+
109
+ export default function (pi: ExtensionAPI) {
110
+ const cwd = process.cwd();
111
+ const bashTool = createBashTool(cwd, {
112
+ commandPrefix: `export PATH="${interceptedCommandsPath}:$PATH"`,
113
+ spawnHook: (ctx) => {
114
+ const blockedMessage = getBlockedCommandMessage(ctx.command);
115
+ if (blockedMessage) {
116
+ throw new Error(blockedMessage);
117
+ }
118
+ return ctx;
119
+ },
120
+ });
121
+
122
+ pi.registerTool(bashTool);
123
+ }
@@ -0,0 +1,10 @@
1
+ ---
2
+ name: brainstorm
3
+ description: Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, or mentions "brainstorm".
4
+ ---
5
+
6
+ Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.
7
+
8
+ Ask the questions one at a time.
9
+
10
+ If a question can be answered by exploring the codebase, explore the codebase instead.
@@ -0,0 +1,192 @@
1
+ ---
2
+ name: cli-detector
3
+ description: >
4
+ Scan a repository to discover all external SaaS tools and services it integrates with,
5
+ then determine whether each has an official CLI. Use this skill whenever the user asks
6
+ to find CLIs for their project, audit third-party service integrations, discover what
7
+ external services a codebase depends on, check for official CLI tools, or wants to know
8
+ "what services does this repo use." Also trigger when the user asks about automating
9
+ service management, scripting deployments, or wants to interact with their project's
10
+ services from the terminal.
11
+ ---
12
+
13
+ # CLI Detector
14
+
15
+ Analyze a repository to identify every external SaaS service it integrates with, then
16
+ research whether each service provides an official CLI tool.
17
+
18
+ The workflow has three phases: **Detect**, **Verify**, **Report**. Do not skip or
19
+ reorder these phases.
20
+
21
+ ## Phase 1: Detect services
22
+
23
+ Scan the repository using all applicable detection vectors below. Each vector catches
24
+ services the others miss, so work through every one that applies to this project's
25
+ language ecosystem.
26
+
27
+ ### What counts as an "external service"
28
+
29
+ An external service is a hosted platform or SaaS product that the application connects
30
+ to over the network. The company behind it manages the infrastructure.
31
+
32
+ **Include:** Stripe, Sentry, Clerk, Auth0, Vercel, AWS S3, Twilio, SendGrid, Resend,
33
+ Datadog, LaunchDarkly, Algolia, Supabase, Neon, PlanetScale, Upstash, DigitalOcean,
34
+ Cloudflare, Firebase, GitHub (as a service), Netlify, Fly.io, Render, Railway, etc.
35
+
36
+ **Exclude (these are never external services):**
37
+ - Generic database clients: `mysql2`, `pg`, `psycopg2`, `database/sql`, `SQLAlchemy`
38
+ - Generic protocols: SSH libraries, HTTP clients (`axios`, `requests`, `fetch`)
39
+ - Frameworks: Next.js, Django, Rails, Express, FastAPI
40
+ - ORMs: Drizzle, Prisma, TypeORM, ActiveRecord
41
+ - UI libraries: React, Vue, Tailwind, Bootstrap
42
+ - Build tools, runtimes, test runners, linters, formatters
43
+
44
+ The test: if removing the integration means losing access to a *third-party managed
45
+ platform* (not just a protocol or library), it is an external service.
46
+
47
+ ### Vector 1: Package manager manifests
48
+
49
+ Read dependency files for SDK packages from known service vendors.
50
+
51
+ | Ecosystem | Files |
52
+ |-----------|-------|
53
+ | Node.js / TypeScript | `package.json` |
54
+ | Python | `pyproject.toml`, `requirements.txt`, `setup.py`, `Pipfile` |
55
+ | Go | `go.mod` |
56
+ | Ruby | `Gemfile` |
57
+ | Rust | `Cargo.toml` |
58
+ | Java / Kotlin | `build.gradle`, `pom.xml` |
59
+ | PHP | `composer.json` |
60
+ | .NET | `*.csproj`, `packages.config` |
61
+
62
+ Vendor-namespaced packages are strong signals: `@sentry/nextjs`, `@clerk/nextjs`,
63
+ `stripe`, `boto3`, `google-cloud-storage`.
64
+
65
+ ### Vector 2: Environment variables
66
+
67
+ Search source code for env var access patterns and collect all variable names.
68
+
69
+ | Language | Search pattern |
70
+ |----------|---------------|
71
+ | Node.js / TypeScript | `process.env.VARIABLE_NAME` |
72
+ | Python | `os.environ`, `os.getenv()` |
73
+ | Go | `os.Getenv("VARIABLE")` |
74
+ | Ruby | `ENV["VARIABLE"]`, `ENV.fetch` |
75
+
76
+ Also check `.env.example`, `.env.sample`, `.env.template` files.
77
+
78
+ Variable names reveal services: `STRIPE_SECRET_KEY` -> Stripe, `SENTRY_DSN` -> Sentry,
79
+ `CLERK_SECRET_KEY` -> Clerk, `RESEND_API_KEY` -> Resend, `DO_API_TOKEN` -> DigitalOcean,
80
+ `UPSTASH_REDIS_REST_URL` -> Upstash, `AWS_ACCESS_KEY_ID` -> AWS, etc.
81
+
82
+ ### Vector 3: Configuration files
83
+
84
+ Service-specific config files at the project root:
85
+
86
+ `sentry.*.config.ts` -> Sentry, `vercel.json` / `.vercel/` -> Vercel,
87
+ `firebase.json` -> Firebase, `netlify.toml` -> Netlify, `fly.toml` -> Fly.io,
88
+ `wrangler.toml` -> Cloudflare Workers, `serverless.yml` -> check provider field,
89
+ `render.yaml` -> Render, `railway.json` -> Railway
90
+
91
+ ### Vector 4: Source code imports and API URLs
92
+
93
+ Search for direct SDK imports and hardcoded API base URLs:
94
+
95
+ ```bash
96
+ # Service SDK imports (adapt patterns to the project's language)
97
+ grep -r "from '@sentry\|from \"@sentry\|require('@sentry" src/
98
+ grep -r "api.digitalocean.com\|api.stripe.com\|api.sendgrid.com" src/
99
+ ```
100
+
101
+ ### Vector 5: Implicit / indirect signals
102
+
103
+ Some services leave clues without explicit SDK imports. **Actively search** for these
104
+ patterns rather than waiting to stumble on them:
105
+
106
+ ```bash
107
+ # Vercel signals
108
+ grep -r "maxDuration" src/ --include="*.ts" --include="*.tsx" -l
109
+ grep -r "CRON_SECRET" src/ --include="*.ts" --include="*.tsx" -l
110
+ ls vercel.json .vercel/ 2>/dev/null
111
+
112
+ # Heroku signals
113
+ ls Procfile app.json 2>/dev/null
114
+
115
+ # Hosting platform from git remote
116
+ git remote -v 2>/dev/null
117
+ ```
118
+
119
+ - **Vercel**: `maxDuration` exports in API route files are Vercel-specific serverless
120
+ config. `CRON_SECRET` is a Vercel Cron Jobs feature. `@vercel/*` packages.
121
+ - **GitHub**: git remote pointing to github.com, `.github/` directory with workflows.
122
+ - **GitLab**: git remote pointing to gitlab.com, `.gitlab-ci.yml`.
123
+ - **Heroku**: `Procfile`, `app.json`.
124
+
125
+ ### Vector 6: CI/CD pipelines
126
+
127
+ Scan pipeline configs for service references not visible in application code:
128
+
129
+ - `.github/workflows/*.yml`: `uses:` actions, secrets references
130
+ - `.gitlab-ci.yml`, `.circleci/config.yml`, `Jenkinsfile`
131
+
132
+ ## Phase 2: Verify CLI existence with Exa
133
+
134
+ This phase is mandatory. Do not determine CLI status from memory or training data.
135
+
136
+ Service CLIs are launched and deprecated frequently. Training data is often wrong
137
+ about whether a specific service has a CLI, especially for newer or smaller services.
138
+ The only reliable way to determine CLI status is to check externally.
139
+
140
+ ### What qualifies as an "official CLI"
141
+
142
+ All four criteria must be met:
143
+ - Created and maintained by the service provider (not a community wrapper)
144
+ - Purpose-built to interact with that specific service
145
+ - Has official documentation from the provider
146
+ - Available through standard package managers (npm, brew, apt, pip, etc.)
147
+
148
+ ### Verification procedure
149
+
150
+ For **every** service identified in Phase 1, call `exa_search` with the `answer`
151
+ endpoint:
152
+
153
+ ```
154
+ exa_search endpoint=answer query="Does [SERVICE_NAME] have an official CLI tool?"
155
+ ```
156
+
157
+ This returns the CLI name, install command, and source links. If the answer is
158
+ ambiguous or uncertain, follow up with a targeted doc-site search:
159
+
160
+ ```
161
+ exa_search endpoint=search query="[SERVICE_NAME] CLI"
162
+ includeDomains=["official-docs-domain.com"]
163
+ ```
164
+
165
+ Do not mark any service as "No CLI" without first running an Exa query for it.
166
+ Even services that seem unlikely to have a CLI (auth providers, email services,
167
+ newer startups) should be verified. CLI tooling is expanding rapidly and assumptions
168
+ from training data are frequently wrong.
169
+
170
+ ## Phase 3: Report
171
+
172
+ Present findings in two tables.
173
+
174
+ ### Primary table: services with CLI status
175
+
176
+ | # | Service | Usage in This Repo | Official CLI? | CLI Name | Install |
177
+ |---|---------|-------------------|:---:|----------|---------|
178
+ | 1 | **Stripe** | Payment processing (`stripe` SDK, `STRIPE_SECRET_KEY`) | Yes | `stripe` | `brew install stripe/stripe-cli/stripe` |
179
+ | 2 | **SomeService** | Feature flags (`SOMESERVICE_API_KEY`) | No | N/A | N/A |
180
+
181
+ The "Usage in This Repo" column should include:
182
+ - What the service is used for (brief)
183
+ - How it was detected (SDK name, env var, config file)
184
+
185
+ ### Secondary table: excluded items
186
+
187
+ | Tool | Reason excluded |
188
+ |------|----------------|
189
+ | MySQL (`mysql2`) | Generic database client, not an external service |
190
+
191
+ This table shows the user you considered these tools and correctly filtered them.
192
+ It demonstrates thoroughness.
@@ -0,0 +1,173 @@
1
+ ---
2
+ name: gh-issue-creator
3
+ description: Use when creating GitHub issues via the `gh` CLI. Covers body structure, issue type classification (bug, feature, task), label selection, and consistent formatting. Triggers on requests to file, create, open, or submit a GitHub issue.
4
+ ---
5
+
6
+ # GitHub Issue Creator
7
+
8
+ Create well-structured GitHub issues using the `gh` CLI with consistent formatting, appropriate labels, and type-specific body templates.
9
+
10
+ ## Ground rules
11
+
12
+ - Always use `gh issue create` with `--title`, `--body`, and `--label` flags
13
+ - Auto-detect the repo from the current git context (do not ask the user to specify unless `gh` cannot resolve it)
14
+ - Never include AI attribution or emojis in issue titles or bodies
15
+ - Use imperative mood in titles (e.g., "Add retry logic" not "Added retry logic")
16
+
17
+ ## Issue types and label mapping
18
+
19
+ Classify every issue into one of three types based on user intent. Map to the corresponding GitHub label:
20
+
21
+ | User intent | GitHub label | When to use |
22
+ |---|---|---|
23
+ | **Bug** | `bug` | Something is broken, produces wrong results, or crashes |
24
+ | **Feature** | `enhancement` | New capability, improvement, or behavioral change |
25
+ | **Task** | context-dependent | Maintenance, refactoring, docs, infra work, chores |
26
+
27
+ If the user says "feature request", "new feature", or "enhancement", use `enhancement`.
28
+ If the user says "bug", "broken", "regression", or "not working", use `bug`.
29
+ If the user says "task", "chore", "refactor", or "cleanup", pick the most fitting existing label (e.g., `documentation` for docs work) or omit `--label` entirely when nothing fits. Do not force a label.
30
+
31
+ When uncertain, ask the user which type fits before creating the issue.
32
+
33
+ ## Title guidelines
34
+
35
+ - Short and descriptive, max 72 characters
36
+ - Imperative mood: "Add X", "Fix Y", "Update Z"
37
+ - Include the affected area when it adds clarity: "fix(routing): handle missing advertiser ID"
38
+ - No trailing punctuation
39
+
40
+ ## Body structure by type
41
+
42
+ ### Feature request (`enhancement`)
43
+
44
+ ```markdown
45
+ ## Summary
46
+
47
+ One paragraph describing what the feature does and why it matters.
48
+
49
+ ## Motivation
50
+
51
+ - Why this is needed
52
+ - What problem it solves
53
+ - What is painful or missing today
54
+
55
+ ## Proposed Changes
56
+
57
+ ### Before
58
+
59
+ Show the current state -- code, config, architecture, or behavior.
60
+ Use code blocks when showing concrete artifacts.
61
+
62
+ ### After
63
+
64
+ Show the proposed state with the same level of detail.
65
+ Before/after should be directly comparable.
66
+
67
+ ## Implementation Phases
68
+
69
+ Numbered list of major steps if the work spans multiple PRs or stages.
70
+ Skip this section for small, single-PR features.
71
+
72
+ ## Affected Files
73
+
74
+ List the key files or areas of the codebase that will change.
75
+ Group by category (runtime, config, tests, etc.) when helpful.
76
+
77
+ ## Acceptance Criteria
78
+
79
+ - [ ] Checklist of conditions that must be true for the work to be complete
80
+ - [ ] Each item should be independently verifiable
81
+ - [ ] Include both functional and testing criteria
82
+ ```
83
+
84
+ **Optional sections** (include when relevant):
85
+ - **Rollback Strategy** -- for risky or reversible changes
86
+ - **Risks** -- known risks and mitigations
87
+ - **References** -- links to external docs, RFCs, or related issues
88
+
89
+ ### Bug report (`bug`)
90
+
91
+ ```markdown
92
+ ## Summary
93
+
94
+ One paragraph describing the bug and its impact.
95
+
96
+ ## Steps to Reproduce
97
+
98
+ 1. Numbered steps to trigger the bug
99
+ 2. Be specific about inputs, environment, and timing
100
+ 3. Include commands, config snippets, or screenshots as needed
101
+
102
+ ## Expected Behavior
103
+
104
+ What should happen.
105
+
106
+ ## Actual Behavior
107
+
108
+ What happens instead. Include error messages, logs, or stack traces in code blocks.
109
+
110
+ ## Environment
111
+
112
+ - OS / runtime version
113
+ - Relevant dependency versions
114
+ - Any environment-specific context (staging vs prod, specific client config, etc.)
115
+
116
+ ## Possible Cause
117
+
118
+ If known or suspected, describe the likely root cause.
119
+ Skip this section if unknown.
120
+
121
+ ## Acceptance Criteria
122
+
123
+ - [ ] Bug no longer reproduces under the described steps
124
+ - [ ] Regression test added
125
+ ```
126
+
127
+ ### Task (no label or contextual label)
128
+
129
+ ```markdown
130
+ ## Summary
131
+
132
+ One paragraph describing the task and why it needs to happen.
133
+
134
+ ## Context
135
+
136
+ Background information, motivation, or link to the broader initiative.
137
+
138
+ ## Requirements
139
+
140
+ - Bulleted list of what the task must accomplish
141
+ - Be specific and verifiable
142
+
143
+ ## Acceptance Criteria
144
+
145
+ - [ ] Checklist of done conditions
146
+ ```
147
+
148
+ ## Workflow
149
+
150
+ 1. **Determine the issue type** from the user's request or ask if ambiguous
151
+ 2. **Map to the correct label** using the table above
152
+ 3. **Check existing labels** on the repo with `gh label list` to confirm the label exists
153
+ 4. **Gather enough context** -- if the user's request is brief, check the codebase for relevant details (file paths, current behavior, config shapes) before drafting. Do not ask the user for information you can find yourself.
154
+ 5. **Draft the title and body** using the appropriate template
155
+ 6. **Create the issue** -- for short bodies use `gh issue create --title "..." --body "..." --label "..."`. For longer or complex bodies, write to a temp file and use `--body-file` to avoid shell escaping issues.
156
+ 7. **Report the issue URL** back to the user
157
+
158
+ ## Adapting the template
159
+
160
+ The body templates above are starting points. Adjust based on the content:
161
+
162
+ - **Drop empty sections** -- if there is no rollback strategy or the feature is trivial, omit those sections rather than leaving them blank
163
+ - **Add before/after blocks** -- whenever the change involves a concrete artifact (config, API shape, schema, data format), show the before and after states with code blocks
164
+ - **Scale detail to complexity** -- a one-line bug fix needs a shorter body than a multi-phase architectural change
165
+ - **Preserve the user's language** -- if the user provides specific wording or context, use it rather than rephrasing into generic template language
166
+
167
+ ## What NOT to do
168
+
169
+ - Do not create issues without `--title` and `--body` flags (no interactive mode)
170
+ - Do not guess labels that do not exist on the repo
171
+ - Do not include a References section unless the user explicitly provides links or references to include
172
+ - Do not pad the body with boilerplate when the issue is simple
173
+ - Do not ask the user to specify the repo -- detect it from git context