@michaelhartmayer/agentctl 1.0.3 → 1.1.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/dist/skills.js CHANGED
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
4
  };
@@ -17,34 +8,32 @@ exports.copySkill = copySkill;
17
8
  const path_1 = __importDefault(require("path"));
18
9
  const fs_extra_1 = __importDefault(require("fs-extra"));
19
10
  exports.SUPPORTED_AGENTS = ['cursor', 'antigravity', 'agentsmd', 'gemini'];
20
- function copySkill(targetDir, agent) {
21
- return __awaiter(this, void 0, void 0, function* () {
22
- // We assume the skill file is located at ../skills/agentctl/SKILL.md relative to specific dist/src/ location
23
- // Or we find it in the project root if running from source.
24
- // In production (dist), structure might be:
25
- // dist/index.js
26
- // skills/agentctl/SKILL.md (if we copy it to dist)
27
- // Let's try to locate the source SKILL.md
28
- // If we are in /src, it is in ../skills/agentctl/SKILL.md
29
- // If we are in /dist/src (tsc default?), it depends on build.
30
- // Robust finding:
31
- let sourcePath = path_1.default.resolve(__dirname, '../../skills/agentctl/SKILL.md');
32
- if (!fs_extra_1.default.existsSync(sourcePath)) {
33
- // Try looking in src check (dev mode)
34
- sourcePath = path_1.default.resolve(__dirname, '../skills/agentctl/SKILL.md');
35
- }
36
- if (!fs_extra_1.default.existsSync(sourcePath)) {
37
- // Fallback for when running from dist/src
38
- sourcePath = path_1.default.resolve(__dirname, '../../../skills/agentctl/SKILL.md');
39
- }
40
- if (!fs_extra_1.default.existsSync(sourcePath)) {
41
- throw new Error(`Could not locate source SKILL.md. Checked: ${path_1.default.resolve(__dirname, '../../skills/agentctl/SKILL.md')}`);
42
- }
43
- yield fs_extra_1.default.ensureDir(targetDir);
44
- // Determine filename
45
- const filename = agent === 'cursor' ? 'agentctl.md' : 'SKILL.md';
46
- const targetFile = path_1.default.join(targetDir, filename);
47
- yield fs_extra_1.default.copy(sourcePath, targetFile, { overwrite: true });
48
- return targetFile;
49
- });
11
+ async function copySkill(targetDir, agent) {
12
+ // We assume the skill file is located at ../skills/agentctl/SKILL.md relative to specific dist/src/ location
13
+ // Or we find it in the project root if running from source.
14
+ // In production (dist), structure might be:
15
+ // dist/index.js
16
+ // skills/agentctl/SKILL.md (if we copy it to dist)
17
+ // Let's try to locate the source SKILL.md
18
+ // If we are in /src, it is in ../skills/agentctl/SKILL.md
19
+ // If we are in /dist/src (tsc default?), it depends on build.
20
+ // Robust finding:
21
+ let sourcePath = path_1.default.resolve(__dirname, '../../skills/agentctl/SKILL.md');
22
+ if (!fs_extra_1.default.existsSync(sourcePath)) {
23
+ // Try looking in src check (dev mode)
24
+ sourcePath = path_1.default.resolve(__dirname, '../skills/agentctl/SKILL.md');
25
+ }
26
+ if (!fs_extra_1.default.existsSync(sourcePath)) {
27
+ // Fallback for when running from dist/src
28
+ sourcePath = path_1.default.resolve(__dirname, '../../../skills/agentctl/SKILL.md');
29
+ }
30
+ if (!fs_extra_1.default.existsSync(sourcePath)) {
31
+ throw new Error(`Could not locate source SKILL.md. Checked: ${path_1.default.resolve(__dirname, '../../skills/agentctl/SKILL.md')}`);
32
+ }
33
+ await fs_extra_1.default.ensureDir(targetDir);
34
+ // Determine filename
35
+ const filename = agent === 'cursor' ? 'agentctl.md' : 'SKILL.md';
36
+ const targetFile = path_1.default.join(targetDir, filename);
37
+ await fs_extra_1.default.copy(sourcePath, targetFile, { overwrite: true });
38
+ return targetFile;
50
39
  }
package/dist/src/index.js CHANGED
@@ -123,7 +123,7 @@ program
123
123
  }
124
124
  });
125
125
  const ctl = program.command('ctl')
