oh-my-opencode-slim 0.8.2 → 0.8.4

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.
@@ -1,4 +1,4 @@
1
1
  export { ast_grep_replace, ast_grep_search } from './ast-grep';
2
2
  export { createBackgroundTools } from './background';
3
3
  export { grep } from './grep';
4
- export { lsp_diagnostics, lsp_find_references, lsp_goto_definition, lsp_rename, lspManager, } from './lsp';
4
+ export { lsp_diagnostics, lsp_find_references, lsp_goto_definition, lsp_rename, lspManager, setUserLspConfig, } from './lsp';
@@ -0,0 +1,29 @@
1
+ /**
2
+ * User-provided LSP server config (from opencode.json lsp section).
3
+ * Fields are optional because user config may not include all properties.
4
+ */
5
+ export interface UserLspConfig {
6
+ id: string;
7
+ command?: string[];
8
+ extensions?: string[];
9
+ disabled?: boolean;
10
+ env?: Record<string, string>;
11
+ initialization?: Record<string, unknown>;
12
+ }
13
+ /**
14
+ * Set the user's lsp config from opencode.json.
15
+ * Called during plugin initialization.
16
+ */
17
+ export declare function setUserLspConfig(config: Record<string, unknown> | undefined): void;
18
+ /**
19
+ * Get the user's lsp config for a specific server ID.
20
+ */
21
+ export declare function getUserLspConfig(serverId: string): UserLspConfig | undefined;
22
+ /**
23
+ * Get all user-configured lsp servers.
24
+ */
25
+ export declare function getAllUserLspConfigs(): Map<string, UserLspConfig>;
26
+ /**
27
+ * Check if user has configured any lsp servers.
28
+ */
29
+ export declare function hasUserLspConfig(): boolean;
@@ -1,8 +1,24 @@
1
- import type { LSPServerConfig } from './types';
1
+ import type { LSPServerConfig, RootFunction } from './types';
2
2
  export declare const SYMBOL_KIND_MAP: Record<number, string>;
3
3
  export declare const SEVERITY_MAP: Record<number, string>;
4
4
  export declare const DEFAULT_MAX_REFERENCES = 200;
5
5
  export declare const DEFAULT_MAX_DIAGNOSTICS = 200;
6
+ /**
7
+ * NearestRoot helper - mirrors OpenCode core's NearestRoot function.
8
+ * Creates a RootFunction that walks up directories looking for root markers.
9
+ */
10
+ export declare function NearestRoot(includePatterns: string[], excludePatterns?: string[]): RootFunction;
11
+ /**
12
+ * Built-in LSP servers - mirrors OpenCode core LSPServer namespace.
13
+ * User configuration from opencode.json lsp section takes precedence and is
14
+ * merged on top of these: user settings override command/extensions/env, while
15
+ * root patterns are always preserved from built-in. Servers can be removed by
16
+ * setting `"disabled": true` in the user config.
17
+ */
6
18
  export declare const BUILTIN_SERVERS: Record<string, Omit<LSPServerConfig, 'id'>>;
7
19
  export declare const LSP_INSTALL_HINTS: Record<string, string>;
8
- export declare const EXT_TO_LANG: Record<string, string>;
20
+ /**
21
+ * Maps file extensions to LSP language IDs.
22
+ * Mirrors OpenCode core's LANGUAGE_EXTENSIONS constant.
23
+ */
24
+ export declare const LANGUAGE_EXTENSIONS: Record<string, string>;
@@ -1,3 +1,4 @@
1
1
  export { lspManager } from './client';
2
+ export { getUserLspConfig, setUserLspConfig } from './config-store';
2
3
  export { lsp_diagnostics, lsp_find_references, lsp_goto_definition, lsp_rename, } from './tools';
3
4
  export type { Diagnostic, Location, LSPServerConfig, ResolvedServer, WorkspaceEdit, } from './types';
