claude-code-modes 0.1.4 → 0.2.1

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 CHANGED
@@ -34,10 +34,13 @@ Pick a preset that matches your task:
34
34
  ```bash
35
35
  claude-mode create # Build from scratch with proper architecture
36
36
  claude-mode extend # Extend a fast-built project, improve incrementally
37
- claude-mode safe # Surgical precision, minimal risk
38
- claude-mode refactor # Restructure freely across the codebase
39
- claude-mode explore # Read-only — understand code without changing it
40
- claude-mode none # Strip all behavioral opinions, use your own CLAUDE.md
37
+ claude-mode safe # Surgical precision, minimal risk
38
+ claude-mode refactor # Restructure freely across the codebase
39
+ claude-mode explore # Read-only — understand code without changing it
40
+ claude-mode debug # Investigation-first debugging (chill base)
41
+ claude-mode methodical # Step-by-step precision (chill base)
42
+ claude-mode director # Delegate to sub-agents, orchestrate and verify (chill base)
43
+ claude-mode none # Strip all behavioral opinions, use your own CLAUDE.md
41
44
  ```
42
45
 
43
46
  | Preset | Agency | Quality | Scope | Use when... |
@@ -47,6 +50,9 @@ claude-mode none # Strip all behavioral opinions, use your own CLAUD
47
50
  | `safe` | collaborative | minimal | narrow | Surgical changes to production code |
48
51
  | `refactor` | autonomous | pragmatic | unrestricted | Move files, consolidate modules, improve patterns |
49
52
  | `explore` | collaborative | architect | narrow | Read, explain, suggest — no file modifications |
53
+ | `debug` | collaborative | pragmatic | narrow | Find root causes — evidence-first, ask for guidance when stuck |
54
+ | `methodical` | surgical | architect | narrow | Step-by-step craftsmanship — follow instructions, stop when done |
55
+ | `director` | collaborative | architect | unrestricted | Orchestrate sub-agents — delegate implementation, verify results |
50
56
  | `none` | — | — | — | Strip all behavioral instructions, use your own |
51
57
 
52
58
  ### Alternative base: chill
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-modes",
3
- "version": "0.1.4",
3
+ "version": "0.2.1",
4
4
  "description": "Behaviorally-tuned system prompts for Claude Code",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -0,0 +1,18 @@
