refactor: apply repository naming contract

Apply the accepted pre-release package, service, type, directory, and role renames as one repository-wide change.
This commit is contained in:
Tianyi Cui
2026-08-13 00:36:22 +08:00
parent 101df7cf58
commit a2d0f7f411
3281 changed files with 21730 additions and 21592 deletions

View File

@@ -2,5 +2,5 @@
# 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 packages/util/README.md
README.md: b84f2cbb88981aa2edbde65d8a711b28cc5b48e9
README.zh.md: 3814dffe1eb8c68f6d38d39aa750c80ce325f9af
README.md: 7867f6c235dfd3cb063214381ac2f40ed0f26ce3
README.zh.md: 65c48de0de038b4910583f79d9fa0c31ea2d67d0

View File

@@ -7,8 +7,8 @@ These zero-dependency packages provide small primitives shared by multiple capab
| Package | Role |
|---|---|
| [`brand/`](brand/README.md) | Provides nominally branded types |
| [`paths/`](paths/README.md) | Resolves the Harness data root and shared paths |
| [`paths/`](home-paths/README.md) | Resolves the Harness data root and shared paths |
| [`timeout/`](timeout/README.md) | Provides deadline and timeout classification primitives |
| [`retention/`](retention/README.md) | Bounds retained text and item collections |
| [`retention/`](output-retention/README.md) | Bounds retained text and item collections |
| [`atomic-write/`](atomic-write/README.md) | Replaces files atomically |
| [`native-command/`](native-command/README.md) | Runs host-native commands without a shell |

View File

@@ -7,8 +7,8 @@
| 包 | 职责 |
|---|---|
| [`brand/`](brand/README.md) | 提供带名义品牌的类型 |
| [`paths/`](paths/README.md) | 解析 Harness 数据根目录和共享路径 |
| [`paths/`](home-paths/README.md) | 解析 Harness 数据根目录和共享路径 |
| [`timeout/`](timeout/README.md) | 提供截止时间和超时分类原语 |
| [`retention/`](retention/README.md) | 限制保留文本和项集合的大小 |
| [`retention/`](output-retention/README.md) | 限制保留文本和项集合的大小 |
| [`atomic-write/`](atomic-write/README.md) | 以原子方式替换文件 |
| [`native-command/`](native-command/README.md) | 不经 shell 运行宿主原生命令 |

View File

@@ -2,5 +2,5 @@
# 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 packages/util/atomic-write/README.md
README.md: 2ff4abb6ac10d8b592ccd2056b4f1f92cc8518b0
README.zh.md: 570a5243aefbe6870c1991786f711adc77faacae
README.md: a767f24064c368b60d85fed6fa1d88349cab9587
README.zh.md: 6388e264898e0025fb6586acecab450be3eb9e55

View File

@@ -2,7 +2,7 @@
English | [中文](README.zh.md)
Zero-dependency atomic file replacement shared by file-backed stores that must never leave partial, symlink-hijacked, or wider-than-intended content on disk — the user-settings document (`dsh-settings-local`) and the credentials store (`dsh-credentials-local`).
Zero-dependency atomic file replacement shared by file-backed stores that must never leave partial, symlink-hijacked, or wider-than-intended content on disk — the user-settings document (`dsh-settings-file`) and the credentials store (`dsh-credentials-local`).
## Surface

View File

@@ -2,7 +2,7 @@
[English](README.md) | 中文
零依赖的原子文件替换,供绝不允许在磁盘上留下不完整、被符号链接劫持或权限过宽内容的文件型存储共用:用户设置文档(`dsh-settings-local`)与凭据存储(`dsh-credentials-local`)。
零依赖的原子文件替换,供绝不允许在磁盘上留下不完整、被符号链接劫持或权限过宽内容的文件型存储共用:用户设置文档(`dsh-settings-file`)与凭据存储(`dsh-credentials-local`)。
## 接口面

View File

