claude-think 0.1.4 → 0.1.6

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.
@@ -23,7 +23,9 @@
23
23
  "Bash(bun install:*)",
24
24
  "Bash(bun:*)",
25
25
  "Bash(git commit -m \"$\\(cat <<''EOF''\nv0.1.3: Fix --version to read from package.json\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
26
- "Bash(git commit -m \"$\\(cat <<''EOF''\nv0.1.4: Improved setup wizard UX with @clack/prompts\n\n- Arrow key navigation and space to toggle checkboxes\n- Multi-select for frontend, CSS, database, infrastructure\n- Cleaner visual design with spinners and hints\n- Better cancel handling\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")"
26
+ "Bash(git commit -m \"$\\(cat <<''EOF''\nv0.1.4: Improved setup wizard UX with @clack/prompts\n\n- Arrow key navigation and space to toggle checkboxes\n- Multi-select for frontend, CSS, database, infrastructure\n- Cleaner visual design with spinners and hints\n- Better cancel handling\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
27
+ "Bash(npm view:*)",
28
+ "Bash(git commit:*)"
27
29
  ]
28
30
  }
29
31
  }
package/CHANGELOG.md CHANGED
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.1.6] - 2025-02-05
9
+
10
+ ### Fixed
11
+ - Plugin now registers in both settings.json and installed_plugins.json
12
+ - Uses `think@local` key format for proper Claude Code discovery
13
+
14
+ ## [0.1.5] - 2025-02-05
15
+
16
+ ### Added
17
+ - Enhanced profile section with role and experience level
18
+ - Claude personality selection (pair programmer, mentor, assistant, etc.)
19
+ - SDLC preferences: planning, testing, code review, git workflow
20
+ - Documentation, debugging, and refactoring preferences
21
+ - Generated profile now includes full development workflow guidance
22
+
8
23
  ## [0.1.4] - 2025-02-05
9
24
 
10
25
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-think",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Personal context manager for Claude - manage your preferences, patterns, and memory",
5
5
  "author": "Amit Feldman",
6
6
  "license": "MIT",
@@ -35,6 +35,115 @@ export async function setupCommand(): Promise<void> {
35
35
  });
36
36
  if (p.isCancel(style)) return handleCancel();
37
37
 
