Skip to content
DocsHow Kody works

Introduction

How Kody works

Official Kody doc

Let's say you use as your regular coding agent, as your chat agent on your phone, and as another agent you sometimes use. Here's an example of conversations you might have with them when they're connected to Kody.

You start on the computer with OpenClaw.

Ask once

  1. You

    What did my favorite bot ship recently on GitHub?

  2. OpenClaw

    Reasoning: I will look up GitHub user activity and any memory that names your favorite bot.

  3. searchFind a saved GitHub token for user activity
    memoryContext
    {
      "task": "What did my favorite bot ship recently on GitHub?",
      "entities": [
        "favorite bot"
      ]
    }
    query
    "github user activity"

    Returns
    conversationId: 3k7n2p9q4r8w
    Tool conversation id; pass it back on subsequent search/execute calls.
    
    # Search results
    
    For full detail on entity-backed hits, call `search` with `entity: "{id}:{type}"`.
    
    1. **secret** `githubAccessToken` — github OAuth access token. Entity: `githubAccessToken:secret`
    
    ## Relevant memories
    
    - **Favorite bot** — kody-bot is my favorite bot. I'm really interested in what it ships on github
  4. OpenClaw

    Reasoning: Favorite bot is the GitHub account kody-bot. I will fetch its public events with the saved token.

  5. executeFetch public events with the saved token and keep only real ships
    conversationId
    "3k7n2p9q4r8w"
    memoryContext
    {
      "task": "What did my favorite bot ship recently on GitHub?",
      "entities": [
        "favorite bot"
      ]
    }
    code
    export default async function main() {
    	const response = await fetch(
    		'https://api.github.com/users/kody-bot/events/public',
    		{
    			headers: {
    				Accept: 'application/vnd.github+json',
    				Authorization: 'Bearer {{secret:githubAccessToken}}',
    				'X-GitHub-Api-Version': '2022-11-28',
    			},
    		},
    	)
    	if (!response.ok) throw new Error(`GitHub ${response.status}`)
    	const events = await response.json()
    	return events.flatMap((event) => {
    		if (
    			event.type === 'ReleaseEvent' &&
    			event.payload.action === 'published'
    		) {
    			return [{
    				id: event.id,
    				kind: 'release',
    				title: `${event.repo.name} ${event.payload.release.tag_name}`,
    			}]
    		}
    		if (
    			event.type === 'CreateEvent' &&
    			event.payload.ref_type === 'repository'
    		) {
    			return [{
    				id: event.id,
    				kind: 'repository',
    				title: `New repo ${event.repo.name}`,
    			}]
    		}
    		return []
    	})
    }

    Returns
    conversationId: 3k7n2p9q4r8w
    Tool conversation id; pass it back on subsequent search/execute calls.
    
    [
      {
        "id": "51284920123",
        "kind": "release",
        "title": "kody-bot/lantern v1.4.0"
      },
      {
        "id": "51279004401",
        "kind": "repository",
        "title": "New repo kody-bot/quiet-days"
      }
    ]
    
    ## Relevant memories
    
    - **Favorite bot** — kody-bot is my favorite bot. I'm really interested in what it ships on github
  6. OpenClaw

    Two things since the last look: kody-bot/lantern v1.4.0, and a new public repo kody-bot/quiet-days. Want this as a package so I can get you the answer quicker next time?

  7. You

    Yes

  8. OpenClaw

    Reasoning: I will load the package authoring guides, then save the filter as an export you own.

  9. searchFind the official package authoring guides
    conversationId
    "3k7n2p9q4r8w"
    query
    "package authoring lifecycle"
    domain
    "coding"

    Returns
    conversationId: 3k7n2p9q4r8w
    Tool conversation id; pass it back on subsequent search/execute calls.
    
    # Search results
    
    For full detail on entity-backed hits, call `search` with `entity: "{id}:{type}"`.
    
    1. **guide** Package authoring guide — START HERE when creating or materially changing a Kody package. Entity: `package_authoring:guide`
    2. **guide** Durable package lifecycle guide — Choose reuse vs temporary execute vs a new durable package. Entity: `package_lifecycle:guide`
    searchOpen the package authoring and lifecycle guides
    conversationId
    "3k7n2p9q4r8w"
    entity
    [
      "package_authoring:guide",
      "package_lifecycle:guide"
    ]

    Returns
    conversationId: 3k7n2p9q4r8w
    Tool conversation id; pass it back on subsequent search/execute calls.
    
    # Guide — `package_authoring`
    
    START HERE when creating or materially changing a Kody package.
    
    ## Summary
    
    - Entity: `package_authoring:guide`
    - Category: `platform`
    - Web: `/docs/package-authoring`
    
    # Package authoring guide
    
    Use this guide when creating a new Kody package or materially changing an existing one.
    
    ## Choose an authoring lane
    
    
    
    ---
    
    # Guide — `package_lifecycle`
    
    Choose between invoking existing behavior, temporary execute exploration, and creating a durable repo-backed package.
    
    ## Summary
    
    - Entity: `package_lifecycle:guide`
    - Category: `platform`
    - Web: `/docs/package-lifecycle`
    
    # Durable package lifecycle
    
    Use this guide to decide whether to reuse existing behavior, explore with `execute`, or create durable repo-backed package code. Use it before scheduling new package behavior.
    
    ## Choose the smallest durable surface
    
    
  10. OpenClaw

    Reasoning: The authoring guide prefers the git lane. I will register a stub, clone it, write the export, push, and publish.

  11. executeRegister the stub and mint a clone remote
    conversationId
    "3k7n2p9q4r8w"
    memoryContext
    {
      "task": "What did my favorite bot ship recently on GitHub?",
      "entities": [
        "favorite bot"
      ]
    }
    code
    import { kody } from 'kody:runtime'
    
    export default async function main() {
    	return await kody.packageGetGitRemote({
    		kody_id: 'kody-bot-shipped',
    		create: true,
    		description: 'What kody-bot shipped since you last asked.',
    	})
    }

    Returns
    conversationId: 3k7n2p9q4r8w
    Tool conversation id; pass it back on subsequent search/execute calls.
    
    {
      "package_id": "pkg_kody_bot_shipped",
      "kody_id": "kody-bot-shipped",
      "created": true,
      "remote": "https://acct.artifacts.cloudflare.net/git/default/package-pkg_kody_bot_shipped.git",
      "authenticated_remote": "[REDACTED SECRET]",
      "git_extra_header": "[REDACTED SECRET]",
      "scope": "write",
      "expires_at": "2026-08-13T18:52:00.000Z",
      "git_author": {
        "name": "You",
        "email": "you@example.com"
      },
      "setup_commands": [
        "git -c http.extraHeader='Authorization: Bearer [REDACTED SECRET]' clone 'https://acct.artifacts.cloudflare.net/git/default/package-pkg_kody_bot_shipped.git' 'pkg_kody_bot_shipped'",
        "cd 'pkg_kody_bot_shipped'",
        "git config --local user.email -- 'you@example.com'",
        "git config --local user.name -- 'You'",
        "git remote add kody 'https://acct.artifacts.cloudflare.net/git/default/package-pkg_kody_bot_shipped.git'",
        "git config remote.kody.fetch '+refs/heads/*:refs/remotes/kody/*'",
        "git config --add remote.kody.fetch '+refs/notes/*:refs/notes/*'",
        "git -c http.extraHeader='Authorization: Bearer [REDACTED SECRET]' fetch kody 'refs/notes/*:refs/notes/*'",
        "git -c http.extraHeader='Authorization: Bearer [REDACTED SECRET]' push kody HEAD:'main'"
      ]
    }
  12. filesWrite the export in the temporary clone
    package.jsonExport only — no job yet
    {
      "name": "@you/kody-bot-shipped",
      "private": true,
      "exports": {
        "./whatShipped": "./src/what-shipped.ts"
      },
      "kody": {
        "id": "kody-bot-shipped",
        "description": "What kody-bot shipped since you last asked."
      }
    }
    README.mdWhy this package exists
    # kody-bot-shipped
    
    ## Intent
    
    Tell me what kody-bot shipped — published releases and new public repos —
    since I last asked.
    
    src/what-shipped.tsFilter public events and advance the cursor
    import { packageStorage } from 'kody:runtime'
    
    const login = 'kody-bot'
    const seenKey = 'lastSeenEventId'
    
    export default async function whatShipped() {
    	const storage = packageStorage()
    	const sinceId = (await storage.get(seenKey)) as string | null
    	const shipped = await listShipped(sinceId)
    	if (shipped[0]) await storage.set(seenKey, shipped[0].id)
    	return shipped.length === 0
    		? { shipped, message: 'Nothing new.' }
    		: { shipped, message: shipped.map((item) => item.title).join('\n') }
    }
    
    async function listShipped(sinceId: string | null) {
    	const response = await fetch(
    		`https://api.github.com/users/${login}/events/public`,
    		{
    			headers: {
    				Accept: 'application/vnd.github+json',
    				Authorization: 'Bearer {{secret:githubAccessToken}}',
    				'X-GitHub-Api-Version': '2022-11-28',
    			},
    		},
    	)
    	if (!response.ok) throw new Error(`GitHub ${response.status}`)
    	const events = (await response.json()) as Array<{
    		id: string
    		type: string
    		repo: { name: string }
    		payload: {
    			action?: string
    			ref_type?: string
    			release?: { tag_name?: string }
    		}
    	}>
    	const shipped = []
    	for (const event of events) {
    		if (sinceId && event.id === sinceId) break
    		if (
    			event.type === 'ReleaseEvent' &&
    			event.payload.action === 'published'
    		) {
    			shipped.push({
    				id: event.id,
    				kind: 'release',
    				title: `${event.repo.name} ${event.payload.release?.tag_name ?? 'release'}`,
    			})
    		}
    		if (
    			event.type === 'CreateEvent' &&
    			event.payload.ref_type === 'repository'
    		) {
    			shipped.push({
    				id: event.id,
    				kind: 'repository',
    				title: `New repo ${event.repo.name}`,
    			})
    		}
    	}
    	return shipped
    }
    
  13. executePublish Artifacts HEAD as the owned package
    conversationId
    "3k7n2p9q4r8w"
    memoryContext
    {
      "task": "What did my favorite bot ship recently on GitHub?",
      "entities": [
        "favorite bot"
      ]
    }
    code
    import { kody } from 'kody:runtime'
    
    export default async function main() {
    	return await kody.packagePublishExternalPush({
    		kody_id: 'kody-bot-shipped',
    	})
    }

    Returns
    conversationId: 3k7n2p9q4r8w
    Tool conversation id; pass it back on subsequent search/execute calls.
    
    {
      "status": "published",
      "previous_commit": "4c1a0e8b2d91",
      "published_commit": "7f3a91c2e8b4",
      "manifest": {
        "name": "@you/kody-bot-shipped",
        "private": true,
        "exports": {
          "./whatShipped": "./src/what-shipped.ts"
        },
        "kody": {
          "id": "kody-bot-shipped",
          "description": "What kody-bot shipped since you last asked."
        }
      },
      "checks": [
        {
          "kind": "manifest",
          "ok": true,
          "message": "ok"
        }
      ],
      "hosted_app_url": null,
      "static_dependents": {
        "total": 0,
        "items": []
      },
      "pending_secret_package_approvals": null
    }
  14. OpenClaw

    You now have `@you/kody-bot-shipped`. Ask again from any agent and I will invoke the export instead of walking GitHub by hand.

