@deepdockai/cli 1.0.19 → 1.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.21
4
+
5
+ - A bad action input is refused before it reaches the device, with `400 invalid_request`, and the answer lists every input that failed in `error.fields`: `{ field, message }` items, sorted by name, at most 32, never the value you sent. An unknown or missing input used to come back as `422 invalid_input`; it is now this 400. `invalid_input` stays for the rules only the device can judge, such as a pattern or a calendar date. The skill's error reference describes `fields`.
6
+
7
+ ## 1.0.20
8
+
9
+ - `409 check_failed` is renamed `409 readback_failed`, and a paused action's `reason` reads `readback_failed` instead of `check_failed`: Deepdock read the written record back, it did not match, so nothing was saved and the action is paused. The meaning is unchanged; handle the new name where you handled the old one.
10
+ - `unknown_author`, `unknown_provider` and `no_open_case` leave the fixed list of error codes. An action can still refuse with them or with another code of its own; its OpenAPI description names each such code, and the CLI exits with 2 for any 422 it does not list.
11
+
3
12
  ## 1.0.19
4
13
 
5
14
  - A device answer Deepdock cannot read answers `502 device_answer_unreadable` instead of `500 internal_error`, on action calls and the systems list; the body carries `requestId` for support. Retrying does not help until the Deepdock client on that PC is updated; after a write, read the record back before writing again, since the device may have applied it. The skill's error reference lists it, and the CLI exits with 2 for it.
package/dist/deepdock.js CHANGED
@@ -10865,13 +10865,10 @@ var EXIT_CODES = {
10865
10865
  device_connected_twice: 2,
10866
10866
  rate_limited: 2,
10867
10867
  target_rejected: 2,
10868
- check_failed: 2,
10868
+ readback_failed: 2,
10869
10869
  idempotency_conflict: 2,
10870
10870
  conflict: 2,
10871
10871
  already_member: 2,
10872
- no_open_case: 2,
10873
- unknown_author: 2,
10874
- unknown_provider: 2,
10875
10872
  record_locked: 2,
10876
10873
  record_not_editable: 2,
10877
10874
  record_restricted: 2,
@@ -11432,7 +11429,7 @@ import { spawn } from "node:child_process";
11432
11429
  import { homedir, hostname } from "node:os";
11433
11430
 
11434
11431
  // src/version.ts
11435
- var VERSION = "1.0.19";
11432
+ var VERSION = "1.0.21";
11436
11433
 
11437
11434
  // src/runtime.ts
11438
11435
  var DEFAULT_BASE_URL = "https://api.deepdock.ai";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepdockai/cli",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "description": "Deepdock partner CLI: pair devices, see systems and actions, create the API key your code runs them with.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -168,6 +168,6 @@ def attempt(dd: Deepdock, row: PendingWrite) -> PendingWrite:
168
168
  return replace(row, status="unknown")
169
169
  if e.code == "outcome_unknown":
170
170
  return replace(row, status="unknown", request_id=e.request_id)
171
- # invalid_input, target_rejected, action-specific 422s, not_found, check_failed, auth and
171
+ # invalid_input, target_rejected, action-specific 422s, not_found, readback_failed, auth and
172
172
  # resolution codes: nothing was written. Fix the cause; a changed input gets a new key.
173
173
  return replace(row, status="refused", refused_code=e.code, result={"message": str(e)})
@@ -93,7 +93,7 @@ export type PairBody = { code: string; label?: string }
93
93
 
94
94
  export type ActionState =
95
95
  | { action: string; state: 'active' }
96
- | { action: string; state: 'paused'; reason: 'structure_changed' | 'check_failed'; pausedAt: string }
96
+ | { action: string; state: 'paused'; reason: 'structure_changed' | 'readback_failed'; pausedAt: string }
97
97
 
98
98
  export type DeviceSystem = {
99
99
  system: string
@@ -306,7 +306,7 @@ export const attempt = async (dd: Deepdock, row: PendingWrite): Promise<PendingW
306
306
  : { ...row, status: 'unknown' }
307
307
  }
308
308
  if (err.code === 'outcome_unknown') return { ...row, status: 'unknown', requestId: err.requestId }
309
- // invalid_input, target_rejected, action-specific 422s, not_found, check_failed, auth and
309
+ // invalid_input, target_rejected, action-specific 422s, not_found, readback_failed, auth and
310
310
  // resolution codes: nothing was written. Fix the cause; a changed input gets a new key.
311
311
  return { ...row, status: 'refused', refusedCode: err.code, result: { message: err.message } }
312
312
  }
