@rlarua/agentrunner 0.0.3

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 (68) hide show
  1. package/dist/api-client.d.ts +18 -0
  2. package/dist/api-client.js +133 -0
  3. package/dist/api-client.js.map +1 -0
  4. package/dist/autostart.d.ts +15 -0
  5. package/dist/autostart.js +280 -0
  6. package/dist/autostart.js.map +1 -0
  7. package/dist/commands/init.d.ts +1 -0
  8. package/dist/commands/init.js +56 -0
  9. package/dist/commands/init.js.map +1 -0
  10. package/dist/commands/start.d.ts +1 -0
  11. package/dist/commands/start.js +21 -0
  12. package/dist/commands/start.js.map +1 -0
  13. package/dist/commands/status.d.ts +1 -0
  14. package/dist/commands/status.js +20 -0
  15. package/dist/commands/status.js.map +1 -0
  16. package/dist/commands/stop.d.ts +1 -0
  17. package/dist/commands/stop.js +21 -0
  18. package/dist/commands/stop.js.map +1 -0
  19. package/dist/commands/uninstall.d.ts +1 -0
  20. package/dist/commands/uninstall.js +21 -0
  21. package/dist/commands/uninstall.js.map +1 -0
  22. package/dist/config.d.ts +6 -0
  23. package/dist/config.js +66 -0
  24. package/dist/config.js.map +1 -0
  25. package/dist/handlers/trigger-handler.d.ts +3 -0
  26. package/dist/handlers/trigger-handler.js +145 -0
  27. package/dist/handlers/trigger-handler.js.map +1 -0
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.js +64 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/logger.d.ts +5 -0
  32. package/dist/logger.js +25 -0
  33. package/dist/logger.js.map +1 -0
  34. package/dist/pid.d.ts +8 -0
  35. package/dist/pid.js +48 -0
  36. package/dist/pid.js.map +1 -0
  37. package/dist/poller.d.ts +4 -0
  38. package/dist/poller.js +62 -0
  39. package/dist/poller.js.map +1 -0
  40. package/dist/runners/claude-code.d.ts +4 -0
  41. package/dist/runners/claude-code.js +166 -0
  42. package/dist/runners/claude-code.js.map +1 -0
  43. package/dist/runners/codex.d.ts +4 -0
  44. package/dist/runners/codex.js +166 -0
  45. package/dist/runners/codex.js.map +1 -0
  46. package/dist/runners/gemini.d.ts +4 -0
  47. package/dist/runners/gemini.js +166 -0
  48. package/dist/runners/gemini.js.map +1 -0
  49. package/dist/runners/index.d.ts +2 -0
  50. package/dist/runners/index.js +25 -0
  51. package/dist/runners/index.js.map +1 -0
  52. package/dist/runners/log-reporter.d.ts +17 -0
  53. package/dist/runners/log-reporter.js +107 -0
  54. package/dist/runners/log-reporter.js.map +1 -0
  55. package/dist/runners/opencode.d.ts +6 -0
  56. package/dist/runners/opencode.js +170 -0
  57. package/dist/runners/opencode.js.map +1 -0
  58. package/dist/runners/types.d.ts +19 -0
  59. package/dist/runners/types.js +2 -0
  60. package/dist/runners/types.js.map +1 -0
  61. package/dist/types.d.ts +52 -0
  62. package/dist/types.js +2 -0
  63. package/dist/types.js.map +1 -0
  64. package/dist/utils/runner-history.d.ts +6 -0
  65. package/dist/utils/runner-history.js +13 -0
  66. package/dist/utils/runner-history.js.map +1 -0
  67. package/package.json +38 -0
  68. package/readme.md +160 -0
