nolo-cli 0.54.0-alpha.2 → 0.61.0-alpha.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.
Files changed (172) hide show
  1. package/README.md +3 -3
  2. package/{_executeModel-ANY4SIAS.js → _executeModel-CKT6RGTL.js} +58 -49
  3. package/{action-Q4W5JPI5.js → action-76JX3JX3.js} +9 -8
  4. package/{addContentAction-O25HFR37.js → addContentAction-V3NAZRTJ.js} +9 -7
  5. package/{addDialogAgentAction-GH7AUPPB.js → addDialogAgentAction-RZOAF46K.js} +11 -9
  6. package/{agentDeleteCommand-JWIKNWWI.js → agentDeleteCommand-VN7NPXQ4.js} +37 -32
  7. package/{agentEmailCommands-PL22BEU5.js → agentEmailCommands-F2TNAV4A.js} +73 -65
  8. package/{agentGrantCommands-2LEZDADN.js → agentGrantCommands-R3VQEZJR.js} +1 -1
  9. package/{agentListCommands-6NR7AQEK.js → agentListCommands-OSM2ANI3.js} +78 -39
  10. package/{agentMachineCommands-TASPU6OA.js → agentMachineCommands-MTPWYVRV.js} +38 -33
  11. package/{agentPullCommand-M552CYSI.js → agentPullCommand-N7L2CT7L.js} +2 -2
  12. package/agentRecordCommands-VWAWTVVC.js +122 -0
  13. package/agentRunCommand-PLZOBNVK.js +149 -0
  14. package/{agentRunControl-4GHHSXFZ.js → agentRunControl-WECMOO6O.js} +13 -6
  15. package/{agentRuntimeLocal-PCJJ56J2.js → agentRuntimeLocal-XCJLRWQE.js} +35 -28
  16. package/{agentSlice-KYLDUSNN.js → agentSlice-F6DOP4IW.js} +10 -9
  17. package/{appDeleteCommands-WLHMJAVT.js → appDeleteCommands-3BCFTRFJ.js} +37 -32
  18. package/{appDeployCommands-CKON7N2E.js → appDeployCommands-B4GMHCYA.js} +37 -32
  19. package/{appDeployStatusCommands-PXRLDASH.js → appDeployStatusCommands-4MN36WIG.js} +37 -32
  20. package/{appGetCommands-RAB5RM4M.js → appGetCommands-4GJIEUAX.js} +37 -32
  21. package/{appListCommands-GU57FB62.js → appListCommands-CHU53GSX.js} +37 -32
  22. package/{authCommand-QOPOEYEK.js → authCommand-WOTWLJNF.js} +38 -32
  23. package/{authCommands-SBQVTD6V.js → authCommands-ILTBI6JV.js} +8 -6
  24. package/{chatQueueReduxAdapter-5O2WLITN.js → chatQueueReduxAdapter-HNSQXNIR.js} +29 -24
  25. package/{chunk-WL3UOGYO.js → chunk-22BTGNSP.js} +151 -155
  26. package/{chunk-7CH6U3FL.js → chunk-2GRGFCF6.js} +2 -4
  27. package/{chunk-V4KZGLOI.js → chunk-2HPRMEEZ.js} +3059 -1079
  28. package/{chunk-UNZDCI3O.js → chunk-2KDR4CWE.js} +35 -4
  29. package/{chunk-VRZIH5JO.js → chunk-2PGGC63K.js} +1 -1
  30. package/{chunk-T27IEBNQ.js → chunk-2QDDKFG5.js} +74 -1
  31. package/{chunk-7K5VMB4Q.js → chunk-37QVS7BU.js} +21 -8
  32. package/{chunk-UITMHBVK.js → chunk-37XDGCY7.js} +1 -1
  33. package/chunk-3BLB7QKO.js +433 -0
  34. package/{chunk-NQ4N4IGO.js → chunk-3JQ2NRYU.js} +33 -10
  35. package/{chunk-UW4INMD2.js → chunk-3JWKQDA4.js} +2 -2
  36. package/{chunk-IKTHA3JH.js → chunk-3QGUVVX5.js} +2 -2
  37. package/{chunk-WHVQA7PJ.js → chunk-45YO6H7P.js} +97 -35
  38. package/chunk-4C4ST2YE.js +20015 -0
  39. package/{chunk-32I5RVMY.js → chunk-4NJEIGBQ.js} +5 -5
  40. package/{chunk-KUUTWU4I.js → chunk-5ZYA4JJ3.js} +90 -22
  41. package/chunk-6YTOJY35.js +352 -0
  42. package/{chunk-INXBNYCG.js → chunk-7A3RRUCQ.js} +155 -12
  43. package/{chunk-GV35EHNA.js → chunk-7O7KH4X5.js} +1262 -971
  44. package/{chunk-Y7LNKP32.js → chunk-7UF7CQ6B.js} +4 -6
  45. package/{chunk-2BWU4ORW.js → chunk-AQMVUA7N.js} +2 -1
  46. package/{chunk-LA4IDAK7.js → chunk-AVE2YR4F.js} +1056 -3591
  47. package/{chunk-TI5BCZCH.js → chunk-B7DXRX7F.js} +59 -121
  48. package/chunk-BFU6C242.js +66 -0
  49. package/{chunk-FA4SY4F5.js → chunk-BYEJ7K2Z.js} +1 -1
  50. package/chunk-BYXBJQAS.js +0 -0
  51. package/{chunk-IA3A5373.js → chunk-C3FZR5EC.js} +1 -1
  52. package/{chunk-IWUMSAQF.js → chunk-CJCJF5XB.js} +26 -3
  53. package/{chunk-PAHILFNT.js → chunk-CP7VIDZ7.js} +4 -4
  54. package/{chunk-OYNDYVSE.js → chunk-CTCW7U7N.js} +1 -1
  55. package/{chunk-BJLYCOZK.js → chunk-D5XKNNUV.js} +135 -795
  56. package/{chunk-AV6KQCM5.js → chunk-DNNSCSA2.js} +19 -14
  57. package/{chunk-3AOLVADY.js → chunk-DVINR3PL.js} +1 -1
  58. package/{chunk-NI2BS6UD.js → chunk-DWUCB2A3.js} +1 -1
  59. package/{chunk-AA564GBL.js → chunk-DZZL7UBV.js} +1 -1
  60. package/{chunk-6FGXGFAH.js → chunk-E6RGHPDR.js} +6 -4
  61. package/chunk-EDKF7RX4.js +30 -0
  62. package/{chunk-6SZ52ORL.js → chunk-ES6CVKVD.js} +24 -30
  63. package/{chunk-DQLYEGP7.js → chunk-FHAGENAS.js} +3 -4
  64. package/{chunk-56W233KG.js → chunk-FKFMIBTT.js} +5 -1
  65. package/{chunk-INZZJSQF.js → chunk-FZGV4FGK.js} +24 -12
  66. package/{chunk-D3JQPONH.js → chunk-GAL47RNP.js} +1 -1
  67. package/{chunk-6FQ2552G.js → chunk-HBPV76EK.js} +1085 -1150
  68. package/{chunk-LN3OQJGG.js → chunk-HLU5Q2GV.js} +4 -4
  69. package/{chunk-U2A47SVI.js → chunk-HQP7HJDL.js} +7 -7
  70. package/{chunk-H2G6JXTR.js → chunk-HQUORJTM.js} +1 -1
  71. package/{chunk-3Z3DXZBD.js → chunk-IYCUMIYS.js} +24 -20
  72. package/{chunk-7APQB6R6.js → chunk-JX5PJCWS.js} +8 -6
  73. package/{chunk-LYGNQHUW.js → chunk-JYYZCK2Z.js} +2 -4
  74. package/{chunk-PYKV6FSC.js → chunk-KWSQR2KK.js} +16 -31
  75. package/{chunk-VULELK4T.js → chunk-L7B47JXR.js} +37 -64
  76. package/{chunk-4NN3EK7H.js → chunk-LAFC3B2I.js} +1 -1
  77. package/{chunk-VRJUIUIY.js → chunk-LJKICKVC.js} +2 -2
  78. package/chunk-M3JEW6N6.js +193 -0
  79. package/chunk-MBOEV4L2.js +301 -0
  80. package/{chunk-QDHZCAH3.js → chunk-MMZ6ZTVO.js} +229 -74
  81. package/{chunk-JDSUTNYY.js → chunk-MP64VFGD.js} +2 -2
  82. package/{chunk-U5Z7LFZF.js → chunk-MXUDQZXQ.js} +47 -8
  83. package/chunk-N4G4PKQ6.js +23 -0
  84. package/{chunk-SVEUG45B.js → chunk-NHRQCXIQ.js} +0 -24
  85. package/{chunk-KXKQO4Q6.js → chunk-NTW5GWDM.js} +58 -1
  86. package/chunk-ONXOABJR.js +215 -0
  87. package/{chunk-BANYWEYY.js → chunk-OZX2IPKM.js} +8 -3
  88. package/{chunk-Q24S4NDF.js → chunk-P7OOB7QP.js} +1 -1
  89. package/{chunk-GLGD2JGY.js → chunk-PEZJEQAO.js} +7 -7
  90. package/{chunk-GBADO3SM.js → chunk-PQDIDWGX.js} +1 -1
  91. package/chunk-PSCNXBYA.js +11 -0
  92. package/chunk-QEFJJS2I.js +508 -0
  93. package/{chunk-757BGY6Y.js → chunk-QEW2MFDQ.js} +1 -1
  94. package/{chunk-SP3DPVBH.js → chunk-RDBARW6T.js} +8 -3
  95. package/{chunk-TNPCQNGQ.js → chunk-RJ2SAFB5.js} +83 -41
  96. package/{chunk-FGEYVPPR.js → chunk-RVWRKFUB.js} +8 -65
  97. package/{chunk-43CXXVJD.js → chunk-RXX4GDIH.js} +1 -1
  98. package/chunk-SEJ5OS6F.js +49 -0
  99. package/{chunk-MFI4FGHX.js → chunk-SOJM57FX.js} +5 -2
  100. package/{chunk-EKLRRZIN.js → chunk-SPAQ4PVV.js} +0 -5
  101. package/{chunk-L7NG2M6H.js → chunk-TRV2MIDW.js} +89 -74
  102. package/chunk-UAD2WT54.js +64 -0
  103. package/{chunk-RTLJUGQH.js → chunk-UZPQSVM6.js} +2 -2
  104. package/{chunk-3QJTD6DO.js → chunk-VMWYBIXG.js} +9 -7
  105. package/{chunk-ZHXJ6M7T.js → chunk-W7XHHYWM.js} +4 -0
  106. package/{chunk-5WADL4O7.js → chunk-XAVSS3KE.js} +21 -3
  107. package/{chunk-CVT7L2WZ.js → chunk-XOKOSO35.js} +13 -22
  108. package/{chunk-6BYAXNH5.js → chunk-XTJTN3RW.js} +57 -4
  109. package/{chunk-T5HJEUQN.js → chunk-YCDWJX45.js} +1 -1
  110. package/{chunk-MRWGHF56.js → chunk-YDH3FDFQ.js} +12 -356
  111. package/{chunk-H4RYESI6.js → chunk-Z4QSJILV.js} +85 -13
  112. package/chunk-ZJ7UHBJS.js +89 -0
  113. package/{chunk-O5FLGN2L.js → chunk-ZRSJ3JEH.js} +6 -2
  114. package/{cliExecutor-BBUVQU4L.js → cliExecutor-HG3S345O.js} +1 -1
  115. package/{codingSkills-BCQXRZOI.js → codingSkills-VDXQYWX4.js} +2 -2
  116. package/contentThunks-7YG2ZYQC.js +73 -0
  117. package/{cooldownCommands-GI5NNWGL.js → cooldownCommands-BSCH2W7P.js} +2 -2
  118. package/{createAgentAutomationAction-UJLNFFFC.js → createAgentAutomationAction-PJQSCAIO.js} +32 -26
  119. package/createDialogAction-SFEJX6SP.js +64 -0
  120. package/{createPageAction-N3IYABHV.js → createPageAction-B7WRHOQO.js} +35 -28
  121. package/{dbSlice-D5CNGWPD.js → dbSlice-IBVOBVMS.js} +7 -6
  122. package/{deleteFile-44TUM34Y.js → deleteFile-FWP2PSBG.js} +4 -3
  123. package/{dialogCommands-35M6RBAC.js → dialogCommands-VL2X22QC.js} +38 -33
  124. package/{dialogSlice-KO7ADD7H.js → dialogSlice-ANMACABO.js} +29 -24
  125. package/{docCreateCommands-VXHZWQ3P.js → docCreateCommands-ITLGZ5YI.js} +40 -35
  126. package/{docDeleteCommands-4WFAJR6A.js → docDeleteCommands-LH3YNL4C.js} +37 -32
  127. package/{docReadCommands-OYREEFAR.js → docReadCommands-YAJ77F36.js} +36 -31
  128. package/{docStore-5BU76DFK.js → docStore-D4HGHPWI.js} +9 -33
  129. package/{docUpdateCommands-A7QERSME.js → docUpdateCommands-DQBOMH2G.js} +40 -35
  130. package/{fetchMessages-KZQVBXKY.js → fetchMessages-DRABNDPZ.js} +3 -3
  131. package/{getPricing-HAU62AFM.js → getPricing-NM3NUTAS.js} +5 -5
  132. package/handleSendMessageAction-DF2OABGW.js +675 -0
  133. package/index.js +79 -88
  134. package/{lib-2ZTNRXR4.js → lib-FRRS27KN.js} +63 -28
  135. package/{localDialogRead-NQ33HBSI.js → localDialogRead-PUQKFI73.js} +1 -1
  136. package/{localRuntimeAuthority-KQDAE64E.js → localRuntimeAuthority-R5UBODT3.js} +6 -4
  137. package/{localRuntimeDb-PF7CFKDL.js → localRuntimeDb-P37ZTX55.js} +1 -1
  138. package/{machineCommands-J43U3TX5.js → machineCommands-JXDYQ5LB.js} +309 -87
  139. package/{machineWsRunDispatch-Z2Z6STXZ.js → machineWsRunDispatch-3QHI7JX5.js} +67 -59
  140. package/memberThunks-VZI6G7YZ.js +640 -0
  141. package/{models-4QF4BJVY.js → models-FAMINFZ7.js} +2 -2
  142. package/package.json +3 -2
  143. package/{read-RGNPI5H2.js → read-2BYWW7AA.js} +4 -3
  144. package/{readDocTool-6ESWKTXD.js → readDocTool-LC3A7QTB.js} +1 -1
  145. package/{readlineWorkspace-YRPV6JPN.js → readlineWorkspace-KVZTEAHB.js} +4609 -2698
  146. package/{removeDialogAgentAction-JYT73FU2.js → removeDialogAgentAction-SFYZXHNK.js} +14 -12
  147. package/{runAgentClientLoop-5YM5WMAY.js → runAgentClientLoop-KGTEL7ZP.js} +60 -50
  148. package/{runtimeDoctorCommands-JKTTN723.js → runtimeDoctorCommands-CROTMULY.js} +7 -5
  149. package/{setDialogExtraReferencesAction-D564LMYQ.js → setDialogExtraReferencesAction-Q32RGFTA.js} +10 -8
  150. package/{setPrimaryDialogAgentAction-ACY3BLYA.js → setPrimaryDialogAgentAction-BFYJHUJS.js} +14 -12
  151. package/{settingSlice-MKI3MNZJ.js → settingSlice-IRUU4VFB.js} +8 -7
  152. package/{skillDiscovery-GPUDHDTZ.js → skillDiscovery-NTRLM6KP.js} +3 -3
  153. package/{spaceCommands-MY26V52L.js → spaceCommands-KNAYWMCZ.js} +40 -220
  154. package/{streamAgentChatTurn-XV5X5TNQ.js → streamAgentChatTurn-FLYPTXKZ.js} +140 -95
  155. package/{switchDialogAgentAction-CJ5H6SAR.js → switchDialogAgentAction-L2KOKCGG.js} +11 -9
  156. package/{tableCommands-R6WFRDYF.js → tableCommands-SUNTHAYX.js} +1 -1
  157. package/{toolApiClient-B2MFXMEG.js → toolApiClient-VGYUB4P5.js} +4 -2
  158. package/{tools-MIMELA2Y.js → tools-CVLUXK6P.js} +46 -38
  159. package/{tuiSummaryLlmCaller-XJ5BKNNS.js → tuiSummaryLlmCaller-F3DPFFZM.js} +20 -16
  160. package/{updateCommands-IYKLF3JX.js → updateCommands-AJYSD73Y.js} +2 -2
  161. package/{updateDialogTitleAction-EIZUSWHR.js → updateDialogTitleAction-HWJIZEIV.js} +33 -27
  162. package/agentRecordCommands-Z64TA63M.js +0 -114
  163. package/agentRunCommand-4QJQLPRW.js +0 -134
  164. package/agentSuperviseCommands-VB6BUS5H.js +0 -640
  165. package/chunk-6BGAQ3KR.js +0 -7081
  166. package/chunk-FD36SCCD.js +0 -105
  167. package/chunk-J3UALFHL.js +0 -370
  168. package/chunk-RU5D3B22.js +0 -230
  169. package/chunk-YBV6QJKM.js +0 -441
  170. package/createDialogAction-TJCX6GUE.js +0 -58
  171. package/handleSendMessageAction-OSGQJQ45.js +0 -406
  172. package/spaceSlice-JUIXC365.js +0 -127