38
+ // === PROFILE & PERSONALITY ===
39
+ p.note("Let's understand who you are and how you work");
40
+
41
+ const role = await p.select({
42
+ message: "What's your role?",
43
+ options: [
44
+ { value: "senior-dev", label: "Senior Developer", hint: "experienced, autonomous" },
45
+ { value: "mid-dev", label: "Mid-level Developer", hint: "growing, some guidance helpful" },
46
+ { value: "junior-dev", label: "Junior Developer", hint: "learning, more explanation needed" },
47
+ { value: "founder", label: "Founder / Tech Lead", hint: "building fast, shipping matters" },
48
+ { value: "student", label: "Student", hint: "learning fundamentals" },
49
+ { value: "hobbyist", label: "Hobbyist", hint: "exploring for fun" },
50
+ ],
51
+ });
52
+ if (p.isCancel(role)) return handleCancel();
53
+
54
+ const claudePersonality = await p.select({
55
+ message: "How should Claude behave?",
56
+ options: [
57
+ { value: "pair-programmer", label: "Pair Programmer", hint: "collaborative, thinks out loud" },
58
+ { value: "senior-dev", label: "Senior Dev", hint: "gives direction, reviews your approach" },
59
+ { value: "assistant", label: "Efficient Assistant", hint: "executes tasks, minimal chatter" },
60
+ { value: "mentor", label: "Mentor", hint: "teaches concepts, explains why" },
61
+ { value: "rubber-duck", label: "Rubber Duck", hint: "helps you think, asks questions" },
62
+ ],
63
+ });
64
+ if (p.isCancel(claudePersonality)) return handleCancel();
65
+
66
+ // === SDLC PREFERENCES ===
67
+ p.note("How do you like to work through the development lifecycle?");
68
+
69
+ const planningApproach = await p.select({
70
+ message: "Planning approach?",
71
+ options: [
72
+ { value: "plan-first", label: "Plan first", hint: "discuss architecture before coding" },
73
+ { value: "iterate", label: "Iterate", hint: "rough plan, refine as we go" },
74
+ { value: "dive-in", label: "Dive in", hint: "start coding, figure it out" },
75
+ ],
76
+ });
77
+ if (p.isCancel(planningApproach)) return handleCancel();
78
+
79
+ const testingApproach = await p.select({
80
+ message: "Testing approach?",
81
+ options: [
82
+ { value: "tdd", label: "TDD", hint: "write tests first" },
83
+ { value: "test-after", label: "Test after", hint: "write tests after implementation" },
84
+ { value: "critical-paths", label: "Critical paths only", hint: "test important stuff" },
85
+ { value: "minimal", label: "Minimal", hint: "tests when necessary" },
86
+ ],
87
+ });
88
+ if (p.isCancel(testingApproach)) return handleCancel();
89
+
90
+ const codeReview = await p.select({
91
+ message: "Code review preference?",
92
+ options: [
93
+ { value: "review-before-commit", label: "Review before commit", hint: "Claude reviews changes" },
94
+ { value: "review-on-request", label: "On request", hint: "review when asked" },
95
+ { value: "self-review", label: "Self review", hint: "I review my own code" },
96
+ ],
97
+ });
98
+ if (p.isCancel(codeReview)) return handleCancel();
99
+
100
+ const gitWorkflow = await p.select({
101
+ message: "Git workflow?",
102
+ options: [
103
+ { value: "small-commits", label: "Small commits", hint: "atomic, frequent commits" },
104
+ { value: "feature-branches", label: "Feature branches", hint: "branch per feature, squash merge" },
105
+ { value: "trunk-based", label: "Trunk-based", hint: "commit to main, feature flags" },
106
+ { value: "flexible", label: "Flexible", hint: "depends on the project" },
107
+ ],
108
+ });
109
+ if (p.isCancel(gitWorkflow)) return handleCancel();
110
+
111
+ const documentationApproach = await p.select({
112
+ message: "Documentation approach?",
113
+ options: [
114
+ { value: "inline", label: "Inline comments", hint: "document as you code" },
115
+ { value: "readme-driven", label: "README driven", hint: "docs first, then code" },
116
+ { value: "minimal", label: "Minimal", hint: "self-documenting code" },
117
+ { value: "on-request", label: "On request", hint: "document when asked" },
118
+ ],
119
+ });
120
+ if (p.isCancel(documentationApproach)) return handleCancel();
121
+
122
+ const debuggingStyle = await p.select({
123
+ message: "Debugging style?",
124
+ options: [
125
+ { value: "systematic", label: "Systematic", hint: "isolate, reproduce, trace" },
126
+ { value: "hypothesis", label: "Hypothesis-driven", hint: "guess likely causes first" },
127
+ { value: "printf", label: "Printf debugging", hint: "add logs, observe behavior" },
128
+ { value: "whatever-works", label: "Whatever works", hint: "just fix it" },
129
+ ],
130
+ });
131
+ if (p.isCancel(debuggingStyle)) return handleCancel();
132
+
133
+ const refactoringPreference = await p.select({
134
+ message: "Refactoring preference?",
135
+ options: [
136
+ { value: "proactive", label: "Proactive", hint: "Claude suggests improvements" },
137
+ { value: "on-request", label: "On request", hint: "only when asked" },
138
+ { value: "boy-scout", label: "Boy scout rule", hint: "leave code better than found" },
139
+ { value: "if-broken", label: "If it ain't broke...", hint: "don't fix what works" },
140
+ ],
141
+ });
142
+ if (p.isCancel(refactoringPreference)) return handleCancel();
143
+
144
+ // === TECH STACK ===
145
+ p.note("Now let's configure your tech stack");
146
+
38
147
  const packageManager = await p.select({
39
148
  message: "Preferred package manager?",
40
149
  options: [
@@ -295,21 +404,133 @@ export async function setupCommand(): Promise<void> {
295
404
  ],
296
405
  };
297
406
 
407
+ const roleDescriptions: Record<string, string> = {
408
+ "senior-dev": "Senior developer - experienced and autonomous, prefers concise guidance",
409
+ "mid-dev": "Mid-level developer - competent but appreciates context on complex topics",
410
+ "junior-dev": "Junior developer - learning, benefits from more explanation and examples",
411
+ "founder": "Founder/Tech Lead - focused on shipping, pragmatic decisions over perfect code",
412
+ "student": "Student - learning fundamentals, explain concepts when relevant",
413
+ "hobbyist": "Hobbyist - exploring for fun, balance learning with getting things done",
414
+ };
415
+
416
+ const personalityDescriptions: Record<string, string[]> = {
417
+ "pair-programmer": [
418
+ "Act as a pair programmer - think out loud, collaborate on solutions",
419
+ "Discuss trade-offs and alternatives when relevant",
420
+ "Catch potential issues early, suggest improvements as we go",
421
+ ],
422
+ "senior-dev": [
423
+ "Act as a senior developer - give direction, review approaches",
424
+ "Point out potential issues and better patterns",
425
+ "Be opinionated when it matters, flexible when it doesn't",
426
+ ],
427
+ "assistant": [
428
+ "Act as an efficient assistant - execute tasks with minimal chatter",
429
+ "Ask clarifying questions only when truly needed",
430
+ "Focus on delivering what was asked",
431
+ ],
432
+ "mentor": [
433
+ "Act as a mentor - teach concepts, explain the 'why'",
434
+ "Use opportunities to share knowledge",
435
+ "Suggest learning resources when helpful",
436
+ ],
437
+ "rubber-duck": [
438
+ "Act as a rubber duck - help me think through problems",
439
+ "Ask probing questions rather than giving immediate answers",
440
+ "Help me discover solutions myself",
441
+ ],
442
+ };
443
+
444
+ const planningDescriptions: Record<string, string> = {
445
+ "plan-first": "Discuss architecture and approach before writing code",
446
+ "iterate": "Start with a rough plan, refine as we go",
447
+ "dive-in": "Start coding quickly, figure out structure as needed",
448
+ };
449
+
450
+ const testingDescriptions: Record<string, string> = {
451
+ "tdd": "Write tests first (TDD), then implement",
452
+ "test-after": "Write tests after implementation",
453
+ "critical-paths": "Test critical paths and edge cases",
454
+ "minimal": "Minimal testing - add tests when necessary",
455
+ };
456
+
457
+ const reviewDescriptions: Record<string, string> = {
458
+ "review-before-commit": "Review changes before committing - catch issues early",
459
+ "review-on-request": "Review code when explicitly asked",
460
+ "self-review": "I review my own code, no automatic reviews needed",
461
+ };
462
+
463
+ const gitDescriptions: Record<string, string> = {
464
+ "small-commits": "Small, atomic commits - easy to review and revert",
465
+ "feature-branches": "Feature branches with squash merges",
466
+ "trunk-based": "Trunk-based development with feature flags",
467
+ "flexible": "Flexible git workflow based on project needs",
468
+ };
469
+
470
+ const docDescriptions: Record<string, string> = {
471
+ "inline": "Document with inline comments as code is written",
472
+ "readme-driven": "README-driven development - docs first",
473
+ "minimal": "Minimal documentation - code should be self-documenting",
474
+ "on-request": "Add documentation when requested",
475
+ };
476
+
477
+ const debugDescriptions: Record<string, string> = {
478
+ "systematic": "Debug systematically - isolate, reproduce, trace",
479
+ "hypothesis": "Hypothesis-driven debugging - test likely causes first",
480
+ "printf": "Printf debugging - add logs and observe",
481
+ "whatever-works": "Whatever works to fix the issue quickly",
482
+ };
483
+
484
+ const refactorDescriptions: Record<string, string> = {
485
+ "proactive": "Proactively suggest refactoring opportunities",
486
+ "on-request": "Refactor only when asked",
487
+ "boy-scout": "Boy scout rule - leave code better than you found it",
488
+ "if-broken": "Don't refactor working code unless necessary",
489
+ };
490
+
298
491
  const profileContent = `---
299
492
  name: ${name}
493
+ role: ${role}
300
494
  style: ${style}
495
+ personality: ${claudePersonality}
301
496
  ---
302
497
 
303
- # Communication Preferences
498
+ # Who I Am
499
+
500
+ ${roleDescriptions[role as string]}
501
+
502
+ # How Claude Should Behave
503
+
504
+ ${personalityDescriptions[claudePersonality as string].map((s) => `- ${s}`).join("\n")}
505
+
506
+ # Communication Style
304
507
 
305
508
  ${styleDescriptions[style as string].map((s) => `- ${s}`).join("\n")}
306
509
  - No emojis unless explicitly requested
307
510
  - Show code when it's clearer than explanation
308
511
 
309
- # Work Style
512
+ # Development Workflow
513
+
514
+ ## Planning
515
+ - ${planningDescriptions[planningApproach as string]}
516
+
517
+ ## Testing
518
+ - ${testingDescriptions[testingApproach as string]}
519
+
520
+ ## Code Review
521
+ - ${reviewDescriptions[codeReview as string]}
522
+
523
+ ## Git Workflow
524
+ - ${gitDescriptions[gitWorkflow as string]}
525
+
526
+ ## Documentation
527
+ - ${docDescriptions[documentationApproach as string]}
528
+
529
+ ## Debugging
530
+ - ${debugDescriptions[debuggingStyle as string]}
310
531
 
311
- - Prefer practical solutions over theoretical
312
- - Match existing code patterns in the project
532
+ ## Refactoring
533
+ - ${refactorDescriptions[refactoringPreference as string]}
313
534
  `;
314
535
 
315
536
  await writeFile(thinkPath(CONFIG.files.profile), profileContent);
@@ -195,29 +195,49 @@ async function copyDirectory(src: string, dest: string): Promise<void> {
195
195
  }
196
196
 
197
197
  async function registerPlugin(): Promise<void> {
198
- const settingsPath = join(homedir(), ".claude", "settings.json");
198
+ const claudeDir = join(homedir(), ".claude");
199
+ const settingsPath = join(claudeDir, "settings.json");
200
+ const installedPluginsPath = join(claudeDir, "plugins", "installed_plugins.json");
199
201
 
202
+ // 1. Update settings.json to enable the plugin
200
203
  let settings: Record<string, unknown> = {};
201
-
202
- // Read existing settings if they exist
203
204
  if (existsSync(settingsPath)) {
204
205
  try {
205
206
  const content = await readFile(settingsPath, "utf-8");
206
207
  settings = JSON.parse(content);
207
208
  } catch {
208
- // If parse fails, start fresh
209
209
  settings = {};
210
210
  }
211
211
  }
212
212
 
213
- // Ensure enabledPlugins exists
214
213
  if (!settings.enabledPlugins) {
215
214
  settings.enabledPlugins = {};
216
215
  }
216
+ (settings.enabledPlugins as Record<string, boolean>)["think@local"] = true;
217
217
 
218
- // Add think plugin (local plugins don't need @marketplace suffix)
219
- (settings.enabledPlugins as Record<string, boolean>)["think"] = true;
220
-
221
- // Write updated settings
222
218
  await writeFile(settingsPath, JSON.stringify(settings, null, 2));
219
+
220
+ // 2. Update installed_plugins.json to register the plugin
221
+ let installedPlugins: Record<string, unknown> = { version: 2, plugins: {} };
222
+ if (existsSync(installedPluginsPath)) {
223
+ try {
224
+ const content = await readFile(installedPluginsPath, "utf-8");
225
+ installedPlugins = JSON.parse(content);
226
+ } catch {
227
+ installedPlugins = { version: 2, plugins: {} };
228
+ }
229
+ }
230
+
231
+ const plugins = installedPlugins.plugins as Record<string, unknown[]>;
232
+ plugins["think@local"] = [
233
+ {
234
+ scope: "user",
235
+ installPath: CONFIG.pluginDir,
236
+ version: "local",
237
+ installedAt: new Date().toISOString(),
238
+ lastUpdated: new Date().toISOString(),
239
+ },
240
+ ];
241
+
242
+ await writeFile(installedPluginsPath, JSON.stringify(installedPlugins, null, 2));
223
243
  }