refactor(infra): keep Codex notices direct
This commit is contained in:
parent
4775095aa2
commit
cb229c8964
3 changed files with 2 additions and 245 deletions
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
DeepSeek Harness is licensed under [MIT](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 and the explicitly disclosed official Claude Code and Codex platform payload closures. 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 Code 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, including the Landlock launcher workspace, is recorded with exact pinned versions in [`pnpm-lock.yaml`](pnpm-lock.yaml) — inspect it with `pnpm licenses list`. The Python closure is recorded separately in [`python/sdk/uv.lock`](python/sdk/uv.lock).
|
||||
|
||||
|
|
@ -114,20 +114,6 @@ The installed SDK 0.3.220 declares the following optional platform packages. Eac
|
|||
| [`@anthropic-ai/claude-agent-sdk-win32-x64`](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk-win32-x64) | 0.3.220 | SEE LICENSE IN LICENSE.md |
|
||||
|
||||
|
||||
## Official Codex platform payloads
|
||||
|
||||
The installed `@openai/codex` wrapper 0.147.0 declares the following optional-dependency aliases. Every alias resolves to an official platform-specific `@openai/codex` version that carries the native Codex CLI and its bundled resources; the declared license is verified against the payload installed for the current host.
|
||||
|
||||
| Optional dependency alias | Published package | Version | Declared license |
|
||||
| --- | --- | --- | --- |
|
||||
| `@openai/codex-darwin-arm64` | [`@openai/codex`](https://www.npmjs.com/package/@openai/codex/v/0.147.0-darwin-arm64) | 0.147.0-darwin-arm64 | Apache-2.0 |
|
||||
| `@openai/codex-darwin-x64` | [`@openai/codex`](https://www.npmjs.com/package/@openai/codex/v/0.147.0-darwin-x64) | 0.147.0-darwin-x64 | Apache-2.0 |
|
||||
| `@openai/codex-linux-arm64` | [`@openai/codex`](https://www.npmjs.com/package/@openai/codex/v/0.147.0-linux-arm64) | 0.147.0-linux-arm64 | Apache-2.0 |
|
||||
| `@openai/codex-linux-x64` | [`@openai/codex`](https://www.npmjs.com/package/@openai/codex/v/0.147.0-linux-x64) | 0.147.0-linux-x64 | Apache-2.0 |
|
||||
| `@openai/codex-win32-arm64` | [`@openai/codex`](https://www.npmjs.com/package/@openai/codex/v/0.147.0-win32-arm64) | 0.147.0-win32-arm64 | Apache-2.0 |
|
||||
| `@openai/codex-win32-x64` | [`@openai/codex`](https://www.npmjs.com/package/@openai/codex/v/0.147.0-win32-x64) | 0.147.0-win32-x64 | Apache-2.0 |
|
||||
|
||||
|
||||
## Development-only npm dependencies
|
||||
|
||||
External packages **directly declared** only by repository tooling, test infrastructure, the documentation site, the demo leaves, or the native launcher's build workspace. No shipped surface names them itself. A package here may still be pulled in transitively by a runtime dependency — `pnpm-lock.yaml` is the authority on the full closure — so this tier records who declares a package, not what a build ultimately bundles.
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@ import { tmpdir } from 'node:os'
|
|||
import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
CLAUDE_AGENT_SDK_PACKAGE,
|
||||
CODEX_PACKAGE,
|
||||
claudeDistributionFromManifest,
|
||||
codexDistributionFromManifest,
|
||||
codexDistributionFromInstalledPackage,
|
||||
collectPythonDependencies,
|
||||
isOwnerAuthorizedRuntime,
|
||||
isPermissive,
|
||||
|
|
@ -334,94 +331,6 @@ describe('official Claude distribution authorization', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('official Codex platform payloads', () => {
|
||||
it('derives versioned packages from the wrapper aliases', () => {
|
||||
expect(codexDistributionFromManifest({
|
||||
name: CODEX_PACKAGE,
|
||||
version: '9.8.7',
|
||||
optionalDependencies: {
|
||||
'@openai/codex-linux-x64': 'npm:@openai/codex@9.8.7-linux-x64',
|
||||
'@openai/codex-darwin-arm64': 'npm:@openai/codex@9.8.7-darwin-arm64',
|
||||
},
|
||||
})).toEqual({
|
||||
wrapperVersion: '9.8.7',
|
||||
payloads: [
|
||||
{ alias: '@openai/codex-darwin-arm64', version: '9.8.7-darwin-arm64' },
|
||||
{ alias: '@openai/codex-linux-x64', version: '9.8.7-linux-x64' },
|
||||
],
|
||||
})
|
||||
})
|
||||
|
||||
it('rejects a wrong identity, missing payloads, and non-official aliases', () => {
|
||||
expect(() => codexDistributionFromManifest({
|
||||
name: '@openai/unrelated',
|
||||
version: '1.0.0',
|
||||
optionalDependencies: {
|
||||
'@openai/codex-linux-x64': 'npm:@openai/codex@1.0.0-linux-x64',
|
||||
},
|
||||
})).toThrow(`expected ${CODEX_PACKAGE} manifest`)
|
||||
expect(() => codexDistributionFromManifest({
|
||||
name: CODEX_PACKAGE,
|
||||
version: '1.0.0',
|
||||
})).toThrow('declares no optional platform payloads')
|
||||
expect(() => codexDistributionFromManifest({
|
||||
name: CODEX_PACKAGE,
|
||||
version: '1.0.0',
|
||||
optionalDependencies: {
|
||||
'@openai/unrelated': 'npm:@openai/codex@1.0.0-linux-x64',
|
||||
},
|
||||
})).toThrow('outside its platform alias namespace')
|
||||
expect(() => codexDistributionFromManifest({
|
||||
name: CODEX_PACKAGE,
|
||||
version: '1.0.0',
|
||||
optionalDependencies: {
|
||||
'@openai/codex-linux-x64': '1.0.0',
|
||||
},
|
||||
})).toThrow('does not alias an official versioned payload')
|
||||
})
|
||||
|
||||
it('resolves installed payload aliases from the wrapper package', () => {
|
||||
const fixtureRoot = mkdtempSync(join(tmpdir(), 'dsh-notices-codex-wrapper-'))
|
||||
try {
|
||||
const wrapperPath = join(
|
||||
fixtureRoot,
|
||||
'node_modules/@openai/codex/package.json',
|
||||
)
|
||||
mkdirSync(resolve(wrapperPath, '..'), { recursive: true })
|
||||
writeFileSync(wrapperPath, JSON.stringify({
|
||||
name: CODEX_PACKAGE,
|
||||
version: '9.8.7',
|
||||
optionalDependencies: {
|
||||
'@openai/codex-darwin-arm64': 'npm:@openai/codex@9.8.7-darwin-arm64',
|
||||
'@openai/codex-linux-x64': 'npm:@openai/codex@9.8.7-linux-x64',
|
||||
},
|
||||
}))
|
||||
for (const platform of ['darwin-arm64', 'linux-x64']) {
|
||||
const payloadPath = join(
|
||||
fixtureRoot,
|
||||
`node_modules/@openai/codex-${platform}/package.json`,
|
||||
)
|
||||
mkdirSync(resolve(payloadPath, '..'), { recursive: true })
|
||||
writeFileSync(payloadPath, JSON.stringify({
|
||||
name: CODEX_PACKAGE,
|
||||
version: `9.8.7-${platform}`,
|
||||
license: 'Apache-2.0',
|
||||
}))
|
||||
}
|
||||
|
||||
expect(codexDistributionFromInstalledPackage(wrapperPath)).toEqual({
|
||||
wrapperVersion: '9.8.7',
|
||||
payloads: [
|
||||
{ alias: '@openai/codex-darwin-arm64', version: '9.8.7-darwin-arm64' },
|
||||
{ alias: '@openai/codex-linux-x64', version: '9.8.7-linux-x64' },
|
||||
],
|
||||
})
|
||||
} finally {
|
||||
rmSync(fixtureRoot, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('manifestPatterns', () => {
|
||||
it('derives globs from the declared members, so a new member area is read', () => {
|
||||
expect(manifestPatterns(['packages/*/*', 'tools/*', 'native/landlock-run', 'native/landlock-run/packages/*'])).toEqual([
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
*/
|
||||
|
||||
import { existsSync, globSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'
|
||||
import { createRequire } from 'node:module'
|
||||
import { resolve } from 'node:path'
|
||||
import * as yaml from 'js-yaml'
|
||||
import { parse as parseToml, type TomlTableWithoutBigInt, type TomlValueWithoutBigInt } from 'smol-toml'
|
||||
|
|
@ -51,9 +50,6 @@ const FIRST_PARTY = new Set([
|
|||
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'
|
||||
export const CODEX_PACKAGE = '@openai/codex'
|
||||
const CODEX_PLATFORM_ALIAS_PREFIX = `${CODEX_PACKAGE}-`
|
||||
const CODEX_DECLARED_LICENSE = 'Apache-2.0'
|
||||
|
||||
/**
|
||||
* Whether a non-permissive runtime declaration has an identity-scoped owner
|
||||
|
|
@ -198,18 +194,6 @@ export interface ClaudeDistribution {
|
|||
readonly payloads: ClaudePlatformPayload[]
|
||||
}
|
||||
|
||||
/** One optional-dependency alias for an official Codex platform payload. */
|
||||
export interface CodexPlatformPayload {
|
||||
readonly alias: string
|
||||
readonly version: string
|
||||
}
|
||||
|
||||
/** Current Codex wrapper and platform payload facts from the official manifest. */
|
||||
export interface CodexDistribution {
|
||||
readonly wrapperVersion: string
|
||||
readonly payloads: CodexPlatformPayload[]
|
||||
}
|
||||
|
||||
function requiredManifestString(
|
||||
value: string | undefined,
|
||||
field: string,
|
||||
|
|
@ -259,91 +243,6 @@ export function claudeDistributionFromManifest(
|
|||
return { sdkVersion, claudeCodeVersion, payloads }
|
||||
}
|
||||
|
||||
/** Derive official Codex platform aliases and published package versions. */
|
||||
export function codexDistributionFromManifest(
|
||||
manifest: VirtualManifest,
|
||||
): CodexDistribution {
|
||||
if (manifest.name !== CODEX_PACKAGE) {
|
||||
throw new Error(
|
||||
`gen-third-party-notices: expected ${CODEX_PACKAGE} manifest, got ${JSON.stringify(manifest.name)}.`,
|
||||
)
|
||||
}
|
||||
const wrapperVersion = manifest.version
|
||||
if (wrapperVersion === undefined || wrapperVersion.length === 0) {
|
||||
throw new Error(`gen-third-party-notices: ${CODEX_PACKAGE} has no version.`)
|
||||
}
|
||||
const entries = Object.entries(manifest.optionalDependencies ?? {})
|
||||
if (entries.length === 0) {
|
||||
throw new Error(`gen-third-party-notices: ${CODEX_PACKAGE} declares no optional platform payloads.`)
|
||||
}
|
||||
const payloads = entries.map(([alias, spec]) => {
|
||||
if (!alias.startsWith(CODEX_PLATFORM_ALIAS_PREFIX)) {
|
||||
throw new Error(
|
||||
`gen-third-party-notices: ${CODEX_PACKAGE} optional dependency ${alias} is outside its platform alias namespace.`,
|
||||
)
|
||||
}
|
||||
const prefix = `npm:${CODEX_PACKAGE}@`
|
||||
if (!spec.startsWith(prefix) || spec.length === prefix.length) {
|
||||
throw new Error(
|
||||
`gen-third-party-notices: ${CODEX_PACKAGE} optional dependency ${alias} does not alias an official versioned payload.`,
|
||||
)
|
||||
}
|
||||
return { alias, version: spec.slice(prefix.length) }
|
||||
}).sort((left, right) => left.alias.localeCompare(right.alias))
|
||||
return { wrapperVersion, payloads }
|
||||
}
|
||||
|
||||
function requireManifest(
|
||||
requireFrom: NodeJS.Require,
|
||||
name: string,
|
||||
): VirtualManifest | undefined {
|
||||
let packageJsonPath: string
|
||||
try {
|
||||
packageJsonPath = requireFrom.resolve(`${name}/package.json`)
|
||||
} catch (error: unknown) {
|
||||
if (error instanceof Error && 'code' in error && error.code === 'MODULE_NOT_FOUND') {
|
||||
return undefined
|
||||
}
|
||||
throw error
|
||||
}
|
||||
return JSON.parse(readFileSync(packageJsonPath, 'utf8')) as VirtualManifest
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive and verify the Codex distribution from the wrapper package's own
|
||||
* Node resolution context.
|
||||
* @param packageJsonPath - absolute manifest path for the installed wrapper.
|
||||
* @returns the wrapper version and all declared platform aliases.
|
||||
*/
|
||||
export function codexDistributionFromInstalledPackage(
|
||||
packageJsonPath: string,
|
||||
): CodexDistribution {
|
||||
const manifest = JSON.parse(readFileSync(packageJsonPath, 'utf8')) as VirtualManifest
|
||||
const distribution = codexDistributionFromManifest(manifest)
|
||||
const requireFromWrapper = createRequire(packageJsonPath)
|
||||
let installedPayloads = 0
|
||||
for (const payload of distribution.payloads) {
|
||||
const installed = requireManifest(requireFromWrapper, payload.alias)
|
||||
if (installed === undefined) continue
|
||||
installedPayloads += 1
|
||||
if (
|
||||
installed.name !== CODEX_PACKAGE
|
||||
|| installed.version !== payload.version
|
||||
|| installed.license !== CODEX_DECLARED_LICENSE
|
||||
) {
|
||||
throw new Error(
|
||||
`gen-third-party-notices: installed ${payload.alias} does not match its official ${CODEX_PACKAGE}@${payload.version} payload and ${CODEX_DECLARED_LICENSE} license.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
if (installedPayloads === 0) {
|
||||
throw new Error(
|
||||
'gen-third-party-notices: no Codex platform payload is installed; install optional dependencies before regenerating.',
|
||||
)
|
||||
}
|
||||
return distribution
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve one package's manifest inside a pnpm virtual store. The prefix scan
|
||||
* matches ordinary `@scope+name@version` directory names; pnpm 11 truncates
|
||||
|
|
@ -434,20 +333,6 @@ function collectClaudeDistribution(): ClaudeDistribution {
|
|||
return distribution
|
||||
}
|
||||
|
||||
function collectCodexDistribution(): CodexDistribution {
|
||||
const requireFromProvider = createRequire(resolve(
|
||||
root,
|
||||
'packages/subagent/subagent-codex/package.json',
|
||||
))
|
||||
let packageJsonPath: string
|
||||
try {
|
||||
packageJsonPath = requireFromProvider.resolve(`${CODEX_PACKAGE}/package.json`)
|
||||
} catch {
|
||||
throw new Error(`gen-third-party-notices: cannot resolve ${CODEX_PACKAGE}; run \`pnpm install\`.`)
|
||||
}
|
||||
return codexDistributionFromInstalledPackage(packageJsonPath)
|
||||
}
|
||||
|
||||
/** Normalize a manifest repository/homepage value to a browsable https URL. */
|
||||
function normalizeRepo(raw: string | undefined): string | undefined {
|
||||
if (raw === undefined || raw === '') return undefined
|
||||
|
|
@ -771,24 +656,6 @@ ${rows.join('\n')}
|
|||
`
|
||||
}
|
||||
|
||||
function renderCodexDistribution(
|
||||
distribution: CodexDistribution | undefined,
|
||||
): string {
|
||||
if (distribution === undefined) return ''
|
||||
const rows = distribution.payloads.map(payload => (
|
||||
`| \`${payload.alias}\` | [\`${CODEX_PACKAGE}\`](https://www.npmjs.com/package/${CODEX_PACKAGE}/v/${payload.version}) | ${payload.version} | ${CODEX_DECLARED_LICENSE} |`
|
||||
))
|
||||
return `
|
||||
## Official Codex platform payloads
|
||||
|
||||
The installed \`${CODEX_PACKAGE}\` wrapper ${distribution.wrapperVersion} declares the following optional-dependency aliases. Every alias resolves to an official platform-specific \`${CODEX_PACKAGE}\` version that carries the native Codex CLI and its bundled resources; the declared license is verified against the payload installed for the current host.
|
||||
|
||||
| Optional dependency alias | Published package | Version | Declared license |
|
||||
| --- | --- | --- | --- |
|
||||
${rows.join('\n')}
|
||||
`
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the complete notices document.
|
||||
* @returns the exact bytes `THIRD_PARTY_NOTICES.md` must hold.
|
||||
|
|
@ -806,10 +673,6 @@ export function render(): string {
|
|||
)
|
||||
? collectClaudeDistribution()
|
||||
: undefined
|
||||
const codexDistribution = runtimeDeps.some(dep => dep.name === CODEX_PACKAGE)
|
||||
? collectCodexDistribution()
|
||||
: 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.
|
||||
|
|
@ -829,7 +692,7 @@ export function render(): string {
|
|||
|
||||
DeepSeek Harness is licensed under [MIT](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 and the explicitly disclosed official Claude Code and Codex platform payload closures. 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 Code 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, including the Landlock launcher workspace, is recorded with exact pinned versions in [\`pnpm-lock.yaml\`](pnpm-lock.yaml) — inspect it with \`pnpm licenses list\`. The Python closure is recorded separately in [\`python/sdk/uv.lock\`](python/sdk/uv.lock).
|
||||
|
||||
|
|
@ -851,7 +714,6 @@ pnpm applies local patches to the following packages at install time, so shipped
|
|||
|
||||
${patchedLines.join('\n')}
|
||||
${renderClaudeDistribution(claudeDistribution)}
|
||||
${renderCodexDistribution(codexDistribution)}
|
||||
|
||||
## Development-only npm dependencies
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue