@getdial/cli 0.34.2 → 0.35.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/commands/onboard.js +11 -1
- package/dist/lib/dashboard.js +38 -0
- package/dist/lib/ops/account.js +3 -0
- package/dist/mcp/tools/onboard.js +13 -0
- package/package.json +1 -1
- package/skills.tar.gz +0 -0
package/dist/commands/onboard.js
CHANGED
|
@@ -3,6 +3,8 @@ import { isDialError } from "../lib/ops/errors.js";
|
|
|
3
3
|
import { readAuth, authFilePath } from "../lib/state.js";
|
|
4
4
|
import { installSkill, isSupportedAgent, SUPPORTED_AGENTS, } from "../lib/skill-install.js";
|
|
5
5
|
import { supervisorAvailability } from "../lib/supervisor/index.js";
|
|
6
|
+
import { baseUrl } from "../lib/api.js";
|
|
7
|
+
import { dashboardHint, dashboardUrl } from "../lib/dashboard.js";
|
|
6
8
|
function maskApiKey(key) {
|
|
7
9
|
return key.length >= 4 ? `sk_live_***${key.slice(-4)}` : "sk_live_***";
|
|
8
10
|
}
|
|
@@ -60,8 +62,10 @@ export async function runOnboard(opts) {
|
|
|
60
62
|
apiKeyMasked: maskApiKey(auth.apiKey),
|
|
61
63
|
apiKeyPath: authFilePath(),
|
|
62
64
|
accountId: auth.accountId,
|
|
65
|
+
email: auth.email || null,
|
|
63
66
|
phoneNumber: auth.phoneNumber ?? null,
|
|
64
67
|
phoneNumberId: auth.phoneNumberId ?? null,
|
|
68
|
+
dashboardUrl: dashboardUrl(baseUrl()),
|
|
65
69
|
listen: {
|
|
66
70
|
installed: false,
|
|
67
71
|
autoInstalled: false,
|
|
@@ -87,6 +91,7 @@ export async function runOnboard(opts) {
|
|
|
87
91
|
else if (r.unchanged)
|
|
88
92
|
console.log(` skill (${r.agent}): already up to date → ${r.path}`);
|
|
89
93
|
}
|
|
94
|
+
console.log(dashboardHint(dashboardUrl(baseUrl()), auth.email || null));
|
|
90
95
|
}
|
|
91
96
|
return 0;
|
|
92
97
|
}
|
|
@@ -123,7 +128,7 @@ export async function runOnboard(opts) {
|
|
|
123
128
|
console.error(`onboard failed: ${e.message}`);
|
|
124
129
|
return 2;
|
|
125
130
|
}
|
|
126
|
-
const { apiKey, accountId, phoneNumber, phoneNumberId, apiKeyPath, skills, supervisor } = result;
|
|
131
|
+
const { apiKey, accountId, email, phoneNumber, phoneNumberId, apiKeyPath, skills, supervisor } = result;
|
|
127
132
|
const masked = maskApiKey(apiKey);
|
|
128
133
|
if (opts.json) {
|
|
129
134
|
console.log(JSON.stringify({
|
|
@@ -132,8 +137,10 @@ export async function runOnboard(opts) {
|
|
|
132
137
|
apiKeyMasked: masked,
|
|
133
138
|
apiKeyPath,
|
|
134
139
|
accountId,
|
|
140
|
+
email,
|
|
135
141
|
phoneNumber,
|
|
136
142
|
phoneNumberId,
|
|
143
|
+
dashboardUrl: result.dashboardUrl,
|
|
137
144
|
listen: {
|
|
138
145
|
installed: false,
|
|
139
146
|
autoInstalled: false,
|
|
@@ -177,6 +184,9 @@ export async function runOnboard(opts) {
|
|
|
177
184
|
console.log(` skill (${r.agent}): already up to date → ${r.path}`);
|
|
178
185
|
}
|
|
179
186
|
}
|
|
187
|
+
// Part of the summary, deliberately above the finalization block so that
|
|
188
|
+
// block stays the last thing an agent reads.
|
|
189
|
+
console.log(dashboardHint(result.dashboardUrl, email));
|
|
180
190
|
console.log(``);
|
|
181
191
|
if (!supervisor.available) {
|
|
182
192
|
console.log(`listen service: not available on this machine (${supervisor.reason}).`);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Where a user manages the account in a browser, derived from whichever API base
|
|
2
|
+
// the CLI is pointed at — so a dev pointing DIAL_API_URL at localhost gets the
|
|
3
|
+
// local dashboard, not production's.
|
|
4
|
+
//
|
|
5
|
+
// Deliberately import-free: api.ts installs a global undici dispatcher at import
|
|
6
|
+
// time, and this is pure string work that shouldn't drag that into its own test.
|
|
7
|
+
// Callers pass `baseUrl()` in.
|
|
8
|
+
/**
|
|
9
|
+
* The dashboard URL for an API base. The web app lives on the same host as the API
|
|
10
|
+
* minus its `api.` label (`api.getdial.ai` → `getdial.ai`); a base without that
|
|
11
|
+
* label — staging, or a localhost dev server serving both — is used as-is.
|
|
12
|
+
*/
|
|
13
|
+
export function dashboardUrl(apiBase) {
|
|
14
|
+
const url = new URL(apiBase);
|
|
15
|
+
// Strip only a leading `api.` LABEL. A substring check would turn a host like
|
|
16
|
+
// `apiary.example.com` into `ary.example.com`.
|
|
17
|
+
if (url.hostname.startsWith("api."))
|
|
18
|
+
url.hostname = url.hostname.slice("api.".length);
|
|
19
|
+
// `pathname` is "/" for a bare origin and keeps a trailing slash when one was
|
|
20
|
+
// given, so join on a trimmed copy rather than concatenating blindly.
|
|
21
|
+
url.pathname = `${url.pathname.replace(/\/+$/, "")}/dashboard`;
|
|
22
|
+
return url.toString();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The closing line of `dial onboard`: where to manage the account, and which
|
|
26
|
+
* address signs in there.
|
|
27
|
+
*
|
|
28
|
+
* The address matters more than it looks. Sign-in is an emailed code, and when an
|
|
29
|
+
* agent onboarded on the user's behalf the user usually doesn't know which address
|
|
30
|
+
* it used — that's the single biggest reason they never reach the dashboard. Omitted
|
|
31
|
+
* when the CLI genuinely doesn't know it (an explicit `--verification-id` with no
|
|
32
|
+
* pending signup), since offering to sign in as nobody is worse than saying nothing.
|
|
33
|
+
*/
|
|
34
|
+
export function dashboardHint(url, email) {
|
|
35
|
+
return email
|
|
36
|
+
? `manage your account: ${url} (sign in with ${email} — it emails you a code)`
|
|
37
|
+
: `manage your account: ${url} (sign in with the email this account was created under)`;
|
|
38
|
+
}
|
package/dist/lib/ops/account.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readAuth, readPendingSignup, writePendingSignup, clearPendingSignup, writeAuth, authFilePath, } from "../state.js";
|
|
2
2
|
import { apiGet, apiPost, baseUrl, pingBackend } from "../api.js";
|
|
3
|
+
import { dashboardUrl } from "../dashboard.js";
|
|
3
4
|
import { supervisorStatus, lastEventAtFromLog, supervisorAvailability, } from "../supervisor/index.js";
|
|
4
5
|
import { paths } from "../paths.js";
|
|
5
6
|
import { VERSION } from "../version.js";
|
|
@@ -167,8 +168,10 @@ export async function onboard(opts) {
|
|
|
167
168
|
apiKeyFingerprint: apiKey.slice(-4),
|
|
168
169
|
apiKeyPath: authFilePath(),
|
|
169
170
|
accountId: res.data.accountId,
|
|
171
|
+
email,
|
|
170
172
|
phoneNumber: res.data.phoneNumber ?? null,
|
|
171
173
|
phoneNumberId: res.data.phoneNumberId ?? null,
|
|
174
|
+
dashboardUrl: dashboardUrl(baseUrl()),
|
|
172
175
|
skills,
|
|
173
176
|
supervisor: supervisorAvailability(),
|
|
174
177
|
};
|
|
@@ -4,6 +4,8 @@ import { onboard } from "../../lib/ops/account.js";
|
|
|
4
4
|
import { readAuth, authFilePath } from "../../lib/state.js";
|
|
5
5
|
import { installSkill, isSupportedAgent, SUPPORTED_AGENTS, } from "../../lib/skill-install.js";
|
|
6
6
|
import { supervisorAvailability } from "../../lib/supervisor/index.js";
|
|
7
|
+
import { baseUrl } from "../../lib/api.js";
|
|
8
|
+
import { dashboardUrl } from "../../lib/dashboard.js";
|
|
7
9
|
const inputSchema = {
|
|
8
10
|
code: z
|
|
9
11
|
.string()
|
|
@@ -34,8 +36,15 @@ export const onboardTool = {
|
|
|
34
36
|
apiKeyFingerprint: z.string().describe("Last 4 chars of the saved API key"),
|
|
35
37
|
apiKeyPath: z.string().describe("Where the key was saved"),
|
|
36
38
|
accountId: z.string(),
|
|
39
|
+
email: z
|
|
40
|
+
.string()
|
|
41
|
+
.nullable()
|
|
42
|
+
.describe("Address that signs in to the dashboard (a code is emailed to it). Null when the CLI never saw the signup — an explicit verificationId. Pass it on to the user: after an agent onboards for them, they usually don't know which address was used."),
|
|
37
43
|
phoneNumber: z.string().nullable(),
|
|
38
44
|
phoneNumberId: z.string().nullable(),
|
|
45
|
+
dashboardUrl: z
|
|
46
|
+
.string()
|
|
47
|
+
.describe("Where the user manages the account in a browser. Tell them about it once onboarding succeeds, then keep working from the CLI — it's only needed for paying, team sharing, and carrier (10DLC) registration."),
|
|
39
48
|
skills: z.array(z.object({}).passthrough()).describe("Per-agent skill install results"),
|
|
40
49
|
supervisor: z.object({}).passthrough().describe("Listen daemon availability on this machine"),
|
|
41
50
|
listenAvailable: z.boolean(),
|
|
@@ -75,8 +84,12 @@ export const onboardTool = {
|
|
|
75
84
|
apiKeyFingerprint: auth.apiKey.slice(-4),
|
|
76
85
|
apiKeyPath: authFilePath(),
|
|
77
86
|
accountId: auth.accountId,
|
|
87
|
+
// Built by hand rather than spread, so both fields have to be added here
|
|
88
|
+
// explicitly to match the full-onboard path below.
|
|
89
|
+
email: auth.email || null,
|
|
78
90
|
phoneNumber: auth.phoneNumber ?? null,
|
|
79
91
|
phoneNumberId: auth.phoneNumberId ?? null,
|
|
92
|
+
dashboardUrl: dashboardUrl(baseUrl()),
|
|
80
93
|
skills,
|
|
81
94
|
supervisor,
|
|
82
95
|
listenAvailable: supervisor.available,
|
package/package.json
CHANGED
package/skills.tar.gz
CHANGED
|
Binary file
|