@boyingliu01/xp-gate 0.19.1 → 0.19.3

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 (87) hide show
  1. package/gate-10.sh +105 -0
  2. package/hooks/pre-commit +24 -5
  3. package/lib/__tests__/npm-package.test.js +25 -0
  4. package/lib/mattpocock-license-verdict.json +1 -1
  5. package/mock-policy/AGENTS.md +3 -3
  6. package/mutation/AGENTS.md +3 -3
  7. package/package.json +2 -1
  8. package/plugins/claude-code/.claude-plugin/plugin.json +2 -2
  9. package/plugins/claude-code/skills/delphi-review/AGENTS.md +3 -3
  10. package/plugins/claude-code/skills/sprint-flow/AGENTS.md +3 -3
  11. package/plugins/claude-code/skills/test-specification-alignment/AGENTS.md +3 -3
  12. package/plugins/dsh/package.json +1 -1
  13. package/plugins/dsh/skills/delphi-review/AGENTS.md +3 -3
  14. package/plugins/dsh/skills/sprint-flow/AGENTS.md +3 -3
  15. package/plugins/dsh/skills/test-specification-alignment/AGENTS.md +3 -3
  16. package/plugins/opencode/package.json +1 -1
  17. package/plugins/opencode/skills/delphi-review/AGENTS.md +3 -3
  18. package/plugins/opencode/skills/sprint-flow/AGENTS.md +3 -3
  19. package/plugins/opencode/skills/test-specification-alignment/AGENTS.md +3 -3
  20. package/plugins/qoder/plugin.json +2 -2
  21. package/plugins/qoder/skills/admin-template-guidelines/SKILL.md +6 -797
  22. package/plugins/qoder/skills/admin-template-guidelines/references/rule-1.md +91 -0
  23. package/plugins/qoder/skills/admin-template-guidelines/references/rule-2.md +155 -0
  24. package/plugins/qoder/skills/admin-template-guidelines/references/rule-3.md +70 -0
  25. package/plugins/qoder/skills/admin-template-guidelines/references/rule-4.md +154 -0
  26. package/plugins/qoder/skills/admin-template-guidelines/references/rule-5.md +126 -0
  27. package/plugins/qoder/skills/admin-template-guidelines/references/rule-6.md +180 -0
  28. package/plugins/qoder/skills/batch-grill-me/SKILL.md +15 -0
  29. package/plugins/qoder/skills/clipboard-vision/describe-clipboard.ps1 +115 -0
  30. package/plugins/qoder/skills/clipboard-vision/describe-clipboard.sh +161 -0
  31. package/plugins/qoder/skills/delphi-review/.delphi-config.json.example +61 -28
  32. package/plugins/qoder/skills/delphi-review/AGENTS.md +3 -3
  33. package/plugins/qoder/skills/delphi-review/INSTALL.md +97 -98
  34. package/plugins/qoder/skills/delphi-review/SKILL.md +77 -54
  35. package/plugins/qoder/skills/delphi-review/hooks.md +19 -0
  36. package/plugins/qoder/skills/delphi-review/opencode.json.delphi.example +6 -10
  37. package/plugins/qoder/skills/delphi-review/references/orchestrator-dispatch.md +64 -0
  38. package/plugins/qoder/skills/delphi-review/references/requirements.md +402 -0
  39. package/plugins/qoder/skills/delphi-review/references/round-templates.md +134 -0
  40. package/plugins/qoder/skills/delphi-review/scripts/verify-consensus.sh +43 -0
  41. package/plugins/qoder/skills/delphi-review/tools.md +29 -0
  42. package/plugins/qoder/skills/domain-modeling/ADR-FORMAT.md +64 -0
  43. package/plugins/qoder/skills/domain-modeling/CONTEXT-FORMAT.md +60 -0
  44. package/plugins/qoder/skills/domain-modeling/SKILL.md +74 -0
  45. package/plugins/qoder/skills/grill-with-docs/SKILL.md +7 -0
  46. package/plugins/qoder/skills/grilling/SKILL.md +12 -0
  47. package/plugins/qoder/skills/ralph-loop/SKILL.md +87 -428
  48. package/plugins/qoder/skills/ralph-loop/references/components.md +113 -0
  49. package/plugins/qoder/skills/ralph-loop/references/workflow-details.md +99 -0
  50. package/plugins/qoder/skills/sprint-flow/AGENTS.md +4 -4
  51. package/plugins/qoder/skills/sprint-flow/SKILL.md +255 -454
  52. package/plugins/qoder/skills/sprint-flow/__tests__/sprint-flow.test.cjs +457 -0
  53. package/plugins/qoder/skills/sprint-flow/hooks.md +18 -0
  54. package/plugins/qoder/skills/sprint-flow/references/components/memory.md +1 -1
  55. package/plugins/qoder/skills/sprint-flow/references/components/middleware.md +1 -1
  56. package/plugins/qoder/skills/sprint-flow/references/components/skill-invocations.md +21 -20
  57. package/plugins/qoder/skills/sprint-flow/references/components/tool-descriptions.md +22 -23
  58. package/plugins/qoder/skills/sprint-flow/references/force-levels.md +0 -1
  59. package/plugins/qoder/skills/sprint-flow/references/orchestration-rules.md +34 -27
  60. package/plugins/qoder/skills/sprint-flow/references/phase-1-prep.md +1 -1
  61. package/plugins/qoder/skills/sprint-flow/references/phase-2-design.md +157 -120
  62. package/plugins/qoder/skills/sprint-flow/references/phase-3-build.md +203 -2
  63. package/plugins/qoder/skills/sprint-flow/references/phase-4-verify.md +107 -34
  64. package/plugins/qoder/skills/sprint-flow/references/phase-5-ship.md +194 -12
  65. package/plugins/qoder/skills/sprint-flow/references/phase-6-close.md +139 -7
  66. package/plugins/qoder/skills/sprint-flow/references/phase-overview.md +486 -0
  67. package/plugins/qoder/skills/sprint-flow/scripts/verify-sprint-state.sh +38 -0
  68. package/plugins/qoder/skills/sprint-flow/tools.md +29 -0
  69. package/plugins/qoder/skills/test-specification-alignment/AGENTS.md +3 -3
  70. package/plugins/qoder/skills/test-specification-alignment/SKILL.md +104 -601
  71. package/plugins/qoder/skills/to-issues/SKILL.md +1 -1
  72. package/principles/AGENTS.md +3 -3
  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/qoder/skills/clipboard-vision/clipboard-vision/SKILL.md +0 -47
  77. package/plugins/qoder/skills/clipboard-vision/clipboard-vision/__tests__/clipboard-vision-distribution.test.cjs +0 -65
  78. package/plugins/qoder/skills/clipboard-vision/clipboard-vision/__tests__/clipboard-vision-security.test.cjs +0 -185
  79. package/plugins/qoder/skills/clipboard-vision/clipboard-vision/__tests__/clipboard-vision.Tests.ps1 +0 -138
  80. package/plugins/qoder/skills/clipboard-vision/clipboard-vision/__tests__/clipboard-vision.test.cjs +0 -273
  81. package/plugins/qoder/skills/clipboard-vision/clipboard-vision/scripts/clipboard-vision.ps1 +0 -86
  82. package/plugins/qoder/skills/clipboard-vision/clipboard-vision/scripts/clipboard-vision.sh +0 -137
  83. package/plugins/qoder/skills/ralph-loop/references/components/memory.md +0 -55
  84. package/plugins/qoder/skills/ralph-loop/references/components/middleware.md +0 -54
  85. package/plugins/qoder/skills/ralph-loop/references/components/skill-invocations.md +0 -39
  86. package/plugins/qoder/skills/ralph-loop/references/components/system-prompt.md +0 -24
  87. package/plugins/qoder/skills/ralph-loop/references/components/tool-descriptions.md +0 -32
