infinicode 1.0.0 → 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.
Files changed (157) hide show
  1. package/.opencode/plugins/home-logo-animation.tsx +120 -0
  2. package/.opencode/plugins/routing-mode-display.tsx +135 -0
  3. package/.opencode/themes/infinibot-gold.json +222 -0
  4. package/.opencode/tui.json +8 -0
  5. package/README.md +527 -75
  6. package/dist/ascii-video-animation.d.ts +2 -0
  7. package/dist/ascii-video-animation.js +243 -0
  8. package/dist/cli.js +195 -50
  9. package/dist/commands/console.d.ts +6 -0
  10. package/dist/commands/console.js +111 -0
  11. package/dist/commands/kernel-setup.d.ts +3 -0
  12. package/dist/commands/kernel-setup.js +303 -0
  13. package/dist/commands/mcp.d.ts +12 -0
  14. package/dist/commands/mcp.js +96 -0
  15. package/dist/commands/mission.d.ts +16 -0
  16. package/dist/commands/mission.js +301 -0
  17. package/dist/commands/models.d.ts +3 -1
  18. package/dist/commands/models.js +111 -55
  19. package/dist/commands/providers.d.ts +6 -0
  20. package/dist/commands/providers.js +95 -0
  21. package/dist/commands/run.d.ts +2 -1
  22. package/dist/commands/run.js +349 -59
  23. package/dist/commands/serve.d.ts +18 -0
  24. package/dist/commands/serve.js +127 -0
  25. package/dist/commands/setup.d.ts +1 -1
  26. package/dist/commands/setup.js +77 -44
  27. package/dist/commands/status.d.ts +2 -1
  28. package/dist/commands/status.js +46 -30
  29. package/dist/commands/workers.d.ts +5 -0
  30. package/dist/commands/workers.js +103 -0
  31. package/dist/kernel/autonomy/goal-loop.d.ts +49 -0
  32. package/dist/kernel/autonomy/goal-loop.js +113 -0
  33. package/dist/kernel/autonomy/index.d.ts +8 -0
  34. package/dist/kernel/autonomy/index.js +7 -0
  35. package/dist/kernel/browser/browser-controller.d.ts +57 -0
  36. package/dist/kernel/browser/browser-controller.js +175 -0
  37. package/dist/kernel/checkpoint-engine.d.ts +17 -0
  38. package/dist/kernel/checkpoint-engine.js +128 -0
  39. package/dist/kernel/command-system.d.ts +37 -0
  40. package/dist/kernel/command-system.js +239 -0
  41. package/dist/kernel/config-schema.d.ts +53 -0
  42. package/dist/kernel/config-schema.js +36 -0
  43. package/dist/kernel/event-bus.d.ts +19 -0
  44. package/dist/kernel/event-bus.js +65 -0
  45. package/dist/kernel/federation/auto-update.d.ts +36 -0
  46. package/dist/kernel/federation/auto-update.js +57 -0
  47. package/dist/kernel/federation/compute-router.d.ts +27 -0
  48. package/dist/kernel/federation/compute-router.js +44 -0
  49. package/dist/kernel/federation/config-sync.d.ts +33 -0
  50. package/dist/kernel/federation/config-sync.js +37 -0
  51. package/dist/kernel/federation/discovery.d.ts +11 -0
  52. package/dist/kernel/federation/discovery.js +44 -0
  53. package/dist/kernel/federation/event-bridge.d.ts +30 -0
  54. package/dist/kernel/federation/event-bridge.js +61 -0
  55. package/dist/kernel/federation/federation-plugin.d.ts +24 -0
  56. package/dist/kernel/federation/federation-plugin.js +35 -0
  57. package/dist/kernel/federation/federation.d.ts +126 -0
  58. package/dist/kernel/federation/federation.js +335 -0
  59. package/dist/kernel/federation/index.d.ts +31 -0
  60. package/dist/kernel/federation/index.js +23 -0
  61. package/dist/kernel/federation/moltfed-adapter.d.ts +30 -0
  62. package/dist/kernel/federation/moltfed-adapter.js +52 -0
  63. package/dist/kernel/federation/moltfed-connector.d.ts +98 -0
  64. package/dist/kernel/federation/moltfed-connector.js +193 -0
  65. package/dist/kernel/federation/node-identity.d.ts +19 -0
  66. package/dist/kernel/federation/node-identity.js +86 -0
  67. package/dist/kernel/federation/peer-mesh.d.ts +46 -0
  68. package/dist/kernel/federation/peer-mesh.js +117 -0
  69. package/dist/kernel/federation/protocol.d.ts +20 -0
  70. package/dist/kernel/federation/protocol.js +61 -0
  71. package/dist/kernel/federation/role-context.d.ts +5 -0
  72. package/dist/kernel/federation/role-context.js +45 -0
  73. package/dist/kernel/federation/telemetry.d.ts +21 -0
  74. package/dist/kernel/federation/telemetry.js +138 -0
  75. package/dist/kernel/federation/transport-http.d.ts +44 -0
  76. package/dist/kernel/federation/transport-http.js +207 -0
  77. package/dist/kernel/federation/types.d.ts +212 -0
  78. package/dist/kernel/federation/types.js +3 -0
  79. package/dist/kernel/free-providers.d.ts +28 -0
  80. package/dist/kernel/free-providers.js +162 -0
  81. package/dist/kernel/frontend-scoring.d.ts +21 -0
  82. package/dist/kernel/frontend-scoring.js +125 -0
  83. package/dist/kernel/index.d.ts +63 -0
  84. package/dist/kernel/index.js +45 -0
  85. package/dist/kernel/kernel.d.ts +75 -0
  86. package/dist/kernel/kernel.js +223 -0
  87. package/dist/kernel/logger.d.ts +18 -0
  88. package/dist/kernel/logger.js +26 -0
  89. package/dist/kernel/mcp/index.d.ts +9 -0
  90. package/dist/kernel/mcp/index.js +8 -0
  91. package/dist/kernel/mcp/mcp-server.d.ts +27 -0
  92. package/dist/kernel/mcp/mcp-server.js +178 -0
  93. package/dist/kernel/mission-engine.d.ts +42 -0
  94. package/dist/kernel/mission-engine.js +160 -0
  95. package/dist/kernel/orchestrator.d.ts +51 -0
  96. package/dist/kernel/orchestrator.js +226 -0
  97. package/dist/kernel/plugin-manager.d.ts +28 -0
  98. package/dist/kernel/plugin-manager.js +76 -0
  99. package/dist/kernel/plugins/browser-plugin.d.ts +22 -0
  100. package/dist/kernel/plugins/browser-plugin.js +34 -0
  101. package/dist/kernel/plugins/dashboard-plugin.d.ts +17 -0
  102. package/dist/kernel/plugins/dashboard-plugin.js +72 -0
  103. package/dist/kernel/plugins/discord-plugin.d.ts +11 -0
  104. package/dist/kernel/plugins/discord-plugin.js +35 -0
  105. package/dist/kernel/plugins/metrics-plugin.d.ts +33 -0
  106. package/dist/kernel/plugins/metrics-plugin.js +86 -0
  107. package/dist/kernel/plugins/search-plugin.d.ts +17 -0
  108. package/dist/kernel/plugins/search-plugin.js +20 -0
  109. package/dist/kernel/plugins/slack-plugin.d.ts +11 -0
  110. package/dist/kernel/plugins/slack-plugin.js +35 -0
  111. package/dist/kernel/plugins/telegram-plugin.d.ts +20 -0
  112. package/dist/kernel/plugins/telegram-plugin.js +122 -0
  113. package/dist/kernel/policies.d.ts +33 -0
  114. package/dist/kernel/policies.js +105 -0
  115. package/dist/kernel/provider-discovery.d.ts +41 -0
  116. package/dist/kernel/provider-discovery.js +179 -0
  117. package/dist/kernel/provider-manager.d.ts +38 -0
  118. package/dist/kernel/provider-manager.js +206 -0
  119. package/dist/kernel/provider-url.d.ts +18 -0
  120. package/dist/kernel/provider-url.js +45 -0
  121. package/dist/kernel/providers/gemini-provider.d.ts +43 -0
  122. package/dist/kernel/providers/gemini-provider.js +203 -0
  123. package/dist/kernel/providers/ollama-provider.d.ts +44 -0
  124. package/dist/kernel/providers/ollama-provider.js +241 -0
  125. package/dist/kernel/providers/openai-compatible-provider.d.ts +43 -0
  126. package/dist/kernel/providers/openai-compatible-provider.js +233 -0
  127. package/dist/kernel/recovery-manager.d.ts +38 -0
  128. package/dist/kernel/recovery-manager.js +156 -0
  129. package/dist/kernel/router.d.ts +44 -0
  130. package/dist/kernel/router.js +222 -0
  131. package/dist/kernel/sample-missions.d.ts +11 -0
  132. package/dist/kernel/sample-missions.js +132 -0
  133. package/dist/kernel/scheduler.d.ts +30 -0
  134. package/dist/kernel/scheduler.js +147 -0
  135. package/dist/kernel/sdk/harness-sdk.d.ts +37 -0
  136. package/dist/kernel/sdk/harness-sdk.js +48 -0
  137. package/dist/kernel/sdk/plugin-sdk.d.ts +27 -0
  138. package/dist/kernel/sdk/plugin-sdk.js +40 -0
  139. package/dist/kernel/search/search-controller.d.ts +32 -0
  140. package/dist/kernel/search/search-controller.js +141 -0
  141. package/dist/kernel/setup.d.ts +13 -0
  142. package/dist/kernel/setup.js +59 -0
  143. package/dist/kernel/types.d.ts +479 -0
  144. package/dist/kernel/types.js +7 -0
  145. package/dist/kernel/verification-engine.d.ts +33 -0
  146. package/dist/kernel/verification-engine.js +287 -0
  147. package/dist/kernel/worker-runtime.d.ts +66 -0
  148. package/dist/kernel/worker-runtime.js +261 -0
  149. package/dist/kernel/workers/browser-worker.d.ts +6 -0
  150. package/dist/kernel/workers/browser-worker.js +92 -0
  151. package/dist/kernel/workers/builtin-workers.d.ts +20 -0
  152. package/dist/kernel/workers/builtin-workers.js +120 -0
  153. package/dist/kernel/workers/research-worker.d.ts +5 -0
  154. package/dist/kernel/workers/research-worker.js +90 -0
  155. package/dist/prompt-ascii-video-animation.d.ts +2 -0
  156. package/dist/prompt-ascii-video-animation.js +243 -0
  157. package/package.json +43 -9
