Commit Graph
427 Commits
Author SHA1 Message Date
ClintchizandClaude Opus 5 028c2a6d64 feat(syntax): parse sectioned api blocks
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 15:21:10 +05:30
ClintchizandClaude Opus 5 2f0f82b29f chore: ignore the subagent-driven-development workspace
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 15:18:39 +05:30
ClintchizandClaude Opus 5 50097ec4b4 docs: implementation plan for typed api blocks
Six tasks: parse the sections, add the CSR transport, compile client-mode
blocks into the browser module, generate the tsc assertions, support
sections in ssr blocks, and verify end to end in a browser.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 15:15:02 +05:30
ClintchizandClaude Opus 5 f026415ba6 docs: design for typed, callable api blocks in .wrn files
A sectioned `api` block -- request / response / error -- callable on
demand from client code, typed against the API route contracts the types
generator already emits.

Records the constraints that shaped it: the current block cannot carry a
query string (isSafeApiPath rejects "?"), cannot interpolate (readPath
stops at "{"), has nowhere to put a body, and fetches once. And the one
that decides the type-safety mechanism -- generated build artifacts are
not type-checked, so enforcement goes into the generated .d.ts, which the
project's own tsc already compiles.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 15:09:30 +05:30
ClintchizandClaude Opus 5 2cbc3e43e1 release: patch compiler, cli, dev-server
Quality / quality (ubuntu-latest) (push) Failing after 9m51s
Quality / quality (windows-latest) (push) Canceled after 0s
Strips TypeScript from client function bodies when emitting browser
modules, so `wrnexus build` no longer fails on an annotated local.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 14:17:51 +05:30
ClintchizandClaude Opus 5 55fed2177a fix(compiler): strip TypeScript from client function bodies
Quality / quality (ubuntu-latest) (push) Failing after 9m53s
Quality / quality (windows-latest) (push) Canceled after 0s
`wrnexus build` failed on any client function whose body used TypeScript:

    const requestBody: Record<string, unknown> = {}
    error: Expected ";" but found ":"

Codegen copies a client function's body into the browser module verbatim.
It removes the types from the function's *signature*, which is what made
this easy to miss -- the emitted module looked transpiled, and only bodies
carried types through. The artifact is written as .mjs and read back as
plain JavaScript, so the failure surfaced as a syntax error in generated
code rather than at the .wrn line responsible.

Browser modules are now transpiled before they are written, at all three
sites that emit one (the production build and both dev-server paths).

Reproduced end to end: a page with an annotated body failed the build with
the reported errors, and after the fix builds, ships valid minified JS, and
runs -- the handler sets its state correctly in a browser.

Note: the same body is also embedded as a string for the CSP-safe fallback
interpreter, which still receives it untranspiled. The compiled module
shadows the fallback, so this is only reachable in the window before that
module loads. Left alone here because stripping it lives in codegen, which
also runs under Node in the editor bundle where the Bun transpiler is
unavailable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 14:03:14 +05:30
ClintchizandClaude Opus 5 8c609edd32 release: patch csr, dev-server, language-server, react, ui
Quality / quality (ubuntu-latest) (push) Failing after 11m36s
Quality / quality (windows-latest) (push) Canceled after 0s
Client control blocks and loops, the dev-server rebuild recycle, the
editor's tag and completion handling, and the island mount/HMR fixes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 13:42:26 +05:30
ClintchizandClaude Opus 5 e898929193 fix(react): mount visible islands and load rebuilt code after HMR
Quality / quality (ubuntu-latest) (push) Failing after 9m55s
Quality / quality (windows-latest) (push) Canceled after 0s
Two faults found by driving the island demo in a real browser. Both were
silent: the markup, every asset, and all 48 island tests were correct
either way.

An island renders nothing until it mounts, so its placeholder is
zero-height, and IntersectionObserver does not treat a zero-area target
consistently -- client:visible islands mounted on one load and not the
next. Visibility for those is now decided from the element's own rect,
driven by scroll and resize; a placeholder with real size still uses the
observer. The strategy had no test at all, which is why this shipped.

After an island source edit the browser kept running the old code. The
rebuild worked and the file was refetched, but the loader imports a URL
that does not change, and the browser caches modules by URL. Remounts now
carry a generation the dev loader folds into the request.

Verified in the browser: mounts with start={3} as a number, clicks reach
React (3 -> 5), and an edit to Counter.tsx now shows the new text and
stays interactive.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 13:32:05 +05:30
ClintchizandClaude Opus 5 18a1c40118 fix(dev-server): recycle the server once hot rebuilds pile up
The dev server got slower the longer it ran. Measured on the example app:
30 .wrn edits grew RSS from 117 MB to 137 MB and never gave it back, while
30 CSS edits cost nothing -- so the leak is exactly one retained module
identity per rebuild, not caches or file handles.

