opencode-mask-j0k3r-dev-rgl 2.0.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.
@@ -0,0 +1,81 @@
1
+ // ─── Arch Linux ASCII Art Assets ──────────────────────────────────────────────
2
+
3
+ // Zone colors for semantic coloring (sidebar)
4
+ export const zoneColors = {
5
+ spike: "#ff2d78", // hot pink — top spike
6
+ arch: "#00c8ff", // neon blue — upper arch
7
+ bridge: "#9d4edd", // purple — lower bridge
8
+ base: "#4dd8ff", // neon blue2 — base feet
9
+ } as const
10
+
11
+ // ─── Home screen logo (large, prominent) ──────────────────────────────────────
12
+ //
13
+ // /\
14
+ // / \
15
+ // / / \
16
+ // / / \
17
+ // / / \
18
+ // /_/ \
19
+ // _/ \_
20
+ // / \
21
+ // / .______, \
22
+ // / | | \
23
+ // / |______| \
24
+ // / \
25
+ // / \
26
+ // /____________________________\
27
+ //
28
+ export const archLogoHome: string[] = [
29
+ " /\\",
30
+ " / \\",
31
+ " / / \\",
32
+ " / / \\",
33
+ " / / \\",
34
+ " /_/ \\",
35
+ " _/ \\_",
36
+ " / \\",
37
+ " / .______, \\",
38
+ " / | | \\",
39
+ " / |______| \\",
40
+ " / \\",
41
+ " / \\",
42
+ " /____________________________\\",
43
+ ]
44
+
45
+ // Line-to-zone mapping for home logo coloring
46
+ export const homeLogoZones: ("spike" | "arch" | "bridge" | "base")[] = [
47
+ "spike", // line 0: /\
48
+ "spike", // line 1: / \
49
+ "arch", // line 2: / / \
50
+ "arch", // line 3: / / \
51
+ "arch", // line 4: / / \
52
+ "arch", // line 5: /_/ \
53
+ "bridge", // line 6: _/ \_
54
+ "bridge", // line 7: / \
55
+ "bridge", // line 8: / .______, \
56
+ "bridge", // line 9: / | | \
57
+ "bridge", // line 10: / |______| \
58
+ "base", // line 11: / \
59
+ "base", // line 12: / \
60
+ "base", // line 13: /____________________________\
61
+ ]
62
+
63
+ // ─── Sidebar logo (compact) ──────────────────────────────────────────────────
64
+ export const archLogoSidebar: string[] = [
65
+ " /\\",
66
+ " / \\",
67
+ " / /\\ \\",
68
+ " / / \\ \\",
69
+ " / / \\ \\",
70
+ " /_/ \\_\\",
71
+ ]
72
+
73
+ // Line-to-zone mapping for sidebar logo
74
+ export const sidebarLogoZones: ("spike" | "arch" | "bridge")[] = [
75
+ "spike", // line 0
76
+ "spike", // line 1
77
+ "arch", // line 2
78
+ "arch", // line 3
79
+ "bridge", // line 4
80
+ "bridge", // line 5
81
+ ]
package/components.tsx ADDED
@@ -0,0 +1,94 @@
1
+ // @ts-nocheck
2
+ /** @jsxImportSource @opentui/solid */
3
+ import type { TuiThemeCurrent } from "@opencode-ai/plugin/tui"
4
+ import type { Cfg } from "./config"
5
+ import { getOSName, getProviders } from "./detection"
6
+ import {
7
+ archLogoHome,
8
+ homeLogoZones,
9
+ archLogoSidebar,
10
+ sidebarLogoZones,
11
+ zoneColors,
12
+ } from "./ascii-frames"
13
+
14
+ // ─── Home screen: Large Arch Linux logo + legend ─────────────────────────────
15
+ export const HomeLogo = (props: { theme: TuiThemeCurrent }) => {
16
+ const t = props.theme
17
+
18
+ return (
19
+ <box flexDirection="column" alignItems="center">
20
+ {/* Arch Linux logo — zone-colored */}
21
+ {archLogoHome.map((line, i) => {
22
+ const zone = homeLogoZones[i]
23
+ const color = zoneColors[zone] || t.primary
24
+ return <text fg={color}>{line}</text>
25
+ })}
26
+
27
+ {/* Legend: j0k3r-dev-rgl@latest */}
28
+ <text> </text>
29
+ <box flexDirection="row" gap={0}>
30
+ <text fg="#ff2d78" bold={true}>j0k3r</text>
31
+ <text fg="#9d4edd">-</text>
32
+ <text fg="#00c8ff" bold={true}>dev</text>
33
+ <text fg="#9d4edd">-</text>
34
+ <text fg="#4dd8ff" bold={true}>rgl</text>
35
+ <text fg="#9d4edd">@</text>
36
+ <text fg="#ffd166" bold={true}>latest</text>
37
+ </box>
38
+
39
+ {/* Subtle separator */}
40
+ <box flexDirection="row" gap={0} marginTop={1}>
41
+ <text fg={t.textMuted} dimColor={true}>╭ </text>
42
+ <text fg={t.textMuted}>arch linux </text>
43
+ <text fg={t.textMuted} dimColor={true}>·</text>
44
+ <text fg={t.textMuted}> opencode </text>
45
+ <text fg={t.textMuted} dimColor={true}>╮</text>
46
+ </box>
47
+
48
+ <text> </text>
49
+ </box>
50
+ )
51
+ }
52
+
53
+ // ─── Sidebar: Compact Arch logo ──────────────────────────────────────────────
54
+ export const SidebarArch = (props: { theme: TuiThemeCurrent; config: Cfg }) => {
55
+ if (!props.config.show_sidebar) return null
56
+
57
+ return (
58
+ <box flexDirection="column" alignItems="center">
59
+ {/* Compact Arch logo — zone-colored */}
60
+ {archLogoSidebar.map((line, i) => {
61
+ const zone = sidebarLogoZones[i]
62
+ const color = zoneColors[zone] || props.theme.primary
63
+ return <text fg={color}>{line.padEnd(14, " ")}</text>
64
+ })}
65
+
66
+ {/* Compact label */}
67
+ <text fg={props.theme.textMuted}>j0k3r@latest</text>
68
+ <text> </text>
69
+ </box>
70
+ )
71
+ }
72
+
73
+ // ─── Environment detection line ──────────────────────────────────────────────
74
+ export const DetectedEnv = (props: {
75
+ theme: TuiThemeCurrent
76
+ providers: ReadonlyArray<{ id: string; name: string }> | undefined
77
+ config: Cfg
78
+ }) => {
79
+ if (!props.config.show_detected) return null
80
+
81
+ const os = props.config.show_os ? getOSName() : null
82
+ const providers = props.config.show_providers ? getProviders(props.providers) : null
83
+
84
+ if (!os && !providers) return null
85
+
86
+ return (
87
+ <box flexDirection="row" gap={1}>
88
+ <text fg={props.theme.textMuted}>detected:</text>
89
+ {os && <text fg={props.theme.text}>{os}</text>}
90
+ {os && providers && <text fg={props.theme.textMuted}>·</text>}
91
+ {providers && <text fg={props.theme.text}>{providers}</text>}
92
+ </box>
93
+ )
94
+ }
package/config.ts ADDED
@@ -0,0 +1,34 @@
1
+ // ─── Configuration types and parsing helpers ──────────────────────────────────
2
+
3
+ export type Cfg = {
4
+ enabled: boolean
5
+ theme: string
6
+ set_theme: boolean
7
+ show_detected: boolean
8
+ show_os: boolean
9
+ show_providers: boolean
10
+ show_sidebar: boolean
11
+ }
12
+
13
+ const pick = (value: unknown, fallback: string): string => {
14
+ if (typeof value !== "string") return fallback
15
+ if (!value.trim()) return fallback
16
+ return value
17
+ }
18
+
19
+ const bool = (value: unknown, fallback: boolean): boolean => {
20
+ if (typeof value !== "boolean") return fallback
21
+ return value
22
+ }
23
+
24
+ export const cfg = (opts: Record<string, unknown> | undefined): Cfg => {
25
+ return {
26
+ enabled: bool(opts?.enabled, true),
27
+ theme: pick(opts?.theme, "j0k3r-dev-rgl"),
28
+ set_theme: bool(opts?.set_theme, true),
29
+ show_detected: bool(opts?.show_detected, true),
30
+ show_os: bool(opts?.show_os, true),
31
+ show_providers: bool(opts?.show_providers, true),
32
+ show_sidebar: bool(opts?.show_sidebar, true),
33
+ }
34
+ }
package/detection.ts ADDED
@@ -0,0 +1,56 @@
1
+ // ─── OS and provider detection ────────────────────────────────────────────────
2
+
3
+ /**
4
+ * Detects the OS name. On Linux, reads /etc/os-release for distro name.
5
+ */
6
+ export function getOSName(): string {
7
+ try {
8
+ // @ts-ignore — bun/node runtime only
9
+ const platform = process.platform
10
+ if (platform === "darwin") return "macOS"
11
+ if (platform === "win32") return "Windows"
12
+
13
+ // Linux — try to read distro name
14
+ // @ts-ignore
15
+ const fs = require("fs")
16
+ const osRelease = fs.readFileSync("/etc/os-release", "utf8")
17
+ const nameLine = osRelease.split("\n").find((l: string) => l.startsWith("NAME="))
18
+ if (nameLine) {
19
+ return nameLine
20
+ .replace("NAME=", "")
21
+ .replace(/"/g, "")
22
+ .trim()
23
+ }
24
+ return "Linux"
25
+ } catch {
26
+ return "Unknown"
27
+ }
28
+ }
29
+
30
+ // Friendly name mapping for LLM providers
31
+ const PROVIDER_NAMES: Record<string, string> = {
32
+ openai: "OpenAI",
33
+ google: "Google",
34
+ "github-copilot": "Copilot",
35
+ "opencode-go": "OpenCode GO",
36
+ anthropic: "Claude",
37
+ deepseek: "DeepSeek",
38
+ openrouter: "OpenRouter",
39
+ mistral: "Mistral",
40
+ groq: "Groq",
41
+ cohere: "Cohere",
42
+ together: "Together",
43
+ perplexity: "Perplexity",
44
+ }
45
+
46
+ /**
47
+ * Returns a comma-separated list of active provider display names.
48
+ */
49
+ export function getProviders(
50
+ providers: ReadonlyArray<{ id: string; name: string }> | undefined
51
+ ): string | null {
52
+ if (!providers || providers.length === 0) return null
53
+
54
+ const names = providers.map((p) => PROVIDER_NAMES[p.id] ?? p.name ?? p.id)
55
+ return names.join(", ")
56
+ }
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/package.json",
3
+ "name": "opencode-mask-j0k3r-dev-rgl",
4
+ "version": "2.0.0",
5
+ "description": "Arch Linux TUI mask for OpenCode — neon blue + hot pink theme with prominent ASCII logo and j0k3r-dev-rgl@latest legend",
6
+ "type": "module",
7
+ "exports": {
8
+ "./tui": {
9
+ "import": "./tui.tsx",
10
+ "config": {
11
+ "enabled": true,
12
+ "theme": "j0k3r-dev-rgl",
13
+ "set_theme": true,
14
+ "show_detected": true,
15
+ "show_os": true,
16
+ "show_providers": true,
17
+ "show_sidebar": true
18
+ }
19
+ }
20
+ },
21
+ "files": [
22
+ "tui.tsx",
23
+ "config.ts",
24
+ "detection.ts",
25
+ "ascii-frames.ts",
26
+ "components.tsx",
27
+ "themes/j0k3r-dev-rgl.json"
28
+ ],
29
+ "engines": {
30
+ "opencode": ">=1.3.13"
31
+ },
32
+ "peerDependencies": {
33
+ "@opencode-ai/plugin": "*",
34
+ "@opentui/core": "*",
35
+ "@opentui/solid": "*",
36
+ "solid-js": "*"
37
+ },
38
+ "keywords": [
39
+ "opencode",
40
+ "plugin",
41
+ "theme",
42
+ "arch-linux",
43
+ "tui",
44
+ "ascii"
45
+ ],
46
+ "author": "j0k3r",
47
+ "license": "ISC",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/j0k3r/opencode-mask.git"
51
+ }
52
+ }
@@ -0,0 +1,88 @@
1
+ {
2
+ "$schema": "https://opencode.ai/theme.json",
3
+ "defs": {
4
+ "bg0": "#0a0b18",
5
+ "bg1": "#0f1128",
6
+ "bg2": "#161830",
7
+ "bg3": "#1d1f3a",
8
+ "bg4": "#252847",
9
+
10
+ "nBlue": "#00c8ff",
11
+ "nBlue2": "#4dd8ff",
12
+ "nBlue3": "#99e9ff",
13
+
14
+ "hPink": "#ff2d78",
15
+ "hPink2": "#ff6b9d",
16
+ "hPink3": "#ffb3cc",
17
+
18
+ "purple": "#9d4edd",
19
+ "purple2": "#c77dff",
20
+ "purple3": "#e0b3ff",
21
+
22
+ "fg0": "#e8eaf6",
23
+ "fg1": "#9399c9",
24
+ "fg2": "#5c6bc0",
25
+
26
+ "success": "#00e5a0",
27
+ "warning": "#ffd166",
28
+ "error": "#ff2d78"
29
+ },
30
+ "theme": {
31
+ "primary": { "dark": "nBlue", "light": "nBlue" },
32
+ "secondary": { "dark": "hPink", "light": "hPink" },
33
+ "accent": { "dark": "purple", "light": "purple" },
34
+ "error": { "dark": "error", "light": "error" },
35
+ "warning": { "dark": "warning", "light": "warning" },
36
+ "success": { "dark": "success", "light": "success" },
37
+ "info": { "dark": "nBlue", "light": "nBlue" },
38
+
39
+ "text": { "dark": "fg0", "light": "bg0" },
40
+ "textMuted": { "dark": "fg1", "light": "fg2" },
41
+
42
+ "background": { "dark": "bg0", "light": "#f5f6ff" },
43
+ "backgroundPanel": { "dark": "bg1", "light": "#ecedff" },
44
+ "backgroundElement": { "dark": "bg2", "light": "#e2e4ff" },
45
+
46
+ "border": { "dark": "bg3", "light": "#c5c8e8" },
47
+ "borderActive": { "dark": "nBlue", "light": "nBlue" },
48
+ "borderSubtle": { "dark": "bg2", "light": "#d5d8f0" },
49
+
50
+ "diffAdded": { "dark": "success", "light": "success" },
51
+ "diffRemoved": { "dark": "error", "light": "error" },
52
+ "diffContext": { "dark": "fg1", "light": "fg2" },
53
+ "diffHunkHeader": { "dark": "purple", "light": "purple" },
54
+ "diffHighlightAdded": { "dark": "success", "light": "success" },
55
+ "diffHighlightRemoved": { "dark": "error", "light": "error" },
56
+ "diffAddedBg": { "dark": "bg2", "light": "#d0fff0" },
57
+ "diffRemovedBg": { "dark": "bg2", "light": "#ffd0e0" },
58
+ "diffContextBg": { "dark": "bg1", "light": "#ecedff" },
59
+ "diffLineNumber": { "dark": "fg2", "light": "fg2" },
60
+ "diffAddedLineNumberBg": { "dark": "bg3", "light": "#b0ffe0" },
61
+ "diffRemovedLineNumberBg": { "dark": "bg3", "light": "#ffb0cc" },
62
+
63
+ "markdownText": { "dark": "fg0", "light": "bg0" },
64
+ "markdownHeading": { "dark": "nBlue", "light": "nBlue" },
65
+ "markdownLink": { "dark": "hPink", "light": "hPink" },
66
+ "markdownLinkText": { "dark": "nBlue2", "light": "nBlue" },
67
+ "markdownCode": { "dark": "purple2", "light": "purple" },
68
+ "markdownBlockQuote": { "dark": "fg2", "light": "fg2" },
69
+ "markdownEmph": { "dark": "hPink2", "light": "hPink" },
70
+ "markdownStrong": { "dark": "nBlue", "light": "nBlue" },
71
+ "markdownHorizontalRule": { "dark": "bg4", "light": "fg2" },
72
+ "markdownListItem": { "dark": "nBlue", "light": "nBlue" },
73
+ "markdownListEnumeration": { "dark": "purple", "light": "purple" },
74
+ "markdownImage": { "dark": "hPink", "light": "hPink" },
75
+ "markdownImageText": { "dark": "nBlue2", "light": "nBlue" },
76
+ "markdownCodeBlock": { "dark": "fg0", "light": "bg0" },
77
+
78
+ "syntaxComment": { "dark": "fg2", "light": "fg2" },
79
+ "syntaxKeyword": { "dark": "hPink", "light": "hPink" },
80
+ "syntaxFunction": { "dark": "nBlue", "light": "nBlue" },
81
+ "syntaxVariable": { "dark": "fg0", "light": "bg0" },
82
+ "syntaxString": { "dark": "nBlue2", "light": "nBlue" },
83
+ "syntaxNumber": { "dark": "purple2", "light": "purple" },
84
+ "syntaxType": { "dark": "hPink2", "light": "hPink" },
85
+ "syntaxOperator": { "dark": "hPink", "light": "hPink" },
86
+ "syntaxPunctuation": { "dark": "fg1", "light": "fg2" }
87
+ }
88
+ }
package/tui.tsx ADDED
@@ -0,0 +1,66 @@
1
+ // @ts-nocheck
2
+ /** @jsxImportSource @opentui/solid */
3
+ import type { TuiPlugin, TuiPluginModule } from "@opencode-ai/plugin/tui"
4
+ import { cfg } from "./config"
5
+ import { HomeLogo, SidebarArch, DetectedEnv } from "./components"
6
+
7
+ const id = "j0k3r-dev-rgl"
8
+
9
+ const rec = (value: unknown) => {
10
+ if (!value || typeof value !== "object" || Array.isArray(value)) return
11
+ return Object.fromEntries(Object.entries(value))
12
+ }
13
+
14
+ const tui: TuiPlugin = async (api, options) => {
15
+ const boot = cfg(rec(options))
16
+ if (!boot.enabled) return
17
+
18
+ // Theme setup (wrapped in try-catch)
19
+ try {
20
+ await api.theme.install("./themes/j0k3r-dev-rgl.json")
21
+ if (boot.set_theme) {
22
+ api.theme.set(boot.theme)
23
+ }
24
+ } catch (error) {
25
+ console.error("[j0k3r-dev-rgl] Theme setup failed:", error)
26
+ }
27
+
28
+ // Slot registration
29
+ api.slots.register({
30
+ slots: {
31
+ // Home screen: large Arch logo + j0k3r-dev-rgl@latest legend
32
+ home_logo(ctx) {
33
+ return <HomeLogo theme={ctx.theme.current} />
34
+ },
35
+
36
+ // Below the prompt: environment detection
37
+ home_bottom(ctx) {
38
+ return <DetectedEnv theme={ctx.theme.current} providers={api.state.provider} config={boot} />
39
+ },
40
+
41
+ // Sidebar: compact Arch logo
42
+ sidebar_content(ctx) {
43
+ return <SidebarArch theme={ctx.theme.current} config={boot} />
44
+ },
45
+
46
+ // Prompt bar right side: session info
47
+ session_prompt_right(ctx, value) {
48
+ const t = ctx.theme.current
49
+ return (
50
+ <text fg={t.textMuted}>
51
+ <span style={{ fg: "#ff2d78" }}>j0k3r</span>
52
+ <span style={{ fg: "#9d4edd" }}>@</span>
53
+ {(value.session_id ?? "").slice(0, 6)}
54
+ </text>
55
+ )
56
+ },
57
+ },
58
+ })
59
+ }
60
+
61
+ const plugin: TuiPluginModule & { id: string } = {
62
+ id,
63
+ tui,
64
+ }
65
+
66
+ export default plugin