@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 +10 -0
- package/README.md +8 -8
- package/dist/deepdock.js +6 -3
- package/package.json +2 -2
- package/skill/references/auth-and-keys.md +4 -3
- package/skill/references/cli.md +1 -1
- package/skill/references/clients/deepdock.py +2 -2
- package/skill/references/clients/deepdock.ts +9 -4
- package/skill/references/errors.md +4 -0
- package/skill/references/idempotency.md +1 -1
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.
|
|
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,
|
|
12153
|
-
|
|
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.
|
|
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:
|
|
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)
|
|
89
|
-
|
|
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
|
|
package/skill/references/cli.md
CHANGED
|
@@ -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", "
|
|
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(
|
|
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)
|