Repository navigation
feat(core): language lexicons on profiles (M19a) - #26
Open
jgrodziski wants to merge 4 commits into
Open
jgrodziski wants to merge 4 commits into
jgrodziski wants to merge 4 commits into
Conversation
Profile.lexicon is what the vocabulary splitter (M19, #6) must know about a language and cannot derive: the specification's reserved words (contextual keywords are identifiers, often domain words), the whole names the language or its runtime dictates, its plumbing words, the kinds whose name is a file path, and C#'s interface marker. Word boundaries are universal, so separators and sigils carry no data. The eleven shipped profiles carry one; TypeScript and JavaScript read one ECMASCRIPT_LEXICON. validateProfile gains four codes for entries that could never do what their list says. `codegraph profiles` prints the lexicon between the kinds and the notes, and --json carries it in a fixed key order. schemas/ is unchanged: a profile is not on the wire. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The lexicon drops the draft's separators, prefixes and suffixes, which could change no output once the splitter breaks on every non-word character, and turns the per-profile fileModules flag into per-kind fileKinds: Elixir's `module` is a dotted name, not a file. The split steps and principle 2 follow; the M19a profile item is ticked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
profiles-page.mjs stops the kinds at `lexicon:` and renders each profile's reserved words, conventional names, technical words and file kinds as a list (Ruby's `|` operator rules out a table cell); the page is regenerated from the CLI. The metamodel page gains the lexicon row and section, and now says eleven shipped profiles, not nine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The page generator matched the CLI's indentation with runs of literal
spaces, which eslint's no-regex-spaces rejects; the lexicon row added
one more. Written as {2} and {4}, the script passes lint and writes
the same page byte for byte.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
codegraph | 51ed180 | Commit Preview URL Branch Preview URL |
Oct 23 2026, 03:14 PM |
This was referenced Oct 23, 2026
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.
First step of the word cloud / glossary (#6), milestone M19a in PLAN.md §20. Each language profile now carries a lexicon: the words the vocabulary splitter has to know about that language. Like the rest of a profile, it is data in
@codegraph/core. Nothing reads it yet. PR 2 adds the splitter that does.What a lexicon holds
keywordsnew, GotypeconventionaltoString,__init__, Ruby<=>, C#op_Additiontechnicalctx,opts,cbfileKindsmodule, Ruby/Elixirfile, PHPcodeFileinterfacePrefixIof an interface nameAll eleven shipped profiles have one. TypeScript and JavaScript share one ECMAScript list, because TypeScript reserves exactly ECMAScript's words.
Only reserved words count as keywords. A contextual keyword (
record,var,event, TStype) is a legal identifier and often a domain word. Listing it would hide it from the default cloud. A test pins this per language.Changes from the plan
PLAN §20.1 sketched
separators,prefixesandsuffixesas profile data. The splitter has to break on every non-letter, non-digit character anyway, or names like<=>andthis[]would become words. Once it does, those fields change nothing, so they are gone. The plan's single profile-wide file flag becamefileKinds, declared per kind: Elixir'smoduleis dotted (AcmeOrder.Registry) while itsfileis a path, so a profile-wide flag would cut.Registryoff as an extension. PLAN.md is updated to match.Validation
validateProfilegains four codes:lexicon-duplicatelexicon-not-a-word(an entry that can never match a split word)lexicon-keyword-overlap(a conventional or technical entry that is already a keyword)lexicon-unknown-kind(a file kind the profile does not declare)Every shipped profile passes them.
Surfaces
codegraph profiles --lang Xprints the lexicon between the kinds and the notes.--jsoncarries it in a fixed key order.docs/cli.md, and both website pages. The website profiles page is regenerated from the CLI.model.jsonl, andpnpm run gen:schemasleavesschemas/unchanged.Verification
pnpm -r typecheckgreen. Lint clean on touched code.is not vacuous: a static import of the same builtin does warn) expects Node to warn onnode:sqlite. Node 26 no longer warns.explaintest "without an API key" fails whenOPENROUTER_API_KEYis set in the shell. It passes with the key removed.git submodule update --init(docs: initialise the Hextra submodule first #24). I read the rendered lexicon section and its link anchor in the built page.Part of #6.
🤖 Generated with Claude Code