Remove stale ADR-005 drift tables across all architecture docs since ResponseEnvelope types, factories, detection, and integration points are now fully implemented in source code. Key changes: - api-surface.md: Remove ADR-005 drift table (all items implemented), retain ADR-006 drift table without execute() return type (now done) - call-protocol.md: Remove ADR-005 drift table, update ADR-006 table, fix CallHandlerConfig to show callMap? (current source) - adapters.md: Remove 'current source state' and 'implementation changes needed' tables for from_mcp and from_openapi, replace with current-accurate descriptions of envelope behavior - response-envelopes.md: Remove 'current source state' blocks, update migration checklist to show all code changes completed - 005-response-envelopes.md: Change status from Draft to Implemented - 006-unified-invocation-path.md: Update Prerequisites section to note ADR-005 is now implemented - build-distribution.md: Add response-envelope.ts to source layout - architecture.md: Add response-envelopes.md link and ADR-005/006 entries to design decisions table - README.md: Add response-envelopes.md to documents table - Update last_updated dates on all changed docs
4.8 KiB
4.8 KiB
status, last_updated
| status | last_updated |
|---|---|
| draft | 2026-05-11 |
Build & Distribution
Dependencies, project structure, sub-path exports, peer deps, and build tooling.
Dependencies
Runtime
| Package | Purpose |
|---|---|
@alkdev/typebox |
Schema system. Type for building schemas, Value for validation, KindGuard for schema assertion. |
@alkdev/pubsub |
Call protocol transport. PendingRequestMap creates an internal PubSub for event routing. Uses subscribe(type, id) and publish(type, id, payload) API with EventEnvelope wrapping. |
@logtape/logtape |
Structured logging. Direct import, no wrapper. See ADR-001. |
Peer (Optional)
| Package | Required By | Purpose |
|---|---|---|
@modelcontextprotocol/sdk |
from_mcp sub-path |
MCP client transport (stdio, HTTP). Dynamic import — only loaded when createMCPClient is called. |
Dev
| Package | Purpose |
|---|---|
tsup |
Build tool. Dual ESM + CJS with declarations. |
typescript |
Type checking (tsc --noEmit for lint). |
vitest |
Test runner. |
@vitest/coverage-v8 |
V8 coverage provider. |
@modelcontextprotocol/sdk |
Dev dep for MCP tests. Also listed as optional peer. |
@types/node |
Node.js type definitions. |
Project Structure
@alkdev/operations/
src/
index.ts # Barrel: re-exports all public API
types.ts # Core types: IOperationDefinition, OperationSpec, OperationType, etc.
registry.ts # OperationRegistry: registerSpec, registerHandler, execute, get, list
validation.ts # assertIsSchema, validateOrThrow, collectErrors, formatValueErrors
response-envelope.ts # ResponseEnvelope types, factories, detection, schemas, unwrap
call.ts # PendingRequestMap, buildCallHandler, CallEventMap, event types
subscribe.ts # subscribe(): direct AsyncGenerator execution
env.ts # buildEnv(): namespace-keyed env with direct/call-protocol modes
error.ts # CallError, InfrastructureErrorCode, mapError
from_schema.ts # FromSchema: JSON Schema → TypeBox conversion
from_openapi.ts # FromOpenAPI, FromOpenAPIFile, FromOpenAPIUrl
from_mcp.ts # createMCPClient, closeMCPClient, MCPClientLoader
scanner.ts # scanOperations: filesystem auto-discovery
test/
# Unit tests per module
docs/
architecture.md
architecture/
README.md
api-surface.md
call-protocol.md
adapters.md
build-distribution.md
decisions/
package.json
tsconfig.json
tsup.config.ts
vitest.config.ts
Sub-Path Exports
{
"exports": {
".": {
"import": { "types": "./dist/index.d.ts", "default": "./dist/index.js" },
"require": { "types": "./dist/index.d.cts", "default": "./dist/index.cjs" }
},
"./from-mcp": {
"import": { "types": "./dist/from-mcp.d.ts", "default": "./dist/from-mcp.js" },
"require": { "types": "./dist/from-mcp.d.cts", "default": "./dist/from-mcp.cjs" }
}
}
}
The ./from-mcp sub-path isolates the MCP SDK peer dependency. Consumers that don't use MCP don't need to install @modelcontextprotocol/sdk. See ADR-003.
The main barrel (src/index.ts) re-exports everything including createMCPClient and MCPClientLoader for convenience. The sub-path exists for explicit dependency isolation, not for excluding from the barrel.
Build
- Tool:
tsup— produces dual ESM + CJS with declarations - Entry points:
src/index.ts,src/from_mcp.ts - Format: ESM + CJS
- Target:
es2022 - Splitting: enabled
// tsup.config.ts
import { defineConfig } from 'tsup'
export default defineConfig({
entry: ['src/index.ts', 'src/from_mcp.ts'],
format: ['esm', 'cjs'],
dts: true,
sourcemap: true,
clean: true,
splitting: true,
target: 'es2022',
})
Scripts
| Script | Command | Purpose |
|---|---|---|
build |
tsup |
Build ESM + CJS + declarations |
lint |
tsc --noEmit |
Type-check only (no emit) |
test |
vitest run |
Run tests |
test:watch |
vitest |
Watch mode |
test:coverage |
vitest run --coverage |
Coverage report (v8) |
Testing
- Runner:
vitest - Coverage:
@vitest/coverage-v8 - Config:
vitest.config.ts
Tests should mock external services (MCP servers, HTTP endpoints) and use injectable FS interfaces (ScannerFS, OpenAPIFS) rather than real filesystem access.
Targets
- Publish: npm (
@alkdev/operations) - Runtime: Node 18+, Deno, Bun — pure JS except
from_mcpwhich requires@modelcontextprotocol/sdk - Deno compatibility: Source is standard TypeScript with no Deno-specific APIs. Runtime-agnostic FS injection means Deno can provide its own
ScannerFSandOpenAPIFSimplementations