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.
- package/CLAUDE.md +164 -0
- package/LICENSE +21 -0
- package/README.md +447 -0
- package/dist/cli/commands/add.d.ts +6 -0
- package/dist/cli/commands/add.d.ts.map +1 -0
- package/dist/cli/commands/add.js +150 -0
- package/dist/cli/commands/add.js.map +1 -0
- package/dist/cli/commands/daemon.d.ts +6 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -0
- package/dist/cli/commands/daemon.js +97 -0
- package/dist/cli/commands/daemon.js.map +1 -0
- package/dist/cli/commands/delete.d.ts +6 -0
- package/dist/cli/commands/delete.d.ts.map +1 -0
- package/dist/cli/commands/delete.js +34 -0
- package/dist/cli/commands/delete.js.map +1 -0
- package/dist/cli/commands/down.d.ts +6 -0
- package/dist/cli/commands/down.d.ts.map +1 -0
- package/dist/cli/commands/down.js +53 -0
- package/dist/cli/commands/down.js.map +1 -0
- package/dist/cli/commands/list.d.ts +6 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +41 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +6 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +124 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/run.d.ts +6 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +45 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/scheduler-tick.d.ts +8 -0
- package/dist/cli/commands/scheduler-tick.d.ts.map +1 -0
- package/dist/cli/commands/scheduler-tick.js +25 -0
- package/dist/cli/commands/scheduler-tick.js.map +1 -0
- package/dist/cli/commands/show.d.ts +6 -0
- package/dist/cli/commands/show.d.ts.map +1 -0
- package/dist/cli/commands/show.js +81 -0
- package/dist/cli/commands/show.js.map +1 -0
- package/dist/cli/commands/status.d.ts +6 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +63 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/toggle.d.ts +6 -0
- package/dist/cli/commands/toggle.d.ts.map +1 -0
- package/dist/cli/commands/toggle.js +24 -0
- package/dist/cli/commands/toggle.js.map +1 -0
- package/dist/cli/commands/up.d.ts +6 -0
- package/dist/cli/commands/up.d.ts.map +1 -0
- package/dist/cli/commands/up.js +48 -0
- package/dist/cli/commands/up.js.map +1 -0
- package/dist/cli/utils/errors.d.ts +17 -0
- package/dist/cli/utils/errors.d.ts.map +1 -0
- package/dist/cli/utils/errors.js +37 -0
- package/dist/cli/utils/errors.js.map +1 -0
- package/dist/cli/utils/output.d.ts +17 -0
- package/dist/cli/utils/output.d.ts.map +1 -0
- package/dist/cli/utils/output.js +52 -0
- package/dist/cli/utils/output.js.map +1 -0
- package/dist/cli/utils/prompts.d.ts +8 -0
- package/dist/cli/utils/prompts.d.ts.map +1 -0
- package/dist/cli/utils/prompts.js +27 -0
- package/dist/cli/utils/prompts.js.map +1 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +71 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/auth.d.ts +40 -0
- package/dist/core/auth.d.ts.map +1 -0
- package/dist/core/auth.js +114 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/config.d.ts +43 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +179 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/docker.d.ts +60 -0
- package/dist/core/docker.d.ts.map +1 -0
- package/dist/core/docker.js +507 -0
- package/dist/core/docker.js.map +1 -0
- package/dist/core/index.d.ts +10 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +10 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/jobs.d.ts +53 -0
- package/dist/core/jobs.d.ts.map +1 -0
- package/dist/core/jobs.js +264 -0
- package/dist/core/jobs.js.map +1 -0
- package/dist/core/scheduler-runner.d.ts +15 -0
- package/dist/core/scheduler-runner.d.ts.map +1 -0
- package/dist/core/scheduler-runner.js +230 -0
- package/dist/core/scheduler-runner.js.map +1 -0
- package/dist/core/scheduler.d.ts +41 -0
- package/dist/core/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler.js +373 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/core/setup.d.ts +84 -0
- package/dist/core/setup.d.ts.map +1 -0
- package/dist/core/setup.js +315 -0
- package/dist/core/setup.js.map +1 -0
- package/dist/core/types.d.ts +181 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +12 -0
- package/dist/core/types.js.map +1 -0
- package/dist/tui/App.d.ts +7 -0
- package/dist/tui/App.d.ts.map +1 -0
- package/dist/tui/App.js +103 -0
- package/dist/tui/App.js.map +1 -0
- package/dist/tui/components/Dashboard.d.ts +9 -0
- package/dist/tui/components/Dashboard.d.ts.map +1 -0
- package/dist/tui/components/Dashboard.js +70 -0
- package/dist/tui/components/Dashboard.js.map +1 -0
- package/dist/tui/components/InitWizard.d.ts +2 -0
- package/dist/tui/components/InitWizard.d.ts.map +1 -0
- package/dist/tui/components/InitWizard.js +522 -0
- package/dist/tui/components/InitWizard.js.map +1 -0
- package/dist/tui/components/JobDetail.d.ts +12 -0
- package/dist/tui/components/JobDetail.d.ts.map +1 -0
- package/dist/tui/components/JobDetail.js +137 -0
- package/dist/tui/components/JobDetail.js.map +1 -0
- package/dist/tui/components/JobForm.d.ts +10 -0
- package/dist/tui/components/JobForm.d.ts.map +1 -0
- package/dist/tui/components/JobForm.js +183 -0
- package/dist/tui/components/JobForm.js.map +1 -0
- package/dist/tui/components/JobList.d.ts +11 -0
- package/dist/tui/components/JobList.d.ts.map +1 -0
- package/dist/tui/components/JobList.js +136 -0
- package/dist/tui/components/JobList.js.map +1 -0
- package/dist/tui/components/LogViewer.d.ts +10 -0
- package/dist/tui/components/LogViewer.d.ts.map +1 -0
- package/dist/tui/components/LogViewer.js +184 -0
- package/dist/tui/components/LogViewer.js.map +1 -0
- package/dist/tui/index.d.ts +11 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +11 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/types.d.ts +21 -0
- package/dist/tui/types.d.ts.map +1 -0
- package/dist/tui/types.js +5 -0
- package/dist/tui/types.js.map +1 -0
- package/images/base-tasks/Dockerfile +33 -0
- package/images/node-tasks/Dockerfile +36 -0
- package/images/pipeline-runner/Dockerfile +43 -0
- package/images/pipeline-runner/entrypoint.sh +60 -0
- package/images/python-tasks/Dockerfile +43 -0
- package/package.json +91 -0
- 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
|
+
[](https://www.npmjs.com/package/agent-oven)
|
|
4
|
+
[](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 @@
|
|
|
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"}
|