@ours.network/install 1.2.1-nightly.11 → 1.2.1-nightly.13

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/target.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { serverBase } from './gateway.mjs';
1
2
  // ours-install v3 — argument handling and daemon detection.
2
3
  //
3
4
  // Pure argument handling and daemon-target selection. The orchestrator
@@ -85,17 +86,23 @@ export function validateHostProfile(value) {
85
86
  const mixed = LEGACY_PROFILE_KEYS.filter((key) => Object.hasOwn(value, key));
86
87
  if (mixed.length) throw profileError(`legacy selection keys cannot be mixed with a host profile (${mixed.join(', ')}).`);
87
88
  const { endpoint, expectedInstanceId, credentialPath } = value;
88
- if (typeof endpoint !== 'string' || endpoint.trim() !== endpoint || endpoint === '') throw profileError('endpoint must be a non-empty HTTP or HTTPS origin.');
89
+ if (typeof endpoint !== 'string' || endpoint.trim() !== endpoint || endpoint === '') throw profileError('endpoint must be a non-empty HTTP or HTTPS base URL.');
89
90
  if (typeof expectedInstanceId !== 'string' || !PROFILE_UUID.test(expectedInstanceId)) throw profileError('expectedInstanceId must be a lowercase UUID.');
90
91
  if (typeof credentialPath !== 'string' || credentialPath === '' || !credentialPath.startsWith('/') || resolve(credentialPath) !== credentialPath) {
91
92
  throw profileError('credentialPath must be a normalized absolute path.');
92
93
  }
93
94
  let url;
94
- try { url = new URL(endpoint); } catch { throw profileError('endpoint must be an HTTP or HTTPS origin.'); }
95
- if ((url.protocol !== 'http:' && url.protocol !== 'https:') || url.username || url.password || url.pathname !== '/' || url.search || url.hash) {
96
- throw profileError('endpoint must be an HTTP or HTTPS origin without credentials, path, query, or fragment.');
95
+ try { url = new URL(endpoint); } catch { throw profileError('endpoint must be an HTTP or HTTPS base URL.'); }
96
+ if ((url.protocol !== 'http:' && url.protocol !== 'https:') || url.username || url.password || url.search || url.hash) {
97
+ throw profileError('endpoint must be an HTTP or HTTPS base URL without credentials, query, or fragment.');
97
98
  }
98
- return { endpoint: url.origin, expectedInstanceId, credentialPath };
99
+ const endpointBase = serverBase(endpoint);
100
+ if (value.serverUrl !== undefined) {
101
+ const serverUrl = serverBase(value.serverUrl);
102
+ if (endpointBase !== serverUrl + '/daemon') throw profileError('endpoint must select serverUrl/daemon.');
103
+ return { serverUrl, endpoint: endpointBase, expectedInstanceId, credentialPath };
104
+ }
105
+ return { endpoint: endpointBase, expectedInstanceId, credentialPath };
99
106
  }
100
107
 
101
108
  export function resolveProfileSelection({ args, env = {}, home = homedir(), exists, readProfile }) {
@@ -454,10 +461,11 @@ export function searchFreePort(isTaken, { floor = FREE_PORT_FLOOR, reserved = IN
454
461
  export function parseNetworkArgs(argv) {
455
462
  if (!['server', 'client'].includes(argv[0])) return null;
456
463
  const [role, operation] = argv;
457
- const operations = role === 'client' ? ['install'] : ['install', 'status', 'start', 'stop', 'restart', 'access-issue', 'access-replace', 'backup', 'restore', 'reset', 'update', 'rebuild'];
464
+ const operations = role === 'client' ? ['install'] : ['install', 'status', 'start', 'stop', 'restart', 'access-issue', 'access-replace', 'backup', 'restore', 'reset', 'update', 'rebuild', 'gateway-enable'];
458
465
  if (!operations.includes(operation)) throw new InstallUsageError(`Unsupported ${role} operation: ${operation ?? '(missing)'}`);
459
466
  const allowed = role === 'client' ? ['config'] : ['state-dir'];
460
467
  if (role === 'server' && operation === 'install') allowed.push('mode', 'sources', 'migrate');
468
+ if (role === 'server' && ['install', 'gateway-enable'].includes(operation)) allowed.push('server-url');
461
469
  if (operation === 'access-issue') allowed.push('output');
462
470
  if (['access-replace', 'reset'].includes(operation)) allowed.push('confirm');
463
471
  if (['restore', 'update'].includes(operation)) allowed.push('compatible');
@@ -486,7 +494,7 @@ export function parseNetworkArgs(argv) {
486
494
  } else {
487
495
  const value = inline ?? argv[++i];
488
496
  if (!value || value.startsWith('--')) throw new InstallUsageError(`--${name} requires a value`);
489
- result[key] = name === 'mode' ? value : resolve(value);
497
+ result[key] = name === 'mode' ? value : name === 'server-url' ? serverBase(value) : resolve(value);
490
498
  }
491
499
  }
492
500
  const required = role === 'client' ? [] : ['stateDir'];
package/lib/usage.mjs CHANGED
@@ -29,6 +29,7 @@ export const USAGE = `ours-install — interactive setup or complete CLI presets
29
29
  --config PATH complete connection profile for client-only setup
30
30
  --sources PATH explicit full development source policy override
31
31
  --port N daemon port (default 3050 on a fresh installation)
32
+ --server-url URL external gateway URL (Docker install; configure authenticated entry separately)
32
33
  --cowork-port N cowork port (default 3052)
33
34
  --messenger-port N messenger port (default 8420)
34
35
  --compatible required for server updates and legacy state migration
@@ -46,6 +47,7 @@ Fleet is configured but left stopped for operator review.
46
47
 
47
48
  Scoped maintenance:
48
49
  ours-install server status|start|stop|restart|rebuild --state-dir PATH
50
+ ours-install server gateway-enable --state-dir PATH [--server-url URL]
49
51
  ours-install server access-issue --state-dir PATH --output PATH
50
52
  ours-install server access-replace --state-dir PATH --confirm
51
53
  ours-install server backup|restore server|daemon|telegram|cowork|messenger LABEL --state-dir PATH
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/install",
3
- "version": "1.2.1-nightly.11",
3
+ "version": "1.2.1-nightly.13",
4
4
  "private": false,
5
5
  "description": "The all-in-one ours.network installer: one shared daemon, MCP, cowork, Telegram, Fleet initialization, harness plugins, Human identity, progress UI, and guided next steps.",
6
6
  "type": "module",