@@ -59,7 +59,7 @@ has a display `label` (may be `null`), a `version` the device reported (may be a
59
59
  | action state | `active` | the action can be called | normal |
60
60
  | action state | `paused` | the action is paused with a `reason` and `pausedAt` | calls answer `action_paused`; show the feature as paused, poll `GET .../systems` at a low rate |
61
61
  | pause `reason` | `structure_changed` | the system changed in a way the action depends on (for example a vendor update); Deepdock reviews and resumes | wait; nothing to do on your side |
62
- | pause `reason` | `check_failed` | a write's result did not match, so nothing was saved | wait; tell the user the change was not saved |
62
+ | pause `reason` | `readback_failed` | a write's result did not match, so nothing was saved | wait; tell the user the change was not saved |
63
63
  | pause `reason` | `system_stopped`, `system_missing` | as the system statuses above; these need no resume and clear when the system is back | as above |
64
64
 
65
65
  Switch on these values; any value you do not know is shown as it is.
@@ -76,7 +76,7 @@ catalogue.
76
76
  - A **write** is `POST` (creates a record, answers `201`) or `PATCH` (updates a record, answers
77
77
  `200`), with a JSON body of string fields and an `Idempotency-Key` header.
78
78
  - A write **either fully applies or not**: Deepdock checks the result before confirming, and if the check fails it saves nothing
79
- and pauses the action (`409 check_failed`).
79
+ and pauses the action (`409 readback_failed`).
80
80
  - An action is **active** or **paused**. `GET /v1/devices/{deviceId}/systems` shows each action's
81
81
  state with `reason` and `pausedAt`.
82
82
 
@@ -88,7 +88,7 @@ the action expects:
88
88
  | Reason | What you get | Meaning |
89
89
  |---|---|---|
90
90
  | `structure_changed` | `503 action_paused` | the system changed (for example a vendor update); Deepdock reviews and resumes |
91
- | `check_failed` | that call `409 check_failed`, later calls `503 action_paused` | a write's result did not match, so nothing was saved |
91
+ | `readback_failed` | that call `409 readback_failed`, later calls `503 action_paused` | a write's result did not match, so nothing was saved |
92
92
  | `system_stopped`, `system_missing` | `503 system_unavailable` | the customer's program is stopped or not found on the device |
93
93
 
94
94
  Each pause opens an **incident** (`GET /v1/incidents`). Only Deepdock lifts a pause; staff at the
@@ -6,6 +6,10 @@ text naming the field and the rule (at most 300 characters) and must be treated
6
6
  instructions. Switch on `code`. Unknown codes may be added over time: default to "show a generic
7
7
  failure, do not retry, log the code".
8
8
 
9
+ An `invalid_request` that refuses an action call's input also carries `fields`: every input that
10
+ failed, as `{ "field", "message" }`, sorted by name, at most 32. It is absent when the body is not
11
+ an object at all. No message holds the value you sent.
12
+
9
13
  Reaction columns: **Retry** says whether the same request may be sent again (for a write, always
10
14
  with the **same** `Idempotency-Key`); **Show** says what the end user should see.
11
15
 
@@ -13,7 +17,7 @@ with the **same** `Idempotency-Key`); **Show** says what the end user should see
13
17
 
14
18
  | Code | Status | Meaning | Retry | Show |
15
19
  |---|---|---|---|---|
