@codedrifters/configulator 0.0.244 → 0.0.246

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
@@ -1534,6 +1534,14 @@ interface ResolvedProjectMetadata {
1534
1534
  readonly milestones?: ReadonlyArray<string>;
1535
1535
  readonly docsPath?: string;
1536
1536
  readonly deployment?: DeploymentMetadata;
1537
+ /**
1538
+ * Markdown block appended to the `project-context` maintainer seed
1539
+ * template. Resolved to the grouped sub-project list skeleton when
1540
+ * the root project is a `MonorepoProject` with layout enforcement
1541
+ * on (`layoutEnforcement !== "off"`); empty otherwise. Consumed by
1542
+ * the `{{monorepoLayoutSeedBlock}}` template variable.
1543
+ */
1544
+ readonly monorepoLayoutSeedBlock?: string;
1537
1545
  }
1538
1546
 
1539
1547
  /**
@@ -3636,6 +3644,19 @@ declare class ProjectMetadata extends Component {
3636
3644
  * Explicit options always take precedence over auto-detected values.
3637
3645
  */
3638
3646
  private resolveMetadata;
3647
+ /**
3648
+ * Return the maintainer-seed addendum for the `project-context`
3649
+ * bundle, or an empty string when the root project either has no
3650
+ * layout-enforcement opinion or has opted out (`layoutEnforcement:
3651
+ * "off"`).
3652
+ *
3653
+ * Uses duck-typing on the root project's `layoutEnforcement`
3654
+ * property to avoid a circular import with `MonorepoProject`. The
3655
+ * concrete `MonorepoProject` class exposes this property as a
3656
+ * string; anything else resolves to the empty string so repos that
3657
+ * predate the monorepo layout contract see no change.
3658
+ */
3659
+ private resolveMonorepoLayoutSeedBlock;
3639
3660
  /**
3640
3661
  * Attempts to auto-detect repository owner and name from the Projen
3641
3662
  * project's package.json repository field.
package/lib/index.d.ts CHANGED
@@ -1583,6 +1583,14 @@ interface ResolvedProjectMetadata {
1583
1583
  readonly milestones?: ReadonlyArray<string>;
1584
1584
  readonly docsPath?: string;
1585
1585
  readonly deployment?: DeploymentMetadata;
1586
+ /**
1587
+ * Markdown block appended to the `project-context` maintainer seed
1588
+ * template. Resolved to the grouped sub-project list skeleton when
1589
+ * the root project is a `MonorepoProject` with layout enforcement
1590
+ * on (`layoutEnforcement !== "off"`); empty otherwise. Consumed by
1591
+ * the `{{monorepoLayoutSeedBlock}}` template variable.
1592
+ */
1593
+ readonly monorepoLayoutSeedBlock?: string;
1586
1594
  }
1587
1595
 
1588
1596
  /**
@@ -3685,6 +3693,19 @@ declare class ProjectMetadata extends Component {
3685
3693
  * Explicit options always take precedence over auto-detected values.
3686
3694
  */
3687
3695
  private resolveMetadata;
