dotmd-cli 0.12.0 → 0.13.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 +2 -1
- package/bin/dotmd.mjs +31 -4
- package/package.json +1 -1
- package/src/completions.mjs +2 -1
- package/src/render.mjs +38 -0
package/README.md
CHANGED
|
@@ -113,7 +113,8 @@ dotmd coverage [--json] Metadata coverage report
|
|
|
113
113
|
dotmd stats [--json] Doc health dashboard
|
|
114
114
|
dotmd graph [--dot|--json] Visualize document relationships
|
|
115
115
|
dotmd deps [file] Dependency tree or overview
|
|
116
|
-
dotmd
|
|
116
|
+
dotmd briefing Compact summary for session start
|
|
117
|
+
dotmd context [--summarize] Full briefing (LLM-oriented)
|
|
117
118
|
dotmd focus [status] Detailed view for one status group
|
|
118
119
|
dotmd query [filters] Filtered search
|
|
119
120
|
dotmd plans List all plans
|
package/bin/dotmd.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { resolveConfig } from '../src/config.mjs';
|
|
7
7
|
import { buildIndex } from '../src/index.mjs';
|
|
8
|
-
import { renderCompactList, renderVerboseList, renderContext, renderCheck, renderCoverage, buildCoverage } from '../src/render.mjs';
|
|
8
|
+
import { renderCompactList, renderVerboseList, renderContext, renderBriefing, renderCheck, renderCoverage, buildCoverage } from '../src/render.mjs';
|
|
9
9
|
import { renderIndexFile, writeIndex } from '../src/index-file.mjs';
|
|
10
10
|
import { runFocus, runQuery } from '../src/query.mjs';
|
|
11
11
|
import { runStatus, runArchive, runTouch, runBulkArchive, runPickup, runFinish } from '../src/lifecycle.mjs';
|
|
@@ -39,7 +39,8 @@ const HELP = {
|
|
|
39
39
|
View & Query:
|
|
40
40
|
list [--verbose] [--json] List docs grouped by status (default command)
|
|
41
41
|
json Full index as JSON
|
|
42
|
-
|
|
42
|
+
briefing [--json] Compact summary for session start (5-10 lines)
|
|
43
|
+
context [--summarize] [--json] Full briefing (LLM-oriented)
|
|
43
44
|
focus [status] [--json] Detailed view for one status group
|
|
44
45
|
query [filters] [--json] Filtered search (--status, --keyword, --stale, etc.)
|
|
45
46
|
coverage [--json] Metadata coverage report
|
|
@@ -191,7 +192,15 @@ Shows detailed info for all docs matching the given status (default: active).
|
|
|
191
192
|
Options:
|
|
192
193
|
--json Output as JSON`,
|
|
193
194
|
|
|
194
|
-
|
|
195
|
+
briefing: `dotmd briefing — compact summary for session start
|
|
196
|
+
|
|
197
|
+
Shows plan statuses with next steps, doc/research counts, and health
|
|
198
|
+
in 5-10 lines. Designed for LLM context injection.
|
|
199
|
+
|
|
200
|
+
Options:
|
|
201
|
+
--json Output as JSON`,
|
|
202
|
+
|
|
203
|
+
context: `dotmd context — full briefing (LLM-oriented)
|
|
195
204
|
|
|
196
205
|
Generates a compact status briefing designed for AI/LLM consumption.
|
|
197
206
|
|
|
@@ -648,6 +657,24 @@ async function main() {
|
|
|
648
657
|
|
|
649
658
|
if (command === 'focus') { runFocus(index, restArgs, config); return; }
|
|
650
659
|
if (command === 'query') { runQuery(index, restArgs, config); return; }
|
|
660
|
+
if (command === 'briefing') {
|
|
661
|
+
if (args.includes('--json')) {
|
|
662
|
+
const plans = index.docs.filter(d => d.type === 'plan');
|
|
663
|
+
const docs = index.docs.filter(d => d.type === 'doc');
|
|
664
|
+
const research = index.docs.filter(d => d.type === 'research');
|
|
665
|
+
const stale = index.docs.filter(d => d.isStale && !config.lifecycle.skipStaleFor.has(d.status)).length;
|
|
666
|
+
process.stdout.write(JSON.stringify({
|
|
667
|
+
plans: { total: plans.length, inSession: plans.filter(d => d.status === 'in-session').map(d => ({ path: d.path, title: d.title, nextStep: d.nextStep })), active: plans.filter(d => d.status === 'active').map(d => ({ path: d.path, title: d.title, nextStep: d.nextStep })) },
|
|
668
|
+
docs: { total: docs.length, active: docs.filter(d => !config.lifecycle.terminalStatuses.has(d.status)).length },
|
|
669
|
+
research: { total: research.length, active: research.filter(d => d.status === 'active').length },
|
|
670
|
+
stale, errorCount: index.errors.length, warningCount: index.warnings.length,
|
|
671
|
+
}, null, 2) + '\n');
|
|
672
|
+
} else {
|
|
673
|
+
process.stdout.write(renderBriefing(index, config));
|
|
674
|
+
}
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
|
|
651
678
|
if (command === 'context') {
|
|
652
679
|
const summarize = args.includes('--summarize');
|
|
653
680
|
const modelIdx = args.indexOf('--model');
|
|
@@ -723,7 +750,7 @@ async function main() {
|
|
|
723
750
|
|
|
724
751
|
// Unknown command — suggest closest match
|
|
725
752
|
const allCommands = [
|
|
726
|
-
'list', 'json', 'check', 'coverage', 'stats', 'graph', 'deps', 'context',
|
|
753
|
+
'list', 'json', 'check', 'coverage', 'stats', 'graph', 'deps', 'briefing', 'context',
|
|
727
754
|
'focus', 'query', 'plans', 'stale', 'actionable', 'index', 'pickup', 'finish', 'status', 'archive', 'touch', 'doctor',
|
|
728
755
|
'fix-refs', 'lint', 'rename', 'migrate', 'notion', 'export', 'summary',
|
|
729
756
|
'watch', 'diff', 'new', 'init', 'completions',
|
package/package.json
CHANGED
package/src/completions.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { die } from './util.mjs';
|
|
2
2
|
|
|
3
3
|
const COMMANDS = [
|
|
4
|
-
'list', 'json', 'check', 'coverage', 'stats', 'graph', 'deps', 'unblocks', 'health', 'glossary', 'context', 'focus', 'query',
|
|
4
|
+
'list', 'json', 'check', 'coverage', 'stats', 'graph', 'deps', 'unblocks', 'health', 'glossary', 'briefing', 'context', 'focus', 'query',
|
|
5
5
|
'plans', 'stale', 'actionable', 'index', 'pickup', 'finish', 'status', 'archive', 'bulk', 'touch', 'doctor', 'lint', 'rename', 'migrate',
|
|
6
6
|
'fix-refs', 'notion', 'export', 'summary', 'watch', 'diff', 'init', 'new', 'completions',
|
|
7
7
|
];
|
|
@@ -32,6 +32,7 @@ const COMMAND_FLAGS = {
|
|
|
32
32
|
plans: ['--status', '--json', '--sort', '--limit', '--all', '--stale', '--has-next-step'],
|
|
33
33
|
stale: ['--json', '--sort', '--limit', '--all'],
|
|
34
34
|
actionable: ['--json', '--sort', '--limit', '--all'],
|
|
35
|
+
briefing: ['--json'],
|
|
35
36
|
pickup: ['--json'],
|
|
36
37
|
finish: ['--json'],
|
|
37
38
|
status: [],
|
package/src/render.mjs
CHANGED
|
@@ -258,6 +258,44 @@ function _renderContext(index, config, opts = {}) {
|
|
|
258
258
|
return `${lines.join('\n').trimEnd()}\n`;
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
+
export function renderBriefing(index, config) {
|
|
262
|
+
const lines = [];
|
|
263
|
+
const plans = index.docs.filter(d => d.type === 'plan');
|
|
264
|
+
const docs = index.docs.filter(d => d.type === 'doc');
|
|
265
|
+
const research = index.docs.filter(d => d.type === 'research');
|
|
266
|
+
const untyped = index.docs.filter(d => !d.type);
|
|
267
|
+
|
|
268
|
+
if (plans.length) {
|
|
269
|
+
const bySt = {};
|
|
270
|
+
for (const p of plans) { bySt[p.status] = (bySt[p.status] ?? 0) + 1; }
|
|
271
|
+
const counts = Object.entries(bySt).map(([s, n]) => `${n} ${s}`).join(', ');
|
|
272
|
+
lines.push(`${plans.length} plans: ${counts}`);
|
|
273
|
+
const show = plans.filter(p => p.status === 'in-session' || p.status === 'active');
|
|
274
|
+
for (const p of show) {
|
|
275
|
+
const next = p.nextStep ? `next: ${p.nextStep}` : '(no next step)';
|
|
276
|
+
lines.push(` > ${path.basename(p.path, '.md')} (${p.status}) ${next}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const parts = [];
|
|
281
|
+
if (docs.length) {
|
|
282
|
+
const active = docs.filter(d => !config.lifecycle.terminalStatuses.has(d.status)).length;
|
|
283
|
+
const rest = docs.length - active;
|
|
284
|
+
parts.push(`${active} docs active` + (rest ? `, ${rest} other` : ''));
|
|
285
|
+
}
|
|
286
|
+
if (research.length) {
|
|
287
|
+
const active = research.filter(d => d.status === 'active').length;
|
|
288
|
+
parts.push(`${active} research active`);
|
|
289
|
+
}
|
|
290
|
+
if (untyped.length) parts.push(`${untyped.length} untyped`);
|
|
291
|
+
if (parts.length) lines.push(parts.join(' | '));
|
|
292
|
+
|
|
293
|
+
const stale = index.docs.filter(d => d.isStale && !config.lifecycle.skipStaleFor.has(d.status)).length;
|
|
294
|
+
lines.push(`Stale: ${stale} | Errors: ${index.errors.length} | Warnings: ${index.warnings.length}`);
|
|
295
|
+
|
|
296
|
+
return lines.join('\n') + '\n';
|
|
297
|
+
}
|
|
298
|
+
|
|
261
299
|
export function renderCheck(index, config, opts = {}) {
|
|
262
300
|
const defaultRenderer = (idx) => _renderCheck(idx, opts);
|
|
263
301
|
if (config.hooks.renderCheck) {
|