dotmd-cli 0.85.0 → 0.86.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/hud.mjs +20 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dotmd-cli",
3
- "version": "0.85.0",
3
+ "version": "0.86.0",
4
4
  "description": "CLI for managing markdown documents with YAML frontmatter — index, query, validate, graph, export, lifecycle, and AI summaries.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/hud.mjs CHANGED
@@ -10,7 +10,7 @@ import { buildIndex } from './index.mjs';
10
10
  import { readJournalEntries, journalFilePath, readMisuseEntries } from './journal.mjs';
11
11
  import { compareVersions } from './update.mjs';
12
12
  import { findOwnedPlan } from './baton.mjs';
13
- import { listOwnedPlans } from './pickup.mjs';
13
+ import { listOwnedPlans, surveyOwnershipClaims } from './pickup.mjs';
14
14
  import { actionablePromptStatuses, comparePromptDocs, resolveStatusMetadata } from './status-metadata.mjs';
15
15
 
16
16
  export { actionablePromptStatuses } from './status-metadata.mjs';
@@ -84,7 +84,22 @@ export function buildHudFast(config) {
84
84
  const records = listOwnedPlans(config);
85
85
  if (!records.diagnostics?.length && records.length === 1) owned = { path: records[0].plan, title: null, via: 'ownership' };
86
86
  } catch { /* hud must not fail */ }
87
- return { owned, prompts, misuseRecap: buildMisuseRecap(config) };
87
+ return { owned, prompts, misuseRecap: buildMisuseRecap(config), deadClaimsLine: deadClaimsHudLine(config) };
88
+ }
89
+
90
+ // A claim whose session is provably gone wedges `set`, `archive` and `baton` on
91
+ // that plan until someone releases it, and nothing at session start said so:
92
+ // three platform claims sat dead for up to 25 days, and the session that found
93
+ // them had to read `doctor --help` to learn the verb. Name them and the command.
94
+ export function deadClaimsHudLine(config, { top = 3 } = {}) {
95
+ let claims;
96
+ try { claims = surveyOwnershipClaims(config); } catch { return null; }
97
+ const dead = claims.filter(claim => !claim.corrupt && claim.liveness === 'dead');
98
+ if (!dead.length) return null;
99
+ const n = dead.length;
100
+ const shown = dead.slice(0, top).map(claim => claim.plan).join(', ');
101
+ const more = n > top ? `, +${n - top} more` : '';
102
+ return `[runlist] ${n} plan${n === 1 ? ' is' : 's are'} claimed by a session that is gone (${shown}${more}) — \`runlist doctor --claims --apply\` releases ${n === 1 ? 'it' : 'them'}; \`runlist doctor --claims\` lists every claim.`;
88
103
  }
89
104
 
90
105
  function findActionablePrompts(config, index) {
@@ -264,6 +279,7 @@ export function buildHud(config) {
264
279
  fleet,
265
280
  recentRejections,
266
281
  misuseRecap,
282
+ deadClaims: (() => { try { return surveyOwnershipClaims(config).filter(c => !c.corrupt && c.liveness === 'dead').map(c => ({ plan: c.plan, sessionId: c.sessionId, since: c.since })); } catch { return []; } })(),
267
283
  flags: (() => { try { return openFlags(config).map(f => ({ id: f.id, severity: f.severity, file: f.file, line: f.line, text: f.text })); } catch { return []; } })(),
268
284
  };
269
285
  }
@@ -277,6 +293,7 @@ export function buildHud(config) {
277
293
  const SUBAGENT_PRIMER = [
278
294
  'runlist manages this repo\'s plans/docs/prompts (markdown + YAML frontmatter).',
279
295
  'Verbs: plans|briefing | query <filters> | use [<file>] | set <status> <file> | new <type> <slug> | archive <file>.',
296
+ 'Claims: `runlist doctor --claims` lists which session holds each plan; `--apply` releases the ones whose session is gone.',
280
297
  'Do NOT: cat/read a docs/prompts/*.md (use `runlist use <file>` — archive/claim commits before at-most-once output);',
281
298
  'git add/commit a prompt (they are session-local, often gitignored); hand-edit a `status:` field (use `runlist set`).',
282
299
  ].join('\n');
@@ -405,6 +422,7 @@ export function runHud(argv, config) {
405
422
  process.stdout.write(yellow(`[runlist] ${n} pending prompt${n === 1 ? '' : 's'} queued for this session — unless the user asks for something else, start by running \`runlist use\` to consume the oldest (${hud.prompts[0]}) and act on it. Peek first: \`runlist prompts show <file>\`; list: \`runlist prompts\`.`) + '\n');
406
423
  }
407
424
  if (hud.misuseRecap) process.stdout.write(yellow(`[runlist] ${hud.misuseRecap}`) + '\n');
425
+ if (hud.deadClaimsLine) process.stdout.write(yellow(hud.deadClaimsLine) + '\n');
408
426
  // Open flags are the one piece of passive state printed here: the person
409
427
  // asked that every session start knowing where things stand. It is worded
410
428
  // as awareness, not an instruction, so no session treats it as its task.