@codedrifters/configulator 0.0.166 → 0.0.167

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.d.mts CHANGED
@@ -394,6 +394,15 @@ interface AgentRuleBundle {
394
394
  readonly skills?: ReadonlyArray<AgentSkill>;
395
395
  /** Sub-agents included in this bundle. */
396
396
  readonly subAgents?: ReadonlyArray<AgentSubAgent>;
397
+ /**
398
+ * Claude Code permission entries contributed by this bundle.
399
+ * Allow and deny entries are merged with the default and user-supplied
400
+ * permissions when the bundle is active.
401
+ */
402
+ readonly claudePermissions?: {
403
+ readonly allow?: ReadonlyArray<string>;
404
+ readonly deny?: ReadonlyArray<string>;
405
+ };
397
406
  }
398
407
  /*******************************************************************************
399
408
  *
@@ -815,6 +824,13 @@ declare class AgentConfig extends Component {
815
824
  * Find the AgentConfig component on a project.
816
825
  */
817
826
  static of(project: Project$1): AgentConfig | undefined;
827
+ /**
828
+ * Merges default Claude permissions with bundle and user-supplied settings.
829
+ *
830
+ * Merge order: defaults → bundle permissions → user-supplied entries.
831
+ * `defaultMode` defaults to `"dontAsk"` unless overridden.
832
+ */
833
+ private static mergeClaudeDefaults;
818
834
  private readonly options;
819
835
  constructor(project: Project$1, options?: AgentConfigOptions);
820
836
  preSynthesize(): void;
@@ -835,6 +851,10 @@ declare class AgentConfig extends Component {
835
851
  * Resolves template variables in sub-agent prompts using project metadata.
836
852
  */
837
853
  private resolveSubAgentTemplates;
854
+ /**
855
+ * Collects Claude permission entries from all active bundles.
856
+ */
857
+ private resolveBundlePermissions;
838
858
  }
839
859
 
840
860
  /**
package/lib/index.d.ts CHANGED
@@ -443,6 +443,15 @@ interface AgentRuleBundle {
443
443
  readonly skills?: ReadonlyArray<AgentSkill>;
444
444
  /** Sub-agents included in this bundle. */
445
445
  readonly subAgents?: ReadonlyArray<AgentSubAgent>;
446
+ /**
447
+ * Claude Code permission entries contributed by this bundle.
448
+ * Allow and deny entries are merged with the default and user-supplied
449
+ * permissions when the bundle is active.
450
+ */
451
+ readonly claudePermissions?: {
452
+ readonly allow?: ReadonlyArray<string>;
453
+ readonly deny?: ReadonlyArray<string>;
454
+ };
446
455
  }
447
456
  /*******************************************************************************
448
457
  *
@@ -864,6 +873,13 @@ declare class AgentConfig extends Component {
864
873
  * Find the AgentConfig component on a project.
865
874
  */
866
875
  static of(project: Project): AgentConfig | undefined;
876
+ /**
877
+ * Merges default Claude permissions with bundle and user-supplied settings.
878
+ *
879
+ * Merge order: defaults → bundle permissions → user-supplied entries.
880
+ * `defaultMode` defaults to `"dontAsk"` unless overridden.
881
+ */
882
+ private static mergeClaudeDefaults;
867
883
  private readonly options;
868
884
  constructor(project: Project, options?: AgentConfigOptions);
869
885
  preSynthesize(): void;
@@ -884,6 +900,10 @@ declare class AgentConfig extends Component {
884
900
  * Resolves template variables in sub-agent prompts using project metadata.
885
901
  */
886
902
  private resolveSubAgentTemplates;
903
+ /**
904
+ * Collects Claude permission entries from all active bundles.
905
+ */
906
+ private resolveBundlePermissions;
887
907
  }
888
908
 
