ur-agent 1.37.0 → 1.37.2

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
@@ -178,12 +178,14 @@ placeholder and is hidden from the list.
178
178
  ur provider list
179
179
  ur provider status
180
180
  ur provider doctor
181
+ ur provider models [provider] --json
181
182
  ur config set provider ollama
182
183
  ur config set provider openai-api
183
184
  ur config set provider anthropic-api
184
185
  ur config set provider gemini-api
185
186
  ur config set provider openrouter
186
187
  ur config set model qwen3-coder:480b-cloud
188
+ ur provider select-model ollama qwen3-coder:480b-cloud --json
187
189
  ur config set base_url http://localhost:11434
188
190
  ur config set provider.fallback ollama
189
191
  ```
package/bin/ur.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawn, spawnSync } from 'node:child_process'
3
- import { existsSync, readFileSync, writeSync } from 'node:fs'
3
+ import { existsSync, readFileSync } from 'node:fs'
4
4
  import { dirname, resolve } from 'node:path'
5
5
  import { fileURLToPath } from 'node:url'
6
6
 
@@ -113,13 +113,65 @@ const child = spawn(bun, args, {
113
113
 
114
114
  if (shouldPipeChildOutput) {
115
115
  child.stdout?.on('data', chunk => {
116
- writeSync(1, chunk)
116
+ forwardChildOutput(child.stdout, process.stdout, chunk)
117
117
  })
118
118
  child.stderr?.on('data', chunk => {
119
- writeSync(2, chunk)
119
+ forwardChildOutput(child.stderr, process.stderr, chunk)
120
120
  })
121
121
  }
122
122
 
123
+ function forwardChildOutput(source, target, chunk) {
124
+ try {
125
+ const canContinue = target.write(chunk)
126
+ if (!canContinue) {
127
+ source.pause()
128
+ target.once('drain', () => source.resume())
129
+ }
130
+ } catch (error) {
131
+ if (isRetryableWriteError(error)) {
132
+ source.pause()
133
+ setTimeout(() => {
134
+ if (target.destroyed) return
135
+ try {
136
+ const canContinue = target.write(chunk)
137
+ if (canContinue) source.resume()
138
+ else target.once('drain', () => source.resume())
139
+ } catch (retryError) {
140
+ if (isRetryableWriteError(retryError)) {
141
+ forwardChildOutput(source, target, chunk)
142
+ return
143
+ }
144
+ if (!isBrokenPipe(retryError)) {
145
+ try {
146
+ process.stderr.write(`UR launcher output forwarding failed: ${retryError.message ?? String(retryError)}\n`)
147
+ } catch {
148
+ // Nothing sensible remains if stderr itself is unavailable.
149
+ }
150
+ }
151
+ }
152
+ }, 10)
153
+ return
154
+ }
155
+ if (isBrokenPipe(error)) {
156
+ source.destroy?.()
157
+ return
158
+ }
159
+ try {
160
+ process.stderr.write(`UR launcher output forwarding failed: ${error.message ?? String(error)}\n`)
161
+ } catch {
162
+ // Nothing sensible remains if stderr itself is unavailable.
163
+ }
164
+ }
165
+ }
166
+
167
+ function isRetryableWriteError(error) {
168
+ return error && (error.code === 'EAGAIN' || error.code === 'EWOULDBLOCK')
169
+ }
170
+
171
+ function isBrokenPipe(error) {
172
+ return error && error.code === 'EPIPE'
173
+ }
174
+
123
175
  child.on('error', error => {
124
176
  if (error.code === 'ENOENT') {
125
177
  printBunRuntimeError(error.message)
@@ -136,5 +188,5 @@ child.on('close', (code, signal) => {
136
188
  return
137
189
  }
138
190
 
139
- process.exit(code ?? 1)
191
+ process.exitCode = code ?? 1
140
192
  })