@codedrifters/configulator 0.0.177 → 0.0.179

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
@@ -204,23 +204,50 @@ var MCP_TRANSPORT = {
204
204
  };
205
205
 
206
206
  // src/agent/bundles/utils.ts
207
+ function findProjectsWithComponent(project, ctor) {
208
+ const out = [];
209
+ if (project.components.some((c) => c instanceof ctor)) {
210
+ out.push(project);
211
+ }
212
+ for (const sub of project.subprojects) {
213
+ if (sub.components.some((c) => c instanceof ctor)) {
214
+ out.push(sub);
215
+ }
216
+ }
217
+ return out;
218
+ }
219
+ function findProjectsWithDep(project, name) {
220
+ const out = [];
221
+ if (project.deps.all.some((d) => d.name === name)) {
222
+ out.push(project);
223
+ }
224
+ for (const sub of project.subprojects) {
225
+ if (sub.deps.all.some((d) => d.name === name)) {
226
+ out.push(sub);
227
+ }
228
+ }
229
+ return out;
230
+ }
231
+ function findProjectsWithFile(project, filename) {
232
+ const out = [];
233
+ if (project.tryFindFile(filename) !== void 0) {
234
+ out.push(project);
235
+ }
236
+ for (const sub of project.subprojects) {
237
+ if (sub.tryFindFile(filename) !== void 0) {
238
+ out.push(sub);
239
+ }
240
+ }
241
+ return out;
242
+ }
207
243
  function hasComponent(project, ctor) {
208
- if (project.components.some((c) => c instanceof ctor)) return true;
209
- return project.subprojects.some(
210
- (sub) => sub.components.some((c) => c instanceof ctor)
211
- );
244
+ return findProjectsWithComponent(project, ctor).length > 0;
212
245
  }
213
246
  function hasDep(project, name) {
214
- if (project.deps.all.some((d) => d.name === name)) return true;
215
- return project.subprojects.some(
216
- (sub) => sub.deps.all.some((d) => d.name === name)
217
- );
247
+ return findProjectsWithDep(project, name).length > 0;
218
248
  }
219
249
  function hasFile(project, filename) {
220
- if (project.tryFindFile(filename) !== void 0) return true;
221
- return project.subprojects.some(
222
- (sub) => sub.tryFindFile(filename) !== void 0
223
- );
250
+ return findProjectsWithFile(project, filename).length > 0;
224
251
  }
225
252
 
226
253
  // src/agent/bundles/aws-cdk.ts
