@technomoron/agent-run 0.99.24 → 0.99.26

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/checks.js ADDED
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkProject = checkProject;
4
+ exports.checkSourceTree = checkSourceTree;
5
+ exports.printProjectReport = printProjectReport;
6
+ exports.printBatchReport = printBatchReport;
7
+ exports.hasErrors = hasErrors;
8
+ const fs = require("fs");
9
+ const path = require("path");
10
+ const constants_1 = require("./constants");
11
+ const manifest_1 = require("./manifest");
12
+ const project_1 = require("./project");
13
+ const renderer_1 = require("./renderer");
14
+ const utils_1 = require("./utils");
15
+ function checkProject(projectRoot) {
16
+ const findings = [];
17
+ (0, utils_1.verbose)(`checking project ${projectRoot}`);
18
+ const profileResult = (0, project_1.resolveProfileResult)(projectRoot);
19
+ if (profileResult.profile === null) {
20
+ for (const file of (0, project_1.findLocalAiFiles)(projectRoot)) {
21
+ findings.push({ message: `local AI file in project: ${file}`, severity: 'ERROR' });
22
+ }
23
+ findings.push({ message: profileResult.reason, severity: 'ERROR' });
24
+ return findings;
25
+ }
26
+ const agentDir = (0, project_1.resolveAgentDir)(projectRoot);
27
+ if (profileForbidsLocalAiFiles(projectRoot, agentDir, profileResult.profile)) {
28
+ for (const file of (0, project_1.findLocalAiFiles)(projectRoot, agentDir)) {
29
+ findings.push({ message: `local AI file in project: ${file}`, severity: 'ERROR' });
30
+ }
31
+ }
32
+ findings.push(...checkAgentDirectory(projectRoot, agentDir));
33
+ return findings;
34
+ }
35
+ function profileForbidsLocalAiFiles(projectRoot, agentDir, profile) {
36
+ try {
37
+ return (0, manifest_1.normalizeManifest)((0, manifest_1.loadManifest)((0, project_1.defaultConfigRoot)(projectRoot), agentDir, profile), profile).guardrails
38
+ .forbidRepoAiFiles;
39
+ }
40
+ catch {
41
+ return true;
42
+ }
43
+ }
44
+ function checkAgentDirectory(projectRoot, agentDir) {
45
+ const findings = [];
46
+ const configRoot = (0, project_1.defaultConfigRoot)(projectRoot);
47
+ if (!(0, manifest_1.isProfileConfigured)(agentDir)) {
48
+ return [{ message: `missing manifest or legacy/local source file in ${agentDir}`, severity: 'ERROR' }];
49
+ }
50
+ for (const relativeTemplate of constants_1.REQUIRED_GLOBAL_TEMPLATES) {
51
+ if (!fs.existsSync(path.join(configRoot, relativeTemplate))) {
52
+ findings.push({
53
+ message: `missing required global template: ${path.join(configRoot, relativeTemplate)}`,
54
+ severity: 'ERROR'
55
+ });
56
+ }
57
+ }
58
+ findings.push(...(0, renderer_1.checkRenderedProfile)(projectRoot, agentDir));
59
+ return findings;
60
+ }
61
+ function checkSourceTree(rootPath) {
62
+ const entries = (0, project_1.findSourceRepos)(rootPath).map((projectRoot) => ({
63
+ findings: checkProject(projectRoot),
64
+ label: projectRoot
65
+ }));
66
+ return {
67
+ entries,
68
+ hasErrors: entries.length === 0 || entries.some((entry) => hasErrors(entry.findings)),
69
+ root: rootPath
70
+ };
71
+ }
72
+ function printProjectReport(projectRoot, findings) {
73
+ process.stdout.write(`Check: ${projectRoot}\n`);
74
+ if (findings.length === 0) {
75
+ process.stdout.write('OK no issues found\n');
76
+ return;
77
+ }
78
+ for (const finding of findings) {
79
+ process.stdout.write(`${finding.severity} ${finding.message}\n`);
80
+ }
81
+ process.stdout.write(`Summary: ${countFindings(findings, 'ERROR')} error(s), ${countFindings(findings, 'WARN')} warning(s)\n`);
82
+ }
83
+ function printBatchReport(rootPath, entries) {
84
+ process.stdout.write(`Check all: ${rootPath}\n`);
85
+ if (entries.length === 0) {
86
+ process.stdout.write('ERROR no source repos found\n');
87
+ return;
88
+ }
89
+ let totalErrors = 0;
90
+ let totalWarnings = 0;
91
+ for (const entry of entries) {
92
+ if (entry.findings.length === 0) {
93
+ process.stdout.write(`OK ${entry.label}\n`);
94
+ continue;
95
+ }
96
+ process.stdout.write(`FAIL ${entry.label}\n`);
97
+ for (const finding of entry.findings) {
98
+ process.stdout.write(` ${finding.severity} ${finding.message}\n`);
99
+ }
100
+ totalErrors += countFindings(entry.findings, 'ERROR');
101
+ totalWarnings += countFindings(entry.findings, 'WARN');
102
+ }
103
+ process.stdout.write(`Summary: ${totalErrors} error(s), ${totalWarnings} warning(s)\n`);
104
+ }
105
+ function hasErrors(findings) {
106
+ return findings.some((finding) => finding.severity === 'ERROR');
107
+ }
108
+ function countFindings(findings, severity) {
109
+ return findings.filter((finding) => finding.severity === severity).length;
110
+ }
package/dist/cli.js ADDED
@@ -0,0 +1,371 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseInvocation = parseInvocation;
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const constants_1 = require("./constants");
7
+ const project_1 = require("./project");
8
+ const utils_1 = require("./utils");
9
+ function parseInvocation(invokedTool, argv) {
10
+ let command = normalizeCommandName(invokedTool);
11
+ const options = extractGlobalOptions(argv);
12
+ applyGlobalOptions(options);
13
+ if (options.initConfig) {
14
+ if (options.args.length > 0) {
15
+ (0, utils_1.fail)('--init cannot be combined with a command');
16
+ }
17
+ return {
18
+ command: 'init-config',
19
+ targetPath: path.resolve(options.initConfigTargetPath ?? (0, project_1.defaultConfigRoot)())
20
+ };
21
+ }
22
+ if (command === null) {
23
+ command = extractCommand(options.args);
24
+ }
25
+ return parseCommand(command, options.args);
26
+ }
27
+ function applyGlobalOptions(options) {
28
+ if (options.verbose) {
29
+ process.env[constants_1.VERBOSE_ENV] = '1';
30
+ }
31
+ if (options.configRootOverride !== null) {
32
+ process.env[constants_1.CONFIG_ROOT_OVERRIDE_ENV] = options.configRootOverride;
33
+ }
34
+ }
35
+ function extractCommand(args) {
36
+ if (args.length === 0) {
37
+ (0, utils_1.fail)('usage: agent-run <codex|claude|check|init|edit|update> [options] (run with --help for details)');
38
+ }
39
+ if (isHelpFlag(args[0])) {
40
+ printHelp('general');
41
+ }
42
+ if (isVersionFlag(args[0])) {
43
+ printVersion();
44
+ }
45
+ const commandIndex = args.findIndex((arg) => arg !== '--' && normalizeCommandName(arg) !== null);
46
+ if (commandIndex === -1 || args.slice(0, commandIndex).includes('--')) {
47
+ (0, utils_1.fail)(`unknown command: ${args[0] ?? ''} (run with --help for usage)`);
48
+ }
49
+ const command = normalizeCommandName(args[commandIndex] ?? '');
50
+ if (command === null) {
51
+ (0, utils_1.fail)(`unknown command: ${args[0] ?? ''} (run with --help for usage)`);
52
+ }
53
+ args.splice(commandIndex, 1);
54
+ return command;
55
+ }
56
+ function parseCommand(command, args) {
57
+ switch (command) {
58
+ case 'check':
59
+ return parseCheckCommand(args);
60
+ case 'init':
61
+ return parseInitCommand(args);
62
+ case 'edit':
63
+ return parseEditCommand(args);
64
+ case 'update':
65
+ return parseUpdateCommand(args);
66
+ case 'migrate-config':
67
+ return parseMigrateConfigCommand(args);
68
+ default:
69
+ return parseRunCommand(command, args);
70
+ }
71
+ }
72
+ function extractGlobalOptions(argv) {
73
+ const options = {
74
+ args: [],
75
+ configRootOverride: null,
76
+ initConfig: false,
77
+ initConfigTargetPath: null,
78
+ verbose: false
79
+ };
80
+ let passthrough = false;
81
+ for (let index = 0; index < argv.length; index += 1) {
82
+ const arg = argv[index];
83
+ if (arg === undefined) {
84
+ continue;
85
+ }
86
+ if (passthrough) {
87
+ options.args.push(arg);
88
+ continue;
89
+ }
90
+ if (arg === '--') {
91
+ passthrough = true;
92
+ options.args.push(arg);
93
+ }
94
+ else if (arg === '-v' || arg === '--verbose') {
95
+ options.verbose = true;
96
+ }
97
+ else if (arg === '--init') {
98
+ options.initConfig = true;
99
+ const nextArg = argv[index + 1];
100
+ if (nextArg !== undefined && !nextArg.startsWith('-')) {
101
+ options.initConfigTargetPath = nextArg;
102
+ index += 1;
103
+ }
104
+ }
105
+ else if (arg === '--config-root') {
106
+ const nextArg = argv[index + 1];
107
+ if (nextArg === undefined) {
108
+ (0, utils_1.fail)('missing value for --config-root');
109
+ }
110
+ options.configRootOverride = path.resolve(nextArg);
111
+ index += 1;
112
+ }
113
+ else if (arg.startsWith('--config-root=')) {
114
+ const rootValue = arg.slice('--config-root='.length);
115
+ if (!rootValue) {
116
+ (0, utils_1.fail)('missing value for --config-root');
117
+ }
118
+ options.configRootOverride = path.resolve(rootValue);
119
+ }
120
+ else {
121
+ options.args.push(arg);
122
+ }
123
+ }
124
+ return options;
125
+ }
126
+ function parseRunCommand(command, inputArgs) {
127
+ const wrapperArgs = {
128
+ none: false,
129
+ create: false,
130
+ local: false,
131
+ show: false,
132
+ generate: false,
133
+ sandboxMode: null,
134
+ codexNetwork: false
135
+ };
136
+ const args = [];
137
+ let passthrough = false;
138
+ for (const arg of inputArgs) {
139
+ if (passthrough) {
140
+ args.push(arg);
141
+ continue;
142
+ }
143
+ if (arg === '--') {
144
+ passthrough = true;
145
+ args.push(arg);
146
+ continue;
147
+ }
148
+ if (applyCommonRunOption(arg, wrapperArgs)) {
149
+ continue;
150
+ }
151
+ if (applySandboxRunOption(command, arg, wrapperArgs)) {
152
+ continue;
153
+ }
154
+ args.push(arg);
155
+ }
156
+ if (wrapperArgs.codexNetwork && wrapperArgs.sandboxMode === 'danger') {
157
+ (0, utils_1.fail)('--network cannot be combined with agent-run codex --danger');
158
+ }
159
+ return { args, command, wrapperArgs };
160
+ }
161
+ function applyCommonRunOption(arg, options) {
162
+ const fields = {
163
+ '--none': 'none',
164
+ '--create': 'create',
165
+ '--local': 'local',
166
+ '--show': 'show',
167
+ '--generate': 'generate'
168
+ };
169
+ const field = fields[arg];
170
+ if (field === undefined) {
171
+ return false;
172
+ }
173
+ options[field] = true;
174
+ return true;
175
+ }
176
+ function applySandboxRunOption(command, arg, options) {
177
+ if (!['--danger', '--sandboxed', '--network'].includes(arg)) {
178
+ return false;
179
+ }
180
+ if (arg !== '--danger' && command !== 'codex') {
181
+ (0, utils_1.fail)(`${arg} is only supported for agent-run codex`);
182
+ }
183
+ if (arg === '--network') {
184
+ options.codexNetwork = true;
185
+ return true;
186
+ }
187
+ const mode = arg === '--danger' ? 'danger' : 'sandboxed';
188
+ if (options.sandboxMode !== null && options.sandboxMode !== mode) {
189
+ (0, utils_1.fail)('cannot combine --danger and --sandboxed');
190
+ }
191
+ options.sandboxMode = mode;
192
+ return true;
193
+ }
194
+ function parseCheckCommand(inputArgs) {
195
+ let all = false;
196
+ let targetPath = process.cwd();
197
+ for (const arg of inputArgs) {
198
+ if (isHelpFlag(arg)) {
199
+ printHelp('check');
200
+ }
201
+ if (arg === '--all') {
202
+ all = true;
203
+ }
204
+ else if (arg.startsWith('--')) {
205
+ (0, utils_1.fail)(`unknown check option: ${arg}`);
206
+ }
207
+ else {
208
+ targetPath = arg;
209
+ }
210
+ }
211
+ return { all, command: 'check', targetPath: path.resolve(targetPath) };
212
+ }
213
+ function parseInitCommand(inputArgs) {
214
+ return { command: 'init', targetPath: parseSinglePath(inputArgs, 'init') };
215
+ }
216
+ function parseEditCommand(inputArgs) {
217
+ return { command: 'edit', targetPath: parseSinglePath(inputArgs, 'edit') };
218
+ }
219
+ function parseSinglePath(inputArgs, command) {
220
+ let targetPath = process.cwd();
221
+ for (const arg of inputArgs) {
222
+ if (isHelpFlag(arg)) {
223
+ printHelp(command);
224
+ }
225
+ if (arg.startsWith('--')) {
226
+ (0, utils_1.fail)(`unknown ${command} option: ${arg}`);
227
+ }
228
+ targetPath = arg;
229
+ }
230
+ return path.resolve(targetPath);
231
+ }
232
+ function parseUpdateCommand(inputArgs) {
233
+ let all = false;
234
+ let targetPath = process.cwd();
235
+ for (const arg of inputArgs) {
236
+ if (isHelpFlag(arg)) {
237
+ printHelp('update');
238
+ }
239
+ if (arg === '--all') {
240
+ all = true;
241
+ }
242
+ else if (arg.startsWith('--')) {
243
+ (0, utils_1.fail)(`unknown update option: ${arg}`);
244
+ }
245
+ else {
246
+ targetPath = arg;
247
+ }
248
+ }
249
+ return { all, command: 'update', targetPath: path.resolve(targetPath) };
250
+ }
251
+ function parseMigrateConfigCommand(inputArgs) {
252
+ let configRoot = (0, project_1.defaultConfigRoot)();
253
+ for (const arg of inputArgs) {
254
+ if (isHelpFlag(arg)) {
255
+ printHelp('migrate-config');
256
+ }
257
+ if (arg.startsWith('--')) {
258
+ (0, utils_1.fail)(`unknown migrate-config option: ${arg}`);
259
+ }
260
+ configRoot = arg;
261
+ }
262
+ return { command: 'migrate-config', configRoot: path.resolve(configRoot) };
263
+ }
264
+ function isHelpFlag(value) {
265
+ return value === '-h' || value === '--help';
266
+ }
267
+ function isVersionFlag(value) {
268
+ return value === '-V' || value === '--version';
269
+ }
270
+ function printVersion() {
271
+ process.stdout.write(`agent-run ${agentRunVersion()}\n`);
272
+ process.exit(0);
273
+ }
274
+ function printHelp(topic) {
275
+ process.stdout.write(renderHelp(topic));
276
+ process.exit(0);
277
+ }
278
+ function renderHelp(topic) {
279
+ const help = {
280
+ check: [
281
+ 'Usage:',
282
+ ' agent-run check [--all] [path]',
283
+ '',
284
+ 'Check generated profile files, native skills, guard shims, and local AI-file leaks.',
285
+ '',
286
+ 'Options:',
287
+ ' -h, --help Show this help text',
288
+ ' --all Check every repo under path',
289
+ ''
290
+ ],
291
+ init: ['Usage:', ' agent-run init [path]', '', 'Create a minimal mapped profile marker and render generated files.', ''],
292
+ edit: ['Usage:', ' agent-run edit [path]', '', 'Create or open the editable local profile template.', ''],
293
+ update: [
294
+ 'Usage:',
295
+ ' agent-run update [--all] [path]',
296
+ '',
297
+ 'Render generated files, native skills, config, and guard shims for an existing profile.',
298
+ 'With --all, render every profile found under the config root without requiring code checkouts.',
299
+ ''
300
+ ],
301
+ 'migrate-config': [
302
+ 'Usage:',
303
+ ' agent-run migrate-config [config-root]',
304
+ '',
305
+ 'Convert an existing agent config tree to the current manifest and global-template layout.',
306
+ ''
307
+ ]
308
+ };
309
+ if (topic !== 'general') {
310
+ return help[topic].join('\n');
311
+ }
312
+ return [
313
+ `agent-run ${agentRunVersion()}`,
314
+ '',
315
+ 'Usage:',
316
+ ' agent-run <codex|claude|check|init|edit|update> [options]',
317
+ ' agent-run --init [config-root]',
318
+ '',
319
+ 'Commands:',
320
+ ' codex [--none] [--create] [--local] [--show] [--generate] [--danger|--sandboxed] [--network] [args...]',
321
+ ' Run codex with generated private config',
322
+ ' claude [--none] [--create] [--local] [--show] [--generate] [--danger] [args...]',
323
+ ' Run claude with generated private config',
324
+ ' check [--all] [path] Validate generated profile output',
325
+ ' init [path] Create a sparse profile marker and render output',
326
+ ' edit [path] Create or open local.md.njk',
327
+ ' update [--all] [path] Regenerate existing profile output',
328
+ ' migrate-config [config-root] Convert existing config tree layout',
329
+ '',
330
+ 'Global options:',
331
+ ' -h, --help Show this help text',
332
+ ' -V, --version Show the agent-run version',
333
+ ' -v, --verbose Print path resolution and wrapper actions',
334
+ ' --config-root DIR Override the agent-config root',
335
+ ' --init [DIR] Copy the packaged starter config root to DIR (default ~/.agent-config)',
336
+ '',
337
+ 'Run wrapper options:',
338
+ ' --local Warn about local AI files instead of failing',
339
+ ' --show Show read/include and generated files without running the tool',
340
+ ' --generate Generate files without running the tool',
341
+ ' --danger Run unattended without approval prompts:',
342
+ ' Codex with -a never -s danger-full-access,',
343
+ ' Claude with --dangerously-skip-permissions',
344
+ '',
345
+ 'Codex wrapper options:',
346
+ ' --sandboxed Run Codex with workspace-write sandbox (default)',
347
+ ' --network Enable network for the workspace-write sandbox',
348
+ ''
349
+ ].join('\n');
350
+ }
351
+ function agentRunVersion() {
352
+ try {
353
+ const pkg = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', 'package.json'), 'utf8'));
354
+ return typeof pkg.version === 'string' && pkg.version ? pkg.version : constants_1.PACKAGE_VERSION;
355
+ }
356
+ catch {
357
+ return constants_1.PACKAGE_VERSION;
358
+ }
359
+ }
360
+ function normalizeCommandName(value) {
361
+ if (!value) {
362
+ return null;
363
+ }
364
+ const base = path.basename(value).toLowerCase().replace(/\.(?:js|cmd|exe|bat)$/, '');
365
+ if (base === 'agent-run') {
366
+ return null;
367
+ }
368
+ return ['codex', 'claude', 'check', 'init', 'edit', 'update', 'migrate-config'].includes(base)
369
+ ? base
370
+ : null;
371
+ }