ocpipe 0.5.8 → 0.5.10

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 CHANGED
@@ -80,8 +80,8 @@ claudeCode: { permissionMode: 'acceptEdits' },
80
80
 
81
81
  **For OpenCode backend:** Currently requires [this OpenCode fork](https://github.com/paralin/opencode). Once the following PRs are merged, the official release will work:
82
82
 
83
- - [#5426](https://github.com/anomalyco/opencode/pull/5426) - Adds `--prompt-file` flag
84
- - [#5339](https://github.com/anomalyco/opencode/pull/5339) - Session export fixes
83
+ - [#5426](https://github.com/anomalyco/opencode/pull/5426) - Adds session export command
84
+ - [#5339](https://github.com/anomalyco/opencode/pull/5339) - Adds `--tools` flag to limit available tools (optional)
85
85
 
86
86
  **For Claude Code backend:** Install the SDK as a peer dependency:
87
87
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ocpipe",
3
- "version": "0.5.8",
3
+ "version": "0.5.10",
4
4
  "description": "SDK for LLM pipelines with OpenCode and Zod",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -31,7 +31,7 @@
31
31
  "dependencies": {},
32
32
  "peerDependencies": {
33
33
  "zod": "4.3.6",
34
- "@anthropic-ai/claude-agent-sdk": "0.2.27"
34
+ "@anthropic-ai/claude-agent-sdk": "0.2.31"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
37
  "@anthropic-ai/claude-agent-sdk": {
@@ -34,8 +34,14 @@ const TOOL_COLORS: Record<string, string> = {
34
34
  Grep: Style.TEXT_INFO_BOLD,
35
35
  }
36
36
 
37
+ /** Track whether the last stderr write ended with a newline. */
38
+ let lastOutputEndedWithNewline = true
39
+
37
40
  /** Print a tool event with colored pipe prefix. */
38
41
  function printToolEvent(color: string, type: string, title: string): void {
42
+ if (!lastOutputEndedWithNewline) {
43
+ process.stderr.write('\n')
44
+ }
39
45
  const line = [
40
46
  color + '|',
41
47
  Style.TEXT_NORMAL + Style.TEXT_DIM + ` ${type.padEnd(7)}`,
@@ -149,6 +155,9 @@ export async function runClaudeCodeAgent(
149
155
  }
150
156
  signal?.addEventListener('abort', abortHandler, { once: true })
151
157
 
158
+ // Declare outside try block so finally can access it
159
+ let timeoutId: ReturnType<typeof setTimeout> | null = null
160
+
152
161
  try {
153
162
  // Send the prompt
154
163
  await session.send(prompt)
@@ -157,11 +166,11 @@ export async function runClaudeCodeAgent(
157
166
  const textParts: string[] = []
158
167
  let newSessionId = sessionId || ''
159
168
 
160
- // Set up timeout
169
+ // Set up timeout (store ID so we can clear it later)
161
170
  const timeoutPromise =
162
171
  timeoutSec > 0 ?
163
172
  new Promise<never>((_, reject) => {
164
- setTimeout(() => {
173
+ timeoutId = setTimeout(() => {
165
174
  session.close()
166
175
  reject(new Error(`Timeout after ${timeoutSec}s`))
167
176
  }, timeoutSec * 1000)
@@ -194,6 +203,7 @@ export async function runClaudeCodeAgent(
194
203
  if (text) {
195
204
  textParts.push(text)
196
205
  process.stderr.write(text)
206
+ lastOutputEndedWithNewline = text.endsWith('\n')
197
207
  }
198
208
  }
199
209
  })()
@@ -204,18 +214,27 @@ export async function runClaudeCodeAgent(
204
214
  if (abortPromise) promises.push(abortPromise)
205
215
  await Promise.race(promises)
206
216
 
217
+ // Clear the timeout to prevent it from keeping the event loop alive
218
+ if (timeoutId) clearTimeout(timeoutId)
219
+
207
220
  const response = textParts.join('')
208
221
  const sessionStr = newSessionId || 'none'
209
222
  console.error(
210
223
  `\n<<< Claude Code done (${response.length} chars) [session:${sessionStr}]`,
211
224
  )
212
225
 
226
+ // Detect rate limit errors in the response
227
+ if (response.includes("You've hit your limit")) {
228
+ throw new Error('Claude Code rate limit exceeded')
229
+ }
230
+
213
231
  return {
214
232
  text: response,
215
233
  sessionId: newSessionId,
216
234
  }
217
235
  } finally {
218
236
  signal?.removeEventListener('abort', abortHandler)
237
+ if (timeoutId) clearTimeout(timeoutId)
219
238
  session.close()
220
239
  }
221
240
  }