@@ -228,6 +255,7 @@ var awsCdkBundle = {
228
255
  name: "aws-cdk",
229
256
  description: "AWS CDK construct patterns, L2/L3 conventions, IAM best practices",
230
257
  appliesWhen: (project) => hasDep(project, "aws-cdk-lib"),
258
+ findApplicableProjects: (project) => findProjectsWithDep(project, "aws-cdk-lib"),
231
259
  rules: [
232
260
  {
233
261
  name: "aws-cdk-conventions",
@@ -859,6 +887,7 @@ var jestBundle = {
859
887
  name: "jest",
860
888
  description: "Jest testing conventions and patterns",
861
889
  appliesWhen: (project) => hasDep(project, "jest"),
890
+ findApplicableProjects: (project) => findProjectsWithDep(project, "jest"),
862
891
  rules: [
863
892
  {
864
893
  name: "jest-testing",
@@ -1645,6 +1674,7 @@ var typescriptBundle = {
1645
1674
  name: "typescript",
1646
1675
  description: "TypeScript conventions, type safety, naming, JSDoc, member ordering",
1647
1676
  appliesWhen: (project) => hasFile(project, "tsconfig.json"),
1677
+ findApplicableProjects: (project) => findProjectsWithFile(project, "tsconfig.json"),
1648
1678
  rules: [
1649
1679
  {
1650
1680
  name: "typescript-conventions",
@@ -1862,6 +1892,7 @@ var vitestBundle = {
1862
1892
  name: "vitest",
1863
1893
  description: "Vitest testing conventions, patterns, and file scoping",
1864
1894
  appliesWhen: (project) => hasComponent(project, Vitest),
1895
+ findApplicableProjects: (project) => findProjectsWithComponent(project, Vitest),
1865
1896
  rules: [
1866
1897
  {
1867
1898
  name: "vitest-testing",
@@ -1931,6 +1962,38 @@ var BUILT_IN_BUNDLES = [
1931
1962
  slackBundle
1932
1963
  ];
1933
1964
 
1965
+ // src/agent/bundles/scope.ts
1966
+ import * as path from "path";
1967
+ function scopeFilePatternsToProjects(root, detected) {
1968
+ const patterns = /* @__PURE__ */ new Set();
1969
+ for (const project of detected) {
1970
+ const rel = path.relative(root.outdir, project.outdir);
1971
+ const include = readTsconfigInclude(project);
1972
+ if (include && include.length > 0) {
1973
+ for (const entry of include) {
1974
+ patterns.add(prefix(rel, entry));
1975
+ }
1976
+ } else {
1977
+ const srcdir = project.srcdir ?? "src";
1978
+ patterns.add(prefix(rel, path.posix.join(srcdir, "**/*.ts")));
1979
+ }
1980
+ }
1981
+ return [...patterns].sort();
1982
+ }
1983
+ function readTsconfigInclude(project) {
1984
+ const tsconfig = project.tsconfig;
1985
+ if (!tsconfig) {
1986
+ return void 0;
1987
+ }
1988
+ return tsconfig.include;
1989
+ }
1990
+ function prefix(rel, entry) {
1991
+ if (!rel) {
1992
+ return entry;
1993
+ }
1994
+ return path.posix.join(rel, entry);
1995
+ }
1996
+
1934
1997
  // src/projects/project-metadata.ts
1935
1998
  import { Component as Component5 } from "projen";
1936
1999
  import { NodeProject as NodeProject2 } from "projen/lib/javascript";
@@ -1949,12 +2012,22 @@ function parseGitHubUrl(url) {
1949
2012
  }
1950
2013
  var ProjectMetadata = class _ProjectMetadata extends Component5 {
1951
2014
  /**
1952
- * Returns the ProjectMetadata instance for a project, or undefined
1953
- * if the component has not been added.
2015
+ * Returns the ProjectMetadata instance for a project. Walks up the parent
2016
+ * chain so sub-projects resolve the metadata declared on a root
2017
+ * `MonorepoProject` without needing a duplicate declaration of their own.
2018
+ * Returns `undefined` if no ancestor has a `ProjectMetadata` component.
1954
2019
  */
1955
2020
  static of(project) {
1956
2021
  const isProjectMetadata = (c) => c instanceof _ProjectMetadata;
1957
- return project.components.find(isProjectMetadata);
2022
+ let current = project;
2023
+ while (current) {
2024
+ const found = current.components.find(isProjectMetadata);
2025
+ if (found) {
2026
+ return found;
2027
+ }
2028
+ current = current.parent;
2029
+ }
2030
+ return void 0;
1958
2031
  }
1959
2032
  constructor(project, options = {}) {
1960
2033
  super(project);
@@ -2503,8 +2576,8 @@ var FALLBACKS = {
2503
2576
  docsPath: "<docs-path>"
2504
2577
  };
2505
2578
  var TEMPLATE_RE = /\{\{(\w+(?:\.\w+)*)\}\}/g;
2506
- function getNestedValue(obj, path) {
2507
- const parts = path.split(".");
2579
+ function getNestedValue(obj, path2) {
2580
+ const parts = path2.split(".");
2508
2581
  let current = obj;
2509
2582
  for (const part of parts) {
2510
2583
  if (current == null || typeof current !== "object") {
@@ -2745,7 +2818,7 @@ var AgentConfig = class _AgentConfig extends Component8 {
2745
2818
  continue;
2746
2819
  }
2747
2820
  if (bundle.appliesWhen(this.project)) {
2748
- for (const rule of bundle.rules) {
2821
+ for (const rule of this.bundleRulesFor(bundle)) {
2749
2822
  ruleMap.set(rule.name, rule);
2750
2823
  }
2751
2824
  }
@@ -2755,7 +2828,7 @@ var AgentConfig = class _AgentConfig extends Component8 {
2755
2828
  for (const bundleName of this.options.includeBundles) {
2756
2829
  const bundle = BUILT_IN_BUNDLES.find((b) => b.name === bundleName);
2757
2830
  if (bundle) {
2758
- for (const rule of bundle.rules) {
2831
+ for (const rule of this.bundleRulesFor(bundle)) {
2759
2832
  ruleMap.set(rule.name, rule);
2760
2833
  }
2761
2834
  }
@@ -2795,6 +2868,25 @@ ${extra}`
2795
2868
  return a.name.localeCompare(b.name);
2796
2869
  });
2797
2870
  }
2871
+ /**
2872
+ * Return a bundle's rules with `filePatterns` narrowed to the projects
2873
+ * that actually matched the bundle's detection predicate (when the bundle
2874
+ * provides `findApplicableProjects`). Rules with `ALWAYS` scope and rules
2875
+ * on bundles that don't implement the hook are returned unchanged.
2876
+ */
2877
+ bundleRulesFor(bundle) {
2878
+ if (!bundle.findApplicableProjects) {
2879
+ return bundle.rules;
2880
+ }
2881
+ const detected = bundle.findApplicableProjects(this.project);
2882
+ if (detected.length === 0) {
2883
+ return bundle.rules;
2884
+ }
2885
+ const scoped = scopeFilePatternsToProjects(this.project, detected);
2886
+ return bundle.rules.map(
2887
+ (rule) => rule.scope === AGENT_RULE_SCOPE.FILE_PATTERN ? { ...rule, filePatterns: scoped } : rule
2888
+ );
2889
+ }
2798
2890
  resolveSkills() {
2799
2891
  const skillMap = /* @__PURE__ */ new Map();
2800
2892
  if (this.options.autoDetectBundles !== false) {
@@ -2923,7 +3015,7 @@ ${extra}`
2923
3015
 
2924
3016
  // src/aws/aws-deployment-config.ts
2925
3017
  var import_utils9 = __toESM(require_lib());
2926
- import { join, relative as relative2 } from "path";
3018
+ import { join, relative as relative3 } from "path";
2927
3019
  import { Component as Component9 } from "projen";
2928
3020
  var AwsDeploymentConfig = class _AwsDeploymentConfig extends Component9 {
2929
3021
  constructor(project) {
@@ -2949,8 +3041,8 @@ var AwsDeploymentConfig = class _AwsDeploymentConfig extends Component9 {
2949
3041
  this.env = {
2950
3042
  GIT_BRANCH_NAME: '$(echo "${GIT_BRANCH_NAME:-$(git branch --show-current)}")'
2951
3043
  };
2952
- this.projectPath = relative2(project.root.outdir, project.outdir);
2953
- this.rootPath = relative2(project.outdir, project.root.outdir);
3044
+ this.projectPath = relative3(project.root.outdir, project.outdir);
3045
+ this.rootPath = relative3(project.outdir, project.root.outdir);
2954
3046
  this.rootCdkOut = join("dist", this.projectPath, "cdk.out");
2955
3047
  this.cdkOut = join(this.rootPath, "dist", this.projectPath, "cdk.out");
2956
3048
  ["deploy", "watch"].forEach((taskName) => {
@@ -3459,15 +3551,11 @@ var TypeScriptProject = class extends typescript.TypeScriptProject {
3459
3551
  turbo.compileTask?.outputs.push("dist/**");
3460
3552
  turbo.compileTask?.outputs.push("lib/**");
3461
3553
  }
3462
- const parentHasAgentConfig = userOptions.parent instanceof MonorepoProject && AgentConfig.of(userOptions.parent) !== void 0;
3463
- if (options.agentConfig !== false) {
3464
- const shouldEnable = typeof options.agentConfig === "object" || options.agentConfig === true || parentHasAgentConfig;
3465
- if (shouldEnable) {
3466
- new AgentConfig(
3467
- this,
3468
- typeof options.agentConfig === "object" ? options.agentConfig : {}
3469
- );
3470
- }
3554
+ if (options.agentConfig === true || typeof options.agentConfig === "object") {
3555
+ new AgentConfig(
3556
+ this,
3557
+ typeof options.agentConfig === "object" ? options.agentConfig : {}
3558
+ );
3471
3559
  }
3472
3560
  if (options.resetTask !== false) {
3473
3561
  const defaultResetTaskOptions = {
@@ -3521,8 +3609,8 @@ var ResetTask = class _ResetTask extends Component12 {
3521
3609
  const resetTask = this.project.tasks.addTask(this.taskName, {
3522
3610
  description: "Delete build artifacts specified by pathsToRemove option, or artifactsDirectory if pathsToRemove is empty"
3523
3611
  });
3524
- this.pathsToRemove.forEach((path) => {
3525
- resetTask.exec(`[ -e "${path}" ] && rm -rf ${path} || true`);
3612
+ this.pathsToRemove.forEach((path2) => {
3613
+ resetTask.exec(`[ -e "${path2}" ] && rm -rf ${path2} || true`);
3526
3614
  });
3527
3615
  const rootHasTurbo = TurboRepo.of(this.project.root) !== void 0;
3528
3616
  const isSubproject = this.project !== this.project.root;
@@ -3837,7 +3925,11 @@ var MonorepoProject = class extends TypeScriptAppProject {
3837
3925
  */
3838
3926
  disableTsconfigDev: true,
3839
3927
  /**
3840
- * Kill the srcdir in the root since we aren't using one.
3928
+ * Kill the srcdir in the root since we aren't using one. Projen's
3929
+ * default `tsconfig.include` still points at `src/**\/*.ts`, so
3930
+ * callers that want to treat the monorepo root as a pure shell
3931
+ * should see an empty include — consumers add their own entries via
3932
+ * `tsconfig.addInclude(...)` (e.g. `.projenrc.ts`, `projenrc/**\/*.ts`).
3841
3933
  */
3842
3934
  tsconfig: {
3843
3935
  compilerOptions: {
@@ -3911,6 +4003,7 @@ var MonorepoProject = class extends TypeScriptAppProject {
3911
4003
  );
3912
4004
  super({ ...options });
3913
4005
  postInstallDependenciesMap.set(this, []);
4006
+ this.tsconfig?.removeInclude(`${this.srcdir}/**/*.ts`);
3914
4007
  this.pnpmVersion = options.pnpmVersion;
3915
4008
  this.configulatorRegistryConsumer = options.configulatorRegistryConsumer ?? true;
3916
4009
  new VSCodeConfig(this);
@@ -4029,7 +4122,7 @@ var MonorepoProject = class extends TypeScriptAppProject {
4029
4122
  };
4030
4123
 
4031
4124
  // src/typescript/typescript-config.ts
4032
- import { relative as relative3 } from "path";
4125
+ import { relative as relative4 } from "path";
4033
4126
  import { Component as Component14 } from "projen";
4034
4127
  import { ensureRelativePathStartsWithDot } from "projen/lib/util/path";
4035
4128
  var TypeScriptConfig = class extends Component14 {
@@ -4048,7 +4141,7 @@ var TypeScriptConfig = class extends Component14 {
4048
4141
  ...tsPaths,
4049
4142
  [dep.name]: [
4050
4143
  ensureRelativePathStartsWithDot(
4051
- relative3(project.outdir, subproject.outdir)
4144
+ relative4(project.outdir, subproject.outdir)
4052
4145
  )
4053
4146
  ]
4054
4147
  };
@@ -4120,9 +4213,9 @@ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component15 {
4120
4213
  for (const branch of branches) {
4121
4214
  const branchPattern = branch.branch;
4122
4215
  if (branchPattern.includes("*")) {
4123
- const prefix = branchPattern.replace(/\*.*$/, "");
4124
- conditions.push(`startsWith(github.ref, 'refs/heads/${prefix}')`);
4125
- conditions.push(`startsWith(github.head_ref, '${prefix}')`);
4216
+ const prefix2 = branchPattern.replace(/\*.*$/, "");
4217
+ conditions.push(`startsWith(github.ref, 'refs/heads/${prefix2}')`);
4218
+ conditions.push(`startsWith(github.head_ref, '${prefix2}')`);
4126
4219
  } else {
4127
4220
  conditions.push(`github.ref == 'refs/heads/${branchPattern}'`);
4128
4221
  }