nolo-cli 0.8.0-alpha.6 → 0.8.0-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/_executeModel-XIGO7HW5.js +198 -0
  2. package/action-PAXRPJJF.js +27 -0
  3. package/addContentAction-CZVWF3QZ.js +25 -0
  4. package/addDialogAgentAction-CCIDTPHC.js +67 -0
  5. package/agentDeleteCommand-47B24JYG.js +323 -0
  6. package/agentEmailCommands-D4FC6OZJ.js +621 -0
  7. package/agentListCommands-UFET7CC4.js +219 -0
  8. package/agentMachineCommands-LH7QDQPP.js +421 -0
  9. package/agentPullCommand-O2MTUAFR.js +122 -0
  10. package/agentRecordCommands-CWS2B5IA.js +89 -0
  11. package/agentRunCommand-3FRPISLG.js +102 -0
  12. package/agentRunControl-K4VKNEHF.js +57 -0
  13. package/agentRuntimeLocal-JNQQC2WG.js +99 -0
  14. package/agentSlice-XDFSELFJ.js +41 -0
  15. package/authCommand-WXMD3IPR.js +574 -0
  16. package/authCommands-X74AFDTC.js +26 -0
  17. package/chunk-2EISRLRC.js +238 -0
  18. package/chunk-2FTTDCD4.js +675 -0
  19. package/chunk-2JHWPW5B.js +2127 -0
  20. package/chunk-2LMT6K6N.js +171 -0
  21. package/chunk-2MALU52L.js +51 -0
  22. package/chunk-364VYAX2.js +19 -0
  23. package/chunk-3ASDTTEI.js +1774 -0
  24. package/chunk-3EUW3WEO.js +8 -0
  25. package/chunk-3LY4F7SV.js +9293 -0
  26. package/chunk-4CQLVGRV.js +50 -0
  27. package/chunk-4IJYA27C.js +342 -0
  28. package/chunk-4SN6J65J.js +38 -0
  29. package/chunk-4VNS5WPM.js +42 -0
  30. package/chunk-543C7RDK.js +562 -0
  31. package/chunk-572EKYLF.js +792 -0
  32. package/chunk-5MIDPSSK.js +206 -0
  33. package/chunk-5MMAK75Q.js +15 -0
  34. package/chunk-5XH3NZ4T.js +3631 -0
  35. package/chunk-63W5N6P3.js +150 -0
  36. package/chunk-6HYVJV7B.js +102 -0
  37. package/chunk-6PWWWMI7.js +628 -0
  38. package/chunk-6WD3OOJS.js +20 -0
  39. package/chunk-A3X4Y7MO.js +4294 -0
  40. package/chunk-AR7ZSGDI.js +929 -0
  41. package/chunk-ATNTHIZI.js +13 -0
  42. package/chunk-AUGHVUFE.js +69 -0
  43. package/chunk-AVMKZHBC.js +85 -0
  44. package/chunk-AZPCASRE.js +36 -0
  45. package/chunk-B76D3JJK.js +1447 -0
  46. package/chunk-BR2WP3DF.js +548 -0
  47. package/chunk-BSTNFPHD.js +231 -0
  48. package/chunk-CF2WZF4N.js +134 -0
  49. package/chunk-CF7PE763.js +10 -0
  50. package/chunk-CKOJQDKR.js +198 -0
  51. package/chunk-CM54RSSA.js +206 -0
  52. package/chunk-CWMSB67P.js +34 -0
  53. package/chunk-DA2OEKS6.js +27 -0
  54. package/chunk-DFFIZ25G.js +30 -0
  55. package/chunk-DWLEOOGR.js +8 -0
  56. package/chunk-DZ3XJVET.js +231 -0
  57. package/chunk-E5HMHIKL.js +222 -0
  58. package/chunk-EHLHSX7R.js +1433 -0
  59. package/chunk-ELRRLDWI.js +478 -0
  60. package/chunk-EYEEHCU4.js +3066 -0
  61. package/chunk-G3SUCT4W.js +8 -0
  62. package/chunk-G5H7RNFL.js +807 -0
  63. package/chunk-GAKEBQD6.js +30 -0
  64. package/chunk-GBRG75BQ.js +86 -0
  65. package/chunk-GEKCOPTN.js +190 -0
  66. package/chunk-H2RMRZJE.js +113 -0
  67. package/chunk-H33743XH.js +25 -0
  68. package/chunk-HEIIIZBX.js +104 -0
  69. package/chunk-HNMXYYJR.js +12 -0
  70. package/chunk-IAXBCTTE.js +175 -0
  71. package/chunk-IDZTNRP2.js +85 -0
  72. package/chunk-IECI4YHR.js +421 -0
  73. package/chunk-ISNCLGUZ.js +146 -0
  74. package/chunk-IYQV26RA.js +138 -0
  75. package/chunk-JBTJAPUF.js +35 -0
  76. package/chunk-JZPBVBIY.js +94 -0
  77. package/chunk-KK6SWS5B.js +1078 -0
  78. package/chunk-KQHGZWSV.js +63 -0
  79. package/chunk-KTI2WDDG.js +24674 -0
  80. package/chunk-KUG52IAP.js +8 -0
  81. package/chunk-KX6YBIHG.js +8 -0
  82. package/chunk-LCBAMY2M.js +60 -0
  83. package/chunk-LM25IZBJ.js +902 -0
  84. package/chunk-LM6IYQ3F.js +16 -0
  85. package/chunk-M76ECQRD.js +13658 -0
  86. package/chunk-MRC4Q34M.js +188 -0
  87. package/chunk-NE3E3XJ2.js +936 -0
  88. package/chunk-NXZGF7F7.js +2878 -0
  89. package/chunk-OF5H3QWS.js +300 -0
  90. package/chunk-OLZBQWZU.js +6 -0
  91. package/chunk-OVGXXUVI.js +91 -0
  92. package/chunk-OWOHNGCN.js +50 -0
  93. package/chunk-PN7AFLOK.js +3401 -0
  94. package/chunk-QSJ3HFEF.js +8 -0
  95. package/chunk-QYXLLLGL.js +4519 -0
  96. package/chunk-ROWQEJRP.js +139 -0
  97. package/chunk-S7Z2HMCN.js +25 -0
  98. package/chunk-SL3EPWB4.js +1949 -0
  99. package/chunk-TDIQFT2F.js +301 -0
  100. package/chunk-TILFE6LV.js +381 -0
  101. package/chunk-U4TRT5V4.js +246 -0
  102. package/chunk-U6VC4MU4.js +8 -0
  103. package/chunk-UAD2WT54.js +64 -0
  104. package/chunk-USZDUWOV.js +191 -0
  105. package/chunk-USZMK5UT.js +105 -0
  106. package/chunk-UVPF33PW.js +46995 -0
  107. package/chunk-V2F4OGYM.js +9013 -0
  108. package/chunk-VEJLAVTC.js +2052 -0
  109. package/chunk-VF4K2QE6.js +21 -0
  110. package/chunk-VHBWHNVT.js +59 -0
  111. package/chunk-VIDPVFP3.js +20 -0
  112. package/chunk-VP4WJWKW.js +8882 -0
  113. package/chunk-VQ2AJRGD.js +148 -0
  114. package/chunk-W4NVOSFF.js +37 -0
  115. package/chunk-WWC7I6TA.js +8 -0
  116. package/chunk-X7W4TNB4.js +1550 -0
  117. package/chunk-XDVAYP26.js +537 -0
  118. package/chunk-XKIMRZO2.js +221 -0
  119. package/chunk-Y5GCAMGP.js +9 -0
  120. package/chunk-YD43KPCK.js +360 -0
  121. package/chunk-YIJFUVKA.js +34 -0
  122. package/chunk-Z4NR32XR.js +50 -0
  123. package/chunk-ZNFJWEN4.js +56 -0
  124. package/cliExecutor-DNE7TCC4.js +36 -0
  125. package/clipboardy-BVE3LVEH.js +12001 -0
  126. package/createAgentAutomationAction-3QTGNYJC.js +864 -0
  127. package/createDialogAction-5YX3ARBK.js +52 -0
  128. package/createPageAction-EQNQQRCW.js +169 -0
  129. package/db-HCJ5PRB5.js +271 -0
  130. package/dbSlice-C4UJLRZP.js +59 -0
  131. package/deleteFile-4SKGPHOZ.js +41 -0
  132. package/dialogCommands-AOQS23FV.js +59 -0
  133. package/dialogSlice-GZE3NCMC.js +146 -0
  134. package/docCreateCommands-GVOQVJON.js +215 -0
  135. package/docDeleteCommands-GEB7YAUZ.js +176 -0
  136. package/docReadCommands-XYKI2DF2.js +129 -0
  137. package/docStore-MLM5AME5.js +96 -0
  138. package/docUpdateCommands-4L3RAMHZ.js +313 -0
  139. package/fetchMessages-JOCYIFKL.js +16 -0
  140. package/getPricing-PWPJ6MNV.js +30 -0
  141. package/handleSendMessageAction-WG2GKTGZ.js +183 -0
  142. package/index.js +188 -113035
  143. package/localDialogRead-D3BELSTF.js +26 -0
  144. package/localFirstLog-DHNOY2NA.js +19 -0
  145. package/localRuntimeAuthority-TEGCOWX4.js +471 -0
  146. package/localRuntimeDb-LGDF6FQP.js +12 -0
  147. package/machineCommands-ZNXKLH6Q.js +774 -0
  148. package/machineInfo-M6KB6HZN.js +10 -0
  149. package/machineWsRunDispatch-7WRG6HNV.js +105 -0
  150. package/memoryCommands-O4MIPIWQ.js +476 -0
  151. package/models-XLEOET3E.js +9 -0
  152. package/offlineMarxistsAgentCommand-BCPJITJL.js +242 -0
  153. package/package.json +3 -25
  154. package/read-RIJCIVKX.js +17 -0
  155. package/readDocTool-GZD2N3LO.js +16 -0
  156. package/readlineWorkspace-AQURUDN4.js +5357 -0
  157. package/removeDialogAgentAction-CXLST3N6.js +72 -0
  158. package/runAgentClientLoop-VQUEKGA5.js +288 -0
  159. package/runtimeDoctorCommands-LRHLPDRC.js +289 -0
  160. package/setDialogExtraReferencesAction-LP6VYGU7.js +59 -0
  161. package/setPrimaryDialogAgentAction-D3GGH23T.js +79 -0
  162. package/settingSlice-J4I3Z5H7.js +198 -0
  163. package/skillSummaryMarker-42HKSXYY.js +9 -0
  164. package/slateToRenderMarkdown-Y5IYN73U.js +7 -0
  165. package/slateUtils-2M7MUTWX.js +19 -0
  166. package/spaceCommands-R2RXD5UY.js +450 -0
  167. package/spaceSlice-5UT4JNIN.js +145 -0
  168. package/streamAgentChatTurn-NRWSQKFN.js +4503 -0
  169. package/tableCommands-66XEWHAK.js +1286 -0
  170. package/toolApiClient-QI3YBNWB.js +26 -0
  171. package/tools-TNMUDDRK.js +83 -0
  172. package/understanding-HCSFPE7R.js +318 -0
  173. package/updateCommands-VOSPKXFF.js +31 -0
  174. package/updateDialogTitleAction-IXOKAVX3.js +185 -0
