@cotal-ai/linear 0.0.0-bootstrap.0 → 0.76.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/serve.js ADDED
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Serving one Linear account as a registered Cotal endpoint.
3
+ *
4
+ * Two layers. {@link runLinearEndpoint} is the generic runner: it takes an already-authorized,
5
+ * scoped serve bundle (the `authorizeServeGrant` artifact plus a serve credential source) and serves
6
+ * the fixed Linear contract on it. A hosted embedder that issues serve credentials its own way uses
7
+ * it directly. {@link registerLinearEndpoint} is the local operator setup for a static-auth mesh: it
8
+ * walks the same registration path every ordinary endpoint walks (contract-store publish, issuance
9
+ * gate, registration barrier, serve grant, ready status, fenced `endpoint-serve` mint) over one-shot
10
+ * `endpoint-serve-executor` connections, and keeps the space signer inside the operator process for
11
+ * renewal. The signer is never returned, logged, or passed to the runner.
12
+ *
13
+ * The endpoint name comes from operator configuration and must be a reverse-DNS name in a namespace
14
+ * the operator owns. The name authority authorizes exactly that name for the local owner, nothing
15
+ * else. A per-user-auth mesh is refused: its serve credentials come from the remote issuer, which
16
+ * this package has no client for.
17
+ */
18
+ import { credsAuthenticator } from "@nats-io/transport-node";
19
+ import { Kvm } from "@nats-io/kv";
20
+ import { authorizeServeGrant, contractArtifactCanonicalBytes, contractStoreContext, CotalEndpoint, deregisterServiceInstance, DEV_OWNER, dialerFor, endpointRegistrationBarrier, epAuthBucket, inspectCredHealth, mintCreds, mintLifecycleUid, newIdentity, principalKey, provisionAgent, provisionEndpointGateOpen, publishContractArtifact, readEndpointGateGeneration, recordsBucket, registerServiceInstance, serveEndpoint, serveIssuanceGateKv, SERVICE_READY, standaloneConnectOpts, writeServiceStatus, } from "@cotal-ai/core";
21
+ import { linearClusterArtifacts, linearCommandDefs, linearContractArtifactValues, LINEAR_COMMANDS } from "./contract.js";
22
+ /** A reverse-DNS endpoint name: at least two lowercase labels, as the operator configured it. */
23
+ export function assertLinearEndpointName(name) {
24
+ if (!/^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/.test(name) || name.length > 200)
25
+ throw new Error(`"${name}" is not a reverse-DNS endpoint name (for example com.example.linear); use a namespace you own`);
26
+ return name;
27
+ }
28
+ function within(p, ms) {
29
+ return Promise.race([p, new Promise((r) => setTimeout(() => r(undefined), ms).unref())]);
30
+ }
31
+ /** Serve the fixed Linear contract on an authorized bundle. Command names, schemas and the
32
+ * `linear.mcp` capability are fixed; the upstream result is returned as data and never parsed. */
33
+ export async function runLinearEndpoint(bundle, upstream) {
34
+ const enc = new TextEncoder();
35
+ const nc = await dialerFor(bundle.servers)({
36
+ servers: bundle.servers,
37
+ ...(bundle.tls ? { tls: {} } : {}),
38
+ authenticator: (nonce) => credsAuthenticator(enc.encode(bundle.creds()))(nonce),
39
+ inboxPrefix: `_INBOX_${bundle.identity.id}`,
40
+ maxReconnectAttempts: -1,
41
+ });
42
+ let handle;
43
+ try {
44
+ handle = serveEndpoint(nc, bundle.space, bundle.grant, linearCommandDefs(upstream), { public: true });
45
+ }
46
+ catch (e) {
47
+ await nc.drain().catch(() => nc.close());
48
+ throw e;
49
+ }
50
+ return {
51
+ endpoint: bundle.grant.endpoint,
52
+ instanceId: bundle.grant.instanceId,
53
+ epoch: bundle.grant.epoch,
54
+ closed: nc.closed().then((e) => e ?? undefined),
55
+ async stop(graceMs = 10_000) {
56
+ await within(handle.stop(), graceMs);
57
+ await within(nc.drain().catch(() => nc.close()), graceMs);
58
+ if (!nc.isClosed())
59
+ await nc.close().catch(() => { });
60
+ await upstream.close(graceMs);
61
+ },
62
+ };
63
+ }
64
+ /**
65
+ * Register `endpoint` as a fresh instance on a static-auth mesh and mint its serve credential.
66
+ * `auth` is the operator's own space authority; it stays in this closure for renewal and
67
+ * deregistration and is never placed in the returned bundle.
68
+ */
69
+ export async function registerLinearEndpoint(opts) {
70
+ const { auth, servers, space, tls } = opts;
71
+ if (auth.space !== space)
72
+ throw new Error(`the space authority is for "${auth.space}", not "${space}"`);
73
+ const endpoint = assertLinearEndpointName(opts.endpoint);
74
+ const instanceId = mintLifecycleUid();
75
+ const opId = mintLifecycleUid();
76
+ const identity = newIdentity();
77
+ const artifacts = linearClusterArtifacts();
78
+ const store = new Map([[artifacts.rootDigest, artifacts.document], [artifacts.closureDigest, artifacts.manifest]]);
79
+ const readClusterArtifact = (digest) => store.get(digest);
80
+ // Operator configuration is the trusted source: this name, for the local owner, and nothing else.
81
+ const authority = {
82
+ authorize: (name, owner) => ({ authorized: name === endpoint && owner === DEV_OWNER, revision: 0 }),
83
+ };
84
+ const withExecutor = async (fn) => {
85
+ const creds = await mintCreds(auth, newIdentity(), "endpoint-serve-executor", { endpointServeExecutor: { endpoint, instanceId } });
86
+ const nc = await dialerFor(servers)({ servers, ...standaloneConnectOpts({ creds, tls }), maxReconnectAttempts: 0 });
87
+ try {
88
+ const kvm = new Kvm(nc);
89
+ return await fn({ recordsKv: await kvm.open(recordsBucket(space)), authKv: await kvm.open(epAuthBucket(space)), nc });
90
+ }
91
+ finally {
92
+ await nc.drain().catch(() => nc.close());
93
+ }
94
+ };
95
+ const fenceOf = (authKv) => serveIssuanceGateKv(authKv, space, { endpoint, instanceId });
96
+ const epochOf = (authKv) => async () => {
97
+ const g = await fenceOf(authKv).observe();
98
+ if (g === null)
99
+ throw new Error(`no issuance gate for ${endpoint}/${instanceId}`);
100
+ return g.processEpoch;
101
+ };
102
+ const { grant, creds: first } = await withExecutor(async ({ recordsKv, authKv, nc }) => {
103
+ const storeCtx = await contractStoreContext(nc, space);
104
+ for (const value of [...linearContractArtifactValues(), artifacts.document, artifacts.manifest])
105
+ await publishContractArtifact(storeCtx, contractArtifactCanonicalBytes(value));
106
+ await provisionEndpointGateOpen(authKv, { endpoint, instanceId, principal: principalKey(DEV_OWNER, identity.id).key });
107
+ // A fresh instance has an empty credential family, so the barrier has nothing to evict.
108
+ const barrier = endpointRegistrationBarrier(authKv, space, { endpoint, instanceId, opId });
109
+ const spec = { endpoint, owner: DEV_OWNER, clusterDigests: [artifacts.closureDigest], protocol: { v: 1 } };
110
+ const { registrationRevision } = await registerServiceInstance(recordsKv, {
111
+ space, spec, instanceId, registrant: { owner: DEV_OWNER }, authority, barrier, readClusterArtifact,
112
+ observeHolderGeneration: (holder) => readEndpointGateGeneration(authKv, { endpoint, instanceId: holder }),
113
+ });
114
+ // The record exists from here on. A failure in any later step takes it back down before the
115
+ // error is reported, so a start that never reaches serving leaves no advertised instance; when
116
+ // the rollback itself fails, the error says so instead of claiming a clean refusal.
117
+ try {
118
+ const fence = fenceOf(authKv);
119
+ const observed = await fence.observe();
120
+ if (observed === null)
121
+ throw new Error(`the issuance gate for ${endpoint}/${instanceId} vanished after registration`);
122
+ const grant = await authorizeServeGrant(recordsKv, {
123
+ space, endpoint, instanceId, epoch: observed.processEpoch, holder: { owner: DEV_OWNER }, authority, readClusterArtifact,
124
+ readProcessEpoch: epochOf(authKv),
125
+ });
126
+ await writeServiceStatus(recordsKv, {
127
+ endpoint, instanceId, epoch: observed.processEpoch,
128
+ status: { state: SERVICE_READY, epoch: observed.processEpoch, observedSpecRevision: registrationRevision },
129
+ readProcessEpoch: epochOf(authKv),
130
+ });
131
+ const creds = await mintCreds(auth, identity, "endpoint-serve", { serveIssuance: fence, endpointServe: grant });
132
+ return { grant, creds };
133
+ }
134
+ catch (e) {
135
+ const why = e.message;
136
+ try {
137
+ await deregisterServiceInstance(recordsKv, { endpoint, instanceId, observeGeneration: () => readEndpointGateGeneration(authKv, { endpoint, instanceId }) });
138
+ }
139
+ catch (d) {
140
+ throw new Error(`${why}; the service record for ${endpoint}/${instanceId} could not be removed afterwards (${d.message}) and still advertises an instance nobody serves`);
141
+ }
142
+ throw new Error(`${why}; the service record for ${endpoint}/${instanceId} was removed again`);
143
+ }
144
+ });
145
+ let current = first;
146
+ const renew = async () => {
147
+ current = await withExecutor(({ authKv }) => mintCreds(auth, identity, "endpoint-serve", { serveIssuance: fenceOf(authKv), endpointServe: grant }));
148
+ return current;
149
+ };
150
+ const deregister = async () => {
151
+ await withExecutor(async ({ recordsKv, authKv }) => {
152
+ await deregisterServiceInstance(recordsKv, { endpoint, instanceId, observeGeneration: () => readEndpointGateGeneration(authKv, { endpoint, instanceId }) });
153
+ });
154
+ };
155
+ return { bundle: { servers, space, tls, identity, grant, creds: () => current }, renew, deregister };
156
+ }
157
+ /** Milliseconds until a credential reaches 75% of its remaining lifetime, or undefined when it is
158
+ * unbounded. */
159
+ export function renewalDelayMs(creds, nowMs = Date.now()) {
160
+ const exp = inspectCredHealth(creds).exp;
161
+ if (exp === undefined)
162
+ return undefined;
163
+ return Math.max(1_000, Math.floor((exp * 1000 - nowMs) * 0.75));
164
+ }
165
+ /** The caller rows for every Linear command on `endpoint`: what a least-privilege caller
166
+ * credential carries, and nothing more. */
167
+ export function linearCallerCapabilities(endpoint) {
168
+ assertLinearEndpointName(endpoint);
169
+ return LINEAR_COMMANDS.map((command) => ({ endpoint, command }));
170
+ }
171
+ /**
172
+ * Provision and mint a standalone caller for a static-auth mesh: the ordinary `agent` profile, its
173
+ * lifecycle-keyed mailboxes, and the exact request rows for the Linear commands on `endpoint`. It
174
+ * carries no spawn, run, admin or provisioner capability. The caller is an isolated, hand-launched
175
+ * seat the operator starts with this credential and lifecycle UID; managed spawns still refuse
176
+ * endpoint capabilities in static mode, which this does not change. The provisioner connection is
177
+ * minted for this call and stopped before it returns.
178
+ */
179
+ export async function provisionLinearCaller(auth, target, endpoint, opts = {}) {
180
+ if (auth.space !== target.space)
181
+ throw new Error(`the space authority is for "${auth.space}", not "${target.space}"`);
182
+ const identity = newIdentity();
183
+ const lifecycleUid = mintLifecycleUid();
184
+ const channels = opts.channels ?? [];
185
+ const prov = new CotalEndpoint({
186
+ space: target.space,
187
+ servers: target.servers,
188
+ tls: target.tls,
189
+ creds: await mintCreds(auth, newIdentity(), "provisioner"),
190
+ channels: [],
191
+ consume: false,
192
+ registerPresence: false,
193
+ watchPresence: false,
194
+ watchChannels: false,
195
+ card: { name: "linear-caller-provisioner", role: "provisioner", kind: "endpoint" },
196
+ });
197
+ prov.on("error", () => { });
198
+ try {
199
+ await prov.start();
200
+ const creds = await provisionAgent(prov, auth, identity, {
201
+ lifecycleUid,
202
+ endpointCapabilities: linearCallerCapabilities(endpoint),
203
+ allowSubscribe: channels,
204
+ allowPublish: channels,
205
+ subscribe: channels,
206
+ ...(opts.expiresInSeconds !== undefined ? { expiresInSeconds: opts.expiresInSeconds } : {}),
207
+ });
208
+ return { creds, identity: identity.id, lifecycleUid };
209
+ }
210
+ finally {
211
+ await prov.stop().catch(() => { });
212
+ }
213
+ }
214
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,148 @@
1
+ import type { LinearAccount } from "./account.js";
2
+ export interface LinearLimits {
3
+ /** Cap on one HTTP response body, checked before it is accumulated. */
4
+ maxResponseBytes: number;
5
+ /** Cap on the summed bytes of every discovery page. */
6
+ maxInventoryBytes: number;
7
+ /** Cap on the number of discovery pages across all lists. */
8
+ maxInventoryPages: number;
9
+ /** Cap on one inventory entry (a tool, resource, template or prompt) and on the initialize head
10
+ * (server, instructions, capabilities), measured as an agent tool prints them
11
+ * ({@link renderedBytes}), so every accepted entry and the first page fit the reply that tool
12
+ * can carry. One over it refuses the whole inventory, named. */
13
+ maxInventoryEntryBytes: number;
14
+ /** Upstream requests in flight at once. */
15
+ maxConcurrent: number;
16
+ /** Requests allowed to wait for a slot; one more is refused before dispatch. */
17
+ maxQueued: number;
18
+ /** Default and ceiling for one request's deadline. */
19
+ defaultTimeoutMs: number;
20
+ maxTimeoutMs: number;
21
+ /** An inventory older than this is read again before the next request, for servers that do not
22
+ * send list-changed notifications. */
23
+ maxInventoryAgeMs: number;
24
+ }
25
+ /** Bytes of `value` as an agent tool prints it: pretty JSON, nested where an inventory page nests an
26
+ * entry. Indentation grows with depth, so a compact entry of a few kilobytes can print to hundreds;
27
+ * this measure is never smaller than the wire form, so one bound covers both. */
28
+ export declare function renderedBytes(value: unknown): number;
29
+ export declare const DEFAULT_LIMITS: LinearLimits;
30
+ type Json = Record<string, unknown>;
31
+ export interface LinearInventory {
32
+ endpoint: string;
33
+ mode: LinearAccount["mode"];
34
+ server: {
35
+ name?: string;
36
+ version?: string;
37
+ };
38
+ instructions?: string;
39
+ /** The server's capabilities object, verbatim. */
40
+ capabilities: Json;
41
+ tools: Json[];
42
+ resources?: Json[];
43
+ resourceTemplates?: Json[];
44
+ prompts?: Json[];
45
+ /** Capability paths the server advertised that this package does not represent. */
46
+ unsupported: string[];
47
+ pages: number;
48
+ bytes: number;
49
+ fetchedAt: string;
50
+ /** Digest over everything above except `pages`, `bytes` and `fetchedAt`. */
51
+ digest: string;
52
+ }
53
+ export type Outcome = "not-executed" | "unknown";
54
+ /** The result of one forwarded request. `result` covers tool results whose `isError` is true. */
55
+ export type UpstreamReply = {
56
+ kind: "result";
57
+ result: Json;
58
+ inventoryDigest: string;
59
+ } | {
60
+ kind: "protocol-error";
61
+ code: number;
62
+ message: string;
63
+ data?: unknown;
64
+ outcome: Outcome;
65
+ } | {
66
+ kind: "refused";
67
+ reason: "queue-full" | "unknown-tool" | "not-advertised" | "stale-inventory" | "discovery-failed" | "deadline" | "closed";
68
+ detail: string;
69
+ outcome: "not-executed";
70
+ } | {
71
+ kind: "failed";
72
+ reason: "timeout" | "cancelled" | "output-too-large" | "session-expired" | "unauthenticated" | "permission-denied" | "rate-limited" | "transport";
73
+ detail: string;
74
+ outcome: Outcome;
75
+ };
76
+ export declare class LinearUpstream {
77
+ readonly account: LinearAccount;
78
+ readonly limits: LinearLimits;
79
+ private client?;
80
+ private transport?;
81
+ /** The server's `initialize` result, verbatim. */
82
+ private initialized?;
83
+ private connecting?;
84
+ private current?;
85
+ private stale;
86
+ private closed;
87
+ /** Aborts every queued or in-flight operation on {@link close}. */
88
+ private readonly closing;
89
+ private readonly slots;
90
+ private readonly url;
91
+ private readonly credential;
92
+ constructor(account: LinearAccount, limits?: LinearLimits);
93
+ /** The session, or the connect in flight shared by every caller waiting on it. `signal` is this
94
+ * caller's own deadline: when the last waiting caller leaves, the connect is ended with it, so an
95
+ * operation's deadline never leaves an initialize running behind nobody. */
96
+ private session;
97
+ private connect;
98
+ /** Forget a session the server ended or that failed. Its in-flight requests reject. */
99
+ private drop;
100
+ /** One SDK request in its own dispatch context: the schema still validates the shape, and the
101
+ * server's `result` is returned verbatim. */
102
+ private raw;
103
+ /** Complete discovery. Refuses on any cap rather than returning a partial inventory. `signal`
104
+ * bounds the whole read, including the slot wait and connect. */
105
+ inventory(opts?: {
106
+ refresh?: boolean;
107
+ signal?: AbortSignal;
108
+ }): Promise<LinearInventory>;
109
+ /** Forward `tools/call`. `inventoryDigest`, when given, must match the live inventory. */
110
+ callTool(req: {
111
+ name: string;
112
+ arguments?: Json;
113
+ inventoryDigest?: string;
114
+ timeoutMs?: number;
115
+ signal?: AbortSignal;
116
+ }): Promise<UpstreamReply>;
117
+ readResource(req: {
118
+ uri: string;
119
+ inventoryDigest?: string;
120
+ timeoutMs?: number;
121
+ signal?: AbortSignal;
122
+ }): Promise<UpstreamReply>;
123
+ getPrompt(req: {
124
+ name: string;
125
+ arguments?: Record<string, string>;
126
+ inventoryDigest?: string;
127
+ timeoutMs?: number;
128
+ signal?: AbortSignal;
129
+ }): Promise<UpstreamReply>;
130
+ complete(req: {
131
+ params: Json;
132
+ inventoryDigest?: string;
133
+ timeoutMs?: number;
134
+ signal?: AbortSignal;
135
+ }): Promise<UpstreamReply>;
136
+ private forward;
137
+ /** A failure as a status or class, with the bearer scrubbed. Response bodies are never kept. */
138
+ private describeError;
139
+ /** Remove the current bearer from text the server or a library produced. */
140
+ private scrub;
141
+ private scrubValue;
142
+ private classify;
143
+ /** Close the session and end it upstream, within `graceMs`. Queued requests refuse before
144
+ * dispatch; in-flight ones are cancelled and report `unknown`. */
145
+ close(graceMs?: number): Promise<void>;
146
+ }
147
+ export {};
148
+ //# sourceMappingURL=upstream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upstream.d.ts","sourceRoot":"","sources":["../src/upstream.ts"],"names":[],"mappings":"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"}