Skip to content

Commit 6b9dfe7

Browse files
authored
feat(cli): improve progress output with live updates (#21)
* feat(progress): add live progress output * feat(sync): add offline support * feat(cli): add timer to progress display * feat(cli): improve progress output * refactor(config): migrate to Zod schema validation * refactor(config): extract common schema options * feat(config): migrate interface to schema * feat(complexity): add ts-complex analysis script * refactor(init): reduce nesting * refactor(cli): split runCommand into funcs * refactor(sync): extract result builders * refactor(cli): extract parsing functions * refactor(cli): extract add entry helpers * refactor(remove): extract helper functions * refactor(remove): extract helper functions * refactor(sync): extract sync result builders * refactor(add): extract helper functions * refactor(fetch): extract helper functions * refactor(config): extract config I/O * refactor: organize files into commands and config * refactor: update file structure and imports * feat(output): disable live output in tests * fix: exports and build * fix: exports and build * feat: upgrade picomatch * chore: upgrade more dependencies * chore: revert cli-truncate upgrade * fix: pre-check node 18 * chore: adjust from feedback * chore: cleanup * chore: cleanup
1 parent 1cde8f4 commit 6b9dfe7

47 files changed

Lines changed: 3639 additions & 2423 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
- name: Setup Node
2323
uses: actions/setup-node@v4
2424
with:
25-
node-version: 22
25+
node-version: 18
2626
cache: pnpm
2727

2828
- name: Install dependencies

AGENTS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ pnpm.
3838

3939
- Use `node:` specifiers for built-in modules.
4040
- Keep modules small and single-purpose; prefer focused helpers in `src/`.
41+
- Prefer early returns to reduce nested control flow.
42+
- Avoid `else if` branches when early returns or separate conditionals are clearer.
43+
- Avoid type casts when a safe type guard or discriminated union can be used.
4144
- Place shared types in `src/types/` and import them via `import type`.
4245
- Use `index.ts` barrels for public entrypoints.
4346

build.config.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,58 @@
1+
import path from "node:path";
12
import { defineBuildConfig } from "unbuild";
23

34
export default defineBuildConfig({
45
entries: [
56
{ input: "src/cli/index", name: "cli" },
67
{ input: "src/api", name: "api" },
7-
{ input: "src/lock", name: "lock" },
8+
{ input: "src/cache/lock", name: "lock" },
9+
{
10+
builder: "mkdist",
11+
input: "./src",
12+
outDir: "./dist/esm",
13+
},
814
],
915
declaration: true,
1016
clean: true,
1117
sourcemap: true,
1218
rollup: {
1319
emitCJS: false,
20+
alias: {
21+
entries: [
22+
{
23+
find: /^#cache\/(.*)$/,
24+
replacement: path.resolve("src/cache/$1"),
25+
},
26+
{
27+
find: /^#cli\/(.*)$/,
28+
replacement: path.resolve("src/cli/$1"),
29+
},
30+
{
31+
find: /^#commands\/(.*)$/,
32+
replacement: path.resolve("src/commands/$1"),
33+
},
34+
{
35+
find: /^#config\/(.*)$/,
36+
replacement: path.resolve("src/config/$1"),
37+
},
38+
{
39+
find: "#config",
40+
replacement: path.resolve("src/config/index"),
41+
},
42+
{
43+
find: /^#core\/(.*)$/,
44+
replacement: path.resolve("src/$1"),
45+
},
46+
{
47+
find: /^#git\/(.*)$/,
48+
replacement: path.resolve("src/git/$1"),
49+
},
50+
{
51+
find: /^#types\/(.*)$/,
52+
replacement: path.resolve("src/types/$1"),
53+
},
54+
],
55+
},
1456
inlineDependencies: ["picocolors"],
1557
esbuild: {
1658
minify: true,

docs.config.schema.json

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,6 @@
5858
"ignoreHidden": {
5959
"type": "boolean"
6060
},
61-
"allowHosts": {
62-
"minItems": 1,
63-
"type": "array",
64-
"items": {
65-
"type": "string",
66-
"minLength": 1
67-
}
68-
},
6961
"toc": {
7062
"anyOf": [
7163
{
@@ -79,6 +71,14 @@
7971
},
8072
"unwrapSingleRootDir": {
8173
"type": "boolean"
74+
},
75+
"allowHosts": {
76+
"minItems": 1,
77+
"type": "array",
78+
"items": {
79+
"type": "string",
80+
"minLength": 1
81+
}
8282
}
8383
},
8484
"additionalProperties": false
@@ -88,22 +88,6 @@
8888
"items": {
8989
"type": "object",
9090
"properties": {
91-
"id": {
92-
"type": "string",
93-
"minLength": 1
94-
},
95-
"repo": {
96-
"type": "string",
97-
"minLength": 1
98-
},
99-
"targetDir": {
100-
"type": "string",
101-
"minLength": 1
102-
},
103-
"targetMode": {
104-
"type": "string",
105-
"enum": ["symlink", "copy"]
106-
},
10791
"ref": {
10892
"type": "string",
10993
"minLength": 1
@@ -113,6 +97,7 @@
11397
"enum": ["materialize"]
11498
},
11599
"include": {
100+
"minItems": 1,
116101
"type": "array",
117102
"items": {
118103
"type": "string",
@@ -126,6 +111,10 @@
126111
"minLength": 1
127112
}
128113
},
114+
"targetMode": {
115+
"type": "string",
116+
"enum": ["symlink", "copy"]
117+
},
129118
"required": {
130119
"type": "boolean"
131120
},
@@ -140,6 +129,32 @@
140129
"ignoreHidden": {
141130
"type": "boolean"
142131
},
132+
"toc": {
133+
"anyOf": [
134+
{
135+
"type": "boolean"
136+
},
137+
{
138+
"type": "string",
139+
"enum": ["tree", "compressed"]
140+
}
141+
]
142+
},
143+
"unwrapSingleRootDir": {
144+
"type": "boolean"
145+
},
146+
"id": {
147+
"type": "string",
148+
"minLength": 1
149+
},
150+
"repo": {
151+
"type": "string",
152+
"minLength": 1
153+
},
154+
"targetDir": {
155+
"type": "string",
156+
"minLength": 1
157+
},
143158
"integrity": {
144159
"type": "object",
145160
"properties": {
@@ -160,20 +175,6 @@
160175
},
161176
"required": ["type", "value"],
162177
"additionalProperties": false
163-
},
164-
"toc": {
165-
"anyOf": [
166-
{
167-
"type": "boolean"
168-
},
169-
{
170-
"type": "string",
171-
"enum": ["tree", "compressed"]
172-
}
173-
]
174-
},
175-
"unwrapSingleRootDir": {
176-
"type": "boolean"
177178
}
178179
},
179180
"required": ["id", "repo"],

package.json

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
"files": [
3535
"bin",
3636
"dist/cli.mjs",
37-
"dist/chunks/*.mjs",
37+
"dist/esm/**/*.mjs",
38+
"dist/esm/**/*.d.ts",
3839
"dist/lock.mjs",
3940
"dist/shared/*.mjs",
4041
"README.md",
@@ -49,32 +50,70 @@
4950
"test": "pnpm build && node --test",
5051
"test:coverage": "pnpm build && c8 --include dist --exclude bin --reporter=text node --test",
5152
"bench": "pnpm build && node scripts/benchmarks/run.mjs",
53+
"complexity": "node scripts/complexity/run.mjs",
5254
"schema:build": "node scripts/generate-schema.mjs",
5355
"size": "size-limit",
5456
"test:watch": "node --test --watch",
5557
"typecheck": "tsc --noEmit",
5658
"prepare": "simple-git-hooks"
5759
},
60+
"imports": {
61+
"#cache/*": {
62+
"types": "./dist/esm/cache/*.d.ts",
63+
"default": "./dist/esm/cache/*.mjs"
64+
},
65+
"#cli/*": {
66+
"types": "./dist/esm/cli/*.d.ts",
67+
"default": "./dist/esm/cli/*.mjs"
68+
},
69+
"#commands/*": {
70+
"types": "./dist/esm/commands/*.d.ts",
71+
"default": "./dist/esm/commands/*.mjs"
72+
},
73+
"#core/*": {
74+
"types": "./dist/esm/*.d.ts",
75+
"default": "./dist/esm/*.mjs"
76+
},
77+
"#config": {
78+
"types": "./dist/esm/config/index.d.ts",
79+
"default": "./dist/esm/config/index.mjs"
80+
},
81+
"#config/*": {
82+
"types": "./dist/esm/config/*.d.ts",
83+
"default": "./dist/esm/config/*.mjs"
84+
},
85+
"#git/*": {
86+
"types": "./dist/esm/git/*.d.ts",
87+
"default": "./dist/esm/git/*.mjs"
88+
},
89+
"#types/*": {
90+
"types": "./dist/esm/types/*.d.ts",
91+
"default": "./dist/esm/types/*.mjs"
92+
}
93+
},
5894
"dependencies": {
5995
"@clack/prompts": "^1.0.0",
6096
"cac": "^6.7.14",
97+
"cli-truncate": "^4.0.0",
6198
"execa": "^9.6.1",
6299
"fast-glob": "^3.3.2",
100+
"log-update": "^7.0.2",
63101
"picocolors": "^1.1.1",
64-
"picomatch": "^2.3.1",
102+
"picomatch": "^4.0.3",
65103
"zod": "^4.3.6"
66104
},
67105
"devDependencies": {
68-
"@biomejs/biome": "^2.3.8",
69-
"@size-limit/file": "^11.2.0",
70-
"@types/node": "^24.2.1",
106+
"@biomejs/biome": "^2.3.14",
107+
"@size-limit/file": "^12.0.0",
108+
"@types/node": "^25.2.0",
71109
"bumpp": "^10.3.2",
72110
"c8": "^10.1.3",
73111
"jiti": "^2.5.1",
74112
"lint-staged": "^16.2.7",
75113
"simple-git-hooks": "^2.13.1",
76-
"size-limit": "^11.2.0",
114+
"size-limit": "^12.0.0",
77115
"tinybench": "^6.0.0",
116+
"ts-complex": "^1.0.0",
78117
"typescript": "^5.9.3",
79118
"unbuild": "^3.6.1"
80119
},
@@ -84,6 +123,11 @@
84123
"limit": "10 kB"
85124
}
86125
],
126+
"complexity": {
127+
"maxCyclomatic": 20,
128+
"minMaintainability": 60,
129+
"top": 10
130+
},
87131
"simple-git-hooks": {
88132
"pre-commit": "pnpm lint-staged && pnpm typecheck"
89133
},

0 commit comments

Comments
 (0)