@ours.network/install 1.2.1-nightly.22 → 1.2.1-nightly.23

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/README.md CHANGED
@@ -567,3 +567,14 @@ Workspace setup automatically reuses the saved managed gateway profile (or expli
567
567
  Fresh image builds explicitly make non-secret maintenance/runtime scripts readable by the container user even when the host build context was copied under umask077. Host scripts, selected source policy and state retain their private permissions.
568
568
 
569
569
  For a pending installation using an older image, run the corrected installer against the same pending workspace. It recognizes older shipped script COPY instructions combined with private host script modes, updates those image COPY modes and rebuilds the daemon image from the retained source selection. It leaves host data and enrollment state intact and qualifies the rebuilt image before preparing services. A private retry marker retains the rebuild requirement after interruption; it is removed only after verification succeeds. This rebuild resolves third-party transitive dependencies using the existing testing-delivery rules; selected Ours versions and integrity remain release-checked. It is not a byte-identical image permission-layer repair.
570
+
571
+ Fresh server setup checks its loopback daemon, Cowork and Messenger ports before
572
+ writing the installation configuration. Occupied implicit defaults advance to a
573
+ free port, skipping reserved sibling ports; the selected values are saved in the
574
+ installation record and used by native/container services, gateway and client
575
+ profile generation. An explicitly requested occupied port fails with a diagnostic.
576
+ Existing installation records keep their ports and identities. A listener acquired
577
+ by another process after preflight still causes startup to fail safely; no foreign
578
+ process is stopped and no retained installation is silently moved.
579
+
580
+ Workspace setup pins Fleet `1.2.0-nightly.31` with its recorded registry integrity. This release includes the packaged `/fleet` browser entry and persists the available Fleet loopback port used by the workspace tunnel. Existing installation identities and configured ports remain retained; a retained-port collision fails safely.
@@ -13,7 +13,7 @@
13
13
  "@ours.network/codex": "1.2.0-nightly.10",
14
14
  "@ours.network/cowork": "1.3.3-nightly.20261001.6d49d3a",
15
15
  "@ours.network/daemon": "3.8.1-nightly.7",
16
- "@ours.network/fleet": "1.2.0-nightly.30",
16
+ "@ours.network/fleet": "1.2.0-nightly.31",
17
17
  "@ours.network/mcp": "1.2.0-nightly.10",
18
18
  "@ours.network/messenger-server": "1.0.31-nightly.13",
19
19
  "@ours.network/sdk": "3.8.1-nightly.15",
@@ -1085,9 +1085,9 @@
1085
1085
  }
1086
1086
  },
