@promptci/core 0.0.1 → 0.2.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/LICENSE +201 -201
- package/README.md +29 -30
- package/dist/action-pinning.d.ts +37 -0
- package/dist/action-pinning.d.ts.map +1 -0
- package/dist/action-pinning.js +277 -0
- package/dist/action-pinning.js.map +1 -0
- package/dist/agent-practices.d.ts +3 -1
- package/dist/agent-practices.d.ts.map +1 -1
- package/dist/agent-practices.js +198 -94
- package/dist/agent-practices.js.map +1 -1
- package/dist/ai-config.d.ts +178 -0
- package/dist/ai-config.d.ts.map +1 -0
- package/dist/ai-config.js +721 -0
- package/dist/ai-config.js.map +1 -0
- package/dist/alias-files.d.ts +33 -0
- package/dist/alias-files.d.ts.map +1 -0
- package/dist/alias-files.js +60 -0
- package/dist/alias-files.js.map +1 -0
- package/dist/baseline.d.ts +17 -1
- package/dist/baseline.d.ts.map +1 -1
- package/dist/baseline.js +5 -1
- package/dist/baseline.js.map +1 -1
- package/dist/buried-critical.d.ts +17 -0
- package/dist/buried-critical.d.ts.map +1 -0
- package/dist/buried-critical.js +107 -0
- package/dist/buried-critical.js.map +1 -0
- package/dist/canonical-owner.d.ts.map +1 -1
- package/dist/canonical-owner.js +60 -30
- package/dist/canonical-owner.js.map +1 -1
- package/dist/ci-alignment.d.ts.map +1 -1
- package/dist/ci-alignment.js +3 -2
- package/dist/ci-alignment.js.map +1 -1
- package/dist/command-validity.d.ts +16 -0
- package/dist/command-validity.d.ts.map +1 -1
- package/dist/command-validity.js +387 -134
- package/dist/command-validity.js.map +1 -1
- package/dist/conflicts.d.ts.map +1 -1
- package/dist/conflicts.js +4 -44
- package/dist/conflicts.js.map +1 -1
- package/dist/context-analysis.d.ts.map +1 -1
- package/dist/context-analysis.js +13 -2
- package/dist/context-analysis.js.map +1 -1
- package/dist/context-bloat.d.ts +20 -1
- package/dist/context-bloat.d.ts.map +1 -1
- package/dist/context-bloat.js +99 -15
- package/dist/context-bloat.js.map +1 -1
- package/dist/context-optimizer.d.ts.map +1 -1
- package/dist/context-optimizer.js +18 -54
- package/dist/context-optimizer.js.map +1 -1
- package/dist/copilot-instructions-detector.d.ts +24 -0
- package/dist/copilot-instructions-detector.d.ts.map +1 -0
- package/dist/copilot-instructions-detector.js +145 -0
- package/dist/copilot-instructions-detector.js.map +1 -0
- package/dist/cursor-rules-detector.d.ts +17 -0
- package/dist/cursor-rules-detector.d.ts.map +1 -0
- package/dist/cursor-rules-detector.js +110 -0
- package/dist/cursor-rules-detector.js.map +1 -0
- package/dist/custom-rules.d.ts +52 -0
- package/dist/custom-rules.d.ts.map +1 -0
- package/dist/custom-rules.js +303 -0
- package/dist/custom-rules.js.map +1 -0
- package/dist/dead-references.d.ts +8 -2
- package/dist/dead-references.d.ts.map +1 -1
- package/dist/dead-references.js +315 -68
- package/dist/dead-references.js.map +1 -1
- package/dist/dependency-staleness.d.ts +35 -0
- package/dist/dependency-staleness.d.ts.map +1 -0
- package/dist/dependency-staleness.js +1001 -0
- package/dist/dependency-staleness.js.map +1 -0
- package/dist/detectors.d.ts +1 -3
- package/dist/detectors.d.ts.map +1 -1
- package/dist/detectors.js +74 -56
- package/dist/detectors.js.map +1 -1
- package/dist/duplicates.d.ts.map +1 -1
- package/dist/duplicates.js +15 -9
- package/dist/duplicates.js.map +1 -1
- package/dist/evidence.d.ts +39 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +78 -0
- package/dist/evidence.js.map +1 -0
- package/dist/finding-id.d.ts +21 -0
- package/dist/finding-id.d.ts.map +1 -0
- package/dist/finding-id.js +31 -0
- package/dist/finding-id.js.map +1 -0
- package/dist/fix-engine.d.ts +11 -0
- package/dist/fix-engine.d.ts.map +1 -1
- package/dist/fix-engine.js +88 -71
- package/dist/fix-engine.js.map +1 -1
- package/dist/frameworks/dotnet.js +2 -2
- package/dist/frameworks/dotnet.js.map +1 -1
- package/dist/frameworks/python.d.ts.map +1 -1
- package/dist/frameworks/python.js +5 -2
- package/dist/frameworks/python.js.map +1 -1
- package/dist/frameworks/rust.d.ts.map +1 -1
- package/dist/frameworks/rust.js +2 -1
- package/dist/frameworks/rust.js.map +1 -1
- package/dist/git-symlinks.d.ts +30 -0
- package/dist/git-symlinks.d.ts.map +1 -0
- package/dist/git-symlinks.js +161 -0
- package/dist/git-symlinks.js.map +1 -0
- package/dist/gitignore.d.ts +22 -0
- package/dist/gitignore.d.ts.map +1 -0
- package/dist/gitignore.js +157 -0
- package/dist/gitignore.js.map +1 -0
- package/dist/health-score.d.ts.map +1 -1
- package/dist/health-score.js +35 -5
- package/dist/health-score.js.map +1 -1
- package/dist/hooks-settings-detector.d.ts +17 -0
- package/dist/hooks-settings-detector.d.ts.map +1 -0
- package/dist/hooks-settings-detector.js +228 -0
- package/dist/hooks-settings-detector.js.map +1 -0
- package/dist/index.d.ts +29 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -6
- package/dist/index.js.map +1 -1
- package/dist/makefile.d.ts +37 -0
- package/dist/makefile.d.ts.map +1 -0
- package/dist/makefile.js +156 -0
- package/dist/makefile.js.map +1 -0
- package/dist/manifest-consistency.d.ts +6 -0
- package/dist/manifest-consistency.d.ts.map +1 -1
- package/dist/manifest-consistency.js +75 -10
- package/dist/manifest-consistency.js.map +1 -1
- package/dist/markdown-fences.d.ts +112 -0
- package/dist/markdown-fences.d.ts.map +1 -0
- package/dist/markdown-fences.js +174 -0
- package/dist/markdown-fences.js.map +1 -0
- package/dist/mcp-config-detector.d.ts +20 -0
- package/dist/mcp-config-detector.d.ts.map +1 -0
- package/dist/mcp-config-detector.js +237 -0
- package/dist/mcp-config-detector.js.map +1 -0
- package/dist/missing-context.d.ts.map +1 -1
- package/dist/missing-context.js +2 -52
- package/dist/missing-context.js.map +1 -1
- package/dist/model-budgets.d.ts +69 -0
- package/dist/model-budgets.d.ts.map +1 -0
- package/dist/model-budgets.js +110 -0
- package/dist/model-budgets.js.map +1 -0
- package/dist/negative-instructions.d.ts +26 -0
- package/dist/negative-instructions.d.ts.map +1 -0
- package/dist/negative-instructions.js +169 -0
- package/dist/negative-instructions.js.map +1 -0
- package/dist/path-containment.d.ts +41 -0
- package/dist/path-containment.d.ts.map +1 -0
- package/dist/path-containment.js +123 -0
- package/dist/path-containment.js.map +1 -0
- package/dist/project-type.d.ts +12 -2
- package/dist/project-type.d.ts.map +1 -1
- package/dist/project-type.js +25 -12
- package/dist/project-type.js.map +1 -1
- package/dist/prompt-cache.d.ts.map +1 -1
- package/dist/prompt-cache.js +33 -24
- package/dist/prompt-cache.js.map +1 -1
- package/dist/promptci-gitignore.d.ts +34 -0
- package/dist/promptci-gitignore.d.ts.map +1 -0
- package/dist/promptci-gitignore.js +42 -0
- package/dist/promptci-gitignore.js.map +1 -0
- package/dist/repo-context.d.ts +80 -0
- package/dist/repo-context.d.ts.map +1 -1
- package/dist/repo-context.js +170 -16
- package/dist/repo-context.js.map +1 -1
- package/dist/report.d.ts +8 -0
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +163 -63
- package/dist/report.js.map +1 -1
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +47 -4
- package/dist/scan.js.map +1 -1
- package/dist/scanner.d.ts +61 -1
- package/dist/scanner.d.ts.map +1 -1
- package/dist/scanner.js +367 -70
- package/dist/scanner.js.map +1 -1
- package/dist/security-pack.d.ts +20 -0
- package/dist/security-pack.d.ts.map +1 -1
- package/dist/security-pack.js +33 -14
- package/dist/security-pack.js.map +1 -1
- package/dist/skill-supply-chain.d.ts +132 -0
- package/dist/skill-supply-chain.d.ts.map +1 -0
- package/dist/skill-supply-chain.js +2954 -0
- package/dist/skill-supply-chain.js.map +1 -0
- package/dist/skills-detector.d.ts +23 -0
- package/dist/skills-detector.d.ts.map +1 -0
- package/dist/skills-detector.js +279 -0
- package/dist/skills-detector.js.map +1 -0
- package/dist/stale-instructions.d.ts +4 -1
- package/dist/stale-instructions.d.ts.map +1 -1
- package/dist/stale-instructions.js +53 -55
- package/dist/stale-instructions.js.map +1 -1
- package/dist/subagents-detector.d.ts +19 -0
- package/dist/subagents-detector.d.ts.map +1 -0
- package/dist/subagents-detector.js +155 -0
- package/dist/subagents-detector.js.map +1 -0
- package/dist/suppression.d.ts +2 -0
- package/dist/suppression.d.ts.map +1 -1
- package/dist/suppression.js +16 -47
- package/dist/suppression.js.map +1 -1
- package/dist/types.d.ts +62 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +47 -1
- package/dist/types.js.map +1 -1
- package/dist/vague-guidance.d.ts +15 -2
- package/dist/vague-guidance.d.ts.map +1 -1
- package/dist/vague-guidance.js +44 -41
- package/dist/vague-guidance.js.map +1 -1
- package/dist/windsurf-detector.d.ts +22 -0
- package/dist/windsurf-detector.d.ts.map +1 -0
- package/dist/windsurf-detector.js +96 -0
- package/dist/windsurf-detector.js.map +1 -0
- package/dist/within-section-dedup.d.ts +16 -0
- package/dist/within-section-dedup.d.ts.map +1 -0
- package/dist/within-section-dedup.js +148 -0
- package/dist/within-section-dedup.js.map +1 -0
- package/dist/workspace-manifests.d.ts +80 -0
- package/dist/workspace-manifests.d.ts.map +1 -0
- package/dist/workspace-manifests.js +333 -0
- package/dist/workspace-manifests.js.map +1 -0
- package/package.json +11 -8
- package/dist/cheap-model-routing.d.ts +0 -4
- package/dist/cheap-model-routing.d.ts.map +0 -1
- package/dist/cheap-model-routing.js +0 -43
- package/dist/cheap-model-routing.js.map +0 -1
- package/dist/cli-output-filter.d.ts +0 -16
- package/dist/cli-output-filter.d.ts.map +0 -1
- package/dist/cli-output-filter.js +0 -88
- package/dist/cli-output-filter.js.map +0 -1
- package/dist/context-cost.d.ts +0 -4
- package/dist/context-cost.d.ts.map +0 -1
- package/dist/context-cost.js +0 -70
- package/dist/context-cost.js.map +0 -1
- package/dist/context-recommender.d.ts +0 -3
- package/dist/context-recommender.d.ts.map +0 -1
- package/dist/context-recommender.js +0 -329
- package/dist/context-recommender.js.map +0 -1
- package/dist/llm.d.ts +0 -6
- package/dist/llm.d.ts.map +0 -1
- package/dist/llm.js +0 -67
- package/dist/llm.js.map +0 -1
- package/dist/mcp-detector.d.ts +0 -4
- package/dist/mcp-detector.d.ts.map +0 -1
- package/dist/mcp-detector.js +0 -131
- package/dist/mcp-detector.js.map +0 -1
- package/dist/native-tool-preference.d.ts +0 -20
- package/dist/native-tool-preference.d.ts.map +0 -1
- package/dist/native-tool-preference.js +0 -94
- package/dist/native-tool-preference.js.map +0 -1
- package/dist/output-verbosity.d.ts +0 -3
- package/dist/output-verbosity.d.ts.map +0 -1
- package/dist/output-verbosity.js +0 -83
- package/dist/output-verbosity.js.map +0 -1
- package/dist/product-boundary.d.ts +0 -11
- package/dist/product-boundary.d.ts.map +0 -1
- package/dist/product-boundary.js +0 -301
- package/dist/product-boundary.js.map +0 -1
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import * as crypto from 'node:crypto';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* GitHub Actions pinning detector (detect-only).
|
|
5
|
+
*
|
|
6
|
+
* Flags `uses:` references in `.github/workflows/*.yml` and in composite
|
|
7
|
+
* actions (`action.yml` at the repo root or under `.github/actions/`) that
|
|
8
|
+
* point at a tag or branch instead of a full commit SHA. A tag is a mutable
|
|
9
|
+
* pointer: whoever can push to the action's repository can move it, and every
|
|
10
|
+
* workflow referencing it runs the new code on its next run. A SHA cannot be
|
|
11
|
+
* repointed.
|
|
12
|
+
*
|
|
13
|
+
* Deliberately DETECT-ONLY: there is no fix recipe and `autoApplySafe` is never
|
|
14
|
+
* set. Resolving a tag to its SHA needs a network call, and this package makes
|
|
15
|
+
* none from detector code — pinning is left to the user (or Dependabot /
|
|
16
|
+
* Renovate, which keep a pinned SHA and its version comment in step).
|
|
17
|
+
*
|
|
18
|
+
* Exempt: local actions (`./path`) and container actions (`docker://…`), which
|
|
19
|
+
* have no git ref to pin. These files are read from `workflows.sources`, never
|
|
20
|
+
* from `context.files`, so they are never treated as instruction files.
|
|
21
|
+
*
|
|
22
|
+
* Deterministic and offline: line-oriented parsing of the YAML text, no clock,
|
|
23
|
+
* no network.
|
|
24
|
+
*/
|
|
25
|
+
/** A full git commit id: 40-hex SHA-1, or 64-hex for SHA-256 repositories. */
|
|
26
|
+
const FULL_SHA_RE = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/i;
|
|
27
|
+
/** `owner/repo` or `owner/repo/sub/path` — the only action shape shown verbatim. */
|
|
28
|
+
const ACTION_RE = /^[\w.-]+\/[\w.-]+(?:\/[\w./-]+)?$/;
|
|
29
|
+
/** A plausible tag/branch name — the only version shape shown verbatim. */
|
|
30
|
+
const VERSION_RE = /^[\w./+-]+$/;
|
|
31
|
+
/**
|
|
32
|
+
* Owners whose actions GitHub itself maintains. An unpinned first-party ref is
|
|
33
|
+
* still a mutable pointer, but the account holding it is GitHub's own, so it
|
|
34
|
+
* is reported one severity lower than a third-party ref.
|
|
35
|
+
*/
|
|
36
|
+
const FIRST_PARTY_OWNERS = new Set(['actions', 'github']);
|
|
37
|
+
/** A `key: value` mapping line, optionally the first key of a list item. */
|
|
38
|
+
const KEY_LINE_RE = /^(\s*)(-\s+)?([\w.-]+)\s*:(?:\s+(.*))?$/;
|
|
39
|
+
/** A list item whose value is a flow mapping: `- { uses: x@v1, with: {...} }`. */
|
|
40
|
+
const FLOW_ITEM_RE = /^\s*-\s+(\{.*)$/;
|
|
41
|
+
/** A block scalar indicator (`|`, `>-`, `|2+`), optionally followed by a comment. */
|
|
42
|
+
const BLOCK_SCALAR_RE = /^[|>][+-]?\d*\s*(?:#.*)?$/;
|
|
43
|
+
/**
|
|
44
|
+
* Keys whose block-mapping values are free-form data, not steps. A `uses:` key
|
|
45
|
+
* nested under them (e.g. an input literally named `uses`) is not a step.
|
|
46
|
+
*/
|
|
47
|
+
const DATA_MAPPING_KEYS = new Set(['with', 'env', 'secrets', 'inputs', 'outputs']);
|
|
48
|
+
/** Strip a trailing ` # comment` and surrounding quotes from a scalar value. */
|
|
49
|
+
function scalarValue(raw) {
|
|
50
|
+
let value = raw.trim();
|
|
51
|
+
const quote = value[0];
|
|
52
|
+
if (quote === '"' || quote === "'") {
|
|
53
|
+
const end = value.indexOf(quote, 1);
|
|
54
|
+
return end > 0 ? value.slice(1, end) : value.slice(1);
|
|
55
|
+
}
|
|
56
|
+
const comment = value.search(/(?:^|\s)#/);
|
|
57
|
+
if (comment >= 0)
|
|
58
|
+
value = value.slice(0, comment);
|
|
59
|
+
return value.trim();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The value of a top-level `uses` key in a single-line flow mapping, or
|
|
63
|
+
* undefined. Nested maps (`with: { uses: … }`) are depth > 1 and ignored.
|
|
64
|
+
*/
|
|
65
|
+
function flowMappingUses(flow) {
|
|
66
|
+
const entries = [];
|
|
67
|
+
let depth = 0;
|
|
68
|
+
let quote = '';
|
|
69
|
+
let current = '';
|
|
70
|
+
for (const c of flow) {
|
|
71
|
+
if (quote) {
|
|
72
|
+
if (c === quote)
|
|
73
|
+
quote = '';
|
|
74
|
+
if (depth === 1)
|
|
75
|
+
current += c;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (c === '"' || c === "'") {
|
|
79
|
+
quote = c;
|
|
80
|
+
if (depth === 1)
|
|
81
|
+
current += c;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (c === '{' || c === '[') {
|
|
85
|
+
depth++;
|
|
86
|
+
if (depth > 1)
|
|
87
|
+
current += c;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (c === '}' || c === ']') {
|
|
91
|
+
depth--;
|
|
92
|
+
if (depth === 0)
|
|
93
|
+
break;
|
|
94
|
+
current += c;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (c === ',' && depth === 1) {
|
|
98
|
+
entries.push(current);
|
|
99
|
+
current = '';
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (depth >= 1)
|
|
103
|
+
current += c;
|
|
104
|
+
}
|
|
105
|
+
entries.push(current);
|
|
106
|
+
for (const entry of entries) {
|
|
107
|
+
const m = /^\s*uses\s*:\s*(.*)$/.exec(entry);
|
|
108
|
+
if (m)
|
|
109
|
+
return scalarValue(m[1]);
|
|
110
|
+
}
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Every step/job-level `uses:` reference in a workflow or composite-action
|
|
115
|
+
* file, in line order. Skipped: comments, lines inside block scalars (a
|
|
116
|
+
* `run: |` script that prints `uses: foo@v1`), and `uses` keys nested under
|
|
117
|
+
* data mappings such as `with:`.
|
|
118
|
+
*/
|
|
119
|
+
export function extractActionUses(content) {
|
|
120
|
+
const lines = content.split(/\r?\n/);
|
|
121
|
+
const uses = [];
|
|
122
|
+
// Lines indented deeper than this column belong to a block scalar or data
|
|
123
|
+
// mapping and are skipped; -1 = not inside one.
|
|
124
|
+
let skipDeeperThan = -1;
|
|
125
|
+
for (let i = 0; i < lines.length; i++) {
|
|
126
|
+
const line = lines[i];
|
|
127
|
+
if (line.trim() === '')
|
|
128
|
+
continue;
|
|
129
|
+
const indent = /^\s*/.exec(line)[0].length;
|
|
130
|
+
if (skipDeeperThan >= 0) {
|
|
131
|
+
if (indent > skipDeeperThan)
|
|
132
|
+
continue;
|
|
133
|
+
skipDeeperThan = -1;
|
|
134
|
+
}
|
|
135
|
+
if (/^\s*#/.test(line))
|
|
136
|
+
continue;
|
|
137
|
+
const flow = FLOW_ITEM_RE.exec(line);
|
|
138
|
+
if (flow) {
|
|
139
|
+
const ref = flowMappingUses(flow[1]);
|
|
140
|
+
if (ref)
|
|
141
|
+
uses.push({ ref, line: i + 1 });
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const kv = KEY_LINE_RE.exec(line);
|
|
145
|
+
if (!kv)
|
|
146
|
+
continue;
|
|
147
|
+
const keyCol = kv[1].length + (kv[2]?.length ?? 0);
|
|
148
|
+
const key = kv[3];
|
|
149
|
+
const rawValue = kv[4] ?? '';
|
|
150
|
+
const value = rawValue.trim();
|
|
151
|
+
if (key === 'uses') {
|
|
152
|
+
const ref = scalarValue(rawValue);
|
|
153
|
+
if (ref)
|
|
154
|
+
uses.push({ ref, line: i + 1 });
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (BLOCK_SCALAR_RE.test(value)) {
|
|
158
|
+
skipDeeperThan = keyCol;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if ((value === '' || value.startsWith('#')) && DATA_MAPPING_KEYS.has(key)) {
|
|
162
|
+
skipDeeperThan = keyCol;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return uses;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Classify one `uses:` value. Returns the parts for a remote ref that should
|
|
169
|
+
* be pinned but is not, or `undefined` when it is pinned, local, a container,
|
|
170
|
+
* or an expression.
|
|
171
|
+
*/
|
|
172
|
+
export function unpinnedUse(use) {
|
|
173
|
+
const { ref } = use;
|
|
174
|
+
if (ref.startsWith('./') || ref.startsWith('.\\'))
|
|
175
|
+
return undefined; // local action
|
|
176
|
+
if (ref.startsWith('docker://'))
|
|
177
|
+
return undefined; // container action
|
|
178
|
+
if (ref.includes('${{'))
|
|
179
|
+
return undefined; // expression — not statically resolvable
|
|
180
|
+
const at = ref.lastIndexOf('@');
|
|
181
|
+
if (at <= 0 || !ref.slice(0, at).includes('/'))
|
|
182
|
+
return undefined; // not a remote action ref
|
|
183
|
+
const action = ref.slice(0, at);
|
|
184
|
+
const version = ref.slice(at + 1);
|
|
185
|
+
if (FULL_SHA_RE.test(version))
|
|
186
|
+
return undefined;
|
|
187
|
+
const displayable = ACTION_RE.test(action) && VERSION_RE.test(version);
|
|
188
|
+
return {
|
|
189
|
+
...use,
|
|
190
|
+
displayable,
|
|
191
|
+
action,
|
|
192
|
+
version,
|
|
193
|
+
owner: displayable ? action.split('/')[0].toLowerCase() : '',
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function shortHash(value) {
|
|
197
|
+
return crypto.createHash('sha1').update(value).digest('hex').slice(0, 12);
|
|
198
|
+
}
|
|
199
|
+
/** Belt and braces for text that is shown inside Markdown code spans. */
|
|
200
|
+
function codeSafe(text) {
|
|
201
|
+
return text.replace(/`/g, "'");
|
|
202
|
+
}
|
|
203
|
+
function buildIssue(context, site) {
|
|
204
|
+
const { filePath, lines, use } = site;
|
|
205
|
+
const absPath = path.resolve(context.repoRoot, filePath);
|
|
206
|
+
const base = {
|
|
207
|
+
// One finding per (file, ref): pinning the ref in one workflow must not
|
|
208
|
+
// re-key the finding for the other files that still use it.
|
|
209
|
+
id: `action-pin-${shortHash(`action-pin:${filePath}:${use.ref}`)}`,
|
|
210
|
+
category: 'security',
|
|
211
|
+
// Absolute, like every other finding's paths; the JSON report relativizes.
|
|
212
|
+
filePaths: [absPath],
|
|
213
|
+
locations: lines.map((line) => ({ filePath: absPath, startLine: line, endLine: line })),
|
|
214
|
+
// The ref is certainly mutable; whether that matters for this repo is the
|
|
215
|
+
// heuristic part, so confidence stays below 1 and the score hit modest
|
|
216
|
+
// (and capped — see TAG_DEDUCTION_CAP in health-score.ts).
|
|
217
|
+
confidence: 0.8,
|
|
218
|
+
tags: ['supply-chain', 'github-actions'],
|
|
219
|
+
};
|
|
220
|
+
const why = "A tag or branch is a mutable pointer: whoever can push to the action's repository can move " +
|
|
221
|
+
"it, and the next run executes the new code with this repository's token and secrets.";
|
|
222
|
+
if (!use.displayable) {
|
|
223
|
+
// The raw value never reaches the title, evidence, or a shell command.
|
|
224
|
+
return {
|
|
225
|
+
...base,
|
|
226
|
+
severity: 'warning',
|
|
227
|
+
title: 'GitHub Action reference is not pinned to a commit SHA',
|
|
228
|
+
summary: `${filePath} has a \`uses:\` reference (line ${lines.join(', ')}) that is not pinned to a full ` +
|
|
229
|
+
`commit SHA and does not look like a plain \`owner/repo@ref\` value. ${why}`,
|
|
230
|
+
// No line numbers (baseline fingerprints hash evidence); a hash of the
|
|
231
|
+
// raw value keeps two different refs in one file distinct.
|
|
232
|
+
evidence: [`${filePath}: unrecognised uses: value (sha1 ${shortHash(use.ref)})`],
|
|
233
|
+
recommendation: 'Review this `uses:` line by hand. Pin the action to the full 40-character commit SHA of a ' +
|
|
234
|
+
"release you trust (resolved from the action's own repository), keep the version in a trailing " +
|
|
235
|
+
'comment, and let Dependabot or Renovate update both. PromptCI reports this but does not rewrite ' +
|
|
236
|
+
'workflow files.',
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
const firstParty = FIRST_PARTY_OWNERS.has(use.owner);
|
|
240
|
+
const [repoOwner, repoName] = use.action.split('/');
|
|
241
|
+
const ref = codeSafe(use.ref);
|
|
242
|
+
return {
|
|
243
|
+
...base,
|
|
244
|
+
severity: firstParty ? 'info' : 'warning',
|
|
245
|
+
title: `GitHub Action \`${ref}\` is not pinned to a commit SHA`,
|
|
246
|
+
summary: `${filePath} references \`${codeSafe(use.action)}\` at \`${codeSafe(use.version)}\`, which appears ` +
|
|
247
|
+
`to be a tag or branch rather than a full commit SHA. ${why} ` +
|
|
248
|
+
(firstParty
|
|
249
|
+
? 'This action is maintained by GitHub, which lowers but does not remove the risk.'
|
|
250
|
+
: 'Consider pinning third-party actions to a reviewed commit.'),
|
|
251
|
+
evidence: [`${filePath}: uses: ${ref}`],
|
|
252
|
+
recommendation: 'Pin the action to the full commit SHA of the release you trust and keep the version in a ' +
|
|
253
|
+
`trailing comment, e.g. \`uses: ${codeSafe(use.action)}@<40-char-sha> # ${codeSafe(use.version)}\`. ` +
|
|
254
|
+
`Resolve the SHA from the action's own repository (\`gh api repos/${repoOwner}/${repoName}/commits/` +
|
|
255
|
+
`${use.version} --jq .sha\`), and let Dependabot or Renovate update the SHA and comment together. ` +
|
|
256
|
+
'PromptCI reports this but does not rewrite workflow files.',
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
export function detectActionPinning(context) {
|
|
260
|
+
const sources = context.workflows.sources ?? [];
|
|
261
|
+
// Group occurrences by (file, ref): several jobs in one workflow using the
|
|
262
|
+
// same unpinned action are one fix, and one finding.
|
|
263
|
+
const sites = new Map();
|
|
264
|
+
for (const source of sources) {
|
|
265
|
+
for (const use of extractActionUses(source.content)) {
|
|
266
|
+
const unpinned = unpinnedUse(use);
|
|
267
|
+
if (!unpinned)
|
|
268
|
+
continue;
|
|
269
|
+
const key = `${source.filePath}\u0000${unpinned.ref}`;
|
|
270
|
+
const site = sites.get(key) ?? { filePath: source.filePath, lines: [], use: unpinned };
|
|
271
|
+
site.lines.push(unpinned.line);
|
|
272
|
+
sites.set(key, site);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return [...sites.keys()].sort().map((key) => buildIssue(context, sites.get(key)));
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=action-pinning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-pinning.js","sourceRoot":"","sources":["../src/action-pinning.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,13 +10,15 @@
|
|
|
10
10
|
* Checks:
|
|
11
11
|
* - Verification loop — "run lint/tests before saying done"
|
|
12
12
|
* - Honesty policy — "report failures, don't fake success"
|
|
13
|
+
* - Ask-when-unsure — "say so and ask when uncertain, don't guess"
|
|
13
14
|
* - Read-before-edit — "read a file before editing it"
|
|
14
15
|
* - Scope control — "prefer focused diffs, don't rewrite unrelated code"
|
|
16
|
+
* - Code preservation — "preserve existing code, only change what's needed"
|
|
15
17
|
* - Plan-first guidance — "outline the approach before coding"
|
|
16
18
|
* - No contradictory "do not edit" header in human-maintained files
|
|
17
19
|
*
|
|
18
20
|
* All findings are info/warning severity — these are guidance gaps, not errors.
|
|
19
21
|
*/
|
|
20
22
|
import type { InstructionFile, PromptCiIssue } from './types.js';
|
|
21
|
-
export declare function detectAgentPractices(files: InstructionFile[]): PromptCiIssue[];
|
|
23
|
+
export declare function detectAgentPractices(files: InstructionFile[], aliases?: InstructionFile[]): PromptCiIssue[];
|
|
22
24
|
//# sourceMappingURL=agent-practices.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-practices.d.ts","sourceRoot":"","sources":["../src/agent-practices.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"agent-practices.d.ts","sourceRoot":"","sources":["../src/agent-practices.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAscjE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE,OAAO,GAAE,eAAe,EAAO,GAAG,aAAa,EAAE,CAwS/G"}
|