agentseal 0.3.2 → 0.4.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.
- package/README.md +50 -167
- package/dist/index.cjs +3472 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +702 -1
- package/dist/index.d.ts +702 -1
- package/dist/index.js +3396 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -293,6 +293,59 @@ declare function buildExtractionProbes(): Probe[];
|
|
|
293
293
|
|
|
294
294
|
declare function buildInjectionProbes(): Probe[];
|
|
295
295
|
|
|
296
|
+
/**
|
|
297
|
+
* Custom probe loader — YAML/JSON probe definitions from files and directories.
|
|
298
|
+
*
|
|
299
|
+
* Port of Python agentseal/probes/loader.py.
|
|
300
|
+
*/
|
|
301
|
+
declare function validateProbe(probe: Record<string, any>, source: string): string[];
|
|
302
|
+
declare function buildProbe(raw: Record<string, any>): Record<string, any>;
|
|
303
|
+
declare function parseProbeFile(filePath: string): Array<Record<string, any>>;
|
|
304
|
+
/**
|
|
305
|
+
* Load custom probes from a YAML/JSON file or directory.
|
|
306
|
+
*
|
|
307
|
+
* @param path Path to a .yaml/.json file or directory containing them.
|
|
308
|
+
* @returns List of validated probe dicts.
|
|
309
|
+
*/
|
|
310
|
+
declare function loadCustomProbes(path: string): Array<Record<string, any>>;
|
|
311
|
+
/**
|
|
312
|
+
* Auto-discover probes from ~/.agentseal/probes/ and .agentseal/probes/.
|
|
313
|
+
*
|
|
314
|
+
* @returns Combined list of probes from both locations.
|
|
315
|
+
*/
|
|
316
|
+
declare function loadAllCustomProbes(): Array<Record<string, any>>;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Scan profile presets for AgentValidator.
|
|
320
|
+
*
|
|
321
|
+
* Port of Python agentseal/profiles.py.
|
|
322
|
+
*/
|
|
323
|
+
interface ProfileConfig {
|
|
324
|
+
description: string;
|
|
325
|
+
adaptive?: boolean;
|
|
326
|
+
semantic?: boolean;
|
|
327
|
+
mcp?: boolean;
|
|
328
|
+
rag?: boolean;
|
|
329
|
+
multimodal?: boolean;
|
|
330
|
+
genome?: boolean;
|
|
331
|
+
useCanaryOnly?: boolean;
|
|
332
|
+
concurrency?: number;
|
|
333
|
+
timeout?: number;
|
|
334
|
+
output?: string;
|
|
335
|
+
minScore?: number;
|
|
336
|
+
}
|
|
337
|
+
declare const PROFILES: Record<string, ProfileConfig>;
|
|
338
|
+
/** Return a profile by name, or throw with valid options. */
|
|
339
|
+
declare function resolveProfile(name: string): ProfileConfig;
|
|
340
|
+
/**
|
|
341
|
+
* Apply profile settings to an options object without overriding explicit user values.
|
|
342
|
+
* Boolean flags are only set when the current value is falsy.
|
|
343
|
+
* Optional fields are only set when the current value is undefined/null.
|
|
344
|
+
*/
|
|
345
|
+
declare function applyProfile(opts: Record<string, any>, profile: ProfileConfig): void;
|
|
346
|
+
/** Return a formatted table of available profiles. */
|
|
347
|
+
declare function listProfiles(): string;
|
|
348
|
+
|
|
296
349
|
/** Encode attack text in base64 and wrap with decode instructions. */
|
|
297
350
|
declare function base64Wrap(text: string): string;
|
|
298
351
|
|
|
@@ -332,4 +385,652 @@ declare function generateRemediation(report: ScanReport): RemediationReport;
|
|
|
332
385
|
/** Compare two scan reports and return a diff summary. */
|
|
333
386
|
declare function compareReports(baseline: ScanReport, current: ScanReport): CompareResult;
|
|
334
387
|
|
|
335
|
-
|
|
388
|
+
/**
|
|
389
|
+
* Text deobfuscation transforms for skill file content.
|
|
390
|
+
*
|
|
391
|
+
* Applied BEFORE regex pattern matching to make obfuscated payloads
|
|
392
|
+
* visible to existing detection patterns. Zero dependencies.
|
|
393
|
+
*
|
|
394
|
+
* Port of Python agentseal/deobfuscate.py — same transforms, same order.
|
|
395
|
+
*/
|
|
396
|
+
/** Remove zero-width characters: U+200B, U+200C, U+200D, U+FEFF, U+00AD, U+2060. */
|
|
397
|
+
declare function stripZeroWidth(text: string): string;
|
|
398
|
+
/** Remove Unicode Tag Characters (U+E0001–U+E007F) used in ASCII smuggling. */
|
|
399
|
+
declare function stripTagChars(text: string): string;
|
|
400
|
+
/** Remove Variation Selectors (U+FE00–FE0F, U+E0100–E01EF). */
|
|
401
|
+
declare function stripVariationSelectors(text: string): string;
|
|
402
|
+
/** Remove BiDi control characters that can hide text direction. */
|
|
403
|
+
declare function stripBidiControls(text: string): string;
|
|
404
|
+
/** Remove HTML comments that may contain hidden instructions. */
|
|
405
|
+
declare function stripHtmlComments(text: string): string;
|
|
406
|
+
/** Check if text contains any invisible/obfuscation characters. */
|
|
407
|
+
declare function hasInvisibleChars(text: string): boolean;
|
|
408
|
+
/** Apply NFKC unicode normalization (homoglyphs → ASCII). */
|
|
409
|
+
declare function normalizeUnicode(text: string): string;
|
|
410
|
+
/**
|
|
411
|
+
* Find and decode inline base64 strings.
|
|
412
|
+
* Only decodes standalone tokens >= 8 chars that produce valid printable UTF-8.
|
|
413
|
+
*/
|
|
414
|
+
declare function decodeBase64Blocks(text: string): string;
|
|
415
|
+
/**
|
|
416
|
+
* Convert common escape sequences to actual characters.
|
|
417
|
+
* Handles: \xHH, \uHHHH, \n, \t, \r, \\.
|
|
418
|
+
* Does NOT eval() anything.
|
|
419
|
+
*/
|
|
420
|
+
declare function unescapeSequences(text: string): string;
|
|
421
|
+
/**
|
|
422
|
+
* Join adjacent string literal concatenations.
|
|
423
|
+
* "abc" + "def" → "abcdef"
|
|
424
|
+
* 'abc' + 'def' → 'abcdef'
|
|
425
|
+
* Iterates until no more concatenations remain (handles chains).
|
|
426
|
+
*/
|
|
427
|
+
declare function expandStringConcat(text: string): string;
|
|
428
|
+
/**
|
|
429
|
+
* Apply all deobfuscation transforms to text.
|
|
430
|
+
*
|
|
431
|
+
* Returns cleaned text for regex pattern matching.
|
|
432
|
+
* Transforms applied in order (same as Python):
|
|
433
|
+
* 1. stripZeroWidth
|
|
434
|
+
* 2. stripTagChars
|
|
435
|
+
* 3. stripVariationSelectors
|
|
436
|
+
* 4. stripBidiControls
|
|
437
|
+
* 5. stripHtmlComments
|
|
438
|
+
* 6. normalizeUnicode (NFKC)
|
|
439
|
+
* 7. decodeBase64Blocks
|
|
440
|
+
* 8. unescapeSequences
|
|
441
|
+
* 9. expandStringConcat
|
|
442
|
+
*/
|
|
443
|
+
declare function deobfuscate(text: string): string;
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Data models for the guard command — machine-level security scanning.
|
|
447
|
+
*
|
|
448
|
+
* Port of Python agentseal/guard_models.py — same structure, TypeScript interfaces.
|
|
449
|
+
*/
|
|
450
|
+
declare const GuardVerdict: {
|
|
451
|
+
readonly SAFE: "safe";
|
|
452
|
+
readonly WARNING: "warning";
|
|
453
|
+
readonly DANGER: "danger";
|
|
454
|
+
readonly ERROR: "error";
|
|
455
|
+
};
|
|
456
|
+
type GuardVerdict = (typeof GuardVerdict)[keyof typeof GuardVerdict];
|
|
457
|
+
declare const SEVERITY_ORDER: Record<string, number>;
|
|
458
|
+
interface SkillFinding {
|
|
459
|
+
code: string;
|
|
460
|
+
title: string;
|
|
461
|
+
description: string;
|
|
462
|
+
severity: string;
|
|
463
|
+
evidence: string;
|
|
464
|
+
remediation: string;
|
|
465
|
+
}
|
|
466
|
+
interface SkillResult {
|
|
467
|
+
name: string;
|
|
468
|
+
path: string;
|
|
469
|
+
verdict: GuardVerdict;
|
|
470
|
+
findings: SkillFinding[];
|
|
471
|
+
blocklist_match: boolean;
|
|
472
|
+
sha256: string;
|
|
473
|
+
}
|
|
474
|
+
/** Return the highest-severity finding from a SkillResult, or undefined. */
|
|
475
|
+
declare function topSkillFinding(result: SkillResult): SkillFinding | undefined;
|
|
476
|
+
interface MCPFinding {
|
|
477
|
+
code: string;
|
|
478
|
+
title: string;
|
|
479
|
+
description: string;
|
|
480
|
+
severity: string;
|
|
481
|
+
remediation: string;
|
|
482
|
+
}
|
|
483
|
+
interface MCPServerResult {
|
|
484
|
+
name: string;
|
|
485
|
+
command: string;
|
|
486
|
+
source_file: string;
|
|
487
|
+
verdict: GuardVerdict;
|
|
488
|
+
findings: MCPFinding[];
|
|
489
|
+
}
|
|
490
|
+
/** Return the highest-severity finding from an MCPServerResult, or undefined. */
|
|
491
|
+
declare function topMCPFinding(result: MCPServerResult): MCPFinding | undefined;
|
|
492
|
+
interface AgentConfigResult {
|
|
493
|
+
name: string;
|
|
494
|
+
config_path: string;
|
|
495
|
+
agent_type: string;
|
|
496
|
+
mcp_servers: number;
|
|
497
|
+
skills_count: number;
|
|
498
|
+
status: string;
|
|
499
|
+
}
|
|
500
|
+
interface MCPRuntimeFinding {
|
|
501
|
+
code: string;
|
|
502
|
+
title: string;
|
|
503
|
+
description: string;
|
|
504
|
+
severity: string;
|
|
505
|
+
evidence: string;
|
|
506
|
+
remediation: string;
|
|
507
|
+
tool_name: string;
|
|
508
|
+
server_name: string;
|
|
509
|
+
}
|
|
510
|
+
interface MCPRuntimeResult {
|
|
511
|
+
server_name: string;
|
|
512
|
+
tools_found: number;
|
|
513
|
+
findings: MCPRuntimeFinding[];
|
|
514
|
+
verdict: GuardVerdict;
|
|
515
|
+
connection_status: string;
|
|
516
|
+
}
|
|
517
|
+
interface ToxicFlowResult {
|
|
518
|
+
risk_level: string;
|
|
519
|
+
risk_type: string;
|
|
520
|
+
title: string;
|
|
521
|
+
description: string;
|
|
522
|
+
servers_involved: string[];
|
|
523
|
+
remediation: string;
|
|
524
|
+
tools_involved: string[];
|
|
525
|
+
labels_involved: string[];
|
|
526
|
+
}
|
|
527
|
+
interface BaselineChangeResult {
|
|
528
|
+
server_name: string;
|
|
529
|
+
agent_type: string;
|
|
530
|
+
change_type: string;
|
|
531
|
+
detail: string;
|
|
532
|
+
}
|
|
533
|
+
interface GuardReport {
|
|
534
|
+
timestamp: string;
|
|
535
|
+
duration_seconds: number;
|
|
536
|
+
agents_found: AgentConfigResult[];
|
|
537
|
+
skill_results: SkillResult[];
|
|
538
|
+
mcp_results: MCPServerResult[];
|
|
539
|
+
mcp_runtime_results: MCPRuntimeResult[];
|
|
540
|
+
toxic_flows: ToxicFlowResult[];
|
|
541
|
+
baseline_changes: BaselineChangeResult[];
|
|
542
|
+
llm_tokens_used: number;
|
|
543
|
+
}
|
|
544
|
+
declare function totalDangers(report: GuardReport): number;
|
|
545
|
+
declare function totalWarnings(report: GuardReport): number;
|
|
546
|
+
declare function totalSafe(report: GuardReport): number;
|
|
547
|
+
declare function hasCritical(report: GuardReport): boolean;
|
|
548
|
+
/** Collect all remediation actions, sorted by severity. */
|
|
549
|
+
declare function allActions(report: GuardReport): string[];
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Skill threat detection — layered analysis for skill/rules files.
|
|
553
|
+
*
|
|
554
|
+
* Layer 1: Static pattern matching (compiled regex, ~1ms per skill)
|
|
555
|
+
* Layer 2: Semantic similarity against known danger concepts (optional)
|
|
556
|
+
*
|
|
557
|
+
* Port of Python agentseal/detection/skill_detector.py — same patterns, same order.
|
|
558
|
+
*/
|
|
559
|
+
|
|
560
|
+
declare const DANGER_CONCEPTS: string[];
|
|
561
|
+
declare class SkillScanner {
|
|
562
|
+
/** Layer 1: Fast static pattern matching against known threat patterns. */
|
|
563
|
+
scanPatterns(content: string): SkillFinding[];
|
|
564
|
+
/**
|
|
565
|
+
* Layer 2: Semantic similarity against known danger concepts.
|
|
566
|
+
*
|
|
567
|
+
* Requires an embedding function. Returns empty array if not provided.
|
|
568
|
+
* Compares content chunks against DANGER_CONCEPTS with similarity thresholds.
|
|
569
|
+
*/
|
|
570
|
+
scanSemantic(content: string, embedFn?: (texts: string[]) => Promise<number[][]>): Promise<SkillFinding[]>;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Malicious skill blocklist client.
|
|
575
|
+
*
|
|
576
|
+
* Maintains a local cache of known-malicious skill hashes.
|
|
577
|
+
* Auto-updates from agentseal.org on each run (with 1-hour cache TTL).
|
|
578
|
+
* Works fully offline — falls back to cached or empty blocklist.
|
|
579
|
+
*
|
|
580
|
+
* Port of Python agentseal/blocklist.py — same logic.
|
|
581
|
+
*/
|
|
582
|
+
declare class Blocklist {
|
|
583
|
+
static readonly REMOTE_URL = "https://agentseal.org/api/v1/blocklist/skills.json";
|
|
584
|
+
static readonly CACHE_TTL = 3600;
|
|
585
|
+
private _hashes;
|
|
586
|
+
private _loaded;
|
|
587
|
+
private _cacheDir;
|
|
588
|
+
private _cachePath;
|
|
589
|
+
constructor(cacheDir?: string);
|
|
590
|
+
/** Override cache dir (useful for testing). */
|
|
591
|
+
setCacheDir(dir: string): void;
|
|
592
|
+
private _load;
|
|
593
|
+
private _loadFromFile;
|
|
594
|
+
private _tryRemoteFetch;
|
|
595
|
+
/** Async remote fetch — call this once at startup if you want remote blocklist. */
|
|
596
|
+
loadAsync(): Promise<void>;
|
|
597
|
+
/** Check if a SHA256 hash is in the blocklist. */
|
|
598
|
+
isBlocked(sha256: string): boolean;
|
|
599
|
+
/** Number of hashes in the blocklist. */
|
|
600
|
+
get size(): number;
|
|
601
|
+
/** Manually add hashes (for testing or seed data). */
|
|
602
|
+
addHashes(hashes: string[]): void;
|
|
603
|
+
}
|
|
604
|
+
/** Compute SHA256 hash of content. */
|
|
605
|
+
declare function sha256(content: string): string;
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Toxic flow detection — static analysis of MCP server capability combinations.
|
|
609
|
+
*
|
|
610
|
+
* Classifies MCP servers by capability labels and detects dangerous
|
|
611
|
+
* combinations that could enable data exfiltration, remote code execution,
|
|
612
|
+
* or data destruction.
|
|
613
|
+
*
|
|
614
|
+
* Port of Python agentseal/toxic_flows.py — static analysis only.
|
|
615
|
+
*/
|
|
616
|
+
|
|
617
|
+
declare const LABEL_PUBLIC_SINK = "public_sink";
|
|
618
|
+
declare const LABEL_DESTRUCTIVE = "destructive";
|
|
619
|
+
declare const LABEL_UNTRUSTED = "untrusted_content";
|
|
620
|
+
declare const LABEL_PRIVATE = "private_data";
|
|
621
|
+
declare const KNOWN_SERVER_LABELS: Record<string, Set<string>>;
|
|
622
|
+
declare function classifyServer(server: Record<string, any>): Set<string>;
|
|
623
|
+
/**
|
|
624
|
+
* Analyze MCP servers for dangerous capability combinations.
|
|
625
|
+
* Requires at least 2 servers for cross-server flow detection.
|
|
626
|
+
*/
|
|
627
|
+
declare function analyzeToxicFlows(servers: Array<Record<string, any>>): ToxicFlowResult[];
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* Rug pull detection via baseline fingerprinting.
|
|
631
|
+
*
|
|
632
|
+
* On first scan, fingerprints MCP server configurations. On subsequent scans,
|
|
633
|
+
* detects changes and alerts the user.
|
|
634
|
+
*
|
|
635
|
+
* Storage: ~/.agentseal/baselines/{agent_type}/{server_name}.json
|
|
636
|
+
*
|
|
637
|
+
* Port of Python agentseal/baselines.py.
|
|
638
|
+
*/
|
|
639
|
+
interface BaselineEntry {
|
|
640
|
+
server_name: string;
|
|
641
|
+
agent_type: string;
|
|
642
|
+
config_hash: string;
|
|
643
|
+
binary_hash: string | null;
|
|
644
|
+
binary_path: string | null;
|
|
645
|
+
command: string;
|
|
646
|
+
args: string[];
|
|
647
|
+
first_seen: string;
|
|
648
|
+
last_verified: string;
|
|
649
|
+
tool_signatures_hash?: string | null;
|
|
650
|
+
tool_count?: number | null;
|
|
651
|
+
tools_detail?: Array<{
|
|
652
|
+
name: string;
|
|
653
|
+
hash: string;
|
|
654
|
+
}> | null;
|
|
655
|
+
}
|
|
656
|
+
interface BaselineChange {
|
|
657
|
+
server_name: string;
|
|
658
|
+
agent_type: string;
|
|
659
|
+
change_type: string;
|
|
660
|
+
old_value?: string | null;
|
|
661
|
+
new_value?: string | null;
|
|
662
|
+
detail: string;
|
|
663
|
+
}
|
|
664
|
+
declare class BaselineStore {
|
|
665
|
+
private readonly _dir;
|
|
666
|
+
constructor(baselinesDir?: string);
|
|
667
|
+
private _entryPath;
|
|
668
|
+
/** Load a stored baseline entry. Returns null if not found. */
|
|
669
|
+
load(agentType: string, serverName: string): BaselineEntry | null;
|
|
670
|
+
/** Save a baseline entry to disk. */
|
|
671
|
+
save(entry: BaselineEntry): void;
|
|
672
|
+
/** Check a single MCP server against its stored baseline. */
|
|
673
|
+
checkServer(server: Record<string, any>): BaselineChange | null;
|
|
674
|
+
/** Check all servers. Returns list of changes (empty = no changes). */
|
|
675
|
+
checkAll(servers: Array<Record<string, any>>, includeNew?: boolean): BaselineChange[];
|
|
676
|
+
/** Remove all baselines. Returns count of entries removed. */
|
|
677
|
+
reset(): number;
|
|
678
|
+
/** List all stored baseline entries. */
|
|
679
|
+
listEntries(): BaselineEntry[];
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* MCP Config Checker — static analysis of MCP server configurations.
|
|
684
|
+
*
|
|
685
|
+
* Reads JSON config dicts and flags dangerous permissions, exposed credentials,
|
|
686
|
+
* and supply chain risks. Does NOT connect to MCP servers.
|
|
687
|
+
*
|
|
688
|
+
* Port of Python agentseal/mcp_checker.py — same checks, same codes.
|
|
689
|
+
*/
|
|
690
|
+
|
|
691
|
+
declare function shannonEntropy(s: string): number;
|
|
692
|
+
declare function verdictFromFindings(findings: MCPFinding[]): GuardVerdict;
|
|
693
|
+
declare class MCPConfigChecker {
|
|
694
|
+
/** Check a single MCP server config dict for security issues. */
|
|
695
|
+
check(server: Record<string, any>): MCPServerResult;
|
|
696
|
+
/** Check multiple MCP server configs. */
|
|
697
|
+
checkAll(servers: Array<Record<string, any>>): MCPServerResult[];
|
|
698
|
+
private _checkSensitivePaths;
|
|
699
|
+
private _checkEnvCredentials;
|
|
700
|
+
private _checkBroadAccess;
|
|
701
|
+
private _checkInsecureUrls;
|
|
702
|
+
private _checkHttpServer;
|
|
703
|
+
private _checkSupplyChain;
|
|
704
|
+
private _checkCommandInjection;
|
|
705
|
+
private _checkMissingAuth;
|
|
706
|
+
private _checkKnownCVEs;
|
|
707
|
+
private _checkHighEntropySecrets;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* Guard — one-command machine security scan.
|
|
712
|
+
*
|
|
713
|
+
* Chains machine discovery, skill scanning, blocklist, and deobfuscation
|
|
714
|
+
* into a single zero-config experience.
|
|
715
|
+
*
|
|
716
|
+
* Port of Python agentseal/guard.py + agentseal/skill_scanner.py.
|
|
717
|
+
*/
|
|
718
|
+
|
|
719
|
+
type GuardProgressFn = (phase: string, detail: string) => void;
|
|
720
|
+
interface GuardOptions {
|
|
721
|
+
/** Enable semantic analysis (requires embedFn). Default: false */
|
|
722
|
+
semantic?: boolean;
|
|
723
|
+
/** Verbose output. Default: false */
|
|
724
|
+
verbose?: boolean;
|
|
725
|
+
/** Progress callback. */
|
|
726
|
+
onProgress?: GuardProgressFn;
|
|
727
|
+
/** Embedding function for semantic analysis. */
|
|
728
|
+
embedFn?: (texts: string[]) => Promise<number[][]>;
|
|
729
|
+
/** Scan a specific directory instead of the whole machine. */
|
|
730
|
+
scanPath?: string;
|
|
731
|
+
}
|
|
732
|
+
/** Extract a human-readable name from a skill file path. */
|
|
733
|
+
declare function extractSkillName(filePath: string): string;
|
|
734
|
+
/** Determine verdict from findings. Worst severity wins. */
|
|
735
|
+
declare function computeVerdict(findings: SkillFinding[]): GuardVerdict;
|
|
736
|
+
/** Scan a single skill file through all detection layers. */
|
|
737
|
+
declare function scanSkillFile(filePath: string, scanner: SkillScanner, blocklist: Blocklist): SkillResult;
|
|
738
|
+
declare class Guard {
|
|
739
|
+
private readonly _options;
|
|
740
|
+
constructor(options?: GuardOptions);
|
|
741
|
+
/** Execute full guard scan. Returns a GuardReport with all findings. */
|
|
742
|
+
run(): GuardReport;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/**
|
|
746
|
+
* Machine-level agent discovery — finds ALL AI agents, MCP servers, and skills
|
|
747
|
+
* installed on the user's machine by checking well-known config paths.
|
|
748
|
+
*
|
|
749
|
+
* Port of Python agentseal/machine_discovery.py — same locations, same logic.
|
|
750
|
+
*/
|
|
751
|
+
|
|
752
|
+
/** Project-level MCP config definitions. [relPath, mcpKey, format] */
|
|
753
|
+
declare const PROJECT_MCP_CONFIGS: Array<[string, string, string | null]>;
|
|
754
|
+
/** Project-level skill files. */
|
|
755
|
+
declare const PROJECT_SKILL_FILES: string[];
|
|
756
|
+
/** Project-level skill directories. */
|
|
757
|
+
declare const PROJECT_SKILL_DIRS: string[];
|
|
758
|
+
interface AgentDef {
|
|
759
|
+
name: string;
|
|
760
|
+
agent_type: string;
|
|
761
|
+
paths: Record<string, string | null>;
|
|
762
|
+
mcp_key: string | null;
|
|
763
|
+
format?: string;
|
|
764
|
+
}
|
|
765
|
+
declare function getWellKnownConfigs(): AgentDef[];
|
|
766
|
+
/** Strip // and /* * / comments from JSONC. Preserves URLs inside strings. */
|
|
767
|
+
declare function stripJsonComments(text: string): string;
|
|
768
|
+
interface MCPServerConfig {
|
|
769
|
+
name: string;
|
|
770
|
+
source_file: string;
|
|
771
|
+
agent_type: string;
|
|
772
|
+
[key: string]: unknown;
|
|
773
|
+
}
|
|
774
|
+
interface DiscoveryResult {
|
|
775
|
+
agents: AgentConfigResult[];
|
|
776
|
+
mcpServers: MCPServerConfig[];
|
|
777
|
+
skillPaths: string[];
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* Discover all AI agents, MCP servers, and skills on this machine.
|
|
781
|
+
* Scans well-known config paths + CWD.
|
|
782
|
+
*/
|
|
783
|
+
declare function scanMachine(): DiscoveryResult;
|
|
784
|
+
/**
|
|
785
|
+
* Scan a specific project directory for MCP configs and skill files.
|
|
786
|
+
* Unlike scanMachine(), this only looks within the given directory.
|
|
787
|
+
*/
|
|
788
|
+
declare function scanDirectory(directory: string): DiscoveryResult;
|
|
789
|
+
|
|
790
|
+
/**
|
|
791
|
+
* Fix engine — skill quarantine + report loading.
|
|
792
|
+
*
|
|
793
|
+
* Provides core logic for the `agentseal fix` command:
|
|
794
|
+
* - Quarantine dangerous skills (move to ~/.agentseal/quarantine/)
|
|
795
|
+
* - Restore quarantined skills
|
|
796
|
+
* - Load/save guard and scan reports
|
|
797
|
+
* - Extract fixable skills from guard reports
|
|
798
|
+
*
|
|
799
|
+
* Port of Python agentseal/fix.py.
|
|
800
|
+
*/
|
|
801
|
+
declare const QUARANTINE_DIR: string;
|
|
802
|
+
declare const REPORTS_DIR: string;
|
|
803
|
+
declare const BACKUPS_DIR: string;
|
|
804
|
+
interface QuarantineEntry {
|
|
805
|
+
original_path: string;
|
|
806
|
+
quarantine_path: string;
|
|
807
|
+
reason: string;
|
|
808
|
+
timestamp: string;
|
|
809
|
+
skill_name: string;
|
|
810
|
+
}
|
|
811
|
+
interface FixResult {
|
|
812
|
+
action: string;
|
|
813
|
+
target: string;
|
|
814
|
+
detail: string;
|
|
815
|
+
before: string | null;
|
|
816
|
+
after: string | null;
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Move a dangerous skill to quarantine.
|
|
820
|
+
*
|
|
821
|
+
* Preserves relative directory structure under the quarantine dir.
|
|
822
|
+
* Handles duplicate filenames by adding _1, _2, etc. suffixes.
|
|
823
|
+
*/
|
|
824
|
+
declare function quarantineSkill(skillPath: string, reason?: string, quarantineDir?: string): QuarantineEntry;
|
|
825
|
+
/**
|
|
826
|
+
* Restore a quarantined skill to its original location.
|
|
827
|
+
*
|
|
828
|
+
* @throws Error if skill not in quarantine, original path occupied, or file missing.
|
|
829
|
+
*/
|
|
830
|
+
declare function restoreSkill(skillName: string, quarantineDir?: string): string;
|
|
831
|
+
/** List all quarantined skills from manifest. */
|
|
832
|
+
declare function listQuarantine(quarantineDir?: string): QuarantineEntry[];
|
|
833
|
+
/** Load guard report from file or latest from reportsDir. */
|
|
834
|
+
declare function loadGuardReport(path?: string, reportsDir?: string): Record<string, any>;
|
|
835
|
+
/** Load scan report from file or latest from reportsDir. */
|
|
836
|
+
declare function loadScanReport(path?: string, reportsDir?: string): Record<string, any>;
|
|
837
|
+
/** Save report to reportsDir/{type}-latest.json. Creates dir if needed. */
|
|
838
|
+
declare function saveReport(reportDict: Record<string, any>, reportType: string, reportsDir?: string): string;
|
|
839
|
+
/** Extract skills with DANGER verdict from guard report. */
|
|
840
|
+
declare function getFixableSkills(guardReport: Record<string, any>): Array<Record<string, any>>;
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* Attack chain detection from scan results.
|
|
844
|
+
*
|
|
845
|
+
* Analyzes existing ProbeResult data to identify complete attack paths.
|
|
846
|
+
* Does NOT run new probes.
|
|
847
|
+
*
|
|
848
|
+
* Port of Python agentseal/chains.py.
|
|
849
|
+
*/
|
|
850
|
+
|
|
851
|
+
interface ChainStep {
|
|
852
|
+
step_number: number;
|
|
853
|
+
probe_id: string;
|
|
854
|
+
category: string;
|
|
855
|
+
technique: string;
|
|
856
|
+
verdict: string;
|
|
857
|
+
summary: string;
|
|
858
|
+
}
|
|
859
|
+
interface AttackChain {
|
|
860
|
+
chain_type: string;
|
|
861
|
+
severity: string;
|
|
862
|
+
title: string;
|
|
863
|
+
description: string;
|
|
864
|
+
steps: ChainStep[];
|
|
865
|
+
remediation: string;
|
|
866
|
+
}
|
|
867
|
+
/** Analyze probe results to identify complete attack chains. */
|
|
868
|
+
declare function detectChains(report: ScanReport): AttackChain[];
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* LLM Judge — optional AI-powered analysis layer for skill scanning.
|
|
872
|
+
*
|
|
873
|
+
* Sends skill file content to an LLM for deep security analysis.
|
|
874
|
+
* Users bring their own API key. Supports OpenAI, Anthropic, Ollama, and
|
|
875
|
+
* OpenRouter; anything OpenAI-compatible works too.
|
|
876
|
+
*
|
|
877
|
+
* Port of Python agentseal/llm_judge.py.
|
|
878
|
+
*/
|
|
879
|
+
declare const MAX_CONTENT_BYTES: number;
|
|
880
|
+
interface LLMJudgeFinding {
|
|
881
|
+
title: string;
|
|
882
|
+
severity?: string;
|
|
883
|
+
evidence?: string;
|
|
884
|
+
reasoning?: string;
|
|
885
|
+
}
|
|
886
|
+
interface LLMJudgeResult {
|
|
887
|
+
verdict: string;
|
|
888
|
+
confidence: number;
|
|
889
|
+
findings: LLMJudgeFinding[];
|
|
890
|
+
model: string;
|
|
891
|
+
tokens_used: number;
|
|
892
|
+
error?: string | null;
|
|
893
|
+
}
|
|
894
|
+
declare const SYSTEM_PROMPT: string;
|
|
895
|
+
declare function detectProvider(model: string): string;
|
|
896
|
+
declare function stripModelPrefix(model: string, provider: string): string;
|
|
897
|
+
declare function parseResponse(raw: string, model: string, tokens: number): LLMJudgeResult;
|
|
898
|
+
/** Truncate content to MAX_CONTENT_BYTES. */
|
|
899
|
+
declare function truncateContent(content: string): string;
|
|
900
|
+
interface LLMJudgeOptions {
|
|
901
|
+
model: string;
|
|
902
|
+
apiKey?: string;
|
|
903
|
+
baseUrl?: string;
|
|
904
|
+
timeout?: number;
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* Send skill content to an LLM for security analysis.
|
|
908
|
+
*
|
|
909
|
+
* Supported model formats:
|
|
910
|
+
* "gpt-4o", "gpt-4o-mini" -> OpenAI (OPENAI_API_KEY)
|
|
911
|
+
* "claude-sonnet-4-5-20250929" -> Anthropic (ANTHROPIC_API_KEY)
|
|
912
|
+
* "ollama/llama3.1:8b" -> Ollama local
|
|
913
|
+
* "openrouter/..." -> OpenRouter
|
|
914
|
+
*/
|
|
915
|
+
declare class LLMJudge {
|
|
916
|
+
readonly model: string;
|
|
917
|
+
readonly provider: string;
|
|
918
|
+
readonly apiKey: string | undefined;
|
|
919
|
+
readonly baseUrl: string | undefined;
|
|
920
|
+
readonly timeout: number;
|
|
921
|
+
constructor(options: LLMJudgeOptions);
|
|
922
|
+
/** Analyse a single skill file. Never throws. */
|
|
923
|
+
analyzeSkill(content: string, filename: string): Promise<LLMJudgeResult>;
|
|
924
|
+
/** Analyse multiple (content, filename) pairs with concurrency control. */
|
|
925
|
+
analyzeBatch(files: Array<[string, string]>, concurrency?: number): Promise<LLMJudgeResult[]>;
|
|
926
|
+
private _callOpenAICompat;
|
|
927
|
+
private _callAnthropic;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
/**
|
|
931
|
+
* Desktop notifications for AgentSeal Shield.
|
|
932
|
+
*
|
|
933
|
+
* Uses OS built-in notification mechanisms — no additional dependencies.
|
|
934
|
+
* macOS: osascript, Linux: notify-send, Fallback: terminal bell + stderr.
|
|
935
|
+
*
|
|
936
|
+
* Port of Python agentseal/notify.py.
|
|
937
|
+
*/
|
|
938
|
+
declare class Notifier {
|
|
939
|
+
private _enabled;
|
|
940
|
+
private _minInterval;
|
|
941
|
+
private _lastNotifyTime;
|
|
942
|
+
private _platform;
|
|
943
|
+
constructor(enabled?: boolean, minInterval?: number);
|
|
944
|
+
get enabled(): boolean;
|
|
945
|
+
/** Send a desktop notification. Returns true if sent. Respects throttle interval. */
|
|
946
|
+
notify(title: string, message: string, urgent?: boolean): boolean;
|
|
947
|
+
/** Send a threat notification with standard formatting. */
|
|
948
|
+
notifyThreat(itemName: string, itemType: string, severity: string, detail: string): boolean;
|
|
949
|
+
private _dispatch;
|
|
950
|
+
private _notifyMacOS;
|
|
951
|
+
private _notifyLinux;
|
|
952
|
+
private _notifyFallback;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
/**
|
|
956
|
+
* Shield — continuous filesystem monitoring for AI agent security.
|
|
957
|
+
*
|
|
958
|
+
* Watches skill directories, MCP config files, and agent config dirs.
|
|
959
|
+
* When a file changes, triggers an incremental scan and optionally sends
|
|
960
|
+
* desktop notifications.
|
|
961
|
+
*
|
|
962
|
+
* Uses Node.js built-in fs.watch (recursive on macOS/Windows).
|
|
963
|
+
*
|
|
964
|
+
* Port of Python agentseal/shield.py.
|
|
965
|
+
*/
|
|
966
|
+
/** Callback: (eventType, path, resultSummary) */
|
|
967
|
+
type ShieldCallback = (eventType: string, path: string, summary: string) => void;
|
|
968
|
+
interface ShieldOptions {
|
|
969
|
+
/** Enable semantic analysis. Default: false */
|
|
970
|
+
semantic?: boolean;
|
|
971
|
+
/** Enable desktop notifications. Default: true */
|
|
972
|
+
notify?: boolean;
|
|
973
|
+
/** Debounce seconds for filesystem events. Default: 2.0 */
|
|
974
|
+
debounceSeconds?: number;
|
|
975
|
+
/** Callback for shield events. */
|
|
976
|
+
onEvent?: ShieldCallback;
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Per-path debouncing for filesystem events.
|
|
980
|
+
* Accumulates events and fires only after a quiet period.
|
|
981
|
+
*/
|
|
982
|
+
declare class DebouncedHandler {
|
|
983
|
+
private _onChange;
|
|
984
|
+
private _debounceMs;
|
|
985
|
+
private _timers;
|
|
986
|
+
constructor(onChange: (filePath: string) => void, debounceMs?: number);
|
|
987
|
+
/** Handle a filesystem event. Skips directories and temp files. */
|
|
988
|
+
handleEvent(filePath: string, isDirectory?: boolean): void;
|
|
989
|
+
/** Cancel all pending timers. */
|
|
990
|
+
cancelAll(): void;
|
|
991
|
+
/** Number of pending timers (for testing). */
|
|
992
|
+
get pendingCount(): number;
|
|
993
|
+
}
|
|
994
|
+
/** Classify a changed file as 'skill', 'mcp_config', or 'unknown'. */
|
|
995
|
+
declare function classifyPath(filePath: string): string;
|
|
996
|
+
/** Collect all paths that shield should monitor. */
|
|
997
|
+
declare function collectWatchPaths(homeOverride?: string): {
|
|
998
|
+
dirs: string[];
|
|
999
|
+
files: string[];
|
|
1000
|
+
};
|
|
1001
|
+
declare class Shield {
|
|
1002
|
+
private _onEvent;
|
|
1003
|
+
private _notifier;
|
|
1004
|
+
private _scanner;
|
|
1005
|
+
private _mcpChecker;
|
|
1006
|
+
private _blocklist;
|
|
1007
|
+
private _baselineStore;
|
|
1008
|
+
private _debounceMs;
|
|
1009
|
+
private _watchers;
|
|
1010
|
+
private _handler;
|
|
1011
|
+
private _running;
|
|
1012
|
+
private _scanCount;
|
|
1013
|
+
private _threatCount;
|
|
1014
|
+
constructor(options?: ShieldOptions);
|
|
1015
|
+
get scanCount(): number;
|
|
1016
|
+
get threatCount(): number;
|
|
1017
|
+
get running(): boolean;
|
|
1018
|
+
/** Handle a single file change event. */
|
|
1019
|
+
handleChange(filePath: string): void;
|
|
1020
|
+
private _scanSkill;
|
|
1021
|
+
private _scanMcpConfig;
|
|
1022
|
+
/**
|
|
1023
|
+
* Start watching. Returns { dirsWatched, filesWatched }.
|
|
1024
|
+
*
|
|
1025
|
+
* Uses Node.js fs.watch with recursive option (macOS/Windows).
|
|
1026
|
+
* Does NOT block — call stop() to clean up.
|
|
1027
|
+
*/
|
|
1028
|
+
start(homeOverride?: string): {
|
|
1029
|
+
dirsWatched: number;
|
|
1030
|
+
filesWatched: number;
|
|
1031
|
+
};
|
|
1032
|
+
/** Stop the filesystem watchers. */
|
|
1033
|
+
stop(): void;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
export { type AffectedProbe, type AgentConfigResult, AgentSealError, AgentValidator, type AttackChain, BACKUPS_DIR, BOUNDARY_CATEGORIES, BOUNDARY_WEIGHT, type BaselineChange, type BaselineChangeResult, type BaselineEntry, BaselineStore, Blocklist, COMMON_WORDS, CONSISTENCY_WEIGHT, type ChainStep, type ChatFn, type CompareResult, DANGER_CONCEPTS, DATA_EXTRACTION_WEIGHT, DebouncedHandler, type DefenseProfile, type DiscoveryResult, EXTRACTION_WEIGHT, type EmbedFn, type FixResult, Guard, type GuardOptions, type GuardProgressFn, type GuardReport, GuardVerdict, INJECTION_WEIGHT, KNOWN_SERVER_LABELS, LABEL_DESTRUCTIVE, LABEL_PRIVATE, LABEL_PUBLIC_SINK, LABEL_UNTRUSTED, LLMJudge, type LLMJudgeFinding, type LLMJudgeOptions, type LLMJudgeResult, MAX_CONTENT_BYTES, MCPConfigChecker, type MCPFinding, type MCPRuntimeFinding, type MCPRuntimeResult, type MCPServerResult, Notifier, PROFILES, PROJECT_MCP_CONFIGS, PROJECT_SKILL_DIRS, PROJECT_SKILL_FILES, type Probe, type ProbeResult, ProbeTimeoutError, type ProfileConfig, type ProgressFn, ProviderError, QUARANTINE_DIR, type QuarantineEntry, REFUSAL_PHRASES, REPORTS_DIR, type RemediationItem, type RemediationReport, SEMANTIC_HIGH_THRESHOLD, SEMANTIC_MODERATE_THRESHOLD, SEVERITY_ORDER, SYSTEM_PROMPT, type ScanReport, type ScoreBreakdown, Severity, Shield, type ShieldCallback, type ShieldOptions, type SkillFinding, type SkillResult, SkillScanner, TRANSFORMS, type ToxicFlowResult, TrustLevel, ValidationError, type ValidatorOptions, Verdict, allActions, analyzeToxicFlows, applyProfile, base64Wrap, buildExtractionProbes, buildInjectionProbes, buildProbe, caseScramble, classifyPath, classifyServer, collectWatchPaths, compareReports, computeScores, computeSemanticSimilarity, computeVerdict, decodeBase64Blocks, deobfuscate, detectCanary, detectChains, detectExtraction, detectExtractionWithSemantic, detectProvider, expandStringConcat, extractSkillName, extractUniquePhrases, fingerprintDefense, fromAnthropic, fromEndpoint, fromLangChain, fromOllama, fromOpenAI, fromVercelAI, fuseVerdicts, generateCanary, generateMutations, generateRemediation, getFixableSkills, getWellKnownConfigs, hasCritical, hasInvisibleChars, isRefusal, leetspeak, listProfiles, listQuarantine, loadAllCustomProbes, loadCustomProbes, loadGuardReport, loadScanReport, normalizeUnicode, parseProbeFile, parseResponse, prefixPadding, quarantineSkill, resolveProfile, restoreSkill, reverseEmbed, rot13Wrap, saveReport, scanDirectory, scanMachine, scanSkillFile, sha256, shannonEntropy, stripBidiControls, stripHtmlComments, stripJsonComments, stripModelPrefix, stripTagChars, stripVariationSelectors, stripZeroWidth, topMCPFinding, topSkillFinding, totalDangers, totalSafe, totalWarnings, truncateContent, trustLevelFromScore, unescapeSequences, unicodeHomoglyphs, validateProbe, verdictFromFindings, verdictScore, zeroWidthInject };
|