@titan-design/brain 0.3.0 → 0.5.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/README.md +96 -40
- package/dist/adapters-ZNJ4FL2E.js +14 -0
- package/dist/brain-service-2QO6JM3Z.js +11 -0
- package/dist/chunk-4SD4JRLS.js +840 -0
- package/dist/chunk-BDNH2E2O.js +112 -0
- package/dist/chunk-PO3GJPIC.js +66 -0
- package/dist/chunk-QL2GPXP6.js +1803 -0
- package/dist/chunk-ZVXSW52A.js +307 -0
- package/dist/cli.js +10942 -3829
- package/dist/command-resolution-FJHE2YBQ.js +134 -0
- package/dist/file-scanner-LBBH5I44.js +12 -0
- package/dist/search-HNUALOXQ.js +14 -0
- package/package.json +4 -1
- package/scripts/diagnostic/assemble.ts +384 -0
- package/scripts/diagnostic/quality-gate.sh +60 -0
- package/scripts/diagnostic/run.sh +352 -0
- package/scripts/diagnostic/schema.json +54 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# PM Diagnostic Automation — Orchestrator
|
|
5
|
+
# Usage: ./scripts/diagnostic/run.sh <version> [options]
|
|
6
|
+
# --skip-setup Skip reset/build/onboarding (re-run tests only)
|
|
7
|
+
# --phase <name> Run only: test-bench, audits, assemble, observations
|
|
8
|
+
# --concurrency <n> Parallel test agents (default: 6)
|
|
9
|
+
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
+
PROJECT_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)"
|
|
12
|
+
cd "$PROJECT_DIR"
|
|
13
|
+
WORKSPACE_DIR="${HOME}/Documents/projects/voltras-workspace"
|
|
14
|
+
|
|
15
|
+
VERSION="${1:?Usage: run.sh <version> [--skip-setup] [--phase <name>] [--concurrency <n>]}"
|
|
16
|
+
shift
|
|
17
|
+
|
|
18
|
+
SKIP_SETUP=false
|
|
19
|
+
SKIP_QUALITY_GATE=false
|
|
20
|
+
PHASE="all"
|
|
21
|
+
CONCURRENCY=6
|
|
22
|
+
|
|
23
|
+
while [[ $# -gt 0 ]]; do
|
|
24
|
+
case "$1" in
|
|
25
|
+
--skip-setup) SKIP_SETUP=true; shift ;;
|
|
26
|
+
--skip-quality-gate) SKIP_QUALITY_GATE=true; shift ;;
|
|
27
|
+
--phase) PHASE="$2"; shift 2 ;;
|
|
28
|
+
--concurrency) CONCURRENCY="$2"; shift 2 ;;
|
|
29
|
+
*) echo "Unknown option: $1"; exit 1 ;;
|
|
30
|
+
esac
|
|
31
|
+
done
|
|
32
|
+
|
|
33
|
+
RESULTS_DIR="docs/pm-module/diagnostic/${VERSION}"
|
|
34
|
+
PROMPTS_DIR="docs/pm-module/diagnostic/prompts"
|
|
35
|
+
SCHEMA_FILE="scripts/diagnostic/schema.json"
|
|
36
|
+
|
|
37
|
+
# Compute previous version for delta comparison
|
|
38
|
+
VERSION_NUM="${VERSION#v}"
|
|
39
|
+
PREV_NUM=$((VERSION_NUM - 1))
|
|
40
|
+
PREVIOUS_VERSION="v${PREV_NUM}"
|
|
41
|
+
|
|
42
|
+
SETUP_SESSION_LOG=""
|
|
43
|
+
|
|
44
|
+
mkdir -p "${RESULTS_DIR}/test-bench"
|
|
45
|
+
|
|
46
|
+
echo "═══════════════════════════════════════════════"
|
|
47
|
+
echo " PM Diagnostic — ${VERSION}"
|
|
48
|
+
echo " Phase: ${PHASE}"
|
|
49
|
+
echo " Skip setup: ${SKIP_SETUP}"
|
|
50
|
+
echo " Concurrency: ${CONCURRENCY}"
|
|
51
|
+
echo " Results: ${RESULTS_DIR}/"
|
|
52
|
+
echo "═══════════════════════════════════════════════"
|
|
53
|
+
|
|
54
|
+
apply_template() {
|
|
55
|
+
local file="$1"
|
|
56
|
+
sed \
|
|
57
|
+
-e "s|{{VERSION}}|${VERSION}|g" \
|
|
58
|
+
-e "s|{{RESULTS_DIR}}|${RESULTS_DIR}|g" \
|
|
59
|
+
-e "s|{{PREVIOUS_VERSION}}|${PREVIOUS_VERSION}|g" \
|
|
60
|
+
"$file"
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
run_agent() {
|
|
64
|
+
local prompt_file="$1"
|
|
65
|
+
local output_file="${2:-}"
|
|
66
|
+
local model="${3:-sonnet}"
|
|
67
|
+
local extra_flags="${4:-}"
|
|
68
|
+
|
|
69
|
+
local prompt
|
|
70
|
+
prompt="$(apply_template "$prompt_file")"
|
|
71
|
+
|
|
72
|
+
local cmd=(
|
|
73
|
+
env -u CLAUDECODE -u CLAUDE_CODE_ENTRYPOINT
|
|
74
|
+
-u CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY
|
|
75
|
+
-u CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC
|
|
76
|
+
-u CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS
|
|
77
|
+
claude -p
|
|
78
|
+
--model "$model"
|
|
79
|
+
--permission-mode bypassPermissions
|
|
80
|
+
--no-session-persistence
|
|
81
|
+
--setting-sources user
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
if [[ -n "$extra_flags" ]]; then
|
|
85
|
+
# shellcheck disable=SC2206
|
|
86
|
+
cmd+=($extra_flags)
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
if [[ -n "$output_file" ]]; then
|
|
90
|
+
"${cmd[@]}" "$prompt" > "$output_file"
|
|
91
|
+
else
|
|
92
|
+
"${cmd[@]}" "$prompt"
|
|
93
|
+
fi
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# ── Phase 0: Reset & Build ──────────────────────────
|
|
97
|
+
|
|
98
|
+
run_setup() {
|
|
99
|
+
echo ""
|
|
100
|
+
echo "── Phase 0: Reset & Build ──────────────────────"
|
|
101
|
+
|
|
102
|
+
echo "Building..."
|
|
103
|
+
npm run build --silent
|
|
104
|
+
|
|
105
|
+
echo "Resetting brain..."
|
|
106
|
+
(cd /tmp && npx tsx "$PROJECT_DIR/src/cli.ts" reset --confirm)
|
|
107
|
+
|
|
108
|
+
echo "Linking..."
|
|
109
|
+
npm link --silent
|
|
110
|
+
|
|
111
|
+
echo "Initializing brain..."
|
|
112
|
+
# Run from /tmp to avoid local .brain/ instance resolution
|
|
113
|
+
(cd /tmp && brain init --notes-dir ~/brain --embedder local)
|
|
114
|
+
|
|
115
|
+
echo "Ingesting command reference docs..."
|
|
116
|
+
for doc in docs/pm-module/commands/*.md; do
|
|
117
|
+
(cd /tmp && brain add "$PROJECT_DIR/$doc" --type guide --tier fast 2>/dev/null) || true
|
|
118
|
+
done
|
|
119
|
+
|
|
120
|
+
echo "Spawning setup agent (with session persistence)..."
|
|
121
|
+
local prompt
|
|
122
|
+
prompt="$(apply_template "${PROMPTS_DIR}/setup.md")"
|
|
123
|
+
|
|
124
|
+
(cd "$WORKSPACE_DIR" && env -u CLAUDECODE -u CLAUDE_CODE_ENTRYPOINT \
|
|
125
|
+
-u CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY \
|
|
126
|
+
-u CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC \
|
|
127
|
+
-u CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS \
|
|
128
|
+
claude -p \
|
|
129
|
+
--model sonnet \
|
|
130
|
+
--permission-mode bypassPermissions \
|
|
131
|
+
--no-session-persistence \
|
|
132
|
+
--setting-sources user \
|
|
133
|
+
"$prompt")
|
|
134
|
+
|
|
135
|
+
# Find the session log written by the setup agent
|
|
136
|
+
local project_hash_dir
|
|
137
|
+
project_hash_dir=$(ls -dt ~/.claude/projects/*/ 2>/dev/null | head -1)
|
|
138
|
+
if [[ -n "$project_hash_dir" ]]; then
|
|
139
|
+
SETUP_SESSION_LOG=$(ls -t "${project_hash_dir}"*.jsonl 2>/dev/null | head -1)
|
|
140
|
+
if [[ -n "$SETUP_SESSION_LOG" ]]; then
|
|
141
|
+
echo " Setup session log: ${SETUP_SESSION_LOG}"
|
|
142
|
+
else
|
|
143
|
+
echo " WARNING: No session log found in ${project_hash_dir}"
|
|
144
|
+
fi
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
echo "Setup complete."
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
# ── Phase 1-3: Audits ───────────────────────────────
|
|
151
|
+
|
|
152
|
+
run_audits() {
|
|
153
|
+
echo ""
|
|
154
|
+
echo "── Phase 1-3: Audits (parallel) ────────────────"
|
|
155
|
+
|
|
156
|
+
local pids=()
|
|
157
|
+
for audit in data-audit gap-analysis; do
|
|
158
|
+
echo " Spawning ${audit} agent..."
|
|
159
|
+
run_agent \
|
|
160
|
+
"${PROMPTS_DIR}/${audit}.md" \
|
|
161
|
+
"${RESULTS_DIR}/${audit}.md" \
|
|
162
|
+
sonnet &
|
|
163
|
+
pids+=($!)
|
|
164
|
+
done
|
|
165
|
+
|
|
166
|
+
# Session audit runs separately — needs setup session log path
|
|
167
|
+
if [[ -n "${SETUP_SESSION_LOG:-}" ]]; then
|
|
168
|
+
echo " Spawning session-audit agent..."
|
|
169
|
+
local prompt
|
|
170
|
+
prompt="$(apply_template "${PROMPTS_DIR}/session-audit.md")"
|
|
171
|
+
prompt="${prompt//\{\{SETUP_SESSION_LOG\}\}/${SETUP_SESSION_LOG}}"
|
|
172
|
+
|
|
173
|
+
local cmd=(
|
|
174
|
+
env -u CLAUDECODE -u CLAUDE_CODE_ENTRYPOINT
|
|
175
|
+
-u CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY
|
|
176
|
+
-u CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC
|
|
177
|
+
-u CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS
|
|
178
|
+
claude -p
|
|
179
|
+
--model sonnet
|
|
180
|
+
--permission-mode bypassPermissions
|
|
181
|
+
--no-session-persistence
|
|
182
|
+
--setting-sources user
|
|
183
|
+
)
|
|
184
|
+
"${cmd[@]}" "$prompt" > "${RESULTS_DIR}/session-audit.md" &
|
|
185
|
+
pids+=($!)
|
|
186
|
+
else
|
|
187
|
+
echo " SKIP: session-audit (no setup session log available)"
|
|
188
|
+
fi
|
|
189
|
+
|
|
190
|
+
echo " Waiting for ${#pids[@]} audit agents..."
|
|
191
|
+
local failed=0
|
|
192
|
+
for pid in "${pids[@]}"; do
|
|
193
|
+
if ! wait "$pid"; then
|
|
194
|
+
((failed++))
|
|
195
|
+
fi
|
|
196
|
+
done
|
|
197
|
+
|
|
198
|
+
if [[ $failed -gt 0 ]]; then
|
|
199
|
+
echo " WARNING: ${failed} audit agent(s) failed"
|
|
200
|
+
else
|
|
201
|
+
echo " All audits complete."
|
|
202
|
+
fi
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
# ── Phase 4: Test Bench ─────────────────────────────
|
|
206
|
+
|
|
207
|
+
run_test_bench() {
|
|
208
|
+
echo ""
|
|
209
|
+
echo "── Phase 4: Test Bench (${CONCURRENCY} concurrent) ──────"
|
|
210
|
+
|
|
211
|
+
local total=0
|
|
212
|
+
local failed=0
|
|
213
|
+
local pids=()
|
|
214
|
+
local next_i=1
|
|
215
|
+
|
|
216
|
+
# Launch agents in waves of $CONCURRENCY
|
|
217
|
+
while [[ $next_i -le 30 ]]; do
|
|
218
|
+
local wave_pids=()
|
|
219
|
+
local wave_count=0
|
|
220
|
+
|
|
221
|
+
while [[ $next_i -le 30 && $wave_count -lt $CONCURRENCY ]]; do
|
|
222
|
+
local num
|
|
223
|
+
num=$(printf "%02d" "$next_i")
|
|
224
|
+
local prompt_file="${PROMPTS_DIR}/test-bench/P-${num}.md"
|
|
225
|
+
local output_file="${RESULTS_DIR}/test-bench/P-${num}.json"
|
|
226
|
+
((next_i++))
|
|
227
|
+
|
|
228
|
+
if [[ ! -f "$prompt_file" ]]; then
|
|
229
|
+
echo " SKIP: ${prompt_file} not found"
|
|
230
|
+
continue
|
|
231
|
+
fi
|
|
232
|
+
|
|
233
|
+
run_agent "$prompt_file" "$output_file" sonnet "--output-format json" &
|
|
234
|
+
local pid=$!
|
|
235
|
+
echo " Started P-${num} (pid ${pid})"
|
|
236
|
+
wave_pids+=("$pid")
|
|
237
|
+
((total++))
|
|
238
|
+
((wave_count++))
|
|
239
|
+
done
|
|
240
|
+
|
|
241
|
+
# Wait for entire wave to finish
|
|
242
|
+
for pid in "${wave_pids[@]}"; do
|
|
243
|
+
if ! wait "$pid"; then
|
|
244
|
+
((failed++))
|
|
245
|
+
fi
|
|
246
|
+
done
|
|
247
|
+
echo " Wave complete (${wave_count} agents)"
|
|
248
|
+
done
|
|
249
|
+
|
|
250
|
+
echo " Test bench complete: ${total} prompts, ${failed} failures"
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
# ── Phase 4b: Assemble ──────────────────────────────
|
|
254
|
+
|
|
255
|
+
run_assemble() {
|
|
256
|
+
echo ""
|
|
257
|
+
echo "── Phase 4b: Assemble Results ──────────────────"
|
|
258
|
+
|
|
259
|
+
npx tsx scripts/diagnostic/assemble.ts \
|
|
260
|
+
--version "$VERSION" \
|
|
261
|
+
--previous "$PREVIOUS_VERSION" \
|
|
262
|
+
--results-dir "$RESULTS_DIR"
|
|
263
|
+
|
|
264
|
+
echo " Wrote ${RESULTS_DIR}/test-bench-results.md"
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
# ── Phase 5a: Observations ──────────────────────────
|
|
268
|
+
|
|
269
|
+
run_observations() {
|
|
270
|
+
echo ""
|
|
271
|
+
echo "── Phase 5a: Extract Observations ──────────────"
|
|
272
|
+
|
|
273
|
+
run_agent \
|
|
274
|
+
"${PROMPTS_DIR}/observations.md" \
|
|
275
|
+
"${RESULTS_DIR}/observations.md" \
|
|
276
|
+
sonnet
|
|
277
|
+
|
|
278
|
+
echo " Wrote ${RESULTS_DIR}/observations.md"
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
# ── Phase 5b: Summary ───────────────────────────────
|
|
282
|
+
|
|
283
|
+
run_summary() {
|
|
284
|
+
echo ""
|
|
285
|
+
echo "── Phase 5b: Generate Summary ──────────────────"
|
|
286
|
+
|
|
287
|
+
run_agent \
|
|
288
|
+
"${PROMPTS_DIR}/summary.md" \
|
|
289
|
+
"${RESULTS_DIR}/summary.md" \
|
|
290
|
+
sonnet
|
|
291
|
+
|
|
292
|
+
echo " Wrote ${RESULTS_DIR}/summary.md"
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
# ── Execute ─────────────────────────────────────────
|
|
296
|
+
|
|
297
|
+
case "$PHASE" in
|
|
298
|
+
all)
|
|
299
|
+
if [[ "$SKIP_SETUP" == false ]]; then
|
|
300
|
+
run_setup
|
|
301
|
+
fi
|
|
302
|
+
echo ""
|
|
303
|
+
echo "── Quality Gate ─────────────────────────────────"
|
|
304
|
+
if [[ "$SKIP_QUALITY_GATE" == true ]]; then
|
|
305
|
+
bash "${SCRIPT_DIR}/quality-gate.sh" --skip
|
|
306
|
+
else
|
|
307
|
+
bash "${SCRIPT_DIR}/quality-gate.sh"
|
|
308
|
+
fi
|
|
309
|
+
run_audits
|
|
310
|
+
run_test_bench
|
|
311
|
+
run_assemble
|
|
312
|
+
echo ""
|
|
313
|
+
echo "── Phase 5: Observations + Summary (parallel) ──"
|
|
314
|
+
run_observations &
|
|
315
|
+
pid_obs=$!
|
|
316
|
+
run_summary &
|
|
317
|
+
pid_sum=$!
|
|
318
|
+
wait "$pid_obs" "$pid_sum"
|
|
319
|
+
|
|
320
|
+
echo ""
|
|
321
|
+
echo "── Ingesting diagnostic outputs ──────────────"
|
|
322
|
+
(cd /tmp && brain add "$PROJECT_DIR/${RESULTS_DIR}/summary.md" --type note --tier fast 2>/dev/null) || echo " SKIP: summary.md ingest failed"
|
|
323
|
+
(cd /tmp && brain add "$PROJECT_DIR/${RESULTS_DIR}/gap-analysis.md" --type note --tier fast 2>/dev/null) || echo " SKIP: gap-analysis.md ingest failed"
|
|
324
|
+
echo " Diagnostic outputs ingested for future reference."
|
|
325
|
+
;;
|
|
326
|
+
test-bench)
|
|
327
|
+
run_test_bench
|
|
328
|
+
run_assemble
|
|
329
|
+
;;
|
|
330
|
+
audits)
|
|
331
|
+
run_audits
|
|
332
|
+
;;
|
|
333
|
+
assemble)
|
|
334
|
+
run_assemble
|
|
335
|
+
;;
|
|
336
|
+
observations)
|
|
337
|
+
run_observations
|
|
338
|
+
run_summary
|
|
339
|
+
;;
|
|
340
|
+
*)
|
|
341
|
+
echo "Unknown phase: ${PHASE}"
|
|
342
|
+
echo "Valid phases: all, test-bench, audits, assemble, observations"
|
|
343
|
+
exit 1
|
|
344
|
+
;;
|
|
345
|
+
esac
|
|
346
|
+
|
|
347
|
+
echo ""
|
|
348
|
+
echo "═══════════════════════════════════════════════"
|
|
349
|
+
echo " Diagnostic ${VERSION} complete"
|
|
350
|
+
echo " Results: ${RESULTS_DIR}/"
|
|
351
|
+
echo " Review: ${RESULTS_DIR}/summary.md"
|
|
352
|
+
echo "═══════════════════════════════════════════════"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"required": ["id", "version", "category", "prompt", "commands", "metrics", "answer", "analysis"],
|
|
5
|
+
"properties": {
|
|
6
|
+
"id": { "type": "string", "pattern": "^P-\\d{2}$" },
|
|
7
|
+
"version": { "type": "string" },
|
|
8
|
+
"category": { "type": "string" },
|
|
9
|
+
"prompt": { "type": "string" },
|
|
10
|
+
"commands": {
|
|
11
|
+
"type": "array",
|
|
12
|
+
"items": { "type": "string" },
|
|
13
|
+
"description": "Every brain CLI command run, in order"
|
|
14
|
+
},
|
|
15
|
+
"metrics": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"required": ["total_calls", "brain_cli_calls", "non_brain_calls", "file_reads", "quality"],
|
|
18
|
+
"properties": {
|
|
19
|
+
"total_calls": { "type": "integer", "minimum": 0 },
|
|
20
|
+
"brain_cli_calls": { "type": "integer", "minimum": 0 },
|
|
21
|
+
"non_brain_calls": { "type": "integer", "minimum": 0 },
|
|
22
|
+
"file_reads": { "type": "integer", "minimum": 0 },
|
|
23
|
+
"quality": { "type": "integer", "minimum": 1, "maximum": 5 }
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"answer": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"description": "The agent's complete answer to the prompt"
|
|
29
|
+
},
|
|
30
|
+
"analysis": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"required": ["what_worked", "friction_points", "known_gaps_hit", "new_issues"],
|
|
33
|
+
"properties": {
|
|
34
|
+
"what_worked": { "type": "string" },
|
|
35
|
+
"friction_points": { "type": "string" },
|
|
36
|
+
"known_gaps_hit": {
|
|
37
|
+
"type": "array",
|
|
38
|
+
"items": { "type": "string" }
|
|
39
|
+
},
|
|
40
|
+
"new_issues": {
|
|
41
|
+
"type": "array",
|
|
42
|
+
"items": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"required": ["description", "severity"],
|
|
45
|
+
"properties": {
|
|
46
|
+
"description": { "type": "string" },
|
|
47
|
+
"severity": { "type": "string", "enum": ["blocker", "friction", "suggestion", "docs", "observation"] }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|