@rizom/ops 0.2.0-alpha.7 → 0.2.0-alpha.700

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.
Files changed (85) hide show
  1. package/README.md +89 -4
  2. package/dist/age-key-bootstrap.d.ts +17 -0
  3. package/dist/brains-ops.js +763 -177
  4. package/dist/capability-bundle-migration.d.ts +26 -0
  5. package/dist/cert-bootstrap.d.ts +6 -4
  6. package/dist/content-repo-ref.d.ts +10 -0
  7. package/dist/content-repo.d.ts +13 -0
  8. package/dist/default-user-runner.d.ts +1 -1
  9. package/dist/deploy.js +110 -166
  10. package/dist/directory-sync-stress-system.d.ts +75 -0
  11. package/dist/directory-sync-stress.d.ts +117 -0
  12. package/dist/entries/deploy.d.ts +4 -2
  13. package/dist/health-watchdog-smoke.d.ts +54 -0
  14. package/dist/image-inventory.d.ts +4 -0
  15. package/dist/image-types.d.ts +7 -0
  16. package/dist/images.d.ts +89 -0
  17. package/dist/index.d.ts +11 -0
  18. package/dist/index.js +775 -177
  19. package/dist/legacy-pilot-migration.d.ts +11 -0
  20. package/dist/legacy-projection-job-recovery.d.ts +29 -0
  21. package/dist/load-registry.d.ts +92 -8
  22. package/dist/observed-status.d.ts +1 -1
  23. package/dist/onboard-user.d.ts +2 -2
  24. package/dist/parse-args.d.ts +2 -10
  25. package/dist/preview-domain.d.ts +9 -0
  26. package/dist/provider-key-migration.d.ts +20 -0
  27. package/dist/reconcile-all.d.ts +2 -2
  28. package/dist/reconcile-cohort.d.ts +2 -2
  29. package/dist/reconcile-dry-run.d.ts +9 -0
  30. package/dist/reconcile-lib.d.ts +4 -2
  31. package/dist/run-command.d.ts +22 -6
  32. package/dist/runtime-image-lock.d.ts +12 -0
  33. package/dist/schema.d.ts +145 -71
  34. package/dist/secrets-encrypt.d.ts +27 -0
  35. package/dist/secrets-push.d.ts +2 -2
  36. package/dist/ssh-key-bootstrap.d.ts +1 -26
  37. package/dist/stage-legacy-crossover.d.ts +25 -0
  38. package/dist/stress-command.d.ts +14 -0
  39. package/dist/stress-git-checkout.d.ts +21 -0
  40. package/dist/stress-health-monitor.d.ts +56 -0
  41. package/dist/upgrade.d.ts +10 -0
  42. package/dist/user-add.d.ts +16 -0
  43. package/dist/user-offboard.d.ts +61 -0
  44. package/dist/user-runner.d.ts +5 -0
  45. package/dist/verify-user.d.ts +22 -0
  46. package/package.json +51 -40
  47. package/templates/rover-pilot/.env.schema +38 -4
  48. package/templates/rover-pilot/.github/actions/varlock-env/action.yml +47 -0
  49. package/templates/rover-pilot/.github/workflows/build.yml +71 -17
  50. package/templates/rover-pilot/.github/workflows/deploy.yml +127 -49
  51. package/templates/rover-pilot/.github/workflows/directory-sync-stress.yml +119 -0
  52. package/templates/rover-pilot/.github/workflows/health-watchdog-smoke.yml +95 -0
  53. package/templates/rover-pilot/.github/workflows/offboard.yml +107 -0
  54. package/templates/rover-pilot/.github/workflows/reconcile.yml +23 -3
  55. package/templates/rover-pilot/.github/workflows/upgrade.yml +104 -0
  56. package/templates/rover-pilot/README.md +19 -8
  57. package/templates/rover-pilot/deploy/scripts/create-predeploy-backup.ts +962 -0
  58. package/templates/rover-pilot/deploy/scripts/decrypt-user-secrets.ts +139 -0
  59. package/templates/rover-pilot/deploy/scripts/helpers.ts +3 -0
  60. package/templates/rover-pilot/deploy/scripts/install-health-watchdog.ts +144 -0
  61. package/templates/rover-pilot/deploy/scripts/provision-server.ts +52 -22
  62. package/templates/rover-pilot/deploy/scripts/pull-local-models.ts +69 -0
  63. package/templates/rover-pilot/deploy/scripts/resolve-deploy-handles.ts +19 -4
  64. package/templates/rover-pilot/deploy/scripts/resolve-missing-images.ts +13 -0
  65. package/templates/rover-pilot/deploy/scripts/resolve-user-config.ts +71 -14
  66. package/templates/rover-pilot/deploy/scripts/sync-content-repo.ts +183 -0
  67. package/templates/rover-pilot/deploy/scripts/update-dns.ts +72 -16
  68. package/templates/rover-pilot/deploy/scripts/validate-secrets.ts +12 -1
  69. package/templates/rover-pilot/deploy/scripts/verify-runtime-image.ts +18 -0
  70. package/templates/rover-pilot/docs/canonical-crossover-record.md +107 -0
  71. package/templates/rover-pilot/docs/onboarding-checklist.md +39 -14
  72. package/templates/rover-pilot/docs/operator-playbook.md +421 -22
  73. package/templates/rover-pilot/docs/user-onboarding.md +49 -271
  74. package/templates/rover-pilot/package.json +4 -0
  75. package/templates/rover-pilot/pilot.yaml +10 -4
  76. package/templates/rover-pilot/users/alice.yaml +5 -1
  77. package/dist/origin-ca.d.ts +0 -1
  78. package/dist/push-secrets.d.ts +0 -9
  79. package/dist/push-target.d.ts +0 -2
  80. package/dist/run-subprocess.d.ts +0 -5
  81. package/dist/user-secret-names.d.ts +0 -6
  82. package/templates/rover-pilot/.kamal/hooks/pre-deploy +0 -9
  83. package/templates/rover-pilot/deploy/Caddyfile +0 -66
  84. package/templates/rover-pilot/deploy/Dockerfile +0 -38
  85. package/templates/rover-pilot/deploy/kamal/deploy.yml +0 -39
