@deepraxis/cli 0.2.0-dev.4c0c1e3 → 0.2.0-dev.a538fab

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/COMMANDS.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Generated by `bun run commands`. DO NOT EDIT.
4
4
 
5
- 421 HTTP operations; 423 commands including aliases.
5
+ 426 HTTP operations; 428 commands including aliases.
6
6
 
7
7
  Environment: `PRAXIS_ENV=develop|production` (dev package defaults to `develop`; stable package defaults to `production`). No `--env` option.
8
8
 
@@ -142,6 +142,11 @@ Handwritten commands: `login`, `logout`, `whoami`, `org list`, `org switch <orga
142
142
  | `praxis api automation action rollback <name>` | `automation.actions.rollback` | POST `/automation/v1/actions/{ns}/{name}/rollback` | `--action`, `--revision`, `--message` |
143
143
  | `praxis api automation action update <name>` | `automation.actions.update` | PUT `/automation/v1/actions/{ns}/{name}` | `--action`, `--dry-run`, `--description`, `--timeout-ms`, `--message` |
144
144
  | `praxis api automation hook send <token>` | `automation.hooks.send` | POST `/automation/v1/hooks/{trigger_id}/{token}` | `--hook` |
145
+ | `praxis api automation human-task cancel <id>` | `automation.humanTasks.cancel` | POST `/automation/v1/human-tasks/{id}/cancel` | `--reason` |
146
+ | `praxis api automation human-task delegate <id>` | `automation.humanTasks.delegate` | POST `/automation/v1/human-tasks/{id}/delegate` | `--to-user` |
147
+ | `praxis api automation human-task get <id>` | `automation.humanTasks.retrieve` | GET `/automation/v1/human-tasks/{id}` | |
148
+ | `praxis api automation human-task list` | `automation.humanTasks.list` | GET `/automation/v1/human-tasks` | `--param-limit`, `--param-cursor`, `--status`, `--run-id`, `--scope` |
149
+ | `praxis api automation human-task respond <id>` | `automation.humanTasks.respond` | POST `/automation/v1/human-tasks/{id}/respond` | `--action-id`, `--comment` |
145
150
  | `praxis api automation resolve get` | `automation.resolve.retrieve` | GET `/automation/v1/resolve` | `--target` |
146
151
  | `praxis api automation run artifact list` | `automation.runs.artifacts.list` | GET `/automation/v1/runs/{id}/artifacts` | `--run`, `--param-limit`, `--param-cursor` |
147
152
  | `praxis api automation run call list` | `automation.runs.calls.list` | GET `/automation/v1/runs/{id}/calls` | `--run`, `--param-limit`, `--param-cursor` |
package/dist/praxis.js CHANGED
@@ -4511,6 +4511,177 @@ file at the root of that directory.`
4511
4511
  fields: []
4512
4512
  }
4513
4513
  },
