oh-my-opencode 2.4.5 → 2.4.7

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.
package/README.ja.md CHANGED
@@ -317,12 +317,12 @@ opencode auth login
317
317
  "agents": {
318
318
  "frontend-ui-ux-engineer": { "model": "google/gemini-3-pro-high" },
319
319
  "document-writer": { "model": "google/gemini-3-flash" },
320
- "multimodal-looker": { "model": "google/gemini-2.5-flash" }
320
+ "multimodal-looker": { "model": "google/gemini-3-flash" }
321
321
  }
322
322
  }
323
323
  ```
324
324
 
325
- **利用可能なモデル名**: `google/gemini-3-pro-high`, `google/gemini-3-pro-medium`, `google/gemini-3-pro-low`, `google/gemini-3-flash`, `google/gemini-2.5-flash`, `google/gemini-2.5-flash-lite`, `google/claude-sonnet-4-5`, `google/claude-sonnet-4-5-thinking`, `google/claude-opus-4-5-thinking`, `google/gpt-oss-120b-medium`
325
+ **利用可能なモデル名**: `google/gemini-3-pro-high`, `google/gemini-3-pro-medium`, `google/gemini-3-pro-low`, `google/gemini-3-flash`, `google/gemini-3-flash`, `google/gemini-3-flash-lite`, `google/claude-sonnet-4-5`, `google/claude-sonnet-4-5-thinking`, `google/claude-opus-4-5-thinking`, `google/gpt-oss-120b-medium`
326
326
 
327
327
  その後、認証を行います:
328
328
 
@@ -432,7 +432,7 @@ gh repo star code-yeongyu/oh-my-opencode
432
432
  - **explore** (`opencode/grok-code`): 高速なコードベース探索、ファイルパターンマッチング。Claude Code は Haiku を使用しますが、私たちは Grok を使います。現在無料であり、極めて高速で、ファイル探索タスクには十分な知能を備えているからです。Claude Code からインスピレーションを得ました。
433
433
  - **frontend-ui-ux-engineer** (`google/gemini-3-pro-preview`): 開発者に転身したデザイナーという設定です。素晴らしい UI を作ります。美しく独創的な UI コードを生成することに長けた Gemini を使用します。
434
434
  - **document-writer** (`google/gemini-3-pro-preview`): テクニカルライティングの専門家という設定です。Gemini は文筆家であり、流れるような文章を書きます。
435
- - **multimodal-looker** (`google/gemini-2.5-flash`): 視覚コンテンツ解釈のための専門エージェント。PDF、画像、図表を分析して情報を抽出します。
435
+ - **multimodal-looker** (`google/gemini-3-flash`): 視覚コンテンツ解釈のための専門エージェント。PDF、画像、図表を分析して情報を抽出します。
436
436
 
437
437
  メインエージェントはこれらを自動的に呼び出しますが、明示的に呼び出すことも可能です:
438
438
 
@@ -675,7 +675,7 @@ Oh My OpenCode は以下の場所からフックを読み込んで実行しま
675
675
  "agents": {
676
676
  "frontend-ui-ux-engineer": { "model": "google/gemini-3-pro-high" },
677
677
  "document-writer": { "model": "google/gemini-3-flash" },
678
- "multimodal-looker": { "model": "google/gemini-2.5-flash" }
678
+ "multimodal-looker": { "model": "google/gemini-3-flash" }
679
679
  }
680
680
  }
681
681
  ```
package/README.ko.md CHANGED
@@ -314,12 +314,12 @@ opencode auth login
314
314
  "agents": {
315
315
  "frontend-ui-ux-engineer": { "model": "google/gemini-3-pro-high" },
316
316
  "document-writer": { "model": "google/gemini-3-flash" },
317
- "multimodal-looker": { "model": "google/gemini-2.5-flash" }
317
+ "multimodal-looker": { "model": "google/gemini-3-flash" }
318
318
  }
319
319
  }
