Skip to content

chore+feat: reconcile Phase 0-6 state, add Azure OpenAI provider#1

Merged
Nether403 merged 2 commits into
mainfrom
chore/phase-0-to-6-reconcile
May 12, 2026
Merged

chore+feat: reconcile Phase 0-6 state, add Azure OpenAI provider#1
Nether403 merged 2 commits into
mainfrom
chore/phase-0-to-6-reconcile

Conversation

@Nether403

@Nether403 Nether403 commented May 12, 2026

Copy link
Copy Markdown
Owner

Summary

Reconciles main with the on-disk state of Phases 0, 2, 3, 5, and 6, and completes Phase 5 by shipping a real Azure OpenAI provider alongside Gemini and the heuristic fallback.

Phase 0 — Cleanup

  • Removed old branches, root client/server/shared/, legacy build configs, attached assets, stale reference docs, debris files.

Phase 5 — Blueprint AI (complete for MVP)

  • packages/ai Gemini provider (@ai-sdk/google) with Zod-validated responses and heuristic fallback on every method.
  • New: packages/ai Azure OpenAI provider (@ai-sdk/azure) using the operator's Azure AI Foundry deployment (e.g. gpt-5.5 or gpt-4.1). Deployment name is operator-configured via AZURE_OPENAI_DEPLOYMENT.
  • Removed the previous "openai" stub branch.
  • /api/v1/blueprints fans out AI calls in parallel and returns rationale, key reasons, confidence, tradeoffs, whyNot, roadmap, and cost estimates.
  • New ADR: docs/decisions/002-ai-provider-strategy.md.

Phase 6 — Registry expansion

  • Registry v1.1.0: 97 tools, 93 rules, 20 categories, exceeding the 80-tool Phase 6 target.
  • Every tool has lastVerified, sourceUrls, confidence, capabilities[].

Phase 3 hardening

  • Admin API key middleware, production fails closed when auth isn't configured.
  • In-memory rate limit with cleanup (TODO Phase 8: migrate to Upstash/Redis).
  • CORS per-env with credentials; no wildcard.
  • OpenAPI document with component schemas and security schemes.

Quality gate (ran locally)

  • pnpm -r type-check — 0 errors across 8 projects
  • pnpm -r lint — 0 errors across 8 projects
  • pnpm -r build — web + api + all packages built
  • pnpm -r test60 tests pass (40 API + 6 AI + 5 rules-engine + 5 exporter + 4 registry)
  • pnpm validate:registry — passes

Config for Azure OpenAI

AI_PROVIDER=azure-openai
AZURE_OPENAI_RESOURCE_NAME=<foundry-resource-name>
AZURE_OPENAI_API_KEY=<key>
AZURE_OPENAI_DEPLOYMENT=gpt-5.5

Missing config falls back to the heuristic explainer at startup with a warning; the API never fails closed on AI configuration.

Not in this PR

  • .env remains gitignored.
  • Phase 4 UI gaps (blueprint wizard, compatibility heatmap, TanStack Query sweep) — follow-up PRs.
  • Phase 8 deployment work is out of scope here.

This commit brings the git history in sync with the actual working
tree after Phases 0, 2, 3, 5, and 6 were executed on disk without
being committed.

Phase 0 (Cleanup & Preserve)
- Remove Branches/StackFast-101, StackfastPro, StackWiseAI, StackFastold
- Remove WebAILyzerAPI (deferred — preserved in docs/deferred/webailyzer.md)
- Remove root client/, server/, shared/ (replaced by apps/ and packages/)
- Remove legacy root build configs (vite/tailwind/drizzle/tsconfig/postcss/components)
- Remove developer-tools-api, attached_assets, stale Referencedocs
- Remove debris: fix-scores.js, export.csv, dev.log, run.log, package-lock.json, Dockerfile
- .gitignore already covers .env, dist/, node_modules, build artifacts

