Skip to content

AGENTS.md

120 lines · 3.7 KB · Markdown
Raw

@kody/asana — agent notes

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

Auth

LaneCredentialNotes
A (recommended)Integration asana (or asana-<purpose>)BYO OAuth + PKCE. Host app.asana.com.
BUser secret asanaPat (or asanaPat-<purpose>)PAT Bearer. account: "work" → asana-work / asanaPat-work.

Every export accepts integrationName / integration, account, secretName, and auth: "oauth" | "pat" when both exist. Placeholder: {{secret:asanaPat|scope=user}}. Do not hard-code a personal workspace GID.

Import paths

ExportImport
package overviewkody:@kody/asana
accountskody:@kody/asana/accounts
smoke-testkody:@kody/asana/smoke-test
viewerkody:@kody/asana/viewer
list-workspaceskody:@kody/asana/list-workspaces
get-workspacekody:@kody/asana/get-workspace
list-projectskody:@kody/asana/list-projects
get-projectkody:@kody/asana/get-project
create-projectkody:@kody/asana/create-project
list-taskskody:@kody/asana/list-tasks
get-taskkody:@kody/asana/get-task
create-taskkody:@kody/asana/create-task
update-taskkody:@kody/asana/update-task
list-storieskody:@kody/asana/list-stories
create-storykody:@kody/asana/create-story
request (escape hatch)kody:@kody/asana/request
typeskody:@kody/asana/types

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

Smoke test (read-only)

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

export default async function main() {
	return await smokeTest()
	// without creds => { ok: true, live: false, setup: { ...URLs } }
	// with creds => { ok: true, live: true, hasViewerGid, ... } (no email)
}

Common snippets

List workspaces then projects:

import listWorkspaces from 'kody:@kody/asana/list-workspaces'
import listProjects from 'kody:@kody/asana/list-projects'

export default async function main() {
	const { items: workspaces } = await listWorkspaces()
	return await listProjects({
		workspaceGid: workspaces[0]?.gid,
		limit: 20,
	})
}

Unwrapped REST:

import request from 'kody:@kody/asana/request'

export default async function main() {
	return await request({
		path: '/users/me',
		query: { opt_fields: 'gid,name' },
	})
}

dryRun / confirm (writes)

create-project, create-task, update-task, create-story, and mutating ./request (POST/PUT/PATCH/DELETE) require confirm: true. Pass dryRun: true to inspect the REST payload without calling Asana.

import createTask from 'kody:@kody/asana/create-task'

export default async function main() {
	const preview = await createTask({
		name: 'Investigate checkout timeout',
		workspaceGid: '123',
		assignee: 'me',
		dryRun: true,
	})
	// Only after explicit user confirmation of workspace + title:
	const created = await createTask({
		name: 'Investigate checkout timeout',
		workspaceGid: '123',
		assignee: 'me',
		confirm: true,
	})
	return { preview, created }
}

Edge cases / fork notes

  • REST base: https://app.asana.com/api/1.0
  • Helpers project slim objects with opt_fields. Use ./request for extra fields.
  • assignee: 'me' is the authorizing user.
  • List tasks requires projectGid, or both assignee and workspaceGid.
  • Fork/adapt: keep secret/integration names documented; do not hard-code personal workspace GIDs or treat live @kody/asana storage as yours.
  • Never paste Asana PATs or OAuth client secrets into chat or logs.