@ax-hub/sdk 2.0.0 → 2.1.1

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/README.md CHANGED
@@ -18,6 +18,48 @@ agent-first Node.js SDK for AX Hub. Designed for Claude, Codex, and other coding
18
18
  | use admin/governance APIs | [`@ax-hub/admin-sdk`](../admin-sdk/README.md) |
19
19
  | upgrade from 0.x | [Migration & Upgrade](#migration--upgrade) |
20
20
 
21
+ ## Agent field guide from live QA (2026-06-08)
22
+
23
+ Use this section when an autonomous agent only has the README and must ship against AX Hub safely.
24
+
25
+ ### 1. Runtime inputs
26
+
27
+ ```bash
28
+ export AX_HUB_PAT="<short-lived PAT>"
29
+ export AX_HUB_TENANT_ID="cc1e58f1-8e46-4ac7-96c1-190c4cdd5b70" # test tenant
30
+ export AX_HUB_TENANT_SLUG="test"
31
+ ```
32
+
33
+ - PAT auth is `tokenType: 'pat'` and is sent as `X-Api-Key`.
34
+ - JWT auth is `tokenType: 'jwt'` and is sent as `Authorization: Bearer`.
35
+ - Never log the token. Redact env dumps before saving QA artifacts.
36
+
37
+ ### 2. Fastest safe live loop
38
+
39
+ 1. Create a timestamp-suffixed private app in tenant `test`.
40
+ 2. Set an env var, list env vars, then delete it and assert it is absent.
41
+ 3. Create a table with `owner_id`, `title`, `status`, and optional metadata columns.
42
+ 4. Add a column, inspect the table, then delete the column and inspect again.
43
+ 5. Add a table grant, list grants, revoke the grant, then assert the same grant id has `revokedAt`.
44
+ 6. Insert a row, get it by id, patch it, list it with a filter, count it, browse admin rows, then delete it.
45
+ 7. Assert row get after delete returns `404` or `410`.
46
+ 8. Delete the table and assert inspect after delete returns `404` or `410`.
47
+ 9. Soft-delete the app, then permanent-delete the app.
48
+
49
+ ### 3. Deletion semantics that prevent false positives
50
+
51
+ - Row delete: prove it by a follow-up `get` returning `404` or `410`.
52
+ - Table delete: prove it by a follow-up `inspect` returning `404` or `410`.
53
+ - Table grant delete: AX Hub currently soft-revokes. `listGrants` can still return the grant, but `revokedAt` must be set. Do not assert hard disappearance.
54
+ - Deploy without git/bootstrap source can return a precondition-style 4xx. That proves error handling, not a deployment failure.
55
+
56
+ ### 4. Production evidence already collected
57
+
58
+ - Node production mutation suite exercised app/env/comments/likes/table/columns/grants/data/OAuth/publication/deploy/git preconditions with exit `0`.
59
+ - A real app bootstrap/deploy wait succeeded in production: app `d31958ad-4a9b-4dcc-8951-64a1f3060c3d`, deployment `d3a48ce3-0f9c-4bab-aa07-863c31c44460`, final status `succeeded`, followed by app permanent delete.
60
+ - Go, Java, Kotlin, Python, and Ruby each hit 189 generated backend operation facades against the same production `test` tenant with SDK exceptions `0` and backend 5xx `0`.
61
+ - Go, Java, Kotlin, Python, and Ruby each passed the strict destructive DB loop above: 22 live steps, 17 assertions, 7 cleanup calls.
62
+
21
63
  ## Magic Moment
22
64
 
23
65
  ```ts
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';var fs=require('fs'),path=require('path');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;function t(e=process.cwd()){let r=[{name:"package.json",ok:fs.existsSync(path.resolve(e,"package.json"))},{name:"codegen/swagger.json",ok:fs.existsSync(path.resolve(e,"codegen/swagger.json"))},{name:"packages/sdk/src/index.ts",ok:fs.existsSync(path.resolve(e,"packages/sdk/src/index.ts"))}];return {ok:r.every(n=>n.ok),checks:r}}if((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('doctor.cjs', document.baseURI).href))===`file://${process.argv[1]}`){let e=t();process.stdout.write(`${JSON.stringify(e,null,2)}
3
- `),process.exit(e.ok?0:1);}exports.runDoctor=t;
2
+ 'use strict';var fs=require('fs'),path=require('path');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;var c=Object.defineProperty;var n=(e,o)=>c(e,"name",{value:o,configurable:true});function a(e=process.cwd()){let o=[{name:"package.json",ok:fs.existsSync(path.resolve(e,"package.json"))},{name:"codegen/swagger.json",ok:fs.existsSync(path.resolve(e,"codegen/swagger.json"))},{name:"packages/sdk/src/index.ts",ok:fs.existsSync(path.resolve(e,"packages/sdk/src/index.ts"))}];return {ok:o.every(t=>t.ok),checks:o}}n(a,"runDoctor");if((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('doctor.cjs', document.baseURI).href))===`file://${process.argv[1]}`){let e=a();process.stdout.write(`${JSON.stringify(e,null,2)}
3
+ `),process.exit(e.ok?0:1);}exports.runDoctor=a;
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import {existsSync}from'fs';import {resolve}from'path';function t(e=process.cwd()){let r=[{name:"package.json",ok:existsSync(resolve(e,"package.json"))},{name:"codegen/swagger.json",ok:existsSync(resolve(e,"codegen/swagger.json"))},{name:"packages/sdk/src/index.ts",ok:existsSync(resolve(e,"packages/sdk/src/index.ts"))}];return {ok:r.every(n=>n.ok),checks:r}}if(import.meta.url===`file://${process.argv[1]}`){let e=t();process.stdout.write(`${JSON.stringify(e,null,2)}
3
- `),process.exit(e.ok?0:1);}export{t as runDoctor};
2
+ import {existsSync}from'fs';import {resolve}from'path';var c=Object.defineProperty;var n=(e,o)=>c(e,"name",{value:o,configurable:true});function a(e=process.cwd()){let o=[{name:"package.json",ok:existsSync(resolve(e,"package.json"))},{name:"codegen/swagger.json",ok:existsSync(resolve(e,"codegen/swagger.json"))},{name:"packages/sdk/src/index.ts",ok:existsSync(resolve(e,"packages/sdk/src/index.ts"))}];return {ok:o.every(t=>t.ok),checks:o}}n(a,"runDoctor");if(import.meta.url===`file://${process.argv[1]}`){let e=a();process.stdout.write(`${JSON.stringify(e,null,2)}
3
+ `),process.exit(e.ok?0:1);}export{a as runDoctor};