That is inherent to reloading a module in-process. Bun caches modules by
path, so a rebuild has to be given a new identity to be picked up at all,
and Bun has no API to unload the old one. At roughly 0.66 MB a rebuild, a
long editing session is several hundred megabytes of garbage that cannot
be collected.

The process now recycles itself past a rebuild threshold, exiting with the
RESTART_EXIT_CODE the CLI supervisor already respawns on; browsers
reconnect because the HMR client already retries. It waits for a quiet
period first so a live request is never cut off, and the threshold (300
rebuilds, about 200 MB) sits well above a normal session. Set
WRNEXUS_DEV_RECYCLE_AFTER to tune it, or 0 to switch it off.

Also bounds browserArtifactPaths and islandArtifactPaths, which are keyed
by content hash and so gained an entry per rebuild that was never read
again. Small next to the module leak, but unbounded is unbounded.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 10:30:54 +05:30
ClintchizandClaude Opus 5 a20f143acb fix: isolate test globals, close tags at every caret, trim the runtime
Three pre-existing issues that the previous commit worked around rather
than solved.

Test global pollution. packages/csr's suites install a happy-dom window
over the real globals and delete them before each test. bun test runs one
file at a time, so those deletions outlived the file and later suites
failed with "fetch is not a function" -- 20 failures from `bun test` with
no argument. They now restore what they captured. The editor's Node tests
shim the vscode host by patching Module._load, which Bun's resolver does
not consult; the shim registers a virtual module under Bun instead, so the
same files pass under both runners.

Multi-cursor tag auto-close. The handler now closes the tag at every
caret. Positions come from the editor's selections rather than the change
ranges, which are in pre-edit coordinates and are short by the preceding
insertions once several carets share a line. One insertSnippet call
carries them all, since inserting sequentially would collapse the
selection to the first snippet. Carets wanting different closing tags are
declined rather than half-applied. Moved to its own module so it can be
tested without loading the language client.

Runtime size. Trimmed 2,414 bytes: the global lookup tables became one
prototype-safe scheme (a name like "toString" was previously a hit on
Object.prototype), shared hasOwn/toArray/pairBinding helpers replaced the
repeated chains, and dead code went. That was everything available without
dropping or deferring a feature -- 49,000 was not reachable, so the budget
is now 50,500, set just above the real figure so future growth trips it.

Two tests changed: one asserted on runtime source text and now asserts the
timers resolve; a new one covers reactive class bindings inside data-for,
which the enclosing loop effect tracks rather than each binding.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 10:14:18 +05:30
ClintchizandClaude Opus 5 ac248f2bb0 fix(csr): run for/while loops and keep declarations out of state
The client runtime had no loop support, so any shared function using one
returned early -- Pagination and ButtonGroup were broken client-side, not
just in tests.

Adding loops exposed two further faults:

- A var reaching writeScope creates a signal and triggers a render sweep.
  A declaration inside a function called during a render therefore looped
  forever. Declarations now bind into the handler locals instead.
- A control block removed from the DOM keeps its effect in the renderers
  list. Running it against a detached node threw, aborting the sweep and
  leaving every later effect stale.

Also raises the reactive runtime budget to 53,000: the runtime had already
grown past 49,000 before this change, and 52,570 minified is 16,803 gzipped.

