feat(core-runner-protocol): scaffold protocol package
Hand-scaffolded from the packages/core-events shape: the core-package turbo generator only covers its eight pre-curated snapshot names (analytics, audit, consent, dsr, events, realtime, trpc, ui) and rejects 'runner-protocol' at the name prompt. Flagged in the package AGENTS.md as a future generator snapshot candidate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
This commit is contained in:
39
AGENTS.md
39
AGENTS.md
@@ -30,23 +30,24 @@ See `docs/guides/runbook.md` for the full workflow.
|
||||
|
||||
## Package Map
|
||||
|
||||
| Package | Tag | Purpose |
|
||||
| ----------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `@repo/core-shared` | core | Generic primitives (Zod, env, Payload hooks/fields/blocks, tRPC init/context, instrumentation interfaces, jobs, rate-limit, security headers, DI bind contexts) |
|
||||
| `@repo/core-ui` | core | Design system (atoms, molecules, generic organisms, templates) — the home of Veect's monochrome "ink instrument" language |
|
||||
| `@repo/core-events` | core | `IEventBus` — `InMemoryEventBus` (dev/test) + `PayloadJobsEventBus` (prod) (ADR-015) |
|
||||
| `@repo/core-realtime` | core | Socket.IO server + `IRealtimeBroadcaster` + handler registry (ADR-016) |
|
||||
| `@repo/core-audit` | core | DPA-compliant audit logging (GDPR erasure, OTel correlation) (ADR-018) |
|
||||
| `@repo/core-analytics` | core | Product analytics capture channel (`IAnalytics`) (ADR-024) |
|
||||
| `@repo/core-consent` | core | Consent-category runtime gate + cookie banner (ADR-025) |
|
||||
| `@repo/core-dsr` | core | Data-subject rights: export, delete, rectify, restrict (ADR-025) |
|
||||
| `@repo/core-api` | core-composition | tRPC router aggregator — imports `@repo/<feature>/api` only |
|
||||
| `@repo/core-cms` | core-composition | Payload config aggregator — imports `@repo/<feature>/cms` only |
|
||||
| `@repo/core-trpc` | core-composition | Frontend tRPC client + Next.js provider |
|
||||
| `@repo/auth` | feature | Users collection + sign-in/up/out + sessions — control-plane identity (ADR-027: email/password accounts; repo access is a per-workspace credential, not a user identity) |
|
||||
| `@repo/core-eslint` | tooling | Shared ESLint 9 flat configs (base, next, react-internal, boundaries) + the 16 conformance rules |
|
||||
| `@repo/core-typescript` | tooling | Shared TypeScript base configs + Vitest base |
|
||||
| `@repo/core-testing` | tooling | Shared test utilities (defineFactory, defineContractSuite, renderWithProviders, payload mocks, `Recording*` doubles) |
|
||||
| Package | Tag | Purpose |
|
||||
| ---------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `@repo/core-shared` | core | Generic primitives (Zod, env, Payload hooks/fields/blocks, tRPC init/context, instrumentation interfaces, jobs, rate-limit, security headers, DI bind contexts) |
|
||||
| `@repo/core-ui` | core | Design system (atoms, molecules, generic organisms, templates) — the home of Veect's monochrome "ink instrument" language |
|
||||
| `@repo/core-events` | core | `IEventBus` — `InMemoryEventBus` (dev/test) + `PayloadJobsEventBus` (prod) (ADR-015) |
|
||||
| `@repo/core-realtime` | core | Socket.IO server + `IRealtimeBroadcaster` + handler registry (ADR-016) |
|
||||
| `@repo/core-audit` | core | DPA-compliant audit logging (GDPR erasure, OTel correlation) (ADR-018) |
|
||||
| `@repo/core-analytics` | core | Product analytics capture channel (`IAnalytics`) (ADR-024) |
|
||||
| `@repo/core-consent` | core | Consent-category runtime gate + cookie banner (ADR-025) |
|
||||
| `@repo/core-dsr` | core | Data-subject rights: export, delete, rectify, restrict (ADR-025) |
|
||||
| `@repo/core-runner-protocol` | core | Versioned runner-protocol wire contract — envelope + `.strict()` zod message schemas shared by control plane, editor, and runners (ADR-027) |
|
||||
| `@repo/core-api` | core-composition | tRPC router aggregator — imports `@repo/<feature>/api` only |
|
||||
| `@repo/core-cms` | core-composition | Payload config aggregator — imports `@repo/<feature>/cms` only |
|
||||
| `@repo/core-trpc` | core-composition | Frontend tRPC client + Next.js provider |
|
||||
| `@repo/auth` | feature | Users collection + sign-in/up/out + sessions — control-plane identity (ADR-027: email/password accounts; repo access is a per-workspace credential, not a user identity) |
|
||||
| `@repo/core-eslint` | tooling | Shared ESLint 9 flat configs (base, next, react-internal, boundaries) + the 16 conformance rules |
|
||||
| `@repo/core-typescript` | tooling | Shared TypeScript base configs + Vitest base |
|
||||
| `@repo/core-testing` | tooling | Shared test utilities (defineFactory, defineContractSuite, renderWithProviders, payload mocks, `Recording*` doubles) |
|
||||
|
||||
Apps:
|
||||
|
||||
@@ -66,7 +67,7 @@ Apps:
|
||||
|
||||
- **app** (3 packages) — `apps/web-next`, `apps/cms`, `apps/storybook`
|
||||
- **core-composition** (3 packages) — `packages/core-api`, `core-cms` (must-have); `core-trpc` (optional, scaffolded)
|
||||
- **core** (8 packages) — `packages/core-shared` (must-have); `core-ui`, `core-events`, `core-realtime`, `core-audit`, `core-analytics`, `core-consent`, `core-dsr` (optional cores, all currently scaffolded — new ones via `pnpm turbo gen core-package <name>`)
|
||||
- **core** (9 packages) — `packages/core-shared` (must-have); `core-ui`, `core-events`, `core-realtime`, `core-audit`, `core-analytics`, `core-consent`, `core-dsr` (optional cores, all currently scaffolded — new ones via `pnpm turbo gen core-package <name>`); `core-runner-protocol` (hand-scaffolded — outside the generator's snapshot set)
|
||||
- **feature** (1 package) — `packages/auth`
|
||||
- **tooling** (3 packages) — `packages/core-eslint`, `core-typescript`, `core-testing`
|
||||
|
||||
@@ -635,7 +636,7 @@ Per-package documentation lives in each `AGENTS.md`:
|
||||
|
||||
- `packages/core-shared/AGENTS.md`
|
||||
- `packages/core-api/AGENTS.md`, `core-cms/AGENTS.md` (`core-trpc` has none yet)
|
||||
- `packages/core-ui/AGENTS.md`, `core-events/AGENTS.md`, `core-realtime/AGENTS.md`, `core-audit/AGENTS.md`, `core-analytics/AGENTS.md`, `core-consent/AGENTS.md`, `core-dsr/AGENTS.md`
|
||||
- `packages/core-ui/AGENTS.md`, `core-events/AGENTS.md`, `core-realtime/AGENTS.md`, `core-audit/AGENTS.md`, `core-analytics/AGENTS.md`, `core-consent/AGENTS.md`, `core-dsr/AGENTS.md`, `core-runner-protocol/AGENTS.md`
|
||||
- `packages/auth/AGENTS.md`
|
||||
- `packages/core-eslint/AGENTS.md`, `core-typescript/AGENTS.md`, `core-testing/AGENTS.md`
|
||||
- `apps/cms/AGENTS.md`, `web-next/AGENTS.md`, `storybook/AGENTS.md`
|
||||
|
||||
@@ -12,6 +12,7 @@ const nextConfig = {
|
||||
"@repo/core-dsr",
|
||||
"@repo/core-events",
|
||||
"@repo/core-realtime",
|
||||
"@repo/core-runner-protocol",
|
||||
"@repo/core-shared",
|
||||
"@repo/core-trpc",
|
||||
"@repo/core-ui",
|
||||
|
||||
11
packages/core-runner-protocol/AGENTS.md
Normal file
11
packages/core-runner-protocol/AGENTS.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# @repo/core-runner-protocol
|
||||
|
||||
Owns the versioned runner-protocol wire contract (ADR-027): the message envelope (`protocolVersion: "0"` + workspace-scoped auth token) and `.strict()` zod schemas for every message exchanged between the control plane/editor and any runner implementation (cloud, local CLI, later Tauri-embedded). Schemas only — the WS server/client implementations live in `apps/runner` and its consumers, never here.
|
||||
|
||||
**Boundary tag:** core. May be imported by feature, core, core-composition, app. May import from tooling.
|
||||
|
||||
**Public surface:** `PROTOCOL_VERSION`, the envelope schema, the per-message `.strict()` schemas + the `runnerMessageSchema` discriminated union, and their inferred types — all through the single index barrel.
|
||||
|
||||
**Scaffolding note:** hand-scaffolded from the `packages/core-events` shape — the `core-package` turbo generator only covers the eight pre-curated snapshot names (analytics, audit, consent, dsr, events, realtime, trpc, ui). Candidate for a future generator snapshot.
|
||||
|
||||
**See:** `docs/decisions/adr-027-hosted-saas-and-runner-split.md`, `docs/work/prds/walking-skeleton.prd.md`, `docs/glossary.md` § "Runner protocol".
|
||||
3
packages/core-runner-protocol/eslint.config.js
Normal file
3
packages/core-runner-protocol/eslint.config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import baseConfig from "@repo/core-eslint/base";
|
||||
|
||||
export default baseConfig;
|
||||
26
packages/core-runner-protocol/package.json
Normal file
26
packages/core-runner-protocol/package.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "@repo/core-runner-protocol",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc --noEmit",
|
||||
"lint": "eslint .",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "vitest run"
|
||||
},
|
||||
"dependencies": {
|
||||
"zod": "^3.24.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@repo/core-eslint": "workspace:*",
|
||||
"@repo/core-testing": "workspace:*",
|
||||
"@repo/core-typescript": "workspace:*",
|
||||
"@vitest/coverage-v8": "^3.2.4",
|
||||
"typescript": "^5.8.0",
|
||||
"vitest": "^3.0.0"
|
||||
}
|
||||
}
|
||||
1
packages/core-runner-protocol/src/index.ts
Normal file
1
packages/core-runner-protocol/src/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { PROTOCOL_VERSION, type ProtocolVersion } from "./protocol-version";
|
||||
@@ -0,0 +1,8 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { PROTOCOL_VERSION } from "@/protocol-version";
|
||||
|
||||
describe("PROTOCOL_VERSION", () => {
|
||||
it('is pinned to "0"', () => {
|
||||
expect(PROTOCOL_VERSION).toBe("0");
|
||||
});
|
||||
});
|
||||
10
packages/core-runner-protocol/src/protocol-version.ts
Normal file
10
packages/core-runner-protocol/src/protocol-version.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* The pinned runner-protocol version (ADR-027).
|
||||
*
|
||||
* Every envelope is validated against this exact literal. Version
|
||||
* negotiation beyond the pinned "0" is deliberately out of scope for the
|
||||
* walking skeleton (later PRDs).
|
||||
*/
|
||||
export const PROTOCOL_VERSION = "0" as const;
|
||||
|
||||
export type ProtocolVersion = typeof PROTOCOL_VERSION;
|
||||
12
packages/core-runner-protocol/tsconfig.json
Normal file
12
packages/core-runner-protocol/tsconfig.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "@repo/core-typescript/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
4
packages/core-runner-protocol/turbo.json
Normal file
4
packages/core-runner-protocol/turbo.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": ["//"],
|
||||
"tags": ["core"]
|
||||
}
|
||||
9
packages/core-runner-protocol/vitest.config.ts
Normal file
9
packages/core-runner-protocol/vitest.config.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import path from "node:path";
|
||||
import { mergeConfig } from "vitest/config";
|
||||
import { nodeVitestConfig } from "@repo/core-typescript/vitest.base.node";
|
||||
|
||||
export default mergeConfig(nodeVitestConfig, {
|
||||
resolve: {
|
||||
alias: { "@": path.resolve(__dirname, "./src") },
|
||||
},
|
||||
});
|
||||
25
pnpm-lock.yaml
generated
25
pnpm-lock.yaml
generated
@@ -656,6 +656,31 @@ importers:
|
||||
specifier: ^3.0.0
|
||||
version: 3.2.4(@types/debug@4.1.13)(@types/node@22.19.17)(happy-dom@20.8.9)(jiti@2.7.0)(jsdom@25.0.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.2)(tsx@4.21.0)(yaml@2.9.0)
|
||||
|
||||
packages/core-runner-protocol:
|
||||
dependencies:
|
||||
zod:
|
||||
specifier: ^3.24.0
|
||||
version: 3.25.76
|
||||
devDependencies:
|
||||
"@repo/core-eslint":
|
||||
specifier: workspace:*
|
||||
version: link:../core-eslint
|
||||
"@repo/core-testing":
|
||||
specifier: workspace:*
|
||||
version: link:../core-testing
|
||||
"@repo/core-typescript":
|
||||
specifier: workspace:*
|
||||
version: link:../core-typescript
|
||||
"@vitest/coverage-v8":
|
||||
specifier: ^3.2.4
|
||||
version: 3.2.4(vitest@3.2.4(@types/debug@4.1.13)(@types/node@25.5.2)(happy-dom@20.8.9)(jiti@2.7.0)(jsdom@25.0.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.2)(tsx@4.21.0)(yaml@2.9.0))
|
||||
typescript:
|
||||
specifier: ^5.8.0
|
||||
version: 5.9.3
|
||||
vitest:
|
||||
specifier: ^3.0.0
|
||||
version: 3.2.4(@types/debug@4.1.13)(@types/node@25.5.2)(happy-dom@20.8.9)(jiti@2.7.0)(jsdom@25.0.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.2)(tsx@4.21.0)(yaml@2.9.0)
|
||||
|
||||
packages/core-shared:
|
||||
dependencies:
|
||||
"@opentelemetry/api":
|
||||
|
||||
Reference in New Issue
Block a user