@boyingliu01/xp-gate 0.25.0 → 0.27.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.
Files changed (120) hide show
  1. package/adapters/python.sh +53 -3
  2. package/bin/xp-gate.js +161 -28
  3. package/hooks/lib/python-incremental-typecheck.sh +104 -0
  4. package/hooks/lib/typecheck.sh +10 -0
  5. package/hooks/pre-commit +84 -32
  6. package/lib/__tests__/check-alignment-cli.test.mjs +77 -0
  7. package/lib/__tests__/doctor-469-hook-env.test.js +12 -7
  8. package/lib/__tests__/doctor-module-resolution-parity.test.js +15 -6
  9. package/lib/__tests__/doctor-tui-skill-freshness.test.js +16 -4
  10. package/lib/__tests__/test-alignment.test.ts +37 -0
  11. package/lib/__tests__/windows-bash-probe.test.js +73 -0
  12. package/lib/check-alignment-runner.cjs +74 -0
  13. package/lib/detect-deps.js +82 -19
  14. package/lib/gate-runner.js +12 -5
  15. package/lib/mattpocock-license-verdict.json +1 -1
  16. package/lib/sprint-status.js +5 -2
  17. package/lib/test-alignment.ts +136 -12
  18. package/mock-policy/AGENTS.md +3 -3
  19. package/mutation/AGENTS.md +3 -3
  20. package/package.json +1 -1
  21. package/plugins/claude-code/.claude-plugin/plugin.json +1 -1
  22. package/plugins/claude-code/skills/delphi-review/AGENTS.md +3 -3
  23. package/plugins/claude-code/skills/sprint-flow/AGENTS.md +3 -3
  24. package/plugins/claude-code/skills/test-specification-alignment/AGENTS.md +3 -3
  25. package/plugins/dsh/README.md +1 -1
  26. package/plugins/dsh/package.json +1 -1
  27. package/plugins/dsh/scripts/prepack.cjs +2 -2
  28. package/plugins/dsh/skills/delphi-review/AGENTS.md +3 -3
  29. package/plugins/dsh/skills/sprint-flow/AGENTS.md +3 -3
  30. package/plugins/dsh/skills/test-specification-alignment/AGENTS.md +3 -3
  31. package/plugins/dsh/src/skills.test.ts +20 -7
  32. package/plugins/opencode/package.json +1 -1
  33. package/plugins/opencode/scripts/prepack.cjs +0 -1
  34. package/plugins/opencode/skills/delphi-review/AGENTS.md +3 -3
  35. package/plugins/opencode/skills/sprint-flow/AGENTS.md +3 -3
  36. package/plugins/opencode/skills/test-specification-alignment/AGENTS.md +3 -3
  37. package/plugins/qoder/plugin.json +1 -1
  38. package/plugins/qoder/skills/delphi-review/AGENTS.md +3 -3
  39. package/plugins/qoder/skills/sprint-flow/AGENTS.md +3 -3
  40. package/plugins/qoder/skills/test-specification-alignment/AGENTS.md +3 -3
  41. package/principles/AGENTS.md +3 -3
  42. package/principles/rules/__tests__/clean-code/code-duplication.test.ts +9 -8
  43. package/principles/rules/__tests__/clean-code/deep-nesting.test.ts +3 -4
  44. package/principles/rules/__tests__/clean-code/god-class.test.ts +2 -4
  45. package/principles/rules/__tests__/clean-code/large-file.test.ts +2 -4
  46. package/principles/rules/__tests__/clean-code/long-function.test.ts +2 -4
  47. package/principles/rules/__tests__/clean-code/many-exports.test.ts +2 -3
  48. package/principles/rules/__tests__/clean-code/missing-error-handling.test.ts +2 -4
  49. package/principles/rules/__tests__/clean-code/too-many-params.test.ts +2 -4
  50. package/principles/rules/__tests__/clean-code/unused-imports.test.ts +4 -4
  51. package/principles/rules/__tests__/solid/dip.test.ts +2 -4
  52. package/principles/rules/__tests__/solid/isp.test.ts +2 -4
  53. package/principles/rules/__tests__/solid/lsp.test.ts +2 -4
  54. package/principles/rules/__tests__/solid/ocp.test.ts +2 -4
  55. package/principles/rules/__tests__/solid/srp.test.ts +2 -4
  56. package/principles/rules/clean-code/code-duplication.ts +12 -14
  57. package/principles/rules/clean-code/deep-nesting.ts +18 -20
  58. package/principles/rules/clean-code/god-class.ts +32 -34
  59. package/principles/rules/clean-code/large-file.ts +14 -16
  60. package/principles/rules/clean-code/long-function.ts +26 -28
  61. package/principles/rules/clean-code/magic-numbers.ts +39 -38
  62. package/principles/rules/clean-code/many-exports.ts +21 -23
  63. package/principles/rules/clean-code/missing-error-handling.ts +13 -15
  64. package/principles/rules/clean-code/too-many-params.ts +15 -17
  65. package/principles/rules/clean-code/unused-imports.ts +13 -15
  66. package/principles/rules/solid/dip.ts +16 -18
  67. package/principles/rules/solid/isp.ts +17 -19
  68. package/principles/rules/solid/lsp.ts +4 -6
  69. package/principles/rules/solid/ocp.ts +17 -19
  70. package/principles/rules/solid/srp.ts +20 -22
  71. package/scripts/__tests__/sync-package-content.test.js +0 -1
  72. package/scripts/sync-package-content.js +0 -1
  73. package/skills/delphi-review/AGENTS.md +3 -3
  74. package/skills/sprint-flow/AGENTS.md +3 -3
  75. package/skills/test-specification-alignment/AGENTS.md +3 -3
  76. package/plugins/claude-code/skills/clipboard-vision/SKILL.md +0 -48
  77. package/plugins/claude-code/skills/clipboard-vision/__tests__/clipboard-vision-distribution.test.cjs +0 -64
  78. package/plugins/claude-code/skills/clipboard-vision/__tests__/clipboard-vision-security.test.cjs +0 -185
  79. package/plugins/claude-code/skills/clipboard-vision/__tests__/clipboard-vision.Tests.ps1 +0 -138
  80. package/plugins/claude-code/skills/clipboard-vision/__tests__/clipboard-vision.test.cjs +0 -273
  81. package/plugins/claude-code/skills/clipboard-vision/describe-clipboard.ps1 +0 -115
  82. package/plugins/claude-code/skills/clipboard-vision/describe-clipboard.sh +0 -161
  83. package/plugins/claude-code/skills/clipboard-vision/scripts/clipboard-vision.ps1 +0 -86
  84. package/plugins/claude-code/skills/clipboard-vision/scripts/clipboard-vision.sh +0 -137
  85. package/plugins/dsh/skills/clipboard-vision/SKILL.md +0 -48
  86. package/plugins/dsh/skills/clipboard-vision/__tests__/clipboard-vision-distribution.test.cjs +0 -64
  87. package/plugins/dsh/skills/clipboard-vision/__tests__/clipboard-vision-security.test.cjs +0 -185
  88. package/plugins/dsh/skills/clipboard-vision/__tests__/clipboard-vision.Tests.ps1 +0 -138
  89. package/plugins/dsh/skills/clipboard-vision/__tests__/clipboard-vision.test.cjs +0 -273
  90. package/plugins/dsh/skills/clipboard-vision/describe-clipboard.ps1 +0 -115
  91. package/plugins/dsh/skills/clipboard-vision/describe-clipboard.sh +0 -161
  92. package/plugins/dsh/skills/clipboard-vision/scripts/clipboard-vision.ps1 +0 -86
  93. package/plugins/dsh/skills/clipboard-vision/scripts/clipboard-vision.sh +0 -137
  94. package/plugins/opencode/skills/clipboard-vision/SKILL.md +0 -48
  95. package/plugins/opencode/skills/clipboard-vision/__tests__/clipboard-vision-distribution.test.cjs +0 -64
  96. package/plugins/opencode/skills/clipboard-vision/__tests__/clipboard-vision-security.test.cjs +0 -185
  97. package/plugins/opencode/skills/clipboard-vision/__tests__/clipboard-vision.Tests.ps1 +0 -138
  98. package/plugins/opencode/skills/clipboard-vision/__tests__/clipboard-vision.test.cjs +0 -273
  99. package/plugins/opencode/skills/clipboard-vision/describe-clipboard.ps1 +0 -115
  100. package/plugins/opencode/skills/clipboard-vision/describe-clipboard.sh +0 -161
  101. package/plugins/opencode/skills/clipboard-vision/scripts/clipboard-vision.ps1 +0 -86
  102. package/plugins/opencode/skills/clipboard-vision/scripts/clipboard-vision.sh +0 -137
  103. package/plugins/qoder/skills/clipboard-vision/SKILL.md +0 -48
  104. package/plugins/qoder/skills/clipboard-vision/__tests__/clipboard-vision-distribution.test.cjs +0 -64
  105. package/plugins/qoder/skills/clipboard-vision/__tests__/clipboard-vision-security.test.cjs +0 -185
  106. package/plugins/qoder/skills/clipboard-vision/__tests__/clipboard-vision.Tests.ps1 +0 -138
  107. package/plugins/qoder/skills/clipboard-vision/__tests__/clipboard-vision.test.cjs +0 -273
  108. package/plugins/qoder/skills/clipboard-vision/describe-clipboard.ps1 +0 -115
  109. package/plugins/qoder/skills/clipboard-vision/describe-clipboard.sh +0 -161
  110. package/plugins/qoder/skills/clipboard-vision/scripts/clipboard-vision.ps1 +0 -86
  111. package/plugins/qoder/skills/clipboard-vision/scripts/clipboard-vision.sh +0 -137
  112. package/skills/clipboard-vision/SKILL.md +0 -48
  113. package/skills/clipboard-vision/__tests__/clipboard-vision-distribution.test.cjs +0 -64
  114. package/skills/clipboard-vision/__tests__/clipboard-vision-security.test.cjs +0 -185
  115. package/skills/clipboard-vision/__tests__/clipboard-vision.Tests.ps1 +0 -138
  116. package/skills/clipboard-vision/__tests__/clipboard-vision.test.cjs +0 -273
  117. package/skills/clipboard-vision/describe-clipboard.ps1 +0 -115
  118. package/skills/clipboard-vision/describe-clipboard.sh +0 -161
  119. package/skills/clipboard-vision/scripts/clipboard-vision.ps1 +0 -86
  120. package/skills/clipboard-vision/scripts/clipboard-vision.sh +0 -137