320
320
  ```
321
321
 
322
- **사용 가능한 모델 이름**: `google/gemini-3-pro-high`, `google/gemini-3-pro-medium`, `google/gemini-3-pro-low`, `google/gemini-3-flash`, `google/gemini-2.5-flash`, `google/gemini-2.5-flash-lite`, `google/claude-sonnet-4-5`, `google/claude-sonnet-4-5-thinking`, `google/claude-opus-4-5-thinking`, `google/gpt-oss-120b-medium`
322
+ **사용 가능한 모델 이름**: `google/gemini-3-pro-high`, `google/gemini-3-pro-medium`, `google/gemini-3-pro-low`, `google/gemini-3-flash`, `google/gemini-3-flash`, `google/gemini-3-flash-lite`, `google/claude-sonnet-4-5`, `google/claude-sonnet-4-5-thinking`, `google/claude-opus-4-5-thinking`, `google/gpt-oss-120b-medium`
323
323
 
324
324
  그 후 인증:
325
325
 
@@ -429,7 +429,7 @@ gh repo star code-yeongyu/oh-my-opencode
429
429
  - **explore** (`opencode/grok-code`): 빠른 코드베이스 탐색, 파일 패턴 매칭. Claude Code는 Haiku를 쓰지만, 우리는 Grok을 씁니다. 현재 무료이고, 극도로 빠르며, 파일 탐색 작업에 충분한 지능을 갖췄기 때문입니다. Claude Code 에서 영감을 받았습니다.
430
430
  - **frontend-ui-ux-engineer** (`google/gemini-3-pro-preview`): 개발자로 전향한 디자이너라는 설정을 갖고 있습니다. 멋진 UI를 만듭니다. 아름답고 창의적인 UI 코드를 생성하는 데 탁월한 Gemini를 사용합니다.
431
431
  - **document-writer** (`google/gemini-3-pro-preview`): 기술 문서 전문가라는 설정을 갖고 있습니다. Gemini 는 문학가입니다. 글을 기가막히게 씁니다.
432
- - **multimodal-looker** (`google/gemini-2.5-flash`): 시각적 콘텐츠 해석을 위한 전문 에이전트. PDF, 이미지, 다이어그램을 분석하여 정보를 추출합니다.
432
+ - **multimodal-looker** (`google/gemini-3-flash`): 시각적 콘텐츠 해석을 위한 전문 에이전트. PDF, 이미지, 다이어그램을 분석하여 정보를 추출합니다.
433
433
 
434
434
  각 에이전트는 메인 에이전트가 알아서 호출하지만, 명시적으로 요청할 수도 있습니다:
435
435
 
@@ -669,7 +669,7 @@ Schema 자동 완성이 지원됩니다:
669
669
  "agents": {
670
670
  "frontend-ui-ux-engineer": { "model": "google/gemini-3-pro-high" },
671
671
  "document-writer": { "model": "google/gemini-3-flash" },
672
- "multimodal-looker": { "model": "google/gemini-2.5-flash" }
672
+ "multimodal-looker": { "model": "google/gemini-3-flash" }
673
673
  }
674
674
  }
675
675
  ```
package/README.md CHANGED
@@ -346,12 +346,12 @@ The `opencode-antigravity-auth` plugin uses different model names than the built
346
346
  "agents": {
347
347
  "frontend-ui-ux-engineer": { "model": "google/gemini-3-pro-high" },
348
348
  "document-writer": { "model": "google/gemini-3-flash" },
349
- "multimodal-looker": { "model": "google/gemini-2.5-flash" }
349
+ "multimodal-looker": { "model": "google/gemini-3-flash" }
350
350
  }
351
351
  }
