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/settings/README.md
README.md: 6f3719c58564a90fec3bd9f305cfaeb2b7bf0bf4
README.zh.md: 41a640e3bbb8b297f08e354e8bdcf56e524ea3bd
README.md: 9aad9391160ba6232d2de5005010ea99d8760abe
README.zh.md: 1ffc4f5184ac044d9605b256e9b57dcceecfa562

View File

@@ -7,6 +7,6 @@ This family resolves user-editable configuration through registered namespaces a
| Package | Role | ctx key |
|---|---|---|
| [`settings/`](settings/README.md) | Defines namespace registration, layered resolution, and commits | `ctx.settings` |
| [`settings-local/`](settings-local/README.md) | Stores settings in a local file and observes external edits | registers on `ctx.settings` |
| [`settings-file/`](settings-file/README.md) | Stores settings in a local file and observes external edits | registers on `ctx.settings` |
The subsystem reference — namespaces, owner scopes, resolution order, hot commits — is [docs/subsystems/settings.md](../../docs/subsystems/settings.md).

View File

@@ -7,6 +7,6 @@
| 包 | 职责 | ctx key |
|---|---|---|
| [`settings/`](settings/README.md) | 定义命名空间注册、分层解析与提交 | `ctx.settings` |
| [`settings-local/`](settings-local/README.md) | 在本地文件中存储设置并观察外部编辑 | 注册到 `ctx.settings` |
| [`settings-file/`](settings-file/README.md) | 在本地文件中存储设置并观察外部编辑 | 注册到 `ctx.settings` |
子系统参考——命名空间、owner scope、解析顺序、热提交——见 [docs/subsystems/settings.md](../../docs/subsystems/settings.md)。

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/settings/settings-local/README.md
README.md: a0bc94630f78aa7c101e3eb0795a7d07e585e347
README.zh.md: 5d829effb2c2422e957b7b32c6e8a2cf715af659
# pnpm run verify-translation-pairing --write packages/settings/settings-file/README.md
README.md: 78ff50bd3f9b7c0bd52d50a837bc3cb7dad7c5be
README.zh.md: 2be0494bd7fd40cb59ff3999f5405adc49ff2a2d

View File

@@ -1,4 +1,4 @@
# @deepseek-ai/dsh-settings-local
# @deepseek-ai/dsh-settings-file
English | [中文](README.zh.md)

View File

@@ -1,4 +1,4 @@
# @deepseek-ai/dsh-settings-local
# @deepseek-ai/dsh-settings-file
[English](README.md) | 中文

View File

@@ -1,5 +1,5 @@
{
"name": "@deepseek-ai/dsh-settings-local",
"name": "@deepseek-ai/dsh-settings-file",
"description": "File-backed settings provider (settings.yaml) 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/settings/settings-local"
"directory": "packages/settings/settings-file"
},
"type": "module",
"main": "lib/index.js",
@@ -34,7 +34,7 @@
"peerDependencies": {
"@deepseek-ai/dsh-atomic-write": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-paths": "workspace:^",
"@deepseek-ai/dsh-home-paths": "workspace:^",
"@deepseek-ai/dsh-settings": "workspace:^",
"@deepseek-ai/cordis": "workspace:^"
},
@@ -46,7 +46,7 @@
"devDependencies": {
"@deepseek-ai/dsh-atomic-write": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-paths": "workspace:^",
"@deepseek-ai/dsh-home-paths": "workspace:^",
"@deepseek-ai/dsh-settings": "workspace:^",
"@deepseek-ai/cordis": "workspace:^"
}

View File

