nolo-cli 0.201.0-alpha.2 → 0.202.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.
- package/{_executeModel-BNYZLAN6.js → _executeModel-IPRTPSW7.js} +34 -33
- package/{agentDeleteCommand-4V4YSAXS.js → agentDeleteCommand-6HFA37FH.js} +49 -47
- package/{agentEmailCommands-EYIQEH6Z.js → agentEmailCommands-TDBNVIAT.js} +51 -49
- package/{agentListCommands-2KGUT7UB.js → agentListCommands-YSQSDQM3.js} +81 -45
- package/{agentMachineCommands-WUN47ILO.js → agentMachineCommands-5W23BLFR.js} +28 -26
- package/{agentProviderCommands-T6E3JCR6.js → agentProviderCommands-5ALOQLE5.js} +2 -2
- package/{agentRecordCommands-XL2CON36.js → agentRecordCommands-SRIMZZFK.js} +47 -45
- package/{agentRunCommand-R237ZGMQ.js → agentRunCommand-BLYHIN6S.js} +49 -47
- package/{agentRunControl-6HHESKDB.js → agentRunControl-ABDUPJLX.js} +10 -5
- package/{agentRuntimeLocal-XLLWFAVI.js → agentRuntimeLocal-FE66EBRC.js} +24 -22
- package/{agentSlice-Z5NKGMB7.js → agentSlice-BFDKYW6H.js} +4 -3
- package/{appDeleteCommands-IPF2VI3W.js → appDeleteCommands-BEVZGCAG.js} +29 -27
- package/{appDeployCommands-IBQ7GUXO.js → appDeployCommands-E7TFCHSP.js} +29 -27
- package/{appDeployStatusCommands-6ESVU6XE.js → appDeployStatusCommands-MYY5Z5G3.js} +29 -27
- package/{appGetCommands-VTSYTM4V.js → appGetCommands-HNED5JUU.js} +29 -27
- package/{appListCommands-VCP5TUX7.js → appListCommands-MSBFWPIY.js} +29 -27
- package/{authCommand-RV5MQDWN.js → authCommand-W34UWJGR.js} +14 -13
- package/{builtinSkillRegistry-7RAJP7FD.js → builtinSkillRegistry-NJVHQIKY.js} +1 -1
- package/{chromeOpsCommands-BA6CS4DI.js → chromeOpsCommands-USKE4B4K.js} +15 -4
- package/{chunk-RE3B2OCC.js → chunk-266E37EL.js} +69 -14
- package/chunk-2BMURXSB.js +1863 -0
- package/{chunk-NABJEYPJ.js → chunk-2Q3LOAFE.js} +38 -3
- package/{chunk-EOLPKHSB.js → chunk-326HCB6L.js} +28 -24
- package/{chunk-4CEAZRZ4.js → chunk-33W4IFUU.js} +1 -1
- package/{chunk-V3MGT3RF.js → chunk-3CWF2EUZ.js} +8 -8
- package/{chunk-G6OOUQWJ.js → chunk-4KB6WQUL.js} +2 -0
- package/{chunk-DYQXB46J.js → chunk-4KPB3KWX.js} +2 -2
- package/{chunk-WAZ6BTSC.js → chunk-5E4FSR4J.js} +1 -1
- package/{chunk-PVD7CRYV.js → chunk-6I7ZP7KJ.js} +3 -3
- package/chunk-6UBGXX2W.js +12 -0
- package/{chunk-ZBCBFOWC.js → chunk-A2ZMIRLN.js} +2 -2
- package/{chunk-Z646E5YH.js → chunk-ASG7VWPK.js} +3 -3
- package/{chunk-QWVGFBOQ.js → chunk-BLFZULEQ.js} +3 -3
- package/{chunk-RRHJJUA3.js → chunk-BRZTSZBG.js} +174 -100
- package/{chunk-JIFYXQRD.js → chunk-BTYQAODF.js} +26 -8
- package/{chunk-KORCRPLO.js → chunk-C7PKPHK6.js} +334 -12
- package/{chunk-6WZQGT5X.js → chunk-CJ37ZMCQ.js} +6 -2
- package/{chunk-VHGD6FHV.js → chunk-CKAHAVMK.js} +40 -10
- package/{chunk-UNOILAZP.js → chunk-CLTGWJVT.js} +76 -4
- package/{chunk-Q6RMLYSA.js → chunk-CMLBKYEI.js} +4 -2
- package/{chunk-NVOYW6H4.js → chunk-CQHMBWZH.js} +12 -8
- package/{chunk-7KWPNGVJ.js → chunk-CTZ4O3XD.js} +1 -1
- package/{chunk-OHRDHS4N.js → chunk-CVCRAO6Q.js} +9 -4
- package/{chunk-26CRLZFD.js → chunk-D57YYGMD.js} +2 -2
- package/{chunk-TEC5UHQK.js → chunk-DHJXDGC3.js} +2 -2
- package/{chunk-QYOB7RVA.js → chunk-DKZJJ2NQ.js} +3 -2
- package/{chunk-4YX7VQOC.js → chunk-E2FC5RMU.js} +17 -14
- package/{chunk-EH4MNUMF.js → chunk-ETTDZBK5.js} +4 -4
- package/{chunk-ZWQUWF6W.js → chunk-G7Y4GXTY.js} +8 -14
- package/{chunk-5KTQVMCX.js → chunk-GOO6G4PY.js} +85 -0
- package/{chunk-FMOZ57LN.js → chunk-H7HWWNJB.js} +1 -1
- package/{chunk-SW5AAI5D.js → chunk-HKMPGHFZ.js} +5 -5
- package/{chunk-H44LQSZ2.js → chunk-HKWGI3TM.js} +178 -311
- package/{chunk-BBGYSMUE.js → chunk-JH7KMNGT.js} +143 -19
- package/{chunk-YXMZHGNA.js → chunk-KDUYNEJ5.js} +33 -16
- package/{chunk-FEKMTBKJ.js → chunk-LAYFVGS4.js} +192 -55
- package/{chunk-O5V7QQAF.js → chunk-LEX6DEH4.js} +114 -2
- package/{chunk-BTBT2566.js → chunk-MNUOMXJH.js} +412 -9
- package/{chunk-N7E3LQ4A.js → chunk-MZXWSY4E.js} +1 -1
- package/{chunk-ZQ3EAOY3.js → chunk-NTLJGRAT.js} +1 -1
- package/{chunk-BUXH3H5M.js → chunk-OIB4GARE.js} +3743 -4848
- package/{chunk-WFUIXNKC.js → chunk-P4YLK2OD.js} +3 -3
- package/chunk-PRJ473FK.js +63 -0
- package/{chunk-2SHLT6JB.js → chunk-Q7GNBUT4.js} +2 -2
- package/{chunk-C2UXCAMB.js → chunk-RIKSN62L.js} +3 -3
- package/{chunk-GTP6VNWH.js → chunk-RQ22OZD7.js} +3 -3
- package/{chunk-H7NIQGTU.js → chunk-RS66RJLA.js} +2 -2
- package/{chunk-GC64WGMD.js → chunk-SM3NSZJV.js} +16 -5
- package/{chunk-QKDMI22S.js → chunk-SSK4WNJA.js} +1 -1
- package/{chunk-6MAFLMAO.js → chunk-SUBNV2JH.js} +3 -3
- package/{chunk-HLAL63BZ.js → chunk-T43B7LB2.js} +1 -1
- package/{chunk-HTLIKE5U.js → chunk-TWVVTUNG.js} +2 -2
- package/{chunk-X3RWBJDQ.js → chunk-U7HTU2S7.js} +1 -1
- package/{chunk-76YUTLOT.js → chunk-UIOEHFF6.js} +1 -1
- package/{chunk-IIX6VWLW.js → chunk-VCFU3BO5.js} +224 -38
- package/{chunk-QU3TLYBR.js → chunk-VEUSD6OF.js} +35 -11
- package/{chunk-4YMD7B4Y.js → chunk-WPOKOKZA.js} +2 -2
- package/{chunk-A5VR65AE.js → chunk-WPQGLJHU.js} +4 -4
- package/{chunk-K6TZSON4.js → chunk-WTKYP6QO.js} +19 -5
- package/{chunk-ZSO5B6SW.js → chunk-Y2WUYX4I.js} +9 -0
- package/{chunk-A3SXTJDE.js → chunk-YAGFPXOX.js} +14 -14
- package/{chunk-TVGX5QIN.js → chunk-YUA6OAH5.js} +2 -2
- package/{chunk-NYE2INIO.js → chunk-YV2RSLM4.js} +13 -13
- package/{chunk-MJWUBTK7.js → chunk-YZGNKHUM.js} +2 -2
- package/{commandRegistry-YFXWA5SF.js → commandRegistry-ZU3RX7A2.js} +87 -67
- package/{contentThunks-2BV7CFUP.js → contentThunks-I4IHSDTM.js} +14 -13
- package/{cooldownCommands-KRILPXOZ.js → cooldownCommands-5SJ74DNP.js} +1 -1
- package/{createAgentAutomationAction-T6CGXCSO.js → createAgentAutomationAction-WQCH5HR2.js} +14 -13
- package/{createDialogAction-X27IA3G2.js → createDialogAction-CKMZK5JQ.js} +15 -14
- package/{createPageAction-EHDHNW5P.js → createPageAction-QAZHQGY7.js} +14 -13
- package/{dialogCommands-XZXH3HSQ.js → dialogCommands-NEQ6NW5H.js} +30 -28
- package/{dialogSlice-AZNPVOCU.js → dialogSlice-GEGACCH2.js} +13 -12
- package/{docCreateCommands-Z64V5BFZ.js → docCreateCommands-EXV267FP.js} +28 -26
- package/{docDeleteCommands-7UFHIM4C.js → docDeleteCommands-TSBILA2Z.js} +29 -27
- package/{docReadCommands-NLU7Y67R.js → docReadCommands-AKVYHITD.js} +28 -26
- package/{docStore-M37Q6JFO.js → docStore-B4EFT53J.js} +1 -1
- package/{docUpdateCommands-S2KGBEG3.js → docUpdateCommands-G6GULDGZ.js} +28 -26
- package/{fetchMessages-HWBVATSE.js → fetchMessages-YY4SATNR.js} +1 -1
- package/{getPricing-E2PLNWCR.js → getPricing-3PQY3TGI.js} +3 -3
- package/{handleSendMessageAction-KUJQZ6B6.js → handleSendMessageAction-4BACQWOG.js} +70 -29
- package/index.js +7 -7
- package/{lib-4YTWAGY7.js → lib-5KKIBFIT.js} +439 -272
- package/{localDialogRead-CT5HGDMC.js → localDialogRead-FUXGZ57B.js} +1 -1
- package/{localRuntimeAdapter-5BNHO6JZ.js → localRuntimeAdapter-MTDULOUZ.js} +45 -43
- package/{machineCommands-2KDROAVV.js → machineCommands-OGHHBRV3.js} +48 -46
- package/{machineWsRunDispatch-4NP5M574.js → machineWsRunDispatch-R6DNC3H7.js} +46 -44
- package/{models-UUNO6DOL.js → models-PJBE6JDV.js} +2 -2
- package/{oauthTokenStore-PADKLNOC.js → oauthTokenStore-OEERZFUC.js} +2 -1
- package/package.json +1 -1
- package/{providerPresetApply-JGNMO2KX.js → providerPresetApply-HBBUUVJD.js} +6 -6
- package/{providerRegistry-33J3ZYFJ.js → providerRegistry-5LK2NXYE.js} +6 -6
- package/{readlineWorkspace-MKUSR6HA.js → readlineWorkspace-NC2O4DQP.js} +290 -121
- package/{runAgentClientLoop-J32KRVN7.js → runAgentClientLoop-QKV66PX5.js} +31 -30
- package/{runtimeDoctorCommands-NYBOTA6D.js → runtimeDoctorCommands-3VFVTGPI.js} +8 -7
- package/{secretCommands-N6CMCJDZ.js → secretCommands-MKU25CDP.js} +311 -3
- package/{settingThunks-YRYNPWJM.js → settingThunks-4WU7YE62.js} +2 -2
- package/{skillDiscovery-F3TMVQOJ.js → skillDiscovery-BKLWW2EZ.js} +2 -2
- package/{spaceCommands-VV4K7TGI.js → spaceCommands-J7BRTTM3.js} +27 -25
- package/{streamAgentChatTurn-S2Q7STXS.js → streamAgentChatTurn-GM3UNSLS.js} +46 -43
- package/{tools-KOIPW4ZA.js → tools-UJLEQBKI.js} +25 -24
- package/{tuiSummaryLlmCaller-FSOADMXK.js → tuiSummaryLlmCaller-73QO3HAD.js} +12 -12
- package/{updateCommands-KE6LP3QX.js → updateCommands-RVDAFHBT.js} +3 -3
- package/{updateDialogTitleAction-ILS5OIXF.js → updateDialogTitleAction-24QO27NT.js} +14 -13
- 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-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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,
|