Later, on your phone with Grok Bot.

Ask again. Now safer, cheaper, and more reliable.

  1. You

    Anything interesting shipped by my favorite bot recently?

  2. Grok Bot

    Reasoning: I will search for a package that already answers this.

  3. searchFind the owned package, not a new GitHub walk
    memoryContext
    {
      "task": "Anything interesting shipped by my favorite bot recently?",
      "entities": [
        "favorite bot"
      ]
    }
    query
    "anything interesting shipped favorite bot"

    Returns
    conversationId: 5h8m2q7t1v4x
    Tool conversation id; pass it back on subsequent search/execute calls.
    
    # Search results
    
    For full detail on entity-backed hits, call `search` with `entity: "{id}:{type}"`.
    
    1. **package** @you/kody-bot-shipped (`kody-bot-shipped`) — What kody-bot shipped since you last asked. Entity: `kody-bot-shipped:package`
    
    ## Relevant memories
    
    - **Favorite bot** — kody-bot is my favorite bot. I'm really interested in what it ships on github
    executeInvoke the export — no model rewriting the filter
    conversationId
    "5h8m2q7t1v4x"
    memoryContext
    {
      "task": "Anything interesting shipped by my favorite bot recently?",
      "entities": [
        "favorite bot"
      ]
    }
    code
    import whatShipped from 'kody:@you/kody-bot-shipped/whatShipped'
    
    export default async function main() {
    	return await whatShipped()
    }

    Returns
    conversationId: 5h8m2q7t1v4x
    Tool conversation id; pass it back on subsequent search/execute calls.
    
    {
      "shipped": [],
      "message": "Nothing new."
    }
    
    ## Relevant memories
    
    - **Favorite bot** — kody-bot is my favorite bot. I'm really interested in what it ships on github
  4. Grok Bot

    Nothing interesting has shipped.

