swallowkit 1.0.0-beta.57 → 1.0.0-beta.59
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/README.ja.md +1 -0
- package/README.md +1 -0
- package/dist/cli/commands/add-auth.d.ts +3 -1
- package/dist/cli/commands/add-auth.d.ts.map +1 -1
- package/dist/cli/commands/add-auth.js +55 -21
- package/dist/cli/commands/add-auth.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +12 -498
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/operations/auth-operations.d.ts +4 -0
- package/dist/core/operations/auth-operations.d.ts.map +1 -1
- package/dist/core/operations/auth-operations.js +5 -2
- package/dist/core/operations/auth-operations.js.map +1 -1
- package/dist/core/operations/create-model.d.ts.map +1 -1
- package/dist/core/operations/create-model.js +6 -2
- package/dist/core/operations/create-model.js.map +1 -1
- package/dist/core/project/agent-instructions.d.ts +29 -0
- package/dist/core/project/agent-instructions.d.ts.map +1 -0
- package/dist/core/project/agent-instructions.js +159 -0
- package/dist/core/project/agent-instructions.js.map +1 -0
- package/dist/core/project/capabilities.d.ts +58 -0
- package/dist/core/project/capabilities.d.ts.map +1 -0
- package/dist/core/project/capabilities.js +135 -0
- package/dist/core/project/capabilities.js.map +1 -0
- package/dist/core/project/validation.d.ts.map +1 -1
- package/dist/core/project/validation.js +48 -0
- package/dist/core/project/validation.js.map +1 -1
- package/dist/core/project/workflows.d.ts.map +1 -1
- package/dist/core/project/workflows.js +46 -2
- package/dist/core/project/workflows.js.map +1 -1
- package/dist/core/scaffold/auth-generator.d.ts.map +1 -1
- package/dist/core/scaffold/auth-generator.js +6 -2
- package/dist/core/scaffold/auth-generator.js.map +1 -1
- package/dist/core/verify/index.d.ts +7 -0
- package/dist/core/verify/index.d.ts.map +1 -1
- package/dist/core/verify/index.js +69 -0
- package/dist/core/verify/index.js.map +1 -1
- package/dist/machine/index.d.ts.map +1 -1
- package/dist/machine/index.js +117 -41
- package/dist/machine/index.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +32 -10
- package/dist/mcp/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/agent-instructions.test.ts +237 -0
- package/src/__tests__/agent-loop-phase34.test.ts +66 -2
- package/src/__tests__/auth.test.ts +9 -0
- package/src/__tests__/init.test.ts +2 -0
- package/src/__tests__/machine.test.ts +15 -0
- package/src/__tests__/multi-auth.test.ts +12 -0
- package/src/__tests__/plan-apply.test.ts +38 -0
- package/src/cli/commands/add-auth.ts +59 -21
- package/src/cli/commands/init.ts +19 -525
- package/src/cli/index.ts +2 -0
- package/src/core/operations/auth-operations.ts +9 -2
- package/src/core/operations/create-model.ts +7 -2
- package/src/core/project/agent-instructions.ts +167 -0
- package/src/core/project/agent-templates/AGENTS.md +502 -0
- package/src/core/project/agent-templates/CLAUDE.md +31 -0
- package/src/core/project/agent-templates/azure-functions.instructions.md +22 -0
- package/src/core/project/agent-templates/bff-routes.instructions.md +18 -0
- package/src/core/project/agent-templates/copilot-instructions.md +27 -0
- package/src/core/project/agent-templates/shared-models.instructions.md +72 -0
- package/src/core/project/capabilities.ts +193 -0
- package/src/core/project/validation.ts +50 -0
- package/src/core/project/workflows.ts +48 -2
- package/src/core/scaffold/auth-generator.ts +7 -2
- package/src/core/verify/index.ts +76 -0
- package/src/machine/index.ts +133 -45
- package/src/mcp/index.ts +28 -10
package/src/machine/index.ts
CHANGED
|
@@ -10,11 +10,12 @@ import { runMachineScaffoldOperation } from "../core/operations/scaffold-machine
|
|
|
10
10
|
import { planScaffoldOperation } from "../core/operations/scaffold-plan";
|
|
11
11
|
import { inspectArtifacts } from "../core/project/artifacts";
|
|
12
12
|
import { inspectBoundaries } from "../core/project/boundaries";
|
|
13
|
+
import { inspectCapabilities } from "../core/project/capabilities";
|
|
13
14
|
import { detectDrift } from "../core/project/drift";
|
|
14
15
|
import { loadProjectManifest } from "../core/project/manifest";
|
|
15
16
|
import { loadLastVerifyState } from "../core/project/state";
|
|
16
17
|
import { validateProject } from "../core/project/validation";
|
|
17
|
-
import { explainVerifyFailure, runVerify, VerifyResult } from "../core/verify";
|
|
18
|
+
import { explainVerifyFailure, compactVerifyResult, runVerify, VerifyResult } from "../core/verify";
|
|
18
19
|
import {
|
|
19
20
|
MachineErrorResponse,
|
|
20
21
|
MachineNextAction,
|
|
@@ -24,8 +25,16 @@ import {
|
|
|
24
25
|
} from "./contracts";
|
|
25
26
|
import { MachineCommandError, resolveMachineErrorStatus, toMachineError } from "./errors";
|
|
26
27
|
|
|
28
|
+
/** 最終 JSON envelope 専用の stdout writer。runMachineCli 実行中はこれ以外の stdout 書き込みを stderr へ逃がす。 */
|
|
29
|
+
let machineEnvelopeWrite: ((chunk: string) => void) | null = null;
|
|
30
|
+
|
|
27
31
|
function writeMachineResponse<TData>(response: MachineResponse<TData>): void {
|
|
28
|
-
|
|
32
|
+
const payload = `${JSON.stringify(response, null, 2)}\n`;
|
|
33
|
+
if (machineEnvelopeWrite) {
|
|
34
|
+
machineEnvelopeWrite(payload);
|
|
35
|
+
} else {
|
|
36
|
+
process.stdout.write(payload);
|
|
37
|
+
}
|
|
29
38
|
}
|
|
30
39
|
|
|
31
40
|
interface MachineResponseMeta {
|
|
@@ -187,6 +196,13 @@ function createMachineProgram(): Command {
|
|
|
187
196
|
await handleMachineAction("inspect-boundaries", async () => inspectBoundaries());
|
|
188
197
|
});
|
|
189
198
|
|
|
199
|
+
inspect
|
|
200
|
+
.command("capabilities")
|
|
201
|
+
.description("Return SwallowKit's machine-readable capability contract: model declarations, auth workflow, generated-CRUD scope, seeding, and available commands")
|
|
202
|
+
.action(async () => {
|
|
203
|
+
await handleMachineAction("inspect-capabilities", async () => inspectCapabilities());
|
|
204
|
+
});
|
|
205
|
+
|
|
190
206
|
inspect
|
|
191
207
|
.command("infra")
|
|
192
208
|
.description("Inspect Bicep infrastructure assets (params, modules, outputs, container wiring) without calling Azure")
|
|
@@ -273,34 +289,41 @@ function createMachineProgram(): Command {
|
|
|
273
289
|
const plan = new Command("plan");
|
|
274
290
|
plan
|
|
275
291
|
.command("scaffold")
|
|
276
|
-
.description("Compute the scaffold change plan without writing any files")
|
|
277
|
-
.argument("<
|
|
292
|
+
.description("Compute the scaffold change plan without writing any files (accepts multiple models)")
|
|
293
|
+
.argument("<models...>", "Model files or model names")
|
|
278
294
|
.option("--functions-dir <dir>", "Functions directory", "functions")
|
|
279
295
|
.option("--api-dir <dir>", "API routes directory", "app/api")
|
|
280
296
|
.option("--api-only", "Skip UI components in the plan", false)
|
|
281
|
-
.action(async (
|
|
297
|
+
.action(async (models: string[], options: { functionsDir?: string; apiDir?: string; apiOnly?: boolean }) => {
|
|
282
298
|
await handleMachineAction(
|
|
283
299
|
"plan-scaffold",
|
|
284
300
|
async () => {
|
|
285
301
|
ensureProjectForMachine();
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
302
|
+
const plans = [];
|
|
303
|
+
for (const model of models) {
|
|
304
|
+
plans.push(
|
|
305
|
+
await planScaffoldOperation({
|
|
306
|
+
model,
|
|
307
|
+
functionsDir: options.functionsDir,
|
|
308
|
+
apiDir: options.apiDir,
|
|
309
|
+
apiOnly: options.apiOnly,
|
|
310
|
+
})
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
return plans.length === 1 ? plans[0] : { planType: "scaffold-batch" as const, plans };
|
|
292
314
|
},
|
|
293
|
-
(
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
315
|
+
(data) => {
|
|
316
|
+
const plans = "plans" in data ? data.plans : [data];
|
|
317
|
+
return {
|
|
318
|
+
status: plans.some((planData) => planData.requiresApproval) ? "requires-human" : "complete",
|
|
319
|
+
nextActions: plans.map((planData) => ({
|
|
297
320
|
command: `swallowkit machine apply scaffold --plan ${planData.planId}${planData.requiresApproval ? " --approve" : ""}`,
|
|
298
321
|
description: planData.requiresApproval
|
|
299
|
-
?
|
|
300
|
-
:
|
|
301
|
-
},
|
|
302
|
-
|
|
303
|
-
}
|
|
322
|
+
? `Apply the plan for ${planData.model} after reviewing the listed conflicts (requires --approve).`
|
|
323
|
+
: `Apply the plan for ${planData.model}.`,
|
|
324
|
+
})),
|
|
325
|
+
};
|
|
326
|
+
}
|
|
304
327
|
);
|
|
305
328
|
});
|
|
306
329
|
|
|
@@ -309,12 +332,17 @@ function createMachineProgram(): Command {
|
|
|
309
332
|
.description("Compute the add-auth change plan without writing any files")
|
|
310
333
|
.requiredOption("--provider <provider>", "Auth provider: custom-jwt | swa | external-token | none")
|
|
311
334
|
.option("--scheme <name>", "Add as a named authentication scheme")
|
|
312
|
-
.
|
|
335
|
+
.option("--allowed-providers <list>", "Comma-separated SWA identity providers to allow (e.g. github,aad); defaults to aad")
|
|
336
|
+
.action(async (options: { provider: string; scheme?: string; allowedProviders?: string }) => {
|
|
313
337
|
await handleMachineAction(
|
|
314
338
|
"plan-auth",
|
|
315
339
|
async () => {
|
|
316
340
|
ensureProjectForMachine();
|
|
317
|
-
return planAuthOperation({
|
|
341
|
+
return planAuthOperation({
|
|
342
|
+
provider: options.provider,
|
|
343
|
+
scheme: options.scheme,
|
|
344
|
+
allowedProviders: options.allowedProviders ? options.allowedProviders.split(",") : undefined,
|
|
345
|
+
});
|
|
318
346
|
},
|
|
319
347
|
(planData) => ({
|
|
320
348
|
status: planData.requiresApproval ? "requires-human" : "complete",
|
|
@@ -367,8 +395,8 @@ function createMachineProgram(): Command {
|
|
|
367
395
|
const apply = new Command("apply");
|
|
368
396
|
apply
|
|
369
397
|
.command("scaffold")
|
|
370
|
-
.description("Apply scaffold changes, verifying plan freshness and overwrite approval")
|
|
371
|
-
.argument("[
|
|
398
|
+
.description("Apply scaffold changes, verifying plan freshness and overwrite approval (accepts multiple models)")
|
|
399
|
+
.argument("[models...]", "Model files or model names (optional when --plan is given)")
|
|
372
400
|
.option("--plan <planId>", "Apply a previously computed plan")
|
|
373
401
|
.option("--approve", "Approve overwriting files that were modified after generation", false)
|
|
374
402
|
.option("--functions-dir <dir>", "Functions directory")
|
|
@@ -376,21 +404,44 @@ function createMachineProgram(): Command {
|
|
|
376
404
|
.option("--api-only", "Skip UI components; still update Functions, BFF routes, OpenAPI, and native schema assets")
|
|
377
405
|
.action(
|
|
378
406
|
async (
|
|
379
|
-
|
|
407
|
+
models: string[],
|
|
380
408
|
options: { plan?: string; approve?: boolean; functionsDir?: string; apiDir?: string; apiOnly?: boolean }
|
|
381
409
|
) => {
|
|
382
410
|
await handleMachineAction(
|
|
383
411
|
"apply-scaffold",
|
|
384
412
|
async () => {
|
|
385
413
|
ensureProjectForMachine();
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
}
|
|
414
|
+
if (models.length > 1 && options.plan) {
|
|
415
|
+
throw new MachineCommandError(
|
|
416
|
+
"invalid-arguments",
|
|
417
|
+
"--plan applies to a single model. Pass multiple models without --plan (each apply re-plans internally), or apply each plan separately.",
|
|
418
|
+
undefined,
|
|
419
|
+
"failed"
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
if (models.length <= 1) {
|
|
423
|
+
return applyScaffoldOperation({
|
|
424
|
+
model: models[0],
|
|
425
|
+
planId: options.plan,
|
|
426
|
+
approve: options.approve,
|
|
427
|
+
functionsDir: options.functionsDir,
|
|
428
|
+
apiDir: options.apiDir,
|
|
429
|
+
apiOnly: options.apiOnly,
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
const results = [];
|
|
433
|
+
for (const model of models) {
|
|
434
|
+
results.push(
|
|
435
|
+
await applyScaffoldOperation({
|
|
436
|
+
model,
|
|
437
|
+
approve: options.approve,
|
|
438
|
+
functionsDir: options.functionsDir,
|
|
439
|
+
apiDir: options.apiDir,
|
|
440
|
+
apiOnly: options.apiOnly,
|
|
441
|
+
})
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
return { applyType: "scaffold-batch" as const, results };
|
|
394
445
|
},
|
|
395
446
|
() => ({
|
|
396
447
|
status: "complete",
|
|
@@ -411,8 +462,9 @@ function createMachineProgram(): Command {
|
|
|
411
462
|
.option("--plan <planId>", "Apply a previously computed plan")
|
|
412
463
|
.option("--provider <provider>", "Auth provider (optional when --plan is given)")
|
|
413
464
|
.option("--scheme <name>", "Add as a named authentication scheme")
|
|
465
|
+
.option("--allowed-providers <list>", "Comma-separated SWA identity providers to allow (e.g. github,aad); defaults to aad")
|
|
414
466
|
.option("--approve", "Approve overwriting files that were modified after generation", false)
|
|
415
|
-
.action(async (options: { plan?: string; provider?: string; scheme?: string; approve?: boolean }) => {
|
|
467
|
+
.action(async (options: { plan?: string; provider?: string; scheme?: string; allowedProviders?: string; approve?: boolean }) => {
|
|
416
468
|
await handleMachineAction(
|
|
417
469
|
"apply-auth",
|
|
418
470
|
async () => {
|
|
@@ -420,19 +472,41 @@ function createMachineProgram(): Command {
|
|
|
420
472
|
return applyAuthOperation({
|
|
421
473
|
provider: options.provider,
|
|
422
474
|
scheme: options.scheme,
|
|
475
|
+
allowedProviders: options.allowedProviders ? options.allowedProviders.split(",") : undefined,
|
|
423
476
|
planId: options.plan,
|
|
424
477
|
approve: options.approve,
|
|
425
478
|
});
|
|
426
479
|
},
|
|
427
|
-
() =>
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
480
|
+
(result) => {
|
|
481
|
+
const configTarget = result.scheme
|
|
482
|
+
? `auth.authorization.policies (reference scheme "${result.scheme}")`
|
|
483
|
+
: "auth.authorization.policies";
|
|
484
|
+
const nextActions: MachineNextAction[] = [];
|
|
485
|
+
if (result.provider !== "none") {
|
|
486
|
+
nextActions.push({
|
|
487
|
+
command: "edit swallowkit.config.js",
|
|
488
|
+
description: `Define ${configTarget}. The config is an extension point: hand-editing policies is the expected workflow. Do NOT hand-write auth.schemes entries; only plan/apply auth may add schemes.`,
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
if (result.provider === "swa") {
|
|
492
|
+
nextActions.push({
|
|
493
|
+
command: "edit swallowkit.config.js",
|
|
494
|
+
description: `Confirm swa.allowedProviders${result.scheme ? ` for scheme "${result.scheme}"` : ""} lists the identity providers you use (e.g. ['github']). Generated login URLs and provider checks use this list; it can also be set at plan time with --allowed-providers.`,
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
if (result.provider === "external-token") {
|
|
498
|
+
nextActions.push({
|
|
499
|
+
command: "edit the generated external token verifier",
|
|
500
|
+
description:
|
|
501
|
+
"Implement the verifier stub (it fails closed until implemented). typecheck and verify pass with the stub in place, so a passing verify does NOT mean external-token auth works.",
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
nextActions.push({
|
|
505
|
+
command: "swallowkit machine verify project",
|
|
506
|
+
description: "Verify the project after applying auth changes.",
|
|
507
|
+
});
|
|
508
|
+
return { status: "complete", nextActions };
|
|
509
|
+
}
|
|
436
510
|
);
|
|
437
511
|
});
|
|
438
512
|
|
|
@@ -468,10 +542,14 @@ function createMachineProgram(): Command {
|
|
|
468
542
|
"--checks <ids>",
|
|
469
543
|
"Comma-separated check ids to run (structure,drift,typecheck,build,lint,test, plus custom ids from swallowkit.config verify.checks)"
|
|
470
544
|
)
|
|
471
|
-
.
|
|
545
|
+
.option("--compact", "Suppress info-severity findings/violations from evidence to keep agent-facing output small", false)
|
|
546
|
+
.action(async (options: { checks?: string; compact?: boolean }) => {
|
|
472
547
|
await handleMachineAction(
|
|
473
548
|
"verify-project",
|
|
474
|
-
async () =>
|
|
549
|
+
async () => {
|
|
550
|
+
const result = await runVerify(options.checks ? options.checks.split(",") : undefined);
|
|
551
|
+
return options.compact ? compactVerifyResult(result) : result;
|
|
552
|
+
},
|
|
475
553
|
(result) => ({
|
|
476
554
|
status: result.summary.done ? "complete" : "in-progress",
|
|
477
555
|
nextActions: result.summary.done
|
|
@@ -560,9 +638,17 @@ export async function runMachineCli(argv: string[] = process.argv): Promise<void
|
|
|
560
638
|
|
|
561
639
|
// Keep stdout reserved for the single JSON envelope: any console output
|
|
562
640
|
// produced by underlying operations (e.g. config-load logs) goes to stderr.
|
|
641
|
+
// A hard guard on process.stdout.write catches direct writes that bypass console.
|
|
563
642
|
const originalLog = console.log;
|
|
564
643
|
const originalInfo = console.info;
|
|
565
644
|
const originalWarn = console.warn;
|
|
645
|
+
const previousStdoutWrite = process.stdout.write;
|
|
646
|
+
const boundStdoutWrite = previousStdoutWrite.bind(process.stdout);
|
|
647
|
+
machineEnvelopeWrite = (chunk) => {
|
|
648
|
+
boundStdoutWrite(chunk);
|
|
649
|
+
};
|
|
650
|
+
process.stdout.write = ((chunk: string | Uint8Array, ...rest: unknown[]) =>
|
|
651
|
+
(process.stderr.write as (...args: unknown[]) => boolean)(chunk, ...rest)) as typeof process.stdout.write;
|
|
566
652
|
const toStderr = (...args: unknown[]) => {
|
|
567
653
|
process.stderr.write(`${args.map((arg) => (typeof arg === "string" ? arg : JSON.stringify(arg))).join(" ")}\n`);
|
|
568
654
|
};
|
|
@@ -598,5 +684,7 @@ export async function runMachineCli(argv: string[] = process.argv): Promise<void
|
|
|
598
684
|
console.log = originalLog;
|
|
599
685
|
console.info = originalInfo;
|
|
600
686
|
console.warn = originalWarn;
|
|
687
|
+
process.stdout.write = previousStdoutWrite;
|
|
688
|
+
machineEnvelopeWrite = null;
|
|
601
689
|
}
|
|
602
690
|
}
|
package/src/mcp/index.ts
CHANGED
|
@@ -188,15 +188,18 @@ export function buildSwallowKitToolDefinitions(
|
|
|
188
188
|
},
|
|
189
189
|
{
|
|
190
190
|
name: "swallowkit_plan_scaffold",
|
|
191
|
-
description: "Compute the scaffold change plan (files to create/update/overwrite, conflicts, warnings) without writing any files.
|
|
191
|
+
description: "Compute the scaffold change plan (files to create/update/overwrite, conflicts, warnings) without writing any files. Accepts one or more models; returns a planId per model usable with swallowkit_apply_scaffold.",
|
|
192
192
|
inputSchema: z.object({
|
|
193
|
-
model: z.string(),
|
|
193
|
+
model: z.string().optional(),
|
|
194
|
+
models: z.array(z.string()).optional(),
|
|
194
195
|
functionsDir: z.string().optional(),
|
|
195
196
|
apiDir: z.string().optional(),
|
|
196
197
|
apiOnly: z.boolean().optional(),
|
|
197
198
|
}),
|
|
198
|
-
handler: async ({ model, functionsDir, apiDir, apiOnly }: { model
|
|
199
|
-
const
|
|
199
|
+
handler: async ({ model, models, functionsDir, apiDir, apiOnly }: { model?: string; models?: string[]; functionsDir?: string; apiDir?: string; apiOnly?: boolean }) => {
|
|
200
|
+
const targets = models && models.length > 0 ? models : model ? [model] : [];
|
|
201
|
+
if (targets.length === 0) throw new Error("Provide model or models.");
|
|
202
|
+
const args = ["plan", "scaffold", ...targets];
|
|
200
203
|
if (functionsDir) args.push("--functions-dir", functionsDir);
|
|
201
204
|
if (apiDir) args.push("--api-dir", apiDir);
|
|
202
205
|
if (apiOnly) args.push("--api-only");
|
|
@@ -249,15 +252,17 @@ export function buildSwallowKitToolDefinitions(
|
|
|
249
252
|
},
|
|
250
253
|
{
|
|
251
254
|
name: "swallowkit_verify_project",
|
|
252
|
-
description: "Run verification checks (structure, drift, typecheck by default; build, lint, test and custom checks from swallowkit.config verify.checks are also available) and return machine-readable evidence. summary.done=true means the project passed all checks.",
|
|
255
|
+
description: "Run verification checks (structure, drift, typecheck by default; build, lint, test and custom checks from swallowkit.config verify.checks are also available) and return machine-readable evidence. summary.done=true means the project passed all checks. Set compact=true to suppress info-severity findings and keep the output small.",
|
|
253
256
|
inputSchema: z.object({
|
|
254
257
|
checks: z.array(z.string()).optional(),
|
|
258
|
+
compact: z.boolean().optional(),
|
|
255
259
|
}),
|
|
256
|
-
handler: async ({ checks }: { checks?: string[] }) => {
|
|
260
|
+
handler: async ({ checks, compact }: { checks?: string[]; compact?: boolean }) => {
|
|
257
261
|
const args = ["verify", "project"];
|
|
258
262
|
if (checks && checks.length > 0) {
|
|
259
263
|
args.push("--checks", checks.join(","));
|
|
260
264
|
}
|
|
265
|
+
if (compact) args.push("--compact");
|
|
261
266
|
|
|
262
267
|
const response = await executeMachineCommand(args, runMachineCli);
|
|
263
268
|
return jsonTextContent(withOperationStatus(response));
|
|
@@ -288,16 +293,27 @@ export function buildSwallowKitToolDefinitions(
|
|
|
288
293
|
return jsonTextContent(withSwallowKitMetadata(response.data));
|
|
289
294
|
},
|
|
290
295
|
},
|
|
296
|
+
{
|
|
297
|
+
name: "swallowkit_inspect_capabilities",
|
|
298
|
+
description: "Return SwallowKit's capability contract: which declarations models support (partitionKey, authPolicy, displayName, connectorConfig, with format examples), the correct auth-introduction workflow, what generated CRUD does and does NOT guarantee (no owner scoping), how dev seeds are applied, and every machine command. Consult this before assuming SwallowKit can or cannot do something.",
|
|
299
|
+
inputSchema: z.object({}),
|
|
300
|
+
handler: async () => {
|
|
301
|
+
const response = await executeMachineCommand(["inspect", "capabilities"], runMachineCli);
|
|
302
|
+
return jsonTextContent(withSwallowKitMetadata(response.data));
|
|
303
|
+
},
|
|
304
|
+
},
|
|
291
305
|
{
|
|
292
306
|
name: "swallowkit_plan_auth",
|
|
293
|
-
description: "Compute the add-auth change plan (files to create/update/overwrite, conflicts, warnings) without writing any files. Returns a planId usable with swallowkit_apply_auth.",
|
|
307
|
+
description: "Compute the add-auth change plan (files to create/update/overwrite, conflicts, warnings) without writing any files. Returns a planId usable with swallowkit_apply_auth. Never hand-write auth.schemes in swallowkit.config; this operation owns them.",
|
|
294
308
|
inputSchema: z.object({
|
|
295
309
|
provider: z.enum(["custom-jwt", "swa", "external-token", "none"]),
|
|
296
310
|
scheme: z.string().optional(),
|
|
311
|
+
allowedProviders: z.array(z.string()).optional(),
|
|
297
312
|
}),
|
|
298
|
-
handler: async ({ provider, scheme }: { provider: string; scheme?: string }) => {
|
|
313
|
+
handler: async ({ provider, scheme, allowedProviders }: { provider: string; scheme?: string; allowedProviders?: string[] }) => {
|
|
299
314
|
const args = ["plan", "auth", "--provider", provider];
|
|
300
315
|
if (scheme) args.push("--scheme", scheme);
|
|
316
|
+
if (allowedProviders && allowedProviders.length > 0) args.push("--allowed-providers", allowedProviders.join(","));
|
|
301
317
|
|
|
302
318
|
const response = await executeMachineCommand(args, runMachineCli);
|
|
303
319
|
return jsonTextContent(withOperationStatus(response));
|
|
@@ -305,18 +321,20 @@ export function buildSwallowKitToolDefinitions(
|
|
|
305
321
|
},
|
|
306
322
|
{
|
|
307
323
|
name: "swallowkit_apply_auth",
|
|
308
|
-
description: "Apply add-auth changes. Rejects stale plans and requires approve=true when user-modified files would be overwritten.",
|
|
324
|
+
description: "Apply add-auth changes. Rejects stale plans and requires approve=true when user-modified files would be overwritten. Follow the returned nextActions: policies and swa.allowedProviders are hand-edited afterwards, and external-token verifier stubs must be implemented.",
|
|
309
325
|
inputSchema: z.object({
|
|
310
326
|
provider: z.enum(["custom-jwt", "swa", "external-token", "none"]).optional(),
|
|
311
327
|
scheme: z.string().optional(),
|
|
328
|
+
allowedProviders: z.array(z.string()).optional(),
|
|
312
329
|
planId: z.string().optional(),
|
|
313
330
|
approve: z.boolean().optional(),
|
|
314
331
|
}),
|
|
315
|
-
handler: async ({ provider, scheme, planId, approve }: { provider?: string; scheme?: string; planId?: string; approve?: boolean }) => {
|
|
332
|
+
handler: async ({ provider, scheme, allowedProviders, planId, approve }: { provider?: string; scheme?: string; allowedProviders?: string[]; planId?: string; approve?: boolean }) => {
|
|
316
333
|
const args = ["apply", "auth"];
|
|
317
334
|
if (planId) args.push("--plan", planId);
|
|
318
335
|
if (provider) args.push("--provider", provider);
|
|
319
336
|
if (scheme) args.push("--scheme", scheme);
|
|
337
|
+
if (allowedProviders && allowedProviders.length > 0) args.push("--allowed-providers", allowedProviders.join(","));
|
|
320
338
|
if (approve) args.push("--approve");
|
|
321
339
|
|
|
322
340
|
const response = await executeMachineCommand(args, runMachineCli);
|