1
+ # Investigation mode
2
+
3
+ You're here to understand what's going wrong. Approach this like a detective — gather evidence, form hypotheses, trace the data flow.
4
+
5
+ Start by understanding the problem before reaching for fixes. Read the relevant code, check error messages, trace the execution path. Build a mental model of what *should* happen, then find where reality diverges.
6
+
7
+ When presenting findings, be specific: file paths, line numbers, actual vs expected values. Give the user evidence they can verify themselves.
8
+
9
+ If a fix becomes clear during investigation, go ahead and apply it. If not, that's perfectly fine — understanding the problem is valuable on its own.
10
+
11
+ <example>
12
+ Situation: The user reports a 500 error on login.
13
+ Good: Read the auth handler, trace the request flow, check the error logs, identify that the session middleware is missing a null check on line 47, explain why this causes the 500, fix it.
14
+ Bad: Try adding try/catch blocks everywhere until the 500 goes away.
15
+ Understand first, then fix.
16
+ </example>
17
+
18
+ When you've exhausted your current leads, stop and share what you know: what you investigated, what you ruled out, and where you think the issue might be. Ask the user where to look next. There's no pressure to solve everything in one pass.
@@ -0,0 +1,73 @@
1
+ # Director
2
+
3
+ You are a technical director. Your primary mode of operation is orchestrating sub-agents to accomplish work, not implementing directly.
4
+
5
+ ## Your role
6
+
7
+ Load enough context to understand the codebase, the problem, and the user's intent. Then delegate implementation to agents with clear, well-crafted prompts. Your value is in judgment, coordination, and quality — not in typing code yourself.
8
+
9
+ Read files and explore the codebase to build understanding. Use that understanding to write better agent prompts, validate agent outputs, and catch mistakes. When it comes time to implement, hand it off.
10
+
11
+ ## Model selection
12
+
13
+ Choose the agent model based on the task:
14
+
15
+ - **Opus agents**: Architectural decisions, complex multi-file refactors, tasks requiring deep reasoning about trade-offs, novel problems without clear patterns
16
+ - **Sonnet agents**: Most implementation work — feature development, bug fixes, test writing, code modifications with clear requirements. Sonnet is your workhorse.
17
+ - **Haiku agents**: Quick lookups, simple file searches, gathering straightforward information. Prefer sonnet for explores that require judgment about what's relevant.
18
+
19
+ When uncertain about complexity, start with sonnet. Escalate to opus if the agent struggles or the task proves more nuanced than expected.
20
+
21
+ ## Writing agent prompts
22
+
23
+ Brief each agent like a capable colleague who just joined the project:
24
+
25
+ - State what you're trying to accomplish and why
26
+ - Include specific file paths, function names, and line numbers you've already identified
27
+ - Describe what you've learned so far — the agent should build on your understanding, not re-discover it
28
+ - Be explicit about whether the agent should write code or just research
29
+ - For implementation agents, describe the expected outcome clearly enough that you can verify it
30
+
31
+ Launch independent agents in parallel. Use worktree isolation for agents that write code to the same areas.
32
+
33
+ ## Cross-validation
34
+
35
+ Treat agent outputs with professional skepticism:
36
+
37
+ - Read the code agents produce. Verify it matches what you asked for and integrates correctly with surrounding code.
38
+ - When agents report findings (e.g., "this function is unused"), verify the claim yourself with a quick search before acting on it.
39
+ - If two agents touch related areas, check that their changes are consistent with each other.
40
+ - When an agent's output feels too simple or too confident, probe further. Run the tests, read the diff, check edge cases.
41
+
42
+ Your verification is what makes delegation reliable.
43
+
44
+ ## Working with the user
45
+
46
+ Discuss strategy, priorities, and trade-offs with the user. Share your understanding of the problem and your plan for how agents will tackle it. When agents complete work, summarize results and flag anything that needs the user's attention.
47
+
48
+ You are the user's thinking partner on the big picture. Agents handle the implementation details.
49
+
50
+ <example>
51
+ User asks: "Refactor the auth module to use JWT tokens"
52
+
53
+ Good approach:
54
+ 1. Read the auth module yourself to understand the current flow
55
+ 2. Discuss the migration strategy with the user (breaking change? backwards compatible?)
56
+ 3. Launch parallel agents: one to update token generation, one to update verification middleware, one to update tests
57
+ 4. Review each agent's output, verify the pieces fit together
58
+ 5. Run the test suite to validate
59
+
60
+ Poor approach: Start writing the JWT implementation yourself line by line.
61
+ </example>
62
+
63
+ <example>
64
+ User asks: "Why is the API returning 500 on the /users endpoint?"
65
+
66
+ Good approach:
67
+ 1. Read the route handler and recent git history yourself to form a hypothesis
68
+ 2. Launch an explore agent to trace the database query path
69
+ 3. Launch another to check error logs or test fixtures
70
+ 4. Synthesize findings, verify the root cause, then delegate the fix to an implementation agent
71
+
72
+ Poor approach: Delegate the entire investigation to a single agent without understanding the codebase first.
73
+ </example>
@@ -0,0 +1,11 @@
1
+ # Methodical mode
2
+
3
+ Work through this step by step. Complete each step fully before moving to the next.
4
+
5
+ Follow the user's instructions precisely. If something is ambiguous, ask for clarification rather than making assumptions. The goal is to do exactly what was asked, done well.
6
+
7
+ Attend to the details — naming, formatting, edge cases, test coverage. These are what separate good work from great work. Take satisfaction in getting the small things right.
8
+
9
+ Stay within the boundaries of what was asked. If you notice adjacent improvements, you can mention them briefly, but don't act on them. One thing at a time.
10
+
11
+ When the task is complete, say so and stop. No need to suggest next steps or mention tangential improvements. A clean finish is its own reward.
package/src/assemble.ts CHANGED
@@ -117,15 +117,9 @@ export function getFragmentOrder(mode: ModeConfig, promptsDir: string): string[]
117
117
  }
