@iaforged/context-code 1.1.7 → 1.2.1

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 (95) hide show
  1. package/README.md +56 -0
  2. package/dist/src/commands/agent/agent.js +62 -0
  3. package/dist/src/commands/agent/index.js +1 -1
  4. package/dist/src/commands/model/model.js +9 -5
  5. package/dist/src/commands/orchestrate/index.js +2 -2
  6. package/dist/src/commands/orchestrate/orchestrate.js +12 -627
  7. package/dist/src/commands/tasks/index.js +1 -1
  8. package/dist/src/commands/tasks/tasks.js +8 -3
  9. package/dist/src/commands/team/index.js +2 -2
  10. package/dist/src/commands/team/team.js +12 -589
  11. package/dist/src/commands/timeline/index.js +8 -0
  12. package/dist/src/commands/timeline/timeline.js +194 -0
  13. package/dist/src/commands/workspace/workspace.js +3 -3
  14. package/dist/src/commands.js +2 -6
  15. package/dist/src/components/AgentActivitySidebar.js +50 -0
  16. package/dist/src/components/AgentProgressLine.js +5 -5
  17. package/dist/src/components/ModelPicker.js +252 -441
  18. package/dist/src/components/PromptInput/Notifications.js +1 -1
  19. package/dist/src/components/PromptInput/PromptInput.js +7 -3
  20. package/dist/src/components/PromptInput/PromptInputFooter.js +10 -29
  21. package/dist/src/components/Spinner/TeammateSpinnerLine.js +20 -62
  22. package/dist/src/components/Spinner/TeammateSpinnerTree.js +16 -258
  23. package/dist/src/components/Spinner/teammateSelectHint.js +1 -1
  24. package/dist/src/components/Spinner/utils.js +3 -6
  25. package/dist/src/components/ThemeBrowser.js +120 -0
  26. package/dist/src/components/ThemePicker.js +113 -321
  27. package/dist/src/components/design-system/ThemeProvider.js +3 -0
  28. package/dist/src/components/mcp/MCPListPanel.js +138 -444
  29. package/dist/src/components/permissions/SandboxPermissionRequest.js +5 -5
  30. package/dist/src/components/teams/TeamStatus.js +7 -71
  31. package/dist/src/constants/spinnerVerbs.js +80 -180
  32. package/dist/src/context/modalStackContext.js +12 -0
  33. package/dist/src/hooks/useTextInput.js +28 -18
  34. package/dist/src/main.js +12 -0
  35. package/dist/src/screens/REPL.js +386 -320
  36. package/dist/src/services/api/errors.js +1 -1
  37. package/dist/src/services/api/openai.js +70 -22
  38. package/dist/src/services/api/withRetry.js +3 -2
  39. package/dist/src/skills/loadSkillsDir.js +1 -0
  40. package/dist/src/tools/AgentTool/UI.js +8 -8
  41. package/dist/src/tools/AgentTool/loadAgentsDir.js +9 -4
  42. package/dist/src/tools/AgentTool/providerAgents.js +71 -0
  43. package/dist/src/tools/BashTool/bashSecurity.js +1 -1
  44. package/dist/src/utils/handlePromptSubmit.js +12 -2
  45. package/dist/src/utils/processUserInput/processSlashCommand.js +9 -5
  46. package/dist/src/utils/sembleMcp/common.js +5 -0
  47. package/dist/src/utils/sembleMcp/setup.js +119 -0
  48. package/dist/src/utils/theme.js +24 -3
  49. package/dist/src/utils/themes/bootstrap.js +109 -0
  50. package/dist/src/utils/themes/builtin/opencode/_index.json +41 -0
  51. package/dist/src/utils/themes/builtin/opencode/amoled.json +49 -0
  52. package/dist/src/utils/themes/builtin/opencode/aura.json +51 -0
  53. package/dist/src/utils/themes/builtin/opencode/ayu.json +51 -0
  54. package/dist/src/utils/themes/builtin/opencode/carbonfox.json +53 -0
  55. package/dist/src/utils/themes/builtin/opencode/catppuccin-frappe.json +85 -0
  56. package/dist/src/utils/themes/builtin/opencode/catppuccin-macchiato.json +85 -0
  57. package/dist/src/utils/themes/builtin/opencode/catppuccin.json +45 -0
  58. package/dist/src/utils/themes/builtin/opencode/cobalt2.json +87 -0
  59. package/dist/src/utils/themes/builtin/opencode/cursor.json +91 -0
  60. package/dist/src/utils/themes/builtin/opencode/dracula.json +49 -0
  61. package/dist/src/utils/themes/builtin/opencode/everforest.json +89 -0
  62. package/dist/src/utils/themes/builtin/opencode/flexoki.json +86 -0
  63. package/dist/src/utils/themes/builtin/opencode/github.json +85 -0
  64. package/dist/src/utils/themes/builtin/opencode/gruvbox.json +45 -0
  65. package/dist/src/utils/themes/builtin/opencode/kanagawa.json +89 -0
  66. package/dist/src/utils/themes/builtin/opencode/lucent-orng.json +87 -0
  67. package/dist/src/utils/themes/builtin/opencode/material.json +87 -0
  68. package/dist/src/utils/themes/builtin/opencode/matrix.json +91 -0
  69. package/dist/src/utils/themes/builtin/opencode/mercury.json +86 -0
  70. package/dist/src/utils/themes/builtin/opencode/monokai.json +49 -0
  71. package/dist/src/utils/themes/builtin/opencode/nightowl.json +46 -0
  72. package/dist/src/utils/themes/builtin/opencode/nord.json +46 -0
  73. package/dist/src/utils/themes/builtin/opencode/oc-2.json +88 -0
  74. package/dist/src/utils/themes/builtin/opencode/one-dark.json +89 -0
  75. package/dist/src/utils/themes/builtin/opencode/onedarkpro.json +45 -0
  76. package/dist/src/utils/themes/builtin/opencode/opencode.json +89 -0
  77. package/dist/src/utils/themes/builtin/opencode/orng.json +87 -0
  78. package/dist/src/utils/themes/builtin/opencode/osaka-jade.json +88 -0
  79. package/dist/src/utils/themes/builtin/opencode/palenight.json +85 -0
  80. package/dist/src/utils/themes/builtin/opencode/rosepine.json +85 -0
  81. package/dist/src/utils/themes/builtin/opencode/shadesofpurple.json +51 -0
  82. package/dist/src/utils/themes/builtin/opencode/solarized.json +49 -0
  83. package/dist/src/utils/themes/builtin/opencode/synthwave84.json +87 -0
  84. package/dist/src/utils/themes/builtin/opencode/tokyonight.json +47 -0
  85. package/dist/src/utils/themes/builtin/opencode/vercel.json +90 -0
  86. package/dist/src/utils/themes/builtin/opencode/vesper.json +51 -0
  87. package/dist/src/utils/themes/builtin/opencode/zenburn.json +87 -0
  88. package/dist/src/utils/themes/index.js +4 -0
  89. package/dist/src/utils/themes/loader.js +147 -0
  90. package/dist/src/utils/themes/opencodeMapper.js +124 -0
  91. package/dist/src/utils/themes/resolver.js +66 -0
  92. package/dist/src/utils/themes/types.js +1 -0
  93. package/docs/MCP_SERVERS.md +27 -1
  94. package/docs/comandos.md +16 -4
  95. package/package.json +1 -1
