mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
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:
@@ -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.',
|
||||
},
|
||||
|
||||
@@ -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([
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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' },
|
||||
|
||||
@@ -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).
|
||||
|
||||
Reference in New Issue
Block a user