4514
+ {
4515
+ resource: "automation.humanTasks",
4516
+ method: "list",
4517
+ summary: "List human tasks",
4518
+ description: "List the human tasks that praxis/approval workflow steps opened, newest first. By default it returns only open tasks assigned to the caller: their approval inbox. scope=all lists every task of the organization, and status and run_id narrow the list. Use a returned id with retrieve for details and respond to decide. Read-only: listing never changes a task.",
4519
+ http: "GET",
4520
+ path: "/automation/v1/human-tasks",
4521
+ streaming: "no",
4522
+ pagination: true,
4523
+ pathParams: [],
4524
+ query: [
4525
+ {
4526
+ name: "limit",
4527
+ type: "integer",
4528
+ required: false,
4529
+ description: "Page size, 1–100, default 50."
4530
+ },
4531
+ {
4532
+ name: "cursor",
4533
+ type: "string",
4534
+ required: false,
4535
+ description: "The next_cursor of the previous page; omit for the first page."
4536
+ },
4537
+ {
4538
+ name: "status",
4539
+ type: "array",
4540
+ itemType: "string",
4541
+ enum: [
4542
+ "open",
4543
+ "completed",
4544
+ "expired",
4545
+ "cancelled"
4546
+ ],
4547
+ required: false,
4548
+ description: "Filter by status, comma-separated: open, completed, expired, cancelled. Defaults to open."
4549
+ },
4550
+ {
4551
+ name: "run_id",
4552
+ type: "string",
4553
+ required: false,
4554
+ description: "Only tasks opened by this run (run_)."
4555
+ },
4556
+ {
4557
+ name: "scope",
4558
+ type: "string",
4559
+ enum: [
4560
+ "assigned",
4561
+ "all"
4562
+ ],
4563
+ required: false,
4564
+ description: "assigned (default) lists only tasks assigned to the caller; all lists every task of the organization."
4565
+ }
4566
+ ]
4567
+ },
4568
+ {
4569
+ resource: "automation.humanTasks",
4570
+ method: "retrieve",
4571
+ summary: "Retrieve a human task",
4572
+ description: "Read one human task - title, Markdown body, context, actions, form, assignees, mode, due time, responses and outcome - so an assignee can choose an action and fill the form. Read-only; the Console approval page /automation/tasks/{id} reads the same resource.",
4573
+ http: "GET",
4574
+ path: "/automation/v1/human-tasks/{id}",
4575
+ streaming: "no",
4576
+ pagination: false,
4577
+ pathParams: [
4578
+ {
4579
+ name: "id",
4580
+ sdkName: "id",
4581
+ description: "Human task ID (htask_), from the list or the run's waits."
4582
+ }
4583
+ ],
4584
+ query: []
4585
+ },
4586
+ {
4587
+ resource: "automation.humanTasks",
4588
+ method: "cancel",
4589
+ summary: "Cancel a human task",
4590
+ description: "Cancel an open human task; only the person who started the run or an organization API key may cancel. The task becomes cancelled and the waiting workflow step raises a runtime error with code HUMAN_TASK_CANCELLED, which try/catch can catch. Open tasks are cancelled automatically when their run ends, so this call is not needed then.",
4591
+ http: "POST",
4592
+ path: "/automation/v1/human-tasks/{id}/cancel",
4593
+ streaming: "no",
4594
+ pagination: false,
4595
+ pathParams: [
4596
+ {
4597
+ name: "id",
4598
+ sdkName: "id",
4599
+ description: "Human task ID (htask_)."
4600
+ }
4601
+ ],
4602
+ query: [],
4603
+ body: {
4604
+ required: false,
4605
+ fields: [
4606
+ {
4607
+ name: "reason",
4608
+ type: "string",
4609
+ required: false,
4610
+ description: "Optional cancellation reason, at most 500 characters."
4611
+ }
4612
+ ]
4613
+ }
4614
+ },
4615
+ {
4616
+ resource: "automation.humanTasks",
4617
+ method: "delegate",
4618
+ summary: "Delegate a human task",
4619
+ description: "An assignee who has not responded hands their place to another user (to_user), replacing their entry in assignees.users in place, so sequential order is kept. The new user cannot already be an assignee, nor the initiator unless self-approval is allowed. The task must still be open.",
4620
+ http: "POST",
4621
+ path: "/automation/v1/human-tasks/{id}/delegate",
4622
+ streaming: "no",
4623
+ pagination: false,
4624
+ pathParams: [
4625
+ {
4626
+ name: "id",
4627
+ sdkName: "id",
4628
+ description: "Human task ID (htask_)."
4629
+ }
4630
+ ],
4631
+ query: [],
4632
+ body: {
4633
+ required: true,
4634
+ fields: [
4635
+ {
4636
+ name: "to_user",
4637
+ type: "string",
4638
+ required: true,
4639
+ description: "User ID taking over; cannot already be an assignee, nor the initiator unless self-approval is allowed."
4640
+ }
4641
+ ]
4642
+ }
4643
+ },
4644
+ {
4645
+ resource: "automation.humanTasks",
4646
+ method: "respond",
4647
+ summary: "Respond to a human task",
4648
+ description: "Submit an action (action_id), form values (values) and a comment as the calling user. Depending on the task's mode the response either decides it (status becomes completed, outcome is set, and the waiting workflow resumes with outcome as the step output) or is recorded while other assignees are awaited. When two assignees respond at once, exactly one decides and the other gets TASK_CLOSED. An agent may respond only if the workflow set allow_agent_decision. Send an Idempotency-Key to retry safely.",
4649
+ http: "POST",
4650
+ path: "/automation/v1/human-tasks/{id}/respond",
4651
+ streaming: "no",
4652
+ pagination: false,
4653
+ pathParams: [
4654
+ {
4655
+ name: "id",
4656
+ sdkName: "id",
4657
+ description: "Human task ID (htask_)."
4658
+ }
4659
+ ],
4660
+ query: [],
4661
+ body: {
4662
+ required: true,
4663
+ fields: [
4664
+ {
4665
+ name: "action_id",
4666
+ type: "string",
4667
+ required: true,
4668
+ description: "The chosen action ID from the task's actions, for example approve."
4669
+ },
4670
+ {
4671
+ name: "values",
4672
+ type: "object",
4673
+ required: false,
4674
+ description: "Any JSON object whose keys are strings and whose values are any JSON value."
4675
+ },
4676
+ {
4677
+ name: "comment",
4678
+ type: "string",
4679
+ required: false,
4680
+ description: "Comment of at most 4000 characters; required when the action has require_comment true."
4681
+ }
4682
+ ]
4683
+ }
4684
+ },
4514
4685
  {
4515
4686
  resource: "automation.resolve",
4516
4687
  method: "retrieve",
@@ -4691,7 +4862,7 @@ file at the root of that directory.`
4691
4862
  resource: "automation.runs",
4692
4863
  method: "create",
4693
4864
  summary: "Run a published target or execute draft source",
4694
- description: 'Execute a published script or workflow with target, or test unpublished code directly with source and language (ts for TypeScript, yaml for workflow YAML), without first saving or publishing a definition. Minimal script: `export default async ({ file_id }: { file_id: string }) => { const result = await call("ocr", { document: { type: "file", file_id } }); return result; }`; send it as source with language="ts", input={"file_id":"<uploaded file ID>"} and wait=0, using a PDF or image already uploaded to your account. To call a platform API directly in the same script, use the praxis SDK object, for example `praxis.model.ocr.create({ body: { model: "glm-ocr", document: { type: "file", file_id } } })`; Action IDs are strings passed to call(), not SDK methods such as praxis.ocr(...). praxis, call, invoke, console and codemode are module-scope bindings, not on globalThis, and need no import; invoke("namespace/name", input) starts a child run. target and source are mutually exclusive; target accepts ns/name@version, @tag or @range and defaults to latest when @ is omitted. Source/input validation precedes run creation, so a separate validate call is optional. input defaults to {} and must match the input schema and fit within 1 MiB. wait is 0–60 seconds (default 0): a terminal run returns 200, otherwise 202. Use the returned id with praxis.automation.runs.retrieve and inspect status, output and error; acceptance does not mean successful completion. For long-running, background or batch work, use wait: 0 and poll the run, or split work into child runs or a workflow; wait only controls the response wait and does not extend execution limits. Actions time out after 30 s (run-sandbox after 10 min); scripts have a 5 min wall-clock limit and a 30 s CPU limit; workflows default to 24 h and allow up to 7 days. Each run can start at most 100 child runs, with at most 20 active at once; nesting depth is limited to 10. Idempotency-Key is scoped to tenant, method and path for 24 hours, excluding wait from the fingerprint; replay returns the current run with Idempotent-Replayed: true, changed contents return 422 and an in-flight request returns 409. With language=yaml, source is a workflow YAML: the run input is . in the first step, and the shape is described in create workflow. Error details are in errors[] (pointer, detail, hint). New non-deterministic run IDs contain 78 characters, compared with 46 for legacy random IDs; treat IDs as opaque strings. Historical and deterministic IDs remain valid; same-millisecond order is not guaranteed.',
4865
+ description: 'Execute a published script or workflow with target, or test unpublished code directly with source and language (ts for TypeScript, yaml for workflow YAML), without first saving or publishing a definition. Minimal script: `export default async ({ file_id }: { file_id: string }) => { const result = await call("ocr", { document: { type: "file", file_id } }); return result; }`; send it as source with language="ts", input={"file_id":"<uploaded file ID>"} and wait=0, using a PDF or image already uploaded to your account. To call a platform API directly in the same script, use the praxis SDK object, for example `praxis.model.ocr.create({ body: { model: "glm-ocr", document: { type: "file", file_id } } })`; Action IDs are strings passed to call(), not SDK methods such as praxis.ocr(...). praxis, call, invoke, console and codemode are module-scope bindings, not on globalThis, and need no import; invoke("namespace/name", input) starts a child run. target and source are mutually exclusive; target accepts ns/name@version, @tag or @range and defaults to latest when @ is omitted. Source/input validation precedes run creation, so a separate validate call is optional. input defaults to {} and must match the input schema and fit within 1 MiB. wait is 0–60 seconds (default 0): a terminal run returns 200, otherwise 202. Use the returned id with praxis.automation.runs.retrieve and inspect status, output and error; acceptance does not mean successful completion. For long-running, background or batch work, use wait: 0 and poll the run, or split work into child runs or a workflow; wait only controls the response wait and does not extend execution limits. Actions time out after 30 s (run-sandbox after 10 min); scripts have a 5 min wall-clock limit and a 30 s CPU limit; workflows default to 24 h and allow up to 30 days. Each run can start at most 100 child runs, with at most 20 active at once; nesting depth is limited to 10. Idempotency-Key is scoped to tenant, method and path for 24 hours, excluding wait from the fingerprint; replay returns the current run with Idempotent-Replayed: true, changed contents return 422 and an in-flight request returns 409. With language=yaml, source is a workflow YAML: the run input is . in the first step, and the shape is described in create workflow. Error details are in errors[] (pointer, detail, hint). New non-deterministic run IDs contain 78 characters, compared with 46 for legacy random IDs; treat IDs as opaque strings. Historical and deterministic IDs remain valid; same-millisecond order is not guaranteed.',
4695
4866
  http: "POST",
4696
4867
  path: "/automation/v1/runs",
4697
4868
  streaming: "no",
@@ -6239,7 +6410,7 @@ file at the root of that directory.`
6239
6410
  resource: "automation.workflows",
6240
6411
  method: "create",
6241
6412
  summary: "Create a workflow",
6242
- description: 'Save a YAML workflow as an editable draft; this does not validate, publish or run it, so check it with validate (kind=workflow) first. Minimal draft: document with dsl ("1.0.3"), namespace, name and version, plus a do list of steps, for example document: {dsl: "1.0.3", namespace: demo, name: add, version: "1.0.0"} and do: [{first: {call: demo/add-one, with: {n: "${ .n }"}}}]. call: <ns/name> calls an Action directly (bare name for built-ins such as ocr) and with is the Action input; the input contract is at current_revision.input_schema in the get-action response. run: starts a saved script or child workflow. The run input is . in the first step, and expressions are jq written as a whole ${ ... } string. Limits: Action 30 s (run-sandbox 10 min), workflow 24 h by default and 7 days at most, payload 1 MiB. Test the draft by sending its source and language=yaml to praxis.automation.runs.create. Guide: /docs/developers/automation/guides/write-workflow. Error details are in the errors[] of the response (pointer, detail, hint). Choose your own namespace without registering it first; praxis is reserved for built-in Actions. Scripts and workflows share names within the tenant; a duplicate returns NAME_TAKEN. run.workflow accepts ns/name@range or {namespace, name, version, input}; run.script uses the same reference shape as a platform extension. Object namespace, name and version are required; version accepts an exact version, dist-tag or range, locked at publication. Object input defaults to {} and supports expressions; string references retain task-level with. run.await defaults to true and returns the child output. With false, the child uses detach and the task immediately returns {run_id}; parent cancellation does not cascade. Inline script.code returns DEFINITION_INVALID with a detail asking you to save a script and reference it first. raise.error retains its type URI, status, title and detail in the run error.',
6413
+ description: 'Save a YAML workflow as an editable draft; this does not validate, publish or run it, so check it with validate (kind=workflow) first. Minimal draft: document with dsl ("1.0.3"), namespace, name and version, plus a do list of steps, for example document: {dsl: "1.0.3", namespace: demo, name: add, version: "1.0.0"} and do: [{first: {call: demo/add-one, with: {n: "${ .n }"}}}]. call: <ns/name> calls an Action directly (bare name for built-ins such as ocr) and with is the Action input; the input contract is at current_revision.input_schema in the get-action response. run: starts a saved script or child workflow. The run input is . in the first step, and expressions are jq written as a whole ${ ... } string. Limits: Action 30 s (run-sandbox 10 min), workflow 24 h by default and 30 days at most, payload 1 MiB. Test the draft by sending its source and language=yaml to praxis.automation.runs.create. Guide: /docs/developers/automation/guides/write-workflow. Error details are in the errors[] of the response (pointer, detail, hint). Choose your own namespace without registering it first; praxis is reserved for built-in Actions. Scripts and workflows share names within the tenant; a duplicate returns NAME_TAKEN. run.workflow accepts ns/name@range or {namespace, name, version, input}; run.script uses the same reference shape as a platform extension. Object namespace, name and version are required; version accepts an exact version, dist-tag or range, locked at publication. Object input defaults to {} and supports expressions; string references retain task-level with. run.await defaults to true and returns the child output. With false, the child uses detach and the task immediately returns {run_id}; parent cancellation does not cascade. Inline script.code returns DEFINITION_INVALID with a detail asking you to save a script and reference it first. raise.error retains its type URI, status, title and detail in the run error.',
6243
6414
  http: "POST",
6244
6415
  path: "/automation/v1/workflows",
6245
6416
  streaming: "no",
@@ -8234,7 +8405,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
8234
8405
  resource: "file.files",
8235
8406
  method: "create",
8236
8407
  summary: "Upload file",
8237
- description: 'Upload a file to reuse in conversations or attach to a knowledge base. Unlike OpenAI Files, uploads must be nonempty and at most 100000000 bytes, and only user_data, assistants and vision purposes are accepted. Send file bytes as a multipart file part, not a filename or file ID; in the SDK use a File or Blob, for example new File(["Return within 23 days."], "policy.txt", { type: "text/plain" }). Content determines the MIME type. Supported uploads include PDF, DOCX/XLSX/PPTX, PNG/JPEG/GIF/WebP, MP3/WAV/FLAC/OGG/M4A, MP4/WebM, and UTF-8 JSON/NDJSON/CSV/Markdown/plain text; empty, unsupported, oversized files and unsupported purposes return 400. Use Uploads for larger files. The purpose vision accepts only PNG, JPEG, GIF and WebP, while conversation images require user_data. The returned ID belongs to your tenant; upload alone does not ingest the file into Knowledge. Knowledge attachment has a lower limit of 100000000 bytes. Optionally set expires_after[anchor]=created_at with expires_after[seconds] (3600–2592000), or praxis[expires_in_seconds] (3600–7776000), never both. Without expiry, the file persists until deleted.',
8408
+ description: 'Upload a file to reuse in conversations or attach to a knowledge base. Unlike OpenAI Files, uploads must be nonempty and at most 100000000 bytes, and only user_data and vision purposes are accepted. Send file bytes as a multipart file part, not a filename or file ID; in the SDK use a File or Blob, for example new File(["Return within 23 days."], "policy.txt", { type: "text/plain" }). Content determines the MIME type. Supported uploads include PDF, DOCX/XLSX/PPTX, PNG/JPEG/GIF/WebP, MP3/WAV/FLAC/OGG/M4A, MP4/WebM, and UTF-8 JSON/NDJSON/CSV/Markdown/plain text; empty, unsupported, oversized files and unsupported purposes return 400. Use Uploads for larger files. The purpose vision accepts only PNG, JPEG, GIF and WebP, while conversation images require user_data. The returned ID belongs to your tenant; upload alone does not ingest the file into Knowledge. Knowledge attachment has a lower limit of 100000000 bytes. Optionally set expires_after[anchor]=created_at with expires_after[seconds] (3600–7776000). Without expiry, the file persists until deleted.',
8238
8409
  http: "POST",
8239
8410
  path: "/file/v1/files",
8240
8411
  streaming: "no",
@@ -8256,23 +8427,16 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
8256
8427
  type: "string",
8257
8428
  enum: [
8258
8429
  "user_data",
8259
- "assistants",
8260
8430
  "vision"
8261
8431
  ],
8262
8432
  required: true,
8263
- description: "Purpose label stored with the file: user_data, assistants or vision. The vision purpose accepts only PNG, JPEG, GIF and WebP images. Conversation image references require user_data."
8433
+ description: "Purpose label stored with the file: user_data or vision. The vision purpose accepts only PNG, JPEG, GIF and WebP images. Conversation image references require user_data."
8264
8434
  },
