Ver Fonte

fix: normalize glob paths with split(sep).join('/') on Windows

glob/globSync returns host-separator paths on Windows. Nine scripts that consume these paths for split('/'), manifest-key comparison, startsWith/includes exclusion checks, or committed-output rendering now normalize with .map(s => s.split(sep).join('/')) at ingestion. This replaces the previous replaceAll('\\\\', '/') with an explicit, self-documenting OS-separator-to-POSIX conversion.
Huanqi Cao há 2 meses atrás
pai
commit
ae8aedb2fd

+ 2 - 2
scripts/gen-config-catalog.ts

@@ -8,7 +8,7 @@
  */
 
 import { globSync, readFileSync, writeFileSync } from 'node:fs'
-import { dirname, resolve } from 'node:path'
+import { dirname, resolve, sep } from 'node:path'
 import ts from 'typescript'
 import { LINK_MAP } from './gen-cordis-catalog.ts'
 import { parseJsDoc, pointer, rawJsDoc } from './jsdoc.ts'
@@ -581,7 +581,7 @@ export function collectConfigCatalog(scanRoot: string = root): CatalogEntry[] {
   // workspace-package imports while individual packages are still being walked.
   const pkgDirByName = new Map<string, string>()
   const manifests: { dir: string; pkg: string }[] = []
-  for (const manifestRel of globSync('packages/*/*/package.json', { cwd: scanRoot }).sort()) {
+  for (const manifestRel of globSync('packages/*/*/package.json', { cwd: scanRoot }).map(path => path.split(sep).join('/')).sort()) {
     const dir = manifestRel.slice(0, -'/package.json'.length)
     const manifest = JSON.parse(readFileSync(resolve(scanRoot, manifestRel), 'utf8')) as { name?: string; os?: string[]; cpu?: string[] }
     const pkg = manifest.name

+ 3 - 3
scripts/gen-cordis-catalog.ts

@@ -6,7 +6,7 @@
  */
 
 import { globSync, readFileSync, writeFileSync } from 'node:fs'
-import { resolve } from 'node:path'
+import { resolve, sep } from 'node:path'
 import ts from 'typescript'
 import { checkParams, checkReturns, parseJsDoc, parseTags, pointer, rawJsDoc, reportViolations, type Mode } from './jsdoc.ts'
 
@@ -129,7 +129,7 @@ function memberSignature(member: ts.TypeElement | ts.ClassElement, sf: ts.Source
 export function collectEvents(scanRoot: string = root): EventEntry[] {
   const entries: EventEntry[] = []
   const violations: string[] = []
-  for (const rel of globSync('packages/*/*/src/*.ts', { cwd: scanRoot }).sort()) {
+  for (const rel of globSync('packages/*/*/src/*.ts', { cwd: scanRoot }).map(s => s.split(sep).join('/')).sort()) {
     const abs = resolve(scanRoot, rel)
     const text = readFileSync(abs, 'utf8')
     if (!text.includes('interface Events')) continue
@@ -183,7 +183,7 @@ export function collectEvents(scanRoot: string = root): EventEntry[] {
 export function collectServices(scanRoot: string = root): ServiceEntry[] {
   const entries: ServiceEntry[] = []
   const violations: string[] = []
-  for (const rel of globSync('packages/*/*/src/index.ts', { cwd: scanRoot }).sort()) {
+  for (const rel of globSync('packages/*/*/src/index.ts', { cwd: scanRoot }).map(s => s.split(sep).join('/')).sort()) {
     const abs = resolve(scanRoot, rel)
     const text = readFileSync(abs, 'utf8')
     if (!text.includes('interface Context')) continue

+ 3 - 3
scripts/gen-persistence-catalog.ts

@@ -7,7 +7,7 @@
  */
 
 import { globSync, readFileSync, writeFileSync } from 'node:fs'
-import { resolve } from 'node:path'
+import { resolve, sep } from 'node:path'
 import ts from 'typescript'
 import { parseJsDoc, pointer, rawJsDoc, reportViolations } from './jsdoc.ts'
 
@@ -117,7 +117,7 @@ export function collectLogEvents(scanRoot: string = root): LogEventEntry[] {
   const violations: string[] = []
   const seen = new Map<string, string>()
   let owningDecl: string | null = null
-  for (const rel of globSync('packages/*/*/src/**/*.ts', { cwd: scanRoot }).sort()) {
+  for (const rel of globSync('packages/*/*/src/**/*.ts', { cwd: scanRoot }).map(s => s.split(sep).join('/')).sort()) {
     const abs = resolve(scanRoot, rel)
     const text = readFileSync(abs, 'utf8')
     if (!text.includes('SessionEventMap')) continue
@@ -194,7 +194,7 @@ export function collectLogEvents(scanRoot: string = root): LogEventEntry[] {
  */
 export function collectSurfaceEventTypes(scanRoot: string = root): string[] {
   const found: { names: string[]; source: string }[] = []
-  for (const rel of globSync('packages/*/*/src/**/*.ts', { cwd: scanRoot }).sort()) {
+  for (const rel of globSync('packages/*/*/src/**/*.ts', { cwd: scanRoot }).map(s => s.split(sep).join('/')).sort()) {
     const abs = resolve(scanRoot, rel)
     const text = readFileSync(abs, 'utf8')
     if (!text.includes('SurfaceEventType')) continue

+ 2 - 2
scripts/package-graph.ts

@@ -6,7 +6,7 @@
  */
 
 import { globSync, readFileSync } from 'node:fs'
-import { dirname, resolve } from 'node:path'
+import { dirname, resolve, sep } from 'node:path'
 
 const SCOPE = '@deepseek-ai/dsh-'
 
@@ -33,7 +33,7 @@ export interface PackageGraphNode {
  */
 export function collectPackageGraph(root: string, groupOrder: readonly string[], gate: string): PackageGraphNode[] {
   const packages: PackageGraphNode[] = []
-  for (const rel of globSync('packages/*/*/package.json', { cwd: root }).sort()) {
+  for (const rel of globSync('packages/*/*/package.json', { cwd: root }).map(path => path.split(sep).join('/')).sort()) {
     const json = JSON.parse(readFileSync(resolve(root, rel), 'utf8')) as {
       name: string
       peerDependencies?: Record<string, string>

+ 2 - 2
scripts/rfc-index.ts

@@ -7,7 +7,7 @@
  */
 
 import { readFileSync, readdirSync } from 'node:fs'
-import { resolve } from 'node:path'
+import { resolve, sep } from 'node:path'
 import { globSync } from 'node:fs'
 
 export const rfcRoot = resolve(import.meta.dirname, '../docs/rfc')
@@ -58,7 +58,7 @@ export function walkRfcTree(): { rfcs: Rfc[]; errors: string[] } {
     }
   }
   for (const lifecycle of LIFECYCLES) {
-    for (const match of globSync(`${lifecycle}/**/*.md`, { cwd: rfcRoot }).sort()) {
+    for (const match of globSync(`${lifecycle}/**/*.md`, { cwd: rfcRoot }).map(path => path.split(sep).join('/')).sort()) {
       const segs = match.split('/')
       // Allowlisted file directly at the lifecycle root (e.g. implemented/AGENTS.md).
       if (segs.length === 2 && ROOT_ALLOWLIST.has(segs[1] ?? '')) continue

+ 2 - 2
scripts/verify-package-readme-limitations.ts

@@ -6,7 +6,7 @@
  */
 
 import { existsSync, globSync, readFileSync } from 'node:fs'
-import { resolve } from 'node:path'
+import { resolve, sep } from 'node:path'
 import { markdownHeadingLines, markdownProseLines } from './markdown.ts'
 
 const root = resolve(import.meta.dirname, '..')
@@ -30,7 +30,7 @@ function isLimitationsLike(headingText: string): boolean {
   )
 }
 
-const packageJsons = globSync('packages/*/*/package.json', { cwd: root }).sort()
+const packageJsons = globSync('packages/*/*/package.json', { cwd: root }).map(path => path.split(sep).join('/')).sort()
 const scannedPackages = new Set(packageJsons.map(path => path.slice(0, -'/package.json'.length)))
 const failures: string[] = []
 

+ 2 - 2
scripts/verify-package-readme-model-experience.ts

@@ -6,7 +6,7 @@
  */
 
 import { existsSync, globSync, readFileSync } from 'node:fs'
-import { relative, resolve } from 'node:path'
+import { relative, resolve, sep } from 'node:path'
 import { markdownHeadingLines, markdownProseLines, type MarkdownProseLine } from './markdown.ts'
 
 const root = resolve(import.meta.dirname, '..')
@@ -145,7 +145,7 @@ for (const line of readFileSync(resolve(root, 'docs/tool-catalog.md'), 'utf8').s
 }
 
 const failures: Failure[] = []
-const packageJsons = globSync('packages/*/*/package.json', { cwd: root }).sort()
+const packageJsons = globSync('packages/*/*/package.json', { cwd: root }).map(path => path.split(sep).join('/')).sort()
 const scannedPackages = new Set(packageJsons.map(path => path.slice(0, -'/package.json'.length)))
 let structuredCount = 0
 let contextSurfaceCount = 0

+ 2 - 2
scripts/verify-type-equiv.ts

@@ -5,7 +5,7 @@
  */
 
 import { globSync, readFileSync, existsSync } from 'node:fs'
-import { resolve } from 'node:path'
+import { resolve, sep } from 'node:path'
 import ts from 'typescript'
 
 const root = resolve(import.meta.dirname, '..')
@@ -121,7 +121,7 @@ const keyOf = (x: { doc: string; symbol: string }): string => `${x.doc}::${x.sym
 // as an orphan rather than silently skipped.
 const docSet = new Set<string>()
 for (const pattern of MARKDOWN_GLOBS) {
-  for (const match of globSync(pattern, { cwd: root })) docSet.add(match)
+  for (const match of globSync(pattern, { cwd: root })) docSet.add(match.split(sep).join('/'))
 }
 const blocks: EquivBlock[] = [...docSet].sort().flatMap(extractEquivBlocks)