Phase 5 (Blueprint AI layer)
- packages/ai: Gemini provider via Vercel AI SDK with Zod-validated responses
- Heuristic fallback wrapper on every method (explainStack, tradeoffs, whyNot, roadmap)
- Cost estimator pulled from registry pricing
- apps/api: /blueprints fans out AI calls in parallel, returns rationale +
  keyReasons + confidence + tradeoffs + whyNot + roadmap + costEstimate

Phase 6 (Registry expansion)
- Registry at v1.1.0: 97 tools, 93 rules, 20 categories
- New schema-supported categories: agent frameworks, AI model providers,
  vector databases, eval/observability, backend frameworks, queues/workflows,
  testing, monorepos, CMS, mobile
- lastVerified, sourceUrls, confidence, capabilities[] on every tool

Phase 3 hardening on /admin, /internal, generation auth, and rate limiting
- Admin API key middleware; production fails closed when auth isn't configured
- In-memory rate-limit with periodic cleanup (TODO Phase 8: move to Upstash/Redis)
- CORS configured per environment, credentialed; no wildcard
- OpenAPI document with all MVP paths, component schemas, security schemes

Quality gate (runs locally, green)
- apps/api: 40 tests pass (auth, rate-limit, zod, admin protection, shape)
- Registry validation passes
- Type-check, lint, build pass across all 8 workspace projects
- Playwright E2E suite covers the four primary MVP flows

Docs
- docs/decisions/001-authentication-strategy.md (Better Auth + Neon)
- docs/deferred/webailyzer.md (post-MVP SSRF review required)
- docs/backlog/INTEGRATION_PLAN.md (moved from Referencedocs)
- ROADMAP.md and SALVAGE_MANIFEST.md updated to reflect actual state

Not committed (intentionally)
- .env (gitignored; secrets)

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

View 7 additional findings in Devin Review.

Open in Devin Review

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Inconsistent JSON fence stripping in summarizeTradeoffs