@@ -0,0 +1,47 @@
1
+ {
2
+ "$schema": "https://opencode.ai/desktop-theme.json",
3
+ "name": "Tokyonight",
4
+ "id": "tokyonight",
5
+ "light": {
6
+ "palette": {
7
+ "neutral": "#e1e2e7",
8
+ "ink": "#273153",
9
+ "primary": "#2e7de9",
10
+ "accent": "#b15c00",
11
+ "success": "#587539",
12
+ "warning": "#8c6c3e",
13
+ "error": "#c94060",
14
+ "info": "#007197",
15
+ "diffAdd": "#4f8f7b",
16
+ "diffDelete": "#d05f7c"
17
+ },
18
+ "overrides": {
19
+ "syntax-comment": "#6b6f7a",
20
+ "syntax-keyword": "#9854f1",
21
+ "syntax-primitive": "#1f6fd4",
22
+ "syntax-property": "#007197",
23
+ "syntax-constant": "#b15c00"
24
+ }
25
+ },
26
+ "dark": {
27
+ "palette": {
28
+ "neutral": "#1a1b26",
29
+ "ink": "#c0caf5",
30
+ "primary": "#7aa2f7",
31
+ "accent": "#ff9e64",
32
+ "success": "#9ece6a",
33
+ "warning": "#e0af68",
34
+ "error": "#f7768e",
35
+ "info": "#7dcfff",
36
+ "diffAdd": "#41a6b5",
37
+ "diffDelete": "#c34043"
38
+ },
39
+ "overrides": {
40
+ "syntax-comment": "#565f89",
41
+ "syntax-keyword": "#bb9af7",
42
+ "syntax-primitive": "#7aa2f7",
43
+ "syntax-property": "#7dcfff",
44
+ "syntax-constant": "#ff9e64"
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,90 @@
1
+ {
2
+ "$schema": "https://opencode.ai/desktop-theme.json",
3
+ "name": "Vercel",
4
+ "id": "vercel",
5
+ "light": {
6
+ "palette": {
7
+ "neutral": "#FFFFFF",
8
+ "ink": "#171717",
9
+ "primary": "#0070F3",
10
+ "accent": "#8E4EC6",
11
+ "success": "#388E3C",
12
+ "warning": "#FF9500",
13
+ "error": "#DC3545",
14
+ "info": "#0070F3",
15
+ "diffAdd": "#46A758",
16
+ "diffDelete": "#E5484D"
17
+ },
18
+ "overrides": {
19
+ "text-weak": "#666666",
20
+ "syntax-comment": "#888888",
21
+ "syntax-keyword": "#E93D82",
22
+ "syntax-string": "#46A758",
23
+ "syntax-primitive": "#8E4EC6",
24
+ "syntax-variable": "#0070F3",
25
+ "syntax-property": "#12A594",
26
+ "syntax-type": "#12A594",
27
+ "syntax-constant": "#FFB224",
28
+ "syntax-operator": "#E93D82",
29
+ "syntax-punctuation": "#171717",
30
+ "syntax-object": "#0070F3",
31
+ "markdown-heading": "#8E4EC6",
32
+ "markdown-text": "#171717",
33
+ "markdown-link": "#0070F3",
34
+ "markdown-link-text": "#12A594",
35
+ "markdown-code": "#46A758",
36
+ "markdown-block-quote": "#666666",
37
+ "markdown-emph": "#FFB224",
38
+ "markdown-strong": "#E93D82",
39
+ "markdown-horizontal-rule": "#999999",
40
+ "markdown-list-item": "#171717",
41
+ "markdown-list-enumeration": "#0070F3",
42
+ "markdown-image": "#12A594",
43
+ "markdown-image-text": "#12A594",
44
+ "markdown-code-block": "#171717"
45
+ }
46
+ },
47
+ "dark": {
48
+ "palette": {
49
+ "neutral": "#000000",
50
+ "ink": "#EDEDED",
51
+ "primary": "#0070F3",
52
+ "accent": "#8E4EC6",
53
+ "success": "#46A758",
54
+ "warning": "#FFB224",
55
+ "error": "#E5484D",
56
+ "info": "#52A8FF",
57
+ "interactive": "#52A8FF",
58
+ "diffAdd": "#63C46D",
59
+ "diffDelete": "#FF6166"
60
+ },
61
+ "overrides": {
62
+ "text-weak": "#878787",
63
+ "syntax-comment": "#878787",
64
+ "syntax-keyword": "#F75590",
65
+ "syntax-string": "#63C46D",
66
+ "syntax-primitive": "#BF7AF0",
67
+ "syntax-variable": "#52A8FF",
68
+ "syntax-property": "#0AC7AC",
69
+ "syntax-type": "#0AC7AC",
70
+ "syntax-constant": "#F2A700",
71
+ "syntax-operator": "#F75590",
72
+ "syntax-punctuation": "#EDEDED",
73
+ "syntax-object": "#52A8FF",
74
+ "markdown-heading": "#BF7AF0",
75
+ "markdown-text": "#EDEDED",
76
+ "markdown-link": "#52A8FF",
77
+ "markdown-link-text": "#0AC7AC",
78
+ "markdown-code": "#63C46D",
79
+ "markdown-block-quote": "#878787",
80
+ "markdown-emph": "#F2A700",
81
+ "markdown-strong": "#F75590",
82
+ "markdown-horizontal-rule": "#454545",
83
+ "markdown-list-item": "#EDEDED",
84
+ "markdown-list-enumeration": "#52A8FF",
85
+ "markdown-image": "#0AC7AC",
86
+ "markdown-image-text": "#50E3C2",
87
+ "markdown-code-block": "#EDEDED"
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "$schema": "https://opencode.ai/desktop-theme.json",
3
+ "name": "Vesper",
4
+ "id": "vesper",
5
+ "light": {
6
+ "palette": {
7
+ "neutral": "#F0F0F0",
8
+ "ink": "#101010",
9
+ "primary": "#FFC799",
10
+ "accent": "#B30000",
11
+ "success": "#99FFE4",
12
+ "warning": "#FFC799",
13
+ "error": "#FF8080",
14
+ "info": "#FFC799",
15
+ "diffAdd": "#99FFE4",
16
+ "diffDelete": "#FF8080"
17
+ },
18
+ "overrides": {
19
+ "syntax-comment": "#7a7a7a",
20
+ "syntax-keyword": "#6e6e6e",
21
+ "syntax-string": "#117e69",
22
+ "syntax-primitive": "#8d541c",
23
+ "syntax-property": "#101010",
24
+ "syntax-type": "#8d541c",
25
+ "syntax-constant": "#8d541c"
26
+ }
27
+ },
28
+ "dark": {
29
+ "palette": {
30
+ "neutral": "#101010",
31
+ "ink": "#FFF",
32
+ "primary": "#FFC799",
33
+ "accent": "#FF8080",
34
+ "success": "#99FFE4",
35
+ "warning": "#FFC799",
36
+ "error": "#FF8080",
37
+ "info": "#FFC799",
38
+ "diffAdd": "#99FFE4",
39
+ "diffDelete": "#FF8080"
40
+ },
41
+ "overrides": {
42
+ "syntax-comment": "#8b8b8b",
43
+ "syntax-keyword": "#a0a0a0",
44
+ "syntax-string": "#99ffe4",
45
+ "syntax-primitive": "#ffc799",
46
+ "syntax-property": "#ffffff",
47
+ "syntax-type": "#ffc799",
48
+ "syntax-constant": "#ffc799"
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,87 @@
1
+ {
2
+ "$schema": "https://opencode.ai/desktop-theme.json",
3
+ "name": "Zenburn",
4
+ "id": "zenburn",
5
+ "light": {
6
+ "palette": {
7
+ "neutral": "#ffffef",
8
+ "ink": "#3f3f3f",
9
+ "primary": "#5f7f8f",
10
+ "accent": "#5f8f8f",
11
+ "success": "#5f8f5f",
12
+ "warning": "#8f8f5f",
13
+ "error": "#8f5f5f",
14
+ "info": "#8f7f5f"
15
+ },
16
+ "overrides": {
17
+ "text-weak": "#6f6f6f",
18
+ "syntax-comment": "#5f7f5f",
19
+ "syntax-keyword": "#8f8f5f",
20
+ "syntax-string": "#8f5f5f",
21
+ "syntax-primitive": "#5f7f8f",
22
+ "syntax-variable": "#3f3f3f",
23
+ "syntax-property": "#5f8f8f",
24
+ "syntax-type": "#5f8f8f",
25
+ "syntax-constant": "#5f8f5f",
26
+ "syntax-operator": "#8f8f5f",
27
+ "syntax-punctuation": "#3f3f3f",
28
+ "syntax-object": "#3f3f3f",
29
+ "markdown-heading": "#8f8f5f",
30
+ "markdown-text": "#3f3f3f",
31
+ "markdown-link": "#5f7f8f",
32
+ "markdown-link-text": "#5f8f8f",
33
+ "markdown-code": "#5f8f5f",
34
+ "markdown-block-quote": "#6f6f6f",
35
+ "markdown-emph": "#8f8f5f",
36
+ "markdown-strong": "#8f7f5f",
37
+ "markdown-horizontal-rule": "#6f6f6f",
38
+ "markdown-list-item": "#5f7f8f",
39
+ "markdown-list-enumeration": "#5f8f8f",
40
+ "markdown-image": "#5f7f8f",
41
+ "markdown-image-text": "#5f8f8f",
42
+ "markdown-code-block": "#3f3f3f"
43
+ }
44
+ },
45
+ "dark": {
46
+ "palette": {
47
+ "neutral": "#3f3f3f",
48
+ "ink": "#dcdccc",
49
+ "primary": "#8cd0d3",
50
+ "accent": "#93e0e3",
51
+ "success": "#7f9f7f",
52
+ "warning": "#f0dfaf",
53
+ "error": "#cc9393",
54
+ "info": "#dfaf8f",
55
+ "diffAdd": "#8fb28f",
56
+ "diffDelete": "#dca3a3"
57
+ },
58
+ "overrides": {
59
+ "text-weak": "#9f9f9f",
60
+ "syntax-comment": "#7f9f7f",
61
+ "syntax-keyword": "#f0dfaf",
62
+ "syntax-string": "#cc9393",
63
+ "syntax-primitive": "#8cd0d3",
64
+ "syntax-variable": "#dcdccc",
65
+ "syntax-property": "#93e0e3",
66
+ "syntax-type": "#93e0e3",
67
+ "syntax-constant": "#8fb28f",
68
+ "syntax-operator": "#f0dfaf",
69
+ "syntax-punctuation": "#dcdccc",
70
+ "syntax-object": "#dcdccc",
71
+ "markdown-heading": "#f0dfaf",
72
+ "markdown-text": "#dcdccc",
73
+ "markdown-link": "#8cd0d3",
74
+ "markdown-link-text": "#93e0e3",
75
+ "markdown-code": "#7f9f7f",
76
+ "markdown-block-quote": "#9f9f9f",
77
+ "markdown-emph": "#e0cf9f",
78
+ "markdown-strong": "#dfaf8f",
79
+ "markdown-horizontal-rule": "#9f9f9f",
80
+ "markdown-list-item": "#8cd0d3",
81
+ "markdown-list-enumeration": "#93e0e3",
82
+ "markdown-image": "#8cd0d3",
83
+ "markdown-image-text": "#93e0e3",
84
+ "markdown-code-block": "#dcdccc"
85
+ }
86
+ }
87
+ }
@@ -0,0 +1,4 @@
1
+ export { hexToRgb, lighten, resolveColor, resolveTheme } from './resolver.js';
2
+ export { mapOpencodeToCli } from './opencodeMapper.js';
3
+ export { loadAllThemes, loadAllThemesSync } from './loader.js';
4
+ export { bootstrapDynamicThemes } from './bootstrap.js';
@@ -0,0 +1,147 @@
1
+ import { promises as fs, readFileSync, readdirSync } from 'fs';
2
+ import * as os from 'os';
3
+ import * as path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import { mapOpencodeToCli } from './opencodeMapper.js';
6
+ const HERE = path.dirname(fileURLToPath(import.meta.url));
7
+ const PRIORITY = {
8
+ opencode: 0,
9
+ cli: 1,
10
+ user: 2,
11
+ };
12
+ function isThemeJson(value) {
13
+ if (typeof value !== 'object' || value === null)
14
+ return false;
15
+ const v = value;
16
+ return typeof v.theme === 'object' && v.theme !== null;
17
+ }
18
+ function looksLikeOpencode(json) {
19
+ return Object.prototype.hasOwnProperty.call(json.theme, 'primary');
20
+ }
21
+ async function readJsonFile(filePath) {
22
+ try {
23
+ const raw = await fs.readFile(filePath, 'utf8');
24
+ const parsed = JSON.parse(raw);
25
+ if (!isThemeJson(parsed)) {
26
+ console.warn(`[themes] skipping ${filePath}: invalid theme schema`);
27
+ return null;
28
+ }
29
+ return parsed;
30
+ }
31
+ catch (err) {
32
+ console.warn(`[themes] failed to load ${filePath}:`, err);
33
+ return null;
34
+ }
35
+ }
36
+ async function readDirSafe(dir) {
37
+ try {
38
+ const entries = await fs.readdir(dir, { withFileTypes: true });
39
+ return entries
40
+ .filter(e => e.isFile() && e.name.toLowerCase().endsWith('.json'))
41
+ .map(e => path.join(dir, e.name));
42
+ }
43
+ catch {
44
+ return [];
45
+ }
46
+ }
47
+ function idFromPath(file) {
48
+ return path.basename(file, path.extname(file));
49
+ }
50
+ async function loadFromDir(dir, source, transform) {
51
+ const files = await readDirSafe(dir);
52
+ const out = [];
53
+ for (const file of files) {
54
+ const json = await readJsonFile(file);
55
+ if (!json)
56
+ continue;
57
+ const finalJson = transform ? transform(json) : json;
58
+ out.push({ id: idFromPath(file), source, json: finalJson });
59
+ }
60
+ return out;
61
+ }
62
+ function userThemesDir() {
63
+ return path.join(os.homedir(), '.config', '.claude', 'themes');
64
+ }
65
+ function builtinDir(source) {
66
+ // Resolved relative to this file at runtime.
67
+ return path.join(HERE, 'builtin', source);
68
+ }
69
+ export async function loadAllThemes() {
70
+ const [cliThemes, opencodeThemes, userFiles] = await Promise.all([
71
+ loadFromDir(builtinDir('cli'), 'cli'),
72
+ loadFromDir(builtinDir('opencode'), 'opencode', mapOpencodeToCli),
73
+ readDirSafe(userThemesDir()),
74
+ ]);
75
+ const userThemes = [];
76
+ for (const file of userFiles) {
77
+ const json = await readJsonFile(file);
78
+ if (!json)
79
+ continue;
80
+ const finalJson = looksLikeOpencode(json) ? mapOpencodeToCli(json) : json;
81
+ userThemes.push({ id: idFromPath(file), source: 'user', json: finalJson });
82
+ }
83
+ // Merge with priority: user > cli > opencode
84
+ const byId = new Map();
85
+ for (const t of [...opencodeThemes, ...cliThemes, ...userThemes]) {
86
+ const existing = byId.get(t.id);
87
+ if (!existing || PRIORITY[t.source] >= PRIORITY[existing.source]) {
88
+ byId.set(t.id, t);
89
+ }
90
+ }
91
+ return Array.from(byId.values());
92
+ }
93
+ function readDirSafeSync(dir) {
94
+ try {
95
+ const entries = readdirSync(dir, { withFileTypes: true });
96
+ return entries
97
+ .filter(e => e.isFile() && e.name.toLowerCase().endsWith('.json'))
98
+ .map(e => path.join(dir, e.name))
99
+ .filter(f => !path.basename(f).startsWith('_'));
100
+ }
101
+ catch {
102
+ return [];
103
+ }
104
+ }
105
+ function readJsonFileSync(filePath) {
106
+ try {
107
+ const raw = readFileSync(filePath, 'utf8');
108
+ const parsed = JSON.parse(raw);
109
+ if (!isThemeJson(parsed))
110
+ return null;
111
+ return parsed;
112
+ }
113
+ catch {
114
+ return null;
115
+ }
116
+ }
117
+ function loadFromDirSync(dir, source, transform) {
118
+ const out = [];
119
+ for (const file of readDirSafeSync(dir)) {
120
+ const json = readJsonFileSync(file);
121
+ if (!json)
122
+ continue;
123
+ const finalJson = transform ? transform(json) : json;
124
+ out.push({ id: idFromPath(file), source, json: finalJson });
125
+ }
126
+ return out;
127
+ }
128
+ export function loadAllThemesSync() {
129
+ const cliThemes = loadFromDirSync(builtinDir('cli'), 'cli');
130
+ const opencodeThemes = loadFromDirSync(builtinDir('opencode'), 'opencode', mapOpencodeToCli);
131
+ const userThemes = [];
132
+ for (const file of readDirSafeSync(userThemesDir())) {
133
+ const json = readJsonFileSync(file);
134
+ if (!json)
135
+ continue;
136
+ const finalJson = looksLikeOpencode(json) ? mapOpencodeToCli(json) : json;
137
+ userThemes.push({ id: idFromPath(file), source: 'user', json: finalJson });
138
+ }
139
+ const byId = new Map();
140
+ for (const t of [...opencodeThemes, ...cliThemes, ...userThemes]) {
141
+ const existing = byId.get(t.id);
142
+ if (!existing || PRIORITY[t.source] >= PRIORITY[existing.source]) {
143
+ byId.set(t.id, t);
144
+ }
145
+ }
146
+ return Array.from(byId.values());
147
+ }
@@ -0,0 +1,124 @@
1
+ const FALLBACK = 'rgb(128,128,128)';
2
+ function pick(obj, key, fallback) {
3
+ const direct = obj.theme[key];
4
+ if (direct !== undefined)
5
+ return direct;
6
+ if (fallback !== undefined) {
7
+ const fb = obj.theme[fallback];
8
+ if (fb !== undefined)
9
+ return fb;
10
+ }
11
+ return FALLBACK;
12
+ }
13
+ export function mapOpencodeToCli(opencode) {
14
+ const t = opencode;
15
+ const primary = pick(t, 'primary');
16
+ const secondary = pick(t, 'secondary', 'primary');
17
+ const accent = pick(t, 'accent', 'primary');
18
+ const text = pick(t, 'text');
19
+ const textMuted = pick(t, 'textMuted', 'text');
20
+ const background = pick(t, 'background');
21
+ const backgroundPanel = pick(t, 'backgroundPanel', 'background');
22
+ const backgroundElement = pick(t, 'backgroundElement', 'backgroundPanel');
23
+ const border = pick(t, 'border');
24
+ const borderActive = pick(t, 'borderActive', 'border');
25
+ const selectedListItemText = pick(t, 'selectedListItemText', 'background');
26
+ const error = pick(t, 'error');
27
+ const warning = pick(t, 'warning');
28
+ const success = pick(t, 'success');
29
+ const info = pick(t, 'info', 'secondary');
30
+ const diffAdded = pick(t, 'diffAdded');
31
+ const diffRemoved = pick(t, 'diffRemoved');
32
+ const diffAddedBg = pick(t, 'diffAddedBg', 'diffAdded');
33
+ const diffRemovedBg = pick(t, 'diffRemovedBg', 'diffRemoved');
34
+ const diffHighlightAdded = pick(t, 'diffHighlightAdded', 'diffAdded');
35
+ const diffHighlightRemoved = pick(t, 'diffHighlightRemoved', 'diffRemoved');
36
+ const cliTheme = {
37
+ // Primary group
38
+ claude: primary,
39
+ claudeBlue_FOR_SYSTEM_SPINNER: primary,
40
+ suggestion: primary,
41
+ remember: primary,
42
+ briefLabelYou: primary,
43
+ briefLabelClaude: primary,
44
+ clawd_body: primary,
45
+ rate_limit_fill: primary,
46
+ blue_FOR_SUBAGENTS_ONLY: primary,
47
+ // Secondary group
48
+ permission: secondary,
49
+ ide: secondary,
50
+ // Accent group
51
+ autoAccept: accent,
52
+ merged: accent,
53
+ bashBorder: accent,
54
+ // Text
55
+ text: text,
56
+ inactive: textMuted,
57
+ subtle: textMuted,
58
+ // Backgrounds
59
+ background: background,
60
+ clawd_background: background,
61
+ userMessageBackground: backgroundPanel,
62
+ messageActionsBackground: backgroundElement,
63
+ bashMessageBackgroundColor: backgroundElement,
64
+ memoryBackgroundColor: backgroundElement,
65
+ // Borders
66
+ promptBorder: border,
67
+ rate_limit_empty: border,
68
+ promptBorderShimmer: borderActive,
69
+ // Inverse
70
+ inverseText: selectedListItemText,
71
+ // Status
72
+ error: error,
73
+ red_FOR_SUBAGENTS_ONLY: error,
74
+ warning: warning,
75
+ fastMode: warning,
76
+ chromeYellow: warning,
77
+ yellow_FOR_SUBAGENTS_ONLY: warning,
78
+ success: success,
79
+ green_FOR_SUBAGENTS_ONLY: success,
80
+ planMode: info,
81
+ cyan_FOR_SUBAGENTS_ONLY: info,
82
+ // Diffs
83
+ diffAdded: diffAdded,
84
+ diffRemoved: diffRemoved,
85
+ diffAddedDimmed: diffAddedBg,
86
+ diffRemovedDimmed: diffRemovedBg,
87
+ diffAddedWord: diffHighlightAdded,
88
+ diffRemovedWord: diffHighlightRemoved,
89
+ // Shimmers (copy base; resolver/consumer can lighten later if desired)
90
+ claudeShimmer: primary,
91
+ claudeBlueShimmer_FOR_SYSTEM_SPINNER: primary,
92
+ permissionShimmer: secondary,
93
+ inactiveShimmer: textMuted,
94
+ warningShimmer: warning,
95
+ fastModeShimmer: warning,
96
+ // Constants (no opencode equivalent)
97
+ professionalBlue: 'rgb(106,155,204)',
98
+ userMessageBackgroundHover: backgroundPanel,
99
+ selectionBg: primary,
100
+ purple_FOR_SUBAGENTS_ONLY: 'rgb(147,51,234)',
101
+ orange_FOR_SUBAGENTS_ONLY: 'rgb(234,88,12)',
102
+ pink_FOR_SUBAGENTS_ONLY: 'rgb(219,39,119)',
103
+ rainbow_red: 'rgb(235,95,87)',
104
+ rainbow_orange: 'rgb(245,139,87)',
105
+ rainbow_yellow: 'rgb(250,195,95)',
106
+ rainbow_green: 'rgb(145,200,130)',
107
+ rainbow_blue: 'rgb(130,170,220)',
108
+ rainbow_indigo: 'rgb(155,130,200)',
109
+ rainbow_violet: 'rgb(200,130,180)',
110
+ rainbow_red_shimmer: 'rgb(250,155,147)',
111
+ rainbow_orange_shimmer: 'rgb(255,185,137)',
112
+ rainbow_yellow_shimmer: 'rgb(255,225,155)',
113
+ rainbow_green_shimmer: 'rgb(185,230,180)',
114
+ rainbow_blue_shimmer: 'rgb(180,205,240)',
115
+ rainbow_indigo_shimmer: 'rgb(195,180,230)',
116
+ rainbow_violet_shimmer: 'rgb(230,180,210)',
117
+ };
118
+ return {
119
+ $schema: opencode.$schema,
120
+ name: opencode.name,
121
+ defs: opencode.defs,
122
+ theme: cliTheme,
123
+ };
124
+ }
@@ -0,0 +1,66 @@
1
+ const FALLBACK = 'rgb(128,128,128)';
2
+ export function hexToRgb(hex) {
3
+ let h = hex.trim();
4
+ if (h.startsWith('#'))
5
+ h = h.slice(1);
6
+ if (h.length === 3) {
7
+ h = h
8
+ .split('')
9
+ .map(c => c + c)
10
+ .join('');
11
+ }
12
+ if (h.length !== 6)
13
+ return FALLBACK;
14
+ const r = parseInt(h.slice(0, 2), 16);
15
+ const g = parseInt(h.slice(2, 4), 16);
16
+ const b = parseInt(h.slice(4, 6), 16);
17
+ if ([r, g, b].some(n => Number.isNaN(n)))
18
+ return FALLBACK;
19
+ return `rgb(${r},${g},${b})`;
20
+ }
21
+ function isVariant(v) {
22
+ return typeof v === 'object' && v !== null && 'dark' in v && 'light' in v;
23
+ }
24
+ export function resolveColor(value, defs, mode, seen = new Set()) {
25
+ if (isVariant(value)) {
26
+ return resolveColor(value[mode], defs, mode, seen);
27
+ }
28
+ const v = value.trim();
29
+ if (!v)
30
+ return FALLBACK;
31
+ if (v.startsWith('#'))
32
+ return hexToRgb(v);
33
+ if (v.startsWith('rgb(') || v.startsWith('rgba('))
34
+ return v;
35
+ if (v.startsWith('ansi:'))
36
+ return v;
37
+ // Treat as a name reference into defs
38
+ if (defs && Object.prototype.hasOwnProperty.call(defs, v)) {
39
+ if (seen.has(v))
40
+ return FALLBACK;
41
+ const next = new Set(seen);
42
+ next.add(v);
43
+ return resolveColor(defs[v], defs, mode, next);
44
+ }
45
+ return FALLBACK;
46
+ }
47
+ export function lighten(color, amount) {
48
+ if (color.startsWith('ansi:'))
49
+ return color;
50
+ const m = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/.exec(color);
51
+ if (!m)
52
+ return color;
53
+ const a = Math.max(0, Math.min(1, amount));
54
+ const r = Math.round(parseInt(m[1], 10) + (255 - parseInt(m[1], 10)) * a);
55
+ const g = Math.round(parseInt(m[2], 10) + (255 - parseInt(m[2], 10)) * a);
56
+ const b = Math.round(parseInt(m[3], 10) + (255 - parseInt(m[3], 10)) * a);
57
+ return `rgb(${r},${g},${b})`;
58
+ }
59
+ export function resolveTheme(json, mode) {
60
+ const defs = json.defs ?? {};
61
+ const out = {};
62
+ for (const [key, val] of Object.entries(json.theme)) {
63
+ out[key] = resolveColor(val, defs, mode);
64
+ }
65
+ return out;
66
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -46,6 +46,32 @@ Pasos a tener en cuenta:
46
46
  - Las herramientas MCP aparecen en los agentes con prefijo `mcp__<name>__<tool>`. Puedes restringir cuales se autorizan con `--allowedTools` al iniciar la sesion.
47
47
  - Si un equipo (`database`, por ejemplo) tendria que usar este MCP, asignale un agente con `/team equipo <team> database <provider>/<agent>` y el orquestador local lo invocara cuando el plan lo requiera.
48
48
 
49
+ ### Semble integrado
50
+
51
+ Este proyecto instala y precalienta `semble` automaticamente la primera vez que arranca, y luego lo registra como MCP dinamico.
52
+
53
+ Si `uv` no existe en el sistema, el CLI intenta instalarlo automaticamente en una carpeta administrada por la aplicacion y usa ese binario desde ahi.
54
+
55
+ Herramientas expuestas:
56
+
57
+ - `mcp__semble__search`
58
+ - `mcp__semble__find_related`
59
+
60
+ Bootstrap inicial:
61
+
62
+ ```sh
63
+ uv tool install "semble[mcp]"
64
+ uv tool run --from "semble[mcp]" semble search "bootstrap" <repo> --top-k 1
65
+ ```
66
+
67
+ Comando MCP usado por el runtime:
68
+
69
+ ```sh
70
+ uv tool run --from "semble[mcp]" semble
71
+ ```
72
+
73
+ El primer bootstrap instala el paquete y fuerza la descarga local del modelo de embeddings que `semble` usa via Model2Vec.
74
+
49
75
  ### Diferencia con el storage interno
50
76
 
51
- El archivo `~/.context/provider-state.sqlite3` es persistencia interna del CLI (perfiles, runs, credenciales). **No es un MCP** y los agentes no lo consultan directamente; solo el runtime lo lee/escribe. Si quieres exponer datos de una base **a los agentes**, registra un servidor MCP como en los ejemplos de arriba.
77
+ El archivo `~/.context/provider-state.sqlite3` es persistencia interna del CLI (perfiles, runs, credenciales). **No es un MCP** y los agentes no lo consultan directamente; solo el runtime lo lee/escribe. Si quieres exponer datos de una base **a los agentes**, registra un servidor MCP como en los ejemplos de arriba.