Skip to content
helmstudio
Contents

jobs

GET /jobs

The calling studio's jobs, of every kind, newest first.

R40. Only the token's studio: its install, build, download, update, export and uninstall jobs, and the task jobs it reported. Never another studio's (M4 first review, #2).

Needs the jobs capability.

GoList(ctx context.Context, params *JobsListParams) (*JobPage, error)
Pythondef list(self, *, limit: Optional[Any] = None, cursor: Optional[Any] = None) -> Any
JavaScriptlist(params = {})
ParameterInTypeAbout
limitqueryinteger
cursorquerystringThe `next_cursor` of the previous page, unchanged.
StatusBodyMeans
200JobPageA page of jobs.
400ErrorThe request is malformed. Codes: `bad_request`, `bad_filter`, `bad_cursor`, `invalid_document`.
401ErrorNo studio token, or a revoked or unknown one. Code `unauthenticated`.
403ErrorThe token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`).

POST /jobs

Report a long-running piece of the studio's own work as a task job.

R40, Q24. The daemon runs nothing: the studio updates progress and state with PATCH, appends log lines, and ends the job itself. The job starts `running` unless `state: queued` is given.

Needs the jobs capability.

GoCreate(ctx context.Context, body TaskCreate) (*Job, error)
Pythondef create(self, body: Dict[str, Any]) -> Any
JavaScriptcreate(body)

Request body: TaskCreate (application/json)

StatusBodyMeans
201JobThe new task job.
400ErrorThe request is malformed. Codes: `bad_request`, `bad_filter`, `bad_cursor`, `invalid_document`.
401ErrorNo studio token, or a revoked or unknown one. Code `unauthenticated`.
403ErrorThe token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`).

GET /jobs/{id}

One of the calling studio's jobs. Another studio's is 404.

Needs the jobs capability.

GoGet(ctx context.Context, id string) (*Job, error)
Pythondef get(self, id: str) -> Any
JavaScriptget(id)
ParameterInTypeAbout
idpath · requiredULID
StatusBodyMeans
200JobThe job.
401ErrorNo studio token, or a revoked or unknown one. Code `unauthenticated`.
403ErrorThe token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`).
404ErrorAbsent, deleted, or not the caller's to see. Code `not_found`.

PATCH /jobs/{id}

Report progress on, or finish, a task job the calling studio created.

Q24, M4 first review #11. A JSON merge patch. State may move `queued → running`, and from either to `succeeded`, `failed` or `cancelled`; a finished job cannot change (409 `job_finished`). `progress_num` must not exceed `progress_den`. `last_error: null` clears it. Only the studio's own `task` jobs: another studio's job is 404, and one of its own lifecycle jobs is 403 `not_a_task`.

Needs the jobs capability.

GoUpdate(ctx context.Context, id string, body map[string]any) (*Job, error)
Pythondef update(self, id: str, body: Dict[str, Any]) -> Any
JavaScriptupdate(id, body)
ParameterInTypeAbout
idpath · requiredULID

Request body: TaskUpdate (application/merge-patch+json)

StatusBodyMeans
200JobThe updated job.
400ErrorThe request is malformed. Codes: `bad_request`, `bad_filter`, `bad_cursor`, `invalid_document`.
401ErrorNo studio token, or a revoked or unknown one. Code `unauthenticated`.
403ErrorThe token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`).
404ErrorAbsent, deleted, or not the caller's to see. Code `not_found`.
409ErrorCodes: `etag_mismatch`, `name_taken`, `job_finished`, `already_running`, `not_running`, `port_conflict`, `heavy_conflict` (with `details.heavy`), `not_installed`, `conflict`, `in_use`, `missing`, `confirm_required` and `preview_changed` (with `details.preview`), `not_reclaimable`, and from M7: `approval_required` (with `details.approval`), `id_taken`, `not_fetched`, `already_exists`.

GET /jobs/{id}/logs

One of the calling studio's job logs as server-sent events, from the start, then live until the job finishes.

Events: `step` when an install step's log begins, `line` per line, and `end` once the job has finished and every line has been sent. A task job has no `step` events. Another studio's job is 404.

Needs the jobs capability.

GoLogs(ctx context.Context, id string) (*EventStream, error)
Pythondef logs(self, id: str) -> Any
JavaScriptlogs(id)
ParameterInTypeAbout
idpath · requiredULID

Events:

StatusBodyMeans
200stringAn event stream.
401ErrorNo studio token, or a revoked or unknown one. Code `unauthenticated`.
403ErrorThe token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`).
404ErrorAbsent, deleted, or not the caller's to see. Code `not_found`.

POST /jobs/{id}/logs

Append lines to a running task job's log.

Q24. Written to a log file the daemon owns under the logs root, never into the database. A finished job is 409 `job_finished`; a lifecycle job is 403 `not_a_task`; another studio's job is 404.

Needs the jobs capability.

GoAppendLog(ctx context.Context, id string, body LogAppend) error
Pythondef append_log(self, id: str, body: Dict[str, Any]) -> Any
JavaScriptappendLog(id, body)
ParameterInTypeAbout
idpath · requiredULID

Request body: LogAppend (application/json)

StatusBodyMeans
204Appended.
400ErrorThe request is malformed. Codes: `bad_request`, `bad_filter`, `bad_cursor`, `invalid_document`.
401ErrorNo studio token, or a revoked or unknown one. Code `unauthenticated`.
403ErrorThe token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`).
404ErrorAbsent, deleted, or not the caller's to see. Code `not_found`.
409ErrorCodes: `etag_mismatch`, `name_taken`, `job_finished`, `already_running`, `not_running`, `port_conflict`, `heavy_conflict` (with `details.heavy`), `not_installed`, `conflict`, `in_use`, `missing`, `confirm_required` and `preview_changed` (with `details.preview`), `not_reclaimable`, and from M7: `approval_required` (with `details.approval`), `id_taken`, `not_fetched`, `already_exists`.
413ErrorThe body is over its limit. Code `too_large`, with `details.limit` in bytes.

POST /jobs/{id}:cancel

Ask for one of the calling studio's task jobs to be cancelled.

Q24. Records `cancel_requested_at` and emits a `job` event. The job stays `running` until the studio ends it. Cancelling a finished job is 409 `job_finished`. A studio cannot cancel its own install, build, download or uninstall jobs (403 `not_a_task`); only the launcher can (POST /launcher/jobs/{id}:cancel). Another studio's job is 404.

Needs the jobs capability.

GoCancel(ctx context.Context, id string) error
Pythondef cancel(self, id: str) -> Any
JavaScriptcancel(id)
ParameterInTypeAbout
idpath · requiredULID
StatusBodyMeans
204Cancellation requested.
401ErrorNo studio token, or a revoked or unknown one. Code `unauthenticated`.
403ErrorThe token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`).
404ErrorAbsent, deleted, or not the caller's to see. Code `not_found`.
409ErrorCodes: `etag_mismatch`, `name_taken`, `job_finished`, `already_running`, `not_running`, `port_conflict`, `heavy_conflict` (with `details.heavy`), `not_installed`, `conflict`, `in_use`, `missing`, `confirm_required` and `preview_changed` (with `details.preview`), `not_reclaimable`, and from M7: `approval_required` (with `details.approval`), `id_taken`, `not_fetched`, `already_exists`.