proto: freeze the wire contract at 1.0.0
Schemas for the whole v1 surface: 38 methods, 9 events, 25 named types and the
JSON-RPC envelope, with x-privileged / x-transports / x-deadlineMs / x-errors
annotations that both generators emit as data rather than prose.
Four generators over one IR (contracts/codegen/schema_ir.py), so the C++ structs,
the TypeScript types and the OpenRPC document cannot disagree about what the
contract says:
gen_cpp.py -> core/generated/velox_proto.{hpp,cpp}
gen_ts.py -> extension/src/shared/protocol/
gen_openrpc.py -> contracts/openrpc.json
gen_cpp_conformance.py -> tests/conformance/cpp/fixture_dispatcher.hpp
Inbound parsing never throws: parse<T>() returns std::expected<T, ParseError> and
nlohmann's throwing ADL from_json is deliberately not emitted. Schema constraints
(minimum, maxLength, pattern, ...) become real runtime checks in both languages —
the daemon does not trust the extension and the extension does not trust the
daemon.
59 golden fixtures: a success case per method, 12 error cases, 9 events. Replayed
by tests/conformance/ against both the generated C++ and a live server over both
transports. tools/mockd serves the same fixtures with unhappy-path flags so the
GUI and EXT lanes never wait for veloxd.
run.sh also proves capture.offer fails open: with a daemon answering slower than
750 ms the client gives up and lets Firefox take the download.
core/generated/ is libveloxproto, a separate target from libveloxcore, which
still never sees JSON — see docs/adr/0009.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_012fgjnqFCS5h5L7gZTZo3rV
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/capture.getRules.schema.json",
|
||||
"title": "capture.getRules",
|
||||
"description": "The daemon's capture policy, so the extension's shouldCapture decision cannot drift from the daemon's. Fetched on connect and whenever event.settings.changed names a capture.* key. If this call fails the extension keeps its last known rules and stays fail-open.",
|
||||
"x-privileged": false,
|
||||
"x-transports": [
|
||||
"uds",
|
||||
"ws"
|
||||
],
|
||||
"x-deadlineMs": 2000,
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
},
|
||||
"result": {
|
||||
"$ref": "https://velox.dev/schema/types/CaptureRules.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,11 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/capture.offer.schema.json",
|
||||
"title": "capture.offer",
|
||||
"description": "Firefox offers an intercepted response to the daemon. The daemon MUST reply within 750 ms; the extension abandons the offer and lets Firefox download normally on timeout. TEMPLATE — lane PROTO owns the final shape.",
|
||||
"description": "Firefox offers an intercepted response to the daemon. The daemon MUST reply within 750 ms; the extension abandons the offer and lets Firefox download normally on timeout. This deadline is the whole reason capture fails open, and it is conformance-tested: a daemon that is slow, down, or erroring must never cost the user a download.",
|
||||
"x-privileged": false,
|
||||
"x-transports": ["uds", "ws"],
|
||||
"x-deadlineMs": 750,
|
||||
"x-errors": [-32011],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
@@ -16,32 +17,20 @@
|
||||
"url": { "type": "string", "format": "uri" },
|
||||
"method": { "type": "string", "enum": ["GET", "POST"] },
|
||||
"tabUrl": { "type": "string", "format": "uri" },
|
||||
"headers": {
|
||||
"type": "object",
|
||||
"description": "Request headers Firefox was about to send, verbatim. Needed for signed-URL and referrer-gated CDNs.",
|
||||
"additionalProperties": { "type": "string" }
|
||||
},
|
||||
"headers": { "oneOf": [{ "$ref": "https://velox.dev/schema/types/Headers.schema.json" }, { "type": "null" }] },
|
||||
"cookies": {
|
||||
"type": "array",
|
||||
"type": ["array", "null"],
|
||||
"description": "Cookies for the URL, so authenticated downloads work outside the browser.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["name", "value"],
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"value": { "type": "string" },
|
||||
"domain": { "type": "string" },
|
||||
"path": { "type": "string" }
|
||||
}
|
||||
}
|
||||
"items": { "$ref": "https://velox.dev/schema/types/Cookie.schema.json" }
|
||||
},
|
||||
"contentType": { "type": ["string", "null"] },
|
||||
"contentLength": { "type": ["integer", "null"], "minimum": 0 },
|
||||
"contentDisposition": { "type": ["string", "null"] },
|
||||
"filename": { "type": ["string", "null"], "description": "Extension's best guess; the daemon may override" },
|
||||
"filename": { "type": ["string", "null"], "description": "The extension's best guess; the daemon may override it." },
|
||||
"userAgent": { "type": ["string", "null"] },
|
||||
"referrer": { "type": ["string", "null"] },
|
||||
"origin": { "type": "string", "description": "moz-extension://… — the daemon verifies this on the WS transport" }
|
||||
"origin": { "type": ["string", "null"], "description": "moz-extension://... The daemon verifies this on the WS transport and refuses anything else." },
|
||||
"requestId": { "type": ["string", "null"], "description": "The extension's webRequest id, echoed in logs so a capture decision can be traced back to one browser request." }
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
@@ -50,11 +39,12 @@
|
||||
"required": ["action"],
|
||||
"properties": {
|
||||
"action": { "type": "string", "enum": ["take", "ignore"] },
|
||||
"taskId": { "type": ["string", "null"], "format": "uuid" },
|
||||
"taskId": { "type": ["string", "null"], "format": "uuid", "description": "Set when action is 'take'." },
|
||||
"reason": {
|
||||
"type": ["string", "null"],
|
||||
"description": "Why the offer was declined. Set when action is 'ignore'; the extension logs it in the popup's diagnostics.",
|
||||
"enum": ["excluded_host", "type_not_monitored", "below_min_size", "duplicate",
|
||||
"capture_disabled", "user_declined", null]
|
||||
"capture_disabled", "user_declined", "rule_ignore", null]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/category.list.schema.json",
|
||||
"title": "category.list",
|
||||
"description": "Every category with its folder and extension list. The extension calls this to populate its default-category picker, which is why it is not privileged; it is read-only and exposes only paths the user already configured.",
|
||||
"x-privileged": false,
|
||||
"x-transports": [
|
||||
"uds",
|
||||
"ws"
|
||||
],
|
||||
"x-deadlineMs": 2000,
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "https://velox.dev/schema/types/Category.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/category.remove.schema.json",
|
||||
"title": "category.remove",
|
||||
"description": "Delete a user-created category. Built-in categories are refused with -32602. Tasks filed under it are reassigned to reassignTo, or to the default category when that is null; no task is ever orphaned.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32003,
|
||||
-32602
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"categoryId"
|
||||
],
|
||||
"properties": {
|
||||
"categoryId": {
|
||||
"type": "string"
|
||||
},
|
||||
"reassignTo": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"removed",
|
||||
"reassignedTaskIds"
|
||||
],
|
||||
"properties": {
|
||||
"removed": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"reassignedTaskIds": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/category.upsert.schema.json",
|
||||
"title": "category.upsert",
|
||||
"description": "Create or replace a category. Omit categoryId to create; supply it to replace. Changing saveDir does not move existing files \u2014 the GUI asks separately and issues download.update per task, so a re-point is never a surprise mass file move.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32003,
|
||||
-32011
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"category"
|
||||
],
|
||||
"properties": {
|
||||
"category": {
|
||||
"$ref": "https://velox.dev/schema/types/Category.schema.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "The stored category, with categoryId filled in on create.",
|
||||
"required": [
|
||||
"category"
|
||||
],
|
||||
"properties": {
|
||||
"category": {
|
||||
"$ref": "https://velox.dev/schema/types/Category.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/download.add.schema.json",
|
||||
"title": "download.add",
|
||||
"description": "Create one task. saveDir is canonicalized and checked against saveTo.allowedRoots before anything is written; a path that escapes them is refused with -32011 and no file is created.",
|
||||
"x-privileged": false,
|
||||
"x-transports": ["uds", "ws"],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [-32011, -32012, -32013],
|
||||
"x-wsRestrictions": ["saveDir must be absent or resolve inside an existing category folder; anything else is -32011. The extension may request a download, it may not choose an arbitrary destination."],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": { "$ref": "https://velox.dev/schema/types/DownloadSpec.schema.json" },
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["taskId", "state"],
|
||||
"properties": {
|
||||
"taskId": { "type": "string", "format": "uuid" },
|
||||
"state": { "$ref": "https://velox.dev/schema/types/TaskState.schema.json" },
|
||||
"duplicate": { "type": ["string", "null"], "format": "uuid", "description": "The existing task this URL matched, when downloads.duplicatePolicy resolved to 'skip'. taskId then names that existing task." }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/download.addBatch.schema.json",
|
||||
"title": "download.addBatch",
|
||||
"description": "Create many tasks in one call: the clipboard blob, the wildcard expander, and the extension's 'Download all links'. Partial success is normal and is reported per item rather than failing the whole batch.",
|
||||
"x-privileged": false,
|
||||
"x-transports": ["uds", "ws"],
|
||||
"x-deadlineMs": 30000,
|
||||
"x-errors": [-32011, -32012],
|
||||
"x-wsRestrictions": ["Same saveDir restriction as download.add, applied to defaults and to every item."],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["items"],
|
||||
"properties": {
|
||||
"items": { "type": "array", "minItems": 1, "maxItems": 5000, "items": { "$ref": "https://velox.dev/schema/types/DownloadSpec.schema.json" } },
|
||||
"defaults": { "oneOf": [{ "$ref": "https://velox.dev/schema/types/DownloadSpec.schema.json" }, { "type": "null" }], "description": "Applied to any field an item left unset. Its url is ignored." }
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["taskIds", "failed"],
|
||||
"properties": {
|
||||
"taskIds": { "type": "array", "items": { "type": "string", "format": "uuid" }, "description": "In the same order as the accepted items." },
|
||||
"failed": {
|
||||
"type": "array",
|
||||
"description": "One entry per item that could not be added. index refers to params.items.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["index", "code", "message"],
|
||||
"properties": {
|
||||
"index": { "type": "integer", "minimum": 0 },
|
||||
"code": { "$ref": "https://velox.dev/schema/types/ErrorCode.schema.json" },
|
||||
"message": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/download.cancel.schema.json",
|
||||
"title": "download.cancel",
|
||||
"description": "Stop the given tasks and mark them cancelled. The .veloxpart file is kept so the user can still resume from the list; download.remove is what deletes bytes.",
|
||||
"x-privileged": false,
|
||||
"x-transports": [
|
||||
"uds",
|
||||
"ws"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32010
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"taskIds"
|
||||
],
|
||||
"properties": {
|
||||
"taskIds": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 5000,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"$ref": "https://velox.dev/schema/types/BulkTaskResult.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/download.get.schema.json",
|
||||
"title": "download.get",
|
||||
"description": "Full detail for one task, including per-segment state. Backs the progress dialog. Poll it no faster than the progress dialog repaints; the table must use events instead.",
|
||||
"x-privileged": false,
|
||||
"x-transports": ["uds", "ws"],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [-32010],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["taskId"],
|
||||
"properties": { "taskId": { "type": "string", "format": "uuid" } }
|
||||
},
|
||||
"result": { "$ref": "https://velox.dev/schema/types/TaskDetail.schema.json" }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/download.list.schema.json",
|
||||
"title": "download.list",
|
||||
"description": "The main table. Filtering, sorting and paging all happen in the daemon so the GUI never materializes 100k rows to show 40. Called once on connect; after that the table is maintained from events, never re-fetched on a progress tick.",
|
||||
"x-privileged": false,
|
||||
"x-transports": ["uds", "ws"],
|
||||
"x-deadlineMs": 5000,
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"filter": { "oneOf": [{ "$ref": "https://velox.dev/schema/types/TaskFilter.schema.json" }, { "type": "null" }] },
|
||||
"sort": { "oneOf": [{ "$ref": "https://velox.dev/schema/types/TaskSort.schema.json" }, { "type": "null" }] },
|
||||
"offset": { "type": ["integer", "null"], "minimum": 0 },
|
||||
"limit": { "type": ["integer", "null"], "minimum": 1, "maximum": 5000, "description": "Defaults to 500. The GUI pages; the extension popup asks for far fewer." }
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["total", "items"],
|
||||
"properties": {
|
||||
"total": { "type": "integer", "minimum": 0, "description": "Rows matching the filter, ignoring offset and limit." },
|
||||
"items": { "type": "array", "items": { "$ref": "https://velox.dev/schema/types/TaskSummary.schema.json" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/download.pause.schema.json",
|
||||
"title": "download.pause",
|
||||
"description": "Suspend transfers and flush every segment's progress to the .veloxpart.meta file, so a pause is indistinguishable from a crash as far as resume is concerned. Never loses bytes already written.",
|
||||
"x-privileged": false,
|
||||
"x-transports": [
|
||||
"uds",
|
||||
"ws"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32010
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"taskIds"
|
||||
],
|
||||
"properties": {
|
||||
"taskIds": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 5000,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"$ref": "https://velox.dev/schema/types/BulkTaskResult.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/download.probe.schema.json",
|
||||
"title": "download.probe",
|
||||
"description": "Ask what is at a URL without creating a task. Populates the File Info dialog. Runs a HEAD, falling back to a ranged GET when HEAD is refused, which is also how resumability is established. Never blocks the RPC loop; the dialog opens immediately and fills in when this lands.",
|
||||
"x-privileged": false,
|
||||
"x-transports": ["uds", "ws"],
|
||||
"x-deadlineMs": 30000,
|
||||
"x-errors": [-32013],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["url"],
|
||||
"properties": {
|
||||
"url": { "type": "string", "format": "uri" },
|
||||
"headers": { "oneOf": [{ "$ref": "https://velox.dev/schema/types/Headers.schema.json" }, { "type": "null" }] },
|
||||
"cookies": { "type": ["array", "null"], "items": { "$ref": "https://velox.dev/schema/types/Cookie.schema.json" } },
|
||||
"referrer": { "type": ["string", "null"] },
|
||||
"userAgent": { "type": ["string", "null"] }
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["filename", "mime", "resumable", "effectiveUrl", "suggestedCategoryId"],
|
||||
"properties": {
|
||||
"filename": { "type": "string", "description": "From Content-Disposition when present, else the URL path, sanitized." },
|
||||
"sizeBytes": { "type": ["integer", "null"], "minimum": 0 },
|
||||
"mime": { "type": "string" },
|
||||
"resumable": { "type": "boolean", "description": "Accept-Ranges: bytes and a validator (ETag or Last-Modified) are both present." },
|
||||
"effectiveUrl": { "type": "string", "format": "uri" },
|
||||
"suggestedCategoryId": { "type": "string", "description": "What the rules engine would pick. The dialog preselects it; the user may override." },
|
||||
"suggestedSaveDir": { "type": ["string", "null"] },
|
||||
"etag": { "type": ["string", "null"] },
|
||||
"lastModified": { "type": ["string", "null"] },
|
||||
"acceptRanges": { "type": "boolean" },
|
||||
"redirectChain": { "type": "array", "items": { "type": "string", "format": "uri" }, "description": "Every hop, so the user can see where a shortener actually led." },
|
||||
"requiresAuth": { "type": "boolean", "description": "The probe got a 401/407. The GUI should collect credentials before adding." }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/download.refreshUrl.schema.json",
|
||||
"title": "download.refreshUrl",
|
||||
"description": "IDM's 'Refresh Download Address'. Point an existing task at a freshly-issued URL when a signed link has expired, keeping every byte already on disk. The daemon re-probes and compares size and validator: if they still match, the transfer resumes from where it stopped; if they do not, it says so rather than silently restarting.",
|
||||
"x-privileged": false,
|
||||
"x-transports": ["uds", "ws"],
|
||||
"x-deadlineMs": 30000,
|
||||
"x-errors": [-32010, -32013],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["taskId", "url"],
|
||||
"properties": {
|
||||
"taskId": { "type": "string", "format": "uuid" },
|
||||
"url": { "type": "string", "format": "uri" },
|
||||
"headers": { "oneOf": [{ "$ref": "https://velox.dev/schema/types/Headers.schema.json" }, { "type": "null" }] },
|
||||
"cookies": { "type": ["array", "null"], "items": { "$ref": "https://velox.dev/schema/types/Cookie.schema.json" } }
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["ok", "resumable", "contentChanged"],
|
||||
"properties": {
|
||||
"ok": { "type": "boolean" },
|
||||
"resumable": { "type": "boolean" },
|
||||
"contentChanged": { "type": "boolean", "description": "true when size or validator differ from what was recorded. The GUI must ask before restarting from zero — never discard bytes without consent." },
|
||||
"sizeBytes": { "type": ["integer", "null"], "minimum": 0 },
|
||||
"effectiveUrl": { "type": ["string", "null"], "format": "uri" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/download.remove.schema.json",
|
||||
"title": "download.remove",
|
||||
"description": "Drop tasks from the list, optionally deleting the bytes on disk. Privileged: this is the only method that destroys user data, and the extension is never allowed to reach it. The daemon deletes the .veloxpart and .veloxpart.meta pair, and the finished file only when deleteFile is true.",
|
||||
"x-privileged": true,
|
||||
"x-transports": ["uds"],
|
||||
"x-deadlineMs": 10000,
|
||||
"x-errors": [-32003, -32010],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["taskIds", "deleteFile"],
|
||||
"properties": {
|
||||
"taskIds": { "type": "array", "minItems": 1, "maxItems": 5000, "items": { "type": "string", "format": "uuid" } },
|
||||
"deleteFile": { "type": "boolean", "description": "Explicit and required — there is no default for deleting a user's file." }
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["removed", "failed"],
|
||||
"properties": {
|
||||
"removed": { "type": "array", "items": { "type": "string", "format": "uuid" } },
|
||||
"failed": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["taskId", "code", "message"],
|
||||
"properties": {
|
||||
"taskId": { "type": "string", "format": "uuid" },
|
||||
"code": { "$ref": "https://velox.dev/schema/types/ErrorCode.schema.json" },
|
||||
"message": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/download.resume.schema.json",
|
||||
"title": "download.resume",
|
||||
"description": "Continue paused tasks. Resumption is revalidated with If-Range against the stored ETag or Last-Modified; a 200 where 206 was expected means the file changed on the server, and the task moves to failed with a clear error rather than corrupting the part file.",
|
||||
"x-privileged": false,
|
||||
"x-transports": [
|
||||
"uds",
|
||||
"ws"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32010
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"taskIds"
|
||||
],
|
||||
"properties": {
|
||||
"taskIds": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 5000,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"$ref": "https://velox.dev/schema/types/BulkTaskResult.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/download.start.schema.json",
|
||||
"title": "download.start",
|
||||
"description": "Begin or restart the given tasks. A task in 'queued' jumps its queue; a task already downloading is a no-op reported as changed false.",
|
||||
"x-privileged": false,
|
||||
"x-transports": [
|
||||
"uds",
|
||||
"ws"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32010
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"taskIds"
|
||||
],
|
||||
"properties": {
|
||||
"taskIds": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"maxItems": 5000,
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"$ref": "https://velox.dev/schema/types/BulkTaskResult.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/download.update.schema.json",
|
||||
"title": "download.update",
|
||||
"description": "Change a task's mutable fields. Moving saveDir or filename moves the file on disk in the same operation, which is what makes dragging a row onto a category work as one RPC. Privileged: it can name a destination path.",
|
||||
"x-privileged": true,
|
||||
"x-transports": ["uds"],
|
||||
"x-deadlineMs": 30000,
|
||||
"x-errors": [-32003, -32010, -32011],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["taskId", "patch"],
|
||||
"properties": {
|
||||
"taskId": { "type": "string", "format": "uuid" },
|
||||
"patch": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "Only the present fields change. An explicit null clears a nullable field.",
|
||||
"properties": {
|
||||
"filename": { "type": ["string", "null"], "maxLength": 255 },
|
||||
"saveDir": { "type": ["string", "null"] },
|
||||
"categoryId": { "type": ["string", "null"] },
|
||||
"queueId": { "type": ["string", "null"] },
|
||||
"description": { "type": ["string", "null"], "maxLength": 1024 },
|
||||
"segments": { "type": ["integer", "null"], "minimum": 1, "maximum": 32, "description": "Takes effect on the next start; a running task is not re-segmented underneath the user." },
|
||||
"bufferBytes": { "type": ["integer", "null"], "minimum": 4096, "maximum": 8388608 },
|
||||
"checksum": { "oneOf": [{ "$ref": "https://velox.dev/schema/types/Checksum.schema.json" }, { "type": "null" }] }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": { "$ref": "https://velox.dev/schema/types/TaskSummary.schema.json" }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/grabber.harvest.schema.json",
|
||||
"title": "grabber.harvest",
|
||||
"description": "Turn selected crawl results into tasks. This is the only grabber call that creates downloads, and it names exactly the files the user ticked \u2014 a crawl never starts a download on its own.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 30000,
|
||||
"x-errors": [
|
||||
-32003,
|
||||
-32011
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"jobId",
|
||||
"select"
|
||||
],
|
||||
"properties": {
|
||||
"jobId": {
|
||||
"type": "string"
|
||||
},
|
||||
"select": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "fileIds from grabber.status."
|
||||
},
|
||||
"defaults": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "https://velox.dev/schema/types/DownloadSpec.schema.json"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"taskIds",
|
||||
"failed"
|
||||
],
|
||||
"properties": {
|
||||
"taskIds": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
},
|
||||
"failed": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"fileId",
|
||||
"code",
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"fileId": {
|
||||
"type": "string"
|
||||
},
|
||||
"code": {
|
||||
"$ref": "https://velox.dev/schema/types/ErrorCode.schema.json"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/grabber.start.schema.json",
|
||||
"title": "grabber.start",
|
||||
"description": "Start a depth-limited crawl. Nothing is downloaded by this call: it only walks pages and collects candidate links, which the wizard then shows for selection. Privileged because an unbounded crawl is a resource commitment the browser must not be able to make on the user's behalf.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32003
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"startUrl",
|
||||
"depth"
|
||||
],
|
||||
"properties": {
|
||||
"startUrl": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"depth": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 10
|
||||
},
|
||||
"includePatterns": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"excludePatterns": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"fileTypes": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Extensions, without the dot. null means every type."
|
||||
},
|
||||
"sameHostOnly": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"maxFiles": {
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"minimum": 1,
|
||||
"maximum": 10000
|
||||
},
|
||||
"headers": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "https://velox.dev/schema/types/Headers.schema.json"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"cookies": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "https://velox.dev/schema/types/Cookie.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"jobId"
|
||||
],
|
||||
"properties": {
|
||||
"jobId": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/grabber.status.schema.json",
|
||||
"title": "grabber.status",
|
||||
"description": "Poll one crawl. Also delivered as event.grabber.progress; the poll exists so the wizard can be reopened on a job it did not start and still catch up.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32003,
|
||||
-32602
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"jobId"
|
||||
],
|
||||
"properties": {
|
||||
"jobId": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"jobId",
|
||||
"state",
|
||||
"crawled",
|
||||
"found",
|
||||
"files"
|
||||
],
|
||||
"properties": {
|
||||
"jobId": {
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"crawling",
|
||||
"done",
|
||||
"failed",
|
||||
"cancelled"
|
||||
]
|
||||
},
|
||||
"crawled": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"found": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"files": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "https://velox.dev/schema/types/GrabberFile.schema.json"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/limiter.get.schema.json",
|
||||
"title": "limiter.get",
|
||||
"description": "Current global speed limit. Privileged: changing or reading the limiter belongs to the GUI and CLI; the extension shows throughput from event.speed.global instead.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 2000,
|
||||
"x-errors": [
|
||||
-32003
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
},
|
||||
"result": {
|
||||
"$ref": "https://velox.dev/schema/types/Limiter.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/limiter.set.schema.json",
|
||||
"title": "limiter.set",
|
||||
"description": "Set the global token-bucket limit. With applyToRunning true the change re-tunes transfers already in flight instead of taking effect only on the next task \u2014 the Speed Limiter window's 'apply now' button.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32003,
|
||||
-32602
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"$ref": "https://velox.dev/schema/types/Limiter.schema.json"
|
||||
},
|
||||
"result": {
|
||||
"$ref": "https://velox.dev/schema/types/Limiter.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/media.addVariant.schema.json",
|
||||
"title": "media.addVariant",
|
||||
"description": "Turn one enumerated variant into a task. The daemon fetches the segments in parallel and muxes them with ffmpeg; the result is an ordinary task that appears in the list like any other download. Refused with -32602 when the variant is DRM-protected.",
|
||||
"x-privileged": false,
|
||||
"x-transports": [
|
||||
"uds",
|
||||
"ws"
|
||||
],
|
||||
"x-deadlineMs": 30000,
|
||||
"x-errors": [
|
||||
-32011,
|
||||
-32602,
|
||||
-32013
|
||||
],
|
||||
"x-wsRestrictions": [
|
||||
"Same saveDir restriction as download.add."
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "spec carries the same destination and queueing fields as download.add; its url is ignored because the manifest and variant determine the source.",
|
||||
"required": [
|
||||
"manifestUrl",
|
||||
"variantId"
|
||||
],
|
||||
"properties": {
|
||||
"manifestUrl": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"variantId": {
|
||||
"type": "string"
|
||||
},
|
||||
"audioVariantId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"description": "For DASH and HLS renditions where audio is a separate track to be muxed in."
|
||||
},
|
||||
"spec": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "https://velox.dev/schema/types/DownloadSpec.schema.json"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"taskId",
|
||||
"state"
|
||||
],
|
||||
"properties": {
|
||||
"taskId": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"state": {
|
||||
"$ref": "https://velox.dev/schema/types/TaskState.schema.json"
|
||||
},
|
||||
"estimatedBytes": {
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
],
|
||||
"minimum": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/media.listVariants.schema.json",
|
||||
"title": "media.listVariants",
|
||||
"description": "Parse an HLS or DASH manifest in the daemon and enumerate its renditions. The extension never parses a manifest \u2014 that logic lives in one language, in one place. Variants with drm true are reported so the UI can grey them out; DRM-protected streams are refused, not attempted.",
|
||||
"x-privileged": false,
|
||||
"x-transports": [
|
||||
"uds",
|
||||
"ws"
|
||||
],
|
||||
"x-deadlineMs": 30000,
|
||||
"x-errors": [
|
||||
-32013
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"manifestUrl"
|
||||
],
|
||||
"properties": {
|
||||
"manifestUrl": {
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"headers": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "https://velox.dev/schema/types/Headers.schema.json"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"cookies": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "https://velox.dev/schema/types/Cookie.schema.json"
|
||||
}
|
||||
},
|
||||
"referrer": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"variants",
|
||||
"manifestType",
|
||||
"drmProtected"
|
||||
],
|
||||
"properties": {
|
||||
"variants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "https://velox.dev/schema/types/MediaVariant.schema.json"
|
||||
}
|
||||
},
|
||||
"manifestType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"hls",
|
||||
"dash"
|
||||
]
|
||||
},
|
||||
"durationSec": {
|
||||
"type": [
|
||||
"number",
|
||||
"null"
|
||||
],
|
||||
"minimum": 0
|
||||
},
|
||||
"title": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"drmProtected": {
|
||||
"type": "boolean",
|
||||
"description": "The manifest as a whole is DRM-protected. Refuse with a clear message rather than downloading undecryptable segments."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/queue.list.schema.json",
|
||||
"title": "queue.list",
|
||||
"description": "Every queue with its run state and ordering. Not privileged: the extension's 'Add to Queue' picker needs it.",
|
||||
"x-privileged": false,
|
||||
"x-transports": [
|
||||
"uds",
|
||||
"ws"
|
||||
],
|
||||
"x-deadlineMs": 2000,
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "https://velox.dev/schema/types/Queue.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/queue.reorder.schema.json",
|
||||
"title": "queue.reorder",
|
||||
"description": "Rewrite a queue's run order. taskIds must be a permutation of the queue's current membership; anything else is -32602 rather than a partial reorder, so a stale drag from an out-of-date view cannot quietly reshuffle the queue.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32003,
|
||||
-32602
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"queueId",
|
||||
"taskIds"
|
||||
],
|
||||
"properties": {
|
||||
"queueId": {
|
||||
"type": "string"
|
||||
},
|
||||
"taskIds": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"queue"
|
||||
],
|
||||
"properties": {
|
||||
"queue": {
|
||||
"$ref": "https://velox.dev/schema/types/Queue.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/queue.start.schema.json",
|
||||
"title": "queue.start",
|
||||
"description": "Start a queue running. The scheduler then admits up to maxConcurrent tasks from it, in order, and keeps that many running until the queue drains or is stopped.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32003
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"queueId"
|
||||
],
|
||||
"properties": {
|
||||
"queueId": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"queue",
|
||||
"startedTaskIds"
|
||||
],
|
||||
"properties": {
|
||||
"queue": {
|
||||
"$ref": "https://velox.dev/schema/types/Queue.schema.json"
|
||||
},
|
||||
"startedTaskIds": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/queue.stop.schema.json",
|
||||
"title": "queue.stop",
|
||||
"description": "Stop admitting new tasks from a queue. Tasks already running are paused when pauseRunning is true, and otherwise allowed to finish \u2014 the difference between 'stop the queue' and 'stop everything', which IDM conflates and users trip over.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32003
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"queueId"
|
||||
],
|
||||
"properties": {
|
||||
"queueId": {
|
||||
"type": "string"
|
||||
},
|
||||
"pauseRunning": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"queue",
|
||||
"pausedTaskIds"
|
||||
],
|
||||
"properties": {
|
||||
"queue": {
|
||||
"$ref": "https://velox.dev/schema/types/Queue.schema.json"
|
||||
},
|
||||
"pausedTaskIds": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/queue.upsert.schema.json",
|
||||
"title": "queue.upsert",
|
||||
"description": "Create or replace a queue, including its schedule and concurrency cap. Omit queueId to create. taskIds in the payload is ignored \u2014 membership changes through download.update and queue.reorder so that two clients editing at once cannot silently drop a task.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32003
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"queue"
|
||||
],
|
||||
"properties": {
|
||||
"queue": {
|
||||
"$ref": "https://velox.dev/schema/types/Queue.schema.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"queue"
|
||||
],
|
||||
"properties": {
|
||||
"queue": {
|
||||
"$ref": "https://velox.dev/schema/types/Queue.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/rules.list.schema.json",
|
||||
"title": "rules.list",
|
||||
"description": "The rules engine's table, in priority order. Privileged: these are the daemon's routing policy. The extension gets its own narrowed view through capture.getRules instead.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 2000,
|
||||
"x-errors": [
|
||||
-32003
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "https://velox.dev/schema/types/Rule.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/rules.upsert.schema.json",
|
||||
"title": "rules.upsert",
|
||||
"description": "Create, replace, or delete rules in one atomic write. 'upsert' carries the rules to store and 'remove' the ruleIds to drop; applying both at once means a reprioritisation never leaves the table in a half-valid state.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32003
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"upsert"
|
||||
],
|
||||
"properties": {
|
||||
"upsert": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "https://velox.dev/schema/types/Rule.schema.json"
|
||||
}
|
||||
},
|
||||
"remove": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "The full table after the write, in priority order.",
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "https://velox.dev/schema/types/Rule.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/schedule.get.schema.json",
|
||||
"title": "schedule.get",
|
||||
"description": "The schedule for one queue, or every schedule when queueId is null. Backs the Scheduler window.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 2000,
|
||||
"x-errors": [
|
||||
-32003
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"queueId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"properties": {
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"queueId",
|
||||
"schedule"
|
||||
],
|
||||
"properties": {
|
||||
"queueId": {
|
||||
"type": "string"
|
||||
},
|
||||
"schedule": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "https://velox.dev/schema/types/Schedule.schema.json"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/schedule.set.schema.json",
|
||||
"title": "schedule.set",
|
||||
"description": "Set or clear a queue's schedule. A null schedule clears it and leaves the queue under manual control. Times are local wall-clock and are re-evaluated on a DST change rather than being resolved to absolute instants at set time.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32003,
|
||||
-32602
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"queueId",
|
||||
"schedule"
|
||||
],
|
||||
"properties": {
|
||||
"queueId": {
|
||||
"type": "string"
|
||||
},
|
||||
"schedule": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "https://velox.dev/schema/types/Schedule.schema.json"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"queueId",
|
||||
"schedule"
|
||||
],
|
||||
"properties": {
|
||||
"queueId": {
|
||||
"type": "string"
|
||||
},
|
||||
"schedule": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "https://velox.dev/schema/types/Schedule.schema.json"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"nextRunAt": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/session.hello.schema.json",
|
||||
"title": "session.hello",
|
||||
"description": "First call on every connection, on every transport. The daemon compares protocolVersion majors and refuses a mismatch with -32001 so a stale GUI or extension fails loudly on connect instead of subtly at the tenth field. On the WebSocket transport a valid token is required unless the client is about to call session.pair.",
|
||||
"x-privileged": false,
|
||||
"x-transports": ["uds", "ws"],
|
||||
"x-deadlineMs": 2000,
|
||||
"x-errors": [-32001, -32002],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["clientType", "clientName", "protocolVersion"],
|
||||
"properties": {
|
||||
"clientType": { "type": "string", "enum": ["gui", "cli", "extension", "nmhost", "test"] },
|
||||
"clientName": { "type": "string", "maxLength": 64, "description": "Human-readable, shown in the pairing prompt and the logs." },
|
||||
"protocolVersion": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(-[0-9A-Za-z.-]+)?$" },
|
||||
"token": { "type": ["string", "null"], "description": "Required on the WebSocket transport once paired. Ignored on the Unix socket, where SO_PEERCRED is the authorization." }
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["daemonVersion", "protocolVersion", "capabilities", "sessionId"],
|
||||
"properties": {
|
||||
"daemonVersion": { "type": "string" },
|
||||
"protocolVersion": { "type": "string" },
|
||||
"capabilities": { "type": "array", "items": { "type": "string" }, "description": "Optional features this build has, e.g. 'media', 'grabber', 'secretservice'. A client must degrade gracefully when one is absent rather than assuming it." },
|
||||
"sessionId": { "type": "string", "format": "uuid" },
|
||||
"transport": { "type": "string", "enum": ["uds", "ws"], "description": "How the daemon sees this connection. Lets a client know up front which privileged methods will be refused." }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/session.pair.schema.json",
|
||||
"title": "session.pair",
|
||||
"description": "WebSocket transport only. Triggers a GUI or desktop-notification prompt showing a four-digit code; the user must approve before a token is issued. Failed attempts are rate-limited to 5/min followed by a 60 s lockout (-32014) so a token cannot be brute-forced by another local process. The daemon stores only a hash of the token.",
|
||||
"x-privileged": false,
|
||||
"x-transports": ["ws"],
|
||||
"x-deadlineMs": 120000,
|
||||
"x-errors": [-32003, -32014],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["clientName", "extensionId"],
|
||||
"properties": {
|
||||
"clientName": { "type": "string", "maxLength": 64 },
|
||||
"extensionId": { "type": "string", "description": "The moz-extension origin UUID. Must match the Origin header verified on the WS upgrade." },
|
||||
"code": { "type": ["string", "null"], "pattern": "^[0-9]{4}$", "description": "Set when the user typed the code into the extension's Options page instead of clicking Allow in the GUI." }
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["token", "expiresAt"],
|
||||
"properties": {
|
||||
"token": { "type": "string", "minLength": 43, "description": "256 bits, base64url. Stored by the extension in browser.storage.local and sent on every later connect." },
|
||||
"expiresAt": { "type": ["string", "null"], "format": "date-time", "description": "null means the token does not expire; it is revoked from Options -> Unpair." }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/session.subscribe.schema.json",
|
||||
"title": "session.subscribe",
|
||||
"description": "Choose which notifications this connection receives. Subscribing replaces the previous selection rather than adding to it, so a client can narrow its firehose without reconnecting. Nothing is delivered until this is called.",
|
||||
"x-privileged": false,
|
||||
"x-transports": ["uds", "ws"],
|
||||
"x-deadlineMs": 2000,
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["events"],
|
||||
"properties": {
|
||||
"events": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["event.task.added", "event.task.removed", "event.task.state",
|
||||
"event.task.progress", "event.speed.global", "event.auth.required",
|
||||
"event.notify", "event.settings.changed", "event.grabber.progress"]
|
||||
}
|
||||
},
|
||||
"taskIds": { "type": ["array", "null"], "items": { "type": "string", "format": "uuid" }, "description": "Narrow task events to these ids. The extension popup uses it to avoid receiving progress for downloads it is not showing. null means all tasks." }
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["ok", "events"],
|
||||
"properties": {
|
||||
"ok": { "type": "boolean" },
|
||||
"events": { "type": "array", "items": { "type": "string" }, "description": "Echoed back so a client can detect that it asked for an event this daemon does not emit." }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/settings.get.schema.json",
|
||||
"title": "settings.get",
|
||||
"description": "Read settings. keys null means everything. Privileged: the settings bag names local filesystem paths and the allowed write roots, which the extension has no business enumerating \u2014 it gets capture.getRules instead.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 2000,
|
||||
"x-errors": [
|
||||
-32003
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"keys": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "https://velox.dev/schema/types/SettingKey.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"values"
|
||||
],
|
||||
"properties": {
|
||||
"values": {
|
||||
"$ref": "https://velox.dev/schema/types/Settings.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://velox.dev/schema/methods/settings.set.schema.json",
|
||||
"title": "settings.set",
|
||||
"description": "Write settings. Only the keys present in values change. Rejected with -32602 if a key is unknown or a value fails the Settings schema, and with -32011 if a directory key names a path that cannot be written. Emits event.settings.changed with exactly the keys that took effect.",
|
||||
"x-privileged": true,
|
||||
"x-transports": [
|
||||
"uds"
|
||||
],
|
||||
"x-deadlineMs": 5000,
|
||||
"x-errors": [
|
||||
-32003,
|
||||
-32602,
|
||||
-32011
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"params": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"values"
|
||||
],
|
||||
"properties": {
|
||||
"values": {
|
||||
"$ref": "https://velox.dev/schema/types/Settings.schema.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "The stored values for the keys that were set, and the list of keys that actually changed.",
|
||||
"required": [
|
||||
"values",
|
||||
"changed"
|
||||
],
|
||||
"properties": {
|
||||
"values": {
|
||||
"$ref": "https://velox.dev/schema/types/Settings.schema.json"
|
||||
},
|
||||
"changed": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "https://velox.dev/schema/types/SettingKey.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user