conduyt 1.13.0 → 1.14.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 (2) hide show
  1. package/dist/index.js +98 -0
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2110,6 +2110,104 @@ ringGroups
2110
2110
  }
2111
2111
  return client.post("/api/v1/ring-groups/release-number", body);
2112
2112
  }));
2113
+ // ---------------------------------------------------------------------------
2114
+ // Smart Views + Smart Dialing (#53). The dial-enabled Smart Views are the
2115
+ // Smart Dialing priorities: agents dial them one lead at a time, top to
2116
+ // bottom. Dialing settings + reorder are admin-only in the API.
2117
+ // ---------------------------------------------------------------------------
2118
+ const smartViews = program.command("smart-views").description("Smart Views and their Smart Dialing priorities");
2119
+ smartViews
2120
+ .command("list")
2121
+ .description("List Smart Views in sidebar order (= Smart Dialing priority) with lead counts and dialing settings")
2122
+ .option("--dialing", "only the dial-enabled views (the Smart Dialing priorities)")
2123
+ .action(run(async (client, opts) => {
2124
+ const views = (await client.get("/api/v1/smart-views"));
2125
+ const rows = Array.isArray(views) ? views : [];
2126
+ const sorted = [...rows].sort((a, b) => Number(a.sortPosition ?? 0) - Number(b.sortPosition ?? 0));
2127
+ return opts.dialing ? sorted.filter((v) => v.dialEnabled === true) : sorted;
2128
+ }));
2129
+ smartViews
2130
+ .command("dialing <id>")
2131
+ .description("Change one Smart View's Smart Dialing settings (PATCH — only the flags you pass change)")
2132
+ .option("--enable", "make this view a Smart Dialing priority")
2133
+ .option("--disable", "stop dialing this view")
2134
+ .option("--max-attempts <n>", "stop after N calls to a lead, ever (1-20)")
2135
+ .option("--per-day <n>", "most calls to one lead per account-local day (1-20); pass 'none' to remove the daily cap")
2136
+ .option("--cooldown <minutes>", "minutes to wait between calls to the same lead (0-10080)")
2137
+ .option("--schedule <json>", 'retry schedule JSON, e.g. \'[{"attemptNumber":1,"delayMinutes":0},{"attemptNumber":2,"delayMinutes":60}]\'')
2138
+ .action(run(async (client, id, opts) => {
2139
+ assertUuid(id, "smart view id");
2140
+ if (opts.enable && opts.disable)
2141
+ throw new Error("Pass --enable or --disable, not both.");
2142
+ const body = {};
2143
+ if (opts.enable)
2144
+ body.dialEnabled = true;
2145
+ if (opts.disable)
2146
+ body.dialEnabled = false;
2147
+ const intFlag = (raw, flag, min, max) => {
2148
+ if (raw === undefined)
2149
+ return undefined;
2150
+ const n = Number(raw);
2151
+ if (!Number.isInteger(n) || n < min || n > max)
2152
+ throw new Error(`${flag} must be an integer between ${min} and ${max}.`);
2153
+ return n;
2154
+ };
2155
+ const maxAttempts = intFlag(opts.maxAttempts, "--max-attempts", 1, 20);
2156
+ if (maxAttempts !== undefined)
2157
+ body.maxDialAttempts = maxAttempts;
2158
+ if (opts.perDay !== undefined) {
2159
+ body.maxDialAttemptsPerDay = opts.perDay.trim().toLowerCase() === "none" ? null : intFlag(opts.perDay, "--per-day", 1, 20);
2160
+ }
2161
+ const cooldown = intFlag(opts.cooldown, "--cooldown", 0, 10080);
2162
+ if (cooldown !== undefined)
2163
+ body.dialCooldownMinutes = cooldown;
2164
+ if (opts.schedule !== undefined) {
2165
+ let parsed;
2166
+ try {
2167
+ parsed = JSON.parse(opts.schedule);
2168
+ }
2169
+ catch {
2170
+ throw new Error("--schedule must be valid JSON.");
2171
+ }
2172
+ if (!Array.isArray(parsed) || parsed.length === 0 || parsed.length > 20)
2173
+ throw new Error("--schedule must be a JSON array of 1-20 steps.");
2174
+ for (const step of parsed) {
2175
+ if (!step || !Number.isInteger(step.attemptNumber) || Number(step.attemptNumber) < 1 || !Number.isInteger(step.delayMinutes) || Number(step.delayMinutes) < 0) {
2176
+ throw new Error("Each --schedule step needs attemptNumber (>= 1) and delayMinutes (>= 0).");
2177
+ }
2178
+ }
2179
+ body.dialSchedule = parsed;
2180
+ }
2181
+ if (Object.keys(body).length === 0)
2182
+ throw new Error("Nothing to change. Pass --enable/--disable, --max-attempts, --per-day, --cooldown or --schedule.");
2183
+ return client.patch(`/api/v1/smart-views/${encodeURIComponent(id)}`, body);
2184
+ }));
2185
+ smartViews
2186
+ .command("dial-order [ids...]")
2187
+ .description("No ids: show the Smart Dialing priorities, uncapped (every dial-enabled view in dial order + candidates). With ids: set the priority order — every dial-enabled view id, first = dialed first (the server keeps non-priority views in their slots)")
2188
+ .action(run(async (client, ids) => {
2189
+ if (!ids || ids.length === 0)
2190
+ return client.get("/api/v1/smart-views/dial-order");
2191
+ if (ids.length > 2000)
2192
+ throw new Error("Pass at most 2000 Smart View ids.");
2193
+ if (new Set(ids).size !== ids.length)
2194
+ throw new Error("Smart View ids must not repeat.");
2195
+ for (const id of ids)
2196
+ assertUuid(id, "smart view id");
2197
+ return client.patch("/api/v1/smart-views/dial-order", { order: ids });
2198
+ }));
2199
+ smartViews
2200
+ .command("reorder <ids...>")
2201
+ .description("Set the SIDEBAR order of Smart Views. Pass EVERY view id; views left out keep a stale position. For the dialing priority use dial-order")
2202
+ .action(run(async (client, ids) => {
2203
+ if (ids.length === 0 || ids.length > 200)
2204
+ throw new Error("Pass 1-200 Smart View ids.");
2205
+ if (new Set(ids).size !== ids.length)
2206
+ throw new Error("Smart View ids must not repeat.");
2207
+ for (const id of ids)
2208
+ assertUuid(id, "smart view id");
2209
+ return client.patch("/api/v1/smart-views/reorder", { order: ids });
2210
+ }));
2113
2211
  program.parseAsync(process.argv).catch(fail);
2114
2212
  // helpers
2115
2213
  // Parse a --json / --stages style argument, throwing a clear CLI error (caught
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conduyt",
3
- "version": "1.13.0",
3
+ "version": "1.14.0",
4
4
  "description": "Command-line interface for Conduyt CRM — manage contacts, deals, pipelines, and run insight queries from your terminal.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",