@gmickel/gno 1.36.1 → 1.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -26
- package/assets/spa-production.json.gz +0 -0
- package/browser-extension/artifacts/{gno-browser-clipper-v1.36.1.zip → gno-browser-clipper-v1.37.0.zip} +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v1.37.0.zip.sha256 +1 -0
- package/browser-extension/dist/manifest.json +1 -1
- package/package.json +4 -2
- package/spec/cli.md +12 -1
- package/src/cli/program.ts +23 -0
- package/src/serve/public/app.tsx +44 -24
- package/src/serve/public/components/ai-elements/code-block.tsx +11 -6
- package/src/serve/public/index.html +0 -1
- package/src/serve/public/lib/code-language.ts +4 -2
- package/src/serve/public/lib/shiki-language-ids.ts +335 -0
- package/src/serve/public/pages/Dashboard.tsx +81 -44
- package/src/serve/public/pages/DocView.tsx +4 -4
- package/src/serve/public/pages/Search.tsx +1 -2
- package/src/serve/public/pages/doc-frontmatter-display.tsx +10 -0
- package/src/serve/public/pages/search-page-widgets.tsx +8 -0
- package/src/serve/server.ts +6 -6
- package/src/serve/spa-bundle-source.ts +98 -22
- package/src/serve/spa-production-build.ts +130 -0
- package/src/serve/spa-production.ts +43 -0
- package/src/types/file-assets.d.ts +4 -0
- package/browser-extension/artifacts/gno-browser-clipper-v1.36.1.zip.sha256 +0 -1
package/README.md
CHANGED
|
@@ -105,7 +105,7 @@ gno daemon --detach # headless indexing + resident MCP gateway
|
|
|
105
105
|
|
|
106
106
|
**Start here** · [Quick Start](#quick-start) · [Installation](#installation) · [Agent Integration](#agent-integration) · [Search Modes](#search-modes)
|
|
107
107
|
|
|
108
|
-
**Surfaces** · [Web UI](#web-ui) · [REST API](#rest-api) · [SDK](#sdk) · [Daemon Mode](#daemon-mode) · [Publish to gno.sh](#publish-to-gnosh)
|
|
108
|
+
**Surfaces** · [Web UI](#web-ui) · [Omarchy Plugin](#omarchy-plugin) · [REST API](#rest-api) · [SDK](#sdk) · [Daemon Mode](#daemon-mode) · [Publish to gno.sh](#publish-to-gnosh)
|
|
109
109
|
|
|
110
110
|
**Under the hood** · [How It Works](#how-it-works) · [Features](#features) · [Local Models](#local-models) · [Fine-Tuned Models](#fine-tuned-models) · [Architecture](#architecture) · [Development](#development)
|
|
111
111
|
|
|
@@ -117,12 +117,25 @@ gno daemon --detach # headless indexing + resident MCP gateway
|
|
|
117
117
|
|
|
118
118
|
<!-- public-truth:current-version -->
|
|
119
119
|
|
|
120
|
-
> Current release: **v1.
|
|
120
|
+
> Current release: **v1.36.1**. See [CHANGELOG.md](./CHANGELOG.md).
|
|
121
121
|
|
|
122
122
|
<!-- /public-truth -->
|
|
123
123
|
|
|
124
124
|
> Full release history: [CHANGELOG.md](./CHANGELOG.md)
|
|
125
125
|
|
|
126
|
+
- **Cheap peek snapshot**: `gno peek --json` and MCP `gno_peek` return a
|
|
127
|
+
model-free `peek@1.0` snapshot (document/collection counts, embedding backlog,
|
|
128
|
+
10 recent docs with `docid` and `absPath`, pid-file serve detection).
|
|
129
|
+
Uninitialized reports `initialized:false` with pinned nulls and exit 0. Any
|
|
130
|
+
subquery failure is an atomic `RUNTIME` envelope (exit 2). `serve.running` is
|
|
131
|
+
true only for `gno serve --detach`. JSON search hits pin
|
|
132
|
+
`results[].source.absPath`. Open a document in the Web UI with
|
|
133
|
+
`{serveUrl}/doc?uri=<encodeURIComponent(uri)>`.
|
|
134
|
+
- **Prose-first snippets**: `gno search`, `gno vsearch`, and `gno query` skip
|
|
135
|
+
leading YAML frontmatter and prefer document prose. A frontmatter-dominated
|
|
136
|
+
FTS window falls back to stripped chunk prose. `--full` and `--line-numbers`
|
|
137
|
+
still emit raw source. `line` and `snippetRange.startLine` follow the trimmed
|
|
138
|
+
display range.
|
|
126
139
|
- **Trustworthy local context compiler**: deterministic Context Capsules replace
|
|
127
140
|
repeated agent `query → get → multi-get` orchestration with one bounded,
|
|
128
141
|
citation-complete evidence handoff. The promoted benchmark retained 100%
|
|
@@ -544,7 +557,10 @@ Output formats: `--json`, `--files`, `--csv`, `--md`, `--xml`
|
|
|
544
557
|
# Search one collection
|
|
545
558
|
gno search "PostgreSQL connection pool" --collection work-docs
|
|
546
559
|
|
|
547
|
-
#
|
|
560
|
+
# Cheap index snapshot for a status bar or desktop widget
|
|
561
|
+
gno peek --json
|
|
562
|
+
|
|
563
|
+
# Export retrieval results for an agent (`source.absPath` on file-backed hits)
|
|
548
564
|
gno query "authentication flow" --json -n 10
|
|
549
565
|
gno query "deployment rollback" --all --files --min-score 0.4
|
|
550
566
|
|
|
@@ -645,30 +661,31 @@ Connect GNO to Claude Desktop, Cursor, Raycast, and more:
|
|
|
645
661
|
|
|
646
662
|

|
|
647
663
|
|
|
648
|
-
GNO exposes
|
|
664
|
+
GNO exposes 33 tools by default via [Model Context Protocol](https://modelcontextprotocol.io),
|
|
649
665
|
including the core retrieval tools below. Starting MCP with `--enable-write`
|
|
650
|
-
adds
|
|
651
|
-
|
|
652
|
-
| Tool | Description
|
|
653
|
-
| :------------------- |
|
|
654
|
-
| `gno_search` | BM25 keyword search
|
|
655
|
-
| `gno_vsearch` | Vector semantic search
|
|
656
|
-
| `gno_query` | Hybrid search (recommended)
|
|
657
|
-
| `gno_context` | Budgeted exact evidence Capsule
|
|
658
|
-
| `gno_context_verify` | Verify saved Capsule provenance
|
|
659
|
-
| `gno_ask` | Opt-in closed-Capsule verified answer
|
|
660
|
-
| `gno_get` | Retrieve document by ID
|
|
661
|
-
| `gno_multi_get` | Batch document retrieval
|
|
662
|
-
| `gno_links` | Get outgoing links from document
|
|
663
|
-
| `gno_backlinks` | Get documents linking TO document
|
|
664
|
-
| `gno_similar` | Find semantically similar documents
|
|
665
|
-
| `gno_graph` | Get knowledge graph (nodes and edges)
|
|
666
|
-
| `
|
|
667
|
-
| `
|
|
668
|
-
| `
|
|
669
|
-
| `
|
|
670
|
-
| `
|
|
671
|
-
| `
|
|
666
|
+
adds 18 opt-in mutation tools, for 51 total.
|
|
667
|
+
|
|
668
|
+
| Tool | Description |
|
|
669
|
+
| :------------------- | :---------------------------------------------- |
|
|
670
|
+
| `gno_search` | BM25 keyword search |
|
|
671
|
+
| `gno_vsearch` | Vector semantic search |
|
|
672
|
+
| `gno_query` | Hybrid search (recommended) |
|
|
673
|
+
| `gno_context` | Budgeted exact evidence Capsule |
|
|
674
|
+
| `gno_context_verify` | Verify saved Capsule provenance |
|
|
675
|
+
| `gno_ask` | Opt-in closed-Capsule verified answer |
|
|
676
|
+
| `gno_get` | Retrieve document by ID |
|
|
677
|
+
| `gno_multi_get` | Batch document retrieval |
|
|
678
|
+
| `gno_links` | Get outgoing links from document |
|
|
679
|
+
| `gno_backlinks` | Get documents linking TO document |
|
|
680
|
+
| `gno_similar` | Find semantically similar documents |
|
|
681
|
+
| `gno_graph` | Get knowledge graph (nodes and edges) |
|
|
682
|
+
| `gno_peek` | Cheap `peek@1.0` counts, backlog, recent, serve |
|
|
683
|
+
| `gno_status` | Index health check |
|
|
684
|
+
| `gno_trace_list` | List private local retrieval receipts |
|
|
685
|
+
| `gno_trace_show` | Inspect one bounded trace receipt |
|
|
686
|
+
| `gno_changes` | Read retained metadata-only changes |
|
|
687
|
+
| `gno_diff` | Read one structural document delta |
|
|
688
|
+
| `gno_impact` | Trace bounded dependency impact |
|
|
672
689
|
|
|
673
690
|
**Design**: Default MCP mode is read-only: retrieval, opt-in verified synthesis,
|
|
674
691
|
graph, status, and job inspection. Raw retrieval tools leave synthesis to your
|
|
@@ -792,6 +809,18 @@ gno.sh.
|
|
|
792
809
|
|
|
793
810
|
---
|
|
794
811
|
|
|
812
|
+
## Omarchy Plugin
|
|
813
|
+
|
|
814
|
+
On [Omarchy](https://omarchy.org/), [**GNO Recall**](https://github.com/gmickel/omarchy-gno-recall) puts the index in your bar: a quiet health widget, an anchored panel with counts and recent documents, and a keyboard-first overlay (Super+R) for search, deep search, collection browsing, and opening documents.
|
|
815
|
+
|
|
816
|
+
```bash
|
|
817
|
+
omarchy plugin add https://github.com/gmickel/omarchy-gno-recall --enable
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
Requires gno >= 1.36.0 on `PATH`.
|
|
821
|
+
|
|
822
|
+
---
|
|
823
|
+
|
|
795
824
|
## Publish to gno.sh
|
|
796
825
|
|
|
797
826
|
GNO is local-first, but sometimes you want a URL to send someone. [**gno.sh**](https://gno.sh/publish) is the hosted reader on top of GNO — a polished, reading-first page for a single note or a whole collection, without mounting your vault or syncing anything.
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
497d8e90a34b7472eac55da861c3049b7453a33d9fdbd0a27e49f2ce36ccde9b gno-browser-clipper-v1.37.0.zip
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gmickel/gno",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.37.0",
|
|
4
4
|
"description": "Local semantic search for your documents. Index Markdown, PDF, and Office files with hybrid BM25 + vector search.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"embeddings",
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"test": "bun test",
|
|
66
66
|
"test:web": "bun test test/serve/public --timeout 30000",
|
|
67
67
|
"test:e2e": "bun scripts/web-ui-smoke.ts",
|
|
68
|
+
"bench:webui-first-page": "bun scripts/webui-first-page-load.ts",
|
|
68
69
|
"test:e2e:clipper": "bun test test/clipper/e2e.test.ts --timeout 240000",
|
|
69
70
|
"test:e2e:pdf": "bun scripts/pdf-viewer-smoke.ts",
|
|
70
71
|
"smoke:pdf-viewer": "bun scripts/pdf-viewer-smoke.ts",
|
|
@@ -144,8 +145,9 @@
|
|
|
144
145
|
"website:sync-assets": "bun scripts/sync-assets.ts",
|
|
145
146
|
"sync:agents": "scripts/sync-agents.sh",
|
|
146
147
|
"build:css": "tailwindcss -i src/serve/public/globals.css -o src/serve/public/globals.built.css --minify",
|
|
148
|
+
"build:spa": "bun scripts/build-spa-production.ts",
|
|
147
149
|
"serve": "bun src/index.ts serve",
|
|
148
|
-
"serve:dev": "
|
|
150
|
+
"serve:dev": "bun --hot src/index.ts serve --dev",
|
|
149
151
|
"version:patch": "npm version patch --no-git-tag-version",
|
|
150
152
|
"version:minor": "npm version minor --no-git-tag-version",
|
|
151
153
|
"version:major": "npm version major --no-git-tag-version",
|
package/spec/cli.md
CHANGED
|
@@ -3335,16 +3335,26 @@ API share the listener; use `gno daemon` for authenticated non-loopback MCP.
|
|
|
3335
3335
|
**Synopsis:**
|
|
3336
3336
|
|
|
3337
3337
|
```bash
|
|
3338
|
-
gno serve [--port <num>] [gateway-options] [--detach] [--pid-file <path>] [--log-file <path>]
|
|
3338
|
+
gno serve [--port <num>] [--dev] [gateway-options] [--detach] [--pid-file <path>] [--log-file <path>]
|
|
3339
3339
|
gno serve --status [--json]
|
|
3340
3340
|
gno serve --stop
|
|
3341
3341
|
```
|
|
3342
3342
|
|
|
3343
|
+
Default `gno serve` (no `--dev`) is the production WebUI bundle, even when
|
|
3344
|
+
`NODE_ENV` is unset. Production serve loads the committed SPA snapshot
|
|
3345
|
+
(`assets/spa-production.json.gz`) so first listen does not wait on `Bun.build`.
|
|
3346
|
+
Refresh the snapshot with `bun scripts/build-spa-production.ts`. `--dev` is the
|
|
3347
|
+
operator switch for the development bundle and HMR (`serve:dev` / `bun --hot`
|
|
3348
|
+
remain the hot-reload path). `--dev` does not apply to `--status` or `--stop`
|
|
3349
|
+
(those paths do not boot the UI). A detached child inherits the same
|
|
3350
|
+
production default unless the parent was started with `--dev`.
|
|
3351
|
+
|
|
3343
3352
|
**Options:**
|
|
3344
3353
|
|
|
3345
3354
|
| Option | Type | Default | Description |
|
|
3346
3355
|
| ---------------------- | ------- | ------------------------ | ---------------------------------------------------------------- |
|
|
3347
3356
|
| `-p, --port` | number | 3000 | Port to listen on |
|
|
3357
|
+
| `--dev` | boolean | false | Serve the development bundle with HMR (default is production) |
|
|
3348
3358
|
| `--detach` | boolean | false | Self-spawn a detached child; parent prints `{pid,url}` and exits |
|
|
3349
3359
|
| `--pid-file <path>` | string | `{data}/serve.pid` | Override pid-file location (JSON metadata, absolute path) |
|
|
3350
3360
|
| `--log-file <path>` | string | `{data}/serve.log` | Override log-file location (append mode) |
|
|
@@ -3423,6 +3433,7 @@ is blocked.
|
|
|
3423
3433
|
```bash
|
|
3424
3434
|
gno serve
|
|
3425
3435
|
gno serve --port 8080
|
|
3436
|
+
gno serve --dev
|
|
3426
3437
|
|
|
3427
3438
|
# Backgrounding
|
|
3428
3439
|
gno serve --detach
|
package/src/cli/program.ts
CHANGED
|
@@ -4164,12 +4164,29 @@ function wireServeCommand(program: Command): void {
|
|
|
4164
4164
|
"internal detached-child marker"
|
|
4165
4165
|
).hideHelp()
|
|
4166
4166
|
);
|
|
4167
|
+
serveCmd.addOption(
|
|
4168
|
+
new Option(
|
|
4169
|
+
"--dev",
|
|
4170
|
+
"serve the development bundle with HMR (default: production)"
|
|
4171
|
+
)
|
|
4172
|
+
);
|
|
4167
4173
|
|
|
4168
4174
|
serveCmd.action(async (cmdOpts: Record<string, unknown>, cmd: Command) => {
|
|
4169
4175
|
await handleServeAction(cmdOpts, cmd);
|
|
4170
4176
|
});
|
|
4171
4177
|
}
|
|
4172
4178
|
|
|
4179
|
+
/** CLI serve bundle mode. Default `gno serve` is production unless `--dev`. */
|
|
4180
|
+
export function resolveServeNodeEnv(
|
|
4181
|
+
dev: boolean
|
|
4182
|
+
): "development" | "production" {
|
|
4183
|
+
return dev ? "development" : "production";
|
|
4184
|
+
}
|
|
4185
|
+
|
|
4186
|
+
function applyServeBundleEnv(dev: boolean): void {
|
|
4187
|
+
process.env.NODE_ENV = resolveServeNodeEnv(dev);
|
|
4188
|
+
}
|
|
4189
|
+
|
|
4173
4190
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
4174
4191
|
// Serve lifecycle branching (detach / status / stop / detached-child / fg)
|
|
4175
4192
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -4238,6 +4255,9 @@ async function handleServeAction(
|
|
|
4238
4255
|
return;
|
|
4239
4256
|
}
|
|
4240
4257
|
|
|
4258
|
+
const dev = cmdOpts.dev === true;
|
|
4259
|
+
applyServeBundleEnv(dev);
|
|
4260
|
+
|
|
4241
4261
|
if (cmdOpts.detach) {
|
|
4242
4262
|
const port = parsePositiveInt("port", cmdOpts.port);
|
|
4243
4263
|
await runServeDetach({
|
|
@@ -4245,6 +4265,7 @@ async function handleServeAction(
|
|
|
4245
4265
|
paths,
|
|
4246
4266
|
spawnDetached,
|
|
4247
4267
|
argv: resolveCliArgv(cmd),
|
|
4268
|
+
nodeEnv: resolveServeNodeEnv(dev),
|
|
4248
4269
|
});
|
|
4249
4270
|
return;
|
|
4250
4271
|
}
|
|
@@ -4423,6 +4444,7 @@ interface ServeDetachDeps {
|
|
|
4423
4444
|
* can't taint each other's child argv.
|
|
4424
4445
|
*/
|
|
4425
4446
|
argv: string[];
|
|
4447
|
+
nodeEnv: "development" | "production";
|
|
4426
4448
|
}
|
|
4427
4449
|
|
|
4428
4450
|
async function runServeDetach(deps: ServeDetachDeps): Promise<void> {
|
|
@@ -4432,6 +4454,7 @@ async function runServeDetach(deps: ServeDetachDeps): Promise<void> {
|
|
|
4432
4454
|
const result = await deps.spawnDetached({
|
|
4433
4455
|
kind: "serve",
|
|
4434
4456
|
argv: childArgv,
|
|
4457
|
+
env: { NODE_ENV: deps.nodeEnv },
|
|
4435
4458
|
pidFile: deps.paths.pidFile,
|
|
4436
4459
|
logFile: deps.paths.logFile,
|
|
4437
4460
|
port: deps.port,
|
package/src/serve/public/app.tsx
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
lazy,
|
|
3
|
+
Suspense,
|
|
4
|
+
useCallback,
|
|
5
|
+
useEffect,
|
|
6
|
+
useMemo,
|
|
7
|
+
useState,
|
|
8
|
+
} from "react";
|
|
2
9
|
import { createRoot } from "react-dom/client";
|
|
3
10
|
|
|
4
11
|
import { HelpButton } from "./components/HelpButton";
|
|
5
|
-
import { QuickSwitcher } from "./components/QuickSwitcher";
|
|
6
|
-
import { ShortcutHelpModal } from "./components/ShortcutHelpModal";
|
|
7
12
|
import { WorkspaceTabs } from "./components/WorkspaceTabs";
|
|
8
13
|
import { CaptureModalProvider, useCaptureModal } from "./hooks/useCaptureModal";
|
|
9
14
|
import { useKeyboardShortcuts } from "./hooks/useKeyboardShortcuts";
|
|
@@ -21,17 +26,28 @@ import {
|
|
|
21
26
|
updateActiveTabBrowseState,
|
|
22
27
|
type WorkspaceState,
|
|
23
28
|
} from "./lib/workspace-tabs";
|
|
24
|
-
import Ask from "./pages/Ask";
|
|
25
|
-
import Browse from "./pages/Browse";
|
|
26
29
|
import ClipperPairing from "./pages/ClipperPairing";
|
|
27
|
-
import Collections from "./pages/Collections";
|
|
28
|
-
import Connectors from "./pages/Connectors";
|
|
29
30
|
import Dashboard from "./pages/Dashboard";
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
import
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
|
|
32
|
+
const QuickSwitcher = lazy(() =>
|
|
33
|
+
import("./components/QuickSwitcher").then((module) => ({
|
|
34
|
+
default: module.QuickSwitcher,
|
|
35
|
+
}))
|
|
36
|
+
);
|
|
37
|
+
const ShortcutHelpModal = lazy(() =>
|
|
38
|
+
import("./components/ShortcutHelpModal").then((module) => ({
|
|
39
|
+
default: module.ShortcutHelpModal,
|
|
40
|
+
}))
|
|
41
|
+
);
|
|
42
|
+
const Search = lazy(() => import("./pages/Search"));
|
|
43
|
+
const Browse = lazy(() => import("./pages/Browse"));
|
|
44
|
+
const DocView = lazy(() => import("./pages/DocView"));
|
|
45
|
+
const DocumentEditor = lazy(() => import("./pages/DocumentEditor"));
|
|
46
|
+
const Collections = lazy(() => import("./pages/Collections"));
|
|
47
|
+
const Connectors = lazy(() => import("./pages/Connectors"));
|
|
48
|
+
const Ask = lazy(() => import("./pages/Ask"));
|
|
49
|
+
const GraphView = lazy(() => import("./pages/GraphView"));
|
|
50
|
+
const TraceHistory = lazy(() => import("./pages/TraceHistory"));
|
|
35
51
|
|
|
36
52
|
type Route =
|
|
37
53
|
| "/"
|
|
@@ -155,7 +171,9 @@ function AppContent({
|
|
|
155
171
|
tabs={workspace.tabs}
|
|
156
172
|
/>
|
|
157
173
|
<div className="flex-1">
|
|
158
|
-
<
|
|
174
|
+
<Suspense fallback={null}>
|
|
175
|
+
<Page key={pageKey} location={location} navigate={navigate} />
|
|
176
|
+
</Suspense>
|
|
159
177
|
</div>
|
|
160
178
|
<footer className="border-t border-border/30 bg-background/60 py-6 text-center text-sm backdrop-blur-sm">
|
|
161
179
|
<div className="ornament mx-auto mb-4 max-w-[8rem] text-muted-foreground/20">
|
|
@@ -217,17 +235,19 @@ function AppContent({
|
|
|
217
235
|
</footer>
|
|
218
236
|
</div>
|
|
219
237
|
<HelpButton onClick={() => setShortcutHelpOpen(true)} />
|
|
220
|
-
<
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
238
|
+
<Suspense fallback={null}>
|
|
239
|
+
<QuickSwitcher
|
|
240
|
+
location={location}
|
|
241
|
+
navigate={(to) => navigate(to)}
|
|
242
|
+
onCreateNote={openCapture}
|
|
243
|
+
onOpenChange={setQuickSwitcherOpen}
|
|
244
|
+
open={quickSwitcherOpen}
|
|
245
|
+
/>
|
|
246
|
+
<ShortcutHelpModal
|
|
247
|
+
onOpenChange={setShortcutHelpOpen}
|
|
248
|
+
open={shortcutHelpOpen}
|
|
249
|
+
/>
|
|
250
|
+
</Suspense>
|
|
231
251
|
</>
|
|
232
252
|
);
|
|
233
253
|
}
|
|
@@ -33,14 +33,19 @@ const CodeBlockContext = createContext<CodeBlockContextType>({
|
|
|
33
33
|
code: "",
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
let highlighterPromise: ReturnType<typeof createHighlighter> | null = null;
|
|
37
|
+
|
|
38
|
+
function getHighlighterRuntime(): ReturnType<typeof createHighlighter> {
|
|
39
|
+
highlighterPromise ??= createHighlighter({
|
|
40
|
+
engine: createJavaScriptRegexEngine(),
|
|
41
|
+
langs: ["text"],
|
|
42
|
+
themes: ["one-light", "one-dark-pro"],
|
|
43
|
+
});
|
|
44
|
+
return highlighterPromise;
|
|
45
|
+
}
|
|
41
46
|
|
|
42
47
|
async function getHighlighter(language: BundledLanguage | "text") {
|
|
43
|
-
const highlighter = await
|
|
48
|
+
const highlighter = await getHighlighterRuntime();
|
|
44
49
|
if (!highlighter.getLoadedLanguages().includes(language)) {
|
|
45
50
|
await highlighter.loadLanguage(language);
|
|
46
51
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { BundledLanguage } from "shiki";
|
|
2
|
+
|
|
3
|
+
import { BUNDLED_LANGUAGE_IDS } from "./shiki-language-ids";
|
|
2
4
|
|
|
3
5
|
export type CodeLanguage = BundledLanguage | "text";
|
|
4
6
|
|
|
@@ -41,7 +43,7 @@ export function resolveCodeLanguage(
|
|
|
41
43
|
return "text";
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
if (aliased
|
|
46
|
+
if (BUNDLED_LANGUAGE_IDS.has(aliased)) {
|
|
45
47
|
return aliased as BundledLanguage;
|
|
46
48
|
}
|
|
47
49
|
|