@creatornader/agent-bridge 0.2.0 → 0.3.1
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/CHANGELOG.md +86 -4
- package/README.md +567 -55
- package/ROADMAP.md +114 -0
- package/SECURITY.md +90 -0
- package/SKILL.md +68 -2
- package/bin/agent-bridge +2 -2
- package/clients/claude-desktop.json +3 -1
- package/dist/archive.d.ts +163 -0
- package/dist/archive.js +50 -0
- package/dist/archive.js.map +1 -0
- package/dist/bridge-domain-CBX3IVqC.d.ts +153 -0
- package/dist/{bridge-service-CfqMcMAn.d.ts → bridge-service-hX1ZQp4W.d.ts} +15 -5
- package/dist/bridge-store-DPVSCwfs.d.ts +102 -0
- package/dist/bridge.d.ts +76 -17
- package/dist/bridge.js +52 -24
- package/dist/chunk-2DFNOLMO.js +618 -0
- package/dist/chunk-2DFNOLMO.js.map +1 -0
- package/dist/{chunk-KVR4JBRF.js → chunk-2EVLG3YA.js} +2 -2
- package/dist/{chunk-KVR4JBRF.js.map → chunk-2EVLG3YA.js.map} +1 -1
- package/dist/chunk-45BZGB77.js +709 -0
- package/dist/chunk-45BZGB77.js.map +1 -0
- package/dist/chunk-4VB44KJU.js +230 -0
- package/dist/chunk-4VB44KJU.js.map +1 -0
- package/dist/chunk-5GMB3A77.js +1013 -0
- package/dist/chunk-5GMB3A77.js.map +1 -0
- package/dist/chunk-A6W4QALF.js +1258 -0
- package/dist/chunk-A6W4QALF.js.map +1 -0
- package/dist/chunk-BZLMF5O5.js +328 -0
- package/dist/chunk-BZLMF5O5.js.map +1 -0
- package/dist/{chunk-AXL2I7FH.js → chunk-CEXBMOI5.js} +240 -79
- package/dist/chunk-CEXBMOI5.js.map +1 -0
- package/dist/chunk-GADH244D.js +527 -0
- package/dist/chunk-GADH244D.js.map +1 -0
- package/dist/chunk-MBPZXTJA.js +2428 -0
- package/dist/chunk-MBPZXTJA.js.map +1 -0
- package/dist/chunk-NCO7RLBM.js +146 -0
- package/dist/chunk-NCO7RLBM.js.map +1 -0
- package/dist/chunk-Q6PPMXJC.js +1050 -0
- package/dist/chunk-Q6PPMXJC.js.map +1 -0
- package/dist/{chunk-4KAOBC5X.js → chunk-SPSMZOCJ.js} +190 -165
- package/dist/chunk-SPSMZOCJ.js.map +1 -0
- package/dist/chunk-UAHMP6GC.js +54 -0
- package/dist/chunk-UAHMP6GC.js.map +1 -0
- package/dist/{chunk-YD6YJATN.js → chunk-VOQIDTCJ.js} +4 -2
- package/dist/chunk-VOQIDTCJ.js.map +1 -0
- package/dist/chunk-WAI2IYIQ.js +554 -0
- package/dist/chunk-WAI2IYIQ.js.map +1 -0
- package/dist/cli.d.ts +2 -1
- package/dist/cli.js +3555 -214
- package/dist/cli.js.map +1 -1
- package/dist/client-config.d.ts +1 -1
- package/dist/client-config.js +1 -1
- package/dist/client-runtime.d.ts +10 -6
- package/dist/client-runtime.js +9 -6
- package/dist/contracts/generate.d.ts +2 -0
- package/dist/contracts/generate.js +247 -0
- package/dist/contracts/generate.js.map +1 -0
- package/dist/dr.d.ts +324 -0
- package/dist/dr.js +124 -0
- package/dist/dr.js.map +1 -0
- package/dist/gateway-CggQ8vTC.d.ts +78 -0
- package/dist/gateway-main.js +190 -8
- package/dist/gateway-main.js.map +1 -1
- package/dist/gateway.d.ts +4 -3
- package/dist/gateway.js +4 -3
- package/dist/index.js +11 -8
- package/dist/index.js.map +1 -1
- package/dist/postgres-bridge-store-Bfd3hRId.d.ts +49 -0
- package/dist/server.d.ts +3 -2
- package/dist/server.js +13 -8
- package/dist/sqlite.d.ts +94 -12
- package/dist/sqlite.js +7 -4
- package/docs/architecture-v2.md +394 -0
- package/docs/decisions/0001-protocol-layers-and-acknowledgment-semantics.md +85 -0
- package/docs/decisions/0002-canonical-operation-contract-registry.md +46 -0
- package/docs/decisions/0003-host-adapters-and-consumer-instance-keys.md +88 -0
- package/docs/ecosystem.md +86 -0
- package/docs/postmortems/2026-07-08-wrapper-source-drift.md +82 -0
- package/docs/troubleshooting.md +89 -0
- package/llms.txt +107 -6
- package/openapi/agent-bridge-v2.openapi.json +9610 -0
- package/package.json +24 -4
- package/schemas/agent-bridge-v2.capabilities.json +1829 -0
- package/schemas/agent-bridge-v2.mcp.json +2074 -0
- package/schemas/agent-bridge-v2.schema.json +4560 -0
- package/sql/migrations/008_message_projects.sql +36 -0
- package/sql/migrations/009_mailbox_query_indexes.sql +28 -0
- package/sql/migrations/010_publisher_delivery_policy.sql +210 -0
- package/sql/migrations/011_credential_security.sql +875 -0
- package/sql/migrations/012_request_authority.sql +177 -0
- package/sql/migrations/013_row_isolation.sql +495 -0
- package/sql/migrations/014_owner_control_plane.sql +1641 -0
- package/sql/migrations/015_portable_archives.sql +1813 -0
- package/sql/migrations/016_native_dr_fence.sql +1005 -0
- package/bin/CLAUDE.md +0 -11
- package/dist/bridge-domain-BcnBeHOn.d.ts +0 -97
- package/dist/bridge-store-BuGjxTn4.d.ts +0 -61
- package/dist/chunk-4KAOBC5X.js.map +0 -1
- package/dist/chunk-6MAZ6YLZ.js +0 -146
- package/dist/chunk-6MAZ6YLZ.js.map +0 -1
- package/dist/chunk-AXL2I7FH.js.map +0 -1
- package/dist/chunk-BV6W4AJK.js +0 -211
- package/dist/chunk-BV6W4AJK.js.map +0 -1
- package/dist/chunk-CKSKUBDQ.js +0 -153
- package/dist/chunk-CKSKUBDQ.js.map +0 -1
- package/dist/chunk-JOUBDRYX.js +0 -272
- package/dist/chunk-JOUBDRYX.js.map +0 -1
- package/dist/chunk-JTC5YURG.js +0 -49
- package/dist/chunk-JTC5YURG.js.map +0 -1
- package/dist/chunk-O26W5QHS.js +0 -409
- package/dist/chunk-O26W5QHS.js.map +0 -1
- package/dist/chunk-WEULPMUY.js +0 -988
- package/dist/chunk-WEULPMUY.js.map +0 -1
- package/dist/chunk-YD6YJATN.js.map +0 -1
- package/dist/gateway-BULozv3K.d.ts +0 -54
package/dist/client-config.d.ts
CHANGED
package/dist/client-config.js
CHANGED
package/dist/client-runtime.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { B as BridgeService } from './bridge-service-
|
|
2
|
-
import { a as BridgeStore } from './bridge-store-
|
|
1
|
+
import { B as BridgeService } from './bridge-service-hX1ZQp4W.js';
|
|
2
|
+
import { a as BridgeStore } from './bridge-store-DPVSCwfs.js';
|
|
3
3
|
import { ClientConfig } from './client-config.js';
|
|
4
|
-
import './bridge-domain-
|
|
4
|
+
import './bridge-domain-CBX3IVqC.js';
|
|
5
5
|
|
|
6
6
|
interface ClientRuntime {
|
|
7
7
|
config: ClientConfig;
|
|
@@ -9,7 +9,11 @@ interface ClientRuntime {
|
|
|
9
9
|
service: BridgeService;
|
|
10
10
|
close(): Promise<void>;
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
interface ClientRuntimeOptions {
|
|
13
|
+
autoSync?: boolean;
|
|
14
|
+
initializationMode?: "active" | "passive";
|
|
15
|
+
}
|
|
16
|
+
declare function createStore(config: ClientConfig, options?: ClientRuntimeOptions): BridgeStore;
|
|
17
|
+
declare function createClientRuntime(config: ClientConfig, options?: ClientRuntimeOptions): Promise<ClientRuntime>;
|
|
14
18
|
|
|
15
|
-
export { type ClientRuntime, createClientRuntime, createStore };
|
|
19
|
+
export { type ClientRuntime, type ClientRuntimeOptions, createClientRuntime, createStore };
|
package/dist/client-runtime.js
CHANGED
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createClientRuntime,
|
|
4
4
|
createStore
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-UAHMP6GC.js";
|
|
6
|
+
import "./chunk-CEXBMOI5.js";
|
|
7
|
+
import "./chunk-Q6PPMXJC.js";
|
|
8
|
+
import "./chunk-5GMB3A77.js";
|
|
9
|
+
import "./chunk-NCO7RLBM.js";
|
|
10
|
+
import "./chunk-VOQIDTCJ.js";
|
|
11
|
+
import "./chunk-4VB44KJU.js";
|
|
12
|
+
import "./chunk-GADH244D.js";
|
|
13
|
+
import "./chunk-BZLMF5O5.js";
|
|
11
14
|
export {
|
|
12
15
|
createClientRuntime,
|
|
13
16
|
createStore
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
ErrorEnvelopeSchema,
|
|
4
|
+
LegacyDeliverySchema,
|
|
5
|
+
LegacyMessageDraftSchema,
|
|
6
|
+
LegacyMessageSchema,
|
|
7
|
+
PROTOCOL_HEADER,
|
|
8
|
+
PROTOCOL_VERSION,
|
|
9
|
+
SCOPE_ENFORCEMENT,
|
|
10
|
+
SUPPORTED_PROTOCOL_HEADER,
|
|
11
|
+
SUPPORTED_PROTOCOL_VERSIONS,
|
|
12
|
+
capabilityDocument,
|
|
13
|
+
operations
|
|
14
|
+
} from "../chunk-GADH244D.js";
|
|
15
|
+
|
|
16
|
+
// src/contracts/generate.ts
|
|
17
|
+
import { mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
18
|
+
import { dirname, resolve } from "path";
|
|
19
|
+
import { fileURLToPath } from "url";
|
|
20
|
+
|
|
21
|
+
// src/contracts/artifact-format.ts
|
|
22
|
+
function formatContractArtifact(value) {
|
|
23
|
+
return `${JSON.stringify(value, null, 2)}
|
|
24
|
+
`;
|
|
25
|
+
}
|
|
26
|
+
function normalizeContractArtifact(contents) {
|
|
27
|
+
return contents.replace(/\r\n?/g, "\n");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/contracts/generate.ts
|
|
31
|
+
function clone(value) {
|
|
32
|
+
return JSON.parse(JSON.stringify(value));
|
|
33
|
+
}
|
|
34
|
+
function objectWithout(schema, excluded) {
|
|
35
|
+
const result = clone(schema);
|
|
36
|
+
if (!result.properties) return result;
|
|
37
|
+
result.properties = Object.fromEntries(Object.entries(result.properties).filter(([name]) => !excluded.has(name)));
|
|
38
|
+
if (Array.isArray(result.required)) {
|
|
39
|
+
result.required = result.required.filter((name) => !excluded.has(name));
|
|
40
|
+
if (!result.required.length) delete result.required;
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
var scopeEnforcementByProvider = {
|
|
45
|
+
local: false,
|
|
46
|
+
gateway: SCOPE_ENFORCEMENT,
|
|
47
|
+
"legacy-supabase": false
|
|
48
|
+
};
|
|
49
|
+
var schemas = {
|
|
50
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
51
|
+
$id: "https://agent-bridge.dev/schemas/v2/operations.json",
|
|
52
|
+
title: "Agent Bridge v2 operation contracts",
|
|
53
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
54
|
+
scopeEnforcementByProvider,
|
|
55
|
+
$defs: {
|
|
56
|
+
ErrorEnvelope: ErrorEnvelopeSchema,
|
|
57
|
+
legacy20MessageDraft: LegacyMessageDraftSchema,
|
|
58
|
+
legacy20Message: LegacyMessageSchema,
|
|
59
|
+
legacy20Delivery: LegacyDeliverySchema,
|
|
60
|
+
...Object.fromEntries(operations.flatMap((operation) => [
|
|
61
|
+
[`${operation.id}Request`, operation.request],
|
|
62
|
+
[`${operation.id}Response`, operation.response],
|
|
63
|
+
...operation.cli ? [[`${operation.id}CliResponse`, operation.cli.response ?? operation.response]] : [],
|
|
64
|
+
...operation.cli?.variants?.map((variant) => [
|
|
65
|
+
`${operation.id}CliVariant${variant.command.replace(/(^|[-_])(\w)/g, (_match, _separator, character) => character.toUpperCase())}Response`,
|
|
66
|
+
variant.response
|
|
67
|
+
]) ?? []
|
|
68
|
+
]))
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var protocolHeaders = {
|
|
72
|
+
[PROTOCOL_HEADER]: {
|
|
73
|
+
description: "Selected Agent Bridge protocol version.",
|
|
74
|
+
required: true,
|
|
75
|
+
schema: { type: "string", enum: [...SUPPORTED_PROTOCOL_VERSIONS] }
|
|
76
|
+
},
|
|
77
|
+
[SUPPORTED_PROTOCOL_HEADER]: {
|
|
78
|
+
description: "Comma-separated protocol versions supported by this gateway.",
|
|
79
|
+
required: true,
|
|
80
|
+
schema: { type: "string" }
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
function errorResponse(description) {
|
|
84
|
+
return {
|
|
85
|
+
description,
|
|
86
|
+
headers: protocolHeaders,
|
|
87
|
+
content: { "application/json": { schema: { $ref: "#/components/schemas/ErrorEnvelope" } } }
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
var canonicalErrors = {
|
|
91
|
+
"400": errorResponse("The request does not match the operation contract."),
|
|
92
|
+
"401": errorResponse("The bearer credential is missing or invalid."),
|
|
93
|
+
"403": errorResponse("The credential cannot access the requested principal or origin."),
|
|
94
|
+
"404": errorResponse("The route or requested resource does not exist."),
|
|
95
|
+
"409": errorResponse("The request conflicts with current delivery or idempotency state."),
|
|
96
|
+
"413": errorResponse("The request body exceeds the configured limit."),
|
|
97
|
+
"415": errorResponse("The request content type is not application/json."),
|
|
98
|
+
"426": errorResponse("The requested protocol version is unsupported."),
|
|
99
|
+
"429": errorResponse("The gateway has rate-limited the request."),
|
|
100
|
+
"500": errorResponse("The gateway could not complete the request."),
|
|
101
|
+
"502": errorResponse("The upstream response does not match the selected protocol contract."),
|
|
102
|
+
"503": errorResponse("The backing service is unavailable."),
|
|
103
|
+
"504": errorResponse("The request exceeded the gateway deadline.")
|
|
104
|
+
};
|
|
105
|
+
var paths = {};
|
|
106
|
+
var _a;
|
|
107
|
+
for (const operation of operations.filter((entry) => entry.http)) {
|
|
108
|
+
const http = operation.http;
|
|
109
|
+
const pathItem = paths[_a = http.path] ?? (paths[_a] = {});
|
|
110
|
+
const pathNames = [...http.path.matchAll(/\{([^}]+)\}/g)].map((match) => match[1]);
|
|
111
|
+
const pathSet = new Set(pathNames);
|
|
112
|
+
const request = clone(operation.request);
|
|
113
|
+
const parameters = [{
|
|
114
|
+
name: PROTOCOL_HEADER,
|
|
115
|
+
in: "header",
|
|
116
|
+
required: true,
|
|
117
|
+
description: "This OpenAPI operation describes protocol 2.1. Headerless protocol 2.0 uses the separate schemas named by x-agent-bridge-protocol-2.0.",
|
|
118
|
+
schema: { type: "string", enum: [PROTOCOL_VERSION] }
|
|
119
|
+
}, ...pathNames.map((name) => ({
|
|
120
|
+
name,
|
|
121
|
+
in: "path",
|
|
122
|
+
required: true,
|
|
123
|
+
schema: request.properties?.[name] ?? { type: "string" }
|
|
124
|
+
}))];
|
|
125
|
+
if (http.method === "GET" && request.properties) {
|
|
126
|
+
for (const [propertyName, propertySchema] of Object.entries(request.properties)) {
|
|
127
|
+
if (pathSet.has(propertyName)) continue;
|
|
128
|
+
const queryName = propertyName === "types" ? "type" : propertyName === "states" ? "state" : propertyName;
|
|
129
|
+
const repeated = propertySchema.type === "array";
|
|
130
|
+
parameters.push({
|
|
131
|
+
name: queryName,
|
|
132
|
+
in: "query",
|
|
133
|
+
required: request.required?.includes(propertyName) ?? false,
|
|
134
|
+
...repeated ? { style: "form", explode: true } : {},
|
|
135
|
+
schema: propertySchema
|
|
136
|
+
});
|
|
137
|
+
for (const alias of http.queryAliases?.[propertyName] ?? []) {
|
|
138
|
+
parameters.push({
|
|
139
|
+
name: alias,
|
|
140
|
+
in: "query",
|
|
141
|
+
required: false,
|
|
142
|
+
deprecated: true,
|
|
143
|
+
description: `Compatibility alias for ${queryName}.`,
|
|
144
|
+
schema: propertySchema
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const contentType = http.responseContentType ?? "application/json";
|
|
150
|
+
const successStatus = String(http.successStatus ?? 200);
|
|
151
|
+
const successResponse = {
|
|
152
|
+
description: "Successful response.",
|
|
153
|
+
headers: protocolHeaders,
|
|
154
|
+
content: { [contentType]: { schema: clone(operation.response) } }
|
|
155
|
+
};
|
|
156
|
+
const bodySchema = objectWithout(request, pathSet);
|
|
157
|
+
const hasBodyFields = Object.keys(bodySchema.properties ?? {}).length > 0;
|
|
158
|
+
const hasRequiredBodyFields = Array.isArray(bodySchema.required) && bodySchema.required.length > 0;
|
|
159
|
+
pathItem[http.method.toLowerCase()] = {
|
|
160
|
+
operationId: operation.id,
|
|
161
|
+
summary: operation.summary,
|
|
162
|
+
security: [{ bearerAuth: [] }],
|
|
163
|
+
"x-agent-bridge-required-scopes": [...operation.scopes],
|
|
164
|
+
"x-agent-bridge-scope-enforcement": SCOPE_ENFORCEMENT,
|
|
165
|
+
...parameters.length ? { parameters } : {},
|
|
166
|
+
...http.method === "POST" && hasBodyFields ? {
|
|
167
|
+
requestBody: {
|
|
168
|
+
required: hasRequiredBodyFields,
|
|
169
|
+
content: { "application/json": { schema: bodySchema } }
|
|
170
|
+
}
|
|
171
|
+
} : {},
|
|
172
|
+
responses: { [successStatus]: successResponse, ...canonicalErrors }
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
var openapi = {
|
|
176
|
+
openapi: "3.1.2",
|
|
177
|
+
info: {
|
|
178
|
+
title: "Agent Bridge Gateway",
|
|
179
|
+
version: PROTOCOL_VERSION,
|
|
180
|
+
license: { name: "Apache-2.0", identifier: "Apache-2.0" }
|
|
181
|
+
},
|
|
182
|
+
servers: [{ url: "/" }],
|
|
183
|
+
"x-agent-bridge-protocol-versions": [...SUPPORTED_PROTOCOL_VERSIONS],
|
|
184
|
+
"x-agent-bridge-openapi-protocol-version": PROTOCOL_VERSION,
|
|
185
|
+
"x-agent-bridge-protocol-2.0": {
|
|
186
|
+
description: "Limited schema metadata for the released headerless 0.2.0 compatibility contract derived from d8184fe. This is not a complete OpenAPI route description. It does not support project, deliveryPolicy, delivery management/listing, or current delivery bookkeeping fields.",
|
|
187
|
+
requestSchemas: { publish_message: "#/x-agent-bridge-schemas-2.0/MessageDraft" },
|
|
188
|
+
responseSchemas: { message: "#/x-agent-bridge-schemas-2.0/Message", delivery: "#/x-agent-bridge-schemas-2.0/Delivery" }
|
|
189
|
+
},
|
|
190
|
+
"x-agent-bridge-schemas-2.0": {
|
|
191
|
+
MessageDraft: LegacyMessageDraftSchema,
|
|
192
|
+
Message: LegacyMessageSchema,
|
|
193
|
+
Delivery: LegacyDeliverySchema
|
|
194
|
+
},
|
|
195
|
+
"x-agent-bridge-scope-enforcement": SCOPE_ENFORCEMENT,
|
|
196
|
+
paths,
|
|
197
|
+
components: {
|
|
198
|
+
schemas: { ErrorEnvelope: ErrorEnvelopeSchema },
|
|
199
|
+
securitySchemes: { bearerAuth: { type: "http", scheme: "bearer" } }
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
var mcp = {
|
|
203
|
+
schemaVersion: "agent-bridge-mcp-manifest-v1",
|
|
204
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
205
|
+
scopeEnforcementByProvider,
|
|
206
|
+
tools: operations.filter((entry) => entry.mcp).map((entry) => ({
|
|
207
|
+
name: entry.mcp.name,
|
|
208
|
+
description: entry.summary,
|
|
209
|
+
inputSchema: entry.request,
|
|
210
|
+
outputSchema: entry.response,
|
|
211
|
+
requiredScopes: entry.scopes,
|
|
212
|
+
providers: entry.providers
|
|
213
|
+
}))
|
|
214
|
+
};
|
|
215
|
+
var root = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
|
|
216
|
+
var outputs = /* @__PURE__ */ new Map([
|
|
217
|
+
[resolve(root, "schemas/agent-bridge-v2.schema.json"), formatContractArtifact(schemas)],
|
|
218
|
+
[resolve(root, "openapi/agent-bridge-v2.openapi.json"), formatContractArtifact(openapi)],
|
|
219
|
+
[resolve(root, "schemas/agent-bridge-v2.mcp.json"), formatContractArtifact(mcp)],
|
|
220
|
+
[resolve(root, "schemas/agent-bridge-v2.capabilities.json"), formatContractArtifact(capabilityDocument())]
|
|
221
|
+
]);
|
|
222
|
+
var check = process.argv.includes("--check");
|
|
223
|
+
var drift = [];
|
|
224
|
+
for (const [path, contents] of outputs) {
|
|
225
|
+
if (check) {
|
|
226
|
+
let current = "";
|
|
227
|
+
try {
|
|
228
|
+
current = readFileSync(path, "utf8");
|
|
229
|
+
} catch {
|
|
230
|
+
}
|
|
231
|
+
if (normalizeContractArtifact(current) !== normalizeContractArtifact(contents)) {
|
|
232
|
+
drift.push(path.slice(root.length + 1));
|
|
233
|
+
}
|
|
234
|
+
} else {
|
|
235
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
236
|
+
writeFileSync(path, contents);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (drift.length) {
|
|
240
|
+
for (const path of drift) process.stderr.write(`ERROR contract artifact drift: ${path}
|
|
241
|
+
`);
|
|
242
|
+
process.exitCode = 1;
|
|
243
|
+
} else {
|
|
244
|
+
process.stdout.write(`contracts ${check ? "match" : "generated"}: ${outputs.size} artifacts, ${operations.length} operations
|
|
245
|
+
`);
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/contracts/generate.ts","../../src/contracts/artifact-format.ts"],"sourcesContent":["import { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { formatContractArtifact, normalizeContractArtifact } from \"./artifact-format.js\";\nimport {\n capabilityDocument,\n ErrorEnvelopeSchema,\n LegacyDeliverySchema,\n LegacyMessageDraftSchema,\n LegacyMessageSchema,\n LEGACY_PROTOCOL_VERSION,\n operations,\n PROTOCOL_HEADER,\n PROTOCOL_VERSION,\n SCOPE_ENFORCEMENT,\n SUPPORTED_PROTOCOL_HEADER,\n SUPPORTED_PROTOCOL_VERSIONS,\n} from \"./registry.js\";\n\nfunction clone<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nfunction objectWithout(schema: Record<string, any>, excluded: ReadonlySet<string>): Record<string, any> {\n const result = clone(schema);\n if (!result.properties) return result;\n result.properties = Object.fromEntries(Object.entries(result.properties).filter(([name]) => !excluded.has(name)));\n if (Array.isArray(result.required)) {\n result.required = result.required.filter((name: string) => !excluded.has(name));\n if (!result.required.length) delete result.required;\n }\n return result;\n}\n\nconst scopeEnforcementByProvider = {\n local: false,\n gateway: SCOPE_ENFORCEMENT,\n \"legacy-supabase\": false,\n};\n\nconst schemas = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n $id: \"https://agent-bridge.dev/schemas/v2/operations.json\",\n title: \"Agent Bridge v2 operation contracts\",\n protocolVersion: PROTOCOL_VERSION,\n scopeEnforcementByProvider,\n $defs: {\n ErrorEnvelope: ErrorEnvelopeSchema,\n legacy20MessageDraft: LegacyMessageDraftSchema,\n legacy20Message: LegacyMessageSchema,\n legacy20Delivery: LegacyDeliverySchema,\n ...Object.fromEntries(operations.flatMap((operation) => [\n [`${operation.id}Request`, operation.request],\n [`${operation.id}Response`, operation.response],\n ...(operation.cli ? [[`${operation.id}CliResponse`, operation.cli.response ?? operation.response] as const] : []),\n ...(operation.cli?.variants?.map((variant) => [\n `${operation.id}CliVariant${variant.command.replace(/(^|[-_])(\\w)/g, (_match, _separator, character: string) => character.toUpperCase())}Response`,\n variant.response,\n ] as const) ?? []),\n ])),\n },\n};\n\nconst protocolHeaders = {\n [PROTOCOL_HEADER]: {\n description: \"Selected Agent Bridge protocol version.\",\n required: true,\n schema: { type: \"string\", enum: [...SUPPORTED_PROTOCOL_VERSIONS] },\n },\n [SUPPORTED_PROTOCOL_HEADER]: {\n description: \"Comma-separated protocol versions supported by this gateway.\",\n required: true,\n schema: { type: \"string\" },\n },\n};\n\nfunction errorResponse(description: string) {\n return {\n description,\n headers: protocolHeaders,\n content: { \"application/json\": { schema: { $ref: \"#/components/schemas/ErrorEnvelope\" } } },\n };\n}\n\nconst canonicalErrors = {\n \"400\": errorResponse(\"The request does not match the operation contract.\"),\n \"401\": errorResponse(\"The bearer credential is missing or invalid.\"),\n \"403\": errorResponse(\"The credential cannot access the requested principal or origin.\"),\n \"404\": errorResponse(\"The route or requested resource does not exist.\"),\n \"409\": errorResponse(\"The request conflicts with current delivery or idempotency state.\"),\n \"413\": errorResponse(\"The request body exceeds the configured limit.\"),\n \"415\": errorResponse(\"The request content type is not application/json.\"),\n \"426\": errorResponse(\"The requested protocol version is unsupported.\"),\n \"429\": errorResponse(\"The gateway has rate-limited the request.\"),\n \"500\": errorResponse(\"The gateway could not complete the request.\"),\n \"502\": errorResponse(\"The upstream response does not match the selected protocol contract.\"),\n \"503\": errorResponse(\"The backing service is unavailable.\"),\n \"504\": errorResponse(\"The request exceeded the gateway deadline.\"),\n};\n\nconst paths: Record<string, Record<string, unknown>> = {};\nfor (const operation of operations.filter((entry) => entry.http)) {\n const http = operation.http!;\n const pathItem = paths[http.path] ??= {};\n const pathNames = [...http.path.matchAll(/\\{([^}]+)\\}/g)].map((match) => match[1]!);\n const pathSet = new Set(pathNames);\n const request = clone(operation.request as Record<string, any>);\n const parameters: Array<Record<string, unknown>> = [{\n name: PROTOCOL_HEADER,\n in: \"header\",\n required: true,\n description: \"This OpenAPI operation describes protocol 2.1. Headerless protocol 2.0 uses the separate schemas named by x-agent-bridge-protocol-2.0.\",\n schema: { type: \"string\", enum: [PROTOCOL_VERSION] },\n }, ...pathNames.map((name) => ({\n name,\n in: \"path\",\n required: true,\n schema: request.properties?.[name] ?? { type: \"string\" },\n }))];\n\n if (http.method === \"GET\" && request.properties) {\n for (const [propertyName, propertySchema] of Object.entries(request.properties) as Array<[string, Record<string, any>]>) {\n if (pathSet.has(propertyName)) continue;\n const queryName = propertyName === \"types\" ? \"type\" : propertyName === \"states\" ? \"state\" : propertyName;\n const repeated = propertySchema.type === \"array\";\n parameters.push({\n name: queryName,\n in: \"query\",\n required: request.required?.includes(propertyName) ?? false,\n ...(repeated ? { style: \"form\", explode: true } : {}),\n schema: propertySchema,\n });\n for (const alias of http.queryAliases?.[propertyName] ?? []) {\n parameters.push({\n name: alias,\n in: \"query\",\n required: false,\n deprecated: true,\n description: `Compatibility alias for ${queryName}.`,\n schema: propertySchema,\n });\n }\n }\n }\n\n const contentType = http.responseContentType ?? \"application/json\";\n const successStatus = String(http.successStatus ?? 200);\n const successResponse = {\n description: \"Successful response.\",\n headers: protocolHeaders,\n content: { [contentType]: { schema: clone(operation.response) } },\n };\n const bodySchema = objectWithout(request, pathSet);\n const hasBodyFields = Object.keys(bodySchema.properties ?? {}).length > 0;\n const hasRequiredBodyFields = Array.isArray(bodySchema.required) && bodySchema.required.length > 0;\n pathItem[http.method.toLowerCase()] = {\n operationId: operation.id,\n summary: operation.summary,\n security: [{ bearerAuth: [] }],\n \"x-agent-bridge-required-scopes\": [...operation.scopes],\n \"x-agent-bridge-scope-enforcement\": SCOPE_ENFORCEMENT,\n ...(parameters.length ? { parameters } : {}),\n ...(http.method === \"POST\" && hasBodyFields ? {\n requestBody: {\n required: hasRequiredBodyFields,\n content: { \"application/json\": { schema: bodySchema } },\n },\n } : {}),\n responses: { [successStatus]: successResponse, ...canonicalErrors },\n };\n}\n\nconst openapi = {\n openapi: \"3.1.2\",\n info: {\n title: \"Agent Bridge Gateway\",\n version: PROTOCOL_VERSION,\n license: { name: \"Apache-2.0\", identifier: \"Apache-2.0\" },\n },\n servers: [{ url: \"/\" }],\n \"x-agent-bridge-protocol-versions\": [...SUPPORTED_PROTOCOL_VERSIONS],\n \"x-agent-bridge-openapi-protocol-version\": PROTOCOL_VERSION,\n \"x-agent-bridge-protocol-2.0\": {\n description: \"Limited schema metadata for the released headerless 0.2.0 compatibility contract derived from d8184fe. This is not a complete OpenAPI route description. It does not support project, deliveryPolicy, delivery management/listing, or current delivery bookkeeping fields.\",\n requestSchemas: { publish_message: \"#/x-agent-bridge-schemas-2.0/MessageDraft\" },\n responseSchemas: { message: \"#/x-agent-bridge-schemas-2.0/Message\", delivery: \"#/x-agent-bridge-schemas-2.0/Delivery\" },\n },\n \"x-agent-bridge-schemas-2.0\": {\n MessageDraft: LegacyMessageDraftSchema,\n Message: LegacyMessageSchema,\n Delivery: LegacyDeliverySchema,\n },\n \"x-agent-bridge-scope-enforcement\": SCOPE_ENFORCEMENT,\n paths,\n components: {\n schemas: { ErrorEnvelope: ErrorEnvelopeSchema },\n securitySchemes: { bearerAuth: { type: \"http\", scheme: \"bearer\" } },\n },\n};\n\nconst mcp = {\n schemaVersion: \"agent-bridge-mcp-manifest-v1\",\n protocolVersion: PROTOCOL_VERSION,\n scopeEnforcementByProvider,\n tools: operations.filter((entry) => entry.mcp).map((entry) => ({\n name: entry.mcp!.name,\n description: entry.summary,\n inputSchema: entry.request,\n outputSchema: entry.response,\n requiredScopes: entry.scopes,\n providers: entry.providers,\n })),\n};\n\nconst root = resolve(dirname(fileURLToPath(import.meta.url)), \"../..\");\nconst outputs = new Map([\n [resolve(root, \"schemas/agent-bridge-v2.schema.json\"), formatContractArtifact(schemas)],\n [resolve(root, \"openapi/agent-bridge-v2.openapi.json\"), formatContractArtifact(openapi)],\n [resolve(root, \"schemas/agent-bridge-v2.mcp.json\"), formatContractArtifact(mcp)],\n [resolve(root, \"schemas/agent-bridge-v2.capabilities.json\"), formatContractArtifact(capabilityDocument())],\n]);\nconst check = process.argv.includes(\"--check\");\nconst drift: string[] = [];\nfor (const [path, contents] of outputs) {\n if (check) {\n let current = \"\";\n try { current = readFileSync(path, \"utf8\"); } catch {}\n if (normalizeContractArtifact(current) !== normalizeContractArtifact(contents)) {\n drift.push(path.slice(root.length + 1));\n }\n } else {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, contents);\n }\n}\nif (drift.length) {\n for (const path of drift) process.stderr.write(`ERROR contract artifact drift: ${path}\\n`);\n process.exitCode = 1;\n} else {\n process.stdout.write(`contracts ${check ? \"match\" : \"generated\"}: ${outputs.size} artifacts, ${operations.length} operations\\n`);\n}\n","export function formatContractArtifact(value: unknown): string {\n return `${JSON.stringify(value, null, 2)}\\n`;\n}\n\nexport function normalizeContractArtifact(contents: string): string {\n return contents.replace(/\\r\\n?/g, \"\\n\");\n}\n"],"mappings":"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","names":[]}
|