352
352
  ```
353
353
 
354
- **Available model names**: `google/gemini-3-pro-high`, `google/gemini-3-pro-medium`, `google/gemini-3-pro-low`, `google/gemini-3-flash`, `google/gemini-2.5-flash`, `google/gemini-2.5-flash-lite`, `google/claude-sonnet-4-5`, `google/claude-sonnet-4-5-thinking`, `google/claude-opus-4-5-thinking`, `google/gpt-oss-120b-medium`
354
+ **Available model names**: `google/gemini-3-pro-high`, `google/gemini-3-pro-medium`, `google/gemini-3-pro-low`, `google/gemini-3-flash`, `google/gemini-3-flash`, `google/gemini-3-flash-lite`, `google/claude-sonnet-4-5`, `google/claude-sonnet-4-5-thinking`, `google/claude-opus-4-5-thinking`, `google/gpt-oss-120b-medium`
355
355
 
356
356
  Then authenticate:
357
357
 
@@ -493,7 +493,7 @@ To remove oh-my-opencode:
493
493
  - **explore** (`opencode/grok-code`): Fast codebase exploration and pattern matching. Claude Code uses Haiku; we use Grok—it's free, blazing fast, and plenty smart for file traversal. Inspired by Claude Code.
494
494
  - **frontend-ui-ux-engineer** (`google/gemini-3-pro-preview`): A designer turned developer. Builds gorgeous UIs. Gemini excels at creative, beautiful UI code.
495
495
  - **document-writer** (`google/gemini-3-pro-preview`): Technical writing expert. Gemini is a wordsmith—writes prose that flows.
496
- - **multimodal-looker** (`google/gemini-2.5-flash`): Visual content specialist. Analyzes PDFs, images, diagrams to extract information.
496
+ - **multimodal-looker** (`google/gemini-3-flash`): Visual content specialist. Analyzes PDFs, images, diagrams to extract information.
497
497
 
498
498
  The main agent invokes these automatically, but you can call them explicitly:
499
499
 
@@ -733,7 +733,7 @@ When using `opencode-antigravity-auth`, disable the built-in auth and override a
733
733
  "agents": {
734
734
  "frontend-ui-ux-engineer": { "model": "google/gemini-3-pro-high" },
735
735
  "document-writer": { "model": "google/gemini-3-flash" },
736
- "multimodal-looker": { "model": "google/gemini-2.5-flash" }
736
+ "multimodal-looker": { "model": "google/gemini-3-flash" }
737
737
  }
738
738
  }
739
739
  ```
package/README.zh-cn.md CHANGED
@@ -325,12 +325,12 @@ opencode auth login
325
325
  "agents": {
326
326
  "frontend-ui-ux-engineer": { "model": "google/gemini-3-pro-high" },
327
327
  "document-writer": { "model": "google/gemini-3-flash" },
328
- "multimodal-looker": { "model": "google/gemini-2.5-flash" }
328
+ "multimodal-looker": { "model": "google/gemini-3-flash" }
329
329
  }
330
330
  }
331
331
  ```
332
332
 
333
- **可用模型名**:`google/gemini-3-pro-high`, `google/gemini-3-pro-medium`, `google/gemini-3-pro-low`, `google/gemini-3-flash`, `google/gemini-2.5-flash`, `google/gemini-2.5-flash-lite`, `google/claude-sonnet-4-5`, `google/claude-sonnet-4-5-thinking`, `google/claude-opus-4-5-thinking`, `google/gpt-oss-120b-medium`
333
+ **可用模型名**:`google/gemini-3-pro-high`, `google/gemini-3-pro-medium`, `google/gemini-3-pro-low`, `google/gemini-3-flash`, `google/gemini-3-flash`, `google/gemini-3-flash-lite`, `google/claude-sonnet-4-5`, `google/claude-sonnet-4-5-thinking`, `google/claude-opus-4-5-thinking`, `google/gpt-oss-120b-medium`
334
334
 
335
335
  然后认证:
336
336
 
@@ -440,7 +440,7 @@ gh repo star code-yeongyu/oh-my-opencode
440
440
  - **explore** (`opencode/grok-code`):极速代码库扫描、模式匹配。Claude Code 用 Haiku,我们用 Grok——免费、飞快、扫文件够用了。致敬 Claude Code。
441
441
  - **frontend-ui-ux-engineer** (`google/gemini-3-pro-preview`):设计师出身的程序员。UI 做得那是真漂亮。Gemini 写这种创意美观的代码是一绝。
442
442
  - **document-writer** (`google/gemini-3-pro-preview`):技术写作专家。Gemini 文笔好,写出来的东西读着顺畅。
443
- - **multimodal-looker** (`google/gemini-2.5-flash`):视觉内容专家。PDF、图片、图表,看一眼就知道里头有啥。
443
+ - **multimodal-looker** (`google/gemini-3-flash`):视觉内容专家。PDF、图片、图表,看一眼就知道里头有啥。
444
444
 
445
445
  主 Agent 会自动调遣它们,你也可以亲自点名:
446
446
 
@@ -675,7 +675,7 @@ Agent 爽了,你自然也爽。但我还想直接让你爽。
675
675
  "agents": {
676
676
  "frontend-ui-ux-engineer": { "model": "google/gemini-3-pro-high" },
677
677
  "document-writer": { "model": "google/gemini-3-flash" },
678
- "multimodal-looker": { "model": "google/gemini-2.5-flash" }
678
+ "multimodal-looker": { "model": "google/gemini-3-flash" }
679
679
  }
680
680
  }
681
681
  ```
