Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kody/origin

README.md

162 lines · 6.3 KB · Markdown

@kody/origin

Intent

Give Kody agents a durable, secret-safe way to call the Cursor Origin REST API (repos, pull requests, installation discovery, and a raw request escape hatch) using an Origin App. Cloud Agents API keys are not Origin credentials.

This package mints short-lived app JWTs through secret_jwt_sign (EdDSA) and exchanges them for installation tokens. The Ed25519 private key never enters package or execute code. Writes default to dry-run and require confirm: true. Jobs are not enabled.

Share this listing at https://kody.codes/@kody/origin

What this package does

After you save an Origin App private key and app/installation ids, agents can:

  • Verify the Origin App rate-limit budget (rate-limit)
  • List installations and installation-visible repos
  • List or fetch repositories and pull requests
  • Preview or apply writes (repos create, pulls create/update/merge, raw request)
  • Persist app and installation ids in this package's storage (settings)

It does not create an Origin App for you, and it does not back Kody package source. Artifacts remains the durable home for Kody repos.

Setup

Follow coding_guide_get({ guide: "provider_origin" }). Origin Apps live at cursor.com/codebase/settings/apps.

  1. Create an Origin App and copy the app id (app_01…).
  2. Generate an Ed25519 key pair locally. Register only the public key on the app. Keep the PKCS#8 private key out of chat and out of git.
  3. Install the app into a codebase. After install, copy the installation id (i_01…).
  4. Save the private key in Kody (do not paste it in chat):
https://kody.codes/account/secrets/new?name=originAppPrivateKey&description=Origin%20App%20Ed25519%20PKCS%238%20private%20key&allowedHosts=api.cursor.com&allowedCapabilities=secret_jwt_sign&scope=user

Approve host api.cursor.com and capability secret_jwt_sign.

  1. Persist the readable ids with ./settings (confirm: true), or pass appId / installationId on each call. Leftover user values named originAppId / originInstallationId are copied into package storage on first read.

Default helper input: omit account, integrationName, and secretName. The package uses secret originAppPrivateKey and storage keys originAppId / originInstallationId.

There is no Origin OAuth lane. /connect/oauth is not used here.

Multiple Origin Apps

Every export accepts optional account / integrationName (default origin) and secretName. Extra apps use a distinct namespace — for example origin-work — which reads secret originAppPrivateKey-origin-work and storage keys originAppId-origin-work / originInstallationId-origin-work. Or pass secretName explicitly.

import getOriginRateLimit from 'kody:@kody/origin/rate-limit'

export default async function main() {
	return await getOriginRateLimit({ integrationName: 'origin-work' })
}

account is accepted as an alias for integrationName. There are no hard-coded personal aliases. When more than one installation is visible and none is saved, helpers throw instead of picking one.

Mutations and dryRun

Create/update/merge helpers, settings writes, and REST methods other than GET / HEAD / OPTIONS require:

  • dryRun: true — validate and return a preview; Origin is not written
  • confirm: true — perform the live write
import { createOriginPull } from 'kody:@kody/origin/pulls'

export default async function main() {
	return await createOriginPull({
		ownerSlug: 'example-owner',
		repoName: 'example',
		title: 'Example',
		head: 'topic',
		base: 'main',
		dryRun: true,
	})
}

Internal installation-token minting is auth, not a caller-facing mutation.

Smoke tests

Run these from execute after the secret exists. Prefer a static kody:@kody/origin import — packages.invoke({ kodyId: "origin" }) may resolve a different origin package.

Package overview (no credentials)
import describeOrigin from 'kody:@kody/origin'

export default async function main() {
	return await describeOrigin()
}

A successful response includes package: "@kody/origin" and secretSetupUrl.

Rate limit (Origin App)
import getOriginRateLimit from 'kody:@kody/origin/rate-limit'

export default async function main() {
	return await getOriginRateLimit()
}

A 401 that says the request is missing a Bearer token usually means Origin did not accept the credential kind — confirm you are signing with the Origin App private key, not cursorApiKey.

Mutation preview
import originRequest from 'kody:@kody/origin/request'

export default async function main() {
	return await originRequest({
		method: 'POST',
		path: '/repos/example-owner',
		body: { name: 'example' },
		dryRun: true,
	})
}

Exports

  • kody:@kody/origin — package overview and setup URLs
  • kody:@kody/origin/accounts — Origin App lane and multi-account guidance
  • kody:@kody/origin/rate-limit — zero-cost rate-limit smoke test
  • kody:@kody/origin/auth — sign an app JWT / mint an installation token (no token value)
  • kody:@kody/origin/installations — list installations and installation repos
  • kody:@kody/origin/repos — list, get, or create repositories (create is dryRun / confirm)
  • kody:@kody/origin/pulls — list, get, create, update, or merge pull requests (writes are dryRun / confirm)
  • kody:@kody/origin/request — raw /v1/origin request helper
  • kody:@kody/origin/settings — read or persist app / installation ids
  • kody:@kody/origin/migrate-from-values — copy leftover user values into package storage
  • kody:@kody/origin/types — shared TypeScript types

Notes

  • Origin tokens last at most 15 minutes. This package mints them per call.
  • Repositories Origin mirrors in from GitHub are outside the installation.
  • Native Origin repos and repos Origin mirrors out to GitHub are in scope.
  • Artifacts remains the durable home for Kody package source.

Branding

community-icon.svg is Cursor's official cube mark (white cube on black). Cursor and Origin are trademarks of Anysphere, Inc. This package is not affiliated with or endorsed by Cursor.

Docs