@aifabrix/builder 2.44.6 → 2.45.0

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 (86) hide show
  1. package/.cursor/rules/cli-layout.mdc +7 -3
  2. package/jest.projects.js +56 -0
  3. package/lib/app/helpers.js +3 -3
  4. package/lib/app/index.js +3 -3
  5. package/lib/app/register.js +7 -6
  6. package/lib/app/restart-display.js +52 -21
  7. package/lib/app/rotate-secret.js +7 -6
  8. package/lib/app/run-helpers.js +15 -8
  9. package/lib/app/run.js +57 -9
  10. package/lib/app/show-display.js +7 -0
  11. package/lib/app/show.js +87 -5
  12. package/lib/build/index.js +9 -5
  13. package/lib/cli/infra-guided.js +42 -27
  14. package/lib/cli/installation-log-command.js +73 -0
  15. package/lib/cli/setup-app.js +11 -1
  16. package/lib/cli/setup-auth.js +94 -49
  17. package/lib/cli/setup-infra-up-dataplane-action.js +111 -0
  18. package/lib/cli/setup-infra-up-platform-action.js +131 -0
  19. package/lib/cli/setup-infra.js +60 -119
  20. package/lib/cli/setup-platform.js +1 -1
  21. package/lib/cli/setup-utility-resolve.js +132 -0
  22. package/lib/cli/setup-utility.js +65 -51
  23. package/lib/commands/app-logs.js +81 -33
  24. package/lib/commands/auth-config.js +116 -18
  25. package/lib/commands/setup-modes.js +19 -6
  26. package/lib/commands/setup-prompts.js +41 -8
  27. package/lib/commands/setup.js +114 -9
  28. package/lib/commands/teardown.js +54 -5
  29. package/lib/commands/up-common.js +48 -14
  30. package/lib/commands/up-dataplane.js +21 -18
  31. package/lib/commands/up-miso.js +12 -8
  32. package/lib/commands/upload.js +5 -3
  33. package/lib/core/audit-logger.js +1 -34
  34. package/lib/core/config-admin-email.js +56 -0
  35. package/lib/core/config-normalize.js +60 -0
  36. package/lib/core/config-registered-controller-urls.js +54 -0
  37. package/lib/core/config.js +33 -50
  38. package/lib/core/secrets-ensure-infra.js +1 -1
  39. package/lib/core/secrets-env-content.js +86 -90
  40. package/lib/core/secrets-env-declarative-expand.js +170 -0
  41. package/lib/core/secrets-env-write.js +2 -0
  42. package/lib/core/secrets-load.js +106 -102
  43. package/lib/external-system/deploy.js +5 -1
  44. package/lib/internal/node-fs.js +2 -0
  45. package/lib/schema/application-schema.json +4 -0
  46. package/lib/schema/infra.parameter.yaml +10 -0
  47. package/lib/utils/app-config-resolver.js +24 -1
  48. package/lib/utils/applications-config-defaults.js +206 -0
  49. package/lib/utils/auth-config-validator.js +2 -12
  50. package/lib/utils/bash-secret-env.js +1 -1
  51. package/lib/utils/compose-generate-docker-compose.js +111 -6
  52. package/lib/utils/compose-generator.js +17 -8
  53. package/lib/utils/controller-url.js +50 -7
  54. package/lib/utils/env-copy.js +99 -14
  55. package/lib/utils/env-template.js +5 -1
  56. package/lib/utils/health-check-url.js +18 -15
  57. package/lib/utils/health-check.js +7 -5
  58. package/lib/utils/infra-optional-service-flags.js +69 -0
  59. package/lib/utils/installation-log-core.js +282 -0
  60. package/lib/utils/installation-log-record.js +237 -0
  61. package/lib/utils/installation-log.js +123 -0
  62. package/lib/utils/log-redaction.js +105 -0
  63. package/lib/utils/manifest-location.js +164 -0
  64. package/lib/utils/manifest-source-emit.js +162 -0
  65. package/lib/utils/paths.js +238 -89
  66. package/lib/utils/remote-secrets-loader.js +7 -1
  67. package/lib/utils/run-cli-flags.js +29 -0
  68. package/lib/utils/secrets-canonical.js +10 -3
  69. package/lib/utils/secrets-path.js +3 -4
  70. package/lib/utils/secrets-utils.js +20 -10
  71. package/lib/utils/system-builder-root.js +10 -2
  72. package/lib/utils/url-declarative-public-base.js +80 -12
  73. package/lib/utils/url-declarative-resolve-build-urls.js +238 -0
  74. package/lib/utils/url-declarative-resolve-build.js +24 -393
  75. package/lib/utils/url-declarative-resolve-expand-token.js +189 -0
  76. package/lib/utils/url-declarative-resolve-load-doc.js +12 -3
  77. package/lib/utils/url-declarative-resolve-surface-state.js +102 -0
  78. package/lib/utils/url-declarative-resolve.js +47 -7
  79. package/lib/utils/url-declarative-runtime-base-path.js +21 -1
  80. package/lib/utils/urls-local-registry-scan.js +103 -0
  81. package/lib/utils/urls-local-registry.js +161 -90
  82. package/package.json +3 -1
  83. package/templates/applications/dataplane/application.yaml +4 -0
  84. package/templates/applications/miso-controller/application.yaml +2 -0
  85. package/templates/applications/miso-controller/env.template +27 -29
  86. package/.npmrc.token +0 -1
