@deepraxis/cli 0.1.0-dev.9d9e2b6 → 0.1.0-dev.a5cf3ce

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.
Files changed (3) hide show
  1. package/COMMANDS.md +22 -6
  2. package/dist/praxis.js +797 -70
  3. package/package.json +1 -1
package/dist/praxis.js CHANGED
@@ -68,7 +68,7 @@ var operations = [
68
68
  resource: "agent.agents",
69
69
  method: "create",
70
70
  summary: "Create agent",
71
- description: 'Create a reusable agent definition, then pass its returned id to sessions.create to start a conversation. The definition includes model, system prompt, tools, MCP servers and an optional multiagent roster. It is saved as version 1; real updates create new versions. Unlike Anthropic Managed Agents, nonempty skills attachments and custom tool entries return 400; the native skill tool is separate from the skills field. Use tools: [{type: "agent_toolset_20260401"}] for built-in tools including codemode, skill and agent; inspect toolsets.list for names and schemas, and keep bash enabled for native additions. To offer only some tools, set default_config: {enabled: false} and list the tools to keep in configs, e.g. tools: [{type: "agent_toolset_20260401", default_config: {enabled: false}, configs: [{name: "codemode", enabled: true}, {name: "bash", enabled: true, permission_policy: {type: "always_ask"}}]}]; every tool not listed, including todo_write, enter_plan_mode, ask_user_question and goal_read, follows default_config, and the response echoes it. codemode runs through bash, so enabling codemode while bash is disabled returns 400. Optional mcp_toolset entries pair with mcp_servers. model accepts platform model IDs such as deepseek-flash, not only the Claude IDs in the protocol examples. model.settings.reasoning sets default thinking; other extra model controls return 400. Example: {"name":"helper","model":{"id":"deepseek-flash"},"tools":[{"type":"agent_toolset_20260401"}]}.',
71
+ description: 'Create a reusable agent definition, then pass its returned id to sessions.create to start a conversation. The definition includes model, system prompt, tools, MCP servers and an optional multiagent roster. It is saved as version 1; real updates create new versions. Unlike Anthropic Managed Agents, nonempty skills attachments return 400; the native skill tool is separate from the skills field. Use tools: [{type: "agent_toolset_20260401"}] for built-in tools including codemode, skill and agent; inspect toolsets.list for names and schemas, and keep bash enabled for native additions. To offer only some tools, set default_config: {enabled: false} and list the tools to keep in configs, e.g. tools: [{type: "agent_toolset_20260401", default_config: {enabled: false}, configs: [{name: "codemode", enabled: true}, {name: "bash", enabled: true, permission_policy: {type: "always_ask"}}]}]; every tool not listed, including todo_write, enter_plan_mode, ask_user_question and goal_read, follows default_config, and the response echoes it. codemode runs through bash, so enabling codemode while bash is disabled returns 400. Optional mcp_toolset entries pair with mcp_servers. model accepts platform model IDs such as deepseek-flash, not only the Claude IDs in the protocol examples. model.settings.reasoning sets default thinking; other extra model controls return 400. Example: {"name":"helper","model":{"id":"deepseek-flash"},"tools":[{"type":"agent_toolset_20260401"}]}.',
72
72
  http: "POST",
73
73
  path: "/agent/v1/agents",
74
74
  streaming: "no",
@@ -183,6 +183,17 @@ across all toolsets allowed.`
183
183
  type: "object",
184
184
  required: false,
185
185
  description: "Praxis extension: switchable model ids on /agent/v1 only. The default model must be included. When omitted, only the default model is selectable."
186
+ },
187
+ {
188
+ name: "preset",
189
+ type: "string",
190
+ enum: [
191
+ "minimal",
192
+ "data-editor",
193
+ "full"
194
+ ],
195
+ required: false,
196
+ description: "Optional tool preset. minimal enables read, glob, grep and ask_user_question; data-editor also enables write and edit; full uses the default toolset with always_allow. Explicit tools override matching preset entries. codemode requires bash and is absent from data-editor."
186
197
  }
187
198
  ]
188
199
  }
@@ -215,7 +226,7 @@ across all toolsets allowed.`
215
226
  resource: "agent.agents",
216
227
  method: "update",
217
228
  summary: "Update agent",
218
- description: "Update an agent. Send the current version in the body for optimistic concurrency: a stale version returns 409, and an update that changes nothing keeps the version number. Any real change saves a new version; existing sessions keep the version they were created with. Omitted fields keep their value. multiagent takes null or a coordinator roster; subagent_model keeps its value when omitted and is cleared by null. Archived agents cannot be updated. Unlike Anthropic Managed Agents, nonempty skills attachments and custom tools return 400; use the native skill tool for available runtime skills.",
229
+ description: "Update an agent. Send the current version in the body for optimistic concurrency: a stale version returns 409, and an update that changes nothing keeps the version number. Any real change saves a new version; existing sessions keep the version they were created with. Omitted fields keep their value. multiagent takes null or a coordinator roster; subagent_model keeps its value when omitted and is cleared by null. Archived agents cannot be updated. Unlike Anthropic Managed Agents, nonempty skills attachments return 400; use the native skill tool for available runtime skills.",
219
230
  http: "POST",
220
231
  path: "/agent/v1/agents/{agent_id}",
221
232
  streaming: "no",
@@ -348,6 +359,17 @@ current version; omit to apply the update unconditionally.`
348
359
  type: "object",
349
360
  required: false,
350
361
  description: "Praxis extension: switchable model ids on /agent/v1 only. The default model must be included. When omitted, only the default model is selectable."
362
+ },
363
+ {
364
+ name: "preset",
365
+ type: "string",
366
+ enum: [
367
+ "minimal",
368
+ "data-editor",
369
+ "full"
370
+ ],
371
+ required: false,
372
+ description: "Optional tool preset. minimal enables read, glob, grep and ask_user_question; data-editor also enables write and edit; full uses the default toolset with always_allow. Explicit tools override matching preset entries. codemode requires bash and is absent from data-editor."
351
373
  }
352
374
  ]
353
375
  }
@@ -369,6 +391,206 @@ current version; omit to apply the update unconditionally.`
369
391
  ],
370
392
  query: []
371
393
  },