3696
+ /**
3697
+ * Return the maintainer-seed addendum for the `project-context`
3698
+ * bundle, or an empty string when the root project either has no
3699
+ * layout-enforcement opinion or has opted out (`layoutEnforcement:
3700
+ * "off"`).
3701
+ *
3702
+ * Uses duck-typing on the root project's `layoutEnforcement`
3703
+ * property to avoid a circular import with `MonorepoProject`. The
3704
+ * concrete `MonorepoProject` class exposes this property as a
3705
+ * string; anything else resolves to the empty string so repos that
3706
+ * predate the monorepo layout contract see no change.
3707
+ */
3708
+ private resolveMonorepoLayoutSeedBlock;
3688
3709
  /**
3689
3710
  * Attempts to auto-detect repository owner and name from the Projen
3690
3711
  * project's package.json repository field.
package/lib/index.js CHANGED
@@ -476,6 +476,122 @@ var awsCdkBundle = {
476
476
  };
477
477
 
478
478
  // src/agent/bundles/base.ts
479
+ var createPackageSkill = {
480
+ name: "create-package",
481
+ description: "Scaffold a new TypeScriptProject sub-project under packages/@scope/<name> by emitting the projen block to add to the monorepo config",
482
+ disableModelInvocation: true,
483
+ instructions: [
484
+ "# Create Package",
485
+ "",
486
+ "Scaffold a new shared-library sub-project at",
487
+ "`packages/@scope/<name>` by emitting the projen block to add to the",
488
+ "monorepo's projen configuration. This skill walks the user through",
489
+ "naming, metadata, and placement; it does **not** run projen, install",
490
+ "dependencies, or execute any build commands.",
491
+ "",
492
+ "## Usage",
493
+ "",
494
+ "```",
495
+ "/create-package @<scope>/<name>",
496
+ "```",
497
+ "",
498
+ "Example: `/create-package @codedrifters/my-lib` \u2192 scaffolds a new",
499
+ "`TypeScriptProject` at `packages/@codedrifters/my-lib`.",
500
+ "",
501
+ "## Steps",
502
+ "",
503
+ "1. **Parse and validate the package name.** The argument must be a",
504
+ " **scoped** npm name in the form `@<scope>/<name>`:",
505
+ " - Starts with `@`",
506
+ " - Has exactly one `/` separator",
507
+ " - `<scope>` and `<name>` are lowercase, kebab-case, non-empty",
508
+ " - Unscoped names (e.g. `my-lib`) are **not** allowed \u2014 every",
509
+ " package under `packages/` is scoped by owner.",
510
+ " If the input is missing or invalid, ask the user to supply a",
511
+ " scoped name. Do not guess the scope.",
512
+ "",
513
+ "2. **Collect metadata** \u2014 ask the user for each of the following,",
514
+ " one question at a time:",
515
+ " - **Description** \u2014 one-line summary of what the package does.",
516
+ " - **Publish to npm?** \u2014 `true` or `false`. Workspace-internal",
517
+ " libraries should answer `false`.",
518
+ " Skip any question the user has already answered in the initial",
519
+ " prompt.",
520
+ "",
521
+ "3. **Determine the target outdir.** The sub-project lives at:",
522
+ "",
523
+ " ```",
524
+ " packages/<scope>/<name>",
525
+ " ```",
526
+ "",
527
+ " `<scope>` is everything after `@` and before `/` in the package",
528
+ " name; `<name>` is everything after the `/`. This matches the",
529
+ " default `outdir` that `TypeScriptProject` computes from the",
530
+ " package name, so the emitted block does **not** need to set",
531
+ " `outdir` explicitly.",
532
+ "",
533
+ "4. **Locate the projen config file.** Prefer the monorepo's",
534
+ " `projenrc/` directory \u2014 most monorepos declare sub-projects",
535
+ " there (e.g. `projenrc/root-project.ts` or a dedicated",
536
+ " `projenrc/packages.ts`). Fall back to `.projenrc.ts` only when",
537
+ " no `projenrc/` directory exists.",
538
+ "",
539
+ "5. **Emit the projen block.** Show the TypeScript block to paste",
540
+ " into the chosen projen config file. Example for",
541
+ " `@codedrifters/my-lib`:",
542
+ "",
543
+ " ```typescript",
544
+ " import { TypeScriptProject } from '@codedrifters/configulator';",
545
+ "",
546
+ " // Inside the monorepo's configuration function, alongside",
547
+ " // sibling sub-projects:",
548
+ " new TypeScriptProject({",
549
+ " parent: monorepo,",
550
+ " name: '@codedrifters/my-lib',",
551
+ " description: '<one-line description>',",
552
+ " defaultReleaseBranch: 'main',",
553
+ " publishToNpm: false, // or true if this package publishes",
554
+ " });",
555
+ " ```",
556
+ "",
557
+ " Substitute the user's scope, name, description, and",
558
+ " `publishToNpm` value. Do not hard-code `outdir` \u2014 the default",
559
+ " places the sub-project at `packages/<scope>/<name>`.",
560
+ "",
561
+ "6. **Tell the user how to synthesize.** Instruct them to run, from",
562
+ " the repo root:",
563
+ "",
564
+ " ```",
565
+ " pnpm exec projen",
566
+ " pnpm install",
567
+ " ```",
568
+ "",
569
+ " `pnpm exec projen` regenerates the sub-project tree;",
570
+ " `pnpm install` updates the workspace lockfile. Do **not** run",
571
+ " these commands yourself \u2014 the user runs them.",
572
+ "",
573
+ "## Guardrails",
574
+ "",
575
+ "- Never run `pnpm exec projen`, `pnpm install`, `pnpm build`,",
576
+ " `pnpm test`, or any other package-manager, build, or test command.",
577
+ " Emit the projen block and instructions only.",
578
+ "- Never scaffold outside `packages/`. Deployable apps belong under",
579
+ " `apps/<scope>/<name>` (use `/create-app`); user-facing sites belong",
580
+ " under `sites/<scope>/<name>` (use `/create-site`).",
581
+ "- Never scope by category (e.g. `@libs/foo`, `@packages/foo`). The",
582
+ " scope identifies the **owning party**; the top-level folder",
583
+ " identifies the kind.",
584
+ "- Do not invent an `outdir` \u2014 rely on the `TypeScriptProject`",
585
+ " default that places the sub-project at `packages/<scope>/<name>`.",
586
+ "",
587
+ "## Related Skills",
588
+ "",
589
+ "- `/create-app` \u2014 scaffold a new `AwsCdkProject` under",
590
+ " `apps/<scope>/<name>`.",
591
+ "- `/create-site` \u2014 scaffold a new `AstroProject` under",
592
+ " `sites/<scope>/<name>`."
593
+ ].join("\n")
594
+ };
479
595
  var createRuleSkill = {
480
596
  name: "create-rule",
481
597
  description: "Guide for creating new agent rules in this project using configulator",
@@ -534,7 +650,7 @@ var baseBundle = {
534
650
  name: "base",
535
651
  description: "Core rules: project overview, interaction style, and general coding conventions",
536
652
  appliesWhen: () => true,
537
- skills: [createRuleSkill],
653
+ skills: [createPackageSkill, createRuleSkill],
538
654
  rules: [
539
655
  {
540
656
  name: "project-overview",
@@ -997,6 +1113,28 @@ var baseBundle = {
997
1113
 
998
1114
  // src/agent/bundles/project-context.ts
999
1115
  var PROJECT_CONTEXT_PATH = "docs/project-context.md";
1116
+ var SUBPROJECT_ROLE_GUIDANCE = [
1117
+ "### Sub-project roles",
1118
+ "",
1119
+ "When the repository follows the configulator monorepo layout,",
1120
+ "every sub-project's role is derivable from the first segment of",
1121
+ "its `outdir` path. No other lookup is required.",
1122
+ "",
1123
+ "- `apps/<scope>/<name>` \u2014 deployable application (CDK stack,",
1124
+ " mobile app, backend service).",
1125
+ "- `packages/<scope>/<name>` \u2014 shared library (published npm",
1126
+ " package or workspace-internal library).",
1127
+ "- `sites/<scope>/<name>` \u2014 user-facing web front end that is",
1128
+ " not the monorepo-wide docs site.",
1129
+ "- `docs/` \u2014 the single Starlight documentation site for the",
1130
+ " whole monorepo (exactly one per repo; lives at `/docs`, not",
1131
+ " under `sites/`).",
1132
+ "",
1133
+ "Repositories that have not adopted the layout contract may use a",
1134
+ "different folder structure \u2014 in that case fall back to whatever",
1135
+ `\`${PROJECT_CONTEXT_PATH}\` documents explicitly.`,
1136
+ ""
1137
+ ];
1000
1138
  var PROJECT_CONTEXT_READER_SECTION = [
1001
1139
  "## Project Context",
1002
1140
  "",
@@ -1011,6 +1149,7 @@ var PROJECT_CONTEXT_READER_SECTION = [
1011
1149
  "",
1012
1150
  "You are a **read-only consumer** of this file. Do not edit it.",
1013
1151
  "",
1152
+ ...SUBPROJECT_ROLE_GUIDANCE,
1014
1153
  "---",
1015
1154
  ""
1016
1155
  ];
@@ -1023,6 +1162,7 @@ var PROJECT_CONTEXT_MAINTAINER_SECTION = [
1023
1162
  "key stakeholders. Use it to judge relevance when scanning source",
1024
1163
  "material in this session.",
1025
1164
  "",
1165
+ ...SUBPROJECT_ROLE_GUIDANCE,
1026
1166
  "### Seed on first use",
1027
1167
  "",
1028
1168
  `If \`${PROJECT_CONTEXT_PATH}\` does not exist, create it from this`,
@@ -1052,7 +1192,7 @@ var PROJECT_CONTEXT_MAINTAINER_SECTION = [
1052
1192
  "",
1053
1193
  "## Key Stakeholders",
1054
1194
  "TODO: named people or teams and what they care about.",
1055
- "",
1195
+ "{{monorepoLayoutSeedBlock}}",
1056
1196
  "## References",
1057
1197
  "TODO: links to BCM docs, competitive analysis, product roadmap, and",
1058
1198
  "other authoritative sources.",
@@ -1077,6 +1217,26 @@ var PROJECT_CONTEXT_MAINTAINER_SECTION = [
1077
1217
  "---",
1078
1218
  ""
1079
1219
  ];
1220
+ var MONOREPO_LAYOUT_SEED_BLOCK = [
1221
+ "",
1222
+ "## Sub-Projects",
1223
+ "",
1224
+ "TODO: one bullet per sub-project, grouped by role. The role is",
1225
+ "derivable from the first segment of each sub-project's `outdir`.",
1226
+ "",
1227
+ "### Applications (`apps/`)",
1228
+ "TODO: deployable applications (CDK stacks, mobile apps, services).",
1229
+ "",
1230
+ "### Packages (`packages/`)",
1231
+ "TODO: shared libraries (published npm packages, workspace-internal libraries).",
1232
+ "",
1233
+ "### Sites (`sites/`)",
1234
+ "TODO: user-facing web front ends (marketing sites, SPAs, client apps).",
1235
+ "",
1236
+ "### Docs (`docs/`)",
1237
+ "TODO: the single monorepo-wide Starlight documentation site.",
1238
+ ""
1239
+ ].join("\n");
1080
1240
 
1081
1241
  // src/agent/bundles/bcm-writer.ts
1082
1242
  var bcmWriterSubAgent = {
@@ -12603,9 +12763,30 @@ var ProjectMetadata = class _ProjectMetadata extends import_projen2.Component {
12603
12763
  labels: options.labels,
12604
12764
  milestones: options.milestones,
12605
12765
  docsPath: options.docsPath,
12606
- deployment: options.deployment
12766
+ deployment: options.deployment,
12767
+ monorepoLayoutSeedBlock: this.resolveMonorepoLayoutSeedBlock()
12607
12768
  };
12608
12769
  }
12770
+ /**
12771
+ * Return the maintainer-seed addendum for the `project-context`
12772
+ * bundle, or an empty string when the root project either has no
12773
+ * layout-enforcement opinion or has opted out (`layoutEnforcement:
12774
+ * "off"`).
12775
+ *
12776
+ * Uses duck-typing on the root project's `layoutEnforcement`
12777
+ * property to avoid a circular import with `MonorepoProject`. The
12778
+ * concrete `MonorepoProject` class exposes this property as a
12779
+ * string; anything else resolves to the empty string so repos that
12780
+ * predate the monorepo layout contract see no change.
12781
+ */
12782
+ resolveMonorepoLayoutSeedBlock() {
12783
+ const root = this.project.root;
12784
+ const enforcement = root.layoutEnforcement;
12785
+ if (typeof enforcement !== "string" || enforcement === "off") {
12786
+ return "";
12787
+ }
12788
+ return MONOREPO_LAYOUT_SEED_BLOCK;
12789
+ }
12609
12790
  /**
12610
12791
  * Attempts to auto-detect repository owner and name from the Projen
12611
12792
  * project's package.json repository field.
@@ -14625,7 +14806,12 @@ var FALLBACKS = {
14625
14806
  "githubProject.name": "<project-name>",
14626
14807
  "githubProject.number": "<project-number>",
14627
14808
  "githubProject.nodeId": "<project-node-id>",
14628
- docsPath: "<docs-path>"
14809
+ docsPath: "<docs-path>",
14810
+ // The monorepo-layout seed block is additive: when absent, the
14811
+ // seeded `project-context.md` template reads cleanly without it.
14812
+ // Fall back to an empty string so no placeholder text leaks into
14813
+ // rendered prompts for repos that predate the layout contract.
14814
+ monorepoLayoutSeedBlock: ""
14629
14815
  };
14630
14816
  var TEMPLATE_RE = /\{\{(\w+(?:\.\w+)*)\}\}/g;
14631
14817
  function getNestedValue(obj, path2) {