unoverse 0.1.29 → 0.1.30
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.mjs +16 -0
- package/operator/lib/init.sh +72 -29
- package/package.json +1 -1
package/lib/create.mjs
CHANGED
|
@@ -214,6 +214,22 @@ export async function create(nameArg) {
|
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
if (choice === "2") {
|
|
217
|
+
// ALREADY A UNIVERSE? Then this is a re-run, not a conflict. The first create
|
|
218
|
+
// scaffolds the files; if setup was interrupted (Ctrl-C at any question), running
|
|
219
|
+
// create again used to refuse with "this folder is not empty" — which reads as
|
|
220
|
+
// broken when the folder holds exactly what create itself put there. A universe is
|
|
221
|
+
// recognized by its compose file; resume setup instead.
|
|
222
|
+
const target = nameArg || ".";
|
|
223
|
+
if (existsSync(`${target}/docker-compose.yml`)) {
|
|
224
|
+
console.log(`\n ${dim(`${target === "." ? "This folder" : `./${target}`} is already a universe. Picking setup back up.`)}\n`);
|
|
225
|
+
rl.close();
|
|
226
|
+
const here2 = dirname(fileURLToPath(import.meta.url));
|
|
227
|
+
const vend = resolve(here2, "../operator/operator.sh");
|
|
228
|
+
const op = existsSync(vend) ? vend : resolve(here2, "../../../scripts/operator.sh");
|
|
229
|
+
const r2 = spawnSync("bash", [op, "init"], { stdio: "inherit", cwd: target });
|
|
230
|
+
process.exit(r2.status ?? 0);
|
|
231
|
+
}
|
|
232
|
+
|
|
217
233
|
// TARGET FIRST, credential second. This used to ask for the registry token, make a
|
|
218
234
|
// network round-trip to validate it, and only then discover the folder was not
|
|
219
235
|
// empty. Never ask for a credential you are about to throw away.
|
package/operator/lib/init.sh
CHANGED
|
@@ -77,22 +77,19 @@ cmd_init() {
|
|
|
77
77
|
echo ""
|
|
78
78
|
fi
|
|
79
79
|
|
|
80
|
-
#
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if [[ ! "$REPLY" =~ ^[Yy]$ ]]; then
|
|
86
|
-
info "Keeping existing .env"
|
|
87
|
-
cmd_login
|
|
88
|
-
cmd_pull
|
|
89
|
-
return
|
|
90
|
-
fi
|
|
91
|
-
fi
|
|
80
|
+
# RE-RUNNING EDITS. There is no "overwrite? [y/N]" gate any more: every existing value
|
|
81
|
+
# becomes its question's default, so Enter keeps a setting and typing replaces it.
|
|
82
|
+
# Walking through changes only what you change — which makes this the way to change
|
|
83
|
+
# one env var, not a destructive restart.
|
|
84
|
+
_env_cur() { grep "^$1=" "$ROOT/.env" 2>/dev/null | head -1 | cut -d= -f2-; }
|
|
92
85
|
|
|
93
86
|
echo ""
|
|
94
87
|
echo -e " ${BOLD}Configure your environment:${NC}"
|
|
95
|
-
|
|
88
|
+
if [ -f "$ROOT/.env" ]; then
|
|
89
|
+
echo -e " ${DIM}(Existing .env found. Enter keeps each current value)${NC}"
|
|
90
|
+
else
|
|
91
|
+
echo -e " ${DIM}(Press Enter to use defaults)${NC}"
|
|
92
|
+
fi
|
|
96
93
|
echo ""
|
|
97
94
|
|
|
98
95
|
# DOCR Token. `unoverse create` has already asked for this and VALIDATED it against
|
|
@@ -102,8 +99,15 @@ cmd_init() {
|
|
|
102
99
|
DOCR_TOKEN="$UNOVERSE_DOCR_TOKEN"
|
|
103
100
|
ok "Registry token carried over from create"
|
|
104
101
|
else
|
|
102
|
+
local cur_token
|
|
103
|
+
cur_token=$(_env_cur DOCR_TOKEN)
|
|
105
104
|
while true; do
|
|
106
|
-
|
|
105
|
+
if [ -n "$cur_token" ]; then
|
|
106
|
+
read -p " DOCR Token [keep current]: " DOCR_TOKEN || { fail "no input (end of stream). Run unoverse init interactively"; exit 1; }
|
|
107
|
+
DOCR_TOKEN="${DOCR_TOKEN:-$cur_token}"
|
|
108
|
+
else
|
|
109
|
+
read -p " DOCR Token (from your Unoverse admin): " DOCR_TOKEN || { fail "no input (end of stream). Run unoverse init interactively"; exit 1; }
|
|
110
|
+
fi
|
|
107
111
|
if [[ "$DOCR_TOKEN" == dop_v1_* ]]; then
|
|
108
112
|
break
|
|
109
113
|
fi
|
|
@@ -114,7 +118,8 @@ cmd_init() {
|
|
|
114
118
|
# A DEFAULT, because "from your admin" is meaningless when you are the admin. The
|
|
115
119
|
# platform ships no database (docker-compose has no postgres), so this points at one
|
|
116
120
|
# you run. Enter takes the conventional local one.
|
|
117
|
-
DB_DEFAULT
|
|
121
|
+
DB_DEFAULT=$(_env_cur DATABASE_URL)
|
|
122
|
+
DB_DEFAULT="${DB_DEFAULT:-postgres://postgres:postgres@localhost:5432/unoverse}"
|
|
118
123
|
while true; do
|
|
119
124
|
read -p " DATABASE_URL [${DB_DEFAULT}]: " DATABASE_URL || { fail "no input (end of stream). Run unoverse init interactively"; exit 1; }
|
|
120
125
|
DATABASE_URL="${DATABASE_URL:-$DB_DEFAULT}"
|
|
@@ -139,17 +144,27 @@ cmd_init() {
|
|
|
139
144
|
fi
|
|
140
145
|
fi
|
|
141
146
|
|
|
142
|
-
# Redis
|
|
143
|
-
|
|
144
|
-
REDIS_HOST="${
|
|
147
|
+
# Redis, current values as defaults
|
|
148
|
+
local rd
|
|
149
|
+
rd=$(_env_cur REDIS_HOST); rd="${rd:-host.docker.internal}"
|
|
150
|
+
read -p " REDIS_HOST [$rd]: " REDIS_HOST
|
|
151
|
+
REDIS_HOST="${REDIS_HOST:-$rd}"
|
|
145
152
|
|
|
146
|
-
|
|
147
|
-
REDIS_PORT
|
|
153
|
+
rd=$(_env_cur REDIS_PORT); rd="${rd:-6379}"
|
|
154
|
+
read -p " REDIS_PORT [$rd]: " REDIS_PORT
|
|
155
|
+
REDIS_PORT="${REDIS_PORT:-$rd}"
|
|
148
156
|
|
|
149
|
-
|
|
157
|
+
rd=$(_env_cur REDIS_PASSWORD)
|
|
158
|
+
if [ -n "$rd" ]; then
|
|
159
|
+
read -p " REDIS_PASSWORD [keep current]: " REDIS_PASSWORD
|
|
160
|
+
REDIS_PASSWORD="${REDIS_PASSWORD:-$rd}"
|
|
161
|
+
else
|
|
162
|
+
read -p " REDIS_PASSWORD (blank for none): " REDIS_PASSWORD
|
|
163
|
+
fi
|
|
150
164
|
|
|
151
|
-
|
|
152
|
-
REDIS_TLS
|
|
165
|
+
rd=$(_env_cur REDIS_TLS); rd="${rd:-false}"
|
|
166
|
+
read -p " REDIS_TLS [$rd]: " REDIS_TLS
|
|
167
|
+
REDIS_TLS="${REDIS_TLS:-$rd}"
|
|
153
168
|
|
|
154
169
|
# Auth (required — from admin)
|
|
155
170
|
# ASK BEFORE DEMANDING. A developer trying the platform locally has no identity
|
|
@@ -160,13 +175,28 @@ cmd_init() {
|
|
|
160
175
|
# rather than trusting this wizard: authConfig.ts refuses to start with auth off when
|
|
161
176
|
# NODE_ENV=production. So answering "no" here cannot produce an unprotected deployment.
|
|
162
177
|
echo ""
|
|
163
|
-
|
|
178
|
+
local cur_auth idp_prompt
|
|
179
|
+
cur_auth=$(_env_cur AUTH_ENABLED)
|
|
180
|
+
idp_prompt="[y/N]"
|
|
181
|
+
[ "$cur_auth" = "true" ] && idp_prompt="[Y/n]"
|
|
182
|
+
read -r -p " Do you have an identity provider (Auth0/OIDC) to connect? $idp_prompt " HAS_IDP
|
|
164
183
|
echo ""
|
|
184
|
+
if [ -z "$HAS_IDP" ] && [ "$cur_auth" = "true" ]; then HAS_IDP=y; fi
|
|
165
185
|
|
|
166
186
|
if [[ "$HAS_IDP" =~ ^[Yy]$ ]]; then
|
|
167
187
|
AUTH_ENABLED=true
|
|
188
|
+
local cur_iss cur_cid cur_aud
|
|
189
|
+
cur_iss=$(_env_cur AUTH_ISSUER)
|
|
190
|
+
cur_cid=$(_env_cur AUTH_CLIENT_ID)
|
|
191
|
+
cur_aud=$(_env_cur AUTH_AUDIENCE)
|
|
192
|
+
|
|
168
193
|
while true; do
|
|
169
|
-
|
|
194
|
+
if [ -n "$cur_iss" ]; then
|
|
195
|
+
read -p " AUTH_ISSUER [$cur_iss]: " AUTH_ISSUER || { fail "no input (end of stream). Run unoverse init interactively"; exit 1; }
|
|
196
|
+
AUTH_ISSUER="${AUTH_ISSUER:-$cur_iss}"
|
|
197
|
+
else
|
|
198
|
+
read -p " AUTH_ISSUER (e.g. https://your-tenant.auth0.com): " AUTH_ISSUER || { fail "no input (end of stream). Run unoverse init interactively"; exit 1; }
|
|
199
|
+
fi
|
|
170
200
|
if [ -n "$AUTH_ISSUER" ] && [[ "$AUTH_ISSUER" == https://* ]]; then
|
|
171
201
|
break
|
|
172
202
|
fi
|
|
@@ -174,15 +204,21 @@ cmd_init() {
|
|
|
174
204
|
done
|
|
175
205
|
|
|
176
206
|
while true; do
|
|
177
|
-
|
|
207
|
+
if [ -n "$cur_cid" ]; then
|
|
208
|
+
read -p " AUTH_CLIENT_ID [$cur_cid]: " AUTH_CLIENT_ID || { fail "no input (end of stream). Run unoverse init interactively"; exit 1; }
|
|
209
|
+
AUTH_CLIENT_ID="${AUTH_CLIENT_ID:-$cur_cid}"
|
|
210
|
+
else
|
|
211
|
+
read -p " AUTH_CLIENT_ID: " AUTH_CLIENT_ID || { fail "no input (end of stream). Run unoverse init interactively"; exit 1; }
|
|
212
|
+
fi
|
|
178
213
|
if [ -n "$AUTH_CLIENT_ID" ] && [[ "$AUTH_CLIENT_ID" != *"your-"* ]]; then
|
|
179
214
|
break
|
|
180
215
|
fi
|
|
181
216
|
fail "AUTH_CLIENT_ID is required"
|
|
182
217
|
done
|
|
183
218
|
|
|
184
|
-
|
|
185
|
-
AUTH_AUDIENCE
|
|
219
|
+
cur_aud="${cur_aud:-gravity-api}"
|
|
220
|
+
read -p " AUTH_AUDIENCE [$cur_aud]: " AUTH_AUDIENCE
|
|
221
|
+
AUTH_AUDIENCE="${AUTH_AUDIENCE:-$cur_aud}"
|
|
186
222
|
else
|
|
187
223
|
AUTH_ENABLED=false
|
|
188
224
|
AUTH_ISSUER=""
|
|
@@ -207,7 +243,14 @@ cmd_init() {
|
|
|
207
243
|
ok "Redis namespace: ${BOLD}${REDIS_NAMESPACE}${NC}"
|
|
208
244
|
|
|
209
245
|
# OpenAI (for Memory Server)
|
|
210
|
-
|
|
246
|
+
local cur_oai
|
|
247
|
+
cur_oai=$(_env_cur OPENAI_API_KEY)
|
|
248
|
+
if [ -n "$cur_oai" ]; then
|
|
249
|
+
read -p " OPENAI_API_KEY [keep current]: " OPENAI_API_KEY
|
|
250
|
+
OPENAI_API_KEY="${OPENAI_API_KEY:-$cur_oai}"
|
|
251
|
+
else
|
|
252
|
+
read -p " OPENAI_API_KEY (for Memory Server, blank to skip): " OPENAI_API_KEY
|
|
253
|
+
fi
|
|
211
254
|
|
|
212
255
|
# Write .env
|
|
213
256
|
cat > "$ROOT/.env" << ENVEOF
|
package/package.json
CHANGED