Later still, with Amp.

Ask to be notified.

  1. You

    Update me when kody-bot does something.

  2. Amp

    Reasoning: I will search for how to notify you when this package has something new.

  3. searchFind how to notify when the export has news
    memoryContext
    {
      "task": "Update me when kody-bot does something.",
      "entities": [
        "kody-bot"
      ]
    }
    query
    "notify when github user ships"

    Returns
    conversationId: 8w3k6n1p5r9t
    Tool conversation id; pass it back on subsequent search/execute calls.
    
    # Search results
    
    For full detail on entity-backed hits, call `search` with `entity: "{id}:{type}"`.
    
    1. **guide** Durable package lifecycle guide — Choose reuse vs temporary execute vs a new durable package. Entity: `package_lifecycle:guide`
    2. **capability** `webhookUrlMint` (`webhooks`) — Mint an inbound webhook URL for a package-declared webhook. Entity: `webhookUrlMint:capability`
    3. **capability** `jobList` (`jobs`) — List scheduled jobs for the signed-in user. Entity: `jobList:capability`
    
    ## Relevant memories
    
    - **Favorite bot** — kody-bot is my favorite bot. I'm really interested in what it ships on github
    searchOpen the package lifecycle guide
    conversationId
    "8w3k6n1p5r9t"
    entity
    "package_lifecycle:guide"

    Returns
    conversationId: 8w3k6n1p5r9t
    Tool conversation id; pass it back on subsequent search/execute calls.
    
    # Guide — `package_lifecycle`
    
    Choose between invoking existing behavior, temporary execute exploration, and creating a durable repo-backed package.
    
    ## Summary
    
    - Entity: `package_lifecycle:guide`
    - Category: `platform`
    - Web: `/docs/package-lifecycle`
    
    # Durable package lifecycle
    
    Use this guide to decide whether to reuse existing behavior, explore with `execute`, or create durable repo-backed package code. Use it before scheduling new package behavior.
    
    ## Choose the smallest durable surface
    
    
  4. Amp

    Reasoning: Inbound webhooks are URLs I host, not a GitHub feed of one person’s public activity. Recurring schedules belong on a package under `kody.jobs`. I will open a repo session, patch in a daily cron wrapper, test it, then enable the job.

  5. executePatch the package in a repo session, job left off
    conversationId
    "8w3k6n1p5r9t"
    memoryContext
    {
      "task": "Update me when kody-bot does something.",
      "entities": [
        "kody-bot"
      ]
    }
    code
    import { kody } from 'kody:runtime'
    
    const dailyDigest = `import { kody } from 'kody:runtime'
    import whatShipped from './what-shipped.ts'
    
    export default async function dailyDigest() {
    	const result = await whatShipped()
    	if (result.shipped.length === 0) return { emailed: false }
    	await kody.emailSend({
    		subject:
    			result.shipped.length === 1
    				? 'kody-bot shipped something'
    				: \`kody-bot shipped \${result.shipped.length} things\`,
    		text: result.message,
    	})
    	return { emailed: true, count: result.shipped.length }
    }
    `
    
    export default async function main() {
    	const session = await kody.repoOpenSession({
    		target: { kind: 'package', kody_id: 'kody-bot-shipped' },
    		conversation_id: '8w3k6n1p5r9t',
    	})
    	await kody.repoEditFiles({
    		session_id: session.id,
    		edits: [
    			{
    				kind: 'write',
    				path: 'src/daily-digest.ts',
    				content: dailyDigest,
    			},
    			{
    				kind: 'replace',
    				path: 'package.json',
    				search: '    "./whatShipped": "./src/what-shipped.ts"',
    				replacement:
    					'    "./whatShipped": "./src/what-shipped.ts",\n    "./daily-digest": "./src/daily-digest.ts"',
    			},
    			{
    				kind: 'replace',
    				path: 'package.json',
    				search: '    "description": "What kody-bot shipped since you last asked."',
    				replacement: `    "description": "What kody-bot shipped since you last asked.",
        "jobs": {
          "daily-digest": {
            "entry": "./src/daily-digest.ts",
            "schedule": { "type": "cron", "expression": "0 8 * * *" },
            "timezone": "America/Denver",
            "enabled": false
          }
        }`,
    			},
    			{
    				kind: 'replace',
    				path: 'README.md',
    				search: 'since I last asked.',
    				replacement:
    					'since I last asked. Email me only when that list is not empty.',
    			},
    		],
    	})
    	await kody.repoCommit({
    		session_id: session.id,
    		message: 'Add a quiet daily digest job',
    	})
    	const checks = await kody.repoRunChecks({ session_id: session.id })
    	const published = await kody.repoPublishSession({
    		session_id: session.id,
    	})
    	return { session_id: session.id, checks, published }
    }

    Returns
    conversationId: 8w3k6n1p5r9t
    Tool conversation id; pass it back on subsequent search/execute calls.
    
    {
      "session_id": "rs_kody_bot_shipped",
      "checks": {
        "ok": true,
        "results": [
          {
            "kind": "manifest",
            "ok": true,
            "message": "ok"
          },
          {
            "kind": "typecheck",
            "ok": true,
            "message": "ok"
          }
        ],
        "manifest": {
          "name": "@you/kody-bot-shipped",
          "kody_id": "kody-bot-shipped",
          "description": "What kody-bot shipped since you last asked.",
          "has_app": false
        }
      },
      "published": {
        "status": "ok",
        "session_id": "rs_kody_bot_shipped",
        "published_commit": "c8e2b1a04f73",
        "message": "Published session to main."
      }
    }
    executeTest the no-argument wrapper the scheduler will call
    conversationId
    "8w3k6n1p5r9t"
    memoryContext
    {
      "task": "Update me when kody-bot does something.",
      "entities": [
        "kody-bot"
      ]
    }
    code
    import dailyDigest from 'kody:@you/kody-bot-shipped/daily-digest'
    
    export default async function main() {
    	return await dailyDigest()
    }

    Returns
    conversationId: 8w3k6n1p5r9t
    Tool conversation id; pass it back on subsequent search/execute calls.
    
    {
      "emailed": false
    }
    executeEnable the daily job after the wrapper succeeds
    conversationId
    "8w3k6n1p5r9t"
    memoryContext
    {
      "task": "Update me when kody-bot does something.",
      "entities": [
        "kody-bot"
      ]
    }
    code
    import { kody } from 'kody:runtime'
    
    export default async function main() {
    	const session = await kody.repoOpenSession({
    		target: { kind: 'package', kody_id: 'kody-bot-shipped' },
    		conversation_id: '8w3k6n1p5r9t',
    	})
    	await kody.repoEditFiles({
    		session_id: session.id,
    		edits: [
    			{
    				kind: 'replace',
    				path: 'package.json',
    				search: '"enabled": false',
    				replacement: '"enabled": true',
    			},
    		],
    	})
    	await kody.repoCommit({
    		session_id: session.id,
    		message: 'Enable the daily digest job',
    	})
    	const checks = await kody.repoRunChecks({ session_id: session.id })
    	const published = await kody.repoPublishSession({
    		session_id: session.id,
    	})
    	return { session_id: session.id, checks, published }
    }

    Returns
    conversationId: 8w3k6n1p5r9t
    Tool conversation id; pass it back on subsequent search/execute calls.
    
    {
      "session_id": "rs_kody_bot_shipped",
      "checks": {
        "ok": true,
        "results": [
          {
            "kind": "manifest",
            "ok": true,
            "message": "ok"
          },
          {
            "kind": "typecheck",
            "ok": true,
            "message": "ok"
          }
        ],
        "manifest": {
          "name": "@you/kody-bot-shipped",
          "kody_id": "kody-bot-shipped",
          "description": "What kody-bot shipped since you last asked.",
          "has_app": false
        }
      },
      "published": {
        "status": "ok",
        "session_id": "rs_kody_bot_shipped",
        "published_commit": "e1d9c70b3a26",
        "message": "Published session to main."
      }
    }
  6. Amp

    It will check every morning. If kody-bot shipped something, you get mail. If not, nothing hits your inbox.

