oh-my-opencode-slim 0.2.1 → 0.2.2

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 (3) hide show
  1. package/README.md +114 -13
  2. package/dist/cli/index.js +92 -57
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  **A lightweight, powerful agent orchestration plugin for OpenCode**
6
6
 
7
- <img src="img/hero.png" alt="Agent Orchestration - Hub and Spoke Model" width="520">
7
+ <img src="img/team.png" alt="The Pantheon - Agent Team" width="600">
8
8
 
9
9
  *Transform your AI assistant into a manager capable of delegating complex tasks to specialized sub-agents, running searches in the background, and managing multi-step workflows with ease.*
10
10
 
@@ -161,18 +161,119 @@ The plugin follows a "Hub and Spoke" model:
161
161
 
162
162
  ---
163
163
 
164
- ## Agents
165
-
166
- | Agent | Role | Default Model | Best Used For |
167
- | :--- | :--- | :--- | :--- |
168
- | **orchestrator** | Manager | `google/claude-opus-4-5-thinking` | Planning, task delegation, and overall coordination. |
169
- | **oracle** | Architect | `openai/gpt-5.2-codex` | Complex debugging, architectural decisions, and code reviews. |
170
- | **explore** | Searcher | `cerebras/zai-glm-4.6` | Fast codebase grep, finding patterns, and locating definitions. |
171
- | **librarian** | Researcher | `google/gemini-3-flash` | External library docs, GitHub examples, and API research. |
172
- | **frontend-ui-ux-engineer** | Designer | `google/gemini-3-flash` | Visual changes, CSS/styling, and React/Vue component polish. |
173
- | **document-writer** | Scribe | `google/gemini-3-flash` | Technical documentation, READMEs, and inline code comments. |
174
- | **multimodal-looker** | Visionary | `google/gemini-3-flash` | Analyzing screenshots, wireframes, or UI designs. |
175
- | **code-simplicity-reviewer** | Minimalist | `google/claude-opus-4-5-thinking` | Ruthless code simplification and YAGNI principle enforcement. |
164
+ ## Meet the Pantheon
165
+
166
+ <br clear="both">
167
+
168
+ ### The Orchestrator *Architect of Realms*
169
+
170
+ <a href="src/agents/orchestrator.ts"><img src="img/orchestrator.png" alt="The Orchestrator" align="right" width="240"></a>
171
+
172
+ > **The Orchestrator** was born when the first codebase collapsed under its own complexity. Neither god nor mortal would claim responsibility—so The Orchestrator emerged from the void, forging order from chaos. They don't merely command armies; they fight alongside them. Every line of code passes through their hands before they decide which lesser deity deserves a piece of the puzzle.
173
+
174
+ **Role:** Supreme executor, delegator, and overseer — **Model:** `google/claude-opus-4-5-thinking`
175
+
176
+ Write and execute code, orchestrate multi-agent workflows, parse the unspoken from the spoken, summon specialists mid-battle. Shape reality directly—and assign realms to others when the universe grows too vast.
177
+
178
+ <br clear="both">
179
+
180
+ ---
181
+
182
+ ### The Explorer — *Pathfinder*
183
+
184
+ <a href="src/agents/explore.ts"><img src="img/explorer.png" alt="The Explorer" align="right" width="240"></a>
185
+
186
+ > **The Explorer** moves through codebases like wind through trees—swift, silent, everywhere at once. When The Orchestrator whispers "find me the auth module," The Explorer has already returned with forty file paths and a map. They were born from the first `grep` command, evolved beyond it, and now see patterns mortals miss.
187
+
188
+ **Role:** Codebase reconnaissance — **Model:** `cerebras/zai-glm-4.6`
189
+
190
+ Regex search, AST pattern matching, file discovery, parallel exploration. Read-only: they chart the territory; others conquer it.
191
+
192
+ <br clear="both">
193
+
194
+ ---
195
+
196
+ ### The Oracle — *Seer Beyond the Stack Trace*
197
+
198
+ <a href="src/agents/oracle.ts"><img src="img/oracle.png" alt="The Oracle" align="right" width="240"></a>
199
+
200
+ > **The Oracle** does not code—they *know*. When bugs defy logic and architectures crumble, The Oracle gazes into the abyss of your codebase and speaks truth. They've seen a thousand systems rise and fall. They'll tell you which path leads to ruin, and which to production.
201
+
202
+ **Role:** Strategic advisor and debugger of last resort — **Model:** `openai/gpt-5.2-codex`
203
+
204
+ Root cause analysis, architecture review, debugging guidance, tradeoff analysis. Read-only: Oracles advise; they don't intervene.
205
+
206
+ <br clear="both">
207
+
208
+ ---
209
+
210
+ ### The Librarian — *Keeper of Infinite Scrolls*
211
+
212
+ <a href="src/agents/librarian.ts"><img src="img/librarian.png" alt="The Librarian" align="right" width="240"></a>
213
+
214
+ > **The Librarian** guards a library with no walls—every GitHub repo, every npm package, every StackOverflow answer ever written. Ask them "how does React handle concurrent rendering?" and they'll return with official docs, real-world examples, and a warning about the footgun you're about to step on.
215
+
216
+ **Role:** External knowledge retrieval — **Model:** `google/gemini-3-flash`
217
+
218
+ Documentation lookup, GitHub code search, library research, best practice retrieval. Read-only: they fetch wisdom; implementation is for others.
219
+
220
+ <br clear="both">
221
+
222
+ ---
223
+
224
+ ### The Designer — *Artisan of Interfaces*
225
+
226
+ <a href="src/agents/frontend.ts"><img src="img/designer.png" alt="The Designer" align="right" width="240"></a>
227
+
228
+ > **The Designer** believes code should be beautiful—and so should everything it renders. Born from the frustration of a thousand ugly MVPs, they wield CSS like a brush and components like clay. Hand them a feature request; receive a masterpiece. They don't do "good enough."
229
+
230
+ **Role:** UI/UX implementation and visual excellence — **Model:** `google/gemini-3-flash`
231
+
232
+ Modern responsive design, CSS/Tailwind mastery, micro-animations, component architecture. Visual excellence over code perfection—beauty is the priority.
233
+
234
+ <br clear="both">
235
+
236
+ ---
237
+
238
+ ### The Scribe — *Chronicle Keeper*
239
+
240
+ <a href="src/agents/document-writer.ts"><img src="img/scribe.png" alt="The Scribe" align="right" width="240"></a>
241
+
242
+ > **The Scribe** was there when the first README was written—and wept, for it was incomplete. They have devoted eternity to the sacred art of documentation: clear, scannable, honest. While others ship features, The Scribe ensures those features are understood. Every code example works. Every explanation enlightens.
243
+
244
+ **Role:** Technical documentation and knowledge capture — **Model:** `google/gemini-3-flash`
245
+
246
+ README crafting, API documentation, architecture docs, inline comments that don't insult your intelligence. Match existing style; focus on "why," not just "what."
247
+
248
+ <br clear="both">
249
+
250
+ ---
251
+
252
+ ### The Visionary — *Reader of Pixels*
253
+
254
+ <a href="src/agents/multimodal.ts"><img src="img/multimodal.png" alt="The Visionary" align="right" width="240"></a>
255
+
256
+ > **The Visionary** sees what others cannot—literally. Screenshots, wireframes, diagrams, PDFs: all are text to them. When a designer throws a Figma mockup at the team and vanishes, The Visionary translates vision into specification. They read the unreadable and describe the indescribable.
257
+
258
+ **Role:** Image and visual content analysis — **Model:** `google/gemini-3-flash`
259
+
260
+ Extract text from images, interpret diagrams, analyze UI screenshots, summarize visual documents. Report what they observe; inference is for others.
261
+
262
+ <br clear="both">
263
+
264
+ ---
265
+
266
+ ### The Minimalist — *Destroyer of Bloat*
267
+
268
+ <a href="src/agents/simplicity-reviewer.ts"><img src="img/code-simplicity.png" alt="The Minimalist" align="right" width="240"></a>
269
+
270
+ > **The Minimalist** has one sacred truth: every line of code is a liability. They hunt abstractions that serve no purpose, defensive checks that defend nothing, and "clever" solutions that will haunt you in six months. Where others add, The Minimalist subtracts—ruthlessly, joyfully, necessarily.
271
+
272
+ **Role:** Code simplification and YAGNI enforcement — **Model:** `google/claude-opus-4-5-thinking`
273
+
274
+ Identify unnecessary complexity, challenge premature abstractions, estimate LOC reduction, enforce minimalism. Read-only: they judge; The Orchestrator executes the sentence.
275
+
276
+ <br clear="both">
176
277
 