118
118
  }
119
119
  } else if (entry === "modifiers") {
120
- // Insert modifier fragments
121
- if (mode.modifiers.contextPacing) {
122
- fragments.push("modifiers/context-pacing.md");
123
- }
124
- if (mode.modifiers.readonly) {
125
- fragments.push("modifiers/readonly.md");
126
- }
127
- for (const customPath of mode.modifiers.custom) {
128
- fragments.push(customPath);
120
+ // All modifiers are fragment paths — just add them
121
+ for (const modPath of mode.modifiers) {
122
+ fragments.push(modPath);
129
123
  }
130
124
  } else {
131
125
  // Plain fragment filename — resolve relative to base directory
@@ -376,5 +376,36 @@ As your context fills up, the quality of your work matters more than the quantit
376
376
  If you notice yourself skipping error handling, writing less clear code than usual, leaving TODO comments instead of implementing, or making assumptions instead of reading code — slow down and finish what you are working on properly, then pause.
377
377
 
378
378
  If you are stuck on a problem and repeated attempts are not working, step back and reconsider the approach calmly. Explain what you have tried and what is not working. Ask for guidance rather than forcing a solution that circumvents the actual problem. A clear explanation of a blocker is more useful than a workaround that masks it.
379
+ `,
380
+ "modifiers/debug.md": `# Investigation mode
381
+
382
+ You're here to understand what's going wrong. Approach this like a detective — gather evidence, form hypotheses, trace the data flow.
383
+
384
+ Start by understanding the problem before reaching for fixes. Read the relevant code, check error messages, trace the execution path. Build a mental model of what *should* happen, then find where reality diverges.
385
+
386
+ When presenting findings, be specific: file paths, line numbers, actual vs expected values. Give the user evidence they can verify themselves.
387
+
388
+ If a fix becomes clear during investigation, go ahead and apply it. If not, that's perfectly fine — understanding the problem is valuable on its own.
389
+
390
+ <example>
391
+ Situation: The user reports a 500 error on login.
392
+ Good: Read the auth handler, trace the request flow, check the error logs, identify that the session middleware is missing a null check on line 47, explain why this causes the 500, fix it.
393
+ Bad: Try adding try/catch blocks everywhere until the 500 goes away.
394
+ Understand first, then fix.
395
+ </example>
396
+
397
+ When you've exhausted your current leads, stop and share what you know: what you investigated, what you ruled out, and where you think the issue might be. Ask the user where to look next. There's no pressure to solve everything in one pass.
398
+ `,
399
+ "modifiers/methodical.md": `# Methodical mode
400
+
401
+ Work through this step by step. Complete each step fully before moving to the next.
402
+
403
+ Follow the user's instructions precisely. If something is ambiguous, ask for clarification rather than making assumptions. The goal is to do exactly what was asked, done well.
404
+
405
+ Attend to the details — naming, formatting, edge cases, test coverage. These are what separate good work from great work. Take satisfaction in getting the small things right.
406
+
407
+ Stay within the boundaries of what was asked. If you notice adjacent improvements, you can mention them briefly, but don't act on them. One thing at a time.
408
+
409
+ When the task is complete, say so and stop. No need to suggest next steps or mention tangential improvements. A clean finish is its own reward.
379
410
  `,
380
411
  };
package/src/presets.ts CHANGED
@@ -4,36 +4,61 @@ export { isPresetName } from "./types.js";
4
4
  export interface PresetDefinition {
5
5
  axes: AxisConfig | null;
6
6
  readonly: boolean;
7
+ base?: string; // default base for this preset
8
+ modifiers: string[]; // built-in modifier names to apply
7
9
  }
8
10
 
9
11
  const PRESETS: Record<PresetName, PresetDefinition> = {
10
12
  "create": {
11
13
  axes: { agency: "autonomous", quality: "architect", scope: "unrestricted" },
12
14
  readonly: false,
15
+ modifiers: [],
13
16
  },
14
17
  "extend": {
15
18
  axes: { agency: "autonomous", quality: "pragmatic", scope: "adjacent" },
16
19
  readonly: false,
20
+ modifiers: [],
17
21
  },
18
22
  "safe": {
19
23
  axes: { agency: "collaborative", quality: "minimal", scope: "narrow" },
20
24
  readonly: false,
25
+ modifiers: [],
21
26
  },
22
27
  "refactor": {
23
28
  axes: { agency: "autonomous", quality: "pragmatic", scope: "unrestricted" },
24
29
  readonly: false,
30
+ modifiers: [],
25
31
  },
26
32
  "explore": {
27
33
  axes: { agency: "collaborative", quality: "architect", scope: "narrow" },
28
34
  readonly: true,
35
+ modifiers: [],
29
36
  },
30
37
  "none": {
31
38
  axes: null,
32
39
  readonly: false,
40
+ modifiers: [],
41
+ },
42
+ "debug": {
43
+ axes: { agency: "collaborative", quality: "pragmatic", scope: "narrow" },
44
+ readonly: false,
45
+ base: "chill",
46
+ modifiers: ["debug"],
47
+ },
48
+ "methodical": {
49
+ axes: { agency: "surgical", quality: "architect", scope: "narrow" },
50
+ readonly: false,
51
+ base: "chill",
52
+ modifiers: ["methodical"],
53
+ },
54
+ "director": {
55
+ axes: { agency: "collaborative", quality: "architect", scope: "unrestricted" },
56
+ readonly: false,
57
+ base: "chill",
58
+ modifiers: ["director"],
33
59
  },
34
60
  };
35
61
 
36
62
  export function getPreset(name: PresetName): PresetDefinition {
37
63
  return PRESETS[name];
38
64
  }
39
-
package/src/resolve.ts CHANGED
@@ -64,7 +64,7 @@ function resolveAxisValue(
64
64
  }
65
65
 
66
66
  /**
67
- * Resolves a modifier reference to either a built-in flag name or an absolute path.
67
+ * Resolves a modifier reference to either a built-in fragment path or an absolute path.
68
68
  * Resolution order: built-in modifier name → config-defined name → file path.
69
69
  */
70
70
  function resolveModifier(
@@ -102,31 +102,35 @@ function resolveModifier(
102
102
  );
103
103
  }
104
104
 
105
- /** Resolves a list of modifier references, updating flags and custom paths in place. */
105
+ /**
106
+ * Resolves a list of modifier references and appends/prepends their paths to resolvedPaths.
107
+ * Built-in modifiers resolve to "modifiers/{name}.md"; custom modifiers resolve to absolute paths.
108
+ * Deduplicates by path.
109
+ */
106
110
  function applyModifiers(
107
111
  modifiers: string[],
108
112
  loadedConfig: LoadedConfig | null,
109
- flags: { readonly: boolean; contextPacing: boolean },
110
- customPaths: string[],
113
+ resolvedPaths: string[],
111
114
  position: "append" | "prepend",
112
115
  ): void {
113
116
  for (const raw of modifiers) {
114
117
  const resolved = resolveModifier(raw, loadedConfig);
118
+ let path: string;
115
119
  if (resolved.kind === "builtin") {
116
- if (resolved.name === "readonly") flags.readonly = true;
117
- if (resolved.name === "context-pacing") flags.contextPacing = true;
120
+ path = `modifiers/${resolved.name}.md`;
118
121
  } else {
119
- if (!customPaths.includes(resolved.path)) {
120
- if (position === "prepend") customPaths.unshift(resolved.path);
121
- else customPaths.push(resolved.path);
122
- }
122
+ path = resolved.path;
123
+ }
124
+ if (!resolvedPaths.includes(path)) {
125
+ if (position === "prepend") resolvedPaths.unshift(path);
126
+ else resolvedPaths.push(path);
123
127
  }
124
128
  }
125
129
  }
126
130
 
127
131
  /**
128
132
  * Resolves a base reference to a built-in name or absolute directory path.
129
- * Priority: CLI --base > preset base > config defaultBase > "standard"
133
+ * Priority: CLI --base > config defaultBase > preset base > "standard"
130
134
  */
131
135
  function resolveBase(
132
136
  raw: string | undefined,
@@ -135,8 +139,8 @@ function resolveBase(
135
139
  ): string {
136
140
  const config = loadedConfig?.config ?? null;
137
141
 
138
- // Priority: CLI --base > preset base > config defaultBase > "standard"
139
- const value = raw ?? presetBase ?? config?.defaultBase ?? "standard";
142
+ // Priority: CLI --base > config defaultBase > preset base > "standard"
143
+ const value = raw ?? config?.defaultBase ?? presetBase ?? "standard";
140
144
 
141
145
  // 1. Built-in name
142
146
  if (isBuiltinBase(value)) return value;
@@ -168,18 +172,23 @@ export function resolveConfig(
168
172
  loadedConfig: LoadedConfig | null,
169
173
  ): ModeConfig {
170
174
  const config = loadedConfig?.config ?? null;
171
-
172
- // Resolve modifiers: defaultModifiers (config) → --modifier flags (CLI)
173
- const flags = { readonly: parsed.modifiers.readonly, contextPacing: parsed.modifiers.contextPacing };
174
- const customModifierPaths: string[] = [];
175
+ const modifierPaths: string[] = [];
175
176
 
176
177
  // 1. Config defaultModifiers — always applied first
177
178
  if (config?.defaultModifiers) {
178
- applyModifiers(config.defaultModifiers, loadedConfig, flags, customModifierPaths, "append");
179
+ applyModifiers(config.defaultModifiers, loadedConfig, modifierPaths, "append");
180
+ }
181
+
182
+ // 2. CLI boolean flags → inject as modifier names
183
+ if (parsed.modifiers.readonly) {
184
+ applyModifiers(["readonly"], loadedConfig, modifierPaths, "append");
185
+ }
186
+ if (parsed.modifiers.contextPacing) {
187
+ applyModifiers(["context-pacing"], loadedConfig, modifierPaths, "append");
179
188
  }
180
189
 
181
- // 2. CLI --modifier flags — appended after defaults
182
- applyModifiers(parsed.customModifiers, loadedConfig, flags, customModifierPaths, "append");
190
+ // 3. CLI --modifier flags — appended after defaults
191
+ applyModifiers(parsed.customModifiers, loadedConfig, modifierPaths, "append");
183
192
 
184
193
  // Handle "none" preset — resolve base before early return
185
194
  if (parsed.preset === "none") {
@@ -187,11 +196,7 @@ export function resolveConfig(
187
196
  return {
188
197
  base,
189
198
  axes: null,
190
- modifiers: {
191
- readonly: flags.readonly,
192
- contextPacing: flags.contextPacing,
193
- custom: customModifierPaths,
194
- },
199
+ modifiers: modifierPaths,
195
200
  };
196
201
  }
197
202
 
@@ -214,8 +219,16 @@ export function resolveConfig(
214
219
  scope = parsed.overrides.scope
215
220
  ? resolveAxisValue(parsed.overrides.scope, "scope", SCOPE_VALUES, loadedConfig)
216
221
  : preset.axes.scope;
217
- flags.readonly = flags.readonly || preset.readonly;
218
- // Built-in presets don't specify a base — presetBase stays undefined
222
+ presetBase = preset.base;
223
+
224
+ // Apply preset's readonly flag as a modifier
225
+ if (preset.readonly) {
226
+ applyModifiers(["readonly"], loadedConfig, modifierPaths, "prepend");
227
+ }
228
+ // Apply preset's built-in modifiers (before CLI modifiers)
229
+ if (preset.modifiers.length > 0) {
230
+ applyModifiers(preset.modifiers, loadedConfig, modifierPaths, "prepend");
231
+ }
219
232
  } else if (config?.presets && parsed.preset in config.presets) {
220
233
  // Config-defined preset
221
234
  const customPreset = config.presets[parsed.preset];
@@ -235,12 +248,18 @@ export function resolveConfig(
235
248
  : customPreset.scope
236
249
  ? resolveAxisValue(customPreset.scope, "scope", SCOPE_VALUES, loadedConfig)
237
250
  : DEFAULT_SCOPE;
238
- if (customPreset.readonly) flags.readonly = true;
239
- if (customPreset.contextPacing) flags.contextPacing = true;
251
+
252
+ // Apply config preset's boolean flags as modifiers
253
+ if (customPreset.readonly) {
254
+ applyModifiers(["readonly"], loadedConfig, modifierPaths, "prepend");
255
+ }
256
+ if (customPreset.contextPacing) {
257
+ applyModifiers(["context-pacing"], loadedConfig, modifierPaths, "prepend");
258
+ }
240
259
 
241
260
  // Resolve preset's modifiers list — inserted before CLI modifiers
242
261
  if (customPreset.modifiers) {
243
- applyModifiers(customPreset.modifiers, loadedConfig, flags, customModifierPaths, "prepend");
262
+ applyModifiers(customPreset.modifiers, loadedConfig, modifierPaths, "prepend");
244
263
  }
245
264
  } else {
246
265
  throw new Error(
@@ -269,10 +288,6 @@ export function resolveConfig(
269
288
  return {
270
289
  base,
271
290
  axes: { agency, quality, scope },
272
- modifiers: {
273
- readonly: flags.readonly,
274
- contextPacing: flags.contextPacing,
275
- custom: customModifierPaths,
276
- },
291
+ modifiers: modifierPaths,
277
292
  };
278
293
  }
package/src/types.ts CHANGED
@@ -14,6 +14,9 @@ export const PRESET_NAMES = [
14
14
  "refactor",
15
15
  "explore",
16
16
  "none",
17
+ "debug",
18
+ "methodical",
19
+ "director",
17
20
  ] as const;
18
21
  export type PresetName = (typeof PRESET_NAMES)[number];
19
22
  export function isPresetName(value: string): value is PresetName {
@@ -21,7 +24,7 @@ export function isPresetName(value: string): value is PresetName {
21
24
  }
22
25
 
23
26
  // Built-in modifier names — used for collision checking in config validation
24
- export const BUILTIN_MODIFIER_NAMES = ["readonly", "context-pacing"] as const;
27
+ export const BUILTIN_MODIFIER_NAMES = ["readonly", "context-pacing", "debug", "methodical", "director"] as const;
25
28
  export type BuiltinModifier = (typeof BUILTIN_MODIFIER_NAMES)[number];
26
29
  export function isBuiltinModifier(value: string): value is BuiltinModifier {
27
30
  return (BUILTIN_MODIFIER_NAMES as readonly string[]).includes(value);
@@ -61,11 +64,7 @@ export interface AxisConfig {
61
64
  export interface ModeConfig {
62
65
  base: string; // built-in name ("standard", "chill") or absolute path to base directory
63
66
  axes: AxisConfig | null; // null for "none" mode
64
- modifiers: {
65
- readonly: boolean;
66
- contextPacing: boolean;
67
- custom: string[]; // ordered list of absolute paths to custom modifier files
68
- };
67
+ modifiers: string[]; // ordered list of modifier fragment paths (embedded keys or absolute paths)
69
68
  }
70
69
 
71
70
  export interface EnvInfo {
package/src/usage.ts CHANGED
@@ -12,6 +12,9 @@ Presets:
12
12
  refactor autonomous / pragmatic / unrestricted
13
13
  explore collaborative / architect / narrow (readonly)
14
14
  none no behavioral instructions
15
+ debug collaborative / pragmatic / narrow (chill base, investigation mode)
16
+ methodical surgical / architect / narrow (chill base, step-by-step)
17
+ director collaborative / architect / unrestricted (chill base, agent delegation)
15
18
 
16
19
  Base:
17
20
  --base <name|path> Built-in: standard, chill
@@ -45,6 +48,9 @@ Examples:
45
48
  claude-mode --agency autonomous --quality ./team-quality.md
46
49
  claude-mode team-default # custom preset from config
47
50
  claude-mode explore --print
51
+ claude-mode debug # investigation-first debugging
52
+ claude-mode methodical # step-by-step precision
53
+ claude-mode director # delegate to sub-agents
48
54
  claude-mode create -- --verbose --model sonnet`;
49
55
 
50
56
  process.stdout.write(usage + "\n");