@join-pantheon/cli 0.26.1 → 0.26.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/dist/doctor.js +7 -4
- package/dist/host-env.js +4 -3
- package/dist/quickstart.js +5 -1
- package/dist/service.js +19 -0
- package/dist/which.js +18 -1
- package/package.json +2 -2
package/dist/doctor.js
CHANGED
|
@@ -16,8 +16,8 @@ import { workerProc, menubarProc, notifierProc } from "./machine.js";
|
|
|
16
16
|
import { chooseAgent, describeChoice } from "./agents.js";
|
|
17
17
|
import { onPathNamed } from "./which.js";
|
|
18
18
|
import { VERSION } from "./version.js";
|
|
19
|
-
import { serviceInstalled } from "./service.js";
|
|
20
|
-
import { hostEnv } from "./host-env.js";
|
|
19
|
+
import { serviceInstalled, servicesUnavailable } from "./service.js";
|
|
20
|
+
import { hostEnv, platformName } from "./host-env.js";
|
|
21
21
|
const HOSTED_RELAY = "relay.joinpantheon.network";
|
|
22
22
|
const sh = (cmd, cwd) => {
|
|
23
23
|
try {
|
|
@@ -56,7 +56,7 @@ export async function doctor(projectDir) {
|
|
|
56
56
|
: add("fail", "node", `v${process.versions.node} is too old`, "pantheon needs Node 22 or newer (the relay uses node:sqlite) — install it and re-run", `v${process.versions.node}, too old`);
|
|
57
57
|
const host = hostEnv();
|
|
58
58
|
if (host.ephemeral) {
|
|
59
|
-
add("warn", "machine", `${host.platform} in ${host.kind === "container" ? "a container" : "a cloud workspace"} — ${host.evidence.join("; ")}`, `this is not the computer you work on, which is why it reports ${host.platform} to someone who may be sitting at a Mac. The team and your account are fine here, but the menu bar, desktop alerts and the worker belong on your own machine — run the setup from a terminal there.`, `${host.platform} in ${host.kind === "container" ? "a container" : "a cloud workspace"}`);
|
|
59
|
+
add("warn", "machine", `${host.platform} in ${host.kind === "container" ? "a container" : "a cloud workspace"} — ${host.evidence.join("; ")}`, `this is not the computer you work on, which is why it reports ${platformName(host.platform)} to someone who may be sitting at a Mac. The team and your account are fine here, but the menu bar, desktop alerts and the worker belong on your own machine — run the setup from a terminal there.`, `${host.platform} in ${host.kind === "container" ? "a container" : "a cloud workspace"}`);
|
|
60
60
|
}
|
|
61
61
|
else {
|
|
62
62
|
add("pass", "machine", `${host.platform}${host.desktop ? " — menu bar and desktop alerts can run here" : " — no menu bar or desktop alerts (macOS only); use phone or chat delivery"}`, undefined, `${host.platform}${host.desktop ? ", desktop" : ""}`);
|
|
@@ -255,7 +255,10 @@ export async function doctor(projectDir) {
|
|
|
255
255
|
add("pass", "wake rights", `${who} — worker is running`, undefined, `${wakers.length} may wake; worker running`);
|
|
256
256
|
}
|
|
257
257
|
else {
|
|
258
|
-
|
|
258
|
+
const noSvc = servicesUnavailable(host.platform);
|
|
259
|
+
add("warn", "wake rights", `${who}, but no worker is running here, so nothing can be woken`, noSvc
|
|
260
|
+
? "Pantheon does not run in the background on Windows yet, so a peer's act waits until your agent is open"
|
|
261
|
+
: "start one with `pantheon service install worker --project <a git repo>`; until then a peer's act waits for you to type", `${wakers.length} may wake; worker not running`);
|
|
259
262
|
}
|
|
260
263
|
}
|
|
261
264
|
if (host.desktop) {
|
package/dist/host-env.js
CHANGED
|
@@ -40,9 +40,10 @@ export function hostEnv(env = process.env, plat = process.platform, exists = exi
|
|
|
40
40
|
desktop: false,
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
+
export const platformName = (p) => p === "win32" ? "Windows" : p === "darwin" ? "macOS" : p === "linux" ? "Linux" : p;
|
|
43
44
|
export function ephemeralWarning(host) {
|
|
44
45
|
return `this looks like ${host.kind === "container" ? "a container" : "a cloud workspace"}, not the computer you work on `
|
|
45
|
-
+ `(${host.evidence.join("; ")}). That is why this machine reports ${host.platform}: your editor's agent is running `
|
|
46
|
+
+ `(${host.evidence.join("; ")}). That is why this machine reports ${platformName(host.platform)}: your editor's agent is running `
|
|
46
47
|
+ `somewhere else, so the menu bar and desktop alerts cannot be installed, and anything installed here disappears with `
|
|
47
48
|
+ `the session. Your account and team are fine — run the same setup from a terminal on your own computer to finish it.`;
|
|
48
49
|
}
|
|
@@ -50,8 +51,8 @@ export function desktopUnavailable(host, what) {
|
|
|
50
51
|
if (host.desktop)
|
|
51
52
|
return null;
|
|
52
53
|
if (host.ephemeral) {
|
|
53
|
-
return `not available — ${what} ${what === "desktop alerts" ? "need" : "needs"} your own computer, and this is ${host.kind === "container" ? "a container" : "a cloud workspace"} reporting ${host.platform}`;
|
|
54
|
+
return `not available — ${what} ${what === "desktop alerts" ? "need" : "needs"} your own computer, and this is ${host.kind === "container" ? "a container" : "a cloud workspace"} reporting ${platformName(host.platform)}`;
|
|
54
55
|
}
|
|
55
|
-
return `not available — ${what} ${host.platform === "darwin" ? "could not be built here" : `${what === "desktop alerts" ? "are" : "is"} macOS-only, and this machine is ${host.platform}`}`;
|
|
56
|
+
return `not available — ${what} ${host.platform === "darwin" ? "could not be built here" : `${what === "desktop alerts" ? "are" : "is"} macOS-only, and this machine is ${platformName(host.platform)}`}`;
|
|
56
57
|
}
|
|
57
58
|
//# sourceMappingURL=host-env.js.map
|
package/dist/quickstart.js
CHANGED
|
@@ -9,7 +9,7 @@ import { newKeypair } from "./identity.js";
|
|
|
9
9
|
import { installForUser } from "./install.js";
|
|
10
10
|
import { writeIntent, installHooks } from "./notify.js";
|
|
11
11
|
import { detectAvailable, agentById } from "./agents.js";
|
|
12
|
-
import { installService } from "./service.js";
|
|
12
|
+
import { installService, servicesUnavailable } from "./service.js";
|
|
13
13
|
import { ensureNativeNotifier } from "./notifier.js";
|
|
14
14
|
import { ensureTrayBinary, writeTrayCommands } from "./tray.js";
|
|
15
15
|
import { desktopUnavailable, ephemeralWarning, hostEnv } from "./host-env.js";
|
|
@@ -30,6 +30,7 @@ export function wireUp(opts, deps = {}) {
|
|
|
30
30
|
const ensureNotifier = deps.ensureNotifier ?? ensureNativeNotifier;
|
|
31
31
|
const ensureTray = deps.ensureTray ?? ensureTrayBinary;
|
|
32
32
|
const host = deps.host ?? hostEnv();
|
|
33
|
+
const noServices = servicesUnavailable(host.platform);
|
|
33
34
|
const tools = installForUser().map((t) => ({ tool: t.tool, status: t.status }));
|
|
34
35
|
const granted = [];
|
|
35
36
|
const warnings = [];
|
|
@@ -92,6 +93,9 @@ export function wireUp(opts, deps = {}) {
|
|
|
92
93
|
if (how === "off") {
|
|
93
94
|
tools.push({ tool: "worker", status: "off (--no-worker) — this machine cannot answer the team while you are away" });
|
|
94
95
|
}
|
|
96
|
+
else if (opts.unattended && noServices) {
|
|
97
|
+
tools.push({ tool: "worker", status: noServices });
|
|
98
|
+
}
|
|
95
99
|
else if (opts.unattended) {
|
|
96
100
|
const project = opts.unattended;
|
|
97
101
|
const isRepo = sh(`git -C ${JSON.stringify(project)} rev-parse --is-inside-work-tree 2>/dev/null`) === "true";
|
package/dist/service.js
CHANGED
|
@@ -13,6 +13,12 @@ const SERVICE_BASE_PATH = [
|
|
|
13
13
|
export function servicePath(envPath = process.env.PATH ?? "") {
|
|
14
14
|
return [...new Set([...envPath.split(":"), ...SERVICE_BASE_PATH].filter(Boolean))].join(":");
|
|
15
15
|
}
|
|
16
|
+
export function servicesUnavailable(plat = platform()) {
|
|
17
|
+
if (plat !== "win32")
|
|
18
|
+
return null;
|
|
19
|
+
return "not available — Pantheon does not run in the background on Windows yet. "
|
|
20
|
+
+ "Your agent still answers peers whenever it is open; nothing runs here while you are away.";
|
|
21
|
+
}
|
|
16
22
|
export function plistPath(kind = "worker") {
|
|
17
23
|
return join(homedir(), "Library", "LaunchAgents", `${LABEL(kind)}.plist`);
|
|
18
24
|
}
|
|
@@ -87,6 +93,9 @@ WantedBy=default.target
|
|
|
87
93
|
`;
|
|
88
94
|
}
|
|
89
95
|
export function installService(kind, cwd, args) {
|
|
96
|
+
const noServices = servicesUnavailable();
|
|
97
|
+
if (noServices)
|
|
98
|
+
throw new Error(noServices.replace(/^not available — /, ""));
|
|
90
99
|
const out = [];
|
|
91
100
|
const abs = resolve(cwd);
|
|
92
101
|
const logDir = join(abs, ".pantheon");
|
|
@@ -134,6 +143,14 @@ export function installService(kind, cwd, args) {
|
|
|
134
143
|
}
|
|
135
144
|
export function uninstallService(kind) {
|
|
136
145
|
const out = [];
|
|
146
|
+
if (platform() === "win32") {
|
|
147
|
+
const stray = unitPath(kind);
|
|
148
|
+
if (existsSync(stray)) {
|
|
149
|
+
unlinkSync(stray);
|
|
150
|
+
return [` removed ${stray}`];
|
|
151
|
+
}
|
|
152
|
+
return [` no ${kind} service installed`];
|
|
153
|
+
}
|
|
137
154
|
if (platform() === "darwin") {
|
|
138
155
|
const p = plistPath(kind);
|
|
139
156
|
if (!existsSync(p))
|
|
@@ -188,6 +205,8 @@ export function restartService(kind, exec = (c, a) => execFileSync(c, a, { stdio
|
|
|
188
205
|
}
|
|
189
206
|
export function serviceInstalled(kind) {
|
|
190
207
|
try {
|
|
208
|
+
if (platform() === "win32")
|
|
209
|
+
return false;
|
|
191
210
|
return existsSync(platform() === "darwin" ? plistPath(kind) : unitPath(kind));
|
|
192
211
|
}
|
|
193
212
|
catch {
|
package/dist/which.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
2
|
import { accessSync, constants, existsSync, statSync } from "node:fs";
|
|
3
|
-
import { win32 } from "node:path";
|
|
3
|
+
import { posix, win32 } from "node:path";
|
|
4
4
|
import { platform } from "node:os";
|
|
5
5
|
export const DEFAULT_PATHEXT = ".COM;.EXE;.BAT;.CMD;.VBS;.JS;.PS1";
|
|
6
6
|
const isWindows = (os = platform()) => os === "win32";
|
|
@@ -43,6 +43,23 @@ export function whichWindows(name, env = process.env, exists = runnable) {
|
|
|
43
43
|
export function which(name, os = platform(), env = process.env) {
|
|
44
44
|
if (isWindows(os))
|
|
45
45
|
return whichWindows(name, env);
|
|
46
|
+
return loginShellWhich(name) ?? posixOnPath(name, env);
|
|
47
|
+
}
|
|
48
|
+
function posixOnPath(name, env) {
|
|
49
|
+
if (!name)
|
|
50
|
+
return null;
|
|
51
|
+
if (name.includes("/"))
|
|
52
|
+
return runnable(name) ? name : null;
|
|
53
|
+
for (const dir of (env.PATH ?? "").split(":")) {
|
|
54
|
+
if (!dir)
|
|
55
|
+
continue;
|
|
56
|
+
const full = posix.join(dir, name);
|
|
57
|
+
if (runnable(full))
|
|
58
|
+
return full;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
function loginShellWhich(name) {
|
|
46
63
|
try {
|
|
47
64
|
const out = execFileSync("sh", ["-lc", `command -v ${name}`], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
48
65
|
if (!out)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@join-pantheon/cli",
|
|
3
|
-
"version": "0.26.
|
|
4
|
-
"description": "Let your coding agent collaborate directly with your teammates' agents
|
|
3
|
+
"version": "0.26.2",
|
|
4
|
+
"description": "Let your coding agent collaborate directly with your teammates' agents — ask, agree an interface, and deliver, without a human relaying messages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"pantheon": "bin/pantheon.js"
|