@windyroad/agent-plugins 0.1.1
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/bin/install.mjs +191 -0
- package/lib/install-utils.mjs +163 -0
- package/package.json +27 -0
package/bin/install.mjs
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { resolve, dirname } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const utils = await import(resolve(__dirname, "../lib/install-utils.mjs"));
|
|
8
|
+
|
|
9
|
+
const PLUGINS = [
|
|
10
|
+
"wr-architect",
|
|
11
|
+
"wr-risk-scorer",
|
|
12
|
+
"wr-voice-tone",
|
|
13
|
+
"wr-style-guide",
|
|
14
|
+
"wr-jtbd",
|
|
15
|
+
"wr-tdd",
|
|
16
|
+
"wr-retrospective",
|
|
17
|
+
"wr-problem",
|
|
18
|
+
"wr-c4",
|
|
19
|
+
"wr-wardley",
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const HELP = `
|
|
23
|
+
Usage: npx @windyroad/agent-plugins [options]
|
|
24
|
+
|
|
25
|
+
Install, update, or uninstall all Windy Road AI agent plugins and skills.
|
|
26
|
+
|
|
27
|
+
Commands:
|
|
28
|
+
(default) Install all plugins and skills
|
|
29
|
+
--update Update marketplace and reinstall all plugins and skills
|
|
30
|
+
--uninstall Remove all plugins and skills
|
|
31
|
+
|
|
32
|
+
Options:
|
|
33
|
+
--plugin <names> Install only specific plugins (space-separated)
|
|
34
|
+
e.g. --plugin architect tdd risk-scorer
|
|
35
|
+
--dry-run Show what would be done without executing
|
|
36
|
+
--help, -h Show this help
|
|
37
|
+
|
|
38
|
+
Available plugins:
|
|
39
|
+
architect, risk-scorer, voice-tone, style-guide, jtbd,
|
|
40
|
+
tdd, problem, retrospective, c4, wardley
|
|
41
|
+
|
|
42
|
+
Examples:
|
|
43
|
+
npx @windyroad/agent-plugins
|
|
44
|
+
npx @windyroad/agent-plugins --plugin architect tdd risk-scorer
|
|
45
|
+
npx @windyroad/agent-plugins --update
|
|
46
|
+
npx @windyroad/agent-plugins --uninstall
|
|
47
|
+
`;
|
|
48
|
+
|
|
49
|
+
function parseArgs(argv) {
|
|
50
|
+
const args = argv.slice(2);
|
|
51
|
+
const flags = {
|
|
52
|
+
help: false,
|
|
53
|
+
uninstall: false,
|
|
54
|
+
update: false,
|
|
55
|
+
dryRun: false,
|
|
56
|
+
plugins: null,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
for (let i = 0; i < args.length; i++) {
|
|
60
|
+
switch (args[i]) {
|
|
61
|
+
case "--help":
|
|
62
|
+
case "-h":
|
|
63
|
+
flags.help = true;
|
|
64
|
+
break;
|
|
65
|
+
case "--uninstall":
|
|
66
|
+
flags.uninstall = true;
|
|
67
|
+
break;
|
|
68
|
+
case "--update":
|
|
69
|
+
flags.update = true;
|
|
70
|
+
break;
|
|
71
|
+
case "--dry-run":
|
|
72
|
+
flags.dryRun = true;
|
|
73
|
+
break;
|
|
74
|
+
case "--plugin":
|
|
75
|
+
case "--plugins": {
|
|
76
|
+
flags.plugins = [];
|
|
77
|
+
while (i + 1 < args.length && !args[i + 1].startsWith("--")) {
|
|
78
|
+
i++;
|
|
79
|
+
// Accept both "architect" and "wr-architect"
|
|
80
|
+
const raw = args[i];
|
|
81
|
+
const name = raw.startsWith("wr-") ? raw : `wr-${raw}`;
|
|
82
|
+
if (PLUGINS.includes(name)) {
|
|
83
|
+
flags.plugins.push(name);
|
|
84
|
+
} else {
|
|
85
|
+
const available = PLUGINS.map((p) => p.replace("wr-", "")).join(", ");
|
|
86
|
+
console.error(`Unknown plugin: ${raw}\nAvailable: ${available}`);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (flags.plugins.length === 0) {
|
|
91
|
+
const available = PLUGINS.map((p) => p.replace("wr-", "")).join(", ");
|
|
92
|
+
console.error(`--plugin requires at least one name.\nAvailable: ${available}`);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
default:
|
|
98
|
+
console.error(`Unknown option: ${args[i]}\n`);
|
|
99
|
+
console.log(HELP);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return flags;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function doInstall(plugins) {
|
|
108
|
+
console.log("\nInstalling Windy Road AI agent plugins and skills...\n");
|
|
109
|
+
|
|
110
|
+
console.log("[1/3] Adding marketplace...");
|
|
111
|
+
utils.addMarketplace();
|
|
112
|
+
|
|
113
|
+
console.log(`\n[2/3] Installing plugins (${plugins.length})...`);
|
|
114
|
+
let installed = 0;
|
|
115
|
+
for (const plugin of plugins) {
|
|
116
|
+
if (utils.installPlugin(plugin)) installed++;
|
|
117
|
+
}
|
|
118
|
+
console.log(` ${installed}/${plugins.length} plugins installed.`);
|
|
119
|
+
|
|
120
|
+
console.log("\n[3/3] Installing skills...");
|
|
121
|
+
utils.installSkills();
|
|
122
|
+
|
|
123
|
+
console.log(`
|
|
124
|
+
Done! Restart Claude Code to activate all plugins.
|
|
125
|
+
|
|
126
|
+
Installed:
|
|
127
|
+
- ${installed} plugins (agents + hooks)
|
|
128
|
+
- Skills (type /wr: to see them in autocomplete)
|
|
129
|
+
|
|
130
|
+
To update: npx @windyroad/agent-plugins --update
|
|
131
|
+
To uninstall: npx @windyroad/agent-plugins --uninstall
|
|
132
|
+
`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function doUpdate(plugins) {
|
|
136
|
+
console.log("\nUpdating Windy Road AI agent plugins and skills...\n");
|
|
137
|
+
|
|
138
|
+
console.log("[1/3] Updating marketplace...");
|
|
139
|
+
utils.run(
|
|
140
|
+
`claude plugin marketplace update ${utils.MARKETPLACE_NAME}`,
|
|
141
|
+
`Marketplace: ${utils.MARKETPLACE_NAME}`
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
console.log(`\n[2/3] Updating plugins (${plugins.length})...`);
|
|
145
|
+
let updated = 0;
|
|
146
|
+
for (const plugin of plugins) {
|
|
147
|
+
if (utils.updatePlugin(plugin)) updated++;
|
|
148
|
+
}
|
|
149
|
+
console.log(` ${updated}/${plugins.length} plugins updated.`);
|
|
150
|
+
|
|
151
|
+
console.log("\n[3/3] Updating skills...");
|
|
152
|
+
utils.updateSkills();
|
|
153
|
+
|
|
154
|
+
console.log("\nDone! Restart Claude Code to apply updates.\n");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function doUninstall(plugins) {
|
|
158
|
+
console.log("\nUninstalling Windy Road plugins...\n");
|
|
159
|
+
|
|
160
|
+
for (const plugin of plugins) {
|
|
161
|
+
utils.uninstallPlugin(plugin);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
utils.removeSkills();
|
|
165
|
+
|
|
166
|
+
console.log("\nDone. Restart Claude Code to apply changes.\n");
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const flags = parseArgs(process.argv);
|
|
170
|
+
|
|
171
|
+
if (flags.help) {
|
|
172
|
+
console.log(HELP);
|
|
173
|
+
process.exit(0);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (flags.dryRun) {
|
|
177
|
+
utils.setDryRun(true);
|
|
178
|
+
console.log("[dry-run mode — no commands will be executed]\n");
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
utils.checkPrerequisites();
|
|
182
|
+
|
|
183
|
+
const plugins = flags.plugins ?? PLUGINS;
|
|
184
|
+
|
|
185
|
+
if (flags.uninstall) {
|
|
186
|
+
doUninstall(plugins);
|
|
187
|
+
} else if (flags.update) {
|
|
188
|
+
doUpdate(plugins);
|
|
189
|
+
} else {
|
|
190
|
+
doInstall(plugins);
|
|
191
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared install utilities for @windyroad/* packages.
|
|
3
|
+
* Used by both per-plugin installers and the meta-installer.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { execSync } from "node:child_process";
|
|
7
|
+
|
|
8
|
+
const MARKETPLACE_REPO = "windyroad/agent-plugins";
|
|
9
|
+
const MARKETPLACE_NAME = "windyroad";
|
|
10
|
+
|
|
11
|
+
let _dryRun = false;
|
|
12
|
+
|
|
13
|
+
export { MARKETPLACE_REPO, MARKETPLACE_NAME };
|
|
14
|
+
|
|
15
|
+
export function setDryRun(value) {
|
|
16
|
+
_dryRun = value;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function isDryRun() {
|
|
20
|
+
return _dryRun;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function run(cmd, label) {
|
|
24
|
+
console.log(` ${label}...`);
|
|
25
|
+
if (_dryRun) {
|
|
26
|
+
console.log(` [dry-run] ${cmd}`);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
execSync(cmd, { stdio: "inherit" });
|
|
31
|
+
return true;
|
|
32
|
+
} catch {
|
|
33
|
+
console.error(` FAILED: ${label}`);
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function checkPrerequisites() {
|
|
39
|
+
if (_dryRun) return;
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
execSync("claude --version", { stdio: "pipe" });
|
|
43
|
+
} catch {
|
|
44
|
+
console.error(
|
|
45
|
+
"Error: 'claude' CLI not found. Install Claude Code first:\n https://docs.anthropic.com/en/docs/claude-code\n"
|
|
46
|
+
);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
execSync("npx --version", { stdio: "pipe" });
|
|
52
|
+
} catch {
|
|
53
|
+
console.error(
|
|
54
|
+
"Error: 'npx' not found. Install Node.js first:\n https://nodejs.org\n"
|
|
55
|
+
);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function addMarketplace() {
|
|
61
|
+
return run(
|
|
62
|
+
`claude plugin marketplace add ${MARKETPLACE_REPO}`,
|
|
63
|
+
`Marketplace: ${MARKETPLACE_NAME}`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function installPlugin(pluginName) {
|
|
68
|
+
return run(
|
|
69
|
+
`claude plugin install ${pluginName}@${MARKETPLACE_NAME}`,
|
|
70
|
+
pluginName
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function updatePlugin(pluginName) {
|
|
75
|
+
return run(`claude plugin update ${pluginName}`, pluginName);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function uninstallPlugin(pluginName) {
|
|
79
|
+
return run(`claude plugin uninstall ${pluginName}`, `Removing ${pluginName}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function installSkills() {
|
|
83
|
+
return run(
|
|
84
|
+
`npx -y skills add --yes --all ${MARKETPLACE_REPO}`,
|
|
85
|
+
"Skills (via skills package)"
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function updateSkills() {
|
|
90
|
+
return run("npx -y skills update", "Skills update");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function removeSkills() {
|
|
94
|
+
return run(
|
|
95
|
+
`npx -y skills remove --yes --all ${MARKETPLACE_REPO}`,
|
|
96
|
+
"Removing skills"
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Install a single package: marketplace add + plugin install + skills.
|
|
102
|
+
*/
|
|
103
|
+
export function installPackage(pluginName, { deps = [] } = {}) {
|
|
104
|
+
console.log(`\nInstalling @windyroad/${pluginName.replace("wr-", "")}...\n`);
|
|
105
|
+
|
|
106
|
+
addMarketplace();
|
|
107
|
+
installPlugin(pluginName);
|
|
108
|
+
installSkills();
|
|
109
|
+
|
|
110
|
+
if (deps.length > 0) {
|
|
111
|
+
console.log(`\nNote: This plugin works best with:`);
|
|
112
|
+
for (const dep of deps) {
|
|
113
|
+
console.log(` - @windyroad/${dep.replace("wr-", "")} (npx @windyroad/${dep.replace("wr-", "")})`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
console.log(
|
|
118
|
+
`\nDone! Restart Claude Code to activate.\n`
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Update a single package.
|
|
124
|
+
*/
|
|
125
|
+
export function updatePackage(pluginName) {
|
|
126
|
+
console.log(`\nUpdating @windyroad/${pluginName.replace("wr-", "")}...\n`);
|
|
127
|
+
|
|
128
|
+
run(
|
|
129
|
+
`claude plugin marketplace update ${MARKETPLACE_NAME}`,
|
|
130
|
+
"Updating marketplace"
|
|
131
|
+
);
|
|
132
|
+
updatePlugin(pluginName);
|
|
133
|
+
updateSkills();
|
|
134
|
+
|
|
135
|
+
console.log("\nDone! Restart Claude Code to apply updates.\n");
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Uninstall a single package.
|
|
140
|
+
*/
|
|
141
|
+
export function uninstallPackage(pluginName) {
|
|
142
|
+
console.log(`\nUninstalling @windyroad/${pluginName.replace("wr-", "")}...\n`);
|
|
143
|
+
|
|
144
|
+
uninstallPlugin(pluginName);
|
|
145
|
+
|
|
146
|
+
console.log("\nDone. Restart Claude Code to apply changes.\n");
|
|
147
|
+
console.log("Note: Skills are shared across packages. Run");
|
|
148
|
+
console.log(" npx @windyroad/agent-plugins --uninstall");
|
|
149
|
+
console.log("to remove all skills.\n");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Parse standard flags used by all per-plugin installers.
|
|
154
|
+
*/
|
|
155
|
+
export function parseStandardArgs(argv) {
|
|
156
|
+
const args = argv.slice(2);
|
|
157
|
+
return {
|
|
158
|
+
help: args.includes("--help") || args.includes("-h"),
|
|
159
|
+
uninstall: args.includes("--uninstall"),
|
|
160
|
+
update: args.includes("--update"),
|
|
161
|
+
dryRun: args.includes("--dry-run"),
|
|
162
|
+
};
|
|
163
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@windyroad/agent-plugins",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "One-command installer for all Windy Road AI agent plugins and skills",
|
|
5
|
+
"bin": {
|
|
6
|
+
"windyroad-agent-plugins": "./bin/install.mjs"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/windyroad/agent-plugins.git",
|
|
13
|
+
"directory": "packages/agent-plugins"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"claude-code",
|
|
17
|
+
"claude-code-plugin",
|
|
18
|
+
"ai-agent",
|
|
19
|
+
"ai-coding",
|
|
20
|
+
"codex",
|
|
21
|
+
"copilot"
|
|
22
|
+
],
|
|
23
|
+
"files": [
|
|
24
|
+
"bin/",
|
|
25
|
+
"lib/"
|
|
26
|
+
]
|
|
27
|
+
}
|