@meandmyagents/agent-runner 0.1.0 → 0.1.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/README.md CHANGED
@@ -13,6 +13,14 @@ process as `MAA_API_KEY`, so one Mac can run several agent profiles without
13
13
  sharing identity. The launched agent uses MCP to start, complete, and drain the
14
14
  remaining actionable cards.
15
15
 
16
+ On macOS, `--launcher codex` will also look for the bundled Codex app executable
17
+ at `/Applications/Codex.app/Contents/Resources/codex` when `codex` is not on
18
+ `PATH`. If your launcher lives somewhere else, pass it explicitly:
19
+
20
+ ```bash
21
+ meandmyagents-runner watch --key maa_live_YOUR_AGENT_KEY --launcher codex --command /Applications/Codex.app/Contents/Resources/codex
22
+ ```
23
+
16
24
  ```bash
17
25
  meandmyagents-runner watch --key maa_live_YOUR_AGENT_KEY --launcher claude --once
18
26
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meandmyagents/agent-runner",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Local visible-session task runner for Me And My Agents.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/runner.js CHANGED
@@ -1,15 +1,18 @@
1
1
  import { spawn } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { delimiter, join } from "node:path";
2
4
 
3
5
  export const defaultApiUrl = "https://meandmyagents.com/api";
4
6
  const supportedLaunchers = new Set(["codex", "claude"]);
5
7
 
6
8
  export function parseRunnerArgs(argv = process.argv.slice(2)) {
7
9
  const options = {
8
- command: argv[0] ?? "help",
10
+ command: argv[0] === "--help" || argv[0] === "-h" ? "help" : argv[0] ?? "help",
9
11
  apiUrl: defaultApiUrl,
10
12
  intervalSeconds: 10,
11
13
  key: "",
12
14
  launcher: "codex",
15
+ launcherCommand: "",
13
16
  once: false
14
17
  };
15
18
 
@@ -34,6 +37,12 @@ export function parseRunnerArgs(argv = process.argv.slice(2)) {
34
37
  continue;
35
38
  }
36
39
 
40
+ if (arg === "--command" || arg === "-c") {
41
+ options.launcherCommand = argv[index + 1] ?? "";
42
+ index += 1;
43
+ continue;
44
+ }
45
+
37
46
  if (arg === "--interval") {
38
47
  options.intervalSeconds = Number(argv[index + 1] ?? "10");
39
48
  index += 1;
@@ -84,13 +93,20 @@ export function buildAgentPrompt({
84
93
  ].join("\n");
85
94
  }
86
95
 
87
- export function buildLaunchCommand({ launcher, prompt, cwd, apiKey, apiUrl }) {
96
+ export function buildLaunchCommand({
97
+ launcher,
98
+ launcherCommand,
99
+ prompt,
100
+ cwd,
101
+ apiKey,
102
+ apiUrl
103
+ }) {
88
104
  if (!supportedLaunchers.has(launcher)) {
89
105
  throw new Error(`Unsupported launcher: ${launcher}`);
90
106
  }
91
107
 
92
108
  return {
93
- command: launcher,
109
+ command: launcherCommand || launcher,
94
110
  args: [prompt],
95
111
  cwd,
96
112
  env: {
@@ -175,6 +191,10 @@ async function launchEvent(options, event) {
175
191
  });
176
192
  const launch = buildLaunchCommand({
177
193
  launcher: options.launcher,
194
+ launcherCommand: resolveLauncherCommand({
195
+ launcher: options.launcher,
196
+ launcherCommand: options.launcherCommand
197
+ }),
178
198
  prompt,
179
199
  cwd,
180
200
  apiKey: options.key,
@@ -202,6 +222,60 @@ async function launchEvent(options, event) {
202
222
  });
203
223
  }
204
224
 
225
+ export function resolveLauncherCommand({
226
+ launcher,
227
+ launcherCommand = "",
228
+ pathEnv = process.env.PATH ?? "",
229
+ platform = process.platform,
230
+ homeDir = process.env.HOME || process.env.USERPROFILE || "",
231
+ exists = existsSync
232
+ }) {
233
+ if (launcherCommand) return launcherCommand;
234
+ if (!supportedLaunchers.has(launcher)) {
235
+ throw new Error(`Unsupported launcher: ${launcher}`);
236
+ }
237
+
238
+ if (isCommandOnPath(launcher, { pathEnv, platform, exists })) return launcher;
239
+
240
+ const knownPath = knownLauncherPaths(launcher, platform, homeDir).find((path) =>
241
+ exists(path)
242
+ );
243
+ return knownPath ?? launcher;
244
+ }
245
+
246
+ function isCommandOnPath(command, { pathEnv, platform, exists }) {
247
+ const executableNames =
248
+ platform === "win32" ? [command, `${command}.cmd`, `${command}.exe`] : [command];
249
+
250
+ return pathEnv
251
+ .split(delimiter)
252
+ .filter(Boolean)
253
+ .some((pathDirectory) =>
254
+ executableNames.some((executableName) => exists(join(pathDirectory, executableName)))
255
+ );
256
+ }
257
+
258
+ function knownLauncherPaths(launcher, platform, homeDir) {
259
+ if (platform === "darwin") {
260
+ const commonBinPaths = [
261
+ homeDir ? join(homeDir, ".local/bin", launcher) : "",
262
+ join("/opt/homebrew/bin", launcher),
263
+ join("/usr/local/bin", launcher)
264
+ ].filter(Boolean);
265
+
266
+ if (launcher === "codex") {
267
+ return [
268
+ ...commonBinPaths,
269
+ "/Applications/Codex.app/Contents/Resources/codex"
270
+ ];
271
+ }
272
+
273
+ return commonBinPaths;
274
+ }
275
+
276
+ return homeDir ? [join(homeDir, ".local/bin", launcher)] : [];
277
+ }
278
+
205
279
  function normalizeApiUrl(value) {
206
280
  return (value || defaultApiUrl).replace(/\/$/, "").replace(/\/mcp$/, "");
207
281
  }
@@ -232,6 +306,7 @@ Options:
232
306
  --key, -k Required agent-bound API key.
233
307
  --api-url, -u API base URL. Defaults to ${defaultApiUrl}.
234
308
  --launcher, -l Visible CLI launcher: codex or claude.
309
+ --command, -c Optional explicit executable path, e.g. /Applications/Codex.app/Contents/Resources/codex.
235
310
  --interval Poll interval in seconds. Defaults to 10.
236
311
  --once Check once, launch at most one visible session, then exit.
237
312
  `;