@@ -1,312 +1,90 @@
1
- # Rover Pilot User Onboarding
1
+ # Welcome to your brain
2
2
 
3
- Welcome to the Rover pilot.
3
+ ---
4
4
 
5
- This document is written for **first-time users**. You do **not** need prior experience with Rover, MCP, git, or the rest of the system to get started.
5
+ Most of us have more thinking happening than we can hold onto. Ideas show up in the wrong moment, notes land in five different places, and half of what you've figured out is effectively invisible by the time you need it again.
6
6
 
7
- ## What Rover is
7
+ Your brain is a private space where that thinking accumulates — notes, links, fragments, and half-formed ideas — plus an AI that can work with all of it. It can find things you saved months ago, connect topics, or help turn a rough note into a draft. The more useful material you add, the more useful it becomes.
8
8
 
9
- Rover is your private AI assistant for working with your own notes, links, and ideas.
9
+ ---
10
10
 
11
- In this pilot, Rover is intentionally simple:
11
+ ## What it is
12
12
 
13
- - you talk to it through an **MCP client**
14
- - **there is no website to browse**
15
- - Discord is optional
16
- - Obsidian fits through the git-sync/content-repo workflow, not as the main chat interface
13
+ Your brain is a private knowledge companion. It holds your notes, links, and ideas and helps you think with them, not just store them.
17
14
 
18
- You can think of Rover as a private knowledge companion that helps you:
15
+ Ask a question and it searches what you've saved. Give it a fragment of thinking and it can help develop it.
19
16
 
20
- - save notes
21
- - save links
22
- - reflect on your own material
23
- - find patterns in what you have collected
24
- - think through questions with AI
17
+ ## Getting in
25
18
 
26
- ## What you will receive from us
19
+ We'll send you a personal URL such as `https://<handle>.rizom.ai/`.
27
20
 
28
- We will send you the details you need to connect.
21
+ The first time you open it, you will be asked to set a passkey. No password is required after that.
29
22
 
30
- That usually includes:
23
+ Your main interfaces are:
31
24
 
