diff --git a/.agents/notes/implemented/process/2026-08-27-explicit-workspace-path-aliases.i18n.yaml b/.agents/notes/implemented/process/2026-08-27-explicit-workspace-path-aliases.i18n.yaml new file mode 100644 index 0000000000..b4862560f8 --- /dev/null +++ b/.agents/notes/implemented/process/2026-08-27-explicit-workspace-path-aliases.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-27-explicit-workspace-path-aliases.md +2026-08-27-explicit-workspace-path-aliases.md: 4cd97062fa56b5b8730101e81d20b33b206ea670 +2026-08-27-explicit-workspace-path-aliases.zh.md: 003f04077837b055a50996edb49cdc25ccd8f73a diff --git a/.agents/notes/implemented/process/2026-08-27-explicit-workspace-path-aliases.md b/.agents/notes/implemented/process/2026-08-27-explicit-workspace-path-aliases.md new file mode 100644 index 0000000000..4cd97062fa --- /dev/null +++ b/.agents/notes/implemented/process/2026-08-27-explicit-workspace-path-aliases.md @@ -0,0 +1,53 @@ +# Agent Note: Explicit workspace path aliases replace per-group wildcards + +Status: implemented + +English | [中文](2026-08-27-explicit-workspace-path-aliases.zh.md) + +## Problem + +`tsconfig.base.json` is the resolution facade for the whole repository: every package project extends it, both aggregates read it, and every Vitest config points `vite-tsconfig-paths` at it. Two of its aliases carried one candidate per package *group* rather than one per package — `@deepseek-ai/dsh-*` listed 49 candidate globs and `@deepseek-ai/dsh-*/invariant` listed 45. + +TypeScript and tsx try those candidates in order and take the first that exists, so a specifier whose package sits late in the list pays for every earlier miss. Under the `dsh` source launch each miss is an `ERR_MODULE_NOT_FOUND` that Node decorates with `decorateErrorWithCommonJSHints`, which runs a full CommonJS resolution walk per failure. A profile of a source-launch boot attributed 934.6 ms — 35% of the boot — to that decoration path alone, from 60,942 failed resolutions. + +The cost fell hardest on the most-imported packages. `packages/util/*` sat at position 44 of 49 and holds the leaf utilities nearly every plugin imports, so `dsh-timeout` paid roughly 9 ms per resolution against 0.05 ms for a specifier with an explicit alias. + +## Decision + +`scripts/gen-tsconfig-paths.ts` writes one explicit alias per workspace package into a marked region at the end of `paths`, and both group wildcards are deleted. `pnpm run gen-tsconfig-paths` rewrites the region; `pnpm run verify-tsconfig-paths` reports drift instead, and runs in the `ci-static` lane beside the other generated-artifact checks. + +The generator emits an alias only for a package whose declared name is exactly `@deepseek-ai/dsh-`, because that is the only shape a wildcard could ever have resolved: it substituted the specifier's suffix into `packages///src`. Packages named after something other than their directory — `@deepseek-ai/dsh-typert-protocol` at `packages/typert/protocol`, the `dsh-client-*` and `dsh-host-*` families — already carry hand-written aliases and are left alone. A specifier claimed by two package directories throws rather than picking one, because an explicit map cannot express the group-order tiebreak the wildcard used; no such collision exists today. + +The region is written by text surgery between marker comments rather than by re-serializing the file. `tsconfig.base.json` is JSONC and its hand-written aliases carry comments that explain non-obvious mappings; re-serializing would drop them. + +Four wildcards remain, each with a single candidate: `dsh-host-*/invariant`, `dsh-client-*/invariant`, `dsh-client-*/client`, and the five `dsh-host-/*` subpath maps. One candidate costs one probe, so expanding them would trade file size for nothing. + +## Resolution differences this change makes + +Every `@deepseek-ai/dsh-*` specifier appearing in repository sources — 1,022 distinct — resolves to the same target as before, with seven exceptions that now resolve where they previously did not: + +`dsh-invariants/invariant`, `dsh-lsp/invariant`, `dsh-lsp-stdio/invariant`, `dsh-tool-lsp/invariant`, `dsh-terminal/invariant`, `dsh-terminal-bash/invariant`, and `dsh-tool-terminal/invariant`. + +The deleted `dsh-*/invariant` wildcard omitted the `lsp`, `terminal`, `client`, and `host` groups. The `client` and `host` omissions are deliberate and documented — those families have dedicated wildcards because their package names prefix the group directory. The `lsp` and `terminal` omissions have no such reason, and `packages/runtime-diagnostics/invariants` appeared in neither list. Those seven specifiers therefore resolved through the workspace symlink and the package's `./invariant` export to built `lib/types/*.d.ts` instead of to source, which contradicts the rule that static gates resolve workspace imports through `paths` to `src` and pass on a clean tree. Making the aliases uniform resolves them to source like every sibling. + +## Testing + +`scripts/gen-tsconfig-paths.spec.ts` pins that the collector maps a package to its own directory, skips packages carrying hand-written aliases, and returns a sorted list; that the renderer yields to a hand-written specifier and closes the region without a trailing comma; that the region writer replaces only the marked span and refuses a config without markers; and that neither group wildcard survives in the committed config. + +The gate's rejection path is exercised directly: deleting one generated alias makes `verify-tsconfig-paths` exit non-zero, and restoring it makes the check pass. + +## Alternatives considered + +**Reordering the wildcard's candidate globs so the hottest groups come first.** This needs no generator and no new gate, and recovers perhaps half the cost by moving `util`, `core`, `llm`, and `session` to the front. It was rejected because the win decays as packages are added, the ordering has no invariant a reader could check, and every group after the first still pays. It also leaves the worst property intact: adding a package group silently slows every boot. + +**Moving `paths` into a generated `tsconfig.paths.json` that the base config extends.** This keeps the generated content out of the hand-written file entirely and produces a cleaner diff. It was rejected for this change because several consumers read `tsconfig.base.json` directly rather than through a resolver that follows `extends` — six Vitest configs plus `project-reference-faces.ts`, `verify-export-jsdoc.ts`, `doc-typecheck.ts`, and `rescope-vendor.ts` — and auditing each is a larger change than the aliasing itself. The marker region achieves the same isolation with no consumer risk. + +**Keeping the wildcards as a fallback beneath the explicit aliases.** An explicit alias already wins over a wildcard, so correctness would be unchanged, and a package added without regenerating would keep resolving. It was rejected because the fallback is exactly what makes a stale config invisible: the repository's stance is that misconfiguration fails loud, and the `--check` gate turns a missing alias into a named failure instead of a slow boot nobody attributes. + +## Consequences + +A source-launch boot of the `headless` profile drops from a 2,157/2,182/2,153 ms baseline to 1,069/1,052/1,055 ms — about 1.1 seconds, or 51%, with the two ranges nowhere near overlapping and `--help` output byte-identical. + +The win is confined to the tsx source launch. Vitest resolves through `vite-tsconfig-paths`, which matches in-process and checks file existence without ever constructing a Node module error, so it never paid the decoration cost: an A/B over one package's suite measured 5,934/5,829/5,908 ms against 5,878/5,851/5,905 ms, which is noise. Repository gate scripts import few `@deepseek-ai/dsh-*` packages and likewise show no separable difference. Shipped users run built `lib/` under plain Node and were never affected. + +`paths` grows from 188 keys to 519, and adding a package now requires running the generator. The `--check` gate makes that a named failure rather than a silent one, and the generated region keeps the diff of such a change to a single line. diff --git a/.agents/notes/implemented/process/2026-08-27-explicit-workspace-path-aliases.zh.md b/.agents/notes/implemented/process/2026-08-27-explicit-workspace-path-aliases.zh.md new file mode 100644 index 0000000000..003f040778 --- /dev/null +++ b/.agents/notes/implemented/process/2026-08-27-explicit-workspace-path-aliases.zh.md @@ -0,0 +1,53 @@ +# Agent Note: Explicit workspace path aliases replace per-group wildcards + +Status: implemented + +[English](2026-08-27-explicit-workspace-path-aliases.md) | 中文 + +## Problem + +`tsconfig.base.json` 是整个仓库的解析门面:每个包的 project 都 extends 它,两个聚合配置都读它,每个 Vitest 配置都把 `vite-tsconfig-paths` 指向它。其中两条别名按包**分组**而不是按包各写一条候选——`@deepseek-ai/dsh-*` 列了 49 个候选 glob,`@deepseek-ai/dsh-*/invariant` 列了 45 个。 + +TypeScript 与 tsx 按顺序逐个尝试这些候选、取第一个存在的,因此一个位于列表靠后位置的包,其说明符要为前面每一次未命中买单。在 `dsh` 源码启动下,每次未命中都是一个 `ERR_MODULE_NOT_FOUND`,而 Node 会用 `decorateErrorWithCommonJSHints` 装饰它——每次失败都跑一遍完整的 CommonJS 解析走查。一次源码启动的 profile 把 **934.6 ms(占启动 35%)**单独归给了这条装饰路径,来源是 60,942 次失败解析。 + +代价最重的恰好落在被引用最多的包上:`packages/util/*` 排在 49 个候选里的第 44 位,却装着几乎每个插件都要引用的叶子工具,因此 `dsh-timeout` 每次解析约付 9 ms,而一个有显式别名的说明符只要 0.05 ms。 + +## Decision + +`scripts/gen-tsconfig-paths.ts` 在 `paths` 末尾一个带标记的区域里,为每个 workspace 包写入一条显式别名,两条分组通配符随之删除。`pnpm run gen-tsconfig-paths` 重写该区域;`pnpm run verify-tsconfig-paths` 只报告漂移,并与其他生成物检查一起跑在 `ci-static` 车道上。 + +生成器只为**声明名恰好等于 `@deepseek-ai/dsh-<目录名>`** 的包发别名,因为那是通配符唯一可能解析出的形态:它把说明符的后缀代入 `packages//<后缀>/src`。名字与目录不一致的包——`packages/typert/protocol` 上的 `@deepseek-ai/dsh-typert-protocol`、以及 `dsh-client-*` 与 `dsh-host-*` 两族——本来就有手写别名,保持不动。若某个说明符被两个包目录同时认领,生成器**抛错**而不是任选其一,因为显式映射无法表达通配符依赖的分组顺序裁决;当前不存在这种冲突。 + +该区域用标记注释之间的**定点文本改写**生成,而不是重新序列化整个文件。`tsconfig.base.json` 是 JSONC,其手写别名带有解释非显然映射的注释,重新序列化会把它们丢掉。 + +保留四条通配符,每条只有一个候选:`dsh-host-*/invariant`、`dsh-client-*/invariant`、`dsh-client-*/client`,以及五条 `dsh-host-/*` 子路径映射。一个候选只花一次探测,展开它们只会换来文件变大而无收益。 + +## Resolution differences this change makes + +仓库源码中出现的每个 `@deepseek-ai/dsh-*` 说明符——共 1,022 个互不相同——解析目标与改动前完全一致,只有七个例外:它们现在能解析,而此前不能。 + +`dsh-invariants/invariant`、`dsh-lsp/invariant`、`dsh-lsp-stdio/invariant`、`dsh-tool-lsp/invariant`、`dsh-terminal/invariant`、`dsh-terminal-bash/invariant`、`dsh-tool-terminal/invariant`。 + +被删除的 `dsh-*/invariant` 通配符遗漏了 `lsp`、`terminal`、`client`、`host` 四个分组。其中 `client` 与 `host` 的遗漏是**刻意且有文档的**——这两族有专用通配符,因为它们的包名以分组目录名为前缀。而 `lsp` 与 `terminal` 的遗漏没有任何这类理由,`packages/runtime-diagnostics/invariants` 则两条列表都不在。于是这七个说明符此前是通过 workspace 软链与包的 `./invariant` 导出解析到构建产物 `lib/types/*.d.ts`,而不是解析到源码——这与「静态门禁通过 `paths` 把 workspace 导入解析到 `src`、并在干净树上通过」的规则相抵触。把别名统一之后,它们与所有同类一样解析到源码。 + +## Testing + +`scripts/gen-tsconfig-paths.spec.ts` 钉住:收集器把包映射到它自己的目录、跳过带手写别名的包、返回有序列表;渲染器让位于手写说明符,且区域收尾不带多余逗号;区域写入器只替换标记范围,并在缺少标记时拒绝;以及提交后的配置里两条分组通配符都不复存在。 + +门禁的拒绝路径被直接验证过:删掉一条生成的别名会让 `verify-tsconfig-paths` 以非零码退出,恢复后检查通过。 + +## Alternatives considered + +**给通配符的候选 glob 重新排序,把最热的分组放前面。** 这不需要生成器也不需要新门禁,把 `util`、`core`、`llm`、`session` 挪到前面大约能拿回一半收益。否决理由:收益随着包的增加而衰减,这个顺序没有任何读者可核验的不变量,而且第一个分组之后的每一组仍然要付钱。它还保留了最糟的性质——新增一个包分组会悄悄拖慢所有人的启动。 + +**把 `paths` 挪进一个生成的 `tsconfig.paths.json`,由 base 配置 `extends`。** 这能把生成内容彻底移出手写文件,diff 也更干净。本次否决的理由是:有若干消费者**直接读** `tsconfig.base.json`,而不是通过会跟随 `extends` 的解析器——六个 Vitest 配置,外加 `project-reference-faces.ts`、`verify-export-jsdoc.ts`、`doc-typecheck.ts`、`rescope-vendor.ts`——逐个审计它们比这次别名改造本身还大。标记区域用零消费者风险达成了同样的隔离。 + +**在显式别名下方保留通配符作为兜底。** 显式别名本来就优先于通配符,因此正确性不变,而且新增包忘了重新生成也仍能解析。否决理由:兜底恰恰是让陈旧配置隐形的原因——仓库的立场是「misconfiguration fails loud」,而 `--check` 门禁把缺失的别名变成一次具名失败,而不是一次没人归因的慢启动。 + +## Consequences + +`headless` profile 的源码启动从 2,157 / 2,182 / 2,153 ms 的基线降到 1,069 / 1,052 / 1,055 ms——约 **1.1 秒,51%**,两个区间相距极远,且 `--help` 输出逐字节一致。 + +**收益仅限于 tsx 源码启动这一条路径。** Vitest 走 `vite-tsconfig-paths`,它在进程内做匹配与文件存在性检查,从不构造 Node 模块错误,因此从未付过那笔装饰代价:对某个包的整套用例做 A/B,实测 5,934 / 5,829 / 5,908 ms 对 5,878 / 5,851 / 5,905 ms,属于噪声。仓库的门禁脚本只 import 少数几个 `@deepseek-ai/dsh-*` 包,同样测不出可分离的差异。发布用户在裸 Node 下跑构建好的 `lib/`,本来就不受影响。 + +`paths` 从 188 个 key 增长到 519 个,新增包时必须运行生成器。`--check` 门禁把这件事变成一次具名失败而非静默失败,而生成区域让这类改动的 diff 只有一行。 diff --git a/package.json b/package.json index bec66ae4c9..552d9e9c5f 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,8 @@ "rescope-vendor": "tsx scripts/rescope-vendor.ts", "rescope-vendor:check": "tsx scripts/rescope-vendor.ts --check", "verify-client-domain-graph": "tsx scripts/verify-client-domain-graph.ts", + "gen-tsconfig-paths": "tsx scripts/gen-tsconfig-paths.ts", + "verify-tsconfig-paths": "tsx scripts/gen-tsconfig-paths.ts --check", "gen-cordis-catalog": "tsx scripts/gen-cordis-catalog.ts", "verify-cordis-catalog": "tsx scripts/gen-cordis-catalog.ts --check", "gen-cordis-api": "tsx scripts/gen-cordis-api.ts", diff --git a/scripts/gen-tsconfig-paths.spec.ts b/scripts/gen-tsconfig-paths.spec.ts new file mode 100644 index 0000000000..2455406a96 --- /dev/null +++ b/scripts/gen-tsconfig-paths.spec.ts @@ -0,0 +1,69 @@ +import { readFileSync } from 'node:fs' +import { resolve } from 'node:path' +import { describe, expect, it } from 'vitest' +import { collectPackageAliases, renderAliases, writeRegion } from './gen-tsconfig-paths.ts' + +const root = resolve(import.meta.dirname, '..') + +describe('generated tsconfig package aliases', () => { + it('maps each package to its own source directory', () => { + const aliases = collectPackageAliases() + expect(aliases.length).toBeGreaterThan(100) + const session = aliases.find(alias => alias.specifier === '@deepseek-ai/dsh-session') + expect(session).toEqual({ + specifier: '@deepseek-ai/dsh-session', + source: './packages/core/session/src', + hasInvariant: true, + }) + // Sorted, so a package added anywhere lands in a stable spot in the diff. + expect([...aliases].sort((a, b) => a.specifier.localeCompare(b.specifier))).toEqual(aliases) + // Only packages named after their directory: the rest carry hand-written + // aliases, because the removed wildcards could never have resolved them. + expect(aliases.some(alias => alias.specifier === '@deepseek-ai/dsh-typert-protocol')).toBe(false) + }) + + it('yields to a hand-written alias and closes without a trailing comma', () => { + const aliases = [ + { specifier: '@deepseek-ai/dsh-a', source: './packages/g/a/src', hasInvariant: true }, + { specifier: '@deepseek-ai/dsh-b', source: './packages/g/b/src', hasInvariant: false }, + ] + const body = renderAliases(aliases, new Set(['@deepseek-ai/dsh-a'])) + + // The hand-written bare alias is skipped; its /invariant sibling is not. + expect(body).toBe([ + ' "@deepseek-ai/dsh-a/invariant": ["./packages/g/a/src/invariant.ts"]', + ' "@deepseek-ai/dsh-b": ["./packages/g/b/src"]', + ].join(',\n')) + expect(body.endsWith(',')).toBe(false) + }) + + it('replaces only the marked region', () => { + const text = [ + '{ "before": 1,', + ' // BEGIN generated package aliases — pnpm run gen-tsconfig-paths', + ' "stale": ["gone"]', + ' // END generated package aliases', + ' "after": 2 }', + ].join('\n') + + const next = writeRegion(text, ' "fresh": ["kept"]') + + expect(next).toContain('{ "before": 1,') + expect(next).toContain(' "after": 2 }') + expect(next).toContain('"fresh": ["kept"]') + expect(next).not.toContain('stale') + }) + + it('refuses a config without the region markers', () => { + expect(() => writeRegion('{}', '')).toThrow('missing the generated-region markers') + }) + + it('leaves no wildcard that probes every package group', () => { + const config = readFileSync(resolve(root, 'tsconfig.base.json'), 'utf8') + // These two listed one candidate per group, so resolving a package late in + // the list cost a filesystem probe — and under tsx a decorated module + // error — for every group before it. + expect(config).not.toContain('"@deepseek-ai/dsh-*":') + expect(config).not.toContain('"@deepseek-ai/dsh-*/invariant":') + }) +}) diff --git a/scripts/gen-tsconfig-paths.ts b/scripts/gen-tsconfig-paths.ts new file mode 100644 index 0000000000..edb14f98d6 --- /dev/null +++ b/scripts/gen-tsconfig-paths.ts @@ -0,0 +1,171 @@ +/** + * Expand the workspace path aliases that a wildcard would otherwise resolve by + * probing every package group in turn. + * + * `tsconfig.base.json` is the resolution facade for the whole repository, and + * two of its aliases used one key per *group* rather than per package: + * `@deepseek-ai/dsh-*` listed 49 candidate globs and `@deepseek-ai/dsh-*\/invariant` + * listed 45. TypeScript and tsx try those candidates in order, so a specifier + * whose package sits late in the list pays for every earlier miss. Under tsx's + * ESM hook each miss is an `ERR_MODULE_NOT_FOUND` that Node decorates with a + * full CommonJS resolution walk, which dominated source-launch boot. + * + * This generator writes one explicit entry per package into a marked region of + * `tsconfig.base.json`, leaving every hand-written alias and comment outside + * that region untouched. `--check` reports drift instead of writing, so a new + * package that needs an alias fails a gate rather than silently resolving + * through a fallback that no longer exists. + * + * @module scripts/gen-tsconfig-paths + */ + +import { readFileSync, writeFileSync, existsSync, readdirSync, statSync } from 'node:fs' +import { join } from 'node:path' +import { fileURLToPath } from 'node:url' + +const ROOT = fileURLToPath(new URL('..', import.meta.url)) +const CONFIG = join(ROOT, 'tsconfig.base.json') +const BEGIN = ' // BEGIN generated package aliases — pnpm run gen-tsconfig-paths' +const END = ' // END generated package aliases' + +/** Package-name prefix the expanded aliases cover. */ +const PREFIX = '@deepseek-ai/dsh-' + +/** One workspace package the generated region maps. */ +interface PackageAlias { + /** Bare specifier, e.g. `@deepseek-ai/dsh-session`. */ + readonly specifier: string + /** Repository-relative source directory, e.g. `./packages/session/session/src`. */ + readonly source: string + /** Whether the package carries `src/invariant.ts`, which earns a second alias. */ + readonly hasInvariant: boolean +} + +/** + * Read a workspace manifest's declared name. + * @param manifest - absolute path to a `package.json`. + * @returns The declared name, or undefined when the file is absent or nameless. + */ +function packageName(manifest: string): string | undefined { + let parsed: unknown + try { + parsed = JSON.parse(readFileSync(manifest, 'utf8')) + } catch (_absentOrUnreadableManifest) { + return undefined + } + if (typeof parsed !== 'object' || parsed === null) return undefined + const name: unknown = (parsed as { name?: unknown }).name + return typeof name === 'string' ? name : undefined +} + +/** + * Collect every package the removed wildcards could resolve. + * + * A wildcard substituted the specifier's suffix into `packages///src`, + * so it only ever resolved a package whose declared name is exactly + * `@deepseek-ai/dsh-`. Packages named after something other than + * their directory already carry a hand-written alias and are skipped here. + * + * @returns Aliases sorted by specifier. + * @throws When two package directories claim one specifier, which the removed + * wildcards resolved by group order and an explicit map cannot express. + */ +export function collectPackageAliases(): PackageAlias[] { + const packages = join(ROOT, 'packages') + const bySpecifier = new Map() + for (const group of readdirSync(packages).sort()) { + const groupDir = join(packages, group) + if (!statSync(groupDir).isDirectory()) continue + for (const directory of readdirSync(groupDir).sort()) { + const packageDir = join(groupDir, directory) + const name = packageName(join(packageDir, 'package.json')) + if (name === undefined || name !== `${PREFIX}${directory}`) continue + if (!existsSync(join(packageDir, 'src'))) continue + const previous = bySpecifier.get(name) + if (previous !== undefined) { + throw new Error( + `gen-tsconfig-paths: ${name} is claimed by packages/${previous.directory} and packages/${group}/${directory}; ` + + 'an explicit alias cannot express the group-order tiebreak the wildcard used.', + ) + } + bySpecifier.set(name, { + specifier: name, + source: `./packages/${group}/${directory}/src`, + hasInvariant: existsSync(join(packageDir, 'src', 'invariant.ts')), + directory: `${group}/${directory}`, + }) + } + } + return [...bySpecifier.values()] + .map(({ specifier, source, hasInvariant }) => ({ specifier, source, hasInvariant })) + .sort((left, right) => left.specifier.localeCompare(right.specifier)) +} + +/** + * Render the generated region's alias lines. + * @param aliases - packages to map, in emission order. + * @param handWritten - specifiers already mapped outside the region; a duplicate key would shadow one silently. + * @returns The region body, one JSON member per line. + */ +export function renderAliases(aliases: readonly PackageAlias[], handWritten: ReadonlySet): string { + const lines: string[] = [] + for (const alias of aliases) { + if (!handWritten.has(alias.specifier)) { + lines.push(` ${JSON.stringify(alias.specifier)}: [${JSON.stringify(alias.source)}]`) + } + const invariant = `${alias.specifier}/invariant` + if (alias.hasInvariant && !handWritten.has(invariant)) { + lines.push(` ${JSON.stringify(invariant)}: [${JSON.stringify(`${alias.source}/invariant.ts`)}]`) + } + } + // The region closes `paths`, so the last member carries no trailing comma. + return lines.join(',\n') +} + +/** + * Replace the generated region of a config's text. + * @param text - current `tsconfig.base.json` contents. + * @param body - rendered alias lines. + * @returns The updated contents. + * @throws When the markers are missing or out of order. + */ +export function writeRegion(text: string, body: string): string { + const begin = text.indexOf(BEGIN) + const end = text.indexOf(END) + if (begin < 0 || end < begin) { + throw new Error(`gen-tsconfig-paths: ${CONFIG} is missing the generated-region markers.`) + } + return `${text.slice(0, begin)}${BEGIN}\n${body}\n${END}${text.slice(end + END.length)}` +} + +/** + * Parse the config's `paths` keys, ignoring the generated region. + * @param text - current `tsconfig.base.json` contents. + * @returns Specifiers mapped by hand. + */ +function handWrittenSpecifiers(text: string): Set { + const begin = text.indexOf(BEGIN) + const end = text.indexOf(END) + const outside = begin < 0 || end < begin ? text : text.slice(0, begin) + text.slice(end) + const keys = new Set() + for (const match of outside.matchAll(/^\s*"(@deepseek-ai\/[^"]+)":/gm)) { + const key = match[1] + if (key !== undefined) keys.add(key) + } + return keys +} + +if (import.meta.url === `file://${process.argv[1] ?? ''}`) { + const check = process.argv.includes('--check') + const current = readFileSync(CONFIG, 'utf8') + const next = writeRegion(current, renderAliases(collectPackageAliases(), handWrittenSpecifiers(current))) + if (current === next) { + console.log('gen-tsconfig-paths: tsconfig.base.json package aliases are current.') + } else if (check) { + console.error('gen-tsconfig-paths: tsconfig.base.json is stale; run `pnpm run gen-tsconfig-paths`.') + process.exitCode = 1 + } else { + writeFileSync(CONFIG, next) + console.log('gen-tsconfig-paths: rewrote tsconfig.base.json package aliases.') + } +} diff --git a/scripts/run-gates.ts b/scripts/run-gates.ts index c655876759..6b7b7a5ec3 100644 --- a/scripts/run-gates.ts +++ b/scripts/run-gates.ts @@ -720,6 +720,7 @@ function docSyncLeafGates(options: { pnpmScript('doc-refs', 'verify-doc-refs', { label: 'doc refs', quick: true }), pnpmScript('subsystem-pages', 'verify-subsystem-pages', { label: 'subsystem pages' }), pnpmScript('package-paths', 'verify-package-paths', { label: 'package paths' }), + pnpmScript('tsconfig-paths', 'verify-tsconfig-paths', { label: 'tsconfig paths' }), pnpmScript('config-source-ownership', 'verify-config-source-ownership', { label: 'config source ownership' }), pnpmScript('package-readme-model-experience', 'verify-package-readme-model-experience', { label: 'package README model experience', quick: true }), pnpmScript('agent-note-classification', 'verify-agent-note-classification', { label: 'agent note classification', quick: true }), diff --git a/tsconfig.base.json b/tsconfig.base.json index 83c2432053..00783e4835 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -126,53 +126,6 @@ "@deepseek-ai/dsh-experimental-webworker-runtime/invariant": ["./packages/experimental/webworker-runtime/src/invariant.ts"], "@deepseek-ai/dsh-experimental-webworker-packer/invariant": ["./packages/experimental/webworker-packer/src/invariant.ts"], "@deepseek-ai/dsh-util-crypto/invariant": ["./packages/util/crypto/src/invariant.ts"], - "@deepseek-ai/dsh-*/invariant": [ - "./packages/core/*/src/invariant.ts", - "./packages/prompt/*/src/invariant.ts", - "./packages/llm/*/src/invariant.ts", - "./packages/shell/*/src/invariant.ts", - "./packages/subprocess/*/src/invariant.ts", - "./packages/e2b/*/src/invariant.ts", - "./packages/code-runtime/*/src/invariant.ts", - "./packages/fs/*/src/invariant.ts", - "./packages/skill/*/src/invariant.ts", - "./packages/compaction/*/src/invariant.ts", - "./packages/context/*/src/invariant.ts", - "./packages/goal/*/src/invariant.ts", - "./packages/feedback/*/src/invariant.ts", - "./packages/schedule/*/src/invariant.ts", - "./packages/guard/*/src/invariant.ts", - "./packages/plan/*/src/invariant.ts", - "./packages/preset/*/src/invariant.ts", - "./packages/subagent/*/src/invariant.ts", - "./packages/jobs/*/src/invariant.ts", - "./packages/experimental/*/src/invariant.ts", - "./packages/workflow/*/src/invariant.ts", - "./packages/webhook/*/src/invariant.ts", - "./packages/web/*/src/invariant.ts", - "./packages/attachment/*/src/invariant.ts", - "./packages/spill/*/src/invariant.ts", - "./packages/todo/*/src/invariant.ts", - "./packages/bundle/*/src/invariant.ts", - "./packages/extensions/*/src/invariant.ts", - "./packages/sandbox/*/src/invariant.ts", - "./packages/hooks/*/src/invariant.ts", - "./packages/session/*/src/invariant.ts", - "./packages/session-query/*/src/invariant.ts", - "./packages/settings/*/src/invariant.ts", - "./packages/credentials/*/src/invariant.ts", - "./packages/acp/*/src/invariant.ts", - "./packages/storage/*/src/invariant.ts", - "./packages/workspace/*/src/invariant.ts", - "./packages/sdk/*/src/invariant.ts", - "./packages/interaction/*/src/invariant.ts", - "./packages/boot/*/src/invariant.ts", - "./packages/examples/*/src/invariant.ts", - "./packages/util/*/src/invariant.ts", - "./packages/mcp/*/src/invariant.ts", - "./packages/identity/*/src/invariant.ts", - "./packages/test-support/*/src/invariant.ts" - ], // host/client package names prefix the group dir (dsh-client-), so // the generic dsh-*/invariant list above cannot map them; strip the // group prefix with a dedicated wildcard per group instead. @@ -181,12 +134,6 @@ "@deepseek-ai/dsh-headless/startup": ["./packages/bundle/headless/src/startup.ts"], "@deepseek-ai/dsh-web-app/startup": ["./packages/bundle/web-app/src/startup.ts"], "@deepseek-ai/dsh-client-*/client": ["./packages/client/*/src/client"], - // One wildcard maps every @deepseek-ai/dsh- to its source. Package - // dir names are unique across groups, so first-on-disk-wins resolution is - // unambiguous; adding a package under an existing group needs no edit - // here. The aggregates' project references (tsconfig.host.json / - // tsconfig.client.json) stay explicit — TS project references have no - // wildcard form. "@deepseek-ai/dsh-host-apiproxy": ["./packages/host/apiproxy/src"], "@deepseek-ai/dsh-host-directory-picker": ["./packages/host/directory-picker/src"], "@deepseek-ai/dsh-host-directory-picker/*": ["./packages/host/directory-picker/src/*"], @@ -272,57 +219,341 @@ "@deepseek-ai/dsh-experimental-webworker-runtime": ["./packages/experimental/webworker-runtime/src"], "@deepseek-ai/dsh-experimental-webworker-packer": ["./packages/experimental/webworker-packer/src"], "@deepseek-ai/dsh-util-crypto": ["./packages/util/crypto/src"], - "@deepseek-ai/dsh-*": [ - "./packages/core/*/src", - "./packages/prompt/*/src", - "./packages/llm/*/src", - "./packages/shell/*/src", - "./packages/terminal/*/src", - "./packages/subprocess/*/src", - "./packages/e2b/*/src", - "./packages/code-runtime/*/src", - "./packages/fs/*/src", - "./packages/lsp/*/src", - "./packages/skill/*/src", - "./packages/compaction/*/src", - "./packages/context/*/src", - "./packages/goal/*/src", - "./packages/feedback/*/src", - "./packages/schedule/*/src", - "./packages/guard/*/src", - "./packages/plan/*/src", - "./packages/preset/*/src", - "./packages/subagent/*/src", - "./packages/jobs/*/src", - "./packages/experimental/*/src", - "./packages/workflow/*/src", - "./packages/webhook/*/src", - "./packages/web/*/src", - "./packages/attachment/*/src", - "./packages/spill/*/src", - "./packages/todo/*/src", - "./packages/bundle/*/src", - "./packages/extensions/*/src", - "./packages/sandbox/*/src", - "./packages/hooks/*/src", - "./packages/session/*/src", - "./packages/session-query/*/src", - "./packages/settings/*/src", - "./packages/credentials/*/src", - "./packages/acp/*/src", - "./packages/storage/*/src", - "./packages/workspace/*/src", - "./packages/sdk/*/src", - "./packages/interaction/*/src", - "./packages/boot/*/src", - "./packages/examples/*/src", - "./packages/util/*/src", - "./packages/mcp/*/src", - "./packages/identity/*/src", - "./packages/test-support/*/src", - "./packages/host/*/src", - "./packages/client/*/src" - ] + // BEGIN generated package aliases — pnpm run gen-tsconfig-paths + "@deepseek-ai/dsh-acp": ["./packages/acp/acp/src"], + "@deepseek-ai/dsh-acp/invariant": ["./packages/acp/acp/src/invariant.ts"], + "@deepseek-ai/dsh-acp-app": ["./packages/bundle/acp-app/src"], + "@deepseek-ai/dsh-acp-app/invariant": ["./packages/bundle/acp-app/src/invariant.ts"], + "@deepseek-ai/dsh-agent": ["./packages/core/agent/src"], + "@deepseek-ai/dsh-agent-default-model": ["./packages/core/agent-default-model/src"], + "@deepseek-ai/dsh-agent-default-model/invariant": ["./packages/core/agent-default-model/src/invariant.ts"], + "@deepseek-ai/dsh-agent-instructions": ["./packages/context/agent-instructions/src"], + "@deepseek-ai/dsh-agent-instructions/invariant": ["./packages/context/agent-instructions/src/invariant.ts"], + "@deepseek-ai/dsh-agent-loop": ["./packages/core/agent-loop/src"], + "@deepseek-ai/dsh-agent-loop-testkit": ["./packages/test-support/agent-loop-testkit/src"], + "@deepseek-ai/dsh-agent-loop-testkit/invariant": ["./packages/test-support/agent-loop-testkit/src/invariant.ts"], + "@deepseek-ai/dsh-agent-presets": ["./packages/preset/agent-presets/src"], + "@deepseek-ai/dsh-agent-presets/invariant": ["./packages/preset/agent-presets/src/invariant.ts"], + "@deepseek-ai/dsh-agent-spine-demo": ["./packages/examples/agent-spine-demo/src"], + "@deepseek-ai/dsh-agent-spine-demo/invariant": ["./packages/examples/agent-spine-demo/src/invariant.ts"], + "@deepseek-ai/dsh-agent-tool-presentation": ["./packages/core/agent-tool-presentation/src"], + "@deepseek-ai/dsh-agent-tool-presentation/invariant": ["./packages/core/agent-tool-presentation/src/invariant.ts"], + "@deepseek-ai/dsh-anonymous-user-id": ["./packages/identity/anonymous-user-id/src"], + "@deepseek-ai/dsh-anonymous-user-id/invariant": ["./packages/identity/anonymous-user-id/src/invariant.ts"], + "@deepseek-ai/dsh-app-boot": ["./packages/boot/app-boot/src"], + "@deepseek-ai/dsh-app-boot/invariant": ["./packages/boot/app-boot/src/invariant.ts"], + "@deepseek-ai/dsh-atomic-write": ["./packages/util/atomic-write/src"], + "@deepseek-ai/dsh-atomic-write/invariant": ["./packages/util/atomic-write/src/invariant.ts"], + "@deepseek-ai/dsh-attachment": ["./packages/attachment/attachment/src"], + "@deepseek-ai/dsh-attachment/invariant": ["./packages/attachment/attachment/src/invariant.ts"], + "@deepseek-ai/dsh-attachment-local": ["./packages/attachment/attachment-local/src"], + "@deepseek-ai/dsh-attachment-local/invariant": ["./packages/attachment/attachment-local/src/invariant.ts"], + "@deepseek-ai/dsh-authorization": ["./packages/credentials/authorization/src"], + "@deepseek-ai/dsh-authorization/invariant": ["./packages/credentials/authorization/src/invariant.ts"], + "@deepseek-ai/dsh-base": ["./packages/bundle/base/src"], + "@deepseek-ai/dsh-base/invariant": ["./packages/bundle/base/src/invariant.ts"], + "@deepseek-ai/dsh-bash-local": ["./packages/shell/bash-local/src"], + "@deepseek-ai/dsh-bash-local/invariant": ["./packages/shell/bash-local/src/invariant.ts"], + "@deepseek-ai/dsh-bash-sandbox": ["./packages/shell/bash-sandbox/src"], + "@deepseek-ai/dsh-bash-sandbox/invariant": ["./packages/shell/bash-sandbox/src/invariant.ts"], + "@deepseek-ai/dsh-brand": ["./packages/util/brand/src"], + "@deepseek-ai/dsh-brand/invariant": ["./packages/util/brand/src/invariant.ts"], + "@deepseek-ai/dsh-cmdline": ["./packages/boot/cmdline/src"], + "@deepseek-ai/dsh-cmdline/invariant": ["./packages/boot/cmdline/src/invariant.ts"], + "@deepseek-ai/dsh-code-runtime": ["./packages/code-runtime/code-runtime/src"], + "@deepseek-ai/dsh-code-runtime/invariant": ["./packages/code-runtime/code-runtime/src/invariant.ts"], + "@deepseek-ai/dsh-code-runtime-python": ["./packages/code-runtime/code-runtime-python/src"], + "@deepseek-ai/dsh-code-runtime-python/invariant": ["./packages/code-runtime/code-runtime-python/src/invariant.ts"], + "@deepseek-ai/dsh-code-runtime-worker-thread": ["./packages/code-runtime/code-runtime-worker-thread/src"], + "@deepseek-ai/dsh-code-runtime-worker-thread/invariant": ["./packages/code-runtime/code-runtime-worker-thread/src/invariant.ts"], + "@deepseek-ai/dsh-command-compact": ["./packages/compaction/command-compact/src"], + "@deepseek-ai/dsh-command-compact/invariant": ["./packages/compaction/command-compact/src/invariant.ts"], + "@deepseek-ai/dsh-command-feedback": ["./packages/feedback/command-feedback/src"], + "@deepseek-ai/dsh-command-feedback/invariant": ["./packages/feedback/command-feedback/src/invariant.ts"], + "@deepseek-ai/dsh-command-goal": ["./packages/goal/command-goal/src"], + "@deepseek-ai/dsh-command-goal/invariant": ["./packages/goal/command-goal/src/invariant.ts"], + "@deepseek-ai/dsh-commands": ["./packages/interaction/commands/src"], + "@deepseek-ai/dsh-commands/invariant": ["./packages/interaction/commands/src/invariant.ts"], + "@deepseek-ai/dsh-compaction": ["./packages/compaction/compaction/src"], + "@deepseek-ai/dsh-compaction/invariant": ["./packages/compaction/compaction/src/invariant.ts"], + "@deepseek-ai/dsh-compaction-basic": ["./packages/compaction/compaction-basic/src"], + "@deepseek-ai/dsh-compaction-basic/invariant": ["./packages/compaction/compaction-basic/src/invariant.ts"], + "@deepseek-ai/dsh-compaction-tool-result-pruner": ["./packages/compaction/compaction-tool-result-pruner/src"], + "@deepseek-ai/dsh-compaction-tool-result-pruner/invariant": ["./packages/compaction/compaction-tool-result-pruner/src/invariant.ts"], + "@deepseek-ai/dsh-cordis-host-runner/invariant": ["./packages/extensions/cordis-host-runner/src/invariant.ts"], + "@deepseek-ai/dsh-credentials": ["./packages/credentials/credentials/src"], + "@deepseek-ai/dsh-credentials/invariant": ["./packages/credentials/credentials/src/invariant.ts"], + "@deepseek-ai/dsh-credentials-local": ["./packages/credentials/credentials-local/src"], + "@deepseek-ai/dsh-credentials-local/invariant": ["./packages/credentials/credentials-local/src/invariant.ts"], + "@deepseek-ai/dsh-deepseek-llm-api-extensions": ["./packages/llm/deepseek-llm-api-extensions/src"], + "@deepseek-ai/dsh-deepseek-llm-api-extensions/invariant": ["./packages/llm/deepseek-llm-api-extensions/src/invariant.ts"], + "@deepseek-ai/dsh-e2b": ["./packages/e2b/e2b/src"], + "@deepseek-ai/dsh-e2b/invariant": ["./packages/e2b/e2b/src/invariant.ts"], + "@deepseek-ai/dsh-file-reference": ["./packages/context/file-reference/src"], + "@deepseek-ai/dsh-file-reference/invariant": ["./packages/context/file-reference/src/invariant.ts"], + "@deepseek-ai/dsh-file-reference-local": ["./packages/context/file-reference-local/src"], + "@deepseek-ai/dsh-file-reference-local/invariant": ["./packages/context/file-reference-local/src/invariant.ts"], + "@deepseek-ai/dsh-fs": ["./packages/fs/fs/src"], + "@deepseek-ai/dsh-fs/invariant": ["./packages/fs/fs/src/invariant.ts"], + "@deepseek-ai/dsh-fs-e2b": ["./packages/e2b/fs-e2b/src"], + "@deepseek-ai/dsh-fs-e2b/invariant": ["./packages/e2b/fs-e2b/src/invariant.ts"], + "@deepseek-ai/dsh-fs-local": ["./packages/fs/fs-local/src"], + "@deepseek-ai/dsh-fs-local/invariant": ["./packages/fs/fs-local/src/invariant.ts"], + "@deepseek-ai/dsh-fs-observation-policy": ["./packages/fs/fs-observation-policy/src"], + "@deepseek-ai/dsh-fs-observation-policy/invariant": ["./packages/fs/fs-observation-policy/src/invariant.ts"], + "@deepseek-ai/dsh-fs-sandbox": ["./packages/fs/fs-sandbox/src"], + "@deepseek-ai/dsh-fs-sandbox/invariant": ["./packages/fs/fs-sandbox/src/invariant.ts"], + "@deepseek-ai/dsh-goal": ["./packages/goal/goal/src"], + "@deepseek-ai/dsh-goal/invariant": ["./packages/goal/goal/src/invariant.ts"], + "@deepseek-ai/dsh-goal-round-driver": ["./packages/goal/goal-round-driver/src"], + "@deepseek-ai/dsh-goal-round-driver/invariant": ["./packages/goal/goal-round-driver/src/invariant.ts"], + "@deepseek-ai/dsh-headless": ["./packages/bundle/headless/src"], + "@deepseek-ai/dsh-headless/invariant": ["./packages/bundle/headless/src/invariant.ts"], + "@deepseek-ai/dsh-home-paths": ["./packages/util/home-paths/src"], + "@deepseek-ai/dsh-home-paths/invariant": ["./packages/util/home-paths/src/invariant.ts"], + "@deepseek-ai/dsh-hook-protocol": ["./packages/hooks/hook-protocol/src"], + "@deepseek-ai/dsh-hook-protocol/invariant": ["./packages/hooks/hook-protocol/src/invariant.ts"], + "@deepseek-ai/dsh-hooks-claude-code": ["./packages/hooks/hooks-claude-code/src"], + "@deepseek-ai/dsh-hooks-claude-code/invariant": ["./packages/hooks/hooks-claude-code/src/invariant.ts"], + "@deepseek-ai/dsh-hooks-codex": ["./packages/hooks/hooks-codex/src"], + "@deepseek-ai/dsh-hooks-codex/invariant": ["./packages/hooks/hooks-codex/src/invariant.ts"], + "@deepseek-ai/dsh-invariants/invariant": ["./packages/runtime-diagnostics/invariants/src/invariant.ts"], + "@deepseek-ai/dsh-jobs": ["./packages/jobs/jobs/src"], + "@deepseek-ai/dsh-jobs/invariant": ["./packages/jobs/jobs/src/invariant.ts"], + "@deepseek-ai/dsh-jobs-local": ["./packages/jobs/jobs-local/src"], + "@deepseek-ai/dsh-jobs-local/invariant": ["./packages/jobs/jobs-local/src/invariant.ts"], + "@deepseek-ai/dsh-launch-environment": ["./packages/util/launch-environment/src"], + "@deepseek-ai/dsh-launch-environment/invariant": ["./packages/util/launch-environment/src/invariant.ts"], + "@deepseek-ai/dsh-llm": ["./packages/llm/llm/src"], + "@deepseek-ai/dsh-llm/invariant": ["./packages/llm/llm/src/invariant.ts"], + "@deepseek-ai/dsh-llm-deepseek": ["./packages/llm/llm-deepseek/src"], + "@deepseek-ai/dsh-llm-deepseek/invariant": ["./packages/llm/llm-deepseek/src/invariant.ts"], + "@deepseek-ai/dsh-llm-mock-server": ["./packages/test-support/llm-mock-server/src"], + "@deepseek-ai/dsh-llm-mock-server/invariant": ["./packages/test-support/llm-mock-server/src/invariant.ts"], + "@deepseek-ai/dsh-llm-pi-ai": ["./packages/llm/llm-pi-ai/src"], + "@deepseek-ai/dsh-llm-pi-ai/invariant": ["./packages/llm/llm-pi-ai/src/invariant.ts"], + "@deepseek-ai/dsh-llm-replay": ["./packages/test-support/llm-replay/src"], + "@deepseek-ai/dsh-llm-replay/invariant": ["./packages/test-support/llm-replay/src/invariant.ts"], + "@deepseek-ai/dsh-llm-retry": ["./packages/llm/llm-retry/src"], + "@deepseek-ai/dsh-llm-retry/invariant": ["./packages/llm/llm-retry/src/invariant.ts"], + "@deepseek-ai/dsh-loader-smoke": ["./packages/test-support/loader-smoke/src"], + "@deepseek-ai/dsh-loader-smoke/invariant": ["./packages/test-support/loader-smoke/src/invariant.ts"], + "@deepseek-ai/dsh-lsp": ["./packages/lsp/lsp/src"], + "@deepseek-ai/dsh-lsp/invariant": ["./packages/lsp/lsp/src/invariant.ts"], + "@deepseek-ai/dsh-lsp-stdio": ["./packages/lsp/lsp-stdio/src"], + "@deepseek-ai/dsh-lsp-stdio/invariant": ["./packages/lsp/lsp-stdio/src/invariant.ts"], + "@deepseek-ai/dsh-mcp-client": ["./packages/mcp/mcp-client/src"], + "@deepseek-ai/dsh-mcp-client/invariant": ["./packages/mcp/mcp-client/src/invariant.ts"], + "@deepseek-ai/dsh-message-feedback": ["./packages/feedback/message-feedback/src"], + "@deepseek-ai/dsh-message-feedback/invariant": ["./packages/feedback/message-feedback/src/invariant.ts"], + "@deepseek-ai/dsh-native-command": ["./packages/util/native-command/src"], + "@deepseek-ai/dsh-native-command/invariant": ["./packages/util/native-command/src/invariant.ts"], + "@deepseek-ai/dsh-output-retention": ["./packages/util/output-retention/src"], + "@deepseek-ai/dsh-output-retention/invariant": ["./packages/util/output-retention/src/invariant.ts"], + "@deepseek-ai/dsh-permission-presets": ["./packages/interaction/permission-presets/src"], + "@deepseek-ai/dsh-permission-presets/invariant": ["./packages/interaction/permission-presets/src/invariant.ts"], + "@deepseek-ai/dsh-persona": ["./packages/preset/persona/src"], + "@deepseek-ai/dsh-persona/invariant": ["./packages/preset/persona/src/invariant.ts"], + "@deepseek-ai/dsh-plan-mode": ["./packages/plan/plan-mode/src"], + "@deepseek-ai/dsh-plan-mode/invariant": ["./packages/plan/plan-mode/src/invariant.ts"], + "@deepseek-ai/dsh-plugin-package-inventory-deepseek": ["./packages/llm/plugin-package-inventory-deepseek/src"], + "@deepseek-ai/dsh-plugin-package-inventory-deepseek/invariant": ["./packages/llm/plugin-package-inventory-deepseek/src/invariant.ts"], + "@deepseek-ai/dsh-pwsh-local/invariant": ["./packages/shell/pwsh-local/src/invariant.ts"], + "@deepseek-ai/dsh-pwsh-sandbox": ["./packages/shell/pwsh-sandbox/src"], + "@deepseek-ai/dsh-pwsh-sandbox/invariant": ["./packages/shell/pwsh-sandbox/src/invariant.ts"], + "@deepseek-ai/dsh-repeat-tool-reminder": ["./packages/guard/repeat-tool-reminder/src"], + "@deepseek-ai/dsh-repeat-tool-reminder/invariant": ["./packages/guard/repeat-tool-reminder/src/invariant.ts"], + "@deepseek-ai/dsh-sandbox": ["./packages/sandbox/sandbox/src"], + "@deepseek-ai/dsh-sandbox/invariant": ["./packages/sandbox/sandbox/src/invariant.ts"], + "@deepseek-ai/dsh-sandbox-local": ["./packages/sandbox/sandbox-local/src"], + "@deepseek-ai/dsh-sandbox-local/invariant": ["./packages/sandbox/sandbox-local/src/invariant.ts"], + "@deepseek-ai/dsh-sandbox-policy": ["./packages/sandbox/sandbox-policy/src"], + "@deepseek-ai/dsh-sandbox-policy/invariant": ["./packages/sandbox/sandbox-policy/src/invariant.ts"], + "@deepseek-ai/dsh-sandbox-windows-acl": ["./packages/sandbox/sandbox-windows-acl/src"], + "@deepseek-ai/dsh-sandbox-windows-acl/invariant": ["./packages/sandbox/sandbox-windows-acl/src/invariant.ts"], + "@deepseek-ai/dsh-schedule": ["./packages/schedule/schedule/src"], + "@deepseek-ai/dsh-schedule/invariant": ["./packages/schedule/schedule/src/invariant.ts"], + "@deepseek-ai/dsh-scope": ["./packages/core/scope/src"], + "@deepseek-ai/dsh-sdk-app": ["./packages/bundle/sdk-app/src"], + "@deepseek-ai/dsh-sdk-app/invariant": ["./packages/bundle/sdk-app/src/invariant.ts"], + "@deepseek-ai/dsh-sdk-minimal": ["./packages/bundle/sdk-minimal/src"], + "@deepseek-ai/dsh-sdk-minimal/invariant": ["./packages/bundle/sdk-minimal/src/invariant.ts"], + "@deepseek-ai/dsh-session": ["./packages/core/session/src"], + "@deepseek-ai/dsh-session-checkpoint-policy": ["./packages/session/session-checkpoint-policy/src"], + "@deepseek-ai/dsh-session-checkpoint-policy/invariant": ["./packages/session/session-checkpoint-policy/src/invariant.ts"], + "@deepseek-ai/dsh-session-log-deepseek": ["./packages/session/session-log-deepseek/src"], + "@deepseek-ai/dsh-session-log-deepseek/invariant": ["./packages/session/session-log-deepseek/src/invariant.ts"], + "@deepseek-ai/dsh-session-log-export": ["./packages/session-query/session-log-export/src"], + "@deepseek-ai/dsh-session-log-export/invariant": ["./packages/session-query/session-log-export/src/invariant.ts"], + "@deepseek-ai/dsh-session-persistence": ["./packages/session/session-persistence/src"], + "@deepseek-ai/dsh-session-persistence/invariant": ["./packages/session/session-persistence/src/invariant.ts"], + "@deepseek-ai/dsh-session-persistence-jsonl": ["./packages/session/session-persistence-jsonl/src"], + "@deepseek-ai/dsh-session-persistence-jsonl/invariant": ["./packages/session/session-persistence-jsonl/src/invariant.ts"], + "@deepseek-ai/dsh-session-persistence-sqlite": ["./packages/session/session-persistence-sqlite/src"], + "@deepseek-ai/dsh-session-persistence-sqlite/invariant": ["./packages/session/session-persistence-sqlite/src/invariant.ts"], + "@deepseek-ai/dsh-session-projection": ["./packages/session/session-projection/src"], + "@deepseek-ai/dsh-session-projection/invariant": ["./packages/session/session-projection/src/invariant.ts"], + "@deepseek-ai/dsh-session-projection-cache": ["./packages/session/session-projection-cache/src"], + "@deepseek-ai/dsh-session-projection-cache/invariant": ["./packages/session/session-projection-cache/src/invariant.ts"], + "@deepseek-ai/dsh-session-query": ["./packages/session-query/session-query/src"], + "@deepseek-ai/dsh-session-query/invariant": ["./packages/session-query/session-query/src/invariant.ts"], + "@deepseek-ai/dsh-session-query-sqlite": ["./packages/session-query/session-query-sqlite/src"], + "@deepseek-ai/dsh-session-query-sqlite/invariant": ["./packages/session-query/session-query-sqlite/src/invariant.ts"], + "@deepseek-ai/dsh-session-reference": ["./packages/context/session-reference/src"], + "@deepseek-ai/dsh-session-reference/invariant": ["./packages/context/session-reference/src/invariant.ts"], + "@deepseek-ai/dsh-session-snapshot": ["./packages/test-support/session-snapshot/src"], + "@deepseek-ai/dsh-session-snapshot/invariant": ["./packages/test-support/session-snapshot/src/invariant.ts"], + "@deepseek-ai/dsh-session-stats": ["./packages/session/session-stats/src"], + "@deepseek-ai/dsh-session-stats/invariant": ["./packages/session/session-stats/src/invariant.ts"], + "@deepseek-ai/dsh-session-telemetry": ["./packages/session/session-telemetry/src"], + "@deepseek-ai/dsh-session-telemetry/invariant": ["./packages/session/session-telemetry/src/invariant.ts"], + "@deepseek-ai/dsh-session-telemetry-otel": ["./packages/session/session-telemetry-otel/src"], + "@deepseek-ai/dsh-session-telemetry-otel/invariant": ["./packages/session/session-telemetry-otel/src/invariant.ts"], + "@deepseek-ai/dsh-session-title": ["./packages/session/session-title/src"], + "@deepseek-ai/dsh-session-title/invariant": ["./packages/session/session-title/src/invariant.ts"], + "@deepseek-ai/dsh-session-title-all-prompts-llm": ["./packages/session/session-title-all-prompts-llm/src"], + "@deepseek-ai/dsh-session-title-all-prompts-llm/invariant": ["./packages/session/session-title-all-prompts-llm/src/invariant.ts"], + "@deepseek-ai/dsh-session-title-first-prompt-llm": ["./packages/session/session-title-first-prompt-llm/src"], + "@deepseek-ai/dsh-session-title-first-prompt-llm/invariant": ["./packages/session/session-title-first-prompt-llm/src/invariant.ts"], + "@deepseek-ai/dsh-session-title-llm": ["./packages/session/session-title-llm/src"], + "@deepseek-ai/dsh-session-title-llm/invariant": ["./packages/session/session-title-llm/src/invariant.ts"], + "@deepseek-ai/dsh-settings": ["./packages/settings/settings/src"], + "@deepseek-ai/dsh-settings/invariant": ["./packages/settings/settings/src/invariant.ts"], + "@deepseek-ai/dsh-settings-file": ["./packages/settings/settings-file/src"], + "@deepseek-ai/dsh-settings-file/invariant": ["./packages/settings/settings-file/src/invariant.ts"], + "@deepseek-ai/dsh-shell": ["./packages/shell/shell/src"], + "@deepseek-ai/dsh-shell/invariant": ["./packages/shell/shell/src/invariant.ts"], + "@deepseek-ai/dsh-shell-env/invariant": ["./packages/shell/shell-env/src/invariant.ts"], + "@deepseek-ai/dsh-skill": ["./packages/skill/skill/src"], + "@deepseek-ai/dsh-skill/invariant": ["./packages/skill/skill/src/invariant.ts"], + "@deepseek-ai/dsh-skill-badge": ["./packages/skill/skill-badge/src"], + "@deepseek-ai/dsh-skill-badge/invariant": ["./packages/skill/skill-badge/src/invariant.ts"], + "@deepseek-ai/dsh-skill-filesystem": ["./packages/skill/skill-filesystem/src"], + "@deepseek-ai/dsh-skill-filesystem/invariant": ["./packages/skill/skill-filesystem/src/invariant.ts"], + "@deepseek-ai/dsh-spill": ["./packages/spill/spill/src"], + "@deepseek-ai/dsh-spill/invariant": ["./packages/spill/spill/src/invariant.ts"], + "@deepseek-ai/dsh-spill-local": ["./packages/spill/spill-local/src"], + "@deepseek-ai/dsh-spill-local/invariant": ["./packages/spill/spill-local/src/invariant.ts"], + "@deepseek-ai/dsh-spill-policy": ["./packages/spill/spill-policy/src"], + "@deepseek-ai/dsh-spill-policy/invariant": ["./packages/spill/spill-policy/src/invariant.ts"], + "@deepseek-ai/dsh-storage": ["./packages/storage/storage/src"], + "@deepseek-ai/dsh-storage/invariant": ["./packages/storage/storage/src/invariant.ts"], + "@deepseek-ai/dsh-storage-domain": ["./packages/storage/storage-domain/src"], + "@deepseek-ai/dsh-storage-domain/invariant": ["./packages/storage/storage-domain/src/invariant.ts"], + "@deepseek-ai/dsh-storage-json": ["./packages/storage/storage-json/src"], + "@deepseek-ai/dsh-storage-json/invariant": ["./packages/storage/storage-json/src/invariant.ts"], + "@deepseek-ai/dsh-storage-sqlite": ["./packages/storage/storage-sqlite/src"], + "@deepseek-ai/dsh-storage-sqlite/invariant": ["./packages/storage/storage-sqlite/src/invariant.ts"], + "@deepseek-ai/dsh-subagent": ["./packages/subagent/subagent/src"], + "@deepseek-ai/dsh-subagent/invariant": ["./packages/subagent/subagent/src/invariant.ts"], + "@deepseek-ai/dsh-subagent-acp": ["./packages/subagent/subagent-acp/src"], + "@deepseek-ai/dsh-subagent-acp/invariant": ["./packages/subagent/subagent-acp/src/invariant.ts"], + "@deepseek-ai/dsh-subagent-claude-code": ["./packages/subagent/subagent-claude-code/src"], + "@deepseek-ai/dsh-subagent-claude-code/invariant": ["./packages/subagent/subagent-claude-code/src/invariant.ts"], + "@deepseek-ai/dsh-subagent-codex": ["./packages/subagent/subagent-codex/src"], + "@deepseek-ai/dsh-subagent-codex/invariant": ["./packages/subagent/subagent-codex/src/invariant.ts"], + "@deepseek-ai/dsh-subagent-dsh-sdk": ["./packages/subagent/subagent-dsh-sdk/src"], + "@deepseek-ai/dsh-subagent-dsh-sdk/invariant": ["./packages/subagent/subagent-dsh-sdk/src/invariant.ts"], + "@deepseek-ai/dsh-subagent-fork-in-process": ["./packages/subagent/subagent-fork-in-process/src"], + "@deepseek-ai/dsh-subagent-fork-in-process/invariant": ["./packages/subagent/subagent-fork-in-process/src/invariant.ts"], + "@deepseek-ai/dsh-subagent-in-process-driver": ["./packages/subagent/subagent-in-process-driver/src"], + "@deepseek-ai/dsh-subagent-in-process-driver/invariant": ["./packages/subagent/subagent-in-process-driver/src/invariant.ts"], + "@deepseek-ai/dsh-subagent-spawn-in-process": ["./packages/subagent/subagent-spawn-in-process/src"], + "@deepseek-ai/dsh-subagent-spawn-in-process/invariant": ["./packages/subagent/subagent-spawn-in-process/src/invariant.ts"], + "@deepseek-ai/dsh-subprocess": ["./packages/subprocess/subprocess/src"], + "@deepseek-ai/dsh-subprocess/invariant": ["./packages/subprocess/subprocess/src/invariant.ts"], + "@deepseek-ai/dsh-subprocess-e2b": ["./packages/e2b/subprocess-e2b/src"], + "@deepseek-ai/dsh-subprocess-e2b/invariant": ["./packages/e2b/subprocess-e2b/src/invariant.ts"], + "@deepseek-ai/dsh-subprocess-local": ["./packages/subprocess/subprocess-local/src"], + "@deepseek-ai/dsh-subprocess-local/invariant": ["./packages/subprocess/subprocess-local/src/invariant.ts"], + "@deepseek-ai/dsh-system-prompt": ["./packages/core/system-prompt/src"], + "@deepseek-ai/dsh-system-prompt/invariant": ["./packages/core/system-prompt/src/invariant.ts"], + "@deepseek-ai/dsh-terminal": ["./packages/terminal/terminal/src"], + "@deepseek-ai/dsh-terminal/invariant": ["./packages/terminal/terminal/src/invariant.ts"], + "@deepseek-ai/dsh-terminal-bash": ["./packages/terminal/terminal-bash/src"], + "@deepseek-ai/dsh-terminal-bash/invariant": ["./packages/terminal/terminal-bash/src/invariant.ts"], + "@deepseek-ai/dsh-time-context": ["./packages/context/time-context/src"], + "@deepseek-ai/dsh-time-context/invariant": ["./packages/context/time-context/src/invariant.ts"], + "@deepseek-ai/dsh-timeout": ["./packages/util/timeout/src"], + "@deepseek-ai/dsh-timeout/invariant": ["./packages/util/timeout/src/invariant.ts"], + "@deepseek-ai/dsh-tmux-context": ["./packages/context/tmux-context/src"], + "@deepseek-ai/dsh-tmux-context/invariant": ["./packages/context/tmux-context/src/invariant.ts"], + "@deepseek-ai/dsh-token-meter": ["./packages/llm/token-meter/src"], + "@deepseek-ai/dsh-token-meter/invariant": ["./packages/llm/token-meter/src/invariant.ts"], + "@deepseek-ai/dsh-tool-ask-user": ["./packages/interaction/tool-ask-user/src"], + "@deepseek-ai/dsh-tool-ask-user/invariant": ["./packages/interaction/tool-ask-user/src/invariant.ts"], + "@deepseek-ai/dsh-tool-bash": ["./packages/shell/tool-bash/src"], + "@deepseek-ai/dsh-tool-bash/invariant": ["./packages/shell/tool-bash/src/invariant.ts"], + "@deepseek-ai/dsh-tool-bash-persistent": ["./packages/shell/tool-bash-persistent/src"], + "@deepseek-ai/dsh-tool-bash-persistent/invariant": ["./packages/shell/tool-bash-persistent/src/invariant.ts"], + "@deepseek-ai/dsh-tool-cordis": ["./packages/extensions/tool-cordis/src"], + "@deepseek-ai/dsh-tool-cordis/invariant": ["./packages/extensions/tool-cordis/src/invariant.ts"], + "@deepseek-ai/dsh-tool-fs": ["./packages/fs/tool-fs/src"], + "@deepseek-ai/dsh-tool-fs/invariant": ["./packages/fs/tool-fs/src/invariant.ts"], + "@deepseek-ai/dsh-tool-fs-search": ["./packages/fs/tool-fs-search/src"], + "@deepseek-ai/dsh-tool-fs-search/invariant": ["./packages/fs/tool-fs-search/src/invariant.ts"], + "@deepseek-ai/dsh-tool-goal": ["./packages/goal/tool-goal/src"], + "@deepseek-ai/dsh-tool-goal/invariant": ["./packages/goal/tool-goal/src/invariant.ts"], + "@deepseek-ai/dsh-tool-jobs": ["./packages/jobs/tool-jobs/src"], + "@deepseek-ai/dsh-tool-jobs/invariant": ["./packages/jobs/tool-jobs/src/invariant.ts"], + "@deepseek-ai/dsh-tool-lsp": ["./packages/lsp/tool-lsp/src"], + "@deepseek-ai/dsh-tool-lsp/invariant": ["./packages/lsp/tool-lsp/src/invariant.ts"], + "@deepseek-ai/dsh-tool-pwsh/invariant": ["./packages/shell/tool-pwsh/src/invariant.ts"], + "@deepseek-ai/dsh-tool-pwsh-persistent": ["./packages/shell/tool-pwsh-persistent/src"], + "@deepseek-ai/dsh-tool-pwsh-persistent/invariant": ["./packages/shell/tool-pwsh-persistent/src/invariant.ts"], + "@deepseek-ai/dsh-tool-ralph": ["./packages/workflow/tool-ralph/src"], + "@deepseek-ai/dsh-tool-ralph/invariant": ["./packages/workflow/tool-ralph/src/invariant.ts"], + "@deepseek-ai/dsh-tool-session-query": ["./packages/session-query/tool-session-query/src"], + "@deepseek-ai/dsh-tool-session-query/invariant": ["./packages/session-query/tool-session-query/src/invariant.ts"], + "@deepseek-ai/dsh-tool-skill": ["./packages/skill/tool-skill/src"], + "@deepseek-ai/dsh-tool-skill/invariant": ["./packages/skill/tool-skill/src/invariant.ts"], + "@deepseek-ai/dsh-tool-str-replace-editor": ["./packages/fs/tool-str-replace-editor/src"], + "@deepseek-ai/dsh-tool-str-replace-editor/invariant": ["./packages/fs/tool-str-replace-editor/src/invariant.ts"], + "@deepseek-ai/dsh-tool-subagent": ["./packages/subagent/tool-subagent/src"], + "@deepseek-ai/dsh-tool-subagent/invariant": ["./packages/subagent/tool-subagent/src/invariant.ts"], + "@deepseek-ai/dsh-tool-subagent-control": ["./packages/subagent/tool-subagent-control/src"], + "@deepseek-ai/dsh-tool-subagent-control/invariant": ["./packages/subagent/tool-subagent-control/src/invariant.ts"], + "@deepseek-ai/dsh-tool-subagent-report": ["./packages/subagent/tool-subagent-report/src"], + "@deepseek-ai/dsh-tool-subagent-report/invariant": ["./packages/subagent/tool-subagent-report/src/invariant.ts"], + "@deepseek-ai/dsh-tool-terminal": ["./packages/terminal/tool-terminal/src"], + "@deepseek-ai/dsh-tool-terminal/invariant": ["./packages/terminal/tool-terminal/src/invariant.ts"], + "@deepseek-ai/dsh-tool-todo": ["./packages/todo/tool-todo/src"], + "@deepseek-ai/dsh-tool-todo/invariant": ["./packages/todo/tool-todo/src/invariant.ts"], + "@deepseek-ai/dsh-tool-web": ["./packages/web/tool-web/src"], + "@deepseek-ai/dsh-tool-web/invariant": ["./packages/web/tool-web/src/invariant.ts"], + "@deepseek-ai/dsh-tool-workflow": ["./packages/workflow/tool-workflow/src"], + "@deepseek-ai/dsh-tool-workflow/invariant": ["./packages/workflow/tool-workflow/src/invariant.ts"], + "@deepseek-ai/dsh-tools": ["./packages/core/tools/src"], + "@deepseek-ai/dsh-tools/invariant": ["./packages/core/tools/src/invariant.ts"], + "@deepseek-ai/dsh-user-approval": ["./packages/interaction/user-approval/src"], + "@deepseek-ai/dsh-user-approval/invariant": ["./packages/interaction/user-approval/src/invariant.ts"], + "@deepseek-ai/dsh-user-questions": ["./packages/interaction/user-questions/src"], + "@deepseek-ai/dsh-user-questions/invariant": ["./packages/interaction/user-questions/src/invariant.ts"], + "@deepseek-ai/dsh-web": ["./packages/web/web/src"], + "@deepseek-ai/dsh-web/invariant": ["./packages/web/web/src/invariant.ts"], + "@deepseek-ai/dsh-web-app": ["./packages/bundle/web-app/src"], + "@deepseek-ai/dsh-web-app/invariant": ["./packages/bundle/web-app/src/invariant.ts"], + "@deepseek-ai/dsh-web-fetch-http": ["./packages/web/web-fetch-http/src"], + "@deepseek-ai/dsh-web-fetch-http/invariant": ["./packages/web/web-fetch-http/src/invariant.ts"], + "@deepseek-ai/dsh-web-search-deepseek": ["./packages/web/web-search-deepseek/src"], + "@deepseek-ai/dsh-web-search-deepseek/invariant": ["./packages/web/web-search-deepseek/src/invariant.ts"], + "@deepseek-ai/dsh-web-search-exa": ["./packages/web/web-search-exa/src"], + "@deepseek-ai/dsh-web-search-exa/invariant": ["./packages/web/web-search-exa/src/invariant.ts"], + "@deepseek-ai/dsh-web-search-perplexity": ["./packages/web/web-search-perplexity/src"], + "@deepseek-ai/dsh-web-search-perplexity/invariant": ["./packages/web/web-search-perplexity/src/invariant.ts"], + "@deepseek-ai/dsh-webhook": ["./packages/webhook/webhook/src"], + "@deepseek-ai/dsh-webhook/invariant": ["./packages/webhook/webhook/src/invariant.ts"], + "@deepseek-ai/dsh-webhook-github": ["./packages/webhook/webhook-github/src"], + "@deepseek-ai/dsh-webhook-github/invariant": ["./packages/webhook/webhook-github/src/invariant.ts"], + "@deepseek-ai/dsh-win32-process": ["./packages/subprocess/win32-process/src"], + "@deepseek-ai/dsh-win32-process/invariant": ["./packages/subprocess/win32-process/src/invariant.ts"], + "@deepseek-ai/dsh-workflow": ["./packages/workflow/workflow/src"], + "@deepseek-ai/dsh-workflow/invariant": ["./packages/workflow/workflow/src/invariant.ts"], + "@deepseek-ai/dsh-workflow-worker-thread": ["./packages/workflow/workflow-worker-thread/src"], + "@deepseek-ai/dsh-workflow-worker-thread/invariant": ["./packages/workflow/workflow-worker-thread/src/invariant.ts"], + "@deepseek-ai/dsh-workspace": ["./packages/workspace/workspace/src"], + "@deepseek-ai/dsh-workspace/invariant": ["./packages/workspace/workspace/src/invariant.ts"] + // END generated package aliases } } }