Skip to content

Commit b4a18bd

Browse files
docs: update for Docker-first deployment and dual license (#28)
* docs: update for Docker-first deployment and dual license - Add Quick Start section to root README with docker run command - Restructure docs/README.md: pre-built image first, build from source as alternative - Update SDK README with gateway quick start and absolute GitHub links - Update gateway README to mention both pre-built and source options - Rename "Local Development" to "Building from Source" in docker-deployment.md - Fix license references: dual-licensed (AGPL-3.0 or commercial) - Update package.json license fields to "SEE LICENSE IN LICENSE" * docs: add OpenAPI docs endpoint and scripts - Update api-reference.md to reference /docs (Scalar UI) and /openapi.yaml - Add openapi:generate and openapi:check scripts to CONTRIBUTING.md * fix(test): make health route tests deterministic Replace setTimeout with polling pattern that waits until spawn is called before emitting mock events. Fixes flaky CI failures where events fired before listeners were attached. * fix(test): add timeout safeguard to afterSpawnCalled helper Makes test failures clearer by throwing explicit error after ~1 second instead of waiting for vitest's 10-second timeout.
1 parent 7e79949 commit b4a18bd

File tree

10 files changed

+99
-65
lines changed

10 files changed

+99
-65
lines changed

CONTRIBUTING.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ We're eager for collaborators! This project is in early stages and there's plent
66

77
```bash
88
bun install
9-
bun run dev # Start gateway with hot reload
10-
bun run test # Run tests
11-
bun run lint # Lint check
9+
bun run dev # Start gateway with hot reload
10+
bun run test # Run tests
11+
bun run lint # Lint check
12+
bun run openapi:generate # Regenerate OpenAPI spec
13+
bun run openapi:check # Verify spec is up to date
1214
```
1315

1416
## Pre-commit Hooks

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ Koine turns Claude Code into a programmable inference layer. Use it to:
4040
- **Run on internal networks** — VPN or Docker networks are ideal for service-to-service communication
4141
- **Authenticate all requests** — the gateway requires an API key separate from Claude authentication
4242

43+
## Quick Start
44+
45+
```bash
46+
docker run -d -p 3100:3100 \
47+
-e CLAUDE_CODE_GATEWAY_API_KEY=your-key \
48+
-e CLAUDE_CODE_OAUTH_TOKEN=your-token \
49+
ghcr.io/pattern-zones-co/koine:latest
50+
51+
curl http://localhost:3100/health
52+
```
53+
54+
See [Docker Deployment](docs/docker-deployment.md) for version pinning, docker-compose setup, and production configuration.
55+
4356
## Documentation
4457

4558
| Guide | Description |
@@ -61,7 +74,7 @@ Koine turns Claude Code into a programmable inference layer. Use it to:
6174

6275
## License
6376

64-
See [LICENSE](LICENSE) for details (AGPL-3.0).
77+
Dual-licensed under AGPL-3.0 or commercial license. See [LICENSE](LICENSE) for details.
6578

6679
## Contributing
6780

docs/README.md

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,29 @@
1111

1212
## Getting Started
1313

14+
```bash
15+
docker run -d -p 3100:3100 \
16+
-e CLAUDE_CODE_GATEWAY_API_KEY=your-key \
17+
-e CLAUDE_CODE_OAUTH_TOKEN=your-token \
18+
ghcr.io/pattern-zones-co/koine:latest
19+
20+
curl http://localhost:3100/health
21+
```
22+
23+
See [Docker Deployment](docker-deployment.md) for docker-compose setup, version pinning, and production configuration.
24+
25+
### From Source
26+
27+
Alternatively, clone and build from source:
28+
1429
```bash
1530
git clone https://github.com/pattern-zones-co/koine.git
1631
cd koine
1732

1833
cp .env.example .env
1934
# Edit .env with your keys
2035

21-
docker compose up -d koine
22-
```
23-
24-
Verify it's running:
25-
26-
```bash
27-
curl http://localhost:3100/health
36+
docker compose up -d
2837
```
2938

3039
### Usage

docs/api-reference.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# API Reference
22

3-
> **TODO**: Generate OpenAPI spec from Zod schemas. See [#17](https://github.com/pattern-zones-co/koine/issues/17).
3+
The gateway provides interactive API documentation at [`/docs`](http://localhost:3100/docs) powered by [Scalar](https://scalar.com/). The raw OpenAPI 3.1 specification is available at [`/openapi.yaml`](http://localhost:3100/openapi.yaml).
44

55
## Authentication
66

@@ -16,6 +16,8 @@ curl -H "Authorization: Bearer $CLAUDE_CODE_GATEWAY_API_KEY" \
1616
| Method | Path | Description |
1717
|--------|------|-------------|
1818
| GET | `/health` | Health check (no auth) |
19+
| GET | `/docs` | Interactive API docs (no auth) |
20+
| GET | `/openapi.yaml` | OpenAPI spec (no auth) |
1921
| POST | `/generate-text` | Generate text |
2022
| POST | `/generate-object` | Extract structured JSON |
2123
| POST | `/stream` | Stream via SSE |

docs/docker-deployment.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ Available version formats:
3232
- `1` - Latest minor/patch of major version
3333
- `latest` - Most recent release (default)
3434

35-
## Local Development
35+
## Building from Source
3636

3737
Build from source using the dev profile:
3838

3939
```bash
4040
docker compose --profile dev up --build
4141
```
4242

43-
This uses `koine-dev` service which builds locally from the Dockerfile.
43+
This uses the `koine-dev` service which builds locally from the Dockerfile. See [CONTRIBUTING.md](../CONTRIBUTING.md) for development setup.
4444

4545
## Configuration
4646

packages/gateway/README.md

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@
22

33
HTTP gateway that exposes [Claude Code CLI](https://github.com/anthropics/claude-code) as a REST API.
44

5-
This package is not published to npm. Deploy via Docker from the [repository root](../../README.md).
5+
This package is not published to npm. Deploy via Docker (pre-built or from source).
66

7-
## Deployment
7+
## Quick Start
88

99
```bash
10-
git clone https://github.com/pattern-zones-co/koine.git
11-
cd koine
12-
13-
cp .env.example .env
14-
# Edit .env with your keys
15-
16-
docker compose up -d koine
10+
docker run -d -p 3100:3100 \
11+
-e CLAUDE_CODE_GATEWAY_API_KEY=your-key \
12+
-e CLAUDE_CODE_OAUTH_TOKEN=your-token \
13+
ghcr.io/pattern-zones-co/koine:latest
1714
```
1815

16+
See [Docker Deployment](../../docs/docker-deployment.md) for docker-compose setup, version pinning, and production configuration.
17+
1918
## Documentation
2019

2120
- [Getting Started](../../docs/README.md)

packages/gateway/__tests__/routes/health.test.ts

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,24 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
1111
import healthRouter from "../../src/routes/health.js";
1212
import { createMockChildProcess } from "../helpers.js";
1313

14+
/** Schedule callback after spawn is called (non-blocking) */
15+
function afterSpawnCalled(
16+
mockSpawn: ReturnType<typeof vi.fn>,
17+
callback: () => void,
18+
): void {
19+
let iterations = 0;
20+
const check = () => {
21+
if (mockSpawn.mock.calls.length > 0) {
22+
callback();
23+
} else if (iterations++ < 1000) {
24+
setTimeout(check, 1);
25+
} else {
26+
throw new Error("Timeout waiting for spawn to be called");
27+
}
28+
};
29+
check();
30+
}
31+
1432
// Mock node:child_process
1533
vi.mock("node:child_process", () => ({
1634
spawn: vi.fn(),
@@ -42,11 +60,11 @@ describe("Health Route", () => {
4260
const app = createTestApp();
4361
const responsePromise = request(app).get("/health");
4462

45-
// Simulate successful claude --version
46-
setTimeout(() => {
63+
// Simulate successful claude --version after spawn is called
64+
afterSpawnCalled(mockSpawn, () => {
4765
mockProc.exitCode = 0;
4866
mockProc.emit("close", 0, null);
49-
}, 10);
67+
});
5068

5169
const res = await responsePromise;
5270

@@ -65,11 +83,11 @@ describe("Health Route", () => {
6583
const app = createTestApp();
6684
const responsePromise = request(app).get("/health");
6785

68-
// Simulate failed claude --version
69-
setTimeout(() => {
86+
// Simulate failed claude --version after spawn is called
87+
afterSpawnCalled(mockSpawn, () => {
7088
mockProc.exitCode = 1;
7189
mockProc.emit("close", 1, null);
72-
}, 10);
90+
});
7391

7492
const res = await responsePromise;
7593

@@ -88,10 +106,10 @@ describe("Health Route", () => {
88106
const app = createTestApp();
89107
const responsePromise = request(app).get("/health");
90108

91-
// Simulate spawn error (e.g., command not found)
92-
setTimeout(() => {
109+
// Simulate spawn error (e.g., command not found) after spawn is called
110+
afterSpawnCalled(mockSpawn, () => {
93111
mockProc.emit("error", new Error("ENOENT"));
94-
}, 10);
112+
});
95113

96114
const res = await responsePromise;
97115

@@ -107,10 +125,10 @@ describe("Health Route", () => {
107125
const responsePromise = request(app).get("/health");
108126

109127
// Simulate successful response so the request completes
110-
setTimeout(() => {
128+
afterSpawnCalled(mockSpawn, () => {
111129
mockProc.exitCode = 0;
112130
mockProc.emit("close", 0, null);
113-
}, 10);
131+
});
114132

115133
await responsePromise;
116134

@@ -155,10 +173,10 @@ describe("Health Route", () => {
155173
const responsePromise = request(app).get("/health");
156174

157175
// CLI completes successfully - this should cancel the 5s timeout
158-
setTimeout(() => {
176+
afterSpawnCalled(mockSpawn, () => {
159177
mockProc.exitCode = 0;
160178
mockProc.emit("close", 0, null);
161-
}, 10);
179+
});
162180

163181
const res = await responsePromise;
164182

packages/gateway/package.json

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,7 @@
4949
"node": "22.21.1",
5050
"bun": "1.3.3"
5151
},
52-
"keywords": [
53-
"claude",
54-
"claude-code",
55-
"anthropic",
56-
"ai",
57-
"gateway",
58-
"api"
59-
],
60-
"license": "AGPL-3.0",
61-
"files": [
62-
"dist",
63-
"README.md"
64-
]
52+
"keywords": ["claude", "claude-code", "anthropic", "ai", "gateway", "api"],
53+
"license": "SEE LICENSE IN LICENSE",
54+
"files": ["dist", "README.md"]
6555
}

packages/sdks/typescript/README.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
# @patternzones/koine-sdk
22

3-
TypeScript SDK for [Koine](../../../README.md) — the HTTP gateway for Claude Code CLI.
3+
TypeScript SDK for [Koine](https://github.com/pattern-zones-co/koine) — the HTTP gateway for Claude Code CLI.
4+
5+
## Running the Gateway
6+
7+
```bash
8+
docker run -d -p 3100:3100 \
9+
-e CLAUDE_CODE_GATEWAY_API_KEY=your-key \
10+
-e CLAUDE_CODE_OAUTH_TOKEN=your-token \
11+
ghcr.io/pattern-zones-co/koine:latest
12+
```
13+
14+
See [Docker Deployment](https://github.com/pattern-zones-co/koine/blob/main/docs/docker-deployment.md) for version pinning and production setup.
415

516
## Installation
617

@@ -57,7 +68,7 @@ console.log(result.text);
5768

5869
## Documentation
5970

60-
See the [SDK Guide](../../../docs/sdk-guide.md) for:
71+
See the [SDK Guide](https://github.com/pattern-zones-co/koine/blob/main/docs/sdk-guide.md) for:
6172

6273
- Configuration options
6374
- Streaming examples
@@ -67,4 +78,4 @@ See the [SDK Guide](../../../docs/sdk-guide.md) for:
6778

6879
## License
6980

70-
[AGPL-3.0](../../../LICENSE)
81+
Dual-licensed under [AGPL-3.0 or commercial license](https://github.com/pattern-zones-co/koine/blob/main/LICENSE).

packages/sdks/typescript/package.json

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,7 @@
4242
"node": "22.21.1",
4343
"bun": "1.3.3"
4444
},
45-
"keywords": [
46-
"claude",
47-
"claude-code",
48-
"anthropic",
49-
"ai",
50-
"sdk",
51-
"gateway"
52-
],
53-
"license": "AGPL-3.0",
54-
"files": [
55-
"dist",
56-
"README.md"
57-
]
45+
"keywords": ["claude", "claude-code", "anthropic", "ai", "sdk", "gateway"],
46+
"license": "SEE LICENSE IN LICENSE",
47+
"files": ["dist", "README.md"]
5848
}

0 commit comments

Comments
 (0)