Merge pull request #4610 from deepseek-harness/worktree/prohibit-as-unknown

feat(infra): prohibit new unknown casts and clean up existing uses
This commit is contained in:
Tianyi Cui authored and GitHub committed 2026-09-19 20:27:11 +08:00
commit fafa154a14
158 files changed
+3286 -257

No files matched your search

@@ -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-09-19-no-unknown-casts.md
2026-09-19-no-unknown-casts.md: 2f90422d0980fddc2569951ef7f8dba34b488ce4
2026-09-19-no-unknown-casts.zh.md: 3b66236e586a60a61cdcc1f93b1c0c14ce27eb15
@@ -0,0 +1,35 @@
# Agent Note: Prohibit new assertions to unknown
Status: implemented
English | [中文](2026-09-19-no-unknown-casts.zh.md)
## Problem
An assertion through `unknown` removes TypeScript's compatibility check between the original value and a subsequent asserted type. Production code can hide an incorrect interface, and tests can claim that an incomplete fixture satisfies a service. Existing uses also include legitimate widening of untyped parser results, which can use explicit `unknown` declarations instead.
The repository contains assertions across many independent package and test owners. Removing all of them in one change would combine the enforcement decision with unrelated type and fixture redesigns, making the behavior of each replacement harder to review.
## Decision
New direct assertions to `unknown` are prohibited in first-party JavaScript and TypeScript, including tests, fixtures, benchmarks, and scripts. Both `as unknown` and `<unknown>` syntax are covered, including parenthesized target types and union targets with a direct `unknown` member. An `unknown` declaration remains valid: external data can enter as `const value: unknown = JSON.parse(text)` and reach its declared parser before use. Typed in-process values retain the existing rule against unnecessary runtime validation.
The [checker](../../../../scripts/verify-no-unknown-casts.ts), exposed as `pnpm run verify-no-unknown-casts`, uses the TypeScript syntax tree. It scans tracked source files and non-ignored untracked source files; vendored sources and frozen archived Agent Notes retain their ownership exclusions. The checker ignores comments, strings, and declarations of `unknown`.
Existing assertions have an exact baseline keyed by repository-relative path, a SHA-256 digest of the assertion's syntax tokens, and occurrence count. Baseline edits may only delete entries or decrease counts; reviewers must reject added files, new fingerprints, and increased counts. New or changed assertions outside the baseline and stale baseline entries fail the check; a file-wide allowance or a count budget cannot authorize replacement debt. `--prune` mechanically removes entries or reduces counts and refuses to write while new violations exist. There is no command that adds new exceptions.
The checker participates in CI static and primary modes and the local `hygiene` and `check-all` profiles in [the gate runner](../../../../scripts/run-gates.ts). Existing casts remain visible debt for their owners to remove with suitable type, parser, or fixture changes.
## Alternatives considered
**Remove every existing assertion before enforcing the rule.** Rejected because the cleanup spans unrelated services, wire parsers, and test doubles. Exact existing exceptions let enforcement begin without treating a bulk substitution as a type-safety improvement.
**Allow whole files or a repository-wide count.** Rejected because either permits a new assertion to replace a removed one. The baseline identifies each existing assertion and rejects increased occurrence counts.
**Search text for `as unknown`.** Rejected because comments and strings can contain the phrase, while whitespace, comments between tokens, and angle-bracket syntax can conceal an actual assertion from a text pattern.
## Consequences
Owners must resolve a cast before changing or moving its assertion into an unlisted form or file. Any change to an operand token, including an identifier rename or a quote, trailing comma, or parentheses edit, invalidates the fingerprint even when runtime behavior is unchanged. Formatting whitespace and comments alone do not change the recorded tokens. Removing a cast also requires pruning its baseline entry, so obsolete allowances cannot silently accumulate.
Passing this check establishes absence of unlisted direct assertions to `unknown`, including union targets absorbed by a direct `unknown` member. It does not establish general type safety or resolve type aliases or intersections. JavaScript JSDoc `@type` assertions, `unknown[]`, `Promise<unknown>`, and other containing types are outside this syntactic rule. Replacing a cast with `any`, another unchecked assertion, or a helper that merely hides the conversion does not resolve the underlying typing problem.
@@ -0,0 +1,35 @@
# Agent Note: 禁止新增到 unknown 的类型断言
Status: implemented
[English](2026-09-19-no-unknown-casts.md) | 中文
## 问题
经由 `unknown` 的类型断言会移除 TypeScript 对原始值与后续断言类型之间的兼容性检查。生产代码可能因此掩盖错误的接口,测试也可能声称不完整的 fixture(测试前置数据)满足某项服务类型。现有用法还包括合理地将无类型的解析结果拓宽为 `unknown`,这种情况可以改用显式的 `unknown` 声明。
仓库中的断言分布在许多相互独立的包和测试中。一次性全部移除会把执行规则的决策与无关的类型、fixture 重新设计混在一起,使每处替换的行为更难审查。
## 决策
第一方 JavaScript 和 TypeScript 禁止新增直接断言到 `unknown` 的表达式,范围包括测试、fixture、基准测试和脚本。规则覆盖 `as unknown` 和 `<unknown>` 两种语法,也覆盖带括号的目标类型,以及直接包含 `unknown` 成员的联合目标类型。`unknown` 声明仍然有效:外部数据可以通过 `const value: unknown = JSON.parse(text)` 进入,再交给其声明的解析器处理后使用。同进程内已有类型的值仍遵循不得添加不必要运行时校验的现有规则。
[检查器](../../../../scripts/verify-no-unknown-casts.ts)通过 `pnpm run verify-no-unknown-casts` 运行,使用 TypeScript 语法树。它扫描已跟踪的源文件和未被忽略的未跟踪源文件;vendored 源码和已冻结的归档 Agent Notes 保留各自维护规则要求的排除项。检查器忽略注释、字符串和 `unknown` 声明。
现有断言使用精确基线记录,键由仓库相对路径、断言语法 token 的 SHA-256 摘要及出现次数组成。基线修改只能删除条目或减少次数;审查者必须拒绝新增文件、新增指纹和增加次数。基线之外新增或变化的断言以及陈旧的基线条目都会使检查失败;整个文件的放行或数量预算不能授权替换成新的技术债。`--prune` 机械地删除条目或减少次数,存在新增违规时拒绝写入。没有可添加新例外的命令。
检查器加入 CI 静态模式和主模式,以及[门禁运行器](../../../../scripts/run-gates.ts)中的本地 `hygiene` 和 `check-all` 配置。现有断言仍是明确记录的技术债,由所属模块通过适当的类型、解析器或 fixture 修改来移除。
## 考虑过的替代方案
**先移除所有现有断言,再执行规则。** 不采用,因为清理涉及互不相关的服务、协议解析器和测试替身。精确记录现有例外后即可开始执行规则,无须把批量替换视为类型安全的改善。
**放行整个文件或设置仓库级数量限制。** 不采用,因为两者都允许用新增断言替代已删除的断言。基线识别每个现有断言,并拒绝增加出现次数。
**在文本中搜索 `as unknown`。** 不采用,因为注释和字符串可能包含这段文字,而空白、token 之间的注释和尖括号语法可能让实际断言躲过文本模式。
## 影响
所属模块必须先解决类型转换问题,才能将断言改为未登记的形式或移至未登记的文件。操作数 token 的任何变化,包括标识符重命名或引号、尾随逗号、括号修改,即使不改变运行时行为,也会使指纹失效。仅修改格式空白和注释不会改变所记录的 token。删除断言后还须缩减其基线条目,防止无效例外悄然累积。
通过检查只说明没有未登记的、直接到 `unknown` 的类型断言,其中包括被直接 `unknown` 成员吸收的联合目标类型。它不证明整体类型安全,也不解析类型别名或交叉类型。JavaScript JSDoc `@type` 断言、`unknown[]`、`Promise<unknown>` 等包含该类型的类型不属于这条语法规则。将断言替换成 `any`、另一种未经检查的断言,或仅隐藏转换的辅助函数,都没有解决底层类型问题。
+1
View File
@@ -140,6 +140,7 @@ Real-API tests/demos read `DEEPSEEK_API_KEY`, optional `DEEPSEEK_BASE_URL`, and
- **Misconfiguration fails loud** at load when self-contained, otherwise at the earliest resolvable point; never silently skip a missing referent.
- **Opaque cross-boundary ids are branded** (`Branded<B>` from `dsh-brand`), never bare `string`.
- **Trust TypeScript at typed same-process boundaries.** Do not add runtime validation, fallback behavior, or hostile-input tests solely for values the static interface requires; validate at parser/config, queued, model/tool JSON, durable/file, worker, process, and wire boundaries.
- **No new assertions to `unknown`** (`as unknown` or `<unknown>`). Preserve or reduce the exact legacy baseline; use typed values or validation for replacements ([rule](.agents/notes/implemented/process/2026-09-19-no-unknown-casts.md)).
- **Source plane vs artifact plane, never mixed.** Static gates and tests resolve workspace imports through tsconfig `paths` to `src` and pass on a clean tree; gates consuming built `lib/` declare that dependency ([layout](docs/development.md#typescript-project-layout)).
- **Keep compiler faces explicit.** A package with both Host and Client programs exposes face-specific leaf configs and a solution-only root; repo-wide programs seed a face config, never the root solution ([layout](docs/development.md#typescript-project-layout)).
- **An empty `catch` names the error** and why; keep its `try` to one statement.
+3 -3
View File
@@ -25,10 +25,10 @@ describe('dsh badge assembled snapshot', () => {
configPath,
tsconfigPath,
})
const disabledSnapshot = JSON.parse(disabled.stdout) as unknown
const enabledSnapshot = JSON.parse(
const disabledSnapshot: unknown = JSON.parse(disabled.stdout)
const enabledSnapshot: unknown = JSON.parse(
enabled.stdout.replaceAll(badgeAssetsPath, '{{badgeAssetsPath}}'),
) as unknown
)
expect(disabled.stderr).toBe('')
expect(enabled.stderr).toBe('')
@@ -87,7 +87,7 @@ describe('same-session goal snapshot through the ACP automation driver', () => {
const log = result.sessionLogs[0]
if (log === undefined) throw new Error('goal snapshot did not persist its session')
const records = parseJsonl(log.content)
const events = records.slice(1) as unknown as SessionEvent[]
const events = records.slice(1) as SessionEvent[]
const calls = events.filter(event => event.type === 'tool/call').map(event => event.data.name)
expect(calls).toEqual(['create_goal', 'get_goal'])
const rounds = events.flatMap(event => event.type === 'user/message' && event.data.source.kind === 'goal'
@@ -136,7 +136,7 @@ describe('same-session goal snapshot through the ACP automation driver', () => {
const log = result.sessionLogs[0]
if (log === undefined) throw new Error('goal wrap-up snapshot did not persist its session')
const records = parseJsonl(log.content)
const events = records.slice(1) as unknown as SessionEvent[]
const events = records.slice(1) as SessionEvent[]
const calls = events.filter(event => event.type === 'tool/call').map(event => event.data.name)
expect(calls).toEqual(['create_goal', 'update_goal'])
expect(foldGoal(events)).toMatchObject({
@@ -81,7 +81,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY)('compaction: a long session compa
const summaries = events.filter(e => e.type === 'compaction/summary')
expect(summaries.length, JSON.stringify(ends.map(event => event.data.error))).toBeGreaterThan(0)
const replaceNode = events.find((e) => {
const se = e as unknown as { type: string; surfaceOp?: unknown }
const se = e as { type: string; surfaceOp?: unknown }
return se.type === 'user/message' && typeof se.surfaceOp === 'object' && se.surfaceOp !== null
})
expect(replaceNode).toBeDefined()
+1 -1
View File
@@ -182,7 +182,7 @@ describe('dsh web authentication through the real CLI', () => {
const authenticated = await describeSettings(port, firstUrl.host, cookie)
expect(authenticated.status).toBe(200)
const authenticatedBody = JSON.parse(authenticated.body) as unknown
const authenticatedBody: unknown = JSON.parse(authenticated.body)
expect(authenticatedBody).toMatchObject({
type: 'server-response',
rpcId: 'web-auth-real-cli',
+1 -1
View File
@@ -128,7 +128,7 @@ export function writeDesktopRuntime(
const sharedPackages = [...new Set(sharedNames)].sort().map((name) => {
if (!PACKAGE_NAME.test(name)) throw new Error(`desktop runtime: invalid shared package ${name}`)
const path = `node_modules/${name}`
const manifest = JSON.parse(readFileSync(join(runtimePath(root, path), 'package.json'), 'utf8')) as unknown
const manifest: unknown = JSON.parse(readFileSync(join(runtimePath(root, path), 'package.json'), 'utf8'))
if (!record(manifest) || manifest.name !== name || typeof manifest.version !== 'string' || valid(manifest.version) === null) {
throw new Error(`desktop runtime: invalid shared package manifest ${name}`)
}
+1 -1
View File
@@ -27,7 +27,7 @@ afterEach(async () => { await ctx.fiber.dispose() })
function idleAgent(): AgentState { return { status: 'idle', inbox: { nextTurn: [], nextStep: [] } } }
function request(next: () => Promise<void>) {
const incoming = Readable.from([]) as unknown as IncomingMessage
const incoming = Readable.from([]) as IncomingMessage
const response = { writeHead: vi.fn(), end: vi.fn() }
return { response, done: ctx.waterfall('connection/request', incoming, response as unknown as ServerResponse, next) }
}
+1 -1
View File
@@ -1275,7 +1275,7 @@ describe('desktop main startup', () => {
const window = harness.windows[0]!
const frame = { url: 'dsh-app://app/' }
Object.assign(window.webContents, { mainFrame: frame })
const handler = harness.handlers.get(DESKTOP_IPC.bootFailed)! as unknown as (event: unknown, message: unknown) => void
const handler = harness.handlers.get(DESKTOP_IPC.bootFailed)! as (event: unknown, message: unknown) => void
const event = { sender: window.webContents, senderFrame: frame }
expect(() => { handler({ ...event, senderFrame: { url: 'https://other.example/' } }, 'untrusted') }).toThrow('unowned renderer')
expect(() => { handler({ ...event, senderFrame: { ...frame } }, 'subframe') }).toThrow('non-primary frame')
+1 -1
View File
@@ -43,7 +43,7 @@ it('forwards upload bytes and cancellation with Host credentials while keeping t
method: 'POST', body: 'upload bytes', headers: { origin: 'dsh-app://app', cookie: 'untrusted' },
})
const response = await forwardWebRequest(request, 'http://127.0.0.1:1234/?token=secret', 'session=owned')
const [target, init] = fetch.mock.calls[0] as unknown as [URL, RequestInit]
const [target, init] = fetch.mock.calls[0] as [URL, RequestInit]
expect(target.href).toBe('http://127.0.0.1:1234/api/upload?name=file')
expect(new Headers(init.headers).get('cookie')).toBe('session=owned')
expect(new Headers(init.headers).get('origin')).toBeNull()
+1 -1
View File
@@ -682,7 +682,7 @@ describe('web e2e: shipped right Sidebar', () => {
}, 60_000)
it('CONTROL: the host endpoint answers when called directly, bypassing the wire', async () => {
const files = (scaffold.ctx as unknown as {
const files = (scaffold.ctx as {
get(name: string): {
read(
scope: { sessionId: string; workspaceRoot: string },
+1 -1
View File
@@ -84,7 +84,7 @@ async function startSearchServer(captured: CapturedSearchRequest[]): Promise<{ s
request.setEncoding('utf8')
request.on('data', (chunk: string) => { body += chunk })
request.on('end', () => {
const parsedBody = JSON.parse(body) as unknown
const parsedBody: unknown = JSON.parse(body)
captured.push({
path: request.url ?? '',
apiKey: typeof request.headers['x-api-key'] === 'string' ? request.headers['x-api-key'] : undefined,
+1
View File
@@ -99,6 +99,7 @@
"verify-public-repository-links": "tsx scripts/verify-public-repository-links.ts",
"verify-repository-references": "tsx scripts/verify-repository-references.ts",
"verify-concrete-terms": "tsx scripts/verify-concrete-terms.ts",
"verify-no-unknown-casts": "tsx scripts/verify-no-unknown-casts.ts",
"verify-doc-refs": "tsx scripts/verify-doc-refs.ts",
"verify-subsystem-pages": "tsx scripts/verify-subsystem-pages.ts",
"verify-package-paths": "tsx scripts/verify-package-paths.ts",
+1 -1
View File
@@ -476,7 +476,7 @@ function decodeSessionListCursor(value: string | null | undefined): SessionListC
if (value === undefined || value === null) return undefined
if (!/^[A-Za-z0-9_-]+$/.test(value)) throw new Error('session/list cursor is invalid')
try {
const decoded = JSON.parse(Buffer.from(value, 'base64url').toString('utf8')) as unknown
const decoded: unknown = JSON.parse(Buffer.from(value, 'base64url').toString('utf8'))
const createdAt: unknown = Array.isArray(decoded) ? decoded[0] : undefined
const sessionId: unknown = Array.isArray(decoded) ? decoded[1] : undefined
if (
@@ -93,7 +93,7 @@ export class ClientRemoteEvents {
): () => void {
const dispose = privateEvents(callerCtx).on(
this.eventKey(event),
listener as unknown as RemoteEventListener,
listener as RemoteEventListener,
)
return () => { dispose() }
}
+12 -12
View File
@@ -276,10 +276,10 @@ export class TypertGatewayService extends Service implements TypertGateway {
const claims = new Set<string>()
for (const [serviceKey, definition] of Object.entries(this.ctx.reflect.props)) {
if (definition.type !== 'service') continue
const receiver = this.ctx.get(serviceKey) as unknown
const receiver: unknown = this.ctx.get(serviceKey)
if (!isObject(receiver)) continue
const original = originalOf(receiver)
const binding = Reflect.get(original, 'typertRemote') as unknown
const binding: unknown = Reflect.get(original, 'typertRemote')
if (!isObject(binding) || typeof Reflect.get(binding, 'namespace') !== 'string') continue
const namespace = Reflect.get(binding, 'namespace') as string
for (const candidate of remoteMethods(original)) {
@@ -483,7 +483,7 @@ export class TypertGatewayService extends Service implements TypertGateway {
}
const signals = new Set(projected.signal === undefined ? [] : [projected.signal])
const abort = (): void => {
const reason = [...signals].find(signal => signal.aborted)?.reason as unknown
const reason: unknown = [...signals].find(signal => signal.aborted)?.reason
this.cancelRemoteEvent(pending, reason instanceof Error
? reason
: new Error('typert gateway: Remote event was cancelled', { cause: reason }))
@@ -599,7 +599,7 @@ export class TypertGatewayService extends Service implements TypertGateway {
const descriptor = this.resolveDescriptor(request.namespace, request.method, endpoint)
assertExactArguments(request.args, descriptor, endpoint)
const receiverContext = await this.resolveReceiverContext(descriptor, request.args, endpoint)
const receiver = receiverContext.get(descriptor.service) as unknown
const receiver: unknown = receiverContext.get(descriptor.service)
if (!isObject(receiver)) {
throw new TypertGatewayError(
'gateway/service-unavailable',
@@ -612,7 +612,7 @@ export class TypertGatewayService extends Service implements TypertGateway {
this.resolveParameter(parameter, request.args, endpoint)))
if (descriptor.cancellation !== undefined) args.push(request.signal ?? NEVER_ABORTED_SIGNAL)
const implementation = descriptor.implementation ?? descriptor.method
const method = Reflect.get(receiver, implementation) as unknown
const method: unknown = Reflect.get(receiver, implementation)
if (typeof method !== 'function') {
throw new TypertGatewayError(
'gateway/method-unavailable',
@@ -640,10 +640,10 @@ export class TypertGatewayService extends Service implements TypertGateway {
const candidates: InvocationDescriptor[] = []
for (const [serviceKey, definition] of Object.entries(this.ctx.reflect.props)) {
if (definition.type !== 'service') continue
const receiver = this.ctx.get(serviceKey) as unknown
const receiver: unknown = this.ctx.get(serviceKey)
if (!isObject(receiver)) continue
const original = originalOf(receiver)
const value = Reflect.get(original, 'typertRemote') as unknown
const value: unknown = Reflect.get(original, 'typertRemote')
if (value === undefined) continue
const binding = readBinding(value, original, serviceKey, endpoint)
if (binding.namespace !== namespace) continue
@@ -961,8 +961,8 @@ async function *cancellableStream(
endpoint: string,
signal: AbortSignal,
): AsyncGenerator {
const asyncFactory = Reflect.get(source, Symbol.asyncIterator) as unknown
const syncFactory = Reflect.get(source, Symbol.iterator) as unknown
const asyncFactory: unknown = Reflect.get(source, Symbol.asyncIterator)
const syncFactory: unknown = Reflect.get(source, Symbol.iterator)
const iterator = typeof asyncFactory === 'function'
? Reflect.apply(asyncFactory, source, []) as AsyncIterator<unknown>
: Reflect.apply(syncFactory as (...args: never[]) => Iterator<unknown>, source, [])
@@ -1020,7 +1020,7 @@ function validateBinding(
endpoint: string,
): ResolvedBinding {
const original = originalOf(receiver)
const value = Reflect.get(original, 'typertRemote') as unknown
const value: unknown = Reflect.get(original, 'typertRemote')
if (value === undefined) {
throw new TypertGatewayError(
'gateway/binding-invalid',
@@ -1052,11 +1052,11 @@ function readBinding(
`Service ${JSON.stringify(serviceKey)} has an inconsistent typertRemote binding`,
)
}
return value as unknown as TypertGatewayBinding
return value as TypertGatewayBinding
}
function originalOf(receiver: object): object {
const original = Reflect.get(receiver, symbols.original) as unknown
const original: unknown = Reflect.get(receiver, symbols.original)
return isObject(original) ? original : receiver
}
+5 -5
View File
@@ -270,14 +270,14 @@ export type RemoteStreamServerMessage =
export function parseRemoteStreamClientMessage(text: string): RemoteStreamClientMessage {
return parseMessage(text, (value) => {
if (value.type === 'cancel' && exactKeys(value, ['type', 'streamId']) && validId(value.streamId)) {
return value as unknown as RemoteStreamClientMessage
return value as RemoteStreamClientMessage
}
if (value.type === 'open'
&& exactKeys(value, ['type', 'streamId', 'endpoint', 'payload'])
&& validId(value.streamId)
&& typeof value.endpoint === 'string'
&& value.endpoint.length > 0) {
return value as unknown as RemoteStreamClientMessage
return value as RemoteStreamClientMessage
}
throw new Error('api gateway: invalid Remote stream client message')
})
@@ -293,10 +293,10 @@ export function parseRemoteStreamServerMessage(text: string): RemoteStreamServer
if (value.type === 'item'
&& (exactKeys(value, ['type', 'streamId']) || exactKeys(value, ['type', 'streamId', 'value']))
&& validId(value.streamId)) {
return value as unknown as RemoteStreamServerMessage
return value as RemoteStreamServerMessage
}
if (value.type === 'end' && exactKeys(value, ['type', 'streamId']) && validId(value.streamId)) {
return value as unknown as RemoteStreamServerMessage
return value as RemoteStreamServerMessage
}
if (value.type === 'error'
&& exactKeys(value, ['type', 'streamId', 'error'])
@@ -306,7 +306,7 @@ export function parseRemoteStreamServerMessage(text: string): RemoteStreamServer
&& typeof value.error.code === 'string'
&& typeof value.error.message === 'string'
&& isRecord(value.error.details)) {
return value as unknown as RemoteStreamServerMessage
return value as RemoteStreamServerMessage
}
throw new Error('api gateway: invalid Remote stream server message')
})
@@ -1080,7 +1080,7 @@ function rawText(data: RawData): string {
function streamErrorMessage(frames: readonly Record<string, unknown>[], streamId: string): string | undefined {
const error = frames.find(frame => frame.streamId === streamId)?.error
if (typeof error !== 'object' || error === null) return undefined
const message = Reflect.get(error, 'message') as unknown
const message: unknown = Reflect.get(error, 'message')
return typeof message === 'string' ? message : undefined
}
@@ -981,7 +981,7 @@ describe('Client Typert API', () => {
await vi.waitFor(() => { expect(ctx.typert.remotes.list()).toEqual([]) })
const retry = await ctx.remote.$mount({ package: '@fixture/retry-batch', descriptors: [first, second] })
expect(ctx.remote.probe.create).toBeTypeOf('function')
expect((ctx.remote.probe as unknown as Record<string, unknown>).archive).toBeTypeOf('function')
expect((ctx.remote.probe as Record<string, unknown>).archive).toBeTypeOf('function')
await retry()
})
@@ -1223,7 +1223,7 @@ describe('TypertGatewayService', () => {
}),
})
expect(invalid.status).toBe(200)
const invalidBody = await invalid.json() as unknown
const invalidBody: unknown = await invalid.json()
expect(invalidBody).toMatchObject({
type: 'server-response',
rpcId: 'rpc-invalid',
@@ -1247,7 +1247,7 @@ describe('TypertGatewayService', () => {
}),
})
expect(withdrawn.status).toBe(200)
const withdrawnBody = await withdrawn.json() as unknown
const withdrawnBody: unknown = await withdrawn.json()
expect(withdrawnBody).toMatchObject({
type: 'server-response',
rpcId: 'rpc-withdrawn',
@@ -172,7 +172,7 @@ describe('Remote stream mux server carrier lifecycle', () => {
client.send(openFrame('write-failure'))
await didOpen
const serverSocket = acceptedSocket(entry.mux)
const mutable = serverSocket as unknown as {
const mutable = serverSocket as {
send(data: unknown, callback: (error?: Error) => void): void
}
mutable.send = (_data, callback): void => {
@@ -52,7 +52,7 @@ function sourceOf(gateway: GatewayProbe): TypertRemoteEventSource {
}
function emitRaw(ctx: Context, event: string, args: readonly unknown[]): void {
const emit = ctx.emit.bind(ctx) as unknown as (name: string, ...values: readonly unknown[]) => void
const emit = ctx.emit.bind(ctx) as (name: string, ...values: readonly unknown[]) => void
emit(event, ...args)
}
@@ -63,7 +63,7 @@ function waterfallRaw(
args: readonly unknown[],
next: () => Promise<unknown>,
): Promise<unknown> {
const waterfall = ctx.waterfall.bind(ctx) as unknown as (
const waterfall = ctx.waterfall.bind(ctx) as (
receiver: object,
name: string,
...values: readonly unknown[]
@@ -40,7 +40,7 @@ export function assertSessionWireEvent(value: unknown): asserts value is Session
throw new Error(`${subject} has an invalid envelope`)
}
// Event names and payloads are merge-extensible; only event-local owner rules run here.
const current = event as unknown as SessionEvent
const current = event as SessionEvent
validateSurfaceMetadata(current)
validateSessionEventData(current, subject)
}
@@ -19,12 +19,12 @@ const modelSelectionSchema = z.object({
const modelSelectionProjectionStateSchema = z.object({
lastUsed: modelSelectionSchema.nullable(),
pending: modelSelectionSchema.nullable(),
}) as unknown as z.ZodType<ModelSelectionProjectionState>
}) as z.ZodType<ModelSelectionProjectionState>
const modelSelectionProjectionSchema = z.object({
lastUsed: modelSelectionSchema.nullable(),
next: modelSelectionSchema.nullable(),
}) as unknown as z.ZodType<ModelSelectionProjection>
}) as z.ZodType<ModelSelectionProjection>
/**
* Advance durable model-selection state by one Session event.
@@ -164,7 +164,7 @@ describe('session.search', () => {
},
})
expect(searchSessions).toHaveBeenCalledOnce()
const [query, exec] = searchSessions.mock.calls[0] as unknown as [
const [query, exec] = searchSessions.mock.calls[0] as [
SessionSearchRequest,
{ signal: AbortSignal },
]
+2 -2
View File
@@ -156,12 +156,12 @@ function parseArguments(raw: string): unknown {
if (raw === '') return {}
const seen = { nonFinite: false }
try {
const parsed = JSON.parse(raw, (_key, value: unknown) => {
const parsed: unknown = JSON.parse(raw, (_key, value: unknown) => {
// `1e400` is valid JSON but parses to Infinity, which JSON.stringify
// reports as null; keep the raw text rather than misdescribe the call.
if (typeof value === 'number' && !Number.isFinite(value)) seen.nonFinite = true
return value
}) as unknown
})
return seen.nonFinite ? raw : parsed
} catch {
return raw
@@ -57,7 +57,7 @@ type BrowserLauncher = ChildProcess & { stderr: PassThrough }
/** Minimal browser-launcher process for the native handoff adapter. */
function launcher(): BrowserLauncher {
return Object.assign(new EventEmitter(), { stderr: new PassThrough() }) as unknown as BrowserLauncher
return Object.assign(new EventEmitter(), { stderr: new PassThrough() }) as BrowserLauncher
}
/** Stage a dist fixture and point the bundle's resolver at it. */
@@ -7,7 +7,7 @@ import { bridge } from '../src/http-bridge.ts'
describe('HTTP bridge abort', () => {
it('destroys a declared-oversize request instead of draining it', async () => {
const destroyed: true[] = []
const request = Readable.from([]) as unknown as IncomingMessage
const request = Readable.from([]) as IncomingMessage
Object.assign(request, {
url: '/api/session.prompt',
method: 'POST',
@@ -38,7 +38,7 @@ describe('HTTP bridge abort', () => {
const body = JSON.stringify({
type: 'client-request', rpcId: 'picker-1', method: 'directoryPicker/pick', payload: { args: {} },
})
const request = Readable.from([Buffer.from(body)]) as unknown as IncomingMessage
const request = Readable.from([Buffer.from(body)]) as IncomingMessage
Object.assign(request, {
url: '/api/directoryPicker/pick',
method: 'POST',
@@ -76,7 +76,7 @@ describe('HTTP bridge abort', () => {
})
it('streams a declared 2.19 GiB request before the body ends and bypasses the JSON buffer cap', async () => {
const request = new Readable({ read() {} }) as unknown as IncomingMessage
const request = new Readable({ read() {} }) as IncomingMessage
Object.assign(request, {
url: '/api/session/uploadFileBinary?sessionId=s1',
method: 'POST',
@@ -120,7 +120,7 @@ describe('HTTP bridge abort', () => {
it('closes an unread streaming request after returning an early validation response', async () => {
const destroyed: true[] = []
const request = new Readable({ read() {} }) as unknown as IncomingMessage
const request = new Readable({ read() {} }) as IncomingMessage
Object.assign(request, {
url: '/api/session/uploadFileBinary',
method: 'POST',
@@ -36,21 +36,21 @@ function fakeHttpServer(
/** Bodyless GET carrying the given headers (enough for the trust fence + bridge). */
function fakeRequest(headers: Record<string, string>, url = `${API_PATH}/session.list`): IncomingMessage {
const request = Readable.from([]) as unknown as IncomingMessage
const request = Readable.from([]) as IncomingMessage
Object.assign(request, { url, method: 'GET', headers })
return request
}
/** JSON POST carrying a complete client-request envelope. */
function fakePost(headers: Record<string, string>, url: string, body: unknown): IncomingMessage {
const request = Readable.from([Buffer.from(JSON.stringify(body))]) as unknown as IncomingMessage
const request = Readable.from([Buffer.from(JSON.stringify(body))]) as IncomingMessage
Object.assign(request, { url, method: 'POST', headers: { 'content-type': 'application/json', ...headers } })
return request
}
/** Raw POST for malformed-body and media-type boundary cases. */
function fakeRawPost(headers: Record<string, string>, url: string, body: string): IncomingMessage {
const request = Readable.from([Buffer.from(body)]) as unknown as IncomingMessage
const request = Readable.from([Buffer.from(body)]) as IncomingMessage
Object.assign(request, { url, method: 'POST', headers })
return request
}
@@ -298,7 +298,7 @@ function workerTransport(): FileUploadTransport {
}
function parseFileUploadResult(body: string): RemoteResult<FileUploadValue> {
const value = JSON.parse(body) as unknown
const value: unknown = JSON.parse(body)
if (!isRecord(value) || typeof value.ok !== 'boolean') {
throw new TypeError('file upload transport returned an invalid result')
}
+1 -1
View File
@@ -325,7 +325,7 @@ function readSourceMap(clientPath: string): Record<string, unknown> | undefined
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined
throw error
}
const value = JSON.parse(body.toString('utf8')) as unknown
const value: unknown = JSON.parse(body.toString('utf8'))
const parsed = typeof value === 'object' && value !== null ? value as Record<string, unknown> : undefined
if (
parsed === undefined
@@ -771,7 +771,7 @@ describe('client bundle activation', () => {
expect((await routeRequest(route, batch.url, 'HEAD')).body).toHaveLength(0)
expect((await routeRequest(route, batch.url, 'POST')).status).toBe(405)
const batchMap = await routeRequest(route, mapUrl(batch.url))
const parsedBatchMap = JSON.parse(batchMap.body.toString('utf8')) as unknown
const parsedBatchMap: unknown = JSON.parse(batchMap.body.toString('utf8'))
const parsedPluginMap = JSON.parse(map) as Record<string, unknown>
expect(parsedBatchMap).toMatchObject({
version: 3,
@@ -945,12 +945,13 @@ describe('shared module declarations', () => {
const { service } = constructWithRoute([packageName])
const row = service.graph().entries[0]
if (row === undefined) throw new Error('shared-declared graph row missing')
const revisionMatcher: unknown = expect.any(String)
// The browser resolves this reference against its own document; the
// response table still answers the absolute route it resolves to.
expect(row).toEqual({
id: packageName,
url: `plugins/??${packageName}/client.js&rev=${row.rev}`,
rev: expect.any(String) as unknown,
rev: revisionMatcher,
external: ['react'],
})
})
@@ -32,7 +32,7 @@ const WHEEL_LINE_PX = 16
function pageBehavior(): ScrollBehavior {
// jsdom (the unit lane) implements no matchMedia despite lib.dom's
// non-optional typing; the optional call keeps that lane on the default.
const matchMedia = (window as unknown as { matchMedia?: Window['matchMedia'] }).matchMedia
const matchMedia = (window as { matchMedia?: Window['matchMedia'] }).matchMedia
return matchMedia?.('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth'
}
@@ -80,7 +80,7 @@ function compactSource(event: Parameters<ConversationNodeDefinition['match']>[0]
sourceCommandId?: CommandId
} | undefined {
if (event.type !== 'user/message' || !isReplacementSurfaceEvent(event)) return undefined
const source = event.data.source as unknown as {
const source = event.data.source as {
kind?: unknown
compactionId?: unknown
sourceCommandId?: CommandId
@@ -7,8 +7,8 @@ import type { AssistantBlock } from '../src/client/contract/snapshot.ts'
afterEach(cleanup)
const t = ((_key: string) => 'label') as unknown as ChatViewSlotProps['t']
const renderMessageImages = (() => null) as unknown as ChatNodeOwnerProps['renderMessageImages']
const t = ((_key: string) => 'label') as ChatViewSlotProps['t']
const renderMessageImages = (() => null) as ChatNodeOwnerProps['renderMessageImages']
function textBlock(text: string): AssistantBlock {
return { kind: 'text', text }
@@ -129,7 +129,7 @@ describe('Chat apply wiring', () => {
b.runtime.slots.entries('conversation.composer.dock').find(entry => entry.options.id === 'stats')!,
b.runtime.slots.entries('conversation.chat.node').find(entry => entry.options.key === 'turn-tail')!,
]) {
const injected = (entry.inject as unknown as () => Pick<PerformanceUsageRowInjected, 'hooks'>)()
const injected = (entry.inject as () => Pick<PerformanceUsageRowInjected, 'hooks'>)()
expect(injected.hooks.performanceUsage).toBe(face.hooks.performanceUsage)
}
await b.runtime.dispose()
@@ -285,8 +285,8 @@ function makeHarness(
inspectCall: ChatNodeOwnerProps['inspectCall']
}> = []
const renderCommandSlot = ((_key: string, _owner: object, opts?: { fallback?: React.ReactNode }) =>
opts?.fallback ?? null) as unknown as React.ComponentProps<typeof CommandNodeView>['renderSlot']
const renderTurnTailSlot = (() => null) as unknown as
opts?.fallback ?? null) as React.ComponentProps<typeof CommandNodeView>['renderSlot']
const renderTurnTailSlot = (() => null) as
React.ComponentProps<typeof TurnTailNodeView>['renderSlot']
let nodeSlotOverride: React.ComponentProps<typeof ChatNodeSeat>['renderSlot'] | undefined
const renderNodeSlot = ((key: string, owner: object, opts?: {
@@ -367,7 +367,7 @@ function makeHarness(
default:
return opts?.fallback ?? null
}
}) as unknown as React.ComponentProps<typeof ChatNodeSeat>['renderSlot']
}) as React.ComponentProps<typeof ChatNodeSeat>['renderSlot']
const renderSlot = renderNodeSlot
// SessionProvider seat arrives with the session-scope child declaration;
// ChatView never invokes it (pass-through stub).
@@ -1244,7 +1244,7 @@ describe('ChatView', () => {
data-first={JSON.stringify(images[0])}
/>
)
}) as unknown as ChatViewSlotProps['renderSlot']
}) as ChatViewSlotProps['renderSlot']
const view = render(<h.ChatView {...{ ...h.props, renderSlot }} />)
const images = view.getAllByTestId('echo-image')
expect(images).toHaveLength(2)
@@ -1289,7 +1289,7 @@ describe('ChatView', () => {
data-compact={String(compact)}
/>
)
}) as unknown as ChatViewSlotProps['renderSlot']
}) as ChatViewSlotProps['renderSlot']
const view = render(<h.ChatView {...{ ...h.props, renderSlot }} />)
const first = view.getByTestId('images-first.png')
const file = view.getByTitle('notes.txt')
@@ -7,7 +7,7 @@ import { describe, expect, it } from 'vitest'
import type { StreamChunk } from '@deepseek-ai/dsh-api-remotes/client'
import { PartialAccumulator } from '../src/client/conversation-nodes/partial.ts'
const chunk = (c: Record<string, unknown>): StreamChunk => c as unknown as StreamChunk
const chunk = (c: Record<string, unknown>): StreamChunk => c as StreamChunk
describe('PartialAccumulator', () => {
it('builds empty blocks per block-start type, unknown type falls to other', () => {
@@ -839,7 +839,7 @@ describe('execute payload', () => {
const after = vi.fn()
const warn = vi.spyOn(b.ctx.logger, 'warn').mockImplementation(() => undefined)
b.ctx.on('command/executed', () => { throw syncFailure })
const rejectingListener = (() => Promise.reject(asyncFailure)) as unknown as () => void
const rejectingListener = (() => Promise.reject(asyncFailure)) as () => void
b.ctx.on('command/executed', rejectingListener)
b.ctx.on('command/executed', after)
@@ -69,7 +69,7 @@ class BoundConversation implements ConversationBinding {
): ObservableSnapshot<ConversationViewSnapshotMap[Target] | undefined> {
let source = this.targetSources.get(target)
if (source === undefined) {
const views = this.viewStore as unknown as { get(key: string): unknown }
const views = this.viewStore as { get(key: string): unknown }
source = {
getSnapshot: () => views.get(target),
subscribe: (listener) => {
@@ -102,7 +102,7 @@ function kitFor(snapshot: SessionSnapshot, injected: Partial<QueueDockInjected>
sessionId: SID,
t,
usePanelInfo,
useSessions: (() => { throw new Error('unused') }) as unknown as SnapshotSelectorHook<SessionListState>,
useSessions: (() => { throw new Error('unused') }) as SnapshotSelectorHook<SessionListState>,
useSessionRetainInfo: () => undefined,
useResource,
useSessionStatus: bindSnapshotSelector(
@@ -745,7 +745,7 @@ describe('plugin registration', () => {
3,
(path) => { opened.push(path) },
)
const service = (ctx as unknown as { get(name: string): ChatFileMentions | undefined }).get('chatFileMentions')
const service = (ctx as { get(name: string): ChatFileMentions | undefined }).get('chatFileMentions')
const mentions = service?.forClosing(owner, SessionId('viewed-session'))
expect(mentions?.resolve('report.html')?.label).toBe('Open site/report.html in sidebar')
mentions?.resolve('report.html')?.open()
@@ -813,7 +813,7 @@ describe('plugin registration', () => {
expect(ctx.slots.entries('sidebar.right.pane.tab')).toHaveLength(0)
expect(registered).toBeUndefined()
// Fiber teardown retracts the service: the consumer's ctx.get sees the off state.
expect((ctx as unknown as { get(name: string): unknown }).get('chatFileMentions')).toBeUndefined()
expect((ctx as { get(name: string): unknown }).get('chatFileMentions')).toBeUndefined()
})
})
@@ -36,7 +36,7 @@ function mount(overrides: Partial<FeedbackDialogState> = {}) {
}
const useDialog = (<T,>(select: (v: FeedbackDialogState) => T): T =>
useSyncExternalStore(() => () => {}, () => select(state))) as never
const props = { useDialog, ...verbs, t } as unknown as Parameters<typeof FeedbackDialog>[0]
const props = { useDialog, ...verbs, t } as Parameters<typeof FeedbackDialog>[0]
return { ...render(<FeedbackDialog {...props} />), ...verbs }
}
@@ -61,7 +61,7 @@ export function permissionDefaultOf(view: SettingsNamespaceView, schema: Setting
? (node.list as SchemaNode[] | undefined) ?? []
: [node]
const options = rawChoices.flatMap((candidate) => {
const choice = candidate as unknown as ConstChoice
const choice = candidate as ConstChoice
if (choice.type !== 'const' || typeof choice.value !== 'string') return []
const described = choice.meta?.description
return [{
@@ -176,14 +176,14 @@ describe('plan entry points and document', () => {
fireEvent.click(screen.getByRole('button', { name: 'Open plan in sidebar' }))
expect(openReview).toHaveBeenCalledTimes(2)
const revised = { plan: '# Revised', ...(logged ? { callId: 'call:2' } : {}) }
second.rerender(<PlanReviewOpen {...{ ...props, review: revised, requestKey: 'question:2' } as unknown as Parameters<typeof PlanReviewOpen>[0]} />)
second.rerender(<PlanReviewOpen {...{ ...props, review: revised, requestKey: 'question:2' } as Parameters<typeof PlanReviewOpen>[0]} />)
expect(openReview).toHaveBeenLastCalledWith(revised, 'question:2')
expect(openReview).toHaveBeenCalledTimes(3)
second.unmount()
const other = createPlanReviewStore().create()
render(<PlanReviewOpen {...{ ...props, actions: other.actions,
useStore: (select: (state: ReturnType<typeof other.getSnapshot>) => unknown) => select(other.getSnapshot()),
} as unknown as Parameters<typeof PlanReviewOpen>[0]} />)
} as Parameters<typeof PlanReviewOpen>[0]} />)
expect(openReview).toHaveBeenCalledTimes(4)
})
it('renders temporary Markdown and reports expired navigation after reload', () => {
@@ -487,7 +487,7 @@ export class SlotRegistry extends Service {
// Core write first: all load-time validation (undeclared target,
// duplicate declaration, kind conflicts, cross-scope handle) throws
// there before this layer commits anything.
const dispose = (this._core as unknown as ErasedCore).register(erased, component)
const dispose = (this._core as ErasedCore).register(erased, component)
if (store !== undefined) {
const scope = (this._core.specDynamic(options.name) as SlotSpec<SlotEntryDef>).scope
this._acquire(store, scope)
@@ -507,7 +507,7 @@ export class SlotRegistry extends Service {
...options,
...(registrant === undefined ? {} : { registrant }),
}
const dispose = (this._core as unknown as ErasedFactoryCore).registerFactory(erased, component)
const dispose = (this._core as ErasedFactoryCore).registerFactory(erased, component)
const definition = this._core.factory(options.name)
if (definition === undefined) throw new Error(`slot factory "${options.name}" disappeared during registration`)
if (definition.store !== undefined && typeof definition.store !== 'function') {
@@ -551,7 +551,7 @@ export class SlotRegistry extends Service {
storeOf: (entry, scopeBinding) =>
entry.store === undefined
? undefined
: this.resolveStore(entry.store as unknown as EngineStoreHandle, scopeBinding),
: this.resolveStore(entry.store as EngineStoreHandle, scopeBinding),
factoryStoreOf: (definition, scopeBinding, occurrence) =>
this.resolveFactoryStore(definition, scopeBinding, occurrence),
retainFactoryOccurrence: (definition, occurrence) =>
@@ -346,8 +346,8 @@ describe('Factory rendering', () => {
const view = runtime.renderRoot()
expect(view.container.textContent).toBe('selected')
if (retainedRender === undefined || retainedChain === undefined) throw new Error('Factory child bindings are missing')
const render = retainedRender as unknown as (key: string, owner: object) => ReactNode
const renderChain = retainedChain as unknown as (key: string, owner: object) => ReactNode
const render = retainedRender as (key: string, owner: object) => ReactNode
const renderChain = retainedChain as (key: string, owner: object) => ReactNode
expect(() => render('renderer.factory.chain', {})).toThrow(/use renderSlotChain/)
expect(() => renderChain('renderer.factory.child', {})).toThrow(/not 'chain'/)
dispose()
@@ -28,7 +28,7 @@ describe('renderer slots/changed invariant', () => {
// A real registration bumps the version first and re-emits through
// onMutate — the audit sees version > 0 and stays quiet. (Erased call:
// the typed register face rides the wave-1 ui-slots types.)
const slots = ctx.slots as unknown as { register(options: object, component: unknown): () => void }
const slots = ctx.slots as { register(options: object, component: unknown): () => void }
expect(() => slots.register({ name: 'root' }, () => null)).not.toThrow()
})
@@ -50,7 +50,7 @@ async function boot(): Promise<Bench> {
// Service accessor (ctx.get reads the reflect store, which Service-class
// plugins do not write; the accessor is the product path).
const svc = ctx.slots
return { ctx, svc, erased: svc as unknown as ErasedService }
return { ctx, svc, erased: svc }
}
/** Engine-shaped instance stub (bare-source form: subscribe/getSnapshot + baked actions + clearPersisted). */
@@ -910,7 +910,7 @@ describe('entry-unload cascade', () => {
name: 'occupant',
inject: ['slots'],
apply: (pluginCtx: Context) => {
;(pluginCtx.slots as unknown as ErasedService).register({ name: 't.host' }, C)
;(pluginCtx.slots as ErasedService).register({ name: 't.host' }, C)
},
})
await fiber.await()
@@ -723,12 +723,13 @@ describe('ui-session apply', () => {
apply(ctx)
expect(ctx.uiSession).toBeInstanceOf(UiSession)
const retainInfoMatcher: unknown = expect.any(Function)
expect(slots.provideRoot).toHaveBeenCalledWith({
hooks: {
sessions: bench.sessions.list,
sessionStatus: ctx.uiSession.sessionStatus,
},
keyedHooks: { sessionRetainInfo: expect.any(Function) as unknown },
keyedHooks: { sessionRetainInfo: retainInfoMatcher },
})
expect(slots.installScope).toHaveBeenCalledWith('session', ctx.uiSession.adapter)
const root = slots.provideRoot.mock.calls[0]![0] as RootStandardSourceContribution
@@ -230,13 +230,13 @@ describe('pushed invalidations', () => {
store: { getSnapshot: () => ({ status: 'ready' }) },
load: () => { loads.push(1); return Promise.resolve() },
}
refreshIfLoaded(controller as unknown as import('../src/client/store.ts').ModelsSettingsStore)
refreshIfLoaded(controller as import('../src/client/store.ts').ModelsSettingsStore)
expect(loads).toHaveLength(1)
const idle = {
store: { getSnapshot: () => ({ status: 'idle' }) },
load: () => { loads.push(2); return Promise.resolve() },
}
refreshIfLoaded(idle as unknown as import('../src/client/store.ts').ModelsSettingsStore)
refreshIfLoaded(idle as import('../src/client/store.ts').ModelsSettingsStore)
expect(loads).toHaveLength(1)
})
@@ -181,7 +181,7 @@ interface MutateCall {
/** The latest interrogation payload; fails the case when nothing was asked. */
function lastProbe(discover: ReturnType<typeof vi.fn>): unknown {
const call = (discover.mock.calls as unknown as [string, Record<string, unknown>][]).at(-1)
const call = (discover.mock.calls as [string, Record<string, unknown>][]).at(-1)
if (call === undefined) throw new Error('no interrogation was recorded')
return { settingsNs: call[0], ...call[1] }
}
@@ -59,7 +59,7 @@ export class SettingsSchemaService extends Service {
*/
validate(schema: SchemaNode, draft: unknown): string | undefined {
try {
;(schema as unknown as (value: unknown) => unknown)(draft)
;(schema as (value: unknown) => unknown)(draft)
return undefined
} catch (error) {
return error instanceof Error ? error.message : String(error)
@@ -174,8 +174,9 @@ describe('document toolbar', () => {
const renderSlot = vi.fn(() => null)
view.rerender(<TextPreview {...h.props()} useDocumentPreviews={selector => selector([{ ...binary, loading: 'renderer' }])} renderSlot={renderSlot} />)
expect(view.container.textContent).not.toContain('previous reader content')
const rendererContentMatcher: unknown = expect.objectContaining({ kind: 'renderer' })
expect(renderSlot).toHaveBeenCalledWith('sidebar.right.tab.document', expect.objectContaining({
content: expect.objectContaining({ kind: 'renderer' }) as unknown,
content: rendererContentMatcher,
}), expect.any(Object))
expect(h.instance.getSnapshot().byTab[TAB_ID]?.complete).toBeUndefined()
expect(h.bytes).not.toHaveBeenCalled()
@@ -28,7 +28,7 @@ function firstLine(text: string): string {
/** Skill names are the only call argument the compact row presents. */
function skillName(argsRaw: string, callId: string): string {
try {
const parsed = JSON.parse(argsRaw) as unknown
const parsed: unknown = JSON.parse(argsRaw)
if (typeof parsed === 'object' && parsed !== null) {
const name = (parsed as Record<string, unknown>).name
if (typeof name === 'string' && name !== '') return firstLine(name)
@@ -86,7 +86,7 @@ describe('lifecycle cascade (one axis)', () => {
core.onMutate((key) => {
if (key === 'test.single') observed.push(core.specDynamic('test.session'))
})
const registerFactory = core.registerFactory as unknown as (
const registerFactory = core.registerFactory as (
options: object,
component: unknown,
) => () => void
@@ -16,7 +16,7 @@ function checkpointId(
event: Parameters<ConversationNodeDefinition['match']>[0],
): string | undefined {
if (event.type !== 'user/message') return undefined
const source = event.data.source as unknown as {
const source = event.data.source as {
readonly kind?: unknown
readonly plugin?: unknown
readonly compactionId?: unknown
@@ -457,7 +457,7 @@ describe('plugin registration', () => {
expect(resolveSource(binding)).toBe(source)
expect(resolveSource(binding)).toBe(source)
const optionalTrajectory = b.trajectoryStore as unknown as {
const optionalTrajectory = b.trajectoryStore as {
set(value: TrajectorySnapshot | undefined): void
}
optionalTrajectory.set(undefined)
@@ -15,7 +15,7 @@ const win = globalThis as DshWindow
const transportGlobal = globalThis as {
__DSH_TRANSPORT__?: { loadBundle(url: string): Promise<void> }
}
const moduleFace = modulesClient as unknown as Record<string, unknown>
const moduleFace = modulesClient as Record<string, unknown>
afterEach(() => {
vi.restoreAllMocks()
@@ -86,7 +86,7 @@ describe('real Loader composition', () => {
expect(unloaded).toEqual([])
expect(loaded.get('toolResultPruner')).toBeInstanceOf(ToolResultPruner)
expect(loaded.get('compaction')).toBeInstanceOf(BasicCompactionEngine)
expect((loaded.compaction as unknown as BasicCompactionEngine).config).toMatchObject({
expect((loaded.compaction as BasicCompactionEngine).config).toMatchObject({
thresholdRatio: 0.5,
headroomTokens: 4000,
modelPolicies: [{ provider: 'mock', model: 'small', headroomTokens: 0, maxTokens: 32 }],
+1 -1
View File
@@ -207,7 +207,7 @@ describe('scope parent chain', () => {
agentScope.ctx.on('probe/event' as never, ((): void => { seen.push('agent') }) as never)
otherScope.ctx.on('probe/event' as never, ((): void => { seen.push('other') }) as never)
const emit = ctx as unknown as { emit: (carrier: object, type: string) => void }
const emit = ctx as { emit: (carrier: object, type: string) => void }
// Dispatch at the AGENT key: its own tag and its ancestor's admit; a
// sibling root does not.
emit.emit(scopeTarget({}, agent), 'probe/event')
+1 -1
View File
@@ -14,7 +14,7 @@ interface SessionEvent {
function interruptedTurnClosers(events: readonly SessionEvent[]): LogicalSessionEvent[] {
for (const event of events) SessionSeq(event.seq)
return repairInterruptedTurn(events as unknown as readonly LogicalSessionEvent[])
return repairInterruptedTurn(events as readonly LogicalSessionEvent[])
}
function openTurnClosers(events: readonly SessionEvent[], cause: OpenTurnCloseCause): LogicalSessionEvent[] {
+4 -4
View File
@@ -270,14 +270,14 @@ describe('Session', () => {
data: { header: { config: { provider: 'mock', model: 'model' } }, reason: 'initial' },
} as const
for (const reason of ['fallback', 'unknown', null]) {
const invalid = structuredClone(base) as unknown as SessionEvent
const invalid = structuredClone(base) as SessionEvent
if (invalid.type !== 'request/header') throw new Error('test fixture must be a request header')
invalid.data.reason = reason as never
expect(() => Session.create(SessionId('invalid-header-reason'), [invalid]))
.toThrow('seed request/header at index 0 has an invalid reason')
}
for (const startsSeries of [false, 1, 'true']) {
const invalid = structuredClone(base) as unknown as SessionEvent
const invalid = structuredClone(base) as SessionEvent
if (invalid.type !== 'request/header') throw new Error('test fixture must be a request header')
invalid.data.startsSeries = startsSeries as never
expect(() => Session.create(SessionId('invalid-series-marker'), [invalid]))
@@ -543,7 +543,7 @@ describe('Session', () => {
.toEqual(valid)
for (const reasoningEffort of ['', 1]) {
const invalid = structuredClone(valid) as unknown as SessionEvent
const invalid = structuredClone(valid) as SessionEvent
if (invalid.type !== 'request/header') throw new Error('test fixture must be a request header')
const config = invalid.data.header.config as unknown as Record<string, unknown>
config.reasoningEffort = reasoningEffort
@@ -578,7 +578,7 @@ describe('Session', () => {
{ maxTokens: false },
{ reasoningEffort: true },
]) {
const invalid = structuredClone(valid) as unknown as SessionEvent
const invalid = structuredClone(valid) as SessionEvent
if (invalid.type !== 'request/header') throw new Error('test fixture must be a request header')
invalid.data.header.adapterDefaults = adapterDefaults as never
expect(() => Session.create(SessionId('invalid-adapter-defaults'), [invalid]))
+2 -2
View File
@@ -575,11 +575,11 @@ export function defineTool<const S extends ParameterSchemaSpec, const O extends
output: {
schema: outputSchema,
render(args: unknown, value: JsonValue): ContentBlock[] {
return userRender(args as InferArgs<S>, value as unknown as InferValue<NoInfer<O>>)
return userRender(args as InferArgs<S>, value as InferValue<NoInfer<O>>)
},
...userPresentationMeta !== undefined ? {
presentationMeta(args: unknown, value: JsonValue): JsonValue {
return userPresentationMeta(args as InferArgs<S>, value as unknown as InferValue<NoInfer<O>>)
return userPresentationMeta(args as InferArgs<S>, value as InferValue<NoInfer<O>>)
},
} : {},
},
@@ -231,13 +231,13 @@ describe('the enforced raw JSON Schema subset', () => {
})
it('accepts lossless annotation containers from another JavaScript realm', () => {
const schema = runInNewContext(`({
const schema: unknown = runInNewContext(`({
type: 'object',
properties: { value: { type: 'string', enum: ['x'] } },
required: ['value'],
default: { x: 1 },
examples: [[{ ok: true }]],
})`) as unknown
})`)
expect(() => { assertSupportedJsonSchema(schema) }).not.toThrow()
})
+2 -2
View File
@@ -351,10 +351,10 @@ describe('ToolRuntime', () => {
output: {
schema: { type: 'string' },
render: () => projector === 'render'
? hostile as unknown as ContentBlock[]
? hostile as ContentBlock[]
: [{ type: 'text', text: 'ok' }],
presentationMeta: () => projector === 'presentationMeta'
? hostile as unknown as JsonValue
? hostile as JsonValue
: null,
},
execute: async () => 'ok',
@@ -156,7 +156,7 @@ export class ClientInspectorSource extends InspectorSourceConnection {
if (new TextEncoder().encode(event.data).byteLength > this.bootstrap.maxFrameBytes) {
throw new Error(`inspector protocol: Worker frame exceeds ${String(this.bootstrap.maxFrameBytes)} bytes`)
}
const value = JSON.parse(event.data) as unknown
const value: unknown = JSON.parse(event.data)
if (this.queries.receive(value)) return
const frame = parseWorkerSourceFrame(value)
if (frame.t !== 'source/rejected'
@@ -125,8 +125,8 @@ export class ClientConsoleObserver {
}
private readonly onError = (event: Event): void => {
const error = Reflect.get(event, 'error') as unknown
const message = Reflect.get(event, 'message') as unknown
const error: unknown = Reflect.get(event, 'error')
const message: unknown = Reflect.get(event, 'message')
this.captureException(error ?? new Error(typeof message === 'string' ? message : 'Client error'))
}
@@ -166,11 +166,11 @@ export class ClientConsoleObserver {
}
function addGlobalListener(type: string, listener: EventListener): void {
const add = Reflect.get(globalThis, 'addEventListener') as unknown
const add: unknown = Reflect.get(globalThis, 'addEventListener')
if (typeof add === 'function') Reflect.apply(add, globalThis, [type, listener])
}
function removeGlobalListener(type: string, listener: EventListener): void {
const remove = Reflect.get(globalThis, 'removeEventListener') as unknown
const remove: unknown = Reflect.get(globalThis, 'removeEventListener')
if (typeof remove === 'function') Reflect.apply(remove, globalThis, [type, listener])
}
@@ -212,7 +212,7 @@ function serializeByValue(value: unknown): InspectorJsonValue {
throw new ClientRuntimeExecutionError('unsupported', `Value cannot be returned by value: ${renderError(error)}`)
}
if (typeof serialized !== 'string') throw new ClientRuntimeExecutionError('unsupported', 'Value cannot be returned by value')
const result = JSON.parse(serialized) as unknown
const result: unknown = JSON.parse(serialized)
if (!isJsonValue(result)) throw new ClientRuntimeExecutionError('unsupported', 'Value is outside the JSON value set')
return result
}
@@ -365,7 +365,7 @@ class ClientRuntimeSession {
const args = (command.arguments ?? []).map(argument => this.resolveArgument(argument))
let value: unknown
try {
const fn = globalThis.eval(`(${command.functionDeclaration}\n)`) as unknown
const fn: unknown = globalThis.eval(`(${command.functionDeclaration}\n)`)
if (typeof fn !== 'function') throw new TypeError('functionDeclaration did not evaluate to a function')
value = Reflect.apply(fn, receiver, args)
if (command.awaitPromise === true) value = await awaitWithCancellation(value, signal)
@@ -460,9 +460,9 @@ function parseUnserializable(value: string): unknown {
}
function clientUrl(): { readonly url?: string } {
const location = Reflect.get(globalThis, 'location') as unknown
const location: unknown = Reflect.get(globalThis, 'location')
if (typeof location !== 'object' || location === null) return {}
const href = Reflect.get(location, 'href') as unknown
const href: unknown = Reflect.get(location, 'href')
return typeof href === 'string' ? { url: href } : {}
}
@@ -172,9 +172,9 @@ export class ClientSourceCatalog {
* @returns A lazy catalog, or `undefined` outside the assembled web application.
*/
export function discoverInspectorClientSourceCatalog(): ClientSourceCatalog | undefined {
const graph = Reflect.get(globalThis, '__DSH_BOOT__') as unknown
const graph: unknown = Reflect.get(globalThis, '__DSH_BOOT__')
if (typeof graph !== 'object' || graph === null) return undefined
const entries = Reflect.get(graph, 'entries') as unknown
const entries: unknown = Reflect.get(graph, 'entries')
if (!Array.isArray(entries)) return undefined
const row = entries.find((value) => {
if (typeof value !== 'object' || value === null) return false
@@ -208,14 +208,14 @@ async function fetchText(url: string): Promise<string> {
* `baseURI`, else the location URL, else undefined outside a browser.
*/
function documentBase(): string | undefined {
const document = Reflect.get(globalThis, 'document') as unknown
const document: unknown = Reflect.get(globalThis, 'document')
if (typeof document === 'object' && document !== null) {
const baseURI = Reflect.get(document, 'baseURI') as unknown
const baseURI: unknown = Reflect.get(document, 'baseURI')
if (typeof baseURI === 'string' && baseURI !== '') return baseURI
}
const location = Reflect.get(globalThis, 'location') as unknown
const location: unknown = Reflect.get(globalThis, 'location')
if (typeof location !== 'object' || location === null) return undefined
const href = Reflect.get(location, 'href') as unknown
const href: unknown = Reflect.get(location, 'href')
return typeof href === 'string' ? href : undefined
}
@@ -119,8 +119,8 @@ function tryClaimSourceId(
}
function clientOrigin(): string {
const location = Reflect.get(globalThis, 'location') as unknown
const location: unknown = Reflect.get(globalThis, 'location')
if (typeof location !== 'object' || location === null) return ''
const origin = Reflect.get(location, 'origin') as unknown
const origin: unknown = Reflect.get(location, 'origin')
return typeof origin === 'string' ? origin : ''
}
@@ -168,7 +168,7 @@ export function identifyRealmObject(value: unknown): InspectorObjectReference |
function registries(): Map<InspectorObjectRegistryId, RealmObjectRegistry> {
const key = Symbol.for(REGISTRIES_SYMBOL)
const existing = Reflect.get(globalThis, key) as unknown
const existing: unknown = Reflect.get(globalThis, key)
if (existing instanceof Map) return existing as Map<InspectorObjectRegistryId, RealmObjectRegistry>
const value = new Map<InspectorObjectRegistryId, RealmObjectRegistry>()
Reflect.set(globalThis, key, value)
@@ -188,7 +188,7 @@ export class InspectorEndpoint {
this.ingestConnections.set(socket, connection)
socket.on('message', (data) => {
try {
const value = JSON.parse(rawText(data)) as unknown
const value: unknown = JSON.parse(rawText(data))
if (!queryPeer.receive(value)) this.sources.receive(connection, value)
} catch {
connection.close(1008, 'source frame must be JSON')
@@ -9,7 +9,7 @@ import { startInspectorWorker } from './server.ts'
if (parentPort === null) throw new Error('experimental inspector: Worker entry loaded on the main thread')
const controlPort = parentPort
const bootData = workerData as unknown
const bootData: unknown = workerData
if (!isPlainObject(bootData)
|| !(bootData.hostSourcePort instanceof MessagePort)) {
throw new Error('experimental inspector: invalid Worker boot data')
@@ -19,7 +19,7 @@ interface DynamicInspectorSession {
/** Connection-local carrier for requests and notifications from the Host V8 inspector. */
export class HostInspectorSession {
private readonly session = new Session() as unknown as DynamicInspectorSession
private readonly session = new Session() as DynamicInspectorSession
private readonly listeners = new Set<(message: HostInspectorNotification) => void>()
private connected = false
private failure: string | undefined
@@ -291,7 +291,7 @@ describe('Cordis tree inspection', () => {
const runtimeFiber = fiber.ctx.fiber
const uidDescriptor = Object.getOwnPropertyDescriptor(runtimeFiber, 'uid')
Object.defineProperty(runtimeFiber, 'uid', { ...uidDescriptor, value: null })
const hooks = root.events._hooks as unknown as Record<PropertyKey, Array<{ ctx: unknown }> | undefined>
const hooks = root.events._hooks as Record<PropertyKey, Array<{ ctx: unknown }> | undefined>
const probe = Symbol('inspector-collector-probe')
const empty = Symbol('inspector-collector-empty')
const shadow = Object.create(root) as object
@@ -27,7 +27,7 @@ describe('Inspector JSON values', () => {
cyclic.self = cyclic
const arrayWithField = [1]
Reflect.set(arrayWithField, 'extra', true)
const inheritedArray = Object.setPrototypeOf([1], null) as unknown
const inheritedArray: unknown = Object.setPrototypeOf([1], null)
const symbolObject = { [Symbol('field')]: true }
const hidden = {}
Object.defineProperty(hidden, 'value', { value: 1, enumerable: false })
@@ -1986,7 +1986,7 @@ export class PythonPtcRuntime extends PtcRuntime {
// that reads fd 3 continuously, so arrival order was never observable,
// and the bindings themselves still run concurrently. Only the host's peak
// memory and the flush timing change.
const replyQueue: ReplyMessage[] = []
const replyQueue: (ReplyMessage | undefined)[] = []
// Replies queued but not yet written, tracked separately from
// `replyQueue.length`: the drain loop clears consumed slots to `undefined`
// but does not shrink the array until it finishes, so `length` counts
@@ -2050,7 +2050,7 @@ export class PythonPtcRuntime extends PtcRuntime {
// in `replyQueue` for the whole busy period, making host memory grow
// with cumulative processing rather than the current backlog.
const payload = replyQueue[head] as ReplyMessage
replyQueue[head] = undefined as unknown as ReplyMessage
replyQueue[head] = undefined
head += 1
pendingReplies -= 1
// Compact the consumed prefix once it reaches the backlog bound:
@@ -297,7 +297,7 @@ describe('checkDoneValue', () => {
it('emits exact digits for beyond-safe integral doubles', () => {
// String(2**60) prints the ROUNDED ...847000; echoing that to the child
// would change the integer. BigInt digits give the exact ...846976.
const v = JSON.parse('[1152921504606846976]') as unknown
const v: unknown = JSON.parse('[1152921504606846976]')
expect(encodeJsonPlain(v)).toBe('[1152921504606846976]')
expect(checkDoneValue(v, 100)).toEqual({ ok: true, bytes: Buffer.byteLength('[1152921504606846976]', 'utf8') })
})
@@ -1260,7 +1260,7 @@ describe('PythonPtcRuntime — programs and bindings', () => {
cyclic.self = cyclic
const error = new Error('placeholder')
// Writable per spec, so no cast is needed to install a non-string.
;(error as unknown as { message: unknown }).message = cyclic
;(error as { message: unknown }).message = cyclic
throw error
},
}),
@@ -1289,7 +1289,7 @@ describe('PythonPtcRuntime — programs and bindings', () => {
bindings: tools({
absent: async () => {
const error = new Error('placeholder')
;(error as unknown as { message: unknown }).message = undefined
;(error as { message: unknown }).message = undefined
throw error
},
}),
@@ -215,7 +215,7 @@ export function spawn(
if (typeof program !== 'string' || program === '') {
// Node refuses a non-string command with this error rather than starting
// anything; a caller whose own lookup produced nothing reads why.
const invalid = new TypeError(`The "file" argument must be a non-empty string. Received ${program as unknown as string}`) as NodeJS.ErrnoException
const invalid = new TypeError(`The "file" argument must be a non-empty string. Received ${program as string}`) as NodeJS.ErrnoException
invalid.code = 'ERR_INVALID_ARG_TYPE'
throw invalid
}
@@ -283,12 +283,12 @@ type RefTimer = { ref?: () => unknown; unref?: () => unknown }
/** Browser timers are numeric; Node timers expose optional liveness methods. */
const timerRef = (timer: ReturnType<typeof setTimeout>): void => {
;(timer as unknown as RefTimer).ref?.()
;(timer as RefTimer).ref?.()
}
/** Browser timers are numeric; Node timers expose optional liveness methods. */
const timerUnref = (timer: ReturnType<typeof setTimeout>): void => {
;(timer as unknown as RefTimer).unref?.()
;(timer as RefTimer).unref?.()
}
const statWatchers = new Map<string, StatWatcher>()
@@ -28,7 +28,7 @@ const {
Duplex, PassThrough, Readable, Stream: StreamBase, Transform, Writable,
addAbortSignal, compose, destroy, finished, isDisturbed, isErrored, isReadable, pipeline, promises,
} = nodeStream
const streamStatics = StreamBase as unknown as StreamStatics
const streamStatics = StreamBase as StreamStatics
const {
getDefaultHighWaterMark, isDestroyed, isWritable, setDefaultHighWaterMark,
} = streamStatics
@@ -31,7 +31,7 @@ export function callbackify<A extends unknown[], R>(
): (...args: [...A, (error: unknown, value?: R) => void]) => void {
return (...args) => {
const callback = args.at(-1) as (error: unknown, value?: R) => void
const rest = args.slice(0, -1) as unknown as A
const rest = args.slice(0, -1) as A
fn(...rest).then((value) => { callback(null, value) }, (error: unknown) => { callback(error) })
}
}
@@ -53,11 +53,11 @@ const wrapClear = (clear: Clear): ((handle?: unknown) => void) =>
/** Replace the worker's timer globals with the Node-shaped wrappers. */
export function installTimerGlobals(): void {
const scope = globalThis as unknown as Record<string, unknown>
const setTimeoutRaw = globalThis.setTimeout.bind(globalThis) as unknown as Scheduler
const setIntervalRaw = globalThis.setInterval.bind(globalThis) as unknown as Scheduler
const clearTimeoutRaw = globalThis.clearTimeout.bind(globalThis) as unknown as Clear
const clearIntervalRaw = globalThis.clearInterval.bind(globalThis) as unknown as Clear
const scope = globalThis as Record<string, unknown>
const setTimeoutRaw = globalThis.setTimeout.bind(globalThis) as Scheduler
const setIntervalRaw = globalThis.setInterval.bind(globalThis) as Scheduler
const clearTimeoutRaw = globalThis.clearTimeout.bind(globalThis) as Clear
const clearIntervalRaw = globalThis.clearInterval.bind(globalThis) as Clear
scope.setTimeout = wrapScheduler(setTimeoutRaw)
scope.setInterval = wrapScheduler(setIntervalRaw)
scope.clearTimeout = wrapClear(clearTimeoutRaw)
@@ -84,7 +84,7 @@ afterEach(async () => {
function onceEvent<T>(watcher: import('chokidar').FSWatcher, event: string): Promise<T> {
return new Promise<T>((resolve, reject) => {
const timeout = setTimeout(() => { reject(new Error(`timed out waiting for chokidar ${event}`)) }, 2_000)
const emitter = watcher as unknown as {
const emitter = watcher as {
once(name: string, listener: (...args: unknown[]) => void): void
}
emitter.once(event, (...args: unknown[]) => {
@@ -301,7 +301,7 @@ describe('file streams', () => {
once(event: string, listener: (...args: unknown[]) => void): unknown
destroy(): unknown
}
const streams = [nativeRead, nativeWrite, workerRead, workerWrite] as unknown as CloseableStream[]
const streams = [nativeRead, nativeWrite, workerRead, workerWrite] as CloseableStream[]
const closed = streams.map(stream => new Promise<void>((resolve) => {
stream.once('error', () => {})
stream.once('close', () => { resolve() })
@@ -96,7 +96,7 @@ function stubWorker(): {
const { worker, sent, deliver } = stubWorker()
const tunnel = new WorkerTunnel(worker)
const response = tunnel.fetch('/api/session.list', { method: 'POST', body: '{"a":1}' })
const request = sent[0] as unknown as { t: string; id: number; method: string; url: string; body: ArrayBuffer }
const request = sent[0] as { t: string; id: number; method: string; url: string; body: ArrayBuffer }
check('the request frame carries method and absolute url', [request.t, request.id, request.method, request.url],
['req', 1, 'POST', 'http://localhost:4173/api/session.list'])
check('the request body travels as bytes', new TextDecoder().decode(request.body), '{"a":1}')
@@ -71,10 +71,10 @@ function denyContext(value: unknown, service: string, env: DynamicCordisGuardEnv
function guardedService(service: object, name: string, env: DynamicCordisGuardEnv): unknown {
return new Proxy(service, {
get(target, prop) {
const value = Reflect.get(target, prop, target) as unknown
const value: unknown = Reflect.get(target, prop, target)
if (typeof value !== 'function') return denyContext(value, name, env)
return (...args: unknown[]): unknown => {
const result = Reflect.apply(value, target, args) as unknown
const result: unknown = Reflect.apply(value, target, args)
if (result instanceof Promise) return result.then(resolved => denyContext(resolved, name, env))
return denyContext(result, name, env)
}
@@ -96,7 +96,7 @@ interface ErasedSlotOptions {
function guardedSlots(slots: SlotRegistry, env: DynamicCordisGuardEnv): unknown {
return new Proxy(slots, {
get(target, prop) {
const value = Reflect.get(target, prop, target) as unknown
const value: unknown = Reflect.get(target, prop, target)
if (prop !== 'register' && prop !== 'registerFactory') {
if (typeof value !== 'function') return denyContext(value, 'slots', env)
return (...args: unknown[]): unknown => denyContext(Reflect.apply(value, target, args), 'slots', env)
@@ -130,7 +130,7 @@ function guardedSlots(slots: SlotRegistry, env: DynamicCordisGuardEnv): unknown
priority = env.allocatePriority()
options.priority = priority
}
const register = Reflect.get(target, 'register', target) as unknown as (opts: object, comp: unknown) => () => void
const register = Reflect.get(target, 'register', target) as (opts: object, comp: unknown) => () => void
const dispose = register.call(target, options, component)
env.ledger.push({ slot, priority })
// After the registry accepted it: a rejected registration seats no entry,
@@ -155,10 +155,10 @@ function guardedTheme(theme: ThemeRuntime, env: DynamicCordisGuardEnv, ctx: Cont
return new Proxy(theme, {
get(target, prop) {
if (prop !== 'overrideTokens') {
const value = Reflect.get(target, prop, target) as unknown
const value: unknown = Reflect.get(target, prop, target)
if (typeof value !== 'function') return denyContext(value, 'theme', env)
return (...args: unknown[]): unknown => {
const result = Reflect.apply(value, target, args) as unknown
const result: unknown = Reflect.apply(value, target, args)
if (result instanceof Promise) return result.then(resolved => denyContext(resolved, 'theme', env))
return denyContext(result, 'theme', env)
}
@@ -235,7 +235,7 @@ export function dynamicCordisContext(ctx: Context, env: DynamicCordisGuardEnv):
has: (_target, prop) => prop === 'get'
|| (typeof prop === 'string'
&& ((CTX_VERBS.has(prop) && (!TIMER_VERBS.has(prop) || declared.has('timer'))) || declared.has(prop))),
}) as unknown as Context
}) as Context
}
function rejectGuard(env: DynamicCordisGuardEnv, message: string): never {
@@ -126,7 +126,7 @@ describe('facade surface', () => {
expect('slots' in bench.facade).toBe(true)
expect('registry' in bench.facade).toBe(false)
expect(Symbol.iterator in bench.facade).toBe(false)
expect((bench.facade as unknown as Record<symbol, unknown>)[Symbol.iterator]).toBeUndefined()
expect((bench.facade as Record<symbol, unknown>)[Symbol.iterator]).toBeUndefined()
expect(() => { bench.facade.slots = 1 }).toThrow(/dynamic ctx is read-only/)
})
@@ -11,7 +11,7 @@ describe('Client inspect providers', () => {
const ctx = new Context()
const fiber = ctx.plugin(SlotRegistry)
await fiber
const slots = ctx.slots as unknown as {
const slots = ctx.slots as {
registerFactory(options: object, component: unknown): () => void
}
slots.registerFactory({
@@ -564,7 +564,7 @@ export function sandboxDefineTool(options: unknown): ToolDefinition {
const rawExecute = options.execute as (args: unknown, exec: unknown) => Promise<unknown>
const rawRender = output.render as (args: unknown, value: unknown) => unknown
const rawPresentationMeta = output.presentationMeta as ((args: unknown, value: unknown) => unknown) | undefined
const erasedDefineTool = defineTool as unknown as (definition: unknown) => ToolDefinition
const erasedDefineTool = defineTool as (definition: unknown) => ToolDefinition
const tool = erasedDefineTool({
...options,
parameters: normalized.spec,
@@ -685,10 +685,10 @@ function denyContext(value: unknown, service: string, reportFailure: (error: Err
function guardedService(service: object, name: string, reportFailure: (error: Error) => void): unknown {
return new Proxy(service, {
get(target, prop) {
const value = Reflect.get(target, prop, target) as unknown
const value: unknown = Reflect.get(target, prop, target)
if (typeof value !== 'function') return denyContext(value, name, reportFailure)
return (...args: unknown[]): unknown => {
const result = Reflect.apply(value, target, args) as unknown
const result: unknown = Reflect.apply(value, target, args)
if (result instanceof Promise) return result.then(v => denyContext(v, name, reportFailure))
return denyContext(result, name, reportFailure)
}
@@ -776,7 +776,7 @@ function sandboxContext(ctx: Context, reportFailure: (error: Error) => void): Co
has: (_target, prop) => prop === 'tools' || prop === 'get'
|| (typeof prop === 'string'
&& ((CTX_VERBS.has(prop) && (!TIMER_VERBS.has(prop) || declared.has('timer'))) || declared.has(prop))),
}) as unknown as Context
}) as Context
/* jscpd:ignore-end */
}
@@ -60,7 +60,7 @@ function objectAt(source: Record<string, unknown>, key: string): Record<string,
function parseArgs(argsRaw: string): Record<string, unknown> | null {
try {
const parsed = JSON.parse(argsRaw) as unknown
const parsed: unknown = JSON.parse(argsRaw)
return typeof parsed === 'object' && parsed !== null ? parsed as Record<string, unknown> : null
} catch {
// Running calls can expose a truncated JSON prefix.
@@ -92,7 +92,7 @@ const IID_IFILE_OPEN_DIALOG = guidBytes('d57c7288-d4ad-4768-be02-9d969532d960')
* @returns the bindings {@link runFolderDialog} sequences against.
*/
export async function loadWin32DialogBindings(): Promise<Win32DialogBindings> {
const koffi = (await import('koffi')).default as unknown as Koffi
const koffi = (await import('koffi')).default as Koffi
const ole32 = koffi.load('ole32.dll')
const user32 = koffi.load('user32.dll')
const kernel32 = koffi.load('kernel32.dll')
@@ -189,7 +189,7 @@ export async function loadWin32DialogBindings(): Promise<Win32DialogBindings> {
* @param threadId - the dialog thread's native id (from the `showing` notice).
*/
export async function closeThreadWindows(threadId: number): Promise<void> {
const koffi = (await import('koffi')).default as unknown as Koffi
const koffi = (await import('koffi')).default as Koffi
const user32 = koffi.load('user32.dll')
const enumThreadWindows = user32.func('__stdcall', 'EnumThreadWindows', 'int', ['uint32', 'void *', 'intptr'])
const postMessageW = user32.func('__stdcall', 'PostMessageW', 'int', ['void *', 'uint32', 'uintptr', 'intptr'])
+1 -1
View File
@@ -97,7 +97,7 @@ function createGzipMiddleware(config: ResolvedConfig): NodeMiddleware {
if (typeof contentType === 'string' && contentType.toLowerCase().startsWith('text/event-stream')) return false
return compressionMiddleware.filter(request, response)
},
}) as unknown as NodeMiddleware
}) as NodeMiddleware
return (req, res, next) => {
// The Web Worker tunnel has no socket and transfers identity bytes.
@@ -299,7 +299,7 @@ describe('CommandRuntime', () => {
[{ ...command('bad-handler'), handler: undefined }, /handler/],
] as const)('rejects invalid definition %#', async (definition, expected) => {
const ctx = await mount()
expect(() => ctx.commands.register(definition as unknown as CommandDefinition)).toThrow(expected)
expect(() => ctx.commands.register(definition as CommandDefinition)).toThrow(expected)
})
it('logs a paired command/run + command/done around a successful handler', async () => {
+1 -1
View File
@@ -90,7 +90,7 @@ describe('JobRegistry seam', () => {
it('mounting the abstract seam directly fails loudly at load (stale-composition fence)', async () => {
const ctx = new Context()
await expect(ctx.plugin(JobRegistry as unknown as typeof StubJobRegistry))
await expect(ctx.plugin(JobRegistry as typeof StubJobRegistry))
.rejects.toThrow(/abstract job registry seam; load an implementation such as @deepseek-ai\/dsh-jobs-local/)
})
})
Loaded 100 of 158 files, more files were not shown because too many files have changed in this diff. Show more