Goal
Wire @codespar/sdk to formally depend on @codespar/session-contract. Re-export all contract types from the SDK's main entrypoint. Update createSession to construct CreateSessionRequest explicitly. Convert loop(), tools(), and findTools() from interface methods to free functions. Add null-guards to @codespar/mcp. Update all fakeSession() mocks across the repo. Bump all affected packages to 0.3.0.
This is the largest issue in the milestone. All changes follow a mechanical pattern — the scope is wide but the transformations are uniform.
Context
The previous issue extracted the shared session contract types into @codespar/session-contract. This issue completes the wiring: the SDK formally declares the dependency, re-exports the contract types, and all internal code is updated to use the new shapes.
Key facts:
SessionBase is the narrower interface (no mcp transport, no proxyExecute, no authorize). It covers what all runtimes guarantee.
Session extends SessionBase adds the MCP transport fields and the managed-runtime methods.
mcp is now optional on Session — callers and internal code that access session.mcp unconditionally will get a TypeScript type error until they add a null-guard.
loop(), tools(), and findTools() were interface methods. They must become free functions accepting SessionBase so they work with any conforming runtime, not just the SDK's concrete implementation.
The TypeScript compiler will surface every broken call site as a type error. Fix all of them before marking this issue complete.
Acceptance Criteria
1. SDK package.json — add runtime dependency
packages/core/package.json lists @codespar/session-contract in dependencies (not devDependencies).
"dependencies": {
"@codespar/session-contract": "*"
}
If @codespar/session-contract was temporarily added as a devDependency or workspace link while extracting the types, remove that entry and replace it with the dependencies entry above.
2. Re-export from SDK main entrypoint
packages/core/src/index.ts includes a re-export of all contract types:
export * from "@codespar/session-contract";
This must appear early in the file (before SDK-specific exports). Callers who import Session, SessionBase, StreamEvent, CreateSessionRequest, or any other contract type from @codespar/sdk continue to receive them without changing their import paths.
3. createSession uses CreateSessionRequest explicitly
Inside the createSession factory in packages/core/src/session.ts, the object posted to /v1/sessions is constructed as a typed CreateSessionRequest:
const req: CreateSessionRequest = {
servers: config.servers ?? presetToServers(config.preset),
metadata: config.metadata,
projectId: config.projectId ?? deps.projectId,
};
SessionConfig (the SDK-level input type) retains the SDK-specific fields: preset, manageConnections, apiKey, baseUrl. Only the fields that cross the wire move into CreateSessionRequest.
4. loop, tools, findTools are free functions
These three functions are moved from interface methods to free functions in their own modules:
// packages/core/src/loop.ts
export function loop(session: SessionBase, options?: LoopOptions): Promise<LoopResult>
// packages/core/src/tools.ts
export function tools(session: SessionBase): Promise<McpTool[]>
export function findTools(session: SessionBase, query: string): Promise<McpTool[]>
All call sites in the repo that use session.loop(), session.tools(), or session.findTools() must be updated to the free-function form: loop(session), tools(session), findTools(session, query).
Search the entire repo for these patterns before removing the interface methods. Both the method definitions on the interface and any concrete class implementations must be removed.
5. Null-guard in @codespar/mcp
mcp is now typed as optional on Session. The @codespar/mcp package has call sites that access session.mcp.url and session.mcp.headers unconditionally. Every such site must add a guard:
if (!session.mcp) {
throw new Error("session does not expose an MCP transport endpoint");
}
The exact error message may vary by call site context, but must be descriptive. The TypeScript compiler will flag all 4 sites as type errors after the type change — the criterion is zero type errors in @codespar/mcp after this issue.
Do not use non-null assertions (!) as a workaround. The guard must be explicit.
6. All fakeSession() mocks updated
Search for fakeSession across the entire repo. Every mock object must satisfy the structural split:
- Mocks typed against
Session retain proxyExecute and authorize.
- Mocks typed against
SessionBase may omit those fields.
- All mocks include the
SessionBase methods: whatever SessionBase declares must be present.
No mock should cause a TypeScript type error after this issue.
7. Version bumps
The following packages are bumped to 0.3.0:
@codespar/sdk (packages/core/package.json): 0.2.2 → 0.3.0
@codespar/mcp: → 0.3.0
- All framework adapter packages: →
0.3.0
@codespar/session-contract is not bumped — it publishes at 0.1.0 for the first time in ISSUE:2 and has no prior version to increment from.
CHANGELOG.md files where present must document the changes. The mcp null-guard is a breaking change for any caller that accessed session.mcp without a guard — document this explicitly in the SDK changelog under a ### Breaking Changes heading.
Validation
Run the following after all changes are applied. All commands must exit 0.
#!/usr/bin/env bash
set -euo pipefail
echo "=== Build all packages ==="
pnpm build
echo "=== Typecheck SDK ==="
pnpm --filter @codespar/sdk typecheck
echo "=== Typecheck mcp ==="
pnpm --filter @codespar/mcp typecheck
echo "=== Run SDK tests ==="
pnpm --filter @codespar/sdk test
echo "=== Verify SDK version is 0.3.0 ==="
SDK_VERSION=$(node -p "require('./packages/core/package.json').version")
if [ "$SDK_VERSION" != "0.3.0" ]; then
echo "FAIL: SDK version is $SDK_VERSION, expected 0.3.0"
exit 1
fi
echo "SDK version: $SDK_VERSION — OK"
echo "=== Verify mcp version is 0.3.0 ==="
MCP_VERSION=$(node -p "require('./packages/mcp/package.json').version")
if [ "$MCP_VERSION" != "0.3.0" ]; then
echo "FAIL: mcp version is $MCP_VERSION, expected 0.3.0"
exit 1
fi
echo "mcp version: $MCP_VERSION — OK"
echo "=== Verify session-contract is in SDK dependencies (not devDependencies) ==="
node -e "
const pkg = require('./packages/core/package.json');
const inDeps = !!(pkg.dependencies && pkg.dependencies['@codespar/session-contract']);
const inDev = !!(pkg.devDependencies && pkg.devDependencies['@codespar/session-contract']);
if (!inDeps) { console.error('FAIL: @codespar/session-contract not in dependencies'); process.exit(1); }
if (inDev) { console.error('FAIL: @codespar/session-contract still in devDependencies'); process.exit(1); }
console.log('@codespar/session-contract in dependencies — OK');
"
echo "=== All checks passed ==="
Dependencies
- ISSUE:2 —
@codespar/session-contract package must exist and export SessionBase, Session, CreateSessionRequest, and all related types before this issue can be started. The SDK wiring in this issue imports from that package; if the package does not exist, pnpm build will fail immediately.
Downstream Dependencies
None. This is the leaf node for the core wiring work in this milestone. Once this issue merges at 0.3.0, consumers (framework adapters, example projects, downstream packages) can update their peer dependency ranges, but that work is tracked separately.
Security Checklist
Goal
Wire
@codespar/sdkto formally depend on@codespar/session-contract. Re-export all contract types from the SDK's main entrypoint. UpdatecreateSessionto constructCreateSessionRequestexplicitly. Convertloop(),tools(), andfindTools()from interface methods to free functions. Add null-guards to@codespar/mcp. Update allfakeSession()mocks across the repo. Bump all affected packages to 0.3.0.This is the largest issue in the milestone. All changes follow a mechanical pattern — the scope is wide but the transformations are uniform.
Context
The previous issue extracted the shared session contract types into
@codespar/session-contract. This issue completes the wiring: the SDK formally declares the dependency, re-exports the contract types, and all internal code is updated to use the new shapes.Key facts:
SessionBaseis the narrower interface (nomcptransport, noproxyExecute, noauthorize). It covers what all runtimes guarantee.Session extends SessionBaseadds the MCP transport fields and the managed-runtime methods.mcpis now optional onSession— callers and internal code that accesssession.mcpunconditionally will get a TypeScript type error until they add a null-guard.loop(),tools(), andfindTools()were interface methods. They must become free functions acceptingSessionBaseso they work with any conforming runtime, not just the SDK's concrete implementation.The TypeScript compiler will surface every broken call site as a type error. Fix all of them before marking this issue complete.
Acceptance Criteria
1. SDK package.json — add runtime dependency
packages/core/package.jsonlists@codespar/session-contractindependencies(notdevDependencies).If
@codespar/session-contractwas temporarily added as adevDependencyor workspace link while extracting the types, remove that entry and replace it with thedependenciesentry above.2. Re-export from SDK main entrypoint
packages/core/src/index.tsincludes a re-export of all contract types:This must appear early in the file (before SDK-specific exports). Callers who import
Session,SessionBase,StreamEvent,CreateSessionRequest, or any other contract type from@codespar/sdkcontinue to receive them without changing their import paths.3. createSession uses CreateSessionRequest explicitly
Inside the
createSessionfactory inpackages/core/src/session.ts, the object posted to/v1/sessionsis constructed as a typedCreateSessionRequest:SessionConfig(the SDK-level input type) retains the SDK-specific fields:preset,manageConnections,apiKey,baseUrl. Only the fields that cross the wire move intoCreateSessionRequest.4. loop, tools, findTools are free functions
These three functions are moved from interface methods to free functions in their own modules:
All call sites in the repo that use
session.loop(),session.tools(), orsession.findTools()must be updated to the free-function form:loop(session),tools(session),findTools(session, query).Search the entire repo for these patterns before removing the interface methods. Both the method definitions on the interface and any concrete class implementations must be removed.
5. Null-guard in @codespar/mcp
mcpis now typed as optional onSession. The@codespar/mcppackage has call sites that accesssession.mcp.urlandsession.mcp.headersunconditionally. Every such site must add a guard:The exact error message may vary by call site context, but must be descriptive. The TypeScript compiler will flag all 4 sites as type errors after the type change — the criterion is zero type errors in
@codespar/mcpafter this issue.Do not use non-null assertions (
!) as a workaround. The guard must be explicit.6. All fakeSession() mocks updated
Search for
fakeSessionacross the entire repo. Every mock object must satisfy the structural split:SessionretainproxyExecuteandauthorize.SessionBasemay omit those fields.SessionBasemethods: whateverSessionBasedeclares must be present.No mock should cause a TypeScript type error after this issue.
7. Version bumps
The following packages are bumped to
0.3.0:@codespar/sdk(packages/core/package.json):0.2.2→0.3.0@codespar/mcp: →0.3.00.3.0@codespar/session-contractis not bumped — it publishes at0.1.0for the first time in ISSUE:2 and has no prior version to increment from.CHANGELOG.mdfiles where present must document the changes. Themcpnull-guard is a breaking change for any caller that accessedsession.mcpwithout a guard — document this explicitly in the SDK changelog under a### Breaking Changesheading.Validation
Run the following after all changes are applied. All commands must exit 0.
Dependencies
@codespar/session-contractpackage must exist and exportSessionBase,Session,CreateSessionRequest, and all related types before this issue can be started. The SDK wiring in this issue imports from that package; if the package does not exist,pnpm buildwill fail immediately.Downstream Dependencies
None. This is the leaf node for the core wiring work in this milestone. Once this issue merges at 0.3.0, consumers (framework adapters, example projects, downstream packages) can update their peer dependency ranges, but that work is tracked separately.
Security Checklist
session.mcpunconditional access is documented under### Breaking Changesin the SDKCHANGELOG.md. Callers who accesssession.mcpwithout a null-guard will see a TypeScript compile error — not a silent runtime failure.@codespar/mcpnull-guard sites covered: confirm the TypeScript compiler reports zero errors in@codespar/mcpafter changes. Do not suppress errors with// @ts-ignoreor non-null assertions.session.mcp.urlthrowCannot read properties of undefined. The runtime behavior is strictly safer than before.