@dench.com/cli 3.5.6-staging.344 → 3.6.0-staging.356

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.
@@ -83,6 +83,23 @@ export type AppSdkScope = (typeof APP_SDK_SCOPES)[number];
83
83
 
84
84
  /** Every public /api/v1 operation reachable through dench.api.call. */
85
85
  export const APP_SDK_OPERATIONS: readonly AppSdkOperationInfo[] = [
86
+ {"id":"campaigns.drafts.create","group":"campaigns","summary":"Create an idempotent empty campaign draft with the caller's available sender pools. Does not launch or send.","cli":"dench campaign draft","method":"POST","path":"/campaigns/drafts","permission":"campaigns:write","pathParams":[]},
87
+ {"id":"campaigns.audience.search","group":"campaigns","summary":"Search people by filters without adding CRM records or campaign recipients. Search credits apply; this is not a free provider preview.","cli":"dench campaign search","method":"POST","path":"/campaigns/audience/search","permission":"campaigns:write","pathParams":[]},
88
+ {"id":"campaigns.people.addFromSearch","group":"campaigns","summary":"Search and add up to 50 people to an existing campaign. New identities become Leads. Search credits apply; use nextPageToken for another page.","cli":"dench campaign add --search","method":"POST","path":"/campaigns/{sequenceId}/people/search","permission":"campaigns:write","pathParams":["sequenceId"]},
89
+ {"id":"campaigns.people.addBatch","group":"campaigns","summary":"Add up to 50 selected recipients without another search. Deduplicates, applies suppression, and preserves the campaign's launch state.","cli":"dench campaign add --people-file","method":"POST","path":"/campaigns/{sequenceId}/people/batch","permission":"campaigns:write","pathParams":["sequenceId"]},
90
+ {"id":"campaigns.sources.get","group":"campaigns","summary":"Read a campaign's saved signal source, targeting and schedule.","cli":"dench campaign sources get","method":"GET","path":"/campaigns/{sequenceId}/sources","permission":"campaigns:read","pathParams":["sequenceId"]},
91
+ {"id":"campaigns.sources.signals","group":"campaigns","summary":"Read signal choices, suggested terms and current source configuration.","cli":"dench campaign sources signals","method":"GET","path":"/campaigns/{sequenceId}/sources/signals","permission":"campaigns:read","pathParams":["sequenceId"]},
92
+ {"id":"campaigns.sources.update","group":"campaigns","summary":"Update source cadence, pause/resume, targeting, signals or terms. Active sources may perform billable future work.","cli":"dench campaign sources set","method":"PATCH","path":"/campaigns/{sequenceId}/sources","permission":"campaigns:write","pathParams":["sequenceId"]},
93
+ {"id":"campaigns.sources.preview","group":"campaigns","summary":"Preview a signal source using its current audience. Provider credits may apply; does not enroll people.","cli":"dench campaign sources preview","method":"POST","path":"/campaigns/{sequenceId}/sources/preview","permission":"campaigns:write","pathParams":["sequenceId"]},
94
+ {"id":"campaigns.builder.profile","group":"campaigns","summary":"Read the company profile and suggested campaign audience.","cli":"dench campaign builder profile","method":"GET","path":"/campaigns/builder/profile","permission":"campaigns:read","pathParams":[]},
95
+ {"id":"campaigns.builder.save","group":"campaigns","summary":"Save a signal campaign's audience, signals and terms idempotently. Does not start a build.","cli":"dench campaign builder save","method":"POST","path":"/campaigns/builder/drafts","permission":"campaigns:write","pathParams":[]},
96
+ {"id":"campaigns.builder.get","group":"campaigns","summary":"Read signal build progress, preview people, messages and errors.","cli":"dench campaign builder get","method":"GET","path":"/campaigns/builder/drafts/{draftId}","permission":"campaigns:read","pathParams":["draftId"]},
97
+ {"id":"campaigns.builder.build","group":"campaigns","summary":"Start the same billable signal/audience/message build used by the UI; poll the draft for progress.","cli":"dench campaign builder build","method":"POST","path":"/campaigns/builder/drafts/{draftId}/build","permission":"campaigns:write","pathParams":["draftId"]},
98
+ {"id":"campaigns.builder.create","group":"campaigns","summary":"Create a campaign from a reviewed signal draft. Does not launch the campaign.","cli":"dench campaign builder create","method":"POST","path":"/campaigns/builder/drafts/{draftId}/create","permission":"campaigns:write","pathParams":["draftId"]},
99
+ {"id":"campaigns.builder.opener","group":"campaigns","summary":"Edit or reset one preview person's opening line before creating the campaign.","cli":"dench campaign builder opener","method":"PUT","path":"/campaigns/builder/drafts/{draftId}/people/{leadId}/opener","permission":"campaigns:write","pathParams":["draftId","leadId"]},
100
+ {"id":"campaigns.builder.autofill","group":"campaigns","summary":"Turn an audience description into targeting filters. AI credits apply.","cli":"dench campaign builder autofill","method":"POST","path":"/campaigns/builder/autofill","permission":"campaigns:write","pathParams":[]},
101
+ {"id":"campaigns.builder.terms","group":"campaigns","summary":"Suggest signal terms for the selected audience. AI credits apply.","cli":"dench campaign builder terms","method":"POST","path":"/campaigns/builder/terms","permission":"campaigns:write","pathParams":[]},
102
+ {"id":"campaigns.builder.estimate","group":"campaigns","summary":"Estimate audience or weekly signal volume using the UI's cached estimator. Provider credits may apply.","cli":"dench campaign builder estimate","method":"POST","path":"/campaigns/builder/estimate","permission":"campaigns:write","pathParams":[]},
86
103
  {"id":"commands.list","group":"meta","summary":"List all CLI/API operations and parity classifications.","cli":"dench help","method":"GET","path":"/commands","permission":null,"pathParams":[]},
87
104
  {"id":"auth.signin.create","group":"auth","summary":"Create an agent sign-in request.","cli":"dench signin","method":"POST","path":"/auth/signin-requests","permission":"auth:write","pathParams":[]},
88
105
  {"id":"auth.signin.poll","group":"auth","summary":"Poll an agent sign-in request until approval.","cli":"dench signin","method":"POST","path":"/auth/signin-requests/{requestId}/poll","permission":"auth:write","pathParams":["requestId"]},
@@ -330,23 +347,42 @@ export const APP_SDK_OPERATIONS: readonly AppSdkOperationInfo[] = [
330
347
  {"id":"email.sequence.enrollment.resume","group":"email","summary":"Resume one paused enrollment.","cli":"dench email sequence enrollment resume","method":"POST","path":"/email/sequences/enrollments/{enrollmentId}/resume","permission":"email:write","pathParams":["enrollmentId"]},
331
348
  {"id":"email.sequence.enrollment.stop","group":"email","summary":"Stop one enrollment (no further steps send).","cli":"dench email sequence enrollment stop","method":"POST","path":"/email/sequences/enrollments/{enrollmentId}/stop","permission":"email:write","pathParams":["enrollmentId"]},
332
349
  {"id":"campaigns.accounts.linkedin","group":"campaigns","summary":"Discover LinkedIn sender ids, labels, availability and remaining capacity visible to the acting workspace member. Never returns provider credentials.","cli":"dench campaign accounts","method":"GET","path":"/campaigns/accounts/linkedin","permission":"campaigns:read","pathParams":[]},
350
+ {"id":"campaigns.accounts.email","group":"campaigns","summary":"Discover the mailboxes the acting workspace member can send campaign email from: ids for emailMailboxAccountIds, status, warm-up state and when it is done, the daily cold-email cap and what is left today. Never returns provider credentials.","cli":"dench campaign accounts","method":"GET","path":"/campaigns/accounts/email","permission":"campaigns:read","pathParams":[]},
333
351
  {"id":"campaigns.list","group":"campaigns","summary":"List outreach campaigns (archived ones on request).","cli":"dench campaign list","method":"GET","path":"/campaigns","permission":"campaigns:read","pathParams":[]},
334
352
  {"id":"campaigns.create","group":"campaigns","summary":"Create a draft outreach campaign with email and LinkedIn sender pools and a business-hours send window in the given timezone.","cli":"dench campaign create","method":"POST","path":"/campaigns","permission":"campaigns:write","pathParams":[]},
353
+ {"id":"campaigns.duplicate","group":"campaigns","summary":"Copy a campaign into a new draft named \"<name> copy\": the same steps, schedule, sender pools and personalized lines, its lead source paused, and no people. To reach more than 300 people, duplicate and add the next page of the search to the copy.","cli":"dench campaign duplicate","method":"POST","path":"/campaigns/{sequenceId}/duplicate","permission":"campaigns:write","pathParams":["sequenceId"]},
335
354
  {"id":"campaigns.get","group":"campaigns","summary":"Read a campaign: settings, steps, people, their current step and hold, last touches, linked leads.","cli":"dench campaign get","method":"GET","path":"/campaigns/{sequenceId}","permission":"campaigns:read","pathParams":["sequenceId"]},
336
355
  {"id":"campaigns.analytics","group":"campaigns","summary":"Campaign funnel: enrolled, contacted, invited, accepted, messaged, replied, opens and clicks.","cli":"dench campaign get","method":"GET","path":"/campaigns/{sequenceId}/analytics","permission":"campaigns:read","pathParams":["sequenceId"]},
337
356
  {"id":"campaigns.live","group":"campaigns","summary":"What the campaign is doing now, what comes next and when, and why it is holding.","cli":"dench campaign get","method":"GET","path":"/campaigns/{sequenceId}/live","permission":"campaigns:read","pathParams":["sequenceId"]},
357
+ {"id":"campaigns.pipeline","group":"campaigns","summary":"Where a campaign's people sit in the workspace's lead pipeline right now: each lead Status in order with how many enrolled leads are at it, and how many have no lead or a status outside the pipeline.","cli":"dench campaign pipeline","method":"GET","path":"/campaigns/{sequenceId}/pipeline","permission":"campaigns:read","pathParams":["sequenceId"]},
338
358
  {"id":"campaigns.update","group":"campaigns","summary":"Change a campaign's name, sender pools, send windows, daily email cap, stop-on-reply, start or end. Works until archived; existing conversations keep their assigned sender.","cli":"dench campaign set","method":"PATCH","path":"/campaigns/{sequenceId}","permission":"campaigns:write","pathParams":["sequenceId"]},
339
- {"id":"campaigns.steps.replace","group":"campaigns","summary":"Replace every step of a draft campaign (email, wait, LinkedIn visit, connection request, message). Configure sender pools on the campaign; step sender ids are legacy-only.","cli":"dench campaign steps set","method":"PUT","path":"/campaigns/{sequenceId}/steps","permission":"campaigns:write","pathParams":["sequenceId"]},
359
+ {"id":"campaigns.steps.replace","group":"campaigns","summary":"Replace every step of a draft campaign (email, wait, LinkedIn visit, connection request, message, post reaction, InMail). Steps are checked first: a field the step type would drop, missing text or {TOKEN} single braces are rejected, not saved. Configure sender pools on the campaign; step sender ids are legacy-only.","cli":"dench campaign steps set","method":"PUT","path":"/campaigns/{sequenceId}/steps","permission":"campaigns:write","pathParams":["sequenceId"]},
360
+ {"id":"campaigns.steps.update","group":"campaigns","summary":"Edit the text, waits and conditions of a launched (or paused) campaign's steps in place. Each step keeps its id, type and place; pass the stepId and the updatedAt you read, and only the fields you change. Messages already sent or being prepared keep their text; drafts use campaigns.steps.replace.","cli":"dench campaign steps edit","method":"PATCH","path":"/campaigns/{sequenceId}/steps","permission":"campaigns:write","pathParams":["sequenceId"]},
361
+ {"id":"campaigns.personalization.get","group":"campaigns","summary":"Read a campaign's personalized lines (written for each person): their {{keys}} for steps, instructions and fallbacks, how many people have them, and the cost per person.","cli":"dench campaign personalize get","method":"GET","path":"/campaigns/{sequenceId}/personalization","permission":"campaigns:read","pathParams":["sequenceId"]},
362
+ {"id":"campaigns.personalization.set","group":"campaigns","summary":"Define up to 5 personalized lines (each used as {{key}} in steps) and what you sell. Saving starts writing missing lines for up to 100 people, about 3 cents a person; for more it returns needsConfirm and writes nothing until campaigns.personalization.write is confirmed.","cli":"dench campaign personalize set","method":"PUT","path":"/campaigns/{sequenceId}/personalization","permission":"campaigns:write","pathParams":["sequenceId"]},
363
+ {"id":"campaigns.personalization.clear","group":"campaigns","summary":"Turn off a campaign's personalized lines and cancel the ones not yet written. Refused while a step still uses one of the {{keys}}.","cli":"dench campaign personalize clear","method":"DELETE","path":"/campaigns/{sequenceId}/personalization","permission":"campaigns:write","pathParams":["sequenceId"]},
364
+ {"id":"campaigns.personalization.write","group":"campaigns","summary":"Write personalized lines for the people missing them (mode missing) or rewrite everyone's (mode all). Rewriting everyone or more than 100 people returns needsConfirm and the estimate until called with confirmed: true.","cli":"dench campaign personalize write","method":"POST","path":"/campaigns/{sequenceId}/personalization/write","permission":"campaigns:write","pathParams":["sequenceId"]},
365
+ {"id":"campaigns.personalization.edit","group":"campaigns","summary":"Set one person's personalized line by hand; an empty value undoes the edit. Braces are removed and text past the line's length is cut.","cli":"dench campaign personalize edit","method":"PUT","path":"/campaigns/people/{enrollmentId}/personalization","permission":"campaigns:write","pathParams":["enrollmentId"]},
366
+ {"id":"campaigns.personalization.rewrite","group":"campaigns","summary":"Write a fresh personalized line for one person: one key, or all of their lines when key is left out. About 3 cents.","cli":"dench campaign personalize rewrite","method":"POST","path":"/campaigns/people/{enrollmentId}/personalization/rewrite","permission":"campaigns:write","pathParams":["enrollmentId"]},
340
367
  {"id":"campaigns.people.addFromCrm","group":"campaigns","summary":"Add CRM records (up to 100 ids per call) to a campaign; returns how many were added and why others were skipped.","cli":"dench campaign add","method":"POST","path":"/campaigns/{sequenceId}/people","permission":"campaigns:write","pathParams":["sequenceId"]},
341
368
  {"id":"campaigns.people.add","group":"campaigns","summary":"Add one person by email and/or LinkedIn profile URL.","cli":"dench campaign add --name","method":"POST","path":"/campaigns/{sequenceId}/person","permission":"campaigns:write","pathParams":["sequenceId"]},
342
- {"id":"campaigns.launch.preview","group":"campaigns","summary":"Launch readiness: blockers grouped by problem, warnings, and the fingerprint `launch` requires.","cli":"dench campaign launch","method":"GET","path":"/campaigns/{sequenceId}/launch","permission":"campaigns:read","pathParams":["sequenceId"]},
369
+ {"id":"campaigns.preview","group":"campaigns","summary":"Show the message one person gets at one email or LinkedIn step, with their fields and personalized lines filled in: subject, body, sender, recipient, merge fields still missing, warnings, and why the step would be skipped. Nothing is sent, prepared or charged.","cli":"dench campaign preview","method":"GET","path":"/campaigns/{sequenceId}/preview","permission":"campaigns:read","pathParams":["sequenceId"]},
370
+ {"id":"campaigns.launch.preview","group":"campaigns","summary":"Launch readiness without launching: blockers grouped by problem, warnings, and the fingerprint `launch` requires.","cli":"dench campaign launch --check","method":"GET","path":"/campaigns/{sequenceId}/launch","permission":"campaigns:read","pathParams":["sequenceId"]},
343
371
  {"id":"campaigns.launch","group":"campaigns","summary":"Launch a ready draft. Pass the fingerprint from the preview and acknowledge the LinkedIn notice when LinkedIn steps exist.","cli":"dench campaign launch","method":"POST","path":"/campaigns/{sequenceId}/launch","permission":"campaigns:write","pathParams":["sequenceId"]},
344
372
  {"id":"campaigns.pause","group":"campaigns","summary":"Pause an active campaign.","cli":"dench campaign pause","method":"POST","path":"/campaigns/{sequenceId}/pause","permission":"campaigns:write","pathParams":["sequenceId"]},
345
373
  {"id":"campaigns.resume","group":"campaigns","summary":"Resume a paused campaign.","cli":"dench campaign resume","method":"POST","path":"/campaigns/{sequenceId}/resume","permission":"campaigns:write","pathParams":["sequenceId"]},
346
- {"id":"campaigns.archive","group":"campaigns","summary":"Archive a campaign and stop everyone still in flight.","cli":"dench campaign archive","method":"POST","path":"/campaigns/{sequenceId}/archive","permission":"campaigns:write","pathParams":["sequenceId"]},
374
+ {"id":"campaigns.archive","group":"campaigns","summary":"Archive a campaign and stop everyone still in flight. This is the app's Delete: campaigns are never erased, and their people, leads and activity stay.","cli":"dench campaign archive","method":"POST","path":"/campaigns/{sequenceId}/archive","permission":"campaigns:write","pathParams":["sequenceId"]},
347
375
  {"id":"campaigns.events","group":"campaigns","summary":"The campaign's activity log, newest first (sent, accepted, replied, skipped, failed, paused, stopped).","cli":"dench campaign events","method":"GET","path":"/campaigns/{sequenceId}/events","permission":"campaigns:read","pathParams":["sequenceId"]},
348
376
  {"id":"campaigns.people.stop","group":"campaigns","summary":"Stop one person: nothing more is sent to them from this campaign.","cli":"dench campaign stop","method":"POST","path":"/campaigns/people/{enrollmentId}/stop","permission":"campaigns:write","pathParams":["enrollmentId"]},
349
377
  {"id":"campaigns.people.resume","group":"campaigns","summary":"Resume one paused person in an active campaign.","cli":"dench campaign resume-person","method":"POST","path":"/campaigns/people/{enrollmentId}/resume","permission":"campaigns:write","pathParams":["enrollmentId"]},
378
+ {"id":"campaigns.people.setEmail","group":"campaigns","summary":"Give a person in a draft campaign a new or corrected email address; their linked CRM record gets it too. Only before launch; another person in the campaign can't share it.","cli":"dench campaign person set --email","method":"PUT","path":"/campaigns/people/{enrollmentId}/email","permission":"campaigns:write","pathParams":["enrollmentId"]},
379
+ {"id":"campaigns.people.setLinkedin","group":"campaigns","summary":"Give a person in a draft campaign a new or corrected LinkedIn profile URL; their linked CRM record gets it too. Only before launch.","cli":"dench campaign person set --linkedin-url","method":"PUT","path":"/campaigns/people/{enrollmentId}/linkedin","permission":"campaigns:write","pathParams":["enrollmentId"]},
380
+ {"id":"campaigns.people.setField","group":"campaigns","summary":"Fill or fix one {{merge field}} for a person in a draft campaign, e.g. a missing Company that blocks launch; a matching column on their CRM record is updated too. Only before launch; written personalized lines are not merge fields and can't be set here.","cli":"dench campaign person set --field","method":"PUT","path":"/campaigns/people/{enrollmentId}/fields","permission":"campaigns:write","pathParams":["enrollmentId"]},
381
+ {"id":"campaigns.people.resumeAll","group":"campaigns","summary":"Resume every paused person in an active campaign at once, e.g. after a sending account is reconnected. Returns how many were resumed.","cli":"dench campaign resume-person --all","method":"POST","path":"/campaigns/{sequenceId}/people/resume","permission":"campaigns:write","pathParams":["sequenceId"]},
382
+ {"id":"campaigns.people.sync","group":"campaigns","summary":"Fill each unfinished person's empty email, LinkedIn URL, name and merge fields from their linked CRM record, e.g. after enriching the records. Never overwrites a value the campaign already has; returns how many people changed.","cli":"dench campaign sync","method":"POST","path":"/campaigns/{sequenceId}/people/sync","permission":"campaigns:write","pathParams":["sequenceId"]},
383
+ {"id":"campaigns.people.forRecord","group":"campaigns","summary":"The campaigns a CRM record (a person or a lead) is in, newest first, with the person's status in each and the accounts that send to them.","cli":"dench campaign where","method":"GET","path":"/campaigns/by-record/{entryId}","permission":"campaigns:read","pathParams":["entryId"]},
384
+ {"id":"campaigns.people.timeline","group":"campaigns","summary":"Everything a campaign did for one person, step by step: what was sent (subject and text), whether it was opened or clicked, what was skipped and why, waits, failures and retries.","cli":"dench campaign person show","method":"GET","path":"/campaigns/people/{enrollmentId}/timeline","permission":"campaigns:read","pathParams":["enrollmentId"]},
385
+ {"id":"campaigns.people.remove","group":"campaigns","summary":"Remove a person who was never contacted from a draft campaign. Frees their place in the 300-person cap and keeps the draft launchable; stop anyone already contacted instead.","cli":"dench campaign remove","method":"DELETE","path":"/campaigns/people/{enrollmentId}","permission":"campaigns:write","pathParams":["enrollmentId"]},
350
386
  {"id":"cron.list","group":"routines","summary":"List routines.","cli":"dench cron list","method":"GET","path":"/routines","permission":"cron:schedule","pathParams":[]},
351
387
  {"id":"cron.history","group":"routines","summary":"List routine run history.","cli":"dench cron history","method":"GET","path":"/routines/history","permission":"cron:schedule","pathParams":[]},
352
388
  {"id":"cron.get","group":"routines","summary":"Get a routine.","cli":"dench cron get","method":"GET","path":"/routines/{jobId}","permission":"cron:schedule","pathParams":["jobId"]},
@@ -382,7 +418,7 @@ export const APP_SDK_OPERATIONS: readonly AppSdkOperationInfo[] = [
382
418
  {"id":"web.brandSearch","group":"gateway","summary":"Autocomplete brand names.","cli":"dench web brand-search","method":"POST","path":"/context/brand-search","permission":"web:read","pathParams":[]},
383
419
  {"id":"image.generate","group":"gateway","summary":"Generate an image through the Dench gateway.","cli":"dench image generate","method":"POST","path":"/images/generations","permission":"image:write","pathParams":[]},
384
420
  {"id":"image.edit","group":"gateway","summary":"Edit an image through the Dench gateway.","cli":"dench image edit","method":"POST","path":"/images/edits","permission":"image:write","pathParams":[]},
385
- {"id":"integrations.list","group":"gateway","summary":"List every connected integration — Composio apps plus the Gmail, Outlook, Calendar, LinkedIn and Slack connections Dench brokers itself (Slack rows report source: dench).","cli":"dench integrations","method":"GET","path":"/integrations","permission":"integrations:read","pathParams":[]},
421
+ {"id":"integrations.list","group":"gateway","summary":"List every connected integration — connected apps plus the Gmail, Outlook, Calendar, LinkedIn and Slack connections Dench provides itself (Slack rows report source: dench).","cli":"dench integrations","method":"GET","path":"/integrations","permission":"integrations:read","pathParams":[]},
386
422
  {"id":"apps.list","group":"apps","summary":"List installed App Store apps in the workspace.","cli":"dench apps list","method":"GET","path":"/apps","permission":"apps:read","pathParams":[]},
387
423
  {"id":"apps.gallery","group":"apps","summary":"List Discover listings — Official (Dench) + Community shelves.","cli":"dench apps gallery","method":"GET","path":"/apps/gallery","permission":"apps:read","pathParams":[]},
388
424
  {"id":"apps.create","group":"apps","summary":"Scaffold and register a new App Store app.","cli":"dench apps create","method":"POST","path":"/apps","permission":"apps:write","pathParams":[]},
@@ -396,9 +432,9 @@ export const APP_SDK_OPERATIONS: readonly AppSdkOperationInfo[] = [
396
432
  {"id":"apps.webhooks.poll","group":"apps","summary":"Read events an app webhook received since a timestamp.","cli":"dench apps webhooks poll","method":"GET","path":"/apps/{slug}/webhooks/{hookName}/events","permission":"webhooks:receive","pathParams":["slug","hookName"]},
397
433
  {"id":"apps.webhooks.delete","group":"apps","summary":"Remove an app webhook and every event it stored.","cli":"dench apps webhooks delete","method":"DELETE","path":"/apps/{slug}/webhooks/{hookName}","permission":"webhooks:receive","pathParams":["slug","hookName"]},
398
434
  {"id":"tool.status","group":"gateway","summary":"List connected tool accounts.","cli":"dench tool status","method":"GET","path":"/tools/status","permission":"integrations:read","pathParams":[]},
399
- {"id":"tool.connect","group":"gateway","summary":"Create a tool OAuth connection link. Slack is in-house, never Composio: for toolkit slack the CLI prints the first-party install URL (/api/slack/install?slug=<workspace>, org admin) instead of calling this endpoint.","cli":"dench tool connect","method":"POST","path":"/tools/connections","permission":"integrations:write","pathParams":[]},
435
+ {"id":"tool.connect","group":"gateway","summary":"Create a tool OAuth connection link. Slack is in-house, never a third-party connection: for toolkit slack the CLI prints the first-party install URL (/api/slack/install?slug=<workspace>, org admin) instead of calling this endpoint.","cli":"dench tool connect","method":"POST","path":"/tools/connections","permission":"integrations:write","pathParams":[]},
400
436
  {"id":"tool.search","group":"gateway","summary":"Search for external tool actions.","cli":"dench tool search","method":"POST","path":"/tools/search","permission":"integrations:read","pathParams":[]},
401
- {"id":"tool.run","group":"gateway","summary":"Run an external tool action. SLACK_* slugs (SLACK_SEND_MESSAGE with Block Kit blocks/buttons, SLACK_FETCH_HISTORY, SLACK_LIST_CHANNELS, …) run through Dench's in-house Slack app install — any channel in the connected workspace — and are always preferred over Composio Slack.","cli":"dench tool run","method":"POST","path":"/tools/run","permission":"integrations:write","pathParams":[]},
437
+ {"id":"tool.run","group":"gateway","summary":"Run an external tool action. SLACK_* slugs (SLACK_SEND_MESSAGE with Block Kit blocks/buttons, SLACK_FETCH_HISTORY, SLACK_LIST_CHANNELS, …) run through Dench's in-house Slack app install — any channel in the connected workspace — and are always preferred over any third-party Slack connection.","cli":"dench tool run","method":"POST","path":"/tools/run","permission":"integrations:write","pathParams":[]},
402
438
  {"id":"tool.disconnect","group":"gateway","summary":"Disconnect an external tool account.","cli":"dench tool disconnect","method":"DELETE","path":"/tools/connections/{connectionId}","permission":"integrations:write","pathParams":["connectionId"]},
403
439
  {"id":"tool.labels.list","group":"gateway","summary":"List human names given to connected accounts.","cli":"dench tool labels","method":"GET","path":"/tools/labels","permission":"integrations:read","pathParams":[]},
404
440
  {"id":"tool.label.set","group":"gateway","summary":"Name a connected account, or clear its name with an empty string.","cli":"dench tool label","method":"PUT","path":"/tools/connections/{connectionId}/label","permission":"integrations:write","pathParams":["connectionId"]},
@@ -525,12 +561,52 @@ export const APP_SDK_METHODS: Readonly<Record<string, AppSdkMethodInfo>> = {
525
561
  "lists.get": {"kind":"op","permission":"lists:read","op":"lists.get","doc":"One saved list with its rows."},
526
562
  "lists.rename": {"kind":"op","permission":"lists:write","op":"lists.rename","doc":"Rename a list."},
527
563
  "lists.delete": {"kind":"op","permission":"lists:write","op":"lists.delete","doc":"Delete a list."},
564
+ "campaigns.create": {"kind":"op","permission":"campaigns:write","op":"campaigns.create","doc":"Create a draft campaign."},
565
+ "campaigns.draft": {"kind":"op","permission":"campaigns:write","op":"campaigns.drafts.create","doc":"Create an idempotent draft with available sender pools."},
566
+ "campaigns.search": {"kind":"op","permission":"campaigns:write","op":"campaigns.audience.search","doc":"Search people without enrolling them. Search credits apply."},
567
+ "campaigns.addPeople": {"kind":"op","permission":"campaigns:write","op":"campaigns.people.addBatch","doc":"Add up to 50 selected recipients without running another search."},
568
+ "campaigns.addFromSearch": {"kind":"op","permission":"campaigns:write","op":"campaigns.people.addFromSearch","doc":"Search and add up to 50 people to an existing campaign."},
569
+ "campaigns.sources": {"kind":"op","permission":"campaigns:read","op":"campaigns.sources.get","doc":"Read the campaign's lead source."},
570
+ "campaigns.sourceSignals": {"kind":"op","permission":"campaigns:read","op":"campaigns.sources.signals","doc":"Read signal choices and suggestions."},
571
+ "campaigns.updateSources": {"kind":"op","permission":"campaigns:write","op":"campaigns.sources.update","doc":"Update targeting, signals, cadence or source status."},
572
+ "campaigns.previewSignal": {"kind":"op","permission":"campaigns:write","op":"campaigns.sources.preview","doc":"Preview a signal without enrolling people. Provider credits may apply."},
573
+ "campaigns.profile": {"kind":"op","permission":"campaigns:read","op":"campaigns.builder.profile","doc":"Read suggested campaign targeting."},
574
+ "campaigns.saveDraft": {"kind":"op","permission":"campaigns:write","op":"campaigns.builder.save","doc":"Save signal-draft targeting and choices."},
575
+ "campaigns.getDraft": {"kind":"op","permission":"campaigns:read","op":"campaigns.builder.get","doc":"Read preview people, messages and build progress."},
576
+ "campaigns.buildDraft": {"kind":"op","permission":"campaigns:write","op":"campaigns.builder.build","doc":"Start a billable signal draft build."},
577
+ "campaigns.createFromDraft": {"kind":"op","permission":"campaigns:write","op":"campaigns.builder.create","doc":"Create a campaign from a reviewed signal draft, without launching."},
578
+ "campaigns.setDraftOpener": {"kind":"op","permission":"campaigns:write","op":"campaigns.builder.opener","doc":"Edit a preview person's opening line."},
579
+ "campaigns.autofill": {"kind":"op","permission":"campaigns:write","op":"campaigns.builder.autofill","doc":"Translate a description into targeting. AI credits apply."},
580
+ "campaigns.suggestTerms": {"kind":"op","permission":"campaigns:write","op":"campaigns.builder.terms","doc":"Suggest signal terms. AI credits apply."},
581
+ "campaigns.estimate": {"kind":"op","permission":"campaigns:write","op":"campaigns.builder.estimate","doc":"Estimate audience or signal volume."},
582
+ "campaigns.mailboxes": {"kind":"op","permission":"campaigns:read","op":"campaigns.accounts.email","doc":"Mailboxes campaigns can send from, with warm-up and daily cap."},
583
+ "campaigns.linkedinAccounts": {"kind":"op","permission":"campaigns:read","op":"campaigns.accounts.linkedin","doc":"LinkedIn accounts campaigns can send from, with capacity."},
528
584
  "campaigns.list": {"kind":"op","permission":"campaigns:read","op":"campaigns.list","doc":"LinkedIn / multi-channel outreach campaigns."},
529
585
  "campaigns.get": {"kind":"op","permission":"campaigns:read","op":"campaigns.get","doc":"One campaign."},
586
+ "campaigns.setSteps": {"kind":"op","permission":"campaigns:write","op":"campaigns.steps.replace","doc":"Replace every step of a draft campaign."},
587
+ "campaigns.editSteps": {"kind":"op","permission":"campaigns:write","op":"campaigns.steps.update","doc":"Edit launched steps in place by stepId and updatedAt."},
588
+ "campaigns.duplicate": {"kind":"op","permission":"campaigns:write","op":"campaigns.duplicate","doc":"Copy a campaign into a new draft without its people."},
530
589
  "campaigns.analytics": {"kind":"op","permission":"campaigns:read","op":"campaigns.analytics","doc":"Campaign funnel numbers."},
531
590
  "campaigns.events": {"kind":"op","permission":"campaigns:read","op":"campaigns.events","doc":"Campaign event log."},
532
591
  "campaigns.pause": {"kind":"op","permission":"campaigns:write","op":"campaigns.pause","doc":"Pause a campaign."},
533
592
  "campaigns.resume": {"kind":"op","permission":"campaigns:write","op":"campaigns.resume","doc":"Resume a campaign."},
593
+ "campaigns.archive": {"kind":"op","permission":"campaigns:write","op":"campaigns.archive","doc":"Archive (the app's Delete) a campaign; nothing is erased."},
594
+ "campaigns.previewMessage": {"kind":"op","permission":"campaigns:read","op":"campaigns.preview","doc":"The message one person gets at one step, fields filled in. Sends nothing."},
595
+ "campaigns.personalization": {"kind":"op","permission":"campaigns:read","op":"campaigns.personalization.get","doc":"Personalized lines, their {{keys}} and how many are written."},
596
+ "campaigns.setPersonalization": {"kind":"op","permission":"campaigns:write","op":"campaigns.personalization.set","doc":"Define up to 5 personalized lines. Writing them costs credits."},
597
+ "campaigns.clearPersonalization": {"kind":"op","permission":"campaigns:write","op":"campaigns.personalization.clear","doc":"Turn personalized lines off."},
598
+ "campaigns.writeLines": {"kind":"op","permission":"campaigns:write","op":"campaigns.personalization.write","doc":"Write missing (or all) personalized lines. Costs credits."},
599
+ "campaigns.editLine": {"kind":"op","permission":"campaigns:write","op":"campaigns.personalization.edit","doc":"Set one person's personalized line by hand."},
600
+ "campaigns.rewriteLine": {"kind":"op","permission":"campaigns:write","op":"campaigns.personalization.rewrite","doc":"Write a fresh line for one person. Costs credits."},
601
+ "campaigns.syncPeople": {"kind":"op","permission":"campaigns:write","op":"campaigns.people.sync","doc":"Fill people's empty contact details from their CRM records."},
602
+ "campaigns.resumeAllPeople": {"kind":"op","permission":"campaigns:write","op":"campaigns.people.resumeAll","doc":"Resume every paused person in an active campaign."},
603
+ "campaigns.setPersonEmail": {"kind":"op","permission":"campaigns:write","op":"campaigns.people.setEmail","doc":"Fix a draft person's email address."},
604
+ "campaigns.setPersonLinkedin": {"kind":"op","permission":"campaigns:write","op":"campaigns.people.setLinkedin","doc":"Fix a draft person's LinkedIn profile URL."},
605
+ "campaigns.setPersonField": {"kind":"op","permission":"campaigns:write","op":"campaigns.people.setField","doc":"Fill one {{merge field}} for a draft person."},
606
+ "campaigns.pipeline": {"kind":"op","permission":"campaigns:read","op":"campaigns.pipeline","doc":"Where the campaign's people sit in the lead pipeline."},
607
+ "campaigns.campaignsForRecord": {"kind":"op","permission":"campaigns:read","op":"campaigns.people.forRecord","doc":"The campaigns a CRM record is in, with its status in each."},
608
+ "campaigns.personTimeline": {"kind":"op","permission":"campaigns:read","op":"campaigns.people.timeline","doc":"Everything a campaign did for one person, step by step."},
609
+ "campaigns.removePerson": {"kind":"op","permission":"campaigns:write","op":"campaigns.people.remove","doc":"Remove a never-contacted person from a draft campaign."},
534
610
  "email.send": {"kind":"op","permission":"email:write","op":"email.send","doc":"Send one email from a verified identity."},
535
611
  "email.messages": {"kind":"op","permission":"email:read","op":"email.message.list","doc":"Sent messages."},
536
612
  "email.message": {"kind":"op","permission":"email:read","op":"email.message.get","doc":"One sent message with delivery events."},
@@ -629,6 +629,126 @@ export const APP_SDK_SURFACE: AppSdkSurface = {
629
629
  },
630
630
 
631
631
  campaigns: {
632
+ create: {
633
+ op: "campaigns.create",
634
+ doc: "Create a draft campaign.",
635
+ args: `opts: ${A("campaigns.create")}`,
636
+ returns: R("campaigns.create"),
637
+ },
638
+ draft: {
639
+ op: "campaigns.drafts.create",
640
+ doc: "Create an idempotent draft with available sender pools.",
641
+ args: `opts: ${A("campaigns.drafts.create")}`,
642
+ returns: R("campaigns.drafts.create"),
643
+ },
644
+ search: {
645
+ op: "campaigns.audience.search",
646
+ doc: "Search people without enrolling them. Search credits apply.",
647
+ args: `opts: ${A("campaigns.audience.search")}`,
648
+ returns: R("campaigns.audience.search"),
649
+ },
650
+ addPeople: {
651
+ op: "campaigns.people.addBatch",
652
+ doc: "Add up to 50 selected recipients without running another search.",
653
+ args: `opts: ${A("campaigns.people.addBatch")}`,
654
+ returns: R("campaigns.people.addBatch"),
655
+ },
656
+ addFromSearch: {
657
+ op: "campaigns.people.addFromSearch",
658
+ doc: "Search and add up to 50 people to an existing campaign.",
659
+ args: `opts: ${A("campaigns.people.addFromSearch")}`,
660
+ returns: R("campaigns.people.addFromSearch"),
661
+ },
662
+ sources: {
663
+ op: "campaigns.sources.get",
664
+ doc: "Read the campaign's lead source.",
665
+ args: "sequenceId: string",
666
+ returns: R("campaigns.sources.get"),
667
+ },
668
+ sourceSignals: {
669
+ op: "campaigns.sources.signals",
670
+ doc: "Read signal choices and suggestions.",
671
+ args: "sequenceId: string",
672
+ returns: R("campaigns.sources.signals"),
673
+ },
674
+ updateSources: {
675
+ op: "campaigns.sources.update",
676
+ doc: "Update targeting, signals, cadence or source status.",
677
+ args: `opts: ${A("campaigns.sources.update")}`,
678
+ returns: R("campaigns.sources.update"),
679
+ },
680
+ previewSignal: {
681
+ op: "campaigns.sources.preview",
682
+ doc: "Preview a signal without enrolling people. Provider credits may apply.",
683
+ args: `opts: ${A("campaigns.sources.preview")}`,
684
+ returns: R("campaigns.sources.preview"),
685
+ },
686
+ profile: {
687
+ op: "campaigns.builder.profile",
688
+ doc: "Read suggested campaign targeting.",
689
+ args: "",
690
+ returns: R("campaigns.builder.profile"),
691
+ },
692
+ saveDraft: {
693
+ op: "campaigns.builder.save",
694
+ doc: "Save signal-draft targeting and choices.",
695
+ args: `opts: ${A("campaigns.builder.save")}`,
696
+ returns: R("campaigns.builder.save"),
697
+ },
698
+ getDraft: {
699
+ op: "campaigns.builder.get",
700
+ doc: "Read preview people, messages and build progress.",
701
+ args: "draftId: string",
702
+ returns: R("campaigns.builder.get"),
703
+ },
704
+ buildDraft: {
705
+ op: "campaigns.builder.build",
706
+ doc: "Start a billable signal draft build.",
707
+ args: "draftId: string",
708
+ returns: R("campaigns.builder.build"),
709
+ },
710
+ createFromDraft: {
711
+ op: "campaigns.builder.create",
712
+ doc: "Create a campaign from a reviewed signal draft, without launching.",
713
+ args: `opts: ${A("campaigns.builder.create")}`,
714
+ returns: R("campaigns.builder.create"),
715
+ },
716
+ setDraftOpener: {
717
+ op: "campaigns.builder.opener",
718
+ doc: "Edit a preview person's opening line.",
719
+ args: `opts: ${A("campaigns.builder.opener")}`,
720
+ returns: R("campaigns.builder.opener"),
721
+ },
722
+ autofill: {
723
+ op: "campaigns.builder.autofill",
724
+ doc: "Translate a description into targeting. AI credits apply.",
725
+ args: `opts: ${A("campaigns.builder.autofill")}`,
726
+ returns: R("campaigns.builder.autofill"),
727
+ },
728
+ suggestTerms: {
729
+ op: "campaigns.builder.terms",
730
+ doc: "Suggest signal terms. AI credits apply.",
731
+ args: `opts: ${A("campaigns.builder.terms")}`,
732
+ returns: R("campaigns.builder.terms"),
733
+ },
734
+ estimate: {
735
+ op: "campaigns.builder.estimate",
736
+ doc: "Estimate audience or signal volume.",
737
+ args: `opts: ${A("campaigns.builder.estimate")}`,
738
+ returns: R("campaigns.builder.estimate"),
739
+ },
740
+ mailboxes: {
741
+ op: "campaigns.accounts.email",
742
+ doc: "Mailboxes campaigns can send from, with warm-up and daily cap.",
743
+ args: "",
744
+ returns: R("campaigns.accounts.email"),
745
+ },
746
+ linkedinAccounts: {
747
+ op: "campaigns.accounts.linkedin",
748
+ doc: "LinkedIn accounts campaigns can send from, with capacity.",
749
+ args: "",
750
+ returns: R("campaigns.accounts.linkedin"),
751
+ },
632
752
  list: {
633
753
  op: "campaigns.list",
634
754
  doc: "LinkedIn / multi-channel outreach campaigns.",
@@ -641,6 +761,24 @@ export const APP_SDK_SURFACE: AppSdkSurface = {
641
761
  args: "sequenceId: string",
642
762
  returns: R("campaigns.get"),
643
763
  },
764
+ setSteps: {
765
+ op: "campaigns.steps.replace",
766
+ doc: "Replace every step of a draft campaign.",
767
+ args: `opts: ${A("campaigns.steps.replace")}`,
768
+ returns: R("campaigns.steps.replace"),
769
+ },
770
+ editSteps: {
771
+ op: "campaigns.steps.update",
772
+ doc: "Edit launched steps in place by stepId and updatedAt.",
773
+ args: `opts: ${A("campaigns.steps.update")}`,
774
+ returns: R("campaigns.steps.update"),
775
+ },
776
+ duplicate: {
777
+ op: "campaigns.duplicate",
778
+ doc: "Copy a campaign into a new draft without its people.",
779
+ args: "sequenceId: string",
780
+ returns: R("campaigns.duplicate"),
781
+ },
644
782
  analytics: {
645
783
  op: "campaigns.analytics",
646
784
  doc: "Campaign funnel numbers.",
@@ -665,6 +803,108 @@ export const APP_SDK_SURFACE: AppSdkSurface = {
665
803
  args: "sequenceId: string",
666
804
  returns: R("campaigns.resume"),
667
805
  },
806
+ archive: {
807
+ op: "campaigns.archive",
808
+ doc: "Archive (the app's Delete) a campaign; nothing is erased.",
809
+ args: "sequenceId: string",
810
+ returns: R("campaigns.archive"),
811
+ },
812
+ previewMessage: {
813
+ op: "campaigns.preview",
814
+ doc: "The message one person gets at one step, fields filled in. Sends nothing.",
815
+ args: "sequenceId: string, enrollmentId: string, stepId: string",
816
+ returns: R("campaigns.preview"),
817
+ },
818
+ personalization: {
819
+ op: "campaigns.personalization.get",
820
+ doc: "Personalized lines, their {{keys}} and how many are written.",
821
+ args: "sequenceId: string",
822
+ returns: R("campaigns.personalization.get"),
823
+ },
824
+ setPersonalization: {
825
+ op: "campaigns.personalization.set",
826
+ doc: "Define up to 5 personalized lines. Writing them costs credits.",
827
+ args: `opts: ${A("campaigns.personalization.set")}`,
828
+ returns: R("campaigns.personalization.set"),
829
+ },
830
+ clearPersonalization: {
831
+ op: "campaigns.personalization.clear",
832
+ doc: "Turn personalized lines off.",
833
+ args: "sequenceId: string",
834
+ returns: R("campaigns.personalization.clear"),
835
+ },
836
+ writeLines: {
837
+ op: "campaigns.personalization.write",
838
+ doc: "Write missing (or all) personalized lines. Costs credits.",
839
+ args: `opts: ${A("campaigns.personalization.write")}`,
840
+ returns: R("campaigns.personalization.write"),
841
+ },
842
+ editLine: {
843
+ op: "campaigns.personalization.edit",
844
+ doc: "Set one person's personalized line by hand.",
845
+ args: "enrollmentId: string, key: string, value: string",
846
+ returns: R("campaigns.personalization.edit"),
847
+ },
848
+ rewriteLine: {
849
+ op: "campaigns.personalization.rewrite",
850
+ doc: "Write a fresh line for one person. Costs credits.",
851
+ args: "enrollmentId: string, key?: string",
852
+ returns: R("campaigns.personalization.rewrite"),
853
+ },
854
+ syncPeople: {
855
+ op: "campaigns.people.sync",
856
+ doc: "Fill people's empty contact details from their CRM records.",
857
+ args: "sequenceId: string",
858
+ returns: R("campaigns.people.sync"),
859
+ },
860
+ resumeAllPeople: {
861
+ op: "campaigns.people.resumeAll",
862
+ doc: "Resume every paused person in an active campaign.",
863
+ args: "sequenceId: string",
864
+ returns: R("campaigns.people.resumeAll"),
865
+ },
866
+ setPersonEmail: {
867
+ op: "campaigns.people.setEmail",
868
+ doc: "Fix a draft person's email address.",
869
+ args: "enrollmentId: string, email: string",
870
+ returns: R("campaigns.people.setEmail"),
871
+ },
872
+ setPersonLinkedin: {
873
+ op: "campaigns.people.setLinkedin",
874
+ doc: "Fix a draft person's LinkedIn profile URL.",
875
+ args: "enrollmentId: string, linkedinProfileUrl: string",
876
+ returns: R("campaigns.people.setLinkedin"),
877
+ },
878
+ setPersonField: {
879
+ op: "campaigns.people.setField",
880
+ doc: "Fill one {{merge field}} for a draft person.",
881
+ args: "enrollmentId: string, key: string, value: string",
882
+ returns: R("campaigns.people.setField"),
883
+ },
884
+ pipeline: {
885
+ op: "campaigns.pipeline",
886
+ doc: "Where the campaign's people sit in the lead pipeline.",
887
+ args: "sequenceId: string",
888
+ returns: R("campaigns.pipeline"),
889
+ },
890
+ campaignsForRecord: {
891
+ op: "campaigns.people.forRecord",
892
+ doc: "The campaigns a CRM record is in, with its status in each.",
893
+ args: "entryId: string",
894
+ returns: R("campaigns.people.forRecord"),
895
+ },
896
+ personTimeline: {
897
+ op: "campaigns.people.timeline",
898
+ doc: "Everything a campaign did for one person, step by step.",
899
+ args: "enrollmentId: string",
900
+ returns: R("campaigns.people.timeline"),
901
+ },
902
+ removePerson: {
903
+ op: "campaigns.people.remove",
904
+ doc: "Remove a never-contacted person from a draft campaign.",
905
+ args: "enrollmentId: string",
906
+ returns: R("campaigns.people.remove"),
907
+ },
668
908
  },
669
909
 
670
910
  email: {