dotmd-cli 0.39.7 → 0.39.9
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 +32 -11
- package/package.json +1 -1
- package/src/hud.mjs +5 -2
- package/src/index.mjs +21 -13
- package/src/prompts.mjs +5 -1
package/bin/dotmd.mjs
CHANGED
|
@@ -581,10 +581,16 @@ Types and their default destinations:
|
|
|
581
581
|
\`<name>\` is slugified for the filename.
|
|
582
582
|
|
|
583
583
|
Body input (all built-in types — required for prompt, optional for plan/doc):
|
|
584
|
-
|
|
585
|
-
--message "<text>" Explicit inline body
|
|
584
|
+
@path Read body from a file (preferred for multi-line bodies)
|
|
586
585
|
- Read body from stdin (heredoc-friendly for agents)
|
|
587
|
-
|
|
586
|
+
--message "<text>" Explicit inline body
|
|
587
|
+
<text> Inline body as 3rd positional
|
|
588
|
+
|
|
589
|
+
Tip for agents: prefer \`@path\` or \`-\` for multi-line bodies. Inline bodies
|
|
590
|
+
put the entire content on the bash command line, which (a) breaks under shell
|
|
591
|
+
quoting for backticks/dollar-signs and (b) trips PreToolUse hooks that scan
|
|
592
|
+
command strings for forbidden literals (destructive-git patterns, etc.).
|
|
593
|
+
\`@/tmp/foo.md\` sidesteps both.
|
|
588
594
|
|
|
589
595
|
For plan/doc, a single-section body lands under the type's first scaffolded
|
|
590
596
|
section (e.g. \`## Problem\` for plans). If the body already authors
|
|
@@ -594,19 +600,19 @@ the title + your body is emitted — no duplicated empty outline below
|
|
|
594
600
|
|
|
595
601
|
Examples:
|
|
596
602
|
dotmd new plan auth-revamp
|
|
597
|
-
dotmd new
|
|
603
|
+
dotmd new prompt resume-foo @/tmp/draft.md
|
|
604
|
+
dotmd new prompt resume-foo - <<'EOF'
|
|
605
|
+
multi-line
|
|
606
|
+
prompt body
|
|
607
|
+
EOF
|
|
608
|
+
dotmd new prompt cleanup-tomorrow "look at remaining lint warnings"
|
|
598
609
|
dotmd new plan full-spec - <<'EOF'
|
|
599
610
|
## Problem
|
|
600
611
|
…
|
|
601
612
|
## Phases
|
|
602
613
|
…
|
|
603
614
|
EOF
|
|
604
|
-
dotmd new
|
|
605
|
-
dotmd new prompt resume-foo - <<'EOF'
|
|
606
|
-
multi-line
|
|
607
|
-
prompt body
|
|
608
|
-
EOF
|
|
609
|
-
dotmd new prompt from-file @/tmp/draft.md
|
|
615
|
+
dotmd new plan auth-revamp "Investigation findings before scoping…"
|
|
610
616
|
|
|
611
617
|
Other options:
|
|
612
618
|
--status <s> Set initial status (defaults to first valid status for the type)
|
|
@@ -754,12 +760,17 @@ Prompts are documents with \`type: prompt\`, typically saved under
|
|
|
754
760
|
docs/prompts/. They seed future Claude sessions; consuming a prompt
|
|
755
761
|
prints its body to stdout and atomically archives it (one-shot).
|
|
756
762
|
|
|
763
|
+
\`dotmd prompt\` (singular) is an alias for \`dotmd prompts\` — every
|
|
764
|
+
subcommand below works under either spelling.
|
|
765
|
+
|
|
757
766
|
Subcommands:
|
|
758
767
|
list List pending prompts (default)
|
|
759
768
|
next Consume the oldest pending prompt:
|
|
760
769
|
print body to stdout, flip status to archived
|
|
761
770
|
use <file-or-slug> Consume a specific prompt (same as next, but
|
|
762
771
|
targets the named prompt instead of picking oldest)
|
|
772
|
+
resume <file-or-slug> Alias for \`use\` — same behavior, easier name
|
|
773
|
+
when continuing a session
|
|
763
774
|
archive <file-or-slug> Archive a prompt without printing its body
|
|
764
775
|
shelve <file-or-slug> Park a prompt (status → shelved): kept in list,
|
|
765
776
|
hidden from hud/briefing pending surfaces, skipped
|
|
@@ -786,6 +797,8 @@ Examples:
|
|
|
786
797
|
claude "$(dotmd prompts next)" # consume oldest pending + run claude
|
|
787
798
|
claude "$(dotmd prompts use resume-foo)" # by slug
|
|
788
799
|
claude "$(dotmd prompts use docs/prompts/foo.md)" # by path
|
|
800
|
+
claude "$(dotmd prompts resume resume-foo)" # \`resume\` is an alias for \`use\`
|
|
801
|
+
dotmd prompt list # singular alias for \`dotmd prompts list\`
|
|
789
802
|
|
|
790
803
|
dotmd prompts next --dry-run # preview without consuming
|
|
791
804
|
dotmd prompts archive old-thing
|
|
@@ -958,7 +971,7 @@ the whole docs tree is scanned.`,
|
|
|
958
971
|
|
|
959
972
|
async function main() {
|
|
960
973
|
const args = process.argv.slice(2);
|
|
961
|
-
|
|
974
|
+
let command = args[0] ?? 'list';
|
|
962
975
|
|
|
963
976
|
// Pre-config flags
|
|
964
977
|
if (args.includes('--version') || args.includes('-v')) {
|
|
@@ -979,6 +992,14 @@ async function main() {
|
|
|
979
992
|
return;
|
|
980
993
|
}
|
|
981
994
|
|
|
995
|
+
// Singular-form alias for the prompts subcommand namespace. Trivial
|
|
996
|
+
// no-collision collapse — `prompt` was previously "unknown command", now
|
|
997
|
+
// routes everywhere `prompts` does (incl. per-command --help below, and the
|
|
998
|
+
// subcommand dispatch at the `prompts` branch in the chain). The other
|
|
999
|
+
// singular/plural pairs (`plan`/`plans`, `module`/`modules`,
|
|
1000
|
+
// `status`/`statuses`) are deliberately kept distinct — see F20 plan.
|
|
1001
|
+
if (command === 'prompt') command = 'prompts';
|
|
1002
|
+
|
|
982
1003
|
// Per-command help
|
|
983
1004
|
if (args.includes('--help') || args.includes('-h')) {
|
|
984
1005
|
process.stdout.write(`${HELP[command] ?? HELP._main}\n`);
|
package/package.json
CHANGED
package/src/hud.mjs
CHANGED
|
@@ -76,10 +76,13 @@ export function buildHud(config) {
|
|
|
76
76
|
// Validation error count — hud's "silent when clean" contract should treat
|
|
77
77
|
// `check` errors as not-clean. Without this, a SessionStart hook firing hud
|
|
78
78
|
// can leave the agent with no visible signal that a check is failing.
|
|
79
|
-
//
|
|
79
|
+
// `errorsOnly: true` skips warning-only cross-doc passes (git staleness,
|
|
80
|
+
// bidirectional refs, claude-commands) that hud never reads — ~6× faster on
|
|
81
|
+
// SessionStart for platform-scale corpora. Per-file validation + checkIndex
|
|
82
|
+
// still run, so the error count matches `dotmd check`'s.
|
|
80
83
|
let errors = 0;
|
|
81
84
|
try {
|
|
82
|
-
const index = buildIndex(config);
|
|
85
|
+
const index = buildIndex(config, { errorsOnly: true });
|
|
83
86
|
errors = index.errors.length;
|
|
84
87
|
} catch { /* swallow — bad config shouldn't break the SessionStart hook */ }
|
|
85
88
|
|
package/src/index.mjs
CHANGED
|
@@ -7,14 +7,22 @@ import { validateDoc, validatePlanShape, validateDocShape, checkBidirectionalRef
|
|
|
7
7
|
import { checkIndex } from './index-file.mjs';
|
|
8
8
|
import { checkClaudeCommands } from './claude-commands.mjs';
|
|
9
9
|
|
|
10
|
-
// `fast: true` skips every pass that
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
10
|
+
// `fast: true` skips every pass that produces warnings/errors — the rendered
|
|
11
|
+
// index file consumes only status/title/snapshot/etc., not the validation
|
|
12
|
+
// output. Use it from `regenIndex` (post-mutation index refresh) where
|
|
13
|
+
// validation has already run elsewhere (or will, next time the user runs
|
|
14
|
+
// `dotmd check`). Saves the full-repo `git log` scan in `checkGitStaleness`
|
|
15
|
+
// plus the bidirectional ref walk + claude-commands check.
|
|
16
|
+
//
|
|
17
|
+
// `errorsOnly: true` runs every error-producing pass (per-file `validateDoc`,
|
|
18
|
+
// `checkIndex`, the `validate` hook) but skips the warning-only cross-doc
|
|
19
|
+
// passes (bidirectional refs, runlist back-pointers, git staleness, claude
|
|
20
|
+
// commands). Use it from `dotmd hud` — the SessionStart hook only renders the
|
|
21
|
+
// error COUNT, so the warning-only passes are pure overhead there. Preserves
|
|
22
|
+
// the invariant that hud's "✗ N validation errors" line matches `dotmd check`.
|
|
16
23
|
export function buildIndex(config, opts = {}) {
|
|
17
|
-
const { fast = false } = opts;
|
|
24
|
+
const { fast = false, errorsOnly = false } = opts;
|
|
25
|
+
const skipWarningOnlyChecks = fast || errorsOnly;
|
|
18
26
|
const docs = collectDocFiles(config).map(f => parseDocFile(f, config, { fast }));
|
|
19
27
|
if (!fast) {
|
|
20
28
|
// Per-file validation (validateDoc) ran during parse without sibling
|
|
@@ -86,13 +94,13 @@ export function buildIndex(config, opts = {}) {
|
|
|
86
94
|
countsByType[type][doc.status] = (countsByType[type][doc.status] ?? 0) + 1;
|
|
87
95
|
}
|
|
88
96
|
|
|
89
|
-
if (!fast) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
97
|
+
if (!fast && config.indexPath) {
|
|
98
|
+
const indexCheck = checkIndex(transformedDocs, config);
|
|
99
|
+
warnings.push(...indexCheck.warnings);
|
|
100
|
+
errors.push(...indexCheck.errors);
|
|
101
|
+
}
|
|
95
102
|
|
|
103
|
+
if (!skipWarningOnlyChecks) {
|
|
96
104
|
const refCheck = checkBidirectionalReferences(transformedDocs, config);
|
|
97
105
|
warnings.push(...refCheck.warnings);
|
|
98
106
|
|
package/src/prompts.mjs
CHANGED
|
@@ -8,7 +8,10 @@ import { runArchive, runStatus } from './lifecycle.mjs';
|
|
|
8
8
|
import { runNew } from './new.mjs';
|
|
9
9
|
import { green, dim } from './color.mjs';
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
// `resume` is an alias for `use` — agents reach for "resume" when continuing a
|
|
12
|
+
// session; `use` reads as internal mechanics. Both names stay valid; the
|
|
13
|
+
// canonical output ("Consumed: …") is unchanged.
|
|
14
|
+
const SUBCOMMANDS = new Set(['list', 'next', 'use', 'resume', 'archive', 'new', 'shelve', 'unshelve']);
|
|
12
15
|
|
|
13
16
|
export async function runPrompts(argv, config, opts = {}) {
|
|
14
17
|
const sub = argv[0];
|
|
@@ -22,6 +25,7 @@ export async function runPrompts(argv, config, opts = {}) {
|
|
|
22
25
|
case 'list': return runPromptsList(rest, config, opts);
|
|
23
26
|
case 'next': return runPromptsNext(rest, config, opts);
|
|
24
27
|
case 'use': return runPromptsUse(rest, config, opts);
|
|
28
|
+
case 'resume': return runPromptsUse(rest, config, opts);
|
|
25
29
|
case 'archive': return runPromptsArchive(rest, config, opts);
|
|
26
30
|
case 'new': return runPromptsNew(rest, config, opts);
|
|
27
31
|
case 'shelve': return runPromptsShelve(rest, config, opts);
|