@technomoron/agent-run 0.99.5 → 0.99.7

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.
Files changed (28) hide show
  1. package/CHANGES +10 -0
  2. package/README.md +29 -0
  3. package/dist/agent-run.js +81 -4
  4. package/examples/basic-config/README.md +22 -0
  5. package/examples/basic-config/agent-config/gitignore +21 -0
  6. package/examples/basic-config/agent-config/global/agents/code.md.njk +9 -0
  7. package/examples/basic-config/agent-config/global/agents/writing.md.njk +5 -0
  8. package/examples/basic-config/agent-config/global/skills/code-review/SKILL.md.njk +12 -0
  9. package/examples/basic-config/agent-config/global/skills/commit-workflow/SKILL.md.njk +12 -0
  10. package/examples/basic-config/agent-config/global/skills/github-release/SKILL.md.njk +8 -0
  11. package/examples/basic-config/agent-config/global/skills/triage/SKILL.md.njk +8 -0
  12. package/examples/basic-config/agent-config/global/snippets/git-rules.md.njk +9 -0
  13. package/examples/basic-config/agent-config/global/snippets/no-ai-files.md.njk +9 -0
  14. package/examples/basic-config/agent-config/global/snippets/verification.md.njk +7 -0
  15. package/examples/basic-config/agent-config/global/tool-templates/AGENTS.md.njk +20 -0
  16. package/examples/basic-config/agent-config/global/tool-templates/CLAUDE.md.njk +7 -0
  17. package/examples/basic-config/agent-config/global/tool-templates/claude-settings.json.njk +7 -0
  18. package/examples/basic-config/agent-config/global/tool-templates/codex-config.toml.njk +11 -0
  19. package/examples/basic-config/agent-config/starter/basic-project/agent-run.jsonc +43 -0
  20. package/examples/basic-config/agent-config/starter/basic-project/local.md.njk +5 -0
  21. package/examples/basic-config/agent-config/starter/basic-project/overrides/claude-settings.json.njk +8 -0
  22. package/examples/basic-config/agent-config/starter/basic-project/overrides/codex-config.toml.njk +11 -0
  23. package/examples/basic-config/agent-config/starter/basic-project/overrides/triage.SKILL.md.njk +12 -0
  24. package/examples/basic-config/agent-config/starter/basic-project/project-rules.md.njk +5 -0
  25. package/examples/basic-config/project/.agent-run.env +2 -0
  26. package/examples/basic-config/project/CHANGES +7 -0
  27. package/examples/basic-config/project/package.json +8 -0
  28. package/package.json +4 -2
package/CHANGES CHANGED
@@ -4,6 +4,16 @@ CHANGES
4
4
  Unreleased (2026-04-24)
5
5
  -----------------------
6
6
 
7
+ Version 0.99.7 (2026-04-26)
8
+ ---------------------------
9
+ * Add a checked-in basic starter config under `examples/basic-config` that exercises manifests, templates, snippets, skills, overrides, guardrails, checks, and generated runtime paths.
10
+ * Add `agent-run --init [config-root]` to copy the packaged starter config skeleton to a destination, defaulting to `~/.agent-config`.
11
+ * Replace the placeholder test command with an integration test suite covering the starter config, rendering, checking, stale-file detection, guard shims, local AI-file detection, and flexible command parsing.
12
+
13
+ Version 0.99.6 (2026-04-26)
14
+ ---------------------------
15
+ * Allow `agent-run` to find the target command after wrapper arguments, so invocations like `agent-run --sandboxed --network codex` work the same as `agent-run codex --sandboxed --network`.
16
+
7
17
  Version 0.99.5 (2026-04-25)
8
18
  ---------------------------
9
19
  * Bootstrap missing default global templates, manifests, local templates, and overrides before `agent-run codex`, `agent-run claude`, or `agent-run update` render a profile.