8265
8435
  {
8266
8436
  name: "expires_after",
8267
8437
  type: "object",
8268
8438
  required: false,
8269
8439
  description: "Optional expiry relative to created_at. Files without an expiry persist until deleted."
8270
- },
8271
- {
8272
- name: "praxis",
8273
- type: "object",
8274
- required: false,
8275
- description: "Own-face extensions. Use at most one expiry setting."
8276
8440
  }
8277
8441
  ]
8278
8442
  }
@@ -8335,7 +8499,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
8335
8499
  resource: "file.uploads",
8336
8500
  method: "create",
8337
8501
  summary: "Create an upload",
8338
- description: "Start a multipart upload for a file larger than the 100000000-byte direct-upload limit. Supply the exact byte length, filename, MIME type and purpose. Unlike OpenAI, uploads accept at most 2 GiB (2147483648 bytes) and only user_data, assistants and vision purposes. Add parts of at most 64000000 bytes and complete within one hour. Optional part_size enables fixed-size, retryable parts. expires_after applies to the resulting file (3600–7776000 seconds on this own face); without it the file persists until deleted.",
8502
+ description: "Start a multipart upload for a file larger than the 100000000-byte direct-upload limit. Supply the exact byte length, filename, MIME type and purpose. Unlike OpenAI, uploads accept at most 2 GiB (2147483648 bytes) and only user_data and vision purposes. Add parts of at most 64000000 bytes and complete within one hour. Optional part_size enables fixed-size, retryable parts. expires_after applies to the resulting file (3600–7776000 seconds on this own face); without it the file persists until deleted.",
8339
8503
  http: "POST",
