@getdial/cli 0.33.1 → 0.33.3

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.
Files changed (45) hide show
  1. package/dist/cli.js +1 -3
  2. package/dist/commands/call/list.js +5 -1
  3. package/dist/commands/listen/index.js +17 -3
  4. package/dist/commands/listen/install.js +7 -2
  5. package/dist/commands/listen/status.js +11 -7
  6. package/dist/commands/message/list.js +5 -1
  7. package/dist/commands/message/reply.js +5 -1
  8. package/dist/commands/number/set.js +6 -2
  9. package/dist/commands/onboard.js +17 -5
  10. package/dist/commands/signup.js +7 -1
  11. package/dist/commands/typing/start.js +5 -1
  12. package/dist/commands/typing/stop.js +5 -1
  13. package/dist/commands/uninstall.js +3 -1
  14. package/dist/commands/wait-for.js +2 -2
  15. package/dist/lib/api.js +24 -5
  16. package/dist/lib/cli-error.js +6 -1
  17. package/dist/lib/fanout.js +5 -3
  18. package/dist/lib/log-tail.js +5 -2
  19. package/dist/lib/log.js +2 -2
  20. package/dist/lib/ops/account.js +20 -7
  21. package/dist/lib/ops/calls.js +3 -1
  22. package/dist/lib/ops/events.js +6 -1
  23. package/dist/lib/ops/listen.js +8 -1
  24. package/dist/lib/ops/uninstall.js +9 -3
  25. package/dist/lib/pubnub.js +47 -9
  26. package/dist/lib/ref-params.js +37 -0
  27. package/dist/lib/skill-install.js +1 -1
  28. package/dist/lib/supervisor/index.js +6 -3
  29. package/dist/lib/supervisor/launchd.js +13 -4
  30. package/dist/lib/supervisor/systemd.js +3 -1
  31. package/dist/lib/versioned-file.js +1 -1
  32. package/dist/mcp/schemas.js +22 -5
  33. package/dist/mcp/server.js +1 -3
  34. package/dist/mcp/tools/add-command-target.js +14 -3
  35. package/dist/mcp/tools/add-url-target.js +22 -5
  36. package/dist/mcp/tools/get-account-status.js +3 -1
  37. package/dist/mcp/tools/onboard.js +26 -7
  38. package/dist/mcp/tools/place-call.js +34 -8
  39. package/dist/mcp/tools/purchase-number.js +21 -5
  40. package/dist/mcp/tools/reply-to-message.js +4 -1
  41. package/dist/mcp/tools/send-message.js +8 -2
  42. package/dist/mcp/tools/set-number-properties.js +34 -8
  43. package/dist/mcp/tools/wait-for-event.js +12 -3
  44. package/package.json +5 -1
  45. package/skills.tar.gz +0 -0
package/dist/cli.js CHANGED
@@ -99,9 +99,7 @@ if (!sandbox) {
99
99
  .option("--json", "machine-readable output")
100
100
  .action(async (opts) => process.exit(await runListenStatus({ json: !!opts.json })));
101
101
  }
102
- const number = program
103
- .command("number")
104
- .description("Manage your Dial phone numbers.");
102
+ const number = program.command("number").description("Manage your Dial phone numbers.");
105
103
  number
106
104
  .command("list")
107
105
  .description("List the numbers on your account. GET /api/v1/numbers.")
@@ -3,7 +3,11 @@ import { isDialError } from "../../lib/ops/errors.js";
3
3
  import { printDialError } from "../../lib/cli-error.js";
