@technomoron/agent-run 0.99.28 → 0.99.30

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 (43) hide show
  1. package/CHANGES +26 -0
  2. package/README.md +202 -26
  3. package/dist/agents/claude.js +93 -0
  4. package/dist/agents/codex.js +77 -0
  5. package/dist/agents/gemini.js +112 -0
  6. package/dist/agents/grok.js +73 -0
  7. package/dist/agents/registry.js +26 -0
  8. package/dist/agents/shared.js +17 -0
  9. package/dist/agents/types.js +4 -0
  10. package/dist/checks.js +4 -0
  11. package/dist/cli.js +45 -12
  12. package/dist/commands.js +72 -18
  13. package/dist/config/render-instructions.js +54 -0
  14. package/dist/config/render-mcp.js +88 -0
  15. package/dist/config/render-settings.js +35 -0
  16. package/dist/config/render-skills.js +51 -0
  17. package/dist/config-tree.js +249 -0
  18. package/dist/constants.js +5 -2
  19. package/dist/defaults.js +65 -8
  20. package/dist/manifest.js +39 -2
  21. package/dist/renderer.js +81 -227
  22. package/dist/runtime/environment.js +17 -0
  23. package/dist/runtime/postflight.js +40 -0
  24. package/dist/runtime/shared-state.js +44 -0
  25. package/dist/runtime/spawn-agent.js +7 -0
  26. package/dist/templates.js +12 -0
  27. package/examples/basic-config/README.md +2 -1
  28. package/examples/basic-config/agent-config/agent-run.defaults.jsonc +8 -2
  29. package/examples/basic-config/agent-config/global/tool-templates/AGENTS.md.njk +2 -0
  30. package/examples/basic-config/agent-config/global/tool-templates/CLAUDE.md.njk +1 -0
  31. package/examples/basic-config/agent-config/global/tool-templates/claude-settings.json.njk +2 -0
  32. package/examples/basic-config/agent-config/global/tool-templates/codex-config.toml.njk +2 -1
  33. package/examples/basic-config/agent-config/global/tool-templates/gemini-settings.json.njk +5 -0
  34. package/examples/basic-config/agent-config/global/tool-templates/grok-config.toml.njk +1 -0
  35. package/examples/basic-config/agent-config/starter/basic-project/agent-run.jsonc +20 -0
  36. package/examples/basic-config/agent-config/starter/basic-project/notes/memory/README.md +8 -0
  37. package/examples/basic-config/agent-config/starter/basic-project/overrides/claude-settings.json.njk +2 -0
  38. package/examples/basic-config/agent-config/starter/basic-project/overrides/codex-config.toml.njk +2 -1
  39. package/ops/systemd/ai-tools-update.service +1 -1
  40. package/package.json +1 -1
  41. package/scripts/install-systemd-jobs.sh +15 -5
  42. package/scripts/update-ai-tools.sh +27 -16
  43. package/dist/tools.js +0 -119
@@ -3,6 +3,7 @@
3
3
  "AGENT_DIR": {{ agentDir | dump }},
4
4
  "AGENT_PROFILE_DIR": {{ profileDir | dump }},
5
5
  "AGENT_RUN_PROJECT_ROOT": {{ projectRoot | dump }},
6
+ "AGENT_PROJECT_MEMORY_DIR": {{ paths.projectMemoryDir | dump }},
6
7
  "AGENT_GLOBAL_MEMORY_DIR": {{ paths.globalMemoryDir | dump }},
7
8
  "STARTER_PROFILE": {{ profile | dump }},
8
9
  "STARTER_OVERRIDE": "true"
@@ -16,6 +17,7 @@
16
17
  "AGENT_DIR": {{ agentDir | dump }},
17
18
  "AGENT_PROFILE_DIR": {{ profileDir | dump }},
18
19
  "AGENT_RUN_PROJECT_ROOT": {{ projectRoot | dump }},
20
+ "AGENT_PROJECT_MEMORY_DIR": {{ paths.projectMemoryDir | dump }},
19
21
  "AGENT_GLOBAL_MEMORY_DIR": {{ paths.globalMemoryDir | dump }},
20
22
  "STARTER_PROFILE": {{ profile | dump }},
21
23
  "STARTER_OVERRIDE": "true"
@@ -7,6 +7,7 @@ sandbox_mode = "workspace-write"
7
7
  writable_roots = [
8
8
  {{ projectRoot | dump }},
9
9
  {{ paths.reviewDir | dump }},
10
- {{ paths.memoriesDir | dump }}
10
+ {{ paths.memoriesDir | dump }},
11
+ {{ paths.projectMemoryDir | dump }}
11
12
  ]
