@rizom/ops 0.2.0-alpha.6 → 0.2.0-alpha.60

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 (45) hide show
  1. package/README.md +6 -3
  2. package/dist/age-key-bootstrap.d.ts +17 -0
  3. package/dist/brains-ops.js +305 -149
  4. package/dist/cert-bootstrap.d.ts +2 -2
  5. package/dist/content-repo.d.ts +13 -0
  6. package/dist/default-user-runner.d.ts +1 -1
  7. package/dist/deploy.js +24 -24
  8. package/dist/index.d.ts +3 -0
  9. package/dist/index.js +305 -149
  10. package/dist/load-registry.d.ts +19 -3
  11. package/dist/onboard-user.d.ts +2 -2
  12. package/dist/parse-args.d.ts +2 -0
  13. package/dist/push-secrets.d.ts +1 -1
  14. package/dist/reconcile-all.d.ts +2 -2
  15. package/dist/reconcile-cohort.d.ts +2 -2
  16. package/dist/reconcile-lib.d.ts +4 -2
  17. package/dist/run-command.d.ts +0 -1
  18. package/dist/run-subprocess.d.ts +1 -0
  19. package/dist/schema.d.ts +100 -0
  20. package/dist/secrets-encrypt.d.ts +32 -0
  21. package/dist/secrets-push.d.ts +1 -1
  22. package/dist/user-add.d.ts +15 -0
  23. package/dist/user-runner.d.ts +5 -0
  24. package/package.json +7 -3
  25. package/templates/rover-pilot/.env.schema +11 -0
  26. package/templates/rover-pilot/.github/workflows/build.yml +1 -0
  27. package/templates/rover-pilot/.github/workflows/deploy.yml +74 -19
  28. package/templates/rover-pilot/.github/workflows/reconcile.yml +16 -2
  29. package/templates/rover-pilot/README.md +6 -3
  30. package/templates/rover-pilot/deploy/scripts/decrypt-user-secrets.ts +83 -0
  31. package/templates/rover-pilot/deploy/scripts/provision-server.ts +1 -1
  32. package/templates/rover-pilot/deploy/scripts/resolve-deploy-handles.ts +15 -4
  33. package/templates/rover-pilot/deploy/scripts/resolve-user-config.ts +12 -12
  34. package/templates/rover-pilot/deploy/scripts/sync-content-repo.ts +179 -0
  35. package/templates/rover-pilot/deploy/scripts/update-dns.ts +14 -4
  36. package/templates/rover-pilot/docs/onboarding-checklist.md +28 -11
  37. package/templates/rover-pilot/docs/operator-playbook.md +43 -5
  38. package/templates/rover-pilot/docs/user-onboarding.md +505 -0
  39. package/templates/rover-pilot/package.json +3 -0
  40. package/templates/rover-pilot/pilot.yaml +4 -0
  41. package/templates/rover-pilot/users/alice.yaml +5 -1
  42. package/dist/user-secret-names.d.ts +0 -6
  43. package/templates/rover-pilot/.kamal/hooks/pre-deploy +0 -9
  44. package/templates/rover-pilot/deploy/Dockerfile +0 -15
  45. package/templates/rover-pilot/deploy/kamal/deploy.yml +0 -39
