← Public packages
@kentcdodds/devin
Start, monitor, and manage Devin sessions, knowledge, playbooks, and schedules via the Devin v3 API
src/playbooks.ts
117 lines · 2.9 KB · TypeScriptimport {
clampInt,
compact,
devinOrgApi,
type Paginated,
trimString,
} from './lib/client.ts'
export type Playbook = {
playbook_id: string
title: string
body: string
macro: string | null
structured_output_schema: Record<string, unknown> | null
access_type: 'org' | 'enterprise' | string
org_id: string | null
created_by?: string | null
updated_by?: string | null
created_at: number
updated_at: number
}
export async function listPlaybooks(
params: { orgId?: string; first?: number; after?: string } = {},
) {
return devinOrgApi<Paginated<Playbook>>({
orgId: params.orgId,
path: '/playbooks',
query: compact({
first: params.first === undefined ? undefined : clampInt(params.first, 1, 200, 50),
after: params.after,
}),
})
}
export async function getPlaybook(params: {
playbookId: string
orgId?: string
}) {
return devinOrgApi<Playbook>({
orgId: params.orgId,
path: `/playbooks/${encodeURIComponent(params.playbookId)}`,
})
}
export type PlaybookInput = {
orgId?: string
title: string
body: string
/** Slack-style macro, must start with "!" (e.g. "!triage"). */
macro?: string
structuredOutputSchema?: Record<string, unknown>
}
function playbookBody(params: PlaybookInput) {
const title = trimString(params.title)
const body = trimString(params.body)
if (!title || !body) throw new Error('Playbooks require title and body')
return compact({
title,
body,
macro: params.macro,
structured_output_schema: params.structuredOutputSchema,
})
}
export async function createPlaybook(params: PlaybookInput) {
return devinOrgApi<Playbook>({
orgId: params.orgId,
path: '/playbooks',
method: 'POST',
body: playbookBody(params),
})
}
/** Full replace — Devin's PUT takes the same shape as create. */
export async function updatePlaybook(
params: PlaybookInput & { playbookId: string },
) {
return devinOrgApi<Playbook>({
orgId: params.orgId,
path: `/playbooks/${encodeURIComponent(params.playbookId)}`,
method: 'PUT',
body: playbookBody(params),
})
}
/** Destructive — confirm the playbook id before calling. */
export async function deletePlaybook(params: {
playbookId: string
orgId?: string
}) {
return devinOrgApi<unknown>({
orgId: params.orgId,
path: `/playbooks/${encodeURIComponent(params.playbookId)}`,
method: 'DELETE',
})
}
/**
* List Devin playbooks for the configured org (default `./playbooks` action).
* Use when browsing playbooks; named exports cover get/create/update/delete.
*
* @param params.orgId - Optional org override (else stored destinOrgId)
* @param params.first - Page size (1–200)
* @returns Paginated playbooks
*
* @example
* import listPlaybooks from 'kody:@kentcdodds/devin/playbooks'
* const page = await listPlaybooks({ first: 20 })
* // => { items: [{ playbook_id: '...', title: '...', ... }], ... }
*/
export default async function listPlaybooksDefault(
params: { orgId?: string; first?: number; after?: string } = {},
) {
return await listPlaybooks(params)
}