Skip to content

feat(cli): vocabulary:<word> in the city (M19b) - #33

Merged
jgrodziski merged 9 commits into
feat/m19b-vocabulary-tabfrom
feat/m19b-vocabulary-metric
Oct 27, 2026
Merged

jgrodziski merged 9 commits into
feat/m19b-vocabulary-tabfrom
feat/m19b-vocabulary-metric

Conversation

@jgrodziski

Copy link
Copy Markdown
Contributor

Third and last step of milestone M19b in PLAN.md §20 (word cloud / glossary, #6). Stacked on #32 (itself on #31, #30, #29, #28, #27 and #26): review those first. This PR's diff is the six commits after #32, plus the merge that brings #28's closure-check fix up the stack.

It makes a word a city metric: --height vocabulary:order raises each building by how much its type's names say order. It also adds the demo images to the README and updates the navigator tutorial.

The metric (packages/cli/src/vocabulary-metric.ts)

  • What it measures. --height, --footprint and --carry accept vocabulary:<word>: the word's weight in the names of the type and its members, each name weighted by its role. This is the number in the type's row of vocabulary.json and the Vocabulary tab. A serve test checks that every served type's building equals its row.

  • The word goes through the splitter. vocabulary:Order reads as order. These are usage errors (exit 2):

    • two words, e.g. vocabulary:OrderService;
    • no word, e.g. vocabulary: or vocabulary:42;
    • a word no name says, e.g. vocabulary:zebra.

    A typo would otherwise draw a flat city that looks like an answer.

  • Several classes, one sum. A word that two languages classify differently (Java's type, Go's keyword type) counts all of its classes.

  • 0, not unmeasured. A type whose names never say the word measures 0: its names were read and say nothing about order. Only stubs are unmeasured, because their names are never read. With --internal-only there are no stubs.

  • Counted only when asked. codegraph city counts words only when a vocabulary: metric is named. serve and the desktop daemon reuse the vocabulary they already build. @codegraph/city is unchanged: this is the CLI's metric hook, the same one that serves history:.

  • --help lists the form.

The viewer's help (viz)

The help said "a taller tower holds more code", which is only true when height is lines of code. It now defers to the legend, and a test checks that the help names no metric of its own.

Docs

  • README. A new "Read its vocabulary" section with the cloud SVG and a city image, and a fifth row in the questions table.
  • docs/vocabulary-city-broadleaf.png (323 KB, 1600×1000). The real City tab on BroadleafCommerce with --internal-only --height vocabulary:order --height-scale sqrt, arrows hidden, and OrderServiceImpl selected; its panel reads vocabulary:order 203. core.order.service and core.offer stand as towers.
  • Reference. docs/cli.md; on the website, City metrics gains a "Vocabulary form" section, and the city, serve and vocabulary pages are updated. CLAUDE.md gets two command lines.
  • Navigator tutorial. It now lists all six tabs and walks through the Vocabulary tab on gson's TypeAdapter.
    • The numbers come from re-extracting gson at the tutorial's tag (gson-parent-2.14.0), which reproduces the tutorial's 1,855 nodes and 6,236 rows. On TypeAdapter, tree weighs 7, carried by fromJsonTree and toJsonTree (3 each) and the parameter jsonTree (1).
    • I followed every step in the browser.
  • PLAN. §20.2 records the channel as built, §20.4's last two M19b items are checked, and the M19b row is marked done (not yet merged).

Worth a look in review:

  • 0 versus unmeasured departs from PLAN, which said "unmeasured". With "unmeasured", nearly every building of such a city would print a warning.
  • A height, not a colour. The city's one colour channel is the framework role, which is categorical, so a number has no colour channel to go to. PLAN principle 5 now says "measures". feat(vocabulary): the word cloud as SVG (M19b) #31's description claimed PLAN already said this; it did not until now.
  • Square root in the demo. 627 of Broadleaf's 3,305 types say order. On the sqrt scale, 589 of them rise above 5 of 40 height units; on the linear scale only 92 do, and the city reads as flat.

Verification

  • pnpm -r build and typecheck are green, eslint is clean on every changed file, pnpm run gen:schemas leaves schemas/ unchanged, and the Hugo site builds.
  • cli 998 tests, viz 143, vocabulary 324, navigator-ui 105, core 544, city 94. Every other package passes except the Node 26 node:sqlite warning test noted on feat(core): language lexicons on profiles (M19a) #26.
  • 7 deliberate mutations, one at a time; the tests caught each:
    • an unknown word accepted;
    • 0 turned into unmeasured;
    • many words accepted;
    • the word left unsplit;
    • the last class winning instead of the sum;
    • a handed vocabulary ignored;
    • the metric left unwired.
  • The single executable. ./build.sh --ts --sea passes its smoke checks. Its city gives the Java fixture's hand counts (Order 8, AbstractOrder 8, OrderService 10, Notifications 4), and vocabulary:zebra exits 2.
  • In the browser: the City tab on Broadleaf as in the image, with no console error.

Part of #6.

🤖 Generated with Claude Code

Jérémie Grodziski and others added 7 commits October 26, 2026 23:02
`--height`, `--footprint` and `--carry` take `vocabulary:<word>`: the
word's weight in the names of the type and its members, the Vocabulary
tab's type scope, so the City and Vocabulary tabs read one number.

- Wired through cityOf's metric hook beside `history:`; the city
  package is unchanged.
- A type whose names never say the word weighs 0, a measured zero; a
  stub, whose names the vocabulary never reads, is unmeasured.
- The word is read by the splitter (`Order` is `order`); several words,
  none, or a word no name in the view says is a usage error.
- Two classes of one text add up: the metric is about the text.
- `serve` and the app job hand cityOf the vocabulary they already
  build; `city` counts one only when such a metric is named.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The help dialog said "a taller tower holds more code", true only when
height is `loc`. Height is whatever metric was bound (fanIn, sum:
cyclomatic, vocabulary:order…), so the prose now defers to the legend.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`docs/cli.md`'s city section; the website's City metrics page gains a
"Vocabulary form" section (what it reads, 0 against unmeasured, the
usage errors); the `--height`/`--footprint` rows of `city` and `serve`
as their help now reads; an "In the city" note on `vocabulary`; and
the two commands in CLAUDE.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A "Read its vocabulary" section and a fifth question in the README's
table, showing the issue's two demo images:

- `docs/vocabulary-broadleaf.svg`, BroadleafCommerce's corpus cloud
  (from the cloud PR);
- `docs/vocabulary-city-broadleaf.png`, new: the City tab on
  BroadleafCommerce at `--height vocabulary:order --height-scale sqrt`,
  arrows hidden and `OrderServiceImpl` selected (vocabulary:order 203).

`docs/cli.md` links the city image from the vocabulary section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tutorial listed Navigate, Graph, Cycles and Coupling. It now names
all six and adds a Vocabulary step on its own subject, `TypeAdapter`,
with numbers re-taken from gson at `gson-parent-2.14.0` (the model
reproduces the tutorial's 1,855 nodes and 6,236 rows): 7 domain terms
of 17, `tree` the heaviest at 7, carried by `fromJsonTree`,
`toJsonTree` and `jsonTree`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
§20.2: the channel is a height, not a colour (the city's one colour
channel is the categorical role); a type that never says the word
weighs 0 and only a stub is unmeasured; the splitter reads the word;
Broadleaf's numbers and the demo image's settings. §20.4's last two
M19b items are checked and the milestone row marked done.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From feat/m19b-vocabulary-tab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
codegraph 04ed6c0 Commit Preview URL

Branch Preview URL
Oct 27 2026, 03:06 PM

@jgrodziski
jgrodziski added this pull request to stack #34 October 27, 2026 14:28
From feat/m19b-vocabulary-tab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From feat/m19b-vocabulary-tab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jgrodziski
jgrodziski merged commit 24910be into feat/m19a-profile-lexicon Oct 27, 2026
103 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant