@ultimat3/cli 19.1.0 → 19.1.1

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.
Files changed (2) hide show
  1. package/package.json +29 -29
  2. package/src/fix-path.ts +34 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultimat3/cli",
3
- "version": "19.1.0",
3
+ "version": "19.1.1",
4
4
  "description": "The `x` binary: new, dev, build, verify, generate, db, mcp, doctor, deploy",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -37,34 +37,34 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@babel/core": "^7.28.4",
40
- "@ultimat3/action": "19.1.0",
41
- "@ultimat3/admin": "19.1.0",
42
- "@ultimat3/ai": "19.1.0",
43
- "@ultimat3/auth": "19.1.0",
44
- "@ultimat3/cache": "19.1.0",
45
- "@ultimat3/core": "19.1.0",
46
- "@ultimat3/db": "19.1.0",
47
- "@ultimat3/entity": "19.1.0",
48
- "@ultimat3/flags": "19.1.0",
49
- "@ultimat3/http": "19.1.0",
50
- "@ultimat3/i18n": "19.1.0",
51
- "@ultimat3/jobs": "19.1.0",
52
- "@ultimat3/mail": "19.1.0",
53
- "@ultimat3/manifest": "19.1.0",
54
- "@ultimat3/mcp": "19.1.0",
55
- "@ultimat3/money": "19.1.0",
56
- "@ultimat3/notify": "19.1.0",
57
- "@ultimat3/policy": "19.1.0",
58
- "@ultimat3/pwa": "19.1.0",
59
- "@ultimat3/query": "19.1.0",
60
- "@ultimat3/realtime": "19.1.0",
61
- "@ultimat3/render": "19.1.0",
62
- "@ultimat3/schema": "19.1.0",
63
- "@ultimat3/scraping": "19.1.0",
64
- "@ultimat3/seo": "19.1.0",
65
- "@ultimat3/storage": "19.1.0",
66
- "@ultimat3/testing": "19.1.0",
67
- "@ultimat3/time": "19.1.0",
40
+ "@ultimat3/action": "19.1.1",
41
+ "@ultimat3/admin": "19.1.1",
42
+ "@ultimat3/ai": "19.1.1",
43
+ "@ultimat3/auth": "19.1.1",
44
+ "@ultimat3/cache": "19.1.1",
45
+ "@ultimat3/core": "19.1.1",
46
+ "@ultimat3/db": "19.1.1",
47
+ "@ultimat3/entity": "19.1.1",
48
+ "@ultimat3/flags": "19.1.1",
49
+ "@ultimat3/http": "19.1.1",
50
+ "@ultimat3/i18n": "19.1.1",
51
+ "@ultimat3/jobs": "19.1.1",
52
+ "@ultimat3/mail": "19.1.1",
53
+ "@ultimat3/manifest": "19.1.1",
54
+ "@ultimat3/mcp": "19.1.1",
55
+ "@ultimat3/money": "19.1.1",
56
+ "@ultimat3/notify": "19.1.1",
57
+ "@ultimat3/policy": "19.1.1",
58
+ "@ultimat3/pwa": "19.1.1",
59
+ "@ultimat3/query": "19.1.1",
60
+ "@ultimat3/realtime": "19.1.1",
61
+ "@ultimat3/render": "19.1.1",
62
+ "@ultimat3/schema": "19.1.1",
63
+ "@ultimat3/scraping": "19.1.1",
64
+ "@ultimat3/seo": "19.1.1",
65
+ "@ultimat3/storage": "19.1.1",
66
+ "@ultimat3/testing": "19.1.1",
67
+ "@ultimat3/time": "19.1.1",
68
68
  "babel-preset-solid": "^1.9.15"
69
69
  }
70
70
  }
package/src/fix-path.ts CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  // why: Bun exposes no synchronous existence primitive — `Bun.file(p).exists()` is async and answers
7
7
  // false for a DIRECTORY, and this rule has to judge both. Delete when Bun ships one.
8
- import { existsSync } from 'node:fs';
8
+ import { existsSync, readFileSync } from 'node:fs';
9
9
  // why: Bun exposes no path-join or dirname primitive. The same necessity `error-contract.ts`
10
10
  // already records for `join`.
11
11
  import { dirname, join } from 'node:path';
@@ -60,6 +60,11 @@ const URL_SPAN = /\b[a-z][\w+.-]*:\/\/\S+/gi;
60
60
  */
61
61
  function isJudgeable(token: string, root: string): boolean {
62
62
  if (token.startsWith('@') || token.startsWith('./') || token.startsWith('../')) return false;
63
+ // A FOURTH exclusion, measured 2026-09-05 on the first app whose fixes name its private files:
64
+ // `.personal/fleet.yml` is the right thing to tell a reader to edit, and the repository holds
65
+ // `.personal/` in its `.gitignore` on purpose — the file exists on every developer's disk and on
66
+ // no CI runner. A path the repo itself says it never commits is not a path this root can judge.
67
+ if (isPrivateByDesign(token, root)) return false;
63
68
  const star = token.indexOf('*');
64
69
  // A glob's FIXED prefix is what has to exist; the segments a `*` stands for are the answer. Cut
65
70
  // at the separator before the star rather than at the star — `dirname('packages/')` is `.`, and
@@ -69,6 +74,34 @@ function isJudgeable(token: string, root: string): boolean {
69
74
  return base !== '.' && base !== '' && existsSync(join(root, base));
70
75
  }
71
76
 
77
+ /**
78
+ * The directories the root `.gitignore` lists as ignored, as `dir/` prefixes. Only the plain
79
+ * directory form is read (`.personal/`, `/tmp/`, `dist`): a negation, a glob or a nested pattern
80
+ * is a rule about files the repo may still hold, and this exclusion errs towards judging.
81
+ */
82
+ const ignoredDirs = new Map<string, readonly string[]>();
83
+
84
+ function ignoredDirectories(root: string): readonly string[] {
85
+ const known = ignoredDirs.get(root);
86
+ if (known !== undefined) return known;
87
+ const file = join(root, '.gitignore');
88
+ const lines = existsSync(file) ? readFileSync(file, 'utf8').split('\n') : [];
89
+ const dirs = lines
90
+ .map((line) => line.trim())
91
+ .filter((line) => line !== '' && !line.startsWith('#') && !line.startsWith('!'))
92
+ .filter((line) => !/[*?[\]]/.test(line))
93
+ .map((line) => line.replace(/^\//, '').replace(/\/$/, ''))
94
+ .filter((line) => line !== '' && !line.includes('/'))
95
+ .map((dir) => `${dir}/`);
96
+ ignoredDirs.set(root, dirs);
97
+ return dirs;
98
+ }
99
+
100
+ /** Whether the citation sits under a directory the repo's own `.gitignore` never commits. */
101
+ function isPrivateByDesign(token: string, root: string): boolean {
102
+ return ignoredDirectories(root).some((dir) => token.startsWith(dir));
103
+ }
104
+
72
105
  /** Every path-shaped citation on a fix line that this root can resolve, in the order written. */
73
106
  export function pathCitations(fix: string, root: string): readonly string[] {
74
107
  const prose = fix.replaceAll(URL_SPAN, ' ');