126
- .description('Agent Controller Management - Create, organizing, and managing commands');
126
+ .description('Agent Controller Management - Create, organize, and manage commands');
127
127
  // --- Lifecycle Commands ---
128
128
  // We'll stick to flat list but with good descriptions.
129
129
  // Helper for consistent error handling
@@ -145,67 +145,101 @@ const withErrorHandling = (fn) => {
145
145
  };
146
146
  };
147
147
  ctl.command('scaffold')
148
- .description('Create a new capped command with a script file')
149
- .argument('<path...>', 'Command path segments (e.g., "dev start")')
148
+ .description('Scaffold a new command script (creates a manifest and a .sh/.cmd file)')
149
+ .argument('[path...]', 'The hierarchical path for the new command (e.g. "dev start")')
150
150
  .addHelpText('after', `
151
+ Description:
152
+ Scaffolding creates a new directory for your command containing a 'manifest.json'
153
+ and a boilerplate script file (.sh on Linux/Mac, .cmd on Windows).
154
+ You can then edit the script to add your own logic.
155
+
151
156
  Examples:
152
157
  $ agentctl ctl scaffold dev start
153
- $ agentctl ctl scaffold sys backup
158
+ $ agentctl ctl scaffold utils/backup
154
159
  `)
155
- .action(withErrorHandling(async (pathParts) => {
160
+ .action(withErrorHandling(async (pathParts, _options, command) => {
161
+ if (!pathParts || pathParts.length === 0) {
162
+ command.help();
163
+ return;
164
+ }
156
165
  await (0, ctl_1.scaffold)(pathParts);
157
166
  }));
158
167
  ctl.command('alias')
159
- .description('Create a new capped command that runs an inline shell command')
160
- .argument('<args...>', 'Name parts followed by target (e.g., "tools" "gh" "gh")')
161
- .action(withErrorHandling(async (args) => {
162
- if (args.length < 2) {
163
- console.error('Usage: ctl alias <name...> <target>');
164
- process.exit(1);
168
+ .description('Create an alias command that executes a shell string')
169
+ .argument('[path_and_cmd...]', 'Hierarchical path segments followed by the shell command')
170
+ .action(withErrorHandling(async (args, _options, command) => {
171
+ if (!args || args.length < 2) {
172
+ command.help();
173
+ return;
165
174
  }
166
175
  const target = args.pop();
167
176
  const name = args;
168
177
  await (0, ctl_1.alias)(name, target);
169
178
  }))
170
179
  .addHelpText('after', `
180
+ How it works:
181
+ The last argument is always treated as the shell command to execute.
182
+ All preceding arguments form the hierarchical path.
183
+
184
+ If the shell command contains spaces, wrap it in quotes.
185
+
171
186
  Examples:
172
- $ agentctl ctl alias tools gh "gh"
187
+ $ agentctl ctl alias tools git-status "git status"
188
+ -> Creates 'agentctl tools git-status' which runs 'git status'.
189
+
173
190
  $ agentctl ctl alias dev build "npm run build"
191
+ -> Creates 'agentctl dev build' which runs 'npm run build'.
174
192
  `);
175
193
  ctl.command('group')
176
- .description('Create a new command group (namespace)')
177
- .argument('<path...>', 'Group path (e.g., "dev")')
194
+ .description('Create a command group (namespace) to organize related commands')
195
+ .argument('[path...]', 'Hierarchical path for the group (e.g. "dev")')
178
196
  .addHelpText('after', `
197
+ Description:
198
+ Groups are essentially folders that contain other commands.
199
+ They don't execute anything themselves but provide organization.
200
+
179
201
  Examples:
180
202
  $ agentctl ctl group dev
181
- $ agentctl ctl group tools
203
+ $ agentctl ctl group tools/internal
182
204
  `)
183
- .action(withErrorHandling(async (parts) => {
205
+ .action(withErrorHandling(async (parts, _options, command) => {
206
+ if (!parts || parts.length === 0) {
207
+ command.help();
208
+ return;
209
+ }
184
210
  await (0, ctl_1.group)(parts);
185
211
  }));
186
212
  ctl.command('rm')
187
213
  .description('Remove a command or group permanently')
188
- .argument('<path...>', 'Command path to remove')
214
+ .argument('[path...]', 'Command path to remove')
189
215
  .option('--global', 'Remove from global scope')
190
216
  .addHelpText('after', `
191
217
  Examples:
192
218
  $ agentctl ctl rm dev start
193
219
  $ agentctl ctl rm tools --global
194
220
  `)
195
- .action(withErrorHandling(async (parts, opts) => {
221
+ .action(withErrorHandling(async (parts, opts, command) => {
222
+ if (!parts || parts.length === 0) {
223
+ command.help();
224
+ return;
225
+ }
196
226
  await (0, ctl_1.rm)(parts, { global: opts.global });
197
227
  }));
198
228
  ctl.command('mv')
199
- .description('Move a command or group to a new path')
200
- .argument('<src>', 'Source path (quoted string or single token)')
201
- .argument('<dest>', 'Destination path')
202
- .option('--global', 'Move command in global scope')
229
+ .description('Move or rename a command or group')
230
+ .argument('[src]', 'Current path of the command')
231
+ .argument('[dest]', 'New path for the command')
232
+ .option('--global', 'Perform operation in global scope')
203
233
  .addHelpText('after', `
204
234
  Examples:
205
235
  $ agentctl ctl mv "dev start" "dev boot"
206
236
  $ agentctl ctl mv tools/gh tools/github --global
207
237
  `)
208
- .action(withErrorHandling(async (src, dest, opts) => {
238
+ .action(withErrorHandling(async (src, dest, opts, command) => {
239
+ if (!src || !dest) {
240
+ command.help();
241
+ return;
242
+ }
209
243
  await (0, ctl_1.mv)(src.split(' '), dest.split(' '), { global: opts.global });
210
244
  }));
211
245
  // --- Introspection ---
@@ -220,8 +254,12 @@ ctl.command('list')
220
254
  }));
221
255
  ctl.command('inspect')
222
256
  .description('Inspect the internal manifest and details of a command')
223
- .argument('<path...>', 'Command path to inspect')
224
- .action(withErrorHandling(async (parts) => {
257
+ .argument('[path...]', 'Command path to inspect')
258
+ .action(withErrorHandling(async (parts, _options, command) => {
259
+ if (!parts || parts.length === 0) {
260
+ command.help();
261
+ return;
262
+ }
225
263
  const info = await (0, ctl_1.inspect)(parts);
226
264
  if (info) {
227
265
  console.log(JSON.stringify(info, null, 2));
@@ -234,7 +272,7 @@ ctl.command('inspect')
234
272
  // --- Scoping ---
235
273
  ctl.command('global')
236
274
  .description('Push a local command to the global scope')
237
- .argument('<path...>', 'Local command path')
275
+ .argument('[path...]', 'Local command path')
238
276
  .option('--move', 'Move instead of copy')
239
277
  .option('--copy', 'Copy (default)')
240
278
  .addHelpText('after', `
@@ -242,19 +280,27 @@ Examples:
242
280
  $ agentctl ctl global sys --move
243
281
  $ agentctl ctl global tools --copy
244
282
  `)
245
- .action(withErrorHandling(async (parts, opts) => {
283
+ .action(withErrorHandling(async (parts, opts, command) => {
284
+ if (!parts || parts.length === 0) {
285
+ command.help();
286
+ return;
287
+ }
246
288
  await (0, ctl_1.pushGlobal)(parts, { move: opts.move, copy: opts.copy || !opts.move });
247
289
  }));
248
290
  ctl.command('local')
249
291
  .description('Pull a global command to the local scope')
250
- .argument('<path...>', 'Global command path')
292
+ .argument('[path...]', 'Global command path')
251
293
  .option('--move', 'Move instead of copy')
252
294
  .option('--copy', 'Copy (default)')
253
295
  .addHelpText('after', `
254
296
  Examples:
255
297
  $ agentctl ctl local tools --copy
256
298
  `)
257
- .action(withErrorHandling(async (parts, opts) => {
299
+ .action(withErrorHandling(async (parts, opts, command) => {
300
+ if (!parts || parts.length === 0) {
301
+ command.help();
302
+ return;
303
+ }
258
304
  await (0, ctl_1.pullLocal)(parts, { move: opts.move, copy: opts.copy || !opts.move });
259
305
  }));
260
306
  // --- Agent Integration ---
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "description": "Agent Controller - A unified interface for humans and AI agents",
7
- "version": "1.0.3",
7
+ "version": "1.1.0",
8
8
  "main": "dist/index.js",
9
9
  "bin": {
10
10
  "agentctl": "./dist/index.js"