@nst173/superpowers-ccg 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/skills/brainstorming/SKILL.md +26 -0
- package/.agent/skills/coordinating-multi-model-work/SKILL.md +29 -0
- package/.agent/skills/executing-plans/SKILL.md +27 -0
- package/.agent/skills/using-superpowers/SKILL.md +29 -0
- package/.agent/skills/verifying-before-completion/SKILL.md +20 -0
- package/.agent/skills/writing-plans/SKILL.md +29 -0
- package/.cursor/agents/code-reviewer.md +22 -0
- package/.cursor/commands/brainstorm.md +11 -0
- package/.cursor/commands/execute-plan.md +12 -0
- package/.cursor/commands/write-plan.md +11 -0
- package/.cursor/hook-scripts/after-file-edit.mjs +3 -0
- package/.cursor/hook-scripts/before-shell-execution.mjs +3 -0
- package/.cursor/hook-scripts/session-end.mjs +3 -0
- package/.cursor/hooks.json +21 -0
- package/.cursor/mcp.json +20 -0
- package/.cursor/rules/checkpoint-protocol.mdc +11 -0
- package/.cursor/rules/orchestrator-routing.mdc +12 -0
- package/.cursor/rules/token-discipline.mdc +12 -0
- package/.cursor/skills/brainstorming/SKILL.md +26 -0
- package/.cursor/skills/coordinating-multi-model-work/SKILL.md +29 -0
- package/.cursor/skills/executing-plans/SKILL.md +27 -0
- package/.cursor/skills/using-superpowers/SKILL.md +29 -0
- package/.cursor/skills/verifying-before-completion/SKILL.md +20 -0
- package/.cursor/skills/writing-plans/SKILL.md +29 -0
- package/AGENTS.md +23 -0
- package/CLAUDE.md +78 -0
- package/GEMINI.md +27 -0
- package/LICENSE +21 -0
- package/README.md +171 -0
- package/agents/code-reviewer.md +54 -0
- package/cli/superpowers-ccg.mjs +8 -0
- package/commands/brainstorm.md +6 -0
- package/commands/execute-plan.md +6 -0
- package/commands/write-plan.md +6 -0
- package/config/antigravity/mcp_config.example.json +26 -0
- package/hooks/hooks.json +37 -0
- package/hooks/pre-tool-use-task.sh +4 -0
- package/hooks/run-hook.cmd +19 -0
- package/hooks/session-start.sh +72 -0
- package/hooks/user-prompt-submit.sh +31 -0
- package/package.json +56 -0
- package/skills/EVALUATION.md +201 -0
- package/skills/brainstorming/SKILL.md +120 -0
- package/skills/coordinating-multi-model-work/GATE.md +36 -0
- package/skills/coordinating-multi-model-work/INTEGRATION.md +51 -0
- package/skills/coordinating-multi-model-work/SKILL.md +51 -0
- package/skills/coordinating-multi-model-work/checkpoints.md +31 -0
- package/skills/coordinating-multi-model-work/cross-validation.md +37 -0
- package/skills/coordinating-multi-model-work/prompts/codex-base.md +40 -0
- package/skills/coordinating-multi-model-work/prompts/gemini-base.md +41 -0
- package/skills/coordinating-multi-model-work/review-chain.md +25 -0
- package/skills/coordinating-multi-model-work/routing-decision.md +50 -0
- package/skills/debugging-systematically/CREATION-LOG.md +119 -0
- package/skills/debugging-systematically/SKILL.md +325 -0
- package/skills/debugging-systematically/condition-based-waiting-example.ts +158 -0
- package/skills/debugging-systematically/condition-based-waiting.md +115 -0
- package/skills/debugging-systematically/defense-in-depth.md +122 -0
- package/skills/debugging-systematically/find-polluter.sh +63 -0
- package/skills/debugging-systematically/root-cause-tracing.md +169 -0
- package/skills/debugging-systematically/test-academic.md +14 -0
- package/skills/debugging-systematically/test-pressure-1.md +58 -0
- package/skills/debugging-systematically/test-pressure-2.md +68 -0
- package/skills/debugging-systematically/test-pressure-3.md +69 -0
- package/skills/developing-with-subagents/SKILL.md +51 -0
- package/skills/developing-with-subagents/code-quality-reviewer-prompt.md +30 -0
- package/skills/developing-with-subagents/implementer-prompt.md +41 -0
- package/skills/developing-with-subagents/spec-reviewer-prompt.md +25 -0
- package/skills/dispatching-parallel-agents/SKILL.md +195 -0
- package/skills/executing-plans/SKILL.md +67 -0
- package/skills/finishing-development-branches/SKILL.md +208 -0
- package/skills/practicing-test-driven-development/SKILL.md +346 -0
- package/skills/practicing-test-driven-development/testing-anti-patterns.md +299 -0
- package/skills/receiving-code-review/SKILL.md +221 -0
- package/skills/requesting-code-review/SKILL.md +127 -0
- package/skills/requesting-code-review/code-reviewer.md +146 -0
- package/skills/shared/multi-model-integration-section.md +32 -0
- package/skills/shared/protocol-threshold.md +46 -0
- package/skills/shared/supplementary-tools.md +132 -0
- package/skills/shared/task-format-reference.md +83 -0
- package/skills/using-git-worktrees/SKILL.md +225 -0
- package/skills/using-superpowers/SKILL.md +101 -0
- package/skills/verifying-before-completion/SKILL.md +159 -0
- package/skills/writing-plans/SKILL.md +55 -0
- package/skills/writing-skills/CHECKLIST.md +92 -0
- package/skills/writing-skills/SKILL.md +111 -0
- package/skills/writing-skills/STRUCTURE.md +208 -0
- package/skills/writing-skills/TESTING.md +155 -0
- package/skills/writing-skills/anthropic-best-practices.md +1150 -0
- package/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/skills/writing-skills/persuasion-principles.md +187 -0
- package/skills/writing-skills/render-graphs.js +168 -0
- package/skills/writing-skills/testing-skills-with-subagents.md +384 -0
- package/src/cli.mjs +165 -0
- package/src/constants.mjs +7 -0
- package/src/install.mjs +186 -0
- package/src/io.mjs +81 -0
package/src/install.mjs
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { AGENT_LABELS } from "./constants.mjs";
|
|
4
|
+
import {
|
|
5
|
+
chmodExecutable,
|
|
6
|
+
copyDirectory,
|
|
7
|
+
copyFile,
|
|
8
|
+
ensureDir,
|
|
9
|
+
pathExists,
|
|
10
|
+
readJsonIfExists,
|
|
11
|
+
writeJson
|
|
12
|
+
} from "./io.mjs";
|
|
13
|
+
|
|
14
|
+
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
15
|
+
|
|
16
|
+
function source(...segments) {
|
|
17
|
+
return path.join(packageRoot, ...segments);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function claudeHooksSettings() {
|
|
21
|
+
return {
|
|
22
|
+
hooks: {
|
|
23
|
+
SessionStart: [
|
|
24
|
+
{
|
|
25
|
+
matcher: "startup|resume|clear|compact",
|
|
26
|
+
hooks: [
|
|
27
|
+
{
|
|
28
|
+
type: "command",
|
|
29
|
+
command: "\".claude/hooks/run-hook.cmd\" session-start.sh"
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
UserPromptSubmit: [
|
|
35
|
+
{
|
|
36
|
+
matcher: "*",
|
|
37
|
+
hooks: [
|
|
38
|
+
{
|
|
39
|
+
type: "command",
|
|
40
|
+
command: "\".claude/hooks/run-hook.cmd\" user-prompt-submit.sh"
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
PreToolUse: [
|
|
46
|
+
{
|
|
47
|
+
matcher: "Task",
|
|
48
|
+
hooks: [
|
|
49
|
+
{
|
|
50
|
+
type: "command",
|
|
51
|
+
command: "\".claude/hooks/run-hook.cmd\" pre-tool-use-task.sh"
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function mergeMcp(existing) {
|
|
61
|
+
const base = existing && typeof existing === "object" ? existing : {};
|
|
62
|
+
const baseServers = base.mcpServers && typeof base.mcpServers === "object" ? base.mcpServers : {};
|
|
63
|
+
const desired = JSON.parse(
|
|
64
|
+
JSON.stringify({
|
|
65
|
+
codex: {
|
|
66
|
+
command: "uvx",
|
|
67
|
+
args: ["--from", "git+https://github.com/GuDaStudio/codexmcp.git", "codexmcp"],
|
|
68
|
+
env: {
|
|
69
|
+
OPENAI_API_KEY: "${OPENAI_API_KEY}"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
gemini: {
|
|
73
|
+
command: "uvx",
|
|
74
|
+
args: ["--from", "git+https://github.com/GuDaStudio/geminimcp.git", "geminimcp"],
|
|
75
|
+
env: {
|
|
76
|
+
GEMINI_API_KEY: "${GEMINI_API_KEY}"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
...base,
|
|
84
|
+
mcpServers: {
|
|
85
|
+
...desired,
|
|
86
|
+
...baseServers
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function mergeHooks(existing, desired) {
|
|
92
|
+
const base = existing && typeof existing === "object" ? existing : {};
|
|
93
|
+
const baseHooks = base.hooks && typeof base.hooks === "object" ? base.hooks : {};
|
|
94
|
+
return {
|
|
95
|
+
...base,
|
|
96
|
+
hooks: {
|
|
97
|
+
...baseHooks,
|
|
98
|
+
...desired.hooks
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function installClaudeCode(targetRoot, options, summary) {
|
|
104
|
+
await copyFile(source("CLAUDE.md"), path.join(targetRoot, "CLAUDE.md"), options);
|
|
105
|
+
await ensureDir(path.join(targetRoot, ".claude"), options.dryRun);
|
|
106
|
+
await copyDirectory(source("skills"), path.join(targetRoot, ".claude", "skills"), options);
|
|
107
|
+
await copyDirectory(source("commands"), path.join(targetRoot, ".claude", "commands"), options);
|
|
108
|
+
await copyDirectory(source("agents"), path.join(targetRoot, ".claude", "agents"), options);
|
|
109
|
+
await copyDirectory(source("hooks"), path.join(targetRoot, ".claude", "hooks"), options);
|
|
110
|
+
|
|
111
|
+
const hookTargets = [
|
|
112
|
+
path.join(targetRoot, ".claude", "hooks", "run-hook.cmd"),
|
|
113
|
+
path.join(targetRoot, ".claude", "hooks", "session-start.sh"),
|
|
114
|
+
path.join(targetRoot, ".claude", "hooks", "user-prompt-submit.sh"),
|
|
115
|
+
path.join(targetRoot, ".claude", "hooks", "pre-tool-use-task.sh")
|
|
116
|
+
];
|
|
117
|
+
for (const hookTarget of hookTargets) {
|
|
118
|
+
await chmodExecutable(hookTarget, options.dryRun);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const settingsPath = path.join(targetRoot, ".claude", "settings.json");
|
|
122
|
+
const existingSettings = await readJsonIfExists(settingsPath);
|
|
123
|
+
const mergedSettings = mergeHooks(existingSettings, claudeHooksSettings());
|
|
124
|
+
await writeJson(settingsPath, mergedSettings, options.dryRun);
|
|
125
|
+
|
|
126
|
+
const projectMcpPath = path.join(targetRoot, ".mcp.json");
|
|
127
|
+
const existingMcp = await readJsonIfExists(projectMcpPath);
|
|
128
|
+
await writeJson(projectMcpPath, mergeMcp(existingMcp), options.dryRun);
|
|
129
|
+
|
|
130
|
+
summary.push(`${AGENT_LABELS["claude-code"]}: installed CLAUDE.md, .claude skills/commands/agents/hooks, .claude/settings.json, and .mcp.json`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async function installCursor(targetRoot, options, summary) {
|
|
134
|
+
await copyFile(source("AGENTS.md"), path.join(targetRoot, "AGENTS.md"), options);
|
|
135
|
+
await copyDirectory(source(".cursor", "rules"), path.join(targetRoot, ".cursor", "rules"), options);
|
|
136
|
+
await copyDirectory(source(".cursor", "commands"), path.join(targetRoot, ".cursor", "commands"), options);
|
|
137
|
+
await copyDirectory(source(".cursor", "skills"), path.join(targetRoot, ".cursor", "skills"), options);
|
|
138
|
+
await copyDirectory(source(".cursor", "agents"), path.join(targetRoot, ".cursor", "agents"), options);
|
|
139
|
+
await copyDirectory(source(".cursor", "hook-scripts"), path.join(targetRoot, ".cursor", "hook-scripts"), options);
|
|
140
|
+
|
|
141
|
+
const existingHooks = await readJsonIfExists(path.join(targetRoot, ".cursor", "hooks.json"));
|
|
142
|
+
const desiredHooks = await readJsonIfExists(source(".cursor", "hooks.json"));
|
|
143
|
+
await writeJson(path.join(targetRoot, ".cursor", "hooks.json"), mergeHooks(existingHooks, desiredHooks), options.dryRun);
|
|
144
|
+
|
|
145
|
+
const existingMcp = await readJsonIfExists(path.join(targetRoot, ".cursor", "mcp.json"));
|
|
146
|
+
await writeJson(path.join(targetRoot, ".cursor", "mcp.json"), mergeMcp(existingMcp), options.dryRun);
|
|
147
|
+
|
|
148
|
+
summary.push(`${AGENT_LABELS.cursor}: installed AGENTS.md and .cursor rules/commands/skills/agents/hooks/mcp`);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function installAntigravity(targetRoot, options, summary) {
|
|
152
|
+
await copyFile(source("AGENTS.md"), path.join(targetRoot, "AGENTS.md"), options);
|
|
153
|
+
await copyFile(source("GEMINI.md"), path.join(targetRoot, "GEMINI.md"), options);
|
|
154
|
+
await copyDirectory(source(".agent", "skills"), path.join(targetRoot, ".agent", "skills"), options);
|
|
155
|
+
await copyFile(
|
|
156
|
+
source("config", "antigravity", "mcp_config.example.json"),
|
|
157
|
+
path.join(targetRoot, "config", "antigravity", "mcp_config.example.json"),
|
|
158
|
+
options
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
summary.push(`${AGENT_LABELS.antigravity}: installed AGENTS.md, GEMINI.md, .agent/skills, and Antigravity MCP config example`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const installers = {
|
|
165
|
+
"claude-code": installClaudeCode,
|
|
166
|
+
cursor: installCursor,
|
|
167
|
+
antigravity: installAntigravity
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export async function installAgents(targetRoot, agents, options) {
|
|
171
|
+
if (!(await pathExists(targetRoot))) {
|
|
172
|
+
throw new Error(`Target directory does not exist: ${targetRoot}`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const summary = [];
|
|
176
|
+
|
|
177
|
+
for (const agent of agents) {
|
|
178
|
+
const installer = installers[agent];
|
|
179
|
+
if (!installer) {
|
|
180
|
+
throw new Error(`Unsupported agent: ${agent}`);
|
|
181
|
+
}
|
|
182
|
+
await installer(targetRoot, options, summary);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return summary;
|
|
186
|
+
}
|
package/src/io.mjs
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
export async function pathExists(targetPath) {
|
|
5
|
+
try {
|
|
6
|
+
await fs.access(targetPath);
|
|
7
|
+
return true;
|
|
8
|
+
} catch {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function ensureDir(targetPath, dryRun = false) {
|
|
14
|
+
if (dryRun) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
await fs.mkdir(targetPath, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function readJsonIfExists(targetPath) {
|
|
21
|
+
if (!(await pathExists(targetPath))) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const content = await fs.readFile(targetPath, "utf8");
|
|
25
|
+
return JSON.parse(content);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function writeJson(targetPath, value, dryRun = false) {
|
|
29
|
+
if (dryRun) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
await fs.mkdir(path.dirname(targetPath), { recursive: true });
|
|
33
|
+
await fs.writeFile(targetPath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function copyFile(sourcePath, targetPath, { force = false, dryRun = false } = {}) {
|
|
37
|
+
const exists = await pathExists(targetPath);
|
|
38
|
+
if (exists && !force) {
|
|
39
|
+
return "skipped";
|
|
40
|
+
}
|
|
41
|
+
if (!dryRun) {
|
|
42
|
+
await fs.mkdir(path.dirname(targetPath), { recursive: true });
|
|
43
|
+
await fs.copyFile(sourcePath, targetPath);
|
|
44
|
+
}
|
|
45
|
+
return exists ? "overwritten" : "created";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function copyDirectory(sourceDir, targetDir, options = {}) {
|
|
49
|
+
const entries = await fs.readdir(sourceDir, { withFileTypes: true });
|
|
50
|
+
const results = [];
|
|
51
|
+
|
|
52
|
+
for (const entry of entries) {
|
|
53
|
+
const sourcePath = path.join(sourceDir, entry.name);
|
|
54
|
+
const targetPath = path.join(targetDir, entry.name);
|
|
55
|
+
|
|
56
|
+
if (entry.isDirectory()) {
|
|
57
|
+
if (!options.dryRun) {
|
|
58
|
+
await fs.mkdir(targetPath, { recursive: true });
|
|
59
|
+
}
|
|
60
|
+
const nested = await copyDirectory(sourcePath, targetPath, options);
|
|
61
|
+
results.push(...nested);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const result = await copyFile(sourcePath, targetPath, options);
|
|
66
|
+
results.push({ path: targetPath, result });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return results;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export async function chmodExecutable(targetPath, dryRun = false) {
|
|
73
|
+
if (dryRun) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
await fs.chmod(targetPath, 0o755);
|
|
78
|
+
} catch {
|
|
79
|
+
// Ignore chmod failures on Windows and restricted filesystems.
|
|
80
|
+
}
|
|
81
|
+
}
|