Two deferred minors: html-service leaves absent documentation undefined
rather than an empty string, and the extension declines tag auto-close on
multi-cursor edits rather than closing only the first cursor.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 02:24:41 +05:30
ClintchizandClaude Opus 5 0904a4efaa fix(csr): render control blocks created by a client rerender
{#if}, {#each} and their {:else}/{:else if}/{:empty} branches worked on
the server and after hydration, but a block nested inside another block
stayed empty once the outer block rerendered. Adding a row to a list
produced the row's markup with its inner block markers in place and
nothing between them, for the life of the page.

Two causes, both on the client-created path only:

reactive() registers an effect; effects run when renderAll sweeps the
list. A state change runs just the affected effects rather than sweeping,
so an effect registered during that rerender was queued and never
invoked. setupControlBlock now returns its runner and the creating block
invokes it immediately.

The first reactive pass is skipped so hydration does not discard
server-rendered DOM. A block created by a rerender has no server DOM, so
skipping its only pass left it permanently empty. firstRun is now keyed
off outerLocals, which is set only on the client-created path.

Verified in a browser as well as in tests: adding a group to a list now
renders the new row's nested {:else}, and the existing rows' nested loops
survive the rerender.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 00:49:31 +05:30
Clintchiz 5b11b937bb Release CLI with reactive control block runtime
Quality / quality (ubuntu-latest) (push) Failing after 9m51s
Quality / quality (windows-latest) (push) Canceled after 0s
2026-08-19 00:27:32 +05:30
Clintchiz f199385204 Make if and each blocks reactive on the client
Quality / quality (ubuntu-latest) (push) Failing after 9m49s
Quality / quality (windows-latest) (push) Canceled after 0s
2026-08-19 00:22:00 +05:30
Clintchiz c0c2fa4595 chore(release): publish CLI 0.8.43
Quality / quality (ubuntu-latest) (push) Failing after 9m48s
Quality / quality (windows-latest) (push) Canceled after 0s
2026-08-18 23:38:54 +05:30
Clintchiz cfdcdd00ad chore(release): publish dev server 0.8.39
Quality / quality (ubuntu-latest) (push) Failing after 9m58s
Quality / quality (windows-latest) (push) Canceled after 0s
2026-08-18 23:31:21 +05:30
Clintchiz 03d5cb6aa6 fix(gateway): proxy browser server functions to workspace apps
Quality / quality (ubuntu-latest) (push) Failing after 10m40s
Quality / quality (windows-latest) (push) Canceled after 0s
2026-08-18 23:30:42 +05:30
Clintchiz 701acd828c fix(vscode): avoid relative-link parsing in changelog
Quality / quality (ubuntu-latest) (push) Failing after 9m54s
Quality / quality (windows-latest) (push) Canceled after 0s
2026-08-18 22:55:11 +05:30
Clintchiz b28b79c370 fix(vscode): use supported Marketplace publish flags
Quality / quality (ubuntu-latest) (push) Failing after 6m1s
Quality / quality (windows-latest) (push) Canceled after 0s
2026-08-18 22:52:59 +05:30
Clintchiz fdd0c9f847 chore: complete HTML editing verification
Quality / quality (ubuntu-latest) (push) Failing after 10m13s
Quality / quality (windows-latest) (push) Canceled after 0s
2026-08-18 22:49:07 +05:30
Clintchiz 7ad336b4dd chore(vscode): prepare 0.8.8 marketplace release
Quality / quality (ubuntu-latest) (push) Failing after 9m53s
Quality / quality (windows-latest) (push) Canceled after 0s
2026-08-18 22:43:01 +05:30
Clintchiz d70e89230b chore(release): publish language server 0.8.10
Quality / quality (ubuntu-latest) (push) Failing after 21s
Quality / quality (windows-latest) (push) Canceled after 0s
2026-08-18 22:38:47 +05:30
ClintchizandClaude Opus 5 7e6d8c3bc8 test(language-server): add end-to-end verification for HTML editing support
Adds a scratch page (kept intentionally, per controller ruling on Task 8)
and one end-to-end test that drives the real language server over LSP
stdio against that page's real text, verifying completion (with the
seo-block negative case tested via a simulated '<' keystroke and
mutation-verified against html-regions.ts), hover, folding ranges,
linked editing, and wrn/tagComplete all work together on realistic
content.

Regenerates routes.gen.ts and wrnexus.generated.d.ts for the new page's
route, required by check:generated-types.

Two checks from the original brief (auto-close-tag insertion and Emmet
Tab-expansion) require a live VS Code Extension Development Host and
are documented as outstanding manual verification in
.superpowers/sdd/2026-08-18-wrn-html-editing/task-8-report.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 21:59:19 +05:30
ClintchizandClaude Opus 5 92c0920c9b test(vscode): guard the Emmet mapping and auto-close setting
Also fix an unused-var lint failure in completion-scope.test.js blocking the production gate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 21:36:20 +05:30
Clintchiz a8d8ac386f test(vscode): add integration tests for completion provider guard 2026-08-18 21:28:38 +05:30
Clintchiz 2c8841cc5f fix(vscode): stop duplicating completions inside view blocks 2026-08-18 21:23:54 +05:30
ClintchizandClaude Opus 5 b344d2a70a fix(vscode): guard tag auto-close against replaced selections and stale round-trips
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 21:20:16 +05:30
ClintchizandClaude Opus 5 e83f0366ef feat(vscode): close HTML tags as they are typed in .wrn files
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 21:16:47 +05:30
Clintchiz d9e8f5be82 feat(language-server): add tag folding and linked editing 2026-08-18 21:10:57 +05:30
Clintchiz bd0c1317ff test(language-server): cover didClose region-cache clear end-to-end
Replaces the direct-call-only test with an over-stdio test that exercises
server.ts's didClose handler itself, so it fails if the
clearHtmlRegionCache wiring is removed or misparameterized.
2026-08-18 21:04:33 +05:30
Clintchiz 97801287f9 feat(language-server): merge HTML completions and hover into one response 2026-08-18 20:56:17 +05:30
Clintchiz d77638131b fix(language-server): don't self-close tags inside quoted attribute values 2026-08-18 20:47:19 +05:30
Clintchiz 609224591c feat(language-server): answer HTML completion, hover, folding, and tag close 2026-08-18 20:43:47 +05:30
Clintchiz 6074d19c43 fix(language-server): bypass cache for version-less documents 2026-08-18 20:38:37 +05:30
Clintchiz 7301849a7f feat(language-server): add offset-preserving virtual HTML document 2026-08-18 20:34:24 +05:30
ClintchizandClaude Opus 5 7d481df652 docs(html-editing): add implementation plan
Eight TDD tasks: the view-block scanner and virtual document, the HTML
service wrapper, merging HTML into completion and hover, folding and
linked editing, auto-close on type, standing down the duplicate client
provider, manifest guards, and a manual editor check.