@@ -1,18 +1,20 @@
1
1
  import {
2
- getCredentialsDir
3
- } from "./chunk-FD36SCCD.js";
2
+ getCredentialsDir,
3
+ getLegacyCredentialPath,
4
+ migrateLegacyCredentialFile
5
+ } from "./chunk-ONXOABJR.js";
4
6
  import {
5
7
  asNonEmptyStringArray
6
8
  } from "./chunk-I42VC5KR.js";
7
- import {
8
- isRecord
9
- } from "./chunk-KUG52IAP.js";
10
9
  import {
11
10
  asTrimmedString
12
11
  } from "./chunk-3EUW3WEO.js";
13
12
  import {
14
13
  asOptionalPositiveFiniteNumber
15
14
  } from "./chunk-U6VC4MU4.js";
15
+ import {
16
+ isRecord
17
+ } from "./chunk-KUG52IAP.js";
16
18
 
17
19
  // packages/agent-runtime/fileCredentialBroker.ts
18
20
  import {
@@ -23,6 +25,7 @@ import {
23
25
  unlinkSync,
24
26
  writeFileSync
25
27
  } from "node:fs";
28
+ import { homedir } from "node:os";
26
29
  import { join } from "node:path";
27
30
 
28
31
  // packages/agent-runtime/credentialBroker.ts
@@ -65,7 +68,26 @@ function writePrivateFile(path, body) {
65
68
  } catch {
66
69
  }
67
70
  }
