divergent-thinking-skill 1.1.0 → 1.2.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.
Files changed (3) hide show
  1. package/README.md +10 -0
  2. package/bin/install.js +77 -44
  3. package/package.json +4 -1
package/README.md CHANGED
@@ -14,6 +14,8 @@ npx divergent-thinking-skill init
14
14
  divergent-thinking init
15
15
  ```
16
16
 
17
+ `init` detects common AI tool directories, pre-selects detected tools, and supports multi-select install.
18
+
17
19
  ## Install
18
20
 
19
21
  Default target: `~/.agents/skills/divergent-thinking/SKILL.md`.
@@ -27,6 +29,8 @@ npx divergent-thinking-skill --dir ~/.claude/skills
27
29
  npx divergent-thinking-skill --tool codex
28
30
  npx divergent-thinking-skill --tool claude
29
31
  npx divergent-thinking-skill --tool cursor
32
+ # Multiple tools at once
33
+ npx divergent-thinking-skill --tool codex,claude
30
34
  ```
31
35
 
32
36
  Or set environment (parent directory only):
@@ -35,6 +39,12 @@ Or set environment (parent directory only):
35
39
  DIVERGENT_THINKING_SKILL_DIR=~/.claude/skills npx divergent-thinking-skill
36
40
  ```
37
41
 
42
+ Non-interactive detected setup:
43
+
44
+ ```bash
45
+ npx divergent-thinking-skill init --yes
46
+ ```
47
+
38
48
  ## Publish to npm (maintainers)
39
49
 
40
50
  1. Edit `package.json` → set `"repository.url"` to your real Git URL.
package/bin/install.js CHANGED
@@ -11,13 +11,15 @@
11
11
  const fs = require("fs");
12
12
  const path = require("path");
13
13
  const os = require("os");
14
- const readline = require("readline");
15
14
 
16
- const TOOL_PRESETS = {
17
- codex: "~/.codex/skills",
18
- claude: "~/.claude/skills",
19
- cursor: "~/.agents/skills",
20
- };
15
+ const TOOL_PRESETS = [
16
+ { key: "cursor", name: "Cursor", dir: "~/.agents/skills" },
17
+ { key: "codex", name: "Codex", dir: "~/.codex/skills" },
18
+ { key: "claude", name: "Claude Code", dir: "~/.claude/skills" },
19
+ { key: "gemini", name: "Gemini CLI", dir: "~/.gemini/skills" },
20
+ { key: "copilot", name: "GitHub Copilot", dir: "~/.copilot/skills" },
21
+ { key: "continue", name: "Continue", dir: "~/.continue/skills" },
22
+ ];
21
23
 
22
24
  function expandHome(p) {
23
25
  if (!p || p[0] !== "~") return p;
@@ -29,10 +31,12 @@ function parseArgs(argv) {
29
31
  let help = false;
30
32
  let init = false;
31
33
  let tool = null;
34
+ let yes = false;
32
35
  for (let i = 2; i < argv.length; i++) {
33
36
  const a = argv[i];
34
37
  if (a === "--help" || a === "-h") help = true;
35
38
  else if (a === "init") init = true;
39
+ else if (a === "--yes" || a === "-y") yes = true;
36
40
  else if (a === "--dir" && argv[i + 1]) {
37
41
  outDir = expandHome(argv[++i]);
38
42
  } else if (a.startsWith("--dir=")) {
@@ -43,7 +47,7 @@ function parseArgs(argv) {
43
47
  tool = a.slice("--tool=".length).toLowerCase();
44
48
  }
45
49
  }
46
- return { outDir, help, init, tool };
50
+ return { outDir, help, init, tool, yes };
47
51
  }
48
52
 
49
53
  function defaultSkillsRoot() {
@@ -57,7 +61,13 @@ function defaultSkillsRoot() {
57
61
 
58
62
  function resolvePreset(tool) {
59
63
  if (!tool) return null;
60
- return TOOL_PRESETS[tool] ? expandHome(TOOL_PRESETS[tool]) : null;
64
+ const tools = tool.split(",").map((t) => t.trim().toLowerCase()).filter(Boolean);
65
+ const dirs = tools.map((key) => {
66
+ const p = TOOL_PRESETS.find((x) => x.key === key);
67
+ return p ? expandHome(p.dir) : null;
68
+ });
69
+ if (dirs.some((d) => d === null)) return null;
70
+ return Array.from(new Set(dirs));
61
71
  }
62
72
 
63
73
  function printHelp() {
@@ -69,14 +79,16 @@ Usage:
69
79
  npx divergent-thinking-skill init
70
80
  npx divergent-thinking-skill --dir ~/.agents/skills
71
81
  npx divergent-thinking-skill --tool codex
82
+ npx divergent-thinking-skill --tool codex,claude
72
83
  divergent-thinking init
73
84
 
74
85
  Commands:
75
- init Interactive install wizard (choose AI tool)
86
+ init Interactive setup (detect + multi-select tools)
76
87
 
77
88
  Options:
78
89
  --dir <path> Parent skills directory (final: <path>/divergent-thinking/SKILL.md)
79
- --tool <codex|claude|cursor> Use built-in tool preset path
90
+ --tool <list> Comma-separated tool keys (e.g. codex,claude,cursor)
91
+ --yes, -y Non-interactive; with init uses detected tools
80
92
  -h, --help Show help
81
93
 
82
94
  Environment:
@@ -84,9 +96,7 @@ Environment:
84
96
  AGENT_SKILLS_DIR Fallback alias
85
97
 
86
98
  Preset defaults:
87
- codex -> ~/.codex/skills
88
- claude -> ~/.claude/skills
89
- cursor -> ~/.agents/skills
99
+ ${TOOL_PRESETS.map((t) => ` ${t.key.padEnd(8)} -> ${t.dir}`).join("\n")}
90
100
  `);
