fix(test): declare Loader fixture dependencies

This commit is contained in:
Tianyi Cui
2026-08-24 22:02:44 +08:00
parent 4125514a08
commit 3b090c3c1b
13 changed files with 502 additions and 67 deletions
+49
View File
@@ -261,6 +261,13 @@
"project": [ "project": [
"src/**/*.ts", "src/**/*.ts",
"tests/**/*.ts" "tests/**/*.ts"
],
"ignoreDependencies": [
"@deepseek-ai/dsh-agent-spine-demo",
"@deepseek-ai/dsh-bash-local",
"@deepseek-ai/dsh-session-checkpoint-policy",
"@deepseek-ai/dsh-session-persistence-jsonl",
"@deepseek-ai/dsh-subprocess-local"
] ]
}, },
"packages/lsp/lsp-stdio": { "packages/lsp/lsp-stdio": {
@@ -296,6 +303,14 @@
"project": [ "project": [
"src/**/*.ts", "src/**/*.ts",
"tests/**/*.ts" "tests/**/*.ts"
],
"ignoreDependencies": [
"@deepseek-ai/cordis-plugin-logger-console",
"@deepseek-ai/dsh-agent-spine-demo",
"@deepseek-ai/dsh-bash-local",
"@deepseek-ai/dsh-session-checkpoint-policy",
"@deepseek-ai/dsh-session-persistence-jsonl",
"@deepseek-ai/dsh-subprocess-local"
] ]
}, },
"packages/util/brand": { "packages/util/brand": {
@@ -347,6 +362,13 @@
"project": [ "project": [
"src/**/*.ts", "src/**/*.ts",
"tests/**/*.ts" "tests/**/*.ts"
],
"ignoreDependencies": [
"@deepseek-ai/dsh-agent-spine-demo",
"@deepseek-ai/dsh-bash-local",
"@deepseek-ai/dsh-session-checkpoint-policy",
"@deepseek-ai/dsh-session-persistence-jsonl",
"@deepseek-ai/dsh-subprocess-local"
] ]
}, },
"packages/session-query/session-query-sqlite": { "packages/session-query/session-query-sqlite": {
@@ -531,6 +553,12 @@
"project": [ "project": [
"src/**/*.ts", "src/**/*.ts",
"tests/**/*.ts" "tests/**/*.ts"
],
"ignoreDependencies": [
"@deepseek-ai/dsh-agent-spine-demo",
"@deepseek-ai/dsh-session-checkpoint-policy",
"@deepseek-ai/dsh-session-persistence-jsonl",
"@deepseek-ai/dsh-tool-subagent"
] ]
}, },
"packages/subagent/subagent-codex": { "packages/subagent/subagent-codex": {
@@ -542,6 +570,12 @@
"project": [ "project": [
"src/**/*.ts", "src/**/*.ts",
"tests/**/*.ts" "tests/**/*.ts"
],
"ignoreDependencies": [
"@deepseek-ai/dsh-agent-spine-demo",
"@deepseek-ai/dsh-session-checkpoint-policy",
"@deepseek-ai/dsh-session-persistence-jsonl",
"@deepseek-ai/dsh-tool-subagent"
] ]
}, },
"packages/subagent/subagent-claude-code": { "packages/subagent/subagent-claude-code": {
@@ -553,6 +587,13 @@
"project": [ "project": [
"src/**/*.ts", "src/**/*.ts",
"tests/**/*.ts" "tests/**/*.ts"
],
"ignoreDependencies": [
"@deepseek-ai/dsh-agent-spine-demo",
"@deepseek-ai/dsh-session-checkpoint-policy",
"@deepseek-ai/dsh-session-persistence-jsonl",
"@deepseek-ai/dsh-subagent-codex",
"@deepseek-ai/dsh-tool-subagent"
] ]
}, },
"packages/fs/tool-fs": { "packages/fs/tool-fs": {
@@ -642,6 +683,14 @@
"project": [ "project": [
"src/**/*.ts", "src/**/*.ts",
"tests/**/*.ts" "tests/**/*.ts"
],
"ignoreDependencies": [
"@deepseek-ai/dsh-agent-instructions",
"@deepseek-ai/dsh-agent-spine-demo",
"@deepseek-ai/dsh-llm-deepseek",
"@deepseek-ai/dsh-session-checkpoint-policy",
"@deepseek-ai/dsh-session-persistence-jsonl",
"@deepseek-ai/dsh-tool-subagent"
] ]
}, },
"packages/shell/tool-pwsh": { "packages/shell/tool-pwsh": {
@@ -44,10 +44,16 @@
"@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^",
"@deepseek-ai/dsh-agent-loop": "workspace:^", "@deepseek-ai/dsh-agent-loop": "workspace:^",
"@deepseek-ai/dsh-agent-loop-testkit": "workspace:^", "@deepseek-ai/dsh-agent-loop-testkit": "workspace:^",
"@deepseek-ai/dsh-agent-spine-demo": "workspace:^",
"@deepseek-ai/dsh-app-boot": "workspace:^",
"@deepseek-ai/dsh-bash-local": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^",
"@deepseek-ai/dsh-loader-smoke": "workspace:^", "@deepseek-ai/dsh-loader-smoke": "workspace:^",
"@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^",
"@deepseek-ai/dsh-session-checkpoint-policy": "workspace:^",
"@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^",
"@deepseek-ai/dsh-subprocess-local": "workspace:^",
"@deepseek-ai/dsh-system-prompt": "workspace:^", "@deepseek-ai/dsh-system-prompt": "workspace:^",
"@deepseek-ai/dsh-tools": "workspace:^", "@deepseek-ai/dsh-tools": "workspace:^",
"@deepseek-ai/cordis": "workspace:^" "@deepseek-ai/cordis": "workspace:^"
+10
View File
@@ -40,9 +40,19 @@
"@deepseek-ai/schemastery": "workspace:^" "@deepseek-ai/schemastery": "workspace:^"
}, },
"devDependencies": { "devDependencies": {
"@deepseek-ai/dsh-agent": "workspace:^",
"@deepseek-ai/dsh-app-boot": "workspace:^",
"@deepseek-ai/dsh-bash-local": "workspace:^",
"@deepseek-ai/dsh-fs-e2b": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-loader-smoke": "workspace:^", "@deepseek-ai/dsh-loader-smoke": "workspace:^",
"@deepseek-ai/dsh-lsp": "workspace:^",
"@deepseek-ai/dsh-lsp-stdio": "workspace:^",
"@deepseek-ai/dsh-sandbox-policy": "workspace:^", "@deepseek-ai/dsh-sandbox-policy": "workspace:^",
"@deepseek-ai/dsh-session": "workspace:^",
"@deepseek-ai/dsh-subprocess-e2b": "workspace:^",
"@deepseek-ai/dsh-terminal": "workspace:^",
"@deepseek-ai/dsh-terminal-bash": "workspace:^",
"@deepseek-ai/cordis": "workspace:^" "@deepseek-ai/cordis": "workspace:^"
} }
} }
+5
View File
@@ -69,6 +69,8 @@
}, },
"devDependencies": { "devDependencies": {
"@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^",
"@deepseek-ai/dsh-agent-spine-demo": "workspace:^",
"@deepseek-ai/dsh-bash-local": "workspace:^",
"@deepseek-ai/dsh-session-projection": "workspace:^", "@deepseek-ai/dsh-session-projection": "workspace:^",
"@deepseek-ai/dsh-brand": "workspace:^", "@deepseek-ai/dsh-brand": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^",
@@ -76,6 +78,9 @@
"@deepseek-ai/dsh-loader-smoke": "workspace:^", "@deepseek-ai/dsh-loader-smoke": "workspace:^",
"@deepseek-ai/dsh-scope": "workspace:^", "@deepseek-ai/dsh-scope": "workspace:^",
"@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^",
"@deepseek-ai/dsh-session-checkpoint-policy": "workspace:^",
"@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^",
"@deepseek-ai/dsh-subprocess-local": "workspace:^",
"@deepseek-ai/dsh-typert-protocol": "workspace:^", "@deepseek-ai/dsh-typert-protocol": "workspace:^",
"@deepseek-ai/cordis": "workspace:^" "@deepseek-ai/cordis": "workspace:^"
} }
@@ -50,12 +50,20 @@
"@deepseek-ai/cordis": "workspace:^" "@deepseek-ai/cordis": "workspace:^"
}, },
"devDependencies": { "devDependencies": {
"@deepseek-ai/cordis-plugin-logger-console": "workspace:^",
"@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/cordis-plugin-loader": "workspace:^",
"@deepseek-ai/dsh-agent-spine-demo": "workspace:^",
"@deepseek-ai/dsh-app-boot": "workspace:^",
"@deepseek-ai/dsh-bash-local": "workspace:^",
"@deepseek-ai/dsh-command-feedback": "workspace:^", "@deepseek-ai/dsh-command-feedback": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^",
"@deepseek-ai/dsh-loader-smoke": "workspace:^",
"@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^",
"@deepseek-ai/dsh-session-checkpoint-policy": "workspace:^",
"@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^",
"@deepseek-ai/dsh-session-telemetry": "workspace:^", "@deepseek-ai/dsh-session-telemetry": "workspace:^",
"@deepseek-ai/dsh-subprocess-local": "workspace:^",
"@deepseek-ai/dsh-anonymous-user-id": "workspace:^", "@deepseek-ai/dsh-anonymous-user-id": "workspace:^",
"@deepseek-ai/cordis": "workspace:^" "@deepseek-ai/cordis": "workspace:^"
} }
+1
View File
@@ -50,6 +50,7 @@
}, },
"devDependencies": { "devDependencies": {
"@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^",
"@deepseek-ai/dsh-app-boot": "workspace:^",
"@deepseek-ai/dsh-shell": "workspace:^", "@deepseek-ai/dsh-shell": "workspace:^",
"@deepseek-ai/dsh-shell-env": "workspace:^", "@deepseek-ai/dsh-shell-env": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^",
@@ -48,14 +48,19 @@
"devDependencies": { "devDependencies": {
"@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/cordis-plugin-loader": "workspace:^",
"@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^",
"@deepseek-ai/dsh-agent-spine-demo": "workspace:^",
"@deepseek-ai/dsh-app-boot": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^",
"@deepseek-ai/dsh-loader-smoke": "workspace:^", "@deepseek-ai/dsh-loader-smoke": "workspace:^",
"@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^",
"@deepseek-ai/dsh-session-checkpoint-policy": "workspace:^",
"@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^",
"@deepseek-ai/dsh-subagent": "workspace:^", "@deepseek-ai/dsh-subagent": "workspace:^",
"@deepseek-ai/dsh-subprocess": "workspace:^", "@deepseek-ai/dsh-subprocess": "workspace:^",
"@deepseek-ai/dsh-subprocess-local": "workspace:^", "@deepseek-ai/dsh-subprocess-local": "workspace:^",
"@deepseek-ai/dsh-timeout": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^",
"@deepseek-ai/dsh-tool-subagent": "workspace:^",
"@deepseek-ai/cordis": "workspace:^" "@deepseek-ai/cordis": "workspace:^"
} }
} }
@@ -55,14 +55,21 @@
}, },
"devDependencies": { "devDependencies": {
"@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^",
"@deepseek-ai/dsh-agent-spine-demo": "workspace:^",
"@deepseek-ai/dsh-app-boot": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^",
"@deepseek-ai/dsh-loader-smoke": "workspace:^", "@deepseek-ai/dsh-loader-smoke": "workspace:^",
"@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^",
"@deepseek-ai/dsh-session-checkpoint-policy": "workspace:^",
"@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^",
"@deepseek-ai/dsh-subagent": "workspace:^", "@deepseek-ai/dsh-subagent": "workspace:^",
"@deepseek-ai/dsh-subagent-codex": "workspace:^",
"@deepseek-ai/dsh-subprocess": "workspace:^", "@deepseek-ai/dsh-subprocess": "workspace:^",
"@deepseek-ai/dsh-subprocess-local": "workspace:^", "@deepseek-ai/dsh-subprocess-local": "workspace:^",
"@deepseek-ai/dsh-timeout": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^",
"@deepseek-ai/dsh-tool-subagent": "workspace:^",
"@deepseek-ai/dsh-tools": "workspace:^",
"@deepseek-ai/cordis": "workspace:^" "@deepseek-ai/cordis": "workspace:^"
} }
} }
@@ -54,14 +54,20 @@
"devDependencies": { "devDependencies": {
"@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/cordis-plugin-loader": "workspace:^",
"@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^",
"@deepseek-ai/dsh-agent-spine-demo": "workspace:^",
"@deepseek-ai/dsh-app-boot": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^",
"@deepseek-ai/dsh-loader-smoke": "workspace:^", "@deepseek-ai/dsh-loader-smoke": "workspace:^",
"@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^",
"@deepseek-ai/dsh-session-checkpoint-policy": "workspace:^",
"@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^",
"@deepseek-ai/dsh-subagent": "workspace:^", "@deepseek-ai/dsh-subagent": "workspace:^",
"@deepseek-ai/dsh-subprocess": "workspace:^", "@deepseek-ai/dsh-subprocess": "workspace:^",
"@deepseek-ai/dsh-subprocess-local": "workspace:^", "@deepseek-ai/dsh-subprocess-local": "workspace:^",
"@deepseek-ai/dsh-timeout": "workspace:^", "@deepseek-ai/dsh-timeout": "workspace:^",
"@deepseek-ai/dsh-tool-subagent": "workspace:^",
"@deepseek-ai/dsh-tools": "workspace:^",
"@deepseek-ai/cordis": "workspace:^" "@deepseek-ai/cordis": "workspace:^"
} }
} }
@@ -47,14 +47,22 @@
"devDependencies": { "devDependencies": {
"@deepseek-ai/cordis-plugin-loader": "workspace:^", "@deepseek-ai/cordis-plugin-loader": "workspace:^",
"@deepseek-ai/dsh-agent": "workspace:^", "@deepseek-ai/dsh-agent": "workspace:^",
"@deepseek-ai/dsh-agent-instructions": "workspace:^",
"@deepseek-ai/dsh-agent-spine-demo": "workspace:^",
"@deepseek-ai/dsh-app-boot": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-llm": "workspace:^", "@deepseek-ai/dsh-llm": "workspace:^",
"@deepseek-ai/dsh-llm-deepseek": "workspace:^",
"@deepseek-ai/dsh-loader-smoke": "workspace:^", "@deepseek-ai/dsh-loader-smoke": "workspace:^",
"@deepseek-ai/dsh-sdk-client": "workspace:^", "@deepseek-ai/dsh-sdk-client": "workspace:^",
"@deepseek-ai/dsh-sdk-protocol": "workspace:^", "@deepseek-ai/dsh-sdk-protocol": "workspace:^",
"@deepseek-ai/dsh-session": "workspace:^", "@deepseek-ai/dsh-session": "workspace:^",
"@deepseek-ai/dsh-session-checkpoint-policy": "workspace:^",
"@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^",
"@deepseek-ai/dsh-subagent": "workspace:^", "@deepseek-ai/dsh-subagent": "workspace:^",
"@deepseek-ai/dsh-subprocess": "workspace:^", "@deepseek-ai/dsh-subprocess": "workspace:^",
"@deepseek-ai/dsh-system-prompt": "workspace:^",
"@deepseek-ai/dsh-tool-subagent": "workspace:^",
"@deepseek-ai/cordis": "workspace:^" "@deepseek-ai/cordis": "workspace:^"
} }
} }
+229 -62
View File
@@ -524,7 +524,6 @@ importers:
specifier: ^4.1.8 specifier: ^4.1.8
version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1(@noble/hashes@2.3.0))(vite@6.4.3(@types/node@22.20.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)(yaml@2.9.0)) version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1(@noble/hashes@2.3.0))(vite@6.4.3(@types/node@22.20.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)(yaml@2.9.0))
native/landlock-run: native/landlock-run:
devDependencies: devDependencies:
'@deepseek-ai/node-addon-landlock-run': '@deepseek-ai/node-addon-landlock-run':
@@ -3972,6 +3971,15 @@ importers:
'@deepseek-ai/dsh-agent-loop-testkit': '@deepseek-ai/dsh-agent-loop-testkit':
specifier: workspace:^ specifier: workspace:^
version: link:../../test-support/agent-loop-testkit version: link:../../test-support/agent-loop-testkit
'@deepseek-ai/dsh-agent-spine-demo':
specifier: workspace:^
version: link:../../examples/agent-spine-demo
'@deepseek-ai/dsh-app-boot':
specifier: workspace:^
version: link:../../boot/app-boot
'@deepseek-ai/dsh-bash-local':
specifier: workspace:^
version: link:../../shell/bash-local
'@deepseek-ai/dsh-invariants': '@deepseek-ai/dsh-invariants':
specifier: workspace:^ specifier: workspace:^
version: link:../../runtime-diagnostics/invariants version: link:../../runtime-diagnostics/invariants
@@ -3984,6 +3992,15 @@ importers:
'@deepseek-ai/dsh-session': '@deepseek-ai/dsh-session':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/session version: link:../../core/session
'@deepseek-ai/dsh-session-checkpoint-policy':
specifier: workspace:^
version: link:../../session/session-checkpoint-policy
'@deepseek-ai/dsh-session-persistence-jsonl':
specifier: workspace:^
version: link:../../session/session-persistence-jsonl
'@deepseek-ai/dsh-subprocess-local':
specifier: workspace:^
version: link:../../subprocess/subprocess-local
'@deepseek-ai/dsh-system-prompt': '@deepseek-ai/dsh-system-prompt':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/system-prompt version: link:../../core/system-prompt
@@ -4295,15 +4312,45 @@ importers:
'@deepseek-ai/cordis': '@deepseek-ai/cordis':
specifier: workspace:^ specifier: workspace:^
version: link:../../../vendor/cordis version: link:../../../vendor/cordis
'@deepseek-ai/dsh-agent':
specifier: workspace:^
version: link:../../core/agent
'@deepseek-ai/dsh-app-boot':
specifier: workspace:^
version: link:../../boot/app-boot
'@deepseek-ai/dsh-bash-local':
specifier: workspace:^
version: link:../../shell/bash-local
'@deepseek-ai/dsh-fs-e2b':
specifier: workspace:^
version: link:../fs-e2b
'@deepseek-ai/dsh-invariants': '@deepseek-ai/dsh-invariants':
specifier: workspace:^ specifier: workspace:^
version: link:../../runtime-diagnostics/invariants version: link:../../runtime-diagnostics/invariants
'@deepseek-ai/dsh-loader-smoke': '@deepseek-ai/dsh-loader-smoke':
specifier: workspace:^ specifier: workspace:^
version: link:../../test-support/loader-smoke version: link:../../test-support/loader-smoke
'@deepseek-ai/dsh-lsp':
specifier: workspace:^
version: link:../../lsp/lsp
'@deepseek-ai/dsh-lsp-stdio':
specifier: workspace:^
version: link:../../lsp/lsp-stdio
'@deepseek-ai/dsh-sandbox-policy': '@deepseek-ai/dsh-sandbox-policy':
specifier: workspace:^ specifier: workspace:^
version: link:../../sandbox/sandbox-policy version: link:../../sandbox/sandbox-policy
'@deepseek-ai/dsh-session':
specifier: workspace:^
version: link:../../core/session
'@deepseek-ai/dsh-subprocess-e2b':
specifier: workspace:^
version: link:../subprocess-e2b
'@deepseek-ai/dsh-terminal':
specifier: workspace:^
version: link:../../terminal/terminal
'@deepseek-ai/dsh-terminal-bash':
specifier: workspace:^
version: link:../../terminal/terminal-bash
packages/e2b/fs-e2b: packages/e2b/fs-e2b:
devDependencies: devDependencies:
@@ -5178,6 +5225,12 @@ importers:
'@deepseek-ai/dsh-agent': '@deepseek-ai/dsh-agent':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/agent version: link:../../core/agent
'@deepseek-ai/dsh-agent-spine-demo':
specifier: workspace:^
version: link:../../examples/agent-spine-demo
'@deepseek-ai/dsh-bash-local':
specifier: workspace:^
version: link:../../shell/bash-local
'@deepseek-ai/dsh-brand': '@deepseek-ai/dsh-brand':
specifier: workspace:^ specifier: workspace:^
version: link:../../util/brand version: link:../../util/brand
@@ -5196,9 +5249,18 @@ importers:
'@deepseek-ai/dsh-session': '@deepseek-ai/dsh-session':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/session version: link:../../core/session
'@deepseek-ai/dsh-session-checkpoint-policy':
specifier: workspace:^
version: link:../../session/session-checkpoint-policy
'@deepseek-ai/dsh-session-persistence-jsonl':
specifier: workspace:^
version: link:../../session/session-persistence-jsonl
'@deepseek-ai/dsh-session-projection': '@deepseek-ai/dsh-session-projection':
specifier: workspace:^ specifier: workspace:^
version: link:../../session/session-projection version: link:../../session/session-projection
'@deepseek-ai/dsh-subprocess-local':
specifier: workspace:^
version: link:../../subprocess/subprocess-local
'@deepseek-ai/dsh-typert-protocol': '@deepseek-ai/dsh-typert-protocol':
specifier: workspace:^ specifier: workspace:^
version: link:../../typert/protocol version: link:../../typert/protocol
@@ -6636,12 +6698,12 @@ importers:
'@deepseek-ai/dsh-agent': '@deepseek-ai/dsh-agent':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/agent version: link:../../core/agent
'@deepseek-ai/dsh-attachment':
specifier: workspace:^
version: link:../../attachment/attachment
'@deepseek-ai/dsh-agent-spine-demo': '@deepseek-ai/dsh-agent-spine-demo':
specifier: workspace:^ specifier: workspace:^
version: link:../../examples/agent-spine-demo version: link:../../examples/agent-spine-demo
'@deepseek-ai/dsh-attachment':
specifier: workspace:^
version: link:../../attachment/attachment
'@deepseek-ai/dsh-invariants': '@deepseek-ai/dsh-invariants':
specifier: workspace:^ specifier: workspace:^
version: link:../../runtime-diagnostics/invariants version: link:../../runtime-diagnostics/invariants
@@ -7074,9 +7136,21 @@ importers:
'@deepseek-ai/cordis-plugin-loader': '@deepseek-ai/cordis-plugin-loader':
specifier: workspace:^ specifier: workspace:^
version: link:../../../vendor/loader version: link:../../../vendor/loader
'@deepseek-ai/cordis-plugin-logger-console':
specifier: workspace:^
version: link:../../../vendor/logger-console
'@deepseek-ai/dsh-agent-spine-demo':
specifier: workspace:^
version: link:../../examples/agent-spine-demo
'@deepseek-ai/dsh-anonymous-user-id': '@deepseek-ai/dsh-anonymous-user-id':
specifier: workspace:^ specifier: workspace:^
version: link:../../identity/anonymous-user-id version: link:../../identity/anonymous-user-id
'@deepseek-ai/dsh-app-boot':
specifier: workspace:^
version: link:../../boot/app-boot
'@deepseek-ai/dsh-bash-local':
specifier: workspace:^
version: link:../../shell/bash-local
'@deepseek-ai/dsh-command-feedback': '@deepseek-ai/dsh-command-feedback':
specifier: workspace:^ specifier: workspace:^
version: link:../../feedback/command-feedback version: link:../../feedback/command-feedback
@@ -7086,12 +7160,24 @@ importers:
'@deepseek-ai/dsh-llm': '@deepseek-ai/dsh-llm':
specifier: workspace:^ specifier: workspace:^
version: link:../../llm/llm version: link:../../llm/llm
'@deepseek-ai/dsh-loader-smoke':
specifier: workspace:^
version: link:../../test-support/loader-smoke
'@deepseek-ai/dsh-session': '@deepseek-ai/dsh-session':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/session version: link:../../core/session
'@deepseek-ai/dsh-session-checkpoint-policy':
specifier: workspace:^
version: link:../session-checkpoint-policy
'@deepseek-ai/dsh-session-persistence-jsonl':
specifier: workspace:^
version: link:../session-persistence-jsonl
'@deepseek-ai/dsh-session-telemetry': '@deepseek-ai/dsh-session-telemetry':
specifier: workspace:^ specifier: workspace:^
version: link:../session-telemetry version: link:../session-telemetry
'@deepseek-ai/dsh-subprocess-local':
specifier: workspace:^
version: link:../../subprocess/subprocess-local
packages/session/session-title: packages/session/session-title:
dependencies: dependencies:
@@ -7548,6 +7634,9 @@ importers:
'@deepseek-ai/dsh-agent': '@deepseek-ai/dsh-agent':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/agent version: link:../../core/agent
'@deepseek-ai/dsh-app-boot':
specifier: workspace:^
version: link:../../boot/app-boot
'@deepseek-ai/dsh-invariants': '@deepseek-ai/dsh-invariants':
specifier: workspace:^ specifier: workspace:^
version: link:../../runtime-diagnostics/invariants version: link:../../runtime-diagnostics/invariants
@@ -7964,6 +8053,12 @@ importers:
'@deepseek-ai/dsh-agent': '@deepseek-ai/dsh-agent':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/agent version: link:../../core/agent
'@deepseek-ai/dsh-agent-spine-demo':
specifier: workspace:^
version: link:../../examples/agent-spine-demo
'@deepseek-ai/dsh-app-boot':
specifier: workspace:^
version: link:../../boot/app-boot
'@deepseek-ai/dsh-invariants': '@deepseek-ai/dsh-invariants':
specifier: workspace:^ specifier: workspace:^
version: link:../../runtime-diagnostics/invariants version: link:../../runtime-diagnostics/invariants
@@ -7976,6 +8071,12 @@ importers:
'@deepseek-ai/dsh-session': '@deepseek-ai/dsh-session':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/session version: link:../../core/session
'@deepseek-ai/dsh-session-checkpoint-policy':
specifier: workspace:^
version: link:../../session/session-checkpoint-policy
'@deepseek-ai/dsh-session-persistence-jsonl':
specifier: workspace:^
version: link:../../session/session-persistence-jsonl
'@deepseek-ai/dsh-subagent': '@deepseek-ai/dsh-subagent':
specifier: workspace:^ specifier: workspace:^
version: link:../subagent version: link:../subagent
@@ -7988,6 +8089,9 @@ importers:
'@deepseek-ai/dsh-timeout': '@deepseek-ai/dsh-timeout':
specifier: workspace:^ specifier: workspace:^
version: link:../../util/timeout version: link:../../util/timeout
'@deepseek-ai/dsh-tool-subagent':
specifier: workspace:^
version: link:../tool-subagent
packages/subagent/subagent-claude-code: packages/subagent/subagent-claude-code:
dependencies: dependencies:
@@ -8013,6 +8117,12 @@ importers:
'@deepseek-ai/dsh-agent': '@deepseek-ai/dsh-agent':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/agent version: link:../../core/agent
'@deepseek-ai/dsh-agent-spine-demo':
specifier: workspace:^
version: link:../../examples/agent-spine-demo
'@deepseek-ai/dsh-app-boot':
specifier: workspace:^
version: link:../../boot/app-boot
'@deepseek-ai/dsh-invariants': '@deepseek-ai/dsh-invariants':
specifier: workspace:^ specifier: workspace:^
version: link:../../runtime-diagnostics/invariants version: link:../../runtime-diagnostics/invariants
@@ -8025,9 +8135,18 @@ importers:
'@deepseek-ai/dsh-session': '@deepseek-ai/dsh-session':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/session version: link:../../core/session
'@deepseek-ai/dsh-session-checkpoint-policy':
specifier: workspace:^
version: link:../../session/session-checkpoint-policy
'@deepseek-ai/dsh-session-persistence-jsonl':
specifier: workspace:^
version: link:../../session/session-persistence-jsonl
'@deepseek-ai/dsh-subagent': '@deepseek-ai/dsh-subagent':
specifier: workspace:^ specifier: workspace:^
version: link:../subagent version: link:../subagent
'@deepseek-ai/dsh-subagent-codex':
specifier: workspace:^
version: link:../subagent-codex
'@deepseek-ai/dsh-subprocess': '@deepseek-ai/dsh-subprocess':
specifier: workspace:^ specifier: workspace:^
version: link:../../subprocess/subprocess version: link:../../subprocess/subprocess
@@ -8037,6 +8156,12 @@ importers:
'@deepseek-ai/dsh-timeout': '@deepseek-ai/dsh-timeout':
specifier: workspace:^ specifier: workspace:^
version: link:../../util/timeout version: link:../../util/timeout
'@deepseek-ai/dsh-tool-subagent':
specifier: workspace:^
version: link:../tool-subagent
'@deepseek-ai/dsh-tools':
specifier: workspace:^
version: link:../../core/tools
packages/subagent/subagent-codex: packages/subagent/subagent-codex:
dependencies: dependencies:
@@ -8059,6 +8184,12 @@ importers:
'@deepseek-ai/dsh-agent': '@deepseek-ai/dsh-agent':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/agent version: link:../../core/agent
'@deepseek-ai/dsh-agent-spine-demo':
specifier: workspace:^
version: link:../../examples/agent-spine-demo
'@deepseek-ai/dsh-app-boot':
specifier: workspace:^
version: link:../../boot/app-boot
'@deepseek-ai/dsh-invariants': '@deepseek-ai/dsh-invariants':
specifier: workspace:^ specifier: workspace:^
version: link:../../runtime-diagnostics/invariants version: link:../../runtime-diagnostics/invariants
@@ -8071,6 +8202,12 @@ importers:
'@deepseek-ai/dsh-session': '@deepseek-ai/dsh-session':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/session version: link:../../core/session
'@deepseek-ai/dsh-session-checkpoint-policy':
specifier: workspace:^
version: link:../../session/session-checkpoint-policy
'@deepseek-ai/dsh-session-persistence-jsonl':
specifier: workspace:^
version: link:../../session/session-persistence-jsonl
'@deepseek-ai/dsh-subagent': '@deepseek-ai/dsh-subagent':
specifier: workspace:^ specifier: workspace:^
version: link:../subagent version: link:../subagent
@@ -8083,6 +8220,12 @@ importers:
'@deepseek-ai/dsh-timeout': '@deepseek-ai/dsh-timeout':
specifier: workspace:^ specifier: workspace:^
version: link:../../util/timeout version: link:../../util/timeout
'@deepseek-ai/dsh-tool-subagent':
specifier: workspace:^
version: link:../tool-subagent
'@deepseek-ai/dsh-tools':
specifier: workspace:^
version: link:../../core/tools
packages/subagent/subagent-dsh-sdk: packages/subagent/subagent-dsh-sdk:
dependencies: dependencies:
@@ -8099,12 +8242,24 @@ importers:
'@deepseek-ai/dsh-agent': '@deepseek-ai/dsh-agent':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/agent version: link:../../core/agent
'@deepseek-ai/dsh-agent-instructions':
specifier: workspace:^
version: link:../../context/agent-instructions
'@deepseek-ai/dsh-agent-spine-demo':
specifier: workspace:^
version: link:../../examples/agent-spine-demo
'@deepseek-ai/dsh-app-boot':
specifier: workspace:^
version: link:../../boot/app-boot
'@deepseek-ai/dsh-invariants': '@deepseek-ai/dsh-invariants':
specifier: workspace:^ specifier: workspace:^
version: link:../../runtime-diagnostics/invariants version: link:../../runtime-diagnostics/invariants
'@deepseek-ai/dsh-llm': '@deepseek-ai/dsh-llm':
specifier: workspace:^ specifier: workspace:^
version: link:../../llm/llm version: link:../../llm/llm
'@deepseek-ai/dsh-llm-deepseek':
specifier: workspace:^
version: link:../../llm/llm-deepseek
'@deepseek-ai/dsh-loader-smoke': '@deepseek-ai/dsh-loader-smoke':
specifier: workspace:^ specifier: workspace:^
version: link:../../test-support/loader-smoke version: link:../../test-support/loader-smoke
@@ -8117,12 +8272,24 @@ importers:
'@deepseek-ai/dsh-session': '@deepseek-ai/dsh-session':
specifier: workspace:^ specifier: workspace:^
version: link:../../core/session version: link:../../core/session
'@deepseek-ai/dsh-session-checkpoint-policy':
specifier: workspace:^
version: link:../../session/session-checkpoint-policy
'@deepseek-ai/dsh-session-persistence-jsonl':
specifier: workspace:^
version: link:../../session/session-persistence-jsonl
'@deepseek-ai/dsh-subagent': '@deepseek-ai/dsh-subagent':
specifier: workspace:^ specifier: workspace:^
version: link:../subagent version: link:../subagent
'@deepseek-ai/dsh-subprocess': '@deepseek-ai/dsh-subprocess':
specifier: workspace:^ specifier: workspace:^
version: link:../../subprocess/subprocess version: link:../../subprocess/subprocess
'@deepseek-ai/dsh-system-prompt':
specifier: workspace:^
version: link:../../core/system-prompt
'@deepseek-ai/dsh-tool-subagent':
specifier: workspace:^
version: link:../tool-subagent
packages/subagent/subagent-fork-in-process: packages/subagent/subagent-fork-in-process:
dependencies: dependencies:
@@ -8585,64 +8752,6 @@ importers:
specifier: workspace:^ specifier: workspace:^
version: link:../../core/tools version: link:../../core/tools
packages/test-support/session-snapshot:
dependencies:
'@agentclientprotocol/sdk':
specifier: 1.4.0
version: 1.4.0(zod@4.4.3)
'@deepseek-ai/cordis-plugin-include':
specifier: workspace:*
version: link:../../../vendor/include
'@deepseek-ai/dsh-loader-smoke':
specifier: workspace:*
version: link:../loader-smoke
js-yaml:
specifier: ^4.2.0
version: 4.2.0
vitest:
specifier: ^4.1.8
version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1(@noble/hashes@2.3.0))(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
devDependencies:
'@deepseek-ai/cordis':
specifier: workspace:^
version: link:../../../vendor/cordis
'@deepseek-ai/dsh-agent':
specifier: workspace:^
version: link:../../core/agent
'@deepseek-ai/dsh-agent-loop':
specifier: workspace:^
version: link:../../core/agent-loop
'@deepseek-ai/dsh-compaction':
specifier: workspace:^
version: link:../../compaction/compaction
'@deepseek-ai/dsh-invariants':
specifier: workspace:^
version: link:../../runtime-diagnostics/invariants
'@deepseek-ai/dsh-llm':
specifier: workspace:^
version: link:../../llm/llm
'@deepseek-ai/dsh-sandbox':
specifier: workspace:^
version: link:../../sandbox/sandbox
'@deepseek-ai/dsh-sandbox-policy':
specifier: workspace:^
version: link:../../sandbox/sandbox-policy
'@deepseek-ai/dsh-session':
specifier: workspace:^
version: link:../../core/session
'@deepseek-ai/dsh-subagent':
specifier: workspace:^
version: link:../../subagent/subagent
'@deepseek-ai/dsh-tools':
specifier: workspace:^
version: link:../../core/tools
'@deepseek-ai/dsh-user-questions':
specifier: workspace:^
version: link:../../interaction/user-questions
'@types/js-yaml':
specifier: ^4.0.9
version: 4.0.9
packages/test-support/agent-loop-testkit: packages/test-support/agent-loop-testkit:
devDependencies: devDependencies:
'@deepseek-ai/cordis': '@deepseek-ai/cordis':
@@ -8795,6 +8904,64 @@ importers:
specifier: workspace:^ specifier: workspace:^
version: link:../../core/session version: link:../../core/session
packages/test-support/session-snapshot:
dependencies:
'@agentclientprotocol/sdk':
specifier: 1.4.0
version: 1.4.0(zod@4.4.3)
'@deepseek-ai/cordis-plugin-include':
specifier: workspace:*
version: link:../../../vendor/include
'@deepseek-ai/dsh-loader-smoke':
specifier: workspace:*
version: link:../loader-smoke
js-yaml:
specifier: ^4.2.0
version: 4.2.0
vitest:
specifier: ^4.1.8
version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1(@noble/hashes@2.3.0))(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
devDependencies:
'@deepseek-ai/cordis':
specifier: workspace:^
version: link:../../../vendor/cordis
'@deepseek-ai/dsh-agent':
specifier: workspace:^
version: link:../../core/agent
'@deepseek-ai/dsh-agent-loop':
specifier: workspace:^
version: link:../../core/agent-loop
'@deepseek-ai/dsh-compaction':
specifier: workspace:^
version: link:../../compaction/compaction
'@deepseek-ai/dsh-invariants':
specifier: workspace:^
version: link:../../runtime-diagnostics/invariants
'@deepseek-ai/dsh-llm':
specifier: workspace:^
version: link:../../llm/llm
'@deepseek-ai/dsh-sandbox':
specifier: workspace:^
version: link:../../sandbox/sandbox
'@deepseek-ai/dsh-sandbox-policy':
specifier: workspace:^
version: link:../../sandbox/sandbox-policy
'@deepseek-ai/dsh-session':
specifier: workspace:^
version: link:../../core/session
'@deepseek-ai/dsh-subagent':
specifier: workspace:^
version: link:../../subagent/subagent
'@deepseek-ai/dsh-tools':
specifier: workspace:^
version: link:../../core/tools
'@deepseek-ai/dsh-user-questions':
specifier: workspace:^
version: link:../../interaction/user-questions
'@types/js-yaml':
specifier: ^4.0.9
version: 4.0.9
packages/todo/tool-todo: packages/todo/tool-todo:
dependencies: dependencies:
'@deepseek-ai/schemastery': '@deepseek-ai/schemastery':
+67
View File
@@ -12,6 +12,8 @@ import {
bundleManifestPaths, bundleManifestPaths,
bundlePluginDependencyErrors, bundlePluginDependencyErrors,
metadataExpressionErrors, metadataExpressionErrors,
packageTestFixtureDependencyErrors,
packageTestPluginDependencyErrors,
} from './verify-cordis-config.ts' } from './verify-cordis-config.ts'
describe('verify-cordis-config metadata expressions', () => { describe('verify-cordis-config metadata expressions', () => {
@@ -86,3 +88,68 @@ describe('workspace Bundle discovery and product dependency closures', () => {
]) ])
}) })
}) })
describe('package-owned Loader test dependency closures', () => {
it('requires package test configs to declare each named plugin they load', () => {
const manifestPath = 'packages/example/owner/package.json'
const file = 'packages/example/owner/tests/fixtures/cordis.yml'
const manifest = {
name: '@deepseek-ai/dsh-owner',
dependencies: {},
devDependencies: {
'@deepseek-ai/dsh-declared': 'workspace:^',
},
}
expect(packageTestPluginDependencyErrors(manifestPath, manifest, [
{ file, name: '@deepseek-ai/dsh-owner' },
{ file, name: '@deepseek-ai/dsh-declared' },
{ file, name: '@deepseek-ai/dsh-missing' },
])).toEqual([
`${file}: @deepseek-ai/dsh-missing must be declared in ${manifestPath} dependencies or devDependencies`,
])
})
it('requires executable package test fixtures to declare their bare imports', () => {
const fixture = mkdtempSync(join(tmpdir(), 'dsh-package-test-entrypoint-'))
try {
const packageDir = join(fixture, 'packages/example/owner')
const driverDir = join(packageDir, 'tests/fixtures/loader')
mkdirSync(driverDir, { recursive: true })
writeFileSync(join(packageDir, 'package.json'), JSON.stringify({
name: '@deepseek-ai/dsh-owner',
devDependencies: {
'@deepseek-ai/dsh-declared': 'workspace:^',
},
}))
writeFileSync(join(driverDir, 'driver.ts'), [
"import '@deepseek-ai/dsh-owner'",
"import '@deepseek-ai/dsh-declared'",
"import '@deepseek-ai/dsh-missing'",
].join('\n'))
writeFileSync(join(driverDir, 'cordis.yml'), '[]\n')
writeFileSync(join(driverDir, 'fixture.mjs'), "import '@deepseek-ai/dsh-declared'\n")
const unrelatedDir = join(packageDir, 'tests/fixtures/unrelated')
mkdirSync(unrelatedDir, { recursive: true })
writeFileSync(join(unrelatedDir, 'driver.ts'), "import '@deepseek-ai/dsh-unrelated'\n")
expect(packageTestFixtureDependencyErrors(fixture)).toEqual([
'packages/example/owner/tests/fixtures/loader/driver.ts: '
+ '@deepseek-ai/dsh-missing must be declared in '
+ 'packages/example/owner/package.json dependencies or devDependencies',
])
} finally {
rmSync(fixture, { recursive: true, force: true })
}
})
it('fails loud when package-owned Loader fixtures disappear from the scan', () => {
const fixture = mkdtempSync(join(tmpdir(), 'dsh-empty-package-test-entrypoint-'))
try {
expect(packageTestFixtureDependencyErrors(fixture)).toEqual([
'package test fixture dependency scan found no package-owned Loader configs',
])
} finally {
rmSync(fixture, { recursive: true, force: true })
}
})
})
+101 -5
View File
@@ -6,7 +6,8 @@
* every mount decision, against the loader context). Every other entry * every mount decision, against the loader context). Every other entry
* metadata field stays static, so an expression there remains truthy data and * metadata field stays static, so an expression there remains truthy data and
* silently changes composition. Shipped and test-only dsh overlays resolve * silently changes composition. Shipped and test-only dsh overlays resolve
* named plugins from the CLI application's owning manifest. * named plugins from the CLI application's owning manifest; package-owned
* Loader fixtures resolve from their package manifest.
*/ */
import { globSync, readFileSync } from 'node:fs' import { globSync, readFileSync } from 'node:fs'
@@ -71,6 +72,8 @@ if (import.meta.main) {
} }
errors.push(...validateAppResolution()) errors.push(...validateAppResolution())
errors.push(...validatePackageTestResolution())
errors.push(...packageTestFixtureDependencyErrors())
errors.push(...validateSourcePlaneResolution()) errors.push(...validateSourcePlaneResolution())
errors.push(...validatePresetPlaneSeparation()) errors.push(...validatePresetPlaneSeparation())
errors.push(...validateClientHalvesDeclared()) errors.push(...validateClientHalvesDeclared())
@@ -237,7 +240,11 @@ function validateAppResolution(): string[] {
const shipped = new Set(globSync('*.cordis.yml', { cwd: resolve(root, 'apps/cli/config') }) const shipped = new Set(globSync('*.cordis.yml', { cwd: resolve(root, 'apps/cli/config') })
.map(file => `apps/cli/config/${file}`)) .map(file => `apps/cli/config/${file}`))
const appReferences = pluginReferences.filter(reference => shipped.has(reference.file) || appOverlayFiles.has(reference.file)) const appReferences = pluginReferences.filter(reference => shipped.has(reference.file) || appOverlayFiles.has(reference.file))
violations.push(...missingPluginDependencies(appReferences, appDependencies, 'apps/cli/package.json or a bundle manifest')) violations.push(...missingPluginDependencies(
appReferences,
appDependencies,
'apps/cli/package.json dependencies or a bundle manifest',
))
const appTestReferences = pluginReferences.filter(reference => reference.file.startsWith('apps/cli/tests/')) const appTestReferences = pluginReferences.filter(reference => reference.file.startsWith('apps/cli/tests/'))
violations.push(...missingPluginDependencies( violations.push(...missingPluginDependencies(
appTestReferences, appTestReferences,
@@ -258,6 +265,95 @@ function validateAppResolution(): string[] {
return violations return violations
} }
/**
* Package-owned Loader fixtures resolve named plugins from their package's
* dependency surface, not from a repository-level test umbrella.
* @returns one violation per configured package absent from the owner manifest.
*/
function validatePackageTestResolution(): string[] {
const referencesByManifest = new Map<string, PluginReference[]>()
for (const reference of pluginReferences) {
const manifestPath = packageTestManifestPath(reference.file)
if (manifestPath === undefined) continue
const references = referencesByManifest.get(manifestPath) ?? []
references.push(reference)
referencesByManifest.set(manifestPath, references)
}
return [...referencesByManifest].flatMap(([manifestPath, references]) =>
packageTestPluginDependencyErrors(manifestPath, readManifest(manifestPath), references))
}
/**
* Validate the named plugins one package-owned Loader fixture resolves.
* Self-references use Node package self-resolution; every other package must
* be an ordinary production or test dependency of the owner.
* @param manifestPath Repository-relative owner manifest path.
* @param manifest Parsed owner manifest.
* @param references Named plugin references from owner-local test configs.
* @returns Missing dependency diagnostics.
*/
export function packageTestPluginDependencyErrors(
manifestPath: string,
manifest: PackageManifest,
references: readonly PluginReference[],
): string[] {
return missingPluginDependencies(
references.filter(reference => packageNameFromSpecifier(reference.name) !== manifest.name),
{ ...manifest.dependencies, ...manifest.devDependencies },
`${manifestPath} dependencies or devDependencies`,
)
}
/**
* Validate imports made by fixture modules adjacent to package-owned Loader
* configs. These files execute as plain Node/tsx children, so a stale root
* `node_modules` link must not hide an undeclared dependency.
* @param repoRoot Repository root to scan.
* @returns Missing dependency diagnostics.
*/
export function packageTestFixtureDependencyErrors(repoRoot: string = root): string[] {
const fixtureDirectories = new Set(cordisConfigFiles(repoRoot)
.filter(file => packageTestManifestPath(file) !== undefined)
.map(file => dirname(file).replaceAll('\\', '/')))
if (fixtureDirectories.size === 0) {
return ['package test fixture dependency scan found no package-owned Loader configs']
}
const referencesByManifest = new Map<string, PluginReference[]>()
let fixtureModuleCount = 0
for (const fixtureDirectory of fixtureDirectories) {
const files = globSync([
`${fixtureDirectory}/**/*.ts`,
`${fixtureDirectory}/**/*.mjs`,
], { cwd: repoRoot })
fixtureModuleCount += files.length
for (const file of files) {
const manifestPath = packageTestManifestPath(file)
if (manifestPath === undefined) continue
const references = referencesByManifest.get(manifestPath) ?? []
const source = readFileSync(resolve(repoRoot, file), 'utf8')
for (const imported of ts.preProcessFile(source, true, true).importedFiles) {
references.push({ file: file.replaceAll('\\', '/'), name: imported.fileName })
}
referencesByManifest.set(manifestPath, references)
}
}
if (fixtureModuleCount === 0) {
return ['package test fixture dependency scan found no fixture modules beside Loader configs']
}
return [...referencesByManifest].flatMap(([manifestPath, references]) =>
packageTestPluginDependencyErrors(
manifestPath,
readManifest(manifestPath, repoRoot),
references,
))
}
/** Owner manifest for a package-local test path. */
function packageTestManifestPath(file: string): string | undefined {
const match = /^(packages\/[^/]+\/[^/]+)\/tests(?:\/|$)/.exec(file.replaceAll('\\', '/'))
return match?.[1] === undefined ? undefined : `${match[1]}/package.json`
}
/** /**
* Discover workspace Bundle packages from their manifest declaration. * Discover workspace Bundle packages from their manifest declaration.
* @param repoRoot Repository root to scan. * @param repoRoot Repository root to scan.
@@ -286,7 +382,7 @@ export function bundlePluginDependencyErrors(
// A Bundle may mount its own package (for example, its provider or runtime row). // A Bundle may mount its own package (for example, its provider or runtime row).
references.filter(reference => packageNameFromSpecifier(reference.name) !== manifest.name), references.filter(reference => packageNameFromSpecifier(reference.name) !== manifest.name),
manifest.dependencies ?? {}, manifest.dependencies ?? {},
manifestPath, `${manifestPath} dependencies`,
) )
} }
@@ -344,7 +440,7 @@ function validateSourcePlaneResolution(): string[] {
function missingPluginDependencies( function missingPluginDependencies(
references: readonly PluginReference[], references: readonly PluginReference[],
dependencies: Readonly<Record<string, string>>, dependencies: Readonly<Record<string, string>>,
manifestPath: string, dependencyOwner: string,
): string[] { ): string[] {
const requiredPackages = new Map<string, Set<string>>() const requiredPackages = new Map<string, Set<string>>()
const require = (packageName: string, file: string): void => { const require = (packageName: string, file: string): void => {
@@ -362,7 +458,7 @@ function missingPluginDependencies(
} }
return [...requiredPackages].flatMap(([packageName, locations]) => packageName in dependencies return [...requiredPackages].flatMap(([packageName, locations]) => packageName in dependencies
? [] ? []
: `${[...locations].join(', ')}: ${packageName} must be declared in ${manifestPath} dependencies`) : `${[...locations].join(', ')}: ${packageName} must be declared in ${dependencyOwner}`)
} }
function readManifest(path: string, repoRoot: string = root): PackageManifest { function readManifest(path: string, repoRoot: string = root): PackageManifest {