@codedrifters/configulator 0.0.213 → 0.0.214

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
@@ -6652,11 +6652,106 @@ var researchPipelineBundle = {
6652
6652
  ]
6653
6653
  };
6654
6654
 
6655
+ // src/projects/project-metadata.ts
6656
+ import { Component as Component2 } from "projen";
6657
+ import { NodeProject } from "projen/lib/javascript";
6658
+ var GITHUB_HTTPS_RE = /(?:https?:\/\/|git\+https:\/\/)github\.com\/([^/]+)\/([^/.]+)(?:\.git)?/;
6659
+ var GITHUB_SSH_RE = /git@github\.com:([^/]+)\/([^/.]+)(?:\.git)?/;
6660
+ function parseGitHubUrl(url) {
6661
+ const httpsMatch = url.match(GITHUB_HTTPS_RE);
6662
+ if (httpsMatch) {
6663
+ return { owner: httpsMatch[1], name: httpsMatch[2] };
6664
+ }
6665
+ const sshMatch = url.match(GITHUB_SSH_RE);
6666
+ if (sshMatch) {
6667
+ return { owner: sshMatch[1], name: sshMatch[2] };
6668
+ }
6669
+ return { owner: void 0, name: void 0 };
6670
+ }
6671
+ var ProjectMetadata = class _ProjectMetadata extends Component2 {
6672
+ /**
6673
+ * Returns the ProjectMetadata instance for a project. Walks up the parent
6674
+ * chain so sub-projects resolve the metadata declared on a root
6675
+ * `MonorepoProject` without needing a duplicate declaration of their own.
6676
+ * Returns `undefined` if no ancestor has a `ProjectMetadata` component.
6677
+ */
6678
+ static of(project) {
6679
+ const isProjectMetadata = (c) => c instanceof _ProjectMetadata;
6680
+ let current = project;
6681
+ while (current) {
6682
+ const found = current.components.find(isProjectMetadata);
6683
+ if (found) {
6684
+ return found;
6685
+ }
6686
+ current = current.parent;
6687
+ }
6688
+ return void 0;
6689
+ }
6690
+ constructor(project, options = {}) {
6691
+ super(project);
6692
+ this.metadata = this.resolveMetadata(options);
6693
+ }
6694
+ /**
6695
+ * Merges explicit options with auto-detected values.
6696
+ * Auto-detection reads the repository URL from package.json
6697
+ * (via Projen's NodePackage manifest) and parses GitHub owner/name.
6698
+ * Explicit options always take precedence over auto-detected values.
6699
+ */
6700
+ resolveMetadata(options) {
6701
+ const autoDetected = this.autoDetectRepository();
6702
+ return {
6703
+ repository: {
6704
+ owner: options.repository?.owner ?? autoDetected.owner,
6705
+ name: options.repository?.name ?? autoDetected.name,
6706
+ defaultBranch: options.repository?.defaultBranch ?? "main"
6707
+ },
6708
+ githubProject: options.githubProject,
6709
+ organization: options.organization,
6710
+ slack: options.slack,
6711
+ labels: options.labels,
6712
+ milestones: options.milestones,
6713
+ docsPath: options.docsPath,
6714
+ deployment: options.deployment
6715
+ };
6716
+ }
6717
+ /**
6718
+ * Attempts to auto-detect repository owner and name from the Projen
6719
+ * project's package.json repository field.
6720
+ */
6721
+ autoDetectRepository() {
6722
+ if (!(this.project instanceof NodeProject)) {
6723
+ return { owner: void 0, name: void 0 };
6724
+ }
6725
+ const manifest = this.project.package.manifest;
6726
+ const repoField = manifest.repository;
6727
+ if (!repoField) {
6728
+ return { owner: void 0, name: void 0 };
6729
+ }
6730
+ const url = typeof repoField === "string" ? repoField : repoField.url ?? "";
6731
+ return parseGitHubUrl(url);
6732
+ }
6733
+ };
6734
+
6655
6735
  // src/agent/bundles/slack.ts