68
- function readApiKeyCredential(ref, homeDir) {
71
+ function migrateApiKeyCredentialIfNeeded(ref, homeDir, migration) {
72
+ if (homeDir !== void 0 || !migration?.enableLegacyMigration) return;
73
+ const legacyHomeDir = migration.legacyHomeDir ?? homedir();
74
+ const relativePath = join("keys", credentialRefToFileName(ref));
75
+ migrateLegacyCredentialFile({
76
+ canonicalPath: getApiKeyCredentialPath(ref),
77
+ legacyPath: getLegacyCredentialPath(relativePath, legacyHomeDir),
78
+ mode: migration.mode ?? (migration.legacyHomeDir ? "test" : "production"),
79
+ isValid: (raw) => {
80
+ try {
81
+ const parsed = JSON.parse(raw);
82
+ return typeof parsed?.secret === "string" && Boolean(parsed.secret);
83
+ } catch {
84
+ return false;
85
+ }
86
+ }
87
+ });
88
+ }
89
+ function readApiKeyCredential(ref, homeDir, migration) {
90
+ migrateApiKeyCredentialIfNeeded(ref, homeDir, migration);
69
91
  const path = getApiKeyCredentialPath(ref, homeDir);
70
92
  if (!existsSync(path)) return null;
71
93
  try {
@@ -99,15 +121,16 @@ function removeApiKeyCredential(ref, homeDir) {
99
121
  if (!existsSync(path)) return;
100
122
  unlinkSync(path);
101
123
  }
102
- function hasApiKeyCredential(ref, homeDir) {
103
- return readApiKeyCredential(ref, homeDir) !== null;
124
+ function hasApiKeyCredential(ref, homeDir, migration) {
125
+ return readApiKeyCredential(ref, homeDir, migration) !== null;
104
126
  }
105
127
  function createFileCredentialBroker(options = {}) {
106
128
  const homeDir = options.homeDir;
129
+ const migration = options.migration;
107
130
  const now = options.now ?? Date.now;
108
131
  return {
109
132
  get(ref) {
110
- return readApiKeyCredential(ref, homeDir);
133
+ return readApiKeyCredential(ref, homeDir, migration);
111
134
  },
112
135
  put(ref, secret) {
113
136
  writeApiKeyCredential(ref, secret, homeDir, now());
@@ -116,7 +139,7 @@ function createFileCredentialBroker(options = {}) {
116
139
  removeApiKeyCredential(ref, homeDir);
117
140
  },
118
141
  has(ref) {
119
- return hasApiKeyCredential(ref, homeDir);
142
+ return hasApiKeyCredential(ref, homeDir, migration);
120
143
  }
121
144
  };
122
145
  }
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  i18n_default,
3
3
  toolRegistry
4
- } from "./chunk-V4KZGLOI.js";
4
+ } from "./chunk-2HPRMEEZ.js";
5
5
  import {
6
6
  canonicalizeToolNames
7
7
  } from "./chunk-O6OSWFZQ.js";
8
8
  import {
9
9
  isNoloHostedProvider
10
- } from "./chunk-WL3UOGYO.js";
10
+ } from "./chunk-22BTGNSP.js";
11
11
  import {
12
12
  asTrimmedLowercaseString
13
13
  } from "./chunk-QSJ3HFEF.js";
@@ -6,10 +6,10 @@ import {
6
6
  } from "./chunk-AGGIDPCZ.js";
7
7
  import {
8
8
  getModelConfig
9
- } from "./chunk-QDHZCAH3.js";
9
+ } from "./chunk-MMZ6ZTVO.js";
10
10
  import {
11
11
  isPlatformHostedImageModel
12
- } from "./chunk-WL3UOGYO.js";
12
+ } from "./chunk-22BTGNSP.js";
13
13
  import {
14
14
  asOptionalFiniteNumber
15
15
  } from "./chunk-WWC7I6TA.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isAgentRunTerminalStatus
