@bivy/bivy 0.16.1-staging.3 → 0.16.1-staging.4
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/bin/bivy.mjs +11 -9
- package/bin/install-kind.mjs +20 -0
- package/bin/service-state.mjs +12 -0
- package/package.json +1 -1
package/bin/bivy.mjs
CHANGED
|
@@ -39,6 +39,8 @@ import { renderManagedBlock, upsertManagedBlock, removeManagedBlock, rcFileForSh
|
|
|
39
39
|
import { removeInstallAndState } from "./uninstall-paths.mjs";
|
|
40
40
|
import { findAvailablePort, reconcilePort } from "./port-picker.mjs";
|
|
41
41
|
import { resolveAttachSessionId } from "./attach-session-id.mjs";
|
|
42
|
+
import { detectInstallKind as classifyInstallKind } from "./install-kind.mjs";
|
|
43
|
+
import { hasConfiguredService as configuredServiceExists } from "./service-state.mjs";
|
|
42
44
|
|
|
43
45
|
const selfScript = fileURLToPath(import.meta.url);
|
|
44
46
|
const __dirname = path.dirname(selfScript);
|
|
@@ -69,14 +71,10 @@ process.env.BIVY_DATA_DIR = appDir;
|
|
|
69
71
|
// background service can point at repoRoot:
|
|
70
72
|
// - "git" dev checkout (has .git)
|
|
71
73
|
// - "npx" ephemeral `npx bivy` run (repoRoot under an npm _npx cache)
|
|
72
|
-
// - "npm-global" `npm i -g @bivy/bivy` (repoRoot
|
|
74
|
+
// - "npm-global" `npm i -g @bivy/bivy` (repoRoot is below node_modules/@bivy)
|
|
73
75
|
// - "packaged" install.sh tarball tree (user-owned, self-preserving)
|
|
74
76
|
function detectInstallKind() {
|
|
75
|
-
|
|
76
|
-
const inNodeModules = path.basename(path.dirname(repoRoot)) === "node_modules";
|
|
77
|
-
if (inNodeModules && /[\\/]_npx[\\/]/.test(repoRoot)) return "npx";
|
|
78
|
-
if (inNodeModules) return "npm-global";
|
|
79
|
-
return "packaged";
|
|
77
|
+
return classifyInstallKind(repoRoot);
|
|
80
78
|
}
|
|
81
79
|
const cliConfigPath = path.join(appDir, "cli.json");
|
|
82
80
|
const canonicalConfigPath = path.join(appDir, "config.yaml");
|
|
@@ -3254,6 +3252,10 @@ async function reconcileNodePort(config) {
|
|
|
3254
3252
|
// reloads/relaunches). Otherwise a plain restart. Returns true if the service
|
|
3255
3253
|
// was (re)started. Used by `bivy restart` and `bivy update` — the paths that
|
|
3256
3254
|
// previously trusted the saved port verbatim.
|
|
3255
|
+
function hasConfiguredService(config) {
|
|
3256
|
+
return configuredServiceExists(config, servicePaths().file);
|
|
3257
|
+
}
|
|
3258
|
+
|
|
3257
3259
|
async function restartServiceReconciled(config) {
|
|
3258
3260
|
const { kind, file } = servicePaths();
|
|
3259
3261
|
if (!fs.existsSync(file)) return restartService();
|
|
@@ -4442,7 +4444,7 @@ async function runUpdate(args = []) {
|
|
|
4442
4444
|
await ensureKnownAgents();
|
|
4443
4445
|
const config = loadConfig();
|
|
4444
4446
|
await waitForIdleSessions(config, { skip: skipWait });
|
|
4445
|
-
if (config
|
|
4447
|
+
if (hasConfiguredService(config) && (await restartServiceReconciled(config))) {
|
|
4446
4448
|
if (await verifyNodeCameUp(config)) {
|
|
4447
4449
|
console.log(c.green("Updated and restarted the background service."));
|
|
4448
4450
|
} else {
|
|
@@ -4474,7 +4476,7 @@ async function runUpdate(args = []) {
|
|
|
4474
4476
|
});
|
|
4475
4477
|
// install.sh restarts the service itself; verify the node actually came up
|
|
4476
4478
|
// rather than trusting the installer's exit code over a crash-looping node.
|
|
4477
|
-
if (code === 0 && config
|
|
4479
|
+
if (code === 0 && hasConfiguredService(config) && !(await verifyNodeCameUp(config))) {
|
|
4478
4480
|
reportNodeDidNotStart();
|
|
4479
4481
|
process.exit(1);
|
|
4480
4482
|
}
|
|
@@ -4490,7 +4492,7 @@ async function runUpdate(args = []) {
|
|
|
4490
4492
|
await ensureKnownAgents();
|
|
4491
4493
|
const config = loadConfig();
|
|
4492
4494
|
await waitForIdleSessions(config, { skip: skipWait });
|
|
4493
|
-
if (config
|
|
4495
|
+
if (hasConfiguredService(config) && (await restartServiceReconciled(config))) {
|
|
4494
4496
|
if (await verifyNodeCameUp(config)) {
|
|
4495
4497
|
console.log(c.green("Updated and restarted the background service."));
|
|
4496
4498
|
} else {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (c) 2026 Petter André Sjulstad
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
/** Classify a Bivy package root without assuming unscoped npm package layout. */
|
|
7
|
+
export function detectInstallKind(repoRoot, existsSync = fs.existsSync) {
|
|
8
|
+
if (existsSync(path.join(repoRoot, ".git"))) return "git";
|
|
9
|
+
|
|
10
|
+
// npm installs an unscoped package at node_modules/name and a scoped package
|
|
11
|
+
// at node_modules/@scope/name. Bivy uses the latter layout.
|
|
12
|
+
const parent = path.dirname(repoRoot);
|
|
13
|
+
const grandparent = path.dirname(parent);
|
|
14
|
+
const inNodeModules = path.basename(parent) === "node_modules"
|
|
15
|
+
|| (path.basename(parent).startsWith("@") && path.basename(grandparent) === "node_modules");
|
|
16
|
+
|
|
17
|
+
if (inNodeModules && /[\\/]_npx[\\/]/.test(repoRoot)) return "npx";
|
|
18
|
+
if (inNodeModules) return "npm-global";
|
|
19
|
+
return "packaged";
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (c) 2026 Petter André Sjulstad
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Whether an install has a background service that an update must restart.
|
|
7
|
+
* The on-disk unit/plist is authoritative; cli.json.service is only a hint and
|
|
8
|
+
* may be absent on migrated installs.
|
|
9
|
+
*/
|
|
10
|
+
export function hasConfiguredService(config, serviceFile, existsSync = fs.existsSync) {
|
|
11
|
+
return Boolean(config?.service) || existsSync(serviceFile);
|
|
12
|
+
}
|
package/package.json
CHANGED