@dench.com/cli 2.7.6-staging.1 → 2.7.7-staging.21
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/crm.ts +134 -17
- package/dench.ts +2 -3
- package/email.ts +50 -6
- package/lib/command-registry.ts +76 -12
- package/package.json +1 -1
package/crm.ts
CHANGED
|
@@ -687,6 +687,21 @@ const api = {
|
|
|
687
687
|
reposition: makeFunctionReference<"mutation">(
|
|
688
688
|
"functions/workspaceNav:repositionMyNavItem",
|
|
689
689
|
),
|
|
690
|
+
createGroup: makeFunctionReference<"mutation">(
|
|
691
|
+
"functions/workspaceNav:createNavGroup",
|
|
692
|
+
),
|
|
693
|
+
renameGroup: makeFunctionReference<"mutation">(
|
|
694
|
+
"functions/workspaceNav:renameNavGroup",
|
|
695
|
+
),
|
|
696
|
+
deleteGroup: makeFunctionReference<"mutation">(
|
|
697
|
+
"functions/workspaceNav:deleteNavGroup",
|
|
698
|
+
),
|
|
699
|
+
moveItemToGroup: makeFunctionReference<"mutation">(
|
|
700
|
+
"functions/workspaceNav:moveNavItemToGroup",
|
|
701
|
+
),
|
|
702
|
+
setRootPin: makeFunctionReference<"mutation">(
|
|
703
|
+
"functions/workspaceNav:setNavRootPin",
|
|
704
|
+
),
|
|
690
705
|
},
|
|
691
706
|
fields: {
|
|
692
707
|
list: makeFunctionReference<"query">("functions/crm/fields:list"),
|
|
@@ -959,13 +974,15 @@ async function runCrmMembersCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
959
974
|
}
|
|
960
975
|
|
|
961
976
|
/**
|
|
962
|
-
* `dench crm sidebar …` — the workspace app rail.
|
|
977
|
+
* `dench crm sidebar …` — the workspace app rail's Library.
|
|
963
978
|
*
|
|
964
|
-
*
|
|
965
|
-
*
|
|
966
|
-
*
|
|
967
|
-
*
|
|
968
|
-
*
|
|
979
|
+
* The whole layout is WORKSPACE-SHARED: one tree of rows and named
|
|
980
|
+
* groups for every member. Permissions split by operation — `move` (and
|
|
981
|
+
* `crm objects archive` / `crm views archive`) are ADMIN-ONLY because
|
|
982
|
+
* they change what everyone sees; `group …` operations and view pinning
|
|
983
|
+
* are open to any member. `list` shows the visible rows in tree order
|
|
984
|
+
* (rows inside a group carry `groupId`/`groupName`), the groups, what's
|
|
985
|
+
* hidden and why, and whether YOU are an admin (`viewerIsAdmin`).
|
|
969
986
|
*/
|
|
970
987
|
async function runSidebarCommand(ctx: CrmCliContext): Promise<void> {
|
|
971
988
|
const verb = ctx.args.shift() ?? "list";
|
|
@@ -997,6 +1014,85 @@ async function runSidebarCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
997
1014
|
);
|
|
998
1015
|
return;
|
|
999
1016
|
}
|
|
1017
|
+
// Pin/unpin a Library row (or a whole group) on the Sidebar's home
|
|
1018
|
+
// level shortcut strip. Member-level, workspace-shared — like view
|
|
1019
|
+
// pinning.
|
|
1020
|
+
case "pin":
|
|
1021
|
+
case "unpin": {
|
|
1022
|
+
const navId = shift(ctx.args, "nav id");
|
|
1023
|
+
assertNoUnknownFlags(ctx.args, `crm sidebar ${verb}`);
|
|
1024
|
+
out(
|
|
1025
|
+
ctx,
|
|
1026
|
+
await callMutation(ctx, api.sidebar.setRootPin, {
|
|
1027
|
+
navId,
|
|
1028
|
+
pinned: verb === "pin",
|
|
1029
|
+
}),
|
|
1030
|
+
);
|
|
1031
|
+
return;
|
|
1032
|
+
}
|
|
1033
|
+
case "group": {
|
|
1034
|
+
const groupVerb = ctx.args.shift();
|
|
1035
|
+
switch (groupVerb) {
|
|
1036
|
+
case "create": {
|
|
1037
|
+
const name = shift(ctx.args, "group name");
|
|
1038
|
+
assertNoUnknownFlags(ctx.args, "crm sidebar group create");
|
|
1039
|
+
out(ctx, await callMutation(ctx, api.sidebar.createGroup, { name }));
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
case "rename": {
|
|
1043
|
+
const groupId = shift(ctx.args, "group id");
|
|
1044
|
+
const name = shift(ctx.args, "new name");
|
|
1045
|
+
assertNoUnknownFlags(ctx.args, "crm sidebar group rename");
|
|
1046
|
+
out(
|
|
1047
|
+
ctx,
|
|
1048
|
+
await callMutation(ctx, api.sidebar.renameGroup, {
|
|
1049
|
+
groupId,
|
|
1050
|
+
name,
|
|
1051
|
+
}),
|
|
1052
|
+
);
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
case "delete": {
|
|
1056
|
+
const groupId = shift(ctx.args, "group id");
|
|
1057
|
+
assertNoUnknownFlags(ctx.args, "crm sidebar group delete");
|
|
1058
|
+
out(
|
|
1059
|
+
ctx,
|
|
1060
|
+
await callMutation(ctx, api.sidebar.deleteGroup, { groupId }),
|
|
1061
|
+
);
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
case "add": {
|
|
1065
|
+
const navId = shift(ctx.args, "nav id");
|
|
1066
|
+
const groupId = shift(ctx.args, "group id");
|
|
1067
|
+
assertNoUnknownFlags(ctx.args, "crm sidebar group add");
|
|
1068
|
+
out(
|
|
1069
|
+
ctx,
|
|
1070
|
+
await callMutation(ctx, api.sidebar.moveItemToGroup, {
|
|
1071
|
+
navId,
|
|
1072
|
+
groupId,
|
|
1073
|
+
}),
|
|
1074
|
+
);
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
case "remove": {
|
|
1078
|
+
const navId = shift(ctx.args, "nav id");
|
|
1079
|
+
assertNoUnknownFlags(ctx.args, "crm sidebar group remove");
|
|
1080
|
+
out(
|
|
1081
|
+
ctx,
|
|
1082
|
+
await callMutation(ctx, api.sidebar.moveItemToGroup, {
|
|
1083
|
+
navId,
|
|
1084
|
+
groupId: null,
|
|
1085
|
+
}),
|
|
1086
|
+
);
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
default:
|
|
1090
|
+
throw new CrmCliError(
|
|
1091
|
+
`Unknown crm sidebar group verb: ${groupVerb ?? "(none)"}. ` +
|
|
1092
|
+
"Use create|rename|delete|add|remove.",
|
|
1093
|
+
);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1000
1096
|
default:
|
|
1001
1097
|
throw new CrmCliError(`Unknown crm sidebar verb: ${verb}`);
|
|
1002
1098
|
}
|
|
@@ -1071,9 +1167,10 @@ async function runObjectsCommand(ctx: CrmCliContext): Promise<void> {
|
|
|
1071
1167
|
out(ctx, await callMutation(ctx, api.objects.remove, { name }));
|
|
1072
1168
|
return;
|
|
1073
1169
|
}
|
|
1074
|
-
// Archive is the sidebar's "remove from
|
|
1170
|
+
// Archive is the sidebar's "remove from the rail", NOT a delete: the
|
|
1075
1171
|
// table, its rows and every link to it keep working, the row just
|
|
1076
|
-
// moves into the rail's Archived flyout. Team-shared
|
|
1172
|
+
// moves into the rail's Archived flyout. Team-shared, and ADMIN-ONLY
|
|
1173
|
+
// (the server rejects non-admin members).
|
|
1077
1174
|
case "archive":
|
|
1078
1175
|
case "unarchive": {
|
|
1079
1176
|
const name = shift(ctx.args, "object name");
|
|
@@ -3571,7 +3668,7 @@ Objects (CRM tables):
|
|
|
3571
3668
|
dench crm objects archive <name> | unarchive <name>
|
|
3572
3669
|
Hides/restores the object's workspace SIDEBAR row. Not a delete —
|
|
3573
3670
|
the table, its rows and every link keep working; the row just moves
|
|
3574
|
-
into the rail's Archived flyout. Team-shared.
|
|
3671
|
+
into the rail's Archived flyout. Team-shared and ADMIN-ONLY.
|
|
3575
3672
|
|
|
3576
3673
|
Views (saved CRM subsets):
|
|
3577
3674
|
dench crm views list <object> [--json]
|
|
@@ -3596,17 +3693,37 @@ Views (saved CRM subsets):
|
|
|
3596
3693
|
clears any archive stamp.
|
|
3597
3694
|
dench crm views archive <object> <view-name> | unarchive <object> <view-name>
|
|
3598
3695
|
Moves the view's sidebar row into the Archived flyout. Unarchiving
|
|
3599
|
-
re-asserts the pin so the row comes back.
|
|
3696
|
+
re-asserts the pin so the row comes back. ADMIN-ONLY: archiving
|
|
3697
|
+
hides the row for the whole workspace.
|
|
3600
3698
|
|
|
3601
|
-
Sidebar (the workspace app rail):
|
|
3699
|
+
Sidebar (the workspace app rail's Library — layout is WORKSPACE-SHARED):
|
|
3602
3700
|
dench crm sidebar list [--json]
|
|
3603
|
-
Visible rows in order
|
|
3604
|
-
|
|
3701
|
+
Visible rows in tree order (rows inside a group carry groupId/
|
|
3702
|
+
groupName), the groups, what's hidden and why (archived vs. an
|
|
3703
|
+
unpinned view), and whether you are an admin (viewerIsAdmin).
|
|
3605
3704
|
dench crm sidebar move <nav-id> <top|bottom|N>
|
|
3606
|
-
Reposition one row
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3705
|
+
Reposition one row (or a whole group by its group id) among the
|
|
3706
|
+
TOP-LEVEL slots — a group counts as one slot, and a row inside a
|
|
3707
|
+
group is pulled out to the top level. Nav ids come from 'sidebar
|
|
3708
|
+
list' — e.g. 'crm-object:task', 'crm-view:task:Due%20today',
|
|
3709
|
+
'crm-people', 'group:abc123'. Automations and Outreach are fixed
|
|
3710
|
+
home-level tabs, not Library rows. ADMIN-ONLY: the order is
|
|
3711
|
+
shared by every member.
|
|
3712
|
+
dench crm sidebar group create <name>
|
|
3713
|
+
New named group (e.g. "Hiring") at the bottom of the Library.
|
|
3714
|
+
Open to any member; prints the group id.
|
|
3715
|
+
dench crm sidebar group rename <group-id> <new-name>
|
|
3716
|
+
dench crm sidebar group delete <group-id>
|
|
3717
|
+
Dissolves the group; its rows return to the top level in its slot.
|
|
3718
|
+
dench crm sidebar group add <nav-id> <group-id>
|
|
3719
|
+
File a row into a group (appended at its end).
|
|
3720
|
+
dench crm sidebar group remove <nav-id>
|
|
3721
|
+
Move a row out of its group, back to the top level.
|
|
3722
|
+
dench crm sidebar pin <nav-id> | unpin <nav-id>
|
|
3723
|
+
Pin/unpin a Library row — or a whole group (group id) — on the
|
|
3724
|
+
Sidebar's home level, under Chats/Inbox/Meetings/Automations/
|
|
3725
|
+
Outreach/Library.
|
|
3726
|
+
A pin is a shared shortcut, not a move; open to any member.
|
|
3610
3727
|
|
|
3611
3728
|
Fields (columns):
|
|
3612
3729
|
dench crm fields list <object> [--json]
|
package/dench.ts
CHANGED
|
@@ -538,9 +538,8 @@ Monetize the AI "thinking…" line (supported hooks only — no file patching):
|
|
|
538
538
|
dench ads uninstall [--target claude|shell|agentmd|all]
|
|
539
539
|
Aliases: dench ad, dench adline. Help: dench ads help
|
|
540
540
|
|
|
541
|
-
Managed email campaigns
|
|
542
|
-
dench email
|
|
543
|
-
dench email template create --name "Intro" --subject "Hi {{firstName}}" --html-file body.html [--json]
|
|
541
|
+
Managed email campaigns:
|
|
542
|
+
dench email campaign create --name "Q2 outreach" --mailbox you@gmail.com --template <id> [--json]
|
|
544
543
|
dench email campaign create --name "Q2 outreach" --identity <id> --template <id> [--json]
|
|
545
544
|
dench email campaign recipients add --campaign <id> --file recipients.jsonl [--json]
|
|
546
545
|
dench email campaign submit --campaign <id> [--json]
|
package/email.ts
CHANGED
|
@@ -118,6 +118,48 @@ function requiredFlag(args: string[], name: string): string {
|
|
|
118
118
|
return value;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
async function resolveMailboxAccountIds(
|
|
122
|
+
ctx: EmailCliContext,
|
|
123
|
+
mailbox: string,
|
|
124
|
+
): Promise<string[]> {
|
|
125
|
+
const payload = await callQuery(
|
|
126
|
+
ctx,
|
|
127
|
+
"functions/emailMailboxAccounts:listAccounts",
|
|
128
|
+
{},
|
|
129
|
+
);
|
|
130
|
+
const accounts = Array.isArray(payload) ? (payload as JsonRecord[]) : [];
|
|
131
|
+
const needle = mailbox.trim().toLowerCase();
|
|
132
|
+
const match = accounts.find((row) => {
|
|
133
|
+
const id = typeof row._id === "string" ? row._id : "";
|
|
134
|
+
const email = typeof row.email === "string" ? row.email.toLowerCase() : "";
|
|
135
|
+
return id === mailbox.trim() || email === needle;
|
|
136
|
+
});
|
|
137
|
+
if (!match || typeof match._id !== "string") {
|
|
138
|
+
throw new EmailCliError(
|
|
139
|
+
`Connected inbox not found: ${mailbox}. Connect Gmail or Outlook in Outreach → Accounts.`,
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
return [match._id];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async function campaignSenderArgs(ctx: EmailCliContext): Promise<{
|
|
146
|
+
identityId?: string;
|
|
147
|
+
mailboxAccountIds?: string[];
|
|
148
|
+
}> {
|
|
149
|
+
const identity = getFlag(ctx.args, "--identity")?.trim();
|
|
150
|
+
const mailbox = getFlag(ctx.args, "--mailbox")?.trim();
|
|
151
|
+
if (identity && mailbox) {
|
|
152
|
+
throw new EmailCliError("Pass --mailbox or --identity, not both.");
|
|
153
|
+
}
|
|
154
|
+
if (mailbox) {
|
|
155
|
+
return { mailboxAccountIds: await resolveMailboxAccountIds(ctx, mailbox) };
|
|
156
|
+
}
|
|
157
|
+
if (identity) return { identityId: identity };
|
|
158
|
+
throw new EmailCliError(
|
|
159
|
+
"Pass --mailbox <email> (connected inbox) or --identity <sender>.",
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
121
163
|
function optionalJsonFlag(args: string[], name: string): unknown | undefined {
|
|
122
164
|
const raw = getFlag(args, name);
|
|
123
165
|
return raw === undefined ? undefined : parseJson(raw);
|
|
@@ -185,7 +227,7 @@ function toRecipients(rows: JsonRecord[]) {
|
|
|
185
227
|
}
|
|
186
228
|
|
|
187
229
|
export function emailHelp() {
|
|
188
|
-
console.log(`dench email — Dench Emailing Service
|
|
230
|
+
console.log(`dench email — outbound email from a connected inbox (or Dench Emailing Service)
|
|
189
231
|
|
|
190
232
|
Usage:
|
|
191
233
|
dench email identity verify --from founder@example.com [--json]
|
|
@@ -204,7 +246,7 @@ Usage:
|
|
|
204
246
|
dench email message list [--limit 25] [--json]
|
|
205
247
|
dench email template create --name "Intro" --subject "Hi {{firstName}}" --html-file body.html [--text-file body.txt] [--json]
|
|
206
248
|
dench email template preview --template <id> --data '{"firstName":"Ada"}' [--json]
|
|
207
|
-
dench email campaign create --name "Q2 outreach" --identity <identityId|fromEmail> --template <id> [--json]
|
|
249
|
+
dench email campaign create --name "Q2 outreach" (--mailbox you@gmail.com | --identity <identityId|fromEmail>) --template <id> [--json]
|
|
208
250
|
dench email campaign list [--status sending] [--limit 25] [--json]
|
|
209
251
|
dench email campaign recipients add --campaign <id> --file recipients.jsonl [--json]
|
|
210
252
|
dench email campaign recipients list --campaign <id> [--status queued] [--limit 50] [--json]
|
|
@@ -215,7 +257,7 @@ Usage:
|
|
|
215
257
|
dench email campaign pause|resume|cancel --campaign <id> [--json]
|
|
216
258
|
|
|
217
259
|
Sequences (automatic multi-step follow-ups):
|
|
218
|
-
dench email sequence create --name "New-customer follow-up" --identity <identityId|fromEmail> [--stop-on-click] [--no-stop-on-reply] [--json]
|
|
260
|
+
dench email sequence create --name "New-customer follow-up" (--mailbox you@gmail.com | --identity <identityId|fromEmail>) [--stop-on-click] [--no-stop-on-reply] [--json]
|
|
219
261
|
dench email sequence list [--all] [--json]
|
|
220
262
|
dench email sequence status --sequence <id> [--json]
|
|
221
263
|
dench email sequence steps add --sequence <id> --subject "Hi {{firstName}}" --html-file step1.html [--delay-days 0] [--delay-hours 0] [--json]
|
|
@@ -495,7 +537,7 @@ async function runIdentity(ctx: EmailCliContext) {
|
|
|
495
537
|
const identities = await listIdentitiesQuery(ctx, domain);
|
|
496
538
|
const text =
|
|
497
539
|
identities.length === 0
|
|
498
|
-
? "No sending identities
|
|
540
|
+
? "No sending identities. Connect Gmail or Outlook in Outreach → Accounts."
|
|
499
541
|
: identities
|
|
500
542
|
.map(
|
|
501
543
|
(identity) =>
|
|
@@ -716,12 +758,13 @@ async function runTemplate(ctx: EmailCliContext) {
|
|
|
716
758
|
async function runCampaign(ctx: EmailCliContext) {
|
|
717
759
|
const sub = ctx.args.shift();
|
|
718
760
|
if (sub === "create") {
|
|
761
|
+
const sender = await campaignSenderArgs(ctx);
|
|
719
762
|
const payload = await callMutation(
|
|
720
763
|
ctx,
|
|
721
764
|
"functions/emailCampaigns:createCampaign",
|
|
722
765
|
{
|
|
723
766
|
name: requiredFlag(ctx.args, "--name"),
|
|
724
|
-
|
|
767
|
+
...sender,
|
|
725
768
|
templateId: requiredFlag(ctx.args, "--template"),
|
|
726
769
|
scheduledAt: getFlag(ctx.args, "--scheduled-at")
|
|
727
770
|
? Date.parse(requiredFlag(ctx.args, "--scheduled-at"))
|
|
@@ -867,12 +910,13 @@ async function runSequence(ctx: EmailCliContext) {
|
|
|
867
910
|
const sub = ctx.args.shift();
|
|
868
911
|
if (sub === "create") {
|
|
869
912
|
const stopOnReply = !hasFlag(ctx.args, "--no-stop-on-reply");
|
|
913
|
+
const sender = await campaignSenderArgs(ctx);
|
|
870
914
|
const payload = await callMutation(
|
|
871
915
|
ctx,
|
|
872
916
|
"functions/emailSequences:createSequence",
|
|
873
917
|
{
|
|
874
918
|
name: requiredFlag(ctx.args, "--name"),
|
|
875
|
-
|
|
919
|
+
...sender,
|
|
876
920
|
replyToMode: getFlag(ctx.args, "--reply-to-mode"),
|
|
877
921
|
stopOnReply,
|
|
878
922
|
stopOnClick: getFlag(ctx.args, "--stop-on-click") !== undefined,
|
package/lib/command-registry.ts
CHANGED
|
@@ -588,7 +588,7 @@ const rawApiOperations = [
|
|
|
588
588
|
id: "crm.objects.archive",
|
|
589
589
|
group: "crm",
|
|
590
590
|
summary:
|
|
591
|
-
"Hide a CRM object's workspace sidebar row. Not a delete — the table keeps working.",
|
|
591
|
+
"Hide a CRM object's workspace sidebar row for the whole workspace. Not a delete — the table keeps working. Admin-only.",
|
|
592
592
|
cli: "dench crm objects archive",
|
|
593
593
|
method: "POST",
|
|
594
594
|
path: "/crm/objects/{name}/archive",
|
|
@@ -599,7 +599,7 @@ const rawApiOperations = [
|
|
|
599
599
|
op({
|
|
600
600
|
id: "crm.objects.unarchive",
|
|
601
601
|
group: "crm",
|
|
602
|
-
summary: "Restore a CRM object's workspace sidebar row.",
|
|
602
|
+
summary: "Restore a CRM object's workspace sidebar row. Admin-only.",
|
|
603
603
|
cli: "dench crm objects unarchive",
|
|
604
604
|
method: "POST",
|
|
605
605
|
path: "/crm/objects/{name}/unarchive",
|
|
@@ -679,7 +679,8 @@ const rawApiOperations = [
|
|
|
679
679
|
op({
|
|
680
680
|
id: "crm.views.archive",
|
|
681
681
|
group: "crm",
|
|
682
|
-
summary:
|
|
682
|
+
summary:
|
|
683
|
+
"Move a pinned view's sidebar row into the Archived flyout. Admin-only.",
|
|
683
684
|
cli: "dench crm views archive",
|
|
684
685
|
method: "POST",
|
|
685
686
|
path: "/crm/objects/{objectName}/views/{viewName}/archive",
|
|
@@ -690,7 +691,7 @@ const rawApiOperations = [
|
|
|
690
691
|
op({
|
|
691
692
|
id: "crm.views.unarchive",
|
|
692
693
|
group: "crm",
|
|
693
|
-
summary: "Restore a view's sidebar row (re-asserts its pin).",
|
|
694
|
+
summary: "Restore a view's sidebar row (re-asserts its pin). Admin-only.",
|
|
694
695
|
cli: "dench crm views unarchive",
|
|
695
696
|
method: "POST",
|
|
696
697
|
path: "/crm/objects/{objectName}/views/{viewName}/unarchive",
|
|
@@ -699,15 +700,15 @@ const rawApiOperations = [
|
|
|
699
700
|
backend: convex("mutation", "functions/crm/objects:setArchived"),
|
|
700
701
|
}),
|
|
701
702
|
|
|
702
|
-
// The workspace app rail.
|
|
703
|
-
//
|
|
704
|
-
//
|
|
705
|
-
//
|
|
703
|
+
// The workspace app rail's Library. The whole layout — row order AND
|
|
704
|
+
// named groups — is WORKSPACE-SHARED (one tree for every member,
|
|
705
|
+
// stored on the organization). Reordering (`move`) and archiving are
|
|
706
|
+
// admin-only; group management and view pinning are open to any member.
|
|
706
707
|
op({
|
|
707
708
|
id: "crm.sidebar.list",
|
|
708
709
|
group: "crm",
|
|
709
710
|
summary:
|
|
710
|
-
"Describe the workspace sidebar: visible rows in order,
|
|
711
|
+
"Describe the workspace sidebar: visible rows in tree order (with their groups), what is hidden and why, and whether the caller is an admin.",
|
|
711
712
|
cli: "dench crm sidebar list",
|
|
712
713
|
method: "GET",
|
|
713
714
|
path: "/crm/sidebar",
|
|
@@ -718,7 +719,8 @@ const rawApiOperations = [
|
|
|
718
719
|
op({
|
|
719
720
|
id: "crm.sidebar.move",
|
|
720
721
|
group: "crm",
|
|
721
|
-
summary:
|
|
722
|
+
summary:
|
|
723
|
+
"Reposition one sidebar row (or group) among the top-level slots. The layout is workspace-shared; admin-only.",
|
|
722
724
|
cli: "dench crm sidebar move",
|
|
723
725
|
method: "POST",
|
|
724
726
|
path: "/crm/sidebar/move",
|
|
@@ -726,6 +728,67 @@ const rawApiOperations = [
|
|
|
726
728
|
responseSchema: anyResponse,
|
|
727
729
|
backend: convex("mutation", "functions/workspaceNav:repositionMyNavItem"),
|
|
728
730
|
}),
|
|
731
|
+
op({
|
|
732
|
+
id: "crm.sidebar.groups.create",
|
|
733
|
+
group: "crm",
|
|
734
|
+
summary:
|
|
735
|
+
'Create a named sidebar group (e.g. "Hiring") in the workspace-shared Library. Open to any member.',
|
|
736
|
+
cli: "dench crm sidebar group create",
|
|
737
|
+
method: "POST",
|
|
738
|
+
path: "/crm/sidebar/groups",
|
|
739
|
+
requestSchema: anyObject,
|
|
740
|
+
responseSchema: anyResponse,
|
|
741
|
+
backend: convex("mutation", "functions/workspaceNav:createNavGroup"),
|
|
742
|
+
}),
|
|
743
|
+
op({
|
|
744
|
+
id: "crm.sidebar.groups.rename",
|
|
745
|
+
group: "crm",
|
|
746
|
+
summary: "Rename a sidebar group. Open to any member.",
|
|
747
|
+
cli: "dench crm sidebar group rename",
|
|
748
|
+
method: "POST",
|
|
749
|
+
path: "/crm/sidebar/groups/rename",
|
|
750
|
+
requestSchema: anyObject,
|
|
751
|
+
responseSchema: anyResponse,
|
|
752
|
+
backend: convex("mutation", "functions/workspaceNav:renameNavGroup"),
|
|
753
|
+
}),
|
|
754
|
+
op({
|
|
755
|
+
id: "crm.sidebar.groups.delete",
|
|
756
|
+
group: "crm",
|
|
757
|
+
summary:
|
|
758
|
+
"Dissolve a sidebar group; its rows return to the top level in its slot. Open to any member.",
|
|
759
|
+
cli: "dench crm sidebar group delete",
|
|
760
|
+
method: "POST",
|
|
761
|
+
path: "/crm/sidebar/groups/delete",
|
|
762
|
+
requestSchema: anyObject,
|
|
763
|
+
responseSchema: anyResponse,
|
|
764
|
+
backend: convex("mutation", "functions/workspaceNav:deleteNavGroup"),
|
|
765
|
+
}),
|
|
766
|
+
op({
|
|
767
|
+
id: "crm.sidebar.groups.move-item",
|
|
768
|
+
group: "crm",
|
|
769
|
+
summary:
|
|
770
|
+
"Move a sidebar row into a group (groupId set) or back to the top level (groupId null). Open to any member.",
|
|
771
|
+
cli: "dench crm sidebar group add",
|
|
772
|
+
aliases: ["dench crm sidebar group remove"],
|
|
773
|
+
method: "POST",
|
|
774
|
+
path: "/crm/sidebar/groups/move",
|
|
775
|
+
requestSchema: anyObject,
|
|
776
|
+
responseSchema: anyResponse,
|
|
777
|
+
backend: convex("mutation", "functions/workspaceNav:moveNavItemToGroup"),
|
|
778
|
+
}),
|
|
779
|
+
op({
|
|
780
|
+
id: "crm.sidebar.pins.set",
|
|
781
|
+
group: "crm",
|
|
782
|
+
summary:
|
|
783
|
+
"Pin (pinned true) or unpin a Library row — or a whole group — on the Sidebar's home-level shortcut strip. Workspace-shared; open to any member.",
|
|
784
|
+
cli: "dench crm sidebar pin",
|
|
785
|
+
aliases: ["dench crm sidebar unpin"],
|
|
786
|
+
method: "POST",
|
|
787
|
+
path: "/crm/sidebar/pins",
|
|
788
|
+
requestSchema: anyObject,
|
|
789
|
+
responseSchema: anyResponse,
|
|
790
|
+
backend: convex("mutation", "functions/workspaceNav:setNavRootPin"),
|
|
791
|
+
}),
|
|
729
792
|
|
|
730
793
|
op({
|
|
731
794
|
id: "crm.fields.list",
|
|
@@ -1581,7 +1644,8 @@ const rawApiOperations = [
|
|
|
1581
1644
|
op({
|
|
1582
1645
|
id: "email.campaign.create",
|
|
1583
1646
|
group: "email",
|
|
1584
|
-
summary:
|
|
1647
|
+
summary:
|
|
1648
|
+
"Create a managed email campaign draft from a connected inbox or verified sender.",
|
|
1585
1649
|
cli: "dench email campaign create",
|
|
1586
1650
|
method: "POST",
|
|
1587
1651
|
path: "/email/campaigns",
|
|
@@ -1711,7 +1775,7 @@ const rawApiOperations = [
|
|
|
1711
1775
|
id: "email.sequence.create",
|
|
1712
1776
|
group: "email",
|
|
1713
1777
|
summary:
|
|
1714
|
-
"Create a follow-up sequence
|
|
1778
|
+
"Create a follow-up sequence from a connected inbox or verified sender.",
|
|
1715
1779
|
cli: "dench email sequence create",
|
|
1716
1780
|
method: "POST",
|
|
1717
1781
|
path: "/email/sequences",
|