@@ -1,8 +1,14 @@
1
1
  import type { CreateFile, DeleteFile, Diagnostic, DocumentSymbol, Location, LocationLink, Position, Range, RenameFile, SymbolInformation as SymbolInfo, TextDocumentEdit, TextDocumentIdentifier, TextEdit, VersionedTextDocumentIdentifier, WorkspaceEdit } from 'vscode-languageserver-protocol';
2
+ /**
3
+ * Root function type - mirrors OpenCode core's RootFunction.
4
+ * Returns the project root directory for a given file, or undefined if not applicable.
5
+ */
6
+ export type RootFunction = (file: string) => string | undefined;
2
7
  export interface LSPServerConfig {
3
8
  id: string;
4
9
  command: string[];
5
10
  extensions: string[];
11
+ root?: RootFunction;
6
12
  disabled?: boolean;
7
13
  env?: Record<string, string>;
8
14
  initialization?: Record<string, unknown>;
@@ -11,6 +17,7 @@ export interface ResolvedServer {
11
17
  id: string;
12
18
  command: string[];
13
19
  extensions: string[];
20
+ root?: RootFunction;
14
21
  env?: Record<string, string>;
15
22
  initialization?: Record<string, unknown>;
16
23
  }
@@ -1,5 +1,18 @@
1
1
  import type { LSPClient } from './client';
2
- import type { Diagnostic, Location, LocationLink, ServerLookupResult, WorkspaceEdit } from './types';
2
+ import type { Diagnostic, Location, LocationLink, ResolvedServer, ServerLookupResult, WorkspaceEdit } from './types';
3
+ /**
4
+ * Find the project root for a specific LSP server using its root function.
5
+ * Mirrors OpenCode core's RootFunction approach.
6
+ *
7
+ * @param filePath - The file to find the root for
8
+ * @param server - The LSP server config with root function
9
+ * @returns The project root directory, or file's directory if no root function
10
+ */
11
+ export declare function findServerProjectRoot(filePath: string, server: ResolvedServer): string;
12
+ /**
13
+ * Legacy function for backward compatibility.
14
+ * @deprecated Use findServerProjectRoot with server-specific patterns instead.
15
+ */
3
16
  export declare function findWorkspaceRoot(filePath: string): string;
4
17
  export declare function uriToPath(uri: string): string;
5
18
  export declare function formatServerLookupError(result: Exclude<ServerLookupResult, {
@@ -0,0 +1,448 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "type": "object",
4
+ "properties": {
5
+ "preset": {
6
+ "type": "string"
7
+ },
8
+ "setDefaultAgent": {
9
+ "type": "boolean"
10
+ },
11
+ "scoringEngineVersion": {
12
+ "type": "string",
13
+ "enum": [
14
+ "v1",
15
+ "v2-shadow",
16
+ "v2"
17
+ ]
18
+ },
19
+ "balanceProviderUsage": {
20
+ "type": "boolean"
21
+ },
22
+ "manualPlan": {
23
+ "type": "object",
24
+ "properties": {
25
+ "orchestrator": {
26
+ "type": "object",
27
+ "properties": {
28
+ "primary": {
29
+ "type": "string",
30
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
31
+ },
32
+ "fallback1": {
33
+ "type": "string",
34
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
35
+ },
36
+ "fallback2": {
37
+ "type": "string",
38
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
39
+ },
40
+ "fallback3": {
41
+ "type": "string",
42
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
43
+ }
44
+ },
45
+ "required": [
46
+ "primary",
47
+ "fallback1",
48
+ "fallback2",
49
+ "fallback3"
50
+ ]
51
+ },
52
+ "oracle": {
53
+ "type": "object",
54
+ "properties": {
55
+ "primary": {
56
+ "type": "string",
57
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
58
+ },
59
+ "fallback1": {
60
+ "type": "string",
61
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
62
+ },
63
+ "fallback2": {
64
+ "type": "string",
65
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
66
+ },
67
+ "fallback3": {
68
+ "type": "string",
69
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
70
+ }
71
+ },
72
+ "required": [
73
+ "primary",
74
+ "fallback1",
75
+ "fallback2",
76
+ "fallback3"
77
+ ]
78
+ },
79
+ "designer": {
80
+ "type": "object",
81
+ "properties": {
82
+ "primary": {
83
+ "type": "string",
84
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
85
+ },
86
+ "fallback1": {
87
+ "type": "string",
88
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
89
+ },
90
+ "fallback2": {
91
+ "type": "string",
92
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
93
+ },
94
+ "fallback3": {
95
+ "type": "string",
96
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
97
+ }
98
+ },
99
+ "required": [
100
+ "primary",
101
+ "fallback1",
102
+ "fallback2",
103
+ "fallback3"
104
+ ]
105
+ },
106
+ "explorer": {
107
+ "type": "object",
108
+ "properties": {
109
+ "primary": {
110
+ "type": "string",
111
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
112
+ },
113
+ "fallback1": {
114
+ "type": "string",
115
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
116
+ },
117
+ "fallback2": {
118
+ "type": "string",
119
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
120
+ },
121
+ "fallback3": {
122
+ "type": "string",
123
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
124
+ }
125
+ },
126
+ "required": [
127
+ "primary",
128
+ "fallback1",
129
+ "fallback2",
130
+ "fallback3"
131
+ ]
132
+ },
133
+ "librarian": {
134
+ "type": "object",
135
+ "properties": {
136
+ "primary": {
137
+ "type": "string",
138
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
139
+ },
140
+ "fallback1": {
141
+ "type": "string",
142
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
143
+ },
144
+ "fallback2": {
145
+ "type": "string",
146
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
147
+ },
148
+ "fallback3": {
149
+ "type": "string",
150
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
151
+ }
152
+ },
153
+ "required": [
154
+ "primary",
155
+ "fallback1",
156
+ "fallback2",
157
+ "fallback3"
158
+ ]
159
+ },
160
+ "fixer": {
161
+ "type": "object",
162
+ "properties": {
163
+ "primary": {
164
+ "type": "string",
165
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
166
+ },
167
+ "fallback1": {
168
+ "type": "string",
169
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
170
+ },
171
+ "fallback2": {
172
+ "type": "string",
173
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
174
+ },
175
+ "fallback3": {
176
+ "type": "string",
177
+ "pattern": "^[^/\\s]+\\/[^\\s]+$"
178
+ }
179
+ },
180
+ "required": [
181
+ "primary",
182
+ "fallback1",
183
+ "fallback2",
184
+ "fallback3"
185
+ ]
186
+ }
187
+ },
188
+ "required": [
189
+ "orchestrator",
190
+ "oracle",
191
+ "designer",
192
+ "explorer",
193
+ "librarian",
194
+ "fixer"
195
+ ],
196
+ "additionalProperties": false
197
+ },
198
+ "presets": {
199
+ "type": "object",
200
+ "propertyNames": {
201
+ "type": "string"
202
+ },
203
+ "additionalProperties": {
204
+ "type": "object",
205
+ "propertyNames": {
206
+ "type": "string"
207
+ },
208
+ "additionalProperties": {
209
+ "type": "object",
210
+ "properties": {
211
+ "model": {
212
+ "anyOf": [
213
+ {
214
+ "type": "string"
215
+ },
216
+ {
217
+ "type": "array",
218
+ "items": {
219
+ "anyOf": [
220
+ {
221
+ "type": "string"
222
+ },
223
+ {
224
+ "type": "object",
225
+ "properties": {
226
+ "id": {
227
+ "type": "string"
228
+ },
229
+ "variant": {
230
+ "type": "string"
231
+ }
232
+ },
233
+ "required": [
234
+ "id"
235
+ ]
236
+ }
237
+ ]
238
+ }
239
+ }
240
+ ]
241
+ },
242
+ "temperature": {
243
+ "type": "number",
244
+ "minimum": 0,
245
+ "maximum": 2
246
+ },
247
+ "variant": {
248
+ "type": "string"
249
+ },
250
+ "skills": {
251
+ "type": "array",
252
+ "items": {
253
+ "type": "string"
254
+ }
255
+ },
256
+ "mcps": {
257
+ "type": "array",
258
+ "items": {
259
+ "type": "string"
260
+ }
261
+ }
262
+ }
263
+ }
264
+ }
265
+ },
266
+ "agents": {
267
+ "type": "object",
268
+ "propertyNames": {
269
+ "type": "string"
270
+ },
271
+ "additionalProperties": {
272
+ "type": "object",
273
+ "properties": {
274
+ "model": {
275
+ "anyOf": [
276
+ {
277
+ "type": "string"
278
+ },
279
+ {
280
+ "type": "array",
281
+ "items": {
282
+ "anyOf": [
283
+ {
284
+ "type": "string"
285
+ },
286
+ {
287
+ "type": "object",
288
+ "properties": {
289
+ "id": {
290
+ "type": "string"
291
+ },
292
+ "variant": {
293
+ "type": "string"
294
+ }
295
+ },
296
+ "required": [
297
+ "id"
298
+ ]
299
+ }
300
+ ]
301
+ }
302
+ }
303
+ ]
304
+ },
305
+ "temperature": {
306
+ "type": "number",
307
+ "minimum": 0,
308
+ "maximum": 2
309
+ },
310
+ "variant": {
311
+ "type": "string"
312
+ },
313
+ "skills": {
314
+ "type": "array",
315
+ "items": {
316
+ "type": "string"
317
+ }
318
+ },
319
+ "mcps": {
320
+ "type": "array",
321
+ "items": {
322
+ "type": "string"
323
+ }
324
+ }
325
+ }
326
+ }
327
+ },
328
+ "disabled_mcps": {
329
+ "type": "array",
330
+ "items": {
331
+ "type": "string"
332
+ }
333
+ },
334
+ "tmux": {
335
+ "type": "object",
336
+ "properties": {
337
+ "enabled": {
338
+ "default": false,
339
+ "type": "boolean"
340
+ },
341
+ "layout": {
342
+ "default": "main-vertical",
343
+ "type": "string",
344
+ "enum": [
345
+ "main-horizontal",
346
+ "main-vertical",
347
+ "tiled",
348
+ "even-horizontal",
349
+ "even-vertical"
350
+ ]
351
+ },
352
+ "main_pane_size": {
353
+ "default": 60,
354
+ "type": "number",
355
+ "minimum": 20,
356
+ "maximum": 80
357
+ }
358
+ }
359
+ },
360
+ "background": {
361
+ "type": "object",
362
+ "properties": {
363
+ "maxConcurrentStarts": {
364
+ "default": 10,
365
+ "type": "number",
366
+ "minimum": 1,
367
+ "maximum": 50
368
+ }
369
+ }
370
+ },
371
+ "fallback": {
372
+ "type": "object",
373
+ "properties": {
374
+ "enabled": {
375
+ "default": true,
376
+ "type": "boolean"
377
+ },
378
+ "timeoutMs": {
379
+ "default": 15000,
380
+ "type": "number",
381
+ "minimum": 0
382
+ },
383
+ "retryDelayMs": {
384
+ "default": 500,
385
+ "type": "number",
386
+ "minimum": 0
387
+ },
388
+ "chains": {
389
+ "default": {},
390
+ "type": "object",
391
+ "properties": {
392
+ "orchestrator": {
393
+ "minItems": 1,
394
+ "type": "array",
395
+ "items": {
396
+ "type": "string"
397
+ }
398
+ },
399
+ "oracle": {
400
+ "minItems": 1,
401
+ "type": "array",
402
+ "items": {
403
+ "type": "string"
404
+ }
405
+ },
406
+ "designer": {
407
+ "minItems": 1,
408
+ "type": "array",
409
+ "items": {
410
+ "type": "string"
411
+ }
412
+ },
413
+ "explorer": {
414
+ "minItems": 1,
415
+ "type": "array",
416
+ "items": {
417
+ "type": "string"
418
+ }
419
+ },
420
+ "librarian": {
421
+ "minItems": 1,
422
+ "type": "array",
423
+ "items": {
424
+ "type": "string"
425
+ }
426
+ },
427
+ "fixer": {
428
+ "minItems": 1,
429
+ "type": "array",
430
+ "items": {
431
+ "type": "string"
432
+ }
433
+ }
434
+ },
435
+ "additionalProperties": {
436
+ "minItems": 1,
437
+ "type": "array",
438
+ "items": {
439
+ "type": "string"
440
+ }
441
+ }
442
+ }
443
+ }
444
+ }
445
+ },
446
+ "title": "oh-my-opencode-slim",
447
+ "description": "Configuration schema for oh-my-opencode-slim plugin for OpenCode"
448
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode-slim",
3
- "version": "0.8.2",
3
+ "version": "0.8.4",
4
4
  "description": "Lightweight agent orchestration plugin for OpenCode - a slimmed-down fork of oh-my-opencode",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -31,11 +31,13 @@
31
31
  "files": [
32
32
  "dist",
33
33
  "src/skills",
34
+ "oh-my-opencode-slim.schema.json",
34
35
  "README.md",
35
36
  "LICENSE"
36
37
  ],
37
38
  "scripts": {
38
- "build": "bun build src/index.ts --outdir dist --target bun --format esm && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm && tsc --emitDeclarationOnly",
39
+ "build": "bun build src/index.ts --outdir dist --target bun --format esm && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm && tsc --emitDeclarationOnly && bun run generate-schema",
40
+ "generate-schema": "bun run scripts/generate-schema.ts",
39
41
  "typecheck": "tsc --noEmit",
40
42
  "test": "bun test",
41
43
  "lint": "biome lint .",
@@ -55,10 +57,12 @@
55
57
  "@opencode-ai/sdk": "^1.2.6",
56
58
  "vscode-jsonrpc": "^8.2.0",
57
59
  "vscode-languageserver-protocol": "^3.17.5",
60
+ "which": "^6.0.0",
58
61
  "zod": "^4.3.6"
59
62
  },
60
63
  "devDependencies": {
61
64
  "@biomejs/biome": "2.4.2",
65
+ "@types/which": "^3.0.4",
62
66
  "bun-types": "1.3.9",
63
67
  "typescript": "^5.9.3"
64
68
  },
@@ -79,6 +79,29 @@ Once all specific directories are mapped, the Orchestrator must create or update
79
79
  2. **Aggregate Sub-Maps**: Create a "Repository Directory Map" section. For every folder that has a `codemap.md`, extract its **Responsibility** summary and include it in a table or list in the root map.
80
80
  3. **Cross-Reference**: Ensure that the root map contains the absolute or relative paths to the sub-maps so agents can jump directly to the relevant details.
81
81
 
82
+ ### Step 5: Register Codemap in AGENTS.md
83
+
84
+ **OpenCode auto-loads `AGENTS.md` into agent context on every session.** To ensure agents automatically discover and use the codemap, update (or create) `AGENTS.md` at the repo root:
85
+
86
+ 1. If `AGENTS.md` already exists and already contains a `## Repository Map` section, **skip this step** — the reference is already set up.
87
+ 2. If `AGENTS.md` exists but has no `## Repository Map` section, **append** the section below.
88
+ 3. If `AGENTS.md` doesn't exist, **create** it with the section below.
89
+
90
+ ```markdown
91
+ ## Repository Map
92
+
93
+ A full codemap is available at `codemap.md` in the project root.
94
+
95
+ Before working on any task, read `codemap.md` to understand:
96
+ - Project architecture and entry points
97
+ - Directory responsibilities and design patterns
98
+ - Data flow and integration points between modules
99
+
100
+ For deep work on a specific folder, also read that folder's `codemap.md`.
101
+ ```
102
+
103
+ This is idempotent — repeated cartography runs will detect the existing section and skip. No duplication.
104
+
82
105
 
83
106
  ## Codemap Content
84
107