athar-mcp 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.
- package/LICENSE +21 -0
- package/README.md +242 -0
- package/dist/cli/commands/list.d.ts +10 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +73 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/review.d.ts +2 -0
- package/dist/cli/commands/review.d.ts.map +1 -0
- package/dist/cli/commands/review.js +112 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +2 -0
- package/dist/cli/commands/setup.d.ts.map +1 -0
- package/dist/cli/commands/setup.js +55 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/status.d.ts +2 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +39 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/index.d.ts +12 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +43 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/db/connection.d.ts +11 -0
- package/dist/db/connection.d.ts.map +1 -0
- package/dist/db/connection.js +49 -0
- package/dist/db/connection.js.map +1 -0
- package/dist/db/schema.d.ts +12 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +95 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +139 -0
- package/dist/server.js.map +1 -0
- package/dist/smoke-test.d.ts +7 -0
- package/dist/smoke-test.d.ts.map +1 -0
- package/dist/smoke-test.js +99 -0
- package/dist/smoke-test.js.map +1 -0
- package/dist/spaced-repetition/scheduler.d.ts +46 -0
- package/dist/spaced-repetition/scheduler.d.ts.map +1 -0
- package/dist/spaced-repetition/scheduler.js +98 -0
- package/dist/spaced-repetition/scheduler.js.map +1 -0
- package/dist/spaced-repetition/sm2.d.ts +36 -0
- package/dist/spaced-repetition/sm2.d.ts.map +1 -0
- package/dist/spaced-repetition/sm2.js +90 -0
- package/dist/spaced-repetition/sm2.js.map +1 -0
- package/dist/tools/memory.d.ts +25 -0
- package/dist/tools/memory.d.ts.map +1 -0
- package/dist/tools/memory.js +112 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/tools/save-lesson.d.ts +11 -0
- package/dist/tools/save-lesson.d.ts.map +1 -0
- package/dist/tools/save-lesson.js +137 -0
- package/dist/tools/save-lesson.js.map +1 -0
- package/dist/tools/validators.d.ts +82 -0
- package/dist/tools/validators.d.ts.map +1 -0
- package/dist/tools/validators.js +86 -0
- package/dist/tools/validators.js.map +1 -0
- package/dist/utils/logger.d.ts +23 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +55 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/paths.d.ts +17 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +43 -0
- package/dist/utils/paths.js.map +1 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ameen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# Ų£Ų«Ų± ā Athar
|
|
2
|
+
|
|
3
|
+
> **Every mistake leaves a trace, every lesson leaves an impact.**
|
|
4
|
+
|
|
5
|
+
An open-source, local-first MCP server that captures programming lessons from AI-assisted coding sessions, stores them in a local SQLite database, and uses spaced repetition to ensure you never repeat the same mistake twice.
|
|
6
|
+
|
|
7
|
+
<div align="center">
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+

|
|
11
|
+

