@codedrifters/configulator 0.0.238 → 0.0.240

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.mts CHANGED
@@ -2721,6 +2721,77 @@ declare class AwsDeployWorkflow extends Component {
2721
2721
  preSynthesize(): void;
2722
2722
  }
2723
2723
 
2724
+ /**
2725
+ * Canonical top-level folders for a configulator monorepo (ADR-006).
2726
+ *
2727
+ * Every sub-project must live under one of these roots. `DOCS` is a
2728
+ * singleton (the single Starlight site at `/docs`); `APPS`, `PACKAGES`,
2729
+ * and `SITES` are parents for `@scope/<name>` sub-projects.
2730
+ *
2731
+ * @see docs/requirements/architectural-decisions/ADR-006-monorepo-layout.md
2732
+ */
2733
+ declare const MONOREPO_LAYOUT: {
2734
+ readonly DOCS: "docs";
2735
+ readonly APPS: "apps";
2736
+ readonly PACKAGES: "packages";
2737
+ readonly SITES: "sites";
2738
+ };
2739
+ type MonorepoLayoutRoot = (typeof MONOREPO_LAYOUT)[keyof typeof MONOREPO_LAYOUT];
2740
+ /**
2741
+ * How `MonorepoProject` reacts when a sub-project's `outdir` falls outside
2742
+ * the root expected for its project type (see ADR-006 §4).
2743
+ *
2744
+ * - `"off"` — no validation runs.
2745
+ * - `"warn"` — log a console warning per offending sub-project; synth proceeds.
2746
+ * - `"error"` — throw on the first offending sub-project; synth fails.
2747
+ */
2748
+ declare const LAYOUT_ENFORCEMENT: {
2749
+ readonly OFF: "off";
2750
+ readonly WARN: "warn";
2751
+ readonly ERROR: "error";
2752
+ };
2753
+ type LayoutEnforcement = (typeof LAYOUT_ENFORCEMENT)[keyof typeof LAYOUT_ENFORCEMENT];
2754
+ /**
2755
+ * Mapping from configulator project-type class name to the root folder its
2756
+ * `outdir` must live under.
2757
+ *
2758
+ * We key by class name (not class reference) so this module stays free of
2759
+ * import cycles with the project-type files that validate against it.
2760
+ * `StarlightProject` maps to `DOCS` because the docs-singleton rule says
2761
+ * Starlight is only ever used as the monorepo-wide docs site.
2762
+ *
2763
+ * @see ADR-006 §4 — Configulator project-type → `outdir` mapping
2764
+ */
2765
+ declare const LAYOUT_ROOT_BY_PROJECT_TYPE: Readonly<Record<string, MonorepoLayoutRoot>>;
2766
+ /**
2767
+ * A single offender reported by {@link validateMonorepoLayout}. One entry
2768
+ * per sub-project whose `outdir` falls outside its expected root.
2769
+ */
2770
+ interface LayoutViolation {
2771
+ readonly projectName: string;
2772
+ readonly projectType: string;
2773
+ readonly outdir: string;
2774
+ readonly expectedRoot: MonorepoLayoutRoot;
2775
+ }
2776
+ /**
2777
+ * Inspect every sub-project of `root` and collect those whose `outdir` does
2778
+ * not live under the root expected for their project class (ADR-006 §4).
2779
+ *
2780
+ * - Sub-projects whose class name is not in
2781
+ * {@link LAYOUT_ROOT_BY_PROJECT_TYPE} are skipped — the contract only
2782
+ * covers the four documented project types.
2783
+ * - The root project itself is skipped (it *is* the monorepo root, not a
2784
+ * sub-project).
2785
+ * - `outdir` comparison is done in POSIX form against the project root so
2786
+ * absolute paths synthesised on Windows still match.
2787
+ */
2788
+ declare function validateMonorepoLayout(root: Project$1): Array<LayoutViolation>;
2789
+ /**
2790
+ * Render one {@link LayoutViolation} as an actionable, single-line error
2791
+ * message pointing the reader at ADR-006.
2792
+ */
2793
+ declare function formatLayoutViolation(violation: LayoutViolation): string;
2794
+
2724
2795
  /**
2725
2796
  * Each of the below options corresponds to a task property found here:
2726
2797
  * * https://turborepo.com/docs/reference/configuration#defining-tasks
@@ -3303,6 +3374,22 @@ interface MonorepoProjectOptions extends Omit<TypeScriptProjectOptions$1, "defau
3303
3374
  * @default true
3304
3375
  */
3305
3376
  readonly syncLabels?: SyncLabelsOptions | boolean;
3377
+ /**
3378
+ * How to react when a sub-project's `outdir` falls outside the root
3379
+ * expected for its project type (ADR-006 §4).
3380
+ *
3381
+ * - `"off"` — skip validation entirely.
3382
+ * - `"warn"` — log a console warning per violation; synth proceeds.
3383
+ * - `"error"` — throw on the first violation; synth fails.
3384
+ *
3385
+ * Defaults to `"warn"` during the ADR-006 rollout so existing consumers
3386
+ * with legacy outdirs see actionable warnings but do not break. A future
3387
+ * release will flip the default to `"error"`.
3388
+ *
3389
+ * @default "warn"
3390
+ * @see docs/requirements/architectural-decisions/ADR-006-monorepo-layout.md
3391
+ */
3392
+ readonly layoutEnforcement?: LayoutEnforcement;
3306
3393
  }