Something shipped.

  1. Email

    kody-bot shipped 2 things

    kody-bot/lantern v1.4.1 kody-bot/quiet-days v0.1.0

The package

What your agents , , and wrote

Same implementation for “ask again” and the morning job. The job calls emailSend only when the list is not empty.

package.jsonExport plus a daily job
{
  "name": "@you/kody-bot-shipped",
  "private": true,
  "exports": {
    "./whatShipped": "./src/what-shipped.ts",
    "./daily-digest": "./src/daily-digest.ts"
  },
  "kody": {
    "id": "kody-bot-shipped",
    "description": "What kody-bot shipped since you last asked.",
    "jobs": {
      "daily-digest": {
        "entry": "./src/daily-digest.ts",
        "schedule": { "type": "cron", "expression": "0 8 * * *" },
        "timezone": "America/Denver",
        "enabled": true
      }
    }
  }
}
README.mdWhy this package exists
# kody-bot-shipped

## Intent

Tell me what kody-bot shipped — published releases and new public repos —
since I last asked. Email me only when that list is not empty.
AGENTS.mdImports, smoke tests, and edge cases
# kody-bot-shipped

## Imports

```ts
import whatShipped from 'kody:@you/kody-bot-shipped/whatShipped'
```

## Smoke tests

Call `whatShipped` from `execute` after publish. The daily job wrapper
sends mail only when that list is not empty.

