@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.mjs CHANGED
@@ -386,6 +386,122 @@ var awsCdkBundle = {
386
386
  };
387
387
 
388
388
  // src/agent/bundles/base.ts
389
+ var createPackageSkill = {
390
+ name: "create-package",
391
+ description: "Scaffold a new TypeScriptProject sub-project under packages/@scope/<name> by emitting the projen block to add to the monorepo config",
392
+ disableModelInvocation: true,
393
+ instructions: [
394
+ "# Create Package",
395
+ "",
396
+ "Scaffold a new shared-library sub-project at",
397
+ "`packages/@scope/<name>` by emitting the projen block to add to the",
398
+ "monorepo's projen configuration. This skill walks the user through",
399
+ "naming, metadata, and placement; it does **not** run projen, install",
400
+ "dependencies, or execute any build commands.",
401
+ "",
402
+ "## Usage",
403
+ "",
404
+ "```",
405
+ "/create-package @<scope>/<name>",
406
+ "```",
407
+ "",
408
+ "Example: `/create-package @codedrifters/my-lib` \u2192 scaffolds a new",
409
+ "`TypeScriptProject` at `packages/@codedrifters/my-lib`.",
410
+ "",
411
+ "## Steps",
412
+ "",
413
+ "1. **Parse and validate the package name.** The argument must be a",
414
+ " **scoped** npm name in the form `@<scope>/<name>`:",
415
+ " - Starts with `@`",
416
+ " - Has exactly one `/` separator",
417
+ " - `<scope>` and `<name>` are lowercase, kebab-case, non-empty",
418
+ " - Unscoped names (e.g. `my-lib`) are **not** allowed \u2014 every",
419
+ " package under `packages/` is scoped by owner.",
420
+ " If the input is missing or invalid, ask the user to supply a",
421
+ " scoped name. Do not guess the scope.",
422
+ "",
423
+ "2. **Collect metadata** \u2014 ask the user for each of the following,",
424
+ " one question at a time:",
425
+ " - **Description** \u2014 one-line summary of what the package does.",
426
+ " - **Publish to npm?** \u2014 `true` or `false`. Workspace-internal",
427
+ " libraries should answer `false`.",
428
+ " Skip any question the user has already answered in the initial",
429
+ " prompt.",
430
+ "",
431
+ "3. **Determine the target outdir.** The sub-project lives at:",
432
+ "",
433
+ " ```",
434
+ " packages/<scope>/<name>",
435
+ " ```",
436
+ "",
437
+ " `<scope>` is everything after `@` and before `/` in the package",
438
+ " name; `<name>` is everything after the `/`. This matches the",
439
+ " default `outdir` that `TypeScriptProject` computes from the",
440
+ " package name, so the emitted block does **not** need to set",
441
+ " `outdir` explicitly.",
442
+ "",
443
+ "4. **Locate the projen config file.** Prefer the monorepo's",
444
+ " `projenrc/` directory \u2014 most monorepos declare sub-projects",
445
+ " there (e.g. `projenrc/root-project.ts` or a dedicated",
446
+ " `projenrc/packages.ts`). Fall back to `.projenrc.ts` only when",
447
+ " no `projenrc/` directory exists.",
448
+ "",
449
+ "5. **Emit the projen block.** Show the TypeScript block to paste",
450
+ " into the chosen projen config file. Example for",
451
+ " `@codedrifters/my-lib`:",
452
+ "",
453
+ " ```typescript",
454
+ " import { TypeScriptProject } from '@codedrifters/configulator';",
455
+ "",
456
+ " // Inside the monorepo's configuration function, alongside",
457
+ " // sibling sub-projects:",
458
+ " new TypeScriptProject({",
459
+ " parent: monorepo,",
460
+ " name: '@codedrifters/my-lib',",
461
+ " description: '<one-line description>',",
462
+ " defaultReleaseBranch: 'main',",
463
+ " publishToNpm: false, // or true if this package publishes",
464
+ " });",
465
+ " ```",
466
+ "",
467
+ " Substitute the user's scope, name, description, and",
468
+ " `publishToNpm` value. Do not hard-code `outdir` \u2014 the default",
469
+ " places the sub-project at `packages/<scope>/<name>`.",
470
+ "",
471
+ "6. **Tell the user how to synthesize.** Instruct them to run, from",
472
+ " the repo root:",
473
+ "",
474
+ " ```",
475
+ " pnpm exec projen",
476
+ " pnpm install",
477
+ " ```",
478
+ "",
479
+ " `pnpm exec projen` regenerates the sub-project tree;",
480
+ " `pnpm install` updates the workspace lockfile. Do **not** run",
481
+ " these commands yourself \u2014 the user runs them.",
482
+ "",
483
+ "## Guardrails",
484
+ "",
485
+ "- Never run `pnpm exec projen`, `pnpm install`, `pnpm build`,",
486
+ " `pnpm test`, or any other package-manager, build, or test command.",
487
+ " Emit the projen block and instructions only.",
488
+ "- Never scaffold outside `packages/`. Deployable apps belong under",
489
+ " `apps/<scope>/<name>` (use `/create-app`); user-facing sites belong",
490
+ " under `sites/<scope>/<name>` (use `/create-site`).",
491
+ "- Never scope by category (e.g. `@libs/foo`, `@packages/foo`). The",
492
+ " scope identifies the **owning party**; the top-level folder",
493
+ " identifies the kind.",
494
+ "- Do not invent an `outdir` \u2014 rely on the `TypeScriptProject`",
495
+ " default that places the sub-project at `packages/<scope>/<name>`.",
496
+ "",
497
+ "## Related Skills",
498
+ "",
499
+ "- `/create-app` \u2014 scaffold a new `AwsCdkProject` under",
500
+ " `apps/<scope>/<name>`.",
501
+ "- `/create-site` \u2014 scaffold a new `AstroProject` under",
502
+ " `sites/<scope>/<name>`."
503
+ ].join("\n")
504
+ };
389
505
  var createRuleSkill = {
390
506
  name: "create-rule",
391
507
  description: "Guide for creating new agent rules in this project using configulator",
@@ -444,7 +560,7 @@ var baseBundle = {
444
560
  name: "base",
445
561
  description: "Core rules: project overview, interaction style, and general coding conventions",
446
562
  appliesWhen: () => true,
447
- skills: [createRuleSkill],
563
+ skills: [createPackageSkill, createRuleSkill],
448
564
  rules: [
449
565
  {
450
566
  name: "project-overview",
@@ -907,6 +1023,28 @@ var baseBundle = {
907
1023
 
908
1024
  // src/agent/bundles/project-context.ts
909
1025
  var PROJECT_CONTEXT_PATH = "docs/project-context.md";
1026
+ var SUBPROJECT_ROLE_GUIDANCE = [
1027
+ "### Sub-project roles",
1028
+ "",
1029
+ "When the repository follows the configulator monorepo layout,",
1030
+ "every sub-project's role is derivable from the first segment of",
1031
+ "its `outdir` path. No other lookup is required.",
1032
+ "",
1033
+ "- `apps/<scope>/<name>` \u2014 deployable application (CDK stack,",
1034
+ " mobile app, backend service).",
1035
+ "- `packages/<scope>/<name>` \u2014 shared library (published npm",
1036
+ " package or workspace-internal library).",
1037
+ "- `sites/<scope>/<name>` \u2014 user-facing web front end that is",
1038
+ " not the monorepo-wide docs site.",
1039
+ "- `docs/` \u2014 the single Starlight documentation site for the",
1040
+ " whole monorepo (exactly one per repo; lives at `/docs`, not",
1041
+ " under `sites/`).",
1042
+ "",
1043
+ "Repositories that have not adopted the layout contract may use a",
1044
+ "different folder structure \u2014 in that case fall back to whatever",
1045
+ `\`${PROJECT_CONTEXT_PATH}\` documents explicitly.`,
1046
+ ""
1047
+ ];
910
1048
  var PROJECT_CONTEXT_READER_SECTION = [
911
1049
  "## Project Context",
912
1050
  "",
@@ -921,6 +1059,7 @@ var PROJECT_CONTEXT_READER_SECTION = [
921
1059
  "",
922
1060
  "You are a **read-only consumer** of this file. Do not edit it.",
923
1061
  "",
1062
+ ...SUBPROJECT_ROLE_GUIDANCE,
924
1063
  "---",
925
1064
  ""
926
1065
  ];
@@ -933,6 +1072,7 @@ var PROJECT_CONTEXT_MAINTAINER_SECTION = [
933
1072
  "key stakeholders. Use it to judge relevance when scanning source",
934
1073
  "material in this session.",
935
1074
  "",
1075
+ ...SUBPROJECT_ROLE_GUIDANCE,
936
1076
  "### Seed on first use",
937
1077
  "",
938
1078
  `If \`${PROJECT_CONTEXT_PATH}\` does not exist, create it from this`,
@@ -962,7 +1102,7 @@ var PROJECT_CONTEXT_MAINTAINER_SECTION = [
962
1102
  "",
963
1103
  "## Key Stakeholders",
964
1104
  "TODO: named people or teams and what they care about.",
965
- "",
1105
+ "{{monorepoLayoutSeedBlock}}",
966
1106
  "## References",
967
1107
  "TODO: links to BCM docs, competitive analysis, product roadmap, and",
968
1108
  "other authoritative sources.",
@@ -987,6 +1127,26 @@ var PROJECT_CONTEXT_MAINTAINER_SECTION = [
987
1127
  "---",
988
1128
  ""
989
1129
  ];
1130
+ var MONOREPO_LAYOUT_SEED_BLOCK = [
1131
+ "",
1132
+ "## Sub-Projects",
1133
+ "",
1134
+ "TODO: one bullet per sub-project, grouped by role. The role is",
1135
+ "derivable from the first segment of each sub-project's `outdir`.",
1136
+ "",
1137
+ "### Applications (`apps/`)",
1138
+ "TODO: deployable applications (CDK stacks, mobile apps, services).",
1139
+ "",
1140
+ "### Packages (`packages/`)",
1141
+ "TODO: shared libraries (published npm packages, workspace-internal libraries).",
1142
+ "",
1143
+ "### Sites (`sites/`)",
1144
+ "TODO: user-facing web front ends (marketing sites, SPAs, client apps).",
1145
+ "",
1146
+ "### Docs (`docs/`)",
1147
+ "TODO: the single monorepo-wide Starlight documentation site.",
1148
+ ""
1149
+ ].join("\n");
990
1150
 
991
1151
  // src/agent/bundles/bcm-writer.ts
992
1152
  var bcmWriterSubAgent = {
@@ -12513,9 +12673,30 @@ var ProjectMetadata = class _ProjectMetadata extends Component2 {
12513
12673
  labels: options.labels,
12514
12674
  milestones: options.milestones,
12515
12675
  docsPath: options.docsPath,
12516
- deployment: options.deployment
12676
+ deployment: options.deployment,
12677
+ monorepoLayoutSeedBlock: this.resolveMonorepoLayoutSeedBlock()
12517
12678
  };
12518
12679
  }
12680
+ /**
12681
+ * Return the maintainer-seed addendum for the `project-context`
12682
+ * bundle, or an empty string when the root project either has no
12683
+ * layout-enforcement opinion or has opted out (`layoutEnforcement:
12684
+ * "off"`).
12685
+ *
12686
+ * Uses duck-typing on the root project's `layoutEnforcement`
12687
+ * property to avoid a circular import with `MonorepoProject`. The
12688
+ * concrete `MonorepoProject` class exposes this property as a
12689
+ * string; anything else resolves to the empty string so repos that
12690
+ * predate the monorepo layout contract see no change.
12691
+ */
12692
+ resolveMonorepoLayoutSeedBlock() {
12693
+ const root = this.project.root;
12694
+ const enforcement = root.layoutEnforcement;
12695
+ if (typeof enforcement !== "string" || enforcement === "off") {
12696
+ return "";
12697
+ }
12698
+ return MONOREPO_LAYOUT_SEED_BLOCK;
12699
+ }
12519
12700
  /**
12520
12701
  * Attempts to auto-detect repository owner and name from the Projen
12521
12702
  * project's package.json repository field.
@@ -14535,7 +14716,12 @@ var FALLBACKS = {
14535
14716
  "githubProject.name": "<project-name>",
14536
14717
  "githubProject.number": "<project-number>",
14537
14718
  "githubProject.nodeId": "<project-node-id>",
14538
- docsPath: "<docs-path>"
14719
+ docsPath: "<docs-path>",
14720
+ // The monorepo-layout seed block is additive: when absent, the
14721
+ // seeded `project-context.md` template reads cleanly without it.
14722
+ // Fall back to an empty string so no placeholder text leaks into
14723
+ // rendered prompts for repos that predate the layout contract.
14724
+ monorepoLayoutSeedBlock: ""
14539
14725
  };
14540
14726
  var TEMPLATE_RE = /\{\{(\w+(?:\.\w+)*)\}\}/g;
14541
14727
  function getNestedValue(obj, path2) {