Files
deepseek-harness/scripts/verify-runtime-closure.ts
Tianyi Cui c3873464ba refactor(scripts): consolidate gate scripts on mdast fences, parseArgs, and globSync
Implements the gate-consolidation Agent Note from the NIH dependency audit:

- Shared markdownFences helper in scripts/markdown.ts (mdast code-node visit);
  doc-typecheck and verify-type-equiv extract fences through it; md-fences.ts
  and the duplicated extractEquivBlocks regex scanner are deleted;
  markdownProseLines derives fenced lines from parsed code-node positions
  instead of a second fence regex.
- publint-all.ts and verify-built-package-invariants.mjs parse argv with
  node:util parseArgs instead of hand-stepped parseOptions copies.
- Five straggler readdirSync walks become globSync: verify-runtime-closure,
  dev-web discoverPluginDirs, verify-package-paths realPackageNames,
  verify-client-domain-graph listSources, publint-all addPath. The
  dirent-diagnostic walks in check-workspace-constraints.ts and clean.ts stay.

Behavior parity verified: pnpm run doc-sync and every rewritten gate produce
byte-identical output before and after on this tree.

Moves the owning Agent Note proposed -> implemented and re-records its pair.
2026-07-26 23:14:28 +08:00

104 lines
3.7 KiB
TypeScript

/**
* Verify that the executable deploy manifest supplies every required workspace
* peer in its dependency graph. With auto peer installation disabled, a missing
* root peer can otherwise fail only when Cordis loads the packaged plugin.
*/
import { globSync } from 'node:fs'
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
import { parseArgs } from 'node:util'
interface PackageManifest {
name?: string
dependencies?: Record<string, string>
optionalDependencies?: Record<string, string>
peerDependencies?: Record<string, string>
peerDependenciesMeta?: Record<string, { optional?: boolean }>
}
interface WorkspacePackage {
path: string
manifest: PackageManifest
}
const root = resolve(import.meta.dirname, '..')
const { values } = parseArgs({
args: process.argv.slice(2),
options: { manifest: { type: 'string' } },
})
const runtimeManifestPath = resolve(root, values.manifest ?? 'python/sdk-runtime/package.json')
const runtimeManifest = await loadManifest(runtimeManifestPath)
const runtimeName = runtimeManifest.name ?? 'python/sdk-runtime'
const workspace = await loadWorkspacePackages()
const runtimeDependencies = runtimeManifest.dependencies ?? {}
const parents = new Map<string, string | undefined>()
const queue: string[] = []
for (const dependency of Object.keys(runtimeDependencies).sort()) {
if (!workspace.has(dependency)) continue
parents.set(dependency, undefined)
queue.push(dependency)
}
const failures: string[] = []
for (let index = 0; index < queue.length; index += 1) {
const packageName = queue[index]
if (packageName === undefined) continue
const current = workspace.get(packageName)
if (current === undefined) continue
const peers = current.manifest.peerDependencies ?? {}
const peerMeta = current.manifest.peerDependenciesMeta ?? {}
for (const peer of Object.keys(peers).sort()) {
if (!workspace.has(peer) || peerMeta[peer]?.optional === true) continue
if (runtimeDependencies[peer]?.startsWith('workspace:') === true) continue
failures.push(`${formatChain(runtimeName, packageName, parents)} -> ${peer}`)
}
const dependencies = {
...current.manifest.dependencies,
...current.manifest.optionalDependencies,
}
for (const dependency of Object.keys(dependencies).sort()) {
if (!workspace.has(dependency) || parents.has(dependency)) continue
parents.set(dependency, packageName)
queue.push(dependency)
}
}
if (failures.length > 0) {
console.error('verify-runtime-closure: required workspace peers are missing from python/sdk-runtime dependencies:')
for (const failure of failures) console.error(` ${failure}`)
process.exit(1)
}
console.log(`verify-runtime-closure: ${queue.length} workspace packages form a closed runtime dependency graph.`)
async function loadWorkspacePackages(): Promise<Map<string, WorkspacePackage>> {
const paths = globSync(['packages/*/*/package.json', 'vendor/*/package.json'], { cwd: root })
.sort()
.map(relative => resolve(root, relative))
const result = new Map<string, WorkspacePackage>()
for (const path of paths) {
const manifest = await loadManifest(path)
if (manifest.name !== undefined) result.set(manifest.name, { path, manifest })
}
return result
}
async function loadManifest(path: string): Promise<PackageManifest> {
return JSON.parse(await readFile(path, 'utf8')) as PackageManifest
}
function formatChain(
runtimeName: string,
packageName: string,
parents: ReadonlyMap<string, string | undefined>,
): string {
const chain = [packageName]
let parent = parents.get(packageName)
while (parent !== undefined) {
chain.unshift(parent)
parent = parents.get(parent)
}
return [runtimeName, ...chain].join(' -> ')
}