securewithtrace 0.50.0 → 0.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +111 -26
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -23193,12 +23193,6 @@ var AgentSessionTypeValues = [
23193
23193
  "SETUP"
23194
23194
  ];
23195
23195
  var AgentSessionType = external_exports.enum(AgentSessionTypeValues);
23196
- var SetupTenantSchema = external_exports.object({
23197
- admin: external_exports.boolean(),
23198
- member: external_exports.boolean(),
23199
- apiKey: external_exports.boolean()
23200
- }).strict();
23201
- var MAX_SETUP_TENANTS = 4;
23202
23196
  var AgentSessionStatusValues = [
23203
23197
  "LAUNCHING",
23204
23198
  "RUNNING",
@@ -23251,6 +23245,7 @@ var MAX_AGENT_SESSION_MAX_USD = 1500;
23251
23245
  var MAX_AGENT_SESSION_MAX_WALL_CLOCK_MIN = 24 * 60;
23252
23246
  var MAX_AGENT_SESSION_FOCUS_CHARS = 8e3;
23253
23247
  var MAX_AGENT_SESSION_FOCUS_BRIEF_CHARS = MAX_AGENT_SESSION_FOCUS_CHARS * 3;
23248
+ var MAX_SETUP_NOTES_CHARS = 8e3;
23254
23249
  var OperatorSessionPurpose = external_exports.enum(OPERATOR_PURPOSES);
23255
23250
  var CreateAgentSessionCommonSchema = external_exports.object({
23256
23251
  provider: AgentSessionProvider.optional(),
@@ -23363,16 +23358,14 @@ var CreateAgentSessionRequestSchema = external_exports.discriminatedUnion("type"
23363
23358
  focus: external_exports.string().min(1).max(MAX_AGENT_SESSION_FOCUS_CHARS).optional()
23364
23359
  }),
23365
23360
  // SETUP: sets up a PoC engagement's application, environment, exclusions and tenant
23366
- // accounts. `focus` carries the staff notes (which environment, rate limits, what is
23367
- // off-limits); `tenants` the accounts to aim for; `shareLink` the customer's logins.
23361
+ // accounts from the setup notes. Strict, so a client still sending the removed `focus`,
23362
+ // `tenants` or `shareLink` gets a 400 instead of a launch that silently lost its input.
23368
23363
  CreateAgentSessionCommonSchema.extend({
23369
23364
  type: external_exports.literal("SETUP"),
23370
- focus: external_exports.string().min(1).max(MAX_AGENT_SESSION_FOCUS_CHARS).optional(),
23371
- /** Absent = the default target, two tenants of admin + member + API key. */
23372
- tenants: external_exports.array(SetupTenantSchema).min(1).max(MAX_SETUP_TENANTS).optional(),
23373
- /** A credential share link. Stored encrypted and never returned by any read route. */
23374
- shareLink: external_exports.url({ protocol: /^https$/ }).max(2048).optional()
23375
- })
23365
+ /** What the customer sent and what staff want: environments, rules, logins, share links.
23366
+ * Stored encrypted and never returned by any read route. */
23367
+ notes: external_exports.string().trim().min(1).max(MAX_SETUP_NOTES_CHARS).optional()
23368
+ }).strict()
23376
23369
  ]);
