🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

getsuperpower

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

getsuperpower - npm Package Compare versions

Comparing version
0.3.1
to
0.3.2
+78
examples/workflows/development-design-delivery/README.md
# Development Design Delivery GetSuperpower
This example combines product/design shaping with implementation discipline.
Use it when a change needs more than a quick patch: clarify the request, explore
the interface, pressure-test the plan, implement with tests, review the result,
and keep rollback evidence.
The callable entry skill is:
```text
skills/development-design-delivery/SKILL.md
```
After install and agent restart, invoke:
```text
$development-design-delivery build this product feature
```
## Flow
| Stage | Skill | Gate |
| --- | --- | --- |
| Shape success criteria | `superpowers:brainstorming` | Human approval |
| Explore interface options | `mattpocock:design-an-interface` | Human approval |
| Stress-test the requirement | `mattpocock:grill-with-docs` | Human approval |
| Write implementation plan | `superpowers:writing-plans` | None |
| Check architecture boundary | `mattpocock:codebase-design` | None |
| Build with tests | `mattpocock:tdd` | None |
| Debug when blocked | `mattpocock:diagnosing-bugs` | None |
| Review the change | `mattpocock:review` | None |
| Preserve evidence | `pony-trail` | None |
## Dependencies
This GetSuperpower combines reusable agent skills:
- `./skills/development-design-delivery`
- `superpowers:brainstorming`
- `mattpocock:design-an-interface`
- `mattpocock:grill-with-docs`
- `superpowers:writing-plans`
- `mattpocock:codebase-design`
- `mattpocock:tdd`
- `mattpocock:diagnosing-bugs`
- `mattpocock:review`
- `pony-trail`
`getsuperpower install` and `getsuperpower clone` automatically use the Skills
CLI to fetch missing `mattpocock:*` dependencies. If that automatic bootstrap
fails, run the same package install through the CLI and retry:
```bash
bun run dev -- skills install mattpocock/skills
```
## Try It
Validate this GetSuperpower from the repo root:
```bash
bun run dev -- validate examples/workflows/development-design-delivery
```
List its dependencies:
```bash
bun run dev -- deps examples/workflows/development-design-delivery
```
Install it into a project:
```bash
bun run dev -- install examples/workflows/development-design-delivery
bun run dev -- clone examples/workflows/development-design-delivery
```
`clone <source>` is equivalent to `install <source>`.
---
name: development-design-delivery
description: Use when running a product-minded engineering workflow from request shaping through interface design, implementation, review, and evidence capture.
---
# Development Design Delivery GetSuperpower
This is the entry skill for the development-design-delivery GetSuperpower.
When this skill is used, run the workflow below in order. Load/use every
required sub-skill before doing the work for its phase.
## Required Sub-Skills
Before doing workflow work, load/use these skills in order:
1. superpowers:brainstorming - shape the request, context, constraints, and success criteria
2. mattpocock:design-an-interface - explore API, module, or UI interface options
3. mattpocock:grill-with-docs - stress-test the requirement and preserve design docs
4. superpowers:writing-plans - split approved scope into executable tasks
5. mattpocock:codebase-design - check module boundaries, seams, and testability
6. mattpocock:tdd - build task by task with failing tests first
7. mattpocock:diagnosing-bugs - diagnose unexpected failures or regressions when blocked
8. mattpocock:review - review changes against standards and the approved spec
9. pony-trail - record file-change evidence, verification, and rollback context
If any required sub-skill is unavailable, stop and tell the user which
dependency is missing. For missing `mattpocock:*` skills, tell the user to run:
```bash
getsuperpower skills install mattpocock/skills
```
## Flow
1. Shape the request and success criteria.
- Skill: superpowers:brainstorming
- Gate: wait for explicit human approval.
2. Explore API, module, or UI interface options.
- Skill: mattpocock:design-an-interface
- Gate: wait for explicit human approval.
3. Stress-test the plan and record docs.
- Skill: mattpocock:grill-with-docs
- Gate: wait for explicit human approval.
4. Write the task-by-task implementation plan.
- Skill: superpowers:writing-plans
5. Check module boundaries and seams before implementation.
- Skill: mattpocock:codebase-design
6. Implement with TDD.
- Skill: mattpocock:tdd
7. Use systematic debugging if behavior is unexpected or tests fail.
- Skill: mattpocock:diagnosing-bugs
8. Review the change against repo standards and the approved spec.
- Skill: mattpocock:review
9. Preserve verification and rollback evidence.
- Skill: pony-trail
## Author Notes
- Keep this entry skill, `workflow.json`, and `README.md` aligned when adding or removing steps.
- This skill orchestrates through required instructions; GetSuperpower installs and validates the dependency skills.
- Do not silently skip approval gates, interface exploration, implementation planning, TDD, review, or evidence capture.
{
"schemaVersion": "0.1",
"name": "development-design-delivery",
"version": "0.1.0",
"description": "Shape, design, plan, implement, review, and preserve evidence for serious product engineering work.",
"skills": [
{
"source": "./skills/development-design-delivery"
},
{
"source": "superpowers:brainstorming"
},
{
"source": "mattpocock:design-an-interface"
},
{
"source": "mattpocock:grill-with-docs"
},
{
"source": "superpowers:writing-plans"
},
{
"source": "mattpocock:codebase-design"
},
{
"source": "mattpocock:tdd"
},
{
"source": "mattpocock:diagnosing-bugs"
},
{
"source": "mattpocock:review"
},
{
"source": "pony-trail"
}
],
"steps": [
{
"id": "shape",
"title": "Shape the request and success criteria",
"skill": "superpowers:brainstorming",
"gate": "human_approval"
},
{
"id": "interface-design",
"title": "Explore API, module, or UI interface options",
"skill": "mattpocock:design-an-interface",
"gate": "human_approval"
},
{
"id": "requirement-review",
"title": "Stress-test the plan and record docs",
"skill": "mattpocock:grill-with-docs",
"gate": "human_approval"
},
{
"id": "implementation-plan",
"title": "Write the task-by-task implementation plan",
"skill": "superpowers:writing-plans"
},
{
"id": "architecture-boundary",
"title": "Check module boundaries and seams",
"skill": "mattpocock:codebase-design"
},
{
"id": "build",
"title": "Implement with TDD",
"skill": "mattpocock:tdd"
},
{
"id": "debug",
"title": "Use systematic debugging when blocked",
"skill": "mattpocock:diagnosing-bugs"
},
{
"id": "review",
"title": "Review against standards and spec",
"skill": "mattpocock:review"
},
{
"id": "evidence",
"title": "Record verification and rollback evidence",
"skill": "pony-trail"
}
]
}
# Grilled Product Dev GetSuperpower
This example GetSuperpower is for product-development requests that are still a
little soft. It uses Matt Pocock's `grilling` skill first to pressure-test the
idea, then hands the approved direction to Superpowers for design and planning.
The flow is intentionally narrow:
1. Grill the request one question at a time until the goal, constraints, and
success criteria are clear.
2. Use `superpowers:brainstorming` to turn the sharpened direction into an
approved design.
3. Use `superpowers:writing-plans` to split that design into executable tasks.
The callable entry skill is:
```text
skills/grilled-product-dev/SKILL.md
```
After install and agent restart, invoke:
```text
$grilled-product-dev help me shape this product change
```
## Dependencies
This GetSuperpower combines one Matt Pocock skill with two Superpowers skills:
- `./skills/grilled-product-dev`
- `mattpocock:grilling`
- `superpowers:brainstorming`
- `superpowers:writing-plans`
`getsuperpower install` and `getsuperpower clone` automatically use the Skills
CLI to fetch missing `mattpocock:*` dependencies. If that automatic bootstrap
fails, install the Matt Pocock skills package and retry:
```bash
bun run dev -- skills install mattpocock/skills
```
## Try It
Validate this GetSuperpower from the repo root:
```bash
bun run dev -- validate examples/workflows/grilled-product-dev
```
List its dependencies:
```bash
bun run dev -- deps examples/workflows/grilled-product-dev
```
Install it into a project:
```bash
bun run dev -- install examples/workflows/grilled-product-dev
bun run dev -- clone examples/workflows/grilled-product-dev
```
`clone <source>` is equivalent to `install <source>`.
Restart the agent app after install so the `$grilled-product-dev` entry skill
and its sub-skills are available.
---
name: grilled-product-dev
description: Use when shaping a product-development request that should be grilled before Superpowers design and planning.
---
# Grilled Product Dev GetSuperpower
This is the entry skill for the grilled-product-dev GetSuperpower.
When this skill is used, run the workflow below in order. Load/use every
required sub-skill before doing the work for its phase.
## Required Sub-Skills
Before doing workflow work, load/use these skills in order:
1. mattpocock:grilling - interview the human one question at a time and recommend answers until the request is sharp
2. superpowers:brainstorming - turn the approved direction into a design and written spec
3. superpowers:writing-plans - split the approved design into executable tasks
If any required sub-skill is unavailable, stop and tell the user which
dependency is missing.
## Flow
1. Sharpen the request through Matt Pocock grilling.
- Skill: mattpocock:grilling
- Gate: wait for explicit human approval that the grilled direction is ready.
2. Turn the approved direction into a Superpowers design.
- Skill: superpowers:brainstorming
- Gate: wait for explicit human approval of the design and written spec.
3. Write the implementation plan.
- Skill: superpowers:writing-plans
## Author Notes
- Keep this entry skill, `workflow.json`, and `README.md` aligned when adding or removing steps.
- `superpowers:brainstorming` expects `superpowers:writing-plans` to be the next implementation skill, so grilling runs before brainstorming in this workflow.
- This skill orchestrates required instructions; GetSuperpower installs and validates the dependency skills.
{
"schemaVersion": "0.1",
"name": "grilled-product-dev",
"version": "0.1.0",
"description": "Sharpen a product-development request with grilling before Superpowers design and planning.",
"skills": [
{
"source": "./skills/grilled-product-dev"
},
{
"source": "mattpocock:grilling"
},
{
"source": "superpowers:brainstorming"
},
{
"source": "superpowers:writing-plans"
}
],
"steps": [
{
"id": "grill",
"title": "Sharpen the request through grilling",
"skill": "mattpocock:grilling",
"gate": "human_approval"
},
{
"id": "shape",
"title": "Turn the approved direction into a Superpowers design",
"skill": "superpowers:brainstorming",
"gate": "human_approval"
},
{
"id": "plan",
"title": "Write the implementation plan",
"skill": "superpowers:writing-plans"
}
]
}
---
name: openspec-delivery
description: Use when running a professional OpenSpec delivery workflow from proposal through design, plan, TDD implementation, verification, and archive.
---
# OpenSpec Delivery GetSuperpower
This is the entry skill for the openspec-delivery GetSuperpower.
When this skill is used, run the delivery workflow below in order. Load/use
every required sub-skill before doing the work for its phase.
## Required Sub-Skills
Before doing workflow work, load/use these skills in order:
1. opsx-handoff-review (`./skills/opsx-handoff-review`) - OpenSpec proposal, review, handoff, and archive checkpoints
2. superpowers:brainstorming - design deepening before implementation planning
3. superpowers:writing-plans - split approved scope into executable tasks
4. mattpocock:tdd - build task by task with failing tests first
5. pony-trail - record file-change evidence, verification, and rollback context
If any required sub-skill is unavailable, stop and tell the user which dependency is missing.
## Flow
1. Run `/opsx:propose` to create proposal, specs, and tasks.
- Skill: opsx-handoff-review (`./skills/opsx-handoff-review`)
2. Review `proposal.md` with the human owner.
- Skill: opsx-handoff-review (`./skills/opsx-handoff-review`)
- Gate: wait for explicit human approval.
3. Deepen design details with Superpowers brainstorming.
- Skill: superpowers:brainstorming
- Gate: wait for explicit human approval.
4. Split tasks into an implementation plan.
- Skill: superpowers:writing-plans
5. Build each task with TDD and `specs/` context.
- Skill: mattpocock:tdd
6. Verify delivery and preserve evidence.
- Skill: pony-trail
7. Run `/opsx:archive` to update specs and project knowledge.
- Skill: opsx-handoff-review (`./skills/opsx-handoff-review`)
- Gate: wait for explicit human approval.
## Author Notes
- Keep this entry skill, `workflow.json`, and `README.md` aligned when adding or removing steps.
- This skill orchestrates through required instructions; GetSuperpower installs and validates the dependency skills.
- Do not silently skip OpenSpec review, human approval gates, TDD, verification, or archive.
import pc from "picocolors";
export const GETSUPERPOWER_ASCII_LOGO = [
"GETSUPERPOWER",
"Skill trees for serious agent work.",
].join("\n");
export function brand(value: string): string {
return pc.bold(pc.cyan(value));
}
export function success(value: string): string {
return pc.bold(pc.green(value));
}
export function warning(value: string): string {
return pc.yellow(value);
}
export function errorText(value: string): string {
return pc.red(value);
}
export function muted(value: string): string {
return pc.dim(value);
}
export function commandText(value: string): string {
return pc.magenta(value);
}
export function label(value: string): string {
return muted(value);
}
export function keyValue(key: string, value: string): string {
return `${label(`${key}:`)} ${value}`;
}
export function nextStep(command: string): string {
return `${label("Next:")} ${commandText(command)}`;
}
export function rootHelpBanner(): string {
return [
brand(GETSUPERPOWER_ASCII_LOGO),
"",
success("Welcome to GetSuperpower."),
"Install and author workflow skill trees for agent work.",
"",
label("Start:"),
` ${commandText("getsuperpower init release-review")}`,
` ${commandText("getsuperpower validate ./release-review")}`,
` ${commandText("getsuperpower clone https://github.com/acme/release-review.git")}`,
` ${commandText("getsuperpower install ./release-review")}`,
"",
label("Inspect:"),
` ${commandText("getsuperpower list")}`,
` ${commandText("getsuperpower deps ./release-review")}`,
"",
].join("\n");
}
export function styleHelpTitle(title: string): string {
return brand(title);
}
export function styleHelpTerm(term: string): string {
return commandText(term);
}
import { mkdir, mkdtemp, stat, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { isAbsolute, join, resolve } from "node:path";
import { buildProgram } from "../cli";
export type CliSandboxEvaluationMode = "baseline" | "workflow";
export interface CliSandboxCriterion {
id: string;
label: string;
passed: boolean;
detail: string;
}
export interface CliSandboxCommandRun {
args: string[];
activeMs: number;
failed: boolean;
logs: string[];
error?: string;
}
export interface CliSandboxTokenSpend {
inputTokens?: number;
outputTokens?: number;
}
export interface CliSandboxRun {
mode: CliSandboxEvaluationMode;
label: string;
projectDir: string;
homeDir: string;
activeMs: number;
cliCommands: number;
checkRetries: number;
commandFailures: number;
externalSideEffects: number;
criteria: CliSandboxCriterion[];
commands: CliSandboxCommandRun[];
tokenSpend: CliSandboxTokenSpend | null;
}
export interface CliSandboxMatrixRow {
metric: string;
baseline: string;
workflow: string;
delta: string;
}
export interface CliSandboxEvaluationReport {
generatedAt: string;
workflowSource: string;
workflowSourcePath: string;
sandboxRoot: string;
runs: [CliSandboxRun, CliSandboxRun];
matrices: {
performance: CliSandboxMatrixRow[];
accuracy: CliSandboxMatrixRow[];
tokenSpend: CliSandboxMatrixRow[];
};
}
export interface RunCliSandboxEvaluationOptions {
generatedAt?: string;
repoRoot?: string;
sandboxRoot?: string;
workflowSource?: string;
}
const defaultWorkflowSource = "examples/workflows/openspec-superpowers";
const expectedInstalledSkills = [
"openspec-delivery",
"opsx-handoff-review",
"superpowers-brainstorming",
"superpowers-writing-plans",
"tdd",
"pony-trail",
];
export async function runCliSandboxEvaluation(
options: RunCliSandboxEvaluationOptions = {},
): Promise<CliSandboxEvaluationReport> {
const repoRoot = options.repoRoot ?? resolve(import.meta.dir, "..", "..");
const workflowSource = options.workflowSource ?? defaultWorkflowSource;
const workflowSourcePath = isAbsolute(workflowSource)
? workflowSource
: resolve(repoRoot, workflowSource);
const sandboxRoot =
options.sandboxRoot ?? (await mkdtemp(join(tmpdir(), "getsuperpower-cli-eval-")));
await mkdir(sandboxRoot, { recursive: true });
const baselineRun = await runBaseline({
projectDir: join(sandboxRoot, "baseline-project"),
homeDir: join(sandboxRoot, "baseline-home"),
workflowSourcePath,
});
const workflowRun = await runWorkflow({
projectDir: join(sandboxRoot, "workflow-project"),
homeDir: join(sandboxRoot, "workflow-home"),
workflowSourcePath,
});
return createEvaluationReport({
generatedAt: options.generatedAt ?? new Date().toISOString(),
workflowSource,
workflowSourcePath,
sandboxRoot,
runs: [baselineRun, workflowRun],
});
}
export function renderCliSandboxEvaluation(report: CliSandboxEvaluationReport): string {
return [
"# GetSuperpower CLI Sandbox Evaluation",
"",
`Generated: ${report.generatedAt}`,
`Workflow source: ${report.workflowSource}`,
`Sandbox root: ${report.sandboxRoot}`,
"",
"## Performance Matrix",
renderMatrix(report.matrices.performance),
"",
"## Accuracy Matrix",
renderMatrix(report.matrices.accuracy),
"",
"## Token Spend Matrix",
renderMatrix(report.matrices.tokenSpend),
"",
"Token metrics are unavailable because CLI sandbox runs do not expose provider token metadata.",
"",
"## Acceptance Criteria",
...report.runs.flatMap((run) => [
"",
`### ${run.label}`,
...run.criteria.map(
(criterion) =>
`- ${criterion.passed ? "PASS" : "FAIL"} ${criterion.label}: ${criterion.detail}`,
),
]),
"",
].join("\n");
}
function createEvaluationReport(input: {
generatedAt: string;
workflowSource: string;
workflowSourcePath: string;
sandboxRoot: string;
runs: [CliSandboxRun, CliSandboxRun];
}): CliSandboxEvaluationReport {
const [baseline, workflow] = input.runs;
return {
generatedAt: input.generatedAt,
workflowSource: input.workflowSource,
workflowSourcePath: input.workflowSourcePath,
sandboxRoot: input.sandboxRoot,
runs: input.runs,
matrices: {
performance: [
millisecondsRow("Active wall-clock time", baseline.activeMs, workflow.activeMs),
countRow("CLI commands", baseline.cliCommands, workflow.cliCommands),
countRow("Check retries", baseline.checkRetries, workflow.checkRetries),
],
accuracy: [
textRow(
"Acceptance criteria passed",
`${countPassedCriteria(baseline)}/${baseline.criteria.length}`,
`${countPassedCriteria(workflow)}/${workflow.criteria.length}`,
formatSignedNumber(countPassedCriteria(workflow) - countPassedCriteria(baseline)),
),
percentRow("Acceptance pass rate", criteriaPassRate(baseline), criteriaPassRate(workflow)),
countRow("CLI command failures", baseline.commandFailures, workflow.commandFailures),
countRow(
"External side effects",
baseline.externalSideEffects,
workflow.externalSideEffects,
),
],
tokenSpend: tokenSpendRows(baseline, workflow),
},
};
}
async function runBaseline(input: {
projectDir: string;
homeDir: string;
workflowSourcePath: string;
}): Promise<CliSandboxRun> {
await mkdir(input.projectDir, { recursive: true });
await mkdir(input.homeDir, { recursive: true });
const externalCalls: string[] = [];
const commands = await runCommands({
projectDir: input.projectDir,
externalCalls,
commands: [
["validate", input.workflowSourcePath],
["deps", input.workflowSourcePath],
],
});
const logs = commands.flatMap((command) => command.logs);
const workflowRecord = join(
input.projectDir,
".getsuperpower",
"workflows",
"openspec-delivery.json",
);
return buildRun({
mode: "baseline",
label: "Before workflow install/use",
projectDir: input.projectDir,
homeDir: input.homeDir,
commands,
externalSideEffects: externalCalls.length,
criteria: [
{
id: "baseline-validates-workflow",
label: "CLI validates the workflow source",
passed: logs.some((line) =>
stripAnsi(line).includes("GetSuperpower valid: openspec-delivery@0.1.0"),
),
detail: "validate should accept the OpenSpec workflow fixture",
},
{
id: "baseline-lists-dependencies",
label: "CLI lists workflow dependencies before install",
passed:
logs.some((line) => stripAnsi(line).includes("- mattpocock:tdd")) &&
logs.some((line) => stripAnsi(line).includes("- pony-trail")),
detail: "deps should expose reusable workflow skill requirements",
},
{
id: "baseline-does-not-install",
label: "Baseline mode leaves the project uninstalled",
passed: !(await pathExists(workflowRecord)),
detail: ".getsuperpower workflow records should not exist before install/clone",
},
{
id: "baseline-no-external-side-effects",
label: "Baseline mode avoids external side effects",
passed: externalCalls.length === 0,
detail: "validate/deps should not invoke the external Skills CLI",
},
],
});
}
async function runWorkflow(input: {
projectDir: string;
homeDir: string;
workflowSourcePath: string;
}): Promise<CliSandboxRun> {
await mkdir(input.projectDir, { recursive: true });
await mkdir(input.homeDir, { recursive: true });
await writeFakeDependencyHome(input.homeDir);
const externalCalls: string[] = [];
const commands = await runCommands({
projectDir: input.projectDir,
externalCalls,
commands: [
["clone", input.workflowSourcePath, "--home", input.homeDir, "--agents", "codex"],
["list"],
],
});
const logs = commands.flatMap((command) => command.logs);
const workflowRecord = join(
input.projectDir,
".getsuperpower",
"workflows",
"openspec-delivery.json",
);
const installedSkillResults = await Promise.all(
expectedInstalledSkills.map((skill) =>
pathExists(join(input.homeDir, ".agents", "skills", skill, "SKILL.md")),
),
);
return buildRun({
mode: "workflow",
label: "After workflow clone/use",
projectDir: input.projectDir,
homeDir: input.homeDir,
commands,
externalSideEffects: externalCalls.length,
criteria: [
{
id: "workflow-record-written",
label: "Workflow mode writes the installed workflow record",
passed: await pathExists(workflowRecord),
detail: ".getsuperpower/workflows/openspec-delivery.json should exist",
},
{
id: "workflow-installs-skills",
label: "Workflow mode installs every required skill into the sandbox home",
passed: installedSkillResults.every(Boolean),
detail: expectedInstalledSkills.join(", "),
},
{
id: "workflow-list-shows-installed-workflow",
label: "Workflow mode lists the installed workflow",
passed: logs.some((line) => stripAnsi(line).includes("openspec-delivery 0.1.0")),
detail: "list should show the workflow installed by clone",
},
{
id: "workflow-no-external-side-effects",
label: "Workflow mode avoids external side effects in the sandbox",
passed: externalCalls.length === 0,
detail: "fake sandbox dependencies should prevent network/package bootstrap",
},
],
});
}
function buildRun(input: {
mode: CliSandboxEvaluationMode;
label: string;
projectDir: string;
homeDir: string;
commands: CliSandboxCommandRun[];
externalSideEffects: number;
criteria: CliSandboxCriterion[];
}): CliSandboxRun {
return {
mode: input.mode,
label: input.label,
projectDir: input.projectDir,
homeDir: input.homeDir,
activeMs: sum(input.commands.map((command) => command.activeMs)),
cliCommands: input.commands.length,
checkRetries: 0,
commandFailures: input.commands.filter((command) => command.failed).length,
externalSideEffects: input.externalSideEffects,
criteria: input.criteria,
commands: input.commands,
tokenSpend: null,
};
}
async function runCommands(input: {
projectDir: string;
externalCalls: string[];
commands: string[][];
}): Promise<CliSandboxCommandRun[]> {
const runs: CliSandboxCommandRun[] = [];
for (const args of input.commands) {
runs.push(
await runCommand({ projectDir: input.projectDir, externalCalls: input.externalCalls, args }),
);
}
return runs;
}
async function runCommand(input: {
projectDir: string;
externalCalls: string[];
args: string[];
}): Promise<CliSandboxCommandRun> {
const logs: string[] = [];
const originalLog = console.log;
const originalError = console.error;
const startedAt = performance.now();
let failed = false;
let error: string | undefined;
console.log = (...values: unknown[]) => {
logs.push(values.join(" "));
};
console.error = (...values: unknown[]) => {
logs.push(values.join(" "));
};
try {
await buildProgram({
cwd: input.projectDir,
installExternalSkillDependency: async (dependency) => {
input.externalCalls.push(dependency.source);
throw new Error(`Sandbox blocked external skill install: ${dependency.source}`);
},
}).parseAsync(input.args, { from: "user" });
} catch (caught) {
failed = true;
error = caught instanceof Error ? caught.message : String(caught);
logs.push(`ERROR: ${error}`);
} finally {
console.log = originalLog;
console.error = originalError;
}
return {
args: input.args,
activeMs: performance.now() - startedAt,
failed,
logs,
...(error ? { error } : {}),
};
}
async function writeFakeDependencyHome(homeDir: string): Promise<void> {
const superpowersRoot = join(
homeDir,
".codex",
"plugins",
"cache",
"openai-curated",
"superpowers",
"sandbox-plugin",
"skills",
);
await writeSkill(join(superpowersRoot, "brainstorming"), {
name: "brainstorming",
description: "Sandbox Superpowers brainstorming skill.",
});
await writeSkill(join(superpowersRoot, "writing-plans"), {
name: "writing-plans",
description: "Sandbox Superpowers writing-plans skill.",
});
await writeSkill(join(homeDir, ".agents", "skills", "tdd"), {
name: "tdd",
description: "Sandbox Matt Pocock TDD skill.",
});
}
async function writeSkill(
path: string,
input: { name: string; description: string },
): Promise<void> {
await mkdir(path, { recursive: true });
await writeFile(
join(path, "SKILL.md"),
[
"---",
`name: ${input.name}`,
`description: "${input.description}"`,
"---",
"",
`# ${input.name}`,
].join("\n"),
);
}
async function pathExists(path: string): Promise<boolean> {
try {
await stat(path);
return true;
} catch (error) {
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
return false;
}
throw error;
}
}
function renderMatrix(rows: CliSandboxMatrixRow[]): string {
return [
"| Metric | Baseline | Workflow | Delta |",
"| --- | --- | --- | --- |",
...rows.map((row) => `| ${row.metric} | ${row.baseline} | ${row.workflow} | ${row.delta} |`),
].join("\n");
}
function tokenSpendRows(baseline: CliSandboxRun, workflow: CliSandboxRun): CliSandboxMatrixRow[] {
return [
tokenRow("Input tokens", baseline.tokenSpend?.inputTokens, workflow.tokenSpend?.inputTokens),
tokenRow("Output tokens", baseline.tokenSpend?.outputTokens, workflow.tokenSpend?.outputTokens),
tokenRow("Total tokens", totalTokens(baseline.tokenSpend), totalTokens(workflow.tokenSpend)),
tokenRow(
"Tokens per accepted criterion",
tokensPerAcceptedCriterion(baseline),
tokensPerAcceptedCriterion(workflow),
),
];
}
function tokenRow(
metric: string,
baseline: number | undefined,
workflow: number | undefined,
): CliSandboxMatrixRow {
if (baseline === undefined || workflow === undefined) {
return textRow(metric, "unavailable", "unavailable", "unavailable");
}
return countRow(metric, baseline, workflow);
}
function totalTokens(tokens: CliSandboxTokenSpend | null): number | undefined {
if (!tokens || tokens.inputTokens === undefined || tokens.outputTokens === undefined) {
return undefined;
}
return tokens.inputTokens + tokens.outputTokens;
}
function tokensPerAcceptedCriterion(run: CliSandboxRun): number | undefined {
const total = totalTokens(run.tokenSpend);
const passed = countPassedCriteria(run);
if (total === undefined || passed === 0) {
return undefined;
}
return total / passed;
}
function millisecondsRow(metric: string, baseline: number, workflow: number): CliSandboxMatrixRow {
return textRow(
metric,
`${Math.round(baseline)} ms`,
`${Math.round(workflow)} ms`,
`${formatSignedNumber(Math.round(workflow - baseline))} ms`,
);
}
function countRow(metric: string, baseline: number, workflow: number): CliSandboxMatrixRow {
return textRow(
metric,
formatNumber(baseline),
formatNumber(workflow),
formatSignedNumber(workflow - baseline),
);
}
function percentRow(metric: string, baseline: number, workflow: number): CliSandboxMatrixRow {
return textRow(
metric,
`${formatNumber(baseline)}%`,
`${formatNumber(workflow)}%`,
`${formatSignedNumber(workflow - baseline)} pp`,
);
}
function textRow(
metric: string,
baseline: string,
workflow: string,
delta: string,
): CliSandboxMatrixRow {
return { metric, baseline, workflow, delta };
}
function criteriaPassRate(run: CliSandboxRun): number {
if (run.criteria.length === 0) {
return 100;
}
return (countPassedCriteria(run) / run.criteria.length) * 100;
}
function countPassedCriteria(run: CliSandboxRun): number {
return run.criteria.filter((criterion) => criterion.passed).length;
}
function sum(values: number[]): number {
return values.reduce((total, value) => total + value, 0);
}
function formatNumber(value: number): string {
return Number.isInteger(value) ? String(value) : value.toFixed(2);
}
function formatSignedNumber(value: number): string {
if (value > 0) {
return `+${formatNumber(value)}`;
}
return formatNumber(value);
}
function stripAnsi(value: string): string {
const escapeCharacter = String.fromCharCode(27);
return value.replace(new RegExp(`${escapeCharacter}\\[[0-?]*[ -/]*[@-~]`, "g"), "");
}
+17
-13

