claude-think 0.1.0

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.
Files changed (51) hide show
  1. package/.claude/settings.local.json +19 -0
  2. package/.think.yaml +30 -0
  3. package/CHANGELOG.md +20 -0
  4. package/CLAUDE.md +111 -0
  5. package/README.md +97 -0
  6. package/bun.lock +144 -0
  7. package/package.json +37 -0
  8. package/src/cli/commands/allow.ts +46 -0
  9. package/src/cli/commands/edit.ts +57 -0
  10. package/src/cli/commands/help.ts +64 -0
  11. package/src/cli/commands/init.ts +76 -0
  12. package/src/cli/commands/learn.ts +50 -0
  13. package/src/cli/commands/profile.ts +30 -0
  14. package/src/cli/commands/project.ts +64 -0
  15. package/src/cli/commands/review.ts +130 -0
  16. package/src/cli/commands/setup.ts +220 -0
  17. package/src/cli/commands/status.ts +66 -0
  18. package/src/cli/commands/sync.ts +30 -0
  19. package/src/cli/commands/tree.ts +30 -0
  20. package/src/cli/index.ts +126 -0
  21. package/src/core/banner.ts +25 -0
  22. package/src/core/config.ts +57 -0
  23. package/src/core/dedup.ts +75 -0
  24. package/src/core/file-tree.ts +255 -0
  25. package/src/core/generator.ts +189 -0
  26. package/src/core/parser.ts +65 -0
  27. package/src/core/project-detect.ts +120 -0
  28. package/src/templates/allowed-commands.md +19 -0
  29. package/src/templates/anti-patterns.md +11 -0
  30. package/src/templates/corrections.md +4 -0
  31. package/src/templates/file-tree.md +28 -0
  32. package/src/templates/learnings.md +4 -0
  33. package/src/templates/patterns.md +10 -0
  34. package/src/templates/pending.md +5 -0
  35. package/src/templates/profile.md +11 -0
  36. package/src/templates/settings.md +6 -0
  37. package/src/templates/subagents.md +15 -0
  38. package/src/templates/tools.md +13 -0
  39. package/src/templates/workflows.md +9 -0
  40. package/src/tui/App.tsx +100 -0
  41. package/src/tui/components/Agents.tsx +117 -0
  42. package/src/tui/components/Automation.tsx +88 -0
  43. package/src/tui/components/Help.tsx +56 -0
  44. package/src/tui/components/Memory.tsx +101 -0
  45. package/src/tui/components/Navigation.tsx +63 -0
  46. package/src/tui/components/Permissions.tsx +88 -0
  47. package/src/tui/components/Preferences.tsx +89 -0
  48. package/src/tui/components/Profile.tsx +62 -0
  49. package/src/tui/components/Skills.tsx +118 -0
  50. package/src/tui/index.tsx +7 -0
  51. package/tsconfig.json +29 -0
