@siliconoid/agentkit 0.1.0 → 0.1.2
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/cli.mjs +11 -0
- package/lib/commands/add-platform.mjs +9 -1
- package/lib/commands/add-skill-bundle.mjs +71 -0
- package/lib/commands/init.mjs +27 -6
- package/lib/commands/list.mjs +15 -1
- package/lib/prompts.mjs +53 -9
- package/lib/scaffold.mjs +38 -0
- package/lib/schema.mjs +8 -1
- package/package.json +1 -1
package/bin/cli.mjs
CHANGED
|
@@ -93,6 +93,17 @@ program
|
|
|
93
93
|
await runAddSkillPack(pack)
|
|
94
94
|
})
|
|
95
95
|
|
|
96
|
+
program
|
|
97
|
+
.command('add-skill-bundle')
|
|
98
|
+
.description('Add a skill bundle (e.g. superpowers) to an existing project')
|
|
99
|
+
.argument('<bundle>', 'Skill bundle ID (e.g. superpowers)')
|
|
100
|
+
.option('--global', 'Install to ~/.claude/skills/ (works across all projects)')
|
|
101
|
+
.option('--project', 'Install to project platform dirs (default)')
|
|
102
|
+
.action(async (bundle, opts) => {
|
|
103
|
+
const { runAddSkillBundle } = await import('../lib/commands/add-skill-bundle.mjs')
|
|
104
|
+
await runAddSkillBundle(bundle, opts)
|
|
105
|
+
})
|
|
106
|
+
|
|
96
107
|
program
|
|
97
108
|
.command('doctor')
|
|
98
109
|
.description('Check project configuration for issues')
|
|
@@ -2,7 +2,7 @@ import { join } from 'path'
|
|
|
2
2
|
import {
|
|
3
3
|
findProjectRoot, readConfig, writeConfig, PLATFORMS,
|
|
4
4
|
} from '../utils.mjs'
|
|
5
|
-
import { scaffoldPlatforms, scaffoldWorkflows, scaffoldSkills } from '../scaffold.mjs'
|
|
5
|
+
import { scaffoldPlatforms, scaffoldWorkflows, scaffoldSkills, scaffoldSkillBundles } from '../scaffold.mjs'
|
|
6
6
|
import { runSync } from './sync.mjs'
|
|
7
7
|
import log from '../log.mjs'
|
|
8
8
|
|
|
@@ -58,6 +58,14 @@ export async function runAddPlatform(platformId) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
// Install skill bundles if any (project-level only)
|
|
62
|
+
if (config.skillBundles?.length > 0) {
|
|
63
|
+
const bundleFiles = scaffoldSkillBundles(projectRoot, [platformId], config.skillBundles)
|
|
64
|
+
if (bundleFiles.length > 0) {
|
|
65
|
+
log.success(` ${bundleFiles.length} skill bundle files installed`)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
61
69
|
// Sync portable skills
|
|
62
70
|
await runSync({ _projectRoot: projectRoot, _platforms: [platformId], _vars: vars })
|
|
63
71
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {
|
|
2
|
+
findProjectRoot, readConfig, writeConfig, SKILL_BUNDLES,
|
|
3
|
+
} from '../utils.mjs'
|
|
4
|
+
import { scaffoldSkillBundles, scaffoldSkillBundlesGlobal } from '../scaffold.mjs'
|
|
5
|
+
import log from '../log.mjs'
|
|
6
|
+
|
|
7
|
+
export async function runAddSkillBundle(bundleId, opts = {}) {
|
|
8
|
+
const validIds = SKILL_BUNDLES.map(b => b.id)
|
|
9
|
+
|
|
10
|
+
if (!validIds.includes(bundleId)) {
|
|
11
|
+
log.error(`Unknown skill bundle "${bundleId}". Available: ${validIds.join(', ')}`)
|
|
12
|
+
process.exit(1)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const projectRoot = findProjectRoot()
|
|
17
|
+
const config = readConfig(projectRoot)
|
|
18
|
+
|
|
19
|
+
if (!config) {
|
|
20
|
+
log.error('No .ai/agentkit.json found. Run `agentkit init` first.')
|
|
21
|
+
process.exit(1)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (config.skillBundles.includes(bundleId)) {
|
|
25
|
+
log.warn(`Skill bundle "${bundleId}" is already installed.`)
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const bundle = SKILL_BUNDLES.find(b => b.id === bundleId)
|
|
30
|
+
|
|
31
|
+
// Determine scope from flags, config, or default
|
|
32
|
+
let scope = 'project'
|
|
33
|
+
if (opts.global && opts.project) scope = 'both'
|
|
34
|
+
else if (opts.global) scope = 'global'
|
|
35
|
+
else if (opts.project) scope = 'project'
|
|
36
|
+
|
|
37
|
+
// Add to config
|
|
38
|
+
config.skillBundles.push(bundleId)
|
|
39
|
+
config.superpowersScope = scope
|
|
40
|
+
|
|
41
|
+
log.header(`Adding skill bundle: ${bundle.name} (${scope})...`)
|
|
42
|
+
|
|
43
|
+
let totalFiles = 0
|
|
44
|
+
|
|
45
|
+
// Project-level install
|
|
46
|
+
if (scope === 'project' || scope === 'both') {
|
|
47
|
+
const files = scaffoldSkillBundles(projectRoot, config.platforms, [bundleId])
|
|
48
|
+
totalFiles += files.length
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Global install
|
|
52
|
+
if (scope === 'global' || scope === 'both') {
|
|
53
|
+
const files = scaffoldSkillBundlesGlobal([bundleId])
|
|
54
|
+
totalFiles += files.length
|
|
55
|
+
log.info(` Global: ${files.length} files → ~/.claude/skills/`)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (totalFiles > 0) {
|
|
59
|
+
log.success(` ${totalFiles} file(s) installed`)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Update config
|
|
63
|
+
writeConfig(projectRoot, config)
|
|
64
|
+
log.success(`\nSkill bundle "${bundleId}" added.`)
|
|
65
|
+
log.plain('')
|
|
66
|
+
} catch (err) {
|
|
67
|
+
log.error(`Add skill bundle failed: ${err.message}`)
|
|
68
|
+
log.verbose(err.stack)
|
|
69
|
+
process.exit(1)
|
|
70
|
+
}
|
|
71
|
+
}
|
package/lib/commands/init.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from '../prompts.mjs'
|
|
8
8
|
import {
|
|
9
9
|
scaffoldBase, scaffoldFramework, scaffoldPlatforms,
|
|
10
|
-
scaffoldWorkflows, scaffoldSkills, scaffoldSkillBundles,
|
|
10
|
+
scaffoldWorkflows, scaffoldSkills, scaffoldSkillBundles, scaffoldSkillBundlesGlobal,
|
|
11
11
|
runTemplateReplace, generateQuickStart,
|
|
12
12
|
} from '../scaffold.mjs'
|
|
13
13
|
import { runSync } from './sync.mjs'
|
|
@@ -28,7 +28,7 @@ export async function runInit(opts = {}) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
// Gather configuration
|
|
31
|
-
let projectName, projectDescription, framework, platforms, workflowPacks, skillPacks, skillBundles
|
|
31
|
+
let projectName, projectDescription, framework, platforms, workflowPacks, skillPacks, skillBundles, superpowersScope
|
|
32
32
|
|
|
33
33
|
if (opts.smart) {
|
|
34
34
|
// --smart: zero-question fully auto-detected init
|
|
@@ -46,6 +46,7 @@ export async function runInit(opts = {}) {
|
|
|
46
46
|
)
|
|
47
47
|
workflowPacks = WORKFLOW_PACKS.map(w => w.id)
|
|
48
48
|
skillBundles = SKILL_BUNDLES.map(b => b.id)
|
|
49
|
+
superpowersScope = 'project'
|
|
49
50
|
|
|
50
51
|
log.info(' Smart mode: auto-detecting project configuration...')
|
|
51
52
|
log.plain(` Name: ${projectName}`)
|
|
@@ -67,6 +68,7 @@ export async function runInit(opts = {}) {
|
|
|
67
68
|
workflowPacks = []
|
|
68
69
|
skillPacks = []
|
|
69
70
|
skillBundles = []
|
|
71
|
+
superpowersScope = 'project'
|
|
70
72
|
} else if (opts.yes) {
|
|
71
73
|
// -y: Auto-detect as much as possible, fill remaining with defaults
|
|
72
74
|
const detected = autoDetect(projectRoot)
|
|
@@ -77,6 +79,7 @@ export async function runInit(opts = {}) {
|
|
|
77
79
|
workflowPacks = WORKFLOW_PACKS.map(w => w.id)
|
|
78
80
|
skillPacks = discoverSkillPacks().map(s => s.id)
|
|
79
81
|
skillBundles = SKILL_BUNDLES.map(b => b.id)
|
|
82
|
+
superpowersScope = 'project'
|
|
80
83
|
} else {
|
|
81
84
|
// Interactive flow with auto-detection
|
|
82
85
|
const answers = await runInteractivePrompts(projectRoot)
|
|
@@ -86,7 +89,8 @@ export async function runInit(opts = {}) {
|
|
|
86
89
|
platforms = answers.platforms
|
|
87
90
|
workflowPacks = answers.workflowPacks
|
|
88
91
|
skillPacks = answers.skillPacks
|
|
89
|
-
skillBundles = answers.skillBundles
|
|
92
|
+
skillBundles = answers.skillBundles
|
|
93
|
+
superpowersScope = answers.superpowersScope || 'project'
|
|
90
94
|
}
|
|
91
95
|
|
|
92
96
|
// Build extended vars from auto-detection for template replacement
|
|
@@ -198,12 +202,28 @@ export async function runInit(opts = {}) {
|
|
|
198
202
|
|
|
199
203
|
// Step 6b: Install skill bundles (e.g. Superpowers)
|
|
200
204
|
if (skillBundles.length > 0) {
|
|
205
|
+
const scope = superpowersScope || 'project'
|
|
201
206
|
for (const bundleId of skillBundles) {
|
|
202
207
|
const bundle = SKILL_BUNDLES.find(b => b.id === bundleId)
|
|
203
208
|
if (!bundle) continue
|
|
204
|
-
log.header(`Installing ${bundle.name}...`)
|
|
205
|
-
|
|
206
|
-
|
|
209
|
+
log.header(`Installing ${bundle.name} (${scope})...`)
|
|
210
|
+
|
|
211
|
+
let totalFiles = 0
|
|
212
|
+
|
|
213
|
+
// Project-level install
|
|
214
|
+
if (scope === 'project' || scope === 'both') {
|
|
215
|
+
const bundleFiles = scaffoldSkillBundles(projectRoot, platforms, [bundleId])
|
|
216
|
+
totalFiles += bundleFiles.length
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Global install (~/.claude/skills/)
|
|
220
|
+
if (scope === 'global' || scope === 'both') {
|
|
221
|
+
const globalFiles = scaffoldSkillBundlesGlobal([bundleId])
|
|
222
|
+
totalFiles += globalFiles.length
|
|
223
|
+
log.info(` Global: ${globalFiles.length} files → ~/.claude/skills/`)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
log.success(` ${totalFiles} files (14 skills + agents)`)
|
|
207
227
|
}
|
|
208
228
|
}
|
|
209
229
|
|
|
@@ -217,6 +237,7 @@ export async function runInit(opts = {}) {
|
|
|
217
237
|
workflowPacks,
|
|
218
238
|
skillPacks,
|
|
219
239
|
skillBundles,
|
|
240
|
+
superpowersScope: superpowersScope || 'project',
|
|
220
241
|
detected: {
|
|
221
242
|
packageManager: vars.packageManager,
|
|
222
243
|
primaryLanguage: vars.primaryLanguage,
|
package/lib/commands/list.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { join } from 'path'
|
|
2
2
|
import { existsSync, readdirSync, readFileSync } from 'fs'
|
|
3
|
-
import { findProjectRoot, readConfig, PLATFORMS, WORKFLOW_PACKS, discoverSkills, discoverSkillPacks } from '../utils.mjs'
|
|
3
|
+
import { findProjectRoot, readConfig, PLATFORMS, WORKFLOW_PACKS, SKILL_BUNDLES, discoverSkills, discoverSkillPacks } from '../utils.mjs'
|
|
4
4
|
import log from '../log.mjs'
|
|
5
5
|
import pc from 'picocolors'
|
|
6
6
|
|
|
@@ -56,6 +56,20 @@ export async function runList(opts = {}) {
|
|
|
56
56
|
log.dim(' No skill packs installed')
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
// Skill Bundles
|
|
60
|
+
log.header('Skill Bundles')
|
|
61
|
+
if (config.skillBundles?.length > 0) {
|
|
62
|
+
const scope = config.superpowersScope || 'project'
|
|
63
|
+
for (const bundleId of config.skillBundles) {
|
|
64
|
+
const bundle = SKILL_BUNDLES.find(b => b.id === bundleId)
|
|
65
|
+
const name = bundle ? bundle.name : bundleId
|
|
66
|
+
const desc = bundle ? pc.dim(`— ${bundle.description}`) : ''
|
|
67
|
+
log.plain(` ${pc.green('✓')} ${name} ${desc} ${pc.dim(`(${scope})`)}`)
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
log.dim(' No skill bundles installed')
|
|
71
|
+
}
|
|
72
|
+
|
|
59
73
|
// Workflow Packs
|
|
60
74
|
log.header('Workflow Packs')
|
|
61
75
|
if (config.workflowPacks?.length > 0) {
|
package/lib/prompts.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { input, select, checkbox, confirm } from '@inquirer/prompts'
|
|
2
2
|
import { existsSync, readFileSync } from 'fs'
|
|
3
3
|
import { join, basename } from 'path'
|
|
4
|
-
import { PLATFORMS, WORKFLOW_PACKS, detectPlatforms, discoverSkillPacks } from './utils.mjs'
|
|
4
|
+
import { PLATFORMS, WORKFLOW_PACKS, SKILL_BUNDLES, detectPlatforms, discoverSkillPacks } from './utils.mjs'
|
|
5
5
|
|
|
6
6
|
// ---------------------------------------------------------------------------
|
|
7
7
|
// Auto-detection helpers
|
|
@@ -235,13 +235,57 @@ export async function askPlatforms(detected) {
|
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
export async function askWorkflowPacks() {
|
|
238
|
-
|
|
238
|
+
// Combine workflow packs and skill bundles into one prompt
|
|
239
|
+
const workflowChoices = WORKFLOW_PACKS.map(w => ({
|
|
240
|
+
name: `${w.name} — ${w.description}`,
|
|
241
|
+
value: { type: 'workflow', id: w.id },
|
|
242
|
+
checked: true,
|
|
243
|
+
}))
|
|
244
|
+
|
|
245
|
+
const bundleChoices = SKILL_BUNDLES.map(b => ({
|
|
246
|
+
name: `${b.name} — ${b.description}`,
|
|
247
|
+
value: { type: 'bundle', id: b.id },
|
|
248
|
+
checked: true,
|
|
249
|
+
}))
|
|
250
|
+
|
|
251
|
+
const choices = [...workflowChoices, ...bundleChoices]
|
|
252
|
+
if (choices.length === 0) return { workflowPacks: [], skillBundles: [], superpowersScope: 'project' }
|
|
253
|
+
|
|
254
|
+
const selected = await checkbox({
|
|
239
255
|
message: 'Install workflow packs? (space to toggle, enter to confirm)',
|
|
240
|
-
choices
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
256
|
+
choices,
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
const workflowPacks = selected.filter(s => s.type === 'workflow').map(s => s.id)
|
|
260
|
+
const skillBundles = selected.filter(s => s.type === 'bundle').map(s => s.id)
|
|
261
|
+
|
|
262
|
+
// Ask install scope if Superpowers was selected
|
|
263
|
+
let superpowersScope = 'project'
|
|
264
|
+
if (skillBundles.includes('superpowers')) {
|
|
265
|
+
superpowersScope = await askSuperpowersScope()
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return { workflowPacks, skillBundles, superpowersScope }
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export async function askSuperpowersScope() {
|
|
272
|
+
return select({
|
|
273
|
+
message: 'Superpowers install scope:',
|
|
274
|
+
choices: [
|
|
275
|
+
{
|
|
276
|
+
name: 'Project-level (recommended) — Install to project platform dirs',
|
|
277
|
+
value: 'project',
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
name: 'Global (~/.claude/skills/) — Install to user home, works across all projects',
|
|
281
|
+
value: 'global',
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
name: 'Both — Install to both locations',
|
|
285
|
+
value: 'both',
|
|
286
|
+
},
|
|
287
|
+
],
|
|
288
|
+
default: 'project',
|
|
245
289
|
})
|
|
246
290
|
}
|
|
247
291
|
|
|
@@ -311,10 +355,10 @@ export async function runInteractivePrompts(projectRoot) {
|
|
|
311
355
|
platforms = await askPlatforms(detected.platforms)
|
|
312
356
|
}
|
|
313
357
|
|
|
314
|
-
const workflowPacks = await askWorkflowPacks()
|
|
358
|
+
const { workflowPacks, skillBundles, superpowersScope } = await askWorkflowPacks()
|
|
315
359
|
const skillPacks = await askSkillPacks()
|
|
316
360
|
|
|
317
|
-
return { projectName, projectDescription, framework, platforms, workflowPacks, skillPacks }
|
|
361
|
+
return { projectName, projectDescription, framework, platforms, workflowPacks, skillBundles, skillPacks, superpowersScope }
|
|
318
362
|
}
|
|
319
363
|
|
|
320
364
|
/**
|
package/lib/scaffold.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { join, relative } from 'path'
|
|
2
|
+
import { homedir } from 'os'
|
|
2
3
|
import { existsSync, readdirSync, readFileSync, writeFileSync } from 'fs'
|
|
3
4
|
import {
|
|
4
5
|
copyDir, ensureDir, writeIfNotExists, writeWithMarker, templateReplace, getTemplatesDir, MARKERS,
|
|
@@ -282,6 +283,43 @@ export function scaffoldSkillBundles(projectRoot, platforms, bundleIds) {
|
|
|
282
283
|
return created
|
|
283
284
|
}
|
|
284
285
|
|
|
286
|
+
/**
|
|
287
|
+
* Install skill bundles globally to ~/.claude/skills/ and ~/.claude/agents/.
|
|
288
|
+
* Works across all projects (Claude Code only).
|
|
289
|
+
*/
|
|
290
|
+
export function scaffoldSkillBundlesGlobal(bundleIds) {
|
|
291
|
+
const templatesDir = getTemplatesDir()
|
|
292
|
+
const home = homedir()
|
|
293
|
+
const created = []
|
|
294
|
+
|
|
295
|
+
for (const bundleId of bundleIds) {
|
|
296
|
+
const bundle = SKILL_BUNDLES.find(b => b.id === bundleId)
|
|
297
|
+
if (!bundle) continue
|
|
298
|
+
|
|
299
|
+
const bundleDir = join(templatesDir, bundle.templateDir)
|
|
300
|
+
if (!existsSync(bundleDir)) continue
|
|
301
|
+
|
|
302
|
+
// Install each skill subdirectory to ~/.claude/skills/
|
|
303
|
+
for (const entry of readdirSync(bundleDir, { withFileTypes: true })) {
|
|
304
|
+
if (!entry.isDirectory()) continue
|
|
305
|
+
if (entry.name === '_agents') continue
|
|
306
|
+
|
|
307
|
+
const skillSrc = join(bundleDir, entry.name)
|
|
308
|
+
const dest = join(home, '.claude', 'skills', entry.name)
|
|
309
|
+
copyRecursiveIfNotExists(skillSrc, dest, home, created)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Install agents to ~/.claude/agents/
|
|
313
|
+
const agentsDir = join(bundleDir, '_agents')
|
|
314
|
+
if (existsSync(agentsDir)) {
|
|
315
|
+
const destDir = join(home, '.claude', 'agents')
|
|
316
|
+
copyRecursiveIfNotExists(agentsDir, destDir, home, created)
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return created
|
|
321
|
+
}
|
|
322
|
+
|
|
285
323
|
/** Helper: recursively copy files, skip existing */
|
|
286
324
|
function copyRecursiveIfNotExists(src, dest, projectRoot, created) {
|
|
287
325
|
ensureDir(dest)
|
package/lib/schema.mjs
CHANGED
|
@@ -65,6 +65,13 @@ export function validateConfig(config) {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
// Superpowers scope
|
|
69
|
+
if (config.superpowersScope !== undefined) {
|
|
70
|
+
if (!['project', 'global', 'both'].includes(config.superpowersScope)) {
|
|
71
|
+
warnings.push(`"superpowersScope" should be one of: project, global, both`)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
68
75
|
// Workflow packs validation
|
|
69
76
|
if (Array.isArray(config.workflowPacks)) {
|
|
70
77
|
for (const w of config.workflowPacks) {
|
|
@@ -97,7 +104,7 @@ export function validateConfig(config) {
|
|
|
97
104
|
// Warn on unknown top-level keys
|
|
98
105
|
const knownKeys = new Set([
|
|
99
106
|
'version', 'projectName', 'projectDescription', 'framework',
|
|
100
|
-
'platforms', 'workflowPacks', 'skillPacks', 'skillBundles', 'packages', 'detected',
|
|
107
|
+
'platforms', 'workflowPacks', 'skillPacks', 'skillBundles', 'superpowersScope', 'packages', 'detected',
|
|
101
108
|
])
|
|
102
109
|
for (const key of Object.keys(config)) {
|
|
103
110
|
if (!knownKeys.has(key)) {
|