Merge remote-tracking branch 'origin/master' into claude/unified-environment-credentials-c8841a

# Conflicts:
#	apps/cli/src/profile-boot.ts
#	apps/cli/src/web.ts
This commit is contained in:
Yichen Jiang
2026-08-06 22:34:46 +08:00
164 changed files with 7393 additions and 551 deletions

View File

@@ -320,8 +320,8 @@ const SERVICE_ROLES: ServiceRole[] = [
title: 'Subprocess seam',
mode: 'seam',
implementations: ['subprocess-local'],
consumers: ['bash-local', 'bash-sandbox', 'lsp-local', 'subagent-acp'],
note: 'The bash executors, the LSP host, and the ACP subagent backend spawn their children through ctx.subprocess; the service owns tree lifetime, stdio dispositions (pipes, inherit, bounded spill-backed collection), and kill escalation.',
consumers: ['bash-local', 'bash-sandbox', 'lsp-local', 'subagent-acp', 'subagent-codex', 'subagent-claude-code'],
note: 'The bash executors, the LSP host, and the out-of-process ACP, Codex, and Claude Code subagent backends spawn their children through ctx.subprocess; the service owns tree lifetime, stdio dispositions (pipes, inherit, bounded spill-backed collection), and kill escalation.',
},
{
key: 'bash',
@@ -417,7 +417,7 @@ const SERVICE_ROLES: ServiceRole[] = [
pkg: 'subagent',
title: 'Subagent provider and continuation service',
mode: 'seam',
implementations: ['subagent-spawn', 'subagent-fork', 'subagent-acp'],
implementations: ['subagent-spawn', 'subagent-fork', 'subagent-acp', 'subagent-codex', 'subagent-claude-code', 'subagent-dsh-sdk'],
consumers: ['tool-subagent', 'tool-subagent-control', 'tool-ralph'],
note: 'Providers implement transports; the service also owns optional Activation-based continuation orchestration, tool-subagent selects one-shot or continuable delegation, tool-subagent-control delivers follow-ups, and tool-ralph requires one fresh structured-output route.',
},

View File

@@ -2,7 +2,20 @@ import { mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSyn
import { join, resolve } from 'node:path'
import { tmpdir } from 'node:os'
import { describe, expect, it } from 'vitest'
import { collectPythonDependencies, isPermissive, type Manifest, manifestPatterns, parsePyprojectRequirements, parseVendoredRows, render, tierExternalDeps, virtualManifest } from './gen-third-party-notices.ts'
import {
CLAUDE_AGENT_SDK_PACKAGE,
claudeDistributionFromManifest,
collectPythonDependencies,
isOwnerAuthorizedRuntime,
isPermissive,
type Manifest,
manifestPatterns,
parsePyprojectRequirements,
parseVendoredRows,
render,
tierExternalDeps,
virtualManifest,
} from './gen-third-party-notices.ts'
const root = resolve(import.meta.dirname, '..')
@@ -12,7 +25,9 @@ describe('THIRD_PARTY_NOTICES.md', () => {
// Pre-commit regenerates the file whenever a manifest is staged, so reaching
// this assertion means the notices were committed without that hook.
it('matches what the generator produces from the current manifests', () => {
expect(readFileSync(resolve(root, 'THIRD_PARTY_NOTICES.md'), 'utf8'), 'stale notices — run `pnpm run gen-third-party-notices`').toBe(render())
const generated = render()
expect(generated).toContain('It depends on the third-party software listed below.')
expect(readFileSync(resolve(root, 'THIRD_PARTY_NOTICES.md'), 'utf8'), 'stale notices — run `pnpm run gen-third-party-notices`').toBe(generated)
})
})
@@ -223,7 +238,14 @@ describe('collectPythonDependencies', () => {
describe('isPermissive', () => {
it('accepts the licenses this project ships and rejects copyleft or unknown ones', () => {
expect(['MIT', 'ISC', 'BSD-3-Clause', 'Apache-2.0', 'MIT / Apache-2.0', '(MIT OR CC0-1.0)'].every(isPermissive)).toBe(true)
expect(['LGPL-3.0-only', 'MPL-2.0', 'GPL-3.0-or-later', 'SEE LICENSE IN LICENSE'].some(isPermissive)).toBe(false)
expect([
'LGPL-3.0-only',
'MPL-2.0',
'GPL-3.0-or-later',
'SEE LICENSE IN LICENSE',
'SEE LICENSE IN README.md',
'SEE LICENSE IN LICENSE.md',
].some(isPermissive)).toBe(false)
})
it('requires every operand of an AND, so a copyleft conjunct cannot ride along', () => {
@@ -245,6 +267,66 @@ describe('isPermissive', () => {
})
})
describe('official Claude distribution authorization', () => {
it('authorizes only the direct SDK identity without relabeling its license', () => {
expect(isOwnerAuthorizedRuntime(CLAUDE_AGENT_SDK_PACKAGE)).toBe(true)
expect(isOwnerAuthorizedRuntime(`${CLAUDE_AGENT_SDK_PACKAGE}-linux-x64`))
.toBe(false)
expect(isOwnerAuthorizedRuntime('@anthropic-ai/unrelated')).toBe(false)
expect(isPermissive('SEE LICENSE IN README.md')).toBe(false)
})
it('derives version-independent platform payloads from the official SDK manifest', () => {
expect(claudeDistributionFromManifest({
name: CLAUDE_AGENT_SDK_PACKAGE,
version: '9.8.7',
license: 'future declared terms',
claudeCodeVersion: '6.5.4',
optionalDependencies: {
[`${CLAUDE_AGENT_SDK_PACKAGE}-linux-x64`]: '9.8.7',
[`${CLAUDE_AGENT_SDK_PACKAGE}-darwin-arm64`]: '9.8.7',
},
})).toEqual({
sdkVersion: '9.8.7',
claudeCodeVersion: '6.5.4',
payloads: [
{
name: `${CLAUDE_AGENT_SDK_PACKAGE}-darwin-arm64`,
version: '9.8.7',
},
{
name: `${CLAUDE_AGENT_SDK_PACKAGE}-linux-x64`,
version: '9.8.7',
},
],
})
})
it('rejects a wrong SDK identity, missing payloads, and unrelated optionals', () => {
expect(() => claudeDistributionFromManifest({
name: '@anthropic-ai/unrelated',
version: '1.0.0',
claudeCodeVersion: '1.0.0',
optionalDependencies: {
[`${CLAUDE_AGENT_SDK_PACKAGE}-linux-x64`]: '1.0.0',
},
})).toThrow(`expected ${CLAUDE_AGENT_SDK_PACKAGE} manifest`)
expect(() => claudeDistributionFromManifest({
name: CLAUDE_AGENT_SDK_PACKAGE,
version: '1.0.0',
claudeCodeVersion: '1.0.0',
})).toThrow('declares no optional platform payloads')
expect(() => claudeDistributionFromManifest({
name: CLAUDE_AGENT_SDK_PACKAGE,
version: '1.0.0',
claudeCodeVersion: '1.0.0',
optionalDependencies: {
'@anthropic-ai/unrelated': '1.0.0',
},
})).toThrow('outside its authorized platform-payload identity')
})
})
describe('manifestPatterns', () => {
it('derives globs from the declared members, so a new member area is read', () => {
expect(manifestPatterns(['packages/*/*', 'tools/*'], ['packages/*'])).toEqual([

View File

@@ -49,6 +49,21 @@ const FIRST_PARTY = new Set([
'node-addon-landlock-run-linux-x64',
])
/** Official SDK identity covered by the project's narrow owner authorization. */
export const CLAUDE_AGENT_SDK_PACKAGE = '@anthropic-ai/claude-agent-sdk'
const CLAUDE_PLATFORM_PACKAGE_PREFIX = `${CLAUDE_AGENT_SDK_PACKAGE}-`
const CLAUDE_PLATFORM_DECLARED_LICENSE = 'SEE LICENSE IN LICENSE.md'
/**
* Whether a non-permissive runtime declaration has an identity-scoped owner
* authorization. This does not reclassify its terms as permissive.
* @param name - exact npm package identity.
* @returns true only for the official Claude Agent SDK package.
*/
export function isOwnerAuthorizedRuntime(name: string): boolean {
return name === CLAUDE_AGENT_SDK_PACKAGE
}
/**
* Metadata overrides where the installed manifest is wrong or unreachable.
* Each entry documents why the store cannot answer.
@@ -92,6 +107,7 @@ const BUILD_TIME_TOOLS = [
/** The `package.json` fields this generator reads. */
export interface Manifest {
name?: string
version?: string
private?: boolean
license?: string
dependencies?: Record<string, string>
@@ -164,7 +180,74 @@ function loadWorkspaceManifests(): { manifests: Map<string, Manifest>; names: Se
return { manifests, names }
}
type VirtualManifest = Manifest & { license?: string; repository?: string | { url?: string }; homepage?: string }
type VirtualManifest = Manifest & {
claudeCodeVersion?: string
license?: string
repository?: string | { url?: string }
homepage?: string
}
/** One platform payload declared by the official Claude Agent SDK. */
export interface ClaudePlatformPayload {
readonly name: string
readonly version: string
}
/** Current SDK and CLI distribution facts derived from the installed SDK manifest. */
export interface ClaudeDistribution {
readonly sdkVersion: string
readonly claudeCodeVersion: string
readonly payloads: ClaudePlatformPayload[]
}
function requiredManifestString(
value: string | undefined,
field: string,
): string {
if (value === undefined || value.length === 0) {
throw new Error(`gen-third-party-notices: ${CLAUDE_AGENT_SDK_PACKAGE} has no ${field}.`)
}
return value
}
/**
* Derive the official platform payload set without a version or platform
* allowlist. Only identities in the SDK's own package namespace are covered.
* @param manifest - installed official SDK manifest.
* @returns current SDK, CLI, and optional platform payload facts.
*/
export function claudeDistributionFromManifest(
manifest: VirtualManifest,
): ClaudeDistribution {
if (manifest.name !== CLAUDE_AGENT_SDK_PACKAGE) {
throw new Error(
`gen-third-party-notices: expected ${CLAUDE_AGENT_SDK_PACKAGE} manifest, got ${JSON.stringify(manifest.name)}.`,
)
}
const sdkVersion = requiredManifestString(manifest.version, 'version')
const claudeCodeVersion = requiredManifestString(
manifest.claudeCodeVersion,
'claudeCodeVersion',
)
const entries = Object.entries(manifest.optionalDependencies ?? {})
if (entries.length === 0) {
throw new Error(
`gen-third-party-notices: ${CLAUDE_AGENT_SDK_PACKAGE} declares no optional platform payloads.`,
)
}
const payloads = entries.map(([name, version]) => {
if (!name.startsWith(CLAUDE_PLATFORM_PACKAGE_PREFIX)) {
throw new Error(
`gen-third-party-notices: ${CLAUDE_AGENT_SDK_PACKAGE} optional dependency ${name} is outside its authorized platform-payload identity.`,
)
}
return {
name,
version: requiredManifestString(version, `${name} optional dependency version`),
}
}).sort((left, right) => left.name.localeCompare(right.name))
return { sdkVersion, claudeCodeVersion, payloads }
}
/**
* Resolve one package's manifest inside a pnpm virtual store. The prefix scan
@@ -193,9 +276,8 @@ export function virtualManifest(virtual: string, name: string): VirtualManifest
return undefined
}
/** License and repository URL for an installed external package, from the pnpm store. */
function installedMetadata(name: string): { license: string; repo: string } {
const override = OVERRIDES[name]
/** Resolve one installed external package manifest from either pnpm store. */
function installedManifest(name: string): VirtualManifest | undefined {
let manifest: (Manifest & { license?: string; repository?: string | { url?: string }; homepage?: string }) | undefined
// The nested Landlock workspace installs into its own store, so a package
// only that workspace depends on is unreachable from the root one.
@@ -210,6 +292,13 @@ function installedMetadata(name: string): { license: string; repo: string } {
manifest = virtualManifest(virtual, name)
if (manifest !== undefined) break
}
return manifest
}
/** License and repository URL for an installed external package, from the pnpm store. */
function installedMetadata(name: string): { license: string; repo: string } {
const override = OVERRIDES[name]
const manifest = installedManifest(name)
const license = override?.license ?? manifest?.license
const rawRepo = typeof manifest?.repository === 'string' ? manifest.repository : manifest?.repository?.url ?? manifest?.homepage
const repo = override?.repo ?? normalizeRepo(rawRepo)
@@ -219,6 +308,37 @@ function installedMetadata(name: string): { license: string; repo: string } {
return { license, repo }
}
function collectClaudeDistribution(): ClaudeDistribution {
const manifest = installedManifest(CLAUDE_AGENT_SDK_PACKAGE)
if (manifest === undefined) {
throw new Error(
`gen-third-party-notices: cannot resolve ${CLAUDE_AGENT_SDK_PACKAGE}; run \`pnpm install\`.`,
)
}
const distribution = claudeDistributionFromManifest(manifest)
let installedPayloads = 0
for (const payload of distribution.payloads) {
const installed = installedManifest(payload.name)
if (installed === undefined) continue
installedPayloads += 1
if (
installed.name !== payload.name
|| installed.version !== payload.version
|| installed.license !== CLAUDE_PLATFORM_DECLARED_LICENSE
) {
throw new Error(
`gen-third-party-notices: installed ${payload.name} does not match its SDK-declared version and ${CLAUDE_PLATFORM_DECLARED_LICENSE} license field.`,
)
}
}
if (installedPayloads === 0) {
throw new Error(
'gen-third-party-notices: no SDK-declared Claude platform payload is installed; install optional dependencies before regenerating.',
)
}
return distribution
}
/** Normalize a manifest repository/homepage value to a browsable https URL. */
function normalizeRepo(raw: string | undefined): string | undefined {
if (raw === undefined || raw === '') return undefined
@@ -519,6 +639,26 @@ function renderNpmTable(deps: ExternalDep[]): string {
return lines.join('\n')
}
function renderClaudeDistribution(
distribution: ClaudeDistribution | undefined,
): string {
if (distribution === undefined) return ''
const rows = distribution.payloads.map(payload =>
`| [\`${payload.name}\`](https://www.npmjs.com/package/${payload.name}) | ${payload.version} | ${CLAUDE_PLATFORM_DECLARED_LICENSE} |`,
)
return `
## Official Claude Code platform payloads
The project owner authorizes distribution of every version of the official \`${CLAUDE_AGENT_SDK_PACKAGE}\` package and the official Claude Code CLI/platform payloads that each version declares through \`optionalDependencies\`. This identity-scoped authorization does not classify their declared terms as permissive and does not cover any unrelated runtime package; version, declared-license, and payload-set changes still require the ordinary dependency, lockfile, compatibility, terms, and notices review.
The installed SDK ${distribution.sdkVersion} declares the following optional platform packages. Each carries the official Claude Code ${distribution.claudeCodeVersion} executable; the package identities and versions come from the SDK manifest, while the declared license field is verified against the platform payload installed for the current host.
| Optional platform package | Version | Declared license |
| --- | --- | --- |
${rows.join('\n')}
`
}
/**
* Render the complete notices document.
* @returns the exact bytes `THIRD_PARTY_NOTICES.md` must hold.
@@ -531,11 +671,19 @@ export function render(): string {
const vendored = collectVendored()
const python = collectPython()
const patched = collectPatched()
const claudeDistribution = runtimeDeps.some(
dep => dep.name === CLAUDE_AGENT_SDK_PACKAGE,
)
? collectClaudeDistribution()
: undefined
const nonPermissiveDev = devDeps.filter(dep => !isPermissive(dep.license))
// A copyleft license reaching a shipped surface is a distribution decision,
// not a rendering detail; the notices cannot quietly absorb it.
const nonPermissiveRuntime = runtimeDeps.filter(dep => !isPermissive(dep.license))
const nonPermissiveRuntime = runtimeDeps.filter(dep =>
!isPermissive(dep.license)
&& !isOwnerAuthorizedRuntime(dep.name),
)
if (nonPermissiveRuntime.length > 0) {
throw new Error(`gen-third-party-notices: runtime ${nonPermissiveRuntime.map(dep => `${dep.name} (${dep.license})`).join(', ')} is not a permissive license; review the distribution terms and record the decision before regenerating.`)
}
@@ -546,9 +694,9 @@ export function render(): string {
# Third-Party Notices
DeepSeek Harness is licensed under [BSD 3-Clause](LICENSE). It depends on the third-party open-source software listed below. Each project remains under its own license; nothing in this file changes those terms.
DeepSeek Harness is licensed under [BSD 3-Clause](LICENSE). It depends on the third-party software listed below. Each project remains under its own license; nothing in this file changes those terms.
This file lists **direct** dependencies declared by the workspace. It is generated from the workspace manifests by \`scripts/gen-third-party-notices.ts\`: a pre-commit hook regenerates it whenever a staged file changes one of its inputs, and \`scripts/gen-third-party-notices.spec.ts\` asserts in the test lane that the committed bytes match. Deleting a manifest runs no hook, so that case is caught by the assertion instead. Run \`pnpm run verify-third-party-notices\` for the standalone check.
This file lists **direct** dependencies declared by the workspace and the explicitly disclosed official Claude platform payload closure. It is generated from the workspace manifests by \`scripts/gen-third-party-notices.ts\`: a pre-commit hook regenerates it whenever a staged file changes one of its inputs, and \`scripts/gen-third-party-notices.spec.ts\` asserts in the test lane that the committed bytes match. Deleting a manifest runs no hook, so that case is caught by the assertion instead. Run \`pnpm run verify-third-party-notices\` for the standalone check.
The complete npm transitive closure, with exact pinned versions, is recorded in [\`pnpm-lock.yaml\`](pnpm-lock.yaml) — inspect it with \`pnpm licenses list\`. The Python closure is recorded in [\`python/sdk/uv.lock\`](python/sdk/uv.lock), and the Landlock launcher workspace keeps its own in [\`native/landlock-run/pnpm-lock.yaml\`](native/landlock-run/pnpm-lock.yaml).
@@ -569,6 +717,7 @@ ${renderNpmTable(runtimeDeps)}
pnpm applies local patches to the following packages at install time, so shipped artifacts carry modified copies; each patch file is the complete record of the modification:
${patchedLines.join('\n')}
${renderClaudeDistribution(claudeDistribution)}
## Development-only npm dependencies

View File

@@ -189,6 +189,12 @@ describe('Node 24 lane ownership', () => {
expect(subject.find(item => item.id === 'doc-typecheck')?.env).toEqual({
DSH_DOC_TYPECHECK_USE_BUILD_OUTPUT: '1',
})
expect(subject.find(item => item.id === 'built-bin-smoke')?.args).toEqual(
expect.arrayContaining([
'packages/subagent/subagent-codex/tests/loader-composition.e2e.ts',
'packages/subagent/subagent-claude-code/tests/loader-composition.e2e.ts',
]),
)
expect(subject.find(item => item.id === 'web-snapshot')).toMatchObject({
displayCommand: 'DSH_SNAPSHOT=replay pnpm run test:web:built',
env: { DSH_SNAPSHOT: 'replay' },

View File

@@ -600,6 +600,8 @@ function builtBinSmokeGate(needs: string[] = ['build']): Gate {
'packages/examples/acp-demo/tests/built-bin.e2e.ts',
'packages/host/directory-picker-native/tests/built-worker.e2e.ts',
'packages/ui/jsonrpc/tests/built-scope-carrier.e2e.ts',
'packages/subagent/subagent-codex/tests/loader-composition.e2e.ts',
'packages/subagent/subagent-claude-code/tests/loader-composition.e2e.ts',
// The worker-entry packages' built bundles: the only automated proof
// that lib/index.js resolves its sibling lib/worker.cjs under plain node
// (the e2e lane runs unbuilt, so these files self-skip there).