@@ -0,0 +1,505 @@
1
+ # Rover Pilot User Onboarding
2
+
3
+ Welcome to the Rover pilot.
4
+
5
+ This guide is written for **first-time users**. You do **not** need prior experience with Rover, MCP, git, GitHub, or Obsidian to get started.
6
+
7
+ ## What Rover is
8
+
9
+ Rover is your private AI assistant for working with your own notes, links, and ideas.
10
+
11
+ In this pilot, the normal experience is:
12
+
13
+ - **Discord** for chatting with Rover
14
+ - the **Dashboard** in your browser at `https://<handle>.rizom.ai/`
15
+ - the **CMS** in your browser at `https://<handle>.rizom.ai/cms`
16
+
17
+ Optional workflows exist too:
18
+
19
+ - **MCP** for direct client access from supported AI tools
20
+ - **git** if you want to work with the underlying files directly
21
+ - **Obsidian** if you want a nicer note-focused editor for those same files
22
+
23
+ You can think of Rover as a private knowledge companion that helps you:
24
+
25
+ - save notes
26
+ - save links
27
+ - reflect on your own material
28
+ - find patterns in what you have collected
29
+ - think through questions with AI
30
+
31
+ ## The default mental model
32
+
33
+ If you remember only one thing, remember this:
34
+
35
+ - **Discord** = talk to Rover
36
+ - **Dashboard** = browser overview
37
+ - **CMS** = browser editing interface
38
+ - **MCP** = optional direct client integration
39
+ - **git / Obsidian** = optional file-based workflow
40
+
41
+ Most pilot users should start with the first three.
42
+
43
+ ## What you will receive from us
44
+
45
+ We will send you the details you need to get started.
46
+
47
+ That usually includes:
48
+
49
+ - confirmation that Discord is enabled for you, plus the invite/setup steps
50
+ - your **Dashboard URL**: `https://<handle>.rizom.ai/`
51
+ - your **CMS URL**: `https://<handle>.rizom.ai/cms`
52
+ - if you will use the CMS, an invite to your **private** Rover content repo plus instructions for creating a GitHub token
53
+ - if needed, your Rover MCP URL: `https://<handle>.rizom.ai/mcp`
54
+ - if needed, your **Bearer token**
55
+ - any extra instructions if we are testing a specific workflow with your cohort
56
+
57
+ If we give you a **Bearer token**, treat it like a password. Do not share it.
58
+
59
+ ## Start here: your first 5 minutes
60
+
61
+ For most users, the best first setup is:
62
+
63
+ 1. join the Discord server we send you
64
+ 2. open your Dashboard at `https://<handle>.rizom.ai/`
65
+ 3. open the CMS at `https://<handle>.rizom.ai/cms`
66
+ 4. when the CMS asks for GitHub access, use a fine-grained GitHub token with access to your private Rover content repo
67
+ 5. send a first message in Discord and make one small edit in the CMS
68
+
69
+ A simple first chat message is:
70
+
71
+ > What can you help me do, and what should I use you for?
72
+
73
+ Or:
74
+
75
+ > Help me save my first note.
76
+
77
+ A simple first CMS action is:
78
+
79
+ - open the **Notes** collection
80
+ - create a short note about why you want to use Rover
81
+ - save it
82
+
83
+ If Discord is not enabled for you yet, tell us and we will share the right next step.
84
+
85
+ ## One important idea: Discord + Dashboard + CMS are the default, MCP is optional
86
+
87
+ If you are new to Rover, the shortest explanation is:
88
+
89
+ - **Rover** is the assistant
90
+ - **Discord** is the default chat interface
91
+ - the **Dashboard** is the default browser view
92
+ - the **CMS** is the default browser editing interface
93
+ - **MCP** is an optional direct connection method for supported AI clients
94
+
95
+ You do not need to understand the protocol details unless we specifically ask you to use MCP.
96
+
97
+ For most users, the practical meaning is simple:
98
+
99
+ - join Discord
100
+ - open your dashboard in the browser
101
+ - use the CMS when you want to edit structured content directly
102
+ - start using it
103
+
104
+ If your cohort is also testing MCP, we will send the URL, Bearer token, and setup help separately.
105
+
106
+ ## Working in the CMS
107
+
108
+ The CMS is the easiest way to edit Rover content in the browser.
109
+
110
+ Use it when you want to:
111
+
112
+ - create notes without touching git directly
113
+ - edit existing content in a structured form
114
+ - browse your collections in one place
115
+ - make quick updates from the browser
116
+
117
+ ### Why the CMS asks for GitHub access
118
+
119
+ Your Rover content lives in a **private GitHub repo**.
120
+
121
+ The CMS edits that repo for you.
122
+
123
+ That is why it asks for a **GitHub token**.
124
+
125
+ In practice, that means:
126
+
127
+ - you can use the CMS without cloning the repo locally
128
+ - your changes still go into your private content repo
129
+ - if you later open that repo with git or Obsidian, you are looking at the same underlying content
130
+
131
+ ### What to expect the first time you open it
132
+
133
+ When you open `https://<handle>.rizom.ai/cms`, you should expect something like this:
134
+
135
+ 1. the CMS asks you to authenticate with GitHub
136
+ 2. you enter the GitHub token we told you to create
137
+ 3. the CMS loads your content collections
138
+ 4. you can open an entry, edit it, and save your changes
139
+
140
+ If the CMS loads correctly, that is a good sign that:
141
+
142
+ - your browser access is working
143
+ - your repo access is working
144
+ - the token is working
145
+
146
+ ### What you will see in the CMS
147
+
148
+ The exact collections may change over time, but a normal pilot setup includes collections for things like:
149
+
150
+ - **Notes**
151
+ - links or saved resources
152
+ - settings or other structured content
153
+
154
+ The important idea is not the exact list — it is that the CMS is the browser-based editor for your Rover content.
155
+
156
+ ### A good first CMS task
157
+
158
+ A good first CMS task is to create a short note.
159
+
160
+ For example:
161
+
162
+ - open **Notes**
163
+ - create a new note
164
+ - title it something like `Why I’m using Rover`
165
+ - write 3 to 5 sentences
166
+ - save it
167
+
168
+ Then go back to Discord and ask Rover something like:
169
+
170
+ > What do you know about why I’m using Rover so far?
171
+
172
+ That connects the browser editing workflow with the chat workflow.
173
+
174
+ ### When to use Discord vs CMS
175
+
176
+ A good rule of thumb is:
177
+
178
+ Use **Discord** when you want to:
179
+
180
+ - think out loud
181
+ - ask questions
182
+ - capture something quickly
183
+ - use Rover as a day-to-day assistant
184
+
185
+ Use the **CMS** when you want to:
186
+
187
+ - deliberately create or revise content
188
+ - browse existing entries
189
+ - make cleaner edits than you would in chat
190
+ - work in a more editor-like browser interface
191
+
192
+ Use both together. That is the default pilot workflow.
193
+
194
+ ### If the CMS feels confusing
195
+
196
+ That is useful feedback.
197
+
198
+ Please tell us:
199
+
200
+ - what part was confusing
201
+ - whether the problem was authentication, navigation, editing, or saving
202
+ - what you expected to happen instead
203
+
204
+ We want to improve this workflow.
205
+
206
+ ## Optional: direct MCP access
207
+
208
+ If we have asked you to use an MCP client, use one that supports:
209
+
210
+ - **HTTP / Streamable HTTP MCP**
211
+ - **Bearer token authentication**
212
+
213
+ When your client asks for connection details, use:
214
+
215
+ - **Server URL:** `https://<handle>.rizom.ai/mcp`
216
+ - **Authentication type:** Bearer token
217
+ - **Bearer token:** the token we sent you
218
+
219
+ If the client asks for a name, use something simple like:
220
+
221
+ - `Rover (<handle>)`
222
+
223
+ ## Optional: Claude Desktop setup
224
+
225
+ If we ask you to connect through Claude Desktop and your version supports a **remote HTTP / Streamable HTTP MCP server**, enter:
226
+
227
+ - **Server URL:** `https://<handle>.rizom.ai/mcp`
228
+ - **Authentication:** Bearer token
229
+ - **Token:** the token we sent you
230
+
231
+ Then try a first message like:
232
+
233
+ > What can you help me do, and what should I use you for?
234
+
235
+ Or:
236
+
237
+ > Help me save my first note.
238
+
239
+ 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.
240
+
241
+ ## Optional: git, text files, and Obsidian
242
+
243
+ The underlying content workflow is still a normal **git repo** with normal **markdown/text files**.
244
+
245
+ But for this pilot, treat that as **optional**.
246
+
247
+ Use direct git or file-based workflows only if you want more control.
248
+
249
+ Obsidian is optional. It is just one possible editor for those files.
250
+
251
+ That means:
252
+
253
+ - use **Discord** as the main way to talk to Rover
254
+ - use the **Dashboard** and **CMS** as the normal browser workflow
255
+ - use a normal editor plus **git** only if you want to browse, draft, and edit your files directly
256
+ - use **Obsidian** only if you want a more note-focused interface for the same files
257
+ - Rover can pick up those file changes through the normal git-sync / directory-sync flow
258
+
259
+ ### Important: your content repo is private
260
+
261
+ If you use the git/text-file workflow, you will be working in your own **private** GitHub repo.
262
+
263
+ That means:
264
+
265
+ - you do **not** need repo access just to use Rover in Discord
266
+ - you **do** need GitHub access if you want to clone, edit, and push to your content repo
267
+ - we will invite you only to **your own** content repo, not to the operator repo and not to other users' repos
268
+
269
+ ### How you get access
270
+
271
+ If you want the git/text-file workflow, we will:
272
+
273
+ 1. create or confirm your private content repo
274
+ 2. invite your GitHub account to that repo
275
+ 3. ask you to accept the GitHub invite
276
+ 4. send you the repo URL
277
+
278
+ ### Authentication options
279
+
280
+ To work with a private repo or the CMS, you need GitHub authentication.
281
+
282
+ Usually the easiest order is:
283
+
284
+ 1. **GitHub sign-in** to accept the private repo invite
285
+ 2. a **fine-grained personal access token** for the CMS, with access to your private Rover content repo
286
+ 3. **GitHub Desktop** or normal git auth if you also want to clone the repo locally
287
+ 4. **SSH key** only if you already use git that way
288
+
289
+ You do **not** need a GitHub token just to use Rover in Discord.
290
+ You do **not** need an MCP Bearer token unless we explicitly ask you to use MCP.
291
+
292
+ ### If you want the local file workflow
293
+
294
+ If we have already shared your content repo workflow with you, the normal setup is:
295
+
296
+ 1. clone your Rover content repo locally
297
+ 2. edit the markdown/text files in your normal editor, or open that same folder as an Obsidian vault if you prefer
298
+ 3. optionally install the **Obsidian Git** plugin if you want in-app commit/push/pull support
299
+ 4. edit or organize your notes there
300
+ 5. commit and push your changes through normal git, GitHub Desktop, or the Obsidian Git plugin
301
+ 6. let the normal git-sync flow carry those changes into Rover
302
+
303
+ If we have **not** given you a direct content repo workflow yet, that is fine. You can ignore git, text files, and Obsidian for now and use Rover in Discord and the CMS. If we have also asked you to test MCP, you can use that too.
304
+
305
+ ## Discord (default chat interface)
306
+
307
+ Discord is the default chat interface for this pilot.
308
+
309
+ Think of it as the main place to:
310
+
311
+ - save quick notes
312
+ - drop in links to save
313
+ - ask short or long questions
314
+ - use Rover day to day without setting up a separate client
315
+
316
+ Important:
317
+
318
+ - **Discord is the main pilot chat interface**
319
+ - the **Dashboard** and **CMS** are the main browser interfaces
320
+ - MCP is **optional**
321
+ - if Discord is enabled, we will send the exact invite/setup steps separately
322
+ - for some pilot setups, Discord-enabled users may need to supply their own bot token
323
+
324
+ If Discord is **not** enabled for you yet, ask us and we will tell you whether your cohort is on the Discord-first workflow.
325
+
326
+ ## Dashboard basics
327
+
328
+ The Dashboard is the browser landing page for your Rover.
329
+
330
+ Use it when you want to:
331
+
332
+ - confirm the instance is up
333
+ - see the browser-side operator surface
334
+ - jump into the CMS quickly
335
+
336
+ This is not meant to be a public website. It is part of your Rover control surface.
337
+
338
+ ## Wishlist: when Rover cannot do something yet
339
+
340
+ Rover has a built-in **wishlist**.
341
+
342
+ This matters because Rover will not be able to do everything yet.
343
+
344
+ If you ask for something Rover cannot do, it should add that request to the wishlist instead of just failing silently.
345
+
346
+ You can think of the wishlist as:
347
+
348
+ - a backlog of missing capabilities
349
+ - a record of things users want Rover to do
350
+ - a way for the pilot team to see which missing features matter most
351
+
352
+ ### When the wishlist is useful
353
+
354
+ The wishlist is especially useful when you ask Rover to do something like:
355
+
356
+ - connect to a tool it does not support yet
357
+ - perform an action it cannot perform yet
358
+ - add a workflow or feature that does not exist yet
359
+
360
+ Examples:
361
+
362
+ > I want Rover to draft and send emails for me.
363
+
364
+ > I want Rover to connect to my calendar.
365
+
366
+ > I want Rover to summarize voice notes automatically.
367
+
368
+ If Rover cannot actually do those things yet, it should tell you that and add the request to the wishlist.
369
+
370
+ ### What happens when something is added to the wishlist
371
+
372
+ When a request is added to the wishlist:
373
+
374
+ - it is saved as a **wish**
375
+ - it starts in a **new** state
376
+ - similar requests can be grouped together instead of creating endless duplicates
377
+ - repeated demand can increase the count of how many times that wish was requested
378
+
379
+ That helps us see which gaps are one-off ideas and which ones keep coming up across real usage.
380
+
381
+ ### How you should use it
382
+
383
+ You do **not** need special commands.
384
+
385
+ Just ask naturally.
386
+
387
+ If Rover cannot do what you asked, a good response from Rover is something like:
388
+
389
+ - it explains the limitation clearly
390
+ - it says the request was added to the wishlist
391
+
392
+ If that does **not** happen, that is useful feedback for us too.
393
+
394
+ ## What to expect in the pilot
395
+
396
+ This is a real working system, but it is still an early pilot.
397
+
398
+ So you should expect:
399
+
400
+ - some rough edges
401
+ - a setup process that may still be a bit manual
402
+ - a Rover that becomes more useful as you add more notes and links
403
+ - occasional follow-up questions from us about your experience
404
+ - improvements and changes during the pilot
405
+
406
+ That is normal. The point of the pilot is to learn from real use.
407
+
408
+ ## Privacy and boundaries
409
+
410
+ For the pilot:
411
+
412
+ - your Rover is deployed specifically for you
413
+ - if you are using MCP, access to `/mcp` is protected by your Bearer token
414
+ - your content repo is private
415
+ - you should avoid putting highly sensitive material into the pilot unless we have explicitly agreed that it is in scope
416
+
417
+ If you are unsure whether something belongs in Rover, ask us first.
418
+
419
+ ## Troubleshooting
420
+
421
+ ### I opened the domain and it does not look like a normal public site
422
+
423
+ That is expected. The root URL is your **Dashboard**, not a public website. The CMS lives at `/cms`. Rover also runs through Discord and, optionally, a direct MCP endpoint.
424
+
425
+ ### The CMS asks for GitHub auth and I am not sure what to do
426
+
427
+ That is expected.
428
+
429
+ Use the GitHub token we told you to create for your **private Rover content repo**.
430
+
431
+ If you are missing one of these pieces, tell us:
432
+
433
+ - you did not get the repo invite
434
+ - you did not accept the repo invite yet
435
+ - you are not sure how to create the token
436
+ - the token was accepted but the CMS still does not load
437
+
438
+ ### The CMS loads, but I am not sure whether my change worked
439
+
440
+ A good quick test is:
441
+
442
+ 1. edit a short note in the CMS
443
+ 2. save it
444
+ 3. refresh the CMS and confirm the change is still there
445
+ 4. ask Rover in Discord about that note
446
+
447
+ If anything in that loop feels unclear, tell us exactly where it became confusing.
448
+
449
+ ### I got an authentication error in MCP
450
+
451
+ Usually this means one of three things:
452
+
453
+ - the Bearer token was missing
454
+ - the Bearer token was pasted incorrectly
455
+ - the client is using the wrong authentication type
456
+
457
+ Double-check that you are using:
458
+
459
+ - URL: `https://<handle>.rizom.ai/mcp`
460
+ - auth type: **Bearer token**
461
+ - token: exactly the token we sent you
462
+
463
+ ### My MCP client says it cannot connect
464
+
465
+ Some clients support local MCP servers better than remote HTTP MCP servers.
466
+
467
+ If that happens, send us:
468
+
469
+ - the name of the client
470
+ - the version you are using
471
+ - the exact error message
472
+ - a screenshot if possible
473
+
474
+ ## What feedback helps us most
475
+
476
+ We especially want to hear:
477
+
478
+ - what was confusing during setup
479
+ - whether Discord, Dashboard, and CMS each made sense
480
+ - what felt useful immediately
481
+ - what felt weak, awkward, or unclear
482
+ - what you expected Rover to do but could not get it to do
483
+ - whether you would keep using it after the pilot
484
+
485
+ Short, honest feedback is perfect.
486
+
487
+ ## Quick handoff template
488
+
489
+ When we onboard you, the message will look roughly like this:
490
+
491
+ ```text
492
+ Discord enabled: yes/no
493
+ Discord setup: <invite link or setup steps>
494
+ Dashboard URL: https://<handle>.rizom.ai/
495
+ CMS URL: https://<handle>.rizom.ai/cms
496
+ CMS auth: GitHub token with access to your private Rover content repo
497
+ MCP access: optional / enabled / not enabled
498
+
499
+ If MCP is enabled:
500
+ MCP URL: https://<handle>.rizom.ai/mcp
501
+ Auth type: Bearer token
502
+ Bearer token: <token>
503
+ ```
504
+
505
+ If anything is unclear, reply with the exact error text or a screenshot and we will help.
@@ -3,6 +3,9 @@
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": {
7
10
  "@rizom/ops": "__BRAINS_OPS_VERSION__"
