@deepraxis/cli 0.2.0-dev.a538fab → 0.2.0-dev.ed5af3e

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 (2) hide show
  1. package/dist/praxis.js +25 -38
  2. package/package.json +1 -1
package/dist/praxis.js CHANGED
@@ -8405,7 +8405,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
8405
8405
  resource: "file.files",
8406
8406
  method: "create",
8407
8407
  summary: "Upload file",
8408
- description: 'Upload a file to reuse in conversations or attach to a knowledge base. Unlike OpenAI Files, uploads must be nonempty and at most 100000000 bytes, and only user_data and vision purposes are accepted. Send file bytes as a multipart file part, not a filename or file ID; in the SDK use a File or Blob, for example new File(["Return within 23 days."], "policy.txt", { type: "text/plain" }). Content determines the MIME type. Supported uploads include PDF, DOCX/XLSX/PPTX, PNG/JPEG/GIF/WebP, MP3/WAV/FLAC/OGG/M4A, MP4/WebM, and UTF-8 JSON/NDJSON/CSV/Markdown/plain text; empty, unsupported, oversized files and unsupported purposes return 400. Use Uploads for larger files. The purpose vision accepts only PNG, JPEG, GIF and WebP, while conversation images require user_data. The returned ID belongs to your tenant; upload alone does not ingest the file into Knowledge. Knowledge attachment has a lower limit of 100000000 bytes. Optionally set expires_after[anchor]=created_at with expires_after[seconds] (3600–7776000). Without expiry, the file persists until deleted.',
8408
+ description: 'Upload a file to reuse in conversations or attach to a knowledge base. Unlike OpenAI Files, uploads must be nonempty and at most 100000000 bytes, and only user_data, assistants and vision purposes are accepted. Send file bytes as a multipart file part, not a filename or file ID; in the SDK use a File or Blob, for example new File(["Return within 23 days."], "policy.txt", { type: "text/plain" }). Content determines the MIME type. Supported uploads include PDF, DOCX/XLSX/PPTX, PNG/JPEG/GIF/WebP, MP3/WAV/FLAC/OGG/M4A, MP4/WebM, and UTF-8 JSON/NDJSON/CSV/Markdown/plain text; empty, unsupported, oversized files and unsupported purposes return 400. Use Uploads for larger files. The purpose vision accepts only PNG, JPEG, GIF and WebP, while conversation images require user_data. The returned ID belongs to your tenant; upload alone does not ingest the file into Knowledge. Knowledge attachment has a lower limit of 100000000 bytes. Optionally set expires_after[anchor]=created_at with expires_after[seconds] (3600–2592000), or praxis[expires_in_seconds] (3600–7776000), never both. Without expiry, the file persists until deleted.',
8409
8409
  http: "POST",
8410
8410
  path: "/file/v1/files",
8411
8411
  streaming: "no",
@@ -8427,16 +8427,23 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
8427
8427
  type: "string",
8428
8428
  enum: [
8429
8429
  "user_data",
8430
+ "assistants",
8430
8431
  "vision"
8431
8432
  ],
8432
8433
  required: true,
8433
- description: "Purpose label stored with the file: user_data or vision. The vision purpose accepts only PNG, JPEG, GIF and WebP images. Conversation image references require user_data."
8434
+ description: "Purpose label stored with the file: user_data, assistants or vision. The vision purpose accepts only PNG, JPEG, GIF and WebP images. Conversation image references require user_data."
8434
8435
  },
8435
8436
  {
8436
8437
  name: "expires_after",
8437
8438
  type: "object",
8438
8439
  required: false,
8439
8440
  description: "Optional expiry relative to created_at. Files without an expiry persist until deleted."
8441
+ },
8442
+ {
8443
+ name: "praxis",
8444
+ type: "object",
8445
+ required: false,
8446
+ description: "Own-face extensions. Use at most one expiry setting."
8440
8447
  }