3
- } from "./chunk-KXKQO4Q6.js";
3
+ } from "./chunk-NTW5GWDM.js";
4
4
  import {
5
5
  isCompiledBinary,
6
6
  resolveCliEntrypointPath
@@ -335,12 +335,6 @@ async function popQueueMessages(queuePath, depsOrFs = {}) {
335
335
  const entries = await popAllQueueEntries(queuePath, depsOrFs);
336
336
  return entries.map((e) => e.text);
337
337
  }
338
- function resolveRunReportPath(runId, env, homedir = nodeHomedir) {
339
- return join(resolveRunsDir(env, homedir), `${runId}.report.md`);
340
- }
341
- function resolveRunReportJsonPath(runId, env, homedir = nodeHomedir) {
342
- return join(resolveRunsDir(env, homedir), `${runId}.report.json`);
343
- }
344
338
  function defaultGenerateRunId() {
345
339
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
346
340
  const random = Math.random().toString(36).slice(2, 8);
@@ -432,11 +426,18 @@ function createRunActivityTracker(runId, deps = {}, options = {}) {
432
426
  }
433
427
  function doWrite() {
434
428
  writeTimer = void 0;
435
- const record = readRunRecord(runId, deps);
436
- if (!record) return;
437
- const activity = serializeActivity();
438
- writeRunRecord({ ...record, activity }, deps);
439
- lastWriteAt = now().getTime();
429
+ withRunRecordLock(
430
+ runId,
431
+ deps,
432
+ () => {
433
+ const record = readRunRecord(runId, deps);
434
+ if (!record) return;
435
+ const activity = serializeActivity();
436
+ writeRunRecord({ ...record, activity }, deps);
437
+ lastWriteAt = now().getTime();
438
+ },
439
+ { strict: true }
440
+ );
440
441
  }
441
442
  function scheduleWrite() {
442
443
  if (writeTimer !== void 0) return;
@@ -498,6 +499,16 @@ function readRunRecord(runId, deps = {}) {
498
499
  }
499
500
  return null;
500
501
  }
502
+ function backfillRunRecordParentDialog(runId, parentDialogId, deps = {}) {
503
+ if (!parentDialogId) return false;
504
+ const updated = withRunRecordLock(runId, deps, () => {
505
+ const record = readRunRecord(runId, deps);
506
+ if (!record || record.parentDialogId) return false;
507
+ writeRunRecord({ ...record, parentDialogId }, deps);
508
+ return true;
509
+ });
510
+ return updated === true;
511
+ }
501
512
  function listRunRecords(deps = {}) {
502
513
  const fs = deps.fs ?? nodeFs;
503
514
  const dir = resolveRunsDir(deps.env, deps.homedir);
@@ -585,8 +596,6 @@ async function gcRunRecords(deps = {}, options = {}) {
585
596
  const jsonPath = resolveRunRecordPath(record.runId, deps.env, deps.homedir);
586
597
  const logPath = resolveRunLogPath(record.runId, deps.env, deps.homedir);
587
598
  const queuePath = record.queuePath ?? resolveRunQueuePath(record.runId, deps.env, deps.homedir);
588
- const reportPath = resolveRunReportPath(record.runId, deps.env, deps.homedir);
589
- const reportJsonPath = resolveRunReportJsonPath(record.runId, deps.env, deps.homedir);
590
599
  const msgPath = record.msgFile ?? join(resolveRunsDir(deps.env, deps.homedir), `${record.runId}.msg.md`);
591
600
  const logOk = tryUnlinkFile(fs, logPath);
592
601
  const msgOk = tryUnlinkFile(fs, msgPath);
@@ -600,8 +609,9 @@ async function gcRunRecords(deps = {}, options = {}) {
600
609
  queueOk = false;
601
610
  }
602
611
  }
603
- tryUnlinkFile(fs, reportPath);
604
- tryUnlinkFile(fs, reportJsonPath);
612
+ const runsDirForLegacy = resolveRunsDir(deps.env, deps.homedir);
613
+ tryUnlinkFile(fs, join(runsDirForLegacy, `${record.runId}.report.md`));
614
+ tryUnlinkFile(fs, join(runsDirForLegacy, `${record.runId}.report.json`));
605
615
  if (!logOk || !msgOk || !queueOk) {
606
616
  failedIds.push(record.runId);
607
617
  continue;
@@ -880,18 +890,60 @@ function releaseRunRecordAck(runId, token, deps = {}) {
880
890
  writeRunRecord(record, deps);
881
891
  });
882
892
  }
883
- function finalizeRunRecord(runId, update, deps = {}) {
884
- withRunRecordLock(runId, deps, () => {
885
- const record = readRunRecord(runId, deps);
886
- if (!record) return;
893
+ function transitionRunToTerminal(runId, update, deps = {}, options = {}) {
894
+ const settled = withRunRecordLock(runId, deps, () => {
895
+ const record2 = readRunRecord(runId, deps);
896
+ if (!record2) return { kind: "not_found" };
897
+ const orphanCorrection = options.allowOverOrphaned === true && record2.status === "orphaned" && (update.status === "done" || update.status === "failed");
898
+ if (isAgentRunTerminalStatus(record2.status) && !orphanCorrection) {
899
+ return { kind: "kept", record: record2 };
900
+ }
887
901
  const now = deps.now ?? (() => /* @__PURE__ */ new Date());
888
- record.status = update.status;
889
- if (typeof update.exitCode === "number") record.exitCode = update.exitCode;
890
- if (update.dialogId) record.dialogId = update.dialogId;
891
- record.endedAt = now().toISOString();
892
- if (record.note?.startsWith("orphaned:")) record.note = void 0;
893
- writeRunRecord(record, deps);
894
- });
902
+ record2.status = update.status;
903
+ if (typeof update.exitCode === "number") record2.exitCode = update.exitCode;
904
+ if (update.dialogId) record2.dialogId = update.dialogId;
905
+ if (typeof update.credits === "number" && Number.isFinite(update.credits)) {
906
+ record2.credits = update.credits;
907
+ }
908
+ if (update.dodResults && update.dodResults.length > 0) {
909
+ record2.dodResults = update.dodResults;
910
+ }
911
+ record2.endedAt = now().toISOString();
912
+ if (typeof update.note === "string" && update.note.trim()) {
913
+ record2.note = update.note.trim();
914
+ }
915
+ if (record2.note?.startsWith("orphaned:")) record2.note = void 0;
916
+ writeRunRecord(record2, deps);
917
+ return { kind: "transitioned", record: record2 };
918
+ }, { strict: true });
919
+ if (settled !== void 0) return settled;
920
+ const record = readRunRecord(runId, deps);
921
+ if (!record) return { kind: "not_found" };
922
+ if (isAgentRunTerminalStatus(record.status)) return { kind: "kept", record };
923
+ return { kind: "contended", record };
924
+ }
925
+ var AUTHORITATIVE_SETTLE_MAX_ATTEMPTS = 4;
926
+ var AUTHORITATIVE_SETTLE_RETRY_DELAY_MS = 15;
927
+ async function settleRunTerminalAuthoritatively(runId, update, deps = {}, transition = transitionRunToTerminal) {
928
+ const attempt = () => transition(runId, update, deps, { allowOverOrphaned: true });
929
+ let result = attempt();
930
+ for (let attemptNo = 1; result?.kind === "contended" && attemptNo < AUTHORITATIVE_SETTLE_MAX_ATTEMPTS; attemptNo += 1) {
931
+ await (deps.sleep ?? defaultSleep)(AUTHORITATIVE_SETTLE_RETRY_DELAY_MS);
932
+ result = attempt();
933
+ }
934
+ if (result?.kind === "contended") {
935
+ console.error(
936
+ `[nolo] authoritative settlement for run ${runId} lost the record lock ${AUTHORITATIVE_SETTLE_MAX_ATTEMPTS} times; durable record still ${result.record.status} \u2014 terminal status pending reconcile, child outcome (exitCode/dialogId/credits/DoD) may be lost`
937
+ );
938
+ } else if (result?.kind === "kept" && result.record.status !== update.status) {
939
+ console.warn(
940
+ `[nolo] run ${runId} already terminal (${result.record.status}); keeping the durable outcome over intended ${update.status}`
941
+ );
942
+ }
943
+ return result ?? { kind: "not_found" };
944
+ }
945
+ function finalizeRunRecord(runId, update, deps = {}) {
946
+ transitionRunToTerminal(runId, update, deps);
895
947
  }
896
948
  function isPidGone(pid, deps = {}) {
897
949
  const kill = deps.kill ?? ((p, s) => process.kill(p, s));
@@ -964,7 +1016,7 @@ function checkStaleRun(runId, deps = {}) {
964
1016
  latest.pid = void 0;
965
1017
  writeRunRecord(latest, deps);
966
1018
  return latest;
967
- });
1019
+ }) ?? record;
968
1020
  }