12
13
  network_access = false
@@ -13,4 +13,4 @@ Environment=XDG_CONFIG_HOME=/root/.config
13
13
  Environment=NPM_CONFIG_PREFIX=/usr/local
14
14
  Environment=PNPM_HOME=/usr/local
15
15
  Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
16
- ExecStart=/usr/local/lib/agent-run/update-ai-tools.sh
16
+ ExecStart=/usr/local/libexec/agent-run/update-ai-tools
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@technomoron/agent-run",
3
- "version": "0.99.28",
3
+ "version": "0.99.30",
4
4
  "packageManager": "pnpm@10.28.1",
5
5
  "bin": {
6
6
  "agent-run": "dist/agent-run.js"
@@ -19,10 +19,20 @@ USAGE
19
19
  }
20
20
 
21
21
  ROOT="$(cd "$(dirname "$0")/.." && pwd)"
22
- INSTALL_LIB_DIR="${INSTALL_LIB_DIR:-/usr/local/lib/agent-run}"
22
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
23
+ INSTALL_LIBEXEC_DIR="${INSTALL_LIBEXEC_DIR:-${INSTALL_LIB_DIR:-/usr/local/libexec/agent-run}}"
23
24
  SYSTEMD_DIR="${SYSTEMD_DIR:-/etc/systemd/system}"
24
25
  ORIGINAL_ARGS=("$@")
25
26
 
27
+ UPDATE_SCRIPT="$ROOT/scripts/update-ai-tools.sh"
28
+ SERVICE_FILE="$ROOT/ops/systemd/ai-tools-update.service"
29
+ TIMER_FILE="$ROOT/ops/systemd/ai-tools-update.timer"
30
+ if [ ! -f "$UPDATE_SCRIPT" ]; then
31
+ UPDATE_SCRIPT="$SCRIPT_DIR/update-ai-tools.sh"
32
+ SERVICE_FILE="$SCRIPT_DIR/ai-tools-update.service"
33
+ TIMER_FILE="$SCRIPT_DIR/ai-tools-update.timer"
34
+ fi
35
+
26
36
  INSTALL_AI_TOOLS=0
27
37
  DRY_RUN=0
28
38
 
@@ -71,10 +81,10 @@ run() {
71
81
  "$@"
72
82
  }
73
83
 
74
- run install -d -m 0755 "$INSTALL_LIB_DIR" "$SYSTEMD_DIR"
75
- run install -m 0755 "$ROOT/scripts/update-ai-tools.sh" "$INSTALL_LIB_DIR/update-ai-tools.sh"
76
- run install -m 0644 "$ROOT/ops/systemd/ai-tools-update.service" "$SYSTEMD_DIR/ai-tools-update.service"
77
- run install -m 0644 "$ROOT/ops/systemd/ai-tools-update.timer" "$SYSTEMD_DIR/ai-tools-update.timer"
84
+ run install -d -m 0755 "$INSTALL_LIBEXEC_DIR" "$SYSTEMD_DIR"
85
+ run install -m 0755 "$UPDATE_SCRIPT" "$INSTALL_LIBEXEC_DIR/update-ai-tools"
86
+ run install -m 0644 "$SERVICE_FILE" "$SYSTEMD_DIR/ai-tools-update.service"
87
+ run install -m 0644 "$TIMER_FILE" "$SYSTEMD_DIR/ai-tools-update.timer"
78
88
 
79
89
  if [ "$INSTALL_AI_TOOLS" -eq 1 ]; then
80
90
  run systemctl daemon-reload
@@ -1,38 +1,49 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
- export HOME="${HOME:-/root}"
5
- export NPM_CONFIG_PREFIX="${NPM_CONFIG_PREFIX:-/usr/local}"
6
- export PNPM_HOME="${PNPM_HOME:-/usr/local}"
7
- export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH:-}"
4
+ export HOME=/root
5
+ export NPM_CONFIG_PREFIX=/usr/local
6
+ export PNPM_HOME=/usr/local
7
+ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
8
8
 
9
- NPM_BIN="${AI_TOOLS_NPM_BIN:-/usr/local/bin/npm}"
10
- APT_GET_BIN="${AI_TOOLS_APT_GET_BIN:-/usr/bin/apt-get}"
9
+ NPM_BIN=/usr/local/bin/npm
10
+ NODE_BIN=/usr/local/bin/node
11
+ PNPM_BIN=/usr/local/bin/pnpm
12
+ APT_GET_BIN=/usr/bin/apt-get
11
13
 