@@ -0,0 +1,120 @@
1
+ import { createSignal, onCleanup } from "solid-js";
2
+ import { ASCII_VIDEO_FPS, ASCII_VIDEO_FRAMES } from "../../dist/ascii-video-animation.js";
3
+
4
+ // On the home screen the logo slot shares the column with (above it) a flexible
5
+ // spacer + a 4-row gap, and (below it) the prompt box and footer. Those lower
6
+ // elements do not shrink, so we must keep the logo within `terminalHeight minus
7
+ // this reserve` or its top/bottom gets clipped off the screen.
8
+ const VERTICAL_CHROME_ROWS = 9;
9
+ // Fallbacks used only before the renderer reports a real size.
10
+ const FALLBACK_COLUMNS = 120;
11
+ const FALLBACK_ROWS = 40;
12
+
13
+ type BoundingBox = {
14
+ lines: string[];
15
+ left: number;
16
+ width: number;
17
+ };
18
+
19
+ function boundingBox(frame: string): BoundingBox | null {
20
+ const lines = frame.split("\n");
21
+ const nonEmptyRows = lines
22
+ .map((line, index) => (line.trim() ? index : -1))
23
+ .filter(index => index >= 0);
24
+
25
+ if (nonEmptyRows.length === 0) return null;
26
+
27
+ const top = nonEmptyRows[0];
28
+ const bottom = nonEmptyRows[nonEmptyRows.length - 1];
29
+ const visibleLines = lines.slice(top, bottom + 1).map(line => line.replace(/\s+$/, ""));
30
+
31
+ const left = Math.min(
32
+ ...visibleLines.map(line => (line.length ? line.length - line.trimStart().length : Number.POSITIVE_INFINITY))
33
+ );
34
+ const right = Math.max(...visibleLines.map(line => line.length), 0);
35
+
36
+ return { lines: visibleLines, left: Number.isFinite(left) ? left : 0, width: Math.max(0, right - left) };
37
+ }
38
+
39
+ // Sample `count` evenly spaced indices across a span of `length` items.
40
+ function sampleIndices(length: number, count: number): number[] {
41
+ if (count >= length) return Array.from({ length }, (_, index) => index);
42
+ const indices: number[] = [];
43
+ for (let i = 0; i < count; i++) {
44
+ indices.push(Math.min(length - 1, Math.round((i * (length - 1)) / (count - 1 || 1))));
45
+ }
46
+ return indices;
47
+ }
48
+
49
+ function fitFrame(frame: string, terminalColumns: number, terminalRows: number): string {
50
+ const box = boundingBox(frame);
51
+ if (!box) return "";
52
+
53
+ const { lines, left, width } = box;
54
+ const height = lines.length;
55
+
56
+ const availableColumns = Math.max(20, terminalColumns - 2);
57
+ const availableRows = Math.max(6, terminalRows - VERTICAL_CHROME_ROWS);
58
+
59
+ // Single uniform scale so the whole logo fits without distorting its aspect.
60
+ const scale = Math.min(1, availableColumns / Math.max(1, width), availableRows / height);
61
+ const targetHeight = Math.max(1, Math.round(height * scale));
62
+ const targetWidth = Math.max(1, Math.round(width * scale));
63
+
64
+ const rowIndices = sampleIndices(height, targetHeight);
65
+ const columnIndices = sampleIndices(width, targetWidth);
66
+
67
+ return rowIndices
68
+ .map(rowIndex => {
69
+ const line = lines[rowIndex];
70
+ return columnIndices
71
+ .map(columnIndex => line[left + columnIndex] ?? " ")
72
+ .join("")
73
+ .replace(/\s+$/, "");
74
+ })
75
+ .join("\n");
76
+ }
77
+
78
+ function AnimatedLogo(props: { renderer?: any }) {
79
+ const [frameIndex, setFrameIndex] = createSignal(0);
80
+
81
+ // Track the real terminal size from the TUI renderer (process.stdout.rows is
82
+ // unreliable inside the plugin runtime). Re-fit whenever the terminal resizes.
83
+ const renderer = props.renderer;
84
+ const readSize = () => ({
85
+ columns: Math.max(40, renderer?.width ?? process.stdout.columns ?? FALLBACK_COLUMNS),
86
+ rows: Math.max(10, renderer?.height ?? process.stdout.rows ?? FALLBACK_ROWS),
87
+ });
88
+ const [size, setSize] = createSignal(readSize());
89
+
90
+ if (typeof renderer?.on === "function") {
91
+ const onResize = () => setSize(readSize());
92
+ renderer.on("resize", onResize);
93
+ onCleanup(() => {
94
+ if (typeof renderer.off === "function") renderer.off("resize", onResize);
95
+ else if (typeof renderer.removeListener === "function") renderer.removeListener("resize", onResize);
96
+ });
97
+ }
98
+
99
+ const frameDelayMs = Math.max(16, Math.round(1000 / ASCII_VIDEO_FPS));
100
+ const timer = setInterval(() => {
101
+ setFrameIndex(index => (index + 1) % ASCII_VIDEO_FRAMES.length);
102
+ }, frameDelayMs);
103
+ onCleanup(() => clearInterval(timer));
104
+
105
+ return (
106
+ <text fg="#fbbf24">
107
+ {fitFrame(ASCII_VIDEO_FRAMES[frameIndex()] ?? "", size().columns, size().rows)}
108
+ </text>
109
+ );
110
+ }
111
+
112
+ export const tui = async (api: any) => {
113
+ api.slots.register({
114
+ slots: {
115
+ home_logo() {
116
+ return <AnimatedLogo renderer={api.renderer} />;
117
+ },
118
+ },
119
+ });
120
+ };
@@ -0,0 +1,135 @@
1
+ import { createSignal, onCleanup, createMemo } from "solid-js";
2
+ import { existsSync, readFileSync } from "fs";
3
+ import { homedir } from "os";
4
+ import { join } from "path";
5
+
6
+ // ── Config reader (no external deps) ───────────────────────────────────────
7
+
8
+ interface InfinicodeConfig {
9
+ masterUrl: string;
10
+ defaultModel: string;
11
+ policy?: string;
12
+ workerModels?: Record<string, { providerId: string; modelId: string }>;
13
+ cloudProviders?: Array<{ id: string; name: string; enabled: boolean; apiKey?: string }>;
14
+ }
15
+
16
+ function findConfigPath(): string {
17
+ const home = homedir();
18
+ const paths = [
19
+ // Windows — Conf appends "-nodejs" for Node projects
20
+ join(home, "AppData", "Roaming", "infinicode-nodejs", "Config", "config.json"),
21
+ join(home, "AppData", "Roaming", "infinicode", "Config", "config.json"),
22
+ // Linux
23
+ join(home, ".config", "infinicode", "config.json"),
24
+ // macOS
25
+ join(home, "Library", "Preferences", "infinicode", "config.json"),
26
+ ];
27
+ for (const p of paths) {
28
+ if (existsSync(p)) return p;
29
+ }
30
+ return paths[0];
31
+ }
32
+
33
+ function loadConfig(): InfinicodeConfig | null {
34
+ try {
35
+ const path = findConfigPath();
36
+ if (!existsSync(path)) return null;
37
+ return JSON.parse(readFileSync(path, "utf-8")) as InfinicodeConfig;
38
+ } catch {
39
+ return null;
40
+ }
41
+ }
42
+
43
+ // ── Routing info ───────────────────────────────────────────────────────────
44
+
45
+ // Every policy auto-routes across providers except `offline`, which is locked
46
+ // to the local machine — mirrors the kernel router's one locked mode.
47
+ const LOCKED_POLICIES = new Set(["offline"]);
48
+
49
+ interface RoutingBadge {
50
+ glyph: string;
51
+ text: string;
52
+ /** true = actively auto-routing (drives the pulse highlight). */
53
+ active: boolean;
54
+ }
55
+
56
+ function buildRoutingBadge(cfg: InfinicodeConfig | null, tuiModel?: string): RoutingBadge {
57
+ if (!cfg) return { glyph: "◆", text: "AUTO (no config)", active: true };
58
+
59
+ const enabledCloud = (cfg.cloudProviders ?? []).filter((p) => p.enabled && p.apiKey);
60
+ const providerCount = 1 + enabledCloud.length; // ollama + cloud
61
+ const pinned = Object.keys(cfg.workerModels ?? {}).length;
62
+ const policy = cfg.policy ?? "balanced";
63
+ const codingPin = cfg.workerModels?.["coding"];
64
+ const autoModel = codingPin
65
+ ? `${codingPin.providerId}/${codingPin.modelId}`
66
+ : `ollama/${cfg.defaultModel}`;
67
+
68
+ // If the user manually pinned a model in the TUI, that overrides routing.
69
+ if (tuiModel && tuiModel !== autoModel) {
70
+ const [prov, ...rest] = tuiModel.split("/");
71
+ return { glyph: "◇", text: `SINGLE ${prov}/${rest.join("/")}`, active: false };
72
+ }
73
+
74
+ // The one locked mode: offline stays local-only.
75
+ if (LOCKED_POLICIES.has(policy)) {
76
+ return { glyph: "🔒", text: `LOCKED ${policy} (local only)`, active: false };
77
+ }
78
+
79
+ return {
80
+ glyph: "◆",
81
+ text: `AUTO policy=${policy} providers=${providerCount} pins=${pinned}`,
82
+ active: true,
83
+ };
84
+ }
85
+
86
+ // ── Plugin ──────────────────────────────────────────────────────────────────
87
+
88
+ export const tui = async (api: any) => {
89
+ const [cfg] = createSignal(loadConfig());
90
+
91
+ const getTuiModel = (): string | undefined => {
92
+ try {
93
+ return api.state?.config?.model;
94
+ } catch {
95
+ return undefined;
96
+ }
97
+ };
98
+
99
+ const [tuiModel, setTuiModel] = createSignal<string | undefined>(getTuiModel());
100
+
101
+ if (api.event?.on) {
102
+ const unsub = api.event.on("session.next.model_switched", () => {
103
+ setTuiModel(getTuiModel());
104
+ });
105
+ onCleanup(unsub);
106
+ }
107
+
108
+ const badge = createMemo(() => buildRoutingBadge(cfg(), tuiModel()));
109
+
110
+ // Pulse the highlight color while auto-routing is active so the badge reads
111
+ // as "live". Static gold when locked / single-pinned.
112
+ const PULSE = ["#FFD86B", "#FFE9A6", "#F5C542"];
113
+ const [pulse, setPulse] = createSignal(0);
114
+ const timer = setInterval(() => setPulse((i) => (i + 1) % PULSE.length), 600);
115
+ onCleanup(() => clearInterval(timer));
116
+
117
+ const color = () => (badge().active ? PULSE[pulse()] : "#FFD86B");
118
+ const render = () => (
119
+ <text fg={color()}>{`${badge().glyph} ${badge().text}`}</text>
120
+ );
121
+
122
+ api.slots.register({
123
+ slots: {
124
+ // Right of the home prompt — routing badge
125
+ home_prompt_right() {
126
+ return render();
127
+ },
128
+
129
+ // Right of the session prompt — routing badge
130
+ session_prompt_right(props: { session_id: string }) {
131
+ return render();
132
+ },
133
+ },
134
+ });
135
+ };
@@ -0,0 +1,222 @@
1
+ {
2
+ "$schema": "https://opencode.ai/theme.json",
3
+ "defs": {
4
+ "obsidian": "#090703",
5
+ "panel": "#151008",
6
+ "panel2": "#211708",
7
+ "gold0": "#7A420A",
8
+ "gold1": "#B97816",
9
+ "gold2": "#E6B23C",
10
+ "gold3": "#FFD86B",
11
+ "gold4": "#FFF2B8",
12
+ "gold5": "#D08C1F",
13
+ "cream": "#F9E7B0",
14
+ "muted": "#9A7A3B",
15
+ "red": "#FF6B6B",
16
+ "green": "#8FE388",
17
+ "blue": "#78C7FF",
18
+ "purple": "#C79BFF"
19
+ },
20
+ "theme": {
21
+ "primary": {
22
+ "dark": "gold3",
23
+ "light": "gold1"
24
+ },
25
+ "secondary": {
26
+ "dark": "gold2",
27
+ "light": "gold0"
28
+ },
29
+ "accent": {
30
+ "dark": "gold4",
31
+ "light": "gold2"
32
+ },
33
+ "error": {
34
+ "dark": "red",
35
+ "light": "red"
36
+ },
37
+ "warning": {
38
+ "dark": "gold2",
39
+ "light": "gold1"
40
+ },
41
+ "success": {
42
+ "dark": "green",
43
+ "light": "green"
44
+ },
45
+ "info": {
46
+ "dark": "blue",
47
+ "light": "blue"
48
+ },
49
+ "text": {
50
+ "dark": "cream",
51
+ "light": "#231704"
52
+ },
53
+ "textMuted": {
54
+ "dark": "muted",
55
+ "light": "#6E4A12"
56
+ },
57
+ "background": {
58
+ "dark": "obsidian",
59
+ "light": "#FFF8DE"
60
+ },
61
+ "backgroundPanel": {
62
+ "dark": "panel",
63
+ "light": "#F4E5B6"
64
+ },
65
+ "backgroundElement": {
66
+ "dark": "panel2",
67
+ "light": "#E8CB7E"
68
+ },
69
+ "border": {
70
+ "dark": "gold0",
71
+ "light": "gold1"
72
+ },
73
+ "borderActive": {
74
+ "dark": "gold3",
75
+ "light": "gold0"
76
+ },
77
+ "borderSubtle": {
78
+ "dark": "#332106",
79
+ "light": "#D6B260"
80
+ },
81
+ "diffAdded": {
82
+ "dark": "green",
83
+ "light": "green"
84
+ },
85
+ "diffRemoved": {
86
+ "dark": "red",
87
+ "light": "red"
88
+ },
89
+ "diffContext": {
90
+ "dark": "muted",
91
+ "light": "#6E4A12"
92
+ },
93
+ "diffHunkHeader": {
94
+ "dark": "gold2",
95
+ "light": "gold0"
96
+ },
97
+ "diffHighlightAdded": {
98
+ "dark": "green",
99
+ "light": "green"
100
+ },
101
+ "diffHighlightRemoved": {
102
+ "dark": "red",
103
+ "light": "red"
104
+ },
105
+ "diffAddedBg": {
106
+ "dark": "#102112",
107
+ "light": "#DAF0D6"
108
+ },
109
+ "diffRemovedBg": {
110
+ "dark": "#2A1010",
111
+ "light": "#F5D6D6"
112
+ },
113
+ "diffContextBg": {
114
+ "dark": "panel",
115
+ "light": "#F4E5B6"
116
+ },
117
+ "diffLineNumber": {
118
+ "dark": "muted",
119
+ "light": "#8A641D"
120
+ },
121
+ "diffAddedLineNumberBg": {
122
+ "dark": "#102112",
123
+ "light": "#DAF0D6"
124
+ },
125
+ "diffRemovedLineNumberBg": {
126
+ "dark": "#2A1010",
127
+ "light": "#F5D6D6"
128
+ },
129
+ "markdownText": {
130
+ "dark": "cream",
131
+ "light": "#231704"
132
+ },
133
+ "markdownHeading": {
134
+ "dark": "gold3",
135
+ "light": "gold0"
136
+ },
137
+ "markdownLink": {
138
+ "dark": "gold4",
139
+ "light": "gold1"
140
+ },
141
+ "markdownLinkText": {
142
+ "dark": "gold3",
143
+ "light": "gold0"
144
+ },
145
+ "markdownCode": {
146
+ "dark": "gold2",
147
+ "light": "gold0"
148
+ },
149
+ "markdownBlockQuote": {
150
+ "dark": "muted",
151
+ "light": "#6E4A12"
152
+ },
153
+ "markdownEmph": {
154
+ "dark": "gold2",
155
+ "light": "gold1"
156
+ },
157
+ "markdownStrong": {
158
+ "dark": "gold4",
159
+ "light": "gold0"
160
+ },
161
+ "markdownHorizontalRule": {
162
+ "dark": "gold0",
163
+ "light": "gold1"
164
+ },
165
+ "markdownListItem": {
166
+ "dark": "gold2",
167
+ "light": "gold0"
168
+ },
169
+ "markdownListEnumeration": {
170
+ "dark": "gold3",
171
+ "light": "gold1"
172
+ },
173
+ "markdownImage": {
174
+ "dark": "purple",
175
+ "light": "purple"
176
+ },
177
+ "markdownImageText": {
178
+ "dark": "gold3",
179
+ "light": "gold0"
180
+ },
181
+ "markdownCodeBlock": {
182
+ "dark": "cream",
183
+ "light": "#231704"
184
+ },
185
+ "syntaxComment": {
186
+ "dark": "muted",
187
+ "light": "#8A641D"
188
+ },
189
+ "syntaxKeyword": {
190
+ "dark": "gold3",
191
+ "light": "gold0"
192
+ },
193
+ "syntaxFunction": {
194
+ "dark": "gold4",
195
+ "light": "gold1"
196
+ },
197
+ "syntaxVariable": {
198
+ "dark": "cream",
199
+ "light": "#231704"
200
+ },
201
+ "syntaxString": {
202
+ "dark": "green",
203
+ "light": "#3E7D36"
204
+ },
205
+ "syntaxNumber": {
206
+ "dark": "purple",
207
+ "light": "#835AB8"
208
+ },
209
+ "syntaxType": {
210
+ "dark": "blue",
211
+ "light": "#1F6F9E"
212
+ },
213
+ "syntaxOperator": {
214
+ "dark": "gold2",
215
+ "light": "gold0"
216
+ },
217
+ "syntaxPunctuation": {
218
+ "dark": "cream",
219
+ "light": "#231704"
220
+ }
221
+ }
222
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "https://opencode.ai/tui.json",
3
+ "theme": "infinibot-gold",
4
+ "plugin": [
5
+ "./plugins/home-logo-animation.tsx",
6
+ "./plugins/routing-mode-display.tsx"
7
+ ]
8
+ }