docs-cache 0.5.2 → 0.5.3

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/README.md CHANGED
@@ -102,7 +102,7 @@ These fields can be set in `defaults` and are inherited by every source unless o
102
102
  | `ignoreHidden` | Skip hidden files and directories (dotfiles). Default: `false`. |
103
103
  | `allowHosts` | Allowed Git hosts. Default: `["github.com", "gitlab.com", "visualstudio.com"]`. |
104
104
  | `toc` | Generate per-source `TOC.md`. Default: `true`. Supports `true`, `false`, or a format: `"tree"` (human readable), `"compressed"` |
105
- | `unwrapSingleRootDir` | If the materialized output is nested under a single directory, unwrap it (recursively). Default: `false`. |
105
+ | `unwrapSingleRootDir` | If the materialized output is nested under a single directory, unwrap it (recursively). Default: `true`. |
106
106
 
107
107
  ### Source options
108
108
 
@@ -121,7 +121,7 @@ const resolveMaterializeParams = (params) => ({
121
121
  ...params,
122
122
  exclude: params.exclude ?? [],
123
123
  ignoreHidden: params.ignoreHidden ?? false,
124
- unwrapSingleRootDir: params.unwrapSingleRootDir ?? false,
124
+ unwrapSingleRootDir: params.unwrapSingleRootDir ?? true,
125
125
  json: params.json ?? false,
126
126
  progressThrottleMs: params.progressThrottleMs ?? 120
127
127
  });
@@ -19,7 +19,7 @@ export const DEFAULT_CONFIG = {
19
19
  ignoreHidden: false,
20
20
  allowHosts: ["github.com", "gitlab.com", "visualstudio.com"],
21
21
  toc: true,
22
- unwrapSingleRootDir: false
22
+ unwrapSingleRootDir: true
23
23
  },
24
24
  sources: []
25
25
  };