8441
8448
  ]
8442
8449
  }
@@ -8499,7 +8506,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
8499
8506
  resource: "file.uploads",
8500
8507
  method: "create",
8501
8508
  summary: "Create an upload",
8502
- description: "Start a multipart upload for a file larger than the 100000000-byte direct-upload limit. Supply the exact byte length, filename, MIME type and purpose. Unlike OpenAI, uploads accept at most 2 GiB (2147483648 bytes) and only user_data and vision purposes. Add parts of at most 64000000 bytes and complete within one hour. Optional part_size enables fixed-size, retryable parts. expires_after applies to the resulting file (3600–7776000 seconds on this own face); without it the file persists until deleted.",
8509
+ description: "Start a multipart upload for a file larger than the 100000000-byte direct-upload limit. Supply the exact byte length, filename, MIME type and purpose. Unlike OpenAI, uploads accept at most 2 GiB (2147483648 bytes) and only user_data, assistants and vision purposes. Add parts of at most 64000000 bytes and complete within one hour. Optional part_size enables fixed-size, retryable parts. expires_after applies to the resulting file (3600–7776000 seconds on this own face); without it the file persists until deleted.",
8503
8510
  http: "POST",
8504
8511
  path: "/file/v1/uploads",
8505
8512
  streaming: "no",
@@ -8532,10 +8539,11 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
8532
8539
  type: "string",
8533
8540
  enum: [
8534
8541
  "user_data",
8542
+ "assistants",
8535
8543
  "vision"
8536
8544
  ],
8537
8545
  required: true,
8538
- description: "Use user_data for conversation attachments, or vision for PNG, JPEG, GIF and WebP images."
8546
+ description: "Use user_data for conversation attachments, assistants for assistant files, or vision for PNG, JPEG, GIF and WebP images."
8539
8547
  },
8540
8548
  {
8541
8549
  name: "expires_after",
@@ -9715,7 +9723,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
9715
9723
  name: "overwrite",
9716
9724
  type: "boolean",
9717
9725
  required: false,
9718
- description: "Allow replacing an existing public_id, preserving its asset_id and increasing its version. Only the latest version is deliverable; old version URLs return 404. Create a new public_id to retain old deliveries. False returns the existing resource without replacing it; defaults to true."
9726
+ description: "Allow replacing an existing public_id, preserving its asset_id and increasing its version. False returns the existing resource without replacing it; defaults to true."
9719
9727
  },
9720
9728
  {
9721
9729
  name: "tags",
@@ -9774,7 +9782,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
9774
9782
  name: "file_id",
9775
9783
  type: "string",
9776
9784
  required: true,
9777
- description: "File ID to copy into this library; passed as the upload source instead of file bytes. This creates an independent public copy readable without authentication. Deleting the source File does not delete this asset; do not import confidential content."
9785
+ description: "File ID to copy into this library; passed as the upload source instead of file bytes."
9778
9786
  },
9779
9787
  {
9780
9788
  name: "public_id",
@@ -9828,7 +9836,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
9828
9836
  name: "overwrite",
9829
9837
  type: "boolean",
9830
9838
  required: false,
9831
- description: "Allow replacing an existing public_id, preserving its asset_id and increasing its version. Only the latest version is deliverable; old version URLs return 404. Create a new public_id to retain old deliveries. False returns the existing resource without replacing it; defaults to true."
9839
+ description: "Allow replacing an existing public_id, preserving its asset_id and increasing its version. False returns the existing resource without replacing it; defaults to true."
9832
9840
  },
9833
9841
  {
9834
9842
  name: "tags",
@@ -10345,7 +10353,7 @@ The default is return=minimal: success returns HTTP 201 with an empty body. Send
10345
10353
  name: "expression",
10346
10354
  type: "string",
10347
10355
  required: false,
10348
- description: 'Asset filter expression supporting field comparisons, AND, OR, NOT, parentheses and suffix wildcards. An empty expression matches all assets. For business metadata use context.sku=KETTLE-RED AND context.revision=2; request with_field: ["context"] to include context.'
10356
+ description: "Asset filter expression supporting field comparisons, AND, OR, NOT, parentheses and suffix wildcards. An empty expression matches all assets."
10349
10357
  },
