Merge remote-tracking branch 'origin/master' into worktree/web-sidebar-terminal

This commit is contained in:
Yichen Jiang committed 2026-09-09 19:53:05 +08:00
commit cfdfd7ccb9
61 files changed
+336 -169

No files matched your search

@@ -14,6 +14,14 @@ const experimental: WorkspaceManifest = {
manifest: { name: '@deepseek-ai/dsh-experimental-prototype', private: true },
}
const publicExperimental: WorkspaceManifest = {
dir: 'packages/experimental/agent-team',
manifest: {
name: '@deepseek-ai/dsh-experimental-agent-team',
publishConfig: { access: 'public' },
},
}
describe('experimental workspace constraints', () => {
it('requires the experimental package-name prefix', () => {
expect(checkExperimentalManifest({
@@ -35,6 +43,20 @@ describe('experimental workspace constraints', () => {
])
})
it('requires public metadata only for the Agent Teams exceptions', () => {
expect(checkExperimentalManifest(publicExperimental)).toEqual([])
expect(checkExperimentalManifest({
...publicExperimental,
manifest: {
name: '@deepseek-ai/dsh-experimental-agent-team',
private: true,
},
})).toEqual([
'@deepseek-ai/dsh-experimental-agent-team: public experimental package must not set "private": true',
'@deepseek-ai/dsh-experimental-agent-team: public experimental package must set publishConfig.access to "public"',
])
})
it.each(['dependencies', 'optionalDependencies', 'peerDependencies'] as const)(
'rejects release %s on an experimental package',
(section) => {
+21 -9
View File
@@ -8,6 +8,7 @@
import { existsSync, readdirSync, readFileSync } from 'node:fs'
import { join, relative, resolve } from 'node:path'
import { pathToFileURL } from 'node:url'
import { isPublicExperimentalPackageDirectory } from './experimental-package-policy.ts'
import { hasTypertRemoteNavigation, isForbiddenPublicationFile } from './publication-payload.ts'
import { collectProjectReferenceFaceViolations } from './project-reference-faces.ts'
@@ -50,12 +51,12 @@ const repositoryUrl = 'git+https://github.com/deepseek-harness/deepseek-harness.
* their trusted publishing against the repository that runs the workflow.
*/
const publishedRepositoryUrl = 'git+https://github.com/deepseek-ai/deepseek-harness.git'
/** Private packages that participate in workspace checks but not releases. */
/** Packages that participate in the experimental policy. */
const experimentalPackageDirectory = /^packages\/experimental\/[^/]+$/
/** npm namespace reserved for private experimental packages. */
/** npm namespace reserved for experimental packages. */
const experimentalPackageNamePrefix = '@deepseek-ai/dsh-experimental-'
/** Directories whose packages this repository publishes: one release member each. */
const releaseMemberDirectory = /^(?:packages\/(?!experimental\/)[^/]+\/[^/]+|apps\/(?!desktop(?:-host)?$)[^/]+|vendor\/[^/]+)$/
/** Ordinary directories whose packages this repository publishes: one release member each. */
const standardReleaseMemberDirectory = /^(?:packages\/(?!experimental\/)[^/]+\/[^/]+|apps\/(?!desktop(?:-host)?$)[^/]+|vendor\/[^/]+)$/
/** Installable application assembled by electron-builder rather than published to npm. */
const desktopApplicationDirectory = 'apps/desktop'
const localArtifactDirs = new Set(['node_modules'])
@@ -267,7 +268,7 @@ function usesEmittedTreeDefaults(manifest: PackageManifest): boolean {
exportDefault(manifest, subpath)?.startsWith('./lib/types/') === true)
}
/** Experimental manifest requirements enforced independently from release metadata. */
/** Experimental manifest requirements, including explicit public exceptions. */
export function checkExperimentalManifest({ dir, manifest }: WorkspaceManifest): string[] {
if (!experimentalPackageDirectory.test(dir)) return []
const label = manifest.name ?? dir
@@ -275,11 +276,22 @@ export function checkExperimentalManifest({ dir, manifest }: WorkspaceManifest):
if (manifest.name?.startsWith(experimentalPackageNamePrefix) !== true) {
errors.push(`${label}: experimental package name must start with ${JSON.stringify(experimentalPackageNamePrefix)}`)
}
if (manifest.private !== true) errors.push(`${label}: experimental package must set "private": true`)
if (manifest.publishConfig !== undefined) errors.push(`${label}: experimental package must omit publishConfig`)
if (isPublicExperimentalPackageDirectory(dir)) {
if (manifest.private === true) errors.push(`${label}: public experimental package must not set "private": true`)
if (manifest.publishConfig?.access !== 'public') {
errors.push(`${label}: public experimental package must set publishConfig.access to "public"`)
}
} else {
if (manifest.private !== true) errors.push(`${label}: experimental package must set "private": true`)
if (manifest.publishConfig !== undefined) errors.push(`${label}: experimental package must omit publishConfig`)
}
return errors
}
function isReleaseMemberDirectory(dir: string): boolean {
return standardReleaseMemberDirectory.test(dir) || isPublicExperimentalPackageDirectory(dir)
}
/**
* Require a dsh-family manifest to carry the workspace version.
*
@@ -330,7 +342,7 @@ export function checkWorkspaceManifest({ dir, manifest }: WorkspaceManifest): st
|| manifest.repository.directory !== expectedDirectory) {
errors.push(`${label}: published Landlock package repository must use ${repositoryUrl} with directory ${expectedDirectory} for trusted publishing`)
}
} else if (releaseMemberDirectory.test(dir)) {
} else if (isReleaseMemberDirectory(dir)) {
// Release members state that they are publishable: npm refuses a private
// package, and the repository field is how a consumer finds the source of
// the package it installed.
@@ -482,7 +494,7 @@ export function checkExperimentalDependencyIsolation(manifests: readonly Workspa
.filter(name => name !== undefined))
const errors: string[] = []
for (const { dir, manifest } of manifests) {
if (!releaseMemberDirectory.test(dir) && dir !== 'python/sdk-runtime') continue
if (!standardReleaseMemberDirectory.test(dir) && dir !== 'python/sdk-runtime') continue
for (const section of runtimeDependencySections) {
for (const name of Object.keys(manifest[section] ?? {})) {
if (!experimentalNames.has(name)) continue
+19
View File
@@ -0,0 +1,19 @@
/** Experimental packages that publish with the dsh release family without changing names. */
export const PUBLIC_EXPERIMENTAL_PACKAGE_DIRECTORIES = [
'packages/experimental/agent-team',
'packages/experimental/agent-team-profile',
'packages/experimental/agent-team-web-profile',
'packages/experimental/client-ui-agent-team',
'packages/experimental/tool-agent-team',
] as const
const publicExperimentalPackageDirectories = new Set<string>(PUBLIC_EXPERIMENTAL_PACKAGE_DIRECTORIES)
/**
* Whether an experimental package is an explicit public-release exception.
* @param directory - repository-relative package directory.
* @returns Whether the package publishes with the dsh family.
*/
export function isPublicExperimentalPackageDirectory(directory: string): boolean {
return publicExperimentalPackageDirectories.has(directory)
}
+2
View File
@@ -18,6 +18,7 @@ import { basename, dirname, isAbsolute, join, normalize, relative, resolve, sep
import { createInterface } from 'node:readline/promises'
import { pathToFileURL } from 'node:url'
import { parseArgs } from 'node:util'
import { PUBLIC_EXPERIMENTAL_PACKAGE_DIRECTORIES } from './experimental-package-policy.ts'
import { validateTarballPayload } from './publication-payload.ts'
const DEFAULT_REGISTRY = 'https://registry.npm.harnessment.com'
@@ -26,6 +27,7 @@ const PACKAGE_PATTERNS = [
'vendor/*/package.json',
'packages/!(experimental)/*/package.json',
'apps/*/package.json',
...PUBLIC_EXPERIMENTAL_PACKAGE_DIRECTORIES.map(directory => `${directory}/package.json`),
] as const
const DEPENDENCY_SECTIONS = [
'dependencies',
+11 -3
View File
@@ -42,11 +42,19 @@ afterEach(() => {
})
describe('release families', () => {
it('excludes private experimental packages from the dsh release', () => {
it('publishes Agent Teams while excluding private experimental packages', () => {
const members = releaseFamily('dsh').members(resolve(import.meta.dirname, '../..'))
expect(members.some(member => member.directory.startsWith('packages/experimental/'))).toBe(false)
expect(members.map(member => member.name)).not.toContain('@deepseek-ai/dsh-experimental-agent-team')
expect(members
.filter(member => member.directory.startsWith('packages/experimental/'))
.map(member => member.name)).toEqual([
'@deepseek-ai/dsh-experimental-agent-team-profile',
'@deepseek-ai/dsh-experimental-agent-team-web-profile',
'@deepseek-ai/dsh-experimental-agent-team',
'@deepseek-ai/dsh-experimental-client-ui-agent-team',
'@deepseek-ai/dsh-experimental-tool-agent-team',
])
expect(members.map(member => member.name)).not.toContain('@deepseek-ai/dsh-experimental-inspector')
})
it('excludes private applications from the publish set', () => {
+6 -1
View File
@@ -15,6 +15,7 @@ import {
officialClientBuildEnvironment,
readClientBuildRecord,
} from '../client-build-environment.ts'
import { PUBLIC_EXPERIMENTAL_PACKAGE_DIRECTORIES } from '../experimental-package-policy.ts'
import { validateTarballPayload } from '../publication-payload.ts'
/**
@@ -321,7 +322,11 @@ export abstract class ReleaseFamily {
/** Release packages and apps: one shared version across the whole family. */
class DshFamily extends ReleaseFamily {
readonly id = 'dsh'
readonly patterns = ['packages/!(experimental)/*/package.json', 'apps/*/package.json'] as const
readonly patterns = [
'packages/!(experimental)/*/package.json',
'apps/*/package.json',
...PUBLIC_EXPERIMENTAL_PACKAGE_DIRECTORIES.map(directory => `${directory}/package.json`),
] as const
readonly tagPrefix = 'dsh-v'
/** Require current artifacts from a complete official client build. */
@@ -84,7 +84,7 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly<Record<string, SentenceContract>> = {
'packages/client/connection': { kind: 'none', reason: 'Browser-side UI plugin layer; registers nothing model-facing.' },
'packages/client/file-upload': { kind: 'none', reason: 'Browser-side request-body transport; registers nothing model-facing.' },
'packages/api/remotes': { kind: 'none', reason: 'The Remote BFF selects business methods and forwarded events; selected services own any model-visible effect.' },
'packages/experimental/agent-team-web-profile': { kind: 'indirect', reason: 'The private Web layer delegates model composition to the Host-side Agent Teams profile.' },
'packages/experimental/agent-team-web-profile': { kind: 'indirect', reason: 'The Web layer delegates model composition to the Host-side Agent Teams profile.' },
'packages/experimental/client-ui-agent-team': { kind: 'none', reason: 'The browser projection and task controls register no model-facing input.' },
'packages/client/ui-layout': { kind: 'none', reason: 'Browser-side UI plugin layer; registers nothing model-facing.' },
'packages/client/ui-dockkit': { kind: 'none', reason: 'Browser-side docking layout engine and components; registers nothing model-facing.' },