@powerhousedao/codegen 6.0.2-staging.8 → 6.1.0-dev.0

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.
@@ -1,16 +1,16 @@
1
+ import { ANALYTICS_ENGINE_CORE_PACKAGE, BOILERPLATE_ALLOWED_BUILDS, GRAPHQL_PACKAGE, GRAPHQL_TAG_PACKAGE, PEER_EXTERNAL_DEPENDENCIES, REACTOR_API_PACKAGE, VERSIONED_DEV_DEPENDENCIES, VERSIONED_PEER_DEPENDENCIES, defaultManifest, directoryExists, externalDevDependencies, fileExists, fileExistsSync, isDirectory, makeVersionedDependenciesMap, packageJsonExports, spawnAsync, writeFileEnsuringDir } from "@powerhousedao/shared/clis";
2
+ import { readdirSync } from "fs";
3
+ import path, { join } from "path";
1
4
  import { DocumentModelGlobalStateSchema, ManifestSchema } from "@powerhousedao/shared/document-model";
5
+ import fs, { copyFile, mkdir, readdir, writeFile } from "node:fs/promises";
2
6
  import { camelCase, capitalCase, constantCase, kebabCase, pascalCase } from "change-case";
3
- import path, { join } from "path";
4
7
  import { DEFAULT_REGISTRY_URL } from "@powerhousedao/shared/registry";
5
- import { capitalize, concat, conditional, constant, filter, find, first, flatMap, forEach, isDefined, isIncludedIn, isNonNullish, isNot, isStrictEqual, isString, isTruthy, last, map, merge, pipe, prop, sort, split, startsWith, subtract, unique, uniqueBy, when } from "remeda";
8
+ import { capitalize, concat, conditional, constant, endsWith, filter, find, first, flatMap, forEach, isDefined, isIncludedIn, isNonNullish, isNot, isStrictEqual, isString, isTruthy, last, map, mapValues, merge, pipe, prop, sort, split, startsWith, subtract, unique, uniqueBy, when } from "remeda";
6
9
  import { IndentationText, Project, SyntaxKind, VariableDeclarationKind, ts } from "ts-morph";
7
10
  import arg from "arg";
8
- import { readdirSync } from "fs";
9
- import { VERSIONED_DEPENDENCIES, VERSIONED_DEV_DEPENDENCIES, directoryExists, fileExists, fileExistsSync, isDirectory, makeVersionedDependencies, spawnAsync, writeFileEnsuringDir } from "@powerhousedao/shared/clis";
10
11
  import { format } from "prettier";
11
12
  import { z } from "zod";
12
13
  import { loadJsonFile, loadJsonFileSync } from "load-json-file";
13
- import fs, { copyFile, mkdir, readdir, writeFile } from "node:fs/promises";
14
14
  import { stripVTControlCharacters } from "node:util";
15
15
  import path$1, { join as join$1, relative } from "node:path";
16
16
  import { generate } from "@graphql-codegen/cli";