12
- AI_TOOLS_NPM_PACKAGES="${AI_TOOLS_NPM_PACKAGES:-npm@latest pnpm@latest corepack@latest fallow@latest ripgrep@latest pm2@latest tsx@latest typescript@latest @openai/codex@latest @anthropic-ai/claude-code@latest @technomoron/agent-run@latest}"
13
- AI_TOOLS_PNPM_PACKAGE="${AI_TOOLS_PNPM_PACKAGE:-pnpm@latest}"
14
14
  AI_TOOLS_APT_PACKAGES="${AI_TOOLS_APT_PACKAGES:-gh}"
15
15
 
16
+ packages=(
17
+ npm@latest corepack@latest fallow@latest ripgrep@latest
18
+ pm2@latest tsx@latest typescript@latest @openai/codex@latest
19
+ @anthropic-ai/claude-code@latest @google/gemini-cli@latest
20
+ @xai-official/grok@latest @technomoron/agent-run@latest
21
+ )
22
+
16
23
  if [ "$(id -u)" -ne 0 ]; then
17
24
  echo "update-ai-tools.sh must run as root" >&2
18
25
  exit 1
19
26
  fi
20
27
 
21
- if [ -n "$AI_TOOLS_NPM_PACKAGES" ]; then
22
- read -r -a npm_packages <<<"$AI_TOOLS_NPM_PACKAGES"
23
- "$NPM_BIN" install -g --force "${npm_packages[@]}"
28
+ if [ "$("$NPM_BIN" prefix -g)" != /usr/local ] || [ "$("$NPM_BIN" root -g)" != /usr/local/lib/node_modules ]; then
29
+ echo "npm global tooling must use /usr/local" >&2
30
+ exit 1
24
31
  fi
25
32
 
33
+ "$NPM_BIN" install -g --force "${packages[@]}"
34
+
26
35
  # corepack and pnpm both own the pnpm/pnpx shims; install pnpm last so npm's
27
36
  # current pnpm package remains the command users execute.
28
- if [ -n "$AI_TOOLS_PNPM_PACKAGE" ]; then
29
- read -r -a pnpm_packages <<<"$AI_TOOLS_PNPM_PACKAGE"
30
- "$NPM_BIN" install -g --force "${pnpm_packages[@]}"
31
- fi
37
+ "$NPM_BIN" install -g --force pnpm@latest
38
+
39
+ install -d -o root -g root -m 0755 /usr/local/share/pnpm/global /usr/local/share/pnpm/store /usr/local/bin
40
+ "$PNPM_BIN" config set --global global-dir /usr/local/share/pnpm/global
41
+ "$PNPM_BIN" config set --global global-bin-dir /usr/local/bin
42
+ "$PNPM_BIN" config set --global store-dir /usr/local/share/pnpm/store
32
43
 
33
44
  CLAUDE_INSTALL="$("$NPM_BIN" root -g)/@anthropic-ai/claude-code/install.cjs"
34
45
  if [ -f "$CLAUDE_INSTALL" ]; then
35
- /usr/local/bin/node "$CLAUDE_INSTALL"
46
+ "$NODE_BIN" "$CLAUDE_INSTALL"
36
47
  fi
37
48
 
38
49
  if [ -n "$AI_TOOLS_APT_PACKAGES" ] && command -v "$APT_GET_BIN" >/dev/null 2>&1; then
