@vibe-agent-toolkit/utils 0.1.41 → 0.1.42-rc.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 (115) hide show
  1. package/README.md +146 -31
  2. package/dist/asset.d.ts +9 -0
  3. package/dist/asset.d.ts.map +1 -0
  4. package/dist/asset.js +9 -0
  5. package/dist/asset.js.map +1 -0
  6. package/dist/crawl.d.ts +19 -0
  7. package/dist/crawl.d.ts.map +1 -0
  8. package/dist/crawl.js +19 -0
  9. package/dist/crawl.js.map +1 -0
  10. package/dist/file-crawler.d.ts +19 -2
  11. package/dist/file-crawler.d.ts.map +1 -1
  12. package/dist/file-crawler.js +19 -1
  13. package/dist/file-crawler.js.map +1 -1
  14. package/dist/fs-utils.d.ts +60 -3
  15. package/dist/fs-utils.d.ts.map +1 -1
  16. package/dist/fs-utils.js +88 -10
  17. package/dist/fs-utils.js.map +1 -1
  18. package/dist/fs.d.ts +7 -6
  19. package/dist/fs.d.ts.map +1 -1
  20. package/dist/fs.js +7 -6
  21. package/dist/fs.js.map +1 -1
  22. package/dist/git-utils.d.ts +2 -0
  23. package/dist/git-utils.d.ts.map +1 -1
  24. package/dist/git-utils.js +16 -0
  25. package/dist/git-utils.js.map +1 -1
  26. package/dist/git.d.ts +23 -0
  27. package/dist/git.d.ts.map +1 -0
  28. package/dist/git.js +23 -0
  29. package/dist/git.js.map +1 -0
  30. package/dist/gitignore-checker.d.ts +0 -9
  31. package/dist/gitignore-checker.d.ts.map +1 -1
  32. package/dist/gitignore-checker.js +0 -12
  33. package/dist/gitignore-checker.js.map +1 -1
  34. package/dist/glob/glob-pattern.js +1 -1
  35. package/dist/glob/glob-pattern.js.map +1 -1
  36. package/dist/glob.d.ts +8 -0
  37. package/dist/glob.d.ts.map +1 -0
  38. package/dist/glob.js +8 -0
  39. package/dist/glob.js.map +1 -0
  40. package/dist/path-core.d.ts +196 -0
  41. package/dist/path-core.d.ts.map +1 -0
  42. package/dist/path-core.js +251 -0
  43. package/dist/path-core.js.map +1 -0
  44. package/dist/path-utils.d.ts +12 -183
  45. package/dist/path-utils.d.ts.map +1 -1
  46. package/dist/path-utils.js +13 -237
  47. package/dist/path-utils.js.map +1 -1
  48. package/dist/path.d.ts +12 -0
  49. package/dist/path.d.ts.map +1 -0
  50. package/dist/path.js +12 -0
  51. package/dist/path.js.map +1 -0
  52. package/dist/process.d.ts +7 -4
  53. package/dist/process.d.ts.map +1 -1
  54. package/dist/process.js +7 -4
  55. package/dist/process.js.map +1 -1
  56. package/dist/project.d.ts +31 -0
  57. package/dist/project.d.ts.map +1 -0
  58. package/dist/project.js +31 -0
  59. package/dist/project.js.map +1 -0
  60. package/dist/safe-exec.d.ts.map +1 -1
  61. package/dist/safe-exec.js +8 -4
  62. package/dist/safe-exec.js.map +1 -1
  63. package/dist/spawn-hardened.d.ts.map +1 -1
  64. package/dist/spawn-hardened.js +4 -17
  65. package/dist/spawn-hardened.js.map +1 -1
  66. package/dist/template-entry.d.ts +10 -0
  67. package/dist/template-entry.d.ts.map +1 -0
  68. package/dist/template-entry.js +10 -0
  69. package/dist/template-entry.js.map +1 -0
  70. package/dist/testing.d.ts +8 -0
  71. package/dist/testing.d.ts.map +1 -0
  72. package/dist/testing.js +8 -0
  73. package/dist/testing.js.map +1 -0
  74. package/dist/windows-shell.d.ts +140 -8
  75. package/dist/windows-shell.d.ts.map +1 -1
  76. package/dist/windows-shell.js +218 -11
  77. package/dist/windows-shell.js.map +1 -1
  78. package/dist/yaml.d.ts +9 -0
  79. package/dist/yaml.d.ts.map +1 -0
  80. package/dist/yaml.js +9 -0
  81. package/dist/yaml.js.map +1 -0
  82. package/dist/zod.d.ts +10 -0
  83. package/dist/zod.d.ts.map +1 -0
  84. package/dist/zod.js +10 -0
  85. package/dist/zod.js.map +1 -0
  86. package/eslint/README.md +191 -0
  87. package/eslint/index.cjs +161 -0
  88. package/eslint/index.d.cts +60 -0
  89. package/eslint/rules/eslint-rule-factory.cjs +241 -0
  90. package/eslint/rules/exempt-path-matcher.cjs +265 -0
  91. package/eslint/rules/no-bare-dynamic-import-path.cjs +142 -0
  92. package/eslint/rules/no-child-process-execSync.cjs +23 -0
  93. package/eslint/rules/no-command-direct-factory.cjs +246 -0
  94. package/eslint/rules/no-file-url-string-concat.cjs +77 -0
  95. package/eslint/rules/no-fs-mkdirSync.cjs +23 -0
  96. package/eslint/rules/no-fs-promises-cp.cjs +36 -0
  97. package/eslint/rules/no-fs-realpathSync.cjs +23 -0
  98. package/eslint/rules/no-hardcoded-path-split.cjs +141 -0
  99. package/eslint/rules/no-manual-path-normalize.cjs +130 -0
  100. package/eslint/rules/no-os-tmpdir.cjs +24 -0
  101. package/eslint/rules/no-path-join.cjs +14 -0
  102. package/eslint/rules/no-path-operations-in-comparisons.cjs +148 -0
  103. package/eslint/rules/no-path-relative.cjs +14 -0
  104. package/eslint/rules/no-path-resolve.cjs +14 -0
  105. package/eslint/rules/no-path-sep-in-strings.cjs +130 -0
  106. package/eslint/rules/no-path-startswith.cjs +139 -0
  107. package/eslint/rules/no-test-scoped-functions.cjs +134 -0
  108. package/eslint/rules/no-unix-shell-commands.cjs +152 -0
  109. package/eslint/rules/no-unsafe-root-join.cjs +85 -0
  110. package/eslint/rules/no-url-pathname-for-fs.cjs +107 -0
  111. package/eslint/rules/path-function-rule-factory.cjs +216 -0
  112. package/eslint/rules/prefer-startswith-over-regex.cjs +111 -0
  113. package/eslint/rules/require-justified-skip.cjs +348 -0
  114. package/eslint/rules/safe-import.cjs +141 -0
  115. package/package.json +65 -7
