mindlore 0.3.0 → 0.3.2
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 +8 -4
- package/dist/scripts/init.js +84 -9
- package/dist/scripts/init.js.map +1 -1
- package/dist/scripts/lib/constants.d.ts +7 -0
- package/dist/scripts/lib/constants.d.ts.map +1 -1
- package/dist/scripts/lib/constants.js +22 -1
- package/dist/scripts/lib/constants.js.map +1 -1
- package/dist/scripts/mindlore-health-check.d.ts +1 -1
- package/dist/scripts/mindlore-health-check.js +6 -18
- package/dist/scripts/mindlore-health-check.js.map +1 -1
- package/dist/scripts/quality-populate.d.ts +11 -0
- package/dist/scripts/quality-populate.d.ts.map +1 -0
- package/dist/scripts/quality-populate.js +86 -0
- package/dist/scripts/quality-populate.js.map +1 -0
- package/dist/scripts/uninstall.js +16 -6
- package/dist/scripts/uninstall.js.map +1 -1
- package/dist/tests/fts5-sync.test.d.ts +2 -0
- package/dist/tests/fts5-sync.test.d.ts.map +1 -0
- package/dist/tests/fts5-sync.test.js +120 -0
- package/dist/tests/fts5-sync.test.js.map +1 -0
- package/dist/tests/fts5.test.js +21 -7
- package/dist/tests/fts5.test.js.map +1 -1
- package/dist/tests/hook-smoke.test.js +2 -2
- package/dist/tests/hook-smoke.test.js.map +1 -1
- package/dist/tests/init.test.js +59 -0
- package/dist/tests/init.test.js.map +1 -1
- package/dist/tests/model-router.test.d.ts +2 -0
- package/dist/tests/model-router.test.d.ts.map +1 -0
- package/dist/tests/model-router.test.js +146 -0
- package/dist/tests/model-router.test.js.map +1 -0
- package/dist/tests/quality-populate.test.js +73 -0
- package/dist/tests/quality-populate.test.js.map +1 -1
- package/hooks/lib/mindlore-common.cjs +49 -0
- package/hooks/mindlore-model-router.cjs +54 -0
- package/package.json +3 -2
- package/plugin.json +6 -1
- package/skills/mindlore-evolve/SKILL.md +22 -4
- package/skills/mindlore-explore/SKILL.md +23 -3
- package/skills/mindlore-ingest/SKILL.md +51 -33
- package/templates/config.json +9 -0
|
@@ -3,7 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
6
7
|
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
7
9
|
const db_1 = require("./helpers/db");
|
|
8
10
|
const TEST_DIR = path_1.default.join(__dirname, '..', '.test-quality-populate');
|
|
9
11
|
const DB_PATH = path_1.default.join(TEST_DIR, 'mindlore.db');
|
|
@@ -82,4 +84,75 @@ describe('Quality populate — storage and retrieval', () => {
|
|
|
82
84
|
expect(qualities).toContain(null);
|
|
83
85
|
});
|
|
84
86
|
});
|
|
87
|
+
// ── Bulk populate script integration tests ──────────────────────────────
|
|
88
|
+
const INIT_SCRIPT = path_1.default.join(__dirname, '..', 'dist', 'scripts', 'init.js');
|
|
89
|
+
const POPULATE_SCRIPT = path_1.default.join(__dirname, '..', 'dist', 'scripts', 'quality-populate.js');
|
|
90
|
+
const BULK_DIR = path_1.default.join(__dirname, '..', '.test-quality-bulk');
|
|
91
|
+
function initMindlore() {
|
|
92
|
+
(0, child_process_1.execSync)(`node "${INIT_SCRIPT}" init`, {
|
|
93
|
+
cwd: BULK_DIR,
|
|
94
|
+
stdio: 'pipe',
|
|
95
|
+
env: { ...process.env, HOME: BULK_DIR, USERPROFILE: BULK_DIR },
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function writeSource(filename, frontmatter, body) {
|
|
99
|
+
const sourcesDir = path_1.default.join(BULK_DIR, '.mindlore', 'sources');
|
|
100
|
+
fs_1.default.mkdirSync(sourcesDir, { recursive: true });
|
|
101
|
+
fs_1.default.writeFileSync(path_1.default.join(sourcesDir, filename), `---\n${frontmatter}\n---\n\n${body}\n`, 'utf8');
|
|
102
|
+
}
|
|
103
|
+
function readSourceQuality(filename) {
|
|
104
|
+
const content = fs_1.default.readFileSync(path_1.default.join(BULK_DIR, '.mindlore', 'sources', filename), 'utf8');
|
|
105
|
+
const match = content.match(/^quality:\s*(.+)$/m);
|
|
106
|
+
return match?.[1]?.trim() ?? null;
|
|
107
|
+
}
|
|
108
|
+
function runPopulate() {
|
|
109
|
+
return (0, child_process_1.execSync)(`node "${POPULATE_SCRIPT}"`, {
|
|
110
|
+
cwd: BULK_DIR,
|
|
111
|
+
encoding: 'utf8',
|
|
112
|
+
env: { ...process.env, HOME: BULK_DIR, USERPROFILE: BULK_DIR },
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
describe('Quality populate — bulk script', () => {
|
|
116
|
+
beforeEach(() => {
|
|
117
|
+
fs_1.default.mkdirSync(BULK_DIR, { recursive: true });
|
|
118
|
+
initMindlore();
|
|
119
|
+
});
|
|
120
|
+
afterEach(() => {
|
|
121
|
+
fs_1.default.rmSync(BULK_DIR, { recursive: true, force: true });
|
|
122
|
+
});
|
|
123
|
+
test('should assign quality based on source_type heuristic', () => {
|
|
124
|
+
writeSource('github-test.md', 'slug: github-test\ntype: source\nsource_type: github-repo', '# GitHub Test');
|
|
125
|
+
writeSource('blog-test.md', 'slug: blog-test\ntype: source\nsource_type: blog', '# Blog Test');
|
|
126
|
+
writeSource('snippet-test.md', 'slug: snippet-test\ntype: source\nsource_type: snippet', '# Snippet Test');
|
|
127
|
+
runPopulate();
|
|
128
|
+
expect(readSourceQuality('github-test.md')).toBe('high');
|
|
129
|
+
expect(readSourceQuality('blog-test.md')).toBe('medium');
|
|
130
|
+
expect(readSourceQuality('snippet-test.md')).toBe('low');
|
|
131
|
+
});
|
|
132
|
+
test('should preserve existing quality values', () => {
|
|
133
|
+
writeSource('already-set.md', 'slug: already-set\ntype: source\nsource_type: blog\nquality: high', '# Already High');
|
|
134
|
+
runPopulate();
|
|
135
|
+
expect(readSourceQuality('already-set.md')).toBe('high');
|
|
136
|
+
});
|
|
137
|
+
test('should handle missing source_type with URL fallback', () => {
|
|
138
|
+
writeSource('github-url.md', 'slug: github-url\ntype: source\nsource_url: https://github.com/user/repo', '# GitHub URL');
|
|
139
|
+
writeSource('docs-url.md', 'slug: docs-url\ntype: source\nsource_url: https://docs.anthropic.com/api', '# Docs URL');
|
|
140
|
+
runPopulate();
|
|
141
|
+
expect(readSourceQuality('github-url.md')).toBe('high');
|
|
142
|
+
expect(readSourceQuality('docs-url.md')).toBe('high');
|
|
143
|
+
});
|
|
144
|
+
test('should default to medium when no heuristic matches', () => {
|
|
145
|
+
writeSource('unknown.md', 'slug: unknown\ntype: source', '# Unknown Source');
|
|
146
|
+
runPopulate();
|
|
147
|
+
expect(readSourceQuality('unknown.md')).toBe('medium');
|
|
148
|
+
});
|
|
149
|
+
test('should report correct counts', () => {
|
|
150
|
+
writeSource('needs-quality.md', 'slug: needs-quality\ntype: source\nsource_type: blog', '# Needs Quality');
|
|
151
|
+
writeSource('has-quality.md', 'slug: has-quality\ntype: source\nquality: low', '# Has Quality');
|
|
152
|
+
const output = runPopulate();
|
|
153
|
+
expect(output).toContain('1 updated');
|
|
154
|
+
expect(output).toContain('1 already set');
|
|
155
|
+
expect(output).toContain('2 total');
|
|
156
|
+
});
|
|
157
|
+
});
|
|
85
158
|
//# sourceMappingURL=quality-populate.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quality-populate.test.js","sourceRoot":"","sources":["../../tests/quality-populate.test.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;
|
|
1
|
+
{"version":3,"file":"quality-populate.test.js","sourceRoot":"","sources":["../../tests/quality-populate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -233,6 +233,52 @@ function readHookStdin(fields) {
|
|
|
233
233
|
return input;
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
+
/**
|
|
237
|
+
* Read .mindlore/config.json and return parsed object.
|
|
238
|
+
* Returns null if file doesn't exist or is invalid JSON.
|
|
239
|
+
*/
|
|
240
|
+
function readConfig(mindloreDir) {
|
|
241
|
+
if (!mindloreDir) return null;
|
|
242
|
+
const configPath = path.join(mindloreDir, 'config.json');
|
|
243
|
+
try {
|
|
244
|
+
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
245
|
+
} catch (_err) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Detect FTS5 schema version by probing columns.
|
|
252
|
+
* FTS5 virtual tables don't support PRAGMA table_info, so try/catch is required.
|
|
253
|
+
* @param {import('better-sqlite3').Database} db
|
|
254
|
+
* @returns {number} 2 | 7 | 9 | 10
|
|
255
|
+
*/
|
|
256
|
+
function detectSchemaVersion(db) {
|
|
257
|
+
try {
|
|
258
|
+
db.prepare('SELECT tags, quality, date_captured FROM mindlore_fts LIMIT 0').run();
|
|
259
|
+
return 10;
|
|
260
|
+
} catch (_err) {
|
|
261
|
+
try {
|
|
262
|
+
db.prepare('SELECT tags, quality FROM mindlore_fts LIMIT 0').run();
|
|
263
|
+
return 9;
|
|
264
|
+
} catch (_err2) {
|
|
265
|
+
try {
|
|
266
|
+
db.prepare('SELECT slug, description, category, title FROM mindlore_fts LIMIT 0').run();
|
|
267
|
+
return 7;
|
|
268
|
+
} catch (_err3) {
|
|
269
|
+
return 2;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const DEFAULT_MODELS = {
|
|
276
|
+
ingest: 'haiku',
|
|
277
|
+
evolve: 'sonnet',
|
|
278
|
+
explore: 'sonnet',
|
|
279
|
+
default: 'haiku',
|
|
280
|
+
};
|
|
281
|
+
|
|
236
282
|
module.exports = {
|
|
237
283
|
MINDLORE_DIR,
|
|
238
284
|
GLOBAL_MINDLORE_DIR,
|
|
@@ -254,4 +300,7 @@ module.exports = {
|
|
|
254
300
|
requireDatabase,
|
|
255
301
|
openDatabase,
|
|
256
302
|
getAllMdFiles,
|
|
303
|
+
readConfig,
|
|
304
|
+
detectSchemaVersion,
|
|
305
|
+
DEFAULT_MODELS,
|
|
257
306
|
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* mindlore-model-router — PreToolUse (Agent) hook
|
|
5
|
+
* Overrides model for [mindlore:SKILL] marked Agent spawns.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const { findMindloreDir, readConfig, DEFAULT_MODELS } = require('./lib/mindlore-common.cjs');
|
|
10
|
+
|
|
11
|
+
const SKILL_KEYS = Object.keys(DEFAULT_MODELS).filter((k) => k !== 'default');
|
|
12
|
+
const MARKER_REGEX = new RegExp(`\\[mindlore:(${SKILL_KEYS.join('|')})\\]`);
|
|
13
|
+
|
|
14
|
+
function main() {
|
|
15
|
+
const mindloreDir = findMindloreDir();
|
|
16
|
+
if (!mindloreDir) return;
|
|
17
|
+
|
|
18
|
+
let input;
|
|
19
|
+
try {
|
|
20
|
+
const raw = fs.readFileSync(0, 'utf8').trim();
|
|
21
|
+
if (!raw) return;
|
|
22
|
+
input = JSON.parse(raw);
|
|
23
|
+
} catch (_err) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const toolName = input.tool_name || '';
|
|
28
|
+
if (toolName !== 'Agent') return;
|
|
29
|
+
|
|
30
|
+
const toolInput = input.tool_input || {};
|
|
31
|
+
const prompt = toolInput.prompt || '';
|
|
32
|
+
const match = prompt.match(MARKER_REGEX);
|
|
33
|
+
if (!match) return;
|
|
34
|
+
|
|
35
|
+
const skill = match[1];
|
|
36
|
+
|
|
37
|
+
// Resolve model: config.json → config default → hardcoded
|
|
38
|
+
const config = readConfig(mindloreDir);
|
|
39
|
+
const models = (config && config.models) || {};
|
|
40
|
+
const model = models[skill] || models.default || DEFAULT_MODELS[skill] || DEFAULT_MODELS.default;
|
|
41
|
+
|
|
42
|
+
const updatedInput = { ...toolInput, model: model };
|
|
43
|
+
|
|
44
|
+
const output = {
|
|
45
|
+
hookSpecificOutput: {
|
|
46
|
+
hookEventName: 'PreToolUse',
|
|
47
|
+
updatedInput: updatedInput,
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
process.stdout.write(JSON.stringify(output));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindlore",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "AI-native knowledge system for Claude Code",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"prepublishOnly": "npm run build",
|
|
17
17
|
"health": "node dist/scripts/mindlore-health-check.js",
|
|
18
18
|
"index": "node dist/scripts/mindlore-fts5-index.js",
|
|
19
|
-
"search": "node dist/scripts/mindlore-fts5-search.js"
|
|
19
|
+
"search": "node dist/scripts/mindlore-fts5-search.js",
|
|
20
|
+
"quality": "node dist/scripts/quality-populate.js"
|
|
20
21
|
},
|
|
21
22
|
"keywords": [
|
|
22
23
|
"claude-code",
|
package/plugin.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
{
|
|
12
12
|
"name": "mindlore-health",
|
|
13
13
|
"path": "skills/mindlore-health/SKILL.md",
|
|
14
|
-
"description": "Run
|
|
14
|
+
"description": "Run 16-point structural health check on .mindlore/ knowledge base"
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
17
|
"name": "mindlore-query",
|
|
@@ -89,6 +89,11 @@
|
|
|
89
89
|
"event": "PreToolUse",
|
|
90
90
|
"script": "hooks/mindlore-dont-repeat.cjs",
|
|
91
91
|
"if": "Write|Edit"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"event": "PreToolUse",
|
|
95
|
+
"script": "hooks/mindlore-model-router.cjs",
|
|
96
|
+
"if": "Agent"
|
|
92
97
|
}
|
|
93
98
|
]
|
|
94
99
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: mindlore-evolve
|
|
3
3
|
description: Knowledge schema co-evolution — scan domains+sources, detect inconsistencies, suggest updates
|
|
4
4
|
effort: medium
|
|
5
|
-
allowed-tools: [Read, Write, Edit, Bash, Grep, Glob]
|
|
5
|
+
allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent]
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# /mindlore-evolve
|
|
@@ -26,10 +26,27 @@ User says `/mindlore-evolve`, "knowledge evolve", "bilgi sistemi evrimle", "sema
|
|
|
26
26
|
|
|
27
27
|
Scan all domains and sources for inconsistencies.
|
|
28
28
|
|
|
29
|
+
**Agent Delegation:** Tarama işini subagent'a delege et (context koruma).
|
|
30
|
+
|
|
29
31
|
**Flow:**
|
|
30
|
-
1.
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
1. Spawn an Agent for scanning:
|
|
33
|
+
```
|
|
34
|
+
Agent({
|
|
35
|
+
description: "mindlore evolve: scan",
|
|
36
|
+
subagent_type: "Explore",
|
|
37
|
+
prompt: "[mindlore:evolve] Scan .mindlore/ for inconsistencies. <aşağıdaki talimatları buraya koy>"
|
|
38
|
+
})
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Agent talimatları:
|
|
42
|
+
a. Read INDEX.md to get domain and source file lists
|
|
43
|
+
b. Read all domain files (from `domains/`)
|
|
44
|
+
c. Read all source files (from `sources/`)
|
|
45
|
+
d. Detect issues (see list below)
|
|
46
|
+
e. Return findings as structured table
|
|
47
|
+
|
|
48
|
+
2. After agent returns — review findings
|
|
49
|
+
3. Show findings table to user
|
|
33
50
|
4. Detect issues:
|
|
34
51
|
- **Orphan files:** .md files in content directories not listed in INDEX.md
|
|
35
52
|
- **Missing references:** Source exists but no domain mentions it
|
|
@@ -65,6 +82,7 @@ Apply suggested changes with user approval.
|
|
|
65
82
|
- Show diff preview before applying
|
|
66
83
|
- After changes, run `node dist/scripts/mindlore-fts5-index.js` for FTS5 sync
|
|
67
84
|
- Log every change to log.md with timestamp
|
|
85
|
+
- The `[mindlore:evolve]` marker in the Agent prompt is required — it triggers the model-router hook to use the cost-optimized model (sonnet by default)
|
|
68
86
|
|
|
69
87
|
## Output Format
|
|
70
88
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: mindlore-explore
|
|
3
3
|
description: Discover unexpected connections between sources — undirected knowledge exploration
|
|
4
4
|
effort: medium
|
|
5
|
-
allowed-tools: [Read, Write, Edit, Bash, Grep, Glob]
|
|
5
|
+
allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent]
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# /mindlore-explore
|
|
@@ -22,8 +22,27 @@ User says `/mindlore-explore`, "knowledge explore", "baglanti kesfet", "cross-re
|
|
|
22
22
|
|
|
23
23
|
## Flow
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
**Agent Delegation:** Cross-reference analizini subagent'a delege et (context koruma).
|
|
26
|
+
|
|
27
|
+
1. Spawn an Agent for analysis:
|
|
28
|
+
```
|
|
29
|
+
Agent({
|
|
30
|
+
description: "mindlore explore: connections",
|
|
31
|
+
subagent_type: "Explore",
|
|
32
|
+
prompt: "[mindlore:explore] Analyze .mindlore/ for unexpected connections. <aşağıdaki talimatları buraya koy>"
|
|
33
|
+
})
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Agent talimatları:
|
|
37
|
+
a. Read all source and domain files from active scope
|
|
38
|
+
b. Cross-match by tag + content (see criteria below)
|
|
39
|
+
c. Rank connections by strength
|
|
40
|
+
d. Return findings as structured table
|
|
41
|
+
|
|
42
|
+
2. After agent returns — review and show findings to user
|
|
43
|
+
3. On approval, write connection files (main session handles writes)
|
|
44
|
+
|
|
45
|
+
**Cross-match criteria:**
|
|
27
46
|
- Files sharing tags but not referencing each other
|
|
28
47
|
- Sources covering similar topics from different angles
|
|
29
48
|
- Sources that could bridge between domains
|
|
@@ -65,6 +84,7 @@ tags: [shared-tag-1, shared-tag-2]
|
|
|
65
84
|
- Update INDEX.md with new connections entry
|
|
66
85
|
- Append EXPLORE entry to log.md
|
|
67
86
|
- Strength is LLM-assessed based on tag overlap + content similarity
|
|
87
|
+
- The `[mindlore:explore]` marker in the Agent prompt is required — it triggers the model-router hook to use the cost-optimized model (sonnet by default)
|
|
68
88
|
|
|
69
89
|
## Output Format
|
|
70
90
|
|
|
@@ -24,41 +24,59 @@ User shares a URL, text, file, or says "kaynak ekle", "source ingest", "bu linki
|
|
|
24
24
|
## Modes
|
|
25
25
|
|
|
26
26
|
### URL Mode
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
1. markitdown installed → `markitdown <url>` (includes transcript)
|
|
32
|
-
2. Else youtube-transcript npm → `hasYoutubeTranscript()` check
|
|
33
|
-
3. Else → ask user to paste transcript manually
|
|
34
|
-
2. Save raw capture to `.mindlore/raw/` with frontmatter:
|
|
35
|
-
```yaml
|
|
36
|
-
---
|
|
37
|
-
slug: source-name-kebab
|
|
38
|
-
type: raw
|
|
39
|
-
source_url: https://...
|
|
40
|
-
date_captured: YYYY-MM-DD
|
|
41
|
-
tags: [tag1, tag2]
|
|
42
|
-
---
|
|
27
|
+
|
|
28
|
+
**Agent Delegation:** URL fetch + raw/sources yazımını subagent'a delege et (maliyet optimizasyonu).
|
|
29
|
+
|
|
30
|
+
1. Spawn an Agent with the following pattern:
|
|
43
31
|
```
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
title: Human Readable Title
|
|
50
|
-
source_url: https://...
|
|
51
|
-
source_type: github-repo|blog|docs|video|x-thread
|
|
52
|
-
date_captured: YYYY-MM-DD
|
|
53
|
-
tags: [tag1, tag2]
|
|
54
|
-
quality: high|medium|low
|
|
55
|
-
ingested: true
|
|
56
|
-
---
|
|
32
|
+
Agent({
|
|
33
|
+
description: "mindlore ingest: <slug>",
|
|
34
|
+
subagent_type: "researcher",
|
|
35
|
+
prompt: "[mindlore:ingest] <aşağıdaki talimatları buraya koy>"
|
|
36
|
+
})
|
|
57
37
|
```
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
38
|
+
|
|
39
|
+
Agent talimatları:
|
|
40
|
+
- Extract content from URL:
|
|
41
|
+
- If `markitdown` is available: `markitdown <url>` (best quality, zero tokens)
|
|
42
|
+
- Else: use `WebFetch` or `ctx_fetch_and_index`
|
|
43
|
+
- **YouTube URL** detected (`youtube.com` or `youtu.be`):
|
|
44
|
+
1. markitdown installed → `markitdown <url>` (includes transcript)
|
|
45
|
+
2. Else youtube-transcript npm → `hasYoutubeTranscript()` check
|
|
46
|
+
3. Else → return error, ask user to paste transcript
|
|
47
|
+
- Save raw capture to `.mindlore/raw/` with frontmatter:
|
|
48
|
+
```yaml
|
|
49
|
+
---
|
|
50
|
+
slug: source-name-kebab
|
|
51
|
+
type: raw
|
|
52
|
+
source_url: https://...
|
|
53
|
+
date_captured: YYYY-MM-DD
|
|
54
|
+
tags: [tag1, tag2]
|
|
55
|
+
---
|
|
56
|
+
```
|
|
57
|
+
- Summarize into `.mindlore/sources/` with full frontmatter:
|
|
58
|
+
```yaml
|
|
59
|
+
---
|
|
60
|
+
slug: source-name-kebab
|
|
61
|
+
type: source
|
|
62
|
+
title: Human Readable Title
|
|
63
|
+
source_url: https://...
|
|
64
|
+
source_type: github-repo|blog|docs|video|x-thread
|
|
65
|
+
date_captured: YYYY-MM-DD
|
|
66
|
+
tags: [tag1, tag2]
|
|
67
|
+
quality: high|medium|low
|
|
68
|
+
ingested: true
|
|
69
|
+
---
|
|
70
|
+
```
|
|
71
|
+
- Agent must report: created file paths, slug, quality assigned
|
|
72
|
+
|
|
73
|
+
2. After agent returns — verify raw/ and sources/ files exist and have valid frontmatter
|
|
74
|
+
3. Update relevant domain page(s) in `.mindlore/domains/` (max 2)
|
|
75
|
+
4. Update `.mindlore/INDEX.md` stats line
|
|
76
|
+
5. Append entry to `.mindlore/log.md`
|
|
77
|
+
6. Run FTS5 re-index: `npm run index`
|
|
78
|
+
|
|
79
|
+
**IMPORTANT:** The `[mindlore:ingest]` marker in the Agent prompt is required — it triggers the model-router hook to use the cost-optimized model (haiku by default).
|
|
62
80
|
|
|
63
81
|
### Text Mode
|
|
64
82
|
1. User pastes text directly
|