nolo-cli 0.54.0 → 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.
- package/README.md +3 -3
- package/{_executeModel-OPTKYHJA.js → _executeModel-CKT6RGTL.js} +48 -45
- package/{action-ORXWW2ZG.js → action-76JX3JX3.js} +7 -6
- package/{addContentAction-53BZ34AE.js → addContentAction-V3NAZRTJ.js} +6 -5
- package/{addDialogAgentAction-JRYUS54Y.js → addDialogAgentAction-RZOAF46K.js} +5 -4
- package/{agentDeleteCommand-FJIWU2BS.js → agentDeleteCommand-VN7NPXQ4.js} +30 -27
- package/{agentEmailCommands-CE32L43B.js → agentEmailCommands-F2TNAV4A.js} +59 -56
- package/{agentGrantCommands-2LEZDADN.js → agentGrantCommands-R3VQEZJR.js} +1 -1
- package/{agentListCommands-VJNKULIK.js → agentListCommands-OSM2ANI3.js} +61 -31
- package/{agentMachineCommands-HCJ3WQXL.js → agentMachineCommands-MTPWYVRV.js} +31 -28
- package/{agentPullCommand-M552CYSI.js → agentPullCommand-N7L2CT7L.js} +2 -2
- package/{agentRecordCommands-QFWERED4.js → agentRecordCommands-VWAWTVVC.js} +57 -54
- package/{agentRunCommand-G3GQMUNN.js → agentRunCommand-PLZOBNVK.js} +61 -58
- package/{agentRunControl-INKFDXDA.js → agentRunControl-WECMOO6O.js} +11 -6
- package/{agentRuntimeLocal-K327ELSL.js → agentRuntimeLocal-XCJLRWQE.js} +26 -23
- package/{agentSlice-ODKF4J6M.js → agentSlice-F6DOP4IW.js} +8 -7
- package/{appDeleteCommands-XUXMFDI4.js → appDeleteCommands-3BCFTRFJ.js} +30 -27
- package/{appDeployCommands-37F4GPCU.js → appDeployCommands-B4GMHCYA.js} +30 -27
- package/{appDeployStatusCommands-WSPU7TUK.js → appDeployStatusCommands-4MN36WIG.js} +30 -27
- package/{appGetCommands-YLOBA3EM.js → appGetCommands-4GJIEUAX.js} +30 -27
- package/{appListCommands-UD62R5ME.js → appListCommands-CHU53GSX.js} +30 -27
- package/{authCommand-OK6HLHGS.js → authCommand-WOTWLJNF.js} +35 -29
- package/{authCommands-2DUIUEMT.js → authCommands-ILTBI6JV.js} +7 -5
- package/{chatQueueReduxAdapter-TV2TUOQS.js → chatQueueReduxAdapter-HNSQXNIR.js} +20 -18
- package/{chunk-HPW5MNDQ.js → chunk-22BTGNSP.js} +113 -57
- package/{chunk-TR4DXUYX.js → chunk-2HPRMEEZ.js} +1180 -736
- package/{chunk-UNZDCI3O.js → chunk-2KDR4CWE.js} +35 -4
- package/{chunk-3ZTR7ZO4.js → chunk-2PGGC63K.js} +1 -1
- package/{chunk-JXIP6ZWH.js → chunk-37QVS7BU.js} +18 -5
- package/{chunk-EA5OYZVD.js → chunk-37XDGCY7.js} +1 -1
- package/chunk-3BLB7QKO.js +433 -0
- package/{chunk-CS6TCJ7E.js → chunk-3JQ2NRYU.js} +30 -7
- package/{chunk-RHMDMTDK.js → chunk-3JWKQDA4.js} +2 -2
- package/{chunk-3LKZRP7E.js → chunk-3QGUVVX5.js} +2 -2
- package/{chunk-SSXTSPSG.js → chunk-45YO6H7P.js} +71 -30
- package/{chunk-EJE33XNR.js → chunk-4C4ST2YE.js} +1521 -565
- package/{chunk-YLCUU3WM.js → chunk-4NJEIGBQ.js} +5 -5
- package/{chunk-K4NISKOR.js → chunk-5ZYA4JJ3.js} +47 -17
- package/{chunk-3Y2K5O2R.js → chunk-7A3RRUCQ.js} +125 -40
- package/{chunk-5FCIPEKT.js → chunk-7O7KH4X5.js} +1051 -926
- package/{chunk-6HDYSFLO.js → chunk-7UF7CQ6B.js} +3 -3
- package/{chunk-SUEIAK5N.js → chunk-AQMVUA7N.js} +1 -0
- package/{chunk-WQHGJHAL.js → chunk-AVE2YR4F.js} +732 -726
- package/{chunk-6COJEAYH.js → chunk-B7DXRX7F.js} +44 -37
- package/chunk-BFU6C242.js +66 -0
- package/{chunk-IA3A5373.js → chunk-C3FZR5EC.js} +1 -1
- package/{chunk-IWUMSAQF.js → chunk-CJCJF5XB.js} +26 -3
- package/{chunk-UGBHDMHI.js → chunk-CP7VIDZ7.js} +1 -1
- package/{chunk-JON2PHYT.js → chunk-CTCW7U7N.js} +1 -1
- package/{chunk-YBFJQC2M.js → chunk-D5XKNNUV.js} +65 -42
- package/{chunk-7NYDJAQ7.js → chunk-DNNSCSA2.js} +5 -5
- package/{chunk-NI2BS6UD.js → chunk-DWUCB2A3.js} +1 -1
- package/{chunk-AA564GBL.js → chunk-DZZL7UBV.js} +1 -1
- package/{chunk-75MSWWUE.js → chunk-E6RGHPDR.js} +5 -3
- package/chunk-EDKF7RX4.js +30 -0
- package/{chunk-FJHMLRDQ.js → chunk-ES6CVKVD.js} +21 -27
- package/{chunk-SYYUU7EV.js → chunk-FHAGENAS.js} +2 -3
- package/{chunk-NJUQBYFJ.js → chunk-FKFMIBTT.js} +3 -1
- package/{chunk-INZZJSQF.js → chunk-FZGV4FGK.js} +24 -12
- package/{chunk-YQBXOHE6.js → chunk-GAL47RNP.js} +1 -1
- package/{chunk-UOWXD4VN.js → chunk-HBPV76EK.js} +335 -243
- package/{chunk-MLEZPE3U.js → chunk-HLU5Q2GV.js} +4 -4
- package/{chunk-TC6P4NDR.js → chunk-HQP7HJDL.js} +6 -6
- package/{chunk-7FAS3NEF.js → chunk-IYCUMIYS.js} +19 -15
- package/{chunk-AUVFJGPC.js → chunk-JX5PJCWS.js} +7 -5
- package/{chunk-LYGNQHUW.js → chunk-JYYZCK2Z.js} +2 -4
- package/{chunk-XOJRZUPF.js → chunk-KWSQR2KK.js} +14 -29
- package/{chunk-2WBFJHQA.js → chunk-L7B47JXR.js} +34 -39
- package/{chunk-EICIFHVS.js → chunk-LAFC3B2I.js} +1 -1
- package/{chunk-N4JKMCY3.js → chunk-LJKICKVC.js} +2 -2
- package/chunk-M3JEW6N6.js +193 -0
- package/{chunk-LRGKOI5Y.js → chunk-MBOEV4L2.js} +7 -3
- package/{chunk-SVDMVX4G.js → chunk-MMZ6ZTVO.js} +112 -73
- package/{chunk-JDSUTNYY.js → chunk-MP64VFGD.js} +2 -2
- package/{chunk-NFLA6GSU.js → chunk-MXUDQZXQ.js} +44 -5
- package/chunk-N4G4PKQ6.js +23 -0
- package/{chunk-KXKQO4Q6.js → chunk-NTW5GWDM.js} +58 -1
- package/chunk-ONXOABJR.js +215 -0
- package/{chunk-TY3ADTX5.js → chunk-OZX2IPKM.js} +7 -2
- package/{chunk-Q4XZVZPN.js → chunk-P7OOB7QP.js} +1 -1
- package/{chunk-XIJZOCSP.js → chunk-PEZJEQAO.js} +1 -1
- package/{chunk-SWJGJMTW.js → chunk-PQDIDWGX.js} +1 -1
- package/chunk-PSCNXBYA.js +11 -0
- package/{chunk-BY2FF2C4.js → chunk-QEFJJS2I.js} +55 -73
- package/{chunk-BG7J6Y5X.js → chunk-QEW2MFDQ.js} +1 -1
- package/{chunk-KLIBF3BY.js → chunk-RDBARW6T.js} +8 -3
- package/{chunk-ZVOHVJI3.js → chunk-RJ2SAFB5.js} +82 -35
- package/{chunk-MYMBBB6Q.js → chunk-RVWRKFUB.js} +5 -3
- package/{chunk-43CXXVJD.js → chunk-RXX4GDIH.js} +1 -1
- package/chunk-SEJ5OS6F.js +49 -0
- package/{chunk-SAJSBPI2.js → chunk-SOJM57FX.js} +5 -2
- package/{chunk-EKLRRZIN.js → chunk-SPAQ4PVV.js} +0 -5
- package/{chunk-L7NG2M6H.js → chunk-TRV2MIDW.js} +89 -74
- package/{chunk-5UAYZEXO.js → chunk-UZPQSVM6.js} +1 -1
- package/{chunk-SVC3GGUA.js → chunk-VMWYBIXG.js} +7 -5
- package/{chunk-ZHXJ6M7T.js → chunk-W7XHHYWM.js} +4 -0
- package/{chunk-UR66XPVF.js → chunk-XAVSS3KE.js} +21 -3
- package/{chunk-A65UV3M5.js → chunk-XOKOSO35.js} +10 -19
- package/{chunk-VZMUOPYG.js → chunk-XTJTN3RW.js} +46 -3
- package/{chunk-T5HJEUQN.js → chunk-YCDWJX45.js} +1 -1
- package/{chunk-BBTN4NQD.js → chunk-Z4QSJILV.js} +85 -13
- package/{chunk-O5FLGN2L.js → chunk-ZRSJ3JEH.js} +6 -2
- package/{cliExecutor-BBUVQU4L.js → cliExecutor-HG3S345O.js} +1 -1
- package/{codingSkills-BCQXRZOI.js → codingSkills-VDXQYWX4.js} +2 -2
- package/{contentThunks-KNI6VXLT.js → contentThunks-7YG2ZYQC.js} +21 -19
- package/{cooldownCommands-GI5NNWGL.js → cooldownCommands-BSCH2W7P.js} +2 -2
- package/{createAgentAutomationAction-OK4L33KF.js → createAgentAutomationAction-PJQSCAIO.js} +23 -21
- package/{createDialogAction-JDSMY4AY.js → createDialogAction-SFEJX6SP.js} +23 -21
- package/{createPageAction-T7RA3HCG.js → createPageAction-B7WRHOQO.js} +24 -22
- package/{dbSlice-TVX6SN2T.js → dbSlice-IBVOBVMS.js} +5 -4
- package/{deleteFile-JYKRT7C3.js → deleteFile-FWP2PSBG.js} +3 -2
- package/{dialogCommands-UQZYWOOV.js → dialogCommands-VL2X22QC.js} +30 -27
- package/{dialogSlice-TYW2G7IL.js → dialogSlice-ANMACABO.js} +20 -18
- package/{docCreateCommands-OA6HZBWO.js → docCreateCommands-ITLGZ5YI.js} +29 -26
- package/{docDeleteCommands-KBB3YQI2.js → docDeleteCommands-LH3YNL4C.js} +30 -27
- package/{docReadCommands-ZLMFVC67.js → docReadCommands-YAJ77F36.js} +29 -26
- package/{docStore-2URPBVCS.js → docStore-D4HGHPWI.js} +6 -5
- package/{docUpdateCommands-HMH5KUON.js → docUpdateCommands-DQBOMH2G.js} +29 -26
- package/{getPricing-RFOPUWHY.js → getPricing-NM3NUTAS.js} +4 -4
- package/handleSendMessageAction-DF2OABGW.js +675 -0
- package/index.js +79 -88
- package/{lib-2ZTNRXR4.js → lib-FRRS27KN.js} +63 -28
- package/{localRuntimeAuthority-KQDAE64E.js → localRuntimeAuthority-R5UBODT3.js} +6 -4
- package/{localRuntimeDb-PF7CFKDL.js → localRuntimeDb-P37ZTX55.js} +1 -1
- package/{machineCommands-RK6L7ZWL.js → machineCommands-JXDYQ5LB.js} +296 -79
- package/{machineWsRunDispatch-3X64DW2Z.js → machineWsRunDispatch-3QHI7JX5.js} +55 -52
- package/{memberThunks-THZYZFSN.js → memberThunks-VZI6G7YZ.js} +10 -8
- package/{models-JVKUEER5.js → models-FAMINFZ7.js} +2 -2
- package/package.json +3 -2
- package/{read-K4JU4MQC.js → read-2BYWW7AA.js} +3 -2
- package/{readDocTool-LQGR6FUN.js → readDocTool-LC3A7QTB.js} +1 -1
- package/{readlineWorkspace-XUFJV3RS.js → readlineWorkspace-KVZTEAHB.js} +4365 -2795
- package/{removeDialogAgentAction-ECHCFB7N.js → removeDialogAgentAction-SFYZXHNK.js} +8 -7
- package/{runAgentClientLoop-24GQ2AW6.js → runAgentClientLoop-KGTEL7ZP.js} +49 -45
- package/{runtimeDoctorCommands-JKTTN723.js → runtimeDoctorCommands-CROTMULY.js} +7 -5
- package/{setDialogExtraReferencesAction-KCVJNGMB.js → setDialogExtraReferencesAction-Q32RGFTA.js} +6 -5
- package/{setPrimaryDialogAgentAction-VDOBOMKC.js → setPrimaryDialogAgentAction-BFYJHUJS.js} +8 -7
- package/{settingSlice-VR2IJSXC.js → settingSlice-IRUU4VFB.js} +6 -5
- package/{skillDiscovery-2QTZINON.js → skillDiscovery-NTRLM6KP.js} +1 -1
- package/{spaceCommands-S5YJJXL7.js → spaceCommands-KNAYWMCZ.js} +33 -215
- package/{streamAgentChatTurn-QHKP3ABO.js → streamAgentChatTurn-FLYPTXKZ.js} +105 -73
- package/{switchDialogAgentAction-5L4UP7VI.js → switchDialogAgentAction-L2KOKCGG.js} +5 -4
- package/{tableCommands-R6WFRDYF.js → tableCommands-SUNTHAYX.js} +1 -1
- package/{toolApiClient-53U4UDFF.js → toolApiClient-VGYUB4P5.js} +2 -1
- package/{tools-SSXSTC3O.js → tools-CVLUXK6P.js} +37 -34
- package/{tuiSummaryLlmCaller-URFJHFC5.js → tuiSummaryLlmCaller-F3DPFFZM.js} +15 -13
- package/{updateCommands-IYKLF3JX.js → updateCommands-AJYSD73Y.js} +2 -2
- package/{updateDialogTitleAction-YFYAEW3T.js → updateDialogTitleAction-HWJIZEIV.js} +23 -21
- package/agentSuperviseCommands-5AR3DKNN.js +0 -640
- package/chunk-6IGD47IC.js +0 -19
- package/chunk-FD36SCCD.js +0 -105
- package/chunk-GRFK2XP4.js +0 -230
- package/chunk-HJTAGT3W.js +0 -370
- package/handleSendMessageAction-GO53TY7U.js +0 -409
package/chunk-FD36SCCD.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
// packages/agent-runtime/oauthTokenStore.ts
|
|
2
|
-
import {
|
|
3
|
-
chmodSync,
|
|
4
|
-
existsSync,
|
|
5
|
-
mkdirSync,
|
|
6
|
-
readFileSync,
|
|
7
|
-
unlinkSync,
|
|
8
|
-
writeFileSync
|
|
9
|
-
} from "node:fs";
|
|
10
|
-
import { join as join2 } from "node:path";
|
|
11
|
-
|
|
12
|
-
// packages/agent-runtime/noloStateDir.ts
|
|
13
|
-
import { homedir } from "node:os";
|
|
14
|
-
import { join } from "node:path";
|
|
15
|
-
function resolveNoloStateDir(name, homeDir) {
|
|
16
|
-
if (homeDir) return join(homeDir, ".nolo", name);
|
|
17
|
-
const noloHome = process.env.NOLO_HOME?.trim();
|
|
18
|
-
return noloHome ? join(noloHome, name) : join(homedir(), ".nolo", name);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// packages/agent-runtime/oauthTokenStore.ts
|
|
22
|
-
var DEFAULT_REFRESH_SKEW_MS = 5 * 60 * 1e3;
|
|
23
|
-
function getCredentialsDir(homeDir) {
|
|
24
|
-
return resolveNoloStateDir("credentials", homeDir);
|
|
25
|
-
}
|
|
26
|
-
function getCredentialPath(provider, homeDir) {
|
|
27
|
-
return join2(getCredentialsDir(homeDir), `${provider}.json`);
|
|
28
|
-
}
|
|
29
|
-
function ensurePrivateDir(dir) {
|
|
30
|
-
mkdirSync(dir, { recursive: true, mode: 448 });
|
|
31
|
-
try {
|
|
32
|
-
chmodSync(dir, 448);
|
|
33
|
-
} catch {
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
function writePrivateFile(path, body) {
|
|
37
|
-
writeFileSync(path, body, { encoding: "utf8", mode: 384 });
|
|
38
|
-
try {
|
|
39
|
-
chmodSync(path, 384);
|
|
40
|
-
} catch {
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
function readOAuthCredential(provider, homeDir) {
|
|
44
|
-
const path = getCredentialPath(provider, homeDir);
|
|
45
|
-
if (!existsSync(path)) return null;
|
|
46
|
-
const raw = readFileSync(path, "utf8");
|
|
47
|
-
try {
|
|
48
|
-
const parsed = JSON.parse(raw);
|
|
49
|
-
if (!parsed?.provider || !parsed?.accessToken) return null;
|
|
50
|
-
return parsed;
|
|
51
|
-
} catch {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
function writeOAuthCredential(provider, credential, homeDir) {
|
|
56
|
-
const path = getCredentialPath(provider, homeDir);
|
|
57
|
-
ensurePrivateDir(getCredentialsDir(homeDir));
|
|
58
|
-
writePrivateFile(path, `${JSON.stringify(credential, null, 2)}
|
|
59
|
-
`);
|
|
60
|
-
}
|
|
61
|
-
function removeOAuthCredential(provider, homeDir) {
|
|
62
|
-
const path = getCredentialPath(provider, homeDir);
|
|
63
|
-
if (!existsSync(path)) return;
|
|
64
|
-
unlinkSync(path);
|
|
65
|
-
}
|
|
66
|
-
function createOAuthTokenStore(homeDir) {
|
|
67
|
-
return {
|
|
68
|
-
read(provider) {
|
|
69
|
-
return readOAuthCredential(provider, homeDir);
|
|
70
|
-
},
|
|
71
|
-
write(provider, credential) {
|
|
72
|
-
writeOAuthCredential(provider, credential, homeDir);
|
|
73
|
-
},
|
|
74
|
-
remove(provider) {
|
|
75
|
-
removeOAuthCredential(provider, homeDir);
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
function isTokenExpired(credential, skewMs = DEFAULT_REFRESH_SKEW_MS, now = Date.now()) {
|
|
80
|
-
if (!credential.expiresAt) return false;
|
|
81
|
-
return credential.expiresAt - now <= skewMs;
|
|
82
|
-
}
|
|
83
|
-
async function resolveFreshAccessToken(args) {
|
|
84
|
-
const store = args.store ?? createOAuthTokenStore(args.homeDir);
|
|
85
|
-
const now = args.now ?? Date.now;
|
|
86
|
-
const credential = store.read(args.provider);
|
|
87
|
-
if (!credential) return null;
|
|
88
|
-
if (!args.force && !isTokenExpired(credential, args.skewMs ?? DEFAULT_REFRESH_SKEW_MS, now())) {
|
|
89
|
-
return credential.accessToken;
|
|
90
|
-
}
|
|
91
|
-
if (!credential.refreshToken || !args.refresh) return null;
|
|
92
|
-
const refreshed = await args.refresh(credential);
|
|
93
|
-
store.write(args.provider, refreshed);
|
|
94
|
-
return refreshed.accessToken;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export {
|
|
98
|
-
resolveNoloStateDir,
|
|
99
|
-
getCredentialsDir,
|
|
100
|
-
readOAuthCredential,
|
|
101
|
-
writeOAuthCredential,
|
|
102
|
-
createOAuthTokenStore,
|
|
103
|
-
isTokenExpired,
|
|
104
|
-
resolveFreshAccessToken
|
|
105
|
-
};
|
package/chunk-GRFK2XP4.js
DELETED
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isOAuthApiKeyRef
|
|
3
|
-
} from "./chunk-YYLHWIW6.js";
|
|
4
|
-
import {
|
|
5
|
-
compareAgentSelection
|
|
6
|
-
} from "./chunk-ZVOHVJI3.js";
|
|
7
|
-
import {
|
|
8
|
-
getModelAbility
|
|
9
|
-
} from "./chunk-NJUQBYFJ.js";
|
|
10
|
-
import {
|
|
11
|
-
isOwnedAgentKey,
|
|
12
|
-
ownedAgentKey,
|
|
13
|
-
publicAgentKey
|
|
14
|
-
} from "./chunk-BJIRLHJR.js";
|
|
15
|
-
|
|
16
|
-
// packages/ai/agent/safeAgentSummary.ts
|
|
17
|
-
function parseTimestamp(val) {
|
|
18
|
-
if (typeof val === "number" && Number.isFinite(val)) return val;
|
|
19
|
-
if (typeof val === "string") return Date.parse(val) || 0;
|
|
20
|
-
return 0;
|
|
21
|
-
}
|
|
22
|
-
function safeTimestamp(val) {
|
|
23
|
-
if (typeof val === "number" && Number.isFinite(val)) return val;
|
|
24
|
-
if (typeof val === "string") return val;
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
function parseAgentRecordId(privateKey, explicitId) {
|
|
28
|
-
if (explicitId && typeof explicitId === "string" && explicitId.trim()) {
|
|
29
|
-
return explicitId.trim();
|
|
30
|
-
}
|
|
31
|
-
if (privateKey && typeof privateKey === "string") {
|
|
32
|
-
const match = privateKey.match(/^agent-[^-]+-(.+)$/i);
|
|
33
|
-
if (match?.[1]) return match[1];
|
|
34
|
-
}
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
function resolveFavoriteStatus(record, options) {
|
|
38
|
-
if (options?.isFavorite !== void 0) {
|
|
39
|
-
return {
|
|
40
|
-
isFavorite: !!options.isFavorite,
|
|
41
|
-
favoritedAt: safeTimestamp(options.favoritedAt)
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
if (record?.isFavorite === true) {
|
|
45
|
-
return {
|
|
46
|
-
isFavorite: true,
|
|
47
|
-
favoritedAt: safeTimestamp(record?.favoritedAt)
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
const favoritesMap = options?.favoritesMap;
|
|
51
|
-
if (!favoritesMap) {
|
|
52
|
-
return { isFavorite: false, favoritedAt: null };
|
|
53
|
-
}
|
|
54
|
-
const candidateKeys = [];
|
|
55
|
-
if (typeof record?.dbKey === "string" && record.dbKey) candidateKeys.push(record.dbKey);
|
|
56
|
-
if (typeof record?.privateKey === "string" && record.privateKey) candidateKeys.push(record.privateKey);
|
|
57
|
-
if (typeof record?.publicKey === "string" && record.publicKey) candidateKeys.push(record.publicKey);
|
|
58
|
-
if (typeof record?.id === "string" && record.id) {
|
|
59
|
-
candidateKeys.push(record.id);
|
|
60
|
-
candidateKeys.push(publicAgentKey(record.id));
|
|
61
|
-
if (options?.userId) {
|
|
62
|
-
candidateKeys.push(ownedAgentKey(options.userId, record.id));
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
let matched = false;
|
|
66
|
-
let highestFavAt = null;
|
|
67
|
-
let highestFavTime = -1;
|
|
68
|
-
for (const key of candidateKeys) {
|
|
69
|
-
const val = favoritesMap instanceof Map ? favoritesMap.get(key) : favoritesMap[key];
|
|
70
|
-
if (val !== void 0 && val !== false && val !== null) {
|
|
71
|
-
const favAt = val === true ? 1 : safeTimestamp(val);
|
|
72
|
-
if (favAt === null) continue;
|
|
73
|
-
matched = true;
|
|
74
|
-
const time = parseTimestamp(favAt);
|
|
75
|
-
if (time > highestFavTime) {
|
|
76
|
-
highestFavTime = time;
|
|
77
|
-
highestFavAt = favAt;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
if (matched) {
|
|
82
|
-
return {
|
|
83
|
-
isFavorite: true,
|
|
84
|
-
favoritedAt: highestFavAt ?? 1
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
return { isFavorite: false, favoritedAt: null };
|
|
88
|
-
}
|
|
89
|
-
function toSafeAgentSummary(record, options) {
|
|
90
|
-
const rawId = parseAgentRecordId(
|
|
91
|
-
typeof record?.privateKey === "string" ? record.privateKey : record?.dbKey,
|
|
92
|
-
typeof record?.id === "string" ? record.id : void 0
|
|
93
|
-
);
|
|
94
|
-
const id = rawId ?? (typeof record?.id === "string" ? record.id : null);
|
|
95
|
-
const publicRecordDenied = record?.publicRecordExists === false || options?.publicRecordExists === false;
|
|
96
|
-
const publicRecordConfirmed = record?.publicRecordExists === true || options?.publicRecordExists === true;
|
|
97
|
-
let publicKey;
|
|
98
|
-
if (typeof record?.publicKey === "string" && record.publicKey && !publicRecordDenied) {
|
|
99
|
-
publicKey = record.publicKey;
|
|
100
|
-
} else if (publicRecordConfirmed && id) {
|
|
101
|
-
publicKey = publicAgentKey(id);
|
|
102
|
-
}
|
|
103
|
-
const name = typeof record?.name === "string" && record.name ? record.name : "(unnamed)";
|
|
104
|
-
const handle = typeof record?.handle === "string" && record.handle ? record.handle : null;
|
|
105
|
-
const introduction = typeof record?.introduction === "string" && record.introduction ? record.introduction : typeof record?.description === "string" && record.description ? record.description : null;
|
|
106
|
-
const model = typeof record?.model === "string" && record.model ? record.model : null;
|
|
107
|
-
const provider = typeof record?.provider === "string" && record.provider ? record.provider : typeof record?.apiSource === "string" && record.apiSource ? record.apiSource : null;
|
|
108
|
-
const apiSource = typeof record?.apiSource === "string" && record.apiSource ? record.apiSource : null;
|
|
109
|
-
const cliProvider = typeof record?.cliProvider === "string" && record.cliProvider ? record.cliProvider : null;
|
|
110
|
-
const tools = Array.isArray(record?.tools) ? record.tools.filter((t) => typeof t === "string") : [];
|
|
111
|
-
const inputPrice = typeof record?.inputPrice === "number" && Number.isFinite(record.inputPrice) ? record.inputPrice : null;
|
|
112
|
-
const outputPrice = typeof record?.outputPrice === "number" && Number.isFinite(record.outputPrice) ? record.outputPrice : null;
|
|
113
|
-
const modelAbility = model ? getModelAbility(model) ?? null : null;
|
|
114
|
-
const favStatus = resolveFavoriteStatus(record, options);
|
|
115
|
-
const isPublic = record?.isPublic === true || record?.isPublicFlag === true || record?.publicRecordExists === true;
|
|
116
|
-
const updatedAt = safeTimestamp(record?.updatedAt ?? record?.createdAt ?? record?.created);
|
|
117
|
-
const nextAvailableAt = typeof record?.nextAvailableAt === "number" && Number.isFinite(record.nextAvailableAt) ? record.nextAvailableAt : void 0;
|
|
118
|
-
const currentUserId = options?.userId;
|
|
119
|
-
const isOwnedByRecord = Boolean(currentUserId) && (typeof record?.userId === "string" && record.userId === currentUserId || typeof record?.ownerId === "string" && record.ownerId === currentUserId);
|
|
120
|
-
const ownedKey = currentUserId ? [record?.dbKey, record?.privateKey].find(
|
|
121
|
-
(key) => isOwnedAgentKey(key, currentUserId)
|
|
122
|
-
) : void 0;
|
|
123
|
-
const isOwned = isOwnedByRecord || Boolean(ownedKey);
|
|
124
|
-
const isOAuth = isOAuthApiKeyRef(record?.apiKeyRef);
|
|
125
|
-
let agentKey;
|
|
126
|
-
if (currentUserId) {
|
|
127
|
-
if (isOwned) {
|
|
128
|
-
agentKey = ownedKey ?? (id ? ownedAgentKey(currentUserId, id) : void 0);
|
|
129
|
-
} else if (publicKey) {
|
|
130
|
-
agentKey = publicKey;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return {
|
|
134
|
-
id,
|
|
135
|
-
...agentKey !== void 0 ? { agentKey } : {},
|
|
136
|
-
...publicKey !== void 0 ? { publicKey } : {},
|
|
137
|
-
name,
|
|
138
|
-
handle,
|
|
139
|
-
introduction,
|
|
140
|
-
model,
|
|
141
|
-
provider,
|
|
142
|
-
apiSource,
|
|
143
|
-
cliProvider,
|
|
144
|
-
tools,
|
|
145
|
-
inputPrice,
|
|
146
|
-
outputPrice,
|
|
147
|
-
modelAbility,
|
|
148
|
-
isFavorite: favStatus.isFavorite,
|
|
149
|
-
favoritedAt: favStatus.favoritedAt,
|
|
150
|
-
isPublic,
|
|
151
|
-
isOwned,
|
|
152
|
-
isOAuth,
|
|
153
|
-
...nextAvailableAt !== void 0 ? { nextAvailableAt } : {},
|
|
154
|
-
updatedAt
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
function sortSafeAgentSummaries(agents) {
|
|
158
|
-
return [...agents].sort(compareAgentSelection);
|
|
159
|
-
}
|
|
160
|
-
var COMPACT_AGENT_SUMMARY_FIELDS = [
|
|
161
|
-
"agentKey",
|
|
162
|
-
"name",
|
|
163
|
-
"model",
|
|
164
|
-
"provider",
|
|
165
|
-
"apiSource",
|
|
166
|
-
"isFavorite",
|
|
167
|
-
"isOAuth",
|
|
168
|
-
"isOwned",
|
|
169
|
-
"isPublic",
|
|
170
|
-
"tools",
|
|
171
|
-
// 仅限流中的 agent 才会带(可用 agent 上不存在)。对"现在能不能选它"是
|
|
172
|
-
// 决策信息(CLI --show-unavailable 场景);默认列表已把这类 agent 过滤掉,
|
|
173
|
-
// 所以通常根本不占字节。
|
|
174
|
-
"nextAvailableAt"
|
|
175
|
-
];
|
|
176
|
-
function omitNullishAgentSummaryFields(summary) {
|
|
177
|
-
const result = {};
|
|
178
|
-
for (const [key, value] of Object.entries(summary)) {
|
|
179
|
-
if (value !== null && value !== void 0) {
|
|
180
|
-
result[key] = value;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return result;
|
|
184
|
-
}
|
|
185
|
-
function toCompactAgentSummary(summary) {
|
|
186
|
-
const compact = {};
|
|
187
|
-
for (const field of COMPACT_AGENT_SUMMARY_FIELDS) {
|
|
188
|
-
const value = summary[field];
|
|
189
|
-
if (value !== null && value !== void 0) {
|
|
190
|
-
compact[field] = value;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return compact;
|
|
194
|
-
}
|
|
195
|
-
var UNAVAILABLE_AGENT_SUMMARY_FIELDS = [
|
|
196
|
-
"agentKey",
|
|
197
|
-
"name",
|
|
198
|
-
"model",
|
|
199
|
-
"provider",
|
|
200
|
-
"apiSource",
|
|
201
|
-
"isFavorite",
|
|
202
|
-
"isOAuth",
|
|
203
|
-
"isOwned",
|
|
204
|
-
"nextAvailableAt",
|
|
205
|
-
"favoritedAt",
|
|
206
|
-
"updatedAt"
|
|
207
|
-
];
|
|
208
|
-
function toUnavailableAgentSummary(summary) {
|
|
209
|
-
const item = {
|
|
210
|
-
name: summary.name,
|
|
211
|
-
isFavorite: summary.isFavorite,
|
|
212
|
-
isOAuth: summary.isOAuth,
|
|
213
|
-
isOwned: summary.isOwned
|
|
214
|
-
};
|
|
215
|
-
for (const field of UNAVAILABLE_AGENT_SUMMARY_FIELDS) {
|
|
216
|
-
const value = summary[field];
|
|
217
|
-
if (value !== null && value !== void 0) {
|
|
218
|
-
item[field] = value;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
return item;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
export {
|
|
225
|
-
toSafeAgentSummary,
|
|
226
|
-
sortSafeAgentSummaries,
|
|
227
|
-
omitNullishAgentSummaryFields,
|
|
228
|
-
toCompactAgentSummary,
|
|
229
|
-
toUnavailableAgentSummary
|
|
230
|
-
};
|
package/chunk-HJTAGT3W.js
DELETED
|
@@ -1,370 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
resolveRunLogPath,
|
|
3
|
-
resolveRunReportJsonPath,
|
|
4
|
-
resolveRunReportPath,
|
|
5
|
-
resolveRunsDir
|
|
6
|
-
} from "./chunk-SSXTSPSG.js";
|
|
7
|
-
|
|
8
|
-
// packages/cli/agentRunReport.ts
|
|
9
|
-
import { homedir as nodeHomedir } from "node:os";
|
|
10
|
-
import { join } from "node:path";
|
|
11
|
-
import * as nodeFs from "node:fs";
|
|
12
|
-
import {
|
|
13
|
-
execFileSync as nodeExecFileSync,
|
|
14
|
-
spawnSync as nodeSpawnSync
|
|
15
|
-
} from "node:child_process";
|
|
16
|
-
function formatDuration(startedAt, endedAt, now) {
|
|
17
|
-
const start = new Date(startedAt).getTime();
|
|
18
|
-
const end = endedAt ? new Date(endedAt).getTime() : (now ?? /* @__PURE__ */ new Date()).getTime();
|
|
19
|
-
if (isNaN(start)) return "-";
|
|
20
|
-
const elapsedMs = Math.max(0, (isNaN(end) ? Date.now() : end) - start);
|
|
21
|
-
const seconds = Math.floor(elapsedMs / 1e3) % 60;
|
|
22
|
-
const minutes = Math.floor(elapsedMs / 6e4) % 60;
|
|
23
|
-
const hours = Math.floor(elapsedMs / 36e5);
|
|
24
|
-
if (hours > 0) return `${hours}h ${minutes}m ${seconds}s`;
|
|
25
|
-
if (minutes > 0) return `${minutes}m ${seconds}s`;
|
|
26
|
-
return `${seconds}s`;
|
|
27
|
-
}
|
|
28
|
-
function extractTailLines(text, count) {
|
|
29
|
-
if (!text) return [];
|
|
30
|
-
const lines = String(text).split(/\r?\n/);
|
|
31
|
-
if (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
|
|
32
|
-
return lines.slice(Math.max(0, lines.length - count));
|
|
33
|
-
}
|
|
34
|
-
function formatCodeBlockCell(lines) {
|
|
35
|
-
if (lines.length === 0) return "-";
|
|
36
|
-
const escaped = lines.map((line) => line.replace(/\|/g, "\\|")).join("<br>");
|
|
37
|
-
return `<pre>${escaped}</pre>`;
|
|
38
|
-
}
|
|
39
|
-
function executeDoDCommand(cmd, cwd, deps = {}) {
|
|
40
|
-
const spawnSync = deps.spawnSync ?? nodeSpawnSync;
|
|
41
|
-
try {
|
|
42
|
-
const res = spawnSync(cmd, {
|
|
43
|
-
shell: true,
|
|
44
|
-
cwd: cwd || process.cwd(),
|
|
45
|
-
timeout: 12e4,
|
|
46
|
-
maxBuffer: 10 * 1024 * 1024,
|
|
47
|
-
encoding: "utf8"
|
|
48
|
-
});
|
|
49
|
-
if (res.error) {
|
|
50
|
-
const errCode = res.error.code;
|
|
51
|
-
if (errCode === "ETIMEDOUT" || res.signal === "SIGTERM" || res.signal === "SIGKILL") {
|
|
52
|
-
return {
|
|
53
|
-
command: cmd,
|
|
54
|
-
exitCode: "timeout",
|
|
55
|
-
stdoutTail: extractTailLines(res.stdout, 20),
|
|
56
|
-
stderrTail: extractTailLines(res.stderr || res.error.message, 10)
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
return {
|
|
60
|
-
command: cmd,
|
|
61
|
-
exitCode: "error",
|
|
62
|
-
stdoutTail: extractTailLines(res.stdout, 20),
|
|
63
|
-
stderrTail: extractTailLines(res.stderr || res.error.message, 10)
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
if (res.status === null && (res.signal === "SIGTERM" || res.signal === "SIGKILL")) {
|
|
67
|
-
return {
|
|
68
|
-
command: cmd,
|
|
69
|
-
exitCode: "timeout",
|
|
70
|
-
stdoutTail: extractTailLines(res.stdout, 20),
|
|
71
|
-
stderrTail: extractTailLines(res.stderr, 10)
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
const exitCode = typeof res.status === "number" ? res.status : "error";
|
|
75
|
-
return {
|
|
76
|
-
command: cmd,
|
|
77
|
-
exitCode,
|
|
78
|
-
stdoutTail: extractTailLines(res.stdout, 20),
|
|
79
|
-
stderrTail: extractTailLines(res.stderr, 10)
|
|
80
|
-
};
|
|
81
|
-
} catch (err) {
|
|
82
|
-
return {
|
|
83
|
-
command: cmd,
|
|
84
|
-
exitCode: "error",
|
|
85
|
-
stdoutTail: [],
|
|
86
|
-
stderrTail: extractTailLines(err instanceof Error ? err.message : String(err), 10)
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
function collectGitSummary(cwd, spawnHead, deps = {}) {
|
|
91
|
-
const targetCwd = cwd || process.cwd();
|
|
92
|
-
const execFile = deps.execFileSync ?? nodeExecFileSync;
|
|
93
|
-
try {
|
|
94
|
-
const isRepo = execFile("git", ["rev-parse", "--is-inside-work-tree"], {
|
|
95
|
-
cwd: targetCwd,
|
|
96
|
-
encoding: "utf8",
|
|
97
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
98
|
-
timeout: 5e3
|
|
99
|
-
}).trim();
|
|
100
|
-
if (isRepo !== "true") {
|
|
101
|
-
return { isGitRepo: false };
|
|
102
|
-
}
|
|
103
|
-
let modifiedCount = 0;
|
|
104
|
-
let untrackedCount = 0;
|
|
105
|
-
try {
|
|
106
|
-
const statusOut = execFile("git", ["status", "--porcelain"], {
|
|
107
|
-
cwd: targetCwd,
|
|
108
|
-
encoding: "utf8",
|
|
109
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
110
|
-
timeout: 1e4
|
|
111
|
-
});
|
|
112
|
-
const statusLines = statusOut.split(/\r?\n/).filter((l) => l.trim().length > 0);
|
|
113
|
-
for (const line of statusLines) {
|
|
114
|
-
if (line.startsWith("??")) {
|
|
115
|
-
untrackedCount += 1;
|
|
116
|
-
} else {
|
|
117
|
-
modifiedCount += 1;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
} catch (err) {
|
|
121
|
-
return {
|
|
122
|
-
isGitRepo: true,
|
|
123
|
-
error: `git status \u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
let commits;
|
|
127
|
-
if (spawnHead) {
|
|
128
|
-
try {
|
|
129
|
-
const logOut = execFile(
|
|
130
|
-
"git",
|
|
131
|
-
["log", `${spawnHead}..HEAD`, "--oneline", "-n", "20"],
|
|
132
|
-
{
|
|
133
|
-
cwd: targetCwd,
|
|
134
|
-
encoding: "utf8",
|
|
135
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
136
|
-
timeout: 1e4
|
|
137
|
-
}
|
|
138
|
-
);
|
|
139
|
-
commits = logOut.split(/\r?\n/).filter((l) => l.trim().length > 0).slice(0, 20);
|
|
140
|
-
} catch (logErr) {
|
|
141
|
-
commits = [`(git log \u5931\u8D25: ${logErr instanceof Error ? logErr.message : String(logErr)})`];
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
return {
|
|
145
|
-
isGitRepo: true,
|
|
146
|
-
modifiedCount,
|
|
147
|
-
untrackedCount,
|
|
148
|
-
spawnHead,
|
|
149
|
-
commits
|
|
150
|
-
};
|
|
151
|
-
} catch (err) {
|
|
152
|
-
return {
|
|
153
|
-
isGitRepo: false,
|
|
154
|
-
error: err instanceof Error ? err.message : String(err)
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
function parseDoDResultsFromMarkdown(markdown) {
|
|
159
|
-
const dodResults = [];
|
|
160
|
-
const lines = markdown.split(/\r?\n/);
|
|
161
|
-
let inDoDSection = false;
|
|
162
|
-
for (const line of lines) {
|
|
163
|
-
if (line.startsWith("## DoD \u9A8C\u6536\u7ED3\u679C")) {
|
|
164
|
-
inDoDSection = true;
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
if (inDoDSection && line.startsWith("## ")) {
|
|
168
|
-
inDoDSection = false;
|
|
169
|
-
break;
|
|
170
|
-
}
|
|
171
|
-
if (inDoDSection && line.startsWith("|")) {
|
|
172
|
-
const cells = line.split("|").map((c) => c.trim()).filter((c) => c.length > 0);
|
|
173
|
-
if (cells.length >= 2) {
|
|
174
|
-
if (cells[0] === "\u547D\u4EE4" || cells[0].startsWith("---")) continue;
|
|
175
|
-
const cmd = cells[0].replace(/^`|`$/g, "").trim();
|
|
176
|
-
const codeRaw = cells[1].trim();
|
|
177
|
-
let exitCode;
|
|
178
|
-
if (codeRaw === "timeout") exitCode = "timeout";
|
|
179
|
-
else if (codeRaw === "error") exitCode = "error";
|
|
180
|
-
else {
|
|
181
|
-
const parsedNum = parseInt(codeRaw, 10);
|
|
182
|
-
exitCode = isNaN(parsedNum) ? "error" : parsedNum;
|
|
183
|
-
}
|
|
184
|
-
dodResults.push({ command: cmd, exitCode });
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
const passed = dodResults.length > 0 && dodResults.every((r) => r.exitCode === 0);
|
|
189
|
-
return { passed, dodResults };
|
|
190
|
-
}
|
|
191
|
-
function extractChildAgentOutput(logPath, deps = {}) {
|
|
192
|
-
if (!logPath) return void 0;
|
|
193
|
-
const fs = deps.fs ?? nodeFs;
|
|
194
|
-
let raw;
|
|
195
|
-
try {
|
|
196
|
-
raw = fs.readFileSync(logPath, "utf8");
|
|
197
|
-
} catch {
|
|
198
|
-
return void 0;
|
|
199
|
-
}
|
|
200
|
-
const stripped = raw.replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g, "").replace(/\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]/g, "").replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "");
|
|
201
|
-
const lines = stripped.split(/\r?\n/);
|
|
202
|
-
let lastMarkerLineIdx = -1;
|
|
203
|
-
for (let i = lines.length - 1; i >= 0; i--) {
|
|
204
|
-
const line = lines[i];
|
|
205
|
-
if (/^(?:agent-[^\s>]+|[a-zA-Z0-9_@/.-]+)\s*>\s*/.test(line)) {
|
|
206
|
-
lastMarkerLineIdx = i;
|
|
207
|
-
break;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
if (lastMarkerLineIdx === -1) return void 0;
|
|
211
|
-
const collectedLines = [];
|
|
212
|
-
const firstLine = lines[lastMarkerLineIdx];
|
|
213
|
-
const firstMarkerIdx = firstLine.indexOf(" > ");
|
|
214
|
-
collectedLines.push(firstLine.slice(firstMarkerIdx + 3));
|
|
215
|
-
for (let j = lastMarkerLineIdx + 1; j < lines.length; j++) {
|
|
216
|
-
const line = lines[j];
|
|
217
|
-
if (line.startsWith("[nolo] dialog") || line.startsWith("[nolo] background dialog")) {
|
|
218
|
-
break;
|
|
219
|
-
}
|
|
220
|
-
collectedLines.push(line);
|
|
221
|
-
}
|
|
222
|
-
const joined = collectedLines.join("\n").trim();
|
|
223
|
-
if (!joined) return void 0;
|
|
224
|
-
const MAX_CHARS = 2e3;
|
|
225
|
-
const chars = Array.from(joined);
|
|
226
|
-
if (chars.length > MAX_CHARS) {
|
|
227
|
-
return `${chars.slice(0, MAX_CHARS).join("")}
|
|
228
|
-
|
|
229
|
-
...(\u622A\u65AD\uFF0C\u5B8C\u6574\u65E5\u5FD7\u8BF7\u67E5\u770B log)...`;
|
|
230
|
-
}
|
|
231
|
-
return joined;
|
|
232
|
-
}
|
|
233
|
-
async function buildRunReportData(record, deps = {}) {
|
|
234
|
-
const now = (deps.now ?? (() => /* @__PURE__ */ new Date()))();
|
|
235
|
-
const duration = formatDuration(record.startedAt, record.endedAt, now);
|
|
236
|
-
const edits = record.activity?.counters?.fileEdits ?? 0;
|
|
237
|
-
const tools = record.activity?.counters?.toolCalls ?? 0;
|
|
238
|
-
const llmCalls = record.activity?.counters?.llmCalls ?? 0;
|
|
239
|
-
const activityStr = `${edits} edits, ${tools} tools`;
|
|
240
|
-
const exitCodeStr = typeof record.exitCode === "number" ? String(record.exitCode) : "-";
|
|
241
|
-
const agentDisplay = record.agentName ? `${record.agentName} (${record.agentKey})` : record.agentKey;
|
|
242
|
-
const dialogIdStr = record.dialogId || "-";
|
|
243
|
-
const resolvedLogPath = record.logPath || resolveRunLogPath(record.runId, deps.env, deps.homedir);
|
|
244
|
-
const runsDir = resolveRunsDir(deps.env, deps.homedir);
|
|
245
|
-
const reportPath = resolveRunReportPath(record.runId, deps.env, deps.homedir);
|
|
246
|
-
const reportJsonPath = resolveRunReportJsonPath(record.runId, deps.env, deps.homedir);
|
|
247
|
-
const msgPath = record.msgFile ?? join(runsDir, `${record.runId}.msg.md`);
|
|
248
|
-
const fs = deps.fs ?? nodeFs;
|
|
249
|
-
const msgPathExists = fs.existsSync(msgPath);
|
|
250
|
-
const childOutput = extractChildAgentOutput(resolvedLogPath, deps);
|
|
251
|
-
const lines = [];
|
|
252
|
-
lines.push(`# Run \u9A8C\u6536\u62A5\u544A: ${record.runId}`);
|
|
253
|
-
lines.push("");
|
|
254
|
-
lines.push("## \u6982\u8981");
|
|
255
|
-
lines.push("");
|
|
256
|
-
lines.push("| \u5B57\u6BB5 | \u503C |");
|
|
257
|
-
lines.push("| --- | --- |");
|
|
258
|
-
lines.push(`| runId | ${record.runId} |`);
|
|
259
|
-
lines.push(`| agent | ${agentDisplay} |`);
|
|
260
|
-
lines.push(`| status | ${record.status} |`);
|
|
261
|
-
lines.push(`| exitCode | ${exitCodeStr} |`);
|
|
262
|
-
lines.push(`| \u5F00\u59CB\u65F6\u95F4 | ${record.startedAt} |`);
|
|
263
|
-
lines.push(`| \u7ED3\u675F\u65F6\u95F4 | ${record.endedAt ?? "-"} |`);
|
|
264
|
-
lines.push(`| \u8017\u65F6 | ${duration} |`);
|
|
265
|
-
lines.push(`| activity | ${activityStr} |`);
|
|
266
|
-
lines.push(`| dialogId | ${dialogIdStr} |`);
|
|
267
|
-
lines.push("");
|
|
268
|
-
lines.push("## \u5B50 Agent \u4EA7\u51FA");
|
|
269
|
-
lines.push("");
|
|
270
|
-
if (childOutput) {
|
|
271
|
-
lines.push(childOutput);
|
|
272
|
-
} else {
|
|
273
|
-
lines.push(`\uFF08\u65E0\u6CD5\u4ECE log \u63D0\u53D6\u6700\u7EC8\u7B54\u590D\uFF0C\u5B8C\u6574\u65E5\u5FD7\uFF1A${resolvedLogPath}\uFF09`);
|
|
274
|
-
}
|
|
275
|
-
lines.push("");
|
|
276
|
-
lines.push("## \u7ED3\u679C\u53BB\u54EA\u53D6");
|
|
277
|
-
lines.push("");
|
|
278
|
-
if (record.dialogId) {
|
|
279
|
-
lines.push(
|
|
280
|
-
`- \u5BF9\u8BDD\u8BB0\u5F55: ${record.dialogId}\uFF08\u53EF\u7528 controlAgentRun(action:"status", runId:"${record.runId}") \u67E5\u770B\uFF0C\u6216\u7EC8\u7AEF\u8FD0\u884C nolo dialog read ${record.dialogId}\uFF09`
|
|
281
|
-
);
|
|
282
|
-
} else {
|
|
283
|
-
lines.push("- \u5BF9\u8BDD\u8BB0\u5F55: \u65E0\uFF08\u672A\u6301\u4E45\u5316\u6216 ephemeral run\uFF09");
|
|
284
|
-
}
|
|
285
|
-
lines.push(`- \u5B8C\u6574\u65E5\u5FD7: ${resolvedLogPath}`);
|
|
286
|
-
if (msgPathExists) {
|
|
287
|
-
lines.push(`- \u4EFB\u52A1\u8F93\u5165: ${msgPath}`);
|
|
288
|
-
}
|
|
289
|
-
lines.push(`- \u9A8C\u6536\u62A5\u544A (Markdown): ${reportPath}`);
|
|
290
|
-
lines.push(`- \u9A8C\u6536\u62A5\u544A (JSON): ${reportJsonPath}`);
|
|
291
|
-
lines.push("");
|
|
292
|
-
let dodResults;
|
|
293
|
-
if (record.dodCommands && record.dodCommands.length > 0) {
|
|
294
|
-
dodResults = [];
|
|
295
|
-
lines.push("## DoD \u9A8C\u6536\u7ED3\u679C");
|
|
296
|
-
lines.push("");
|
|
297
|
-
lines.push("| \u547D\u4EE4 | exit code | stdout (\u5C3E\u90E8 20 \u884C) | stderr (\u5C3E\u90E8 10 \u884C) |");
|
|
298
|
-
lines.push("| --- | --- | --- | --- |");
|
|
299
|
-
for (const cmd of record.dodCommands) {
|
|
300
|
-
const result = executeDoDCommand(cmd, record.cwd, deps);
|
|
301
|
-
dodResults.push(result);
|
|
302
|
-
const codeStr = typeof result.exitCode === "number" ? String(result.exitCode) : result.exitCode;
|
|
303
|
-
const stdoutCell = formatCodeBlockCell(result.stdoutTail);
|
|
304
|
-
const stderrCell = formatCodeBlockCell(result.stderrTail);
|
|
305
|
-
const cmdCell = `\`${cmd.replace(/\|/g, "\\|")}\``;
|
|
306
|
-
lines.push(`| ${cmdCell} | ${codeStr} | ${stdoutCell} | ${stderrCell} |`);
|
|
307
|
-
}
|
|
308
|
-
lines.push("");
|
|
309
|
-
}
|
|
310
|
-
let gitSummary;
|
|
311
|
-
if (record.spawnHead) {
|
|
312
|
-
const summary = collectGitSummary(record.cwd, record.spawnHead, deps);
|
|
313
|
-
if (summary.isGitRepo && summary.commits && summary.commits.length > 0 && !summary.error && !summary.commits[0]?.startsWith("(")) {
|
|
314
|
-
gitSummary = summary;
|
|
315
|
-
lines.push("## Git \u6458\u8981");
|
|
316
|
-
lines.push("");
|
|
317
|
-
lines.push(`- \u65B0\u589E Commit (${record.spawnHead}..HEAD):`);
|
|
318
|
-
for (const c of summary.commits) {
|
|
319
|
-
lines.push(` - ${c}`);
|
|
320
|
-
}
|
|
321
|
-
lines.push("");
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
lines.push("---");
|
|
325
|
-
lines.push(`_\u751F\u6210\u65F6\u95F4: ${now.toISOString()}_`);
|
|
326
|
-
lines.push("");
|
|
327
|
-
const markdown = lines.join("\n");
|
|
328
|
-
const report = {
|
|
329
|
-
runId: record.runId,
|
|
330
|
-
agentKey: record.agentKey,
|
|
331
|
-
...record.agentName ? { agentName: record.agentName } : {},
|
|
332
|
-
status: record.status,
|
|
333
|
-
...typeof record.exitCode === "number" ? { exitCode: record.exitCode } : {},
|
|
334
|
-
startedAt: record.startedAt,
|
|
335
|
-
...record.endedAt ? { endedAt: record.endedAt } : {},
|
|
336
|
-
duration,
|
|
337
|
-
activity: { fileEdits: edits, toolCalls: tools, llmCalls },
|
|
338
|
-
...record.dialogId ? { dialogId: record.dialogId } : {},
|
|
339
|
-
...childOutput ? { childOutputTail: childOutput } : {},
|
|
340
|
-
...dodResults ? { dodResults } : {},
|
|
341
|
-
...gitSummary ? { gitSummary } : {},
|
|
342
|
-
generatedAt: now.toISOString()
|
|
343
|
-
};
|
|
344
|
-
return { markdown, report };
|
|
345
|
-
}
|
|
346
|
-
async function generateRunReport(record, deps = {}) {
|
|
347
|
-
const fs = deps.fs ?? nodeFs;
|
|
348
|
-
const env = deps.env ?? process.env;
|
|
349
|
-
const homedir = deps.homedir ?? nodeHomedir;
|
|
350
|
-
const runsDir = resolveRunsDir(env, homedir);
|
|
351
|
-
const reportPath = resolveRunReportPath(record.runId, env, homedir);
|
|
352
|
-
const reportJsonPath = resolveRunReportJsonPath(record.runId, env, homedir);
|
|
353
|
-
const { markdown, report } = await buildRunReportData(record, deps);
|
|
354
|
-
const shouldWrite = deps.forceReport === true || env.NOLO_RUN_REPORT === "1";
|
|
355
|
-
if (shouldWrite) {
|
|
356
|
-
try {
|
|
357
|
-
fs.mkdirSync(runsDir, { recursive: true });
|
|
358
|
-
fs.writeFileSync(reportPath, markdown, "utf8");
|
|
359
|
-
fs.writeFileSync(reportJsonPath, JSON.stringify(report, null, 2), "utf8");
|
|
360
|
-
} catch (err) {
|
|
361
|
-
console.warn(`[nolo] failed to write run report file to ${reportPath}:`, err);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
return { reportPath, reportJsonPath, markdown, report };
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
export {
|
|
368
|
-
parseDoDResultsFromMarkdown,
|
|
369
|
-
generateRunReport
|
|
370
|
-
};
|