@11agents/cli 0.1.19 → 0.1.21

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.19",
3
+ "version": "0.1.21",
4
4
  "description": "11agents local runtime and telemetry CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  import { spawn } from 'node:child_process'
2
2
  import { createHash } from 'node:crypto'
3
3
  import { appendFileSync, readFileSync } from 'node:fs'
4
- import { appendFile, mkdir, readFile, rm, writeFile } from 'node:fs/promises'
4
+ import { appendFile, mkdir, readFile, readdir, rm, writeFile } from 'node:fs/promises'
5
5
  import os from 'node:os'
6
6
  import { dirname, resolve } from 'node:path'
7
7
  import path from 'node:path'
@@ -86,27 +86,49 @@ function runtimeDeps(overrides = {}) {
86
86
  }
87
87
  }
88
88
 
89
- function currentClaimPath(homeDir) {
89
+ function legacyClaimPath(homeDir) {
90
90
  return path.join(homeDir, '.11agents', 'claim_id')
91
91
  }
92
92
 
93
+ function claimsDirPath(homeDir) {
94
+ return path.join(homeDir, '.11agents', 'claims')
95
+ }
96
+
97
+ function claimFilePath(homeDir, taskId) {
98
+ return path.join(claimsDirPath(homeDir), `${sanitizeTaskId(taskId)}.json`)
99
+ }
100
+
93
101
  async function writeCurrentClaim(deps, task, machineKey) {
94
102
  const payload = {
95
103
  task_id: String(task.id || ''),
96
104
  runtime_id: String(task.runtime_id || task.runtime?.id || ''),
97
105
  machine_key: String(task.runtime?.machine_key || machineKey || ''),
98
106
  }
99
- await mkdir(path.dirname(currentClaimPath(deps.homeDir)), { recursive: true })
100
- await writeFile(currentClaimPath(deps.homeDir), JSON.stringify(payload))
107
+ await mkdir(claimsDirPath(deps.homeDir), { recursive: true })
108
+ await writeFile(claimFilePath(deps.homeDir, task.id), JSON.stringify(payload))
101
109
  return payload
102
110
  }
103
111
 
104
- async function readCurrentClaim(deps) {
105
- return readJsonFile(currentClaimPath(deps.homeDir), null)
112
+ async function clearCurrentClaim(deps, taskId) {
113
+ await rm(claimFilePath(deps.homeDir, taskId), { force: true })
106
114
  }
107
115
 
108
- async function clearCurrentClaim(deps) {
109
- await rm(currentClaimPath(deps.homeDir), { force: true })
116
+ async function readAllCurrentClaims(deps) {
117
+ const claims = []
118
+ // Backward compat: consume legacy single-claim file
119
+ const legacy = await readJsonFile(legacyClaimPath(deps.homeDir), null)
120
+ if (legacy?.task_id && legacy?.runtime_id) {
121
+ claims.push({ ...legacy, _path: legacyClaimPath(deps.homeDir) })
122
+ }
123
+ // Per-task claim files
124
+ const entries = await readdir(claimsDirPath(deps.homeDir)).catch(err => (err?.code === 'ENOENT' ? [] : Promise.reject(err)))
125
+ for (const entry of entries) {
126
+ if (!entry.endsWith('.json')) continue
127
+ const filePath = path.join(claimsDirPath(deps.homeDir), entry)
128
+ const claim = await readJsonFile(filePath, null)
129
+ if (claim?.task_id && claim?.runtime_id) claims.push({ ...claim, _path: filePath })
130
+ }
131
+ return claims
110
132
  }
111
133
 
112
134
  function errorMessage(error) {
@@ -339,15 +361,20 @@ function codexAssistantTextFromJsonl(text) {
339
361
  return messages.join('\n\n')
340
362
  }
341
363
 
342
- async function failPersistedCurrentClaim(flags, deps, comment) {
343
- const claim = await readCurrentClaim(deps)
344
- if (!claim?.task_id || !claim?.runtime_id) return false
345
- await deps.requestJson('/api/runtime/tasks/complete', {
346
- method: 'POST',
347
- body: failedClaimCompletionBody(claim, comment),
348
- config: configFromFlags(flags),
349
- })
350
- await clearCurrentClaim(deps)
364
+ async function failAllPersistedClaims(flags, deps, comment) {
365
+ const claims = await readAllCurrentClaims(deps)
366
+ if (!claims.length) return false
367
+ const config = configFromFlags(flags)
368
+ for (const claim of claims) {
369
+ try {
370
+ await deps.requestJson('/api/runtime/tasks/complete', {
371
+ method: 'POST',
372
+ body: failedClaimCompletionBody(claim, comment),
373
+ config,
374
+ })
375
+ } catch {}
376
+ await rm(claim._path, { force: true })
377
+ }
351
378
  return true
352
379
  }
353
380
 
@@ -357,14 +384,14 @@ function installCurrentClaimExitHandlers(flags, deps) {
357
384
  if (shuttingDown) return
358
385
  shuttingDown = true
359
386
  try {
360
- await failPersistedCurrentClaim(
387
+ await failAllPersistedClaims(
361
388
  flags,
362
389
  deps,
363
390
  `Runtime task failed locally: daemon received ${signal} before the claimed task completed.`
364
391
  )
365
392
  } catch (error) {
366
393
  deps.log(JSON.stringify({
367
- warning: 'failed to mark current claimed task failed during daemon shutdown',
394
+ warning: 'failed to mark current claimed tasks failed during daemon shutdown',
368
395
  signal,
369
396
  error: errorMessage(error),
370
397
  }, null, 2))
@@ -972,7 +999,6 @@ function buildCodexPrompt(task) {
972
999
  issue: task.issue,
973
1000
  trigger_summary: task.trigger_summary,
974
1001
  thread_memory: task.thread_memory,
975
- project_knowledge: task.project_knowledge,
976
1002
  }),
977
1003
  '',
978
1004
  'Assigned agent context:',
@@ -984,7 +1010,6 @@ function buildCodexPrompt(task) {
984
1010
  memory: task.agent?.memory,
985
1011
  permissions: task.agent?.permissions,
986
1012
  triggers: task.agent?.triggers,
987
- skills: task.agent?.skills,
988
1013
  }),
989
1014
  '',
990
1015
  'Thread comments:',
@@ -1365,7 +1390,7 @@ async function runOneRuntimeTaskSlot(runtime, config, machineKey, registration,
1365
1390
  config,
1366
1391
  })
1367
1392
  ), deps, retryState)
1368
- await clearCurrentClaim(deps)
1393
+ await clearCurrentClaim(deps, runtimeTask.id)
1369
1394
  deps.log(JSON.stringify(result, null, 2))
1370
1395
  return true
1371
1396
  }
@@ -1412,7 +1437,7 @@ export async function startRuntimeDaemon(flags = {}, deps = {}) {
1412
1437
  const uninstallExitHandlers = installCurrentClaimExitHandlers(flags, resolvedDeps)
1413
1438
  try {
1414
1439
  let registration = await runWithDaemonRetry('register runtime', () => registerRuntime(flags, resolvedDeps), resolvedDeps, retryState)
1415
- await runWithDaemonRetry('recover current claimed task', () => failPersistedCurrentClaim(
1440
+ await runWithDaemonRetry('recover current claimed task', () => failAllPersistedClaims(
1416
1441
  flags,
1417
1442
  resolvedDeps,
1418
1443
  'Runtime task failed locally: daemon restarted with a persisted claimed task that had not completed.'
@@ -1447,7 +1472,7 @@ export async function startRuntimeDaemon(flags = {}, deps = {}) {
1447
1472
  }
1448
1473
  } catch (error) {
1449
1474
  try {
1450
- await failPersistedCurrentClaim(
1475
+ await failAllPersistedClaims(
1451
1476
  flags,
1452
1477
  resolvedDeps,
1453
1478
  `Runtime task failed locally: daemon exited with error before the claimed task completed: ${errorMessage(error)}`