@getdial/cli 0.23.0 → 0.24.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 +9 -5
- package/dist/commands/billing.js +56 -0
- package/dist/commands/number/purchase.js +0 -1
- package/dist/lib/ops/billing.js +10 -0
- package/dist/lib/ops/numbers.js +0 -2
- package/dist/mcp/tools/purchase-number.js +1 -3
- package/dist/mcp/tools/set-number-properties.js +1 -1
- package/package.json +1 -1
- package/skills.tar.gz +0 -0
package/dist/cli.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import { VERSION } from "./lib/version.js";
|
|
4
4
|
import { runDoctor } from "./commands/doctor.js";
|
|
5
|
+
import { runBilling } from "./commands/billing.js";
|
|
5
6
|
import { runSignup } from "./commands/signup.js";
|
|
6
7
|
import { runOnboard } from "./commands/onboard.js";
|
|
7
8
|
import { runListen } from "./commands/listen/index.js";
|
|
@@ -41,6 +42,11 @@ program
|
|
|
41
42
|
.description("Report state and what to do next.")
|
|
42
43
|
.option("--json", "machine-readable output")
|
|
43
44
|
.action(async (opts) => process.exit(await runDoctor({ json: !!opts.json })));
|
|
45
|
+
program
|
|
46
|
+
.command("billing")
|
|
47
|
+
.description("Show account billing: balance, plan, per-number mode, recent activity. GET /api/v1/billing.")
|
|
48
|
+
.option("--json", "machine-readable output")
|
|
49
|
+
.action(async (opts) => process.exit(await runBilling({ json: !!opts.json })));
|
|
44
50
|
program
|
|
45
51
|
.command("signup <email>")
|
|
46
52
|
.description("Request an email OTP for the given address.")
|
|
@@ -94,13 +100,11 @@ number
|
|
|
94
100
|
.description("Purchase an additional phone number. POST /api/v1/numbers.")
|
|
95
101
|
.requiredOption("--inbound-instruction <text>", "system prompt for inbound calls to this number")
|
|
96
102
|
.option("--inbound-voice-gender <male|female>", "voice gender for inbound calls (default: female; pass male to override)")
|
|
97
|
-
.option("--
|
|
98
|
-
.option("--area-code <code>", "preferred area code (US/CA)")
|
|
103
|
+
.option("--area-code <code>", "preferred US area code (only US numbers can be provisioned)")
|
|
99
104
|
.option("--json", "machine-readable output")
|
|
100
105
|
.action(async (opts) => process.exit(await runNumberPurchase({
|
|
101
106
|
inboundInstruction: opts.inboundInstruction,
|
|
102
107
|
inboundVoiceGender: opts.inboundVoiceGender,
|
|
103
|
-
country: opts.country,
|
|
104
108
|
areaCode: opts.areaCode,
|
|
105
109
|
json: !!opts.json,
|
|
106
110
|
})));
|
|
@@ -110,7 +114,7 @@ number
|
|
|
110
114
|
.option("--inbound-instruction <text>", "new system prompt for inbound calls to this number")
|
|
111
115
|
.option("--inbound-voice-gender <male|female>", 'voice gender for inbound calls; pass "" to clear (reverts to the default, female)')
|
|
112
116
|
.option("--nickname <text>", 'human-readable label for the number, e.g. "Support line"; pass "" to clear')
|
|
113
|
-
.option("--max-call-duration <seconds>", "
|
|
117
|
+
.option("--max-call-duration <seconds>", "call duration cap for this number, in seconds, applied as a hard ceiling to both inbound and outbound calls (the smallest of the per-number, account, and per-call caps wins)", (v) => {
|
|
114
118
|
const n = parseInt(v, 10);
|
|
115
119
|
if (!Number.isInteger(n) || n <= 0 || String(n) !== v.trim()) {
|
|
116
120
|
console.error(`error: --max-call-duration must be a positive integer (seconds), got: ${v}`);
|
|
@@ -118,7 +122,7 @@ number
|
|
|
118
122
|
}
|
|
119
123
|
return n;
|
|
120
124
|
})
|
|
121
|
-
.option("--clear-max-call-duration", "remove the per-number
|
|
125
|
+
.option("--clear-max-call-duration", "remove the per-number call duration cap")
|
|
122
126
|
.option("--json", "machine-readable output")
|
|
123
127
|
.action(async (numberArg, opts) => {
|
|
124
128
|
let maxCallDurationSeconds;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { getBilling } from "../lib/ops/billing.js";
|
|
2
|
+
import { isDialError } from "../lib/ops/errors.js";
|
|
3
|
+
import { printDialError } from "../lib/cli-error.js";
|
|
4
|
+
const usd = (cents) => `$${(cents / 100).toFixed(2)}`;
|
|
5
|
+
export async function runBilling(opts) {
|
|
6
|
+
try {
|
|
7
|
+
const billing = await getBilling();
|
|
8
|
+
if (opts.json) {
|
|
9
|
+
console.log(JSON.stringify({ ok: true, ...billing }));
|
|
10
|
+
return 0;
|
|
11
|
+
}
|
|
12
|
+
console.log(`balance: ${usd(billing.balanceCents)}`);
|
|
13
|
+
if (billing.subscription) {
|
|
14
|
+
const s = billing.subscription;
|
|
15
|
+
const numbers = `${s.quantity} number${s.quantity === 1 ? "" : "s"}`;
|
|
16
|
+
const renewal = s.cancelAtPeriodEnd ? `cancels ${s.periodEnd}` : `renews ${s.periodEnd}`;
|
|
17
|
+
console.log(`plan: subscribed (${s.interval}, ${numbers}) — ${renewal}`);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
console.log(`plan: pay-as-you-go`);
|
|
21
|
+
}
|
|
22
|
+
if (billing.numbers.length > 0) {
|
|
23
|
+
console.log(`numbers:`);
|
|
24
|
+
for (const n of billing.numbers) {
|
|
25
|
+
const mode = n.mode === "FIXED" ? "subscription" : "pay-as-you-go";
|
|
26
|
+
const nick = n.nickname ? ` "${n.nickname}"` : "";
|
|
27
|
+
console.log(` ${n.number}${nick} ${mode} id=${n.id}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (billing.deposits.length > 0) {
|
|
31
|
+
console.log(`recent credits:`);
|
|
32
|
+
for (const d of billing.deposits) {
|
|
33
|
+
console.log(` ${d.createdAt} +${usd(d.amountCents)} (${d.kind})`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (billing.paymentMethods.length > 0) {
|
|
37
|
+
console.log(`payment methods:`);
|
|
38
|
+
for (const p of billing.paymentMethods) {
|
|
39
|
+
const tag = p.isDefault ? " (default)" : "";
|
|
40
|
+
if (p.type === "card") {
|
|
41
|
+
const exp = `${String(p.expMonth).padStart(2, "0")}/${String(p.expYear).slice(-2)}`;
|
|
42
|
+
console.log(` ${p.brand} •••• ${p.last4} exp ${exp}${tag}`);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.log(` ${p.type}${p.email ? ` ${p.email}` : ""}${tag}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
if (isDialError(e))
|
|
53
|
+
return printDialError(opts.json, e);
|
|
54
|
+
throw e;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { apiGet } from "../api.js";
|
|
2
|
+
import { requireAuth } from "./auth.js";
|
|
3
|
+
import { DialError } from "./errors.js";
|
|
4
|
+
export async function getBilling() {
|
|
5
|
+
const auth = requireAuth();
|
|
6
|
+
const res = await apiGet("/api/v1/billing", auth.apiKey);
|
|
7
|
+
if (!res.ok)
|
|
8
|
+
throw new DialError("billing_failed", res.error, res.status);
|
|
9
|
+
return res.data;
|
|
10
|
+
}
|
package/dist/lib/ops/numbers.js
CHANGED
|
@@ -13,8 +13,6 @@ export async function purchaseNumber(opts) {
|
|
|
13
13
|
const body = { inboundInstruction: opts.inboundInstruction };
|
|
14
14
|
if (opts.inboundVoiceGender)
|
|
15
15
|
body.inboundVoiceGender = opts.inboundVoiceGender;
|
|
16
|
-
if (opts.country)
|
|
17
|
-
body.country = opts.country;
|
|
18
16
|
if (opts.areaCode)
|
|
19
17
|
body.areaCode = opts.areaCode;
|
|
20
18
|
const res = await apiPost("/api/v1/numbers", body, auth.apiKey);
|
|
@@ -5,8 +5,7 @@ import { phoneNumberSchema } from "../schemas.js";
|
|
|
5
5
|
const inputSchema = {
|
|
6
6
|
inboundInstruction: z.string().min(1).describe("System prompt for inbound calls to this number"),
|
|
7
7
|
inboundVoiceGender: z.enum(["male", "female"]).optional().describe("Voice gender for inbound calls to this number; the default is female"),
|
|
8
|
-
|
|
9
|
-
areaCode: z.string().optional().describe("Preferred area code (US/CA)"),
|
|
8
|
+
areaCode: z.string().optional().describe("Preferred US area code; omitted → any available US number. Only US numbers can be provisioned at this time"),
|
|
10
9
|
};
|
|
11
10
|
export const purchaseNumberTool = {
|
|
12
11
|
name: "purchase_number",
|
|
@@ -21,7 +20,6 @@ export const purchaseNumberTool = {
|
|
|
21
20
|
number: await purchaseNumber({
|
|
22
21
|
inboundInstruction: args.inboundInstruction,
|
|
23
22
|
inboundVoiceGender: args.inboundVoiceGender,
|
|
24
|
-
country: args.country,
|
|
25
23
|
areaCode: args.areaCode,
|
|
26
24
|
}),
|
|
27
25
|
}),
|
|
@@ -7,7 +7,7 @@ const inputSchema = {
|
|
|
7
7
|
inboundInstruction: z.string().min(1).optional().describe("New system prompt for inbound calls to this number"),
|
|
8
8
|
inboundVoiceGender: z.enum(["male", "female"]).optional().describe("Voice gender for inbound calls to this number; the default is female"),
|
|
9
9
|
nickname: z.string().max(100).optional().describe('Human-readable label for the number, e.g. "Support line". Pass an empty string to clear it.'),
|
|
10
|
-
maxCallDurationSeconds: z.number().int().positive().nullable().optional().describe("
|
|
10
|
+
maxCallDurationSeconds: z.number().int().positive().nullable().optional().describe("Call duration cap for this number, in seconds, applied as a hard ceiling to both inbound and outbound calls (the smallest of the per-number, account, and per-call caps wins). Pass null to clear the cap; omit to leave it unchanged."),
|
|
11
11
|
};
|
|
12
12
|
export const setNumberPropertiesTool = {
|
|
13
13
|
name: "set_number_properties",
|
package/package.json
CHANGED
package/skills.tar.gz
CHANGED
|
Binary file
|