network-ai
Advanced tools
| /** | ||
| * Redis Blackboard Backend | ||
| * | ||
| * Provides a `RedisBackend` implementation of `BlackboardBackend` suitable for | ||
| * multi-process and multi-machine agent coordination. Data is shared across all | ||
| * processes that connect to the same Redis server. | ||
| * | ||
| * Architecture — write-through cache: | ||
| * Reads → served from a local in-memory cache (fast, sync) | ||
| * Writes → written to local cache immediately, then flushed to Redis async | ||
| * Hydrate → on startup, loads existing keys from Redis into the local cache | ||
| * | ||
| * This design keeps the synchronous `BlackboardBackend` interface intact while | ||
| * still leveraging Redis for distributed coordination. | ||
| * | ||
| * Peer dependency: | ||
| * Install `ioredis`, `node-redis`, or any Redis client that satisfies the | ||
| * minimal `RedisClient` interface defined below. No production dependency is | ||
| * added to network-ai — Redis is optional and user-supplied. | ||
| * | ||
| * npm install ioredis # recommended | ||
| * # or | ||
| * npm install redis # node-redis v4+ | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import Redis from 'ioredis'; | ||
| * import { RedisBackend } from 'network-ai/lib/blackboard-backend-redis'; | ||
| * | ||
| * const client = new Redis({ host: 'localhost', port: 6379 }); | ||
| * const backend = new RedisBackend(client, { keyPrefix: 'myapp:bb:' }); | ||
| * await backend.hydrate(); // load existing data from Redis | ||
| * | ||
| * const board = orchestrator.getBlackboard('prod', { backend }); | ||
| * ``` | ||
| * | ||
| * @module BlackboardBackendRedis | ||
| * @version 1.0.0 | ||
| * @license MIT | ||
| */ | ||
| import type { BlackboardBackend, BlackboardEntry } from './blackboard-backend'; | ||
| /** | ||
| * Minimal pipeline interface — returned by `client.pipeline()` or | ||
| * `client.multi()`. Only the methods used by `RedisBackend` are required. | ||
| */ | ||
| export interface RedisPipeline { | ||
| set(key: string, value: string): this; | ||
| set(key: string, value: string, exArg: 'EX', seconds: number): this; | ||
| exec(): Promise<unknown[]>; | ||
| } | ||
| /** | ||
| * Minimal Redis client interface. | ||
| * | ||
| * Any client that satisfies this shape can be used — ioredis, node-redis v4+, | ||
| * or a custom mock for testing. | ||
| */ | ||
| export interface RedisClient { | ||
| get(key: string): Promise<string | null>; | ||
| set(key: string, value: string): Promise<unknown>; | ||
| set(key: string, value: string, exArg: 'EX', seconds: number): Promise<unknown>; | ||
| del(...keys: string[]): Promise<number>; | ||
| keys(pattern: string): Promise<string[]>; | ||
| pipeline(): RedisPipeline; | ||
| } | ||
| export interface RedisBackendOptions { | ||
| /** | ||
| * Prefix prepended to every Redis key. | ||
| * Useful for namespacing multiple boards on the same Redis server. | ||
| * @default 'network-ai:bb:' | ||
| */ | ||
| keyPrefix?: string; | ||
| } | ||
| /** | ||
| * Redis-backed `BlackboardBackend` for multi-process / multi-machine | ||
| * agent coordination. | ||
| * | ||
| * Uses a write-through local cache so reads remain synchronous and fast. | ||
| * Call `hydrate()` after construction to load any pre-existing Redis data | ||
| * into the local cache before your agents start reading. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import Redis from 'ioredis'; | ||
| * import { RedisBackend } from 'network-ai/lib/blackboard-backend-redis'; | ||
| * | ||
| * const client = new Redis(); | ||
| * const backend = new RedisBackend(client, { keyPrefix: 'project-x:bb:' }); | ||
| * await backend.hydrate(); | ||
| * | ||
| * const board = orchestrator.getBlackboard('shared', { backend }); | ||
| * ``` | ||
| */ | ||
| export declare class RedisBackend implements BlackboardBackend { | ||
| private cache; | ||
| private client; | ||
| private keyPrefix; | ||
| private _ready; | ||
| constructor(client: RedisClient, options?: RedisBackendOptions); | ||
| /** | ||
| * Read a single entry from the local cache. | ||
| * Returns `null` if not found or TTL has expired. | ||
| */ | ||
| read(key: string): BlackboardEntry | null; | ||
| /** | ||
| * Write a value to the local cache and push to Redis asynchronously. | ||
| * The write is immediately visible to all local reads. | ||
| */ | ||
| write(key: string, value: unknown, sourceAgent: string, ttl?: number): BlackboardEntry; | ||
| /** | ||
| * Delete an entry from the local cache and Redis asynchronously. | ||
| * Returns `true` if the key existed. | ||
| */ | ||
| delete(key: string): boolean; | ||
| /** | ||
| * Return all non-expired keys from the local cache. | ||
| */ | ||
| listKeys(): string[]; | ||
| /** | ||
| * Return a full snapshot of all non-expired entries from the local cache. | ||
| */ | ||
| getSnapshot(): Record<string, BlackboardEntry>; | ||
| /** | ||
| * Load all existing entries from Redis into the local cache. | ||
| * | ||
| * Call this once after construction before your agents start reading, so the | ||
| * local cache reflects any state written by other processes. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const backend = new RedisBackend(client); | ||
| * await backend.hydrate(); | ||
| * ``` | ||
| */ | ||
| hydrate(): Promise<void>; | ||
| /** | ||
| * Flush all local cache entries to Redis in a single pipeline. | ||
| * | ||
| * Useful for ensuring durability before a graceful shutdown, or for | ||
| * synchronising a newly-started process with the latest in-memory state. | ||
| */ | ||
| flush(): Promise<void>; | ||
| /** | ||
| * Clear the local cache. Does NOT delete keys in Redis. | ||
| * Call `hydrate()` afterwards to reload from Redis. | ||
| */ | ||
| clearCache(): void; | ||
| /** | ||
| * `true` after `hydrate()` has completed at least once. | ||
| */ | ||
| get isReady(): boolean; | ||
| /** | ||
| * Number of entries currently in the local cache | ||
| * (including expired entries not yet evicted). | ||
| */ | ||
| get cacheSize(): number; | ||
| private _isExpired; | ||
| private _pushToRedis; | ||
| } | ||
| //# sourceMappingURL=blackboard-backend-redis.d.ts.map |
| {"version":3,"file":"blackboard-backend-redis.d.ts","sourceRoot":"","sources":["../../lib/blackboard-backend-redis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAQ/E;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACpE,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChF,GAAG,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,QAAQ,IAAI,aAAa,CAAC;CAC3B;AAMD,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,YAAa,YAAW,iBAAiB;IACpD,OAAO,CAAC,KAAK,CAA2C;IACxD,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAkB;gBAEpB,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,mBAAmB;IAS9D;;;OAGG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAYzC;;;OAGG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,eAAe;IAkBtF;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAO5B;;OAEG;IACH,QAAQ,IAAI,MAAM,EAAE;IAMpB;;OAEG;IACH,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC;IAc9C;;;;;;;;;;;OAWG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB9B;;;;;OAKG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB5B;;;OAGG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;OAGG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;IAMD,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,YAAY;CASrB"} |
| "use strict"; | ||
| /** | ||
| * Redis Blackboard Backend | ||
| * | ||
| * Provides a `RedisBackend` implementation of `BlackboardBackend` suitable for | ||
| * multi-process and multi-machine agent coordination. Data is shared across all | ||
| * processes that connect to the same Redis server. | ||
| * | ||
| * Architecture — write-through cache: | ||
| * Reads → served from a local in-memory cache (fast, sync) | ||
| * Writes → written to local cache immediately, then flushed to Redis async | ||
| * Hydrate → on startup, loads existing keys from Redis into the local cache | ||
| * | ||
| * This design keeps the synchronous `BlackboardBackend` interface intact while | ||
| * still leveraging Redis for distributed coordination. | ||
| * | ||
| * Peer dependency: | ||
| * Install `ioredis`, `node-redis`, or any Redis client that satisfies the | ||
| * minimal `RedisClient` interface defined below. No production dependency is | ||
| * added to network-ai — Redis is optional and user-supplied. | ||
| * | ||
| * npm install ioredis # recommended | ||
| * # or | ||
| * npm install redis # node-redis v4+ | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import Redis from 'ioredis'; | ||
| * import { RedisBackend } from 'network-ai/lib/blackboard-backend-redis'; | ||
| * | ||
| * const client = new Redis({ host: 'localhost', port: 6379 }); | ||
| * const backend = new RedisBackend(client, { keyPrefix: 'myapp:bb:' }); | ||
| * await backend.hydrate(); // load existing data from Redis | ||
| * | ||
| * const board = orchestrator.getBlackboard('prod', { backend }); | ||
| * ``` | ||
| * | ||
| * @module BlackboardBackendRedis | ||
| * @version 1.0.0 | ||
| * @license MIT | ||
| */ | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.RedisBackend = void 0; | ||
| // ============================================================================ | ||
| // REDIS BACKEND | ||
| // ============================================================================ | ||
| /** | ||
| * Redis-backed `BlackboardBackend` for multi-process / multi-machine | ||
| * agent coordination. | ||
| * | ||
| * Uses a write-through local cache so reads remain synchronous and fast. | ||
| * Call `hydrate()` after construction to load any pre-existing Redis data | ||
| * into the local cache before your agents start reading. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * import Redis from 'ioredis'; | ||
| * import { RedisBackend } from 'network-ai/lib/blackboard-backend-redis'; | ||
| * | ||
| * const client = new Redis(); | ||
| * const backend = new RedisBackend(client, { keyPrefix: 'project-x:bb:' }); | ||
| * await backend.hydrate(); | ||
| * | ||
| * const board = orchestrator.getBlackboard('shared', { backend }); | ||
| * ``` | ||
| */ | ||
| class RedisBackend { | ||
| cache = new Map(); | ||
| client; | ||
| keyPrefix; | ||
| _ready = false; | ||
| constructor(client, options) { | ||
| this.client = client; | ||
| this.keyPrefix = options?.keyPrefix ?? 'network-ai:bb:'; | ||
| } | ||
| // -------------------------------------------------------------------------- | ||
| // BlackboardBackend interface | ||
| // -------------------------------------------------------------------------- | ||
| /** | ||
| * Read a single entry from the local cache. | ||
| * Returns `null` if not found or TTL has expired. | ||
| */ | ||
| read(key) { | ||
| const entry = this.cache.get(key); | ||
| if (!entry) | ||
| return null; | ||
| if (this._isExpired(entry)) { | ||
| this.cache.delete(key); | ||
| // Async eviction from Redis | ||
| this.client.del(this.keyPrefix + key).catch(() => { }); | ||
| return null; | ||
| } | ||
| return entry; | ||
| } | ||
| /** | ||
| * Write a value to the local cache and push to Redis asynchronously. | ||
| * The write is immediately visible to all local reads. | ||
| */ | ||
| write(key, value, sourceAgent, ttl) { | ||
| const existing = this.cache.get(key); | ||
| const version = existing ? existing.version + 1 : 1; | ||
| const entry = { | ||
| key, | ||
| value, | ||
| source_agent: sourceAgent, | ||
| timestamp: new Date().toISOString(), | ||
| ttl: ttl ?? null, | ||
| version, | ||
| }; | ||
| this.cache.set(key, entry); | ||
| this._pushToRedis(key, entry, ttl); | ||
| return entry; | ||
| } | ||
| /** | ||
| * Delete an entry from the local cache and Redis asynchronously. | ||
| * Returns `true` if the key existed. | ||
| */ | ||
| delete(key) { | ||
| const existed = this.cache.has(key); | ||
| this.cache.delete(key); | ||
| this.client.del(this.keyPrefix + key).catch(() => { }); | ||
| return existed; | ||
| } | ||
| /** | ||
| * Return all non-expired keys from the local cache. | ||
| */ | ||
| listKeys() { | ||
| return Array.from(this.cache.entries()) | ||
| .filter(([, entry]) => !this._isExpired(entry)) | ||
| .map(([key]) => key); | ||
| } | ||
| /** | ||
| * Return a full snapshot of all non-expired entries from the local cache. | ||
| */ | ||
| getSnapshot() { | ||
| const result = {}; | ||
| for (const [key, entry] of this.cache.entries()) { | ||
| if (!this._isExpired(entry)) { | ||
| result[key] = entry; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| // -------------------------------------------------------------------------- | ||
| // Extended Redis API | ||
| // -------------------------------------------------------------------------- | ||
| /** | ||
| * Load all existing entries from Redis into the local cache. | ||
| * | ||
| * Call this once after construction before your agents start reading, so the | ||
| * local cache reflects any state written by other processes. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const backend = new RedisBackend(client); | ||
| * await backend.hydrate(); | ||
| * ``` | ||
| */ | ||
| async hydrate() { | ||
| const redisKeys = await this.client.keys(`${this.keyPrefix}*`); | ||
| for (const redisKey of redisKeys) { | ||
| const raw = await this.client.get(redisKey); | ||
| if (raw) { | ||
| try { | ||
| const entry = JSON.parse(raw); | ||
| const localKey = redisKey.slice(this.keyPrefix.length); | ||
| if (!this._isExpired(entry)) { | ||
| this.cache.set(localKey, entry); | ||
| } | ||
| } | ||
| catch { | ||
| // Skip malformed entries | ||
| } | ||
| } | ||
| } | ||
| this._ready = true; | ||
| } | ||
| /** | ||
| * Flush all local cache entries to Redis in a single pipeline. | ||
| * | ||
| * Useful for ensuring durability before a graceful shutdown, or for | ||
| * synchronising a newly-started process with the latest in-memory state. | ||
| */ | ||
| async flush() { | ||
| const pipeline = this.client.pipeline(); | ||
| for (const [key, entry] of this.cache.entries()) { | ||
| if (this._isExpired(entry)) | ||
| continue; | ||
| const redisKey = this.keyPrefix + key; | ||
| const raw = JSON.stringify(entry); | ||
| if (entry.ttl) { | ||
| // Calculate remaining TTL in seconds | ||
| const elapsed = (Date.now() - new Date(entry.timestamp).getTime()) / 1000; | ||
| const remaining = Math.max(1, Math.ceil(entry.ttl - elapsed)); | ||
| pipeline.set(redisKey, raw, 'EX', remaining); | ||
| } | ||
| else { | ||
| pipeline.set(redisKey, raw); | ||
| } | ||
| } | ||
| await pipeline.exec(); | ||
| } | ||
| /** | ||
| * Clear the local cache. Does NOT delete keys in Redis. | ||
| * Call `hydrate()` afterwards to reload from Redis. | ||
| */ | ||
| clearCache() { | ||
| this.cache.clear(); | ||
| this._ready = false; | ||
| } | ||
| /** | ||
| * `true` after `hydrate()` has completed at least once. | ||
| */ | ||
| get isReady() { | ||
| return this._ready; | ||
| } | ||
| /** | ||
| * Number of entries currently in the local cache | ||
| * (including expired entries not yet evicted). | ||
| */ | ||
| get cacheSize() { | ||
| return this.cache.size; | ||
| } | ||
| // -------------------------------------------------------------------------- | ||
| // Private helpers | ||
| // -------------------------------------------------------------------------- | ||
| _isExpired(entry) { | ||
| if (!entry.ttl) | ||
| return false; | ||
| return Date.now() > new Date(entry.timestamp).getTime() + entry.ttl * 1000; | ||
| } | ||
| _pushToRedis(key, entry, ttl) { | ||
| const redisKey = this.keyPrefix + key; | ||
| const raw = JSON.stringify(entry); | ||
| if (ttl) { | ||
| this.client.set(redisKey, raw, 'EX', ttl).catch(() => { }); | ||
| } | ||
| else { | ||
| this.client.set(redisKey, raw).catch(() => { }); | ||
| } | ||
| } | ||
| } | ||
| exports.RedisBackend = RedisBackend; | ||
| //# sourceMappingURL=blackboard-backend-redis.js.map |
| {"version":3,"file":"blackboard-backend-redis.js","sourceRoot":"","sources":["../../lib/blackboard-backend-redis.ts"],"names":[],"mappings":"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"} |
+2
-0
@@ -675,2 +675,4 @@ /** | ||
| export type { BlackboardBackend } from './lib/blackboard-backend'; | ||
| export { RedisBackend } from './lib/blackboard-backend-redis'; | ||
| export type { RedisClient, RedisPipeline, RedisBackendOptions } from './lib/blackboard-backend-redis'; | ||
| export { Logger, LogLevel } from './lib/logger'; | ||
@@ -677,0 +679,0 @@ export type { LogEntry, LogTransport, LoggerConfig } from './lib/logger'; |
+5
-4
| { | ||
| "name": "network-ai", | ||
| "version": "3.5.1", | ||
| "version": "3.6.0", | ||
| "description": "AI agent orchestration framework for TypeScript/Node.js - plug-and-play multi-agent coordination with 12 frameworks (LangChain, AutoGen, CrewAI, OpenAI Assistants, LlamaIndex, Semantic Kernel, Haystack, DSPy, Agno, MCP, OpenClaw). Built-in security, swarm intelligence, and agentic workflow patterns.", | ||
@@ -19,3 +19,4 @@ "main": "dist/index.js", | ||
| "test:phase5b": "npx ts-node test-phase5b.ts", | ||
| "test:all": "npx ts-node test-standalone.ts && npx ts-node test-security.ts && npx ts-node test-adapters.ts && npx ts-node test-priority.ts && npx ts-node test-phase4.ts && npx ts-node test-phase5.ts && npx ts-node test-phase5b.ts", | ||
| "test:phase5c": "npx ts-node test-phase5c.ts", | ||
| "test:all": "npx ts-node test-standalone.ts && npx ts-node test-security.ts && npx ts-node test-adapters.ts && npx ts-node test-priority.ts && npx ts-node test-phase4.ts && npx ts-node test-phase5.ts && npx ts-node test-phase5b.ts && npx ts-node test-phase5c.ts", | ||
| "setup": "npx ts-node setup.ts", | ||
@@ -76,4 +77,4 @@ "setup:check": "npx ts-node setup.ts --check", | ||
| "devDependencies": { | ||
| "@types/node": "^25.2.3", | ||
| "openai": "^6.22.0", | ||
| "@types/node": "^25.3.0", | ||
| "openai": "^6.23.0", | ||
| "ts-node": "^10.9.2", | ||
@@ -80,0 +81,0 @@ "typescript": "^5.9.3" |
+2
-2
@@ -7,3 +7,3 @@ # Network-AI: Multi-Agent Orchestration Framework | ||
| [](https://github.com/jovanSAPFIONEER/Network-AI/actions/workflows/codeql.yml) | ||
| [](https://github.com/jovanSAPFIONEER/Network-AI/releases) | ||
| [](https://github.com/jovanSAPFIONEER/Network-AI/releases) | ||
| [](https://www.npmjs.com/package/network-ai) | ||
@@ -17,3 +17,3 @@ [](https://clawhub.ai/skills/network-ai) | ||
| [](https://agentskills.io) | ||
| [](#testing) | ||
| [](#testing) | ||
| [](#adapter-system) | ||
@@ -20,0 +20,0 @@ [](https://github.com/jovanSAPFIONEER/Network-AI/releases.atom) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 3 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
992833
2.19%124
3.33%15494
2.7%27
17.39%