mirror of
https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli.git
synced 2026-09-28 13:14:08 +08:00
embeddedMCPMetadata only feeds interface validation now; its summary was projected onto every schema payload as a constant-empty blob. Remove the SchemaRegistry field, all three payload projections, the snapshot wire field, the overview copy, the compact strip entry, and the jq policy gate. Also delete the redundant io.Discard dead-code suppressor in event_command.go (io has five genuine uses there).
165 lines
7.1 KiB
Bash
Executable File
165 lines
7.1 KiB
Bash
Executable File
#!/bin/sh
|
|
set -eu
|
|
|
|
ROOT="$(CDPATH= cd -- "$(dirname -- "$0")/../.." && pwd)"
|
|
cd "$ROOT"
|
|
|
|
BIN="${DWS_BIN:-$ROOT/dws}"
|
|
|
|
tmp="$(mktemp -d)"
|
|
trap 'rm -rf "$tmp"' EXIT HUP INT TERM
|
|
|
|
# Assemble a fresh runtime Catalog dump (ResolveSchemaBuild via with-catalog.sh)
|
|
# into the single-document shape this check consumes. No committed
|
|
# schema_catalog/ split is consulted.
|
|
catalog_combined="$tmp/catalog-combined.json"
|
|
scripts/policy/with-catalog.sh >"$catalog_combined"
|
|
|
|
if [ ! -x "$BIN" ]; then
|
|
printf 'error: dws binary not found at %s (run make build first)\n' "$BIN" >&2
|
|
exit 2
|
|
fi
|
|
|
|
go run ./internal/generator/cmd_schema_registry_smoke >"$tmp/smoke-vector.json"
|
|
|
|
"$BIN" schema list --format json >"$tmp/list.json"
|
|
"$BIN" schema --all --format json >"$tmp/all.json"
|
|
|
|
if ! jq -e '
|
|
.version == 1 and
|
|
(.registry_hash | type) == "string" and
|
|
(.registry_hash | test("^sha256:[0-9a-f]{64}$")) and
|
|
(.commands | type) == "array" and
|
|
(.commands | length) > 0 and
|
|
((.commands | map(.canonical_path) | unique | length) == (.commands | length)) and
|
|
((.commands | map(.primary_cli_path) | unique | length) == (.commands | length)) and
|
|
all(.commands[];
|
|
(.canonical_path | type) == "string" and (.canonical_path | length) > 0 and
|
|
(.primary_cli_path | type) == "string" and (.primary_cli_path | length) > 0 and
|
|
(.alias_cli_paths | type) == "array" and
|
|
((.alias_cli_paths | unique | length) == (.alias_cli_paths | length)))
|
|
' "$tmp/smoke-vector.json" >/dev/null; then
|
|
printf '%s\n' 'EffectiveCommandRegistry full smoke vector is malformed or empty' >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! jq -e -n \
|
|
--slurpfile vector "$tmp/smoke-vector.json" \
|
|
--slurpfile catalog "$catalog_combined" \
|
|
--slurpfile list "$tmp/list.json" \
|
|
--slurpfile all "$tmp/all.json" '
|
|
$vector[0] as $vector |
|
|
$catalog[0] as $catalog |
|
|
$list[0] as $list |
|
|
$all[0] as $all |
|
|
$vector.registry_hash == $catalog.surface_hash and
|
|
$list.surface_hash == $vector.registry_hash and
|
|
$all.surface_hash == $vector.registry_hash and
|
|
$list.catalog_hash == $catalog.source_hash and
|
|
$all.catalog_hash == $catalog.source_hash and
|
|
($vector.commands | map(.canonical_path) | sort) == ($catalog.tools | keys | sort) and
|
|
($vector.commands | map(.canonical_path) | sort) ==
|
|
([$all.products[].tools[].canonical_path] | sort) and
|
|
([$vector.commands[] as $command |
|
|
($catalog.tools[$command.canonical_path].primary_cli_path == $command.primary_cli_path and
|
|
(($catalog.tools[$command.canonical_path].aliases // []) | sort) ==
|
|
($command.alias_cli_paths | sort))] | all) and
|
|
all($all.products[].tools[]; . == $catalog.tools[.canonical_path])
|
|
' >/dev/null; then
|
|
printf '%s\n' 'built dws Schema navigation/hash/--all content differs from EffectiveCommandRegistry or assembled Catalog dump' >&2
|
|
exit 1
|
|
fi
|
|
|
|
# schema list is an intentionally compact product overview, but every field
|
|
# still has to be the exact typed projection of the same assembled Catalog dump.
|
|
# Derive the expected overview without invoking another Schema code path so a
|
|
# release binary cannot hide loader/query drift behind two identical helpers.
|
|
jq -S '
|
|
def nonempty: type == "string" and (gsub("^\\s+|\\s+$"; "") | length) > 0;
|
|
. as $snapshot |
|
|
$snapshot.catalog as $catalog |
|
|
{
|
|
kind: (if ($catalog.kind | nonempty) then $catalog.kind else "schema" end),
|
|
level: "products",
|
|
count: ($catalog.products | length),
|
|
tool_count: ($catalog.products | map(.tool_count) | add // 0),
|
|
products: [
|
|
$catalog.products[] |
|
|
. as $product |
|
|
{
|
|
id: $product.id,
|
|
tool_count: $product.tool_count,
|
|
schema_path: $product.id
|
|
} +
|
|
if (($product.agent_summary // "") | nonempty) then
|
|
{agent_summary: $product.agent_summary}
|
|
elif (($product.use_when // []) | length) > 0 then
|
|
{use_when: [$product.use_when[0]]}
|
|
elif (($product.description // "") | type == "string" and length > 0) then
|
|
{description: $product.description}
|
|
else {} end
|
|
]
|
|
} +
|
|
(if (($catalog.source // "") | type == "string" and length > 0) then {source: $catalog.source} else {} end) +
|
|
(if $catalog | has("agent_metadata") then {agent_metadata: $catalog.agent_metadata} else {} end) +
|
|
{catalog_hash: $snapshot.source_hash} +
|
|
(if (($snapshot.surface_hash // "") | nonempty) then {surface_hash: $snapshot.surface_hash} else {} end)
|
|
' "$catalog_combined" >"$tmp/expected-list.json"
|
|
jq -S . "$tmp/list.json" >"$tmp/actual-list.json"
|
|
if ! cmp -s "$tmp/expected-list.json" "$tmp/actual-list.json"; then
|
|
printf '%s\n' 'built dws schema list differs from the typed Catalog overview projection' >&2
|
|
diff -u "$tmp/expected-list.json" "$tmp/actual-list.json" || true
|
|
exit 1
|
|
fi
|
|
|
|
# The exact public EffectiveCommandRegistry set and every alias mapping were compared above using the
|
|
# release binary's --all payload. Exercise representative canonical/primary
|
|
# query routes here; exhaustive per-path resolution runs in the in-process Go
|
|
# delivery gate, avoiding more than one thousand cold binary startups in CI.
|
|
jq -c '.commands as $commands | [$commands[0], $commands[($commands|length)/2|floor], $commands[-1]] | unique_by(.canonical_path)[]' \
|
|
"$tmp/smoke-vector.json" >"$tmp/commands.jsonl"
|
|
while IFS= read -r command; do
|
|
canonical="$(printf '%s\n' "$command" | jq -r '.canonical_path')"
|
|
primary="$(printf '%s\n' "$command" | jq -r '.primary_cli_path')"
|
|
|
|
"$BIN" schema "$canonical" --format json >"$tmp/canonical.json"
|
|
"$BIN" schema --cli-path "$primary" --format json >"$tmp/primary.json"
|
|
jq -S --arg canonical "$canonical" '
|
|
[.products[].tools[] | select(.canonical_path == $canonical)] |
|
|
if length == 1 then .[0] else null end
|
|
' "$tmp/all.json" >"$tmp/all-tool.json"
|
|
jq -S . "$tmp/canonical.json" >"$tmp/canonical-sorted.json"
|
|
jq -S . "$tmp/primary.json" >"$tmp/primary-sorted.json"
|
|
|
|
if ! cmp -s "$tmp/canonical-sorted.json" "$tmp/primary-sorted.json" ||
|
|
! cmp -s "$tmp/canonical-sorted.json" "$tmp/all-tool.json"; then
|
|
printf 'built dws schema canonical/primary/--all payloads differ: %s\n' "$canonical" >&2
|
|
exit 1
|
|
fi
|
|
|
|
done <"$tmp/commands.jsonl"
|
|
|
|
alias_command="$(jq -c 'first(.commands[] | select((.alias_cli_paths | length) > 0)) // empty' "$tmp/smoke-vector.json")"
|
|
if [ -n "$alias_command" ]; then
|
|
canonical="$(printf '%s\n' "$alias_command" | jq -r '.canonical_path')"
|
|
alias_path="$(printf '%s\n' "$alias_command" | jq -r '.alias_cli_paths[0]')"
|
|
"$BIN" schema "$canonical" --format json >"$tmp/canonical.json"
|
|
"$BIN" schema --cli-path "$alias_path" --format json >"$tmp/alias.json"
|
|
jq -S 'del(.cli_path, .is_alias)' "$tmp/canonical.json" >"$tmp/canonical-content.json"
|
|
jq -S 'del(.cli_path, .is_alias)' "$tmp/alias.json" >"$tmp/alias-content.json"
|
|
if ! cmp -s "$tmp/canonical-content.json" "$tmp/alias-content.json"; then
|
|
printf 'built dws schema alias changes fields other than cli_path/is_alias: %s\n' "$alias_path" >&2
|
|
exit 1
|
|
fi
|
|
if ! jq -e --arg canonical "$canonical" --arg alias_path "$alias_path" '
|
|
.canonical_path == $canonical and
|
|
.cli_path == $alias_path and
|
|
.is_alias == true
|
|
' "$tmp/alias.json" >/dev/null; then
|
|
printf 'built dws schema alias view fields are invalid: %s\n' "$alias_path" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
printf '%s\n' 'schema binary smoke: ok'
|