3307
3394
  declare class MonorepoProject extends TypeScriptAppProject {
3308
3395
  /**
@@ -3313,7 +3400,22 @@ declare class MonorepoProject extends TypeScriptAppProject {
3313
3400
  * Whether this monorepo consumes configulator from a registry (drives upgrade workflow steps).
3314
3401
  */
3315
3402
  readonly configulatorRegistryConsumer: boolean;
3403
+ /**
3404
+ * Layout-enforcement mode for sub-project `outdir` validation (ADR-006).
3405
+ */
3406
+ readonly layoutEnforcement: LayoutEnforcement;
3316
3407
  constructor(userOptions: MonorepoProjectOptions);
3408
+ /**
3409
+ * Validate sub-project `outdir` values against the ADR-006 monorepo
3410
+ * layout contract. Runs in `preSynthesize` so all sub-projects are
3411
+ * attached by the time we inspect the tree.
3412
+ *
3413
+ * Behavior is controlled by `layoutEnforcement`:
3414
+ * - `"off"` — skip validation.
3415
+ * - `"warn"` — log a `console.warn` per violation; continue.
3416
+ * - `"error"` — throw on the first violation.
3417
+ */
3418
+ preSynthesize(): void;
3317
3419
  /**
3318
3420
  * Allows a sub project to request installation of dependency at the Monorepo root
3319
3421
  * They must provide a function that is executed after dependencies have been installed
@@ -3636,4 +3738,4 @@ declare const COMPLETE_JOB_ID = "complete";
3636
3738
  */
3637
3739
  declare function addBuildCompleteJob(buildWorkflow: BuildWorkflow): void;
3638
3740
 
3639
- export { AGENT_MODEL, AGENT_PLATFORM, AGENT_RULE_SCOPE, AgentConfig, type AgentConfigOptions, type AgentModel, type AgentPlatform, type AgentPlatformOverrides, type AgentProcedure, type AgentRule, type AgentRuleBundle, type AgentRuleScope, type AgentSkill, type AgentSubAgent, type AgentSubAgentPlatformOverrides, type ApproveMergeUpgradeOptions, AstroConfig, type AstroConfigOptions, type AstroIntegrationSpec, AstroOutput, AstroProject, type AstroProjectOptions, type AwsAccount, AwsCdkProject, type AwsCdkProjectOptions, AwsDeployWorkflow, AwsDeploymentConfig, AwsDeploymentTarget, type AwsDeploymentTargetOptions, type AwsLocalDeploymentConfig, type AwsOrganization, type AwsRegion, AwsTeardownWorkflow, type AwsTeardownWorkflowOptions, BUILT_IN_BUNDLES, CLAUDE_RULE_TARGET, COMPLETE_JOB_ID, type CiDeploymentConfig, type ClassTypeOptions, type ClaudeAutoModeConfig, type ClaudeHookAction, type ClaudeHookEntry, type ClaudeHooksConfig, type ClaudePermissionsConfig, type ClaudeRuleTarget, type ClaudeSandboxConfig, type ClaudeSettingsConfig, type CopilotHandoff, type CursorHookAction, type CursorHooksConfig, type CursorSettingsConfig, DEFAULT_PRIORITY_LABELS, DEFAULT_STATUS_LABELS, DEFAULT_TEARDOWN_BRANCH_PATTERNS, DEFAULT_TYPE_LABELS, type DeployWorkflowOptions, type DeploymentMetadata, type GitBranch, type GitHubBoardMetadata, type GitHubProjectMetadata, type GitHubSprintMetadata, type IDependencyResolver, JsiiFaker, type LabelDefinition, MCP_TRANSPORT, MERGE_METHODS, MIMIMUM_RELEASE_AGE, MINIMUM_RELEASE_AGE, type McpServerConfig, type McpTransport, type MergeMethod, MonorepoProject, type MonorepoProjectOptions, type OrganizationMetadata, PROD_DEPLOY_NAME, PnpmWorkspace, type PnpmWorkspaceOptions, ProjectMetadata, type ProjectMetadataOptions, REQUIREMENTS_WRITER_PATHS, ROOT_CI_TASK_NAME, ROOT_TURBO_TASK_NAME, type RemoteCacheOptions, type RepositoryMetadata, ResetTask, type ResetTaskOptions, type ResolvedProjectMetadata, type SlackMetadata, type StarlightEditLink, type StarlightLogo, StarlightProject, type StarlightProjectOptions, type StarlightSidebarItem, type StarlightSocialLink, type SyncLabelsOptions, type TemplateResolveResult, TestRunner, TurboRepo, type TurboRepoOptions, TurboRepoTask, type TurboRepoTaskOptions, TypeScriptConfig, TypeScriptProject, type TypeScriptProjectOptions, VERSION, VERSION_KEYS_SKIP, VERSION_NPM_PACKAGES, VSCodeConfig, type VersionKey, Vitest, type VitestConfigOptions, type VitestOptions, addApproveMergeUpgradeWorkflow, addBuildCompleteJob, addSyncLabelsWorkflow, awsCdkBundle, baseBundle, bcmWriterBundle, companyProfileBundle, getLatestEligibleVersion, githubWorkflowBundle, industryDiscoveryBundle, jestBundle, maintenanceAuditBundle, meetingAnalysisBundle, orchestratorBundle, peopleProfileBundle, pnpmBundle, prReviewBundle, projenBundle, requirementsAnalystBundle, requirementsReviewerBundle, requirementsWriterBundle, researchPipelineBundle, resolveModelAlias, resolveTemplateVariables, slackBundle, softwareProfileBundle, turborepoBundle, typescriptBundle, vitestBundle };
3741
+ export { AGENT_MODEL, AGENT_PLATFORM, AGENT_RULE_SCOPE, AgentConfig, type AgentConfigOptions, type AgentModel, type AgentPlatform, type AgentPlatformOverrides, type AgentProcedure, type AgentRule, type AgentRuleBundle, type AgentRuleScope, type AgentSkill, type AgentSubAgent, type AgentSubAgentPlatformOverrides, type ApproveMergeUpgradeOptions, AstroConfig, type AstroConfigOptions, type AstroIntegrationSpec, AstroOutput, AstroProject, type AstroProjectOptions, type AwsAccount, AwsCdkProject, type AwsCdkProjectOptions, AwsDeployWorkflow, AwsDeploymentConfig, AwsDeploymentTarget, type AwsDeploymentTargetOptions, type AwsLocalDeploymentConfig, type AwsOrganization, type AwsRegion, AwsTeardownWorkflow, type AwsTeardownWorkflowOptions, BUILT_IN_BUNDLES, CLAUDE_RULE_TARGET, COMPLETE_JOB_ID, type CiDeploymentConfig, type ClassTypeOptions, type ClaudeAutoModeConfig, type ClaudeHookAction, type ClaudeHookEntry, type ClaudeHooksConfig, type ClaudePermissionsConfig, type ClaudeRuleTarget, type ClaudeSandboxConfig, type ClaudeSettingsConfig, type CopilotHandoff, type CursorHookAction, type CursorHooksConfig, type CursorSettingsConfig, DEFAULT_PRIORITY_LABELS, DEFAULT_STATUS_LABELS, DEFAULT_TEARDOWN_BRANCH_PATTERNS, DEFAULT_TYPE_LABELS, type DeployWorkflowOptions, type DeploymentMetadata, type GitBranch, type GitHubBoardMetadata, type GitHubProjectMetadata, type GitHubSprintMetadata, type IDependencyResolver, JsiiFaker, LAYOUT_ENFORCEMENT, LAYOUT_ROOT_BY_PROJECT_TYPE, type LabelDefinition, type LayoutEnforcement, type LayoutViolation, MCP_TRANSPORT, MERGE_METHODS, MIMIMUM_RELEASE_AGE, MINIMUM_RELEASE_AGE, MONOREPO_LAYOUT, type McpServerConfig, type McpTransport, type MergeMethod, type MonorepoLayoutRoot, MonorepoProject, type MonorepoProjectOptions, type OrganizationMetadata, PROD_DEPLOY_NAME, PnpmWorkspace, type PnpmWorkspaceOptions, ProjectMetadata, type ProjectMetadataOptions, REQUIREMENTS_WRITER_PATHS, ROOT_CI_TASK_NAME, ROOT_TURBO_TASK_NAME, type RemoteCacheOptions, type RepositoryMetadata, ResetTask, type ResetTaskOptions, type ResolvedProjectMetadata, type SlackMetadata, type StarlightEditLink, type StarlightLogo, StarlightProject, type StarlightProjectOptions, type StarlightSidebarItem, type StarlightSocialLink, type SyncLabelsOptions, type TemplateResolveResult, TestRunner, TurboRepo, type TurboRepoOptions, TurboRepoTask, type TurboRepoTaskOptions, TypeScriptConfig, TypeScriptProject, type TypeScriptProjectOptions, VERSION, VERSION_KEYS_SKIP, VERSION_NPM_PACKAGES, VSCodeConfig, type VersionKey, Vitest, type VitestConfigOptions, type VitestOptions, addApproveMergeUpgradeWorkflow, addBuildCompleteJob, addSyncLabelsWorkflow, awsCdkBundle, baseBundle, bcmWriterBundle, companyProfileBundle, formatLayoutViolation, getLatestEligibleVersion, githubWorkflowBundle, industryDiscoveryBundle, jestBundle, maintenanceAuditBundle, meetingAnalysisBundle, orchestratorBundle, peopleProfileBundle, pnpmBundle, prReviewBundle, projenBundle, requirementsAnalystBundle, requirementsReviewerBundle, requirementsWriterBundle, researchPipelineBundle, resolveModelAlias, resolveTemplateVariables, slackBundle, softwareProfileBundle, turborepoBundle, typescriptBundle, validateMonorepoLayout, vitestBundle };
package/lib/index.d.ts CHANGED
@@ -2770,6 +2770,77 @@ declare class AwsDeployWorkflow extends Component {
2770
2770
  preSynthesize(): void;
2771
2771
  }
2772
2772
 
2773
+ /**
2774
+ * Canonical top-level folders for a configulator monorepo (ADR-006).
2775
+ *
2776
+ * Every sub-project must live under one of these roots. `DOCS` is a
2777
+ * singleton (the single Starlight site at `/docs`); `APPS`, `PACKAGES`,
2778
+ * and `SITES` are parents for `@scope/<name>` sub-projects.
2779
+ *
2780
+ * @see docs/requirements/architectural-decisions/ADR-006-monorepo-layout.md
2781
+ */
2782
+ declare const MONOREPO_LAYOUT: {
2783
+ readonly DOCS: "docs";
2784
+ readonly APPS: "apps";
2785
+ readonly PACKAGES: "packages";
2786
+ readonly SITES: "sites";
2787
+ };
2788
+ type MonorepoLayoutRoot = (typeof MONOREPO_LAYOUT)[keyof typeof MONOREPO_LAYOUT];
2789
+ /**
2790
+ * How `MonorepoProject` reacts when a sub-project's `outdir` falls outside
2791
+ * the root expected for its project type (see ADR-006 §4).
2792
+ *
2793
+ * - `"off"` — no validation runs.
2794
+ * - `"warn"` — log a console warning per offending sub-project; synth proceeds.
2795
+ * - `"error"` — throw on the first offending sub-project; synth fails.
2796
+ */
2797
+ declare const LAYOUT_ENFORCEMENT: {
2798
+ readonly OFF: "off";
2799
+ readonly WARN: "warn";
2800
+ readonly ERROR: "error";
2801
+ };
2802
+ type LayoutEnforcement = (typeof LAYOUT_ENFORCEMENT)[keyof typeof LAYOUT_ENFORCEMENT];
2803
+ /**
2804
+ * Mapping from configulator project-type class name to the root folder its
2805
+ * `outdir` must live under.
2806
+ *
2807
+ * We key by class name (not class reference) so this module stays free of
2808
+ * import cycles with the project-type files that validate against it.
2809
+ * `StarlightProject` maps to `DOCS` because the docs-singleton rule says
2810
+ * Starlight is only ever used as the monorepo-wide docs site.
2811
+ *
2812
+ * @see ADR-006 §4 — Configulator project-type → `outdir` mapping
2813
+ */
2814
+ declare const LAYOUT_ROOT_BY_PROJECT_TYPE: Readonly<Record<string, MonorepoLayoutRoot>>;
2815
+ /**
2816
+ * A single offender reported by {@link validateMonorepoLayout}. One entry
2817
+ * per sub-project whose `outdir` falls outside its expected root.
2818
+ */
2819
+ interface LayoutViolation {
2820
+ readonly projectName: string;
2821
+ readonly projectType: string;
2822
+ readonly outdir: string;
2823
+ readonly expectedRoot: MonorepoLayoutRoot;
2824
+ }
2825
+ /**
2826
+ * Inspect every sub-project of `root` and collect those whose `outdir` does
2827
+ * not live under the root expected for their project class (ADR-006 §4).
2828
+ *
2829
+ * - Sub-projects whose class name is not in
2830
+ * {@link LAYOUT_ROOT_BY_PROJECT_TYPE} are skipped — the contract only
2831
+ * covers the four documented project types.
2832
+ * - The root project itself is skipped (it *is* the monorepo root, not a
2833
+ * sub-project).
2834
+ * - `outdir` comparison is done in POSIX form against the project root so
2835
+ * absolute paths synthesised on Windows still match.
2836
+ */
2837
+ declare function validateMonorepoLayout(root: Project): Array<LayoutViolation>;
2838
+ /**
2839
+ * Render one {@link LayoutViolation} as an actionable, single-line error
2840
+ * message pointing the reader at ADR-006.
2841
+ */
2842
+ declare function formatLayoutViolation(violation: LayoutViolation): string;
2843
+
2773
2844
  /**
2774
2845
  * Each of the below options corresponds to a task property found here:
2775
2846
  * * https://turborepo.com/docs/reference/configuration#defining-tasks
@@ -3352,6 +3423,22 @@ interface MonorepoProjectOptions extends Omit<TypeScriptProjectOptions$1, "defau
3352
3423
  * @default true
3353
3424
  */
3354
3425
  readonly syncLabels?: SyncLabelsOptions | boolean;
3426
+ /**
3427
+ * How to react when a sub-project's `outdir` falls outside the root
3428
+ * expected for its project type (ADR-006 §4).
3429
+ *
3430
+ * - `"off"` — skip validation entirely.
3431
+ * - `"warn"` — log a console warning per violation; synth proceeds.
3432
+ * - `"error"` — throw on the first violation; synth fails.
3433
+ *
3434
+ * Defaults to `"warn"` during the ADR-006 rollout so existing consumers
3435
+ * with legacy outdirs see actionable warnings but do not break. A future
3436
+ * release will flip the default to `"error"`.
3437
+ *
3438
+ * @default "warn"
3439
+ * @see docs/requirements/architectural-decisions/ADR-006-monorepo-layout.md
3440
+ */
3441
+ readonly layoutEnforcement?: LayoutEnforcement;
3355
3442
  }