1087
1087
  "node_modules/@ours.network/fleet": {
1088
- "version": "1.2.0-nightly.30",
1089
- "resolved": "https://registry.npmjs.org/@ours.network/fleet/-/fleet-1.2.0-nightly.30.tgz",
1090
- "integrity": "sha512-rZJqVpg2KSWOvDQxWs/nDlDwJ5VapZO7BK5RKFfv22FJgELArrO5/os03+J1sFazLlHv2qf93iBJ+Ht04h6B7Q==",
1088
+ "version": "1.2.0-nightly.31",
1089
+ "resolved": "https://registry.npmjs.org/@ours.network/fleet/-/fleet-1.2.0-nightly.31.tgz",
1090
+ "integrity": "sha512-45oIV09WCsK5yEZF8IKU8LEJjC4Hk26XG/OeA+BqxSFvQWEXoHhMhLeabP5Jc9QcDcEmtH5AeYKXRvCXTeb+YA==",
1091
1091
  "license": "FSL-1.1-Apache-2.0",
1092
1092
  "dependencies": {
1093
1093
  "@agentclientprotocol/sdk": "^1.3.0",
@@ -2313,9 +2313,9 @@
2313
2313
  "license": "ISC"
2314
2314
  },
2315
2315
  "node_modules/ip-address": {
2316
- "version": "10.7.2",
2317
- "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.2.tgz",
2318
- "integrity": "sha512-7H/2gFSIitxc0hG3nOI1glS8QLo/EHBFFLk8vEUjXY/xu0AdL8jZ9U1IzO2PUm0d2D/ofQcAifb0g6OBkt8U7w==",
2316
+ "version": "10.7.3",
2317
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.3.tgz",
2318
+ "integrity": "sha512-A1kdq/tSb5QjvKvAMgIoEvDBIgL7qaqVP/jkvSwYYRZ9iEzvPpopxp2wQfu3SuZRHtpHNxMn8Fs0bS+gf5Xmwg==",
2319
2319
  "license": "MIT",
2320
2320
  "engines": {
2321
2321
  "node": ">= 12"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema": 1,
3
3
  "channel": "nightly",
4
- "installerVersion": "1.2.1-nightly.22",
4
+ "installerVersion": "1.2.1-nightly.23",
5
5
  "packages": {
6
6
  "@ours.network/sdk": {
7
7
  "version": "3.8.1-nightly.15",
@@ -24,8 +24,8 @@
24
24
  "integrity": "sha512-hDosXHgQ+vyzPdSxqTz6vCaOCn0LMTmOL4TJiWplkJhzyw2c586RckXJbqNJsTa0mmodvLxW0ewZyQ/xJVIeXA=="
25
25
  },
26
26
  "@ours.network/fleet": {
27
- "version": "1.2.0-nightly.30",
28
- "integrity": "sha512-rZJqVpg2KSWOvDQxWs/nDlDwJ5VapZO7BK5RKFfv22FJgELArrO5/os03+J1sFazLlHv2qf93iBJ+Ht04h6B7Q=="
27
+ "version": "1.2.0-nightly.31",
28
+ "integrity": "sha512-45oIV09WCsK5yEZF8IKU8LEJjC4Hk26XG/OeA+BqxSFvQWEXoHhMhLeabP5Jc9QcDcEmtH5AeYKXRvCXTeb+YA=="
29
29
  },
30
30
  "@ours.network/mcp": {
31
31
  "version": "1.2.0-nightly.10",
@@ -2,7 +2,7 @@
2
2
  "release": {
3
3
  "schema": 1,
4
4
  "channel": "nightly",
5
- "installerVersion": "1.2.1-nightly.22",
5
+ "installerVersion": "1.2.1-nightly.23",
6
6
  "packages": {
7
7
  "@ours.network/sdk": {
8
8
  "version": "3.8.1-nightly.15",
@@ -25,8 +25,8 @@
25
25
  "integrity": "sha512-hDosXHgQ+vyzPdSxqTz6vCaOCn0LMTmOL4TJiWplkJhzyw2c586RckXJbqNJsTa0mmodvLxW0ewZyQ/xJVIeXA=="
26
26
  },
27
27
  "@ours.network/fleet": {
28
- "version": "1.2.0-nightly.30",
29
- "integrity": "sha512-rZJqVpg2KSWOvDQxWs/nDlDwJ5VapZO7BK5RKFfv22FJgELArrO5/os03+J1sFazLlHv2qf93iBJ+Ht04h6B7Q=="
28
+ "version": "1.2.0-nightly.31",
29
+ "integrity": "sha512-45oIV09WCsK5yEZF8IKU8LEJjC4Hk26XG/OeA+BqxSFvQWEXoHhMhLeabP5Jc9QcDcEmtH5AeYKXRvCXTeb+YA=="
30
30
  },
31
31
  "@ours.network/mcp": {
32
32
  "version": "1.2.0-nightly.10",
@@ -79,7 +79,7 @@
79
79
  },
80
80
  "@ours.network/fleet": {
81
81
  "type": "npm",
82
- "version": "1.2.0-nightly.30"
82
+ "version": "1.2.0-nightly.31"
83
83
  },
84
84
  "@ours.network/mcp": {
85
85
  "type": "npm",
package/lib/effects.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { selectServerPorts } from './server-ports.mjs';
1
2
  import { qualifyPodman } from './podman-preflight.mjs';
2
3
  import { engineName, bindPodman, runContainer, nativeBuildCommands } from './container-engine.mjs';
3
4
  // ours-install v3 — the real side effects.
@@ -677,7 +678,8 @@ export function networkEffects(effects) {
677
678
  const project = `ours-${createHash('sha256').update(root).digest('hex').slice(0, 16)}`;
678
679
  return { schema: 2, root, mode, ...(containerEngine ? { containerEngine } : {}), instanceId, project, workDir: join(root, 'runtime'), configPath: installationPaths({ schema: 2, root }).config, sourcesPath: join(root, 'sources.json'), services: [...SERVER_SERVICES, ...(mode === 'docker' ? ['gateway'] : [])], ...(mode === 'docker' ? { gateway: { version: 1 } } : {}), port: 3050, coworkPort: 3052, messengerPort: 8420, messengerIdentity: env.OURS_MESSENGER_IDENTITY || null, uid: 1000, gid: 1000 };
679
680
  },
680
- async serverPreflight(record, operation, { existing, sourcePath = record.sourcesPath, sourceManifest, identityName } = {}) {
681
+ async serverPreflight(record, operation, { existing, sourcePath = record.sourcesPath, sourceManifest, identityName, explicitPorts } = {}) {
682
+ if (!existing && operation === 'install' && Number.isInteger(record.port)) selectServerPorts(record, portTakenSync, explicitPorts, effects.out);
681
683
  if (existing) {
682
684
  privateDirectory(record.root);
683
685
  assertPrivateRegularFile(join(record.root, 'installation.json'), 'selection');
@@ -1363,7 +1363,7 @@ async function executeServerCommand(args, effects) {
1363
1363
  }
1364
1364
  if (!existing && args.sources) record.sourcePolicyHash = effects.sourcePolicyHash(args.sources);
1365
1365
  await installStage('Prerequisite checks', record.mode === 'docker' ? 'Check Docker Engine and Docker Compose.' : 'Check native tools and the user service manager.', () => effects.serverPreflight(record, args.operation, {
1366
- existing, sourcePath: args.sources ?? record.sourcesPath, sourceManifest: args.resolvedSources, identityName: args.identityName,
1366
+ existing, sourcePath: args.sources ?? record.sourcesPath, sourceManifest: args.resolvedSources, identityName: args.identityName, explicitPorts: args.explicitPorts,
1367
1367
  }));
1368
1368
  if (existing && (record.schema === 1 || record.layoutConversion)
1369
1369
  && ['install', 'start', 'restart', 'update', 'rebuild'].includes(args.operation)) {
@@ -0,0 +1,17 @@
1
+ /** Fresh selections only; retained installations keep their recorded addresses. */
2
+ export function selectServerPorts(record, isTaken, explicitPorts = [], out = () => {}) {
3
+ const reserved = new Set([3051]);
4
+ for (const key of ['port', 'coworkPort', 'messengerPort']) {
5
+ const preferred = record[key];
6
+ let selected = preferred;
7
+ while (reserved.has(selected) || isTaken(selected)) {
8
+ if (explicitPorts.includes(key)) throw Error(`Requested ${key} ${preferred} is unavailable; select another explicit port`);
9
+ selected++;
10
+ if (selected > 65535) throw Error(`No free loopback port available for ${key}`);
11
+ }
12
+ reserved.add(selected);
13
+ record[key] = selected;
14
+ if (selected !== preferred) out(`${key}: ${preferred} is unavailable; selected loopback port ${selected}`);
15
+ }
16
+ return record;
17
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/install",
3
- "version": "1.2.1-nightly.22",
3
+ "version": "1.2.1-nightly.23",
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",