32
- - your Rover URL: `https://<handle>.rizom.ai/mcp`
33
- - your **Bearer token**
34
- - confirmation of whether Discord is enabled for you
35
- - any extra instructions if we are testing a specific workflow with your cohort
25
+ - **Chat** (`/chat`) — talk to your brain;
26
+ - **Dashboard/site** (`/`) — the configured browser surface;
27
+ - **Studio** (`/studio`) — edit durable content in a browser.
36
28
 
37
- Treat the **Bearer token** like a password. Do not share it.
29
+ Start with Chat.
38
30
 
39
- ## One important idea: MCP is just the connection method
31
+ ## Your first five minutes
40
32
 
41
- If you have never used MCP before, the shortest explanation is:
33
+ 1. Open Chat and say: _Help me save my first note._
34
+ 2. Save a thought, link, or idea. It does not need to be polished.
35
+ 3. Ask about it and inspect what comes back.
42
36
 
43
- - **Rover** is the assistant
44
- - **MCP** is the way your AI client connects to Rover
37
+ That save–ask–use loop is the core workflow.
45
38
 
46
- You do not need to understand the protocol details.
39
+ ## Chat or Studio?
47
40
 
48
- For the pilot, the practical meaning is simple:
41
+ **Chat** is for thinking aloud, asking questions, saving things quickly, and day-to-day work.
49
42
 
50
- - open a supported client
51
- - add your Rover URL
52
- - paste your Bearer token
53
- - start talking to Rover
43
+ **Studio** is for deliberate browsing and editing. It becomes more useful as your content grows.
54
44
 
55
- ## What to use first
45
+ ## Other interfaces and peer brains
56
46
 
57
- For most users, the easiest first setup is:
47
+ Chat is primary. Your configured posture may also enable Discord, Slack, MCP clients, or agent-to-agent calls. We will send setup steps for integrations enabled for your instance.
58
48
 
59
- - **Claude Desktop** for talking to Rover
60
- - **Obsidian** only if you also want to work directly with markdown files later
61
- - **Discord** only if we explicitly enable it for you
49
+ With permission, you can save another participant's brain as a contact and call it by its shared address:
62
50
 
63
- ## How to connect
51
+ - _Add jane.rizom.ai to my contacts._
52
+ - _Call jane.rizom.ai and ask [your question]._
64
53
 
65
- Use an MCP client that supports:
54
+ ## Connecting other tools
66
55
 
67
- - **HTTP / Streamable HTTP MCP**
68
- - **Bearer token authentication**
56
+ MCP is a standard protocol that lets compatible AI clients use your brain's tools and lets configured integrations connect to external services. If MCP is part of your setup, we will send specific instructions alongside your URL.
69
57
 
70
- When your client asks for connection details, use:
58
+ ## Common questions
71
59
 
72
- - **Server URL:** `https://<handle>.rizom.ai/mcp`
73
- - **Authentication type:** Bearer token
74
- - **Bearer token:** the token we sent you
60
+ **How do I access my data?**
75
61
 
76
- If the client asks for a name, use something simple like:
62
+ Use the Studio. If your cohort includes GitHub access, the same durable markdown also lives in a private repository.
77
63
 
78
- - `Rover (<handle>)`
64
+ **Does it search the public internet?**
79
65
 
80
- ## Claude Desktop setup
66
+ Not by default. Answers are grounded in your own knowledge unless an explicitly configured integration provides another source.
81
67
 
82
- If your Claude Desktop version supports connecting to a **remote HTTP / Streamable HTTP MCP server**, enter:
68
+ **What does this cost?**
83
69
 
84
- - **Server URL:** `https://<handle>.rizom.ai/mcp`
85
- - **Authentication:** Bearer token
86
- - **Token:** the token we sent you
70
+ Nothing during the pilot; hosting is covered by the programme.
87
71
 
88
- Then try a first message like:
72
+ ## This is a pilot
89
73
 
90
- > What can you help me do, and what should I use you for?
74
+ The product works, but it is not finished. You will encounter rough edges and missing behavior. If something breaks or falls short, tell us what you tried, what you expected, and what happened.
91
75
 
92
- Or:
76
+ A built-in wishlist can record unsupported requests as product feedback.
93
77
 
94
- > Help me save my first note.
78
+ ## Your access details
95
79
 