8
11
  }
@@ -6,3 +6,7 @@ contentRepoPrefix: rover-
6
6
  domainSuffix: .rizom.ai
7
7
  preset: core
8
8
  aiApiKey: AI_API_KEY
9
+ gitSyncToken: GIT_SYNC_TOKEN
10
+ contentRepoAdminToken: CONTENT_REPO_ADMIN_TOKEN
11
+ mcpAuthToken: MCP_AUTH_TOKEN
12
+ 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,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,15 +0,0 @@
1
- ARG BUN_VERSION=1.3.10
2
- FROM oven/bun:${BUN_VERSION}-slim
3
-
4
- ARG BRAIN_VERSION
5
- WORKDIR /app
6
-
7
- RUN test -n "$BRAIN_VERSION" \
8
- && printf '{"name":"rover-pilot-runtime","private":true}\n' > package.json \
9
- && bun add @rizom/brain@$BRAIN_VERSION
10
-
11
- ENV XDG_DATA_HOME=/data
12
- ENV XDG_CONFIG_HOME=/config
13
- RUN mkdir -p /app/brain-data /data /config && chmod -R 777 /app/brain-data /data /config
14
-
15
- CMD ["sh", "-c", "exec ./node_modules/.bin/brain start"]
@@ -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: 3333
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