dotmd-cli 0.58.0 → 0.59.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/bin/dotmd.mjs CHANGED
@@ -507,11 +507,16 @@ Options:
507
507
  --json Output errors and warnings as JSON (always full detail)
508
508
  --dry-run, -n Preview fixes without writing (with --fix)`,
509
509
 
510
- archive: `dotmd archive <file> — archive a document
510
+ archive: `dotmd archive <file-or-slug> — archive a document
511
511
 
512
512
  Sets status to 'archived', moves to the archive directory, auto-updates
513
513
  references in other docs, and regenerates the index.
514
514
 
515
+ <file-or-slug> resolves like \`dotmd use\`: an exact path wins, but a bare
516
+ slug / basename (e.g. \`archive resume-foo\`) falls back to a recursive
517
+ basename match under the doc roots. An ambiguous basename (the same name in
518
+ two places) errors with the candidate list instead of guessing.
519
+
515
520
  Options:
516
521
  --no-index Skip index regen. Use when multiple sessions are
517
522
  working concurrently and you want a path-limited
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dotmd-cli",
3
- "version": "0.58.0",
3
+ "version": "0.59.0",
4
4
  "description": "CLI for managing markdown documents with YAML frontmatter — index, query, validate, graph, export, Notion sync, AI summaries.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/lifecycle.mjs CHANGED
@@ -15,6 +15,29 @@ function findFileRoot(filePath, config) {
15
15
  return roots.find(r => filePath.startsWith(r + '/')) ?? config.docsRoot;
16
16
  }
17
17
 
18
+ // Resolve an archive target like `dotmd use` resolves a pickup target: an exact
19
+ // path wins (the resolveDocPath fast path), but a bare slug / basename falls
20
+ // back to a recursive basename match under the doc roots. Mirrors
21
+ // resolvePromptInput's basename pass so the closure verb is as forgiving about
22
+ // naming as `use`/`prompts archive`. A basename shared by two files errors with
23
+ // the candidate list rather than guessing which one to move.
24
+ function resolveArchiveTarget(input, config) {
25
+ const direct = resolveDocPath(input, config);
26
+ if (direct) return direct;
27
+ if (!input.endsWith('.md')) {
28
+ const withExt = resolveDocPath(input + '.md', config);
29
+ if (withExt) return withExt;
30
+ }
31
+
32
+ const slug = input.replace(/\.md$/, '');
33
+ const byBasename = collectDocFiles(config).filter(f => path.basename(f, '.md') === slug);
34
+ if (byBasename.length === 1) return byBasename[0];
35
+ if (byBasename.length > 1) {
36
+ die(`Multiple docs match "${input}" by basename:\n${byBasename.map(f => ' ' + toRepoPath(f, config.repoRoot)).join('\n')}`);
37
+ }
38
+ return null;
39
+ }
40
+
18
41
  function defaultTypeDir(docType, config) {
19
42
  if (docType === 'plan') return 'plans';
20
43
  if (docType === 'prompt') return 'prompts';
@@ -401,7 +424,7 @@ export function runArchive(argv, config, opts = {}) {
401
424
 
402
425
  if (!input) { die('Usage: dotmd archive <file>'); }
403
426
 
404
- const filePath = resolveDocPath(input, config);
427
+ const filePath = resolveArchiveTarget(input, config);
405
428
  if (!filePath) { die(`File not found: ${input}\nSearched: ${toRepoPath(config.repoRoot, config.repoRoot) || '.'}, ${toRepoPath(config.docsRoot, config.repoRoot)}`); }
406
429
 
407
430
  const archiveFileRoot = findFileRoot(filePath, config);