feat(subagent): add Claude Code provider
This commit is contained in:
@@ -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.`)
|
||||
}
|
||||
@@ -548,7 +696,7 @@ export function render(): string {
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user