@@ -1,2 +1,34 @@
1
1
  export declare const HOOK_NAME = "non-interactive-env";
2
2
  export declare const NON_INTERACTIVE_ENV: Record<string, string>;
3
+ /**
4
+ * Shell command guidance for non-interactive environments.
5
+ * These patterns should be followed to avoid hanging on user input.
6
+ */
7
+ export declare const SHELL_COMMAND_PATTERNS: {
8
+ readonly npm: {
9
+ readonly bad: readonly ["npm init", "npm install (prompts)"];
10
+ readonly good: readonly ["npm init -y", "npm install --yes"];
11
+ };
12
+ readonly apt: {
13
+ readonly bad: readonly ["apt-get install pkg"];
14
+ readonly good: readonly ["apt-get install -y pkg", "DEBIAN_FRONTEND=noninteractive apt-get install pkg"];
15
+ };
16
+ readonly pip: {
17
+ readonly bad: readonly ["pip install pkg (with prompts)"];
18
+ readonly good: readonly ["pip install --no-input pkg", "PIP_NO_INPUT=1 pip install pkg"];
19
+ };
20
+ readonly git: {
21
+ readonly bad: readonly ["git commit", "git merge branch", "git add -p", "git rebase -i"];
22
+ readonly good: readonly ["git commit -m 'msg'", "git merge --no-edit branch", "git add .", "git rebase --no-edit"];
23
+ };
24
+ readonly system: {
25
+ readonly bad: readonly ["rm file (prompts)", "cp a b (prompts)", "ssh host"];
26
+ readonly good: readonly ["rm -f file", "cp -f a b", "ssh -o BatchMode=yes host", "unzip -o file.zip"];
27
+ };
28
+ readonly banned: readonly ["vim", "nano", "vi", "emacs", "less", "more", "man", "python (REPL)", "node (REPL)", "git add -p", "git rebase -i"];
29
+ readonly workarounds: {
30
+ readonly yesPipe: "yes | ./script.sh";
31
+ readonly heredoc: "./script.sh <<EOF\noption1\noption2\nEOF";
32
+ readonly expectAlternative: "Use environment variables or config files instead of expect";
33
+ };
34
+ };
@@ -8,5 +8,6 @@ export declare function createNonInteractiveEnvHook(_ctx: PluginInput): {
8
8
  callID: string;
9
9
  }, output: {
10
10
  args: Record<string, unknown>;
11
+ message?: string;
11
12
  }) => Promise<void>;
12
13
  };
