{"id":49296373,"url":"https://github.com/tone4hook/headless-coding-agent-sdk","last_synced_at":"2026-04-26T04:01:14.349Z","repository":{"id":353513982,"uuid":"1219736689","full_name":"tone4hook/headless-coding-agent-sdk","owner":"tone4hook","description":"TypeScript SDK that unifies headless coding-agent CLIs (Claude Code, Gemini CLI) behind one I/O schema — spawn, stream events, and swap agents without rewriting your code.","archived":false,"fork":false,"pushed_at":"2026-04-24T07:19:56.000Z","size":179,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-24T09:33:16.802Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tone4hook.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-24T07:07:46.000Z","updated_at":"2026-04-24T07:19:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tone4hook/headless-coding-agent-sdk","commit_stats":null,"previous_names":["tone4hook/headless-coding-agent-sdk"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/tone4hook/headless-coding-agent-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tone4hook%2Fheadless-coding-agent-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tone4hook%2Fheadless-coding-agent-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tone4hook%2Fheadless-coding-agent-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tone4hook%2Fheadless-coding-agent-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tone4hook","download_url":"https://codeload.github.com/tone4hook/headless-coding-agent-sdk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tone4hook%2Fheadless-coding-agent-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32285283,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T18:29:39.964Z","status":"online","status_checked_at":"2026-04-26T02:00:05.962Z","response_time":129,"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":[],"created_at":"2026-04-26T04:01:13.319Z","updated_at":"2026-04-26T04:01:14.343Z","avatar_url":"https://github.com/tone4hook.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# headless-coding-agent-sdk\n\nTypeScript SDK that unifies headless coding-agent **CLI binaries**\nbehind one I/O schema. MVP targets:\n\n- `claude` — Claude Code in headless mode (`claude -p`)\n- `gemini` — Gemini CLI in headless mode (`gemini -p`)\n\nThis SDK wraps the CLIs only. It does **not** depend on any vendor JS\nSDK (`@anthropic-ai/*`, `@google/generative-ai`). Auth is whatever the\ninstalled CLI already has configured on your machine.\n\n## Installation\n\nThis package is published to **GitHub Packages**, so installing it requires a\none-time auth setup.\n\n1. Create a GitHub [Personal Access Token (classic)](https://github.com/settings/tokens)\n   with the `read:packages` scope.\n2. Add the following to `~/.npmrc` (or a project-level `.npmrc`), substituting\n   your token:\n\n   ```\n   @tone4hook:registry=https://npm.pkg.github.com\n   //npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN\n   ```\n\n3. Install:\n\n   ```sh\n   npm install @tone4hook/headless-coding-agent-sdk\n   # plus the CLI(s) you plan to use:\n   # npm install -g @anthropic-ai/claude-code\n   # npm install -g @google/gemini-cli\n   ```\n\n## 60-second quickstart\n\n```ts\nimport { createCoder } from '@tone4hook/headless-coding-agent-sdk';\n\nconst coder = createCoder('claude'); // or 'gemini'\nconst thread = await coder.startThread();\n\nconst result = await thread.run('Say hi in three words.');\nconsole.log(result.text);\nconsole.log(thread.id); // persistent session UUID — use with resumeThread()\n\nawait thread.close();\n```\n\n### Streaming\n\n```ts\nfor await (const ev of thread.runStreamed('plan a migration')) {\n  if (ev.type === 'message' \u0026\u0026 ev.role === 'assistant') process.stdout.write(ev.text ?? '');\n  if (ev.type === 'tool_use') console.error(`[tool] ${ev.name}`, ev.args);\n}\n```\n\n### Custom tools (works on both adapters)\n\n```ts\nimport { createCoder, tool } from '@tone4hook/headless-coding-agent-sdk';\n\nconst weather = tool({\n  name: 'get_weather',\n  description: 'Current temperature for coordinates',\n  inputSchema: { latitude: 'number', longitude: 'number' },\n  handler: async ({ latitude, longitude }: { latitude: number; longitude: number }) =\u003e ({\n    content: [{ type: 'text', text: `72°F at ${latitude},${longitude}` }],\n  }),\n});\n\nconst coder = createCoder('claude', {\n  tools: [weather],\n  permissionMode: 'bypassPermissions',\n});\n```\n\nBehind the scenes the SDK hosts a localhost MCP server per thread and\nwires each CLI to it — Claude via `--mcp-config`, Gemini via an\nephemeral `GEMINI_CLI_HOME` with merged settings.\n\n### Resume a prior session\n\n```ts\nconst coder = createCoder('claude');\nconst thread = await coder.resumeThread(previousThreadId);\n```\n\nBoth CLIs identify sessions by UUID.\n\n### Structured output\n\n```ts\nconst { json } = await thread.run('return {\"name\": \"...\", \"age\": N}', {\n  outputSchema: { type: 'object', properties: { name: { type: 'string' }, age: { type: 'number' } }, required: ['name', 'age'] },\n});\n```\n\nClaude validates server-side via `--json-schema`. Gemini best-efforts\nvia prompt injection; pass `strictSchema: true` to get a\n`FeatureNotSupportedError` instead of best-effort.\n\n## Design principle\n\nThe shared schema is not a lowest-common-denominator: features only one\nCLI supports (permission modes, `--fork-session`, `--json-schema`, etc.)\nremain accessible as optional fields. Adapters that don't honor a field\nthrow `FeatureNotSupportedError` at call time rather than silently\ndropping it.\n\nSee [`.plan/findings.md`](./.plan/findings.md) for the full design and\n[`docs/adapters.md`](./docs/adapters.md) for the per-adapter flag\ncoverage matrix.\n\n## Subpath imports\n\n```ts\nimport { createClaudeCoder } from '@tone4hook/headless-coding-agent-sdk/claude';\nimport { createGeminiCoder } from '@tone4hook/headless-coding-agent-sdk/gemini';\n```\n\n## Status\n\nPre-alpha. MVP feature set implemented; breaking API changes likely\nbefore 1.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftone4hook%2Fheadless-coding-agent-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftone4hook%2Fheadless-coding-agent-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftone4hook%2Fheadless-coding-agent-sdk/lists"}