## Edge cases

A quiet day must skip email. The `lastSeenEventId` cursor lives in
`packageStorage()`.
src/what-shipped.tsFilter public events and advance the cursor
import { packageStorage } from 'kody:runtime'

const login = 'kody-bot'
const seenKey = 'lastSeenEventId'

export default async function whatShipped() {
	const storage = packageStorage()
	const sinceId = (await storage.get(seenKey)) as string | null
	const shipped = await listShipped(sinceId)
	if (shipped[0]) await storage.set(seenKey, shipped[0].id)
	return shipped.length === 0
		? { shipped, message: 'Nothing new.' }
		: { shipped, message: shipped.map((item) => item.title).join('\n') }
}

async function listShipped(sinceId: string | null) {
	const response = await fetch(
		`https://api.github.com/users/${login}/events/public`,
		{
			headers: {
				Accept: 'application/vnd.github+json',
				Authorization: 'Bearer {{secret:githubAccessToken}}',
				'X-GitHub-Api-Version': '2022-11-28',
			},
		},
	)
	if (!response.ok) throw new Error(`GitHub ${response.status}`)
	const events = (await response.json()) as Array<{
		id: string
		type: string
		repo: { name: string }
		payload: {
			action?: string
			ref_type?: string
			release?: { tag_name?: string }
		}
	}>
	const shipped = []
	for (const event of events) {
		if (sinceId && event.id === sinceId) break
		if (
			event.type === 'ReleaseEvent' &&
			event.payload.action === 'published'
		) {
			shipped.push({
				id: event.id,
				kind: 'release',
				title: `${event.repo.name} ${event.payload.release?.tag_name ?? 'release'}`,
			})
		}
		if (
			event.type === 'CreateEvent' &&
			event.payload.ref_type === 'repository'
		) {
			shipped.push({
				id: event.id,
				kind: 'repository',
				title: `New repo ${event.repo.name}`,
			})
		}
	}
	return shipped
}
src/daily-digest.tsSkip mail on a quiet day
import { kody } from 'kody:runtime'
import whatShipped from './what-shipped.ts'

export default async function dailyDigest() {
	const result = await whatShipped()
	if (result.shipped.length === 0) return { emailed: false }
	await kody.emailSend({
		subject:
			result.shipped.length === 1
				? 'kody-bot shipped something'
				: `kody-bot shipped ${result.shipped.length} things`,
		text: result.message,
	})
	return { emailed: true, count: result.shipped.length }
}

Working with an agent? This page is also plain markdown at /docs/how-kody-works.md, or load it over MCP with search({ entity: 'how_kody_works:guide' }).