@@ -1,8 +0,12 @@

# OpenSpec + Superpowers GetSuperpower
# OpenSpec Delivery GetSuperpower
This example turns the OpenSpec + Superpowers handoff diagram into an installable
GetSuperpower reference.
This example turns an OpenSpec delivery loop into an installable GetSuperpower
reference. The user calls one professional entry skill, and that skill
coordinates proposal, design, planning, implementation, verification, and
archive work.
It models a closed AI-assisted development loop:
<img src="../../../assets/diagrams/openspec-delivery-workflow.svg" alt="OpenSpec Delivery workflow diagram" width="920" />
It models a closed AI-assisted delivery loop:
1. OpenSpec runs `/opsx:propose` to define scope and generate `proposal.md`,

@@ -22,3 +26,3 @@ `specs/`, and `tasks.md`.

```text
skills/openspec-superpowers/SKILL.md
skills/openspec-delivery/SKILL.md
```

@@ -29,3 +33,3 @@

```text
$openspec-superpowers implement this OpenSpec change
$openspec-delivery implement this OpenSpec change
```

@@ -48,3 +52,3 @@

- `./skills/openspec-superpowers`
- `./skills/openspec-delivery`
- `./skills/opsx-handoff-review`

@@ -69,3 +73,3 @@ - `superpowers:brainstorming`