@@ -2039,7 +2039,7 @@ export function FolderTree() {
2039
2039
  const [selectedDrive] = useSelectedDrive();
2040
2040
  const nodes = useNodesInSelectedDrive();
2041
2041
  const selectedNode = useSelectedNode();
2042
- const driveName = selectedDrive.header.name;
2042
+ const driveName = selectedDrive?.header.name ?? "";
2043
2043
  // Transform Node[] to hierarchical SidebarNode structure
2044
2044
  const sidebarNodes = useMemo(
2045
2045
  () => transformNodesToSidebarNodes(nodes || [], driveName),
@@ -2056,7 +2056,7 @@ export function FolderTree() {
2056
2056
  };
2057
2057
  // Map selectedNodeId to activeNodeId (use "root" when undefined)
2058
2058
  const activeNodeId =
2059
- !selectedNode || selectedNode.id === selectedDrive.header.id
2059
+ !selectedNode || selectedNode.id === selectedDrive?.header.id
2060
2060
  ? "root"
2061
2061
  : selectedNode.id;
2062
2062
 
@@ -2209,52 +2209,18 @@ After doing changes to the code, or after creating a new document model or a new
2209
2209
 
2210
2210
  #### Strategy: reaching 100% reducer coverage
2211
2211
 
2212
- 95% is the enforced floor (vitest will fail below it). This strategy describes how to push toward 100% when feasible and how to recognize when an uncovered branch indicates an implementation problem rather than a missing test.
2213
-
2214
- ##### Phase 1: Baseline measurement
2215
-
2216
- Run coverage and identify the gap. Statements and lines reach high coverage quickly — the real challenge is **branch coverage**. Every \`||\`, \`??\`, \`if\`, and \`&&\` creates two branches; V8 counts them independently.
2217
-
2218
- ##### Phase 2: Write scenario tests first
2219
-
2220
- Before chasing branches, write a small number of tests that exercise **realistic operation sequences**. Each test should chain multiple operations together the way a real consumer would use them. This covers the majority of code paths naturally and reveals which branches remain uncovered.
2221
-
2222
- Prefer fewer tests that each cover wide ranges of behavior over many isolated unit tests per branch. A single "full conversation flow" test that exercises 14 operations in sequence is more valuable and more maintainable than 14 separate tests.
2223
-
2224
- ##### Phase 3: Categorize every uncovered branch
2225
-
2226
- Don't write tests to hit uncovered branches yet. First, examine each one and classify it:
2227
-
2228
- 1. **Wrong nullability in the schema** — The type allows \`null\` but the value is always initialized and never null at runtime. The defensive fallback (\`?? 0\`, \`?? defaultValue\`) creates an unreachable branch. No test can meaningfully cover it because the condition cannot occur through any valid operation sequence.
2229
- 2. **Missing validation** — The type is nullable because the schema uses a flattened structure (e.g. a tagged union where fields are optional per variant). Some fields are _required for specific variants_ but the reducer silently accepts their absence. The fallback branch is reachable but only with invalid input that should be rejected.
2230
- 3. **Wrong coercion operator** — \`||\` is used where \`??\` is needed. Values like \`0\`, \`false\`, and \`""\` are valid but \`||\` coerces them to the fallback. This is a bug, not a coverage gap.
2231
- 4. **Legitimate optionality** — The field is genuinely optional. Both branches (value provided / not provided) are reachable through valid inputs. These are the only branches worth covering with tests.
2212
+ 95% is the enforced floor push toward 100% when feasible. Statements and lines reach high coverage quickly; the real challenge is **branch coverage** (every \`||\`, \`??\`, \`if\`, \`&&\` is two branches).
2232
2213
 
2233
- ##### Phase 4: Fix the implementation, don't test around it
2214
+ Write a small number of **scenario tests** first — each chaining many operations the way a real consumer would. One "full conversation flow" test that exercises 14 ops is more valuable than 14 isolated unit tests. Then categorize each remaining uncovered branch before writing a test for it:
2234
2215
 
2235
- For each category:
2216
+ 1. **Wrong nullability** — type allows \`null\` but the value is always initialized. Fix the type (e.g. \`Int!\` in the schema via \`SET_STATE_SCHEMA\` / \`SET_OPERATION_SCHEMA\`); the fallback branch disappears.
2217
+ 2. **Missing validation** — the field is genuinely required for a variant but the reducer silently accepts its absence. Add a named error via \`ADD_OPERATION_ERROR\` and reject; the new branch is reachable and worth testing.
2218
+ 3. **Wrong coercion operator** — \`||\` used where \`??\` is needed; falsy-but-valid values (\`0\`, \`false\`, \`""\`) get coerced to the fallback. Fix the operator and add a test with a falsy-but-valid value.
2219
+ 4. **Legitimate optionality** — both sides reachable through valid inputs. Fold both into existing scenario tests by varying inputs.
2236
2220
 
2237
- - **Wrong nullability** Tighten the type definition. Make the field non-nullable at the source (e.g. \`Int!\` instead of \`Int\` in the GraphQL schema). This eliminates the fallback code entirely, removing the untestable branch. Update the source schema via MCP (\`SET_STATE_SCHEMA\` / \`SET_OPERATION_SCHEMA\`) and regenerate see "Document Model Modification Process" below.
2238
- - **Missing validation** → Add validation that throws a specific named error for invalid input (define it via \`ADD_OPERATION_ERROR\` — see "Error Handling in Operations" below). This converts a silent fallback into an explicit rejection. The validation branch is now both reachable and worth testing.
2239
- - **Wrong operator** → Fix \`||\` to \`??\` (or vice versa). Add a test that passes a falsy-but-valid value (\`0\`, \`false\`, \`""\`) and asserts it is preserved.
2240
- - **Legitimate optionality** → Add test cases that exercise both sides. Often these can be folded into existing scenario tests by varying inputs (e.g. one call provides the field, another omits it).
2221
+ Then extend scenario tests to hit remaining branches: skip initialization to hit "not yet initialized" branches; chain invalid operations using the operation-index pattern from "Testing Reducer Errors" (never \`.toThrow()\`); use minimal/empty inputs for fallback-to-null branches; vary inputs so both sides of legitimate \`||\` / \`??\` are hit.
2241
2222
 
2242
- ##### Phase 5: Extend scenario tests to cover remaining branches
2243
-
2244
- With the implementation corrected, extend the existing scenario tests to hit newly-testable branches:
2245
-
2246
- - Add a test that skips initialization to cover "not yet initialized" false branches.
2247
- - Add error path tests that chain multiple invalid operations in sequence, asserting each error and verifying state is unchanged (use the operation-index pattern from "Testing Reducer Errors" below — never \`.toThrow()\`).
2248
- - Add a test that uses minimal/empty inputs to cover fallback-to-null branches on optional fields.
2249
- - Vary inputs across tests so both sides of legitimate \`||\` / \`??\` operators are hit (e.g. one test provides \`stepIndex: 0\`, another omits it).
2250
-
2251
- ##### Phase 6: Verify
2252
-
2253
- Run \`npm run test:coverage\`. Reducers should be at or near 100% across all four metrics. If any branches remain uncovered, repeat the categorization in Phase 3: is it a type problem, a validation gap, an operator bug, or a legitimate test gap? Do not stop at 95% if a small number of uncovered branches remain — they are usually the cheapest signals of an underlying implementation issue.
2254
-
2255
- ##### The principle
2256
-
2257
- **Don't test around bad types — fix the types.** When a branch is untestable, the problem is almost never a missing test. It is a type that is too loose, a validation that is missing, or an operator that is wrong. Fix the implementation so that every branch is either reachable and meaningful, or eliminated entirely. Coverage follows naturally from correct types, proper validation, and realistic test scenarios.
2223
+ **Principle: don't test around bad types fix them.** When a branch is untestable, it's almost always a type that's too loose, missing validation, or a wrong operator. Coverage follows naturally from correct types and realistic scenarios.
2258
2224
 
2259
2225
  ## Document editor creation flow
2260
2226
 
@@ -2394,90 +2360,26 @@ function str(v: unknown): string {
2394
2360
 
2395
2361
  ### Drag-and-drop file uploads (optional pattern)
2396
2362
 
2397
- Use this pattern **only** when your editor needs to accept arbitrary file drops (images, PDFs, CSVs, attachments, etc.). Default editors do **not** need any of this — skip this entire section if your editor does not handle file uploads.
2398
-
2399
- #### Why the default does not work
2363
+ Use this **only** when your editor needs to accept arbitrary file drops (images, PDFs, CSVs, attachments). Default editors do not need any of this.
2400
2364
 
2401
- Connect wraps every editor inside a \`DropZoneWrapper\` (from \`@powerhousedao/design-system/connect\`). That outer wrapper:
2402
-
2403
- 1. Only accepts \`.phd\`, \`.phdm\`, and \`.zip\` files (Powerhouse document files).
2404
- 2. Sets \`dataTransfer.dropEffect = "none"\` (the blocked / no-entry cursor) for any other file type.
2405
- 3. Calls \`event.stopPropagation()\` on \`dragover\`, \`dragenter\`, and \`dragleave\` so events do not bubble past it.
2406
- 4. Shows a full-screen overlay when a valid Powerhouse document is dragged in.
2407
-
2408
- Your editor is a **descendant** of \`DropZoneWrapper\`. DOM events bubble inner → outer, so your editor's handlers run **before** DropZone's. Calling \`stopPropagation()\` in your editor prevents DropZone from ever seeing the event — that is how you bypass the \`dropEffect = "none"\` block and accept arbitrary files.
2409
-
2410
- #### Implementation recipe
2411
-
2412
- Attach all four drag handlers (\`onDragOver\`, \`onDragEnter\`, \`onDragLeave\`, \`onDrop\`) to your editor's **root \`div\`**. Always gate every handler on \`event.dataTransfer.types.includes("Files")\` so internal Connect drags (e.g. sidebar nodes carrying \`UI_NODE\`) bubble through to DropZone untouched — only intercept file drags.
2365
+ Connect wraps every editor in an outer DropZone that only handles Powerhouse document files (\`.phd\`, \`.phdm\`, \`.zip\`). To accept other files in your editor, use the \`useEditorFileDrop\` hook — it spreads the right handlers and a marker attribute that tells the outer DropZone to leave your subtree alone.
2413
2366
 
2414
2367
  ~~~tsx
2415
- import { useCallback, useRef, useState, type DragEvent } from "react";
2416
-
2417
- const ALLOWED_EXTENSIONS = [".png", ".jpg", ".jpeg", ".pdf"]; // adjust per editor
2418
-
2419
- function filterAcceptedFiles(fileList: FileList): File[] {
2420
- return Array.from(fileList).filter((file) => {
2421
- const lower = file.name.toLowerCase();
2422
- return ALLOWED_EXTENSIONS.some((ext) => lower.endsWith(ext));
2423
- });
2424
- }
2368
+ import { useEditorFileDrop } from "@powerhousedao/reactor-browser";
2425
2369
 
2426
2370
  export default function Editor() {
2427
- const [isDragOver, setIsDragOver] = useState(false);
2428
- const dragDepthRef = useRef(0);
2429
-
2430
- const onEditorDragOver = useCallback((e: DragEvent) => {
2431
- if (e.dataTransfer.types.includes("Files")) {
2432
- e.preventDefault(); // signals "drop is allowed here"
2433
- e.stopPropagation(); // blocks DropZone from setting dropEffect="none"
2434
- }
2435
- }, []);
2436
-
2437
- const onEditorDragEnter = useCallback((e: DragEvent) => {
2438
- if (e.dataTransfer.types.includes("Files")) {
2439
- e.stopPropagation();
2440
- dragDepthRef.current += 1;
2441
- if (dragDepthRef.current === 1) setIsDragOver(true);
2442
- }
2443
- }, []);
2444
-
2445
- const onEditorDragLeave = useCallback((e: DragEvent) => {
2446
- if (e.dataTransfer.types.includes("Files")) {
2447
- e.stopPropagation();
2448
- dragDepthRef.current = Math.max(0, dragDepthRef.current - 1);
2449
- if (dragDepthRef.current === 0) setIsDragOver(false);
2450
- }
2451
- }, []);
2452
-
2453
- const onEditorDrop = useCallback((e: DragEvent) => {
2454
- if (e.dataTransfer.types.includes("Files")) {
2455
- e.preventDefault(); // prevents the browser from opening the file
2456
- e.stopPropagation();
2457
- dragDepthRef.current = 0;
2458
- setIsDragOver(false);
2459
-
2460
- const accepted = filterAcceptedFiles(e.dataTransfer.files);
2461
- if (accepted.length === 0) return; // silently ignore rejected files
2462
- handleFiles(accepted);
2463
- }
2464
- }, []);
2371
+ const { dragProps, isDragOver } = useEditorFileDrop({
2372
+ accept: [".png", ".jpg", ".jpeg", ".pdf"],
2373
+ onFiles: (files) => handleFiles(files),
2374
+ });
2465
2375
 
2466
2376
  return (
2467
- <div
2468
- onDragOver={onEditorDragOver}
2469
- onDragEnter={onEditorDragEnter}
2470
- onDragLeave={onEditorDragLeave}
2471
- onDrop={onEditorDrop}
2472
- className="relative"
2473
- >
2377
+ <div {...dragProps} className="relative">
2474
2378
  {isDragOver && (
2475
2379
  <div className="pointer-events-none absolute inset-0 z-50 flex items-center justify-center bg-black/40">
2476
- <div className="border-primary/60 bg-background/90 flex flex-col items-center gap-3 rounded-2xl border-2 border-dashed px-10 py-8 shadow-lg">
2477
- <p className="text-foreground text-base font-medium">
2478
- Drop files to attach
2479
- </p>
2480
- </div>
2380
+ <p className="text-foreground text-base font-medium">
2381
+ Drop files to attach
2382
+ </p>
2481
2383
  </div>
2482
2384
  )}
2483
2385
  {/* ... editor content ... */}
@@ -2486,192 +2388,66 @@ export default function Editor() {
2486
2388
  }
2487
2389
  ~~~
2488
2390
 
2489
- #### Drag-depth counter (flicker-free overlay)
2490
-
2491
- \`dragenter\` and \`dragleave\` fire every time the cursor crosses **any** child boundary inside the editor. Without a depth counter the overlay flickers on/off as the cursor moves over nested elements. The required pattern:
2492
-
2493
- - \`dragenter\`: increment depth; show the overlay when depth goes \`0\` → \`1\`.
2494
- - \`dragleave\`: decrement depth; hide the overlay when depth returns to \`0\`.
2495
- - \`drop\`: reset depth to \`0\` and hide the overlay unconditionally.
2496
-
2497
- #### Drop overlay rules
2498
-
2499
- The overlay \`div\` **MUST** use \`pointer-events-none\`. Without it, the overlay element captures the \`drop\` event and your handler on the root \`div\` will never fire. Use theme tokens (\`bg-background\`, \`text-foreground\`, \`text-primary\`, etc.) so the overlay renders correctly in both light and dark mode.
2500
-
2501
- #### File-type validation
2502
-
2503
- Always validate dropped files at the editor level — do not assume the user dropped what you expect. The \`filterAcceptedFiles\` helper above filters by file-name extension (case-insensitive). For stricter validation, additionally check \`file.type\` (MIME type) before processing. Files that fail validation should be **silently ignored** or surfaced via a toast/notification — never throw on unexpected input, since drag-and-drop is a user-initiated action and exceptions will surface as uncaught render errors.
2504
-
2505
- #### Bridging file handlers in child component contexts
2506
-
2507
- If your file-upload handler lives inside a **child** component's React context (for example, \`usePromptInputAttachments().add\` inside a \`PromptInput\`), you cannot call it directly from the editor root. Use a ref bridge:
2508
-
2509
- ~~~tsx
2510
- // editor.tsx — expose a ref the child fills in:
2511
- const addFilesRef = useRef<((files: File[]) => void) | null>(null);
2512
-
2513
- // inside onEditorDrop, after filtering:
2514
- addFilesRef.current?.(accepted);
2515
-
2516
- // pass the ref down to the child:
2517
- <ChatInputBar addFilesRef={addFilesRef} />;
2518
- ~~~
2519
-
2520
- ~~~tsx
2521
- // ChatInputBar.tsx — bridge component mounted inside the consumer's context:
2522
- import type { MutableRefObject } from "react";
2523
- import { useEffect } from "react";
2524
-
2525
- function DropBridge({
2526
- addFilesRef,
2527
- }: {
2528
- addFilesRef?: MutableRefObject<((files: File[]) => void) | null>;
2529
- }) {
2530
- const { add } = usePromptInputAttachments();
2531
- useEffect(() => {
2532
- if (addFilesRef) addFilesRef.current = add;
2533
- return () => {
2534
- if (addFilesRef) addFilesRef.current = null;
2535
- };
2536
- }, [add, addFilesRef]);
2537
- return null;
2538
- }
2539
-
2540
- <PromptInput onSubmit={handleSubmit} multiple>
2541
- <DropBridge addFilesRef={addFilesRef} />
2542
- {/* ... */}
2543
- </PromptInput>;
2544
- ~~~
2545
-
2546
- #### Common pitfalls — DO NOT make these mistakes
2391
+ The overlay \`div\` **MUST** use \`pointer-events-none\` — otherwise it captures the \`drop\` event and your handler never fires.
2547
2392
 
2548
- 1. **Do NOT use \`globalDrop\` together with \`stopPropagation\`.** \`PromptInput\`'s \`globalDrop\` prop attaches drop handlers on \`document\`. \`stopPropagation()\` at the editor root prevents events from ever reaching \`document\`. The two are incompatible use the ref-bridge pattern instead.
2549
- 2. **Always \`preventDefault()\` on BOTH \`dragover\` AND \`drop\`.** Without \`preventDefault\` on \`dragover\`, the browser signals "drop not allowed" and the \`drop\` event will not fire at all. Without \`preventDefault\` on \`drop\`, the browser navigates away to open the dropped file.
2550
- 3. **Always gate handlers on \`e.dataTransfer.types.includes("Files")\`.** Connect uses non-file drag types internally (e.g. \`UI_NODE\` for sidebar items). Those drags must bubble through to DropZone untouched — only intercept file drags.
2551
- 4. **\`dragenter\` and \`dragleave\` do NOT need \`preventDefault\`.** \`stopPropagation()\` alone is enough on those two; only \`dragover\` and \`drop\` require \`preventDefault\`.
2552
- 5. **The overlay \`div\` MUST have \`pointer-events-none\`.** Otherwise the overlay swallows the \`drop\` event and your drop handler never fires.
2553
- 6. **Reset \`dragDepthRef.current = 0\` inside \`onDrop\`.** Otherwise a subsequent drag will start with stale depth and the overlay logic breaks.
2393
+ If your file-upload handler lives inside a **child** component's React context (e.g. \`usePromptInputAttachments().add\` inside a \`PromptInput\`), use a ref bridge: store the child's add function in a ref from a tiny bridge component, and call \`ref.current?.(files)\` from \`onFiles\`.
2554
2394
 
2555
2395
  ### Using shadcn / Vercel AI Elements in editors (optional)
2556
2396
 
2557
- Use this section **only** when your editor needs UI primitives that are not covered by \`@powerhousedao/design-system\` or \`@powerhousedao/document-engineering\` — typically chat-style UIs that consume Vercel's AI Elements (\`Conversation\`, \`Message\`, \`Reasoning\`, \`Tool\`, \`PromptInput\`, etc.). Default editors should prefer the design-system / document-engineering primitives and skip this entire section.
2558
-
2559
- #### Why manual setup is required
2560
-
2561
- \`shadcn init\` will fail with \`Error: We could not detect a supported framework\`. The project is a Powerhouse reactor package, not a Next.js / Vite app, so the shadcn CLI cannot run its init flow. Set up shadcn manually with the steps below.
2562
-
2563
- #### Step 1 install runtime dependencies
2564
-
2565
- ~~~bash
2566
- pnpm add class-variance-authority clsx tailwind-merge lucide-react tw-animate-css
2567
- ~~~
2568
-
2569
- #### Step 2 — create \`components.json\` at the project root
2570
-
2571
- Substitute \`<name>\` with your editor's name (e.g. \`chat-session-editor\`):
2572
-
2573
- ~~~json
2574
- {
2575
- "$schema": "https://ui.shadcn.com/schema.json",
2576
- "style": "new-york",
2577
- "rsc": false,
2578
- "tsx": true,
2579
- "tailwind": {
2580
- "config": "",
2581
- "css": "style.css",
2582
- "baseColor": "neutral",
2583
- "cssVariables": true
2584
- },
2585
- "aliases": {
2586
- "components": "@/editors/<name>/components",
2587
- "utils": "@/editors/<name>/lib/utils",
2588
- "ui": "@/editors/<name>/components/ui",
2589
- "lib": "@/editors/<name>/lib",
2590
- "hooks": "@/editors/<name>/hooks"
2591
- },
2592
- "iconLibrary": "lucide"
2593
- }
2594
- ~~~
2595
-
2596
- The \`@/*\` alias inside \`components.json\` is consumed by the shadcn / AI Elements CLIs at install time only — they generate \`@/...\` imports inside the components they produce. You will rewrite those imports to relative paths in Step 7. **Do NOT** add a corresponding \`@/*\` alias to \`tsconfig.json\` — see the "Editor code conventions" section above.
2597
-
2598
- #### Step 3 — create \`lib/utils.ts\` under your editor
2599
-
2600
- ~~~typescript
2601
- // editors/<name>/lib/utils.ts
2602
- import { clsx, type ClassValue } from "clsx";
2603
- import { twMerge } from "tailwind-merge";
2604
-
2605
- export function cn(...inputs: ClassValue[]) {
2606
- return twMerge(clsx(inputs));
2607
- }
2608
- ~~~
2609
-
2610
- #### Step 4 — extend \`style.css\` with the shadcn theme variables
2611
-
2612
- The boilerplate \`style.css\` already imports \`tailwindcss\`, \`@powerhousedao/design-system/theme.css\`, and \`@powerhousedao/connect/style.css\`. **Append** (do not replace) the shadcn additions:
2613
-
2614
- - \`@import "tw-animate-css";\` (after the existing \`@import "tailwindcss";\`)
2615
- - \`@custom-variant dark (&:is(.dark *));\`
2616
- - A \`@theme inline { ... }\` block mapping \`--color-*\` and \`--radius-*\` to the shadcn variables
2617
- - \`:root { ... }\` and \`.dark { ... }\` blocks with \`oklch(...)\` color values
2618
- - \`@layer base { * { @apply border-border outline-ring/50; } body { @apply bg-background text-foreground; } }\`
2619
-
2620
- ⚠️ **Theme conflict warning**: \`@powerhousedao/design-system/theme.css\` already declares its own theme tokens. Adding shadcn's color variables on top has not been verified for conflicts — after this step, render a Connect view and confirm both the editor and the rest of Connect still look correct in light and dark mode. If the design-system theme breaks, fall back to using \`@powerhousedao/design-system\` and \`@powerhousedao/document-engineering\` primitives instead of shadcn.
2621
-
2622
- #### Step 5 — install AI Elements (Vercel's CLI, NOT shadcn's)
2623
-
2624
- Vercel ships its own CLI for AI chat components — use it, **not** \`npx shadcn add\`:
2625
-
2626
- ~~~bash
2627
- npx ai-elements@latest add conversation message reasoning tool prompt-input code-block
2628
- ~~~
2629
-
2630
- **Verify each component name exists in the AI Elements registry before adding** — names that aren't in the registry will hard-error and abort the entire install. The registry list is at https://ai-sdk.dev/elements .
2631
-
2632
- The CLI auto-installs supporting deps: \`ai\` (the Vercel AI SDK, used for types like \`UIMessage\`, \`ToolUIPart\`), \`use-stick-to-bottom\` (auto-scroll for \`Conversation\`), \`streamdown\` plus its plugins (\`@streamdown/cjk\`, \`@streamdown/code\`, \`@streamdown/math\`, \`@streamdown/mermaid\`) for markdown rendering, and \`@radix-ui/react-use-controllable-state\` (for the \`Reasoning\` toggle). These are pulled into your \`package.json\` automatically.
2633
-
2634
- #### Step 6 — relocate AI Elements files into the editor directory
2635
-
2636
- The CLI puts AI Elements files at \`components/ai-elements/\` at the **project root**, not inside your editor. Move them:
2637
-
2638
- ~~~
2639
- components/ai-elements/ → editors/<name>/components/ai-elements/
2640
- ~~~
2641
-
2642
- After the move, the project-root \`components/\` directory should be empty and can be deleted. UI primitives installed under \`editors/<name>/components/ui/\` are already correctly placed.
2643
-
2644
- #### Step 7 — rewrite all \`@/...\` imports to relative paths with \`.js\` extensions
2645
-
2646
- The shadcn / AI Elements CLIs generate imports like:
2647
-
2648
- ~~~typescript
2649
- import { Button } from "@/editors/<name>/components/ui/button";
2650
- import { cn } from "@/editors/<name>/lib/utils";
2651
- ~~~
2397
+ Use this **only** when your editor needs UI primitives not covered by \`@powerhousedao/design-system\` or \`@powerhousedao/document-engineering\` — typically chat-style UIs built on Vercel AI Elements (\`Conversation\`, \`Message\`, \`Reasoning\`, \`Tool\`, \`PromptInput\`). Default editors should prefer the design-system / document-engineering primitives and skip this section.
2398
+
2399
+ \`shadcn init\` does not work here (it fails with "could not detect a supported framework"), so configure shadcn manually with the steps below. Substitute \`<name>\` with your editor's name throughout.
2400
+
2401
+ #### Setup steps
2402
+
2403
+ 1. **Install deps**: \`pnpm add class-variance-authority clsx tailwind-merge lucide-react tw-animate-css\`
2404
+
2405
+ 2. **Create \`components.json\`** at the project root. The \`@/*\` alias here is consumed by the shadcn / AI Elements CLIs at install time only — do **NOT** add a matching \`@/*\` alias to \`tsconfig.json\`:
2406
+
2407
+ ~~~json
2408
+ {
2409
+ "$schema": "https://ui.shadcn.com/schema.json",
2410
+ "style": "new-york",
2411
+ "rsc": false,
2412
+ "tsx": true,
2413
+ "tailwind": {
2414
+ "config": "",
2415
+ "css": "style.css",
2416
+ "baseColor": "neutral",
2417
+ "cssVariables": true
2418
+ },
2419
+ "aliases": {
2420
+ "components": "@/editors/<name>/components",
2421
+ "utils": "@/editors/<name>/lib/utils",
2422
+ "ui": "@/editors/<name>/components/ui",
2423
+ "lib": "@/editors/<name>/lib",
2424
+ "hooks": "@/editors/<name>/hooks"
2425
+ },
2426
+ "iconLibrary": "lucide"
2427
+ }
2428
+ ~~~
2652
2429
 
2653
- Both forms break under \`nodenext\`: \`@/*\` does not resolve (no \`baseUrl\`), and the missing \`.js\` extension fails compilation. Do a bulk find-and-replace across **every file generated in Steps 5–6**. From an \`ai-elements/\` file, rewrite:
2430
+ 3. **Create \`editors/<name>/lib/utils.ts\`** exporting the standard \`cn\` helper (\`twMerge(clsx(inputs))\`).
2654
2431
 
2655
- - \`@/editors/<name>/components/ui/button\` \`../ui/button.js\`
2656
- - \`@/editors/<name>/lib/utils\` → \`../../lib/utils.js\`
2432
+ 4. **Extend \`style.css\`** (append, do not replace): \`@import "tw-animate-css";\`, \`@custom-variant dark (&:is(.dark *));\`, a \`@theme inline { ... }\` block mapping \`--color-*\`/\`--radius-*\`, \`:root\` and \`.dark\` blocks with \`oklch(...)\` values, and a \`@layer base\` block. ⚠️ The design-system theme already declares its own tokens — verify both the editor and Connect still render correctly in light/dark mode after this step. If they break, fall back to design-system primitives.
2657
2433
 
2658
- From a \`ui/\` file, rewrite:
2434
+ 5. **Install AI Elements** using Vercel's CLI (not shadcn's). Verify each name exists at https://ai-sdk.dev/elements first — unknown names abort the install:
2659
2435
 
2660
- - \`@/editors/<name>/components/ui/button\` → \`./button.js\`
2661
- - \`@/editors/<name>/lib/utils\` \`../../lib/utils.js\`
2436
+ ~~~bash
2437
+ npx ai-elements@latest add conversation message reasoning tool prompt-input code-block
2438
+ ~~~
2662
2439
 
2663
- Also fix relative imports between AI Elements files that the CLI generated without extensions — e.g. \`./shimmer\` \`./shimmer.js\`, \`./code-block\` \`./code-block.js\`.
2440
+ The CLI auto-installs \`ai\`, \`use-stick-to-bottom\`, \`streamdown\` (+ \`@streamdown/{cjk,code,math,mermaid}\`), and \`@radix-ui/react-use-controllable-state\`.
2664
2441
 
2665
- #### Step 8 bridge document-model types to AI Elements types
2442
+ 6. **Move \`components/ai-elements/\`** from the project root into \`editors/<name>/components/ai-elements/\`, then delete the empty project-root \`components/\`. (Files under \`editors/<name>/components/ui/\` are already in the right place.)
2666
2443
 
2667
- AI Elements components use Vercel AI SDK types (\`UIMessage\`, \`ToolUIPart\`, \`DynamicToolUIPart\`). Your document model has its own types (\`Message\`, \`ContentPart\`, etc.).
2444
+ 7. **Rewrite \`@/...\` imports to relative paths with \`.js\` extensions** across every CLI-generated file — \`@/*\` does not resolve under \`nodenext\`, and extensionless relative imports fail too. From an \`ai-elements/\` file: \`@/editors/<name>/components/ui/button\` → \`../ui/button.js\`, \`@/editors/<name>/lib/utils\` → \`../../lib/utils.js\`. From a \`ui/\` file: \`./button.js\` and \`../../lib/utils.js\`. Also add \`.js\` to any extensionless sibling imports (e.g. \`./shimmer\` → \`./shimmer.js\`).
2668
2445
 
2669
- **Do NOT try to convert between them.** Instead, use the **low-level primitives** (which accept plain props — strings, ReactNode) and write thin wrapper components that bridge your document-model types to those primitives:
2446
+ #### Bridging document-model types to AI Elements
2670
2447
 
2671
- - Plain-prop primitives: \`Message\`, \`MessageContent\`, \`Conversation\`, \`ConversationContent\`, \`Reasoning\`, \`ReasoningTrigger\`, \`ReasoningContent\`, \`Tool\`, \`ToolHeader\`, \`ToolContent\`, \`ToolInput\`, \`ToolOutput\`, \`MessageResponse\`.
2672
- - For \`ToolHeader\`, use \`type="dynamic-tool"\` with explicit \`toolName\` and \`state\` props.
2448
+ AI Elements use Vercel AI SDK types (\`UIMessage\`, \`ToolUIPart\`, \`DynamicToolUIPart\`); your document model has its own. **Do not convert between them.** Use the plain-prop low-level primitives (\`Message\`, \`MessageContent\`, \`Conversation\`, \`ConversationContent\`, \`Reasoning\`, \`ReasoningTrigger\`, \`ReasoningContent\`, \`Tool\`, \`ToolHeader\`, \`ToolContent\`, \`ToolInput\`, \`ToolOutput\`, \`MessageResponse\`) and write thin wrapper components. For \`ToolHeader\`, pass \`type="dynamic-tool"\` with explicit \`toolName\` and \`state\`.
2673
2449
 
2674
- ##### Tool state mapping
2450
+ Tool-state mapping:
2675
2451
 
2676
2452
  | Document-model state | AI Elements \`ToolPart["state"]\` |
2677
2453
  | ---------------------------- | ------------------------------- |
@@ -2679,54 +2455,21 @@ AI Elements components use Vercel AI SDK types (\`UIMessage\`, \`ToolUIPart\`, \
2679
2455
  | Tool call with result | \`"output-available"\` |
2680
2456
  | Tool call with error result | \`"output-error"\` |
2681
2457
 
2682
- ##### Index-signature mismatch when bridging types
2458
+ If TypeScript complains that your concrete interface is missing an index signature when passed where \`Record<string, unknown> & { ... }\` is expected, add \`[key: string]: unknown;\` to the interface.
2683
2459
 
2684
- When passing a concrete document-model interface into a function or component typed as \`Record<string, unknown> & { id: string; type: ... }\`, TypeScript will complain:
2685
-
2686
- ~~~
2687
- Type 'MyInterface' is not assignable to type 'Record<string, unknown>'.
2688
- Index signature for type 'string' is missing in type 'MyInterface'.
2689
- ~~~
2690
-
2691
- **Fix**: add \`[key: string]: unknown;\` to the concrete interface so it satisfies the index signature.
2692
-
2693
- #### Recommended file structure
2460
+ #### Final file structure
2694
2461
 
2695
2462
  ~~~
2696
2463
  editors/<name>/
2697
2464
  editor.tsx ← main editor (edit codegen output)
2698
2465
  module.ts ← DO NOT EDIT (codegen)
2699
- lib/
2700
- utils.ts ← cn() helper
2466
+ lib/utils.ts ← cn() helper
2701
2467
  components/
2702
- ai-elements/ ← moved from project root in Step 6
2703
- conversation.tsx
2704
- message.tsx
2705
- reasoning.tsx
2706
- tool.tsx
2707
- code-block.tsx
2708
- prompt-input.tsx
2468
+ ai-elements/ ← moved from project root in step 6
2709
2469
  ui/ ← shadcn primitives installed by ai-elements CLI
2710
- button.tsx
2711
- badge.tsx
2712
- tooltip.tsx
2713
- ... etc
2714
- <wrapper components that bridge document-model types to AI Elements primitives>
2470
+ <wrappers bridging document-model types to AI Elements primitives>
2715
2471
  ~~~
2716
2472
 
2717
- #### Quick checklist for a shadcn-using editor
2718
-
2719
- 1. Create the editor document via MCP and confirm its status (see "Phase 1" above).
2720
- 2. Wait for codegen to produce the editor boilerplate.
2721
- 3. \`pnpm add class-variance-authority clsx tailwind-merge lucide-react tw-animate-css\`
2722
- 4. Create \`components.json\` and \`editors/<name>/lib/utils.ts\`.
2723
- 5. Extend \`style.css\` with the shadcn theme additions; verify the design-system theme still renders correctly.
2724
- 6. \`npx ai-elements@latest add <components>\` — verify component names against the registry first.
2725
- 7. Move \`components/ai-elements/\` into \`editors/<name>/components/ai-elements/\`.
2726
- 8. Bulk-rewrite every \`@/...\` import to a relative path with a \`.js\` extension; also add \`.js\` to extensionless relative imports.
2727
- 9. Use the top-level \`document-models/<name>\` barrel for all document-model imports (see "Editor code conventions" above).
2728
- 10. Run \`npm run tsc\` and \`npm run lint:fix\`.
2729
-
2730
2473
  ## ⚠️ CRITICAL: Generated Files & Modification Rules
2731
2474
 
2732
2475
  ### Generated Files Rule
@@ -4723,141 +4466,15 @@ const mcpTemplate = json`
4723
4466
  //#region src/templates/boilerplate/npmrc.ts
4724
4467
  const npmrcTemplate = `@jsr:registry=https://npm.jsr.io`;
4725
4468
  //#endregion
4726
- //#region src/file-builders/constants.ts
4727
- const packageJsonExports = {
4728
- ".": {
4729
- types: "./dist/types/index.d.ts",
4730
- browser: "./dist/browser/index.js",
4731
- node: "./dist/node/index.mjs"
4732
- },
4733
- "./document-models": {
4734
- types: "./dist/types/document-models/index.d.ts",
4735
- browser: "./dist/browser/document-models/index.js",
4736
- node: "./dist/node/document-models/index.mjs"
4737
- },
4738
- "./document-models/*": {
4739
- types: "./dist/types/document-models/*/index.d.ts",
4740
- browser: "./dist/browser/document-models/*/index.js",
4741
- node: "./dist/node/document-models/*/index.mjs"
4742
- },
4743
- "./editors": {
4744
- types: "./dist/types/editors/index.d.ts",
4745
- browser: "./dist/browser/editors/index.js",
4746
- node: "./dist/node/editors/index.mjs"
4747
- },
4748
- "./editors/*": {
4749
- types: "./dist/types/editors/*/editor.d.ts",
4750
- browser: "./dist/browser/editors/*/editor.js",
4751
- node: "./dist/node/editors/*/editor.mjs"
4752
- },
4753
- "./subgraphs": {
4754
- types: "./dist/types/subgraphs/index.d.ts",
4755
- browser: "./dist/browser/subgraphs/index.js",
4756
- node: "./dist/node/subgraphs/index.mjs"
4757
- },
4758
- "./processors": {
4759
- types: "./dist/types/processors/index.d.ts",
4760
- browser: "./dist/browser/processors/index.js",
4761
- node: "./dist/node/processors/index.mjs"
4762
- },
4763
- "./manifest": "./dist/powerhouse.manifest.json",
4764
- "./style.css": "./dist/style.css"
4765
- };
4766
- const packageScripts = {
4767
- "test:watch": "vitest",
4768
- lint: "eslint --config eslint.config.js --cache",
4769
- "lint:fix": "npm run lint -- --fix",
4770
- tsc: "tsc",
4771
- "tsc:watch": "tsc --watch",
4772
- generate: "ph-cli generate",
4773
- connect: "ph-cli connect",
4774
- build: "ph-cli build",
4775
- reactor: "ph-cli reactor",
4776
- service: "ph-cli service",
4777
- vetra: "ph-cli vetra",
4778
- "service-startup": "bash ./node_modules/@powerhousedao/ph-cli/dist/scripts/service-startup.sh",
4779
- "service-unstartup": "bash ./node_modules/@powerhousedao/ph-cli/dist/scripts/service-unstartup.sh"
4780
- };
4781
- const externalDependencies = {
4782
- "@powerhousedao/document-engineering": "1.40.3",
4783
- graphql: "16.12.0",
4784
- "graphql-tag": "^2.12.6",
4785
- zod: "4.3.6",
4786
- react: "^19.2.3",
4787
- "react-dom": "^19.2.3"
4788
- };
4789
- const externalDevDependencies = {
4790
- "@electric-sql/pglite": "0.3.15",
4791
- "@electric-sql/pglite-tools": "0.2.20",
4792
- "@eslint/js": "^9.38.0",
4793
- "@tailwindcss/cli": "^4.1.18",
4794
- "@types/node": "^24.9.2",
4795
- "@types/react": "^19.2.3",
4796
- "@vitest/coverage-v8": "4.1.1",
4797
- eslint: "^9.38.0",
4798
- "eslint-config-prettier": "^10.1.8",
4799
- "eslint-plugin-prettier": "^5.5.4",
4800
- "eslint-plugin-react": "^7.37.5",
4801
- "eslint-plugin-react-hooks": "^7.0.1",
4802
- globals: "^16.4.0",
4803
- tailwindcss: "^4.1.16",
4804
- typescript: "^5.9.3",
4805
- "typescript-eslint": "^8.46.2",
4806
- "vite-tsconfig-paths": "6.1.1",
4807
- vitest: "4.1.1"
4808
- };
4809
- const defaultManifest = {
4810
- name: "",
4811
- description: "",
4812
- category: "",
4813
- publisher: {
4814
- name: "",
4815
- url: ""
4816
- },
4817
- documentModels: [],
4818
- editors: [],
4819
- apps: [],
4820
- subgraphs: [],
4821
- processors: []
4822
- };
4823
- //#endregion
4824
4469
  //#region src/templates/boilerplate/package.json.ts
4825
- /**
4826
- * Renders a JS object as the inner body of a JSON object
4827
- */
4828
4470
  function innerJsonBody(value) {
4829
4471
  return JSON.stringify(value, null, 2).slice(2, -2).trimEnd();
4830
4472
  }
4473
+ function sortedJsonBody(value) {
4474
+ return innerJsonBody(Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b))));
4475
+ }
4831
4476
  const exportsTemplate = innerJsonBody(packageJsonExports);