6736
+ function hasSlackConfig(slack) {
6737
+ if (!slack) {
6738
+ return false;
6739
+ }
6740
+ if (slack.projectChannel || slack.alertsChannel) {
6741
+ return true;
6742
+ }
6743
+ if (slack.channels && Object.keys(slack.channels).length > 0) {
6744
+ return true;
6745
+ }
6746
+ return false;
6747
+ }
6656
6748
  var slackBundle = {
6657
6749
  name: "slack",
6658
- description: "Slack MCP message formatting and best practices",
6659
- appliesWhen: () => false,
6750
+ description: "Slack MCP message formatting and best practices. Auto-activates when ProjectMetadata declares a Slack integration; can still be force-included via `includeBundles: ['slack']`.",
6751
+ appliesWhen: (project) => {
6752
+ const pm = ProjectMetadata.of(project);
6753
+ return hasSlackConfig(pm?.metadata.slack);
6754
+ },
6660
6755
  rules: [
6661
6756
  {
6662
6757
  name: "slack-message-formatting",
@@ -6685,7 +6780,11 @@ var slackBundle = {
6685
6780
  " \u2022 Feature B: <https://github.com/org/repo/pull/2|repo#2>",
6686
6781
  " ```",
6687
6782
  "",
6688
- "5. **Avoid:** Plain URLs immediately after a bullet/label on the same line (e.g., `\u2022 Feature A: https://github.com/...`) when sending via API, as it can render with bullets inside or between links"
6783
+ "5. **Avoid:** Plain URLs immediately after a bullet/label on the same line (e.g., `\u2022 Feature A: https://github.com/...`) when sending via API, as it can render with bullets inside or between links",
6784
+ "",
6785
+ "## Activation",
6786
+ "",
6787
+ "This bundle auto-activates when the consuming project declares a Slack integration through `ProjectMetadata` (any of `slack.projectChannel`, `slack.alertsChannel`, or a non-empty `slack.channels` record). If no `ProjectMetadata` is configured, opt in manually via `AgentConfigOptions.includeBundles: ['slack']`."
6689
6788
  ].join("\n"),
6690
6789
  tags: ["workflow"]
6691
6790
  }
@@ -7310,12 +7409,12 @@ var softwareProfileBundle = {
7310
7409
  };
7311
7410
 
7312
7411
  // src/turbo/turbo-repo.ts
7313
- import { Component as Component3, FileBase, JsonFile } from "projen/lib";
7412
+ import { Component as Component4, FileBase, JsonFile } from "projen/lib";
7314
7413
  import { JobPermission } from "projen/lib/github/workflows-model";
7315
7414
 
7316
7415
  // src/turbo/turbo-repo-task.ts
7317
- import { Component as Component2 } from "projen/lib";
7318
- var TurboRepoTask = class extends Component2 {
7416
+ import { Component as Component3 } from "projen/lib";
7417
+ var TurboRepoTask = class extends Component3 {
7319
7418
  constructor(project, options) {
7320
7419
  super(project);
7321
7420
  this.project = project;
@@ -7356,7 +7455,7 @@ var TurboRepoTask = class extends Component2 {
7356
7455
  // src/turbo/turbo-repo.ts
7357
7456
  var ROOT_TURBO_TASK_NAME = "turbo:build";
7358
7457
  var ROOT_CI_TASK_NAME = "build:all";
7359
- var _TurboRepo = class _TurboRepo extends Component3 {
7458
+ var _TurboRepo = class _TurboRepo extends Component4 {
7360
7459
  constructor(project, options = {}) {
7361
7460
  super(project);
7362
7461
  this.project = project;
@@ -7682,7 +7781,7 @@ var typescriptBundle = {
7682
7781
  };
7683
7782
 
7684
7783
  // src/vitest/vitest-component.ts
7685
- import { Component as Component4 } from "projen";
7784
+ import { Component as Component5 } from "projen";
7686
7785
  import { Jest } from "projen/lib/javascript";
7687
7786
  import { TextFile } from "projen/lib/textfile";
7688
7787
 
@@ -7761,7 +7860,7 @@ var VERSION = {
7761
7860
  };
7762
7861
 
7763
7862
  // src/vitest/vitest-component.ts
7764
- var Vitest = class _Vitest extends Component4 {
7863
+ var Vitest = class _Vitest extends Component5 {
7765
7864
  constructor(project, options = {}) {
7766
7865
  super(project);
7767
7866
  this.project = project;
@@ -7961,86 +8060,6 @@ function prefix(rel, entry) {
7961
8060
  return path.posix.join(rel, entry);
7962
8061
  }
7963
8062
 
7964
- // src/projects/project-metadata.ts
7965
- import { Component as Component5 } from "projen";
7966
- import { NodeProject as NodeProject2 } from "projen/lib/javascript";
7967
- var GITHUB_HTTPS_RE = /(?:https?:\/\/|git\+https:\/\/)github\.com\/([^/]+)\/([^/.]+)(?:\.git)?/;
7968
- var GITHUB_SSH_RE = /git@github\.com:([^/]+)\/([^/.]+)(?:\.git)?/;
7969
- function parseGitHubUrl(url) {
7970
- const httpsMatch = url.match(GITHUB_HTTPS_RE);
7971
- if (httpsMatch) {
7972
- return { owner: httpsMatch[1], name: httpsMatch[2] };
7973
- }
7974
- const sshMatch = url.match(GITHUB_SSH_RE);
7975
- if (sshMatch) {
7976
- return { owner: sshMatch[1], name: sshMatch[2] };
7977
- }
7978
- return { owner: void 0, name: void 0 };
7979
- }
7980
- var ProjectMetadata = class _ProjectMetadata extends Component5 {
7981
- /**
7982
- * Returns the ProjectMetadata instance for a project. Walks up the parent
7983
- * chain so sub-projects resolve the metadata declared on a root
7984
- * `MonorepoProject` without needing a duplicate declaration of their own.
7985
- * Returns `undefined` if no ancestor has a `ProjectMetadata` component.
7986
- */
7987
- static of(project) {
7988
- const isProjectMetadata = (c) => c instanceof _ProjectMetadata;
7989
- let current = project;
7990
- while (current) {
7991
- const found = current.components.find(isProjectMetadata);
7992
- if (found) {
7993
- return found;
7994
- }
7995
- current = current.parent;
7996
- }
7997
- return void 0;
7998
- }
7999
- constructor(project, options = {}) {
8000
- super(project);
8001
- this.metadata = this.resolveMetadata(options);
8002
- }
8003
- /**
8004
- * Merges explicit options with auto-detected values.
8005
- * Auto-detection reads the repository URL from package.json
8006
- * (via Projen's NodePackage manifest) and parses GitHub owner/name.
8007
- * Explicit options always take precedence over auto-detected values.
8008
- */
8009
- resolveMetadata(options) {
8010
- const autoDetected = this.autoDetectRepository();
8011
- return {
8012
- repository: {
8013
- owner: options.repository?.owner ?? autoDetected.owner,
8014
- name: options.repository?.name ?? autoDetected.name,
8015
- defaultBranch: options.repository?.defaultBranch ?? "main"
8016
- },
8017
- githubProject: options.githubProject,
8018
- organization: options.organization,
8019
- slack: options.slack,
8020
- labels: options.labels,
8021
- milestones: options.milestones,
8022
- docsPath: options.docsPath,
8023
- deployment: options.deployment
8024
- };
8025
- }
8026
- /**
8027
- * Attempts to auto-detect repository owner and name from the Projen
8028
- * project's package.json repository field.
8029
- */
8030
- autoDetectRepository() {
8031
- if (!(this.project instanceof NodeProject2)) {
8032
- return { owner: void 0, name: void 0 };
8033
- }
8034
- const manifest = this.project.package.manifest;
8035
- const repoField = manifest.repository;
8036
- if (!repoField) {
8037
- return { owner: void 0, name: void 0 };
8038
- }
8039
- const url = typeof repoField === "string" ? repoField : repoField.url ?? "";
8040
- return parseGitHubUrl(url);
8041
- }
8042
- };
8043
-
8044
8063
  // src/agent/renderers/claude-renderer.ts
8045
8064
  import { JsonFile as JsonFile2 } from "projen";
8046
8065
  import { TextFile as TextFile2 } from "projen/lib/textfile";