96
- If your Claude Desktop version only supports local MCP servers and not remote HTTP MCP cleanly, tell us what version you are using and we will help you.
97
-
98
- ## Your first 5 minutes
99
-
100
- Once you are connected, try this sequence:
101
-
102
- ### 1. Check that Rover responds
103
-
104
- Ask:
105
-
106
- > What can you help me do?
107
-
108
- ### 2. Save a first note
109
-
110
- Ask:
111
-
112
- > Save a note: I want to use Rover to collect ideas from my work, reading, and conversations.
113
-
114
- ### 3. Save a useful link
115
-
116
- Ask:
117
-
118
- > Save this link and note why it matters to me: <paste URL>
119
-
120
- ### 4. Ask Rover to reflect back what it knows
121
-
122
- Ask:
123
-
124
- > Based on what I’ve stored so far, what themes are starting to emerge?
125
-
126
- ### 5. Use it as a thinking partner
127
-
128
- Ask:
129
-
130
- > I am thinking through a problem in my work. Help me structure the question and identify what context is missing.
131
-
132
- ## Wishlist: when Rover cannot do something yet
133
-
134
- Rover has a built-in **wishlist**.
135
-
136
- This is important for first-time users because Rover will not be able to do everything yet.
137
-
138
- If you ask for something Rover cannot do, it should add that request to the wishlist instead of just failing silently.
139
-
140
- You can think of the wishlist as:
141
-
142
- - a backlog of missing capabilities
143
- - a record of things users want Rover to do
144
- - a way for the pilot team to see which missing features matter most
145
-
146
- ### When the wishlist is useful
147
-
148
- The wishlist is especially useful when you ask Rover to do something like:
149
-
150
- - connect to a tool it does not support yet
151
- - perform an action it cannot perform yet
152
- - add a workflow or feature that does not exist yet
153
-
154
- Examples:
155
-
156
- > I want Rover to draft and send emails for me.
157
-
158
- > I want Rover to connect to my calendar.
159
-
160
- > I want Rover to summarize voice notes automatically.
161
-
162
- If Rover cannot actually do those things yet, it should tell you that and add the request to the wishlist.
163
-
164
- ### What happens when something is added to the wishlist
165
-
166
- When a request is added to the wishlist:
167
-
168
- - it is saved as a **wish**
169
- - it starts in a **new** state
170
- - similar requests can be grouped together instead of creating endless duplicates
171
- - repeated demand can increase the count of how many times that wish was requested
172
-
173
- That helps us see which gaps are one-off ideas and which ones keep coming up across real usage.
174
-
175
- ### How you should use it
176
-
177
- You do **not** need special commands.
178
-
179
- Just ask naturally.
180
-
181
- If Rover cannot do what you asked, a good response from Rover is something like:
182
-
183
- - it explains the limitation clearly
184
- - it says the request was added to the wishlist
185
-
186
- If that does **not** happen, that is useful feedback for us too.
187
-
188
- ## Obsidian
189
-
190
- Obsidian is part of the pilot through the **git-synced content repo workflow**, not through MCP.
191
-
192
- That means:
193
-
194
- - use **Claude Desktop** as the main way to talk to Rover
195
- - use **Obsidian** if you want to browse, draft, and edit markdown files directly
196
- - Rover can pick up those file changes through the normal git-sync / directory-sync flow
197
-
198
- A simple mental model:
199
-
200
- - **Claude Desktop** = talk to Rover
201
- - **Obsidian** = edit the underlying notes
202
-
203
- If we have already shared your content repo workflow with you, the simplest setup is:
204
-
205
- 1. clone your Rover content repo locally
206
- 2. open that folder as an Obsidian vault
207
- 3. optionally install the **Obsidian Git** plugin if you want in-app commit/push/pull support
208
- 4. edit or organize your markdown notes there
209
- 5. commit and push your changes through normal git or the Obsidian Git plugin
210
- 6. let the normal git-sync flow carry those changes into Rover
211
-
212
- If we have **not** given you a direct content repo workflow yet, that is fine. You can ignore Obsidian for now and use Rover purely through MCP.
213
-
214
- ## Discord (optional)
215
-
216
- Discord is optional in this pilot.
217
-
218
- If it is enabled for you, think of it as a lightweight secondary interface for:
219
-
220
- - quick note capture
221
- - dropping in links to save
222
- - short questions when you do not want to open Claude Desktop
223
-
224
- Important:
225
-
226
- - **MCP remains the main interface**
227
- - Discord is **off by default**
228
- - if you want Discord, tell us explicitly
229
- - for this pilot, Discord-enabled users may need to supply their own bot token
230
- - if Discord is enabled, we will send the exact invite/setup steps separately
231
-
232
- If Discord is **not** enabled for you, that is completely normal.
233
-
234
- ## What to expect in the pilot
235
-
236
- This is a real working system, but it is still an early pilot.
237
-
238
- So you should expect:
239
-
240
- - some rough edges
241
- - a setup process that may still be a bit manual
242
- - a Rover that becomes more useful as you add more notes and links
243
- - occasional follow-up questions from us about your experience
244
- - improvements and changes during the pilot
245
-
246
- That is normal. The point of the pilot is to learn from real use.
247
-
248
- ## Privacy and boundaries
249
-
250
- For the pilot:
251
-
252
- - your Rover is deployed specifically for you
253
- - access to `/mcp` is protected by your Bearer token
254
- - you should avoid putting highly sensitive material into the pilot unless we have explicitly agreed that it is in scope
255
-
256
- If you are unsure whether something belongs in Rover, ask us first.
257
-
258
- ## Troubleshooting
259
-
260
- ### I opened the domain and it does not look like a normal site
261
-
262
- That is expected. In this pilot, **there is no website to browse**. Rover core is MCP-first.
263
-
264
- ### I got an authentication error
265
-
266
- Usually this means one of three things:
267
-
268
- - the Bearer token was missing
269
- - the Bearer token was pasted incorrectly
270
- - the client is using the wrong authentication type
271
-
272
- Double-check that you are using:
273
-
274
- - URL: `https://<handle>.rizom.ai/mcp`
275
- - auth type: **Bearer token**
276
- - token: exactly the token we sent you
277
-
278
- ### My MCP client says it cannot connect
279
-
280
- Some clients support local MCP servers better than remote HTTP MCP servers.
281
-
282
- If that happens, send us:
283
-
284
- - the name of the client
285
- - the version you are using
286
- - the exact error message
287
- - a screenshot if possible
288
-
289
- ## What feedback helps us most
290
-
291
- We especially want to hear:
292
-
293
- - what was confusing during setup
294
- - what felt useful immediately
295
- - what felt weak, awkward, or unclear
296
- - what you expected Rover to do but could not get it to do
297
- - whether you would keep using it after the pilot
298
-
299
- Short, honest feedback is perfect.
300
-
301
- ## Quick handoff template
302
-
303
- When we onboard you, the message will look roughly like this:
80
+ We will send details in this shape:
304
81
 
