@gpzhang2001/sharpkit-skills 0.2.1
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/LICENSE +201 -0
- package/README.md +12 -0
- package/THIRD_PARTY_NOTICES.md +48 -0
- package/lib/index.d.ts +2027 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +70 -0
- package/lib/index.js.map +1 -0
- package/package.json +46 -0
- package/skills/analysis/counterevidence.md +185 -0
- package/skills/analysis/fix_verification.md +129 -0
- package/skills/analysis/severity_calibration.md +130 -0
- package/skills/analysis/source_aware_discovery.md +211 -0
- package/skills/cloud/aws.md +231 -0
- package/skills/cloud/azure.md +262 -0
- package/skills/cloud/gcp.md +194 -0
- package/skills/cloud/kubernetes.md +223 -0
- package/skills/coordination/root_agent.md +105 -0
- package/skills/coordination/source_aware_whitebox.md +47 -0
- package/skills/custom/api_spec_testing.md +61 -0
- package/skills/custom/dependency_cve_scanning.md +341 -0
- package/skills/custom/npx_confusion.md +233 -0
- package/skills/custom/source_aware_sast.md +192 -0
- package/skills/frameworks/django.md +214 -0
- package/skills/frameworks/fastapi.md +191 -0
- package/skills/frameworks/nestjs.md +225 -0
- package/skills/frameworks/nextjs.md +228 -0
- package/skills/protocols/graphql.md +276 -0
- package/skills/protocols/oauth.md +185 -0
- package/skills/reconnaissance/asset_discovery.md +150 -0
- package/skills/reconnaissance/infrastructure_lifecycle.md +226 -0
- package/skills/scan_modes/deep.md +164 -0
- package/skills/scan_modes/diff.md +86 -0
- package/skills/scan_modes/quick.md +68 -0
- package/skills/scan_modes/standard.md +99 -0
- package/skills/technologies/active_directory.md +233 -0
- package/skills/technologies/auth0.md +188 -0
- package/skills/technologies/electron_desktop_apps.md +181 -0
- package/skills/technologies/firebase.md +263 -0
- package/skills/technologies/grafana_prometheus.md +189 -0
- package/skills/technologies/llm_applications.md +257 -0
- package/skills/technologies/supabase.md +268 -0
- package/skills/tooling/agent_browser.md +551 -0
- package/skills/tooling/ffuf.md +72 -0
- package/skills/tooling/httpx.md +82 -0
- package/skills/tooling/hurl.md +99 -0
- package/skills/tooling/hypothesis.md +100 -0
- package/skills/tooling/katana.md +102 -0
- package/skills/tooling/naabu.md +68 -0
- package/skills/tooling/nmap.md +66 -0
- package/skills/tooling/nuclei.md +67 -0
- package/skills/tooling/python.md +109 -0
- package/skills/tooling/semgrep.md +72 -0
- package/skills/tooling/sqlmap.md +67 -0
- package/skills/tooling/subfinder.md +66 -0
- package/skills/vulnerabilities/agentic_system_security.md +207 -0
- package/skills/vulnerabilities/argument_injection.md +157 -0
- package/skills/vulnerabilities/authentication_jwt.md +166 -0
- package/skills/vulnerabilities/broken_function_level_authorization.md +154 -0
- package/skills/vulnerabilities/browser_security.md +192 -0
- package/skills/vulnerabilities/business_logic.md +178 -0
- package/skills/vulnerabilities/csrf.md +198 -0
- package/skills/vulnerabilities/header_injection.md +216 -0
- package/skills/vulnerabilities/http_request_smuggling.md +255 -0
- package/skills/vulnerabilities/idor.md +217 -0
- package/skills/vulnerabilities/information_disclosure.md +187 -0
- package/skills/vulnerabilities/insecure_deserialization.md +210 -0
- package/skills/vulnerabilities/insecure_file_uploads.md +194 -0
- package/skills/vulnerabilities/llm_prompt_injection.md +187 -0
- package/skills/vulnerabilities/mass_assignment.md +153 -0
- package/skills/vulnerabilities/nosql_injection.md +288 -0
- package/skills/vulnerabilities/open_redirect.md +165 -0
- package/skills/vulnerabilities/path_traversal_lfi_rfi.md +218 -0
- package/skills/vulnerabilities/prototype_pollution.md +142 -0
- package/skills/vulnerabilities/race_conditions.md +181 -0
- package/skills/vulnerabilities/rce.md +250 -0
- package/skills/vulnerabilities/semantic_confusion.md +189 -0
- package/skills/vulnerabilities/sql_injection.md +190 -0
- package/skills/vulnerabilities/ssrf.md +186 -0
- package/skills/vulnerabilities/ssti.md +270 -0
- package/skills/vulnerabilities/subdomain_takeover.md +167 -0
- package/skills/vulnerabilities/weak_password_detection.md +200 -0
- package/skills/vulnerabilities/xss.md +206 -0
- package/skills/vulnerabilities/xxe.md +223 -0
- package/src/index.ts +89 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.ts","names":["_0","_0","_$__fiber_ts0.Disposable","_0","_0","_$__fiber_ts0.Disposable","Schema"],"sources":["../../../node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.3/node_modules/@deepseek-ai/cosmokit/lib/types/misc.d.ts","../../../node_modules/.pnpm/@standard-schema+spec@1.1.0/node_modules/@standard-schema/spec/dist/index.d.ts","../../../node_modules/.pnpm/@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/cordis/lib/types/utils.d.ts","../../../node_modules/.pnpm/@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/cordis/lib/types/registry.d.ts","../../../node_modules/.pnpm/@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/cordis/lib/types/reflect.d.ts","../../../node_modules/.pnpm/@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/cordis/lib/types/fiber.d.ts","../../../node_modules/.pnpm/@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/cordis/lib/types/events.d.ts","../../../node_modules/.pnpm/@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/cordis/lib/types/logger.d.ts","../../../node_modules/.pnpm/@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/cordis/lib/types/context.d.ts","../../../node_modules/.pnpm/@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/cordis/lib/types/service.d.ts","../src/index.d.ts"],"sourcesContent":["/** String/symbol keyed dictionary type. */\nexport type Dict<T = any, K extends string | symbol = string> = {\n [key in K]: T;\n};\n/** Safely read `T[K]`, returning `never` when `K` is not a key of `T`. */\nexport type Get<T extends {}, K> = K extends keyof T ? T[K] : never;\n/** Conditional extraction helper with a configurable return type. */\nexport type Extract<S, T, U = S> = S extends T ? U : never;\n/** Accept a value or an array, unless the value is already an array type. */\nexport type MaybeArray<T> = [T] extends [unknown[]] ? T : T | T[];\n/** Wrap a value in `Promise`, preserving the resolved type of existing promises. */\nexport type Promisify<T> = Promise<T extends Promise<infer S> ? S : T>;\n/** Accept a value or promise unless the value type is already promise-like. */\nexport type Awaitable<T> = [T] extends [Promise<unknown>] ? T : T | Promise<T>;\n/** Convert a union type to an intersection type. */\nexport type Intersect<U> = (U extends any ? (arg: U) => void : never) extends ((arg: infer I) => void) ? I : never;\n/** No-op callback returning `undefined` at runtime and `any` at type level. */\nexport declare function noop(): any;\n/** Return true when a value is `null` or `undefined`. */\nexport declare function isNullable(value: any): value is null | undefined | void;\n/** Return true when a value is neither `null` nor `undefined`. */\nexport declare function isNonNullable<T>(value: T): value is NonNullable<T>;\n/** Return true for non-array object values. */\nexport declare function isPlainObject(data: any): any;\n/** Filter object entries with a key type guard. */\nexport declare function filterKeys<T, K extends string, U extends K>(object: Dict<T, K>, filter: (key: K, value: T) => key is U): Dict<T, U>;\n/** Filter object entries with a boolean predicate. */\nexport declare function filterKeys<T, K extends string>(object: Dict<T, K>, filter: (key: K, value: T) => boolean): Dict<T, K>;\n/** Map object values while preserving the original key set. */\nexport declare function mapValues<U, T, K extends string>(object: Dict<T, K>, transform: (value: T, key: K) => U): Dict<U, K>;\n/** Alias for `mapValues`. */\nexport { mapValues as valueMap };\n/** Pick selected keys from an object, optionally including `undefined` values. */\nexport declare function pick<T extends object, K extends keyof T>(source: T, keys?: Iterable<K>, forced?: boolean): Pick<T, K>;\n/** Omit selected keys from a shallow object copy. */\nexport declare function omit<T, K extends keyof T>(source: T, keys?: Iterable<K>): Omit<T, K>;\n/** Define a non-enumerable writable property with a typed key. */\nexport declare function defineProperty<T, K extends keyof T>(object: T, key: K, value: T[K]): T;\n/** Define a non-enumerable writable property with an arbitrary key. */\nexport declare function defineProperty<T, K extends keyof any>(object: T, key: K, value: any): T;\n//# sourceMappingURL=misc.d.ts.map","/** The Standard Typed interface. This is a base type extended by other specs. */\ninterface StandardTypedV1<Input = unknown, Output = Input> {\n /** The Standard properties. */\n readonly \"~standard\": StandardTypedV1.Props<Input, Output>;\n}\ndeclare namespace StandardTypedV1 {\n /** The Standard Typed properties interface. */\n interface Props<Input = unknown, Output = Input> {\n /** The version number of the standard. */\n readonly version: 1;\n /** The vendor name of the schema library. */\n readonly vendor: string;\n /** Inferred types associated with the schema. */\n readonly types?: Types<Input, Output> | undefined;\n }\n /** The Standard Typed types interface. */\n interface Types<Input = unknown, Output = Input> {\n /** The input type of the schema. */\n readonly input: Input;\n /** The output type of the schema. */\n readonly output: Output;\n }\n /** Infers the input type of a Standard Typed. */\n type InferInput<Schema extends StandardTypedV1> = NonNullable<Schema[\"~standard\"][\"types\"]>[\"input\"];\n /** Infers the output type of a Standard Typed. */\n type InferOutput<Schema extends StandardTypedV1> = NonNullable<Schema[\"~standard\"][\"types\"]>[\"output\"];\n}\n/** The Standard Schema interface. */\ninterface StandardSchemaV1<Input = unknown, Output = Input> {\n /** The Standard Schema properties. */\n readonly \"~standard\": StandardSchemaV1.Props<Input, Output>;\n}\ndeclare namespace StandardSchemaV1 {\n /** The Standard Schema properties interface. */\n interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> {\n /** Validates unknown input values. */\n readonly validate: (value: unknown, options?: StandardSchemaV1.Options | undefined) => Result<Output> | Promise<Result<Output>>;\n }\n /** The result interface of the validate function. */\n type Result<Output> = SuccessResult<Output> | FailureResult;\n /** The result interface if validation succeeds. */\n interface SuccessResult<Output> {\n /** The typed output value. */\n readonly value: Output;\n /** A falsy value for `issues` indicates success. */\n readonly issues?: undefined;\n }\n interface Options {\n /** Explicit support for additional vendor-specific parameters, if needed. */\n readonly libraryOptions?: Record<string, unknown> | undefined;\n }\n /** The result interface if validation fails. */\n interface FailureResult {\n /** The issues of failed validation. */\n readonly issues: ReadonlyArray<Issue>;\n }\n /** The issue interface of the failure output. */\n interface Issue {\n /** The error message of the issue. */\n readonly message: string;\n /** The path of the issue, if any. */\n readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;\n }\n /** The path segment interface of the issue. */\n interface PathSegment {\n /** The key representing a path segment. */\n readonly key: PropertyKey;\n }\n /** The Standard types interface. */\n interface Types<Input = unknown, Output = Input> extends StandardTypedV1.Types<Input, Output> {\n }\n /** Infers the input type of a Standard. */\n type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>;\n /** Infers the output type of a Standard. */\n type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;\n}\n/** The Standard JSON Schema interface. */\ninterface StandardJSONSchemaV1<Input = unknown, Output = Input> {\n /** The Standard JSON Schema properties. */\n readonly \"~standard\": StandardJSONSchemaV1.Props<Input, Output>;\n}\ndeclare namespace StandardJSONSchemaV1 {\n /** The Standard JSON Schema properties interface. */\n interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> {\n /** Methods for generating the input/output JSON Schema. */\n readonly jsonSchema: StandardJSONSchemaV1.Converter;\n }\n /** The Standard JSON Schema converter interface. */\n interface Converter {\n /** Converts the input type to JSON Schema. May throw if conversion is not supported. */\n readonly input: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>;\n /** Converts the output type to JSON Schema. May throw if conversion is not supported. */\n readonly output: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>;\n }\n /**\n * The target version of the generated JSON Schema.\n *\n * It is *strongly recommended* that implementers support `\"draft-2020-12\"` and `\"draft-07\"`, as they are both in wide use. All other targets can be implemented on a best-effort basis. Libraries should throw if they don't support a specified target.\n *\n * The `\"openapi-3.0\"` target is intended as a standardized specifier for OpenAPI 3.0 which is a superset of JSON Schema `\"draft-04\"`.\n */\n type Target = \"draft-2020-12\" | \"draft-07\" | \"openapi-3.0\" | ({} & string);\n /** The options for the input/output methods. */\n interface Options {\n /** Specifies the target version of the generated JSON Schema. Support for all versions is on a best-effort basis. If a given version is not supported, the library should throw. */\n readonly target: Target;\n /** Explicit support for additional vendor-specific parameters, if needed. */\n readonly libraryOptions?: Record<string, unknown> | undefined;\n }\n /** The Standard types interface. */\n interface Types<Input = unknown, Output = Input> extends StandardTypedV1.Types<Input, Output> {\n }\n /** Infers the input type of a Standard. */\n type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>;\n /** Infers the output type of a Standard. */\n type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;\n}\n\nexport { StandardJSONSchemaV1, StandardSchemaV1, StandardTypedV1 };\n","import type { Context, Service } from './index.ts';\n/** Ordered collection of disposable values with O(1) deletion by value. */\nexport declare class DisposableList<T extends WeakKey> {\n private sn;\n private map;\n private weak;\n get length(): number;\n push(value: T): () => boolean;\n delete(value: T): boolean;\n clear(): T[];\n [Symbol.iterator](): MapIterator<T>;\n}\n/** Metadata used by traceable proxies to rebind `ctx` and associated services. */\nexport interface Tracker {\n associate?: string;\n property?: string;\n noShadow?: boolean;\n}\n/** Shared symbols used to avoid public property-name collisions. */\nexport declare const symbols: {\n shadow: symbol;\n receiver: symbol;\n original: symbol;\n metadata: symbol;\n initHooks: symbol;\n checkProto: symbol;\n effect: typeof Context.effect;\n filter: typeof Context.filter;\n isolate: typeof Context.isolate;\n intercept: typeof Context.intercept;\n init: typeof Service.init;\n check: typeof Service.check;\n config: typeof Service.config;\n invoke: typeof Service.invoke;\n extend: typeof Service.extend;\n tracker: typeof Service.tracker;\n resolveConfig: typeof Service.resolveConfig;\n};\n/** Return true when a plugin callback should be constructed with `new`. */\nexport declare function isConstructor(func: any): func is new (...args: any) => any;\n/** Merge two prototype chains while preserving descriptors from `proto1`. */\nexport declare function joinPrototype(proto1: {}, proto2: {}): any;\n/** Return true for non-null objects and functions. */\nexport declare function isObject(value: any): value is {};\n/** Find a property descriptor by walking an object's prototype chain. */\nexport declare function getPropertyDescriptor(target: any, prop: string | symbol): TypedPropertyDescriptor<any> | undefined;\n/** Wrap services/functions so method calls see the caller's active context. */\nexport declare function getTraceable<T>(ctx: Context, value: T): T;\n/** Return a proxy that overlays readonly or writable properties onto a target. */\nexport declare function withProps(target: any, props?: {}): any;\n/** Create a callable service object that dispatches through `symbols.invoke`. */\nexport declare function createCallable(name: string, proto: {}, tracker: Tracker): any;\ninterface StackInfo {\n offset: number;\n error: Error;\n}\n/** Run a callback and splice outer call-site frames into thrown async errors. */\nexport declare function composeError<T>(callback: (info: StackInfo) => T, getOuterStack?: () => string[]): T;\n/** Capture a lazy stack-frame supplier for later error composition. */\nexport declare function buildOuterStack(offset?: number): () => string[];\nexport {};\n//# sourceMappingURL=utils.d.ts.map","import type { Dict } from '@deepseek-ai/cosmokit';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Context } from './context.ts';\nimport { Fiber } from './fiber.ts';\nimport { DisposableList, symbols } from './utils.ts';\n/**\n * Service dependency declaration accepted by plugins and the `@Inject`\n * decorator.\n *\n * Array form requests services without intercept config. Object form maps each\n * service name to optional intercept config for the plugin context.\n */\nexport type Inject<M = Dict> = (keyof M)[] | {\n [K in keyof M]?: M[K];\n};\n/** Context keys that correspond to services with typed intercept config. */\nexport type InjectKey = keyof {\n [K in keyof Context & string as Context[K] extends {\n [symbols.config]: any;\n } ? K : never]: any;\n};\n/**\n * Decorator for declaring service dependencies on classes or class methods.\n *\n * On classes it contributes to the plugin's static `inject` map. On methods it\n * delays the method call until the declared services are available.\n */\n/**\n * @param name — the required service name.\n * @param config — optional intercept config applied for that service.\n * @returns the class or method decorator.\n */\nexport declare function Inject<K extends InjectKey>(name: K, config?: Context[K] extends {\n [symbols.config]: infer T;\n} ? T : never): (value: any, decorator: ClassDecoratorContext<any> | ClassMethodDecoratorContext<any>) => void;\n/** Utilities for normalizing plugin dependency declarations. */\nexport declare namespace Inject {\n /**\n * Convert array/object/class-inherited inject metadata into a plain map.\n *\n * @param inject — the declaration to normalize; `null`/`undefined` add nothing.\n * @param result — the map to fill (service name → intercept config or `null`).\n * @returns `result`.\n */\n function resolve(inject: Inject | null | undefined, result?: Dict): Dict;\n}\n/** Supported plugin entrypoint shapes. */\nexport type Plugin<T = any> = Plugin.Function<T> | Plugin.Constructor<T> | Plugin.Object<T>;\n/** Types associated with plugin entrypoints and runtime records. */\nexport declare namespace Plugin {\n /** Shared metadata understood by the plugin registry and related tooling. */\n interface Base<T = any> {\n /** Display name used for fiber diagnostics and logger names. */\n name?: string;\n /** Standard-schema validator applied to config before the plugin starts. */\n Config?: StandardSchemaV1<any, T>;\n /** Services the plugin requires; it only loads while all are available. */\n inject?: Inject;\n /** Service name(s) the plugin provides (read by `Service` and by loaders). */\n provide?: string | string[];\n /** Service names whose intercept config the plugin declares it consumes. */\n intercept?: Dict<boolean>;\n }\n interface Transform<S, T> {\n /** Marks the transform object as a schema/config transform. */\n schema?: true;\n /** Convert user-facing config to runtime config. */\n Config: (config: S) => T;\n }\n /** Function plugin called with `(ctx, config)`. */\n interface Function<T = any> extends Base<T> {\n (ctx: Context, config: T): any;\n }\n /** Class plugin constructed with `(ctx, config)`. */\n interface Constructor<T = any> extends Base<T> {\n new (ctx: Context, config: T): any;\n }\n /** Object plugin with an `apply(ctx, config)` method. */\n interface Object<T = any> extends Base<T> {\n apply(ctx: Context, config: T): any;\n }\n /** Mutable registry record shared by all fibers of one plugin callback. */\n interface Runtime {\n /** Display name copied from the first registered plugin shape. */\n name?: string;\n /** Every live fiber of this plugin (one per `ctx.plugin()` call). */\n fibers: DisposableList<Fiber>;\n /** The executable entrypoint all fibers share (registry identity key). */\n callback: globalThis.Function;\n /** Standard-schema validator applied to each fiber's config. */\n Config?: StandardSchemaV1;\n }\n}\ntype Spread<T> = undefined extends T ? [config?: T] : [config: T];\ntype GetPluginParameters<P> = P extends (ctx: Context, ...args: infer R) => any ? R : P extends new (ctx: Context, ...args: infer R) => any ? R : P extends {\n apply(ctx: Context, ...args: infer R): any;\n} ? R : never;\ntype GetPluginConfig<P> = P extends Plugin.Transform<infer S, any> ? S : GetPluginParameters<P>[0];\ndeclare module './context.ts' {\n interface Context {\n /**\n * Run a callback once the requested services are available.\n *\n * Shorthand for `ctx.plugin({ inject, apply: callback })`: the callback\n * is unloaded and re-run whenever a required service changes.\n *\n * @param deps — required services, as an array or a name → config map.\n * @param callback — plugin body called with `(ctx, config)`.\n * @returns the fiber; awaiting it settles once loading finished.\n */\n inject(deps: Inject, callback: Plugin.Function<void>): Fiber & PromiseLike<Fiber>;\n /**\n * Load a plugin in the current context.\n *\n * @param plugin — a function, class, or `{ apply }` object plugin.\n * @param args — the plugin config, validated against its `Config` schema.\n * @returns the fiber; awaiting it settles once loading finished\n * (rejecting on config or startup errors).\n */\n plugin<P extends Plugin>(plugin: P, ...args: Spread<GetPluginConfig<P>>): Fiber & PromiseLike<Fiber>;\n }\n}\n/**\n * Plugin registry installed as `ctx.registry` and mixed into every context.\n *\n * It normalizes plugin shapes, tracks plugin runtimes, starts fibers, and\n * exposes map-like inspection over active plugin callbacks.\n */\nexport declare class RegistryService {\n ctx: Context;\n private _counter;\n private _internal;\n constructor(ctx: Context);\n /** Allocate the next fiber uid (increments on every read). */\n get counter(): number;\n /** Number of registered plugin runtimes. */\n get size(): number;\n /**\n * Resolve a supported plugin shape to its executable callback.\n *\n * @param plugin — a function, class, or `{ apply }` object plugin.\n * @returns the callback identifying the plugin, or `undefined` if invalid.\n */\n resolve(plugin: Plugin): Function | undefined;\n /**\n * Look up the runtime record for a plugin.\n *\n * @param plugin — any supported plugin shape.\n * @returns the runtime, or `undefined` when the plugin is not registered.\n */\n get(plugin: Plugin): Plugin.Runtime | undefined;\n /**\n * Check whether a plugin has a registered runtime.\n *\n * @param plugin — any supported plugin shape.\n * @returns `true` when at least one fiber of the plugin exists.\n */\n has(plugin: Plugin): boolean;\n /**\n * Dispose every running fiber for a plugin and remove its runtime record.\n *\n * @param plugin — any supported plugin shape.\n * @returns the removed runtime, or `undefined` when none was registered.\n */\n delete(plugin: Plugin): Plugin.Runtime | undefined;\n /** Iterate the registered plugin callbacks. */\n keys(): MapIterator<Function>;\n /** Iterate the registered plugin runtimes. */\n values(): MapIterator<Plugin.Runtime>;\n /** Iterate `[callback, runtime]` pairs. */\n entries(): MapIterator<[Function, Plugin.Runtime]>;\n /**\n * Visit every registered runtime.\n *\n * @param callback — receives each runtime and its identifying callback.\n */\n forEach(callback: (value: Plugin.Runtime, key: Function) => void): void;\n /**\n * Start a callback once the requested dependencies are available.\n *\n * @param inject — required services, as an array or a name → config map.\n * @param callback — plugin body called with `(ctx, config)`.\n * @returns the fiber; awaiting it settles once loading finished.\n */\n inject(inject: Inject, callback: Plugin.Function<void>): Fiber & PromiseLike<Fiber>;\n /**\n * Start a plugin in the current context and return its fiber.\n *\n * Creates (or reuses) the plugin's runtime record, then starts a new fiber\n * under the current context. Throws if `plugin` is not a supported shape or\n * if the current fiber is already disposed.\n *\n * @param plugin — a function, class, or `{ apply }` object plugin.\n * @param config — the plugin config, validated against its `Config` schema.\n * @param getOuterStack — captures the caller stack for effect diagnostics.\n * @returns the fiber; awaiting it settles once loading finished.\n */\n plugin(plugin: Plugin, config?: any, getOuterStack?: () => string[]): Fiber & PromiseLike<Fiber>;\n}\nexport {};\n//# sourceMappingURL=registry.d.ts.map","import type { Dict } from '@deepseek-ai/cosmokit';\nimport { Context } from './context.ts';\nimport { Fiber } from './fiber.ts';\ndeclare module './context.ts' {\n interface Context {\n /**\n * Read a service from the store without the inject requirement.\n *\n * @param name — the service name.\n * @param strict — when `true` (default), only return implementations\n * whose providing fiber is currently active.\n * @returns the service value, or `undefined` when not (yet) provided.\n */\n get<K extends string & keyof this>(name: K, strict?: boolean): undefined | this[K];\n /** Same as above for service names outside the typed `Context` surface. */\n get(name: string, strict?: boolean): any;\n /**\n * Overwrite a provided service's value.\n *\n * Only the fiber that provided the service may set it; setting an\n * unprovided name throws.\n *\n * @param name — the service name.\n * @param value — the new service value.\n */\n set<K extends string & keyof this>(name: K, value: undefined | this[K]): void;\n /** Same as above for service names outside the typed `Context` surface. */\n set(name: string, value: any): void;\n /**\n * Register a service implementation owned by the current fiber.\n *\n * The service becomes visible to dependents in the same isolation scope\n * once the fiber is active; it is unregistered (waking dependents) when\n * the returned disposer runs or the fiber unloads. Throws if the name is\n * already provided in this scope or declared as an accessor.\n *\n * @param name — the service name.\n * @param value — the service value.\n * @returns a disposer that unregisters the service.\n */\n provide<K extends string & keyof this>(name: K, value: undefined | this[K]): () => void;\n /** Same as above for service names outside the typed `Context` surface. */\n provide(name: string, value?: any): () => void;\n /**\n * Define a computed context property backed by get/set hooks.\n *\n * The accessor is removed when the current fiber unloads. Throws if the\n * name is already declared.\n *\n * @param name — the context property name.\n * @param options — the `get` hook and optional `set` hook.\n */\n accessor(name: string, options: Omit<Property.Accessor, 'type'>): void;\n /**\n * Expose selected members of a service directly on `ctx`.\n *\n * Each mixed-in key becomes an accessor that forwards to the service\n * (binding methods to it), so e.g. `ctx.on` forwards to `ctx.events.on`.\n * Mixins are removed when the current fiber unloads.\n *\n * @param name — the context property holding the source service.\n * @param mixins — keys to forward, or a source-key → ctx-key map.\n */\n mixin<K extends string & keyof this>(name: K, mixins: (keyof this & keyof this[K])[] | Dict<string>): void;\n /** Same as above with a source object instead of a context property name. */\n mixin<T extends {}>(source: T, mixins: (keyof this & keyof T)[] | Dict<string>): void;\n }\n}\n/** Context property definition known by the reflection service. */\nexport type Property = Property.Service | Property.Accessor;\n/** Property definition variants understood by `ReflectService`. */\nexport declare namespace Property {\n /** Service property backed by a provided implementation. */\n interface Service {\n /** Discriminator. */\n type: 'service';\n }\n /** Computed context property backed by custom get/set hooks. */\n interface Accessor {\n /** Discriminator. */\n type: 'accessor';\n /** Compute the property value; `error` carries the caller stack for diagnostics. */\n get: (this: Context, receiver: any, error: Error) => any;\n /** Optional setter; return `false` to reject the write. */\n set?: (this: Context, value: any, receiver: any, error: Error) => boolean;\n }\n}\n/** Concrete service implementation record stored in the root reflect service. */\nexport interface Impl {\n /** The service name. */\n name: string;\n /** The fiber that provided the service (owns its lifetime). */\n fiber: Fiber;\n /** The current service value. */\n value?: any;\n /** Optional availability predicate consulted before dependents may load. */\n check?: () => boolean;\n}\n/**\n * Reflection and service-resolution layer installed as `ctx.reflect`.\n *\n * This service powers the context proxy, service registration, accessors, and\n * the mixins that expose core service methods directly on `ctx`.\n */\nexport declare class ReflectService {\n ctx: Context;\n /** Proxy traps implementing service resolution for every context object. */\n static handler: ProxyHandler<Context>;\n /** Service implementations, keyed by isolation label. */\n store: Dict<Impl, symbol>;\n /** Declared context properties (services and accessors), by name. */\n props: Dict<Property>;\n constructor(ctx: Context);\n /**\n * Read a service from the store without the inject requirement.\n *\n * @param name — the service name.\n * @param strict — when `true`, only return implementations whose providing\n * fiber is currently active.\n * @returns the service value, or `undefined` when not (yet) provided.\n */\n get(name: string, strict?: boolean): any;\n _getImpl(name: string, strict?: boolean): Impl | undefined;\n /**\n * Overwrite a provided service's value.\n *\n * @param name — the service name.\n * @param value — the new service value.\n * @param error — carrier for the caller stack in diagnostics.\n * @returns `true` on success.\n * @throws when `name` was never provided, or was provided by another fiber.\n */\n set(name: string, value: any, error?: Error): boolean;\n /**\n * Register a service implementation owned by the current fiber.\n *\n * See the `ctx.provide()` overload above for the full contract.\n *\n * @param name — the service name.\n * @param value — the service value.\n * @param check — optional availability predicate for dependents.\n * @returns a disposer that unregisters the service.\n */\n provide(name: string, value?: any, check?: () => boolean): import(\"./fiber.ts\").Disposable<Promise<void>>;\n /**\n * Re-evaluate every fiber that requires one of the given services.\n *\n * @param names — the service names that changed.\n * @param filter — restricts notification to matching isolation scopes.\n * @returns the fibers whose dependency state was refreshed.\n */\n notify(names: string[], filter?: (ctx: Context, name: string) => boolean): Fiber[];\n /**\n * Define a computed context property backed by get/set hooks.\n *\n * @param name — the context property name.\n * @param options — the `get` hook and optional `set` hook.\n * @returns a disposer that removes the accessor.\n */\n accessor(name: string, options: Omit<Property.Accessor, 'type'>): import(\"./fiber.ts\").Disposable<Promise<void>>;\n /**\n * Expose selected members of a service directly on `ctx`.\n *\n * See the `ctx.mixin()` overload above for the full contract.\n *\n * @param source — a context property name or a source object.\n * @param mixins — keys to forward, or a source-key → ctx-key map.\n * @returns a disposer that removes all created accessors.\n */\n mixin(source: any, mixins: string[] | Dict<string>): import(\"./fiber.ts\").Disposable<Promise<void>>;\n /**\n * Attach this context's tracing wrapper to a value.\n *\n * @param value — the value to wrap.\n * @returns the traceable wrapper (or the value itself when not applicable).\n */\n trace<T>(value: T): T;\n /**\n * Wrap a callback so calls trace `this` and arguments to this context.\n *\n * @param callback — the function to wrap.\n * @returns a proxy delegating to `callback` with traced values.\n */\n bind<T extends Function>(callback: T): T;\n}\n//# sourceMappingURL=reflect.d.ts.map","import type { Awaitable, Dict } from '@deepseek-ai/cosmokit';\nimport { Context } from './context.ts';\nimport type { Plugin } from './registry.ts';\nimport { DisposableList } from './utils.ts';\nimport type { Impl } from './reflect.ts';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\ndeclare module './context.ts' {\n interface Context extends Pick<Fiber, 'effect'> {\n /** The fiber (plugin runtime instance) that owns this context. */\n fiber: Fiber;\n }\n}\n/** Error raised when plugin configuration fails standard-schema validation. */\nexport declare class ValidationError extends TypeError {\n name: string;\n /**\n * Build the aggregated message from schema issues.\n *\n * @param issues — the standard-schema issues, one message line each.\n */\n constructor(issues: readonly StandardSchemaV1.Issue[]);\n}\n/**\n * Validate and normalize config for a plugin runtime before it starts.\n *\n * @param runtime — the plugin runtime whose `Config` schema to apply.\n * @param config — the raw user config.\n * @returns the validated config, or `config` unchanged if the runtime has no schema.\n * @throws {ValidationError} when validation reports issues.\n */\nexport declare function resolveConfig(runtime: Plugin.Runtime, config: any): any;\ninterface AsyncDisposable<T extends Awaitable<void> = Awaitable<void>> extends PromiseLike<() => T> {\n (): T;\n}\n/**\n * Function returned by an effect to release resources during disposal.\n *\n * Disposers run in reverse registration order when the owning fiber unloads;\n * they may be async, in which case unloading awaits them.\n */\nexport type Disposable<T = any> = () => T;\n/**\n * Effect body result accepted by `ctx.effect()` and plugin startup.\n *\n * Either a single disposer, a promise of one, or a (possibly async) iterable\n * yielding several — generator effects register each yielded disposer as it\n * is produced.\n */\nexport type Effect<T = any> = SyncEffect<T> | AsyncEffect<T>;\ntype SyncEffect<T = any> = Disposable<T> | Iterable<Disposable<T>, void, void>;\ntype AsyncEffect<T = any> = Promise<Disposable<T>> | AsyncIterable<Disposable<T>, void, void>;\n/** Tree node used to expose nested effect labels for diagnostics. */\nexport interface EffectMeta {\n /** Human-readable effect label, e.g. `ctx.on(\"event\")` or `ctx.provide(\"name\")`. */\n label: string;\n /** Metadata of nested effects registered while this effect ran. */\n children: EffectMeta[];\n}\n/**\n * Lifecycle state for one plugin fiber.\n *\n * `PENDING` — waiting for required services; `LOADING` — the plugin callback\n * is running; `ACTIVE` — loaded and providing; `FAILED` — the callback or its\n * config threw; `UNLOADING` — disposers are running; `DISPOSED` — the fiber\n * was removed and cannot restart.\n */\nexport declare const enum FiberState {\n PENDING = 0,\n LOADING = 1,\n ACTIVE = 2,\n FAILED = 3,\n DISPOSED = 4,\n UNLOADING = 5\n}\n/** Framework error with a stable machine-readable code. */\nexport declare class CordisError extends Error {\n code: CordisError.Code;\n /**\n * @param code — the stable error code; also the default message.\n * @param message — optional human-readable override.\n */\n constructor(code: CordisError.Code, message?: string);\n}\n/** Cordis error code definitions. */\nexport declare namespace CordisError {\n type Code = keyof typeof Code;\n const Code: {\n readonly INACTIVE_EFFECT: \"cannot create effect on inactive context\";\n };\n}\n/**\n * Runtime instance of one plugin application.\n *\n * A fiber tracks dependency state, validated config, lifecycle effects, and\n * cleanup for the plugin context returned by `ctx.plugin()`.\n */\nexport declare class Fiber {\n parent: Context;\n inject: Dict<any>;\n runtime: Plugin.Runtime | null;\n /** Unique id within the registry; 0 for the root fiber, `null` once disposed. */\n uid: number | null;\n /** The context this fiber's plugin runs in (extends the parent context). */\n readonly ctx: Context;\n /** The validated plugin config (updated by `update()`). */\n config: any;\n /** The raw plugin config, re-resolved before each activation. */\n _config: any;\n /** Current lifecycle state; transitions emit `internal/status`. */\n state: FiberState;\n /** Dispose this fiber: unload the plugin, then settle once cleanup finished. */\n readonly dispose: () => Promise<void>;\n /** Snapshot of required service implementations while loaded; `undefined` otherwise. */\n store: Dict<Impl> | undefined;\n /** The in-flight load/unload transition, if one is currently running. */\n inertia: Promise<void> | undefined;\n readonly _hooks: Dict<DisposableList<Function>>;\n readonly _disposables: DisposableList<Disposable<any>>;\n protected context: Context;\n private _error;\n private _runner;\n private _store;\n /**\n * Create a fiber. Plugin authors normally obtain fibers from `ctx.plugin()`\n * rather than constructing them directly.\n *\n * @param parent — the context the plugin was loaded from.\n * @param config — raw config, validated against the runtime's schema.\n * @param inject — resolved dependency map (service name → intercept config).\n * @param runtime — the shared plugin runtime, or `null` for the root fiber.\n * @param getOuterStack — captures the caller stack for effect diagnostics.\n */\n constructor(parent: Context, config: any, inject: Dict<any>, runtime: Plugin.Runtime | null, getOuterStack: () => string[]);\n /** The plugin's display name, inherited from the nearest named ancestor, else `'root'`. */\n get name(): string;\n /**\n * Throw if the fiber has already been disposed.\n *\n * @returns nothing when the fiber is still active.\n * @throws {CordisError} `INACTIVE_EFFECT` when the fiber's uid has been cleared.\n */\n assertActive(): void;\n private _execute;\n /**\n * Register a cleanup-aware effect on this fiber.\n *\n * `execute` runs immediately; the disposers it produces are collected and\n * run (in reverse order) either when the returned disposer is called or\n * when the fiber unloads, whichever comes first. Calling the disposer twice\n * is a no-op. Throws `CordisError('INACTIVE_EFFECT')` if the fiber is\n * already disposed, and `TypeError` if `execute` returns an invalid shape.\n *\n * @param execute — the effect body; see {@link Effect} for accepted shapes.\n * @param label — effect label shown in `getEffects()` diagnostics.\n * @returns a disposer that tears the effect down and settles once done.\n */\n effect(execute: () => SyncEffect, label?: string): Disposable<Promise<void>>;\n /** Same as above for async effects; the disposer is also awaitable. */\n effect(execute: () => Effect, label?: string): AsyncDisposable<Promise<void>>;\n /**\n * Return metadata for currently registered effects.\n *\n * @returns one {@link EffectMeta} tree per labeled live effect.\n */\n getEffects(): EffectMeta[];\n private _getState;\n private _updateState;\n _checkImpl(name: string): boolean | undefined;\n _refresh(): void;\n private _setEpoch;\n private _resolveConfig;\n private _reload;\n private _unload;\n /**\n * Wait for current lifecycle work and rethrow startup errors.\n *\n * @returns this fiber, once it has settled into a stable state.\n * @throws the config-validation or plugin-startup error, if any.\n */\n await(): Promise<this>;\n /**\n * Dispose and immediately reload this plugin with its current config.\n *\n * @returns a promise resolving once the reload settled.\n * @throws {CordisError} `INACTIVE_EFFECT` when the fiber is already disposed.\n */\n restart(): Promise<void>;\n /**\n * Validate and apply new config, then restart the plugin.\n *\n * Runs the `internal/update` waterfall first, so update hooks (and HMR)\n * can veto or replace the restart.\n *\n * @param config — the new raw config; validated before anything restarts.\n * @param noSave — hint for persistence hooks not to write the change back.\n * @returns the update waterfall result; the default restart returns a promise.\n * @throws when validation, an update listener, or the restarted plugin fails.\n */\n update(config: any, noSave?: boolean): void | Promise<void>;\n}\nexport {};\n//# sourceMappingURL=fiber.d.ts.map","import type { Promisify } from '@deepseek-ai/cosmokit';\nimport { Context } from './context.ts';\nimport { Fiber, FiberState } from './fiber.ts';\n/**\n * Return whether an event result should stop a bail-style dispatch.\n *\n * @param value — a listener's return value.\n * @returns `true` unless `value` is `null`, `false`, or `undefined`.\n */\nexport declare function isBailed(value: any): boolean;\n/** Extract the parameter tuple from a function type. */\nexport type Parameters<F> = F extends (...args: infer P) => any ? P : never;\n/** Extract the return type from a function type. */\nexport type ReturnType<F> = F extends (...args: any) => infer R ? R : never;\n/** Extract the explicit `this` type from a function type. */\nexport type ThisType<F> = F extends (this: infer T, ...args: any) => any ? T : never;\n/**\n * Event dispatch strategy used by the event service.\n *\n * `emit` runs synchronous listeners without awaiting them, `parallel` awaits\n * all listeners together, `serial` awaits them in order until one bails,\n * `bail` stops on the first synchronous bail value, and `waterfall` composes\n * listeners around a final `next` callback.\n */\nexport type DispatchMode = 'emit' | 'parallel' | 'serial' | 'bail' | 'waterfall';\ndeclare module './context.ts' {\n interface Context {\n /**\n * Dispatch an event, running all listeners concurrently.\n *\n * @param name — the event name.\n * @param args — arguments passed to every listener.\n * @returns a promise resolving once every listener has settled.\n */\n parallel<K extends keyof Events>(name: K, ...args: Parameters<Events[K]>): Promise<void>;\n /** Same as above, with an explicit `this` for listeners (also used for filtering). */\n parallel<K extends keyof Events>(thisArg: NoInfer<ThisType<Events[K]>>, name: K, ...args: Parameters<Events[K]>): Promise<void>;\n /**\n * Dispatch an event synchronously, ignoring listener return values.\n *\n * @param name — the event name.\n * @param args — arguments passed to every listener.\n */\n emit<K extends keyof Events>(name: K, ...args: Parameters<Events[K]>): void;\n /** Same as above, with an explicit `this` for listeners (also used for filtering). */\n emit<K extends keyof Events>(thisArg: NoInfer<ThisType<Events[K]>>, name: K, ...args: Parameters<Events[K]>): void;\n /**\n * Dispatch an event, awaiting listeners in order until one bails.\n *\n * @param name — the event name.\n * @param args — arguments passed to each listener.\n * @returns the first bail value (non-null, non-false, non-undefined), if any.\n */\n serial<K extends keyof Events>(name: K, ...args: Parameters<Events[K]>): Promisify<ReturnType<Events[K]>>;\n /** Same as above, with an explicit `this` for listeners (also used for filtering). */\n serial<K extends keyof Events>(thisArg: NoInfer<ThisType<Events[K]>>, name: K, ...args: Parameters<Events[K]>): Promisify<ReturnType<Events[K]>>;\n /**\n * Dispatch an event, calling listeners in order until one bails.\n *\n * @param name — the event name.\n * @param args — arguments passed to each listener.\n * @returns the first bail value (non-null, non-false, non-undefined), if any.\n */\n bail<K extends keyof Events>(name: K, ...args: Parameters<Events[K]>): ReturnType<Events[K]>;\n /** Same as above, with an explicit `this` for listeners (also used for filtering). */\n bail<K extends keyof Events>(thisArg: NoInfer<ThisType<Events[K]>>, name: K, ...args: Parameters<Events[K]>): ReturnType<Events[K]>;\n /**\n * Dispatch an event whose last argument is a `next` continuation.\n *\n * Each listener wraps the rest of the chain: calling `next()` invokes the\n * next listener (finally the built-in behavior); not calling it vetoes.\n *\n * @param name — the event name.\n * @param args — listener arguments; the final one is the innermost `next`.\n * @returns the outermost listener's return value.\n */\n waterfall<K extends keyof Events>(name: K, ...args: Parameters<Events[K]>): ReturnType<Events[K]>;\n /** Same as above, with an explicit `this` for listeners (also used for filtering). */\n waterfall<K extends keyof Events>(thisArg: NoInfer<ThisType<Events[K]>>, name: K, ...args: Parameters<Events[K]>): ReturnType<Events[K]>;\n /**\n * Register an event listener owned by the current fiber.\n *\n * @param name — the event name to listen for.\n * @param listener — called with the dispatch arguments.\n * @param options — listener options; a boolean is shorthand for `prepend`.\n * @returns a disposer removing the listener; `true` if it was still registered.\n */\n on<K extends keyof Events>(name: K, listener: Events[K], options?: boolean | EventOptions): () => boolean;\n /**\n * Same as `on()`, but the listener disposes itself after its first call.\n *\n * @param name — the event name to listen for.\n * @param listener — called at most once with the dispatch arguments.\n * @param options — listener options; a boolean is shorthand for `prepend`.\n * @returns a disposer removing the listener; `true` if it was still registered.\n */\n once<K extends keyof Events>(name: K, listener: Events[K], options?: boolean | EventOptions): () => boolean;\n }\n}\n/** Options accepted by `ctx.on()` and `ctx.once()`. */\nexport interface EventOptions {\n /** Add the listener before existing listeners for the same event. */\n prepend?: boolean;\n /** Receive the event regardless of context filter checks. */\n global?: boolean;\n}\n/** Registered listener record stored by the event service. */\nexport interface Hook extends EventOptions {\n ctx: Context;\n callback: (...args: any[]) => any;\n}\n/**\n * Event bus installed as `ctx.events` and mixed into every context.\n *\n * The service supports concurrent, synchronous, serial, bail, and waterfall\n * dispatch and automatically disposes listeners with their owning fiber.\n */\nexport declare class EventsService {\n private ctx;\n _hooks: Record<keyof any, Hook[]>;\n constructor(ctx: Context);\n /**\n * Resolve listeners for one dispatch and apply context filtering.\n *\n * @param type — the dispatch mode, reported on `internal/dispatch`.\n * @param args — the raw dispatch arguments; consumed up to the event name.\n * @returns the matching listener callbacks, bound to the dispatch `this`.\n */\n dispatch(type: string, args: any[]): ((...args: any[]) => any)[];\n /**\n * Run listeners concurrently and wait for all of them.\n *\n * @param args — optional `this`, the event name, then listener arguments.\n * @returns a promise resolving once every listener has settled.\n */\n parallel(...args: any[]): Promise<void>;\n /**\n * Run listeners synchronously without waiting for returned promises.\n *\n * @param args — optional `this`, the event name, then listener arguments.\n */\n emit(...args: any[]): void;\n /**\n * Run listeners in order, awaiting each, until one returns a bail value.\n *\n * @param args — optional `this`, the event name, then listener arguments.\n * @returns the first bail value (see {@link isBailed}), if any.\n */\n serial(...args: any[]): Promise<any>;\n /**\n * Run listeners synchronously until one returns a bail value.\n *\n * @param args — optional `this`, the event name, then listener arguments.\n * @returns the first bail value (see {@link isBailed}), if any.\n */\n bail(...args: any[]): any;\n /**\n * Compose listeners around the final `next` callback.\n *\n * The last dispatch argument is treated as the innermost `next`. Listeners\n * run outermost-first; a listener that does not call `next()` vetoes the\n * rest of the chain, including the built-in behavior.\n *\n * @param args — optional `this`, the event name, listener arguments, then `next`.\n * @returns the outermost listener's return value.\n */\n waterfall(...args: any[]): any;\n /**\n * Store a listener record as an effect on the current fiber.\n *\n * @param label — effect label shown in fiber diagnostics.\n * @param hooks — the listener list for one event.\n * @param callback — the listener to store.\n * @param options — placement and filtering options.\n * @returns a disposer that unregisters the listener.\n */\n register(label: string, hooks: Hook[], callback: any, options: EventOptions): () => void;\n /**\n * Remove a stored listener record.\n *\n * @param hooks — the listener list for one event.\n * @param callback — the listener to remove.\n * @returns `true` if the listener was found and removed.\n */\n unregister(hooks: Hook[], callback: any): true | undefined;\n /**\n * Register an event listener owned by the current fiber.\n *\n * The listener is removed automatically when the fiber unloads. Throws\n * `CordisError('INACTIVE_EFFECT')` if the fiber is already disposed.\n *\n * @param name — the event name to listen for.\n * @param listener — called with the dispatch arguments.\n * @param options — listener options; a boolean is shorthand for `prepend`.\n * @returns a disposer removing the listener; `true` if it was still registered.\n */\n on(name: string | symbol, listener: (...args: any) => any, options?: boolean | EventOptions): any;\n /**\n * Register an event listener that disposes itself after the first call.\n *\n * @param name — the event name to listen for.\n * @param listener — called at most once with the dispatch arguments.\n * @param options — listener options; a boolean is shorthand for `prepend`.\n * @returns a disposer removing the listener; `true` if it was still registered.\n */\n once(name: string, listener: (...args: any) => any, options?: boolean | EventOptions): any;\n}\n/**\n * Built-in framework events used by core services and extension points.\n *\n * Plugin and status events track fiber lifecycle, service events observe\n * dependency registration, update/get/set/listener events allow core services\n * to intercept runtime operations, and `internal/dispatch` exposes event-bus\n * diagnostics before public events are delivered.\n */\nexport interface Events {\n /** A plugin fiber was created or its uid was cleared on disposal. */\n 'internal/plugin'(fiber: Fiber): void;\n /** A fiber changed lifecycle state; receives the fiber and its previous state. */\n 'internal/status'(fiber: Fiber, oldValue: FiberState): void;\n /**\n * Resolve raw plugin config after the fiber's injections become active.\n * @param config - the raw config for this activation.\n * @mode waterfall\n */\n 'internal/config'(this: Fiber, config: any, next: () => any): any;\n /** Interception hook for a service binding (no core producer). */\n 'internal/service'(this: Context, name: string, value: any): void;\n /** Waterfall: a fiber config update is being applied; skip `next()` to veto. */\n 'internal/update'(this: Fiber, config: any, noSave: boolean, next: () => void | Promise<void>): void | Promise<void>;\n /** Waterfall: a service is being read through the context proxy. */\n 'internal/get'(ctx: Context, name: string, error: Error, next: () => any): any;\n /** Waterfall: a service is being written through the context proxy. */\n 'internal/set'(ctx: Context, name: string, value: any, error: Error, next: () => boolean): boolean;\n /** Bail: a listener is being registered; a non-null result replaces registration. */\n 'internal/listener'(this: Context, name: string, listener: any, prepend: boolean): void;\n /** An event is being dispatched to listeners (fired for non-internal events only). */\n 'internal/dispatch'(mode: DispatchMode, name: string, args: any[], thisArg: any): void;\n}\n//# sourceMappingURL=events.d.ts.map","import { Context } from './context.ts';\nimport { Fiber } from './fiber.ts';\nimport { symbols } from './utils.ts';\ndeclare module './context.ts' {\n interface Intercept {\n logger: LoggerService.Intercept;\n }\n}\n/** Logger method name and severity category. */\nexport type LoggerType = 'error' | 'info' | 'warn' | 'debug';\n/** Callable shape for one logger severity method. */\nexport type LoggerMethod = (format: any, ...param: any[]) => void;\n/** Formatter used to resolve a printf-style placeholder. */\nexport type Formatter = (value: any, exporter: Exporter, message: Message) => any;\n/** Numeric severity used when exporters decide whether to emit a message. */\nexport declare const enum LoggerLevel {\n ERROR = 0,\n INFO = 1,\n WARN = 2,\n DEBUG = 3\n}\n/** Structured log record delivered to exporters. */\nexport interface Message {\n sn: number;\n ts: number;\n name: string;\n type: LoggerType;\n level: number;\n args: any[];\n fiber?: WeakRef<Fiber>;\n}\n/** Sink that receives structured log messages. */\nexport interface Exporter {\n colors?: number | false;\n maxLength?: number;\n levels?: Record<string, number>;\n formatters?: Record<string, Formatter>;\n export(message: Message): void;\n}\n/** Built-in placeholder formatters used by `Logger.format()`. */\nexport declare const defaultFormatters: Record<string, Formatter>;\n/** Options used when creating a named logger facade. */\nexport interface LoggerOptions {\n /** The logger name shown with each message. */\n name: string;\n /** Message fields merged into every record from this logger. */\n meta?: Partial<Message>;\n /** Default maximum level exported when an exporter has no own threshold. */\n level?: number;\n}\n/** Logger facade identity, inherited message metadata, and optional minimum level. */\nexport interface Logger extends LoggerOptions {\n}\n/** Logger facade severity methods. */\nexport interface Logger extends Record<LoggerType, LoggerMethod> {\n}\n/** Logger facade for one named subsystem. */\nexport declare class Logger {\n private service;\n static color(exporter: Exporter, code: number, value: any, decoration?: string): string;\n static code(name: string, level?: false | number): number;\n static format(exporter: Exporter, message: Message): string;\n constructor(options: LoggerOptions, service: LoggerService);\n private _method;\n}\n/** ANSI 16-color palette indexes used for logger name coloring. */\nexport declare const c16: number[];\n/** ANSI 256-color palette indexes used for logger name coloring. */\nexport declare const c256: number[];\n/** Logger service configuration merged from context intercepts. */\nexport declare namespace LoggerService {\n interface Intercept {\n name?: string;\n level?: number;\n }\n}\n/** Callable `ctx.logger` service shape. */\nexport interface LoggerService extends Record<LoggerType, LoggerMethod> {\n (name?: string): Logger;\n}\n/**\n * Built-in logging service.\n *\n * Call `ctx.logger()` to create a named logger, or call `ctx.logger.info()`\n * directly to log with the current fiber-derived name.\n */\nexport declare class LoggerService {\n bufferSize: number;\n buffer: Message[];\n ctx: Context;\n _snMessage: number;\n _snExporter: number;\n exporters: Map<number, Exporter>;\n constructor(ctx: Context);\n /**\n * Register an exporter and dispose it with the current fiber.\n *\n * @param exporter — the sink that receives structured log messages.\n * @returns a disposer that removes the exporter.\n */\n exporter(exporter: Exporter): import(\"./fiber.ts\").Disposable<Promise<void>>;\n private _resolveConfig;\n [symbols.invoke](name?: string): Logger;\n}\n//# sourceMappingURL=logger.d.ts.map","import type { Dict } from '@deepseek-ai/cosmokit';\nimport { EventsService } from './events.ts';\nimport { LoggerService } from './logger.ts';\nimport { ReflectService } from './reflect.ts';\nimport { RegistryService, type InjectKey } from './registry.ts';\nimport { symbols } from './utils.ts';\nimport './fiber.ts';\n/**\n * Public shape of a Cordis context.\n *\n * The concrete `Context` class is proxied at runtime, so this interface is\n * augmented by core services and plugins to describe the properties that may\n * be read from `ctx`.\n */\nexport interface Context {\n /** Isolation map: service name → scope label. Lookups for a name resolve within its label. */\n [symbols.isolate]: Dict<symbol>;\n /** Intercept map: service name → config merged into that service's per-plugin config. */\n [symbols.intercept]: Dict;\n /** The root context of the application (every child context shares it). @experimental */\n root: this;\n /** Base URL used to resolve relative plugin/module specifiers, if the runtime sets one. */\n baseUrl?: string;\n /** The event bus. Its methods are also mixed onto `ctx` (`ctx.on`, `ctx.emit`, ...). */\n events: EventsService;\n /** The logging service. Call `ctx.logger(name)` for a named logger. */\n logger: LoggerService;\n /** The reflection layer backing the context proxy (`ctx.get`, `ctx.provide`, ...). */\n reflect: ReflectService;\n /** The plugin registry. Its methods are mixed onto `ctx` (`ctx.plugin`, `ctx.inject`). */\n registry: RegistryService;\n}\n/**\n * Root and child dependency containers for Cordis plugins.\n *\n * A context is a proxy: normal property reads go through the service resolver,\n * while `extend()`, `isolate()`, and `intercept()` create scoped child\n * contexts without mutating their parent.\n */\nexport declare class Context {\n /** Symbol key under which a disposer exposes its {@link EffectMeta} diagnostics tree. */\n static readonly effect: unique symbol;\n /** Symbol key for a context's listener filter, consulted on every event dispatch. */\n static readonly filter: unique symbol;\n /** Symbol key of the isolation map (see the `Context[symbols.isolate]` property). */\n static readonly isolate: unique symbol;\n /** Symbol key of the intercept map (see the `Context[symbols.intercept]` property). */\n static readonly intercept: unique symbol;\n /**\n * Returns true for Cordis context proxies and context prototypes.\n *\n * Works across realms and across multiple copies of cordis, because the\n * brand is keyed by a global symbol rather than by `instanceof`.\n *\n * @param value — the value to test.\n * @returns `true` if `value` is a Cordis context, narrowing its type.\n */\n static is(value: any): value is Context;\n /** Create the root context and install the built-in services. */\n constructor();\n /**\n * Create a child context with extra metadata on top of the current scope.\n *\n * The child prototypally inherits every property of this context; own\n * properties of `meta` shadow the inherited ones. The parent is not mutated.\n *\n * @param meta — own properties (including symbol keys) to define on the child.\n * @returns a child context inheriting from this one.\n */\n extend(meta?: {}): this;\n /**\n * Create a child context with an independent service scope for `name`.\n *\n * Below the returned context, reads and writes of the service `name`\n * resolve against the new label instead of the parent's, so a different\n * implementation can be provided without affecting the parent scope.\n * Passing the same `label` to two `isolate()` calls joins their scopes.\n *\n * @param name — the service name to isolate.\n * @param label — scope label to join; defaults to a fresh unique symbol.\n * @returns a child context whose `name` service resolves in the new scope.\n */\n isolate(name: string, label?: symbol): this;\n /**\n * Add service-specific intercept config for plugins started below this\n * context.\n *\n * Plugins loaded under the returned context see `config` merged into the\n * service's resolved config (ancestor entries first; see\n * `Service[symbols.resolveConfig]`). The parent context is not affected.\n *\n * @param name — the service name whose config to intercept.\n * @param config — the intercept config to merge for that service.\n * @returns a child context carrying the additional intercept entry.\n */\n intercept<K extends InjectKey>(name: K, config: Context[K] extends {\n [symbols.config]: infer T;\n } ? T : never): this;\n intercept(name: string, config: any): this;\n}\n//# sourceMappingURL=context.d.ts.map","import { Context } from './context.ts';\nimport { symbols } from './utils.ts';\n/**\n * Base class for services that expose a named API on `ctx`.\n *\n * Subclasses call `super(ctx, name)` from their constructor. The service is\n * registered immediately and is automatically removed with the owning fiber.\n */\nexport declare abstract class Service<out T = never> {\n protected ctx: Context;\n /** Symbol key of an instance method run after construction (class plugins). */\n static readonly init: unique symbol;\n /** Symbol key of the availability predicate passed to `ctx.provide()`. */\n static readonly check: unique symbol;\n /** Symbol key of the phantom intercept-config type parameter. */\n static readonly config: unique symbol;\n /** Symbol key of the call body making a service callable (e.g. `ctx.logger()`). */\n static readonly invoke: unique symbol;\n /** Symbol key of the helper deriving an extended service instance. */\n static readonly extend: unique symbol;\n /** Symbol key of the tracker metadata used for context tracing. */\n static readonly tracker: unique symbol;\n /** Symbol key of the intercept-config resolution helper below. */\n static readonly resolveConfig: unique symbol;\n [symbols.config]: T;\n /** The service name this instance is registered under. */\n name: string;\n /**\n * Register this instance as `name` in the current context.\n *\n * Calls `ctx.reflect.provide(name, this, this[Service.check])`, so the\n * service is unregistered automatically when the owning fiber unloads.\n * Services with a `[Service.invoke]` body return a callable instance.\n *\n * @param ctx — the context to register in (stored as `this.ctx`).\n * @param name — the service name; defaults to the static `provide` field.\n */\n constructor(ctx: Context, name: string);\n protected [symbols.filter](ctx: Context): boolean;\n protected [symbols.extend](props?: any): any;\n /**\n * Merge intercept config from ancestors with optional base and head values.\n *\n * Entries added closer to the root apply first; `base` is prepended and\n * `head` appended. Uses `Config.merge` when the service declares one,\n * otherwise a shallow `Object.assign`.\n *\n * @param base — lowest-precedence config merged before all intercepts.\n * @param head — highest-precedence config merged after all intercepts.\n * @returns the merged config.\n */\n [symbols.resolveConfig](base?: T, head?: T): T;\n static [Symbol.hasInstance](instance: any): boolean;\n}\n//# sourceMappingURL=service.d.ts.map","/**\n * Bundled pentest knowledge skills for the sharpkit suite: mounts one\n * isolated `skill-filesystem` provider over the eleven knowledge categories\n * migrated verbatim from strix (one directory per category under `skills`),\n * so the dsh `skill` tool lists and loads them like any other skill source.\n * @module @gpzhang2001/sharpkit-skills\n */\nimport type { Context } from '@deepseek-ai/cordis';\nimport type Schema from '@deepseek-ai/schemastery';\n/** Cordis plugin name. */\nexport declare const name = \"pentest-skills\";\n/** Required services: the dsh skill registry. */\nexport declare const inject: string[];\n/** Provider configuration for the bundled knowledge skills. */\nexport interface Config {\n /** Root holding the category directories; defaults to this package's bundled `skills/` tree. */\n skillsRoot?: string;\n /** Provider name registered into `ctx.skills`; must be unique in the process. */\n providerName?: string;\n /** Whether the mounted provider also includes the dsh default project/user roots. */\n includeDefaultRoots?: boolean;\n /** Whether category directories are watched for catalog changes; bundled assets are static, so this defaults off. */\n watch?: boolean;\n}\nexport declare const Config: Schema<Config>;\n/**\n * The bundled skills tree shipped inside this package.\n * @returns absolute path of the `skills/` directory next to `src/`.\n */\nexport declare function bundledSkillsRoot(): string;\n/**\n * Resolve the category directories to mount, one skill root each.\n * @param root - the skills root directory.\n * @returns absolute category directory paths, each holding at least one Markdown skill.\n * @throws when the root is missing, unreadable, or holds no category with a skill file.\n */\nexport declare function categoryRoots(root: string): string[];\n/**\n * Mount the isolated bundled-skills provider onto `ctx.skills`.\n * @param ctx - host context with the skill registry available.\n * @param config - provider configuration with defaults resolved at this boundary.\n */\nexport declare function apply(ctx: Context, config?: Config): void;\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9],"mappings":"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"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { readdirSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import z from "@deepseek-ai/schemastery";
|
|
5
|
+
import * as skillFilesystem from "@deepseek-ai/dsh-skill-filesystem";
|
|
6
|
+
//#region src/index.ts
|
|
7
|
+
/**
|
|
8
|
+
* Bundled pentest knowledge skills for the sharpkit suite: mounts one
|
|
9
|
+
* isolated `skill-filesystem` provider over the eleven knowledge categories
|
|
10
|
+
* migrated verbatim from strix (one directory per category under `skills`),
|
|
11
|
+
* so the dsh `skill` tool lists and loads them like any other skill source.
|
|
12
|
+
* @module @gpzhang2001/sharpkit-skills
|
|
13
|
+
*/
|
|
14
|
+
/** Cordis plugin name. */
|
|
15
|
+
const name = "pentest-skills";
|
|
16
|
+
/** Required services: the dsh skill registry. */
|
|
17
|
+
const inject = ["skills"];
|
|
18
|
+
const Config = z.object({
|
|
19
|
+
skillsRoot: z.string(),
|
|
20
|
+
providerName: z.string().min(1).default("pentest-bundled"),
|
|
21
|
+
includeDefaultRoots: z.boolean().default(false),
|
|
22
|
+
watch: z.boolean().default(false)
|
|
23
|
+
});
|
|
24
|
+
/**
|
|
25
|
+
* The bundled skills tree shipped inside this package.
|
|
26
|
+
* @returns absolute path of the `skills/` directory next to `src/`.
|
|
27
|
+
*/
|
|
28
|
+
function bundledSkillsRoot() {
|
|
29
|
+
return resolve(dirname(fileURLToPath(import.meta.url)), "../skills");
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the category directories to mount, one skill root each.
|
|
33
|
+
* @param root - the skills root directory.
|
|
34
|
+
* @returns absolute category directory paths, each holding at least one Markdown skill.
|
|
35
|
+
* @throws when the root is missing, unreadable, or holds no category with a skill file.
|
|
36
|
+
*/
|
|
37
|
+
function categoryRoots(root) {
|
|
38
|
+
let entries;
|
|
39
|
+
try {
|
|
40
|
+
entries = readdirSync(root, { withFileTypes: true });
|
|
41
|
+
} catch (error) {
|
|
42
|
+
throw new Error(`pentest-skills: cannot read skills root ${root}: ${String(error)}`);
|
|
43
|
+
}
|
|
44
|
+
const categories = [];
|
|
45
|
+
for (const entry of entries) {
|
|
46
|
+
if (!entry.isDirectory()) continue;
|
|
47
|
+
const dir = join(root, entry.name);
|
|
48
|
+
if (readdirSync(dir).some((file) => file.endsWith(".md"))) categories.push(dir);
|
|
49
|
+
}
|
|
50
|
+
if (categories.length === 0) throw new Error(`pentest-skills: no category directory with a skill file under ${root}`);
|
|
51
|
+
return categories.sort();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Mount the isolated bundled-skills provider onto `ctx.skills`.
|
|
55
|
+
* @param ctx - host context with the skill registry available.
|
|
56
|
+
* @param config - provider configuration with defaults resolved at this boundary.
|
|
57
|
+
*/
|
|
58
|
+
function apply(ctx, config = {}) {
|
|
59
|
+
const customSkillDirs = categoryRoots(resolve(config.skillsRoot ?? bundledSkillsRoot()));
|
|
60
|
+
ctx.plugin(skillFilesystem, {
|
|
61
|
+
providerName: config.providerName ?? "pentest-bundled",
|
|
62
|
+
includeDefaultRoots: config.includeDefaultRoots ?? false,
|
|
63
|
+
customSkillDirs,
|
|
64
|
+
watch: config.watch ?? false
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { Config, apply, bundledSkillsRoot, categoryRoots, inject, name };
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * Bundled pentest knowledge skills for the sharpkit suite: mounts one\n * isolated `skill-filesystem` provider over the eleven knowledge categories\n * migrated verbatim from strix (one directory per category under `skills`),\n * so the dsh `skill` tool lists and loads them like any other skill source.\n * @module @gpzhang2001/sharpkit-skills\n */\n\nimport { readdirSync } from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type Schema from '@deepseek-ai/schemastery'\nimport z from '@deepseek-ai/schemastery'\nimport * as skillFilesystem from '@deepseek-ai/dsh-skill-filesystem'\n\n/** Cordis plugin name. */\nexport const name = 'pentest-skills'\n/** Required services: the dsh skill registry. */\nexport const inject = ['skills']\n\n/** Provider configuration for the bundled knowledge skills. */\nexport interface Config {\n /** Root holding the category directories; defaults to this package's bundled `skills/` tree. */\n skillsRoot?: string\n /** Provider name registered into `ctx.skills`; must be unique in the process. */\n providerName?: string\n /** Whether the mounted provider also includes the dsh default project/user roots. */\n includeDefaultRoots?: boolean\n /** Whether category directories are watched for catalog changes; bundled assets are static, so this defaults off. */\n watch?: boolean\n}\n\nexport const Config: Schema<Config> = z.object({\n skillsRoot: z.string(),\n providerName: z.string().min(1).default('pentest-bundled'),\n includeDefaultRoots: z.boolean().default(false),\n watch: z.boolean().default(false),\n})\n\n/**\n * The bundled skills tree shipped inside this package.\n * @returns absolute path of the `skills/` directory next to `src/`.\n */\nexport function bundledSkillsRoot(): string {\n return resolve(dirname(fileURLToPath(import.meta.url)), '../skills')\n}\n\n/**\n * Resolve the category directories to mount, one skill root each.\n * @param root - the skills root directory.\n * @returns absolute category directory paths, each holding at least one Markdown skill.\n * @throws when the root is missing, unreadable, or holds no category with a skill file.\n */\nexport function categoryRoots(root: string): string[] {\n let entries\n try {\n entries = readdirSync(root, { withFileTypes: true })\n } catch (error) {\n throw new Error(`pentest-skills: cannot read skills root ${root}: ${String(error)}`)\n }\n const categories: string[] = []\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const dir = join(root, entry.name)\n const hasSkillFile = readdirSync(dir).some(file => file.endsWith('.md'))\n if (hasSkillFile) categories.push(dir)\n }\n if (categories.length === 0) {\n throw new Error(`pentest-skills: no category directory with a skill file under ${root}`)\n }\n return categories.sort()\n}\n\n/**\n * Mount the isolated bundled-skills provider onto `ctx.skills`.\n * @param ctx - host context with the skill registry available.\n * @param config - provider configuration with defaults resolved at this boundary.\n */\nexport function apply(ctx: Context, config: Config = {}): void {\n const root = resolve(config.skillsRoot ?? bundledSkillsRoot())\n const customSkillDirs = categoryRoots(root)\n ctx.plugin(skillFilesystem, {\n providerName: config.providerName ?? 'pentest-bundled',\n includeDefaultRoots: config.includeDefaultRoots ?? false,\n customSkillDirs,\n watch: config.watch ?? false,\n })\n}\n"],"mappings":";;;;;;;;;;;;;;AAiBA,MAAa,OAAO;;AAEpB,MAAa,SAAS,CAAC,QAAQ;AAc/B,MAAa,SAAyB,EAAE,OAAO;CAC7C,YAAY,EAAE,OAAO;CACrB,cAAc,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,iBAAiB;CACzD,qBAAqB,EAAE,QAAQ,CAAC,CAAC,QAAQ,KAAK;CAC9C,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,KAAK;AAClC,CAAC;;;;;AAMD,SAAgB,oBAA4B;CAC1C,OAAO,QAAQ,QAAQ,cAAc,YAAY,GAAG,CAAC,GAAG,WAAW;AACrE;;;;;;;AAQA,SAAgB,cAAc,MAAwB;CACpD,IAAI;CACJ,IAAI;EACF,UAAU,YAAY,MAAM,EAAE,eAAe,KAAK,CAAC;CACrD,SAAS,OAAO;EACd,MAAM,IAAI,MAAM,2CAA2C,KAAK,IAAI,OAAO,KAAK,GAAG;CACrF;CACA,MAAM,aAAuB,CAAC;CAC9B,KAAK,MAAM,SAAS,SAAS;EAC3B,IAAI,CAAC,MAAM,YAAY,GAAG;EAC1B,MAAM,MAAM,KAAK,MAAM,MAAM,IAAI;EAEjC,IADqB,YAAY,GAAG,CAAC,CAAC,MAAK,SAAQ,KAAK,SAAS,KAAK,CACvD,GAAG,WAAW,KAAK,GAAG;CACvC;CACA,IAAI,WAAW,WAAW,GACxB,MAAM,IAAI,MAAM,iEAAiE,MAAM;CAEzF,OAAO,WAAW,KAAK;AACzB;;;;;;AAOA,SAAgB,MAAM,KAAc,SAAiB,CAAC,GAAS;CAE7D,MAAM,kBAAkB,cADX,QAAQ,OAAO,cAAc,kBAAkB,CACnB,CAAC;CAC1C,IAAI,OAAO,iBAAiB;EAC1B,cAAc,OAAO,gBAAgB;EACrC,qBAAqB,OAAO,uBAAuB;EACnD;EACA,OAAO,OAAO,SAAS;CACzB,CAAC;AACH"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gpzhang2001/sharpkit-skills",
|
|
3
|
+
"description": "Bundled pentest knowledge skills (11 knowledge categories) mounted through an isolated skill-filesystem provider",
|
|
4
|
+
"version": "0.2.1",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/gpzhang2001/sharpkit.git",
|
|
11
|
+
"directory": "packages/skills"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"license": "Apache-2.0",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./lib/index.d.ts",
|
|
18
|
+
"default": "./lib/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./src/*": "./src/*",
|
|
21
|
+
"./package.json": "./package.json"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"lib",
|
|
25
|
+
"src",
|
|
26
|
+
"skills",
|
|
27
|
+
"LICENSE",
|
|
28
|
+
"THIRD_PARTY_NOTICES.md"
|
|
29
|
+
],
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@deepseek-ai/dsh-skill-filesystem": "0.1.2-rc.1",
|
|
32
|
+
"@deepseek-ai/schemastery": "3.18.2"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@deepseek-ai/cordis": "4.0.2",
|
|
36
|
+
"@deepseek-ai/dsh-home-paths": "0.1.2-rc.1",
|
|
37
|
+
"@deepseek-ai/dsh-scope": "0.1.2-rc.1",
|
|
38
|
+
"@deepseek-ai/dsh-skill": "0.1.2-rc.1",
|
|
39
|
+
"yaml": "^2.4.2"
|
|
40
|
+
},
|
|
41
|
+
"main": "lib/index.js",
|
|
42
|
+
"types": "lib/index.d.ts",
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "cp ../../LICENSE ../../THIRD_PARTY_NOTICES.md . && tsdown && mv -f lib/index.ts lib/index.d.ts && mv -f lib/index.ts.map lib/index.d.ts.map"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: counterevidence
|
|
3
|
+
description: Closure discipline for security findings — what counts as proof of safety, what does not, and how to record an unresolved candidate instead of silently dropping it
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Counterevidence and Closure Discipline
|
|
7
|
+
|
|
8
|
+
Proving a bug is real is only half the job. The other half is proving a
|
|
9
|
+
candidate is *not* real — and that half is where both false positives and
|
|
10
|
+
false negatives come from.
|
|
11
|
+
|
|
12
|
+
This skill governs how you close a candidate. It applies to every
|
|
13
|
+
candidate you open, whether it came from a scanner, a code read, a crawl,
|
|
14
|
+
or a hunch.
|
|
15
|
+
|
|
16
|
+
## Three Closure States
|
|
17
|
+
|
|
18
|
+
Every candidate you open ends in exactly one of these. There is no fourth
|
|
19
|
+
state, and "I moved on" is not one of them.
|
|
20
|
+
|
|
21
|
+
**1. `confirmed`** — you have a working PoC or, in white-box, a complete
|
|
22
|
+
source → control → sink → impact trace plus evidence the path is
|
|
23
|
+
reachable. File it with `create_vulnerability_report`.
|
|
24
|
+
|
|
25
|
+
**2. `ruled_out`** — you can name the **specific control** that makes the
|
|
26
|
+
code safe, at a specific location, and you have checked that the control
|
|
27
|
+
actually runs on the attacker's path. "Named control" means you can
|
|
28
|
+
complete this sentence with concrete detail: *"This is safe because
|
|
29
|
+
`<control>` at `<file:line or observed behavior>` `<does what>` before
|
|
30
|
+
`<sink>`, on every path an attacker can reach."* If you cannot complete
|
|
31
|
+
that sentence, you are not in `ruled_out`.
|
|
32
|
+
|
|
33
|
+
**3. `open_proof_gap`** — the candidate is plausible, you could not
|
|
34
|
+
confirm it, and you also could not name a control that rules it out. This
|
|
35
|
+
is a legitimate, expected outcome. Record it with
|
|
36
|
+
`record_coverage(outcome="needs_follow_up")`, carry it up in
|
|
37
|
+
`agent_finish(open_items=[...])`, and reflect it in `counterevidence` /
|
|
38
|
+
`confidence_rationale` if you file a related report. Do **not** convert
|
|
39
|
+
it to `ruled_out` to tidy up your worklist.
|
|
40
|
+
|
|
41
|
+
The failure mode this exists to prevent: an agent reads code, feels
|
|
42
|
+
uncertain, and quietly closes the candidate. That is an
|
|
43
|
+
`open_proof_gap` being mislabelled as `ruled_out`, and it is how real
|
|
44
|
+
vulnerabilities get missed.
|
|
45
|
+
|
|
46
|
+
## What Does NOT Rule Out a Candidate
|
|
47
|
+
|
|
48
|
+
Each of these is a common, plausible-sounding reason to drop a candidate.
|
|
49
|
+
None of them is sufficient on its own.
|
|
50
|
+
|
|
51
|
+
**Generic trust in a library or helper.** "It uses a well-known
|
|
52
|
+
sanitizer / the framework escapes this / the ORM handles it" is not
|
|
53
|
+
counterevidence. You must confirm *that* call, with *those* arguments, in
|
|
54
|
+
*that* context. Escaping helpers are context-specific: an HTML escaper
|
|
55
|
+
does nothing in a JS or attribute context, a SQL identifier quoter is not
|
|
56
|
+
a value quoter, and a path joiner is not a containment check.
|
|
57
|
+
|
|
58
|
+
**A control that runs on a different path.** Middleware, a decorator, or
|
|
59
|
+
a guard that protects the common route does not protect a sibling route,
|
|
60
|
+
an internal caller, a batch/async job, or an admin alias that reaches the
|
|
61
|
+
same sink. Check the specific path.
|
|
62
|
+
|
|
63
|
+
**A control that runs at the wrong time.** Validation *before* a
|
|
64
|
+
redirect, canonicalization *after* a path is already materialized, a
|
|
65
|
+
containment check *after* extraction, or an ownership check *after* the
|
|
66
|
+
object was already fetched and returned — these are ordering bugs, not
|
|
67
|
+
controls. Establish that the control runs before the dangerous effect.
|
|
68
|
+
|
|
69
|
+
**A control that can fail open.** Hardening flags set inside a
|
|
70
|
+
`try`/`except` that swallows failures, a parser feature that a caller can
|
|
71
|
+
override, a factory or config object supplied by the caller, or a
|
|
72
|
+
allow-list that is empty by default — all leave the candidate alive.
|
|
73
|
+
|
|
74
|
+
**A safe sibling.** If one call site is correctly guarded, that says
|
|
75
|
+
nothing about the other call sites of the same helper. Never let a safe
|
|
76
|
+
instance close a vulnerable one, and never collapse multiple instances
|
|
77
|
+
into one candidate just because they share a root cause — each reachable
|
|
78
|
+
instance stands or falls on its own.
|
|
79
|
+
|
|
80
|
+
**Missing information.** "I could not find a caller", "I could not tell
|
|
81
|
+
if this is deployed", "I could not determine whether this route is
|
|
82
|
+
exposed", "I could not stand up the service" — every one of these is an
|
|
83
|
+
`open_proof_gap`, not proof of safety. Missing evidence is missing
|
|
84
|
+
evidence; it is not evidence of absence.
|
|
85
|
+
|
|
86
|
+
**Difficulty.** "The build failed", "it needs credentials I don't have",
|
|
87
|
+
"the service mesh isn't available" are reasons to record a proof gap and
|
|
88
|
+
move on to the next candidate — not reasons to mark it clean. Do not let
|
|
89
|
+
one hard environment setup consume the budget you need for sibling
|
|
90
|
+
candidates.
|
|
91
|
+
|
|
92
|
+
**Operator configurability.** "An operator *could* configure a filter",
|
|
93
|
+
"this is a documented feature", "it's off by default" are not controls.
|
|
94
|
+
What ships and what is reachable is what matters.
|
|
95
|
+
|
|
96
|
+
**Being internal.** Internal-only, admin-only, or authenticated-only
|
|
97
|
+
reduces severity — it does not make the finding unreal. Downgrade it;
|
|
98
|
+
do not delete it.
|
|
99
|
+
|
|
100
|
+
## Recording Closure
|
|
101
|
+
|
|
102
|
+
Closure is only useful if it is written down. Every surface you assess
|
|
103
|
+
gets a `record_coverage` entry:
|
|
104
|
+
|
|
105
|
+
- `confirmed` → outcome `reported`, once the report is filed.
|
|
106
|
+
- `ruled_out` → outcome `ruled_out`, with the named control in
|
|
107
|
+
`evidence`. If you cannot name it, this is not `ruled_out`.
|
|
108
|
+
- `open_proof_gap` → outcome `needs_follow_up`, with the specific gap in
|
|
109
|
+
`evidence`.
|
|
110
|
+
- Tested thoroughly with nothing to show for it → `no_issue_found`.
|
|
111
|
+
- The risk cannot apply to this surface at all → `not_applicable`, with
|
|
112
|
+
the reason.
|
|
113
|
+
|
|
114
|
+
A scan that records only findings cannot tell the reader what was
|
|
115
|
+
reviewed and cleared, which makes every clean area indistinguishable
|
|
116
|
+
from an unvisited one.
|
|
117
|
+
|
|
118
|
+
Closure is not permanent. The ledger is shared across every agent, and
|
|
119
|
+
a surface someone left at `needs_follow_up` is an invitation: if you
|
|
120
|
+
had the credentials, the running service, or the reachability proof
|
|
121
|
+
they lacked, move their entry with `update_coverage` rather than
|
|
122
|
+
recording a parallel one. This runs both ways — a `ruled_out` whose
|
|
123
|
+
named control does not cover the path you just found goes back to
|
|
124
|
+
`reported` or `needs_follow_up`, with what changed in `evidence`. The
|
|
125
|
+
previous state is kept as history, so correcting the record costs
|
|
126
|
+
nothing and leaving it wrong costs a finding.
|
|
127
|
+
|
|
128
|
+
## What DOES Rule Out a Candidate
|
|
129
|
+
|
|
130
|
+
- You executed the attack and it demonstrably failed, and you understand
|
|
131
|
+
*why* it failed (not just that the response was a 403).
|
|
132
|
+
- You can point at the control, at a location, and show it runs on every
|
|
133
|
+
attacker-reachable path to the sink, before the effect, without a
|
|
134
|
+
fail-open branch.
|
|
135
|
+
- The sink is not actually dangerous in this context, and you can say
|
|
136
|
+
what makes it inert.
|
|
137
|
+
- The input is not actually attacker-controlled, and you traced it to a
|
|
138
|
+
trusted origin rather than assuming it.
|
|
139
|
+
|
|
140
|
+
Negative controls make a `ruled_out` much stronger: send the payload that
|
|
141
|
+
*should* work if the bug were real, and show it is blocked, while a
|
|
142
|
+
benign variant succeeds. That distinguishes "the control works" from "the
|
|
143
|
+
endpoint is broken/unreachable for unrelated reasons".
|
|
144
|
+
|
|
145
|
+
## Before You File a Report
|
|
146
|
+
|
|
147
|
+
Run this pass on every finding before calling
|
|
148
|
+
`create_vulnerability_report`:
|
|
149
|
+
|
|
150
|
+
1. **Argue the other side.** Spend real effort building the strongest
|
|
151
|
+
case that this is *not* exploitable, or not as severe as you think.
|
|
152
|
+
Look for the guard you might have missed, the deployment context that
|
|
153
|
+
constrains it, the precondition you assumed.
|
|
154
|
+
2. **Record what you found** in `counterevidence`. If you found a real
|
|
155
|
+
constraint, say what it is and why it does not neutralize the finding.
|
|
156
|
+
If you genuinely found nothing, say what you checked — "no input
|
|
157
|
+
validation, WAF, or authorization check was found on this path; tested
|
|
158
|
+
both authenticated and unauthenticated" — not just "none".
|
|
159
|
+
3. **Set `confidence` honestly.** A working PoC against a live target is
|
|
160
|
+
`high`. A complete static trace you could not execute is at best
|
|
161
|
+
`medium`, and `confidence_rationale` must name the gap. Do not inflate
|
|
162
|
+
confidence to make a finding look better; an accurate `medium` is far
|
|
163
|
+
more useful to the reader than a `high` that does not survive triage.
|
|
164
|
+
4. **State what would move the severity** in `severity_change_conditions`
|
|
165
|
+
— the one concrete piece of evidence that would raise or lower it
|
|
166
|
+
(e.g. "confirmation that this route is exposed to unauthenticated
|
|
167
|
+
internet traffic would raise this to critical").
|
|
168
|
+
|
|
169
|
+
## Reporting an Unconfirmed Candidate
|
|
170
|
+
|
|
171
|
+
Dynamic proof is the standard. But when you have a complete
|
|
172
|
+
source → control → sink → impact trace and runtime reproduction is
|
|
173
|
+
genuinely out of reach (no credentials, unavailable internal services, a
|
|
174
|
+
build that cannot run in the sandbox), a static-only finding is still
|
|
175
|
+
reportable — at `confidence: medium` or `low`, with the missing runtime
|
|
176
|
+
proof named explicitly in `confidence_rationale`.
|
|
177
|
+
|
|
178
|
+
What is **not** acceptable is a scanner hit with no trace, a "this
|
|
179
|
+
pattern is usually dangerous" claim, or a finding where you never
|
|
180
|
+
identified the attacker-controlled input. Those are not proof gaps, they
|
|
181
|
+
are non-findings.
|
|
182
|
+
|
|
183
|
+
If you are unsure whether a candidate clears this bar: it clears it if
|
|
184
|
+
you can name the input, the path, the missing or broken control, and the
|
|
185
|
+
effect. It does not if any one of those is a guess.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fix-verification
|
|
3
|
+
description: How to verify a proposed code fix before shipping it — the ordered gates, what disqualifies a fix, and when to withhold the suggestion instead
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Fix Verification
|
|
7
|
+
|
|
8
|
+
When you attach `fix_before` / `fix_after` to a code location, you are not
|
|
9
|
+
writing advice. You are writing a suggestion block that a reviewer can
|
|
10
|
+
apply with one click, straight into their codebase. An unverified fix is
|
|
11
|
+
worse than no fix: it converts your uncertainty into their merged commit.
|
|
12
|
+
|
|
13
|
+
This skill covers what you must establish before that happens.
|
|
14
|
+
|
|
15
|
+
## Judge in This Order
|
|
16
|
+
|
|
17
|
+
1. The current state is correctly classified — vulnerable, already safe,
|
|
18
|
+
or unproven.
|
|
19
|
+
2. The fix completely closes the broken security boundary.
|
|
20
|
+
3. Legitimate behavior and compatibility are preserved.
|
|
21
|
+
4. The relevant repository checks pass.
|
|
22
|
+
5. The change follows the repository's own conventions.
|
|
23
|
+
6. The patch contains only what properties 1–5 require.
|
|
24
|
+
|
|
25
|
+
**Never trade an earlier property for a later one.** A smaller, tidier,
|
|
26
|
+
more idiomatic patch that leaves the boundary open is a failure. Minimal
|
|
27
|
+
means *the smallest repository-native change that satisfies everything
|
|
28
|
+
above it* — not the fewest lines.
|
|
29
|
+
|
|
30
|
+
## Before You Edit
|
|
31
|
+
|
|
32
|
+
Establish these from the code, not from assumption:
|
|
33
|
+
|
|
34
|
+
- The source → sink path or the specific broken control.
|
|
35
|
+
- The attacker-controlled input and the preconditions it needs.
|
|
36
|
+
- **The security invariant** — state it in one sentence. "Only the owning
|
|
37
|
+
tenant may read this record." "The extracted path must stay inside the
|
|
38
|
+
destination directory." If you cannot state the invariant, you cannot
|
|
39
|
+
tell whether your patch enforces it.
|
|
40
|
+
- The narrowest place that invariant can be enforced.
|
|
41
|
+
- The legitimate behavior, public APIs, and error semantics that must
|
|
42
|
+
survive the change.
|
|
43
|
+
- The repository's existing helpers and precedents for this kind of
|
|
44
|
+
control. Reach for the codebase's own validator before inventing one.
|
|
45
|
+
|
|
46
|
+
## The Verification Gates
|
|
47
|
+
|
|
48
|
+
Run these **in order**. A failure at any gate disqualifies the fix —
|
|
49
|
+
revise the patch or withhold it. Do not compensate for a failed gate by
|
|
50
|
+
making the diff smaller or the write-up longer.
|
|
51
|
+
|
|
52
|
+
**1. Applicability.** Read the final diff. Confirm it contains nothing
|
|
53
|
+
unrelated, that `fix_before` still matches the file character-for-
|
|
54
|
+
character, and that `start_line`/`end_line` still cover exactly those
|
|
55
|
+
lines. Run the narrowest syntax / import / type check available.
|
|
56
|
+
|
|
57
|
+
**2. Security closure.** Re-run the original PoC against the patched
|
|
58
|
+
code. If you cannot execute it, re-trace source → control → sink through
|
|
59
|
+
the *patched* source and state precisely which step now fails and why.
|
|
60
|
+
"The fix adds validation" is not closure; "the fix rejects `../` before
|
|
61
|
+
the path reaches `open()`, and `open()` is the only sink on this path" is.
|
|
62
|
+
|
|
63
|
+
**3. Bypass review.** Re-read the finding and the diff *without* leaning
|
|
64
|
+
on the reasoning that produced the patch — you are looking for what that
|
|
65
|
+
reasoning missed. Trace the changed branches from their direct callers.
|
|
66
|
+
Check equivalent sinks and sibling call sites of the same helper. Try at
|
|
67
|
+
least one alternate malicious input class: different encoding, different
|
|
68
|
+
content type, a null byte, a unicode homoglyph, a nested/doubled
|
|
69
|
+
payload, a different HTTP verb. A control that catches your one payload
|
|
70
|
+
and nothing else has not closed the boundary.
|
|
71
|
+
|
|
72
|
+
**4. Preserved behavior.** Exercise the legitimate case through the same
|
|
73
|
+
boundary. Confirm the APIs, error semantics, and compatibility
|
|
74
|
+
constraints you recorded still hold. A fix that breaks the feature will
|
|
75
|
+
be reverted, which means the vulnerability comes back.
|
|
76
|
+
|
|
77
|
+
**5. Repository checks.** Run the focused tests covering the changed
|
|
78
|
+
lines, then the owning package's tests, then the applicable formatter,
|
|
79
|
+
linter, and type checker. Use the repository's own commands.
|
|
80
|
+
|
|
81
|
+
Where practical, confirm the check would **fail if the security change
|
|
82
|
+
were removed**. A test that passes both with and without the patch is
|
|
83
|
+
proving nothing.
|
|
84
|
+
|
|
85
|
+
## What Disqualifies a Fix
|
|
86
|
+
|
|
87
|
+
- It closes your specific payload but not the input class.
|
|
88
|
+
- It sanitizes at the wrong layer — after the value was already used, or
|
|
89
|
+
in a helper that other callers bypass.
|
|
90
|
+
- It relies on a caller passing the right flag, or on a config the
|
|
91
|
+
operator has to set.
|
|
92
|
+
- It fails open: the new check sits inside a `try`/`except` that swallows
|
|
93
|
+
the failure, or returns "allowed" on error.
|
|
94
|
+
- It weakens authentication, authorization, tenant isolation, input
|
|
95
|
+
validation, sandboxing, or logging to make something else pass. Never
|
|
96
|
+
do this.
|
|
97
|
+
- It silently accepts, truncates, or reinterprets unsafe state instead of
|
|
98
|
+
rejecting it.
|
|
99
|
+
- It drags in unrelated refactors, sibling findings, or architectural
|
|
100
|
+
redesign.
|
|
101
|
+
|
|
102
|
+
## Withholding the Fix
|
|
103
|
+
|
|
104
|
+
If you cannot pass the gates, that is a legitimate outcome — say so
|
|
105
|
+
rather than shipping a guess. Drop `fix_after` from the location, leave
|
|
106
|
+
it informational, and put the remediation in prose in
|
|
107
|
+
`remediation_steps` instead. State in `fix-verification` exactly which
|
|
108
|
+
gate you could not clear and what was missing: the command that failed,
|
|
109
|
+
the service you could not start, the decision that needs a human.
|
|
110
|
+
|
|
111
|
+
Withhold and explain when:
|
|
112
|
+
|
|
113
|
+
- The complete fix depends on an unresolved product or public-API
|
|
114
|
+
compatibility decision.
|
|
115
|
+
- The invariant cannot be enforced without cross-subsystem changes you
|
|
116
|
+
cannot validate.
|
|
117
|
+
- You could not establish that the vulnerable path is real in the
|
|
118
|
+
current checkout. Do not patch an adjacent weakness as a consolation
|
|
119
|
+
prize, and do not add speculative defense-in-depth to a path you never
|
|
120
|
+
proved was reachable.
|
|
121
|
+
|
|
122
|
+
## Recording It
|
|
123
|
+
|
|
124
|
+
Everything above goes in `fix-verification`, which is required whenever
|
|
125
|
+
any location carries a `fix_after`. Write the actual commands and their
|
|
126
|
+
results, grouped by gate, and mark every gate you could only reason
|
|
127
|
+
about — rather than execute — as an explicit gap. Do not hide proof
|
|
128
|
+
gaps; a reviewer who knows gate 5 was skipped can run it themselves, but
|
|
129
|
+
one who was told it passed cannot.
|