depcurfew 0.0.0-stage → 1.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/LICENSE +21 -0
- package/README.md +301 -2
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +17 -0
- package/dist/index.d.ts +609 -0
- package/dist/index.js +1 -0
- package/dist/run-D7KMlsVh.js +6595 -0
- package/package.json +67 -4
- package/schema.json +160 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DevXord
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,302 @@
|
|
|
1
|
-
#
|
|
1
|
+
# depcurfew
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
One supply-chain security policy for npm, pnpm, Yarn, Bun, Deno, Renovate and Dependabot, and a doctor that finds configuration that silently does nothing.
|
|
4
|
+
|
|
5
|
+
## Why
|
|
6
|
+
|
|
7
|
+
Package managers and update bots now each protect you against freshly published malicious versions: a release-age delay, an allow-list for install scripts, limits on git and tarball dependencies. Each tool names these settings differently, counts time in its own unit, reads them from its own files and supports them only from some version on. A setting can also look right and do nothing, for example because CI pins an older version of the package manager, or because a bot proposes versions the package manager would refuse.
|
|
8
|
+
|
|
9
|
+
depcurfew keeps one policy file, `depcurfew.json`, writes it into the configuration of every tool in the repository, and checks that the result really works.
|
|
10
|
+
|
|
11
|
+
## Five-minute start
|
|
12
|
+
|
|
13
|
+
1. `npx depcurfew init` writes `depcurfew.json` with the default policy below and lists the tools it detected.
|
|
14
|
+
2. `npx depcurfew explain` shows what it detected and what the policy means for each tool.
|
|
15
|
+
3. `npx depcurfew apply --dry-run` prints the changes as a diff, without writing anything.
|
|
16
|
+
4. `npx depcurfew apply` writes them. Run it again whenever `depcurfew.json` changes; a second run with the same policy changes nothing.
|
|
17
|
+
5. `npx depcurfew doctor` reports configuration that silently does not work and drift from the policy, and exits with 1 when it finds an error.
|
|
18
|
+
6. Add the [GitHub Action](#github-action) so that doctor runs on every push and reports to code scanning.
|
|
19
|
+
|
|
20
|
+
The default policy:
|
|
21
|
+
|
|
22
|
+
<!-- BEGIN GENERATED: default-policy -->
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"$schema": "https://unpkg.com/depcurfew/schema.json",
|
|
26
|
+
"version": 1,
|
|
27
|
+
"cooldown": {
|
|
28
|
+
"minimum": "3d",
|
|
29
|
+
"exclude": [],
|
|
30
|
+
"securityUpdates": "bypass"
|
|
31
|
+
},
|
|
32
|
+
"installScripts": {
|
|
33
|
+
"default": "deny",
|
|
34
|
+
"allow": []
|
|
35
|
+
},
|
|
36
|
+
"sources": {
|
|
37
|
+
"git": "deny",
|
|
38
|
+
"remoteTarball": "deny",
|
|
39
|
+
"file": "allow",
|
|
40
|
+
"directory": "allow"
|
|
41
|
+
},
|
|
42
|
+
"targets": "auto"
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
<!-- END GENERATED: default-policy -->
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
depcurfew needs Node.js 22 or later and has a single runtime dependency, [`yaml`](https://github.com/eemeli/yaml).
|
|
50
|
+
|
|
51
|
+
Add it to the project as a development dependency, so the team, CI and coding agents all run the version pinned in the lockfile. Once `apply` has written the project's release-age delay, later updates of depcurfew go through that delay as well:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install --save-dev depcurfew
|
|
55
|
+
npx dcf doctor
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Who needs it installed:
|
|
59
|
+
|
|
60
|
+
- **Developers working on the project:** nothing to do. The protection does not depend on depcurfew being installed: it lives in the package manager configuration that `apply` writes into the repository (`.npmrc`, `pnpm-workspace.yaml`, `.yarnrc.yml`, `bunfig.toml`, `deno.json` and the bot configuration), and the package managers read it on their own. The project install brings depcurfew along as a development dependency anyway.
|
|
61
|
+
- **Whoever changes `depcurfew.json`:** runs `npx dcf apply` and commits the result.
|
|
62
|
+
- **CI:** runs `doctor`, with the GitHub Action below or with the project's own copy on other CI systems.
|
|
63
|
+
|
|
64
|
+
A global install (`npm install -g depcurfew`) works, but teams should not rely on it: each machine may run a different version, the lockfile does not pin it, and npm does not read the project's `.npmrc` in global mode, so the project's release-age delay does not cover the install.
|
|
65
|
+
|
|
66
|
+
To work on depcurfew itself, run it from a clone of this repository:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
git clone https://github.com/DevXord/depcurfew.git
|
|
70
|
+
cd depcurfew
|
|
71
|
+
npm ci
|
|
72
|
+
npm run build
|
|
73
|
+
node dist/cli.js doctor /path/to/your/repository
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## The policy file
|
|
77
|
+
|
|
78
|
+
Every section is optional: a section that is absent means depcurfew does not manage that area. Durations are converted to each tool's own unit and always rounded up, so a tool never waits less than the policy says. Where a tool cannot express part of the policy, depcurfew says so instead of skipping it silently.
|
|
79
|
+
|
|
80
|
+
<!-- BEGIN GENERATED: policy-fields -->
|
|
81
|
+
| Field | Values | Default | Meaning |
|
|
82
|
+
| --- | --- | --- | --- |
|
|
83
|
+
| `version` | | | Version of the policy format. |
|
|
84
|
+
| `cooldown` | | | Release-age delay (cooldown): freshly published versions wait before they are used. |
|
|
85
|
+
| `cooldown.minimum` | | | Minimum age of a release before it is installed or proposed: a whole number followed by m (minutes), h (hours), d (days) or w (weeks). Converted to each tool's unit, always rounding up. |
|
|
86
|
+
| `cooldown.exclude` | | `[]` | Packages that skip the release-age delay, e.g. your own scope. |
|
|
87
|
+
| `cooldown.securityUpdates` | `"bypass"`, `"delay"` | `"bypass"` | Whether security updates skip the delay ("bypass") or wait like other updates ("delay"), where the tool can tell them apart. |
|
|
88
|
+
| `installScripts` | | | Dependency lifecycle scripts. |
|
|
89
|
+
| `installScripts.default` | `"allow"`, `"deny"` | | Whether dependency lifecycle scripts (preinstall, install, postinstall) run by default. |
|
|
90
|
+
| `installScripts.allow` | | `[]` | Packages whose lifecycle scripts may run when the default is "deny". |
|
|
91
|
+
| `sources` | | | Where dependencies may come from besides the registry. An absent field is not managed. |
|
|
92
|
+
| `sources.git` | `"allow"`, `"deny"` | | Dependencies installed from git repositories. |
|
|
93
|
+
| `sources.remoteTarball` | `"allow"`, `"deny"` | | Dependencies installed from tarball URLs outside the registry. |
|
|
94
|
+
| `sources.file` | `"allow"`, `"deny"` | | Dependencies installed from local tarball files. |
|
|
95
|
+
| `sources.directory` | `"allow"`, `"deny"` | | Dependencies installed from local directories. |
|
|
96
|
+
| `targets` | | `"auto"` | Tools to configure: "auto" detects them in the repository, or list them explicitly. |
|
|
97
|
+
<!-- END GENERATED: policy-fields -->
|
|
98
|
+
|
|
99
|
+
## Commands
|
|
100
|
+
|
|
101
|
+
The package installs two names for the same command: `depcurfew` and the short `dcf`, so `dcf doctor` works like `depcurfew doctor`.
|
|
102
|
+
|
|
103
|
+
| Command | What it does |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| `depcurfew init [directory] [--force]` | Writes `depcurfew.json` with the default policy; `--force` overwrites an existing one. |
|
|
106
|
+
| `depcurfew explain [directory] [--json]` | Describes the detected package managers, versions, bots and workspaces, and the policy values for each tool. |
|
|
107
|
+
| `depcurfew apply [directory] [--dry-run]` | Writes the policy into the configuration of every target tool; `--dry-run` prints a unified diff instead. |
|
|
108
|
+
| `depcurfew doctor [directory] [--json \| --sarif]` | Finds configuration that silently does not work and drift from the policy; `--sarif` prints SARIF 2.1.0 for code scanning. |
|
|
109
|
+
|
|
110
|
+
Exit codes: `0` success (warnings included), `1` an error (an invalid policy, a file that cannot be edited, a doctor finding with level error), `2` a usage error. `depcurfew <command> --help` describes a command with examples and its exit codes.
|
|
111
|
+
|
|
112
|
+
Every finding and warning says what to do about it. Text for people is colored on a terminal; `NO_COLOR=1` turns colors off and `FORCE_COLOR=1` turns them on, for example in a CI log that shows them. `--json`, `--sarif` and a diff written to a file stay plain, for programs and AI agents.
|
|
113
|
+
|
|
114
|
+
How `apply` edits files:
|
|
115
|
+
|
|
116
|
+
- It keeps comments, formatting, line endings and key order. In line-based files (INI, TOML) it writes a block between `# >>> depcurfew managed block` and `# <<< depcurfew managed block` markers and comments out older copies of the settings it manages; in YAML it marks the keys it writes with `# managed by depcurfew`; JSON files keep their comments and indentation.
|
|
117
|
+
- It never removes settings it does not manage. Allow-lists are only added to; exception lists follow the policy.
|
|
118
|
+
- If any file cannot be edited, nothing is written.
|
|
119
|
+
- It does not create bot configuration files; it creates a package manager's configuration file when it is missing.
|
|
120
|
+
|
|
121
|
+
## Supported tools
|
|
122
|
+
|
|
123
|
+
What depcurfew configures and checks for each tool, from its [knowledge base](docs/knowledge.md), where every value links to the official documentation or changelog it was verified against.
|
|
124
|
+
|
|
125
|
+
<!-- BEGIN GENERATED: tools -->
|
|
126
|
+
| Tool | Release-age delay | Exceptions | Install-script allow-list | Dependency sources | Verified |
|
|
127
|
+
| --- | --- | --- | --- | --- | --- |
|
|
128
|
+
| npm | `min-release-age` in `.npmrc` (days), since 11.10.0 | `min-release-age-exclude`, since 11.17.0 | `allowScripts` in `package.json` | git: `allow-git`<br>remote tarball: `allow-remote`<br>local tarball: `allow-file`<br>local directory: `allow-directory` | 2026-10-28 – 2026-10-29 |
|
|
129
|
+
| pnpm | `minimumReleaseAge` in `pnpm-workspace.yaml` (minutes), since 10.16.0 | `minimumReleaseAgeExclude`, since 10.16.0 | `allowBuilds` in `pnpm-workspace.yaml` | git: `blockExoticSubdeps`<br>remote tarball: `blockExoticSubdeps` | 2026-10-28 – 2026-10-29 |
|
|
130
|
+
| Yarn (Berry) | `npmMinimalAgeGate` in `.yarnrc.yml` (minutes), since 4.10.2 | `npmPreapprovedPackages`, since 4.10.0 | `dependenciesMeta.<package>.built` in `package.json` | git: `approvedGitRepositories` | 2026-10-28 – 2026-10-29 |
|
|
131
|
+
| Bun | `install.minimumReleaseAge` in `bunfig.toml` (seconds), since 1.3.0 | `install.minimumReleaseAgeExcludes`, since 1.3.0 | `trustedDependencies` in `package.json` | none | 2026-10-28 – 2026-10-29 |
|
|
132
|
+
| Deno | `minimumDependencyAge` in `deno.json`, `.npmrc` (minutes), since 2.5.5 / 2.6.0 ⚠️ | `minimumDependencyAge.exclude`, since 2.5.5 | `allowScripts` in `deno.json` | none | 2026-10-28 – 2026-10-29 |
|
|
133
|
+
| Renovate | `minimumReleaseAge` in `renovate.json`, `renovate.jsonc` … (duration string), since 35.46.0 | `packageRules: matchPackageNames + minimumReleaseAge: null`, since 35.46.0 ❓ | none | n/a | 2026-10-28 |
|
|
134
|
+
| Dependabot | `cooldown` in `.github/dependabot.yml`, `.github/dependabot.yaml` (days), since 2025 07 01 | `cooldown.exclude`, since 2025 07 01 ❓ | none | n/a | 2026-10-28 |
|
|
135
|
+
|
|
136
|
+
⚠️ official sources disagree (depcurfew takes the safer reading) · ❓ official sources are incomplete. Every value with its source: [docs/knowledge.md](docs/knowledge.md).
|
|
137
|
+
<!-- END GENERATED: tools -->
|
|
138
|
+
|
|
139
|
+
Yarn Classic (1.x) is detected but not supported.
|
|
140
|
+
|
|
141
|
+
## doctor rules
|
|
142
|
+
|
|
143
|
+
Findings have a level: an **error** makes `depcurfew doctor` exit with 1, a **warning** or a **note** does not. Things doctor could not check (a binary lockfile, a lockfile format without install-script data, a missing policy) are listed as notes after the findings, not as findings.
|
|
144
|
+
|
|
145
|
+
<!-- BEGIN GENERATED: rules -->
|
|
146
|
+
### `manager-version-too-old`
|
|
147
|
+
|
|
148
|
+
**error** · A declared package manager version is older than a setting the repository relies on.
|
|
149
|
+
|
|
150
|
+
Package managers ignore settings they do not know yet. When packageManager, devEngines, Volta, .tool-versions or a CI step pins an older version, the setting is silently not applied there.
|
|
151
|
+
|
|
152
|
+
Fix: Raise the declared version to at least the version that introduced the setting, everywhere it is declared.
|
|
153
|
+
|
|
154
|
+
### `setting-ignored-by-version`
|
|
155
|
+
|
|
156
|
+
**error** · A setting or file is ignored by the package manager version in use.
|
|
157
|
+
|
|
158
|
+
Package managers drop old settings and files in new major versions and only accept new forms from some version on. The configuration stays in the repository and looks effective while the version in use ignores it.
|
|
159
|
+
|
|
160
|
+
Fix: Move the setting to the place and form this version reads.
|
|
161
|
+
|
|
162
|
+
### `npmrc-overrides-policy`
|
|
163
|
+
|
|
164
|
+
**error** · An .npmrc file changes a security setting in a way the policy does not see, or is ignored.
|
|
165
|
+
|
|
166
|
+
Package managers read .npmrc from different places with different priorities. npm ignores the .npmrc of workspace packages, and pnpm 10 applies a root .npmrc value whenever pnpm-workspace.yaml does not set the same setting, which can weaken the policy.
|
|
167
|
+
|
|
168
|
+
Fix: Keep security settings out of .npmrc files that are ignored or that override the policy; set them through depcurfew.json and depcurfew apply.
|
|
169
|
+
|
|
170
|
+
### `pnpm-shared-workspace-lockfile`
|
|
171
|
+
|
|
172
|
+
**warning** · pnpm 10 without a shared lockfile lets a package .npmrc change the release-age delay.
|
|
173
|
+
|
|
174
|
+
With sharedWorkspaceLockfile: false, pnpm 10 installs every workspace project separately with that project's own .npmrc layered over the workspace settings (read from the pnpm 10 source code), so a setting such as minimum-release-age=0 in a package .npmrc applies to that package.
|
|
175
|
+
|
|
176
|
+
Fix: Remove security settings from package .npmrc files, or keep the default shared lockfile.
|
|
177
|
+
|
|
178
|
+
### `config-drift`
|
|
179
|
+
|
|
180
|
+
**error** · needs depcurfew.json · A configuration file does not match what depcurfew apply writes for depcurfew.json.
|
|
181
|
+
|
|
182
|
+
A generated setting was edited by hand, or depcurfew.json changed without running depcurfew apply, so the tools enforce something other than the policy.
|
|
183
|
+
|
|
184
|
+
Fix: Run depcurfew apply (depcurfew apply --dry-run shows the difference), or change depcurfew.json if the edit was intended.
|
|
185
|
+
|
|
186
|
+
### `bot-cooldown-mismatch`
|
|
187
|
+
|
|
188
|
+
**error** · An update bot waits less than the package manager before proposing a new version.
|
|
189
|
+
|
|
190
|
+
The bot then opens pull requests with versions the package manager would not pick yet: they fail to install where the manager re-checks the lockfile, or they bring in a version younger than the manager allows. Security updates that skip the bot delay fail the same way where the manager re-checks the lockfile.
|
|
191
|
+
|
|
192
|
+
Fix: Give the bot a delay at least as long as the package manager's (depcurfew apply does this).
|
|
193
|
+
|
|
194
|
+
### `broad-exclusion`
|
|
195
|
+
|
|
196
|
+
**error** · An exception list matches every package, which turns the protection off.
|
|
197
|
+
|
|
198
|
+
A release-age exception such as "*" (or a policy allow-list entry such as "@*/*") looks like a narrow exception but exempts every package, so the delay or the install-script block never applies.
|
|
199
|
+
|
|
200
|
+
Fix: Replace the pattern with the packages or scopes that really need the exception.
|
|
201
|
+
|
|
202
|
+
### `lockfile-forbidden-source`
|
|
203
|
+
|
|
204
|
+
**error** · needs depcurfew.json · The lockfile installs a package from a source depcurfew.json denies.
|
|
205
|
+
|
|
206
|
+
A git repository, a tarball URL or a local path bypasses the registry and its checks (release age, provenance, integrity from the registry). The lockfile shows what installs really fetch, whatever the package manager settings say.
|
|
207
|
+
|
|
208
|
+
Fix: Replace the dependency with a registry version, or allow that source in depcurfew.json.
|
|
209
|
+
|
|
210
|
+
### `lockfile-install-scripts`
|
|
211
|
+
|
|
212
|
+
**error** · needs depcurfew.json · The lockfile has packages with install scripts that depcurfew.json does not allow.
|
|
213
|
+
|
|
214
|
+
Install scripts run arbitrary code during installation. Where the package manager runs them by default, these packages execute code the policy does not allow; where it blocks them, they may not work without a build step. Only npm, Bun (1.4.4+) and Deno (lockfile v5) record install scripts in the lockfile.
|
|
215
|
+
|
|
216
|
+
Fix: Remove or replace the package, or add it to installScripts.allow in depcurfew.json after reviewing its scripts.
|
|
217
|
+
|
|
218
|
+
### `unreadable-config`
|
|
219
|
+
|
|
220
|
+
**error** · A configuration file or lockfile cannot be read, parsed or edited, so depcurfew cannot check it.
|
|
221
|
+
|
|
222
|
+
A package manager or bot may still read the file and its settings may weaken the policy; depcurfew fails closed and reports an error instead of passing silently.
|
|
223
|
+
|
|
224
|
+
Fix: Fix what the message describes: invalid syntax, a symlink, a file over the size limit or a style depcurfew apply cannot edit.
|
|
225
|
+
<!-- END GENERATED: rules -->
|
|
226
|
+
|
|
227
|
+
## GitHub Action
|
|
228
|
+
|
|
229
|
+
The action runs `depcurfew doctor`, prints the report to the job log, shows each finding as an annotation on its file and in a table in the job summary, each with how to fix it, uploads the SARIF report to code scanning and fails the job when doctor finds an error. It runs from its own checkout, with nothing to install, and sets up Node.js 22 only when the runner has an older version.
|
|
230
|
+
|
|
231
|
+
Pin it to a full commit SHA, like every action in your workflows. If the repository cannot use code scanning, set `upload-sarif: false`; the findings stay in the job log.
|
|
232
|
+
|
|
233
|
+
<!-- BEGIN GENERATED: action-workflow -->
|
|
234
|
+
```yaml
|
|
235
|
+
name: depcurfew
|
|
236
|
+
|
|
237
|
+
on:
|
|
238
|
+
push:
|
|
239
|
+
pull_request:
|
|
240
|
+
|
|
241
|
+
jobs:
|
|
242
|
+
doctor:
|
|
243
|
+
runs-on: ubuntu-latest
|
|
244
|
+
permissions:
|
|
245
|
+
security-events: write
|
|
246
|
+
# Only needed in private repositories:
|
|
247
|
+
actions: read
|
|
248
|
+
contents: read
|
|
249
|
+
steps:
|
|
250
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
251
|
+
with:
|
|
252
|
+
persist-credentials: false
|
|
253
|
+
- uses: DevXord/depcurfew@<full-commit-sha> # pin a commit, not a tag
|
|
254
|
+
```
|
|
255
|
+
<!-- END GENERATED: action-workflow -->
|
|
256
|
+
|
|
257
|
+
<!-- BEGIN GENERATED: action-reference -->
|
|
258
|
+
| Input | Default | Description |
|
|
259
|
+
| --- | --- | --- |
|
|
260
|
+
| `directory` | `.` | Directory to check, relative to the workspace. |
|
|
261
|
+
| `sarif-file` | `depcurfew.sarif` | Where to write the SARIF report, relative to the workspace. |
|
|
262
|
+
| `upload-sarif` | `true` | Upload the SARIF report to GitHub code scanning. The job needs the security-events write permission. |
|
|
263
|
+
| `category` | `depcurfew` | Code scanning category of the upload, to tell several depcurfew runs in one workflow apart. |
|
|
264
|
+
| `fail-on-error` | `true` | Fail the step when doctor reports an error. |
|
|
265
|
+
| `annotations` | `true` | Show the findings as annotations on the files, each with how to fix it. GitHub shows a limited number per step; the log lists every finding. Turn off when code scanning already shows them. |
|
|
266
|
+
| `job-summary` | `true` | Add a table of the findings, each with how to fix it, to the job summary. |
|
|
267
|
+
|
|
268
|
+
| Output | Description |
|
|
269
|
+
| --- | --- |
|
|
270
|
+
| `errors` | Number of findings with level error. |
|
|
271
|
+
| `warnings` | Number of findings with level warning. |
|
|
272
|
+
| `notes` | Number of findings with level note. |
|
|
273
|
+
| `sarif-file` | Path of the SARIF report, relative to the workspace; empty when doctor could not run. |
|
|
274
|
+
<!-- END GENERATED: action-reference -->
|
|
275
|
+
|
|
276
|
+
### Other CI systems
|
|
277
|
+
|
|
278
|
+
The action works only on GitHub. On GitLab CI or any other CI, install the project's dependencies without running their install scripts, so nothing from the lockfile runs before doctor has checked it, then run the depcurfew version the lockfile pins; the job fails when doctor finds an error (exit code 1):
|
|
279
|
+
|
|
280
|
+
```yaml
|
|
281
|
+
depcurfew:
|
|
282
|
+
image: node:22
|
|
283
|
+
script:
|
|
284
|
+
- npm ci --ignore-scripts
|
|
285
|
+
- npx --no depcurfew doctor
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
`--no` makes npx fail instead of downloading the latest depcurfew when the project does not have it; in CI npx otherwise downloads without asking. With pnpm, Yarn or Bun, use their frozen-lockfile install with install scripts turned off instead of `npm ci --ignore-scripts`.
|
|
289
|
+
|
|
290
|
+
`depcurfew doctor --json` and `--sarif` write the findings for other tools; set `FORCE_COLOR=1` if the CI log shows colors.
|
|
291
|
+
|
|
292
|
+
## Library
|
|
293
|
+
|
|
294
|
+
The same functions are available from the package: `detectProject`, `planApply` and `applyProject`, `runDoctor` with `toSarif`, and the policy parser and converters. See `src/index.ts`.
|
|
295
|
+
|
|
296
|
+
## Contributing
|
|
297
|
+
|
|
298
|
+
Facts about package managers live only in `src/knowledge/`, each with the official URL it was verified against and the date. A correction is welcome with a link to the official documentation or changelog. `npm test` builds the project and runs every test without network access.
|
|
299
|
+
|
|
300
|
+
## License
|
|
301
|
+
|
|
302
|
+
[MIT](LICENSE)
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { A as colorsFor, t as run } from "./run-D7KMlsVh.js";
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
run(process.argv.slice(2), {
|
|
5
|
+
stdout: (text) => process.stdout.write(text),
|
|
6
|
+
stderr: (text) => process.stderr.write(text),
|
|
7
|
+
colors: {
|
|
8
|
+
stdout: colorsFor(process.stdout, process.env),
|
|
9
|
+
stderr: colorsFor(process.stderr, process.env)
|
|
10
|
+
}
|
|
11
|
+
}).then((code) => {
|
|
12
|
+
process.exitCode = code;
|
|
13
|
+
}, (error) => {
|
|
14
|
+
process.stderr.write(`depcurfew: unexpected error: ${error instanceof Error ? error.stack : String(error)}\n`);
|
|
15
|
+
process.exitCode = 1;
|
|
16
|
+
});
|
|
17
|
+
export {};
|