3356
3443
  declare class MonorepoProject extends TypeScriptAppProject {
3357
3444
  /**
@@ -3362,7 +3449,22 @@ declare class MonorepoProject extends TypeScriptAppProject {
3362
3449
  * Whether this monorepo consumes configulator from a registry (drives upgrade workflow steps).
3363
3450
  */
3364
3451
  readonly configulatorRegistryConsumer: boolean;
3452
+ /**
3453
+ * Layout-enforcement mode for sub-project `outdir` validation (ADR-006).
3454
+ */
3455
+ readonly layoutEnforcement: LayoutEnforcement;
3365
3456
  constructor(userOptions: MonorepoProjectOptions);
3457
+ /**
3458
+ * Validate sub-project `outdir` values against the ADR-006 monorepo
3459
+ * layout contract. Runs in `preSynthesize` so all sub-projects are
3460
+ * attached by the time we inspect the tree.
3461
+ *
3462
+ * Behavior is controlled by `layoutEnforcement`:
3463
+ * - `"off"` — skip validation.
3464
+ * - `"warn"` — log a `console.warn` per violation; continue.
3465
+ * - `"error"` — throw on the first violation.
3466
+ */
3467
+ preSynthesize(): void;
3366
3468
  /**
3367
3469
  * Allows a sub project to request installation of dependency at the Monorepo root
3368
3470
  * They must provide a function that is executed after dependencies have been installed
@@ -3685,5 +3787,5 @@ declare const COMPLETE_JOB_ID = "complete";
3685
3787
  */
3686
3788
  declare function addBuildCompleteJob(buildWorkflow: BuildWorkflow): void;
3687
3789
 
3688
- export { AGENT_MODEL, AGENT_PLATFORM, AGENT_RULE_SCOPE, AgentConfig, AstroConfig, AstroOutput, AstroProject, AwsCdkProject, AwsDeployWorkflow, AwsDeploymentConfig, AwsDeploymentTarget, AwsTeardownWorkflow, BUILT_IN_BUNDLES, CLAUDE_RULE_TARGET, COMPLETE_JOB_ID, DEFAULT_PRIORITY_LABELS, DEFAULT_STATUS_LABELS, DEFAULT_TEARDOWN_BRANCH_PATTERNS, DEFAULT_TYPE_LABELS, JsiiFaker, MCP_TRANSPORT, MERGE_METHODS, MIMIMUM_RELEASE_AGE, MINIMUM_RELEASE_AGE, MonorepoProject, PROD_DEPLOY_NAME, PnpmWorkspace, ProjectMetadata, REQUIREMENTS_WRITER_PATHS, ROOT_CI_TASK_NAME, ROOT_TURBO_TASK_NAME, ResetTask, StarlightProject, TestRunner, TurboRepo, TurboRepoTask, TypeScriptConfig, TypeScriptProject, VERSION, VERSION_KEYS_SKIP, VERSION_NPM_PACKAGES, VSCodeConfig, Vitest, addApproveMergeUpgradeWorkflow, addBuildCompleteJob, addSyncLabelsWorkflow, awsCdkBundle, baseBundle, bcmWriterBundle, companyProfileBundle, getLatestEligibleVersion, githubWorkflowBundle, industryDiscoveryBundle, jestBundle, maintenanceAuditBundle, meetingAnalysisBundle, orchestratorBundle, peopleProfileBundle, pnpmBundle, prReviewBundle, projenBundle, requirementsAnalystBundle, requirementsReviewerBundle, requirementsWriterBundle, researchPipelineBundle, resolveModelAlias, resolveTemplateVariables, slackBundle, softwareProfileBundle, turborepoBundle, typescriptBundle, vitestBundle };
3689
- export type { AgentConfigOptions, AgentModel, AgentPlatform, AgentPlatformOverrides, AgentProcedure, AgentRule, AgentRuleBundle, AgentRuleScope, AgentSkill, AgentSubAgent, AgentSubAgentPlatformOverrides, ApproveMergeUpgradeOptions, AstroConfigOptions, AstroIntegrationSpec, AstroProjectOptions, AwsAccount, AwsCdkProjectOptions, AwsDeploymentTargetOptions, AwsLocalDeploymentConfig, AwsOrganization, AwsRegion, AwsTeardownWorkflowOptions, CiDeploymentConfig, ClassTypeOptions, ClaudeAutoModeConfig, ClaudeHookAction, ClaudeHookEntry, ClaudeHooksConfig, ClaudePermissionsConfig, ClaudeRuleTarget, ClaudeSandboxConfig, ClaudeSettingsConfig, CopilotHandoff, CursorHookAction, CursorHooksConfig, CursorSettingsConfig, DeployWorkflowOptions, DeploymentMetadata, GitBranch, GitHubBoardMetadata, GitHubProjectMetadata, GitHubSprintMetadata, IDependencyResolver, LabelDefinition, McpServerConfig, McpTransport, MergeMethod, MonorepoProjectOptions, OrganizationMetadata, PnpmWorkspaceOptions, ProjectMetadataOptions, RemoteCacheOptions, RepositoryMetadata, ResetTaskOptions, ResolvedProjectMetadata, SlackMetadata, StarlightEditLink, StarlightLogo, StarlightProjectOptions, StarlightSidebarItem, StarlightSocialLink, SyncLabelsOptions, TemplateResolveResult, TurboRepoOptions, TurboRepoTaskOptions, TypeScriptProjectOptions, VersionKey, VitestConfigOptions, VitestOptions };
3790
+ export { AGENT_MODEL, AGENT_PLATFORM, AGENT_RULE_SCOPE, AgentConfig, AstroConfig, AstroOutput, AstroProject, AwsCdkProject, AwsDeployWorkflow, AwsDeploymentConfig, AwsDeploymentTarget, AwsTeardownWorkflow, BUILT_IN_BUNDLES, CLAUDE_RULE_TARGET, COMPLETE_JOB_ID, DEFAULT_PRIORITY_LABELS, DEFAULT_STATUS_LABELS, DEFAULT_TEARDOWN_BRANCH_PATTERNS, DEFAULT_TYPE_LABELS, JsiiFaker, LAYOUT_ENFORCEMENT, LAYOUT_ROOT_BY_PROJECT_TYPE, MCP_TRANSPORT, MERGE_METHODS, MIMIMUM_RELEASE_AGE, MINIMUM_RELEASE_AGE, MONOREPO_LAYOUT, MonorepoProject, PROD_DEPLOY_NAME, PnpmWorkspace, ProjectMetadata, REQUIREMENTS_WRITER_PATHS, ROOT_CI_TASK_NAME, ROOT_TURBO_TASK_NAME, ResetTask, StarlightProject, TestRunner, TurboRepo, TurboRepoTask, TypeScriptConfig, TypeScriptProject, VERSION, VERSION_KEYS_SKIP, VERSION_NPM_PACKAGES, VSCodeConfig, Vitest, addApproveMergeUpgradeWorkflow, addBuildCompleteJob, addSyncLabelsWorkflow, awsCdkBundle, baseBundle, bcmWriterBundle, companyProfileBundle, formatLayoutViolation, getLatestEligibleVersion, githubWorkflowBundle, industryDiscoveryBundle, jestBundle, maintenanceAuditBundle, meetingAnalysisBundle, orchestratorBundle, peopleProfileBundle, pnpmBundle, prReviewBundle, projenBundle, requirementsAnalystBundle, requirementsReviewerBundle, requirementsWriterBundle, researchPipelineBundle, resolveModelAlias, resolveTemplateVariables, slackBundle, softwareProfileBundle, turborepoBundle, typescriptBundle, validateMonorepoLayout, vitestBundle };
3791
+ export type { AgentConfigOptions, AgentModel, AgentPlatform, AgentPlatformOverrides, AgentProcedure, AgentRule, AgentRuleBundle, AgentRuleScope, AgentSkill, AgentSubAgent, AgentSubAgentPlatformOverrides, ApproveMergeUpgradeOptions, AstroConfigOptions, AstroIntegrationSpec, AstroProjectOptions, AwsAccount, AwsCdkProjectOptions, AwsDeploymentTargetOptions, AwsLocalDeploymentConfig, AwsOrganization, AwsRegion, AwsTeardownWorkflowOptions, CiDeploymentConfig, ClassTypeOptions, ClaudeAutoModeConfig, ClaudeHookAction, ClaudeHookEntry, ClaudeHooksConfig, ClaudePermissionsConfig, ClaudeRuleTarget, ClaudeSandboxConfig, ClaudeSettingsConfig, CopilotHandoff, CursorHookAction, CursorHooksConfig, CursorSettingsConfig, DeployWorkflowOptions, DeploymentMetadata, GitBranch, GitHubBoardMetadata, GitHubProjectMetadata, GitHubSprintMetadata, IDependencyResolver, LabelDefinition, LayoutEnforcement, LayoutViolation, McpServerConfig, McpTransport, MergeMethod, MonorepoLayoutRoot, MonorepoProjectOptions, OrganizationMetadata, PnpmWorkspaceOptions, ProjectMetadataOptions, RemoteCacheOptions, RepositoryMetadata, ResetTaskOptions, ResolvedProjectMetadata, SlackMetadata, StarlightEditLink, StarlightLogo, StarlightProjectOptions, StarlightSidebarItem, StarlightSocialLink, SyncLabelsOptions, TemplateResolveResult, TurboRepoOptions, TurboRepoTaskOptions, TypeScriptProjectOptions, VersionKey, VitestConfigOptions, VitestOptions };
package/lib/index.js CHANGED
@@ -195,10 +195,13 @@ __export(index_exports, {
195
195
  DEFAULT_TEARDOWN_BRANCH_PATTERNS: () => DEFAULT_TEARDOWN_BRANCH_PATTERNS,
196
196
  DEFAULT_TYPE_LABELS: () => DEFAULT_TYPE_LABELS,
197
197
  JsiiFaker: () => JsiiFaker,
198
+ LAYOUT_ENFORCEMENT: () => LAYOUT_ENFORCEMENT,
199
+ LAYOUT_ROOT_BY_PROJECT_TYPE: () => LAYOUT_ROOT_BY_PROJECT_TYPE,
198
200
  MCP_TRANSPORT: () => MCP_TRANSPORT,
199
201
  MERGE_METHODS: () => MERGE_METHODS,
200
202
  MIMIMUM_RELEASE_AGE: () => MIMIMUM_RELEASE_AGE,
201
203
  MINIMUM_RELEASE_AGE: () => MINIMUM_RELEASE_AGE,
204
+ MONOREPO_LAYOUT: () => MONOREPO_LAYOUT,
202
205
  MonorepoProject: () => MonorepoProject,
203
206
  PROD_DEPLOY_NAME: () => PROD_DEPLOY_NAME,
204
207
  PnpmWorkspace: () => PnpmWorkspace,
@@ -225,6 +228,7 @@ __export(index_exports, {
225
228
  baseBundle: () => baseBundle,
226
229
  bcmWriterBundle: () => bcmWriterBundle,
227
230
  companyProfileBundle: () => companyProfileBundle,
231
+ formatLayoutViolation: () => formatLayoutViolation,
228
232
  getLatestEligibleVersion: () => getLatestEligibleVersion,
229
233
  githubWorkflowBundle: () => githubWorkflowBundle,
230
234
  industryDiscoveryBundle: () => industryDiscoveryBundle,
@@ -246,6 +250,7 @@ __export(index_exports, {
246
250
  softwareProfileBundle: () => softwareProfileBundle,
247
251
  turborepoBundle: () => turborepoBundle,
248
252
  typescriptBundle: () => typescriptBundle,
253
+ validateMonorepoLayout: () => validateMonorepoLayout,
249
254
  vitestBundle: () => vitestBundle
250
255
  });
251
256
  module.exports = __toCommonJS(index_exports);
@@ -845,6 +850,91 @@ var baseBundle = {
845
850
  ].join("\n"),
846
851
  tags: ["workflow"]
847
852
  },
853
+ {
854
+ name: "monorepo-layout",
855
+ description: "Canonical monorepo top-level folders (docs, apps, packages, sites), the @ownerscope/<name> scoping rule, the docs-singleton carve-out, and the scaffolding skills that place new sub-projects",
856
+ scope: AGENT_RULE_SCOPE.ALWAYS,
857
+ content: [
858
+ "# Monorepo Layout",
859
+ "",
860
+ "Every monorepo built with `@codedrifters/configulator` uses a single,",
861
+ "fixed top-level folder layout. Agents, scaffolding skills, pnpm-workspace",
862
+ "globs, Turbo filters, and CI cache keys all assume these roots.",
863
+ "",
864
+ "## Four Canonical Top-Level Folders",
865
+ "",
866
+ "| Folder | Purpose | Examples |",
867
+ "|--------|---------|----------|",
868
+ "| `/docs` | **Single** Starlight site covering the entire monorepo. The one site that lives outside `/sites`. | Monorepo-wide developer docs, ADRs, how-to guides. |",
869
+ "| `/apps/@scope/<name>` | Deployable applications \u2014 anything that runs or ships as a running process. | AWS CDK stacks, mobile apps (iOS/Android), backend services. |",
870
+ "| `/packages/@scope/<name>` | Shared libraries \u2014 published npm packages and workspace-internal libraries. | `@codedrifters/configulator`, `@codedrifters/constructs`, `@codedrifters/utils`. |",
871
+ "| `/sites/@scope/<name>` | User-facing web front ends that are **not** the monorepo-wide docs site. | Marketing sites, SPAs, per-client static sites. |",
872
+ "",
873
+ "No other top-level folder is part of this contract. Generated roots",
874
+ "(`.projen/`, `.github/`, `node_modules/`, `.turbo/`, etc.) are orthogonal",
875
+ "and unchanged.",
876
+ "",
877
+ "## Scoping Rule",
878
+ "",
879
+ "Every sub-project under `apps/`, `packages/`, or `sites/` is named",
880
+ "`@ownerscope/<name>`, where **scope is the owning party** (not a category).",
881
+ "",
882
+ "- `@codedrifters/configulator` \u2014 a shared library owned by CodeDrifters \u2192 `packages/@codedrifters/configulator`",
883
+ "- `@codedrifters/infrastructure-stack` \u2014 an AWS CDK app owned by CodeDrifters \u2192 `apps/@codedrifters/infrastructure-stack`",
884
+ "- `@clientA/iphone-app` \u2014 a mobile app owned by Client A \u2192 `apps/@clientA/iphone-app`",
885
+ "- `@clientB/marketing-site` \u2014 a marketing site owned by Client B \u2192 `sites/@clientB/marketing-site`",
886
+ "",
887
+ "The scope identifies **who owns the sub-project**, not what kind of",
888
+ "sub-project it is. Kind is captured by the top-level folder (`apps/`,",
889
+ "`packages/`, `sites/`). Never scope by category (e.g. `@apps/foo`,",
890
+ "`@libs/bar`) \u2014 the top-level folder already carries that information.",
891
+ "",
892
+ "## Docs-Singleton Carve-Out",
893
+ "",
894
+ "There is **exactly one** Starlight docs site per monorepo, and it lives",
895
+ "at `/docs`. It is **not** `sites/@scope/docs`.",
896
+ "",
897
+ "- The docs site is monorepo-wide. Sub-project documentation belongs",
898
+ " inside that single site (under `docs/content/`), not in a per-package",
899
+ " `docs/` folder.",
900
+ "- Configulator's `StarlightProject` defaults its `outdir` to `/docs`.",
901
+ "- `/sites` is reserved for end-user-facing web front ends (marketing",
902
+ " sites, SPAs, client-facing apps). It deliberately does not host the",
903
+ " dev-docs site.",
904
+ "",
905
+ "## Project-Type \u2192 `outdir` Mapping",
906
+ "",
907
+ "Configulator project types default their `outdir` according to the",
908
+ "following table. Override `outdir` explicitly only when you have a",
909
+ "genuine reason \u2014 the defaults cover the common path.",
910
+ "",
911
+ "| Configulator project type | Default `outdir` |",
912
+ "|---------------------------|------------------|",
913
+ "| `TypeScriptProject` | `packages/<scope>/<name>` |",
914
+ "| `AwsCdkProject` | `apps/<scope>/<name>` |",
915
+ "| `AstroProject` | `sites/<scope>/<name>` |",
916
+ "| `StarlightProject` (role = docs) | `docs/` |",
917
+ "",
918
+ "`<scope>` is parsed from the sub-project's package name (everything",
919
+ "after `@` and before `/`). `<name>` is the unscoped part of the",
920
+ "package name.",
921
+ "",
922
+ "## Placing New Sub-Projects",
923
+ "",
924
+ "Never hand-roll a sub-project path. Use one of the scaffolding skills,",
925
+ "which take `@scope/<name>` as input, validate it, and place the new",
926
+ "project in the correct folder:",
927
+ "",
928
+ "- `/create-package` \u2014 scaffolds a new `TypeScriptProject` under `packages/<scope>/<name>`",
929
+ "- `/create-app` \u2014 scaffolds a new `AwsCdkProject` under `apps/<scope>/<name>`",
930
+ "- `/create-site` \u2014 scaffolds a new `AstroProject` under `sites/<scope>/<name>`",
931
+ "",
932
+ "The monorepo-wide docs site at `/docs` is a singleton and is created",
933
+ "once per repo via `StarlightProject` \u2014 it is not scaffolded per",
934
+ "sub-project."
935
+ ].join("\n"),
936
+ tags: ["project"]
937
+ },
848
938
  {
849
939
  name: "issue-conventions",
850
940
  description: "Issue title prefixes, GitHub issue type mapping, prerequisite issues",
@@ -15556,6 +15646,77 @@ var import_javascript3 = require("projen/lib/javascript");
15556
15646
  var import_typescript3 = require("projen/lib/typescript");
15557
15647
  var import_ts_deepmerge = require("ts-deepmerge");
15558
15648
 
15649
+ // src/projects/monorepo-layout.ts
15650
+ var MONOREPO_LAYOUT = {
15651
+ DOCS: "docs",
15652
+ APPS: "apps",
15653
+ PACKAGES: "packages",
15654
+ SITES: "sites"
15655
+ };
15656
+ var LAYOUT_ENFORCEMENT = {
15657
+ OFF: "off",
15658
+ WARN: "warn",
15659
+ ERROR: "error"
15660
+ };
15661
+ var LAYOUT_ROOT_BY_PROJECT_TYPE = {
15662
+ TypeScriptProject: MONOREPO_LAYOUT.PACKAGES,
15663
+ AwsCdkProject: MONOREPO_LAYOUT.APPS,
15664
+ AstroProject: MONOREPO_LAYOUT.SITES,
15665
+ StarlightProject: MONOREPO_LAYOUT.DOCS
15666
+ };
15667
+ function validateMonorepoLayout(root) {
15668
+ const violations = [];
15669
+ const rootOutdir = toPosix(root.outdir);
15670
+ for (const sub of root.subprojects) {
15671
+ const className = sub.constructor.name;
15672
+ const expectedRoot = LAYOUT_ROOT_BY_PROJECT_TYPE[className];
15673
+ if (expectedRoot === void 0) {
15674
+ continue;
15675
+ }
15676
+ const relOutdir = relativeOutdir(rootOutdir, toPosix(sub.outdir));
15677
+ if (!outdirMatchesRoot(relOutdir, expectedRoot)) {
15678
+ violations.push({
15679
+ projectName: sub.name,
15680
+ projectType: className,
15681
+ outdir: relOutdir,
15682
+ expectedRoot
15683
+ });
15684
+ }
15685
+ }
15686
+ return violations;
15687
+ }
15688
+ function formatLayoutViolation(violation) {
15689
+ const { projectName, projectType, outdir, expectedRoot } = violation;
15690
+ const expectedExample = expectedRoot === MONOREPO_LAYOUT.DOCS ? "docs/" : `${expectedRoot}/<scope>/<name>`;
15691
+ return `[monorepo-layout] ${projectType} "${projectName}" has outdir "${outdir}", which is outside the expected root "${expectedRoot}/" (expected e.g. "${expectedExample}"). See docs/requirements/architectural-decisions/ADR-006-monorepo-layout.md.`;
15692
+ }
15693
+ function outdirMatchesRoot(relOutdir, expectedRoot) {
15694
+ const segments = relOutdir.split("/").filter((s) => s.length > 0);
15695
+ if (segments.length === 0) {
15696
+ return false;
15697
+ }
15698
+ if (segments[0] !== expectedRoot) {
15699
+ return false;
15700
+ }
15701
+ if (expectedRoot === MONOREPO_LAYOUT.DOCS) {
15702
+ return true;
15703
+ }
15704
+ return segments.length >= 2;
15705
+ }
15706
+ function toPosix(p) {
15707
+ return p.replace(/\\/g, "/");
15708
+ }
15709
+ function relativeOutdir(rootOutdir, subOutdir) {
15710
+ if (subOutdir === rootOutdir) {
15711
+ return "";
15712
+ }
15713
+ const prefix2 = rootOutdir.endsWith("/") ? rootOutdir : `${rootOutdir}/`;
15714
+ if (subOutdir.startsWith(prefix2)) {
15715
+ return subOutdir.slice(prefix2.length);
15716
+ }
15717
+ return subOutdir;
15718
+ }
15719
+
15559
15720
  // src/tasks/reset-task.ts
15560
15721
  var import_projen13 = require("projen");
15561
15722
  var ResetTask = class _ResetTask extends import_projen13.Component {
@@ -16064,6 +16225,11 @@ var MonorepoProject = class extends import_typescript3.TypeScriptAppProject {
16064
16225
  * By default treat as a registry consumer (upgrade workflow syncs configulator).
16065
16226
  */
16066
16227
  configulatorRegistryConsumer: true,
16228
+ /**
16229
+ * ADR-006 layout enforcement defaults to "warn" during rollout so
16230
+ * legacy outdirs log actionable warnings but do not break synth.
16231
+ */
16232
+ layoutEnforcement: LAYOUT_ENFORCEMENT.WARN,
16067
16233
  /**
16068
16234
  * We don't want sample code generated for the root project.
16069
16235
  */
@@ -16177,6 +16343,7 @@ var MonorepoProject = class extends import_typescript3.TypeScriptAppProject {
16177
16343
  this.tsconfig?.removeInclude(`${this.srcdir}/**/*.ts`);
16178
16344
  this.pnpmVersion = options.pnpmVersion;
16179
16345
  this.configulatorRegistryConsumer = options.configulatorRegistryConsumer ?? true;
16346
+ this.layoutEnforcement = options.layoutEnforcement ?? LAYOUT_ENFORCEMENT.WARN;
16180
16347
  new VSCodeConfig(this);
16181
16348
  new PnpmWorkspace(this, options.pnpmOptions?.pnpmWorkspaceOptions);
16182
16349
  if (options.turbo) {
@@ -16271,6 +16438,32 @@ var MonorepoProject = class extends import_typescript3.TypeScriptAppProject {
16271
16438
  );
16272
16439
  }
16273
16440
  }
16441
+ /**
16442
+ * Validate sub-project `outdir` values against the ADR-006 monorepo
16443
+ * layout contract. Runs in `preSynthesize` so all sub-projects are
16444
+ * attached by the time we inspect the tree.
16445
+ *
16446
+ * Behavior is controlled by `layoutEnforcement`:
16447
+ * - `"off"` — skip validation.
16448
+ * - `"warn"` — log a `console.warn` per violation; continue.
16449
+ * - `"error"` — throw on the first violation.
16450
+ */
16451
+ preSynthesize() {
16452
+ super.preSynthesize();
16453
+ if (this.layoutEnforcement === LAYOUT_ENFORCEMENT.OFF) {
16454
+ return;
16455
+ }
16456
+ const violations = validateMonorepoLayout(this);
16457
+ if (violations.length === 0) {
16458
+ return;
16459
+ }
16460
+ if (this.layoutEnforcement === LAYOUT_ENFORCEMENT.ERROR) {
16461
+ throw new Error(formatLayoutViolation(violations[0]));
16462
+ }
16463
+ for (const violation of violations) {
16464
+ console.warn(formatLayoutViolation(violation));
16465
+ }
16466
+ }
16274
16467
  /**
16275
16468
  * Allows a sub project to request installation of dependency at the Monorepo root
16276
16469
  * They must provide a function that is executed after dependencies have been installed
@@ -17388,10 +17581,13 @@ var TypeScriptConfig = class extends import_projen22.Component {
17388
17581
  DEFAULT_TEARDOWN_BRANCH_PATTERNS,
17389
17582
  DEFAULT_TYPE_LABELS,
17390
17583
  JsiiFaker,
17584
+ LAYOUT_ENFORCEMENT,
17585
+ LAYOUT_ROOT_BY_PROJECT_TYPE,
17391
17586
  MCP_TRANSPORT,
17392
17587
  MERGE_METHODS,
17393
17588
  MIMIMUM_RELEASE_AGE,
17394
17589
  MINIMUM_RELEASE_AGE,
17590
+ MONOREPO_LAYOUT,
17395
17591
  MonorepoProject,
17396
17592
  PROD_DEPLOY_NAME,
17397
17593
  PnpmWorkspace,
@@ -17418,6 +17614,7 @@ var TypeScriptConfig = class extends import_projen22.Component {
17418
17614
  baseBundle,
17419
17615
  bcmWriterBundle,
17420
17616
  companyProfileBundle,
17617
+ formatLayoutViolation,
17421
17618
  getLatestEligibleVersion,
17422
17619
  githubWorkflowBundle,
17423
17620
  industryDiscoveryBundle,
@@ -17439,6 +17636,7 @@ var TypeScriptConfig = class extends import_projen22.Component {
17439
17636
  softwareProfileBundle,
17440
17637
  turborepoBundle,
17441
17638
  typescriptBundle,
17639
+ validateMonorepoLayout,
17442
17640
  vitestBundle
17443
17641
  });
17444
17642
  //# sourceMappingURL=index.js.map