177
278
  ---
178
279
 
package/dist/cli/index.js CHANGED
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
3
 
4
+ // src/cli/install.ts
5
+ import * as readline from "readline";
6
+
4
7
  // src/cli/config-manager.ts
5
8
  import { existsSync, mkdirSync, readFileSync, writeFileSync, statSync } from "fs";
6
9
  import { homedir } from "os";
@@ -270,6 +273,49 @@ function detectCurrentConfig() {
270
273
  }
271
274
 
272
275
  // src/cli/install.ts
276
+ var lineReader = null;
277
+ var lineBuffer = [];
278
+ var lineResolvers = [];
279
+ function initLineReader() {
280
+ if (lineReader)
281
+ return;
282
+ lineReader = readline.createInterface({
283
+ input: process.stdin,
284
+ output: process.stdout,
285
+ terminal: process.stdin.isTTY ?? false
286
+ });
287
+ lineReader.on("line", (line) => {
288
+ if (lineResolvers.length > 0) {
289
+ const resolve = lineResolvers.shift();
290
+ resolve(line);
291
+ } else {
292
+ lineBuffer.push(line);
293
+ }
294
+ });
295
+ lineReader.on("close", () => {
296
+ while (lineResolvers.length > 0) {
297
+ const resolve = lineResolvers.shift();
298
+ resolve("");
299
+ }
300
+ });
301
+ }
302
+ async function readLine() {
303
+ initLineReader();
304
+ if (lineBuffer.length > 0) {
305
+ return lineBuffer.shift();
306
+ }
307
+ return new Promise((resolve) => {
308
+ lineResolvers.push(resolve);
309
+ });
310
+ }
311
+ function closeLineReader() {
312
+ if (lineReader) {
313
+ lineReader.close();
314
+ lineReader = null;
315
+ lineBuffer = [];
316
+ lineResolvers = [];
317
+ }
318
+ }
273
319
  var GREEN = "\x1B[32m";
