dotmd-cli 0.29.1 → 0.29.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/new.mjs +21 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dotmd-cli",
3
- "version": "0.29.1",
3
+ "version": "0.29.2",
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/new.mjs CHANGED
@@ -128,6 +128,7 @@ Status markers (put in heading text):
128
128
  targetRoot: 'prompts',
129
129
  defaultStatus: 'pending',
130
130
  requiresBody: true,
131
+ acceptsBody: true,
131
132
  frontmatter: (s, d, ctx) => [
132
133
  'type: prompt',
133
134
  `status: ${s}`,
@@ -222,13 +223,31 @@ export async function runNew(argv, config, opts = {}) {
222
223
 
223
224
  // Body input resolution: messageFlag > bodyArg > nothing
224
225
  let bodyInput = null;
225
- if (messageFlag !== null) bodyInput = readBodyInput(messageFlag);
226
- else if (bodyArg !== null) bodyInput = readBodyInput(bodyArg);
226
+ let bodyInputSource = null;
227
+ if (messageFlag !== null) { bodyInput = readBodyInput(messageFlag); bodyInputSource = '--message'; }
228
+ else if (bodyArg !== null) {
229
+ bodyInput = readBodyInput(bodyArg);
230
+ bodyInputSource = bodyArg === '-' ? 'stdin (`-`)' : (bodyArg.startsWith('@') ? `file (\`${bodyArg}\`)` : 'inline body argument');
231
+ }
227
232
 
228
233
  if (template.requiresBody && (!bodyInput || !bodyInput.trim())) {
229
234
  die(`\`${typeName}\` template requires a body. Pass inline, --message "...", - for stdin, or @path for a file.`);
230
235
  }
231
236
 
237
+ // Fail-fast when the user passes body input to a template that doesn't
238
+ // consume it — silently discarding heredoc content is the worst UX.
239
+ // Templates opt in via `acceptsBody: true` or `requiresBody: true`. Built-in
240
+ // `prompt` is the only template that consumes body by default.
241
+ if (bodyInput !== null && !template.acceptsBody && !template.requiresBody) {
242
+ const accepting = Object.entries(BUILTIN_TEMPLATES)
243
+ .filter(([, t]) => t.acceptsBody || t.requiresBody)
244
+ .map(([n]) => n);
245
+ const hint = accepting.length > 0
246
+ ? ` Templates that accept body input: ${accepting.join(', ')}.`
247
+ : '';
248
+ die(`\`${typeName}\` template does not accept body input, but body was passed via ${bodyInputSource}.${hint}\nEither drop the body, switch to a template that accepts it, or set \`acceptsBody: true\` on your custom \`${typeName}\` template in dotmd.config.mjs.`);
249
+ }
250
+
232
251
  // If name contains path separators, split into directory prefix and basename
233
252
  let nameDir = null;
234
253
  let namePart = name;