@knowttl/artium-axi 0.0.16 → 0.0.18

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
@@ -155,6 +155,7 @@ Use `--host codex`, `--host opencode` or `--host pi` without `--hook` for those
155
155
  Only Claude Code supports the optional `SessionStart` hook, which injects the `tools` discovery output.
156
156
  Setup preserves unrelated settings and refuses edited/unmanaged skills unless `--force` is explicit.
157
157
  Re-run setup after moving the executable or changing grants; skills for removed grants are retained and reported.
158
+ On Windows, installed skills include labelled PowerShell and Git Bash invocations; use the command for your shell.
158
159
  See [installation paths and manual removal](docs/client-reference.md#agent-installation) before uninstalling.
159
160
  Artium's authenticated setup fetches managed skills; a standalone skill installer does not configure this server account.
160
161
 
@@ -163,7 +164,13 @@ Artium's authenticated setup fetches managed skills; a standalone skill installe
163
164
  All tools start disabled; write access defaults to off.
164
165
  Administrator capability alone grants no tool access; upstream permissions remain an additional boundary.
165
166
 
166
- Microsoft Graph supports the `entra` pack only; the bundled upstream `security hunting query` command for Defender XDR advanced hunting is unavailable through Artium.
167
+ Microsoft Graph defaults to the `entra` pack.
168
+ Administrators can opt in to the single read-only `security hunting query` command for Defender XDR advanced hunting with `enabledPacks: ["entra", "security"]` in the managed tool settings.
169
+ Hunting accepts exactly one UTF-8 plain-text upload named `query.kql`, at most 64 KiB, through `artium-axi mg-axi security hunting query --file query.kql`.
170
+ See [client input handling](docs/client-reference.md#command-surface-and-subcommands) for local file paths and upload restrictions.
171
+ Queries must use the upstream restricted read-only KQL subset.
172
+ The existing mg-axi role grant is required; other security commands remain unavailable.
173
+ See [Graph credential setup](docs/tool-credentials.md#microsoft-graph) for hunting permissions and consent; tenant acceptance remains unverified.
167
174
 
168
175
  Falcon investigation reads include detection lineage, process details and trees, existing sandbox reports, FileVantage changes and device-control policy details.
169
176
 
@@ -20191,10 +20191,14 @@ var nativeSettingsSchemas = {
20191
20191
  "awx-axi": external_exports.strictObject({ allowWrites: external_exports.boolean().optional() }),
20192
20192
  "ldap-axi": external_exports.strictObject({}),
20193
20193
  "ado-axi": external_exports.strictObject({ allowWrites: external_exports.boolean().optional() }),
20194
- "mg-axi": external_exports.strictObject({ preview: external_exports.boolean().optional(), writes: external_exports.strictObject({
20195
- allowWrites: external_exports.boolean(),
20196
- operations: external_exports.array(external_exports.string().min(1).max(256)).min(1).max(64)
20197
- }).optional() }),
20194
+ "mg-axi": external_exports.strictObject({
20195
+ enabledPacks: external_exports.array(external_exports.enum(["entra", "security"])).min(1).max(2).refine((packs) => packs.includes("entra") && new Set(packs).size === packs.length).optional(),
20196
+ preview: external_exports.boolean().optional(),
20197
+ writes: external_exports.strictObject({
20198
+ allowWrites: external_exports.boolean(),
20199
+ operations: external_exports.array(external_exports.string().min(1).max(256)).min(1).max(64)
20200
+ }).optional()
20201
+ }),
20198
20202
  "falcon-axi": external_exports.strictObject({
20199
20203
  allowWrites: external_exports.boolean().optional(),
20200
20204
  rtr: falconRtrSettingsSchema.optional(),
@@ -20744,7 +20748,7 @@ import { resolve } from "node:path";
20744
20748
  // package.json
20745
20749
  var package_default = {
20746
20750
  name: "artium-axi",
20747
- version: "0.0.16",
20751
+ version: "0.0.18",
20748
20752
  private: true,
20749
20753
  license: "MIT",
20750
20754
  type: "module",
@@ -29837,7 +29841,8 @@ var mg_axi_default = {
29837
29841
  "home",
29838
29842
  "doctor",
29839
29843
  "entra",
29840
- "api get"
29844
+ "api get",
29845
+ "security hunting query"
29841
29846
  ],
29842
29847
  example: [
29843
29848
  "entra",
@@ -29937,11 +29942,12 @@ var mg_axi_default = {
29937
29942
  "home",
29938
29943
  "doctor",
29939
29944
  "entra",
29940
- "api get"
29945
+ "api get",
29946
+ "security hunting query"
29941
29947
  ],
29942
29948
  inputs: {
29943
29949
  stdin: "cursor - only",
29944
- files: "unsupported",
29950
+ files: "security hunting query only: one UTF-8 query.kql upload, at most 64 KiB; fixed runner leaf name",
29945
29951
  cursor: "opaque token or stdin; never a path",
29946
29952
  api: "reviewed GET routes only; pinned Graph destination and operation gates retained"
29947
29953
  },
@@ -29956,7 +29962,8 @@ var mg_axi_default = {
29956
29962
  ],
29957
29963
  knownOutputScanValues: [
29958
29964
  "clientSecret and trimmed clientSecret",
29959
- "privateKey and normalized PEM"
29965
+ "privateKey and normalized PEM",
29966
+ "hunting query text"
29960
29967
  ],
29961
29968
  outputScanLimit: "Upstream-minted Graph tokens and assertions are not available during prepare; live redaction remains unverified.",
29962
29969
  resources: {
@@ -44207,7 +44214,7 @@ import { homedir as homedir2 } from "node:os";
44207
44214
  import { dirname as dirname2, join as join2, resolve as resolve2 } from "node:path";
44208
44215
 
44209
44216
  // skill/artium-axi/SKILL.md
44210
- 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\nUse artium-axi tools first for requests involving data from Artium-managed tools.\nRun `artium-axi tools` to discover the tools available to this account before choosing a tool.\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.\n\nIf artium-axi is absent from PATH, use the installed command below in place of `artium-axi` in every example:\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 follow `artium-axi login --help` for 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";
44217
+ 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\nUse artium-axi tools first for requests involving data from Artium-managed tools.\nRun `artium-axi tools` to discover the tools available to this account before choosing a tool.\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 follow `artium-axi login --help` for 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";
44211
44218
 
44212
44219
  // src/cli/setup.ts
44213
44220
  var hosts = {
@@ -44304,12 +44311,23 @@ async function setup(args) {
44304
44311
  throw new ArtiumError("INVALID_INPUT", `Hook installation is unsupported for ${host}: this installer has no verified ${host} hook implementation. No files were written.`, `Install the skill with artium-axi setup --host ${host} without --hook; Claude Code supports --hook.`);
44305
44312
  }
44306
44313
  const executable = resolve2(process.argv[1]);
44307
- const invocation = process.platform === "win32" ? `& '${process.execPath.replaceAll("'", "''")}' '${executable.replaceAll("'", "''")}'` : `${quote(process.execPath)} ${quote(executable)}`;
44308
- const executableBlock = `<!-- artium-axi executable -->
44314
+ const gitBashQuote = (path) => `"${path.replaceAll("\\", "/").replaceAll(/["$`]/g, "\\$&")}"`;
44315
+ const invocation = process.platform === "win32" ? `PowerShell:
44316
+
44317
+ \`\`\`powershell
44318
+ & '${process.execPath.replaceAll("'", "''")}' '${executable.replaceAll("'", "''")}'
44319
+ \`\`\`
44320
+
44321
+ Git Bash:
44309
44322
 
44310
44323
  \`\`\`sh
44324
+ ${gitBashQuote(process.execPath)} ${gitBashQuote(executable)}
44325
+ \`\`\`` : `\`\`\`sh
44326
+ ${quote(process.execPath)} ${quote(executable)}
44327
+ \`\`\``;
44328
+ const executableBlock = `<!-- artium-axi executable -->
44329
+
44311
44330
  ${invocation}
44312
- \`\`\`
44313
44331
 
44314
44332
  <!-- /artium-axi executable -->`;
44315
44333
  const content = SKILL_default.replace(/<!-- artium-axi executable -->[\s\S]*?<!-- \/artium-axi executable -->/, () => executableBlock);
@@ -44372,23 +44390,25 @@ async function toolInput(tool, original) {
44372
44390
  const args = [...original];
44373
44391
  const input2 = {};
44374
44392
  let totalFileBytes = 0;
44375
- if ((tool === "az-axi" || tool === "hybrid-axi") && !args.some((arg) => ["--help", "-h", "--version", "-v", "-V"].includes(arg))) {
44376
- const fileFlags = tool === "hybrid-axi" ? hybrid_axi_default.adapterBoundary.inputFileFlags : az_axi_default.adapterBoundary.inputFileFlags;
44393
+ const hunting = tool === "mg-axi" && args.slice(0, 3).join(" ") === "security hunting query";
44394
+ if ((tool === "az-axi" || tool === "hybrid-axi" || tool === "tenable-axi" || hunting) && !args.some((arg) => ["--help", "-h", "--version", "-v", "-V"].includes(arg))) {
44395
+ const fileFlags = hunting ? ["file"] : tool === "tenable-axi" ? tenable_axi_default.adapterBoundary.inputFileFlags : tool === "hybrid-axi" ? hybrid_axi_default.adapterBoundary.inputFileFlags : az_axi_default.adapterBoundary.inputFileFlags;
44377
44396
  for (let index = 0; index < args.length; index++) {
44378
44397
  if (args[index] === "--") break;
44379
44398
  const [flag] = args[index].split("=");
44380
44399
  if (!fileFlags.some((name2) => flag === `--${name2}`)) continue;
44381
44400
  const equals = args[index].indexOf("=");
44382
44401
  const path = equals < 0 ? args[++index] : args[index].slice(equals + 1);
44383
- if (path === "-" && tool === "hybrid-axi" && flag === "--body-file") {
44402
+ if (path === "-" && (tool === "tenable-axi" || tool === "hybrid-axi" && flag === "--body-file")) {
44384
44403
  input2.stdin = (await readBounded(process.stdin, inputLimits.stdinBytes)).toString("utf8");
44385
44404
  continue;
44386
44405
  }
44387
44406
  if (!path || path === "-") throw new ArtiumError("UNSUPPORTED_INPUT", "A file flag requires a local file path.");
44388
- const name = basename(path);
44407
+ if (hunting && (path.split(/[\\/]/).includes("..") || input2.files?.length)) throw new ArtiumError("INVALID_INPUT");
44408
+ const name = hunting ? "query.kql" : basename(path);
44389
44409
  if (input2.files?.some((file2) => file2.name === name)) throw new ArtiumError("INVALID_INPUT", "Upload file names must be distinct.");
44390
44410
  if ((input2.files?.length ?? 0) >= inputLimits.files) throw new ArtiumError("INVALID_INPUT", "Too many upload files.");
44391
- const content = await readBounded(createReadStream(path), inputLimits.fileBytes);
44411
+ const content = await readBounded(createReadStream(path), hunting ? 65536 : inputLimits.fileBytes);
44392
44412
  totalFileBytes += content.length;
44393
44413
  if (totalFileBytes > inputLimits.totalFileBytes) throw new ArtiumError("INVALID_INPUT", "Uploads exceed the total byte limit.");
44394
44414
  input2.files ??= [];
@@ -44403,8 +44423,35 @@ async function toolInput(tool, original) {
44403
44423
  leading++;
44404
44424
  if (!token.includes("=") && (name !== "full" || ["true", "false"].includes(args[leading]))) leading++;
44405
44425
  }
44406
- const consumesStdin = az_axi_default.commands.some((route) => ["rg query", "logs query", "api"].includes(route.handlerCommand) && route.command.split(" ").every((word, index) => args[leading + index] === word));
44407
- if (tool === "az-axi" && consumesStdin && !process.stdin.isTTY) {
44426
+ const route = az_axi_default.commands.find((route2) => ["rg query", "logs query", "api"].includes(route2.handlerCommand) && route2.command.split(" ").every((word, index) => args[leading + index] === word));
44427
+ let positional = false;
44428
+ if (route) {
44429
+ for (let index = leading + route.command.split(" ").length; index < args.length; index++) {
44430
+ const token = args[index];
44431
+ if (token === "--") {
44432
+ positional = index + 1 < args.length;
44433
+ break;
44434
+ }
44435
+ if (!token.startsWith("-") || token === "-") {
44436
+ positional = true;
44437
+ break;
44438
+ }
44439
+ const raw = token.slice(token.startsWith("--") ? 2 : 1).split("=")[0];
44440
+ const expanded = token.startsWith("--") ? raw : route.shortFlags[raw] ?? raw;
44441
+ const name = route.flagAliases[expanded] ?? expanded;
44442
+ const kind = route.flags[name];
44443
+ if (token.includes("=") || !kind) continue;
44444
+ if (kind === "boolean") {
44445
+ if (["true", "false"].includes(args[index + 1])) index++;
44446
+ } else {
44447
+ while (args[index + 1] !== void 0 && (!args[index + 1].startsWith("-") || /^-\d/.test(args[index + 1]) || az_axi_default.adapterBoundary.inputFileFlags.includes(name) && input2.files?.some((file2) => file2.name === args[index + 1]))) {
44448
+ index++;
44449
+ if (!["list", "literal-list"].includes(kind) || route.positionalInput) break;
44450
+ }
44451
+ }
44452
+ }
44453
+ }
44454
+ if (tool === "az-axi" && route && !input2.files?.length && !positional && !process.stdin.isTTY) {
44408
44455
  const stdin = await readBounded(process.stdin, inputLimits.stdinBytes);
44409
44456
  if (stdin.length) input2.stdin = stdin.toString("utf8");
44410
44457
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knowttl/artium-axi",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "description": "Client CLI and embedded skill for the Artium managed tools server.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -8,8 +8,10 @@ Run `artium-axi tools` to discover the tools available to this account before ch
8
8
  Run `artium-axi tools show <tool>` for its commands and a vetted example, then run `artium-axi <tool> <args>`.
9
9
  Follow the returned next commands; they already include the Artium prefix.
10
10
  Keep upstream arguments intact and use the managed credentials rather than configuring an upstream CLI directly.
11
+ See [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.
11
12
 
12
13
  If artium-axi is absent from PATH, use the installed command below in place of `artium-axi` in every example:
14
+ On Windows, choose the labelled PowerShell or Git Bash command for your shell.
13
15
 
14
16
  <!-- artium-axi executable -->
15
17
  The setup command records the standalone bundle's Node invocation here.