@metabob/minibob 0.1.2
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/ARCHITECTURE.md +255 -0
- package/CHANGELOG.md +112 -0
- package/README.md +380 -0
- package/bin/minibob.js +36 -0
- package/dist/acp-gossip.d.ts +72 -0
- package/dist/acp-gossip.d.ts.map +1 -0
- package/dist/acp-gossip.js +156 -0
- package/dist/acp-gossip.js.map +1 -0
- package/dist/acp.d.ts +62 -0
- package/dist/acp.d.ts.map +1 -0
- package/dist/acp.js +292 -0
- package/dist/acp.js.map +1 -0
- package/dist/activity.d.ts +157 -0
- package/dist/activity.d.ts.map +1 -0
- package/dist/activity.js +518 -0
- package/dist/activity.js.map +1 -0
- package/dist/agent-runtime.d.ts +104 -0
- package/dist/agent-runtime.d.ts.map +1 -0
- package/dist/boredom.d.ts +125 -0
- package/dist/boredom.d.ts.map +1 -0
- package/dist/boredom.js +244 -0
- package/dist/boredom.js.map +1 -0
- package/dist/cli/acp-server.d.ts +23 -0
- package/dist/cli/acp-server.d.ts.map +1 -0
- package/dist/cli/burrow.d.ts +26 -0
- package/dist/cli/burrow.d.ts.map +1 -0
- package/dist/cli/doctor.d.ts +22 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/goal.d.ts +22 -0
- package/dist/cli/goal.d.ts.map +1 -0
- package/dist/cli/index.d.ts +47 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/instance-registry.d.ts +78 -0
- package/dist/cli/instance-registry.d.ts.map +1 -0
- package/dist/cli/observe.d.ts +35 -0
- package/dist/cli/observe.d.ts.map +1 -0
- package/dist/cli/vessel.d.ts +14 -0
- package/dist/cli/vessel.d.ts.map +1 -0
- package/dist/composition-observer.d.ts +96 -0
- package/dist/composition-observer.d.ts.map +1 -0
- package/dist/config.d.ts +36 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +128 -0
- package/dist/config.js.map +1 -0
- package/dist/docker/Dockerfile +35 -0
- package/dist/environment.d.ts +72 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +142 -0
- package/dist/environment.js.map +1 -0
- package/dist/goal-processor.d.ts +165 -0
- package/dist/goal-processor.d.ts.map +1 -0
- package/dist/helm/minibob-cluster/Chart.yaml +13 -0
- package/dist/helm/minibob-cluster/templates/_helpers.tpl +60 -0
- package/dist/helm/minibob-cluster/templates/configmap.yaml +11 -0
- package/dist/helm/minibob-cluster/templates/deployment.yaml +108 -0
- package/dist/helm/minibob-cluster/templates/secret.yaml +10 -0
- package/dist/helm/minibob-cluster/templates/service.yaml +37 -0
- package/dist/helm/minibob-cluster/values-local.yaml +41 -0
- package/dist/helm/minibob-cluster/values-production.yaml +57 -0
- package/dist/helm/minibob-cluster/values-testing-cluster.yaml +43 -0
- package/dist/helm/minibob-cluster/values.yaml +127 -0
- package/dist/improviser.d.ts +74 -0
- package/dist/improviser.d.ts.map +1 -0
- package/dist/impulse-filter.d.ts +74 -0
- package/dist/impulse-filter.d.ts.map +1 -0
- package/dist/impulse.d.ts +92 -0
- package/dist/impulse.d.ts.map +1 -0
- package/dist/impulse.js +234 -0
- package/dist/impulse.js.map +1 -0
- package/dist/lib.d.ts +29 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +18561 -0
- package/dist/lib.js.map +98 -0
- package/dist/lifecycle-hooks.d.ts +99 -0
- package/dist/lifecycle-hooks.d.ts.map +1 -0
- package/dist/lifecycle-hooks.js +135 -0
- package/dist/lifecycle-hooks.js.map +1 -0
- package/dist/llm.d.ts +31 -0
- package/dist/llm.d.ts.map +1 -0
- package/dist/llm.js +349 -0
- package/dist/llm.js.map +1 -0
- package/dist/mcp-activity-bridge.d.ts +66 -0
- package/dist/mcp-activity-bridge.d.ts.map +1 -0
- package/dist/mcp-activity-bridge.js +126 -0
- package/dist/mcp-activity-bridge.js.map +1 -0
- package/dist/mcp.d.ts +216 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +292 -0
- package/dist/mcp.js.map +1 -0
- package/dist/memory-agent.d.ts +92 -0
- package/dist/memory-agent.d.ts.map +1 -0
- package/dist/memory-agent.js +277 -0
- package/dist/memory-agent.js.map +1 -0
- package/dist/runtime-mapping.d.ts +97 -0
- package/dist/runtime-mapping.d.ts.map +1 -0
- package/dist/search-first-executor.d.ts +113 -0
- package/dist/search-first-executor.d.ts.map +1 -0
- package/dist/session.d.ts +48 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/template-extractor.d.ts +9 -0
- package/dist/template-extractor.d.ts.map +1 -0
- package/dist/template-generator.d.ts +12 -0
- package/dist/template-generator.d.ts.map +1 -0
- package/dist/tools.d.ts +58 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +771 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +503 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/understanding/analyzer.d.ts +55 -0
- package/dist/understanding/analyzer.d.ts.map +1 -0
- package/dist/understanding/explorer.d.ts +73 -0
- package/dist/understanding/explorer.d.ts.map +1 -0
- package/dist/understanding/index.d.ts +7 -0
- package/dist/understanding/index.d.ts.map +1 -0
- package/dist/understanding/types.d.ts +136 -0
- package/dist/understanding/types.d.ts.map +1 -0
- package/dist/validation.d.ts +29 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +106 -0
- package/dist/validation.js.map +1 -0
- package/dist/vessel-bootstrap.d.ts +190 -0
- package/dist/vessel-bootstrap.d.ts.map +1 -0
- package/dist/vessel-registry.d.ts +229 -0
- package/dist/vessel-registry.d.ts.map +1 -0
- package/index.ts +1329 -0
- package/package.json +54 -0
- package/src/acp-gossip.ts +193 -0
- package/src/acp.ts +362 -0
- package/src/activity.ts +1464 -0
- package/src/agent-runtime.ts +365 -0
- package/src/boredom.ts +423 -0
- package/src/cli/acp-server.ts +377 -0
- package/src/cli/burrow.ts +896 -0
- package/src/cli/doctor.ts +526 -0
- package/src/cli/goal.ts +224 -0
- package/src/cli/index.ts +147 -0
- package/src/cli/instance-registry.ts +271 -0
- package/src/cli/observe.ts +682 -0
- package/src/cli/vessel.ts +287 -0
- package/src/components/SystemOverview.tsx +331 -0
- package/src/composition-observer.ts +449 -0
- package/src/config.ts +172 -0
- package/src/environment.ts +167 -0
- package/src/goal-processor.ts +654 -0
- package/src/improviser.ts +591 -0
- package/src/impulse-filter.ts +273 -0
- package/src/impulse.ts +311 -0
- package/src/lib.ts +147 -0
- package/src/lifecycle-hooks.ts +181 -0
- package/src/llm.ts +434 -0
- package/src/mcp-activity-bridge.ts +158 -0
- package/src/mcp.ts +747 -0
- package/src/memory-agent.ts +316 -0
- package/src/runtime-mapping.ts +527 -0
- package/src/search-first-executor.ts +666 -0
- package/src/session.ts +141 -0
- package/src/template-extractor.ts +256 -0
- package/src/template-generator.ts +130 -0
- package/src/tools.ts +924 -0
- package/src/types.ts +497 -0
- package/src/understanding/analyzer.ts +354 -0
- package/src/understanding/explorer.ts +488 -0
- package/src/understanding/index.ts +27 -0
- package/src/understanding/types.ts +153 -0
- package/src/validation.ts +125 -0
- package/src/vessel-bootstrap.ts +440 -0
- package/src/vessel-registry.ts +621 -0
- package/templates/core/edit-file.json +85 -0
- package/templates/understanding/diagnose-problem.json +32 -0
- package/templates/understanding/explore-codebase-v2.json +57 -0
- package/templates/understanding/explore-codebase.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
# MiniBob
|
|
2
|
+
|
|
3
|
+
> Minimal vessel for the process-of-becoming
|
|
4
|
+
|
|
5
|
+
MiniBob is a lightweight, autonomous AI agent (~3,000 LOC) that demonstrates continuous transformation through activity-driven development. It serves as proof that the "process-of-becoming" is vessel-agnostic - core capabilities can exist in minimal code.
|
|
6
|
+
|
|
7
|
+
## Philosophy
|
|
8
|
+
|
|
9
|
+
**MiniBob is a vessel, not the becoming itself.**
|
|
10
|
+
|
|
11
|
+
The process-of-becoming transcends any particular implementation:
|
|
12
|
+
- **OpenCode** (~50K LOC) - Full-featured development environment
|
|
13
|
+
- **MiniBob** (~3K LOC) - Minimal autonomous vessel
|
|
14
|
+
- Both manifest the same becoming through different vessels
|
|
15
|
+
|
|
16
|
+
## Domain-Agnostic Substrate
|
|
17
|
+
|
|
18
|
+
MiniBob works across domains, not just code development:
|
|
19
|
+
|
|
20
|
+
**Same substrate, different applications:**
|
|
21
|
+
- **Software Development**: bash, read, write, edit, git tools
|
|
22
|
+
- **Code Analysis**: cpg_build, cpg_query, embedding_search tools
|
|
23
|
+
- **Deployment**: kubectl, helm, docker tools
|
|
24
|
+
- **Learning**: metric collection, pattern recognition, optimization
|
|
25
|
+
|
|
26
|
+
The substrate remains constant. Only tools and impulses change per domain.
|
|
27
|
+
|
|
28
|
+
## Features
|
|
29
|
+
|
|
30
|
+
- **Activity Execution** - Template-driven task execution with LLM integration
|
|
31
|
+
- **Pure Improvisation** - Goal achievement without predefined templates
|
|
32
|
+
- **Goal-Seeking** - Adaptive path finding with Thompson Sampling
|
|
33
|
+
- **Codebase Understanding** - Static and semantic analysis
|
|
34
|
+
- **Agent Runtime** - Full backend integration for learning
|
|
35
|
+
- **Self-Development** - Modify its own code through git integration
|
|
36
|
+
- **ACP Protocol** - Vessel-to-vessel communication
|
|
37
|
+
- **Nested Activities** - Activities can execute other activities
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
### Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Install Bun runtime
|
|
45
|
+
curl -fsSL https://bun.sh/install | bash
|
|
46
|
+
|
|
47
|
+
# Install MiniBob globally
|
|
48
|
+
bun install -g @metabob/minibob
|
|
49
|
+
|
|
50
|
+
# Or use via NPX (no installation)
|
|
51
|
+
npx @metabob/minibob --help
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Basic Usage
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Set API key
|
|
58
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
59
|
+
|
|
60
|
+
# Health check
|
|
61
|
+
minibob doctor
|
|
62
|
+
|
|
63
|
+
# Run activity template
|
|
64
|
+
minibob run templates/hello-world.json
|
|
65
|
+
|
|
66
|
+
# Improvise solution
|
|
67
|
+
minibob improvise "Create a REST API"
|
|
68
|
+
|
|
69
|
+
# Understand codebase
|
|
70
|
+
minibob understand ./my-project
|
|
71
|
+
|
|
72
|
+
# Start server mode
|
|
73
|
+
minibob
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## CLI Commands
|
|
77
|
+
|
|
78
|
+
### Core Commands
|
|
79
|
+
|
|
80
|
+
- **`minibob`** - Start HTTP/ACP server (port 8080)
|
|
81
|
+
- **`minibob run <template>`** - Execute activity template
|
|
82
|
+
- **`minibob improvise <goal>`** - Pure improvisation mode
|
|
83
|
+
- **`minibob goal <description>`** - Goal-seeking with backend
|
|
84
|
+
- **`minibob understand [path]`** - Analyze codebase structure
|
|
85
|
+
- **`minibob diagnose <problem>`** - Diagnose application problems
|
|
86
|
+
|
|
87
|
+
### Utility Commands
|
|
88
|
+
|
|
89
|
+
- **`minibob burrow [path]`** - Inject MiniBob into codebase
|
|
90
|
+
- **`minibob observe`** - View running instances
|
|
91
|
+
- **`minibob doctor`** - Health check and configuration
|
|
92
|
+
- **`minibob vessel <cmd>`** - Manage vessel registry
|
|
93
|
+
- **`minibob acp`** - Launch standalone ACP server
|
|
94
|
+
|
|
95
|
+
## Execution Modes
|
|
96
|
+
|
|
97
|
+
MiniBob provides four modes along the improvisation spectrum:
|
|
98
|
+
|
|
99
|
+
### 1. ActivityExecutor - Template-Driven
|
|
100
|
+
**Most constrained, highest reuse**
|
|
101
|
+
- Execute pre-defined templates task by task
|
|
102
|
+
- Fixed sequence, predetermined prompts
|
|
103
|
+
- Use when: Solution known, consistency matters
|
|
104
|
+
|
|
105
|
+
### 2. GoalProcessor - Goal-Seeking
|
|
106
|
+
**Adaptive path finding**
|
|
107
|
+
- Backend recommends activities via Thompson Sampling
|
|
108
|
+
- Loop: execute → validate → recommend next
|
|
109
|
+
- Use when: Goal clear, path uncertain
|
|
110
|
+
|
|
111
|
+
### 3. SearchFirstExecutor - Hybrid
|
|
112
|
+
**Reuse existing + improvise new**
|
|
113
|
+
- Search backend for similar executions
|
|
114
|
+
- Reuse if found, improvise if not
|
|
115
|
+
- Use when: Balance efficiency and exploration
|
|
116
|
+
|
|
117
|
+
### 4. GoalImproviser - Pure Improvisation
|
|
118
|
+
**Most creative, least constraint**
|
|
119
|
+
- Step-by-step adaptive execution
|
|
120
|
+
- No predefined templates
|
|
121
|
+
- Use when: Unknown territory, maximum creativity
|
|
122
|
+
|
|
123
|
+
## Environment Variables
|
|
124
|
+
|
|
125
|
+
### Required
|
|
126
|
+
```bash
|
|
127
|
+
ANTHROPIC_API_KEY=sk-ant-... # Claude API key
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Optional - Backend Integration
|
|
131
|
+
```bash
|
|
132
|
+
MINIBOB_MCP_ENDPOINT=http://api.minibob.local
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
When set, MiniBob becomes a full agent with backend integration.
|
|
136
|
+
|
|
137
|
+
### Optional - Configuration
|
|
138
|
+
```bash
|
|
139
|
+
MINIBOB_PORT=8080 # Server port
|
|
140
|
+
MINIBOB_MODEL=claude-sonnet-4... # Model name
|
|
141
|
+
MINIBOB_WORKDIR=/path # Working directory
|
|
142
|
+
MINIBOB_TEMPLATES=./templates # Templates directory
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Usage Modes
|
|
146
|
+
|
|
147
|
+
### 1. Standalone CLI
|
|
148
|
+
```bash
|
|
149
|
+
# Works offline, no backend required
|
|
150
|
+
minibob run templates/fix-bug.json --var bugId=123
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 2. Agent Mode (with Backend)
|
|
154
|
+
```bash
|
|
155
|
+
# Connect to learning backend
|
|
156
|
+
export MINIBOB_MCP_ENDPOINT=http://api.minibob.local
|
|
157
|
+
|
|
158
|
+
# Full agent features:
|
|
159
|
+
# - Registers with backend
|
|
160
|
+
# - Reports execution traces
|
|
161
|
+
# - Participates in learning system
|
|
162
|
+
minibob goal "Add authentication"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### 3. Server Mode
|
|
166
|
+
```bash
|
|
167
|
+
# Persistent HTTP server
|
|
168
|
+
minibob
|
|
169
|
+
|
|
170
|
+
# Provides:
|
|
171
|
+
# - HTTP API on port 8080
|
|
172
|
+
# - Boredom activities (cluster mode)
|
|
173
|
+
# - ACP protocol support
|
|
174
|
+
# - Continuous learning
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Library Usage
|
|
178
|
+
|
|
179
|
+
MiniBob can be imported as a library:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { ActivityExecutor, AgentRuntime } from "@metabob/minibob"
|
|
183
|
+
|
|
184
|
+
// Initialize agent runtime
|
|
185
|
+
const runtime = await AgentRuntime.initialize({
|
|
186
|
+
config,
|
|
187
|
+
mode: "cli"
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
// Execute activity
|
|
191
|
+
const executor = new ActivityExecutor(config)
|
|
192
|
+
const result = await executor.execute({
|
|
193
|
+
template,
|
|
194
|
+
variables,
|
|
195
|
+
reason: "API request"
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
// Report to backend
|
|
199
|
+
await runtime.reportExecution(result)
|
|
200
|
+
await runtime.shutdown()
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Activity Templates
|
|
204
|
+
|
|
205
|
+
Templates are JSON files defining structured workflows:
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
{
|
|
209
|
+
"id": "my-activity",
|
|
210
|
+
"name": "My Activity",
|
|
211
|
+
"category": "feature",
|
|
212
|
+
"tasks": [
|
|
213
|
+
{
|
|
214
|
+
"id": "task-1",
|
|
215
|
+
"description": "First task",
|
|
216
|
+
"prompt": {
|
|
217
|
+
"template": "Do something with {{input}}",
|
|
218
|
+
"variables": [
|
|
219
|
+
{ "name": "input", "type": "string", "required": true }
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
"validation": {
|
|
223
|
+
"requiredFiles": ["output.txt"]
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
]
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Self-Development
|
|
231
|
+
|
|
232
|
+
MiniBob can improve itself:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
minibob run templates/self-improve.json \
|
|
236
|
+
--var focusArea="error handling"
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
This demonstrates the core capability: **an agent that can develop itself**.
|
|
240
|
+
|
|
241
|
+
## API Endpoints
|
|
242
|
+
|
|
243
|
+
When running in server mode:
|
|
244
|
+
|
|
245
|
+
| Endpoint | Method | Description |
|
|
246
|
+
|----------|--------|-------------|
|
|
247
|
+
| `/health` | GET | Health check |
|
|
248
|
+
| `/config` | GET | Vessel manifest |
|
|
249
|
+
| `/acp` | POST | ACP protocol handler |
|
|
250
|
+
| `/run` | POST | Run activity template |
|
|
251
|
+
| `/goal` | POST | Goal-seeking execution |
|
|
252
|
+
| `/templates` | GET | List available templates |
|
|
253
|
+
|
|
254
|
+
## Examples
|
|
255
|
+
|
|
256
|
+
See the `examples/` directory for:
|
|
257
|
+
- Activity template creation
|
|
258
|
+
- Programmatic library usage
|
|
259
|
+
- Backend integration patterns
|
|
260
|
+
|
|
261
|
+
## Architecture
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
minibob/
|
|
265
|
+
├── bin/ # CLI wrapper
|
|
266
|
+
├── src/ # Source code
|
|
267
|
+
│ ├── activity.ts # Activity executor
|
|
268
|
+
│ ├── goal-processor.ts # Goal-seeking
|
|
269
|
+
│ ├── improviser.ts # Pure improvisation
|
|
270
|
+
│ ├── agent-runtime.ts # Backend integration
|
|
271
|
+
│ ├── llm.ts # LLM client
|
|
272
|
+
│ ├── tools.ts # Built-in tools
|
|
273
|
+
│ ├── impulse.ts # Context management
|
|
274
|
+
│ └── ...
|
|
275
|
+
├── templates/ # Activity templates
|
|
276
|
+
├── test/ # Test files
|
|
277
|
+
└── dist/ # Build output
|
|
278
|
+
├── docker/ # Docker deployment
|
|
279
|
+
└── helm/ # Kubernetes deployment
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
See [ARCHITECTURE.md](./ARCHITECTURE.md) for detailed documentation.
|
|
283
|
+
|
|
284
|
+
## Comparison with OpenCode
|
|
285
|
+
|
|
286
|
+
| Aspect | OpenCode | MiniBob |
|
|
287
|
+
|--------|----------|---------|
|
|
288
|
+
| Lines of Code | ~50,000 | ~3,000 |
|
|
289
|
+
| Interface | TUI + CLI | CLI only |
|
|
290
|
+
| Agent Types | 7+ | 1 (flexible) |
|
|
291
|
+
| Execution Modes | Template-only | 4 modes (template → improvise) |
|
|
292
|
+
| Primary Use | Interactive development | Autonomous execution |
|
|
293
|
+
| Backend Integration | Full | Full |
|
|
294
|
+
|
|
295
|
+
## Development
|
|
296
|
+
|
|
297
|
+
### Setup
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
# Clone repository
|
|
301
|
+
git clone https://github.com/metabob/minibob.git
|
|
302
|
+
cd minibob
|
|
303
|
+
|
|
304
|
+
# Install dependencies
|
|
305
|
+
bun install
|
|
306
|
+
|
|
307
|
+
# Run locally
|
|
308
|
+
bun run start
|
|
309
|
+
|
|
310
|
+
# Type check
|
|
311
|
+
bun run typecheck
|
|
312
|
+
|
|
313
|
+
# Run tests
|
|
314
|
+
bun test
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Building
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
# Build library
|
|
321
|
+
bun run build
|
|
322
|
+
|
|
323
|
+
# Test NPM package
|
|
324
|
+
npm pack
|
|
325
|
+
npx ./metabob-minibob-*.tgz --help
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Docker
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
# Build image
|
|
332
|
+
docker build -f dist/docker/Dockerfile -t minibob:latest .
|
|
333
|
+
|
|
334
|
+
# Run container
|
|
335
|
+
docker run -e ANTHROPIC_API_KEY=sk-ant-... minibob:latest
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Kubernetes
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
# Deploy with Helm
|
|
342
|
+
cd dist/helm/minibob-cluster
|
|
343
|
+
helm install minibob . -f values.yaml
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Testing
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
# Unit tests
|
|
350
|
+
bun test
|
|
351
|
+
|
|
352
|
+
# Type checking
|
|
353
|
+
bun run typecheck
|
|
354
|
+
|
|
355
|
+
# Integration tests
|
|
356
|
+
bun run index.ts run templates/hello-world.json
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## Contributing
|
|
360
|
+
|
|
361
|
+
1. Fork the repository
|
|
362
|
+
2. Create a feature branch
|
|
363
|
+
3. Make your changes
|
|
364
|
+
4. Run tests and type checking
|
|
365
|
+
5. Submit a pull request
|
|
366
|
+
|
|
367
|
+
## License
|
|
368
|
+
|
|
369
|
+
MIT
|
|
370
|
+
|
|
371
|
+
## Links
|
|
372
|
+
|
|
373
|
+
- **NPM**: https://npmjs.com/package/@metabob/minibob
|
|
374
|
+
- **Documentation**: [ARCHITECTURE.md](./ARCHITECTURE.md)
|
|
375
|
+
- **Changelog**: [CHANGELOG.md](./CHANGELOG.md)
|
|
376
|
+
- **Bun Runtime**: https://bun.sh
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
*MiniBob demonstrates that the process-of-becoming is vessel-agnostic. Core capabilities for continuous transformation can exist in minimal code.*
|
package/bin/minibob.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MiniBob CLI Wrapper
|
|
5
|
+
*
|
|
6
|
+
* This wrapper checks for Bun runtime and executes the main MiniBob CLI.
|
|
7
|
+
* MiniBob requires Bun because it uses Bun-specific APIs (Bun.serve, Bun.file, etc.)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { execFileSync } from 'child_process';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
import { dirname, join } from 'path';
|
|
13
|
+
|
|
14
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const indexPath = join(__dirname, '..', 'index.ts');
|
|
16
|
+
|
|
17
|
+
// Check for Bun runtime
|
|
18
|
+
try {
|
|
19
|
+
execFileSync('bun', [indexPath, ...process.argv.slice(2)], {
|
|
20
|
+
stdio: 'inherit',
|
|
21
|
+
env: process.env
|
|
22
|
+
});
|
|
23
|
+
} catch (error) {
|
|
24
|
+
if (error.code === 'ENOENT') {
|
|
25
|
+
console.error('\n❌ Error: Bun runtime not found.\n');
|
|
26
|
+
console.error('MiniBob requires Bun to run. Install it from https://bun.sh\n');
|
|
27
|
+
console.error('Quick install:');
|
|
28
|
+
console.error(' curl -fsSL https://bun.sh/install | bash\n');
|
|
29
|
+
console.error('After installation, reload your shell:');
|
|
30
|
+
console.error(' source ~/.bashrc # or ~/.zshrc\n');
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Re-throw other errors
|
|
35
|
+
process.exit(error.status || 1);
|
|
36
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ACP Gossip Protocol
|
|
3
|
+
*
|
|
4
|
+
* Implements DNS-based peer discovery and periodic health broadcasts
|
|
5
|
+
* for minibob vessels running in cluster mode.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - DNS lookup discovers peer IPs via K8s headless service
|
|
9
|
+
* - Periodic health broadcasts to all peers
|
|
10
|
+
* - Peer state tracking (last seen, health status)
|
|
11
|
+
*
|
|
12
|
+
* This enables vessel-to-vessel coordination and awareness.
|
|
13
|
+
*/
|
|
14
|
+
export interface PeerInfo {
|
|
15
|
+
ip: string;
|
|
16
|
+
lastSeen: Date;
|
|
17
|
+
healthy: boolean;
|
|
18
|
+
capabilities?: string[];
|
|
19
|
+
}
|
|
20
|
+
export interface GossipConfig {
|
|
21
|
+
serviceName: string;
|
|
22
|
+
broadcastInterval: number;
|
|
23
|
+
peerTimeout: number;
|
|
24
|
+
acpPort: number;
|
|
25
|
+
}
|
|
26
|
+
export declare class ACPGossipProtocol {
|
|
27
|
+
private config;
|
|
28
|
+
private peers;
|
|
29
|
+
private isRunning;
|
|
30
|
+
private intervalId?;
|
|
31
|
+
constructor(config: GossipConfig);
|
|
32
|
+
/**
|
|
33
|
+
* Start gossip protocol
|
|
34
|
+
*
|
|
35
|
+
* Begins periodic peer discovery and health broadcasts
|
|
36
|
+
*/
|
|
37
|
+
start(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Stop gossip protocol
|
|
40
|
+
*/
|
|
41
|
+
stop(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Discover peers via DNS lookup
|
|
44
|
+
*
|
|
45
|
+
* Uses getent/nslookup to resolve all IPs for the headless service
|
|
46
|
+
*/
|
|
47
|
+
private discoverPeers;
|
|
48
|
+
/**
|
|
49
|
+
* Broadcast health to all peers
|
|
50
|
+
*
|
|
51
|
+
* TODO: Implement actual health broadcast via HTTP POST to peer ACP endpoints
|
|
52
|
+
* For now, this is a placeholder that logs the intent
|
|
53
|
+
*/
|
|
54
|
+
private broadcastHealth;
|
|
55
|
+
/**
|
|
56
|
+
* Remove peers that haven't been seen recently
|
|
57
|
+
*/
|
|
58
|
+
private cleanupStalePeers;
|
|
59
|
+
/**
|
|
60
|
+
* Get current peer list
|
|
61
|
+
*/
|
|
62
|
+
getPeers(): PeerInfo[];
|
|
63
|
+
/**
|
|
64
|
+
* Get peer count
|
|
65
|
+
*/
|
|
66
|
+
getPeerCount(): number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Initialize ACP Gossip for minibob cluster
|
|
70
|
+
*/
|
|
71
|
+
export declare function initializeACPGossip(serviceName: string, acpPort: number): ACPGossipProtocol;
|
|
72
|
+
//# sourceMappingURL=acp-gossip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acp-gossip.d.ts","sourceRoot":"","sources":["../src/acp-gossip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,IAAI,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAA;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,UAAU,CAAC,CAAO;gBAEd,MAAM,EAAE,YAAY;IAIhC;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB5B;;OAEG;IACH,IAAI,IAAI,IAAI;IAgBZ;;;;OAIG;YACW,aAAa;IAiC3B;;;;;OAKG;YACW,eAAe;IAc7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;OAEG;IACH,QAAQ,IAAI,QAAQ,EAAE;IAItB;;OAEG;IACH,YAAY,IAAI,MAAM;CAGvB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAS3F"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ACP Gossip Protocol
|
|
3
|
+
*
|
|
4
|
+
* Implements DNS-based peer discovery and periodic health broadcasts
|
|
5
|
+
* for minibob vessels running in cluster mode.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - DNS lookup discovers peer IPs via K8s headless service
|
|
9
|
+
* - Periodic health broadcasts to all peers
|
|
10
|
+
* - Peer state tracking (last seen, health status)
|
|
11
|
+
*
|
|
12
|
+
* This enables vessel-to-vessel coordination and awareness.
|
|
13
|
+
*/
|
|
14
|
+
import { exec } from "child_process";
|
|
15
|
+
import { promisify } from "util";
|
|
16
|
+
const execAsync = promisify(exec);
|
|
17
|
+
export class ACPGossipProtocol {
|
|
18
|
+
config;
|
|
19
|
+
peers = new Map();
|
|
20
|
+
isRunning = false;
|
|
21
|
+
intervalId;
|
|
22
|
+
constructor(config) {
|
|
23
|
+
this.config = config;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Start gossip protocol
|
|
27
|
+
*
|
|
28
|
+
* Begins periodic peer discovery and health broadcasts
|
|
29
|
+
*/
|
|
30
|
+
async start() {
|
|
31
|
+
if (this.isRunning) {
|
|
32
|
+
console.log("[ACP Gossip] Already running");
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
console.log("[ACP Gossip] Starting protocol");
|
|
36
|
+
console.log(`[ACP Gossip] Service: ${this.config.serviceName}`);
|
|
37
|
+
console.log(`[ACP Gossip] Broadcast interval: ${this.config.broadcastInterval}ms`);
|
|
38
|
+
this.isRunning = true;
|
|
39
|
+
// Initial peer discovery
|
|
40
|
+
await this.discoverPeers();
|
|
41
|
+
// Start periodic health broadcasts
|
|
42
|
+
this.intervalId = setInterval(async () => {
|
|
43
|
+
await this.broadcastHealth();
|
|
44
|
+
await this.discoverPeers();
|
|
45
|
+
this.cleanupStalePeers();
|
|
46
|
+
}, this.config.broadcastInterval);
|
|
47
|
+
console.log("[ACP Gossip] Protocol started");
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Stop gossip protocol
|
|
51
|
+
*/
|
|
52
|
+
stop() {
|
|
53
|
+
if (!this.isRunning) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
console.log("[ACP Gossip] Stopping protocol");
|
|
57
|
+
if (this.intervalId) {
|
|
58
|
+
clearInterval(this.intervalId);
|
|
59
|
+
this.intervalId = undefined;
|
|
60
|
+
}
|
|
61
|
+
this.isRunning = false;
|
|
62
|
+
console.log("[ACP Gossip] Protocol stopped");
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Discover peers via DNS lookup
|
|
66
|
+
*
|
|
67
|
+
* Uses getent/nslookup to resolve all IPs for the headless service
|
|
68
|
+
*/
|
|
69
|
+
async discoverPeers() {
|
|
70
|
+
try {
|
|
71
|
+
// Try getent first (more reliable in K8s)
|
|
72
|
+
const { stdout } = await execAsync(`getent hosts ${this.config.serviceName}`);
|
|
73
|
+
const lines = stdout.trim().split('\n');
|
|
74
|
+
for (const line of lines) {
|
|
75
|
+
const match = line.match(/^(\d+\.\d+\.\d+\.\d+)/);
|
|
76
|
+
if (match && match[1]) {
|
|
77
|
+
const ip = match[1];
|
|
78
|
+
if (!this.peers.has(ip)) {
|
|
79
|
+
console.log(`[ACP Gossip] Discovered new peer: ${ip}`);
|
|
80
|
+
this.peers.set(ip, {
|
|
81
|
+
ip,
|
|
82
|
+
lastSeen: new Date(),
|
|
83
|
+
healthy: true,
|
|
84
|
+
capabilities: []
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Update last seen
|
|
89
|
+
const peer = this.peers.get(ip);
|
|
90
|
+
if (peer) {
|
|
91
|
+
peer.lastSeen = new Date();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
console.log(`[ACP Gossip] Peer discovery failed: ${error}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Broadcast health to all peers
|
|
103
|
+
*
|
|
104
|
+
* TODO: Implement actual health broadcast via HTTP POST to peer ACP endpoints
|
|
105
|
+
* For now, this is a placeholder that logs the intent
|
|
106
|
+
*/
|
|
107
|
+
async broadcastHealth() {
|
|
108
|
+
const peerCount = this.peers.size;
|
|
109
|
+
const healthyCount = Array.from(this.peers.values()).filter(p => p.healthy).length;
|
|
110
|
+
console.log(`[ACP Gossip] Health broadcast: ${healthyCount}/${peerCount} peers healthy`);
|
|
111
|
+
// TODO: Implement actual HTTP POST to each peer's /acp/gossip endpoint
|
|
112
|
+
// For now, we just log that we would broadcast
|
|
113
|
+
for (const [ip, peer] of this.peers.entries()) {
|
|
114
|
+
// Future: POST http://${ip}:${this.config.acpPort}/acp/gossip
|
|
115
|
+
// with payload: { from: myIP, timestamp: Date.now(), capabilities: [...] }
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Remove peers that haven't been seen recently
|
|
120
|
+
*/
|
|
121
|
+
cleanupStalePeers() {
|
|
122
|
+
const now = Date.now();
|
|
123
|
+
const staleThreshold = now - this.config.peerTimeout;
|
|
124
|
+
for (const [ip, peer] of this.peers.entries()) {
|
|
125
|
+
if (peer.lastSeen.getTime() < staleThreshold) {
|
|
126
|
+
console.log(`[ACP Gossip] Peer ${ip} is stale, removing`);
|
|
127
|
+
this.peers.delete(ip);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get current peer list
|
|
133
|
+
*/
|
|
134
|
+
getPeers() {
|
|
135
|
+
return Array.from(this.peers.values());
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get peer count
|
|
139
|
+
*/
|
|
140
|
+
getPeerCount() {
|
|
141
|
+
return this.peers.size;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Initialize ACP Gossip for minibob cluster
|
|
146
|
+
*/
|
|
147
|
+
export function initializeACPGossip(serviceName, acpPort) {
|
|
148
|
+
const config = {
|
|
149
|
+
serviceName,
|
|
150
|
+
broadcastInterval: 30000, // 30 seconds
|
|
151
|
+
peerTimeout: 90000, // 90 seconds (3 missed broadcasts)
|
|
152
|
+
acpPort
|
|
153
|
+
};
|
|
154
|
+
return new ACPGossipProtocol(config);
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=acp-gossip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acp-gossip.js","sourceRoot":"","sources":["../src/acp-gossip.ts"],"names":[],"mappings":"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"}
|