package/README.md CHANGED
@@ -165,6 +165,35 @@ Per-profile override templates can be placed in:
165
165
  - `overrides/codex-config.toml.njk`
166
166
  - `overrides/claude-settings.json.njk`
167
167
 
168
+ ## Starter Config
169
+
170
+ A complete starter lives in `examples/basic-config`. It includes a minimal
171
+ project, `.agent-run.env`, a config root with global templates and snippets,
172
+ profile-local templates, skill templates, profile skill overrides, tool config
173
+ overrides, guardrails, checks, and generated runtime paths.
174
+
175
+ To copy the packaged starter config root into your default config location:
176
+
177
+ ```sh
178
+ agent-run --init
179
+ ```
180
+
181
+ Or choose a destination:
182
+
183
+ ```sh
184
+ agent-run --init ~/.agent-config
185
+ ```
186
+
187
+ The copy skips files that already exist, so local edits are preserved.
188
+
189
+ Try it from a checkout:
190
+
191
+ ```sh
192
+ pnpm build
193
+ node dist/agent-run.js update examples/basic-config/project
194
+ node dist/agent-run.js check examples/basic-config/project
195
+ ```
196
+
168
197
  Check the current repo:
169
198
 
170
199
  ```sh
package/dist/agent-run.js CHANGED
@@ -69,6 +69,10 @@ function main(invokedTool, argv) {
69
69
  runInit(parsed);
70
70
  return;
71
71
  }
72
+ if (parsed.command === 'init-config') {
73
+ runInitConfig(parsed);
74
+ return;
75
+ }
72
76
  if (parsed.command === 'edit') {
73
77
  runEdit(parsed);
74
78
  return;
@@ -93,18 +97,33 @@ function parseInvocation(invokedTool, argv) {
93
97
  if (extracted.configRootOverride !== null) {
94
98
  process.env[CONFIG_ROOT_OVERRIDE_ENV] = extracted.configRootOverride;
95
99
  }
100
+ if (extracted.initConfig) {
101
+ if (inputArgs.length > 0) {
102
+ fail('--init cannot be combined with a command');
103
+ }
104
+ return {
105
+ command: 'init-config',
106
+ targetPath: path.resolve(extracted.initConfigTargetPath ?? defaultConfigRoot())
107
+ };
108
+ }
96
109
  if (command === null) {
97
110
  if (inputArgs.length === 0) {
98
111
  fail('usage: agent-run <codex|claude|check|init|edit|update> [options] (run with --help for details)');
99
112
  }
100
- const firstArg = inputArgs.shift();
113
+ const firstArg = inputArgs[0];
101
114
  if (isHelpFlag(firstArg)) {
102
115
  printHelp('general');
103
116
  }
104
- command = normalizeCommandName(firstArg ?? '');
105
- if (command === null) {
117
+ const commandIndex = findCommandArgIndex(inputArgs);
118
+ if (commandIndex === -1) {
106
119
  fail(`unknown command: ${firstArg ?? ''} (run with --help for usage)`);
107
120
  }
121
+ const parsedCommand = normalizeCommandName(inputArgs[commandIndex] ?? '');
122
+ if (parsedCommand === null) {
123
+ fail(`unknown command: ${firstArg ?? ''} (run with --help for usage)`);
124
+ }
125
+ command = parsedCommand;
126
+ inputArgs.splice(commandIndex, 1);
108
127
  }
109
128
  if (command === 'check') {
110
129
  return parseCheckCommand(inputArgs);
@@ -123,9 +142,23 @@ function parseInvocation(invokedTool, argv) {
123
142
  }
124
143
  return parseRunCommand(command, inputArgs);
125
144
  }
145
+ function findCommandArgIndex(args) {
146
+ for (let index = 0; index < args.length; index += 1) {
147
+ const arg = args[index];
148
+ if (arg === '--') {
149
+ return -1;
150
+ }
151
+ if (normalizeCommandName(arg ?? '') !== null) {
152
+ return index;
153
+ }
154
+ }
155
+ return -1;
156
+ }
126
157
  function extractGlobalOptions(argv) {
127
158
  const args = [];
128
159
  let configRootOverride = null;
160
+ let initConfig = false;
161
+ let initConfigTargetPath = null;
129
162
  let verbose = false;
130
163
  let passthrough = false;
131
164
  for (let index = 0; index < argv.length; index += 1) {
@@ -145,6 +178,15 @@ function extractGlobalOptions(argv) {
145
178
  verbose = true;
146
179
  continue;
147
180
  }
181
+ if (arg === '--init') {
182
+ initConfig = true;
183
+ const nextArg = argv[index + 1];
184
+ if (nextArg !== undefined && !nextArg.startsWith('-')) {
185
+ initConfigTargetPath = nextArg;
186
+ index += 1;
187
+ }
188
+ continue;
189
+ }
148
190
  if (arg === '--config-root') {
149
191
  const nextArg = argv[index + 1];
150
192
  if (nextArg === undefined) {
@@ -164,7 +206,7 @@ function extractGlobalOptions(argv) {
164
206
  }
165
207
  args.push(arg);
166
208
  }
167
- return { args, configRootOverride, verbose };
209
+ return { args, configRootOverride, initConfig, initConfigTargetPath, verbose };
168
210
  }
169
211
  function parseRunCommand(command, inputArgs) {
170
212
  const wrapperArgs = {
@@ -354,6 +396,7 @@ function renderHelp(topic) {
354
396
  return [
355
397
  'Usage:',
356
398
  ' agent-run <codex|claude|check|init|edit|update> [options]',
399
+ ' agent-run --init [config-root]',
357
400
  '',
358
401
  'Commands:',
359
402
  ' codex [--none] [--create] [--danger|--sandboxed] [--network] [args...]',
@@ -369,6 +412,7 @@ function renderHelp(topic) {
369
412
  ' -h, --help Show this help text',
370
413
  ' -v, --verbose Print path resolution and wrapper actions',
371
414
  ' --config-root DIR Override the agent-config root',
415
+ ' --init [DIR] Copy the packaged starter config root to DIR (default ~/.agent-config)',
372
416
  '',
373
417
  'Codex wrapper options:',
374
418
  ' --danger Run Codex with no sandbox: -a never -s danger-full-access (default)',
@@ -464,6 +508,15 @@ function runInit(parsed) {
464
508
  const rendered = syncAgentProfile(projectRoot, agentDir);
465
509
  printUpdateSummary(rendered);
466
510
  }
511
+ function runInitConfig(parsed) {
512
+ const targetPath = path.resolve(parsed.targetPath);
513
+ const sourcePath = starterConfigRootPath();
514
+ if (!fs.existsSync(sourcePath)) {
515
+ fail(`starter config skeleton not found: ${sourcePath}`);
516
+ }
517
+ copySkeletonTree(sourcePath, targetPath);
518
+ process.stdout.write(`OK copied starter config to ${targetPath}\n`);
519
+ }
467
520
  function ensureRunnableProfile(configRoot, agentDir, profile) {
468
521
  ensureConfigRootLayout(configRoot);
469
522
  ensureConfigRootGitignore(configRoot);
@@ -974,6 +1027,30 @@ function writeGeneratedFile(filePath, content, executable = false) {
974
1027
  }
975
1028
  verbose(`write ${filePath}`);
976
1029
  }
1030
+ function starterConfigRootPath() {
1031
+ return path.resolve(__dirname, '..', 'examples', 'basic-config', 'agent-config');
1032
+ }
1033
+ function copySkeletonTree(sourceDir, targetDir) {
1034
+ fs.mkdirSync(targetDir, { recursive: true });
1035
+ const entries = fs.readdirSync(sourceDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
1036
+ for (const entry of entries) {
1037
+ const sourcePath = path.join(sourceDir, entry.name);
1038
+ const targetName = entry.name === 'gitignore' ? '.gitignore' : entry.name;
1039
+ const targetPath = path.join(targetDir, targetName);
1040
+ if (entry.isDirectory()) {
1041
+ copySkeletonTree(sourcePath, targetPath);
1042
+ continue;
1043
+ }
1044
+ if (!entry.isFile()) {
1045
+ continue;
1046
+ }
1047
+ if (fs.existsSync(targetPath)) {
1048
+ continue;
1049
+ }
1050
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
1051
+ fs.copyFileSync(sourcePath, targetPath);
1052
+ }
1053
+ }
977
1054
  function renderProfile(projectRoot, agentDir, checkOnly = false) {
978
1055
  const configRoot = defaultConfigRoot(projectRoot);
979
1056
  const profile = resolveProfile(projectRoot);
@@ -0,0 +1,22 @@
1
+ # agent-run Basic Config
2
+
3
+ This directory is a small, copyable starter for a repo that wants to keep
4
+ agent-run files outside the source tree.
5
+
6
+ It contains two pieces:
7
+
8
+ - `project/`: a minimal project with `.agent-run.env` pointing at the bundled
9
+ config root.
10
+ - `agent-config/`: a complete config root with global templates, snippets,
11
+ skill templates, a profile manifest, profile-local instructions, and profile
12
+ overrides.
13
+
14
+ Try it from this repository after building:
15
+
16
+ ```sh
17
+ pnpm build
18
+ node dist/agent-run.js update examples/basic-config/project
19
+ node dist/agent-run.js check examples/basic-config/project
20
+ ```
21
+
22
+ Generated files are written under `examples/basic-config/agent-config/starter/basic-project/`.
@@ -0,0 +1,21 @@
1
+ # Generated agent-run files
2
+ **/AGENTS.md
3
+ **/CLAUDE.md
4
+ **/GEMINI.md
5
+ **/config.toml
6
+
7
+ # Generated native agent homes
8
+ **/.agents/
9
+ **/.claude/
10
+ **/.codex/
11
+
12
+ # Generated runtime files
13
+ **/bin/
14
+ **/reviews/
15
+ **/memories/
16
+
17
+ # Generated review reports
18
+ **/REVIEW-*.md
19
+
20
+ # Optional generated caches
21
+ **/.agent-run-cache/
@@ -0,0 +1,9 @@
1
+ # Starter Code Agent
2
+
3
+ Project kind: `{{ kind }}`.
4
+
5
+ {% include "global/snippets/git-rules.md.njk" %}
6
+
7
+ {% include "global/snippets/no-ai-files.md.njk" %}
8
+
9
+ {% include "global/snippets/verification.md.njk" %}
@@ -0,0 +1,5 @@
1
+ # Starter Writing Agent
2
+
3
+ Write clear project documentation and preserve existing facts.
4
+
5
+ {% include "global/snippets/no-ai-files.md.njk" %}
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: code-review
3
+ description: Use for reviewing code changes in {{ profile }}.
4
+ ---
5
+
6
+ # Code Review
7
+
8
+ Write review notes to:
9
+
10
+ ```text
11
+ {{ paths.reviewFile }}
12
+ ```
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: commit-workflow
3
+ description: Use when preparing commits for {{ profile }}.
4
+ ---
5
+
6
+ # Commit Workflow
7
+
8
+ Review changed files before committing. Run:
9
+
10
+ {% for check in checks %}
11
+ - `{{ check }}`
12
+ {% endfor %}
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: github-release
3
+ description: Use when preparing a release for {{ profile }}.
4
+ ---
5
+
6
+ # GitHub Release
7
+
8
+ Use `{{ paths.changesFile }}` for release notes. Do not publish without user approval.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: triage
3
+ description: Use for sorting incoming work for {{ profile }}.
4
+ ---
5
+
6
+ # Triage
7
+
8
+ Classify requests, identify blockers, and name the configured checks that apply.
@@ -0,0 +1,9 @@
1
+ ## Git Rules
2
+
3
+ Do not commit, tag, or push unless the user explicitly asks for that action.
4
+
5
+ Guardrails:
6
+
7
+ - blockGitWrite: `{{ guardrails.blockGitWrite }}`
8
+ - blockPublish: `{{ guardrails.blockPublish }}`
9
+ - blockGithubRelease: `{{ guardrails.blockGithubRelease }}`
@@ -0,0 +1,9 @@
1
+ ## Agent File Storage
2
+
3
+ Keep generated agent files out of the project repository.
4
+
5
+ Agent directory:
6
+
7
+ ```text
8
+ {{ agentDir }}
9
+ ```
@@ -0,0 +1,7 @@
1
+ ## Verification
2
+
3
+ Run the configured checks before reporting completion:
4
+
5
+ {% for check in checks %}
6
+ - `{{ check }}`
7
+ {% endfor %}
@@ -0,0 +1,20 @@
1
+ # Starter AGENTS for {{ profile }}
2
+
3
+ Do not edit this generated file. Edit `agent-run.jsonc` and `local.md.njk`.
4
+
5
+ {% for section in renderedAgentSections %}
6
+ {{ section }}
7
+
8
+ {% endfor %}
9
+ ## Paths
10
+
11
+ - projectRoot: `{{ projectRoot }}`
12
+ - agentDir: `{{ agentDir }}`
13
+ - reviewFile: `{{ paths.reviewFile }}`
14
+ - memoriesDir: `{{ paths.memoriesDir }}`
15
+
16
+ ## Skills
17
+
18
+ {% for skill in skills %}
19
+ - `{{ skill.name }}`: {{ skill.description }}
20
+ {% endfor %}
@@ -0,0 +1,7 @@
1
+ # Starter CLAUDE for {{ profile }}
2
+
3
+ {% for section in renderedAgentSections %}
4
+ {{ section }}
5
+
6
+ {% endfor %}
7
+ Claude reads this file from the private agent directory.
@@ -0,0 +1,7 @@
1
+ {
2
+ "env": {
3
+ "AGENT_DIR": "{{ agentDir }}",
4
+ "AGENT_RUN_PROJECT_ROOT": "{{ projectRoot }}",
5
+ "STARTER_PROFILE": "{{ profile }}"
6
+ }
7
+ }
@@ -0,0 +1,11 @@
1
+ # Starter global Codex config
2
+ project_doc_max_bytes = 32768
3
+ sandbox_mode = "workspace-write"
4
+
5
+ [sandbox_workspace_write]
6
+ writable_roots = [
7
+ "{{ projectRoot }}",
8
+ "{{ agentDir }}",
9
+ "{{ paths.memoriesDir }}"
10
+ ]
11
+ network_access = false
@@ -0,0 +1,43 @@
1
+ {
2
+ "profile": "starter/basic-project",
3
+ "kind": "code",
4
+ "agent": {
5
+ "base": "global/agents/code.md.njk",
6
+ "includes": [
7
+ "{{ profile }}/local.md.njk",
8
+ "{{ profile }}/project-rules.md.njk"
9
+ ]
10
+ },
11
+ "skills": {
12
+ "install": [
13
+ "commit-workflow",
14
+ "github-release",
15
+ "code-review",
16
+ "triage"
17
+ ],
18
+ "overrides": {
19
+ "triage": "{{ profile }}/overrides/triage.SKILL.md.njk"
20
+ }
21
+ },
22
+ "tools": {
23
+ "codex": true,
24
+ "claude": true
25
+ },
26
+ "checks": [
27
+ "agent-run check .",
28
+ "pnpm run cleanbuild",
29
+ "pnpm test"
30
+ ],
31
+ "guardrails": {
32
+ "blockGitWrite": true,
33
+ "blockPublish": true,
34
+ "blockGithubRelease": true,
35
+ "forbidRepoAiFiles": true
36
+ },
37
+ "paths": {
38
+ "changesFile": "{{ projectRoot }}/CHANGES",
39
+ "reviewDir": "{{ agentDir }}/reviews",
40
+ "reviewFile": "{{ agentDir }}/reviews/REVIEW-{{ date }}.md",
41
+ "memoriesDir": "{{ agentDir }}/memories"
42
+ }
43
+ }
@@ -0,0 +1,5 @@
1
+ ## Local Project Instructions
2
+
3
+ This starter profile belongs to `{{ profile }}`.
4
+
5
+ Use the project root at `{{ projectRoot }}` and keep generated files in `{{ agentDir }}`.
@@ -0,0 +1,8 @@
1
+ {
2
+ "env": {
3
+ "AGENT_DIR": "{{ agentDir }}",
4
+ "AGENT_RUN_PROJECT_ROOT": "{{ projectRoot }}",
5
+ "STARTER_PROFILE": "{{ profile }}",
6
+ "STARTER_OVERRIDE": "true"
7
+ }
8
+ }
@@ -0,0 +1,11 @@
1
+ # Starter profile Codex override
2
+ project_doc_max_bytes = 65536
3
+ sandbox_mode = "workspace-write"
4
+
5
+ [sandbox_workspace_write]
6
+ writable_roots = [
7
+ "{{ projectRoot }}",
8
+ "{{ agentDir }}",
9
+ "{{ paths.memoriesDir }}"
10
+ ]
11
+ network_access = false
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: triage
3
+ description: Use this profile-specific triage workflow for {{ profile }}.
4
+ ---
5
+
6
+ # Starter Triage
7
+
8
+ Use the project checks from this profile before closing out:
9
+
10
+ {% for check in checks %}
11
+ - `{{ check }}`
12
+ {% endfor %}
@@ -0,0 +1,5 @@
1
+ ## Project Rules
2
+
3
+ - Prefer small, reviewed changes.
4
+ - Keep release notes in `{{ paths.changesFile }}`.
5
+ - Store durable notes in `{{ paths.memoriesDir }}`.
@@ -0,0 +1,2 @@
1
+ AGENT_CONFIG_DIR=../agent-config
2
+ AGENT_RUN_PROFILE=starter/basic-project
@@ -0,0 +1,7 @@
1
+ CHANGES
2
+ =======
3
+
4
+ Unreleased
5
+ ----------
6
+
7
+ * Starter project.
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "@starter/basic-project",
3
+ "private": true,
4
+ "scripts": {
5
+ "cleanbuild": "echo cleanbuild",
6
+ "test": "echo test"
7
+ }
8
+ }
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@technomoron/agent-run",
3
- "version": "0.99.5",
3
+ "version": "0.99.7",
4
4
  "packageManager": "pnpm@10.28.1",
5
5
  "bin": {
6
6
  "agent-run": "dist/agent-run.js"
7
7
  },
8
8
  "files": [
9
9
  "dist/",
10
+ "examples/",
10
11
  "README.md",
11
12
  "LICENSE",
12
13
  "CHANGES"
@@ -21,7 +22,8 @@
21
22
  "clean:dist": "rimraf ./dist/",
22
23
  "cleanbuild": "run-s clean:dist build",
23
24
  "prepack": "run-s build",
24
- "test": "echo 'No tests for agent-run'",
25
+ "test": "run-s build test:integration",
26
+ "test:integration": "bash ./scripts/test.sh",
25
27
  "release": "bash ./scripts/release.sh",
26
28
  "release:check": "bash ./scripts/release-check.sh",
27
29
  "release:preflight": "pnpm cleanbuild && pnpm test && pnpm release:check -- --local",