@ours.network/install 1.2.1-nightly.6 → 1.2.1-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.
@@ -4285,9 +4285,9 @@
4285
4285
  }
4286
4286
  },
4287
4287
  "node_modules/lru-cache": {
4288
- "version": "11.5.2",
4289
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz",
4290
- "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==",
4288
+ "version": "11.5.3",
4289
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz",
4290
+ "integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==",
4291
4291
  "license": "BlueOak-1.0.0",
4292
4292
  "engines": {
4293
4293
  "node": "20 || >=22"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema": 1,
3
3
  "channel": "nightly",
4
- "installerVersion": "1.2.1-nightly.6",
4
+ "installerVersion": "1.2.1-nightly.7",
5
5
  "packages": {
6
6
  "@ours.network/sdk": {
7
7
  "version": "3.8.1-nightly.3",
@@ -2,7 +2,7 @@
2
2
  "release": {
3
3
  "schema": 1,
4
4
  "channel": "nightly",
5
- "installerVersion": "1.2.1-nightly.6",
5
+ "installerVersion": "1.2.1-nightly.7",
6
6
  "packages": {
7
7
  "@ours.network/sdk": {
8
8
  "version": "3.8.1-nightly.3",
@@ -86,6 +86,41 @@ async function perform(effects, dryRun, label, thunk) {
86
86
 
87
87
  const reason = (error) => (error instanceof Error ? error.message : String(error));
88
88
 
89
+ function clientDiagnostic(error) {
90
+ return reason(error)
91
+ .replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, '')
92
+ .replace(/\bBearer\s+[^\s,;]+/gi, 'Bearer [redacted]')
93
+ .replace(/((?:api[_-]?key|api[_-]?token|access[_-]?token|refresh[_-]?token|token|password|secret|authorization|credential)\s*["']?\s*[:=]\s*["']?)[^\s"',;]+/gi, '$1[redacted]')
94
+ .replace(/(https?:\/\/)[^\s/@]+:[^\s/@]+@/gi, '$1[redacted]@')
95
+ .replace(/[\x00-\x1f\x7f]/g, ' ').slice(0, 700);
96
+ }
97
+
98
+ function clientRetry(effects, imported, integrations) {
99
+ effects.out(info(`Saved server connection: ${imported.configPath}.`));
100
+ if (integrations.includes('fleet') && !imported.settings.fleetSettingsPath) {
101
+ effects.out(info('Saved profile and settings retained. Run ours-install, choose Connect to an existing server, and reuse the saved profile to finish the interactive Fleet configuration.'));
102
+ return;
103
+ }
104
+ const args = ['client', 'install', '--config', imported.configPath, '--integrations', integrations.join(','), '--sources', imported.settings.sourcesPath];
105
+ if (imported.settings.fleetSettingsPath) args.push('--fleet-settings', imported.settings.fleetSettingsPath);
106
+ const command = `ours-install client install ${args.slice(2).map((value, i) => i % 2 === 0 ? value : shellQuote(value)).join(' ')}`;
107
+ effects.out(info(`Saved profile and settings retained; re-run ${command}`));
108
+ }
109
+
110
+ function explainClientFailure(effects, name, row) {
111
+ const label = { codex: 'Codex', 'claude-code': 'Claude Code', fleet: 'Fleet' }[name];
112
+ const command = name === 'claude-code' ? 'claude' : name;
113
+ if (row?.note === 'not installed') {
114
+ effects.out(warn(`${label}: executable not found on PATH. Install ${label} or make its executable available in this shell, then check ${command} --version before retrying.`));
115
+ } else if (row?.manual) {
116
+ effects.out(warn(`${label}: cannot register the plugin automatically — ${clientDiagnostic(row.note)}. Use the real executable (check ${command} --version), or register the displayed local marketplace manually.`));
117
+ } else {
118
+ effects.out(warn(`${label}: ${row?.failedStep ?? 'integration setup'} failed. ${clientDiagnostic(row?.detail ?? row?.note ?? 'The integration did not report successful completion. Review the messages above.')} Fix the reported command error before retrying.`));
119
+ if (row?.failedCommand) effects.out(info(`Failed command: ${row.failedCommand.map(shellQuote).join(' ')}`));
120
+ }
121
+ }
122
+
123
+
89
124
  function semverMajor(version) {
90
125
  const match = /^(?:[~^<>= ]*)(\d+)\./.exec(String(version ?? '').trim());
91
126
  return match ? Number(match[1]) : null;
@@ -193,11 +228,11 @@ async function prepareIncompatibleUpgrade(args, effects, target, cliPkg, mismatc
193
228
  * rather than one harness. So a failure here is one honest line plus whatever
194
229
  * the caller wants to say about retrying, and the walk continues.
195
230
  */
196
- async function attempt(effects, dryRun, label, thunk) {
231
+ async function attempt(effects, dryRun, label, thunk, formatReason = reason) {
197
232
  try {
198
233
  return { ok: true, ...(await perform(effects, dryRun, label, thunk)) };
199
234
  } catch (error) {
200
- effects.out(warn(`${label} — did not complete: ${reason(error)}`));
235
+ effects.out(warn(`${label} — did not complete: ${formatReason(error)}`));
201
236
  return { ok: false, error };
202
237
  }
203
238
  }
@@ -817,6 +852,9 @@ export async function runIdentityPhase(args, effects, { target, mcpReady }) {
817
852
  export async function runHarnessPhase(args, effects, { target, isDefaultStateDir, exactSuite = null }) {
818
853
  effects.out(heading('Harness plugins'));
819
854
  const detected = (await effects.detectHarnesses()).filter(h => !args.clientIntegrations || args.clientIntegrations.includes(h.name));
855
+ for (const name of args.clientIntegrations ?? []) {
856
+ if (name !== 'fleet' && !detected.some(h => h.name === name)) detected.push({ name, status: 'absent' });
857
+ }
820
858
  for (const h of detected) {
821
859
  if (h.status === 'ok') effects.out(ok(`'${h.command ?? h.name}' → ${h.detail ?? 'real program'} (its plugin can be installed)`));
822
860
  else if (h.status === 'alias') effects.out(warn(`'${h.command ?? h.name}' → ${h.detail} (I won't call it — manual steps below)`));
@@ -826,7 +864,7 @@ export async function runHarnessPhase(args, effects, { target, isDefaultStateDir
826
864
  if (detected.every((h) => h.status === 'absent')) {
827
865
  effects.out(info('No Claude Code, Codex or Hermes found — install one and re-run to wire it up.'));
828
866
  effects.out(info('Your daemon is unaffected; nothing else in this run depends on a harness.'));
829
- return [];
867
+ return args.clientIntegrations ? detected.map(h => ({ key: h.name, state: 'skipped', note: 'not installed' })) : [];
830
868
  }
831
869
 
832
870
  const plans = planHarnessPlugins({
@@ -851,7 +889,7 @@ export async function runHarnessPhase(args, effects, { target, isDefaultStateDir
851
889
  if (plan.action === 'manual' && exactSuite?.localPackages?.[plan.name]) {
852
890
  const root = await effects.prepareClientMarketplace(plan.name, exactSuite.localPackages[plan.name]);
853
891
  effects.out(warn(`${plan.label} requires manual registration of exact local marketplace ${root}; ${target.managed ? 'the saved client default is retained' : `keep OURS_CONFIG=${target.configPath}`}.`));
854
- rows.push({ ...row, state: 'failed', note: 'native executable unavailable' });
892
+ rows.push({ ...row, state: 'failed', note: plan.reason, manual: true });
855
893
  continue;
856
894
  }
857
895
  if (plan.action === 'manual') {
@@ -873,7 +911,7 @@ export async function runHarnessPhase(args, effects, { target, isDefaultStateDir
873
911
  effects.out(warn(`${plan.label} — ${plan.reason}; install it yourself with:`));
874
912
  for (const step of manual) effects.out(info(` ${step}`));
875
913
  if (plan.envLine) effects.out(info(`Before later native launches, set: ${plan.envLine}`));
876
- rows.push({ ...row, state: 'skipped', note: plan.reason });
914
+ rows.push({ ...row, state: 'skipped', note: plan.reason, manual: true });
877
915
  continue;
878
916
  }
879
917
 
@@ -884,13 +922,16 @@ export async function runHarnessPhase(args, effects, { target, isDefaultStateDir
884
922
  const steps = plan.name === 'codex'
885
923
  ? [['codex', 'plugin', 'marketplace', 'add', registration], ['codex', 'plugin', 'add', 'ours@ours-codex-marketplace']]
886
924
  : [['claude', 'plugin', 'marketplace', 'add', registration], ['claude', 'plugin', await effects.hasClaudePlugin() ? 'update' : 'install', 'ours@ours.network']];
887
- let failed = false;
925
+ let failure = null;
888
926
  for (const step of steps) {
889
- const outcome = await attempt(effects, false, step.join(' '), () => effects.run(step[0], step.slice(1), { env: profileEnv(target) }));
890
- if (!outcome.ok) { failed = true; break; }
927
+ const outcome = await attempt(effects, false, step.join(' '), () => effects.run(step[0], step.slice(1), { env: profileEnv(target) }), clientDiagnostic);
928
+ if (!outcome.ok) {
929
+ failure = { failedCommand: step, failedStep: step[2] === 'marketplace' ? `Register ${plan.label} marketplace` : `Install ${plan.label} plugin`, detail: clientDiagnostic(outcome.error) };
930
+ break;
931
+ }
891
932
  }
892
933
  effects.out(info(target.managed ? `Native ${plan.name} launches use the saved client default.` : `Native ${plan.name} launches must retain OURS_CONFIG=${target.configPath}.`));
893
- rows.push({ ...row, state: failed ? 'failed' : 'installed' });
934
+ rows.push({ ...row, state: failure ? 'failed' : 'installed', ...(failure ?? {}) });
894
935
  continue;
895
936
  }
896
937
 
@@ -1428,29 +1469,36 @@ export async function runClientCommand(command, effects) {
1428
1469
  }
1429
1470
  effects.out(progress(0, 4, 'Client configuration', 'Prepare the selected integrations and private connection profile.'));
1430
1471
  const imported = effects.importClientProfile({ profile, sourcesPath, sources: resolvedSources, integrations, fleetSettingsPath, refresh: !!command.preset });
1472
+ let phase = 'Validate saved server connection';
1431
1473
  try {
1432
1474
  await effects.verifyHostProfile(imported.configPath);
1433
1475
  effects.out(progress(1, 4, 'Client packages', 'Acquire and verify the selected client package versions.'));
1476
+ phase = 'Acquire client packages';
1434
1477
  const exactSuite = await effects.acquireClientPackages(imported.configPath, imported.settings.sourcesPath, integrations, { refresh: !!command.preset });
1435
1478
  const args = { assumeYes: true, dryRun: false, channel: 'latest', clientIntegrations: integrations,
1436
1479
  acquiredFleet: exactSuite.fleetBin, fleetSettingsPath: imported.settings.fleetSettingsPath };
1437
1480
  const target = { mode: 'host-profile', managed: true, configPath: imported.configPath, profile: imported.profile, endpoint: imported.profile.endpoint };
1438
1481
  effects.out(progress(2, 4, 'Client integrations', 'Register the selected agent integrations.'));
1482
+ phase = 'Register client integrations';
1439
1483
  const summary = await runHarnessPhase(args, effects, { target, isDefaultStateDir: false, exactSuite });
1440
1484
  if (integrations.includes('fleet')) {
1441
1485
  effects.out(progress(3, 4, 'Fleet configuration', 'Apply prepared settings or open the selected Fleet wizard.'));
1486
+ phase = 'Configure Fleet';
1442
1487
  summary.push(await runFleetPhase(args, effects, { target, isDefaultStateDir: false }));
1443
1488
  }
1444
1489
  const incomplete = integrations.filter(name => !summary.some(row => row.key === name && row.state === 'installed'));
1445
1490
  if (effects.env.OURS_CONFIG && resolve(effects.env.OURS_CONFIG) !== imported.configPath)
1446
1491
  effects.out(warn('This shell has an explicit OURS_CONFIG override. Unset it for new clients to use the saved default; installer did not edit your shell.'));
1447
- effects.out(incomplete.length
1448
- ? warn(`Client setup incomplete (${incomplete.join(', ')}); saved profile and settings retained. Re-run ours-install client install.`)
1449
- : ok(`Client setup complete. New clients discover ${imported.configPath}; no OURS_CONFIG export is required.`));
1492
+ if (incomplete.length) {
1493
+ effects.out(warn(`Client setup incomplete (${incomplete.join(', ')}). The selected client integrations need attention:`));
1494
+ for (const name of incomplete) explainClientFailure(effects, name, summary.find(row => row.key === name));
1495
+ clientRetry(effects, imported, integrations);
1496
+ } else effects.out(ok(`Client setup complete. New clients discover ${imported.configPath}; no OURS_CONFIG export is required.`));
1450
1497
  if (!incomplete.length) effects.out(progress(4, 4, 'Client setup complete', 'All selected integrations are configured.'));
1451
1498
  return incomplete.length ? EXIT_REFUSED : EXIT_OK;
1452
1499
  } catch (error) {
1453
- effects.out(warn(`Client setup incomplete: ${reason(error)}. Saved profile and settings retained; re-run ours-install client install.`));
1500
+ effects.out(warn(`Client setup incomplete: ${phase} failed — ${clientDiagnostic(error)}. Fix this error before retrying.`));
1501
+ clientRetry(effects, imported, integrations);
1454
1502
  return EXIT_REFUSED;
1455
1503
  }
1456
1504
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/install",
3
- "version": "1.2.1-nightly.6",
3
+ "version": "1.2.1-nightly.7",
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",