nolo-cli 0.6.1 → 0.8.0-alpha.10
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-CPDNUUQV.js +198 -0
- package/action-PAXRPJJF.js +27 -0
- package/addContentAction-CZVWF3QZ.js +25 -0
- package/addDialogAgentAction-CCIDTPHC.js +67 -0
- package/agentDeleteCommand-OSUMJMZM.js +323 -0
- package/agentEmailCommands-OQTJIPQU.js +621 -0
- package/agentListCommands-FATQEUYT.js +219 -0
- package/agentMachineCommands-6LZWF4GL.js +421 -0
- package/agentPullCommand-O2MTUAFR.js +122 -0
- package/agentRecordCommands-TIHFU65Z.js +89 -0
- package/agentRunCommand-R64Y3HCH.js +102 -0
- package/agentRunControl-K4VKNEHF.js +57 -0
- package/agentRuntimeLocal-6PIWAHLQ.js +99 -0
- package/agentSlice-TP4VARJF.js +41 -0
- package/authCommand-WXMD3IPR.js +574 -0
- package/authCommands-X74AFDTC.js +26 -0
- package/chunk-2EISRLRC.js +238 -0
- package/chunk-2FTTDCD4.js +675 -0
- package/chunk-2MALU52L.js +51 -0
- package/chunk-2TPUKEU7.js +1078 -0
- package/chunk-3ASDTTEI.js +1774 -0
- package/chunk-3EUW3WEO.js +8 -0
- package/chunk-3LY4F7SV.js +9293 -0
- package/chunk-4CQLVGRV.js +50 -0
- package/chunk-4IJYA27C.js +342 -0
- package/chunk-4SN6J65J.js +38 -0
- package/chunk-4VNS5WPM.js +42 -0
- package/chunk-572EKYLF.js +792 -0
- package/chunk-5MIDPSSK.js +206 -0
- package/chunk-5MMAK75Q.js +15 -0
- package/chunk-5VV37AT4.js +222 -0
- package/chunk-63W5N6P3.js +150 -0
- package/chunk-6A5EF6IR.js +929 -0
- package/chunk-6HYVJV7B.js +102 -0
- package/chunk-6P2WX5IA.js +3631 -0
- package/chunk-6WD3OOJS.js +20 -0
- package/chunk-ATNTHIZI.js +13 -0
- package/chunk-AUGHVUFE.js +69 -0
- package/chunk-AVMKZHBC.js +85 -0
- package/chunk-AZPCASRE.js +36 -0
- package/chunk-BNMT7YY5.js +34 -0
- package/chunk-BR2WP3DF.js +548 -0
- package/chunk-BSTNFPHD.js +231 -0
- package/chunk-BU4OPIXC.js +171 -0
- package/chunk-CF2WZF4N.js +134 -0
- package/chunk-CF7PE763.js +10 -0
- package/chunk-CKOJQDKR.js +198 -0
- package/chunk-CM54RSSA.js +206 -0
- package/chunk-CWMSB67P.js +34 -0
- package/chunk-DA2OEKS6.js +27 -0
- package/chunk-DFFIZ25G.js +30 -0
- package/chunk-DWLEOOGR.js +8 -0
- package/chunk-DZ3XJVET.js +231 -0
- package/chunk-EHLHSX7R.js +1433 -0
- package/chunk-ELRRLDWI.js +478 -0
- package/chunk-EYEEHCU4.js +3066 -0
- package/chunk-FQZWM5YX.js +628 -0
- package/chunk-G3SUCT4W.js +8 -0
- package/chunk-G5H7RNFL.js +807 -0
- package/chunk-GAKEBQD6.js +30 -0
- package/chunk-GBRG75BQ.js +86 -0
- package/chunk-H2RMRZJE.js +113 -0
- package/chunk-H33743XH.js +25 -0
- package/chunk-HD63YREL.js +19 -0
- package/chunk-HEIIIZBX.js +104 -0
- package/chunk-HNMXYYJR.js +12 -0
- package/chunk-HOMYP7GZ.js +2152 -0
- package/chunk-HZFOMJRA.js +4300 -0
- package/chunk-IAXBCTTE.js +175 -0
- package/chunk-IDZTNRP2.js +85 -0
- package/chunk-IHHA5Y2S.js +9013 -0
- package/chunk-ISNCLGUZ.js +146 -0
- package/chunk-IYQV26RA.js +138 -0
- package/chunk-J4576WMJ.js +91 -0
- package/chunk-JBTJAPUF.js +35 -0
- package/chunk-JZPBVBIY.js +94 -0
- package/chunk-KQHGZWSV.js +63 -0
- package/chunk-KUG52IAP.js +8 -0
- package/chunk-KX6YBIHG.js +8 -0
- package/chunk-LCBAMY2M.js +60 -0
- package/chunk-LM25IZBJ.js +902 -0
- package/chunk-LM6IYQ3F.js +16 -0
- package/chunk-M76ECQRD.js +13658 -0
- package/chunk-MRC4Q34M.js +188 -0
- package/chunk-NEMRK4EK.js +944 -0
- package/chunk-NXZGF7F7.js +2878 -0
- package/chunk-OF5H3QWS.js +300 -0
- package/chunk-OLZBQWZU.js +6 -0
- package/chunk-OOYVBFM7.js +191 -0
- package/chunk-OWOHNGCN.js +50 -0
- package/chunk-PN7AFLOK.js +3401 -0
- package/chunk-POCFIDGQ.js +562 -0
- package/chunk-Q6WACBKB.js +1949 -0
- package/chunk-QFV2OAIM.js +421 -0
- package/chunk-QJ6V2NIN.js +1447 -0
- package/chunk-QSJ3HFEF.js +8 -0
- package/chunk-QUWDTOUP.js +190 -0
- package/chunk-QYXLLLGL.js +4519 -0
- package/chunk-ROWQEJRP.js +139 -0
- package/chunk-S7Z2HMCN.js +25 -0
- package/chunk-TDIQFT2F.js +301 -0
- package/chunk-TILFE6LV.js +381 -0
- package/chunk-TKOUBWBO.js +24674 -0
- package/chunk-TYH5JE6N.js +27158 -0
- package/chunk-U4TRT5V4.js +246 -0
- package/chunk-U6VC4MU4.js +8 -0
- package/chunk-UAD2WT54.js +64 -0
- package/chunk-USZMK5UT.js +105 -0
- package/chunk-VEJLAVTC.js +2052 -0
- package/chunk-VF4K2QE6.js +21 -0
- package/chunk-VHBWHNVT.js +59 -0
- package/chunk-VIDPVFP3.js +20 -0
- package/chunk-VP4WJWKW.js +8882 -0
- package/chunk-VQ2AJRGD.js +148 -0
- package/chunk-W4NVOSFF.js +37 -0
- package/chunk-WWC7I6TA.js +8 -0
- package/chunk-X7W4TNB4.js +1550 -0
- package/chunk-XDVAYP26.js +537 -0
- package/chunk-XKIMRZO2.js +221 -0
- package/chunk-Y5GCAMGP.js +9 -0
- package/chunk-YWPXYBY7.js +360 -0
- package/chunk-Z4NR32XR.js +50 -0
- package/chunk-ZNFJWEN4.js +56 -0
- package/cliExecutor-DNE7TCC4.js +36 -0
- package/clipboardy-BVE3LVEH.js +12001 -0
- package/createAgentAutomationAction-KLKS2HGU.js +864 -0
- package/createDialogAction-Z33JMBF5.js +52 -0
- package/createPageAction-AQVNOAAI.js +169 -0
- package/db-HCJ5PRB5.js +271 -0
- package/dbSlice-C4UJLRZP.js +59 -0
- package/deleteFile-4SKGPHOZ.js +41 -0
- package/dialogCommands-W5PD6MZU.js +59 -0
- package/dialogSlice-RBJYVSAR.js +146 -0
- package/docCreateCommands-MM34S4Z3.js +215 -0
- package/docDeleteCommands-JJTU722V.js +176 -0
- package/docReadCommands-GLYDMCTU.js +129 -0
- package/docStore-5TYME4DO.js +96 -0
- package/docUpdateCommands-ZCGQ7URR.js +313 -0
- package/fetchMessages-JOCYIFKL.js +16 -0
- package/getPricing-PWPJ6MNV.js +30 -0
- package/handleSendMessageAction-KA2MRW6E.js +183 -0
- package/index.js +184 -112254
- package/lib-FYYBQIXS.js +19839 -0
- package/localDialogRead-D3BELSTF.js +26 -0
- package/localFirstLog-DHNOY2NA.js +19 -0
- package/localRuntimeAuthority-TEGCOWX4.js +471 -0
- package/localRuntimeDb-LGDF6FQP.js +12 -0
- package/machineCommands-ZB5WUSPF.js +774 -0
- package/machineInfo-M6KB6HZN.js +10 -0
- package/machineWsRunDispatch-GWCAPPCM.js +105 -0
- package/memoryCommands-O4MIPIWQ.js +476 -0
- package/models-XLEOET3E.js +9 -0
- package/offlineMarxistsAgentCommand-BCPJITJL.js +242 -0
- package/package.json +3 -25
- package/read-RIJCIVKX.js +17 -0
- package/readDocTool-GZD2N3LO.js +16 -0
- package/readlineWorkspace-FEDY44AA.js +5357 -0
- package/removeDialogAgentAction-CXLST3N6.js +72 -0
- package/runAgentClientLoop-W4NKE64V.js +288 -0
- package/runtimeDoctorCommands-LRHLPDRC.js +289 -0
- package/setDialogExtraReferencesAction-LP6VYGU7.js +59 -0
- package/setPrimaryDialogAgentAction-D3GGH23T.js +79 -0
- package/settingSlice-J4I3Z5H7.js +198 -0
- package/skillSummaryMarker-42HKSXYY.js +9 -0
- package/slateToRenderMarkdown-Y5IYN73U.js +7 -0
- package/slateUtils-2M7MUTWX.js +19 -0
- package/spaceCommands-LC4FDAKE.js +450 -0
- package/spaceSlice-32XOGBEF.js +145 -0
- package/streamAgentChatTurn-YQW32AQH.js +4503 -0
- package/tableCommands-GOFP7QKA.js +1286 -0
- package/toolApiClient-QI3YBNWB.js +26 -0
- package/tools-XGTFRYD7.js +83 -0
- package/understanding-HCSFPE7R.js +318 -0
- package/updateCommands-VOSPKXFF.js +31 -0
- package/updateDialogTitleAction-4LHQDNHQ.js +185 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// packages/cli/client/profileConfig.ts
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
|
|
6
|
+
// packages/core/noloServerUrl.ts
|
|
7
|
+
function isNoloChatHostname(hostname) {
|
|
8
|
+
if (typeof hostname !== "string") return false;
|
|
9
|
+
const host = hostname.trim().toLowerCase();
|
|
10
|
+
if (!host) return false;
|
|
11
|
+
return host === "nolo.chat" || host.endsWith(".nolo.chat");
|
|
12
|
+
}
|
|
13
|
+
function canonicalizeNoloServerUrl(value) {
|
|
14
|
+
const normalized = value.trim().replace(/\/+$/, "");
|
|
15
|
+
if (!normalized) return normalized;
|
|
16
|
+
try {
|
|
17
|
+
const url = new URL(normalized);
|
|
18
|
+
if (url.protocol === "http:" && isNoloChatHostname(url.hostname)) {
|
|
19
|
+
url.protocol = "https:";
|
|
20
|
+
return url.toString().replace(/\/+$/, "");
|
|
21
|
+
}
|
|
22
|
+
} catch {
|
|
23
|
+
return normalized;
|
|
24
|
+
}
|
|
25
|
+
return normalized;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// packages/cli/client/profileConfig.ts
|
|
29
|
+
var normalizeProfileServerUrl = canonicalizeNoloServerUrl;
|
|
30
|
+
function getDefaultProfileConfigPath() {
|
|
31
|
+
return join(homedir(), ".nolo", "config.json");
|
|
32
|
+
}
|
|
33
|
+
function loadProfileConfig(path = getDefaultProfileConfigPath()) {
|
|
34
|
+
if (!existsSync(path)) return null;
|
|
35
|
+
const raw = readFileSync(path, "utf8");
|
|
36
|
+
const parsed = JSON.parse(raw);
|
|
37
|
+
if (!parsed.currentProfile || !parsed.profiles?.[parsed.currentProfile]) return null;
|
|
38
|
+
for (const profile of Object.values(parsed.profiles)) {
|
|
39
|
+
if (!profile?.serverUrl) continue;
|
|
40
|
+
profile.serverUrl = normalizeProfileServerUrl(profile.serverUrl);
|
|
41
|
+
}
|
|
42
|
+
return parsed;
|
|
43
|
+
}
|
|
44
|
+
function clearProfileAuthToken(path = getDefaultProfileConfigPath()) {
|
|
45
|
+
const config = loadProfileConfig(path);
|
|
46
|
+
if (!config) return false;
|
|
47
|
+
const profile = config.profiles[config.currentProfile];
|
|
48
|
+
if (!profile?.authToken?.trim()) return false;
|
|
49
|
+
delete profile.authToken;
|
|
50
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
51
|
+
writeFileSync(path, `${JSON.stringify(config, null, 2)}
|
|
52
|
+
`, "utf8");
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
function saveDefaultProfile(path, profile) {
|
|
56
|
+
const existing = loadProfileConfig(path);
|
|
57
|
+
const mergedDefault = {
|
|
58
|
+
...existing?.profiles?.default ?? {},
|
|
59
|
+
serverUrl: normalizeProfileServerUrl(profile.serverUrl),
|
|
60
|
+
authToken: profile.authToken.trim()
|
|
61
|
+
};
|
|
62
|
+
const config = {
|
|
63
|
+
currentProfile: "default",
|
|
64
|
+
profiles: {
|
|
65
|
+
...existing?.profiles ?? {},
|
|
66
|
+
default: mergedDefault
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
70
|
+
writeFileSync(path, `${JSON.stringify(config, null, 2)}
|
|
71
|
+
`, "utf8");
|
|
72
|
+
return config;
|
|
73
|
+
}
|
|
74
|
+
function buildEnvFromProfile(config) {
|
|
75
|
+
if (!config) return {};
|
|
76
|
+
const profile = config.profiles[config.currentProfile];
|
|
77
|
+
if (!profile) return {};
|
|
78
|
+
return {
|
|
79
|
+
NOLO_PROFILE: config.currentProfile,
|
|
80
|
+
NOLO_SERVER: profile.serverUrl,
|
|
81
|
+
...profile.authToken?.trim() ? { AUTH_TOKEN: profile.authToken.trim() } : {},
|
|
82
|
+
...profile.agentKey ? { NOLO_AGENT: profile.agentKey } : {},
|
|
83
|
+
...profile.agentName ? { NOLO_AGENT_NAME: profile.agentName } : {},
|
|
84
|
+
...profile.locale ? { NOLO_LANG: profile.locale } : {}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function buildCliRuntimeEnv(processEnv, config) {
|
|
88
|
+
const profileEnv = buildEnvFromProfile(config);
|
|
89
|
+
const explicitAuthToken = processEnv.AUTH_TOKEN || processEnv.AUTH;
|
|
90
|
+
const explicitServerUrl = processEnv.NOLO_SERVER || processEnv.NOLO_SERVER_URL || processEnv.BASE_URL;
|
|
91
|
+
return {
|
|
92
|
+
...processEnv,
|
|
93
|
+
...profileEnv,
|
|
94
|
+
...explicitAuthToken ? { AUTH_TOKEN: explicitAuthToken } : {},
|
|
95
|
+
...explicitServerUrl ? {
|
|
96
|
+
NOLO_SERVER: explicitServerUrl,
|
|
97
|
+
BASE_URL: explicitServerUrl
|
|
98
|
+
} : {}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function getCurrentProfile(config) {
|
|
102
|
+
if (!config) return null;
|
|
103
|
+
return config.profiles[config.currentProfile] ?? null;
|
|
104
|
+
}
|
|
105
|
+
function saveProfileLocale(locale, path = getDefaultProfileConfigPath()) {
|
|
106
|
+
const config = loadProfileConfig(path);
|
|
107
|
+
if (!config) return null;
|
|
108
|
+
const profile = config.profiles[config.currentProfile];
|
|
109
|
+
if (!profile) return null;
|
|
110
|
+
profile.locale = locale;
|
|
111
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
112
|
+
writeFileSync(path, `${JSON.stringify(config, null, 2)}
|
|
113
|
+
`, "utf8");
|
|
114
|
+
return config;
|
|
115
|
+
}
|
|
116
|
+
function saveProfileAgentSelection(selection, path = getDefaultProfileConfigPath()) {
|
|
117
|
+
const config = loadProfileConfig(path);
|
|
118
|
+
if (!config) return null;
|
|
119
|
+
const profile = config.profiles[config.currentProfile];
|
|
120
|
+
if (!profile) return null;
|
|
121
|
+
profile.agentKey = selection.agentKey.trim();
|
|
122
|
+
profile.agentName = selection.agentName.trim();
|
|
123
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
124
|
+
writeFileSync(path, `${JSON.stringify(config, null, 2)}
|
|
125
|
+
`, "utf8");
|
|
126
|
+
return config;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export {
|
|
130
|
+
getDefaultProfileConfigPath,
|
|
131
|
+
loadProfileConfig,
|
|
132
|
+
clearProfileAuthToken,
|
|
133
|
+
saveDefaultProfile,
|
|
134
|
+
buildEnvFromProfile,
|
|
135
|
+
buildCliRuntimeEnv,
|
|
136
|
+
getCurrentProfile,
|
|
137
|
+
saveProfileLocale,
|
|
138
|
+
saveProfileAgentSelection
|
|
139
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// packages/cli/secretScan.ts
|
|
2
|
+
var SECRET_PATTERNS = [
|
|
3
|
+
{ label: "password", pattern: /\bpassword\s*[:=]\s*["']?[^"',\s#]{8,}/i },
|
|
4
|
+
{ label: "psk", pattern: /\bpsk\s*[:=]\s*["']?[^"',\s#]{8,}/i },
|
|
5
|
+
{ label: "api key", pattern: /\b(api[_-]?key|apikey)\s*[:=]\s*["']?[^"',\s#]{12,}/i },
|
|
6
|
+
{ label: "token", pattern: /\b(token|secret)\s*[:=]\s*["']?[^"',\s#]{12,}/i },
|
|
7
|
+
{ label: "private key", pattern: /-----BEGIN [A-Z ]*PRIVATE KEY-----/ }
|
|
8
|
+
];
|
|
9
|
+
function findPotentialSecrets(text) {
|
|
10
|
+
return text.split(/\r?\n/).flatMap(
|
|
11
|
+
(line, index) => SECRET_PATTERNS.filter(({ pattern }) => pattern.test(line)).map(({ label }) => ({
|
|
12
|
+
label,
|
|
13
|
+
line: index + 1,
|
|
14
|
+
preview: line.length > 120 ? `${line.slice(0, 117)}...` : line
|
|
15
|
+
}))
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
function formatSecretFindings(findings) {
|
|
19
|
+
return findings.map((finding) => ` line ${finding.line} (${finding.label}): ${finding.preview}`).join("\n");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
findPotentialSecrets,
|
|
24
|
+
formatSecretFindings
|
|
25
|
+
};
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getCredentialsDir
|
|
3
|
+
} from "./chunk-JZPBVBIY.js";
|
|
4
|
+
import {
|
|
5
|
+
asNonEmptyStringArray
|
|
6
|
+
} from "./chunk-PN7AFLOK.js";
|
|
7
|
+
import {
|
|
8
|
+
asTrimmedString
|
|
9
|
+
} from "./chunk-3EUW3WEO.js";
|
|
10
|
+
import {
|
|
11
|
+
asOptionalPositiveFiniteNumber
|
|
12
|
+
} from "./chunk-U6VC4MU4.js";
|
|
13
|
+
import {
|
|
14
|
+
isRecord
|
|
15
|
+
} from "./chunk-KUG52IAP.js";
|
|
16
|
+
|
|
17
|
+
// packages/agent-runtime/fileCredentialBroker.ts
|
|
18
|
+
import {
|
|
19
|
+
chmodSync,
|
|
20
|
+
existsSync,
|
|
21
|
+
mkdirSync,
|
|
22
|
+
readFileSync,
|
|
23
|
+
unlinkSync,
|
|
24
|
+
writeFileSync
|
|
25
|
+
} from "node:fs";
|
|
26
|
+
import { homedir } from "node:os";
|
|
27
|
+
import { join } from "node:path";
|
|
28
|
+
|
|
29
|
+
// packages/agent-runtime/credentialBroker.ts
|
|
30
|
+
function assertCredentialRef(ref) {
|
|
31
|
+
const trimmed = asTrimmedString(ref);
|
|
32
|
+
if (!trimmed) {
|
|
33
|
+
throw new Error("invalid_ref");
|
|
34
|
+
}
|
|
35
|
+
if (trimmed.includes("..") || trimmed.includes("/") || trimmed.includes("\\")) {
|
|
36
|
+
throw new Error("invalid_ref");
|
|
37
|
+
}
|
|
38
|
+
return trimmed;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// packages/agent-runtime/fileCredentialBroker.ts
|
|
42
|
+
function getApiKeyCredentialsDir(homeDir = homedir()) {
|
|
43
|
+
return join(getCredentialsDir(homeDir), "keys");
|
|
44
|
+
}
|
|
45
|
+
function credentialRefToFileName(ref) {
|
|
46
|
+
const safe = assertCredentialRef(ref).replace(/[^a-zA-Z0-9._-]+/g, "_");
|
|
47
|
+
if (!safe || safe === "." || safe === "..") {
|
|
48
|
+
throw new Error(`Credential ref is not filesystem-safe: ${ref}`);
|
|
49
|
+
}
|
|
50
|
+
return `${safe}.json`;
|
|
51
|
+
}
|
|
52
|
+
function getApiKeyCredentialPath(ref, homeDir = homedir()) {
|
|
53
|
+
return join(getApiKeyCredentialsDir(homeDir), credentialRefToFileName(ref));
|
|
54
|
+
}
|
|
55
|
+
function ensurePrivateDir(dir) {
|
|
56
|
+
mkdirSync(dir, { recursive: true, mode: 448 });
|
|
57
|
+
try {
|
|
58
|
+
chmodSync(dir, 448);
|
|
59
|
+
} catch {
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function writePrivateFile(path, body) {
|
|
63
|
+
writeFileSync(path, body, { encoding: "utf8", mode: 384 });
|
|
64
|
+
try {
|
|
65
|
+
chmodSync(path, 384);
|
|
66
|
+
} catch {
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function readApiKeyCredential(ref, homeDir = homedir()) {
|
|
70
|
+
const path = getApiKeyCredentialPath(ref, homeDir);
|
|
71
|
+
if (!existsSync(path)) return null;
|
|
72
|
+
try {
|
|
73
|
+
const raw = readFileSync(path, "utf8");
|
|
74
|
+
const parsed = JSON.parse(raw);
|
|
75
|
+
if (typeof parsed?.secret !== "string" || !parsed.secret) return null;
|
|
76
|
+
return parsed.secret;
|
|
77
|
+
} catch {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function writeApiKeyCredential(ref, secret, homeDir = homedir(), now = Date.now()) {
|
|
82
|
+
const trimmedSecret = secret.trim();
|
|
83
|
+
if (!trimmedSecret) {
|
|
84
|
+
throw new Error("Cannot store an empty credential secret.");
|
|
85
|
+
}
|
|
86
|
+
assertCredentialRef(ref);
|
|
87
|
+
const dir = getApiKeyCredentialsDir(homeDir);
|
|
88
|
+
ensurePrivateDir(dir);
|
|
89
|
+
const path = getApiKeyCredentialPath(ref, homeDir);
|
|
90
|
+
const payload = {
|
|
91
|
+
secret: trimmedSecret,
|
|
92
|
+
updatedAt: now
|
|
93
|
+
};
|
|
94
|
+
writePrivateFile(path, `${JSON.stringify(payload, null, 2)}
|
|
95
|
+
`);
|
|
96
|
+
}
|
|
97
|
+
function removeApiKeyCredential(ref, homeDir = homedir()) {
|
|
98
|
+
assertCredentialRef(ref);
|
|
99
|
+
const path = getApiKeyCredentialPath(ref, homeDir);
|
|
100
|
+
if (!existsSync(path)) return;
|
|
101
|
+
unlinkSync(path);
|
|
102
|
+
}
|
|
103
|
+
function hasApiKeyCredential(ref, homeDir = homedir()) {
|
|
104
|
+
return readApiKeyCredential(ref, homeDir) !== null;
|
|
105
|
+
}
|
|
106
|
+
function createFileCredentialBroker(options = {}) {
|
|
107
|
+
const homeDir = options.homeDir ?? homedir();
|
|
108
|
+
const now = options.now ?? Date.now;
|
|
109
|
+
return {
|
|
110
|
+
get(ref) {
|
|
111
|
+
return readApiKeyCredential(ref, homeDir);
|
|
112
|
+
},
|
|
113
|
+
put(ref, secret) {
|
|
114
|
+
writeApiKeyCredential(ref, secret, homeDir, now());
|
|
115
|
+
},
|
|
116
|
+
delete(ref) {
|
|
117
|
+
removeApiKeyCredential(ref, homeDir);
|
|
118
|
+
},
|
|
119
|
+
has(ref) {
|
|
120
|
+
return hasApiKeyCredential(ref, homeDir);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// packages/agent-runtime/migrateAgentSecrets.ts
|
|
126
|
+
function buildAgentApiKeyCredentialRef(agentKey) {
|
|
127
|
+
const key = asTrimmedString(agentKey);
|
|
128
|
+
if (!key) throw new Error("agentKey is required to build a credential ref.");
|
|
129
|
+
return `api-key:${key}`;
|
|
130
|
+
}
|
|
131
|
+
function readRawApiKey(agent) {
|
|
132
|
+
return asTrimmedString(agent.apiKey);
|
|
133
|
+
}
|
|
134
|
+
function resolveTargetRef(agent) {
|
|
135
|
+
const fromCredential = asTrimmedString(agent.credentialRef);
|
|
136
|
+
if (fromCredential) return fromCredential;
|
|
137
|
+
const fromApiKeyRef = asTrimmedString(agent.apiKeyRef);
|
|
138
|
+
if (fromApiKeyRef.startsWith("api-key:")) return fromApiKeyRef;
|
|
139
|
+
return buildAgentApiKeyCredentialRef(agent.key);
|
|
140
|
+
}
|
|
141
|
+
async function brokerHas(broker, ref) {
|
|
142
|
+
return Boolean(await broker.has(ref));
|
|
143
|
+
}
|
|
144
|
+
async function brokerPut(broker, ref, secret) {
|
|
145
|
+
await broker.put(ref, secret);
|
|
146
|
+
}
|
|
147
|
+
async function migrateAgentSecrets(args) {
|
|
148
|
+
const { agent, broker } = args;
|
|
149
|
+
const raw = readRawApiKey(agent);
|
|
150
|
+
const migration = asTrimmedString(agent.credentialMigration);
|
|
151
|
+
if (migration === "done" && !raw) {
|
|
152
|
+
const ref = typeof agent.credentialRef === "string" && agent.credentialRef.trim() || (typeof agent.apiKeyRef === "string" && agent.apiKeyRef.startsWith("api-key:") ? agent.apiKeyRef.trim() : "") || void 0;
|
|
153
|
+
return {
|
|
154
|
+
updates: {},
|
|
155
|
+
status: "already-done",
|
|
156
|
+
...ref ? { credentialRef: ref } : {},
|
|
157
|
+
phase: "complete"
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (!raw && migration !== "pending") {
|
|
161
|
+
return { updates: {}, status: "noop", phase: "none" };
|
|
162
|
+
}
|
|
163
|
+
const targetRef = resolveTargetRef(agent);
|
|
164
|
+
if (raw) {
|
|
165
|
+
await brokerPut(broker, targetRef, raw);
|
|
166
|
+
const stored2 = await brokerHas(broker, targetRef);
|
|
167
|
+
if (!stored2) {
|
|
168
|
+
return {
|
|
169
|
+
updates: {
|
|
170
|
+
credentialRef: targetRef,
|
|
171
|
+
credentialMigration: "pending"
|
|
172
|
+
},
|
|
173
|
+
status: "resumed-pending",
|
|
174
|
+
credentialRef: targetRef,
|
|
175
|
+
phase: "put"
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
updates: {
|
|
180
|
+
apiKey: null,
|
|
181
|
+
credentialRef: targetRef,
|
|
182
|
+
// Keep apiKeyRef for resolution if not already an OAuth provider name.
|
|
183
|
+
// Prefer explicit credentialRef; set apiKeyRef only when empty so OAuth agents stay intact.
|
|
184
|
+
...!(typeof agent.apiKeyRef === "string" && agent.apiKeyRef.trim()) ? { apiKeyRef: targetRef } : {},
|
|
185
|
+
credentialMigration: "done"
|
|
186
|
+
},
|
|
187
|
+
status: migration === "pending" ? "resumed-pending" : "migrated",
|
|
188
|
+
credentialRef: targetRef,
|
|
189
|
+
phase: "strip"
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const stored = await brokerHas(broker, targetRef);
|
|
193
|
+
if (stored) {
|
|
194
|
+
return {
|
|
195
|
+
updates: {
|
|
196
|
+
credentialRef: targetRef,
|
|
197
|
+
credentialMigration: "done",
|
|
198
|
+
...!(typeof agent.apiKeyRef === "string" && agent.apiKeyRef.trim()) ? { apiKeyRef: targetRef } : {}
|
|
199
|
+
},
|
|
200
|
+
status: "resumed-pending",
|
|
201
|
+
credentialRef: targetRef,
|
|
202
|
+
phase: "complete"
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
updates: {
|
|
207
|
+
credentialRef: targetRef,
|
|
208
|
+
credentialMigration: "pending"
|
|
209
|
+
},
|
|
210
|
+
status: "awaiting-secret",
|
|
211
|
+
credentialRef: targetRef,
|
|
212
|
+
phase: "put"
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function applyAgentSecretMigrationUpdates(record, updates) {
|
|
216
|
+
const next = { ...record };
|
|
217
|
+
if ("apiKey" in updates) {
|
|
218
|
+
if (updates.apiKey === null || updates.apiKey === "") {
|
|
219
|
+
delete next.apiKey;
|
|
220
|
+
} else if (typeof updates.apiKey === "string") {
|
|
221
|
+
next.apiKey = updates.apiKey;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (updates.apiKeyRef !== void 0) next.apiKeyRef = updates.apiKeyRef;
|
|
225
|
+
if (updates.credentialRef !== void 0) next.credentialRef = updates.credentialRef;
|
|
226
|
+
if (updates.credentialMigration !== void 0) {
|
|
227
|
+
next.credentialMigration = updates.credentialMigration;
|
|
228
|
+
}
|
|
229
|
+
return next;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// packages/agent-runtime/runtimeToolPolicy.ts
|
|
233
|
+
function unique(values) {
|
|
234
|
+
return [...new Set(values)];
|
|
235
|
+
}
|
|
236
|
+
function normalizeAgentRuntimeToolPolicy(value) {
|
|
237
|
+
if (!isRecord(value)) return void 0;
|
|
238
|
+
return {
|
|
239
|
+
version: 1,
|
|
240
|
+
...asNonEmptyStringArray(value.agentTools).length ? { agentTools: unique(asNonEmptyStringArray(value.agentTools)) } : {},
|
|
241
|
+
...asNonEmptyStringArray(value.runtimeTools).length ? { runtimeTools: unique(asNonEmptyStringArray(value.runtimeTools)) } : {},
|
|
242
|
+
...isRecord(value.workspace) ? { workspace: { ...value.workspace } } : {},
|
|
243
|
+
...isRecord(value.shell) ? { shell: { ...value.shell } } : {},
|
|
244
|
+
...isRecord(value.isolation) ? { isolation: { ...value.isolation } } : {},
|
|
245
|
+
...isRecord(value.git) ? { git: { ...value.git } } : {},
|
|
246
|
+
...isRecord(value.budget) ? { budget: { ...value.budget } } : {},
|
|
247
|
+
...isRecord(value.audit) ? { audit: { ...value.audit } } : {}
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function runtimeBindingRecord(runtimeBinding) {
|
|
251
|
+
return isRecord(runtimeBinding) ? runtimeBinding : void 0;
|
|
252
|
+
}
|
|
253
|
+
function runtimeToolNamesFromPolicy(policy) {
|
|
254
|
+
return asNonEmptyStringArray(policy?.runtimeTools);
|
|
255
|
+
}
|
|
256
|
+
function readPositiveNumber(value) {
|
|
257
|
+
return asOptionalPositiveFiniteNumber(Number(value));
|
|
258
|
+
}
|
|
259
|
+
function resolveRequestedRuntimeToolNames(args) {
|
|
260
|
+
const runtimeBinding = runtimeBindingRecord(args.agentConfig.runtimeBinding);
|
|
261
|
+
const bindingPolicy = normalizeAgentRuntimeToolPolicy(
|
|
262
|
+
runtimeBinding?.runtimeToolPolicy
|
|
263
|
+
);
|
|
264
|
+
const bindingSnapshotPolicy = normalizeAgentRuntimeToolPolicy(
|
|
265
|
+
runtimeBinding?.runtimeToolPolicySnapshot
|
|
266
|
+
);
|
|
267
|
+
return unique([
|
|
268
|
+
...asNonEmptyStringArray(args.agentConfig.toolNames),
|
|
269
|
+
...runtimeToolNamesFromPolicy(
|
|
270
|
+
normalizeAgentRuntimeToolPolicy(args.agentConfig.runtimeToolPolicy)
|
|
271
|
+
),
|
|
272
|
+
...runtimeToolNamesFromPolicy(bindingPolicy),
|
|
273
|
+
...runtimeToolNamesFromPolicy(bindingSnapshotPolicy)
|
|
274
|
+
]);
|
|
275
|
+
}
|
|
276
|
+
function resolveCurrentRunRuntimeToolPolicy(agentConfig) {
|
|
277
|
+
const runtimeBinding = runtimeBindingRecord(agentConfig?.runtimeBinding);
|
|
278
|
+
return normalizeAgentRuntimeToolPolicy(
|
|
279
|
+
runtimeBinding?.runtimeToolPolicySnapshot ?? agentConfig?.runtimeToolPolicy ?? runtimeBinding?.runtimeToolPolicy
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
function resolveLocalRuntimeEnvFromPolicy(runtimeEnv, policy) {
|
|
283
|
+
return { ...runtimeEnv };
|
|
284
|
+
}
|
|
285
|
+
function resolveLocalWorkspaceExecutorOptionsFromPolicy(policy) {
|
|
286
|
+
const maxOutputBytes = readPositiveNumber(policy?.shell?.maxOutputBytes);
|
|
287
|
+
return {
|
|
288
|
+
...maxOutputBytes ? { commandOutputLimit: Math.floor(maxOutputBytes) } : {}
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export {
|
|
293
|
+
createFileCredentialBroker,
|
|
294
|
+
migrateAgentSecrets,
|
|
295
|
+
applyAgentSecretMigrationUpdates,
|
|
296
|
+
normalizeAgentRuntimeToolPolicy,
|
|
297
|
+
resolveRequestedRuntimeToolNames,
|
|
298
|
+
resolveCurrentRunRuntimeToolPolicy,
|
|
299
|
+
resolveLocalRuntimeEnvFromPolicy,
|
|
300
|
+
resolveLocalWorkspaceExecutorOptionsFromPolicy
|
|
301
|
+
};
|