@@ -0,0 +1,180 @@
1
+ # Rule 6: HTMX + Alpine Separation — Examples
2
+
3
+ ## ❌ 错误示例:HTMX 与 Alpine 混用
4
+
5
+ ```nunjucks
6
+ {# admin/views/plans.njk — 反模式 #}
7
+
8
+ {# 使用 Alpine 做服务端请求 — 职责错误 #}
9
+ <div x-data="{ plans: [], loading: false }"
10
+ x-init="loading = true; fetch('/admin/api/plans').then(r => r.json()).then(d => plans = d); loading = false">
11
+ <template x-for="plan in plans" :key="plan.id">
12
+ <div>
13
+ <span x-text="plan.name"></span>
14
+ {# 删除操作使用 Alpine 而非 HTMX — 失去服务端渲染优势 #}
15
+ <button @click="fetch('/admin/plans/' + plan.id, { method: 'DELETE' })
16
+ .then(() => plans = plans.filter(p => p.id !== plan.id))">
17
+ Delete
18
+ </button>
19
+ </div>
20
+ </template>
21
+ </div>
22
+
23
+ {# HTMX 驱动下拉菜单状态 — 职责错误 #}
24
+ <div hx-get="/admin/plans" hx-swap="innerHTML">
25
+ <button hx-on::after-request="this.nextElementSibling.style.display = 'block'">
26
+ Show Filters
27
+ </button>
28
+ <div style="display: none">
29
+ <input type="text" name="search" placeholder="Search..."
30
+ hx-get="/admin/plans" hx-trigger="keyup changed delay:300ms" />
31
+ </div>
32
+ </div>
33
+ ```
34
+
35
+ ## ✅ 正确示例:职责分离
36
+
37
+ ```nunjucks
38
+ {# admin/views/plans.njk #}
39
+
40
+ {# 整体布局与内容列表由 HTMX 驱动 #}
41
+ <div id="plans-content" hx-boost="true">
42
+ <div class="header-bar" x-data="{ showFilters: false }">
43
+ <h1>Interview Plans</h1>
44
+
45
+ {# 下拉菜单状态由 Alpine 管理 #}
46
+ <button type="button" @click="showFilters = !showFilters"
47
+ :class="{ 'active': showFilters }">
48
+ Filters
49
+ </button>
50
+
51
+ {# Alpine 控制本地显示/隐藏 #}
52
+ <div x-show="showFilters" x-transition class="filter-panel">
53
+ {# 搜索输入通过 HTMX 触发服务端请求 #}
54
+ <input type="text" name="search" placeholder="Search plans..."
55
+ hx-get="/admin/plans"
56
+ hx-target="#plans-list"
57
+ hx-trigger="keyup changed delay:300ms"
58
+ hx-indicator=".search-spinner" />
59
+ </div>
60
+ </div>
61
+
62
+ {# 列表内容完全由 HTMX 服务端渲染 #}
63
+ <div id="plans-list">
64
+ {% for plan in plans %}
65
+ <div class="plan-card" id="plan-{{ plan.id }}">
66
+ <h3>{{ plan.name }}</h3>
67
+ <p>Status: {{ plan.status | upper }}</p>
68
+ <p>Completion: {{ plan.completionRate | round(1) }}%</p>
69
+
70
+ <div class="actions">
71
+ {# 删除操作通过 HTMX 提交,服务端响应更新 DOM #}
72
+ <button class="btn-danger"
73
+ hx-delete="/admin/plans/{{ plan.id }}"
74
+ hx-target="#plan-{{ plan.id }}"
75
+ hx-swap="outerHTML"
76
+ hx-confirm="Are you sure you want to delete this plan?"
77
+ x-data="{ deleting: false }"
78
+ hx-on::before-request="deleting = true"
79
+ hx-on::after-request="deleting = false">
80
+ <span x-show="!deleting">Delete</span>
81
+ <span x-show="deleting" class="spinner">Deleting...</span>
82
+ </button>
83
+ </div>
84
+ </div>
85
+ {% endfor %}
86
+ </div>
87
+ </div>
88
+ ```
89
+
90
+ ```nunjucks
91
+ {# admin/views/modals/confirm-delete.njk — Modal 由 Alpine 管理 #}
92
+
93
+ <div x-data="{ open: false, targetId: null, targetName: '' }"
94
+ @open-modal.window="open = true; targetId = $event.detail.id; targetName = $event.detail.name"
95
+ x-show="open"
96
+ x-cloak
97
+ class="modal-backdrop"
98
+ @click.self="open = false">
99
+
100
+ <div class="modal-content" x-transition>
101
+ <h2>Confirm Delete</h2>
102
+ <p>Are you sure you want to delete "<span x-text="targetName"></span>"?</p>
103
+
104
+ <div class="modal-actions">
105
+ <button @click="open = false">Cancel</button>
106
+
107
+ {# 真正的删除操作通过 HTMX 提交 #}
108
+ <button class="btn-danger"
109
+ hx-delete="/admin/plans/"
110
+ hx-vals='js:{ id: targetId }'
111
+ hx-target="#plans-list"
112
+ @click="open = false">
113
+ Confirm Delete
114
+ </button>
115
+ </div>
116
+ </div>
117
+ </div>
118
+ ```
119
+
120
+ ```nunjucks
121
+ {# admin/views/templates/edit.njk — 表单字段本地验证由 Alpine 管理 #}
122
+
123
+ <form x-data="{
124
+ name: '',
125
+ nameError: '',
126
+ content: '',
127
+ contentError: '',
128
+ get isValid() {
129
+ return this.name.length > 0 && this.content.length > 0 && !this.nameError && !this.contentError;
130
+ },
131
+ validateName(value) {
132
+ this.name = value;
133
+ this.nameError = value.length < 3 ? 'Name must be at least 3 characters.' : '';
134
+ },
135
+ validateContent(value) {
136
+ this.content = value;
137
+ this.contentError = value.trim().length === 0 ? 'Content cannot be empty.' : '';
138
+ }
139
+ }" hx-post="/admin/templates/{{ template.id }}"
140
+ hx-target="#form-result"
141
+ hx-swap="innerHTML"
142
+ hx-on::before-request="if (!isValid) { $event.preventDefault(); }">
143
+
144
+ <div class="form-group">
145
+ <label for="name">Template Name</label>
146
+ <input type="text" id="name" name="name"
147
+ x-model="name"
148
+ @input="validateName(name)"
149
+ :class="{ 'error': nameError }"
150
+ value="{{ template.name }}" />
151
+ <span x-show="nameError" x-text="nameError" class="field-error"></span>
152
+ </div>
153
+
154
+ <div class="form-group">
155
+ <label for="content">Template Content</label>
156
+ <textarea id="content" name="content" rows="20"
157
+ x-model="content"
158
+ @input="validateContent(content)"
159
+ :class="{ 'error': contentError }">{{ template.content }}</textarea>
160
+ <span x-show="contentError" x-text="contentError" class="field-error"></span>
161
+ </div>
162
+
163
+ <div class="form-actions">
164
+ <button type="submit" :disabled="!isValid" class="btn-primary">
165
+ Save Template
166
+ </button>
167
+ <a href="/admin/templates" class="btn-secondary">Cancel</a>
168
+ </div>
169
+ </form>
170
+
171
+ {# HTMX 响应结果区域 #}
172
+ <div id="form-result"></div>
173
+ ```
174
+
175
+ ## 分离原则
176
+
177
+ 1. **HTMX 是服务端与 DOM 之间的桥梁** — 所有数据变更、页面导航、内容更新必须通过 HTMX
178
+ 2. **Alpine 是组件状态的管理者** — 只管理不需要服务端参与的 UI 状态(开关、显隐、验证)
179
+ 3. **HTMX 属性不应操作 DOM 状态** — `hx-on::after-request` 里不应出现 `element.style.display`
180
+ 4. **Alpine 方法不应发起 fetch** — `@click="fetch('/api/...')"` 是反模式,应用 `hx-get/hx-post`
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: batch-grill-me
3
+ description: A relentless interview that asks every frontier question at once, round by round.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ Interview the user relentlessly until you reach a shared understanding. Map this as a **design tree**: every decision branches into the decisions that hang off it.
8
+
9
+ Work the tree in **rounds**. The **frontier** is every decision whose prerequisites are already settled — the questions you can ask *now* without guessing at answers you haven't heard yet. Ask the whole frontier in one round: number each question and give your recommended answer. Then wait for the user's answers before the next round.
10
+
11
+ Each round the user answers reshapes the tree — settled decisions push the frontier outward and unblock questions that depended on them. Recompute the frontier and ask the next round. A question whose answer depends on another question still open in this round belongs to a *later* round, not this one.
12
+
13
+ Finding *facts* is your job, never the user's. When a frontier question needs a fact from the environment (filesystem, tools, etc.), dispatch a sub-agent to find it — don't ask the user for anything you could look up yourself. Don't block on it: a running exploration is an unsettled prerequisite, so only the questions downstream of it wait for the sub-agent to report — ask the rest of the frontier now. The *decisions* are the user's — put each to them and wait.
14
+
15
+ The session is done when the frontier is empty: every branch of the design tree visited, nothing left silently assumed. Do not act on it until the user confirms you have reached a shared understanding.
@@ -0,0 +1,115 @@
1
+ # describe-clipboard.ps1
2
+ # Reads image from clipboard, sends to vision model API, writes description to stdout.
3
+ # API key is read from CLIPBOARD_VISION_API_KEY environment variable.
4
+ # WARNING: Do not enable -Verbose or Set-PSDebug -Trace 2 — the API key would be logged.
5
+ param(
6
+ [string]$OutputFile = "$env:TEMP\clipboard_desc.txt"
7
+ )
8
+
9
+ $ErrorActionPreference = "Stop"
10
+
11
+ # Platform guard
12
+ if (-not $IsWindows) {
13
+ Write-Host "ERROR: This script requires Windows (uses .NET System.Windows.Forms)"
14
+ exit 1
15
+ }
16
+
17
+ $apiKey = $env:CLIPBOARD_VISION_API_KEY
18
+ if (-not $apiKey) {
19
+ Write-Host "ERROR: CLIPBOARD_VISION_API_KEY environment variable not set"
20
+ exit 1
21
+ }
22
+
23
+ $tempPng = $null
24
+ $img = $null
25
+
26
+ try {
27
+ # --- Read clipboard image ---
28
+ Add-Type -AssemblyName System.Windows.Forms -ErrorAction Stop
29
+ Add-Type -AssemblyName System.Drawing -ErrorAction Stop
30
+
31
+ $img = [System.Windows.Forms.Clipboard]::GetImage()
32
+ if (-not $img) {
33
+ Write-Host "ERROR: No image found in clipboard"
34
+ exit 1
35
+ }
36
+
37
+ # Save to temp PNG
38
+ $tempPng = Join-Path $env:TEMP "clipboard_$(Get-Date -Format 'yyyyMMdd_HHmmss').png"
39
+ $img.Save($tempPng, [System.Drawing.Imaging.ImageFormat]::Png)
40
+
41
+ # Convert to base64
42
+ $bytes = [System.IO.File]::ReadAllBytes($tempPng)
43
+ $base64 = [System.Convert]::ToBase64String($bytes)
44
+
45
+ # --- Build API request ---
46
+ $apiBase = "https://lab.iwhalecloud.com/gpt-proxy"
47
+ $model = "LOCAL/Qwen3.5-122B-A10B"
48
+
49
+ $body = @{
50
+ model = $model
51
+ messages = @(
52
+ @{
53
+ role = "user"
54
+ content = @(
55
+ @{
56
+ type = "text"
57
+ text = "Describe this image in detail. Include all visible text, UI elements, code, error messages, objects, people, and any information conveyed. Be specific and thorough but concise. If it contains code or terminal output, quote it exactly."
58
+ },
59
+ @{
60
+ type = "image_url"
61
+ image_url = @{
62
+ url = "data:image/png;base64,$base64"
63
+ }
64
+ }
65
+ )
66
+ }
67
+ )
68
+ max_tokens = 1024
69
+ temperature = 0.1
70
+ } | ConvertTo-Json -Depth 5
71
+
72
+ # --- Call API ---
73
+ $response = Invoke-RestMethod -Uri "$apiBase/chat/completions" `
74
+ -Method Post `
75
+ -Headers @{
76
+ "Authorization" = "Bearer $apiKey"
77
+ "Content-Type" = "application/json"
78
+ } `
79
+ -Body ([System.Text.Encoding]::UTF8.GetBytes($body)) `
80
+ -TimeoutSec 30
81
+
82
+ # Validate response structure
83
+ if (-not $response.choices -or -not $response.choices[0].message -or -not $response.choices[0].message.content) {
84
+ Write-Host "ERROR: Unexpected API response structure"
85
+ Write-Host "Response: $($response | ConvertTo-Json -Compress -Depth 2)"
86
+ exit 1
87
+ }
88
+
89
+ $description = $response.choices[0].message.content
90
+ } catch {
91
+ Write-Host "ERROR: $_"
92
+ exit 1
93
+ } finally {
94
+ # Cleanup temp file and GDI+ handle
95
+ if ($tempPng -and (Test-Path $tempPng)) {
96
+ Remove-Item $tempPng -Force -ErrorAction SilentlyContinue
97
+ }
98
+ if ($img) {
99
+ $img.Dispose()
100
+ }
101
+ }
102
+
103
+ if (-not $description) {
104
+ Write-Host "ERROR: Empty response from vision model"
105
+ exit 1
106
+ }
107
+
108
+ # Write to output file
109
+ $description | Out-File -FilePath $OutputFile -Encoding UTF8 -Force
110
+
111
+ # Output to stdout
112
+ Write-Host "Clipboard image description saved to: $OutputFile"
113
+ Write-Host "---"
114
+ Write-Host $description
115
+ Write-Host "---"
@@ -0,0 +1,161 @@
1
+ #!/usr/bin/env bash
2
+ # describe-clipboard.sh
3
+ # Cross-platform: reads clipboard image, calls vision API, writes description.
4
+ # Works on: WSL/Linux (xclip), macOS (osascript), Windows Git Bash (PowerShell)
5
+ #
6
+ # Requires CLIPBOARD_VISION_API_KEY environment variable.
7
+ # WARNING: Do not run with `set -x` — the API key would be logged.
8
+ set -euo pipefail
9
+
10
+ OUTPUT_FILE="${1:-/tmp/clipboard_desc.txt}"
11
+ API_KEY="${CLIPBOARD_VISION_API_KEY:-}"
12
+ API_BASE="${CLIPBOARD_VISION_API_BASE:-https://lab.iwhalecloud.com/gpt-proxy}"
13
+ MODEL="LOCAL/Qwen3.5-122B-A10B"
14
+ TEMP_PNG=""
15
+
16
+ if [ -z "$API_KEY" ]; then
17
+ echo "ERROR: CLIPBOARD_VISION_API_KEY environment variable not set" >&2
18
+ exit 1
19
+ fi
20
+
21
+ cleanup() {
22
+ if [ -n "$TEMP_PNG" ] && [ -f "$TEMP_PNG" ]; then
23
+ rm -f "$TEMP_PNG"
24
+ fi
25
+ }
26
+ trap cleanup EXIT
27
+
28
+ # --- Detect platform and read clipboard ---
29
+ get_base64_from_clipboard() {
30
+ local platform b64_cmd
31
+ platform="$(uname -s)"
32
+
33
+ if [ "$platform" = "Linux" ]; then
34
+ b64_cmd="base64 -w 0"
35
+ # WSL / Linux: use xclip or wl-paste
36
+ if command -v xclip &>/dev/null; then
37
+ TARGETS="$(xclip -selection clipboard -o -t TARGETS 2>/dev/null || echo "")"
38
+ if echo "$TARGETS" | grep -qx "image/png"; then
39
+ TEMP_PNG="$(mktemp /tmp/clipboard_XXXXXX.png)"
40
+ xclip -selection clipboard -o -t image/png > "$TEMP_PNG"
41
+ $b64_cmd "$TEMP_PNG"
42
+ else
43
+ echo "ERROR: No PNG image in clipboard (xclip targets: ${TARGETS:-none})" >&2
44
+ exit 1
45
+ fi
46
+ elif command -v wl-paste &>/dev/null; then
47
+ TEMP_PNG="$(mktemp /tmp/clipboard_XXXXXX.png)"
48
+ wl-paste -t image/png > "$TEMP_PNG"
49
+ $b64_cmd "$TEMP_PNG"
50
+ else
51
+ echo "ERROR: No clipboard tool found (install xclip or wl-clipboard)" >&2
52
+ exit 1
53
+ fi
54
+ elif [ "$platform" = "MINGW64_NT" ] || [ "$platform" = "MSYS_NT" ] || [ "${OS:-}" = "Windows_NT" ]; then
55
+ b64_cmd="base64 -w 0"
56
+ # Windows Git Bash: delegate to PowerShell
57
+ PS_EXE="/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe"
58
+ if [ ! -f "$PS_EXE" ]; then
59
+ PS_EXE="powershell.exe"
60
+ fi
61
+ TEMP_PNG="$(mktemp --suffix=.png)"
62
+ WIN_TEMP="$(cygpath -w "$TEMP_PNG" 2>/dev/null || echo "$TEMP_PNG")"
63
+ "$PS_EXE" -NoProfile -NonInteractive -Command "
64
+ Add-Type -AssemblyName System.Windows.Forms;
65
+ Add-Type -AssemblyName System.Drawing;
66
+ \$img = [System.Windows.Forms.Clipboard]::GetImage();
67
+ if (-not \$img) { Write-Host 'NO_IMAGE'; exit 1 };
68
+ \$img.Save('$WIN_TEMP', [System.Drawing.Imaging.ImageFormat]::Png);
69
+ Write-Host 'OK';
70
+ " > /dev/null
71
+ if [ ! -f "$TEMP_PNG" ] || [ ! -s "$TEMP_PNG" ]; then
72
+ echo "ERROR: No image found in clipboard" >&2
73
+ exit 1
74
+ fi
75
+ $b64_cmd "$TEMP_PNG"
76
+ else
77
+ # macOS
78
+ b64_cmd="base64 -b 0"
79
+ if command -v osascript &>/dev/null; then
80
+ TEMP_PNG="$(mktemp /tmp/clipboard_XXXXXX.png)"
81
+ if ! osascript -e "set theFile to (open for access POSIX file \"$TEMP_PNG\" with write permission)" \
82
+ -e "write (the clipboard as «class PNGf») to theFile" \
83
+ -e "close access theFile" 2>/dev/null; then
84
+ echo "ERROR: Failed to read image from macOS clipboard" >&2
85
+ exit 1
86
+ fi
87
+ if [ ! -s "$TEMP_PNG" ]; then
88
+ echo "ERROR: No image in clipboard" >&2
89
+ exit 1
90
+ fi
91
+ $b64_cmd "$TEMP_PNG"
92
+ else
93
+ echo "ERROR: Unsupported platform ($platform)" >&2
94
+ exit 1
95
+ fi
96
+ fi
97
+ }
98
+
99
+ # --- Build and send API request via python3 (safe JSON construction) ---
100
+ call_vision_api() {
101
+ local b64="$1"
102
+ python3 -c "
103
+ import json, sys, os, urllib.request
104
+
105
+ api_key = os.environ['CLIPBOARD_VISION_API_KEY']
106
+ api_base = os.environ.get('CLIPBOARD_VISION_API_BASE', 'https://lab.iwhalecloud.com/gpt-proxy')
107
+ model = 'LOCAL/Qwen3.5-122B-A10B'
108
+
109
+ body = json.dumps({
110
+ 'model': model,
111
+ 'messages': [{
112
+ 'role': 'user',
113
+ 'content': [
114
+ {'type': 'text', 'text': 'Describe this image in detail. Include all visible text, UI elements, code, error messages, objects, people, and any information conveyed. Be specific and thorough but concise. If it contains code or terminal output, quote it exactly.'},
115
+ {'type': 'image_url', 'image_url': {'url': f'data:image/png;base64,{sys.argv[1]}'}}
116
+ ]
117
+ }],
118
+ 'max_tokens': 1024,
119
+ 'temperature': 0.1
120
+ }).encode('utf-8')
121
+
122
+ req = urllib.request.Request(
123
+ f'{api_base}/chat/completions',
124
+ data=body,
125
+ headers={
126
+ 'Authorization': f'Bearer {api_key}',
127
+ 'Content-Type': 'application/json'
128
+ }
129
+ )
130
+
131
+ try:
132
+ with urllib.request.urlopen(req, timeout=30) as resp:
133
+ data = json.loads(resp.read().decode('utf-8'))
134
+ if not data.get('choices') or not data['choices'][0].get('message'):
135
+ print('ERROR: Unexpected API response structure', file=sys.stderr)
136
+ sys.exit(1)
137
+ content = data['choices'][0]['message'].get('content', '')
138
+ if not content:
139
+ print('ERROR: Empty response from vision model', file=sys.stderr)
140
+ sys.exit(1)
141
+ print(content)
142
+ except Exception as e:
143
+ print(f'ERROR: API call failed: {e}', file=sys.stderr)
144
+ sys.exit(1)
145
+ " "$b64"
146
+ }
147
+
148
+ # --- Main ---
149
+ echo "[clipboard-vision] Reading clipboard..." >&2
150
+ B64="$(get_base64_from_clipboard)"
151
+
152
+ echo "[clipboard-vision] Calling vision model ($MODEL)..." >&2
153
+
154
+ DESCRIPTION="$(call_vision_api "$B64")"
155
+
156
+ echo "$DESCRIPTION" > "$OUTPUT_FILE"
157
+ echo "[clipboard-vision] Description saved to: $OUTPUT_FILE" >&2
158
+
159
+ echo "---"
160
+ echo "$DESCRIPTION"
161
+ echo "---"
@@ -1,37 +1,70 @@
1
1
  {
2
- "$schema": "./.delphi-config.schema.json",
3
- "version": 1,
4
- "description": "Delphi review expert mapping — customize with your own models. Copy to .delphi-config.json and edit.",
5
- "num_experts": 3,
6
- "model_policy": {
7
- "description": "Provider, vendor, gateway, and model nationality are unrestricted. Three distinct trimmed executable model IDs are required."
8
- },
9
- "experts": {
10
- "architecture": {
11
- "agent_name": "delphi-reviewer-architecture",
12
- "perspective": "Architecture and requirements alignment",
13
- "requirements_alignment": true,
14
- "recommended_model": "deepseek-v4-pro",
15
- "alternatives": ["qwen3.6-plus", "glm-5.1"]
16
- },
17
- "technical": {
18
- "agent_name": "delphi-reviewer-technical",
19
- "perspective": "Technical implementation, code correctness, edge cases",
20
- "requirements_alignment": true,
21
- "recommended_model": "kimi-k2.6",
22
- "alternatives": ["deepseek-v4-pro", "minimax-m2.7"]
2
+ "$comment": [
3
+ "Delphi Review Configuration Template",
4
+ "======================================",
5
+ "Copy this file to .delphi-config.json and fill in your API keys.",
6
+ "Place this file alongside SKILL.md in the delphi-review skill directory.",
7
+ "Exactly three roles are required, with distinct trimmed executable model IDs.",
8
+ "",
9
+ "Provider and vendor are unrestricted. provider=local is a fallback and cannot count as a successful expert execution.",
10
+ "cross_provider_required is deprecated and ignored with warning code cross_provider_required_ignored."
11
+ ],
12
+
13
+ "active_profile": "default",
14
+
15
+ "profiles": {
16
+ "default": {
17
+ "providers": {
18
+ "bailian-tp": {
19
+ "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
20
+ "api_key": "YOUR_API_KEY"
21
+ }
22
+ },
23
+ "experts": {
24
+ "architecture": {
25
+ "provider": "bailian-tp",
26
+ "model": "qwen-plus"
27
+ },
28
+ "technical": {
29
+ "provider": "bailian-tp",
30
+ "model": "deepseek-v3"
31
+ },
32
+ "feasibility": {
33
+ "provider": "bailian-tp",
34
+ "model": "glm-4.5"
35
+ }
36
+ }
23
37
  },
24
- "feasibility": {
25
- "agent_name": "delphi-reviewer-feasibility",
26
- "perspective": "Feasibility analysis, risk assessment, execution complexity",
27
- "requirements_alignment": true,
28
- "recommended_model": "qwen3.6-plus",
29
- "alternatives": ["kimi-k2.6", "glm-5.1"]
38
+
39
+ "starter": {
40
+ "$comment": "One provider and token plan serving three distinct models",
41
+ "providers": {
42
+ "bailian-tp": {
43
+ "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
44
+ "api_key": "YOUR_API_KEY"
45
+ }
46
+ },
47
+ "experts": {
48
+ "architecture": {
49
+ "provider": "bailian-tp",
50
+ "model": "qwen-plus"
51
+ },
52
+ "technical": {
53
+ "provider": "bailian-tp",
54
+ "model": "deepseek-v3"
55
+ },
56
+ "feasibility": {
57
+ "provider": "bailian-tp",
58
+ "model": "glm-4.5"
59
+ }
60
+ }
30
61
  }
31
62
  },
63
+
32
64
  "consensus": {
33
65
  "threshold_percent": 90,
34
66
  "max_review_rounds": 5,
35
- "distinct_models_required": true
67
+ "distinct_models_required": true,
68
+ "cross_provider_required": true
36
69
  }
37
70
  }
@@ -1,9 +1,9 @@
1
1
  # SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-08-30
4
- **Commit:** 0848858
3
+ **Generated:** 2026-09-24
4
+ **Commit:** 467174d
5
5
  **Branch:** main
6
- **Version:** 0.19.1.0
6
+ **Version:** 0.19.3.0
7
7
 
8
8
  ## OVERVIEW
9
9
  Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, exactly 3 experts with distinct executable model IDs). Supports design, requirements, and code-walkthrough modes.