diff --git a/packages/agent/src/harness/context.ts b/packages/agent/src/harness/context.ts index 9b633c305..b2a4fe4a5 100644 --- a/packages/agent/src/harness/context.ts +++ b/packages/agent/src/harness/context.ts @@ -1,19 +1,28 @@ +import type { Context, ContextKey } from "@earendil-works/chord"; import { + awaitWithContext, BACKGROUND_CONTEXT, - type Context, - type ContextKey, - INTERNAL_CONTEXT_OPERATIONS, + createContextKey, TODO_CONTEXT, + withAbortSignal, + withCancel, + withContextValue, + withoutAbortSignal, } from "@earendil-works/chord/context"; import { NOOP_TELEMETRY_CONTEXT, type TelemetryContext } from "@earendil-works/pi-telemetry"; -export { BACKGROUND_CONTEXT, type Context, type ContextKey, TODO_CONTEXT }; -export const awaitWithContext = INTERNAL_CONTEXT_OPERATIONS.awaitWithContext; -export const createContextKey = INTERNAL_CONTEXT_OPERATIONS.createContextKey; -export const withAbortSignal = INTERNAL_CONTEXT_OPERATIONS.withAbortSignal; -export const withCancel = INTERNAL_CONTEXT_OPERATIONS.withCancel; -export const withContextValue = INTERNAL_CONTEXT_OPERATIONS.withContextValue; -export const withoutAbortSignal = INTERNAL_CONTEXT_OPERATIONS.withoutAbortSignal; +export { + awaitWithContext, + BACKGROUND_CONTEXT, + type Context, + type ContextKey, + createContextKey, + TODO_CONTEXT, + withAbortSignal, + withCancel, + withContextValue, + withoutAbortSignal, +}; const TELEMETRY_CONTEXT_KEY = createContextKey("pi.telemetryContext"); diff --git a/packages/agent/src/harness/session/types.ts b/packages/agent/src/harness/session/types.ts index 9abb77c3d..4c9cefeaa 100644 --- a/packages/agent/src/harness/session/types.ts +++ b/packages/agent/src/harness/session/types.ts @@ -1,4 +1,4 @@ -import type { JsonValue } from "@earendil-works/chord/types"; +import type { JsonValue } from "@earendil-works/chord"; import type { AssistantMessage, StopReason, Usage } from "@earendil-works/pi-ai"; import type { AgentMessage, QueueMode, ThinkingLevel } from "../../types.ts"; import type { BranchPreparation } from "../compaction/branch-summarization.ts"; @@ -7,7 +7,7 @@ import type { Context } from "../context.ts"; import type { AgentHarnessStreamOptions } from "../types.ts"; import type { ListElement, ListReadOptions, ListWrite, StoredValue, Value, ValueList, ValueWrite } from "./values.ts"; -export type { JsonValue } from "@earendil-works/chord/types"; +export type { JsonValue } from "@earendil-works/chord"; export type SettledAssistantMessage = AssistantMessage & { stopReason: Exclude; diff --git a/packages/ai/src/types.ts b/packages/ai/src/types.ts index 5b56a5611..6ce3fccf7 100644 --- a/packages/ai/src/types.ts +++ b/packages/ai/src/types.ts @@ -1,4 +1,4 @@ -import type { JsonValue } from "@earendil-works/chord/types"; +import type { JsonValue } from "@earendil-works/chord"; import type { TelemetryContext } from "@earendil-works/pi-telemetry"; import type { AnthropicOptions } from "./api/anthropic-messages.ts"; import type { AzureOpenAIResponsesOptions } from "./api/azure-openai-responses.ts"; @@ -405,7 +405,7 @@ export interface Usage { export type StopReason = "pending" | "stop" | "length" | "toolUse" | "error" | "aborted" | "deferred"; -export type { JsonValue } from "@earendil-works/chord/types"; +export type { JsonValue } from "@earendil-works/chord"; export interface DeferredHandle { provider: string; diff --git a/packages/chord/PLANNING.md b/packages/chord/PLANNING.md index 9e3359a8b..5a8b6d290 100644 --- a/packages/chord/PLANNING.md +++ b/packages/chord/PLANNING.md @@ -583,10 +583,10 @@ This is a planning aid, not a requirement to create all files immediately. packages/chord/ src/ index.ts platform-neutral public API - api.ts public functions - types.ts public types, including strict JSON values + api.ts root-exported functions + types.ts root-exported types, including strict JSON values context/ - index.ts invocation context internals and compatibility entry + index.ts invocation context constants and functions errors.ts lifecycle, service, and RPC errors services/ types.ts tokens, contracts, modes, snapshots diff --git a/packages/chord/README.md b/packages/chord/README.md index e8deebd36..1376fa1c8 100644 --- a/packages/chord/README.md +++ b/packages/chord/README.md @@ -48,9 +48,10 @@ The design has a few connected pieces: The current runtime exports service tokens, singleton and keyed providers, remote bindings, replicated state, facet hosts, and facet loaders from -`@earendil-works/chord`. All public functions are collected in -`@earendil-works/chord/api`, while all public types are collected in -`@earendil-works/chord/types`; both are re-exported from the main entry point. +`@earendil-works/chord`. Import public types and general runtime APIs from the +package root. Context constants and functions live in +`@earendil-works/chord/context` because their generic names should not pollute +the root API. Chord-owned identifiers use the `chord.*` namespace and its reserved service prefix is `$chord.*`. diff --git a/packages/chord/package.json b/packages/chord/package.json index e4f37cce5..5a0d6d3f4 100644 --- a/packages/chord/package.json +++ b/packages/chord/package.json @@ -11,21 +11,11 @@ "types": "./dist/index.d.ts", "import": "./dist/index.js" }, - "./api": { - "source": "./src/api.ts", - "types": "./dist/api.d.ts", - "import": "./dist/api.js" - }, "./context": { "source": "./src/context/index.ts", "types": "./dist/context/index.d.ts", "import": "./dist/context/index.js" }, - "./types": { - "source": "./src/types.ts", - "types": "./dist/types.d.ts", - "import": "./dist/types.js" - }, "./package.json": "./package.json" }, "sideEffects": false, diff --git a/packages/chord/src/api.ts b/packages/chord/src/api.ts index 57c5115ca..ba87f1eee 100644 --- a/packages/chord/src/api.ts +++ b/packages/chord/src/api.ts @@ -1,19 +1,10 @@ -import { - deriveCancellableContext, - deriveContextValue, - deriveContextWithAbortSignal, - deriveContextWithoutAbortSignal, - waitWithContext, -} from "./context/index.ts"; import { FacetKernel } from "./facets/host.ts"; import { disposeLoadedFacets } from "./facets/loader.ts"; import { RemoteServiceBindingImpl } from "./services/consumer.ts"; import { lookupServiceInstanceKey } from "./services/instances.ts"; import type { RemoteServiceProvider } from "./services/provider.ts"; -import { createDeliveryContext, MutableReplicatedStateImpl } from "./services/state.ts"; +import { MutableReplicatedStateImpl, serviceDeliveryContext } from "./services/state.ts"; import type { - Context, - ContextKey, Facet, FacetHost, FacetLoader, @@ -27,44 +18,6 @@ import type { Service, } from "./types.ts"; -export function createContextKey(description: string): ContextKey { - return Object.freeze({ token: Symbol(description) }); -} - -/** Derive a context containing one additional or replaced value. */ -export function withContextValue(key: ContextKey, value: T, parent: Context): Context { - return deriveContextValue(key, value, parent); -} - -/** - * Derive a context cancelled by either the parent signal or the supplied signal. - * The parent context remains unchanged. - */ -export function withAbortSignal(signal: AbortSignal, context: Context): Context { - return deriveContextWithAbortSignal(signal, context); -} - -/** Derive a context retaining all values except caller cancellation. Intended for mandatory cleanup only. */ -export function withoutAbortSignal(context: Context): Context { - return deriveContextWithoutAbortSignal(context); -} - -/** Derive an independently cancellable child context. */ -export function withCancel(context: Context): { - readonly context: Context; - readonly cancel: (reason?: unknown) => void; -} { - return deriveCancellableContext(context); -} - -/** - * Observe a promise until it settles or the invocation is cancelled. - * Cancellation rejects only this waiter; it does not cancel the underlying promise. - */ -export function awaitWithContext(promise: Promise, context: Context): Promise { - return waitWithContext(promise, context); -} - /** Create an active host for one complete set of facets. */ export async function createFacetHost(options: FacetOptions): Promise { const kernel = new FacetKernel(options); @@ -151,7 +104,7 @@ export function createLoopbackServiceConnection(provider: RemoteServiceProvider) invoke: (call, context) => provider.invoke(call, context), subscribe: async (serviceId, mode, listener) => { const subscription = provider.subscribe(serviceId, mode, (update) => - listener(update, createDeliveryContext()), + listener(update, serviceDeliveryContext()), ); return { snapshot: subscription.snapshot, @@ -165,8 +118,3 @@ export function createLoopbackServiceConnection(provider: RemoteServiceProvider) export function replicatedState(initial: T): MutableReplicatedState { return new MutableReplicatedStateImpl(initial); } - -/** @publicApiReview Delivery contexts may only be an internal service-replication concern. */ -export function freshDeliveryContext(): Context { - return createDeliveryContext(); -} diff --git a/packages/chord/src/context/index.ts b/packages/chord/src/context/index.ts index fcc991ac8..fbe54bcc4 100644 --- a/packages/chord/src/context/index.ts +++ b/packages/chord/src/context/index.ts @@ -1,8 +1,6 @@ import type { Context, ContextKey } from "../types.ts"; -export type { Context, ContextKey } from "../types.ts"; - -export const ABORT_SIGNAL_CONTEXT_KEY: ContextKey = Object.freeze({ +const ABORT_SIGNAL_CONTEXT_KEY: ContextKey = Object.freeze({ token: Symbol("chord.abortSignal"), }); @@ -57,36 +55,47 @@ class ContextValue extends BaseContext { export const BACKGROUND_CONTEXT: Context = new EmptyContext("[Context BACKGROUND_CONTEXT]"); export const TODO_CONTEXT: Context = new EmptyContext("[Context TODO_CONTEXT]"); -function createContextKey(description: string): ContextKey { +export function createContextKey(description: string): ContextKey { return Object.freeze({ token: Symbol(description) }); } -export function deriveContextValue(key: ContextKey, value: T, parent: Context): Context { +/** Derive a context containing one additional or replaced value. */ +export function withContextValue(key: ContextKey, value: T, parent: Context): Context { return new ContextValue(parent, key, value); } -export function deriveContextWithAbortSignal(signal: AbortSignal, context: Context): Context { +/** + * Derive a context cancelled by either the parent signal or the supplied signal. + * The parent context remains unchanged. + */ +export function withAbortSignal(signal: AbortSignal, context: Context): Context { const parentSignal = context.abortSignal; const combined = parentSignal === undefined ? signal : AbortSignal.any([parentSignal, signal]); - return deriveContextValue(ABORT_SIGNAL_CONTEXT_KEY, combined, context); + return withContextValue(ABORT_SIGNAL_CONTEXT_KEY, combined, context); } -export function deriveContextWithoutAbortSignal(context: Context): Context { - return deriveContextValue(ABORT_SIGNAL_CONTEXT_KEY, undefined, context); +/** Derive a context retaining all values except caller cancellation. Intended for mandatory cleanup only. */ +export function withoutAbortSignal(context: Context): Context { + return withContextValue(ABORT_SIGNAL_CONTEXT_KEY, undefined, context); } -export function deriveCancellableContext(context: Context): { +/** Derive an independently cancellable child context. */ +export function withCancel(context: Context): { readonly context: Context; readonly cancel: (reason?: unknown) => void; } { const controller = new AbortController(); return { - context: deriveContextWithAbortSignal(controller.signal, context), + context: withAbortSignal(controller.signal, context), cancel: (reason?: unknown) => controller.abort(reason), }; } -export function waitWithContext(promise: Promise, context: Context): Promise { +/** + * Observe a promise until it settles or the invocation is cancelled. + * Cancellation rejects only this waiter; it does not cancel the underlying promise. + */ +export function awaitWithContext(promise: Promise, context: Context): Promise { const signal = context.abortSignal; if (signal === undefined) return promise; if (signal.aborted) return Promise.reject(abortError(signal)); @@ -110,13 +119,3 @@ function abortError(signal: AbortSignal): Error { const reason: unknown = signal.reason; return reason instanceof Error ? reason : new DOMException("The operation was aborted", "AbortError"); } - -/** @internal Narrow compatibility surface for the legacy context entry point. */ -export const INTERNAL_CONTEXT_OPERATIONS = Object.freeze({ - awaitWithContext: waitWithContext, - createContextKey, - withAbortSignal: deriveContextWithAbortSignal, - withCancel: deriveCancellableContext, - withContextValue: deriveContextValue, - withoutAbortSignal: deriveContextWithoutAbortSignal, -}); diff --git a/packages/chord/src/index.ts b/packages/chord/src/index.ts index df28f4ee1..d7e922cef 100644 --- a/packages/chord/src/index.ts +++ b/packages/chord/src/index.ts @@ -1,27 +1,17 @@ /** - * Chord is a standalone application-composition runtime. - * - * Its public API is under development. + * Chord is a standalone application-composition runtime for agentic applications. */ export { - awaitWithContext, combineFacetLoaders, - createContextKey, createFacetHost, createLoopbackServiceConnection, createRemoteServiceBinding, createStaticFacetLoader, defineFacet, defineService, - freshDeliveryContext, getServiceInstanceKey, replicatedState, - withAbortSignal, - withCancel, - withContextValue, - withoutAbortSignal, } from "./api.ts"; -export { BACKGROUND_CONTEXT, TODO_CONTEXT } from "./context/index.ts"; export { RemoteServiceError } from "./services/errors.ts"; export { RemoteServiceProvider } from "./services/provider.ts"; export type { diff --git a/packages/chord/src/services/consumer.ts b/packages/chord/src/services/consumer.ts index f349e3833..4be99fdd0 100644 --- a/packages/chord/src/services/consumer.ts +++ b/packages/chord/src/services/consumer.ts @@ -1,4 +1,4 @@ -import { BACKGROUND_CONTEXT, waitWithContext } from "../context/index.ts"; +import { awaitWithContext, BACKGROUND_CONTEXT } from "../context/index.ts"; import type { Context, JsonValue, @@ -14,7 +14,7 @@ import type { } from "../types.ts"; import { RemoteServiceError } from "./errors.ts"; import { InstanceDirectory, type InstanceDirectoryEntry } from "./instances.ts"; -import { createDeliveryContext, ReplicatedStateReplica } from "./state.ts"; +import { ReplicatedStateReplica, serviceDeliveryContext } from "./state.ts"; type ErrorReporter = (error: Error) => void; type ServiceMemberKind = ServiceMemberSnapshot["kind"]; @@ -346,7 +346,7 @@ class KeyedBinding { if (subscription.snapshot.mode !== "keyed" || subscription.snapshot.serviceId !== this.#service.id) { throw new Error(`Remote service ${this.#service.id} returned the wrong keyed snapshot`); } - for (const snapshot of subscription.snapshot.instances) this.#spawn(snapshot, createDeliveryContext()); + for (const snapshot of subscription.snapshot.instances) this.#spawn(snapshot, serviceDeliveryContext()); this.#instances.ready(); subscription.activate(); } @@ -500,7 +500,7 @@ export class RemoteServiceBindingImpl implements RemoteServiceBinding { ), ...[...this.#keyed.values()].map((binding) => binding.ready()), ]; - await waitWithContext( + await awaitWithContext( Promise.all(starts).then(() => undefined), context, ); @@ -595,7 +595,7 @@ export class RemoteServiceBindingImpl implements RemoteServiceBinding { if (snapshot.mode !== "singleton" || snapshot.serviceId !== serviceId || snapshot.instances.length !== 1) { throw new Error(`Remote service ${serviceId} returned an invalid singleton snapshot`); } - binding.facade.install(snapshot.instances[0]!, createDeliveryContext()); + binding.facade.install(snapshot.instances[0]!, serviceDeliveryContext()); subscription.activate(); } diff --git a/packages/chord/src/services/instances.ts b/packages/chord/src/services/instances.ts index 41909f5c7..0d7076ecd 100644 --- a/packages/chord/src/services/instances.ts +++ b/packages/chord/src/services/instances.ts @@ -1,4 +1,4 @@ -import { BACKGROUND_CONTEXT, deriveCancellableContext } from "../context/index.ts"; +import { BACKGROUND_CONTEXT, withCancel } from "../context/index.ts"; import type { Context } from "../types.ts"; const instanceKeys = new WeakMap(); @@ -134,7 +134,7 @@ export class InstanceDirectory { #start(observer: Observer, entry: TEntry): void { if (observer.closed || observer.tasks.has(entry)) return; - const { context, cancel } = deriveCancellableContext(BACKGROUND_CONTEXT); + const { context, cancel } = withCancel(BACKGROUND_CONTEXT); observer.tasks.set(entry, { cancel }); try { void Promise.resolve(observer.handler(entry.service, context)).catch((error: unknown) => { diff --git a/packages/chord/src/services/provider.ts b/packages/chord/src/services/provider.ts index 3da0cc46f..a15479c64 100644 --- a/packages/chord/src/services/provider.ts +++ b/packages/chord/src/services/provider.ts @@ -14,7 +14,7 @@ import type { ServiceSubscriptionSnapshot, } from "../types.ts"; import { RemoteServiceError } from "./errors.ts"; -import { createDeliveryContext } from "./state.ts"; +import { serviceDeliveryContext } from "./state.ts"; import { getReplicatedStateInternals, type ReplicatedStateInternals } from "./state-internals.ts"; type RemoteMethod = (...args: unknown[]) => unknown; @@ -364,7 +364,7 @@ export class RemoteServiceProvider { #emit(registration: ServiceRegistration, update: ServiceProviderUpdate, context?: Context): void { if (registration.subscribers.size === 0) return; - const deliveryContext = context ?? createDeliveryContext(); + const deliveryContext = context ?? serviceDeliveryContext(); for (const subscriber of registration.subscribers) { if (subscriber.closed) continue; const entry = { update, context: deliveryContext }; diff --git a/packages/chord/src/services/state.ts b/packages/chord/src/services/state.ts index d3ff4ed57..c973a914e 100644 --- a/packages/chord/src/services/state.ts +++ b/packages/chord/src/services/state.ts @@ -1,4 +1,4 @@ -import { BACKGROUND_CONTEXT, deriveCancellableContext } from "../context/index.ts"; +import { BACKGROUND_CONTEXT } from "../context/index.ts"; import type { Context, JsonValue, MutableReplicatedState, ReplicatedState } from "../types.ts"; import { registerReplicatedStateInternals } from "./state-internals.ts"; @@ -41,7 +41,7 @@ export class MutableReplicatedStateImpl implements MutableReplicatedState subscribe(listener: (value: T, context: Context) => void): () => void { this.#listeners.add(listener); - listener(this.value, createDeliveryContext()); + listener(this.value, serviceDeliveryContext()); return () => this.#listeners.delete(listener); } } @@ -63,7 +63,7 @@ export class ReplicatedStateReplica implements subscribe(listener: (value: T, context: Context) => void): () => void { this.#listeners.add(listener); - if (this.#value !== undefined) this.#deliver(listener, this.#value, createDeliveryContext()); + if (this.#value !== undefined) this.#deliver(listener, this.#value, serviceDeliveryContext()); return () => this.#listeners.delete(listener); } @@ -101,8 +101,10 @@ export class ReplicatedStateReplica implements } } -export function createDeliveryContext(): Context { - return deriveCancellableContext(BACKGROUND_CONTEXT).context; +/** @internal Context for synthetic service deliveries without a caller. */ +export function serviceDeliveryContext(): Context { + // TODO: Add delivery-scoped cancellation or metadata if deliveries gain an owned lifecycle. + return BACKGROUND_CONTEXT; } function toError(error: unknown): Error { diff --git a/packages/chord/test/context.test.ts b/packages/chord/test/context.test.ts index 7360a04ee..3384d3891 100644 --- a/packages/chord/test/context.test.ts +++ b/packages/chord/test/context.test.ts @@ -8,7 +8,7 @@ import { withCancel, withContextValue, withoutAbortSignal, -} from "../src/index.ts"; +} from "../src/context/index.ts"; describe("Context", () => { it("provides distinct empty root contexts", () => { diff --git a/packages/chord/test/facet-loader.test.ts b/packages/chord/test/facet-loader.test.ts index f5322128f..75d2b2f82 100644 --- a/packages/chord/test/facet-loader.test.ts +++ b/packages/chord/test/facet-loader.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test, vi } from "vitest"; +import { BACKGROUND_CONTEXT } from "../src/context/index.ts"; import { - BACKGROUND_CONTEXT, type Context, combineFacetLoaders, createFacetHost, diff --git a/packages/chord/test/facets.test.ts b/packages/chord/test/facets.test.ts index 2b18e0a90..952e88814 100644 --- a/packages/chord/test/facets.test.ts +++ b/packages/chord/test/facets.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test, vi } from "vitest"; +import { BACKGROUND_CONTEXT } from "../src/context/index.ts"; import { - BACKGROUND_CONTEXT, type Context, createFacetHost, createLoopbackServiceConnection, diff --git a/packages/chord/test/services.test.ts b/packages/chord/test/services.test.ts index 8ae74b890..72198e503 100644 --- a/packages/chord/test/services.test.ts +++ b/packages/chord/test/services.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test, vi } from "vitest"; +import { BACKGROUND_CONTEXT } from "../src/context/index.ts"; import { - BACKGROUND_CONTEXT, type Context, createLoopbackServiceConnection, createRemoteServiceBinding, diff --git a/packages/coding-agent/src/experimental/client-runtime.ts b/packages/coding-agent/src/experimental/client-runtime.ts index 8fe1341b5..eb879ea88 100644 --- a/packages/coding-agent/src/experimental/client-runtime.ts +++ b/packages/coding-agent/src/experimental/client-runtime.ts @@ -1,5 +1,5 @@ import { basename } from "node:path"; -import { BACKGROUND_CONTEXT } from "@earendil-works/chord"; +import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { Client } from "@earendil-works/pi-client"; import { createUnixTransportFactory, discoverUnixServers, type UnixServerRoute } from "@earendil-works/pi-client/unix"; import { isServerId, type ServerId } from "@earendil-works/pi-protocol"; diff --git a/packages/coding-agent/src/experimental/client-tui.ts b/packages/coding-agent/src/experimental/client-tui.ts index e1f3c7df2..334a7b1ae 100644 --- a/packages/coding-agent/src/experimental/client-tui.ts +++ b/packages/coding-agent/src/experimental/client-tui.ts @@ -1,5 +1,4 @@ import { - BACKGROUND_CONTEXT, combineFacetLoaders, createFacetHost, createStaticFacetLoader, @@ -8,6 +7,7 @@ import { type FacetLoader, type LoadedFacets, } from "@earendil-works/chord"; +import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import type { SessionSummary } from "@earendil-works/pi-protocol"; import { CombinedAutocompleteProvider, diff --git a/packages/coding-agent/src/experimental/services/connection.ts b/packages/coding-agent/src/experimental/services/connection.ts index c171d2c01..725ad65af 100644 --- a/packages/coding-agent/src/experimental/services/connection.ts +++ b/packages/coding-agent/src/experimental/services/connection.ts @@ -1,9 +1,7 @@ import { - BACKGROUND_CONTEXT, type Context, createRemoteServiceBinding, type FacetConnection, - freshDeliveryContext, type JsonValue, type MutableReplicatedState, type RemoteServiceBinding, @@ -13,6 +11,7 @@ import { replicatedState, type Service, } from "@earendil-works/chord"; +import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import type { Client } from "@earendil-works/pi-client"; import type { ProtocolRpcCall, @@ -464,7 +463,7 @@ function createRemoteServiceConnection( target, serviceId, mode, - (update: ServiceProviderUpdate) => listener(update, freshDeliveryContext()), + (update: ServiceProviderUpdate) => listener(update, BACKGROUND_CONTEXT), context.abortSignal, ); return { diff --git a/packages/coding-agent/src/experimental/services/models-provider.ts b/packages/coding-agent/src/experimental/services/models-provider.ts index 608fcbe46..a79ae4df5 100644 --- a/packages/coding-agent/src/experimental/services/models-provider.ts +++ b/packages/coding-agent/src/experimental/services/models-provider.ts @@ -1,10 +1,5 @@ -import { - BACKGROUND_CONTEXT, - type Context, - defineFacet, - type Facet, - type MutableReplicatedState, -} from "@earendil-works/chord"; +import { type Context, defineFacet, type Facet, type MutableReplicatedState } from "@earendil-works/chord"; +import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import type { AgentLane, ThinkingLevel } from "@earendil-works/pi-agent-core"; import { getSupportedThinkingLevels } from "@earendil-works/pi-ai"; import type { ModelRuntime } from "../../core/model-runtime.ts"; diff --git a/packages/coding-agent/src/experimental/services/server.ts b/packages/coding-agent/src/experimental/services/server.ts index 97c6f66c2..3b808edec 100644 --- a/packages/coding-agent/src/experimental/services/server.ts +++ b/packages/coding-agent/src/experimental/services/server.ts @@ -1,11 +1,11 @@ import { - BACKGROUND_CONTEXT, type Context, type ServiceProviderUpdate as CoreServiceProviderUpdate, RemoteServiceProvider, replicatedState, type ServiceSubscription, } from "@earendil-works/chord"; +import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { decodeServiceControlCall, type JsonValue, diff --git a/packages/coding-agent/test/experimental-client-tui.test.ts b/packages/coding-agent/test/experimental-client-tui.test.ts index 5e45d5c30..3ae39d97b 100644 --- a/packages/coding-agent/test/experimental-client-tui.test.ts +++ b/packages/coding-agent/test/experimental-client-tui.test.ts @@ -1,5 +1,4 @@ import { - BACKGROUND_CONTEXT, createLoopbackServiceConnection, createRemoteServiceBinding, defineFacet, @@ -7,6 +6,7 @@ import { RemoteServiceProvider, replicatedState, } from "@earendil-works/chord"; +import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import type { AgentLane } from "@earendil-works/pi-agent-core"; import type { LaneEvent, LaneSnapshot, SessionSummary } from "@earendil-works/pi-protocol"; import { ProcessTerminal, TuiMainScreen } from "@earendil-works/pi-tui"; diff --git a/packages/coding-agent/test/experimental-remote-runtime.test.ts b/packages/coding-agent/test/experimental-remote-runtime.test.ts index b16cc90f2..9578ecc00 100644 --- a/packages/coding-agent/test/experimental-remote-runtime.test.ts +++ b/packages/coding-agent/test/experimental-remote-runtime.test.ts @@ -1,6 +1,7 @@ import { lstat, mkdtemp, readdir, rm, writeFile } from "node:fs/promises"; import { join, resolve } from "node:path"; -import { BACKGROUND_CONTEXT, type Context, createFacetHost, defineFacet, withCancel } from "@earendil-works/chord"; +import { type Context, createFacetHost, defineFacet } from "@earendil-works/chord"; +import { BACKGROUND_CONTEXT, withCancel } from "@earendil-works/chord/context"; import { Client } from "@earendil-works/pi-client"; import { createUnixTransportFactory } from "@earendil-works/pi-client/unix"; import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; diff --git a/packages/coding-agent/test/experimental-service-stubs.test.ts b/packages/coding-agent/test/experimental-service-stubs.test.ts index c187e9c63..dbf8bdf67 100644 --- a/packages/coding-agent/test/experimental-service-stubs.test.ts +++ b/packages/coding-agent/test/experimental-service-stubs.test.ts @@ -1,4 +1,5 @@ -import { BACKGROUND_CONTEXT, createFacetHost } from "@earendil-works/chord"; +import { createFacetHost } from "@earendil-works/chord"; +import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context"; import { describe, expect, test } from "vitest"; import { accountsServiceFacet, diff --git a/packages/protocol/src/json-value.ts b/packages/protocol/src/json-value.ts index 8215809ab..0884cd161 100644 --- a/packages/protocol/src/json-value.ts +++ b/packages/protocol/src/json-value.ts @@ -1,7 +1,7 @@ -import type { JsonValue } from "@earendil-works/chord/types"; +import type { JsonValue } from "@earendil-works/chord"; import Type from "typebox"; /** Static JSON contract. Concrete serializers are responsible for rejecting unsupported runtime values. */ export const JsonValueSchema = Type.Unsafe(Type.Unknown()); -export type { JsonValue } from "@earendil-works/chord/types"; +export type { JsonValue } from "@earendil-works/chord"; diff --git a/tsconfig.json b/tsconfig.json index 62b44ddaf..2b7eb1f5c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,9 +7,7 @@ "paths": { "*": ["./*"], "@earendil-works/chord": ["./packages/chord/src/index.ts"], - "@earendil-works/chord/api": ["./packages/chord/src/api.ts"], "@earendil-works/chord/context": ["./packages/chord/src/context/index.ts"], - "@earendil-works/chord/types": ["./packages/chord/src/types.ts"], "@earendil-works/pi-telemetry": ["./packages/telemetry/src/index.ts"], "@earendil-works/pi-telemetry/testing": ["./packages/telemetry/src/testing/index.ts"], "@earendil-works/pi-ai": ["./packages/ai/src/index.ts"],