889
909
  /**
package/lib/index.js CHANGED
@@ -678,6 +678,17 @@ var baseBundle = {
678
678
  "| `release:` | Release preparation, version bumps |",
679
679
  "| `hotfix:` | Urgent production fixes |",
680
680
  "",
681
+ "## GitHub Issue Type",
682
+ "",
683
+ "When creating issues, always assign the appropriate **GitHub issue type** based on the title prefix:",
684
+ "",
685
+ "| Prefix | GitHub Issue Type |",
686
+ "|--------|------------------|",
687
+ "| `epic:` | Epic |",
688
+ "| `feat:` | Feature |",
689
+ "| `fix:` | Bug |",
690
+ "| `chore:`, `docs:`, `refactor:`, `release:`, `hotfix:` | Task |",
691
+ "",
681
692
  "## Prerequisite Issues",
682
693
  "",
683
694
  "Include any prerequisite (blocking) issues in the issue body when they exist.",
@@ -706,18 +717,20 @@ var githubWorkflowBundle = {
706
717
  "",
707
718
  "When the user says **work on issue X** (or similar), follow these steps exactly:",
708
719
  "",
709
- "1. **Fetch issue details** \u2014 use `gh issue view <number>` to get the title, body, and labels",
710
- "2. **Determine branch type** from the issue title prefix:",
720
+ "1. **Ensure you have the latest code** \u2014 switch to the default branch and pull:",
721
+ " - `git checkout {{repository.defaultBranch}} && git pull origin {{repository.defaultBranch}}`",
722
+ "2. **Fetch issue details** \u2014 use `gh issue view <number>` to get the title, body, and labels",
723
+ "3. **Determine branch type** from the issue title prefix:",
711
724
  " - `feat:` / `feature:` \u2192 `feat/`",
712
725
  " - `fix:` / `bug:` \u2192 `fix/`",
713
726
  " - `docs:` \u2192 `docs/`",
714
727
  " - `chore:` / `refactor:` \u2192 `chore/`",
715
728
  " - `test:` \u2192 `test/`",
716
729
  " - No prefix \u2192 `feat/`",
717
- "3. **Create a branch** following the naming convention: `<type>/<short-slug>-<issue-number>` (e.g., `feat/add-login-42`)",
718
- "4. **Checkout the branch** locally",
719
- "5. **Link the branch to the issue** by posting a comment: `gh issue comment <number> --body 'Branch: \\`<branch-name>\\`'`",
720
- "6. **Stop and wait** for user instructions \u2014 do **NOT** start implementing",
730
+ "4. **Create a branch** following the naming convention: `<type>/<short-slug>-<issue-number>` (e.g., `feat/add-login-42`)",
731
+ "5. **Checkout the branch** locally",
732
+ "6. **Link the branch to the issue** by posting a comment: `gh issue comment <number> --body 'Branch: \\`<branch-name>\\`'`",
733
+ "7. **Stop and wait** for user instructions \u2014 do **NOT** start implementing",
721
734
  "",
722
735
  "### Important",
723
736
  "",
@@ -834,7 +847,10 @@ var jestBundle = {
834
847
  ].join("\n"),
835
848
  tags: ["testing"]
836
849
  }
837
- ]
850
+ ],
851
+ claudePermissions: {
852
+ allow: ["Bash(npx jest:*)"]
853
+ }
838
854
  };
839
855
 
840
856
  // src/pnpm/pnpm-workspace.ts
@@ -1337,7 +1353,10 @@ var turborepoBundle = {
1337
1353
  ].join("\n"),
1338
1354
  tags: ["workflow"]
1339
1355
  }
1340
- ]
1356
+ ],
1357
+ claudePermissions: {
1358
+ allow: ["Bash(npx turbo:*)"]
1359
+ }
1341
1360
  };
1342
1361
 
1343
1362
  // src/agent/bundles/typescript.ts
@@ -1412,7 +1431,10 @@ var typescriptBundle = {
1412
1431
  ].join("\n"),
1413
1432
  tags: ["coding"]
1414
1433
  }
1415
- ]
1434
+ ],
1435
+ claudePermissions: {
1436
+ allow: ["Bash(npx tsc:*)"]
1437
+ }
1416
1438
  };
1417
1439
 
1418
1440
  // src/vitest/vitest-component.ts
@@ -1604,7 +1626,10 @@ var vitestBundle = {
1604
1626
  ].join("\n"),
1605
1627
  tags: ["testing"]
1606
1628
  }
1607
- ]
1629
+ ],
1630
+ claudePermissions: {
1631
+ allow: ["Bash(npx vitest:*)"]
1632
+ }
1608
1633
  };
1609
1634
 
1610
1635
  // src/agent/bundles/index.ts
@@ -2229,6 +2254,110 @@ function resolveTemplateVariables(template, metadata) {
2229
2254
  }
2230
2255
 
2231
2256
  // src/agent/agent-config.ts
2257
+ var DEFAULT_CLAUDE_ALLOW = [
2258
+ // ── Git ──────────────────────────────────────────────────────────────
2259
+ "Bash(git add *)",
2260
+ "Bash(git branch *)",
2261
+ "Bash(git checkout *)",
2262
+ "Bash(git commit *)",
2263
+ "Bash(git diff *)",
2264
+ "Bash(git fetch *)",
2265
+ "Bash(git log *)",
2266
+ "Bash(git merge *)",
2267
+ "Bash(git mv *)",
2268
+ "Bash(git pull *)",
2269
+ "Bash(git push *)",
2270
+ "Bash(git rebase *)",
2271
+ "Bash(git rm *)",
2272
+ "Bash(git stash *)",
2273
+ "Bash(git status *)",
2274
+ "Bash(git show *)",
2275
+ "Bash(git rev-parse *)",
2276
+ // ── GitHub CLI ───────────────────────────────────────────────────────
2277
+ "Bash(gh issue *)",
2278
+ "Bash(gh pr *)",
2279
+ "Bash(gh repo *)",
2280
+ "Bash(gh api *)",
2281
+ "Bash(gh label *)",
2282
+ "Bash(gh run *)",
2283
+ "Bash(gh search *)",
2284
+ "Bash(gh browse *)",
2285
+ "Bash(gh status *)",
2286
+ // ── Package manager ──────────────────────────────────────────────────
2287
+ "Bash(pnpm *)",
2288
+ // ── Read-only shell utilities ────────────────────────────────────────
2289
+ "Bash(ls *)",
2290
+ "Bash(find *)",
2291
+ "Bash(cat *)",
2292
+ "Bash(head *)",
2293
+ "Bash(tail *)",
2294
+ "Bash(wc *)",
2295
+ "Bash(grep *)",
2296
+ "Bash(sort *)",
2297
+ "Bash(uniq *)",
2298
+ "Bash(dirname *)",
2299
+ "Bash(basename *)",
2300
+ "Bash(which *)",
2301
+ "Bash(diff *)",
2302
+ "Bash(jq *)",
2303
+ "Bash(date *)",
2304
+ // ── Safe output / test utilities ─────────────────────────────────────
2305
+ "Bash(echo *)",
2306
+ "Bash(printf *)",
2307
+ "Bash(test *)",
2308
+ "Bash([ *)",
2309
+ "Bash(true *)",
2310
+ "Bash(false *)",
2311
+ // ── Safe directory operations ────────────────────────────────────────
2312
+ "Bash(mkdir *)",
2313
+ "Bash(rmdir *)",
2314
+ // ── Built-in tools ───────────────────────────────────────────────────
2315
+ "Read(/**)",
2316
+ "Edit(/**)",
2317
+ "Write(/**)",
2318
+ "WebFetch",
2319
+ "WebSearch"
2320
+ ];
2321
+ var DEFAULT_CLAUDE_DENY = [
2322
+ // ── Destructive git ──────────────────────────────────────────────────
2323
+ "Bash(git push --force *)",
2324
+ "Bash(git push -f *)",
2325
+ "Bash(git push origin --force *)",
2326
+ "Bash(git push origin -f *)",
2327
+ "Bash(git reset --hard *)",
2328
+ "Bash(git clean -f *)",
2329
+ "Bash(git remote *)",
2330
+ // ── Destructive file operations ──────────────────────────────────────
2331
+ "Bash(rm -rf *)",
2332
+ "Bash(rm -r *)",
2333
+ "Bash(rm *)",
2334
+ // ── Network / remote access ──────────────────────────────────────────
2335
+ "Bash(curl *)",
2336
+ "Bash(wget *)",
2337
+ "Bash(ssh *)",
2338
+ "Bash(scp *)",
2339
+ // ── System administration ────────────────────────────────────────────
2340
+ "Bash(sudo *)",
2341
+ "Bash(chmod *)",
2342
+ "Bash(chown *)",
2343
+ "Bash(kill *)",
2344
+ "Bash(killall *)",
2345
+ "Bash(pkill *)",
2346
+ // ── Code execution / shell spawning ──────────────────────────────────
2347
+ "Bash(eval *)",
2348
+ "Bash(exec *)",
2349
+ "Bash(source *)",
2350
+ "Bash(. *)",
2351
+ "Bash(bash *)",
2352
+ "Bash(sh *)",
2353
+ "Bash(zsh *)",
2354
+ // ── App launching ────────────────────────────────────────────────────
2355
+ "Bash(open *)",
2356
+ "Bash(xdg-open *)",
2357
+ // ── Environment manipulation ─────────────────────────────────────────
2358
+ "Bash(export *)",
2359
+ "Bash(env *)"
2360
+ ];
2232
2361
  var AgentConfig = class _AgentConfig extends import_projen8.Component {
2233
2362
  /**
2234
2363
  * Find the AgentConfig component on a project.
@@ -2237,6 +2366,27 @@ var AgentConfig = class _AgentConfig extends import_projen8.Component {
2237
2366
  const isAgentConfig = (c) => c instanceof _AgentConfig;
2238
2367
  return project.components.find(isAgentConfig);
2239
2368
  }
2369
+ /**
2370
+ * Merges default Claude permissions with bundle and user-supplied settings.
2371
+ *
2372
+ * Merge order: defaults → bundle permissions → user-supplied entries.
2373
+ * `defaultMode` defaults to `"dontAsk"` unless overridden.
2374
+ */
2375
+ static mergeClaudeDefaults(userSettings, bundlePermissions) {
2376
+ const bundleAllow = bundlePermissions?.allow ?? [];
2377
+ const bundleDeny = bundlePermissions?.deny ?? [];
2378
+ const userAllow = userSettings?.permissions?.allow ?? [];
2379
+ const userDeny = userSettings?.permissions?.deny ?? [];
2380
+ return {
2381
+ ...userSettings,
2382
+ defaultMode: userSettings?.defaultMode ?? "dontAsk",
2383
+ permissions: {
2384
+ ...userSettings?.permissions,
2385
+ allow: [...DEFAULT_CLAUDE_ALLOW, ...bundleAllow, ...userAllow],
2386
+ deny: [...DEFAULT_CLAUDE_DENY, ...bundleDeny, ...userDeny]
2387
+ }
2388
+ };
2389
+ }
2240
2390
  constructor(project, options = {}) {
2241
2391
  super(project);
2242
2392
  this.options = options;
@@ -2267,13 +2417,17 @@ var AgentConfig = class _AgentConfig extends import_projen8.Component {
2267
2417
  );
2268
2418
  }
