nolo-cli 0.201.0-alpha.2 → 0.202.0-alpha.1

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 (124) hide show
  1. package/{_executeModel-BNYZLAN6.js → _executeModel-IPRTPSW7.js} +34 -33
  2. package/{agentDeleteCommand-4V4YSAXS.js → agentDeleteCommand-WHT2MMAP.js} +49 -47
  3. package/{agentEmailCommands-EYIQEH6Z.js → agentEmailCommands-4LW2BFLY.js} +51 -49
  4. package/{agentListCommands-2KGUT7UB.js → agentListCommands-2KF47HY6.js} +81 -45
  5. package/{agentMachineCommands-WUN47ILO.js → agentMachineCommands-QQCFQQ4T.js} +28 -26
  6. package/{agentProviderCommands-T6E3JCR6.js → agentProviderCommands-5ALOQLE5.js} +2 -2
  7. package/{agentRecordCommands-XL2CON36.js → agentRecordCommands-ARVXF2C2.js} +47 -45
  8. package/{agentRunCommand-R237ZGMQ.js → agentRunCommand-3IL5PW2S.js} +49 -47
  9. package/{agentRunControl-6HHESKDB.js → agentRunControl-ABDUPJLX.js} +10 -5
  10. package/{agentRuntimeLocal-XLLWFAVI.js → agentRuntimeLocal-YXHJV65L.js} +24 -22
  11. package/{agentSlice-Z5NKGMB7.js → agentSlice-BFDKYW6H.js} +4 -3
  12. package/{appDeleteCommands-IPF2VI3W.js → appDeleteCommands-OWJO3WFB.js} +29 -27
  13. package/{appDeployCommands-IBQ7GUXO.js → appDeployCommands-X7HLT27G.js} +29 -27
  14. package/{appDeployStatusCommands-6ESVU6XE.js → appDeployStatusCommands-CHCZ7ZUD.js} +29 -27
  15. package/{appGetCommands-VTSYTM4V.js → appGetCommands-AZW2EE4R.js} +29 -27
  16. package/{appListCommands-VCP5TUX7.js → appListCommands-YFN6DP6K.js} +29 -27
  17. package/{authCommand-RV5MQDWN.js → authCommand-W34UWJGR.js} +14 -13
  18. package/{builtinSkillRegistry-7RAJP7FD.js → builtinSkillRegistry-NJVHQIKY.js} +1 -1
  19. package/{chromeOpsCommands-BA6CS4DI.js → chromeOpsCommands-USKE4B4K.js} +15 -4
  20. package/{chunk-RE3B2OCC.js → chunk-266E37EL.js} +69 -14
  21. package/chunk-2BMURXSB.js +1863 -0
  22. package/{chunk-RRHJJUA3.js → chunk-2PI4QFAL.js} +174 -100
  23. package/{chunk-NABJEYPJ.js → chunk-2Q3LOAFE.js} +38 -3
  24. package/{chunk-EOLPKHSB.js → chunk-326HCB6L.js} +28 -24
  25. package/{chunk-4CEAZRZ4.js → chunk-33W4IFUU.js} +1 -1
  26. package/{chunk-V3MGT3RF.js → chunk-3CWF2EUZ.js} +8 -8
  27. package/{chunk-G6OOUQWJ.js → chunk-4KB6WQUL.js} +2 -0
  28. package/{chunk-DYQXB46J.js → chunk-4KPB3KWX.js} +2 -2
  29. package/{chunk-SW5AAI5D.js → chunk-4SH22ZG7.js} +5 -5
  30. package/{chunk-WAZ6BTSC.js → chunk-5E4FSR4J.js} +1 -1
  31. package/{chunk-PVD7CRYV.js → chunk-6I7ZP7KJ.js} +3 -3
  32. package/chunk-6UBGXX2W.js +12 -0
  33. package/{chunk-ZBCBFOWC.js → chunk-A2ZMIRLN.js} +2 -2
  34. package/{chunk-Z646E5YH.js → chunk-ASG7VWPK.js} +3 -3
  35. package/{chunk-QWVGFBOQ.js → chunk-BLFZULEQ.js} +3 -3
  36. package/{chunk-JIFYXQRD.js → chunk-BTYQAODF.js} +26 -8
  37. package/{chunk-KORCRPLO.js → chunk-C7PKPHK6.js} +334 -12
  38. package/{chunk-6WZQGT5X.js → chunk-CJ37ZMCQ.js} +6 -2
  39. package/{chunk-VHGD6FHV.js → chunk-CKAHAVMK.js} +40 -10
  40. package/{chunk-UNOILAZP.js → chunk-CLTGWJVT.js} +76 -4
  41. package/{chunk-Q6RMLYSA.js → chunk-CMLBKYEI.js} +4 -2
  42. package/{chunk-NVOYW6H4.js → chunk-CQHMBWZH.js} +12 -8
  43. package/{chunk-7KWPNGVJ.js → chunk-CTZ4O3XD.js} +1 -1
  44. package/{chunk-OHRDHS4N.js → chunk-CVCRAO6Q.js} +9 -4
  45. package/{chunk-26CRLZFD.js → chunk-D57YYGMD.js} +2 -2
  46. package/{chunk-TEC5UHQK.js → chunk-DHJXDGC3.js} +2 -2
  47. package/{chunk-QYOB7RVA.js → chunk-DKZJJ2NQ.js} +3 -2
  48. package/{chunk-4YX7VQOC.js → chunk-E2FC5RMU.js} +17 -14
  49. package/{chunk-EH4MNUMF.js → chunk-ETTDZBK5.js} +4 -4
  50. package/{chunk-BUXH3H5M.js → chunk-FWMOJTGR.js} +3722 -4851
  51. package/{chunk-ZWQUWF6W.js → chunk-G7Y4GXTY.js} +8 -14
  52. package/{chunk-5KTQVMCX.js → chunk-GOO6G4PY.js} +85 -0
  53. package/{chunk-FMOZ57LN.js → chunk-H7HWWNJB.js} +1 -1
  54. package/{chunk-A5VR65AE.js → chunk-HJS5EIKS.js} +4 -4
  55. package/{chunk-H44LQSZ2.js → chunk-HKWGI3TM.js} +178 -311
  56. package/{chunk-BBGYSMUE.js → chunk-JH7KMNGT.js} +143 -19
  57. package/{chunk-YXMZHGNA.js → chunk-KDUYNEJ5.js} +33 -16
  58. package/{chunk-O5V7QQAF.js → chunk-LEX6DEH4.js} +114 -2
  59. package/{chunk-BTBT2566.js → chunk-MNUOMXJH.js} +412 -9
  60. package/{chunk-N7E3LQ4A.js → chunk-MZXWSY4E.js} +1 -1
  61. package/{chunk-ZQ3EAOY3.js → chunk-NTLJGRAT.js} +1 -1
  62. package/{chunk-WFUIXNKC.js → chunk-P4YLK2OD.js} +3 -3
  63. package/chunk-PRJ473FK.js +63 -0
  64. package/{chunk-2SHLT6JB.js → chunk-Q7GNBUT4.js} +2 -2
  65. package/{chunk-C2UXCAMB.js → chunk-RIKSN62L.js} +3 -3
  66. package/{chunk-GTP6VNWH.js → chunk-RQ22OZD7.js} +3 -3
  67. package/{chunk-H7NIQGTU.js → chunk-RS66RJLA.js} +2 -2
  68. package/{chunk-GC64WGMD.js → chunk-SM3NSZJV.js} +16 -5
  69. package/{chunk-QKDMI22S.js → chunk-SSK4WNJA.js} +1 -1
  70. package/{chunk-6MAFLMAO.js → chunk-SUBNV2JH.js} +3 -3
  71. package/{chunk-HLAL63BZ.js → chunk-T43B7LB2.js} +1 -1
  72. package/{chunk-HTLIKE5U.js → chunk-TWVVTUNG.js} +2 -2
  73. package/{chunk-X3RWBJDQ.js → chunk-U7HTU2S7.js} +1 -1
  74. package/{chunk-76YUTLOT.js → chunk-UIOEHFF6.js} +1 -1
  75. package/{chunk-IIX6VWLW.js → chunk-VCFU3BO5.js} +224 -38
  76. package/{chunk-QU3TLYBR.js → chunk-VEUSD6OF.js} +35 -11
  77. package/{chunk-4YMD7B4Y.js → chunk-WPOKOKZA.js} +2 -2
  78. package/{chunk-K6TZSON4.js → chunk-WTKYP6QO.js} +19 -5
  79. package/{chunk-FEKMTBKJ.js → chunk-XW6B2RJW.js} +192 -55
  80. package/{chunk-ZSO5B6SW.js → chunk-Y2WUYX4I.js} +9 -0
  81. package/{chunk-A3SXTJDE.js → chunk-YAGFPXOX.js} +14 -14
  82. package/{chunk-TVGX5QIN.js → chunk-YUA6OAH5.js} +2 -2
  83. package/{chunk-NYE2INIO.js → chunk-YV2RSLM4.js} +13 -13
  84. package/{chunk-MJWUBTK7.js → chunk-YZGNKHUM.js} +2 -2
  85. package/{commandRegistry-YFXWA5SF.js → commandRegistry-HEBIO2A4.js} +87 -67
  86. package/{contentThunks-2BV7CFUP.js → contentThunks-I4IHSDTM.js} +14 -13
  87. package/{cooldownCommands-KRILPXOZ.js → cooldownCommands-5SJ74DNP.js} +1 -1
  88. package/{createAgentAutomationAction-T6CGXCSO.js → createAgentAutomationAction-WQCH5HR2.js} +14 -13
  89. package/{createDialogAction-X27IA3G2.js → createDialogAction-CKMZK5JQ.js} +15 -14
  90. package/{createPageAction-EHDHNW5P.js → createPageAction-QAZHQGY7.js} +14 -13
  91. package/{dialogCommands-XZXH3HSQ.js → dialogCommands-YMAHICPJ.js} +30 -28
  92. package/{dialogSlice-AZNPVOCU.js → dialogSlice-GEGACCH2.js} +13 -12
  93. package/{docCreateCommands-Z64V5BFZ.js → docCreateCommands-SNMAKBXN.js} +28 -26
  94. package/{docDeleteCommands-7UFHIM4C.js → docDeleteCommands-K52UESRC.js} +29 -27
  95. package/{docReadCommands-NLU7Y67R.js → docReadCommands-AG6LLHJ7.js} +28 -26
  96. package/{docStore-M37Q6JFO.js → docStore-B4EFT53J.js} +1 -1
  97. package/{docUpdateCommands-S2KGBEG3.js → docUpdateCommands-B5EZ7DYN.js} +28 -26
  98. package/{fetchMessages-HWBVATSE.js → fetchMessages-YY4SATNR.js} +1 -1
  99. package/{getPricing-E2PLNWCR.js → getPricing-3PQY3TGI.js} +3 -3
  100. package/{handleSendMessageAction-KUJQZ6B6.js → handleSendMessageAction-4BACQWOG.js} +70 -29
  101. package/index.js +7 -7
  102. package/{lib-4YTWAGY7.js → lib-5KKIBFIT.js} +439 -272
  103. package/{localDialogRead-CT5HGDMC.js → localDialogRead-FUXGZ57B.js} +1 -1
  104. package/{localRuntimeAdapter-5BNHO6JZ.js → localRuntimeAdapter-5CVSCXHI.js} +45 -43
  105. package/{machineCommands-2KDROAVV.js → machineCommands-R7L4IBQL.js} +48 -46
  106. package/{machineWsRunDispatch-4NP5M574.js → machineWsRunDispatch-KZHTW7DW.js} +46 -44
  107. package/{models-UUNO6DOL.js → models-PJBE6JDV.js} +2 -2
  108. package/{oauthTokenStore-PADKLNOC.js → oauthTokenStore-OEERZFUC.js} +2 -1
  109. package/package.json +1 -1
  110. package/{providerPresetApply-JGNMO2KX.js → providerPresetApply-HBBUUVJD.js} +6 -6
  111. package/{providerRegistry-33J3ZYFJ.js → providerRegistry-5LK2NXYE.js} +6 -6
  112. package/{readlineWorkspace-MKUSR6HA.js → readlineWorkspace-PDPEWRSG.js} +290 -121
  113. package/{runAgentClientLoop-J32KRVN7.js → runAgentClientLoop-QKV66PX5.js} +31 -30
  114. package/{runtimeDoctorCommands-NYBOTA6D.js → runtimeDoctorCommands-3VFVTGPI.js} +8 -7
  115. package/{secretCommands-N6CMCJDZ.js → secretCommands-MKU25CDP.js} +311 -3
  116. package/{settingThunks-YRYNPWJM.js → settingThunks-4WU7YE62.js} +2 -2
  117. package/{skillDiscovery-F3TMVQOJ.js → skillDiscovery-BKLWW2EZ.js} +2 -2
  118. package/{spaceCommands-VV4K7TGI.js → spaceCommands-VD3CZWXM.js} +27 -25
  119. package/{streamAgentChatTurn-S2Q7STXS.js → streamAgentChatTurn-GM3UNSLS.js} +46 -43
  120. package/{tools-KOIPW4ZA.js → tools-UJLEQBKI.js} +25 -24
  121. package/{tuiSummaryLlmCaller-FSOADMXK.js → tuiSummaryLlmCaller-73QO3HAD.js} +12 -12
  122. package/{updateCommands-KE6LP3QX.js → updateCommands-RVDAFHBT.js} +3 -3
  123. package/{updateDialogTitleAction-ILS5OIXF.js → updateDialogTitleAction-24QO27NT.js} +14 -13
  124. package/{windowsSelfUpdate-26TSFXEZ.js → windowsSelfUpdate-N2VH2OBW.js} +2 -2