394
+ {
395
+ resource: "agent.agents.endUsers",
396
+ method: "list",
397
+ summary: "List End Users",
398
+ description: `List users who have sessions or token issuance history on a service agent.
399
+
400
+ Ordered by last_active_at and external_user_id descending. q is a case-sensitive literal prefix, including underscores. limit is 1–100, default 20. Reuse next_page with the same organization, agent, q and limit. Preemptively blocked users without history do not appear. End-user credentials and inaccessible or personal agents return 404.`,
401
+ http: "GET",
402
+ path: "/agent/v1/agents/{agent_id}/end_users",
403
+ streaming: "no",
404
+ pagination: false,
405
+ pathParams: [
406
+ {
407
+ name: "agent_id",
408
+ sdkName: "agent_id"
409
+ }
410
+ ],
411
+ query: [
412
+ {
413
+ name: "limit",
414
+ type: "integer",
415
+ required: false,
416
+ description: "Maximum users per page; defaults to 20."
417
+ },
418
+ {
419
+ name: "page",
420
+ type: "string",
421
+ required: false,
422
+ description: "next_page from the previous response with the same agent, q and limit."
423
+ },
424
+ {
425
+ name: "q",
426
+ type: "string",
427
+ required: false,
428
+ description: "Case-sensitive literal prefix of external_user_id; omit or use an empty string for all users."
429
+ }
430
+ ]
431
+ },
432
+ {
433
+ resource: "agent.agents.endUsers",
434
+ method: "delete",
435
+ summary: "Delete end-user data",
436
+ description: `Delete a host application's end-user data from one service agent after explicit confirmation.
437
+
438
+ Develop only. Set confirm to the exact external_user_id; missing or mismatched confirmation returns 400. Returns 202 with a pending task id, not completion. Poll the deletion endpoint. Concurrent requests reuse the unfinished task; retry DELETE after failure to resume it. Tokens are revoked and the user is blocked before a seven-day recovery snapshot is verified. Sessions including child sessions, conversation data, grants and feedback are then removed. A pre-existing block remains; a temporary block is removed on success. Attachment metadata is recorded and File attachments are retained. No charge is introduced by this operation. Example: DELETE /agent/v1/agents/agent_example/end_users/customer_123?confirm=customer_123.`,
439
+ http: "DELETE",
440
+ path: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}",
441
+ streaming: "no",
442
+ pagination: false,
443
+ pathParams: [
444
+ {
445
+ name: "agent_id",
446
+ sdkName: "agent_id"
447
+ },
448
+ {
449
+ name: "external_user_id",
450
+ sdkName: "external_user_id"
451
+ }
452
+ ],
453
+ query: [
454
+ {
455
+ name: "confirm",
456
+ type: "string",
457
+ required: true,
458
+ description: "Must exactly equal the external_user_id path parameter to confirm destructive deletion."
459
+ }
460
+ ]
461
+ },
462
+ {
463
+ resource: "agent.agents.endUsers",
464
+ method: "retrieve",
465
+ summary: "Get End User",
466
+ description: `Inspect one end user and their twenty most recently updated sessions.
467
+
468
+ Use external_user_id from listing or your host application. Users without session or issuance history return 404, including preemptively blocked users. End-user credentials and inaccessible or personal agents return 404.`,
469
+ http: "GET",
470
+ path: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}",
471
+ streaming: "no",
472
+ pagination: false,
473
+ pathParams: [
474
+ {
475
+ name: "agent_id",
476
+ sdkName: "agent_id"
477
+ },
478
+ {
479
+ name: "external_user_id",
480
+ sdkName: "external_user_id"
481
+ }
482
+ ],
483
+ query: []
484
+ },
485
+ {
486
+ resource: "agent.agents.endUsers.block",
487
+ method: "create",
488
+ summary: "Block End User",
489
+ description: `Block token issuance and session creation, then revoke existing tokens for an end user.
490
+
491
+ May block a user before any history exists; timestamps are then null and counts and cost are zero. Requires an embed policy, otherwise returns 409 with setup guidance. Deduplicates the policy blocklist and retains its 1000-user maximum. If revocation returns 502, the user remains blocked; retry to finish revocation. Repeats keep the user blocked and revoke any remaining grants. End-user credentials and inaccessible or personal agents return 404.`,
492
+ http: "POST",
493
+ path: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/block",
494
+ streaming: "no",
495
+ pagination: false,
496
+ pathParams: [
497
+ {
498
+ name: "agent_id",
499
+ sdkName: "agent_id"
500
+ },
501
+ {
502
+ name: "external_user_id",
503
+ sdkName: "external_user_id"
504
+ }
505
+ ],
506
+ query: []
507
+ },
508
+ {
509
+ resource: "agent.agents.endUsers",
510
+ method: "retrieveDeletion",
511
+ summary: "Get end-user deletion",
512
+ description: `Poll the latest deletion task for an end user, including after the user data has been removed.
513
+
514
+ Use the same agent_id and external_user_id as the confirmed DELETE. Status is pending, snapshotting, deleting, done or failed. Counts are empty until a verified snapshot exists. A failed task remains blocked and resumes when DELETE is retried with matching confirmation. snapshot_key is an operator recovery reference retained for seven days, not a public download URL. End-user credentials, inaccessible or personal agents, and missing tasks return 404. This read does not create a task or charge usage.`,
515
+ http: "GET",
516
+ path: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/deletion",
517
+ streaming: "no",
518
+ pagination: false,
519
+ pathParams: [
520
+ {
521
+ name: "agent_id",
522
+ sdkName: "agent_id"
523
+ },
524
+ {
525
+ name: "external_user_id",
526
+ sdkName: "external_user_id"
527
+ }
528
+ ],
529
+ query: []
530
+ },
531
+ {
532
+ resource: "agent.agents.endUsers.revokeTokens",
533
+ method: "create",
534
+ summary: "Revoke End User Tokens",
535
+ description: `Revoke all issued tokens for an end user and terminate their open embed streams.
536
+
537
+ Revokes credentials before marking grants revoked. Upstream failure returns 502 without changing grant revocation timestamps. Returns the count of newly revoked grants; a repeat without new grants returns zero. Does not block future issuance. End-user credentials and inaccessible or personal agents return 404.`,
538
+ http: "POST",
539
+ path: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/revoke_tokens",
540
+ streaming: "no",
541
+ pagination: false,
542
+ pathParams: [
543
+ {
544
+ name: "agent_id",
545
+ sdkName: "agent_id"
546
+ },
547
+ {
548
+ name: "external_user_id",
549
+ sdkName: "external_user_id"
550
+ }
551
+ ],
552
+ query: []
553
+ },
554
+ {
555
+ resource: "agent.agents.endUsers.unblock",
556
+ method: "create",
557
+ summary: "Unblock End User",
558
+ description: `Allow an end user to receive new tokens and create new sessions again.
559
+
560
+ Removes the user from the blocklist; previously revoked tokens stay revoked. Idempotent. Requires an embed policy, otherwise returns 409 with setup guidance. Returns null timestamps and zero counts and cost when no session or issuance history exists. End-user credentials and inaccessible or personal agents return 404.`,
561
+ http: "POST",
562
+ path: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/unblock",
563
+ streaming: "no",
564
+ pagination: false,
565
+ pathParams: [
566
+ {
567
+ name: "agent_id",
568
+ sdkName: "agent_id"
569
+ },
570
+ {
571
+ name: "external_user_id",
572
+ sdkName: "external_user_id"
573
+ }
574
+ ],
575
+ query: []
576
+ },
577
+ {
578
+ resource: "agent.agents.unarchive",
579
+ method: "create",
580
+ summary: "Unarchive Agent",
581
+ description: "Restore an archived agent without creating a configuration version. Already active agents are unchanged. Missing or inaccessible agents return 404. Use the returned agent id to create new sessions.",
582
+ http: "POST",
583
+ path: "/agent/v1/agents/{agent_id}/unarchive",
584
+ streaming: "no",
585
+ pagination: false,
586
+ pathParams: [
587
+ {
588
+ name: "agent_id",
589
+ sdkName: "agent_id"
590
+ }
591
+ ],
592
+ query: []
593
+ },
372
594
  {
373
595
  resource: "agent.agents.versions",
374
596
  method: "list",
@@ -580,7 +802,9 @@ Own-face superset: Managed Agents has no persistent Computer attachment director
580
802
  summary: "Connect computer",
581
803
  description: `Resume the computer and issue a sandbox connection.
582
804
 
583
- Own-face extension: Managed Agents has no persistent Computer connection. Returns the public SDK sandbox_id, envd_access_token and template_id. Archived computers remain accessible; foreign or absent computers return 404. Never cache credentials.`,
805
+ Own-face extension: Managed Agents has no persistent Computer connection. Returns the public SDK sandbox_id, envd_access_token and template_id, plus the machine tier the computer is on now (light or heavy) and the lease that keeps it there (lease_id, lease_expires_at; lease_id is null when no lease exists). Keep the lease while the connection stays open: renew it about every 20 seconds (POST .../leases/{lease_id}/renew) and release it on close (DELETE .../leases/{lease_id}). An unrenewed lease simply expires, and the full machine is reclaimed only after that. Archived computers remain accessible; foreign or absent computers return 404. Never cache credentials.
806
+
807
+ Connect to a computer with a caller-held lease. Omit the body or send {} to request light: the lightweight shell, or the heavy instance while it is running. Send {"need":"heavy"} to request full Linux for interactive programs; files are synchronized before the heavy connection is returned with tier heavy. Heavy running time counts toward the daily budget in seconds. Renew the lease while using the connection and release it with DELETE when finished. If the daily budget is exhausted, 429 COMPUTER_BUDGET_EXHAUSTED allows you to continue with need light.`,
584
808
  http: "POST",
585
809
  path: "/agent/v1/computers/{computer_id}/connect",
586
810
  streaming: "no",
@@ -591,7 +815,22 @@ Own-face extension: Managed Agents has no persistent Computer connection. Return
591
815
  sdkName: "computer_id"
592
816
  }
593
817
  ],
594
- query: []
818
+ query: [],
819
+ body: {
820
+ required: false,
821
+ fields: [
822
+ {
823
+ name: "need",
824
+ type: "string",
825
+ enum: [
826
+ "light",
827
+ "heavy"
828
+ ],
829
+ required: false,
830
+ description: "Defaults to light. light uses the lightweight shell, or the heavy instance while it is running. heavy requests a full Linux computer for interactive programs; heavy running time counts toward the daily budget in seconds."
831
+ }
832
+ ]
833
+ }
595
834
  },
596
835
  {
597
836
  resource: "agent.computers.files",
@@ -645,6 +884,52 @@ Praxis extension: MA only has session-scoped temporary containers and memory_sto
645
884
  }
646
885
  ]
647
886
  },
887
+ {
888
+ resource: "agent.computers.leases",
889
+ method: "delete",
890
+ summary: "Release computer lease",
891
+ description: `Give the lease back when a connection closes so the full machine can be reclaimed without waiting for it to expire.
892
+
893
+ Own-face extension. Idempotent: an unknown or already released lease succeeds as well. Foreign or absent computers return 404.`,
894
+ http: "DELETE",
895
+ path: "/agent/v1/computers/{computer_id}/leases/{lease_id}",
896
+ streaming: "no",
897
+ pagination: false,
898
+ pathParams: [
899
+ {
900
+ name: "computer_id",
901
+ sdkName: "computer_id"
902
+ },
903
+ {
904
+ name: "lease_id",
905
+ sdkName: "lease_id"
906
+ }
907
+ ],
908
+ query: []
909
+ },
910
+ {
911
+ resource: "agent.computers.leases.renew",
912
+ method: "create",
913
+ summary: "Renew computer lease",
914
+ description: `Extend the lease a connection holds so the full machine stays in service while the connection is open.
915
+
916
+ Own-face extension. A lease that is no longer valid (released, expired, or the computer moved to another machine) returns 409 LEASE_STALE; call connect again for a new connection and lease. Foreign or absent computers return 404.`,
917
+ http: "POST",
918
+ path: "/agent/v1/computers/{computer_id}/leases/{lease_id}/renew",
919
+ streaming: "no",
920
+ pagination: false,
921
+ pathParams: [
922
+ {
923
+ name: "computer_id",
924
+ sdkName: "computer_id"
925
+ },
926
+ {
927
+ name: "lease_id",
928
+ sdkName: "lease_id"
929
+ }
930
+ ],
931
+ query: []
932
+ },
648
933
  {
649
934
  resource: "agent.deploymentRuns",
650
935
  method: "list",
@@ -1074,6 +1359,43 @@ null to clear. Maximum 50.`
1074
1359
  ],
1075
1360
  query: []
1076
1361
  },
