convoai 1.6.2 → 1.8.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.
Files changed (72) hide show
  1. package/README.md +38 -2
  2. package/dist/src/api/calls.d.ts +33 -36
  3. package/dist/src/api/calls.js +12 -7
  4. package/dist/src/api/calls.js.map +1 -1
  5. package/dist/src/api/numbers.d.ts +63 -0
  6. package/dist/src/api/numbers.js +27 -0
  7. package/dist/src/api/numbers.js.map +1 -0
  8. package/dist/src/api/types.d.ts +6 -0
  9. package/dist/src/commands/call/hangup.js +9 -16
  10. package/dist/src/commands/call/hangup.js.map +1 -1
  11. package/dist/src/commands/call/initiate.js +69 -112
  12. package/dist/src/commands/call/initiate.js.map +1 -1
  13. package/dist/src/commands/call/status.js +14 -32
  14. package/dist/src/commands/call/status.js.map +1 -1
  15. package/dist/src/commands/completion.js +2 -1
  16. package/dist/src/commands/completion.js.map +1 -1
  17. package/dist/src/commands/go.js +64 -0
  18. package/dist/src/commands/go.js.map +1 -1
  19. package/dist/src/commands/phone/_dashboard.d.ts +31 -0
  20. package/dist/src/commands/phone/_dashboard.js +127 -0
  21. package/dist/src/commands/phone/_dashboard.js.map +1 -0
  22. package/dist/src/commands/phone/_helpers.d.ts +30 -0
  23. package/dist/src/commands/phone/_helpers.js +133 -0
  24. package/dist/src/commands/phone/_helpers.js.map +1 -0
  25. package/dist/src/commands/phone/_modes/agent.d.ts +22 -0
  26. package/dist/src/commands/phone/_modes/agent.js +59 -0
  27. package/dist/src/commands/phone/_modes/agent.js.map +1 -0
  28. package/dist/src/commands/phone/_modes/free.d.ts +29 -0
  29. package/dist/src/commands/phone/_modes/free.js +44 -0
  30. package/dist/src/commands/phone/_modes/free.js.map +1 -0
  31. package/dist/src/commands/phone/_modes/translate.d.ts +30 -0
  32. package/dist/src/commands/phone/_modes/translate.js +89 -0
  33. package/dist/src/commands/phone/_modes/translate.js.map +1 -0
  34. package/dist/src/commands/phone/get.d.ts +2 -0
  35. package/dist/src/commands/phone/get.js +34 -0
  36. package/dist/src/commands/phone/get.js.map +1 -0
  37. package/dist/src/commands/phone/go.d.ts +2 -0
  38. package/dist/src/commands/phone/go.js +235 -0
  39. package/dist/src/commands/phone/go.js.map +1 -0
  40. package/dist/src/commands/phone/hangup.d.ts +2 -0
  41. package/dist/src/commands/phone/hangup.js +20 -0
  42. package/dist/src/commands/phone/hangup.js.map +1 -0
  43. package/dist/src/commands/phone/history.d.ts +2 -0
  44. package/dist/src/commands/phone/history.js +56 -0
  45. package/dist/src/commands/phone/history.js.map +1 -0
  46. package/dist/src/commands/phone/import.d.ts +2 -0
  47. package/dist/src/commands/phone/import.js +88 -0
  48. package/dist/src/commands/phone/import.js.map +1 -0
  49. package/dist/src/commands/phone/numbers.d.ts +2 -0
  50. package/dist/src/commands/phone/numbers.js +34 -0
  51. package/dist/src/commands/phone/numbers.js.map +1 -0
  52. package/dist/src/commands/phone/remove.d.ts +2 -0
  53. package/dist/src/commands/phone/remove.js +31 -0
  54. package/dist/src/commands/phone/remove.js.map +1 -0
  55. package/dist/src/commands/phone/send.d.ts +2 -0
  56. package/dist/src/commands/phone/send.js +228 -0
  57. package/dist/src/commands/phone/send.js.map +1 -0
  58. package/dist/src/commands/phone/status.d.ts +2 -0
  59. package/dist/src/commands/phone/status.js +34 -0
  60. package/dist/src/commands/phone/status.js.map +1 -0
  61. package/dist/src/commands/phone/update.d.ts +2 -0
  62. package/dist/src/commands/phone/update.js +41 -0
  63. package/dist/src/commands/phone/update.js.map +1 -0
  64. package/dist/src/commands/quickstart.js +85 -19
  65. package/dist/src/commands/quickstart.js.map +1 -1
  66. package/dist/src/config/schema.d.ts +23 -0
  67. package/dist/src/config/schema.js +6 -0
  68. package/dist/src/config/schema.js.map +1 -1
  69. package/dist/src/index.js +42 -3
  70. package/dist/src/index.js.map +1 -1
  71. package/package.json +1 -1
  72. package/src/web/phone-dashboard.html +180 -0
