@opencode/ui 0.0.0-dev-21507 → 0.0.0-dev-21524

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.
@@ -0,0 +1,68 @@
1
+ export declare const OpenCodeTheme: {
2
+ name: string;
3
+ appearance: "dark";
4
+ cssVariables: {
5
+ prefix: string;
6
+ };
7
+ style: {
8
+ "editor.background": string;
9
+ "editor.foreground": string;
10
+ created: string;
11
+ deleted: string;
12
+ modified: string;
13
+ syntax: {
14
+ attribute: string;
15
+ background: string;
16
+ boolean: string;
17
+ comment: string;
18
+ constant: string;
19
+ constructor: string;
20
+ "diff.minus": string;
21
+ "diff.plus": string;
22
+ embedded: string;
23
+ emphasis: string;
24
+ enum: string;
25
+ foreground: string;
26
+ function: string;
27
+ hint: string;
28
+ keyword: string;
29
+ "keyword.operator": string;
30
+ label: string;
31
+ link_text: string;
32
+ link_uri: string;
33
+ namespace: string;
34
+ number: string;
35
+ operator: string;
36
+ predictive: {
37
+ color: string;
38
+ font_style: "italic";
39
+ };
40
+ preproc: string;
41
+ primary: string;
42
+ property: string;
43
+ punctuation: string;
44
+ "punctuation.special": string;
45
+ selector: string;
46
+ "selector.class": string;
47
+ "selector.id": string;
48
+ "selector.pseudo": string;
49
+ string: string;
50
+ "string.escape": string;
51
+ "string.regex": string;
52
+ "string.special": string;
53
+ tag: string;
54
+ "tag.component.jsx": string;
55
+ text: string;
56
+ "text.literal": string;
57
+ title: {
58
+ color: string;
59
+ font_weight: 700;
60
+ };
61
+ type: string;
62
+ variable: string;
63
+ "variable.parameter": string;
64
+ "variable.special": string;
65
+ variant: string;
66
+ };
67
+ };
68
+ };
@@ -1,3 +1,3 @@
1
1
  import type { MarkedExtension } from "marked";
2
- export declare function createMarkdownParser(highlight: (code: string, language: string) => string | Promise<string>): import("marked").Marked<string, string>;
2
+ export declare function createMarkdownParser(): import("marked").Marked<string, string>;
3
3
  export declare const markdownMath: MarkedExtension;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencode/ui",
3
- "version": "0.0.0-dev-21507",
3
+ "version": "0.0.0-dev-21524",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -247,16 +247,15 @@
247
247
  "dependencies": {
248
248
  "@kitlangton/solid-motion": "0.2.2",
249
249
  "@kobalte/core": "0.13.13",
250
- "@pierre/diffs": "1.5.1",
250
+ "@pierre/diffs": "1.6.1",
251
+ "@pierre/highlights": "0.2.0",
251
252
  "@solid-primitives/event-listener": "2.4.6",
252
253
  "@solid-primitives/resize-observer": "2.2.0",
253
254
  "fuzzysort": "3.1.0",
254
255
  "katex": "0.16.47",
255
256
  "marked": "18.0.11",
256
- "marked-shiki": "1.2.1",
257
257
  "motion": "12.34.5",
258
258
  "remeda": "2.26.0",
259
- "shiki": "4.4.3",
260
259
  "solid-list": "0.3.0",
261
260
  "solid-sonner": "0.3.1"
262
261
  },
