agent-oven 0.1.0

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 (146) hide show
  1. package/CLAUDE.md +164 -0
  2. package/LICENSE +21 -0
  3. package/README.md +447 -0
  4. package/dist/cli/commands/add.d.ts +6 -0
  5. package/dist/cli/commands/add.d.ts.map +1 -0
  6. package/dist/cli/commands/add.js +150 -0
  7. package/dist/cli/commands/add.js.map +1 -0
  8. package/dist/cli/commands/daemon.d.ts +6 -0
  9. package/dist/cli/commands/daemon.d.ts.map +1 -0
  10. package/dist/cli/commands/daemon.js +97 -0
  11. package/dist/cli/commands/daemon.js.map +1 -0
  12. package/dist/cli/commands/delete.d.ts +6 -0
  13. package/dist/cli/commands/delete.d.ts.map +1 -0
  14. package/dist/cli/commands/delete.js +34 -0
  15. package/dist/cli/commands/delete.js.map +1 -0
  16. package/dist/cli/commands/down.d.ts +6 -0
  17. package/dist/cli/commands/down.d.ts.map +1 -0
  18. package/dist/cli/commands/down.js +53 -0
  19. package/dist/cli/commands/down.js.map +1 -0
  20. package/dist/cli/commands/list.d.ts +6 -0
  21. package/dist/cli/commands/list.d.ts.map +1 -0
  22. package/dist/cli/commands/list.js +41 -0
  23. package/dist/cli/commands/list.js.map +1 -0
  24. package/dist/cli/commands/logs.d.ts +6 -0
  25. package/dist/cli/commands/logs.d.ts.map +1 -0
  26. package/dist/cli/commands/logs.js +124 -0
  27. package/dist/cli/commands/logs.js.map +1 -0
  28. package/dist/cli/commands/run.d.ts +6 -0
  29. package/dist/cli/commands/run.d.ts.map +1 -0
  30. package/dist/cli/commands/run.js +45 -0
  31. package/dist/cli/commands/run.js.map +1 -0
  32. package/dist/cli/commands/scheduler-tick.d.ts +8 -0
  33. package/dist/cli/commands/scheduler-tick.d.ts.map +1 -0
  34. package/dist/cli/commands/scheduler-tick.js +25 -0
  35. package/dist/cli/commands/scheduler-tick.js.map +1 -0
  36. package/dist/cli/commands/show.d.ts +6 -0
  37. package/dist/cli/commands/show.d.ts.map +1 -0
  38. package/dist/cli/commands/show.js +81 -0
  39. package/dist/cli/commands/show.js.map +1 -0
  40. package/dist/cli/commands/status.d.ts +6 -0
  41. package/dist/cli/commands/status.d.ts.map +1 -0
  42. package/dist/cli/commands/status.js +63 -0
  43. package/dist/cli/commands/status.js.map +1 -0
  44. package/dist/cli/commands/toggle.d.ts +6 -0
  45. package/dist/cli/commands/toggle.d.ts.map +1 -0
  46. package/dist/cli/commands/toggle.js +24 -0
  47. package/dist/cli/commands/toggle.js.map +1 -0
  48. package/dist/cli/commands/up.d.ts +6 -0
  49. package/dist/cli/commands/up.d.ts.map +1 -0
  50. package/dist/cli/commands/up.js +48 -0
  51. package/dist/cli/commands/up.js.map +1 -0
  52. package/dist/cli/utils/errors.d.ts +17 -0
  53. package/dist/cli/utils/errors.d.ts.map +1 -0
  54. package/dist/cli/utils/errors.js +37 -0
  55. package/dist/cli/utils/errors.js.map +1 -0
  56. package/dist/cli/utils/output.d.ts +17 -0
  57. package/dist/cli/utils/output.d.ts.map +1 -0
  58. package/dist/cli/utils/output.js +52 -0
  59. package/dist/cli/utils/output.js.map +1 -0
  60. package/dist/cli/utils/prompts.d.ts +8 -0
  61. package/dist/cli/utils/prompts.d.ts.map +1 -0
  62. package/dist/cli/utils/prompts.js +27 -0
  63. package/dist/cli/utils/prompts.js.map +1 -0
  64. package/dist/cli.d.ts +8 -0
  65. package/dist/cli.d.ts.map +1 -0
  66. package/dist/cli.js +71 -0
  67. package/dist/cli.js.map +1 -0
  68. package/dist/core/auth.d.ts +40 -0
  69. package/dist/core/auth.d.ts.map +1 -0
  70. package/dist/core/auth.js +114 -0
  71. package/dist/core/auth.js.map +1 -0
  72. package/dist/core/config.d.ts +43 -0
  73. package/dist/core/config.d.ts.map +1 -0
  74. package/dist/core/config.js +179 -0
  75. package/dist/core/config.js.map +1 -0
  76. package/dist/core/docker.d.ts +60 -0
  77. package/dist/core/docker.d.ts.map +1 -0
  78. package/dist/core/docker.js +507 -0
  79. package/dist/core/docker.js.map +1 -0
  80. package/dist/core/index.d.ts +10 -0
  81. package/dist/core/index.d.ts.map +1 -0
  82. package/dist/core/index.js +10 -0
  83. package/dist/core/index.js.map +1 -0
  84. package/dist/core/jobs.d.ts +53 -0
  85. package/dist/core/jobs.d.ts.map +1 -0
  86. package/dist/core/jobs.js +264 -0
  87. package/dist/core/jobs.js.map +1 -0
  88. package/dist/core/scheduler-runner.d.ts +15 -0
  89. package/dist/core/scheduler-runner.d.ts.map +1 -0
  90. package/dist/core/scheduler-runner.js +230 -0
  91. package/dist/core/scheduler-runner.js.map +1 -0
  92. package/dist/core/scheduler.d.ts +41 -0
  93. package/dist/core/scheduler.d.ts.map +1 -0
  94. package/dist/core/scheduler.js +373 -0
  95. package/dist/core/scheduler.js.map +1 -0
  96. package/dist/core/setup.d.ts +84 -0
  97. package/dist/core/setup.d.ts.map +1 -0
  98. package/dist/core/setup.js +315 -0
  99. package/dist/core/setup.js.map +1 -0
  100. package/dist/core/types.d.ts +181 -0
  101. package/dist/core/types.d.ts.map +1 -0
  102. package/dist/core/types.js +12 -0
  103. package/dist/core/types.js.map +1 -0
  104. package/dist/tui/App.d.ts +7 -0
  105. package/dist/tui/App.d.ts.map +1 -0
  106. package/dist/tui/App.js +103 -0
  107. package/dist/tui/App.js.map +1 -0
  108. package/dist/tui/components/Dashboard.d.ts +9 -0
  109. package/dist/tui/components/Dashboard.d.ts.map +1 -0
  110. package/dist/tui/components/Dashboard.js +70 -0
  111. package/dist/tui/components/Dashboard.js.map +1 -0
  112. package/dist/tui/components/InitWizard.d.ts +2 -0
  113. package/dist/tui/components/InitWizard.d.ts.map +1 -0
  114. package/dist/tui/components/InitWizard.js +522 -0
  115. package/dist/tui/components/InitWizard.js.map +1 -0
  116. package/dist/tui/components/JobDetail.d.ts +12 -0
  117. package/dist/tui/components/JobDetail.d.ts.map +1 -0
  118. package/dist/tui/components/JobDetail.js +137 -0
  119. package/dist/tui/components/JobDetail.js.map +1 -0
  120. package/dist/tui/components/JobForm.d.ts +10 -0
  121. package/dist/tui/components/JobForm.d.ts.map +1 -0
  122. package/dist/tui/components/JobForm.js +183 -0
  123. package/dist/tui/components/JobForm.js.map +1 -0
  124. package/dist/tui/components/JobList.d.ts +11 -0
  125. package/dist/tui/components/JobList.d.ts.map +1 -0
  126. package/dist/tui/components/JobList.js +136 -0
  127. package/dist/tui/components/JobList.js.map +1 -0
  128. package/dist/tui/components/LogViewer.d.ts +10 -0
  129. package/dist/tui/components/LogViewer.d.ts.map +1 -0
  130. package/dist/tui/components/LogViewer.js +184 -0
  131. package/dist/tui/components/LogViewer.js.map +1 -0
  132. package/dist/tui/index.d.ts +11 -0
  133. package/dist/tui/index.d.ts.map +1 -0
  134. package/dist/tui/index.js +11 -0
  135. package/dist/tui/index.js.map +1 -0
  136. package/dist/tui/types.d.ts +21 -0
  137. package/dist/tui/types.d.ts.map +1 -0
  138. package/dist/tui/types.js +5 -0
  139. package/dist/tui/types.js.map +1 -0
  140. package/images/base-tasks/Dockerfile +33 -0
  141. package/images/node-tasks/Dockerfile +36 -0
  142. package/images/pipeline-runner/Dockerfile +43 -0
  143. package/images/pipeline-runner/entrypoint.sh +60 -0
  144. package/images/python-tasks/Dockerfile +43 -0
  145. package/package.json +91 -0
  146. package/scheduler.sh +522 -0