2269
2419
  if (platforms.includes(AGENT_PLATFORM.CLAUDE)) {
2420
+ const bundlePermissions = this.resolveBundlePermissions();
2270
2421
  ClaudeRenderer.render(
2271
2422
  this,
2272
2423
  resolvedRules,
2273
2424
  resolvedSkills,
2274
2425
  resolvedSubAgents,
2275
2426
  mcpServers,
2276
- this.options.claudeSettings
2427
+ _AgentConfig.mergeClaudeDefaults(
2428
+ this.options.claudeSettings,
2429
+ bundlePermissions
2430
+ )
2277
2431
  );
2278
2432
  }
2279
2433
  if (platforms.includes(AGENT_PLATFORM.CODEX)) {
@@ -2445,6 +2599,40 @@ ${extra}`
2445
2599
  return resolved !== agent.prompt ? { ...agent, prompt: resolved } : agent;
2446
2600
  });
2447
2601
  }
2602
+ /**
2603
+ * Collects Claude permission entries from all active bundles.
2604
+ */
2605
+ resolveBundlePermissions() {
2606
+ const allow = [];
2607
+ const deny = [];
2608
+ if (this.options.autoDetectBundles !== false) {
2609
+ for (const bundle of BUILT_IN_BUNDLES) {
2610
+ if (this.options.excludeBundles?.includes(bundle.name)) continue;
2611
+ if (bundle.appliesWhen(this.project) && bundle.claudePermissions) {
2612
+ if (bundle.claudePermissions.allow) {
2613
+ allow.push(...bundle.claudePermissions.allow);
2614
+ }
2615
+ if (bundle.claudePermissions.deny) {
2616
+ deny.push(...bundle.claudePermissions.deny);
2617
+ }
2618
+ }
2619
+ }
2620
+ }
2621
+ if (this.options.includeBundles) {
2622
+ for (const bundleName of this.options.includeBundles) {
2623
+ const bundle = BUILT_IN_BUNDLES.find((b) => b.name === bundleName);
2624
+ if (bundle?.claudePermissions) {
2625
+ if (bundle.claudePermissions.allow) {
2626
+ allow.push(...bundle.claudePermissions.allow);
2627
+ }
2628
+ if (bundle.claudePermissions.deny) {
2629
+ deny.push(...bundle.claudePermissions.deny);
2630
+ }
2631
+ }
2632
+ }
2633
+ }
2634
+ return { allow, deny };
2635
+ }
2448
2636
  };
2449
2637
 
2450
2638
  // src/aws/aws-deployment-config.ts