8340
8504
  path: "/file/v1/uploads",
8341
8505
  streaming: "no",
@@ -8368,11 +8532,10 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
8368
8532
  type: "string",
8369
8533
  enum: [
8370
8534
  "user_data",
8371
- "assistants",
8372
8535
  "vision"
8373
8536
  ],
8374
8537
  required: true,
8375
- description: "Use user_data for conversation attachments, assistants for assistant files, or vision for PNG, JPEG, GIF and WebP images."
8538
+ description: "Use user_data for conversation attachments, or vision for PNG, JPEG, GIF and WebP images."
8376
8539
  },
8377
8540
  {
8378
8541
  name: "expires_after",
@@ -9552,7 +9715,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
9552
9715
  name: "overwrite",
9553
9716
  type: "boolean",
9554
9717
  required: false,
9555
- description: "Allow replacing an existing public_id, preserving its asset_id and increasing its version. False returns the existing resource without replacing it; defaults to true."
9718
+ description: "Allow replacing an existing public_id, preserving its asset_id and increasing its version. Only the latest version is deliverable; old version URLs return 404. Create a new public_id to retain old deliveries. False returns the existing resource without replacing it; defaults to true."
9556
9719
  },
9557
9720
  {
9558
9721
  name: "tags",
@@ -9611,7 +9774,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
9611
9774
  name: "file_id",
9612
9775
  type: "string",
9613
9776
  required: true,
9614
- description: "File ID to copy into this library; passed as the upload source instead of file bytes."
9777
+ description: "File ID to copy into this library; passed as the upload source instead of file bytes. This creates an independent public copy readable without authentication. Deleting the source File does not delete this asset; do not import confidential content."
9615
9778
  },
