@ours.network/install 0.11.0 → 0.11.2

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/install.mjs CHANGED
@@ -32,6 +32,12 @@ let DRY = !!process.env.OURS_INSTALL_DRY_RUN;
32
32
  const SELFHOST_URL = 'ours.network';
33
33
  const CLAUDE_MARKET = 'adapt-toolkit/ours-claude-marketplace';
34
34
  const CODEX_MARKET = 'adapt-toolkit/ours-codex-marketplace';
35
+ // The ours-fleet HARNESS PLUGINS (separate from the `ours` plugin) — these are what actually give
36
+ // Claude Code / Codex the fleet skill. Claude: plugin "fleet" in the ours.network marketplace
37
+ // (@ours.network/fleet-claude-code). Codex: plugin "ours-fleet" in the ours-codex-marketplace
38
+ // (@ours.network/fleet-codex).
39
+ const CLAUDE_FLEET_PLUGIN = 'fleet@ours.network';
40
+ const CODEX_FLEET_PLUGIN = 'ours-fleet@ours-codex-marketplace';
35
41
 
36
42
  const sink = (s) => process.stdout.write(s);
37
43
  const line = (s = '') => sink(`${s}\n`);
@@ -447,8 +453,33 @@ async function main() {
447
453
  if (goFleet) {
448
454
  await actSpin('installing @ours.network/fleet@latest…', 'npm i -g @ours.network/fleet@latest', () => runAsync(NPM, ['i', '-g', '@ours.network/fleet@latest']));
449
455
  const init = await act('ours-fleet init (one-time host setup: units, dirs, linger)', async () => run('ours-fleet', ['init']));
450
- if (init.ok) { line(ok('ours-fleet ready — Claude and Codex both know the fleet skill. No problems.')); record({ key: 'fleet', label: 'ours-fleet', state: 'installed', version: globalVersion('@ours.network/fleet') }); }
451
- else { line(warn(`ours-fleet host setup didn't finish — retry '${c.cyan('ours-fleet init')}'.`)); record({ key: 'fleet', label: 'ours-fleet', state: 'failed', note: 'ours-fleet init failed' }); }
456
+ if (!init.ok) line(warn(`ours-fleet host setup didn't finish — retry '${c.cyan('ours-fleet init')}'.`));
457
+
458
+ // Install the fleet HARNESS PLUGIN into each real+safe harness — the piece that actually gives
459
+ // Claude Code / Codex the fleet skill. Same drive-the-CLI, alias-safe, loud-on-failure pattern
460
+ // as Step 2; never dead-ends. (The `ours` plugin does NOT bundle this — it's a separate plugin.)
461
+ const fleetIn = [];
462
+ for (const h of harnesses) {
463
+ if (h.status === 'absent') continue;
464
+ if (h.name === 'claude') {
465
+ if (h.status !== 'ok') { manualClaudeFleet(h); continue; }
466
+ await act(`claude plugin marketplace add ${CLAUDE_MARKET}`, async () => run('claude', ['plugin', 'marketplace', 'add', CLAUDE_MARKET], { capture: true }));
467
+ const r = await act(`claude plugin install ${CLAUDE_FLEET_PLUGIN}`, async () => run('claude', ['plugin', 'install', CLAUDE_FLEET_PLUGIN], { capture: true }));
468
+ if (r.ok) { line(ok('Claude Code fleet plugin installed — you can spawn agents from Claude Code. No problems.')); fleetIn.push('Claude Code'); }
469
+ else failClaudeFleet();
470
+ } else { // codex
471
+ if (h.status !== 'ok') { manualCodexFleet(h); continue; }
472
+ await act(`codex plugin marketplace add ${CODEX_MARKET}`, async () => run('codex', ['plugin', 'marketplace', 'add', CODEX_MARKET], { capture: true }));
473
+ const r = await act(`codex plugin add ${CODEX_FLEET_PLUGIN}`, async () => run('codex', ['plugin', 'add', CODEX_FLEET_PLUGIN], { capture: true }));
474
+ if (r.ok) { line(ok('Codex fleet plugin installed — you can spawn agents from Codex. No problems.')); fleetIn.push('Codex'); }
475
+ else failCodexFleet();
476
+ }
477
+ }
478
+ // Only claim the skill is present where the fleet plugin actually installed.
479
+ if (init.ok && fleetIn.length) line(ok(`ours-fleet ready — ${fleetIn.join(' + ')} now know the fleet skill. No problems.`));
480
+ else if (init.ok) line(info('ours-fleet CLI is installed; add the fleet plugin to your harness with the commands above.'));
481
+ const fleetOk = init.ok && (fleetIn.length > 0 || harnesses.every((h) => h.status === 'absent'));
482
+ record({ key: 'fleet', label: 'ours-fleet', state: fleetOk ? 'installed' : 'failed', version: globalVersion('@ours.network/fleet'), note: fleetIn.length ? fleetIn.join(' + ') : (init.ok ? 'CLI only — add plugin manually' : 'ours-fleet init failed') });
452
483
  } else {
453
484
  line(info('skipped cleanly — re-run ours-install any time to add it.'));
454
485
  record({ key: 'fleet', label: 'ours-fleet', state: 'skipped' });
@@ -524,6 +555,37 @@ function failCodex() {
524
555
  line(' ' + c.cyan('npm i -g @ours.network/codex'));
525
556
  line(info('Your daemon and other steps are intact. Continuing.'));
526
557
  }
558
+ // --- fleet HARNESS PLUGIN never-dead-end messaging ---------------------------------------------
559
+ function manualClaudeFleet(h) {
560
+ line(warn(h.status === 'alias'
561
+ ? '"claude" is installed as an alias, so I can\'t add the fleet plugin for you.'
562
+ : 'Couldn\'t safely drive "claude" to add the fleet plugin.'));
563
+ line(info('Add it yourself — inside Claude Code, run these two:'));
564
+ line(' ' + c.cyan(`/plugin marketplace add ${CLAUDE_MARKET}`));
565
+ line(' ' + c.cyan('/plugin install fleet'));
566
+ }
567
+ function failClaudeFleet() {
568
+ line(warn('Couldn\'t install the Claude Code fleet plugin automatically.'));
569
+ line(info('Install it by hand — inside Claude Code, run these two, then re-run ours-install:'));
570
+ line(' ' + c.cyan(`/plugin marketplace add ${CLAUDE_MARKET}`));
571
+ line(' ' + c.cyan('/plugin install fleet'));
572
+ line(info('Your daemon and other steps are intact. Continuing.'));
573
+ }
574
+ function manualCodexFleet(h) {
575
+ line(warn(h.status === 'alias'
576
+ ? '"codex" is installed as an alias, so I can\'t add the fleet plugin for you.'
577
+ : 'Couldn\'t safely drive "codex" to add the fleet plugin.'));
578
+ line(info('Add it yourself — run these two in your terminal:'));
579
+ line(' ' + c.cyan(`codex plugin marketplace add ${CODEX_MARKET}`));
580
+ line(' ' + c.cyan(`codex plugin add ${CODEX_FLEET_PLUGIN}`));
581
+ }
582
+ function failCodexFleet() {
583
+ line(warn('Couldn\'t install the Codex fleet plugin automatically.'));
584
+ line(info('Install it by hand — run these two, then re-run ours-install:'));
585
+ line(' ' + c.cyan(`codex plugin marketplace add ${CODEX_MARKET}`));
586
+ line(' ' + c.cyan(`codex plugin add ${CODEX_FLEET_PLUGIN}`));
587
+ line(info('Your daemon and other steps are intact. Continuing.'));
588
+ }
527
589
 
528
590
  // --- final summary + copy-paste hand-off -------------------------------------------------------
529
591
  function endScreen({ ttyFd, summary, chosenPort, chosenBroker }) {
package/lib/logic.mjs CHANGED
@@ -162,8 +162,9 @@ export function buildHandoffPrompt({ identity = false, fleet = false, telegram =
162
162
  }
163
163
  if (fleet) {
164
164
  steps.push(
165
- "Set up ours-fleet: confirm it's ready and show me how to spawn a\n" +
166
- ' temporary agent, then spawn one so I can see it.',
165
+ 'Set up my ours-fleet: ask me what agents I want in my fleet for\n' +
166
+ ' PERMANENT use (a name + role/purpose for each), then create and\n' +
167
+ ' configure those permanent fleet agents for me.',
167
168
  );
168
169
  }
169
170
  if (telegram) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ours.network/install",
3
- "version": "0.11.0",
3
+ "version": "0.11.2",
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",