@@ -4,7 +4,7 @@
* through the seam, and every write re-reads the document under a
* cross-process writer lock before patching it as a comment-preserving
* leaf-level diff.
* @module @deepseek-ai/dsh-settings-local
* @module @deepseek-ai/dsh-settings-file
*/
import { Context, Service } from '@deepseek-ai/cordis'
@@ -14,8 +14,8 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises'
import { dirname, extname, join, resolve } from 'node:path'
import { Document, parseDocument } from 'yaml'
import { withFileLock, writeFileAtomic } from '@deepseek-ai/dsh-atomic-write'
import { canonicalizeWatchPath, resolveDshHome } from '@deepseek-ai/dsh-paths'
import { Settings, deepEqualJson, type SettingsNamespace } from '@deepseek-ai/dsh-settings'
import { canonicalizeWatchPath, resolveDshHome } from '@deepseek-ai/dsh-home-paths'
import { SettingsProvider, deepEqualJson, type SettingsNamespace } from '@deepseek-ai/dsh-settings'
/** Plugin config: file location and hot-reload behavior. */
export interface Config {
@@ -56,7 +56,7 @@ export function resolveSpec(config: Config): ResolvedSpec {
const filename = resolve(config.path ?? join(resolveDshHome(config.dshHome), 'settings.yaml'))
const format = FORMATS[extname(filename)]
if (format === undefined) {
throw new Error(`settings-local: extension "${extname(filename)}" is not supported (use .yaml, .yml, or .json)`)
throw new Error(`settings-file: extension "${extname(filename)}" is not supported (use .yaml, .yml, or .json)`)
}
return {
filename,
@@ -102,7 +102,7 @@ function isEEXIST(error: unknown): boolean {
}
/** File-backed settings provider (`settings.yaml`/`.json`). */
export class SettingsLocal extends Settings {
export class FileSettingsProvider extends SettingsProvider {
static Config: z<Config> = z.object({
path: z.string(),
dshHome: z.string(),
@@ -139,7 +139,7 @@ export class SettingsLocal extends Settings {
this.spec = resolveSpec(config)
}
/** The local document is always writable through {@link Settings.update}. */
/** The local document is always writable through {@link SettingsProvider.update}. */
get writable(): boolean {
return true
}
@@ -202,7 +202,7 @@ export class SettingsLocal extends Settings {
// Only an invariant violation escaping the commit path can reject a
// refresh; keep the operation queue alive and surface it as an error so
// one poisoned commit cannot silently end hot reloading forever.
this.ctx.logger.error('settings-local: reload commit failed at %s', this.spec.filename)
this.ctx.logger.error('settings-file: reload commit failed at %s', this.spec.filename)
this.ctx.logger.error(error)
})
}
@@ -256,7 +256,7 @@ export class SettingsLocal extends Settings {
this.queueRefresh()
})
watcher.on('error', (error) => {
this.ctx.logger.warn('settings-local: watcher error on %s', this.spec.filename)
this.ctx.logger.warn('settings-file: watcher error on %s', this.spec.filename)
this.ctx.logger.warn(error)
})
}
@@ -277,7 +277,7 @@ export class SettingsLocal extends Settings {
// settings document can hold a `role('secret')` value.
const document = parseDocument(text, { prettyErrors: true })
if (document.errors.length > 0) {
throw new Error(`settings-local: invalid document at ${this.spec.filename}: ${
throw new Error(`settings-file: invalid document at ${this.spec.filename}: ${
document.errors.map((error) => {
const at = error.linePos?.[0]
/* v8 ignore next -- `prettyErrors` populates linePos on every error; the guard answers its optional type */
@@ -289,7 +289,7 @@ export class SettingsLocal extends Settings {
root = text.trim().length === 0 ? {} : JSON.parse(text)
}
if (typeof root !== 'object' || root === null || Array.isArray(root)) {
throw new TypeError(`settings-local: ${this.spec.filename} must be a map of namespace sections`)
throw new TypeError(`settings-file: ${this.spec.filename} must be a map of namespace sections`)
}
return root as Record<string, unknown>
}
@@ -307,7 +307,7 @@ export class SettingsLocal extends Settings {
await this.reconcileFromDisk()
} catch (error) {
if ((error as { code?: unknown } | null)?.code === 'INVARIANT') throw error
this.ctx.logger.warn('settings-local: reload failed at %s; keeping the last good document', this.spec.filename)
this.ctx.logger.warn('settings-file: reload failed at %s; keeping the last good document', this.spec.filename)
this.ctx.logger.warn(error)
}
}
@@ -367,4 +367,4 @@ export class SettingsLocal extends Settings {
}
}
export default SettingsLocal
export default FileSettingsProvider

View File

@@ -1,16 +1,16 @@
/**
* Package-owned invariant companion for `@deepseek-ai/dsh-settings-local`.
* @module @deepseek-ai/dsh-settings-local/invariant
* Package-owned invariant companion for `@deepseek-ai/dsh-settings-file`.
* @module @deepseek-ai/dsh-settings-file/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-settings-local'
const PACKAGE_NAME = '@deepseek-ai/dsh-settings-file'
/** Cordis companion plugin name. */
export const name = 'settings-local-invariant'
export const name = 'settings-file-invariant'
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']

View File

@@ -9,7 +9,7 @@ import { chmod, mkdtemp, readFile, rm, utimes, writeFile } from 'node:fs/promise
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { settingsNamespace } from '@deepseek-ai/dsh-settings'
import { SettingsLocal } from '../src/index.ts'
import { FileSettingsProvider } from '../src/index.ts'
const AlphaSchema: z<{ value: number }> = z.object({ value: z.number().default(0) })
const BetaSchema: z<{ value: number }> = z.object({ value: z.number().default(0) })
@@ -26,9 +26,9 @@ async function tempDir(): Promise<string> {
return dir
}
async function boot(config: ConstructorParameters<typeof SettingsLocal>[1]): Promise<Context> {
async function boot(config: ConstructorParameters<typeof FileSettingsProvider>[1]): Promise<Context> {
const ctx = new Context()
const fiber = ctx.plugin(SettingsLocal, config)
const fiber = ctx.plugin(FileSettingsProvider, config)
cleanups.push(async () => { await fiber.dispose() })
await fiber
return ctx

View File

@@ -16,7 +16,7 @@ import Loader from '@deepseek-ai/cordis-plugin-loader'
import Include from '@deepseek-ai/cordis-plugin-include'
import z from '@deepseek-ai/schemastery'
import { settingsNamespace, type SettingsScope } from '@deepseek-ai/dsh-settings'
import SettingsLocal from '../src/index.ts'
import FileSettingsProvider from '../src/index.ts'
interface ThemeConfig {
theme: 'dark' | 'light'
@@ -79,7 +79,7 @@ async function loadComposition(
...withSettings
? [
'- id: settings',
" name: '@deepseek-ai/dsh-settings-local'",
" name: '@deepseek-ai/dsh-settings-file'",
' config:',
` path: ${JSON.stringify(settingsPath)}`,
' debounceMs: 10',
@@ -96,7 +96,7 @@ async function loadComposition(
await ctx.plugin(Loader)
ctx.loader.builtins.include = Include
const modules = new Map<string, unknown>([
['@deepseek-ai/dsh-settings-local', SettingsLocal],
['@deepseek-ai/dsh-settings-file', FileSettingsProvider],
['test-settings-consumer', consumer],
])
ctx.loader.internal = {
@@ -114,7 +114,7 @@ async function loadComposition(
return { ctx, state, settingsPath }
}
describe('settings-local real composition', () => {
describe('settings-file real composition', () => {
it('boots from cordis.yml and hot-publishes an external settings edit', async () => {
const { ctx, state, settingsPath } = await loadComposition()

View File

@@ -6,7 +6,7 @@ import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { writeFileAtomic } from '@deepseek-ai/dsh-atomic-write'
import { settingsNamespace } from '@deepseek-ai/dsh-settings'
import { SettingsLocal, resolveSpec } from '../src/index.ts'
import { FileSettingsProvider, resolveSpec } from '../src/index.ts'
interface ThemeConfig {
theme: 'dark' | 'light'
@@ -30,9 +30,9 @@ async function tempDir(): Promise<string> {
return dir
}
async function boot(config: ConstructorParameters<typeof SettingsLocal>[1]): Promise<Context> {
async function boot(config: ConstructorParameters<typeof FileSettingsProvider>[1]): Promise<Context> {
const ctx = new Context()
const fiber = ctx.plugin(SettingsLocal, config)
const fiber = ctx.plugin(FileSettingsProvider, config)
cleanups.push(async () => { await fiber.dispose() })
await fiber
return ctx

View File

@@ -7,7 +7,7 @@ import { access, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { settingsNamespace } from '@deepseek-ai/dsh-settings'
import { SettingsLocal } from '../src/index.ts'
import { FileSettingsProvider } from '../src/index.ts'
const state = vi.hoisted(() => ({
failTempWrite: false,
@@ -59,9 +59,9 @@ async function tempDir(): Promise<string> {
return dir
}
async function boot(config: ConstructorParameters<typeof SettingsLocal>[1]): Promise<Context> {
async function boot(config: ConstructorParameters<typeof FileSettingsProvider>[1]): Promise<Context> {
const ctx = new Context()
const fiber = ctx.plugin(SettingsLocal, config)
const fiber = ctx.plugin(FileSettingsProvider, config)
cleanups.push(async () => { await fiber.dispose() })
await fiber
return ctx
@@ -72,7 +72,7 @@ describe('writer-lock failure cleanup', () => {
const dir = await tempDir()
const path = join(dir, 'settings.yaml')
const ctx = new Context()
const fiber = ctx.plugin(SettingsLocal, { path, watch: false })
const fiber = ctx.plugin(FileSettingsProvider, { path, watch: false })
cleanups.push(async () => { await fiber.dispose() })
await fiber
const settings = ctx.settings

View File

@@ -5,7 +5,7 @@ import { chmod, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { settingsNamespace } from '@deepseek-ai/dsh-settings'
import { SettingsLocal } from '../src/index.ts'
import { FileSettingsProvider } from '../src/index.ts'
// chokidar is the nondeterministic OS boundary: faking it lets these tests
// drive the event pipeline (error events, races with unreadable files)
@@ -56,9 +56,9 @@ async function tempDir(): Promise<string> {
return dir
}
async function boot(config: ConstructorParameters<typeof SettingsLocal>[1]): Promise<Context> {
async function boot(config: ConstructorParameters<typeof FileSettingsProvider>[1]): Promise<Context> {
const ctx = new Context()
const fiber = ctx.plugin(SettingsLocal, config)
const fiber = ctx.plugin(FileSettingsProvider, config)
cleanups.push(async () => { await fiber.dispose() })
await fiber
return ctx
@@ -137,7 +137,7 @@ describe('watcher pipeline', () => {
const path = join(dir, 'settings.yaml')
await writeFile(path, 'ui-theme:\n theme: light\n')
const ctx = new Context()
const fiber = ctx.plugin(SettingsLocal, { path, debounceMs: 5 })
const fiber = ctx.plugin(FileSettingsProvider, { path, debounceMs: 5 })
await fiber
ctx.settings.register(settingsNamespace('ui-theme'), ThemeSchema)
let disposed = false

View File

@@ -21,13 +21,13 @@
"path": "../../util/atomic-write"
},
{
"path": "../../util/paths"
"path": "../../util/home-paths"
},
{
"path": "../settings"
},
{
"path": "../../support/invariants"
"path": "../../runtime-diagnostics/invariants"
}
]
}

View File

@@ -89,7 +89,7 @@ export interface SettingsDescriptor {
secrets?: RedactedSecret[]
}
/** Options for {@link Settings.describe}. */
/** Options for {@link SettingsProvider.describe}. */
export interface SettingsDescribeOptions {
/**
* Strip `role('secret')` fields from `value`/`base`/`user` and enumerate
@@ -130,7 +130,7 @@ export interface SettingsScope<T> {
declare module '@deepseek-ai/cordis' {
interface Context {
settings: Settings
settings: SettingsProvider
}
}
@@ -347,7 +347,7 @@ interface SettingsRegistration {
* the base class owns namespace registration, resolution, validation, change
* detection, and the `settings/updated` commit event.
*/
export abstract class Settings extends Service {
export abstract class SettingsProvider extends Service {
private readonly registrations = new Map<SettingsNamespace, SettingsRegistration>()
/** Latest published raw document; empty until the provider's first publish. */
private document: Record<string, unknown> = {}
@@ -896,4 +896,4 @@ export function installSettingsSection<T>(
})
}
export default Settings
export default SettingsProvider

View File

@@ -1,14 +1,14 @@
import { describe, expect, it } from 'vitest'
import { Context } from '@deepseek-ai/cordis'
import z from '@deepseek-ai/schemastery'
import InvariantService from '@deepseek-ai/dsh-invariants'
import InvariantRegistry from '@deepseek-ai/dsh-invariants'
import * as SettingsInvariant from '../src/invariant.ts'
import { settingsNamespace } from '../src/index.ts'
import { MemorySettings } from './memory.ts'
async function setup(withProvider: boolean): Promise<Context> {
const ctx = new Context()
await ctx.plugin(InvariantService)
await ctx.plugin(InvariantRegistry)
await ctx.plugin(SettingsInvariant)
if (withProvider) await ctx.plugin(MemorySettings)
return ctx

View File

@@ -5,10 +5,10 @@
* packages.
*/
import { Settings, type SettingsNamespace } from '../src/index.ts'
import { SettingsProvider, type SettingsNamespace } from '../src/index.ts'
/** In-memory provider exposing the protected provider hooks to tests. */
export class MemorySettings extends Settings {
export class MemorySettings extends SettingsProvider {
/** Raw document the provider "storage" currently holds. */
doc: Record<string, unknown>
/** Every persist() call observed, in order. */
@@ -19,7 +19,7 @@ export class MemorySettings extends Settings {
/** Artificial persist latency so tests can interleave concurrent updates. */
persistDelayMs: number
constructor(ctx: ConstructorParameters<typeof Settings>[0], options?: {
constructor(ctx: ConstructorParameters<typeof SettingsProvider>[0], options?: {
doc?: Record<string, unknown>
writable?: boolean
persistDelayMs?: number

View File

@@ -1,14 +1,14 @@
import { describe, expect, it, vi } from 'vitest'
import { Context } from '@deepseek-ai/cordis'
import z from '@deepseek-ai/schemastery'
import { Settings, SettingsConflictError, deepEqualJson, installSettingsSection, settingsNamespace, type SettingsNamespace, type SettingsScope, type SettingsUpdateSource } from '../src/index.ts'
import { SettingsProvider, SettingsConflictError, deepEqualJson, installSettingsSection, settingsNamespace, type SettingsNamespace, type SettingsScope, type SettingsUpdateSource } from '../src/index.ts'
import { MemorySettings } from './memory.ts'
/** A provider implementing only the three primitives: the Service Definition owns initialization. */
class BareProvider extends Settings {
class BareProvider extends SettingsProvider {
doc: Record<string, unknown>
constructor(ctx: ConstructorParameters<typeof Settings>[0], options?: { doc?: Record<string, unknown> }) {
constructor(ctx: ConstructorParameters<typeof SettingsProvider>[0], options?: { doc?: Record<string, unknown> }) {
super(ctx)
this.doc = structuredClone(options?.doc ?? {})
}

View File

@@ -21,7 +21,7 @@
"path": "../../util/brand"
},
{
"path": "../../support/invariants"
"path": "../../runtime-diagnostics/invariants"
}
]
}