fix(cli): headings name a project by its label; four small CLI fixes - #415
Merged
Merged
Conversation
Found by dogfooding release 4.10.2. Refs #409, #410 and #412; each of them also has parts this commit does not touch. - Headings and empty-state lines of the briefing, the task-state lines, the first-run banner and the lines `memesh task` prints name a project by its label ("memesh"), not its whole id ("memesh~<32 hex>"). One rule, `projectLabel` in work-topology.ts, removes one trailing `~` plus exactly 32 lowercase hex characters and leaves anything else alone. The full id stays wherever it identifies data: `project:` tags, entity names, the `project` field of results, `--project`, and the unread-message line. - `briefing --json` reports `hasTaskState: true` only when a task-state line leads the block; the unread-message reminder no longer counts. - `memesh config get <key>` exists: the stored value, or "<key> is not set in config.json" (it says nothing about which value applies: an environment variable can still override the default); an unknown key is refused in the same words as `set` and `unset`. - `memesh status` on an install newer than npm `latest` says "running pre-release version (X), npm latest is Y", as `memesh doctor` already did, instead of "up to date", and prints no update path. A newer install that is also deprecated, whose check only partly succeeded, or whose check could not run keeps its update path: only the "running pre-release version" line withholds it. - `memesh config list` always shows the briefing level in effect and where it comes from (default, config.json or the environment). Not changed on purpose: the stored fallback title of a task state, the titles the pre-compact and session-summary hooks write (so the whole id can still appear in the lines under "Recent activity"), lesson names and the dashboard still carry the full id.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #409, #410 and #412. Each of them also has parts this PR does not touch, so none is closed here.
Five small user-visible fixes found by an independent dogfood pass on release 4.10.2, in one commit (
fix(cli): headings name a project by its label; four small CLI fixes).What changes for a user
Decisions and direction for "memesh~2c0fe491888c8efb9a4894828bbc2733":now readsDecisions and direction for "memesh":. The same goes for the other headings of the briefing, the task-state lines, the durable-memory index heading and its empty-state line, the first-run banner and the linesmemesh taskprints. One rule owns it,projectLabelinsrc/core/work-topology.ts: it removes one trailing~plus exactly 32 lowercase hex characters and leaves anything else alone. The full id stays wherever it identifies data:project:tags, entity names, theprojectfield of JSON and MCP results,--project, and the unread-message line, which tells an agent which project to poll. Still there: the titles the session-summary and pre-compact hooks stored (2026-09-22 memesh~…: edited 12 file(s)) contain the whole id and are printed as stored underRecent activity(see "Not in this PR").briefing --jsonno longer reportshasTaskState: truewhen the only state line is the unread-message reminder. It is now true exactly when a task-state line leads the block: the fresh state, the one-line stale flag, or the unreadable-record line. The CLI's "set the task state" hint reads it, so that hint now also appears beside the reminder on a project with a message waiting and no task state.memesh config get <key>exists (CLI inconsistencies: config get is missing, status says up to date on a newer version, briefing --index prints the framing #410). It printedunknown command 'get'. It prints the stored value asconfig listshows it (forbriefing: what is stored, not the level in effect), or<key> is not set in config.json(exit 0; it says nothing about which value applies, because an environment variable can still override the default). An unknown key is refused in the same two lines assetandunset(exit 1); the three share onerequireAllowedKey.memesh statusno longer calls a newer install "up to date" (CLI inconsistencies: config get is missing, status says up to date on a newer version, briefing --index prints the framing #410). On 4.10.2 (a trial build on thenexttag) while npmlatestwas 4.9.4 it printedUpdate check: up to date (fresh; latest 4.9.4)and anUpdate path:for@latest, a downgrade. It now saysrunning pre-release version (4.10.2), npm latest is 4.9.4, asmemesh doctoralready did, and prints no update path. A newer install that is also deprecated, whose check only partly succeeded, or whose check could not run keeps its update path: only the "running pre-release version" line withholds it, through one shared predicate (showsPreReleaseNotice) that the status line and the trailer both use.memesh config listalways shows the briefing level in effect and where it comes from (The effective briefing level is not shown anywhere, and no live journey runs at the default level #412):briefing: minimal (default),briefing: standard (config.json),briefing: full (env MEMESH_BRIEFING), or, for a stored or environment value that is not a level,briefing: minimal (default; the value in config.json is invalid: "banana"). It uses the same resolver the hook uses. With nothing stored it prints(nothing stored — all defaults)first.Evidence
npm run verifyGREEN on the tree of the commit (tree 27d19998019b; 262 test files, 4529 tests passed, 9 skipped; the isolated suite, the packaged-artifact smoke and the dashboard e2e included).~<32 hex>outside theprojectfield. The MCPbriefingtool was checked through a real JSON-RPC call.showsPreReleaseNoticeturns exactly its truth-table row red; putting the oldconfig gettext back turns the twoconfig gettests red.config getsaid "the default applies" while an environment variable could override it; the update path was wrongly hidden for a deprecated or partly checked install (a regression this change had introduced); a docs sentence said "every stored key" although one stored key is not settable. Two of them (silent-failure and code review) then re-reviewed the fix: no blocking finding, every earlier finding closed, and the status predicate checked against the status chain over 384 state combinations (0 mismatches). The remaining findings of those two were wording, fixed in the final commit; the third reviewer's non-blocking findings are either fixed or tracked above.Simplification pass
A read-only pass over the whole diff found two candidates, both applied: the API reference repeated the allowed-key list in prose (cut: it goes stale unchecked, and
memesh config set --helpnames the keys), andconfig set/config unsetcarried a pure alias,const canonical = key(removed). Kept on purpose, each checked for a consumer: the sort inconfig list(a test asserts the key order), thelabel === ''guard inprojectLabel(a test pins it),describeEffectiveBriefing(one caller, but no other copy of it exists), and the overlapping test assertions (each goes through a different entry point).Not in this PR (tracked)
standardindex repeating memories the block already shows, and the stored hook titles that still carry the whole id (a comment there describes both ways to close it). CLI inconsistencies: config get is missing, status says up to date on a newer version, briefing --index prints the framing #410: thebriefing --indexframing and thereplaced_history_countdocs. The effective briefing level is not shown anywhere, and no live journey runs at the default level #412: no live journey runs at the default level.memesh updatesays "Already on latest version" for an install ahead oflatest, andmemesh statussays "up to date" whenlatestcannot be parsed. Both pre-date this change.memesh statusprints noUpdate path:on any install channel. Only the npm-global channel would have been sent to a downgrade; keeping the hint for the others would need a test that can stand up a global npm install, which is not worth one line of output.