91
101
  }
92
102
 
@@ -106,62 +116,85 @@ function installTo(parent) {
106
116
  console.log("Parent skills directory:", path.resolve(parent));
107
117
  }
108
118
 
109
- function ask(rl, q) {
110
- return new Promise((resolve) => rl.question(q, resolve));
119
+ function detectedTools() {
120
+ return TOOL_PRESETS.filter((t) => fs.existsSync(expandHome(t.dir)));
111
121
  }
112
122
 
113
123
  async function interactiveInit() {
114
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
115
- try {
116
- console.log("\nChoose your AI tool:");
117
- console.log(" 1) Codex (~/.codex/skills)");
118
- console.log(" 2) Claude (~/.claude/skills)");
119
- console.log(" 3) Cursor (~/.agents/skills)");
120
- console.log(" 4) Custom path");
121
-
122
- const picked = (await ask(rl, "Select [1-4] (default 1): ")).trim() || "1";
123
- let parent;
124
- if (picked === "1") parent = expandHome(TOOL_PRESETS.codex);
125
- else if (picked === "2") parent = expandHome(TOOL_PRESETS.claude);
126
- else if (picked === "3") parent = expandHome(TOOL_PRESETS.cursor);
127
- else if (picked === "4") {
128
- const custom = (await ask(rl, "Enter parent skills directory: ")).trim();
129
- if (!custom) {
130
- console.error("No custom path provided.");
131
- process.exit(1);
132
- }
133
- parent = expandHome(custom);
134
- } else {
135
- console.error("Invalid selection.");
136
- process.exit(1);
124
+ const { checkbox, input } = await import("@inquirer/prompts");
125
+ const detected = detectedTools();
126
+ const detectedNames = detected.length
127
+ ? detected.map((t) => t.name).join(", ")
128
+ : "none";
129
+ console.log(`Detected tool directories: ${detectedNames}`);
130
+
131
+ const choices = TOOL_PRESETS.map((tool) => ({
132
+ name: `${tool.name}${detected.some((d) => d.key === tool.key) ? " (detected)" : ""} [${tool.dir}]`,
133
+ value: tool.key,
134
+ checked: detected.some((d) => d.key === tool.key),
135
+ }));
136
+ choices.push({ name: "Custom path", value: "__custom__", checked: false });
137
+
138
+ const selected = await checkbox({
139
+ message: `Select tools to set up (${choices.length - 1} available)`,
140
+ choices,
141
+ loop: false,
142
+ });
143
+
144
+ if (!selected.length) {
145
+ console.log("No tools selected. Nothing installed.");
146
+ return;
147
+ }
148
+
149
+ let parents = selected
150
+ .filter((v) => v !== "__custom__")
151
+ .map((key) => TOOL_PRESETS.find((t) => t.key === key))
152
+ .filter(Boolean)
153
+ .map((t) => expandHome(t.dir));
154
+
155
+ if (selected.includes("__custom__")) {
156
+ const custom = await input({ message: "Enter parent skills directory for custom target" });
157
+ if (custom && custom.trim()) {
158
+ parents.push(expandHome(custom.trim()));
137
159
  }
160
+ }
138
161
 
162
+ parents = Array.from(new Set(parents));
163
+ for (const parent of parents) {
139
164
  installTo(parent);
140
- } finally {
141
- rl.close();
142
165
  }
143
166
  }
144
167
 
145
168
  async function main() {
146
- const { outDir, help, init, tool } = parseArgs(process.argv);
169
+ const { outDir, help, init, tool, yes } = parseArgs(process.argv);
147
170
  if (help) {
148
171
  printHelp();
149
172
  process.exit(0);
150
173
  }
151
174
 
152
175
  if (init) {
176
+ if (yes) {
177
+ const detected = detectedTools();
178
+ if (!detected.length) {
179
+ console.log("No detected tool directories. Falling back to ~/.agents/skills");
180
+ installTo(defaultSkillsRoot());
181
+ return;
182
+ }
183
+ for (const t of detected) installTo(expandHome(t.dir));
184
+ return;
185
+ }
153
186
  await interactiveInit();
154
187
  return;
155
188
  }
156
189
 
157
190
  const fromToolPreset = resolvePreset(tool);
158
191
  if (tool && !fromToolPreset) {
159
- console.error(`Unknown --tool value: ${tool}. Use codex, claude, or cursor.`);
192
+ console.error(`Unknown --tool value: ${tool}. Use one or more of: ${TOOL_PRESETS.map((t) => t.key).join(", ")}.`);
160
193
  process.exit(1);
161
194
  }
162
195
 
163
- const parent = outDir || fromToolPreset || defaultSkillsRoot();
164
- installTo(parent);
196
+ const parents = outDir ? [outDir] : fromToolPreset || [defaultSkillsRoot()];
197
+ for (const parent of parents) installTo(parent);
165
198
  }
166
199
 
167
200
  main().catch((err) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "divergent-thinking-skill",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Agent skill: diverge → compare → recommend (frontend-friendly). Install SKILL.md via npx.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -31,5 +31,8 @@
31
31
  },
32
32
  "engines": {
33
33
  "node": ">=18"
34
+ },
35
+ "dependencies": {
36
+ "@inquirer/prompts": "^8.4.1"
34
37
  }
35
38
  }