@@ -1,8 +1,14 @@
1
1
  /**
2
- * Primary `urls.local.yaml` under {@link module:lib/utils/paths.getAifabrixHome} (same as
3
- * `secrets.local.yaml`). When that file is missing, falls back to the config directory for migration.
2
+ * Primary `urls.local.yaml` beside `config.yaml` (same directory as {@link module:lib/utils/paths.getConfigDirForPaths}),
3
+ * aligned with `secrets.local.yaml`. When missing, {@link readUrlsLocalRegistrySync} may read a legacy
4
+ * file under {@link module:lib/utils/paths.getAifabrixHome} (older releases when `aifabrix-home` was `$HOME`).
4
5
  *
5
- * @fileoverview Read/write registry; scan each builder app folder for application.yaml
6
+ * Per-app keys (see {@link mergeDocIntoRegistry}): `appKey-port`, `appKey-pattern`, `appKey-containerPort`,
7
+ * optional `appKey-internalDockerUseOriginOnly` (boolean) — overrides `frontDoorRouting.internalDockerUseOriginOnly`
8
+ * for declarative `url://` resolution when set (e.g. Keycloak internal URL without `/auth` when true).
9
+ *
10
+ * @fileoverview Read/write registry; scan builder/package dirs in canonical order (plan 141 P3).
11
+ * Duplicate `app.key`: last scan directory wins — no cross-root mtime merge or `AIFABRIX_BUILDER_DIR` ordering.
6
12
  * @author AI Fabrix Team
7
13
  * @version 1.0.0
8
14
  */
@@ -14,17 +20,18 @@ const path = require('path');
14
20
  const yaml = require('js-yaml');
15
21
  const { DECLARATIVE_URL_INFRA_DEFAULTS } = require('./infra-env-defaults');
16
22
  const pathsUtil = require('./paths');
23
+ const { collectLatestApplicationYamlEntriesPerApp } = require('./urls-local-registry-scan');
17
24
 
18
25
  /**
19
- * @returns {string} Absolute path to urls.local.yaml (primary; under resolved AI Fabrix home)
26
+ * @returns {string} Absolute path to urls.local.yaml (beside config.yaml)
20
27
  */
21
28
  function getUrlsLocalYamlPath() {
22
- return path.join(pathsUtil.getAifabrixHome(), 'urls.local.yaml');
29
+ return path.join(pathsUtil.getConfigDirForPaths(), 'urls.local.yaml');
23
30
  }
24
31
 
