@deepdockai/cli 1.0.5 → 1.0.7

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,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.7
4
+
5
+ - The CLI knows `device_syncing` and `device_outdated` (exit code 3, retry later) instead of falling back on the HTTP status.
6
+ - The agent skill's error reference and both clients' pending-write helpers retry them with the same key.
7
+ - `--help`, the README and the skill's CLI and idempotency references list every exit-3 code, `outcome_unknown` and the access codes included.
8
+
9
+ ## 1.0.6
10
+
11
+ - The agent skill's TypeScript client types a device's `hostname`, `os` and `clientVersion` as `string | null`, as the API answers them before the device has reported them. The skill names `GET /v1/devices` and `GET /v1/devices/{deviceId}`.
12
+
3
13
  ## 1.0.5
4
14
 
5
15
  - The agent skill's clients: `systems()` is typed as the list of systems the API answers, and a paired `Device` lists its systems as objects, with `outdated` and a `claimedAt` that can be `null`.
package/README.md CHANGED
@@ -154,14 +154,14 @@ your code will receive; `auth`, `org select` and `keys create` build it from nam
154
154
  failure is one document on stderr, `{ "error": { "code", "message" }, "meta": { "hint" } }`,
155
155
  with the API's error object unchanged. Switch on `code` or on the exit code, never on `message`.
156
156
 
157
- | Exit | Meaning |
158
- | ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
159
- | 0 | done |
160
- | 1 | something on the command line to fix (`invalid_usage`, `org_required`) |
161
- | 2 | the API refused the request; do not repeat it unchanged (`invalid_request`, `not_found`, `forbidden`, `rate_limited` and the other refusals) |
162
- | 3 | retry later (`device_offline`, `action_paused`, `system_unavailable`, `target_busy`, `temporarily_unavailable`, `internal_error`, `connection_lost`) |
163
- | 4 | the CLI is too old for the API (`client_outdated`): run `npx @deepdockai/cli@latest` |
164
- | 5 | sign-in needed (`sign_in_needed`, `approval_denied`, `approval_expired`); `auth status` when nobody is signed in |
157
+ | Exit | Meaning |
158
+ | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
159
+ | 0 | done |
160
+ | 1 | something on the command line to fix (`invalid_usage`, `org_required`) |
161
+ | 2 | the API refused the request; do not repeat it unchanged (`invalid_request`, `not_found`, `forbidden`, `rate_limited` and the other refusals) |
162
+ | 3 | retry later (`device_offline`, `device_syncing`, `device_outdated`, `action_paused`, `access_outdated`, `access_missing`, `system_unavailable`, `target_busy`, `temporarily_unavailable`, `internal_error`, `outcome_unknown`, `connection_lost`) |
163
+ | 4 | the CLI is too old for the API (`client_outdated`): run `npx @deepdockai/cli@latest` |
164
+ | 5 | sign-in needed (`sign_in_needed`, `approval_denied`, `approval_expired`); `auth status` when nobody is signed in |
165
165
 
166
166
  The CLI never retries on its own: exit 3 says retry, you decide when. `deepdock commands --json`
167
167
  prints the whole command tree.