4832
- const externalDepsTemplate = innerJsonBody(externalDependencies);
4833
- const externalDevDepsTemplate = innerJsonBody(externalDevDependencies);
4834
- const scriptsTemplate = json`
4835
- "test": "vitest run",
4836
- "test:watch": "vitest",
4837
- "test:coverage": "vitest run --coverage",
4838
- "lint": "eslint --config eslint.config.js --cache --cache-strategy content",
4839
- "lint:fix": "npm run lint -- --fix",
4840
- "tsc": "tsc",
4841
- "tsc:watch": "tsc --watch",
4842
- "check-circular-imports": "npx dpdm -T ./index.ts",
4843
- "generate": "ph-cli generate",
4844
- "connect": "ph-cli connect",
4845
- "build": "ph-cli build",
4846
- "reactor": "ph-cli reactor",
4847
- "service": "ph-cli service",
4848
- "vetra": "ph-cli vetra",
4849
- "service-startup": "bash ./node_modules/@powerhousedao/ph-cli/dist/scripts/service-startup.sh",
4850
- "service-unstartup": "bash ./node_modules/@powerhousedao/ph-cli/dist/scripts/service-unstartup.sh"
4851
- `.raw;
4852
- const dependenciesTemplate = (versionedDependencies) => json`
4853
- ${versionedDependencies.join(",\n ")},
4854
- ${externalDepsTemplate}
4855
- `.raw;
4856
- const devDependenciesTemplate = (versionedDevDependencies) => json`
4857
- ${versionedDevDependencies.join(",\n ")},
4858
- ${externalDevDepsTemplate}
4859
- `.raw;
4860
- const packageJsonTemplate = (projectName, versionedDependencies, versionedDevDependencies) => json`
4477
+ const packageJsonTemplate = (projectName, peerDependencies, devDependencies) => json`
4861
4478
  {
4862
4479
  "name": "${projectName}",
4863
4480
  "version": "1.0.0",
@@ -4871,24 +4488,32 @@ const packageJsonTemplate = (projectName, versionedDependencies, versionedDevDep
4871
4488
  ${exportsTemplate}
4872
4489
  },
4873
4490
  "scripts": {
4874
- ${scriptsTemplate}
4491
+ "test": "vitest run",
4492
+ "test:watch": "vitest",
4493
+ "test:coverage": "vitest run --coverage",
4494
+ "lint": "eslint --config eslint.config.js --cache --cache-strategy content",
4495
+ "lint:fix": "npm run lint -- --fix",
4496
+ "tsc": "tsc",
4497
+ "tsc:watch": "tsc --watch",
4498
+ "check-circular-imports": "npx dpdm -T ./index.ts",
4499
+ "generate": "ph-cli generate",
4500
+ "connect": "ph-cli connect",
4501
+ "build": "ph-cli build",
4502
+ "reactor": "ph-cli reactor",
4503
+ "service": "ph-cli service",
4504
+ "vetra": "ph-cli vetra",
4505
+ "service-startup": "bash ./node_modules/@powerhousedao/ph-cli/dist/scripts/service-startup.sh",
4506
+ "service-unstartup": "bash ./node_modules/@powerhousedao/ph-cli/dist/scripts/service-unstartup.sh"
4875
4507
  },
4876
- "dependencies": {
4877
- ${dependenciesTemplate(versionedDependencies)}
4508
+ "peerDependencies": {
4509
+ ${sortedJsonBody(peerDependencies)}
4878
4510
  },
4879
4511
  "devDependencies": {
4880
- ${devDependenciesTemplate(versionedDevDependencies)}
4512
+ ${sortedJsonBody(devDependencies)}
4881
4513
  }
4882
4514
  }
4883
4515
  `.raw;
4884
- //#endregion
4885
- //#region src/templates/boilerplate/pnpm-workspace.ts
4886
- const pnpmWorkspaceTemplate = `allowBuilds:
4887
- "@apollo/protobufjs": true
4888
- "@parcel/watcher": true
4889
- esbuild: true
4890
- protobufjs: true
4891
- `;
4516
+ const pnpmWorkspaceTemplate = `allowBuilds:\n${BOILERPLATE_ALLOWED_BUILDS.map((pkg) => ` ${/[@/]/.test(pkg) ? `"${pkg}"` : pkg}: true`).join("\n")}\n`;
4892
4517
  //#endregion
4893
4518
  //#region src/templates/boilerplate/package.json.legacy.ts
4894
4519
  const packageJsonScriptsTemplate = {
@@ -5444,7 +5069,9 @@ export default function Editor() {
5444
5069
  `.raw;
5445
5070
  //#endregion
5446
5071
  //#region src/templates/document-editor/module.ts
5447
- const documentEditorModuleFileTemplate = (v) => tsx`
5072
+ const documentEditorModuleFileTemplate = (v) => {
5073
+ const documentTypesLiteral = JSON.stringify(v.documentTypes);
5074
+ return tsx`
5448
5075
  /**
5449
5076
  * WARNING: DO NOT EDIT
5450
5077
  * This file is auto-generated and updated by codegen
@@ -5452,16 +5079,17 @@ const documentEditorModuleFileTemplate = (v) => tsx`
5452
5079
  import type { EditorModule } from "document-model";
5453
5080
  import { lazy } from "react";
5454
5081
 
5455
- /** Document editor module for the "${v.documentTypes}" document type */
5082
+ /** ${v.documentTypes.length === 1 ? `Document editor module for the "${v.documentTypes[0]}" document type` : `Document editor module for document types: ${v.documentTypes.map((t) => `"${t}"`).join(", ")}`} */
5456
5083
  export const ${v.pascalCaseEditorName}: EditorModule = {
5457
5084
  Component: lazy(() => import("./editor.js")),
5458
- documentTypes: ${v.documentTypes},
5085
+ documentTypes: ${documentTypesLiteral},
5459
5086
  config: {
5460
5087
  id: "${v.editorId}",
5461
5088
  name: "${v.editorName}",
5462
5089
  },
5463
5090
  };
5464
5091
  `.raw;
5092
+ };
5465
5093
  //#endregion
5466
5094
  //#region src/templates/document-model/actions.ts
5467
5095
  function buildModuleActionsName(module, camelCaseDocumentType) {
@@ -6692,7 +6320,7 @@ export * from "./processor.js";
6692
6320
  //#endregion
6693
6321
  //#region src/templates/processors/analytics/processor.ts
6694
6322
  const analyticsProcessorTemplate = (v) => ts$1`
6695
- import type { AnalyticsSeriesInput, AnalyticsPath, IAnalyticsStore } from "@powerhousedao/analytics-engine-core";
6323
+ import type { AnalyticsSeriesInput, AnalyticsPath, IAnalyticsStore } from "${ANALYTICS_ENGINE_CORE_PACKAGE}";
6696
6324
  import type { OperationWithContext, IProcessor } from "@powerhousedao/reactor-browser";
6697
6325
 
6698
6326
  export class ${v.pascalCaseName} implements IProcessor {
@@ -6896,8 +6524,8 @@ export interface DB {
6896
6524
  //#endregion
6897
6525
  //#region src/templates/subgraphs/index-file.ts
6898
6526
  const subgraphIndexFileTemplate = (v) => ts$1`
6899
- import { BaseSubgraph } from "@powerhousedao/reactor-api";
6900
- import type { DocumentNode } from "graphql";
6527
+ import { BaseSubgraph } from "${REACTOR_API_PACKAGE}";
6528
+ import type { DocumentNode } from "${GRAPHQL_PACKAGE}";
6901
6529
  import { schema } from "./schema.js";
6902
6530
  import { getResolvers } from "./resolvers.js";
6903
6531
 
@@ -6921,8 +6549,8 @@ const subgraphLibFileTemplate = () => ts$1`
6921
6549
  //#endregion
6922
6550
  //#region src/templates/subgraphs/custom-schema.ts
6923
6551
  const customSubgraphSchemaTemplate = (v) => ts$1`
6924
- import { gql } from "graphql-tag";
6925
- import type { DocumentNode } from "graphql";
6552
+ import { gql } from "${GRAPHQL_TAG_PACKAGE}";
6553
+ import type { DocumentNode } from "${GRAPHQL_PACKAGE}";
6926
6554
 
6927
6555
  export const schema: DocumentNode = gql\`
6928
6556
  """
@@ -6941,7 +6569,7 @@ type Query {
6941
6569
  //#endregion
6942
6570
  //#region src/templates/subgraphs/custom-resolvers.ts
6943
6571
  const customSubgraphResolversTemplate = (v) => ts$1`
6944
- import { type ISubgraph } from "@powerhousedao/reactor-api";
6572
+ import { type ISubgraph } from "${REACTOR_API_PACKAGE}";
6945
6573
 
6946
6574
  export const getResolvers = (subgraph: ISubgraph): Record<string, unknown> => {
6947
6575
  const reactor = subgraph.reactorClient;
@@ -7285,6 +6913,16 @@ function handleEmptyState(state) {
7285
6913
  return state === "" ? "{}" : state;
7286
6914
  }
7287
6915
  //#endregion
6916
+ //#region src/utils/update-versioned-imports.ts
6917
+ function updateVersionedImports(args) {
6918
+ const { sourceFile, version } = args;
6919
+ const previousVersion = subtract(version, 1);
6920
+ if (previousVersion < 1) return;
6921
+ const versionDir = `/v${version}`;
6922
+ const previousVersionDir = `/v${previousVersion}`;
6923
+ pipe(sourceFile.getImportDeclarations(), filter((i) => endsWith(i.getModuleSpecifier().getLiteralValue(), previousVersionDir)), forEach((i) => i.setModuleSpecifier(i.getModuleSpecifier().getLiteralValue().replace(previousVersionDir, versionDir))));
6924
+ }
6925
+ //#endregion
7288
6926
  //#region src/utils/validation.ts
7289
6927
  /**
7290
6928
  * Validates that a DocumentModelGlobalState has all required properties for successful code generation.
@@ -7360,7 +6998,7 @@ function validateDocumentModelState(documentModelState) {
7360
6998
  //#endregion
7361
6999
  //#region src/file-builders/editor-common.ts
7362
7000
  /** Generates the `module.ts` file for a document editor or app */
7363
- function makeEditorModuleFile({ project, editorDirPath, editorName, documentModelId, editorId, legacyMultipleDocumentTypes }) {
7001
+ async function makeEditorModuleFile({ project, editorDirPath, editorName, documentModelId, editorId, legacyMultipleDocumentTypes }) {
7364
7002
  if (documentModelId && !!legacyMultipleDocumentTypes) throw new Error("Cannot specify both documentModelId and legacyMultipleDocumentTypes");
7365
7003
  const { sourceFile } = getOrCreateSourceFile(project, path.join(editorDirPath, "module.ts"));
7366
7004
  sourceFile.replaceWithText("");
@@ -7368,9 +7006,10 @@ function makeEditorModuleFile({ project, editorDirPath, editorName, documentMode
7368
7006
  editorName,
7369
7007
  editorId,
7370
7008
  pascalCaseEditorName: pascalCase(editorName),
7371
- documentTypes: documentModelId ? `["${documentModelId}"]` : JSON.stringify(legacyMultipleDocumentTypes)
7009
+ documentTypes: documentModelId ? [documentModelId] : legacyMultipleDocumentTypes ?? []
7372
7010
  });
7373
7011
  sourceFile.replaceWithText(template);
7012
+ await formatSourceFileWithPrettier(sourceFile);
7374
7013
  }
7375
7014
  async function makeEditorsFile(args) {
7376
7015
  const { project, editorsDirPath } = args;
@@ -7420,56 +7059,58 @@ async function tsMorphGenerateApp({ project, editorDir, editorName, editorId, al
7420
7059
  const editorDirPath = path.join(editorsDirPath, editorDir);
7421
7060
  const projectDir = editorsDir.getParentOrThrow().getPath();
7422
7061
  const editorComponentsDirPath = path.join(editorDirPath, "components");
7423
- await ensureDirectoriesExist(project, documentModelsDirPath, editorsDirPath, editorDirPath, editorComponentsDirPath);
7424
- await makeNavigationBreadcrumbsFile({
7425
- project,
7426
- editorComponentsDirPath
7427
- });
7428
- await makeCreateDocumentFile({
7429
- project,
7430
- editorComponentsDirPath
7431
- });
7432
- await makeEmptyStateFile({
7433
- project,
7434
- editorComponentsDirPath
7435
- });
7436
- await makeFoldersFile({
7437
- project,
7438
- editorComponentsDirPath
7439
- });
7440
- await makeFolderTreeFile({
7441
- project,
7442
- editorComponentsDirPath
7443
- });
7444
- await makeFilesFile({
7445
- project,
7446
- editorComponentsDirPath
7447
- });
7448
- await makeDriveExplorerFile({
7449
- project,
7450
- editorComponentsDirPath
7451
- });
7452
- await makeDriveContentsFile({
7453
- project,
7454
- editorComponentsDirPath
7455
- });
7456
- await makeAppComponent({
7062
+ await ensureDirectoriesExist(project, documentModelsDirPath, editorsDirPath, editorDirPath);
7063
+ if (!await makeAppComponent({
7457
7064
  project,
7458
7065
  editorDirPath
7459
- });
7460
- await makeAppConfigFile({
7461
- project,
7462
- allowedDocumentModelIds,
7463
- isDragAndDropEnabled,
7464
- editorDirPath
7465
- });
7466
- makeEditorModuleFile({
7467
- project,
7468
- editorName,
7469
- editorId,
7470
- editorDirPath,
7471
- documentModelId: "powerhouse/document-drive"
7472
- });
7066
+ })) {
7067
+ await ensureDirectoriesExist(project, editorComponentsDirPath);
7068
+ await makeNavigationBreadcrumbsFile({
7069
+ project,
7070
+ editorComponentsDirPath
7071
+ });
7072
+ await makeCreateDocumentFile({
7073
+ project,
7074
+ editorComponentsDirPath
7075
+ });
7076
+ await makeEmptyStateFile({
7077
+ project,
7078
+ editorComponentsDirPath
7079
+ });
7080
+ await makeFoldersFile({
7081
+ project,
7082
+ editorComponentsDirPath
7083
+ });
7084
+ await makeFolderTreeFile({
7085
+ project,
7086
+ editorComponentsDirPath
7087
+ });
7088
+ await makeFilesFile({
7089
+ project,
7090
+ editorComponentsDirPath
7091
+ });
7092
+ await makeDriveExplorerFile({
7093
+ project,
7094
+ editorComponentsDirPath
7095
+ });
7096
+ await makeDriveContentsFile({
7097
+ project,
7098
+ editorComponentsDirPath
7099
+ });
7100
+ await makeAppConfigFile({
7101
+ project,
7102
+ allowedDocumentModelIds,
7103
+ isDragAndDropEnabled,
7104
+ editorDirPath
7105
+ });
7106
+ await makeEditorModuleFile({
7107
+ project,
7108
+ editorName,
7109
+ editorId,
7110
+ editorDirPath,
7111
+ documentModelId: "powerhouse/document-drive"
7112
+ });
7113
+ }
7473
7114
  await makeEditorsFile({
7474
7115
  project,
7475
7116
  editorsDirPath
@@ -7481,7 +7122,7 @@ async function tsMorphGenerateApp({ project, editorDir, editorName, editorId, al
7481
7122
  await createOrUpdateManifest({ apps: [{
7482
7123
  name: editorName,
7483
7124
  id: editorId,
7484
- documentTypes: ["powerhousedao/document-drive"]
7125
+ documentTypes: ["powerhouse/document-drive"]
7485
7126
  }] }, projectDir);
7486
7127
  }
7487
7128
  async function makeAppComponent({ project, editorDirPath }) {
@@ -7490,12 +7131,13 @@ async function makeAppComponent({ project, editorDirPath }) {
7490
7131
  const editorFunction = sourceFile.getFunction("Editor");
7491
7132
  if (editorFunction) {
7492
7133
  if (!editorFunction.isDefaultExport()) editorFunction.setIsDefaultExport(true);
7493
- return;
7134
+ return true;
7494
7135
  }
7495
7136
  }
7496
7137
  const template = appEditorFileTemplate();
7497
7138
  sourceFile.replaceWithText(template);
7498
7139
  await formatSourceFileWithPrettier(sourceFile);
7140
+ return false;
7499
7141
  }
7500
7142
  async function makeAppConfigFile({ project, editorDirPath, allowedDocumentModelIds, isDragAndDropEnabled }) {
7501
7143
  const { sourceFile } = getOrCreateSourceFile(project, path.join(editorDirPath, "config.ts"));
@@ -7595,12 +7237,12 @@ async function writeModuleFiles(projectDir = process.cwd()) {
7595
7237
  await writeGeneratedSubgraphsFiles(projectDir);
7596
7238
  }
7597
7239
  async function writeAiConfigFiles(projectDir = process.cwd()) {
7598
- await writeFileEnsuringDir(join(projectDir, "CLAUDE.md"), agentsTemplate);
7599
- await writeFileEnsuringDir(join(projectDir, "AGENTS.md"), agentsTemplate);
7600
- await writeFileEnsuringDir(join(projectDir, ".mcp.json"), mcpTemplate);
7601
- await writeFileEnsuringDir(join(projectDir, ".gemini/settings.json"), geminiSettingsTemplate);
7602
- await writeFileEnsuringDir(join(projectDir, ".cursor/mcp.json"), cursorMcpTemplate);
7603
- await writeFileEnsuringDir(join(projectDir, ".claude/settings.local.json"), claudeSettingsLocalTemplate);
7240
+ await writeFileEnsuringDir(join(projectDir, "CLAUDE.md"), agentsTemplate.trimStart());
7241
+ await writeFileEnsuringDir(join(projectDir, "AGENTS.md"), agentsTemplate.trimStart());
7242
+ await writeFileEnsuringDir(join(projectDir, ".mcp.json"), mcpTemplate.trimStart());
7243
+ await writeFileEnsuringDir(join(projectDir, ".gemini/settings.json"), geminiSettingsTemplate.trimStart());
7244
+ await writeFileEnsuringDir(join(projectDir, ".cursor/mcp.json"), cursorMcpTemplate.trimStart());
7245
+ await writeFileEnsuringDir(join(projectDir, ".claude/settings.local.json"), claudeSettingsLocalTemplate.trimStart());
7604
7246
  }
7605
7247
  async function writeProjectRootFiles(args, projectDir = process.cwd()) {
7606
7248
  const { name, tag, version, remoteDrive, packageManager } = args;
@@ -7637,16 +7279,26 @@ async function writeAllGeneratedProjectFiles(projectDir = process.cwd()) {
7637
7279
  //#endregion
7638
7280
  //#region src/file-builders/boilerplate/package.json.ts
7639
7281
  async function buildBoilerplatePackageJson(args) {
7640
- const { name, tag, version, workspace } = args;
7641
- return packageJsonTemplate(name, await makeVersionedDependencies({
7642
- names: VERSIONED_DEPENDENCIES,
7282
+ const { name, tag, version } = args;
7283
+ const workspacePeers = await makeVersionedDependenciesMap({
7284
+ names: VERSIONED_PEER_DEPENDENCIES,
7643
7285
  tag,
7644
7286
  version
7645
- }), await makeVersionedDependencies({
7287
+ });
7288
+ const workspaceDevs = await makeVersionedDependenciesMap({
7646
7289
  names: VERSIONED_DEV_DEPENDENCIES,
7647
7290
  tag,
7648
7291
  version
7649
- }));
7292
+ });
7293
+ return packageJsonTemplate(name, {
7294
+ ...workspacePeers,
7295
+ ...mapValues(PEER_EXTERNAL_DEPENDENCIES, (v) => v.peer)
7296
+ }, {
7297
+ ...workspaceDevs,
7298
+ ...workspacePeers,
7299
+ ...mapValues(PEER_EXTERNAL_DEPENDENCIES, (v) => v.dev),
7300
+ ...externalDevDependencies
7301
+ });
7650
7302
  }
7651
7303
  //#endregion
7652
7304
  //#region src/file-builders/clis/generate-cli-docs.ts
@@ -7695,7 +7347,7 @@ async function tsMorphGenerateDocumentEditor({ project, editorDir, editorName, e
7695
7347
  ...documentTypeMetadata,
7696
7348
  ...editorVariableNames
7697
7349
  });
7698
- makeEditorModuleFile({
7350
+ await makeEditorModuleFile({
7699
7351
  project,
7700
7352
  editorName,
7701
7353
  editorId,
@@ -8141,8 +7793,13 @@ async function makeOperationModuleTestFile(args) {
8141
7793
  version,
8142
7794
  filePath
8143
7795
  });
8144
- if (previousVersionSourceFile) sourceFile.replaceWithText(previousVersionSourceFile.getText());
8145
- else sourceFile.replaceWithText(ts$1`
7796
+ if (previousVersionSourceFile) {
7797
+ sourceFile.replaceWithText(previousVersionSourceFile.getText());
7798
+ updateVersionedImports({
7799
+ sourceFile,
7800
+ version
7801
+ });
7802
+ } else sourceFile.replaceWithText(ts$1`
8146
7803
  import { generateMock } from "document-model";
8147
7804
  import { describe, expect, it } from "vitest";
8148
7805
 
@@ -8153,8 +7810,8 @@ async function makeOperationModuleTestFile(args) {
8153
7810
  }
8154
7811
  const importNames = makeOperationImportNames(args);
8155
7812
  const namedImports = importNames.map((name) => ({ name }));
8156
- let actionsImportDeclaration = sourceFile.getImportDeclarations().filter((i) => !i.isTypeOnly()).find((importDeclaration) => importDeclaration.getModuleSpecifier().getText().includes(versionImportPath));
8157
- if (!actionsImportDeclaration) actionsImportDeclaration = sourceFile.addImportDeclaration({
7813
+ const actionsImportDeclaration = sourceFile.getImportDeclarations().filter((i) => !i.isTypeOnly()).find((importDeclaration) => importDeclaration.getModuleSpecifier().getText().includes(versionImportPath));
7814
+ if (!actionsImportDeclaration) sourceFile.addImportDeclaration({
8158
7815
  namedImports,
8159
7816
  moduleSpecifier: versionImportPath
8160
7817
  });
@@ -8190,7 +7847,7 @@ async function makeOperationModuleTestFile(args) {
8190
7847
  }), map((o) => makeTestCaseForOperation(o, isPhDocumentOfTypeFunctionName)));
8191
7848
  describeCallBody.addStatements(testCasesToAdd);
8192
7849
  const GENERATE_MOCK_NAME = "generateMock";
8193
- const GENERATE_MOCK_MODULE_SPECIFIER = "@powerhousedao/codegen";
7850
+ const GENERATE_MOCK_MODULE_SPECIFIER = "document-model";
8194
7851
  const generateMockImport = sourceFile.getImportDeclaration((i) => i.getNamedImports().some((v) => v.getText().includes(GENERATE_MOCK_NAME)));
8195
7852
  if (sourceFile.getText().includes(GENERATE_MOCK_NAME) && !generateMockImport) sourceFile.addImportDeclaration({
8196
7853
  namedImports: [GENERATE_MOCK_NAME],
@@ -8200,10 +7857,16 @@ async function makeOperationModuleTestFile(args) {
8200
7857
  await formatSourceFileWithPrettier(sourceFile);
8201
7858
  }
8202
7859
  async function makeDocumentModelTestFile(args) {
8203
- const { project, testsDirPath } = args;
7860
+ const { project, version, testsDirPath } = args;
8204
7861
  const template = documentModelTestFileTemplate(args);
8205
7862
  const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(testsDirPath, "document-model.test.ts"));
8206
- if (alreadyExists) return;
7863
+ if (alreadyExists) {
7864
+ updateVersionedImports({
7865
+ sourceFile,
7866
+ version
7867
+ });
7868
+ return;
7869
+ }
8207
7870
  sourceFile.replaceWithText(template);
8208
7871
  await formatSourceFileWithPrettier(sourceFile);
8209
7872
  }
@@ -8567,7 +8230,7 @@ function makeModulesIndexFile({ project, modulesDirPath, modules }) {
8567
8230
  //#endregion
8568
8231
  //#region src/file-builders/manifest.ts
8569
8232
  async function getOrCreateManifestFile(manifestPath) {
8570
- if (!await fileExists(manifestPath)) await writeJsonFile(manifestPath, defaultManifest);
8233
+ if (!await fileExists(manifestPath)) await writeJsonFile(manifestPath, defaultManifest, { indent: 2 });
8571
8234
  const manifestFile = await loadJsonFile(manifestPath);
8572
8235
  return ManifestSchema.parse(manifestFile);
8573
8236
  }
@@ -8577,6 +8240,26 @@ function makeUpdatedModulesList(oldModules = [], newModules = []) {
8577
8240
  function makeUpdatedConfig(oldConfig = [], newConfig = []) {
8578
8241
  return pipe(oldConfig, filter(({ name }) => !isIncludedIn(name, map(newConfig, prop("name")))), concat(newConfig), uniqueBy(prop("name")));
8579
8242
  }
8243
+ /**
8244
+ * Removes entries from a manifest module list whose id is not in `validIds`.
8245
+ * Used by `generateAll<X>` to prune entries that no longer correspond to any
8246
+ * directory in the project (e.g. a module that was renamed or deleted). No-op
8247
+ * if the manifest file doesn't exist yet.
8248
+ */
8249
+ async function pruneManifestSection(projectDir, kind, validIds) {
8250
+ const manifestPath = join(projectDir, "powerhouse.manifest.json");
8251
+ if (!await fileExists(manifestPath)) return;
8252
+ const manifest = await getOrCreateManifestFile(manifestPath);
8253
+ const existing = manifest[kind];
8254
+ if (existing === void 0) return;
8255
+ const validSet = new Set(validIds);
8256
+ const filtered = existing.filter((entry) => validSet.has(entry.id));
8257
+ if (filtered.length === existing.length) return;
8258
+ await writeJsonFile(manifestPath, {
8259
+ ...manifest,
8260
+ [kind]: filtered
8261
+ }, { indent: 2 });
8262
+ }
8580
8263
  async function createOrUpdateManifest(manifestData, projectDir) {
8581
8264
  const manifestPath = join(projectDir, "powerhouse.manifest.json");
8582
8265
  const existingManifest = await getOrCreateManifestFile(manifestPath);
@@ -8591,7 +8274,7 @@ async function createOrUpdateManifest(manifestData, projectDir) {
8591
8274
  subgraphs: makeUpdatedModulesList(existingManifest.subgraphs, manifestData.subgraphs),
8592
8275
  config: makeUpdatedConfig(existingManifest.config, manifestData.config)
8593
8276
  };
8594
- await writeJsonFile(manifestPath, updatedManifest);
8277
+ await writeJsonFile(manifestPath, updatedManifest, { indent: 2 });
8595
8278
  return updatedManifest;
8596
8279
  }
8597
8280
  //#endregion
@@ -8704,6 +8387,19 @@ async function makeMigrationsFile(v) {
8704
8387
  }
8705
8388
  //#endregion
8706
8389
  //#region src/file-builders/processors/processor.ts
8390
+ /**
8391
+ * Detects a hand-customized processor directory using a layout that predates
8392
+ * the current scaffold (class defined in index.ts, no processor.ts). When
8393
+ * present we leave the directory and surrounding wiring (factory-builders
8394
+ * file, manifest) untouched — the user owns it.
8395
+ */
8396
+ function isCustomizedProcessorDir(processorDir) {
8397
+ if (!processorDir) return false;
8398
+ if (processorDir.getSourceFile("processor.ts")) return false;
8399
+ const indexFile = processorDir.getSourceFile("index.ts");
8400
+ if (!indexFile) return false;
8401
+ return indexFile.getClasses().some((c) => c.isExported());
8402
+ }
8707
8403
  async function tsMorphGenerateProcessor(args) {
8708
8404
  const { project, processorName, documentTypes, processorType, processorApps } = args;
8709
8405
  const kebabCaseName = kebabCase(processorName);
@@ -8714,6 +8410,11 @@ async function tsMorphGenerateProcessor(args) {
8714
8410
  const processorsDirPath = processorsDir.getPath();
8715
8411
  const dirPath = path.join(processorsDirPath, kebabCaseName);
8716
8412
  await ensureDirectoriesExist(project, processorsDirPath, dirPath);
8413
+ if (isCustomizedProcessorDir(project.getDirectory(dirPath))) {
8414
+ const relativePath = path.relative(projectDir, path.join(dirPath, "index.ts"));
8415
+ console.warn(`[codegen] Skipping processor scaffold for "${kebabCaseName}": legacy layout detected "${relativePath}"`);
8416
+ return;
8417
+ }
8717
8418
  if (processorType === "analytics") await tsMorphGenerateAnalyticsProcessor({
8718
8419
  processorName,
8719
8420
  documentTypes,
@@ -8836,6 +8537,6 @@ async function makeSubgraphsIndexFile(args) {
8836
8537
  await formatSourceFileWithPrettier(sourceFile);
8837
8538
  }
8838
8539
  //#endregion
8839
- export { getOrCreateDirectory as $, nginxConfTemplate as $n, getDocumentModelSpecByVersionNumber as $t, writeProjectRootFiles as A, packageJsonTemplate as An, upgradeTransitionTemplate as At, getAllImportModuleSpecifiers as B, indexTsTemplate as Bn, documentModelIndexTemplate as Bt, writeCIFiles as C, readmeTemplate as Cn, processorsIndexTemplate as Ct, writeGeneratedProjectRootFiles as D, packageJsonScriptsTemplate as Dn, analyticsIndexTemplate as Dt, writeGeneratedProcessorsFiles as E, packageJsonExportsTemplate as En, analyticsProcessorTemplate as Et, validateDocumentModelState as F, packageScripts as Fn, makeTestCaseForOperation as Ft, getProperyAssignmentByName as G, geminiSettingsTemplate as Gn, documentModelGenReducerFileTemplate as Gt, getBooleanPropertyValue as H, indexHtmlTemplate as Hn, documentModelGenUtilsTemplate as Ht, getInitialStates as I, npmrcTemplate as In, documentModelTestFileTemplate as It, getVariableDeclarationByTypeName as J, editorsTemplate as Jn, documentModelOperationsModuleErrorFileTemplate as Jt, getStringArrayPropertyElements as K, eslintConfigTemplate as Kn, documentModelPhFactoriesFileTemplate as Kt, DEFAULT_PROJECT_OPTIONS as L, mcpTemplate as Ln, documentModelSrcUtilsTemplate as Lt, makeEditorModuleFile as M, externalDependencies as Mn, documentModelOperationsModuleTestFileTemplate as Mt, makeEditorsFile as N, externalDevDependencies as Nn, makeOperationImportNames as Nt, writeGeneratedSubgraphsFiles as O, pnpmWorkspaceTemplate as On, analyticsFactoryTemplate as Ot, makeEditorsIndexFile as P, packageJsonExports as Pn, makeOperationsImports as Pt, ensureDirectoriesExist as Q, switchboardEntrypointTemplate as Qn, getDocumentModelDirName as Qt, buildTsMorphProject as R, mainTsxTemplate as Rn, documentModelSrcIndexFileTemplate as Rt, writeAllGeneratedProjectFiles as S, styleTemplate as Sn, relationalDbFactoryTemplate as St, writeGeneratedEditorsFiles as T, buildPowerhouseConfigTemplate as Tn, factoryBuildersTemplate as Tt, getObjectLiteral as U, gitIgnoreTemplate as Un, documentModelGenTypesTemplate as Ut, getAllImportNames as V, legacyIndexHtmlTemplate as Vn, documentModelHooksFileTemplate as Vt, getObjectProperty as W, syncAndPublishWorkflowTemplate as Wn, documentModelSchemaIndexTemplate as Wt, buildObjectLiteral as X, documentModelsIndexTemplate as Xn, documentModelOperationModuleActionsFileTemplate as Xt, loadDocumentModelInDir as Y, upgradeManifestsTemplate as Yn, documentModelOperationsModuleCreatorsFileTemplate as Yt, buildStringLiteral as Z, documentModelsTemplate as Zn, getModuleExportType as Zt, getCommandsHelpInfo as _, docsFromCliHelpTemplate as _n, subgraphIndexFileTemplate as _t, getOrCreateManifestFile as a, getActionInputTypeNames as an, appEditorFileTemplate as ar, getEditorMetadata as at, buildBoilerplatePackageJson as b, tsconfigPathsTemplate as bn, relationalDbMigrationsTemplate as bt, operationHasEmptyInput as c, documentModelGenIndexFileTemplate as cn, folderTreeFileTemplate as cr, runPrettier as ct, generateDocumentModelZodSchemas as d, documentModelGenCreatorsFileTemplate as dn, emptyStateFileTemplate as dr, configSpec as dt, getDocumentModelVariableNames as en, dockerfileTemplate as er, getOrCreateSourceFile as et, generateTypesAndZodSchemasFromGraphql as f, documentModelGenControllerFileTemplate as fn, driveExplorerFileTemplate as fr, parseArgs as ft, getCommandHelpInfo as g, documentEditorEditorFileTemplate as gn, subgraphLibFileTemplate as gt, tsMorphGenerateDocumentEditor as h, documentEditorModuleFileTemplate as hn, customSubgraphSchemaTemplate as ht, createOrUpdateManifest as i, getActionInputName as in, agentsTemplate as ir, getAppMetadata as it, tsMorphGenerateApp as j, defaultManifest as jn, upgradeManifestTemplate as jt, writeModuleFiles as k, exportsTemplate as kn, documentModelUtilsTemplate as kt, operationHasInput as l, documentModelDocumentTypeTemplate as ln, appFoldersFileTemplate as lr, getDocumentTypeMetadata as lt, scalarsValidation as m, documentModelRootActionsFileTemplate as mn, createDocumentFileTemplate as mr, customSubgraphResolversTemplate as mt, tsMorphGenerateSubgraph as n, getLatestDocumentModelSpec as nn, cursorMcpTemplate as nr, getSubgraphMetadata as nt, makeModulesIndexFile as o, getActionType as on, appConfigFileTemplate as or, formatSafe as ot, scalars as p, documentModelGenActionsFileTemplate as pn, appDriveContentsFileTemplate as pr, parseConfig as pt, getStringPropertyValue as q, editorsIndexTemplate as qn, documentModelOperationsModuleOperationsFileTemplate as qt, tsMorphGenerateProcessor as r, getLatestDocumentModelSpecVersionNumber as rn, claudeSettingsLocalTemplate as rr, getProcessorMetadata as rt, operationHasAttachment as s, getActionTypeName as sn, driveExplorerNavigationBreadcrumbsFileTemplate as sr, formatSourceFileWithPrettier as st, makeSubgraphsIndexFile as t, getEditorVariableNames as tn, connectEntrypointTemplate as tr, getPreviousVersionSourceFile as tt, tsMorphGenerateDocumentModel as u, documentModelDocumentSchemaFileTemplate as un, appFilesFileTemplate as ur, documentModelDocumentTypeMetadata as ut, makeCliDocsFromHelp as v, vitestConfigTemplate as vn, relationalDbSchemaTemplate as vt, writeGeneratedDocumentModelsFiles as w, ManifestTemplate as wn, processorsFactoryTemplate as wt, writeAiConfigFiles as x, subgraphsIndexTemplate as xn, relationalDbIndexTemplate as xt, writeCliDocsMarkdownFile as y, tsConfigTemplate as yn, relationalDbProcessorTemplate as yt, getDefaultProjectOptions as z, licenseTemplate as zn, documentModelModuleFileTemplate as zt };
8540
+ export { buildStringLiteral as $, cursorMcpTemplate as $n, getModuleExportType as $t, writeModuleFiles as A, pnpmWorkspaceTemplate as An, analyticsFactoryTemplate as At, buildTsMorphProject as B, gitIgnoreTemplate as Bn, documentModelSrcIndexFileTemplate as Bt, writeAllGeneratedProjectFiles as C, subgraphsIndexTemplate as Cn, relationalDbIndexTemplate as Ct, writeGeneratedProcessorsFiles as D, buildPowerhouseConfigTemplate as Dn, factoryBuildersTemplate as Dt, writeGeneratedEditorsFiles as E, ManifestTemplate as En, processorsFactoryTemplate as Et, makeEditorsIndexFile as F, mainTsxTemplate as Fn, makeOperationImportNames as Ft, getObjectLiteral as G, editorsTemplate as Gn, documentModelGenTypesTemplate as Gt, getAllImportModuleSpecifiers as H, geminiSettingsTemplate as Hn, documentModelIndexTemplate as Ht, validateDocumentModelState as I, licenseTemplate as In, makeOperationsImports as It, getStringArrayPropertyElements as J, documentModelsTemplate as Jn, documentModelPhFactoriesFileTemplate as Jt, getObjectProperty as K, upgradeManifestsTemplate as Kn, documentModelSchemaIndexTemplate as Kt, updateVersionedImports as L, indexTsTemplate as Ln, makeTestCaseForOperation as Lt, tsMorphGenerateApp as M, packageJsonTemplate as Mn, upgradeTransitionTemplate as Mt, makeEditorModuleFile as N, npmrcTemplate as Nn, upgradeManifestTemplate as Nt, writeGeneratedProjectRootFiles as O, packageJsonExportsTemplate as On, analyticsProcessorTemplate as Ot, makeEditorsFile as P, mcpTemplate as Pn, documentModelOperationsModuleTestFileTemplate as Pt, buildObjectLiteral as Q, connectEntrypointTemplate as Qn, documentModelOperationModuleActionsFileTemplate as Qt, getInitialStates as R, legacyIndexHtmlTemplate as Rn, documentModelTestFileTemplate as Rt, writeAiConfigFiles as S, tsconfigPathsTemplate as Sn, relationalDbMigrationsTemplate as St, writeGeneratedDocumentModelsFiles as T, readmeTemplate as Tn, processorsIndexTemplate as Tt, getAllImportNames as U, eslintConfigTemplate as Un, documentModelHooksFileTemplate as Ut, getDefaultProjectOptions as V, syncAndPublishWorkflowTemplate as Vn, documentModelModuleFileTemplate as Vt, getBooleanPropertyValue as W, editorsIndexTemplate as Wn, documentModelGenUtilsTemplate as Wt, getVariableDeclarationByTypeName as X, nginxConfTemplate as Xn, documentModelOperationsModuleErrorFileTemplate as Xt, getStringPropertyValue as Y, switchboardEntrypointTemplate as Yn, documentModelOperationsModuleOperationsFileTemplate as Yt, loadDocumentModelInDir as Z, dockerfileTemplate as Zn, documentModelOperationsModuleCreatorsFileTemplate as Zt, getCommandHelpInfo as _, documentEditorModuleFileTemplate as _n, customSubgraphSchemaTemplate as _t, getOrCreateManifestFile as a, getLatestDocumentModelSpecVersionNumber as an, folderTreeFileTemplate as ar, getProcessorMetadata as at, writeCliDocsMarkdownFile as b, vitestConfigTemplate as bn, relationalDbSchemaTemplate as bt, operationHasAttachment as c, getActionType as cn, emptyStateFileTemplate as cr, formatSafe as ct, tsMorphGenerateDocumentModel as d, documentModelDocumentTypeTemplate as dn, createDocumentFileTemplate as dr, getDocumentTypeMetadata as dt, getDocumentModelDirName as en, claudeSettingsLocalTemplate as er, ensureDirectoriesExist as et, generateDocumentModelZodSchemas as f, documentModelDocumentSchemaFileTemplate as fn, documentModelDocumentTypeMetadata as ft, tsMorphGenerateDocumentEditor as g, documentModelRootActionsFileTemplate as gn, customSubgraphResolversTemplate as gt, scalarsValidation as h, documentModelGenActionsFileTemplate as hn, parseConfig as ht, createOrUpdateManifest as i, getLatestDocumentModelSpec as in, driveExplorerNavigationBreadcrumbsFileTemplate as ir, getSubgraphMetadata as it, writeProjectRootFiles as j, exportsTemplate as jn, documentModelUtilsTemplate as jt, writeGeneratedSubgraphsFiles as k, packageJsonScriptsTemplate as kn, analyticsIndexTemplate as kt, operationHasEmptyInput as l, getActionTypeName as ln, driveExplorerFileTemplate as lr, formatSourceFileWithPrettier as lt, scalars as m, documentModelGenControllerFileTemplate as mn, parseArgs as mt, tsMorphGenerateSubgraph as n, getDocumentModelVariableNames as nn, appEditorFileTemplate as nr, getOrCreateSourceFile as nt, pruneManifestSection as o, getActionInputName as on, appFoldersFileTemplate as or, getAppMetadata as ot, generateTypesAndZodSchemasFromGraphql as p, documentModelGenCreatorsFileTemplate as pn, configSpec as pt, getProperyAssignmentByName as q, documentModelsIndexTemplate as qn, documentModelGenReducerFileTemplate as qt, tsMorphGenerateProcessor as r, getEditorVariableNames as rn, appConfigFileTemplate as rr, getPreviousVersionSourceFile as rt, makeModulesIndexFile as s, getActionInputTypeNames as sn, appFilesFileTemplate as sr, getEditorMetadata as st, makeSubgraphsIndexFile as t, getDocumentModelSpecByVersionNumber as tn, agentsTemplate as tr, getOrCreateDirectory as tt, operationHasInput as u, documentModelGenIndexFileTemplate as un, appDriveContentsFileTemplate as ur, runPrettier as ut, getCommandsHelpInfo as v, documentEditorEditorFileTemplate as vn, subgraphLibFileTemplate as vt, writeCIFiles as w, styleTemplate as wn, relationalDbFactoryTemplate as wt, buildBoilerplatePackageJson as x, tsConfigTemplate as xn, relationalDbProcessorTemplate as xt, makeCliDocsFromHelp as y, docsFromCliHelpTemplate as yn, subgraphIndexFileTemplate as yt, DEFAULT_PROJECT_OPTIONS as z, indexHtmlTemplate as zn, documentModelSrcUtilsTemplate as zt };
8840
8541
 
8841
- //# sourceMappingURL=file-builders-KGdRKyyn.mjs.map
8542
+ //# sourceMappingURL=file-builders-BGuRLZmo.mjs.map