@11agents/cli 0.1.23 → 0.1.24

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@11agents/cli",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "11agents local runtime and telemetry CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  import { spawn } from 'node:child_process'
2
2
  import { createHash } from 'node:crypto'
3
- import { appendFileSync, readFileSync } from 'node:fs'
3
+ import { createWriteStream, readFileSync } from 'node:fs'
4
4
  import { appendFile, mkdir, readFile, readdir, rm, stat, writeFile } from 'node:fs/promises'
5
5
  import os from 'node:os'
6
6
  import { dirname, resolve } from 'node:path'
@@ -180,6 +180,15 @@ async function runWithRuntimeHeartbeat(operation, registration, flags, deps, hea
180
180
  }
181
181
  }
182
182
 
183
+ function createChunkLogger(filePath) {
184
+ if (!filePath) return null
185
+ const stream = createWriteStream(filePath, { flags: 'a' })
186
+ return {
187
+ write: chunk => { stream.write(chunk) },
188
+ close: () => new Promise(resolve => stream.end(resolve)),
189
+ }
190
+ }
191
+
183
192
  async function runWithDaemonRetry(label, operation, deps, retryState) {
184
193
  while (true) {
185
194
  try {
@@ -1134,8 +1143,13 @@ async function runCodex({ task, prompt, flags = {}, deps }) {
1134
1143
  const taskEnv = task.execution_context?.env || process.env
1135
1144
  const stdoutLogPath = runDir ? path.join(runDir, 'stdout.log') : ''
1136
1145
  if (stdoutLogPath) await writeRunFile(runDir, 'stdout.log', '')
1137
- const onStdoutChunk = stdoutLogPath ? (chunk) => { try { appendFileSync(stdoutLogPath, chunk) } catch {} } : undefined
1138
- let result = await deps.runProcess(codexBin, args, { input: `/goal ${prompt}`, cwd: workdir, env: taskEnv, onStdoutChunk })
1146
+ let stdoutLogger = createChunkLogger(stdoutLogPath)
1147
+ let result
1148
+ try {
1149
+ result = await deps.runProcess(codexBin, args, { input: `/goal ${prompt}`, cwd: workdir, env: taskEnv, onStdoutChunk: stdoutLogger?.write })
1150
+ } finally {
1151
+ await stdoutLogger?.close()
1152
+ }
1139
1153
 
1140
1154
  // When --codex-sandbox is set but bwrap is unavailable in the container (missing CAP_NET_ADMIN),
1141
1155
  // fall back to --yolo exec which runs commands directly without bwrap.
@@ -1147,7 +1161,12 @@ async function runCodex({ task, prompt, flags = {}, deps }) {
1147
1161
  deps.log(JSON.stringify({ warning: 'bwrap unavailable in this environment, retrying without sandbox', fallback_command: fallbackLine }))
1148
1162
  await updateRunMeta(runDir, { bwrap_fallback: true, fallback_command_line: fallbackLine })
1149
1163
  if (stdoutLogPath) await writeRunFile(runDir, 'stdout.log', '')
1150
- result = await deps.runProcess(codexBin, fallbackArgs, { input: `/goal ${prompt}`, cwd: workdir, env: taskEnv, onStdoutChunk })
1164
+ stdoutLogger = createChunkLogger(stdoutLogPath)
1165
+ try {
1166
+ result = await deps.runProcess(codexBin, fallbackArgs, { input: `/goal ${prompt}`, cwd: workdir, env: taskEnv, onStdoutChunk: stdoutLogger?.write })
1167
+ } finally {
1168
+ await stdoutLogger?.close()
1169
+ }
1151
1170
  }
1152
1171
  }
1153
1172
  const rawStdout = String(result.stdout || '')
@@ -1232,13 +1251,18 @@ async function runClaude({ task, prompt, flags = {}, deps }) {
1232
1251
 
1233
1252
  const stdoutLogPath = runDir ? path.join(runDir, 'stdout.log') : ''
1234
1253
  if (stdoutLogPath) await writeRunFile(runDir, 'stdout.log', '')
1235
- const onStdoutChunk = stdoutLogPath ? (chunk) => { try { appendFileSync(stdoutLogPath, chunk) } catch {} } : undefined
1236
- const result = await deps.runProcess(claudeBin, args, {
1237
- input: prompt,
1238
- cwd: workdir,
1239
- env: task.execution_context?.env || process.env,
1240
- onStdoutChunk,
1241
- })
1254
+ const stdoutLogger = createChunkLogger(stdoutLogPath)
1255
+ let result
1256
+ try {
1257
+ result = await deps.runProcess(claudeBin, args, {
1258
+ input: prompt,
1259
+ cwd: workdir,
1260
+ env: task.execution_context?.env || process.env,
1261
+ onStdoutChunk: stdoutLogger?.write,
1262
+ })
1263
+ } finally {
1264
+ await stdoutLogger?.close()
1265
+ }
1242
1266
 
1243
1267
  const rawStdout = String(result.stdout || '')
1244
1268
  const output = rawStdout.trim()
@@ -1339,7 +1363,13 @@ async function runOneRuntimeTaskSlot(runtime, config, machineKey, registration,
1339
1363
  },
1340
1364
  }
1341
1365
 
1342
- deps.log(JSON.stringify({ claimed: runtimeTask.id, runtime_id: runtime.id }, null, 2))
1366
+ deps.log(JSON.stringify({
1367
+ claimed: runtimeTask.id,
1368
+ task_id: runtimeTask.id,
1369
+ task_title: String(runtimeTask.issue?.title || runtimeTask.title || ''),
1370
+ project_slug: String(runtimeTask.workspace?.slug || runtimeTask.workspace_slug || ''),
1371
+ runtime_id: runtime.id,
1372
+ }, null, 2))
1343
1373
  await writeCurrentClaim(deps, runtimeTask, machineKey)
1344
1374
  let completion = null
1345
1375
  let executionContext = null
@@ -1348,15 +1378,17 @@ async function runOneRuntimeTaskSlot(runtime, config, machineKey, registration,
1348
1378
  const syncConfig = { ...config, token }
1349
1379
  try {
1350
1380
  await runWithTaskRetry('sync knowledge base', () => (
1351
- deps.syncKnowledge({
1352
- project: runtimeTask.workspace.slug,
1353
- mode: 'pull',
1354
- server: flags.server,
1355
- token,
1356
- }, {
1357
- requestJson: (apiPath, options = {}) => deps.requestJson(apiPath, { ...options, config: syncConfig }),
1358
- log: () => {},
1359
- })
1381
+ runWithRuntimeHeartbeat(() => (
1382
+ deps.syncKnowledge({
1383
+ project: runtimeTask.workspace.slug,
1384
+ mode: 'pull',
1385
+ server: flags.server,
1386
+ token,
1387
+ }, {
1388
+ requestJson: (apiPath, options = {}) => deps.requestJson(apiPath, { ...options, config: syncConfig }),
1389
+ log: () => {},
1390
+ })
1391
+ ), registration, flags, deps, heartbeatIntervalMs)
1360
1392
  ), deps)
1361
1393
  } catch (error) {
1362
1394
  completion = {
@@ -1418,7 +1450,7 @@ async function runOneRuntimeTaskSlot(runtime, config, machineKey, registration,
1418
1450
  })
1419
1451
  if (isDeepOrganize) {
1420
1452
  try {
1421
- await pushKnowledge()
1453
+ await runWithRuntimeHeartbeat(pushKnowledge, registration, flags, deps, heartbeatIntervalMs)
1422
1454
  } catch (error) {
1423
1455
  const message = `Knowledge sync push failed before task completion: ${errorMessage(error)}. If a knowledge_snapshot is included in completion, the platform will write it directly.`
1424
1456
  completion = {
@@ -1429,7 +1461,9 @@ async function runOneRuntimeTaskSlot(runtime, config, machineKey, registration,
1429
1461
  }
1430
1462
  } else {
1431
1463
  try {
1432
- await runWithTaskRetry('sync knowledge base back to cloud', pushKnowledge, deps)
1464
+ await runWithTaskRetry('sync knowledge base back to cloud', () => (
1465
+ runWithRuntimeHeartbeat(pushKnowledge, registration, flags, deps, heartbeatIntervalMs)
1466
+ ), deps)
1433
1467
  } catch (error) {
1434
1468
  const message = `Knowledge sync push failed before task completion: ${errorMessage(error)}`
1435
1469
  completion = {