@michaelhartmayer/agentctl 1.2.0 → 1.2.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/dist/ctl.js CHANGED
@@ -54,40 +54,56 @@ async function getContext(options) {
54
54
  }
55
55
  async function scaffold(args, options = {}) {
56
56
  const ctx = await getContext(options);
57
- const localRoot = ctx.localRoot || ctx.cwd;
58
- const agentctlDir = path_1.default.join(localRoot, '.agentctl');
57
+ const isGlobal = !!options.global;
58
+ const rootDir = isGlobal ? ctx.globalRoot : ctx.cwd;
59
+ const agentctlDir = isGlobal ? rootDir : path_1.default.join(rootDir, '.agentctl');
59
60
  const targetDir = path_1.default.join(agentctlDir, args.join(path_1.default.sep));
60
61
  const exists = await fs_extra_1.default.pathExists(targetDir);
61
- const cappedAncestor = await getCappedAncestor(targetDir, agentctlDir);
62
- const { effects } = ctl_1.Logic.planScaffold(args, ctx, { exists, cappedAncestor: cappedAncestor || undefined, type: 'scaffold' });
62
+ const cappedAncestor = isGlobal ? null : await getCappedAncestor(targetDir, agentctlDir);
63
+ const isNewLocalRoot = !isGlobal && !(await fs_extra_1.default.pathExists(agentctlDir));
64
+ const { effects } = ctl_1.Logic.planScaffold(args, ctx, {
65
+ exists,
66
+ cappedAncestor: cappedAncestor || undefined,
67
+ type: 'scaffold',
68
+ scope: isGlobal ? 'global' : 'local',
69
+ isNewLocalRoot
70
+ });
63
71
  await (0, effects_1.execute)(effects);
64
72
  }
65
73
  async function alias(args, target, options = {}) {
66
74
  const ctx = await getContext(options);
67
- const localRoot = ctx.localRoot || ctx.cwd;
68
- const agentctlDir = path_1.default.join(localRoot, '.agentctl');
75
+ const isGlobal = !!options.global;
76
+ const rootDir = isGlobal ? ctx.globalRoot : ctx.cwd;
77
+ const agentctlDir = isGlobal ? rootDir : path_1.default.join(rootDir, '.agentctl');
69
78
  const targetDir = path_1.default.join(agentctlDir, args.join(path_1.default.sep));
70
79
  const exists = await fs_extra_1.default.pathExists(targetDir);
71
- const cappedAncestor = await getCappedAncestor(targetDir, agentctlDir);
80
+ const cappedAncestor = isGlobal ? null : await getCappedAncestor(targetDir, agentctlDir);
81
+ const isNewLocalRoot = !isGlobal && !(await fs_extra_1.default.pathExists(agentctlDir));
72
82
  const { effects } = ctl_1.Logic.planScaffold(args, ctx, {
73
83
  exists,
74
84
  cappedAncestor: cappedAncestor || undefined,
75
85
  type: 'alias',
76
- target
86
+ target,
87
+ scope: isGlobal ? 'global' : 'local',
88
+ isNewLocalRoot
77
89
  });
78
90
  await (0, effects_1.execute)(effects);
79
91
  }
80
92
  async function group(args, options = {}) {
81
93
  const ctx = await getContext(options);
82
- const localRoot = ctx.localRoot || ctx.cwd;
83
- const agentctlDir = path_1.default.join(localRoot, '.agentctl');
94
+ const isGlobal = !!options.global;
95
+ const rootDir = isGlobal ? ctx.globalRoot : ctx.cwd;
96
+ const agentctlDir = isGlobal ? rootDir : path_1.default.join(rootDir, '.agentctl');
84
97
  const targetDir = path_1.default.join(agentctlDir, args.join(path_1.default.sep));
85
98
  const exists = await fs_extra_1.default.pathExists(targetDir);
86
- const cappedAncestor = await getCappedAncestor(targetDir, agentctlDir);
99
+ const cappedAncestor = isGlobal ? null : await getCappedAncestor(targetDir, agentctlDir);
100
+ const isNewLocalRoot = !isGlobal && !(await fs_extra_1.default.pathExists(agentctlDir));
87
101
  const { effects } = ctl_1.Logic.planScaffold(args, ctx, {
88
102
  exists,
89
103
  cappedAncestor: cappedAncestor || undefined,
90
- type: 'group'
104
+ type: 'group',
105
+ scope: isGlobal ? 'global' : 'local',
106
+ isNewLocalRoot
91
107
  });
92
108
  await (0, effects_1.execute)(effects);
93
109
  }
@@ -176,13 +192,14 @@ async function installSkill(agent, options = {}) {
176
192
  }