9616
9779
  {
9617
9780
  name: "public_id",
@@ -9665,7 +9828,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
9665
9828
  name: "overwrite",
9666
9829
  type: "boolean",
9667
9830
  required: false,
9668
- description: "Allow replacing an existing public_id, preserving its asset_id and increasing its version. False returns the existing resource without replacing it; defaults to true."
9831
+ description: "Allow replacing an existing public_id, preserving its asset_id and increasing its version. Only the latest version is deliverable; old version URLs return 404. Create a new public_id to retain old deliveries. False returns the existing resource without replacing it; defaults to true."
9669
9832
  },
9670
9833
  {
9671
9834
  name: "tags",
@@ -10182,7 +10345,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
10182
10345
  name: "expression",
10183
10346
  type: "string",
10184
10347
  required: false,
10185
- description: "Asset filter expression supporting field comparisons, AND, OR, NOT, parentheses and suffix wildcards. An empty expression matches all assets."
10348
+ description: 'Asset filter expression supporting field comparisons, AND, OR, NOT, parentheses and suffix wildcards. An empty expression matches all assets. For business metadata use context.sku=KETTLE-RED AND context.revision=2; request with_field: ["context"] to include context.'
10186
10349
  },
10187
10350
  {
10188
10351
  name: "sort_by",
@@ -21707,6 +21870,84 @@ var automationHooksReceive = (options) => (options.client ?? client).post({
21707
21870
  ...options.headers
21708
21871
  }
21709
21872
  });
