@perrylink/dsh-skill-pack-security-provider 1.3.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -1,12 +1,19 @@
1
1
  /**
2
- * Optional provider plugin for dsh-skill-pack-security.
2
+ * Provider plugin for dsh-skill-pack-security — "skill 教流程,插件自动执行".
3
3
  *
4
- * Registers one SkillProvider on `ctx.skills` whose candidates are this
5
- * package's own `skills/` directory, reusing the official
6
- * `FileSystemSkillProvider` so frontmatter parsing semantics are byte-identical
7
- * with the built-in local provider (same fail-closed rules, same kebab-case
8
- * names, same invocation policy). The pack itself works without this plugin —
9
- * installing it only avoids copying skills into a scanned root.
4
+ * Registers two capabilities:
5
+ * 1. a SkillProvider on `ctx.skills` whose candidates are this package's own
6
+ * `skills/` directory (reusing the official `FileSystemSkillProvider`, so
7
+ * frontmatter parsing semantics are byte-identical with the built-in
8
+ * provider), and
9
+ * 2. the `plugin_vet` supply-chain gate tool on `ctx.tools`: an automated
10
+ * pre-install scanner (license / SBOM / commit pinning / malicious
11
+ * patterns / five-dimension risk score) whose every finding cites the
12
+ * pack skill section to continue as a manual audit.
13
+ *
14
+ * The scan engine is zero-dependency (Node built-ins only) and the plugin
15
+ * injects no prompt paragraphs: the gate lives entirely in the tool result,
16
+ * keeping the session persona untouched.
10
17
  *
11
18
  * @module dsh-skill-pack-security/provider
12
19
  */
@@ -15,12 +22,27 @@ import { dirname, join, resolve } from 'node:path';
15
22
  import { fileURLToPath } from 'node:url';
16
23
  import { FileSystemSkillProvider } from '@deepseek-ai/dsh-skill-filesystem';
17
24
  import z from '@deepseek-ai/schemastery';
25
+ import { resolveVetConfig } from './vet/config.js';
26
+ import { buildVetTool } from './vet/tool.js';
18
27
  export const name = 'skill-pack-security';
19
- export const inject = ['skills'];
28
+ export const inject = ['skills', 'tools'];
20
29
  export const Config = z.object({
21
30
  watch: z.boolean().default(false),
22
31
  language: z.union(['zh', 'en']).default('zh'),
23
32
  skillsDir: z.string().min(1),
33
+ vet: z.object({
34
+ enable: z.boolean().default(true),
35
+ timeoutMs: z.natural().min(1000).max(300000).default(15000),
36
+ maxFiles: z.natural().min(1).max(20000).default(800),
37
+ maxFileBytes: z.natural().min(1024).max(16 * 1024 * 1024).default(256 * 1024),
38
+ maxExtractBytes: z.natural().min(1024).max(512 * 1024 * 1024).default(64 * 1024 * 1024),
39
+ maxDepNodes: z.natural().min(1).max(10000).default(600),
40
+ maxFindingsPerCheck: z.natural().min(1).max(100).default(12),
41
+ userAgent: z.string().max(200).default('dsh-skill-pack-security/2.0.0 (+https://github.com/PerryLink/dsh-skill-pack-security)'),
42
+ gate: z.object({
43
+ policy: z.union(['warn', 'deny']).default('warn'),
44
+ }),
45
+ }),
24
46
  });
25
47
  /** Directory of this module: `provider/src` under tsx or `provider/lib` when built. */
26
48
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
@@ -79,4 +101,10 @@ export function apply(ctx, config = {}) {
79
101
  watch: config.watch ?? false,
80
102
  }));
81
103
  });
104
+ const vet = resolveVetConfig(config.vet);
105
+ if (vet.enable) {
106
+ ctx.effect(function* () {
107
+ yield ctx.tools.register(buildVetTool(vet, config.language ?? 'zh'));
108
+ });
109
+ }
82
110
  }
@@ -1,21 +1,31 @@
1
1
  /**
2
- * Optional provider plugin for dsh-skill-pack-security.
2
+ * Provider plugin for dsh-skill-pack-security — "skill 教流程,插件自动执行".
3
3
  *
4
- * Registers one SkillProvider on `ctx.skills` whose candidates are this
5
- * package's own `skills/` directory, reusing the official
6
- * `FileSystemSkillProvider` so frontmatter parsing semantics are byte-identical
7
- * with the built-in local provider (same fail-closed rules, same kebab-case
8
- * names, same invocation policy). The pack itself works without this plugin —
9
- * installing it only avoids copying skills into a scanned root.
4
+ * Registers two capabilities:
5
+ * 1. a SkillProvider on `ctx.skills` whose candidates are this package's own
6
+ * `skills/` directory (reusing the official `FileSystemSkillProvider`, so
7
+ * frontmatter parsing semantics are byte-identical with the built-in
8
+ * provider), and
9
+ * 2. the `plugin_vet` supply-chain gate tool on `ctx.tools`: an automated
10
+ * pre-install scanner (license / SBOM / commit pinning / malicious
11
+ * patterns / five-dimension risk score) whose every finding cites the
12
+ * pack skill section to continue as a manual audit.
13
+ *
14
+ * The scan engine is zero-dependency (Node built-ins only) and the plugin
15
+ * injects no prompt paragraphs: the gate lives entirely in the tool result,
16
+ * keeping the session persona untouched.
10
17
  *
11
18
  * @module dsh-skill-pack-security/provider
12
19
  */
13
20
  import type { Context } from '@deepseek-ai/cordis';
14
21
  import type Schema from '@deepseek-ai/schemastery';
22
+ import { type VetConfigInput } from './vet/config.js';
15
23
  export declare const name = "skill-pack-security";
16
24
  export declare const inject: string[];
17
- /** The skill language the provider publishes. */
25
+ /** The skill language the provider publishes (and the plugin_vet report language). */
18
26
  export type PackLanguage = 'zh' | 'en';
27
+ /** plugin_vet gate policy: warn (default, non-blocking) or deny (blocks install on FAIL). */
28
+ export type GatePolicy = 'warn' | 'deny';
19
29
  /** Configuration for the packaged skill provider. */