1362
+ {
1363
+ resource: "agent.embed",
1364
+ method: "retrieveAppearance",
1365
+ summary: "Read chat appearance",
1366
+ description: "Load saved appearance for an iframe or Hosted chat page. Supply an end-user embed token as Bearer authorization, or a console-issued publishable key in Praxis-Publishable-Key before anonymous token issuance. The credential selects the agent; identity_number and agent_id query parameters are rejected with 400. Missing appearance returns an empty object. Kit option names retain camelCase. Responses are private and cacheable for 60 seconds. Component hosts configure Kit in their own code instead.",
1367
+ http: "GET",
1368
+ path: "/agent/v1/embed/appearance",
1369
+ streaming: "no",
1370
+ pagination: false,
1371
+ pathParams: [],
1372
+ query: []
1373
+ },
1374
+ {
1375
+ resource: "agent.embed.exchange",
1376
+ method: "create",
1377
+ summary: "Exchange Hosted Code",
1378
+ description: `Redeem a single-use hosted link credential for an end-user token.
1379
+
1380
+ Read code from the c fragment parameter of hosted_url returned by embed token creation with hosted true, then remove the fragment before exchanging. No Authorization header is required; the code authenticates this request. The code expires after 60 seconds and is consumed atomically on exchange, so concurrent attempts have only one winner. Expired, used and unknown codes return the same 404 body. Keep the token in memory and return to the host website for a fresh link when it expires; exchange cannot refresh it. Requests are IP limited per minute using the anonymous entrypoint budget (default 20). Example body is {"code":"<code from hosted_url>"}.`,
1381
+ http: "POST",
1382
+ path: "/agent/v1/embed/exchange",
1383
+ streaming: "no",
1384
+ pagination: false,
1385
+ pathParams: [],
1386
+ query: [],
1387
+ body: {
1388
+ required: true,
1389
+ fields: [
1390
+ {
1391
+ name: "code",
1392
+ type: "string",
1393
+ required: true,
1394
+ description: "Single-use credential from the c fragment parameter of hosted_url returned by embed token creation. Valid for 60 seconds."
1395
+ }
1396
+ ]
1397
+ }
1398
+ },
1077
1399
  {
1078
1400
  resource: "agent.embedTokens",
1079
1401
  method: "list",
@@ -1119,7 +1441,7 @@ Includes expired and revoked grants; returns neither token nor token_id. Sorts b
1119
1441
  summary: "Create Embed Token",
1120
1442
  description: `Issue a short-lived credential on your backend for an end user of a service agent.
1121
1443
 
1122
- Requires an active service agent in your organization with an embed policy. Pins the requested version or the latest version and snapshots the policy environment, vaults and resources; metadata comes from the request. Blocked users cannot receive tokens. Keep your API key on the backend and pass only the returned token to the frontend. Every call creates a new grant; issuance is not idempotent. The hosted field is not supported.`,
1444
+ Requires an active service agent in your organization with an embed policy. Pins the requested version or the latest version and snapshots the policy environment, vaults and resources; metadata comes from the request. Blocked users cannot receive tokens. Keep your API key on the backend and pass only the returned token to the frontend. Every call creates a new grant; issuance is not idempotent. Set hosted to true to also receive hosted_url; redirect the user there within 60 seconds. The agent must have an identity_number. The URL fragment contains a single-use exchange credential, not the token. Omit hosted or set false for ordinary token issuance.`,
1123
1445
  http: "POST",
1124
1446
  path: "/agent/v1/embed_tokens",
1125
1447
  streaming: "no",
@@ -1129,6 +1451,12 @@ Requires an active service agent in your organization with an embed policy. Pins
1129
1451
  body: {
1130
1452
  required: true,
1131
1453
  fields: [
1454
+ {
1455
+ name: "hosted",
1456
+ type: "boolean",
1457
+ required: false,
1458
+ description: "Set true to also return a hosted chat URL with a single-use credential valid for 60 seconds. Defaults to false; the agent must have an identity_number."
1459
+ },
1132
1460
  {
1133
1461
  name: "agent",
1134
1462
  type: "string",
@@ -1188,6 +1516,37 @@ Requires an active service agent in your organization with an embed policy. Pins
1188
1516
  ]
1189
1517
  }
1190
1518
  },
1519
+ {
1520
+ resource: "agent.embedTokens.anonymous",
1521
+ method: "create",
1522
+ summary: "Issue anonymous visitor token",
1523
+ description: `Obtain a short-lived embedding token for a visitor without an account using the agent owner's publishable key.
1524
+
1525
+ No Authorization header is required. Send the browser Origin allowed by the agent policy. Save a returned visitor_secret and reuse it for refreshes; only new visitors receive one. Unknown secrets create new visitors, and extra fields including visitor_id return 400. Issuance uses the key creator's organization membership, the key session budget and the smaller of the policy TTL maximum and 3600 seconds. IP requests are limited per minute (default 20); UTC daily session and spending caps are checked across the key's primary sessions created that day. Token issuance itself does not create a session or charge usage; subsequent sessions bill the host organization. Example body: {"publishable_key":"pk_praxis_example"}.`,
1526
+ http: "POST",
1527
+ path: "/agent/v1/embed_tokens/anonymous",
1528
+ streaming: "no",
1529
+ pagination: false,
1530
+ pathParams: [],
1531
+ query: [],
1532
+ body: {
1533
+ required: true,
1534
+ fields: [
1535
+ {
1536
+ name: "publishable_key",
1537
+ type: "string",
1538
+ required: true,
1539
+ description: "Public key created by the service agent owner; safe to include in browser code."
1540
+ },
1541
+ {
1542
+ name: "visitor_secret",
1543
+ type: "string",
1544
+ required: false,
1545
+ description: "Secret returned by a previous anonymous issuance for this key. Omit for a new visitor; an unknown secret creates a new visitor."
1546
+ }
1547
+ ]
1548
+ }
1549
+ },
1191
1550
  {
1192
1551
  resource: "agent.embedTokens.revoke",
1193
1552
  method: "create",
@@ -1492,6 +1851,25 @@ owning account only.`
1492
1851
  type: "string",
1493
1852
  required: false,
1494
1853
  description: "Opaque pagination cursor: pass the next_page value of the previous response unchanged. Omit it for the first page. A cursor from a different query or a malformed one returns 400."
1854
+ },
1855
+ {
1856
+ name: "external_user_id",
1857
+ type: "string",
1858
+ required: false,
1859
+ description: "Filter by an exact end-user identifier (1–128 characters: A-Z, a-z, 0-9, underscore, dot, colon, at sign or hyphen). Keep this filter unchanged when following page."
1860
+ },
1861
+ {
1862
+ name: "source",
1863
+ type: "string",
1864
+ enum: [
1865
+ "kit",
1866
+ "iframe",
1867
+ "hosted",
1868
+ "api",
1869
+ "automation"
1870
+ ],
1871
+ required: false,
1872
+ description: "Filter by session origin: kit, iframe, hosted, api or automation. Keep this filter unchanged when following page."
1495
1873
  }
1496
1874
  ]
1497
1875
  },
@@ -1599,6 +1977,23 @@ offsets ("+08:00") and unknown names return 400. Never stored in
1599
1977
  ]
1600
1978
  }
1601
1979
  },
1980
+ {
1981
+ resource: "agent.sessions",
1982
+ method: "delete",
1983
+ summary: "Delete session",
1984
+ description: "Delete an idle or terminated session and its event history after saving a deletion snapshot. Supply the session id from creation or listing. Running sessions return 409 INVALID_STATE: interrupt first or wait until idle or terminated. Afterwards retrieval and event listing return 404 and lists omit the session. Example: DELETE /agent/v1/sessions/sesn_example.",
1985
+ http: "DELETE",
1986
+ path: "/agent/v1/sessions/{session_id}",
1987
+ streaming: "no",
1988
+ pagination: false,
1989
+ pathParams: [
1990
+ {
1991
+ name: "session_id",
1992
+ sdkName: "session_id"
1993
+ }
1994
+ ],
1995
+ query: []
1996
+ },
1602
1997
  {
1603
1998
  resource: "agent.sessions",
1604
1999
  method: "retrieve",
@@ -1872,7 +2267,7 @@ Praxis extension available only on /agent/v1, following Claude Agent SDK getCont
1872
2267
  resource: "agent.sessions.events",
1873
2268
  method: "list",
1874
2269
  summary: "List session events",
1875
- description: "Read the event history of a session as a page of events, oldest first by default (order=desc for newest first). Use it after sending a message to collect the reply, to find tool calls that wait for approval (session.status_idle with stop_reason requires_action lists their event_ids), or to audit a run; to follow a running session live use sessions.events.stream instead. Filter by types and by a created_at range on processed_at; pages hold at most 100 events (default 20) and next_page continues. A failed run emits session.error before session.status_terminated. Native history also includes user.steer, user.withdraw, system.notification, session.forked, session.goal_changed and session.goal_verification; these are not accepted by the /anthropic/v1 event-type filter.",
2270
+ description: "Read the event history of a session as a page of events, oldest first by default (order=desc for newest first). Use it after sending a message to collect the reply, to find tool calls that wait for approval or client custom tool results (session.status_idle with stop_reason requires_action lists their event_ids), or to audit a run; to follow a running session live use sessions.events.stream instead. Filter by types and by a created_at range on processed_at; pages hold at most 100 events (default 20) and next_page continues. A failed run emits session.error before session.status_terminated. Native history also includes user.steer, user.withdraw, system.notification, session.forked, session.goal_changed and session.goal_verification; these are not accepted by the /anthropic/v1 event-type filter.",
1876
2271
  http: "GET",
1877
2272
  path: "/agent/v1/sessions/{session_id}/events",
1878
2273
  streaming: "no",
@@ -1943,7 +2338,7 @@ Praxis extension available only on /agent/v1, following Claude Agent SDK getCont
1943
2338
  resource: "agent.sessions.events",
1944
2339
  method: "send",
1945
2340
  summary: "Send session events",
1946
- description: 'Send events to a session: user.message (exactly one nonempty text block), user.interrupt, user.tool_confirmation to allow or deny a pending tool call, user.steer to inject a queued user.message into a turn that is still running, and user.withdraw to retract a queued message. The response only acknowledges the inputs; read replies with sessions.events.list or sessions.events.stream. A message sent while the session waits for tool approval is queued (processed_at null) and runs in order after the approval is resolved. Archived sessions reject new messages. To approve, read a pending agent.tool_use or agent.mcp_tool_use event and send {type: "user.tool_confirmation", tool_use_id: <that event id>, result: "allow"} (or deny); include session_thread_id for a child approval. Native confirmations also accept updated_permissions, answers and annotations, which /anthropic/v1 rejects.',
2341
+ description: 'Attach optional praxis_context={items:[{name,value}]} to user.message for untrusted page context on this turn only (maximum 32 items, 4096 UTF-8 JSON bytes). /anthropic/v1 rejects this field. Send events to a session: user.message (exactly one nonempty text block), user.interrupt, user.tool_confirmation to allow or deny a pending tool call, user.custom_tool_result to return a custom tool result, user.steer to inject a queued user.message into a turn that is still running, and user.withdraw to retract a queued message. The response only acknowledges the inputs; read replies with sessions.events.list or sessions.events.stream. A message sent while the session waits for tool approval is queued (processed_at null) and runs in order after the approval is resolved. Archived sessions reject new messages. To approve, read a pending agent.tool_use or agent.mcp_tool_use event and send {type: "user.tool_confirmation", tool_use_id: <that event id>, result: "allow"} (or deny); include session_thread_id for a child approval. Native confirmations also accept updated_permissions, answers and annotations, which /anthropic/v1 rejects. Both faces accept user.custom_tool_result with custom_tool_use_id from agent.custom_tool_use.id or the requires_action stop_reason.event_ids. Unlike Anthropic, result content accepts only text blocks (omit it for an empty array). Omitted or null is_error means false. The server routes child calls by id; session_thread_id is rejected in this input. Unknown call ids return 400; duplicate results or calls no longer waiting return 409.',
1947
2342
  http: "POST",
1948
2343
  path: "/agent/v1/sessions/{session_id}/events",
1949
2344
  streaming: "no",
@@ -3093,12 +3488,33 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
3093
3488
  }
3094
3489
  },
