dsh-plugin-inspector 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,6 +14,26 @@
14
14
  */
15
15
  import type { Finding } from '../model.ts';
16
16
  import type { CheckInput } from './input.ts';
17
+ /** One filesystem location that holds credentials, and how it is spelled. */
18
+ export interface CredentialPath {
19
+ readonly id: string;
20
+ /** Pattern source, matched case-insensitively anywhere in a string literal. */
21
+ readonly pattern: string;
22
+ }
23
+ /**
24
+ * Filesystem locations that hold credentials.
25
+ *
26
+ * A table rather than one regular expression so each location can be pinned by
27
+ * name: `tests/unit/rule-tables.spec.ts` iterates this export, and a location
28
+ * added without a fixture fails there.
29
+ */
30
+ export declare const CREDENTIAL_PATHS: readonly CredentialPath[];
31
+ /**
32
+ * Whether a string names a location that holds credentials.
33
+ * @param text - the literal text of a string in shipped source.
34
+ * @returns true when it names one of {@link CREDENTIAL_PATHS}.
35
+ */
36
+ export declare function matchesCredentialPath(text: string): boolean;
17
37
  /**
18
38
  * Run every Tier B check.
19
39
  * @param input - the decoded package.
@@ -82,10 +82,23 @@ export interface PatchDocument {
82
82
  * means the layer was read in part, which Tier C reports.
83
83
  */
84
84
  readonly limit: WalkLimit;
85
+ /**
86
+ * True when the layer reached at least one node twice, which is what a YAML
87
+ * alias does and what nothing else does. Tier C reports it, because a reader
88
+ * of the file sees one row where the loader sees two.
89
+ */
90
+ readonly aliased: boolean;
85
91
  }
86
- /** Nodes one patch layer may be walked through before the walk gives up. */
92
+ /**
93
+ * The two ceilings that make reading a patch layer terminate.
94
+ *
95
+ * They apply to {@link expandAliases}, and through it to everything downstream:
96
+ * the walk runs over the tree the expansion produced, which holds at most
97
+ * `MAX_WALK_NODES` nodes nested at most `MAX_WALK_DEPTH` deep, so the walk needs
98
+ * no ceiling of its own.
99
+ */
87
100
  export declare const MAX_WALK_NODES = 200000;
88
- /** Nesting one patch layer may reach before the walk gives up. */
101
+ /** Nesting one patch layer may reach before the reader gives up. */
89
102
  export declare const MAX_WALK_DEPTH = 200;
90
103
  /** Thrown when the patch file cannot be parsed as an entry list. */
91
104
  export declare class PatchParseError extends Error {
@@ -11,8 +11,18 @@
11
11
  */
12
12
  import { type RegistryProvenance, type Report, type Severity } from './model.ts';
13
13
  import { type PluginSource } from './source.ts';
14
- /** This tool's own version, reported in the JSON document. */
15
- export declare const TOOL_VERSION = "0.1.0";
14
+ /**
15
+ * This tool's own version, reported in the JSON document, by `--version`, and
16
+ * in the recorded ecosystem measurement.
17
+ *
18
+ * Read from this package's own `package.json` rather than written down a second
19
+ * time. A constant is a copy that only a release checklist keeps honest, and it
20
+ * stopped being honest for two releases: every report claimed `0.1.0` while the
21
+ * published package was `0.2.1`. The manifest sits one directory above this
22
+ * module in the source tree, in `lib/` after a build, and in the published
23
+ * tarball, so the same relative path resolves in all three.
24
+ */
25
+ export declare const TOOL_VERSION: string;
16
26
  /** This tool's package name, reported in the JSON document. */
17
27
  export declare const TOOL_NAME = "dsh-plugin-inspector";
18
28
  /**
@@ -110,6 +110,30 @@ export declare const SKILL_ROOT_CONFIG_KEYS: readonly string[];
110
110
  * only needs one of these to run code before the user has read a line of it.
111
111
  */
112
112
  export declare const INSTALL_LIFECYCLE_SCRIPTS: readonly string[];
113
+ /** One thing a lifecycle command can do that a build never needs to. */
114
+ export interface LifecycleSignal {
115
+ readonly id: string;
116
+ readonly pattern: RegExp;
117
+ /** What the match means, phrased for a report. */
118
+ readonly meaning: string;
119
+ }
120
+ /**
121
+ * Command shapes that make an install lifecycle script the attack rather than
122
+ * the build.
123
+ *
124
+ * The case this table is for is the one where the command line itself fetches,
125
+ * decodes, or evaluates: the whole attack sits in `package.json` and there is
126
+ * no shipped module to read. A lifecycle hook alone does not distinguish that
127
+ * from a build, which is why the hook is a category at `medium` and only the
128
+ * command raises it.
129
+ *
130
+ * Each pattern is chosen against the measured false-positive side rather than
131
+ * against the idea of a build script. The five packages in the pinned corpus
132
+ * that declare a hook run `tsdown`, `npm run build`, `husky`, and
133
+ * `node scripts/prepare.mjs`; running a shipped file is what a build hook is, so
134
+ * that shape is deliberately not a signal here.
135
+ */
136
+ export declare const LIFECYCLE_SIGNALS: readonly LifecycleSignal[];
113
137
  /** Entry fields the loader never interpolates: a `!!js` node here is inert data. */
114
138
  export declare const STATIC_ENTRY_FIELDS: readonly string[];
115
139
  /**
@@ -26,11 +26,20 @@ export declare const MAX_FILE_BYTES: number;
26
26
  export declare const MAX_TOTAL_BYTES: number;
27
27
  /** Largest number of files the analyzer will consider. */
28
28
  export declare const MAX_ENTRIES = 10000;
29
+ /**
30
+ * Decompressed tar bytes one tarball may produce before the read is abandoned.
31
+ *
32
+ * Eight times the in-memory ceiling. A plugin tarball is never this large, and
33
+ * one that is has already answered the only question worth asking about it.
34
+ */
35
+ export declare const MAX_STREAM_BYTES: number;
29
36
  /** The resource ceilings one read runs under. */
30
37
  export interface ReadLimits {
31
38
  readonly maxFileBytes: number;
32
39
  readonly maxTotalBytes: number;
33
40
  readonly maxEntries: number;
41
+ /** Decompressed tar bytes one tarball may produce before the read is abandoned. */
42
+ readonly maxStreamBytes: number;
34
43
  }
35
44
  /** The shipping ceilings. Tests substitute smaller ones to exercise each cap. */
36
45
  export declare const DEFAULT_LIMITS: ReadLimits;
@@ -58,13 +67,6 @@ export interface PluginSource {
58
67
  /** Working-tree files npm would not publish, and which were therefore not read. */
59
68
  readonly unpublishedFiles: number;
60
69
  }
61
- /**
62
- * Decompressed tar bytes one tarball may produce before the read is abandoned.
63
- *
64
- * Eight times the in-memory ceiling. A plugin tarball is never this large, and
65
- * one that is has already answered the only question worth asking about it.
66
- */
67
- export declare const MAX_STREAM_BYTES: number;
68
70
  /**
69
71
  * Read the package under analysis.
70
72
  * @param target - a plugin directory, or a `.tgz` / `.tar.gz` npm tarball.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-inspector",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "description": "Know what a DeepSeek Harness plugin does before you install it — static pre-install analysis of a plugin directory or tarball",
5
5
  "license": "MIT",
6
6
  "author": "Ivan Tyshchenko",