package/dist/fs.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * @vibe-agent-toolkit/utils/fs
3
3
  *
4
- * Narrow subpath export for filesystem and path primitives. Import this entry
5
- * point when you need cross-platform path/fs helpers without pulling in the
6
- * linkAuth, git, skill-testing, or macro-expansion machinery from the full
7
- * `"."` barrel.
4
+ * Filesystem-touching path helpers. Everything here reaches `node:fs`,
5
+ * `node:os`, or `node:url` and is therefore Node-only.
6
+ *
7
+ * For pure path-string manipulation that needs none of that, import
8
+ * `@vibe-agent-toolkit/utils/path` instead — it is dramatically cheaper.
8
9
  */
9
- export { normalizePath, normalizedTmpdir, mkdirSyncReal, isAbsolutePath, isAbsoluteAnyPlatform, hasParentTraversalSegment, toAbsolutePath, getRelativePath, toForwardSlash, safePath, resolveFromImportMeta, dynamicImportPath, } from './path-utils.js';
10
- export { copyDirectory, verifyCaseSensitiveFilename } from './fs-utils.js';
10
+ export { normalizePath, normalizedTmpdir, mkdirSyncReal, resolveFromImportMeta, dynamicImportPath, } from './path-utils.js';
11
+ export { copyDirectory, FsLookupCache, verifyCaseSensitiveFilename } from './fs-utils.js';
11
12
  //# sourceMappingURL=fs.d.ts.map
package/dist/fs.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,yBAAyB,EACzB,cAAc,EACd,eAAe,EACf,cAAc,EACd,QAAQ,EACR,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC"}
package/dist/fs.js CHANGED
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * @vibe-agent-toolkit/utils/fs
3
3
  *