package/dist/deepdock.js CHANGED
@@ -10872,6 +10872,8 @@ var EXIT_CODES = {
10872
10872
  record_not_editable: 2,
10873
10873
  payload_too_large: 2,
10874
10874
  device_offline: 3,
10875
+ device_syncing: 3,
10876
+ device_outdated: 3,
10875
10877
  action_paused: 3,
10876
10878
  access_outdated: 3,
10877
10879
  access_missing: 3,
@@ -11424,7 +11426,7 @@ import { spawn } from "node:child_process";
11424
11426
  import { homedir, hostname } from "node:os";
11425
11427
 
11426
11428
  // src/version.ts
11427
- var VERSION = "1.0.5";
11429
+ var VERSION = "1.0.7";
11428
11430
 
11429
11431
  // src/runtime.ts
11430
11432
  var DEFAULT_BASE_URL = "https://api.deepdock.ai";
@@ -12149,8 +12151,9 @@ var EXIT_CODES_HELP = `Exit codes
12149
12151
  0 done
12150
12152
  1 usage: something on the command line to fix (invalid_usage, org_required)
12151
12153
  2 the API refused the request; do not repeat it unchanged
12152
- 3 retry later (device_offline, action_paused, system_unavailable, target_busy,
12153
- temporarily_unavailable, internal_error, connection_lost)
12154
+ 3 retry later (device_offline, device_syncing, device_outdated, action_paused,
12155
+ access_outdated, access_missing, system_unavailable, target_busy,
12156
+ temporarily_unavailable, internal_error, outcome_unknown, connection_lost)
12154
12157
  4 the CLI is too old for the API (client_outdated)
12155
12158
  5 sign-in needed (sign_in_needed, approval_denied, approval_expired; auth status when nobody is signed in)
12156
12159
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepdockai/cli",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
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",
@@ -30,7 +30,7 @@
30
30
  "lint": "biome lint .",
31
31
  "lint:fix": "biome lint --write .",
32
32
  "typecheck": "tsc --noEmit",
33
- "gen:codes": "bun scripts/genCodes.ts",
33
+ "gen:devices": "bun scripts/genDevices.ts",
34
34
  "check:public": "bun scripts/checkPublic.ts --pack",
35
35
  "test": "bun run build && bun --bun vitest run",
36
36
  "test:node": "vitest run",
@@ -84,9 +84,10 @@ curl -X POST "$BASE/v1/devices" \
84
84
  ```
85
85
 
86
86
  `label` is optional, 1 to 100 characters. The device must be online. Answer: `201` with the device
87
- (`id`, `label`, `hostname`, `os`, `clientVersion`, `status`, `lastSeenAt`, `claimedAt`, `systems`,
88
- and `updateAvailable` when it runs an older build). Keep `id`: it is the `deviceId` of every later
89
- call, and there is no `/v1` call to list devices (use `deepdock devices list` or the dashboard).
87
+ (`id`, `label`, `hostname`, `os`, `clientVersion`, `status`, `lastSeenAt`, `claimedAt`, `outdated`, `systems`,
88
+ and `updateAvailable` when it runs an older build); `hostname`, `os` and `clientVersion` are `null`
89
+ until the device has reported them. Keep `id`: it is the `deviceId` of every later call.
90
+ `GET /v1/devices` lists your devices and `GET /v1/devices/{deviceId}` reads one, in the same shape.
90
91
 
91
92
  4. Release with `DELETE /v1/devices/{deviceId}`; the device then shows a new code.
92
93
 
@@ -84,7 +84,7 @@ A failure is one document on stderr: the API's error object unchanged plus what
84
84
  | 0 | done | |
85
85
  | 1 | something on the command line to fix | `invalid_usage` (a bad flag, an unknown slug, a question with no terminal and no `--yes`, an env file git does not ignore), `org_required` |
86
86
  | 2 | the API refused the request; do not repeat it unchanged | `invalid_request`, `not_found`, `device_not_found`, `pairing_code_invalid`, `other_partner_build`, `rate_limited`, `forbidden`, `conflict` and the other refusals (not `access_outdated` and `access_missing`, see exit 3) |
87
- | 3 | retry later (`access_outdated` and `access_missing`: after the customer repeats "Erneut einrichten" in the Deepdock client) | `device_offline`, `action_paused`, `access_outdated`, `access_missing`, `system_unavailable`, `target_busy`, `temporarily_unavailable`, `internal_error`, `connection_lost` |
87
+ | 3 | retry later (`access_outdated` and `access_missing`: after the customer repeats "Erneut einrichten" in the Deepdock client) | `device_offline`, `device_syncing`, `device_outdated`, `action_paused`, `access_outdated`, `access_missing`, `system_unavailable`, `target_busy`, `temporarily_unavailable`, `internal_error`, `outcome_unknown`, `connection_lost` |
88
88
  | 4 | the CLI is too old for the API: run `npx @deepdockai/cli@latest` | `client_outdated` |
89
89
  | 5 | sign-in needed: run `deepdock auth login` | `sign_in_needed`, `approval_denied`, `approval_expired` |
90
90
 
@@ -126,8 +126,8 @@ class Deepdock:
126
126
 
127
127
  CONFLICT_RETRIES = 5 # a running write finishes within seconds; beyond this, treat it as unknown
128
128
 
129
- RETRY_SAME_KEY = {"device_offline", "target_busy", "temporarily_unavailable", "internal_error",
130
- "action_paused", "system_unavailable"}
129
+ RETRY_SAME_KEY = {"device_offline", "device_syncing", "device_outdated", "target_busy",
130
+ "temporarily_unavailable", "internal_error", "action_paused", "system_unavailable"}
131
131
 
132
132
 
133
133
  @dataclass
@@ -46,9 +46,9 @@ export type SystemAccess = 'ok' | 'outdated' | 'missing' | 'not_set_up' | null
46
46
  export type Device = {
47
47
  id: string
48
48
  label: string | null
49
- hostname: string
50
- os: string
51
- clientVersion: string
49
+ hostname: string | null
50
+ os: string | null
51
+ clientVersion: string | null
52
52
  status: 'connected' | 'offline' | 'inactive'
53
53
  lastSeenAt: string | null
54
54
  claimedAt: string | null
@@ -58,6 +58,8 @@ export type Device = {
58
58
  systems: { system: string; version: string | null; status: SystemStatus; access: SystemAccess; reportedAt: string }[]
59
59
  }
60
60
 
61
+ export type PairBody = { code: string; label?: string }
62
+
61
63
  export type ActionState =
62
64
  | { action: string; state: 'active' }
63
65
  | { action: string; state: 'paused'; reason: 'structure_changed' | 'check_failed'; pausedAt: string }
@@ -199,11 +201,12 @@ export class Deepdock {
199
201
 
200
202
  /** Claims a device by the pairing code it shows. Keep the returned `id`. */
201
203
  async pair(code: string, label?: string): Promise<Device> {
204
+ const body: PairBody = label === undefined ? { code } : { code, label }
202
205
  return (
203
206
  await this.send<Device>('/v1/devices', {
204
207
  method: 'POST',
205
208
  headers: { 'Content-Type': 'application/json' },
206
- body: JSON.stringify(label === undefined ? { code } : { code, label }),
209
+ body: JSON.stringify(body),
207
210
  })
208
211
  ).data
209
212
  }
@@ -241,6 +244,8 @@ export const CONFLICT_RETRIES = 5
241
244
 
242
245
  const RETRY_SAME_KEY = new Set([
243
246
  'device_offline',
247
+ 'device_syncing',
248
+ 'device_outdated',
244
249
  'target_busy',
245
250
  'temporarily_unavailable',
246
251
  'internal_error',
@@ -54,6 +54,8 @@ dashboard-only.
54
54
  | Code | Status | Meaning | Retry | Show |
55
55
  |---|---|---|---|---|
56
56
  | `device_offline` | 503 | the device is not connected, is shutting down, or did not answer within 20 s. **A write may still have landed** | yes, with backoff (seconds to minutes); a write only with the same key | "the customer PC is offline; we will retry" |
57
+ | `device_syncing` | 503 | the device has not reported its Deepdock client yet (just paired, or its report did not come through); Deepdock asks it again. Nothing was written | yes, after `Retry-After` (5 s); a write with the same key | "the customer PC is connecting; retrying" |
58
+ | `device_outdated` | 409 | the device's Deepdock client is too old for this call. It updates itself when a newer version is released for your organisation, once nobody is signed in on the PC. Nothing was written | after the update (`outdated` on `GET /v1/devices/{deviceId}` turns `false`); retrying before it gets the same answer. A write keeps its key | "the Deepdock client on the customer PC needs an update" |
57
59
  | `action_paused` | 503 | the action is paused on the device (`GET .../systems` shows `reason`); only Deepdock resumes it | later, when `GET .../systems` shows it active; do not loop | "this feature is paused while Deepdock checks the customer system" |
58
60
  | `system_unavailable` | 503 | the customer's program is stopped or missing on the device | later; often resolves when the customer restarts the program | "the customer's software is not running" |
59
61
  | `target_busy` | 503 | the customer's system is busy or unreachable | yes, with backoff | "the customer's system is busy; retrying" |
@@ -95,6 +97,8 @@ const REACTION: Record<string, Reaction> = {
95
97
  access_outdated: 'wait-setup',
96
98
  access_missing: 'wait-setup',
97
99
  device_offline: 'retry-same-key',
100
+ device_syncing: 'retry-same-key',
101
+ device_outdated: 'retry-later',
98
102
  action_paused: 'wait-paused',
99
103
  system_unavailable: 'retry-later',
100
104
  target_busy: 'retry-same-key',
@@ -70,7 +70,7 @@ input, a status (`pending`, `sent`, `done`, `unknown`, `refused`) and the result
70
70
 
71
71
  ```
72
72
  pending ──send──▶ sent ──2xx (fresh or replayed)──────────────▶ done
73
- │ ──device_offline, timeout, network error, target_busy, temporarily_unavailable, internal_error ▶ sent (retry later, same key)
73
+ │ ──device_offline, device_syncing, device_outdated, timeout, network error, target_busy, temporarily_unavailable, internal_error ▶ sent (retry later, same key)
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)