Skip to content

AGENTS.md

136 lines · 4.2 KB · Markdown
Raw

@kody/jira — agent notes

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

Auth

CallResolves to
omitjira / jiraEmail + jiraApiToken
account: 'jira-work'jira-work / jiraEmail-work + jiraApiToken-work
auth: 'oauth' | 'token'force lane when both exist
site: 'acme'*.atlassian.net subdomain (API-token lane; also when multi-site OAuth)
cloudIdOAuth cloud id from ./list-sites

OAuth: https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3. API token: https://{site}.atlassian.net/rest/api/3.

Do not hard-code personal workspace aliases or project keys.

Import paths

ExportImport
root dispatcher (defaults to smoke-test)kody:@kody/jira
setupkody:@kody/jira/setup
smoke-testkody:@kody/jira/smoke-test
list-siteskody:@kody/jira/list-sites
list-projectskody:@kody/jira/list-projects
get-issuekody:@kody/jira/get-issue
searchkody:@kody/jira/search
create-issuekody:@kody/jira/create-issue
list-commentskody:@kody/jira/list-comments
add-commentkody:@kody/jira/add-comment
list-transitionskody:@kody/jira/list-transitions
transition-issuekody:@kody/jira/transition-issue
requestkody:@kody/jira/request

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

Smoke test (read-only)

import smokeTest from 'kody:@kody/jira/smoke-test'

export default async function main() {
	return await smokeTest({
		// account: 'jira-work',
		// site: 'acme',
	})
	// Without credentials: { ok: true, live: false } + setup URLs
	// With credentials: live `/myself` (no email)
}

Root dispatcher dry preview:

import jira from 'kody:@kody/jira'

export default async function main() {
	return await jira({ dryRun: true })
}

dryRun / confirm

create-issue, add-comment, transition-issue, and mutating request calls never write when dryRun: true. A live write also requires confirm: true after the user approved the exact issue or fields.

import createIssue from 'kody:@kody/jira/create-issue'
import addComment from 'kody:@kody/jira/add-comment'

export default async function main() {
	const previewIssue = await createIssue({
		projectKey: 'PROJ',
		summary: 'Follow up with the customer',
		issueType: 'Task',
		dryRun: true,
	})
	const previewComment = await addComment({
		issueIdOrKey: 'PROJ-123',
		body: 'Posted from Kody after review.',
		dryRun: true,
	})
	return { previewIssue, previewComment }
}

Read helpers:

import searchIssues from 'kody:@kody/jira/search'
import listProjects from 'kody:@kody/jira/list-projects'

export default async function main() {
	const projects = await listProjects({ query: 'platform', maxResults: 20 })
	const issues = await searchIssues({
		jql: 'assignee = currentUser() AND statusCategory != Done ORDER BY updated DESC',
		maxResults: 10,
		// site: 'acme',
	})
	return { projects, issues }
}

Multi-account:

import listProjects from 'kody:@kody/jira/list-projects'

export default async function main() {
	return listProjects({ account: 'jira-work', site: 'acme' })
}

Edge cases / troubleshooting

  • OAuth authorize fails: confirm redirect URI is exactly https://kody.codes/connect/oauth and the Jira API permissions are added on the Atlassian app.
  • audience errors: reconnect with the prefilled URL so extraAuthorizeParams includes audience=api.atlassian.com and prompt=consent.
  • Host approval: OAuth needs api.atlassian.com (and auth.atlassian.com for token refresh). API token needs {site}.atlassian.net on both secrets.
  • Several OAuth sites: pass site or cloudId from ./list-sites. This package will not pick a default project or site.
  • CAPTCHA / AUTHENTICATION_DENIED: unlock the Atlassian account in the browser, then retry.
  • Prefer @kody/atlassian-mcp only for a faster first win; this package is the preferred invoke path once BYO OAuth or an API token is set up.