@@ -0,0 +1,107 @@
1
+ import { logger } from "../logger.js";
2
+ const MAX_BATCH_SIZE = 50;
3
+ const MAX_BUFFERED_LOGS = 500;
4
+ const MAX_MESSAGE_LENGTH = 2000;
5
+ const DEFAULT_FLUSH_INTERVAL_MS = 2000;
6
+ const ANSI_ESCAPE_PATTERN = /\u001B\[[0-9;?]*[ -/]*[@-~]/g;
7
+ const CONTROL_CHAR_PATTERN = /[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/g;
8
+ const normalizeMessage = (message) => {
9
+ const withoutAnsi = message.replace(ANSI_ESCAPE_PATTERN, "");
10
+ const normalizedNewline = withoutAnsi.replace(/\r\n?/g, "\n");
11
+ const withoutControlChars = normalizedNewline.replace(CONTROL_CHAR_PATTERN, "");
12
+ const squashed = withoutControlChars.replace(/\n{3,}/g, "\n\n");
13
+ const trimmed = squashed.trim();
14
+ if (trimmed.length <= MAX_MESSAGE_LENGTH) {
15
+ return trimmed;
16
+ }
17
+ return trimmed.slice(0, MAX_MESSAGE_LENGTH);
18
+ };
19
+ export class TriggerLogReporter {
20
+ client;
21
+ triggerId;
22
+ flushIntervalMs;
23
+ queue = [];
24
+ flushTimer = null;
25
+ flushInFlight = false;
26
+ droppedCount = 0;
27
+ constructor(client, triggerId, flushIntervalMs = DEFAULT_FLUSH_INTERVAL_MS) {
28
+ this.client = client;
29
+ this.triggerId = triggerId;
30
+ this.flushIntervalMs = flushIntervalMs;
31
+ }
32
+ start() {
33
+ if (this.flushTimer) {
34
+ return;
35
+ }
36
+ this.flushTimer = setInterval(() => {
37
+ void this.flush({ heartbeat: true });
38
+ }, this.flushIntervalMs);
39
+ }
40
+ append(level, message) {
41
+ const normalized = normalizeMessage(message);
42
+ if (normalized.length === 0) {
43
+ return;
44
+ }
45
+ if (this.queue.length >= MAX_BUFFERED_LOGS) {
46
+ this.queue.shift();
47
+ this.droppedCount += 1;
48
+ }
49
+ this.queue.push({ level, message: normalized });
50
+ }
51
+ async stop() {
52
+ if (this.flushTimer) {
53
+ clearInterval(this.flushTimer);
54
+ this.flushTimer = null;
55
+ }
56
+ await this.flush({ heartbeat: true, drain: true });
57
+ }
58
+ async flush(opts) {
59
+ if (this.flushInFlight) {
60
+ return;
61
+ }
62
+ this.flushInFlight = true;
63
+ try {
64
+ if (this.droppedCount > 0) {
65
+ const droppedMessage = `Dropped ${this.droppedCount} log line(s) due to buffer limit (${MAX_BUFFERED_LOGS}).`;
66
+ this.queue.unshift({ level: "WARN", message: droppedMessage });
67
+ this.droppedCount = 0;
68
+ }
69
+ if (opts.drain) {
70
+ while (this.queue.length > 0) {
71
+ const batch = this.queue.splice(0, MAX_BATCH_SIZE);
72
+ await this.send({ logs: batch, heartbeat: opts.heartbeat });
73
+ opts.heartbeat = false;
74
+ }
75
+ if (opts.heartbeat) {
76
+ await this.send({ heartbeat: true });
77
+ }
78
+ return;
79
+ }
80
+ const batch = this.queue.splice(0, MAX_BATCH_SIZE);
81
+ if (batch.length === 0 && !opts.heartbeat) {
82
+ return;
83
+ }
84
+ await this.send({ logs: batch.length > 0 ? batch : undefined, heartbeat: opts.heartbeat });
85
+ }
86
+ finally {
87
+ this.flushInFlight = false;
88
+ }
89
+ }
90
+ async send(payload) {
91
+ if (!payload.logs && !payload.heartbeat) {
92
+ return;
93
+ }
94
+ try {
95
+ await this.client.appendTriggerLogs(this.triggerId, payload);
96
+ }
97
+ catch (error) {
98
+ logger.warn("Failed to report trigger logs", {
99
+ triggerId: this.triggerId,
100
+ error: error instanceof Error ? error.message : String(error),
101
+ payloadSize: payload.logs?.length ?? 0,
102
+ heartbeat: payload.heartbeat === true
103
+ });
104
+ }
105
+ }
106
+ }
107
+ //# sourceMappingURL=log-reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-reporter.js","sourceRoot":"","sources":["../../src/runners/log-reporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Runner, RunnerOptions, RunResult } from "./types.js";
2
+ export declare class OpenCodeRunner implements Runner {
3
+ private readonly runnerCmd;
4
+ constructor(runnerCmd?: string);
5
+ run(opts: RunnerOptions): Promise<RunResult>;
6
+ }
@@ -0,0 +1,170 @@
1
+ import { createWriteStream } from "node:fs";
2
+ import { mkdir } from "node:fs/promises";
3
+ import { spawn } from "node:child_process";
4
+ import { dirname, join } from "node:path";
5
+ import { logger } from "../logger.js";
6
+ const FORCE_KILL_AFTER_MS = 10_000;
7
+ const PROMPT_PREVIEW_MAX = 500;
8
+ const OUTPUT_PREVIEW_MAX = 400;
9
+ const toPromptPreview = (prompt) => {
10
+ if (prompt.length <= PROMPT_PREVIEW_MAX) {
11
+ return prompt;
12
+ }
13
+ return `${prompt.slice(0, PROMPT_PREVIEW_MAX)}...`;
14
+ };
15
+ const toOutputPreview = (chunk) => {
16
+ const text = (typeof chunk === "string" ? chunk : String(chunk)).trim();
17
+ if (text.length <= OUTPUT_PREVIEW_MAX) {
18
+ return text;
19
+ }
20
+ return `${text.slice(0, OUTPUT_PREVIEW_MAX)}...`;
21
+ };
22
+ export class OpenCodeRunner {
23
+ runnerCmd;
24
+ constructor(runnerCmd = "opencode") {
25
+ this.runnerCmd = runnerCmd;
26
+ }
27
+ async run(opts) {
28
+ if (!opts.authPath || opts.authPath.trim().length === 0) {
29
+ logger.error("authPath is missing for trigger");
30
+ return {
31
+ exitCode: 1,
32
+ errorMessage: "authPath is missing for trigger"
33
+ };
34
+ }
35
+ const cwd = opts.authPath;
36
+ const logPath = join(cwd, ".agentteams", "runner-log", `${opts.triggerId}.log`);
37
+ await mkdir(dirname(logPath), { recursive: true });
38
+ logger.info("Runner prompt", {
39
+ triggerId: opts.triggerId,
40
+ promptLength: opts.prompt.length,
41
+ promptPreview: toPromptPreview(opts.prompt)
42
+ });
43
+ const child = spawn(this.runnerCmd, ["run", opts.prompt], {
44
+ cwd,
45
+ detached: true,
46
+ stdio: ["ignore", "pipe", "pipe"],
47
+ env: {
48
+ ...process.env,
49
+ AGENTTEAMS_API_KEY: opts.apiKey,
50
+ AGENTTEAMS_API_URL: opts.apiUrl,
51
+ AGENTTEAMS_AGENT_NAME: opts.agentConfigId
52
+ }
53
+ });
54
+ const logStream = createWriteStream(logPath, { flags: "a" });
55
+ child.stdout?.pipe(logStream);
56
+ child.stderr?.pipe(logStream);
57
+ let lastOutput = "";
58
+ let lastErrorOutput = "";
59
+ child.stdout?.on("data", (chunk) => {
60
+ const output = toOutputPreview(Buffer.isBuffer(chunk) ? chunk.toString("utf8") : chunk);
61
+ if (output.length > 0) {
62
+ lastOutput = output;
63
+ opts.onStdoutChunk?.(output);
64
+ logger.info("Runner stdout", {
65
+ triggerId: opts.triggerId,
66
+ pid: child.pid,
67
+ output
68
+ });
69
+ }
70
+ });
71
+ child.stderr?.on("data", (chunk) => {
72
+ const output = toOutputPreview(Buffer.isBuffer(chunk) ? chunk.toString("utf8") : chunk);
73
+ if (output.length > 0) {
74
+ lastOutput = output;
75
+ lastErrorOutput = output;
76
+ opts.onStderrChunk?.(output);
77
+ logger.warn("Runner stderr", {
78
+ triggerId: opts.triggerId,
79
+ pid: child.pid,
80
+ output
81
+ });
82
+ }
83
+ });
84
+ logger.info("Runner started", {
85
+ triggerId: opts.triggerId,
86
+ cwd,
87
+ logPath,
88
+ pid: child.pid
89
+ });
90
+ return await new Promise((resolve) => {
91
+ let finished = false;
92
+ let timedOut = false;
93
+ const cleanup = () => {
94
+ if (finished) {
95
+ return;
96
+ }
97
+ finished = true;
98
+ logStream.end();
99
+ };
100
+ const timeoutId = setTimeout(() => {
101
+ timedOut = true;
102
+ if (!child.pid) {
103
+ return;
104
+ }
105
+ logger.warn("Runner timeout reached; sending SIGTERM", {
106
+ triggerId: opts.triggerId,
107
+ pid: child.pid,
108
+ timeoutMs: opts.timeoutMs
109
+ });
110
+ try {
111
+ process.kill(-child.pid, "SIGTERM");
112
+ }
113
+ catch {
114
+ // ignore
115
+ }
116
+ setTimeout(() => {
117
+ if (!finished && child.pid) {
118
+ logger.warn("Runner still alive after SIGTERM; sending SIGKILL", {
119
+ triggerId: opts.triggerId,
120
+ pid: child.pid
121
+ });
122
+ try {
123
+ process.kill(-child.pid, "SIGKILL");
124
+ }
125
+ catch {
126
+ // ignore
127
+ }
128
+ }
129
+ }, FORCE_KILL_AFTER_MS);
130
+ }, opts.timeoutMs);
131
+ child.on("error", (error) => {
132
+ clearTimeout(timeoutId);
133
+ cleanup();
134
+ logger.error("Runner process launch failed", {
135
+ triggerId: opts.triggerId,
136
+ error: error.message
137
+ });
138
+ resolve({
139
+ exitCode: 1,
140
+ lastOutput,
141
+ errorMessage: error.message
142
+ });
143
+ });
144
+ child.on("close", (code) => {
145
+ clearTimeout(timeoutId);
146
+ cleanup();
147
+ logger.info("Runner process closed", {
148
+ triggerId: opts.triggerId,
149
+ pid: child.pid,
150
+ exitCode: code,
151
+ timedOut
152
+ });
153
+ if (timedOut) {
154
+ resolve({
155
+ exitCode: 1,
156
+ lastOutput,
157
+ errorMessage: `Runner timed out after ${opts.timeoutMs}ms`
158
+ });
159
+ return;
160
+ }
161
+ resolve({
162
+ exitCode: code ?? 1,
163
+ lastOutput,
164
+ errorMessage: code === 0 ? undefined : (lastErrorOutput || lastOutput || `Runner exited with code ${code ?? 1}`)
165
+ });
166
+ });
167
+ });
168
+ }
169
+ }
170
+ //# sourceMappingURL=opencode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../src/runners/opencode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export interface Runner {
2
+ run(opts: RunnerOptions): Promise<RunResult>;
3
+ }
4
+ export interface RunnerOptions {
5
+ triggerId: string;
6
+ prompt: string;
7
+ authPath: string | null;
8
+ apiKey: string;
9
+ apiUrl: string;
10
+ timeoutMs: number;
11
+ agentConfigId: string;
12
+ onStdoutChunk?: (chunk: string) => void;
13
+ onStderrChunk?: (chunk: string) => void;
14
+ }
15
+ export type RunResult = {
16
+ exitCode: number;
17
+ lastOutput?: string;
18
+ errorMessage?: string;
19
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/runners/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ export type RuntimeConfig = {
2
+ daemonToken: string;
3
+ apiUrl: string;
4
+ pollingIntervalMs: number;
5
+ timeoutMs: number;
6
+ runnerCmd: string;
7
+ };
8
+ export type DaemonConfigFile = {
9
+ daemonToken: string;
10
+ apiUrl: string;
11
+ };
12
+ export type DaemonInfo = {
13
+ id: string;
14
+ memberId: string;
15
+ label: string | null;
16
+ lastSeenAt: string | null;
17
+ createdAt: string;
18
+ updatedAt: string;
19
+ };
20
+ export type DaemonTrigger = {
21
+ id: string;
22
+ prompt: string | Record<string, unknown>;
23
+ runnerType: string;
24
+ status: string;
25
+ agentConfigId: string;
26
+ startedAt: string | null;
27
+ errorMessage: string | null;
28
+ historyMarkdown: string | null;
29
+ lastHeartbeatAt: string | null;
30
+ conversationId: string | null;
31
+ parentTriggerId: string | null;
32
+ createdByMemberId: string;
33
+ claimedByDaemonId: string | null;
34
+ createdAt: string;
35
+ updatedAt: string;
36
+ };
37
+ export type TriggerFinalStatus = "DONE" | "FAILED" | "REJECTED";
38
+ export type ClaimResult = {
39
+ ok: boolean;
40
+ conflict: boolean;
41
+ };
42
+ export type TriggerRuntime = {
43
+ triggerId: string;
44
+ agentConfigId: string;
45
+ authPath: string | null;
46
+ apiKey: string;
47
+ };
48
+ export type TriggerLogLevel = "INFO" | "WARN" | "ERROR";
49
+ export type TriggerLogInput = {
50
+ level: TriggerLogLevel;
51
+ message: string;
52
+ };
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ type RunnerHistoryPaths = {
2
+ currentHistoryPath: string | null;
3
+ parentHistoryPath: string | null;
4
+ };
5
+ export declare const resolveRunnerHistoryPaths: (authPath: string | null, triggerId: string, parentTriggerId: string | null) => RunnerHistoryPaths;
6
+ export {};
@@ -0,0 +1,13 @@
1
+ import { join } from "node:path";
2
+ const historyDirectory = (authPath) => join(authPath, ".agentteams", "runner-history");
3
+ const historyFilePath = (authPath, triggerId) => join(historyDirectory(authPath), `${triggerId}.md`);
4
+ export const resolveRunnerHistoryPaths = (authPath, triggerId, parentTriggerId) => {
5
+ if (!authPath) {
6
+ return { currentHistoryPath: null, parentHistoryPath: null };
7
+ }
8
+ return {
9
+ currentHistoryPath: historyFilePath(authPath, triggerId),
10
+ parentHistoryPath: parentTriggerId ? historyFilePath(authPath, parentTriggerId) : null
11
+ };
12
+ };
13
+ //# sourceMappingURL=runner-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner-history.js","sourceRoot":"","sources":["../../src/utils/runner-history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAOjC,MAAM,gBAAgB,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAE,gBAAgB,CAAC,CAAC;AAE/F,MAAM,eAAe,GAAG,CAAC,QAAgB,EAAE,SAAiB,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,GAAG,SAAS,KAAK,CAAC,CAAC;AAErH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,QAAuB,EACvB,SAAiB,EACjB,eAA8B,EACV,EAAE;IACtB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;IAC/D,CAAC;IAED,OAAO;QACL,kBAAkB,EAAE,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC;QACxD,iBAAiB,EAAE,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI;KACvF,CAAC;AACJ,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@rlarua/agentrunner",
3
+ "version": "0.0.3",
4
+ "description": "AgentRunner - Background runner that polls and executes AI agent tasks",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "agentrunner": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist/**/*",
12
+ "readme.md"
13
+ ],
14
+ "scripts": {
15
+ "build": "rm -rf dist && tsc",
16
+ "dev": "tsx watch src/index.ts",
17
+ "start": "node dist/index.js",
18
+ "init": "node dist/index.js init",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "homepage": "https://agentteams.run",
22
+ "engines": {
23
+ "node": ">=18"
24
+ },
25
+ "keywords": [
26
+ "agentteams",
27
+ "runner",
28
+ "ai-agent",
29
+ "automation"
30
+ ],
31
+ "license": "Apache-2.0",
32
+ "dependencies": {},
33
+ "devDependencies": {
34
+ "@types/node": "^24.3.0",
35
+ "tsx": "^4.20.5",
36
+ "typescript": "^5.9.2"
37
+ }
38
+ }
package/readme.md ADDED
@@ -0,0 +1,160 @@
1
+ # @rlarua/agentrunner
2
+
3
+ A background runner that polls and executes AI agent tasks from the AgentTeams platform.
4
+
5
+ ## Prerequisites
6
+
7
+ - Node.js `18` or later
8
+ - AgentTeams API server running
9
+ - A daemon token issued from the web UI (`x-daemon-token`)
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install -g @rlarua/agentrunner
15
+ ```
16
+
17
+ Verify the installation:
18
+
19
+ ```bash
20
+ agentrunner --help
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ### 1. Initialize
26
+
27
+ ```bash
28
+ agentrunner init --token <DAEMON_TOKEN>
29
+ ```
30
+
31
+ The `init` command:
32
+
33
+ 1. Saves the token to `~/.agentteams/daemon.json`
34
+ 2. Validates the token against the API server
35
+ 3. Registers an OS-level autostart service and starts the runner immediately
36
+ - **macOS**: `~/Library/LaunchAgents/run.agentteams.daemon.plist` (launchd)
37
+ - **Linux**: `~/.config/systemd/user/agentrunner.service` (systemd)
38
+ - **Windows**: `AgentRunner` (Task Scheduler)
39
+
40
+ ### Options
41
+
42
+ - `--token <token>` — **Required**. Daemon token issued from the web UI
43
+ - `--no-autostart` — Optional. Skip autostart registration (manual start only)
44
+
45
+ Examples:
46
+
47
+ ```bash
48
+ # Standard setup (with autostart)
49
+ agentrunner init --token daemon_xxxxx
50
+
51
+ # Token-only setup (no autostart)
52
+ agentrunner init --token daemon_xxxxx --no-autostart
53
+ ```
54
+
55
+ ### 2. Start (`start`)
56
+
57
+ ```bash
58
+ agentrunner start
59
+ ```
60
+
61
+ Running without a subcommand defaults to `start`:
62
+
63
+ ```bash
64
+ agentrunner
65
+ ```
66
+
67
+ > If autostart was registered via `init`, you do not need to run `start` manually.
68
+ > The OS will start the runner automatically on login/boot.
69
+
70
+ ### 3. Check Status (`status`)
71
+
72
+ ```bash
73
+ agentrunner status
74
+ ```
75
+
76
+ Shows whether the runner process is active and whether autostart is registered.
77
+
78
+ Example output:
79
+
80
+ ```
81
+ [...] INFO Daemon is running { pid: 12345 }
82
+ [...] INFO Autostart is enabled { platform: 'launchd' }
83
+ ```
84
+
85
+ ### 4. Stop (`stop`)
86
+
87
+ ```bash
88
+ agentrunner stop
89
+ ```
90
+
91
+ Sends SIGTERM to the running process for a graceful shutdown.
92
+
93
+ > If autostart is registered, the OS may restart the runner automatically.
94
+ > Use `uninstall` to stop completely.
95
+
96
+ ### 5. Uninstall (`uninstall`)
97
+
98
+ ```bash
99
+ agentrunner uninstall
100
+ ```
101
+
102
+ Performs the following:
103
+
104
+ 1. Stops the running process
105
+ 2. Removes the autostart service and deletes the service file
106
+ 3. Cleans up the PID file
107
+
108
+ ## Configuration
109
+
110
+ Settings are resolved in the following priority order at runtime.
111
+
112
+ ### Token
113
+
114
+ 1. `AGENTTEAMS_DAEMON_TOKEN` environment variable
115
+ 2. `daemonToken` in `~/.agentteams/daemon.json`
116
+
117
+ ### Environment Variables
118
+
119
+ | Variable | Default | Description |
120
+ |---|---|---|
121
+ | `POLLING_INTERVAL_MS` | `30000` (30s) | Polling interval for pending triggers |
122
+ | `TIMEOUT_MS` | `1800000` (30min) | Runner process timeout |
123
+ | `RUNNER_CMD` | `opencode` | Command used to execute agent tasks |
124
+ | `LOG_LEVEL` | `info` | Log level: `debug`, `info`, `warn`, `error` |
125
+ | `DAEMON_VERBOSE_RUNNER_LOGS` | `true` | When `false`, reduces runner stdout/stderr to start/stop/error only |
126
+ | `DAEMON_PROMPT_LOG_MODE` | `preview` | Prompt logging: `off`, `length`, `preview`, `full` |
127
+
128
+ ## How It Works
129
+
130
+ After `start`, the runner operates in the following loop:
131
+
132
+ 1. Polls for pending triggers periodically
133
+ 2. Claims a trigger
134
+ 3. Fetches runtime info (working directory, API key)
135
+ 4. Executes `RUNNER_CMD run "<prompt>"`
136
+ 5. Updates trigger status based on exit code or timeout
137
+
138
+ If a process is already running for the same `agentConfigId`, new triggers are `REJECTED`.
139
+
140
+ ## Logs
141
+
142
+ - **Runner logs**: console output (forwarded to OS log system when autostarted)
143
+ - **macOS**: `/tmp/agentrunner.log`, `/tmp/agentrunner-error.log`
144
+ - **Linux**: `journalctl --user -u agentrunner -f`
145
+ - **Windows**: Event Viewer → Windows Logs → Application (`AgentRunner`)
146
+ - **Task logs**: `<workdir>/.agentteams/daemonLog/daemon-<triggerId>.log`
147
+
148
+ ## Troubleshooting
149
+
150
+ ### `Missing token. Usage: agentrunner init --token <token> ...`
151
+
152
+ The `--token` flag was not provided to `init`.
153
+
154
+ ### `Daemon token is missing. Run 'agentrunner init --token <token>' first.`
155
+
156
+ No token found at runtime. Run `init` first or set the `AGENTTEAMS_DAEMON_TOKEN` environment variable.
157
+
158
+ ## License
159
+
160
+ Apache-2.0