package/dist/tools.js DELETED
@@ -1,119 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runCodex = runCodex;
4
- exports.runClaude = runClaude;
5
- exports.getDangerArgs = getDangerArgs;
6
- exports.getPermissionArgs = getPermissionArgs;
7
- const fs = require("fs");
8
- const path = require("path");
9
- const process_1 = require("./process");
10
- const project_1 = require("./project");
11
- function runCodex(realBinary, permissionArgs, context, args, wrapperArgs) {
12
- const liveDir = context.paths.liveDir;
13
- const codexHomeDir = context.paths.codexHomeDir;
14
- const projectRoot = context.projectRoot;
15
- if (!fs.existsSync(path.join(codexHomeDir, 'AGENTS.md'))) {
16
- failMissingConfig('codex', context.profileDir);
17
- }
18
- const realPath = process.env.AGENT_RUN_REAL_PATH ?? process.env.PATH ?? '';
19
- fs.mkdirSync(codexHomeDir, { recursive: true });
20
- const env = {
21
- ...process.env,
22
- CODEX_HOME: codexHomeDir,
23
- AGENT_DIR: liveDir,
24
- AGENT_PROFILE_DIR: context.profileDir,
25
- AGENT_RUN_PROJECT_ROOT: projectRoot,
26
- AGENT_RUN_REAL_PATH: realPath,
27
- PATH: `${path.join(liveDir, 'bin')}${path.delimiter}${realPath}`
28
- };
29
- const runtimeArgs = wrapperArgs.sandboxMode === 'danger' ? getDangerArgs('codex') : ['-a', 'on-request', '-s', 'workspace-write'];
30
- (0, process_1.execCommand)(realBinary, [
31
- ...permissionArgs,
32
- ...runtimeArgs,
33
- '-C',
34
- projectRoot,
35
- ...(wrapperArgs.sandboxMode !== 'danger' && wrapperArgs.codexNetwork
36
- ? ['--config', 'sandbox_workspace_write.network_access=true']
37
- : []),
38
- ...args
39
- ], env, codexHomeDir, (code) => postflightProjectCheck(context, wrapperArgs.local, code));
40
- }
41
- function runClaude(realBinary, permissionArgs, context, args, wrapperArgs) {
42
- const liveDir = context.paths.liveDir;
43
- const claudePath = path.join(liveDir, 'CLAUDE.md');
44
- if (!fs.existsSync(claudePath)) {
45
- failMissingConfig('claude', context.profileDir);
46
- }
47
- const claudeConfigDir = path.join(liveDir, '.claude');
48
- const realPath = process.env.AGENT_RUN_REAL_PATH ?? process.env.PATH ?? '';
49
- const env = {
50
- ...process.env,
51
- AGENT_DIR: liveDir,
52
- AGENT_PROFILE_DIR: context.profileDir,
53
- AGENT_RUN_PROJECT_ROOT: context.projectRoot,
54
- AGENT_RUN_REAL_PATH: realPath,
55
- PATH: `${path.join(liveDir, 'bin')}${path.delimiter}${realPath}`
56
- };
57
- const runtimeArgs = wrapperArgs.sandboxMode === 'danger' ? getDangerArgs('claude') : permissionArgs;
58
- (0, process_1.execCommand)(realBinary, [
59
- ...runtimeArgs,
60
- '--append-system-prompt-file',
61
- claudePath,
62
- '--settings',
63
- path.join(claudeConfigDir, 'agent-run-settings.json'),
64
- '--plugin-dir',
65
- claudeConfigDir,
66
- ...args
67
- ], env, context.projectRoot, (code) => postflightProjectCheck(context, wrapperArgs.local, code));
68
- }
69
- function postflightProjectCheck(context, allowLocal, code) {
70
- if (!context.guardrails.forbidRepoAiFiles) {
71
- return code;
72
- }
73
- if (!allowLocal) {
74
- removeClaudeLocalSettings(context.projectRoot);
75
- }
76
- const localAiFiles = (0, project_1.findLocalAiFiles)(context.projectRoot, context.profileDir);
77
- if (localAiFiles.length === 0) {
78
- return code;
79
- }
80
- (0, project_1.warnForLocalAiFiles)(null, context.projectRoot, localAiFiles);
81
- return allowLocal ? code : 1;
82
- }
83
- function removeClaudeLocalSettings(projectRoot) {
84
- const claudeDir = path.join(projectRoot, '.claude');
85
- const localSettingsPath = path.join(claudeDir, 'settings.local.json');
86
- if (!fs.existsSync(localSettingsPath)) {
87
- return;
88
- }
89
- fs.rmSync(localSettingsPath);
90
- try {
91
- fs.rmdirSync(claudeDir);
92
- }
93
- catch (error) {
94
- if (!isDirectoryNotEmptyError(error)) {
95
- throw error;
96
- }
97
- }
98
- process.stderr.write(`agent-run: removed Claude's project-local settings: ${localSettingsPath}\n`);
99
- }
100
- function isDirectoryNotEmptyError(error) {
101
- return error instanceof Error && 'code' in error && error.code === 'ENOTEMPTY';
102
- }
103
- function failMissingConfig(tool, agentDir) {
104
- process.stderr.write(`agent-run: no ${tool} config found for this project: ${agentDir}\n`);
105
- process.stderr.write(`agent-run: run \`agent-run ${tool} --none\` to bypass agent setup, or \`agent-run ${tool} --create\` to create profile files.\n`);
106
- process.exit(1);
107
- }
108
- function getDangerArgs(tool) {
109
- return tool === 'codex' ? ['-a', 'never', '-s', 'danger-full-access'] : ['--dangerously-skip-permissions'];
110
- }
111
- function getPermissionArgs(tool) {
112
- if (process.env.AGENT_WRAPPER_FORCE_PERMISSIVE !== '1') {
113
- return [];
114
- }
115
- if (tool === 'claude' && typeof process.getuid === 'function' && process.getuid() !== 0) {
116
- return ['--permission-mode', 'bypassPermissions'];
117
- }
118
- return [];
119
- }