@knowttl/checkpoint-axi 0.1.2 → 0.1.4
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 +12 -1
- package/dist/src/catalogue.d.ts +32 -13
- package/dist/src/catalogue.js +39 -9
- package/dist/src/local-commands.js +17 -6
- package/dist/src/reads.js +117 -9
- package/dist/src/transport.d.ts +1 -1
- package/dist/src/transport.js +9 -3
- package/docs/agent-guide.md +25 -3
- package/docs/commands.md +20 -8
- package/docs/reads.md +55 -4
- package/package.json +1 -1
- package/skills/checkpoint-axi/SKILL.md +17 -2
package/README.md
CHANGED
|
@@ -59,6 +59,9 @@ Use the hook, the skill or both; neither is required for ordinary CLI use.
|
|
|
59
59
|
Start investigations with the compact [agent guide](docs/agent-guide.md), linked from [SKILL.md](skills/checkpoint-axi/SKILL.md).
|
|
60
60
|
Use the [command reference](docs/commands.md) for the full catalogue.
|
|
61
61
|
|
|
62
|
+
Email search and event list support opt-in read-only detail expansion with `--expand`.
|
|
63
|
+
See [bounded detail expansion](docs/reads.md#bounded-detail-expansion) for limits, shared budgets, partial results and examples.
|
|
64
|
+
|
|
62
65
|
## What it covers
|
|
63
66
|
|
|
64
67
|
<!-- command-registry:start -->
|
|
@@ -73,7 +76,15 @@ Use the [command reference](docs/commands.md) for the full catalogue.
|
|
|
73
76
|
| exception | Inspect eight kinds; preview or request supported rule changes | Read / gated write | [Guide](docs/writes.md) |
|
|
74
77
|
| home | Show local profile context without resolving secrets | Local read | [Guide](docs/configuration.md) |
|
|
75
78
|
| profile | List named file profiles | Local read | [Guide](docs/configuration.md) |
|
|
76
|
-
| task | Inspect asynchronous action status
|
|
79
|
+
| task | Inspect asynchronous action status once or with bounded read-only waiting | Read | [Guide](docs/reads.md#event-and-task-reads) |
|
|
80
|
+
|
|
81
|
+
Task show reads once by default; use task show <id> --wait --timeout 30 for bounded read-only polling.
|
|
82
|
+
--timeout is required with --wait (integer seconds, range 1-60); --poll-interval defaults to 2 seconds (range 1-10), and --wait-requests defaults to 10 total HTTP requests (range 2-10), including auth and retries.
|
|
83
|
+
Wait stops on completed, failed or stopped; init, inprogress and paused remain non-terminal.
|
|
84
|
+
The task snapshot contains the final status; wait reports terminal, polls (validated status snapshots) and reason (terminal, timeout or budget).
|
|
85
|
+
A non-terminal stop exits 0 with the last snapshot and a read-only next-step hint; inspect wait even on exit 0 and include task,wait,help with --fields.
|
|
86
|
+
Timeout covers auth, requests, retries and delays within the shared 8 MiB response cap; failures before any snapshot remain errors.
|
|
87
|
+
Waiting never resubmits an action or changes remote state; a failed or stopped task is terminal, not successful execution.
|
|
77
88
|
|
|
78
89
|
Email search --filter accepts a JSON array of {saasAttrName, saasAttrOp, saasAttrValue}.
|
|
79
90
|
saasAttrName is a field path, not a closed enum (guide pages 19-20).
|
package/dist/src/catalogue.d.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
|
+
export declare const FILTER_OPERATORS: readonly ["is", "contains", "startsWith", "isEmpty", "isNot", "notContains", "isNotEmpty", "greaterThan", "lessThan"];
|
|
1
2
|
export declare const DESCRIPTION = "Inspect Check Point Email Security through compact, guarded AXI commands";
|
|
2
3
|
export declare const SETUP_GUIDANCE = "Run checkpoint-axi config path; configure a region, clientId and clientSecret env/file SecretRef";
|
|
4
|
+
export declare const TASK_WAIT_GUIDANCE: string;
|
|
5
|
+
export declare const DETAIL_EXPANSION_GUIDANCE: string;
|
|
3
6
|
export declare const EMAIL_PAYLOAD_ATTRIBUTES: string[];
|
|
4
7
|
export declare const EMAIL_FILTER_GUIDANCE: string;
|
|
8
|
+
export declare const EVENT_STATES: readonly ["new", "detected", "pending", "remediated", "dismissed", "exception"];
|
|
9
|
+
export declare const LIST_ROW_FIELDS: {
|
|
10
|
+
readonly "email search": readonly ["id", "subject", "state", "verdict"];
|
|
11
|
+
readonly "event list": readonly ["id", "type", "state", "severity"];
|
|
12
|
+
};
|
|
5
13
|
export declare const catalogue: {
|
|
6
14
|
readonly "email download": {
|
|
7
15
|
readonly description: "Download an email to a new private file with profile opt-in, a 50 MiB cap and mandatory SHA-256 verification; scopes and email hash availability are unverified (guide pages 131-132)";
|
|
@@ -187,13 +195,18 @@ export declare const catalogue: {
|
|
|
187
195
|
readonly "event list": {
|
|
188
196
|
readonly description: "List security events with bounded scroll continuation (API guide pages 37-42)";
|
|
189
197
|
readonly flags: {
|
|
198
|
+
readonly fields: `Comma-separated row fields: ${string}; or top-level events,count,total,complete,reason,cursor,expansion,help; default all`;
|
|
190
199
|
readonly saas: "Comma-separated SaaS overrides; default selected profile saas or office365_emails";
|
|
191
200
|
readonly "event-types": "Comma-separated event types; default unfiltered";
|
|
192
|
-
readonly "event-states":
|
|
193
|
-
readonly
|
|
201
|
+
readonly "event-states": `Comma-separated event states: ${string}; default unfiltered`;
|
|
202
|
+
readonly states: "Alias for --event-states; cannot combine with --event-states";
|
|
203
|
+
readonly severities: "Nonempty comma-separated severity strings; vendor documents no fixed severity list; unrecognised severities can return an empty result; default unfiltered";
|
|
194
204
|
readonly "event-ids": "Comma-separated event IDs; default unfiltered";
|
|
195
205
|
readonly "confidence-indicator": "Confidence indicator selector; default unfiltered";
|
|
196
206
|
readonly description: "Description selector; default unfiltered";
|
|
207
|
+
readonly expand: string;
|
|
208
|
+
readonly "expand-limit": string;
|
|
209
|
+
readonly "expand-requests": string;
|
|
197
210
|
readonly "start-date": string;
|
|
198
211
|
readonly "end-date": string;
|
|
199
212
|
readonly limit: string;
|
|
@@ -201,11 +214,10 @@ export declare const catalogue: {
|
|
|
201
214
|
readonly cursor: string;
|
|
202
215
|
readonly config: string;
|
|
203
216
|
readonly profile: string;
|
|
204
|
-
readonly fields: string;
|
|
205
217
|
readonly full: string;
|
|
206
218
|
readonly help: string;
|
|
207
219
|
};
|
|
208
|
-
readonly examples: readonly ["checkpoint-axi event list", "checkpoint-axi event list --
|
|
220
|
+
readonly examples: readonly ["checkpoint-axi event list", "checkpoint-axi event list --limit 5 --expand --event-types phishing", "checkpoint-axi event list --cursor <cursor>"];
|
|
209
221
|
};
|
|
210
222
|
readonly "event show": {
|
|
211
223
|
readonly description: "Show one event, actions taken and available actions (API guide pages 34-37)";
|
|
@@ -219,34 +231,41 @@ export declare const catalogue: {
|
|
|
219
231
|
readonly examples: readonly ["checkpoint-axi event show <id>", "checkpoint-axi event show <id> --full"];
|
|
220
232
|
};
|
|
221
233
|
readonly "task show": {
|
|
222
|
-
readonly description: "Show asynchronous task status and per-action details (API guide pages 30-33)";
|
|
234
|
+
readonly description: "Show asynchronous task status and per-action details, optionally waiting within explicit bounds (API guide pages 30-33)";
|
|
223
235
|
readonly flags: {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
236
|
+
readonly wait: "Poll existing task status only; default false; requires --timeout; terminal: completed, failed, stopped";
|
|
237
|
+
readonly timeout: "Total wait timeout in integer seconds, range 1-60; required with --wait; includes auth and retries";
|
|
238
|
+
readonly "poll-interval": "Seconds between status reads; default 2, range 1-10; requires --wait";
|
|
239
|
+
readonly "wait-requests": "Total HTTP request cap including auth and retries; default 10, range 2-10; requires --wait";
|
|
240
|
+
readonly config: string;
|
|
241
|
+
readonly profile: string;
|
|
242
|
+
readonly fields: string;
|
|
243
|
+
readonly full: string;
|
|
244
|
+
readonly help: string;
|
|
229
245
|
};
|
|
230
|
-
readonly examples: readonly ["checkpoint-axi task show <id>", "checkpoint-axi task show <id> --full"];
|
|
246
|
+
readonly examples: readonly ["checkpoint-axi task show <id>", "checkpoint-axi task show <id> --wait --timeout 30 --fields task,wait,help", "checkpoint-axi task show <id> --full"];
|
|
231
247
|
};
|
|
232
248
|
readonly "email search": {
|
|
233
249
|
readonly description: "Search emails with a bounded date window and scroll continuation (API guide pages 18-27)";
|
|
234
250
|
readonly flags: {
|
|
235
251
|
readonly filter: `JSON array of {saasAttrName, saasAttrOp, saasAttrValue} filters. ${string}`;
|
|
252
|
+
readonly expand: string;
|
|
253
|
+
readonly "expand-limit": string;
|
|
254
|
+
readonly "expand-requests": string;
|
|
236
255
|
readonly "start-date": string;
|
|
237
256
|
readonly "end-date": string;
|
|
238
257
|
readonly limit: string;
|
|
239
258
|
readonly all: string;
|
|
240
259
|
readonly cursor: string;
|
|
260
|
+
readonly fields: `Comma-separated row fields: ${string}; or top-level emails,count,total,complete,reason,cursor,expansion,help; default all`;
|
|
241
261
|
readonly saas: "SaaS override; default selected profile saas or office365_emails";
|
|
242
262
|
readonly "saas-entity": "Optional SaaS entity type selector";
|
|
243
263
|
readonly config: string;
|
|
244
264
|
readonly profile: string;
|
|
245
|
-
readonly fields: string;
|
|
246
265
|
readonly full: string;
|
|
247
266
|
readonly help: string;
|
|
248
267
|
};
|
|
249
|
-
readonly examples: readonly ["checkpoint-axi email search", "checkpoint-axi email search --
|
|
268
|
+
readonly examples: readonly ["checkpoint-axi email search", "checkpoint-axi email search --limit 5 --expand --saas office365_emails", "checkpoint-axi email search --cursor <cursor>"];
|
|
250
269
|
};
|
|
251
270
|
readonly "email show": {
|
|
252
271
|
readonly description: "Show one email with verdicts, actions and available actions (API guide pages 10-18)";
|
package/dist/src/catalogue.js
CHANGED
|
@@ -1,11 +1,29 @@
|
|
|
1
1
|
import { exceptionFamilies } from "./exceptions.js";
|
|
2
|
+
export const FILTER_OPERATORS = ["is", "contains", "startsWith", "isEmpty", "isNot", "notContains", "isNotEmpty", "greaterThan", "lessThan"];
|
|
2
3
|
export const DESCRIPTION = "Inspect Check Point Email Security through compact, guarded AXI commands";
|
|
3
4
|
export const SETUP_GUIDANCE = "Run checkpoint-axi config path; configure a region, clientId and clientSecret env/file SecretRef";
|
|
5
|
+
export const TASK_WAIT_GUIDANCE = "Task show reads once by default; use task show <id> --wait --timeout 30 for bounded read-only polling.\n"
|
|
6
|
+
+ "--timeout is required with --wait (integer seconds, range 1-60); --poll-interval defaults to 2 seconds (range 1-10), and --wait-requests defaults to 10 total HTTP requests (range 2-10), including auth and retries.\n"
|
|
7
|
+
+ "Wait stops on completed, failed or stopped; init, inprogress and paused remain non-terminal.\n"
|
|
8
|
+
+ "The task snapshot contains the final status; wait reports terminal, polls (validated status snapshots) and reason (terminal, timeout or budget).\n"
|
|
9
|
+
+ "A non-terminal stop exits 0 with the last snapshot and a read-only next-step hint; inspect wait even on exit 0 and include task,wait,help with --fields.\n"
|
|
10
|
+
+ "Timeout covers auth, requests, retries and delays within the shared 8 MiB response cap; failures before any snapshot remain errors.\n"
|
|
11
|
+
+ "Waiting never resubmits an action or changes remote state; a failed or stopped task is terminal, not successful execution.";
|
|
12
|
+
export const DETAIL_EXPANSION_GUIDANCE = "Email search and event list accept --expand for read-only show details in each successful row's detail field.\n"
|
|
13
|
+
+ "Expansion is off by default; --expand-limit caps detail attempts (default 5, range 1-8), and --expand-requests caps total HTTP requests (default 10, range 2-10), including auth, list pages and retries.\n"
|
|
14
|
+
+ "Both limit flags require --expand; listing runs first and shares the 60-second and 8 MiB transport budgets with detail reads.\n"
|
|
15
|
+
+ "Inspect the expansion object's expanded, complete and notExpanded fields for every unexpanded ID and its reason: item-cap-reached, request-cap-reached, budget-exhausted or per-item-error (with an error code).\n"
|
|
16
|
+
+ "Partial expansion keeps every list row and successful detail; list complete/cursor describe pagination separately.\n"
|
|
17
|
+
+ "Use --fields emails,expansion or --fields events,expansion to retain expansion status; --full restores full strings after redaction.\n"
|
|
18
|
+
+ "With --all, list pages can consume the entire request budget before any detail is expanded; reduce the list limit or use individual show reads for remaining IDs.\n"
|
|
19
|
+
+ "Expansion never downloads files, invokes available actions or changes remote state.";
|
|
4
20
|
export const EMAIL_PAYLOAD_ATTRIBUTES = ["subject", "fromEmail", "attachmentCount", "internetMessageId", "received", "size", "emailLinks", "attachments", "mode", "recipients", "fromDomain", "fromUser", "fromName", "to", "toUser", "cc", "ccUser", "bcc", "bccUser", "replyToEmail", "replyToNickname", "isRead", "isDeleted", "isIncoming", "isInternal", "isOutgoing", "isQuarantined", "isQuarantineNotification", "isRestored", "isRestoreRequested", "isRestoreDeclined", "saasSpamVerdict", "SpfResult"].map((name) => `entityPayload.${name}`);
|
|
5
21
|
export const EMAIL_FILTER_GUIDANCE = "saasAttrName is a field path, not a closed enum (guide pages 19-20). Documented examples: "
|
|
6
22
|
+ EMAIL_PAYLOAD_ATTRIBUTES.slice(0, 3).join(", ") + ". Other documented email payload paths (pages 15-16, 24-25): "
|
|
7
23
|
+ EMAIL_PAYLOAD_ATTRIBUTES.slice(3).join(", ")
|
|
8
|
-
+
|
|
24
|
+
+ `. saasAttrOp: ${FILTER_OPERATORS.join(", ")}. The guide defines operators globally, without a per-field compatibility matrix; examples pair fromEmail with is and attachmentCount with greaterThan. saasAttrValue is a string.`;
|
|
25
|
+
export const EVENT_STATES = ["new", "detected", "pending", "remediated", "dismissed", "exception"];
|
|
26
|
+
export const LIST_ROW_FIELDS = { "email search": ["id", "subject", "state", "verdict"], "event list": ["id", "type", "state", "severity"] };
|
|
9
27
|
const common = {
|
|
10
28
|
config: "Config path; default CHECKPOINT_AXI_CONFIG or platform path",
|
|
11
29
|
profile: "Profile name; default CHECKPOINT_AXI_PROFILE, env profile, config default, or sole profile",
|
|
@@ -21,6 +39,11 @@ const paging = {
|
|
|
21
39
|
cursor: "Opaque continuation bound to profile, region, operation and selectors; repeat original selectors",
|
|
22
40
|
};
|
|
23
41
|
const exceptionType = `Required for ${["malware", "url", "dlp"].map((kind) => `${kind}: ${exceptionFamilies[kind].types.join(",")}`).join("; ")}`;
|
|
42
|
+
const expansion = {
|
|
43
|
+
expand: "Opt in to read-only show details on returned rows; default false; partial expansion is reported separately",
|
|
44
|
+
"expand-limit": "Maximum detail attempts; default 5, range 1-8; requires --expand",
|
|
45
|
+
"expand-requests": "Total HTTP request cap including auth, list pages, detail and retries; default 10, range 2-10; requires --expand",
|
|
46
|
+
};
|
|
24
47
|
const writeFlags = { ...common,
|
|
25
48
|
ids: "Required comma-separated unique entity IDs; maximum 20",
|
|
26
49
|
execute: "Send once after all write gates; default false (preview)",
|
|
@@ -70,25 +93,32 @@ export const catalogue = {
|
|
|
70
93
|
"exception show": { description: "Show an exception by kind and ID/value; anomaly refuses ENDPOINT_UNVERIFIED pending commissioning (guide pages 52-123)",
|
|
71
94
|
flags: { ...common, type: exceptionType, items: "Click-time item route instead of list route; default false" },
|
|
72
95
|
examples: ["checkpoint-axi exception show phishing-block <id>", "checkpoint-axi exception show url <value> --type allow-url", "checkpoint-axi exception show click-time <id> --items --full"] },
|
|
73
|
-
"event list": { description: "List security events with bounded scroll continuation (API guide pages 37-42)", flags: { ...common, ...paging,
|
|
96
|
+
"event list": { description: "List security events with bounded scroll continuation (API guide pages 37-42)", flags: { ...common, ...paging, ...expansion,
|
|
97
|
+
fields: `Comma-separated row fields: ${LIST_ROW_FIELDS["event list"].join(",")}; or top-level events,count,total,complete,reason,cursor,expansion,help; default all`,
|
|
74
98
|
saas: "Comma-separated SaaS overrides; default selected profile saas or office365_emails",
|
|
75
99
|
"event-types": "Comma-separated event types; default unfiltered",
|
|
76
|
-
"event-states":
|
|
77
|
-
|
|
100
|
+
"event-states": `Comma-separated event states: ${EVENT_STATES.join(", ")}; default unfiltered`,
|
|
101
|
+
states: "Alias for --event-states; cannot combine with --event-states",
|
|
102
|
+
severities: "Nonempty comma-separated severity strings; vendor documents no fixed severity list; unrecognised severities can return an empty result; default unfiltered",
|
|
78
103
|
"event-ids": "Comma-separated event IDs; default unfiltered",
|
|
79
104
|
"confidence-indicator": "Confidence indicator selector; default unfiltered",
|
|
80
105
|
description: "Description selector; default unfiltered",
|
|
81
|
-
}, examples: ["checkpoint-axi event list", "checkpoint-axi event list --
|
|
106
|
+
}, examples: ["checkpoint-axi event list", "checkpoint-axi event list --limit 5 --expand --event-types phishing", "checkpoint-axi event list --cursor <cursor>"] },
|
|
82
107
|
"event show": { description: "Show one event, actions taken and available actions (API guide pages 34-37)", flags: common,
|
|
83
108
|
examples: ["checkpoint-axi event show <id>", "checkpoint-axi event show <id> --full"] },
|
|
84
|
-
"task show": { description: "Show asynchronous task status and per-action details (API guide pages 30-33)", flags: common,
|
|
85
|
-
|
|
109
|
+
"task show": { description: "Show asynchronous task status and per-action details, optionally waiting within explicit bounds (API guide pages 30-33)", flags: { ...common,
|
|
110
|
+
wait: "Poll existing task status only; default false; requires --timeout; terminal: completed, failed, stopped",
|
|
111
|
+
timeout: "Total wait timeout in integer seconds, range 1-60; required with --wait; includes auth and retries",
|
|
112
|
+
"poll-interval": "Seconds between status reads; default 2, range 1-10; requires --wait",
|
|
113
|
+
"wait-requests": "Total HTTP request cap including auth and retries; default 10, range 2-10; requires --wait",
|
|
114
|
+
}, examples: ["checkpoint-axi task show <id>", "checkpoint-axi task show <id> --wait --timeout 30 --fields task,wait,help", "checkpoint-axi task show <id> --full"] },
|
|
86
115
|
"email search": { description: "Search emails with a bounded date window and scroll continuation (API guide pages 18-27)", flags: { ...common,
|
|
116
|
+
fields: `Comma-separated row fields: ${LIST_ROW_FIELDS["email search"].join(",")}; or top-level emails,count,total,complete,reason,cursor,expansion,help; default all`,
|
|
87
117
|
saas: "SaaS override; default selected profile saas or office365_emails",
|
|
88
118
|
"saas-entity": "Optional SaaS entity type selector",
|
|
89
|
-
...paging,
|
|
119
|
+
...paging, ...expansion,
|
|
90
120
|
filter: `JSON array of {saasAttrName, saasAttrOp, saasAttrValue} filters. ${EMAIL_FILTER_GUIDANCE}`,
|
|
91
|
-
}, examples: ["checkpoint-axi email search", "checkpoint-axi email search --
|
|
121
|
+
}, examples: ["checkpoint-axi email search", "checkpoint-axi email search --limit 5 --expand --saas office365_emails", "checkpoint-axi email search --cursor <cursor>"] },
|
|
92
122
|
"email show": { description: "Show one email with verdicts, actions and available actions (API guide pages 10-18)", flags: common,
|
|
93
123
|
examples: ["checkpoint-axi email show <id>", "checkpoint-axi email show <id> --full"] },
|
|
94
124
|
doctor: { description: "Check regional API authentication and one bounded email search without printing tenant data", flags: { ...common, saas: "SaaS override; default selected profile saas or office365_emails" },
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AxiError } from "axi-sdk-js";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
|
-
import { catalogue, DESCRIPTION, help, SETUP_GUIDANCE } from "./catalogue.js";
|
|
4
|
+
import { catalogue, DESCRIPTION, help, LIST_ROW_FIELDS, SETUP_GUIDANCE } from "./catalogue.js";
|
|
5
5
|
import { doctor } from "./doctor.js";
|
|
6
6
|
import { readCommand } from "./reads.js";
|
|
7
7
|
import { exceptionCommand } from "./exceptions.js";
|
|
@@ -38,7 +38,7 @@ export async function localCommand(argv, store, transport) {
|
|
|
38
38
|
const label = flag.split("=")[0];
|
|
39
39
|
usage(/^--[A-Za-z][A-Za-z0-9-]*$/.test(label) ? `Unknown or duplicate flag ${label}` : undefined);
|
|
40
40
|
}
|
|
41
|
-
if (["--help", "--full", "--all", "--items", "--specific", "--original", "--execute", "--dry-run"].includes(flag))
|
|
41
|
+
if (["--help", "--full", "--all", "--expand", "--wait", "--items", "--specific", "--original", "--execute", "--dry-run"].includes(flag))
|
|
42
42
|
flags.set(flag, "true");
|
|
43
43
|
else {
|
|
44
44
|
const value = argv[++index];
|
|
@@ -50,18 +50,25 @@ export async function localCommand(argv, store, transport) {
|
|
|
50
50
|
if (flags.has("--help"))
|
|
51
51
|
return { command: name, ...entry };
|
|
52
52
|
const available = isException ? name === "exception list" ? ["exceptions", "count", "total", "complete", "reason", "responseSchema", "help"] : ["exception", "responseSchema"]
|
|
53
|
-
: name === "email search" || name === "event list" ? [name === "event list" ? "events" : "emails", "count", "total", "complete", "reason", "cursor", "help"] : name.endsWith(" show") ? [name.split(" ")[0]]
|
|
53
|
+
: name === "email search" || name === "event list" ? [name === "event list" ? "events" : "emails", "count", "total", "complete", "reason", "cursor", "expansion", "help"] : name.endsWith(" show") ? [name.split(" ")[0]]
|
|
54
54
|
: name === "doctor" ? ["region", "saas", "checks", "pass", "help"] : name === "auth status" ? ["profile", "source", "region", "origin", "saas", "clientSecret", "readOnly"]
|
|
55
55
|
: name === "profile list" ? ["profiles", "count", "config"] : name === "config path" ? ["config", "state"]
|
|
56
56
|
: ["bin", "description", "status", "profiles", "count", "help"];
|
|
57
57
|
const isWrite = name === "email quarantine" || name === "email restore" || name === "event action" || isExceptionWrite;
|
|
58
|
+
if (name === "task show")
|
|
59
|
+
available.push("wait", "help");
|
|
58
60
|
if (isWrite)
|
|
59
61
|
available.splice(0, available.length, "outcome", "preview", "auditId", "tasks", "response", "responseSchema", "help");
|
|
60
62
|
if (isDownload)
|
|
61
63
|
available.splice(0, available.length, "path", "size", "sha256");
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
const rowFields = name === "email search" || name === "event list" ? LIST_ROW_FIELDS[name] : [];
|
|
65
|
+
const requested = flags.get("--fields")?.split(",") ?? available;
|
|
66
|
+
const columns = requested.filter((field) => rowFields.includes(field));
|
|
67
|
+
if (requested.some((field) => !available.includes(field) && !rowFields.includes(field)) || new Set(requested).size !== requested.length
|
|
68
|
+
|| (columns.length > 0 && columns.length !== requested.length)) {
|
|
69
|
+
usage(`Invalid --fields; valid top-level fields: ${available.join(",")}${rowFields.length ? `; valid row fields: ${rowFields.join(",")}` : ""}`);
|
|
70
|
+
}
|
|
71
|
+
const fields = columns.length ? available : requested;
|
|
65
72
|
const config = flags.get("--config");
|
|
66
73
|
let result;
|
|
67
74
|
if (isDownload)
|
|
@@ -103,6 +110,10 @@ export async function localCommand(argv, store, transport) {
|
|
|
103
110
|
description: DESCRIPTION, status, profiles: listed.profiles, count: listed.count,
|
|
104
111
|
help: [SETUP_GUIDANCE, "Run checkpoint-axi auth status to validate local credentials", "Run checkpoint-axi profile list to inspect configured profiles"] };
|
|
105
112
|
}
|
|
113
|
+
if (columns.length) {
|
|
114
|
+
const key = name === "event list" ? "events" : "emails";
|
|
115
|
+
result[key] = result[key].map((row) => Object.fromEntries(columns.map((field) => [field, row[field]])));
|
|
116
|
+
}
|
|
106
117
|
let truncated = false;
|
|
107
118
|
const preview = (value) => {
|
|
108
119
|
if (typeof value === "string" && value.length > 500 && !flags.has("--full")) {
|
package/dist/src/reads.js
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import { AxiError } from "axi-sdk-js";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
import { REGIONS } from "./regions.js";
|
|
5
6
|
import { gateway, READ_LIMITS } from "./transport.js";
|
|
6
7
|
import { responseInvalid } from "./response-invalid.js";
|
|
8
|
+
import { EVENT_STATES, FILTER_OPERATORS } from "./catalogue.js";
|
|
7
9
|
const day = 86_400_000;
|
|
8
10
|
const timestamp = z.iso.datetime({ offset: true });
|
|
9
11
|
const filters = z.array(z.strictObject({ saasAttrName: z.string().min(1),
|
|
10
|
-
saasAttrOp: z.enum(
|
|
12
|
+
saasAttrOp: z.enum(FILTER_OPERATORS),
|
|
11
13
|
saasAttrValue: z.string() }));
|
|
12
14
|
const continuation = z.strictObject({ version: z.literal(1), binding: z.string(), start: timestamp, end: timestamp,
|
|
13
15
|
scroll: z.string().optional(), offset: z.number().int().nonnegative(), replayRisk: z.literal(true).optional() });
|
|
14
16
|
// The guide's prose/table (pp.11,14) says security-result array; its JSON examples use an object.
|
|
15
17
|
const securityResults = z.object({ combinedVerdict: z.unknown().optional() }).passthrough();
|
|
16
18
|
// Entity schemas and SaaS-specific payloads: guide pages 11-15 and 21-24.
|
|
17
|
-
const entity = z.object({ entityInfo: z.object({ entityId: z.string().min(1), entityActionState: z.string().
|
|
19
|
+
const entity = z.object({ entityInfo: z.object({ entityId: z.string().min(1), entityActionState: z.string().nullish().transform((value) => value ?? "unactioned") }).passthrough(),
|
|
18
20
|
entityPayload: z.object({ subject: z.string().optional() }).passthrough(),
|
|
19
|
-
entitySecurityResults: z.union([securityResults, z.array(
|
|
21
|
+
entitySecurityResults: z.union([securityResults, z.array(securityResults)]).optional(),
|
|
20
22
|
}).passthrough();
|
|
21
23
|
// Event and task fields: guide pages 31-32, 35-36 and 40-41.
|
|
22
24
|
const event = z.object({ eventId: z.string().min(1), type: z.string(), state: z.string(), severity: z.string() }).passthrough();
|
|
@@ -30,12 +32,32 @@ export async function readCommand(name, id, flags, store, transport) {
|
|
|
30
32
|
const isEvent = name.startsWith("event ");
|
|
31
33
|
if (name.endsWith(" show") && (!id || !/^[A-Za-z0-9_-]+$/.test(id)))
|
|
32
34
|
invalid(`${name} requires one ID containing letters, digits, underscores or hyphens`);
|
|
35
|
+
const waiting = flags.has("--wait");
|
|
36
|
+
if (!waiting && ["--timeout", "--poll-interval", "--wait-requests"].some((flag) => flags.has(flag)))
|
|
37
|
+
invalid("Wait limits require --wait");
|
|
38
|
+
const timeoutText = flags.get("--timeout") ?? "";
|
|
39
|
+
const intervalText = flags.get("--poll-interval") ?? "2";
|
|
40
|
+
const waitRequestsText = flags.get("--wait-requests") ?? "10";
|
|
41
|
+
if (waiting && (!/^[1-9][0-9]*$/.test(timeoutText) || Number(timeoutText) > 60))
|
|
42
|
+
invalid("--wait requires --timeout in integer seconds from 1 to 60");
|
|
43
|
+
if (!/^(?:[1-9]|10)$/.test(intervalText))
|
|
44
|
+
invalid("--poll-interval must be integer seconds from 1 to 10");
|
|
45
|
+
if (!/^(?:[2-9]|10)$/.test(waitRequestsText))
|
|
46
|
+
invalid("--wait-requests must be an integer from 2 to 10");
|
|
33
47
|
const limitText = flags.get("--limit") ?? "50";
|
|
34
48
|
if (!/^[1-9][0-9]*$/.test(limitText) || Number(limitText) > READ_LIMITS.rows)
|
|
35
49
|
invalid("--limit must be an integer from 1 to 1000");
|
|
36
50
|
if (flags.has("--all") && flags.has("--limit"))
|
|
37
51
|
invalid("Use either --all or --limit");
|
|
38
52
|
const limit = flags.has("--all") ? READ_LIMITS.rows : Number(limitText);
|
|
53
|
+
if (!flags.has("--expand") && (flags.has("--expand-limit") || flags.has("--expand-requests")))
|
|
54
|
+
invalid("Expansion limits require --expand");
|
|
55
|
+
const expandLimitText = flags.get("--expand-limit") ?? "5";
|
|
56
|
+
const expandRequestsText = flags.get("--expand-requests") ?? "10";
|
|
57
|
+
if (!/^[1-8]$/.test(expandLimitText))
|
|
58
|
+
invalid("--expand-limit must be an integer from 1 to 8");
|
|
59
|
+
if (!/^(?:[2-9]|10)$/.test(expandRequestsText))
|
|
60
|
+
invalid("--expand-requests must be an integer from 2 to 10");
|
|
39
61
|
let extended;
|
|
40
62
|
if (flags.has("--filter")) {
|
|
41
63
|
let raw;
|
|
@@ -47,7 +69,7 @@ export async function readCommand(name, id, flags, store, transport) {
|
|
|
47
69
|
}
|
|
48
70
|
const parsed = filters.safeParse(raw);
|
|
49
71
|
if (!parsed.success)
|
|
50
|
-
invalid(
|
|
72
|
+
invalid(`--filter must contain saasAttrName, saasAttrValue and saasAttrOp from: ${FILTER_OPERATORS.join(", ")}`);
|
|
51
73
|
extended = parsed.data;
|
|
52
74
|
}
|
|
53
75
|
let cursor;
|
|
@@ -75,12 +97,19 @@ export async function readCommand(name, id, flags, store, transport) {
|
|
|
75
97
|
if (flags.has(flag) && !flags.get(flag).trim())
|
|
76
98
|
invalid(`${flag} must not be blank`);
|
|
77
99
|
const eventSelectors = {};
|
|
100
|
+
if (flags.has("--states")) {
|
|
101
|
+
if (flags.has("--event-states"))
|
|
102
|
+
invalid("Use either --states or --event-states");
|
|
103
|
+
flags.set("--event-states", flags.get("--states"));
|
|
104
|
+
}
|
|
78
105
|
for (const [flag, key] of [["event-types", "eventTypes"], ["event-states", "eventStates"], ["severities", "severities"], ["event-ids", "eventIds"], ["saas", "saas"]]) {
|
|
79
106
|
if (!isEvent || !flags.has(`--${flag}`))
|
|
80
107
|
continue;
|
|
81
108
|
const values = flags.get(`--${flag}`).split(",").map((value) => value.trim());
|
|
82
109
|
if (values.some((value) => !value))
|
|
83
|
-
invalid(`--${flag} must contain nonempty comma-separated values`);
|
|
110
|
+
invalid(`--${flag} must contain nonempty comma-separated ${flag === "severities" ? "severity strings" : "values"}`);
|
|
111
|
+
if (flag === "event-states" && values.some((value) => !EVENT_STATES.includes(value)))
|
|
112
|
+
invalid(`--event-states/--states must contain: ${EVENT_STATES.join(", ")}`);
|
|
84
113
|
eventSelectors[key] = values;
|
|
85
114
|
}
|
|
86
115
|
for (const [flag, key] of [["confidence-indicator", "confidenceIndicator"], ["description", "description"]]) {
|
|
@@ -100,8 +129,14 @@ export async function readCommand(name, id, flags, store, transport) {
|
|
|
100
129
|
origin: REGIONS[profile.region], operation: name, ...(isEvent ? { selectors } : { entityFilter, extended }) })).digest("hex");
|
|
101
130
|
if (cursor && cursor.binding !== binding)
|
|
102
131
|
invalid("Cursor does not match this profile, region or search selectors; repeat the original selectors");
|
|
103
|
-
const
|
|
104
|
-
|
|
132
|
+
const now = transport?.now ?? Date.now;
|
|
133
|
+
const wait = transport?.wait ?? delay;
|
|
134
|
+
const timeout = waiting ? Number(timeoutText) * 1_000 : READ_LIMITS.milliseconds;
|
|
135
|
+
const deadline = now() + timeout;
|
|
136
|
+
const api = gateway(profile, store.credentials(profile, true), store.redactor, transport, false, Number(waiting ? waitRequestsText : expandRequestsText), timeout);
|
|
137
|
+
async function detail(id) {
|
|
138
|
+
if (!/^[A-Za-z0-9_-]+$/.test(id))
|
|
139
|
+
throw new AxiError("Invalid detail ID", "RESPONSE_INVALID", []);
|
|
105
140
|
const kind = name.split(" ")[0];
|
|
106
141
|
const page = await api.read({ path: name === "task show" ? `/task/${id}` : isEvent ? `/event/${id}` : `/search/entity/${id}` });
|
|
107
142
|
const response = { responseData: page.dataIsArray ? page.records : page.records[0] };
|
|
@@ -117,8 +152,43 @@ export async function readCommand(name, id, flags, store, transport) {
|
|
|
117
152
|
const returnedId = name === "task show" ? String(record.id) : isEvent ? record.eventId : record.entityInfo?.entityId;
|
|
118
153
|
if (returnedId !== id)
|
|
119
154
|
throw responseInvalid(`Invalid ${kind} detail response`, response, [[...recordPath, ...(name === "task show" ? ["id"] : isEvent ? ["eventId"] : ["entityInfo", "entityId"])]]);
|
|
120
|
-
return
|
|
155
|
+
return parsed.data;
|
|
156
|
+
}
|
|
157
|
+
if (name === "task show" && waiting) {
|
|
158
|
+
let snapshot;
|
|
159
|
+
let polls = 0;
|
|
160
|
+
let reason;
|
|
161
|
+
for (;;) {
|
|
162
|
+
try {
|
|
163
|
+
snapshot = await detail(id);
|
|
164
|
+
polls++;
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
if (!snapshot || !(error instanceof AxiError) || !["REQUEST_BUDGET", "TIME_BUDGET", "RESPONSE_TOO_LARGE"].includes(error.code))
|
|
168
|
+
throw error;
|
|
169
|
+
reason = error.code === "TIME_BUDGET" ? "timeout" : "budget";
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
if (["completed", "failed", "stopped"].includes(snapshot.status)) {
|
|
173
|
+
reason = "terminal";
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
const remaining = deadline - now();
|
|
177
|
+
if (remaining <= 0) {
|
|
178
|
+
reason = "timeout";
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
await wait(Math.min(Number(intervalText) * 1_000, remaining));
|
|
182
|
+
if (now() >= deadline) {
|
|
183
|
+
reason = "timeout";
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return { task: snapshot, wait: { terminal: reason === "terminal", polls, reason },
|
|
188
|
+
...(reason === "terminal" ? {} : { help: [`Run checkpoint-axi task show ${id}${flags.has("--config") ? " --config <absolute-path>" : ""}${flags.has("--profile") ? " --profile <name>" : ""} to read status again; the task may still run, never resubmit its action to obtain status`] }) };
|
|
121
189
|
}
|
|
190
|
+
if (name.endsWith(" show"))
|
|
191
|
+
return { [name.split(" ")[0]]: await detail(id) };
|
|
122
192
|
const results = [];
|
|
123
193
|
let scroll = cursor?.scroll;
|
|
124
194
|
let offset = cursor?.offset ?? 0;
|
|
@@ -155,7 +225,9 @@ export async function readCommand(name, id, flags, store, transport) {
|
|
|
155
225
|
}
|
|
156
226
|
const value = entity.parse(record);
|
|
157
227
|
return { id: value.entityInfo.entityId, subject: value.entityPayload.subject ?? "",
|
|
158
|
-
state: value.entityInfo.entityActionState
|
|
228
|
+
state: value.entityInfo.entityActionState, verdict: Array.isArray(value.entitySecurityResults)
|
|
229
|
+
? value.entitySecurityResults.find((result) => result.combinedVerdict != null)?.combinedVerdict ?? null
|
|
230
|
+
: value.entitySecurityResults?.combinedVerdict ?? null };
|
|
159
231
|
}));
|
|
160
232
|
offset += rows.length;
|
|
161
233
|
if (offset < page.records.length) {
|
|
@@ -171,7 +243,43 @@ export async function readCommand(name, id, flags, store, transport) {
|
|
|
171
243
|
}
|
|
172
244
|
const next = exhausted ? undefined : Buffer.from(JSON.stringify({ version: 1, binding, start, end, scroll, offset,
|
|
173
245
|
...(replayRisk ? { replayRisk: true } : {}) })).toString("base64url");
|
|
246
|
+
let expansion;
|
|
247
|
+
if (flags.has("--expand")) {
|
|
248
|
+
let attempted = 0;
|
|
249
|
+
let expanded = 0;
|
|
250
|
+
let stopped;
|
|
251
|
+
const notExpanded = [];
|
|
252
|
+
for (const row of results) {
|
|
253
|
+
const itemId = row.id;
|
|
254
|
+
if (stopped) {
|
|
255
|
+
notExpanded.push({ id: itemId, ...stopped });
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if (attempted >= Number(expandLimitText)) {
|
|
259
|
+
notExpanded.push({ id: itemId, reason: "item-cap-reached" });
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
attempted++;
|
|
263
|
+
try {
|
|
264
|
+
row.detail = await detail(itemId);
|
|
265
|
+
expanded++;
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
if (!(error instanceof AxiError))
|
|
269
|
+
throw error;
|
|
270
|
+
const code = error.code;
|
|
271
|
+
if (["REQUEST_BUDGET", "TIME_BUDGET", "RESPONSE_TOO_LARGE"].includes(code)) {
|
|
272
|
+
stopped = { reason: code === "REQUEST_BUDGET" ? "request-cap-reached" : "budget-exhausted", code };
|
|
273
|
+
notExpanded.push({ id: itemId, ...stopped });
|
|
274
|
+
}
|
|
275
|
+
else
|
|
276
|
+
notExpanded.push({ id: itemId, reason: "per-item-error", code });
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
expansion = { expanded, attempted, itemLimit: Number(expandLimitText), requestLimit: Number(expandRequestsText), complete: notExpanded.length === 0, notExpanded };
|
|
280
|
+
}
|
|
174
281
|
return { [isEvent ? "events" : "emails"]: results, count: results.length, ...(total === undefined ? {} : { total }), complete: exhausted && !replayRisk,
|
|
282
|
+
...(expansion ? { expansion } : {}),
|
|
175
283
|
...(replayRisk ? { reason: "replay-may-skip-or-repeat" } : {}), ...(next ? { cursor: next } : {}),
|
|
176
284
|
help: [...(results.length ? [isEvent ? "Run checkpoint-axi event show <id> for event details and available actions" : "Run checkpoint-axi email show <id> for verdicts, actions and available actions"] : [`No ${isEvent ? "events" : "emails"} matched this search window and selectors`]),
|
|
177
285
|
...(next ? ["Repeat this search with --cursor <cursor> and the original selectors to continue"] : []),
|
package/dist/src/transport.d.ts
CHANGED
|
@@ -72,7 +72,7 @@ export declare function decodePage(value: unknown, unverified?: boolean): Page;
|
|
|
72
72
|
export declare function gateway(profile: SelectedProfile, credentials: {
|
|
73
73
|
clientId: string;
|
|
74
74
|
clientSecret: string;
|
|
75
|
-
}, redactor: SecretRedactor, dependencies?: Dependencies, mutation?: boolean): {
|
|
75
|
+
}, redactor: SecretRedactor, dependencies?: Dependencies, mutation?: boolean, requestLimit?: number, milliseconds?: number): {
|
|
76
76
|
authenticate: () => Promise<void>;
|
|
77
77
|
read: (query: ReadRequest) => Promise<Page>;
|
|
78
78
|
download: (query: DownloadRequest) => Promise<{
|
package/dist/src/transport.js
CHANGED
|
@@ -66,10 +66,10 @@ function tokenFrom(value, redactor) {
|
|
|
66
66
|
throw failure("AUTH_SHAPE_UNVERIFIED", "Unverified auth token response shape; owner commissioning is required (API guide page 8 does not specify the shape)");
|
|
67
67
|
return [...tokens][0];
|
|
68
68
|
}
|
|
69
|
-
export function gateway(profile, credentials, redactor, dependencies = {}, mutation = false) {
|
|
69
|
+
export function gateway(profile, credentials, redactor, dependencies = {}, mutation = false, requestLimit = READ_LIMITS.requests, milliseconds = READ_LIMITS.milliseconds) {
|
|
70
70
|
const now = dependencies.now ?? Date.now;
|
|
71
71
|
const wait = dependencies.wait ?? delay;
|
|
72
|
-
const deadline = now() + READ_LIMITS.milliseconds;
|
|
72
|
+
const deadline = now() + Math.min(milliseconds, READ_LIMITS.milliseconds);
|
|
73
73
|
let bytes = 0;
|
|
74
74
|
let requests = 0;
|
|
75
75
|
let token;
|
|
@@ -86,7 +86,7 @@ export function gateway(profile, credentials, redactor, dependencies = {}, mutat
|
|
|
86
86
|
const remaining = deadline - now();
|
|
87
87
|
if (remaining <= 0)
|
|
88
88
|
throw failure("TIME_BUDGET", "Read time budget exhausted");
|
|
89
|
-
if (++requests > (mutation ? 44 : READ_LIMITS.requests))
|
|
89
|
+
if (++requests > (mutation ? 44 : Math.min(requestLimit, READ_LIMITS.requests)))
|
|
90
90
|
throw failure("REQUEST_BUDGET", "Request budget exhausted");
|
|
91
91
|
const payload = body === undefined ? undefined : JSON.stringify(body);
|
|
92
92
|
if (bearer)
|
|
@@ -179,6 +179,12 @@ export function gateway(profile, credentials, redactor, dependencies = {}, mutat
|
|
|
179
179
|
throw failure("AUTH_FAILED", "API rejected authentication after one re-exchange");
|
|
180
180
|
if (response.status === 429)
|
|
181
181
|
throw failure("RATE_LIMITED", "API rate limit remains after two read retries");
|
|
182
|
+
if (response.status === 404)
|
|
183
|
+
throw new AxiError("Requested resource was not found", "NOT_FOUND", ["Check the requested ID"]);
|
|
184
|
+
if (response.status === 422 && query.body === undefined) {
|
|
185
|
+
const id = decodeURIComponent(query.path.slice(query.path.lastIndexOf("/") + 1));
|
|
186
|
+
throw new AxiError(`API rejected requested ID ${id} (HTTP 422)`, "VALIDATION_ERROR", ["Check the requested ID and its format"]);
|
|
187
|
+
}
|
|
182
188
|
if (response.status < 200 || response.status >= 300)
|
|
183
189
|
throw failure("HTTP_ERROR", `Regional API returned HTTP ${response.status}`);
|
|
184
190
|
return decodePage(response.value, /^\/(sectools|sectool-exceptions)\//.test(query.path));
|
package/docs/agent-guide.md
CHANGED
|
@@ -43,12 +43,13 @@ saasAttrOp: is, contains, startsWith, isEmpty, isNot, notContains, isNotEmpty, g
|
|
|
43
43
|
The guide defines operators globally, without a per-field compatibility matrix; examples pair fromEmail with is and attachmentCount with greaterThan.
|
|
44
44
|
saasAttrValue is a string.
|
|
45
45
|
Event selectors include --event-types, --event-states, --severities, --event-ids (comma-separated), --confidence-indicator and --description; --saas accepts comma-separated SaaS values here.
|
|
46
|
-
Event detail includes available actions; task detail reads status and per-action results once
|
|
46
|
+
Event detail includes available actions; task detail reads status and per-action results once by default:
|
|
47
47
|
|
|
48
48
|
```sh
|
|
49
49
|
checkpoint-axi event list --all --event-types phishing --fields events,count,total,complete,reason,cursor
|
|
50
50
|
checkpoint-axi event show synthetic-event-1 --fields event
|
|
51
51
|
checkpoint-axi task show synthetic-task-1 --fields task
|
|
52
|
+
checkpoint-axi task show synthetic-task-1 --wait --timeout 30 --fields task,wait,help
|
|
52
53
|
```
|
|
53
54
|
|
|
54
55
|
Inspect exception rules with exception list <kind> or exception show <kind> <id-or-value>:
|
|
@@ -74,9 +75,30 @@ Inspect complete, reason and cursor even on exit 0; limits and page replay can l
|
|
|
74
75
|
Resume with --cursor <returned-cursor> and the original selectors/profile; see [continuation limitations](reads.md#email-reads).
|
|
75
76
|
Exception --all bounds returned rows at 1000 but cannot fetch additional pages: no continuation parameter is documented.
|
|
76
77
|
Email/event detail already includes available actions, avoiding a separate action lookup.
|
|
77
|
-
|
|
78
|
+
Email search and event list accept --expand for read-only show details in each successful row's detail field.
|
|
79
|
+
Expansion is off by default; --expand-limit caps detail attempts (default 5, range 1-8), and --expand-requests caps total HTTP requests (default 10, range 2-10), including auth, list pages and retries.
|
|
80
|
+
Both limit flags require --expand; listing runs first and shares the 60-second and 8 MiB transport budgets with detail reads.
|
|
81
|
+
Inspect the expansion object's expanded, complete and notExpanded fields for every unexpanded ID and its reason: item-cap-reached, request-cap-reached, budget-exhausted or per-item-error (with an error code).
|
|
82
|
+
Partial expansion keeps every list row and successful detail; list complete/cursor describe pagination separately.
|
|
83
|
+
Use --fields emails,expansion or --fields events,expansion to retain expansion status; --full restores full strings after redaction.
|
|
84
|
+
With --all, list pages can consume the entire request budget before any detail is expanded; reduce the list limit or use individual show reads for remaining IDs.
|
|
85
|
+
Expansion never downloads files, invokes available actions or changes remote state.
|
|
86
|
+
Task show reads once by default; use task show <id> --wait --timeout 30 for bounded read-only polling.
|
|
87
|
+
--timeout is required with --wait (integer seconds, range 1-60); --poll-interval defaults to 2 seconds (range 1-10), and --wait-requests defaults to 10 total HTTP requests (range 2-10), including auth and retries.
|
|
88
|
+
Wait stops on completed, failed or stopped; init, inprogress and paused remain non-terminal.
|
|
89
|
+
The task snapshot contains the final status; wait reports terminal, polls (validated status snapshots) and reason (terminal, timeout or budget).
|
|
90
|
+
A non-terminal stop exits 0 with the last snapshot and a read-only next-step hint; inspect wait even on exit 0 and include task,wait,help with --fields.
|
|
91
|
+
Timeout covers auth, requests, retries and delays within the shared 8 MiB response cap; failures before any snapshot remain errors.
|
|
92
|
+
Waiting never resubmits an action or changes remote state; a failed or stopped task is terminal, not successful execution.
|
|
93
|
+
There is no cross-resource pivot; use returned IDs for individual reads and never replay an action to obtain its status.
|
|
78
94
|
|
|
79
|
-
|
|
95
|
+
```sh
|
|
96
|
+
checkpoint-axi email search --limit 5 --expand --expand-limit 3 --expand-requests 6 --fields emails,count,complete,cursor,expansion
|
|
97
|
+
checkpoint-axi event list --limit 5 --expand --fields events,count,complete,cursor,expansion
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
--fields selects top-level output keys: request emails or events together with count,total,complete,reason,cursor for lists, and email,event,task or exception for details.
|
|
101
|
+
Email search also accepts row fields id,subject,state,verdict; event list accepts id,type,state,severity, retaining pagination metadata when selecting row fields.
|
|
80
102
|
Email rows contain id,subject,state,verdict; event rows contain id,type,state,severity; documented exception rows contain id,sender,subject,comment.
|
|
81
103
|
TOON strings preview at 500 characters; --full expands strings after redaction, while cursors are never truncated.
|
|
82
104
|
|
package/docs/commands.md
CHANGED
|
@@ -32,7 +32,7 @@ Run each command with `--help` for concise help.
|
|
|
32
32
|
| `checkpoint-axi exception update` | Preview or replace one exception; phishing/spam/click-time require an ID; malware/url/dlp identify it in --input without an ID; anomaly unsupported (guide pages 64-67, 78-81, 94-96, 105-107, 116-117, 126-127) |
|
|
33
33
|
| `checkpoint-axi home` | Show local profile context without resolving secrets or making API calls |
|
|
34
34
|
| `checkpoint-axi profile list` | List file profiles without resolving secrets; --profile does not filter this list |
|
|
35
|
-
| `checkpoint-axi task show` | Show asynchronous task status and per-action details (API guide pages 30-33) |
|
|
35
|
+
| `checkpoint-axi task show` | Show asynchronous task status and per-action details, optionally waiting within explicit bounds (API guide pages 30-33) |
|
|
36
36
|
|
|
37
37
|
## attachment download
|
|
38
38
|
|
|
@@ -187,7 +187,7 @@ Search emails with a bounded date window and scroll continuation (API guide page
|
|
|
187
187
|
|---|---|
|
|
188
188
|
| `--config` | Config path; default CHECKPOINT_AXI_CONFIG or platform path |
|
|
189
189
|
| `--profile` | Profile name; default CHECKPOINT_AXI_PROFILE, env profile, config default, or sole profile |
|
|
190
|
-
| `--fields` | Comma-separated
|
|
190
|
+
| `--fields` | Comma-separated row fields: id,subject,state,verdict; or top-level emails,count,total,complete,reason,cursor,expansion,help; default all |
|
|
191
191
|
| `--full` | Show full strings instead of 500-character previews; default false |
|
|
192
192
|
| `--help` | Show concise command help; default false |
|
|
193
193
|
| `--saas` | SaaS override; default selected profile saas or office365_emails |
|
|
@@ -197,11 +197,14 @@ Search emails with a bounded date window and scroll continuation (API guide page
|
|
|
197
197
|
| `--limit` | Maximum rows; default 50, range 1-1000; cannot combine with --all |
|
|
198
198
|
| `--all` | Read up to 1000 rows / 10 HTTP requests / 60 seconds / 8 MiB; default false |
|
|
199
199
|
| `--cursor` | Opaque continuation bound to profile, region, operation and selectors; repeat original selectors |
|
|
200
|
+
| `--expand` | Opt in to read-only show details on returned rows; default false; partial expansion is reported separately |
|
|
201
|
+
| `--expand-limit` | Maximum detail attempts; default 5, range 1-8; requires --expand |
|
|
202
|
+
| `--expand-requests` | Total HTTP request cap including auth, list pages, detail and retries; default 10, range 2-10; requires --expand |
|
|
200
203
|
| `--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. |
|
|
201
204
|
|
|
202
205
|
```sh
|
|
203
206
|
checkpoint-axi email search
|
|
204
|
-
checkpoint-axi email search --
|
|
207
|
+
checkpoint-axi email search --limit 5 --expand --saas office365_emails
|
|
205
208
|
checkpoint-axi email search --cursor <cursor>
|
|
206
209
|
```
|
|
207
210
|
|
|
@@ -252,7 +255,7 @@ List security events with bounded scroll continuation (API guide pages 37-42)
|
|
|
252
255
|
|---|---|
|
|
253
256
|
| `--config` | Config path; default CHECKPOINT_AXI_CONFIG or platform path |
|
|
254
257
|
| `--profile` | Profile name; default CHECKPOINT_AXI_PROFILE, env profile, config default, or sole profile |
|
|
255
|
-
| `--fields` | Comma-separated
|
|
258
|
+
| `--fields` | Comma-separated row fields: id,type,state,severity; or top-level events,count,total,complete,reason,cursor,expansion,help; default all |
|
|
256
259
|
| `--full` | Show full strings instead of 500-character previews; default false |
|
|
257
260
|
| `--help` | Show concise command help; default false |
|
|
258
261
|
| `--start-date` | ISO timestamp with timezone; default 24 hours before end-date; maximum window 31 days |
|
|
@@ -260,17 +263,21 @@ List security events with bounded scroll continuation (API guide pages 37-42)
|
|
|
260
263
|
| `--limit` | Maximum rows; default 50, range 1-1000; cannot combine with --all |
|
|
261
264
|
| `--all` | Read up to 1000 rows / 10 HTTP requests / 60 seconds / 8 MiB; default false |
|
|
262
265
|
| `--cursor` | Opaque continuation bound to profile, region, operation and selectors; repeat original selectors |
|
|
266
|
+
| `--expand` | Opt in to read-only show details on returned rows; default false; partial expansion is reported separately |
|
|
267
|
+
| `--expand-limit` | Maximum detail attempts; default 5, range 1-8; requires --expand |
|
|
268
|
+
| `--expand-requests` | Total HTTP request cap including auth, list pages, detail and retries; default 10, range 2-10; requires --expand |
|
|
263
269
|
| `--saas` | Comma-separated SaaS overrides; default selected profile saas or office365_emails |
|
|
264
270
|
| `--event-types` | Comma-separated event types; default unfiltered |
|
|
265
|
-
| `--event-states` | Comma-separated event states; default unfiltered |
|
|
266
|
-
| `--
|
|
271
|
+
| `--event-states` | Comma-separated event states: new, detected, pending, remediated, dismissed, exception; default unfiltered |
|
|
272
|
+
| `--states` | Alias for --event-states; cannot combine with --event-states |
|
|
273
|
+
| `--severities` | Nonempty comma-separated severity strings; vendor documents no fixed severity list; unrecognised severities can return an empty result; default unfiltered |
|
|
267
274
|
| `--event-ids` | Comma-separated event IDs; default unfiltered |
|
|
268
275
|
| `--confidence-indicator` | Confidence indicator selector; default unfiltered |
|
|
269
276
|
| `--description` | Description selector; default unfiltered |
|
|
270
277
|
|
|
271
278
|
```sh
|
|
272
279
|
checkpoint-axi event list
|
|
273
|
-
checkpoint-axi event list --
|
|
280
|
+
checkpoint-axi event list --limit 5 --expand --event-types phishing
|
|
274
281
|
checkpoint-axi event list --cursor <cursor>
|
|
275
282
|
```
|
|
276
283
|
|
|
@@ -473,7 +480,7 @@ checkpoint-axi profile list --config /example/config.json
|
|
|
473
480
|
|
|
474
481
|
## task show
|
|
475
482
|
|
|
476
|
-
Show asynchronous task status and per-action details (API guide pages 30-33)
|
|
483
|
+
Show asynchronous task status and per-action details, optionally waiting within explicit bounds (API guide pages 30-33)
|
|
477
484
|
|
|
478
485
|
| Flag | Meaning |
|
|
479
486
|
|---|---|
|
|
@@ -482,8 +489,13 @@ Show asynchronous task status and per-action details (API guide pages 30-33)
|
|
|
482
489
|
| `--fields` | Comma-separated output fields; default all |
|
|
483
490
|
| `--full` | Show full strings instead of 500-character previews; default false |
|
|
484
491
|
| `--help` | Show concise command help; default false |
|
|
492
|
+
| `--wait` | Poll existing task status only; default false; requires --timeout; terminal: completed, failed, stopped |
|
|
493
|
+
| `--timeout` | Total wait timeout in integer seconds, range 1-60; required with --wait; includes auth and retries |
|
|
494
|
+
| `--poll-interval` | Seconds between status reads; default 2, range 1-10; requires --wait |
|
|
495
|
+
| `--wait-requests` | Total HTTP request cap including auth and retries; default 10, range 2-10; requires --wait |
|
|
485
496
|
|
|
486
497
|
```sh
|
|
487
498
|
checkpoint-axi task show <id>
|
|
499
|
+
checkpoint-axi task show <id> --wait --timeout 30 --fields task,wait,help
|
|
488
500
|
checkpoint-axi task show <id> --full
|
|
489
501
|
```
|
package/docs/reads.md
CHANGED
|
@@ -20,6 +20,7 @@ Read sessions allow at most 10 HTTP requests; write sessions allow at most 44.
|
|
|
20
20
|
Both are bounded by 8 MiB of JSON response bytes and 60 seconds, including auth, re-exchange, read retries and delays.
|
|
21
21
|
Download bodies have a separate 50 MiB cap per response within the same request/time budgets.
|
|
22
22
|
Reads retry HTTP 429 at most twice, honoring numeric or HTTP-date `Retry-After` within that budget.
|
|
23
|
+
HTTP 404 reads return `NOT_FOUND`; HTTP 422 detail reads return `VALIDATION_ERROR` and identify the requested ID without printing server response data.
|
|
23
24
|
Exception reads and writes share separate 1 request/second Anti-Phishing and 10 requests/second other-exception spacers.
|
|
24
25
|
|
|
25
26
|
## Email reads
|
|
@@ -43,26 +44,76 @@ Cursor strings are never truncated; email text is redacted before 500-character
|
|
|
43
44
|
See [downloads](downloads.md) for private file output.
|
|
44
45
|
|
|
45
46
|
The vendor PDF describes `entitySecurityResults` as an array in its prose/table (pages 11 and 14), while its JSON examples use an object.
|
|
46
|
-
Both
|
|
47
|
-
|
|
47
|
+
Both forms are accepted; search uses `combinedVerdict` from the object or the first array entry containing one, and reports `verdict: null` when none is available.
|
|
48
|
+
Null or missing `entityActionState` within `entityInfo` is rendered as `unactioned` in search and detail.
|
|
48
49
|
`RESPONSE_INVALID` diagnostics for these reads name failing JSON paths and received types, including `missing`, without response values.
|
|
49
50
|
Non-identifier path keys appear as `<key>`.
|
|
50
|
-
|
|
51
|
+
The reported unfiltered-search and spam-detail failures identified null action states; synthetic clean and spam fixtures exercise that shape offline.
|
|
51
52
|
|
|
52
53
|
## Event and task reads
|
|
53
54
|
|
|
54
55
|
`checkpoint-axi event list` returns compact ID, type, state and severity rows (guide pages 37-42).
|
|
55
56
|
`checkpoint-axi event show <id>` preserves event details, action history and available actions (guide pages 34-37).
|
|
56
57
|
`checkpoint-axi task show <id>` returns task status, progress and per-action details for asynchronous actions (guide pages 30-33).
|
|
57
|
-
Task states are `init`, `inprogress`, `completed`, `failed`, `stopped` and `paused`; task show performs one read
|
|
58
|
+
Task states are `init`, `inprogress`, `completed`, `failed`, `stopped` and `paused`; task show performs one read by default.
|
|
59
|
+
Use `checkpoint-axi task show <id> --wait --timeout 30` to poll an already submitted task without resubmitting its action.
|
|
60
|
+
`--wait` requires an explicit `--timeout` in integer seconds, from 1 to 60.
|
|
61
|
+
`--poll-interval` defaults to 2 seconds, from 1 to 10; `--wait-requests` defaults to 10 total HTTP requests, from 2 to 10, including authentication, re-exchange and retries.
|
|
62
|
+
These limits require `--wait` and invalid bounds fail before configuration or network access.
|
|
63
|
+
The timeout includes authentication, requests, retries and delays, and the existing 8 MiB response cap remains shared across polls.
|
|
64
|
+
The first read starts immediately; subsequent reads wait the configured interval after the preceding read, without starting another read at or after the deadline.
|
|
65
|
+
`completed`, `failed` and `stopped` are terminal; `init`, `inprogress` and `paused` remain non-terminal.
|
|
66
|
+
The final `task` snapshot retains status, progress and per-action details; the `wait` object reports `terminal`, `polls` (validated status snapshots, excluding authentication and retries), and `reason`: `terminal`, `timeout` or `budget`.
|
|
67
|
+
Request or response-byte exhaustion reports `budget`; an exhausted deadline or a retry delay that cannot fit reports `timeout`.
|
|
68
|
+
A non-terminal stop exits 0, preserves the last snapshot and includes a `help` hint for another status read.
|
|
69
|
+
Inspect `wait` even on exit 0; terminal failure or stopping does not mean the submitted action succeeded.
|
|
70
|
+
Failures before any snapshot and non-budget read failures remain structured errors rather than reporting stale data as current.
|
|
71
|
+
Use `--fields task,wait,help` to retain wait metadata and recovery guidance when projecting output.
|
|
72
|
+
Waiting only repeats the existing task status GET; it never invokes an available action, downloads a file or resubmits the original mutation.
|
|
58
73
|
Event list accepts comma-separated `--event-types`, `--event-states`, `--severities`, `--event-ids` and `--saas`, plus `--confidence-indicator` and `--description` text selectors.
|
|
74
|
+
`--states` is an alias for `--event-states`; use one of these flags per command.
|
|
75
|
+
States must be `new`, `detected`, `pending`, `remediated`, `dismissed` or `exception`, as defined by the vendor Swagger 1.50 `EventState` schema.
|
|
76
|
+
The vendor Swagger defines severities as an array of strings with no format, min/max constraints or fixed severity list, so the CLI validates nonempty comma-separated severity strings.
|
|
77
|
+
Unrecognised severities can return an empty result.
|
|
59
78
|
SaaS defaults to the selected profile's value or `office365_emails`; other event selectors default to unfiltered.
|
|
60
79
|
Event list uses the same date windows, row and transport budgets, bound continuation and honest page replay flags as [email search](reads.md#email-reads).
|
|
61
80
|
Repeat all original event selectors with `--cursor`; the cursor preserves the original date window.
|
|
62
81
|
Event and task text is redacted before 500-character previews; use `--full` for full strings and `--fields` to select top-level fields.
|
|
82
|
+
Email search also accepts row fields `id,subject,state,verdict`; event list accepts `id,type,state,severity`.
|
|
83
|
+
For example, `email search --fields id,subject` narrows each email row while retaining pagination metadata.
|
|
84
|
+
Existing top-level projections such as `--fields emails,count,cursor` remain supported; mixed row and top-level selections are rejected, and errors list both valid sets.
|
|
63
85
|
For writes, see [event actions](writes.md#event-actions).
|
|
64
86
|
These reads are verified offline with synthetic fixtures; authentication, token lifetime and live API behavior require manual verification.
|
|
65
87
|
|
|
88
|
+
## Bounded detail expansion
|
|
89
|
+
|
|
90
|
+
Email search and event list accept `--expand` to inspect returned items through the same validated read-only path as their individual show commands.
|
|
91
|
+
Expansion is off by default; available actions are returned as data and are never invoked.
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
checkpoint-axi email search --limit 5 --expand --expand-limit 3 --expand-requests 6
|
|
95
|
+
checkpoint-axi event list --limit 5 --expand --fields events,count,complete,cursor,expansion
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`--expand-limit` caps detail attempts, including failed attempts: default 5, minimum 1, maximum 8.
|
|
99
|
+
`--expand-requests` caps total HTTP requests for the invocation: default 10, minimum 2, maximum 10.
|
|
100
|
+
Both limit flags require `--expand`; invalid bounds are rejected before configuration or network access.
|
|
101
|
+
Authentication, token re-exchange, list pages, detail requests and read retries all consume this request cap.
|
|
102
|
+
Listing runs first; detail reads reuse its token, deadline and response-byte accounting without resetting the 60-second or 8 MiB budgets.
|
|
103
|
+
Using `--all` can therefore consume the entire budget before any detail is fetched.
|
|
104
|
+
Use a smaller list limit to leave room for detail, or inspect remaining IDs with individual show commands.
|
|
105
|
+
|
|
106
|
+
Each successfully expanded row gains `detail`, containing the same validated payload and actions as show, with normal secret redaction and 500-character string previews (`--full` restores full strings).
|
|
107
|
+
Every list row and successful detail survives expansion failures; partial expansion exits 0.
|
|
108
|
+
The `expansion` object reports `expanded`, `attempted`, `itemLimit`, `requestLimit`, `complete` and `notExpanded`.
|
|
109
|
+
Each `notExpanded` entry includes the item `id` and `reason`: `item-cap-reached`, `request-cap-reached`, `budget-exhausted` or `per-item-error`.
|
|
110
|
+
Budget and per-item failures also include a safe error `code`; raw upstream error bodies are never printed.
|
|
111
|
+
Budget exhaustion stops further detail attempts; an individual HTTP, response-validation or other read failure records that item and continues within the caps.
|
|
112
|
+
List `complete`, `reason` and `cursor` still describe pagination; `complete` inside `expansion` independently describes whether every returned row was expanded.
|
|
113
|
+
With `--fields`, include `expansion` alongside `emails` or `events` so omissions remain visible.
|
|
114
|
+
Row field selections retain expansion metadata but omit each row's `detail`; use a top-level projection to inspect expanded payloads.
|
|
115
|
+
Expansion performs no writes, actions, downloads, cross-resource pivots or task waiting.
|
|
116
|
+
|
|
66
117
|
## Exception reads
|
|
67
118
|
|
|
68
119
|
`checkpoint-axi exception list <kind>` and `exception show <kind> <id-or-value>` cover `phishing-allow`, `phishing-block`, `spam-allow`, `anomaly`, `click-time`, `malware`, `url` and `dlp` (guide pages 49-123).
|
package/package.json
CHANGED
|
@@ -49,6 +49,14 @@ The guide defines operators globally, without a per-field compatibility matrix;
|
|
|
49
49
|
saasAttrValue is a string.
|
|
50
50
|
See [email-read guidance](../../docs/reads.md#email-reads) for continuation, completion status, cursor safety and page replay limitations.
|
|
51
51
|
Email show <id> includes payload, verdicts, actions taken and available actions (guide pages 10-18).
|
|
52
|
+
Email search and event list accept --expand for read-only show details in each successful row's detail field.
|
|
53
|
+
Expansion is off by default; --expand-limit caps detail attempts (default 5, range 1-8), and --expand-requests caps total HTTP requests (default 10, range 2-10), including auth, list pages and retries.
|
|
54
|
+
Both limit flags require --expand; listing runs first and shares the 60-second and 8 MiB transport budgets with detail reads.
|
|
55
|
+
Inspect the expansion object's expanded, complete and notExpanded fields for every unexpanded ID and its reason: item-cap-reached, request-cap-reached, budget-exhausted or per-item-error (with an error code).
|
|
56
|
+
Partial expansion keeps every list row and successful detail; list complete/cursor describe pagination separately.
|
|
57
|
+
Use --fields emails,expansion or --fields events,expansion to retain expansion status; --full restores full strings after redaction.
|
|
58
|
+
With --all, list pages can consume the entire request budget before any detail is expanded; reduce the list limit or use individual show reads for remaining IDs.
|
|
59
|
+
Expansion never downloads files, invokes available actions or changes remote state.
|
|
52
60
|
Use --full for strings truncated at 500 characters and --fields for top-level output projection.
|
|
53
61
|
Cursor strings are never truncated; secret-derived strings are redacted before previews.
|
|
54
62
|
Downloads require file-profile downloads.allow and an absolute new --out file, created exclusively with mode 0600 or a protected Windows DACL.
|
|
@@ -64,7 +72,14 @@ Event action --ids <ids> --name <action> previews by default and requires the ex
|
|
|
64
72
|
Every target must offer the action on both reads; nonempty actionParameter objects or repeated action names refuse ENDPOINT_UNVERIFIED until live commissioning resolves the object/string contradiction (guide pages 36-37, 43).
|
|
65
73
|
Use event show <id> to inspect all available actions, including deferred parameterized actions.
|
|
66
74
|
Accepted actions return task IDs; use task show <taskId> to inspect asynchronous execution without replaying ambiguous outcomes.
|
|
67
|
-
Event list supports documented selectors and shares email search bounds and continuation; event show preserves actions and task show reads asynchronous status
|
|
75
|
+
Event list supports documented selectors and shares email search bounds and continuation; event show preserves actions and task show reads asynchronous status (guide pages 30-42).
|
|
76
|
+
Task show reads once by default; use task show <id> --wait --timeout 30 for bounded read-only polling.
|
|
77
|
+
--timeout is required with --wait (integer seconds, range 1-60); --poll-interval defaults to 2 seconds (range 1-10), and --wait-requests defaults to 10 total HTTP requests (range 2-10), including auth and retries.
|
|
78
|
+
Wait stops on completed, failed or stopped; init, inprogress and paused remain non-terminal.
|
|
79
|
+
The task snapshot contains the final status; wait reports terminal, polls (validated status snapshots) and reason (terminal, timeout or budget).
|
|
80
|
+
A non-terminal stop exits 0 with the last snapshot and a read-only next-step hint; inspect wait even on exit 0 and include task,wait,help with --fields.
|
|
81
|
+
Timeout covers auth, requests, retries and delays within the shared 8 MiB response cap; failures before any snapshot remain errors.
|
|
82
|
+
Waiting never resubmits an action or changes remote state; a failed or stopped task is terminal, not successful execution.
|
|
68
83
|
Exception list/show accept phishing-allow, phishing-block, spam-allow, anomaly, click-time, malware, url and dlp (guide pages 49-123).
|
|
69
84
|
For malware, url and dlp, --type is required; run exception list --help for the documented values.
|
|
70
85
|
Click-time --items selects item routes; by default list routes are used.
|
|
@@ -105,4 +120,4 @@ All live-only facts remain unverified, including token response shape and lifeti
|
|
|
105
120
|
| `npx -y @knowttl/checkpoint-axi exception update` | Preview or replace one exception; phishing/spam/click-time require an ID; malware/url/dlp identify it in --input without an ID; anomaly unsupported (guide pages 64-67, 78-81, 94-96, 105-107, 116-117, 126-127) |
|
|
106
121
|
| `npx -y @knowttl/checkpoint-axi home` | Show local profile context without resolving secrets or making API calls |
|
|
107
122
|
| `npx -y @knowttl/checkpoint-axi profile list` | List file profiles without resolving secrets; --profile does not filter this list |
|
|
108
|
-
| `npx -y @knowttl/checkpoint-axi task show` | Show asynchronous task status and per-action details (API guide pages 30-33) |
|
|
123
|
+
| `npx -y @knowttl/checkpoint-axi task show` | Show asynchronous task status and per-action details, optionally waiting within explicit bounds (API guide pages 30-33) |
|