@codedrifters/configulator 0.0.160 → 0.0.162
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/README.md +494 -0
- package/lib/index.js +24 -6
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +24 -6
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,6 +18,18 @@ A library of [Projen](https://projen.io/) components used by CodeDrifters to man
|
|
|
18
18
|
- [File Management Rules](#file-management-rules)
|
|
19
19
|
- [Workflow Tips](#workflow-tips)
|
|
20
20
|
- [API Reference](#api-reference)
|
|
21
|
+
- [Agent Configuration](#agent-configuration)
|
|
22
|
+
- [Why Single-Source?](#why-single-source)
|
|
23
|
+
- [Quick Start](#quick-start)
|
|
24
|
+
- [Configuration Options](#configuration-options-1)
|
|
25
|
+
- [Built-in Rule Bundles](#built-in-rule-bundles)
|
|
26
|
+
- [Custom Rules](#custom-rules)
|
|
27
|
+
- [Skills](#skills)
|
|
28
|
+
- [Sub-Agents](#sub-agents)
|
|
29
|
+
- [MCP Server Configuration](#mcp-server-configuration)
|
|
30
|
+
- [Platform-Specific Settings](#platform-specific-settings)
|
|
31
|
+
- [Template Variables](#template-variables)
|
|
32
|
+
- [Examples](#examples)
|
|
21
33
|
- [Troubleshooting](#troubleshooting)
|
|
22
34
|
- [Additional Resources](#additional-resources)
|
|
23
35
|
|
|
@@ -801,6 +813,488 @@ TurboRepo.of(project: Project): TurboRepo | undefined
|
|
|
801
813
|
|
|
802
814
|
Returns the TurboRepo component from a project if it exists.
|
|
803
815
|
|
|
816
|
+
### AgentConfig
|
|
817
|
+
|
|
818
|
+
**Static Method:**
|
|
819
|
+
```typescript
|
|
820
|
+
AgentConfig.of(project: Project): AgentConfig | undefined
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
Returns the AgentConfig component from a project if it exists.
|
|
824
|
+
|
|
825
|
+
## Agent Configuration
|
|
826
|
+
|
|
827
|
+
AgentConfig provides a **single-source, multi-platform** approach to AI coding assistant configuration. Define rules, skills, sub-agents, and MCP servers once in your `.projenrc.ts`, and configulator renders the correct files for each target platform during synthesis.
|
|
828
|
+
|
|
829
|
+
### Why Single-Source?
|
|
830
|
+
|
|
831
|
+
Every AI coding assistant has its own configuration format — Cursor uses `.mdc` files with YAML frontmatter, Claude Code uses `.md` files and `settings.json`, Codex uses `AGENTS.md`, and Copilot uses `.github/instructions/`. Without a unified approach, teams end up maintaining duplicate rule sets that inevitably drift out of sync.
|
|
832
|
+
|
|
833
|
+
AgentConfig solves this by defining rules in a platform-agnostic format and rendering them into each platform's native format:
|
|
834
|
+
|
|
835
|
+
```
|
|
836
|
+
.projenrc.ts (AgentConfig)
|
|
837
|
+
│
|
|
838
|
+
├── Cursor: .cursor/rules/*.mdc, .cursor/agents/*.md, .cursor/mcp.json
|
|
839
|
+
├── Claude: CLAUDE.md, .claude/rules/*.md, .claude/settings.json, .claude/skills/*, .claude/agents/*
|
|
840
|
+
├── Codex: AGENTS.md (planned)
|
|
841
|
+
└── Copilot: .github/instructions/*.md (planned)
|
|
842
|
+
```
|
|
843
|
+
|
|
844
|
+
### Quick Start
|
|
845
|
+
|
|
846
|
+
Enable agent configuration with defaults — auto-detects rule bundles based on your project's tooling:
|
|
847
|
+
|
|
848
|
+
```typescript
|
|
849
|
+
// In .projenrc.ts — MonorepoProject
|
|
850
|
+
const project = new MonorepoProject({
|
|
851
|
+
name: "my-project",
|
|
852
|
+
agentConfig: true, // or {} for defaults
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
// Sub-projects inherit from parent automatically
|
|
856
|
+
const api = new TypeScriptProject({
|
|
857
|
+
parent: project,
|
|
858
|
+
name: "@my-org/api",
|
|
859
|
+
outdir: "packages/api",
|
|
860
|
+
// agentConfig inherited from parent — no explicit config needed
|
|
861
|
+
});
|
|
862
|
+
```
|
|
863
|
+
|
|
864
|
+
After running `npx projen`, the following files are generated (varies by detected tooling):
|
|
865
|
+
|
|
866
|
+
| Platform | Files |
|
|
867
|
+
|----------|-------|
|
|
868
|
+
| Cursor | `.cursor/rules/*.mdc`, `.cursor/agents/*.md`, `.cursor/mcp.json`, `.cursor/hooks.json`, `.cursorignore`, `.cursorindexingignore` |
|
|
869
|
+
| Claude | `CLAUDE.md`, `.claude/rules/*.md`, `.claude/settings.json`, `.claude/skills/*/SKILL.md`, `.claude/agents/*.md` |
|
|
870
|
+
| Codex | `AGENTS.md` (planned) |
|
|
871
|
+
| Copilot | `.github/instructions/*.md` (planned) |
|
|
872
|
+
|
|
873
|
+
### Configuration Options
|
|
874
|
+
|
|
875
|
+
The `AgentConfigOptions` interface controls all aspects of agent configuration:
|
|
876
|
+
|
|
877
|
+
| Option | Type | Default | Description |
|
|
878
|
+
|--------|------|---------|-------------|
|
|
879
|
+
| `platforms` | `AgentPlatform[]` | `[CURSOR, CLAUDE]` | Target platforms to generate config for |
|
|
880
|
+
| `autoDetectBundles` | `boolean` | `true` | Auto-detect rule bundles based on project tooling |
|
|
881
|
+
| `includeBundles` | `string[]` | — | Force-include specific bundles by name |
|
|
882
|
+
| `excludeBundles` | `string[]` | — | Exclude bundles even if auto-detected |
|
|
883
|
+
| `includeBaseRules` | `boolean` | `true` | Include base rules (project-overview, conventions) |
|
|
884
|
+
| `excludeRules` | `string[]` | — | Exclude individual rules by name |
|
|
885
|
+
| `ruleExtensions` | `Record<string, string>` | — | Append content to existing rules |
|
|
886
|
+
| `rules` | `AgentRule[]` | — | Custom rules (override bundled rules of same name) |
|
|
887
|
+
| `skills` | `AgentSkill[]` | — | Custom skill definitions |
|
|
888
|
+
| `subAgents` | `AgentSubAgent[]` | — | Custom sub-agent definitions |
|
|
889
|
+
| `mcpServers` | `Record<string, McpServerConfig>` | — | MCP server configs (cross-platform) |
|
|
890
|
+
| `claudeSettings` | `ClaudeSettingsConfig` | — | Claude Code settings.json config |
|
|
891
|
+
| `cursorSettings` | `CursorSettingsConfig` | — | Cursor hooks and ignore patterns |
|
|
892
|
+
|
|
893
|
+
### Built-in Rule Bundles
|
|
894
|
+
|
|
895
|
+
Configulator ships with context-aware rule bundles that are automatically included when their tooling is detected in the project:
|
|
896
|
+
|
|
897
|
+
| Bundle | Auto-detection | Rules | Description |
|
|
898
|
+
|--------|---------------|-------|-------------|
|
|
899
|
+
| `base` | Always (unless `includeBaseRules: false`) | `project-overview`, `interaction-style`, `general-conventions`, `pull-request-conventions`, `branch-naming-conventions`, `issue-conventions` | Core project context, interaction style, and coding conventions. Also includes `create-rule` and `review-pr` skills. |
|
|
900
|
+
| `typescript` | `tsconfig.json` exists | `typescript-conventions` | Type safety, naming, JSDoc, member ordering |
|
|
901
|
+
| `vitest` | Vitest component present | `vitest-testing` | Vitest testing patterns and file scoping |
|
|
902
|
+
| `jest` | `jest` in dependencies | `jest-testing` | Jest testing patterns, SWC compilation, mocking |
|
|
903
|
+
| `turborepo` | TurboRepo component present | `turborepo-conventions` | Build system, task pipeline, caching |
|
|
904
|
+
| `pnpm` | PnpmWorkspace component present | `pnpm-workspace` | Workspace dependencies, package management |
|
|
905
|
+
| `aws-cdk` | `aws-cdk-lib` in dependencies | `aws-cdk-conventions` | Construct patterns, L2/L3, IAM best practices |
|
|
906
|
+
| `projen` | `projen` in dependencies | `projen-conventions` | Config patterns, synthesis workflow, components |
|
|
907
|
+
|
|
908
|
+
**Controlling bundles:**
|
|
909
|
+
|
|
910
|
+
```typescript
|
|
911
|
+
new AgentConfig(project, {
|
|
912
|
+
// Disable auto-detection entirely
|
|
913
|
+
autoDetectBundles: false,
|
|
914
|
+
|
|
915
|
+
// Force-include bundles that aren't auto-detected
|
|
916
|
+
includeBundles: ["aws-cdk"],
|
|
917
|
+
|
|
918
|
+
// Exclude auto-detected bundles
|
|
919
|
+
excludeBundles: ["jest"],
|
|
920
|
+
|
|
921
|
+
// Disable the base rule set
|
|
922
|
+
includeBaseRules: false,
|
|
923
|
+
|
|
924
|
+
// Exclude individual rules from any source
|
|
925
|
+
excludeRules: ["branch-naming-conventions"],
|
|
926
|
+
|
|
927
|
+
// Append content to an existing rule without replacing it
|
|
928
|
+
ruleExtensions: {
|
|
929
|
+
"typescript-conventions": "## Additional Conventions\n\n- Use branded types for IDs",
|
|
930
|
+
},
|
|
931
|
+
});
|
|
932
|
+
```
|
|
933
|
+
|
|
934
|
+
### Custom Rules
|
|
935
|
+
|
|
936
|
+
Define custom rules using the `AgentRule` interface:
|
|
937
|
+
|
|
938
|
+
```typescript
|
|
939
|
+
import { AGENT_RULE_SCOPE, CLAUDE_RULE_TARGET } from "@codedrifters/configulator";
|
|
940
|
+
|
|
941
|
+
new AgentConfig(project, {
|
|
942
|
+
rules: [
|
|
943
|
+
{
|
|
944
|
+
name: "api-conventions",
|
|
945
|
+
description: "REST API design conventions for this project",
|
|
946
|
+
scope: AGENT_RULE_SCOPE.FILE_PATTERN,
|
|
947
|
+
filePatterns: ["src/api/**/*.ts", "src/routes/**/*.ts"],
|
|
948
|
+
content: `# API Conventions
|
|
949
|
+
|
|
950
|
+
- Use RESTful resource naming
|
|
951
|
+
- Always validate request bodies with Zod
|
|
952
|
+
- Return consistent error response shapes`,
|
|
953
|
+
tags: ["api"],
|
|
954
|
+
},
|
|
955
|
+
],
|
|
956
|
+
});
|
|
957
|
+
```
|
|
958
|
+
|
|
959
|
+
**Rule fields:**
|
|
960
|
+
|
|
961
|
+
| Field | Type | Required | Description |
|
|
962
|
+
|-------|------|----------|-------------|
|
|
963
|
+
| `name` | `string` | Yes | Unique kebab-case identifier, used as filename |
|
|
964
|
+
| `description` | `string` | Yes | AI-readable purpose (Cursor uses this for rule selection) |
|
|
965
|
+
| `scope` | `AgentRuleScope` | Yes | `ALWAYS` (always active) or `FILE_PATTERN` (active on matching files) |
|
|
966
|
+
| `filePatterns` | `string[]` | When `FILE_PATTERN` | Glob patterns for conditional activation |
|
|
967
|
+
| `content` | `string` | Yes | Markdown rule body |
|
|
968
|
+
| `platforms` | `AgentPlatformOverrides` | No | Per-platform overrides |
|
|
969
|
+
| `tags` | `string[]` | No | For categorizing and ordering rules |
|
|
970
|
+
|
|
971
|
+
**Platform overrides** let you customize or exclude rules per platform:
|
|
972
|
+
|
|
973
|
+
```typescript
|
|
974
|
+
{
|
|
975
|
+
name: "claude-specific-rule",
|
|
976
|
+
description: "A rule only for Claude Code",
|
|
977
|
+
scope: AGENT_RULE_SCOPE.ALWAYS,
|
|
978
|
+
content: "# Claude-Only\n\nThis rule is excluded from Cursor.",
|
|
979
|
+
platforms: {
|
|
980
|
+
cursor: { exclude: true },
|
|
981
|
+
claude: { target: CLAUDE_RULE_TARGET.CLAUDE_MD }, // Render to CLAUDE.md instead of .claude/rules/
|
|
982
|
+
},
|
|
983
|
+
}
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
Claude supports three render targets:
|
|
987
|
+
- `SCOPED_FILE` (default) — `.claude/rules/{name}.md` with optional paths frontmatter
|
|
988
|
+
- `AGENTS_MD` — `AGENTS.md` (always-active, shared with Codex)
|
|
989
|
+
- `CLAUDE_MD` — `CLAUDE.md` (always-active, Claude-only)
|
|
990
|
+
|
|
991
|
+
### Skills
|
|
992
|
+
|
|
993
|
+
Skills define slash commands and automated workflows. They are rendered to `.claude/skills/*/SKILL.md` (Claude Code) and `.cursor/skills/` (Cursor).
|
|
994
|
+
|
|
995
|
+
```typescript
|
|
996
|
+
new AgentConfig(project, {
|
|
997
|
+
skills: [
|
|
998
|
+
{
|
|
999
|
+
name: "deploy-check",
|
|
1000
|
+
description: "Verify deployment readiness before merging",
|
|
1001
|
+
instructions: `# Deploy Check
|
|
1002
|
+
|
|
1003
|
+
1. Run the full test suite
|
|
1004
|
+
2. Check for any TODO/FIXME comments in changed files
|
|
1005
|
+
3. Verify no console.log statements in production code
|
|
1006
|
+
4. Report findings`,
|
|
1007
|
+
allowedTools: ["Read", "Glob", "Grep", "Bash(pnpm run test *)"],
|
|
1008
|
+
disableModelInvocation: true, // Only triggered by /deploy-check
|
|
1009
|
+
},
|
|
1010
|
+
],
|
|
1011
|
+
});
|
|
1012
|
+
```
|
|
1013
|
+
|
|
1014
|
+
**Skill fields:**
|
|
1015
|
+
|
|
1016
|
+
| Field | Type | Default | Description |
|
|
1017
|
+
|-------|------|---------|-------------|
|
|
1018
|
+
| `name` | `string` | — | Slash-command name (e.g., `/commit`) |
|
|
1019
|
+
| `description` | `string` | — | Used by AI for auto-invocation decisions |
|
|
1020
|
+
| `instructions` | `string` | — | Markdown body (becomes SKILL.md) |
|
|
1021
|
+
| `allowedTools` | `string[]` | All | Tool allowlist |
|
|
1022
|
+
| `disableModelInvocation` | `boolean` | `false` | Prevent auto-invocation |
|
|
1023
|
+
| `userInvocable` | `boolean` | `true` | Allow `/skill-name` command |
|
|
1024
|
+
| `model` | `string` | — | Model override |
|
|
1025
|
+
| `effort` | `string` | — | Reasoning effort level |
|
|
1026
|
+
| `paths` | `string[]` | — | Auto-load on matching files |
|
|
1027
|
+
| `context` | `string` | — | Set to `'fork'` for isolated subagent |
|
|
1028
|
+
| `agent` | `string` | — | Subagent name when context is `'fork'` |
|
|
1029
|
+
|
|
1030
|
+
**Built-in skills** (from the base bundle):
|
|
1031
|
+
- `create-rule` — Guide for creating new agent rules
|
|
1032
|
+
- `review-pr` — PR review workflow
|
|
1033
|
+
|
|
1034
|
+
### Sub-Agents
|
|
1035
|
+
|
|
1036
|
+
Sub-agents define specialized AI agents that the parent agent can delegate to:
|
|
1037
|
+
|
|
1038
|
+
```typescript
|
|
1039
|
+
import { AGENT_MODEL } from "@codedrifters/configulator";
|
|
1040
|
+
|
|
1041
|
+
new AgentConfig(project, {
|
|
1042
|
+
subAgents: [
|
|
1043
|
+
{
|
|
1044
|
+
name: "test-writer",
|
|
1045
|
+
description: "Write and update unit tests for changed code",
|
|
1046
|
+
prompt: `# Test Writer
|
|
1047
|
+
|
|
1048
|
+
You are a specialized testing agent. Given source files, write comprehensive
|
|
1049
|
+
unit tests following the project's testing conventions.
|
|
1050
|
+
|
|
1051
|
+
- Use the project's test runner (Vitest or Jest)
|
|
1052
|
+
- Follow existing test patterns in the codebase
|
|
1053
|
+
- Ensure full branch coverage`,
|
|
1054
|
+
model: AGENT_MODEL.BALANCED,
|
|
1055
|
+
tools: ["Read", "Glob", "Grep", "Edit", "Write", "Bash(pnpm run test *)"],
|
|
1056
|
+
maxTurns: 20,
|
|
1057
|
+
},
|
|
1058
|
+
],
|
|
1059
|
+
});
|
|
1060
|
+
```
|
|
1061
|
+
|
|
1062
|
+
**Sub-agent fields:**
|
|
1063
|
+
|
|
1064
|
+
| Field | Type | Default | Description |
|
|
1065
|
+
|-------|------|---------|-------------|
|
|
1066
|
+
| `name` | `string` | — | Lowercase kebab-case identifier |
|
|
1067
|
+
| `description` | `string` | — | When to delegate to this agent |
|
|
1068
|
+
| `prompt` | `string` | — | System prompt (markdown) |
|
|
1069
|
+
| `model` | `AgentModel` | `INHERIT` | `INHERIT`, `FAST`, `BALANCED`, or `POWERFUL` |
|
|
1070
|
+
| `tools` | `string[]` | All | Tool allowlist |
|
|
1071
|
+
| `disallowedTools` | `string[]` | — | Tool denylist |
|
|
1072
|
+
| `maxTurns` | `number` | — | Agentic turn limit |
|
|
1073
|
+
| `skills` | `string[]` | — | Pre-loaded skills |
|
|
1074
|
+
| `mcpServers` | `Record<string, McpServerConfig>` | — | MCP servers for this agent |
|
|
1075
|
+
| `canDelegateToAgents` | `string[]` | — | Agents this agent can invoke |
|
|
1076
|
+
| `platforms` | `AgentSubAgentPlatformOverrides` | — | Per-platform overrides |
|
|
1077
|
+
|
|
1078
|
+
**Platform-specific sub-agent overrides:**
|
|
1079
|
+
|
|
1080
|
+
```typescript
|
|
1081
|
+
{
|
|
1082
|
+
name: "code-reviewer",
|
|
1083
|
+
description: "Review code for quality and conventions",
|
|
1084
|
+
prompt: "...",
|
|
1085
|
+
platforms: {
|
|
1086
|
+
claude: {
|
|
1087
|
+
permissionMode: "plan", // default, acceptEdits, dontAsk, bypassPermissions, plan
|
|
1088
|
+
isolation: "worktree", // Run in isolated git worktree
|
|
1089
|
+
background: true, // Run as background task
|
|
1090
|
+
effort: "high", // Reasoning effort: low, medium, high, max
|
|
1091
|
+
},
|
|
1092
|
+
cursor: {
|
|
1093
|
+
readonly: true, // Read-only operations only
|
|
1094
|
+
isBackground: true, // Async background task
|
|
1095
|
+
},
|
|
1096
|
+
},
|
|
1097
|
+
}
|
|
1098
|
+
```
|
|
1099
|
+
|
|
1100
|
+
### MCP Server Configuration
|
|
1101
|
+
|
|
1102
|
+
MCP servers are defined once and rendered to the appropriate config for each platform (`.claude/settings.json` for Claude, `.cursor/mcp.json` for Cursor):
|
|
1103
|
+
|
|
1104
|
+
```typescript
|
|
1105
|
+
import { MCP_TRANSPORT } from "@codedrifters/configulator";
|
|
1106
|
+
|
|
1107
|
+
new AgentConfig(project, {
|
|
1108
|
+
mcpServers: {
|
|
1109
|
+
"my-server": {
|
|
1110
|
+
command: "npx",
|
|
1111
|
+
args: ["-y", "@my-org/mcp-server"],
|
|
1112
|
+
env: { API_KEY: "${API_KEY}" },
|
|
1113
|
+
enabledTools: ["search", "read_file"],
|
|
1114
|
+
},
|
|
1115
|
+
"remote-api": {
|
|
1116
|
+
transport: MCP_TRANSPORT.HTTP,
|
|
1117
|
+
url: "https://api.example.com/mcp",
|
|
1118
|
+
headers: { Authorization: "Bearer ${TOKEN}" },
|
|
1119
|
+
disabledTools: ["dangerous_action"],
|
|
1120
|
+
},
|
|
1121
|
+
},
|
|
1122
|
+
});
|
|
1123
|
+
```
|
|
1124
|
+
|
|
1125
|
+
**McpServerConfig fields:**
|
|
1126
|
+
|
|
1127
|
+
| Field | Type | Default | Description |
|
|
1128
|
+
|-------|------|---------|-------------|
|
|
1129
|
+
| `transport` | `McpTransport` | `STDIO` | `STDIO`, `HTTP`, or `SSE` |
|
|
1130
|
+
| `command` | `string` | — | Command for stdio servers |
|
|
1131
|
+
| `args` | `string[]` | — | Command arguments |
|
|
1132
|
+
| `url` | `string` | — | URL for HTTP/SSE servers |
|
|
1133
|
+
| `headers` | `Record<string, string>` | — | HTTP headers |
|
|
1134
|
+
| `env` | `Record<string, string>` | — | Environment variables |
|
|
1135
|
+
| `enabledTools` | `string[]` | All | Tool allowlist |
|
|
1136
|
+
| `disabledTools` | `string[]` | — | Tool denylist |
|
|
1137
|
+
|
|
1138
|
+
### Platform-Specific Settings
|
|
1139
|
+
|
|
1140
|
+
#### Claude Code Settings
|
|
1141
|
+
|
|
1142
|
+
Configure Claude Code's `settings.json` with permissions, hooks, sandbox, and more:
|
|
1143
|
+
|
|
1144
|
+
```typescript
|
|
1145
|
+
new AgentConfig(project, {
|
|
1146
|
+
claudeSettings: {
|
|
1147
|
+
defaultMode: "default", // default, acceptEdits, plan, auto
|
|
1148
|
+
permissions: {
|
|
1149
|
+
allow: ["Bash(pnpm run *)", "Edit(/src/**/*.ts)"],
|
|
1150
|
+
deny: ["Bash(rm -rf *)"],
|
|
1151
|
+
ask: ["Bash"],
|
|
1152
|
+
additionalDirectories: ["/shared/libs"],
|
|
1153
|
+
},
|
|
1154
|
+
hooks: {
|
|
1155
|
+
PreToolUse: [
|
|
1156
|
+
{
|
|
1157
|
+
matcher: "Bash",
|
|
1158
|
+
hooks: [{ type: "command", command: "echo 'Running Bash'" }],
|
|
1159
|
+
},
|
|
1160
|
+
],
|
|
1161
|
+
},
|
|
1162
|
+
sandbox: { enabled: true },
|
|
1163
|
+
model: "claude-opus-4-6",
|
|
1164
|
+
effortLevel: "high",
|
|
1165
|
+
excludeSensitivePatterns: ["**/.env", "**/*.key"],
|
|
1166
|
+
},
|
|
1167
|
+
});
|
|
1168
|
+
```
|
|
1169
|
+
|
|
1170
|
+
#### Cursor Settings
|
|
1171
|
+
|
|
1172
|
+
Configure Cursor hooks and ignore patterns:
|
|
1173
|
+
|
|
1174
|
+
```typescript
|
|
1175
|
+
new AgentConfig(project, {
|
|
1176
|
+
cursorSettings: {
|
|
1177
|
+
hooks: {
|
|
1178
|
+
beforeShellExecution: [{ command: "echo 'pre-exec check'" }],
|
|
1179
|
+
afterFileEdit: [{ command: "pnpm run lint --fix" }],
|
|
1180
|
+
},
|
|
1181
|
+
ignorePatterns: ["**/.env", "**/secrets/**"],
|
|
1182
|
+
indexingIgnorePatterns: ["**/generated/**", "*.min.js"],
|
|
1183
|
+
},
|
|
1184
|
+
});
|
|
1185
|
+
```
|
|
1186
|
+
|
|
1187
|
+
### Template Variables
|
|
1188
|
+
|
|
1189
|
+
Rule content, skill instructions, and sub-agent prompts support `{{variable}}` template placeholders that are resolved from `ProjectMetadata` during synthesis:
|
|
1190
|
+
|
|
1191
|
+
| Variable | Fallback | Description |
|
|
1192
|
+
|----------|----------|-------------|
|
|
1193
|
+
| `{{repository.owner}}` | `<owner>` | GitHub repository owner |
|
|
1194
|
+
| `{{repository.name}}` | `<repo>` | Repository name |
|
|
1195
|
+
| `{{repository.defaultBranch}}` | `main` | Default branch |
|
|
1196
|
+
| `{{organization.name}}` | `<organization>` | Organization name |
|
|
1197
|
+
| `{{organization.githubOrg}}` | `<org>` | GitHub organization |
|
|
1198
|
+
| `{{githubProject.name}}` | `<project-name>` | GitHub project name |
|
|
1199
|
+
| `{{githubProject.number}}` | `<project-number>` | GitHub project number |
|
|
1200
|
+
| `{{githubProject.nodeId}}` | `<project-node-id>` | GitHub project node ID |
|
|
1201
|
+
| `{{docsPath}}` | `<docs-path>` | Documentation path |
|
|
1202
|
+
|
|
1203
|
+
If `ProjectMetadata` is not configured, fallback placeholders are used and a synthesis warning is emitted.
|
|
1204
|
+
|
|
1205
|
+
### Examples
|
|
1206
|
+
|
|
1207
|
+
**Minimal setup — all defaults:**
|
|
1208
|
+
|
|
1209
|
+
```typescript
|
|
1210
|
+
const project = new MonorepoProject({
|
|
1211
|
+
name: "my-project",
|
|
1212
|
+
agentConfig: true,
|
|
1213
|
+
});
|
|
1214
|
+
```
|
|
1215
|
+
|
|
1216
|
+
**Custom platform selection:**
|
|
1217
|
+
|
|
1218
|
+
```typescript
|
|
1219
|
+
import { AGENT_PLATFORM } from "@codedrifters/configulator";
|
|
1220
|
+
|
|
1221
|
+
const project = new MonorepoProject({
|
|
1222
|
+
name: "my-project",
|
|
1223
|
+
agentConfig: {
|
|
1224
|
+
platforms: [AGENT_PLATFORM.CLAUDE], // Claude only, no Cursor
|
|
1225
|
+
},
|
|
1226
|
+
});
|
|
1227
|
+
```
|
|
1228
|
+
|
|
1229
|
+
**Custom rules and skills:**
|
|
1230
|
+
|
|
1231
|
+
```typescript
|
|
1232
|
+
import { AGENT_RULE_SCOPE } from "@codedrifters/configulator";
|
|
1233
|
+
|
|
1234
|
+
const project = new MonorepoProject({
|
|
1235
|
+
name: "my-project",
|
|
1236
|
+
agentConfig: {
|
|
1237
|
+
rules: [
|
|
1238
|
+
{
|
|
1239
|
+
name: "database-conventions",
|
|
1240
|
+
description: "Database migration and query conventions",
|
|
1241
|
+
scope: AGENT_RULE_SCOPE.FILE_PATTERN,
|
|
1242
|
+
filePatterns: ["src/db/**/*.ts", "migrations/**/*.ts"],
|
|
1243
|
+
content: "# Database Conventions\n\n- Use parameterized queries\n- Never use raw SQL",
|
|
1244
|
+
},
|
|
1245
|
+
],
|
|
1246
|
+
skills: [
|
|
1247
|
+
{
|
|
1248
|
+
name: "migrate",
|
|
1249
|
+
description: "Run database migrations",
|
|
1250
|
+
instructions: "# Migrate\n\nRun `pnpm run db:migrate` and verify the schema.",
|
|
1251
|
+
allowedTools: ["Bash(pnpm run db:*)"],
|
|
1252
|
+
},
|
|
1253
|
+
],
|
|
1254
|
+
},
|
|
1255
|
+
});
|
|
1256
|
+
```
|
|
1257
|
+
|
|
1258
|
+
**Monorepo with per-package overrides:**
|
|
1259
|
+
|
|
1260
|
+
```typescript
|
|
1261
|
+
const root = new MonorepoProject({
|
|
1262
|
+
name: "my-monorepo",
|
|
1263
|
+
agentConfig: {
|
|
1264
|
+
// Root-level config applies to all sub-projects
|
|
1265
|
+
rules: [{ name: "monorepo-rule", description: "...", scope: AGENT_RULE_SCOPE.ALWAYS, content: "..." }],
|
|
1266
|
+
},
|
|
1267
|
+
});
|
|
1268
|
+
|
|
1269
|
+
// Sub-project inherits parent config by default
|
|
1270
|
+
const api = new TypeScriptProject({
|
|
1271
|
+
parent: root,
|
|
1272
|
+
name: "@my-org/api",
|
|
1273
|
+
outdir: "packages/api",
|
|
1274
|
+
// Inherits agentConfig from root
|
|
1275
|
+
});
|
|
1276
|
+
|
|
1277
|
+
// Sub-project with explicit overrides
|
|
1278
|
+
const frontend = new TypeScriptProject({
|
|
1279
|
+
parent: root,
|
|
1280
|
+
name: "@my-org/frontend",
|
|
1281
|
+
outdir: "packages/frontend",
|
|
1282
|
+
agentConfig: {
|
|
1283
|
+
// Override: only generate Claude config for this package
|
|
1284
|
+
platforms: [AGENT_PLATFORM.CLAUDE],
|
|
1285
|
+
excludeBundles: ["jest"], // This package uses Vitest, not Jest
|
|
1286
|
+
},
|
|
1287
|
+
});
|
|
1288
|
+
|
|
1289
|
+
// Sub-project with agent config disabled
|
|
1290
|
+
const scripts = new TypeScriptProject({
|
|
1291
|
+
parent: root,
|
|
1292
|
+
name: "@my-org/scripts",
|
|
1293
|
+
outdir: "packages/scripts",
|
|
1294
|
+
agentConfig: false, // No agent config for this package
|
|
1295
|
+
});
|
|
1296
|
+
```
|
|
1297
|
+
|
|
804
1298
|
## Troubleshooting
|
|
805
1299
|
|
|
806
1300
|
**"Cannot find module" errors**
|
package/lib/index.js
CHANGED
|
@@ -456,6 +456,23 @@ var baseBundle = {
|
|
|
456
456
|
].join("\n"),
|
|
457
457
|
tags: ["project"]
|
|
458
458
|
},
|
|
459
|
+
{
|
|
460
|
+
name: "reference-documentation",
|
|
461
|
+
description: "Consult project rules, documentation, and existing code before answering or making changes",
|
|
462
|
+
scope: AGENT_RULE_SCOPE.ALWAYS,
|
|
463
|
+
content: [
|
|
464
|
+
"# Reference Documentation",
|
|
465
|
+
"",
|
|
466
|
+
"Before answering questions or making changes, always consult available project context.",
|
|
467
|
+
"",
|
|
468
|
+
"1. **Read project rules and guidelines** \u2014 check for agent rules, contribution guides, and coding standards defined in the project.",
|
|
469
|
+
"2. **Review existing code** \u2014 understand current patterns, conventions, and architecture before proposing changes. Look at similar files and modules for reference.",
|
|
470
|
+
"3. **Check documentation** \u2014 consult README files, inline documentation, and any design documents for relevant context.",
|
|
471
|
+
"4. **Respect established patterns** \u2014 follow the conventions already in use rather than introducing new ones without discussion.",
|
|
472
|
+
"5. **Verify before assuming** \u2014 if documentation or code conflicts with your assumptions, trust the project sources and ask for clarification when needed."
|
|
473
|
+
].join("\n"),
|
|
474
|
+
tags: ["project"]
|
|
475
|
+
},
|
|
459
476
|
{
|
|
460
477
|
name: "interaction-style",
|
|
461
478
|
description: "Interaction style \u2014 ask questions one at a time and wait for feedback",
|
|
@@ -465,12 +482,13 @@ var baseBundle = {
|
|
|
465
482
|
"",
|
|
466
483
|
"When responding to requests, follow these interaction principles.",
|
|
467
484
|
"",
|
|
468
|
-
"1. **Ask
|
|
469
|
-
"2. **
|
|
470
|
-
"3. **
|
|
471
|
-
"4. **
|
|
472
|
-
"5. **
|
|
473
|
-
"6. **
|
|
485
|
+
"1. **Ask when ambiguous**: When requirements are ambiguous or incomplete, always ask clarifying questions before proceeding. Do not make assumptions about the user's intent \u2014 it is better to ask than to guess wrong.",
|
|
486
|
+
"2. **Ask questions one at a time**: When clarification is needed, ask a single question and wait for the user's response before proceeding.",
|
|
487
|
+
"3. **Wait for feedback**: After asking a question, pause and wait for the user's answer before asking additional questions or making assumptions.",
|
|
488
|
+
"4. **Avoid question overload**: Do not ask multiple questions in a single response. If multiple clarifications are needed, prioritize the most important question first.",
|
|
489
|
+
"5. **Progressive clarification**: Once the user answers your first question, you may then ask the next most important question if needed.",
|
|
490
|
+
"6. **Confirm understanding**: After receiving feedback, acknowledge the user's response before proceeding with the next step or question.",
|
|
491
|
+
"7. **Be patient**: Do not rush ahead with assumptions. It is better to ask one clarifying question than to proceed with incorrect assumptions."
|
|
474
492
|
].join("\n"),
|
|
475
493
|
tags: ["project"]
|
|
476
494
|
},
|