ramble-vault 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 +36 -0
- package/bin/cli.js +163 -0
- package/package.json +19 -0
- package/skills/ideas.md +25 -0
- package/skills/recall.md +26 -0
- package/skills/trace.md +30 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 THENEXTCO INC.
|
|
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,36 @@
|
|
|
1
|
+
# ramble-vault
|
|
2
|
+
|
|
3
|
+
Connect [Ramble On](https://apps.apple.com/app/ramble-on) voice notes to Claude Code.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
1. In Ramble On → Settings → enable **Markdown Sync** and pick an iCloud Drive folder
|
|
8
|
+
2. Run:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npx ramble-vault
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
3. Open Claude Code and ask about your recordings
|
|
15
|
+
|
|
16
|
+
## What it does
|
|
17
|
+
|
|
18
|
+
- Finds your Ramble On notes in iCloud Drive
|
|
19
|
+
- Adds the folder to Claude Code's `additionalDirectories`
|
|
20
|
+
- Installs 3 skills:
|
|
21
|
+
|
|
22
|
+
| Skill | What it does |
|
|
23
|
+
|-------|-------------|
|
|
24
|
+
| `/recall <query>` | Search voice notes by content, date, context, or speakers |
|
|
25
|
+
| `/ideas` | Find cross-domain patterns and connections across all notes |
|
|
26
|
+
| `/trace <topic>` | Track how an idea evolved over time |
|
|
27
|
+
|
|
28
|
+
## Requirements
|
|
29
|
+
|
|
30
|
+
- macOS (iCloud Drive must be enabled)
|
|
31
|
+
- [Claude Code](https://claude.ai/code) installed
|
|
32
|
+
- Ramble On with Markdown Sync enabled
|
|
33
|
+
|
|
34
|
+
## License
|
|
35
|
+
|
|
36
|
+
MIT
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const os = require("os");
|
|
6
|
+
|
|
7
|
+
const ICLOUD_BASE = path.join(
|
|
8
|
+
os.homedir(),
|
|
9
|
+
"Library/Mobile Documents/com~apple~CloudDocs"
|
|
10
|
+
);
|
|
11
|
+
const CLAUDE_DIR = path.join(os.homedir(), ".claude");
|
|
12
|
+
const SETTINGS_PATH = path.join(CLAUDE_DIR, "settings.json");
|
|
13
|
+
const SKILLS_DIR = path.join(CLAUDE_DIR, "skills");
|
|
14
|
+
|
|
15
|
+
function log(msg) {
|
|
16
|
+
console.log(` ${msg}`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function success(msg) {
|
|
20
|
+
console.log(` \x1b[32m✓\x1b[0m ${msg}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function error(msg) {
|
|
24
|
+
console.error(` \x1b[31m✗\x1b[0m ${msg}`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Find the Ramble On vault in iCloud Drive
|
|
28
|
+
function findVault() {
|
|
29
|
+
if (!fs.existsSync(ICLOUD_BASE)) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Recursively search for a CLAUDE.md containing "Ramble On"
|
|
34
|
+
function search(dir, depth) {
|
|
35
|
+
if (depth > 3) return null;
|
|
36
|
+
|
|
37
|
+
const claudeMd = path.join(dir, "CLAUDE.md");
|
|
38
|
+
if (fs.existsSync(claudeMd)) {
|
|
39
|
+
try {
|
|
40
|
+
const content = fs.readFileSync(claudeMd, "utf-8");
|
|
41
|
+
if (content.includes("Ramble On")) {
|
|
42
|
+
return dir;
|
|
43
|
+
}
|
|
44
|
+
} catch {}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
if (!entry.isDirectory()) continue;
|
|
51
|
+
if (entry.name.startsWith(".")) continue;
|
|
52
|
+
const result = search(path.join(dir, entry.name), depth + 1);
|
|
53
|
+
if (result) return result;
|
|
54
|
+
}
|
|
55
|
+
} catch {}
|
|
56
|
+
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Check common name first
|
|
61
|
+
const defaultPath = path.join(ICLOUD_BASE, "RambleOnNotes");
|
|
62
|
+
if (fs.existsSync(defaultPath)) {
|
|
63
|
+
const claudeMd = path.join(defaultPath, "CLAUDE.md");
|
|
64
|
+
if (fs.existsSync(claudeMd)) {
|
|
65
|
+
return defaultPath;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return search(ICLOUD_BASE, 0);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Add vault path to Claude Code settings
|
|
73
|
+
function addToSettings(vaultPath) {
|
|
74
|
+
fs.mkdirSync(CLAUDE_DIR, { recursive: true });
|
|
75
|
+
|
|
76
|
+
let settings = {};
|
|
77
|
+
if (fs.existsSync(SETTINGS_PATH)) {
|
|
78
|
+
try {
|
|
79
|
+
settings = JSON.parse(fs.readFileSync(SETTINGS_PATH, "utf-8"));
|
|
80
|
+
} catch {
|
|
81
|
+
settings = {};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!Array.isArray(settings.additionalDirectories)) {
|
|
86
|
+
settings.additionalDirectories = [];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!settings.additionalDirectories.includes(vaultPath)) {
|
|
90
|
+
settings.additionalDirectories.push(vaultPath);
|
|
91
|
+
fs.writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2) + "\n");
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return false; // already present
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Install skills to ~/.claude/skills/
|
|
99
|
+
function installSkills() {
|
|
100
|
+
fs.mkdirSync(SKILLS_DIR, { recursive: true });
|
|
101
|
+
|
|
102
|
+
const skillsSource = path.join(__dirname, "..", "skills");
|
|
103
|
+
const files = fs.readdirSync(skillsSource).filter((f) => f.endsWith(".md"));
|
|
104
|
+
const installed = [];
|
|
105
|
+
|
|
106
|
+
for (const file of files) {
|
|
107
|
+
const src = path.join(skillsSource, file);
|
|
108
|
+
const dest = path.join(SKILLS_DIR, file);
|
|
109
|
+
fs.copyFileSync(src, dest);
|
|
110
|
+
installed.push(file.replace(".md", ""));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return installed;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Main
|
|
117
|
+
function main() {
|
|
118
|
+
console.log();
|
|
119
|
+
console.log(" \x1b[1mRamble On → Claude Code\x1b[0m");
|
|
120
|
+
console.log();
|
|
121
|
+
|
|
122
|
+
// Step 1: Find vault
|
|
123
|
+
log("Looking for voice notes in iCloud Drive...");
|
|
124
|
+
const vaultPath = findVault();
|
|
125
|
+
|
|
126
|
+
if (!vaultPath) {
|
|
127
|
+
error("Could not find Ramble On notes in iCloud Drive.");
|
|
128
|
+
console.log();
|
|
129
|
+
log("Make sure you've:");
|
|
130
|
+
log(" 1. Enabled Markdown Sync in Ramble On settings");
|
|
131
|
+
log(" 2. Picked an iCloud Drive folder");
|
|
132
|
+
log(" 3. Exported at least one recording");
|
|
133
|
+
console.log();
|
|
134
|
+
log("Then run this command again.");
|
|
135
|
+
console.log();
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
success(`Found vault: ${vaultPath}`);
|
|
140
|
+
|
|
141
|
+
// Step 2: Add to Claude Code settings
|
|
142
|
+
const added = addToSettings(vaultPath);
|
|
143
|
+
if (added) {
|
|
144
|
+
success("Added to Claude Code settings");
|
|
145
|
+
} else {
|
|
146
|
+
success("Already in Claude Code settings");
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Step 3: Install skills
|
|
150
|
+
const skills = installSkills();
|
|
151
|
+
success(`Installed skills: ${skills.map((s) => `/${s}`).join(", ")}`);
|
|
152
|
+
|
|
153
|
+
// Done
|
|
154
|
+
console.log();
|
|
155
|
+
console.log(" \x1b[1m\x1b[32mDone!\x1b[0m Open Claude Code and try:");
|
|
156
|
+
console.log();
|
|
157
|
+
console.log(" \x1b[36m/recall\x1b[0m what did I talk about this week?");
|
|
158
|
+
console.log(" \x1b[36m/ideas\x1b[0m");
|
|
159
|
+
console.log(" \x1b[36m/trace\x1b[0m pricing strategy");
|
|
160
|
+
console.log();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ramble-vault",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Connect Ramble On voice notes to Claude Code",
|
|
5
|
+
"bin": {
|
|
6
|
+
"ramble-vault": "bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"keywords": [
|
|
9
|
+
"claude-code",
|
|
10
|
+
"voice-notes",
|
|
11
|
+
"ramble-on",
|
|
12
|
+
"transcription"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/arnabing/ramble-vault"
|
|
18
|
+
}
|
|
19
|
+
}
|
package/skills/ideas.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ideas
|
|
3
|
+
description: Find cross-domain patterns and connections across all voice notes
|
|
4
|
+
user_invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Scan all Ramble On voice notes across all context folders to find patterns the user might not see.
|
|
8
|
+
|
|
9
|
+
The voice notes folder is in additionalDirectories — look for the folder containing a CLAUDE.md with "Ramble On" in it.
|
|
10
|
+
|
|
11
|
+
## What to do
|
|
12
|
+
|
|
13
|
+
1. Read recent notes across all context folders (brain-dump, journal, work, medical, legal, school)
|
|
14
|
+
2. Identify recurring themes, people, topics, or concerns
|
|
15
|
+
3. Find connections between different domains (e.g., a work frustration that echoes a journal entry)
|
|
16
|
+
4. Surface ideas the user has been circling but hasn't explicitly named
|
|
17
|
+
|
|
18
|
+
## What to present
|
|
19
|
+
|
|
20
|
+
- **Patterns found**: Recurring themes with evidence from specific notes
|
|
21
|
+
- **Connections**: Links between notes in different contexts
|
|
22
|
+
- **Unnamed ideas**: Things the user keeps coming back to but hasn't crystallized
|
|
23
|
+
- **Suggested next steps**: Based on where their thinking seems to be heading
|
|
24
|
+
|
|
25
|
+
Keep it concise. Lead with the most interesting or surprising finding.
|
package/skills/recall.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: recall
|
|
3
|
+
description: Search your Ramble On voice notes for information matching a query
|
|
4
|
+
user_invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Search the user's Ramble On voice notes for information matching their query.
|
|
8
|
+
|
|
9
|
+
The voice notes folder is in additionalDirectories — look for the folder containing a CLAUDE.md with "Ramble On" in it.
|
|
10
|
+
|
|
11
|
+
## How to search
|
|
12
|
+
|
|
13
|
+
1. **By content**: Grep for keywords across all .md files in the vault
|
|
14
|
+
2. **By frontmatter**: Search YAML fields — `date`, `context` (brain-dump, journal, medical, work, legal, school), `speakers`, `duration`
|
|
15
|
+
3. **By filename**: Files are named `{context}/{YYYY-MM-DD}-{slug}.md`
|
|
16
|
+
|
|
17
|
+
## What to return
|
|
18
|
+
|
|
19
|
+
- Relevant excerpts with source file references
|
|
20
|
+
- The AI-generated summary sections (## headings) are more useful than raw transcripts
|
|
21
|
+
- Include the date and context for each match
|
|
22
|
+
- If multiple notes match, summarize across them
|
|
23
|
+
|
|
24
|
+
## Arguments
|
|
25
|
+
|
|
26
|
+
If the user provides a query after `/recall`, search for that. If no query, ask what they're looking for.
|
package/skills/trace.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: trace
|
|
3
|
+
description: Track how an idea evolved across voice notes over time
|
|
4
|
+
user_invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Search Ramble On voice notes for a given topic and show how the user's thinking evolved over time.
|
|
8
|
+
|
|
9
|
+
The voice notes folder is in additionalDirectories — look for the folder containing a CLAUDE.md with "Ramble On" in it.
|
|
10
|
+
|
|
11
|
+
## Arguments
|
|
12
|
+
|
|
13
|
+
The user provides a topic after `/trace` (e.g., `/trace pricing strategy`). If no topic, ask what to trace.
|
|
14
|
+
|
|
15
|
+
## What to do
|
|
16
|
+
|
|
17
|
+
1. Search all voice notes for the topic — grep content, titles, and frontmatter
|
|
18
|
+
2. Order matches chronologically by the `date` field in YAML frontmatter
|
|
19
|
+
3. Read each matching note to understand the user's position at that point
|
|
20
|
+
|
|
21
|
+
## What to present
|
|
22
|
+
|
|
23
|
+
A timeline narrative showing:
|
|
24
|
+
- **First mention**: When and where the idea first appeared
|
|
25
|
+
- **Evolution**: How the thinking changed over time
|
|
26
|
+
- **Perspective shifts**: Moments where the user changed their mind or gained new insight
|
|
27
|
+
- **Current state**: Where the thinking stands as of the most recent note
|
|
28
|
+
- **Confidence trajectory**: Did they become more or less certain?
|
|
29
|
+
|
|
30
|
+
Present as a readable narrative, not a list. Quote key phrases from the notes.
|