{"content":"# aux4/jobs\n\nBackground job manager for aux4. Run commands in the background, monitor their status, and retrieve their output.\n\n## Installation\n\n``bash\naux4 aux4 pkger install aux4/jobs\n`\n\n## Usage\n\n### Run a background job\n\n`bash\naux4 jobs run \"sleep 10 && echo done\"\n`\n\n`json\n{\n \"id\": \"1\",\n \"command\": \"sleep 10 && echo done\",\n \"pid\": 0,\n \"state\": \"RUNNING\",\n \"exitCode\": 0,\n \"startTime\": \"2025-01-01T00:00:00Z\",\n \"dir\": \"/Users/me/project\"\n}\n`\n\n### Start one job per record from a stream\n\nWith --inputStream true, run reads NDJSON (one JSON object per line) or a JSON array from stdin and starts one background job per record. The current record is injected into the command with aux4's ${item} / ${item.field} / ${index} templating — the same convention as the core each: executor — so any stream of records becomes tracked jobs:\n\n`bash\naux4 queue receive --name resize | aux4 jobs run 'echo resized ${item.file}' --inputStream true --source drain\n`\n\n### List all jobs\n\n`bash\naux4 jobs list\n`\n\n`json\n[\n {\n \"id\": \"1\",\n \"command\": \"sleep 10 && echo done\",\n \"pid\": 12345,\n \"state\": \"RUNNING\",\n \"exitCode\": 0,\n \"startTime\": \"2025-01-01T00:00:00Z\",\n \"dir\": \"/Users/me/project\"\n }\n]\n`\n\nFilter by state:\n\n`bash\naux4 jobs list --state RUNNING\n`\n\n### Check job status\n\n`bash\naux4 jobs status 1\n`\n\n`json\n{\n \"id\": \"1\",\n \"command\": \"sleep 10 && echo done\",\n \"pid\": 12345,\n \"state\": \"COMPLETED\",\n \"exitCode\": 0,\n \"startTime\": \"2025-01-01T00:00:00Z\",\n \"endTime\": \"2025-01-01T00:00:10Z\",\n \"duration\": \"10s\",\n \"dir\": \"/Users/me/project\"\n}\n`\n\n### Get job output\n\n`bash\naux4 jobs output 1\n`\n\n`text\ndone\n`\n\nShow stderr instead:\n\n`bash\naux4 jobs output 1 --stream stderr\n`\n\n### Tail job output\n\nStream output in real time while the job is running:\n\n`bash\naux4 jobs tail 1\n`\n\nTail stderr:\n\n`bash\naux4 jobs tail 1 --stream stderr\n`\n\n### Kill a running job\n\n`bash\naux4 jobs kill 1\n`\n\n`text\njob 1 killed\n`\n\n### Kill all running jobs\n\n`bash\naux4 jobs killall\n`\n\n`text\njob 1 killed\njob 3 killed\n`\n\n### Callbacks\n\nRun a command automatically when a job finishes using --onSuccess, --onFailure, or --onComplete:\n\n`bash\naux4 jobs run \"npm test\" --onSuccess \"echo Tests passed\" --onFailure \"echo Tests FAILED\"\n`\n\nUse --onComplete to run a command on any terminal state (success, failure, or killed):\n\n`bash\naux4 jobs run \"deploy.sh\" --onComplete \"echo Job finished with state $AUX4_JOB_STATE\"\n`\n\nCallbacks run via sh -c in the job's working directory. If both a specific callback (onSuccess/onFailure) and onComplete are set, the specific one runs first.\n\n#### Callback Environment Variables\n\n| Variable | Description | Example |\n|----------|-------------|---------|\n| AUX4_JOB_ID | Job ID | 3 |\n| AUX4_JOB_STATE | Terminal state | COMPLETED, FAILED, KILLED |\n| AUX4_JOB_EXIT_CODE | Exit code | 0, 1, -1 |\n| AUX4_JOB_COMMAND | Original command | npm test |\n| AUX4_JOB_DIR | Working directory | /home/user/project |\n\n### Source tags\n\nTag jobs with a source identifier so multiple agents sharing the same jobs directory can list only their own jobs:\n\n`bash\naux4 jobs run \"long-task.sh\" --source agent-a\naux4 jobs list --source agent-a\n`\n\n### Auto-cleanup\n\nUse --cleanup true to remove the job directory automatically after callbacks finish:\n\n`bash\naux4 jobs run \"send-notification.sh\" --cleanup true\n`\n\nThis is useful for fire-and-forget jobs whose output doesn't need to be retained.\n\n### Custom storage path\n\nUse --path on any command to use a different storage directory than the default .jobs:\n\n`bash\naux4 jobs run \"build.sh\" --path .my-jobs\naux4 jobs list --path .my-jobs\n`\n\nThis lets multiple agents fully isolate their jobs from each other.\n\n### Clean old jobs\n\nRemove all finished jobs older than a given duration:\n\n`bash\naux4 jobs clean 12h\n`\n\n`text\njob 2 removed\njob 5 removed\n`\n\nThe default duration is 24h. Any Go duration format is accepted (e.g. 24h, 12h, 30m). Running jobs are always skipped.\n\n### Removing jobs\n\nRemove a single finished job:\n\n`bash\naux4 jobs remove 3\n`\n\nForce-remove a running job (kills it first):\n\n`bash\naux4 jobs remove 3 --force true\n`\n\nRemove all finished jobs created by a specific source:\n\n`bash\naux4 jobs remove-all --source agent-a\n`\n\nRemove only failed jobs:\n\n`bash\naux4 jobs remove-all --state FAILED\n`\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| aux4 jobs run <command> [--onSuccess] [--onFailure] [--onComplete] [--source] [--cleanup] [--path] | Run a command in the background with optional callbacks, source tag, auto-cleanup, and storage path |\n| aux4 jobs list [--state] [--source] [--path] | List jobs, optionally filtered by state and/or source |\n| aux4 jobs status <id> [--path] | Show job status with exit code and duration |\n| aux4 jobs output <id> [--stream] [--path] | Show full job output |\n| aux4 jobs tail <id> [--stream] [--path] | Tail job output in real time |\n| aux4 jobs kill <id> [--path] | Kill a running job |\n| aux4 jobs killall [--path] | Kill all running jobs |\n| aux4 jobs clean [duration] [--path] | Remove finished jobs older than the given duration (default: 24h) |\n| aux4 jobs remove <id> [--force] [--path] | Remove a finished job from storage |\n| aux4 jobs remove-all [--state] [--source] [--path] | Remove all finished jobs (optionally filtered) |\n| aux4 jobs on <id> [--success] [--failure] [--complete] | Register callbacks on a running job |\n| aux4 jobs attach <pid> <command> [--stdout] [--stderr] [--source] [--path] | Attach an external process to the jobs system |\n\n## How It Works\n\nJobs are stored in .jobs/ in the current directory by default (override with --path). Each job gets its own directory containing:\n\n- job.json — job metadata (command, PID, state, timestamps, source, cleanup flag)\n- stdout — captured standard output\n- stderr — captured standard error\n\nA background monitor process waits for the command to finish and updates the job state with the exit code and end time. If cleanup: true` was set, the directory is removed after callbacks run.\n"}