@@ -0,0 +1,19 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(bun init:*)",
5
+ "Bash(bun add:*)",
6
+ "Bash(bun run:*)",
7
+ "Bash(bun link:*)",
8
+ "Bash(think --help:*)",
9
+ "Bash(think)",
10
+ "Bash(think tree)",
11
+ "Bash(think project init:*)",
12
+ "Bash(think help)",
13
+ "Bash(think --version:*)",
14
+ "Bash(think status)",
15
+ "Bash(think sync)",
16
+ "Bash(git push:*)"
17
+ ]
18
+ }
19
+ }
package/.think.yaml ADDED
@@ -0,0 +1,30 @@
1
+ # Think Project Configuration
2
+ # This file customizes how 'think' generates context for this project.
3
+
4
+ # Project type (auto-detected: node)
5
+ # Uncomment to override: type: node
6
+
7
+ # Project name (auto-detected: think)
8
+ # name: think
9
+
10
+ # Additional patterns to exclude from file tree
11
+ # excludes:
12
+ # - "*.log"
13
+ # - "tmp/"
14
+
15
+ # Additional patterns to include (overrides excludes)
16
+ # includes:
17
+ # - "important.log"
18
+
19
+ # Custom file annotations
20
+ # annotations:
21
+ # src/main.ts: "application entry point"
22
+ # src/config.ts: "configuration loader"
23
+
24
+ # Project-specific context for Claude
25
+ # (This content will be included in the generated CLAUDE.md)
26
+ ---
27
+
28
+ # Project Context
29
+
30
+ Add any project-specific context here that Claude should know about.
package/CHANGELOG.md ADDED
@@ -0,0 +1,20 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2025-02-05
9
+
10
+ ### Added
11
+ - Initial release
12
+ - CLI commands: `init`, `sync`, `status`, `learn`, `review`, `profile`, `edit`, `allow`, `tree`, `project init`, `help`, `setup`
13
+ - Interactive TUI with Ink (React)
14
+ - Profile builder wizard (`think setup`)
15
+ - Semantic deduplication for learnings
16
+ - Project type detection (Node, Bun, Rust, Python, Go, etc.)
17
+ - Annotated file tree generation
18
+ - Auto-generated Claude plugin at `~/.claude/plugins/think/`
19
+ - Pre-approved commands hook
20
+ - Learning suggestion hook for Claude
package/CLAUDE.md ADDED
@@ -0,0 +1,111 @@
1
+ ---
2
+ description: Use Bun instead of Node.js, npm, pnpm, or vite.
3
+ globs: "*.ts, *.tsx, *.html, *.css, *.js, *.jsx, package.json"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ Default to using Bun instead of Node.js.
8
+
9
+ - Use `bun <file>` instead of `node <file>` or `ts-node <file>`
10
+ - Use `bun test` instead of `jest` or `vitest`
11
+ - Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
12
+ - Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
13
+ - Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`
14
+ - Use `bunx <package> <command>` instead of `npx <package> <command>`
15
+ - Bun automatically loads .env, so don't use dotenv.
16
+
17
+ ## APIs
18
+
19
+ - `Bun.serve()` supports WebSockets, HTTPS, and routes. Don't use `express`.
20
+ - `bun:sqlite` for SQLite. Don't use `better-sqlite3`.
21
+ - `Bun.redis` for Redis. Don't use `ioredis`.
22
+ - `Bun.sql` for Postgres. Don't use `pg` or `postgres.js`.
23
+ - `WebSocket` is built-in. Don't use `ws`.
24
+ - Prefer `Bun.file` over `node:fs`'s readFile/writeFile
25
+ - Bun.$`ls` instead of execa.
26
+
27
+ ## Testing
28
+
29
+ Use `bun test` to run tests.
30
+
31
+ ```ts#index.test.ts
32
+ import { test, expect } from "bun:test";
33
+
34
+ test("hello world", () => {
35
+ expect(1).toBe(1);
36
+ });
37
+ ```
38
+
39
+ ## Frontend
40
+
41
+ Use HTML imports with `Bun.serve()`. Don't use `vite`. HTML imports fully support React, CSS, Tailwind.
42
+
43
+ Server:
44
+
45
+ ```ts#index.ts
46
+ import index from "./index.html"
47
+
48
+ Bun.serve({
49
+ routes: {
50
+ "/": index,
51
+ "/api/users/:id": {
52
+ GET: (req) => {
53
+ return new Response(JSON.stringify({ id: req.params.id }));
54
+ },
55
+ },
56
+ },
57
+ // optional websocket support
58
+ websocket: {
59
+ open: (ws) => {
60
+ ws.send("Hello, world!");
61
+ },
62
+ message: (ws, message) => {
63
+ ws.send(message);
64
+ },
65
+ close: (ws) => {
66
+ // handle close
67
+ }
68
+ },
69
+ development: {
70
+ hmr: true,
71
+ console: true,
72
+ }
73
+ })
74
+ ```
75
+
76
+ HTML files can import .tsx, .jsx or .js files directly and Bun's bundler will transpile & bundle automatically. `<link>` tags can point to stylesheets and Bun's CSS bundler will bundle.
77
+
78
+ ```html#index.html
79
+ <html>
80
+ <body>
81
+ <h1>Hello, world!</h1>
82
+ <script type="module" src="./frontend.tsx"></script>
83
+ </body>
84
+ </html>
85
+ ```
86
+
87
+ With the following `frontend.tsx`:
88
+
89
+ ```tsx#frontend.tsx
90
+ import React from "react";
91
+ import { createRoot } from "react-dom/client";
92
+
93
+ // import .css files directly and it works
94
+ import './index.css';
95
+
96
+ const root = createRoot(document.body);
97
+
98
+ export default function Frontend() {
99
+ return <h1>Hello, world!</h1>;
100
+ }
101
+
102
+ root.render(<Frontend />);
103
+ ```
104
+
105
+ Then, run index.ts
106
+
107
+ ```sh
108
+ bun --hot ./index.ts
109
+ ```
110
+
111
+ For more information, read the Bun API docs in `node_modules/bun-types/docs/**.mdx`.
package/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # think
2
+
3
+ Personal context manager for Claude. Stop repeating yourself.
4
+
5
+ ```
6
+ ╭────────────────────────────────────────────╮
7
+ │ │
8
+ │ ████████╗██╗ ██╗██╗███╗ ██╗██╗ ██╗ │
9
+ │ ╚══██╔══╝██║ ██║██║████╗ ██║██║ ██╔╝ │
10
+ │ ██║ ███████║██║██╔██╗ ██║█████╔╝ │
11
+ │ ██║ ██╔══██║██║██║╚██╗██║██╔═██╗ │
12
+ │ ██║ ██║ ██║██║██║ ╚████║██║ ██╗ │
13
+ │ ╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝ │
14
+ │ │
15
+ │ Personal Context for Claude │
16
+ │ │
17
+ ╰────────────────────────────────────────────╯
18
+ ```
19
+
20
+ ## What is this?
21
+
22
+ `think` manages your personal preferences, patterns, and memory for Claude Code. Instead of repeating "use bun not npm" or "be direct, skip the fluff" every session, configure it once and Claude remembers.
23
+
24
+ ## Install
25
+
26
+ ```bash
27
+ # With bun (recommended)
28
+ bun install -g think-cli
29
+
30
+ # With npm
31
+ npm install -g think-cli
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ ```bash
37
+ # Initialize your config
38
+ think init
39
+
40
+ # Run the setup wizard
41
+ think setup
42
+
43
+ # Start using Claude - your context is automatically loaded
44
+ claude
45
+ ```
46
+
47
+ ## How it works
48
+
49
+ 1. Your preferences live in `~/.think/` (markdown files)
50
+ 2. `think sync` generates a Claude plugin at `~/.claude/plugins/think/`
51
+ 3. Claude Code auto-loads the plugin, so your context is always there
52
+
53
+ ## Commands
54
+
55
+ | Command | Description |
56
+ |---------|-------------|
57
+ | `think` | Launch interactive TUI |
58
+ | `think init` | Initialize ~/.think |
59
+ | `think setup` | Interactive profile wizard |
60
+ | `think sync` | Regenerate Claude plugin |
61
+ | `think status` | Show current status |
62
+ | `think learn "..."` | Add a learning |
63
+ | `think review` | Review Claude's suggestions |
64
+ | `think profile` | Edit your profile |
65
+ | `think edit <file>` | Edit any config file |
66
+ | `think allow "cmd"` | Pre-approve a command |
67
+ | `think tree` | Preview project file tree |
68
+ | `think help` | Show all commands |
69
+
70
+ ## What you can configure
71
+
72
+ - **Profile** - Communication style, preferences
73
+ - **Tools** - Package manager, languages, editor
74
+ - **Patterns** - Coding patterns to follow
75
+ - **Anti-patterns** - Things to avoid
76
+ - **Permissions** - Pre-approved commands (no prompts)
77
+ - **Memory** - Learnings that persist across sessions
78
+ - **Skills & Agents** - Custom workflows for Claude
79
+
80
+ ## Example
81
+
82
+ After setup, Claude automatically knows:
83
+
84
+ ```markdown
85
+ # About Amit
86
+ - Be direct and minimal
87
+ - Use bun, not npm
88
+ - TypeScript and Rust
89
+ - Don't over-engineer
90
+ - Don't explain obvious things
91
+ ```
92
+
93
+ No more repeating yourself.
94
+
95
+ ## License
96
+
97
+ MIT
package/bun.lock ADDED
@@ -0,0 +1,144 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "configVersion": 1,
4
+ "workspaces": {
5
+ "": {
6
+ "name": "think",
7
+ "dependencies": {
8
+ "chalk": "^5.6.2",
9
+ "commander": "^14.0.3",
10
+ "gray-matter": "^4.0.3",
11
+ "ink": "^6.6.0",
12
+ "react": "^19.2.4",
13
+ "string-similarity": "^4.0.4",
14
+ },
15
+ "devDependencies": {
16
+ "@types/bun": "latest",
17
+ "@types/react": "^19.2.13",
18
+ "@types/string-similarity": "^4.0.2",
19
+ },
20
+ "peerDependencies": {
21
+ "typescript": "^5",
22
+ },
23
+ },
24
+ },
25
+ "packages": {
26
+ "@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.4", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-HTgrrTgZ9Jgeo6Z3oqbQ7lifOVvRR14vaDuBGPPUxk9Thm+vObaO4QfYYYWw4Zo5CWQDBEfsinFA6Gre+AqwNQ=="],
27
+
28
+ "@types/bun": ["@types/bun@1.3.8", "", { "dependencies": { "bun-types": "1.3.8" } }, "sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA=="],
29
+
30
+ "@types/node": ["@types/node@25.2.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg=="],
31
+
32
+ "@types/react": ["@types/react@19.2.13", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-KkiJeU6VbYbUOp5ITMIc7kBfqlYkKA5KhEHVrGMmUUMt7NeaZg65ojdPk+FtNrBAOXNVM5QM72jnADjM+XVRAQ=="],
33
+
34
+ "@types/string-similarity": ["@types/string-similarity@4.0.2", "", {}, "sha512-LkJQ/jsXtCVMK+sKYAmX/8zEq+/46f1PTQw7YtmQwb74jemS1SlNLmARM2Zml9DgdDTWKAtc5L13WorpHPDjDA=="],
35
+
36
+ "ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="],
37
+
38
+ "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
39
+
40
+ "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
41
+
42
+ "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
43
+
44
+ "auto-bind": ["auto-bind@5.0.1", "", {}, "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg=="],
45
+
46
+ "bun-types": ["bun-types@1.3.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q=="],
47
+
48
+ "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
49
+
50
+ "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="],
51
+
52
+ "cli-cursor": ["cli-cursor@4.0.0", "", { "dependencies": { "restore-cursor": "^4.0.0" } }, "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg=="],
53
+
54
+ "cli-truncate": ["cli-truncate@5.1.1", "", { "dependencies": { "slice-ansi": "^7.1.0", "string-width": "^8.0.0" } }, "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A=="],
55
+
56
+ "code-excerpt": ["code-excerpt@4.0.0", "", { "dependencies": { "convert-to-spaces": "^2.0.1" } }, "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA=="],
57
+
58
+ "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="],
59
+
60
+ "convert-to-spaces": ["convert-to-spaces@2.0.1", "", {}, "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ=="],
61
+
62
+ "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
63
+
64
+ "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
65
+
66
+ "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="],
67
+
68
+ "es-toolkit": ["es-toolkit@1.44.0", "", {}, "sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg=="],
69
+
70
+ "escape-string-regexp": ["escape-string-regexp@2.0.0", "", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="],
71
+
72
+ "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
73
+
74
+ "extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="],
75
+
76
+ "get-east-asian-width": ["get-east-asian-width@1.4.0", "", {}, "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q=="],
77
+
78
+ "gray-matter": ["gray-matter@4.0.3", "", { "dependencies": { "js-yaml": "^3.13.1", "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" } }, "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q=="],
79
+
80
+ "indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="],
81
+
82
+ "ink": ["ink@6.6.0", "", { "dependencies": { "@alcalzone/ansi-tokenize": "^0.2.1", "ansi-escapes": "^7.2.0", "ansi-styles": "^6.2.1", "auto-bind": "^5.0.1", "chalk": "^5.6.0", "cli-boxes": "^3.0.0", "cli-cursor": "^4.0.0", "cli-truncate": "^5.1.1", "code-excerpt": "^4.0.0", "es-toolkit": "^1.39.10", "indent-string": "^5.0.0", "is-in-ci": "^2.0.0", "patch-console": "^2.0.0", "react-reconciler": "^0.33.0", "signal-exit": "^3.0.7", "slice-ansi": "^7.1.0", "stack-utils": "^2.0.6", "string-width": "^8.1.0", "type-fest": "^4.27.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0", "ws": "^8.18.0", "yoga-layout": "~3.2.1" }, "peerDependencies": { "@types/react": ">=19.0.0", "react": ">=19.0.0", "react-devtools-core": "^6.1.2" }, "optionalPeers": ["@types/react", "react-devtools-core"] }, "sha512-QDt6FgJxgmSxAelcOvOHUvFxbIUjVpCH5bx+Slvc5m7IEcpGt3dYwbz/L+oRnqEGeRvwy1tineKK4ect3nW1vQ=="],
83
+
84
+ "is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="],
85
+
86
+ "is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="],
87
+
88
+ "is-in-ci": ["is-in-ci@2.0.0", "", { "bin": { "is-in-ci": "cli.js" } }, "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w=="],
89
+
90
+ "js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="],
91
+
92
+ "kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="],
93
+
94
+ "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
95
+
96
+ "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
97
+
98
+ "patch-console": ["patch-console@2.0.0", "", {}, "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA=="],
99
+
100
+ "react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
101
+
102
+ "react-reconciler": ["react-reconciler@0.33.0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA=="],
103
+
104
+ "restore-cursor": ["restore-cursor@4.0.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg=="],
105
+
106
+ "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
107
+
108
+ "section-matter": ["section-matter@1.0.0", "", { "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" } }, "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA=="],
109
+
110
+ "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
111
+
112
+ "slice-ansi": ["slice-ansi@7.1.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w=="],
113
+
114
+ "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="],
115
+
116
+ "stack-utils": ["stack-utils@2.0.6", "", { "dependencies": { "escape-string-regexp": "^2.0.0" } }, "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ=="],
117
+
118
+ "string-similarity": ["string-similarity@4.0.4", "", {}, "sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ=="],
119
+
120
+ "string-width": ["string-width@8.1.1", "", { "dependencies": { "get-east-asian-width": "^1.3.0", "strip-ansi": "^7.1.0" } }, "sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw=="],
121
+
122
+ "strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
123
+
124
+ "strip-bom-string": ["strip-bom-string@1.0.0", "", {}, "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g=="],
125
+
126
+ "type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
127
+
128
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
129
+
130
+ "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
131
+
132
+ "widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="],
133
+
134
+ "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="],
135
+
136
+ "ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="],
137
+
138
+ "yoga-layout": ["yoga-layout@3.2.1", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="],
139
+
140
+ "widest-line/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
141
+
142
+ "wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
143
+ }
144
+ }
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "claude-think",
3
+ "version": "0.1.0",
4
+ "description": "Personal context manager for Claude - manage your preferences, patterns, and memory",
5
+ "author": "Amit Feldman",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/amit-feldman/think"
10
+ },
11
+ "homepage": "https://github.com/amit-feldman/think#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/amit-feldman/think/issues"
14
+ },
15
+ "keywords": ["claude", "cli", "context", "ai", "productivity", "bun"],
16
+ "module": "src/cli/index.ts",
17
+ "type": "module",
18
+ "bin": {
19
+ "think": "src/cli/index.ts"
20
+ },
21
+ "devDependencies": {
22
+ "@types/bun": "latest",
23
+ "@types/react": "^19.2.13",
24
+ "@types/string-similarity": "^4.0.2"
25
+ },
26
+ "peerDependencies": {
27
+ "typescript": "^5"
28
+ },
29
+ "dependencies": {
30
+ "chalk": "^5.6.2",
31
+ "commander": "^14.0.3",
32
+ "gray-matter": "^4.0.3",
33
+ "ink": "^6.6.0",
34
+ "react": "^19.2.4",
35
+ "string-similarity": "^4.0.4"
36
+ }
37
+ }
@@ -0,0 +1,46 @@
1
+ import { existsSync } from "fs";
2
+ import { readFile, writeFile } from "fs/promises";
3
+ import chalk from "chalk";
4
+ import { CONFIG, thinkPath } from "../../core/config";
5
+ import { syncCommand } from "./sync";
6
+
7
+ /**
8
+ * Add a command to the allowed list
9
+ */
10
+ export async function allowCommand(
11
+ command: string,
12
+ options: { noSync?: boolean }
13
+ ): Promise<void> {
14
+ if (!existsSync(CONFIG.thinkDir)) {
15
+ console.log(chalk.red("~/.think not found. Run `think init` first."));
16
+ process.exit(1);
17
+ }
18
+
19
+ const allowedPath = thinkPath(CONFIG.files.allowedCommands);
20
+
21
+ // Read existing content
22
+ let content = "";
23
+ if (existsSync(allowedPath)) {
24
+ content = await readFile(allowedPath, "utf-8");
25
+ }
26
+
27
+ // Check if command already exists
28
+ if (content.includes(`- ${command}`)) {
29
+ console.log(chalk.yellow("Command already in allowed list:"));
30
+ console.log(chalk.dim(` "${command}"`));
31
+ return;
32
+ }
33
+
34
+ // Append command
35
+ const newContent = content.trimEnd() + `\n- ${command}\n`;
36
+ await writeFile(allowedPath, newContent);
37
+
38
+ console.log(chalk.green("Command added to allowed list:"));
39
+ console.log(chalk.dim(` "${command}"`));
40
+
41
+ // Auto-sync unless disabled
42
+ if (!options.noSync) {
43
+ console.log();
44
+ await syncCommand();
45
+ }
46
+ }
@@ -0,0 +1,57 @@
1
+ import { existsSync } from "fs";
2
+ import { spawn } from "child_process";
3
+ import chalk from "chalk";
4
+ import { CONFIG, thinkPath } from "../../core/config";
5
+
6
+ /**
7
+ * Open any ~/.think file in $EDITOR
8
+ */
9
+ export async function editCommand(file: string): Promise<void> {
10
+ if (!existsSync(CONFIG.thinkDir)) {
11
+ console.log(chalk.red("~/.think not found. Run `think init` first."));
12
+ process.exit(1);
13
+ }
14
+
15
+ // Support shortcuts
16
+ const shortcuts: Record<string, string> = {
17
+ profile: CONFIG.files.profile,
18
+ tools: CONFIG.files.tools,
19
+ patterns: CONFIG.files.patterns,
20
+ "anti-patterns": CONFIG.files.antiPatterns,
21
+ commands: CONFIG.files.allowedCommands,
22
+ learnings: CONFIG.files.learnings,
23
+ corrections: CONFIG.files.corrections,
24
+ pending: CONFIG.files.pending,
25
+ subagents: CONFIG.files.subagents,
26
+ workflows: CONFIG.files.workflows,
27
+ "file-tree": CONFIG.files.fileTree,
28
+ };
29
+
30
+ const resolvedFile = shortcuts[file] || file;
31
+ const filePath = thinkPath(resolvedFile);
32
+
33
+ if (!existsSync(filePath)) {
34
+ console.log(chalk.red(`File not found: ${filePath}`));
35
+ console.log();
36
+ console.log("Available shortcuts:");
37
+ for (const [shortcut, path] of Object.entries(shortcuts)) {
38
+ console.log(` ${chalk.cyan(shortcut)} -> ${path}`);
39
+ }
40
+ process.exit(1);
41
+ }
42
+
43
+ const editor = process.env.EDITOR || "vi";
44
+
45
+ console.log(chalk.dim(`Opening ${filePath} in ${editor}...`));
46
+
47
+ const child = spawn(editor, [filePath], {
48
+ stdio: "inherit",
49
+ });
50
+
51
+ child.on("exit", (code) => {
52
+ if (code === 0) {
53
+ console.log();
54
+ console.log(chalk.dim("Run `think sync` to apply changes."));
55
+ }
56
+ });
57
+ }
@@ -0,0 +1,64 @@
1
+ import chalk from "chalk";
2
+ import { printBanner } from "../../core/banner";
3
+
4
+ /**
5
+ * Show help with command reference
6
+ */
7
+ export async function helpCommand(): Promise<void> {
8
+ printBanner();
9
+
10
+ console.log(chalk.bold("Commands:\n"));
11
+
12
+ const commands = [
13
+ { cmd: "think", desc: "Launch interactive TUI" },
14
+ { cmd: "think init", desc: "Initialize ~/.think with templates" },
15
+ { cmd: "think setup", desc: "Interactive profile setup wizard" },
16
+ { cmd: "think sync", desc: "Regenerate Claude plugin from ~/.think" },
17
+ { cmd: "think status", desc: "Show current status" },
18
+ { cmd: "", desc: "" },
19
+ { cmd: "think learn <text>", desc: "Add a learning" },
20
+ { cmd: "think review", desc: "Review pending learnings from Claude" },
21
+ { cmd: "", desc: "" },
22
+ { cmd: "think profile", desc: "Edit profile in $EDITOR" },
23
+ { cmd: "think edit <file>", desc: "Edit any ~/.think file" },
24
+ { cmd: "", desc: "" },
25
+ { cmd: "think allow <cmd>", desc: "Add command to allowed list" },
26
+ { cmd: "", desc: "" },
27
+ { cmd: "think tree", desc: "Preview file tree for current directory" },
28
+ { cmd: "think project init", desc: "Create .think.yaml for project" },
29
+ ];
30
+
31
+ for (const { cmd, desc } of commands) {
32
+ if (!cmd) {
33
+ console.log();
34
+ continue;
35
+ }
36
+ console.log(` ${chalk.green(cmd.padEnd(22))} ${chalk.dim(desc)}`);
37
+ }
38
+
39
+ console.log();
40
+ console.log(chalk.bold("Edit shortcuts:\n"));
41
+
42
+ const shortcuts = [
43
+ "profile",
44
+ "tools",
45
+ "patterns",
46
+ "anti-patterns",
47
+ "commands",
48
+ "learnings",
49
+ "corrections",
50
+ "pending",
51
+ "subagents",
52
+ "workflows",
53
+ ];
54
+
55
+ console.log(` ${chalk.dim("think edit")} ${chalk.cyan(shortcuts.join(" | "))}`);
56
+
57
+ console.log();
58
+ console.log(chalk.bold("Files:\n"));
59
+ console.log(` ${chalk.dim("Source:")} ~/.think/`);
60
+ console.log(` ${chalk.dim("Plugin:")} ~/.claude/plugins/think/`);
61
+ console.log(` ${chalk.dim("Project:")} .think.yaml (optional)`);
62
+
63
+ console.log();
64
+ }