diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 54cce27..b807c4b 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1,5 +1,4 @@ { - "$schema": "https://anthropic.com/claude-code/marketplace.schema.json", "name": "stackone-marketplace", "owner": { "name": "StackOne", diff --git a/.github/scripts/validate_skills.py b/.github/scripts/validate_skills.py new file mode 100644 index 0000000..09d1f89 --- /dev/null +++ b/.github/scripts/validate_skills.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +"""Validate all SKILL.md files in the skills/ directory. + +Each SKILL.md must have YAML frontmatter (delimited by ---) containing +at least the 'name' and 'description' fields. +""" +import re +import sys +from pathlib import Path + +REQUIRED_FIELDS = ["name", "description"] + + +def validate_skill(path: Path) -> list[str]: + errors = [] + content = path.read_text(encoding="utf-8") + + if not content.startswith("---"): + return [f"{path}: missing YAML frontmatter (file must start with ---)"] + + parts = content.split("---", 2) + if len(parts) < 3: + return [f"{path}: malformed frontmatter (missing closing ---)"] + + frontmatter = parts[1] + for field in REQUIRED_FIELDS: + if not re.search(rf"^{field}\s*:", frontmatter, re.MULTILINE): + errors.append(f"{path}: missing required frontmatter field '{field}'") + + return errors + + +def main() -> None: + repo_root = Path(__file__).resolve().parent.parent.parent + skills_dir = repo_root / "skills" + if not skills_dir.exists(): + print("No skills/ directory found — skipping.") + return + + skill_files = sorted(skills_dir.rglob("SKILL.md")) + if not skill_files: + print("No SKILL.md files found — skipping.") + return + + all_errors: list[str] = [] + for path in skill_files: + all_errors.extend(validate_skill(path)) + + if all_errors: + print("SKILL.md validation failed:\n") + for error in all_errors: + print(f" ✗ {error}") + sys.exit(1) + + print(f"All {len(skill_files)} SKILL.md file(s) passed validation.") + + +if __name__ == "__main__": + main() diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 078b17e..763232b 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -9,7 +9,7 @@ on: - main jobs: - validate: + validate-manifest: name: Validate marketplace.json runs-on: ubuntu-latest steps: @@ -17,3 +17,12 @@ jobs: - name: Validate plugin manifests run: npx --yes @anthropic-ai/claude-code plugin validate . + + validate-skills: + name: Validate SKILL.md files + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + - name: Check SKILL.md frontmatter + run: python3 .github/scripts/validate_skills.py diff --git a/README.md b/README.md index 506392a..6a3566d 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Agent skills for [StackOne](https://stackone.com) — integration infrastructure # Add the marketplace /plugin marketplace add stackonehq/agent-plugins-marketplace -# Install the StackOne plugin (all 6 skills) +# Install the StackOne plugin (all 7 skills) /plugin install stackone@stackone-marketplace ``` @@ -34,6 +34,7 @@ npx skills add stackonehq/agent-plugins-marketplace@stackone-agents | [`stackone-cli`](skills/stackone-cli/) | Custom connector development and deployment | "Build a custom connector", "deploy my connector" | | [`stackone-connectors`](skills/stackone-connectors/) | Discover connectors, actions, and integration capabilities | "Which providers does StackOne support?" | | [`stackone-unified-connectors`](skills/stackone-unified-connectors/) | Build unified connectors that transform provider data into standardized schemas | "start unified build for [provider]", "map fields to schema" | +| [`spark`](skills/spark/) | Find the single smartest, most innovative addition to your current PR/branch or project, then implement it | "/spark", "what's the most impactful thing you could add to this PR?", "what single feature would make this better?" | Each skill includes step-by-step workflows, concrete examples, and troubleshooting for common errors. diff --git a/skills/spark/SKILL.md b/skills/spark/SKILL.md new file mode 100644 index 0000000..af3e501 --- /dev/null +++ b/skills/spark/SKILL.md @@ -0,0 +1,104 @@ +--- +name: spark +description: This skill should be used when the user invokes "/spark" or asks "what's the best thing you could add to this PR/project?", "what single feature would make this better?", "what's the most impactful next move?", or "what would you add to this branch/codebase?". Generates the single smartest, most innovative and high-value addition to the current PR/branch or project, then offers to implement it. +invoke: spark +license: MIT +metadata: + author: stackone + version: "1.0" +--- + +# Spark — Find the Single Best Next Move + +Identify the most innovative, high-value addition to the current context — a PR/branch in progress, or the entire project — then offer to build it. + +## Step 1: Detect Context + +Run these together to understand current state: + +```bash +git branch --show-current # Are we on a named branch? +git status --short # Any uncommitted changes? +git log --oneline -10 # Recent commit history +``` + +Then decide which mode applies: + +### Branch/PR Mode +Triggers when: on a non-default branch (`main`/`master`/`develop`/`trunk`) OR when there are staged/uncommitted changes that form a coherent unit of work. + +Gather PR context: +```bash +BASE=$(git rev-parse --abbrev-ref origin/HEAD 2>/dev/null | sed 's|origin/||' || echo main) +git diff $BASE...HEAD --stat # What files changed? +git diff $BASE...HEAD # Full diff (skim for intent) +git log $BASE...HEAD --oneline # Commits in this branch +gh pr view 2>/dev/null # PR title, description, comments +``` + +### Project Mode +Triggers when: on the default branch with no active feature work. + +Gather project context: +```bash +ls -la # Root structure +cat README.md 2>/dev/null | head -60 +cat package.json 2>/dev/null # or Cargo.toml, pyproject.toml, etc. +git log --oneline -20 # Recent trajectory +``` + +Also read key architectural files (routes, main entry points, core modules) to understand what exists. + +## Step 2: Synthesize and Ideate + +With context gathered, think hard. The goal: find the **single highest-leverage addition** that is: + +- **Non-obvious** — not the next logical TODO item or a feature already implied by the PR +- **Accretive** — genuinely multiplies the value of what's already there +- **Feasible** — implementable in this codebase without a full rewrite +- **Specific** — a concrete feature/change, not a vague theme like "better error handling" + +### For Branch/PR Mode +Focus on: what would make this PR go from good to exceptional? What's the one thing that would make reviewers say "wow, I didn't think of that"? Consider: edge cases that become features, DX improvements, observability, composability, performance wins, security hardening that's elegant rather than bolt-on. + +### For Project Mode +Focus on: what single addition would unlock the most value for users/developers? Consider: killer features that are missing, architectural capabilities that enable a class of new use cases, developer experience that removes the biggest friction point, integrations that make the whole more valuable than the sum of parts. + +**Avoid**: generic suggestions (add tests, add docs, add logging). The idea should be surprising and specific. + +## Step 3: Present the Idea + +Present ONE idea with conviction. Format: + +``` +## Spark: [Catchy Name for the Idea] + +**What**: [One crisp sentence] + +**Why it's the right move**: [2-3 sentences on why this is the highest-leverage addition +right now, referencing specifics from the codebase/PR] + +**How it would work**: [Concrete sketch — key files touched, rough approach, any +interesting technical choices. Not a full spec, just enough to make it tangible] + +**Impact**: [What does this unlock? Who benefits? Why does it matter?] +``` + +Then use `AskUserQuestion` to ask: + +- **"Want to build it?"** with options: Yes, build it now / Refine the idea first / Show me alternatives + +## Step 4: Act on Response + +**"Yes, build it now"** → Call `EnterPlanMode` to design the full implementation. Use the existing codebase patterns, read relevant files, and produce a concrete step-by-step plan before writing any code. + +**"Refine the idea first"** → Ask clarifying questions: scope, constraints, preferences. Then re-present the refined version and loop back to Step 3. + +**"Show me alternatives"** → Generate 2-3 more options (weaker than the primary but still strong), let user pick, then proceed with their choice. + +## Principles + +- **One idea, not a list.** Presenting multiple ideas dilutes the thinking. Commit to the best one. +- **Specificity over generality.** "Add a `--watch` flag that re-runs the build on file change, streaming output to a WebSocket" beats "improve developer experience". +- **Reference what's actually there.** The idea should feel inevitable given the existing code, not imported from another project. +- **Be direct.** Don't hedge with "you might consider" or "one option could be". State the idea with confidence.