20
30
  export interface Config {
21
31
  /** Whether to watch the packaged skills directory; packaged content is static, so default false. */
@@ -24,6 +34,8 @@ export interface Config {
24
34
  language?: PackLanguage;
25
35
  /** Explicit skills root; overrides the `language`-derived default. Must be a non-empty path to an existing root with `<skill>/SKILL.md` bundles. */
26
36
  skillsDir?: string;
37
+ /** plugin_vet scanner + installation-gate configuration. */
38
+ vet?: VetConfigInput;
27
39
  }
28
40
  export declare const Config: Schema<Config>;
29
41
  /** Register the packaged skills directory as a custom-root provider. */
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The eight plugin_vet checks. Every function is pure: it reads the shared
3
+ * inputs and returns one `VetCheck` with redacted, capped findings. No check
4
+ * touches the network or the filesystem — resolution happened upstream in
5
+ * `source.ts`.
6
+ *
7
+ * @module dsh-skill-pack-security/vet/checks
8
+ */
9
+ import { type LockData, type Manifest } from './manifest.js';
10
+ import { type GitHubMeta, type NpmMeta, type ResolvedTarget } from './source.js';
11
+ import { type Lang } from './skills.js';
12
+ import type { VetConfig } from './config.js';
13
+ import type { ScannedFile } from './walk.js';
14
+ import type { CheckId, VetCheck, VetSbom } from './vocabulary.js';
15
+ /** Shared inputs every check reads. */
16
+ export interface CheckInputs {
17
+ readonly files: ScannedFile[];
18
+ readonly manifest: Manifest;
19
+ readonly lock: LockData;
20
+ readonly github: GitHubMeta | null;
21
+ readonly npm: NpmMeta | null;
22
+ readonly target: ResolvedTarget;
23
+ readonly config: VetConfig;
24
+ readonly lang: Lang;
25
+ /** 40-hex HEAD of a local git target, when readable without spawning git. */
26
+ readonly localHead: string;
27
+ readonly now: number;
28
+ }
29
+ /** One check run: the check plus its optional SBOM payload. */
30
+ export interface CheckResult {
31
+ readonly check: VetCheck;
32
+ readonly sbom?: VetSbom;
33
+ }
34
+ export declare function licenseCheck(inputs: CheckInputs): VetCheck;
35
+ export declare function sbomCheck(inputs: CheckInputs): CheckResult;
36
+ export declare function commitLockCheck(inputs: CheckInputs): VetCheck;
37
+ export declare function installScriptsCheck(inputs: CheckInputs): VetCheck;
38
+ export declare function networkExfilCheck(inputs: CheckInputs): VetCheck;
39
+ export declare function obfuscationCheck(inputs: CheckInputs): VetCheck;
40
+ export declare function sourceCheck(inputs: CheckInputs): VetCheck;
41
+ export declare function maintenanceCheck(inputs: CheckInputs): VetCheck;
42
+ /** Run the requested checks over shared inputs. */
43
+ export declare function runChecks(inputs: CheckInputs, ids: readonly CheckId[]): CheckResult[];
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Resolved plugin_vet configuration: plain values with defaults applied.
3
+ *
4
+ * The Schemastery schema lives in `../index.ts` next to the skills-provider
5
+ * config; this module only consumes the already-validated plain object so the
6
+ * engine never depends on Schemastery at runtime.
7
+ *
8
+ * @module dsh-skill-pack-security/vet/config
9
+ */
10
+ import type { GatePolicy } from './vocabulary.js';
11
+ /** Raw config block as validated by the Schemastery schema. */
12
+ export interface VetConfigInput {
13
+ readonly enable?: boolean;
14
+ readonly timeoutMs?: number;
15
+ readonly maxFiles?: number;
16
+ readonly maxFileBytes?: number;
17
+ readonly maxExtractBytes?: number;
18
+ readonly maxDepNodes?: number;
19
+ readonly maxFindingsPerCheck?: number;
20
+ readonly userAgent?: string;
21
+ readonly gate?: {
22
+ readonly policy?: GatePolicy;
23
+ };
24
+ }
25
+ /** Fully resolved configuration with defaults applied. */
26
+ export interface VetConfig {
27
+ readonly enable: boolean;
28
+ readonly timeoutMs: number;
29
+ readonly maxFiles: number;
30
+ readonly maxFileBytes: number;
31
+ readonly maxExtractBytes: number;
32
+ readonly maxDepNodes: number;
33
+ readonly maxFindingsPerCheck: number;
34
+ readonly userAgent: string;
35
+ readonly gate: {
36
+ readonly policy: GatePolicy;
37
+ };
38
+ }
39
+ export declare const VET_DEFAULTS: VetConfig;
40
+ /** Merge raw config over the defaults (the schema already validated shape/ranges). */
41
+ export declare function resolveVetConfig(raw: VetConfigInput | undefined): VetConfig;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * plugin_vet engine: resolves a target, runs the eight checks, scores the five
3
+ * risk dimensions, applies the installation gate, and returns the canonical
4
+ * report. Pure orchestration — all side effects live in `source.ts`/`fetch.ts`
5
+ * and every value produced here is JSON-safe and redacted.
6
+ *
7
+ * @module dsh-skill-pack-security/vet/engine
8
+ */
9
+ import { type GatePolicy, type VetReport } from './vocabulary.js';
10
+ import type { VetConfig } from './config.js';
11
+ import { type Lang } from './skills.js';
12
+ /** Engine-level failure: target unusable (not found, offline, budget). */
13
+ export declare class VetTargetError extends Error {
14
+ constructor(message: string);
15
+ }
16
+ /** Tool argument shape (already JSON-validated by defineTool). */
17
+ export interface VetArgs {
18
+ readonly target: string;
19
+ readonly ref?: string;
20
+ readonly checks?: string[];
21
+ readonly policy?: 'inherit' | GatePolicy;
22
+ }
23
+ /** Run the whole pipeline for one tool call. */
24
+ export declare function runVet(args: VetArgs, config: VetConfig, lang: Lang, signal: AbortSignal | undefined): Promise<VetReport>;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Zero-dependency network access for the scan engine.
3
+ *
4
+ * Only `globalThis.fetch` (Node 18+ built-in undici) is used. Every request:
5
+ * - honors the caller's AbortSignal AND a cooperative timeout
6
+ * (`AbortSignal.any` + `AbortSignal.timeout`), so a hung upstream can never
7
+ * stall a session;
8
+ * - enforces a hard byte cap while reading the body (stream-counted, no
9
+ * unbounded buffering);
10
+ * - sends a fixed User-Agent and never attaches credentials.
11
+ *
12
+ * @module dsh-skill-pack-security/vet/fetch
13
+ */
14
+ /** Options shared by all fetch helpers. */
15
+ export interface FetchOptions {
16
+ readonly signal?: AbortSignal;
17
+ readonly timeoutMs: number;
18
+ readonly userAgent: string;
19
+ /** Hard cap on the response body in bytes; oversized bodies abort early. */
20
+ readonly maxBytes: number;
21
+ }
22
+ /** A successfully read (possibly truncated) text body. */
23
+ export interface FetchedText {
24
+ readonly status: number;
25
+ readonly text: string;
26
+ readonly truncated: boolean;
27
+ }
28
+ /** A successfully read binary body (kept in memory; capped). */
29
+ export interface FetchedBuffer {
30
+ readonly status: number;
31
+ readonly buffer: Uint8Array;
32
+ readonly truncated: boolean;
33
+ }
34
+ /** A network failure — always surfaced as a check `skip`, never as a finding. */
35
+ export declare class VetFetchError extends Error {
36
+ readonly kind: 'timeout' | 'aborted' | 'http' | 'network' | 'too-large';
37
+ constructor(kind: VetFetchError['kind'], message: string);
38
+ }
39
+ /** Fetch a text body with size cap. */
40
+ export declare function fetchText(url: string, options: FetchOptions): Promise<FetchedText>;
41
+ /** Fetch a binary body with size cap (tarballs). */
42
+ export declare function fetchBuffer(url: string, options: FetchOptions): Promise<FetchedBuffer>;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Manifest and lockfile parsing for the SBOM check — pure text/JSON parsing,
3
+ * zero dependencies. Supports package.json plus pnpm-lock.yaml,
4
+ * package-lock.json (v1–v3) and yarn.lock (v1); unknown formats are reported
5
+ * as `unsupported`, never guessed.
6
+ *
7
+ * @module dsh-skill-pack-security/vet/manifest
8
+ */
9
+ import type { ScannedFile } from './walk.js';
10
+ import type { VetPackage } from './vocabulary.js';
11
+ /** Parsed package.json facts the checks consume. */
12
+ export interface Manifest {
13
+ readonly name: string;
14
+ readonly version: string;
15
+ readonly license: string;
16
+ readonly scripts: Record<string, string>;
17
+ readonly dependencies: Record<string, string>;
18
+ readonly devDependencies: Record<string, string>;
19
+ readonly optionalDependencies: Record<string, string>;
20
+ readonly peerDependencies: Record<string, string>;
21
+ readonly repository: string;
22
+ readonly present: boolean;
23
+ }
24
+ /** One dependency edge inside a lockfile entry: name → raw spec. */
25
+ type DepMap = Record<string, string>;
26
+ /** Parsed lockfile summary. */
27
+ export interface LockData {
28
+ readonly kind: 'pnpm' | 'npm' | 'yarn' | 'unsupported' | null;
29
+ readonly lockfile: string | null;
30
+ readonly lockfileVersion: string;
31
+ /** name@version → its dependencies (name → spec). */
32
+ readonly entries: Map<string, DepMap>;
33
+ /** Whether any integrity/shasum field was seen (pinning signal). */
34
+ readonly hasIntegrity: boolean;
35
+ }
36
+ /** Find and parse the first supported lockfile in the scan set. */
37
+ export declare function parseLockfile(files: ScannedFile[]): LockData;
38
+ /** Parse package.json when present. */
39
+ export declare function parseManifest(files: ScannedFile[]): Manifest;
40
+ /** Normalize a dependency spec into a bare version when possible. */
41
+ export declare function specVersion(spec: string): string;
42
+ /**
43
+ * Build the dependency tree: BFS from the manifest's direct dependencies
44
+ * through lockfile edges, deduped by name@version, depth- and node-capped.
45
+ */
46
+ export declare function buildDependencyTree(manifest: Manifest, lock: LockData, maxNodes: number): {
47
+ packages: VetPackage[];
48
+ truncated: boolean;
49
+ total: number;
50
+ };
51
+ /** Direct specs that are not exact-version pinned (a supply-chain signal). */
52
+ export declare function unpinnedSpecs(manifest: Manifest): string[];
53
+ export {};
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Report redaction: no secret-shaped text may ever leave the scan engine.
3
+ *
4
+ * Applied to every evidence snippet and finding message before a value enters
5
+ * the canonical report, mirroring the pack's `secret-scan` redaction rule
6
+ * (type marker only, never the value). Patterns cover the token families the
7
+ * `secret-scan` skill documents plus webhook/bot URLs.
8
+ *
9
+ * @module dsh-skill-pack-security/vet/redact
10
+ */
11
+ /** Replace every secret-shaped substring with a type marker. */
12
+ export declare function redact(text: string): string;
13
+ /** Cap a raw snippet and redact it for use as finding evidence. */
14
+ export declare function redactSnippet(text: string, maxChars?: number): string;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Model-facing renderers for the plugin_vet report: the canonical JSON value
3
+ * becomes a compact markdown report (render), a pending-call card
4
+ * (presentCall), and a completed gate card (presentResult). Everything is
5
+ * pure and capped — no secrets (the engine redacts before this layer), no
6
+ * unbounded trees.
7
+ *
8
+ * @module dsh-skill-pack-security/vet/report
9
+ */
10
+ import { type Lang } from './skills.js';
11
+ import type { VetReport, VetScores } from './vocabulary.js';
12
+ /** Five-dimension score line. */
13
+ export declare function scoresLine(scores: VetScores, lang: Lang): string;
14
+ /** Render the canonical report as model-facing markdown. */
15
+ export declare function renderReport(report: VetReport, lang: Lang): string;
16
+ /** Short gate summary for the completed card (≤ a few lines). */
17
+ export declare function gateSummary(report: VetReport, lang: Lang): string;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Skill cross-references and report-language strings for plugin_vet.
3
+ *
4
+ * Every check cites the pack skill (and section) that continues its subject
5
+ * as a manual audit — "skill 教流程,插件自动执行". Skill names are identical
6
+ * in the zh/en editions, so the reference is language-neutral.
7
+ *
8
+ * @module dsh-skill-pack-security/vet/skills
9
+ */
10
+ import type { CheckId, Dimension } from './vocabulary.js';
11
+ export type Lang = 'zh' | 'en';
12
+ /** check id → pack skill + section (the manual deep-dive continuation). */
13
+ export declare const SKILL_REF: Record<CheckId, string>;
14
+ /** check id → human-readable check name per language. */
15
+ export declare const CHECK_NAME: Record<Lang, Record<CheckId, string>>;
16
+ /** dimension → label per language. */
17
+ export declare const DIMENSION_LABEL: Record<Lang, Record<Dimension, string>>;
18
+ /** Messages shared by checks and the report renderer. */
19
+ export declare const T: {
20
+ readonly zh: {
21
+ readonly pass: '通过';
22
+ readonly warn: '警告';
23
+ readonly fail: '失败';
24
+ readonly skip: '跳过';
25
+ readonly verdictPass: 'PASS';
26
+ readonly verdictWarn: 'WARN';
27
+ readonly verdictFail: 'FAIL';
28
+ readonly gateDenyTitle: '门禁 DENY:此插件未通过供应链检查,安装已被策略拒绝';
29
+ readonly gateDenyBody: '请加载 supply-chain-review / dependency-audit 技能人工深审;或由可信维护者修改门禁策略后重试。';
30
+ readonly gateWarnTitle: '门禁警告:plugin_vet 结果为 FAIL,强烈建议停止安装';
31
+ readonly gateWarnBody: '默认策略 warn 不阻断。继续安装前请按下方 skill 引用人工深审,确认风险可接受。';
32
+ readonly followup: '人工深审建议(加载对应技能继续)';
33
+ readonly budget: '扫描预算';
34
+ readonly budgetTruncated: '扫描被预算截断:结果不完整';
35
+ readonly offline: '离线/受限';
36
+ readonly evidence: '证据';
37
+ };
38
+ readonly en: {
39
+ readonly pass: 'pass';
40
+ readonly warn: 'warn';
41
+ readonly fail: 'fail';
42
+ readonly skip: 'skip';
43
+ readonly verdictPass: 'PASS';
44
+ readonly verdictWarn: 'WARN';
45
+ readonly verdictFail: 'FAIL';
46
+ readonly gateDenyTitle: 'Gate DENY: this plugin failed the supply-chain checks; installation is blocked by policy';
47
+ readonly gateDenyBody: 'Load the supply-chain-review / dependency-audit skills for a manual deep-dive, or have a trusted maintainer change the gate policy and retry.';
48
+ readonly gateWarnTitle: 'Gate warning: plugin_vet returned FAIL — installation is strongly discouraged';
49
+ readonly gateWarnBody: 'The default policy is warn (non-blocking). Before continuing the install, follow the skill references below for a manual review and confirm the risk is acceptable.';
50
+ readonly followup: 'Manual deep-dive (load these skills to continue)';
51
+ readonly budget: 'Scan budget';
52
+ readonly budgetTruncated: 'Scan truncated by budget: results are incomplete';
53
+ readonly offline: 'Offline/limited';
54
+ readonly evidence: 'Evidence';
55
+ };
56
+ };
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Target resolution: one `plugin_vet` target string becomes either
3
+ * - a local directory walk,
4
+ * - a GitHub repo (API metadata + codeload tarball, ref-aware), or
5
+ * - an npm package (registry metadata + published tarball).
6
+ *
7
+ * All remote work flows through the zero-dependency fetch helpers; every
8
+ * failure is typed so the caller can mark affected checks `skip` instead of
9
+ * inventing findings.
10
+ *
11
+ * @module dsh-skill-pack-security/vet/source
12
+ */
13
+ import { type ScannedFile, type ScanBudget } from './walk.js';
14
+ import type { VetConfig } from './config.js';
15
+ import type { TargetKind } from './vocabulary.js';
16
+ /** GitHub repo metadata the checks consume (subset of the REST API response). */
17
+ export interface GitHubMeta {
18
+ readonly exists: boolean;
19
+ readonly defaultBranch: string;
20
+ readonly licenseSpdx: string | null;
21
+ readonly licenseName: string | null;
22
+ readonly pushedAt: string;
23
+ readonly createdAt: string;
24
+ readonly archived: boolean;
25
+ readonly stars: number;
26
+ readonly description: string;
27
+ /** The REST API was rate-limited: timestamps/stars are unavailable (files still scanned). */
28
+ readonly rateLimited: boolean;
29
+ }
30
+ /** npm registry metadata the checks consume. */
31
+ export interface NpmMeta {
32
+ readonly exists: boolean;
33
+ readonly name: string;
34
+ readonly version: string;
35
+ readonly license: string;
36
+ readonly gitHead: string;
37
+ readonly repository: string;
38
+ readonly scripts: Record<string, string>;
39
+ readonly dependencies: Record<string, string>;
40
+ readonly devDependencies: Record<string, string>;
41
+ readonly distIntegrity: string;
42
+ readonly timeModified: string;
43
+ readonly deprecated: string;
44
+ }
45
+ /** A resolved scan target: files, metadata, and identity. */
46
+ export interface ResolvedTarget {
47
+ readonly kind: TargetKind;
48
+ readonly resolved: string;
49
+ readonly ref: string;
50
+ readonly files: ScannedFile[];
51
+ readonly budget: ScanBudget;
52
+ readonly github: GitHubMeta | null;
53
+ readonly npm: NpmMeta | null;
54
+ }
55
+ /** Resolve one target string into scan inputs. Never throws for network skips; hard budget violations propagate. */
56
+ export declare function resolveTarget(raw: string, config: VetConfig, signal?: AbortSignal): Promise<ResolvedTarget>;
57
+ /** Whether a ref string is a 40-hex immutable commit. */
58
+ export declare function isCommitRef(ref: string): boolean;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Minimal gzip + ustar (POSIX tar) extractor — zero dependencies.
3
+ *
4
+ * Only the pieces needed to unpack registry/codeload tarballs: regular files,
5
+ * directories, symlinks (recorded, never followed), GNU long-name (`L`) and
6
+ * pax (`x`/`g`) extended headers. Hard constraints:
7
+ * - path traversal is rejected (absolute paths, `..`, drive letters);
8
+ * - total bytes, per-file bytes, and file count are capped;
9
+ * - symlink targets are stored as strings only (never materialized).
10
+ *
11
+ * @module dsh-skill-pack-security/vet/tar
12
+ */
13
+ /** Budget caps for one extraction. */
14
+ export interface TarBudget {
15
+ /** Hard cap on total extracted payload bytes. */
16
+ readonly maxTotalBytes: number;
17
+ /** Per-file cap; larger members are dropped and `truncated` is set. */
18
+ readonly maxFileBytes: number;
19
+ /** Hard cap on the number of extracted file members. */
20
+ readonly maxFiles: number;
21
+ }
22
+ /** One extracted member. Directories are implied by file paths. */
23
+ export interface TarEntry {
24
+ readonly path: string;
25
+ readonly content: Uint8Array;
26
+ }
27
+ /** Result of one extraction. */
28
+ export interface TarResult {
29
+ readonly files: Map<string, Uint8Array>;
30
+ readonly symlinks: Map<string, string>;
31
+ readonly truncated: boolean;
32
+ readonly totalBytes: number;
33
+ }
34
+ /** Extract one gzipped ustar archive into an in-memory file map. */
35
+ export declare function extractTarGz(gzipped: Uint8Array, budget: TarBudget): TarResult;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The `plugin_vet` tool definition: schema-validated arguments, a strictly
3
+ * validated canonical report, a model-facing markdown render, and the
4
+ * pending/completed UI cards. This is the only module in the vet engine that
5
+ * imports harness packages; everything below it is plain zero-dependency code.
6
+ *
7
+ * @module dsh-skill-pack-security/vet/tool
8
+ */
9
+ import type { VetConfig } from './config.js';
10
+ import type { Lang } from './skills.js';
11
+ /**
12
+ * Build the plugin_vet tool bound to the resolved plugin configuration.
13
+ * @param config - resolved vet configuration (defaults already applied).
14
+ * @param lang - report language, driven by the plugin's `language` config.
15
+ */
16
+ export declare function buildVetTool(config: VetConfig, lang: Lang): import("@deepseek-ai/dsh-tools").ToolDefinition;
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Shared vocabulary for the plugin_vet supply-chain gate.
3
+ *
4
+ * Everything here is plain data (JSON-safe, no live runtime objects) so the
5
+ * scan engine stays a pure, harness-free module: the tool definition in
6
+ * `tool.ts` is the only part that touches ctx/defineTool.
7
+ *
8
+ * @module dsh-skill-pack-security/vet/vocabulary
9
+ */
10
+ /** The five risk dimensions every report scores. */
11
+ export type Dimension = 'license' | 'source' | 'dependencies' | 'build-scripts' | 'maintenance';
12
+ /** Per-check and overall verdicts. `skip` = the check could not run (offline, budget). */
13
+ export type Verdict = 'pass' | 'warn' | 'fail' | 'skip';
14
+ /** One of the two gate policies. */
15
+ export type GatePolicy = 'warn' | 'deny';
16
+ /** How a scan target is addressed. */
17
+ export type TargetKind = 'github-repo' | 'local-path' | 'npm-package';
18
+ /** Stable check ids; each maps to exactly one dimension and one skill section. */
19
+ export type CheckId = 'license' | 'sbom' | 'commit-lock' | 'install-scripts' | 'network-exfil' | 'obfuscation' | 'source' | 'maintenance';
20
+ export declare const ALL_CHECK_IDS: readonly CheckId[];
21
+ /** Finding severity: fail blocks the check, warn downgrades, info is an observation. */
22
+ export type FindingLevel = 'fail' | 'warn' | 'info';
23
+ /**
24
+ * One machine-checkable finding. `skill` points at the pack skill (and its
25
+ * section) that continues the manual audit; `evidence` is a redacted, capped
26
+ * snippet or fact — never a secret, never a full file body.
27
+ */
28
+ export interface VetFinding {
29
+ readonly level: FindingLevel;
30
+ /** Short human-readable claim, in the report language. */
31
+ readonly message: string;
32
+ /** File:line location when known (e.g. `package.json:7` or `README.md:12`). */
33
+ readonly location?: string;
34
+ /** Pack skill + section to continue the manual audit, e.g. `supply-chain-review §1`. */
35
+ readonly skill: string;
36
+ /** Redacted, capped evidence text (≤ 160 chars per entry). */
37
+ readonly evidence?: string;
38
+ }
39
+ /** One executed check: verdict, findings, skill pointer, and its 0–100 dimension score. */
40
+ export interface VetCheck {
41
+ readonly id: CheckId;
42
+ readonly name: string;
43
+ readonly verdict: Verdict;
44
+ /** Why the check was skipped (offline, budget, unsupported target). */
45
+ readonly skipReason?: string;
46
+ readonly score: number;
47
+ /** All findings capped by config.maxFindingsPerCheck (truncated notes the cut). */
48
+ readonly findings: VetFinding[];
49
+ readonly truncatedFindings: boolean;
50
+ /** Primary skill + section for manual deep-dive of this check's subject. */
51
+ readonly skill: string;
52
+ }
53
+ /** One SBOM tree entry (deduped by name@version). */
54
+ export interface VetPackage {
55
+ readonly name: string;
56
+ readonly version: string;
57
+ /** Depth from the root manifest (0 = direct dependency). */
58
+ readonly depth: number;
59
+ /** License string as declared, when the lockfile/manifest carried one. */
60
+ readonly license?: string;
61
+ /** Whether the entry came from devDependencies only. */
62
+ readonly dev: boolean;
63
+ }
64
+ /** SBOM summary produced by the `sbom` check. */
65
+ export interface VetSbom {
66
+ readonly lockfile: string | null;
67
+ readonly lockfileVersion?: string;
68
+ readonly directDependencies: number;
69
+ readonly directDevDependencies: number;
70
+ readonly packages: VetPackage[];
71
+ readonly truncated: boolean;
72
+ readonly totalPackages: number;
73
+ /** Direct dependency specs that are not pinned to an exact version. */
74
+ readonly unpinned: string[];
75
+ }
76
+ /** Scorecard: the five dimensions plus the overall weighted score. */
77
+ export interface VetScores {
78
+ readonly license: number;
79
+ readonly source: number;
80
+ readonly dependencies: number;
81
+ readonly 'build-scripts': number;
82
+ readonly maintenance: number;
83
+ readonly overall: number;
84
+ }
85
+ /** Resolved target metadata recorded in the report. */
86
+ export interface VetTarget {
87
+ readonly raw: string;
88
+ readonly kind: TargetKind;
89
+ /** owner/repo for remote targets, resolved absolute path for local ones. */
90
+ readonly resolved: string;
91
+ /** Effective ref for remote targets (branch/tag/commit or npm version). */
92
+ readonly ref: string;
93
+ }
94
+ /** Gate result: policy applied and whether installation is blocked. */
95
+ export interface VetGate {
96
+ readonly policy: GatePolicy;
97
+ readonly applied: boolean;
98
+ readonly blocked: boolean;
99
+ /** One-line reason when blocked (deny policy + fail verdict). */
100
+ readonly reason?: string;
101
+ }
102
+ /** Scan budget facts so truncation is never presented as completeness. */
103
+ export interface VetBudget {
104
+ readonly filesScanned: number;
105
+ readonly filesSkipped: number;
106
+ readonly bytesScanned: number;
107
+ readonly truncated: boolean;
108
+ readonly truncatedReason?: string;
109
+ }
110
+ /** The canonical plugin_vet report (validated by the tool output schema). */
111
+ export interface VetReport {
112
+ readonly kind: 'vet-report';
113
+ readonly target: VetTarget;
114
+ readonly fetchedAt: string;
115
+ readonly checks: VetCheck[];
116
+ readonly scores: VetScores;
117
+ readonly verdict: Verdict;
118
+ readonly gate: VetGate;
119
+ readonly sbom: VetSbom;
120
+ readonly budget: VetBudget;
121
+ /** Skill names worth loading for the manual follow-up audit. */
122
+ readonly followupSkills: string[];
123
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Bounded file collection: walks a local directory or normalizes an extracted
3
+ * tarball into one shared `ScannedFile` list. Everything is budget-capped so a
4
+ * hostile or simply huge target can never exhaust memory or wall time; caps are
5
+ * reported back as truncation, never hidden.
6
+ *
7
+ * @module dsh-skill-pack-security/vet/walk
8
+ */
9
+ /** One collected file: path relative to the target root, decoded text when readable. */
10
+ export interface ScannedFile {
11
+ readonly path: string;
12
+ readonly text: string | null;
13
+ /** Binary content (NUL byte detected); text is null. */
14
+ readonly binary: boolean;
15
+ /** Files that exceeded per-file budget or failed to decode; null for normal files. */
16
+ readonly skipped: 'too-large' | 'binary' | 'decode' | null;
17
+ }
18
+ /** Budget facts so reports never present truncation as completeness. */
19
+ export interface ScanBudget {
20
+ filesScanned: number;
21
+ filesSkipped: number;
22
+ bytesScanned: number;
23
+ truncated: boolean;
24
+ truncatedReason?: string;
25
+ }
26
+ /** Normalize an extracted tarball's file map into the shared scanned-file list. */
27
+ export declare function filesFromMap(files: Map<string, Uint8Array>, maxFileBytes: number): {
28
+ files: ScannedFile[];
29
+ budget: ScanBudget;
30
+ };
31
+ /** Walk a local directory with caps; symlinks are never followed. */
32
+ export declare function walkLocal(root: string, maxFiles: number, maxFileBytes: number): Promise<{
33
+ files: ScannedFile[];
34
+ budget: ScanBudget;
35
+ }>;
36
+ /** Resolve the strip-prefix of a codeload/npm tarball (its single top-level dir). */
37
+ export declare function stripRoot(files: Map<string, Uint8Array>): string;
@@ -4,13 +4,17 @@ description: '依赖供应链审计:pnpm/npm audit 输出与退出码解读、
4
4
  whenToUse: '用户要求审计或盘点项目依赖安全(漏洞、license、投毒、锁文件漂移)、解读 audit 报告、判断某个依赖能否引入,或写依赖审计结论时使用;单个依赖的普通升级与纯功能开发不触发本技能。'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
 
10
10
  # 依赖审计(dependency-audit)
11
11
 
12
12
  目标:对仓库依赖面给出**每条结论都附命令证据**的审计结果。输出分七块:已知漏洞、license、投毒风险、锁文件漂移、多生态漏洞、SBOM 清单、provenance/签名。
13
13
 
14
+ ## 自动化预检:plugin_vet 工具
15
+
16
+ `plugin_vet` 已自动执行本技能第 3/4/7 节的静态部分(license 判定、投毒清单、SBOM 依赖树),其结果逐条引用本技能小节编号。自动化命中后,按各节命令复核证据并排除误报。
17
+
14
18
  ## 1. 定位包管理器与锁文件
15
19
 
16
20
  ```sh
@@ -4,7 +4,7 @@ description: 'agent 环境安全事件响应:分类→控制蔓延→取证留
4
4
  whenToUse: 'agent 环境(DSH 会话、插件、MCP、CI)出现疑似安全事件——密钥泄露、被注入执行了未授权操作、依赖投毒、权限异常——需要响应、留证与复盘时使用;没有事件迹象的日常开发不触发本技能。'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
 
10
10
  # 事件响应(incident-response)
@@ -4,7 +4,7 @@ description: '面向 agent 项目的提示注入面审查:AGENTS.md、技能
4
4
  whenToUse: '审查 agent 项目的上下文注入面(AGENTS.md/CLAUDE.md、.agents/skills、工具描述、MCP server 来源、web 抓取链路)、评估间接注入风险或对 agent 项目做安全评审时使用;与模型上下文无关的普通代码评审不触发本技能。'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
 
10
10
  # 提示注入面审查(prompt-injection-review)
@@ -4,7 +4,7 @@ description: '凭据/密钥暴露审计:gitleaks、trivy 全历史扫描命令
4
4
  whenToUse: '用户要求扫描或检查仓库的密钥泄露、排查某提交或某文件中的 token、给扫描告警定真伪、写脱敏泄露报告或规划密钥轮换时使用;纯功能开发与常规代码审查不触发本技能。'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
 
10
10
  # 凭据扫描(secret-scan)
@@ -4,7 +4,7 @@ description: '仓库/软件安全审计总览:范围界定→资产清单→
4
4
  whenToUse: '用户要求对代码仓库或项目做安全审计、制定审计计划、划分审计阶段、汇总多类发现成报告,或不确定该从哪个专项技能开始时使用;单一主题任务(只查密钥、只查依赖、只评审一个 PR、只查注入面)直接加载对应专项技能,不触发本技能。'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
 
10
10
  # 安全审计总览(security-audit)
@@ -12,6 +12,10 @@ metadata:
12
12
  本技能编排一次仓库安全审计的完整流程,产出**每条发现都能用一条命令复核**的报告。
13
13
  它只编排;四类主题的检查细节分别在 `secret-scan`(密钥)、`dependency-audit`(依赖)、`supply-chain-review`(新增依赖评审)、`prompt-injection-review`(agent 项目注入面)中。进入相应阶段时,用 `skill` 工具按需加载对应专项技能,不要在本文件里重写其细节。
14
14
 
15
+ ## 自动化预检:plugin_vet 工具
16
+
17
+ 本包 provider 同时注册 `plugin_vet` 工具(license 扫描 / SBOM / commit 锁定 / 恶意模式 / 五维评分)。它只做机器预检,结果中每条 finding 都标注本包对应技能小节,命中后按本技能流程继续人工审计;工具结果 fail 且门禁策略为 deny 时安装被阻断。
18
+
15
19
  ## 阶段 0:固定审计对象(不固定对象,报告不可复现)
16
20
 
17
21
  ```sh
@@ -4,13 +4,17 @@ description: 'PR/新依赖快速供应链评审:危险 install/postinstall 脚
4
4
  whenToUse: '评审含新依赖(package.json/锁文件变更)的 PR、审查某包的 install 脚本行为、判断疑似 typosquat 包或验证构建可复现性时使用;纯业务代码、与新增依赖无关的 PR 评审不触发本技能。'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
 
10
10
  # 新增依赖快速评审(supply-chain-review)
11
11
 
12
12
  目标:在 PR 评审时间内(几分钟)对新增依赖给出 **通过 / 要求修改 / 阻断** 三档结论;每条结论必须附命令证据与误报排除说明。
13
13
 
14
+ ## 自动化预检:plugin_vet 工具
15
+
16
+ `plugin_vet` 已自动执行本技能第 1/2/3 节的静态部分(危险 install 脚本、网络回传、混淆载荷、commit/action 锁定),其结果逐条引用本技能小节编号。自动化命中后,按各节的误报判据与放行判据人工确认,再下三档结论。
17
+
14
18
  ## 0. 确认范围
15
19
 
16
20
  ```sh
@@ -4,7 +4,7 @@ description: '新功能/新系统的轻量威胁建模:固定对象→划定
4
4
  whenToUse: '用户要求对新功能/新系统做威胁建模、设计阶段安全评审、STRIDE 分析、攻击树分析,或要求把安全考虑前置到设计阶段时使用;纯实现细节讨论、与信任边界无关的改动不触发本技能。'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
 
10
10
  # 威胁建模(threat-model)
@@ -4,7 +4,7 @@ description: '漏洞情报检索与判定:NVD/CISA-KEV/GHSA/OSV 四处权威
4
4
  whenToUse: '用户给出 CVE/GHSA 编号要求查详情与影响、判断漏洞是否被在野利用(KEV)、评估漏洞对当前项目/依赖的适用性或汇总漏洞情报简报时使用;没有具体编号的通用安全学习、与特定漏洞无关的讨论不触发本技能。'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
 
10
10
  # 漏洞情报(vuln-intel)
@@ -4,12 +4,16 @@ description: 'Dependency supply-chain audit: reading pnpm/npm audit output and e
4
4
  whenToUse: 'Use when the user asks to audit or inventory project dependency security (vulnerabilities, licenses, poisoning, lockfile drift), to interpret an audit report, to judge whether a dependency may be introduced, or to write a dependency-audit conclusion. Upgrading a single dependency and plain feature development do not trigger this skill.'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
  # Dependency audit (dependency-audit)
10
10
 
11
11
  Goal: produce an audit of the repository's dependency surface in which **every conclusion carries command evidence**. The output has seven blocks: known vulnerabilities, licenses, poisoning risk, lockfile drift, multi-ecosystem vulnerabilities, the SBOM inventory, and provenance/signatures.
12
12
 
13
+ ## Automated pre-check: the plugin_vet tool
14
+
15
+ `plugin_vet` already runs the static parts of sections 3/4/7 (license verdicts, the poisoning checklist, the SBOM dependency tree), and its findings cite those section numbers. After an automated hit, verify the evidence and rule out false positives with each section's commands.
16
+
13
17
  ## 1. Locate the package manager and lockfile
14
18
 
15
19
  ```sh
@@ -4,7 +4,7 @@ description: 'Security incident response for agent environments: a staged flow o
4
4
  whenToUse: 'Use when an agent environment (DSH sessions, plugins, MCP, CI) shows a suspected security incident — secret leak, injected execution of unauthorized actions, dependency poisoning, permission anomalies — and it needs response, evidence, and a postmortem. Day-to-day development without incident indicators does not trigger this skill.'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
 
10
10
  # Incident response (incident-response)
@@ -4,7 +4,7 @@ description: 'Injection-surface review for agent projects: a checklist covering
4
4
  whenToUse: 'Use when reviewing the context injection surfaces of an agent project (AGENTS.md/CLAUDE.md, .agents/skills, tool descriptions, MCP server sources, web-fetch chains), assessing indirect-injection risk, or doing a security review of an agent project. Ordinary code review unrelated to model context does not trigger this skill.'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
  # Prompt-injection surface review (prompt-injection-review)
10
10
 
@@ -4,7 +4,7 @@ description: 'Credential/secret exposure audit: gitleaks and trivy full-history
4
4
  whenToUse: 'Use when the user asks to scan or inspect a repository for secret leaks, to hunt tokens in a commit or file, to tier scan alerts as real or false, to write a redacted leak report, or to plan secret rotation. Plain feature development and ordinary code review do not trigger this skill.'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
  # Secret scanning (secret-scan)
10
10
 
@@ -4,12 +4,16 @@ description: 'Repository/software security audit overview: a staged flow of scop
4
4
  whenToUse: 'Use when the user asks for a security audit of a code repository or project, an audit plan, staged audit steps, a consolidated findings report, or is unsure which specialist skill to start with. Single-topic tasks (only secrets, only dependencies, only one PR, only injection surfaces) load the matching specialist skill directly and do not trigger this overview.'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
  # Security audit overview (security-audit)
10
10
 
11
11
  This skill orchestrates the complete flow of one repository security audit and produces a report in which **every finding can be re-verified with a single command**. It only orchestrates; the check details for the four topics live in `secret-scan` (secrets), `dependency-audit` (dependencies), `supply-chain-review` (new-dependency review), and `prompt-injection-review` (injection surfaces of agent projects). When a stage is reached, load the matching specialist skill on demand with the `skill` tool — do not rewrite its details here.
12
12
 
13
+ ## Automated pre-check: the plugin_vet tool
14
+
15
+ The pack's provider also registers the `plugin_vet` tool (license scan / SBOM / commit pinning / malicious patterns / five-dimension scoring). It performs only machine pre-checks; every finding cites the matching skill section of this pack, and after a hit you continue with this skill's manual audit flow. A FAIL verdict under a deny gate policy blocks installation.
16
+
13
17
  ## Stage 0: fix the audit target (an unfixed target makes the report unreproducible)
14
18
 
15
19
  ```sh
@@ -4,12 +4,16 @@ description: 'Quick PR/new-dependency supply-chain review: dangerous install/pos
4
4
  whenToUse: 'Use when reviewing a PR that adds new dependencies (package.json/lockfile changes), inspecting a package install-script behavior, judging a suspected typosquat package, or verifying build reproducibility. Plain business-code PR reviews unrelated to new dependencies do not trigger this skill.'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
  # New-dependency quick review (supply-chain-review)
10
10
 
11
11
  Goal: within PR-review time (minutes), give each new dependency a **pass / request changes / block** verdict; every verdict must carry command evidence and a false-positive exclusion note.
12
12
 
13
+ ## Automated pre-check: the plugin_vet tool
14
+
15
+ `plugin_vet` already runs the static parts of sections 1/2/3 (dangerous install scripts, network exfiltration, obfuscated payloads, commit/action pinning), and its findings cite those section numbers. After an automated hit, apply each section's false-positive and allowlist criteria manually before giving the three-tier verdict.
16
+
13
17
  ## 0. Confirm the scope
14
18
 
15
19
  ```sh
@@ -4,7 +4,7 @@ description: 'Lightweight threat modeling for new features/systems: fix the targ
4
4
  whenToUse: 'Use when the user asks for threat modeling of a new feature/system, design-stage security review, STRIDE analysis, attack-tree analysis, or wants security considered up front at design time. Pure implementation detail discussions and changes unrelated to trust boundaries do not trigger this skill.'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
 
10
10
  # Threat modeling (threat-model)
@@ -4,7 +4,7 @@ description: 'Vulnerability intelligence lookup and triage: query commands for t
4
4
  whenToUse: 'Use when the user gives a CVE/GHSA id and asks for details and impact, whether a vulnerability is actively exploited (KEV), its applicability to the current project/dependencies, or a vulnerability intelligence brief. General security learning without a specific id, and discussions unrelated to a specific vulnerability, do not trigger this skill.'
5
5
  metadata:
6
6
  pack: dsh-skill-pack-security
7
- version: '1.3.0'
7
+ version: '2.0.0'
8
8
  ---
9
9
 
10
10
  # Vulnerability intelligence (vuln-intel)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@perrylink/dsh-skill-pack-security-provider",
3
- "version": "1.3.0",
4
- "description": "Optional provider plugin for dsh-skill-pack-security: registers the pack's skills/ (zh) or skills-en/ (en) edition on ctx.skills. Ships both editions embedded in pack/.",
3
+ "version": "2.0.0",
4
+ "description": "Provider plugin for dsh-skill-pack-security: registers the pack's skills/ (zh) or skills-en/ (en) edition on ctx.skills AND the plugin_vet supply-chain gate tool on ctx.tools (license/SBOM/commit-lock/malware scans + five-dimension risk card). Ships both skill editions embedded in pack/.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/types/index.d.ts",
@@ -21,6 +21,45 @@
21
21
  "patch": "./cordis.patch.yml"
22
22
  }
23
23
  },
