@ours.network/install 0.17.0-nightly.13 → 0.17.0-nightly.14
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/orchestrate.mjs +56 -2
- package/package.json +1 -1
package/lib/orchestrate.mjs
CHANGED
|
@@ -423,6 +423,47 @@ function readChanged(stdout) {
|
|
|
423
423
|
}
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
+
/**
|
|
427
|
+
* THE QUESTION NOBODY WAS ASKING.
|
|
428
|
+
*
|
|
429
|
+
* `planComponentSelection` has always read an `answers` map — and NOTHING EVER
|
|
430
|
+
* POPULATED IT. `args.answers` is not produced by parseInstallArgs and is not
|
|
431
|
+
* written by any phase, so it was permanently `{}`, every optional component fell
|
|
432
|
+
* to its own default, and tg and cowork (both default false) were skipped in
|
|
433
|
+
* silence. The screen then printed "cowork — not installed" as though that had
|
|
434
|
+
* been a decision.
|
|
435
|
+
*
|
|
436
|
+
* This was the ONE phase with no question. Harness plugins ask, ours-fleet asks,
|
|
437
|
+
* voice asks, the broker asks. Components did not.
|
|
438
|
+
*
|
|
439
|
+
* IT IS NOT A COWORK BUG, and fixing only the component that got reported would
|
|
440
|
+
* have left the identical defect live under a different label: the Telegram
|
|
441
|
+
* connector is unreachable by exactly the same route, and nobody noticed only
|
|
442
|
+
* because tg is usually configured somewhere else.
|
|
443
|
+
*
|
|
444
|
+
* A REQUIRED component is never asked — since #74 the MCP package IS the daemon,
|
|
445
|
+
* the daemon phase has already installed it, and a question whose only honest
|
|
446
|
+
* answer is yes is not a question. Non-interactive runs are unchanged: assumeYes
|
|
447
|
+
* takes each component's own default, which is what NON_INTERACTIVE_ANSWERS
|
|
448
|
+
* documents (mcp yes, tg no, cowork no), so nothing about the unattended contract
|
|
449
|
+
* moves.
|
|
450
|
+
*/
|
|
451
|
+
export async function askComponents(args, effects) {
|
|
452
|
+
const answers = { ...(args.answers ?? {}) };
|
|
453
|
+
if (args.assumeYes) return answers;
|
|
454
|
+
const optional = COMPONENTS.filter((c) => !c.required && answers[c.key] === undefined);
|
|
455
|
+
if (optional.length === 0) return answers;
|
|
456
|
+
effects.out(heading('What else should this daemon carry?'));
|
|
457
|
+
for (const component of optional) {
|
|
458
|
+
const already = (args.installed ?? {})[component.key] === true;
|
|
459
|
+
answers[component.key] = await effects.ask(
|
|
460
|
+
already ? `Keep ${component.label}?` : `Install ${component.label}?`,
|
|
461
|
+
already || component.default,
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
return answers;
|
|
465
|
+
}
|
|
466
|
+
|
|
426
467
|
/**
|
|
427
468
|
* Components: §5. A component that fails is reported with its retry command and
|
|
428
469
|
* the run CONTINUES — a failed component is never a reason to undo a successful
|
|
@@ -432,8 +473,9 @@ export async function runComponentPhase(args, effects, target) {
|
|
|
432
473
|
const dir = target.stateDir;
|
|
433
474
|
const endpoint = `http://127.0.0.1:${target.port}`;
|
|
434
475
|
const isDefaultStateDir = dir === join(effects.home, '.ours');
|
|
476
|
+
const answers = await askComponents(args, effects);
|
|
435
477
|
const chosen = planComponentSelection({
|
|
436
|
-
answers
|
|
478
|
+
answers,
|
|
437
479
|
installed: args.installed ?? {},
|
|
438
480
|
assumeYes: args.assumeYes,
|
|
439
481
|
});
|
|
@@ -1029,7 +1071,19 @@ export async function runInstall(argv, effects) {
|
|
|
1029
1071
|
if (args.version) { effects.out(`ours-install v${effects.version ?? '?'}`); return EXIT_OK; }
|
|
1030
1072
|
|
|
1031
1073
|
args.brokerUrl = args.brokerUrl ?? effects.brokerUrl;
|
|
1032
|
-
|
|
1074
|
+
// THE INSTALLER'S OWN VERSION IS THE CHANNEL SIGNAL WHEN NOTHING SAYS OTHERWISE.
|
|
1075
|
+
//
|
|
1076
|
+
// resolveChannel falls back to `selfVersion` only when the environment is
|
|
1077
|
+
// silent, and this call passed no selfVersion — so a NIGHTLY installer with no
|
|
1078
|
+
// OURS_CHANNEL set resolved to `latest` and installed the whole stack at latest.
|
|
1079
|
+
// That is what put fleet@latest and a stable ours-mcp on a nightly machine.
|
|
1080
|
+
//
|
|
1081
|
+
// The v2 bin has always done this correctly (install.mjs:53 passes pkgVersion());
|
|
1082
|
+
// the v3 orchestrator dropped the argument. @ours.network/install is published on
|
|
1083
|
+
// BOTH dist-tags from one lockstep bump, so its own version is the only thing
|
|
1084
|
+
// that distinguishes a nightly installer from a stable one when the operator has
|
|
1085
|
+
// said nothing.
|
|
1086
|
+
args.channel = resolveChannel(effects.env.OURS_CHANNEL ?? effects.env.OURS_INSTALL_CHANNEL, effects.version);
|
|
1033
1087
|
|
|
1034
1088
|
effects.out(banner());
|
|
1035
1089
|
effects.out(heading(`ours: target ${args.stateDir}${args.portExplicit ? `, port ${args.port}` : ''}`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ours.network/install",
|
|
3
|
-
"version": "0.17.0-nightly.
|
|
3
|
+
"version": "0.17.0-nightly.14",
|
|
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",
|