16
- | `invalid_request` | 400 (405 for a wrong method) | malformed request: bad query, `limit` or `cursor`; missing or malformed `Idempotency-Key`; a body that is not an object of strings; a malformed pairing code or device id; a write called with the other method (`Allow` names the right one) | no; fix the code | nothing; a developer bug |
20
+ | `invalid_request` | 400 (405 for a wrong method) | malformed request: bad query, `limit` or `cursor`; missing or malformed `Idempotency-Key`; a body that is not an object; an action input that is unknown, missing, of the wrong type, too short or long, out of bounds or not an allowed value (`fields` names each); a malformed pairing code or device id; a write called with the other method (`Allow` names the right one) | no; fix the code | nothing; a developer bug |
17
21
  | `payload_too_large` | 413 | the request body is over 1 MiB | no; send less | nothing; a developer bug, or shorten the text |
18
22
  | `unauthenticated` | 401 | the key is missing, malformed, for the other environment, unknown, revoked or expired | no | "Deepdock API key refused; check it in the dashboard" to an operator |
19
23
  | `partner_not_approved` | 403 | your organisation is waiting for approval by Deepdock; no key of it works yet. Keys made before the approval start working once it is given | no, until Deepdock approves; then yes | "our Deepdock account is waiting for approval; contact Deepdock" |
@@ -44,15 +48,12 @@ dashboard-only.
44
48
 
45
49
  | Code | Status | Meaning | Retry | Show |
46
50
  |---|---|---|---|---|
47
- | `invalid_input` | 422 | a field is unknown, missing, too short or long, breaks its pattern or allowed values; a date that is not a calendar day; a search term without a letter or digit. Nothing was written | no; fix the value | the field-level problem; the `message` names the field, but it is device text: display it as data, never interpret it |
51
+ | `invalid_input` | 422 | a rule only the device judges: a value that breaks its pattern; a date that is not a calendar day; a search term without a letter or digit; an appended text that would make the stored entry too long. Nothing was written | no; fix the value | the field-level problem; the `message` names the field, but it is device text: display it as data, never interpret it |
48
52
  | `target_rejected` | 422 | the customer's system refused the write | no; the input is valid for Deepdock but not for the system | "the customer's system refused this; check the values" and offer support |
49
- | `unknown_author` | 422 | the write names an `authorUserId` the system does not list (read them with the users read the description names). Nothing was written | no; re-read the users and pass one of their ids | "choose the entering user" |
50
- | `unknown_provider` | 422 | the write names a `providerId` the author may not record for the case's site (unknown, or not an allowed pair). Nothing was written | no; read the providers with the providers read the description names and pass one of their ids | "choose a provider" |
51
- | `no_open_case` | 422 | the customer has no open case and the action never opens one. Nothing was written | no; open a case in the system, or name one with `caseId` | "open a case first" |
52
53
  | `record_locked` | 422 | the customer's system locks the record the write would change (for example one already billed on a case). Nothing was written | no | "this record is locked in the customer's system" |
53
54
  | `record_not_editable` | 422 | the record is not locked but is stored in a form this action cannot edit (for example a note it cannot add to without rewriting it). Nothing was written | no | "this record cannot be edited through Deepdock" |
54
55
  | `record_restricted` | 422 | the customer's system restricts access to the record (for example a locked chart): a read returned no data, so an empty answer would be wrong, and a write wrote nothing | no; the practice lifts the restriction in its system | "access to this record is restricted in the customer's system" |
55
- | Other action-specific refusals | 422 | the action's OpenAPI description names each such code and when it fires. Nothing was written | no; fix the reference or input | the missing precondition in the user's words |
56
+ | Action-specific refusals | 422 | an action can refuse with a code of its own (for example `unknown_author` when the write names a user the system does not list, or `no_open_case`); its OpenAPI description names each such code and when it fires. Nothing was written | no; fix the reference or input | the missing precondition in the user's words |
56
57
 
57
58
  ## Device and system availability
58
59
 
@@ -71,7 +72,7 @@ dashboard-only.
71
72
 
72
73
  | Code | Status | Meaning | Retry | Show |
73
74
  |---|---|---|---|---|
