From 5d487ac2f870973f79d4df30cd8376feb4ef8f10 Mon Sep 17 00:00:00 2001 From: Suleiman Shahbari Date: Sat, 4 Jul 2026 04:33:07 +0300 Subject: [PATCH] refactor: dedup neutral guardrail persona and flatten run.ts wiring Name the path-neutral guardrail tail once (neutralGuardrails) and spread it into both sharedPersonas and vikeExtensionPersonas so the invariant is structural, not maintained by copy. In run.ts, hoist the duplicated verifyWorkspace option and flatten the deploy step's double-nested ternary that tested opts.deploy twice. No behavior change. Closes #196 --- packages/ai-autopilot/src/personas/library.ts | 12 ++++++++++-- packages/framework/src/run.ts | 17 ++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/packages/ai-autopilot/src/personas/library.ts b/packages/ai-autopilot/src/personas/library.ts index b8b951b..18faad4 100644 --- a/packages/ai-autopilot/src/personas/library.ts +++ b/packages/ai-autopilot/src/personas/library.ts @@ -452,6 +452,14 @@ Reach for a bespoke component only for a genuinely custom region, and even then style it with the theme's CSS variables so it tracks light/dark and the brand.`, }) +/** + * The framework- and path-neutral guardrails that apply on every path — plain + * Prisma or composed extensions, Vike or Next. Kept as one named tail so both + * {@link sharedPersonas} and {@link vikeExtensionPersonas} spread it instead of + * re-listing it, and adding a neutral guardrail can't silently drop from a path. + */ +const neutralGuardrails: readonly Persona[] = Object.freeze([uiIntentDesigner]) + /** * The framework-neutral personas shared by every preset — the data layer and the * intent-based UI guardrail apply the same whether the app is on Vike or Next. @@ -459,7 +467,7 @@ style it with the theme's CSS variables so it tracks light/dark and the brand.`, */ export const sharedPersonas: readonly Persona[] = Object.freeze([ dataModeler, - uiIntentDesigner, + ...neutralGuardrails, ]) /** @@ -478,7 +486,7 @@ export const vikeExtensionPersonas: readonly Persona[] = Object.freeze([ vikeRbacComposer, vikeCrudComposer, vikeShellComposer, - uiIntentDesigner, + ...neutralGuardrails, ]) /** All built-in stack personas (the Vike stack), in a stable order. */ diff --git a/packages/framework/src/run.ts b/packages/framework/src/run.ts index b578571..22d549e 100644 --- a/packages/framework/src/run.ts +++ b/packages/framework/src/run.ts @@ -236,6 +236,7 @@ export async function runFramework(opts: RunFrameworkOptions): Promise ({ scope: opts.scope ?? 'full', intent: opts.intent }), architect: driverArchitect(session), - build: driverBuild(session, verifyWorkspace ? { verifyWorkspace: true } : {}), + build: driverBuild(session, workspaceOpt), checklist, - improve: driverImprove(session, verifyWorkspace ? { verifyWorkspace: true } : {}), - ...(opts.deploy && opts.deployTarget - ? { deploy: deployWith(opts.deploy, opts.deployTarget) } - : opts.deploy - ? { deploy: decideDeploy(opts.deploy) } - : {}), + improve: driverImprove(session, workspaceOpt), + ...(opts.deploy + ? { + deploy: opts.deployTarget + ? deployWith(opts.deploy, opts.deployTarget) + : decideDeploy(opts.deploy), + } + : {}), }, }) const result = await bootstrap.run()