@@ -1,137 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- api_base="${CLIPBOARD_VISION_API_BASE:-http://127.0.0.1:11434/v1}"
5
- model="${CLIPBOARD_VISION_MODEL:-}"
6
- api_key="${CLIPBOARD_VISION_API_KEY:-}"
7
- max_bytes="${CLIPBOARD_VISION_MAX_BYTES:-10485760}"
8
- allow_remote=false
9
- confirm_remote=""
10
- while [ "$#" -gt 0 ]; do
11
- case "$1" in
12
- --allow-remote) allow_remote=true; shift ;;
13
- --confirm-remote)
14
- [ "$#" -ge 2 ] || { printf '%s\n' 'Error: --confirm-remote requires the disclosed token' >&2; exit 2; }
15
- confirm_remote="$2"
16
- shift 2
17
- ;;
18
- --help)
19
- printf '%s\n' 'Usage: clipboard-vision.sh [--allow-remote --confirm-remote TOKEN]'
20
- exit 0
21
- ;;
22
- *) printf 'Error: unknown option: %s\n' "$1" >&2; exit 2 ;;
23
- esac
24
- done
25
-
26
- [ -n "$model" ] || { printf '%s\n' 'Error: CLIPBOARD_VISION_MODEL is required' >&2; exit 2; }
27
- case "$max_bytes" in *[!0-9]*|'') printf '%s\n' 'Error: CLIPBOARD_VISION_MAX_BYTES must be a positive integer' >&2; exit 2 ;; esac
28
- [ "$max_bytes" -gt 0 ] || { printf '%s\n' 'Error: CLIPBOARD_VISION_MAX_BYTES must be positive' >&2; exit 2; }
29
-
30
- endpoint_info=$(python3 - "$api_base" "$model" <<'PY'
31
- import hashlib
32
- import ipaddress
33
- import sys
34
- import urllib.parse
35
-
36
- url = urllib.parse.urlparse(sys.argv[1])
37
- if url.scheme not in {"http", "https"} or not url.hostname or url.username or url.password or url.query or url.fragment:
38
- raise SystemExit(2)
39
- try:
40
- loopback = ipaddress.ip_address(url.hostname).is_loopback
41
- except ValueError:
42
- loopback = False
43
- try:
44
- port = url.port or (443 if url.scheme == "https" else 80)
45
- except ValueError:
46
- raise SystemExit(2)
47
- print("local" if loopback else "remote")
48
- hostname = url.hostname.lower()
49
- print(hostname)
50
- display_host = f"[{hostname}]" if ":" in hostname else hostname
51
- base_path = url.path.rstrip("/")
52
- effective = f"{url.scheme.lower()}://{display_host}:{port}{base_path}/chat/completions"
53
- print(effective)
54
- print(hashlib.sha256(f"{effective}\n{sys.argv[2]}".encode()).hexdigest())
55
- PY
56
- ) || { printf '%s\n' 'Error: invalid CLIPBOARD_VISION_API_BASE' >&2; exit 2; }
57
- endpoint_kind=$(printf '%s\n' "$endpoint_info" | sed -n '1p')
58
- effective_endpoint=$(printf '%s\n' "$endpoint_info" | sed -n '3p')
59
- expected_confirmation=$(printf '%s\n' "$endpoint_info" | sed -n '4p')
60
-
61
- if [ "$endpoint_kind" = remote ]; then
62
- printf 'Remote disclosure: clipboard image data will be sent to %s using model %s.\n' "$effective_endpoint" "$model" >&2
63
- printf 'Confirmation token for this canonical endpoint and model: %s\n' "$expected_confirmation" >&2
64
- if [ "$allow_remote" != true ] || [ "$confirm_remote" != "$expected_confirmation" ]; then
65
- printf '%s\n' 'Error: remote endpoint requires --allow-remote and the disclosed --confirm-remote token' >&2
66
- exit 2
67
- fi
68
- fi
69
-
70
- work_dir=$(mktemp -d "${TMPDIR:-/tmp}/clipboard-vision.XXXXXX")
71
- image_file="$work_dir/clipboard.png"
72
- request_file="$work_dir/request.json"
73
- response_file="$work_dir/response.json"
74
- auth_file="$work_dir/auth-header"
75
- cleanup() { rm -rf -- "$work_dir"; }
76
- trap cleanup EXIT HUP INT TERM
77
-
78
- if command -v pngpaste >/dev/null 2>&1; then
79
- pngpaste "$image_file"
80
- elif command -v wl-paste >/dev/null 2>&1; then
81
- wl-paste --no-newline --type image/png > "$image_file"
82
- elif command -v import >/dev/null 2>&1; then
83
- import clipboard: "$image_file"
84
- else
85
- printf '%s\n' 'Error: install pngpaste, wl-paste, or ImageMagick import' >&2
86
- exit 2
87
- fi
88
-
89
- [ -s "$image_file" ] || { printf '%s\n' 'Error: clipboard does not contain an image' >&2; exit 2; }
90
- image_bytes=$(wc -c < "$image_file" | tr -d '[:space:]')
91
- [ "$image_bytes" -le "$max_bytes" ] || { printf 'Error: clipboard image exceeds %s bytes\n' "$max_bytes" >&2; exit 2; }
92
-
93
- python3 - "$image_file" "$request_file" "$model" <<'PY'
94
- import base64
95
- import json
96
- import pathlib
97
- import sys
98
-
99
- image = base64.b64encode(pathlib.Path(sys.argv[1]).read_bytes()).decode("ascii")
100
- request = {
101
- "model": sys.argv[3],
102
- "messages": [{"role": "user", "content": [
103
- {"type": "text", "text": "Describe this clipboard image."},
104
- {"type": "image_url", "image_url": {"url": "data:image/png;base64," + image}},
105
- ]}],
106
- }
107
- pathlib.Path(sys.argv[2]).write_text(json.dumps(request), encoding="utf-8")
108
- PY
109
-
110
- curl_args=(--silent --show-error --max-redirs 0 --output "$response_file" --write-out '%{http_code}' --header 'Content-Type: application/json' --data-binary "@$request_file")
111
- if [ -n "$api_key" ]; then
112
- case "$api_key" in *$'\n'*|*$'\r'*) printf '%s\n' 'Error: invalid CLIPBOARD_VISION_API_KEY' >&2; exit 2 ;; esac
113
- umask 077
114
- printf 'Authorization: Bearer %s\n' "$api_key" > "$auth_file"
115
- chmod 600 "$auth_file"
116
- curl_args+=(--header "@$auth_file")
117
- fi
118
- status=$(curl "${curl_args[@]}" "$effective_endpoint") || { printf '%s\n' 'Error: vision API request failed' >&2; exit 1; }
119
- case "$status" in 2??) ;; *) printf 'Error: vision API returned HTTP %s (body redacted)\n' "$status" >&2; exit 1 ;; esac
120
-
121
- result=$(python3 - "$response_file" <<'PY'
122
- import json
123
- import pathlib
124
- import sys
125
-
126
- try:
127
- data = json.loads(pathlib.Path(sys.argv[1]).read_text(encoding="utf-8"))
128
- value = data["choices"][0]["message"]["content"]
129
- if not isinstance(value, str):
130
- raise ValueError
131
- except (KeyError, IndexError, TypeError, ValueError, json.JSONDecodeError):
132
- raise SystemExit(2)
133
- print(value)
134
- PY
135
- ) || { printf '%s\n' 'Error: invalid vision API response (body redacted)' >&2; exit 1; }
136
-
137
- printf '%s\n' "$result"