@getdial/cli 0.8.0 → 0.9.0

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.
@@ -1,5 +1,5 @@
1
1
  import { readAuth } from "../../lib/state.js";
2
- import { installSupervised } from "../../lib/supervisor/index.js";
2
+ import { installSupervised, supervisorAvailability } from "../../lib/supervisor/index.js";
3
3
  function resolveDialPath() {
4
4
  return process.env.DIAL_BIN_OVERRIDE ?? process.argv[1] ?? "dial";
5
5
  }
@@ -12,6 +12,14 @@ export async function runListenInstall(opts) {
12
12
  console.error("Not signed in. Run `dial signup` and `dial onboard` first.");
13
13
  return 1;
14
14
  }
15
+ const supervisor = supervisorAvailability();
16
+ if (!supervisor.available) {
17
+ if (opts.json)
18
+ console.log(JSON.stringify({ ok: false, code: "supervisor_unavailable", error: supervisor.reason }));
19
+ else
20
+ console.error(`listen install unavailable: ${supervisor.reason}. This machine has no user-level service supervisor (sandbox/container/CI). Inbound events still work via \`dial wait-for\`; only the always-on background listener and \`dial local-target\` fan-out are unavailable here.`);
21
+ return 2;
22
+ }
15
23
  try {
16
24
  const result = installSupervised(resolveDialPath());
17
25
  if (opts.json)
@@ -2,6 +2,7 @@ import { readPendingSignup, clearPendingSignup, writeAuth } from "../lib/state.j
2
2
  import { apiPost } from "../lib/api.js";
3
3
  import { paths } from "../lib/paths.js";
4
4
  import { installSkill, isSupportedAgent, SUPPORTED_AGENTS } from "../lib/skill-install.js";
5
+ import { supervisorAvailability } from "../lib/supervisor/index.js";
5
6
  function maskApiKey(key) {
6
7
  return key.length >= 4 ? `sk_live_***${key.slice(-4)}` : "sk_live_***";
7
8
  }
@@ -68,6 +69,7 @@ export async function runOnboard(opts) {
68
69
  skillResults.push({ agent: requested, error: err instanceof Error ? err.message : String(err) });
69
70
  }
70
71
  }
72
+ const supervisor = supervisorAvailability();
71
73
  if (opts.json) {
72
74
  console.log(JSON.stringify({
73
75
  ok: true,
@@ -77,19 +79,31 @@ export async function runOnboard(opts) {
77
79
  accountId: res.data.accountId,
78
80
  phoneNumber: res.data.phoneNumber ?? null,
79
81
  phoneNumberId: res.data.phoneNumberId ?? null,
80
- listen: { installed: false, autoInstalled: false },
81
- skills: skillResults,
82
- agentHint: {
83
- action: "ask_user",
84
- kind: "onboarding_finalization",
85
- question: LISTEN_QUESTION,
86
- rationale: LISTEN_RATIONALE,
87
- presentation: PRESENTATION_HINT,
88
- finalizationNote: FINALIZATION_HINT,
89
- useStructuredToolIfAvailable: true,
90
- onYes: "dial listen install",
91
- onNo: null,
82
+ listen: {
83
+ installed: false,
84
+ autoInstalled: false,
85
+ canInstall: supervisor.available,
86
+ unavailableReason: supervisor.available ? null : supervisor.reason,
92
87
  },
88
+ skills: skillResults,
89
+ agentHint: supervisor.available
90
+ ? {
91
+ action: "ask_user",
92
+ kind: "onboarding_finalization",
93
+ question: LISTEN_QUESTION,
94
+ rationale: LISTEN_RATIONALE,
95
+ presentation: PRESENTATION_HINT,
96
+ finalizationNote: FINALIZATION_HINT,
97
+ useStructuredToolIfAvailable: true,
98
+ onYes: "dial listen install",
99
+ onNo: null,
100
+ }
101
+ : {
102
+ action: "skip",
103
+ kind: "listen_install_unavailable",
104
+ reason: supervisor.reason,
105
+ note: "No user-level service supervisor on this machine (sandbox/container/CI). Skip the install offer and continue with the original task. Inbound events are still reachable via `dial wait-for` (long-poll); only the always-on background listener and `dial local-target` fan-out are unavailable here.",
106
+ },
93
107
  }));
94
108
  }
95
109
  else {
@@ -109,6 +123,12 @@ export async function runOnboard(opts) {
109
123
  }
110
124
  }
111
125
  console.log(``);
126
+ if (!supervisor.available) {
127
+ console.log(`listen service: not available on this machine (${supervisor.reason}).`);
128
+ console.log(`Skipping the install offer. Inbound events still work via \`dial wait-for\` (long-poll);`);
129
+ console.log(`only the always-on background listener and \`dial local-target\` fan-out are unavailable here.`);
130
+ return 0;
131
+ }
112
132
  console.log(`Onboarding finalization (required):`);
113
133
  console.log(``);
114
134
  console.log(FINALIZATION_HINT);
@@ -11,6 +11,28 @@ export function currentPlatform() {
11
11
  return "linux";
12
12
  throw new Error(`Unsupported platform: ${process.platform} (macOS and Linux only)`);
13
13
  }
14
+ /**
15
+ * Detects whether a user-level service supervisor (launchd on macOS,
16
+ * systemd --user on Linux) is reachable on this machine. Returns
17
+ * unavailable for sandboxes / containers / CI runners where the user
18
+ * bus is missing — `dial listen install` would fail there with errors
19
+ * like "Failed to connect to bus: No medium found".
20
+ */
21
+ export function supervisorAvailability() {
22
+ if (process.platform === "darwin")
23
+ return { available: true };
24
+ if (process.platform !== "linux") {
25
+ return { available: false, reason: `unsupported platform: ${process.platform}` };
26
+ }
27
+ const runtimeDir = process.env.XDG_RUNTIME_DIR;
28
+ if (!runtimeDir) {
29
+ return { available: false, reason: "XDG_RUNTIME_DIR is not set (no systemd user session)" };
30
+ }
31
+ if (!existsSync(`${runtimeDir}/systemd/private`)) {
32
+ return { available: false, reason: "systemd user bus socket not found (sandbox or container without systemd --user)" };
33
+ }
34
+ return { available: true };
35
+ }
14
36
  export function installSupervised(programPath) {
15
37
  const platform = currentPlatform();
16
38
  const p = paths();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getdial/cli",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Dial CLI — install, sign up, and run the local listen service.",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -35,5 +35,8 @@
35
35
  "@types/node": "^22.10.0",
36
36
  "tsx": "^4.22.3",
37
37
  "typescript": "^5.6.0"
38
+ },
39
+ "overrides": {
40
+ "react-native-url-polyfill": "npm:empty-npm-package@1.0.0"
38
41
  }
39
42
  }
package/skill.tar.gz CHANGED
Binary file