mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-11-09 20:07:43 +08:00
fix(forge): classify the panel's Host imports under the published dependency policy
verify-package-dependencies now covers experimental Client packages, and the forge panel's Host face imported four workspace values that no policy entry classified. appendPluginRecord writes through the Session class's private log, and readers recognize a deadline's TimeoutReason only by instanceof, so both need the provider's shared instance. pluginRecordOf and generatedWorktreeName keep no state; classifying them as peer-required keeps the panel's existing Session and worktree peer edges. With the exports classified, the fixer keeps worktree, Session, and timeout as the panel's only workspace peers, moves its type-only relationships to devDependencies and dsh-typert-protocol to dependencies, and regenerates the lockfile and the module graph. verify-plugin-record-callers counts a string literal that spells appendPluginRecord as a caller, so it now admits the dependency policy file, which names the export to classify it and never calls it.
This commit is contained in:
+2
-12
@@ -935,19 +935,9 @@ flowchart TD
|
||||
pkg_experimental_browser_use_stagehand_native --> pkg_browser_use
|
||||
pkg_experimental_browser_use_stagehand_native --> pkg_system_prompt
|
||||
pkg_experimental_browser_use_stagehand_native --> pkg_tools
|
||||
pkg_experimental_client_ui_forge --> pkg_agent
|
||||
pkg_experimental_client_ui_forge --> pkg_agent_controller
|
||||
pkg_experimental_client_ui_forge --> pkg_experimental_forge
|
||||
pkg_experimental_client_ui_forge --> pkg_experimental_forge_session
|
||||
pkg_experimental_client_ui_forge --> pkg_experimental_worktree
|
||||
pkg_experimental_client_ui_forge --> pkg_fs
|
||||
pkg_experimental_client_ui_forge --> pkg_sandbox
|
||||
pkg_experimental_client_ui_forge --> pkg_sandbox_policy
|
||||
pkg_experimental_client_ui_forge --> pkg_session
|
||||
pkg_experimental_client_ui_forge --> pkg_session_projection
|
||||
pkg_experimental_client_ui_forge --> pkg_subprocess
|
||||
pkg_experimental_client_ui_forge --> pkg_typert_protocol
|
||||
pkg_experimental_client_ui_forge --> pkg_working_directory
|
||||
pkg_experimental_client_ui_forge --> pkg_timeout
|
||||
pkg_experimental_computer_use_cua_driver_native --> pkg_computer_use
|
||||
pkg_experimental_computer_use_cua_driver_native --> pkg_system_prompt
|
||||
pkg_experimental_computer_use_cua_driver_native --> pkg_tools
|
||||
@@ -1735,7 +1725,7 @@ flowchart TD
|
||||
| [`experimental-browser-use-chrome-devtools-mcp`](../packages/experimental/browser-use-chrome-devtools-mcp) | `experimental` | [`agent`](../packages/core/agent), [`browser-use`](../packages/browser-use/browser-use), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`experimental-browser-use-playwright-mcp`](../packages/experimental/browser-use-playwright-mcp) | `experimental` | [`agent`](../packages/core/agent), [`browser-use`](../packages/browser-use/browser-use), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`experimental-browser-use-stagehand-native`](../packages/experimental/browser-use-stagehand-native) | `experimental` | [`agent`](../packages/core/agent), [`browser-use`](../packages/browser-use/browser-use), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
|
||||
| [`experimental-client-ui-forge`](../packages/experimental/client-ui-forge) | `experimental` | [`agent`](../packages/core/agent), [`agent-controller`](../packages/core/agent-controller), [`experimental-forge`](../packages/experimental/forge), [`experimental-forge-session`](../packages/experimental/forge-session), [`experimental-worktree`](../packages/experimental/worktree), [`fs`](../packages/fs/fs), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`subprocess`](../packages/subprocess/subprocess), [`typert-protocol`](../packages/typert/protocol), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`experimental-client-ui-forge`](../packages/experimental/client-ui-forge) | `experimental` | [`experimental-worktree`](../packages/experimental/worktree), [`session`](../packages/core/session), [`timeout`](../packages/util/timeout) |
|
||||
| [`experimental-computer-use-cua-driver-native`](../packages/experimental/computer-use-cua-driver-native) | `experimental` | [`computer-use`](../packages/computer-use/computer-use), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
|
||||
| [`experimental-cua-macos`](../packages/experimental/cua-macos) | `experimental` | [`agent`](../packages/core/agent), [`computer-use`](../packages/computer-use/computer-use), [`subprocess`](../packages/subprocess/subprocess), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-questions`](../packages/interaction/user-questions) |
|
||||
| [`experimental-tool-worktree`](../packages/experimental/tool-worktree) | `experimental` | [`experimental-worktree`](../packages/experimental/worktree), [`tools`](../packages/core/tools) |
|
||||
|
||||
+2
-12
@@ -937,19 +937,9 @@ flowchart TD
|
||||
pkg_experimental_browser_use_stagehand_native --> pkg_browser_use
|
||||
pkg_experimental_browser_use_stagehand_native --> pkg_system_prompt
|
||||
pkg_experimental_browser_use_stagehand_native --> pkg_tools
|
||||
pkg_experimental_client_ui_forge --> pkg_agent
|
||||
pkg_experimental_client_ui_forge --> pkg_agent_controller
|
||||
pkg_experimental_client_ui_forge --> pkg_experimental_forge
|
||||
pkg_experimental_client_ui_forge --> pkg_experimental_forge_session
|
||||
pkg_experimental_client_ui_forge --> pkg_experimental_worktree
|
||||
pkg_experimental_client_ui_forge --> pkg_fs
|
||||
pkg_experimental_client_ui_forge --> pkg_sandbox
|
||||
pkg_experimental_client_ui_forge --> pkg_sandbox_policy
|
||||
pkg_experimental_client_ui_forge --> pkg_session
|
||||
pkg_experimental_client_ui_forge --> pkg_session_projection
|
||||
pkg_experimental_client_ui_forge --> pkg_subprocess
|
||||
pkg_experimental_client_ui_forge --> pkg_typert_protocol
|
||||
pkg_experimental_client_ui_forge --> pkg_working_directory
|
||||
pkg_experimental_client_ui_forge --> pkg_timeout
|
||||
pkg_experimental_computer_use_cua_driver_native --> pkg_computer_use
|
||||
pkg_experimental_computer_use_cua_driver_native --> pkg_system_prompt
|
||||
pkg_experimental_computer_use_cua_driver_native --> pkg_tools
|
||||
@@ -1737,7 +1727,7 @@ flowchart TD
|
||||
| [`experimental-browser-use-chrome-devtools-mcp`](../packages/experimental/browser-use-chrome-devtools-mcp) | `experimental` | [`agent`](../packages/core/agent), [`browser-use`](../packages/browser-use/browser-use), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`experimental-browser-use-playwright-mcp`](../packages/experimental/browser-use-playwright-mcp) | `experimental` | [`agent`](../packages/core/agent), [`browser-use`](../packages/browser-use/browser-use), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`experimental-browser-use-stagehand-native`](../packages/experimental/browser-use-stagehand-native) | `experimental` | [`agent`](../packages/core/agent), [`browser-use`](../packages/browser-use/browser-use), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
|
||||
| [`experimental-client-ui-forge`](../packages/experimental/client-ui-forge) | `experimental` | [`agent`](../packages/core/agent), [`agent-controller`](../packages/core/agent-controller), [`experimental-forge`](../packages/experimental/forge), [`experimental-forge-session`](../packages/experimental/forge-session), [`experimental-worktree`](../packages/experimental/worktree), [`fs`](../packages/fs/fs), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`subprocess`](../packages/subprocess/subprocess), [`typert-protocol`](../packages/typert/protocol), [`working-directory`](../packages/session/working-directory) |
|
||||
| [`experimental-client-ui-forge`](../packages/experimental/client-ui-forge) | `experimental` | [`experimental-worktree`](../packages/experimental/worktree), [`session`](../packages/core/session), [`timeout`](../packages/util/timeout) |
|
||||
| [`experimental-computer-use-cua-driver-native`](../packages/experimental/computer-use-cua-driver-native) | `experimental` | [`computer-use`](../packages/computer-use/computer-use), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
|
||||
| [`experimental-cua-macos`](../packages/experimental/cua-macos) | `experimental` | [`agent`](../packages/core/agent), [`computer-use`](../packages/computer-use/computer-use), [`subprocess`](../packages/subprocess/subprocess), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-questions`](../packages/interaction/user-questions) |
|
||||
| [`experimental-tool-worktree`](../packages/experimental/tool-worktree) | `experimental` | [`experimental-worktree`](../packages/experimental/worktree), [`tools`](../packages/core/tools) |
|
||||
|
||||
@@ -57,25 +57,15 @@
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@deepseek-ai/cordis": "workspace:~",
|
||||
"@deepseek-ai/dsh-agent": "workspace:*",
|
||||
"@deepseek-ai/dsh-agent-controller": "workspace:*",
|
||||
"@deepseek-ai/dsh-experimental-forge": "workspace:*",
|
||||
"@deepseek-ai/dsh-experimental-forge-session": "workspace:*",
|
||||
"@deepseek-ai/dsh-experimental-worktree": "workspace:*",
|
||||
"@deepseek-ai/dsh-fs": "workspace:*",
|
||||
"@deepseek-ai/dsh-sandbox": "workspace:*",
|
||||
"@deepseek-ai/dsh-sandbox-policy": "workspace:*",
|
||||
"@deepseek-ai/dsh-session": "workspace:*",
|
||||
"@deepseek-ai/dsh-session-projection": "workspace:*",
|
||||
"@deepseek-ai/dsh-subprocess": "workspace:*",
|
||||
"@deepseek-ai/dsh-typert-protocol": "workspace:*",
|
||||
"@deepseek-ai/dsh-working-directory": "workspace:*"
|
||||
"@deepseek-ai/dsh-timeout": "workspace:*"
|
||||
},
|
||||
"dependencies": {
|
||||
"@deepseek-ai/schemastery": "workspace:~",
|
||||
"@deepseek-ai/dsh-timeout": "workspace:*",
|
||||
"@deepseek-ai/dsh-util-values": "workspace:*",
|
||||
"zod": "^4.4.3"
|
||||
"zod": "^4.4.3",
|
||||
"@deepseek-ai/dsh-typert-protocol": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@deepseek-ai/cordis": "workspace:~",
|
||||
@@ -109,13 +99,13 @@
|
||||
"@deepseek-ai/dsh-subprocess": "workspace:*",
|
||||
"@deepseek-ai/dsh-subprocess-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-system-prompt": "workspace:*",
|
||||
"@deepseek-ai/dsh-typert-protocol": "workspace:*",
|
||||
"@deepseek-ai/dsh-util-workspace-path": "workspace:*",
|
||||
"@deepseek-ai/dsh-working-directory": "workspace:*",
|
||||
"@testing-library/react": "^16.3.3",
|
||||
"clsx": "^2.1.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react-dom": "^18.2.0",
|
||||
"@deepseek-ai/dsh-timeout": "workspace:*"
|
||||
},
|
||||
"files": [
|
||||
"locale/*.json",
|
||||
|
||||
Generated
+4
-4
@@ -8400,9 +8400,9 @@ importers:
|
||||
|
||||
packages/experimental/client-ui-forge:
|
||||
dependencies:
|
||||
'@deepseek-ai/dsh-timeout':
|
||||
'@deepseek-ai/dsh-typert-protocol':
|
||||
specifier: workspace:*
|
||||
version: link:../../util/timeout
|
||||
version: link:../../typert/protocol
|
||||
'@deepseek-ai/dsh-util-values':
|
||||
specifier: workspace:*
|
||||
version: link:../../util/values
|
||||
@@ -8506,9 +8506,9 @@ importers:
|
||||
'@deepseek-ai/dsh-system-prompt':
|
||||
specifier: workspace:*
|
||||
version: link:../../core/system-prompt
|
||||
'@deepseek-ai/dsh-typert-protocol':
|
||||
'@deepseek-ai/dsh-timeout':
|
||||
specifier: workspace:*
|
||||
version: link:../../typert/protocol
|
||||
version: link:../../util/timeout
|
||||
'@deepseek-ai/dsh-util-workspace-path':
|
||||
specifier: workspace:*
|
||||
version: link:../../util/workspace-path
|
||||
|
||||
@@ -68,9 +68,14 @@ const PEER_REQUIRED_HOST_EXPORTS = {
|
||||
'@deepseek-ai/dsh-user-questions': ['UserQuestionError'],
|
||||
// `instanceof` checks need the translator's own class instance.
|
||||
'@deepseek-ai/dsh-experimental-translator': ['TranslationError'],
|
||||
// Stateless; a safe classification would turn the forge panel's worktree peer into a dependency.
|
||||
'@deepseek-ai/dsh-experimental-worktree': ['generatedWorktreeName'],
|
||||
'@deepseek-ai/dsh-scope': ['carrierKeyOf', 'createScope', 'scopeOf', 'scopeTarget'],
|
||||
'@deepseek-ai/dsh-session': ['SESSION_FORMAT_VERSION'],
|
||||
// appendPluginRecord writes through the Session class's private log; pluginRecordOf is stateless.
|
||||
'@deepseek-ai/dsh-session': ['SESSION_FORMAT_VERSION', 'appendPluginRecord', 'pluginRecordOf'],
|
||||
'@deepseek-ai/dsh-session-persistence': ['SessionPersistenceNotFoundError'],
|
||||
// Readers recognize a deadline's TimeoutReason only by `instanceof` against their own copy.
|
||||
'@deepseek-ai/dsh-timeout': ['deadline'],
|
||||
} as const satisfies HostDependencyExports
|
||||
|
||||
/** Exact import specifier to reviewed runtime exports. */
|
||||
|
||||
@@ -247,6 +247,11 @@ describe('package dependency scope', () => {
|
||||
expect(PACKAGE_DEPENDENCY_POLICY.peerRequiredHostExports['@deepseek-ai/dsh-typert-protocol']).toBeUndefined()
|
||||
expect(PACKAGE_DEPENDENCY_POLICY.peerRequiredHostExports['@deepseek-ai/dsh-experimental-translator'])
|
||||
.toEqual(['TranslationError'])
|
||||
expect(PACKAGE_DEPENDENCY_POLICY.peerRequiredHostExports['@deepseek-ai/dsh-experimental-worktree'])
|
||||
.toEqual(['generatedWorktreeName'])
|
||||
expect(PACKAGE_DEPENDENCY_POLICY.peerRequiredHostExports['@deepseek-ai/dsh-session'])
|
||||
.toEqual(['SESSION_FORMAT_VERSION', 'appendPluginRecord', 'pluginRecordOf'])
|
||||
expect(PACKAGE_DEPENDENCY_POLICY.peerRequiredHostExports['@deepseek-ai/dsh-timeout']).toEqual(['deadline'])
|
||||
})
|
||||
|
||||
it('discovers the Client directory, dsh.client declarations, and configured Host packages', () => {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { afterEach, describe, expect, it } from 'vitest'
|
||||
import {
|
||||
checkDeclaredPluginRecordWrites,
|
||||
checkPluginRecordCallers,
|
||||
DEPENDENCY_POLICY_FILE,
|
||||
findPluginRecordReferences,
|
||||
isAdmittedCaller,
|
||||
OWNER_FILE,
|
||||
@@ -132,10 +133,11 @@ describe('verify-plugin-record-callers', () => {
|
||||
expect(checkPluginRecordCallers(corpus(source))).toEqual([])
|
||||
})
|
||||
|
||||
it('admits experimental source, the owner, tests, and this gate', () => {
|
||||
it('admits experimental source, the owner, tests, this gate, and the dependency policy', () => {
|
||||
for (const file of [
|
||||
EXPERIMENTAL,
|
||||
OWNER_FILE,
|
||||
DEPENDENCY_POLICY_FILE,
|
||||
'packages/session/session-persistence/tests/live-write-contract.ts',
|
||||
'apps/web/tests/session.e2e.ts',
|
||||
'examples/demo/tests/demo.spec.ts',
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
* `appendPluginRecord` in `@deepseek-ai/dsh-session` appends an ignorable `plugin:` record that the
|
||||
* experimental persistence catalogue lists and that a Session format migration keeps only on a best-effort
|
||||
* basis. Experimental packages may rely on that; a release package must declare its events instead.
|
||||
* The owning module and test files, which exercise the operation, are exempt.
|
||||
* The owning module and test files, which exercise the operation, are exempt, as is the published
|
||||
* dependency policy, which names the function to classify the export without calling it.
|
||||
*
|
||||
* Discovery is syntax-aware: every identifier spelled `appendPluginRecord` counts — an import, a
|
||||
* named re-export, a call, a namespace member, a destructured binding, or an alias source — and so
|
||||
@@ -42,6 +43,9 @@ const GATE_FILES: ReadonlySet<string> = new Set([
|
||||
'scripts/verify-plugin-record-callers.spec.ts',
|
||||
])
|
||||
|
||||
/** The published dependency policy names the restricted function to classify the export's package edge. */
|
||||
export const DEPENDENCY_POLICY_FILE = 'scripts/package-dependency-policy.ts'
|
||||
|
||||
const SOURCE_EXTENSION = /\.(?:[cm]?[jt]s|[jt]sx)$/u
|
||||
|
||||
/** A line continuation, which a string or template literal drops from its value. */
|
||||
@@ -99,10 +103,11 @@ export function isTestFile(file: string): boolean {
|
||||
/**
|
||||
* Whether a file may reference the restricted function.
|
||||
* @param file - repository-relative path, in POSIX separators.
|
||||
* @returns whether the file is experimental source, the owner, a test, or this gate.
|
||||
* @returns whether the file is experimental source, the owner, a test, this gate, or the dependency policy.
|
||||
*/
|
||||
export function isAdmittedCaller(file: string): boolean {
|
||||
return file.startsWith(EXPERIMENTAL_PREFIX) || file === OWNER_FILE || isTestFile(file) || GATE_FILES.has(file)
|
||||
|| file === DEPENDENCY_POLICY_FILE
|
||||
}
|
||||
|
||||
function scriptKind(file: string): ts.ScriptKind {
|
||||
|
||||
Reference in New Issue
Block a user