dotmd-cli 0.14.1 → 0.14.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/package.json +1 -1
- package/src/config.mjs +15 -3
- package/src/index.mjs +2 -1
- package/src/init.mjs +3 -2
- package/src/notion.mjs +2 -2
- package/src/query.mjs +1 -1
- package/src/render.mjs +1 -1
package/package.json
CHANGED
package/src/config.mjs
CHANGED
|
@@ -5,6 +5,16 @@ import { die, warn } from './util.mjs';
|
|
|
5
5
|
|
|
6
6
|
const CONFIG_FILENAMES = ['dotmd.config.mjs', '.dotmd.config.mjs', 'dotmd.config.js'];
|
|
7
7
|
|
|
8
|
+
// Keys where user config replaces defaults entirely (not deep-merged).
|
|
9
|
+
// These are flat maps or config sections where the user's version is authoritative —
|
|
10
|
+
// default keys that the user omitted should NOT survive the merge.
|
|
11
|
+
const REPLACE_KEYS = new Set([
|
|
12
|
+
'statuses.staleDays',
|
|
13
|
+
'statuses.rootStatuses',
|
|
14
|
+
'presets',
|
|
15
|
+
'context',
|
|
16
|
+
]);
|
|
17
|
+
|
|
8
18
|
const DEFAULTS = {
|
|
9
19
|
root: '.',
|
|
10
20
|
archiveDir: 'archived',
|
|
@@ -155,12 +165,14 @@ function validateConfig(userConfig, config, validStatuses, indexPath) {
|
|
|
155
165
|
return warnings;
|
|
156
166
|
}
|
|
157
167
|
|
|
158
|
-
function deepMerge(defaults, overrides) {
|
|
168
|
+
function deepMerge(defaults, overrides, parentPath = '') {
|
|
159
169
|
const result = { ...defaults };
|
|
160
170
|
for (const [key, value] of Object.entries(overrides)) {
|
|
171
|
+
const keyPath = parentPath ? `${parentPath}.${key}` : key;
|
|
161
172
|
if (value != null && typeof value === 'object' && !Array.isArray(value) &&
|
|
162
|
-
result[key] != null && typeof result[key] === 'object' && !Array.isArray(result[key])
|
|
163
|
-
|
|
173
|
+
result[key] != null && typeof result[key] === 'object' && !Array.isArray(result[key]) &&
|
|
174
|
+
!REPLACE_KEYS.has(keyPath)) {
|
|
175
|
+
result[key] = deepMerge(result[key], value, keyPath);
|
|
164
176
|
} else {
|
|
165
177
|
result[key] = value;
|
|
166
178
|
}
|
package/src/index.mjs
CHANGED
|
@@ -99,7 +99,8 @@ function walkMarkdownFiles(directory, files, excludedDirs, skipPaths, seen = new
|
|
|
99
99
|
let entries;
|
|
100
100
|
try {
|
|
101
101
|
entries = readdirSync(directory, { withFileTypes: true });
|
|
102
|
-
} catch {
|
|
102
|
+
} catch (err) {
|
|
103
|
+
warn(`Could not read directory ${directory}: ${err.message}`);
|
|
103
104
|
return;
|
|
104
105
|
}
|
|
105
106
|
for (const entry of entries) {
|
package/src/init.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { extractFrontmatter, parseSimpleFrontmatter } from './frontmatter.mjs';
|
|
4
4
|
import { green, dim } from './color.mjs';
|
|
5
|
+
import { warn } from './util.mjs';
|
|
5
6
|
import { scaffoldClaudeCommands } from './claude-commands.mjs';
|
|
6
7
|
|
|
7
8
|
const STARTER_CONFIG = `// dotmd.config.mjs — document management configuration
|
|
@@ -35,12 +36,12 @@ function scanExistingDocs(dir) {
|
|
|
35
36
|
|
|
36
37
|
function walk(d) {
|
|
37
38
|
let entries;
|
|
38
|
-
try { entries = readdirSync(d, { withFileTypes: true }); } catch { return; }
|
|
39
|
+
try { entries = readdirSync(d, { withFileTypes: true }); } catch (err) { warn(`Could not read ${d}: ${err.message}`); return; }
|
|
39
40
|
for (const entry of entries) {
|
|
40
41
|
if (entry.isDirectory()) { walk(path.join(d, entry.name)); continue; }
|
|
41
42
|
if (!entry.name.endsWith('.md')) continue;
|
|
42
43
|
let raw;
|
|
43
|
-
try { raw = readFileSync(path.join(d, entry.name), 'utf8'); } catch { continue; }
|
|
44
|
+
try { raw = readFileSync(path.join(d, entry.name), 'utf8'); } catch (err) { warn(`Could not read ${entry.name}: ${err.message}`); continue; }
|
|
44
45
|
const { frontmatter } = extractFrontmatter(raw);
|
|
45
46
|
if (!frontmatter) continue;
|
|
46
47
|
const parsed = parseSimpleFrontmatter(frontmatter);
|
package/src/notion.mjs
CHANGED
|
@@ -402,7 +402,7 @@ export async function runNotionSync(argv, config, opts = {}) {
|
|
|
402
402
|
try {
|
|
403
403
|
const mdBlocks = await n2m.pageToMarkdown(remote.page.id);
|
|
404
404
|
body = n2m.toMarkdownString(mdBlocks).parent ?? '';
|
|
405
|
-
} catch {
|
|
405
|
+
} catch (err) { warn(`Could not convert Notion page body for "${title}": ${err.message}`); }
|
|
406
406
|
|
|
407
407
|
const content = `---\n${serializeFrontmatter(fm)}\n---\n\n# ${title}\n\n${body}`;
|
|
408
408
|
const filePath = path.join(config.docsRoot, slug + '.md');
|
|
@@ -456,7 +456,7 @@ export async function runNotionSync(argv, config, opts = {}) {
|
|
|
456
456
|
try {
|
|
457
457
|
const mdBlocks = await n2m.pageToMarkdown(remote.page.id);
|
|
458
458
|
body = n2m.toMarkdownString(mdBlocks).parent ?? '';
|
|
459
|
-
} catch {
|
|
459
|
+
} catch (err) { warn(`Could not convert Notion page body for "${title}": ${err.message}`); }
|
|
460
460
|
|
|
461
461
|
const content = `---\n${serializeFrontmatter(fm)}\n---\n\n# ${title}\n\n${body}`;
|
|
462
462
|
const filePath = path.join(config.repoRoot, local.path);
|
package/src/query.mjs
CHANGED
|
@@ -157,7 +157,7 @@ function getDocSummary(doc, config) {
|
|
|
157
157
|
return config.hooks.summarizeDoc
|
|
158
158
|
? config.hooks.summarizeDoc(body, meta)
|
|
159
159
|
: summarizeDocBody(body, meta);
|
|
160
|
-
} catch { return null; }
|
|
160
|
+
} catch (err) { warn(`Could not summarize ${doc.path}: ${err.message}`); return null; }
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
function renderQueryResults(docs, filters, config) {
|
package/src/render.mjs
CHANGED
|
@@ -151,7 +151,7 @@ function _renderContextSection(docs, ctx, opts, config, lines) {
|
|
|
151
151
|
if (summary) {
|
|
152
152
|
lines.push(` ${''.padEnd(maxSlug)} ${dim('ai: ' + truncate(summary, 120))}`);
|
|
153
153
|
}
|
|
154
|
-
} catch {
|
|
154
|
+
} catch (err) { warn(`AI summary failed for ${doc.path}: ${err.message}`); }
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
lines.push('');
|