10350
10358
  {
10351
10359
  name: "sort_by",
@@ -26678,9 +26686,8 @@ function jwtFetch(fetchImpl, token) {
26678
26686
  function credentials(config, vars, ports) {
26679
26687
  const path = ports.path ?? tokenPath(config.env);
26680
26688
  const store = ports.store ?? createTokenStore(config.env, path, ports.secretStore);
26681
- const source = credentialSource(vars);
26682
26689
  const apiKey = vars.PRAXIS_API_KEY;
26683
- const machineToken = source === "machine-token" ? vars.PRAXIS_API_TOKEN : undefined;
26690
+ const machineToken = credentialSource(vars) === "machine-token" ? vars.PRAXIS_API_TOKEN : undefined;
26684
26691
  const remember = ports.remember ?? (() => {});
26685
26692
  if (apiKey)
26686
26693
  remember(apiKey);
@@ -26742,7 +26749,6 @@ function credentials(config, vars, ports) {
26742
26749
  }
26743
26750
  }
26744
26751
  return {
26745
- source,
26746
26752
  get,
26747
26753
  requireLogin,
26748
26754
  async client(org) {
@@ -26798,13 +26804,13 @@ function skillDocument(commands) {
26798
26804
  "## General rules",
26799
26805
  "",
26800
26806
  "- Select the environment only with `PRAXIS_ENV`; there is no `--env` option. The dev package defaults to develop.",
26801
- "- Authenticate with `PRAXIS_API_KEY`, `PRAXIS_API_TOKEN` (a machine token, sent in the Authorization header; computers have it set) or `praxis login`, in that order. Login saves the session even when an environment credential takes precedence; unset the named variable in its warning to use the saved login. API keys and machine tokens determine the organization; login sessions can use `--org <organization_id>`. `PRAXIS_API_URL` overrides the API base and must be an https deepraxis.com URL.",
26807
+ "- Authenticate with `PRAXIS_API_KEY`, `PRAXIS_API_TOKEN` (a machine token, sent in the Authorization header; computers have it set) or `praxis login`, in that order. API keys and machine tokens determine the organization; login sessions can use `--org <organization_id>`. `PRAXIS_API_URL` overrides the API base and must be an https deepraxis.com URL.",
26802
26808
  "- AI mode is enabled automatically in supported agent environments. Use `--format agent` to select it explicitly.",
26803
26809
  "- Use `--json` for the complete JSON response without presentation truncation. Successful JSON output goes to stdout; errors go to stderr.",
26804
26810
  "- Supply bodies with `--data JSON`, `--data @file.json`, or `--data -` for stdin. Scalar field options override matching JSON fields. Structured fields require `--data`.",
26805
26811
  "- Deletion requires `--yes` in AI mode. Confirm the intended resource before using it.",
26806
26812
  "- Use `--limit N` to limit a server page for SDK-paginated commands. Other lists apply it only to displayed rows; `--param-limit` still sends the API parameter when available. `--all` follows supported pagination and cannot be combined with `--limit`.",
26807
- "- Error JSON has an `error` object: `code` identifies the failure, `message` describes it, `hint` suggests recovery, `env` identifies the environment, `command` identifies the command, `status` is the HTTP status, and `request_id` correlates diagnostics. Authentication failures also include `credential_source` (api-key, machine-token, or login); follow the source-specific hint. Unavailable fields are null. Exit codes: 0 success, 1 runtime/API error, 2 usage error.",
26813
+ "- Error JSON has an `error` object: `code` identifies the failure, `message` describes it, `hint` suggests recovery, `env` identifies the environment, `command` identifies the command, `status` is the HTTP status, and `request_id` correlates diagnostics. Unavailable fields are null. Exit codes: 0 success, 1 runtime/API error, 2 usage error.",
26808
26814
  "- Append `--help` to a command for its optional parameters. Required scalar body options below can also be supplied as fields in `--data`.",
26809
26815
  "- Two layers: top-level commands (`login`, `org`, `skill`, …) are workflows and session commands; every API operation is under `praxis api <domain> …`. `praxis api <METHOD> <path>` sends a raw request (the method is uppercase).",
26810
26816
  "",
@@ -26935,12 +26941,7 @@ Enter code: ${code.user_code}` });
26935
26941
  const location = await (ports.store ?? createTokenStore(config.env, path)).save(toStored(flow.tokens, ports.now()));
26936
26942
  if (location !== "keychain")
26937
26943
  ports.emit({ kind: "message", channel: "stderr", text: "stored in a file (no system keychain available)" });
26938
- const shadowedBy = ports.source === "api-key" ? "PRAXIS_API_KEY" : ports.source === "machine-token" ? "PRAXIS_API_TOKEN" : undefined;
26939
26944
  ports.emit({ kind: "message", text: `Logged in (${config.env}).` });
26940
- if (shadowedBy)
26941
- ports.emit({ kind: "message", channel: "stderr", text: `Note: ${shadowedBy} is set and takes precedence over this login. Unset it (unset ${shadowedBy}) to use the login.` });
26942
- if (ports.json)
26943
- ports.emit({ kind: "object", data: { env: config.env, ...shadowedBy ? { shadowed_by: shadowedBy } : {} } });
26944
26945
  }
26945
26946
  async function whoami(auth, env, org) {
26946
26947
  const credential = await auth.get(org);
@@ -27742,7 +27743,7 @@ ${usage ? `usage: ${JSON.stringify(usage)}
27742
27743
 
27743
27744
  // src/output/render.ts
27744
27745
  function errorJSON(result, ctx) {
27745
- return JSON.stringify({ error: { code: result.code, message: result.message, hint: result.hint ?? null, env: result.env, command: ctx.command ?? null, status: result.status ?? null, request_id: result.request_id ?? null, ...result.credential_source ? { credential_source: result.credential_source } : {} } }) + `
27746
+ return JSON.stringify({ error: { code: result.code, message: result.message, hint: result.hint ?? null, env: result.env, command: ctx.command ?? null, status: result.status ?? null, request_id: result.request_id ?? null } }) + `
27746
27747
  `;
27747
27748
  }
27748
27749
  function render(result, ctx) {
@@ -27883,16 +27884,6 @@ var humanize = (code) => {
27883
27884
  const words = code.toLowerCase().split("_").filter(Boolean).join(" ");
27884
27885
  return words.charAt(0).toUpperCase() + words.slice(1);
27885
27886
  };
27886
- function authHint(source) {
27887
- switch (source) {
27888
- case "api-key":
27889
- return "The API key from PRAXIS_API_KEY was rejected; check or replace it, or unset it to use `praxis login`.";
27890
- case "machine-token":
27891
- return "The machine token from PRAXIS_API_TOKEN was rejected (it may have expired); unset it to use `praxis login`, or refresh it.";
27892
- case "login":
27893
- return "Run `praxis login` or set PRAXIS_API_KEY.";
27894
- }
27895
- }
27896
27887
  function errorInput(error, ctx) {
27897
27888
  const sdk = error instanceof PraxisError ? error : undefined;
27898
27889
  const raw = record(sdk?.raw), nested = record(raw.error);
@@ -27907,13 +27898,11 @@ function errorInput(error, ctx) {
27907
27898
  if (stripped)
27908
27899
  message = `${humanize(code)}${message ? `: ${message}` : ""}`;
27909
27900
  const status = sdk?.status, request_id = sdk?.requestId;
27910
- const authFailure = status === 401 || ["NOT_LOGGED_IN", "UNAUTHENTICATED", "TOKEN_REVOKED", "LOGIN_FAILED"].includes(code);
27911
- const source = ctx.credentialSource ?? "login";
27912
27901
  let hint = genericHint;
27913
27902
  if (error instanceof UsageError)
27914
27903
  hint = error.hint;
27915
- else if (authFailure)
27916
- hint = authHint(source);
27904
+ else if (status === 401 || ["NOT_LOGGED_IN", "UNAUTHENTICATED", "TOKEN_REVOKED", "LOGIN_FAILED"].includes(code))
27905
+ hint = "Run `praxis login` or set PRAXIS_API_KEY.";
27917
27906
  else if (status === 404)
27918
27907
  hint = ctx.listCommand ? `Check the id; list existing ones with \`${ctx.listCommand}\`` : "Check the id.";
27919
27908
  else if (status === 403)
@@ -27922,7 +27911,7 @@ function errorInput(error, ctx) {
27922
27911
  hint = "Rate limited; retry later.";
27923
27912
  else if (status !== undefined && status >= 500)
27924
27913
  hint = `Server error; retry later.${request_id ? ` Request id: ${request_id}.` : ""}`;
27925
- return { kind: "error", code, message, hint, env: ctx.env, ...authFailure ? { credential_source: source } : {}, ...status !== undefined ? { status } : {}, ...request_id ? { request_id } : {} };
27914
+ return { kind: "error", code, message, hint, env: ctx.env, ...status !== undefined ? { status } : {}, ...request_id ? { request_id } : {} };
27926
27915
  }
27927
27916
 
27928
27917
  // src/output/progress.ts
@@ -27952,7 +27941,7 @@ function startProgress(ctx, write = (text) => writeOutput({ stderr: text })) {
27952
27941
  }
27953
27942
 
27954
27943
  // src/main.ts
27955
- var version = "0.2.0-dev.a538fab";
27944
+ var version = "0.2.0-dev.ed5af3e";
27956
27945
  var commands = commandTree(operations);
27957
27946
  var manual = [...workflows.map((w) => w.words), [API_WORD]];
27958
27947
  function route(argv) {
@@ -28147,7 +28136,6 @@ Examples:
28147
28136
  const auth = credentials(config, ports.env, { fetch: wireFetch, now: ports.now, path, store, remember: (s) => {
28148
28137
  secrets.push(s);
28149
28138
  } });
28150
- ctx.credentialSource = auth.source;
28151
28139
  const org = flags.org;
28152
28140
  const confirm = (method) => confirmOperation(method, { yes: Boolean(flags.yes), noInput: Boolean(flags["no-input"]) || ctx.mode === "agent", stdinIsTTY: ports.stdinIsTTY, ask: async () => {
28153
28141
  stopProgress();
@@ -28214,8 +28202,7 @@ Examples:
28214
28202
  case "login":
28215
28203
  if (flags["no-input"] || quiet)
28216
28204
  throw new UsageError("login requires displaying a device code", "Remove --no-input / --quiet or set PRAXIS_API_KEY for scripts.");
28217
- ctx.credentialSource = "login";
28218
- await login(config, path, { ...ports, source: auth.source, json: ctx.mode === "json", store, fetch: wireFetch, emit, remember: (s) => secrets.push(s) });
28205
+ await login(config, path, { ...ports, store, fetch: wireFetch, emit, remember: (s) => secrets.push(s) });
28219
28206
  break;
28220
28207
  case "logout":
28221
28208
  emit({ kind: "message", text: await store.delete() ? "Logged out." : "Not logged in." });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepraxis/cli",
3
- "version": "0.2.0-dev.a538fab",
3
+ "version": "0.2.0-dev.ed5af3e",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "praxis": "dist/praxis.js"