Commit graph

14 commits

Author SHA1 Message Date
0d3ee26e24 clients/java: initial Java SDK for clawdforge
- Java 17, Maven, JDK java.net.http.HttpClient, Jackson 2.x
- ForgeClient (builder), records for RunResult / FileToken / AppToken / HealthStatus
- ApiException / AuthException / TransportException all extend ForgeException
  (RuntimeException) — checked exceptions feel un-modern in Java 17
- Multipart upload streams from disk via BodyPublishers.ofByteArrays
- 14 JUnit 5 tests against in-process com.sun.net.httpserver — zero test deps
  beyond JUnit
- mvn package / mvn test / mvn javadoc:javadoc clean
- snake_case wire format mapped to camelCase Java accessors via @JsonProperty
2026-04-28 22:49:06 -07:00
e4e8192d4d clients/swift: initial Swift SDK for clawdforge 2026-04-28 22:48:27 -07:00
15de6e765f clients/typescript: initial TypeScript SDK for clawdforge
Drop-in Node 18+ client with strict types, native fetch, AbortSignal
support, and a typed error hierarchy (ForgeAuthError / ForgeAPIError /
ForgeTransportError). Mirrors the existing Python client surface but
stays generic — no Sulkta-specific assumptions, suitable for anyone
running their own clawdforge instance.

- camelCase TS, snake_case wire — converted at the boundary
- node:test suite (17 tests) covering healthz, run success/error paths,
  502 envelopes, abort/timeout, file upload, and admin token CRUD
- tsc --noEmit clean with strict mode + Node16 module resolution
2026-04-28 22:42:46 -07:00
1cff9b89d2 clients/php: initial PHP SDK for clawdforge
PHP 8.2+ Guzzle-based client mirroring the Python SDK surface:

- Client::healthz / run / uploadFile / createToken / listTokens / revokeToken
- Readonly value objects: RunRequest, RunResult, FileToken, AppToken
- Exception hierarchy: ForgeException (abstract) -> ApiException ->
  AuthException, plus TransportException
- camelCase PHP <-> snake_case wire conversion at the boundary
- Streamed multipart uploads via fopen($path, 'r')
- Injectable GuzzleHttp\ClientInterface (MockHandler-friendly)
- HTTP timeout = subprocess timeout + 30s margin
- 15 PHPUnit tests, 61 assertions, no live network
- README with Laravel + WordPress integration snippets
- MIT license, no Sulkta-specific assumptions
2026-04-28 22:41:02 -07:00
093021cb36 clients/mcp: initial MCP server for clawdforge
Drops a Model Context Protocol server into clients/mcp/ that wraps the
clawdforge HTTP surface so MCP-aware clients (Claude Desktop, Claude Code,
Cursor, Zed, custom agents) can call it as a native tool — claude talking
to claude through the LAN bridge.

Three tools exposed:

  - clawdforge_healthz     -> GET /healthz
  - clawdforge_run         -> POST /run
  - clawdforge_upload_file -> POST /files

Admin endpoints intentionally NOT exposed; token minting stays human-gated.