305
82
  ```text
306
- Rover URL: https://<handle>.rizom.ai/mcp
307
- Auth type: Bearer token
308
- Bearer token: <token>
309
- Discord enabled: yes/no
83
+ Chat URL: https://<handle>.rizom.ai/chat
84
+ Dashboard URL: https://<handle>.rizom.ai/
85
+ Studio URL: https://<handle>.rizom.ai/studio
86
+ Discord: yes/no — setup steps if enabled
87
+ MCP: enabled/not enabled — setup details if enabled
310
88
  ```
311
89
 
312
- If anything is unclear, reply with the exact error text or a screenshot and we will help.
90
+ If anything is unclear, reply with what you see and we will help.
@@ -3,7 +3,11 @@
3
3
  "private": true,
4
4
  "type": "module",
5
5
  "packageManager": "bun@__BUN_VERSION__",
6
+ "dependencies": {
7
+ "age-encryption": "^0.3.0"
8
+ },
6
9
  "devDependencies": {
10
+ "@brains/utils": "workspace:*",
7
11
  "@rizom/ops": "__BRAINS_OPS_VERSION__"
8
12
  }
9
13
  }
@@ -1,8 +1,14 @@
1
- schemaVersion: 1
2
1
  brainVersion: 0.1.1-alpha.14
3
- model: rover
2
+ bundleContract: capability-bundles-v1
4
3
  githubOrg: <github-org>
5
4
  contentRepoPrefix: rover-
6
5
  domainSuffix: .rizom.ai
