npm package: @gemini-jobs/core
Description: Scheduled AI jobs powered by Gemini CLI. Zero to running in one command.
Latest version: 0.2.0

# gemini-jobs

Scheduled AI jobs powered by Gemini CLI. Zero to running in one command.

## Quick Start

```bash
# Set up gemini-jobs (installs Gemini CLI if needed)
npx gemini-jobs init

# Create a job from a built-in template
npx gemini-jobs create --from summarize-folder

# Schedule it to run daily at 9am
npx gemini-jobs schedule summarize-folder "0 9 * * *"
```

That's it. Your job runs on schedule via cron and writes logs to `~/.gemini-jobs/logs/`.

## Commands

| Command | Description |
|---|---|
| `init` | Set up gemini-jobs (install Gemini CLI, configure API key, create directories) |
| `create` | Create a new job (interactive or from a built-in template via `--from`) |
| `list` | List all jobs with schedule and last run status |
| `run <job>` | Run a job immediately |
| `schedule <job> <cron>` | Add a job to crontab |
| `unschedule <job>` | Remove a job from crontab |
| `logs <job>` | Show logs for a job (`--all` to list all log files) |
| `doctor` | Check all prerequisites and system health |

## Built-in Templates

| Template | What it does |
|---|---|
| `summarize-folder` | Summarize all files in a directory using Gemini |
| `daily-briefing` | Generate a daily briefing from configured sources |
| `file-watcher` | Watch a directory for changes and process new files |

Use any template with `npx gemini-jobs create --from <template>`.

## How It Works

Each job is a bash script that calls `gemini` CLI. When you schedule a job, gemini-jobs:

1. Wraps your script with `runner.sh` (handles logging, error capture, timeouts)
2. Adds a crontab entry pointing to the runner
3. Logs every run to `~/.gemini-jobs/logs/`

No daemon. No background process. Just cron + bash + Gemini CLI.

## Model Selection & Free Tier

Gemini CLI defaults to `gemini-2.5-pro` which has a very limited free tier. For scheduled jobs, **use `gemini-2.0-flash`** — it's fast, cheap, and has 60x more daily requests:

| Model | Free Tier (API key) | Best for |
|---|---|---|
| `gemini-2.5-pro` | 25 req/day | Complex reasoning, analysis |
| `gemini-2.0-flash` | 1,500 req/day | Scheduled jobs, summaries, briefings |

Set the model in your job script with the `-m` flag:

```bash
gemini -m gemini-2.0-flash -p "Your prompt here" 2>/dev/null
```

**Google login** (`gemini auth`) gives 1,000 req/day on the default model. Run `npx gemini-jobs init` to configure authentication.

## Writing Jobs

### Using `@file` for large prompts

For jobs that need large prompts (RSS feeds, file contents, etc.), write the prompt to a file and reference it with `@filename`:

```bash
# Build a prompt file with context
echo "Analyze this data:" > "$HOME/.gemini-jobs/.my-prompt.txt"
echo "$DATA" >> "$HOME/.gemini-jobs/.my-prompt.txt"

# Gemini reads the file — keeps your prompt clean and avoids shell escaping issues
gemini -m gemini-2.0-flash -p "Follow the instructions in @.my-prompt.txt" 2>/dev/null
```

> **Important:** Gemini CLI sandboxes `@file` access to the current working directory. The runner automatically sets cwd to `~/.gemini-jobs/`, so place prompt files there. See the `daily-briefing` template for a working example.

### RSS feeds as input

Gemini parses raw RSS/Atom XML natively — no need to extract text first:

```bash
FEED=$(curl -sL --max-time 15 "https://example.com/rss" | head -c 5000)
gemini -m gemini-2.0-flash -p "Summarize the latest news: $FEED" 2>/dev/null
```

## Requirements

- **Node.js** 20+
- **macOS** or **Linux** (cron-based scheduling)
- **Gemini CLI** (installed automatically by `init`)

## Project Structure

```
~/.gemini-jobs/
  config.json              # API key source, defaults
  runner.sh                # Cron environment bridge
  jobs/
    summarize-folder.sh    # Your job scripts
  logs/
    summarize-folder_2026-02-15_09-00-01.log
```

## Packages

This project is a monorepo with two packages:

- **`gemini-jobs`** -- the CLI (`npx gemini-jobs`)
- **`@gemini-jobs/core`** -- shared library (config, cron, templates, runner)

## License

MIT