From 2154896c74651ee57af24fb7c5a5fb7d72e06aa0 Mon Sep 17 00:00:00 2001 From: Darren Cheng Date: Wed, 24 Jun 2026 16:11:39 -0700 Subject: [PATCH 1/2] fix(argus-schedule): iterate .schedules[] envelope in list verb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The daemon's GET /api/schedules returns {"schedules":[...]}, not a bare array. The list verb only pretty-printed with `| jq` and left the agent to guess `.[]`, which indexes the wrapper object and fails with "Cannot index array with string". Make the list example iterate `.schedules[]` and document the envelope explicitly. Audited the other verbs against internal/api/schedules.go: - create/update return a flat scheduleJSON object (.id/.next_run_at correct); added a note confirming the shape. - run returns {"task_id":"..."}; added a note to surface the task ID. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- agents/skills/argus-schedule/SKILL.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/agents/skills/argus-schedule/SKILL.md b/agents/skills/argus-schedule/SKILL.md index 148e1e86..0397887a 100644 --- a/agents/skills/argus-schedule/SKILL.md +++ b/agents/skills/argus-schedule/SKILL.md @@ -50,12 +50,15 @@ Pick the verb from `$ARGUMENTS`. If unclear, ask which one. ### list +The daemon returns an object with the rows under a top-level `schedules` key — `{"schedules": [ ... ]}` — not a bare array. Always iterate `.schedules[]`; a bare `.[]` indexes the wrapper object and fails with "Cannot index array with string". + ``` curl -sS -H "Authorization: Bearer $(cat ~/.argus/api-token)" \ - http://localhost:7743/api/schedules | jq + http://localhost:7743/api/schedules \ + | jq -r '.schedules[] | "\(.id)\t\(.name)\t\(.schedule)\t\(.enabled)\t\(.next_run_at)\t\(.last_run_at // "never")\t\(.last_error // "")"' ``` -Show the user a compact table: `name`, `schedule`, `enabled`, `next_run_at`, `last_run_at`, `last_error` (only if non-empty). Hide `prompt` unless the user asks — prompts can be long. +Render those rows as a compact table for the user: `name`, `schedule`, `enabled`, `next_run_at`, `last_run_at`, and `last_error` (show `last_error` only when non-empty). Keep `id` handy for the update and run verbs, which need it. Hide `prompt` unless the user asks — prompts can be long. ### create @@ -84,7 +87,7 @@ curl -sS -X POST \ http://localhost:7743/api/schedules | jq ``` -After the call, echo the returned `id`, `next_run_at`, and a one-line confirmation. Do not add `--data-raw` shortcuts that bypass jq — embedding raw user input into a shell-quoted JSON string is a quoting hazard. +Create and update both return the schedule object directly (the flat shape, not wrapped under a key), so `.id` and `.next_run_at` index the response without a path prefix. After the call, echo the returned `id`, `next_run_at`, and a one-line confirmation. Do not add `--data-raw` shortcuts that bypass jq — embedding raw user input into a shell-quoted JSON string is a quoting hazard. ### update @@ -111,6 +114,8 @@ curl -sS -X POST \ http://localhost:7743/api/schedules/"$ID"/run | jq ``` +The response is an object carrying only the new task ID — `{"task_id": "..."}` — not a schedule object; surface that task ID so the user can find the run in argus. + Note for the user: the run-now path does NOT send a push notification (the cron tick path does). If they expected the notification, that is the reason it did not arrive. ### enable / disable From 8846bc81ba33f14eed4ff363eb357a3e98f44956 Mon Sep 17 00:00:00 2001 From: Darren Cheng Date: Wed, 24 Jun 2026 16:14:16 -0700 Subject: [PATCH 2/2] fix(argus-schedule): coalesce next_run_at, document list column order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address review findings on the list verb: - next_run_at is omitempty; without `// "pending"` jq prints a literal "null" for never-scheduled/disabled rows. Add the fallback. - Document that the jq emits 7 tab-separated columns with `id` as column 1, so the agent labels the table correctly instead of shifting columns. - Note that empty output means no schedules (exit 0) while a jq "Cannot iterate over null" error means the response was not the expected envelope — surface the body and stop. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- agents/skills/argus-schedule/SKILL.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/agents/skills/argus-schedule/SKILL.md b/agents/skills/argus-schedule/SKILL.md index 0397887a..cae9914e 100644 --- a/agents/skills/argus-schedule/SKILL.md +++ b/agents/skills/argus-schedule/SKILL.md @@ -50,15 +50,15 @@ Pick the verb from `$ARGUMENTS`. If unclear, ask which one. ### list -The daemon returns an object with the rows under a top-level `schedules` key — `{"schedules": [ ... ]}` — not a bare array. Always iterate `.schedules[]`; a bare `.[]` indexes the wrapper object and fails with "Cannot index array with string". +The daemon returns an object with the rows under a top-level `schedules` key — `{"schedules": [ ... ]}` — not a bare array. Always iterate `.schedules[]`; a bare `.[]` indexes the wrapper object and fails with "Cannot index array with string". Several fields are omitted when empty (`next_run_at`, `last_run_at`, `last_error`), so coalesce them with `//` — otherwise jq interpolates the absent value as a literal "null". ``` curl -sS -H "Authorization: Bearer $(cat ~/.argus/api-token)" \ http://localhost:7743/api/schedules \ - | jq -r '.schedules[] | "\(.id)\t\(.name)\t\(.schedule)\t\(.enabled)\t\(.next_run_at)\t\(.last_run_at // "never")\t\(.last_error // "")"' + | jq -r '.schedules[] | "\(.id)\t\(.name)\t\(.schedule)\t\(.enabled)\t\(.next_run_at // "pending")\t\(.last_run_at // "never")\t\(.last_error // "")"' ``` -Render those rows as a compact table for the user: `name`, `schedule`, `enabled`, `next_run_at`, `last_run_at`, and `last_error` (show `last_error` only when non-empty). Keep `id` handy for the update and run verbs, which need it. Hide `prompt` unless the user asks — prompts can be long. +The jq emits seven tab-separated columns in this order: `id`, `name`, `schedule`, `enabled`, `next_run_at`, `last_run_at`, `last_error`. Render them as a compact table; `id` is column 1 and is needed for the update and run verbs. Show `last_error` only when non-empty, and hide `prompt` unless the user asks — prompts can be long. Empty output means there are no schedules (jq still exits 0); a jq error such as "Cannot iterate over null" means the response was not the expected envelope — surface the raw body and stop rather than retrying. ### create