unoverse 0.1.140 → 0.1.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/lib/create/download.mjs +7 -2
- package/lib/create/index.mjs +16 -5
- package/operator/.env.example +69 -0
- package/operator/lib/db-verify.sh +12 -1
- package/operator/operator.sh +15 -0
- package/package.json +1 -1
package/lib/create/download.mjs
CHANGED
|
@@ -7,11 +7,16 @@ import { spawnSync } from "node:child_process";
|
|
|
7
7
|
export const STARTER_TARBALL =
|
|
8
8
|
"https://codeload.github.com/unoverse-platform/starter/tar.gz/refs/heads/main";
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
// The CLIENT STARTER has its own public repo. It used to be a folder inside the starter,
|
|
11
|
+
// which meant handing someone the whole operator kit to give them one web page.
|
|
12
|
+
export const CLIENT_TARBALL =
|
|
13
|
+
"https://codeload.github.com/unoverse-platform/client/tar.gz/refs/heads/main";
|
|
14
|
+
|
|
15
|
+
export function download(dir, stripComponents = 1, filter = "", tarball = STARTER_TARBALL) {
|
|
11
16
|
mkdirSync(dir, { recursive: true });
|
|
12
17
|
const r = spawnSync(
|
|
13
18
|
"sh",
|
|
14
|
-
["-c", `curl -fsSL '${
|
|
19
|
+
["-c", `curl -fsSL '${tarball}' | tar -xz --strip-components=${stripComponents} -C '${dir}' ${filter}`],
|
|
15
20
|
{ stdio: ["ignore", "inherit", "inherit"] },
|
|
16
21
|
);
|
|
17
22
|
if (r.status !== 0) throw new Error("download failed");
|
package/lib/create/index.mjs
CHANGED
|
@@ -15,7 +15,7 @@ import { spawnSync } from "node:child_process";
|
|
|
15
15
|
import { cyan, dim, ok, fail, ask, select } from "../ui.mjs";
|
|
16
16
|
import { parseCredential, validateRegistryToken, dockerUp, dockerLogin } from "./credential.mjs";
|
|
17
17
|
import { resolveTarget, label } from "./target.mjs";
|
|
18
|
-
import { download } from "./download.mjs";
|
|
18
|
+
import { download, CLIENT_TARBALL } from "./download.mjs";
|
|
19
19
|
|
|
20
20
|
export async function create(nameArg) {
|
|
21
21
|
console.log(`\n ${cyan("⬡ What are you building?")}\n`);
|
|
@@ -137,10 +137,21 @@ export async function create(nameArg) {
|
|
|
137
137
|
|
|
138
138
|
if (choice === "3") {
|
|
139
139
|
const name = resolveTarget(nameArg);
|
|
140
|
-
//
|
|
141
|
-
download(name,
|
|
142
|
-
ok(`client
|
|
143
|
-
console.log(
|
|
140
|
+
// Its own public repo, so the whole tree IS the project: one strip level, no filter.
|
|
141
|
+
download(name, 1, "", CLIENT_TARBALL);
|
|
142
|
+
ok(`client scaffolded in ${label(name)}`);
|
|
143
|
+
console.log(`
|
|
144
|
+
Next:${name === "." ? "" : `
|
|
145
|
+
cd ${name}`}
|
|
146
|
+
npm install
|
|
147
|
+
cp .env.example .env ${dim("# your universe, and which app to load")}
|
|
148
|
+
npm run dev
|
|
149
|
+
|
|
150
|
+
The README documents every option: the script tag's attributes, how to hand it
|
|
151
|
+
your login, and how to open it from your own buttons.
|
|
152
|
+
|
|
153
|
+
${cyan("Docs:")} https://docs.unoverse.ai
|
|
154
|
+
`);
|
|
144
155
|
return;
|
|
145
156
|
}
|
|
146
157
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# THE UNIVERSE — LOCAL DEV
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# cp .env.example .env — set DATABASE_URL, OPENAI_API_KEY, and your OIDC
|
|
5
|
+
# values (or AUTH_ENABLED=false to skip login locally). That's it.
|
|
6
|
+
# (Production is Terraform's job — see infra/*/terraform.tfvars.example.)
|
|
7
|
+
|
|
8
|
+
# ── Local development ────────────────────────────────────────────────────────
|
|
9
|
+
# THESE TWO GO TOGETHER. Auth is always on by default, and turning it off is
|
|
10
|
+
# refused when the environment claims to be production — so setting only
|
|
11
|
+
# AUTH_ENABLED=false leaves the platform correctly refusing to start, with the
|
|
12
|
+
# two settings contradicting each other and no way out. A deployed universe sets
|
|
13
|
+
# neither: unset means production with auth on, and Terraform never renders them.
|
|
14
|
+
NODE_ENV=development
|
|
15
|
+
AUTH_ENABLED=false
|
|
16
|
+
|
|
17
|
+
# Postgres. A managed URL works as-is; a Postgres running on YOUR MAC needs
|
|
18
|
+
# host.docker.internal for the same reason as Redis below — the platform runs in containers,
|
|
19
|
+
# and localhost inside one means that container.
|
|
20
|
+
DATABASE_URL=postgres://user:password@host.docker.internal:5432/unoverse
|
|
21
|
+
|
|
22
|
+
# Local Redis. `unoverse start` launches one for you if none is running.
|
|
23
|
+
#
|
|
24
|
+
# host.docker.internal, NOT 127.0.0.1: the platform runs in containers, and inside a
|
|
25
|
+
# container 127.0.0.1 means THAT CONTAINER. Redis runs on your Mac with a published port, so
|
|
26
|
+
# this is the address that reaches it. The sample said 127.0.0.1 and every fresh universe
|
|
27
|
+
# hit the same wall — unoverse died on boot with MaxRetriesPerRequestError while memory,
|
|
28
|
+
# which tolerates a dead Redis, stayed up and made it look like something subtler.
|
|
29
|
+
REDIS_HOST=host.docker.internal
|
|
30
|
+
REDIS_PORT=6379
|
|
31
|
+
REDIS_PASSWORD=
|
|
32
|
+
REDIS_TLS=false
|
|
33
|
+
REDIS_NAMESPACE=gravity
|
|
34
|
+
|
|
35
|
+
# Memory server + OpenAI nodes
|
|
36
|
+
OPENAI_API_KEY=sk-your-key-here
|
|
37
|
+
|
|
38
|
+
# REQUIRED: pulls the platform images. Without it the platform cannot start.
|
|
39
|
+
# (Only platform-source developers building images locally can leave it empty.)
|
|
40
|
+
DOCR_TOKEN=
|
|
41
|
+
|
|
42
|
+
# Page intelligence (promote-page extraction)
|
|
43
|
+
HYPERBROWSER_API_KEY=
|
|
44
|
+
|
|
45
|
+
# Marketplace catalogue to install from (docs/architecture/MARKETPLACE.md).
|
|
46
|
+
# Empty = local items only. No default: a URL is never hardcoded.
|
|
47
|
+
UNOVERSE_MARKETPLACE_URL=
|
|
48
|
+
|
|
49
|
+
# REQUIRED. The master key encrypting every credential saved in the database. There is
|
|
50
|
+
# no default and no fallback: the server refuses to start without it. A default would be
|
|
51
|
+
# a key published in the source, which is what this used to be, and encryption at rest
|
|
52
|
+
# under a key everyone has is evidence of nothing.
|
|
53
|
+
#
|
|
54
|
+
# Generate: openssl rand -base64 32 (at least 32 characters)
|
|
55
|
+
# BACK IT UP with your database. Lose it and every stored credential is unreadable, and
|
|
56
|
+
# no backup can bring them back. `unoverse create` generates one for you.
|
|
57
|
+
#
|
|
58
|
+
# CHANGING IT ORPHANS EXISTING CREDENTIALS. Pointing a fresh .env at a database that
|
|
59
|
+
# already holds credentials fails with OpenSSL "bad decrypt" on every one of them: copy
|
|
60
|
+
# the original key across rather than generating a new one.
|
|
61
|
+
CREDENTIAL_ENCRYPTION_KEY=
|
|
62
|
+
|
|
63
|
+
# Auth is ON by default (missing flag = enabled), same as production.
|
|
64
|
+
AUTH_ISSUER=https://your-tenant.auth0.com
|
|
65
|
+
AUTH_CLIENT_ID=your-client-id
|
|
66
|
+
AUTH_AUDIENCE=gravity-api
|
|
67
|
+
|
|
68
|
+
# Quick no-login mode (local only — production refuses to start with it):
|
|
69
|
+
# AUTH_ENABLED=false
|
|
@@ -96,7 +96,18 @@ cmd_db_verify() {
|
|
|
96
96
|
dictionary_clusters: [
|
|
97
97
|
"cluster_id", "workflow_id", "parent_id", "depth", "name", "description",
|
|
98
98
|
"name_embedding", "medoid_id", "terms", "member_count", "umap_x", "umap_y",
|
|
99
|
-
"umap_z", "radius", "created_at", "updated_at"
|
|
99
|
+
"umap_z", "radius", "created_at", "updated_at",
|
|
100
|
+
"region_id", "carried_overlap", "derived_from", "name_locked", "locked_at",
|
|
101
|
+
"locked_by", "member_ids"
|
|
102
|
+
],
|
|
103
|
+
user_region_events: [
|
|
104
|
+
"id", "workflow_id", "user_id", "region_id", "region_name", "stage",
|
|
105
|
+
"source", "evidence", "occurred_at"
|
|
106
|
+
],
|
|
107
|
+
dictionary_regions: [
|
|
108
|
+
"region_id", "workflow_id", "depth", "name", "description", "name_locked",
|
|
109
|
+
"locked_at", "locked_by", "stage", "stage_set_by", "needs_review",
|
|
110
|
+
"derived_from", "first_seen", "last_seen", "closed_at"
|
|
100
111
|
],
|
|
101
112
|
dictionary_content_chunks: [
|
|
102
113
|
"chunk_id", "text", "source_url", "source_type", "metadata",
|
package/operator/operator.sh
CHANGED
|
@@ -116,6 +116,21 @@ case "${1:-}" in
|
|
|
116
116
|
fi
|
|
117
117
|
fi
|
|
118
118
|
|
|
119
|
+
# .env.example UPDATES LIKE THE COMPOSE FILE, and for the same reason: it is the
|
|
120
|
+
# reference a developer reads when they add a setting by hand, and it was written once
|
|
121
|
+
# at creation and never again. It went stale the moment CREDENTIAL_ENCRYPTION_KEY
|
|
122
|
+
# became required — an old copy still describes it as optional with a built-in default,
|
|
123
|
+
# which is now the shape that refuses to boot.
|
|
124
|
+
#
|
|
125
|
+
# THE EXAMPLE ONLY. Their .env is never touched by anything here.
|
|
126
|
+
_vexample="$GRAVITY_LIB/../.env.example"
|
|
127
|
+
if [ -f "$_vexample" ] && [ -f "$ROOT/.env.example" ]; then
|
|
128
|
+
if ! cmp -s "$_vexample" "$ROOT/.env.example"; then
|
|
129
|
+
cp "$_vexample" "$ROOT/.env.example"
|
|
130
|
+
ok "Refreshed .env.example ${DIM}(your .env is untouched)${NC}"
|
|
131
|
+
fi
|
|
132
|
+
fi
|
|
133
|
+
|
|
119
134
|
_vinfra="$GRAVITY_LIB/../infra"
|
|
120
135
|
if [ -d "$_vinfra" ]; then
|
|
121
136
|
for _g in digitalocean aws; do
|
package/package.json
CHANGED