| name | cjules |
| description | Use the cjules CLI to drive the Jules API — create, list, watch, inspect, message, approve, log, and patch sessions; manage sources; switch between saved API-key accounts. Invoke when the user mentions Jules, jules.google.com session URLs, Jules sessions/sources, or runs `cjules ...`. |
cjules — Jules API CLI
cjules is a Crystal CLI for the Jules API. It complements the official tooling with multi-account auth, bulk operations, watch/tail mode, gitPatch extraction, and pipe-friendly outputs.
When to invoke
- User mentions a Jules session, source, or
jules.google.com/session/<id> URL.
- User asks to create a new Jules task, list/inspect their sessions, send a follow-up, approve a plan, or apply a session's patch.
- User runs
cjules ... and needs help building the command.
- User wants to switch between multiple Jules API keys.
Do not invoke for unrelated Crystal projects, generic Git questions, or other AI coding agents.
Setup check (run first when unsure)
cjules accounts current
cjules config show
If no account exists: cjules login --alias <name> (prompts for the key with hidden input). For non-interactive contexts: cjules login --alias <name> --key <KEY> or --stdin.
Core commands
| Command | Use it for |
|---|
cjules new [PROMPT|-] | Create a session. Auto-detects --repo from git remote origin and --branch from HEAD. |
cjules ls | List sessions. Filters: --state, --repo, --since, --search. Outputs: -f table|json|jsonl|yaml. |
cjules get <ID> | Show one session in full. |
cjules watch <ID> | Tail activities until session reaches a terminal state. --interval N to change polling. |
cjules msg <ID> <TEXT|-> | Send a follow-up message into an active session. |
cjules approve <ID> | Approve a plan. Aborts unless state is AWAITING_PLAN_APPROVAL; pass --force to skip the precheck. |
cjules logs <ID> [-f md|json|text] | Export the full activity log. Markdown is the default and the most useful format for a human report. |
cjules patch <ID> [--list|--apply|--interactive|--index N] | Print, list, git apply, or interactively apply the session's gitPatch artifacts. |
cjules pr <ID> [--open] | Print (or open) the pull-request URL produced by the session. |
cjules rm <ID...> or cjules rm --state X --older-than Y --repo R | Delete sessions individually or in bulk. Confirmation unless -y. |
cjules sources ls / get <ID> | Inspect connected GitHub repos. |
Multi-account auth
Resolution order: JULES_API_KEY env > JULES_ACCOUNT env > config's active alias.
cjules login --alias work
cjules login --alias side --activate
cjules accounts ls
cjules accounts use personal
cjules --account=personal ls
cjules logout work
Output / pipe patterns
Always prefer -f jsonl when piping to jq (one session per line, no commas):
cjules ls --state FAILED --limit 1 -f jsonl | jq -r .id
ID=$(cjules ls --state COMPLETED --since 24h --limit 1 -f jsonl | jq -r .id)
cjules patch $ID --apply
cjules logs $ID -f md > report.md
Common recipes
Triage failures
cjules ls --state FAILED --since 7d
cjules logs <id> -f md | less
Bulk cleanup
cjules rm --state COMPLETED --older-than 30d
cjules rm --state FAILED --older-than 7d -y
Apply a session's changes locally
cjules patch <id> --list
cjules patch <id> --index 0
cjules patch <id> --apply
cjules patch <id> -i
Live-tail a running session
cjules watch <id> --interval 5
Continue a stalled / waiting session
cjules ls --state AWAITING_USER_FEEDBACK
echo "please also update the README" | cjules msg <id> -
Gotchas
- Session IDs are 20-digit numbers (e.g.
18077675164109662449). Pass the full ID to commands. Both sessions/<id> and bare <id> are accepted.
- Source IDs use slashes:
sources/github/<owner>/<repo> (the cjules sources ls ID column shows the slash form). cjules new --repo OWNER/REPO maps to that internally.
approve is a no-op on completed sessions at the API level; cjules now precheckes the state and aborts early. Use --force only if you really want to call approvePlan regardless.
watch polls; it does not use server push. Default interval is 3s. Increase for long sessions.
patch --apply runs git apply in the current working directory. Run it from the right repo / branch.
patch --interactive requires a TTY (it prompts per hunk). Use --apply in scripts instead.
- Bulk
rm filters require either --state, --older-than, or --repo — calling cjules rm with no args and no filters is rejected.
- Prompt input for
new and msg accepts a positional arg, --file PATH, - for stdin, or piped stdin (when neither tty nor explicit). When stdin isn't a tty, the alias/key prompts in login are disabled — pass --alias and --key/--stdin explicitly.
--repo filter matches the source string with String#includes?. hahwul/hwaro-examples will match sources/github/hahwul/hwaro-examples.
- Date filter
--since accepts 30s, 5m, 2h, 7d, 1w (case-insensitive). Anything else errors out fast.
- TTY-only behavior: color output, hidden key input on
login, and the pick numeric fallback rely on a TTY. Set NO_COLOR=1 to force plain output; pipe stdin to make login non-interactive.
Error codes
cjules exits 0 on success, 1 for runtime / API failures (with the API's message printed), and 2 for usage / argument errors. API failures print API error (HTTP <code>): <detail> to stderr.
When something looks wrong
cjules config show — confirms which key, base URL, and account is active.
cjules accounts ls — confirms the saved aliases.
JULES_ACCOUNT=<alias> cjules ls — bypasses config to test a specific key.
- Re-run with
--no-color to capture clean output for an issue report.