add-provider — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited add-provider (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Providers implement interfaces defined in core. They are selected at runtime via config (e.g., STORAGE_PROVIDER_TYPE). Tier 3 providers lazy-load their dependencies to keep the core bundle small.
Providers live inside the package source tree — import the interface via relative path (e.g., import type { IStorageProvider } from '../core/IStorageProvider.js'), not via the package subpath exports (those are for consumers).
| Domain | Interface file |
|---|---|
| Storage | src/storage/core/IStorageProvider.ts |
| LLM | src/services/llm/core/ILlmProvider.ts |
| Speech | src/services/speech/core/ISpeechProvider.ts |
Read the relevant interface fully before implementing — each has distinct required members. ISpeechProvider in particular requires readonly name, readonly supportsTTS, readonly supportsSTT, and healthCheck() in addition to the capability methods; these flags drive routing in SpeechService.
Provider file location and naming differ by domain:
Each provider gets its own subdirectory for the provider file plus any co-located types: src/storage/providers/{{providerName}}/{{providerName}}Provider.ts (e.g., src/storage/providers/inMemory/inMemoryProvider.ts, src/storage/providers/supabase/supabaseProvider.ts + supabase.types.ts)
.provider.ts suffix:src/services/llm/providers/{{provider-name}}.provider.ts src/services/speech/providers/{{provider-name}}.provider.ts (e.g., src/services/llm/providers/openrouter.provider.ts, src/services/speech/providers/elevenlabs.provider.ts)
(see table above).
let _client: SomeClient | undefined;
async function getClient(): Promise<SomeClient> {
if (!_client) {
const { SomeClient } = await import('some-package');
_client = new SomeClient(/* config */);
}
return _client;
}z.enum for STORAGE_PROVIDER_TYPE insrc/config/index.ts — without this, the config schema rejects the env var at runtime.
case to the switch in src/storage/core/storageFactory.tsinside createStorageProvider(). Import the new provider class at the top of that file.
provider union inSpeechProviderConfig (src/services/speech/types.ts, field provider).
case to the switch in createSpeechProvider()(src/services/speech/core/SpeechService.ts). Import the new provider class at the top of that file.
OpenRouterProvider); it isinstantiated directly in src/core/app.ts rather than through a factory switch. There is no factory pattern yet — adding a second provider requires introducing one (a selector env var, a factory function, and a conditional in app.ts). Read src/core/app.ts to understand the current instantiation site before designing the wiring.
Cloudflare Workers. The list is an inline array in storageFactory.ts at the isServerless() guard:
// src/storage/core/storageFactory.ts ~line 112
!['in-memory', 'cloudflare-r2', 'cloudflare-kv', 'cloudflare-d1'].includes(providerType)Add the new provider string to this array. Non-storage providers have no equivalent gate.
peerDependencies andpeerDependenciesMeta (with { "optional": true }) in package.json. Without the peerDependenciesMeta entry, the dep appears required rather than optional.
@fileoverview + @module headername, supportsTTS/supportsSTT for speech)z.enum in src/config/index.tsstorageFactory.ts updated if applicableprovider literal added to SpeechProviderConfig union in types.tssrc/core/app.ts instantiation logic updated if adding a second LLM providerpeerDependencies and peerDependenciesMeta in package.json if Tier 3bun run rebuild succeedsbun run devcheck passessrc/storage/providers/{{name}}/{{name}}Provider.test.ts (or equivalent path for the domain) and bun run test passes~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.