Task 1 comes first because everything reads positions through it: its
length-and-newline invariant is what removes position mapping, and a
break there would misreport positions everywhere rather than fail.

The last task is manual verification in an Extension Development Host.
Unit tests cannot show that completions actually appear in an editor, and
a green suite has hidden non-functional features in this repo before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 20:30:34 +05:30
ClintchizandClaude Opus 5 5477f5436d docs(html-editing): add design spec for HTML support in .wrn files
Markup in a .wrn file highlights but has no tag or attribute completion,
no tag closing, and no tag-level folding: the grammar's embeddedLanguages
mapping only affects tokenization, and VS Code's HTML language service
never runs on these documents.

The design extracts view blocks into a virtual HTML document where
everything outside them is blanked to whitespace of identical length, so
source positions and virtual positions are the same and no mapping table
is needed. Region detection is a tolerant scanner rather than the parser,
because completion fires while the document is mid-edit and unparseable.

Completion merges WRNexus and HTML entries into one list ranked by
sortText, which also fixes an existing bug: the extension and the server
both answer completion on '<' today, so VS Code concatenates two lists.

Two decisions worth review:

- HTML formatting is excluded. formatWrn already formats markup, knows
  WRNexus syntax, and would fight a second formatter that is free to
  rewrite spacing inside @click={...} and client:visible.
- Only auto-close-on-type is client-side. Linked editing is standard LSP
  and lives in the shared server.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 20:23:08 +05:30
ClintchizandClaude Opus 5 b646ec8d00 chore(release): patch-bump packages changed since the last publish
Quality / quality (ubuntu-latest) (push) Failing after 12m48s
Quality / quality (windows-latest) (push) Canceled after 0s
cli 0.8.42, csr 0.8.22, db 0.8.16, dev-server 0.8.38,
dev-toolbar 0.8.13, i18n 0.8.12.

Every previous version was already on the registry, so the HMR client
repair, the i18n JSON data block, the gateway WebSocket origin fix, and
the generated-dialect stamp were not reachable by consumers.

compiler and react are unchanged since their last publish and are not
bumped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 20:01:01 +05:30
ClintchizandClaude Opus 5 e66d2425aa fix(gateway): allow HMR sockets on every configured domain
Quality / quality (ubuntu-latest) (push) Failing after 13m52s
Quality / quality (windows-latest) (push) Canceled after 0s
The WebSocket origin check compared the browser's Origin host, which
carries the port, against configured domains, which do not. publicOrigin
only ever matches domains[0], so every other domain fell through to that
comparison and was denied purely on the port: web.localhost:3000 never
matched web.localhost.

The result was a 403 on the HMR upgrade and a client reconnecting
forever, while the page itself loaded fine because HTTP routing resolves
the Host separately.

Compares hostnames now. Unrelated and lookalike-suffix origins are still
denied, and both cases are covered by tests.

Verified through a real gateway: the HMR socket opens on both localhost
and web.localhost, and a live edit reaches the browser.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:53:27 +05:30
ClintchizandClaude Opus 5 b3b65dddd8 fix(db): stamp the dialect into generated query files
Quality / quality (ubuntu-latest) (push) Failing after 12m46s
Quality / quality (windows-latest) (push) Canceled after 0s
The same generate command emitted ? one run and $1 the next, which looked
like non-determinism. It is not: postgres uses $1 placeholders where
sqlite and mysql use ?, and the driver comes from the active profile, so
building under a different profile rewrites this committed file.