25
- /** @returns {string} Path beside config.yaml (migration / older layouts) */
26
- function getConfigDirUrlsLocalYamlPath() {
27
- return path.join(pathsUtil.getConfigDirForPaths(), 'urls.local.yaml');
32
+ /** @returns {string} Legacy primary path from older CLI (under resolved AI Fabrix home) */
33
+ function getLegacyUrlsLocalYamlPathAtAifabrixHome() {
34
+ return path.join(pathsUtil.getAifabrixHome(), 'urls.local.yaml');
28
35
  }
29
36
 
30
37
  function loadRegistryYamlFile(filePath) {
@@ -44,9 +51,9 @@ function readUrlsLocalRegistrySync() {
44
51
  if (fsRealSync.existsSync(primary)) {
45
52
  return loadRegistryYamlFile(primary);
46
53
  }
47
- const atConfig = getConfigDirUrlsLocalYamlPath();
48
- if (path.resolve(atConfig) !== path.resolve(primary) && fsRealSync.existsSync(atConfig)) {
49
- return loadRegistryYamlFile(atConfig);
54
+ const legacy = getLegacyUrlsLocalYamlPathAtAifabrixHome();
55
+ if (path.resolve(legacy) !== path.resolve(primary) && fsRealSync.existsSync(legacy)) {
56
+ return loadRegistryYamlFile(legacy);
50
57
  }
51
58
  return {};
52
59
  }
@@ -90,22 +97,6 @@ function writeMergedRegistry(merged) {
90
97
  return merged;
91
98
  }
92
99
 
93
- /**
94
- * @param {string} cfgPath
95
- * @returns {object|null}
96
- */
97
- function tryLoadApplicationYaml(cfgPath) {
98
- if (!fsRealSync.existsSync(cfgPath)) {
99
- return null;
100
- }
101
- try {
102
- const doc = yaml.load(fsRealSync.readFileSync(cfgPath, 'utf8'));
103
- return doc && typeof doc === 'object' ? doc : null;
104
- } catch {
105
- return null;
106
- }
107
- }
108
-
109
100
  /**
110
101
  * @param {object} doc
111
102
  * @returns {number|null}
@@ -152,114 +143,193 @@ function mergeDocIntoRegistry(merged, doc, folderName) {
152
143
  } else {
153
144
  delete merged[ckey];
154
145
  }
146
+
147
+ mergeInternalDockerOriginOnlyRegistryKeyFromDoc(merged, appKey, doc);
155
148
  }
156
149
 
157
150
  /**
151
+ * When `application.yaml` explicitly sets `frontDoorRouting.internalDockerUseOriginOnly`, mirror it into
152
+ * `urls.local.yaml` on refresh. If the property is absent, leave any existing registry value unchanged
153
+ * (supports hand-edited `appKey-internalDockerUseOriginOnly` without a YAML field).
154
+ *
158
155
  * @param {Object} merged
159
- * @param {string} builderDir
156
+ * @param {string} appKey
157
+ * @param {object} doc
160
158
  */
161
- function mergeBuilderDirIntoRegistry(merged, builderDir) {
162
- if (!builderDir || !fsRealSync.existsSync(builderDir) || !fsRealSync.statSync(builderDir).isDirectory()) {
159
+ function mergeInternalDockerOriginOnlyRegistryKeyFromDoc(merged, appKey, doc) {
160
+ const key = `${appKey}-internalDockerUseOriginOnly`;
161
+ const fd = doc && doc.frontDoorRouting;
162
+ if (!fd || typeof fd !== 'object') {
163
163
  return;
164
164
  }
165
- for (const ent of fsRealSync.readdirSync(builderDir, { withFileTypes: true })) {
166
- if (!ent.isDirectory()) {
167
- continue;
168
- }
169
- const doc = tryLoadApplicationYaml(path.join(builderDir, ent.name, 'application.yaml'));
170
- if (!doc) {
171
- continue;
172
- }
173
- mergeDocIntoRegistry(merged, doc, ent.name);
165
+ if (!Object.prototype.hasOwnProperty.call(fd, 'internalDockerUseOriginOnly')) {
166
+ return;
167
+ }
168
+ const v = fd.internalDockerUseOriginOnly;
169
+ if (v === true) {
170
+ merged[key] = true;
171
+ } else if (v === false) {
172
+ merged[key] = false;
173
+ } else {
174
+ delete merged[key];
174
175
  }
175
176
  }
176
177
 
177
178
  /**
178
- * True when getBuilderRoot() resolves to the same path as AIFABRIX_BUILDER_DIR (authoritative override).
179
- * @param {string|null} resolvedEffective
180
- * @param {string|null} envResolved
181
- * @returns {boolean}
179
+ * Append a directory to the scan list when it exists, is a directory, and is not already included (resolved).
180
+ * Later entries win duplicate `app.key` merges (see {@link collectLatestApplicationYamlEntriesPerApp}).
181
+ *
182
+ * @param {string[]} scanDirs
183
+ * @param {string|null|undefined} dirPath
184
+ * @returns {void}
182
185
  */
183
- function effectiveBuilderMatchesEnvVar(resolvedEffective, envResolved) {
184
- return Boolean(envResolved && resolvedEffective && resolvedEffective === envResolved);
186
+ function pushUniqueScanDir(scanDirs, dirPath) {
187
+ if (!dirPath || typeof dirPath !== 'string') {
188
+ return;
189
+ }
190
+ let resolved;
191
+ try {
192
+ resolved = path.resolve(dirPath);
193
+ } catch {
194
+ return;
195
+ }
196
+ try {
197
+ if (!fsRealSync.existsSync(resolved) || !fsRealSync.statSync(resolved).isDirectory()) {
198
+ return;
199
+ }
200
+ } catch {
201
+ return;
202
+ }
203
+ for (const existing of scanDirs) {
204
+ try {
205
+ if (path.resolve(existing) === resolved) {
206
+ return;
207
+ }
208
+ } catch {
209
+ // ignore
210
+ }
211
+ }
212
+ scanDirs.push(resolved);
185
213
  }
186
214
 
187
215
  /**
188
- * Builder dirs to scan in order; later merges overwrite registry keys from earlier dirs.
189
- * When `AIFABRIX_BUILDER_DIR` is set and differs from projectRoot/builder, env builder root is merged last.
190
- * Otherwise projectRoot/builder is merged last so explicit refresh roots override getBuilderRoot().
191
- *
192
- * @param {string} root - Resolved project root passed to refresh
193
- * @param {string|null} effectiveBuilderDir - pathsUtil.getBuilderRoot()
194
216
  * @returns {string[]}
195
217
  */
196
- function getOrderedBuilderDirsForRegistryScan(root, effectiveBuilderDir) {
197
- const legacyBuilderDir = path.join(root, 'builder');
198
- let resolvedLegacy;
199
- let resolvedEffective;
218
+ function getPackageBuilderLikeDirsForRegistryScan() {
219
+ const out = [];
200
220
  try {
201
- resolvedLegacy = path.resolve(legacyBuilderDir);
202
- resolvedEffective = effectiveBuilderDir ? path.resolve(effectiveBuilderDir) : null;
221
+ out.push(path.join(pathsUtil.getIntegrationBuilderBaseDir(), 'packages'));
203
222
  } catch {
204
- return [legacyBuilderDir];
223
+ // ignore
224
+ }
225
+ try {
226
+ const pr = pathsUtil.getProjectRoot();
227
+ if (pr) {
228
+ out.push(path.join(pr, 'packages'));
229
+ }
230
+ } catch {
231
+ // ignore
205
232
  }
206
- const envRaw = process.env.AIFABRIX_BUILDER_DIR && String(process.env.AIFABRIX_BUILDER_DIR).trim();
207
- const envResolved = envRaw ? path.resolve(envRaw) : null;
208
- // Only treat env as authoritative when getBuilderRoot() is actually that path. Otherwise a stray
209
- // AIFABRIX_BUILDER_DIR on CI (or Jest mocking getBuilderRoot to a temp dir) must not force
210
- // [legacy, effective] — that order lets the real checkout builder overwrite the mocked root last.
211
- const effectiveMatchesEnvVar = effectiveBuilderMatchesEnvVar(resolvedEffective, envResolved);
233
+ return out;
234
+ }
212
235
 
213
- if (effectiveBuilderDir && resolvedEffective && resolvedEffective === resolvedLegacy) {
214
- return [legacyBuilderDir];
236
+ /**
237
+ * Canonical builder/package scan roots (low → high priority). Plan 141 P3: fixed order replaces
238
+ * mtime merge and `AIFABRIX_BUILDER_DIR` scan ordering; `findProjectRootFromCwd` builder is last when enabled.
239
+ *
240
+ * @param {string|null} root
241
+ * @param {string|null} effectiveBuilderDir
242
+ * @param {{ excludeCwdBuilderScan?: boolean }} opts
243
+ * @returns {string[]}
244
+ */
245
+ function buildCanonicalRegistryScanDirs(root, effectiveBuilderDir, opts = {}) {
246
+ const scanDirs = [];
247
+ pushUniqueScanDir(scanDirs, pathsUtil.getSystemBuilderRoot());
248
+ pushUniqueScanDir(scanDirs, effectiveBuilderDir);
249
+ if (root) {
250
+ pushUniqueScanDir(scanDirs, path.join(root, 'builder'));
215
251
  }
216
- if (effectiveMatchesEnvVar && effectiveBuilderDir && resolvedEffective && resolvedEffective !== resolvedLegacy) {
217
- return [legacyBuilderDir, effectiveBuilderDir];
252
+ for (const pkg of getPackageBuilderLikeDirsForRegistryScan()) {
253
+ pushUniqueScanDir(scanDirs, pkg);
218
254
  }
219
- if (effectiveBuilderDir && resolvedEffective && resolvedEffective !== resolvedLegacy) {
220
- return [effectiveBuilderDir, legacyBuilderDir];
255
+ if (!opts.excludeCwdBuilderScan) {
256
+ let cwdRoot = null;
257
+ try {
258
+ cwdRoot = pathsUtil.findProjectRootFromCwd();
259
+ } catch {
260
+ cwdRoot = null;
261
+ }
262
+ if (cwdRoot && typeof cwdRoot === 'string') {
263
+ pushUniqueScanDir(scanDirs, path.join(cwdRoot, 'builder'));
264
+ }
221
265
  }
222
- return [legacyBuilderDir];
266
+ return scanDirs;
223
267
  }
224
268
 
225
269
  /**
226
270
  * Merge scan results into registry (does not remove stale keys).
227
271
  * @param {string|null} projectRoot - getProjectRoot() or null (same semantics as projectRoot || getProjectRoot())
272
+ * @param {{ excludeCwdBuilderScan?: boolean }} [opts] - When `excludeCwdBuilderScan` is true, omit cwd
273
+ * checkout `builder/` (tests / `ctx.projectRoot` isolation — avoids merging ambient repo `builder/`).
228
274
  * @returns {Object} Updated registry
229
275
  */
230
- function refreshUrlsLocalRegistryFromBuilder(projectRoot) {
276
+ function refreshUrlsLocalRegistryFromBuilder(projectRoot, opts) {
277
+ const o = opts && typeof opts === 'object' ? opts : {};
231
278
  const root = projectRoot || pathsUtil.getProjectRoot();
232
279
  const merged = { ...readUrlsLocalRegistrySync() };
233
280
  if (!root) {
234
281
  return writeMergedRegistry(merged);
235
282
  }
236
- // Published npm tarball omits builder/ under the package root (.npmignore). Global installs must
237
- // still refresh from the real builder tree (AIFABRIX_BUILDER_DIR or integration base + builder).
283
+ // Published npm tarball omits builder/ under the package root (.npmignore). Global installs still
284
+ // resolve materialized apps via getBuilderRoot() (same parent as getSystemBuilderRoot when aligned).
238
285
  let effectiveBuilderDir = null;
239
286
  try {
240
287
  effectiveBuilderDir = pathsUtil.getBuilderRoot();
241
288
  } catch {
242
289
  effectiveBuilderDir = null;
243
290
  }
244
- let builderDirs = getOrderedBuilderDirsForRegistryScan(root, effectiveBuilderDir);
245
- try {
246
- const sysRoot = pathsUtil.getSystemBuilderRoot();
247
- const resolvedSys = path.resolve(sysRoot);
248
- if (fsRealSync.existsSync(sysRoot)) {
249
- const resolvedList = builderDirs.map((d) => path.resolve(d));
250
- if (!resolvedList.includes(resolvedSys)) {
251
- builderDirs = [sysRoot, ...builderDirs];
252
- }
253
- }
254
- } catch {
255
- // ignore
256
- }
257
- for (const builderDir of builderDirs) {
258
- mergeBuilderDirIntoRegistry(merged, builderDir);
291
+ const scanDirs = buildCanonicalRegistryScanDirs(root, effectiveBuilderDir, o);
292
+ const entries = collectLatestApplicationYamlEntriesPerApp(scanDirs);
293
+ for (const { folderName, doc } of entries) {
294
+ mergeDocIntoRegistry(merged, doc, folderName);
259
295
  }
260
296
  return writeMergedRegistry(merged);
261
297
  }
262
298
 
299
+ const REGISTRY_BOOL_TRUE = new Set([true, 'true', 'yes', 'on', 1, '1']);
300
+ const REGISTRY_BOOL_FALSE = new Set([false, 'false', 'no', 'off', 0, '0']);
301
+
302
+ /**
303
+ * @param {unknown} raw
304
+ * @returns {boolean|undefined}
305
+ */
306
+ function coerceRegistryBool(raw) {
307
+ if (REGISTRY_BOOL_TRUE.has(raw)) {
308
+ return true;
309
+ }
310
+ if (REGISTRY_BOOL_FALSE.has(raw)) {
311
+ return false;
312
+ }
313
+ return undefined;
314
+ }
315
+
316
+ /**
317
+ * Optional `appKey-internalDockerUseOriginOnly` in `urls.local.yaml` (boolean or common string coercions).
318
+ * When set, declarative URL resolution uses this value instead of (or in addition to) `application.yaml`.
319
+ *
320
+ * @param {string} appKey
321
+ * @param {Object|null|undefined} registry
322
+ * @returns {boolean|undefined} undefined when the key is absent or not coercible to boolean
323
+ */
324
+ function readRegistryInternalDockerUseOriginOnly(appKey, registry) {
325
+ const r = registry && typeof registry === 'object' ? registry : {};
326
+ const key = `${appKey}-internalDockerUseOriginOnly`;
327
+ if (!Object.prototype.hasOwnProperty.call(r, key)) {
328
+ return undefined;
329
+ }
330
+ return coerceRegistryBool(r[key]);
331
+ }
332
+
263
333
  /**
264
334
  * @param {string} appKey
265
335
  * @param {Object} registry
@@ -293,5 +363,6 @@ module.exports = {
293
363
  writeUrlsLocalRegistrySync,
294
364
  refreshUrlsLocalRegistryFromBuilder,
295
365
  normalizePatternForUrl,
296
- getRegistryEntryForApp
366
+ getRegistryEntryForApp,
367
+ readRegistryInternalDockerUseOriginOnly
297
368
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aifabrix/builder",
3
- "version": "2.44.6",
3
+ "version": "2.45.0",
4
4
  "description": "AI Fabrix Local Fabric & Deployment SDK",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -36,6 +36,8 @@
36
36
  "precommit": "npm run lint:fix && npm run test",
37
37
  "install:local": "node scripts/install-local.js && which aifabrix && which af",
38
38
  "uninstall:local": "node scripts/install-local.js uninstall && which aifabrix && which af",
39
+ "install:global": "npm install -g . --force && which aifabrix && which af && aifabrix --version",
40
+ "uninstall:global": "npm uninstall -g @aifabrix/builder",
39
41
  "diagnose:cli": "node scripts/diagnose-cli.js",
40
42
  "check:schema-sync": "node scripts/check-datasource-test-run-schema-sync.js",
41
43
  "check:flags": "jest tests/lib/schema/flag-map-validation-run.test.js --runInBand --config jest.config.default.js"
@@ -26,6 +26,8 @@ environmentScopedResources: true
26
26
  frontDoorRouting:
27
27
  pattern: /data/*
28
28
  enabled: true
29
+ # Docker url://internal full URLs: http://dataplane:PORT only (ingress /data is not on in-container routes).
30
+ internalDockerUseOriginOnly: false
29
31
  host: ${DEV_USERNAME}.${REMOTE_HOST}
30
32
  tls: ${TLS_ENABLED}
31
33
 
@@ -63,6 +65,8 @@ build:
63
65
  envOutputPath: ../../.env # Copy to repo root for local dev
64
66
  language: python # Runtime language for template selection (typescript or python)
65
67
  reloadStart: uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-3001} --reload # PORT set from port above at run time; default 3001 must match port
68
+ # Pulled-image local compose (no bind-mount): drives `command` in generated docker-compose. Override for non-standard images (e.g. stub ACR tags).
69
+ imageRun: exec python -m uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-3001}
66
70
 
67
71
  # =============================================================================
68
72
  # Portal Input Configuration (Deployment Wizard)
@@ -23,6 +23,8 @@ port: 3000
23
23
  frontDoorRouting:
24
24
  pattern: /miso/*
25
25
  enabled: true
26
+ # Docker url://internal full URLs: http://miso-controller:PORT only (ingress /miso is not on in-container routes).
27
+ internalDockerUseOriginOnly: false
26
28
  host: ${DEV_USERNAME}.${REMOTE_HOST}
27
29
  tls: ${TLS_ENABLED}
28
30
 
@@ -57,7 +57,6 @@ NODE_ENV=dev
57
57
  PORT=${PORT}
58
58
  AUTO_CREATE_TABLES=true
59
59
  FAST_STARTUP=false
60
- ALLOWED_ORIGINS=http://localhost:*,url://host-public,url://host-private,url://dataplane-host-public,url://dataplane-host-private
61
60
  ENABLE_API_DOCS=true
62
61
 
63
62
  # Rate Limiting Configuration (for local development)
@@ -141,6 +140,33 @@ KEYCLOAK_EVENTS_SECRET=kv://keycloak-events-secretKeyVault
141
140
  WAIT_FOR_KEYCLOAK=true
142
141
  # KEYCLOAK_WAIT_TIMEOUT=60
143
142
 
143
+ # =============================================================================
144
+ # MISO CONTROLLER CONFIGURATION
145
+ # =============================================================================
146
+ # Web Server URL (for OpenAPI documentation server URLs and Keycloak callbacks)
147
+ # This is the PUBLIC-FACING URL that browsers/users access (e.g., http://localhost:3100)
148
+ # Used to generate correct server URLs in OpenAPI spec and Keycloak callback URLs
149
+ # For Docker: use localhost with mapped port (e.g., localhost:3100)
150
+ # For production: use public domain (e.g., https://miso.example.com)
151
+ # url://public includes front-door path from application.yaml (e.g. /controller).
152
+ MISO_WEB_SERVER_URL=url://public
153
+ MISO_CONTROLLER_URL=url://internal
154
+ MISO_RELATIVE_PATH=url://vdir-public
155
+ ALLOWED_ORIGINS=http://localhost:*,url://host-public,url://host-private,url://dataplane-host-public,url://dataplane-host-private
156
+
157
+ # MISO Environment Configuration (miso, dev, tst, pro)
158
+ MISO_ENVIRONMENT=miso
159
+
160
+ # MISO Application Client Credentials (per application)
161
+ MISO_CLIENTID=kv://miso-controller-client-idKeyVault
162
+ MISO_CLIENTSECRET=kv://miso-controller-client-secretKeyVault
163
+
164
+ # Evaluation mode (optional .env override of DB controller.configuration.evaluation):
165
+ # When true (default if DB omits flag), infra deploy may coerce :envKey to `miso` — e2e poll on `dev` can 404.
166
+ # Set false locally to force path envKey to match deploy + GET .../deployments/:id.
167
+ # Unset = use DB only.
168
+ CONTROLLER_EVALUATION=
169
+
144
170
  # =============================================================================
145
171
  # TENANT ACTIVATION (TA-3) — EXISTING LLM CATALOG
146
172
  # =============================================================================
@@ -301,34 +327,6 @@ JWT_SECRET=kv://miso-controller-jwt-secretKeyVault
301
327
  # When API_KEY is set, a matching Bearer token bypasses OAuth2 validation
302
328
  API_KEY=kv://miso-controller-secrets-apiKeyVault
303
329
 
304
- # NPM token for private package (npmjs.org)
305
- NPM_TOKEN=kv://BASH_NPM_TOKEN
306
-
307
- # =============================================================================
308
- # MISO CONTROLLER CONFIGURATION
309
- # =============================================================================
310
- # Web Server URL (for OpenAPI documentation server URLs and Keycloak callbacks)
311
- # This is the PUBLIC-FACING URL that browsers/users access (e.g., http://localhost:3100)
312
- # Used to generate correct server URLs in OpenAPI spec and Keycloak callback URLs
313
- # For Docker: use localhost with mapped port (e.g., localhost:3100)
314
- # For production: use public domain (e.g., https://miso.example.com)
315
- # url://public includes front-door path from application.yaml (e.g. /controller).
316
- MISO_WEB_SERVER_URL=url://public
317
- MISO_CONTROLLER_URL=url://internal
318
- MISO_RELATIVE_PATH=url://vdir-public
319
- # MISO Environment Configuration (miso, dev, tst, pro)
320
- MISO_ENVIRONMENT=miso
321
-
322
- # MISO Application Client Credentials (per application)
323
- MISO_CLIENTID=kv://miso-controller-client-idKeyVault
324
- MISO_CLIENTSECRET=kv://miso-controller-client-secretKeyVault
325
-
326
- # Evaluation mode (optional .env override of DB controller.configuration.evaluation):
327
- # When true (default if DB omits flag), infra deploy may coerce :envKey to `miso` — e2e poll on `dev` can 404.
328
- # Set false locally to force path envKey to match deploy + GET .../deployments/:id.
329
- # Unset = use DB only.
330
- CONTROLLER_EVALUATION=
331
-
332
330
  # =============================================================================
333
331
  # LICENSE CONFIGURATION
334
332
  # =============================================================================
package/.npmrc.token DELETED
@@ -1 +0,0 @@
1
- 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