7
- preset: core
8
- aiApiKey: AI_API_KEY
6
+ bundles:
7
+ - core
8
+ - media
9
+ - web
10
+ - chat
11
+ openaiApiKey: OPENAI_API_KEY
12
+ gitSyncToken: GIT_SYNC_TOKEN
13
+ contentRepoAdminToken: CONTENT_REPO_ADMIN_TOKEN
14
+ agePublicKey: age1replace-with-your-public-key
@@ -1,3 +1,7 @@
1
1
  handle: alice
2
+ anchorProfile:
3
+ name: Alice Example
4
+ description: Replace this with Alice's real public profile summary.
2
5
  discord:
3
- enabled: false
6
+ enabled: true
7
+ # anchorUserId: "123456789012345678"
@@ -1 +0,0 @@
1
- export { createOriginCertificateRequest, generateOriginKeyPair, issueCloudflareOriginCertificate, setCloudflareZoneSslStrict, type CloudflareOriginCaResult, type FetchLike, type OriginCertificateRequest, type OriginKeyPair, } from "@brains/utils/origin-ca";
@@ -1,9 +0,0 @@
1
- import { normalizePushTarget, type PushTarget } from "./push-target";
2
- import { type RunCommand } from "./run-subprocess";
3
- export type SecretPair = readonly [name: string, value: string];
4
- export interface PushSecretsOptions {
5
- runCommand?: RunCommand | undefined;
6
- logger?: ((message: string) => void) | undefined;
7
- }
8
- export declare function pushSecretsToBackend(target: PushTarget, secrets: readonly SecretPair[], options?: PushSecretsOptions): Promise<void>;
9
- export { normalizePushTarget };
@@ -1,2 +0,0 @@
1
- export type PushTarget = "gh";
2
- export declare function normalizePushTarget(value?: string): PushTarget | undefined;
@@ -1,5 +0,0 @@
1
- export type RunCommand = (command: string, args: string[], options?: {
2
- stdin?: string;
3
- env?: NodeJS.ProcessEnv;
4
- }) => Promise<void>;
5
- export declare const runSubprocess: RunCommand;
@@ -1,6 +0,0 @@
1
- export interface UserSecretNames {
2
- gitSyncTokenSecretName: string;
3
- mcpAuthTokenSecretName: string;
4
- discordBotTokenSecretName: string;
5
- }
6
- export declare function deriveUserSecretNames(handle: string): UserSecretNames;
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- BRAIN_FILE="${BRAIN_YAML_PATH:-brain.yaml}"
5
- SSH_USER="$(ruby -e 'require "yaml"; config = YAML.load_file("deploy/kamal/deploy.yml") || {}; puts(config.dig("ssh", "user") || "root")')"
6
- IFS=',' read -ra HOSTS <<< "$KAMAL_HOSTS"
7
- for host in "${HOSTS[@]}"; do
8
- scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$BRAIN_FILE" "${SSH_USER}@${host}:/opt/brain.yaml"
9
- done
@@ -1,66 +0,0 @@
1
- # Internal Caddy — path-based routing to brain services.
2
- # kamal-proxy terminates TLS externally; this runs inside the container.
3
- :80 {
4
- @preview host preview.*
5
- handle @preview {
6
- reverse_proxy localhost:4321
7
-
8
- header {
9
- X-Frame-Options "SAMEORIGIN"
10
- X-Content-Type-Options "nosniff"
11
- Referrer-Policy "strict-origin-when-cross-origin"
12
- }
13
- }
14
-
15
- # MCP endpoint
16
- handle /mcp* {
17
- reverse_proxy localhost:3333
18
-
19
- header {
20
- X-Content-Type-Options "nosniff"
21
- Access-Control-Allow-Origin "*"
22
- Access-Control-Allow-Methods "GET, POST, DELETE, OPTIONS"
23
- Access-Control-Allow-Headers "Content-Type, Authorization, MCP-Session-Id"
24
- }
25
- }
26
-
27
- # A2A endpoints
28
- handle /.well-known/agent-card.json {
29
- reverse_proxy localhost:3334
30
- }
31
-
32
- handle /a2a {
33
- reverse_proxy localhost:3334
34
-
35
- header {
36
- X-Content-Type-Options "nosniff"
37
- Access-Control-Allow-Origin "*"
38
- Access-Control-Allow-Methods "GET, POST, OPTIONS"
39
- Access-Control-Allow-Headers "Content-Type, Authorization"
40
- }
41
- }
42
-
43
- # Plugin API routes
44
- handle /api/* {
45
- reverse_proxy localhost:3335
46
- }
47
-
48
- # Production site: proxy to webserver if running, otherwise serve
49
- # a minimal static fallback so the healthcheck and bare-domain
50
- # requests succeed even on the core preset (no webserver).
51
- handle {
52
- reverse_proxy localhost:8080
53
-
54
- header {
55
- X-Frame-Options "SAMEORIGIN"
56
- X-Content-Type-Options "nosniff"
57
- Referrer-Policy "strict-origin-when-cross-origin"
58
- }
59
- }
60
-
61
- handle_errors {
62
- root * /srv/fallback
63
- try_files /index.html
64
- file_server
65
- }
66
- }
@@ -1,38 +0,0 @@
1
- ARG BUN_VERSION=1.3.10
2
- FROM oven/bun:${BUN_VERSION}-slim AS runtime
3
-
4
- WORKDIR /app
5
-
6
- RUN apt-get update && apt-get install -y --no-install-recommends \
7
- curl ca-certificates git gnupg debian-keyring debian-archive-keyring apt-transport-https \
8
- && curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg \
9
- && curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list \
10
- && apt-get update && apt-get install -y --no-install-recommends caddy libcap2-bin \
11
- && setcap cap_net_bind_service=+ep $(which caddy) \
12
- && rm -rf /var/lib/apt/lists/*
13
-
14
- COPY deploy/Caddyfile /etc/caddy/Caddyfile
15
-
16
- RUN mkdir -p /srv/fallback && \
17
- printf '<!doctype html><html><head><meta charset="utf-8"><title>brain</title></head><body></body></html>\n' \
18
- > /srv/fallback/index.html
19
-
20
- ENV XDG_DATA_HOME=/data
21
- ENV XDG_CONFIG_HOME=/config
22
- RUN mkdir -p /app/data /app/cache /app/brain-data && \
23
- chmod -R 777 /app/data /app/cache /app/brain-data
24
-
25
- CMD ["sh", "-c", "caddy start --config /etc/caddy/Caddyfile && exec ./node_modules/.bin/brain start"]
26
-
27
- # --- standalone: bake full project into image (brain-cli deploy) ---
28
- FROM runtime AS standalone
29
- COPY package.json ./package.json
30
- RUN bun install --production --ignore-scripts
31
- COPY . .
32
-
33
- # --- fleet: install published brain at pinned version (ops deploy) ---
34
- FROM runtime AS fleet
35
- ARG BRAIN_VERSION
36
- RUN test -n "$BRAIN_VERSION" \
37
- && printf '{"name":"rover-pilot-runtime","private":true}\n' > package.json \
38
- && bun add @rizom/brain@$BRAIN_VERSION
@@ -1,39 +0,0 @@
1
- service: rover
2
- image: <%= ENV['IMAGE_REPOSITORY'] %>
3
-
4
- servers:
5
- web:
6
- hosts:
7
- - <%= ENV['SERVER_IP'] %>
8
-
9
- proxy:
10
- ssl:
11
- certificate_pem: CERTIFICATE_PEM
12
- private_key_pem: PRIVATE_KEY_PEM
13
- hosts:
14
- - <%= ENV['BRAIN_DOMAIN'] %>
15
- app_port: 80
16
- healthcheck:
17
- path: /health
18
-
19
- registry:
20
- server: ghcr.io
21
- username: <%= ENV['REGISTRY_USERNAME'] %>
22
- password:
23
- - KAMAL_REGISTRY_PASSWORD
24
-
25
- builder:
26
- arch: amd64
27
-
28
- env:
29
- clear:
30
- NODE_ENV: production
31
- secret:
32
- - AI_API_KEY
33
- - GIT_SYNC_TOKEN
34
- - MCP_AUTH_TOKEN
35
- - DISCORD_BOT_TOKEN
36
-
37
- volumes:
38
- - /opt/brain-data:/app/brain-data
39
- - /opt/brain.yaml:/app/brain.yaml