@getdial/cli 0.31.0 → 0.32.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.
- package/dist/cli.js +1 -1
- package/dist/commands/onboard.js +68 -0
- package/dist/mcp/tools/onboard.js +37 -1
- package/package.json +1 -1
- package/skills.tar.gz +0 -0
package/dist/cli.js
CHANGED
|
@@ -60,7 +60,7 @@ program
|
|
|
60
60
|
.command("onboard")
|
|
61
61
|
.description("Verify the OTP and finish onboarding.")
|
|
62
62
|
.option("--verification-id <id>", "explicit verification id (falls back to local pending signup)")
|
|
63
|
-
.
|
|
63
|
+
.option("--code <code>", "6-digit OTP from your email (omit if already signed in — the command just installs the --agent skill and skips verification)")
|
|
64
64
|
.option("--inbound-instruction <text>", "system prompt for inbound calls to your auto-provisioned number (required for a new account; ignored when signing in)")
|
|
65
65
|
.option("--agent <name>", "install the Dial skill into the named agent's config dir. One of: claude-code, cursor, codex, opencode, pi, openclaw, nanoclaw, hermes. Repeatable.", (v, prev = []) => [...prev, v], [])
|
|
66
66
|
.option("--json", "machine-readable output")
|
package/dist/commands/onboard.js
CHANGED
|
@@ -1,8 +1,30 @@
|
|
|
1
1
|
import { onboard } from "../lib/ops/account.js";
|
|
2
2
|
import { isDialError } from "../lib/ops/errors.js";
|
|
3
|
+
import { readAuth, authFilePath } from "../lib/state.js";
|
|
4
|
+
import { installSkill, isSupportedAgent, SUPPORTED_AGENTS } from "../lib/skill-install.js";
|
|
5
|
+
import { supervisorAvailability } from "../lib/supervisor/index.js";
|
|
3
6
|
function maskApiKey(key) {
|
|
4
7
|
return key.length >= 4 ? `sk_live_***${key.slice(-4)}` : "sk_live_***";
|
|
5
8
|
}
|
|
9
|
+
// Install skills for each requested agent — mirrors the loop inside
|
|
10
|
+
// `onboard()` in ops/account.ts. Used by the signed-in-only branch below,
|
|
11
|
+
// which skips OTP verification entirely.
|
|
12
|
+
function installAgentSkills(agents) {
|
|
13
|
+
const skills = [];
|
|
14
|
+
for (const requested of agents) {
|
|
15
|
+
if (!isSupportedAgent(requested)) {
|
|
16
|
+
skills.push({ agent: requested, error: `unknown agent "${requested}". Supported: ${SUPPORTED_AGENTS.join(", ")}.` });
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
skills.push(installSkill(requested));
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
skills.push({ agent: requested, error: err instanceof Error ? err.message : String(err) });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return skills;
|
|
27
|
+
}
|
|
6
28
|
const LISTEN_QUESTION = "Install the background notification listening service?";
|
|
7
29
|
const LISTEN_RATIONALE = "The background notification listening service runs on this machine and listens for notifications from Dial — SMS arrivals (2FA codes, replies) and call-ended notifications — so the agent on this machine learns about them in real time. " +
|
|
8
30
|
"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. " +
|
|
@@ -10,6 +32,52 @@ const LISTEN_RATIONALE = "The background notification listening service runs on
|
|
|
10
32
|
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.";
|
|
11
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.";
|
|
12
34
|
export async function runOnboard(opts) {
|
|
35
|
+
// Skill-install-only branch: when --code isn't supplied, we can't (and shouldn't)
|
|
36
|
+
// re-verify — but if the machine is already signed in, the useful thing to do
|
|
37
|
+
// is just install any --agent skills the caller asked for. This is what agents
|
|
38
|
+
// following the docs on an already-onboarded account hit when they read the
|
|
39
|
+
// integration page: signup is a no-op, all that's left is the skill drop-in.
|
|
40
|
+
if (!opts.code) {
|
|
41
|
+
const auth = readAuth();
|
|
42
|
+
if (!auth) {
|
|
43
|
+
const message = "Not signed in. Run `dial signup <email>` first, then re-run with --code from your inbox.";
|
|
44
|
+
if (opts.json)
|
|
45
|
+
console.log(JSON.stringify({ ok: false, code: "not_signed_in", error: message }));
|
|
46
|
+
else
|
|
47
|
+
console.error(message);
|
|
48
|
+
return 1;
|
|
49
|
+
}
|
|
50
|
+
const skills = installAgentSkills(opts.agents ?? []);
|
|
51
|
+
const supervisor = supervisorAvailability();
|
|
52
|
+
if (opts.json) {
|
|
53
|
+
console.log(JSON.stringify({
|
|
54
|
+
ok: true,
|
|
55
|
+
alreadySignedIn: true,
|
|
56
|
+
apiKeyFingerprint: auth.apiKey.slice(-4),
|
|
57
|
+
apiKeyMasked: maskApiKey(auth.apiKey),
|
|
58
|
+
apiKeyPath: authFilePath(),
|
|
59
|
+
accountId: auth.accountId,
|
|
60
|
+
phoneNumber: auth.phoneNumber ?? null,
|
|
61
|
+
phoneNumberId: auth.phoneNumberId ?? null,
|
|
62
|
+
listen: { installed: false, autoInstalled: false, canInstall: supervisor.available, unavailableReason: supervisor.available ? null : supervisor.reason },
|
|
63
|
+
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." },
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
console.log(`already signed in as ${auth.email || "(unknown email)"} — skipped verification.`);
|
|
69
|
+
console.log(` api key: ${maskApiKey(auth.apiKey)} (saved at ${authFilePath()})`);
|
|
70
|
+
for (const r of skills) {
|
|
71
|
+
if ("error" in r)
|
|
72
|
+
console.log(` skill (${r.agent}): failed — ${r.error}`);
|
|
73
|
+
else if (r.written)
|
|
74
|
+
console.log(` skill (${r.agent}): installed → ${r.path}`);
|
|
75
|
+
else if (r.unchanged)
|
|
76
|
+
console.log(` skill (${r.agent}): already up to date → ${r.path}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
13
81
|
let result;
|
|
14
82
|
try {
|
|
15
83
|
result = await onboard({
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { jsonResult } from "../result.js";
|
|
3
3
|
import { onboard } from "../../lib/ops/account.js";
|
|
4
|
+
import { readAuth, authFilePath } from "../../lib/state.js";
|
|
5
|
+
import { installSkill, isSupportedAgent, SUPPORTED_AGENTS } from "../../lib/skill-install.js";
|
|
6
|
+
import { supervisorAvailability } from "../../lib/supervisor/index.js";
|
|
4
7
|
const inputSchema = {
|
|
5
|
-
code: z.string().min(1).describe("6-digit OTP from the sign-up email"),
|
|
8
|
+
code: z.string().min(1).optional().describe("6-digit OTP from the sign-up email. Omit if the account is already signed in — the tool will just install the requested --agent skills and skip verification."),
|
|
6
9
|
verificationId: z.string().optional().describe("Explicit verification id (defaults to the local pending signup)"),
|
|
7
10
|
inboundInstruction: z.string().optional().describe("System prompt for inbound calls to a newly provisioned number (new accounts)"),
|
|
8
11
|
agents: z.array(z.string()).optional().describe("Agent names to install the Dial skill into (e.g. claude-code, cursor)"),
|
|
@@ -27,6 +30,39 @@ export const onboardTool = {
|
|
|
27
30
|
annotations: { openWorldHint: true },
|
|
28
31
|
},
|
|
29
32
|
run: async (args) => {
|
|
33
|
+
// Skill-install-only branch — mirror runOnboard(): if no --code and we're
|
|
34
|
+
// already signed in, skip verification and just install the requested skills.
|
|
35
|
+
if (!args.code) {
|
|
36
|
+
const auth = readAuth();
|
|
37
|
+
if (!auth) {
|
|
38
|
+
throw new Error("Not signed in. Run `dial signup <email>` first, then invoke this tool with the OTP as `code`.");
|
|
39
|
+
}
|
|
40
|
+
const skills = [];
|
|
41
|
+
for (const requested of args.agents ?? []) {
|
|
42
|
+
if (!isSupportedAgent(requested)) {
|
|
43
|
+
skills.push({ agent: requested, error: `unknown agent "${requested}". Supported: ${SUPPORTED_AGENTS.join(", ")}.` });
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
skills.push(installSkill(requested));
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
skills.push({ agent: requested, error: err instanceof Error ? err.message : String(err) });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const supervisor = supervisorAvailability();
|
|
54
|
+
return jsonResult({
|
|
55
|
+
alreadySignedIn: true,
|
|
56
|
+
apiKeyFingerprint: auth.apiKey.slice(-4),
|
|
57
|
+
apiKeyPath: authFilePath(),
|
|
58
|
+
accountId: auth.accountId,
|
|
59
|
+
phoneNumber: auth.phoneNumber ?? null,
|
|
60
|
+
phoneNumberId: auth.phoneNumberId ?? null,
|
|
61
|
+
skills,
|
|
62
|
+
supervisor,
|
|
63
|
+
listenAvailable: supervisor.available,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
30
66
|
const r = await onboard({
|
|
31
67
|
code: args.code,
|
|
32
68
|
verificationId: args.verificationId,
|
package/package.json
CHANGED
package/skills.tar.gz
CHANGED
|
Binary file
|