@hiai-gg/hiai-opencode 0.1.8 → 0.1.9
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 +68 -1
- package/dist/config/schema/oh-my-opencode-config.d.ts +2 -0
- package/dist/config/schema/ralph-loop.d.ts +2 -0
- package/dist/hooks/todo-continuation-enforcer/auto-loop.d.ts +23 -0
- package/dist/hooks/todo-continuation-enforcer/handler.d.ts +5 -0
- package/dist/hooks/todo-continuation-enforcer/idle-event.d.ts +5 -0
- package/dist/hooks/todo-continuation-enforcer/types.d.ts +18 -0
- package/dist/index.js +706 -645
- package/dist/plugin/hooks/create-continuation-hooks.d.ts +2 -1
- package/hiai-opencode.json +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# hiai-opencode
|
|
2
2
|
|
|
3
|
-
[](https://github.com/HiAi-gg/hiai-opencode/actions/workflows/ci.yml)
|
|
3
|
+
[](https://github.com/HiAi-gg/hiai-opencode/actions/workflows/ci.yml?query=branch%3Amain)
|
|
4
4
|
|
|
5
5
|
`hiai-opencode` is an OpenCode plugin that turns vanilla OpenCode into an opinionated multi-agent cockpit.
|
|
6
6
|
|
|
@@ -98,6 +98,29 @@ MCP integrations and which agents use them:
|
|
|
98
98
|
- MCP wiring for `playwright`, `stitch`, `sequential-thinking`, `firecrawl`, `rag`, `mempalace`, `context7`, plus remote `websearch` and `grep_app`
|
|
99
99
|
- LSP wiring for TypeScript, Svelte, Python, Bash, and ESLint
|
|
100
100
|
|
|
101
|
+
## Continuation, Ralph-Loop, And Auto-Start
|
|
102
|
+
|
|
103
|
+
The plugin runs three layered mechanisms so a session does not give up halfway through a TODO list.
|
|
104
|
+
|
|
105
|
+
| Mechanism | Trigger | What it does |
|
|
106
|
+
|-----------|---------|--------------|
|
|
107
|
+
| **Todo continuation enforcer** | `session.idle` while open todos remain | Injects a continuation prompt after a 2s countdown. Backs off on stagnation, abort, token-limit, and pending-question. |
|
|
108
|
+
| **Ralph-loop** | `/ralph-loop <goal>` or `/ulw-loop <goal>` | Runs an explicit completion loop. Stops on `<promise>DONE</promise>`. Cancel with `/cancel-ralph`. |
|
|
109
|
+
| **Auto ralph-loop** | N+ open todos in one session | Auto-starts ralph-loop in ULTRAWORK mode so each iteration is forced to delegate to specialist agents (researcher / strategist / coder / critic). |
|
|
110
|
+
|
|
111
|
+
Tune the auto-start threshold in `hiai-opencode.json`:
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"ralph_loop": {
|
|
116
|
+
"enabled": true,
|
|
117
|
+
"auto_start_threshold": 5
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`auto_start_threshold: 0` disables auto-start. The enforcer always yields to ralph-loop while it owns the session, so the two never inject duplicate prompts.
|
|
123
|
+
|
|
101
124
|
## Requirements
|
|
102
125
|
|
|
103
126
|
Minimum:
|
|
@@ -493,6 +516,50 @@ On some Windows/OpenCode environments, local MCP process spawning can fail with
|
|
|
493
516
|
|
|
494
517
|
This most often affects `sequential-thinking` and `mempalace`, and sometimes local `npx`-backed tools.
|
|
495
518
|
|
|
519
|
+
## Troubleshooting MCP Servers
|
|
520
|
+
|
|
521
|
+
### Firecrawl tools return "FIRECRAWL_API_KEY missing"
|
|
522
|
+
|
|
523
|
+
The `skill_mcp` env scrubber filters `process.env` before launching stdio MCP servers — secret-shaped names (`*_API_KEY`, `*_TOKEN`, etc.) and npm/pnpm config vars are stripped so they cannot leak into a malicious server. Keys you set via `hiai-opencode.json` are an explicit allowlist and pass through.
|
|
524
|
+
|
|
525
|
+
If your key only lives in `process.env`, move it into the MCP `environment` block:
|
|
526
|
+
|
|
527
|
+
```json
|
|
528
|
+
{
|
|
529
|
+
"mcp": {
|
|
530
|
+
"firecrawl": {
|
|
531
|
+
"enabled": true,
|
|
532
|
+
"environment": { "FIRECRAWL_API_KEY": "fc-..." }
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
(Versions ≤ 0.1.8 had a bug where customEnv was merged before filtering, so even an explicit `FIRECRAWL_API_KEY` got stripped. Fixed in 0.1.9 — explicit `environment` always wins over the filter.)
|
|
539
|
+
|
|
540
|
+
### Playwright MCP fails to find Chromium
|
|
541
|
+
|
|
542
|
+
When `@playwright/mcp` cannot locate a system browser, point it at one explicitly:
|
|
543
|
+
|
|
544
|
+
```json
|
|
545
|
+
{
|
|
546
|
+
"mcp": {
|
|
547
|
+
"playwright": {
|
|
548
|
+
"enabled": true,
|
|
549
|
+
"environment": {
|
|
550
|
+
"PLAYWRIGHT_MCP_EXECUTABLE_PATH": "/usr/bin/chromium"
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
The path can be Chromium, Chrome, or Edge. Run `npx playwright install chromium` first if no browser is installed.
|
|
558
|
+
|
|
559
|
+
### `skill_mcp(playwright)` connects to localhost:3001 and fails
|
|
560
|
+
|
|
561
|
+
If `mcp__playwright__browser_*` works but `skill_mcp(mcp_name="playwright", ...)` errors with a connection to `localhost:3001/mcp`, you have a leftover HTTP-mode MCP registration in your global or parent `opencode.json`. Either start the HTTP server, or remove that registration so the plugin's stdio registration (`npx @playwright/mcp@latest`) is the only one. As a workaround, agents (Vision, Critic) can call `mcp__playwright__browser_*` direct tools instead of going through `skill_mcp`.
|
|
562
|
+
|
|
496
563
|
## Diagnostics
|
|
497
564
|
|
|
498
565
|
The plugin now emits startup warnings for common misconfiguration, including:
|
|
@@ -4177,6 +4177,8 @@ export declare const HiaiOpenCodeConfigSchema: z.ZodObject<{
|
|
|
4177
4177
|
reset: "reset";
|
|
4178
4178
|
continue: "continue";
|
|
4179
4179
|
}>>;
|
|
4180
|
+
auto_start_threshold: z.ZodDefault<z.ZodNumber>;
|
|
4181
|
+
auto_start_with_strategist: z.ZodDefault<z.ZodBoolean>;
|
|
4180
4182
|
}, z.core.$strip>>;
|
|
4181
4183
|
runtime_fallback: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
|
|
4182
4184
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -7,5 +7,7 @@ export declare const RalphLoopConfigSchema: z.ZodObject<{
|
|
|
7
7
|
reset: "reset";
|
|
8
8
|
continue: "continue";
|
|
9
9
|
}>>;
|
|
10
|
+
auto_start_threshold: z.ZodDefault<z.ZodNumber>;
|
|
11
|
+
auto_start_with_strategist: z.ZodDefault<z.ZodBoolean>;
|
|
10
12
|
}, z.core.$strip>;
|
|
11
13
|
export type RalphLoopConfig = z.infer<typeof RalphLoopConfigSchema>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Todo } from "./types";
|
|
2
|
+
export type AutoLoopDecision = {
|
|
3
|
+
kind: "skip";
|
|
4
|
+
reason: string;
|
|
5
|
+
} | {
|
|
6
|
+
kind: "start";
|
|
7
|
+
openTodos: number;
|
|
8
|
+
goal: string;
|
|
9
|
+
};
|
|
10
|
+
export type AutoLoopInputs = {
|
|
11
|
+
threshold: number | undefined;
|
|
12
|
+
todos: Todo[];
|
|
13
|
+
alreadyStarted: boolean;
|
|
14
|
+
hasStartCallback: boolean;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Pure decision: should the enforcer auto-start ralph-loop right now?
|
|
18
|
+
* Kept separate so it can be unit-tested without mocking the full plugin
|
|
19
|
+
* context. The caller is responsible for actually invoking startRalphLoop
|
|
20
|
+
* and updating session state.
|
|
21
|
+
*/
|
|
22
|
+
export declare function decideAutoLoop(input: AutoLoopInputs): AutoLoopDecision;
|
|
23
|
+
export declare function buildAutoLoopGoal(openTodos: number): string;
|
|
@@ -7,6 +7,11 @@ export declare function createTodoContinuationHandler(args: {
|
|
|
7
7
|
backgroundManager?: BackgroundManager;
|
|
8
8
|
skipAgents?: string[];
|
|
9
9
|
isContinuationStopped?: (sessionID: string) => boolean;
|
|
10
|
+
autoLoopThreshold?: number;
|
|
11
|
+
startRalphLoop?: (sessionID: string, prompt: string, options?: {
|
|
12
|
+
ultrawork?: boolean;
|
|
13
|
+
}) => boolean;
|
|
14
|
+
isRalphLoopActive?: (sessionID: string) => boolean;
|
|
10
15
|
}): (input: {
|
|
11
16
|
event: {
|
|
12
17
|
type: string;
|
|
@@ -8,4 +8,9 @@ export declare function handleSessionIdle(args: {
|
|
|
8
8
|
backgroundManager?: BackgroundManager;
|
|
9
9
|
skipAgents?: string[];
|
|
10
10
|
isContinuationStopped?: (sessionID: string) => boolean;
|
|
11
|
+
autoLoopThreshold?: number;
|
|
12
|
+
startRalphLoop?: (sessionID: string, prompt: string, options?: {
|
|
13
|
+
ultrawork?: boolean;
|
|
14
|
+
}) => boolean;
|
|
15
|
+
isRalphLoopActive?: (sessionID: string) => boolean;
|
|
11
16
|
}): Promise<void>;
|
|
@@ -4,6 +4,23 @@ export interface TodoContinuationEnforcerOptions {
|
|
|
4
4
|
backgroundManager?: BackgroundManager;
|
|
5
5
|
skipAgents?: string[];
|
|
6
6
|
isContinuationStopped?: (sessionID: string) => boolean;
|
|
7
|
+
/**
|
|
8
|
+
* If set to N >= 1, the enforcer will auto-start ralph-loop on a session that
|
|
9
|
+
* has N or more open todos and no active loop. 0/undefined disables.
|
|
10
|
+
*/
|
|
11
|
+
autoLoopThreshold?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Lazy callback to start ralph-loop. Lazy because ralph-loop is created
|
|
14
|
+
* after the enforcer in the plugin wiring.
|
|
15
|
+
*/
|
|
16
|
+
startRalphLoop?: (sessionID: string, prompt: string, options?: {
|
|
17
|
+
ultrawork?: boolean;
|
|
18
|
+
}) => boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Lazy callback returning true if ralph-loop is currently active for the
|
|
21
|
+
* session. Used to avoid double-injection.
|
|
22
|
+
*/
|
|
23
|
+
isRalphLoopActive?: (sessionID: string) => boolean;
|
|
7
24
|
}
|
|
8
25
|
export interface TodoContinuationEnforcer {
|
|
9
26
|
handler: (input: {
|
|
@@ -40,6 +57,7 @@ export interface SessionState {
|
|
|
40
57
|
recentCompactionAt?: number;
|
|
41
58
|
recentCompactionEpoch?: number;
|
|
42
59
|
acknowledgedCompactionEpoch?: number;
|
|
60
|
+
autoLoopStarted?: boolean;
|
|
43
61
|
}
|
|
44
62
|
export interface MessageInfo {
|
|
45
63
|
id?: string;
|