@dench.com/cli 2.1.1 → 2.1.3

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.
@@ -0,0 +1,1816 @@
1
+ import { type ZodTypeAny, z } from "zod";
2
+ import { convexExtras, requestSchemas, responseSchemas } from "./api-schemas";
3
+
4
+ export type ApiAuthMode = "none" | "bearer" | "optional";
5
+
6
+ export type ConvexOperation = {
7
+ kind: "convex";
8
+ functionType: "query" | "mutation" | "action";
9
+ functionName: string;
10
+ auth: ApiAuthMode;
11
+ tokenArg?: "sessionToken" | "apiKey";
12
+ includeRunId?: boolean;
13
+ /** Constant args merged into every call (e.g. enable/disable toggles). */
14
+ fixedArgs?: Record<string, unknown>;
15
+ /** Reshape validated input into backend args (e.g. update-many -> batch ops). */
16
+ transformArgs?: (input: Record<string, unknown>) => Record<string, unknown>;
17
+ };
18
+
19
+ export type GatewayOperation = {
20
+ kind: "gateway";
21
+ method: "GET" | "POST" | "DELETE";
22
+ path: string;
23
+ auth: "bearer";
24
+ };
25
+
26
+ export type CustomOperation = {
27
+ kind: "custom";
28
+ handler:
29
+ | "commandsList"
30
+ | "chatSpawn"
31
+ | "chatFollow"
32
+ | "cronRunNow"
33
+ | "billingTopup"
34
+ | "upgrade"
35
+ | "filesMove"
36
+ | "filesStage"
37
+ | "signinOtpStart"
38
+ | "signinOtpVerify"
39
+ | "signinOtpFinalize";
40
+ auth: ApiAuthMode;
41
+ };
42
+
43
+ export type LocalOnlyOperation = {
44
+ kind: "local";
45
+ reason: string;
46
+ };
47
+
48
+ export type ApiOperationBackend =
49
+ | ConvexOperation
50
+ | GatewayOperation
51
+ | CustomOperation
52
+ | LocalOnlyOperation;
53
+
54
+ export type ApiOperation = {
55
+ id: string;
56
+ group: string;
57
+ summary: string;
58
+ cli: string;
59
+ aliases?: string[];
60
+ method: "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
61
+ path: string;
62
+ requestSchema: ZodTypeAny;
63
+ responseSchema: ZodTypeAny;
64
+ backend: ApiOperationBackend;
65
+ deprecated?: boolean;
66
+ };
67
+
68
+ /** Accepts any JSON body (for POST/PATCH endpoints not yet strictly typed). */
69
+ const anyObject = z.object({}).passthrough();
70
+ const anyResponse = z.unknown();
71
+ /** Placeholder for GET/DELETE endpoints that expect no request body. */
72
+ const noBody = z.object({}).passthrough();
73
+
74
+ function op(operation: ApiOperation): ApiOperation {
75
+ return operation;
76
+ }
77
+
78
+ function convex(
79
+ functionType: ConvexOperation["functionType"],
80
+ functionName: string,
81
+ auth: ApiAuthMode = "bearer",
82
+ options: Pick<ConvexOperation, "tokenArg" | "includeRunId"> = {},
83
+ ): ConvexOperation {
84
+ return {
85
+ kind: "convex",
86
+ functionType,
87
+ functionName,
88
+ auth,
89
+ tokenArg:
90
+ options.tokenArg ?? (auth === "bearer" ? "sessionToken" : undefined),
91
+ includeRunId: options.includeRunId,
92
+ };
93
+ }
94
+
95
+ function gateway(
96
+ method: GatewayOperation["method"],
97
+ path: string,
98
+ ): GatewayOperation {
99
+ return { kind: "gateway", method, path, auth: "bearer" };
100
+ }
101
+
102
+ function custom(
103
+ handler: CustomOperation["handler"],
104
+ auth: ApiAuthMode,
105
+ ): CustomOperation {
106
+ return { kind: "custom", handler, auth };
107
+ }
108
+
109
+ function local(reason: string): LocalOnlyOperation {
110
+ return { kind: "local", reason };
111
+ }
112
+
113
+ const rawApiOperations = [
114
+ op({
115
+ id: "commands.list",
116
+ group: "meta",
117
+ summary: "List all CLI/API operations and parity classifications.",
118
+ cli: "dench help",
119
+ method: "GET",
120
+ path: "/commands",
121
+ requestSchema: noBody,
122
+ responseSchema: anyResponse,
123
+ backend: { kind: "custom", handler: "commandsList", auth: "none" },
124
+ }),
125
+
126
+ // Auth and local session management.
127
+ op({
128
+ id: "auth.signin.create",
129
+ group: "auth",
130
+ summary: "Create an agent sign-in request.",
131
+ cli: "dench signin",
132
+ method: "POST",
133
+ path: "/auth/signin-requests",
134
+ requestSchema: anyObject,
135
+ responseSchema: anyResponse,
136
+ backend: convex(
137
+ "mutation",
138
+ "functions/agentWorkspace:createSignInRequest",
139
+ "none",
140
+ ),
141
+ }),
142
+ op({
143
+ id: "auth.signin.poll",
144
+ group: "auth",
145
+ summary: "Poll an agent sign-in request until approval.",
146
+ cli: "dench signin",
147
+ method: "POST",
148
+ path: "/auth/signin-requests/{requestId}/poll",
149
+ requestSchema: anyObject,
150
+ responseSchema: anyResponse,
151
+ backend: convex(
152
+ "mutation",
153
+ "functions/agentWorkspace:pollSignInRequest",
154
+ "none",
155
+ ),
156
+ }),
157
+ op({
158
+ id: "auth.otp.start",
159
+ group: "auth",
160
+ summary: "Start the email OTP sign-in flow.",
161
+ cli: "dench signin --email",
162
+ method: "POST",
163
+ path: "/auth/otp/start",
164
+ requestSchema: anyObject,
165
+ responseSchema: anyResponse,
166
+ backend: custom("signinOtpStart", "none"),
167
+ }),
168
+ op({
169
+ id: "auth.otp.verify",
170
+ group: "auth",
171
+ summary: "Verify an email OTP sign-in code.",
172
+ cli: "dench signin --email",
173
+ method: "POST",
174
+ path: "/auth/otp/verify",
175
+ requestSchema: anyObject,
176
+ responseSchema: anyResponse,
177
+ backend: custom("signinOtpVerify", "none"),
178
+ }),
179
+ op({
180
+ id: "auth.otp.finalize",
181
+ group: "auth",
182
+ summary: "Finalize an email OTP sign-in session.",
183
+ cli: "dench signin --email",
184
+ method: "POST",
185
+ path: "/auth/otp/finalize",
186
+ requestSchema: anyObject,
187
+ responseSchema: anyResponse,
188
+ backend: custom("signinOtpFinalize", "none"),
189
+ }),
190
+ op({
191
+ id: "sessions.local.list",
192
+ group: "local",
193
+ summary: "List local CLI sessions.",
194
+ cli: "dench sessions",
195
+ method: "GET",
196
+ path: "/local/sessions",
197
+ requestSchema: noBody,
198
+ responseSchema: anyResponse,
199
+ backend: local("CLI sessions live in the caller's ~/.dench/config.json."),
200
+ }),
201
+ op({
202
+ id: "sessions.local.use",
203
+ group: "local",
204
+ summary: "Select a local CLI session.",
205
+ cli: "dench use <session-key-or-workspace-slug>",
206
+ method: "POST",
207
+ path: "/local/sessions/use",
208
+ requestSchema: anyObject,
209
+ responseSchema: anyResponse,
210
+ backend: local("The server cannot mutate the caller's local CLI config."),
211
+ }),
212
+ op({
213
+ id: "sessions.local.logout",
214
+ group: "local",
215
+ summary: "Remove local CLI sessions.",
216
+ cli: "dench logout",
217
+ method: "POST",
218
+ path: "/local/logout",
219
+ requestSchema: anyObject,
220
+ responseSchema: anyResponse,
221
+ backend: local("The server cannot mutate the caller's local CLI config."),
222
+ }),
223
+ op({
224
+ id: "backend.local.configure",
225
+ group: "local",
226
+ summary: "Configure the CLI backend target.",
227
+ cli: "dench backend show|set|clear",
228
+ method: "POST",
229
+ path: "/local/backend",
230
+ requestSchema: anyObject,
231
+ responseSchema: anyResponse,
232
+ backend: local("Backend selection is local CLI state."),
233
+ }),
234
+
235
+ // Workspace orientation.
236
+ op({
237
+ id: "workspace.context",
238
+ group: "workspace",
239
+ summary: "Return the current Dench workspace context for the bearer.",
240
+ cli: "dench context",
241
+ method: "GET",
242
+ path: "/context",
243
+ requestSchema: noBody,
244
+ responseSchema: anyResponse,
245
+ backend: convex("query", "functions/agentWorkspace:whatCanIDoHere"),
246
+ }),
247
+ op({
248
+ id: "workspace.status",
249
+ group: "workspace",
250
+ summary: "Return workspace and agent status.",
251
+ cli: "dench status",
252
+ method: "GET",
253
+ path: "/status",
254
+ requestSchema: noBody,
255
+ responseSchema: anyResponse,
256
+ backend: convex("query", "functions/agentWorkspace:whatCanIDoHere"),
257
+ }),
258
+ op({
259
+ id: "workspace.agents",
260
+ group: "workspace",
261
+ summary: "List agents visible in the workspace status payload.",
262
+ cli: "dench agents",
263
+ method: "GET",
264
+ path: "/agents",
265
+ requestSchema: noBody,
266
+ responseSchema: anyResponse,
267
+ backend: convex("query", "functions/agentWorkspace:whatCanIDoHere"),
268
+ }),
269
+ op({
270
+ id: "workspace.approvals.list",
271
+ group: "approvals",
272
+ summary: "List approval requests visible in the workspace status payload.",
273
+ cli: "dench approvals",
274
+ method: "GET",
275
+ path: "/approvals",
276
+ requestSchema: noBody,
277
+ responseSchema: anyResponse,
278
+ backend: convex("query", "functions/agentWorkspace:whatCanIDoHere"),
279
+ }),
280
+ op({
281
+ id: "workspace.artifacts.list",
282
+ group: "workspace",
283
+ summary: "List artifacts for the authenticated workspace.",
284
+ cli: "dench artifacts",
285
+ method: "GET",
286
+ path: "/artifacts",
287
+ requestSchema: noBody,
288
+ responseSchema: anyResponse,
289
+ backend: convex("query", "functions/agentWorkspace:agentListArtifacts"),
290
+ }),
291
+ op({
292
+ id: "workspace.suggestedWork.list",
293
+ group: "workspace",
294
+ summary: "List draft suggested-work artifacts.",
295
+ cli: "dench suggested-work",
296
+ method: "GET",
297
+ path: "/suggested-work",
298
+ requestSchema: noBody,
299
+ responseSchema: anyResponse,
300
+ backend: convex("query", "functions/agentWorkspace:agentListArtifacts"),
301
+ }),
302
+
303
+ // Memory and approvals.
304
+ op({
305
+ id: "memory.search",
306
+ group: "memory",
307
+ summary: "Search durable workspace memory.",
308
+ cli: "dench memory search",
309
+ method: "GET",
310
+ path: "/memory/search",
311
+ requestSchema: z
312
+ .object({ query: z.string(), limit: z.coerce.number().optional() })
313
+ .passthrough(),
314
+ responseSchema: anyResponse,
315
+ backend: convex("query", "functions/agentWorkspace:agentSearchMemory"),
316
+ }),
317
+ op({
318
+ id: "memory.save",
319
+ group: "memory",
320
+ summary: "Save a durable workspace memory fact.",
321
+ cli: "dench memory save",
322
+ method: "POST",
323
+ path: "/memory",
324
+ requestSchema: anyObject,
325
+ responseSchema: anyResponse,
326
+ backend: convex("mutation", "functions/agentWorkspace:agentSaveMemory"),
327
+ }),
328
+ op({
329
+ id: "approval.request",
330
+ group: "approvals",
331
+ summary: "Request human approval.",
332
+ cli: "dench approval request",
333
+ method: "POST",
334
+ path: "/approvals",
335
+ requestSchema: anyObject,
336
+ responseSchema: anyResponse,
337
+ backend: convex(
338
+ "mutation",
339
+ "functions/agentWorkspace:agentRequestApproval",
340
+ ),
341
+ }),
342
+ op({
343
+ id: "approval.decide",
344
+ group: "approvals",
345
+ summary: "Record an approval decision.",
346
+ cli: "dench approval approve|reject",
347
+ method: "POST",
348
+ path: "/approvals/{approvalId}/decision",
349
+ requestSchema: anyObject,
350
+ responseSchema: anyResponse,
351
+ backend: convex("mutation", "functions/agentWorkspace:agentDecideApproval"),
352
+ }),
353
+
354
+ // Billing.
355
+ op({
356
+ id: "billing.status",
357
+ group: "billing",
358
+ summary: "Get billing and AI credit status.",
359
+ cli: "dench billing status",
360
+ method: "GET",
361
+ path: "/billing/status",
362
+ requestSchema: noBody,
363
+ responseSchema: anyResponse,
364
+ backend: convex("query", "functions/agentWorkspace:getAgentBillingStatus"),
365
+ }),
366
+ op({
367
+ id: "billing.topup",
368
+ group: "billing",
369
+ summary: "Create an AI credit top-up checkout link.",
370
+ cli: "dench billing topup",
371
+ method: "POST",
372
+ path: "/billing/topup",
373
+ requestSchema: anyObject,
374
+ responseSchema: anyResponse,
375
+ backend: custom("billingTopup", "bearer"),
376
+ }),
377
+ op({
378
+ id: "billing.upgrade",
379
+ group: "billing",
380
+ summary: "Create a workspace upgrade checkout link.",
381
+ cli: "dench upgrade",
382
+ method: "POST",
383
+ path: "/billing/upgrade",
384
+ requestSchema: anyObject,
385
+ responseSchema: anyResponse,
386
+ backend: custom("upgrade", "bearer"),
387
+ }),
388
+
389
+ // Chat and agent aliases.
390
+ op({
391
+ id: "chat.list",
392
+ group: "chat",
393
+ summary: "List past chat threads.",
394
+ cli: "dench chat list",
395
+ method: "GET",
396
+ path: "/chat/threads",
397
+ requestSchema: noBody,
398
+ responseSchema: anyResponse,
399
+ backend: convex("query", "functions/chat:listPastChats", "bearer", {
400
+ includeRunId: true,
401
+ }),
402
+ }),
403
+ op({
404
+ id: "chat.search",
405
+ group: "chat",
406
+ summary: "Search past chat messages.",
407
+ cli: "dench chat search",
408
+ method: "GET",
409
+ path: "/chat/search",
410
+ requestSchema: anyObject,
411
+ responseSchema: anyResponse,
412
+ backend: convex("query", "functions/chat:searchPastChats", "bearer", {
413
+ includeRunId: true,
414
+ }),
415
+ }),
416
+ op({
417
+ id: "chat.read",
418
+ group: "chat",
419
+ summary: "Read a past chat thread.",
420
+ cli: "dench chat read",
421
+ method: "GET",
422
+ path: "/chat/threads/{threadId}",
423
+ requestSchema: noBody,
424
+ responseSchema: anyResponse,
425
+ backend: convex("query", "functions/chat:readPastChat", "bearer", {
426
+ includeRunId: true,
427
+ }),
428
+ }),
429
+ op({
430
+ id: "chat.tree",
431
+ group: "chat",
432
+ summary: "Read the parent-child chat thread hierarchy.",
433
+ cli: "dench chat tree",
434
+ method: "GET",
435
+ path: "/chat/tree",
436
+ requestSchema: noBody,
437
+ responseSchema: anyResponse,
438
+ backend: convex("query", "functions/chat:listPastChats", "bearer", {
439
+ includeRunId: true,
440
+ }),
441
+ }),
442
+ op({
443
+ id: "chat.rename",
444
+ group: "chat",
445
+ summary: "Rename one or more chat threads.",
446
+ cli: "dench chat rename",
447
+ method: "PATCH",
448
+ path: "/chat/threads",
449
+ requestSchema: anyObject,
450
+ responseSchema: anyResponse,
451
+ backend: convex("mutation", "functions/chat:renameThreads", "bearer", {
452
+ includeRunId: true,
453
+ }),
454
+ }),
455
+ op({
456
+ id: "chat.delete",
457
+ group: "chat",
458
+ summary: "Delete one or more chat threads.",
459
+ cli: "dench chat delete",
460
+ method: "DELETE",
461
+ path: "/chat/threads",
462
+ requestSchema: anyObject,
463
+ responseSchema: anyResponse,
464
+ backend: convex("mutation", "functions/chat:deleteThreads", "bearer", {
465
+ includeRunId: true,
466
+ }),
467
+ }),
468
+ op({
469
+ id: "chat.new",
470
+ group: "chat",
471
+ summary: "Start a new chat-turn workflow.",
472
+ cli: "dench chat new",
473
+ aliases: ["dench agent new"],
474
+ method: "POST",
475
+ path: "/chat/threads",
476
+ requestSchema: anyObject,
477
+ responseSchema: anyResponse,
478
+ backend: custom("chatSpawn", "bearer"),
479
+ }),
480
+ op({
481
+ id: "chat.send",
482
+ group: "chat",
483
+ summary: "Send a message to an existing chat thread.",
484
+ cli: "dench chat send",
485
+ aliases: ["dench agent send"],
486
+ method: "POST",
487
+ path: "/chat/threads/{threadId}/messages",
488
+ requestSchema: anyObject,
489
+ responseSchema: anyResponse,
490
+ backend: custom("chatSpawn", "bearer"),
491
+ }),
492
+ op({
493
+ id: "chat.follow",
494
+ group: "chat",
495
+ summary: "Follow a live chat response stream.",
496
+ cli: "dench chat follow",
497
+ aliases: ["dench agent follow"],
498
+ method: "GET",
499
+ path: "/chat/threads/{threadId}/stream",
500
+ requestSchema: noBody,
501
+ responseSchema: anyResponse,
502
+ backend: custom("chatFollow", "bearer"),
503
+ }),
504
+
505
+ // CRM core.
506
+ op({
507
+ id: "crm.objects.list",
508
+ group: "crm",
509
+ summary: "List CRM objects.",
510
+ cli: "dench crm objects list",
511
+ method: "GET",
512
+ path: "/crm/objects",
513
+ requestSchema: noBody,
514
+ responseSchema: anyResponse,
515
+ backend: convex("query", "functions/crm/objects:list"),
516
+ }),
517
+ op({
518
+ id: "crm.objects.get",
519
+ group: "crm",
520
+ summary: "Get a CRM object.",
521
+ cli: "dench crm objects get",
522
+ method: "GET",
523
+ path: "/crm/objects/{name}",
524
+ requestSchema: noBody,
525
+ responseSchema: anyResponse,
526
+ backend: convex("query", "functions/crm/objects:get"),
527
+ }),
528
+ op({
529
+ id: "crm.objects.create",
530
+ group: "crm",
531
+ summary: "Create a CRM object.",
532
+ cli: "dench crm objects create",
533
+ method: "POST",
534
+ path: "/crm/objects",
535
+ requestSchema: anyObject,
536
+ responseSchema: anyResponse,
537
+ backend: convex("mutation", "functions/crm/objects:create"),
538
+ }),
539
+ op({
540
+ id: "crm.objects.update",
541
+ group: "crm",
542
+ summary: "Update a CRM object.",
543
+ cli: "dench crm objects update",
544
+ method: "PATCH",
545
+ path: "/crm/objects/{name}",
546
+ requestSchema: anyObject,
547
+ responseSchema: anyResponse,
548
+ backend: convex("mutation", "functions/crm/objects:update"),
549
+ }),
550
+ op({
551
+ id: "crm.objects.rename",
552
+ group: "crm",
553
+ summary: "Rename a CRM object.",
554
+ cli: "dench crm objects rename",
555
+ method: "POST",
556
+ path: "/crm/objects/{from}/rename",
557
+ requestSchema: anyObject,
558
+ responseSchema: anyResponse,
559
+ backend: convex("mutation", "functions/crm/objects:rename"),
560
+ }),
561
+ op({
562
+ id: "crm.objects.delete",
563
+ group: "crm",
564
+ summary: "Delete a CRM object.",
565
+ cli: "dench crm objects delete",
566
+ method: "DELETE",
567
+ path: "/crm/objects/{name}",
568
+ requestSchema: anyObject,
569
+ responseSchema: anyResponse,
570
+ backend: convex("mutation", "functions/crm/objects:remove"),
571
+ }),
572
+
573
+ op({
574
+ id: "crm.fields.list",
575
+ group: "crm",
576
+ summary: "List fields for a CRM object.",
577
+ cli: "dench crm fields list",
578
+ method: "GET",
579
+ path: "/crm/objects/{objectName}/fields",
580
+ requestSchema: noBody,
581
+ responseSchema: anyResponse,
582
+ backend: convex("query", "functions/crm/fields:list"),
583
+ }),
584
+ op({
585
+ id: "crm.fields.create",
586
+ group: "crm",
587
+ summary: "Create a CRM field.",
588
+ cli: "dench crm fields create",
589
+ method: "POST",
590
+ path: "/crm/objects/{objectName}/fields",
591
+ requestSchema: anyObject,
592
+ responseSchema: anyResponse,
593
+ backend: convex("mutation", "functions/crm/fields:create"),
594
+ }),
595
+ op({
596
+ id: "crm.fields.update",
597
+ group: "crm",
598
+ summary: "Update a CRM field.",
599
+ cli: "dench crm fields update",
600
+ method: "PATCH",
601
+ path: "/crm/objects/{objectName}/fields/{fieldName}",
602
+ requestSchema: anyObject,
603
+ responseSchema: anyResponse,
604
+ backend: convex("mutation", "functions/crm/fields:update"),
605
+ }),
606
+ op({
607
+ id: "crm.fields.delete",
608
+ group: "crm",
609
+ summary: "Delete a CRM field.",
610
+ cli: "dench crm fields delete",
611
+ method: "DELETE",
612
+ path: "/crm/objects/{objectName}/fields/{fieldName}",
613
+ requestSchema: anyObject,
614
+ responseSchema: anyResponse,
615
+ backend: convex("mutation", "functions/crm/fields:remove"),
616
+ }),
617
+ op({
618
+ id: "crm.fields.reorder",
619
+ group: "crm",
620
+ summary: "Reorder CRM fields.",
621
+ cli: "dench crm fields reorder",
622
+ method: "POST",
623
+ path: "/crm/objects/{objectName}/fields/reorder",
624
+ requestSchema: anyObject,
625
+ responseSchema: anyResponse,
626
+ backend: convex("mutation", "functions/crm/fields:reorder"),
627
+ }),
628
+ op({
629
+ id: "crm.fields.enum.reorder",
630
+ group: "crm",
631
+ summary: "Reorder enum values.",
632
+ cli: "dench crm fields enum-reorder",
633
+ method: "POST",
634
+ path: "/crm/objects/{objectName}/fields/{fieldName}/enum/reorder",
635
+ requestSchema: anyObject,
636
+ responseSchema: anyResponse,
637
+ backend: convex("mutation", "functions/crm/fields:reorderEnumValues"),
638
+ }),
639
+ op({
640
+ id: "crm.fields.enum.add",
641
+ group: "crm",
642
+ summary: "Add an enum value.",
643
+ cli: "dench crm fields enum-add",
644
+ method: "POST",
645
+ path: "/crm/objects/{objectName}/fields/{fieldName}/enum",
646
+ requestSchema: anyObject,
647
+ responseSchema: anyResponse,
648
+ backend: convex("mutation", "functions/crm/fields:addEnumValue"),
649
+ }),
650
+ op({
651
+ id: "crm.fields.enum.remove",
652
+ group: "crm",
653
+ summary: "Remove an enum value.",
654
+ cli: "dench crm fields enum-remove",
655
+ method: "DELETE",
656
+ path: "/crm/objects/{objectName}/fields/{fieldName}/enum/{value}",
657
+ requestSchema: anyObject,
658
+ responseSchema: anyResponse,
659
+ backend: convex("mutation", "functions/crm/fields:removeEnumValue"),
660
+ }),
661
+ op({
662
+ id: "crm.fields.enum.rename",
663
+ group: "crm",
664
+ summary: "Rename an enum value.",
665
+ cli: "dench crm fields enum-rename",
666
+ method: "POST",
667
+ path: "/crm/objects/{objectName}/fields/{fieldName}/enum/{oldValue}/rename",
668
+ requestSchema: anyObject,
669
+ responseSchema: anyResponse,
670
+ backend: convex("mutation", "functions/crm/fields:renameEnumValue"),
671
+ }),
672
+ op({
673
+ id: "crm.fields.enum.color",
674
+ group: "crm",
675
+ summary: "Set an enum color.",
676
+ cli: "dench crm fields enum-set-color",
677
+ method: "POST",
678
+ path: "/crm/objects/{objectName}/fields/{fieldName}/enum/{value}/color",
679
+ requestSchema: anyObject,
680
+ responseSchema: anyResponse,
681
+ backend: convex("mutation", "functions/crm/fields:setEnumColor"),
682
+ }),
683
+
684
+ op({
685
+ id: "crm.entries.list",
686
+ group: "crm",
687
+ summary: "List CRM entries.",
688
+ cli: "dench crm entries list",
689
+ method: "GET",
690
+ path: "/crm/objects/{objectName}/entries",
691
+ requestSchema: noBody,
692
+ responseSchema: anyResponse,
693
+ backend: convex("query", "functions/crm/entries:list"),
694
+ }),
695
+ op({
696
+ id: "crm.entries.get",
697
+ group: "crm",
698
+ summary: "Get a CRM entry.",
699
+ cli: "dench crm entries get",
700
+ method: "GET",
701
+ path: "/crm/objects/{objectName}/entries/{entryId}",
702
+ requestSchema: noBody,
703
+ responseSchema: anyResponse,
704
+ backend: convex("query", "functions/crm/entries:get"),
705
+ }),
706
+ op({
707
+ id: "crm.entries.create",
708
+ group: "crm",
709
+ summary: "Create a CRM entry.",
710
+ cli: "dench crm entries create",
711
+ method: "POST",
712
+ path: "/crm/objects/{objectName}/entries",
713
+ requestSchema: anyObject,
714
+ responseSchema: anyResponse,
715
+ backend: convex("mutation", "functions/crm/entries:create"),
716
+ }),
717
+ op({
718
+ id: "crm.entries.createMany",
719
+ group: "crm",
720
+ summary: "Create many CRM entries.",
721
+ cli: "dench crm entries create-many",
722
+ method: "POST",
723
+ path: "/crm/objects/{objectName}/entries/batch",
724
+ requestSchema: anyObject,
725
+ responseSchema: anyResponse,
726
+ backend: convex("mutation", "functions/crm/entries:createMany"),
727
+ }),
728
+ op({
729
+ id: "crm.entries.update",
730
+ group: "crm",
731
+ summary: "Update a CRM entry.",
732
+ cli: "dench crm entries update",
733
+ method: "PATCH",
734
+ path: "/crm/objects/{objectName}/entries/{entryId}",
735
+ requestSchema: anyObject,
736
+ responseSchema: anyResponse,
737
+ backend: convex("mutation", "functions/crm/entries:update"),
738
+ }),
739
+ op({
740
+ id: "crm.entries.updateMany",
741
+ group: "crm",
742
+ summary: "Update many CRM entries.",
743
+ cli: "dench crm entries update-many",
744
+ method: "PATCH",
745
+ path: "/crm/objects/{objectName}/entries/batch",
746
+ requestSchema: anyObject,
747
+ responseSchema: anyResponse,
748
+ backend: convex("mutation", "functions/crm/batch:apply"),
749
+ }),
750
+ op({
751
+ id: "crm.entries.delete",
752
+ group: "crm",
753
+ summary: "Delete a CRM entry.",
754
+ cli: "dench crm entries delete",
755
+ method: "DELETE",
756
+ path: "/crm/objects/{objectName}/entries/{entryId}",
757
+ requestSchema: anyObject,
758
+ responseSchema: anyResponse,
759
+ backend: convex("mutation", "functions/crm/entries:remove"),
760
+ }),
761
+ op({
762
+ id: "crm.entries.bulkDelete",
763
+ group: "crm",
764
+ summary: "Bulk delete CRM entries.",
765
+ cli: "dench crm entries bulk-delete",
766
+ method: "POST",
767
+ path: "/crm/objects/{objectName}/entries/delete",
768
+ requestSchema: anyObject,
769
+ responseSchema: anyResponse,
770
+ backend: convex("mutation", "functions/crm/entries:bulkDelete"),
771
+ }),
772
+
773
+ op({
774
+ id: "crm.cells.get",
775
+ group: "crm",
776
+ summary: "Get a CRM cell value.",
777
+ cli: "dench crm cells get",
778
+ method: "GET",
779
+ path: "/crm/objects/{objectName}/entries/{entryId}/fields/{fieldName}",
780
+ requestSchema: noBody,
781
+ responseSchema: anyResponse,
782
+ backend: convex("query", "functions/crm/cells:get"),
783
+ }),
784
+ op({
785
+ id: "crm.cells.set",
786
+ group: "crm",
787
+ summary: "Set a CRM cell value.",
788
+ cli: "dench crm cells set",
789
+ method: "PUT",
790
+ path: "/crm/objects/{objectName}/entries/{entryId}/fields/{fieldName}",
791
+ requestSchema: anyObject,
792
+ responseSchema: anyResponse,
793
+ backend: convex("mutation", "functions/crm/cells:set"),
794
+ }),
795
+ op({
796
+ id: "crm.cells.setMany",
797
+ group: "crm",
798
+ summary: "Set many CRM cell values.",
799
+ cli: "dench crm cells set-many",
800
+ method: "POST",
801
+ path: "/crm/cells/batch",
802
+ requestSchema: anyObject,
803
+ responseSchema: anyResponse,
804
+ backend: convex("mutation", "functions/crm/cells:setMany"),
805
+ }),
806
+ op({
807
+ id: "crm.cells.append",
808
+ group: "crm",
809
+ summary: "Append to a CRM cell.",
810
+ cli: "dench crm cells append",
811
+ method: "POST",
812
+ path: "/crm/objects/{objectName}/entries/{entryId}/fields/{fieldName}/append",
813
+ requestSchema: anyObject,
814
+ responseSchema: anyResponse,
815
+ backend: convex("mutation", "functions/crm/cells:append"),
816
+ }),
817
+
818
+ op({
819
+ id: "crm.query",
820
+ group: "crm",
821
+ summary: "Query CRM entries.",
822
+ cli: "dench crm query",
823
+ method: "POST",
824
+ path: "/crm/query",
825
+ requestSchema: anyObject,
826
+ responseSchema: anyResponse,
827
+ backend: convex("query", "functions/crm/query:queryEntries"),
828
+ }),
829
+ op({
830
+ id: "crm.sql",
831
+ group: "crm",
832
+ summary: "Run CRM SQL-compatible query.",
833
+ cli: "dench crm sql",
834
+ method: "POST",
835
+ path: "/crm/sql",
836
+ requestSchema: anyObject,
837
+ responseSchema: anyResponse,
838
+ backend: convex("query", "functions/crm/query:queryEntries"),
839
+ }),
840
+ op({
841
+ id: "crm.aggregate",
842
+ group: "crm",
843
+ summary: "Aggregate CRM entries.",
844
+ cli: "dench crm aggregate",
845
+ method: "POST",
846
+ path: "/crm/aggregate",
847
+ requestSchema: anyObject,
848
+ responseSchema: anyResponse,
849
+ backend: convex("query", "functions/crm/query:aggregate"),
850
+ }),
851
+ op({
852
+ id: "crm.search",
853
+ group: "crm",
854
+ summary: "Search CRM entries.",
855
+ cli: "dench crm search",
856
+ method: "GET",
857
+ path: "/crm/search",
858
+ requestSchema: anyObject,
859
+ responseSchema: anyResponse,
860
+ backend: convex("query", "functions/crm/query:search"),
861
+ }),
862
+ op({
863
+ id: "crm.statuses.list",
864
+ group: "crm",
865
+ summary: "List CRM statuses.",
866
+ cli: "dench crm statuses list",
867
+ method: "GET",
868
+ path: "/crm/objects/{objectName}/statuses",
869
+ requestSchema: noBody,
870
+ responseSchema: anyResponse,
871
+ backend: convex("query", "functions/crm/statuses:list"),
872
+ }),
873
+ op({
874
+ id: "crm.statuses.set",
875
+ group: "crm",
876
+ summary: "Set CRM statuses.",
877
+ cli: "dench crm statuses set",
878
+ method: "PUT",
879
+ path: "/crm/objects/{objectName}/statuses",
880
+ requestSchema: anyObject,
881
+ responseSchema: anyResponse,
882
+ backend: convex("mutation", "functions/crm/statuses:upsertMany"),
883
+ }),
884
+ op({
885
+ id: "crm.batch",
886
+ group: "crm",
887
+ summary: "Apply a CRM batch.",
888
+ cli: "dench crm batch",
889
+ method: "POST",
890
+ path: "/crm/batch",
891
+ requestSchema: anyObject,
892
+ responseSchema: anyResponse,
893
+ backend: convex("mutation", "functions/crm/batch:apply"),
894
+ }),
895
+ op({
896
+ id: "crm.transaction.begin",
897
+ group: "crm",
898
+ summary: "Begin a CRM transaction.",
899
+ cli: "dench crm transaction begin",
900
+ method: "POST",
901
+ path: "/crm/transactions",
902
+ requestSchema: anyObject,
903
+ responseSchema: anyResponse,
904
+ backend: convex("mutation", "functions/crm/transaction:begin"),
905
+ }),
906
+ op({
907
+ id: "crm.transaction.add",
908
+ group: "crm",
909
+ summary: "Add an operation to a CRM transaction.",
910
+ cli: "dench crm transaction add",
911
+ method: "POST",
912
+ path: "/crm/transactions/{txnId}/operations",
913
+ requestSchema: anyObject,
914
+ responseSchema: anyResponse,
915
+ backend: convex("mutation", "functions/crm/transaction:addOp"),
916
+ }),
917
+ op({
918
+ id: "crm.transaction.commit",
919
+ group: "crm",
920
+ summary: "Commit a CRM transaction.",
921
+ cli: "dench crm transaction commit",
922
+ method: "POST",
923
+ path: "/crm/transactions/{txnId}/commit",
924
+ requestSchema: anyObject,
925
+ responseSchema: anyResponse,
926
+ backend: convex("mutation", "functions/crm/transaction:commit"),
927
+ }),
928
+ op({
929
+ id: "crm.transaction.abort",
930
+ group: "crm",
931
+ summary: "Abort a CRM transaction.",
932
+ cli: "dench crm transaction abort",
933
+ method: "POST",
934
+ path: "/crm/transactions/{txnId}/abort",
935
+ requestSchema: anyObject,
936
+ responseSchema: anyResponse,
937
+ backend: convex("mutation", "functions/crm/transaction:abort"),
938
+ }),
939
+ op({
940
+ id: "crm.transaction.inspect",
941
+ group: "crm",
942
+ summary: "Inspect a CRM transaction.",
943
+ cli: "dench crm transaction inspect",
944
+ method: "GET",
945
+ path: "/crm/transactions/{txnId}",
946
+ requestSchema: noBody,
947
+ responseSchema: anyResponse,
948
+ backend: convex("query", "functions/crm/transaction:inspect"),
949
+ }),
950
+ op({
951
+ id: "crm.docs.list",
952
+ group: "crm",
953
+ summary: "List CRM documents.",
954
+ cli: "dench crm docs list",
955
+ method: "GET",
956
+ path: "/crm/docs",
957
+ requestSchema: noBody,
958
+ responseSchema: anyResponse,
959
+ backend: convex("query", "functions/crm/documents:list"),
960
+ }),
961
+ op({
962
+ id: "crm.docs.create",
963
+ group: "crm",
964
+ summary: "Create a CRM document.",
965
+ cli: "dench crm docs create",
966
+ method: "POST",
967
+ path: "/crm/docs",
968
+ requestSchema: anyObject,
969
+ responseSchema: anyResponse,
970
+ backend: convex("mutation", "functions/crm/documents:create"),
971
+ }),
972
+ op({
973
+ id: "crm.docs.link",
974
+ group: "crm",
975
+ summary: "Link a CRM document.",
976
+ cli: "dench crm docs link",
977
+ method: "POST",
978
+ path: "/crm/docs/link",
979
+ requestSchema: anyObject,
980
+ responseSchema: anyResponse,
981
+ backend: convex("mutation", "functions/crm/documents:link"),
982
+ }),
983
+ op({
984
+ id: "crm.actions.list",
985
+ group: "crm",
986
+ summary: "List CRM actions.",
987
+ cli: "dench crm actions list",
988
+ method: "GET",
989
+ path: "/crm/actions",
990
+ requestSchema: noBody,
991
+ responseSchema: anyResponse,
992
+ backend: convex("query", "functions/crm/actions:list"),
993
+ }),
994
+ op({
995
+ id: "crm.actions.run",
996
+ group: "crm",
997
+ summary: "Start a CRM action run.",
998
+ cli: "dench crm actions run",
999
+ method: "POST",
1000
+ path: "/crm/actions/{actionId}/runs",
1001
+ requestSchema: anyObject,
1002
+ responseSchema: anyResponse,
1003
+ backend: convex("mutation", "functions/crm/actions:startActionRun"),
1004
+ }),
1005
+ op({
1006
+ id: "crm.members.list",
1007
+ group: "crm",
1008
+ summary: "List workspace members for CRM user fields.",
1009
+ cli: "dench members list",
1010
+ method: "GET",
1011
+ path: "/members",
1012
+ requestSchema: noBody,
1013
+ responseSchema: anyResponse,
1014
+ backend: convex("query", "functions/crm/members:list"),
1015
+ }),
1016
+ op({
1017
+ id: "crm.reports.generate",
1018
+ group: "crm",
1019
+ summary: "Generate a CRM report.",
1020
+ cli: "dench crm reports generate",
1021
+ method: "POST",
1022
+ path: "/crm/reports",
1023
+ requestSchema: anyObject,
1024
+ responseSchema: anyResponse,
1025
+ backend: convex("query", "functions/crm/reports:generate"),
1026
+ }),
1027
+ op({
1028
+ id: "crm.enrich.cell",
1029
+ group: "crm",
1030
+ summary: "Request enrichment for one CRM cell.",
1031
+ cli: "dench crm enrich cell",
1032
+ method: "POST",
1033
+ path: "/crm/enrich/cell",
1034
+ requestSchema: anyObject,
1035
+ responseSchema: anyResponse,
1036
+ backend: convex("mutation", "functions/crm/enrich:requestCellEnrichment"),
1037
+ }),
1038
+ op({
1039
+ id: "crm.enrich.object",
1040
+ group: "crm",
1041
+ summary: "Request enrichment for a CRM object.",
1042
+ cli: "dench crm enrich object",
1043
+ method: "POST",
1044
+ path: "/crm/enrich/object",
1045
+ requestSchema: anyObject,
1046
+ responseSchema: anyResponse,
1047
+ backend: convex("mutation", "functions/crm/enrich:requestObjectEnrichment"),
1048
+ }),
1049
+ op({
1050
+ id: "crm.people.search",
1051
+ group: "crm",
1052
+ summary: "Search for people through the enrichment gateway.",
1053
+ cli: "dench crm people search",
1054
+ method: "POST",
1055
+ path: "/crm/people/search",
1056
+ requestSchema: anyObject,
1057
+ responseSchema: anyResponse,
1058
+ backend: gateway("POST", "/enrichment/people/search"),
1059
+ }),
1060
+ op({
1061
+ id: "crm.companies.search",
1062
+ group: "crm",
1063
+ summary: "Search for companies through the enrichment gateway.",
1064
+ cli: "dench crm companies search",
1065
+ method: "POST",
1066
+ path: "/crm/companies/search",
1067
+ requestSchema: anyObject,
1068
+ responseSchema: anyResponse,
1069
+ backend: gateway("POST", "/enrichment/company/search"),
1070
+ }),
1071
+ op({
1072
+ id: "crm.import",
1073
+ group: "local",
1074
+ summary: "Import a local CSV into a CRM object.",
1075
+ cli: "dench crm import",
1076
+ method: "POST",
1077
+ path: "/local/crm/import",
1078
+ requestSchema: anyObject,
1079
+ responseSchema: anyResponse,
1080
+ backend: local(
1081
+ "Reads a CSV from the caller's local filesystem. Over the API, parse the CSV client-side and POST rows to /crm/objects/{objectName}/entries/batch.",
1082
+ ),
1083
+ }),
1084
+ op({
1085
+ id: "crm.export",
1086
+ group: "local",
1087
+ summary: "Export a CRM object to a local CSV.",
1088
+ cli: "dench crm export",
1089
+ method: "POST",
1090
+ path: "/local/crm/export",
1091
+ requestSchema: anyObject,
1092
+ responseSchema: anyResponse,
1093
+ backend: local(
1094
+ "Writes a CSV to the caller's local filesystem. Over the API, call POST /crm/query and format CSV client-side.",
1095
+ ),
1096
+ }),
1097
+
1098
+ // Managed email campaigns.
1099
+ op({
1100
+ id: "email.identity.verify",
1101
+ group: "email",
1102
+ summary: "Start Dench Emailing Service sender verification.",
1103
+ cli: "dench email identity verify",
1104
+ method: "POST",
1105
+ path: "/email/identities/verify",
1106
+ requestSchema: anyObject,
1107
+ responseSchema: anyResponse,
1108
+ backend: gateway("POST", "/email/identities/verify"),
1109
+ }),
1110
+ op({
1111
+ id: "email.identity.create",
1112
+ group: "email",
1113
+ summary: "Create a durable Dench email sending identity record.",
1114
+ cli: "dench email identity verify",
1115
+ method: "POST",
1116
+ path: "/email/sending-identities",
1117
+ requestSchema: anyObject,
1118
+ responseSchema: anyResponse,
1119
+ backend: convex("mutation", "functions/emailCampaigns:createIdentity"),
1120
+ }),
1121
+ op({
1122
+ id: "email.identity.refresh",
1123
+ group: "email",
1124
+ summary: "Refresh a Dench Emailing Service sender verification status.",
1125
+ cli: "dench email identity status --identity-id",
1126
+ method: "POST",
1127
+ path: "/email/sending-identities/{identityId}/status",
1128
+ requestSchema: anyObject,
1129
+ responseSchema: anyResponse,
1130
+ backend: convex(
1131
+ "action",
1132
+ "functions/emailCampaignsNode:refreshIdentityStatus",
1133
+ ),
1134
+ }),
1135
+ op({
1136
+ id: "email.identity.beginVerification",
1137
+ group: "email",
1138
+ summary:
1139
+ "Begin the full Dench sender verification flow for a sending identity.",
1140
+ cli: "dench email identity verify",
1141
+ method: "POST",
1142
+ path: "/email/sending-identities/{identityId}/verify",
1143
+ requestSchema: anyObject,
1144
+ responseSchema: anyResponse,
1145
+ backend: convex(
1146
+ "action",
1147
+ "functions/emailCampaignsNode:beginSenderVerification",
1148
+ ),
1149
+ }),
1150
+ op({
1151
+ id: "email.identity.status",
1152
+ group: "email",
1153
+ summary: "Read Dench Emailing Service sender verification status.",
1154
+ cli: "dench email identity status",
1155
+ method: "GET",
1156
+ path: "/email/identities/{identity}/status",
1157
+ requestSchema: anyObject,
1158
+ responseSchema: anyResponse,
1159
+ backend: gateway("GET", "/email/identities/{identity}/status"),
1160
+ }),
1161
+ op({
1162
+ id: "email.template.create",
1163
+ group: "email",
1164
+ summary: "Create a managed email campaign template.",
1165
+ cli: "dench email template create",
1166
+ method: "POST",
1167
+ path: "/email/templates",
1168
+ requestSchema: anyObject,
1169
+ responseSchema: anyResponse,
1170
+ backend: convex("mutation", "functions/emailCampaigns:createTemplate"),
1171
+ }),
1172
+ op({
1173
+ id: "email.template.preview",
1174
+ group: "email",
1175
+ summary: "Preview a managed email campaign template.",
1176
+ cli: "dench email template preview",
1177
+ method: "POST",
1178
+ path: "/email/templates/{templateId}/preview",
1179
+ requestSchema: anyObject,
1180
+ responseSchema: anyResponse,
1181
+ backend: convex("query", "functions/emailCampaigns:previewTemplate"),
1182
+ }),
1183
+ op({
1184
+ id: "email.campaign.create",
1185
+ group: "email",
1186
+ summary: "Create a managed email campaign draft.",
1187
+ cli: "dench email campaign create",
1188
+ method: "POST",
1189
+ path: "/email/campaigns",
1190
+ requestSchema: anyObject,
1191
+ responseSchema: anyResponse,
1192
+ backend: convex("mutation", "functions/emailCampaigns:createCampaign"),
1193
+ }),
1194
+ op({
1195
+ id: "email.campaign.get",
1196
+ group: "email",
1197
+ summary: "Read campaign status and counters.",
1198
+ cli: "dench email campaign status",
1199
+ method: "GET",
1200
+ path: "/email/campaigns/{campaignId}",
1201
+ requestSchema: anyObject,
1202
+ responseSchema: anyResponse,
1203
+ backend: convex("query", "functions/emailCampaigns:getCampaign"),
1204
+ }),
1205
+ op({
1206
+ id: "email.campaign.recipients.add",
1207
+ group: "email",
1208
+ summary: "Add recipients to a managed email campaign.",
1209
+ cli: "dench email campaign recipients add",
1210
+ method: "POST",
1211
+ path: "/email/campaigns/{campaignId}/recipients",
1212
+ requestSchema: anyObject,
1213
+ responseSchema: anyResponse,
1214
+ backend: convex("mutation", "functions/emailCampaigns:addRecipients"),
1215
+ }),
1216
+ op({
1217
+ id: "email.campaign.preview",
1218
+ group: "email",
1219
+ summary: "Preview rendered messages for a campaign sample.",
1220
+ cli: "dench email campaign preview",
1221
+ method: "POST",
1222
+ path: "/email/campaigns/{campaignId}/preview",
1223
+ requestSchema: anyObject,
1224
+ responseSchema: anyResponse,
1225
+ backend: convex("query", "functions/emailCampaigns:previewCampaign"),
1226
+ }),
1227
+ op({
1228
+ id: "email.campaign.submit",
1229
+ group: "email",
1230
+ summary: "Submit a campaign for approval or sending.",
1231
+ cli: "dench email campaign submit",
1232
+ method: "POST",
1233
+ path: "/email/campaigns/{campaignId}/submit",
1234
+ requestSchema: anyObject,
1235
+ responseSchema: anyResponse,
1236
+ backend: convex("mutation", "functions/emailCampaigns:submitCampaign"),
1237
+ }),
1238
+ op({
1239
+ id: "email.campaign.pause",
1240
+ group: "email",
1241
+ summary: "Pause a sending email campaign.",
1242
+ cli: "dench email campaign pause",
1243
+ method: "POST",
1244
+ path: "/email/campaigns/{campaignId}/pause",
1245
+ requestSchema: anyObject,
1246
+ responseSchema: anyResponse,
1247
+ backend: convex("mutation", "functions/emailCampaigns:pauseCampaign"),
1248
+ }),
1249
+ op({
1250
+ id: "email.campaign.resume",
1251
+ group: "email",
1252
+ summary: "Resume a paused email campaign.",
1253
+ cli: "dench email campaign resume",
1254
+ method: "POST",
1255
+ path: "/email/campaigns/{campaignId}/resume",
1256
+ requestSchema: anyObject,
1257
+ responseSchema: anyResponse,
1258
+ backend: convex("mutation", "functions/emailCampaigns:resumeCampaign"),
1259
+ }),
1260
+ op({
1261
+ id: "email.campaign.cancel",
1262
+ group: "email",
1263
+ summary: "Cancel an email campaign.",
1264
+ cli: "dench email campaign cancel",
1265
+ method: "POST",
1266
+ path: "/email/campaigns/{campaignId}/cancel",
1267
+ requestSchema: anyObject,
1268
+ responseSchema: anyResponse,
1269
+ backend: convex("mutation", "functions/emailCampaigns:cancelCampaign"),
1270
+ }),
1271
+
1272
+ // Routines.
1273
+ op({
1274
+ id: "cron.list",
1275
+ group: "routines",
1276
+ summary: "List routines.",
1277
+ cli: "dench cron list",
1278
+ aliases: ["dench routine list", "dench routines list"],
1279
+ method: "GET",
1280
+ path: "/routines",
1281
+ requestSchema: noBody,
1282
+ responseSchema: anyResponse,
1283
+ backend: convex("query", "functions/triggers:listCronJobs"),
1284
+ }),
1285
+ op({
1286
+ id: "cron.history",
1287
+ group: "routines",
1288
+ summary: "List routine run history.",
1289
+ cli: "dench cron history",
1290
+ method: "GET",
1291
+ path: "/routines/history",
1292
+ requestSchema: noBody,
1293
+ responseSchema: anyResponse,
1294
+ backend: convex("query", "functions/triggers:listOrgCronRunHistory"),
1295
+ }),
1296
+ op({
1297
+ id: "cron.get",
1298
+ group: "routines",
1299
+ summary: "Get a routine.",
1300
+ cli: "dench cron get",
1301
+ method: "GET",
1302
+ path: "/routines/{jobId}",
1303
+ requestSchema: noBody,
1304
+ responseSchema: anyResponse,
1305
+ backend: convex("query", "functions/triggers:getCronJob"),
1306
+ }),
1307
+ op({
1308
+ id: "cron.create",
1309
+ group: "routines",
1310
+ summary: "Create a routine.",
1311
+ cli: "dench cron create",
1312
+ method: "POST",
1313
+ path: "/routines",
1314
+ requestSchema: anyObject,
1315
+ responseSchema: anyResponse,
1316
+ backend: convex("mutation", "functions/triggers:createCronTrigger"),
1317
+ }),
1318
+ op({
1319
+ id: "cron.update",
1320
+ group: "routines",
1321
+ summary: "Update a routine.",
1322
+ cli: "dench cron update",
1323
+ method: "PATCH",
1324
+ path: "/routines/{jobId}",
1325
+ requestSchema: anyObject,
1326
+ responseSchema: anyResponse,
1327
+ backend: convex("mutation", "functions/triggers:updateCronTrigger"),
1328
+ }),
1329
+ op({
1330
+ id: "cron.delete",
1331
+ group: "routines",
1332
+ summary: "Delete a routine.",
1333
+ cli: "dench cron delete",
1334
+ method: "DELETE",
1335
+ path: "/routines/{jobId}",
1336
+ requestSchema: anyObject,
1337
+ responseSchema: anyResponse,
1338
+ backend: convex("mutation", "functions/triggers:deleteCronTrigger"),
1339
+ }),
1340
+ op({
1341
+ id: "cron.enable",
1342
+ group: "routines",
1343
+ summary: "Enable a routine.",
1344
+ cli: "dench cron enable",
1345
+ method: "POST",
1346
+ path: "/routines/{jobId}/enable",
1347
+ requestSchema: anyObject,
1348
+ responseSchema: anyResponse,
1349
+ backend: convex("mutation", "functions/triggers:setCronEnabled"),
1350
+ }),
1351
+ op({
1352
+ id: "cron.disable",
1353
+ group: "routines",
1354
+ summary: "Disable a routine.",
1355
+ cli: "dench cron disable",
1356
+ method: "POST",
1357
+ path: "/routines/{jobId}/disable",
1358
+ requestSchema: anyObject,
1359
+ responseSchema: anyResponse,
1360
+ backend: convex("mutation", "functions/triggers:setCronEnabled"),
1361
+ }),
1362
+ op({
1363
+ id: "cron.run",
1364
+ group: "routines",
1365
+ summary: "Run a routine now.",
1366
+ cli: "dench cron run",
1367
+ method: "POST",
1368
+ path: "/routines/{jobId}/run",
1369
+ requestSchema: anyObject,
1370
+ responseSchema: anyResponse,
1371
+ backend: custom("cronRunNow", "bearer"),
1372
+ }),
1373
+ op({
1374
+ id: "cron.runs",
1375
+ group: "routines",
1376
+ summary: "List runs for a routine.",
1377
+ cli: "dench cron runs",
1378
+ method: "GET",
1379
+ path: "/routines/{jobId}/runs",
1380
+ requestSchema: noBody,
1381
+ responseSchema: anyResponse,
1382
+ backend: convex("query", "functions/triggers:listCronRuns"),
1383
+ }),
1384
+
1385
+ // Files.
1386
+ op({
1387
+ id: "files.list",
1388
+ group: "files",
1389
+ summary: "List workspace files.",
1390
+ cli: "dench files ls",
1391
+ method: "GET",
1392
+ path: "/files",
1393
+ requestSchema: noBody,
1394
+ responseSchema: anyResponse,
1395
+ backend: convex("query", "functions/files:listTree", "bearer", {
1396
+ tokenArg: "apiKey",
1397
+ }),
1398
+ }),
1399
+ op({
1400
+ id: "files.downloadUrl",
1401
+ group: "files",
1402
+ summary: "Get a signed file download URL.",
1403
+ cli: "dench files ls",
1404
+ method: "GET",
1405
+ path: "/files/download-url",
1406
+ requestSchema: noBody,
1407
+ responseSchema: anyResponse,
1408
+ backend: convex(
1409
+ "action",
1410
+ "functions/files:getFileSignedDownloadUrl",
1411
+ "bearer",
1412
+ { tokenArg: "apiKey" },
1413
+ ),
1414
+ }),
1415
+ op({
1416
+ id: "files.delete",
1417
+ group: "files",
1418
+ summary: "Remove a workspace file or directory.",
1419
+ cli: "dench files rm",
1420
+ method: "DELETE",
1421
+ path: "/files",
1422
+ requestSchema: anyObject,
1423
+ responseSchema: anyResponse,
1424
+ backend: convex("mutation", "functions/files:deleteFile", "bearer", {
1425
+ tokenArg: "apiKey",
1426
+ }),
1427
+ }),
1428
+ op({
1429
+ id: "files.move",
1430
+ group: "files",
1431
+ summary: "Move a workspace file or directory.",
1432
+ cli: "dench files mv",
1433
+ method: "POST",
1434
+ path: "/files/move",
1435
+ requestSchema: anyObject,
1436
+ responseSchema: anyResponse,
1437
+ backend: custom("filesMove", "bearer"),
1438
+ }),
1439
+ op({
1440
+ id: "files.stage",
1441
+ group: "files",
1442
+ summary: "Stage uploaded content into the workspace.",
1443
+ cli: "dench stage",
1444
+ method: "POST",
1445
+ path: "/files/stage",
1446
+ requestSchema: anyObject,
1447
+ responseSchema: anyResponse,
1448
+ backend: custom("filesStage", "bearer"),
1449
+ }),
1450
+ op({
1451
+ id: "fs.daemon",
1452
+ group: "local",
1453
+ summary: "Run the local file sync daemon.",
1454
+ cli: "dench fs",
1455
+ method: "POST",
1456
+ path: "/local/fs",
1457
+ requestSchema: anyObject,
1458
+ responseSchema: anyResponse,
1459
+ backend: local(
1460
+ "The fs daemon watches the caller's local /workspace mount.",
1461
+ ),
1462
+ }),
1463
+
1464
+ // Gateway-backed commands.
1465
+ op({
1466
+ id: "search.web",
1467
+ group: "gateway",
1468
+ summary: "Search the web through the Dench gateway.",
1469
+ cli: "dench search",
1470
+ method: "POST",
1471
+ path: "/search",
1472
+ requestSchema: anyObject,
1473
+ responseSchema: anyResponse,
1474
+ backend: gateway("POST", "/search"),
1475
+ }),
1476
+ op({
1477
+ id: "search.contents",
1478
+ group: "gateway",
1479
+ summary: "Fetch page contents through the Dench gateway.",
1480
+ cli: "dench search contents",
1481
+ method: "POST",
1482
+ path: "/search/contents",
1483
+ requestSchema: anyObject,
1484
+ responseSchema: anyResponse,
1485
+ backend: gateway("POST", "/search/contents"),
1486
+ }),
1487
+ op({
1488
+ id: "search.answer",
1489
+ group: "gateway",
1490
+ summary: "Answer a question with web search.",
1491
+ cli: "dench search answer",
1492
+ method: "POST",
1493
+ path: "/search/answer",
1494
+ requestSchema: anyObject,
1495
+ responseSchema: anyResponse,
1496
+ backend: gateway("POST", "/search/answer"),
1497
+ }),
1498
+ op({
1499
+ id: "image.generate",
1500
+ group: "gateway",
1501
+ summary: "Generate an image through the Dench gateway.",
1502
+ cli: "dench image generate",
1503
+ method: "POST",
1504
+ path: "/images/generations",
1505
+ requestSchema: anyObject,
1506
+ responseSchema: anyResponse,
1507
+ backend: gateway("POST", "/images/generations"),
1508
+ }),
1509
+ op({
1510
+ id: "image.edit",
1511
+ group: "gateway",
1512
+ summary: "Edit an image through the Dench gateway.",
1513
+ cli: "dench image edit",
1514
+ method: "POST",
1515
+ path: "/images/edits",
1516
+ requestSchema: anyObject,
1517
+ responseSchema: anyResponse,
1518
+ backend: gateway("POST", "/images/edits"),
1519
+ }),
1520
+ op({
1521
+ id: "apps.list",
1522
+ group: "gateway",
1523
+ summary: "List connected apps.",
1524
+ cli: "dench apps",
1525
+ method: "GET",
1526
+ path: "/apps",
1527
+ requestSchema: noBody,
1528
+ responseSchema: anyResponse,
1529
+ backend: gateway("GET", "/composio/connections"),
1530
+ }),
1531
+ op({
1532
+ id: "tool.status",
1533
+ group: "gateway",
1534
+ summary: "List connected tool accounts.",
1535
+ cli: "dench tool status",
1536
+ method: "GET",
1537
+ path: "/tools/status",
1538
+ requestSchema: noBody,
1539
+ responseSchema: anyResponse,
1540
+ backend: gateway("GET", "/composio/connections"),
1541
+ }),
1542
+ op({
1543
+ id: "tool.connect",
1544
+ group: "gateway",
1545
+ summary: "Create a tool OAuth connection link.",
1546
+ cli: "dench tool connect",
1547
+ method: "POST",
1548
+ path: "/tools/connections",
1549
+ requestSchema: anyObject,
1550
+ responseSchema: anyResponse,
1551
+ backend: gateway("POST", "/composio/connect"),
1552
+ }),
1553
+ op({
1554
+ id: "tool.search",
1555
+ group: "gateway",
1556
+ summary: "Search for external tool actions.",
1557
+ cli: "dench tool search",
1558
+ method: "POST",
1559
+ path: "/tools/search",
1560
+ requestSchema: anyObject,
1561
+ responseSchema: anyResponse,
1562
+ backend: gateway("POST", "/composio/tool-router/search"),
1563
+ }),
1564
+ op({
1565
+ id: "tool.run",
1566
+ group: "gateway",
1567
+ summary: "Run an external tool action.",
1568
+ cli: "dench tool run",
1569
+ method: "POST",
1570
+ path: "/tools/run",
1571
+ requestSchema: anyObject,
1572
+ responseSchema: anyResponse,
1573
+ backend: gateway("POST", "/composio/tool-router/execute"),
1574
+ }),
1575
+ op({
1576
+ id: "tool.disconnect",
1577
+ group: "gateway",
1578
+ summary: "Disconnect an external tool account.",
1579
+ cli: "dench tool disconnect",
1580
+ method: "DELETE",
1581
+ path: "/tools/connections/{connectionId}",
1582
+ requestSchema: anyObject,
1583
+ responseSchema: anyResponse,
1584
+ backend: gateway("DELETE", "/composio/connections/{connectionId}"),
1585
+ }),
1586
+
1587
+ // Agent harness config.
1588
+ op({
1589
+ id: "agentConfig.identity.show",
1590
+ group: "agent-config",
1591
+ summary: "Read IDENTITY.md.",
1592
+ cli: "dench identity show",
1593
+ method: "GET",
1594
+ path: "/agent-config/identity",
1595
+ requestSchema: noBody,
1596
+ responseSchema: anyResponse,
1597
+ backend: convex("query", "functions/agentConfig:getAgentConfig"),
1598
+ }),
1599
+ op({
1600
+ id: "agentConfig.identity.edit",
1601
+ group: "agent-config",
1602
+ summary: "Update IDENTITY.md.",
1603
+ cli: "dench identity edit",
1604
+ method: "PUT",
1605
+ path: "/agent-config/identity",
1606
+ requestSchema: anyObject,
1607
+ responseSchema: anyResponse,
1608
+ backend: convex("mutation", "functions/agentConfig:updateIdentity"),
1609
+ }),
1610
+ op({
1611
+ id: "agentConfig.organisation.show",
1612
+ group: "agent-config",
1613
+ summary: "Read ORGANISATION.md.",
1614
+ cli: "dench organisation show",
1615
+ method: "GET",
1616
+ path: "/agent-config/organisation",
1617
+ requestSchema: noBody,
1618
+ responseSchema: anyResponse,
1619
+ backend: convex("query", "functions/agentConfig:getAgentConfig"),
1620
+ }),
1621
+ op({
1622
+ id: "agentConfig.organisation.edit",
1623
+ group: "agent-config",
1624
+ summary: "Update ORGANISATION.md.",
1625
+ cli: "dench organisation edit",
1626
+ method: "PUT",
1627
+ path: "/agent-config/organisation",
1628
+ requestSchema: anyObject,
1629
+ responseSchema: anyResponse,
1630
+ backend: convex("mutation", "functions/agentConfig:updateOrganisation"),
1631
+ }),
1632
+ op({
1633
+ id: "agentConfig.user.show",
1634
+ group: "agent-config",
1635
+ summary: "Read USER.md.",
1636
+ cli: "dench user show",
1637
+ method: "GET",
1638
+ path: "/agent-config/user",
1639
+ requestSchema: noBody,
1640
+ responseSchema: anyResponse,
1641
+ backend: convex("query", "functions/agentConfig:getAgentConfig"),
1642
+ }),
1643
+ op({
1644
+ id: "agentConfig.user.edit",
1645
+ group: "agent-config",
1646
+ summary: "Update USER.md.",
1647
+ cli: "dench user edit",
1648
+ method: "PUT",
1649
+ path: "/agent-config/user",
1650
+ requestSchema: anyObject,
1651
+ responseSchema: anyResponse,
1652
+ backend: convex("mutation", "functions/agentConfig:updateUserProfile"),
1653
+ }),
1654
+ op({
1655
+ id: "agentConfig.tools.show",
1656
+ group: "agent-config",
1657
+ summary: "Read tool notes.",
1658
+ cli: "dench tools show",
1659
+ method: "GET",
1660
+ path: "/agent-config/tools",
1661
+ requestSchema: noBody,
1662
+ responseSchema: anyResponse,
1663
+ backend: convex("query", "functions/agentConfig:getAgentConfig"),
1664
+ }),
1665
+ op({
1666
+ id: "agentConfig.tools.edit",
1667
+ group: "agent-config",
1668
+ summary: "Update tool notes.",
1669
+ cli: "dench tools notes-edit",
1670
+ method: "PUT",
1671
+ path: "/agent-config/tools",
1672
+ requestSchema: anyObject,
1673
+ responseSchema: anyResponse,
1674
+ backend: convex("mutation", "functions/agentConfig:updateToolsNotes"),
1675
+ }),
1676
+ op({
1677
+ id: "agentConfig.mem.show",
1678
+ group: "agent-config",
1679
+ summary: "Read aggregate memory.",
1680
+ cli: "dench mem show",
1681
+ method: "GET",
1682
+ path: "/agent-config/mem",
1683
+ requestSchema: noBody,
1684
+ responseSchema: anyResponse,
1685
+ backend: convex("query", "functions/agentConfig:getAgentConfig"),
1686
+ }),
1687
+ op({
1688
+ id: "agentConfig.mem.edit",
1689
+ group: "agent-config",
1690
+ summary: "Update aggregate memory.",
1691
+ cli: "dench mem set",
1692
+ method: "PUT",
1693
+ path: "/agent-config/mem",
1694
+ requestSchema: anyObject,
1695
+ responseSchema: anyResponse,
1696
+ backend: convex("mutation", "functions/agentConfig:updateMemory"),
1697
+ }),
1698
+ op({
1699
+ id: "agentConfig.bootstrap.show",
1700
+ group: "agent-config",
1701
+ summary: "Read bootstrap state.",
1702
+ cli: "dench bootstrap status",
1703
+ method: "GET",
1704
+ path: "/agent-config/bootstrap",
1705
+ requestSchema: noBody,
1706
+ responseSchema: anyResponse,
1707
+ backend: convex("query", "functions/agentConfig:getAgentConfig"),
1708
+ }),
1709
+ op({
1710
+ id: "agentConfig.bootstrap.complete",
1711
+ group: "agent-config",
1712
+ summary: "Complete bootstrap.",
1713
+ cli: "dench bootstrap complete",
1714
+ method: "POST",
1715
+ path: "/agent-config/bootstrap/complete",
1716
+ requestSchema: anyObject,
1717
+ responseSchema: anyResponse,
1718
+ backend: convex("mutation", "functions/agentConfig:completeBootstrap"),
1719
+ }),
1720
+ op({
1721
+ id: "agentConfig.bootstrap.template",
1722
+ group: "agent-config",
1723
+ summary: "Update bootstrap template.",
1724
+ cli: "dench bootstrap template",
1725
+ method: "PUT",
1726
+ path: "/agent-config/bootstrap/template",
1727
+ requestSchema: anyObject,
1728
+ responseSchema: anyResponse,
1729
+ backend: convex(
1730
+ "mutation",
1731
+ "functions/agentConfig:updateBootstrapTemplate",
1732
+ ),
1733
+ }),
1734
+ op({
1735
+ id: "agentConfig.model.default",
1736
+ group: "agent-config",
1737
+ summary: "Set the default chat model.",
1738
+ cli: "dench model default",
1739
+ method: "PUT",
1740
+ path: "/agent-config/model/default",
1741
+ requestSchema: anyObject,
1742
+ responseSchema: anyResponse,
1743
+ backend: convex("mutation", "functions/agentConfig:setDefaultChatModelV2"),
1744
+ }),
1745
+ op({
1746
+ id: "agentConfig.model.thread",
1747
+ group: "agent-config",
1748
+ summary: "Set a thread model override.",
1749
+ cli: "dench model thread",
1750
+ method: "PUT",
1751
+ path: "/agent-config/model/threads/{threadId}",
1752
+ requestSchema: anyObject,
1753
+ responseSchema: anyResponse,
1754
+ backend: convex("mutation", "functions/agentConfig:setThreadModelOverride"),
1755
+ }),
1756
+ op({
1757
+ id: "agentConfig.daily.today",
1758
+ group: "agent-config",
1759
+ summary: "Read today's daily activity path.",
1760
+ cli: "dench daily today",
1761
+ method: "GET",
1762
+ path: "/agent-config/daily/today",
1763
+ requestSchema: noBody,
1764
+ responseSchema: anyResponse,
1765
+ backend: convex("query", "functions/agentConfig:getAgentConfig"),
1766
+ }),
1767
+ op({
1768
+ id: "agentConfig.daily.show",
1769
+ group: "agent-config",
1770
+ summary: "Read a daily activity path.",
1771
+ cli: "dench daily show",
1772
+ method: "GET",
1773
+ path: "/agent-config/daily/{date}",
1774
+ requestSchema: noBody,
1775
+ responseSchema: anyResponse,
1776
+ backend: convex("query", "functions/agentConfig:getAgentConfig"),
1777
+ }),
1778
+ ] as const satisfies readonly ApiOperation[];
1779
+
1780
+ /**
1781
+ * Final operation list with deep schemas + backend extras injected from
1782
+ * `api-schemas.ts` by operation id. This keeps the literal above readable
1783
+ * while the parameter-level depth (every field, enum, schedule, etc.)
1784
+ * lives in one schema module shared by the dispatcher, OpenAPI generator,
1785
+ * and curl guide.
1786
+ */
1787
+ export const apiOperations: ApiOperation[] = rawApiOperations.map(
1788
+ (operation) => {
1789
+ const requestSchema =
1790
+ requestSchemas[operation.id] ?? operation.requestSchema;
1791
+ const responseSchema =
1792
+ responseSchemas[operation.id] ?? operation.responseSchema;
1793
+ let backend: ApiOperationBackend = operation.backend;
1794
+ if (backend.kind === "convex") {
1795
+ const extras = convexExtras[operation.id];
1796
+ if (extras) backend = { ...backend, ...extras };
1797
+ }
1798
+ return { ...operation, requestSchema, responseSchema, backend };
1799
+ },
1800
+ );
1801
+
1802
+ export function operationRequiresBearer(operation: ApiOperation): boolean {
1803
+ return (
1804
+ (operation.backend.kind === "convex" &&
1805
+ operation.backend.auth === "bearer") ||
1806
+ (operation.backend.kind === "custom" &&
1807
+ operation.backend.auth === "bearer") ||
1808
+ operation.backend.kind === "gateway"
1809
+ );
1810
+ }
1811
+
1812
+ export function publicApiOperations(): ApiOperation[] {
1813
+ return apiOperations.filter(
1814
+ (operation) => operation.backend.kind !== "local",
1815
+ );
1816
+ }