Implementation notes:

  - Built on the official `mcp` Python SDK (>=1.0). asyncio-native server,
    stdio transport, low-level Server class with @list_tools / @call_tool
    handlers.
  - Self-contained `requests` HTTP wrapper rather than depending on the
    sibling clients/python SDK — keeps clawdforge-mcp installable
    standalone. Same error taxonomy (ForgeError / ForgeAPIError /
    ForgeAuthError / ForgeTransportError).
  - Sync HTTP calls offloaded via asyncio.to_thread so a slow `claude -p`
    can't stall the MCP event loop.
  - Errors are formatted into a single 'clawdforge error: ...' text block
    with isError=True; tracebacks never leak through the JSON-RPC pipe.
  - Logging goes to stderr (CLAWDFORGE_MCP_LOG=DEBUG to enable). stdout
    is reserved for JSON-RPC framing.
  - Config via env: CLAWDFORGE_URL (default http://localhost:8800) and
    CLAWDFORGE_TOKEN (required). MCP clients pass these via their `env`
    config block.

Tests: 12 unit tests covering tool discovery, healthz, run-success,
run-with-files, run-empty-prompt, run-subprocess-502, run-auth-401,
upload happy path, upload missing file, unknown tool, server factory.
HTTP layer mocked via `responses`. Plus a manual end-to-end stdio
smoke (initialize + tools/list round-trip) verified during build.

Includes ready-to-paste Claude Desktop and Claude Code config examples,
and a README documenting install, env, all three tools, and operational
notes (stdout-is-sacred, error wrapping, no streaming).
2026-04-28 22:37:08 -07:00
3c62613c30 clients/go: initial Go SDK for clawdforge
Idiomatic Go client wrapping the FastAPI surface in server.py — Healthz,
Run, UploadFile/UploadReader, and admin token CRUD. stdlib net/http only,
context-first signatures, typed errors (ErrAuth sentinel, RunFailure for
/run 502s, APIError for other 4xx/5xx, TransportError for network/EOF).

RunResult.Result is captured as json.RawMessage and materialized via
.AsJSON(out) / .AsText() because claude returns either parsed JSON or
plain text depending on prompt. UploadFile streams via io.Pipe + multipart
without buffering the file in memory.

Module: gitea.sulkta.com/Sulkta-Coop/clawdforge/clients/go
Includes cmd/cf-cli demo binary and httptest-based test suite (13 tests).
2026-04-28 22:36:56 -07:00
062d405a9e clients/rust: initial Rust SDK for clawdforge
Async client over reqwest+tokio with builder-pattern Client, serde
RunRequest/RunResult/FileToken/AppToken types, thiserror Error enum,
streaming multipart upload via tokio::fs::File, and 14 wiremock-backed
integration tests covering healthz, run-success-json, run-success-text,
run-502, run-with-files, file-upload, token mint/list/revoke, auth
failure, missing-token short-circuit, transport timeout, and builder
validation. Doc-tested. cargo test, cargo clippy --all-targets -D
warnings, and cargo build --examples all clean.
2026-04-28 22:35:16 -07:00
b1d6e3f697 clients/ruby: initial Ruby SDK for clawdforge 2026-04-28 22:34:01 -07:00
90e158f2fe clients/python: initial Python SDK for clawdforge
Sync requests-based SDK in clients/python/. Wraps /healthz, /run, /files,
and /admin/tokens behind a Forge class with typed exceptions
(ForgeError + Transport/API/Auth subclasses) and dataclass response shapes
(RunResult, FileToken, AppToken). HTTP timeout = run timeout + 30s margin,
matching the pattern cauldron has been running inline. No retries —
caller's job since /run isn't idempotent.

24 unit tests via responses, all passing. Install with
pip install -e clients/python/.
2026-04-28 22:27:21 -07:00
347fddea0f clients/bash: cf — single-file bash CLI for clawdforge
Tiny curl wrapper so cron jobs, deploy scripts, and shell pipes can drive
clawdforge without dragging in Python or Go.

Surface mirrors the server:
  cf healthz
  cf run "<prompt>"  [--model] [--system] [--timeout] [--files t1,t2]
  cf run -                                        # prompt via stdin (long prompts)
  cf upload <path>   [--ttl 3600]
  cf admin token-mint <name>   [--ip-cidrs cidr1,cidr2]
  cf admin token-list
  cf admin token-revoke <name>

Configuration via env or ~/.config/clawdforge/cf.env:
  CLAWDFORGE_URL, CLAWDFORGE_TOKEN, CLAWDFORGE_ADMIN_TOKEN

Output: JSON to stdout (pipe to jq freely), errors to stderr,
exit codes 0/1/2/3/4/5 mapping clearly to transport/usage/auth/4xx/5xx.

No deps beyond curl + POSIX tools. jq is optional (only used for prettier
error output if available).

Smoke-tested against live clawdforge on Lucy: healthz green, /run with
small prompt returns parsed JSON in 2-7s, /run with stdin large prompts
relies on clawdforge's server-side stdin path (>64KB), admin token-list
returns the cauldron token row.

Build/install:
  sudo install -m 755 clients/bash/cf /usr/local/bin/cf
2026-04-28 22:25:50 -07:00
8d1da6e20d runner: pipe prompts > 64KB via stdin to avoid OS argv limit
Cobb's seed-cleanup job hit OSError [Errno 7] Argument list too long with
a 577KB prompt. Linux ARG_MAX is typically 128KB-2MB depending on kernel +
env; passing the full prompt as 'claude -p <PROMPT>' fails for big jobs.

Fix: detect prompt size > 64KB threshold, omit the positional prompt
argument from the CLI invocation and pipe via subprocess.run(input=...)
instead. claude -p reads the prompt from stdin when no positional given.

System prompt + flags still pass as CLI args (those stay small).
2026-04-28 22:08:47 -07:00
1b4f62950b compose: pin project name to 'clawdforge' so it doesn't bleed into peer stacks 2026-04-28 17:10:39 -07:00
44a8fe743f v0.1 — clawdforge service scaffold
LAN-only HTTP service that runs claude -p subprocess on behalf of Sulkta apps.
Bearer token + IP allowlist gated. SQLite-backed token registry + run audit log.

- POST /run               run a prompt, return parsed result
- POST /files             upload a file, get a file_token to attach to /run
- POST /admin/tokens      mint per-app tokens (admin-bootstrap-token gated)
- GET  /admin/tokens      list, DELETE /admin/tokens/<name>  revoke
- GET  /healthz           liveness + claude --version smoke

Container = node:22 + npm-installed @anthropic-ai/claude-code + uvicorn/FastAPI
wrapper. Persistent volumes for /data (sqlite + run staging) and /root/.claude
(subscription auth — survives container rebuilds; auth via 'docker exec -it
clawdforge claude /login' once). Compose binds 192.168.0.5:8800 only — no
public proxy.

First consumer = cauldron (about to land).
2026-04-28 16:46:44 -07:00
a7be5a7702 Initial commit 2026-04-28 16:43:19 -07:00