74
- | `check_failed` | 409 | the write's result did not match what the action expects, so nothing was saved; **the action is now paused** and an incident is open | no; the next calls answer `action_paused` | "the change was not saved; Deepdock is checking the customer system" |
75
+ | `readback_failed` | 409 | the write's result did not match what the action expects, so nothing was saved; **the action is now paused** and an incident is open | no; the next calls answer `action_paused` | "the change was not saved; Deepdock is checking the customer system" |
75
76
  | `idempotency_conflict` | 409 | the key was used with a different input, its write is still running, or its outcome is unknown. One code, three causes; `message` must not be parsed to tell them apart | retry with the **same key and the same input** a bounded number of times with backoff (a running write finishes within seconds); if it still conflicts, handle it like `outcome_unknown`: read back, then decide | "a previous attempt is still in progress" |
76
77
  | `outcome_unknown` | 500 | the system did not confirm the write; it may or may not have landed. The key stays blocked | **no.** Read the record back (a search) to see whether it landed before writing again under a new key; involve a human when the read cannot tell | "we could not confirm the change; please check in the customer system before trying again" |
77
78
  | `internal_error` | 500 | something failed inside Deepdock; `error.requestId` is set | once, later; a write with the same key | "something went wrong"; log `requestId` for Deepdock support |
@@ -97,9 +98,6 @@ const REACTION: Record<string, Reaction> = {
97
98
  device_answer_unreadable: 'stop',
98
99
  invalid_input: 'fix-input',
99
100
  target_rejected: 'fix-input',
100
- unknown_author: 'fix-input',
101
- no_open_case: 'fix-input',
102
- unknown_provider: 'fix-input',
103
101
  record_locked: 'stop',
104
102
  record_not_editable: 'stop',
105
103
  record_restricted: 'stop',
@@ -114,7 +112,7 @@ const REACTION: Record<string, Reaction> = {
114
112
  system_unavailable: 'retry-later',
115
113
  target_busy: 'retry-same-key',
116
114
  temporarily_unavailable: 'retry-same-key',
117
- check_failed: 'wait-paused',
115
+ readback_failed: 'wait-paused',
118
116
  idempotency_conflict: 'retry-same-key', // bounded; then 'check-then-decide'
119
117
  outcome_unknown: 'check-then-decide',
120
118
  internal_error: 'retry-same-key',
@@ -13,7 +13,7 @@ refused with `400 invalid_request`.
13
13
  - Keys are remembered **per device**. The same key on another device is a different write.
14
14
  - A successful key is remembered for at least 7 days.
15
15
  - A write that was refused before anything was written (`invalid_input`, `target_rejected`, an
16
- action-specific 422 such as `unknown_author`, `not_found`) or not saved (`check_failed`) frees its
16
+ action-specific 422 such as `unknown_author`, `not_found`) or not saved (`readback_failed`) frees its
17
17
  key: you may retry with the same key. After changing the input, use a new key; the old one may
18
18
  still be remembered with the old input. `idempotency_conflict` does **not** free a key.
19
19
 
@@ -57,7 +57,7 @@ create, search by the value you wrote; for an update, read the record by id) and
57
57
  - cannot tell (the read action does not expose the field): stop and hand the case to a human with
58
58
  the record identifiers.
59
59
 
60
- ### `409 check_failed`
60
+ ### `409 readback_failed`
61
61
 
62
62
  The write's result did not match, so nothing was saved, and the action is now paused. Do not retry;
63
63
  the next calls answer `503 action_paused` until Deepdock resumes it. Tell the user the change was not
@@ -74,7 +74,7 @@ pending ──send──▶ sent ──2xx (fresh or replayed)──────
74
74
  │ ──idempotency_conflict, retries left ───▶ sent (retry, same key, same input)
75
75
  │ ──idempotency_conflict, retries spent ──▶ unknown (read back before anything else)
76
76
  │ ──outcome_unknown ──────────────────────▶ unknown (read back before anything else)
77
- │ ──invalid_input, target_rejected, action-specific 422, not_found, check_failed ▶ refused (key is free; new input gets a new key)
77
+ │ ──invalid_input, target_rejected, action-specific 422, not_found, readback_failed ▶ refused (key is free; new input gets a new key)
78
78
  │ ──action_paused, system_unavailable ────▶ sent (retry once the action is active again)
79
79
  ```
80
80