Skip to content

Validate the csk_ API key prefix in the TS client - #37

Merged
rapguit merged 1 commit into
codespar:mainfrom
AndreLFSMartins:fix/core-validate-api-key-prefix
Jun 26, 2026
Merged

Validate the csk_ API key prefix in the TS client#37
rapguit merged 1 commit into
codespar:mainfrom
AndreLFSMartins:fix/core-validate-api-key-prefix

Conversation

@AndreLFSMartins

Copy link
Copy Markdown
Contributor

The Python client rejects API keys not starting with csk_ at construction. The TS CodeSpar constructor only checked for a non-empty key, so a malformed key failed late with an opaque HTTP error on the first request instead of a clear constructor error.

Adds the same csk_ prefix check to the TS constructor (both staging csk_ and prod csk_live_ share the prefix), restoring TS/Python parity with the documented contract.

Behavior change: a CodeSpar constructed with a non-csk_ key now throws at construction instead of on first request. Tests added for the reject and staging-key-accept paths.

npm test + tsc --noEmit green for packages/core.

The Python client rejects keys not starting with csk_ at construction;
the TS CodeSpar constructor only checked for a non-empty key, so a
malformed key failed late with an opaque HTTP error instead of a clear
constructor error. Adds the same prefix check, restoring TS/Python
parity with the documented contract.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rapguit

rapguit commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Thanks for this, Andre — small surface, clean fix.

Verified locally:

  • Parity claim: confirmed against packages/python/src/codespar/_async_client.py:65 — same startswith("csk_") check, same csk_-required contract. The TS gap was real.
  • CLAUDE.md alignment: the repo already documents this as an invariant ("CodeSparConfig.apiKey must start with csk_ (staging) or csk_live_ (prod) — validated at construction"). PR makes the code match the doc.
  • Tests: full @codespar/sdk suite passes (80/80) with the change merged onto current main. tsc --noEmit clean.
  • Merge: applies cleanly on top of the post-feat(sdk): hosted test-mode SDK surface — mocks forwarding, structured errors, tool-result guards, OSS test-parity seam #54 main.

Behavior-change call-out in the PR body is appropriate — failing fast at construction with a clear message is strictly an improvement over the opaque first-request HTTP error, and the staging/prod prefix split is handled correctly by checking csk_ as the common root.

Approving. Will let a maintainer trigger the workflows + merge.

@rapguit
rapguit merged commit 2d934de into codespar:main Jun 26, 2026
rapguit pushed a commit that referenced this pull request Jun 26, 2026
Per-session `projectId` is validated against `^prj_[A-Za-z0-9]{16}$`
(Zod schema in `types.ts`), but the **client-level** `projectId` was
passed straight to the `x-codespar-project` header with no validation —
in both the TS and Python clients. A malformed client-level scope
reached the backend instead of failing fast at construction.

- TS: extracts `PROJECT_ID_REGEX` in `types.ts` (now reused by the Zod
schema and the `CodeSpar` constructor).
- Python: adds the matching `_PROJECT_ID_RE` check to
`AsyncCodeSpar.__init__` (covers the sync client via its factory).
- Fixes three Python test fixtures in `test_session.py` that used
17-char ids (never validated before).

**Behavior change**: a client constructed with a malformed `projectId`
now throws at construction. Tests added (TS + Python).

`npm test` + `tsc --noEmit` green for `packages/core`; `pytest` + `mypy`
+ `ruff` green for `packages/python`.

Note: touches `packages/core/src/index.ts`, which also changes in #37 —
a trivial merge conflict on the constructor is expected if both land;
whichever merges second rebases.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants