cjules
Version, currently 0.3.06 versions
github.com/hahwul/cjules
A power-user CLI for the Jules API in Crystal. Multi-account auth, bulk ops, watch mode, gitPatch extraction, markdown activity export, and pipe-friendly outputs.
Installation
# Add this to your shard.yml
dependencies:
cjules:
github: hahwul/cjules
version: ~> 0.3.0Then run:
shards installshard.yml
- Crystal
>= 1.20.0- License
- MIT
- Author
- hahwul
- Target
cjulesfrom src/main.cr
Dependencies
Development Dependencies
README
[!WARNING] Jules is shutting down, so cjules is no longer maintained. Google announced that Jules becomes read-only after November 11, 2026 and shuts down on December 31, 2026. v0.3.0 is the final release of cjules. The repository will be archived after that. Your code, branches, and PRs stay on GitHub. To keep session history, use the official export from the announcement before the service goes away.
A scriptable CLI for Jules, written in Crystal.
- Git-aware
new— auto-detects--repoand--branch; reads the prompt from args,stdin, or--file. - Parallel sessions —
cjules new --parallel Nruns N sessions with the same prompt. - Watch —
cjules watch <id>tails activities;--auto-approve --reply --notify desktop|slack|discordfor hands-free runs. - Prune — filter by state, age, repo, or
--all; dry-run by default,-yto apply. - **Patch & PR** — `cjules patch <id> --apply` (or `-i` for interactive hunks) runs `git apply`;
cjules pr <id> --openopens the PR. - Git helpers —
cjules commit-msggenerates a commit message fromgit diff(or a session);cjules pr-describe <id> --copygenerates a Markdown PR description from the session's actions and patch. - Logs —
cjules logs <id> -f mdfor a full report,--bashfor shell transcripts,--save-mediafor artifacts. - Pipe-friendly —
-f table|json|jsonl|yamlon every list command. - Multi-account — aliases via
cjules accounts use, or one-shot with--account. - Pick —
cjules pick(usesfzfif available) with--action show|watch|pr|delete. - Retry —
cjules retry <id>re-runs a session by cloning its prompt, repo, branch, and flags;--with-failure-reasoncarries the original failure message into the new prompt;cjules troubleshoot <id>diagnoses compile errors, missing shards, and failing specs from the logs and offers a retry with a fix note. - Templates — drop reusable prompts into
~/.config/cjules/templates/and reference them via--template <name>onneworretry. Templates support dynamic variables:{{.File "path"}},{{.GitDiff}}, and{{.Var "name"}}for powerful prompt generation.
Heads up: the Jules API is currently labelled
v1alpha. Schema and behaviour can change without notice. Pin a release of cjules in scripts you care about and read the CHANGELOG when upgrading.
Install
Homebrew
brew tap hahwul/cjules
brew install cjules
Build from Source
shards build --release
install bin/cjules /usr/local/bin/
AI Skill
npx skills add hahwul/cjules
Auth
Issue an API key at jules.google.com/settings/api and save it with cjules login.
cjules login --alias work # prompts for the API key (input hidden)
cjules login --alias personal --key AIza...
cjules accounts ls
cjules accounts use personal
cjules logout work
Resolution order: JULES_API_KEY env var → JULES_ACCOUNT env var → active alias from config.
Examples
Creating sessions
# Create a session for the current git repo/branch
cjules new "Add a healthcheck endpoint"
# Pipe a longer prompt and let Jules open the PR automatically
cat PROMPT.md | cjules new --auto-pr -
# Read the prompt from a file, override repo/branch, require plan approval
cjules new --file PROMPT.md --repo hahwul/cjules --branch main --require-approval
# Repoless session (no sourceContext)
cjules new --no-repo "Draft release notes for v0.2.0"
# Fan out N parallel sessions with the same prompt and capture the IDs
cjules new --parallel 5 --auto-pr "Refactor the config loader" -f json | jq -r '.[].id' > ids.txt
Burst submissions: under heavy parallelism the Jules API can return
HTTP 400 Precondition check failedfor a session that did get created server-side. By defaultcjules newreconciles 4xx failures by matching against sessions in the account that were created since the call started (preferring--title, falling back to the prompt). Pass--no-reconcile-on-errorto opt out and surface the raw error.
Watching and steering
# Watch a session live (3s default poll)
cjules watch <session-id> --interval 5
# Hands-free run: auto-approve plans, reply to feedback prompts, and send desktop/webhook notifications
cjules watch <session-id> --auto-approve --reply --notify desktop
cjules watch <session-id> --notify slack,discord
# Send a follow-up message
cjules msg <session-id> "Also add a /readyz endpoint"
# Or pipe one in
echo "Please add tests for the error path" | cjules msg <session-id> -
# Approve a pending plan explicitly
cjules approve <session-id>
Listing, filtering, piping
# Recent failures as JSONL, pipe into jq
cjules ls --state FAILED --since 7d -f jsonl | jq -r '.id + "\t" + .title'
# Re-pull logs for the latest failure
cjules ls --state FAILED --since 7d -f jsonl | jq -r .id | head -1 | xargs cjules logs
# Interactive picker (uses fzf if installed) — default action shows the session
cjules pick
cjules pick --action watch # pick → watch
cjules pick --action pr # pick → print PR URL
Patches, PRs, exports
# Inspect or apply the resulting patch locally
cjules patch <session-id> --list
cjules patch <session-id> --apply
cjules patch <session-id> --interactive # select hunks (like `git add -p`)
# Print or open the PR
cjules pr <session-id>
cjules pr <session-id> --open
# Generate a Markdown PR description (and optionally copy to clipboard)
cjules pr-describe <session-id>
cjules pr-describe <session-id> --copy
# Generate a commit message from local git diff or from a session's patch
cjules commit-msg
cjules commit-msg --staged --copy
cjules commit-msg <session-id> --copy
# Full session report as Markdown
cjules logs <session-id> -f md > report.md
# Pull only bash command/output blocks (handy for debugging long runs)
cjules logs <session-id> --bash
# Save media artifacts (screenshots, etc.) to a directory
cjules logs <session-id> --save-media ./artifacts
Re-running with retry
retry clones a session's prompt, repo, branch, title, and --auto-pr /
--require-approval flags into a brand-new session. Handy for FAILED runs.
# Plain retry: same prompt, same repo/branch, new session
cjules retry <session-id>
# Retry and feed the original failure reason back into the prompt
cjules retry <session-id> --with-failure-reason
# Tweak the prompt for the next attempt without losing the rest of the context
cjules retry <session-id> --note "Skip the migration step this time."
# Override prompt or branch entirely
cjules retry <session-id> --prompt "New approach: ..."
cjules retry <session-id> --branch experimental-fix
# Pick the most-recent failure and retry it in one line
cjules ls --state FAILED --limit 1 -f jsonl | jq -r .id | xargs cjules retry --with-failure-reason
# Diagnose a failure from its bash logs and retry with a suggested fix note
cjules troubleshoot <session-id> # asks [Y/n] before retrying
cjules troubleshoot <session-id> --dry-run
cjules troubleshoot <session-id> --yes
Reusable prompts with templates
Drop *.md or *.txt files into ~/.config/cjules/templates/ and reference
them by filename. Templates are looked up there by short name.
Templates now support dynamic variables for powerful prompt generation:
{{.File "path"}}— Insert file contents{{.GitDiff}}— Insert current git diff{{.Var "name"}}— Insert user-defined variables passed via--var
# See what's available and where they live
cjules templates ls
cjules templates path
cjules templates show bugfix # print body
# Use a template as the prompt for a new session
cjules new --template bugfix
cjules new --template bugfix --auto-pr --branch hotfix
# Use templates with variables
cjules new --template refactor --var file=parser.cr --var priority=high
# Or as the prompt for a retry
cjules retry <session-id> --template bugfix
Example template (~/.config/cjules/templates/refactor.md):
Please refactor the following code:
[Code]
{{.File "src/parser.cr"}}
[Notes]
{{.Var "note"}}
[Current Changes]
{{.GitDiff}}
Usage:
cjules new --template refactor --var note="Improve error handling"
Bulk cleanup with prune
prune is dry-run by default — review the matches, then re-run with -y to actually delete.
# Preview what would be deleted
cjules prune --completed --older-than 30d
# Actually delete after the preview looks right
cjules prune --completed --older-than 30d -y
# Sweep failed sessions for a specific repo
cjules prune --failed --repo hahwul/cjules -y
# Match an arbitrary state
cjules prune --state AWAITING_USER_FEEDBACK --older-than 14d -y
# Wipe every session for the active account (cannot be combined with other filters)
cjules prune --all # dry-run preview
cjules prune --all -y # prompts for typed 'yes' confirmation
# One-off targeted delete (no filters needed)
cjules rm <session-id> <session-id> ...
Multi-account workflows
# Run a single command against a non-active account
cjules --account personal ls --since 24h
# One-off override via env var
JULES_ACCOUNT=work cjules new "Bump dependencies"
JULES_API_KEY=AIza... cjules ls
Config
Stored at ~/.config/cjules/config.yml with 0600 permissions. Set defaults:
cjules config set default_repo hahwul/cjules
cjules config set default_branch main
cjules config set slack_webhook https://hooks.slack.com/services/...
cjules config set discord_webhook https://discord.com/api/webhooks/...
Shell completion
cjules completion zsh > "${fpath[1]}/_cjules"
cjules completion bash > /etc/bash_completion.d/cjules
cjules completion fish > ~/.config/fish/completions/cjules.fish
Development
shards build
crystal spec
just lint # requires shards install (pulls ameba)
just check # format check
License
MIT — see LICENSE.
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
0.3.0- Tagged
- Oct 30, 2026
- Commit
e77fbd0884b0- Crystal
>= 1.20.0- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/hahwul/cjules
Metadata
- Created
- Aug 12, 2026
- Updated
- Oct 31, 2026
- Synced
- Oct 30, 2026
- Versions
- 6