ocpipe 0.3.5 → 0.3.7
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 +2 -2
- package/src/agent.ts +37 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ocpipe",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"description": "SDK for LLM pipelines with OpenCode and Zod",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"bun": ">=1.0.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"opencode-ai": "1.1.
|
|
32
|
+
"opencode-ai": "1.1.25"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"zod": "4.3.5"
|
package/src/agent.ts
CHANGED
|
@@ -5,24 +5,42 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { spawn, execSync } from 'child_process'
|
|
8
|
+
import { existsSync } from 'fs'
|
|
8
9
|
import { mkdir } from 'fs/promises'
|
|
10
|
+
import { join } from 'path'
|
|
9
11
|
import { PROJECT_ROOT, TMP_DIR } from './paths.js'
|
|
10
12
|
import type { RunAgentOptions, RunAgentResult } from './types.js'
|
|
11
13
|
|
|
12
|
-
/**
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
/** Find opencode binary from PATH, preferring non-node_modules locations */
|
|
15
|
+
function findOpencode(): string | null {
|
|
16
|
+
const pathDirs = (process.env.PATH || '').split(':')
|
|
17
|
+
|
|
18
|
+
// First pass: look for opencode in non-node_modules directories
|
|
19
|
+
for (const dir of pathDirs) {
|
|
20
|
+
if (dir.includes('node_modules')) continue
|
|
21
|
+
const candidate = join(dir, 'opencode')
|
|
22
|
+
if (existsSync(candidate)) {
|
|
23
|
+
return candidate
|
|
24
|
+
}
|
|
19
25
|
}
|
|
26
|
+
|
|
27
|
+
// Second pass: check node_modules/.bin as fallback
|
|
28
|
+
for (const dir of pathDirs) {
|
|
29
|
+
if (!dir.includes('node_modules')) continue
|
|
30
|
+
const candidate = join(dir, 'opencode')
|
|
31
|
+
if (existsSync(candidate)) {
|
|
32
|
+
return candidate
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return null
|
|
20
37
|
}
|
|
21
38
|
|
|
22
39
|
/** Get command and args to invoke opencode */
|
|
23
40
|
function getOpencodeCommand(args: string[]): { cmd: string; args: string[] } {
|
|
24
|
-
|
|
25
|
-
|
|
41
|
+
const opencode = findOpencode()
|
|
42
|
+
if (opencode) {
|
|
43
|
+
return { cmd: opencode, args }
|
|
26
44
|
}
|
|
27
45
|
// Fallback to bunx with ocpipe package (which has opencode-ai as dependency)
|
|
28
46
|
return { cmd: 'bunx', args: ['-p', 'ocpipe', 'opencode', ...args] }
|
|
@@ -56,19 +74,24 @@ export async function runAgent(
|
|
|
56
74
|
args.push('--session', sessionId)
|
|
57
75
|
}
|
|
58
76
|
|
|
77
|
+
// Pass prompt as positional argument (stdin doesn't work without TTY)
|
|
78
|
+
args.push(prompt)
|
|
79
|
+
|
|
59
80
|
return new Promise((resolve, reject) => {
|
|
60
81
|
const opencodeCmd = getOpencodeCommand(args)
|
|
61
82
|
const proc = spawn(opencodeCmd.cmd, opencodeCmd.args, {
|
|
62
83
|
cwd: workdir ?? PROJECT_ROOT,
|
|
63
|
-
stdio: ['
|
|
84
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
64
85
|
})
|
|
65
86
|
|
|
66
87
|
let newSessionId = sessionId || ''
|
|
67
88
|
const stdoutChunks: string[] = []
|
|
89
|
+
const stderrChunks: string[] = []
|
|
68
90
|
|
|
69
91
|
// Stream stderr in real-time (OpenCode progress output)
|
|
70
92
|
proc.stderr.on('data', (data: Buffer) => {
|
|
71
93
|
const text = data.toString()
|
|
94
|
+
stderrChunks.push(text)
|
|
72
95
|
|
|
73
96
|
// Parse session ID from output
|
|
74
97
|
for (const line of text.split('\n')) {
|
|
@@ -92,10 +115,6 @@ export async function runAgent(
|
|
|
92
115
|
process.stderr.write(text)
|
|
93
116
|
})
|
|
94
117
|
|
|
95
|
-
// Send prompt to stdin
|
|
96
|
-
proc.stdin.write(prompt)
|
|
97
|
-
proc.stdin.end()
|
|
98
|
-
|
|
99
118
|
// Timeout handling (0 = no timeout)
|
|
100
119
|
const timeout =
|
|
101
120
|
timeoutSec > 0 ?
|
|
@@ -109,7 +128,10 @@ export async function runAgent(
|
|
|
109
128
|
if (timeout) clearTimeout(timeout)
|
|
110
129
|
|
|
111
130
|
if (code !== 0) {
|
|
112
|
-
|
|
131
|
+
const stderr = stderrChunks.join('').trim()
|
|
132
|
+
const lastLines = stderr.split('\n').slice(-5).join('\n')
|
|
133
|
+
const detail = lastLines ? `\n${lastLines}` : ''
|
|
134
|
+
reject(new Error(`OpenCode exited with code ${code}${detail}`))
|
|
113
135
|
return
|
|
114
136
|
}
|
|
115
137
|
|