@alavida/agentpack 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/README.md +269 -0
- package/bin/agentpack.js +5 -0
- package/package.json +54 -0
- package/skills/agentpack-cli/SKILL.md +136 -0
- package/skills/agentpack-cli/references/knowledge-as-package.md +48 -0
- package/skills/agentpack-cli/references/plugin-lifecycle.md +58 -0
- package/skills/agentpack-cli/references/skill-lifecycle.md +78 -0
- package/src/cli.js +82 -0
- package/src/commands/plugin.js +169 -0
- package/src/commands/skills.js +491 -0
- package/src/lib/context.js +167 -0
- package/src/lib/plugins.js +414 -0
- package/src/lib/skills.js +1900 -0
- package/src/utils/errors.js +67 -0
- package/src/utils/output.js +61 -0
package/src/cli.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { formatError, AgentpackError, EXIT_CODES } from './utils/errors.js';
|
|
4
|
+
import { output } from './utils/output.js';
|
|
5
|
+
import { skillsCommand } from './commands/skills.js';
|
|
6
|
+
import { pluginCommand } from './commands/plugin.js';
|
|
7
|
+
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const pkg = require('../package.json');
|
|
10
|
+
|
|
11
|
+
export function createProgram() {
|
|
12
|
+
const program = new Command();
|
|
13
|
+
|
|
14
|
+
program
|
|
15
|
+
.name('agentpack')
|
|
16
|
+
.description('agentpack skills lifecycle CLI')
|
|
17
|
+
.version(pkg.version, '-V, --version', 'Show version number')
|
|
18
|
+
.option('--json', 'Output as JSON')
|
|
19
|
+
.option('-q, --quiet', 'Suppress non-essential output')
|
|
20
|
+
.option('-v, --verbose', 'Show detailed output')
|
|
21
|
+
.option('--workbench <path>', 'Override workbench context (name or path)');
|
|
22
|
+
|
|
23
|
+
program.addCommand(skillsCommand());
|
|
24
|
+
program.addCommand(pluginCommand());
|
|
25
|
+
|
|
26
|
+
program.addHelpText('after', `
|
|
27
|
+
Exit Codes:
|
|
28
|
+
0 Success
|
|
29
|
+
1 General error
|
|
30
|
+
2 Usage or validation error
|
|
31
|
+
3 Network error
|
|
32
|
+
4 Not found
|
|
33
|
+
|
|
34
|
+
Run 'agentpack <command> --help' for details on a specific command.`);
|
|
35
|
+
|
|
36
|
+
program.action(() => {
|
|
37
|
+
program.help();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
return program;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function run(argv) {
|
|
44
|
+
const program = createProgram();
|
|
45
|
+
|
|
46
|
+
process.on('uncaughtException', (err) => {
|
|
47
|
+
const opts = program.opts?.() || {};
|
|
48
|
+
if (opts.json) {
|
|
49
|
+
output.json({ error: 'uncaught_exception', message: err.message });
|
|
50
|
+
} else {
|
|
51
|
+
output.error(formatError(err));
|
|
52
|
+
}
|
|
53
|
+
process.exit(EXIT_CODES.GENERAL);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
process.on('unhandledRejection', (reason) => {
|
|
57
|
+
const err = reason instanceof Error ? reason : new Error(String(reason));
|
|
58
|
+
const opts = program.opts?.() || {};
|
|
59
|
+
if (opts.json) {
|
|
60
|
+
output.json({ error: 'unhandled_rejection', message: err.message });
|
|
61
|
+
} else {
|
|
62
|
+
output.error(formatError(err));
|
|
63
|
+
}
|
|
64
|
+
process.exit(EXIT_CODES.GENERAL);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
program.parseAsync(argv).catch((err) => {
|
|
68
|
+
if (err instanceof AgentpackError) {
|
|
69
|
+
const opts = program.opts?.() || {};
|
|
70
|
+
if (opts.json) {
|
|
71
|
+
output.json({ error: err.code, message: err.message });
|
|
72
|
+
} else {
|
|
73
|
+
output.error(formatError(err));
|
|
74
|
+
}
|
|
75
|
+
process.exit(err.exitCode);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
output.error(formatError(err));
|
|
80
|
+
process.exit(EXIT_CODES.GENERAL);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { buildPlugin, inspectPluginBundle, startPluginDev, validatePluginBundle } from '../lib/plugins.js';
|
|
3
|
+
import { output } from '../utils/output.js';
|
|
4
|
+
import { EXIT_CODES } from '../utils/errors.js';
|
|
5
|
+
|
|
6
|
+
export function pluginCommand() {
|
|
7
|
+
const cmd = new Command('plugin')
|
|
8
|
+
.description('Inspect and validate bundled plugin packaging');
|
|
9
|
+
|
|
10
|
+
cmd
|
|
11
|
+
.command('inspect')
|
|
12
|
+
.description('Inspect the bundle closure implied by a plugin package and its local skill requires')
|
|
13
|
+
.argument('<target>', 'Plugin directory path')
|
|
14
|
+
.action((target, opts, command) => {
|
|
15
|
+
const globalOpts = command.optsWithGlobals();
|
|
16
|
+
const result = inspectPluginBundle(target);
|
|
17
|
+
|
|
18
|
+
if (globalOpts.json) {
|
|
19
|
+
output.json(result);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
output.write(`Plugin: ${result.pluginName}`);
|
|
24
|
+
output.write(`Package: ${result.packageName}`);
|
|
25
|
+
output.write(`Version: ${result.packageVersion}`);
|
|
26
|
+
output.write(`Path: ${result.pluginPath}`);
|
|
27
|
+
output.write(`Local Skills: ${result.localSkills.length}`);
|
|
28
|
+
output.write(`Direct Bundled Packages: ${result.directPackages.length}`);
|
|
29
|
+
output.write(`Transitive Bundled Packages: ${result.transitivePackages.length}`);
|
|
30
|
+
|
|
31
|
+
output.write('');
|
|
32
|
+
output.write('Local Skills:');
|
|
33
|
+
for (const skill of result.localSkills) {
|
|
34
|
+
output.write(`- ${skill.localName}`);
|
|
35
|
+
output.write(` requires: ${skill.requires.length === 0 ? 'none' : skill.requires.join(', ')}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
output.write('');
|
|
39
|
+
output.write('Direct Bundled Packages:');
|
|
40
|
+
if (result.directPackages.length === 0) {
|
|
41
|
+
output.write('- none');
|
|
42
|
+
} else {
|
|
43
|
+
for (const entry of result.directPackages) {
|
|
44
|
+
output.write(`- ${entry.packageName}`);
|
|
45
|
+
output.write(` skill: ${entry.skillName}`);
|
|
46
|
+
output.write(` version: ${entry.packageVersion}`);
|
|
47
|
+
output.write(` source: ${entry.source}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
output.write('');
|
|
52
|
+
output.write('Transitive Bundled Packages:');
|
|
53
|
+
if (result.transitivePackages.length === 0) {
|
|
54
|
+
output.write('- none');
|
|
55
|
+
} else {
|
|
56
|
+
for (const entry of result.transitivePackages) {
|
|
57
|
+
output.write(`- ${entry.packageName}`);
|
|
58
|
+
output.write(` skill: ${entry.skillName}`);
|
|
59
|
+
output.write(` version: ${entry.packageVersion}`);
|
|
60
|
+
output.write(` source: ${entry.source}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (result.unresolvedPackages.length > 0) {
|
|
65
|
+
output.write('');
|
|
66
|
+
output.write('Unresolved Packages:');
|
|
67
|
+
for (const packageName of result.unresolvedPackages) {
|
|
68
|
+
output.write(`- ${packageName}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
cmd
|
|
74
|
+
.command('validate')
|
|
75
|
+
.description('Validate that a plugin package can vendor the standalone skills required by its local skills')
|
|
76
|
+
.argument('<target>', 'Plugin directory path')
|
|
77
|
+
.action((target, opts, command) => {
|
|
78
|
+
const globalOpts = command.optsWithGlobals();
|
|
79
|
+
const result = validatePluginBundle(target);
|
|
80
|
+
|
|
81
|
+
if (globalOpts.json) {
|
|
82
|
+
output.json(result);
|
|
83
|
+
if (!result.valid) process.exitCode = EXIT_CODES.VALIDATION;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
output.write(`Plugin: ${result.pluginName}`);
|
|
88
|
+
output.write(`Package: ${result.packageName}`);
|
|
89
|
+
output.write(`Status: ${result.valid ? 'valid' : 'invalid'}`);
|
|
90
|
+
output.write(`Issues: ${result.issueCount}`);
|
|
91
|
+
output.write(`Direct Bundled Packages: ${result.directPackageCount}`);
|
|
92
|
+
output.write(`Transitive Bundled Packages: ${result.transitivePackageCount}`);
|
|
93
|
+
|
|
94
|
+
if (result.issues.length > 0) {
|
|
95
|
+
output.write('');
|
|
96
|
+
output.write('Issues:');
|
|
97
|
+
for (const issue of result.issues) {
|
|
98
|
+
output.write(`- ${issue.code}`);
|
|
99
|
+
output.write(` message: ${issue.message}`);
|
|
100
|
+
if (issue.packageName) output.write(` package: ${issue.packageName}`);
|
|
101
|
+
if (issue.skillFile) output.write(` skill: ${issue.skillFile}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!result.valid) {
|
|
106
|
+
process.exitCode = EXIT_CODES.VALIDATION;
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
cmd
|
|
111
|
+
.command('build')
|
|
112
|
+
.description('Build a self-contained plugin artifact with vendored standalone skills')
|
|
113
|
+
.option('--clean', 'Remove the previous build output before building')
|
|
114
|
+
.argument('<target>', 'Plugin directory path')
|
|
115
|
+
.action((target, opts, command) => {
|
|
116
|
+
const globalOpts = command.optsWithGlobals();
|
|
117
|
+
const result = buildPlugin(target, { clean: opts.clean });
|
|
118
|
+
|
|
119
|
+
if (globalOpts.json) {
|
|
120
|
+
output.json(result);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
output.write(`Plugin: ${result.pluginName}`);
|
|
125
|
+
output.write(`Output: ${result.outputPath}`);
|
|
126
|
+
output.write(`Local Skills: ${result.localSkills.length}`);
|
|
127
|
+
output.write(`Vendored Skills: ${result.vendoredSkills.length}`);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
cmd
|
|
131
|
+
.command('dev')
|
|
132
|
+
.description('Build a plugin artifact and watch the source tree for rebuilds')
|
|
133
|
+
.option('--clean', 'Remove the previous build output before the initial build')
|
|
134
|
+
.argument('<target>', 'Plugin directory path')
|
|
135
|
+
.action((target, opts, command) => {
|
|
136
|
+
const globalOpts = command.optsWithGlobals();
|
|
137
|
+
const session = startPluginDev(target, {
|
|
138
|
+
clean: opts.clean,
|
|
139
|
+
onBuild(result) {
|
|
140
|
+
if (globalOpts.json) {
|
|
141
|
+
output.json(result);
|
|
142
|
+
} else {
|
|
143
|
+
output.write(`Plugin: ${result.pluginName}`);
|
|
144
|
+
output.write(`Output: ${result.outputPath}`);
|
|
145
|
+
output.write(`Use with: claude --plugin-dir ${result.outputPath}`);
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
onRebuild(result) {
|
|
149
|
+
if (result?.error) {
|
|
150
|
+
output.error(`Rebuild failed: ${result.error.message}`);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
output.write(`Rebuilt plugin: ${result.pluginName}`);
|
|
155
|
+
output.write(`Output: ${result.outputPath}`);
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const stop = () => {
|
|
160
|
+
session.close();
|
|
161
|
+
process.exit(0);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
process.once('SIGTERM', stop);
|
|
165
|
+
process.once('SIGINT', stop);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
return cmd;
|
|
169
|
+
}
|