@@ -1,4 +1,5 @@
1
- const SAFE_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
1
+ const INVALID_ID_PATTERN = /[<>:"/\\|?*]/;
2
+ const TRAILING_DOT_SPACE_PATTERN = /[.\s]+$/;
2
3
  const MAX_ID_LENGTH = 200;
3
4
  const RESERVED_NAMES = /* @__PURE__ */ new Set([
4
5
  ".",
@@ -14,15 +15,28 @@ export const assertSafeSourceId = (value, label) => {
14
15
  if (typeof value !== "string" || value.length === 0) {
15
16
  throw new Error(`${label} must be a non-empty string.`);
16
17
  }
18
+ if (value.trim().length === 0) {
19
+ throw new Error(`${label} must not be blank.`);
20
+ }
17
21
  if (value.length > MAX_ID_LENGTH) {
18
22
  throw new Error(`${label} exceeds maximum length of ${MAX_ID_LENGTH}.`);
19
23
  }
20
- if (!SAFE_ID_PATTERN.test(value)) {
24
+ for (const char of value) {
25
+ const code = char.codePointAt(0);
26
+ if (code !== void 0 && (code <= 31 || code === 127)) {
27
+ throw new Error(`${label} must not contain control characters.`);
28
+ }
29
+ }
30
+ if (TRAILING_DOT_SPACE_PATTERN.test(value)) {
31
+ throw new Error(`${label} must not end with dots or spaces.`);
32
+ }
33
+ if (INVALID_ID_PATTERN.test(value) || value.includes("\0")) {
21
34
  throw new Error(
22
- `${label} must contain only alphanumeric characters, hyphens, and underscores.`
35
+ `${label} must not contain path separators or reserved characters (< > : " / \\ | ? *).`
23
36
  );
24
37
  }
25
- if (RESERVED_NAMES.has(value.toUpperCase())) {
38
+ const normalized = value.replace(/[.\s]+$/g, "");
39
+ if (RESERVED_NAMES.has(normalized.toUpperCase())) {
26
40
  throw new Error(`${label} uses reserved name '${value}'.`);
27
41
  }
28
42
  return value;
package/package.json CHANGED
@@ -1,136 +1,139 @@
1
1
  {
2
- "name": "docs-cache",
3
- "private": false,
4
- "type": "module",
5
- "version": "0.5.2",
6
- "description": "CLI for deterministic local caching of external documentation for agents and tools",
7
- "author": "Frederik Bosch",
8
- "license": "MIT",
9
- "homepage": "https://github.com/fbosch/docs-cache#readme",
10
- "repository": {
11
- "type": "git",
12
- "url": "https://github.com/fbosch/docs-cache.git"
13
- },
14
- "bugs": {
15
- "url": "https://github.com/fbosch/docs-cache/issues"
16
- },
17
- "keywords": [
18
- "docs",
19
- "documentation",
20
- "cache",
21
- "agent",
22
- "ai",
23
- "git",
24
- "cli"
25
- ],
26
- "sideEffects": false,
27
- "engines": {
28
- "node": ">=18"
29
- },
30
- "bin": {
31
- "docs-cache": "./bin/docs-cache.mjs"
32
- },
33
- "files": [
34
- "bin",
35
- "dist/cli.mjs",
36
- "dist/esm/**/*.mjs",
37
- "dist/esm/**/*.d.ts",
38
- "dist/lock.mjs",
39
- "dist/shared/*.mjs",
40
- "README.md",
41
- "LICENSE"
42
- ],
43
- "imports": {
44
- "#cache/*": {
45
- "types": "./dist/esm/cache/*.d.ts",
46
- "default": "./dist/esm/cache/*.mjs"
47
- },
48
- "#cli/*": {
49
- "types": "./dist/esm/cli/*.d.ts",
50
- "default": "./dist/esm/cli/*.mjs"
51
- },
52
- "#commands/*": {
53
- "types": "./dist/esm/commands/*.d.ts",
54
- "default": "./dist/esm/commands/*.mjs"
55
- },
56
- "#core/*": {
57
- "types": "./dist/esm/*.d.ts",
58
- "default": "./dist/esm/*.mjs"
59
- },
60
- "#config": {
61
- "types": "./dist/esm/config/index.d.ts",
62
- "default": "./dist/esm/config/index.mjs"
63
- },
64
- "#config/*": {
65
- "types": "./dist/esm/config/*.d.ts",
66
- "default": "./dist/esm/config/*.mjs"
67
- },
68
- "#git/*": {
69
- "types": "./dist/esm/git/*.d.ts",
70
- "default": "./dist/esm/git/*.mjs"
71
- },
72
- "#types/*": {
73
- "types": "./dist/esm/types/*.d.ts",
74
- "default": "./dist/esm/types/*.mjs"
75
- }
76
- },
77
- "dependencies": {
78
- "@clack/prompts": "^1.0.0",
79
- "cac": "^6.7.14",
80
- "cli-truncate": "^4.0.0",
81
- "execa": "^9.6.1",
82
- "fast-glob": "^3.3.2",
83
- "log-update": "^7.0.2",
84
- "picocolors": "^1.1.1",
85
- "picomatch": "^4.0.3",
86
- "zod": "^4.3.6"
87
- },
88
- "devDependencies": {
89
- "@biomejs/biome": "^2.3.14",
90
- "@size-limit/file": "^12.0.0",
91
- "@types/node": "^25.2.0",
92
- "bumpp": "^10.3.2",
93
- "c8": "^10.1.3",
94
- "jiti": "^2.5.1",
95
- "lint-staged": "^16.2.7",
96
- "simple-git-hooks": "^2.13.1",
97
- "size-limit": "^12.0.0",
98
- "tinybench": "^6.0.0",
99
- "ts-complex": "^1.0.0",
100
- "typescript": "^5.9.3",
101
- "unbuild": "^3.6.1"
102
- },
103
- "size-limit": [
104
- {
105
- "path": "dist/cli.mjs",
106
- "limit": "10 kB"
107
- }
108
- ],
109
- "complexity": {
110
- "maxCyclomatic": 20,
111
- "minMaintainability": 60,
112
- "top": 10
113
- },
114
- "simple-git-hooks": {
115
- "pre-commit": "pnpm lint-staged && pnpm typecheck"
116
- },
117
- "lint-staged": {
118
- "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}": [
119
- "biome check --write --no-errors-on-unmatched"
120
- ]
121
- },
122
- "scripts": {
123
- "build": "unbuild",
124
- "dev": "unbuild --stub",
125
- "lint": "biome check .",
126
- "release": "pnpm run lint && pnpm run typecheck && bumpp && pnpm publish --access public",
127
- "test": "pnpm build && node --test",
128
- "test:coverage": "pnpm build && c8 --include dist --exclude bin --reporter=text node --test",
129
- "bench": "pnpm build && node scripts/benchmarks/run.mjs",
130
- "complexity": "node scripts/complexity/run.mjs",
131
- "schema:build": "node scripts/generate-schema.mjs",
132
- "size": "size-limit",
133
- "test:watch": "node --test --watch",
134
- "typecheck": "tsc --noEmit"
135
- }
136
- }
2
+ "name": "docs-cache",
3
+ "private": false,
4
+ "type": "module",
5
+ "version": "0.5.3",
6
+ "packageManager": "pnpm@10.14.0+sha512.ad27a79641b49c3e481a16a805baa71817a04bbe06a38d17e60e2eaee83f6a146c6a688125f5792e48dd5ba30e7da52a5cda4c3992b9ccf333f9ce223af84748",
7
+ "description": "CLI for deterministic local caching of external documentation for agents and tools",
8
+ "author": "Frederik Bosch",
9
+ "license": "MIT",
10
+ "homepage": "https://github.com/fbosch/docs-cache#readme",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/fbosch/docs-cache.git"
14
+ },
15
+ "bugs": {
16
+ "url": "https://github.com/fbosch/docs-cache/issues"
17
+ },
18
+ "keywords": [
19
+ "docs",
20
+ "documentation",
21
+ "cache",
22
+ "agent",
23
+ "ai",
24
+ "git",
25
+ "cli"
26
+ ],
27
+ "sideEffects": false,
28
+ "engines": {
29
+ "node": ">=18"
30
+ },
31
+ "bin": {
32
+ "docs-cache": "./bin/docs-cache.mjs"
33
+ },
34
+ "files": [
35
+ "bin",
36
+ "dist/cli.mjs",
37
+ "dist/esm/**/*.mjs",
38
+ "dist/esm/**/*.d.ts",
39
+ "dist/lock.mjs",
40
+ "dist/shared/*.mjs",
41
+ "README.md",
42
+ "LICENSE"
43
+ ],
44
+ "scripts": {
45
+ "build": "unbuild",
46
+ "dev": "unbuild --stub",
47
+ "lint": "biome check .",
48
+ "prepublishOnly": "pnpm audit --audit-level=high && pnpm build && pnpm size && pnpm schema:build",
49
+ "release": "pnpm run lint && pnpm run typecheck && bumpp && pnpm publish --access public",
50
+ "test": "pnpm build && node --test",
51
+ "test:coverage": "pnpm build && c8 --include dist --exclude bin --reporter=text node --test",
52
+ "bench": "pnpm build && node scripts/benchmarks/run.mjs",
53
+ "complexity": "node scripts/complexity/run.mjs",
54
+ "schema:build": "node scripts/generate-schema.mjs",
55
+ "size": "size-limit",
56
+ "test:watch": "node --test --watch",
57
+ "typecheck": "tsc --noEmit",
58
+ "prepare": "simple-git-hooks"
59
+ },
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
+ },
94
+ "dependencies": {
95
+ "@clack/prompts": "^1.0.0",
96
+ "cac": "^6.7.14",
97
+ "cli-truncate": "^4.0.0",
98
+ "execa": "^9.6.1",
99
+ "fast-glob": "^3.3.2",
100
+ "log-update": "^7.0.2",
101
+ "picocolors": "^1.1.1",
102
+ "picomatch": "^4.0.3",
103
+ "zod": "^4.3.6"
104
+ },
105
+ "devDependencies": {
106
+ "@biomejs/biome": "^2.3.14",
107
+ "@size-limit/file": "^12.0.0",
108
+ "@types/node": "^25.2.0",
109
+ "bumpp": "^10.3.2",
110
+ "c8": "^10.1.3",
111
+ "jiti": "^2.5.1",
112
+ "lint-staged": "^16.2.7",
113
+ "simple-git-hooks": "^2.13.1",
114
+ "size-limit": "^12.0.0",
115
+ "tinybench": "^6.0.0",
116
+ "ts-complex": "^1.0.0",
117
+ "typescript": "^5.9.3",
118
+ "unbuild": "^3.6.1"
119
+ },
120
+ "size-limit": [
121
+ {
122
+ "path": "dist/cli.mjs",
123
+ "limit": "10 kB"
124
+ }
125
+ ],
126
+ "complexity": {
127
+ "maxCyclomatic": 20,
128
+ "minMaintainability": 60,
129
+ "top": 10
130
+ },
131
+ "simple-git-hooks": {
132
+ "pre-commit": "pnpm lint-staged && pnpm typecheck"
133
+ },
134
+ "lint-staged": {
135
+ "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}": [
136
+ "biome check --write --no-errors-on-unmatched"
137
+ ]
138
+ }
139
+ }