23377
23370
  var SendAgentSessionMessageRequestSchema = external_exports.object({
23378
23371
  clientRequestId: external_exports.uuid().optional(),
@@ -23551,6 +23544,9 @@ var OperatorPentestContextSchema = external_exports.object({
23551
23544
  customerPriorityCategories: external_exports.array(external_exports.string()),
23552
23545
  /** Staff scope notes; defaulted so an older API's envelope still parses. */
23553
23546
  scopeNotes: external_exports.string().nullable().default(null),
23547
+ /** The rendered staff-notes block (heading and never-quote line included), or null when the
23548
+ * engagement has none or this session's type never receives them. Defaulted like `scopeNotes`. */
23549
+ staffNotes: external_exports.string().nullable().default(null),
23554
23550
  /** The customer's intake answers, rendered as child briefs carry them. */
23555
23551
  customerIntake: external_exports.string().nullable().default(null),
23556
23552
  status: PentestStatus,
@@ -28487,6 +28483,9 @@ var PentestResponseSchema = external_exports.object({
28487
28483
  /** Customer threat-model context — free text. Used by hypothesis-gen prompt. */
28488
28484
  customerConcernsContext: external_exports.string().nullable(),
28489
28485
  customerPriorityCategories: external_exports.array(CustomerPriorityCategory),
28486
+ /** Staff-only session guidance. Staff response only. `.optional()` for the same
28487
+ * rolling-deploy reason as `purchaseCapUsd`: the panel row reads Unavailable without it. */
28488
+ staffNotes: external_exports.string().nullable().optional(),
28490
28489
  hypothesisBudgetCapUsd: external_exports.number(),
28491
28490
  validationBudgetCapUsd: external_exports.number(),
28492
28491
  perHypothesisBudgetCapUsd: external_exports.number(),
@@ -28712,6 +28711,8 @@ var CreatePentestRequestSchema = external_exports.object({
28712
28711
  perHypothesisBudgetCapUsd: external_exports.number().min(0).max(1e5).optional(),
28713
28712
  purchaseCapUsd: external_exports.number().min(0).max(1e5).optional()
28714
28713
  });
28714
+ var STAFF_NOTES_MAX_CHARS = 1e4;
28715
+ var STAFF_NOTES_BRIEF_MAX_CHARS = STAFF_NOTES_MAX_CHARS * 3;
28715
28716
  var UpdatePentestRequestSchema = external_exports.object({
28716
28717
  title: external_exports.string().min(1).max(500).optional(),
28717
28718
  description: external_exports.string().max(1e4).nullable().optional(),
@@ -28733,6 +28734,8 @@ var UpdatePentestRequestSchema = external_exports.object({
28733
28734
  testType: PentestTestType.optional(),
28734
28735
  customerConcernsContext: external_exports.string().max(2e4).nullable().optional(),
28735
28736
  customerPriorityCategories: external_exports.array(CustomerPriorityCategory).max(20).optional(),
28737
+ /** Staff-only guidance for this engagement's agent sessions; `null` clears. */
28738
+ staffNotes: external_exports.string().max(STAFF_NOTES_MAX_CHARS).nullable().optional(),
28736
28739
  /** Report-cover engagement overrides. `null` clears (reverts to auto-derivation),
28737
28740
  * `undefined` leaves unchanged. Empty SUT is rejected — use `null` to clear. */
28738
28741
  systemUnderTest: external_exports.string().trim().min(1).max(200).nullable().optional(),
@@ -30394,6 +30397,46 @@ var RenewCloudCredentialsResponseSchema = external_exports.object({
30394
30397
  /** The most recently verified ACTIVE resource, whether or not its mint succeeded. Null when none. */
30395
30398
  gcpPrimaryResourceId: GcpPrefixedResourceIdSchema.nullable().optional()
30396
30399
  });
30400
+ var GetSessionCredentialsRequestSchema = external_exports.object({
30401
+ runVersion: external_exports.number().int().nonnegative()
30402
+ });
30403
+ var ParsedWebCredentialSchema = external_exports.union([
30404
+ external_exports.strictObject({
30405
+ reference: external_exports.literal("SESSION_STATE"),
30406
+ credentialId: external_exports.uuid(),
30407
+ environmentId: external_exports.uuid(),
30408
+ origin: external_exports.string()
30409
+ }),
30410
+ external_exports.strictObject({
30411
+ reference: external_exports.literal("SSH_PRIVATE_KEY"),
30412
+ credentialId: external_exports.uuid(),
30413
+ environmentId: external_exports.uuid(),
30414
+ host: external_exports.string(),
30415
+ port: external_exports.number().int(),
30416
+ username: external_exports.string()
30417
+ }),
30418
+ external_exports.strictObject({ username: external_exports.string(), password: external_exports.string() }),
30419
+ external_exports.strictObject({ secretValue: external_exports.string() }),
30420
+ external_exports.strictObject({ loginEmail: external_exports.string() })
30421
+ ]);
30422
+ var WebCredentialEntrySchema = external_exports.object({
30423
+ source: external_exports.literal("customer"),
30424
+ label: external_exports.string(),
30425
+ credentialType: external_exports.enum(CredentialTypeValues),
30426
+ parsed: ParsedWebCredentialSchema,
30427
+ authConfig: external_exports.record(external_exports.string(), external_exports.unknown()).nullable(),
30428
+ mfa: external_exports.object({ kind: external_exports.string() }).optional(),
30429
+ passkeys: external_exports.number().int().positive().optional()
30430
+ });
30431
+ var SessionCredentialsResponseSchema = external_exports.object({
30432
+ /** Empty when the type gets no web credentials or none resolved. */
30433
+ webCredentials: external_exports.array(WebCredentialEntrySchema),
30434
+ vercel: external_exports.object({ token: external_exports.string(), teamId: external_exports.string().nullable() }).nullable(),
30435
+ browserAllowedBaseUrls: external_exports.array(external_exports.string()),
30436
+ browserExclusions: external_exports.array(external_exports.string()),
30437
+ /** API_COVERAGE only; null otherwise. Range checks stay with the host's rate parser. */
30438
+ requestRate: external_exports.object({ perSec: external_exports.number(), burst: external_exports.number() }).nullable()
30439
+ });
30397
30440
  var ConvexReconRequestSchema = external_exports.object({
30398
30441
  runVersion: external_exports.number().int().nonnegative()
30399
30442
  });
@@ -31984,6 +32027,21 @@ var agentSessionInternalContract = c4.router({
31984
32027
  500: ErrorResponseSchema
31985
32028
  }
31986
32029
  },
32030
+ // The session's credentials, fetched by the host at boot (AgentSessionService.getSessionCredentials).
32031
+ getSessionCredentials: {
32032
+ method: "POST",
32033
+ path: "/internal/v1/agent-sessions/:agentSessionId/session-credentials",
32034
+ pathParams: AgentSessionInternalParamsSchema,
32035
+ body: GetSessionCredentialsRequestSchema,
32036
+ responses: {
32037
+ 200: SessionCredentialsResponseSchema,
32038
+ 400: ErrorResponseSchema,
32039
+ 401: ErrorResponseSchema,
32040
+ 403: ErrorResponseSchema,
32041
+ 409: ErrorResponseSchema,
32042
+ 500: ErrorResponseSchema
32043
+ }
32044
+ },
31987
32045
  // get_convex_deployments (Convex integration PR 3): the read-only broker. Every
31988
32046
  // connected Convex deployment for the run's OWN org, each with its function
31989
32047
  // inventory. No request identifier at all — see the schema block above. No 404:
@@ -46555,8 +46613,8 @@ var SetupVerifyResponseSchema = external_exports.object({
46555
46613
  })
46556
46614
  )
46557
46615
  });
46558
- var SetupShareLinkRequestSchema = external_exports.object({ runVersion: RunVersionSchema2 });
46559
- var SetupShareLinkResponseSchema = external_exports.object({ shareLink: external_exports.string().nullable() });
46616
+ var SetupNotesRequestSchema = external_exports.object({ runVersion: RunVersionSchema2 });
46617
+ var SetupNotesResponseSchema = external_exports.object({ notes: external_exports.string().nullable() });
46560
46618
 
46561
46619
  // ../../packages/api-contracts/src/contracts/v1/setup-session-internal.ts
46562
46620
  var c81 = initContract();
@@ -46600,12 +46658,12 @@ var setupSessionInternalContract = c81.router({
46600
46658
  body: SetupVerifyRequestSchema,
46601
46659
  responses: { 200: SetupVerifyResponseSchema, ...errors6 }
46602
46660
  },
46603
- getSetupShareLink: {
46661
+ getSetupNotes: {
46604
46662
  method: "POST",
46605
- path: `${base2}/share-link`,
46663
+ path: `${base2}/notes`,
46606
46664
  pathParams: pathParams2,
46607
- body: SetupShareLinkRequestSchema,
46608
- responses: { 200: SetupShareLinkResponseSchema, ...errors6 }
46665
+ body: SetupNotesRequestSchema,
46666
+ responses: { 200: SetupNotesResponseSchema, ...errors6 }
46609
46667
  }
46610
46668
  });
46611
46669
 
@@ -59077,7 +59135,8 @@ function buildUpdatePentestBody(input) {
59077
59135
  ...input.title !== void 0 ? { title: input.title } : {},
59078
59136
  ...input.description !== void 0 ? { description: input.description } : {},
59079
59137
  ...input.customerConcernsContext !== void 0 ? { customerConcernsContext: input.customerConcernsContext } : {},
59080
- ...input.customerPriorityCategories !== void 0 ? { customerPriorityCategories: input.customerPriorityCategories } : {}
59138
+ ...input.customerPriorityCategories !== void 0 ? { customerPriorityCategories: input.customerPriorityCategories } : {},
59139
+ ...input.staffNotes !== void 0 ? { staffNotes: input.staffNotes } : {}
59081
59140
  };
59082
59141
  }
59083
59142
  function isEmptyPentestUpdate(body) {
@@ -59179,12 +59238,15 @@ function printPentestUpdateDetail(pt) {
59179
59238
  `${"Description:".padEnd(pad)} ${pt.description ? sanitizeDisplay(truncateForDisplay(pt.description)) : "\u2014"}`,
59180
59239
  `${"Priorities:".padEnd(pad)} ${sanitizeDisplay(formatPriorities(pt.customerPriorityCategories))}`,
59181
59240
  `${"Concerns:".padEnd(pad)} ${pt.customerConcernsContext ? sanitizeDisplay(truncateForDisplay(pt.customerConcernsContext)) : "\u2014"}`,
59241
+ `${"Staff notes:".padEnd(pad)} ${pt.staffNotes ? sanitizeDisplay(truncateForDisplay(pt.staffNotes)) : "\u2014"}`,
59182
59242
  `${"Updated:".padEnd(pad)} ${toIso(pt.updatedAt)}`
59183
59243
  ].join("\n")
59184
59244
  );
59185
59245
  }
59186
59246
  function printPentestUpdateTsv(pt) {
59187
- console.log("displayId title status phase description priorities concerns updatedAt");
59247
+ console.log(
59248
+ "displayId title status phase description priorities concerns staffNotes updatedAt"
59249
+ );
59188
59250
  console.log(
59189
59251
  [
59190
59252
  `PT-${pt.displayId}`,
@@ -59194,6 +59256,7 @@ function printPentestUpdateTsv(pt) {
59194
59256
  tsvSafe2(sanitizeDisplay(pt.description ?? "")),
59195
59257
  tsvSafe2(sanitizeDisplay(pt.customerPriorityCategories.join(","))),
59196
59258
  tsvSafe2(sanitizeDisplay(pt.customerConcernsContext ?? "")),
59259
+ tsvSafe2(sanitizeDisplay(pt.staffNotes ?? "")),
59197
59260
  toIso(pt.updatedAt)
59198
59261
  ].join(" ")
59199
59262
  );
@@ -59230,16 +59293,26 @@ async function runUpdate5(pentestIdentifier, options) {
59230
59293
  console.error(colorError(priorities.error));
59231
59294
  process.exit(1);
59232
59295
  }
59296
+ const staffNotes = resolveClearableOption(
59297
+ options.staffNotes,
59298
+ options.clearStaffNotes,
59299
+ "staff-notes"
59300
+ );
59301
+ if ("error" in staffNotes) {
59302
+ console.error(colorError(staffNotes.error));
59303
+ process.exit(1);
59304
+ }
59233
59305
  const body = buildUpdatePentestBody({
59234
59306
  title: options.title,
59235
59307
  description: description.value,
59236
59308
  customerConcernsContext: concerns.value,
59237
- customerPriorityCategories: priorities.value
59309
+ customerPriorityCategories: priorities.value,
59310
+ staffNotes: staffNotes.value
59238
59311
  });
59239
59312
  if (isEmptyPentestUpdate(body)) {
59240
59313
  console.error(
59241
59314
  colorError(
59242
- "Nothing to update. Pass at least one of --title, --description, --clear-description, --concerns, --clear-concerns, --priority, --clear-priorities."
59315
+ "Nothing to update. Pass at least one of --title, --description, --clear-description, --concerns, --clear-concerns, --priority, --clear-priorities, --staff-notes, --clear-staff-notes."
59243
59316
  )
59244
59317
  );
59245
59318
  process.exit(1);
@@ -59252,19 +59325,30 @@ async function runUpdate5(pentestIdentifier, options) {
59252
59325
  if (result.status !== SUCCESS_STATUS) {
59253
59326
  failPentestUpdate(result.status, result.body, pentestIdentifier);
59254
59327
  }
59328
+ if (staffNotesIgnoredByApi(body, result.body)) {
59329
+ console.error(
59330
+ colorError(
59331
+ "This API does not support staff notes yet, so they were not saved. Any other fields you passed were saved."
59332
+ )
59333
+ );
59334
+ process.exit(1);
59335
+ }
59255
59336
  if (output === "table") {
59256
59337
  console.log(colorSuccess(`Updated pentest PT-${result.body.displayId}`));
59257
59338
  }
59258
59339
  outputPentestUpdate(result.body, output);
59259
59340
  }
59341
+ function staffNotesIgnoredByApi(body, response) {
59342
+ return body.staffNotes !== void 0 && !("staffNotes" in response);
59343
+ }
59260
59344
  function createUpdateCommand4() {
59261
59345
  return new Command("update").description(
59262
- "Update pentest details and agent brief (staff-only: title, description, priorities, concerns)"
59346
+ "Update pentest details and agent brief (staff-only: title, description, priorities, concerns, staff notes)"
59263
59347
  ).argument("<pentestId>", "Pentest display ID (e.g. PT-3) or UUID").option("--title <title>", "Engagement title").option("--description <text>", "Engagement description").option("--clear-description", "Clear the engagement description").option("--concerns <text>", "Agent-brief concerns (threat-model context)").option("--clear-concerns", "Clear agent-brief concerns").option(
59264
59348
  "--priority <category>",
59265
59349
  `Agent-brief priority category (repeatable). One of: ${PRIORITY_LIST}`,
59266
59350
  collectPriority
59267
- ).option("--clear-priorities", "Clear all agent-brief priority categories").option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
59351
+ ).option("--clear-priorities", "Clear all agent-brief priority categories").option("--staff-notes <text>", "Guidance for the agent sessions on this pentest").option("--clear-staff-notes", "Clear the staff notes").option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
59268
59352
  "after",
59269
59353
  `
59270
59354
  Staff-only. Requires a browser session from \`tracecli auth login\` with a Trace
@@ -59277,6 +59361,7 @@ Examples:
59277
59361
  tracecli pentest update PT-3 --priority AUTHN_BYPASS --priority AUTHZ_IDOR
59278
59362
  tracecli pentest update PT-3 --concerns "Worried about IDOR on invoice IDs"
59279
59363
  tracecli pentest update PT-3 --clear-concerns --clear-priorities
59364
+ tracecli pentest update PT-3 --staff-notes "Staging is behind a Cloudflare challenge; use headed agent-browser"
59280
59365
  tracecli pentest update PT-3 --title "Acme Q3" -o json`
59281
59366
  ).action(async (pentestId, options) => {
59282
59367
  await runUpdate5(pentestId, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securewithtrace",
3
- "version": "0.50.0",
3
+ "version": "0.51.0",
4
4
  "description": "Official Trace CLI for vulnerability intelligence in your terminal",
5
5
  "type": "module",
6
6
  "bin": {