{"id":50800744,"url":"https://github.com/ronhuafeng/codexsdk-go","last_synced_at":"2026-07-13T08:00:59.678Z","repository":{"id":365975684,"uuid":"1265769872","full_name":"ronhuafeng/codexsdk-go","owner":"ronhuafeng","description":"Unofficial Go SDK for the Codex app-server protocol","archived":false,"fork":false,"pushed_at":"2026-07-11T02:13:29.000Z","size":1445,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-11T04:09:03.141Z","etag":null,"topics":["app-server","codex","go","json-rpc","sdk"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ronhuafeng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-11T04:15:52.000Z","updated_at":"2026-07-11T02:12:31.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ronhuafeng/codexsdk-go","commit_stats":null,"previous_names":["ronhuafeng/codexsdk-go"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/ronhuafeng/codexsdk-go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronhuafeng%2Fcodexsdk-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronhuafeng%2Fcodexsdk-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronhuafeng%2Fcodexsdk-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronhuafeng%2Fcodexsdk-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ronhuafeng","download_url":"https://codeload.github.com/ronhuafeng/codexsdk-go/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ronhuafeng%2Fcodexsdk-go/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35414732,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-13T02:00:06.543Z","response_time":119,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["app-server","codex","go","json-rpc","sdk"],"created_at":"2026-06-12T19:30:51.392Z","updated_at":"2026-07-13T08:00:59.662Z","avatar_url":"https://github.com/ronhuafeng.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# codexsdk-go\n\nGo client and generated protocol types for the Codex app-server JSON-RPC\nprotocol.\n\nThis project is unofficial and experimental. It is not an OpenAI product, is\nnot supported by OpenAI, and may lag or diverge from the Codex CLI/app-server\nimplementation. Use it when you want a small Go SDK that talks to a locally\nlaunched Codex app-server over stdio.\n\n## Status\n\n- License: MIT for this repository.\n- Upstream protocol source: OpenAI Codex, Apache-2.0, generated from the\n  app-server schema baseline recorded in\n  `codexsdk/internal/protocolschema/appserver/v2/baseline_metadata.json`.\n- API stability: pre-1.0. Public APIs are intended to be useful and reviewed,\n  but breaking changes can happen before v1.0.\n- Current stable release: `v0.4.0`.\n- Runtime requirement: the SDK launches an external `codex app-server` command.\n  Unit tests and CI do not require a local Codex binary.\n\nThe pre-v1 API uses a concrete root client, exported concrete opaque generated\nfacades, consumer-owned narrow interfaces, and manifest-classified stable\nversus experimental generated compatibility.\nSee [Pre-v1 Public API Boundary](docs/public-api-boundary.md).\nFor the concrete generated-facade migration, see the\n[v0.4 migration guide](docs/v0.4-migration.md).\n\n## Packages\n\n- `codexsdk`: stdio client, generated typed facades, exact `ThreadRunner`, exact\n  notification streaming, and generated server-request handling.\n- `codexsdk/protocolv2`: generated app-server v2 params, responses,\n  notifications, enums, unions, JSON helpers, and method registry.\n- `codexsdk/internal/protocolgen`: generator internals for the checked-in schema\n  baseline.\n- `codexsdk/internal/protocolschema/appserver/v2`: reviewed schema baseline,\n  classified manifest, coverage matrix, drift report, and provenance metadata.\n\n## Installation\n\n```sh\ngo get github.com/ronhuafeng/codexsdk-go@v0.4.0\n```\n\nThe module targets Go 1.23 or newer.\n\nTo run against a real app-server, install Codex CLI separately and make sure\n`codex` is on `PATH`:\n\n```sh\ncodex --version\n```\n\n## Quick Start: Typed Client\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/ronhuafeng/codexsdk-go/codexsdk\"\n\t\"github.com/ronhuafeng/codexsdk-go/codexsdk/protocolv2\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\tworkspace, err := os.Getwd()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tclient, err := codexsdk.New(codexsdk.ClientOptions{\n\t\tCWD:     workspace,\n\t\tCommand: []string{\"codex\", \"app-server\", \"--listen\", \"stdio://\"},\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer client.Close()\n\n\tresp, err := client.Models().List(ctx, protocolv2.ModelListParams{})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tlog.Printf(\"models: %d\", len(resp.Data))\n}\n```\n\n## Quick Start: Exact ThreadRunner\n\n`ThreadRunner` transparently composes exact generated `thread/start` and\n`turn/start` params. The result retains the exact start response, terminal turn,\nusage, and every attributable generated notification.\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/ronhuafeng/codexsdk-go/codexsdk\"\n\t\"github.com/ronhuafeng/codexsdk-go/codexsdk/protocolv2\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\tworkspace, err := os.Getwd()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tmodel := os.Getenv(\"CODEXSDK_EXAMPLE_MODEL\")\n\tif model == \"\" {\n\t\tlog.Fatal(\"set CODEXSDK_EXAMPLE_MODEL\")\n\t}\n\n\troot, err := codexsdk.New(codexsdk.ClientOptions{\n\t\tCWD:     workspace,\n\t\tCommand: []string{\"codex\", \"app-server\", \"--listen\", \"stdio://\"},\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer root.Close()\n\n\tresult, err := root.ThreadRunner().Start(ctx, codexsdk.StartThreadRunRequest{\n\t\tThread: protocolv2.ThreadStartParams{\n\t\t\tEphemeral: protocolv2.Value(true),\n\t\t\tModel:     protocolv2.Value(model),\n\t\t},\n\t\tTurn: protocolv2.TurnStartParams{\n\t\t\tInput: []protocolv2.UserInput{\n\t\t\t\tprotocolv2.NewUserInputText(protocolv2.UserInputText{\n\t\t\t\t\tText: \"Reply with a short confirmation.\",\n\t\t\t\t}),\n\t\t\t},\n\t\t},\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tlog.Println(result.Run.FinalResponse)\n}\n```\n\n`StartStream` and `ResumeStream` expose every exact\n`protocolv2.ServerNotification`; `Result` remains available on failures and\ncontains the latest immutable partial snapshot. More compile-checked examples\nlive in `codexsdk/examples_test.go`.\n\nA `thread/start` response that decodes but lacks a thread ID fails closed with\n`ErrMissingThreadID` before `turn/start`. `Start` returns the decoded\n`StartedThreadRun.Start` together with that error; `StartStream` returns a\nterminal stream whose `Wait` and `Result` expose the same isolated partial\nevidence. The malformed run is never registered, and the Client remains open.\n\nCall `Stream.Wait` when multiple consumers need to observe the same run without\ncoordinating ownership of `Next`. Any number of waiters can block independently\nand each receives an immutable result snapshot plus the run's stable terminal\nerror. A waiter's context bounds only that call: cancellation returns the latest\npartial snapshot with `ctx.Err()` without canceling the run or changing\n`Stream.Err`. Use `Stream.Close` for explicit shared run cancellation. `Next`\nuses a cursor over the same immutable ordered history retained by `Result`, so\n`Wait` does not need to consume notifications and cannot cause per-run\nbackpressure. `Next` context cancellation retains its shared-run cancellation\nsemantics. The separately configurable global notification-handler queue\nremains bounded.\n\nConfigure `ServerRequestHandler` when the application can provide generated\nresponse data. With no handler, the\nSDK immediately returns a generated fail-closed response for requests that\nhave a safe denial or empty-answer form. Requests requiring application data,\nincluding authentication refresh, dynamic tool output, and attestation, return\na JSON-RPC error and fail the exact run with `ErrExactServerRequest`; partial\nnotifications and run evidence remain available in the result.\n\nCallback admission is atomic with client shutdown. Once `Close` or failure\nshutdown closes admission, no new server-request or notification handler is\nstarted. Normal close cancels exact server-request handler contexts and joins\nevery callback accepted before that boundary before transport teardown;\nfailure shutdown cancels accepted callbacks immediately while preserving the\nfirst failure cause and partial run evidence. Handlers must return when their\ncontext is canceled and must not call `Close` reentrantly.\n\nThe removed v0.1 lifecycle and copied protocol models have no compatibility\naliases. See [the migration mapping](docs/v0.2-migration.md#removed-v01-mapping)\nfor exact replacements.\n\n## Real App-Server Smoke Test\n\nThe real smoke test is opt-in because it launches Codex, uses a configured\nmodel, and may create or consume account state.\n\n```sh\nCODEXSDK_REAL_APP_SERVER_SMOKE=1 \\\nCODEXSDK_REAL_APP_SERVER_MODEL=gpt-5-mini \\\ngo test ./codexsdk -run TestRealAppServerSmokeStartResumeFork -count=1\n```\n\nOptional command override:\n\n```sh\nCODEXSDK_REAL_APP_SERVER_COMMAND='codex app-server --listen stdio://' \\\nCODEXSDK_REAL_APP_SERVER_SMOKE=1 \\\nCODEXSDK_REAL_APP_SERVER_MODEL=gpt-5-mini \\\ngo test ./codexsdk -run TestRealAppServerSmokeStartResumeFork -count=1\n```\n\nNormal CI does not run this test.\n\n## Protocol V2 Schema Strategy\n\n`protocolv2` code is generated from a checked-in Codex app-server v2 schema\nbaseline, not by shelling out to Codex during normal builds. The baseline is\ntracked with:\n\n- `baseline_metadata.json`: upstream tag/ref name, target kind, peeled commit,\n  Codex version, generation command, source license, file count, and schema\n  bundle checksum.\n- `manifest.json`: classified method and exported generated Go surface,\n  request/notification direction, response schema mapping, facade target,\n  explicit generated/deferred facade status, and mechanically derived stable,\n  experimental, or mixed marking. A deferred facade is valid only while a\n  generated method constant or protocol type prerequisite is absent.\n- `coverage_matrix.json`: reviewed support status for methods, types, and key\n  fields.\n- `drift_report.json` and `matrix_update_skeleton.json`: last clean comparison\n  artifacts and the shape of follow-up review work when upstream changes.\n\nRegenerate Go code from the checked-in baseline:\n\n```sh\ngo run ./codexsdk/internal/cmd/protocolv2gen\n```\n\nCheck generated code reproducibility without modifying the tree:\n\n```sh\ngo run ./codexsdk/internal/cmd/protocolv2gen -stdout method-registry |\n  diff -u codexsdk/protocolv2/method_registry.gen.go -\ngo run ./codexsdk/internal/cmd/protocolv2gen -stdout protocol-types |\n  diff -u codexsdk/protocolv2/protocol_types.gen.go -\ntmp=\"$(mktemp -d)/sdk_surface.gen.go\"\npython3 scripts/codexsdk_generate_sdk_surface.py --out \"$tmp\"\ngofmt -w \"$tmp\"\ndiff -u codexsdk/sdk_surface.gen.go \"$tmp\"\n```\n\n## Maintenance\n\nUse the upstream tracking script to generate review artifacts for a Codex\nschema update. The script is read-only for the checked-in baseline unless a\nmaintainer copies reviewed files back into the SDK tree.\n\nCheck the target policy before generating drift artifacts. Scheduled automation\ntracks stable `rust-vX.Y.Z` tags only when the current baseline is already on\nthat stable tag track; manual commits and track switches must be explicit.\n\n```sh\npython3 scripts/codexsdk_target_policy.py \\\n  --baseline codexsdk/internal/protocolschema/appserver/v2/baseline_metadata.json \\\n  --target-ref rust-v0.140.0 \\\n  --target-kind stable_rust_tag \\\n  --target-sha \u003cpeeled-target-commit\u003e \\\n  --target-explicit true \\\n  --mode manual \\\n  --json\n```\n\n```sh\nscripts/codexsdk_track_upstream.sh \\\n  --codex-repo /path/to/openai/codex \\\n  --commit \u003cpeeled-target-commit\u003e \\\n  --source-ref rust-v0.140.0 \\\n  --source-ref-kind stable_rust_tag \\\n  --out /tmp/codexsdk-upstream\n```\n\nThen review the generated `reports/SUMMARY.md`, schema drift summary, and matrix\nupdate skeleton before updating the baseline, manifest, coverage matrix, and\ngenerated Go code. Keep handwritten SDK changes limited to reviewed public\nsurface or compatibility fixes. See `docs/release.md` for the release and\nschema baseline checklists.\n\nAfter committing a successful baseline sync, tag the codexsdk-go commit with an\nannotated upstream sync tag. These tags intentionally live outside the Go module\nrelease namespace.\n\n```sh\npython3 scripts/codexsdk_sync_tag.py --json\npython3 scripts/codexsdk_sync_tag.py --create --push origin --json\n```\n\nStable upstream Codex tags use `upstream-codex-rust-vX.Y.Z`. Existing upstream\nsync tags are never moved; use `--next-suffix` to create\n`upstream-codex-rust-vX.Y.Z-sync.N` for follow-up SDK fixes against the same\nupstream tag. Manual upstream commits and refs intentionally do not get fallback\nsync tags.\n\n## Compatibility Policy\n\nBefore v1.0, minor releases may include breaking changes when the upstream\nCodex app-server protocol changes or when the SDK corrects an unsafe public\nAPI. Patch releases should be backwards compatible except for security or data\ncorruption fixes.\n\nAfter v1.0, the project should follow SemVer for the public API in `codexsdk`\nand `codexsdk/protocolv2`. Generated `protocolv2` additions are usually minor\nchanges. Removing or changing generated types, method constants, or facade\nmethod signatures is a major change unless the upstream protocol removed the\nsurface and compatibility cannot be preserved safely.\n\n## Security\n\nDo not put API keys, account tokens, private workspaces, private schema dumps,\nor local absolute paths into issues, tests, schema metadata, or generated\nartifacts. The SDK starts a local app-server process and forwards requests over\nstdio; callers are responsible for choosing an appropriate Codex command,\nworking directory, approval policy, and server request handler.\n\nSee `SECURITY.md` for vulnerability reporting guidance.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronhuafeng%2Fcodexsdk-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fronhuafeng%2Fcodexsdk-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fronhuafeng%2Fcodexsdk-go/lists"}