In packages/ai/src/providers/gemini.ts, the summarizeTradeoffs method at line 99 uses inline regex to strip markdown fences (result.text.replace(/^\``(?:json)?\n?/, "").replace(/\n?```$/, "").trim()), while all three other methods (explainStack, explainWhyNot, generateRoadmap) use the stripJsonFences()helper function. The inline regex is functionally equivalent, but it represents an incomplete refactor. IfstripJsonFencesis ever updated to handle additional edge cases (e.g., extra trailing whitespace, nested fences),summarizeTradeoffs` would silently diverge.

(Refers to line 99)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread apps/web/index.html
img-src 'self' data: https:;
font-src 'self' data:;
connect-src 'self';
connect-src 'self' http://localhost:* http://127.0.0.1:*;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 CSP connect-src blocks API requests in production

The Content Security Policy meta tag in apps/web/index.html sets connect-src 'self' http://localhost:* http://127.0.0.1:*. In production the web app will be served from a domain like stackfast.app, and the API will be at a separate origin (e.g., https://api.stackfast.app). Since only 'self' and http://localhost:* / http://127.0.0.1:* are allowed, all cross-origin fetch() calls to the production API will be blocked by the browser's CSP enforcement. Additionally, the http:// scheme entries don't cover https://localhost:* either. The meta CSP comment says "Vercel headers take precedence" but the project deploys to Railway, not Vercel, so this CSP will actually be enforced.

Prompt for agents
The connect-src directive in the CSP meta tag at apps/web/index.html:30 only allows 'self', http://localhost:*, and http://127.0.0.1:*. In production, when the API is on a different origin, all API calls will be blocked by the browser. The fix needs to either: (1) remove the restrictive meta CSP and rely on server-side headers that can be dynamically configured per environment, (2) add the production API origin to the connect-src, or (3) use a Vite environment variable to inject the correct API origin at build time. Additionally, the http:// entries should probably also include https:// for local HTTPS dev setups. The comment on line 23 references Vercel but the project deploys to Railway.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7 issues found across 186 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".env.example">

<violation number="1" location=".env.example:16">
P2: Auth bypass comments are inaccurate: bypass applies to all non-production environments unless `ALLOW_AUTH_BYPASS=false`, not only when `DATABASE_URL` is missing.</violation>
</file>

<file name="apps/api/src/middleware/auth.ts">

<violation number="1" location="apps/api/src/middleware/auth.ts:98">
P1: Security: when auth IS configured, this new bypass skips session validation in all non-production environments by default. The old code only bypassed when auth was unavailable (`!auth`). Now staging/preview deployments with a real database have all protected routes wide open unless `ALLOW_AUTH_BYPASS=false` is explicitly set. Consider requiring an explicit opt-in (`ALLOW_AUTH_BYPASS=true`) instead of opt-out, so that configured auth systems aren't silently disabled.</violation>
</file>

<file name="package.json">

<violation number="1" location="package.json:23">
P2: `@types/node` is pinned to v25 while the repo supports/runs on Node 20.x. This can hide runtime compatibility issues by allowing newer Node APIs in type-checking.</violation>
</file>

<file name="apps/web/index.html">

<violation number="1" location="apps/web/index.html:30">
P1: The CSP `connect-src` now permits localhost/127.0.0.1, which weakens the fallback security policy and can allow XSS payloads to reach local machine services. Keep localhost allowances out of the production CSP fallback.</violation>

<violation number="2" location="apps/web/index.html:30">
P1: `connect-src` is restricted to `self` and localhost, which blocks browser requests to a production API on a different origin. Add the production API origin (and local HTTPS variants) to this directive or move CSP to environment-specific response headers.</violation>
</file>

<file name="packages/schemas/src/db.ts">

<violation number="1" location="packages/schemas/src/db.ts:21">
P2: Missing `.$onUpdate(() => new Date())` on `updatedAt` fields. The better-auth canonical Drizzle schema includes this hook so that UPDATE operations automatically refresh the timestamp. Without it, `updatedAt` will remain at the row's creation time after updates.</violation>
</file>

<file name="readme.md">

<violation number="1" location="readme.md:105">
P2: The README labels auth-required endpoints as “Public MVP routes,” which is inaccurate for `/api/v1/blueprints` and `/api/v1/scaffolds` and can mislead API consumers.</violation>
</file>

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
On a pro plan you can use ultrareview for larger PRs.

{ error: "Authentication is not configured", requestId: c.get("requestId") },
503 as ContentfulStatusCode,
);
if (canBypassAuthForLocalDev(c.env)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Security: when auth IS configured, this new bypass skips session validation in all non-production environments by default. The old code only bypassed when auth was unavailable (!auth). Now staging/preview deployments with a real database have all protected routes wide open unless ALLOW_AUTH_BYPASS=false is explicitly set. Consider requiring an explicit opt-in (ALLOW_AUTH_BYPASS=true) instead of opt-out, so that configured auth systems aren't silently disabled.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/api/src/middleware/auth.ts, line 98:

<comment>Security: when auth IS configured, this new bypass skips session validation in all non-production environments by default. The old code only bypassed when auth was unavailable (`!auth`). Now staging/preview deployments with a real database have all protected routes wide open unless `ALLOW_AUTH_BYPASS=false` is explicitly set. Consider requiring an explicit opt-in (`ALLOW_AUTH_BYPASS=true`) instead of opt-out, so that configured auth systems aren't silently disabled.</comment>

<file context>
@@ -91,13 +91,23 @@ export function requireSession(): MiddlewareHandler<{
-          { error: "Authentication is not configured", requestId: c.get("requestId") },
-          503 as ContentfulStatusCode,
-        );
+      if (canBypassAuthForLocalDev(c.env)) {
+        await next();
+        return;
</file context>

Comment thread apps/web/index.html
img-src 'self' data: https:;
font-src 'self' data:;
connect-src 'self';
connect-src 'self' http://localhost:* http://127.0.0.1:*;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The CSP connect-src now permits localhost/127.0.0.1, which weakens the fallback security policy and can allow XSS payloads to reach local machine services. Keep localhost allowances out of the production CSP fallback.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/web/index.html, line 30:

<comment>The CSP `connect-src` now permits localhost/127.0.0.1, which weakens the fallback security policy and can allow XSS payloads to reach local machine services. Keep localhost allowances out of the production CSP fallback.</comment>

<file context>
@@ -27,7 +27,7 @@
       img-src 'self' data: https:;
       font-src 'self' data:;
-      connect-src 'self';
+      connect-src 'self' http://localhost:* http://127.0.0.1:*;
       worker-src 'self' blob:;
       child-src 'self' blob:;
</file context>
Suggested change
connect-src 'self' http://localhost:* http://127.0.0.1:*;
connect-src 'self';

Comment thread apps/web/index.html
img-src 'self' data: https:;
font-src 'self' data:;
connect-src 'self';
connect-src 'self' http://localhost:* http://127.0.0.1:*;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: connect-src is restricted to self and localhost, which blocks browser requests to a production API on a different origin. Add the production API origin (and local HTTPS variants) to this directive or move CSP to environment-specific response headers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/web/index.html, line 30:

<comment>`connect-src` is restricted to `self` and localhost, which blocks browser requests to a production API on a different origin. Add the production API origin (and local HTTPS variants) to this directive or move CSP to environment-specific response headers.</comment>

<file context>
@@ -27,7 +27,7 @@
       img-src 'self' data: https:;
       font-src 'self' data:;
-      connect-src 'self';
+      connect-src 'self' http://localhost:* http://127.0.0.1:*;
       worker-src 'self' blob:;
       child-src 'self' blob:;
</file context>
Suggested change
connect-src 'self' http://localhost:* http://127.0.0.1:*;
connect-src 'self' https://api.stackfast.app http://localhost:* https://localhost:* http://127.0.0.1:* https://127.0.0.1:*;

Comment thread .env.example
Comment on lines +16 to +17
# Local catalog-only dev may bypass auth when no DATABASE_URL is set.
# Production MUST set this to "false" so auth failures fail closed.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Auth bypass comments are inaccurate: bypass applies to all non-production environments unless ALLOW_AUTH_BYPASS=false, not only when DATABASE_URL is missing.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .env.example, line 16:

<comment>Auth bypass comments are inaccurate: bypass applies to all non-production environments unless `ALLOW_AUTH_BYPASS=false`, not only when `DATABASE_URL` is missing.</comment>

<file context>
@@ -4,30 +4,36 @@ NODE_ENV=development
 BETTER_AUTH_URL=http://localhost:3000
-# Local catalog-only development can bypass auth when no DATABASE_URL is set.
-# Production always fails closed if auth/database is unavailable.
+# Local catalog-only dev may bypass auth when no DATABASE_URL is set.
+# Production MUST set this to "false" so auth failures fail closed.
 ALLOW_AUTH_BYPASS=true
</file context>
Suggested change
# Local catalog-only dev may bypass auth when no DATABASE_URL is set.
# Production MUST set this to "false" so auth failures fail closed.
# Local catalog-only dev may bypass auth in non-production when ALLOW_AUTH_BYPASS is not "false".
# Set ALLOW_AUTH_BYPASS=false anywhere you want session auth enforced (including staging).

Comment thread package.json
"validate:registry": "pnpm --filter @stackfast/registry validate"
},
"devDependencies": {
"@eslint/js": "^9.17.0",
"@playwright/test": "^1.59.1",
"@types/node": "^25.6.2",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: @types/node is pinned to v25 while the repo supports/runs on Node 20.x. This can hide runtime compatibility issues by allowing newer Node APIs in type-checking.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At package.json, line 23:

<comment>`@types/node` is pinned to v25 while the repo supports/runs on Node 20.x. This can hide runtime compatibility issues by allowing newer Node APIs in type-checking.</comment>

<file context>
@@ -6,22 +6,31 @@
   "devDependencies": {
     "@eslint/js": "^9.17.0",
+    "@playwright/test": "^1.59.1",
+    "@types/node": "^25.6.2",
+    "concurrently": "^9.2.1",
+    "dotenv-cli": "^11.0.0",
</file context>
Suggested change
"@types/node": "^25.6.2",
"@types/node": "^20.19.0",

emailVerified: boolean("email_verified").notNull().default(false),
image: text("image"),
createdAt: timestamp("created_at").notNull().defaultNow(),
updatedAt: timestamp("updated_at").notNull().defaultNow(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Missing .$onUpdate(() => new Date()) on updatedAt fields. The better-auth canonical Drizzle schema includes this hook so that UPDATE operations automatically refresh the timestamp. Without it, updatedAt will remain at the row's creation time after updates.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/schemas/src/db.ts, line 21:

<comment>Missing `.$onUpdate(() => new Date())` on `updatedAt` fields. The better-auth canonical Drizzle schema includes this hook so that UPDATE operations automatically refresh the timestamp. Without it, `updatedAt` will remain at the row's creation time after updates.</comment>

<file context>
@@ -1,9 +1,82 @@
+  emailVerified: boolean("email_verified").notNull().default(false),
+  image: text("image"),
+  createdAt: timestamp("created_at").notNull().defaultNow(),
+  updatedAt: timestamp("updated_at").notNull().defaultNow(),
+});
+
</file context>
Suggested change
updatedAt: timestamp("updated_at").notNull().defaultNow(),
updatedAt: timestamp("updated_at").notNull().defaultNow().$onUpdate(() => new Date()),

Comment thread readme.md

## API Surface

Public MVP routes:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The README labels auth-required endpoints as “Public MVP routes,” which is inaccurate for /api/v1/blueprints and /api/v1/scaffolds and can mislead API consumers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At readme.md, line 105:

<comment>The README labels auth-required endpoints as “Public MVP routes,” which is inaccurate for `/api/v1/blueprints` and `/api/v1/scaffolds` and can mislead API consumers.</comment>

<file context>
@@ -1,69 +1,152 @@
+
+## API Surface
+
+Public MVP routes:
+
+- `GET /health`
</file context>
Suggested change
Public MVP routes:
MVP routes:

Phase 5 close-out. The operator's Azure AI Foundry resource (with
gpt-5.5 and gpt-4.1 deployments) is now a first-class blueprint
provider alongside Gemini and the heuristic fallback.

What changed
- packages/ai: new AzureOpenAIExplainer using @ai-sdk/azure +
  Vercel AI SDK, same four methods as GeminiExplainer, same Zod
  validation on every response, wrapped in FallbackExplainer.
- packages/ai: createExplainer() now accepts provider = "azure-openai"
  with apiKey, azureResourceName, model (deployment name), and an
  optional azureApiVersion. Missing config falls back to heuristic
  with a warning instead of throwing.
- packages/ai: removed the "openai" stub branch (it only logged and
  returned heuristic; now replaced by real azure-openai support).
- packages/ai: new index.test.ts covering factory fallback paths
  and heuristic roadmap shape (6 tests).
- apps/api: wires AZURE_OPENAI_RESOURCE_NAME / AZURE_OPENAI_API_KEY /
  AZURE_OPENAI_DEPLOYMENT / AZURE_OPENAI_API_VERSION into createExplainer.

Docs and config
- .env.example: added AZURE_OPENAI_* variables and reorganized the
  AI section by provider.
- docs/decisions/002-ai-provider-strategy.md: new ADR capturing the
  heuristic + Gemini + Azure OpenAI strategy and the Zod-validated
  fallback contract.
- ROADMAP.md: Phase 5 marked complete for MVP scope; ADR-in-response
  is the only remaining checkbox, deferred to v1.1.
- readme.md: updated env var table to list the Azure keys.

Quality gate (local)
- pnpm -r type-check: 0 errors
- pnpm -r lint: 0 errors
- pnpm -r test: 60 tests pass (40 api + 6 ai + 5 rules-engine +
  5 exporter + 4 registry)
- pnpm validate:registry: passes
- pnpm -r build: web + api + all packages build

Notes
- Azure deployments are customer-named, so the deployment name is
  provided by the operator via env (AZURE_OPENAI_DEPLOYMENT), not
  hardcoded to gpt-5.5.
- No production environment changes. Provider is selected by
  AI_PROVIDER env; default remains heuristic.
@Nether403 Nether403 changed the title chore: reconcile main with Phase 0-6 on-disk state chore+feat: reconcile Phase 0-6 state, add Azure OpenAI provider May 12, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 11 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="readme.md">

<violation number="1" location="readme.md:81">
P2: The new Azure AI provider docs are inconsistent with Setup guidance, which still mentions only optional `GEMINI_API_KEY`. Update Setup text to also mention Azure OpenAI variables when `AI_PROVIDER=azure-openai`.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread readme.md
| `ALLOW_AUTH_BYPASS` | Local non-production auth bypass when no database is configured |
| `GITHUB_CLIENT_ID`, `GITHUB_CLIENT_SECRET` | GitHub OAuth credentials |
| `ADMIN_API_KEY` | Protects `/admin/*` and `/internal/*` routes |
| `AI_PROVIDER` | `heuristic`, `gemini`, or `azure-openai` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The new Azure AI provider docs are inconsistent with Setup guidance, which still mentions only optional GEMINI_API_KEY. Update Setup text to also mention Azure OpenAI variables when AI_PROVIDER=azure-openai.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At readme.md, line 81:

<comment>The new Azure AI provider docs are inconsistent with Setup guidance, which still mentions only optional `GEMINI_API_KEY`. Update Setup text to also mention Azure OpenAI variables when `AI_PROVIDER=azure-openai`.</comment>

<file context>
@@ -78,8 +78,11 @@ Common local variables are documented in `.env.example`:
 | `ADMIN_API_KEY` | Protects `/admin/*` and `/internal/*` routes |
-| `AI_PROVIDER` | `heuristic`, `gemini`, or `openai` |
-| `GEMINI_API_KEY`, `OPENAI_API_KEY` | Optional AI provider keys |
+| `AI_PROVIDER` | `heuristic`, `gemini`, or `azure-openai` |
+| `GEMINI_API_KEY` | Gemini API key (when `AI_PROVIDER=gemini`) |
+| `AZURE_OPENAI_RESOURCE_NAME` | Azure Foundry resource subdomain (when `AI_PROVIDER=azure-openai`) |
</file context>

@Nether403 Nether403 merged commit c1065a3 into main May 12, 2026
2 checks passed
@Nether403 Nether403 deleted the chore/phase-0-to-6-reconcile branch May 12, 2026 00:50
Nether403 added a commit that referenced this pull request May 12, 2026
Phase 4 gap #1: the Blueprint Builder was a single form with idea +
constraints. This PR splits the flow into a guided 4-step wizard
and adds an integrated scaffold export step so users can go from
idea to downloadable starter repo in one page.

Steps
1. Idea — required textarea, focused and distraction-free
2. Constraints — optional free-form constraints plus structured
   fields for budget, timeline, and team size (all wired to the
   BlueprintRequest schema)
3. Results — existing BlueprintOutputCard rendered inside the wizard
4. Export — scaffold generation via /api/v1/scaffolds with project
   name input, file list preview, warnings panel, and client-side
   ZIP download using the existing archive-generator

UX
- Progress indicator shows completed/active/pending steps with a
  data-testid for E2E assertions
- Back / Next controls with per-step loading states and a "Start
  over" action on the final step
- Errors from blueprint generation and scaffold generation are
  surfaced inline with retry affordances
- Regenerate button on the export step in case the user tweaks
  the project name after scaffolding

E2E coverage
- tests/e2e/mvp-flows.spec.ts walks the full wizard: idea →
  constraints (with budget/timeline selects) → results (asserts
  "Recommended Architecture", "Primary Stack", "Harmony Score")
  → export (asserts "Download ZIP" is visible)
- Saves a screenshot at each step to test-results/wizard-step-*.png
  for visual evidence (test-results/ is gitignored)
- Bumps this test's timeout to 180s because blueprint generation
  can take 25-30s when Gemini provider does the full fan-out

Quality gate (local)
- pnpm -r type-check: 0 errors
- pnpm -r lint: 0 errors
- pnpm -r test: 60 unit/API tests pass
- pnpm -r build: web + api + packages
- pnpm test:e2e: 4 passed, including the new multi-step wizard flow
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant