@codedrifters/configulator 0.0.155 → 0.0.156

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
@@ -173,7 +173,7 @@ var require_lib = __commonJS({
173
173
  });
174
174
 
175
175
  // src/agent/agent-config.ts
176
- import { Component as Component7 } from "projen";
176
+ import { Component as Component8 } from "projen";
177
177
 
178
178
  // src/agent/types.ts
179
179
  var AGENT_RULE_SCOPE = {
@@ -296,6 +296,9 @@ var baseBundle = {
296
296
  content: [
297
297
  "# Project Overview",
298
298
  "",
299
+ "**Repository:** {{repository.owner}}/{{repository.name}}",
300
+ "**Default branch:** {{repository.defaultBranch}}",
301
+ "",
299
302
  "## Important Notes",
300
303
  "",
301
304
  "- **Never edit generated files** \u2014 they are marked with `// ~~ Generated by projen`",
@@ -1256,6 +1259,76 @@ var BUILT_IN_BUNDLES = [
1256
1259
  projenBundle
1257
1260
  ];
1258
1261
 
1262
+ // src/projects/project-metadata.ts
1263
+ import { Component as Component5 } from "projen";
1264
+ import { NodeProject as NodeProject2 } from "projen/lib/javascript";
1265
+ var GITHUB_HTTPS_RE = /(?:https?:\/\/|git\+https:\/\/)github\.com\/([^/]+)\/([^/.]+)(?:\.git)?/;
1266
+ var GITHUB_SSH_RE = /git@github\.com:([^/]+)\/([^/.]+)(?:\.git)?/;
1267
+ function parseGitHubUrl(url) {
1268
+ const httpsMatch = url.match(GITHUB_HTTPS_RE);
1269
+ if (httpsMatch) {
1270
+ return { owner: httpsMatch[1], name: httpsMatch[2] };
1271
+ }
1272
+ const sshMatch = url.match(GITHUB_SSH_RE);
1273
+ if (sshMatch) {
1274
+ return { owner: sshMatch[1], name: sshMatch[2] };
1275
+ }
1276
+ return { owner: void 0, name: void 0 };
1277
+ }
1278
+ var ProjectMetadata = class _ProjectMetadata extends Component5 {
1279
+ /**
1280
+ * Returns the ProjectMetadata instance for a project, or undefined
1281
+ * if the component has not been added.
1282
+ */
1283
+ static of(project) {
1284
+ const isProjectMetadata = (c) => c instanceof _ProjectMetadata;
1285
+ return project.components.find(isProjectMetadata);
1286
+ }
1287
+ constructor(project, options = {}) {
1288
+ super(project);
1289
+ this.metadata = this.resolveMetadata(options);
1290
+ }
1291
+ /**
1292
+ * Merges explicit options with auto-detected values.
1293
+ * Auto-detection reads the repository URL from package.json
1294
+ * (via Projen's NodePackage manifest) and parses GitHub owner/name.
1295
+ * Explicit options always take precedence over auto-detected values.
1296
+ */
1297
+ resolveMetadata(options) {
1298
+ const autoDetected = this.autoDetectRepository();
1299
+ return {
1300
+ repository: {
1301
+ owner: options.repository?.owner ?? autoDetected.owner,
1302
+ name: options.repository?.name ?? autoDetected.name,
1303
+ defaultBranch: options.repository?.defaultBranch ?? "main"
1304
+ },
1305
+ githubProject: options.githubProject,
1306
+ organization: options.organization,
1307
+ slack: options.slack,
1308
+ labels: options.labels,
1309
+ milestones: options.milestones,
1310
+ docsPath: options.docsPath,
1311
+ deployment: options.deployment
1312
+ };
1313
+ }
1314
+ /**
1315
+ * Attempts to auto-detect repository owner and name from the Projen
1316
+ * project's package.json repository field.
1317
+ */
1318
+ autoDetectRepository() {
1319
+ if (!(this.project instanceof NodeProject2)) {
1320
+ return { owner: void 0, name: void 0 };
1321
+ }
1322
+ const manifest = this.project.package.manifest;
1323
+ const repoField = manifest.repository;
1324
+ if (!repoField) {
1325
+ return { owner: void 0, name: void 0 };
1326
+ }
1327
+ const url = typeof repoField === "string" ? repoField : repoField.url ?? "";
1328
+ return parseGitHubUrl(url);
1329
+ }
1330
+ };
1331
+
1259
1332
  // src/agent/renderers/claude-renderer.ts
1260
1333
  import { JsonFile as JsonFile2 } from "projen";
1261
1334
  import { TextFile as TextFile2 } from "projen/lib/textfile";
@@ -1707,8 +1780,57 @@ var CursorRenderer = class _CursorRenderer {
1707
1780
  }
1708
1781
  };
1709
1782
 
1783
+ // src/agent/template-resolver.ts
1784
+ var FALLBACKS = {
1785
+ "repository.owner": "<owner>",
1786
+ "repository.name": "<repo>",
1787
+ "repository.defaultBranch": "main",
1788
+ "organization.name": "<organization>",
1789
+ "organization.githubOrg": "<org>",
1790
+ "githubProject.name": "<project-name>",
1791
+ "githubProject.number": "<project-number>",
1792
+ "githubProject.nodeId": "<project-node-id>",
1793
+ docsPath: "<docs-path>"
1794
+ };
1795
+ var TEMPLATE_RE = /\{\{(\w+(?:\.\w+)*)\}\}/g;
1796
+ function getNestedValue(obj, path) {
1797
+ const parts = path.split(".");
1798
+ let current = obj;
1799
+ for (const part of parts) {
1800
+ if (current == null || typeof current !== "object") {
1801
+ return void 0;
1802
+ }
1803
+ current = current[part];
1804
+ }
1805
+ if (current == null) {
1806
+ return void 0;
1807
+ }
1808
+ return String(current);
1809
+ }
1810
+ function resolveTemplateVariables(template, metadata) {
1811
+ if (!TEMPLATE_RE.test(template)) {
1812
+ return { resolved: template, unresolvedKeys: [] };
1813
+ }
1814
+ const unresolvedKeys = [];
1815
+ TEMPLATE_RE.lastIndex = 0;
1816
+ const resolved = template.replace(TEMPLATE_RE, (_match, key) => {
1817
+ if (metadata) {
1818
+ const value = getNestedValue(
1819
+ metadata,
1820
+ key
1821
+ );
1822
+ if (value !== void 0) {
1823
+ return value;
1824
+ }
1825
+ }
1826
+ unresolvedKeys.push(key);
1827
+ return FALLBACKS[key] ?? `<${key}>`;
1828
+ });
1829
+ return { resolved, unresolvedKeys };
1830
+ }
1831
+
1710
1832
  // src/agent/agent-config.ts
1711
- var AgentConfig = class _AgentConfig extends Component7 {
1833
+ var AgentConfig = class _AgentConfig extends Component8 {
1712
1834
  /**
1713
1835
  * Find the AgentConfig component on a project.
1714
1836
  */
@@ -1727,12 +1849,20 @@ var AgentConfig = class _AgentConfig extends Component7 {
1727
1849
  const skills = this.resolveSkills();
1728
1850
  const subAgents = this.resolveSubAgents();
1729
1851
  const mcpServers = this.options.mcpServers ?? {};
1852
+ const projectMetadata = ProjectMetadata.of(this.project);
1853
+ const metadata = projectMetadata?.metadata;
1854
+ const resolvedRules = this.resolveTemplates(rules, metadata);
1855
+ const resolvedSkills = this.resolveSkillTemplates(skills, metadata);
1856
+ const resolvedSubAgents = this.resolveSubAgentTemplates(
1857
+ subAgents,
1858
+ metadata
1859
+ );
1730
1860
  if (platforms.includes(AGENT_PLATFORM.CURSOR)) {
1731
1861
  CursorRenderer.render(
1732
1862
  this,
1733
- rules,
1734
- skills,
1735
- subAgents,
1863
+ resolvedRules,
1864
+ resolvedSkills,
1865
+ resolvedSubAgents,
1736
1866
  mcpServers,
1737
1867
  this.options.cursorSettings
1738
1868
  );
@@ -1740,18 +1870,28 @@ var AgentConfig = class _AgentConfig extends Component7 {
1740
1870
  if (platforms.includes(AGENT_PLATFORM.CLAUDE)) {
1741
1871
  ClaudeRenderer.render(
1742
1872
  this,
1743
- rules,
1744
- skills,
1745
- subAgents,
1873
+ resolvedRules,
1874
+ resolvedSkills,
1875
+ resolvedSubAgents,
1746
1876
  mcpServers,
1747
1877
  this.options.claudeSettings
1748
1878
  );
1749
1879
  }
1750
1880
  if (platforms.includes(AGENT_PLATFORM.CODEX)) {
1751
- CodexRenderer.render(this, rules, skills, subAgents);
1881
+ CodexRenderer.render(
1882
+ this,
1883
+ resolvedRules,
1884
+ resolvedSkills,
1885
+ resolvedSubAgents
1886
+ );
1752
1887
  }
1753
1888
  if (platforms.includes(AGENT_PLATFORM.COPILOT)) {
1754
- CopilotRenderer.render(this, rules, skills, subAgents);
1889
+ CopilotRenderer.render(
1890
+ this,
1891
+ resolvedRules,
1892
+ resolvedSkills,
1893
+ resolvedSubAgents
1894
+ );
1755
1895
  }
1756
1896
  }
1757
1897
  resolvePlatforms() {
@@ -1854,13 +1994,65 @@ ${extra}`
1854
1994
  }
1855
1995
  return [...agentMap.values()];
1856
1996
  }
1997
+ /**
1998
+ * Resolves template variables in rule content using project metadata.
1999
+ * Emits synthesis warnings for rules with unresolved variables.
2000
+ */
2001
+ resolveTemplates(rules, metadata) {
2002
+ return rules.map((rule) => {
2003
+ const { resolved, unresolvedKeys } = resolveTemplateVariables(
2004
+ rule.content,
2005
+ metadata
2006
+ );
2007
+ if (unresolvedKeys.length > 0) {
2008
+ this.project.logger.warn(
2009
+ `AgentConfig: ProjectMetadata not found; rule '${rule.name}' using default values`
2010
+ );
2011
+ }
2012
+ return resolved !== rule.content ? { ...rule, content: resolved } : rule;
2013
+ });
2014
+ }
2015
+ /**
2016
+ * Resolves template variables in skill instructions using project metadata.
2017
+ */
2018
+ resolveSkillTemplates(skills, metadata) {
2019
+ return skills.map((skill) => {
2020
+ const { resolved, unresolvedKeys } = resolveTemplateVariables(
2021
+ skill.instructions,
2022
+ metadata
2023
+ );
2024
+ if (unresolvedKeys.length > 0) {
2025
+ this.project.logger.warn(
2026
+ `AgentConfig: ProjectMetadata not found; skill '${skill.name}' using default values`
2027
+ );
2028
+ }
2029
+ return resolved !== skill.instructions ? { ...skill, instructions: resolved } : skill;
2030
+ });
2031
+ }
2032
+ /**
2033
+ * Resolves template variables in sub-agent prompts using project metadata.
2034
+ */
2035
+ resolveSubAgentTemplates(subAgents, metadata) {
2036
+ return subAgents.map((agent) => {
2037
+ const { resolved, unresolvedKeys } = resolveTemplateVariables(
2038
+ agent.prompt,
2039
+ metadata
2040
+ );
2041
+ if (unresolvedKeys.length > 0) {
2042
+ this.project.logger.warn(
2043
+ `AgentConfig: ProjectMetadata not found; sub-agent '${agent.name}' using default values`
2044
+ );
2045
+ }
2046
+ return resolved !== agent.prompt ? { ...agent, prompt: resolved } : agent;
2047
+ });
2048
+ }
1857
2049
  };
1858
2050
 
1859
2051
  // src/aws/aws-deployment-config.ts
1860
2052
  var import_utils8 = __toESM(require_lib());
1861
2053
  import { join, relative as relative2 } from "path";
1862
- import { Component as Component8 } from "projen";
1863
- var AwsDeploymentConfig = class _AwsDeploymentConfig extends Component8 {
2054
+ import { Component as Component9 } from "projen";
2055
+ var AwsDeploymentConfig = class _AwsDeploymentConfig extends Component9 {
1864
2056
  constructor(project) {
1865
2057
  super(project);
1866
2058
  /**
@@ -1977,8 +2169,8 @@ var AwsDeploymentConfig = class _AwsDeploymentConfig extends Component8 {
1977
2169
 
1978
2170
  // src/aws/aws-deployment-target.ts
1979
2171
  var import_utils9 = __toESM(require_lib());
1980
- import { Component as Component9 } from "projen";
1981
- var AwsDeploymentTarget = class _AwsDeploymentTarget extends Component9 {
2172
+ import { Component as Component10 } from "projen";
2173
+ var AwsDeploymentTarget = class _AwsDeploymentTarget extends Component10 {
1982
2174
  constructor(project, options) {
1983
2175
  super(project);
1984
2176
  /**
@@ -2193,12 +2385,12 @@ var VERSION_KEYS_SKIP = [
2193
2385
 
2194
2386
  // src/jsii/jsii-faker.ts
2195
2387
  import * as spec from "@jsii/spec";
2196
- import { Component as Component10, JsonFile as JsonFile4 } from "projen";
2388
+ import { Component as Component11, JsonFile as JsonFile4 } from "projen";
2197
2389
  var ProjenBaseFqn = {
2198
2390
  TYPESCRIPT_PROJECT: "projen.typescript.TypeScriptProject",
2199
2391
  TYPESCRIPT_PROJECT_OPTIONS: "projen.typescript.TypeScriptProjectOptions"
2200
2392
  };
2201
- var JsiiFaker = class _JsiiFaker extends Component10 {
2393
+ var JsiiFaker = class _JsiiFaker extends Component11 {
2202
2394
  constructor(project) {
2203
2395
  super(project);
2204
2396
  this.project = project;
@@ -2257,7 +2449,7 @@ import {
2257
2449
  import { merge as merge2 } from "ts-deepmerge";
2258
2450
 
2259
2451
  // src/tasks/reset-task.ts
2260
- import { Component as Component11 } from "projen";
2452
+ import { Component as Component12 } from "projen";
2261
2453
 
2262
2454
  // src/projects/typescript-project.ts
2263
2455
  import { typescript } from "projen";
@@ -2432,7 +2624,7 @@ var TypeScriptProject = class extends typescript.TypeScriptProject {
2432
2624
  };
2433
2625
 
2434
2626
  // src/tasks/reset-task.ts
2435
- var ResetTask = class _ResetTask extends Component11 {
2627
+ var ResetTask = class _ResetTask extends Component12 {
2436
2628
  constructor(project, options = {}) {
2437
2629
  super(project);
2438
2630
  this.project = project;
@@ -2505,8 +2697,8 @@ var ResetTask = class _ResetTask extends Component11 {
2505
2697
  };
2506
2698
 
2507
2699
  // src/vscode/vscode.ts
2508
- import { Component as Component12, vscode } from "projen";
2509
- var VSCodeConfig = class extends Component12 {
2700
+ import { Component as Component13, vscode } from "projen";
2701
+ var VSCodeConfig = class extends Component13 {
2510
2702
  constructor(project) {
2511
2703
  super(project);
2512
2704
  const vsConfig = new vscode.VsCode(project);
@@ -2882,6 +3074,12 @@ var MonorepoProject = class extends TypeScriptAppProject {
2882
3074
  if (options.approveMergeUpgradeOptions) {
2883
3075
  addApproveMergeUpgradeWorkflow(this, options.approveMergeUpgradeOptions);
2884
3076
  }
3077
+ if (options.projectMetadata !== false) {
3078
+ new ProjectMetadata(
3079
+ this,
3080
+ typeof options.projectMetadata === "object" ? options.projectMetadata : {}
3081
+ );
3082
+ }
2885
3083
  if (options.agentConfig) {
2886
3084
  new AgentConfig(this, options.agentConfigOptions);
2887
3085
  }
@@ -2943,9 +3141,9 @@ var MonorepoProject = class extends TypeScriptAppProject {
2943
3141
 
2944
3142
  // src/typescript/typescript-config.ts
2945
3143
  import { relative as relative3 } from "path";
2946
- import { Component as Component13 } from "projen";
3144
+ import { Component as Component14 } from "projen";
2947
3145
  import { ensureRelativePathStartsWithDot } from "projen/lib/util/path";
2948
- var TypeScriptConfig = class extends Component13 {
3146
+ var TypeScriptConfig = class extends Component14 {
2949
3147
  constructor(project) {
2950
3148
  super(project);
2951
3149
  let tsPaths = {};
@@ -2973,12 +3171,12 @@ var TypeScriptConfig = class extends Component13 {
2973
3171
 
2974
3172
  // src/workflows/aws-deploy-workflow.ts
2975
3173
  var import_utils10 = __toESM(require_lib());
2976
- import { Component as Component14 } from "projen";
3174
+ import { Component as Component15 } from "projen";
2977
3175
  import { BuildWorkflow } from "projen/lib/build";
2978
3176
  import { GitHub } from "projen/lib/github";
2979
3177
  import { JobPermission as JobPermission4 } from "projen/lib/github/workflows-model";
2980
3178
  var PROD_DEPLOY_NAME = "prod-deploy";
2981
- var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component14 {
3179
+ var AwsDeployWorkflow = class _AwsDeployWorkflow extends Component15 {
2982
3180
  constructor(project, options = {}) {
2983
3181
  super(project);
2984
3182
  this.project = project;
@@ -3259,6 +3457,7 @@ export {
3259
3457
  MonorepoProject,
3260
3458
  PROD_DEPLOY_NAME,
3261
3459
  PnpmWorkspace,
3460
+ ProjectMetadata,
3262
3461
  ROOT_CI_TASK_NAME,
3263
3462
  ROOT_TURBO_TASK_NAME,
3264
3463
  ResetTask,
@@ -3280,6 +3479,7 @@ export {
3280
3479
  jestBundle,
3281
3480
  pnpmBundle,
3282
3481
  projenBundle,
3482
+ resolveTemplateVariables,
3283
3483
  turborepoBundle,
3284
3484
  typescriptBundle,
3285
3485
  vitestBundle