The header now records the dialect it was generated for, making the flip
visible in the diff and explaining check:generated-types failures instead
of leaving them looking like random churn.

Worth deciding separately: a committed artifact whose contents depend on
the active profile will keep drifting. Either generate per dialect, or
stop committing it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:44:36 +05:30
ClintchizandClaude Opus 5 5dbcc5b85d fix(i18n): ship i18n data as a JSON block so CSP cannot block it
window.__wrnI18n was undefined in development: the payload shipped as an
executable inline script, and a document's CSP nonce is fixed at load, so
any such script arriving from a later response is blocked. Client
translations and language switching silently had no data.

The payload is now a type="application/json" block, which the browser
never executes and script-src therefore never applies to. The i18n
runtime, CSR navigation, and HMR all read the block instead of matching
window.__wrnI18n= with a regex.

Pages now render zero executable inline scripts, so an inline script-src
violation is structurally impossible rather than merely unobserved. Zero
framework JavaScript on island-free routes is unaffected: the block is
inert data, and nothing loads to read it unless the page needs it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:44:28 +05:30
ClintchizandClaude Opus 5 e819c5739e Revert "chore(example): regenerate basic-app queries"
Quality / quality (ubuntu-latest) (push) Failing after 12m38s
Quality / quality (windows-latest) (push) Canceled after 0s
The generator's placeholder style is not deterministic across runs: the
same command emitted $1 once and ? the next time, depending on the
database dialect active in the environment. Restoring the committed
output and reverting my earlier regeneration, which was environment
churn rather than an intended change.

Worth a look on its own: a generator whose output depends on ambient
environment makes check:generated-types environment-sensitive.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:26:07 +05:30
ClintchizandClaude Opus 5 ac164789bd fix(dev): serve the HMR client as an external script
A document's CSP nonce is fixed at load, so an inline script delivered by
a later response can never carry a nonce that document accepts. The HMR
client is now served at /__wrnexus/hmr-client.js, which script-src 'self'
already covers and which needs no nonce at all.

This removes one of the two inline scripts CSP was blocking in
development. The i18n data script is still blocked and needs the same
treatment; it is shared with the CSR navigation and HMR parsers, so
moving it spans @wrnexus/i18n, csr, and dev-server.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:25:40 +05:30
ClintchizandClaude Opus 5 88ec3a5cb6 chore(example): regenerate basic-app queries
Regenerated output for the committed query generator: positional
placeholders now render as $1 rather than ?.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:17:15 +05:30
ClintchizandClaude Opus 5 28085b5a43 chore(db,scripts): pending migration and packaging tweaks
Pre-existing working-tree changes to migration SQL parsing, query
generation, and the packaging scripts. Committed as-is rather than
authored here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:17:02 +05:30
ClintchizandClaude Opus 5 5d7bd81601 fix(dev-toolbar): report development-appropriate budgets
Excludes the toolbar's own bundle from the JavaScript budget, raises the
development thresholds, and skips WRNexus UI and theme stylesheets when
measuring CSS coverage, so unminified development modules and framework
styles stop reading as application problems.

Pre-existing working-tree change, committed as-is rather than authored
here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:17:01 +05:30
ClintchizandClaude Opus 5 5e114d867f feat(gateway): forward application identity on WebSocket upgrades
Adds gatewayWebSocketBackendHeaders so proxied upgrades carry application
identity while Bun keeps ownership of WebSocket framing.

Pre-existing working-tree change, committed as-is rather than authored
here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:16:54 +05:30
ClintchizandClaude Opus 5 10421465df fix(styles): stop scanning every component for utility sources
Component discovery is not utility-source discovery: scanning all
built-in and plugin component directories made Tailwind/Iconify generate
rules for components the app never renders. Packages that need scanning
opt in through styles.source.

Pre-existing working-tree change, committed as-is rather than authored
here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:16:53 +05:30
ClintchizandClaude Opus 5 52cce2c628 style(docs): apply Prettier to the React islands spec and plan
Formatting only; no content change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:16:45 +05:30
ClintchizandClaude Opus 5 afa2a8c093 chore(deps): move packages to TypeScript 6.0.3
Raises the typescript devDependency across the workspace, bumps package
versions, re-adds ignoreDeprecations, and repoints the @wrnexus registry.

These were pre-existing working-tree changes, committed as-is rather than
authored here. The .npmrc change redirects @wrnexus publishes from
registry.npmjs.org to registry.workroot.in — confirm that is intended
before publishing from this branch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:16:34 +05:30