24
+ "dshWorkshop": {
25
+ "schema": "omdsh-workshop-package/v1",
26
+ "type": "plugin",
27
+ "integration": {
28
+ "protocol": "harness-profile",
29
+ "artifact": "cordis.patch.yml"
30
+ },
31
+ "install": {
32
+ "mode": "transactional",
33
+ "adapter": "profile-bundle",
34
+ "failurePolicy": "generation-rollback",
35
+ "touchesCurrentBeforeActivation": false
36
+ },
37
+ "lifecycle": {
38
+ "activation": "restart-profile",
39
+ "dispose": "supported"
40
+ },
41
+ "permissions": [
42
+ "files:read",
43
+ "network:fetch"
44
+ ],
45
+ "compatibility": {
46
+ "dshVersions": [
47
+ "0.1.0-rc.6"
48
+ ]
49
+ },
50
+ "capability": {
51
+ "id": "skill-pack-security",
52
+ "kind": "tool-bundle+provider",
53
+ "invocation": "boot the RC.6 candidate Profile with the bundle mounted (config.language zh|en), call ctx.skills.get('security-audit') through the @deepseek-ai/dsh-skill-filesystem provider contract, and execute the plugin_vet tool against a GitHub owner/repo target",
54
+ "expected": "ctx.skills.get('security-audit') resolves the mounted edition AND ctx.tools has plugin_vet, whose report cites skill sections for manual follow-up"
55
+ },
56
+ "evidence": {
57
+ "install": null,
58
+ "failureIsolation": null,
59
+ "hotReload": null,
60
+ "remove": null
61
+ }
62
+ },
24
63
  "license": "Apache-2.0",
