depfresh 0.9.2

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vibe Code (https://vcode.sh)
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 ADDED
@@ -0,0 +1,279 @@
1
+ # depzy
2
+
3
+ [![npm version](https://img.shields.io/npm/v/depzy)](https://www.npmjs.com/package/depzy)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.9+-3178c6)](https://www.typescriptlang.org/)
6
+ [![Node.js](https://img.shields.io/badge/Node.js-24+-339933)](https://nodejs.org/)
7
+
8
+ Keep your npm dependencies fresh. Fast, correct, zero-config.
9
+
10
+ Spiritual successor to [taze](https://github.com/antfu/taze) by Anthony Fu - a tool that did the job well until maintenance slowed and issues piled up. I took the best ideas, rewrote everything from scratch, fixed the bugs that sat open for years, and made it work for humans and AI agents alike. Credit where it's due.
11
+
12
+ ## Features
13
+
14
+ - **Zero-config dependency checking** -- run `depzy` and it tells you what's outdated. No YAML. No PhD.
15
+ - **Monorepo & workspace support** -- pnpm, bun, yarn, npm. Auto-detected. Catalog deps included.
16
+ - **7 range modes** -- `default`, `major`, `minor`, `patch`, `latest`, `newest`, `next`. One flag, total control.
17
+ - **Interactive cherry-picking** -- grouped multiselect with colour-coded severity. Pick what you want, ignore the rest.
18
+ - **Per-package modes** -- `packageMode` lets you set exact, glob, or regex patterns per dependency.
19
+ - **Write safely** -- `--write` updates files. `--verify-command` tests each dep individually and reverts failures.
20
+ - **Post-write hooks** -- `--execute`, `--install`, `--update`. Chain commands after writing.
21
+ - **Global packages** -- `--global` checks npm, pnpm, and bun globals.
22
+ - **Private registries** -- full `.npmrc` support. Scoped registries, auth tokens, env vars. Fixed from day one.
23
+ - **JSON output** -- structured envelope for scripts and AI agents. No ANSI noise.
24
+ - **CI mode** -- `--fail-on-outdated` exits with code 1. Plug it into your pipeline.
25
+ - **SQLite cache** -- WAL mode, 30min TTL, auto-fallback to memory. Fast repeat runs.
26
+ - **Provenance tracking** -- warnings for unsigned or downgraded attestations.
27
+ - **Node engine compat** -- flags updates that don't match your Node version.
28
+ - **Cooldown filter** -- skip versions published less than N days ago. Let the early adopters find the bugs.
29
+ - **Sorting** -- 6 strategies: by diff severity, publish time, or name.
30
+ - **CRLF preservation** -- Windows line endings survive the write. You're welcome.
31
+ - **Nested workspace detection** -- auto-skips monorepos inside monorepos.
32
+ - **Programmatic API** -- 9 exported functions, 7 lifecycle callbacks, full type safety.
33
+
34
+ ## Why
35
+
36
+ Because `npm outdated` gives you a table and then abandons you. Because Renovate requires a PhD in YAML. Because your AI coding assistant should be able to update your deps without you holding its hand.
37
+
38
+ depzy checks every `package.json` in your project, tells you what's outdated, and optionally writes the updates. Monorepos, workspace catalogs, private registries - it handles all of it without a config file.
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ npm install -g depzy
44
+ ```
45
+
46
+ Or don't install globally. I'm not your parent.
47
+
48
+ ```bash
49
+ npx depzy
50
+ pnpm dlx depzy
51
+ bunx depzy
52
+ ```
53
+
54
+ ## Usage
55
+
56
+ ```bash
57
+ # Check for outdated dependencies
58
+ depzy
59
+
60
+ # Actually update them
61
+ depzy --write
62
+
63
+ # Interactive mode -- pick what to update like a civilised person
64
+ depzy --interactive
65
+
66
+ # Only minor/patch updates (living cautiously)
67
+ depzy minor -w
68
+
69
+ # JSON output for scripts and AI agents
70
+ depzy --output json
71
+
72
+ # Filter specific packages
73
+ depzy --include "react,vue" --exclude "eslint"
74
+
75
+ # Verify each dep individually, revert failures
76
+ depzy -w --verify-command "pnpm test"
77
+
78
+ # CI: fail if anything is outdated
79
+ depzy --fail-on-outdated
80
+ ```
81
+
82
+ ## CLI Flags
83
+
84
+ The top flags to get you started. Full reference with all 27+ flags: **[docs/cli/](docs/cli/)**
85
+
86
+ | Flag | Alias | Default | Description |
87
+ |------|-------|---------|-------------|
88
+ | `--recursive` | `-r` | `true` | Recursively search for package.json files |
89
+ | `--write` | `-w` | `false` | Write updated versions to package files |
90
+ | `--interactive` | `-I` | `false` | Select which deps to update |
91
+ | `--mode` | `-m` | `default` | Range mode: `default` `major` `minor` `patch` `latest` `newest` `next` |
92
+ | `--include` | `-n` | -- | Only include packages matching regex (comma-separated) |
93
+ | `--exclude` | `-x` | -- | Exclude packages matching regex (comma-separated) |
94
+ | `--force` | `-f` | `false` | Force update even if version is satisfied |
95
+ | `--global` | `-g` | `false` | Check global packages |
96
+ | `--output` | `-o` | `table` | Output format: `table` `json` |
97
+ | `--execute` | `-e` | -- | Run command after writing (e.g. `"pnpm test"`) |
98
+ | `--verify-command` | `-V` | -- | Run command per dep, revert on failure |
99
+ | `--install` | `-i` | `false` | Run package manager install after writing |
100
+ | `--fail-on-outdated` | -- | `false` | Exit code 1 when outdated deps found (CI mode) |
101
+ | `--cooldown` | -- | `0` | Skip versions published less than N days ago |
102
+ | `--sort` | `-s` | `diff-asc` | Sort: `diff-asc` `diff-desc` `time-asc` `time-desc` `name-asc` `name-desc` |
103
+
104
+ ## Config File
105
+
106
+ Zero config works. But if you want it, create `depzy.config.ts` (or `.depzyrc`, or add a `depzy` key to `package.json`):
107
+
108
+ ```typescript
109
+ import { defineConfig } from 'depzy'
110
+
111
+ export default defineConfig({
112
+ mode: 'minor',
113
+ exclude: ['typescript'],
114
+ packageMode: {
115
+ 'eslint': 'latest',
116
+ '/^@types/': 'patch',
117
+ },
118
+ })
119
+ ```
120
+
121
+ Full options reference: **[docs/configuration/](docs/configuration/)**
122
+
123
+ ## JSON Output
124
+
125
+ `--output json` emits a single structured envelope. No log noise. No ANSI codes. Just clean JSON that machines can parse without having an existential crisis.
126
+
127
+ ```json
128
+ {
129
+ "packages": [
130
+ {
131
+ "name": "my-app",
132
+ "updates": [
133
+ {
134
+ "name": "react",
135
+ "current": "^18.2.0",
136
+ "target": "^19.1.0",
137
+ "diff": "major",
138
+ "source": "dependencies"
139
+ }
140
+ ]
141
+ }
142
+ ],
143
+ "summary": {
144
+ "total": 12,
145
+ "major": 1,
146
+ "minor": 7,
147
+ "patch": 4,
148
+ "packages": 3
149
+ },
150
+ "meta": {
151
+ "cwd": "/path/to/project",
152
+ "mode": "default",
153
+ "timestamp": "2026-02-22T12:00:00.000Z"
154
+ }
155
+ }
156
+ ```
157
+
158
+ Full schema and field reference: **[docs/output-formats/](docs/output-formats/)**
159
+
160
+ ## AI Agent Usage
161
+
162
+ depzy was designed to work with AI coding assistants out of the box. No special configuration needed.
163
+
164
+ ```bash
165
+ # Check for updates, get structured output
166
+ depzy --output json --loglevel silent
167
+
168
+ # Apply all updates
169
+ depzy --write
170
+
171
+ # Apply only safe updates
172
+ depzy --write --mode patch
173
+
174
+ # Selective update
175
+ depzy --write --include "typescript,vitest"
176
+ ```
177
+
178
+ **Exit codes are semantic:**
179
+ - `0` -- all deps up to date (or updates were written)
180
+ - `1` -- updates available (with `--fail-on-outdated`)
181
+ - `2` -- error
182
+
183
+ **TTY detection** -- when stdout isn't a terminal (piped, captured by an agent), depzy automatically suppresses spinners and interactive prompts. `NO_COLOR` is respected.
184
+
185
+ ## Programmatic API
186
+
187
+ ```typescript
188
+ import { check, resolveConfig } from 'depzy'
189
+
190
+ const options = await resolveConfig({
191
+ cwd: process.cwd(),
192
+ mode: 'minor',
193
+ write: true,
194
+ onDependencyResolved: (pkg, dep) => {
195
+ if (dep.diff === 'major') {
196
+ console.log(`Major update: ${dep.name} ${dep.currentVersion} -> ${dep.targetVersion}`)
197
+ }
198
+ },
199
+ beforePackageWrite: (pkg) => {
200
+ return true // return false to skip
201
+ },
202
+ })
203
+
204
+ const exitCode = await check(options)
205
+ ```
206
+
207
+ 9 exported functions, 7 lifecycle callbacks, 16+ types. Full API reference: **[docs/api/](docs/api/)**
208
+
209
+ ## Monorepo Support
210
+
211
+ depzy auto-detects workspace structures. No config needed.
212
+
213
+ | Package Manager | Workspaces | Catalogs |
214
+ |----------------|------------|----------|
215
+ | pnpm | `pnpm-workspace.yaml` | `catalog:` protocol |
216
+ | Bun | `workspaces` in `package.json` | `workspaces.catalog` |
217
+ | Yarn | `workspaces` in `package.json` | `.yarnrc.yml` catalogs |
218
+ | npm | `workspaces` in `package.json` | -- |
219
+
220
+ Workspace catalogs are resolved and updated in-place. Your `pnpm-workspace.yaml` catalog entries get depzyaded alongside your `package.json` deps. No manual sync needed.
221
+
222
+ ## Private Registries
223
+
224
+ depzy reads `.npmrc` from your project and home directory. Scoped registries, auth tokens, proxies -- all respected.
225
+
226
+ ```ini
227
+ # .npmrc
228
+ @mycompany:registry=https://npm.mycompany.com/
229
+ //npm.mycompany.com/:_authToken=${NPM_TOKEN}
230
+ ```
231
+
232
+ This was broken in taze for 4+ years. I fixed it on day one. You're welcome.
233
+
234
+ ## What I Fixed from taze
235
+
236
+ Not to throw shade at taze -- it served the community well for years. But some things needed fixing, and "PR welcome" only goes so far when the PRs sit open for months.
237
+
238
+ | Problem | taze | depzy |
239
+ |---------|------|------|
240
+ | `.npmrc` / private registries | Ignored | Full support |
241
+ | Network retry | None | Exponential backoff |
242
+ | Write clobber (bun catalogs) | Data loss | Single-writer architecture |
243
+ | Version resolution ordering | Assumed sorted arrays | Explicit semver comparison |
244
+ | Interactive mode | Flickery | @clack/prompts |
245
+ | JSON output | None | Structured envelope |
246
+ | Dep type filtering | None | `--deps-only` / `--dev-only` |
247
+ | Config merging | deepmerge (CJS) | defu (ESM) |
248
+ | npm config loading | @npmcli/config (heavy, hacky) | Direct ini parsing |
249
+ | Cache | JSON file (race conditions) | SQLite with WAL mode |
250
+
251
+ ## Documentation
252
+
253
+ The full docs, for people who read manuals before assembling furniture.
254
+
255
+ - **[CLI Reference](docs/cli/)** -- all 27+ flags, modes, sorting, filtering, hooks, interactive, CI, workspaces
256
+ - **[Configuration](docs/configuration/)** -- config files, every option, packageMode, depFields, private registries, cache
257
+ - **[Programmatic API](docs/api/)** -- exported functions, lifecycle callbacks, types, workflow examples
258
+ - **[Output Formats](docs/output-formats/)** -- table, JSON, SARIF, exit codes, AI agent integration
259
+ - **[Troubleshooting](docs/troubleshooting.md)** -- common issues, workspace gotchas, known limitations
260
+
261
+ ## Requirements
262
+
263
+ - Node.js >= 24
264
+
265
+ ## Standing on the Shoulders of People Who Actually Did the Work
266
+
267
+ depzy wouldn't exist without [taze](https://github.com/antfu/taze). I rewrote everything from scratch, yes, but "from scratch" is easy when someone else already figured out what the thing should do. Every bug report, every feature PR, every typo fix in the taze repo was a free lesson in what users actually need. I just took notes and built a new house on someone else's blueprint.
268
+
269
+ So here's to every contributor who opened a PR on taze. Some of you added features I shamelessly reimplemented. Some of you fixed bugs that taught me where the landmines were. Some of you fixed typos, and honestly, that's braver than any architecture decision I've ever made.
270
+
271
+ Cheers to all of you. I owe you mass-produced coffee at minimum.
272
+
273
+ <!-- Contributors listed alphabetically by GitHub username, because favouritism is for people with better social skills than me -->
274
+
275
+ [a1mer](https://github.com/a1mersnow) · [Alex Liu](https://github.com/LarchLiu) · [Arash Sheyda](https://github.com/arashsheyda) · [await-ovo](https://github.com/await-ovo) · [Aymane Dara Hlamnach](https://github.com/azuradara) · [azaleta](https://github.com/azaleta) · [Benny Powers](https://github.com/bennypowers) · [Bruno Rocha](https://github.com/orochaa) · [btea](https://github.com/btea) · [Carter](https://github.com/Fyko) · [Charles](https://github.com/CharlesOkwuagwu) · [Daniel Bayley](https://github.com/danielbayley) · [Daniel Schmitz](https://github.com/blouflashdb) · [Dreamacro](https://github.com/Dreamacro) · [Duncan Lock](https://github.com/dflock) · [Dunqing](https://github.com/Dunqing) · [Eneko Rodr&iacute;guez](https://github.com/Nisgrak) · [Enzo Innocenzi](https://github.com/innocenzi) · [Eugene](https://github.com/outslept) · [Geoffrey Parrier](https://github.com/GeoffreyParrier) · [Han](https://github.com/hannoeru) · [Harry Yep](https://github.com/okisdev) · [Hassan Zahirnia](https://github.com/HassanZahirnia) · [hyrious](https://github.com/hyrious) · [iiio2](https://github.com/iiio2) · [Iridescent](https://github.com/Iridescent-cdu) · [Jakub Zomerfeld](https://github.com/devzom) · [Jaw](https://github.com/jaw52) · [jinghaihan](https://github.com/jinghaihan) · [Joaqu&iacute;n S&aacute;nchez](https://github.com/userquin) · [Johan Lindskogen](https://github.com/lindskogen) · [Julien Calixte](https://github.com/jcalixte) · [Kerman](https://github.com/kermanx) · [Kevin Deng](https://github.com/sxzz) · [Khalil Yao](https://github.com/yyz945947732) · [Kirk Lin](https://github.com/kirklin) · [Lo](https://github.com/LoTwT) · [Loann Neveu](https://github.com/lneveu) · [Lochlan Bunn](https://github.com/loklaan) · [mancuoj](https://github.com/mancuoj) · [Maxime Dubourg](https://github.com/mdubourg001) · [Nam Nguyen](https://github.com/willnguyen1312) · [ntnyq](https://github.com/ntnyq) · [Patryk Tomczyk](https://github.com/patzick) · [pdx](https://github.com/pdx-xf) · [Pier Dolique](https://github.com/Perdolique) · [RainbowBird](https://github.com/luoling8192) · [Renato Lacerda](https://github.com/ralacerda) · [rg](https://github.com/Gehbt) · [Riri](https://github.com/Daydreamer-riri) · [Runyasak Chaengnaimuang](https://github.com/runyasak) · [sapphi-red](https://github.com/sapphi-red) · [simexce](https://github.com/simexce) · [Simon He](https://github.com/Simon-He95) · [sinoon](https://github.com/sinoon) · [Stephen Zhou](https://github.com/hyoban) · [Sukka](https://github.com/SukkaW) · [Takuya Fukuju](https://github.com/chalkygames123) · [Tanimodori](https://github.com/Tanimodori) · [Tom&aacute;s Hern&aacute;ndez](https://github.com/THernandez03) · [tyler](https://github.com/tylersayshi) · [Vladislav Deryabkin](https://github.com/evermake) · [wChenonly](https://github.com/wChenonly) · [webdiscus](https://github.com/webdiscus) · [Wind](https://github.com/productdevbook) · [wuchao](https://github.com/jerrywu001) · [younggglcy](https://github.com/younggglcy) · [Yu Le](https://github.com/yuler)
276
+
277
+ ## License
278
+
279
+ MIT - [Vibe Code](https://vcode.sh)
@@ -0,0 +1,126 @@
1
+ import { readFile, access } from 'node:fs/promises';
2
+ import { pathToFileURL } from 'node:url';
3
+ import { defu } from 'defu';
4
+ import { join } from 'pathe';
5
+ import { c as createLogger, a as ConfigError } from '../shared/depfresh.B1o7OHO_.mjs';
6
+
7
+ const DEFAULT_OPTIONS = {
8
+ cwd: ".",
9
+ recursive: true,
10
+ mode: "default",
11
+ write: false,
12
+ interactive: false,
13
+ force: false,
14
+ includeLocked: false,
15
+ includeWorkspace: true,
16
+ concurrency: 16,
17
+ timeout: 1e4,
18
+ retries: 2,
19
+ cacheTTL: 30 * 60 * 1e3,
20
+ output: "table",
21
+ loglevel: "info",
22
+ peer: false,
23
+ global: false,
24
+ ignorePaths: ["**/node_modules/**", "**/dist/**", "**/coverage/**", "**/.git/**"],
25
+ ignoreOtherWorkspaces: true,
26
+ all: false,
27
+ group: true,
28
+ sort: "diff-asc",
29
+ timediff: true,
30
+ cooldown: 0,
31
+ nodecompat: true,
32
+ long: false,
33
+ explain: false,
34
+ failOnOutdated: false,
35
+ install: false,
36
+ update: false
37
+ };
38
+
39
+ const TS_RE = /\.[mc]?ts$/;
40
+ const JS_RE = /\.[mc]?js$/;
41
+ const CONFIG_FILES = [
42
+ "depzy.config.ts",
43
+ "depzy.config.mts",
44
+ "depzy.config.cts",
45
+ "depzy.config.js",
46
+ "depzy.config.mjs",
47
+ "depzy.config.cjs",
48
+ "depzy.config.json",
49
+ ".depzyrc.ts",
50
+ ".depzyrc.mts",
51
+ ".depzyrc.cts",
52
+ ".depzyrc.js",
53
+ ".depzyrc.mjs",
54
+ ".depzyrc.cjs",
55
+ ".depzyrc.json",
56
+ ".depzyrc"
57
+ ];
58
+ async function exists(path) {
59
+ try {
60
+ await access(path);
61
+ return true;
62
+ } catch {
63
+ return false;
64
+ }
65
+ }
66
+ async function loadTsFile(filePath) {
67
+ try {
68
+ const { createJiti } = await import('jiti');
69
+ const jiti = createJiti(import.meta.url);
70
+ const mod = await jiti.import(filePath);
71
+ return mod.default ?? mod;
72
+ } catch (error) {
73
+ throw new ConfigError(`Failed to load config file ${filePath}`, { cause: error });
74
+ }
75
+ }
76
+ async function loadJsFile(filePath) {
77
+ try {
78
+ const mod = await import(pathToFileURL(filePath).href);
79
+ return mod.default ?? mod;
80
+ } catch (error) {
81
+ throw new ConfigError(`Failed to load config file ${filePath}`, { cause: error });
82
+ }
83
+ }
84
+ async function loadJsonFile(filePath) {
85
+ try {
86
+ const content = await readFile(filePath, "utf-8");
87
+ return JSON.parse(content);
88
+ } catch (error) {
89
+ throw new ConfigError(`Failed to parse JSON config ${filePath}`, { cause: error });
90
+ }
91
+ }
92
+ async function loadConfigFile(cwd) {
93
+ for (const file of CONFIG_FILES) {
94
+ const filePath = join(cwd, file);
95
+ if (!await exists(filePath)) continue;
96
+ if (TS_RE.test(file)) return loadTsFile(filePath);
97
+ if (JS_RE.test(file)) return loadJsFile(filePath);
98
+ return loadJsonFile(filePath);
99
+ }
100
+ const pkgPath = join(cwd, "package.json");
101
+ if (await exists(pkgPath)) {
102
+ try {
103
+ const content = await readFile(pkgPath, "utf-8");
104
+ const pkg = JSON.parse(content);
105
+ if (pkg.depzy) return pkg.depzy;
106
+ } catch (error) {
107
+ throw new ConfigError(`Failed to parse package.json at ${pkgPath}`, { cause: error });
108
+ }
109
+ }
110
+ return void 0;
111
+ }
112
+ async function resolveConfig(overrides = {}) {
113
+ const cwd = overrides.cwd || process.cwd();
114
+ const fileConfig = await loadConfigFile(cwd);
115
+ const merged = defu(overrides, fileConfig ?? {}, DEFAULT_OPTIONS);
116
+ const logger = createLogger(merged.loglevel);
117
+ logger.debug("Config resolved:", JSON.stringify(merged, null, 2));
118
+ return merged;
119
+ }
120
+
121
+ const config = {
122
+ __proto__: null,
123
+ resolveConfig: resolveConfig
124
+ };
125
+
126
+ export { DEFAULT_OPTIONS as D, config as c, resolveConfig as r };
@@ -0,0 +1,21 @@
1
+ import { c as check } from '../shared/depfresh.ClIHCCxD.mjs';
2
+ export { d as detectPackageManager } from '../shared/depfresh.ClIHCCxD.mjs';
3
+ import 'ansis';
4
+ import '../shared/depfresh.B1o7OHO_.mjs';
5
+ import 'node:fs';
6
+ import 'node:os';
7
+ import 'find-up-simple';
8
+ import 'ini';
9
+ import 'pathe';
10
+ import 'node:child_process';
11
+ import 'detect-indent';
12
+ import 'semver';
13
+ import 'pnpm-workspace-yaml';
14
+ import 'yaml';
15
+ import 'p-limit';
16
+ import 'better-sqlite3';
17
+ import 'tinyglobby';
18
+
19
+
20
+
21
+ export { check };