4
- * Narrow subpath export for filesystem and path primitives. Import this entry
5
- * point when you need cross-platform path/fs helpers without pulling in the
6
- * linkAuth, git, skill-testing, or macro-expansion machinery from the full
7
- * `"."` barrel.
4
+ * Filesystem-touching path helpers. Everything here reaches `node:fs`,
5
+ * `node:os`, or `node:url` and is therefore Node-only.
6
+ *
7
+ * For pure path-string manipulation that needs none of that, import
8
+ * `@vibe-agent-toolkit/utils/path` instead — it is dramatically cheaper.
8
9
  */
9
- export { normalizePath, normalizedTmpdir, mkdirSyncReal, isAbsolutePath, isAbsoluteAnyPlatform, hasParentTraversalSegment, toAbsolutePath, getRelativePath, toForwardSlash, safePath, resolveFromImportMeta, dynamicImportPath, } from './path-utils.js';
10
- export { copyDirectory, verifyCaseSensitiveFilename } from './fs-utils.js';
10
+ export { normalizePath, normalizedTmpdir, mkdirSyncReal, resolveFromImportMeta, dynamicImportPath, } from './path-utils.js';
11
+ export { copyDirectory, FsLookupCache, verifyCaseSensitiveFilename } from './fs-utils.js';
11
12
  //# sourceMappingURL=fs.js.map
