dotmd-cli 0.36.0 → 0.36.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dotmd-cli",
3
- "version": "0.36.0",
3
+ "version": "0.36.1",
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
@@ -1,7 +1,7 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { extractFrontmatter, parseSimpleFrontmatter, replaceFrontmatter } from './frontmatter.mjs';
4
- import { asString, toRepoPath, die, warn, resolveDocPath, resolveRefPath, escapeRegex, nowIso } from './util.mjs';
4
+ import { asString, toRepoPath, die, warn, resolveDocPath, resolveRefPath, escapeRegex, nowIso, suggestCandidates } from './util.mjs';
5
5
  import { gitMv, getGitLastModified, getGitLastModifiedBatch } from './git.mjs';
6
6
  import { buildIndex, collectDocFiles } from './index.mjs';
7
7
  import { renderIndexFile, writeIndex } from './index-file.mjs';
@@ -101,7 +101,11 @@ export async function runStatus(argv, config, opts = {}) {
101
101
  }
102
102
  }
103
103
 
104
- if (!effectiveValid.has(newStatus)) { die(`Invalid status: ${newStatus}\nValid: ${[...effectiveValid].join(', ')}`); }
104
+ if (!effectiveValid.has(newStatus)) {
105
+ const suggestions = suggestCandidates(newStatus, [...effectiveValid]);
106
+ const hint = suggestions.length ? `\nDid you mean: ${suggestions.join(', ')}?` : '';
107
+ die(`Invalid status: ${newStatus}\nValid: ${[...effectiveValid].join(', ')}${hint}`);
108
+ }
105
109
 
106
110
  const oldStatus = asString(parsedFm.status);
107
111
 
package/src/new.mjs CHANGED
@@ -69,14 +69,27 @@ ${ctx?.bodyInput?.trim() ?? ''}
69
69
  'current_state:',
70
70
  'next_step:',
71
71
  ].join('\n'),
72
- body: (t, ctx) => `
72
+ body: (t, ctx) => {
73
+ const bodyInput = ctx?.bodyInput?.trim() ?? '';
74
+ // Full-body shortcut: if the input already authors `## Section` headings,
75
+ // it's a complete plan body the user/agent wrote start-to-finish. Drop
76
+ // the scaffold's later sections to avoid duplicate empty `## Goals`,
77
+ // `## Phases`, etc. below the user's already-filled versions. A bare title
78
+ // (`# X`) at the head of the body is honored — we don't double-print the
79
+ // scaffold's title. Otherwise emit the scaffold and slot the body into
80
+ // `## Problem` as before (section-content mode).
81
+ if (/^##\s+\S/m.test(bodyInput)) {
82
+ const hasOwnTitle = /^#\s+\S/.test(bodyInput);
83
+ return hasOwnTitle ? `\n${bodyInput}\n` : `\n# ${t}\n\n${bodyInput}\n`;
84
+ }
85
+ return `
73
86
  # ${t}
74
87
 
75
88
  > One-paragraph problem statement: what this plan is for, why now.
76
89
 
77
90
  ## Problem
78
91
 
79
- ${ctx?.bodyInput?.trim() ?? ''}
92
+ ${bodyInput}
80
93
 
81
94
  ## Goals
82
95
 
@@ -128,7 +141,8 @@ Status markers (put in heading text):
128
141
  ## Closeout
129
142
 
130
143
  <!-- Filled on archive: what shipped, key commits, deferrals dispositioned. -->
131
- `,
144
+ `;
145
+ },
132
146
  },
133
147
  prompt: {
134
148
  description: 'Saved prompt to seed a future Claude session — body is required',