@@ -1,12 +1,12 @@
import { describe, expect, it } from 'vitest'
import { Context } from '@deepseek-ai/cordis'
import InvariantService from '@deepseek-ai/dsh-invariants'
import InvariantRegistry from '@deepseek-ai/dsh-invariants'
import * as AtomicWriteInvariant from '../src/invariant.ts'
describe('atomic-write invariant companion', () => {
it('registers its explained empty runtime invariant', async () => {
const ctx = new Context()
await ctx.plugin(InvariantService)
await ctx.plugin(InvariantRegistry)
const fiber = await ctx.plugin(AtomicWriteInvariant)
expect(() => {

View File

@@ -9,7 +9,7 @@
],
"references": [
{
"path": "../../support/invariants"
"path": "../../runtime-diagnostics/invariants"
}
]
}

View File

@@ -2,5 +2,5 @@
# 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 packages/util/brand/README.md
README.md: 68401d95a31ed2122386794ad5256a5cd93bb2a6
README.zh.md: 0eeb2c8afb5fe1b279f49c839e769b8d0eea0a5a
README.md: ce05a652e2f863f737bf71fc473224fc16e25ab9
README.zh.md: 07d1279b601d38d4dcf9ca10ddeccb3c3ed3547b

View File

@@ -23,6 +23,6 @@ Construction goes through the per-id factory in the owning package. Comparison,
## Policy: brand ids that cross package boundaries
A package brands the ids it owns — `CallId` in `dsh-llm`, the shared agent/session `SessionId` in `dsh-session`, and `TaskId` in `dsh-tasks`. Brand cross-package ids that could plausibly be confused; not every string needs one.
A package brands the ids it owns — `CallId` in `dsh-llm`, the shared agent/session `SessionId` in `dsh-session`, and `JobId` in `dsh-jobs`. Brand cross-package ids that could plausibly be confused; not every string needs one.
This package owns only the primitive. Keeping it dependency-free lets `dsh-tasks`, for example, brand `TaskId` without importing an unrelated capability package merely to reach `Branded`.
This package owns only the primitive. Keeping it dependency-free lets `dsh-jobs`, for example, brand `JobId` without importing an unrelated capability package merely to reach `Branded`.

View File

@@ -23,6 +23,6 @@ export function SessionId(id: string): SessionId {
## 策略:为跨包边界的 id 添加品牌
包为自己拥有的 id 添加品牌:`CallId` 位于 `dsh-llm`,共享的 agent/会话 `SessionId` 位于 `dsh-session``TaskId` 位于 `dsh-tasks`。为可能被混淆的跨包 id 添加品牌,但无需为每个字符串都添加。
包为自己拥有的 id 添加品牌:`CallId` 位于 `dsh-llm`,共享的 agent/会话 `SessionId` 位于 `dsh-session``JobId` 位于 `dsh-jobs`。为可能被混淆的跨包 id 添加品牌,但无需为每个字符串都添加。
该包只负责这一原语。保持无依赖意味着,例如 `dsh-tasks` 可以为 `TaskId` 使用品牌类型,而无需仅为使用 `Branded` 而导入不相关的功能包。
该包只负责这一原语。保持无依赖意味着,例如 `dsh-jobs` 可以为 `JobId` 使用品牌类型,而无需仅为使用 `Branded` 而导入不相关的功能包。

View File

@@ -11,7 +11,7 @@
*
* Policy: a package brands the ids it owns — `CallId` in dsh-llm (tool-call
* correlation), the shared agent/session `SessionId` in dsh-session, and
* `TaskId` in dsh-tasks. Branding is for ids that cross package boundaries and
* `JobId` in dsh-jobs. Branding is for ids that cross package boundaries and
* could plausibly be confused; not every string needs a brand.
* This package owns ONLY the primitive — no concrete id, no runtime code beyond
* the (erased) type — so the brand vocabulary stays dependency-free and a

View File

@@ -9,7 +9,7 @@
],
"references": [
{
"path": "../../support/invariants"
"path": "../../runtime-diagnostics/invariants"
}
]
}

View File

@@ -1,6 +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 packages/util/paths/README.md
README.md: 8d10ed855a37f1205f87420b3f36f45b10e65bd3
README.zh.md: ed3ca377bd48252fe0ef3f95186dc6eb1fb6e6a0
# pnpm run verify-translation-pairing --write packages/util/home-paths/README.md
README.md: edcab2dcab6fa8957cde965ab8221df71dbe69f7
README.zh.md: 842d8351f2165f759c56a1153b758577ff1fc0bb

View File

@@ -1,4 +1,4 @@
# dsh-paths
# dsh-home-paths
English | [中文](README.zh.md)

View File

@@ -1,4 +1,4 @@
# dsh-paths
# dsh-home-paths
[English](README.md) | 中文

View File

@@ -1,5 +1,5 @@
{
"name": "@deepseek-ai/dsh-paths",
"name": "@deepseek-ai/dsh-home-paths",
"description": "Shared filesystem path helpers for the DeepSeek Harness",
"version": "0.0.1-rc.2",
"publishConfig": {
@@ -8,7 +8,7 @@
"repository": {
"type": "git",
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
"directory": "packages/util/paths"
"directory": "packages/util/home-paths"
},
"type": "module",
"main": "lib/index.js",

View File

@@ -1,7 +1,7 @@
/**
* Shared filesystem path helpers for DeepSeek Harness user data.
*
* @module @deepseek-ai/dsh-paths
* @module @deepseek-ai/dsh-home-paths
*/
import { opendir, realpath } from 'node:fs/promises'

View File

@@ -1,16 +1,16 @@
/**
* Package-owned invariant companion for `@deepseek-ai/dsh-retention`.
* @module @deepseek-ai/dsh-retention/invariant
* Package-owned invariant companion for `@deepseek-ai/dsh-home-paths`.
* @module @deepseek-ai/dsh-home-paths/invariant
*/
/* jscpd:ignore-start */
import type { Context } from '@deepseek-ai/cordis'
import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
const PACKAGE_NAME = '@deepseek-ai/dsh-retention'
const PACKAGE_NAME = '@deepseek-ai/dsh-home-paths'
/** Cordis companion plugin name. */
export const name = 'retention-invariant'
export const name = 'home-paths-invariant'
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']

View File

@@ -11,7 +11,7 @@ import {
dshHomePath,
expandHomePath,
resolveDshHome,
} from '@deepseek-ai/dsh-paths'
} from '@deepseek-ai/dsh-home-paths'
afterEach(() => {
vi.unstubAllEnvs()

View File

@@ -9,7 +9,7 @@
],
"references": [
{
"path": "../../support/invariants"
"path": "../../runtime-diagnostics/invariants"
}
]
}

View File

@@ -1,6 +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 packages/util/retention/README.md
README.md: b33f433db0b430082e7cd60421e9c407ea823c99
README.zh.md: ea5daf3129dba88076ab574c9bf09c9aca1e2cb6
# pnpm run verify-translation-pairing --write packages/util/launch-environment/README.md
README.md: 80ec4d59c38ee296e836f8cff52e3a89b0700ff5
README.zh.md: 5dc9bfd1fc70e5432ca9f62e81a7d7a23f4a48c9

View File

@@ -1,4 +1,4 @@
# dsh-environment
# dsh-launch-environment
English | [中文](README.zh.md)
@@ -22,13 +22,13 @@ Names match the way the platform matches them: exactly on POSIX, case-insensitiv
```ts
import type { Context } from '@deepseek-ai/cordis'
import { environmentOf } from '@deepseek-ai/dsh-environment'
import { launchEnvironmentOf } from '@deepseek-ai/dsh-launch-environment'
declare const ctx: Context
const endpoint = environmentOf(ctx).get('DEEPSEEK_BASE_URL')?.value
const endpoint = launchEnvironmentOf(ctx).get('DEEPSEEK_BASE_URL')?.value
```
`environmentOf(ctx)` returns the launcher's snapshot when the product CLI booted the tree, and otherwise the inherited environment as the only layer. That fallback does not weaken the rules: an SDK host or a bare `cordis.yml` discovered no files, so everything it has really is the environment it was launched with.
`launchEnvironmentOf(ctx)` returns the launcher's snapshot when the product CLI booted the tree, and otherwise the inherited environment as the only layer. That fallback does not weaken the rules: an SDK host or a bare `cordis.yml` discovered no files, so everything it has really is the environment it was launched with.
## Known Limitations and Deferred Work

View File

@@ -1,4 +1,4 @@
# dsh-environment
# dsh-launch-environment
[English](README.md) | 中文
@@ -22,13 +22,13 @@
```ts
import type { Context } from '@deepseek-ai/cordis'
import { environmentOf } from '@deepseek-ai/dsh-environment'
import { launchEnvironmentOf } from '@deepseek-ai/dsh-launch-environment'
declare const ctx: Context
const endpoint = environmentOf(ctx).get('DEEPSEEK_BASE_URL')?.value
const endpoint = launchEnvironmentOf(ctx).get('DEEPSEEK_BASE_URL')?.value
```
当产品 CLI命令行界面启动了这棵树时`environmentOf(ctx)` 返回启动器的快照否则返回只含继承环境的那一层。该回退并不削弱规则SDK 宿主或裸 `cordis.yml` 从未发现过任何文件,因此它拥有的一切确实就是它被启动时的环境。
当产品 CLI命令行界面启动了这棵树时`launchEnvironmentOf(ctx)` 返回启动器的快照否则返回只含继承环境的那一层。该回退并不削弱规则SDK 宿主或裸 `cordis.yml` 从未发现过任何文件,因此它拥有的一切确实就是它被启动时的环境。
## 已知限制与暂缓事项

View File

@@ -1,5 +1,5 @@
{
"name": "@deepseek-ai/dsh-environment",
"name": "@deepseek-ai/dsh-launch-environment",
"description": "Immutable DeepSeek Harness launch environment that records which layer supplied each value",
"version": "0.0.1-rc.2",
"publishConfig": {
@@ -8,7 +8,7 @@
"repository": {
"type": "git",
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
"directory": "packages/util/environment"
"directory": "packages/util/launch-environment"
},
"type": "module",
"main": "lib/index.js",

View File

@@ -3,7 +3,7 @@
* supplied each value. Harness consumers resolve through it instead of a flattened
* `process.env`; launchers may still materialize accepted values for config
* expressions and third-party libraries.
* @module @deepseek-ai/dsh-environment
* @module @deepseek-ai/dsh-launch-environment
*/
import type { Context } from '@deepseek-ai/cordis'
@@ -13,34 +13,34 @@ import type { Context } from '@deepseek-ai/cordis'
* this process inherited, the invoking directory's `.env`, the Harness home's
* `.env`.
*/
export type EnvironmentSource = 'process' | 'project-env' | 'user-env'
export type LaunchEnvironmentSource = 'process' | 'project-env' | 'user-env'
/** Layer order, most trusted first. */
const SOURCE_ORDER: readonly EnvironmentSource[] = ['process', 'project-env', 'user-env']
const SOURCE_ORDER: readonly LaunchEnvironmentSource[] = ['process', 'project-env', 'user-env']
/** One resolved variable and the layer it came from. */
export interface EnvironmentEntry {
export interface LaunchEnvironmentEntry {
/** The value as the layer supplied it; may be empty, which each owner judges for itself. */
value: string
/** The layer that supplied it. */
source: EnvironmentSource
source: LaunchEnvironmentSource
/** Absolute path of the file that supplied it; absent for `process`. */
path?: string
}
/**
* The frozen environment of one launch. Construct through
* {@link createEnvironmentSnapshot}; nothing mutates it afterwards, so a
* {@link createLaunchEnvironmentSnapshot}; nothing mutates it afterwards, so a
* later `chdir`, workspace switch, or resumed session observes the same
* values a consumer resolved at boot.
*/
export interface EnvironmentSnapshot {
export interface LaunchEnvironmentSnapshot {
/**
* Resolve one name across every layer, most trusted first.
* @param name - the variable name.
* @returns the winning entry, or `undefined` when no layer supplies it.
*/
get(name: string): EnvironmentEntry | undefined
get(name: string): LaunchEnvironmentEntry | undefined
/**
* Resolve one name only from `sources`, retaining canonical trust order;
* omitted layers are unreachable.
@@ -48,7 +48,7 @@ export interface EnvironmentSnapshot {
* @param sources - the layers allowed in the canonical trust order.
* @returns the first matching entry, or `undefined`.
*/
getFrom(name: string, sources: readonly EnvironmentSource[]): EnvironmentEntry | undefined
getFrom(name: string, sources: readonly LaunchEnvironmentSource[]): LaunchEnvironmentEntry | undefined
}
/**
@@ -62,9 +62,9 @@ function lookupKey(name: string): string {
return process.platform === 'win32' ? name.toUpperCase() : name
}
/** One layer's raw contents, as {@link createEnvironmentSnapshot} receives them. */
export interface EnvironmentLayerInput {
source: EnvironmentSource
/** One layer's raw contents, as {@link createLaunchEnvironmentSnapshot} receives them. */
export interface LaunchEnvironmentLayerInput {
source: LaunchEnvironmentSource
/** Absolute path of the file behind this layer; omit for `process`. */
path?: string
values: Readonly<Record<string, string>>
@@ -75,17 +75,17 @@ export interface EnvironmentLayerInput {
* @param layers - the layers in any order; the result searches them by canonical trust order.
* @returns the immutable snapshot.
*/
export function createEnvironmentSnapshot(layers: readonly EnvironmentLayerInput[]): EnvironmentSnapshot {
export function createLaunchEnvironmentSnapshot(layers: readonly LaunchEnvironmentLayerInput[]): LaunchEnvironmentSnapshot {
// Copy every layer so later mutations cannot change the snapshot. Fold names
// on Windows so case variants cannot split precedence; POSIX remains exact.
const bySource = new Map<EnvironmentSource, { path?: string; values: Map<string, string> }>()
const bySource = new Map<LaunchEnvironmentSource, { path?: string; values: Map<string, string> }>()
for (const layer of layers) {
bySource.set(layer.source, {
...layer.path === undefined ? {} : { path: layer.path },
values: new Map(Object.entries(layer.values).map(([name, value]) => [lookupKey(name), value])),
})
}
const getFrom = (name: string, sources: readonly EnvironmentSource[]): EnvironmentEntry | undefined => {
const getFrom = (name: string, sources: readonly LaunchEnvironmentSource[]): LaunchEnvironmentEntry | undefined => {
const key = lookupKey(name)
for (const source of SOURCE_ORDER) {
if (!sources.includes(source)) continue
@@ -103,7 +103,7 @@ export function createEnvironmentSnapshot(layers: readonly EnvironmentLayerInput
}
/** Context slot the launcher fills with this run's snapshot before any config entry mounts. */
export const DSH_ENVIRONMENT_KEY = 'launcherEnvironment'
export const DSH_LAUNCH_ENVIRONMENT_KEY = 'launchEnvironment'
/**
* Return the launcher's snapshot, or the inherited environment as the sole
@@ -111,14 +111,14 @@ export const DSH_ENVIRONMENT_KEY = 'launcherEnvironment'
* @param ctx - the consuming plugin's context.
* @returns the snapshot to resolve user-facing values against.
*/
export function environmentOf(ctx: Context): EnvironmentSnapshot {
return ctx.get(DSH_ENVIRONMENT_KEY)
?? createEnvironmentSnapshot([{ source: 'process', values: process.env as Record<string, string> }])
export function launchEnvironmentOf(ctx: Context): LaunchEnvironmentSnapshot {
return ctx.get(DSH_LAUNCH_ENVIRONMENT_KEY)
?? createLaunchEnvironmentSnapshot([{ source: 'process', values: process.env as Record<string, string> }])
}
declare module '@deepseek-ai/cordis' {
interface Context {
/** Launcher-owned snapshot of this run's environment; absent in compositions the product CLI did not boot. */
launcherEnvironment?: EnvironmentSnapshot
launchEnvironment?: LaunchEnvironmentSnapshot
}
}

View File

@@ -1,16 +1,16 @@
/**
* Package-owned invariant companion for `@deepseek-ai/dsh-environment`.
* @module @deepseek-ai/dsh-environment/invariant
* Package-owned invariant companion for `@deepseek-ai/dsh-launch-environment`.
* @module @deepseek-ai/dsh-launch-environment/invariant
*/
/* jscpd:ignore-start */
import type { Context } from '@deepseek-ai/cordis'
import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
const PACKAGE_NAME = '@deepseek-ai/dsh-environment'
const PACKAGE_NAME = '@deepseek-ai/dsh-launch-environment'
/** Cordis companion plugin name. */
export const name = 'environment-invariant'
export const name = 'launch-environment-invariant'
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']

View File

@@ -1,16 +1,16 @@
import { describe, expect, it, vi } from 'vitest'
import { Context } from '@deepseek-ai/cordis'
import {
createEnvironmentSnapshot, DSH_ENVIRONMENT_KEY, environmentOf,
createLaunchEnvironmentSnapshot, DSH_LAUNCH_ENVIRONMENT_KEY, launchEnvironmentOf,
} from '../src/index.ts'
const layered = createEnvironmentSnapshot([
const layered = createLaunchEnvironmentSnapshot([
{ source: 'process', values: { SHARED: 'from-process', ONLY_PROCESS: 'p' } },
{ source: 'project-env', path: '/work/.env', values: { SHARED: 'from-project', ONLY_PROJECT: 'j' } },
{ source: 'user-env', path: '/home/.dsh/.env', values: { SHARED: 'from-user', ONLY_USER: 'u' } },
])
describe('createEnvironmentSnapshot', () => {
describe('createLaunchEnvironmentSnapshot', () => {
it('resolves across every layer, most trusted first, and reports the winning source', () => {
expect(layered.get('SHARED')).toEqual({ value: 'from-process', source: 'process' })
expect(layered.get('ONLY_PROJECT')).toEqual({ value: 'j', source: 'project-env', path: '/work/.env' })
@@ -29,7 +29,7 @@ describe('createEnvironmentSnapshot', () => {
it('copies each layer, so a later mutation of the source object cannot change it', () => {
const values: Record<string, string> = { KEY: 'first' }
const snapshot = createEnvironmentSnapshot([{ source: 'process', values }])
const snapshot = createLaunchEnvironmentSnapshot([{ source: 'process', values }])
values.KEY = 'second'
values.LATE = 'added'
expect(snapshot.get('KEY')).toEqual({ value: 'first', source: 'process' })
@@ -37,12 +37,12 @@ describe('createEnvironmentSnapshot', () => {
})
it('keeps an empty value as a present value, for its owner to judge', () => {
const snapshot = createEnvironmentSnapshot([{ source: 'process', values: { EMPTY: '' } }])
const snapshot = createLaunchEnvironmentSnapshot([{ source: 'process', values: { EMPTY: '' } }])
expect(snapshot.get('EMPTY')).toEqual({ value: '', source: 'process' })
})
it('orders lookups canonically regardless of construction order', () => {
const reversed = createEnvironmentSnapshot([
const reversed = createLaunchEnvironmentSnapshot([
{ source: 'user-env', path: '/u', values: { K: 'u' } },
{ source: 'process', values: { K: 'p' } },
])
@@ -50,17 +50,17 @@ describe('createEnvironmentSnapshot', () => {
})
})
describe('environmentOf', () => {
describe('launchEnvironmentOf', () => {
it('returns the launcher snapshot when the product CLI provided one', () => {
const ctx = new Context()
ctx.provide(DSH_ENVIRONMENT_KEY, layered)
expect(environmentOf(ctx)).toBe(layered)
ctx.provide(DSH_LAUNCH_ENVIRONMENT_KEY, layered)
expect(launchEnvironmentOf(ctx)).toBe(layered)
})
it('falls back to the inherited environment as the only layer', () => {
vi.stubEnv('DSH_ENV_SPEC_FALLBACK', 'ambient')
try {
const snapshot = environmentOf(new Context())
const snapshot = launchEnvironmentOf(new Context())
expect(snapshot.get('DSH_ENV_SPEC_FALLBACK')).toEqual({ value: 'ambient', source: 'process' })
} finally {
vi.unstubAllEnvs()

View File

@@ -9,7 +9,7 @@
],
"references": [
{
"path": "../../support/invariants"
"path": "../../runtime-diagnostics/invariants"
}
]
}

View File

@@ -2,5 +2,5 @@
# 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 packages/util/native-command/README.md
README.md: dd9d1ddaf817b2ff77ec0cd01710053e918b4296
README.zh.md: 3ff8a392f2c511295adb0bf5f62b6e0527cbaea6
README.md: 8a552ac36fac150ae18b2a8adaab1dd489ecb476
README.zh.md: 618e50afe7cd157b2dfc4763adfbf1d5d88d213e

View File

@@ -24,4 +24,4 @@ None; this package neither assembles nor sends a provider request.
## Known Limitations and Deferred Work
- **No output bounding** — both streams buffer unbounded in memory; every current caller invokes small native tools whose output is a path or an error line. Adopt `dsh-retention` bounding before pointing this at commands with meaningful output volume.
- **No output bounding** — both streams buffer unbounded in memory; every current caller invokes small native tools whose output is a path or an error line. Adopt `dsh-output-retention` bounding before pointing this at commands with meaningful output volume.

View File

@@ -24,4 +24,4 @@ import { runNativeCommand, type NativeCommandRunner } from '@deepseek-ai/dsh-nat
## 已知限制与暂缓事项
- **不做输出限量**——两路流在内存中无界缓冲;当前每个调用方只运行输出为一个路径或一行错误的小型原生工具。把它指向输出量可观的命令之前,先接入 `dsh-retention` 限量。
- **不做输出限量**——两路流在内存中无界缓冲;当前每个调用方只运行输出为一个路径或一行错误的小型原生工具。把它指向输出量可观的命令之前,先接入 `dsh-output-retention` 限量。

View File

@@ -9,7 +9,7 @@
],
"references": [
{
"path": "../../support/invariants"
"path": "../../runtime-diagnostics/invariants"
}
]
}

View File

@@ -1,6 +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 packages/util/environment/README.md
README.md: cdbc5b6dd4a5ea90c323f570598e2db124b43857
README.zh.md: bbef1719370c787763eaa686a5609ec31833386e
# pnpm run verify-translation-pairing --write packages/util/output-retention/README.md
README.md: e1d2c828fd4c6526cc391e7f93d7fe20df26e268
README.zh.md: 36730ab83dc7f6a93376a8f0272160d29935e6e0

View File

@@ -1,4 +1,4 @@
# dsh-retention
# dsh-output-retention
English | [中文](README.zh.md)
@@ -14,11 +14,11 @@ It is a **library, not a service or plugin**: no `ctx`, registers nothing, emits
import {
ItemRetainer, TextRetainer,
describeOmitted, formatRetentionNotice,
} from '@deepseek-ai/dsh-retention'
} from '@deepseek-ai/dsh-output-retention'
import type {
Omitted, PushDecision, RetainedItems, RetainedText,
ItemRetentionStrategy, TextRetentionStrategy, RetentionNotice,
} from '@deepseek-ai/dsh-retention'
} from '@deepseek-ai/dsh-output-retention'
```
| Export | Role |
@@ -53,7 +53,7 @@ Current retention consumers use these mappings:
|---|---|---|
| `glob` | `ItemRetainer<FsGlobEntry>`, `head` | Collect the full sorted path list for a spill file while retaining the first page inline. Path mapping, skipped candidates, and `incomplete` stay outside. |
| `grep` | `ItemRetainer<FlatGrepMatch>`, `head` | Collect matches for a spill file while retaining the first page inline. Per-match preview truncation, grouping, sorting, and `incomplete` stay outside. |
| `bash` | `TextRetainer`, `tail` or `headTail` | Executor still owns spill files, exit status, signal, timeout, and background tasks. |
| `bash` | `TextRetainer`, `tail` or `headTail` | Executor still owns spill files, exit status, signal, timeout, and background jobs. |
| `web_fetch` | `TextRetainer`, `head` or `headTail` | Provider/resource caps stay provider facts; the retainer supplies only retained text and omission metadata. |
| `web_search` | `ItemRetainer<WebSearchSource>`, `head` | Standardizes the "sources capped" notice when providers return more sources than the model-facing result should include. |

View File

@@ -1,4 +1,4 @@
# dsh-retention
# dsh-output-retention
[English](README.md) | 中文
@@ -14,11 +14,11 @@
import {
ItemRetainer, TextRetainer,
describeOmitted, formatRetentionNotice,
} from '@deepseek-ai/dsh-retention'
} from '@deepseek-ai/dsh-output-retention'
import type {
Omitted, PushDecision, RetainedItems, RetainedText,
ItemRetentionStrategy, TextRetentionStrategy, RetentionNotice,
} from '@deepseek-ai/dsh-retention'
} from '@deepseek-ai/dsh-output-retention'
```
| 导出项 | 职责 |

View File

@@ -1,5 +1,5 @@
{
"name": "@deepseek-ai/dsh-retention",
"name": "@deepseek-ai/dsh-output-retention",
"description": "Zero-dependency bounded-retention primitive: ItemRetainer/TextRetainer + neutral notice helpers (what did we keep, what did we omit)",
"version": "0.0.1-rc.2",
"publishConfig": {
@@ -8,7 +8,7 @@
"repository": {
"type": "git",
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
"directory": "packages/util/retention"
"directory": "packages/util/output-retention"
},
"type": "module",
"main": "lib/index.js",

View File

@@ -27,7 +27,7 @@
* web bodies). `head` / `tail` / `headTail`, preserving UTF-8 boundaries at
* {@link TextRetainer.finish}.
*
* @module @deepseek-ai/dsh-retention
* @module @deepseek-ai/dsh-output-retention
*/
/**

View File

@@ -1,16 +1,16 @@
/**
* Package-owned invariant companion for `@deepseek-ai/dsh-paths`.
* @module @deepseek-ai/dsh-paths/invariant
* Package-owned invariant companion for `@deepseek-ai/dsh-output-retention`.
* @module @deepseek-ai/dsh-output-retention/invariant
*/
/* jscpd:ignore-start */
import type { Context } from '@deepseek-ai/cordis'
import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
const PACKAGE_NAME = '@deepseek-ai/dsh-paths'
const PACKAGE_NAME = '@deepseek-ai/dsh-output-retention'
/** Cordis companion plugin name. */
export const name = 'paths-invariant'
export const name = 'output-retention-invariant'
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']

View File

@@ -6,7 +6,7 @@ import {
type Omitted,
type RetentionNotice,
TextRetainer,
} from '@deepseek-ai/dsh-retention'
} from '@deepseek-ai/dsh-output-retention'
/** Decode a RetainedText via a round-trip helper for readable UTF-8 assertions. */
const utf8 = (s: string): Uint8Array => new TextEncoder().encode(s)

View File

@@ -9,7 +9,7 @@
],
"references": [
{
"path": "../../support/invariants"
"path": "../../runtime-diagnostics/invariants"
}
]
}

View File

@@ -2,5 +2,5 @@
# 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 packages/util/timeout/README.md
README.md: 54908a7e5df0e6c5d337a0b9f82d447cfc55b49d
README.zh.md: b80cbeffb3a3a729bd2f4d2e0116088e68d0c949
README.md: c29f6a7661abf40eadafc7637c1bbca509a62a24
README.zh.md: ca05fcaf0ac7f3379d746e11a123294e3febf436

View File

@@ -56,7 +56,7 @@ Local file `read`/`write`/`edit` take no `timeoutMs`: file IO runs untimed becau
## Model Experience
Indirectly, through consumers such as `dsh-timeout-policy`, which may replace a provider result with a retained timeout error or suppress a late result.
Indirectly, through consumers such as `dsh-tool-call-timeout-policy`, which may replace a provider result with a retained timeout error or suppress a late result.
#### KV Cache effect

View File

@@ -56,7 +56,7 @@ export async function runWithDeadline(upstream: AbortSignal | undefined, timeout
## 模型体验
通过 `dsh-timeout-policy` 等消费方间接影响模型;消费方可能会将提供方结果替换为已保留的超时错误,或抑制延迟结果。
通过 `dsh-tool-call-timeout-policy` 等消费方间接影响模型;消费方可能会将提供方结果替换为已保留的超时错误,或抑制延迟结果。
#### KV Cache 影响

View File

@@ -9,7 +9,7 @@
],
"references": [
{
"path": "../../support/invariants"
"path": "../../runtime-diagnostics/invariants"
}
]
}