@knowttl/artium-axi 0.0.25 → 0.0.26

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
@@ -133,7 +133,7 @@ Tool output limits vary; `--full` restores supported text within byte/time budge
133
133
  | Artium exit | Meaning |
134
134
  | --- | --- |
135
135
  | 0 | Success |
136
- | 1 | Authentication, server or transport failure |
136
+ | 1 | Authentication, server, transport or local CLI failure |
137
137
  | 2 | Usage or configuration error |
138
138
 
139
139
  See [output behavior](docs/client-reference.md#toon-output-behavior) and the generated [error catalogue](docs/errors.md).
@@ -142,6 +142,7 @@ See [output behavior](docs/client-reference.md#toon-output-behavior) and the gen
142
142
 
143
143
  | Symptom | Next step |
144
144
  | --- | --- |
145
+ | A tool call failed | Follow the tool's help and keep the stderr `request_id` for an administrator; see [troubleshooting a failed tool call](docs/runbook.md#troubleshoot-a-failed-tool-call). |
145
146
  | `CLIENT_CONFIG_INVALID` | Set the HTTPS URL and a readable CA file if needed, then sign in. |
146
147
  | `PASSWORD_CHANGE_REQUIRED` | Run `artium-axi passwd`, then sign in again. |
147
148
  | `CLI_OUTDATED` | Follow [installation-specific update guidance](docs/client-reference.md#verified-client). |
@@ -6,7 +6,6 @@ var __export = (target, all) => {
6
6
  };
7
7
 
8
8
  // src/cli/main.ts
9
- import { randomUUID as randomUUID5 } from "node:crypto";
10
9
  import { homedir as homedir3 } from "node:os";
11
10
  import { resolve as resolve4, relative, sep, isAbsolute as isAbsolute2 } from "node:path";
12
11
 
@@ -19740,6 +19739,7 @@ var definitions = {
19740
19739
  UPSTREAM_AUTH_FAILED: { status: 503, message: "The upstream service rejected the credential.", next: "Ask an administrator to check the provider code, identity, secret expiry and permissions, then test again." },
19741
19740
  UPSTREAM_NETWORK_FAILED: { status: 503, message: "The upstream service could not be reached.", next: "Ask an administrator to check DNS, routing, firewall rules and the diagnostic host and stage." },
19742
19741
  UPSTREAM_TLS_FAILED: { status: 503, message: "The upstream certificate could not be verified.", next: "Ask an administrator to check the host, certificate chain and trusted CA configuration." },
19742
+ UPSTREAM_RESPONSE_INVALID: { status: 503, message: "The upstream service returned a response the tool could not accept.", next: "Ask an administrator to inspect the diagnostic message and hint, check the service endpoint and API compatibility, then test again." },
19743
19743
  TOOL_REJECTED_INPUT: { status: 503, message: "The tool rejected its configuration or arguments.", next: "Ask an administrator to correct the field or combination named by the tool and test again." },
19744
19744
  TOOL_FAILED: { status: 503, message: "The tool exited unsuccessfully.", next: "Ask an administrator to inspect the diagnostic message and hint from Test credential." },
19745
19745
  INVALID_INPUT: { status: 400, message: "The request input is invalid.", next: "Check the request fields and content type." },
@@ -21365,6 +21365,8 @@ var auditCursorSchema = external_exports.string().max(50).regex(/^\d{1,16}:\d{1,
21365
21365
  return [ceiling, time3, id].every(Number.isSafeInteger) && ceiling > 0 && id > 0 && id <= ceiling && time3 <= 864e13;
21366
21366
  });
21367
21367
  var auditFiltersSchema = external_exports.strictObject({
21368
+ requestId: external_exports.string().min(1).max(100).optional(),
21369
+ failed: external_exports.enum(["0", "1"]).optional(),
21368
21370
  user: external_exports.string().min(1).max(256).optional(),
21369
21371
  tool: toolSchema.optional(),
21370
21372
  event: external_exports.string().min(1).max(100).optional(),
@@ -21507,7 +21509,7 @@ var nativeSettingsSchemas = {
21507
21509
  })
21508
21510
  };
21509
21511
  var diagnosticSchema = external_exports.strictObject({
21510
- stage: external_exports.enum(["configuration", "token acquisition", "DNS", "TCP", "TLS", "authentication", "tool run"]),
21512
+ stage: external_exports.enum(["configuration", "token acquisition", "DNS", "TCP", "TLS", "authentication", "response", "tool run"]),
21511
21513
  message: external_exports.string().max(4096),
21512
21514
  toolCode: external_exports.string().max(80).optional(),
21513
21515
  providerCode: external_exports.string().max(80).optional(),
@@ -22012,7 +22014,8 @@ var toolsResponseSchema = external_exports.strictObject({
22012
22014
  name: toolSchema,
22013
22015
  version: external_exports.string(),
22014
22016
  readOnly: external_exports.boolean().default(true),
22015
- status: external_exports.enum(["unconfigured", "unknown", "checking", "ok", "error", "disabled"])
22017
+ status: external_exports.enum(["unconfigured", "unknown", "checking", "ok", "error", "disabled"]),
22018
+ errorCode: healthSchema.shape.errorCode.optional()
22016
22019
  }))
22017
22020
  });
22018
22021
  var inputFileSchema = external_exports.strictObject({
@@ -22068,7 +22071,7 @@ import { resolve } from "node:path";
22068
22071
  // package.json
22069
22072
  var package_default = {
22070
22073
  name: "artium-axi",
22071
- version: "0.0.25",
22074
+ version: "0.0.26",
22072
22075
  private: true,
22073
22076
  license: "MIT",
22074
22077
  type: "module",
@@ -22321,7 +22324,9 @@ var Client = class {
22321
22324
  return this.storedSessions;
22322
22325
  }
22323
22326
  certificateVerified = false;
22327
+ requestId;
22324
22328
  async request(path, method, input2, token, bytes = false, headers = {}) {
22329
+ this.requestId = void 0;
22325
22330
  this.certificateVerified = false;
22326
22331
  let ca;
22327
22332
  try {
@@ -22341,6 +22346,8 @@ var Client = class {
22341
22346
  signal: AbortSignal.any([controller.signal, this.cancellation.signal]),
22342
22347
  headers: { ...headers, "x-artium-cli-version": cliVersion, ...token ? { authorization: `Bearer ${token}` } : {}, ...body ? { "content-type": "application/json" } : {} }
22343
22348
  }, (response) => {
22349
+ const requestId = response.headers["x-artium-request-id"];
22350
+ if (typeof requestId === "string" && /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/.test(requestId)) this.requestId = requestId;
22344
22351
  if (response.statusCode >= 300 && response.statusCode < 400) {
22345
22352
  response.destroy();
22346
22353
  reject(new ArtiumError("INVALID_RESPONSE", "Authenticated redirects are refused."));
@@ -44060,8 +44067,8 @@ var hybrid_axi_default = {
44060
44067
  var beyondtrust_axi_default = {
44061
44068
  generatedBy: "scripts/beyondtrust-inventory.mjs",
44062
44069
  tool: "beyondtrust-axi",
44063
- version: "0.1.1",
44064
- integrity: "sha512-B5Nc4eOIaAlceGRE8FfPbUMuwnedlKfzBYjGeozjqmAD1LVHYJBspQXiJuj7fCtOlUd9ea/axisM3RH82A6Wjg==",
44070
+ version: "0.1.3",
44071
+ integrity: "sha512-tDVP8+wEzdTg9mg/BwGSBmt+BXn7LJ4Ubbh9jAt3Z+g8K1bvZyKhD7gAPUMrYnFBjIGPJOhYfoIHt6RNO4qx3Q==",
44065
44072
  parserEvidence: "Published catalogue and reviewed native parsers, write coordinator, delete gates and download contracts",
44066
44073
  sources: [
44067
44074
  {
@@ -44070,7 +44077,7 @@ var beyondtrust_axi_default = {
44070
44077
  },
44071
44078
  {
44072
44079
  path: "dist/src/cli.js",
44073
- sha256: "3fc44bbbba5bb266e40b13e77d0bb61f356b169f9a67e69cec4ca65fe4919d03"
44080
+ sha256: "9847516327adc4e62d611ca27ee569c1f701229adf5e0de74b6ad15b8ce4d155"
44074
44081
  },
44075
44082
  {
44076
44083
  path: "dist/src/computer-writes.js",
@@ -44114,11 +44121,15 @@ var beyondtrust_axi_default = {
44114
44121
  },
44115
44122
  {
44116
44123
  path: "dist/src/resource-reads.js",
44117
- sha256: "28774772d3f2720324ffa8bf77580bcca0c922f2496d4d426de3922543680713"
44124
+ sha256: "ac21d7f6662d5f33ad80f2ddb3f218e4b1790ed1262a299a065e2a58d7fe8ff4"
44125
+ },
44126
+ {
44127
+ path: "dist/src/response-diagnostics.js",
44128
+ sha256: "dda9e4fbb5d9b6d7e5a763047ac6b0c3d1818c4f692719a04244b649fa040cb5"
44118
44129
  },
44119
44130
  {
44120
44131
  path: "dist/src/transport.js",
44121
- sha256: "9f2d93ffc01016d32782ad183580ecbaa9c5c799c1c5b559de2c829d83bdeb7a"
44132
+ sha256: "1a463695d1d57a74e99894f4bffc0a4e72f1b68695995824db6e2884c0b5c780"
44122
44133
  },
44123
44134
  {
44124
44135
  path: "dist/src/windows-download.js",
@@ -44141,11 +44152,15 @@ var beyondtrust_axi_default = {
44141
44152
  ],
44142
44153
  properties: {
44143
44154
  clientId: {
44155
+ title: "Client ID",
44156
+ description: "The PM Cloud API account client ID.",
44144
44157
  type: "string",
44145
44158
  minLength: 1,
44146
44159
  pattern: "\\S"
44147
44160
  },
44148
44161
  clientSecret: {
44162
+ title: "Client secret",
44163
+ description: "An environment variable or absolute file SecretRef for the API account client secret; never an inline secret. Defaults to BEYONDTRUST_AXI_CLIENT_SECRET.",
44149
44164
  $ref: "#/$defs/secretRef",
44150
44165
  "x-secret": true,
44151
44166
  default: {
@@ -44153,6 +44168,8 @@ var beyondtrust_axi_default = {
44153
44168
  }
44154
44169
  },
44155
44170
  downloads: {
44171
+ title: "Download permissions",
44172
+ description: "Set allow to true to permit raw-byte downloads from a named file profile to a new private destination file. Downloads are disabled by default.",
44156
44173
  type: "object",
44157
44174
  additionalProperties: false,
44158
44175
  required: [
@@ -44168,6 +44185,8 @@ var beyondtrust_axi_default = {
44168
44185
  }
44169
44186
  },
44170
44187
  writes: {
44188
+ title: "Write permissions",
44189
+ description: "Set allowWrites and list exact operations to permit writes from a named file profile. Deletes also require allowDeletes. Writes and deletes are disabled by default.",
44171
44190
  type: "object",
44172
44191
  additionalProperties: false,
44173
44192
  required: [
@@ -44197,6 +44216,8 @@ var beyondtrust_axi_default = {
44197
44216
  }
44198
44217
  },
44199
44218
  host: {
44219
+ title: "PM Cloud API host",
44220
+ description: "The PM Cloud API host as a lowercase DNS name in the documented <organization>-services.pm.beyondtrustcloud.com form, ending in .beyondtrustcloud.com, with no scheme, port or path.",
44200
44221
  type: "string",
44201
44222
  maxLength: 253,
44202
44223
  pattern: "^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+beyondtrustcloud\\.com(?![\\s\\S])"
@@ -44235,7 +44256,7 @@ var beyondtrust_axi_default = {
44235
44256
  }
44236
44257
  }
44237
44258
  },
44238
- skillSha256: "7fed424c9547defcf4f9d2920358bd5f26a60b12aa46b817e7126053de36c881",
44259
+ skillSha256: "9a81f665262f4e3fb473f193948c0327f1bc114f3e64fe41337c027df433afbb",
44239
44260
  nativeWriteSettings: {
44240
44261
  supportedOperations: [
44241
44262
  "admin-request.create",
@@ -45858,13 +45879,13 @@ var beyondtrust_axi_default = {
45858
45879
  var checkpoint_axi_default = {
45859
45880
  generatedBy: "scripts/checkpoint-inventory.mjs",
45860
45881
  tool: "checkpoint-axi",
45861
- version: "0.1.1",
45862
- integrity: "sha512-xkVncU3PYUeGFD5vIMp/lT9JAsTsSaCTVF+dEFYye1iSDkjPjuHJDHnZ8BquT3ClHw9bcBWdLAnEtJRPSVimtg==",
45882
+ version: "0.1.3",
45883
+ integrity: "sha512-bQKjlciR/QO0reXfNK2HXUxpb1WlyZ3snIllEqQagE8C/d4PvaZ17nxwxm5Bws+PNNkYlzbUMUbqRBINpE2jEQ==",
45863
45884
  parserEvidence: "Published catalogue, fixed regional map and reviewed native parsers, write coordinator and download contracts",
45864
45885
  sources: [
45865
45886
  {
45866
45887
  path: "dist/src/catalogue.js",
45867
- sha256: "59b9568b614a101e2746a8275768c238ba8eb7166185119875a40f7eac191f7a"
45888
+ sha256: "3a56a877ea51b473f1b7f2c021920a6a391663eea395d01dd1fe18d5e9c1f0bf"
45868
45889
  },
45869
45890
  {
45870
45891
  path: "dist/src/cli.js",
@@ -45884,7 +45905,7 @@ var checkpoint_axi_default = {
45884
45905
  },
45885
45906
  {
45886
45907
  path: "dist/src/local-commands.js",
45887
- sha256: "ed9c39e204d42f45ae3c5b8008bf1c719d88f8e7214168f68de4d15921e35299"
45908
+ sha256: "f02799ed52ab05c2b6b61aa39c1406921f5ba20bdae20d33856f9c55c023254e"
45888
45909
  },
45889
45910
  {
45890
45911
  path: "dist/src/private-file.js",
@@ -45892,11 +45913,11 @@ var checkpoint_axi_default = {
45892
45913
  },
45893
45914
  {
45894
45915
  path: "dist/src/profiles.js",
45895
- sha256: "db013b041bb6302993d7045fe3bd411bbd1a3593b5b2a84a3d8411645f55d3e6"
45916
+ sha256: "8032b342fa9bc8492f436015dff09c41cddbb394d62305662c46007d6f541c8f"
45896
45917
  },
45897
45918
  {
45898
45919
  path: "dist/src/reads.js",
45899
- sha256: "02a5478edb3d44ab51ea300095794abc69d9e4a353060af4faed0d6e4ce592a7"
45920
+ sha256: "a9484c1410d2ef1e41f6754c001df977405f02a95bc5d9ae164b1e49bf06b633"
45900
45921
  },
45901
45922
  {
45902
45923
  path: "dist/src/redact.js",
@@ -45906,9 +45927,13 @@ var checkpoint_axi_default = {
45906
45927
  path: "dist/src/regions.js",
45907
45928
  sha256: "44288abe19a68fa672bc04ad167141717aed5c3a333b2420b14ee68e13abee78"
45908
45929
  },
45930
+ {
45931
+ path: "dist/src/response-invalid.js",
45932
+ sha256: "323428f95087fec84e36dab86c7a64ecad69f43e9188f6c6425b64498dac6b5c"
45933
+ },
45909
45934
  {
45910
45935
  path: "dist/src/transport.js",
45911
- sha256: "7beb28cc283e876db4f6aeaf5c308280e1fce482c20c19dd9924e29985e54e56"
45936
+ sha256: "fbc3a5c5c7ed35e3cf58cfdbaa6999c2eec4f639468c905629f45c2276b5f583"
45912
45937
  },
45913
45938
  {
45914
45939
  path: "dist/src/write-exceptions.js",
@@ -45935,6 +45960,8 @@ var checkpoint_axi_default = {
45935
45960
  ],
45936
45961
  properties: {
45937
45962
  region: {
45963
+ title: "Region",
45964
+ description: "Required region code for your tenant's regional gateway: us, eu, ca, au, uk, uae or in. Obtain it from your tenant administrator. There is no default; URLs are not accepted.",
45938
45965
  type: "string",
45939
45966
  enum: [
45940
45967
  "us",
@@ -45947,11 +45974,15 @@ var checkpoint_axi_default = {
45947
45974
  ]
45948
45975
  },
45949
45976
  clientId: {
45977
+ title: "Client ID",
45978
+ description: "Required non-blank API client ID from your tenant's API credentials. There is no default.",
45950
45979
  type: "string",
45951
45980
  minLength: 1,
45952
45981
  pattern: "\\S"
45953
45982
  },
45954
45983
  clientSecret: {
45984
+ title: "Client secret reference",
45985
+ description: "Reference the environment variable or absolute private file containing your API client secret, never the secret itself. If omitted, reads CHECKPOINT_AXI_CLIENT_SECRET; a missing or blank secret prevents authentication.",
45955
45986
  $ref: "#/$defs/secretRef",
45956
45987
  "x-secret": true,
45957
45988
  default: {
@@ -45959,17 +45990,26 @@ var checkpoint_axi_default = {
45959
45990
  }
45960
45991
  },
45961
45992
  saas: {
45993
+ title: "SaaS application name",
45994
+ description: "One non-blank SaaS application name for the tenant, not a gateway, host or authentication URL; slash (/) is not allowed. Obtain the exact API application name from your tenant administrator or Check Point support. If omitted, defaults to office365_emails, selecting Microsoft 365 email; supply the appropriate name for another application. A profile takes one value, while --saas on event list accepts a comma-separated list.",
45962
45995
  type: "string",
45963
45996
  minLength: 1,
45964
45997
  pattern: "\\S",
45998
+ not: {
45999
+ pattern: "/"
46000
+ },
45965
46001
  default: "office365_emails"
45966
46002
  },
45967
46003
  scope: {
46004
+ title: "Download scope",
46005
+ description: "Download scope value supplied by your tenant administrator or Check Point support for the intended download. Use printable ASCII with no spaces (characters ! through ~); comma-separated values are sent verbatim. There is no default: omitted means unset, so email download fails because it requires the profile scope as its scopes header. Attachment download uses this only as the default scope query; --scope overrides it, and neither supplied means no scope query. Tenant scope authorization and the relationship between these selectors remain unverified; do not guess a value.",
45968
46006
  type: "string",
45969
46007
  minLength: 1,
45970
- pattern: "\\S"
46008
+ pattern: "^[!-~]+$"
45971
46009
  },
45972
46010
  downloads: {
46011
+ title: "Download permission",
46012
+ description: "Separate file-profile download opt-in. If omitted, downloads are disabled. Environment profiles cannot enable downloads.",
45973
46013
  type: "object",
45974
46014
  additionalProperties: false,
45975
46015
  required: [
@@ -45980,11 +46020,15 @@ var checkpoint_axi_default = {
45980
46020
  },
45981
46021
  properties: {
45982
46022
  allow: {
46023
+ title: "Allow downloads",
46024
+ description: "Set true to permit download commands; each command still requires a new private output file.",
45983
46025
  type: "boolean"
45984
46026
  }
45985
46027
  }
45986
46028
  },
45987
46029
  writes: {
46030
+ title: "Write permissions",
46031
+ description: "File-profile write opt-in and exact operation allow-list. If omitted, writes are disabled with no allowed operations. Forced read-only always wins.",
45988
46032
  type: "object",
45989
46033
  additionalProperties: false,
45990
46034
  required: [
@@ -45997,9 +46041,13 @@ var checkpoint_axi_default = {
45997
46041
  },
45998
46042
  properties: {
45999
46043
  allowWrites: {
46044
+ title: "Allow writes",
46045
+ description: "Set true to permit listed operations, subject to preview, exact confirmation and durable redacted intent.",
46000
46046
  type: "boolean"
46001
46047
  },
46002
46048
  operations: {
46049
+ title: "Allowed write operations",
46050
+ description: "Exact operation names to allow, such as email.quarantine. An empty list permits no writes.",
46003
46051
  type: "array",
46004
46052
  items: {
46005
46053
  type: "string",
@@ -46020,6 +46068,8 @@ var checkpoint_axi_default = {
46020
46068
  ],
46021
46069
  properties: {
46022
46070
  env: {
46071
+ title: "Secret environment variable",
46072
+ description: "Name of the environment variable holding the secret, such as CHECKPOINT_AXI_CLIENT_SECRET. Use letters, digits and underscores, starting with a letter or underscore.",
46023
46073
  type: "string",
46024
46074
  pattern: "^[A-Za-z_][A-Za-z0-9_]*$"
46025
46075
  }
@@ -46033,6 +46083,8 @@ var checkpoint_axi_default = {
46033
46083
  ],
46034
46084
  properties: {
46035
46085
  file: {
46086
+ title: "Secret file path",
46087
+ description: "Absolute path to a private UTF-8 file holding the secret. Symlinks and insecure permissions are rejected; a leading BOM and trailing whitespace are removed from its content.",
46036
46088
  type: "string",
46037
46089
  pattern: "^(?:/|[A-Za-z]:[\\\\/])"
46038
46090
  }
@@ -46051,7 +46103,7 @@ var checkpoint_axi_default = {
46051
46103
  uae: "https://cloudinfra-gw.me.portal.checkpoint.com",
46052
46104
  in: "https://cloudinfra-gw.in.portal.checkpoint.com"
46053
46105
  },
46054
- skillSha256: "b64e7d373d92331cf653ef4478b2438e57c801032ed8cad7e161ed5fa6cc73a0",
46106
+ skillSha256: "33011d4e7abc8fd76b0b3b38450cfdff545117a1950e22ee5176ab3c2cf589c9",
46055
46107
  nativeWriteSettings: {
46056
46108
  supportedOperations: [
46057
46109
  "attachment.download",
@@ -46249,7 +46301,10 @@ var checkpoint_axi_default = {
46249
46301
  limit: "Maximum rows; default 50, range 1-1000; cannot combine with --all",
46250
46302
  all: "Read up to 1000 rows / 10 HTTP requests / 60 seconds / 8 MiB; default false",
46251
46303
  cursor: "Opaque continuation bound to profile, region, operation and selectors; repeat original selectors",
46252
- filter: "JSON array of {saasAttrName, saasAttrOp, saasAttrValue} filters (guide pages 19-20)"
46304
+ expand: "Opt in to read-only show details on returned rows; default false; partial expansion is reported separately",
46305
+ "expand-limit": "Maximum detail attempts; default 5, range 1-8; requires --expand",
46306
+ "expand-requests": "Total HTTP request cap including auth, list pages, detail and retries; default 10, range 2-10; requires --expand",
46307
+ filter: "JSON array of {saasAttrName, saasAttrOp, saasAttrValue} filters. saasAttrName is a field path, not a closed enum (guide pages 19-20). Documented examples: entityPayload.subject, entityPayload.fromEmail, entityPayload.attachmentCount. Other documented email payload paths (pages 15-16, 24-25): entityPayload.internetMessageId, entityPayload.received, entityPayload.size, entityPayload.emailLinks, entityPayload.attachments, entityPayload.mode, entityPayload.recipients, entityPayload.fromDomain, entityPayload.fromUser, entityPayload.fromName, entityPayload.to, entityPayload.toUser, entityPayload.cc, entityPayload.ccUser, entityPayload.bcc, entityPayload.bccUser, entityPayload.replyToEmail, entityPayload.replyToNickname, entityPayload.isRead, entityPayload.isDeleted, entityPayload.isIncoming, entityPayload.isInternal, entityPayload.isOutgoing, entityPayload.isQuarantined, entityPayload.isQuarantineNotification, entityPayload.isRestored, entityPayload.isRestoreRequested, entityPayload.isRestoreDeclined, entityPayload.saasSpamVerdict, entityPayload.SpfResult. saasAttrOp: is, contains, startsWith, isEmpty, isNot, notContains, isNotEmpty, greaterThan, lessThan. The guide defines operators globally, without a per-field compatibility matrix; examples pair fromEmail with is and attachmentCount with greaterThan. saasAttrValue is a string."
46253
46308
  }
46254
46309
  },
46255
46310
  {
@@ -46293,6 +46348,9 @@ var checkpoint_axi_default = {
46293
46348
  limit: "Maximum rows; default 50, range 1-1000; cannot combine with --all",
46294
46349
  all: "Read up to 1000 rows / 10 HTTP requests / 60 seconds / 8 MiB; default false",
46295
46350
  cursor: "Opaque continuation bound to profile, region, operation and selectors; repeat original selectors",
46351
+ expand: "Opt in to read-only show details on returned rows; default false; partial expansion is reported separately",
46352
+ "expand-limit": "Maximum detail attempts; default 5, range 1-8; requires --expand",
46353
+ "expand-requests": "Total HTTP request cap including auth, list pages, detail and retries; default 10, range 2-10; requires --expand",
46296
46354
  saas: "Comma-separated SaaS overrides; default selected profile saas or office365_emails",
46297
46355
  "event-types": "Comma-separated event types; default unfiltered",
46298
46356
  "event-states": "Comma-separated event states; default unfiltered",
@@ -46445,7 +46503,11 @@ var checkpoint_axi_default = {
46445
46503
  profile: "Profile name; default CHECKPOINT_AXI_PROFILE, env profile, config default, or sole profile",
46446
46504
  fields: "Comma-separated output fields; default all",
46447
46505
  full: "Show full strings instead of 500-character previews; default false",
46448
- help: "Show concise command help; default false"
46506
+ help: "Show concise command help; default false",
46507
+ wait: "Poll existing task status only; default false; requires --timeout; terminal: completed, failed, stopped",
46508
+ timeout: "Total wait timeout in integer seconds, range 1-60; required with --wait; includes auth and retries",
46509
+ "poll-interval": "Seconds between status reads; default 2, range 1-10; requires --wait",
46510
+ "wait-requests": "Total HTTP request cap including auth and retries; default 10, range 2-10; requires --wait"
46449
46511
  }
46450
46512
  }
46451
46513
  ]
@@ -47874,6 +47936,13 @@ function rewriteDiscoveryHelp(help, tool) {
47874
47936
  examples: help.examples.map((example) => hostedHelp(example, tool, flags, true))
47875
47937
  });
47876
47938
  }
47939
+ function encodeSuggestion(value, inline) {
47940
+ try {
47941
+ if (value && !(inline && value.includes(",")) && decode3(`value: ${value}`).value === value) return value;
47942
+ } catch {
47943
+ }
47944
+ return JSON.stringify(value);
47945
+ }
47877
47946
  function rewriteSuggestions(output3, tool, truncated = false, invocation) {
47878
47947
  if (truncated) return output3;
47879
47948
  if (tool === "gh-axi") return rewriteGhSuggestions(output3, invocation, truncated);
@@ -47964,6 +48033,7 @@ function rewriteSuggestions(output3, tool, truncated = false, invocation) {
47964
48033
  const executable = new RegExp(`^(?:artium-axi |npx -y @knowttl/)?${tool}(?=\\s|$)`);
47965
48034
  if (executable.test(output3.replace(/^[ \t]*(?:(?:Command|Native operation|Examples|Usage): )?/, "")) || tool === "ldap-axi" && ldapHelp.test(output3)) return hostedHelp(output3, tool, flags, true);
47966
48035
  let spans;
48036
+ let field;
47967
48037
  let unknownOutcome = false;
47968
48038
  try {
47969
48039
  const json2 = output3.trimStart().startsWith("{");
@@ -47993,16 +48063,41 @@ function rewriteSuggestions(output3, tool, truncated = false, invocation) {
47993
48063
  }
47994
48064
  const { spans: suggestions, document } = parsed;
47995
48065
  spans = suggestions;
48066
+ field = parsed.field;
47996
48067
  if (tool === "az-axi") {
47997
48068
  unknownOutcome = document?.code === "UNKNOWN_OUTCOME" || document?.error?.code === "UNKNOWN_OUTCOME";
47998
48069
  }
47999
48070
  } catch {
48000
48071
  return output3;
48001
48072
  }
48002
- for (const span of [...spans].reverse()) {
48003
- const value = hostedHelp(span.value, tool, flags, /^[ \t]*(?:Command|Native operation|Examples|Usage):/m.test(span.value));
48004
- if (value === span.value) continue;
48005
- output3 = output3.slice(0, span.start) + (span.quoted || ["ldap-axi", "ado-axi", "awx-axi", "gh-axi"].includes(tool) && /[,\r\n]/.test(value) ? JSON.stringify(value) : value) + output3.slice(span.start + span.raw.length);
48073
+ const replacements = spans.map((span) => hostedHelp(span.value, tool, flags, /^[ \t]*(?:Command|Native operation|Examples|Usage):/m.test(span.value)));
48074
+ if (field && replacements.some((value) => !value.trim())) {
48075
+ const values = replacements.filter((value) => value.trim());
48076
+ const help = field.array ? values : values[0] ?? "";
48077
+ const replacement = output3.trimStart().startsWith("{") ? JSON.stringify(help) : field.array && !values.length ? "help[0]:" : encode3({ help });
48078
+ output3 = output3.slice(0, field.start) + replacement + output3.slice(field.end);
48079
+ } else {
48080
+ const edits = [];
48081
+ const lists = /* @__PURE__ */ new Map();
48082
+ for (let index = 0; index < spans.length; index++) {
48083
+ const span = spans[index];
48084
+ const value = replacements[index];
48085
+ const changed = value !== span.value;
48086
+ const text2 = span.quoted ? JSON.stringify(value) : encodeSuggestion(value, Boolean(span.list));
48087
+ if (!span.list) {
48088
+ if (changed) edits.push({ start: span.start, end: span.start + span.raw.length, text: text2 });
48089
+ continue;
48090
+ }
48091
+ const list = lists.get(span.list) ?? { items: [], changed: false };
48092
+ if (!changed) list.items.push(span.raw);
48093
+ else if (value) list.items.push(text2);
48094
+ list.changed ||= changed;
48095
+ lists.set(span.list, list);
48096
+ }
48097
+ for (const [{ countStart, end }, { items, changed }] of lists) {
48098
+ if (changed) edits.push({ start: countStart, end, text: `${items.length}]:${items.length ? ` ${items.join(",")}` : ""}` });
48099
+ }
48100
+ for (const edit of edits.sort((a, b) => b.start - a.start)) output3 = output3.slice(0, edit.start) + edit.text + output3.slice(edit.end);
48006
48101
  }
48007
48102
  spans = (output3.trimStart().startsWith("{") ? jsonHelp(output3) : toonHelp(output3)).spans;
48008
48103
  if (spans.some((span) => /\\[`'"]/.test(span.value))) return output3;
@@ -48156,8 +48251,10 @@ function jsonHelp(output3) {
48156
48251
  const spans = [];
48157
48252
  let index = 0;
48158
48253
  let helpFields = 0;
48254
+ let field;
48159
48255
  function value(help = false, root = false) {
48160
48256
  const token = tokens[index++];
48257
+ const start = token.index;
48161
48258
  if (token[0] === "{") {
48162
48259
  while (tokens[index][0] !== "}") {
48163
48260
  const key = JSON.parse(tokens[index++][0]);
@@ -48176,21 +48273,23 @@ function jsonHelp(output3) {
48176
48273
  } else if (help && token[0].startsWith('"')) {
48177
48274
  spans.push({ start: token.index, raw: token[0], value: JSON.parse(token[0]), quoted: true });
48178
48275
  }
48276
+ if (help) field = { start, end: tokens[index - 1].index + tokens[index - 1][0].length, array: token[0] === "[" };
48179
48277
  }
48180
48278
  value(false, true);
48181
- return { spans: helpFields === 1 ? spans : [], document: parsed };
48279
+ return { spans: helpFields === 1 ? spans : [], field: helpFields === 1 ? field : void 0, document: parsed };
48182
48280
  }
48183
48281
  function toonHelp(output3) {
48184
48282
  const lines = [...output3.matchAll(/[^\r\n]*(?:\r\n|\n|$)/g)].filter((line) => line[0]);
48185
48283
  const spans = [];
48186
48284
  const validation = lines.map((line) => line[0].replace(/\r?\n$/, ""));
48187
48285
  let helpFields = 0;
48188
- function scalar(raw, start) {
48286
+ let range;
48287
+ function scalar(raw, start, list) {
48189
48288
  const parsed2 = decode3(`value: ${raw}`);
48190
48289
  if (typeof parsed2.value !== "string") throw new Error("Unknown suggestion format");
48191
48290
  const quoted = raw.startsWith('"');
48192
48291
  if (quoted && JSON.parse(raw) !== parsed2.value) throw new Error("Unknown escaping");
48193
- spans.push({ start, raw, value: parsed2.value, quoted });
48292
+ spans.push({ start, raw, value: parsed2.value, quoted, ...list ? { list } : {} });
48194
48293
  }
48195
48294
  for (let index = 0; index < lines.length; index++) {
48196
48295
  const text2 = lines[index][0].replace(/\r?\n$/, "");
@@ -48206,6 +48305,7 @@ ${line[0]}`);
48206
48305
  }
48207
48306
  }
48208
48307
  helpFields++;
48308
+ range = { start: lines[index].index, end: lines[index].index + text2.length, array: !!field[1] };
48209
48309
  validation[index] = 'help: ""';
48210
48310
  if (!field[1]) {
48211
48311
  scalar(field[2], lines[index].index + text2.length - field[2].length);
@@ -48213,6 +48313,7 @@ ${line[0]}`);
48213
48313
  }
48214
48314
  if (field[2]) {
48215
48315
  const raw = field[2];
48316
+ const list = { countStart: lines[index].index + /^(?:help|"help")\[/.exec(text2)[0].length, end: lines[index].index + text2.length };
48216
48317
  let cursor = 0;
48217
48318
  let items = 0;
48218
48319
  while (cursor < raw.length) {
@@ -48226,7 +48327,7 @@ ${line[0]}`);
48226
48327
  const comma = raw.indexOf(",", cursor);
48227
48328
  cursor = comma === -1 ? raw.length : comma;
48228
48329
  }
48229
- scalar(raw.slice(start, cursor).trimEnd(), lines[index].index + text2.length - raw.length + start);
48330
+ scalar(raw.slice(start, cursor).trimEnd(), lines[index].index + text2.length - raw.length + start, list);
48230
48331
  items++;
48231
48332
  while (/[ \t]/.test(raw[cursor] ?? "")) cursor++;
48232
48333
  if (cursor < raw.length && raw[cursor++] !== ",") throw new Error("Unknown inline suggestion");
@@ -48242,6 +48343,7 @@ ${line[0]}`);
48242
48343
  const row = /^ (?:- )?(\S[^\r\n]*)(?:\r?\n)?$/.exec(line[0]);
48243
48344
  if (!row) throw new Error("Unknown suggestion item");
48244
48345
  scalar(row[1], line.index + line[0].indexOf(row[1]));
48346
+ range.end = line.index + line[0].replace(/\r?\n$/, "").length;
48245
48347
  validation[index] = "";
48246
48348
  }
48247
48349
  if (lines[index + 1]?.[0].startsWith(" ")) throw new Error("Extra suggestion rows");
@@ -48249,7 +48351,7 @@ ${line[0]}`);
48249
48351
  const document = validation.filter((line) => line !== "").join("\n");
48250
48352
  const parsed = decode3(document);
48251
48353
  if (encode3(parsed) !== document) throw new Error("Unknown document structure");
48252
- return { spans: helpFields === 1 ? spans : [], document: parsed };
48354
+ return { spans: helpFields === 1 ? spans : [], field: helpFields === 1 ? range : void 0, document: parsed };
48253
48355
  }
48254
48356
 
48255
48357
  // src/cli/views.ts
@@ -48354,8 +48456,8 @@ async function doctor(createClient = (deadline) => new Client(process.env, void
48354
48456
  line(
48355
48457
  tool.name,
48356
48458
  tool.status === "ok",
48357
- tool.status,
48358
- new ArtiumError(tool.status === "unconfigured" ? "CREDENTIAL_NOT_CONFIGURED" : tool.status === "error" ? "TOOL_FAILED" : tool.status === "disabled" ? "TOOL_DISABLED" : "SERVER_UNAVAILABLE")
48459
+ tool.status === "error" && tool.errorCode ? `${tool.status}: ${tool.errorCode}` : tool.status,
48460
+ new ArtiumError(tool.status === "unconfigured" ? "CREDENTIAL_NOT_CONFIGURED" : tool.status === "error" ? tool.errorCode ?? "TOOL_FAILED" : tool.status === "disabled" ? "TOOL_DISABLED" : "SERVER_UNAVAILABLE")
48359
48461
  );
48360
48462
  }
48361
48463
  } catch (error62) {
@@ -48608,7 +48710,7 @@ import { homedir as homedir2 } from "node:os";
48608
48710
  import { dirname as dirname2, join as join2, resolve as resolve2 } from "node:path";
48609
48711
 
48610
48712
  // skill/artium-axi/SKILL.md
48611
- var SKILL_default = "---\nname: artium-axi\ndescription: Discover and run managed commands through Artium, using the signed-in account and its granted tools.\n---\n\nFor requests involving data from Artium-managed tools, discover the tools available to this account before choosing one.\nRun `artium-axi` for identity and tools together, or `artium-axi tools` when only tool discovery is needed.\nRun `artium-axi tools show <tool>` for its commands and a vetted example, then run `artium-axi <tool> <args>`.\nFollow the returned next commands; they already include the Artium prefix.\nKeep upstream arguments intact and use the managed credentials rather than configuring an upstream CLI directly.\nSee [client input handling](https://github.com/knowttl/artium-axi/blob/main/docs/client-reference.md#command-surface-and-subcommands) for Azure stdin selection and Tenable local uploads or explicit stdin.\n\nIf artium-axi is absent from PATH, use the installed command below in place of `artium-axi` in every example:\nOn Windows, choose the labelled PowerShell or Git Bash command for your shell.\n\n<!-- artium-axi executable -->\nThe setup command records the standalone bundle's Node invocation here.\n<!-- /artium-axi executable -->\n\nIf sign-in is required, ask the user to sign in with their SSO or local account.\nNever request or print tokens or put passwords in arguments.\nAn empty tool list means no enabled runtime tool is available through the account's roles; ask an administrator to check grants and enabled tools.\nUse `artium-axi doctor` for connection or cached health diagnostics.\nDo not retry an uncertain command outcome, especially a write.\n\n## Investigation quick guide\n\nStart with these reads using an already signed-in account, without running help first.\nArtium is a managed transport; vendor investigation syntax and one-call pivots belong to the tool skills installed by setup.\nUse the matching installed skill once you know the granted tool.\n\n| Read command and example | What it answers |\n| --- | --- |\n| `artium-axi` | Identity, roles and available tools together in one call. |\n| `artium-axi tools` | Granted enabled tools, status, pinned version and `readOnly`; no flags required. |\n| `artium-axi tools show falcon-axi` | One tool's reviewed command inventory, vetted upstream help and first read example; substitute a granted tool name. |\n| `artium-axi whoami` | Identity, roles, session expiry and server; no flags required. |\n| `artium-axi doctor` | Connection, certificate, token, version and cached tool health; does not run a fresh upstream credential test. |\n| `artium-axi falcon-axi detection list` | First endpoint detection read when Falcon is granted; keep all upstream arguments after the tool name. |\n\nThe home view combines identity and tool discovery, so skip separate whoami and tools calls when it already answers the question.\nTools show combines command inventory, vetted help and a first call, avoiding help probes for every listed command.\nArtium has no generic batch, start-and-wait, list-with-details or lookup-and-pivot flag.\nUse only single-call forms documented by the granted tool's installed skill and supported by its pinned command inventory; upstream support does not imply managed availability.\n\n### Keep output small\n\nClient discovery has no `--fields`, `--limit` or `--full` flags.\nTools already returns only `name`, `status`, `version` and `readOnly`; use tools show for one tool's details only when needed.\nForward tool-specific filters, `--fields` and `--limit` only where its skill documents them.\nPrefer identifiers, status, timestamps and summary fields; fetch long descriptions only for relevant records.\nUpstream `--full`, where supported, restores text but never bypasses redaction, execution budgets or output caps.\nHeed stderr truncation notices and narrow the query rather than treating partial output as complete; see [output limits](https://github.com/knowttl/artium-axi/blob/main/docs/client-reference.md#toon-output-behavior).\n\n### Help is recovery\n\nUse help for a command that fails or whose arguments are unclear, not to start an investigation.\n`artium-axi --help` returns the local client command list, usage, flags and an example without signing in.\nClient command help, such as `artium-axi tools --help`, `artium-axi tools show --help`, `artium-axi whoami --help` and `artium-axi doctor --help`, describes only that client command.\n`artium-axi --help falcon-axi` is local entry help describing forwarding and managed boundaries.\n`artium-axi falcon-axi --help` and `artium-axi falcon-axi detection list --help` authenticate and forward help to the pinned tool at the requested level.\nThe same before/after-tool distinction applies to other granted tools.\n\n### Read allowlist and state changes\n\nThe six reads above are candidates for a reviewed allowlist, scoped to their exact argument forms.\nAuthenticated reads can refresh local session tokens and create server audit records.\nNever allow an unrestricted tool prefix merely because its discovery row says `readOnly`.\nLogin, passwd and logout change session/account state; setup writes skills/hooks; update replaces the executable; download prepares transfers or saves artifacts.\nForwarded writes and job creation need separate review and administrator enablement where supported.\nHybrid Analysis quick scans can transmit samples or URLs even with managed writes disabled.\nNative preview, execute and exact confirmation gates still apply; there is no universal Artium confirmation flag.\n\n### Failures and next action\n\nArtium errors are TOON on stdout with `error.code`, `source`, `message` and `next`; follow `next` rather than retrying blindly.\nExit 0 means success, 2 means usage/configuration error and 1 means authentication/server/transport failure; upstream exit status passes through.\n\nUse the [generated error reference](https://github.com/knowttl/artium-axi/blob/main/docs/errors.md) for code-specific recovery and exit codes.\n\n## Commands\n\nThis table is kept identical to the [command reference](https://github.com/knowttl/artium-axi/blob/main/docs/commands.md).\nTool reference links describe upstream commands; Artium controls availability, credentials and permissions.\n\n| Command | Purpose |\n| --- | --- |\n| `artium-axi` | Show identity, roles and available tools. |\n| `artium-axi --help [<command>]` | Show local client or tool-entry help without authentication. |\n| `artium-axi --version` | Print the client package version. |\n| `artium-axi login --username <username> [--password-stdin]` | Sign in with a local account using protected password input. |\n| `artium-axi login --sso` | Sign in through browser approval of the terminal code. |\n| `artium-axi passwd [--password-stdin]` | Change the account password, then sign in again. |\n| `artium-axi logout` | Remove local tokens and attempt server-session revocation. |\n| `artium-axi whoami` | Show identity, roles, session expiry and server. |\n| `artium-axi tools` | List granted enabled tools with status and pinned versions. |\n| `artium-axi tools show <tool>` | Show one available tool, vetted upstream help and a first call. |\n| `artium-axi doctor` | Check the server, certificate, token, client version and cached tool health. |\n| `artium-axi update` | Download and verify the server client, replace this file and retain a .bak backup; npm installs use npm instead. |\n| `artium-axi download --operation <operation> --selector <selector> --type <type> --destination <absolute-new-path> [--transfer <id> --execute --confirm <exact-confirm>] [--password-stdin\\|--sso]` | Preview or explicitly verify and save administrator-enabled Hybrid Analysis archives, Check Point emails/attachments, Graph mail exports or BeyondTrust endpoint content; see `artium-axi download --help` for guards. |\n| `artium-axi setup --host <claude\\|codex\\|opencode\\|pi> [--hook] [--force]` | Install skills for the signed-in account's granted tools and an optional Claude Code hook. |\n| `artium-axi --managed-session <command> [<args>]` | Supply and persist caller-owned sessions through private pipes; see `artium-axi --managed-session --help`. |\n| `artium-axi falcon-axi [<args>]` | Run Falcon commands with managed credentials; [tool reference](https://github.com/knowttl/falcon-axi#readme). |\n| `artium-axi vectra-axi [<args>]` | Run Vectra commands with managed credentials; [tool reference](https://www.npmjs.com/package/@knowttl/vectra-axi). |\n| `artium-axi az-axi [<args>]` | Run Azure commands with the managed identity; [tool reference](https://www.npmjs.com/package/@knowttl/az-axi). |\n| `artium-axi mg-axi [<args>]` | Run Microsoft Graph commands with the managed identity; [tool reference](https://www.npmjs.com/package/@knowttl/mg-axi). |\n| `artium-axi ldap-axi [<args>]` | Read directory data with the managed LDAP bind identity; [tool reference](https://www.npmjs.com/package/@knowttl/ldap-axi). |\n| `artium-axi ado-axi [<args>]` | Run Azure DevOps commands with managed credentials; [tool reference](https://www.npmjs.com/package/@jeffreyhaen/ado-axi). |\n| `artium-axi awx-axi [<args>]` | Inspect AWX automation with managed credentials; [tool reference](https://www.npmjs.com/package/awx-axi). |\n| `artium-axi tenable-axi [<args>]` | Investigate Tenable One with managed API keys; [tool reference](https://www.npmjs.com/package/@knowttl/tenable-axi). |\n| `artium-axi hybrid-axi [<args>]` | Investigate Hybrid Analysis with a managed API key; [tool reference](https://www.npmjs.com/package/@knowttl/hybrid-axi). |\n| `artium-axi beyondtrust-axi [<args>]` | Inspect BeyondTrust PM Cloud Endpoint Privilege Management with managed credentials; [tool reference](https://www.npmjs.com/package/@knowttl/beyondtrust-axi). |\n| `artium-axi checkpoint-axi [<args>]` | Investigate Check Point Email Security with managed regional credentials; [tool reference](https://www.npmjs.com/package/@knowttl/checkpoint-axi). |\n| `artium-axi gh-axi [<args>]` | Read and update GitHub data with managed credentials; [tool reference](https://www.npmjs.com/package/gh-axi). |\n";
48713
+ var SKILL_default = "---\nname: artium-axi\ndescription: Discover and run managed commands through Artium, using the signed-in account and its granted tools.\n---\n\nFor requests involving data from Artium-managed tools, discover the tools available to this account before choosing one.\nRun `artium-axi` for identity and tools together, or `artium-axi tools` when only tool discovery is needed.\nRun `artium-axi tools show <tool>` for its commands and a vetted example, then run `artium-axi <tool> <args>`.\nFollow the returned next commands; they already include the Artium prefix.\nKeep upstream arguments intact and use the managed credentials rather than configuring an upstream CLI directly.\nSee [client input handling](https://github.com/knowttl/artium-axi/blob/main/docs/client-reference.md#command-surface-and-subcommands) for Azure stdin selection and Tenable local uploads or explicit stdin.\n\nIf artium-axi is absent from PATH, use the installed command below in place of `artium-axi` in every example:\nOn Windows, choose the labelled PowerShell or Git Bash command for your shell.\n\n<!-- artium-axi executable -->\nThe setup command records the standalone bundle's Node invocation here.\n<!-- /artium-axi executable -->\n\nIf sign-in is required, ask the user to sign in with their SSO or local account.\nNever request or print tokens or put passwords in arguments.\nAn empty tool list means no enabled runtime tool is available through the account's roles; ask an administrator to check grants and enabled tools.\nUse `artium-axi doctor` for connection or cached health diagnostics.\nDo not retry an uncertain command outcome, especially a write.\n\n## Investigation quick guide\n\nStart with these reads using an already signed-in account, without running help first.\nArtium is a managed transport; vendor investigation syntax and one-call pivots belong to the tool skills installed by setup.\nUse the matching installed skill once you know the granted tool.\n\n| Read command and example | What it answers |\n| --- | --- |\n| `artium-axi` | Identity, roles and available tools together in one call. |\n| `artium-axi tools` | Granted enabled tools, status, pinned version and `readOnly`; no flags required. |\n| `artium-axi tools show falcon-axi` | One tool's reviewed command inventory, vetted upstream help and first read example; substitute a granted tool name. |\n| `artium-axi whoami` | Identity, roles, session expiry and server; no flags required. |\n| `artium-axi doctor` | Connection, certificate, token, version and cached tool health; does not run a fresh upstream credential test. |\n| `artium-axi falcon-axi detection list` | First endpoint detection read when Falcon is granted; keep all upstream arguments after the tool name. |\n\nThe home view combines identity and tool discovery, so skip separate whoami and tools calls when it already answers the question.\nTools show combines command inventory, vetted help and a first call, avoiding help probes for every listed command.\nArtium has no generic batch, start-and-wait, list-with-details or lookup-and-pivot flag.\nUse only single-call forms documented by the granted tool's installed skill and supported by its pinned command inventory; upstream support does not imply managed availability.\n\n### Keep output small\n\nClient discovery has no `--fields`, `--limit` or `--full` flags.\nTools already returns only `name`, `status`, `version` and `readOnly`; use tools show for one tool's details only when needed.\nForward tool-specific filters, `--fields` and `--limit` only where its skill documents them.\nPrefer identifiers, status, timestamps and summary fields; fetch long descriptions only for relevant records.\nUpstream `--full`, where supported, restores text but never bypasses redaction, execution budgets or output caps.\nHeed stderr truncation notices and narrow the query rather than treating partial output as complete; see [output limits](https://github.com/knowttl/artium-axi/blob/main/docs/client-reference.md#toon-output-behavior).\n\n### Help is recovery\n\nUse help for a command that fails or whose arguments are unclear, not to start an investigation.\n`artium-axi --help` returns the local client command list, usage, flags and an example without signing in.\nClient command help, such as `artium-axi tools --help`, `artium-axi tools show --help`, `artium-axi whoami --help` and `artium-axi doctor --help`, describes only that client command.\n`artium-axi --help falcon-axi` is local entry help describing forwarding and managed boundaries.\n`artium-axi falcon-axi --help` and `artium-axi falcon-axi detection list --help` authenticate and forward help to the pinned tool at the requested level.\nThe same before/after-tool distinction applies to other granted tools.\n\n### Read allowlist and state changes\n\nThe six reads above are candidates for a reviewed allowlist, scoped to their exact argument forms.\nAuthenticated reads can refresh local session tokens and create server audit records.\nNever allow an unrestricted tool prefix merely because its discovery row says `readOnly`.\nLogin, passwd and logout change session/account state; setup writes skills/hooks; update replaces the executable; download prepares transfers or saves artifacts.\nForwarded writes and job creation need separate review and administrator enablement where supported.\nHybrid Analysis quick scans can transmit samples or URLs even with managed writes disabled.\nNative preview, execute and exact confirmation gates still apply; there is no universal Artium confirmation flag.\n\n### Failures and next action\n\nArtium errors are TOON on stdout with `error.code`, `source`, `message` and `next`; follow `next` rather than retrying blindly.\nFor a non-zero tool exit, keep the stderr `artium-axi: request_id <id>` line and quote that ID, the tool and time when asking an administrator for help; never include credentials or sensitive output.\nFollow the [failed-call troubleshooting path](https://github.com/knowttl/artium-axi/blob/main/docs/runbook.md#troubleshoot-a-failed-tool-call) for administrator investigation, and check current state before retrying an unknown write outcome.\nSee the [output contract](https://github.com/knowttl/artium-axi/blob/main/README.md#toon-output-and-errors) for exit codes and upstream output handling.\n\nUse the [generated error reference](https://github.com/knowttl/artium-axi/blob/main/docs/errors.md) for code-specific recovery and exit codes.\nSee the [credential diagnostic guidance](https://github.com/knowttl/artium-axi/blob/main/docs/runbook.md#scripted-administrator-sessions) for tool-code mappings and administrator troubleshooting.\n\n## Commands\n\nThis table is kept identical to the [command reference](https://github.com/knowttl/artium-axi/blob/main/docs/commands.md).\nTool reference links describe upstream commands; Artium controls availability, credentials and permissions.\n\n| Command | Purpose |\n| --- | --- |\n| `artium-axi` | Show identity, roles and available tools. |\n| `artium-axi --help [<command>]` | Show local client or tool-entry help without authentication. |\n| `artium-axi --version` | Print the client package version. |\n| `artium-axi login --username <username> [--password-stdin]` | Sign in with a local account using protected password input. |\n| `artium-axi login --sso` | Sign in through browser approval of the terminal code. |\n| `artium-axi passwd [--password-stdin]` | Change the account password, then sign in again. |\n| `artium-axi logout` | Remove local tokens and attempt server-session revocation. |\n| `artium-axi whoami` | Show identity, roles, session expiry and server. |\n| `artium-axi tools` | List granted enabled tools with status and pinned versions. |\n| `artium-axi tools show <tool>` | Show one available tool, vetted upstream help and a first call. |\n| `artium-axi doctor` | Check the server, certificate, token, client version and cached tool health. |\n| `artium-axi update` | Download and verify the server client, replace this file and retain a .bak backup; npm installs use npm instead. |\n| `artium-axi download --operation <operation> --selector <selector> --type <type> --destination <absolute-new-path> [--transfer <id> --execute --confirm <exact-confirm>] [--password-stdin\\|--sso]` | Preview or explicitly verify and save administrator-enabled Hybrid Analysis archives, Check Point emails/attachments, Graph mail exports or BeyondTrust endpoint content; see `artium-axi download --help` for guards. |\n| `artium-axi setup --host <claude\\|codex\\|opencode\\|pi> [--hook] [--force]` | Install skills for the signed-in account's granted tools and an optional Claude Code hook. |\n| `artium-axi --managed-session <command> [<args>]` | Supply and persist caller-owned sessions through private pipes; see `artium-axi --managed-session --help`. |\n| `artium-axi falcon-axi [<args>]` | Run Falcon commands with managed credentials; [tool reference](https://github.com/knowttl/falcon-axi#readme). |\n| `artium-axi vectra-axi [<args>]` | Run Vectra commands with managed credentials; [tool reference](https://www.npmjs.com/package/@knowttl/vectra-axi). |\n| `artium-axi az-axi [<args>]` | Run Azure commands with the managed identity; [tool reference](https://www.npmjs.com/package/@knowttl/az-axi). |\n| `artium-axi mg-axi [<args>]` | Run Microsoft Graph commands with the managed identity; [tool reference](https://www.npmjs.com/package/@knowttl/mg-axi). |\n| `artium-axi ldap-axi [<args>]` | Read directory data with the managed LDAP bind identity; [tool reference](https://www.npmjs.com/package/@knowttl/ldap-axi). |\n| `artium-axi ado-axi [<args>]` | Run Azure DevOps commands with managed credentials; [tool reference](https://www.npmjs.com/package/@jeffreyhaen/ado-axi). |\n| `artium-axi awx-axi [<args>]` | Inspect AWX automation with managed credentials; [tool reference](https://www.npmjs.com/package/awx-axi). |\n| `artium-axi tenable-axi [<args>]` | Investigate Tenable One with managed API keys; [tool reference](https://www.npmjs.com/package/@knowttl/tenable-axi). |\n| `artium-axi hybrid-axi [<args>]` | Investigate Hybrid Analysis with a managed API key; [tool reference](https://www.npmjs.com/package/@knowttl/hybrid-axi). |\n| `artium-axi beyondtrust-axi [<args>]` | Inspect BeyondTrust PM Cloud Endpoint Privilege Management with managed credentials; [tool reference](https://www.npmjs.com/package/@knowttl/beyondtrust-axi). |\n| `artium-axi checkpoint-axi [<args>]` | Investigate Check Point Email Security with managed regional credentials; [tool reference](https://www.npmjs.com/package/@knowttl/checkpoint-axi). |\n| `artium-axi gh-axi [<args>]` | Read and update GitHub data with managed credentials; [tool reference](https://www.npmjs.com/package/gh-axi). |\n";
48612
48714
 
48613
48715
  // src/cli/setup.ts
48614
48716
  var hosts = {
@@ -49373,6 +49475,7 @@ async function download(args, output3, managed2) {
49373
49475
 
49374
49476
  // src/cli/main.ts
49375
49477
  var managed;
49478
+ var failureContext = "main";
49376
49479
  for (const stream of [process.stdout, process.stderr]) {
49377
49480
  stream.on("error", (error62) => {
49378
49481
  if (error62.code !== "EPIPE") throw error62;
@@ -49572,26 +49675,35 @@ ${view}${toolsView(tools.data.tools)}`;
49572
49675
  const { stdout, stderr, exitCode, truncated } = parsed.data;
49573
49676
  if (truncated.stdout || truncated.stderr) output2("stderr", `artium-axi: output truncated (${["stdout", "stderr"].filter((stream) => truncated[stream]).join(", ")}).
49574
49677
  `);
49678
+ failureContext = "rewriteSuggestions";
49575
49679
  output2("stdout", rewriteSuggestions(stdout, command, truncated.stdout));
49576
49680
  output2("stderr", rewriteSuggestions(stderr, command, truncated.stderr));
49681
+ if (exitCode !== 0 && client.requestId) output2("stderr", `${stderr && !stderr.endsWith("\n") ? "\n" : ""}artium-axi: request_id ${client.requestId}
49682
+ `);
49577
49683
  process.exitCode = exitCode;
49578
49684
  }
49579
49685
  }
49580
- function printError(response) {
49686
+ function printError(error62) {
49687
+ const errorClass = error62 instanceof TypeError ? "TypeError" : error62 instanceof SyntaxError ? "SyntaxError" : error62 instanceof RangeError ? "RangeError" : error62 instanceof ReferenceError ? "ReferenceError" : error62 instanceof URIError ? "URIError" : error62 instanceof EvalError ? "EvalError" : error62 instanceof Error ? "Error" : "NonError";
49688
+ const response = errorResponse(error62 instanceof ArtiumError ? error62 : new ArtiumError(
49689
+ "INTERNAL_ERROR",
49690
+ `The CLI failed locally (${errorClass} in ${failureContext}).`,
49691
+ "Report the error class and function to the CLI maintainer. Check the previous call outcome before retrying."
49692
+ ), "");
49581
49693
  if (process.argv[2] === "download" || process.argv[2] === "--managed-session" && process.argv[3] === "download") {
49582
49694
  output2("stdout", `warning: ${JSON.stringify(transferWarningFor(process.argv[process.argv.indexOf("--operation") + 1] ?? ""))}
49583
49695
  `);
49584
49696
  }
49585
49697
  output2("stdout", `error:
49586
- ${Object.entries(response.error).map(([key, value]) => ` ${key}: ${JSON.stringify(value)}`).join("\n")}
49698
+ ${Object.entries(response.error).filter(([key, value]) => key !== "requestId" || value).map(([key, value]) => ` ${key}: ${JSON.stringify(value)}`).join("\n")}
49587
49699
  `);
49588
49700
  process.exitCode = errors[response.error.code].exitCode;
49589
49701
  }
49590
- main(process.argv.slice(2)).catch((error62) => printError(errorResponse(error62 instanceof ArtiumError ? error62 : new ArtiumError("INTERNAL_ERROR"), randomUUID5()))).then(() => {
49702
+ main(process.argv.slice(2)).catch(printError).then(() => {
49591
49703
  try {
49592
49704
  managed?.flush();
49593
49705
  } catch {
49594
49706
  managed = void 0;
49595
- printError(errorResponse(new ArtiumError("SECRET_IN_OUTPUT"), randomUUID5()));
49707
+ printError(new ArtiumError("SECRET_IN_OUTPUT"));
49596
49708
  }
49597
49709
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knowttl/artium-axi",
3
- "version": "0.0.25",
3
+ "version": "0.0.26",
4
4
  "description": "Client CLI and embedded skill for the Artium managed tools server.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -74,9 +74,12 @@ Native preview, execute and exact confirmation gates still apply; there is no un
74
74
  ### Failures and next action
75
75
 
76
76
  Artium errors are TOON on stdout with `error.code`, `source`, `message` and `next`; follow `next` rather than retrying blindly.
77
- Exit 0 means success, 2 means usage/configuration error and 1 means authentication/server/transport failure; upstream exit status passes through.
77
+ For a non-zero tool exit, keep the stderr `artium-axi: request_id <id>` line and quote that ID, the tool and time when asking an administrator for help; never include credentials or sensitive output.
78
+ Follow the [failed-call troubleshooting path](https://github.com/knowttl/artium-axi/blob/main/docs/runbook.md#troubleshoot-a-failed-tool-call) for administrator investigation, and check current state before retrying an unknown write outcome.
79
+ See the [output contract](https://github.com/knowttl/artium-axi/blob/main/README.md#toon-output-and-errors) for exit codes and upstream output handling.
78
80
 
79
81
  Use the [generated error reference](https://github.com/knowttl/artium-axi/blob/main/docs/errors.md) for code-specific recovery and exit codes.
82
+ See the [credential diagnostic guidance](https://github.com/knowttl/artium-axi/blob/main/docs/runbook.md#scripted-administrator-sessions) for tool-code mappings and administrator troubleshooting.
80
83
 
81
84
  ## Commands
82
85