Skip to content
← Public packages

@kentcdodds/devin

Start, monitor, and manage Devin sessions, knowledge, playbooks, and schedules via the Devin v3 API

AGENTS.md

133 lines · 4.7 KB · Markdown

@kentcdodds/devin — agent notes

Human setup and intent live in README.md. This file is for agents: imports, smoke execute snippets, and edge cases. Secrets by name only — never paste key values. Do not disable live webhooks or jobs.

Secrets / settings

NameKindRequiredNotes
devinServiceUserKeyuser secretYesv3 service user key (cog_…); host api.devin.ai
devinOrgIdpackage storageYes*org-… id; *or pass orgId on every helper

Placeholder: {{secret:devinServiceUserKey}}. Update org without republish:

import destSettings from 'kody:@kentcdodds/devin/settings'

export default async function main() {
	return await destSettings({ orgId: 'org-…' })
}

Import paths

ExportImportDefault
overviewkody:@kentcdodds/devindescribe package
selfkody:@kentcdodds/devin/selfwhoami
sessionskody:@kentcdodds/devin/sessionslistSessions
knowledgekody:@kentcdodds/devin/knowledgelistNotes
playbookskody:@kentcdodds/devin/playbookslistPlaybooks
scheduleskody:@kentcdodds/devin/scheduleslistSchedules
reviewskody:@kentcdodds/devin/reviewsgetPrReview
usagekody:@kentcdodds/devin/usagedailyConsumption
requestkody:@kentcdodds/devin/requestdevinRequest
settingskody:@kentcdodds/devin/settingsread/update devinOrgId
migrate-from-valueskody:@kentcdodds/devin/migrate-from-valuesone-shot value → storage

Prefer static kody:@kentcdodds/devin/... imports from execute. Do not lead with packages.invoke.

Named helpers on namespaces: createSession, getSessionStatus, sendMessage, listNotes, createNote, getPrReview, createPrReview, dailyConsumption, etc. (see overview export map).

Smoke test (read-only)

import { whoami } from 'kody:@kentcdodds/devin/self'

export default async function main() {
	return await whoami()
	// cheapest auth/permissions check against /v3/self
}

Optional read-only follow-ups: listSessions({ first: 5 }), listNotes({ first: 5 }), or destSettings() (read settings).

Session id field: devinId (not sessionId)

Per-session helpers (getSession, listMessages, sendMessage, getSessionStatus, terminate/archive/tags/attachments) take { devinId }. Use session.session_id from create/list/get responses:

await listMessages({ devinId: session.session_id })
// not listMessages({ sessionId: session.session_id }) — Devin returns 403

A 403 on these calls is most often the wrong field name, not missing RBAC. requireDevinId throws if sessionId is passed.

Costly / destructive calls

Confirm intent (and ids) before:

  • ACU: createSession, createPrReview, generateSessionInsights
  • Destructive: terminateSession, deleteNote, deletePlaybook, deleteSchedule

Prefer updateSchedule({ enabled: false }) over deleting a schedule.

import { createSession, getSessionStatus, sendMessage } from 'kody:@kentcdodds/devin/sessions'

export default async function main() {
	// Only after explicit user approval — consumes ACUs
	const session = await createSession({
		prompt: 'Fix the flaky auth test and open a PR',
		repos: ['owner/repo'],
		tags: ['kody'],
		maxAcuLimit: 10,
	})
	await sendMessage({
		devinId: session.session_id,
		message: 'Also update the changelog',
	})
	return await getSessionStatus({ devinId: session.session_id })
}

Raw escape hatch (non-2xx returned, not thrown):

import { devinRequest } from 'kody:@kentcdodds/devin/request'

export default async function main() {
	return await devinRequest({
		path: '/v3beta1/organizations/{org_id}/repositories',
	})
}

Edge cases

  • v3 only: legacy apk_ keys 403 on /v3/*. Need cog_… service user keys.
  • 403 usually means missing RBAC on the service user role, not a bad key — start with whoami.
  • Cursor pagination: pass after: page.end_cursor while page.has_next_page, or use listAllSessions (capped by maxPages). Schedules use limit/offset instead.
  • Session list filters are flat repeated query params (?tags=a&tags=b); Devin ignores nested qs from the OpenAPI spec.
  • Timestamps are Unix seconds; scheduledAt is an ISO date-time string.
  • getPrReview returns null for an unreviewed PR (404) instead of throwing.
  • Typed helpers throw DevinApiError (status, body) on non-2xx; devinRequest returns { status, body } unwrapped.
  • Unwrapped surface (enterprise admin, code scans, snapshot blueprints, repo indexing, org secrets): use ./request.
  • Never paste devinServiceUserKey values into chat or logs.