📦 deps(thirdparty): update snapshots
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
---
|
||||
name: stack-feedback
|
||||
version: 0.3.0
|
||||
description: Creates GitHub issues for problems discovered while using @outfitter/* packages. Use when finding bugs, missing features, unclear documentation, or improvement opportunities.
|
||||
context: fork
|
||||
agent: stacker
|
||||
allowed-tools: Bash(gh *) Bash(bun *) Read
|
||||
user-invocable: false
|
||||
---
|
||||
|
||||
# Stack Feedback
|
||||
|
||||
Create GitHub issues on `outfitter-dev/outfitter` for problems discovered while using the stack.
|
||||
|
||||
## When to Use
|
||||
|
||||
Invoke this skill when you discover:
|
||||
- **Bugs** in @outfitter/* packages
|
||||
- **Missing features** that would improve DX
|
||||
- **Unclear documentation** that caused confusion
|
||||
- **Pattern gaps** where guidance is missing
|
||||
- **Ergonomic issues** that made tasks harder than expected
|
||||
|
||||
## Issue Categories
|
||||
|
||||
| Category | Label | Example |
|
||||
|----------|-------|---------|
|
||||
| `bug` | `bug` | Package throws when it should return Result |
|
||||
| `enhancement` | `feature` | Add helper for common pattern |
|
||||
| `docs` | `documentation` | Handler contract docs missing edge case |
|
||||
| `unclear-pattern` | `question` | How to handle X scenario with Result types |
|
||||
| `dx` | `dx` | Error message unclear, hard to debug |
|
||||
| `migration-pattern` | `adoption` | Migration scenario lacks guidance |
|
||||
| `conversion-helper` | `adoption` | Need utility for legacy conversion |
|
||||
| `compatibility` | `adoption` | Breaking change concern |
|
||||
| `migration-docs` | `migration, documentation` | Migration docs gap |
|
||||
|
||||
## Using the Helper Script
|
||||
|
||||
The preferred method for creating issues. The script handles templates, labels, and validation.
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```bash
|
||||
bun plugins/outfitter-stack/skills/stack-feedback/scripts/create-issue.ts \
|
||||
--type bug \
|
||||
--title "Result.unwrap throws on valid input" \
|
||||
--package "@outfitter/contracts" \
|
||||
--description "When calling unwrap on Ok value, it unexpectedly throws" \
|
||||
--actual "Throws TypeError instead of returning value"
|
||||
```
|
||||
|
||||
### Dry-Run Mode (Default)
|
||||
|
||||
By default, the script outputs JSON with the `gh` command without executing it:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "gh issue create --repo outfitter-dev/outfitter --title '[Bug] Result.unwrap throws...' --label bug --label feedback --label source/agent --body '...'",
|
||||
"title": "[Bug] Result.unwrap throws on valid input",
|
||||
"labels": ["bug", "feedback", "source/agent"],
|
||||
"body": "## Package\n\n`@outfitter/contracts`\n..."
|
||||
}
|
||||
```
|
||||
|
||||
### Origin Detection
|
||||
|
||||
The script automatically detects the git origin of the current directory and adds a "Discovered In" section to the issue body with a link to the source repo. This helps track where feedback originates.
|
||||
|
||||
### Submit Mode
|
||||
|
||||
Add `--submit` to actually create the issue:
|
||||
|
||||
```bash
|
||||
bun plugins/outfitter-stack/skills/stack-feedback/scripts/create-issue.ts \
|
||||
--type enhancement \
|
||||
--title "Add Result.tap helper" \
|
||||
--package "@outfitter/contracts" \
|
||||
--description "Helper to run side effects without unwrapping" \
|
||||
--useCase "Logging without breaking method chains" \
|
||||
--submit
|
||||
```
|
||||
|
||||
### View Template Requirements
|
||||
|
||||
Run with just `--type` to see required and optional fields:
|
||||
|
||||
```bash
|
||||
bun plugins/outfitter-stack/skills/stack-feedback/scripts/create-issue.ts --type bug
|
||||
```
|
||||
|
||||
### Available Types
|
||||
|
||||
| Type | Required Fields |
|
||||
|------|-----------------|
|
||||
| `bug` | package, description, actual |
|
||||
| `enhancement` | package, description, useCase |
|
||||
| `docs` | package, description, gap |
|
||||
| `unclear-pattern` | package, description, context |
|
||||
| `dx` | package, description, current |
|
||||
| `migration-pattern` | sourcePattern, description, scenario |
|
||||
| `conversion-helper` | legacyPattern, description, targetPattern |
|
||||
| `compatibility` | package, description, breakingChange |
|
||||
| `migration-docs` | area, description, gap |
|
||||
|
||||
## Manual Issue Creation
|
||||
|
||||
For cases where the script doesn't fit, use `gh` directly:
|
||||
|
||||
```bash
|
||||
gh issue create \
|
||||
--repo outfitter-dev/outfitter \
|
||||
--title "[Bug] Brief description" \
|
||||
--label "bug" \
|
||||
--label "feedback" \
|
||||
--label "source/agent" \
|
||||
--body "$(cat <<'EOF'
|
||||
## Package
|
||||
|
||||
`@outfitter/package-name`
|
||||
|
||||
## Description
|
||||
|
||||
What went wrong or what's missing.
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
What actually happens.
|
||||
|
||||
---
|
||||
|
||||
*Created via `outfitter-stack:stack-feedback` skill*
|
||||
EOF
|
||||
)"
|
||||
```
|
||||
|
||||
## Tracking Feedback
|
||||
|
||||
After creating, track in your project:
|
||||
|
||||
```markdown
|
||||
## Stack Feedback
|
||||
|
||||
- [ ] #123: Result.unwrap throws on valid input — bug
|
||||
```
|
||||
|
||||
## Check Existing Issues
|
||||
|
||||
Before creating a new issue, check if it already exists:
|
||||
|
||||
```bash
|
||||
gh issue list --repo outfitter-dev/outfitter --label feedback
|
||||
gh issue list --repo outfitter-dev/outfitter --search "{{KEYWORDS}}"
|
||||
```
|
||||
|
||||
## Batch Feedback
|
||||
|
||||
If multiple issues have accumulated:
|
||||
|
||||
1. Review all feedback items
|
||||
2. Deduplicate similar issues
|
||||
3. Create issues with cross-references where related
|
||||
4. Update tracking with issue numbers
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Be specific** — Include package, function, and line if known
|
||||
2. **Provide context** — Explain what task led to discovery
|
||||
3. **Include workaround** — If you found one, share it
|
||||
4. **Link related issues** — Reference if similar issues exist
|
||||
5. **Stay constructive** — Focus on improvement, not complaint
|
||||
|
||||
## References
|
||||
|
||||
- [Migration-specific feedback](references/migration-feedback.md)
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
# Migration-Specific Feedback
|
||||
|
||||
When migrating existing code to Outfitter Stack, you may discover issues that are particularly relevant to the migration process.
|
||||
|
||||
## Migration-Specific Categories
|
||||
|
||||
| Category | When to Use |
|
||||
|----------|-------------|
|
||||
| `migration-pattern` | Common migration scenario lacks guidance |
|
||||
| `conversion-helper` | Need a utility to convert from legacy pattern |
|
||||
| `compatibility` | Breaking change or compatibility concern |
|
||||
| `migration-docs` | Migration documentation gap |
|
||||
|
||||
## Migration Context Template
|
||||
|
||||
When creating issues discovered during migration, use this context format:
|
||||
|
||||
```markdown
|
||||
## Context
|
||||
|
||||
Discovered during migration of **{PROJECT_NAME}** to Outfitter Stack.
|
||||
|
||||
**Migration stage:** {Foundation | Handlers | Errors | Paths | Adapters}
|
||||
**Source pattern:** {What the code looked like before}
|
||||
**Target pattern:** {What we're trying to achieve}
|
||||
```
|
||||
|
||||
## Common Migration Feedback
|
||||
|
||||
### Pattern Gap: Throw to Result
|
||||
|
||||
```bash
|
||||
gh issue create \
|
||||
--repo outfitter-dev/outfitter \
|
||||
--title "[migration] Guidance needed for X throw pattern" \
|
||||
--label "documentation" \
|
||||
--label "feedback" \
|
||||
--label "adoption" \
|
||||
--body "..."
|
||||
```
|
||||
|
||||
### Missing Helper: Error Conversion
|
||||
|
||||
```bash
|
||||
gh issue create \
|
||||
--repo outfitter-dev/outfitter \
|
||||
--title "[enhancement] Add helper to convert custom errors to taxonomy" \
|
||||
--label "enhancement" \
|
||||
--label "feedback" \
|
||||
--label "adoption" \
|
||||
--body "..."
|
||||
```
|
||||
|
||||
### Compatibility Issue
|
||||
|
||||
```bash
|
||||
gh issue create \
|
||||
--repo outfitter-dev/outfitter \
|
||||
--title "[bug] X doesn't work with common library Y" \
|
||||
--label "bug" \
|
||||
--label "feedback" \
|
||||
--label "adoption" \
|
||||
--body "..."
|
||||
```
|
||||
|
||||
## Linking to Adoption Plan
|
||||
|
||||
When adopting, track feedback in `.outfitter/adopt/plan/99-unknowns.md`:
|
||||
|
||||
```markdown
|
||||
## Stack Feedback (Migration)
|
||||
|
||||
- [ ] #123: Need guidance for async throw patterns — docs
|
||||
- [ ] #124: Add wrapLegacy helper — enhancement
|
||||
- [ ] #125: Compatibility with express middleware — bug
|
||||
```
|
||||
|
||||
## After Migration
|
||||
|
||||
Once migration is complete, review all feedback issues and:
|
||||
|
||||
1. Close any that were resolved by workarounds
|
||||
2. Add reproduction details now that you have working code
|
||||
3. Prioritize based on how painful the issue was
|
||||
+322
@@ -0,0 +1,322 @@
|
||||
#!/usr/bin/env bun
|
||||
/**
|
||||
* Create GitHub issues for stack-feedback skill
|
||||
*
|
||||
* Usage:
|
||||
* bun scripts/create-issue.ts --type bug --title "..." --package "@outfitter/result" ...
|
||||
*
|
||||
* Options:
|
||||
* --type Issue type (bug, enhancement, docs, unclear-pattern, dx,
|
||||
* migration-pattern, conversion-helper, compatibility, migration-docs)
|
||||
* --title Issue title (prefix added automatically)
|
||||
* --submit Actually create the issue (default: dry-run)
|
||||
* --help Show this help message
|
||||
*
|
||||
* All other options are passed as template fields (e.g., --package, --description)
|
||||
*/
|
||||
|
||||
import { parseArgs } from "util";
|
||||
import { templates, templateTypes, type IssueTemplate } from "../templates";
|
||||
|
||||
const REPO = "outfitter-dev/outfitter";
|
||||
|
||||
/**
|
||||
* Detect the origin repo from git remote.
|
||||
* Returns GitHub owner/repo format or null if not detectable.
|
||||
*/
|
||||
async function detectOriginRepo(): Promise<string | null> {
|
||||
try {
|
||||
const proc = Bun.spawn(["git", "remote", "get-url", "origin"], {
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
|
||||
const stdout = await new Response(proc.stdout).text();
|
||||
const exitCode = await proc.exited;
|
||||
|
||||
if (exitCode !== 0) {
|
||||
// Silently fail - this is expected when not in a git repo
|
||||
return null;
|
||||
}
|
||||
|
||||
const url = stdout.trim();
|
||||
|
||||
// Handle SSH format: git@github.com:owner/repo.git
|
||||
const sshMatch = url.match(/git@github\.com:([^/]+\/[^/]+?)(?:\.git)?$/);
|
||||
if (sshMatch) {
|
||||
return sshMatch[1];
|
||||
}
|
||||
|
||||
// Handle HTTPS format: https://github.com/owner/repo.git
|
||||
const httpsMatch = url.match(/github\.com\/([^/]+\/[^/]+?)(?:\.git)?$/);
|
||||
if (httpsMatch) {
|
||||
return httpsMatch[1];
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
interface ParsedArgs {
|
||||
type?: string;
|
||||
title?: string;
|
||||
submit?: boolean;
|
||||
help?: boolean;
|
||||
[key: string]: string | boolean | undefined;
|
||||
}
|
||||
|
||||
function showHelp(): void {
|
||||
console.log(`
|
||||
stack-feedback: Create GitHub issues for Outfitter Stack feedback
|
||||
|
||||
USAGE
|
||||
bun scripts/create-issue.ts --type <type> --title <title> [--field value]... [--submit]
|
||||
|
||||
OPTIONS
|
||||
--type <type> Issue type (required)
|
||||
--title <title> Issue title without prefix (required)
|
||||
--submit Create issue (default: dry-run mode)
|
||||
--help Show this help
|
||||
|
||||
ISSUE TYPES
|
||||
${templateTypes.map((t) => ` ${t}`).join("\n")}
|
||||
|
||||
TEMPLATE FIELDS
|
||||
Each issue type has required and optional fields. Pass them as --fieldName "value".
|
||||
Use --type <type> without other args to see required fields.
|
||||
|
||||
EXAMPLES
|
||||
# Dry-run a bug report
|
||||
bun scripts/create-issue.ts \\
|
||||
--type bug \\
|
||||
--title "Result.unwrap throws on valid input" \\
|
||||
--package "@outfitter/result" \\
|
||||
--description "When calling unwrap on Ok, it throws" \\
|
||||
--actual "Throws TypeError"
|
||||
|
||||
# Submit an enhancement request
|
||||
bun scripts/create-issue.ts \\
|
||||
--type enhancement \\
|
||||
--title "Add Result.tap helper" \\
|
||||
--package "@outfitter/result" \\
|
||||
--description "Helper to run side effects without unwrapping" \\
|
||||
--useCase "Logging without breaking chains" \\
|
||||
--submit
|
||||
`);
|
||||
}
|
||||
|
||||
function showTypeHelp(template: IssueTemplate): void {
|
||||
console.log(`
|
||||
Type: ${template.type}
|
||||
Labels: ${template.labels.join(", ")}
|
||||
Title prefix: ${template.titlePrefix}
|
||||
|
||||
Required fields:
|
||||
${template.requiredFields.map((f) => ` --${f}`).join("\n")}
|
||||
|
||||
Optional fields:
|
||||
${template.optionalFields.map((f) => ` --${f}`).join("\n")}
|
||||
`);
|
||||
}
|
||||
|
||||
function interpolate(template: string, fields: Record<string, string>): string {
|
||||
let result = template;
|
||||
|
||||
// Replace all {placeholder} patterns
|
||||
const placeholderRegex = /\{(\w+)\}/g;
|
||||
result = result.replace(placeholderRegex, (match, fieldName) => {
|
||||
const value = fields[fieldName];
|
||||
if (value !== undefined && value !== "") {
|
||||
return value;
|
||||
}
|
||||
// Remove the section if the field is empty
|
||||
return "_No information provided_";
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape single quotes for shell display.
|
||||
* NOTE: This is ONLY used for displaying the command to users (dry-run output).
|
||||
* Actual issue creation uses Bun.spawn with array arguments, which is safe.
|
||||
*/
|
||||
function escapeForShell(str: string): string {
|
||||
return str.replace(/'/g, "'\\''");
|
||||
}
|
||||
|
||||
function buildGhCommand(
|
||||
title: string,
|
||||
labels: string[],
|
||||
body: string
|
||||
): string {
|
||||
const labelArgs = labels.map((l) => `--label '${l}'`).join(" ");
|
||||
const escapedTitle = escapeForShell(title);
|
||||
const escapedBody = escapeForShell(body);
|
||||
|
||||
return `gh issue create --repo ${REPO} --title '${escapedTitle}' ${labelArgs} --body '${escapedBody}'`;
|
||||
}
|
||||
|
||||
async function createIssue(
|
||||
title: string,
|
||||
labels: string[],
|
||||
body: string
|
||||
): Promise<string> {
|
||||
const proc = Bun.spawn(
|
||||
[
|
||||
"gh",
|
||||
"issue",
|
||||
"create",
|
||||
"--repo",
|
||||
REPO,
|
||||
"--title",
|
||||
title,
|
||||
...labels.flatMap((l) => ["--label", l]),
|
||||
"--body",
|
||||
body,
|
||||
],
|
||||
{
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
}
|
||||
);
|
||||
|
||||
const stdout = await new Response(proc.stdout).text();
|
||||
const stderr = await new Response(proc.stderr).text();
|
||||
const exitCode = await proc.exited;
|
||||
|
||||
if (exitCode !== 0) {
|
||||
throw new Error(`gh issue create failed: ${stderr}`);
|
||||
}
|
||||
|
||||
return stdout.trim();
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
// Parse known options first, collect rest as fields
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
// Handle --help early
|
||||
if (args.includes("--help") || args.includes("-h") || args.length === 0) {
|
||||
showHelp();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Build options object for parseArgs
|
||||
const options: Record<string, { type: "string" | "boolean" }> = {
|
||||
type: { type: "string" },
|
||||
title: { type: "string" },
|
||||
submit: { type: "boolean" },
|
||||
help: { type: "boolean" },
|
||||
};
|
||||
|
||||
// Add all possible template fields as string options
|
||||
const allFields = new Set<string>();
|
||||
for (const template of Object.values(templates)) {
|
||||
for (const field of [...template.requiredFields, ...template.optionalFields]) {
|
||||
allFields.add(field);
|
||||
options[field] = { type: "string" };
|
||||
}
|
||||
}
|
||||
|
||||
let parsed: ParsedArgs;
|
||||
try {
|
||||
const result = parseArgs({
|
||||
args,
|
||||
options,
|
||||
strict: false, // Allow unknown options
|
||||
});
|
||||
parsed = result.values as ParsedArgs;
|
||||
} catch (error) {
|
||||
console.error("Error parsing arguments:", error);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Validate type
|
||||
const issueType = parsed.type;
|
||||
if (!issueType) {
|
||||
console.error("Error: --type is required");
|
||||
console.error(`Available types: ${templateTypes.join(", ")}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const template = templates[issueType];
|
||||
if (!template) {
|
||||
console.error(`Error: Unknown type '${issueType}'`);
|
||||
console.error(`Available types: ${templateTypes.join(", ")}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// If only type provided, show type help
|
||||
if (!parsed.title && Object.keys(parsed).length <= 1) {
|
||||
showTypeHelp(template);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Validate title
|
||||
if (!parsed.title) {
|
||||
console.error("Error: --title is required");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Collect field values
|
||||
const fields: Record<string, string> = {};
|
||||
for (const field of [...template.requiredFields, ...template.optionalFields]) {
|
||||
const value = parsed[field];
|
||||
if (typeof value === "string") {
|
||||
fields[field] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate required fields
|
||||
const missingFields = template.requiredFields.filter(
|
||||
(f) => !fields[f] || fields[f] === ""
|
||||
);
|
||||
if (missingFields.length > 0) {
|
||||
console.error(`Error: Missing required fields: ${missingFields.join(", ")}`);
|
||||
showTypeHelp(template);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Build issue
|
||||
const fullTitle = `${template.titlePrefix} ${parsed.title}`;
|
||||
let body = interpolate(template.bodyTemplate, fields);
|
||||
|
||||
// Add origin repo context if detectable
|
||||
const originRepo = await detectOriginRepo();
|
||||
if (originRepo && originRepo !== REPO) {
|
||||
// Insert before the footer
|
||||
const footerMarker = "---\n\n*Created via";
|
||||
if (body.includes(footerMarker)) {
|
||||
body = body.replace(
|
||||
footerMarker,
|
||||
`## Discovered In\n\n[\`${originRepo}\`](https://github.com/${originRepo})\n\n${footerMarker}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (parsed.submit) {
|
||||
// Submit mode: actually create the issue
|
||||
try {
|
||||
const url = await createIssue(fullTitle, template.labels, body);
|
||||
console.log(`Created issue: ${url}`);
|
||||
} catch (error) {
|
||||
console.error("Failed to create issue:", error);
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
// Dry-run mode: output JSON with command
|
||||
const command = buildGhCommand(fullTitle, template.labels, body);
|
||||
const output = {
|
||||
command,
|
||||
title: fullTitle,
|
||||
labels: template.labels,
|
||||
body,
|
||||
};
|
||||
console.log(JSON.stringify(output, null, 2));
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"type": "bug",
|
||||
"labels": ["bug", "feedback", "source/agent"],
|
||||
"titlePrefix": "[bug]:",
|
||||
"bodyTemplate": "## Package\n\n`{package}`\n\n## Description\n\n{description}\n\n## Expected Behavior\n\n{expected}\n\n## Actual Behavior\n\n{actual}\n\n## Reproduction\n\n{steps}\n\n## Workaround\n\n{workaround}\n\n---\n\n*Created via `outfitter-stack:stack-feedback` skill*",
|
||||
"requiredFields": ["package", "description", "actual"],
|
||||
"optionalFields": ["expected", "steps", "workaround"]
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"type": "compatibility",
|
||||
"labels": ["adoption", "feedback", "source/agent"],
|
||||
"titlePrefix": "[compat]:",
|
||||
"bodyTemplate": "## Package\n\n`{package}`\n\n## Description\n\n{description}\n\n## Breaking Change\n\n{breakingChange}\n\n## Impact Assessment\n\n{impact}\n\n## Suggested Mitigation\n\n{mitigation}\n\n---\n\n*Created via `outfitter-stack:stack-feedback` skill*",
|
||||
"requiredFields": ["package", "description", "breakingChange"],
|
||||
"optionalFields": ["impact", "mitigation"]
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"type": "conversion-helper",
|
||||
"labels": ["adoption", "feedback", "source/agent"],
|
||||
"titlePrefix": "[adoption]:",
|
||||
"bodyTemplate": "## Legacy Pattern\n\n{legacyPattern}\n\n## Description\n\n{description}\n\n## Target Pattern\n\n{targetPattern}\n\n## Proposed Helper\n\n{proposedHelper}\n\n## Frequency\n\n{frequency}\n\n---\n\n*Created via `outfitter-stack:stack-feedback` skill*",
|
||||
"requiredFields": ["legacyPattern", "description", "targetPattern"],
|
||||
"optionalFields": ["proposedHelper", "frequency"]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"type": "docs",
|
||||
"labels": ["documentation", "feedback", "source/agent"],
|
||||
"titlePrefix": "[docs]:",
|
||||
"bodyTemplate": "## Package/Area\n\n`{package}`\n\n## Description\n\n{description}\n\n## What's Missing or Unclear\n\n{gap}\n\n## Suggested Improvement\n\n{suggestion}\n\n## Context\n\n{context}\n\n---\n\n*Created via `outfitter-stack:stack-feedback` skill*",
|
||||
"requiredFields": ["package", "description", "gap"],
|
||||
"optionalFields": ["suggestion", "context"]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"type": "dx",
|
||||
"labels": ["dx", "feedback", "source/agent"],
|
||||
"titlePrefix": "[dx]:",
|
||||
"bodyTemplate": "## Package\n\n`{package}`\n\n## Description\n\n{description}\n\n## Current Experience\n\n{current}\n\n## Ideal Experience\n\n{ideal}\n\n## Impact\n\n{impact}\n\n---\n\n*Created via `outfitter-stack:stack-feedback` skill*",
|
||||
"requiredFields": ["package", "description", "current"],
|
||||
"optionalFields": ["ideal", "impact"]
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"type": "enhancement",
|
||||
"labels": ["feature", "feedback", "source/agent"],
|
||||
"titlePrefix": "[feat]:",
|
||||
"bodyTemplate": "## Package\n\n`{package}`\n\n## Description\n\n{description}\n\n## Use Case\n\n{useCase}\n\n## Proposed API\n\n{proposedApi}\n\n## Alternatives Considered\n\n{alternatives}\n\n---\n\n*Created via `outfitter-stack:stack-feedback` skill*",
|
||||
"requiredFields": ["package", "description", "useCase"],
|
||||
"optionalFields": ["proposedApi", "alternatives"]
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Issue template types and registry for stack-feedback skill
|
||||
*/
|
||||
|
||||
export interface IssueTemplate {
|
||||
type: string;
|
||||
labels: string[];
|
||||
titlePrefix: string;
|
||||
bodyTemplate: string;
|
||||
requiredFields: string[];
|
||||
optionalFields: string[];
|
||||
}
|
||||
|
||||
export interface TemplateFields {
|
||||
[key: string]: string | undefined;
|
||||
}
|
||||
|
||||
// Import all templates
|
||||
import bug from "./bug.json";
|
||||
import enhancement from "./enhancement.json";
|
||||
import docs from "./docs.json";
|
||||
import unclearPattern from "./unclear-pattern.json";
|
||||
import dx from "./dx.json";
|
||||
import migrationPattern from "./migration-pattern.json";
|
||||
import conversionHelper from "./conversion-helper.json";
|
||||
import compatibility from "./compatibility.json";
|
||||
import migrationDocs from "./migration-docs.json";
|
||||
|
||||
export const templates: Record<string, IssueTemplate> = {
|
||||
bug,
|
||||
enhancement,
|
||||
docs,
|
||||
"unclear-pattern": unclearPattern,
|
||||
dx,
|
||||
"migration-pattern": migrationPattern,
|
||||
"conversion-helper": conversionHelper,
|
||||
compatibility,
|
||||
"migration-docs": migrationDocs,
|
||||
};
|
||||
|
||||
export const templateTypes = Object.keys(templates);
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"type": "migration-docs",
|
||||
"labels": ["documentation", "adoption", "feedback", "source/agent"],
|
||||
"titlePrefix": "[docs]:",
|
||||
"bodyTemplate": "## Migration Area\n\n{area}\n\n## Description\n\n{description}\n\n## Documentation Gap\n\n{gap}\n\n## Suggested Content\n\n{suggestion}\n\n## Priority\n\n{priority}\n\n---\n\n*Created via `outfitter-stack:stack-feedback` skill*",
|
||||
"requiredFields": ["area", "description", "gap"],
|
||||
"optionalFields": ["suggestion", "priority"]
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"type": "migration-pattern",
|
||||
"labels": ["adoption", "feedback", "source/agent"],
|
||||
"titlePrefix": "[adoption]:",
|
||||
"bodyTemplate": "## Source Pattern\n\n{sourcePattern}\n\n## Description\n\n{description}\n\n## Migration Scenario\n\n{scenario}\n\n## Current Guidance\n\n{currentGuidance}\n\n## Suggested Approach\n\n{suggestion}\n\n---\n\n*Created via `outfitter-stack:stack-feedback` skill*",
|
||||
"requiredFields": ["sourcePattern", "description", "scenario"],
|
||||
"optionalFields": ["currentGuidance", "suggestion"]
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"type": "unclear-pattern",
|
||||
"labels": ["question", "feedback", "source/agent"],
|
||||
"titlePrefix": "[question]:",
|
||||
"bodyTemplate": "## Package/Area\n\n`{package}`\n\n## Question\n\n{description}\n\n## Context\n\n{context}\n\n## What I've Tried\n\n{attempted}\n\n## Specific Confusion\n\n{confusion}\n\n---\n\n*Created via `outfitter-stack:stack-feedback` skill*",
|
||||
"requiredFields": ["package", "description", "context"],
|
||||
"optionalFields": ["attempted", "confusion"]
|
||||
}
|
||||
Reference in New Issue
Block a user