4
4
  export async function runCallList(opts) {
5
5
  try {
6
- const calls = await listCalls({ numberId: opts.numberId, direction: opts.direction, since: opts.since });
6
+ const calls = await listCalls({
7
+ numberId: opts.numberId,
8
+ direction: opts.direction,
9
+ since: opts.since,
10
+ });
7
11
  if (opts.json) {
8
12
  console.log(JSON.stringify({ ok: true, calls }));
9
13
  return 0;
@@ -11,17 +11,31 @@ function isSupervised() {
11
11
  export async function runListen() {
12
12
  const auth = readAuth();
13
13
  if (!auth) {
14
- appendJsonl(paths().listenLog, { ts: new Date().toISOString(), lifecycle: "startup", ok: false, error: "no saved auth" });
14
+ appendJsonl(paths().listenLog, {
15
+ ts: new Date().toISOString(),
16
+ lifecycle: "startup",
17
+ ok: false,
18
+ error: "no saved auth",
19
+ });
15
20
  if (isSupervised()) {
16
21
  await delay(30_000);
17
22
  }
18
23
  return 1;
19
24
  }
20
- appendJsonl(paths().listenLog, { ts: new Date().toISOString(), lifecycle: "startup", ok: true, accountId: auth.accountId });
25
+ appendJsonl(paths().listenLog, {
26
+ ts: new Date().toISOString(),
27
+ lifecycle: "startup",
28
+ ok: true,
29
+ accountId: auth.accountId,
30
+ });
21
31
  recordListenVersion();
22
32
  const ctrl = startWorker(auth.apiKey, auth.accountId);
23
33
  const onSignal = async (sig) => {
24
- appendJsonl(paths().listenLog, { ts: new Date().toISOString(), lifecycle: "shutdown", signal: sig });
34
+ appendJsonl(paths().listenLog, {
35
+ ts: new Date().toISOString(),
36
+ lifecycle: "shutdown",
37
+ signal: sig,
38
+ });
25
39
  await ctrl.stop();
26
40
  };
27
41
  process.on("SIGTERM", onSignal);
@@ -1,5 +1,5 @@
1
1
  import { readAuth } from "../../lib/state.js";
2
- import { installSupervised, resolveListenCommand, supervisorAvailability } from "../../lib/supervisor/index.js";
2
+ import { installSupervised, resolveListenCommand, supervisorAvailability, } from "../../lib/supervisor/index.js";
3
3
  export async function runListenInstall(opts) {
4
4
  const auth = readAuth();
5
5
  if (!auth) {
@@ -20,7 +20,12 @@ export async function runListenInstall(opts) {
20
20
  try {
21
21
  const result = installSupervised(resolveListenCommand());
22
22
  if (opts.json)
23
- console.log(JSON.stringify({ ok: true, changed: result.changed, unit_path: result.unitPath, warnings: result.warnings }));
23
+ console.log(JSON.stringify({
24
+ ok: true,
25
+ changed: result.changed,
26
+ unit_path: result.unitPath,
27
+ warnings: result.warnings,
28
+ }));
24
29
  else {
25
30
  console.log(`listen service installed${result.changed ? "" : " (no change)"}.`);
26
31
  console.log(` unit: ${result.unitPath}`);
@@ -8,14 +8,18 @@ export async function runListenStatus(opts) {
8
8
  try {
9
9
  const raw = readFileSync(paths().listenLog, "utf8");
10
10
  const lines = raw.trim().split("\n").filter(Boolean);
11
- lastEvents = lines.slice(-5).map((l) => { try {
12
- return JSON.parse(l);
13
- }
14
- catch {
15
- return l;
16
- } });
11
+ lastEvents = lines.slice(-5).map((l) => {
12
+ try {
13
+ return JSON.parse(l);
14
+ }
15
+ catch {
16
+ return l;
17
+ }
18
+ });
19
+ }
20
+ catch {
21
+ /* ignore */
17
22
  }
18
- catch { /* ignore */ }
19
23
  const out = {
20
24
  installed: s.installed,
21
25
  running: s.running,
@@ -3,7 +3,11 @@ import { isDialError } from "../../lib/ops/errors.js";
3
3
  import { printDialError } from "../../lib/cli-error.js";
4
4
  export async function runMessageList(opts) {
5
5
  try {
6
- const messages = await listMessages({ numberId: opts.numberId, direction: opts.direction, since: opts.since });
6
+ const messages = await listMessages({
7
+ numberId: opts.numberId,
8
+ direction: opts.direction,
9
+ since: opts.since,
10
+ });
7
11
  if (opts.json) {
8
12
  console.log(JSON.stringify({ ok: true, messages }));
9
13
  return 0;
@@ -3,7 +3,11 @@ import { isDialError } from "../../lib/ops/errors.js";
3
3
  import { printDialError } from "../../lib/cli-error.js";
4
4
  export async function runMessageReply(opts) {
5
5
  try {
6
- const m = await replyToMessage({ messageId: opts.messageId, body: opts.body, reaction: opts.react });
6
+ const m = await replyToMessage({
7
+ messageId: opts.messageId,
8
+ body: opts.body,
9
+ reaction: opts.react,
10
+ });
7
11
  if (opts.json) {
8
12
  console.log(JSON.stringify({ ok: true, message: m }));
9
13
  }
@@ -6,10 +6,14 @@ export async function runNumberSet(opts) {
6
6
  const n = await setNumberProperties({
7
7
  number: opts.number,
8
8
  inboundInstruction: opts.inboundInstruction,
9
- ...(opts.inboundVoiceGender !== undefined ? { inboundVoiceGender: opts.inboundVoiceGender } : {}),
9
+ ...(opts.inboundVoiceGender !== undefined
10
+ ? { inboundVoiceGender: opts.inboundVoiceGender }
11
+ : {}),
10
12
  ...(opts.inboundLanguage !== undefined ? { inboundLanguage: opts.inboundLanguage } : {}),
11
13
  ...(opts.nickname !== undefined ? { nickname: opts.nickname } : {}),
12
- ...(opts.maxCallDurationSeconds !== undefined ? { maxCallDurationSeconds: opts.maxCallDurationSeconds } : {}),
14
+ ...(opts.maxCallDurationSeconds !== undefined
15
+ ? { maxCallDurationSeconds: opts.maxCallDurationSeconds }
16
+ : {}),
13
17
  });
14
18
  if (opts.json) {
15
19
  console.log(JSON.stringify({ ok: true, number: n }));
@@ -1,7 +1,7 @@
1
1
  import { onboard } from "../lib/ops/account.js";
2
2
  import { isDialError } from "../lib/ops/errors.js";
3
3
  import { readAuth, authFilePath } from "../lib/state.js";
4
- import { installSkill, isSupportedAgent, SUPPORTED_AGENTS } from "../lib/skill-install.js";
4
+ import { installSkill, isSupportedAgent, SUPPORTED_AGENTS, } from "../lib/skill-install.js";
5
5
  import { supervisorAvailability } from "../lib/supervisor/index.js";
6
6
  function maskApiKey(key) {
7
7
  return key.length >= 4 ? `sk_live_***${key.slice(-4)}` : "sk_live_***";
@@ -13,7 +13,10 @@ function installAgentSkills(agents) {
13
13
  const skills = [];
14
14
  for (const requested of agents) {
15
15
  if (!isSupportedAgent(requested)) {
16
- skills.push({ agent: requested, error: `unknown agent "${requested}". Supported: ${SUPPORTED_AGENTS.join(", ")}.` });
16
+ skills.push({
17
+ agent: requested,
18
+ error: `unknown agent "${requested}". Supported: ${SUPPORTED_AGENTS.join(", ")}.`,
19
+ });
17
20
  continue;
18
21
  }
19
22
  try {
@@ -30,7 +33,7 @@ const LISTEN_RATIONALE = "The background notification listening service runs on
30
33
  "Without it the agent is send-only: it can place outbound calls and send messages, but it has no way to know when something arrives at your Dial number. " +
31
34
  "It can always be installed later with `dial listen install`.";
32
35
  const PRESENTATION_HINT = "When you ask the user, describe it as \"the background notification listening service.\" Don't expose technical details (launchd, plists, daemons, systemd units) — that's not how to talk about it to a non-technical user.";
33
- const FINALIZATION_HINT = "To finalize onboarding, ask the user this question before continuing with any other task. If the user's original request was something else (e.g. \"call X\", \"send Y\"), briefly pause that task, ask the question, get an answer, then resume.";
36
+ const FINALIZATION_HINT = 'To finalize onboarding, ask the user this question before continuing with any other task. If the user\'s original request was something else (e.g. "call X", "send Y"), briefly pause that task, ask the question, get an answer, then resume.';
34
37
  export async function runOnboard(opts) {
35
38
  // Skill-install-only branch: when --code isn't supplied, we can't (and shouldn't)
36
39
  // re-verify — but if the machine is already signed in, the useful thing to do
@@ -59,9 +62,18 @@ export async function runOnboard(opts) {
59
62
  accountId: auth.accountId,
60
63
  phoneNumber: auth.phoneNumber ?? null,
61
64
  phoneNumberId: auth.phoneNumberId ?? null,
62
- listen: { installed: false, autoInstalled: false, canInstall: supervisor.available, unavailableReason: supervisor.available ? null : supervisor.reason },
65
+ listen: {
66
+ installed: false,
67
+ autoInstalled: false,
68
+ canInstall: supervisor.available,
69
+ unavailableReason: supervisor.available ? null : supervisor.reason,
70
+ },
63
71
  skills,
64
- agentHint: { action: "skip", kind: "already_signed_in", note: "Account is already signed in; verification was skipped and only the requested --agent skills were installed." },
72
+ agentHint: {
73
+ action: "skip",
74
+ kind: "already_signed_in",
75
+ note: "Account is already signed in; verification was skipped and only the requested --agent skills were installed.",
76
+ },
65
77
  }));
66
78
  }
67
79
  else {
@@ -18,7 +18,13 @@ export async function runSignup(email, opts) {
18
18
  if (e.code === "pending_exists") {
19
19
  const d = e.data ?? {};
20
20
  if (opts.json) {
21
- console.log(JSON.stringify({ ok: false, code: "pending_exists", verificationId: d.verificationId, email: d.email, ageSeconds: d.ageSeconds }));
21
+ console.log(JSON.stringify({
22
+ ok: false,
23
+ code: "pending_exists",
24
+ verificationId: d.verificationId,
25
+ email: d.email,
26
+ ageSeconds: d.ageSeconds,
27
+ }));
22
28
  }
23
29
  else {
24
30
  console.error(e.message);
@@ -3,7 +3,11 @@ import { isDialError } from "../../lib/ops/errors.js";
3
3
  import { printDialError } from "../../lib/cli-error.js";
4
4
  export async function runTypingStart(opts) {
5
5
  try {
6
- const result = await setTyping({ toNumber: opts.toNumber, value: true, fromNumber: opts.fromNumber });
6
+ const result = await setTyping({
7
+ toNumber: opts.toNumber,
8
+ value: true,
9
+ fromNumber: opts.fromNumber,
10
+ });
7
11
  if (opts.json) {
8
12
  console.log(JSON.stringify(result));
9
13
  }
@@ -3,7 +3,11 @@ import { isDialError } from "../../lib/ops/errors.js";
3
3
  import { printDialError } from "../../lib/cli-error.js";
4
4
  export async function runTypingStop(opts) {
5
5
  try {
6
- const result = await setTyping({ toNumber: opts.toNumber, value: false, fromNumber: opts.fromNumber });
6
+ const result = await setTyping({
7
+ toNumber: opts.toNumber,
8
+ value: false,
9
+ fromNumber: opts.fromNumber,
10
+ });
7
11
  if (opts.json) {
8
12
  console.log(JSON.stringify(result));
9
13
  }
@@ -16,7 +16,9 @@ export async function runUninstall(opts) {
16
16
  ? `agent skills: removed from ${removedSkills.map((s) => s.agent).join(", ")}`
17
17
  : "agent skills: none installed");
18
18
  const removedDirs = report.dirs.filter((d) => d.removed);
19
- console.log(removedDirs.length ? `state dirs: removed ${removedDirs.map((d) => d.path).join(", ")}` : "state dirs: none present");
19
+ console.log(removedDirs.length
20
+ ? `state dirs: removed ${removedDirs.map((d) => d.path).join(", ")}`
21
+ : "state dirs: none present");
20
22
  for (const e of report.errors) {
21
23
  console.error(`error in ${e.step}: ${e.message}`);
22
24
  }
@@ -19,7 +19,7 @@ export async function runWaitFor(opts) {
19
19
  }
20
20
  // Hit: print the raw line and succeed.
21
21
  if (!r.timedOut && r.line != null) {
22
- process.stdout.write(r.line + "\n");
22
+ process.stdout.write(`${r.line}\n`);
23
23
  return 0;
24
24
  }
25
25
  // Timed out tailing the log, but there was an earlier matching entry.
@@ -29,7 +29,7 @@ export async function runWaitFor(opts) {
29
29
  }
30
30
  else {
31
31
  console.error(`timed out after ${opts.timeoutSeconds}s; latest matching entry in log:`);
32
- process.stdout.write(r.line + "\n");
32
+ process.stdout.write(`${r.line}\n`);
33
33
  }
34
34
  return 1;
35
35
  }
package/dist/lib/api.js CHANGED
@@ -1,6 +1,7 @@
1
- import { request, fetch as undiciFetch, FormData as UndiciFormData, setGlobalDispatcher, EnvHttpProxyAgent } from "undici";
1
+ import { request, fetch as undiciFetch, FormData as UndiciFormData, setGlobalDispatcher, EnvHttpProxyAgent, } from "undici";
2
2
  import { logger } from "./log.js";
3
3
  import { VERSION } from "./version.js";
4
+ import { refParamsHeader } from "./ref-params.js";
4
5
  // Route this package's undici requests through HTTP(S)_PROXY when one is set.
5
6
  // The `undici` npm package keeps its OWN global dispatcher, which — unlike
6
7
  // Node's built-in fetch (wired by NODE_USE_ENV_PROXY) — ignores the proxy env
@@ -8,7 +9,10 @@ import { VERSION } from "./version.js";
8
9
  // OneCLI gateway sits on HTTPS_PROXY and injects the Authorization header for
9
10
  // api.getdial.ai) our `request()`/`fetch()` calls would otherwise bypass the
10
11
  // gateway entirely and go out UNAUTHENTICATED → 401. Opt in explicitly.
11
- if (process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy) {
12
+ if (process.env.HTTPS_PROXY ||
13
+ process.env.https_proxy ||
14
+ process.env.HTTP_PROXY ||
15
+ process.env.http_proxy) {
12
16
  setGlobalDispatcher(new EnvHttpProxyAgent());
13
17
  }
14
18
  // The bundled undici only multipart-encodes its own FormData class (realm
@@ -21,6 +25,15 @@ const USER_AGENT = `@getdial/cli/${VERSION}`;
21
25
  export function baseUrl() {
22
26
  return process.env.DIAL_API_URL ?? DEFAULT_BASE;
23
27
  }
28
+ // Attach the attribution ref params (base64 of the install-time ref-params.txt)
29
+ // so the server can tie this machine's requests to how the user originally
30
+ // arrived. No-op when the user never went through an attributed install.
31
+ export function applyRefParamsHeader(headers) {
32
+ const ref = refParamsHeader();
33
+ if (ref)
34
+ headers["x-dial-ref-params"] = ref;
35
+ return headers;
36
+ }
24
37
  export async function apiPost(path, body, apiKey, extraHeaders) {
25
38
  return apiRequest("POST", path, body, apiKey, extraHeaders);
26
39
  }
@@ -35,7 +48,9 @@ function toResult(statusCode, text) {
35
48
  try {
36
49
  parsed = text ? JSON.parse(text) : null;
37
50
  }
38
- catch { /* keep raw */ }
51
+ catch {
52
+ /* keep raw */
53
+ }
39
54
  if (statusCode >= 200 && statusCode < 300) {
40
55
  return { ok: true, status: statusCode, data: parsed };
41
56
  }
@@ -52,7 +67,11 @@ function toResult(statusCode, text) {
52
67
  }
53
68
  async function apiRequest(method, path, body, apiKey, extraHeaders) {
54
69
  const url = `${baseUrl()}${path}`;
55
- const headers = { "content-type": "application/json", "user-agent": USER_AGENT, ...(extraHeaders ?? {}) };
70
+ const headers = applyRefParamsHeader({
71
+ "content-type": "application/json",
72
+ "user-agent": USER_AGENT,
73
+ ...(extraHeaders ?? {}),
74
+ });
56
75
  if (apiKey)
57
76
  headers.authorization = `Bearer ${apiKey}`;
58
77
  try {
@@ -70,7 +89,7 @@ async function apiRequest(method, path, body, apiKey, extraHeaders) {
70
89
  /** POST a multipart/form-data body (file uploads). fetch sets the boundary header itself. */
71
90
  export async function apiPostMultipart(path, form, apiKey) {
72
91
  const url = `${baseUrl()}${path}`;
73
- const headers = {};
92
+ const headers = applyRefParamsHeader({});
74
93
  if (apiKey)
75
94
  headers.authorization = `Bearer ${apiKey}`;
76
95
  try {
@@ -16,7 +16,12 @@ const EXIT_1_CODES = new Set([
16
16
  */
17
17
  export function printDialError(json, e) {
18
18
  if (json) {
19
- console.log(JSON.stringify({ ok: false, code: e.code, message: e.message, ...(e.status ? { status: e.status } : {}) }));
19
+ console.log(JSON.stringify({
20
+ ok: false,
21
+ code: e.code,
22
+ message: e.message,
23
+ ...(e.status ? { status: e.status } : {}),
24
+ }));
20
25
  }
21
26
  else {
22
27
  console.error(e.message);
@@ -7,12 +7,12 @@ function clipCapture(buf) {
7
7
  const s = typeof buf === "string" ? buf : buf.toString("utf8");
8
8
  if (s.length <= MAX_CAPTURE_BYTES)
9
9
  return s;
10
- return s.slice(0, MAX_CAPTURE_BYTES) + `…[truncated, total ${s.length} chars]`;
10
+ return `${s.slice(0, MAX_CAPTURE_BYTES)}…[truncated, total ${s.length} chars]`;
11
11
  }
12
12
  async function attemptUrl(target, body) {
13
13
  const headers = { "Content-Type": "application/json" };
14
14
  if (target.bearer)
15
- headers["Authorization"] = `Bearer ${target.bearer}`;
15
+ headers.Authorization = `Bearer ${target.bearer}`;
16
16
  if (target.secret) {
17
17
  const sig = createHmac("sha256", target.secret).update(body).digest("hex");
18
18
  headers[target.signatureHeader ?? DEFAULT_SIGNATURE_HEADER] = sig;
@@ -65,7 +65,9 @@ async function attemptCmd(target, eventJson) {
65
65
  try {
66
66
  child.kill("SIGKILL");
67
67
  }
68
- catch { /* already exited */ }
68
+ catch {
69
+ /* already exited */
70
+ }
69
71
  resolve({
70
72
  ok: false,
71
73
  timedOut: true,
@@ -43,7 +43,7 @@ export function findLatestMatch(file, spec) {
43
43
  return { line: lines[i], obj };
44
44
  }
45
45
  catch {
46
- continue;
46
+ // skip unparsable lines
47
47
  }
48
48
  }
49
49
  return null;
@@ -68,7 +68,10 @@ function readRange(file, offset, length) {
68
68
  }
69
69
  }
70
70
  function parseLines(chunk) {
71
- return chunk.split("\n").filter(Boolean).map((line) => {
71
+ return chunk
72
+ .split("\n")
73
+ .filter(Boolean)
74
+ .map((line) => {
72
75
  try {
73
76
  return { line, obj: JSON.parse(line) };
74
77
  }
package/dist/lib/log.js CHANGED
@@ -3,7 +3,7 @@ import { dirname } from "node:path";
3
3
  import pino from "pino";
4
4
  export function appendJsonl(file, obj) {
5
5
  mkdirSync(dirname(file), { recursive: true });
6
- appendFileSync(file, JSON.stringify(obj) + "\n");
6
+ appendFileSync(file, `${JSON.stringify(obj)}\n`);
7
7
  }
8
8
  export const logger = pino({
9
9
  level: process.env.DIAL_LOG_LEVEL ?? "warn",
@@ -30,5 +30,5 @@ export function rotateIfLarge(file, maxBytes) {
30
30
  const raw = readFileSync(file, "utf8");
31
31
  const lines = raw.split("\n").filter(Boolean);
32
32
  const keep = lines.slice(Math.floor(lines.length / 2));
33
- writeFileSync(file, keep.join("\n") + "\n");
33
+ writeFileSync(file, `${keep.join("\n")}\n`);
34
34
  }
@@ -1,9 +1,9 @@
1
- import { readAuth, readPendingSignup, writePendingSignup, clearPendingSignup, writeAuth, authFilePath } from "../state.js";
1
+ import { readAuth, readPendingSignup, writePendingSignup, clearPendingSignup, writeAuth, authFilePath, } from "../state.js";
2
2
  import { apiGet, apiPost, baseUrl, pingBackend } from "../api.js";
3
- import { supervisorStatus, lastEventAtFromLog, supervisorAvailability } from "../supervisor/index.js";
3
+ import { supervisorStatus, lastEventAtFromLog, supervisorAvailability, } from "../supervisor/index.js";
4
4
  import { paths } from "../paths.js";
5
5
  import { VERSION } from "../version.js";
6
- import { installSkill, isSupportedAgent, SUPPORTED_AGENTS } from "../skill-install.js";
6
+ import { installSkill, isSupportedAgent, SUPPORTED_AGENTS, } from "../skill-install.js";
7
7
  import { isSandbox } from "../sandbox.js";
8
8
  import { DialError } from "./errors.js";
9
9
  const OTP_EXPIRY_MS = 10 * 60 * 1000;
@@ -46,7 +46,11 @@ export async function accountStatus() {
46
46
  let listenState = { installed: false, running: false, lastEventAt: null };
47
47
  try {
48
48
  const s = supervisorStatus();
49
- listenState = { installed: s.installed, running: s.running, lastEventAt: lastEventAtFromLog(paths().listenLog) };
49
+ listenState = {
50
+ installed: s.installed,
51
+ running: s.running,
52
+ lastEventAt: lastEventAtFromLog(paths().listenLog),
53
+ };
50
54
  }
51
55
  catch {
52
56
  // unsupported platform — leave defaults
@@ -100,10 +104,16 @@ export async function signup(opts) {
100
104
  throw new DialError("pending_exists", `A pending OTP for ${existing.email} is still fresh (${ageSeconds}s old). Use \`dial onboard --code <code>\` or re-run with --force to start a new one.`, undefined, { verificationId: existing.verificationId, email: existing.email, ageSeconds });
101
105
  }
102
106
  }
103
- const res = await apiPost("/api/v1/auth/signup", { email: opts.email });
107
+ const res = await apiPost("/api/v1/auth/signup", {
108
+ email: opts.email,
109
+ });
104
110
  if (!res.ok)
105
111
  throw new DialError("signup_failed", res.error, res.status);
106
- writePendingSignup({ verificationId: res.data.verificationId, email: opts.email, createdAt: new Date().toISOString() });
112
+ writePendingSignup({
113
+ verificationId: res.data.verificationId,
114
+ email: opts.email,
115
+ createdAt: new Date().toISOString(),
116
+ });
107
117
  return { verificationId: res.data.verificationId, email: opts.email };
108
118
  }
109
119
  export async function onboard(opts) {
@@ -139,7 +149,10 @@ export async function onboard(opts) {
139
149
  const skills = [];
140
150
  for (const requested of opts.agents ?? []) {
141
151
  if (!isSupportedAgent(requested)) {
142
- skills.push({ agent: requested, error: `unknown agent "${requested}". Supported: ${SUPPORTED_AGENTS.join(", ")}.` });
152
+ skills.push({
153
+ agent: requested,
154
+ error: `unknown agent "${requested}". Supported: ${SUPPORTED_AGENTS.join(", ")}.`,
155
+ });
143
156
  continue;
144
157
  }
145
158
  try {
@@ -12,7 +12,9 @@ export async function placeCall(opts) {
12
12
  // Omitted → the server uses the default voice gender (female).
13
13
  ...(opts.voiceGender ? { voiceGender: opts.voiceGender } : {}),
14
14
  ...(opts.transferTo ? { transferTo: opts.transferTo } : {}),
15
- ...(opts.maxCallDurationSeconds !== undefined ? { maxCallDurationSeconds: opts.maxCallDurationSeconds } : {}),
15
+ ...(opts.maxCallDurationSeconds !== undefined
16
+ ? { maxCallDurationSeconds: opts.maxCallDurationSeconds }
17
+ : {}),
16
18
  }, auth?.apiKey, opts.idempotencyKey ? { "idempotency-key": opts.idempotencyKey } : undefined);
17
19
  if (!res.ok)
18
20
  throw new DialError("call_failed", res.error, res.status);
@@ -52,7 +52,12 @@ async function waitFromApi(spec, opts) {
52
52
  timeout,
53
53
  }, auth?.apiKey);
54
54
  if (res.ok && res.data?.event) {
55
- return { source: "api", timedOut: false, event: res.data.event, line: JSON.stringify(res.data.event) };
55
+ return {
56
+ source: "api",
57
+ timedOut: false,
58
+ event: res.data.event,
59
+ line: JSON.stringify(res.data.event),
60
+ };
56
61
  }
57
62
  if (res.ok === false && res.status === 408)
58
63
  continue;
@@ -44,5 +44,12 @@ export function listenStatus() {
44
44
  catch {
45
45
  // no log yet — leave empty
46
46
  }
47
- return { installed: s.installed, running: s.running, pid: s.pid, unitPath: s.unitPath, lastEventAt, lastEvents };
47
+ return {
48
+ installed: s.installed,
49
+ running: s.running,
50
+ pid: s.pid,
51
+ unitPath: s.unitPath,
52
+ lastEventAt,
53
+ lastEvents,
54
+ };
48
55
  }
@@ -1,7 +1,7 @@
1
1
  import { existsSync, rmSync } from "node:fs";
2
2
  import { paths } from "../paths.js";
3
3
  import { SUPPORTED_AGENTS, uninstallSkill } from "../skill-install.js";
4
- import { supervisorAvailability, uninstallSupervised } from "../supervisor/index.js";
4
+ import { supervisorAvailability, uninstallSupervised, } from "../supervisor/index.js";
5
5
  export const UNINSTALL_HINT = "npm uninstall -g @getdial/cli";
6
6
  /**
7
7
  * Full local teardown, best-effort: every step runs even if an earlier one
@@ -33,7 +33,10 @@ export function uninstallEverything(deps = {}) {
33
33
  skills.push(uninstallSkill(agent, { home: deps.home, cwd: deps.cwd }));
34
34
  }
35
35
  catch (err) {
36
- errors.push({ step: `skill:${agent}`, message: err instanceof Error ? err.message : String(err) });
36
+ errors.push({
37
+ step: `skill:${agent}`,
38
+ message: err instanceof Error ? err.message : String(err),
39
+ });
37
40
  }
38
41
  }
39
42
  const p = paths();
@@ -47,7 +50,10 @@ export function uninstallEverything(deps = {}) {
47
50
  }
48
51
  catch (err) {
49
52
  dirs.push({ path: dir, removed: false });
50
- errors.push({ step: `dir:${dir}`, message: err instanceof Error ? err.message : String(err) });
53
+ errors.push({
54
+ step: `dir:${dir}`,
55
+ message: err instanceof Error ? err.message : String(err),
56
+ });
51
57
  }
52
58
  }
53
59
  return { ok: errors.length === 0, daemon, skills, dirs, hint: UNINSTALL_HINT, errors };