claude-code-tutor 1.0.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/README.md +315 -0
- package/dist/chunk-A6ZZXTHB.js +65 -0
- package/dist/chunk-OYDUGORC.js +75 -0
- package/dist/cli.js +1362 -0
- package/dist/meta-TZOSLFST.js +13 -0
- package/dist/tutor-memory-M6GNB3LQ.js +19 -0
- package/package.json +61 -0
- package/skills-fallback/cc-agent-teams/SKILL.md +38 -0
- package/skills-fallback/cc-best-practices/SKILL.md +34 -0
- package/skills-fallback/cc-changelog/SKILL.md +20 -0
- package/skills-fallback/cc-channels/SKILL.md +34 -0
- package/skills-fallback/cc-cli-reference/SKILL.md +16 -0
- package/skills-fallback/cc-commands/SKILL.md +12 -0
- package/skills-fallback/cc-common-workflows-ask-claude-about-its-capabilities/SKILL.md +43 -0
- package/skills-fallback/cc-common-workflows-create-pull-requests/SKILL.md +26 -0
- package/skills-fallback/cc-common-workflows-fix-bugs-efficiently/SKILL.md +30 -0
- package/skills-fallback/cc-common-workflows-get-notified-when-claude-needs-your-attention/SKILL.md +95 -0
- package/skills-fallback/cc-common-workflows-handle-documentation/SKILL.md +36 -0
- package/skills-fallback/cc-common-workflows-next-steps/SKILL.md +22 -0
- package/skills-fallback/cc-common-workflows-refactor-code/SKILL.md +36 -0
- package/skills-fallback/cc-common-workflows-reference-files-and-directories/SKILL.md +47 -0
- package/skills-fallback/cc-common-workflows-resume-previous-conversations/SKILL.md +57 -0
- package/skills-fallback/cc-common-workflows-run-claude-on-a-schedule/SKILL.md +22 -0
- package/skills-fallback/cc-common-workflows-run-parallel-claude-code-sessions-with-git-worktrees/SKILL.md +43 -0
- package/skills-fallback/cc-common-workflows-understand-new-codebases/SKILL.md +81 -0
- package/skills-fallback/cc-common-workflows-use-claude-as-a-unix-style-utility/SKILL.md +83 -0
- package/skills-fallback/cc-common-workflows-use-extended-thinking-thinking-mode/SKILL.md +15 -0
- package/skills-fallback/cc-common-workflows-use-plan-mode-for-safe-code-analysis/SKILL.md +80 -0
- package/skills-fallback/cc-common-workflows-use-specialized-subagents/SKILL.md +69 -0
- package/skills-fallback/cc-common-workflows-work-with-images/SKILL.md +71 -0
- package/skills-fallback/cc-common-workflows-work-with-tests/SKILL.md +36 -0
- package/skills-fallback/cc-github-actions/SKILL.md +44 -0
- package/skills-fallback/cc-headless/SKILL.md +40 -0
- package/skills-fallback/cc-hooks-config/SKILL.md +32 -0
- package/skills-fallback/cc-hooks-events/SKILL.md +24 -0
- package/skills-fallback/cc-hooks-guide/SKILL.md +59 -0
- package/skills-fallback/cc-hooks-io/SKILL.md +11 -0
- package/skills-fallback/cc-learning-path/SKILL.md +77 -0
- package/skills-fallback/cc-mcp-add-mcp-servers-from-json-configuration/SKILL.md +36 -0
- package/skills-fallback/cc-mcp-authenticate-with-remote-mcp-servers/SKILL.md +52 -0
- package/skills-fallback/cc-mcp-import-mcp-servers-from-claude-desktop/SKILL.md +28 -0
- package/skills-fallback/cc-mcp-installing-mcp-servers/SKILL.md +86 -0
- package/skills-fallback/cc-mcp-managed-mcp-configuration/SKILL.md +55 -0
- package/skills-fallback/cc-mcp-mcp-installation-scopes/SKILL.md +57 -0
- package/skills-fallback/cc-mcp-mcp-output-limits-and-warnings/SKILL.md +46 -0
- package/skills-fallback/cc-mcp-popular-mcp-servers/SKILL.md +11 -0
- package/skills-fallback/cc-mcp-practical-examples/SKILL.md +102 -0
- package/skills-fallback/cc-mcp-respond-to-mcp-elicitation-requests/SKILL.md +20 -0
- package/skills-fallback/cc-mcp-scale-with-mcp-tool-search/SKILL.md +29 -0
- package/skills-fallback/cc-mcp-use-claude-code-as-an-mcp-server/SKILL.md +59 -0
- package/skills-fallback/cc-mcp-use-mcp-prompts-as-commands/SKILL.md +40 -0
- package/skills-fallback/cc-mcp-use-mcp-resources/SKILL.md +45 -0
- package/skills-fallback/cc-mcp-use-mcp-servers-from-claude-ai/SKILL.md +35 -0
- package/skills-fallback/cc-mcp-what-you-can-do-with-mcp/SKILL.md +12 -0
- package/skills-fallback/cc-memory/SKILL.md +28 -0
- package/skills-fallback/cc-model-config/SKILL.md +27 -0
- package/skills-fallback/cc-permissions/SKILL.md +38 -0
- package/skills-fallback/cc-plugins/SKILL.md +44 -0
- package/skills-fallback/cc-sandboxing/SKILL.md +22 -0
- package/skills-fallback/cc-scheduled-tasks/SKILL.md +20 -0
- package/skills-fallback/cc-settings-configuration-scopes/SKILL.md +57 -0
- package/skills-fallback/cc-settings-environment-variables/SKILL.md +13 -0
- package/skills-fallback/cc-settings-plugin-configuration/SKILL.md +11 -0
- package/skills-fallback/cc-settings-see-also/SKILL.md +13 -0
- package/skills-fallback/cc-settings-settings-files/SKILL.md +38 -0
- package/skills-fallback/cc-settings-subagent-configuration/SKILL.md +16 -0
- package/skills-fallback/cc-settings-tools-available-to-claude/SKILL.md +13 -0
- package/skills-fallback/cc-skills-guide/SKILL.md +23 -0
- package/skills-fallback/cc-sub-agents/SKILL.md +30 -0
- package/skills-fallback/cc-tutor/SKILL.md +108 -0
package/README.md
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
# claude-code-tutor
|
|
2
|
+
|
|
3
|
+
Keep Claude Code alive. Fresh docs, built-in tutor, always in sync.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
### Recommended (global install)
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g claude-code-tutor
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Then verify:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pulse --version
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Global install makes the `pulse` command available system-wide, but you still need to initialize each repository where you want to use it:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pulse init
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Update
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm update -g claude-code-tutor
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Then re-initialize each repo to apply hook and skill fixes:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pulse init --force
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Quick run (no global install)
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx pulse init
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This command installs pulse skills in `.claude/skills`, runs an initial sync, and adds a safe `SessionStart` hook.
|
|
48
|
+
|
|
49
|
+
### How it works across repositories and new Claude sessions
|
|
50
|
+
|
|
51
|
+
- Global npm install adds the CLI binary only.
|
|
52
|
+
- `pulse init` configures the current repository only.
|
|
53
|
+
- Each repository must be initialized once.
|
|
54
|
+
- New Claude Code sessions in an initialized repository use that repo's `.claude` configuration and hooks automatically.
|
|
55
|
+
- In a brand-new repository, run `pulse init` first.
|
|
56
|
+
|
|
57
|
+
## What can you do with pulse?
|
|
58
|
+
|
|
59
|
+
### Beginner — Your first steps
|
|
60
|
+
|
|
61
|
+
Never used Claude Code? Pulse guides you from zero:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
You: "It's my first time using Claude Code, help me"
|
|
65
|
+
Pulse: "Welcome! I'm Pulse, your Claude Code tutor. What's your name?
|
|
66
|
+
...Great! Let's start with the basics. Open any project folder
|
|
67
|
+
and type 'claude'. That's it — you're in a session.
|
|
68
|
+
Try asking Claude to explain a file in your project."
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Ask anything, Pulse adapts to your language automatically:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
You: "No entiendo qué es CLAUDE.md"
|
|
75
|
+
Pulse: "Es un archivo que le da contexto a Claude sobre tu proyecto.
|
|
76
|
+
Piensa en él como un README pero para Claude. Creemos uno juntos:
|
|
77
|
+
crea un archivo CLAUDE.md en la raíz de tu proyecto..."
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Learn what commands are available:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
You: "What commands can I use?"
|
|
84
|
+
Pulse: "Here are the essentials to get started:
|
|
85
|
+
/help — see all available commands
|
|
86
|
+
/compact — compress conversation when it gets long
|
|
87
|
+
/cost — check how much you've spent this session
|
|
88
|
+
/memory — see what Claude remembers about your project
|
|
89
|
+
Try /help now and tell me what catches your eye!"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Intermediate — Level up your workflow
|
|
93
|
+
|
|
94
|
+
Already using Claude Code? Pulse helps you unlock powerful features:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
You: "I want to automate something every time I start a session"
|
|
98
|
+
Pulse: "That's what hooks are for! A SessionStart hook runs a shell command
|
|
99
|
+
every time Claude opens. For example, to auto-format your code:
|
|
100
|
+
|
|
101
|
+
In .claude/settings.json:
|
|
102
|
+
{ 'hooks': { 'SessionStart': [{ 'command': 'npm run lint:fix' }] } }
|
|
103
|
+
|
|
104
|
+
Want me to walk you through setting one up for your project?"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Connect external tools:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
You: "Can Claude access my database?"
|
|
111
|
+
Pulse: "Yes! Through MCP servers. You configure them in settings.json
|
|
112
|
+
and Claude gets read/write access. Here's how to connect PostgreSQL:
|
|
113
|
+
..."
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Create custom skills for your team:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
You: "How do I create a skill for code review?"
|
|
120
|
+
Pulse: "Create a file at .claude/skills/code-review/SKILL.md with
|
|
121
|
+
instructions for how Claude should review code in your stack.
|
|
122
|
+
Let me show you the structure..."
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Advanced — Scale with your team
|
|
126
|
+
|
|
127
|
+
For power users building automation and team workflows:
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
You: "I need multiple agents working in parallel on different tasks"
|
|
131
|
+
Pulse: "Agent teams let you coordinate multiple Claude instances.
|
|
132
|
+
You define agents with roles (reviewer, implementer, tester)
|
|
133
|
+
and they work on isolated worktrees. Here's the pattern:
|
|
134
|
+
..."
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Integrate with CI/CD:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
You: "How do I get Claude to review PRs automatically?"
|
|
141
|
+
Pulse: "With GitHub Actions. Add @claude mentions in your workflow
|
|
142
|
+
and Claude reviews PRs, suggests fixes, and can even push
|
|
143
|
+
commits. Here's a working workflow file:
|
|
144
|
+
..."
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Run Claude in scripts:
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
You: "I want to use Claude in a bash script"
|
|
151
|
+
Pulse: "Headless mode! Use 'claude --print' for single-shot tasks:
|
|
152
|
+
|
|
153
|
+
claude --print 'summarize the changes in the last 5 commits'
|
|
154
|
+
|
|
155
|
+
It returns the output directly to stdout. Perfect for
|
|
156
|
+
CI pipelines, cron jobs, or chaining with other tools."
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Pulse remembers you across sessions
|
|
160
|
+
|
|
161
|
+
Your first session:
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
Pulse: "Hey! I'm Pulse, your Claude Code tutor. What's your name?"
|
|
165
|
+
You: "Ana"
|
|
166
|
+
Pulse: "Nice to meet you, Ana! Let's figure out your level..."
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Your next session, days later:
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
Pulse: "Hey Ana! Last time we set up your first hook. Ready to
|
|
173
|
+
learn about MCP servers? That was your next step."
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Check your progress anytime:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
$ pulse memory
|
|
180
|
+
Name: Ana
|
|
181
|
+
Level: intermediate
|
|
182
|
+
Language: es
|
|
183
|
+
Joined: 4/1/2026
|
|
184
|
+
|
|
185
|
+
Topics: 5 completed, 2 in progress, 3 pending
|
|
186
|
+
✓ basic-commands
|
|
187
|
+
✓ permissions
|
|
188
|
+
✓ claude-md
|
|
189
|
+
✓ git-workflow
|
|
190
|
+
✓ hooks
|
|
191
|
+
… mcp-servers
|
|
192
|
+
… sub-agents
|
|
193
|
+
|
|
194
|
+
Next steps:
|
|
195
|
+
→ mcp-servers: Ready after mastering hooks
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Set it up once per repo, works every session
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
npm install -g claude-code-tutor
|
|
202
|
+
cd my-project
|
|
203
|
+
pulse init
|
|
204
|
+
# Done. Every Claude Code session in this repo now has fresh docs and Pulse as your tutor.
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## What pulse does
|
|
208
|
+
|
|
209
|
+
- **Doc sync**: downloads Claude Code docs and keeps skills fresh.
|
|
210
|
+
- **Built-in tutor**: includes `cc-tutor` for guided help in-session.
|
|
211
|
+
- **Learning path**: includes `cc-learning-path` for structured onboarding.
|
|
212
|
+
|
|
213
|
+
## Skills
|
|
214
|
+
|
|
215
|
+
| ID | Description | Priority |
|
|
216
|
+
|---|---|---|
|
|
217
|
+
| `cc-tutor` | Interactive tutor to guide users and answer Claude Code questions. | `critical` |
|
|
218
|
+
| `cc-learning-path` | Structured multi-level learning path. | `high` |
|
|
219
|
+
| `cc-changelog` | Recent updates and changes in Claude Code. | `critical` |
|
|
220
|
+
| `cc-hooks-events` | Hook events table and when they trigger. | `critical` |
|
|
221
|
+
| `cc-hooks-guide` | Practical guide for implementing hooks. | `critical` |
|
|
222
|
+
| `cc-mcp` | MCP server setup and usage. | `critical` |
|
|
223
|
+
| `cc-settings` | `settings.json` reference and scopes. | `critical` |
|
|
224
|
+
| `cc-permissions` | Permission system and per-tool rules. | `critical` |
|
|
225
|
+
| `cc-sub-agents` | Sub-agent setup and usage. | `high` |
|
|
226
|
+
| `cc-agent-teams` | Coordinating multiple agents in teams. | `high` |
|
|
227
|
+
| `cc-skills-guide` | How to create and maintain skills. | `high` |
|
|
228
|
+
| `cc-memory` | Using `CLAUDE.md` and project memory. | `high` |
|
|
229
|
+
| `cc-cli-reference` | CLI commands and flags reference. | `high` |
|
|
230
|
+
| `cc-commands` | Built-in Claude Code commands. | `high` |
|
|
231
|
+
| `cc-model-config` | Model configuration and aliases. | `high` |
|
|
232
|
+
| `cc-plugins` | Plugin architecture and authoring. | `medium` |
|
|
233
|
+
| `cc-channels` | Channels and webhook workflows. | `medium` |
|
|
234
|
+
| `cc-scheduled-tasks` | Scheduled tasks with `/loop` and cron. | `medium` |
|
|
235
|
+
| `cc-headless` | Headless execution and SDK usage. | `medium` |
|
|
236
|
+
| `cc-sandboxing` | Sandboxing and isolation. | `medium` |
|
|
237
|
+
| `cc-common-workflows` | Common development workflows. | `medium` |
|
|
238
|
+
| `cc-best-practices` | Recommended practices and patterns. | `medium` |
|
|
239
|
+
| `cc-github-actions` | Claude Code integration with GitHub Actions. | `medium` |
|
|
240
|
+
|
|
241
|
+
## Team usage
|
|
242
|
+
|
|
243
|
+
If your team wants the same skills, commit the generated directories:
|
|
244
|
+
|
|
245
|
+
```text
|
|
246
|
+
.claude/skills/cc-*/
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Pulse only manages skills marked with `_pulse: true`, so user-owned custom skills are preserved.
|
|
250
|
+
|
|
251
|
+
## CLI commands
|
|
252
|
+
|
|
253
|
+
| Command | Description | Key flags |
|
|
254
|
+
|---|---|---|
|
|
255
|
+
| `pulse init` | Initializes pulse in current project. | `--force`, `--yes`, `--skills <ids...>` |
|
|
256
|
+
| `pulse sync` | Fetches, transforms, and installs skills. | `--force`, `--if-stale <seconds>`, `--silent`, `--skills <ids...>` |
|
|
257
|
+
| `pulse greet` | Emits first-session tutor context. | `--once` |
|
|
258
|
+
| `pulse list` | Lists installed skills and freshness state. | _(none)_ |
|
|
259
|
+
| `pulse status` | Shows global pulse status and diagnostics. | _(none)_ |
|
|
260
|
+
| `pulse uninstall` | Removes pulse hook and pulse-managed skills. | `--keep-hook`, `--keep-skills`, `--purge-memory` |
|
|
261
|
+
|
|
262
|
+
## Your tutor progress
|
|
263
|
+
|
|
264
|
+
Pulse remembers your learning progress across sessions in `~/.claude/pulse/memory.json`.
|
|
265
|
+
|
|
266
|
+
| Command | Description |
|
|
267
|
+
|---|---|
|
|
268
|
+
| `pulse memory` | View your tutor progress summary |
|
|
269
|
+
| `pulse memory --reset` | Reset memory (keeps session logs) |
|
|
270
|
+
| `pulse memory --export` | Export memory as JSON |
|
|
271
|
+
| `pulse memory --import <file>` | Import memory from a JSON file |
|
|
272
|
+
| `pulse memory --update '<JSON>'` | Update specific memory fields |
|
|
273
|
+
| `pulse memory --exercise <id> --status <status>` | Update exercise status |
|
|
274
|
+
| `pulse memory --next-step "<desc>" --reason "<reason>"` | Add a next step |
|
|
275
|
+
|
|
276
|
+
Memory is stored locally and never leaves your machine. Use `pulse uninstall --purge-memory` to delete all memory data.
|
|
277
|
+
|
|
278
|
+
## Sync mechanism
|
|
279
|
+
|
|
280
|
+
- **ETag caching**: unchanged docs return `304` and are skipped.
|
|
281
|
+
- **Transformer pipeline**: tries Claude CLI transform first, then static fallback.
|
|
282
|
+
- **SessionStart hook**: runs daily stale-aware sync (`--if-stale 86400`) and one-time greet.
|
|
283
|
+
|
|
284
|
+
## Configuration
|
|
285
|
+
|
|
286
|
+
Create `.pulserc.json` in your project:
|
|
287
|
+
|
|
288
|
+
```json
|
|
289
|
+
{
|
|
290
|
+
"skills": ["critical", "high"],
|
|
291
|
+
"maxAge": 86400,
|
|
292
|
+
"transformer": "auto",
|
|
293
|
+
"silent": false
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
| Option | Default | Valid values | Description |
|
|
298
|
+
|---|---|---|---|
|
|
299
|
+
| `skills` | `["critical","high"]` | `["critical"]`, `["critical","high"]`, `["all"]`, etc. | Skill priorities to sync. |
|
|
300
|
+
| `maxAge` | `86400` | number (seconds) | Staleness threshold for auto-sync decisions. |
|
|
301
|
+
| `transformer` | `"auto"` | `"auto"`, `"static"` | Transformation mode. `auto` prefers Claude CLI. |
|
|
302
|
+
| `silent` | `false` | `true`, `false` | Suppress non-error output. |
|
|
303
|
+
|
|
304
|
+
## Troubleshooting
|
|
305
|
+
|
|
306
|
+
- **Hook does not run**: check `.claude/settings.json` has a `SessionStart` entry with `_pulse: true`.
|
|
307
|
+
- **Windows behavior**: pulse uses `npx.cmd` on native Windows and Unix format on WSL.
|
|
308
|
+
- **Skills look stale**: run `pulse sync --force` to bypass ETag cache.
|
|
309
|
+
- **Claude CLI unavailable**: pulse automatically falls back to static transformer.
|
|
310
|
+
|
|
311
|
+
## Contributing
|
|
312
|
+
|
|
313
|
+
- Improve static skill sources under `src/static-skills/`.
|
|
314
|
+
- Improve tutor and learning content in `cc-tutor.md` and `cc-learning-path.md`.
|
|
315
|
+
- Add/adjust tests in `tests/` when changing fetch, transform, split, or hook behavior.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/core/tutor-memory.ts
|
|
4
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import { homedir } from "os";
|
|
7
|
+
var baseDirOverride = null;
|
|
8
|
+
function setBaseDir(dir) {
|
|
9
|
+
baseDirOverride = dir;
|
|
10
|
+
}
|
|
11
|
+
function getBaseDir() {
|
|
12
|
+
return baseDirOverride ?? join(homedir(), ".claude", "pulse");
|
|
13
|
+
}
|
|
14
|
+
function memoryPath() {
|
|
15
|
+
return join(getBaseDir(), "memory.json");
|
|
16
|
+
}
|
|
17
|
+
function getDefaultMemory() {
|
|
18
|
+
return {
|
|
19
|
+
name: "",
|
|
20
|
+
language: "en",
|
|
21
|
+
joinedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22
|
+
level: "beginner",
|
|
23
|
+
levelUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24
|
+
topics: {},
|
|
25
|
+
frequentQuestions: [],
|
|
26
|
+
exercises: {},
|
|
27
|
+
nextSteps: [],
|
|
28
|
+
lastSession: null
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
async function readMemory() {
|
|
32
|
+
try {
|
|
33
|
+
const raw = await readFile(memoryPath(), "utf-8");
|
|
34
|
+
return JSON.parse(raw);
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function writeMemory(memory) {
|
|
40
|
+
const dir = getBaseDir();
|
|
41
|
+
await mkdir(dir, { recursive: true });
|
|
42
|
+
await writeFile(memoryPath(), JSON.stringify(memory, null, 2) + "\n", "utf-8");
|
|
43
|
+
}
|
|
44
|
+
async function updateMemory(patch) {
|
|
45
|
+
const current = await readMemory() ?? getDefaultMemory();
|
|
46
|
+
const updated = { ...current, ...patch };
|
|
47
|
+
await writeMemory(updated);
|
|
48
|
+
return updated;
|
|
49
|
+
}
|
|
50
|
+
async function logSession(log) {
|
|
51
|
+
const sessionsDir = join(getBaseDir(), "sessions");
|
|
52
|
+
await mkdir(sessionsDir, { recursive: true });
|
|
53
|
+
const filename = `${log.date}.json`;
|
|
54
|
+
await writeFile(join(sessionsDir, filename), JSON.stringify(log, null, 2) + "\n", "utf-8");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export {
|
|
58
|
+
setBaseDir,
|
|
59
|
+
getBaseDir,
|
|
60
|
+
getDefaultMemory,
|
|
61
|
+
readMemory,
|
|
62
|
+
writeMemory,
|
|
63
|
+
updateMemory,
|
|
64
|
+
logSession
|
|
65
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/core/meta.ts
|
|
4
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
5
|
+
import { join, dirname } from "path";
|
|
6
|
+
|
|
7
|
+
// src/version.ts
|
|
8
|
+
import { createRequire } from "module";
|
|
9
|
+
var require2 = createRequire(import.meta.url);
|
|
10
|
+
var cached;
|
|
11
|
+
function getVersion() {
|
|
12
|
+
if (!cached) {
|
|
13
|
+
try {
|
|
14
|
+
cached = require2("../package.json").version;
|
|
15
|
+
} catch {
|
|
16
|
+
try {
|
|
17
|
+
cached = require2("../../package.json").version;
|
|
18
|
+
} catch {
|
|
19
|
+
cached = "0.0.0";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return cached;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// src/core/meta.ts
|
|
27
|
+
function metaPath() {
|
|
28
|
+
return join(process.cwd(), ".claude", "skills", ".pulse-meta.json");
|
|
29
|
+
}
|
|
30
|
+
function defaultMeta() {
|
|
31
|
+
return {
|
|
32
|
+
version: getVersion(),
|
|
33
|
+
lastSync: "",
|
|
34
|
+
lastSyncStatus: "failed",
|
|
35
|
+
firstSessionDone: false,
|
|
36
|
+
skills: {},
|
|
37
|
+
etags: {}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function getMetaPath() {
|
|
41
|
+
return metaPath();
|
|
42
|
+
}
|
|
43
|
+
function readMeta() {
|
|
44
|
+
const path = metaPath();
|
|
45
|
+
try {
|
|
46
|
+
const raw = readFileSync(path, "utf-8");
|
|
47
|
+
return { ...defaultMeta(), ...JSON.parse(raw) };
|
|
48
|
+
} catch {
|
|
49
|
+
return defaultMeta();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function writeMeta(meta) {
|
|
53
|
+
const path = metaPath();
|
|
54
|
+
const dir = dirname(path);
|
|
55
|
+
if (!existsSync(dir)) {
|
|
56
|
+
mkdirSync(dir, { recursive: true });
|
|
57
|
+
}
|
|
58
|
+
writeFileSync(path, JSON.stringify(meta, null, 2) + "\n", "utf-8");
|
|
59
|
+
}
|
|
60
|
+
function isStale(maxAgeSeconds) {
|
|
61
|
+
const meta = readMeta();
|
|
62
|
+
if (!meta.lastSync) return true;
|
|
63
|
+
const lastSyncTime = new Date(meta.lastSync).getTime();
|
|
64
|
+
if (isNaN(lastSyncTime)) return true;
|
|
65
|
+
const elapsed = (Date.now() - lastSyncTime) / 1e3;
|
|
66
|
+
return elapsed > maxAgeSeconds;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export {
|
|
70
|
+
getVersion,
|
|
71
|
+
getMetaPath,
|
|
72
|
+
readMeta,
|
|
73
|
+
writeMeta,
|
|
74
|
+
isStale
|
|
75
|
+
};
|