CLI

Schedule agent tasks with the CLI

Create a disabled daily task, verify its configuration, and manage runs and updates.

Give a scheduled task its own thread

You need project access, working Codex authentication in that project, and a CLI version with project chat automation. Scheduled agent runs perform real work and use the configured model. This recipe creates a disabled draft first.

In Bash, set the profile, full project ID, chat path, a supported model, and an existing working directory inside the project:

export CLI_PROFILE=cocalc-ai
export PROJECT_ID='REPLACE_WITH_FULL_PROJECT_ID'
export CHAT_PATH='/home/user/daily-check.chat'
export AGENT_MODEL='REPLACE_WITH_SUPPORTED_MODEL'
export PROJECT_WORKDIR='/home/user'

cocalc --profile "$CLI_PROFILE" project get --project "$PROJECT_ID"

Step 1: Create a dedicated thread

cocalc --profile "$CLI_PROFILE" --json project chat thread create \
  --project "$PROJECT_ID" --path "$CHAT_PATH" \
  --name "Daily project check" --agent-kind acp \
  --model "$AGENT_MODEL" --reasoning medium \
  --session-mode read-only --workdir "$PROJECT_WORKDIR"

Check data.created:true, retain data.thread.thread_id as THREAD_ID, and inspect data.thread.acp_config. Scheduled runs use the thread's model, reasoning, working directory, and access mode, but get their own Codex session instead of resuming its interactive session. Write a self-contained task prompt.

Step 2: Save and inspect a disabled draft

export THREAD_ID='REPLACE_WITH_RETURNED_THREAD_ID'

cocalc --profile "$CLI_PROFILE" --json project chat automation upsert \
  --project "$PROJECT_ID" --path "$CHAT_PATH" --thread-id "$THREAD_ID" \
  --title "Daily project check" \
  --prompt "Inspect this project without changing files. Summarize unfinished work and report any failures." \
  --local-time 09:00 --timezone Europe/Madrid \
  --pause-after-unacknowledged-runs 7 --disabled

cocalc --profile "$CLI_PROFILE" --json project chat automation status \
  --project "$PROJECT_ID" --path "$CHAT_PATH" --thread-id "$THREAD_ID"

Always provide a nonempty --title; the backend requires it even though the CLI option is not marked required. Replace the example time and timezone with your intended schedule.

Check both outer ok:true and data.ok:true, then confirm data.config.enabled:false, the title, prompt, daily local time, timezone, and data.state.status:"paused". A successful status request with data.config:null means the thread has no saved automation.

Step 3: Activate when ready

Before enabling the schedule, check the project's browser-idle policy and host lifecycle and the authentication needed by commands in its prompt. An enabled schedule does not reserve compute or renew fresh authentication. Project or host availability, model authentication, and admission limits can prevent a run from completing. Confirm a result after activation before relying on unattended execution; the schedule configuration alone is not that result.

To enable the reviewed daily task:

cocalc --profile "$CLI_PROFILE" --json project chat automation resume \
  --project "$PROJECT_ID" --path "$CHAT_PATH" --thread-id "$THREAD_ID"

Inspect data.ok, data.config.enabled, data.state.status, and data.state.next_run_at_ms. To deliberately request an immediate run:

cocalc --profile "$CLI_PROFILE" --json project chat automation run-now \
  --project "$PROJECT_ID" --path "$CHAT_PATH" --thread-id "$THREAD_ID"

run-now can execute even while the schedule is paused. Its response confirms submission or an already active run, not completion. Read automation status and the chat result afterward. Retain data.state.last_job_op_id, check the last-run timestamps and last_error, and review the actual result before counting it as successful. Admission can fail inside an otherwise successful CLI response, so check data.ok as well as the outer envelope.

Update, pause, or remove a schedule

Read the current configuration before using upsert again. Supply the complete intended title, prompt, local time, timezone, and unacknowledged-run limit. Upsert replaces configuration and enables the task unless --disabled is supplied. Omitted optional settings return to defaults, including an unacknowledged-run limit of seven.

This CLI form creates a daily Codex schedule for every day of the week. It can overwrite an existing command-based, interval, or restricted-weekday configuration; use the appropriate schedule UI for those forms rather than this daily recipe.

Pause future scheduled runs:

cocalc --profile "$CLI_PROFILE" --json project chat automation pause \
  --project "$PROJECT_ID" --path "$CHAT_PATH" --thread-id "$THREAD_ID"

After reviewing results, reset the unacknowledged-run counter:

cocalc --profile "$CLI_PROFILE" --json project chat automation acknowledge \
  --project "$PROJECT_ID" --path "$CHAT_PATH" --thread-id "$THREAD_ID"

Acknowledgment does not resume a paused task. If the unacknowledged-run limit paused it, acknowledge and then resume when appropriate.

To remove the schedule, while retaining the chat thread:

cocalc --profile "$CLI_PROFILE" --json project chat automation delete \
  --project "$PROJECT_ID" --path "$CHAT_PATH" --thread-id "$THREAD_ID"

Check data.ok:true and data.config:null. Pausing or deleting the schedule does not cancel an already running job. For general operation recovery, see scripting and results.