@plures/runebook 0.4.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/ANALYSIS_LADDER.md +231 -0
- package/CHANGELOG.md +124 -0
- package/INTEGRATIONS.md +242 -0
- package/LICENSE +21 -0
- package/MEMORY.md +253 -0
- package/NIXOS.md +357 -0
- package/QUICKSTART.md +157 -0
- package/README.md +295 -0
- package/RELEASE.md +190 -0
- package/ValidationChecklist.md +598 -0
- package/docs/demo.md +338 -0
- package/docs/llm-integration.md +300 -0
- package/docs/parallel-execution-plan.md +160 -0
- package/flake.nix +228 -0
- package/integrations/README.md +242 -0
- package/integrations/demo-steps.sh +64 -0
- package/integrations/nvim-runebook.lua +140 -0
- package/integrations/tmux-status.sh +51 -0
- package/integrations/vim-runebook.vim +77 -0
- package/integrations/wezterm-status-simple.lua +48 -0
- package/integrations/wezterm-status.lua +76 -0
- package/nixos-module.nix +156 -0
- package/package.json +76 -0
- package/packages/design-dojo/index.js +4 -0
- package/packages/design-dojo/package.json +20 -0
- package/packages/design-dojo/tokens.css +69 -0
- package/playwright.config.ts +16 -0
- package/scripts/check-versions.cjs +62 -0
- package/scripts/demo.sh +220 -0
- package/shell.nix +31 -0
- package/src/app.html +13 -0
- package/src/cli/index.ts +1050 -0
- package/src/lib/agent/analysis-pipeline.ts +347 -0
- package/src/lib/agent/analysis-service.ts +171 -0
- package/src/lib/agent/analysis.ts +159 -0
- package/src/lib/agent/analyzers/heuristic.ts +289 -0
- package/src/lib/agent/analyzers/index.ts +7 -0
- package/src/lib/agent/analyzers/llm.ts +204 -0
- package/src/lib/agent/analyzers/local-search.ts +215 -0
- package/src/lib/agent/capture.ts +123 -0
- package/src/lib/agent/index.ts +244 -0
- package/src/lib/agent/integration.ts +81 -0
- package/src/lib/agent/llm/providers/base.ts +99 -0
- package/src/lib/agent/llm/providers/index.ts +60 -0
- package/src/lib/agent/llm/providers/mock.ts +67 -0
- package/src/lib/agent/llm/providers/ollama.ts +151 -0
- package/src/lib/agent/llm/providers/openai.ts +153 -0
- package/src/lib/agent/llm/sanitizer.ts +170 -0
- package/src/lib/agent/llm/types.ts +118 -0
- package/src/lib/agent/memory.ts +363 -0
- package/src/lib/agent/node-status.ts +56 -0
- package/src/lib/agent/node-suggestions.ts +64 -0
- package/src/lib/agent/status.ts +80 -0
- package/src/lib/agent/suggestions.ts +169 -0
- package/src/lib/components/Canvas.svelte +124 -0
- package/src/lib/components/ConnectionLine.svelte +46 -0
- package/src/lib/components/DisplayNode.svelte +167 -0
- package/src/lib/components/InputNode.svelte +158 -0
- package/src/lib/components/TerminalNode.svelte +237 -0
- package/src/lib/components/Toolbar.svelte +359 -0
- package/src/lib/components/TransformNode.svelte +327 -0
- package/src/lib/core/index.ts +31 -0
- package/src/lib/core/observer.ts +278 -0
- package/src/lib/core/redaction.ts +158 -0
- package/src/lib/core/shell-adapters/base.ts +325 -0
- package/src/lib/core/shell-adapters/bash.ts +110 -0
- package/src/lib/core/shell-adapters/index.ts +62 -0
- package/src/lib/core/shell-adapters/zsh.ts +105 -0
- package/src/lib/core/storage.ts +360 -0
- package/src/lib/core/types.ts +176 -0
- package/src/lib/design-dojo/Box.svelte +47 -0
- package/src/lib/design-dojo/Button.svelte +75 -0
- package/src/lib/design-dojo/Input.svelte +65 -0
- package/src/lib/design-dojo/List.svelte +38 -0
- package/src/lib/design-dojo/Select.svelte +48 -0
- package/src/lib/design-dojo/SplitPane.svelte +43 -0
- package/src/lib/design-dojo/StatusBar.svelte +61 -0
- package/src/lib/design-dojo/Table.svelte +47 -0
- package/src/lib/design-dojo/Text.svelte +36 -0
- package/src/lib/design-dojo/Toggle.svelte +48 -0
- package/src/lib/design-dojo/index.ts +10 -0
- package/src/lib/stores/canvas-praxis.ts +268 -0
- package/src/lib/stores/canvas.ts +58 -0
- package/src/lib/types/agent.ts +78 -0
- package/src/lib/types/canvas.ts +71 -0
- package/src/lib/utils/storage.ts +326 -0
- package/src/lib/utils/yaml-loader.ts +52 -0
- package/src/routes/+layout.svelte +5 -0
- package/src/routes/+layout.ts +5 -0
- package/src/routes/+page.svelte +32 -0
- package/src-tauri/Cargo.lock +5735 -0
- package/src-tauri/Cargo.toml +38 -0
- package/src-tauri/build.rs +3 -0
- package/src-tauri/capabilities/default.json +10 -0
- package/src-tauri/icons/128x128.png +0 -0
- package/src-tauri/icons/128x128@2x.png +0 -0
- package/src-tauri/icons/32x32.png +0 -0
- package/src-tauri/icons/Square107x107Logo.png +0 -0
- package/src-tauri/icons/Square142x142Logo.png +0 -0
- package/src-tauri/icons/Square150x150Logo.png +0 -0
- package/src-tauri/icons/Square284x284Logo.png +0 -0
- package/src-tauri/icons/Square30x30Logo.png +0 -0
- package/src-tauri/icons/Square310x310Logo.png +0 -0
- package/src-tauri/icons/Square44x44Logo.png +0 -0
- package/src-tauri/icons/Square71x71Logo.png +0 -0
- package/src-tauri/icons/Square89x89Logo.png +0 -0
- package/src-tauri/icons/StoreLogo.png +0 -0
- package/src-tauri/icons/icon.icns +0 -0
- package/src-tauri/icons/icon.ico +0 -0
- package/src-tauri/icons/icon.png +0 -0
- package/src-tauri/src/agents/agent1.rs +66 -0
- package/src-tauri/src/agents/agent2.rs +80 -0
- package/src-tauri/src/agents/agent3.rs +73 -0
- package/src-tauri/src/agents/agent4.rs +66 -0
- package/src-tauri/src/agents/agent5.rs +68 -0
- package/src-tauri/src/agents/agent6.rs +75 -0
- package/src-tauri/src/agents/base.rs +52 -0
- package/src-tauri/src/agents/mod.rs +17 -0
- package/src-tauri/src/core/coordination.rs +117 -0
- package/src-tauri/src/core/mod.rs +12 -0
- package/src-tauri/src/core/ownership.rs +61 -0
- package/src-tauri/src/core/types.rs +132 -0
- package/src-tauri/src/execution/mod.rs +5 -0
- package/src-tauri/src/execution/runner.rs +143 -0
- package/src-tauri/src/lib.rs +161 -0
- package/src-tauri/src/main.rs +6 -0
- package/src-tauri/src/memory/api.rs +422 -0
- package/src-tauri/src/memory/client.rs +156 -0
- package/src-tauri/src/memory/encryption.rs +79 -0
- package/src-tauri/src/memory/migration.rs +110 -0
- package/src-tauri/src/memory/mod.rs +28 -0
- package/src-tauri/src/memory/schema.rs +275 -0
- package/src-tauri/src/memory/tests.rs +192 -0
- package/src-tauri/src/orchestrator/coordinator.rs +232 -0
- package/src-tauri/src/orchestrator/mod.rs +13 -0
- package/src-tauri/src/orchestrator/planner.rs +304 -0
- package/src-tauri/tauri.conf.json +35 -0
- package/static/examples/date-time-example.yaml +147 -0
- package/static/examples/hello-world.yaml +74 -0
- package/static/examples/transform-example.yaml +157 -0
- package/static/favicon.png +0 -0
- package/static/svelte.svg +1 -0
- package/static/tauri.svg +6 -0
- package/static/vite.svg +1 -0
- package/svelte.config.js +18 -0
- package/tsconfig.json +19 -0
- package/vite.config.js +45 -0
- package/vitest.config.ts +21 -0
package/MEMORY.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# RuneBook Cognitive Memory
|
|
2
|
+
|
|
3
|
+
Local-first "cognitive memory" storage for terminal events, commands, outputs, errors, insights, and suggestions.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The cognitive memory system provides persistent storage for terminal activity, enabling pattern analysis, error tracking, and intelligent suggestions. It uses PluresDB as the storage backend with a Rust API layer for performance and type safety.
|
|
8
|
+
|
|
9
|
+
## Architecture
|
|
10
|
+
|
|
11
|
+
### Storage Schema
|
|
12
|
+
|
|
13
|
+
The memory system organizes data into the following collections:
|
|
14
|
+
|
|
15
|
+
- **sessions**: Terminal session metadata (start time, shell type, working directory)
|
|
16
|
+
- **commands**: Normalized command records (command, args, exit code, duration)
|
|
17
|
+
- **outputs**: Chunked stdout/stderr output (optionally compressed)
|
|
18
|
+
- **errors**: Classified error records (type, severity, context)
|
|
19
|
+
- **insights**: AI/heuristic annotations (patterns, optimizations, warnings)
|
|
20
|
+
- **suggestions**: Ranked suggestions (command, optimization, shortcut, warning, tip)
|
|
21
|
+
- **provenance**: Source tracking (confidence, model/tool used)
|
|
22
|
+
|
|
23
|
+
### Data Flow
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
Terminal Event → MemoryEvent → append_event() → PluresDB
|
|
27
|
+
↓
|
|
28
|
+
Schema-specific storage
|
|
29
|
+
↓
|
|
30
|
+
(sessions, commands, outputs, errors, etc.)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## API Reference
|
|
34
|
+
|
|
35
|
+
### Rust API
|
|
36
|
+
|
|
37
|
+
The main API is provided by the `MemoryStore` struct:
|
|
38
|
+
|
|
39
|
+
```rust
|
|
40
|
+
use runebook_lib::memory::*;
|
|
41
|
+
|
|
42
|
+
// Initialize
|
|
43
|
+
let store = init_memory_store("localhost", 34567, "./pluresdb-data").await?;
|
|
44
|
+
|
|
45
|
+
// Append event
|
|
46
|
+
let event = MemoryEvent { /* ... */ };
|
|
47
|
+
store.append_event(event).await?;
|
|
48
|
+
|
|
49
|
+
// List sessions
|
|
50
|
+
let sessions = store.list_sessions().await?;
|
|
51
|
+
|
|
52
|
+
// Query recent errors
|
|
53
|
+
let errors = store.query_recent_errors(Some(10), None, None).await?;
|
|
54
|
+
|
|
55
|
+
// Get context window
|
|
56
|
+
let context = store.get_context(&session_id, ChronoDuration::hours(1)).await?;
|
|
57
|
+
|
|
58
|
+
// Persist suggestion
|
|
59
|
+
store.persist_suggestion(suggestion).await?;
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### CLI Commands
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Inspect memory storage
|
|
66
|
+
runebook memory inspect
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Memory Model
|
|
70
|
+
|
|
71
|
+
### Sessions
|
|
72
|
+
|
|
73
|
+
A session represents a terminal session with:
|
|
74
|
+
- Unique session ID
|
|
75
|
+
- Start/end timestamps
|
|
76
|
+
- Shell type (bash, zsh, nushell, etc.)
|
|
77
|
+
- Initial working directory
|
|
78
|
+
- Hostname and user (optional)
|
|
79
|
+
|
|
80
|
+
### Commands
|
|
81
|
+
|
|
82
|
+
Commands are normalized and stored with:
|
|
83
|
+
- Command name (normalized, e.g., "git" not "/usr/bin/git")
|
|
84
|
+
- Arguments array
|
|
85
|
+
- Environment summary (sanitized)
|
|
86
|
+
- Working directory
|
|
87
|
+
- Start/end timestamps
|
|
88
|
+
- Exit code and success status
|
|
89
|
+
- Duration in milliseconds
|
|
90
|
+
- Process ID (if available)
|
|
91
|
+
|
|
92
|
+
### Outputs
|
|
93
|
+
|
|
94
|
+
Output chunks are stored separately to enable:
|
|
95
|
+
- Streaming output handling
|
|
96
|
+
- Optional compression (gzip)
|
|
97
|
+
- Efficient retrieval of large outputs
|
|
98
|
+
- Chunk indexing for reconstruction
|
|
99
|
+
|
|
100
|
+
### Errors
|
|
101
|
+
|
|
102
|
+
Errors are classified by:
|
|
103
|
+
- Type (exit_code, stderr, timeout, permission, etc.)
|
|
104
|
+
- Severity (low, medium, high, critical)
|
|
105
|
+
- Message and context
|
|
106
|
+
- Associated command and session
|
|
107
|
+
|
|
108
|
+
### Insights
|
|
109
|
+
|
|
110
|
+
Insights are AI/heuristic annotations with:
|
|
111
|
+
- Type (pattern, optimization, warning, tip, correlation)
|
|
112
|
+
- Confidence score (0.0 to 1.0)
|
|
113
|
+
- Source (heuristic, ai, rule, etc.)
|
|
114
|
+
- Optional links to commands or sessions
|
|
115
|
+
|
|
116
|
+
### Suggestions
|
|
117
|
+
|
|
118
|
+
Suggestions are ranked recommendations with:
|
|
119
|
+
- Type (command, optimization, shortcut, warning, tip)
|
|
120
|
+
- Priority (low, medium, high)
|
|
121
|
+
- Rank score (higher = more relevant)
|
|
122
|
+
- Dismissed/applied status
|
|
123
|
+
|
|
124
|
+
### Provenance
|
|
125
|
+
|
|
126
|
+
Provenance tracks the source of data:
|
|
127
|
+
- Entity type and ID
|
|
128
|
+
- Source (terminal, ai, heuristic, user, etc.)
|
|
129
|
+
- Confidence score (if applicable)
|
|
130
|
+
- Model/tool name (if applicable)
|
|
131
|
+
|
|
132
|
+
## Retention Policy
|
|
133
|
+
|
|
134
|
+
By default, memory data is retained indefinitely. You can configure retention policies:
|
|
135
|
+
|
|
136
|
+
- **Max events**: Limit total number of events stored
|
|
137
|
+
- **Retention days**: Automatically delete data older than N days
|
|
138
|
+
- **Manual cleanup**: Use `wipe_all()` for testing/cleanup
|
|
139
|
+
|
|
140
|
+
### Wiping Memory
|
|
141
|
+
|
|
142
|
+
To completely wipe all memory data (useful for testing or privacy):
|
|
143
|
+
|
|
144
|
+
```rust
|
|
145
|
+
store.wipe_all().await?;
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Warning**: This permanently deletes all stored data. Use with caution.
|
|
149
|
+
|
|
150
|
+
## Encryption
|
|
151
|
+
|
|
152
|
+
The memory system provides encryption hooks for sensitive data:
|
|
153
|
+
|
|
154
|
+
- **No-op encryption**: Default (no encryption)
|
|
155
|
+
- **AES-256-GCM**: Application-level encryption (TODO)
|
|
156
|
+
- **PluresDB native**: If PluresDB supports encryption (TODO)
|
|
157
|
+
|
|
158
|
+
Encryption is optional and can be configured per deployment.
|
|
159
|
+
|
|
160
|
+
## Migration and Versioning
|
|
161
|
+
|
|
162
|
+
The schema includes a migration system for schema evolution:
|
|
163
|
+
|
|
164
|
+
- Current schema version: 1
|
|
165
|
+
- Automatic migration on initialization
|
|
166
|
+
- Version tracking in PluresDB
|
|
167
|
+
|
|
168
|
+
To add a new migration:
|
|
169
|
+
|
|
170
|
+
1. Increment `CURRENT_SCHEMA_VERSION` in `migration.rs`
|
|
171
|
+
2. Add migration logic in `migrate_to_version()`
|
|
172
|
+
3. Test migration with existing data
|
|
173
|
+
|
|
174
|
+
## Performance Considerations
|
|
175
|
+
|
|
176
|
+
- **Streaming output**: Outputs are chunked to handle large streams
|
|
177
|
+
- **Compression**: Optional gzip compression for outputs
|
|
178
|
+
- **Indexing**: Key prefixes enable efficient queries
|
|
179
|
+
- **Async operations**: All operations are async for non-blocking I/O
|
|
180
|
+
|
|
181
|
+
## Testing
|
|
182
|
+
|
|
183
|
+
### Integration Tests
|
|
184
|
+
|
|
185
|
+
Tests require a running PluresDB server:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# Start PluresDB server
|
|
189
|
+
pluresdb --port 34567 --data-dir ./test-pluresdb-data
|
|
190
|
+
|
|
191
|
+
# Run tests
|
|
192
|
+
cargo test --package runebook
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Property Tests
|
|
196
|
+
|
|
197
|
+
Schema roundtrip tests verify data integrity:
|
|
198
|
+
|
|
199
|
+
- Session roundtrip
|
|
200
|
+
- Command roundtrip
|
|
201
|
+
- Suggestion roundtrip
|
|
202
|
+
|
|
203
|
+
## Configuration
|
|
204
|
+
|
|
205
|
+
### PluresDB Connection
|
|
206
|
+
|
|
207
|
+
Default configuration:
|
|
208
|
+
- Host: `localhost`
|
|
209
|
+
- Port: `34567`
|
|
210
|
+
- Data directory: `./pluresdb-data`
|
|
211
|
+
|
|
212
|
+
### Environment Variables
|
|
213
|
+
|
|
214
|
+
- `PLURESDB_HOST`: Override host
|
|
215
|
+
- `PLURESDB_PORT`: Override port
|
|
216
|
+
- `PLURESDB_DATA_DIR`: Override data directory
|
|
217
|
+
|
|
218
|
+
## Troubleshooting
|
|
219
|
+
|
|
220
|
+
### PluresDB Not Available
|
|
221
|
+
|
|
222
|
+
If you see "PluresDB server not available":
|
|
223
|
+
|
|
224
|
+
1. Check if PluresDB is running: `curl http://localhost:34567/health`
|
|
225
|
+
2. Start PluresDB: `pluresdb --port 34567`
|
|
226
|
+
3. Check firewall/network settings
|
|
227
|
+
|
|
228
|
+
### Migration Errors
|
|
229
|
+
|
|
230
|
+
If migrations fail:
|
|
231
|
+
|
|
232
|
+
1. Check PluresDB logs
|
|
233
|
+
2. Verify schema version: `memory:schema:version` key
|
|
234
|
+
3. Manually run migrations if needed
|
|
235
|
+
|
|
236
|
+
### Performance Issues
|
|
237
|
+
|
|
238
|
+
For large datasets:
|
|
239
|
+
|
|
240
|
+
1. Enable output compression
|
|
241
|
+
2. Implement retention policies
|
|
242
|
+
3. Consider archiving old data
|
|
243
|
+
|
|
244
|
+
## Future Enhancements
|
|
245
|
+
|
|
246
|
+
- [ ] Full encryption implementation (AES-256-GCM)
|
|
247
|
+
- [ ] PluresDB native encryption integration
|
|
248
|
+
- [ ] Advanced querying (time ranges, filters)
|
|
249
|
+
- [ ] Data export/import
|
|
250
|
+
- [ ] Backup and restore
|
|
251
|
+
- [ ] Cross-session pattern analysis
|
|
252
|
+
- [ ] Real-time event streaming
|
|
253
|
+
|
package/NIXOS.md
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
# NixOS Support for RuneBook
|
|
2
|
+
|
|
3
|
+
RuneBook is fully integrated with NixOS and Nix Flakes for reproducible builds and development.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### Development Environment
|
|
8
|
+
|
|
9
|
+
Enter the development shell:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
nix develop
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This provides:
|
|
16
|
+
- Node.js 20
|
|
17
|
+
- Rust toolchain (stable, with rustfmt and clippy)
|
|
18
|
+
- Tauri CLI
|
|
19
|
+
- All system dependencies (webkitgtk, librsvg, etc.)
|
|
20
|
+
- TypeScript, Vitest, and other dev tools
|
|
21
|
+
|
|
22
|
+
### Building Packages
|
|
23
|
+
|
|
24
|
+
Build the Tauri application:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
nix build .#runebook
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Build the headless agent CLI:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
nix build .#runebook-agent
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Running Applications
|
|
37
|
+
|
|
38
|
+
Run the Tauri app:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
nix run .#runebook
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Run the agent CLI:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
nix run .#runebook-agent -- agent status
|
|
48
|
+
nix run .#runebook-agent -- observer enable
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Package Outputs
|
|
52
|
+
|
|
53
|
+
The flake provides the following outputs:
|
|
54
|
+
|
|
55
|
+
- `packages.runebook` - The Tauri desktop application
|
|
56
|
+
- `packages.runebook-agent` - Headless CLI agent wrapper
|
|
57
|
+
- `devShells.default` - Development environment with all tools
|
|
58
|
+
- `apps.runebook` - App launcher for the Tauri app
|
|
59
|
+
- `apps.runebook-agent` - App launcher for the agent CLI
|
|
60
|
+
- `nixosModules.default` - NixOS module for systemd service
|
|
61
|
+
|
|
62
|
+
View all outputs:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
nix flake show
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## NixOS Module
|
|
69
|
+
|
|
70
|
+
The flake includes a NixOS module for running `runebook-agent` as a systemd user service.
|
|
71
|
+
|
|
72
|
+
### Basic Configuration
|
|
73
|
+
|
|
74
|
+
Add to your `configuration.nix`:
|
|
75
|
+
|
|
76
|
+
```nix
|
|
77
|
+
{
|
|
78
|
+
imports = [
|
|
79
|
+
/path/to/runebook/nixos-module.nix
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
services.runebook-agent = {
|
|
83
|
+
enable = true;
|
|
84
|
+
captureEvents = true;
|
|
85
|
+
analyzePatterns = true;
|
|
86
|
+
suggestImprovements = true;
|
|
87
|
+
dataDir = "/var/lib/runebook-agent/data";
|
|
88
|
+
maxEvents = 10000;
|
|
89
|
+
retentionDays = 30;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Using the Flake Module
|
|
95
|
+
|
|
96
|
+
If using flakes in your NixOS configuration:
|
|
97
|
+
|
|
98
|
+
```nix
|
|
99
|
+
{
|
|
100
|
+
inputs.runebook.url = "github:plures/runebook";
|
|
101
|
+
|
|
102
|
+
outputs = { self, nixpkgs, runebook }: {
|
|
103
|
+
nixosConfigurations.your-host = nixpkgs.lib.nixosSystem {
|
|
104
|
+
modules = [
|
|
105
|
+
runebook.nixosModules.default
|
|
106
|
+
{
|
|
107
|
+
services.runebook-agent = {
|
|
108
|
+
enable = true;
|
|
109
|
+
captureEvents = true;
|
|
110
|
+
# ... other options
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
];
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Configuration Options
|
|
120
|
+
|
|
121
|
+
- `enable` - Enable the runebook-agent service (default: `false`)
|
|
122
|
+
- `captureEvents` - Enable event capture (default: `true`)
|
|
123
|
+
- `analyzePatterns` - Enable pattern analysis (default: `true`)
|
|
124
|
+
- `suggestImprovements` - Enable suggestion generation (default: `true`)
|
|
125
|
+
- `dataDir` - Data directory for agent storage (default: `/var/lib/runebook-agent/data`)
|
|
126
|
+
- `maxEvents` - Maximum number of events to store (default: `10000`)
|
|
127
|
+
- `retentionDays` - Number of days to retain events (default: `30`)
|
|
128
|
+
- `openaiApiKey` - OpenAI API key (default: `null`)
|
|
129
|
+
|
|
130
|
+
**⚠️ Security Warning**: Setting `openaiApiKey` in the NixOS configuration will store it in the Nix store. Prefer using environment variables, agenix, or sops-nix instead.
|
|
131
|
+
|
|
132
|
+
### Secure Secret Management
|
|
133
|
+
|
|
134
|
+
#### Using Environment Variables
|
|
135
|
+
|
|
136
|
+
Set secrets via systemd environment files:
|
|
137
|
+
|
|
138
|
+
```nix
|
|
139
|
+
{
|
|
140
|
+
services.runebook-agent = {
|
|
141
|
+
enable = true;
|
|
142
|
+
# Don't set openaiApiKey here
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
systemd.user.services.runebook-agent = {
|
|
146
|
+
serviceConfig.EnvironmentFile = "/etc/runebook/secrets.env";
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Create `/etc/runebook/secrets.env`:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
OPENAI_API_KEY=sk-...
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### Using agenix
|
|
158
|
+
|
|
159
|
+
If using [agenix](https://github.com/ryantm/agenix):
|
|
160
|
+
|
|
161
|
+
```nix
|
|
162
|
+
{
|
|
163
|
+
age.secrets.runebook-openai = {
|
|
164
|
+
file = ./secrets/runebook-openai.age;
|
|
165
|
+
owner = "your-user";
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
systemd.user.services.runebook-agent = {
|
|
169
|
+
serviceConfig.EnvironmentFile = config.age.secrets.runebook-openai.path;
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### Using sops-nix
|
|
175
|
+
|
|
176
|
+
If using [sops-nix](https://github.com/Mic92/sops-nix):
|
|
177
|
+
|
|
178
|
+
```nix
|
|
179
|
+
{
|
|
180
|
+
sops.secrets."runebook/openai_key" = {
|
|
181
|
+
owner = "your-user";
|
|
182
|
+
path = "/run/secrets/runebook-openai";
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
systemd.user.services.runebook-agent = {
|
|
186
|
+
serviceConfig.EnvironmentFile = config.sops.secrets."runebook/openai_key".path;
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Disabling the Service
|
|
192
|
+
|
|
193
|
+
To disable the service:
|
|
194
|
+
|
|
195
|
+
```nix
|
|
196
|
+
{
|
|
197
|
+
services.runebook-agent.enable = false;
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Or remove the service configuration entirely.
|
|
202
|
+
|
|
203
|
+
### Manual Service Management
|
|
204
|
+
|
|
205
|
+
If the service is enabled, manage it with systemd:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# Check status
|
|
209
|
+
systemctl --user status runebook-agent
|
|
210
|
+
|
|
211
|
+
# Start service
|
|
212
|
+
systemctl --user start runebook-agent
|
|
213
|
+
|
|
214
|
+
# Stop service
|
|
215
|
+
systemctl --user stop runebook-agent
|
|
216
|
+
|
|
217
|
+
# View logs
|
|
218
|
+
journalctl --user -u runebook-agent -f
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## CI/CD
|
|
222
|
+
|
|
223
|
+
The project includes GitHub Actions workflows that:
|
|
224
|
+
|
|
225
|
+
- Run `nix flake check` to validate the flake
|
|
226
|
+
- Build packages on multiple platforms
|
|
227
|
+
- Run tests (Rust and TypeScript)
|
|
228
|
+
- Check formatting (rustfmt, TypeScript)
|
|
229
|
+
|
|
230
|
+
See `.github/workflows/ci.yml` for details.
|
|
231
|
+
|
|
232
|
+
## Reproducible Builds
|
|
233
|
+
|
|
234
|
+
All dependencies are pinned via Nix, ensuring reproducible builds:
|
|
235
|
+
|
|
236
|
+
- Rust toolchain version is fixed
|
|
237
|
+
- Node.js version is fixed
|
|
238
|
+
- System libraries are pinned to nixpkgs versions
|
|
239
|
+
|
|
240
|
+
To update dependencies, update the `nixpkgs` input in `flake.nix`:
|
|
241
|
+
|
|
242
|
+
```nix
|
|
243
|
+
{
|
|
244
|
+
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; # or a specific commit
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Then update the lock file:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
nix flake update
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Troubleshooting
|
|
255
|
+
|
|
256
|
+
### Build Failures
|
|
257
|
+
|
|
258
|
+
If builds fail, check:
|
|
259
|
+
|
|
260
|
+
1. **Nix version**: Ensure you're using Nix 2.4+ with flakes enabled
|
|
261
|
+
2. **System dependencies**: The flake should handle these automatically
|
|
262
|
+
3. **Network access**: First build requires downloading dependencies
|
|
263
|
+
|
|
264
|
+
### Service Not Starting
|
|
265
|
+
|
|
266
|
+
If the systemd service fails to start:
|
|
267
|
+
|
|
268
|
+
1. Check logs: `journalctl --user -u runebook-agent -n 50`
|
|
269
|
+
2. Verify data directory permissions: `ls -la /var/lib/runebook-agent`
|
|
270
|
+
3. Check configuration: `cat /var/lib/runebook-agent/agent-config.json`
|
|
271
|
+
|
|
272
|
+
### Missing Dependencies
|
|
273
|
+
|
|
274
|
+
If you encounter missing dependencies:
|
|
275
|
+
|
|
276
|
+
1. Enter the dev shell: `nix develop`
|
|
277
|
+
2. All dependencies should be available automatically
|
|
278
|
+
3. If not, check `flake.nix` and add missing packages to `devShells.default.buildInputs`
|
|
279
|
+
|
|
280
|
+
## Development
|
|
281
|
+
|
|
282
|
+
### Adding New Dependencies
|
|
283
|
+
|
|
284
|
+
**Rust dependencies**: Add to `src-tauri/Cargo.toml` as usual.
|
|
285
|
+
|
|
286
|
+
**Node.js dependencies**: Add to `package.json` as usual, then update the `npmDepsHash` in `flake.nix`:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
# After adding dependencies, get the new hash:
|
|
290
|
+
nix build .#runebook-frontend 2>&1 | grep "got:" | head -1
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Or manually calculate:
|
|
294
|
+
```bash
|
|
295
|
+
nix-prefetch-url --unpack --type sha256 $(nix eval --raw .#runebook-frontend.src 2>/dev/null || echo "file://$(pwd)")
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**System dependencies**: Add to `nativeBuildInputs` or `buildInputs` in `flake.nix`.
|
|
299
|
+
|
|
300
|
+
**Note**: The initial `npmDepsHash` in `flake.nix` is set to a placeholder. After the first successful build, Nix will provide the correct hash. You can then update it in the flake for faster subsequent builds.
|
|
301
|
+
|
|
302
|
+
### Pre-commit Hooks (Optional)
|
|
303
|
+
|
|
304
|
+
The dev shell includes `pre-commit` for optional git hooks. To enable:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
nix develop
|
|
308
|
+
pre-commit install
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## Examples
|
|
312
|
+
|
|
313
|
+
### Minimal NixOS Configuration
|
|
314
|
+
|
|
315
|
+
```nix
|
|
316
|
+
{
|
|
317
|
+
imports = [ ./nixos-module.nix ];
|
|
318
|
+
|
|
319
|
+
services.runebook-agent.enable = true;
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Full NixOS Configuration with Secrets
|
|
324
|
+
|
|
325
|
+
```nix
|
|
326
|
+
{
|
|
327
|
+
imports = [ ./nixos-module.nix ];
|
|
328
|
+
|
|
329
|
+
services.runebook-agent = {
|
|
330
|
+
enable = true;
|
|
331
|
+
captureEvents = true;
|
|
332
|
+
analyzePatterns = true;
|
|
333
|
+
suggestImprovements = true;
|
|
334
|
+
dataDir = "/home/user/.local/share/runebook";
|
|
335
|
+
maxEvents = 50000;
|
|
336
|
+
retentionDays = 90;
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
# Use agenix for secrets
|
|
340
|
+
age.secrets.runebook-openai = {
|
|
341
|
+
file = ./secrets/openai.age;
|
|
342
|
+
owner = "user";
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
systemd.user.services.runebook-agent = {
|
|
346
|
+
serviceConfig.EnvironmentFile = config.age.secrets.runebook-openai.path;
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
## Further Reading
|
|
352
|
+
|
|
353
|
+
- [Nix Flakes Documentation](https://nixos.wiki/wiki/Flakes)
|
|
354
|
+
- [NixOS Modules](https://nixos.wiki/wiki/NixOS_modules)
|
|
355
|
+
- [Tauri Prerequisites](https://tauri.app/guides/prerequisites/)
|
|
356
|
+
- [RuneBook Architecture](./ARCHITECTURE.md)
|
|
357
|
+
|