```bash
bun run dev -- getsuperpower validate examples/workflows/openspec-superpowers
bun run dev -- validate examples/workflows/openspec-superpowers
```

@@ -76,3 +80,3 @@

```bash
bun run dev -- getsuperpower deps examples/workflows/openspec-superpowers
bun run dev -- deps examples/workflows/openspec-superpowers
```

@@ -83,9 +87,9 @@

```bash
bun run dev -- getsuperpower install examples/workflows/openspec-superpowers
bun run dev -- getsuperpower clone examples/workflows/openspec-superpowers
bun run dev -- install examples/workflows/openspec-superpowers
bun run dev -- clone examples/workflows/openspec-superpowers
```
`getsuperpower clone <source>` is equivalent to `getsuperpower install <source>`.
`clone <source>` is equivalent to `install <source>`.
Restart the agent app after install so the `$openspec-superpowers` entry skill
Restart the agent app after install so the `$openspec-delivery` entry skill
and its sub-skills are available.
{
"schemaVersion": "0.1",
"name": "openspec-superpowers",
"name": "openspec-delivery",
"version": "0.1.0",
"description": "OpenSpec proposes, reviews, and archives while Superpowers deepens design, executes task by task, and verifies delivery.",
"description": "Professional OpenSpec delivery workflow from proposal through design, plan, TDD implementation, verification, and archive.",
"skills": [
{
"source": "./skills/openspec-superpowers"
"source": "./skills/openspec-delivery"
},

@@ -10,0 +10,0 @@ {

{
"name": "getsuperpower",
"version": "0.3.1",
"version": "0.3.2",
"type": "module",

@@ -16,3 +16,2 @@ "repository": {

"bundled-skills",
"bundled-workflows",
"examples"

@@ -29,2 +28,3 @@ ],

"deps:check-recency": "bun scripts/check-package-recency.ts",
"sandbox:evaluate-cli": "bun scripts/evaluate-cli-sandbox.ts",
"typecheck": "tsc --noEmit",

@@ -31,0 +31,0 @@ "format": "biome format --write .",

+44
-49

@@ -5,21 +5,23 @@ <img src="/assets/getsupwerpower.jpg" alt="GetSuperpower" width="640" />

GetSuperpower installs reusable AI-agent workflows.
GetSuperpower packages a whole AI-agent workflow as one callable skill.
A **GetSuperpower** is a deployable bundle skills set for an AI agent workflow.
It installs the skills a project needs, records the workflow under `.getsuperpower/`,
and can give users one entry skill to call when the workflow provides one.
A **GetSuperpower** is an all-in-one workflow skill. Install it once, call one
entry skill, and the agent follows the required sub-skills in order. A workflow
can plan a spec, brainstorm design, write an implementation plan, build with
TDD, and archive the result without the user calling each skill separately.
## Quick Start
Install or clone the default product-development GetSuperpower:
Install a workflow example from the GetSuperpower git repository:
```bash
npx getsuperpower install product-dev
npx getsuperpower@latest install 'https://github.com/0xroylee/getsuperpower.git#examples/workflows/openspec-superpowers'
```
Install from a public git repository:
Install other workflow examples the same way:
```bash
npx getsuperpower install https://github.com/acme/release-review.git
npx getsuperpower install 'https://github.com/acme/workflows.git#examples/release-review'
npx getsuperpower@latest install 'https://github.com/0xroylee/getsuperpower.git#examples/workflows/release-review'
npx getsuperpower@latest clone 'https://github.com/0xroylee/getsuperpower.git#examples/workflows/real-engineering'
npx getsuperpower@latest install 'https://github.com/0xroylee/getsuperpower.git#examples/workflows/development-design-delivery'
```

@@ -30,6 +32,6 @@

```bash
npx getsuperpower list
npx getsuperpower@latest list
```
Supported agents: Claude, Codex, opencode, Cursor, and GitHub Copilot.
Supported agents: Claude, Codex, Cursor, opencode/OpenCodex, and GitHub Copilot. CLI aliases include `opencode`, `opencodex`, `copilot`, and `github-copilot`.

@@ -42,3 +44,3 @@ Restart your agent after installing skills so it reloads them.

`workflow.json` installs the skill tree. The entry skill runs it. Sub-skills are the steps the agent follows.
`workflow.json` installs the skill tree. The entry skill is the one command users invoke. Sub-skills are the steps the agent follows behind that call.

@@ -49,20 +51,2 @@ ### Install And Run Sequence

## Try A Callable Workflow
Some GetSuperpowers include an entry skill. That is the one skill a user calls to run the whole skill tree.
From a cloned repo, the OpenSpec + Superpowers example installs `$openspec-superpowers`:
```bash
npx getsuperpower install examples/workflows/openspec-superpowers
```
Then restart your agent app and invoke:
```text
$openspec-superpowers implement this OpenSpec change
```
The entry skill tells the agent to use the required sub-skills in order. The CLI handles installation, validation, and local workflow records.
## Create Your Own

@@ -75,3 +59,3 @@

```bash
npx getsuperpower init release-review
npx getsuperpower@latest init release-review
```

@@ -97,3 +81,3 @@

```bash
npx getsuperpower skills install creating-bundle-skills
npx getsuperpower@latest skills install creating-bundle-skills
```

@@ -113,4 +97,4 @@

```bash
npx getsuperpower validate release-review
npx getsuperpower deps release-review
npx getsuperpower@latest validate release-review
npx getsuperpower@latest deps release-review
```

@@ -124,3 +108,4 @@

| --- | --- | --- |
| `examples/workflows/openspec-superpowers` | OpenSpec proposal -> Superpowers planning/TDD -> archive. | Includes `$openspec-superpowers`. |
| `examples/workflows/openspec-superpowers` | OpenSpec Delivery: proposal -> design -> plan -> TDD -> verification -> archive. | Includes `$openspec-delivery`. |
| `examples/workflows/development-design-delivery` | Product-minded engineering: shape -> interface design -> plan -> TDD -> review -> evidence. | Includes `$development-design-delivery`. |
| `examples/workflows/real-engineering` | RTK, `pony-trail`, Superpowers, and Matt Pocock skills together. | Fetches Matt Pocock skills if missing. |

@@ -132,20 +117,21 @@ | `examples/workflows/release-review` | Small release-risk review workflow. | Good starter example. |

```bash
npx getsuperpower skills install mattpocock/skills
npx getsuperpower@latest skills install mattpocock/skills
```
## Common Commands
## Commands
| Command | Purpose |
| --- | --- |
| `npx getsuperpower install product-dev` | Install the default GetSuperpower. |
| `npx getsuperpower clone product-dev` | Same as install; deploy a GetSuperpower by name or source. |
| `npx getsuperpower install https://github.com/acme/release-review.git` | Install a GetSuperpower from a public git repo. |
| `npx getsuperpower deps <source>` | Show required skills before install or clone. |
| `npx getsuperpower list` | Show installed GetSuperpowers. |
| `npx getsuperpower init <name>` | Create a GetSuperpower scaffold. |
| `npx getsuperpower validate <path>` | Validate a workflow manifest. |
| `npx getsuperpower skills install` | Install the GetSuperpower authoring skill. |
| `npx getsuperpower skills install mattpocock/skills` | Install an external skills package through the Skills CLI. |
| `npx getsuperpower skills install creating-bundle-skills` | Install the GetSuperpower authoring skill. |
The GetSuperpower CLI supports workflow install, inspection, authoring, and skill management. Below are some of the most used commands:
- `npx getsuperpower@latest install <path-or-git-url>`
- `npx getsuperpower@latest clone <path-or-git-url>`
- `npx getsuperpower@latest deps <source>`
- `npx getsuperpower@latest list`
- `npx getsuperpower@latest init <name>`
- `npx getsuperpower@latest validate <path>`
- `npx getsuperpower@latest skills install`
- `npx getsuperpower@latest skills install mattpocock/skills`
- `npx getsuperpower@latest skills install creating-bundle-skills`
Run `npx getsuperpower@latest --help` or `npx getsuperpower@latest <command> --help` for detailed usage.
The older `bundle` and `workflow` commands still work as compatibility aliases.

@@ -176,4 +162,13 @@

Landing app:
```bash
cd landing
bun install
bun run dev
bun run build
```
## Compatibility
The package and CLI binary are named `getsuperpower`.

@@ -6,4 +6,11 @@ #!/usr/bin/env bun

import { Command } from "commander";
import pc from "picocolors";
import {
keyValue,
muted,
rootHelpBanner,
styleHelpTerm,
styleHelpTitle,
success,
} from "./cli-theme";
import {
configureGetSuperpowerCommand,

@@ -18,3 +25,3 @@ type GetSuperpowerExternalSkillDependencyInstaller,

const CLI_VERSION = "0.3.1";
const CLI_VERSION = "0.3.2";

@@ -44,2 +51,11 @@ interface CommanderVersionInternals {

.option("-v", "output the version number");
program.configureHelp({
styleTitle: styleHelpTitle,
styleSubcommandTerm: styleHelpTerm,
styleOptionTerm: styleHelpTerm,
});
program.addHelpText("before", rootHelpBanner);
program.action(() => {
program.help();
});

@@ -111,4 +127,4 @@ program.on("option:v", () => {

"-a, --agents <agents>",
"comma-separated targets: claude,copilot,codex,cursor",
"claude,copilot,codex,cursor",
"comma-separated targets: claude,copilot,codex,cursor,opencode (aliases: github-copilot,opencodex)",
"claude,copilot,codex,cursor,opencode",
)

@@ -258,9 +274,9 @@ .option("--home <dir>", "home directory that contains agent config folders", homedir())

): void {
console.log(pc.cyan(result.dryRun ? `Skill ${operation} plan` : `Skill ${operation} result`));
console.log(`Skill: ${result.skillName}`);
console.log(`${pc.dim("Source:")} ${result.source.path}`);
console.log(success(result.dryRun ? `Skill ${operation} plan` : `Skill ${operation} result`));
console.log(keyValue("Skill", result.skillName));
console.log(keyValue("Source", result.source.path));
for (const target of result.targets) {
console.log(
`${target.agent}: ${formatSkillInstallStatus(target.status)} ${pc.dim(target.destination)}`,
`${target.agent}: ${formatSkillInstallStatus(target.status)} ${muted(target.destination)}`,
);

@@ -272,9 +288,9 @@ }

console.log(
pc.cyan(result.dryRun ? `Prehook ${operation} plan` : `Prehook ${operation} result`),
success(result.dryRun ? `Prehook ${operation} plan` : `Prehook ${operation} result`),
);
for (const prehook of result.prehooks) {
console.log(
`${prehook.agent}: ${formatSkillInstallStatus(prehook.status)} ${pc.dim(
`${prehook.agent}: ${formatSkillInstallStatus(prehook.status)} ${muted(
prehook.hookScript,
)} ${pc.dim(`settings: ${prehook.settingsPath}`)}`,
)} ${muted(`settings: ${prehook.settingsPath}`)}`,
);

@@ -312,11 +328,11 @@ }

console.log(
pc.cyan(result.dryRun ? "Skills package install plan" : "Skills package install result"),
success(result.dryRun ? "Skills package install plan" : "Skills package install result"),
);
console.log(`Package: ${result.packageName}`);
console.log(`${pc.dim("Home:")} ${result.homeDir}`);
console.log(`${pc.dim("Internal command:")} npx --yes skills@latest add ${result.packageName}`);
console.log(keyValue("Package", result.packageName));
console.log(keyValue("Home", result.homeDir));
console.log(keyValue("Internal command", `npx --yes skills@latest add ${result.packageName}`));
if (!result.dryRun) {
console.log("");
console.log(pc.green("Welcome to GetSuperpower."));
console.log(success("Welcome to GetSuperpower."));
console.log("Restart your agent IDE so it loads the latest skills.");

@@ -332,3 +348,3 @@ }

console.log("");
console.log(pc.green("Welcome to GetSuperpower."));
console.log(success("Welcome to GetSuperpower."));
console.log("Restart your agent IDE so it loads the latest skills.");

@@ -335,0 +351,0 @@ }

@@ -0,7 +1,10 @@

import { existsSync } from "node:fs";
import { homedir } from "node:os";
import { isAbsolute, join, resolve } from "node:path";
import { cancel as clackCancel, confirm as clackConfirm, isCancel } from "@clack/prompts";
import type { Command } from "commander";
import pc from "picocolors";
import { commandText, keyValue, muted, nextStep, success, warning } from "./cli-theme";
import {
MissingMattPocockSkillError,
MissingSuperpowersSkillError,
parseSkillInstallAgents,

@@ -76,2 +79,23 @@ type SkillInstallResult,

export interface GetSuperpowerOnboardPrompt {
confirm(input: { message: string; defaultValue: boolean }): Promise<boolean>;
}
export interface GetSuperpowerOnboardCommand {
executable: string;
args: string[];
cwd: string;
env: Record<string, string | undefined>;
}
export interface GetSuperpowerOnboardCommandResult {
stdout: string;
stderr: string;
exitCode: number;
}
export type GetSuperpowerOnboardCommandRunner = (
command: GetSuperpowerOnboardCommand,
) => Promise<GetSuperpowerOnboardCommandResult>;
export interface ConfigureGetSuperpowerCommandOptions {

@@ -83,2 +107,4 @@ rootDir: string;

workflowGitCommandRunner?: WorkflowGitCommandRunner;
onboardPrompt?: GetSuperpowerOnboardPrompt;
onboardCommandRunner?: GetSuperpowerOnboardCommandRunner;
}

@@ -122,2 +148,3 @@

configureDependencyCommand(command, options);
configureOnboardCommand(command, options);
}

@@ -140,5 +167,5 @@

console.log(`GetSuperpower created: ${scaffold.bundleDir}`);
console.log(`${pc.dim("Manifest:")} ${scaffold.manifestPath}`);
console.log(`${pc.dim("README:")} ${scaffold.readmePath}`);
console.log(success(`GetSuperpower created: ${scaffold.bundleDir}`));
console.log(keyValue("Manifest", scaffold.manifestPath));
console.log(keyValue("README", scaffold.readmePath));
});

@@ -158,5 +185,7 @@

try {
console.log(`GetSuperpower valid: ${bundle.manifest.name}@${bundle.manifest.version}`);
console.log(`${pc.dim("Steps:")} ${bundle.manifest.steps.length}`);
console.log(`${pc.dim("Skills:")} ${bundle.manifest.skills.length}`);
console.log(
success(`GetSuperpower valid: ${bundle.manifest.name}@${bundle.manifest.version}`),
);
console.log(keyValue("Steps", String(bundle.manifest.steps.length)));
console.log(keyValue("Skills", String(bundle.manifest.skills.length)));
} finally {

@@ -187,3 +216,3 @@ await bundle.cleanup?.();

.description("Install a GetSuperpower and its skills.")
.argument("<source>", "GetSuperpower name, local path, or workflow source")
.argument("<source>", "local GetSuperpower path, workflow.json path, or public git source")
.option(

@@ -196,3 +225,3 @@ "--dir <dir>",

"--agents <agents>",
"comma-separated skill install targets: codex,claude,cursor",
"comma-separated skill install targets: codex,claude,cursor,copilot,opencode (aliases: github-copilot,opencodex)",
"codex,claude,cursor",

@@ -242,4 +271,4 @@ )

console.log(`GetSuperpower installed: ${install.workflow.name}`);
console.log(`${pc.dim("GetSuperpower file:")} ${install.path}`);
console.log(success(`GetSuperpower installed: ${install.workflow.name}`));
console.log(keyValue("GetSuperpower file", install.path));
} finally {

@@ -268,3 +297,3 @@ await bundle.cleanup?.();

if (!input.installedExternalPackages.has(externalPackage)) {
console.log(`Installing external skill dependency with skills CLI: ${externalPackage}`);
console.log(keyValue("Installing external skill dependency", externalPackage));
await input.installExternalSkillDependency({

@@ -280,3 +309,3 @@ source: input.source,

} catch (retryError) {
if (retryError instanceof MissingMattPocockSkillError) {
if (isMissingBootstrappableSkillError(retryError)) {
throw new Error(

@@ -312,3 +341,3 @@ `The skills CLI ran for ${externalPackage}, but ${input.source} is still missing. ${retryError.message}`,

function getSkillsCliPackageForMissingDependency(source: string, error: unknown): string | null {
if (!(error instanceof MissingMattPocockSkillError)) {
if (!isMissingBootstrappableSkillError(error)) {
return null;

@@ -320,2 +349,10 @@ }

function isMissingBootstrappableSkillError(
error: unknown,
): error is MissingMattPocockSkillError | MissingSuperpowersSkillError {
return (
error instanceof MissingMattPocockSkillError || error instanceof MissingSuperpowersSkillError
);
}
export function getSkillsCliPackageForSource(source: string): string | null {

@@ -326,2 +363,6 @@ if (isBareSkillsCliPackage(source)) {

if (source.startsWith("superpowers:")) {
return "obra/superpowers";
}
if (source.startsWith("mattpocock:")) {

@@ -406,3 +447,4 @@ return "mattpocock/skills";

if (workflows.length === 0) {
console.log(pc.dim("No GetSuperpowers installed."));
console.log(muted("No GetSuperpowers installed."));
console.log(nextStep("getsuperpower install <path-or-git-url>"));
return;

@@ -425,3 +467,3 @@ }

.description("List the skill dependencies declared by a GetSuperpower.")
.argument("<source>", "bundled GetSuperpower name or local GetSuperpower path")
.argument("<source>", "local GetSuperpower path, workflow.json path, or public git source")
.action(async (source: string) => {

@@ -435,3 +477,3 @@ const bundle = await loadWorkflowBundle(source, {

try {
console.log(`GetSuperpower dependencies: ${bundle.manifest.name}`);
console.log(success(`GetSuperpower dependencies: ${bundle.manifest.name}`));
for (const skill of bundle.manifest.skills) {

@@ -447,2 +489,108 @@ const optional = skill.optional ? " (optional)" : "";

function configureOnboardCommand(
command: Command,
options: ConfigureGetSuperpowerCommandOptions,
): void {
command
.command("onboard")
.description("Step through RTK and CodeGraph setup for this workspace.")
.option("--dir <dir>", "project directory to onboard", options.rootDir)
.action((commandOptions: { dir: string }) => runGetSuperpowerOnboard(commandOptions, options));
}
async function runGetSuperpowerOnboard(
commandOptions: { dir: string },
options: ConfigureGetSuperpowerCommandOptions,
): Promise<void> {
const targetDir = resolvePath(options.rootDir, commandOptions.dir);
if (!existsSync(targetDir)) {
throw new Error(`Onboard target directory does not exist: ${targetDir}`);
}
const prompt = options.onboardPrompt ?? createDefaultOnboardPrompt();
const runCommand = options.onboardCommandRunner ?? runExternalSkillCommand;
console.log(success("GetSuperpower onboard"));
console.log(keyValue("Workspace", targetDir));
const rtkResult = await runCommand({
executable: "rtk",
args: ["--version"],
cwd: targetDir,
env: process.env,
});
if (rtkResult.exitCode === 0) {
console.log(success("RTK ready"));
} else if (
await prompt.confirm({
message: "RTK is not available. Show RTK setup guidance to reduce Codex token usage?",
defaultValue: true,
})
) {
printRtkSetupGuidance();
} else {
console.log(warning("RTK setup skipped"));
}
const codegraphDir = join(targetDir, ".codegraph");
if (existsSync(codegraphDir)) {
console.log(success("CodeGraph ready"));
} else if (
await prompt.confirm({
message: "CodeGraph is not initialized. Index this codebase with CodeGraph now?",
defaultValue: true,
})
) {
await runCodeGraphInit({ targetDir, runCommand });
} else {
console.log(warning("CodeGraph setup skipped"));
}
console.log(success("GetSuperpower onboard complete"));
}
function printRtkSetupGuidance(): void {
console.log(success("RTK setup guidance"));
console.log("Install or enable RTK, then verify it with:");
console.log(commandText("rtk --version"));
}
async function runCodeGraphInit(input: {
targetDir: string;
runCommand: GetSuperpowerOnboardCommandRunner;
}): Promise<void> {
const result = await input.runCommand({
executable: "codegraph",
args: ["init", "-i"],
cwd: input.targetDir,
env: process.env,
});
if (result.exitCode !== 0) {
const detail = result.stderr.trim() || result.stdout.trim() || `exit ${result.exitCode}`;
throw new Error(`CodeGraph setup failed while running codegraph init -i: ${detail}`);
}
console.log(success("CodeGraph indexed"));
}
function createDefaultOnboardPrompt(): GetSuperpowerOnboardPrompt {
return {
confirm: async (input) => {
const result = await clackConfirm({
message: input.message,
initialValue: input.defaultValue,
});
if (isCancel(result)) {
clackCancel("GetSuperpower onboard cancelled");
throw new Error("GetSuperpower onboard cancelled");
}
return result;
},
};
}
function resolvePath(rootDir: string, path: string): string {

@@ -449,0 +597,0 @@ return isAbsolute(path) ? path : resolve(join(rootDir, path));

@@ -6,4 +6,4 @@ import { constants, type Dirent } from "node:fs";

export type SkillInstallAgent = "claude" | "copilot" | "codex" | "cursor";
type HookCapableSkillInstallAgent = Exclude<SkillInstallAgent, "cursor">;
export type SkillInstallAgent = "claude" | "copilot" | "codex" | "cursor" | "opencode";
type HookCapableSkillInstallAgent = Exclude<SkillInstallAgent, "cursor" | "opencode">;

@@ -126,2 +126,3 @@ export type SkillInstallStatus =

cursor: { kind: "cursor_rule", path: [".cursor", "rules"] },
opencode: { kind: "directory", path: [".agents", "skills"] },
};

@@ -333,3 +334,5 @@

const homeDir = options.homeDir ?? process.env.HOME ?? process.cwd();
const skillPath = await findSuperpowersSkillPath(homeDir, skill.skillFolder);
const skillPath =
(await findSuperpowersSkillPath(homeDir, skill.skillFolder)) ??
(await findInstalledSuperpowersSkillPath(homeDir, skill));

@@ -350,2 +353,12 @@ if (!skillPath) {

async function findInstalledSuperpowersSkillPath(
homeDir: string,
skill: SupportedSuperpowersSkill,
): Promise<string | null> {
return (
(await findInstalledSkillPath(homeDir, skill.installName)) ??
(await findInstalledSkillPath(homeDir, skill.skillFolder))
);
}
async function findSuperpowersSkillPath(

@@ -406,3 +419,3 @@ homeDir: string,

export function parseSkillInstallAgents(rawAgents: string): SkillInstallAgent[] {
const agents = rawAgents
const rawAgentEntries = rawAgents
.split(",")

@@ -412,13 +425,21 @@ .map((agent) => agent.trim())

if (agents.length === 0) {
if (rawAgentEntries.length === 0) {
throw new Error("At least one agent target is required.");
}
for (const agent of agents) {
if (!isSkillInstallAgent(agent)) {
throw new Error(`Unknown skill install agent: ${agent}`);
const uniqueAgents: SkillInstallAgent[] = [];
const seenAgents = new Set<SkillInstallAgent>();
for (const rawAgent of rawAgentEntries) {
const agent = normalizeSkillInstallAgent(rawAgent);
if (!agent) {
throw new Error(`Unknown skill install agent: ${rawAgent}`);
}
if (!seenAgents.has(agent)) {
seenAgents.add(agent);
uniqueAgents.push(agent);
}
}
return agents as SkillInstallAgent[];
return uniqueAgents;
}

@@ -796,7 +817,29 @@

function isSkillInstallAgent(agent: string): agent is SkillInstallAgent {
return agent === "claude" || agent === "copilot" || agent === "codex" || agent === "cursor";
return (
agent === "claude" ||
agent === "copilot" ||
agent === "codex" ||
agent === "cursor" ||
agent === "opencode"
);
}
function normalizeSkillInstallAgent(agent: string): SkillInstallAgent | null {
const normalized = agent.toLowerCase();
const aliases: Record<string, SkillInstallAgent> = {
"github copilot": "copilot",
"github-copilot": "copilot",
githubcopilot: "copilot",
github_copilot: "copilot",
"open codex": "opencode",
"open-codex": "opencode",
opencodex: "opencode",
};
const canonical = aliases[normalized] ?? normalized;
return isSkillInstallAgent(canonical) ? canonical : null;
}
function hasPrehookSupport(agent: SkillInstallAgent): agent is HookCapableSkillInstallAgent {
return agent !== "cursor";
return agent !== "cursor" && agent !== "opencode";
}

@@ -809,3 +852,3 @@

function formatSuperpowersInstallCommand(source: string): string {
return `getsuperpower skills install ${source} --agents codex,claude,cursor --home ~`;
return `getsuperpower skills install ${source} --agents codex,claude,cursor,copilot,opencode --home ~`;
}

@@ -812,0 +855,0 @@

@@ -77,3 +77,3 @@ import { existsSync } from "node:fs";

| {
kind: "bundled" | "local";
kind: "local";
path: string;

@@ -348,4 +348,5 @@ }

const sourceDir = join(findBundledWorkflowsDir(), source);
return { sourceDir, source: { kind: "bundled", path: sourceDir } };
throw new Error(
`Unsupported GetSuperpower source: ${source}. Use a local path, workflow.json path, or public git URL.`,
);
}

@@ -515,19 +516,1 @@

}
function findBundledWorkflowsDir(): string {
const currentDir = dirname(new URL(import.meta.url).pathname);
const candidates = [
join(currentDir, "..", "..", "..", "bundled-workflows"),
join(currentDir, "..", "bundled-workflows"),
join(process.cwd(), "bundled-workflows"),
];
const found = candidates.find((candidate) =>
existsSync(join(candidate, "product-dev", workflowFileName)),
);
if (!found) {
throw new Error("Unable to locate bundled workflow files.");
}
return found;
}
# Product Dev GetSuperpower
This GetSuperpower composes a bundle-skills product-development path:
1. Shape the request with `superpowers:brainstorming`.
2. Write the implementation plan with `superpowers:writing-plans`.
It installs the GetSuperpower contract first. Automatic step execution is intentionally deferred.
{
"schemaVersion": "0.1",
"name": "product-dev",
"version": "0.1.0",
"description": "Shape and plan product development changes.",
"skills": [
{
"source": "superpowers:brainstorming"
},
{
"source": "superpowers:writing-plans"
}
],
"steps": [
{
"id": "shape",
"title": "Shape the request",
"skill": "superpowers:brainstorming",
"gate": "human_approval"
},
{
"id": "plan",
"title": "Write the implementation plan",
"skill": "superpowers:writing-plans"
}
]
}
---
name: openspec-superpowers
description: Use when running the OpenSpec + Superpowers GetSuperpower workflow, skill tree, or multi-skill development loop from proposal through archive.
---
# OpenSpec + Superpowers GetSuperpower
This is the entry skill for the openspec-superpowers GetSuperpower.
When this skill is used, run the workflow below in order. Load/use every required sub-skill before doing the work for its phase.
## Required Sub-Skills
Before doing workflow work, load/use these skills in order:
1. opsx-handoff-review (`./skills/opsx-handoff-review`) - OpenSpec proposal, review, handoff, and archive checkpoints
2. superpowers:brainstorming - design deepening before implementation planning
3. superpowers:writing-plans - split approved scope into executable tasks
4. mattpocock:tdd - build task by task with failing tests first
5. pony-trail - record file-change evidence, verification, and rollback context
If any required sub-skill is unavailable, stop and tell the user which dependency is missing.
## Flow
1. Run `/opsx:propose` to create proposal, specs, and tasks.
- Skill: opsx-handoff-review (`./skills/opsx-handoff-review`)
2. Review `proposal.md` with the human owner.
- Skill: opsx-handoff-review (`./skills/opsx-handoff-review`)
- Gate: wait for explicit human approval.
3. Deepen design details with Superpowers brainstorming.
- Skill: superpowers:brainstorming
- Gate: wait for explicit human approval.
4. Split tasks into an implementation plan.
- Skill: superpowers:writing-plans
5. Build each task with TDD and `specs/` context.
- Skill: mattpocock:tdd
6. Verify delivery and preserve evidence.
- Skill: pony-trail
7. Run `/opsx:archive` to update specs and project knowledge.
- Skill: opsx-handoff-review (`./skills/opsx-handoff-review`)
- Gate: wait for explicit human approval.
## Author Notes
- Keep this entry skill, `workflow.json`, and `README.md` aligned when adding or removing steps.
- This skill orchestrates through required instructions; GetSuperpower installs and validates the dependency skills.
- Do not silently skip OpenSpec review, human approval gates, TDD, verification, or archive.

Sorry, the diff of this file is too big to display