@geoql/mdr 0.0.1 → 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 +3 -3
- package/bin/detect-user.sh +0 -0
- package/bin/index-conversations.ts +2 -2
- package/bin/macrodata-daemon.ts +1 -1
- package/bin/macrodata-hook.sh +1 -1
- package/dist/bin/index-conversations.js +0 -0
- package/dist/bin/macrodata-daemon.js +0 -0
- package/dist/opencode/skills/macrodata-distill/SKILL.md +1 -1
- package/opencode/context.ts +44 -44
- package/opencode/conversations.ts +20 -20
- package/opencode/index.ts +26 -26
- package/opencode/journal.ts +24 -24
- package/opencode/logger.ts +8 -8
- package/opencode/search.ts +31 -31
- package/opencode/skills/macrodata-distill/SKILL.md +1 -1
- package/opencode/tools.ts +62 -62
- package/package.json +17 -18
- package/src/config.ts +13 -13
- package/src/conversations.ts +61 -61
- package/src/daemon.ts +71 -71
- package/src/detect-user.ts +24 -24
- package/src/embeddings.ts +25 -25
- package/src/index.ts +129 -129
- package/src/indexer.ts +36 -36
package/opencode/tools.ts
CHANGED
|
@@ -4,31 +4,31 @@
|
|
|
4
4
|
* Separate tools for memory operations
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { tool } from
|
|
8
|
-
import { existsSync, readFileSync, writeFileSync, readdirSync, mkdirSync, unlinkSync } from
|
|
9
|
-
import { join } from
|
|
10
|
-
import { getRemindersDir } from
|
|
7
|
+
import { tool } from '@opencode-ai/plugin';
|
|
8
|
+
import { existsSync, readFileSync, writeFileSync, readdirSync, mkdirSync, unlinkSync } from 'fs';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import { getRemindersDir } from '../src/config.js';
|
|
11
11
|
import {
|
|
12
12
|
logJournal,
|
|
13
13
|
getRecentJournal,
|
|
14
14
|
getRecentSummaries,
|
|
15
15
|
saveConversationSummary,
|
|
16
|
-
} from
|
|
17
|
-
import { searchMemory, rebuildMemoryIndex, getMemoryIndexStats } from
|
|
16
|
+
} from './journal.js';
|
|
17
|
+
import { searchMemory, rebuildMemoryIndex, getMemoryIndexStats } from './search.js';
|
|
18
18
|
import {
|
|
19
19
|
searchConversations,
|
|
20
20
|
rebuildConversationIndex,
|
|
21
21
|
getConversationIndexStats,
|
|
22
|
-
} from
|
|
23
|
-
import { logger } from
|
|
22
|
+
} from './conversations.js';
|
|
23
|
+
import { logger } from './logger.js';
|
|
24
24
|
|
|
25
25
|
interface Schedule {
|
|
26
26
|
id: string;
|
|
27
|
-
type:
|
|
27
|
+
type: 'cron' | 'once';
|
|
28
28
|
expression: string;
|
|
29
29
|
description: string;
|
|
30
30
|
payload: string;
|
|
31
|
-
agent?:
|
|
31
|
+
agent?: 'opencode' | 'claude';
|
|
32
32
|
model?: string;
|
|
33
33
|
createdAt: string;
|
|
34
34
|
}
|
|
@@ -40,10 +40,10 @@ function loadAllSchedules(): Schedule[] {
|
|
|
40
40
|
try {
|
|
41
41
|
if (!existsSync(remindersDir)) return schedules;
|
|
42
42
|
|
|
43
|
-
const files = readdirSync(remindersDir).filter((f) => f.endsWith(
|
|
43
|
+
const files = readdirSync(remindersDir).filter((f) => f.endsWith('.json'));
|
|
44
44
|
for (const file of files) {
|
|
45
45
|
try {
|
|
46
|
-
const content = readFileSync(join(remindersDir, file),
|
|
46
|
+
const content = readFileSync(join(remindersDir, file), 'utf-8');
|
|
47
47
|
schedules.push(JSON.parse(content));
|
|
48
48
|
} catch {
|
|
49
49
|
// Skip malformed files
|
|
@@ -84,10 +84,10 @@ function deleteScheduleFile(id: string): boolean {
|
|
|
84
84
|
|
|
85
85
|
export const logJournalTool = tool({
|
|
86
86
|
description:
|
|
87
|
-
|
|
87
|
+
'Write a journal entry. Use this to record observations, decisions, or things to remember.',
|
|
88
88
|
args: {
|
|
89
|
-
topic: tool.schema.string().describe(
|
|
90
|
-
content: tool.schema.string().describe(
|
|
89
|
+
topic: tool.schema.string().describe('Short topic/category for the entry'),
|
|
90
|
+
content: tool.schema.string().describe('The journal entry content'),
|
|
91
91
|
agentIntent: tool.schema.string().optional().describe("Optional: why you're logging this"),
|
|
92
92
|
},
|
|
93
93
|
async execute(args) {
|
|
@@ -96,7 +96,7 @@ export const logJournalTool = tool({
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
await logJournal(args.topic, args.content, {
|
|
99
|
-
source:
|
|
99
|
+
source: 'opencode-tool',
|
|
100
100
|
intent: args.agentIntent,
|
|
101
101
|
});
|
|
102
102
|
|
|
@@ -105,9 +105,9 @@ export const logJournalTool = tool({
|
|
|
105
105
|
});
|
|
106
106
|
|
|
107
107
|
export const getRecentJournalTool = tool({
|
|
108
|
-
description:
|
|
108
|
+
description: 'Retrieve recent journal entries for context',
|
|
109
109
|
args: {
|
|
110
|
-
count: tool.schema.number().optional().describe(
|
|
110
|
+
count: tool.schema.number().optional().describe('Number of entries to retrieve (default: 40)'),
|
|
111
111
|
},
|
|
112
112
|
async execute(args) {
|
|
113
113
|
const entries = getRecentJournal(args.count || 40);
|
|
@@ -118,21 +118,21 @@ export const getRecentJournalTool = tool({
|
|
|
118
118
|
// --- Summary Tools ---
|
|
119
119
|
|
|
120
120
|
export const saveConversationSummaryTool = tool({
|
|
121
|
-
description:
|
|
121
|
+
description: 'Save a summary of the current conversation for context recovery in future sessions',
|
|
122
122
|
args: {
|
|
123
|
-
summary: tool.schema.string().describe(
|
|
123
|
+
summary: tool.schema.string().describe('Brief summary of what was discussed/accomplished'),
|
|
124
124
|
keyDecisions: tool.schema
|
|
125
125
|
.array(tool.schema.string())
|
|
126
126
|
.optional()
|
|
127
|
-
.describe(
|
|
127
|
+
.describe('Important decisions made'),
|
|
128
128
|
openThreads: tool.schema
|
|
129
129
|
.array(tool.schema.string())
|
|
130
130
|
.optional()
|
|
131
|
-
.describe(
|
|
131
|
+
.describe('Topics to follow up on'),
|
|
132
132
|
learnedPatterns: tool.schema
|
|
133
133
|
.array(tool.schema.string())
|
|
134
134
|
.optional()
|
|
135
|
-
.describe(
|
|
135
|
+
.describe('New patterns learned about the user'),
|
|
136
136
|
notes: tool.schema
|
|
137
137
|
.string()
|
|
138
138
|
.optional()
|
|
@@ -151,14 +151,14 @@ export const saveConversationSummaryTool = tool({
|
|
|
151
151
|
notes: args.notes,
|
|
152
152
|
});
|
|
153
153
|
|
|
154
|
-
return JSON.stringify({ success: true, message:
|
|
154
|
+
return JSON.stringify({ success: true, message: 'Conversation summary saved' });
|
|
155
155
|
},
|
|
156
156
|
});
|
|
157
157
|
|
|
158
158
|
export const getRecentSummariesTool = tool({
|
|
159
|
-
description:
|
|
159
|
+
description: 'Get recent conversation summaries for context recovery',
|
|
160
160
|
args: {
|
|
161
|
-
count: tool.schema.number().optional().describe(
|
|
161
|
+
count: tool.schema.number().optional().describe('Number of summaries to retrieve (default: 7)'),
|
|
162
162
|
},
|
|
163
163
|
async execute(args) {
|
|
164
164
|
const summaries = getRecentSummaries(args.count || 7);
|
|
@@ -170,15 +170,15 @@ export const getRecentSummariesTool = tool({
|
|
|
170
170
|
|
|
171
171
|
export const searchMemoryTool = tool({
|
|
172
172
|
description:
|
|
173
|
-
|
|
173
|
+
'Semantic search over your history - journal, state files, projects, people. Use to find relevant context.',
|
|
174
174
|
args: {
|
|
175
|
-
query: tool.schema.string().describe(
|
|
175
|
+
query: tool.schema.string().describe('Natural language query to search for'),
|
|
176
176
|
type: tool.schema
|
|
177
|
-
.enum([
|
|
177
|
+
.enum(['journal', 'state', 'project', 'person', 'meeting', 'topic'])
|
|
178
178
|
.optional()
|
|
179
|
-
.describe(
|
|
180
|
-
limit: tool.schema.number().optional().describe(
|
|
181
|
-
since: tool.schema.string().optional().describe(
|
|
179
|
+
.describe('Filter by content type'),
|
|
180
|
+
limit: tool.schema.number().optional().describe('Maximum results to return (default: 5)'),
|
|
181
|
+
since: tool.schema.string().optional().describe('Only include items after this ISO date'),
|
|
182
182
|
},
|
|
183
183
|
async execute(args) {
|
|
184
184
|
if (!args.query) {
|
|
@@ -194,7 +194,7 @@ export const searchMemoryTool = tool({
|
|
|
194
194
|
if (results.length === 0) {
|
|
195
195
|
return JSON.stringify({
|
|
196
196
|
success: true,
|
|
197
|
-
message:
|
|
197
|
+
message: 'No matches found. Try rebuilding the index with rebuild_memory_index',
|
|
198
198
|
results: [],
|
|
199
199
|
});
|
|
200
200
|
}
|
|
@@ -214,11 +214,11 @@ export const searchMemoryTool = tool({
|
|
|
214
214
|
});
|
|
215
215
|
|
|
216
216
|
export const searchConversationsTool = tool({
|
|
217
|
-
description:
|
|
217
|
+
description: 'Search past OpenCode sessions',
|
|
218
218
|
args: {
|
|
219
|
-
query: tool.schema.string().describe(
|
|
220
|
-
projectOnly: tool.schema.boolean().optional().describe(
|
|
221
|
-
limit: tool.schema.number().optional().describe(
|
|
219
|
+
query: tool.schema.string().describe('Natural language query to search for'),
|
|
220
|
+
projectOnly: tool.schema.boolean().optional().describe('Only search current project'),
|
|
221
|
+
limit: tool.schema.number().optional().describe('Maximum results to return (default: 5)'),
|
|
222
222
|
},
|
|
223
223
|
async execute(args) {
|
|
224
224
|
if (!args.query) {
|
|
@@ -234,7 +234,7 @@ export const searchConversationsTool = tool({
|
|
|
234
234
|
if (results.length === 0) {
|
|
235
235
|
return JSON.stringify({
|
|
236
236
|
success: true,
|
|
237
|
-
message:
|
|
237
|
+
message: 'No matching conversations. Try rebuilding with rebuild_memory_index',
|
|
238
238
|
results: [],
|
|
239
239
|
});
|
|
240
240
|
}
|
|
@@ -258,7 +258,7 @@ export const searchConversationsTool = tool({
|
|
|
258
258
|
|
|
259
259
|
export const rebuildMemoryIndexTool = tool({
|
|
260
260
|
description:
|
|
261
|
-
|
|
261
|
+
'Rebuild the semantic search index from scratch. Use if index seems stale or corrupted.',
|
|
262
262
|
args: {},
|
|
263
263
|
async execute() {
|
|
264
264
|
// Rebuild memory index synchronously (fast)
|
|
@@ -272,7 +272,7 @@ export const rebuildMemoryIndexTool = tool({
|
|
|
272
272
|
|
|
273
273
|
return JSON.stringify({
|
|
274
274
|
success: true,
|
|
275
|
-
message:
|
|
275
|
+
message: 'Memory index rebuilt. Conversation index rebuilding in background.',
|
|
276
276
|
stats: {
|
|
277
277
|
memoryItems: memoryStats.itemCount,
|
|
278
278
|
},
|
|
@@ -281,7 +281,7 @@ export const rebuildMemoryIndexTool = tool({
|
|
|
281
281
|
});
|
|
282
282
|
|
|
283
283
|
export const getMemoryIndexStatsTool = tool({
|
|
284
|
-
description:
|
|
284
|
+
description: 'Get statistics about the memory index',
|
|
285
285
|
args: {},
|
|
286
286
|
async execute() {
|
|
287
287
|
const memoryStats = await getMemoryIndexStats();
|
|
@@ -301,17 +301,17 @@ export const scheduleReminderTool = tool({
|
|
|
301
301
|
description:
|
|
302
302
|
"Schedule a recurring reminder using cron syntax. Examples: '0 9 * * *' = 9am daily, '0 */2 * * *' = every 2 hours. IMPORTANT: Check the current time before using this tool to ensure accurate scheduling.",
|
|
303
303
|
args: {
|
|
304
|
-
id: tool.schema.string().describe(
|
|
304
|
+
id: tool.schema.string().describe('Unique reminder identifier'),
|
|
305
305
|
cronExpression: tool.schema
|
|
306
306
|
.string()
|
|
307
307
|
.describe("Cron expression (e.g., '0 9 * * *' for 9am daily)"),
|
|
308
|
-
description: tool.schema.string().describe(
|
|
309
|
-
payload: tool.schema.string().describe(
|
|
308
|
+
description: tool.schema.string().describe('What this reminder is for'),
|
|
309
|
+
payload: tool.schema.string().describe('Message to process when reminder fires'),
|
|
310
310
|
model: tool.schema
|
|
311
311
|
.string()
|
|
312
312
|
.optional()
|
|
313
313
|
.describe(
|
|
314
|
-
|
|
314
|
+
'Model to use for this reminder (see macrodata-models in context for available options)',
|
|
315
315
|
),
|
|
316
316
|
},
|
|
317
317
|
async execute(args) {
|
|
@@ -324,11 +324,11 @@ export const scheduleReminderTool = tool({
|
|
|
324
324
|
|
|
325
325
|
const schedule: Schedule = {
|
|
326
326
|
id: args.id,
|
|
327
|
-
type:
|
|
327
|
+
type: 'cron',
|
|
328
328
|
expression: args.cronExpression,
|
|
329
329
|
description: args.description,
|
|
330
330
|
payload: args.payload,
|
|
331
|
-
agent:
|
|
331
|
+
agent: 'opencode',
|
|
332
332
|
model: args.model,
|
|
333
333
|
createdAt: new Date().toISOString(),
|
|
334
334
|
};
|
|
@@ -337,24 +337,24 @@ export const scheduleReminderTool = tool({
|
|
|
337
337
|
|
|
338
338
|
return JSON.stringify({
|
|
339
339
|
success: true,
|
|
340
|
-
message: `Created recurring reminder: ${args.id} (${args.cronExpression})${args.model ? ` with model ${args.model}` :
|
|
340
|
+
message: `Created recurring reminder: ${args.id} (${args.cronExpression})${args.model ? ` with model ${args.model}` : ''}`,
|
|
341
341
|
});
|
|
342
342
|
},
|
|
343
343
|
});
|
|
344
344
|
|
|
345
345
|
export const scheduleOnceTool = tool({
|
|
346
346
|
description:
|
|
347
|
-
|
|
347
|
+
'Schedule a one-shot reminder at a specific date/time. The reminder fires once and is automatically removed. IMPORTANT: Check the current time before using this tool to ensure accurate scheduling.',
|
|
348
348
|
args: {
|
|
349
|
-
id: tool.schema.string().describe(
|
|
349
|
+
id: tool.schema.string().describe('Unique reminder identifier'),
|
|
350
350
|
datetime: tool.schema.string().describe("ISO 8601 datetime (e.g., '2026-01-06T10:00:00')"),
|
|
351
|
-
description: tool.schema.string().describe(
|
|
352
|
-
payload: tool.schema.string().describe(
|
|
351
|
+
description: tool.schema.string().describe('What this reminder is for'),
|
|
352
|
+
payload: tool.schema.string().describe('Message to process when reminder fires'),
|
|
353
353
|
model: tool.schema
|
|
354
354
|
.string()
|
|
355
355
|
.optional()
|
|
356
356
|
.describe(
|
|
357
|
-
|
|
357
|
+
'Model to use for this reminder (see macrodata-models in context for available options)',
|
|
358
358
|
),
|
|
359
359
|
},
|
|
360
360
|
async execute(args) {
|
|
@@ -367,11 +367,11 @@ export const scheduleOnceTool = tool({
|
|
|
367
367
|
|
|
368
368
|
const schedule: Schedule = {
|
|
369
369
|
id: args.id,
|
|
370
|
-
type:
|
|
370
|
+
type: 'once',
|
|
371
371
|
expression: args.datetime,
|
|
372
372
|
description: args.description,
|
|
373
373
|
payload: args.payload,
|
|
374
|
-
agent:
|
|
374
|
+
agent: 'opencode',
|
|
375
375
|
model: args.model,
|
|
376
376
|
createdAt: new Date().toISOString(),
|
|
377
377
|
};
|
|
@@ -380,15 +380,15 @@ export const scheduleOnceTool = tool({
|
|
|
380
380
|
|
|
381
381
|
return JSON.stringify({
|
|
382
382
|
success: true,
|
|
383
|
-
message: `Scheduled one-shot reminder: ${args.id} at ${args.datetime}${args.model ? ` with model ${args.model}` :
|
|
383
|
+
message: `Scheduled one-shot reminder: ${args.id} at ${args.datetime}${args.model ? ` with model ${args.model}` : ''}`,
|
|
384
384
|
});
|
|
385
385
|
},
|
|
386
386
|
});
|
|
387
387
|
|
|
388
388
|
export const removeReminderTool = tool({
|
|
389
|
-
description:
|
|
389
|
+
description: 'Remove a scheduled reminder',
|
|
390
390
|
args: {
|
|
391
|
-
id: tool.schema.string().describe(
|
|
391
|
+
id: tool.schema.string().describe('Reminder ID to remove'),
|
|
392
392
|
},
|
|
393
393
|
async execute(args) {
|
|
394
394
|
if (!args.id) {
|
|
@@ -405,7 +405,7 @@ export const removeReminderTool = tool({
|
|
|
405
405
|
});
|
|
406
406
|
|
|
407
407
|
export const listRemindersTool = tool({
|
|
408
|
-
description:
|
|
408
|
+
description: 'List all scheduled reminders',
|
|
409
409
|
args: {},
|
|
410
410
|
async execute() {
|
|
411
411
|
const schedules = loadAllSchedules();
|
|
@@ -417,9 +417,9 @@ export const listRemindersTool = tool({
|
|
|
417
417
|
|
|
418
418
|
export const getRelatedTool = tool({
|
|
419
419
|
description:
|
|
420
|
-
|
|
420
|
+
'Get entries related to a specific memory item. Useful for exploring associative connections in your memory.',
|
|
421
421
|
args: {
|
|
422
|
-
id: tool.schema.string().describe(
|
|
422
|
+
id: tool.schema.string().describe('The ID of the memory item to find related entries for'),
|
|
423
423
|
},
|
|
424
424
|
async execute(args) {
|
|
425
425
|
if (!args.id) {
|
|
@@ -429,7 +429,7 @@ export const getRelatedTool = tool({
|
|
|
429
429
|
// TODO: Implement related items lookup
|
|
430
430
|
return JSON.stringify({
|
|
431
431
|
success: true,
|
|
432
|
-
message:
|
|
432
|
+
message: 'Related items feature not yet implemented',
|
|
433
433
|
related: [],
|
|
434
434
|
});
|
|
435
435
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geoql/mdr",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Persistent layered memory for coding agents (OpenCode, Claude Code) — journal, entities, state files, semantic search, daemon, scheduled reminders. A hard fork of ascorbic/macrodata by Matt Kane.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|
|
31
31
|
"url": "git+https://github.com/geoql/mdr.git",
|
|
32
|
-
"directory": "
|
|
32
|
+
"directory": "packages/macrodata"
|
|
33
33
|
},
|
|
34
34
|
"files": [
|
|
35
35
|
"dist",
|
|
@@ -44,19 +44,6 @@
|
|
|
44
44
|
"publishConfig": {
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
|
-
"scripts": {
|
|
48
|
-
"build": "tsdown",
|
|
49
|
-
"prepublishOnly": "pnpm build",
|
|
50
|
-
"start": "node dist/src/index.js",
|
|
51
|
-
"daemon": "node dist/bin/macrodata-daemon.js",
|
|
52
|
-
"pretest": "pnpm build",
|
|
53
|
-
"test": "vitest run",
|
|
54
|
-
"check": "oxlint --type-aware --type-check",
|
|
55
|
-
"lint": "oxlint",
|
|
56
|
-
"lint:fix": "oxlint --fix",
|
|
57
|
-
"format": "oxfmt --write .",
|
|
58
|
-
"format:check": "oxfmt --check ."
|
|
59
|
-
},
|
|
60
47
|
"dependencies": {
|
|
61
48
|
"@huggingface/transformers": "^4.2.0",
|
|
62
49
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
@@ -69,10 +56,10 @@
|
|
|
69
56
|
},
|
|
70
57
|
"devDependencies": {
|
|
71
58
|
"@types/node": "^26.1.1",
|
|
72
|
-
"oxfmt": "
|
|
59
|
+
"oxfmt": "^0.58.0",
|
|
73
60
|
"oxlint": "^1.73.0",
|
|
74
61
|
"oxlint-tsgolint": "latest",
|
|
75
|
-
"
|
|
62
|
+
"vite-plus": "^0.2.4"
|
|
76
63
|
},
|
|
77
64
|
"engines": {
|
|
78
65
|
"node": ">=24.11.0"
|
|
@@ -83,5 +70,17 @@
|
|
|
83
70
|
"chat.message",
|
|
84
71
|
"experimental.session.compacting"
|
|
85
72
|
]
|
|
73
|
+
},
|
|
74
|
+
"scripts": {
|
|
75
|
+
"build": "vp pack",
|
|
76
|
+
"start": "node dist/src/index.js",
|
|
77
|
+
"daemon": "node dist/bin/macrodata-daemon.js",
|
|
78
|
+
"pretest": "pnpm build",
|
|
79
|
+
"test": "vitest run",
|
|
80
|
+
"check": "vp lint --type-aware --type-check",
|
|
81
|
+
"lint": "vp lint",
|
|
82
|
+
"lint:fix": "vp lint --fix",
|
|
83
|
+
"format": "vp fmt",
|
|
84
|
+
"format:check": "vp fmt --check"
|
|
86
85
|
}
|
|
87
|
-
}
|
|
86
|
+
}
|
package/src/config.ts
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* so that config changes take effect without restart.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { existsSync, readFileSync } from
|
|
9
|
-
import { homedir } from
|
|
10
|
-
import { join } from
|
|
8
|
+
import { existsSync, readFileSync } from 'fs';
|
|
9
|
+
import { homedir } from 'os';
|
|
10
|
+
import { join } from 'path';
|
|
11
11
|
|
|
12
|
-
const DEFAULT_ROOT = join(homedir(),
|
|
12
|
+
const DEFAULT_ROOT = join(homedir(), '.config', 'macrodata');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Get the macrodata state root directory.
|
|
@@ -24,10 +24,10 @@ export function getStateRoot(): string {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// Check config file in default location
|
|
27
|
-
const configPath = join(DEFAULT_ROOT,
|
|
27
|
+
const configPath = join(DEFAULT_ROOT, 'config.json');
|
|
28
28
|
if (existsSync(configPath)) {
|
|
29
29
|
try {
|
|
30
|
-
const config = JSON.parse(readFileSync(configPath,
|
|
30
|
+
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
31
31
|
if (config.root) return config.root;
|
|
32
32
|
} catch {
|
|
33
33
|
// Ignore parse errors
|
|
@@ -38,29 +38,29 @@ export function getStateRoot(): string {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
export function getStateDir(): string {
|
|
41
|
-
return join(getStateRoot(),
|
|
41
|
+
return join(getStateRoot(), 'state');
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
export function getEntitiesDir(): string {
|
|
45
|
-
return join(getStateRoot(),
|
|
45
|
+
return join(getStateRoot(), 'entities');
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
export function getJournalDir(): string {
|
|
49
|
-
return join(getStateRoot(),
|
|
49
|
+
return join(getStateRoot(), 'journal');
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export function getSignalsDir(): string {
|
|
53
|
-
return join(getStateRoot(),
|
|
53
|
+
return join(getStateRoot(), 'signals');
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
export function getIndexDir(): string {
|
|
57
|
-
return join(getStateRoot(),
|
|
57
|
+
return join(getStateRoot(), '.index');
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export function getTopicsDir(): string {
|
|
61
|
-
return join(getStateRoot(),
|
|
61
|
+
return join(getStateRoot(), 'topics');
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
export function getRemindersDir(): string {
|
|
65
|
-
return join(getStateRoot(),
|
|
65
|
+
return join(getStateRoot(), 'reminders');
|
|
66
66
|
}
|