@@ -0,0 +1,146 @@
1
+ import {
2
+ DEFAULT_NOLO_SERVER_URL
3
+ } from "./chunk-OLZBQWZU.js";
4
+ import {
5
+ DEFAULT_LOCAL_API_ORIGIN
6
+ } from "./chunk-4SN6J65J.js";
7
+ import {
8
+ NOLO_CLUSTER_SERVERS
9
+ } from "./chunk-LCBAMY2M.js";
10
+ import {
11
+ normalizeServerOrigin
12
+ } from "./chunk-CF7PE763.js";
13
+ import {
14
+ asOptionalTrimmedString
15
+ } from "./chunk-G3SUCT4W.js";
16
+
17
+ // packages/cli/cliEnvHelpers.ts
18
+ import { dirname, extname, join } from "node:path";
19
+ import { fileURLToPath } from "node:url";
20
+ function resolveServerUrlFromEnv(env) {
21
+ return normalizeServerOrigin(
22
+ env.NOLO_SERVER || env.BASE_URL || DEFAULT_NOLO_SERVER_URL
23
+ );
24
+ }
25
+ function isCliArgs(value) {
26
+ return Array.isArray(value);
27
+ }
28
+ function buildServerCandidates(values) {
29
+ return [...new Set(
30
+ values.filter((value) => typeof value === "string" && value.trim().length > 0).map((value) => normalizeServerOrigin(value))
31
+ )];
32
+ }
33
+ function resolveServerUrl(input, env) {
34
+ if (isCliArgs(input)) {
35
+ const explicit = readOption(input, "--server-url") || readOption(input, "--server");
36
+ return normalizeServerOrigin(explicit) || resolveServerUrlFromEnv(env ?? {});
37
+ }
38
+ return resolveServerUrlFromEnv(input);
39
+ }
40
+ function resolveServerCandidates(input, envOrPreferred, preferred) {
41
+ if (isCliArgs(input)) {
42
+ const env2 = envOrPreferred ?? {};
43
+ const explicitServer = resolveServerUrl(input, env2);
44
+ return buildServerCandidates([
45
+ explicitServer,
46
+ preferred?.trim(),
47
+ env2.NOLO_SERVER,
48
+ env2.BASE_URL,
49
+ env2.NOLO_SERVER_URL,
50
+ DEFAULT_NOLO_SERVER_URL,
51
+ ...NOLO_CLUSTER_SERVERS
52
+ ]);
53
+ }
54
+ const env = input;
55
+ return buildServerCandidates([
56
+ asOptionalTrimmedString(envOrPreferred),
57
+ env.NOLO_SERVER,
58
+ env.BASE_URL,
59
+ env.NOLO_SERVER_URL,
60
+ DEFAULT_NOLO_SERVER_URL,
61
+ ...NOLO_CLUSTER_SERVERS
62
+ ]);
63
+ }
64
+ function resolveDeleteServerCandidatesFromEnv(env, ...preferredValues) {
65
+ return buildServerCandidates([
66
+ ...preferredValues,
67
+ env.NOLO_SERVER,
68
+ env.BASE_URL,
69
+ env.NOLO_SERVER_URL,
70
+ env.READ_DIALOG_BASE,
71
+ DEFAULT_NOLO_SERVER_URL,
72
+ ...NOLO_CLUSTER_SERVERS,
73
+ DEFAULT_LOCAL_API_ORIGIN
74
+ ]);
75
+ }
76
+ function resolveDeleteServerCandidates(input, envOrPreferred, preferred) {
77
+ if (isCliArgs(input)) {
78
+ const env2 = envOrPreferred ?? {};
79
+ const explicitServer = resolveServerUrl(input, env2);
80
+ return resolveDeleteServerCandidatesFromEnv(env2, explicitServer, preferred?.trim());
81
+ }
82
+ const env = input;
83
+ return resolveDeleteServerCandidatesFromEnv(
84
+ env,
85
+ asOptionalTrimmedString(envOrPreferred)
86
+ );
87
+ }
88
+ function resolveAuthTokenFromEnv(env, extraEnvKeys = []) {
89
+ for (const key of ["AUTH_TOKEN", "AUTH", ...extraEnvKeys]) {
90
+ const value = env[key];
91
+ if (typeof value === "string" && value.trim()) return value;
92
+ }
93
+ return "";
94
+ }
95
+ function resolveAuthToken(input, envOrExtraEnvKeys, extraEnvKeys = []) {
96
+ if (isCliArgs(input)) {
97
+ const env = envOrExtraEnvKeys ?? {};
98
+ return readOption(input, "--token") || readOption(input, "--machine-key") || resolveAuthTokenFromEnv(env, extraEnvKeys);
99
+ }
100
+ return resolveAuthTokenFromEnv(input, envOrExtraEnvKeys ?? []);
101
+ }
102
+ function parseUserIdFromAuthToken(token) {
103
+ const parts = token.trim().split(".").filter(Boolean);
104
+ const payloadCandidates = parts.length >= 3 ? [parts[1], parts[0]] : [parts[0]];
105
+ for (const payload of payloadCandidates) {
106
+ if (!payload) continue;
107
+ try {
108
+ const parsed = JSON.parse(Buffer.from(payload, "base64").toString("utf8"));
109
+ if (typeof parsed?.userId === "string") return parsed.userId;
110
+ } catch {
111
+ }
112
+ }
113
+ return "";
114
+ }
115
+ function readOption(args, flag) {
116
+ const index = args.indexOf(flag);
117
+ return index >= 0 ? args[index + 1] : void 0;
118
+ }
119
+ function isCompiledBinary() {
120
+ try {
121
+ const url = import.meta.url;
122
+ return url.startsWith("file:///$bunfs/root/") || url.startsWith("/$bunfs/root/");
123
+ } catch {
124
+ return false;
125
+ }
126
+ }
127
+ function resolveCliEntrypointPath(fromModuleUrl = import.meta.url) {
128
+ if (isCompiledBinary()) {
129
+ return process.execPath;
130
+ }
131
+ const sourcePath = fileURLToPath(fromModuleUrl);
132
+ const ext = extname(sourcePath) || ".ts";
133
+ return join(dirname(sourcePath), "..", `index${ext}`);
134
+ }
135
+
136
+ export {
137
+ resolveServerUrl,
138
+ resolveServerCandidates,
139
+ resolveDeleteServerCandidates,
140
+ resolveAuthTokenFromEnv,
141
+ resolveAuthToken,
142
+ parseUserIdFromAuthToken,
143
+ readOption,
144
+ isCompiledBinary,
145
+ resolveCliEntrypointPath
146
+ };
@@ -0,0 +1,138 @@
1
+ import {
2
+ selectCurrentServer
3
+ } from "./chunk-VEJLAVTC.js";
4
+ import {
5
+ patch
6
+ } from "./chunk-G5H7RNFL.js";
7
+ import {
8
+ selectIdentityToken
9
+ } from "./chunk-EYEEHCU4.js";
10
+ import {
11
+ getIsDesktopApp
12
+ } from "./chunk-QYXLLLGL.js";
13
+
14
+ // packages/ai/agent/cliChatClient.ts
15
+ function getCliChatRequestConfig(thunkApi) {
16
+ const state = thunkApi.getState();
17
+ const currentServer = selectCurrentServer(state);
18
+ const token = selectIdentityToken(state);
19
+ if (!currentServer) throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5F53\u524D\u670D\u52A1\u5668\u5730\u5740\u3002");
20
+ return { currentServer, token };
21
+ }
22
+ function resolveCliChatUrl(currentServer) {
23
+ if (getIsDesktopApp()) return "/api/cli/chat";
24
+ return `${currentServer}/api/cli/chat`;
25
+ }
26
+ async function postCliChat(thunkApi, body, signal) {
27
+ const { currentServer, token } = getCliChatRequestConfig(thunkApi);
28
+ return fetch(resolveCliChatUrl(currentServer), {
29
+ method: "POST",
30
+ headers: {
31
+ "Content-Type": "application/json",
32
+ ...token ? { Authorization: `Bearer ${token}` } : {}
33
+ },
34
+ body: JSON.stringify(body),
35
+ signal
36
+ });
37
+ }
38
+ async function startCliChatSession(thunkApi, args) {
39
+ const response = await postCliChat(thunkApi, {
40
+ action: "start",
41
+ cliProvider: args.cliProvider,
42
+ model: args.model,
43
+ systemPrompt: args.systemPrompt,
44
+ reasoningEffort: args.reasoningEffort,
45
+ temperature: args.temperature,
46
+ topP: args.topP,
47
+ frequencyPenalty: args.frequencyPenalty,
48
+ presencePenalty: args.presencePenalty,
49
+ maxTokens: args.maxTokens,
50
+ enableThinking: args.enableThinking,
51
+ thinkingBudget: args.thinkingBudget
52
+ });
53
+ return response.json();
54
+ }
55
+ async function getCliChatSession(thunkApi, args) {
56
+ const response = await postCliChat(thunkApi, {
57
+ action: "get",
58
+ sessionId: args.sessionId
59
+ });
60
+ return response.json();
61
+ }
62
+ async function closeCliChatSession(thunkApi, args) {
63
+ const response = await postCliChat(thunkApi, {
64
+ action: "close",
65
+ sessionId: args.sessionId
66
+ });
67
+ return response.json();
68
+ }
69
+ function createCliChatTurnStream(thunkApi, args, signal) {
70
+ return postCliChat(
71
+ thunkApi,
72
+ args.sessionId ? {
73
+ action: "turn",
74
+ sessionId: args.sessionId,
75
+ prompt: args.prompt,
76
+ model: args.model,
77
+ reasoningEffort: args.reasoningEffort,
78
+ temperature: args.temperature,
79
+ topP: args.topP,
80
+ frequencyPenalty: args.frequencyPenalty,
81
+ presencePenalty: args.presencePenalty,
82
+ maxTokens: args.maxTokens,
83
+ enableThinking: args.enableThinking,
84
+ thinkingBudget: args.thinkingBudget
85
+ } : {
86
+ prompt: args.prompt,
87
+ model: args.model,
88
+ cliProvider: args.cliProvider,
89
+ systemPrompt: args.systemPrompt,
90
+ reasoningEffort: args.reasoningEffort,
91
+ temperature: args.temperature,
92
+ topP: args.topP,
93
+ frequencyPenalty: args.frequencyPenalty,
94
+ presencePenalty: args.presencePenalty,
95
+ maxTokens: args.maxTokens,
96
+ enableThinking: args.enableThinking,
97
+ thinkingBudget: args.thinkingBudget
98
+ },
99
+ signal
100
+ );
101
+ }
102
+
103
+ // packages/chat/dialog/actions/cleanupCliSession.ts
104
+ async function cleanupCliSessionForDialog(thunkApi, dialogConfig) {
105
+ const cliSessionId = dialogConfig?.cliSessionId;
106
+ const dialogKey = dialogConfig?.dbKey;
107
+ if (!cliSessionId || !dialogKey) return;
108
+ try {
109
+ await closeCliChatSession(
110
+ { getState: thunkApi.getState },
111
+ { sessionId: cliSessionId }
112
+ );
113
+ } catch {
114
+ }
115
+ try {
116
+ const patchResult = thunkApi.dispatch(
117
+ patch({
118
+ dbKey: dialogKey,
119
+ changes: {
120
+ cliSessionId: null
121
+ }
122
+ })
123
+ );
124
+ if (typeof patchResult?.unwrap === "function") {
125
+ await patchResult.unwrap();
126
+ } else {
127
+ await patchResult;
128
+ }
129
+ } catch {
130
+ }
131
+ }
132
+
133
+ export {
134
+ startCliChatSession,
135
+ getCliChatSession,
136
+ createCliChatTurnStream,
137
+ cleanupCliSessionForDialog
138
+ };
@@ -0,0 +1,35 @@
1
+ // packages/connector-experimental/codexBinary.ts
2
+ import { copyFileSync, existsSync, mkdirSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { dirname, join } from "node:path";
5
+ var WINDOWS_APPS_CODEX_PATTERN = /\\WindowsApps\\OpenAI\.Codex_[^\\]+\\app\\resources$/i;
6
+ function pathEntries(env) {
7
+ return (env.PATH ?? process.env.PATH ?? "").split(process.platform === "win32" ? ";" : ":");
8
+ }
9
+ function findWindowsAppsCodex(env) {
10
+ if (process.platform !== "win32") return "";
11
+ for (const entry of pathEntries(env)) {
12
+ if (!WINDOWS_APPS_CODEX_PATTERN.test(entry)) continue;
13
+ const candidate = join(entry, "codex.exe");
14
+ if (existsSync(candidate)) return candidate;
15
+ }
16
+ return "";
17
+ }
18
+ function copyCodexToUserBin(source, env) {
19
+ const target = env.NOLO_CODEX_SHIM_PATH ?? join(homedir(), ".nolo", "bin", "codex.exe");
20
+ if (existsSync(target)) return target;
21
+ mkdirSync(dirname(target), { recursive: true });
22
+ copyFileSync(source, target);
23
+ return target;
24
+ }
25
+ function resolveLaunchableCodexCommand(env = process.env) {
26
+ const explicit = env.NOLO_CODEX_BIN?.trim();
27
+ if (explicit) return explicit;
28
+ const windowsAppsCodex = findWindowsAppsCodex(env);
29
+ if (windowsAppsCodex) return copyCodexToUserBin(windowsAppsCodex, env);
30
+ return "codex";
31
+ }
32
+
33
+ export {
34
+ resolveLaunchableCodexCommand
35
+ };
@@ -0,0 +1,94 @@
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 { homedir } from "node:os";
11
+ import { join } from "node:path";
12
+ var DEFAULT_REFRESH_SKEW_MS = 5 * 60 * 1e3;
13
+ function getCredentialsDir(homeDir = homedir()) {
14
+ return join(homeDir, ".nolo", "credentials");
15
+ }
16
+ function getCredentialPath(provider, homeDir = homedir()) {
17
+ return join(getCredentialsDir(homeDir), `${provider}.json`);
18
+ }
19
+ function ensurePrivateDir(dir) {
20
+ mkdirSync(dir, { recursive: true, mode: 448 });
21
+ try {
22
+ chmodSync(dir, 448);
23
+ } catch {
24
+ }
25
+ }
26
+ function writePrivateFile(path, body) {
27
+ writeFileSync(path, body, { encoding: "utf8", mode: 384 });
28
+ try {
29
+ chmodSync(path, 384);
30
+ } catch {
31
+ }
32
+ }
33
+ function readOAuthCredential(provider, homeDir = homedir()) {
34
+ const path = getCredentialPath(provider, homeDir);
35
+ if (!existsSync(path)) return null;
36
+ const raw = readFileSync(path, "utf8");
37
+ try {
38
+ const parsed = JSON.parse(raw);
39
+ if (!parsed?.provider || !parsed?.accessToken) return null;
40
+ return parsed;
41
+ } catch {
42
+ return null;
43
+ }
44
+ }
45
+ function writeOAuthCredential(provider, credential, homeDir = homedir()) {
46
+ const path = getCredentialPath(provider, homeDir);
47
+ ensurePrivateDir(getCredentialsDir(homeDir));
48
+ writePrivateFile(path, `${JSON.stringify(credential, null, 2)}
49
+ `);
50
+ }
51
+ function removeOAuthCredential(provider, homeDir = homedir()) {
52
+ const path = getCredentialPath(provider, homeDir);
53
+ if (!existsSync(path)) return;
54
+ unlinkSync(path);
55
+ }
56
+ function createOAuthTokenStore(homeDir = homedir()) {
57
+ return {
58
+ read(provider) {
59
+ return readOAuthCredential(provider, homeDir);
60
+ },
61
+ write(provider, credential) {
62
+ writeOAuthCredential(provider, credential, homeDir);
63
+ },
64
+ remove(provider) {
65
+ removeOAuthCredential(provider, homeDir);
66
+ }
67
+ };
68
+ }
69
+ function isTokenExpired(credential, skewMs = DEFAULT_REFRESH_SKEW_MS, now = Date.now()) {
70
+ if (!credential.expiresAt) return false;
71
+ return credential.expiresAt - now <= skewMs;
72
+ }
73
+ async function resolveFreshAccessToken(args) {
74
+ const store = args.store ?? createOAuthTokenStore(args.homeDir);
75
+ const now = args.now ?? Date.now;
76
+ const credential = store.read(args.provider);
77
+ if (!credential) return null;
78
+ if (!args.force && !isTokenExpired(credential, args.skewMs ?? DEFAULT_REFRESH_SKEW_MS, now())) {
79
+ return credential.accessToken;
80
+ }
81
+ if (!credential.refreshToken || !args.refresh) return null;
82
+ const refreshed = await args.refresh(credential);
83
+ store.write(args.provider, refreshed);
84
+ return refreshed.accessToken;
85
+ }
86
+
87
+ export {
88
+ getCredentialsDir,
89
+ readOAuthCredential,
90
+ writeOAuthCredential,
91
+ createOAuthTokenStore,
92
+ isTokenExpired,
93
+ resolveFreshAccessToken
94
+ };