@bushizhanghan/dsh-publish-gate 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +1 -1
- package/lib/engine.js +11 -14
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.15.0
|
|
4
|
+
|
|
5
|
+
- Three rules shipped with a *rule name* in their severity slot: `market-repo-too-new`,
|
|
6
|
+
`test-script-dir-arg` and `tool-missing-output-schema` were built as
|
|
7
|
+
`F(rule, "some-other-rule", "a-third-rule", "warn", title, ...)`, because a string replace aimed at
|
|
8
|
+
RULE_ORDER matched an earlier `F(...)` call instead and pushed the new names into its arguments.
|
|
9
|
+
Nothing failed: a finding whose severity is not error/warn/info falls out of every counter and never
|
|
10
|
+
reaches the report, so the rules looked like they simply never fired. Fixed all three, added the six
|
|
11
|
+
rule names that never made it into RULE_ORDER, and added a source scan that fails when any `F(...)`
|
|
12
|
+
call passes something other than an error/warn/info literal (or a ternary of two of them).
|
|
13
|
+
|
|
3
14
|
## 0.14.0
|
|
4
15
|
|
|
5
16
|
- New test layer: `checkTestRun` runs `node --test` in the plugin directory and reports `tests-fail`
|
package/README.md
CHANGED
package/lib/engine.js
CHANGED
|
@@ -931,7 +931,7 @@ export async function checkMarketReadiness(dir, opts = {}) {
|
|
|
931
931
|
if (hours < 24) {
|
|
932
932
|
out.push(
|
|
933
933
|
F(
|
|
934
|
-
'market-repo-too-new',
|
|
934
|
+
'market-repo-too-new',
|
|
935
935
|
'warn',
|
|
936
936
|
`the repo is ${hours.toFixed(1)}h old; the submission gate needs 24h`,
|
|
937
937
|
'The gate fails with a "repo too new" message and reruns on its own, so the PR is not lost — but nothing merges until it passes.',
|
|
@@ -1044,10 +1044,7 @@ export function checkTests(dir) {
|
|
|
1044
1044
|
// while the tests themselves are fine. Auto-discovery needs no argument.
|
|
1045
1045
|
const testScript = pkgJson?.scripts?.test || ''
|
|
1046
1046
|
const dirArg = testScript.match(/\bnode\s+--test\s+(?!-)(\S+)/)
|
|
1047
|
-
if (dirArg) out.push(F('test-script-dir-arg',
|
|
1048
|
-
'tests-fail',
|
|
1049
|
-
'tests-timeout',
|
|
1050
|
-
'tests-not-run', 'warn', `test script passes a path to node --test ("${dirArg[1]}")`, 'Node 22+ treats that argument as a module path, not a directory to glob: `node --test test/` throws MODULE_NOT_FOUND, so npm test can never pass even though the tests are fine.', 'Drop the path — "test": "node --test" auto-discovers test/**/*.test.mjs.'))
|
|
1047
|
+
if (dirArg) out.push(F('test-script-dir-arg', 'warn', `test script passes a path to node --test ("${dirArg[1]}")`, 'Node 22+ treats that argument as a module path, not a directory to glob: `node --test test/` throws MODULE_NOT_FOUND, so npm test can never pass even though the tests are fine.', 'Drop the path — "test": "node --test" auto-discovers test/**/*.test.mjs.'))
|
|
1051
1048
|
return out
|
|
1052
1049
|
}
|
|
1053
1050
|
|
|
@@ -1069,12 +1066,12 @@ export async function checkTestRun(dir, opts = {}) {
|
|
|
1069
1066
|
let stdout = ''
|
|
1070
1067
|
let code = 0
|
|
1071
1068
|
let timedOut = false
|
|
1072
|
-
// NODE_TEST_CONTEXT is inherited from whoever called us: when this gate runs
|
|
1073
|
-
// inside `node --test` itself, the child starts in test-child mode and prints
|
|
1074
|
-
// no summary at all, which reads as "no tests" — a false alarm.
|
|
1075
|
-
const env = { ...process.env }
|
|
1076
|
-
delete env.NODE_TEST_CONTEXT
|
|
1077
|
-
try {
|
|
1069
|
+
// NODE_TEST_CONTEXT is inherited from whoever called us: when this gate runs
|
|
1070
|
+
// inside `node --test` itself, the child starts in test-child mode and prints
|
|
1071
|
+
// no summary at all, which reads as "no tests" — a false alarm.
|
|
1072
|
+
const env = { ...process.env }
|
|
1073
|
+
delete env.NODE_TEST_CONTEXT
|
|
1074
|
+
try {
|
|
1078
1075
|
const r = await runFile(process.execPath, ['--test'], { cwd: dir, env, timeout: timeoutMs, maxBuffer: 16 * 1024 * 1024, windowsHide: true })
|
|
1079
1076
|
stdout = String(r.stdout || '')
|
|
1080
1077
|
} catch (error) {
|
|
@@ -1634,7 +1631,7 @@ export async function checkToolRegistrations(dir, opts = {}) {
|
|
|
1634
1631
|
),
|
|
1635
1632
|
)
|
|
1636
1633
|
}
|
|
1637
|
-
if (!t.hasOutputSchema) out.push(F('tool-missing-output-schema', '
|
|
1634
|
+
if (!t.hasOutputSchema) out.push(F('tool-missing-output-schema', 'warn', `tool "${label}" declares no output.schema`, 'The host validates tool output against output.schema; without one the contract is implicit and a malformed result reaches the caller.', "Add output: { schema: { type: 'json' }, render }."))
|
|
1638
1635
|
if (t.cardKind && typeof t.cardKind === 'object') {
|
|
1639
1636
|
out.push(F('tool-present-call-throws', 'error', `tool "${label}" presentCall() throws`, `presentCall renders the transcript card and must be total: ${t.cardKind.threw}`, 'Do not read args fields that may be absent.'))
|
|
1640
1637
|
} else if (typeof t.cardKind === 'string' && !CARD_KINDS.has(t.cardKind)) {
|
|
@@ -2471,12 +2468,12 @@ const RULE_ORDER = [
|
|
|
2471
2468
|
'client-factory-throws', 'client-no-apply', 'client-apply-throws', 'client-no-registration', 'client-double-load',
|
|
2472
2469
|
'client-inject-missing-slots', 'client-inject-missing-sidebarRightTabs', 'client-unavailable',
|
|
2473
2470
|
'no-patch-file', 'no-insert-row', 'insert-missing-name', 'insert-name-mismatch',
|
|
2474
|
-
'patch-name-unresolvable', 'no-name-export', 'no-apply-export', 'no-inject', 'require-in-esm',
|
|
2471
|
+
'patch-name-unresolvable', 'tests-fail', 'tests-timeout', 'tests-not-run', 'no-name-export', 'no-apply-export', 'no-inject', 'require-in-esm',
|
|
2475
2472
|
'entry-import-failed', 'apply-threw', 'tools-unavailable',
|
|
2476
2473
|
'inject-missing-tools', 'inject-missing-web', 'inject-missing-webServer', 'inject-missing-timer',
|
|
2477
2474
|
'inject-unused-service',
|
|
2478
2475
|
'tool-missing-name', 'tool-duplicate-name', 'tool-missing-execute', 'tool-present-call-throws',
|
|
2479
|
-
'tool-bad-card-kind', 'tool-missing-output-schema', 'tool-none-registered', 'tool-bad-parameter-type', 'tool-undeclared-param', 'tool-input-throws', 'tool-call-throws', 'tool-output-invalid', 'tool-call-slow',
|
|
2476
|
+
'tool-bad-card-kind', 'tool-no-description', 'tool-description-thin', 'tool-no-parameters', 'tool-missing-output-schema', 'tool-none-registered', 'tool-bad-parameter-type', 'tool-undeclared-param', 'tool-input-throws', 'tool-call-throws', 'tool-output-invalid', 'tool-call-slow',
|
|
2480
2477
|
'lib-debugger', 'lib-console-log', 'lib-hardcoded-path', 'lib-url-pathname', 'node-too-old', 'stale-build', 'hand-edited-build',
|
|
2481
2478
|
'undeclared-import', 'dep-in-dev-only', 'unused-dependency',
|
|
2482
2479
|
'pack-omits-lib', 'pack-omits-patch', 'pack-omits-client', 'pack-oversize', 'pack-omits-readme', 'pack-omits-license', 'pack-ships-secret',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bushizhanghan/dsh-publish-gate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Pre-publish gate for DSH plugins: manifest, dependencies, artifact, runtime, browser half, traceability and market readiness — plus an input fuzzer that drives every declared parameter with the wrong type. 发布前的七层门禁 + 入参模糊测试。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|