@@ -0,0 +1,66 @@
1
+ import type { Theme } from "@pierre/highlights"
2
+
3
+ // A Highlights palette: each value names an app CSS variable without its `--`, so code follows the active app theme.
4
+ // Token types are grouped as in Pierre's own `pierre-dark` theme (for example, properties share the variable colour
5
+ // and all punctuation is one muted colour); each group uses the app syntax role with the same meaning.
6
+ // Token names fall back to their parent scope, so `keyword.control` uses `keyword`.
7
+ export const OpenCodeTheme = {
8
+ name: "OpenCode",
9
+ appearance: "dark",
10
+ cssVariables: { prefix: "--" },
11
+ style: {
12
+ "editor.background": "color-background-stronger",
13
+ "editor.foreground": "text-base",
14
+ created: "syntax-diff-add",
15
+ deleted: "syntax-diff-delete",
16
+ modified: "syntax-diff-unknown",
17
+ syntax: {
18
+ attribute: "syntax-property",
19
+ background: "color-background-stronger",
20
+ boolean: "syntax-constant",
21
+ comment: "syntax-comment",
22
+ constant: "syntax-constant",
23
+ constructor: "syntax-type",
24
+ "diff.minus": "syntax-diff-delete",
25
+ "diff.plus": "syntax-diff-add",
26
+ embedded: "text-base",
27
+ emphasis: "text-base",
28
+ enum: "syntax-type",
29
+ foreground: "text-base",
30
+ function: "syntax-primitive",
31
+ hint: "syntax-comment",
32
+ keyword: "syntax-keyword",
33
+ "keyword.operator": "syntax-operator",
34
+ label: "syntax-constant",
35
+ link_text: "syntax-info",
36
+ link_uri: "syntax-keyword",
37
+ namespace: "syntax-constant",
38
+ number: "syntax-constant",
39
+ operator: "syntax-operator",
40
+ predictive: { color: "syntax-comment", font_style: "italic" },
41
+ preproc: "syntax-keyword",
42
+ primary: "syntax-info",
43
+ property: "syntax-variable",
44
+ punctuation: "syntax-punctuation",
45
+ "punctuation.special": "syntax-keyword",
46
+ selector: "syntax-keyword",
47
+ "selector.class": "syntax-property",
48
+ "selector.id": "syntax-primitive",
49
+ "selector.pseudo": "syntax-operator",
50
+ string: "syntax-string",
51
+ "string.escape": "syntax-constant",
52
+ "string.regex": "syntax-regexp",
53
+ "string.special": "syntax-constant",
54
+ tag: "syntax-keyword",
55
+ "tag.component.jsx": "syntax-type",
56
+ text: "text-base",
57
+ "text.literal": "syntax-string",
58
+ title: { color: "syntax-keyword", font_weight: 700 },
59
+ type: "syntax-type",
60
+ variable: "syntax-variable",
61
+ "variable.parameter": "text-base",
62
+ "variable.special": "syntax-constant",
63
+ variant: "syntax-constant",
64
+ },
65
+ },
66
+ } satisfies Theme
@@ -1,10 +1,28 @@
1
+ import { codeToHtml, isSupportedLanguage } from "@pierre/highlights"
1
2
  import katex from "katex"
2
3
  import type { MarkedExtension, Tokens } from "marked"
3
- import markedShiki from "marked-shiki"
4
4
  import { createMarkdownBase } from "./marked-base"
5
+ import { OpenCodeTheme } from "./highlight-theme"
5
6
 