3095
3490
  {
3096
- resource: "application.workers.versions",
3097
- method: "retrieve",
3098
- summary: "Get version",
3099
- description: "Get one version of a Worker with its modules, bindings and asset settings; secret values are never returned.",
3491
+ resource: "application.workers.versions",
3492
+ method: "retrieve",
3493
+ summary: "Get version",
3494
+ description: "Get one version of a Worker with its modules, bindings and asset settings; secret values are never returned.",
3495
+ http: "GET",
3496
+ path: "/application/v1/workers/{worker_id}/versions/{version_id}",
3497
+ streaming: "no",
3498
+ pagination: false,
3499
+ pathParams: [
3500
+ {
3501
+ name: "worker_id",
3502
+ sdkName: "worker_id"
3503
+ },
3504
+ {
3505
+ name: "version_id",
3506
+ sdkName: "version_id"
3507
+ }
3508
+ ],
3509
+ query: []
3510
+ },
3511
+ {
3512
+ resource: "application.workers.versions.assets",
3513
+ method: "retrieveManifest",
3514
+ summary: "Get version asset manifest",
3515
+ description: "Read the retained asset paths, content hashes and byte sizes of a version for publication planning. This read creates no session or version. A version without assets returns an empty manifest; unavailable artifacts and foreign resources return 404.",
3100
3516
  http: "GET",
3101
- path: "/application/v1/workers/{worker_id}/versions/{version_id}",
3517
+ path: "/application/v1/workers/{worker_id}/versions/{version_id}/assets/manifest",
3102
3518
  streaming: "no",
3103
3519
  pagination: false,
3104
3520
  pathParams: [
@@ -6536,7 +6952,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6536
6952
  name: "{column}",
6537
6953
  type: "string",
6538
6954
  required: false,
6539
- description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. See the filter operator matrix."
6955
+ description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. Supported operators: eq (equal), neq (not equal; ne is not supported), gt/gte/lt/lte (comparisons), like (case-sensitive text pattern), ilike (case-insensitive text pattern), in (membership), is (null/boolean test), cs (contains), cd (contained by), and ov (array overlap). For like/ilike, * or % matches any sequence and _ matches one character, e.g. title=ilike.*spring*; URL-encode a literal % as %25. Use days=in.(1,2,3), title=is.null, active=is.true or active=is.false; is.not_null and is.unknown are also accepted (unknown means null). Negate a condition with not., e.g. title=not.eq.draft. Multiple filters are ANDed; use or=(title.eq.a,title.eq.b), and=(days.gte.1,days.lte.3), not.or=(...) or not.and=(...), with nested and(...) and or(...) groups as needed. cs/cd accept JSON objects or arrays on JSON fields; cs also accepts a JSON scalar. For array values or multi-link fields, use cs.{a,b}, cd.{a,b} or ov.{a,b}. JSON paths use -> for JSON and ->> for text, e.g. attributes->>has_onsen=eq.true or attributes->tags=cs.[1,2]; chain -> segments and end with ->> for text. Dot paths such as attributes.has_onsen are unsupported. Full-text, regex, range operators and any/all modifiers are unsupported."
6540
6956
  },
6541
6957
  {
6542
6958
  name: "and",
@@ -6584,7 +7000,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6584
7000
  name: "on_conflict",
6585
7001
  type: "string",
6586
7002
  required: false,
6587
- description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
7003
+ description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. With resolution=merge-duplicates, a conflicting row keeps columns omitted from the request; supplied values replace the whole field value (including JSON objects), and explicit null clears a nullable field. With resolution=ignore-duplicates, a conflicting row is left unchanged. Without a conflict, both modes insert a new row using field defaults for omitted fields. In a batch, a key present in another row is filled with null when omitted in this row unless missing=default is set; that null can overwrite a value during merge. With missing=default, omitted keys stay omitted for conflict merges (existing values are preserved); new rows use defaults, or null when no default exists. Explicit null never invokes a default. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
6588
7004
  },
6589
7005
  {
6590
7006
  name: "columns",
@@ -6598,7 +7014,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6598
7014
  resource: "database.databases.rest",
6599
7015
  method: "retrieve",
6600
7016
  summary: "Select rows",
6601
- description: "Read matching rows with filters, selected columns and ordering. Returns at most 1000 rows per request, including when limit is omitted. Content-Range reports the actual returned interval and the total when count is requested. PATCH and DELETE are not subject to this read cap. Unlike Supabase, casts, aggregates, spread and join modifiers are unsupported. Each table supports up to 1,000,000 rows. Query budget: 8,000 ms with a shared 3,000,000-row safety ceiling. Create indexes on filtered or sorted fields, or narrow the request when it exceeds its budget. Synchronous SQLite aggregates use candidate-row throughput estimates before execution; deployed Workers freeze clocks during synchronous CPU work, so the timer is not a guaranteed server-side interrupt. Count preferences: without filters, exact, planned and estimated all use SQLite's exact b-tree count. With filters, exact counts within budget; planned skips counting and reports an unknown total (Content-Range: 0-24/*); estimated attempts exact counting only when the preflight budget allows it, otherwise reports an unknown total. Preference-Applied echoes the requested count mode. Error table: QUERY_CANCELED / PostgREST 57014 is HTTP 500, retryable=false: Query timed out: index filtered or sorted fields, or narrow the range. DATABASE_INVALID_STATE is HTTP 409 for operations on a deleting database. Cleared or nonexistent databases return DATABASE_NOT_FOUND / HTTP 404. The count is an HTTP Content-Range response header, not a JSON property. Praxis SDK/codemode methods return the body only; a page length is not a total unless you know all matches fit in that page.",
7017
+ description: "Read matching rows with filters, selected columns and ordering. Returns at most 1000 rows per request, including when limit is omitted. Content-Range reports the actual returned interval and the total when count is requested. PATCH and DELETE are not subject to this read cap. Unlike Supabase, casts, aggregates, spread and join modifiers are unsupported. Each table supports up to 1,000,000 rows. Query budget: 8,000 ms with a shared 3,000,000-row safety ceiling. Create indexes on filtered or sorted fields, or narrow the request when it exceeds its budget. Synchronous SQLite aggregates use candidate-row throughput estimates before execution; deployed Workers freeze clocks during synchronous CPU work, so the timer is not a guaranteed server-side interrupt. Count preferences: without filters, exact, planned and estimated all use SQLite's exact b-tree count. With filters, exact counts within budget; planned skips counting and reports an unknown total (Content-Range: 0-24/*); estimated attempts exact counting only when the preflight budget allows it, otherwise reports an unknown total. Preference-Applied echoes the requested count mode. Error table: QUERY_CANCELED / PostgREST 57014 is HTTP 500, retryable=false: Query timed out: index filtered or sorted fields, or narrow the range. DATABASE_INVALID_STATE is HTTP 409 for operations on a deleting database. Cleared or nonexistent databases return DATABASE_NOT_FOUND / HTTP 404. The count is an HTTP Content-Range response header, not a JSON property. Use praxis.database.count in the SDK or codemode to return { count: number | null }; a page length is not a total unless you know all matches fit in that page.",
6602
7018
  http: "GET",
6603
7019
  path: "/database/v1/databases/{database_id}/rest/{table}",
6604
7020
  streaming: "no",
@@ -6624,7 +7040,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6624
7040
  name: "{column}",
6625
7041
  type: "string",
6626
7042
  required: false,
6627
- description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. See the filter operator matrix."
7043
+ description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. Supported operators: eq (equal), neq (not equal; ne is not supported), gt/gte/lt/lte (comparisons), like (case-sensitive text pattern), ilike (case-insensitive text pattern), in (membership), is (null/boolean test), cs (contains), cd (contained by), and ov (array overlap). For like/ilike, * or % matches any sequence and _ matches one character, e.g. title=ilike.*spring*; URL-encode a literal % as %25. Use days=in.(1,2,3), title=is.null, active=is.true or active=is.false; is.not_null and is.unknown are also accepted (unknown means null). Negate a condition with not., e.g. title=not.eq.draft. Multiple filters are ANDed; use or=(title.eq.a,title.eq.b), and=(days.gte.1,days.lte.3), not.or=(...) or not.and=(...), with nested and(...) and or(...) groups as needed. cs/cd accept JSON objects or arrays on JSON fields; cs also accepts a JSON scalar. For array values or multi-link fields, use cs.{a,b}, cd.{a,b} or ov.{a,b}. JSON paths use -> for JSON and ->> for text, e.g. attributes->>has_onsen=eq.true or attributes->tags=cs.[1,2]; chain -> segments and end with ->> for text. Dot paths such as attributes.has_onsen are unsupported. Full-text, regex, range operators and any/all modifiers are unsupported."
6628
7044
  },
6629
7045
  {
6630
7046
  name: "and",
@@ -6672,7 +7088,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6672
7088
  name: "on_conflict",
6673
7089
  type: "string",
6674
7090
  required: false,
6675
- description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
7091
+ description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. With resolution=merge-duplicates, a conflicting row keeps columns omitted from the request; supplied values replace the whole field value (including JSON objects), and explicit null clears a nullable field. With resolution=ignore-duplicates, a conflicting row is left unchanged. Without a conflict, both modes insert a new row using field defaults for omitted fields. In a batch, a key present in another row is filled with null when omitted in this row unless missing=default is set; that null can overwrite a value during merge. With missing=default, omitted keys stay omitted for conflict merges (existing values are preserved); new rows use defaults, or null when no default exists. Explicit null never invokes a default. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
6676
7092
  },
6677
7093
  {
6678
7094
  name: "columns",
@@ -6686,7 +7102,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6686
7102
  resource: "database.databases.rest",
6687
7103
  method: "head",
6688
7104
  summary: "Count rows",
6689
- description: "Inspect the HTTP row count and range without retrieving row data; send Prefer: count=exact for a filtered count. Returns no body and does not fetch or serialize row data. A known count determines the interval using limit/offset or Range with a default and maximum page size of 1000. Without a count preference, or when the selected count mode cannot supply a total, Content-Range is */*. Singular Accept still validates page cardinality. Unlike Supabase, planned and estimated counts do not use PostgreSQL planner estimates. Count preferences: without filters, exact, planned and estimated all use SQLite's exact b-tree count. With filters, exact counts within budget; planned skips counting and reports an unknown total (Content-Range: 0-24/*); estimated attempts exact counting only when the preflight budget allows it, otherwise reports an unknown total. Preference-Applied echoes the requested count mode. Praxis SDK/codemode methods return only the empty body, not the Content-Range response header; use an HTTP client when you need that header.",
7105
+ description: "Inspect the HTTP row count and range without retrieving row data; send Prefer: count=exact for a filtered count. Returns no body and does not fetch or serialize row data. A known count determines the interval using limit/offset or Range with a default and maximum page size of 1000. Without a count preference, or when the selected count mode cannot supply a total, Content-Range is */*. Singular Accept still validates page cardinality. Unlike Supabase, planned and estimated counts do not use PostgreSQL planner estimates. Count preferences: without filters, exact, planned and estimated all use SQLite's exact b-tree count. With filters, exact counts within budget; planned skips counting and reports an unknown total (Content-Range: 0-24/*); estimated attempts exact counting only when the preflight budget allows it, otherwise reports an unknown total. Preference-Applied echoes the requested count mode. Use praxis.database.count in the SDK or codemode to return { count: number | null } from this header without retrieving rows.",
6690
7106
  http: "HEAD",
6691
7107
  path: "/database/v1/databases/{database_id}/rest/{table}",
6692
7108
  streaming: "no",
@@ -6712,7 +7128,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6712
7128
  name: "{column}",
6713
7129
  type: "string",
6714
7130
  required: false,
6715
- description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. See the filter operator matrix."
7131
+ description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. Supported operators: eq (equal), neq (not equal; ne is not supported), gt/gte/lt/lte (comparisons), like (case-sensitive text pattern), ilike (case-insensitive text pattern), in (membership), is (null/boolean test), cs (contains), cd (contained by), and ov (array overlap). For like/ilike, * or % matches any sequence and _ matches one character, e.g. title=ilike.*spring*; URL-encode a literal % as %25. Use days=in.(1,2,3), title=is.null, active=is.true or active=is.false; is.not_null and is.unknown are also accepted (unknown means null). Negate a condition with not., e.g. title=not.eq.draft. Multiple filters are ANDed; use or=(title.eq.a,title.eq.b), and=(days.gte.1,days.lte.3), not.or=(...) or not.and=(...), with nested and(...) and or(...) groups as needed. cs/cd accept JSON objects or arrays on JSON fields; cs also accepts a JSON scalar. For array values or multi-link fields, use cs.{a,b}, cd.{a,b} or ov.{a,b}. JSON paths use -> for JSON and ->> for text, e.g. attributes->>has_onsen=eq.true or attributes->tags=cs.[1,2]; chain -> segments and end with ->> for text. Dot paths such as attributes.has_onsen are unsupported. Full-text, regex, range operators and any/all modifiers are unsupported."
6716
7132
  },
6717
7133
  {
6718
7134
  name: "and",
@@ -6760,7 +7176,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6760
7176
  name: "on_conflict",
6761
7177
  type: "string",
6762
7178
  required: false,
6763
- description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
7179
+ description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. With resolution=merge-duplicates, a conflicting row keeps columns omitted from the request; supplied values replace the whole field value (including JSON objects), and explicit null clears a nullable field. With resolution=ignore-duplicates, a conflicting row is left unchanged. Without a conflict, both modes insert a new row using field defaults for omitted fields. In a batch, a key present in another row is filled with null when omitted in this row unless missing=default is set; that null can overwrite a value during merge. With missing=default, omitted keys stay omitted for conflict merges (existing values are preserved); new rows use defaults, or null when no default exists. Explicit null never invokes a default. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
6764
7180
  },
6765
7181
  {
6766
7182
  name: "columns",
@@ -6800,7 +7216,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6800
7216
  name: "{column}",
6801
7217
  type: "string",
6802
7218
  required: false,
6803
- description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. See the filter operator matrix."
7219
+ description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. Supported operators: eq (equal), neq (not equal; ne is not supported), gt/gte/lt/lte (comparisons), like (case-sensitive text pattern), ilike (case-insensitive text pattern), in (membership), is (null/boolean test), cs (contains), cd (contained by), and ov (array overlap). For like/ilike, * or % matches any sequence and _ matches one character, e.g. title=ilike.*spring*; URL-encode a literal % as %25. Use days=in.(1,2,3), title=is.null, active=is.true or active=is.false; is.not_null and is.unknown are also accepted (unknown means null). Negate a condition with not., e.g. title=not.eq.draft. Multiple filters are ANDed; use or=(title.eq.a,title.eq.b), and=(days.gte.1,days.lte.3), not.or=(...) or not.and=(...), with nested and(...) and or(...) groups as needed. cs/cd accept JSON objects or arrays on JSON fields; cs also accepts a JSON scalar. For array values or multi-link fields, use cs.{a,b}, cd.{a,b} or ov.{a,b}. JSON paths use -> for JSON and ->> for text, e.g. attributes->>has_onsen=eq.true or attributes->tags=cs.[1,2]; chain -> segments and end with ->> for text. Dot paths such as attributes.has_onsen are unsupported. Full-text, regex, range operators and any/all modifiers are unsupported."
6804
7220
  },
6805
7221
  {
6806
7222
  name: "and",
@@ -6848,7 +7264,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6848
7264
  name: "on_conflict",
6849
7265
  type: "string",
6850
7266
  required: false,
6851
- description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
7267
+ description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. With resolution=merge-duplicates, a conflicting row keeps columns omitted from the request; supplied values replace the whole field value (including JSON objects), and explicit null clears a nullable field. With resolution=ignore-duplicates, a conflicting row is left unchanged. Without a conflict, both modes insert a new row using field defaults for omitted fields. In a batch, a key present in another row is filled with null when omitted in this row unless missing=default is set; that null can overwrite a value during merge. With missing=default, omitted keys stay omitted for conflict merges (existing values are preserved); new rows use defaults, or null when no default exists. Explicit null never invokes a default. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
6852
7268
  },
6853
7269
  {
6854
7270
  name: "columns",
@@ -6868,7 +7284,7 @@ Own-face extension. Use a readable session and a run_id from its events. Each su
6868
7284
  summary: "Insert rows",
6869
7285
  description: `Insert rows into an existing table after defining its fields; at most 500 rows per request. Each request is atomic: any failure rolls back the entire batch. There are no transactions across requests.
6870
7286
  Rows are filled to the union of their keys with null; send Prefer: missing=default to use field defaults for missing keys.
6871
- The default is return=minimal: success returns HTTP 201 with an empty body. Send Prefer: return=representation to return the inserted rows. Unlike Supabase, upsert conflicts can target only id or one unique field, not a composite key. Each table supports up to 1,000,000 rows.`,
7287
+ The default is return=minimal: success returns HTTP 201 with an empty body. Send Prefer: return=representation to return the inserted rows. With resolution=merge-duplicates, a conflicting row keeps columns omitted from the request; supplied values replace the whole field value (including JSON objects), and explicit null clears a nullable field. With resolution=ignore-duplicates, a conflicting row is left unchanged. Without a conflict, both modes insert a new row using field defaults for omitted fields. In a batch, a key present in another row is filled with null when omitted in this row unless missing=default is set; that null can overwrite a value during merge. With missing=default, omitted keys stay omitted for conflict merges (existing values are preserved); new rows use defaults, or null when no default exists. Explicit null never invokes a default. Unlike Supabase, upsert conflicts can target only id or one unique field, not a composite key. Each table supports up to 1,000,000 rows.`,
6872
7288
  http: "POST",
6873
7289
  path: "/database/v1/databases/{database_id}/rest/{table}",
6874
7290
  streaming: "no",
@@ -6894,7 +7310,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
6894
7310
  name: "{column}",
6895
7311
  type: "string",
6896
7312
  required: false,
6897
- description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. See the filter operator matrix."
7313
+ description: "Horizontal filter: replace {column} with a field name or JSON path, e.g. title=eq.summary. Repeat for more columns. Supported operators: eq (equal), neq (not equal; ne is not supported), gt/gte/lt/lte (comparisons), like (case-sensitive text pattern), ilike (case-insensitive text pattern), in (membership), is (null/boolean test), cs (contains), cd (contained by), and ov (array overlap). For like/ilike, * or % matches any sequence and _ matches one character, e.g. title=ilike.*spring*; URL-encode a literal % as %25. Use days=in.(1,2,3), title=is.null, active=is.true or active=is.false; is.not_null and is.unknown are also accepted (unknown means null). Negate a condition with not., e.g. title=not.eq.draft. Multiple filters are ANDed; use or=(title.eq.a,title.eq.b), and=(days.gte.1,days.lte.3), not.or=(...) or not.and=(...), with nested and(...) and or(...) groups as needed. cs/cd accept JSON objects or arrays on JSON fields; cs also accepts a JSON scalar. For array values or multi-link fields, use cs.{a,b}, cd.{a,b} or ov.{a,b}. JSON paths use -> for JSON and ->> for text, e.g. attributes->>has_onsen=eq.true or attributes->tags=cs.[1,2]; chain -> segments and end with ->> for text. Dot paths such as attributes.has_onsen are unsupported. Full-text, regex, range operators and any/all modifiers are unsupported."
6898
7314
  },
6899
7315
  {
6900
7316
  name: "and",
@@ -6942,7 +7358,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
6942
7358
  name: "on_conflict",
6943
7359
  type: "string",
6944
7360
  required: false,
6945
- description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
7361
+ description: "POST upsert: id or one unique field with resolution=merge-duplicates|ignore-duplicates. With resolution=merge-duplicates, a conflicting row keeps columns omitted from the request; supplied values replace the whole field value (including JSON objects), and explicit null clears a nullable field. With resolution=ignore-duplicates, a conflicting row is left unchanged. Without a conflict, both modes insert a new row using field defaults for omitted fields. In a batch, a key present in another row is filled with null when omitted in this row unless missing=default is set; that null can overwrite a value during merge. With missing=default, omitted keys stay omitted for conflict merges (existing values are preserved); new rows use defaults, or null when no default exists. Explicit null never invokes a default. POST accepts an optional client id matching [A-Za-z0-9_-]{1,64}; omitted ids are generated. PATCH cannot change id."
6946
7362
  },
6947
7363
  {
6948
7364
  name: "columns",
@@ -6994,7 +7410,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
6994
7410
  resource: "database.databases.tables",
6995
7411
  method: "create",
6996
7412
  summary: "Create table",
6997
- description: "Creates a table together with its initial fields in one call and returns it (HTTP 201) with generated tbl_ and fld_ ids. name must match ^[a-z_][a-z0-9_]{0,62}$ and be unused in this database (duplicate: 409 UNIQUE_VIOLATION). fields is required and may be an empty array; fields can also be added later with databaseAddField. Limits: 50 tables per database, 64 fields per table, and 16 indexed or unique fields per table; exceeding one returns 400 LIMIT_EXCEEDED. Every row also has a system id column, which is not declared as a field. Insert data afterwards with databaseInsert. Unlike Supabase, define schema with this table API and the field APIs; PostgreSQL DDL and SQL migration files cannot be submitted. Each table supports up to 1,000,000 rows.",
7413
+ description: 'Creates a table together with its initial fields in one call and returns it (HTTP 201) with generated tbl_ and fld_ ids. name must match ^[a-z_][a-z0-9_]{0,62}$ and be unused in this database (duplicate: 409 UNIQUE_VIOLATION). fields is required and may be an empty array; fields can also be added later with databaseAddField. Limits: 50 tables per database, 64 fields per table, and 16 indexed or unique fields per table; exceeding one returns 400 LIMIT_EXCEEDED. Fields default to indexed:false. Set indexed:true explicitly for fields used in filters or ordering. Only indexed:true or unique:true consumes one of the 16 indexed-or-unique field slots; a field with both consumes one slot. Unique fields still consume a slot even with indexed:false. Existing fields are unchanged. Minimal field example: {"name":"notes","type":"string","indexed":false}. Every row also has a system id column, which is not declared as a field. Insert data afterwards with databaseInsert. Unlike Supabase, define schema with this table API and the field APIs; PostgreSQL DDL and SQL migration files cannot be submitted. Each table supports up to 1,000,000 rows.',
6998
7414
  http: "POST",
6999
7415
  path: "/database/v1/databases/{database_id}/tables",
7000
7416
  streaming: "no",
@@ -7115,7 +7531,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
7115
7531
  resource: "database.databases.tables.fields",
7116
7532
  method: "create",
7117
7533
  summary: "Add field",
7118
- description: "Adds one field to an existing table and returns the updated table (HTTP 201). Required inputs are name (lowercase letters, digits and underscores; id and names starting with _ are reserved) and type (string, integer, number, boolean, datetime, json or link); json needs options.schema and link needs options.linked_table_id and options.multiple. Adding a required field to a table that already has rows needs a default, otherwise the call fails with 400 VALIDATION_FAILED; a default is written into every existing row. Scalar fields are indexed by default, while json and link fields cannot be indexed. Limits: 64 fields and 16 indexed or unique fields per table (400 LIMIT_EXCEEDED). Unlike Supabase, schema evolution uses field definitions rather than ALTER TABLE statements or SQL migrations.",
7534
+ description: 'Adds one field to an existing table and returns the updated table (HTTP 201). Required inputs are name (lowercase letters, digits and underscores; id and names starting with _ are reserved) and type (string, integer, number, boolean, datetime, json or link); json needs options.schema and link needs options.linked_table_id and options.multiple. Adding a required field to a table that already has rows needs a default, otherwise the call fails with 400 VALIDATION_FAILED; a default is written into every existing row. Fields default to indexed:false. Set indexed:true explicitly for fields used in filters or ordering. Only indexed:true or unique:true consumes one of the 16 indexed-or-unique field slots; a field with both consumes one slot. Unique fields still consume a slot even with indexed:false. Existing fields are unchanged. Minimal field example: {"name":"notes","type":"string","indexed":false}. JSON and link fields cannot be indexed. Limits: 64 fields and 16 indexed or unique fields per table (400 LIMIT_EXCEEDED). Unlike Supabase, schema evolution uses field definitions rather than ALTER TABLE statements or SQL migrations.',
7119
7535
  http: "POST",
7120
7536
  path: "/database/v1/databases/{database_id}/tables/{table}/fields",
7121
7537
  streaming: "no",
@@ -11680,15 +12096,8 @@ for more details.`
11680
12096
  {
11681
12097
  name: "phase",
11682
12098
  type: "string",
11683
- enum: [
11684
- "open",
11685
- "awaiting_customer",
11686
- "in_progress",
11687
- "resolved",
11688
- "closed"
11689
- ],
11690
12099
  required: false,
11691
- description: "Only feedback in this phase: open, awaiting_customer, in_progress, resolved or closed; see the phase field of a feedback for what each means."
12100
+ description: "Only feedback in these phases: a comma-separated list of open, awaiting_customer, in_progress, resolved or closed, for example open,in_progress; see the phase field of a feedback for what each means."
11692
12101
  },
11693
12102
  {
11694
12103
  name: "query",
@@ -11798,6 +12207,18 @@ for more details.`
11798
12207
  ]
11799
12208
  }
11800
12209
  },
12210
+ {
12211
+ resource: "organization.feedback.counts",
12212
+ method: "list",
12213
+ summary: "Count your organization's feedback by phase",
12214
+ description: "How many of your organization's feedback are in each phase, for status tabs. Counts never include another organization's feedback.",
12215
+ http: "GET",
12216
+ path: "/organization/v1/feedback/counts",
12217
+ streaming: "no",
12218
+ pagination: false,
12219
+ pathParams: [],
12220
+ query: []
12221
+ },
11801
12222
  {
11802
12223
  resource: "organization.feedback",
11803
12224
  method: "retrieve",
@@ -15102,6 +15523,19 @@ var createClient = (config = {}) => {
15102
15523
  var client = createClient(createConfig({ baseUrl: "https://api.deepraxis.com" }));
15103
15524
 
15104
15525
  // ../../packages/sdk/typescript/src/generated/sdk.gen.ts
15526
+ var unarchiveAgent = (options) => (options.client ?? client).post({
15527
+ security: [{
15528
+ key: "BearerAuth",
15529
+ scheme: "bearer",
15530
+ type: "http"
15531
+ }, {
15532
+ key: "ApiKeyAuth",
15533
+ name: "X-API-Key",
15534
+ type: "apiKey"
15535
+ }],
15536
+ url: "/agent/v1/agents/{agent_id}/unarchive",
15537
+ ...options
15538
+ });
15105
15539
  var deleteRunFeedback = (options) => (options.client ?? client).delete({
15106
15540
  security: [{
15107
15541
  key: "BearerAuth",
@@ -15132,6 +15566,113 @@ var setRunFeedback = (options) => (options.client ?? client).post({
15132
15566
  ...options.headers
15133
15567
  }
15134
15568
  });
15569
+ var listEndUsers = (options) => (options.client ?? client).get({
15570
+ security: [{
15571
+ key: "BearerAuth",
15572
+ scheme: "bearer",
15573
+ type: "http"
15574
+ }, {
15575
+ key: "ApiKeyAuth",
15576
+ name: "X-API-Key",
15577
+ type: "apiKey"
15578
+ }],
15579
+ url: "/agent/v1/agents/{agent_id}/end_users",
15580
+ ...options
15581
+ });
15582
+ var deleteEndUser = (options) => (options.client ?? client).delete({
15583
+ security: [{
15584
+ key: "BearerAuth",
15585
+ scheme: "bearer",
15586
+ type: "http"
15587
+ }, {
15588
+ key: "ApiKeyAuth",
15589
+ name: "X-API-Key",
15590
+ type: "apiKey"
15591
+ }],
15592
+ url: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}",
15593
+ ...options
15594
+ });
15595
+ var getEndUser = (options) => (options.client ?? client).get({
15596
+ security: [{
15597
+ key: "BearerAuth",
15598
+ scheme: "bearer",
15599
+ type: "http"
15600
+ }, {
15601
+ key: "ApiKeyAuth",
15602
+ name: "X-API-Key",
15603
+ type: "apiKey"
15604
+ }],
15605
+ url: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}",
15606
+ ...options
15607
+ });
15608
+ var getEndUserDeletion = (options) => (options.client ?? client).get({
15609
+ security: [{
15610
+ key: "BearerAuth",
15611
+ scheme: "bearer",
15612
+ type: "http"
15613
+ }, {
15614
+ key: "ApiKeyAuth",
15615
+ name: "X-API-Key",
15616
+ type: "apiKey"
15617
+ }],
15618
+ url: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/deletion",
15619
+ ...options
15620
+ });
15621
+ var revokeEndUserTokens = (options) => (options.client ?? client).post({
15622
+ security: [{
15623
+ key: "BearerAuth",
15624
+ scheme: "bearer",
15625
+ type: "http"
15626
+ }, {
15627
+ key: "ApiKeyAuth",
15628
+ name: "X-API-Key",
15629
+ type: "apiKey"
15630
+ }],
15631
+ url: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/revoke_tokens",
15632
+ ...options
15633
+ });
15634
+ var blockEndUser = (options) => (options.client ?? client).post({
15635
+ security: [{
15636
+ key: "BearerAuth",
15637
+ scheme: "bearer",
15638
+ type: "http"
15639
+ }, {
15640
+ key: "ApiKeyAuth",
15641
+ name: "X-API-Key",
15642
+ type: "apiKey"
15643
+ }],
15644
+ url: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/block",
15645
+ ...options
15646
+ });
15647
+ var unblockEndUser = (options) => (options.client ?? client).post({
15648
+ security: [{
15649
+ key: "BearerAuth",
15650
+ scheme: "bearer",
15651
+ type: "http"
15652
+ }, {
15653
+ key: "ApiKeyAuth",
15654
+ name: "X-API-Key",
15655
+ type: "apiKey"
15656
+ }],
15657
+ url: "/agent/v1/agents/{agent_id}/end_users/{external_user_id}/unblock",
15658
+ ...options
15659
+ });
15660
+ var exchangeEmbedCode = (options) => (options.client ?? client).post({
15661
+ url: "/agent/v1/embed/exchange",
15662
+ ...options,
15663
+ headers: {
15664
+ "Content-Type": "application/json",
15665
+ ...options.headers
15666
+ }
15667
+ });
15668
+ var createAnonymousEmbedToken = (options) => (options.client ?? client).post({
15669
+ url: "/agent/v1/embed_tokens/anonymous",
15670
+ ...options,
15671
+ headers: {
15672
+ "Content-Type": "application/json",
15673
+ ...options.headers
15674
+ }
15675
+ });
15135
15676
  var listEmbedTokens = (options) => (options?.client ?? client).get({
15136
15677
  security: [{
15137
15678
  key: "BearerAuth",
@@ -15316,6 +15857,36 @@ var connectComputer = (options) => (options.client ?? client).post({
15316
15857
  type: "apiKey"
15317
15858
  }],
15318
15859
  url: "/agent/v1/computers/{computer_id}/connect",
15860
+ ...options,
15861
+ headers: {
15862
+ "Content-Type": "application/json",
15863
+ ...options.headers
15864
+ }
15865
+ });
15866
+ var renewComputerLease = (options) => (options.client ?? client).post({
15867
+ security: [{
15868
+ key: "BearerAuth",
15869
+ scheme: "bearer",
15870
+ type: "http"
15871
+ }, {
15872
+ key: "ApiKeyAuth",
15873
+ name: "X-API-Key",
15874
+ type: "apiKey"
15875
+ }],
15876
+ url: "/agent/v1/computers/{computer_id}/leases/{lease_id}/renew",
15877
+ ...options
15878
+ });
15879
+ var releaseComputerLease = (options) => (options.client ?? client).delete({
15880
+ security: [{
15881
+ key: "BearerAuth",
15882
+ scheme: "bearer",
15883
+ type: "http"
15884
+ }, {
15885
+ key: "ApiKeyAuth",
15886
+ name: "X-API-Key",
15887
+ type: "apiKey"
15888
+ }],
15889
+ url: "/agent/v1/computers/{computer_id}/leases/{lease_id}",
15319
15890
  ...options
15320
15891
  });
15321
15892
  var listToolsets = (options) => (options?.client ?? client).get({
@@ -15443,6 +16014,15 @@ var listSessionCompactions = (options) => (options.client ?? client).get({
15443
16014
  url: "/agent/v1/sessions/{session_id}/compactions",
15444
16015
  ...options
15445
16016
  });
16017
+ var getEmbedAppearance = (options) => (options?.client ?? client).get({
16018
+ security: [{
16019
+ key: "BearerAuth",
16020
+ scheme: "bearer",
16021
+ type: "http"
16022
+ }, { name: "Praxis-Publishable-Key", type: "apiKey" }],
16023
+ url: "/agent/v1/embed/appearance",
16024
+ ...options
16025
+ });
15446
16026
  var createAudioSpeech = (options) => (options.client ?? client).post({
15447
16027
  security: [{
15448
16028
  key: "BearerAuth",
@@ -16211,6 +16791,19 @@ var createOrganizationFeedback = (options) => (options.client ?? client).post({
16211
16791
  ...options.headers
16212
16792
  }
16213
16793
  });
16794
+ var getOrganizationFeedbackCounts = (options) => (options?.client ?? client).get({
16795
+ security: [{
16796
+ key: "BearerAuth",
16797
+ scheme: "bearer",
16798
+ type: "http"
16799
+ }, {
16800
+ key: "ApiKeyAuth",
16801
+ name: "X-API-Key",
16802
+ type: "apiKey"
16803
+ }],
16804
+ url: "/organization/v1/feedback/counts",
16805
+ ...options
16806
+ });
16214
16807
  var getOrganizationFeedback = (options) => (options.client ?? client).get({
16215
16808
  security: [{
16216
16809
  key: "BearerAuth",
@@ -16546,7 +17139,7 @@ var runSandboxCommand = (options) => (options.client ?? client).post({
16546
17139
  ...options.headers
16547
17140
  }
16548
17141
  });
16549
- var agentsList = (options) => (options?.client ?? client).get({
17142
+ var sessionsDelete = (options) => (options.client ?? client).delete({
16550
17143
  security: [{
16551
17144
  key: "BearerAuth",
16552
17145
  scheme: "bearer",
@@ -16556,10 +17149,10 @@ var agentsList = (options) => (options?.client ?? client).get({
16556
17149
  name: "X-API-Key",
16557
17150
  type: "apiKey"
16558
17151
  }],
16559
- url: "/agent/v1/agents",
17152
+ url: "/agent/v1/sessions/{session_id}",
16560
17153
  ...options
16561
17154
  });
16562
- var agentsCreate = (options) => (options.client ?? client).post({
17155
+ var sessionsRetrieve = (options) => (options.client ?? client).get({
16563
17156
  security: [{
16564
17157
  key: "BearerAuth",
16565
17158
  scheme: "bearer",
@@ -16569,14 +17162,27 @@ var agentsCreate = (options) => (options.client ?? client).post({
16569
17162
  name: "X-API-Key",
16570
17163
  type: "apiKey"
16571
17164
  }],
16572
- url: "/agent/v1/agents",
17165
+ url: "/agent/v1/sessions/{session_id}",
17166
+ ...options
17167
+ });
17168
+ var sessionsUpdate = (options) => (options.client ?? client).post({
17169
+ security: [{
17170
+ key: "BearerAuth",
17171
+ scheme: "bearer",
17172
+ type: "http"
17173
+ }, {
17174
+ key: "ApiKeyAuth",
17175
+ name: "X-API-Key",
17176
+ type: "apiKey"
17177
+ }],
17178
+ url: "/agent/v1/sessions/{session_id}",
16573
17179
  ...options,
16574
17180
  headers: {
16575
17181
  "Content-Type": "application/json",
16576
17182
  ...options.headers
16577
17183
  }
16578
17184
  });
16579
- var agentsRetrieve = (options) => (options.client ?? client).get({
17185
+ var agentsList = (options) => (options?.client ?? client).get({
16580
17186
  security: [{
16581
17187
  key: "BearerAuth",
16582
17188
  scheme: "bearer",
@@ -16586,10 +17192,10 @@ var agentsRetrieve = (options) => (options.client ?? client).get({
16586
17192
  name: "X-API-Key",
16587
17193
  type: "apiKey"
16588
17194
  }],
16589
- url: "/agent/v1/agents/{agent_id}",
17195
+ url: "/agent/v1/agents",
16590
17196
  ...options
16591
17197
  });
16592
- var agentsUpdate = (options) => (options.client ?? client).post({
17198
+ var agentsCreate = (options) => (options.client ?? client).post({
16593
17199
  security: [{
16594
17200
  key: "BearerAuth",
16595
17201
  scheme: "bearer",
@@ -16599,14 +17205,14 @@ var agentsUpdate = (options) => (options.client ?? client).post({
16599
17205
  name: "X-API-Key",
16600
17206
  type: "apiKey"
16601
17207
  }],
16602
- url: "/agent/v1/agents/{agent_id}",
17208
+ url: "/agent/v1/agents",
16603
17209
  ...options,
16604
17210
  headers: {
16605
17211
  "Content-Type": "application/json",
16606
17212
  ...options.headers
16607
17213
  }
16608
17214
  });
16609
- var agentsArchive = (options) => (options.client ?? client).post({
17215
+ var agentsRetrieve = (options) => (options.client ?? client).get({
16610
17216
  security: [{
16611
17217
  key: "BearerAuth",
16612
17218
  scheme: "bearer",
@@ -16616,10 +17222,10 @@ var agentsArchive = (options) => (options.client ?? client).post({
16616
17222
  name: "X-API-Key",
16617
17223
  type: "apiKey"
16618
17224
  }],
16619
- url: "/agent/v1/agents/{agent_id}/archive",
17225
+ url: "/agent/v1/agents/{agent_id}",
16620
17226
  ...options
16621
17227
  });
16622
- var agentsVersionsList = (options) => (options.client ?? client).get({
17228
+ var agentsUpdate = (options) => (options.client ?? client).post({
16623
17229
  security: [{
16624
17230
  key: "BearerAuth",
16625
17231
  scheme: "bearer",
@@ -16629,10 +17235,14 @@ var agentsVersionsList = (options) => (options.client ?? client).get({
16629
17235
  name: "X-API-Key",
16630
17236
  type: "apiKey"
16631
17237
  }],
16632
- url: "/agent/v1/agents/{agent_id}/versions",
16633
- ...options
17238
+ url: "/agent/v1/agents/{agent_id}",
17239
+ ...options,
17240
+ headers: {
17241
+ "Content-Type": "application/json",
17242
+ ...options.headers
17243
+ }
16634
17244
  });
16635
- var sessionsList = (options) => (options?.client ?? client).get({
17245
+ var agentsArchive = (options) => (options.client ?? client).post({
16636
17246
  security: [{
16637
17247
  key: "BearerAuth",
16638
17248
  scheme: "bearer",
@@ -16642,10 +17252,10 @@ var sessionsList = (options) => (options?.client ?? client).get({
16642
17252
  name: "X-API-Key",
16643
17253
  type: "apiKey"
16644
17254
  }],
16645
- url: "/agent/v1/sessions",
17255
+ url: "/agent/v1/agents/{agent_id}/archive",
16646
17256
  ...options
16647
17257
  });
16648
- var sessionsCreate = (options) => (options.client ?? client).post({
17258
+ var agentsVersionsList = (options) => (options.client ?? client).get({
16649
17259
  security: [{
16650
17260
  key: "BearerAuth",
16651
17261
  scheme: "bearer",
@@ -16655,14 +17265,10 @@ var sessionsCreate = (options) => (options.client ?? client).post({
16655
17265
  name: "X-API-Key",
16656
17266
  type: "apiKey"
16657
17267
  }],
16658
- url: "/agent/v1/sessions",
16659
- ...options,
16660
- headers: {
16661
- "Content-Type": "application/json",
16662
- ...options.headers
16663
- }
17268
+ url: "/agent/v1/agents/{agent_id}/versions",
17269
+ ...options
16664
17270
  });
16665
- var sessionsRetrieve = (options) => (options.client ?? client).get({
17271
+ var sessionsList = (options) => (options?.client ?? client).get({
16666
17272
  security: [{
16667
17273
  key: "BearerAuth",
16668
17274
  scheme: "bearer",
@@ -16672,10 +17278,10 @@ var sessionsRetrieve = (options) => (options.client ?? client).get({
16672
17278
  name: "X-API-Key",
16673
17279
  type: "apiKey"
16674
17280
  }],
16675
- url: "/agent/v1/sessions/{session_id}",
17281
+ url: "/agent/v1/sessions",
16676
17282
  ...options
16677
17283
  });
16678
- var sessionsUpdate = (options) => (options.client ?? client).post({
17284
+ var sessionsCreate = (options) => (options.client ?? client).post({
16679
17285
  security: [{
16680
17286
  key: "BearerAuth",
16681
17287
  scheme: "bearer",
@@ -16685,7 +17291,7 @@ var sessionsUpdate = (options) => (options.client ?? client).post({
16685
17291
  name: "X-API-Key",
16686
17292
  type: "apiKey"
16687
17293
  }],
16688
- url: "/agent/v1/sessions/{session_id}",
17294
+ url: "/agent/v1/sessions",
16689
17295
  ...options,
16690
17296
  headers: {
16691
17297
  "Content-Type": "application/json",
@@ -17186,6 +17792,15 @@ var applicationCreateVersion = (options) => (options.client ?? client).post({
17186
17792
  ...options.headers
17187
17793
  }
17188
17794
  });
17795
+ var applicationGetVersionAssetManifest = (options) => (options.client ?? client).get({
17796
+ security: [{
17797
+ key: "application-bearerAuth",
17798
+ scheme: "bearer",
17799
+ type: "http"
17800
+ }],
17801
+ url: "/application/v1/workers/{worker_id}/versions/{version_id}/assets/manifest",
17802
+ ...options
17803
+ });
17189
17804
  var applicationGetVersion = (options) => (options.client ?? client).get({
17190
17805
  security: [{
17191
17806
  key: "application-bearerAuth",
@@ -20006,8 +20621,26 @@ function createAgent(transport) {
20006
20621
  agents: {
20007
20622
  archive: bind(transport, agentsArchive),
20008
20623
  create: bind(transport, agentsCreate),
20624
+ endUsers: {
20625
+ block: {
20626
+ create: bind(transport, blockEndUser)
20627
+ },
20628
+ delete: bind(transport, deleteEndUser),
20629
+ list: bind(transport, listEndUsers),
20630
+ retrieve: bind(transport, getEndUser),
20631
+ retrieveDeletion: bind(transport, getEndUserDeletion),
20632
+ revokeTokens: {
20633
+ create: bind(transport, revokeEndUserTokens)
20634
+ },
20635
+ unblock: {
20636
+ create: bind(transport, unblockEndUser)
20637
+ }
20638
+ },
20009
20639
  list: bind(transport, agentsList),
20010
20640
  retrieve: bind(transport, agentsRetrieve),
20641
+ unarchive: {
20642
+ create: bind(transport, unarchiveAgent)
20643
+ },
20011
20644
  update: bind(transport, agentsUpdate),
20012
20645
  versions: {
20013
20646
  list: bind(transport, agentsVersionsList)
@@ -20025,6 +20658,12 @@ function createAgent(transport) {
20025
20658
  list: bind(transport, computersFilesList),
20026
20659
  retrieveContent: bind(transport, computersFilesContent)
20027
20660
  },
20661
+ leases: {
20662
+ delete: bind(transport, releaseComputerLease),
20663
+ renew: {
20664
+ create: bind(transport, renewComputerLease)
20665
+ }
20666
+ },
20028
20667
  list: bind(transport, computersList),
20029
20668
  retrieve: bind(transport, computersRetrieve),
20030
20669
  update: bind(transport, computersUpdate)
@@ -20047,7 +20686,16 @@ function createAgent(transport) {
20047
20686
  },
20048
20687
  update: bind(transport, deploymentsUpdate)
20049
20688
  },
20689
+ embed: {
20690
+ exchange: {
20691
+ create: bind(transport, exchangeEmbedCode)
20692
+ },
20693
+ retrieveAppearance: bind(transport, getEmbedAppearance)
20694
+ },
20050
20695
  embedTokens: {
20696
+ anonymous: {
20697
+ create: bind(transport, createAnonymousEmbedToken)
20698
+ },
20051
20699
  create: bind(transport, createEmbedToken),
20052
20700
  list: bind(transport, listEmbedTokens),
20053
20701
  revoke: {
@@ -20073,6 +20721,7 @@ function createAgent(transport) {
20073
20721
  list: bind(transport, listSessionCompactions)
20074
20722
  },
20075
20723
  create: bind(transport, sessionsCreate),
20724
+ delete: bind(transport, sessionsDelete),
20076
20725
  events: {
20077
20726
  list: bind(transport, sessionsEventsList),
20078
20727
  send: bind(transport, sessionsEventsSend),
@@ -20154,6 +20803,9 @@ function createApplication(transport) {
20154
20803
  },
20155
20804
  update: bind(transport, applicationUpdateWorker),
20156
20805
  versions: {
20806
+ assets: {
20807
+ retrieveManifest: bind(transport, applicationGetVersionAssetManifest)
20808
+ },
20157
20809
  create: bind(transport, applicationCreateVersion),
20158
20810
  list: bindPage(transport, applicationListVersions),
20159
20811
  retrieve: bind(transport, applicationGetVersion)
@@ -20569,6 +21221,9 @@ function createOrganization(transport) {
20569
21221
  retrieve: bind(transport, getOrganizationEvent)
20570
21222
  },
20571
21223
  feedback: {
21224
+ counts: {
21225
+ list: bind(transport, getOrganizationFeedbackCounts)
21226
+ },
20572
21227
  create: bind(transport, createOrganizationFeedback),
20573
21228
  list: bind(transport, listOrganizationFeedback),
20574
21229
  messages: {
@@ -21067,9 +21722,13 @@ class Transport {
21067
21722
  };
21068
21723
  }
21069
21724
  async request(operation, options = {}) {
21725
+ return (await this.requestWithResponse(operation, options)).data;
21726
+ }
21727
+ async requestWithResponse(operation, options = {}) {
21070
21728
  const scope = this.scope(options, false);
21071
21729
  try {
21072
- return (await abortable(operation(scope.options), scope.signal)).data;
21730
+ const result = await abortable(operation(scope.options), scope.signal);
21731
+ return { data: result.data, response: result.response };
21073
21732
  } finally {
21074
21733
  scope.close();
21075
21734
  }
@@ -21101,6 +21760,10 @@ function base64(bytes) {
21101
21760
  return btoa(chunks.join(""));
21102
21761
  }
21103
21762
  async function publish(client2, input) {
21763
+ const rolloutFields = ["gradual", "gradualRollout", "gradual_rollout", "canary", "rollout", "percentage", "percent", "traffic", "traffic_percentage", "strategy", "versions"];
21764
+ if (Object.keys(input).some((key) => rolloutFields.includes(key) || /percentage|percent|canary|gradual|rollout|灰度/i.test(key))) {
21765
+ throw new PraxisError({ code: "INVALID_PARAMS", message: '平台不支持灰度 (gradual rollout is not supported). Roll back with praxis.application.workers.deployments.create({ path: { worker_id }, body: { strategy: "percentage", versions: [{ version_id: previousVersionId, percentage: 100 }] } }); the previous version artifacts must still be retained.' });
21766
+ }
21104
21767
  const timeout = input.timeout_ms ?? 120000;
21105
21768
  if (!Number.isFinite(timeout) || timeout < 0)
21106
21769
  throw new RangeError("timeout_ms must be non-negative and finite");
@@ -21119,7 +21782,7 @@ async function publish(client2, input) {
21119
21782
  const files = Object.entries(input.files);
21120
21783
  if (files.length > 1e5)
21121
21784
  throw new PraxisError({ code: "LIMIT_EXCEEDED", message: "At most 100000 asset paths can be published" });
21122
- const manifest = {};
21785
+ let manifest = {};
21123
21786
  const contents = new Map;
21124
21787
  for (const [path2, content] of files) {
21125
21788
  const normalized = path2.startsWith("/") ? path2 : `/${path2}`;
@@ -21128,8 +21791,8 @@ async function publish(client2, input) {
21128
21791
  const bytes = typeof content === "string" ? new TextEncoder().encode(content) : new Uint8Array(content);
21129
21792
  if (bytes.length > FILE_BYTES)
21130
21793
  throw new PraxisError({ code: "LIMIT_EXCEEDED", message: `Asset ${normalized} exceeds 25 MiB` });
21131
- const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
21132
- const hash = Array.from(digest.subarray(0, 16), (byte) => byte.toString(16).padStart(2, "0")).join("");
21794
+ const digest2 = new Uint8Array(await crypto.subtle.digest("SHA-256", bytes));
21795
+ const hash = Array.from(digest2.subarray(0, 16), (byte) => byte.toString(16).padStart(2, "0")).join("");
21133
21796
  manifest[normalized] = { hash, size: bytes.length };
21134
21797
  contents.set(hash, bytes);
21135
21798
  }
@@ -21142,9 +21805,60 @@ async function publish(client2, input) {
21142
21805
  }
21143
21806
  }
21144
21807
  const created = !worker;
21808
+ if (!worker && input.dryRun)
21809
+ throw new PraxisError({ code: "NOT_FOUND", message: "请先创建应用 (create the application before dryRun)" });
21145
21810
  worker ??= await workers.create({ body: { name: input.name, subdomain: { enabled: true } } });
21146
21811
  const path = { worker_id: worker.id };
21812
+ let currentVersion;
21813
+ let currentDeployment;
21814
+ let previous = {};
21815
+ if (worker.praxis?.current_deployment_id) {
21816
+ currentDeployment = await workers.deployments.retrieve({ path: { ...path, deployment_id: worker.praxis.current_deployment_id } });
21817
+ const active = currentDeployment.versions[0];
21818
+ if (!active)
21819
+ throw new PraxisError({ code: "INVALID_RESPONSE", message: "Current deployment has no version" });
21820
+ currentVersion = await workers.versions.retrieve({ path: { ...path, version_id: active.version_id } });
21821
+ previous = (await workers.versions.assets.retrieveManifest({ path: { ...path, version_id: active.version_id } })).manifest;
21822
+ }
21823
+ manifest = {
21824
+ ...Object.fromEntries(Object.entries(previous).filter(([key]) => input.keepExisting || Object.hasOwn(manifest, key))),
21825
+ ...manifest
21826
+ };
21827
+ if (Object.keys(manifest).length > 1e5)
21828
+ throw new PraxisError({ code: "LIMIT_EXCEEDED", message: "At most 100000 asset paths can be published" });
21829
+ const added = Object.keys(manifest).filter((key) => !Object.hasOwn(previous, key));
21830
+ const changed = Object.keys(manifest).filter((key) => previous[key] && (previous[key].hash !== manifest[key].hash || previous[key].size !== manifest[key].size));
21831
+ const removed = Object.keys(previous).filter((key) => !Object.hasOwn(manifest, key));
21832
+ const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(JSON.stringify(manifest))));
21833
+ const manifestHash = Array.from(digest, (byte) => byte.toString(16).padStart(2, "0")).join("");
21834
+ const staticOnly = !["main", "bindings", "compatibility_date", "compatibility_flags", "assets_config"].some((key) => Object.hasOwn(input, key));
21835
+ const unchanged = staticOnly && !!currentVersion && manifestHash === currentVersion.praxis.assets_manifest?.manifest_hash;
21836
+ const hashes = new Set(Object.values(manifest).map((entry) => entry.hash));
21837
+ const currentResult = {
21838
+ url: worker.subdomain.url,
21839
+ worker_id: worker.id,
21840
+ version_id: currentVersion?.id ?? null,
21841
+ deployment_id: currentDeployment?.id ?? null,
21842
+ status: currentDeployment?.praxis.status ?? "draft",
21843
+ created,
21844
+ ...currentVersion ? { version: currentVersion } : {},
21845
+ unchanged,
21846
+ uploaded: 0,
21847
+ reused: hashes.size
21848
+ };
21849
+ if (unchanged && !input.dryRun)
21850
+ return currentResult;
21147
21851
  const session = await workers.assetsUploadSession.create({ path, body: { manifest } });
21852
+ if (input.dryRun) {
21853
+ const missing = new Set(session.buckets.flat());
21854
+ if ([...missing].some((hash) => !hashes.has(hash)))
21855
+ throw new PraxisError({ code: "INVALID_RESPONSE", message: "Upload session requested an unknown hash" });
21856
+ return {
21857
+ ...currentResult,
21858
+ reused: hashes.size - missing.size,
21859
+ plan: { added, changed, removed, upload_hashes: missing.size, existing_hashes: hashes.size - missing.size }
21860
+ };
21861
+ }
21148
21862
  let jwt = session.buckets.length ? null : session.jwt;
21149
21863
  const uploaded = new Set;
21150
21864
  for (const bucket of session.buckets) {
@@ -21215,16 +21929,29 @@ async function publish(client2, input) {
21215
21929
  status: deployment.praxis.status,
21216
21930
  created,
21217
21931
  uploaded: uploaded.size,
21218
- reused: contents.size - uploaded.size
21932
+ reused: hashes.size - uploaded.size
21219
21933
  };
21220
21934
  }
21221
21935
 
21936
+ // ../../packages/sdk/typescript/src/helpers/database-count.ts
21937
+ async function count(transport, input) {
21938
+ const { response } = await transport.requestWithResponse(databaseHead, {
21939
+ path: { database_id: input.database_id, table: input.table },
21940
+ query: input.filters,
21941
+ headers: { Prefer: `count=${input.count ?? "exact"}` }
21942
+ });
21943
+ const total = response.headers.get("Content-Range")?.split("/")[1];
21944
+ return { count: total === undefined || total === "*" ? null : Number(total) };
21945
+ }
21946
+
21222
21947
  // ../../packages/sdk/typescript/src/core/client.ts
21223
21948
  class Praxis {
21224
21949
  constructor(options) {
21225
21950
  const transport = new Transport(options);
21226
21951
  for (const [name, create] of Object.entries(resourceFactories)) {
21227
21952
  const resource = create(transport);
21953
+ if (name === "database")
21954
+ Object.assign(resource, { count: (input) => count(transport, input) });
21228
21955
  if (name === "application")
21229
21956
  Object.assign(resource, { publish: (input) => publish(this, input) });
21230
21957
  Object.defineProperty(this, name, { value: resource, enumerable: true });
@@ -22356,7 +23083,7 @@ function plain(value) {
22356
23083
  }
22357
23084
 
22358
23085
  // src/output/human.ts
22359
- var count = (n, noun) => `${n} ${noun}${n === 1 ? "" : "s"}`;
23086
+ var count3 = (n, noun) => `${n} ${noun}${n === 1 ? "" : "s"}`;
22360
23087
  function identity(result, ctx) {
22361
23088
  const op = "op" in result ? result.op : undefined;
22362
23089
  const split = op?.lastIndexOf(".") ?? -1;
@@ -22444,7 +23171,7 @@ function objectView(data, resource, id, ctx, paint) {
22444
23171
  return v.map(scalar).map(plain).join(", ");
22445
23172
  folded = true;
22446
23173
  const preview = v.slice(0, 3).map((item) => record(item).id ?? record(item).name).filter((x) => x !== undefined).map((x) => plain(scalar(x)));
22447
- return `${count(v.length, "item")}${preview.length ? ` (${preview.join(", ")})` : ""}`;
23174
+ return `${count3(v.length, "item")}${preview.length ? ` (${preview.join(", ")})` : ""}`;
22448
23175
  }
22449
23176
  if (v !== null && typeof v === "object") {
22450
23177
  if (depth >= 1) {
@@ -22485,7 +23212,7 @@ function renderHuman(result, ctx) {
22485
23212
  return {
22486
23213
  stdout: result.items.length ? table(result.items, ctx, out) : out.dim(`No ${plain(resource)}${/(s|x|ch|sh)$/.test(resource) ? "es" : "s"}.`) + `
22487
23214
  `,
22488
- stderr: err.dim(`${result.total !== undefined ? `${result.items.length} of ${result.total} items` : count(result.items.length, "item")}${result.nextCursor ? ` · next: ${ctx.nextCommand ?? "praxis --help"}` : ""}`) + `
23215
+ stderr: err.dim(`${result.total !== undefined ? `${result.items.length} of ${result.total} items` : count3(result.items.length, "item")}${result.nextCursor ? ` · next: ${ctx.nextCommand ?? "praxis --help"}` : ""}`) + `
22489
23216
  `
22490
23217
  };
22491
23218
  case "object": {
@@ -22765,7 +23492,7 @@ function startProgress(ctx, write = (text) => writeOutput({ stderr: text })) {
22765
23492
  }
22766
23493
 
22767
23494
  // src/main.ts
22768
- var version = "0.1.0-dev.9d9e2b6";
23495
+ var version = "0.1.0-dev.a5cf3ce";
22769
23496
  var commands = commandTree(operations);
22770
23497
  var manual = [["login"], ["logout"], ["whoami"], ["org", "list"], ["org", "switch"], ["api"], ["skill"]];
22771
23498
  function route(argv) {