177
193
  async function install(repoUrl, pathArgs, options = {}) {
178
194
  const ctx = await getContext(options);
195
+ const isNewLocalRoot = !options.global && !(await fs_extra_1.default.pathExists(path_1.default.join(ctx.cwd, '.agentctl')));
179
196
  const installCtx = {
180
197
  repoUrl,
181
198
  pathParts: pathArgs,
182
199
  global: !!options.global,
183
200
  allowCollisions: !!options.allowCollisions,
184
- localRoot: ctx.localRoot || ctx.cwd,
185
- isNewLocalRoot: !options.global && !ctx.localRoot,
201
+ localRoot: options.global ? ctx.globalRoot : ctx.cwd,
202
+ isNewLocalRoot,
186
203
  globalRoot: ctx.globalRoot,
187
204
  osTmpdir: os_1.default.tmpdir()
188
205
  };
package/dist/index.js CHANGED
@@ -76,6 +76,7 @@ const normalizePath = (parts) => parts.flatMap(p => p.split(/[\s/\\:]+/).filter(
76
76
  ctl.command('scaffold')
77
77
  .description('Scaffold a new command directory with a manifest and starter script.')
78
78
  .argument('[path...]', 'Hierarchical path for the new command (e.g., "dev start" or "utils/cleanup")')
79
+ .option('-g, --global', 'Create command in global scope')
79
80
  .summary('create a new command')
80
81
  .addHelpText('after', `
81
82
  Additional Info:
@@ -107,11 +108,12 @@ Examples:
107
108
  command.help();
108
109
  return;
109
110
  }
110
- await (0, ctl_1.scaffold)(normalized);
111
+ await (0, ctl_1.scaffold)(normalized, { global: opts.global });
111
112
  }));
112
113
  ctl.command('alias')
113
114
  .description('Create a command that executes a raw shell string.')
114
115
  .argument('[args...]', 'Hierarchical path segments followed by the shell command target')
116
+ .option('-g, --global', 'Create alias in global scope')
115
117
  .summary('create a shell alias')
116
118
  .addHelpText('after', `
117
119
  Examples:
@@ -129,11 +131,12 @@ Examples:
129
131
  command.help();
130
132
  return;
131
133
  }
132
- await (0, ctl_1.alias)(name, target);
134
+ await (0, ctl_1.alias)(name, target, { global: opts.global });
133
135
  }));
134
136
  ctl.command('group')
135
137
  .description('Create a command group (namespace) to organize subcommands.')
136
138
  .argument('[path...]', 'Hierarchical path for the group (e.g., "dev" or "cloud/aws")')
139
+ .option('-g, --global', 'Create group in global scope')
137
140
  .summary('create a namespace group')
138
141
  .addHelpText('after', `
139
142
  Additional Info:
@@ -165,7 +168,7 @@ Examples:
165
168
  command.help();
166
169
  return;
167
170
  }
168
- await (0, ctl_1.group)(normalized);
171
+ await (0, ctl_1.group)(normalized, { global: opts.global });
169
172
  }));
170
173
  ctl.command('rm')
171
174
  .description('Permanently remove a command or group.')
package/dist/logic/ctl.js CHANGED
@@ -21,8 +21,9 @@ exports.Logic = {
21
21
  if (options.cappedAncestor) {
22
22
  throw new Error(`Cannot nest command under capped command: ${options.cappedAncestor.relPath}`);
23
23
  }
24
- const localRoot = ctx.localRoot || ctx.cwd;
25
- const agentctlDir = path_1.default.join(localRoot, '.agentctl');
24
+ const isGlobal = options.scope === 'global';
25
+ const rootDir = isGlobal ? ctx.globalRoot : ctx.cwd;
26
+ const agentctlDir = isGlobal ? rootDir : path_1.default.join(rootDir, '.agentctl');
26
27
  const cmdPath = args.join(path_1.default.sep);
27
28
  const targetDir = path_1.default.join(agentctlDir, cmdPath);
28
29
  const name = args[args.length - 1];
@@ -53,6 +54,9 @@ exports.Logic = {
53
54
  const logMsg = type === 'scaffold' ? `Scaffolded command: ${args.join(' ')}` :
54
55
  type === 'alias' ? `Aliased command: ${args.join(' ')} -> ${options.target}` :
55
56
  `Created group: ${args.join(' ')}`;
57
+ if (options.isNewLocalRoot) {
58
+ effects.unshift({ type: 'log', message: `Initialized new .agentctl folder in ${rootDir}` });
59
+ }
56
60
  effects.push({ type: 'log', message: logMsg });
57
61
  return { effects };
58
62
  },
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.2.0",
7
+ "version": "1.2.1",
8
8
  "main": "dist/index.js",
9
9
  "bin": {
10
10
  "agentctl": "./dist/index.js"