6
- export function createMarkdownParser(highlight: (code: string, language: string) => string | Promise<string>) {
7
- return createMarkdownBase().use(markdownMath, markedShiki({ highlight }))
7
+ export function createMarkdownParser() {
8
+ return createMarkdownBase().use(markdownMath, markdownCode)
9
+ }
10
+
11
+ const decoder = new TextDecoder()
12
+
13
+ // The class keeps the fence's own language, even one without a lexer, so the viewer can label it and render Mermaid.
14
+ const markdownCode: MarkedExtension = {
15
+ renderer: {
16
+ code(token) {
17
+ const language = (token.lang?.match(/^\S*/)?.[0] ?? "").toLowerCase().replace(/[^\w#+.-]/g, "") || "text"
18
+
19
+ const html = decoder.decode(
20
+ codeToHtml(token.text, { lang: isSupportedLanguage(language) ? language : "text", theme: OpenCodeTheme }),
21
+ )
22
+
23
+ return html.replace("<code>", `<code class="language-${language}">`) + "\n"
24
+ },
25
+ },
8
26
  }
9
27
 
10
28
  // `$$...$$` renders as display math anywhere in a line.
@@ -1 +0,0 @@
1
- export declare function registerOpenCodeTheme(): void;
@@ -1,2 +0,0 @@
1
- import type { ThemeRegistrationResolved } from "@pierre/diffs";
2
- export declare const OpenCodeTheme: ThemeRegistrationResolved;
@@ -1,2 +0,0 @@
1
- export { OpenCodeTheme } from "./marked-theme";
2
- export declare const useMarked: () => import("marked").Marked<string, string>, MarkedProvider: (props: import("solid-js").ParentProps<Record<string, any>>) => import("solid-js").JSX.Element;
@@ -1,10 +0,0 @@
1
- import { registerCustomTheme } from "@pierre/diffs"
2
- import { OpenCodeTheme } from "./marked-theme"
3
-
4
- let registered = false
5
-
6
- export function registerOpenCodeTheme() {
7
- if (registered) return
8
- registered = true
9
- registerCustomTheme("OpenCode", () => Promise.resolve(OpenCodeTheme))
10
- }
@@ -1,372 +0,0 @@
1
- import type { ThemeRegistrationResolved } from "@pierre/diffs"
2
-
3
- export const OpenCodeTheme = {
4
- name: "OpenCode",
5
- bg: "var(--color-background-stronger)",
6
- fg: "var(--text-base)",
7
- colors: {
8
- "editor.background": "var(--color-background-stronger)",
9
- "editor.foreground": "var(--text-base)",
10
- "gitDecoration.addedResourceForeground": "var(--syntax-diff-add)",
11
- "gitDecoration.deletedResourceForeground": "var(--syntax-diff-delete)",
12
- "gitDecoration.modifiedResourceForeground": "var(--syntax-diff-unknown)",
13
- // "gitDecoration.conflictingResourceForeground": "#ffca00",
14
- // "gitDecoration.modifiedResourceForeground": "#1a76d4",
15
- // "gitDecoration.untrackedResourceForeground": "#00cab1",
16
- // "gitDecoration.ignoredResourceForeground": "#84848A",
17
- // "terminal.titleForeground": "#adadb1",
18
- // "terminal.titleInactiveForeground": "#84848A",
19
- // "terminal.background": "#141415",
20
- // "terminal.foreground": "#adadb1",
21
- // "terminal.ansiBlack": "#141415",
22
- // "terminal.ansiRed": "#ff2e3f",
23
- // "terminal.ansiGreen": "#0dbe4e",
24
- // "terminal.ansiYellow": "#ffca00",
25
- // "terminal.ansiBlue": "#008cff",
26
- // "terminal.ansiMagenta": "#c635e4",
27
- // "terminal.ansiCyan": "#08c0ef",
28
- // "terminal.ansiWhite": "#c6c6c8",
29
- // "terminal.ansiBrightBlack": "#141415",
30
- // "terminal.ansiBrightRed": "#ff2e3f",
31
- // "terminal.ansiBrightGreen": "#0dbe4e",
32
- // "terminal.ansiBrightYellow": "#ffca00",
33
- // "terminal.ansiBrightBlue": "#008cff",
34
- // "terminal.ansiBrightMagenta": "#c635e4",
35
- // "terminal.ansiBrightCyan": "#08c0ef",
36
- // "terminal.ansiBrightWhite": "#c6c6c8",
37
- },
38
- tokenColors: [
39
- {
40
- scope: ["comment", "punctuation.definition.comment", "string.comment"],
41
- settings: {
42
- foreground: "var(--syntax-comment)",
43
- },
44
- },
45
- {
46
- scope: ["entity.other.attribute-name"],
47
- settings: {
48
- foreground: "var(--syntax-property)", // maybe attribute
49
- },
50
- },
51
- {
52
- scope: ["constant", "entity.name.constant", "variable.other.constant", "variable.language", "entity"],
53
- settings: {
54
- foreground: "var(--syntax-constant)",
55
- },
56
- },
57
- {
58
- scope: ["entity.name", "meta.export.default", "meta.definition.variable"],
59
- settings: {
60
- foreground: "var(--syntax-type)",
61
- },
62
- },
63
- {
64
- scope: ["meta.object.member"],
65
- settings: {
66
- foreground: "var(--syntax-primitive)",
67
- },
68
- },
69
- {
70
- scope: [
71
- "variable.parameter.function",
72
- "meta.jsx.children",
73
- "meta.block",
74
- "meta.tag.attributes",
75
- "entity.name.constant",
76
- "meta.embedded.expression",
77
- "meta.template.expression",
78
- "string.other.begin.yaml",
79
- "string.other.end.yaml",
80
- ],
81
- settings: {
82
- foreground: "var(--syntax-punctuation)",
83
- },
84
- },
85
- {
86
- scope: ["entity.name.function", "support.type.primitive"],
87
- settings: {
88
- foreground: "var(--syntax-primitive)",
89
- },
90
- },
91
- {
92
- scope: ["support.class.component"],
93
- settings: {
94
- foreground: "var(--syntax-type)",
95
- },
96
- },
97
- {
98
- scope: "keyword",
99
- settings: {
100
- foreground: "var(--syntax-keyword)",
101
- },
102
- },
103
- {
104
- scope: [
105
- "keyword.operator",
106
- "storage.type.function.arrow",
107
- "punctuation.separator.key-value.css",
108
- "entity.name.tag.yaml",
109
- "punctuation.separator.key-value.mapping.yaml",
110
- ],
111
- settings: {
112
- foreground: "var(--syntax-operator)",
113
- },
114
- },
115
- {
116
- scope: ["storage", "storage.type"],
117
- settings: {
118
- foreground: "var(--syntax-keyword)",
119
- },
120
- },
121
- {
122
- scope: ["storage.modifier.package", "storage.modifier.import", "storage.type.java"],
123
- settings: {
124
- foreground: "var(--syntax-primitive)",
125
- },
126
- },
127
- {
128
- scope: [
129
- "string",
130
- "punctuation.definition.string",
131
- "string punctuation.section.embedded source",
132
- "entity.name.tag",
133
- ],
134
- settings: {
135
- foreground: "var(--syntax-string)",
136
- },
137
- },
138
- {
139
- scope: "support",
140
- settings: {
141
- foreground: "var(--syntax-primitive)",
142
- },
143
- },
144
- {
145
- scope: ["support.type.object.module", "variable.other.object", "support.type.property-name.css"],
146
- settings: {
147
- foreground: "var(--syntax-object)",
148
- },
149
- },
150
- {
151
- scope: "meta.property-name",
152
- settings: {
153
- foreground: "var(--syntax-property)",
154
- },
155
- },
156
- {
157
- scope: "variable",
158
- settings: {
159
- foreground: "var(--syntax-variable)",
160
- },
161
- },
162
- {
163
- scope: "variable.other",
164
- settings: {
165
- foreground: "var(--syntax-variable)",
166
- },
167
- },
168
- {
169
- scope: [
170
- "invalid.broken",
171
- "invalid.illegal",
172
- "invalid.unimplemented",
173
- "invalid.deprecated",
174
- "message.error",
175
- "markup.deleted",
176
- "meta.diff.header.from-file",
177
- "punctuation.definition.deleted",
178
- "brackethighlighter.unmatched",
179
- "token.error-token",
180
- ],
181
- settings: {
182
- foreground: "var(--syntax-critical)",
183
- },
184
- },
185
- {
186
- scope: "carriage-return",
187
- settings: {
188
- foreground: "var(--syntax-keyword)",
189
- },
190
- },
191
- {
192
- scope: "string source",
193
- settings: {
194
- foreground: "var(--syntax-variable)",
195
- },
196
- },
197
- {
198
- scope: "string variable",
199
- settings: {
200
- foreground: "var(--syntax-constant)",
201
- },
202
- },
203
- {
204
- scope: [
205
- "source.regexp",
206
- "string.regexp",
207
- "string.regexp.character-class",
208
- "string.regexp constant.character.escape",
209
- "string.regexp source.ruby.embedded",
210
- "string.regexp string.regexp.arbitrary-repitition",
211
- "string.regexp constant.character.escape",
212
- ],
213
- settings: {
214
- foreground: "var(--syntax-regexp)",
215
- },
216
- },
217
- {
218
- scope: "support.constant",
219
- settings: {
220
- foreground: "var(--syntax-primitive)",
221
- },
222
- },
223
- {
224
- scope: "support.variable",
225
- settings: {
226
- foreground: "var(--syntax-variable)",
227
- },
228
- },
229
- {
230
- scope: "meta.module-reference",
231
- settings: {
232
- foreground: "var(--syntax-info)",
233
- },
234
- },
235
- {
236
- scope: "punctuation.definition.list.begin.markdown",
237
- settings: {
238
- foreground: "var(--syntax-punctuation)",
239
- },
240
- },
241
- {
242
- scope: ["markup.heading", "markup.heading entity.name"],
243
- settings: {
244
- fontStyle: "bold",
245
- foreground: "var(--syntax-info)",
246
- },
247
- },
248
- {
249
- scope: "markup.quote",
250
- settings: {
251
- foreground: "var(--syntax-info)",
252
- },
253
- },
254
- {
255
- scope: "markup.italic",
256
- settings: {
257
- fontStyle: "italic",
258
- // foreground: "",
259
- },
260
- },
261
- {
262
- scope: "markup.bold",
263
- settings: {
264
- fontStyle: "bold",
265
- foreground: "var(--text-strong)",
266
- },
267
- },
268
- {
269
- scope: [
270
- "markup.raw",
271
- "markup.inserted",
272
- "meta.diff.header.to-file",
273
- "punctuation.definition.inserted",
274
- "markup.changed",
275
- "punctuation.definition.changed",
276
- "markup.ignored",
277
- "markup.untracked",
278
- ],
279
- settings: {
280
- foreground: "var(--text-base)",
281
- },
282
- },
283
- {
284
- scope: "meta.diff.range",
285
- settings: {
286
- fontStyle: "bold",
287
- foreground: "var(--syntax-unknown)",
288
- },
289
- },
290
- {
291
- scope: "meta.diff.header",
292
- settings: {
293
- foreground: "var(--syntax-unknown)",
294
- },
295
- },
296
- {
297
- scope: "meta.separator",
298
- settings: {
299
- fontStyle: "bold",
300
- foreground: "var(--syntax-unknown)",
301
- },
302
- },
303
- {
304
- scope: "meta.output",
305
- settings: {
306
- foreground: "var(--syntax-unknown)",
307
- },
308
- },
309
- {
310
- scope: "meta.export.default",
311
- settings: {
312
- foreground: "var(--syntax-unknown)",
313
- },
314
- },
315
- {
316
- scope: [
317
- "brackethighlighter.tag",
318
- "brackethighlighter.curly",
319
- "brackethighlighter.round",
320
- "brackethighlighter.square",
321
- "brackethighlighter.angle",
322
- "brackethighlighter.quote",
323
- ],
324
- settings: {
325
- foreground: "var(--syntax-unknown)",
326
- },
327
- },
328
- {
329
- scope: ["constant.other.reference.link", "string.other.link"],
330
- settings: {
331
- fontStyle: "underline",
332
- foreground: "var(--syntax-unknown)",
333
- },
334
- },
335
- {
336
- scope: "token.info-token",
337
- settings: {
338
- foreground: "var(--syntax-info)",
339
- },
340
- },
341
- {
342
- scope: "token.warn-token",
343
- settings: {
344
- foreground: "var(--syntax-warning)",
345
- },
346
- },
347
- {
348
- scope: "token.debug-token",
349
- settings: {
350
- foreground: "var(--syntax-info)",
351
- },
352
- },
353
- ],
354
- semanticTokenColors: {
355
- comment: "var(--syntax-comment)",
356
- string: "var(--syntax-string)",
357
- number: "var(--syntax-constant)",
358
- regexp: "var(--syntax-regexp)",
359
- keyword: "var(--syntax-keyword)",
360
- variable: "var(--syntax-variable)",
361
- parameter: "var(--syntax-variable)",
362
- property: "var(--syntax-property)",
363
- function: "var(--syntax-primitive)",
364
- method: "var(--syntax-primitive)",
365
- type: "var(--syntax-type)",
366
- class: "var(--syntax-type)",
367
- namespace: "var(--syntax-type)",
368
- enumMember: "var(--syntax-primitive)",
369
- "variable.constant": "var(--syntax-constant)",
370
- "variable.defaultLibrary": "var(--syntax-unknown)",
371
- },
372
- } as unknown as ThemeRegistrationResolved
@@ -1,31 +0,0 @@
1
- import { getSharedHighlighter } from "@pierre/diffs"
2
- import { bundledLanguages, type BundledLanguage } from "shiki"
3
- import { createSimpleContext } from "./helper"
4
- import { createMarkdownParser } from "./marked-parser"
5
- import { registerOpenCodeTheme } from "./marked-theme-register"
6
-
7
- export { OpenCodeTheme } from "./marked-theme"
8
-
9
- registerOpenCodeTheme()
10
-
11
- export const { use: useMarked, provider: MarkedProvider } = createSimpleContext({
12
- name: "Marked",
13
- init: () =>
14
- createMarkdownParser(async (code, language) => {
15
- const highlighter = await getSharedHighlighter({
16
- themes: ["OpenCode"],
17
- langs: [],
18
- preferredHighlighter: "shiki-wasm",
19
- })
20
-
21
- const name = language in bundledLanguages ? language : "text"
22
-
23
- if (!highlighter.getLoadedLanguages().includes(name)) await highlighter.loadLanguage(name as BundledLanguage)
24
-
25
- return highlighter.codeToHtml(code, {
26
- lang: name,
27
- theme: "OpenCode",
28
- tabindex: false,
29
- })
30
- }),
31
- })