@@ -0,0 +1,133 @@
1
+ // src/commands/phone/_helpers.ts
2
+ import axios from 'axios';
3
+ import { resolveConfig } from '../../config/manager.js';
4
+ import { createClient } from '../../api/client.js';
5
+ import { CallAPI } from '../../api/calls.js';
6
+ import { NumberAPI } from '../../api/numbers.js';
7
+ // ─── E.164 Validation ──────────────────────────────────────────────────────
8
+ const E164_REGEX = /^\+[1-9]\d{1,14}$/;
9
+ export function isE164(phone) {
10
+ return E164_REGEX.test(phone);
11
+ }
12
+ export function validateE164(phone) {
13
+ const trimmed = phone.trim();
14
+ if (!isE164(trimmed)) {
15
+ throw new Error(`Invalid phone number "${trimmed}". Use E.164 format: +15551234567`);
16
+ }
17
+ return trimmed;
18
+ }
19
+ // ─── Credential Check ──────────────────────────────────────────────────────
20
+ function requireCredentials(config) {
21
+ const missing = [];
22
+ if (!config.app_id)
23
+ missing.push('app_id');
24
+ if (!config.customer_id)
25
+ missing.push('customer_id');
26
+ if (!config.customer_secret)
27
+ missing.push('customer_secret');
28
+ if (missing.length > 0) {
29
+ throw new Error(`Missing credentials: ${missing.join(', ')}. Run "convoai quickstart" to configure.`);
30
+ }
31
+ }
32
+ // ─── API Factories ─────────────────────────────────────────────────────────
33
+ /** Create a project-scoped CallAPI (baseURL includes /projects/{appId}). */
34
+ export function getCallAPI(profileName) {
35
+ const config = resolveConfig(profileName);
36
+ requireCredentials(config);
37
+ const client = createClient({
38
+ appId: config.app_id,
39
+ customerId: config.customer_id,
40
+ customerSecret: config.customer_secret,
41
+ baseUrl: config.base_url,
42
+ region: config.region,
43
+ });
44
+ return new CallAPI(client);
45
+ }
46
+ /** Create an account-scoped NumberAPI (baseURL does NOT include /projects/{appId}). */
47
+ export function getNumberAPI(profileName) {
48
+ const config = resolveConfig(profileName);
49
+ requireCredentials(config);
50
+ const region = config.region ?? 'global';
51
+ let baseURL;
52
+ if (config.base_url) {
53
+ // Custom base URL: strip /projects/{appId} suffix if present, keep the base
54
+ baseURL = config.base_url.replace(/\/projects\/[^/]+\/?$/, '');
55
+ }
56
+ else {
57
+ const baseURLs = {
58
+ global: 'https://api.agora.io/api/conversational-ai-agent/v2',
59
+ cn: 'https://api.agora.io/cn/api/conversational-ai-agent/v2',
60
+ };
61
+ baseURL = baseURLs[region] ?? baseURLs.global;
62
+ }
63
+ const credentials = Buffer.from(`${config.customer_id}:${config.customer_secret}`).toString('base64');
64
+ const client = axios.create({
65
+ baseURL,
66
+ headers: {
67
+ 'Content-Type': 'application/json',
68
+ Authorization: `Basic ${credentials}`,
69
+ },
70
+ timeout: 30_000,
71
+ });
72
+ return new NumberAPI(client);
73
+ }
74
+ /** Get resolved config. */
75
+ export function getConfig(profileName) {
76
+ return resolveConfig(profileName);
77
+ }
78
+ // ─── Interactive Number Picker ─────────────────────────────────────────────
79
+ export async function pickOutboundNumber(numbers) {
80
+ const outbound = numbers.filter(n => n.outbound);
81
+ if (outbound.length === 0) {
82
+ throw new Error('No outbound-capable numbers found. Import one with: convoai phone import');
83
+ }
84
+ if (outbound.length === 1)
85
+ return outbound[0];
86
+ const { default: inquirer } = await import('inquirer');
87
+ const { selected } = await inquirer.prompt([{
88
+ type: 'list',
89
+ name: 'selected',
90
+ message: 'From number:',
91
+ choices: outbound.map(n => ({
92
+ name: `${n.phone_number} (${n.label})`,
93
+ value: n.phone_number,
94
+ })),
95
+ }]);
96
+ return outbound.find(n => n.phone_number === selected);
97
+ }
98
+ // ─── Shared Call-Building Helpers ───────────────────────────────────────────
99
+ /** Generate a unique channel name for phone calls. */
100
+ export function buildChannelName() {
101
+ return `call-${Date.now().toString(36)}${Math.random().toString(36).slice(2, 6)}`;
102
+ }
103
+ /** Build a SendCallRequest from resolved parameters. */
104
+ export function buildCallRequest(params) {
105
+ return {
106
+ name: `call-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
107
+ sip: {
108
+ to_number: params.toNumber,
109
+ from_number: params.fromNumber,
110
+ rtc_uid: '1',
111
+ rtc_token: params.sipToken,
112
+ },
113
+ properties: {
114
+ channel: params.channelName,
115
+ token: params.agentToken,
116
+ agent_rtc_uid: '0',
117
+ remote_rtc_uids: ['1'],
118
+ idle_timeout: params.idleTimeout ?? 600,
119
+ llm: params.llm,
120
+ tts: params.tts,
121
+ asr: params.asr,
122
+ },
123
+ };
124
+ }
125
+ /** Build TTS config, optionally applying a voice profile override. */
126
+ export function buildTTSConfig(baseTTS, voiceProfile) {
127
+ const tts = { ...baseTTS, params: { ...baseTTS.params } };
128
+ if (voiceProfile?.voice_id) {
129
+ tts.params = { ...tts.params, voice: voiceProfile.voice_id };
130
+ }
131
+ return tts;
132
+ }
133
+ //# sourceMappingURL=_helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_helpers.js","sourceRoot":"","sources":["../../../../src/commands/phone/_helpers.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAKjD,8EAA8E;AAE9E,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAEvC,MAAM,UAAU,MAAM,CAAC,KAAa;IAClC,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,mCAAmC,CAAC,CAAC;IACvF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,8EAA8E;AAE9E,SAAS,kBAAkB,CAAC,MAA2E;IACrG,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,CAAC,WAAW;QAAE,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrD,IAAI,CAAC,MAAM,CAAC,eAAe;QAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC7D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IACxG,CAAC;AACH,CAAC;AAED,8EAA8E;AAE9E,4EAA4E;AAC5E,MAAM,UAAU,UAAU,CAAC,WAAoB;IAC7C,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC1C,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,YAAY,CAAC;QAC1B,KAAK,EAAE,MAAM,CAAC,MAAO;QACrB,UAAU,EAAE,MAAM,CAAC,WAAY;QAC/B,cAAc,EAAE,MAAM,CAAC,eAAgB;QACvC,OAAO,EAAE,MAAM,CAAC,QAAQ;QACxB,MAAM,EAAE,MAAM,CAAC,MAAqC;KACrD,CAAC,CAAC;IACH,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,YAAY,CAAC,WAAoB;IAC/C,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC1C,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAE3B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,QAAQ,CAAC;IACzC,IAAI,OAAe,CAAC;IACpB,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,4EAA4E;QAC5E,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;IACjE,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,GAA2B;YACvC,MAAM,EAAE,qDAAqD;YAC7D,EAAE,EAAE,wDAAwD;SAC7D,CAAC;QACF,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC;IAChD,CAAC;IACD,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEtG,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC1B,OAAO;QACP,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,SAAS,WAAW,EAAE;SACtC;QACD,OAAO,EAAE,MAAM;KAChB,CAAC,CAAC;IAEH,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,2BAA2B;AAC3B,MAAM,UAAU,SAAS,CAAC,WAAoB;IAC5C,OAAO,aAAa,CAAC,WAAW,CAAC,CAAC;AACpC,CAAC;AAED,8EAA8E;AAE9E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAsB;IAEtB,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,0EAA0E,CAAC,CAAC;IAC9F,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE9C,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IACvD,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC1C,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,cAAc;YACvB,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC1B,IAAI,EAAE,GAAG,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,KAAK,GAAG;gBACtC,KAAK,EAAE,CAAC,CAAC,YAAY;aACtB,CAAC,CAAC;SACJ,CAAC,CAAC,CAAC;IAEJ,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,QAAQ,CAAE,CAAC;AAC1D,CAAC;AAED,+EAA+E;AAE/E,sDAAsD;AACtD,MAAM,UAAU,gBAAgB;IAC9B,OAAO,QAAQ,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACpF,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,gBAAgB,CAAC,MAUhC;IACC,OAAO;QACL,IAAI,EAAE,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QACpE,GAAG,EAAE;YACH,SAAS,EAAE,MAAM,CAAC,QAAQ;YAC1B,WAAW,EAAE,MAAM,CAAC,UAAU;YAC9B,OAAO,EAAE,GAAG;YACZ,SAAS,EAAE,MAAM,CAAC,QAAQ;SAC3B;QACD,UAAU,EAAE;YACV,OAAO,EAAE,MAAM,CAAC,WAAW;YAC3B,KAAK,EAAE,MAAM,CAAC,UAAU;YACxB,aAAa,EAAE,GAAG;YAClB,eAAe,EAAE,CAAC,GAAG,CAAC;YACtB,YAAY,EAAE,MAAM,CAAC,WAAW,IAAI,GAAG;YACvC,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,GAAG,EAAE,MAAM,CAAC,GAAG;SAChB;KACF,CAAC;AACJ,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,cAAc,CAC5B,OAA2B,EAC3B,YAA2B;IAE3B,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAC1D,IAAI,YAAY,EAAE,QAAQ,EAAE,CAAC;QAC3B,GAAG,CAAC,MAAM,GAAG,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,QAAQ,EAAE,CAAC;IAC/D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { LLMConfig, TTSConfig, ASRConfig } from '../../../api/types.js';
2
+ import type { CallConfig } from './free.js';
3
+ export interface AgentCallParams {
4
+ toNumber: string;
5
+ fromNumber: string;
6
+ task: string;
7
+ taskLang: string;
8
+ llm: Partial<LLMConfig>;
9
+ tts: Partial<TTSConfig>;
10
+ asr: Partial<ASRConfig>;
11
+ }
12
+ export declare function buildAgentCallConfig(params: AgentCallParams): CallConfig;
13
+ /** Interactive parameter collection for agent mode. */
14
+ export declare function collectAgentParams(opts: {
15
+ to?: string;
16
+ task?: string;
17
+ taskLang?: string;
18
+ }): Promise<{
19
+ toNumber: string;
20
+ task: string;
21
+ taskLang: string;
22
+ }>;
@@ -0,0 +1,59 @@
1
+ import { SUPPORTED_LANGUAGES } from './translate.js';
2
+ export function buildAgentCallConfig(params) {
3
+ const agentPrompt = `You are an AI phone agent. Your task: ${params.task}\n\n` +
4
+ `Speak in ${params.taskLang}. Be polite and professional. ` +
5
+ `Introduce yourself, state your purpose clearly, and work toward completing the task. ` +
6
+ `If you successfully complete the task, confirm the details. ` +
7
+ `If the task cannot be completed, politely end the conversation.`;
8
+ return {
9
+ mode: 'agent',
10
+ toNumber: params.toNumber,
11
+ fromNumber: params.fromNumber,
12
+ llm: {
13
+ ...params.llm,
14
+ system_messages: [{ role: 'system', content: agentPrompt }],
15
+ },
16
+ tts: { ...params.tts },
17
+ asr: { ...params.asr, language: params.taskLang },
18
+ idleTimeout: 900,
19
+ label: `🤖 Agent → ${params.toNumber}`,
20
+ };
21
+ }
22
+ /** Interactive parameter collection for agent mode. */
23
+ export async function collectAgentParams(opts) {
24
+ const { default: inquirer } = await import('inquirer');
25
+ const { validateE164 } = await import('../_helpers.js');
26
+ let task = opts.task;
27
+ if (!task) {
28
+ const ans = await inquirer.prompt([{
29
+ type: 'input',
30
+ name: 'task',
31
+ message: 'Describe the task:',
32
+ validate: (v) => v.trim().length > 0 || 'Task description is required',
33
+ }]);
34
+ task = ans.task;
35
+ }
36
+ let toNumber = opts.to;
37
+ if (!toNumber) {
38
+ const ans = await inquirer.prompt([{
39
+ type: 'input',
40
+ name: 'to',
41
+ message: 'Phone number to call (E.164):',
42
+ validate: (v) => /^\+[1-9]\d{1,14}$/.test(v.trim()) || 'Invalid E.164 format',
43
+ }]);
44
+ toNumber = ans.to;
45
+ }
46
+ toNumber = validateE164(toNumber);
47
+ let taskLang = opts.taskLang;
48
+ if (!taskLang) {
49
+ const ans = await inquirer.prompt([{
50
+ type: 'list',
51
+ name: 'lang',
52
+ message: 'Language to speak:',
53
+ choices: SUPPORTED_LANGUAGES,
54
+ }]);
55
+ taskLang = ans.lang;
56
+ }
57
+ return { toNumber, task: task, taskLang: taskLang };
58
+ }
59
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../../../src/commands/phone/_modes/agent.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAYrD,MAAM,UAAU,oBAAoB,CAAC,MAAuB;IAC1D,MAAM,WAAW,GACf,yCAAyC,MAAM,CAAC,IAAI,MAAM;QAC1D,YAAY,MAAM,CAAC,QAAQ,gCAAgC;QAC3D,uFAAuF;QACvF,8DAA8D;QAC9D,iEAAiE,CAAC;IAEpE,OAAO;QACL,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,GAAG,EAAE;YACH,GAAG,MAAM,CAAC,GAAG;YACb,eAAe,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;SAC5D;QACD,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE;QACtB,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE;QACjD,WAAW,EAAE,GAAG;QAChB,KAAK,EAAE,cAAc,MAAM,CAAC,QAAQ,EAAE;KACvC,CAAC;AACJ,CAAC;AAED,uDAAuD;AACvD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAIxC;IACC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IACvD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAExD,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACrB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,oBAAoB;gBAC7B,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,8BAA8B;aAC/E,CAAC,CAAC,CAAC;QACJ,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,IAAI,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;IACvB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,+BAA+B;gBACxC,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,sBAAsB;aACtF,CAAC,CAAC,CAAC;QACJ,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC;IACpB,CAAC;IACD,QAAQ,GAAG,YAAY,CAAC,QAAS,CAAC,CAAC;IAEnC,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC7B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,oBAAoB;gBAC7B,OAAO,EAAE,mBAAmB;aAC7B,CAAC,CAAC,CAAC;QACJ,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC;IACtB,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAK,EAAE,QAAQ,EAAE,QAAS,EAAE,CAAC;AACxD,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { LLMConfig, TTSConfig, ASRConfig } from '../../../api/types.js';
2
+ export interface CallConfig {
3
+ mode: 'free' | 'translate' | 'agent';
4
+ toNumber: string;
5
+ fromNumber: string;
6
+ llm: Record<string, unknown>;
7
+ tts: Record<string, unknown>;
8
+ asr: Record<string, unknown>;
9
+ idleTimeout: number;
10
+ label: string;
11
+ }
12
+ export interface FreeCallParams {
13
+ toNumber: string;
14
+ fromNumber: string;
15
+ task?: string;
16
+ llm: Partial<LLMConfig>;
17
+ tts: Partial<TTSConfig>;
18
+ asr: Partial<ASRConfig>;
19
+ }
20
+ export declare function buildFreeCallConfig(params: FreeCallParams): CallConfig;
21
+ /** Interactive parameter collection for free call mode. */
22
+ export declare function collectFreeParams(opts: {
23
+ to?: string;
24
+ from?: string;
25
+ task?: string;
26
+ }): Promise<{
27
+ toNumber: string;
28
+ task?: string;
29
+ }>;
@@ -0,0 +1,44 @@
1
+ const DEFAULT_PROMPT = 'You are a helpful voice assistant. Keep responses concise and conversational.';
2
+ export function buildFreeCallConfig(params) {
3
+ const systemMessage = params.task || DEFAULT_PROMPT;
4
+ return {
5
+ mode: 'free',
6
+ toNumber: params.toNumber,
7
+ fromNumber: params.fromNumber,
8
+ llm: {
9
+ ...params.llm,
10
+ system_messages: [{ role: 'system', content: systemMessage }],
11
+ },
12
+ tts: { ...params.tts },
13
+ asr: { ...params.asr },
14
+ idleTimeout: 600,
15
+ label: `📱 Free Call → ${params.toNumber}`,
16
+ };
17
+ }
18
+ /** Interactive parameter collection for free call mode. */
19
+ export async function collectFreeParams(opts) {
20
+ const { default: inquirer } = await import('inquirer');
21
+ const { validateE164 } = await import('../_helpers.js');
22
+ let toNumber = opts.to;
23
+ if (!toNumber) {
24
+ const ans = await inquirer.prompt([{
25
+ type: 'input',
26
+ name: 'to',
27
+ message: 'Phone number to call (E.164):',
28
+ validate: (v) => /^\+[1-9]\d{1,14}$/.test(v.trim()) || 'Invalid E.164 format',
29
+ }]);
30
+ toNumber = ans.to;
31
+ }
32
+ toNumber = validateE164(toNumber);
33
+ let task = opts.task;
34
+ if (task === undefined) {
35
+ const ans = await inquirer.prompt([{
36
+ type: 'input',
37
+ name: 'task',
38
+ message: 'Anything to tell the agent? (optional):',
39
+ }]);
40
+ task = ans.task || undefined;
41
+ }
42
+ return { toNumber, task }; // fromNumber resolved by caller
43
+ }
44
+ //# sourceMappingURL=free.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"free.js","sourceRoot":"","sources":["../../../../../src/commands/phone/_modes/free.ts"],"names":[],"mappings":"AAsBA,MAAM,cAAc,GAAG,+EAA+E,CAAC;AAEvG,MAAM,UAAU,mBAAmB,CAAC,MAAsB;IACxD,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,IAAI,cAAc,CAAC;IAEpD,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,GAAG,EAAE;YACH,GAAG,MAAM,CAAC,GAAG;YACb,eAAe,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;SAC9D;QACD,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE;QACtB,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE;QACtB,WAAW,EAAE,GAAG;QAChB,KAAK,EAAE,kBAAkB,MAAM,CAAC,QAAQ,EAAE;KAC3C,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAIvC;IACC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IACvD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAExD,IAAI,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;IACvB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,+BAA+B;gBACxC,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,sBAAsB;aACtF,CAAC,CAAC,CAAC;QACJ,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC;IACpB,CAAC;IACD,QAAQ,GAAG,YAAY,CAAC,QAAS,CAAC,CAAC;IAEnC,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACrB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,yCAAyC;aACnD,CAAC,CAAC,CAAC;QACJ,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,SAAS,CAAC;IAC/B,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,gCAAgC;AAC7D,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { LLMConfig, TTSConfig, ASRConfig } from '../../../api/types.js';
2
+ import type { CallConfig } from './free.js';
3
+ export declare const SUPPORTED_LANGUAGES: {
4
+ value: string;
5
+ name: string;
6
+ }[];
7
+ export interface TranslateCallParams {
8
+ toNumber: string;
9
+ fromNumber: string;
10
+ sourceLang: string;
11
+ targetLang: string;
12
+ llm: Partial<LLMConfig>;
13
+ tts: Partial<TTSConfig>;
14
+ asr: Partial<ASRConfig>;
15
+ }
16
+ /** Parse a "source:target" language pair string. */
17
+ export declare function parseLanguagePair(pair: string): {
18
+ source: string;
19
+ target: string;
20
+ };
21
+ export declare function buildTranslateCallConfig(params: TranslateCallParams): CallConfig;
22
+ /** Interactive parameter collection for translate mode. */
23
+ export declare function collectTranslateParams(opts: {
24
+ to?: string;
25
+ lang?: string;
26
+ }): Promise<{
27
+ toNumber: string;
28
+ sourceLang: string;
29
+ targetLang: string;
30
+ }>;
@@ -0,0 +1,89 @@
1
+ export const SUPPORTED_LANGUAGES = [
2
+ { value: 'zh', name: 'Chinese (中文)' },
3
+ { value: 'en', name: 'English' },
4
+ { value: 'ja', name: 'Japanese (日本語)' },
5
+ { value: 'ko', name: 'Korean (한국어)' },
6
+ { value: 'es', name: 'Spanish (Español)' },
7
+ { value: 'fr', name: 'French (Français)' },
8
+ { value: 'de', name: 'German (Deutsch)' },
9
+ { value: 'pt', name: 'Portuguese (Português)' },
10
+ { value: 'ru', name: 'Russian (Русский)' },
11
+ { value: 'ar', name: 'Arabic (العربية)' },
12
+ { value: 'hi', name: 'Hindi (हिन्दी)' },
13
+ { value: 'th', name: 'Thai (ไทย)' },
14
+ { value: 'vi', name: 'Vietnamese (Tiếng Việt)' },
15
+ { value: 'it', name: 'Italian (Italiano)' },
16
+ { value: 'tr', name: 'Turkish (Türkçe)' },
17
+ { value: 'id', name: 'Indonesian (Bahasa)' },
18
+ ];
19
+ /** Parse a "source:target" language pair string. */
20
+ export function parseLanguagePair(pair) {
21
+ const parts = pair.split(':');
22
+ if (parts.length !== 2 || !parts[0].trim() || !parts[1].trim()) {
23
+ throw new Error(`Invalid language pair "${pair}". Use format: zh:ja`);
24
+ }
25
+ return { source: parts[0].trim(), target: parts[1].trim() };
26
+ }
27
+ export function buildTranslateCallConfig(params) {
28
+ const translationPrompt = `You are a real-time voice translator. ` +
29
+ `The caller speaks ${params.sourceLang}. The person on the other end speaks ${params.targetLang}. ` +
30
+ `Translate everything the caller says into ${params.targetLang}, and everything the other person says into ${params.sourceLang}. ` +
31
+ `Translate naturally and conversationally. Do not add commentary, just translate. ` +
32
+ `Preserve tone and intent.`;
33
+ return {
34
+ mode: 'translate',
35
+ toNumber: params.toNumber,
36
+ fromNumber: params.fromNumber,
37
+ llm: {
38
+ ...params.llm,
39
+ system_messages: [{ role: 'system', content: translationPrompt }],
40
+ },
41
+ tts: { ...params.tts },
42
+ asr: { ...params.asr },
43
+ idleTimeout: 1800,
44
+ label: `🌐 Translate [${params.sourceLang} → ${params.targetLang}] → ${params.toNumber}`,
45
+ };
46
+ }
47
+ /** Interactive parameter collection for translate mode. */
48
+ export async function collectTranslateParams(opts) {
49
+ const { default: inquirer } = await import('inquirer');
50
+ const { validateE164 } = await import('../_helpers.js');
51
+ let sourceLang;
52
+ let targetLang;
53
+ if (opts.lang) {
54
+ const parsed = parseLanguagePair(opts.lang);
55
+ sourceLang = parsed.source;
56
+ targetLang = parsed.target;
57
+ }
58
+ else {
59
+ const langAns = await inquirer.prompt([
60
+ {
61
+ type: 'list',
62
+ name: 'source',
63
+ message: 'Your language:',
64
+ choices: SUPPORTED_LANGUAGES,
65
+ },
66
+ {
67
+ type: 'list',
68
+ name: 'target',
69
+ message: 'Target language:',
70
+ choices: SUPPORTED_LANGUAGES,
71
+ },
72
+ ]);
73
+ sourceLang = langAns.source;
74
+ targetLang = langAns.target;
75
+ }
76
+ let toNumber = opts.to;
77
+ if (!toNumber) {
78
+ const ans = await inquirer.prompt([{
79
+ type: 'input',
80
+ name: 'to',
81
+ message: 'Phone number to call (E.164):',
82
+ validate: (v) => /^\+[1-9]\d{1,14}$/.test(v.trim()) || 'Invalid E.164 format',
83
+ }]);
84
+ toNumber = ans.to;
85
+ }
86
+ toNumber = validateE164(toNumber);
87
+ return { toNumber, sourceLang, targetLang };
88
+ }
89
+ //# sourceMappingURL=translate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translate.js","sourceRoot":"","sources":["../../../../../src/commands/phone/_modes/translate.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE;IACrC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE;IAChC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACvC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE;IACrC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,mBAAmB,EAAE;IAC1C,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,mBAAmB,EAAE;IAC1C,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE;IACzC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,wBAAwB,EAAE;IAC/C,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,mBAAmB,EAAE;IAC1C,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE;IACzC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,gBAAgB,EAAE;IACvC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE;IACnC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,yBAAyB,EAAE;IAChD,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,oBAAoB,EAAE;IAC3C,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE;IACzC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,qBAAqB,EAAE;CAC7C,CAAC;AAYF,oDAAoD;AACpD,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,sBAAsB,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,MAA2B;IAClE,MAAM,iBAAiB,GACrB,wCAAwC;QACxC,qBAAqB,MAAM,CAAC,UAAU,wCAAwC,MAAM,CAAC,UAAU,IAAI;QACnG,6CAA6C,MAAM,CAAC,UAAU,+CAA+C,MAAM,CAAC,UAAU,IAAI;QAClI,mFAAmF;QACnF,2BAA2B,CAAC;IAE9B,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,GAAG,EAAE;YACH,GAAG,MAAM,CAAC,GAAG;YACb,eAAe,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;SAClE;QACD,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE;QACtB,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE;QACtB,WAAW,EAAE,IAAI;QACjB,KAAK,EAAE,iBAAiB,MAAM,CAAC,UAAU,MAAM,MAAM,CAAC,UAAU,OAAO,MAAM,CAAC,QAAQ,EAAE;KACzF,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAG5C;IACC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IACvD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAExD,IAAI,UAAkB,CAAC;IACvB,IAAI,UAAkB,CAAC;IAEvB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;QAC3B,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;YACpC;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,gBAAgB;gBACzB,OAAO,EAAE,mBAAmB;aAC7B;YACD;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,kBAAkB;gBAC3B,OAAO,EAAE,mBAAmB;aAC7B;SACF,CAAC,CAAC;QACH,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;QAC5B,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,IAAI,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;IACvB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,+BAA+B;gBACxC,QAAQ,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,sBAAsB;aACtF,CAAC,CAAC,CAAC;QACJ,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC;IACpB,CAAC;IACD,QAAQ,GAAG,YAAY,CAAC,QAAS,CAAC,CAAC;IAEnC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerPhoneGet(phone: Command): void;
@@ -0,0 +1,34 @@
1
+ import { getNumberAPI } from './_helpers.js';
2
+ import { printKeyValue } from '../../ui/table.js';
3
+ import { handleError } from '../../utils/errors.js';
4
+ export function registerPhoneGet(phone) {
5
+ phone
6
+ .command('number <phone-number>')
7
+ .description('View phone number details')
8
+ .option('--profile <name>', 'Config profile')
9
+ .option('--json', 'JSON output')
10
+ .action(async (phoneNumber, opts) => {
11
+ try {
12
+ const api = getNumberAPI(opts.profile);
13
+ const num = await api.get(phoneNumber);
14
+ if (opts.json) {
15
+ console.log(JSON.stringify(num, null, 2));
16
+ return;
17
+ }
18
+ console.log('');
19
+ printKeyValue([
20
+ ['Phone', num.phone_number],
21
+ ['Label', num.label],
22
+ ['Provider', num.provider],
23
+ ['Outbound', num.outbound ? 'yes' : 'no'],
24
+ ['Inbound', num.inbound ? 'yes' : 'no'],
25
+ ['SIP', num.outbound_config ? `${num.outbound_config.address} (${num.outbound_config.transport})` : '-'],
26
+ ['Pipeline', num.associated_pipeline?.pipeline_name ?? '(none)'],
27
+ ]);
28
+ }
29
+ catch (error) {
30
+ handleError(error, { json: opts.json });
31
+ }
32
+ });
33
+ }
34
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../../../src/commands/phone/get.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,KAAK;SACF,OAAO,CAAC,uBAAuB,CAAC;SAChC,WAAW,CAAC,2BAA2B,CAAC;SACxC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC;SAC/B,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;QAClC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvC,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAEvC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC1C,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,aAAa,CAAC;gBACZ,CAAC,OAAO,EAAE,GAAG,CAAC,YAAY,CAAC;gBAC3B,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC;gBACpB,CAAC,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC;gBAC1B,CAAC,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;gBACzC,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;gBACvC,CAAC,KAAK,EAAE,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,eAAe,CAAC,OAAO,KAAK,GAAG,CAAC,eAAe,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;gBACxG,CAAC,UAAU,EAAE,GAAG,CAAC,mBAAmB,EAAE,aAAa,IAAI,QAAQ,CAAC;aACjE,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerPhoneGo(phone: Command): void;