ai-consultants 2.10.1
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/.claude/commands/ai-consultants:consult.md +94 -0
- package/.claude/commands/ai-consultants:debate.md +103 -0
- package/.claude/commands/ai-consultants:help.md +30 -0
- package/CLAUDE.md +839 -0
- package/LICENSE +21 -0
- package/README.md +758 -0
- package/SKILL.md +156 -0
- package/bin/ai-consultants +96 -0
- package/docs/COST_RATES.md +172 -0
- package/docs/JSON_SCHEMA.md +305 -0
- package/docs/SETUP.md +879 -0
- package/docs/SMART_ROUTING.md +219 -0
- package/docs/cost_rates.json +143 -0
- package/package.json +47 -0
- package/references/configuration.md +141 -0
- package/references/details.md +60 -0
- package/scripts/build_context.sh +562 -0
- package/scripts/classify_question.sh +148 -0
- package/scripts/config.sh +753 -0
- package/scripts/configure.sh +1093 -0
- package/scripts/consult_all.sh +934 -0
- package/scripts/debate_round.sh +421 -0
- package/scripts/doctor.sh +642 -0
- package/scripts/followup.sh +197 -0
- package/scripts/install.sh +319 -0
- package/scripts/lib/api.sh +640 -0
- package/scripts/lib/api_query.sh +228 -0
- package/scripts/lib/cache.sh +338 -0
- package/scripts/lib/chunking.sh +880 -0
- package/scripts/lib/code_optimizer.sh +671 -0
- package/scripts/lib/common.sh +1088 -0
- package/scripts/lib/costs.sh +674 -0
- package/scripts/lib/personas.sh +372 -0
- package/scripts/lib/progress.sh +251 -0
- package/scripts/lib/reflection.sh +447 -0
- package/scripts/lib/routing.sh +566 -0
- package/scripts/lib/schema.json +165 -0
- package/scripts/lib/session.sh +327 -0
- package/scripts/lib/symbol_map.sh +445 -0
- package/scripts/lib/voting.sh +495 -0
- package/scripts/peer_review.sh +460 -0
- package/scripts/preflight_check.sh +452 -0
- package/scripts/query_aider.sh +83 -0
- package/scripts/query_amp.sh +67 -0
- package/scripts/query_claude.sh +99 -0
- package/scripts/query_codex.sh +92 -0
- package/scripts/query_cursor.sh +72 -0
- package/scripts/query_deepseek.sh +17 -0
- package/scripts/query_gemini.sh +85 -0
- package/scripts/query_glm.sh +17 -0
- package/scripts/query_grok.sh +17 -0
- package/scripts/query_kilo.sh +140 -0
- package/scripts/query_kimi.sh +67 -0
- package/scripts/query_minimax.sh +17 -0
- package/scripts/query_mistral.sh +97 -0
- package/scripts/query_ollama.sh +328 -0
- package/scripts/query_qwen3.sh +93 -0
- package/scripts/setup_wizard.sh +367 -0
- package/scripts/skillport-install.sh +196 -0
- package/scripts/synthesize.sh +332 -0
- package/templates/consultation_report.md +323 -0
- package/templates/synthesis_prompt.md +120 -0
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# preflight_check.sh - Health check for AI Consultants v2.0
|
|
3
|
+
#
|
|
4
|
+
# Verifies that all consultants are available and functioning
|
|
5
|
+
# before starting a consultation.
|
|
6
|
+
#
|
|
7
|
+
# Usage: ./preflight_check.sh [--quick] [--json] [--suggest-config]
|
|
8
|
+
#
|
|
9
|
+
# Options:
|
|
10
|
+
# --quick Only check commands, no API tests
|
|
11
|
+
# --json Output in JSON format
|
|
12
|
+
# --suggest-config Output recommended ENABLE_* configuration
|
|
13
|
+
|
|
14
|
+
set -euo pipefail
|
|
15
|
+
|
|
16
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
17
|
+
source "$SCRIPT_DIR/lib/common.sh"
|
|
18
|
+
|
|
19
|
+
# --- Parameters ---
|
|
20
|
+
QUICK_MODE=false
|
|
21
|
+
JSON_OUTPUT=false
|
|
22
|
+
SUGGEST_CONFIG=false
|
|
23
|
+
|
|
24
|
+
while [[ $# -gt 0 ]]; do
|
|
25
|
+
case "$1" in
|
|
26
|
+
--quick)
|
|
27
|
+
QUICK_MODE=true
|
|
28
|
+
shift
|
|
29
|
+
;;
|
|
30
|
+
--json)
|
|
31
|
+
JSON_OUTPUT=true
|
|
32
|
+
shift
|
|
33
|
+
;;
|
|
34
|
+
--suggest-config)
|
|
35
|
+
SUGGEST_CONFIG=true
|
|
36
|
+
shift
|
|
37
|
+
;;
|
|
38
|
+
*)
|
|
39
|
+
shift
|
|
40
|
+
;;
|
|
41
|
+
esac
|
|
42
|
+
done
|
|
43
|
+
|
|
44
|
+
# --- State variables ---
|
|
45
|
+
# Using map_* functions from common.sh for bash 3.2 compatibility
|
|
46
|
+
# Maps: CLI_STATUS, API_STATUS, VERSIONS
|
|
47
|
+
ERRORS=0
|
|
48
|
+
WARNINGS=0
|
|
49
|
+
|
|
50
|
+
# =============================================================================
|
|
51
|
+
# CHECK FUNCTIONS
|
|
52
|
+
# =============================================================================
|
|
53
|
+
|
|
54
|
+
check_cli_installed() {
|
|
55
|
+
local name="$1"
|
|
56
|
+
local cmd="$2"
|
|
57
|
+
local install_hint="$3"
|
|
58
|
+
|
|
59
|
+
if command -v "$cmd" &> /dev/null; then
|
|
60
|
+
map_set "CLI_STATUS" "$name" "installed"
|
|
61
|
+
# Try to get version
|
|
62
|
+
local version
|
|
63
|
+
version=$("$cmd" --version 2>/dev/null | head -1 || echo "unknown")
|
|
64
|
+
map_set "VERSIONS" "$name" "$version"
|
|
65
|
+
return 0
|
|
66
|
+
else
|
|
67
|
+
map_set "CLI_STATUS" "$name" "missing"
|
|
68
|
+
map_set "VERSIONS" "$name" "N/A"
|
|
69
|
+
((ERRORS++))
|
|
70
|
+
return 1
|
|
71
|
+
fi
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
check_api_connectivity() {
|
|
75
|
+
local name="$1"
|
|
76
|
+
local cmd="$2"
|
|
77
|
+
shift 2
|
|
78
|
+
local test_args=("$@")
|
|
79
|
+
|
|
80
|
+
if [[ "$(map_get "CLI_STATUS" "$name")" != "installed" ]]; then
|
|
81
|
+
map_set "API_STATUS" "$name" "skipped"
|
|
82
|
+
return 1
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# Quick test with timeout - properly quoted to prevent injection
|
|
86
|
+
if timeout 15 "$cmd" "${test_args[@]}" &>/dev/null; then
|
|
87
|
+
map_set "API_STATUS" "$name" "connected"
|
|
88
|
+
return 0
|
|
89
|
+
else
|
|
90
|
+
map_set "API_STATUS" "$name" "failed"
|
|
91
|
+
((WARNINGS++))
|
|
92
|
+
return 1
|
|
93
|
+
fi
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# =============================================================================
|
|
97
|
+
# SUGGEST CONFIGURATION
|
|
98
|
+
# =============================================================================
|
|
99
|
+
|
|
100
|
+
suggest_configuration() {
|
|
101
|
+
# Run quick checks first
|
|
102
|
+
check_cli_installed "Gemini" "$GEMINI_CMD" "npm install -g @google/gemini-cli" || true
|
|
103
|
+
check_cli_installed "Codex" "$CODEX_CMD" "npm install -g @openai/codex" || true
|
|
104
|
+
check_cli_installed "Mistral" "$MISTRAL_CMD" "pip install mistral-vibe" || true
|
|
105
|
+
check_cli_installed "Kilo" "$KILO_CMD" "npm install -g @kilocode/cli" || true
|
|
106
|
+
check_cli_installed "Cursor" "$CURSOR_CMD" "curl https://cursor.com/install -fsS | bash" || true
|
|
107
|
+
check_cli_installed "Aider" "$AIDER_CMD" "pip install aider-chat" || true
|
|
108
|
+
|
|
109
|
+
local gemini_enabled="false"
|
|
110
|
+
local codex_enabled="false"
|
|
111
|
+
local mistral_enabled="false"
|
|
112
|
+
local kilo_enabled="false"
|
|
113
|
+
local cursor_enabled="false"
|
|
114
|
+
local aider_enabled="false"
|
|
115
|
+
local available_count=0
|
|
116
|
+
|
|
117
|
+
[[ "$(map_get "CLI_STATUS" "Gemini")" == "installed" ]] && { gemini_enabled="true"; ((available_count++)); }
|
|
118
|
+
[[ "$(map_get "CLI_STATUS" "Codex")" == "installed" ]] && { codex_enabled="true"; ((available_count++)); }
|
|
119
|
+
[[ "$(map_get "CLI_STATUS" "Mistral")" == "installed" ]] && { mistral_enabled="true"; ((available_count++)); }
|
|
120
|
+
[[ "$(map_get "CLI_STATUS" "Kilo")" == "installed" ]] && { kilo_enabled="true"; ((available_count++)); }
|
|
121
|
+
[[ "$(map_get "CLI_STATUS" "Cursor")" == "installed" ]] && { cursor_enabled="true"; ((available_count++)); }
|
|
122
|
+
[[ "$(map_get "CLI_STATUS" "Aider")" == "installed" ]] && { aider_enabled="true"; ((available_count++)); }
|
|
123
|
+
|
|
124
|
+
echo "# Recommended configuration based on detected CLIs"
|
|
125
|
+
echo "# Generated by: ./preflight_check.sh --suggest-config"
|
|
126
|
+
echo "# Available consultants: $available_count/6"
|
|
127
|
+
echo ""
|
|
128
|
+
echo "ENABLE_GEMINI=$gemini_enabled"
|
|
129
|
+
echo "ENABLE_CODEX=$codex_enabled"
|
|
130
|
+
echo "ENABLE_MISTRAL=$mistral_enabled"
|
|
131
|
+
echo "ENABLE_KILO=$kilo_enabled"
|
|
132
|
+
echo "ENABLE_CURSOR=$cursor_enabled"
|
|
133
|
+
echo "ENABLE_AIDER=$aider_enabled"
|
|
134
|
+
|
|
135
|
+
if [[ $available_count -lt 2 ]]; then
|
|
136
|
+
echo ""
|
|
137
|
+
echo "# WARNING: Less than 2 consultants available."
|
|
138
|
+
echo "# AI Consultants requires at least 2 consultants."
|
|
139
|
+
echo "# Install more CLIs or run ./scripts/setup_wizard.sh"
|
|
140
|
+
fi
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
# =============================================================================
|
|
144
|
+
# MAIN CHECKS
|
|
145
|
+
# =============================================================================
|
|
146
|
+
|
|
147
|
+
run_preflight() {
|
|
148
|
+
if [[ "$JSON_OUTPUT" != "true" ]]; then
|
|
149
|
+
echo ""
|
|
150
|
+
echo "╔══════════════════════════════════════════════════════════════╗"
|
|
151
|
+
echo "║ AI Consultants v2.0 - Pre-flight Check ║"
|
|
152
|
+
echo "╚══════════════════════════════════════════════════════════════╝"
|
|
153
|
+
echo ""
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
# --- Check CLI Installation ---
|
|
157
|
+
if [[ "$JSON_OUTPUT" != "true" ]]; then
|
|
158
|
+
echo "Checking CLI installations..."
|
|
159
|
+
echo ""
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
check_cli_installed "Gemini" "$GEMINI_CMD" "npm install -g @google/gemini-cli"
|
|
163
|
+
check_cli_installed "Codex" "$CODEX_CMD" "npm install -g @openai/codex"
|
|
164
|
+
check_cli_installed "Mistral" "$MISTRAL_CMD" "pip install mistral-vibe"
|
|
165
|
+
check_cli_installed "Kilo" "$KILO_CMD" "npm install -g @kilocode/cli"
|
|
166
|
+
check_cli_installed "Cursor" "$CURSOR_CMD" "curl https://cursor.com/install -fsS | bash"
|
|
167
|
+
check_cli_installed "Aider" "$AIDER_CMD" "pip install aider-chat"
|
|
168
|
+
|
|
169
|
+
# Check API-based consultants (API key validation)
|
|
170
|
+
if [[ "$ENABLE_QWEN3" == "true" ]]; then
|
|
171
|
+
if [[ -z "${QWEN3_API_KEY:-}" ]]; then
|
|
172
|
+
map_set "CLI_STATUS" "Qwen3" "missing_key"
|
|
173
|
+
((WARNINGS++))
|
|
174
|
+
else
|
|
175
|
+
map_set "CLI_STATUS" "Qwen3" "configured"
|
|
176
|
+
map_set "VERSIONS" "Qwen3" "API"
|
|
177
|
+
fi
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
if [[ "$ENABLE_GLM" == "true" ]]; then
|
|
181
|
+
if [[ -z "${GLM_API_KEY:-}" ]]; then
|
|
182
|
+
map_set "CLI_STATUS" "GLM" "missing_key"
|
|
183
|
+
((WARNINGS++))
|
|
184
|
+
else
|
|
185
|
+
map_set "CLI_STATUS" "GLM" "configured"
|
|
186
|
+
map_set "VERSIONS" "GLM" "API"
|
|
187
|
+
fi
|
|
188
|
+
fi
|
|
189
|
+
|
|
190
|
+
if [[ "$ENABLE_GROK" == "true" ]]; then
|
|
191
|
+
if [[ -z "${GROK_API_KEY:-}" ]]; then
|
|
192
|
+
map_set "CLI_STATUS" "Grok" "missing_key"
|
|
193
|
+
((WARNINGS++))
|
|
194
|
+
else
|
|
195
|
+
map_set "CLI_STATUS" "Grok" "configured"
|
|
196
|
+
map_set "VERSIONS" "Grok" "API"
|
|
197
|
+
fi
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
if [[ "$ENABLE_DEEPSEEK" == "true" ]]; then
|
|
201
|
+
if [[ -z "${DEEPSEEK_API_KEY:-}" ]]; then
|
|
202
|
+
map_set "CLI_STATUS" "DeepSeek" "missing_key"
|
|
203
|
+
((WARNINGS++))
|
|
204
|
+
else
|
|
205
|
+
map_set "CLI_STATUS" "DeepSeek" "configured"
|
|
206
|
+
map_set "VERSIONS" "DeepSeek" "API"
|
|
207
|
+
fi
|
|
208
|
+
fi
|
|
209
|
+
|
|
210
|
+
# Check for jq (required for JSON processing)
|
|
211
|
+
if command -v jq &> /dev/null; then
|
|
212
|
+
map_set "CLI_STATUS" "jq" "installed"
|
|
213
|
+
map_set "VERSIONS" "jq" "$(jq --version 2>/dev/null || echo "unknown")"
|
|
214
|
+
else
|
|
215
|
+
map_set "CLI_STATUS" "jq" "missing"
|
|
216
|
+
map_set "VERSIONS" "jq" "N/A"
|
|
217
|
+
((ERRORS++))
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
# Check for bc (required for floating-point math in cost calculations)
|
|
221
|
+
if command -v bc &> /dev/null; then
|
|
222
|
+
map_set "CLI_STATUS" "bc" "installed"
|
|
223
|
+
map_set "VERSIONS" "bc" "$(bc --version 2>/dev/null | head -1 || echo "unknown")"
|
|
224
|
+
else
|
|
225
|
+
map_set "CLI_STATUS" "bc" "missing"
|
|
226
|
+
map_set "VERSIONS" "bc" "N/A"
|
|
227
|
+
((ERRORS++))
|
|
228
|
+
fi
|
|
229
|
+
|
|
230
|
+
# Check for claude CLI (optional but recommended for synthesis)
|
|
231
|
+
if command -v claude &> /dev/null; then
|
|
232
|
+
map_set "CLI_STATUS" "claude" "installed"
|
|
233
|
+
map_set "VERSIONS" "claude" "$(claude --version 2>/dev/null | head -1 || echo "unknown")"
|
|
234
|
+
else
|
|
235
|
+
map_set "CLI_STATUS" "claude" "missing"
|
|
236
|
+
map_set "VERSIONS" "claude" "N/A"
|
|
237
|
+
((WARNINGS++)) # Warning, not error - fallback available
|
|
238
|
+
fi
|
|
239
|
+
|
|
240
|
+
if [[ "$JSON_OUTPUT" != "true" ]]; then
|
|
241
|
+
# CLI-based consultants
|
|
242
|
+
for name in Gemini Codex Mistral Kilo Cursor jq bc claude; do
|
|
243
|
+
local status version
|
|
244
|
+
status=$(map_get "CLI_STATUS" "$name")
|
|
245
|
+
version=$(map_get "VERSIONS" "$name")
|
|
246
|
+
status="${status:-unknown}"
|
|
247
|
+
version="${version:-N/A}"
|
|
248
|
+
if [[ "$status" == "installed" ]]; then
|
|
249
|
+
echo " [OK] $name: $version"
|
|
250
|
+
elif [[ "$name" == "claude" ]]; then
|
|
251
|
+
echo " [WARN] $name: not installed (optional)"
|
|
252
|
+
else
|
|
253
|
+
echo " [FAIL] $name: NOT FOUND"
|
|
254
|
+
fi
|
|
255
|
+
done
|
|
256
|
+
# API-based consultants
|
|
257
|
+
for name in Qwen3 GLM Grok DeepSeek; do
|
|
258
|
+
local status
|
|
259
|
+
status=$(map_get "CLI_STATUS" "$name")
|
|
260
|
+
status="${status:-unknown}"
|
|
261
|
+
if [[ "$status" == "configured" ]]; then
|
|
262
|
+
echo " [OK] $name: API key configured"
|
|
263
|
+
elif [[ "$status" == "missing_key" ]]; then
|
|
264
|
+
echo " [WARN] $name: API key not set"
|
|
265
|
+
fi
|
|
266
|
+
done
|
|
267
|
+
echo ""
|
|
268
|
+
fi
|
|
269
|
+
|
|
270
|
+
# --- Check API Connectivity (unless quick mode) ---
|
|
271
|
+
if [[ "$QUICK_MODE" != "true" ]]; then
|
|
272
|
+
if [[ "$JSON_OUTPUT" != "true" ]]; then
|
|
273
|
+
echo "Testing API connectivity..."
|
|
274
|
+
echo ""
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
# Gemini - test with version check
|
|
278
|
+
check_api_connectivity "Gemini" "$GEMINI_CMD" "--version" || true
|
|
279
|
+
|
|
280
|
+
# Codex - test with help
|
|
281
|
+
check_api_connectivity "Codex" "$CODEX_CMD" "--help" || true
|
|
282
|
+
|
|
283
|
+
# Mistral - test with help
|
|
284
|
+
check_api_connectivity "Mistral" "$MISTRAL_CMD" "--help" || true
|
|
285
|
+
|
|
286
|
+
# Kilo - test with version
|
|
287
|
+
check_api_connectivity "Kilo" "$KILO_CMD" "--version" || true
|
|
288
|
+
|
|
289
|
+
# Cursor - test with help
|
|
290
|
+
check_api_connectivity "Cursor" "$CURSOR_CMD" "--help" || true
|
|
291
|
+
|
|
292
|
+
# Aider - test with version
|
|
293
|
+
check_api_connectivity "Aider" "$AIDER_CMD" "--version" || true
|
|
294
|
+
|
|
295
|
+
if [[ "$JSON_OUTPUT" != "true" ]]; then
|
|
296
|
+
for name in Gemini Codex Mistral Kilo Cursor Aider; do
|
|
297
|
+
local status
|
|
298
|
+
status=$(map_get "API_STATUS" "$name")
|
|
299
|
+
status="${status:-skipped}"
|
|
300
|
+
case "$status" in
|
|
301
|
+
connected)
|
|
302
|
+
echo " [OK] $name: API reachable"
|
|
303
|
+
;;
|
|
304
|
+
failed)
|
|
305
|
+
echo " [WARN] $name: API connection failed"
|
|
306
|
+
;;
|
|
307
|
+
skipped)
|
|
308
|
+
echo " [SKIP] $name: skipped (CLI not installed)"
|
|
309
|
+
;;
|
|
310
|
+
esac
|
|
311
|
+
done
|
|
312
|
+
echo ""
|
|
313
|
+
fi
|
|
314
|
+
fi
|
|
315
|
+
|
|
316
|
+
# --- Check enabled consultants ---
|
|
317
|
+
local enabled_count=0
|
|
318
|
+
# CLI-based consultants
|
|
319
|
+
[[ "$ENABLE_GEMINI" == "true" && "$(map_get "CLI_STATUS" "Gemini")" == "installed" ]] && ((enabled_count++))
|
|
320
|
+
[[ "$ENABLE_CODEX" == "true" && "$(map_get "CLI_STATUS" "Codex")" == "installed" ]] && ((enabled_count++))
|
|
321
|
+
[[ "$ENABLE_MISTRAL" == "true" && "$(map_get "CLI_STATUS" "Mistral")" == "installed" ]] && ((enabled_count++))
|
|
322
|
+
[[ "$ENABLE_KILO" == "true" && "$(map_get "CLI_STATUS" "Kilo")" == "installed" ]] && ((enabled_count++))
|
|
323
|
+
[[ "$ENABLE_CURSOR" == "true" && "$(map_get "CLI_STATUS" "Cursor")" == "installed" ]] && ((enabled_count++))
|
|
324
|
+
# API-based consultants
|
|
325
|
+
[[ "$ENABLE_QWEN3" == "true" && "$(map_get "CLI_STATUS" "Qwen3")" == "configured" ]] && ((enabled_count++))
|
|
326
|
+
[[ "$ENABLE_GLM" == "true" && "$(map_get "CLI_STATUS" "GLM")" == "configured" ]] && ((enabled_count++))
|
|
327
|
+
[[ "$ENABLE_GROK" == "true" && "$(map_get "CLI_STATUS" "Grok")" == "configured" ]] && ((enabled_count++))
|
|
328
|
+
[[ "$ENABLE_DEEPSEEK" == "true" && "$(map_get "CLI_STATUS" "DeepSeek")" == "configured" ]] && ((enabled_count++))
|
|
329
|
+
|
|
330
|
+
# --- Summary ---
|
|
331
|
+
if [[ "$JSON_OUTPUT" == "true" ]]; then
|
|
332
|
+
# Helper to get map value with default
|
|
333
|
+
get_or_default() {
|
|
334
|
+
local val
|
|
335
|
+
val=$(map_get "$1" "$2")
|
|
336
|
+
echo "${val:-$3}"
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
# JSON output using jq
|
|
340
|
+
jq -n \
|
|
341
|
+
--argjson errors "$ERRORS" \
|
|
342
|
+
--argjson warnings "$WARNINGS" \
|
|
343
|
+
--argjson enabled "$enabled_count" \
|
|
344
|
+
--arg gemini_cli "$(get_or_default CLI_STATUS Gemini unknown)" \
|
|
345
|
+
--arg codex_cli "$(get_or_default CLI_STATUS Codex unknown)" \
|
|
346
|
+
--arg mistral_cli "$(get_or_default CLI_STATUS Mistral unknown)" \
|
|
347
|
+
--arg kilo_cli "$(get_or_default CLI_STATUS Kilo unknown)" \
|
|
348
|
+
--arg cursor_cli "$(get_or_default CLI_STATUS Cursor unknown)" \
|
|
349
|
+
--arg jq_cli "$(get_or_default CLI_STATUS jq unknown)" \
|
|
350
|
+
--arg claude_cli "$(get_or_default CLI_STATUS claude unknown)" \
|
|
351
|
+
--arg gemini_api "$(get_or_default API_STATUS Gemini skipped)" \
|
|
352
|
+
--arg codex_api "$(get_or_default API_STATUS Codex skipped)" \
|
|
353
|
+
--arg mistral_api "$(get_or_default API_STATUS Mistral skipped)" \
|
|
354
|
+
--arg kilo_api "$(get_or_default API_STATUS Kilo skipped)" \
|
|
355
|
+
--arg cursor_api "$(get_or_default API_STATUS Cursor skipped)" \
|
|
356
|
+
--arg gemini_ver "$(get_or_default VERSIONS Gemini N/A)" \
|
|
357
|
+
--arg codex_ver "$(get_or_default VERSIONS Codex N/A)" \
|
|
358
|
+
--arg mistral_ver "$(get_or_default VERSIONS Mistral N/A)" \
|
|
359
|
+
--arg kilo_ver "$(get_or_default VERSIONS Kilo N/A)" \
|
|
360
|
+
--arg cursor_ver "$(get_or_default VERSIONS Cursor N/A)" \
|
|
361
|
+
'{
|
|
362
|
+
preflight: {
|
|
363
|
+
status: (if $errors > 0 then "failed" elif $warnings > 0 then "warning" else "ok" end),
|
|
364
|
+
errors: $errors,
|
|
365
|
+
warnings: $warnings,
|
|
366
|
+
enabled_consultants: $enabled
|
|
367
|
+
},
|
|
368
|
+
cli: {
|
|
369
|
+
Gemini: { status: $gemini_cli, version: $gemini_ver },
|
|
370
|
+
Codex: { status: $codex_cli, version: $codex_ver },
|
|
371
|
+
Mistral: { status: $mistral_cli, version: $mistral_ver },
|
|
372
|
+
Kilo: { status: $kilo_cli, version: $kilo_ver },
|
|
373
|
+
Cursor: { status: $cursor_cli, version: $cursor_ver },
|
|
374
|
+
jq: { status: $jq_cli },
|
|
375
|
+
claude: { status: $claude_cli }
|
|
376
|
+
},
|
|
377
|
+
api: {
|
|
378
|
+
Gemini: $gemini_api,
|
|
379
|
+
Codex: $codex_api,
|
|
380
|
+
Mistral: $mistral_api,
|
|
381
|
+
Kilo: $kilo_api,
|
|
382
|
+
Cursor: $cursor_api
|
|
383
|
+
}
|
|
384
|
+
}'
|
|
385
|
+
else
|
|
386
|
+
echo "╔══════════════════════════════════════════════════════════════╗"
|
|
387
|
+
echo "║ Summary ║"
|
|
388
|
+
echo "╚══════════════════════════════════════════════════════════════╝"
|
|
389
|
+
echo ""
|
|
390
|
+
echo " Enabled consultants: $enabled_count"
|
|
391
|
+
echo " Errors: $ERRORS"
|
|
392
|
+
echo " Warnings: $WARNINGS"
|
|
393
|
+
echo ""
|
|
394
|
+
|
|
395
|
+
if [[ $ERRORS -gt 0 ]]; then
|
|
396
|
+
echo " [FAIL] Pre-flight FAILED - fix errors before proceeding"
|
|
397
|
+
echo ""
|
|
398
|
+
echo " Installation hints:"
|
|
399
|
+
[[ "$(map_get "CLI_STATUS" "Gemini")" == "missing" ]] && echo " npm install -g @google/gemini-cli"
|
|
400
|
+
[[ "$(map_get "CLI_STATUS" "Codex")" == "missing" ]] && echo " npm install -g @openai/codex"
|
|
401
|
+
[[ "$(map_get "CLI_STATUS" "Mistral")" == "missing" ]] && echo " pip install mistral-vibe"
|
|
402
|
+
[[ "$(map_get "CLI_STATUS" "Kilo")" == "missing" ]] && echo " npm install -g @kilocode/cli"
|
|
403
|
+
[[ "$(map_get "CLI_STATUS" "Cursor")" == "missing" ]] && echo " curl https://cursor.com/install -fsS | bash"
|
|
404
|
+
[[ "$(map_get "CLI_STATUS" "jq")" == "missing" ]] && echo " brew install jq # or apt install jq"
|
|
405
|
+
[[ "$(map_get "CLI_STATUS" "bc")" == "missing" ]] && echo " brew install bc # or apt install bc"
|
|
406
|
+
echo ""
|
|
407
|
+
exit 1
|
|
408
|
+
elif [[ $WARNINGS -gt 0 ]]; then
|
|
409
|
+
echo " [WARN] Pre-flight PASSED with warnings"
|
|
410
|
+
echo ""
|
|
411
|
+
exit 0
|
|
412
|
+
else
|
|
413
|
+
echo " [OK] Pre-flight PASSED - all systems go!"
|
|
414
|
+
echo ""
|
|
415
|
+
exit 0
|
|
416
|
+
fi
|
|
417
|
+
fi
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
# =============================================================================
|
|
421
|
+
# RUN
|
|
422
|
+
# =============================================================================
|
|
423
|
+
|
|
424
|
+
# --- Run Unit Tests (optional) ---
|
|
425
|
+
run_unit_tests() {
|
|
426
|
+
if [[ -f "$SCRIPT_DIR/test_functions.sh" ]]; then
|
|
427
|
+
if [[ "$JSON_OUTPUT" != "true" ]]; then
|
|
428
|
+
echo "Running unit tests..."
|
|
429
|
+
echo ""
|
|
430
|
+
fi
|
|
431
|
+
|
|
432
|
+
if "$SCRIPT_DIR/test_functions.sh"; then
|
|
433
|
+
if [[ "$JSON_OUTPUT" != "true" ]]; then
|
|
434
|
+
echo " [OK] Unit tests: PASSED"
|
|
435
|
+
echo ""
|
|
436
|
+
fi
|
|
437
|
+
else
|
|
438
|
+
if [[ "$JSON_OUTPUT" != "true" ]]; then
|
|
439
|
+
echo " [WARN] Unit tests: FAILED"
|
|
440
|
+
echo ""
|
|
441
|
+
fi
|
|
442
|
+
((WARNINGS++))
|
|
443
|
+
fi
|
|
444
|
+
fi
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if [[ "$SUGGEST_CONFIG" == "true" ]]; then
|
|
448
|
+
suggest_configuration
|
|
449
|
+
else
|
|
450
|
+
run_preflight
|
|
451
|
+
run_unit_tests
|
|
452
|
+
fi
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# query_aider.sh - Query Aider CLI
|
|
3
|
+
#
|
|
4
|
+
# Usage: ./query_aider.sh "question" [context_file] [output_file]
|
|
5
|
+
#
|
|
6
|
+
# Environment variables:
|
|
7
|
+
# AIDER_MODEL - Model to use (default: uses aider's default)
|
|
8
|
+
# AIDER_TIMEOUT - Timeout in seconds (default: 180)
|
|
9
|
+
# ENABLE_PERSONA - Enable "The Pair Programmer" persona (default: true)
|
|
10
|
+
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
|
+
source "$SCRIPT_DIR/lib/common.sh"
|
|
15
|
+
source "$SCRIPT_DIR/lib/personas.sh"
|
|
16
|
+
|
|
17
|
+
# --- Parameters ---
|
|
18
|
+
QUERY="${1:-}"
|
|
19
|
+
CONTEXT_FILE="${2:-}"
|
|
20
|
+
OUTPUT_FILE="${3:-/tmp/aider_response.json}"
|
|
21
|
+
|
|
22
|
+
# --- Configuration ---
|
|
23
|
+
ENABLE_PERSONA="${ENABLE_PERSONA:-true}"
|
|
24
|
+
CONSULTANT_NAME="Aider"
|
|
25
|
+
|
|
26
|
+
# --- Check prerequisites ---
|
|
27
|
+
check_command "$AIDER_CMD" "Aider CLI" "pip install aider-chat" || exit 1
|
|
28
|
+
|
|
29
|
+
# --- Build query ---
|
|
30
|
+
FULL_QUERY=$(build_full_query "$QUERY" "$CONTEXT_FILE")
|
|
31
|
+
validate_query "$FULL_QUERY" "Aider" || exit 1
|
|
32
|
+
|
|
33
|
+
# --- Add persona if enabled ---
|
|
34
|
+
if [[ "$ENABLE_PERSONA" == "true" ]]; then
|
|
35
|
+
FULL_QUERY=$(build_query_with_persona "$CONSULTANT_NAME" "$FULL_QUERY")
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# --- Timestamp for metadata ---
|
|
39
|
+
START_TIME=$(get_timestamp_ms)
|
|
40
|
+
|
|
41
|
+
# --- Execution ---
|
|
42
|
+
TEMP_OUTPUT=$(mktemp)
|
|
43
|
+
|
|
44
|
+
# Aider flags:
|
|
45
|
+
# --no-git: Don't use git
|
|
46
|
+
# --message: Send message and exit
|
|
47
|
+
# --yes: Answer yes to all prompts
|
|
48
|
+
# --no-check-update: Don't check for updates
|
|
49
|
+
# --no-suggest-shell-commands: Don't suggest shell commands
|
|
50
|
+
run_query \
|
|
51
|
+
"Aider" \
|
|
52
|
+
"$TEMP_OUTPUT" \
|
|
53
|
+
"$AIDER_TIMEOUT_SECONDS" \
|
|
54
|
+
"$AIDER_CMD" --no-git --no-check-update --no-suggest-shell-commands --yes --message "$FULL_QUERY"
|
|
55
|
+
|
|
56
|
+
exit_code=$?
|
|
57
|
+
|
|
58
|
+
# --- Calculate latency ---
|
|
59
|
+
END_TIME=$(get_timestamp_ms)
|
|
60
|
+
LATENCY_MS=$((END_TIME - START_TIME))
|
|
61
|
+
|
|
62
|
+
# --- Configuration for response building ---
|
|
63
|
+
MODEL_USED="${AIDER_MODEL:-gpt-5.3-codex}"
|
|
64
|
+
PERSONA_NAME=$(get_persona_name "$CONSULTANT_NAME")
|
|
65
|
+
|
|
66
|
+
# --- Post-processing: wrap in full schema using shared helpers ---
|
|
67
|
+
if [[ $exit_code -eq 0 && -f "$TEMP_OUTPUT" && -s "$TEMP_OUTPUT" ]]; then
|
|
68
|
+
RAW_RESPONSE=$(cat "$TEMP_OUTPUT")
|
|
69
|
+
rm -f "$TEMP_OUTPUT"
|
|
70
|
+
|
|
71
|
+
# Try to parse as structured JSON
|
|
72
|
+
if echo "$RAW_RESPONSE" | jq -e '.response.summary' > /dev/null 2>&1; then
|
|
73
|
+
build_structured_response "$CONSULTANT_NAME" "$MODEL_USED" "$PERSONA_NAME" "$RAW_RESPONSE" "$LATENCY_MS" > "$OUTPUT_FILE"
|
|
74
|
+
else
|
|
75
|
+
build_fallback_response "$CONSULTANT_NAME" "$MODEL_USED" "$PERSONA_NAME" "$RAW_RESPONSE" "$LATENCY_MS" > "$OUTPUT_FILE"
|
|
76
|
+
fi
|
|
77
|
+
else
|
|
78
|
+
rm -f "$TEMP_OUTPUT"
|
|
79
|
+
build_error_response "$CONSULTANT_NAME" "$MODEL_USED" "$PERSONA_NAME" "Query failed with exit code $exit_code" "$LATENCY_MS" > "$OUTPUT_FILE"
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
cat "$OUTPUT_FILE"
|
|
83
|
+
exit $exit_code
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# query_amp.sh - Query Amp CLI (v2.8)
|
|
3
|
+
#
|
|
4
|
+
# Usage: ./query_amp.sh "question" [context_file] [output_file]
|
|
5
|
+
#
|
|
6
|
+
# Environment variables:
|
|
7
|
+
# AMP_MODEL - Model identifier (default: amp)
|
|
8
|
+
# AMP_TIMEOUT - Timeout in seconds (default: 180)
|
|
9
|
+
# AMP_API_KEY - API key for authentication (required)
|
|
10
|
+
# ENABLE_PERSONA - Enable "The Systems Thinker" persona (default: true)
|
|
11
|
+
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
15
|
+
source "$SCRIPT_DIR/lib/common.sh"
|
|
16
|
+
source "$SCRIPT_DIR/lib/personas.sh"
|
|
17
|
+
|
|
18
|
+
# --- Parameters ---
|
|
19
|
+
QUERY="${1:-}"
|
|
20
|
+
CONTEXT_FILE="${2:-}"
|
|
21
|
+
OUTPUT_FILE="${3:-/tmp/amp_response.json}"
|
|
22
|
+
|
|
23
|
+
# --- Configuration ---
|
|
24
|
+
ENABLE_PERSONA="${ENABLE_PERSONA:-true}"
|
|
25
|
+
CONSULTANT_NAME="Amp"
|
|
26
|
+
|
|
27
|
+
# --- Build query ---
|
|
28
|
+
FULL_QUERY=$(build_full_query "$QUERY" "$CONTEXT_FILE")
|
|
29
|
+
validate_query "$FULL_QUERY" "Amp" || exit 1
|
|
30
|
+
|
|
31
|
+
# --- Add persona if enabled ---
|
|
32
|
+
if [[ "$ENABLE_PERSONA" == "true" ]]; then
|
|
33
|
+
FULL_QUERY=$(build_query_with_persona "$CONSULTANT_NAME" "$FULL_QUERY")
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# --- Timestamp for metadata ---
|
|
37
|
+
START_TIME=$(get_timestamp_ms)
|
|
38
|
+
|
|
39
|
+
# --- Execution ---
|
|
40
|
+
TEMP_OUTPUT=$(mktemp)
|
|
41
|
+
|
|
42
|
+
# Check CLI prerequisite
|
|
43
|
+
check_command "$AMP_CMD" "Amp CLI" "curl -fsSL https://ampcode.com/install.sh | bash" || exit 1
|
|
44
|
+
|
|
45
|
+
# Amp CLI uses -x (execute mode) for non-interactive usage
|
|
46
|
+
echo "$FULL_QUERY" | run_query \
|
|
47
|
+
"Amp" \
|
|
48
|
+
"$TEMP_OUTPUT" \
|
|
49
|
+
"$AMP_TIMEOUT_SECONDS" \
|
|
50
|
+
"$AMP_CMD" -x
|
|
51
|
+
|
|
52
|
+
exit_code=$?
|
|
53
|
+
|
|
54
|
+
# --- Calculate latency ---
|
|
55
|
+
END_TIME=$(get_timestamp_ms)
|
|
56
|
+
LATENCY_MS=$((END_TIME - START_TIME))
|
|
57
|
+
|
|
58
|
+
# --- Configuration for response building ---
|
|
59
|
+
MODEL_USED="${AMP_MODEL:-amp}"
|
|
60
|
+
PERSONA_NAME=$(get_persona_name "$CONSULTANT_NAME")
|
|
61
|
+
|
|
62
|
+
# --- Post-processing: use shared helper ---
|
|
63
|
+
process_consultant_response "$CONSULTANT_NAME" "$MODEL_USED" "$PERSONA_NAME" \
|
|
64
|
+
"$TEMP_OUTPUT" "$OUTPUT_FILE" "$exit_code" "$LATENCY_MS"
|
|
65
|
+
|
|
66
|
+
cat "$OUTPUT_FILE"
|
|
67
|
+
exit $exit_code
|