@@ -2,9 +2,15 @@ import {
2
2
  isAgentRunTerminalStatus,
3
3
  normalizeRunTitle
4
4
  } from "./chunk-PJNFNEJE.js";
5
+ import {
6
+ findPowerShellExecutable
7
+ } from "./chunk-2BMURXSB.js";
5
8
  import {
6
9
  resolvePlatformAuthToken
7
- } from "./chunk-4YMD7B4Y.js";
10
+ } from "./chunk-WPOKOKZA.js";
11
+ import {
12
+ isRecord
13
+ } from "./chunk-KUG52IAP.js";
8
14
  import {
9
15
  isCompiledBinary,
10
16
  resolveCliEntrypointPath
@@ -318,6 +324,124 @@ function createShellApprovalChild(channel, timeoutMs = TTL) {
318
324
  };
319
325
  }
320
326
 
327
+ // packages/core/redactLogLines.ts
328
+ var TAIL_LINES_MAX = 500;
329
+ var REDACTED_TOKEN = "[REDACTED_TOKEN]";
330
+ var REDACTED_CREDENTIAL = "[REDACTED_CREDENTIAL]";
331
+ var REDACTED_COMMAND = "[REDACTED_COMMAND]";
332
+ var REDACTED_ARGS = "[REDACTED_ARGS]";
333
+ var REDACTED_PATH = "[REDACTED_PATH]";
334
+ var SECRET_RULES = [
335
+ // Authorization: Bearer <token>
336
+ {
337
+ re: /\bBearer\s+[A-Za-z0-9_\-.\~+/=]{8,}/gi,
338
+ replacement: `Bearer ${REDACTED_TOKEN}`
339
+ },
340
+ // GitHub 家族前缀 token(ghp_/gho_/ghu_/ghs_/ghr_)
341
+ {
342
+ re: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}\b/g,
343
+ replacement: REDACTED_TOKEN
344
+ },
345
+ // key=value / key: value。key 名自带凭据关键词才脱敏,避免把普通日志打花。
346
+ // key 字符类含 `-`/`_`,故 `NOLO_WORKER_TOKEN=`(env 前缀)、
347
+ // `x-nolo-machine-lease:`、`x-worker-token:` 都在命中面内。
348
+ // 同时支持带闭合双/单引号的 JSON 键,如 {"apiKey":"..."} 或 {"token": "..."}。
349
+ {
350
+ re: /(["']?)\b([A-Za-z0-9_-]*(?:token|secret|password|passwd|credential|api[_-]?key|machine[_-]lease|workspace[_-]lease)[A-Za-z0-9_-]*)\1(\s*[:=]\s*)(["']?)[^\s"',;}{]{4,}\4/gi,
351
+ replacement: `$1$2$1$3$4${REDACTED_CREDENTIAL}$4`
352
+ }
353
+ ];
354
+ var PATH_RULES = [
355
+ {
356
+ re: /(^|[\s"'`(=:])\/(?:home|Users|var|tmp|app|etc|root|usr|opt|mnt|srv|private|storage|workspace)\/[^\s"'`),;:]+/g,
357
+ replacement: `$1${REDACTED_PATH}`
358
+ },
359
+ {
360
+ re: /(^|[\s"'`(=:])[A-Za-z]:\\[^\s"'`),;:]+/g,
361
+ replacement: `$1${REDACTED_PATH}`
362
+ },
363
+ // `~/.nolo` / `/home/x/.nolo`(凭据与机器身份落点)
364
+ {
365
+ re: /~?\/\.nolo(\/[^\s"'`),;:]*)?/g,
366
+ replacement: REDACTED_PATH
367
+ },
368
+ // process.execPath / bunPath / BUN_PATH
369
+ {
370
+ re: /\b((?:process\.execPath|bunPath|execPath|BUN_PATH)\s*[:=]\s*)(["']?)[^\s"']+\2/gi,
371
+ replacement: `$1$2${REDACTED_PATH}$2`
372
+ }
373
+ ];
374
+ function redactStageStartJson(line) {
375
+ const trimmed = line.trim();
376
+ if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) {
377
+ return { line, hit: false };
378
+ }
379
+ let parsed;
380
+ try {
381
+ parsed = JSON.parse(trimmed);
382
+ } catch {
383
+ return { line, hit: false };
384
+ }
385
+ if (!isRecord(parsed)) return { line, hit: false };
386
+ const isStageStart = parsed.type === "stage-start" || parsed.event === "stage_start" || parsed.phase === "stage_start" || "command" in parsed && "args" in parsed;
387
+ if (!isStageStart) return { line, hit: false };
388
+ let hits = 0;
389
+ if ("command" in parsed) {
390
+ parsed.command = REDACTED_COMMAND;
391
+ hits += 1;
392
+ }
393
+ if ("args" in parsed) {
394
+ parsed.args = [REDACTED_ARGS];
395
+ hits += 1;
396
+ }
397
+ if (hits === 0) return { line, hit: false };
398
+ return { line: JSON.stringify(parsed), hit: true };
399
+ }
400
+ function applyRules(line, rules) {
401
+ let out = line;
402
+ let hit = false;
403
+ for (const rule of rules) {
404
+ rule.re.lastIndex = 0;
405
+ if (!rule.re.test(out)) continue;
406
+ rule.re.lastIndex = 0;
407
+ out = out.replace(rule.re, rule.replacement);
408
+ hit = true;
409
+ }
410
+ return { line: out, hit };
411
+ }
412
+ function redactLogLine(rawLine) {
413
+ if (typeof rawLine !== "string") return { line: "", hit: false };
414
+ const jsonCheck = redactStageStartJson(rawLine);
415
+ let line = jsonCheck.hit ? jsonCheck.line : rawLine;
416
+ let hit = jsonCheck.hit;
417
+ const secrets = applyRules(line, SECRET_RULES);
418
+ line = secrets.line;
419
+ hit = hit || secrets.hit;
420
+ const paths = applyRules(line, PATH_RULES);
421
+ line = paths.line;
422
+ hit = hit || paths.hit;
423
+ return { line, hit };
424
+ }
425
+ function redactLogLines(lines, options = {}) {
426
+ const input = Array.isArray(lines) ? lines : [];
427
+ const requested = options.tailLines !== void 0 && Number.isFinite(options.tailLines) && options.tailLines > 0 ? Math.floor(options.tailLines) : TAIL_LINES_MAX;
428
+ const clampedTail = Math.min(Math.max(1, requested), TAIL_LINES_MAX);
429
+ const truncated = input.length > clampedTail;
430
+ const sliced = input.slice(-clampedTail);
431
+ let redactedCount = 0;
432
+ const redactedLines = sliced.map((raw) => {
433
+ const { line, hit } = redactLogLine(typeof raw === "string" ? raw : String(raw));
434
+ if (hit) redactedCount += 1;
435
+ return line;
436
+ });
437
+ return {
438
+ lines: redactedLines,
439
+ truncated,
440
+ redacted: redactedCount,
441
+ lastUpdatedAt: options.now ?? Date.now()
442
+ };
443
+ }
444
+
321
445
  // packages/cli/agentRunControl.ts
322
446
  import { homedir as nodeHomedir } from "node:os";
323
447
  import { dirname, isAbsolute as isAbsolute2, join as join2, resolve } from "node:path";
@@ -999,6 +1123,7 @@ function serverOriginForDialog(serverUrl) {
999
1123
  }
1000
1124
  }
1001
1125
  function yamlScalar(value) {
1126
+ if (value === null) return "null";
1002
1127
  return typeof value === "number" ? String(value) : JSON.stringify(value);
1003
1128
  }
1004
1129
  function buildResultFrontMatter(input) {
@@ -1011,6 +1136,15 @@ function buildResultFrontMatter(input) {
1011
1136
  ["endedAt", input.endedAt],
1012
1137
  ["durationMs", input.durationMs],
1013
1138
  ["toolCallCount", input.toolCallCount],
1139
+ // 缓存命中观测(见 ai/token/cacheRunSummary):
1140
+ // - cacheInputTokens:本 run 输入 token 总量(各次调用相加,含命中部分)
1141
+ // - cacheCachedTokens:其中命中缓存被复用的量;**null = 未知**(provider
1142
+ // 未提供 cached 字段),0 才是「确实命中 0」——两者不可混
1143
+ // - cacheHitRatio:派生的 cached/input(4 位小数);input=0 时为 0,
1144
+ // cached 未知时为 null
1145
+ ["cacheInputTokens", input.cacheUsage?.input_tokens],
1146
+ ["cacheCachedTokens", input.cacheUsage?.cached_tokens],
1147
+ ["cacheHitRatio", input.cacheUsage?.cache_hit_ratio],
1014
1148
  ["dialogId", input.dialogId],
1015
1149
  ["server", input.server],
1016
1150
  ["serverSync", input.serverSync],
@@ -1485,6 +1619,87 @@ function reportRunProcessIdentity(runId, deps = {}) {
1485
1619
  }
1486
1620
  var FILE_EDIT_TOOL_NAMES = /* @__PURE__ */ new Set(["writeFile", "editFile"]);
1487
1621
  var DEFAULT_ACTIVITY_WRITE_INTERVAL_MS = 2e3;
1622
+ var CREDENTIAL_ASSIGNMENT_PATTERN = /(["']?\b[A-Za-z0-9_-]*(?:token|secret|password|passwd|credential|api[_-]?key|machine[_-]?lease|workspace[_-]?lease)[A-Za-z0-9_-]*["']?\s*[:=]\s*)[\s\S]*$/gi;
1623
+ var BEARER_PATTERN = /\bBearer\s+[\s\S]*$/gi;
1624
+ var GITHUB_TOKEN_PATTERN = /\b(?:ghp|gho|ghu|ghs|ghr)_[\s\S]*/g;
1625
+ function stripCredentialMarkers(text) {
1626
+ const masked = text.replace(CREDENTIAL_ASSIGNMENT_PATTERN, "$1[REDACTED_CREDENTIAL]").replace(BEARER_PATTERN, "Bearer [REDACTED_TOKEN]").replace(GITHUB_TOKEN_PATTERN, "[REDACTED_TOKEN]");
1627
+ return { masked, credential: masked !== text };
1628
+ }
1629
+ function createCredentialScanner() {
1630
+ let identTail = "";
1631
+ let identRunLength = 0;
1632
+ let identHasKeyword = false;
1633
+ let pendingSeparator = false;
1634
+ const KEYWORD = /token|secret|password|passwd|credential|api[_-]?key|machine[_-]?lease|workspace[_-]?lease/i;
1635
+ const GH = /(?:ghp|gho|ghu|ghs|ghr)_/gi;
1636
+ function startsAtWordBoundary(run, index, runLength) {
1637
+ if (index > 0) return !/[A-Za-z0-9_]/.test(run[index - 1]);
1638
+ return runLength === run.length;
1639
+ }
1640
+ function feed(text) {
1641
+ for (let i = 0; i < text.length; i++) {
1642
+ const ch = text[i];
1643
+ if (/[A-Za-z0-9_-]/.test(ch)) {
1644
+ if (pendingSeparator) {
1645
+ pendingSeparator = false;
1646
+ identTail = "";
1647
+ identRunLength = 0;
1648
+ identHasKeyword = false;
1649
+ }
1650
+ identTail = (identTail + ch).slice(-40);
1651
+ identRunLength += 1;
1652
+ if (KEYWORD.test(identTail)) {
1653
+ identHasKeyword = true;
1654
+ }
1655
+ GH.lastIndex = 0;
1656
+ let m;
1657
+ while ((m = GH.exec(identTail)) !== null) {
1658
+ if (startsAtWordBoundary(identTail, m.index, identRunLength)) {
1659
+ reset();
1660
+ return i + 1;
1661
+ }
1662
+ }
1663
+ } else {
1664
+ if (identTail.toLowerCase().endsWith("bearer") && /\s/.test(ch) && startsAtWordBoundary(identTail, identTail.length - 6, identRunLength)) {
1665
+ reset();
1666
+ return i + 1;
1667
+ }
1668
+ if (pendingSeparator) {
1669
+ if (ch === ":" || ch === "=") {
1670
+ reset();
1671
+ return i + 1;
1672
+ }
1673
+ if (/\s/.test(ch) || ch === '"' || ch === "'") {
1674
+ } else {
1675
+ reset();
1676
+ }
1677
+ } else if (identHasKeyword) {
1678
+ if (ch === ":" || ch === "=") {
1679
+ reset();
1680
+ return i + 1;
1681
+ }
1682
+ if (/\s/.test(ch) || ch === '"' || ch === "'") {
1683
+ pendingSeparator = true;
1684
+ }
1685
+ identTail = "";
1686
+ identRunLength = 0;
1687
+ identHasKeyword = false;
1688
+ } else {
1689
+ reset();
1690
+ }
1691
+ }
1692
+ }
1693
+ return -1;
1694
+ }
1695
+ function reset() {
1696
+ identTail = "";
1697
+ identRunLength = 0;
1698
+ identHasKeyword = false;
1699
+ pendingSeparator = false;
1700
+ }
1701
+ return { feed, reset };
1702
+ }
1488
1703
  function createRunActivityTracker(runId, deps = {}, options = {}) {
1489
1704
  const fs = deps.fs ?? nodeFs2;
1490
1705
  const now = deps.now ?? (() => /* @__PURE__ */ new Date());
@@ -1492,15 +1707,81 @@ function createRunActivityTracker(runId, deps = {}, options = {}) {
1492
1707
  const keepAlive = options.keepAlive ?? true;
1493
1708
  let disposed = false;
1494
1709
  let lastEventAt = now().toISOString();
1710
+ let lastProgressAt = now().toISOString();
1495
1711
  let inFlight = null;
1496
1712
  const counters = { llmCalls: 0, toolCalls: 0, fileEdits: 0 };
1713
+ const lastToolNames = [];
1497
1714
  let writeTimer;
1498
1715
  let lastWriteAt = 0;
1716
+ let partialText = "";
1717
+ let pendingLine = "";
1718
+ let droppingLine = false;
1719
+ let droppingCredential = false;
1720
+ const scanner = createCredentialScanner();
1721
+ let lineCredentialHit = false;
1722
+ let partialTruncated = false;
1723
+ let partialRedacted = 0;
1724
+ let partialUpdatedAt;
1725
+ let sourceRound;
1726
+ let currentLlmRound;
1727
+ const PARTIAL_LIMIT = 32e3;
1728
+ const OMITTED_LINE = "[checkpoint: overlong line omitted]";
1729
+ const OMITTED_CREDENTIAL = "[checkpoint: credential content omitted]";
1730
+ function closeLine() {
1731
+ if (droppingCredential) {
1732
+ partialTruncated = true;
1733
+ } else if (lineCredentialHit) {
1734
+ const safe = redactLogLines([stripCredentialMarkers(pendingLine).masked]);
1735
+ partialRedacted += Math.max(1, safe.redacted);
1736
+ let maskedPrefix = safe.lines[0];
1737
+ if (!maskedPrefix.endsWith(REDACTED_CREDENTIAL) && !maskedPrefix.endsWith("[REDACTED_TOKEN]")) {
1738
+ maskedPrefix += REDACTED_CREDENTIAL;
1739
+ }
1740
+ if (partialText.length < 4e3) {
1741
+ partialText += maskedPrefix + "\n";
1742
+ } else {
1743
+ partialTruncated = true;
1744
+ }
1745
+ if (partialText.length > 4e3) partialTruncated = true;
1746
+ droppingCredential = true;
1747
+ partialTruncated = true;
1748
+ } else {
1749
+ const safe = redactLogLines([pendingLine]);
1750
+ partialRedacted += safe.redacted;
1751
+ if (partialText.length < 4e3) {
1752
+ partialText += (droppingLine ? OMITTED_LINE : safe.lines[0]) + "\n";
1753
+ } else {
1754
+ partialTruncated = true;
1755
+ }
1756
+ if (partialText.length > 4e3 || droppingLine) partialTruncated = true;
1757
+ }
1758
+ partialText = partialText.slice(0, 4e3);
1759
+ pendingLine = "";
1760
+ droppingLine = false;
1761
+ lineCredentialHit = false;
1762
+ }
1763
+ function checkpoint() {
1764
+ if (!partialUpdatedAt) return void 0;
1765
+ const text = partialText || (droppingLine ? OMITTED_LINE : droppingCredential ? OMITTED_CREDENTIAL : "");
1766
+ if (!text) return void 0;
1767
+ return {
1768
+ final: false,
1769
+ source: "local-run.text-delta",
1770
+ updatedAt: partialUpdatedAt,
1771
+ sourceRound,
1772
+ currentLlmRound,
1773
+ text,
1774
+ truncated: partialTruncated || droppingLine || droppingCredential,
1775
+ redacted: partialRedacted
1776
+ };
1777
+ }
1499
1778
  function serializeActivity() {
1500
1779
  const nowDate = now();
1501
1780
  const nowMs = nowDate.getTime();
1502
1781
  return {
1503
1782
  lastEventAt,
1783
+ lastProgressAt,
1784
+ ...lastToolNames.length > 0 ? { lastToolNames: [...lastToolNames] } : {},
1504
1785
  inFlight: inFlight ? {
1505
1786
  kind: inFlight.kind,
1506
1787
  name: inFlight.name,
@@ -1519,9 +1800,14 @@ function createRunActivityTracker(runId, deps = {}, options = {}) {
1519
1800
  deps,
1520
1801
  () => {
1521
1802
  const record = readRunRecord(runId, deps);
1522
- if (!record) return;
1803
+ if (!record || isRunTerminalStatus(record.status)) return;
1523
1804
  const activity = serializeActivity();
1524
- writeRunRecord({ ...record, activity }, deps);
1805
+ const partialCheckpoint = checkpoint();
1806
+ writeRunRecord({
1807
+ ...record,
1808
+ activity,
1809
+ ...partialCheckpoint ? { partialCheckpoint } : {}
1810
+ }, deps);
1525
1811
  lastWriteAt = now().getTime();
1526
1812
  },
1527
1813
  { strict: true }
@@ -1536,14 +1822,34 @@ function createRunActivityTracker(runId, deps = {}, options = {}) {
1536
1822
  const delay = Math.max(0, minWriteIntervalMs - elapsed);
1537
1823
  writeTimer = setTimeout(doWrite, delay);
1538
1824
  }
1825
+ let partialRoundStarted = false;
1539
1826
  function onLoopEvent(event) {
1540
1827
  if (disposed) return;
1541
1828
  lastEventAt = new Date(event.atMs).toISOString();
1829
+ lastProgressAt = lastEventAt;
1542
1830
  switch (event.kind) {
1543
1831
  case "llm-start":
1832
+ currentLlmRound = event.round;
1833
+ partialRoundStarted = true;
1834
+ droppingCredential = false;
1835
+ scanner.reset();
1836
+ lineCredentialHit = false;
1544
1837
  inFlight = { kind: "llm", name: "llm", startMs: event.atMs };
1545
1838
  break;
1546
1839
  case "llm-end":
1840
+ if (!partialRoundStarted && event.ok && (pendingLine || droppingLine)) {
1841
+ if (sourceRound !== currentLlmRound) {
1842
+ partialText = "";
1843
+ partialTruncated = false;
1844
+ partialRedacted = 0;
1845
+ sourceRound = currentLlmRound;
1846
+ droppingCredential = false;
1847
+ scanner.reset();
1848
+ lineCredentialHit = false;
1849
+ }
1850
+ closeLine();
1851
+ partialUpdatedAt = now().toISOString();
1852
+ }
1547
1853
  inFlight = null;
1548
1854
  counters.llmCalls += 1;
1549
1855
  break;
@@ -1561,8 +1867,88 @@ function createRunActivityTracker(runId, deps = {}, options = {}) {
1561
1867
  if (toolEndName && FILE_EDIT_TOOL_NAMES.has(toolEndName)) {
1562
1868
  counters.fileEdits += 1;
1563
1869
  }
1870
+ if (toolEndName) {
1871
+ const existingIdx = lastToolNames.indexOf(toolEndName);
1872
+ if (existingIdx >= 0) {
1873
+ lastToolNames.splice(existingIdx, 1);
1874
+ }
1875
+ lastToolNames.push(toolEndName);
1876
+ if (lastToolNames.length > 5) {
1877
+ lastToolNames.splice(0, lastToolNames.length - 5);
1878
+ }
1879
+ }
1564
1880
  break;
1565
1881
  }
1882
+ if (event.kind === "llm-end" && !event.ok) doWrite();
1883
+ else scheduleWrite();
1884
+ }
1885
+ function onPartialText(chunk) {
1886
+ if (disposed || !chunk) return;
1887
+ lastProgressAt = now().toISOString();
1888
+ if (partialRoundStarted) {
1889
+ droppingCredential = false;
1890
+ pendingLine = "";
1891
+ droppingLine = false;
1892
+ scanner.reset();
1893
+ lineCredentialHit = false;
1894
+ partialRoundStarted = false;
1895
+ }
1896
+ for (let start = 0; start < chunk.length; ) {
1897
+ const newline = chunk.indexOf("\n", start);
1898
+ const end = newline < 0 ? chunk.length : newline;
1899
+ const segment = chunk.slice(start, end);
1900
+ const hit = scanner.feed(segment);
1901
+ if (hit >= 0 && !droppingCredential && !lineCredentialHit) {
1902
+ lineCredentialHit = true;
1903
+ if (droppingLine || pendingLine.length + segment.length > PARTIAL_LIMIT) {
1904
+ droppingLine = true;
1905
+ pendingLine = "";
1906
+ droppingCredential = true;
1907
+ partialTruncated = true;
1908
+ partialRedacted += 1;
1909
+ } else {
1910
+ pendingLine += segment.slice(0, hit);
1911
+ }
1912
+ } else if (!lineCredentialHit && !droppingLine) {
1913
+ if (pendingLine.length + segment.length > PARTIAL_LIMIT) {
1914
+ pendingLine = "";
1915
+ droppingLine = true;
1916
+ } else {
1917
+ pendingLine += segment;
1918
+ }
1919
+ } else if (lineCredentialHit && !droppingLine) {
1920
+ if (pendingLine.length + segment.length > PARTIAL_LIMIT) {
1921
+ droppingLine = true;
1922
+ pendingLine = "";
1923
+ droppingCredential = true;
1924
+ partialTruncated = true;
1925
+ partialRedacted += 1;
1926
+ }
1927
+ }
1928
+ if (newline >= 0) {
1929
+ const nlHit = scanner.feed("\n");
1930
+ if (nlHit >= 0 && !droppingCredential && !lineCredentialHit) {
1931
+ lineCredentialHit = true;
1932
+ if (droppingLine) {
1933
+ droppingCredential = true;
1934
+ partialTruncated = true;
1935
+ partialRedacted += 1;
1936
+ }
1937
+ }
1938
+ }
1939
+ if (newline >= 0 || droppingLine) {
1940
+ if (sourceRound !== currentLlmRound) {
1941
+ partialText = "";
1942
+ partialTruncated = false;
1943
+ partialRedacted = 0;
1944
+ sourceRound = currentLlmRound;
1945
+ droppingCredential = false;
1946
+ }
1947
+ if (newline >= 0) closeLine();
1948
+ }
1949
+ start = end + 1;
1950
+ }
1951
+ if (sourceRound === currentLlmRound) partialUpdatedAt = now().toISOString();
1566
1952
  scheduleWrite();
1567
1953
  }
1568
1954
  function getActivity() {
@@ -1578,7 +1964,7 @@ function createRunActivityTracker(runId, deps = {}, options = {}) {
1578
1964
  writeTimer = void 0;
1579
1965
  }
1580
1966
  }
1581
- return { onLoopEvent, getActivity, flush, dispose };
1967
+ return { onLoopEvent, onPartialText, getActivity, flush, dispose };
1582
1968
  }
1583
1969
  function readRunRecord(runId, deps = {}) {
1584
1970
  const fs = deps.fs ?? nodeFs2;
@@ -1900,6 +2286,7 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
1900
2286
  batchId,
1901
2287
  ...typeof input.credentialGroup === "string" && input.credentialGroup.trim() ? { credentialGroup: input.credentialGroup.trim() } : {},
1902
2288
  ...typeof input.parentDialogId === "string" && input.parentDialogId.trim() ? { parentDialogId: input.parentDialogId.trim() } : {},
2289
+ ...typeof input.dialogId === "string" && input.dialogId.trim() ? { dialogId: input.dialogId.trim() } : {},
1903
2290
  ...dodCommands && dodCommands.length > 0 ? { dodCommands } : {},
1904
2291
  ...spawnHead ? { spawnHead } : {},
1905
2292
  ...input.ephemeral ? { ephemeral: true } : {},
@@ -2138,7 +2525,8 @@ function transitionRunToTerminal(runId, update, deps = {}, options = {}) {
2138
2525
  server: update.dialogServer ?? "local",
2139
2526
  serverSync: update.serverSync,
2140
2527
  cwd: record2.cwd,
2141
- continuedFrom: record2.continuedFrom
2528
+ continuedFrom: record2.continuedFrom,
2529
+ ...update.cacheUsage ? { cacheUsage: update.cacheUsage } : {}
2142
2530
  },
2143
2531
  update.lastAssistantText
2144
2532
  );
@@ -2197,8 +2585,9 @@ function defaultGetProcessStartTime(pid, deps = {}) {
2197
2585
  try {
2198
2586
  const execFileSync = deps.execFileSync ?? nodeExecFileSync;
2199
2587
  if ((deps.platform ?? process.platform) === "win32") {
2588
+ const resolvePowerShell = deps.resolvePowerShellExecutable ?? findPowerShellExecutable;
2200
2589
  const systemRoot = (deps.env ?? process.env).SystemRoot;
2201
- const shell = systemRoot ? join2(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : "powershell.exe";
2590
+ const shell = resolvePowerShell() ?? (systemRoot ? join2(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : "powershell.exe");
2202
2591
  const output2 = execFileSync(shell, [
2203
2592
  "-NoProfile",
2204
2593
  "-NonInteractive",
@@ -2444,9 +2833,12 @@ function printStatusTick(record, deps) {
2444
2833
  );
2445
2834
  }
2446
2835
  async function runAgentStatusCommand(args, deps) {
2447
- const { target, json, watch, intervalMs } = parseStatusArgs(args);
2836
+ const includeCheckpoint = args.includes("--include-checkpoint");
2837
+ const { target, json, watch, intervalMs } = parseStatusArgs(
2838
+ args.filter((arg) => arg !== "--include-checkpoint")
2839
+ );
2448
2840
  if (!target) {
2449
- deps.output.write("Usage: nolo agent status <runId|pid> [--json] [--watch] [--interval-ms N]\n");
2841
+ deps.output.write("Usage: nolo agent status <runId|pid> [--json] [--include-checkpoint] [--watch] [--interval-ms N]\n");
2450
2842
  return 1;
2451
2843
  }
2452
2844
  const initial = findRunRecord(target, deps);
@@ -2458,9 +2850,19 @@ async function runAgentStatusCommand(args, deps) {
2458
2850
  const reconciled = checkStaleRun(initial.runId, deps) ?? initial;
2459
2851
  if (json) {
2460
2852
  const record = readRunRecord(reconciled.runId, deps) ?? reconciled;
2461
- deps.output.write(JSON.stringify(record) + "\n");
2853
+ const { partialCheckpoint, ...summary } = record;
2854
+ deps.output.write(JSON.stringify({
2855
+ ...summary,
2856
+ ...includeCheckpoint ? { checkpoint: partialCheckpoint ? { ...partialCheckpoint, available: true } : { available: false, final: false, reason: "checkpoint_missing" } } : {}
2857
+ }) + "\n");
2462
2858
  return 0;
2463
2859
  }
2860
+ if (includeCheckpoint) {
2861
+ const record = readRunRecord(reconciled.runId, deps) ?? reconciled;
2862
+ deps.output.write(record.partialCheckpoint ? `Partial checkpoint (not final; source LLM round: ${record.partialCheckpoint.sourceRound ?? "unknown"}; current LLM round: ${record.partialCheckpoint.currentLlmRound ?? "unknown"}):
2863
+ ${record.partialCheckpoint.text}
2864
+ ` : "Partial checkpoint unavailable.\n");
2865
+ }
2464
2866
  if (!watch) {
2465
2867
  const record = readRunRecord(reconciled.runId, deps) ?? reconciled;
2466
2868
  return printStatusOnce(record, deps);
@@ -2744,6 +3146,7 @@ async function runAgentKillCommand(args, deps) {
2744
3146
  }
2745
3147
 
2746
3148
  export {
3149
+ TAIL_LINES_MAX,
2747
3150
  createShellApprovalChild,
2748
3151
  readHostMemory,
2749
3152
  assertHostMemoryAdmission,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveAgentImageInputSupport
3
- } from "./chunk-PVD7CRYV.js";
3
+ } from "./chunk-6I7ZP7KJ.js";
4
4
  import {
5
5
  TOOL_HAD_IMAGES,
6
6
  hadToolImages
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  readDbRecord,
3
3
  writeAgentRecord
4
- } from "./chunk-6WZQGT5X.js";
4
+ } from "./chunk-CJ37ZMCQ.js";
5
5
  import {
6
6
  buildSkillSummaryMarker
7
7
  } from "./chunk-VF4K2QE6.js";
@@ -5,15 +5,15 @@ import {
5
5
  ANTIGRAVITY_CLOUD_CODE_BASE_URL,
6
6
  isAntigravityCloudCodeBaseUrl,
7
7
  isAntigravityOAuthAgent
8
- } from "./chunk-QU3TLYBR.js";
8
+ } from "./chunk-VEUSD6OF.js";
9
9
  import {
10
10
  isOpenAiResponsesModel,
11
11
  resolvePlatformChatCompletionsEndpoint,
12
12
  resolvePlatformResponsesEndpoint
13
- } from "./chunk-TVGX5QIN.js";
13
+ } from "./chunk-YUA6OAH5.js";
14
14
  import {
15
15
  findModelConfig
16
- } from "./chunk-GC64WGMD.js";
16
+ } from "./chunk-SM3NSZJV.js";
17
17
  import {
18
18
  asOptionalTrimmedString
19
19
  } from "./chunk-G3SUCT4W.js";
@@ -0,0 +1,63 @@
1
+ // packages/agent-runtime/skillSlashReference.ts
2
+ var DEFAULT_SKILL_SLASH_USER_PROMPT = "\u8BF7\u6309\u7167\u8BE5\u6280\u80FD\u7684\u6307\u793A\u6267\u884C\u3002";
3
+ function resolveSkillSlashUserPrompt(args) {
4
+ const trimmed = args.replace(/^\s+/, "");
5
+ return trimmed.length > 0 ? trimmed : DEFAULT_SKILL_SLASH_USER_PROMPT;
6
+ }
7
+ function isNonEmpty(value) {
8
+ return typeof value === "string" && value.trim().length > 0;
9
+ }
10
+ function formatSkillSlashReference(reference) {
11
+ let payload;
12
+ switch (reference.source) {
13
+ case "builtin":
14
+ if (!isNonEmpty(reference.id)) throw new TypeError("Empty builtin skill id");
15
+ payload = reference.id;
16
+ break;
17
+ case "space":
18
+ if (!isNonEmpty(reference.dbKey)) throw new TypeError("Empty space skill dbKey");
19
+ payload = reference.dbKey;
20
+ break;
21
+ case "project":
22
+ if (!isNonEmpty(reference.projectBinding) || !isNonEmpty(reference.relativePath)) {
23
+ throw new TypeError("Empty project skill binding or relative path");
24
+ }
25
+ payload = JSON.stringify([reference.projectBinding, reference.relativePath]);
26
+ break;
27
+ default:
28
+ throw new TypeError("Unknown skill source");
29
+ }
30
+ return `/skill@${reference.source}:${encodeURIComponent(payload)}`;
31
+ }
32
+ function parseSkillSlashReference(input) {
33
+ const match = /^\/skill@([^:\s]+):(\S+)([\s\S]*)$/.exec(input);
34
+ if (!match) return null;
35
+ const [, source, encoded, args] = match;
36
+ if (source !== "builtin" && source !== "space" && source !== "project") return null;
37
+ try {
38
+ const payload = decodeURIComponent(encoded);
39
+ if (!isNonEmpty(payload)) return null;
40
+ switch (source) {
41
+ case "builtin":
42
+ return { reference: { source, id: payload }, args };
43
+ case "space":
44
+ return { reference: { source, dbKey: payload }, args };
45
+ case "project": {
46
+ const pair = JSON.parse(payload);
47
+ if (!Array.isArray(pair) || pair.length !== 2 || !pair.every(isNonEmpty)) return null;
48
+ return {
49
+ reference: { source, projectBinding: pair[0], relativePath: pair[1] },
50
+ args
51
+ };
52
+ }
53
+ }
54
+ } catch {
55
+ return null;
56
+ }
57
+ }
58
+
59
+ export {
60
+ resolveSkillSlashUserPrompt,
61
+ formatSkillSlashReference,
62
+ parseSkillSlashReference
63
+ };
@@ -4,12 +4,12 @@ import {
4
4
  isAgentSkillDisabled,
5
5
  resolveAgentSkillConfig,
6
6
  resolveUserEnabledSkills
7
- } from "./chunk-QYOB7RVA.js";
7
+ } from "./chunk-DKZJJ2NQ.js";
8
8
  import {
9
9
  resolveBuiltinSkillEntry,
10
10
  resolveBuiltinSkillPage,
11
11
  resolveSkillGraphFromRoots
12
- } from "./chunk-O5V7QQAF.js";
12
+ } from "./chunk-LEX6DEH4.js";
13
13
  import {
14
14
  parseSkillDocProtocol
15
15
  } from "./chunk-AETZ7AD6.js";