|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## š§ What is Athar?
|
|
19
|
+
|
|
20
|
+
**Athar** (Ų£Ų«Ų±) is a memory system for developers. It works as an [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that integrates with AI-powered IDEs like [Antigravity IDE](https://antigravity.google).
|
|
21
|
+
|
|
22
|
+
When you're coding with an AI assistant and it helps you fix a real bug, Athar automatically captures the lesson ā the problem, root cause, fix, and review questions ā and stores it locally. Later, it uses **spaced repetition** (SM-2 algorithm) to quiz you on past mistakes so they stick in your memory permanently.
|
|
23
|
+
|
|
24
|
+
### How it works
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
āāāāāāāāāāāāāāāāāāāāāāā stdio āāāāāāāāāāāāāāāāāāāā
|
|
28
|
+
ā Antigravity IDE ā āāāāāāāāāāāāāāŗ ā Athar MCP ā
|
|
29
|
+
ā (AI Assistant) ā JSON-RPC ā Server ā
|
|
30
|
+
āāāāāāāāāāāāāāāāāāāāāāā āāāāāāāāāā¬āāāāāāāāāā
|
|
31
|
+
ā
|
|
32
|
+
āāāāāāāāāā¼āāāāāāāāāā
|
|
33
|
+
ā SQLite DB ā
|
|
34
|
+
ā (local-first) ā
|
|
35
|
+
ā ~/.local/share/ ā
|
|
36
|
+
ā athar/lessons.dbā
|
|
37
|
+
āāāāāāāāāāāāāāāāāāāā
|
|
38
|
+
ā
|
|
39
|
+
āāāāāāāāāā¼āāāāāāāāāā
|
|
40
|
+
ā CLI & Dashboard ā
|
|
41
|
+
ā athar review ā
|
|
42
|
+
ā athar status ā
|
|
43
|
+
āāāāāāāāāāāāāāāāāāāā
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## ⨠Features
|
|
49
|
+
|
|
50
|
+
- **š MCP Integration** ā Works seamlessly with Antigravity IDE via stdio transport
|
|
51
|
+
- **š Smart Lesson Capture** ā AI assistant saves lessons with structured data: problem, root cause, bad/good code, review questions
|
|
52
|
+
- **š”ļø Quality Validation** ā Rejects trivial changes (formatting, typos) and detects duplicates
|
|
53
|
+
- **š Full-Text Search** ā FTS5-powered search to recall past lessons instantly
|
|
54
|
+
- **š§ Spaced Repetition** ā SM-2 algorithm schedules reviews at optimal intervals
|
|
55
|
+
- **š¾ Local-First** ā All data stored locally in SQLite. No cloud, no API keys, no costs
|
|
56
|
+
- **š Bilingual** ā Supports lessons in both Arabic and English
|
|
57
|
+
- **ā” Zero Native Dependencies** ā Uses Node.js built-in `node:sqlite` module
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## š Quick Start
|
|
62
|
+
|
|
63
|
+
### Prerequisites
|
|
64
|
+
|
|
65
|
+
- **Node.js** ā„ 20 (tested on v24)
|
|
66
|
+
- **Antigravity IDE** (or any MCP-compatible IDE)
|
|
67
|
+
|
|
68
|
+
### Installation
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Clone the repository
|
|
72
|
+
git clone https://github.com/ameenmv/athar.git
|
|
73
|
+
cd athar
|
|
74
|
+
|
|
75
|
+
# Install dependencies
|
|
76
|
+
npm install
|
|
77
|
+
|
|
78
|
+
# Build
|
|
79
|
+
npm run build
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Setup with Antigravity IDE
|
|
83
|
+
|
|
84
|
+
Run the setup command (coming in Phase 2), or manually add to your MCP config:
|
|
85
|
+
|
|
86
|
+
**`~/.gemini/config/mcp_config.json`**
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"mcpServers": {
|
|
91
|
+
"athar": {
|
|
92
|
+
"command": "node",
|
|
93
|
+
"args": ["/absolute/path/to/athar/dist/index.js"]
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Then restart/refresh MCP servers in Antigravity IDE.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## š ļø MCP Tools
|
|
104
|
+
|
|
105
|
+
Athar exposes two tools to the AI assistant:
|
|
106
|
+
|
|
107
|
+
### `save_lesson`
|
|
108
|
+
|
|
109
|
+
Captures a programming lesson from a real mistake.
|
|
110
|
+
|
|
111
|
+
| Field | Type | Required | Description |
|
|
112
|
+
|-------|------|----------|-------------|
|
|
113
|
+
| `title` | string | ā
| Concise title describing the mistake pattern |
|
|
114
|
+
| `problem` | string | ā
| What went wrong ā the symptom observed |
|
|
115
|
+
| `root_cause` | string | ā
| WHY it happened ā the actual root cause |
|
|
116
|
+
| `lesson` | string | ā
| Key takeaway ā what to remember |
|
|
117
|
+
| `tags` | string[] | ā
| Categorization tags |
|
|
118
|
+
| `review_questions` | {q,a}[] | ā
| 1-3 review questions for spaced repetition |
|
|
119
|
+
| `error_message` | string | ā | Exact error message or stack trace |
|
|
120
|
+
| `bad_code` | string | ā | The incorrect code snippet |
|
|
121
|
+
| `good_code` | string | ā | The corrected code snippet |
|
|
122
|
+
| `language` | string | ā | Programming language |
|
|
123
|
+
| `file_path` | string | ā | File where the error occurred |
|
|
124
|
+
| `git_diff` | string | ā | Git diff context |
|
|
125
|
+
|
|
126
|
+
**Validation rules:**
|
|
127
|
+
- Rejects trivial formatting/style changes
|
|
128
|
+
- Rejects if problem and root_cause are identical
|
|
129
|
+
- Requires both bad_code and good_code if either is provided
|
|
130
|
+
- Detects and rejects duplicates via FTS5 similarity
|
|
131
|
+
|
|
132
|
+
### `memory`
|
|
133
|
+
|
|
134
|
+
Searches past lessons for relevant mistakes and solutions.
|
|
135
|
+
|
|
136
|
+
| Field | Type | Required | Description |
|
|
137
|
+
|-------|------|----------|-------------|
|
|
138
|
+
| `query` | string | ā
| Search query ā keyword, error pattern, or tag |
|
|
139
|
+
| `limit` | number | ā | Max results (1-10, default: 3) |
|
|
140
|
+
| `language` | string | ā | Filter by programming language |
|
|
141
|
+
| `tags` | string[] | ā | Filter by tags |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## š Project Structure
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
athar/
|
|
149
|
+
āāā src/
|
|
150
|
+
ā āāā index.ts # MCP server entry point
|
|
151
|
+
ā āāā server.ts # McpServer setup & tool registration
|
|
152
|
+
ā āāā db/
|
|
153
|
+
ā ā āāā schema.ts # SQLite schema + FTS5 + triggers
|
|
154
|
+
ā ā āāā connection.ts # Database singleton
|
|
155
|
+
ā āāā tools/
|
|
156
|
+
ā ā āāā save-lesson.ts # save_lesson handler + validation
|
|
157
|
+
ā ā āāā memory.ts # memory search handler
|
|
158
|
+
ā ā āāā validators.ts # Zod schemas
|
|
159
|
+
ā āāā spaced-repetition/ # SM-2 algorithm (Phase 3)
|
|
160
|
+
ā āāā cli/ # CLI commands (Phase 3)
|
|
161
|
+
ā āāā utils/
|
|
162
|
+
ā āāā paths.ts # XDG-compliant paths
|
|
163
|
+
ā āāā logger.ts # stderr-only logger
|
|
164
|
+
āāā dashboard/ # Nuxt 4 web UI (Phase 4)
|
|
165
|
+
āāā package.json
|
|
166
|
+
āāā tsconfig.json
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## šŗļø Roadmap
|
|
172
|
+
|
|
173
|
+
- [x] **Phase 1** ā Core MCP Server & Database
|
|
174
|
+
- [x] SQLite schema with FTS5 full-text search
|
|
175
|
+
- [x] `save_lesson` tool with quality validation
|
|
176
|
+
- [x] `memory` search tool with FTS5 + LIKE fallback
|
|
177
|
+
- [x] Duplicate detection
|
|
178
|
+
- [x] stderr-only logging (MCP-safe)
|
|
179
|
+
|
|
180
|
+
- [ ] **Phase 2** ā IDE Integration
|
|
181
|
+
- [ ] `athar setup` command for Antigravity IDE
|
|
182
|
+
- [ ] Auto-detect and configure MCP settings
|
|
183
|
+
|
|
184
|
+
- [ ] **Phase 3** ā Spaced Repetition & CLI
|
|
185
|
+
- [ ] SM-2 algorithm implementation
|
|
186
|
+
- [ ] `athar review` ā interactive terminal review sessions
|
|
187
|
+
- [ ] `athar status` ā pending reviews dashboard
|
|
188
|
+
- [ ] `athar list` ā browse and filter lessons
|
|
189
|
+
|
|
190
|
+
- [ ] **Phase 4** ā Nuxt 4 Dashboard
|
|
191
|
+
- [ ] Web UI for browsing lessons
|
|
192
|
+
- [ ] Syntax-highlighted code diff viewer
|
|
193
|
+
- [ ] Review progress visualization
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## š§Ŗ Development
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
# Type check
|
|
201
|
+
npm run typecheck
|
|
202
|
+
|
|
203
|
+
# Build
|
|
204
|
+
npm run build
|
|
205
|
+
|
|
206
|
+
# Run MCP server directly (for testing)
|
|
207
|
+
npm run dev
|
|
208
|
+
|
|
209
|
+
# Run smoke tests
|
|
210
|
+
npx tsx src/smoke-test.ts
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Debug logging
|
|
214
|
+
|
|
215
|
+
Set `ATHAR_DEBUG=1` to enable verbose logging to stderr:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
ATHAR_DEBUG=1 npm run dev
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## š” How the AI Decides to Save a Lesson
|
|
224
|
+
|
|
225
|
+
The MCP server includes detailed instructions for the AI assistant. It will save a lesson when:
|
|
226
|
+
|
|
227
|
+
- ā
Helping fix a **non-trivial bug** with a clear root cause
|
|
228
|
+
- ā
Correcting a **misconception** about an API or framework
|
|
229
|
+
- ā
A **debugging session** reveals unexpected behavior
|
|
230
|
+
- ā
An **architectural mistake** is identified
|
|
231
|
+
- ā
A **security vulnerability** or performance issue is discovered
|
|
232
|
+
|
|
233
|
+
It will **NOT** save for:
|
|
234
|
+
- ā Simple typos or formatting fixes
|
|
235
|
+
- ā Routine code generation
|
|
236
|
+
- ā Style preferences
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## š License
|
|
241
|
+
|
|
242
|
+
[MIT](LICENSE) ā Built with ā¤ļø by [Ameen](https://github.com/ameenmv)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"AAIA,UAAU,WAAW;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA2FrE"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { getDatabase } from '../../db/connection.js';
|
|
3
|
+
import { closeDatabase } from '../../db/connection.js';
|
|
4
|
+
export async function listCommand(options) {
|
|
5
|
+
try {
|
|
6
|
+
const db = getDatabase();
|
|
7
|
+
const limit = parseInt(options.limit, 10) || 20;
|
|
8
|
+
let sql = `
|
|
9
|
+
SELECT id, title, tags, language, status, review_count,
|
|
10
|
+
interval_days, next_review_at, created_at
|
|
11
|
+
FROM lessons
|
|
12
|
+
`;
|
|
13
|
+
const conditions = [];
|
|
14
|
+
const params = [];
|
|
15
|
+
if (options.tag) {
|
|
16
|
+
conditions.push('tags LIKE ?');
|
|
17
|
+
params.push(`%"${options.tag}"%`);
|
|
18
|
+
}
|
|
19
|
+
if (options.language) {
|
|
20
|
+
conditions.push('language = ?');
|
|
21
|
+
params.push(options.language);
|
|
22
|
+
}
|
|
23
|
+
if (options.status) {
|
|
24
|
+
conditions.push('status = ?');
|
|
25
|
+
params.push(options.status);
|
|
26
|
+
}
|
|
27
|
+
if (options.search) {
|
|
28
|
+
conditions.push('(title LIKE ? OR problem LIKE ? OR root_cause LIKE ? OR lesson LIKE ?)');
|
|
29
|
+
const q = `%${options.search}%`;
|
|
30
|
+
params.push(q, q, q, q);
|
|
31
|
+
}
|
|
32
|
+
if (conditions.length > 0) {
|
|
33
|
+
sql += ' WHERE ' + conditions.join(' AND ');
|
|
34
|
+
}
|
|
35
|
+
sql += ' ORDER BY created_at DESC LIMIT ?';
|
|
36
|
+
params.push(limit);
|
|
37
|
+
const lessons = db.prepare(sql).all(...params);
|
|
38
|
+
if (lessons.length === 0) {
|
|
39
|
+
console.log(chalk.gray('\n No lessons found matching your criteria.\n'));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
console.log(chalk.bold(`\nš Lessons (${lessons.length} results)\n`));
|
|
43
|
+
const statusIcons = {
|
|
44
|
+
new: 'š',
|
|
45
|
+
learning: 'š',
|
|
46
|
+
learned: 'ā
',
|
|
47
|
+
mastered: 'š',
|
|
48
|
+
};
|
|
49
|
+
for (const lesson of lessons) {
|
|
50
|
+
const tags = JSON.parse(lesson.tags || '[]');
|
|
51
|
+
const icon = statusIcons[lesson.status] || 'ā';
|
|
52
|
+
const date = lesson.created_at.split('T')[0];
|
|
53
|
+
console.log(` ${icon} ${chalk.bold.white(`#${lesson.id}`)} ${chalk.white(lesson.title)}`);
|
|
54
|
+
console.log(` ${chalk.gray(date)} Ā· ${chalk.blue(tags.join(', '))} Ā· ${chalk.gray(lesson.language || 'N/A')} Ā· Reviews: ${chalk.white(lesson.review_count)}`);
|
|
55
|
+
if (lesson.next_review_at) {
|
|
56
|
+
const nextReview = new Date(lesson.next_review_at);
|
|
57
|
+
const now = new Date();
|
|
58
|
+
const daysUntil = Math.ceil((nextReview.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
|
|
59
|
+
if (daysUntil <= 0) {
|
|
60
|
+
console.log(` ${chalk.yellow('ā ļø Due for review!')}`);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
console.log(` ${chalk.gray(`Next review in ${daysUntil} day(s)`)}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
console.log();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
closeDatabase();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/review.ts"],"names":[],"mappings":"AAYA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAqHnD"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { getDueReviews, recordReview } from '../../spaced-repetition/scheduler.js';
|
|
3
|
+
import { qualityLabel } from '../../spaced-repetition/sm2.js';
|
|
4
|
+
import { closeDatabase } from '../../db/connection.js';
|
|
5
|
+
import { createInterface } from 'node:readline';
|
|
6
|
+
function askQuestion(rl, prompt) {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
rl.question(prompt, (answer) => resolve(answer.trim()));
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
export async function reviewCommand() {
|
|
12
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
13
|
+
try {
|
|
14
|
+
const dueReviews = getDueReviews();
|
|
15
|
+
if (dueReviews.length === 0) {
|
|
16
|
+
console.log(chalk.green('\n ⨠No lessons due for review. Great job!'));
|
|
17
|
+
console.log(chalk.gray(' Check back later or run `athar status` for stats.\n'));
|
|
18
|
+
rl.close();
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
console.log(chalk.bold(`\nā${'ā'.repeat(50)}ā`));
|
|
22
|
+
console.log(chalk.bold(`ā Ų£Ų«Ų± Review Session ā ${chalk.yellow(dueReviews.length)} lesson(s) due${' '.repeat(Math.max(0, 50 - 30 - String(dueReviews.length).length))}ā`));
|
|
23
|
+
console.log(chalk.bold(`ā${'ā'.repeat(50)}ā\n`));
|
|
24
|
+
let reviewed = 0;
|
|
25
|
+
let skipped = 0;
|
|
26
|
+
for (let i = 0; i < dueReviews.length; i++) {
|
|
27
|
+
const lesson = dueReviews[i];
|
|
28
|
+
const tags = JSON.parse(lesson.tags || '[]');
|
|
29
|
+
const questions = JSON.parse(lesson.review_questions || '[]');
|
|
30
|
+
console.log(chalk.bold(`\nš Lesson ${i + 1}/${dueReviews.length}: "${lesson.title}"`));
|
|
31
|
+
console.log(chalk.gray('ā'.repeat(55)));
|
|
32
|
+
console.log(`${chalk.gray('Tags:')} ${tags.map(t => chalk.blue(t)).join(', ')}`);
|
|
33
|
+
console.log(`${chalk.gray('Language:')} ${lesson.language || 'N/A'} ${chalk.gray('Status:')} ${lesson.status}`);
|
|
34
|
+
// Show problem
|
|
35
|
+
console.log(chalk.bold('\nā Problem:'));
|
|
36
|
+
console.log(chalk.white(` ${lesson.problem}`));
|
|
37
|
+
// Show review questions one by one
|
|
38
|
+
for (const question of questions) {
|
|
39
|
+
console.log(chalk.bold.yellow(`\nā ${question.q}`));
|
|
40
|
+
await askQuestion(rl, chalk.gray('\n Press Enter to reveal answer...'));
|
|
41
|
+
console.log(chalk.bold.green(`\nā
${question.a}`));
|
|
42
|
+
}
|
|
43
|
+
// Show root cause and lesson
|
|
44
|
+
console.log(chalk.bold('\nš Root Cause:'));
|
|
45
|
+
console.log(chalk.white(` ${lesson.root_cause}`));
|
|
46
|
+
console.log(chalk.bold('\nš” Key Lesson:'));
|
|
47
|
+
console.log(chalk.white(` ${lesson.lesson}`));
|
|
48
|
+
// Show code comparison if available
|
|
49
|
+
if (lesson.bad_code && lesson.good_code) {
|
|
50
|
+
console.log(chalk.bold.red('\nā Bad Code:'));
|
|
51
|
+
console.log(chalk.gray(' āā'));
|
|
52
|
+
for (const line of lesson.bad_code.split('\n')) {
|
|
53
|
+
console.log(chalk.red(` ā ${line}`));
|
|
54
|
+
}
|
|
55
|
+
console.log(chalk.gray(' āā'));
|
|
56
|
+
console.log(chalk.bold.green('\nā Good Code:'));
|
|
57
|
+
console.log(chalk.gray(' āā'));
|
|
58
|
+
for (const line of lesson.good_code.split('\n')) {
|
|
59
|
+
console.log(chalk.green(` ā ${line}`));
|
|
60
|
+
}
|
|
61
|
+
console.log(chalk.gray(' āā'));
|
|
62
|
+
}
|
|
63
|
+
// Ask for quality rating
|
|
64
|
+
console.log(chalk.bold('\nš How well did you recall this?'));
|
|
65
|
+
console.log(chalk.gray(' 0 = Complete blackout'));
|
|
66
|
+
console.log(chalk.gray(' 1 = Incorrect, vague memory'));
|
|
67
|
+
console.log(chalk.gray(' 2 = Incorrect, but recognized answer'));
|
|
68
|
+
console.log(chalk.gray(' 3 = Correct with difficulty'));
|
|
69
|
+
console.log(chalk.gray(' 4 = Correct after hesitation'));
|
|
70
|
+
console.log(chalk.gray(' 5 = Perfect recall'));
|
|
71
|
+
console.log(chalk.gray(' s = Skip this lesson'));
|
|
72
|
+
let quality = null;
|
|
73
|
+
while (quality === null) {
|
|
74
|
+
const answer = await askQuestion(rl, chalk.bold('\n Your rating (0-5 or s): '));
|
|
75
|
+
if (answer.toLowerCase() === 's') {
|
|
76
|
+
skipped++;
|
|
77
|
+
console.log(chalk.gray(' Skipped.'));
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
const parsed = parseInt(answer, 10);
|
|
81
|
+
if (!isNaN(parsed) && parsed >= 0 && parsed <= 5) {
|
|
82
|
+
quality = parsed;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
console.log(chalk.red(' Please enter a number 0-5 or "s" to skip.'));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (quality !== null) {
|
|
89
|
+
const result = recordReview(lesson.id, quality);
|
|
90
|
+
reviewed++;
|
|
91
|
+
console.log(`\n ${qualityLabel(quality)}`);
|
|
92
|
+
console.log(` ā Next review in ${chalk.bold(result.intervalDays + ' day(s)')} ${chalk.green('ā')}`);
|
|
93
|
+
console.log(` ā Status: ${chalk.bold(result.newStatus)}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Summary
|
|
97
|
+
console.log(chalk.bold(`\n${'ā'.repeat(55)}`));
|
|
98
|
+
console.log(chalk.bold('š Review Session Summary'));
|
|
99
|
+
console.log(` Reviewed: ${chalk.green(reviewed)}`);
|
|
100
|
+
console.log(` Skipped: ${chalk.yellow(skipped)}`);
|
|
101
|
+
console.log(` Total: ${dueReviews.length}`);
|
|
102
|
+
console.log(chalk.bold(`${'ā'.repeat(55)}\n`));
|
|
103
|
+
if (reviewed > 0) {
|
|
104
|
+
console.log(chalk.green(' š Great work! Keep learning from your mistakes.\n'));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
rl.close();
|
|
109
|
+
closeDatabase();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../../src/cli/commands/review.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"AAKA,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAsDlD"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import { getMcpConfigPath } from '../../utils/paths.js';
|
|
5
|
+
export async function setupCommand() {
|
|
6
|
+
console.log(chalk.bold('\nš® Athar Setup ā Antigravity IDE Integration\n'));
|
|
7
|
+
const configPath = getMcpConfigPath();
|
|
8
|
+
const serverPath = resolve(join(import.meta.dirname, '..', '..', '..', 'dist', 'index.js'));
|
|
9
|
+
// Check if dist/index.js exists
|
|
10
|
+
if (!existsSync(serverPath)) {
|
|
11
|
+
console.log(chalk.red('ā Built server not found at:'), serverPath);
|
|
12
|
+
console.log(chalk.yellow(' Run `npm run build` first.\n'));
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
console.log(chalk.gray(` Config path: ${configPath}`));
|
|
16
|
+
console.log(chalk.gray(` Server path: ${serverPath}\n`));
|
|
17
|
+
// Read or create config
|
|
18
|
+
let config;
|
|
19
|
+
if (existsSync(configPath)) {
|
|
20
|
+
try {
|
|
21
|
+
config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
22
|
+
if (!config.mcpServers)
|
|
23
|
+
config.mcpServers = {};
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
console.log(chalk.yellow('ā ļø Existing config is invalid, creating new one...'));
|
|
27
|
+
config = { mcpServers: {} };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Create directory if needed
|
|
32
|
+
const dir = join(configPath, '..');
|
|
33
|
+
mkdirSync(dir, { recursive: true });
|
|
34
|
+
config = { mcpServers: {} };
|
|
35
|
+
}
|
|
36
|
+
// Check if already configured
|
|
37
|
+
if (config.mcpServers.athar) {
|
|
38
|
+
console.log(chalk.yellow('ā ļø Athar is already configured in your MCP settings.'));
|
|
39
|
+
console.log(chalk.gray(' Updating to latest path...\n'));
|
|
40
|
+
}
|
|
41
|
+
// Add/update athar entry
|
|
42
|
+
config.mcpServers.athar = {
|
|
43
|
+
command: 'node',
|
|
44
|
+
args: ['--experimental-sqlite', serverPath],
|
|
45
|
+
};
|
|
46
|
+
// Write config
|
|
47
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
48
|
+
console.log(chalk.green('ā
Athar MCP server configured successfully!\n'));
|
|
49
|
+
console.log(chalk.bold('Next steps:'));
|
|
50
|
+
console.log(chalk.white(' 1. Refresh MCP servers in Antigravity IDE'));
|
|
51
|
+
console.log(chalk.white(' (Click "..." ā "Manage MCP Servers" ā Refresh)'));
|
|
52
|
+
console.log(chalk.white(' 2. Start coding ā the AI will save lessons automatically'));
|
|
53
|
+
console.log(chalk.white(' 3. Run `athar status` to check your progress\n'));
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAIA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAoCnD"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { getStats } from '../../spaced-repetition/scheduler.js';
|
|
3
|
+
import { closeDatabase } from '../../db/connection.js';
|
|
4
|
+
export async function statusCommand() {
|
|
5
|
+
try {
|
|
6
|
+
const stats = getStats();
|
|
7
|
+
console.log(chalk.bold('\nš Athar Memory Status'));
|
|
8
|
+
console.log(chalk.gray('ā'.repeat(40)));
|
|
9
|
+
console.log(`\n Total Lessons: ${chalk.bold.white(stats.total)}`);
|
|
10
|
+
console.log(` Due Today: ${stats.dueToday > 0 ? chalk.bold.yellow(stats.dueToday + ' ā ļø') : chalk.green('0 ā')}`);
|
|
11
|
+
console.log(` Due This Week: ${chalk.white(stats.dueThisWeek)}`);
|
|
12
|
+
console.log(chalk.bold('\n By Status:'));
|
|
13
|
+
console.log(` š New: ${chalk.white(stats.byStatus['new'] || 0)}`);
|
|
14
|
+
console.log(` š Learning: ${chalk.cyan(stats.byStatus['learning'] || 0)}`);
|
|
15
|
+
console.log(` ā
Learned: ${chalk.green(stats.byStatus['learned'] || 0)}`);
|
|
16
|
+
console.log(` š Mastered: ${chalk.magenta(stats.byStatus['mastered'] || 0)}`);
|
|
17
|
+
if (stats.topTags.length > 0) {
|
|
18
|
+
console.log(chalk.bold('\n Top Tags:'));
|
|
19
|
+
for (const { tag, count } of stats.topTags) {
|
|
20
|
+
const bar = chalk.blue('ā'.repeat(Math.min(count * 2, 20)));
|
|
21
|
+
console.log(` ${chalk.white(tag.padEnd(18))} ${bar} ${chalk.gray(count)}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (stats.dueToday > 0) {
|
|
25
|
+
console.log(chalk.yellow(`\n š” You have ${stats.dueToday} lesson(s) due for review!`));
|
|
26
|
+
console.log(chalk.white(' Run `athar review` to start.\n'));
|
|
27
|
+
}
|
|
28
|
+
else if (stats.total === 0) {
|
|
29
|
+
console.log(chalk.gray('\n No lessons yet. Start coding with Athar MCP in your IDE!\n'));
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
console.log(chalk.green('\n ⨠All caught up! No reviews due today.\n'));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
closeDatabase();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;QAEzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAExC,OAAO,CAAC,GAAG,CAAC,yBAAyB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1H,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAErE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/E,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QACnF,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QAClF,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QAEtF,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;YACzC,KAAK,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC3C,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC5D,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAChF,CAAC;QACH,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB,KAAK,CAAC,QAAQ,4BAA4B,CAAC,CAAC,CAAC;YACzF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC,CAAC;QAClE,CAAC;aAAM,IAAI,KAAK,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC,CAAC;QAC5F,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;YAAS,CAAC;QACT,aAAa,EAAE,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Athar CLI (Ų£Ų«Ų±)
|
|
4
|
+
*
|
|
5
|
+
* Commands:
|
|
6
|
+
* athar setup ā Configure Antigravity IDE integration
|
|
7
|
+
* athar review ā Interactive spaced repetition review
|
|
8
|
+
* athar status ā Show pending reviews and stats
|
|
9
|
+
* athar list ā Browse all lessons
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG"}
|