969
1021
  function formatDuration(startedAt, endedAt) {
970
1022
  const start = new Date(startedAt).getTime();
@@ -1329,12 +1381,18 @@ async function runSignalCommand(args, signal, verb, deps) {
1329
1381
  `);
1330
1382
  return 1;
1331
1383
  }
1332
- if (typeof record.pid !== "number") {
1333
- deps.output.write(`Run has no pid: ${record.runId}
1384
+ const reconciled = checkStaleRun(record.runId, deps) ?? record;
1385
+ if (isAgentRunTerminalStatus(reconciled.status)) {
1386
+ deps.output.write(`Run ${reconciled.runId} is already ${reconciled.status}.
1387
+ `);
1388
+ return 0;
1389
+ }
1390
+ if (typeof reconciled.pid !== "number") {
1391
+ deps.output.write(`Run has no pid: ${reconciled.runId}
1334
1392
  `);
1335
1393
  return 1;
1336
1394
  }
1337
- const confirmed = await terminateRunProcess(record, signal, deps);
1395
+ const confirmed = await terminateRunProcess(reconciled, signal, deps);
1338
1396
  if (!confirmed) {
1339
1397
  deps.output.write(
1340
1398
  `Failed to ${verb} ${record.runId} (pid ${record.pid}): process still alive after SIGKILL.
@@ -1342,9 +1400,10 @@ async function runSignalCommand(args, signal, verb, deps) {
1342
1400
  );
1343
1401
  return 1;
1344
1402
  }
1345
- finalizeRunRecord(record.runId, { status: "killed" }, deps);
1403
+ const transition = transitionRunToTerminal(reconciled.runId, { status: "killed" }, deps);
1346
1404
  deps.output.write(
1347
- `Stopped ${record.runId} (pid ${record.pid}): process group confirmed gone.
1405
+ transition.kind === "contended" ? `Stopped ${reconciled.runId} (pid ${reconciled.pid}): process group confirmed gone; terminal status pending reconcile.
1406
+ ` : `Stopped ${reconciled.runId} (pid ${reconciled.pid}): process group confirmed gone.
1348
1407
  `
1349
1408
  );
1350
1409
  return 0;
@@ -1384,13 +1443,12 @@ export {
1384
1443
  popAllQueueEntries,
1385
1444
  popSingleQueueMessage,
1386
1445
  popQueueMessages,
1387
- resolveRunReportPath,
1388
- resolveRunReportJsonPath,
1389
1446
  defaultGenerateRunId,
1390
1447
  defaultGenerateBatchId,
1391
1448
  writeRunRecord,
1392
1449
  createRunActivityTracker,
1393
1450
  readRunRecord,
1451
+ backfillRunRecordParentDialog,
1394
1452
  listRunRecords,
1395
1453
  findRunRecordByPid,
1396
1454
  findRunRecord,
@@ -1411,6 +1469,10 @@ export {
1411
1469
  claimRunRecord,
1412
1470
  commitRunRecordClaim,
1413
1471
  releaseRunRecordAck,
1472
+ transitionRunToTerminal,
1473
+ AUTHORITATIVE_SETTLE_MAX_ATTEMPTS,
1474
+ AUTHORITATIVE_SETTLE_RETRY_DELAY_MS,
1475
+ settleRunTerminalAuthoritatively,
1414
1476
  finalizeRunRecord,
1415
1477
  isPidGone,
1416
1478
  defaultGetProcessStartTime,