@ag-eco/agentplate-cli 0.15.0 → 0.15.1
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/package.json +1 -1
- package/src/runtimes/opencode.test.ts +25 -9
- package/src/runtimes/opencode.ts +25 -16
- package/src/version.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ag-eco/agentplate-cli",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "Multi-agent orchestration for AI coding agents — spawn workers in git worktrees via tmux, coordinate through SQLite mail, merge with tiered conflict resolution. Pluggable runtime adapters for Claude Code, Pi, and more.",
|
|
5
5
|
"author": "Jaymin West",
|
|
6
6
|
"license": "MIT",
|
|
@@ -143,20 +143,36 @@ describe("OpenCodeRuntime", () => {
|
|
|
143
143
|
});
|
|
144
144
|
});
|
|
145
145
|
|
|
146
|
-
describe("detectReady
|
|
147
|
-
|
|
146
|
+
describe("detectReady", () => {
|
|
147
|
+
// Snapshot of the opencode 1.14.x ready TUI (input box + status bar).
|
|
148
|
+
const readyPane = [
|
|
149
|
+
'┃ Ask anything... "What is the tech stack of this project?"',
|
|
150
|
+
"┃ Build · Big Pickle OpenCode Zen",
|
|
151
|
+
" tab agents ctrl+p commands",
|
|
152
|
+
" /tmp/project:main 1.14.39",
|
|
153
|
+
].join("\n");
|
|
154
|
+
|
|
155
|
+
// Same TUI with the "Update Available" modal overlaid (outdated install).
|
|
156
|
+
const modalPane = [
|
|
157
|
+
" Update Available esc",
|
|
158
|
+
" A new release v1.15.12 is available. Would you like to",
|
|
159
|
+
" update now?",
|
|
160
|
+
" Skip Confirm",
|
|
161
|
+
'┃ Ask anything... "What is the tech stack of this project?"',
|
|
162
|
+
" tab agents ctrl+p commands",
|
|
163
|
+
].join("\n");
|
|
164
|
+
|
|
165
|
+
test("returns loading for empty / partial pane", () => {
|
|
148
166
|
expect(runtime.detectReady("")).toEqual({ phase: "loading" });
|
|
167
|
+
expect(runtime.detectReady("starting opencode...")).toEqual({ phase: "loading" });
|
|
149
168
|
});
|
|
150
169
|
|
|
151
|
-
test("returns
|
|
152
|
-
expect(runtime.detectReady(
|
|
153
|
-
expect(runtime.detectReady("ready")).toEqual({ phase: "loading" });
|
|
154
|
-
expect(runtime.detectReady("opencode started")).toEqual({ phase: "loading" });
|
|
170
|
+
test("returns ready once the input box + status bar render", () => {
|
|
171
|
+
expect(runtime.detectReady(readyPane)).toEqual({ phase: "ready" });
|
|
155
172
|
});
|
|
156
173
|
|
|
157
|
-
test("
|
|
158
|
-
|
|
159
|
-
expect(state.phase).not.toBe("dialog");
|
|
174
|
+
test("surfaces the Update Available modal as an Escape dialog (checked before ready)", () => {
|
|
175
|
+
expect(runtime.detectReady(modalPane)).toEqual({ phase: "dialog", action: "Escape" });
|
|
160
176
|
});
|
|
161
177
|
});
|
|
162
178
|
|
package/src/runtimes/opencode.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// - Uses `opencode` CLI for interactive sessions
|
|
6
6
|
// - Instruction file: AGENTS.md (unverified — needs confirmation against real OpenCode install)
|
|
7
7
|
// - No hooks: OpenCode does not support Claude Code's hook mechanism
|
|
8
|
-
// - detectReady
|
|
8
|
+
// - detectReady: implemented from observed opencode 1.14.x TUI strings
|
|
9
9
|
// - parseTranscript returns null: output format not yet verified
|
|
10
10
|
|
|
11
11
|
import { mkdir } from "node:fs/promises";
|
|
@@ -28,14 +28,13 @@ import type {
|
|
|
28
28
|
* - Uses `--model` flag for model selection
|
|
29
29
|
* - Instruction file lives at `AGENTS.md` (unverified — confirm against real install)
|
|
30
30
|
* - No hooks deployment (OpenCode has no Claude Code hook mechanism)
|
|
31
|
-
* - `detectReady`
|
|
31
|
+
* - `detectReady` — implemented from observed opencode 1.14.x TUI strings
|
|
32
32
|
* - `parseTranscript` returns null — `opencode` output format not yet verified
|
|
33
33
|
*
|
|
34
|
-
* TODO: Once
|
|
34
|
+
* TODO: Once deeper OpenCode integration is needed:
|
|
35
35
|
* 1. Verify `instructionPath` — run `opencode` and check which file it reads
|
|
36
|
-
* 2. Fill in `
|
|
37
|
-
* 3. Fill in `
|
|
38
|
-
* 4. Fill in `getTranscriptDir` — check where OpenCode writes session files
|
|
36
|
+
* 2. Fill in `parseTranscript` — run `opencode run --format json` and inspect output
|
|
37
|
+
* 3. Fill in `getTranscriptDir` — check where OpenCode writes session files
|
|
39
38
|
*/
|
|
40
39
|
export class OpenCodeRuntime implements AgentRuntime {
|
|
41
40
|
/** Unique identifier for this runtime. */
|
|
@@ -126,18 +125,28 @@ export class OpenCodeRuntime implements AgentRuntime {
|
|
|
126
125
|
/**
|
|
127
126
|
* Detect OpenCode TUI readiness from a tmux pane content snapshot.
|
|
128
127
|
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
128
|
+
* Observed against opencode 1.14.x in tmux:
|
|
129
|
+
* - Ready TUI: the input placeholder "Ask anything..." plus a status bar with
|
|
130
|
+
* command hints ("ctrl+p commands" / "tab agents").
|
|
131
|
+
* - On outdated installs, an "Update Available" modal blocks the TUI until
|
|
132
|
+
* dismissed; we surface it as a dialog so the readiness loop sends Escape
|
|
133
|
+
* (the modal's documented dismiss key) and then re-checks for the ready TUI.
|
|
134
134
|
*
|
|
135
|
-
* @param
|
|
136
|
-
* @returns
|
|
135
|
+
* @param paneContent - Captured tmux pane content
|
|
136
|
+
* @returns Current readiness phase
|
|
137
137
|
*/
|
|
138
|
-
detectReady(
|
|
139
|
-
//
|
|
140
|
-
//
|
|
138
|
+
detectReady(paneContent: string): ReadyState {
|
|
139
|
+
// "Update Available" modal (shown on outdated opencode) intercepts input —
|
|
140
|
+
// dismiss it with Escape before treating the TUI as ready. Checked first
|
|
141
|
+
// because the ready TUI renders behind the modal.
|
|
142
|
+
if (paneContent.includes("Update Available")) {
|
|
143
|
+
return { phase: "dialog", action: "Escape" };
|
|
144
|
+
}
|
|
145
|
+
const hasPrompt = paneContent.includes("Ask anything");
|
|
146
|
+
const hasStatusBar = paneContent.includes("ctrl+p") || paneContent.includes("tab agents");
|
|
147
|
+
if (hasPrompt && hasStatusBar) {
|
|
148
|
+
return { phase: "ready" };
|
|
149
|
+
}
|
|
141
150
|
return { phase: "loading" };
|
|
142
151
|
}
|
|
143
152
|
|
package/src/version.ts
CHANGED