🎩 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.4
to
0.3.5
+1
-1
package.json
{
"name": "getsuperpower",
"version": "0.3.4",
"version": "0.3.5",
"type": "module",

@@ -5,0 +5,0 @@ "repository": {

@@ -142,7 +142,8 @@ <img src="/assets/getsupwerpower.jpg" alt="GetSuperpower" width="640" />

## Local Files
## Installed Files
The CLI writes installed workflow records under `.getsuperpower/`:
By default, the CLI writes installed workflow records under your home directory:
```text
~/
.getsuperpower/

@@ -152,5 +153,7 @@ workflows/

Use `--dir <project>` when you intentionally want a project-local workflow record.
Pony Trail history, revert, and prehook features are paused while GetSuperpower focuses on bundle skills.
Keep `.getsuperpower/` out of git unless you intentionally want to share installed workflow records.
Keep project-local `.getsuperpower/` folders out of git unless you intentionally want to share installed workflow records.

@@ -157,0 +160,0 @@ ## Local Development

@@ -44,2 +44,27 @@ import pc from "picocolors";

export function borderBox(lines: string[]): string {
const content = lines.flatMap((line) => line.split("\n"));
const width = Math.max(...content.map((line) => line.length), 1);
const horizontal = `+${"-".repeat(width + 2)}+`;
return [horizontal, ...content.map((line) => `| ${line.padEnd(width)} |`), horizontal].join("\n");
}
export function getSuperpowerInstallResultBox(input: {
workflowName: string;
workflowVersion: string;
workflowFile: string;
skillCount: number;
}): string {
return brand(
borderBox([
GETSUPERPOWER_ASCII_LOGO,
"",
`GetSuperpower installed: ${input.workflowName}`,
`Version: ${input.workflowVersion}`,
`Skills installed: ${input.skillCount}`,
`GetSuperpower file: ${input.workflowFile}`,
]),
);
}
export function rootHelpBanner(): string {

@@ -46,0 +71,0 @@ return [

@@ -24,3 +24,3 @@ #!/usr/bin/env bun

const CLI_VERSION = "0.3.4";
const CLI_VERSION = "0.3.5";

@@ -27,0 +27,0 @@ interface CommanderVersionInternals {

@@ -6,4 +6,12 @@ import { existsSync } from "node:fs";

import type { Command } from "commander";
import { commandText, keyValue, muted, nextStep, success, warning } from "./cli-theme";
import {
commandText,
getSuperpowerInstallResultBox,
keyValue,
muted,
nextStep,
success,
warning,
} from "./cli-theme";
import {
MissingMattPocockSkillError,

@@ -85,2 +93,20 @@ MissingSuperpowersSkillError,

export interface GetSuperpowerInstallSkillPlan {
source: string;
repo?: string | undefined;
}
export interface GetSuperpowerInstallPromptInput {
workflowName: string;
workflowVersion: string;
skills: GetSuperpowerInstallSkillPlan[];
targetDir: string;
homeDir: string;
agents: ReturnType<typeof parseSkillInstallAgents>;
}
export interface GetSuperpowerInstallPrompt {
confirmInstall(input: GetSuperpowerInstallPromptInput): Promise<boolean>;
}
export interface GetSuperpowerOnboardCommand {

@@ -108,2 +134,3 @@ executable: string;

installExternalSkillDependency?: GetSuperpowerExternalSkillDependencyInstaller;
installPrompt?: GetSuperpowerInstallPrompt;
workflowGitCommandRunner?: WorkflowGitCommandRunner;

@@ -115,3 +142,3 @@ onboardPrompt?: GetSuperpowerOnboardPrompt;

interface GetSuperpowerInstallCommandOptions {
dir: string;
dir?: string;
agents: string;

@@ -206,8 +233,4 @@ home: string;

)
.option("--dir <dir>", "override directory that receives .getsuperpower/workflows")
.option(
"--dir <dir>",
"project directory that receives .getsuperpower/workflows",
options.rootDir,
)
.option(
"--agents <agents>",

@@ -217,3 +240,7 @@ "comma-separated skill install targets: codex,claude,cursor,copilot,opencode (aliases: github-copilot,opencodex)",

)
.option("--home <dir>", "home directory that contains agent config folders", homedir())
.option(
"--home <dir>",
"home directory for global GetSuperpower records and agent config folders",
homedir(),
)
.action((source: string, commandOptions: GetSuperpowerInstallCommandOptions) =>

@@ -229,3 +256,4 @@ runGetSuperpowerInstall(source, commandOptions, options),

): Promise<void> {
const targetDir = resolvePath(options.rootDir, commandOptions.dir);
const homeDir = resolveHomePath(commandOptions.home);
const targetDir = commandOptions.dir ? resolvePath(options.rootDir, commandOptions.dir) : homeDir;
const bundle = await loadWorkflowBundle(source, {

@@ -238,7 +266,35 @@ cwd: options.rootDir,

const installAgents = parseSkillInstallAgents(commandOptions.agents);
const homeDir = resolveHomePath(commandOptions.home);
const installedExternalPackages = new Set<string>();
const skillPlans = getWorkflowInstallSkillPlans(bundle);
const installPrompt = options.installPrompt ?? createDefaultInstallPrompt();
try {
for (const skillDependency of getWorkflowSkillInstallDependencies(bundle)) {
printGetSuperpowerInstallPlan({
workflowName: bundle.manifest.name,
workflowVersion: bundle.manifest.version,
skills: skillPlans,
targetDir,
homeDir,
});
const approved = await installPrompt.confirmInstall({
workflowName: bundle.manifest.name,
workflowVersion: bundle.manifest.version,
skills: skillPlans,
targetDir,
homeDir,
agents: installAgents,
});
if (!approved) {
console.log(warning("GetSuperpower install cancelled."));
return;
}
console.log(success("Installing skills..."));
const skillDependencies = getWorkflowSkillInstallDependencies(bundle);
for (const [index, skillDependency] of skillDependencies.entries()) {
const displaySkill = skillPlans[index]?.source ?? skillDependency.source;
console.log(`Processing ${index + 1}/${skillDependencies.length}: ${displaySkill}`);
const skillResult = await installGetSuperpowerSkillDependency({

@@ -259,2 +315,3 @@ rootDir: targetDir,

});
console.log(success(`Installed skill: ${skillResult.skillInstall.skillName}`));
}

@@ -266,2 +323,10 @@

console.log(keyValue("GetSuperpower file", install.path));
console.log(
getSuperpowerInstallResultBox({
workflowName: install.workflow.name,
workflowVersion: install.workflow.version,
workflowFile: install.path,
skillCount: skillDependencies.length,
}),
);
} finally {

@@ -272,2 +337,33 @@ await bundle.cleanup?.();

function getWorkflowInstallSkillPlans(bundle: {
manifest: { skills: GetSuperpowerInstallSkillPlan[] };
}): GetSuperpowerInstallSkillPlan[] {
return bundle.manifest.skills.map((skill) => ({
source: skill.source,
...(skill.repo ? { repo: skill.repo } : {}),
}));
}
function printGetSuperpowerInstallPlan(input: {
workflowName: string;
workflowVersion: string;
skills: GetSuperpowerInstallSkillPlan[];
targetDir: string;
homeDir: string;
}): void {
console.log(
success(`GetSuperpower install plan: ${input.workflowName}@${input.workflowVersion}`),
);
console.log(keyValue("Workflow records", input.targetDir));
console.log(keyValue("Skill home", input.homeDir));
console.log("Skills to install:");
for (const skill of input.skills) {
console.log(`- ${formatInstallSkillPlan(skill)}`);
}
}
function formatInstallSkillPlan(skill: GetSuperpowerInstallSkillPlan): string {
return skill.repo ? `${skill.source} (${skill.repo})` : skill.source;
}
async function installGetSuperpowerSkillDependency(input: {

@@ -501,6 +597,10 @@ rootDir: string;

.description("List installed GetSuperpowers.")
.option("--dir <dir>", "project directory with .getsuperpower/workflows", rootDir)
.action(async (commandOptions: { dir: string }) => {
.option("--dir <dir>", "override directory with .getsuperpower/workflows")
.option("--home <dir>", "home directory that contains global GetSuperpower records", homedir())
.action(async (commandOptions: { dir?: string; home: string }) => {
const targetDir = commandOptions.dir
? resolvePath(rootDir, commandOptions.dir)
: resolveHomePath(commandOptions.home);
const workflows = await listInstalledWorkflowBundles({
rootDir: resolvePath(rootDir, commandOptions.dir),
rootDir: targetDir,
});

@@ -654,2 +754,25 @@

function createDefaultInstallPrompt(): GetSuperpowerInstallPrompt {
return {
confirmInstall: async (input) => {
if (!process.stdin.isTTY) {
console.log(muted("Non-interactive shell detected; continuing with install."));
return true;
}
const result = await clackConfirm({
message: `Install ${input.skills.length} skills for ${input.workflowName}?`,
initialValue: true,
});
if (isCancel(result)) {
clackCancel("GetSuperpower install cancelled");
return false;
}
return result;
},
};
}
function resolvePath(rootDir: string, path: string): string {

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

@@ -203,3 +203,3 @@ import { mkdir, mkdtemp, stat, writeFile } from "node:fs/promises";

const workflowRecord = join(
input.projectDir,
input.homeDir,
".getsuperpower",

@@ -264,3 +264,3 @@ "workflows",

["install", input.workflowSourcePath, "--home", input.homeDir, "--agents", "codex"],
["list"],
["list", "--home", input.homeDir],
],

@@ -270,3 +270,3 @@ });

const workflowRecord = join(
input.projectDir,
input.homeDir,
".getsuperpower",

@@ -294,3 +294,3 @@ "workflows",

passed: await pathExists(workflowRecord),
detail: ".getsuperpower/workflows/openspec-delivery.json should exist",
detail: "global .getsuperpower/workflows/openspec-delivery.json should exist",
},

@@ -297,0 +297,0 @@ {

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