opencode-ultra 0.2.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.
package/README.md ADDED
@@ -0,0 +1,419 @@
1
+ # opencode-ultra
2
+
3
+ [oh-my-opencode](https://github.com/code-yeongyu/oh-my-opencode) をベースにした OpenCode 1.2.x プラグイン。
4
+ マルチエージェントオーケストレーション・キーワード駆動モード切替・ルール注入を軽量な単一プラグインで実現する。
5
+
6
+ ## oh-my-opencode との違い
7
+
8
+ | | oh-my-opencode | opencode-ultra |
9
+ |---|---|---|
10
+ | 構成 | フルスタック (LSP, AST-Grep, MCP, Hook 25+, Ralph Loop, Comment Checker...) | **オーケストレーション特化** — 同等機能を軽量に再実装 |
11
+ | エージェント表 | ハードコード | **設定から動的生成** — `oh-my-opencode.json` のオーバーライドが Sisyphus のプロンプトに自動反映 |
12
+ | プラン承認 | なし (即実行) | **Plan-First Protocol** — spawn_agent 前に Phase 形式のプランを提示、ユーザー承認を待つ |
13
+ | 並列制御 | バックグラウンドタスク API | **Semaphore ベース** — グローバル/プロバイダー/モデル単位で同時実行制限 |
14
+ | Categories | ハードコード | **設定可能** — カテゴリでモデル/バリアントを一括切替 |
15
+ | Ralph Loop | 外部ツール依存 | **ビルトインツール** — `<promise>DONE</promise>` マーカーで完了検知 |
16
+ | Comment Checker | 外部バイナリ (AST-Grep) | **正規表現ベース** — AIスロップパターン検知 |
17
+ | Todo Enforcer | `tool.execute.after` 方式 | **`session.idle` イベント方式** — セッション idle 時に未完了 TODO を検査 |
18
+ | MCP | Exa, Context7, grep_app | **Context7 のみ** (API キー不要で動作、キーありでレートリミット緩和) |
19
+ | 依存 | 多数 (Exa, tmux...) | **最小限** (`@opencode-ai/plugin`, `jsonc-parser`, `zod`) |
20
+ | 設定形式 | JSON | **JSONC** (コメント・末尾カンマ対応) |
21
+
22
+ ## アーキテクチャ
23
+
24
+ ```
25
+ User
26
+
27
+ │ "ultrawork" / "ulw" キーワード
28
+
29
+
30
+ ┌──────────────────────────────────────────────┐
31
+ │ opencode-ultra plugin │
32
+ │ │
33
+ │ chat.message hook │
34
+ │ ├─ keyword-detector │
35
+ │ │ └─ ultrawork / search / analyze │
36
+ │ └─ ultrawork → variant: "max" │
37
+ │ │
38
+ │ system.transform hook │
39
+ │ ├─ keyword message injection │
40
+ │ └─ rules-injector (.opencode/rules.md) │
41
+ │ │
42
+ │ tool.execute.after hook │
43
+ │ └─ comment-checker (Write/Edit 後に検査) │
44
+ │ │
45
+ │ event hook │
46
+ │ ├─ session cleanup │
47
+ │ └─ todo-enforcer (session.idle 時に検査) │
48
+ │ │
49
+ │ config hook │
50
+ │ └─ register agents to OpenCode │
51
+ │ │
52
+ │ tools │
53
+ │ ├─ spawn_agent (並列実行 + 並列制御) │
54
+ │ ├─ ralph_loop (自律ループ実行) │
55
+ │ └─ cancel_ralph (ループキャンセル) │
56
+ │ │
57
+ │ MCP registration │
58
+ │ └─ context7 (自動登録) │
59
+ └──────────────┬───────────────────────────────┘
60
+
61
+ │ spawn_agent({ agents: [...] })
62
+
63
+ ┌─────────┼─────────┐
64
+ ▼ ▼ ▼
65
+ Session Session Session (ephemeral)
66
+ Agent A Agent B Agent C
67
+ │ │ │
68
+ ▲ ▲ ▲
69
+ └── ConcurrencyPool ┘
70
+ (Semaphore制御)
71
+ ```
72
+
73
+ ## エージェント構成
74
+
75
+ Sisyphus (オーケストレーター) が直接ツールを使わず、全てを spawn_agent 経由でサブエージェントに委任する。
76
+
77
+ ### ビルトインデフォルト
78
+
79
+ | Agent | 役割 | デフォルトモデル | モード |
80
+ |-------|------|-----------------|--------|
81
+ | **sisyphus** | オーケストレーター — 分析・計画・委任 | anthropic/claude-opus-4-5 | primary |
82
+ | **oracle** | 設計・デバッグ・アーキテクチャ判断 | openai/gpt-5.2 | subagent |
83
+ | **explore** | 高速コードベース偵察 | anthropic/claude-haiku-4-5 | subagent |
84
+ | **librarian** | ドキュメント・ベストプラクティス調査 | anthropic/claude-sonnet-4-5 | subagent |
85
+ | **metis** | タスク分解・並列実行計画 | anthropic/claude-sonnet-4-5 | subagent |
86
+ | **hephaestus** | 自律型実装ワーカー | openai/gpt-5.2 | subagent |
87
+ | **momus** | コードレビュー・品質チェック | anthropic/claude-sonnet-4-5 | subagent |
88
+ | **atlas** | タスク管理・進捗追跡 | anthropic/claude-sonnet-4-5 | subagent |
89
+ | **multimodal-looker** | 画像・スクリーンショット解析 | anthropic/claude-sonnet-4-5 | subagent |
90
+
91
+ **全てのモデルは `oh-my-opencode.json` でオーバーライド可能。** Sisyphus のプロンプト内エージェント表にはオーバーライド後の実際のモデル名が動的に埋め込まれる。
92
+
93
+ ### Sisyphus の制約
94
+
95
+ Sisyphus は以下のツールが**物理的に無効化**されている:
96
+
97
+ ```
98
+ Grep: false, Glob: false, Read: false,
99
+ Write: false, Edit: false, Bash: false
100
+ ```
101
+
102
+ 使えるのは `spawn_agent`、`ralph_loop`、`cancel_ralph` と TODO 系ツールのみ。これにより高コストな Orchestrator トークンの浪費を防ぎ、適切なモデルへの委任を強制する。
103
+
104
+ ## Plan-First Protocol
105
+
106
+ Sisyphus は spawn_agent を呼ぶ前に、必ず以下の形式でプランを提示する:
107
+
108
+ ```
109
+ ## Execution Plan
110
+
111
+ ### Phase 1: 偵察 (parallel)
112
+ - [ ] API ルート探索 → explore (gpt-5.3-codex-spark)
113
+ - [ ] フレームワーク仕様調査 → librarian (glm-4.7)
114
+
115
+ ### Phase 2: 実装 (after Phase 1)
116
+ - [ ] エンドポイント実装 → hephaestus (gpt-5.2)
117
+
118
+ ### Phase 3: Review
119
+ - [ ] コードレビュー → momus (gpt-5.3-codex)
120
+
121
+ Estimated agents: 4 | Phases: 3
122
+ ```
123
+
124
+ - 独立タスクは同一 Phase にグループ化 (並列実行)
125
+ - 依存関係があるタスクは別 Phase
126
+ - エージェント名 + 実際のモデル名を表示
127
+ - **「このプランで進めますか?」で承認待ち — OK するまで実行しない**
128
+
129
+ ## spawn_agent ツール
130
+
131
+ Sisyphus が使う並列エージェント実行ツール。
132
+
133
+ ```typescript
134
+ spawn_agent({
135
+ agents: [
136
+ { agent: "explore", prompt: "Find all API routes in src/", description: "Route discovery" },
137
+ { agent: "librarian", prompt: "Research Express middleware best practices", description: "Middleware docs" },
138
+ { agent: "hephaestus", prompt: "Implement the feature", description: "Implementation", category: "deep" }
139
+ ]
140
+ })
141
+ ```
142
+
143
+ - 複数エージェントは **Promise.all で並列実行**(ConcurrencyPool による同時実行制御付き)
144
+ - 各エージェントは**エフェメラルセッション**で起動 — 完了後に自動削除
145
+ - 内部セッションには `internalSessions` フラグを付与し、**フックの再帰を防止**
146
+ - 進捗は `toolCtx.metadata({ title })` でステータスバーに表示
147
+ - Toast 通知で個別エージェントの完了を通知
148
+ - **`category` パラメータ**でモデル/バリアントをカテゴリから自動解決
149
+
150
+ ### 並列制御 (Concurrency)
151
+
152
+ `background_task` が設定されていると、Semaphore ベースの並列制御が有効になる。
153
+
154
+ ```
155
+ spawn_agent に 5 エージェント渡す
156
+ → defaultConcurrency: 3 なら同時 3 個まで
157
+ → 残りは空きを待って順次実行
158
+ ```
159
+
160
+ | 設定フィールド | 目的 | 動作 |
161
+ |---------------|------|------|
162
+ | `defaultConcurrency` | 全体の同時実行上限 | 全エージェント合計で N 個まで同時実行 |
163
+ | `providerConcurrency` | プロバイダー別上限 (例: openai: 8) | 同一プロバイダーのエージェントを N 個に制限 |
164
+ | `modelConcurrency` | モデル別上限 (例: gpt-5.2: 2) | 同一モデルのエージェントを N 個に制限 |
165
+
166
+ セマフォは model → provider → global の順で acquire し、global → provider → model の順で release する。エラー時も確実に release される。
167
+
168
+ `background_task` 未設定の場合は制限なし(従来通り全エージェント同時発火)。
169
+
170
+ ## Categories
171
+
172
+ spawn_agent の `category` パラメータでモデル/バリアントを一括切替できる。
173
+
174
+ ### ビルトインカテゴリ
175
+
176
+ | カテゴリ | 用途 | デフォルトモデル | バリアント |
177
+ |---------|------|-----------------|-----------|
178
+ | `visual-engineering` | フロントエンド/UI実装 | google/gemini-3-pro | — |
179
+ | `ultrabrain` | 最高精度タスク | openai/gpt-5.3-codex | xhigh |
180
+ | `deep` | 深い分析・複雑ロジック | openai/gpt-5.3-codex | medium |
181
+ | `quick` | 高速・低コストタスク | anthropic/claude-haiku-4-5 | — |
182
+ | `writing` | ドキュメント・文章 | zai-coding-plan/glm-4.7 | — |
183
+
184
+ 設定ファイルでカスタムカテゴリの追加やビルトインの上書きが可能:
185
+
186
+ ```jsonc
187
+ {
188
+ "categories": {
189
+ "quick": { "model": "openai/gpt-4o-mini" },
190
+ "my-custom": { "model": "custom/model", "variant": "high" }
191
+ }
192
+ }
193
+ ```
194
+
195
+ ## Ralph Loop
196
+
197
+ 自律ループ実行ツール。エージェントが `<promise>DONE</promise>` を出力するか、最大イテレーション数に達するまで繰り返し実行する。
198
+
199
+ ```typescript
200
+ ralph_loop({
201
+ prompt: "Implement all unit tests for the auth module",
202
+ agent: "hephaestus", // default
203
+ maxIterations: 10 // default
204
+ })
205
+ ```
206
+
207
+ - 各イテレーションで前回の進捗をレビューし、続きから再開するよう指示
208
+ - ステータスバーに `Ralph Loop [3/10] — hephaestus` のように進捗表示
209
+ - `cancel_ralph` ツールで実行中のループを全てキャンセル可能
210
+
211
+ ## Todo Enforcer
212
+
213
+ セッションが idle になったとき、最後の assistant メッセージに未完了の TODO(`- [ ]`)がある場合、強制継続プロンプトを送信する。
214
+
215
+ - **最大 5 回**(デフォルト)の強制で無限ループを防止
216
+ - spawn_agent のサブセッションには適用されない
217
+ - `disabled_hooks: ["todo-enforcer"]` で無効化可能
218
+ - 設定で最大回数を変更可能: `"todo_enforcer": { "maxEnforcements": 3 }`
219
+
220
+ ## Comment Checker
221
+
222
+ Write / Edit ツール実行後に、書き込まれたファイルのコメント品質を検査する。
223
+
224
+ ### 検出するパターン
225
+
226
+ - コメント比率が 30% を超えるファイル
227
+ - 80 文字超の行コメント (`// This function does...`)
228
+ - 説明的すぎる冒頭 (`// This`, `// The`, `// We`, `// Here`, `// Note:`)
229
+ - AI プレースホルダー (`// TODO: implement`)
230
+ - lint 回避コメント (`// eslint-disable`)
231
+ - 300 文字超の巨大 JSDoc
232
+
233
+ 閾値超えの場合、ツール出力に `[Comment Checker]` 警告を追加する。
234
+
235
+ ```jsonc
236
+ {
237
+ "comment_checker": {
238
+ "maxRatio": 0.3, // コメント比率閾値 (default: 0.3)
239
+ "slopThreshold": 3 // AIスロップパターン数閾値 (default: 3)
240
+ }
241
+ }
242
+ ```
243
+
244
+ ## MCP 自動登録
245
+
246
+ プラグイン初期化時に以下の MCP サーバーを自動登録する:
247
+
248
+ | MCP | パッケージ | API キー |
249
+ |-----|-----------|----------|
250
+ | **Context7** | `@upstash/context7-mcp` | オプション(あるとレートリミット緩和) |
251
+
252
+ API キーの渡し方:
253
+
254
+ ```jsonc
255
+ {
256
+ "mcp_api_keys": {
257
+ "context7": "ctx7sk-..."
258
+ }
259
+ }
260
+ ```
261
+
262
+ または環境変数 `CONTEXT7_API_KEY` を設定。
263
+
264
+ `disabled_mcps: ["context7"]` で無効化可能。
265
+
266
+ ## キーワード検知
267
+
268
+ ユーザーのプロンプトからキーワードを検知し、system prompt に動作モード指示を注入する。
269
+ コードブロック (`` ``` `` / `` ` ``) 内のキーワードは無視する。
270
+
271
+ | キーワード | モード | 効果 |
272
+ |-----------|--------|------|
273
+ | `ultrawork` / `ulw` | ultrawork | variant を "max" に設定。全エージェント活用・並列実行・TODO 追跡を強制。ユーザーメッセージからキーワードを除去 |
274
+ | `search` / `find` / `探して` / `検索` 等 | search | 複数 explore + librarian エージェントを並列起動。網羅的検索を強制 |
275
+ | `analyze` / `調査` / `なぜ` / `debug` 等 | analyze | コンテキスト収集フェーズを実行。複雑な場合は Oracle に委任 |
276
+
277
+ 日本語・中国語キーワードにも対応。
278
+
279
+ ## ルール注入
280
+
281
+ `<project>/.opencode/rules.md` が存在する場合、その内容を system prompt に `## Project Rules` として自動注入する。ファイルの mtime でキャッシュし、変更時のみ再読み込み。
282
+
283
+ ## 設定
284
+
285
+ 2 段階の設定マージ:
286
+
287
+ 1. **ユーザー設定**: `~/.config/opencode/oh-my-opencode.json[c]`
288
+ 2. **プロジェクト設定**: `<project>/.opencode/oh-my-opencode.json[c]`
289
+
290
+ プロジェクト設定がユーザー設定をオーバーライドする。
291
+
292
+ ### 設定スキーマ
293
+
294
+ ```jsonc
295
+ {
296
+ // エージェントごとのモデル・プロンプトオーバーライド
297
+ "agents": {
298
+ "sisyphus": { "model": "openai/gpt-5.2" },
299
+ "oracle": { "model": "zai-coding-plan/glm-5" },
300
+ "explore": { "model": "openai/gpt-5.3-codex-spark" }
301
+ },
302
+
303
+ // カテゴリ (spawn_agent の category パラメータで使用)
304
+ "categories": {
305
+ "quick": { "model": "openai/gpt-4o-mini" }
306
+ },
307
+
308
+ // 無効化
309
+ "disabled_agents": [],
310
+ "disabled_hooks": ["keyword-detector", "rules-injector", "todo-enforcer", "comment-checker"],
311
+ "disabled_tools": ["ralph_loop", "cancel_ralph", "spawn_agent"],
312
+ "disabled_mcps": ["context7"],
313
+
314
+ // 並列制御
315
+ "background_task": {
316
+ "defaultConcurrency": 3,
317
+ "providerConcurrency": {
318
+ "openai": 8,
319
+ "zai-coding-plan": 10
320
+ },
321
+ "modelConcurrency": {
322
+ "openai/gpt-5.2": 2
323
+ }
324
+ },
325
+
326
+ // Comment Checker 設定
327
+ "comment_checker": {
328
+ "maxRatio": 0.3,
329
+ "slopThreshold": 3
330
+ },
331
+
332
+ // Todo Enforcer 設定
333
+ "todo_enforcer": {
334
+ "maxEnforcements": 5
335
+ },
336
+
337
+ // MCP API キー
338
+ "mcp_api_keys": {
339
+ "context7": "ctx7sk-..."
340
+ }
341
+ }
342
+ ```
343
+
344
+ ### エージェントオーバーライドで使えるフィールド
345
+
346
+ | フィールド | 型 | 説明 |
347
+ |-----------|---|------|
348
+ | `model` | string | 使用モデル (provider/model 形式) |
349
+ | `description` | string | エージェントの説明 |
350
+ | `prompt` | string | システムプロンプト全体を差し替え |
351
+ | `prompt_append` | string | プロンプト末尾に追記 |
352
+ | `disable` | boolean | 個別に無効化 |
353
+ | `mode` | `"subagent"` / `"primary"` / `"all"` | 実行モード |
354
+ | `maxTokens` | number | 最大出力トークン |
355
+ | `thinking` | `{ type, budgetTokens }` | 思考トークン設定 |
356
+ | `reasoningEffort` | `"low"` / `"medium"` / `"high"` / `"xhigh"` | 推論レベル |
357
+ | `temperature` | number (0-2) | サンプリング温度 |
358
+ | `top_p` | number (0-1) | Top-p |
359
+ | `category` | string | デフォルトカテゴリ |
360
+ | `variant` | string | モデルバリアント |
361
+
362
+ ## フック再帰防止
363
+
364
+ spawn_agent / ralph_loop で生成されたエフェメラルセッションは `internalSessions` Set で追跡される。`chat.message`、`system.transform`、`tool.execute.after`、`event` の各フックは内部セッションに対してスキップされ、キーワード検知・ルール注入・Comment Checker・Todo Enforcer がサブエージェントに二重適用されることを防ぐ。
365
+
366
+ ## プロジェクト構成
367
+
368
+ ```
369
+ opencode-ultra/
370
+ ├── src/
371
+ │ ├── index.ts # プラグインエントリポイント (hook/tool/MCP 統合)
372
+ │ ├── config.ts # 設定ロード・マージ・バリデーション (Zod)
373
+ │ ├── agents/
374
+ │ │ ├── types.ts # AgentDef 型定義
375
+ │ │ └── index.ts # ビルトインエージェント定義 + 動的プロンプト生成
376
+ │ ├── hooks/
377
+ │ │ ├── keyword-detector.ts # ultrawork/search/analyze キーワード検知
378
+ │ │ ├── rules-injector.ts # .opencode/rules.md 注入 (mtime キャッシュ)
379
+ │ │ ├── todo-enforcer.ts # session.idle 時の未完了 TODO 強制継続
380
+ │ │ └── comment-checker.ts # Write/Edit 後の AI スロップ検知
381
+ │ ├── tools/
382
+ │ │ ├── spawn-agent.ts # spawn_agent ツール (並列実行 + 並列制御 + カテゴリ)
383
+ │ │ └── ralph-loop.ts # ralph_loop / cancel_ralph ツール (自律ループ)
384
+ │ ├── concurrency/
385
+ │ │ ├── semaphore.ts # 汎用セマフォ
386
+ │ │ ├── pool.ts # ConcurrencyPool (global/provider/model 三層制御)
387
+ │ │ └── index.ts # バレルエクスポート
388
+ │ ├── categories/
389
+ │ │ └── index.ts # ビルトインカテゴリ + resolveCategory
390
+ │ ├── mcp/
391
+ │ │ ├── servers.ts # ビルトイン MCP サーバー定義
392
+ │ │ └── index.ts # MCP 登録ロジック
393
+ │ └── shared/
394
+ │ ├── paths.ts # XDG パス解決
395
+ │ ├── jsonc.ts # JSONC パーサー
396
+ │ ├── log.ts # [opencode-ultra] プレフィックスログ
397
+ │ └── index.ts # バレルエクスポート
398
+ ├── __test__/ # Bun テスト (70 tests)
399
+ ├── package.json
400
+ ├── tsconfig.json
401
+ └── .gitignore
402
+ ```
403
+
404
+ ## ビルド・テスト
405
+
406
+ ```bash
407
+ # 依存インストール
408
+ bun install
409
+
410
+ # ビルド
411
+ bun build src/index.ts --outdir dist --target bun --format esm
412
+
413
+ # テスト
414
+ bun test
415
+ ```
416
+
417
+ ## ライセンス
418
+
419
+ MIT
@@ -0,0 +1,15 @@
1
+ import type { AgentDef } from "./types";
2
+ export type { AgentDef } from "./types";
3
+ export declare const BUILTIN_AGENTS: Record<string, AgentDef>;
4
+ type AgentOverride = {
5
+ model?: string;
6
+ description?: string;
7
+ prompt?: string;
8
+ [key: string]: unknown;
9
+ };
10
+ type MinimalPluginConfig = {
11
+ agents?: Record<string, AgentOverride | undefined>;
12
+ disabled_agents?: string[];
13
+ [key: string]: unknown;
14
+ };
15
+ export declare function buildAgents(config: Partial<MinimalPluginConfig>): Record<string, AgentDef>;
@@ -0,0 +1,13 @@
1
+ export interface AgentDef {
2
+ model: string;
3
+ description: string;
4
+ prompt: string;
5
+ mode?: "subagent" | "primary" | "all";
6
+ maxTokens?: number;
7
+ thinking?: {
8
+ type: "enabled" | "disabled";
9
+ budgetTokens?: number;
10
+ };
11
+ reasoningEffort?: "low" | "medium" | "high" | "xhigh";
12
+ tools?: Record<string, boolean>;
13
+ }
@@ -0,0 +1,8 @@
1
+ export interface CategoryDef {
2
+ description: string;
3
+ model: string;
4
+ variant?: string;
5
+ }
6
+ export type CategoryConfig = Partial<CategoryDef>;
7
+ export declare const DEFAULT_CATEGORIES: Record<string, CategoryDef>;
8
+ export declare function resolveCategory(categoryName: string, configCategories?: Record<string, CategoryConfig>): CategoryDef | undefined;
@@ -0,0 +1,2 @@
1
+ export { Semaphore } from "./semaphore";
2
+ export { ConcurrencyPool, extractProvider, type ConcurrencyConfig } from "./pool";
@@ -0,0 +1,14 @@
1
+ export interface ConcurrencyConfig {
2
+ defaultConcurrency?: number;
3
+ providerConcurrency?: Record<string, number>;
4
+ modelConcurrency?: Record<string, number>;
5
+ }
6
+ export declare function extractProvider(model: string): string;
7
+ export declare class ConcurrencyPool {
8
+ private global;
9
+ private providers;
10
+ private models;
11
+ private config;
12
+ constructor(config: ConcurrencyConfig);
13
+ run<T>(model: string, fn: () => Promise<T>): Promise<T>;
14
+ }
@@ -0,0 +1,10 @@
1
+ export declare class Semaphore {
2
+ private max;
3
+ private queue;
4
+ private active;
5
+ constructor(max: number);
6
+ acquire(): Promise<void>;
7
+ release(): void;
8
+ get pending(): number;
9
+ get running(): number;
10
+ }
@@ -0,0 +1,60 @@
1
+ import { z } from "zod";
2
+ declare const PluginConfigSchema: z.ZodObject<{
3
+ agents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodOptional<z.ZodObject<{
4
+ model: z.ZodOptional<z.ZodString>;
5
+ variant: z.ZodOptional<z.ZodString>;
6
+ category: z.ZodOptional<z.ZodString>;
7
+ temperature: z.ZodOptional<z.ZodNumber>;
8
+ top_p: z.ZodOptional<z.ZodNumber>;
9
+ prompt: z.ZodOptional<z.ZodString>;
10
+ prompt_append: z.ZodOptional<z.ZodString>;
11
+ disable: z.ZodOptional<z.ZodBoolean>;
12
+ description: z.ZodOptional<z.ZodString>;
13
+ mode: z.ZodOptional<z.ZodEnum<{
14
+ subagent: "subagent";
15
+ primary: "primary";
16
+ all: "all";
17
+ }>>;
18
+ maxTokens: z.ZodOptional<z.ZodNumber>;
19
+ thinking: z.ZodOptional<z.ZodObject<{
20
+ type: z.ZodEnum<{
21
+ enabled: "enabled";
22
+ disabled: "disabled";
23
+ }>;
24
+ budgetTokens: z.ZodOptional<z.ZodNumber>;
25
+ }, z.core.$strip>>;
26
+ reasoningEffort: z.ZodOptional<z.ZodEnum<{
27
+ low: "low";
28
+ medium: "medium";
29
+ high: "high";
30
+ xhigh: "xhigh";
31
+ }>>;
32
+ }, z.core.$loose>>>>;
33
+ categories: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
34
+ model: z.ZodOptional<z.ZodString>;
35
+ variant: z.ZodOptional<z.ZodString>;
36
+ }, z.core.$loose>>>;
37
+ disabled_agents: z.ZodOptional<z.ZodArray<z.ZodString>>;
38
+ disabled_hooks: z.ZodOptional<z.ZodArray<z.ZodString>>;
39
+ disabled_tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
40
+ disabled_mcps: z.ZodOptional<z.ZodArray<z.ZodString>>;
41
+ background_task: z.ZodOptional<z.ZodObject<{
42
+ defaultConcurrency: z.ZodOptional<z.ZodNumber>;
43
+ providerConcurrency: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
44
+ modelConcurrency: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
45
+ staleTimeoutMs: z.ZodOptional<z.ZodNumber>;
46
+ }, z.core.$strip>>;
47
+ comment_checker: z.ZodOptional<z.ZodObject<{
48
+ maxRatio: z.ZodOptional<z.ZodNumber>;
49
+ slopThreshold: z.ZodOptional<z.ZodNumber>;
50
+ }, z.core.$strip>>;
51
+ todo_enforcer: z.ZodOptional<z.ZodObject<{
52
+ maxEnforcements: z.ZodOptional<z.ZodNumber>;
53
+ }, z.core.$strip>>;
54
+ mcp_api_keys: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
55
+ }, z.core.$loose>;
56
+ export type PluginConfig = z.infer<typeof PluginConfigSchema>;
57
+ export declare function parsePluginConfig(raw: unknown): PluginConfig;
58
+ export declare function mergeConfigs(base: PluginConfig, override: PluginConfig): PluginConfig;
59
+ export declare function loadConfig(projectDir: string): PluginConfig;
60
+ export {};
@@ -0,0 +1,17 @@
1
+ export interface CommentCheckResult {
2
+ ratio: number;
3
+ slopCount: number;
4
+ shouldWarn: boolean;
5
+ message: string;
6
+ }
7
+ export declare function isCodeFile(filePath: string): boolean;
8
+ export declare function checkComments(content: string, filePath: string, maxRatio?: number, slopThreshold?: number): CommentCheckResult;
9
+ export declare function createCommentCheckerHook(internalSessions: Set<string>, maxRatio?: number, slopThreshold?: number): (input: {
10
+ tool: {
11
+ name: string;
12
+ };
13
+ args: Record<string, unknown>;
14
+ sessionID: string;
15
+ }, output: {
16
+ output: string;
17
+ }) => void;
@@ -0,0 +1,10 @@
1
+ export interface DetectedKeyword {
2
+ type: "ultrawork" | "search" | "analyze";
3
+ message: string;
4
+ }
5
+ export declare function removeCodeBlocks(text: string): string;
6
+ export declare function extractPromptText(parts: Array<{
7
+ type: string;
8
+ text?: string;
9
+ }>): string;
10
+ export declare function detectKeywords(text: string): DetectedKeyword[];
@@ -0,0 +1,2 @@
1
+ export declare function loadRules(projectDir: string): string | null;
2
+ export declare function clearRulesCache(): void;
@@ -0,0 +1,14 @@
1
+ import type { PluginInput } from "@opencode-ai/plugin";
2
+ interface Todo {
3
+ text: string;
4
+ completed: boolean;
5
+ }
6
+ export declare function createTodoEnforcer(ctx: PluginInput, internalSessions: Set<string>, maxEnforcements?: number): {
7
+ onEvent(event: {
8
+ type: string;
9
+ properties?: unknown;
10
+ }): Promise<void>;
11
+ cleanup(sessionID: string): void;
12
+ };
13
+ export declare function extractTodos(text: string): Todo[];
14
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ declare const OpenCodeUltra: Plugin;
3
+ export default OpenCodeUltra;
4
+ export type { PluginConfig } from "./config";