@kaitranntt/ccs 7.79.1-dev.18 → 7.79.1-dev.19

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.
@@ -1209,7 +1209,18 @@ function getTools() {
1209
1209
  },
1210
1210
  event: {
1211
1211
  type: 'object',
1212
- description: 'Required event selector.',
1212
+ description:
1213
+ 'Required event selector. request events require urlIncludes; download events require urlIncludes or suggestedFilenameIncludes. URLs in returned details are redacted.',
1214
+ properties: {
1215
+ kind: { type: 'string', enum: ['dialog', 'navigation', 'request', 'download'] },
1216
+ dialogType: { type: 'string' },
1217
+ messageIncludes: { type: 'string' },
1218
+ urlIncludes: { type: 'string' },
1219
+ method: { type: 'string' },
1220
+ suggestedFilenameIncludes: { type: 'string' },
1221
+ },
1222
+ required: ['kind'],
1223
+ additionalProperties: false,
1213
1224
  },
1214
1225
  },
1215
1226
  required: ['event'],
@@ -3348,24 +3359,80 @@ function parseEventCondition(value) {
3348
3359
  };
3349
3360
  }
3350
3361
  if (value.kind === 'request') {
3362
+ const urlIncludes = value.urlIncludes ? String(value.urlIncludes) : undefined;
3363
+ if (!urlIncludes) {
3364
+ throw new Error('request events require urlIncludes to limit network metadata exposure');
3365
+ }
3351
3366
  return {
3352
3367
  kind: 'request',
3353
- urlIncludes: value.urlIncludes ? String(value.urlIncludes) : undefined,
3368
+ urlIncludes,
3354
3369
  method: value.method ? String(value.method) : undefined,
3355
3370
  };
3356
3371
  }
3357
3372
  if (value.kind === 'download') {
3373
+ const urlIncludes = value.urlIncludes ? String(value.urlIncludes) : undefined;
3374
+ const suggestedFilenameIncludes = value.suggestedFilenameIncludes
3375
+ ? String(value.suggestedFilenameIncludes)
3376
+ : undefined;
3377
+ if (!urlIncludes && !suggestedFilenameIncludes) {
3378
+ throw new Error(
3379
+ 'download events require urlIncludes or suggestedFilenameIncludes to limit metadata exposure'
3380
+ );
3381
+ }
3358
3382
  return {
3359
3383
  kind: 'download',
3360
- urlIncludes: value.urlIncludes ? String(value.urlIncludes) : undefined,
3361
- suggestedFilenameIncludes: value.suggestedFilenameIncludes
3362
- ? String(value.suggestedFilenameIncludes)
3363
- : undefined,
3384
+ urlIncludes,
3385
+ suggestedFilenameIncludes,
3364
3386
  };
3365
3387
  }
3366
3388
  throw new Error(`unknown event kind: ${String(value.kind || '')}`);
3367
3389
  }
3368
3390
 
3391
+ function redactUrlForModel(value, options = {}) {
3392
+ const rawUrl = String(value || '');
3393
+ if (!rawUrl) {
3394
+ return '';
3395
+ }
3396
+ try {
3397
+ const url = new URL(rawUrl);
3398
+ if (options.originOnly) {
3399
+ return url.origin;
3400
+ }
3401
+ url.username = '';
3402
+ url.password = '';
3403
+ url.search = '';
3404
+ url.hash = '';
3405
+ return url.toString();
3406
+ } catch {
3407
+ return '[redacted-url]';
3408
+ }
3409
+ }
3410
+
3411
+ function redactObservedEvent(event, observed) {
3412
+ if (!observed || typeof observed !== 'object') {
3413
+ return observed;
3414
+ }
3415
+ if (event.kind === 'request') {
3416
+ return {
3417
+ url: redactUrlForModel(observed.url, { originOnly: true }),
3418
+ method: observed.method || '',
3419
+ };
3420
+ }
3421
+ if (event.kind === 'download') {
3422
+ return {
3423
+ url: redactUrlForModel(observed.url, { originOnly: true }),
3424
+ suggestedFilename: observed.suggestedFilename || '',
3425
+ };
3426
+ }
3427
+ if (event.kind === 'navigation' && Object.prototype.hasOwnProperty.call(observed, 'url')) {
3428
+ return {
3429
+ ...observed,
3430
+ url: redactUrlForModel(observed.url, { originOnly: true }),
3431
+ };
3432
+ }
3433
+ return observed;
3434
+ }
3435
+
3369
3436
  function matchesObservedEvent(event, observed) {
3370
3437
  if (event.kind === 'dialog') {
3371
3438
  return (
@@ -4819,7 +4886,8 @@ async function handleWaitForEvent(toolArgs) {
4819
4886
  );
4820
4887
  const event = parseEventCondition(toolArgs.event);
4821
4888
  const observed = await waitForMatchingEvent({ page, pageIndex, timeoutMs, event });
4822
- return `pageIndex: ${pageIndex}\nevent: ${event.kind}\nstatus: observed\ndetail: ${JSON.stringify(observed)}`;
4889
+ const safeObserved = redactObservedEvent(event, observed);
4890
+ return `pageIndex: ${pageIndex}\nevent: ${event.kind}\nstatus: observed\ndetail: ${JSON.stringify(safeObserved)}`;
4823
4891
  }
4824
4892
 
4825
4893
  function findInterceptRuleIndex(ruleId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaitranntt/ccs",
3
- "version": "7.79.1-dev.18",
3
+ "version": "7.79.1-dev.19",
4
4
  "description": "Claude Code Switch - Instant profile switching between Claude, GLM, Kimi, and more",
5
5
  "keywords": [
6
6
  "cli",