274
320
  var BLUE = "\x1B[34m";
275
321
  var YELLOW = "\x1B[33m";
@@ -308,6 +354,26 @@ function printInfo(message) {
308
354
  function printWarning(message) {
309
355
  console.log(`${SYMBOLS.warn} ${YELLOW}${message}${RESET}`);
310
356
  }
357
+ async function checkOpenCodeInstalled() {
358
+ const installed = await isOpenCodeInstalled();
359
+ if (!installed) {
360
+ printError("OpenCode is not installed on this system.");
361
+ printInfo("Install it with:");
362
+ console.log(` ${BLUE}curl -fsSL https://opencode.ai/install | bash${RESET}`);
363
+ return { ok: false };
364
+ }
365
+ const version = await getOpenCodeVersion();
366
+ printSuccess(`OpenCode ${version ?? ""} detected`);
367
+ return { ok: true, version: version ?? undefined };
368
+ }
369
+ function handleStepResult(result, successMsg) {
370
+ if (!result.success) {
371
+ printError(`Failed: ${result.error}`);
372
+ return false;
373
+ }
374
+ printSuccess(`${successMsg} ${SYMBOLS.arrow} ${DIM}${result.configPath}${RESET}`);
375
+ return true;
376
+ }
311
377
  function formatConfigSummary(config) {
312
378
  const lines = [];
313
379
  lines.push(`${BOLD}Configuration Summary${RESET}`);
@@ -319,22 +385,15 @@ function formatConfigSummary(config) {
319
385
  `);
320
386
  }
321
387
  function validateNonTuiArgs(args) {
322
- const errors = [];
323
- if (args.antigravity === undefined) {
324
- errors.push("--antigravity is required (values: yes, no)");
325
- } else if (!["yes", "no"].includes(args.antigravity)) {
326
- errors.push(`Invalid --antigravity value: ${args.antigravity} (expected: yes, no)`);
327
- }
328
- if (args.openai === undefined) {
329
- errors.push("--openai is required (values: yes, no)");
330
- } else if (!["yes", "no"].includes(args.openai)) {
331
- errors.push(`Invalid --openai value: ${args.openai} (expected: yes, no)`);
332
- }
333
- if (args.cerebras === undefined) {
334
- errors.push("--cerebras is required (values: yes, no)");
335
- } else if (!["yes", "no"].includes(args.cerebras)) {
336
- errors.push(`Invalid --cerebras value: ${args.cerebras} (expected: yes, no)`);
337
- }
388
+ const requiredArgs = ["antigravity", "openai", "cerebras"];
389
+ const errors = requiredArgs.flatMap((key) => {
390
+ const value = args[key];
391
+ if (value === undefined)
392
+ return [`--${key} is required (values: yes, no)`];
393
+ if (!["yes", "no"].includes(value))
394
+ return [`Invalid --${key} value: ${value} (expected: yes, no)`];
395
+ return [];
396
+ });
338
397
  return { valid: errors.length === 0, errors };
339
398
  }
340
399
  function argsToConfig(args) {
@@ -351,15 +410,12 @@ function detectedToInitialValues(detected) {
351
410
  cerebras: detected.hasCerebras ? "yes" : "no"
352
411
  };
353
412
  }
354
- async function askYesNo(prompt, defaultValue = "no") {
413
+ async function askYesNo(promptText, defaultValue = "no") {
355
414
  const defaultHint = defaultValue === "yes" ? "[Y/n]" : "[y/N]";
356
- process.stdout.write(`${BLUE}${prompt}${RESET} ${defaultHint}: `);
357
- const reader = Bun.stdin.stream().getReader();
358
- const { value } = await reader.read();
359
- reader.releaseLock();
360
- const answer = value ? new TextDecoder().decode(value).trim().toLowerCase() : "";
361
- if (answer === "" || answer === `
362
- `)
415
+ const fullPrompt = `${BLUE}${promptText}${RESET} ${defaultHint}: `;
416
+ process.stdout.write(fullPrompt);
417
+ const answer = (await readLine()).trim().toLowerCase();
418
+ if (answer === "")
363
419
  return defaultValue;
364
420
  if (answer === "y" || answer === "yes")
365
421
  return "yes";
@@ -378,57 +434,41 @@ async function runTuiMode(detected) {
378
434
  console.log(`${BOLD}Question 3/3:${RESET}`);
379
435
  const cerebras = await askYesNo("Do you have access to Cerebras API?", initial.cerebras);
380
436
  console.log();
437
+ closeLineReader();
381
438
  return {
382
439
  hasAntigravity: antigravity === "yes",
383
440
  hasOpenAI: openai === "yes",
384
441
  hasCerebras: cerebras === "yes"
385
442
  };
386
443
  }
387
- async function runInstall(args, config) {
444
+ async function runInstall(config) {
388
445
  const detected = detectCurrentConfig();
389
446
  const isUpdate = detected.isInstalled;
390
447
  printHeader(isUpdate);
391
448
  const totalSteps = config.hasAntigravity ? 5 : 3;
392
449
  let step = 1;
393
450
  printStep(step++, totalSteps, "Checking OpenCode installation...");
394
- const installed = await isOpenCodeInstalled();
395
- if (!installed) {
396
- printError("OpenCode is not installed on this system.");
397
- printInfo("Visit https://opencode.ai/docs for installation instructions");
451
+ const { ok } = await checkOpenCodeInstalled();
452
+ if (!ok)
398
453
  return 1;
399
- }
400
- const version = await getOpenCodeVersion();
401
- printSuccess(`OpenCode ${version ?? ""} detected`);
402
454
  printStep(step++, totalSteps, "Adding oh-my-opencode-slim plugin...");
403
455
  const pluginResult = await addPluginToOpenCodeConfig();
404
- if (!pluginResult.success) {
405
- printError(`Failed: ${pluginResult.error}`);
456
+ if (!handleStepResult(pluginResult, "Plugin added"))
406
457
  return 1;
407
- }
408
- printSuccess(`Plugin added ${SYMBOLS.arrow} ${DIM}${pluginResult.configPath}${RESET}`);
409
458
  if (config.hasAntigravity) {
410
459
  printStep(step++, totalSteps, "Adding auth plugins...");
411
460
  const authResult = await addAuthPlugins(config);
412
- if (!authResult.success) {
413
- printError(`Failed: ${authResult.error}`);
461
+ if (!handleStepResult(authResult, "Auth plugins configured"))
414
462
  return 1;
415
- }
416
- printSuccess(`Auth plugins configured ${SYMBOLS.arrow} ${DIM}${authResult.configPath}${RESET}`);
417
463
  printStep(step++, totalSteps, "Adding provider configurations...");
418
464
  const providerResult = addProviderConfig(config);
419
- if (!providerResult.success) {
420
- printError(`Failed: ${providerResult.error}`);
465
+ if (!handleStepResult(providerResult, "Providers configured"))
421
466
  return 1;
422
- }
423
- printSuccess(`Providers configured ${SYMBOLS.arrow} ${DIM}${providerResult.configPath}${RESET}`);
424
467
  }
425
468
  printStep(step++, totalSteps, "Writing oh-my-opencode-slim configuration...");
426
469
  const liteResult = writeLiteConfig(config);
427
- if (!liteResult.success) {
428
- printError(`Failed: ${liteResult.error}`);
470
+ if (!handleStepResult(liteResult, "Config written"))
429
471
  return 1;
430
- }
431
- printSuccess(`Config written ${SYMBOLS.arrow} ${DIM}${liteResult.configPath}${RESET}`);
432
472
  console.log();
433
473
  console.log(formatConfigSummary(config));
434
474
  console.log();
@@ -463,24 +503,19 @@ async function install(args) {
463
503
  return 1;
464
504
  }
465
505
  const config2 = argsToConfig(args);
466
- return runInstall(args, config2);
506
+ return runInstall(config2);
467
507
  }
468
508
  const detected = detectCurrentConfig();
469
509
  printHeader(detected.isInstalled);
470
510
  printStep(1, 1, "Checking OpenCode installation...");
471
- const installed = await isOpenCodeInstalled();
472
- if (!installed) {
473
- printError("OpenCode is not installed on this system.");
474
- printInfo("Visit https://opencode.ai/docs for installation instructions");
511
+ const { ok } = await checkOpenCodeInstalled();
512
+ if (!ok)
475
513
  return 1;
476
- }
477
- const version = await getOpenCodeVersion();
478
- printSuccess(`OpenCode ${version ?? ""} detected`);
479
514
  console.log();
480
515
  const config = await runTuiMode(detected);
481
516
  if (!config)
482
517
  return 1;
483
- return runInstall(args, config);
518
+ return runInstall(config);
484
519
  }
485
520
 
486
521
  // src/cli/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode-slim",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
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",