Skip to content

feat(sdk): wire @codespar/session-contract dependency and bump to 0.3.0 #4

Description

@dangazineu

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

  • Breaking change documented: the removal of session.mcp unconditional access is documented under ### Breaking Changes in the SDK CHANGELOG.md. Callers who access session.mcp without a null-guard will see a TypeScript compile error — not a silent runtime failure.
  • All @codespar/mcp null-guard sites covered: confirm the TypeScript compiler reports zero errors in @codespar/mcp after changes. Do not suppress errors with // @ts-ignore or non-null assertions.
  • No production runtime errors introduced: the null-guard throws a descriptive error rather than letting session.mcp.url throw Cannot read properties of undefined. The runtime behavior is strictly safer than before.
  • No secrets or credentials introduced: this issue touches package manifests, type definitions, and function signatures only. No API keys, tokens, or environment-specific values are added.
  • Version bumps are intentional: all bumps to 0.3.0 are coordinated. No package is accidentally left at 0.2.x while its peers are at 0.3.0, which would cause peer dependency resolution failures for consumers who upgrade.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    f4-m1Feature 4, Milestone 1: Shared Session Contract Packagevalidation:criticalCritical validation: security review required

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions