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.
@@ -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
- export function download(dir, stripComponents = 1, filter = "") {
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 '${STARTER_TARBALL}' | tar -xz --strip-components=${stripComponents} -C '${dir}' ${filter}`],
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");
@@ -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
- // The reference client ships inside the starter take just that folder.
141
- download(name, 3, "'*/packages/client'");
142
- ok(`client app scaffolded in ${label(name)}`);
143
- console.log(`\n Next:${name === "." ? "" : `\n cd ${name}`}\n npm install && npm run dev\n\n ${cyan("Build with Claude:")} open this folder in Claude Code and describe what you want, in plain words.\n`);
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",
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unoverse",
3
- "version": "0.1.140",
3
+ "version": "0.1.142",
4
4
  "description": "The Unoverse front door — create a Studio project, a universe, or a client app, and launch Studio.",
5
5
  "license": "SEE LICENSE IN README.md",
6
6
  "type": "module",