Repository navigation
A page for trying VisualText's analyzers, without an account - #22
Merged
Merged
Conversation
/studio/try/ is a second page in the same build: pick one of VisualText's
own analyzers, type text, press Run, and see the pass sequence, the
knowledge base, what the run wrote, the parse trees, and -- with Log files
on -- each pass's own tree and the text marked with what its rules matched.
It is drawn with @visualtext/analyzer-views and loads no Monaco (5.5 kB).
It is read-only, and that is the point. Running an analyzer is running its
author's code, and docs/ARCHITECTURE.md says the per-run sandbox strangers
would need is not built. This page sidesteps that rather than solving it:
the analyzers are copied in when the image is built, from a pinned
VisualText/analyzers release -- the same analyzers.zip VisualText downloads
as its examples -- and the only thing a visitor supplies is the text. The
visitor never supplies code.
Two things have to stay true for that, and neither is enforced by the
server: the page stays read-only, and /api/run -- which still accepts any
files a caller sends -- is not reachable anonymously without rate limits in
front. Both are written down rather than assumed.
Eight of the twenty analyzers in the bundle, each showing something the
others do not, 259 files and 1.45 MB in all. All twenty-one in the
repository were run through /api/run first; the survey, and why the rest are
left out, is in docs/TRY-PAGE.md so nobody repeats it. parse-en-us is
refused because it calls interactive(), which nlp_run.BLOCKED lists with the
desktop app's popups although at both its call sites it only reads state --
left alone here, and written up as an open question.
Also:
- scripts/analyzer-files.mjs holds what travels with an analyzer, shared
with copy-samples.mjs so the two cannot drift on what an analyzer is.
- src/theme.css holds the palette and plain controls, shared with the
editor page so a colour is changed once.
- src/try/result.ts keeps the two translations that are easy to get quietly
wrong -- the run server's `size` against the views' `bytes`, and
readOutput()'s { output } wrapper against what <nlp-values> takes -- in
one place, with tests.
- smoke-test.sh proves the try page and its analyzers are in the image, and
that one of them runs in debug mode, keeps a tree after every pass and can
have one fetched back.
- update.sh tracks the analyzers release as it tracks visualtext-files, so a
new one makes the app out of date.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The NLPFix analyzers carry a syntax-highlighted rendering of every pass and dictionary beside it -- spec/dates.nlp.html next to spec/dates.nlp -- made for a web page. Nothing here reads them: the sequence comes from analyzer.seq and the knowledge base lists only .dict and .kbb, so they were never listed, never opened and never read by the engine. They were still fetched by every visitor and sent up again in the body of every run. They were 46% of the try page's analyzers by size. Without them the catalog is 188 files and 0.78 MB, down from 259 and 1.45 MB; Entities halves and Dates and Times and Formatting lose two thirds each. All eight still run to the same output, the same problems and the same trees. The rule goes in analyzer-files.mjs, with the rest of what an analyzer is made of, rather than in the try page's script alone: a rendering of a pass is not part of an analyzer whichever page is showing it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
/studio/try/is a second page in the same build: pick one of VisualText's own analyzers,type text, press Run, and see the pass sequence, the knowledge base, what the run wrote,
the parse trees, and — with Log files on — each pass's own tree and the text marked with
what its rules matched. It is drawn with
@visualtext/analyzer-viewsand loads no Monaco:5.5 kB of JavaScript.
Full write-up: docs/TRY-PAGE.md.
The decision this rests on: canned analyzers, not a sandbox
Running an analyzer is running its author's code, and
docs/ARCHITECTURE.mdsays theper-run sandbox strangers would need is not built. Of the three ways to have a public try
page — build the sandbox, ship only our own analyzers, or keep the invite gate — this is the
second.
The visitor never supplies code. The analyzers are copied in when the image is built,
from a pinned
VisualText/analyzersrelease — the sameanalyzers.zipVisualText downloadsas its examples, so the page offers exactly the set a VisualText user has — and the page
offers no way to edit the NLP++. The text is data the rules read, not rules the engine runs.
Two things have to stay true for that argument to hold, and neither is enforced by the
server, so both are written down rather than assumed:
.nlp, or ananalyzer named by URL puts it straight back behind the sandbox that does not exist.
/api/runis still the general endpoint — it accepts anyfilesa caller sends. Therestraint lives in the page, not the server. Making this reachable anonymously without
rate-limiting and fronting
/api/runwould put an RCE endpoint on the host that servesvisualtext.org.
This PR changes nothing about who can reach anything. The page ships behind whatever
already guards
/studio/.INSTALL.mdgains a section on what opening it wider would need.Which analyzers, and how they were chosen
All 21 analyzers in the repository were run through
POST /api/runwithdevelop: truebefore any UI existed. 19 ran clean. The eight on the page were picked from those for showing
different things; the survey table is in
docs/TRY-PAGE.mdso nobody repeats it.Two that are not there:
parse-en-usis refused — it callsinteractive(), whichnlp_run.BLOCKEDlists withthe desktop app's popups. At both of its call sites it is a read-only predicate, and in both
the
falsebranch is the safer one (noopenfile, an in-memory buffer). Unblocking itwould very likely give the page the full English parser. Deliberately not done here —
loosening a security control belongs in its own change, with someone deciding it on purpose.
Written up as an open question.
tutorial-01is 26 MB, over the run server's 8 MB limit, for a sequence of one pass.Verification
0 skipped trees.
passes()against the per-pass trees: 0 orphans across all eight. Both numbering trapsare live in the set —
corporatehas astub(takes no number), and a switched-off/nlppass (keeps its number, writes no tree) is covered by the tests.
ruleMatches()over real trees fetched through/api/run/tree, on every pass of everyanalyzer. The all-
@CODEpasses correctly mark nothing.docker build+smoke-test.shpass under the restrictions the container runs with,including the new try-page checks.
Writing
src/try/result.tsfound two real bugs:readOutput()returns a{ output }wrapperwhile
<nlp-values>wants the parsed value (every field would have been listed asoutput.something), and the run server calls a tree's sizesizewhere the views wantbytes. Both now live in one place with tests pinning them.Not verified: the rendered page. There is no browser on the machine this was built on, so
npm run selftestcould not run and nobody has watched it draw. Everything behind the pixelsis verified programmatically. Worth a look in a browser before merge.
Notes for the reviewer
analyzer-views/README.mdsays the package serves "both pages" — with this merged that isthree. Left alone here since it was just rewritten; flagging for whoever owns it.
VisualText/analyzershas no LICENSE file. This page redistributes its contents toevery visitor.
.gitignoredeclines to commit the copy, for the same reason it declines tocommit
analyzer-templates, but the underlying question is the owner's.scripts/analyzer-files.mjs(what travels with an analyzer, shared with
copy-samples.mjs) andsrc/theme.css(thepalette, shared with the editor page).
🤖 Generated with Claude Code