package/dist/fs.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fs.js","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,yBAAyB,EACzB,cAAc,EACd,eAAe,EACf,cAAc,EACd,QAAQ,EACR,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC"}
@@ -43,6 +43,8 @@ export declare function gitLsFiles(options: {
43
43
  * handles the common pattern where a gitignored directory contains symlinks to external content
44
44
  * (e.g., OneDrive, shared drives).
45
45
  *
46
+ * **Outside a repository**: answered from the filesystem, with zero subprocesses (see below).
47
+ *
46
48
  * **Performance warning**: This spawns a git subprocess for each file (plus up to N ancestor
47
49
  * checks when the path traverses a symlink). For bulk workflows, initialize a
48
50
  * {@link GitTracker} once and use `isIgnoredByActiveSet()` for O(1) in-repo lookups.
@@ -1 +1 @@
1
- {"version":3,"file":"git-utils.d.ts","sourceRoot":"","sources":["../src/git-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc3D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,GAAG,MAAM,EAAE,GAAG,IAAI,CA0ClB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,OAAO,CAmDnF"}
1
+ {"version":3,"file":"git-utils.d.ts","sourceRoot":"","sources":["../src/git-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc3D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,GAAG,MAAM,EAAE,GAAG,IAAI,CA0ClB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,OAAO,CAkEnF"}
package/dist/git-utils.js CHANGED
@@ -92,6 +92,8 @@ export function gitLsFiles(options) {
92
92
  * handles the common pattern where a gitignored directory contains symlinks to external content
93
93
  * (e.g., OneDrive, shared drives).
94
94
  *
95
+ * **Outside a repository**: answered from the filesystem, with zero subprocesses (see below).
96
+ *
95
97
  * **Performance warning**: This spawns a git subprocess for each file (plus up to N ancestor
96
98
  * checks when the path traverses a symlink). For bulk workflows, initialize a
97
99
  * {@link GitTracker} once and use `isIgnoredByActiveSet()` for O(1) in-repo lookups.
@@ -101,6 +103,20 @@ export function gitLsFiles(options) {
101
103
  * @returns true if file is gitignored, false otherwise
102
104
  */
103
105
  export function isGitIgnored(filePath, cwd = process.cwd()) {
106
+ // `git check-ignore` exits 128 for two unrelated conditions: "not a git repository"
107
+ // and "beyond a symbolic link". The exit code alone cannot distinguish them, and the
108
+ // symlink recovery below (walk the ancestors, re-spawning git for each) is exactly
109
+ // the wrong response to the first: with no repository *every* ancestor also exits
110
+ // 128, so the walk never breaks, climbs to the filesystem root, and returns `false`
111
+ // after (1 + depth) spawns — per call, for every link in the corpus. It is the right
112
+ // answer by the wrong route, which is why no assertion ever caught it; on a
113
+ // 3,437-document tree with no `.git` ancestor, spawnSync was 87.6% of the run.
114
+ //
115
+ // "Is there a repository here?" is a filesystem question, so settle it from the
116
+ // filesystem before spawning anything.
117
+ if (gitFindRoot(cwd) === null) {
118
+ return false;
119
+ }
104
120
  try {
105
121
  // Resolve git path using which for security (avoids PATH manipulation)
106
122
  const gitPath = which.sync('git');
@@ -1 +1 @@
1
- {"version":3,"file":"git-utils.js","sourceRoot":"","sources":["../src/git-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"git-utils.js","sourceRoot":"","sources":["../src/git-utils.ts"],"names":[],"mappings":"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"}
package/dist/git.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @vibe-agent-toolkit/utils/git
3
+ *
4
+ * Git primitives for build guards and gates: root discovery, tracked-file
5
+ * enumeration, gitignore evaluation, and git URL parsing. Node-only —
6
+ * shells out to `git` and reads the filesystem.
7
+ *
8
+ * The re-exports below are explicit rather than `export *` on purpose. A
9
+ * blanket re-export surfaced TWO root finders under two names — `gitFindRoot`
10
+ * and a `findGitRoot` alias whose entire body was `return gitFindRoot(startDir)`
11
+ * — which guarantees half of all adopters reach for each.
12
+ *
13
+ * Curating this entry alone only moved the coin flip: `findGitRoot` stayed on
14
+ * the `.` barrel, the entry with the most consumers, so both names remained
15
+ * reachable from one import. The alias is now DELETED (pre-1.0 policy: remove
16
+ * old code rather than maintain two APIs). `gitFindRoot` is the only root
17
+ * finder in the package.
18
+ */
19
+ export { gitFindRoot, gitLsFiles, isGitIgnored } from './git-utils.js';
20
+ export { loadGitignoreRules } from './gitignore-checker.js';
21
+ export { GitTracker, type GitTrackerInitOptions } from './git-tracker.js';
22
+ export { isGitUrl, nonInteractiveGitOverrides, parseGitUrl, type NonInteractiveGitOverrides, type ParsedGitUrl, } from './git-url.js';
23
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EACL,QAAQ,EACR,0BAA0B,EAC1B,WAAW,EACX,KAAK,0BAA0B,EAC/B,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC"}
package/dist/git.js ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @vibe-agent-toolkit/utils/git
3
+ *
4
+ * Git primitives for build guards and gates: root discovery, tracked-file
5
+ * enumeration, gitignore evaluation, and git URL parsing. Node-only —
6
+ * shells out to `git` and reads the filesystem.
7
+ *
8
+ * The re-exports below are explicit rather than `export *` on purpose. A
9
+ * blanket re-export surfaced TWO root finders under two names — `gitFindRoot`
10
+ * and a `findGitRoot` alias whose entire body was `return gitFindRoot(startDir)`
11
+ * — which guarantees half of all adopters reach for each.
12
+ *
13
+ * Curating this entry alone only moved the coin flip: `findGitRoot` stayed on
14
+ * the `.` barrel, the entry with the most consumers, so both names remained
15
+ * reachable from one import. The alias is now DELETED (pre-1.0 policy: remove
16
+ * old code rather than maintain two APIs). `gitFindRoot` is the only root
17
+ * finder in the package.
18
+ */
19
+ export { gitFindRoot, gitLsFiles, isGitIgnored } from './git-utils.js';
20
+ export { loadGitignoreRules } from './gitignore-checker.js';
21
+ export { GitTracker } from './git-tracker.js';
22
+ export { isGitUrl, nonInteractiveGitOverrides, parseGitUrl, } from './git-url.js';
23
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAA8B,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EACL,QAAQ,EACR,0BAA0B,EAC1B,WAAW,GAGZ,MAAM,cAAc,CAAC"}
@@ -6,15 +6,6 @@
6
6
  * Use git-utils.ts for authoritative git commands (gitFindRoot, isGitIgnored, gitLsFiles).
7
7
  */
8
8
  import { type Ignore } from 'ignore';
9
- /**
10
- * Find the git repository root by walking up from the given directory.
11
- *
12
- * @param startDir - Directory to start searching from
13
- * @returns Path to git root, or null if not in a git repository
14
- *
15
- * @deprecated Use gitFindRoot from git-utils.ts instead
16
- */
17
- export declare function findGitRoot(startDir: string): string | null;
18
9
  /**
19
10
  * Load and parse .gitignore files from git root to baseDir.
20
11
  * Returns an ignore instance configured with all applicable .gitignore rules.
@@ -1 +1 @@
1
- {"version":3,"file":"gitignore-checker.d.ts","sourceRoot":"","sources":["../src/gitignore-checker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAe,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAK7C;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE3D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAwCnF"}
1
+ {"version":3,"file":"gitignore-checker.d.ts","sourceRoot":"","sources":["../src/gitignore-checker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAe,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAI7C;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAwCnF"}
@@ -8,19 +8,7 @@
8
8
  import fs from 'node:fs';
9
9
  import path from 'node:path';
10
10
  import ignore from 'ignore';
11
- import { gitFindRoot } from './git-utils.js';
12
11
  import { safePath, toForwardSlash } from './path-utils.js';
13
- /**
14
- * Find the git repository root by walking up from the given directory.
15
- *
16
- * @param startDir - Directory to start searching from
17
- * @returns Path to git root, or null if not in a git repository
18
- *
19
- * @deprecated Use gitFindRoot from git-utils.ts instead
20
- */
21
- export function findGitRoot(startDir) {
22
- return gitFindRoot(startDir);
23
- }
24
12
  /**
25
13
  * Load and parse .gitignore files from git root to baseDir.
26
14
  * Returns an ignore instance configured with all applicable .gitignore rules.
@@ -1 +1 @@
1
- {"version":3,"file":"gitignore-checker.js","sourceRoot":"","sources":["../src/gitignore-checker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,MAAuB,MAAM,QAAQ,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAG,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE5D;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,OAAO,WAAW,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,OAAgB;IAClE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACpB,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,+BAA+B;IAC/B,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACf,QAAQ,GAAG,IAAI,CAAC;IAEhB,kDAAkD;IAClD,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,IAAI,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC;IACtD,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAElD,+CAA+C;IAC/C,MAAM,iBAAiB,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;IAE1D,OAAO,cAAc,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAChE,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAChC,IAAI,UAAU,KAAK,eAAe,EAAE,CAAC;YACnC,MAAM;QACR,CAAC;QACD,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAED,sDAAsD;IACtD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QACvD,qHAAqH;QACrH,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC;gBACH,sFAAsF;gBACtF,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;gBACxD,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAClB,CAAC;YAAC,MAAM,CAAC;gBACP,qCAAqC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"gitignore-checker.js","sourceRoot":"","sources":["../src/gitignore-checker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,MAAuB,MAAM,QAAQ,CAAC;AAE7C,OAAO,EAAE,QAAQ,EAAG,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE5D;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,OAAgB;IAClE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACpB,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,+BAA+B;IAC/B,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACf,QAAQ,GAAG,IAAI,CAAC;IAEhB,kDAAkD;IAClD,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,IAAI,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC;IACtD,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAElD,+CAA+C;IAC/C,MAAM,iBAAiB,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;IAE1D,OAAO,cAAc,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAChE,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAChC,IAAI,UAAU,KAAK,eAAe,EAAE,CAAC;YACnC,MAAM;QACR,CAAC;QACD,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAED,sDAAsD;IACtD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QACvD,qHAAqH;QACrH,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC;gBACH,sFAAsF;gBACtF,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;gBACxD,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAClB,CAAC;YAAC,MAAM,CAAC;gBACP,qCAAqC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9B,CAAC"}
@@ -11,7 +11,7 @@
11
11
  * sets an `escaped` flag when it sees `\`; the *next* character is skipped for
12
12
  * magic detection if `escaped` is true.
13
13
  */
14
- import { toForwardSlash } from '../path-utils.js';
14
+ import { toForwardSlash } from '../path-core.js';
15
15
  /** The glob metacharacters recognised by this module. */
16
16
  const MAGIC_CHARS = new Set(['*', '?', '[']);
17
17
  /** Sentinel returned by {@link staticGlobBase} when the first segment is magic. */
@@ -1 +1 @@
1
- {"version":3,"file":"glob-pattern.js","sourceRoot":"","sources":["../../src/glob/glob-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,yDAAyD;AACzD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAE7C,mFAAmF;AACnF,MAAM,GAAG,GAAG,GAAG,CAAC;AAEhB;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,MAAM,CAAC,MAAc;IACnC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,GAAG,KAAK,CAAC;YAChB,SAAS;QACX,CAAC;QACD,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAChB,OAAO,GAAG,IAAI,CAAC;YACf,SAAS;QACX,CAAC;QACD,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,yEAAyE;IACzE,qEAAqE;IACrE,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,cAAc,GAAa,EAAE,CAAC;IAEpC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACpB,MAAM;QACR,CAAC;QACD,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,cAAc,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC9C,oEAAoE;QACpE,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAClB,uEAAuE;QACvE,uEAAuE;QACvE,sEAAsE;QACtE,uEAAuE;QACvE,gDAAgD;QAChD,OAAO,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAChD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;QACjB,+EAA+E;QAC/E,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,yDAAyD;QACzD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;QACjB,yEAAyE;QACzE,yEAAyE;QACzE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IACD,wDAAwD;IACxD,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACxC,CAAC"}
1
+ {"version":3,"file":"glob-pattern.js","sourceRoot":"","sources":["../../src/glob/glob-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,yDAAyD;AACzD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAE7C,mFAAmF;AACnF,MAAM,GAAG,GAAG,GAAG,CAAC;AAEhB;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,MAAM,CAAC,MAAc;IACnC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,GAAG,KAAK,CAAC;YAChB,SAAS;QACX,CAAC;QACD,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAChB,OAAO,GAAG,IAAI,CAAC;YACf,SAAS;QACX,CAAC;QACD,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,yEAAyE;IACzE,qEAAqE;IACrE,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,cAAc,GAAa,EAAE,CAAC;IAEpC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACpB,MAAM;QACR,CAAC;QACD,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,cAAc,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC9C,oEAAoE;QACpE,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAClB,uEAAuE;QACvE,uEAAuE;QACvE,sEAAsE;QACtE,uEAAuE;QACvE,gDAAgD;QAChD,OAAO,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAChD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;QACjB,+EAA+E;QAC/E,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,yDAAyD;QACzD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;QACjB,yEAAyE;QACzE,yEAAyE;QACzE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IACD,wDAAwD;IACxD,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACxC,CAAC"}
package/dist/glob.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @vibe-agent-toolkit/utils/glob
3
+ *
4
+ * Glob pattern inspection (`isGlob`, static base extraction, magic
5
+ * remainder). Pure string analysis — reaches no Node builtin.
6
+ */
7
+ export * from './glob/glob-pattern.js';
8
+ //# sourceMappingURL=glob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../src/glob.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,wBAAwB,CAAC"}
package/dist/glob.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @vibe-agent-toolkit/utils/glob
3
+ *
4
+ * Glob pattern inspection (`isGlob`, static base extraction, magic
5
+ * remainder). Pure string analysis — reaches no Node builtin.
6
+ */
7
+ export * from './glob/glob-pattern.js';
8
+ //# sourceMappingURL=glob.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.js","sourceRoot":"","sources":["../src/glob.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Pure path-string helpers.
3
+ *
4
+ * **This module's only import is `node:path`.** Nothing here touches the
5
+ * filesystem, the OS, or URLs — that is the whole point: the `./path` and
6
+ * `./glob` subpath entries re-export from here so importing them can never
7
+ * pull `node:fs`, `node:os`, or `node:url` into a consumer's graph.
8
+ *
9
+ * Filesystem-touching path helpers (`normalizePath`, `normalizedTmpdir`,
10
+ * `mkdirSyncReal`, `resolveFromImportMeta`, `dynamicImportPath`) live in
11
+ * `./path-utils.ts` and are exposed via the `./fs` entry.
12
+ */
13
+ /**
14
+ * Check if a path is absolute
15
+ *
16
+ * Cross-platform detection of absolute paths:
17
+ * - Unix: /path/to/file
18
+ * - Windows: C:\path\to\file or C:/path/to/file
19
+ *
20
+ * @param p - Path to check
21
+ * @returns True if path is absolute
22
+ *
23
+ * @example
24
+ * isAbsolutePath('/path/to/file') // true
25
+ * isAbsolutePath('./relative') // false
26
+ * isAbsolutePath('C:/Windows') // true (Windows)
27
+ */
28
+ export declare function isAbsolutePath(p: string): boolean;
29
+ /**
30
+ * True if `p` is absolute on ANY platform — a POSIX root path (`/etc`), a
31
+ * Windows drive-letter path (`C:\…` or `C:/…`), or a UNC path (`\\host\share`).
32
+ *
33
+ * Unlike {@link isAbsolutePath} (host-platform only), this is host-independent,
34
+ * so config-containment checks reject Windows-absolute paths even when run on
35
+ * POSIX CI, and vice versa. Used to keep config-supplied relative paths (skill
36
+ * `files:` dest) from escaping their anchor directory (zip-slip class).
37
+ *
38
+ * @example
39
+ * isAbsoluteAnyPlatform('/etc/passwd') // true (POSIX)
40
+ * isAbsoluteAnyPlatform('C:\\Users') // true (Windows drive)
41
+ * isAbsoluteAnyPlatform('scripts/cli') // false (relative)
42
+ */
43
+ export declare function isAbsoluteAnyPlatform(p: string): boolean;
44
+ /**
45
+ * True if `p` contains a `..` parent-directory traversal segment.
46
+ *
47
+ * Forward-slash-normalized, then inspects each `/`-delimited segment — so a
48
+ * `..` is caught regardless of the original OS separator. A containment guard
49
+ * for config-supplied relative paths (skill `files:` dest values, glob magic
50
+ * remainders) that must never climb above their anchor directory.
51
+ *
52
+ * @example
53
+ * hasParentTraversalSegment('a/../b') // true
54
+ * hasParentTraversalSegment('a/b/c') // false
55
+ * hasParentTraversalSegment('..\\evil') // true (backslash normalized)
56
+ * hasParentTraversalSegment('a..b/c') // false (".." must be a whole segment)
57
+ */
58
+ export declare function hasParentTraversalSegment(p: string): boolean;
59
+ /**
60
+ * Compute a `ValidationIssue.location`: an absolute source file path made
61
+ * relative to the scan/project root, forward-slashed.
62
+ *
63
+ * This is the ONE relativizer every VAT validation lane uses. `location` is
64
+ * contractually project-relative (see `ValidationIssue` in
65
+ * `@vibe-agent-toolkit/agent-schema`), so producers must route through here
66
+ * rather than emitting `skillPath` directly — absolute locations leak the
67
+ * developer's home directory into CI logs and make `validation.allow` globs,
68
+ * which match against `location`, unwritable.
69
+ *
70
+ * `projectRoot` is required precisely because "relative to what?" has no safe
71
+ * default: a caller with no root must decide one (the skill directory, the
72
+ * scan root) rather than silently falling back to an absolute path.
73
+ *
74
+ * @param sourceFilePath - Absolute path to the file the issue was found in.
75
+ * @param projectRoot - Root the location is expressed relative to.
76
+ * @returns Forward-slashed relative location.
77
+ *
78
+ * @example
79
+ * issueLocation('/repo/skills/foo/SKILL.md', '/repo') // 'skills/foo/SKILL.md'
80
+ */
81
+ export declare function issueLocation(sourceFilePath: string, projectRoot: string): string;
82
+ /**
83
+ * Convert a relative path to absolute
84
+ *
85
+ * If path is already absolute, returns it normalized.
86
+ * Otherwise resolves relative to baseDir.
87
+ *
88
+ * @param p - Path to convert
89
+ * @param baseDir - Base directory for resolution
90
+ * @returns Absolute path with **forward slashes** (cross-platform safe)
91
+ *
92
+ * @example
93
+ * toAbsolutePath('./docs/README.md', '/project')
94
+ * // Returns: '/project/docs/README.md'
95
+ *
96
+ * toAbsolutePath('/absolute/path.md', '/project')
97
+ * // Returns: '/absolute/path.md'
98
+ */
99
+ export declare function toAbsolutePath(p: string, baseDir: string): string;
100
+ /**
101
+ * Get the relative path from one file to another
102
+ *
103
+ * Useful for generating relative links between markdown files.
104
+ *
105
+ * @param from - Source file path (absolute)
106
+ * @param to - Target file path (absolute)
107
+ * @returns Relative path from source to target with **forward slashes** (cross-platform safe)
108
+ *
109
+ * @example
110
+ * getRelativePath('/project/docs/guide.md', '/project/README.md')
111
+ * // Returns: '../README.md'
112
+ *
113
+ * getRelativePath('/project/README.md', '/project/docs/api.md')
114
+ * // Returns: 'docs/api.md'
115
+ */
116
+ export declare function getRelativePath(from: string, to: string): string;
117
+ /**
118
+ * Convert a path to forward slashes
119
+ *
120
+ * Windows accepts both forward slashes and backslashes as path separators.
121
+ * This function normalizes all paths to use forward slashes for consistency.
122
+ * Useful for glob pattern matching, cross-platform comparisons, and string operations.
123
+ *
124
+ * @param p - Path to convert
125
+ * @returns Path with forward slashes
126
+ *
127
+ * @example
128
+ * toForwardSlash('C:\\Users\\docs\\README.md')
129
+ * // Returns: 'C:/Users/docs/README.md'
130
+ *
131
+ * toForwardSlash('/project/docs/README.md')
132
+ * // Returns: '/project/docs/README.md' (unchanged)
133
+ */
134
+ export declare function toForwardSlash(p: string): string;
135
+ /**
136
+ * Cross-platform safe path operations.
137
+ *
138
+ * Wraps Node's `path.join()`, `path.resolve()`, and `path.relative()` to always
139
+ * return forward-slash paths. On Windows, the native `path.*` functions return
140
+ * backslashes, which causes bugs when paths are used as Map keys, compared as
141
+ * strings, or matched with glob patterns.
142
+ *
143
+ * **Use these instead of importing from `node:path` directly.**
144
+ * ESLint rules enforce this — see `no-path-join`, `no-path-resolve`, `no-path-relative`.
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * import { safePath } from '@vibe-agent-toolkit/utils';
149
+ *
150
+ * // Always forward slashes, even on Windows
151
+ * safePath.join('C:\\Users', 'docs', 'file.md') // → 'C:/Users/docs/file.md'
152
+ * safePath.resolve('/project', './docs') // → '/project/docs'
153
+ * safePath.relative('/project/docs', '/project') // → '..'
154
+ * safePath.joinUnderRoot('/harness', 'skill-abc') // → '/harness/skill-abc'
155
+ * safePath.joinUnderRoot('/harness', '../escape') // throws Error
156
+ * ```
157
+ */
158
+ export declare const safePath: {
159
+ /** Like `path.join()` but always returns forward slashes. */
160
+ readonly join: (...paths: string[]) => string;
161
+ /** Like `path.resolve()` but always returns forward slashes. */
162
+ readonly resolve: (...paths: string[]) => string;
163
+ /** Like `path.relative()` but always returns forward slashes. */
164
+ readonly relative: (from: string, to: string) => string;
165
+ /**
166
+ * Join path segments under a security root, throwing if the result would escape.
167
+ *
168
+ * Resolves `root + segments` and verifies the result is strictly inside `root`
169
+ * (or equal to it). Throws when any segment would cause the result to escape:
170
+ *
171
+ * - A `..` traversal that climbs above root
172
+ * - An absolute POSIX path segment (e.g. `/etc/passwd`)
173
+ * - A Windows drive-letter segment (e.g. `C:\Users\evil`)
174
+ *
175
+ * On success returns a forward-slash-normalized absolute path (consistent with
176
+ * the other `safePath` helpers).
177
+ *
178
+ * **Use this instead of `safePath.join(root, segment)` whenever `segment` may
179
+ * contain caller-controlled input** — this is the bug class that the original
180
+ * skill-test staging code was vulnerable to on Windows.
181
+ *
182
+ * @returns Forward-slash absolute path guaranteed to be inside `root`.
183
+ * @throws {Error} If the resolved path would escape `root`.
184
+ *
185
+ * @example
186
+ * ```typescript
187
+ * // ✅ Safe — throws if caller passes '../../../etc'
188
+ * const dest = safePath.joinUnderRoot(harnessRoot, stagedDirName(item.name));
189
+ *
190
+ * // ❌ Unsafe — silently escapes on Windows with absolute segment
191
+ * const dest = safePath.join(harnessRoot, item.name);
192
+ * ```
193
+ */
194
+ readonly joinUnderRoot: (root: string, ...segments: string[]) => string;
195
+ };
196
+ //# sourceMappingURL=path-core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-core.d.ts","sourceRoot":"","sources":["../src/path-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAEjF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAKjE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,QAAQ;IACnB,6DAA6D;8BAC9C,MAAM,EAAE,KAAG,MAAM;IAIhC,gEAAgE;iCAC9C,MAAM,EAAE,KAAG,MAAM;IAInC,iEAAiE;8BAClD,MAAM,MAAM,MAAM,KAAG,MAAM;IAI1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;mCACiB,MAAM,eAAe,MAAM,EAAE,KAAG,MAAM;CAuClD,CAAC"}