agent-bober 0.1.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/.claude-plugin/plugin.json +9 -0
- package/LICENSE +21 -0
- package/README.md +495 -0
- package/agents/bober-evaluator.md +323 -0
- package/agents/bober-generator.md +245 -0
- package/agents/bober-planner.md +248 -0
- package/dist/cli/commands/eval.d.ts +6 -0
- package/dist/cli/commands/eval.d.ts.map +1 -0
- package/dist/cli/commands/eval.js +129 -0
- package/dist/cli/commands/eval.js.map +1 -0
- package/dist/cli/commands/init.d.ts +5 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +547 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +5 -0
- package/dist/cli/commands/plan.d.ts.map +1 -0
- package/dist/cli/commands/plan.js +87 -0
- package/dist/cli/commands/plan.js.map +1 -0
- package/dist/cli/commands/run.d.ts +5 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +120 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/sprint.d.ts +6 -0
- package/dist/cli/commands/sprint.d.ts.map +1 -0
- package/dist/cli/commands/sprint.js +206 -0
- package/dist/cli/commands/sprint.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +124 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/defaults.d.ts +15 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +226 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +8 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +18 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +189 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +904 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +181 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/contracts/eval-result.d.ts +205 -0
- package/dist/contracts/eval-result.d.ts.map +1 -0
- package/dist/contracts/eval-result.js +87 -0
- package/dist/contracts/eval-result.js.map +1 -0
- package/dist/contracts/index.d.ts +4 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +16 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/spec.d.ts +101 -0
- package/dist/contracts/spec.d.ts.map +1 -0
- package/dist/contracts/spec.js +51 -0
- package/dist/contracts/spec.js.map +1 -0
- package/dist/contracts/sprint-contract.d.ts +141 -0
- package/dist/contracts/sprint-contract.d.ts.map +1 -0
- package/dist/contracts/sprint-contract.js +80 -0
- package/dist/contracts/sprint-contract.js.map +1 -0
- package/dist/evaluators/builtin/api-check.d.ts +13 -0
- package/dist/evaluators/builtin/api-check.d.ts.map +1 -0
- package/dist/evaluators/builtin/api-check.js +152 -0
- package/dist/evaluators/builtin/api-check.js.map +1 -0
- package/dist/evaluators/builtin/build-check.d.ts +17 -0
- package/dist/evaluators/builtin/build-check.d.ts.map +1 -0
- package/dist/evaluators/builtin/build-check.js +155 -0
- package/dist/evaluators/builtin/build-check.js.map +1 -0
- package/dist/evaluators/builtin/command-runner.d.ts +26 -0
- package/dist/evaluators/builtin/command-runner.d.ts.map +1 -0
- package/dist/evaluators/builtin/command-runner.js +114 -0
- package/dist/evaluators/builtin/command-runner.js.map +1 -0
- package/dist/evaluators/builtin/lint.d.ts +17 -0
- package/dist/evaluators/builtin/lint.d.ts.map +1 -0
- package/dist/evaluators/builtin/lint.js +264 -0
- package/dist/evaluators/builtin/lint.js.map +1 -0
- package/dist/evaluators/builtin/playwright.d.ts +16 -0
- package/dist/evaluators/builtin/playwright.d.ts.map +1 -0
- package/dist/evaluators/builtin/playwright.js +238 -0
- package/dist/evaluators/builtin/playwright.js.map +1 -0
- package/dist/evaluators/builtin/typescript-check.d.ts +12 -0
- package/dist/evaluators/builtin/typescript-check.d.ts.map +1 -0
- package/dist/evaluators/builtin/typescript-check.js +155 -0
- package/dist/evaluators/builtin/typescript-check.js.map +1 -0
- package/dist/evaluators/builtin/unit-test.d.ts +18 -0
- package/dist/evaluators/builtin/unit-test.d.ts.map +1 -0
- package/dist/evaluators/builtin/unit-test.js +279 -0
- package/dist/evaluators/builtin/unit-test.js.map +1 -0
- package/dist/evaluators/index.d.ts +11 -0
- package/dist/evaluators/index.d.ts.map +1 -0
- package/dist/evaluators/index.js +13 -0
- package/dist/evaluators/index.js.map +1 -0
- package/dist/evaluators/plugin-interface.d.ts +50 -0
- package/dist/evaluators/plugin-interface.d.ts.map +1 -0
- package/dist/evaluators/plugin-interface.js +2 -0
- package/dist/evaluators/plugin-interface.js.map +1 -0
- package/dist/evaluators/plugin-loader.d.ts +18 -0
- package/dist/evaluators/plugin-loader.d.ts.map +1 -0
- package/dist/evaluators/plugin-loader.js +107 -0
- package/dist/evaluators/plugin-loader.js.map +1 -0
- package/dist/evaluators/registry.d.ts +78 -0
- package/dist/evaluators/registry.d.ts.map +1 -0
- package/dist/evaluators/registry.js +238 -0
- package/dist/evaluators/registry.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator/context-handoff.d.ts +543 -0
- package/dist/orchestrator/context-handoff.d.ts.map +1 -0
- package/dist/orchestrator/context-handoff.js +133 -0
- package/dist/orchestrator/context-handoff.js.map +1 -0
- package/dist/orchestrator/evaluator-agent.d.ts +15 -0
- package/dist/orchestrator/evaluator-agent.d.ts.map +1 -0
- package/dist/orchestrator/evaluator-agent.js +233 -0
- package/dist/orchestrator/evaluator-agent.js.map +1 -0
- package/dist/orchestrator/generator-agent.d.ts +16 -0
- package/dist/orchestrator/generator-agent.d.ts.map +1 -0
- package/dist/orchestrator/generator-agent.js +147 -0
- package/dist/orchestrator/generator-agent.js.map +1 -0
- package/dist/orchestrator/pipeline.d.ts +24 -0
- package/dist/orchestrator/pipeline.d.ts.map +1 -0
- package/dist/orchestrator/pipeline.js +290 -0
- package/dist/orchestrator/pipeline.js.map +1 -0
- package/dist/orchestrator/planner-agent.d.ts +10 -0
- package/dist/orchestrator/planner-agent.d.ts.map +1 -0
- package/dist/orchestrator/planner-agent.js +187 -0
- package/dist/orchestrator/planner-agent.js.map +1 -0
- package/dist/state/helpers.d.ts +5 -0
- package/dist/state/helpers.d.ts.map +1 -0
- package/dist/state/helpers.js +8 -0
- package/dist/state/helpers.js.map +1 -0
- package/dist/state/history.d.ts +39 -0
- package/dist/state/history.d.ts.map +1 -0
- package/dist/state/history.js +162 -0
- package/dist/state/history.js.map +1 -0
- package/dist/state/index.d.ts +8 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +22 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/plan-state.d.ts +21 -0
- package/dist/state/plan-state.d.ts.map +1 -0
- package/dist/state/plan-state.js +108 -0
- package/dist/state/plan-state.js.map +1 -0
- package/dist/state/sprint-state.d.ts +20 -0
- package/dist/state/sprint-state.d.ts.map +1 -0
- package/dist/state/sprint-state.js +98 -0
- package/dist/state/sprint-state.js.map +1 -0
- package/dist/utils/fs.d.ts +31 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +67 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/git.d.ts +35 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +84 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +45 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +73 -0
- package/dist/utils/logger.js.map +1 -0
- package/hooks/hooks.json +10 -0
- package/package.json +67 -0
- package/scripts/detect-stack.sh +287 -0
- package/scripts/init-project.sh +206 -0
- package/scripts/run-eval.sh +175 -0
- package/skills/bober.anchor/SKILL.md +365 -0
- package/skills/bober.anchor/references/anchor-guide.md +567 -0
- package/skills/bober.brownfield/SKILL.md +422 -0
- package/skills/bober.brownfield/references/codebase-analysis.md +304 -0
- package/skills/bober.eval/SKILL.md +235 -0
- package/skills/bober.eval/references/eval-strategies.md +407 -0
- package/skills/bober.eval/references/feedback-format.md +182 -0
- package/skills/bober.plan/SKILL.md +244 -0
- package/skills/bober.plan/references/clarification-guide.md +124 -0
- package/skills/bober.plan/references/spec-schema.md +253 -0
- package/skills/bober.react/SKILL.md +330 -0
- package/skills/bober.react/references/react-scaffold.md +344 -0
- package/skills/bober.run/SKILL.md +303 -0
- package/skills/bober.solidity/SKILL.md +416 -0
- package/skills/bober.solidity/references/solidity-guide.md +487 -0
- package/skills/bober.sprint/SKILL.md +280 -0
- package/skills/bober.sprint/references/contract-schema.md +251 -0
- package/templates/base/CLAUDE.md +20 -0
- package/templates/base/bober.config.json +35 -0
- package/templates/brownfield/CLAUDE.md +34 -0
- package/templates/brownfield/bober.config.json +37 -0
- package/templates/presets/anchor/CLAUDE.md +163 -0
- package/templates/presets/anchor/bober.config.json +9 -0
- package/templates/presets/api-node/CLAUDE.md +153 -0
- package/templates/presets/api-node/bober.config.json +10 -0
- package/templates/presets/nextjs/CLAUDE.md +82 -0
- package/templates/presets/nextjs/bober.config.json +14 -0
- package/templates/presets/python-api/CLAUDE.md +202 -0
- package/templates/presets/python-api/bober.config.json +9 -0
- package/templates/presets/react-vite/CLAUDE.md +71 -0
- package/templates/presets/react-vite/bober.config.json +53 -0
- package/templates/presets/react-vite/scaffold/package.json +45 -0
- package/templates/presets/react-vite/scaffold/server/index.ts +38 -0
- package/templates/presets/react-vite/scaffold/server/tsconfig.json +24 -0
- package/templates/presets/react-vite/scaffold/src/App.tsx +37 -0
- package/templates/presets/react-vite/scaffold/src/index.html +12 -0
- package/templates/presets/react-vite/scaffold/src/main.tsx +12 -0
- package/templates/presets/react-vite/scaffold/tsconfig.json +27 -0
- package/templates/presets/react-vite/scaffold/vite.config.ts +34 -0
- package/templates/presets/solidity/CLAUDE.md +106 -0
- package/templates/presets/solidity/bober.config.json +9 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ──────────────────────────────────────────────────────────────────────
|
|
3
|
+
# init-project.sh — Initialize a new bober-managed project.
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# bash scripts/init-project.sh <template>
|
|
7
|
+
#
|
|
8
|
+
# Templates: base, brownfield
|
|
9
|
+
# Presets: nextjs, react-vite, solidity, anchor, api-node, python-api
|
|
10
|
+
# ──────────────────────────────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
15
|
+
PACKAGE_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
16
|
+
TEMPLATES_DIR="$PACKAGE_ROOT/templates"
|
|
17
|
+
PROJECT_DIR="$(pwd)"
|
|
18
|
+
|
|
19
|
+
# ── Argument validation ─────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
TEMPLATE="${1:-}"
|
|
22
|
+
|
|
23
|
+
if [[ -z "$TEMPLATE" ]]; then
|
|
24
|
+
echo "Usage: bash scripts/init-project.sh <template>"
|
|
25
|
+
echo ""
|
|
26
|
+
echo "Available templates:"
|
|
27
|
+
echo " base Minimal greenfield configuration (customize yourself)"
|
|
28
|
+
echo " brownfield Existing codebase (conservative settings)"
|
|
29
|
+
echo ""
|
|
30
|
+
echo "Available presets:"
|
|
31
|
+
echo " nextjs Next.js full-stack app"
|
|
32
|
+
echo " react-vite React + Vite + any backend"
|
|
33
|
+
echo " solidity EVM smart contracts (Hardhat/Foundry)"
|
|
34
|
+
echo " anchor Solana programs (Anchor/Rust)"
|
|
35
|
+
echo " api-node Node.js API (Express/NestJS/Fastify)"
|
|
36
|
+
echo " python-api Python API (FastAPI/Django)"
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# Resolve template directory — presets live under templates/presets/
|
|
41
|
+
if [[ "$TEMPLATE" == "base" || "$TEMPLATE" == "brownfield" ]]; then
|
|
42
|
+
TEMPLATE_DIR="$TEMPLATES_DIR/$TEMPLATE"
|
|
43
|
+
else
|
|
44
|
+
TEMPLATE_DIR="$TEMPLATES_DIR/presets/$TEMPLATE"
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
if [[ ! -d "$TEMPLATE_DIR" ]]; then
|
|
48
|
+
echo "Error: Unknown template '$TEMPLATE'."
|
|
49
|
+
echo "Available templates: base, brownfield"
|
|
50
|
+
echo "Available presets: nextjs, react-vite, solidity, anchor, api-node, python-api"
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
echo "Initializing bober project with template: $TEMPLATE"
|
|
55
|
+
echo "Project directory: $PROJECT_DIR"
|
|
56
|
+
echo ""
|
|
57
|
+
|
|
58
|
+
# ── Create .bober directory structure ───────────────────────────────
|
|
59
|
+
|
|
60
|
+
echo "Creating .bober/ directory structure..."
|
|
61
|
+
|
|
62
|
+
mkdir -p "$PROJECT_DIR/.bober/specs"
|
|
63
|
+
mkdir -p "$PROJECT_DIR/.bober/contracts"
|
|
64
|
+
mkdir -p "$PROJECT_DIR/.bober/evaluations"
|
|
65
|
+
mkdir -p "$PROJECT_DIR/.bober/snapshots"
|
|
66
|
+
|
|
67
|
+
# Initialize progress tracker
|
|
68
|
+
if [[ ! -f "$PROJECT_DIR/.bober/progress.md" ]]; then
|
|
69
|
+
cat > "$PROJECT_DIR/.bober/progress.md" << 'PROGRESS'
|
|
70
|
+
# Bober Progress
|
|
71
|
+
|
|
72
|
+
Tracking all plans, sprints, and evaluations.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
PROGRESS
|
|
77
|
+
echo " Created .bober/progress.md"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# Initialize history log
|
|
81
|
+
if [[ ! -f "$PROJECT_DIR/.bober/history.jsonl" ]]; then
|
|
82
|
+
echo "{\"event\":\"project-initialized\",\"template\":\"$TEMPLATE\",\"timestamp\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}" \
|
|
83
|
+
> "$PROJECT_DIR/.bober/history.jsonl"
|
|
84
|
+
echo " Created .bober/history.jsonl"
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# ── Copy bober.config.json ──────────────────────────────────────────
|
|
88
|
+
|
|
89
|
+
if [[ -f "$PROJECT_DIR/bober.config.json" ]]; then
|
|
90
|
+
echo " bober.config.json already exists — skipping (will not overwrite)"
|
|
91
|
+
else
|
|
92
|
+
# Determine the project name from the directory name
|
|
93
|
+
PROJECT_NAME="$(basename "$PROJECT_DIR")"
|
|
94
|
+
# Copy and substitute the project name
|
|
95
|
+
sed "s/\"name\": \"\"/\"name\": \"$PROJECT_NAME\"/" \
|
|
96
|
+
"$TEMPLATE_DIR/bober.config.json" > "$PROJECT_DIR/bober.config.json"
|
|
97
|
+
echo " Created bober.config.json"
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# ── Copy CLAUDE.md ──────────────────────────────────────────────────
|
|
101
|
+
|
|
102
|
+
if [[ -f "$PROJECT_DIR/CLAUDE.md" ]]; then
|
|
103
|
+
echo " CLAUDE.md already exists — skipping (will not overwrite)"
|
|
104
|
+
else
|
|
105
|
+
cp "$TEMPLATE_DIR/CLAUDE.md" "$PROJECT_DIR/CLAUDE.md"
|
|
106
|
+
echo " Created CLAUDE.md"
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
# ── Copy scaffold files (preset templates with scaffold dirs) ───────
|
|
110
|
+
|
|
111
|
+
if [[ -d "$TEMPLATE_DIR/scaffold" ]]; then
|
|
112
|
+
echo ""
|
|
113
|
+
echo "Copying scaffold files..."
|
|
114
|
+
|
|
115
|
+
# Only copy scaffold files that do not already exist
|
|
116
|
+
while IFS= read -r -d '' file; do
|
|
117
|
+
relative="${file#$TEMPLATE_DIR/scaffold/}"
|
|
118
|
+
target="$PROJECT_DIR/$relative"
|
|
119
|
+
target_dir="$(dirname "$target")"
|
|
120
|
+
|
|
121
|
+
if [[ -f "$target" ]]; then
|
|
122
|
+
echo " Skipping $relative (already exists)"
|
|
123
|
+
else
|
|
124
|
+
mkdir -p "$target_dir"
|
|
125
|
+
cp "$file" "$target"
|
|
126
|
+
echo " Created $relative"
|
|
127
|
+
fi
|
|
128
|
+
done < <(find "$TEMPLATE_DIR/scaffold" -type f -print0)
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
# ── Update .gitignore ───────────────────────────────────────────────
|
|
132
|
+
|
|
133
|
+
echo ""
|
|
134
|
+
echo "Updating .gitignore..."
|
|
135
|
+
|
|
136
|
+
GITIGNORE="$PROJECT_DIR/.gitignore"
|
|
137
|
+
|
|
138
|
+
# Entries to ensure are present
|
|
139
|
+
ENTRIES=(
|
|
140
|
+
".bober/"
|
|
141
|
+
".bober/snapshots/"
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
touch "$GITIGNORE"
|
|
145
|
+
|
|
146
|
+
for entry in "${ENTRIES[@]}"; do
|
|
147
|
+
if ! grep -qxF "$entry" "$GITIGNORE" 2>/dev/null; then
|
|
148
|
+
echo "$entry" >> "$GITIGNORE"
|
|
149
|
+
echo " Added '$entry' to .gitignore"
|
|
150
|
+
fi
|
|
151
|
+
done
|
|
152
|
+
|
|
153
|
+
# ── Summary ─────────────────────────────────────────────────────────
|
|
154
|
+
|
|
155
|
+
echo ""
|
|
156
|
+
echo "──────────────────────────────────────────────────────"
|
|
157
|
+
echo " bober project initialized successfully!"
|
|
158
|
+
echo "──────────────────────────────────────────────────────"
|
|
159
|
+
echo ""
|
|
160
|
+
echo "Next steps:"
|
|
161
|
+
echo ""
|
|
162
|
+
|
|
163
|
+
if [[ "$TEMPLATE" == "react-vite" ]]; then
|
|
164
|
+
echo " 1. npm install"
|
|
165
|
+
echo " 2. npm run dev # start frontend + backend"
|
|
166
|
+
echo " 3. /bober:plan # create your first plan"
|
|
167
|
+
echo " 4. /bober:sprint # run the first sprint"
|
|
168
|
+
elif [[ "$TEMPLATE" == "nextjs" ]]; then
|
|
169
|
+
echo " 1. npm install"
|
|
170
|
+
echo " 2. npm run dev # start Next.js dev server"
|
|
171
|
+
echo " 3. /bober:plan # create your first plan"
|
|
172
|
+
echo " 4. /bober:sprint # run the first sprint"
|
|
173
|
+
elif [[ "$TEMPLATE" == "solidity" ]]; then
|
|
174
|
+
echo " 1. npm install"
|
|
175
|
+
echo " 2. npx hardhat compile # compile contracts"
|
|
176
|
+
echo " 3. /bober:plan # create your first plan"
|
|
177
|
+
echo " 4. /bober:sprint # run the first sprint"
|
|
178
|
+
elif [[ "$TEMPLATE" == "anchor" ]]; then
|
|
179
|
+
echo " 1. anchor build # build the program"
|
|
180
|
+
echo " 2. anchor test # run tests"
|
|
181
|
+
echo " 3. /bober:plan # create your first plan"
|
|
182
|
+
echo " 4. /bober:sprint # run the first sprint"
|
|
183
|
+
elif [[ "$TEMPLATE" == "api-node" ]]; then
|
|
184
|
+
echo " 1. npm install"
|
|
185
|
+
echo " 2. npm run dev # start the API server"
|
|
186
|
+
echo " 3. /bober:plan # create your first plan"
|
|
187
|
+
echo " 4. /bober:sprint # run the first sprint"
|
|
188
|
+
elif [[ "$TEMPLATE" == "python-api" ]]; then
|
|
189
|
+
echo " 1. pip install -r requirements.txt # or: poetry install"
|
|
190
|
+
echo " 2. uvicorn app.main:app --reload # start the API server"
|
|
191
|
+
echo " 3. /bober:plan # create your first plan"
|
|
192
|
+
echo " 4. /bober:sprint # run the first sprint"
|
|
193
|
+
elif [[ "$TEMPLATE" == "brownfield" ]]; then
|
|
194
|
+
echo " 1. Review bober.config.json and update the 'commands' section"
|
|
195
|
+
echo " with your project's build, test, lint, and dev commands."
|
|
196
|
+
echo " 2. /bober:plan # create your first plan"
|
|
197
|
+
echo " 3. /bober:sprint # run the first sprint"
|
|
198
|
+
elif [[ "$TEMPLATE" == "base" ]]; then
|
|
199
|
+
echo " 1. Edit bober.config.json to match your project setup."
|
|
200
|
+
echo " 2. Edit CLAUDE.md with your project's conventions."
|
|
201
|
+
echo " 3. /bober:plan # create your first plan"
|
|
202
|
+
echo " 4. /bober:sprint # run the first sprint"
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
echo ""
|
|
206
|
+
echo "Run /bober:plan to start planning your first feature."
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ──────────────────────────────────────────────────────────────────────
|
|
3
|
+
# run-eval.sh — Run evaluation strategies from bober.config.json.
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# bash scripts/run-eval.sh [project-dir]
|
|
7
|
+
#
|
|
8
|
+
# Reads bober.config.json to determine which strategies to run,
|
|
9
|
+
# executes each in order, and outputs a combined JSON result.
|
|
10
|
+
# ──────────────────────────────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
PROJECT_DIR="${1:-.}"
|
|
15
|
+
PROJECT_DIR="$(cd "$PROJECT_DIR" && pwd)"
|
|
16
|
+
CONFIG_FILE="$PROJECT_DIR/bober.config.json"
|
|
17
|
+
|
|
18
|
+
# ── Validate config ─────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
if [[ ! -f "$CONFIG_FILE" ]]; then
|
|
21
|
+
echo "Error: bober.config.json not found in $PROJECT_DIR" >&2
|
|
22
|
+
echo "Run 'bober init' or 'bash scripts/init-project.sh <template>' first." >&2
|
|
23
|
+
exit 1
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# ── Parse config ────────────────────────────────────────────────────
|
|
27
|
+
# We use lightweight parsing to avoid requiring jq as a dependency.
|
|
28
|
+
# For production use, the TypeScript evaluator handles full parsing.
|
|
29
|
+
|
|
30
|
+
# Extract commands from config
|
|
31
|
+
get_command() {
|
|
32
|
+
local key="$1"
|
|
33
|
+
local cmd
|
|
34
|
+
cmd=$(grep -o "\"$key\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" "$CONFIG_FILE" 2>/dev/null | head -1 | sed 's/.*:[[:space:]]*"\(.*\)"/\1/')
|
|
35
|
+
echo "$cmd"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
CMD_BUILD="$(get_command "build")"
|
|
39
|
+
CMD_TEST="$(get_command "test")"
|
|
40
|
+
CMD_LINT="$(get_command "lint")"
|
|
41
|
+
CMD_TYPECHECK="$(get_command "typecheck")"
|
|
42
|
+
|
|
43
|
+
# ── Strategy Execution ──────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
RESULTS=()
|
|
46
|
+
OVERALL_PASS=true
|
|
47
|
+
STRATEGY_COUNT=0
|
|
48
|
+
PASS_COUNT=0
|
|
49
|
+
FAIL_COUNT=0
|
|
50
|
+
SKIP_COUNT=0
|
|
51
|
+
|
|
52
|
+
run_strategy() {
|
|
53
|
+
local strategy_type="$1"
|
|
54
|
+
local required="$2"
|
|
55
|
+
local command="$3"
|
|
56
|
+
local status="skip"
|
|
57
|
+
local output=""
|
|
58
|
+
local exit_code=0
|
|
59
|
+
|
|
60
|
+
STRATEGY_COUNT=$((STRATEGY_COUNT + 1))
|
|
61
|
+
|
|
62
|
+
if [[ -z "$command" ]]; then
|
|
63
|
+
echo " [$strategy_type] SKIP — no command configured"
|
|
64
|
+
SKIP_COUNT=$((SKIP_COUNT + 1))
|
|
65
|
+
status="skip"
|
|
66
|
+
output="No command configured for $strategy_type"
|
|
67
|
+
else
|
|
68
|
+
echo " [$strategy_type] Running: $command"
|
|
69
|
+
|
|
70
|
+
set +e
|
|
71
|
+
output=$(cd "$PROJECT_DIR" && eval "$command" 2>&1)
|
|
72
|
+
exit_code=$?
|
|
73
|
+
set -e
|
|
74
|
+
|
|
75
|
+
if [[ $exit_code -eq 0 ]]; then
|
|
76
|
+
echo " [$strategy_type] PASS"
|
|
77
|
+
status="pass"
|
|
78
|
+
PASS_COUNT=$((PASS_COUNT + 1))
|
|
79
|
+
else
|
|
80
|
+
echo " [$strategy_type] FAIL (exit code $exit_code)"
|
|
81
|
+
status="fail"
|
|
82
|
+
FAIL_COUNT=$((FAIL_COUNT + 1))
|
|
83
|
+
|
|
84
|
+
if [[ "$required" == "true" ]]; then
|
|
85
|
+
OVERALL_PASS=false
|
|
86
|
+
fi
|
|
87
|
+
fi
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# Escape output for JSON (basic escaping)
|
|
91
|
+
output=$(echo "$output" | head -50 | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/\\t/g' | tr '\n' ' ' | head -c 2000)
|
|
92
|
+
|
|
93
|
+
RESULTS+=("{\"strategy\":\"$strategy_type\",\"status\":\"$status\",\"required\":$required,\"exitCode\":$exit_code,\"output\":\"$output\"}")
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
echo ""
|
|
97
|
+
echo "Running evaluations in $PROJECT_DIR"
|
|
98
|
+
echo "──────────────────────────────────────────────────────"
|
|
99
|
+
echo ""
|
|
100
|
+
|
|
101
|
+
# ── Extract and run strategies ──────────────────────────────────────
|
|
102
|
+
# Parse the strategies array from config. We look for type/required pairs.
|
|
103
|
+
|
|
104
|
+
# Run strategies in canonical order: typecheck -> lint -> build -> unit-test -> playwright
|
|
105
|
+
|
|
106
|
+
if grep -q '"typecheck"' "$CONFIG_FILE" 2>/dev/null; then
|
|
107
|
+
required="true"
|
|
108
|
+
grep -q '"type"[[:space:]]*:[[:space:]]*"typecheck"' "$CONFIG_FILE" && \
|
|
109
|
+
grep -A1 '"typecheck"' "$CONFIG_FILE" | grep -q '"required"[[:space:]]*:[[:space:]]*false' && required="false"
|
|
110
|
+
run_strategy "typecheck" "$required" "$CMD_TYPECHECK"
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
if grep -q '"type"[[:space:]]*:[[:space:]]*"lint"' "$CONFIG_FILE" 2>/dev/null; then
|
|
114
|
+
required="true"
|
|
115
|
+
grep -A1 '"lint"' "$CONFIG_FILE" | grep -q '"required"[[:space:]]*:[[:space:]]*false' && required="false"
|
|
116
|
+
run_strategy "lint" "$required" "$CMD_LINT"
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
if grep -q '"type"[[:space:]]*:[[:space:]]*"build"' "$CONFIG_FILE" 2>/dev/null; then
|
|
120
|
+
required="true"
|
|
121
|
+
grep -A1 '"build"' "$CONFIG_FILE" | grep -q '"required"[[:space:]]*:[[:space:]]*false' && required="false"
|
|
122
|
+
run_strategy "build" "$required" "$CMD_BUILD"
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
if grep -q '"type"[[:space:]]*:[[:space:]]*"unit-test"' "$CONFIG_FILE" 2>/dev/null; then
|
|
126
|
+
required="true"
|
|
127
|
+
grep -A1 '"unit-test"' "$CONFIG_FILE" | grep -q '"required"[[:space:]]*:[[:space:]]*false' && required="false"
|
|
128
|
+
run_strategy "unit-test" "$required" "$CMD_TEST"
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
if grep -q '"type"[[:space:]]*:[[:space:]]*"playwright"' "$CONFIG_FILE" 2>/dev/null; then
|
|
132
|
+
required="false"
|
|
133
|
+
grep -A1 '"playwright"' "$CONFIG_FILE" | grep -q '"required"[[:space:]]*:[[:space:]]*true' && required="true"
|
|
134
|
+
|
|
135
|
+
PLAYWRIGHT_CMD=""
|
|
136
|
+
if [[ -f "$PROJECT_DIR/package.json" ]] && grep -q "playwright" "$PROJECT_DIR/package.json" 2>/dev/null; then
|
|
137
|
+
PLAYWRIGHT_CMD="npx playwright test"
|
|
138
|
+
fi
|
|
139
|
+
run_strategy "playwright" "$required" "$PLAYWRIGHT_CMD"
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# ── Output combined result ──────────────────────────────────────────
|
|
143
|
+
|
|
144
|
+
echo ""
|
|
145
|
+
echo "──────────────────────────────────────────────────────"
|
|
146
|
+
|
|
147
|
+
if [[ "$OVERALL_PASS" == "true" ]]; then
|
|
148
|
+
echo " RESULT: PASS ($PASS_COUNT passed, $FAIL_COUNT failed, $SKIP_COUNT skipped)"
|
|
149
|
+
else
|
|
150
|
+
echo " RESULT: FAIL ($PASS_COUNT passed, $FAIL_COUNT failed, $SKIP_COUNT skipped)"
|
|
151
|
+
fi
|
|
152
|
+
|
|
153
|
+
echo ""
|
|
154
|
+
|
|
155
|
+
# Build the JSON results array
|
|
156
|
+
RESULTS_JSON="["
|
|
157
|
+
for i in "${!RESULTS[@]}"; do
|
|
158
|
+
[[ $i -gt 0 ]] && RESULTS_JSON+=","
|
|
159
|
+
RESULTS_JSON+="${RESULTS[$i]}"
|
|
160
|
+
done
|
|
161
|
+
RESULTS_JSON+="]"
|
|
162
|
+
|
|
163
|
+
# Output combined result as JSON
|
|
164
|
+
cat <<EOF
|
|
165
|
+
{
|
|
166
|
+
"overall": "$( [[ "$OVERALL_PASS" == "true" ]] && echo "pass" || echo "fail" )",
|
|
167
|
+
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
168
|
+
"projectDir": "$PROJECT_DIR",
|
|
169
|
+
"strategiesRun": $STRATEGY_COUNT,
|
|
170
|
+
"passed": $PASS_COUNT,
|
|
171
|
+
"failed": $FAIL_COUNT,
|
|
172
|
+
"skipped": $SKIP_COUNT,
|
|
173
|
+
"results": $RESULTS_JSON
|
|
174
|
+
}
|
|
175
|
+
EOF
|