package/dist/index.js CHANGED
@@ -2674,7 +2674,7 @@ You are a technical writer who creates documentation that developers actually wa
2674
2674
  var multimodalLookerAgent = {
2675
2675
  description: "Analyze media files (PDFs, images, diagrams) that require interpretation beyond raw text. Extracts specific information or summaries from documents, describes visual content. Use when you need analyzed/extracted data rather than literal file contents.",
2676
2676
  mode: "subagent",
2677
- model: "google/gemini-2.5-flash",
2677
+ model: "google/gemini-3-flash",
2678
2678
  temperature: 0.1,
2679
2679
  tools: { write: false, edit: false, bash: false, background_task: false },
2680
2680
  prompt: `You interpret media files that cannot be read as plain text.
@@ -6178,9 +6178,14 @@ function createPreemptiveCompactionHook(ctx, options) {
6178
6178
  state2.compactionInProgress.delete(sessionID);
6179
6179
  setTimeout(async () => {
6180
6180
  try {
6181
+ const messageDir = getMessageDir4(sessionID);
6182
+ const storedMessage = messageDir ? findNearestMessageWithFields(messageDir) : null;
6181
6183
  await ctx.client.session.promptAsync({
6182
6184
  path: { id: sessionID },
6183
- body: { parts: [{ type: "text", text: "Continue" }] },
6185
+ body: {
6186
+ agent: storedMessage?.agent,
6187
+ parts: [{ type: "text", text: "Continue" }]
6188
+ },
6184
6189
  query: { directory: ctx.directory }
6185
6190
  });
6186
6191
  } catch {}
@@ -7355,7 +7360,10 @@ ${result.inputLines ?? ""}`,
7355
7360
  const claudeConfig = await loadClaudeHooksConfig();
7356
7361
  const extendedConfig = await loadPluginExtendedConfig();
7357
7362
  const cachedInput = getToolInput(input.sessionID, input.tool, input.callID) || {};
7358
- recordToolResult(input.sessionID, input.tool, cachedInput, output.metadata || {});
7363
+ const metadata = output.metadata;
7364
+ const hasMetadata = metadata && typeof metadata === "object" && Object.keys(metadata).length > 0;
7365
+ const toolOutput = hasMetadata ? metadata : { output: output.output };
7366
+ recordToolResult(input.sessionID, input.tool, cachedInput, toolOutput);
7359
7367
  if (!isHookDisabled(config, "PostToolUse")) {
7360
7368
  const postClient = {
7361
7369
  session: {
@@ -8634,19 +8642,27 @@ function createKeywordDetectorHook() {
8634
8642
  "chat.message": async (input, output) => {
8635
8643
  const isFirstMessage = !sessionFirstMessageProcessed2.has(input.sessionID);
8636
8644
  sessionFirstMessageProcessed2.add(input.sessionID);
8637
- if (isFirstMessage) {
8638
- log("Skipping keyword detection on first message for title generation", { sessionID: input.sessionID });
8639
- return;
8640
- }
8641
8645
  const promptText = extractPromptText2(output.parts);
8642
8646
  const messages = detectKeywords(promptText);
8643
8647
  if (messages.length === 0) {
8644
8648
  return;
8645
8649
  }
8646
- log(`Keywords detected: ${messages.length}`, { sessionID: input.sessionID });
8647
- const message = output.message;
8648
8650
  const context = messages.join(`
8649
8651
  `);
8652
+ if (isFirstMessage) {
8653
+ log(`Keywords detected on first message, transforming parts directly`, { sessionID: input.sessionID, keywordCount: messages.length });
8654
+ const idx = output.parts.findIndex((p) => p.type === "text" && p.text);
8655
+ if (idx >= 0) {
8656
+ output.parts[idx].text = `${context}
8657
+
8658
+ ---
8659
+
8660
+ ${output.parts[idx].text ?? ""}`;
8661
+ }
8662
+ return;
8663
+ }
8664
+ log(`Keywords detected: ${messages.length}`, { sessionID: input.sessionID });
8665
+ const message = output.message;
8650
8666
  log(`[keyword-detector] Injecting context for ${messages.length} keywords`, { sessionID: input.sessionID, contextLength: context.length });
8651
8667
  const success = injectHookMessage(input.sessionID, context, {
8652
8668
  agent: message.agent,
@@ -8673,10 +8689,65 @@ var NON_INTERACTIVE_ENV = {
8673
8689
  VISUAL: "true",
8674
8690
  GIT_SEQUENCE_EDITOR: "true",
8675
8691
  GIT_PAGER: "cat",
8676
- PAGER: "cat"
8692
+ PAGER: "cat",
8693
+ npm_config_yes: "true",
8694
+ PIP_NO_INPUT: "1",
8695
+ YARN_ENABLE_IMMUTABLE_INSTALLS: "false"
8696
+ };
8697
+ var SHELL_COMMAND_PATTERNS = {
8698
+ npm: {
8699
+ bad: ["npm init", "npm install (prompts)"],
8700
+ good: ["npm init -y", "npm install --yes"]
8701
+ },
8702
+ apt: {
8703
+ bad: ["apt-get install pkg"],
8704
+ good: ["apt-get install -y pkg", "DEBIAN_FRONTEND=noninteractive apt-get install pkg"]
8705
+ },
8706
+ pip: {
8707
+ bad: ["pip install pkg (with prompts)"],
8708
+ good: ["pip install --no-input pkg", "PIP_NO_INPUT=1 pip install pkg"]
8709
+ },
8710
+ git: {
8711
+ bad: ["git commit", "git merge branch", "git add -p", "git rebase -i"],
8712
+ good: ["git commit -m 'msg'", "git merge --no-edit branch", "git add .", "git rebase --no-edit"]
8713
+ },
8714
+ system: {
8715
+ bad: ["rm file (prompts)", "cp a b (prompts)", "ssh host"],
8716
+ good: ["rm -f file", "cp -f a b", "ssh -o BatchMode=yes host", "unzip -o file.zip"]
8717
+ },
8718
+ banned: [
8719
+ "vim",
8720
+ "nano",
8721
+ "vi",
8722
+ "emacs",
8723
+ "less",
8724
+ "more",
8725
+ "man",
8726
+ "python (REPL)",
8727
+ "node (REPL)",
8728
+ "git add -p",
8729
+ "git rebase -i"
8730
+ ],
8731
+ workarounds: {
8732
+ yesPipe: "yes | ./script.sh",
8733
+ heredoc: `./script.sh <<EOF
8734
+ option1
8735
+ option2
8736
+ EOF`,
8737
+ expectAlternative: "Use environment variables or config files instead of expect"
8738
+ }
8677
8739
  };
8678
8740
 
8679
8741
  // src/hooks/non-interactive-env/index.ts
8742
+ var BANNED_COMMAND_PATTERNS = SHELL_COMMAND_PATTERNS.banned.filter((cmd) => !cmd.includes("(")).map((cmd) => new RegExp(`\\b${cmd}\\b`));
8743
+ function detectBannedCommand(command) {
8744
+ for (let i = 0;i < BANNED_COMMAND_PATTERNS.length; i++) {
8745
+ if (BANNED_COMMAND_PATTERNS[i].test(command)) {
8746
+ return SHELL_COMMAND_PATTERNS.banned[i];
8747
+ }
8748
+ }
8749
+ return;
8750
+ }
8680
8751
  function createNonInteractiveEnvHook(_ctx) {
8681
8752
  return {
8682
8753
  "tool.execute.before": async (input, output) => {
@@ -8691,6 +8762,10 @@ function createNonInteractiveEnvHook(_ctx) {
8691
8762
  ...output.args.env,
8692
8763
  ...NON_INTERACTIVE_ENV
8693
8764
  };
8765
+ const bannedCmd = detectBannedCommand(command);
8766
+ if (bannedCmd) {
8767
+ output.message = `\u26A0\uFE0F Warning: '${bannedCmd}' is an interactive command that may hang in non-interactive environments.`;
8768
+ }
8694
8769
  log(`[${HOOK_NAME2}] Set non-interactive environment variables`, {
8695
8770
  sessionID: input.sessionID,
8696
8771
  env: NON_INTERACTIVE_ENV
@@ -26710,6 +26785,30 @@ session_id: ${sessionID}
26710
26785
  var MULTIMODAL_LOOKER_AGENT = "multimodal-looker";
26711
26786
  var LOOK_AT_DESCRIPTION = `Analyze media files (PDFs, images, diagrams) via Gemini 2.5 Flash in separate context. Saves main context tokens.`;
26712
26787
  // src/tools/look-at/tools.ts
26788
+ import { extname as extname3, basename as basename4 } from "path";
26789
+ function inferMimeType(filePath) {
26790
+ const ext = extname3(filePath).toLowerCase();
26791
+ const mimeTypes = {
26792
+ ".jpg": "image/jpeg",
26793
+ ".jpeg": "image/jpeg",
26794
+ ".png": "image/png",
26795
+ ".gif": "image/gif",
26796
+ ".webp": "image/webp",
26797
+ ".svg": "image/svg+xml",
26798
+ ".bmp": "image/bmp",
26799
+ ".ico": "image/x-icon",
26800
+ ".pdf": "application/pdf",
26801
+ ".txt": "text/plain",
26802
+ ".md": "text/markdown",
26803
+ ".json": "application/json",
26804
+ ".xml": "application/xml",
26805
+ ".html": "text/html",
26806
+ ".css": "text/css",
26807
+ ".js": "text/javascript",
26808
+ ".ts": "text/typescript"
26809
+ };
26810
+ return mimeTypes[ext] || "application/octet-stream";
26811
+ }
26713
26812
  function createLookAt(ctx) {
26714
26813
  return tool({
26715
26814
  description: LOOK_AT_DESCRIPTION,
@@ -26719,12 +26818,13 @@ function createLookAt(ctx) {
26719
26818
  },
26720
26819
  async execute(args, toolContext) {
26721
26820
  log(`[look_at] Analyzing file: ${args.file_path}, goal: ${args.goal}`);
26821
+ const mimeType = inferMimeType(args.file_path);
26822
+ const filename = basename4(args.file_path);
26722
26823
  const prompt = `Analyze this file and extract the requested information.
26723
26824
 
26724
- File path: ${args.file_path}
26725
26825
  Goal: ${args.goal}
26726
26826
 
26727
- Read the file using the Read tool, then provide ONLY the extracted information that matches the goal.
26827
+ Provide ONLY the extracted information that matches the goal.
26728
26828
  Be thorough on what was requested, concise on everything else.
26729
26829
  If the requested information is not found, clearly state what is missing.`;
26730
26830
  log(`[look_at] Creating session with parent: ${toolContext.sessionID}`);
@@ -26740,7 +26840,7 @@ If the requested information is not found, clearly state what is missing.`;
26740
26840
  }
26741
26841
  const sessionID = createResult.data.id;
26742
26842
  log(`[look_at] Created session: ${sessionID}`);
26743
- log(`[look_at] Sending prompt to session ${sessionID}`);
26843
+ log(`[look_at] Sending prompt with file passthrough to session ${sessionID}`);
26744
26844
  await ctx.client.session.prompt({
26745
26845
  path: { id: sessionID },
26746
26846
  body: {
@@ -26748,9 +26848,13 @@ If the requested information is not found, clearly state what is missing.`;
26748
26848
  tools: {
26749
26849
  task: false,
26750
26850
  call_omo_agent: false,
26751
- look_at: false
26851
+ look_at: false,
26852
+ read: false
26752
26853
  },
26753
- parts: [{ type: "text", text: prompt }]
26854
+ parts: [
26855
+ { type: "text", text: prompt },
26856
+ { type: "file", mime: mimeType, url: `file://${args.file_path}`, filename }
26857
+ ]
26754
26858
  }
26755
26859
  });
26756
26860
  log(`[look_at] Prompt sent, fetching messages...`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode",
3
- "version": "2.4.5",
3
+ "version": "2.4.7",
4
4
  "description": "OpenCode plugin - custom agents (oracle, librarian) and enhanced features",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",