@glrs-dev/cli 2.4.0 → 2.4.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/CHANGELOG.md +6 -0
- package/dist/node_modules/@glrs-dev/adapter-opencode/dist/index.d.ts +261 -0
- package/dist/node_modules/@glrs-dev/adapter-opencode/dist/index.js +488 -0
- package/dist/node_modules/@glrs-dev/adapter-opencode/package.json +8 -0
- package/dist/node_modules/@glrs-dev/autopilot/dist/auto-ship-LCT6LIH7.js +7 -0
- package/dist/node_modules/@glrs-dev/autopilot/dist/changeset-generator-DG3MVWVV.js +15 -0
- package/dist/node_modules/@glrs-dev/autopilot/dist/chunk-7OSEI5TF.js +249 -0
- package/dist/node_modules/@glrs-dev/autopilot/dist/chunk-E7PWTRFO.js +91 -0
- package/dist/node_modules/@glrs-dev/autopilot/dist/chunk-M2ZVBPWL.js +101 -0
- package/dist/node_modules/@glrs-dev/autopilot/dist/chunk-Q4ULU6ER.js +68 -0
- package/dist/node_modules/@glrs-dev/autopilot/dist/chunk-VITL2Z45.js +2772 -0
- package/dist/node_modules/@glrs-dev/autopilot/dist/chunk-ZNJWARTM.js +449 -0
- package/dist/node_modules/@glrs-dev/autopilot/dist/index.d.ts +1765 -0
- package/dist/node_modules/@glrs-dev/autopilot/dist/index.js +688 -0
- package/dist/node_modules/@glrs-dev/autopilot/dist/logger-UITJGIZE.js +8 -0
- package/dist/node_modules/@glrs-dev/autopilot/dist/loop-session-XKL3NHUA.js +8 -0
- package/dist/node_modules/@glrs-dev/autopilot/dist/plan-enrichment-D3RPJR2J.js +14 -0
- package/dist/node_modules/@glrs-dev/autopilot/package.json +8 -0
- package/dist/vendor/harness-opencode/dist/index.js +1 -1
- package/dist/vendor/harness-opencode/package.json +1 -1
- package/package.json +9 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @glrs-dev/cli
|
|
2
2
|
|
|
3
|
+
## 2.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#75](https://github.com/iceglober/glrs/pull/75) [`9532a63`](https://github.com/iceglober/glrs/commit/9532a63157cc0edad7822452e710848052dde9fa) Thanks [@iceglober](https://github.com/iceglober)! - Fix `@glrs-dev/cli@2.4.0` install failure caused by `workspace:*` references to private packages leaking into the published tarball. The cli now vendors `@glrs-dev/autopilot` and `@glrs-dev/adapter-opencode` into its `dist/node_modules/` and strips workspace references from the published `package.json`.
|
|
8
|
+
|
|
3
9
|
## 2.4.0
|
|
4
10
|
|
|
5
11
|
## 2.3.0
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { OpencodeClient } from '@opencode-ai/sdk';
|
|
3
|
+
import { AgentAdapter, AgentHandle, AdapterSessionResult } from '@glrs-dev/autopilot';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* OpenCode server lifecycle helpers.
|
|
7
|
+
*
|
|
8
|
+
* General-purpose utilities for starting an OpenCode server, creating
|
|
9
|
+
* sessions, sending messages, and waiting for idle. Used by the Ralph
|
|
10
|
+
* autopilot loop and any future feature that needs to drive OpenCode
|
|
11
|
+
* programmatically.
|
|
12
|
+
*
|
|
13
|
+
* Extracted from src/pilot/server.ts so these helpers are not coupled
|
|
14
|
+
* to the pilot subsystem.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
declare const execFileP: typeof execFile.__promisify__;
|
|
18
|
+
type StartedServer = {
|
|
19
|
+
url: string;
|
|
20
|
+
client: OpencodeClient;
|
|
21
|
+
shutdown: () => Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
type SessionResult = {
|
|
24
|
+
kind: "idle";
|
|
25
|
+
} | {
|
|
26
|
+
kind: "stall";
|
|
27
|
+
stallMs: number;
|
|
28
|
+
} | {
|
|
29
|
+
kind: "abort";
|
|
30
|
+
} | {
|
|
31
|
+
kind: "error";
|
|
32
|
+
message: string;
|
|
33
|
+
} | {
|
|
34
|
+
kind: "question_rejected";
|
|
35
|
+
title: string;
|
|
36
|
+
};
|
|
37
|
+
declare const DEFAULT_STARTUP_TIMEOUT_MS = 30000;
|
|
38
|
+
/**
|
|
39
|
+
* Start an OpenCode server for the given working directory.
|
|
40
|
+
* Returns the server URL, a bound client, and a shutdown function.
|
|
41
|
+
*
|
|
42
|
+
* Uses createOpencode() which spawns the server process and creates
|
|
43
|
+
* a connected client. The server inherits process.cwd() as its project
|
|
44
|
+
* directory.
|
|
45
|
+
*/
|
|
46
|
+
declare function startServer(opts: {
|
|
47
|
+
cwd: string;
|
|
48
|
+
port?: number;
|
|
49
|
+
timeoutMs?: number;
|
|
50
|
+
}): Promise<StartedServer>;
|
|
51
|
+
/**
|
|
52
|
+
* Verify the server is responsive by listing sessions.
|
|
53
|
+
* Fails fast with a diagnostic if the server isn't working.
|
|
54
|
+
*/
|
|
55
|
+
declare function selfTest(client: OpencodeClient): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Create a new OpenCode session for the given directory.
|
|
58
|
+
*
|
|
59
|
+
* Note: the SDK's `session.create` body takes only `parentID` and `title`
|
|
60
|
+
* — agent selection is a per-message concern in OpenCode's model and lives
|
|
61
|
+
* on `session.prompt`'s body, not on session creation. The working
|
|
62
|
+
* directory is passed via the `query.directory` param.
|
|
63
|
+
*
|
|
64
|
+
* Returns the session ID.
|
|
65
|
+
*/
|
|
66
|
+
declare function createSession(client: OpencodeClient, opts: {
|
|
67
|
+
cwd: string;
|
|
68
|
+
agentName?: string;
|
|
69
|
+
}): Promise<string>;
|
|
70
|
+
/**
|
|
71
|
+
* Send a message to a session and wait for the agent to go idle.
|
|
72
|
+
*
|
|
73
|
+
* Uses `session.prompt` (the correct SDK method for sending a message).
|
|
74
|
+
* `session.chat` does not exist on the SDK — an earlier version of this
|
|
75
|
+
* module used that name and silently failed at runtime.
|
|
76
|
+
*
|
|
77
|
+
* The optional `onToolCall` callback fires once per tool invocation that
|
|
78
|
+
* reaches the `completed` state. Used by the autopilot loop to emit
|
|
79
|
+
* debug-level log events for each tool call.
|
|
80
|
+
*
|
|
81
|
+
* The optional `onTextDelta` callback fires for each assistant text
|
|
82
|
+
* chunk the agent streams. Used by the autopilot loop's stream-liveness
|
|
83
|
+
* indicator — between tool calls, the agent may stream text for minutes
|
|
84
|
+
* while reasoning, and without this signal the user can't distinguish
|
|
85
|
+
* "still working" from "hung."
|
|
86
|
+
*
|
|
87
|
+
* When `autoRejectPermissions: true`, any `permission.updated` event
|
|
88
|
+
* fired for this session is immediately answered with `response: "reject"`.
|
|
89
|
+
* Used by autopilot to prevent the `question` tool (or any tool-approval
|
|
90
|
+
* prompt) from deadlocking the session — no human is available to answer.
|
|
91
|
+
* The `onPermissionRejected` callback (if provided) fires each time a
|
|
92
|
+
* permission is auto-rejected so the caller can log it.
|
|
93
|
+
*
|
|
94
|
+
* Returns the result kind.
|
|
95
|
+
*/
|
|
96
|
+
declare function sendAndWait(client: OpencodeClient, opts: {
|
|
97
|
+
sessionId: string;
|
|
98
|
+
message: string;
|
|
99
|
+
agentName?: string;
|
|
100
|
+
stallMs?: number;
|
|
101
|
+
abortSignal?: AbortSignal;
|
|
102
|
+
onToolCall?: (toolName: string, firstArg?: string) => void;
|
|
103
|
+
onTextDelta?: (charCount: number) => void;
|
|
104
|
+
/** Fires on `message.updated` events with cost/token data. Used for
|
|
105
|
+
* real-time cost visibility during long iterations. */
|
|
106
|
+
onCostUpdate?: (cost: number, tokens: {
|
|
107
|
+
input: number;
|
|
108
|
+
output: number;
|
|
109
|
+
}) => void;
|
|
110
|
+
autoRejectPermissions?: boolean;
|
|
111
|
+
/** Server URL for raw HTTP calls (question-reject endpoint). */
|
|
112
|
+
serverUrl?: string;
|
|
113
|
+
onPermissionRejected?: (permission: {
|
|
114
|
+
id: string;
|
|
115
|
+
type: string;
|
|
116
|
+
title: string;
|
|
117
|
+
}) => void;
|
|
118
|
+
}): Promise<SessionResult>;
|
|
119
|
+
/**
|
|
120
|
+
* Wait for a session to go idle (agent done), stall, abort, or error.
|
|
121
|
+
*
|
|
122
|
+
* `client.event.subscribe()` is async and returns `{ stream }` (a
|
|
123
|
+
* `ServerSentEventsResult`). The stream is an AsyncGenerator of events.
|
|
124
|
+
*
|
|
125
|
+
* When `onToolCall` is provided, fires once per tool invocation that
|
|
126
|
+
* reaches the `completed` state. Filters out pending/running transitions
|
|
127
|
+
* to avoid double-counting.
|
|
128
|
+
*
|
|
129
|
+
* When `onTextDelta` is provided, fires for each non-empty delta string
|
|
130
|
+
* the server emits (charCount = delta.length). Used by autopilot to
|
|
131
|
+
* signal liveness during long reasoning streams between tool calls.
|
|
132
|
+
*
|
|
133
|
+
* When `autoRejectPermissions: true`, any `permission.updated` event
|
|
134
|
+
* for this session is answered with `response: "reject"` via
|
|
135
|
+
* `POST /session/{id}/permissions/{permissionID}`. This prevents the
|
|
136
|
+
* `question` tool (and any tool-approval prompts) from deadlocking the
|
|
137
|
+
* session when no human is present to answer. `onPermissionRejected`
|
|
138
|
+
* fires synchronously with the permission payload so callers can log.
|
|
139
|
+
*/
|
|
140
|
+
declare function waitForIdle(client: OpencodeClient, opts: {
|
|
141
|
+
sessionId: string;
|
|
142
|
+
stallMs?: number;
|
|
143
|
+
abortSignal?: AbortSignal;
|
|
144
|
+
onToolCall?: (toolName: string, firstArg?: string) => void;
|
|
145
|
+
onTextDelta?: (charCount: number) => void;
|
|
146
|
+
/** Fires on `message.updated` events with cost/token data. Used for
|
|
147
|
+
* real-time cost visibility during long iterations. */
|
|
148
|
+
onCostUpdate?: (cost: number, tokens: {
|
|
149
|
+
input: number;
|
|
150
|
+
output: number;
|
|
151
|
+
}) => void;
|
|
152
|
+
autoRejectPermissions?: boolean;
|
|
153
|
+
/** Server URL for raw HTTP calls (question-reject endpoint). */
|
|
154
|
+
serverUrl?: string;
|
|
155
|
+
onPermissionRejected?: (permission: {
|
|
156
|
+
id: string;
|
|
157
|
+
type: string;
|
|
158
|
+
title: string;
|
|
159
|
+
}) => void;
|
|
160
|
+
}): Promise<SessionResult>;
|
|
161
|
+
/**
|
|
162
|
+
* Get the cumulative cost of a session in USD.
|
|
163
|
+
*
|
|
164
|
+
* Cost is tracked per-message on the server (AssistantMessage.cost),
|
|
165
|
+
* not aggregated on the Session object. We sum across all assistant
|
|
166
|
+
* messages to get a session total.
|
|
167
|
+
*/
|
|
168
|
+
declare function getSessionCost(client: OpencodeClient, sessionId: string): Promise<number>;
|
|
169
|
+
/**
|
|
170
|
+
* Get cumulative cost + token totals for a session.
|
|
171
|
+
*
|
|
172
|
+
* Sums cost, input tokens, and output tokens across all assistant
|
|
173
|
+
* messages. Returns zeros on any error (non-fatal).
|
|
174
|
+
*/
|
|
175
|
+
declare function getSessionStats(client: OpencodeClient, sessionId: string): Promise<{
|
|
176
|
+
cost: number;
|
|
177
|
+
tokensIn: number;
|
|
178
|
+
tokensOut: number;
|
|
179
|
+
}>;
|
|
180
|
+
/**
|
|
181
|
+
* Fetch the last assistant message text from a session.
|
|
182
|
+
*
|
|
183
|
+
* Calls `client.session.messages()`, filters to assistant-role messages,
|
|
184
|
+
* takes the last one, and concatenates all text parts.
|
|
185
|
+
*
|
|
186
|
+
* Returns an empty string if there are no assistant messages or if the
|
|
187
|
+
* API call fails.
|
|
188
|
+
*/
|
|
189
|
+
declare function getLastAssistantMessage(client: OpencodeClient, sessionId: string): Promise<string>;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Extract actionable error details from OpenCode server logs.
|
|
193
|
+
*
|
|
194
|
+
* When the SSE `session.error` event carries only a generic "session error"
|
|
195
|
+
* message, the real error (credential failure, model not found, etc.) is
|
|
196
|
+
* only in the OpenCode server's own log at ~/.local/share/opencode/log/.
|
|
197
|
+
*
|
|
198
|
+
* This module reads the most recent log file and extracts the last
|
|
199
|
+
* session.processor error line — which contains the actual provider error.
|
|
200
|
+
*/
|
|
201
|
+
/**
|
|
202
|
+
* Read the most recent OpenCode server log and extract the last
|
|
203
|
+
* session.processor error message. Returns null if no log found
|
|
204
|
+
* or no error extracted.
|
|
205
|
+
*
|
|
206
|
+
* This is best-effort — the log directory may not exist, the log
|
|
207
|
+
* format may change, or the error may not be present. Callers
|
|
208
|
+
* should fall back to the generic message when this returns null.
|
|
209
|
+
*/
|
|
210
|
+
declare function extractServerError(): string | null;
|
|
211
|
+
/**
|
|
212
|
+
* Enhance a generic "session error" message with details from the
|
|
213
|
+
* OpenCode server log. If the log contains a more specific error,
|
|
214
|
+
* returns that. Otherwise returns the original message unchanged.
|
|
215
|
+
*/
|
|
216
|
+
declare function enhanceSessionError(genericMessage: string): string;
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* OpenCodeAdapter — implements AgentAdapter using the OpenCode SDK.
|
|
220
|
+
*
|
|
221
|
+
* Wraps the low-level opencode-server.ts functions into the AgentAdapter
|
|
222
|
+
* interface so the autopilot loop engine can drive OpenCode without
|
|
223
|
+
* importing the SDK directly.
|
|
224
|
+
*/
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* OpenCode implementation of AgentAdapter.
|
|
228
|
+
* Creates and manages OpenCode server instances.
|
|
229
|
+
*/
|
|
230
|
+
declare class OpenCodeAdapter implements AgentAdapter {
|
|
231
|
+
readonly name = "opencode";
|
|
232
|
+
start(opts: {
|
|
233
|
+
cwd: string;
|
|
234
|
+
}): Promise<AgentHandle>;
|
|
235
|
+
createSession(handle: AgentHandle, opts: {
|
|
236
|
+
agentName?: string;
|
|
237
|
+
}): Promise<string>;
|
|
238
|
+
sendAndWait(handle: AgentHandle, opts: {
|
|
239
|
+
sessionId: string;
|
|
240
|
+
message: string;
|
|
241
|
+
stallMs?: number;
|
|
242
|
+
abortSignal?: AbortSignal;
|
|
243
|
+
onToolCall?: (name: string, arg?: string) => void;
|
|
244
|
+
onTextDelta?: (chars: number) => void;
|
|
245
|
+
onCostUpdate?: (cost: number, tokens: {
|
|
246
|
+
input: number;
|
|
247
|
+
output: number;
|
|
248
|
+
}) => void;
|
|
249
|
+
}): Promise<AdapterSessionResult>;
|
|
250
|
+
getLastResponse(handle: AgentHandle, sessionId: string): Promise<string>;
|
|
251
|
+
getSessionCost(handle: AgentHandle, sessionId: string): Promise<number>;
|
|
252
|
+
getSessionStats(handle: AgentHandle, sessionId: string): Promise<{
|
|
253
|
+
cost: number;
|
|
254
|
+
tokensIn: number;
|
|
255
|
+
tokensOut: number;
|
|
256
|
+
}>;
|
|
257
|
+
shutdown(handle: AgentHandle): Promise<void>;
|
|
258
|
+
enhanceError(message: string): Promise<string>;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export { DEFAULT_STARTUP_TIMEOUT_MS, OpenCodeAdapter, type SessionResult as OpenCodeSessionResult, type StartedServer, createSession, enhanceSessionError, execFileP, extractServerError, getLastAssistantMessage, getSessionCost, getSessionStats, selfTest, sendAndWait, startServer, waitForIdle };
|