Merge remote-tracking branch 'origin/master' into feat/pwsh-persistent-pty

This commit is contained in:
_Kerman
2026-08-18 16:47:45 +08:00
110 changed files with 8967 additions and 148 deletions
@@ -0,0 +1,67 @@
/** Experimental-package publication and dependency constraints. */
import { describe, expect, it } from 'vitest'
import {
checkExperimentalDependencyIsolation,
checkExperimentalManifest,
type WorkspaceManifest,
} from './check-workspace-constraints.ts'
const experimental: WorkspaceManifest = {
dir: 'packages/experimental/prototype',
manifest: { name: '@deepseek-ai/dsh-prototype', private: true },
}
describe('experimental workspace constraints', () => {
it('requires private manifests without publication metadata', () => {
expect(checkExperimentalManifest(experimental)).toEqual([])
expect(checkExperimentalManifest({
...experimental,
manifest: { ...experimental.manifest, private: false, publishConfig: { access: 'public' } },
})).toEqual([
'@deepseek-ai/dsh-prototype: experimental package must set "private": true',
'@deepseek-ai/dsh-prototype: experimental package must omit publishConfig',
])
})
it.each(['dependencies', 'optionalDependencies', 'peerDependencies'] as const)(
'rejects release %s on an experimental package',
(section) => {
expect(checkExperimentalDependencyIsolation([experimental, {
dir: 'packages/core/consumer',
manifest: {
name: '@deepseek-ai/dsh-consumer',
[section]: { '@deepseek-ai/dsh-prototype': 'workspace:^' },
},
}])).toEqual([
`@deepseek-ai/dsh-consumer: ${section}.@deepseek-ai/dsh-prototype must not reference an experimental package`,
])
},
)
it('allows development and experimental consumers but rejects the Python release runtime', () => {
const manifests: WorkspaceManifest[] = [experimental, {
dir: 'packages/core/test-only',
manifest: {
name: '@deepseek-ai/dsh-test-only',
devDependencies: { '@deepseek-ai/dsh-prototype': 'workspace:^' },
},
}, {
dir: 'packages/experimental/consumer',
manifest: {
name: '@deepseek-ai/dsh-experimental-consumer',
dependencies: { '@deepseek-ai/dsh-prototype': 'workspace:^' },
},
}, {
dir: 'python/sdk-runtime',
manifest: {
name: '@deepseek-ai/dsh-python-runtime',
dependencies: { '@deepseek-ai/dsh-prototype': 'workspace:^' },
},
}]
expect(checkExperimentalDependencyIsolation(manifests)).toEqual([
'@deepseek-ai/dsh-python-runtime: dependencies.@deepseek-ai/dsh-prototype must not reference an experimental package',
])
})
})
+64 -16
View File
@@ -7,6 +7,7 @@
import { existsSync, readdirSync, readFileSync } from 'node:fs'
import { join, relative, resolve } from 'node:path'
import { pathToFileURL } from 'node:url'
import { hasTypertRemoteNavigation, isForbiddenPublicationFile } from './publication-payload.ts'
import { collectProjectReferenceFaceViolations } from './project-reference-faces.ts'
@@ -47,8 +48,10 @@ 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. */
const experimentalPackageDirectory = /^packages\/experimental\/[^/]+$/
/** Directories whose packages this repository publishes: one release member each. */
const releaseMemberDirectory = /^(?:packages\/[^/]+\/[^/]+|apps\/[^/]+|vendor\/[^/]+)$/
const releaseMemberDirectory = /^(?:packages\/(?!experimental\/)[^/]+\/[^/]+|apps\/[^/]+|vendor\/[^/]+)$/
const localArtifactDirs = new Set(['node_modules'])
const appPackageFiles: Readonly<Record<string, readonly string[]>> = {
@@ -59,7 +62,7 @@ const appPackageFiles: Readonly<Record<string, readonly string[]>> = {
}
/** The subset of package.json fields this constraint check cares about. */
interface PackageManifest {
export interface PackageManifest {
name?: string
version?: string
private?: boolean
@@ -87,7 +90,7 @@ interface PackageManifest {
}
/** One workspace manifest and its repo-relative path. */
interface WorkspaceManifest {
export interface WorkspaceManifest {
dir: string
manifest: PackageManifest
}
@@ -228,8 +231,18 @@ function usesEmittedTreeDefaults(manifest: PackageManifest): boolean {
exportDefault(manifest, subpath)?.startsWith('./lib/types/') === true)
}
function checkWorkspace({ dir, manifest }: WorkspaceManifest): string[] {
/** Experimental manifest requirements enforced independently from release metadata. */
export function checkExperimentalManifest({ dir, manifest }: WorkspaceManifest): string[] {
if (!experimentalPackageDirectory.test(dir)) return []
const label = manifest.name ?? dir
const errors: string[] = []
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 checkWorkspace({ dir, manifest }: WorkspaceManifest): string[] {
const errors = checkExperimentalManifest({ dir, manifest })
const label = manifest.name ?? dir
const isLandlockPackageDir = dir.startsWith('native/landlock-run/packages/')
const isPublicLandlockPackage = isLandlockPackageDir
@@ -271,7 +284,7 @@ function checkWorkspace({ dir, manifest }: WorkspaceManifest): string[] {
|| manifest.repository.directory !== dir) {
errors.push(`${label}: release member repository must use ${publishedRepositoryUrl} with directory ${dir}`)
}
} else if (manifest.private !== true) {
} else if (!experimentalPackageDirectory.test(dir) && manifest.private !== true) {
errors.push(`${label}: package.json must set "private": true`)
}
@@ -390,6 +403,31 @@ function checkRepositoryVersion(): string[] {
/** Dependency sections whose ranges reach a published tarball or a local install. */
const dependencySections = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'] as const
/** Dependency sections present in an installed runtime. */
const runtimeDependencySections = ['dependencies', 'optionalDependencies', 'peerDependencies'] as const
/**
* Prevent an official runtime from requiring a package its release omits.
* @param manifests - release, private experimental, and deployment-root manifests.
* @returns One error for each forbidden runtime dependency.
*/
export function checkExperimentalDependencyIsolation(manifests: readonly WorkspaceManifest[]): string[] {
const experimentalNames = new Set(manifests
.filter(entry => experimentalPackageDirectory.test(entry.dir))
.map(entry => entry.manifest.name)
.filter(name => name !== undefined))
const errors: string[] = []
for (const { dir, manifest } of manifests) {
if (!releaseMemberDirectory.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
errors.push(`${manifest.name ?? dir}: ${section}.${name} must not reference an experimental package`)
}
}
}
return errors
}
/**
* Require the `workspace:` protocol for every reference to a workspace member.
@@ -415,15 +453,25 @@ function checkWorkspaceProtocol(manifests: readonly WorkspaceManifest[]): string
return errors
}
const manifests = workspaceManifests()
const errors = [
...checkRepositoryVersion(),
...manifests.flatMap(checkWorkspace),
...checkWorkspaceProtocol(manifests),
...checkHierarchyShape(),
...collectProjectReferenceFaceViolations(root),
]
if (errors.length > 0) {
console.error(errors.join('\n'))
process.exitCode = 1
/** Run the repository constraint gate. */
export function main(): void {
const manifests = workspaceManifests()
const dependencyManifests = [
...manifests,
{ dir: 'python/sdk-runtime', manifest: readJson(join(root, 'python/sdk-runtime/package.json')) },
]
const errors = [
...checkRepositoryVersion(),
...manifests.flatMap(checkWorkspace),
...checkWorkspaceProtocol(manifests),
...checkExperimentalDependencyIsolation(dependencyManifests),
...checkHierarchyShape(),
...collectProjectReferenceFaceViolations(root),
]
if (errors.length > 0) {
console.error(errors.join('\n'))
process.exitCode = 1
}
}
if (process.argv[1] !== undefined && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) main()
+13
View File
@@ -97,6 +97,7 @@ export const SERVICE_PAGE: Record<string, string> = {
systemPrompt: 'system-prompt.md',
jobs: 'jobs.md',
sessionTelemetry: 'session-telemetry.md',
teams: 'team.md',
tokenMeter: 'token-meter.md',
toolResultPruner: 'compaction.md',
tools: 'tools.md',
@@ -423,6 +424,18 @@ export const LINK_MAP: Readonly<Record<string, string>> = {
JobSnapshot: 'jobs.md',
JobStart: 'jobs.md',
JobsChangedListener: 'jobs.md',
CreateTeamTaskRequest: 'team.md',
SendTeamMessageRequest: 'team.md',
SendTeamMessageResult: 'team.md',
SpawnTeammateRequest: 'team.md',
SpawnTeammateResult: 'team.md',
TeamId: 'team.md',
TeamMemberView: 'team.md',
TeamMembership: 'team.md',
TeamTaskId: 'team.md',
TeamTaskView: 'team.md',
TeamWaitResult: 'team.md',
UpdateTeamTaskRequest: 'team.md',
TokenMeasurement: 'token-meter.md',
CodeDispatchLog: 'tools.md',
PostToolDecision: 'tools.md',
+9
View File
@@ -67,6 +67,7 @@ const GROUP_ORDER = [
'core',
'typert',
'goal',
'experimental',
'process',
'bash',
'pty',
@@ -469,6 +470,14 @@ const SERVICE_ROLES: ServiceRole[] = [
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.',
},
{
key: 'teams',
pkg: 'team',
title: 'Agent Teams coordination domain',
mode: 'core',
consumers: ['tool-team'],
note: 'Owns the implicit-root roster, durable peer mailbox, shared task DAG, and continuable-child lifecycle; tool-team contributes the scoped model policy and controls.',
},
{
key: 'jobs',
pkg: 'jobs',
+5
View File
@@ -52,6 +52,11 @@ const LINK_MAP: Record<string, string> = {
SessionTitleModelProvenance: 'session-title.md',
SessionTitleProviderId: 'session-title.md',
SessionTitleSource: 'session-title.md',
TeamId: 'team.md',
TeamMemberSnapshot: 'team.md',
TeamMessageId: 'team.md',
TeamMessageSnapshot: 'team.md',
TeamTaskSnapshot: 'team.md',
}
/** One log event, extracted from a `SessionEventMap` declaration. */
+40
View File
@@ -58,6 +58,8 @@ import * as ToolLsp from '@deepseek-ai/dsh-tool-lsp'
import * as ToolSkill from '@deepseek-ai/dsh-tool-skill'
import * as ToolSessionQuery from '@deepseek-ai/dsh-tool-session-query'
import * as ToolTasks from '@deepseek-ai/dsh-tool-jobs'
import type TeamService from '@deepseek-ai/dsh-team'
import * as ToolTeam from '@deepseek-ai/dsh-tool-team'
import * as ToolTodo from '@deepseek-ai/dsh-tool-todo'
import * as ToolSubagent from '@deepseek-ai/dsh-tool-subagent'
import * as ToolWeb from '@deepseek-ai/dsh-tool-web'
@@ -521,6 +523,44 @@ const TOOL_PACKAGES: ToolPackage[] = [
note:
'The kind-agnostic background-job controller: background bash commands, PTY sends, and subagents are read, listed, and killed through the same three tools. Loading the plugin attaches the controller that arms producers\' `ctx.jobs.start()`.',
},
{
pkg: '@deepseek-ai/dsh-tool-team',
dir: 'tool-team',
source: 'packages/experimental/tool-team/src/index.ts',
requires: ['ctx.tools', 'ctx.systemPrompt', 'ctx.teams', 'an exact live Team member Agent'],
writes: ['tool/call', 'team/member', 'team/message/queued', 'team/message/delivered', 'team/task', 'tool/result'],
async mount(ctx) {
await ctx.plugin(AgentRegistry)
await ctx.plugin(SessionStore)
const session = ctx.sessions.create(SessionId('tool-catalog-team-lead'))
let agent!: Agent
const membership = {
get root() { return agent },
id: session.id,
role: 'lead' as const,
name: 'lead',
}
ctx.provide('teams', {
tryMembership: (candidate: Agent) => candidate === agent ? membership : undefined,
membership: () => membership,
} as unknown as TeamService)
await ctx.plugin(Object.assign((inner: Context) => {
agent = {
id: session.id,
session,
options: {},
status: 'idle',
} as unknown as Agent
Object.assign(agent, { ctx: createScope(inner, agent).ctx })
inner.agents.register(agent)
}, { inject: ['tools', 'systemPrompt', 'agents', 'teams'] }))
await ctx.plugin(ToolTeam)
catalogChildScopes.set(ctx, agent)
},
scope: ctx => catalogChildScopes.get(ctx) as Agent,
note:
'All ten tools are scoped to implicit Team Leads and durable teammates. The shipped dsh-base bundle keeps the package disabled; the documented Agent Teams profile patch enables it while disabling the legacy continuable-child control names.',
},
{
pkg: '@deepseek-ai/dsh-tool-todo',
dir: 'tool-todo',
+1 -1
View File
@@ -24,7 +24,7 @@ const DEFAULT_REGISTRY = 'https://registry.npm.harnessment.com'
const DEFAULT_OUTPUT_DIRECTORY = '.artifacts/npm-baseline'
const PACKAGE_PATTERNS = [
'vendor/*/package.json',
'packages/*/*/package.json',
'packages/!(experimental)/*/package.json',
'apps/*/package.json',
] as const
const DEPENDENCY_SECTIONS = [
+8
View File
@@ -1,5 +1,6 @@
/** Release family discovery, publish order, tag naming, and the bump judgements. */
import { resolve } from 'node:path'
import { describe, expect, it } from 'vitest'
import { releaseFamily, type ReleaseMember } from './families.ts'
import { compareVersions, nextVendorVersion, reachesPayload } from './bump.ts'
@@ -16,6 +17,13 @@ function member(directory: string, name: string, manifest: Record<string, unknow
}
describe('release families', () => {
it('excludes private experimental packages from the dsh release', () => {
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-team')
})
it('names one tag for the whole dsh family and one per vendored package', () => {
const dsh = releaseFamily('dsh')
const vendor = releaseFamily('vendor')
+2 -2
View File
@@ -305,10 +305,10 @@ export abstract class ReleaseFamily {
abstract readonly installedEntry: InstalledEntry | undefined
}
/** `packages/*` and `apps/*`: one shared version across the whole family. */
/** Release packages and apps: one shared version across the whole family. */
class DshFamily extends ReleaseFamily {
readonly id = 'dsh'
readonly patterns = ['packages/*/*/package.json', 'apps/*/package.json'] as const
readonly patterns = ['packages/!(experimental)/*/package.json', 'apps/*/package.json'] as const
readonly tagPrefix = 'dsh-v'
/**
+20
View File
@@ -301,6 +301,26 @@
"symbol": "ScheduleView",
"source": "packages/schedule/schedule/src/types.ts"
},
{
"doc": "docs/subsystems/team.md",
"symbol": "TeamMemberSnapshot",
"source": "packages/experimental/team/src/types.ts"
},
{
"doc": "docs/subsystems/team.md",
"symbol": "TeamMessageSnapshot",
"source": "packages/experimental/team/src/types.ts"
},
{
"doc": "docs/subsystems/team.md",
"symbol": "TeamMessageSource",
"source": "packages/experimental/team/src/types.ts"
},
{
"doc": "docs/subsystems/team.md",
"symbol": "TeamTaskSnapshot",
"source": "packages/experimental/team/src/types.ts"
},
{
"doc": "docs/subsystems/commands.md",
"symbol": "CommandInputDescriptor",