@ours.network/install 0.17.0-nightly.5 → 0.17.0-nightly.7

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.
@@ -144,6 +144,16 @@ function parseServiceFile(path, id, home) {
144
144
  };
145
145
  }
146
146
 
147
+ // The instance-name rule, byte-for-byte core's INSTANCE_RE (packages/core/src/
148
+ // service-instance.ts): 1–32 characters, starting AND ENDING with a letter or
149
+ // digit. Discovery used a looser pattern that also accepted a trailing hyphen or
150
+ // underscore, which meant it recognised unit filenames core itself refuses to
151
+ // produce and profiles.mjs then refuses to normalize — see the guard below.
152
+ const SERVICE_INSTANCE_FILE = {
153
+ systemd: /^ours-([A-Za-z0-9](?:[A-Za-z0-9_-]{0,30}[A-Za-z0-9])?)\.service$/,
154
+ launchd: /^solutions\.adaptframework\.ours\.([A-Za-z0-9](?:[A-Za-z0-9_-]{0,30}[A-Za-z0-9])?)\.plist$/,
155
+ };
156
+
147
157
  function knownServiceCandidates(home) {
148
158
  const candidates = [];
149
159
  const dirs = [
@@ -156,9 +166,15 @@ function knownServiceCandidates(home) {
156
166
  for (const file of files) {
157
167
  let id = null;
158
168
  if (file === 'ours.service' || file === 'solutions.adaptframework.ours.plist') id = 'default';
159
- else if (/^ours-[A-Za-z0-9][A-Za-z0-9_-]{0,31}\.service$/.test(file)) id = file.slice(5, -8);
160
- else if (/^solutions\.adaptframework\.ours\.[A-Za-z0-9][A-Za-z0-9_-]{0,31}\.plist$/.test(file)) id = file.slice('solutions.adaptframework.ours.'.length, -6);
169
+ else id = SERVICE_INSTANCE_FILE.systemd.exec(file)?.[1] ?? SERVICE_INSTANCE_FILE.launchd.exec(file)?.[1] ?? null;
161
170
  if (!id) continue;
171
+ // A file whose name matches is CLAIMED, and any fault reading its contents
172
+ // stays FATAL on purpose. That is not the same question as the one above:
173
+ // once a definition is ours, a malformed entity or corrupt config could
174
+ // otherwise be treated as literal path bytes and point discovery at the
175
+ // wrong state directory, so it must fail closed before anything is probed
176
+ // or mutated (see the launchd malformed-entity test). What the pattern
177
+ // above fixes is the file that was never ours to claim.
162
178
  const candidate = parseServiceFile(join(dir, file), id, home);
163
179
  if (candidate) candidates.push(candidate);
164
180
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/install",
3
- "version": "0.17.0-nightly.5",
3
+ "version": "0.17.0-nightly.7",
4
4
  "private": false,
5
5
  "description": "The unified ours.network stack installer (ours-install): one guided ~3-minute flow for ours core (the daemon) + the harness plugins (Claude Code / Codex) + ours-fleet + the Telegram connector, then a single copy-paste hand-off prompt. Self-contained (Node built-ins only); run as `ours-install` or via curl|bash (install.sh).",
6
6
  "type": "module",