@rizom/ops 0.2.0-alpha.140 → 0.2.0-alpha.142
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/dist/brains-ops.js +145 -75
- package/dist/cert-bootstrap.d.ts +2 -0
- package/dist/content-repo-ref.d.ts +10 -0
- package/dist/deploy.js +7 -3
- package/dist/index.js +145 -75
- package/dist/load-registry.d.ts +8 -0
- package/dist/parse-args.d.ts +1 -0
- package/dist/schema.d.ts +60 -189
- package/dist/secrets-encrypt.d.ts +1 -11
- package/package.json +44 -44
- package/templates/rover-pilot/.github/workflows/build.yml +15 -11
- package/templates/rover-pilot/.github/workflows/deploy.yml +26 -8
- package/templates/rover-pilot/deploy/scripts/decrypt-user-secrets.ts +12 -0
- package/templates/rover-pilot/deploy/scripts/resolve-build-config.ts +53 -0
- package/templates/rover-pilot/deploy/scripts/resolve-deploy-handles.ts +1 -0
- package/templates/rover-pilot/deploy/scripts/resolve-user-config.ts +55 -8
- package/templates/rover-pilot/docs/user-onboarding.md +17 -17
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
1
2
|
import { readFileSync } from "node:fs";
|
|
3
|
+
import { loadPilotRegistry } from "@rizom/ops";
|
|
2
4
|
|
|
3
5
|
import { parseEnvFile, requireEnv, writeGitHubOutput } from "./helpers";
|
|
4
6
|
|
|
@@ -7,6 +9,14 @@ const envPath = `users/${handle}/.env`;
|
|
|
7
9
|
const brainYamlPath = `users/${handle}/brain.yaml`;
|
|
8
10
|
|
|
9
11
|
const envEntries = parseEnvFile(envPath);
|
|
12
|
+
const registry = await loadPilotRegistry(process.cwd());
|
|
13
|
+
const user = registry.users.find((candidate) => candidate.handle === handle);
|
|
14
|
+
if (!user) {
|
|
15
|
+
throw new Error(`Unknown user handle: ${handle}`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const brainVersion = envEntries["BRAIN_VERSION"] ?? "";
|
|
19
|
+
const imageTag = resolveImageTag(registry, brainVersion);
|
|
10
20
|
const repository = process.env["GITHUB_REPOSITORY"] ?? "";
|
|
11
21
|
const repositoryOwner = repository.split("/")[0] ?? "";
|
|
12
22
|
|
|
@@ -17,23 +27,28 @@ if (!brainDomain) {
|
|
|
17
27
|
throw new Error(`Missing domain in ${brainYamlPath}`);
|
|
18
28
|
}
|
|
19
29
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
30
|
+
const pilotSubdomainPrefix = `${handle}.`;
|
|
31
|
+
const pilotZone =
|
|
32
|
+
brainDomain.startsWith(pilotSubdomainPrefix) &&
|
|
33
|
+
brainDomain.length > pilotSubdomainPrefix.length
|
|
34
|
+
? brainDomain.slice(pilotSubdomainPrefix.length)
|
|
23
35
|
: "";
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
const
|
|
36
|
+
const previewDomain = pilotZone
|
|
37
|
+
? `${handle}-preview.${pilotZone}`
|
|
38
|
+
: `preview.${brainDomain}`;
|
|
39
|
+
const wwwDomain = pilotZone ? "" : `www.${brainDomain}`;
|
|
28
40
|
|
|
29
41
|
const outputs: Record<string, string> = {
|
|
30
|
-
brain_version:
|
|
42
|
+
brain_version: brainVersion,
|
|
31
43
|
content_repo: envEntries["CONTENT_REPO"] ?? "",
|
|
32
44
|
brain_domain: brainDomain,
|
|
33
45
|
preview_domain: previewDomain,
|
|
46
|
+
www_domain: wwwDomain,
|
|
47
|
+
cloudflare_zone_id: user.cloudflareZoneId ?? "",
|
|
34
48
|
brain_yaml_path: brainYamlPath,
|
|
35
49
|
instance_name: `rover-${handle}`,
|
|
36
50
|
image_repository: `ghcr.io/${repository}`,
|
|
51
|
+
image_tag: imageTag,
|
|
37
52
|
registry_username: repositoryOwner,
|
|
38
53
|
};
|
|
39
54
|
|
|
@@ -47,3 +62,35 @@ for (const key of required) {
|
|
|
47
62
|
for (const [key, value] of Object.entries(outputs)) {
|
|
48
63
|
writeGitHubOutput(key, value);
|
|
49
64
|
}
|
|
65
|
+
|
|
66
|
+
function resolveImageTag(
|
|
67
|
+
registry: Awaited<ReturnType<typeof loadPilotRegistry>>,
|
|
68
|
+
brainVersion: string,
|
|
69
|
+
): string {
|
|
70
|
+
if (!brainVersion) {
|
|
71
|
+
return "";
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const sitePackages = [
|
|
75
|
+
...new Set(
|
|
76
|
+
registry.users
|
|
77
|
+
.filter((user) => user.brainVersion === brainVersion)
|
|
78
|
+
.flatMap((user) =>
|
|
79
|
+
user.siteOverride
|
|
80
|
+
? [`${user.siteOverride.package}@${user.siteOverride.version}`]
|
|
81
|
+
: [],
|
|
82
|
+
),
|
|
83
|
+
),
|
|
84
|
+
].sort();
|
|
85
|
+
|
|
86
|
+
if (sitePackages.length === 0) {
|
|
87
|
+
return `brain-${brainVersion}`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const siteHash = createHash("sha256")
|
|
91
|
+
.update(sitePackages.join("\n"))
|
|
92
|
+
.digest("hex")
|
|
93
|
+
.slice(0, 12);
|
|
94
|
+
|
|
95
|
+
return `brain-${brainVersion}-sites-${siteHash}`;
|
|
96
|
+
}
|
|
@@ -54,40 +54,40 @@ Most people spend most of their time in Chat. The CMS becomes useful once you ha
|
|
|
54
54
|
---
|
|
55
55
|
|
|
56
56
|
## Other ways to chat with Rover
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
`/chat` is the primary interface, but Rover can also be reached through messaging platforms. Discord is tested and working. Slack, WhatsApp Business, and similar should work out of the box — we'll send setup steps if that's part of your configuration.
|
|
59
59
|
|
|
60
60
|
**Talking to another Rover**
|
|
61
|
-
|
|
61
|
+
|
|
62
62
|
If you know another Rover user, you can add them to your contacts and call their Rover directly from your chat.
|
|
63
|
-
|
|
64
|
-
- To add:
|
|
65
|
-
- To call:
|
|
66
|
-
You'll need their address — in the format `name.rizom.ai` — which they can share with you directly.
|
|
67
|
-
|
|
63
|
+
|
|
64
|
+
- To add: _Add jane.rizom.ai to my contacts._
|
|
65
|
+
- To call: _Call jane.rizom.ai and ask [your question]._
|
|
66
|
+
You'll need their address — in the format `name.rizom.ai` — which they can share with you directly.
|
|
67
|
+
|
|
68
68
|
---
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
## Connecting Rover to other tools
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
Rover can connect to external tools via MCP — a standard protocol that works in two directions: agentic AI clients (like Claude Desktop) can use it to talk to Rover, and Rover can use it to talk to productivity tools like Notion or Linear.
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
Plugins exist for a number of tools already, and new ones can be built quickly in response to what you actually need. If there's a tool you'd want Rover to connect to, tell us.
|
|
75
|
-
|
|
75
|
+
|
|
76
76
|
If MCP is part of your setup, we'll send specific instructions alongside your URL.
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
---
|
|
79
|
-
|
|
79
|
+
|
|
80
80
|
## A few common questions
|
|
81
|
-
|
|
81
|
+
|
|
82
82
|
**How do I access my data?**
|
|
83
83
|
Your primary interface is the CMS (`/cms`), where you can browse and edit everything you've saved. If you're set up with GitHub access, your content also lives in a private repository you can access directly.
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
**Does Rover connect to the internet?**
|
|
86
86
|
No — and that's intentional. Rover works with what you've put into it, not with whatever the internet currently says. That means its answers are grounded in your actual knowledge base, not in generic search results.
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
**What does this cost?**
|
|
89
89
|
Nothing during the pilot. We cover hosting costs while you're part of the programme.
|
|
90
|
-
|
|
90
|
+
|
|
91
91
|
---
|
|
92
92
|
|
|
93
93
|
## This is a pilot
|