21873
+ var automationHumanTasksList = (options) => (options?.client ?? client).get({
21874
+ querySerializer: { parameters: { status: { array: { explode: false } } } },
21875
+ security: [{
21876
+ key: "BearerAuth",
21877
+ scheme: "bearer",
21878
+ type: "http"
21879
+ }, {
21880
+ key: "ApiKeyAuth",
21881
+ name: "X-API-Key",
21882
+ type: "apiKey"
21883
+ }],
21884
+ url: "/automation/v1/human-tasks",
21885
+ ...options
21886
+ });
21887
+ var automationHumanTasksGet = (options) => (options.client ?? client).get({
21888
+ security: [{
21889
+ key: "BearerAuth",
21890
+ scheme: "bearer",
21891
+ type: "http"
21892
+ }, {
21893
+ key: "ApiKeyAuth",
21894
+ name: "X-API-Key",
21895
+ type: "apiKey"
21896
+ }],
21897
+ url: "/automation/v1/human-tasks/{id}",
21898
+ ...options
21899
+ });
21900
+ var automationHumanTasksRespond = (options) => (options.client ?? client).post({
21901
+ security: [{
21902
+ key: "BearerAuth",
21903
+ scheme: "bearer",
21904
+ type: "http"
21905
+ }, {
21906
+ key: "ApiKeyAuth",
21907
+ name: "X-API-Key",
21908
+ type: "apiKey"
21909
+ }],
21910
+ url: "/automation/v1/human-tasks/{id}/respond",
21911
+ ...options,
21912
+ headers: {
21913
+ "Content-Type": "application/json",
21914
+ ...options.headers
21915
+ }
21916
+ });
21917
+ var automationHumanTasksCancel = (options) => (options.client ?? client).post({
21918
+ security: [{
21919
+ key: "BearerAuth",
21920
+ scheme: "bearer",
21921
+ type: "http"
21922
+ }, {
21923
+ key: "ApiKeyAuth",
21924
+ name: "X-API-Key",
21925
+ type: "apiKey"
21926
+ }],
21927
+ url: "/automation/v1/human-tasks/{id}/cancel",
21928
+ ...options,
21929
+ headers: {
21930
+ "Content-Type": "application/json",
21931
+ ...options.headers
21932
+ }
21933
+ });
21934
+ var automationHumanTasksDelegate = (options) => (options.client ?? client).post({
21935
+ security: [{
21936
+ key: "BearerAuth",
21937
+ scheme: "bearer",
21938
+ type: "http"
21939
+ }, {
21940
+ key: "ApiKeyAuth",
21941
+ name: "X-API-Key",
21942
+ type: "apiKey"
21943
+ }],
21944
+ url: "/automation/v1/human-tasks/{id}/delegate",
21945
+ ...options,
21946
+ headers: {
21947
+ "Content-Type": "application/json",
21948
+ ...options.headers
21949
+ }
21950
+ });
21710
21951
  var databaseListDatabases = (options) => (options?.client ?? client).get({
21711
21952
  security: [{
21712
21953
  key: "database-bearerAuth",
@@ -24177,6 +24418,13 @@ function createAutomation(transport) {
24177
24418
  hooks: {
24178
24419
  send: bind(transport, automationHooksReceive)
24179
24420
  },
24421
+ humanTasks: {
24422
+ cancel: bind(transport, automationHumanTasksCancel),
24423
+ delegate: bind(transport, automationHumanTasksDelegate),
24424
+ list: bindPage(transport, automationHumanTasksList),
24425
+ respond: bind(transport, automationHumanTasksRespond),
24426
+ retrieve: bind(transport, automationHumanTasksGet)
24427
+ },
24180
24428
  resolve: {
24181
24429
  retrieve: bind(transport, automationResolveResolve)
24182
24430
  },
@@ -26430,8 +26678,9 @@ function jwtFetch(fetchImpl, token) {
26430
26678
  function credentials(config, vars, ports) {
26431
26679
  const path = ports.path ?? tokenPath(config.env);
26432
26680
  const store = ports.store ?? createTokenStore(config.env, path, ports.secretStore);
26681
+ const source = credentialSource(vars);
26433
26682
  const apiKey = vars.PRAXIS_API_KEY;
26434
- const machineToken = credentialSource(vars) === "machine-token" ? vars.PRAXIS_API_TOKEN : undefined;
26683
+ const machineToken = source === "machine-token" ? vars.PRAXIS_API_TOKEN : undefined;
26435
26684
  const remember = ports.remember ?? (() => {});
26436
26685
  if (apiKey)
26437
26686
  remember(apiKey);
@@ -26493,6 +26742,7 @@ function credentials(config, vars, ports) {
26493
26742
  }
26494
26743
  }
26495
26744
  return {
26745
+ source,
26496
26746
  get,
26497
26747
  requireLogin,
26498
26748
  async client(org) {
@@ -26548,13 +26798,13 @@ function skillDocument(commands) {
26548
26798
  "## General rules",
26549
26799
  "",
26550
26800
  "- Select the environment only with `PRAXIS_ENV`; there is no `--env` option. The dev package defaults to develop.",
26551
- "- Authenticate with `PRAXIS_API_KEY`, `PRAXIS_API_TOKEN` (a machine token, sent in the Authorization header; computers have it set) or `praxis login`, in that order. API keys and machine tokens determine the organization; login sessions can use `--org <organization_id>`. `PRAXIS_API_URL` overrides the API base and must be an https deepraxis.com URL.",
26801
+ "- Authenticate with `PRAXIS_API_KEY`, `PRAXIS_API_TOKEN` (a machine token, sent in the Authorization header; computers have it set) or `praxis login`, in that order. Login saves the session even when an environment credential takes precedence; unset the named variable in its warning to use the saved login. API keys and machine tokens determine the organization; login sessions can use `--org <organization_id>`. `PRAXIS_API_URL` overrides the API base and must be an https deepraxis.com URL.",
26552
26802
  "- AI mode is enabled automatically in supported agent environments. Use `--format agent` to select it explicitly.",
26553
26803
  "- Use `--json` for the complete JSON response without presentation truncation. Successful JSON output goes to stdout; errors go to stderr.",
26554
26804
  "- Supply bodies with `--data JSON`, `--data @file.json`, or `--data -` for stdin. Scalar field options override matching JSON fields. Structured fields require `--data`.",
26555
26805
  "- Deletion requires `--yes` in AI mode. Confirm the intended resource before using it.",
26556
26806
  "- Use `--limit N` to limit a server page for SDK-paginated commands. Other lists apply it only to displayed rows; `--param-limit` still sends the API parameter when available. `--all` follows supported pagination and cannot be combined with `--limit`.",
26557
- "- Error JSON has an `error` object: `code` identifies the failure, `message` describes it, `hint` suggests recovery, `env` identifies the environment, `command` identifies the command, `status` is the HTTP status, and `request_id` correlates diagnostics. Unavailable fields are null. Exit codes: 0 success, 1 runtime/API error, 2 usage error.",
26807
+ "- Error JSON has an `error` object: `code` identifies the failure, `message` describes it, `hint` suggests recovery, `env` identifies the environment, `command` identifies the command, `status` is the HTTP status, and `request_id` correlates diagnostics. Authentication failures also include `credential_source` (api-key, machine-token, or login); follow the source-specific hint. Unavailable fields are null. Exit codes: 0 success, 1 runtime/API error, 2 usage error.",
26558
26808
  "- Append `--help` to a command for its optional parameters. Required scalar body options below can also be supplied as fields in `--data`.",
26559
26809
  "- Two layers: top-level commands (`login`, `org`, `skill`, …) are workflows and session commands; every API operation is under `praxis api <domain> …`. `praxis api <METHOD> <path>` sends a raw request (the method is uppercase).",
26560
26810
  "",
@@ -26685,7 +26935,12 @@ Enter code: ${code.user_code}` });
26685
26935
  const location = await (ports.store ?? createTokenStore(config.env, path)).save(toStored(flow.tokens, ports.now()));
26686
26936
  if (location !== "keychain")
26687
26937
  ports.emit({ kind: "message", channel: "stderr", text: "stored in a file (no system keychain available)" });
26938
+ const shadowedBy = ports.source === "api-key" ? "PRAXIS_API_KEY" : ports.source === "machine-token" ? "PRAXIS_API_TOKEN" : undefined;
26688
26939
  ports.emit({ kind: "message", text: `Logged in (${config.env}).` });
26940
+ if (shadowedBy)
26941
+ ports.emit({ kind: "message", channel: "stderr", text: `Note: ${shadowedBy} is set and takes precedence over this login. Unset it (unset ${shadowedBy}) to use the login.` });
26942
+ if (ports.json)
26943
+ ports.emit({ kind: "object", data: { env: config.env, ...shadowedBy ? { shadowed_by: shadowedBy } : {} } });
26689
26944
  }
26690
26945
  async function whoami(auth, env, org) {
26691
26946
  const credential = await auth.get(org);
@@ -27487,7 +27742,7 @@ ${usage ? `usage: ${JSON.stringify(usage)}
27487
27742
 
27488
27743
  // src/output/render.ts
27489
27744
  function errorJSON(result, ctx) {
27490
- return JSON.stringify({ error: { code: result.code, message: result.message, hint: result.hint ?? null, env: result.env, command: ctx.command ?? null, status: result.status ?? null, request_id: result.request_id ?? null } }) + `
27745
+ return JSON.stringify({ error: { code: result.code, message: result.message, hint: result.hint ?? null, env: result.env, command: ctx.command ?? null, status: result.status ?? null, request_id: result.request_id ?? null, ...result.credential_source ? { credential_source: result.credential_source } : {} } }) + `
27491
27746
  `;
27492
27747
  }
27493
27748
  function render(result, ctx) {
@@ -27628,6 +27883,16 @@ var humanize = (code) => {
27628
27883
  const words = code.toLowerCase().split("_").filter(Boolean).join(" ");
27629
27884
  return words.charAt(0).toUpperCase() + words.slice(1);
27630
27885
  };
27886
+ function authHint(source) {
27887
+ switch (source) {
27888
+ case "api-key":
27889
+ return "The API key from PRAXIS_API_KEY was rejected; check or replace it, or unset it to use `praxis login`.";
27890
+ case "machine-token":
27891
+ return "The machine token from PRAXIS_API_TOKEN was rejected (it may have expired); unset it to use `praxis login`, or refresh it.";
27892
+ case "login":
27893
+ return "Run `praxis login` or set PRAXIS_API_KEY.";
27894
+ }
27895
+ }
27631
27896
  function errorInput(error, ctx) {
27632
27897
  const sdk = error instanceof PraxisError ? error : undefined;
27633
27898
  const raw = record(sdk?.raw), nested = record(raw.error);
@@ -27642,11 +27907,13 @@ function errorInput(error, ctx) {
27642
27907
  if (stripped)
27643
27908
  message = `${humanize(code)}${message ? `: ${message}` : ""}`;
27644
27909
  const status = sdk?.status, request_id = sdk?.requestId;
27910
+ const authFailure = status === 401 || ["NOT_LOGGED_IN", "UNAUTHENTICATED", "TOKEN_REVOKED", "LOGIN_FAILED"].includes(code);
27911
+ const source = ctx.credentialSource ?? "login";
27645
27912
  let hint = genericHint;
27646
27913
  if (error instanceof UsageError)
27647
27914
  hint = error.hint;
27648
- else if (status === 401 || ["NOT_LOGGED_IN", "UNAUTHENTICATED", "TOKEN_REVOKED", "LOGIN_FAILED"].includes(code))
27649
- hint = "Run `praxis login` or set PRAXIS_API_KEY.";
27915
+ else if (authFailure)
27916
+ hint = authHint(source);
27650
27917
  else if (status === 404)
27651
27918
  hint = ctx.listCommand ? `Check the id; list existing ones with \`${ctx.listCommand}\`` : "Check the id.";
27652
27919
  else if (status === 403)
@@ -27655,7 +27922,7 @@ function errorInput(error, ctx) {
27655
27922
  hint = "Rate limited; retry later.";
27656
27923
  else if (status !== undefined && status >= 500)
27657
27924
  hint = `Server error; retry later.${request_id ? ` Request id: ${request_id}.` : ""}`;
27658
- return { kind: "error", code, message, hint, env: ctx.env, ...status !== undefined ? { status } : {}, ...request_id ? { request_id } : {} };
27925
+ return { kind: "error", code, message, hint, env: ctx.env, ...authFailure ? { credential_source: source } : {}, ...status !== undefined ? { status } : {}, ...request_id ? { request_id } : {} };
27659
27926
  }
27660
27927
 
27661
27928
  // src/output/progress.ts
@@ -27685,7 +27952,7 @@ function startProgress(ctx, write = (text) => writeOutput({ stderr: text })) {
27685
27952
  }
27686
27953
 
27687
27954
  // src/main.ts
27688
- var version = "0.2.0-dev.4c0c1e3";
27955
+ var version = "0.2.0-dev.a538fab";
27689
27956
  var commands = commandTree(operations);
27690
27957
  var manual = [...workflows.map((w) => w.words), [API_WORD]];
27691
27958
  function route(argv) {
@@ -27880,6 +28147,7 @@ Examples:
27880
28147
  const auth = credentials(config, ports.env, { fetch: wireFetch, now: ports.now, path, store, remember: (s) => {
27881
28148
  secrets.push(s);
27882
28149
  } });
28150
+ ctx.credentialSource = auth.source;
27883
28151
  const org = flags.org;
27884
28152
  const confirm = (method) => confirmOperation(method, { yes: Boolean(flags.yes), noInput: Boolean(flags["no-input"]) || ctx.mode === "agent", stdinIsTTY: ports.stdinIsTTY, ask: async () => {
27885
28153
  stopProgress();
@@ -27946,7 +28214,8 @@ Examples:
27946
28214
  case "login":
27947
28215
  if (flags["no-input"] || quiet)
27948
28216
  throw new UsageError("login requires displaying a device code", "Remove --no-input / --quiet or set PRAXIS_API_KEY for scripts.");
27949
- await login(config, path, { ...ports, store, fetch: wireFetch, emit, remember: (s) => secrets.push(s) });
28217
+ ctx.credentialSource = "login";
28218
+ await login(config, path, { ...ports, source: auth.source, json: ctx.mode === "json", store, fetch: wireFetch, emit, remember: (s) => secrets.push(s) });
27950
28219
  break;
27951
28220
  case "logout":
27952
28221
  emit({ kind: "message", text: await store.delete() ? "Logged out." : "Not logged in." });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepraxis/cli",
3
- "version": "0.2.0-dev.4c0c1e3",
3
+ "version": "0.2.0-dev.a538fab",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "praxis": "dist/praxis.js"