25
64
  "keywords": [
26
65
  "dsh",
@@ -35,18 +74,20 @@
35
74
  "peerDependencies": {
36
75
  "@deepseek-ai/cordis": "^4.0.1",
37
76
  "@deepseek-ai/dsh-skill-filesystem": "0.1.0-rc.6",
77
+ "@deepseek-ai/dsh-tools": ">=0.0.1-rc.1 <0.2.0",
38
78
  "@deepseek-ai/schemastery": "^3.18.1"
39
79
  },
40
80
  "devDependencies": {
41
81
  "@deepseek-ai/cordis": "^4.0.1",
82
+ "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
42
83
  "@deepseek-ai/dsh-skill-filesystem": "0.1.0-rc.6",
84
+ "@deepseek-ai/dsh-tools": "0.1.0-rc.6",
43
85
  "@deepseek-ai/schemastery": "^3.18.1",
44
- "@types/node": "^22.15.0",
45
- "typescript": "^5.7.0"
86
+ "@types/node": "^26.2.0",
87
+ "typescript": "^7.0.2"
46
88
  },
47
89
  "scripts": {
48
90
  "build": "tsc --noEmitOnError",
49
- "typecheck": "tsc --noEmit",
50
- "prepack": "node scripts/copy-skills.mjs"
91
+ "typecheck": "tsc --noEmit"
51
92
  }
52
- }
93
+ }