package/CLAUDE.md ADDED
@@ -0,0 +1,164 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ Agent Oven is a macOS-native job scheduler that runs Docker containers on a schedule using Colima as the container runtime. It features an interactive terminal UI (TUI) built with React/Ink for job management, and a launchd daemon that executes scheduled jobs.
8
+
9
+ **Status:** In Development
10
+
11
+ **Long-term goal:** A shell app for deploying, managing, and updating VM "ovens" where scripts/agents can be scheduled to run.
12
+
13
+ ## Architecture
14
+
15
+ ```
16
+ ┌─────────────────────────────────────────────────────────┐
17
+ │ TUI (npm start) │
18
+ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────┐ │
19
+ │ │Dashboard│ │Job List │ │Job Form │ │ Log Viewer │ │
20
+ │ └─────────┘ └─────────┘ └─────────┘ └─────────────┘ │
21
+ └─────────────────────────────────────────────────────────┘
22
+
23
+ ┌─────────────────────────────────────────────────────────┐
24
+ │ Core Library │
25
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
26
+ │ │ jobs.ts │ │scheduler │ │docker.ts │ │ config.ts │ │
27
+ │ └──────────┘ └──────────┘ └──────────┘ └───────────┘ │
28
+ └─────────────────────────────────────────────────────────┘
29
+
30
+ ┌─────────────┴─────────────┐
31
+ │ │
32
+ ┌─────────┐ ┌───────────┐
33
+ │jobs.json│ │ Docker │
34
+ └─────────┘ │ (Colima) │
35
+ └───────────┘
36
+
37
+ ┌─────────────────┐ ┌──────────────┐ ┌─────────────┐
38
+ │ launchd │────▶│ scheduler.sh │────▶│ Docker │
39
+ │ (60s interval) │ │ (daemon) │ │ (via Colima)│
40
+ └─────────────────┘ └──────────────┘ └─────────────┘
41
+ ```
42
+
43
+ ## Project Structure
44
+
45
+ ```
46
+ agent-oven/
47
+ ├── src/
48
+ │ ├── core/ # Core library (no UI dependencies)
49
+ │ │ ├── types.ts # TypeScript interfaces
50
+ │ │ ├── config.ts # Configuration management
51
+ │ │ ├── jobs.ts # Job CRUD operations
52
+ │ │ ├── docker.ts # Docker/Colima execution
53
+ │ │ └── scheduler.ts # Cron parsing, schedule matching
54
+ │ │
55
+ │ ├── tui/ # Ink TUI components
56
+ │ │ ├── App.tsx # Main app with navigation
57
+ │ │ └── components/ # Dashboard, JobList, JobForm, etc.
58
+ │ │
59
+ │ └── cli.tsx # Entry point
60
+
61
+ ├── dist/ # Compiled JavaScript
62
+ ├── images/ # Dockerfiles for pre-built images
63
+ ├── scheduler.sh # Daemon (called by launchd)
64
+ ├── setup.sh # Initial setup script
65
+ ├── jobs.json # Job definitions
66
+ ├── package.json
67
+ └── tsconfig.json
68
+ ```
69
+
70
+ ## Commands
71
+
72
+ ```bash
73
+ # Initial setup (installs Colima, Docker, builds images, creates launchd agent)
74
+ ./setup.sh
75
+
76
+ # Run the interactive TUI
77
+ npm start
78
+
79
+ # Run the interactive setup
80
+ npm run init
81
+
82
+ # Development mode with hot reload
83
+ npm run dev
84
+
85
+ # Build TypeScript
86
+ npm run build
87
+
88
+ # Type check without building
89
+ npm run typecheck
90
+ ```
91
+
92
+ ## TUI Keyboard Shortcuts
93
+
94
+ **Dashboard:**
95
+ - `j` - Go to Jobs list
96
+ - `a` - Add new job
97
+ - `l` - View logs
98
+ - `q` - Quit
99
+
100
+ **Job List:**
101
+ - `↑/↓` or `j/k` - Navigate
102
+ - `Enter` - View job details
103
+ - `r` - Run job now
104
+ - `Space` - Toggle enabled/disabled
105
+ - `d` - Delete job
106
+ - `/` - Filter jobs
107
+ - `Esc` - Back
108
+
109
+ **Log Viewer:**
110
+ - `↑/↓` - Scroll
111
+ - `f` - Toggle follow mode
112
+ - `g/G` - Go to top/bottom
113
+ - `o` - View older runs
114
+ - `Esc` - Back
115
+
116
+ ## Job JSON Structure
117
+
118
+ ```json
119
+ {
120
+ "id": "my-job",
121
+ "name": "Human Name",
122
+ "image": "agent-oven/python-tasks",
123
+ "command": ["python", "script.py"],
124
+ "volumes": ["/host/path:/container/path"],
125
+ "env": {"KEY": "value"},
126
+ "schedule": {"type": "cron", "cron": "0 * * * *"},
127
+ "timeout": 300,
128
+ "enabled": true
129
+ }
130
+ ```
131
+
132
+ ## Pre-built Docker Images
133
+
134
+ Built during `./setup.sh` from `images/` directory:
135
+
136
+ - **agent-oven/base-tasks**: Alpine with CLI tools (curl, jq, git, rsync, etc.)
137
+ - **agent-oven/python-tasks**: Python 3.12 with AI/data libs (openai, anthropic, langchain, pandas)
138
+ - **agent-oven/node-tasks**: Node 20 with TypeScript and automation tools (puppeteer, playwright, zx)
139
+
140
+ ## Configuration
141
+
142
+ User config stored at `~/.config/agent-oven/config.json` (XDG compliant):
143
+
144
+ ```json
145
+ {
146
+ "projectDir": "/path/to/agent-oven",
147
+ "colima": { "cpu": 2, "memory": 4, "disk": 20 },
148
+ "docker": { "defaultCpus": 1, "defaultMemory": "512m" },
149
+ "timezone": "America/Los_Angeles"
150
+ }
151
+ ```
152
+
153
+ ## Logs
154
+
155
+ - Scheduler log: `logs/scheduler.log`
156
+ - Job logs: `logs/jobs/<job-id>/<timestamp>.log`
157
+
158
+ ## Development
159
+
160
+ The codebase uses:
161
+ - **TypeScript** with strict mode
162
+ - **React 18** + **Ink 5** for the TUI
163
+ - **execa** for shell command execution
164
+ - ES modules throughout (`"type": "module"`)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Fernando Rojas | FRE Studios (https://fre-studios.com/)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,447 @@
1
+ # Agent Oven
2
+
3
+ [![npm version](https://img.shields.io/npm/v/agent-oven.svg)](https://www.npmjs.com/package/agent-oven)
4
+ [![license](https://img.shields.io/npm/l/agent-oven.svg)](https://github.com/FRE-Studios/Agent-Oven/blob/main/LICENSE)
5
+
6
+ macOS-native job scheduler that runs Docker containers on a schedule using Colima, with an interactive terminal UI for job management.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm install -g agent-oven
12
+ ```
13
+
14
+ Then run the interactive setup wizard and launch the TUI:
15
+
16
+ ```bash
17
+ agent-oven init # one-time setup (installs Colima, Docker, builds images, configures launchd)
18
+ agent-oven # launch the TUI
19
+ ```
20
+
21
+ ### CLI Commands
22
+
23
+ ```bash
24
+ agent-oven # launch TUI
25
+ agent-oven list # list all jobs
26
+ agent-oven show <id> # show job details
27
+ agent-oven add # add a new job (interactive)
28
+ agent-oven run <id> # run a job immediately
29
+ agent-oven toggle <id> # enable/disable a job
30
+ agent-oven delete <id> # delete a job
31
+ agent-oven logs [id] # view logs (scheduler or job-specific)
32
+ agent-oven status # system status (Colima, Docker, daemon)
33
+ agent-oven up # start Colima VM
34
+ agent-oven down # stop Colima VM
35
+ agent-oven daemon install # install/reinstall launchd daemon
36
+ agent-oven daemon remove # remove launchd daemon
37
+ ```
38
+
39
+ ### From Source
40
+
41
+ ```bash
42
+ git clone https://github.com/FRE-Studios/Agent-Oven.git
43
+ cd Agent-Oven
44
+ npm install
45
+ npm run init # interactive setup wizard
46
+ npm start # launch the TUI
47
+ ```
48
+
49
+ ## Architecture
50
+
51
+ ```
52
+ ┌─────────────────────────────────────────────────────────┐
53
+ │ TUI (npm start) │
54
+ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────┐ │
55
+ │ │Dashboard│ │Job List │ │Job Form │ │ Log Viewer │ │
56
+ │ └─────────┘ └─────────┘ └─────────┘ └─────────────┘ │
57
+ └─────────────────────────────────────────────────────────┘
58
+
59
+ ┌─────────────────────────────────────────────────────────┐
60
+ │ Core Library │
61
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
62
+ │ │ jobs.ts │ │scheduler │ │docker.ts │ │ config.ts │ │
63
+ │ └──────────┘ └──────────┘ └──────────┘ └───────────┘ │
64
+ └─────────────────────────────────────────────────────────┘
65
+
66
+ ┌─────────────┴─────────────┐
67
+ │ │
68
+ ┌─────────┐ ┌───────────┐
69
+ │jobs.json│ │ Docker │
70
+ └─────────┘ │ (Colima) │
71
+ └───────────┘
72
+
73
+ ┌─────────────────┐ ┌──────────────┐ ┌─────────────┐
74
+ │ launchd │────▶│ scheduler.sh │────▶│ Docker │
75
+ │ (60s interval) │ │ (daemon) │ │ (via Colima)│
76
+ └─────────────────┘ └──────────────┘ └─────────────┘
77
+ ```
78
+
79
+ ## Prerequisites
80
+
81
+ - macOS
82
+ - [Homebrew](https://brew.sh)
83
+ - Node.js >= 18
84
+
85
+ ## Setup (Init Wizard)
86
+
87
+ `npm run init` launches an interactive wizard that walks through the full setup:
88
+
89
+ 1. **Prerequisites check** — verifies Homebrew, Colima, Docker, and jq are installed
90
+ 2. **Dependency installation** — installs any missing dependencies via Homebrew
91
+ 3. **Colima VM configuration** — configure CPU, memory, and disk allocation for the VM
92
+ 4. **Colima start** — starts the Colima VM with the chosen settings
93
+ 5. **Docker verification** — confirms Docker is reachable through Colima
94
+ 6. **File setup** — creates `logs/`, `logs/jobs/`, and `jobs.json`
95
+ 7. **Image selection** — choose which pre-built Docker images to build
96
+ 8. **Image building** — builds the selected Docker images
97
+ 9. **Timezone configuration** — detects system timezone with option to override
98
+ 10. **Launchd daemon installation** — installs the scheduler as a launchd agent (runs every 60 seconds)
99
+
100
+ Configuration is saved to `~/.config/agent-oven/config.json`.
101
+
102
+ If any step fails, you can **r**etry, **s**kip, or **q**uit.
103
+
104
+ ## Usage — The TUI
105
+
106
+ `npm start` launches the interactive terminal UI. Navigate between screens using keyboard shortcuts.
107
+
108
+ ### Dashboard
109
+
110
+ The landing screen. Displays:
111
+
112
+ - Colima and scheduler daemon status (running/stopped)
113
+ - Job summary: total jobs, cron jobs, pending one-time jobs
114
+ - Running containers
115
+ - Last 5 job executions with status
116
+
117
+ Auto-refreshes every 10 seconds.
118
+
119
+ ### Job List
120
+
121
+ Lists all jobs with their ID, enabled status, and schedule type.
122
+
123
+ - `●` green = enabled
124
+ - `○` red = disabled
125
+ - `◐` yellow = currently running
126
+
127
+ Supports filtering by typing `/` and entering a search term. Shows filtered count vs total.
128
+
129
+ ### Job Form
130
+
131
+ Form for creating or editing Docker jobs. Fields:
132
+
133
+ | Field | Description |
134
+ |-------|-------------|
135
+ | ID | Unique identifier (immutable after creation) |
136
+ | Name | Human-readable name |
137
+ | Image | Docker image (select from built-in images or enter custom) |
138
+ | Command | Command to execute in the container |
139
+ | Schedule Type | Toggle between `cron` and `once` |
140
+ | Cron / Datetime | Cron expression or ISO 8601 datetime |
141
+ | Volumes | Volume mounts, one per line (`host:container[:mode]`) |
142
+ | Timeout | Timeout in seconds |
143
+
144
+ ### Job Detail
145
+
146
+ Shows full configuration for a single job:
147
+
148
+ - Job metadata (name, ID, type, enabled status)
149
+ - Docker jobs: image, command, timeout, volumes
150
+ - Pipeline jobs: pipeline name, repo, branch, auth mode
151
+ - Schedule description and next run time
152
+ - Environment variable count
153
+ - Last 5 runs with exit codes
154
+
155
+ ### Log Viewer
156
+
157
+ Displays log file contents with syntax highlighting:
158
+
159
+ - Error/failed lines in red
160
+ - Warning lines in yellow
161
+ - Success/exit code 0 in green
162
+ - Timestamps dimmed
163
+
164
+ Auto-refreshes every second when follow mode is enabled. Can switch between multiple log files for a job.
165
+
166
+ ## Keyboard Shortcuts
167
+
168
+ ### Dashboard
169
+
170
+ | Key | Action |
171
+ |-----|--------|
172
+ | `j` | Go to Jobs list |
173
+ | `a` | Add new job |
174
+ | `l` | View scheduler log |
175
+ | `q` | Quit |
176
+
177
+ ### Job List
178
+
179
+ | Key | Action |
180
+ |-----|--------|
181
+ | `↑` / `k` | Move selection up |
182
+ | `↓` / `j` | Move selection down |
183
+ | `Enter` | View job details |
184
+ | `r` | Run job now |
185
+ | `Space` | Toggle enabled/disabled |
186
+ | `d` | Delete job |
187
+ | `a` | Add new job |
188
+ | `/` | Filter jobs |
189
+ | `Esc` | Back to dashboard |
190
+
191
+ ### Job Detail
192
+
193
+ | Key | Action |
194
+ |-----|--------|
195
+ | `r` | Run job now |
196
+ | `e` | Edit job |
197
+ | `Space` | Toggle enabled/disabled |
198
+ | `d` | Delete job |
199
+ | `l` | View logs |
200
+ | `Esc` | Back |
201
+
202
+ ### Job Form
203
+
204
+ | Key | Action |
205
+ |-----|--------|
206
+ | `Tab` | Next field |
207
+ | `Shift+Tab` | Previous field |
208
+ | `Ctrl+S` | Save |
209
+ | `Space` / `←` / `→` | Toggle schedule type |
210
+ | `Esc` | Cancel |
211
+
212
+ ### Log Viewer
213
+
214
+ | Key | Action |
215
+ |-----|--------|
216
+ | `↑` / `k` | Scroll up |
217
+ | `↓` / `j` | Scroll down |
218
+ | `Page Up` | Scroll up one page |
219
+ | `Page Down` | Scroll down one page |
220
+ | `g` | Go to top |
221
+ | `G` | Go to bottom |
222
+ | `f` | Toggle follow mode |
223
+ | `o` | View older runs |
224
+ | `r` | Refresh |
225
+ | `Esc` | Back |
226
+
227
+ ### Global
228
+
229
+ | Key | Action |
230
+ |-----|--------|
231
+ | `Ctrl+C` | Quit from anywhere |
232
+
233
+ ## Job Configuration
234
+
235
+ Jobs are stored in `jobs.json`. There are two job types: **Docker** and **Agent Pipeline**.
236
+
237
+ ### Docker Jobs
238
+
239
+ Run a Docker container with a specified image and command.
240
+
241
+ ```json
242
+ {
243
+ "type": "docker",
244
+ "id": "daily-backup",
245
+ "name": "Daily Backup",
246
+ "image": "agent-oven/base-tasks",
247
+ "command": ["sh", "-c", "rsync -av /data/ /backup/"],
248
+ "volumes": ["/Users/me/data:/data:ro", "/Users/me/backup:/backup"],
249
+ "env": { "RETENTION_DAYS": "30" },
250
+ "schedule": { "type": "cron", "cron": "0 2 * * *" },
251
+ "resources": {
252
+ "timeout": 600,
253
+ "memory": "1g",
254
+ "cpus": 1
255
+ },
256
+ "enabled": true
257
+ }
258
+ ```
259
+
260
+ | Field | Type | Required | Description |
261
+ |-------|------|----------|-------------|
262
+ | `type` | `"docker"` | yes | Job type discriminator |
263
+ | `id` | string | yes | Unique identifier |
264
+ | `name` | string | yes | Human-readable name |
265
+ | `image` | string | yes | Docker image to run |
266
+ | `command` | string or string[] | yes | Command to execute |
267
+ | `volumes` | string[] | no | Volume mounts (`host:container[:mode]`) |
268
+ | `env` | object | no | Environment variables |
269
+ | `schedule` | object | yes | Schedule configuration (see below) |
270
+ | `resources` | object | no | Resource limits (timeout, memory, cpus) |
271
+ | `timeout` | number | no | Timeout in seconds (legacy, prefer `resources.timeout`) |
272
+ | `enabled` | boolean | no | Whether the job is active (default: true) |
273
+
274
+ ### Agent Pipeline Jobs
275
+
276
+ Run a Claude Code agent pipeline from a git repository.
277
+
278
+ ```json
279
+ {
280
+ "type": "agent-pipeline",
281
+ "id": "weekly-review",
282
+ "name": "Weekly Code Review",
283
+ "source": {
284
+ "repo": "https://github.com/user/repo.git",
285
+ "branch": "main"
286
+ },
287
+ "pipeline": "code-review",
288
+ "auth": "host-login",
289
+ "schedule": { "type": "cron", "cron": "0 9 * * 1" },
290
+ "enabled": true
291
+ }
292
+ ```
293
+
294
+ | Field | Type | Required | Description |
295
+ |-------|------|----------|-------------|
296
+ | `type` | `"agent-pipeline"` | yes | Job type discriminator |
297
+ | `id` | string | yes | Unique identifier |
298
+ | `name` | string | yes | Human-readable name |
299
+ | `source.repo` | string | yes | Git repository URL |
300
+ | `source.branch` | string | no | Branch to check out (default: `"main"`) |
301
+ | `pipeline` | string | yes | Pipeline name to run |
302
+ | `auth` | `"host-login"` or `"api-key"` | no | Auth mode (defaults to config-level setting) |
303
+ | `schedule` | object | yes | Schedule configuration |
304
+ | `enabled` | boolean | no | Whether the job is active (default: true) |
305
+
306
+ ### Schedule Types
307
+
308
+ **Cron** — standard 5-field format: `minute hour day month weekday`
309
+
310
+ ```json
311
+ { "type": "cron", "cron": "0 * * * *" }
312
+ ```
313
+
314
+ | Expression | Meaning |
315
+ |------------|---------|
316
+ | `* * * * *` | Every minute |
317
+ | `0 * * * *` | Every hour |
318
+ | `0 9 * * *` | Daily at 9 AM |
319
+ | `0 9 * * 1` | Every Monday at 9 AM |
320
+ | `*/15 * * * *` | Every 15 minutes |
321
+ | `0 9-17 * * *` | Every hour from 9 AM to 5 PM |
322
+ | `0 0 1,15 * *` | 1st and 15th of each month |
323
+
324
+ Supported syntax: wildcards (`*`), intervals (`*/5`), ranges (`9-17`), comma-separated values (`1,15,30`). Weekdays: 1=Monday through 7=Sunday.
325
+
326
+ **One-time** — ISO 8601 datetime, runs once then is removed:
327
+
328
+ ```json
329
+ { "type": "once", "datetime": "2025-03-15T14:30:00" }
330
+ ```
331
+
332
+ ## Pre-built Docker Images
333
+
334
+ Built during `npm run init` from the `images/` directory:
335
+
336
+ | Image | Base | Contents |
337
+ |-------|------|----------|
338
+ | `agent-oven/base-tasks` | Alpine | bash, curl, wget, jq, yq, git, rsync, tar, gzip, zip, openssh-client, coreutils, findutils, grep, sed, gawk |
339
+ | `agent-oven/python-tasks` | Python 3.12 slim | requests, httpx, pandas, numpy, openai, anthropic, langchain, beautifulsoup4, playwright, rich, typer |
340
+ | `agent-oven/node-tasks` | Node 20 slim | typescript, tsx, zx, axios, cheerio, puppeteer, playwright, dotenv, commander, chalk |
341
+ | `agent-oven/pipeline-runner` | Node 20 slim | @anthropic-ai/claude-code, agent-pipeline, gh (GitHub CLI), git |
342
+
343
+ All images set `TZ=America/Los_Angeles` and use `/workspace` as the working directory.
344
+
345
+ ## How Scheduling Works
346
+
347
+ The scheduler runs as a macOS launchd daemon that fires every 60 seconds:
348
+
349
+ 1. **launchd** triggers `scheduler.sh`
350
+ 2. The script reads `jobs.json` and checks if Colima is running (starts it if needed)
351
+ 3. For each enabled job, it evaluates the schedule against the current time
352
+ 4. Matching jobs are executed as Docker containers:
353
+ - **Docker jobs**: run with configured image, command, volumes, env, and resource limits (default: 1 CPU, 512m memory)
354
+ - **Pipeline jobs**: run with `agent-oven/pipeline-runner`, mounting Claude and GitHub credentials read-only (default: 2 CPU, 2g memory, 30 minute timeout)
355
+ 5. Output is captured to `logs/jobs/<job-id>/<timestamp>.log`
356
+ 6. `last_run` is updated in `jobs.json`
357
+ 7. Completed one-time jobs are removed
358
+
359
+ ## Configuration
360
+
361
+ Stored at `~/.config/agent-oven/config.json`:
362
+
363
+ ```json
364
+ {
365
+ "projectDir": "/path/to/agent-oven",
366
+ "colima": {
367
+ "cpu": 2,
368
+ "memory": 4,
369
+ "disk": 20
370
+ },
371
+ "docker": {
372
+ "defaultCpus": 1,
373
+ "defaultMemory": "512m"
374
+ },
375
+ "timezone": "America/Los_Angeles",
376
+ "auth": {
377
+ "defaultMode": "host-login",
378
+ "claudeCredPath": "~/.claude",
379
+ "ghCredPath": "~/.config/gh"
380
+ }
381
+ }
382
+ ```
383
+
384
+ | Field | Description |
385
+ |-------|-------------|
386
+ | `projectDir` | Path to the agent-oven project directory |
387
+ | `colima.cpu` | Number of CPUs for the Colima VM |
388
+ | `colima.memory` | Memory in GB for the Colima VM |
389
+ | `colima.disk` | Disk size in GB for the Colima VM |
390
+ | `docker.defaultCpus` | Default CPU limit for Docker jobs |
391
+ | `docker.defaultMemory` | Default memory limit for Docker jobs |
392
+ | `timezone` | Timezone for schedule evaluation |
393
+ | `auth.defaultMode` | Default auth mode for pipeline jobs (`host-login` or `api-key`) |
394
+ | `auth.claudeCredPath` | Path to Claude credentials directory |
395
+ | `auth.ghCredPath` | Path to GitHub CLI credentials directory |
396
+
397
+ ## Logs
398
+
399
+ **Scheduler log**: `logs/scheduler.log` — records each scheduler run, job matches, and execution results.
400
+
401
+ **Job logs**: `logs/jobs/<job-id>/<timestamp>.log` — one file per execution, named by timestamp.
402
+
403
+ View logs through the TUI (press `l` from Dashboard or Job Detail), or read directly from the filesystem.
404
+
405
+ ## Development
406
+
407
+ ```bash
408
+ npm run dev # development mode with hot reload
409
+ npm run build # compile TypeScript to dist/
410
+ npm run typecheck # type check without emitting
411
+ ```
412
+
413
+ The codebase uses TypeScript with strict mode, React 18 + Ink 5 for the TUI, execa for shell execution, and ES modules throughout.
414
+
415
+ ## Project Structure
416
+
417
+ ```
418
+ agent-oven/
419
+ ├── src/
420
+ │ ├── core/ # Core library (no UI dependencies)
421
+ │ │ ├── types.ts # TypeScript interfaces
422
+ │ │ ├── config.ts # Configuration management
423
+ │ │ ├── jobs.ts # Job CRUD operations
424
+ │ │ ├── docker.ts # Docker/Colima execution
425
+ │ │ └── scheduler.ts # Cron parsing, schedule matching
426
+ │ ├── tui/ # Ink TUI components
427
+ │ │ ├── App.tsx # Main app with navigation
428
+ │ │ └── components/ # Dashboard, JobList, JobForm, etc.
429
+ │ └── cli.tsx # Entry point
430
+ ├── images/ # Dockerfiles for pre-built images
431
+ │ ├── base-tasks/
432
+ │ ├── python-tasks/
433
+ │ ├── node-tasks/
434
+ │ └── pipeline-runner/
435
+ ├── scheduler.sh # Daemon script (called by launchd)
436
+ ├── jobs.json # Job definitions
437
+ ├── package.json
438
+ └── tsconfig.json
439
+ ```
440
+
441
+ ## Contributing
442
+
443
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
444
+
445
+ ## License
446
+
447
+ MIT
@@ -0,0 +1,6 @@
1
+ /**
2
+ * `agent-oven add <id>` — Add a new job
3
+ */
4
+ import type { Command } from 'commander';
5
+ export declare function register(program: Command): void;
6
+ //# sourceMappingURL=add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/add.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWzC,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+J/C"}