@beignet/cli 0.0.48 → 0.0.49
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 +34 -0
- package/README.md +76 -21
- package/dist/analysis/contract-factories.d.ts +17 -0
- package/dist/analysis/contract-factories.d.ts.map +1 -0
- package/dist/analysis/contract-factories.js +176 -0
- package/dist/analysis/contract-factories.js.map +1 -0
- package/dist/analysis/layers.d.ts +5 -0
- package/dist/analysis/layers.d.ts.map +1 -0
- package/dist/analysis/layers.js +172 -0
- package/dist/analysis/layers.js.map +1 -0
- package/dist/analysis/port-wiring.d.ts +23 -0
- package/dist/analysis/port-wiring.d.ts.map +1 -0
- package/dist/analysis/port-wiring.js +379 -0
- package/dist/analysis/port-wiring.js.map +1 -0
- package/dist/analysis/source-index.d.ts +5 -0
- package/dist/analysis/source-index.d.ts.map +1 -1
- package/dist/analysis/source-index.js +171 -42
- package/dist/analysis/source-index.js.map +1 -1
- package/dist/analysis/workspace.d.ts +10 -4
- package/dist/analysis/workspace.d.ts.map +1 -1
- package/dist/analysis/workspace.js +66 -6
- package/dist/analysis/workspace.js.map +1 -1
- package/dist/app-map.d.ts.map +1 -1
- package/dist/app-map.js +311 -92
- package/dist/app-map.js.map +1 -1
- package/dist/check.js +37 -3
- package/dist/check.js.map +1 -1
- package/dist/explain.js +4 -4
- package/dist/explain.js.map +1 -1
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +415 -168
- package/dist/inspect.js.map +1 -1
- package/dist/lint.d.ts.map +1 -1
- package/dist/lint.js +309 -487
- package/dist/lint.js.map +1 -1
- package/dist/make/inbox.d.ts.map +1 -1
- package/dist/make/inbox.js +11 -4
- package/dist/make/inbox.js.map +1 -1
- package/dist/make/payments.js +2 -2
- package/dist/make.d.ts.map +1 -1
- package/dist/make.js +144 -8
- package/dist/make.js.map +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +19 -19
- package/dist/mcp.js.map +1 -1
- package/dist/provider-add.d.ts.map +1 -1
- package/dist/provider-add.js +142 -7
- package/dist/provider-add.js.map +1 -1
- package/dist/registry-edits.d.ts +7 -0
- package/dist/registry-edits.d.ts.map +1 -1
- package/dist/registry-edits.js +237 -53
- package/dist/registry-edits.js.map +1 -1
- package/dist/templates/agents.d.ts.map +1 -1
- package/dist/templates/agents.js +16 -0
- package/dist/templates/agents.js.map +1 -1
- package/dist/templates/base.d.ts.map +1 -1
- package/dist/templates/base.js +9 -1
- package/dist/templates/base.js.map +1 -1
- package/dist/templates/server.d.ts.map +1 -1
- package/dist/templates/server.js +2 -0
- package/dist/templates/server.js.map +1 -1
- package/dist/templates/shared.d.ts +1 -0
- package/dist/templates/shared.d.ts.map +1 -1
- package/dist/templates/shared.js +3 -2
- package/dist/templates/shared.js.map +1 -1
- package/package.json +7 -6
- package/skills/app-structure/SKILL.md +46 -5
- package/src/analysis/contract-factories.ts +256 -0
- package/src/analysis/layers.ts +266 -0
- package/src/analysis/port-wiring.ts +506 -0
- package/src/analysis/source-index.ts +225 -57
- package/src/analysis/workspace.ts +115 -6
- package/src/app-map.ts +418 -109
- package/src/check.ts +51 -3
- package/src/explain.ts +4 -4
- package/src/inspect.ts +583 -215
- package/src/lint.ts +393 -643
- package/src/make/inbox.ts +11 -4
- package/src/make/payments.ts +2 -2
- package/src/make.ts +225 -8
- package/src/mcp.ts +19 -22
- package/src/provider-add.ts +186 -7
- package/src/registry-edits.ts +313 -63
- package/src/templates/agents.ts +16 -0
- package/src/templates/base.ts +9 -1
- package/src/templates/server.ts +2 -0
- package/src/templates/shared.ts +3 -2
package/src/make/inbox.ts
CHANGED
|
@@ -518,9 +518,9 @@ export const inboxNotificationSchema = z.object({
|
|
|
518
518
|
});
|
|
519
519
|
|
|
520
520
|
export const listInboxQuerySchema = z.object({
|
|
521
|
-
\tlimit: z.
|
|
521
|
+
\tlimit: z.number().int().min(1).max(50).default(20),
|
|
522
522
|
\tcursor: z.string().min(1).optional(),
|
|
523
|
-
\tunread: z.
|
|
523
|
+
\tunread: z.boolean().default(false),
|
|
524
524
|
});
|
|
525
525
|
|
|
526
526
|
export const listInboxOutputSchema = z.object({
|
|
@@ -659,7 +659,7 @@ export function inboxContractsFile(config: ResolvedBeignetConfig): string {
|
|
|
659
659
|
);
|
|
660
660
|
const errorsModule = aliasModule(resourceSharedErrorsPath(config));
|
|
661
661
|
|
|
662
|
-
return `import { defineContractGroup } from "@beignet/core/contracts";
|
|
662
|
+
return `import { defineContractGroup, defineQueryTransport, query } from "@beignet/core/contracts";
|
|
663
663
|
import {
|
|
664
664
|
\tinboxNotificationSchema,
|
|
665
665
|
\tlistInboxOutputSchema,
|
|
@@ -674,7 +674,14 @@ const inbox = defineContractGroup().namespace("inbox").prefix("/api/inbox");
|
|
|
674
674
|
|
|
675
675
|
export const listInbox = inbox
|
|
676
676
|
\t.get("/")
|
|
677
|
-
\t.query(
|
|
677
|
+
\t.query(
|
|
678
|
+
\t\tlistInboxQuerySchema,
|
|
679
|
+
\t\tdefineQueryTransport({
|
|
680
|
+
\t\t\tlimit: query.integer(),
|
|
681
|
+
\t\t\tcursor: query.string(),
|
|
682
|
+
\t\t\tunread: query.boolean(),
|
|
683
|
+
\t\t}),
|
|
684
|
+
\t)
|
|
678
685
|
\t.meta({ auth: "required" })
|
|
679
686
|
\t.errors({ Unauthorized: errors.Unauthorized })
|
|
680
687
|
\t.responses({
|
package/src/make/payments.ts
CHANGED
|
@@ -862,7 +862,7 @@ export function isBillingAccountActive(
|
|
|
862
862
|
export function billingContractsFile(
|
|
863
863
|
idempotencyScope: "actor" | "actor-tenant" = "actor",
|
|
864
864
|
): string {
|
|
865
|
-
return `import { defineContractGroup } from "@beignet/core/contracts";
|
|
865
|
+
return `import { defineContractGroup, defineQueryTransport } from "@beignet/core/contracts";
|
|
866
866
|
import { z } from "zod";
|
|
867
867
|
import {
|
|
868
868
|
\tbillingStatusOutputSchema,
|
|
@@ -882,7 +882,7 @@ const checkoutBilling = billing.headers(checkoutHeadersSchema);
|
|
|
882
882
|
|
|
883
883
|
export const getBillingStatus = billing
|
|
884
884
|
\t.get("/")
|
|
885
|
-
\t.query(z.object({}))
|
|
885
|
+
\t.query(z.object({}), defineQueryTransport({}))
|
|
886
886
|
\t.meta({ auth: "required" })
|
|
887
887
|
\t.errors({ Unauthorized: errors.Unauthorized })
|
|
888
888
|
\t.responses({
|
package/src/make.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import ts from "typescript";
|
|
5
|
+
import { analyzePortWiringFiles } from "./analysis/port-wiring.js";
|
|
6
|
+
import { listProjectFiles } from "./analysis/workspace.js";
|
|
5
7
|
import type { MakeFeatureAddon, MakeFeatureRecipe } from "./choices.js";
|
|
6
8
|
import {
|
|
7
9
|
type BeignetConfig,
|
|
@@ -1084,6 +1086,10 @@ export async function makeJob(options: MakeJobOptions): Promise<MakeJobResult> {
|
|
|
1084
1086
|
await assertFeatureArtifactApp(targetDir, config, "job");
|
|
1085
1087
|
await assertServerRuntimeApp(targetDir, config, "job");
|
|
1086
1088
|
await updateOutboxPortWiring(targetDir, config, { dryRun: true });
|
|
1089
|
+
const jobDispatcherPlan = await planInlineJobDispatcherWiring(
|
|
1090
|
+
targetDir,
|
|
1091
|
+
config,
|
|
1092
|
+
);
|
|
1087
1093
|
const outboxDrainPlan = await planOutboxDrainWiring(targetDir, config, {
|
|
1088
1094
|
force: Boolean(options.force),
|
|
1089
1095
|
});
|
|
@@ -1114,6 +1120,9 @@ export async function makeJob(options: MakeJobOptions): Promise<MakeJobResult> {
|
|
|
1114
1120
|
await applyOutboxDrainWiring(result, targetDir, outboxDrainPlan, {
|
|
1115
1121
|
dryRun: Boolean(options.dryRun),
|
|
1116
1122
|
});
|
|
1123
|
+
await applyInlineJobDispatcherWiring(result, targetDir, jobDispatcherPlan, {
|
|
1124
|
+
dryRun: Boolean(options.dryRun),
|
|
1125
|
+
});
|
|
1117
1126
|
await applyOutboxPortWiring(result, targetDir, config, {
|
|
1118
1127
|
dryRun: Boolean(options.dryRun),
|
|
1119
1128
|
});
|
|
@@ -1124,6 +1133,201 @@ export async function makeJob(options: MakeJobOptions): Promise<MakeJobResult> {
|
|
|
1124
1133
|
return result;
|
|
1125
1134
|
}
|
|
1126
1135
|
|
|
1136
|
+
type InlineJobDispatcherWiringPlan = {
|
|
1137
|
+
changes: { path: string; before: string; after: string }[];
|
|
1138
|
+
};
|
|
1139
|
+
|
|
1140
|
+
async function planInlineJobDispatcherWiring(
|
|
1141
|
+
targetDir: string,
|
|
1142
|
+
config: ResolvedBeignetConfig,
|
|
1143
|
+
): Promise<InlineJobDispatcherWiringPlan> {
|
|
1144
|
+
const portsFile = config.paths.ports;
|
|
1145
|
+
const portWiringFile = config.paths.portWiring;
|
|
1146
|
+
const providersFile = providersFilePath(config);
|
|
1147
|
+
const ports = await readFile(path.join(targetDir, portsFile), "utf8");
|
|
1148
|
+
const portWiring = await readFile(
|
|
1149
|
+
path.join(targetDir, portWiringFile),
|
|
1150
|
+
"utf8",
|
|
1151
|
+
);
|
|
1152
|
+
const analysis = await analyzePortWiringFiles({
|
|
1153
|
+
targetDir,
|
|
1154
|
+
files: await listProjectFiles(targetDir),
|
|
1155
|
+
config,
|
|
1156
|
+
});
|
|
1157
|
+
const declaresJobs = analysis.declared.has("jobs");
|
|
1158
|
+
const wiresJobs = analysis.bound.has("jobs") || analysis.deferred.has("jobs");
|
|
1159
|
+
|
|
1160
|
+
if (declaresJobs && wiresJobs) {
|
|
1161
|
+
return { changes: [] };
|
|
1162
|
+
}
|
|
1163
|
+
if (!declaresJobs && analysis.declarationIndeterminate) {
|
|
1164
|
+
throw new Error(
|
|
1165
|
+
`Could not prove whether AppPorts in ${portsFile} declares the jobs port. Preserve the app's custom port type and add jobs: JobDispatcherPort manually before running make job.`,
|
|
1166
|
+
);
|
|
1167
|
+
}
|
|
1168
|
+
if (!wiresJobs && analysis.indeterminate) {
|
|
1169
|
+
throw new Error(
|
|
1170
|
+
`Could not prove how the jobs port is wired in ${portWiringFile}. Preserve the app's custom dispatcher by binding or deferring "jobs" in a statically inspectable definePorts(...) object before running make job.`,
|
|
1171
|
+
);
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
let nextPorts = ports;
|
|
1175
|
+
if (!declaresJobs && !analysis.appPortsInferredFromWiring) {
|
|
1176
|
+
nextPorts = addNamedTypeImport(
|
|
1177
|
+
nextPorts,
|
|
1178
|
+
"JobDispatcherPort",
|
|
1179
|
+
"@beignet/core/ports",
|
|
1180
|
+
);
|
|
1181
|
+
nextPorts = insertTypeProperty(
|
|
1182
|
+
nextPorts,
|
|
1183
|
+
"AppPorts",
|
|
1184
|
+
"jobs: JobDispatcherPort;",
|
|
1185
|
+
`Could not find AppPorts in ${portsFile}. Add jobs: JobDispatcherPort manually and wire a dispatcher, or restore the generated ports file before running make job.`,
|
|
1186
|
+
);
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
if (wiresJobs) {
|
|
1190
|
+
return {
|
|
1191
|
+
changes:
|
|
1192
|
+
ports === nextPorts
|
|
1193
|
+
? []
|
|
1194
|
+
: [{ path: portsFile, before: ports, after: nextPorts }],
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
const nextPortWiring = appendDeferredPortKey(portWiring, "jobs");
|
|
1199
|
+
if (nextPortWiring === portWiring) {
|
|
1200
|
+
throw new Error(
|
|
1201
|
+
`Could not find the deferred port list in ${portWiringFile}. Add "jobs" manually and wire a dispatcher, or restore the generated port wiring file before running make job.`,
|
|
1202
|
+
);
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
const providersPath = path.join(targetDir, providersFile);
|
|
1206
|
+
const providers = await readOptionalFile(providersPath);
|
|
1207
|
+
if (providers === undefined) {
|
|
1208
|
+
throw new Error(
|
|
1209
|
+
`Could not find ${providersFile}. Register an inline or provider-backed jobs dispatcher manually, or restore the generated providers file before running make job.`,
|
|
1210
|
+
);
|
|
1211
|
+
}
|
|
1212
|
+
let nextProviders = addNamedImport(
|
|
1213
|
+
providers,
|
|
1214
|
+
"createInlineJobDispatcher",
|
|
1215
|
+
"@beignet/core/jobs",
|
|
1216
|
+
);
|
|
1217
|
+
nextProviders = addNamedImport(
|
|
1218
|
+
nextProviders,
|
|
1219
|
+
"createProvider",
|
|
1220
|
+
"@beignet/core/providers",
|
|
1221
|
+
);
|
|
1222
|
+
nextProviders = addNamedTypeImport(
|
|
1223
|
+
nextProviders,
|
|
1224
|
+
"AppContext",
|
|
1225
|
+
aliasModule(config.paths.appContext),
|
|
1226
|
+
);
|
|
1227
|
+
nextProviders = addNamedTypeImport(
|
|
1228
|
+
nextProviders,
|
|
1229
|
+
"AppPorts",
|
|
1230
|
+
aliasModule(config.paths.ports),
|
|
1231
|
+
);
|
|
1232
|
+
nextProviders = addNamedTypeImport(
|
|
1233
|
+
nextProviders,
|
|
1234
|
+
"AppServiceContextInput",
|
|
1235
|
+
aliasModule(path.join(path.dirname(config.paths.server), "context.ts")),
|
|
1236
|
+
);
|
|
1237
|
+
|
|
1238
|
+
const providerName = "inlineJobsProvider";
|
|
1239
|
+
const generatedProviderMarker = "// beignet:generated-inline-jobs-provider";
|
|
1240
|
+
const providersSourceFile = ts.createSourceFile(
|
|
1241
|
+
providersFile,
|
|
1242
|
+
nextProviders,
|
|
1243
|
+
ts.ScriptTarget.Latest,
|
|
1244
|
+
true,
|
|
1245
|
+
ts.ScriptKind.TS,
|
|
1246
|
+
);
|
|
1247
|
+
const providerDeclaration = providersSourceFile.statements
|
|
1248
|
+
.filter(ts.isVariableStatement)
|
|
1249
|
+
.flatMap((statement) => [...statement.declarationList.declarations])
|
|
1250
|
+
.find(
|
|
1251
|
+
(declaration) =>
|
|
1252
|
+
ts.isIdentifier(declaration.name) &&
|
|
1253
|
+
declaration.name.text === providerName,
|
|
1254
|
+
);
|
|
1255
|
+
const providerDeclarationExists = providerDeclaration !== undefined;
|
|
1256
|
+
const providerIsGenerated = providerDeclaration
|
|
1257
|
+
? nextProviders
|
|
1258
|
+
.slice(0, providerDeclaration.getStart(providersSourceFile))
|
|
1259
|
+
.trimEnd()
|
|
1260
|
+
.endsWith(generatedProviderMarker)
|
|
1261
|
+
: false;
|
|
1262
|
+
if (providerDeclarationExists && !providerIsGenerated) {
|
|
1263
|
+
throw new Error(
|
|
1264
|
+
`Could not install the generated inline jobs dispatcher because ${providerName} already exists in ${providersFile}. Rename the app-owned declaration or wire its jobs port explicitly before running make job.`,
|
|
1265
|
+
);
|
|
1266
|
+
}
|
|
1267
|
+
if (!providerDeclarationExists) {
|
|
1268
|
+
const definition = `// beignet:generated-inline-jobs-provider
|
|
1269
|
+
const ${providerName} = createProvider<
|
|
1270
|
+
{},
|
|
1271
|
+
AppContext,
|
|
1272
|
+
AppServiceContextInput
|
|
1273
|
+
>()({
|
|
1274
|
+
name: "inline-jobs",
|
|
1275
|
+
setup({ createServiceContext }): { ports: Pick<AppPorts, "jobs"> } {
|
|
1276
|
+
return {
|
|
1277
|
+
ports: {
|
|
1278
|
+
jobs: createInlineJobDispatcher<AppContext>({
|
|
1279
|
+
ctx: () => createServiceContext(undefined),
|
|
1280
|
+
}),
|
|
1281
|
+
},
|
|
1282
|
+
};
|
|
1283
|
+
},
|
|
1284
|
+
});
|
|
1285
|
+
`;
|
|
1286
|
+
const inserted = nextProviders.replace(
|
|
1287
|
+
/\nexport const providers = \[/,
|
|
1288
|
+
`\n${definition}\nexport const providers = [`,
|
|
1289
|
+
);
|
|
1290
|
+
if (inserted === nextProviders) {
|
|
1291
|
+
throw new Error(
|
|
1292
|
+
`Could not find the exported providers array in ${providersFile}. Register an inline or provider-backed jobs dispatcher manually, or restore the generated providers file before running make job.`,
|
|
1293
|
+
);
|
|
1294
|
+
}
|
|
1295
|
+
nextProviders = inserted;
|
|
1296
|
+
}
|
|
1297
|
+
const appended = appendToNamedArray(nextProviders, "providers", providerName);
|
|
1298
|
+
if (appended.kind === "missing") {
|
|
1299
|
+
throw new Error(
|
|
1300
|
+
`Could not find the exported providers array in ${providersFile}. Register ${providerName} manually, or restore the generated providers file before running make job.`,
|
|
1301
|
+
);
|
|
1302
|
+
}
|
|
1303
|
+
if (appended.kind === "updated") nextProviders = appended.source;
|
|
1304
|
+
|
|
1305
|
+
return {
|
|
1306
|
+
changes: [
|
|
1307
|
+
{ path: portsFile, before: ports, after: nextPorts },
|
|
1308
|
+
{ path: portWiringFile, before: portWiring, after: nextPortWiring },
|
|
1309
|
+
{ path: providersFile, before: providers, after: nextProviders },
|
|
1310
|
+
].filter((change) => change.before !== change.after),
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
async function applyInlineJobDispatcherWiring(
|
|
1315
|
+
result: MakeResult,
|
|
1316
|
+
targetDir: string,
|
|
1317
|
+
plan: InlineJobDispatcherWiringPlan,
|
|
1318
|
+
options: { dryRun: boolean },
|
|
1319
|
+
): Promise<void> {
|
|
1320
|
+
for (const change of plan.changes) {
|
|
1321
|
+
if (!options.dryRun) {
|
|
1322
|
+
await writeFile(path.join(targetDir, change.path), change.after);
|
|
1323
|
+
}
|
|
1324
|
+
if (!result.updatedFiles.includes(change.path)) {
|
|
1325
|
+
result.updatedFiles.push(change.path);
|
|
1326
|
+
}
|
|
1327
|
+
if (!result.files.includes(change.path)) result.files.push(change.path);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1127
1331
|
export async function makeTask(
|
|
1128
1332
|
options: MakeTaskOptions,
|
|
1129
1333
|
): Promise<MakeTaskResult> {
|
|
@@ -3983,8 +4187,8 @@ export function decode${names.singularPascal}Cursor(cursor: string): ${names.sin
|
|
|
3983
4187
|
|
|
3984
4188
|
export const List${names.pluralPascal}InputSchema = z
|
|
3985
4189
|
.object({
|
|
3986
|
-
limit: z.
|
|
3987
|
-
cursor: z.string().
|
|
4190
|
+
limit: z.number().int().min(1).max(100).default(20),
|
|
4191
|
+
cursor: z.string().optional().transform((value) => value ?? null),
|
|
3988
4192
|
name: z.string().trim().min(1).max(120).optional(),
|
|
3989
4193
|
sortBy: ${names.singularPascal}SortBySchema.default("createdAt"),
|
|
3990
4194
|
sortDirection: ${names.singularPascal}SortDirectionSchema.default("desc"),
|
|
@@ -4840,7 +5044,7 @@ function contractFile(
|
|
|
4840
5044
|
mode: ResourceGenerationMode,
|
|
4841
5045
|
options: ResourceGenerationOptions,
|
|
4842
5046
|
): string {
|
|
4843
|
-
return `import { defineContractGroup } from "@beignet/core/contracts";
|
|
5047
|
+
return `import { defineContractGroup, defineQueryTransport, query } from "@beignet/core/contracts";
|
|
4844
5048
|
import { z } from "zod";
|
|
4845
5049
|
${mode === "resource" ? `import { errors } from "${aliasModule(resourceSharedErrorsPath(config))}";\n` : ""}import {
|
|
4846
5050
|
Create${names.singularPascal}InputSchema,
|
|
@@ -4863,7 +5067,16 @@ const ${names.pluralCamel} = defineContractGroup()
|
|
|
4863
5067
|
|
|
4864
5068
|
export const list${names.pluralPascal} = ${names.pluralCamel}
|
|
4865
5069
|
.get("/api/${names.pluralKebab}")
|
|
4866
|
-
.query(
|
|
5070
|
+
.query(
|
|
5071
|
+
List${names.pluralPascal}InputSchema,
|
|
5072
|
+
defineQueryTransport({
|
|
5073
|
+
limit: query.integer(),
|
|
5074
|
+
cursor: query.string(),
|
|
5075
|
+
name: query.string(),
|
|
5076
|
+
sortBy: query.string(),
|
|
5077
|
+
sortDirection: query.string(),
|
|
5078
|
+
}),
|
|
5079
|
+
)
|
|
4867
5080
|
.responses({
|
|
4868
5081
|
200: List${names.pluralPascal}OutputSchema,
|
|
4869
5082
|
});
|
|
@@ -4908,7 +5121,7 @@ ${options.authorization ? `\t.meta({\n\t\tauth: "required",\n\t\tauthorization:
|
|
|
4908
5121
|
}
|
|
4909
5122
|
|
|
4910
5123
|
function standaloneContractFile(names: ResourceNames): string {
|
|
4911
|
-
return `import { defineContractGroup } from "@beignet/core/contracts";
|
|
5124
|
+
return `import { defineContractGroup, defineQueryTransport, query } from "@beignet/core/contracts";
|
|
4912
5125
|
import { z } from "zod";
|
|
4913
5126
|
|
|
4914
5127
|
const ErrorResponseSchema = z.object({
|
|
@@ -4932,8 +5145,12 @@ export const list${names.pluralPascal} = ${names.pluralCamel}
|
|
|
4932
5145
|
.get("/api/${names.pluralKebab}")
|
|
4933
5146
|
.query(
|
|
4934
5147
|
z.object({
|
|
4935
|
-
limit: z.
|
|
4936
|
-
offset: z.
|
|
5148
|
+
limit: z.number().int().min(1).max(100).default(20),
|
|
5149
|
+
offset: z.number().int().min(0).default(0),
|
|
5150
|
+
}),
|
|
5151
|
+
defineQueryTransport({
|
|
5152
|
+
limit: query.integer(),
|
|
5153
|
+
offset: query.integer(),
|
|
4937
5154
|
}),
|
|
4938
5155
|
)
|
|
4939
5156
|
.responses({
|
|
@@ -6038,7 +6255,7 @@ ${options.authorization ? `\t\t\t\tgate: initialPorts.gate,\n` : ""}
|
|
|
6038
6255
|
);
|
|
6039
6256
|
const secondPage = await tester.run(
|
|
6040
6257
|
list${names.pluralPascal}UseCase,
|
|
6041
|
-
{ limit: 2, cursor: firstPage.page.nextCursor },
|
|
6258
|
+
{ limit: 2, cursor: firstPage.page.nextCursor! },
|
|
6042
6259
|
{ ctx },
|
|
6043
6260
|
);
|
|
6044
6261
|
const nameAscendingPage = await tester.run(
|
package/src/mcp.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { open, realpath } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
8
|
-
import { z } from "zod";
|
|
3
|
+
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/server";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
|
|
5
|
+
import { z } from "zod/v4";
|
|
9
6
|
import { mapApp, projectAppMap } from "./app-map.js";
|
|
10
7
|
import { appMapNodeKinds } from "./app-map-schema.js";
|
|
11
8
|
import { checkApp } from "./check.js";
|
|
@@ -680,7 +677,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
680
677
|
openWorldHint: true,
|
|
681
678
|
},
|
|
682
679
|
},
|
|
683
|
-
async (input,
|
|
680
|
+
async (input, ctx) =>
|
|
684
681
|
safeToolResult(async () =>
|
|
685
682
|
jsonResult(
|
|
686
683
|
await checkApp({
|
|
@@ -689,7 +686,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
689
686
|
preflightConnect: input.preflightConnect ?? false,
|
|
690
687
|
connectTimeoutMs: input.connectTimeoutMs,
|
|
691
688
|
scriptTimeoutMs: input.timeoutMs ?? defaultMcpCheckTimeoutMs,
|
|
692
|
-
signal:
|
|
689
|
+
signal: ctx.mcpReq.signal,
|
|
693
690
|
}),
|
|
694
691
|
),
|
|
695
692
|
),
|
|
@@ -727,7 +724,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
727
724
|
openWorldHint: true,
|
|
728
725
|
},
|
|
729
726
|
},
|
|
730
|
-
async (input,
|
|
727
|
+
async (input, ctx) =>
|
|
731
728
|
safeToolResult(async () =>
|
|
732
729
|
jsonResult(
|
|
733
730
|
await runDatabaseCommand({
|
|
@@ -735,7 +732,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
735
732
|
cwd,
|
|
736
733
|
captureOutput: true,
|
|
737
734
|
maxOutputBytes: defaultDatabaseCommandMaxOutputBytes,
|
|
738
|
-
signal:
|
|
735
|
+
signal: ctx.mcpReq.signal,
|
|
739
736
|
timeoutMs: input.timeoutMs ?? defaultDatabaseCommandTimeoutMs,
|
|
740
737
|
dryRun: input.dryRun,
|
|
741
738
|
}),
|
|
@@ -766,14 +763,14 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
766
763
|
openWorldHint: true,
|
|
767
764
|
},
|
|
768
765
|
},
|
|
769
|
-
async (input,
|
|
766
|
+
async (input, ctx) =>
|
|
770
767
|
safeToolResult(async () =>
|
|
771
768
|
jsonResult(
|
|
772
769
|
await runDatabaseStatus({
|
|
773
770
|
cwd,
|
|
774
771
|
captureOutput: true,
|
|
775
772
|
maxOutputBytes: defaultDatabaseCommandMaxOutputBytes,
|
|
776
|
-
signal:
|
|
773
|
+
signal: ctx.mcpReq.signal,
|
|
777
774
|
timeoutMs: input.timeoutMs ?? defaultDatabaseCommandTimeoutMs,
|
|
778
775
|
}),
|
|
779
776
|
),
|
|
@@ -818,7 +815,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
818
815
|
openWorldHint: false,
|
|
819
816
|
},
|
|
820
817
|
},
|
|
821
|
-
async (input,
|
|
818
|
+
async (input, ctx) =>
|
|
822
819
|
safeToolResult(async () =>
|
|
823
820
|
jsonResult(
|
|
824
821
|
await syncDatabaseSchema({
|
|
@@ -827,7 +824,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
827
824
|
tables: input.tables,
|
|
828
825
|
output: input.output,
|
|
829
826
|
dryRun: input.dryRun,
|
|
830
|
-
signal:
|
|
827
|
+
signal: ctx.mcpReq.signal,
|
|
831
828
|
}),
|
|
832
829
|
),
|
|
833
830
|
),
|
|
@@ -846,7 +843,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
846
843
|
openWorldHint: true,
|
|
847
844
|
},
|
|
848
845
|
},
|
|
849
|
-
async (input,
|
|
846
|
+
async (input, ctx) =>
|
|
850
847
|
safeToolResult(async () =>
|
|
851
848
|
operationalJsonResult(
|
|
852
849
|
await runIsolatedOperationalCommand({
|
|
@@ -858,7 +855,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
858
855
|
tenant: input.tenant,
|
|
859
856
|
modulePath: input.module,
|
|
860
857
|
},
|
|
861
|
-
signal:
|
|
858
|
+
signal: ctx.mcpReq.signal,
|
|
862
859
|
timeoutMs: input.timeoutMs ?? defaultOperationalCommandTimeoutMs,
|
|
863
860
|
}),
|
|
864
861
|
),
|
|
@@ -878,7 +875,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
878
875
|
openWorldHint: true,
|
|
879
876
|
},
|
|
880
877
|
},
|
|
881
|
-
async (input,
|
|
878
|
+
async (input, ctx) =>
|
|
882
879
|
safeToolResult(async () =>
|
|
883
880
|
operationalJsonResult(
|
|
884
881
|
await runIsolatedOperationalCommand({
|
|
@@ -894,7 +891,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
894
891
|
source: input.source,
|
|
895
892
|
modulePath: input.module,
|
|
896
893
|
},
|
|
897
|
-
signal:
|
|
894
|
+
signal: ctx.mcpReq.signal,
|
|
898
895
|
timeoutMs: input.timeoutMs ?? defaultOperationalCommandTimeoutMs,
|
|
899
896
|
}),
|
|
900
897
|
),
|
|
@@ -914,7 +911,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
914
911
|
openWorldHint: true,
|
|
915
912
|
},
|
|
916
913
|
},
|
|
917
|
-
async (input,
|
|
914
|
+
async (input, ctx) =>
|
|
918
915
|
safeToolResult(async () =>
|
|
919
916
|
operationalJsonResult(
|
|
920
917
|
await runIsolatedOperationalCommand({
|
|
@@ -934,7 +931,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
934
931
|
id: input.id,
|
|
935
932
|
modulePath: input.module,
|
|
936
933
|
},
|
|
937
|
-
signal:
|
|
934
|
+
signal: ctx.mcpReq.signal,
|
|
938
935
|
timeoutMs: input.timeoutMs ?? defaultOperationalCommandTimeoutMs,
|
|
939
936
|
}),
|
|
940
937
|
),
|
|
@@ -954,7 +951,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
954
951
|
openWorldHint: true,
|
|
955
952
|
},
|
|
956
953
|
},
|
|
957
|
-
async (input,
|
|
954
|
+
async (input, ctx) =>
|
|
958
955
|
safeToolResult(async () => {
|
|
959
956
|
const request =
|
|
960
957
|
input.operation === "drain"
|
|
@@ -991,7 +988,7 @@ export function buildBeignetMcpServer(options: McpServerOptions): McpServer {
|
|
|
991
988
|
await runIsolatedOperationalCommand({
|
|
992
989
|
cwd,
|
|
993
990
|
request,
|
|
994
|
-
signal:
|
|
991
|
+
signal: ctx.mcpReq.signal,
|
|
995
992
|
timeoutMs: input.timeoutMs ?? defaultOperationalCommandTimeoutMs,
|
|
996
993
|
}),
|
|
997
994
|
);
|