@agentdocumentformat/cli 0.7.8 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +1 -1
  2. package/dist/adf.mjs +59 -8
  3. package/dist/chunks/{APEv2Parser-2CNNHMXV.mjs → APEv2Parser-WIXRJLHB.mjs} +2 -2
  4. package/dist/chunks/{AiffParser-7BR4RL6G.mjs → AiffParser-ZC4QFOVJ.mjs} +5 -5
  5. package/dist/chunks/{App-7RIIOHJJ.mjs → App-4AZZJNN2.mjs} +917 -826
  6. package/dist/chunks/{DsdiffParser-CMD4AX7A.mjs → DsdiffParser-UAPAJHFX.mjs} +5 -5
  7. package/dist/chunks/{DsfParser-UOGZDS2M.mjs → DsfParser-NNYZK2QX.mjs} +6 -6
  8. package/dist/chunks/{FlacParser-HB3T3CD4.mjs → FlacParser-MW2W4LO3.mjs} +6 -6
  9. package/dist/chunks/{MP4Parser-66HBRUSX.mjs → MP4Parser-Z57SYOOQ.mjs} +4 -4
  10. package/dist/chunks/{MpegParser-YW6LIUEW.mjs → MpegParser-XIIPAZVM.mjs} +7 -7
  11. package/dist/chunks/{MusepackParser-PAUSXP7D.mjs → MusepackParser-QWNDEYHJ.mjs} +6 -6
  12. package/dist/chunks/{OggParser-NUBV3GWC.mjs → OggParser-WRX53F77.mjs} +9 -9
  13. package/dist/chunks/{WavPackParser-WQAGT7TC.mjs → WavPackParser-MJ7WCSJ5.mjs} +2 -2
  14. package/dist/chunks/{WaveParser-EWLQVDX4.mjs → WaveParser-RAVLHZ5S.mjs} +7 -7
  15. package/dist/chunks/{adf-schema-US4NFHMR.mjs → adf-schema-AIPBQTR2.mjs} +9 -3
  16. package/dist/chunks/auth-manager-AJ32FZWS.mjs +19 -0
  17. package/dist/chunks/auth-manager-C5OBEQK2.mjs +18 -0
  18. package/dist/chunks/auth-manager-TBNKCJ45.mjs +17 -0
  19. package/dist/chunks/{chatgpt-subscription-E4MXTIAT.mjs → chatgpt-subscription-MMGNW5KJ.mjs} +5 -2
  20. package/dist/chunks/chunk-2Z7X3UUR.mjs +678 -0
  21. package/dist/chunks/chunk-3UGZFWIF.mjs +26 -0
  22. package/dist/chunks/{chunk-XNPZBLYL.mjs → chunk-75DC5EWN.mjs} +13 -2
  23. package/dist/chunks/{chunk-5PO5PKRV.mjs → chunk-7JZXMDDF.mjs} +158 -67
  24. package/dist/chunks/chunk-AEAJDCVK.mjs +517 -0
  25. package/dist/chunks/{chunk-6VQEXLE2.mjs → chunk-BHY7QDCM.mjs} +41 -3
  26. package/dist/chunks/{chunk-CD3ATSXE.mjs → chunk-BR3AD5QZ.mjs} +8 -2
  27. package/dist/chunks/chunk-BS3USVEA.mjs +301 -0
  28. package/dist/chunks/chunk-C2S64Y6F.mjs +203 -0
  29. package/dist/chunks/chunk-D7A77SNL.mjs +976 -0
  30. package/dist/chunks/chunk-DDTTSKGG.mjs +2443 -0
  31. package/dist/chunks/{chunk-VAUOM3IN.mjs → chunk-DLWCKKIO.mjs} +1 -1
  32. package/dist/chunks/{chunk-G6PH7RPW.mjs → chunk-E7LC6SHP.mjs} +3 -3
  33. package/dist/chunks/{chunk-ZESQMP66.mjs → chunk-F3WSCAJD.mjs} +3 -3
  34. package/dist/chunks/{chunk-KXEF4F4E.mjs → chunk-GAZO6UMI.mjs} +1 -1
  35. package/dist/chunks/{chunk-XYTWGHFS.mjs → chunk-H3XLRWVE.mjs} +1 -1
  36. package/dist/chunks/{chunk-7T2YMTWL.mjs → chunk-H4C65MTP.mjs} +4 -4
  37. package/dist/chunks/chunk-HBOFZRUS.mjs +738 -0
  38. package/dist/chunks/{chunk-VN7UH7I5.mjs → chunk-IMVMSU3A.mjs} +251 -68
  39. package/dist/chunks/{chunk-XYV3VCIX.mjs → chunk-JZFONJSL.mjs} +79 -20
  40. package/dist/chunks/chunk-KCIRFUZH.mjs +12799 -0
  41. package/dist/chunks/chunk-KDDVQKCG.mjs +65 -0
  42. package/dist/chunks/chunk-KRPKWOMB.mjs +290 -0
  43. package/dist/chunks/chunk-LKFHERRV.mjs +145 -0
  44. package/dist/chunks/chunk-LTX74NU6.mjs +29 -0
  45. package/dist/chunks/{chunk-HSBV6YFU.mjs → chunk-LVF2DRBR.mjs} +634 -99
  46. package/dist/chunks/chunk-M2F7C2UJ.mjs +425 -0
  47. package/dist/chunks/{chunk-62NE4LG4.mjs → chunk-MQAMI5BF.mjs} +5 -5
  48. package/dist/chunks/chunk-MZRXFWPQ.mjs +278 -0
  49. package/dist/chunks/{chunk-PRMGZZM5.mjs → chunk-NZLEPJ5M.mjs} +2 -0
  50. package/dist/chunks/{chunk-I3UYSITV.mjs → chunk-O7XKQ6CH.mjs} +1 -1
  51. package/dist/chunks/chunk-P3RG5LQA.mjs +244 -0
  52. package/dist/chunks/chunk-PAK5JCO2.mjs +48 -0
  53. package/dist/chunks/chunk-PC63YFB7.mjs +34 -0
  54. package/dist/chunks/{daemon-control-HKFVSQTQ.mjs → chunk-RHBGCOS3.mjs} +67 -26
  55. package/dist/chunks/{chunk-J74STFKE.mjs → chunk-RJDOVMM4.mjs} +362 -58
  56. package/dist/chunks/{chunk-QPLEAE6V.mjs → chunk-SOSPQPEN.mjs} +167 -650
  57. package/dist/chunks/{chunk-LFMB4PAA.mjs → chunk-TKXIH27X.mjs} +974 -113
  58. package/dist/chunks/{chunk-5W7KES6P.mjs → chunk-UZPDETEU.mjs} +1 -1
  59. package/dist/chunks/chunk-V3MM6PCH.mjs +366 -0
  60. package/dist/chunks/chunk-VENQBMOA.mjs +62 -0
  61. package/dist/chunks/chunk-WJGPNHGX.mjs +67 -0
  62. package/dist/chunks/{chunk-Y5ZLKFLE.mjs → chunk-XNNJQCZP.mjs} +196 -165
  63. package/dist/chunks/{chunk-HDBPBORT.mjs → chunk-YRBFIDLB.mjs} +46 -10
  64. package/dist/chunks/{chunk-BNXUAOO4.mjs → chunk-ZGXUOAWZ.mjs} +3186 -959
  65. package/dist/chunks/chunk-ZPB3HYM7.mjs +45 -0
  66. package/dist/chunks/claude-subscription-EB4LAAVV.mjs +29 -0
  67. package/dist/chunks/{cli-NMFIAR7Z.mjs → cli-PCVFB6B4.mjs} +797 -56
  68. package/dist/chunks/{commands-KPJWFRUE.mjs → commands-KOMPXJZS.mjs} +4 -3
  69. package/dist/chunks/{daemon-YDIK3AAM.mjs → daemon-BVDB565V.mjs} +83142 -64424
  70. package/dist/chunks/daemon-control-MKN7G5M3.mjs +59 -0
  71. package/dist/chunks/{daemon-token-WRSULP7G.mjs → daemon-token-L5QKTHU5.mjs} +3 -1
  72. package/dist/chunks/{discord-DSP4HUWI.mjs → discord-IR62565M.mjs} +3 -52
  73. package/dist/chunks/{email-BRG7KUO2.mjs → email-KHHTJBDW.mjs} +4 -2
  74. package/dist/chunks/{grok-subscription-4PYX7TBF.mjs → grok-subscription-E74FS5EG.mjs} +5 -2
  75. package/dist/chunks/{layout-EPJQNFAI.mjs → layout-ECWGJF6M.mjs} +2 -2
  76. package/dist/chunks/{lib-N7FCZWKH.mjs → lib-L27L5PXM.mjs} +22 -22
  77. package/dist/chunks/{open-VAU7PXT6.mjs → open-3OR6WT4T.mjs} +6 -6
  78. package/dist/chunks/{parser-JVY2PWSM.mjs → parser-7GARNT5L.mjs} +1 -1
  79. package/dist/chunks/{pipeline-executor-O77NTGLP.mjs → pipeline-executor-DRYEEFDR.mjs} +6 -5
  80. package/dist/chunks/prompt-RRHZX4YT.mjs +13 -0
  81. package/dist/chunks/remote-access-cli-GLEEP7DI.mjs +268 -0
  82. package/dist/chunks/remote-hello-UFWUBDQI.mjs +37 -0
  83. package/dist/chunks/sdk-OJOAF4DP.mjs +30014 -0
  84. package/dist/chunks/{slack-OCNNF4DX.mjs → slack-IYC5RAB5.mjs} +3 -4
  85. package/dist/chunks/{store-HUVDJPYN.mjs → store-55CQSAOX.mjs} +7 -3
  86. package/dist/chunks/tailscale-WLJATFMB.mjs +25 -0
  87. package/dist/chunks/{theme-SFE3JMA2.mjs → theme-HLBDTF6F.mjs} +1 -1
  88. package/dist/chunks/{themes-YLXLOIJF.mjs → themes-BQ72P446.mjs} +2 -2
  89. package/dist/chunks/{token-6G3HCMNX.mjs → token-6D22WECM.mjs} +20 -16
  90. package/dist/chunks/{token-util-UXYSDQIW.mjs → token-util-YF3ZWBZ4.mjs} +1 -2
  91. package/dist/chunks/{tui-UQJLK7XI.mjs → tui-RAUVFOYY.mjs} +21 -18
  92. package/dist/chunks/{welcome-XHXFV7SH.mjs → welcome-J5JZZAM5.mjs} +1 -1
  93. package/dist/chunks/{whatsapp-AJMRQBT7.mjs → whatsapp-YJFFVN4Q.mjs} +9 -9
  94. package/package.json +1 -1
  95. package/dist/chunks/chunk-GKKCMXIZ.mjs +0 -94
  96. package/dist/chunks/chunk-IHDDCZBS.mjs +0 -112
  97. package/dist/chunks/chunk-KWFOS5WC.mjs +0 -41
  98. package/dist/chunks/chunk-UEZR2CNS.mjs +0 -65
  99. package/dist/chunks/chunk-VMHTYDH4.mjs +0 -172
  100. package/dist/chunks/chunk-Y2QA53AN.mjs +0 -259
  101. package/dist/chunks/{chunk-NBTUWMGP.mjs → chunk-2MTE22CR.mjs} +3 -3
  102. package/dist/chunks/{chunk-APRU6PHC.mjs → chunk-JZ7AQNPM.mjs} +3 -3
  103. package/dist/chunks/{telegram-2EFGKIVK.mjs → telegram-JYY2VDTI.mjs} +5 -5
@@ -0,0 +1,65 @@
1
+ import { createRequire as __adfCreateRequire } from 'node:module';
2
+ import { fileURLToPath as __adfFileURLToPath } from 'node:url';
3
+ import { dirname as __adfDirname } from 'node:path';
4
+ const require = __adfCreateRequire(import.meta.url);
5
+ const __filename = __adfFileURLToPath(import.meta.url);
6
+ const __dirname = __adfDirname(__filename);
7
+ import {
8
+ __commonJS
9
+ } from "./chunk-M2RX3S2T.mjs";
10
+
11
+ // node_modules/fast-deep-equal/es6/index.js
12
+ var require_es6 = __commonJS({
13
+ "node_modules/fast-deep-equal/es6/index.js"(exports, module) {
14
+ "use strict";
15
+ module.exports = function equal(a, b) {
16
+ if (a === b) return !0;
17
+ if (a && b && typeof a == "object" && typeof b == "object") {
18
+ if (a.constructor !== b.constructor) return !1;
19
+ var length, i, keys;
20
+ if (Array.isArray(a)) {
21
+ if (length = a.length, length != b.length) return !1;
22
+ for (i = length; i-- !== 0; )
23
+ if (!equal(a[i], b[i])) return !1;
24
+ return !0;
25
+ }
26
+ if (a instanceof Map && b instanceof Map) {
27
+ if (a.size !== b.size) return !1;
28
+ for (i of a.entries())
29
+ if (!b.has(i[0])) return !1;
30
+ for (i of a.entries())
31
+ if (!equal(i[1], b.get(i[0]))) return !1;
32
+ return !0;
33
+ }
34
+ if (a instanceof Set && b instanceof Set) {
35
+ if (a.size !== b.size) return !1;
36
+ for (i of a.entries())
37
+ if (!b.has(i[0])) return !1;
38
+ return !0;
39
+ }
40
+ if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {
41
+ if (length = a.length, length != b.length) return !1;
42
+ for (i = length; i-- !== 0; )
43
+ if (a[i] !== b[i]) return !1;
44
+ return !0;
45
+ }
46
+ if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
47
+ if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
48
+ if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
49
+ if (keys = Object.keys(a), length = keys.length, length !== Object.keys(b).length) return !1;
50
+ for (i = length; i-- !== 0; )
51
+ if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return !1;
52
+ for (i = length; i-- !== 0; ) {
53
+ var key = keys[i];
54
+ if (!equal(a[key], b[key])) return !1;
55
+ }
56
+ return !0;
57
+ }
58
+ return a !== a && b !== b;
59
+ };
60
+ }
61
+ });
62
+
63
+ export {
64
+ require_es6
65
+ };
@@ -0,0 +1,290 @@
1
+ import { createRequire as __adfCreateRequire } from 'node:module';
2
+ import { fileURLToPath as __adfFileURLToPath } from 'node:url';
3
+ import { dirname as __adfDirname } from 'node:path';
4
+ const require = __adfCreateRequire(import.meta.url);
5
+ const __filename = __adfFileURLToPath(import.meta.url);
6
+ const __dirname = __adfDirname(__filename);
7
+ import {
8
+ startCallbackServer
9
+ } from "./chunk-2NAP2ZF7.mjs";
10
+ import {
11
+ createSubscriptionTokenStore
12
+ } from "./chunk-C2S64Y6F.mjs";
13
+ import {
14
+ __require
15
+ } from "./chunk-M2RX3S2T.mjs";
16
+
17
+ // src/main/providers/chatgpt-subscription/auth-manager.ts
18
+ import crypto from "crypto";
19
+
20
+ // src/main/providers/chatgpt-subscription/token-store.ts
21
+ var store = createSubscriptionTokenStore("chatgpt-subscription");
22
+ function readTokens() {
23
+ return store.readTokens();
24
+ }
25
+ function writeTokens(tokens) {
26
+ store.writeTokens(tokens);
27
+ }
28
+ function clearTokens() {
29
+ store.clearTokens();
30
+ }
31
+ function noteSignIn(accountId) {
32
+ store.signedIn(accountId);
33
+ }
34
+
35
+ // src/main/providers/chatgpt-subscription/auth-manager.ts
36
+ var CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann", AUTH_URL = "https://auth.openai.com/oauth/authorize", TOKEN_URL = "https://auth.openai.com/oauth/token", SCOPE = "openid profile email offline_access api.connectors.read api.connectors.invoke", REFRESH_BUFFER_MS = 300 * 1e3, RELAY_FLOW_TTL_MS = 600 * 1e3;
37
+ function base64url(buf) {
38
+ return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
39
+ }
40
+ function generateCodeVerifier() {
41
+ let bytes = crypto.getRandomValues(new Uint8Array(64));
42
+ return base64url(Buffer.from(bytes));
43
+ }
44
+ function generateCodeChallenge(verifier) {
45
+ let hash = crypto.createHash("sha256").update(verifier).digest();
46
+ return base64url(hash);
47
+ }
48
+ function generateState() {
49
+ return base64url(Buffer.from(crypto.getRandomValues(new Uint8Array(32))));
50
+ }
51
+ function decodeJwtPayload(token) {
52
+ let parts = token.split(".");
53
+ if (parts.length < 2) return {};
54
+ try {
55
+ let payload = Buffer.from(parts[1], "base64url").toString("utf-8");
56
+ return JSON.parse(payload);
57
+ } catch {
58
+ return {};
59
+ }
60
+ }
61
+ function chatgptAccountIdFromJwt(token) {
62
+ if (!token) return "";
63
+ let claims = decodeJwtPayload(token), auth = claims["https://api.openai.com/auth"], id = (auth && typeof auth == "object" ? auth.chatgpt_account_id : void 0) ?? claims.chatgpt_account_id;
64
+ return typeof id == "string" ? id : "";
65
+ }
66
+ async function openExternal(url) {
67
+ try {
68
+ let electron = __require("electron");
69
+ if (electron.shell?.openExternal) {
70
+ await electron.shell.openExternal(url);
71
+ return;
72
+ }
73
+ } catch {
74
+ }
75
+ console.log(`[ChatGPT Auth] Open this URL to sign in: ${url}`);
76
+ }
77
+ function assertLoopbackRedirect(redirectUri) {
78
+ let parsed;
79
+ try {
80
+ parsed = new URL(redirectUri);
81
+ } catch {
82
+ throw new Error(`Invalid redirectUri: ${redirectUri}`);
83
+ }
84
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
85
+ throw new Error("redirectUri must be an http(s) URL");
86
+ if (!["localhost", "127.0.0.1", "[::1]", "::1"].includes(parsed.hostname))
87
+ throw new Error("redirectUri must target localhost \u2014 the OAuth callback runs on the machine with the browser");
88
+ }
89
+ var ChatGptAuthManager = class {
90
+ refreshPromise = null;
91
+ cachedTokens = null;
92
+ email;
93
+ activeAuthFlow = null;
94
+ relayFlows = /* @__PURE__ */ new Map();
95
+ constructor() {
96
+ this.syncFromDisk();
97
+ }
98
+ /**
99
+ * Re-read the token file, picking up writes from other processes.
100
+ *
101
+ * Each surface has its own file (see subscription-token-store), but several
102
+ * processes can share one — e.g. an installed and a dev Studio, or a CLI
103
+ * next to its daemon — and OpenAI rotates the refresh token on every
104
+ * refresh, so acting on a cached copy can invalidate a sibling's session. Always reading is what prevents that; the file is
105
+ * well under a kilobyte and this runs once per LLM request.
106
+ */
107
+ syncFromDisk() {
108
+ let tokens = readTokens();
109
+ return tokens?.access_token !== this.cachedTokens?.access_token && (this.email = void 0), this.cachedTokens = tokens, tokens;
110
+ }
111
+ persist(tokens) {
112
+ writeTokens(tokens), this.cachedTokens = tokens;
113
+ }
114
+ async startAuthFlow() {
115
+ await (await this.startAuthFlowDetached()).completion;
116
+ }
117
+ async startAuthFlowDetached() {
118
+ if (this.activeAuthFlow) return this.activeAuthFlow;
119
+ let codeVerifier = generateCodeVerifier(), codeChallenge = generateCodeChallenge(codeVerifier), state = generateState(), server = await startCallbackServer(), redirectUri = `http://localhost:${server.port}/auth/callback`, params = new URLSearchParams({
120
+ client_id: CLIENT_ID,
121
+ redirect_uri: redirectUri,
122
+ response_type: "code",
123
+ code_challenge: codeChallenge,
124
+ code_challenge_method: "S256",
125
+ state,
126
+ scope: SCOPE,
127
+ id_token_add_organizations: "true",
128
+ codex_cli_simplified_flow: "true",
129
+ originator: "adf_studio"
130
+ }), authUrl = `${AUTH_URL}?${params.toString()}`;
131
+ await openExternal(authUrl);
132
+ let completion = (async () => {
133
+ try {
134
+ let result = await server.waitForCallback();
135
+ if (result.state !== state)
136
+ throw new Error("OAuth state mismatch \u2014 possible CSRF attack");
137
+ await this.exchangeCode(result.code, codeVerifier, redirectUri);
138
+ } finally {
139
+ server.close(), this.activeAuthFlow = null;
140
+ }
141
+ })();
142
+ return this.activeAuthFlow = { authUrl, callbackPort: server.port, completion }, this.activeAuthFlow;
143
+ }
144
+ /**
145
+ * Begin a sign-in whose OAuth callback lands on the *caller's* machine rather
146
+ * than on this process.
147
+ *
148
+ * The loopback flow assumes the browser and the token store share a host.
149
+ * That breaks for a daemon on a remote box: `http://localhost:1455` in the
150
+ * user's browser reaches their laptop, not the daemon. Here the daemon keeps
151
+ * the PKCE verifier, the caller runs its own callback server, and the caller
152
+ * posts the code back via `completeRelayAuthFlow`.
153
+ */
154
+ startRelayAuthFlow(redirectUri) {
155
+ assertLoopbackRedirect(redirectUri), this.pruneRelayFlows();
156
+ let codeVerifier = generateCodeVerifier(), state = generateState(), flowId = base64url(Buffer.from(crypto.getRandomValues(new Uint8Array(24)))), expiresAt = Date.now() + RELAY_FLOW_TTL_MS, params = new URLSearchParams({
157
+ client_id: CLIENT_ID,
158
+ redirect_uri: redirectUri,
159
+ response_type: "code",
160
+ code_challenge: generateCodeChallenge(codeVerifier),
161
+ code_challenge_method: "S256",
162
+ state,
163
+ scope: SCOPE,
164
+ id_token_add_organizations: "true",
165
+ codex_cli_simplified_flow: "true",
166
+ originator: "adf_studio"
167
+ });
168
+ return this.relayFlows.set(flowId, { codeVerifier, state, redirectUri, expiresAt }), { flowId, authUrl: `${AUTH_URL}?${params.toString()}`, state, expiresAt };
169
+ }
170
+ /** Finish a relay flow with the code the caller's callback server received. */
171
+ async completeRelayAuthFlow(flowId, code, state) {
172
+ this.pruneRelayFlows();
173
+ let flow = this.relayFlows.get(flowId);
174
+ if (!flow)
175
+ throw new Error("Unknown or expired auth flow \u2014 start sign-in again");
176
+ if (this.relayFlows.delete(flowId), state !== flow.state)
177
+ throw new Error("OAuth state mismatch \u2014 possible CSRF attack");
178
+ await this.exchangeCode(code, flow.codeVerifier, flow.redirectUri);
179
+ }
180
+ pruneRelayFlows() {
181
+ let now = Date.now();
182
+ for (let [id, flow] of this.relayFlows)
183
+ flow.expiresAt <= now && this.relayFlows.delete(id);
184
+ }
185
+ /** Trade an authorization code for tokens and persist them. */
186
+ async exchangeCode(code, codeVerifier, redirectUri) {
187
+ let tokenResponse = await fetch(TOKEN_URL, {
188
+ method: "POST",
189
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
190
+ body: new URLSearchParams({
191
+ grant_type: "authorization_code",
192
+ client_id: CLIENT_ID,
193
+ code,
194
+ redirect_uri: redirectUri,
195
+ code_verifier: codeVerifier
196
+ }).toString()
197
+ });
198
+ if (!tokenResponse.ok) {
199
+ let body = await tokenResponse.text();
200
+ throw new Error(`Token exchange failed (${tokenResponse.status}): ${body}`);
201
+ }
202
+ let tokenData = await tokenResponse.json();
203
+ tokenData.id_token && (this.email = decodeJwtPayload(tokenData.id_token).email);
204
+ let accountId = chatgptAccountIdFromJwt(tokenData.access_token) || chatgptAccountIdFromJwt(tokenData.id_token);
205
+ console.log(`[ChatGPT Auth] signed in: email=${this.email}, chatgpt_account_id=${accountId || "(missing)"}`), this.persist({
206
+ access_token: tokenData.access_token,
207
+ refresh_token: tokenData.refresh_token,
208
+ expires_at: Date.now() + tokenData.expires_in * 1e3,
209
+ account_id: accountId
210
+ }), noteSignIn(accountId);
211
+ }
212
+ async getValidAccessToken() {
213
+ let tokens = this.syncFromDisk();
214
+ if (!tokens)
215
+ throw new Error("Not authenticated \u2014 sign in first");
216
+ return Date.now() + REFRESH_BUFFER_MS < tokens.expires_at ? tokens.access_token : this.refreshPromise ? this.refreshPromise : (this.refreshPromise = this.refreshIfStillNeeded(tokens).finally(() => {
217
+ this.refreshPromise = null;
218
+ }), this.refreshPromise);
219
+ }
220
+ getAccountId() {
221
+ let tokens = this.syncFromDisk();
222
+ return chatgptAccountIdFromJwt(tokens?.access_token) || tokens?.account_id || void 0;
223
+ }
224
+ /**
225
+ * Re-check the file after winning the in-process refresh lock.
226
+ *
227
+ * OpenAI rotates the refresh token on every refresh, so if Studio refreshed
228
+ * while this call queued, our copy is already dead and spending it would both
229
+ * fail here and be pointless. Adopt the newer set instead.
230
+ */
231
+ async refreshIfStillNeeded(tokens) {
232
+ let fresh = this.syncFromDisk();
233
+ return fresh && Date.now() + REFRESH_BUFFER_MS < fresh.expires_at ? fresh.access_token : this.refreshTokens(fresh ?? tokens);
234
+ }
235
+ async refreshTokens(tokens) {
236
+ let data, rejected = !1;
237
+ try {
238
+ let response = await fetch(TOKEN_URL, {
239
+ method: "POST",
240
+ headers: { "Content-Type": "application/json" },
241
+ body: JSON.stringify({
242
+ client_id: CLIENT_ID,
243
+ grant_type: "refresh_token",
244
+ refresh_token: tokens.refresh_token
245
+ })
246
+ });
247
+ if (!response.ok)
248
+ throw rejected = response.status === 400 || response.status === 401, new Error(`Token refresh failed (${response.status})`);
249
+ data = await response.json();
250
+ } catch (err) {
251
+ let fresh = this.syncFromDisk();
252
+ if (fresh && fresh.refresh_token !== tokens.refresh_token && Date.now() + REFRESH_BUFFER_MS < fresh.expires_at)
253
+ return fresh.access_token;
254
+ throw rejected ? (clearTokens(), this.cachedTokens = null, this.email = void 0, new Error("Session expired \u2014 please sign in again")) : new Error(`Could not refresh the session (${err instanceof Error ? err.message : String(err)}) \u2014 still signed in, try again`);
255
+ }
256
+ if (data.id_token) {
257
+ let claims = decodeJwtPayload(data.id_token);
258
+ this.email = claims.email;
259
+ }
260
+ return this.persist({
261
+ access_token: data.access_token,
262
+ refresh_token: data.refresh_token,
263
+ expires_at: Date.now() + data.expires_in * 1e3,
264
+ account_id: chatgptAccountIdFromJwt(data.access_token) || chatgptAccountIdFromJwt(data.id_token) || tokens.account_id
265
+ }), data.access_token;
266
+ }
267
+ getAuthStatus() {
268
+ let tokens = this.syncFromDisk();
269
+ return tokens ? {
270
+ authenticated: !0,
271
+ email: this.email,
272
+ expiresAt: tokens.expires_at
273
+ } : { authenticated: !1 };
274
+ }
275
+ isAuthenticated() {
276
+ return this.syncFromDisk() !== null;
277
+ }
278
+ logout() {
279
+ clearTokens(), this.cachedTokens = null, this.email = void 0, this.refreshPromise = null, this.relayFlows.clear();
280
+ }
281
+ }, instance = null;
282
+ function getChatGptAuthManager() {
283
+ return instance || (instance = new ChatGptAuthManager()), instance;
284
+ }
285
+
286
+ export {
287
+ readTokens,
288
+ chatgptAccountIdFromJwt,
289
+ getChatGptAuthManager
290
+ };
@@ -0,0 +1,145 @@
1
+ import { createRequire as __adfCreateRequire } from 'node:module';
2
+ import { fileURLToPath as __adfFileURLToPath } from 'node:url';
3
+ import { dirname as __adfDirname } from 'node:path';
4
+ const require = __adfCreateRequire(import.meta.url);
5
+ const __filename = __adfFileURLToPath(import.meta.url);
6
+ const __dirname = __adfDirname(__filename);
7
+ import {
8
+ __export
9
+ } from "./chunk-M2RX3S2T.mjs";
10
+
11
+ // src/shared/utils/file-ref.ts
12
+ var file_ref_exports = {};
13
+ __export(file_ref_exports, {
14
+ adfFileUrl: () => adfFileUrl,
15
+ applyFileRefChanges: () => applyFileRefChanges,
16
+ attachmentMetadata: () => attachmentMetadata,
17
+ attachmentText: () => attachmentText,
18
+ attachmentsOf: () => attachmentsOf,
19
+ deletedFilePlaceholder: () => deletedFilePlaceholder,
20
+ displayAttachment: () => displayAttachment,
21
+ fileRefKind: () => fileRefKind,
22
+ fileRefName: () => fileRefName,
23
+ fileRefText: () => fileRefText,
24
+ isAudioInputMime: () => isAudioInputMime,
25
+ isFileRefBlock: () => isFileRefBlock,
26
+ isVideoInputMime: () => isVideoInputMime,
27
+ isVisionMime: () => isVisionMime,
28
+ mediaKindOfMime: () => mediaKindOfMime,
29
+ splitLegacyUploads: () => splitLegacyUploads
30
+ });
31
+ var VISION_MIMES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/gif", "image/webp"]), AUDIO_INPUT_MIMES = /* @__PURE__ */ new Set([
32
+ "audio/wav",
33
+ "audio/mpeg",
34
+ "audio/mp3",
35
+ "audio/aiff",
36
+ "audio/aac",
37
+ "audio/ogg",
38
+ "audio/flac",
39
+ "audio/x-m4a",
40
+ "audio/webm"
41
+ ]), VIDEO_INPUT_MIMES = /* @__PURE__ */ new Set(["video/mp4", "video/mpeg", "video/quicktime", "video/webm"]);
42
+ function isVisionMime(mime) {
43
+ return !!mime && VISION_MIMES.has(mime);
44
+ }
45
+ function isAudioInputMime(mime) {
46
+ return !!mime && AUDIO_INPUT_MIMES.has(mime);
47
+ }
48
+ function isVideoInputMime(mime) {
49
+ return !!mime && VIDEO_INPUT_MIMES.has(mime);
50
+ }
51
+ function mediaKindOfMime(mime) {
52
+ if (isVisionMime(mime)) return "image";
53
+ if (isAudioInputMime(mime)) return "audio";
54
+ if (isVideoInputMime(mime)) return "video";
55
+ }
56
+ function isFileRefBlock(block) {
57
+ return block.type === "file_ref" && !!block.file_ref && typeof block.file_ref.path == "string";
58
+ }
59
+ function fileRefKind(ref) {
60
+ return mediaKindOfMime(ref.mime_type);
61
+ }
62
+ function fileRefName(ref) {
63
+ let segments = ref.path.split("/");
64
+ return segments[segments.length - 1] || ref.path;
65
+ }
66
+ function deletedFilePlaceholder(ref) {
67
+ return `[deleted: ${fileRefName(ref)}]`;
68
+ }
69
+ function adfFileUrl(path) {
70
+ return `adf-file://${path.split("/").map(encodeURIComponent).join("/")}`;
71
+ }
72
+ function displayAttachment(ref) {
73
+ let kind = fileRefKind(ref);
74
+ return {
75
+ path: ref.path,
76
+ name: fileRefName(ref),
77
+ mime_type: ref.mime_type,
78
+ ...kind ? { kind } : {},
79
+ ...ref.deleted ? { deleted: !0 } : {}
80
+ };
81
+ }
82
+ function attachmentsOf(blocks) {
83
+ let out = [];
84
+ for (let block of blocks) isFileRefBlock(block) && out.push(displayAttachment(block.file_ref));
85
+ return out;
86
+ }
87
+ function attachmentMetadata(content, previews = []) {
88
+ let attachments = attachmentsOf(content);
89
+ if (!(attachments.length === 0 && previews.length === 0))
90
+ return { ...previews.length > 0 ? { imagePreviewUrls: previews } : {}, ...attachments.length > 0 ? { attachments } : {} };
91
+ }
92
+ function attachmentText(a) {
93
+ return a.deleted ? deletedFilePlaceholder(a) : `[${a.kind ?? "file"}: ${a.name}]`;
94
+ }
95
+ var LEGACY_UPLOAD_LINE = /^\[Uploaded file: .+ \(([^,()]+), [^()]+\)\. Use fs_read with path "(.+)" to inspect it\.\]$/;
96
+ function splitLegacyUploads(text) {
97
+ if (!text.includes("[Uploaded file: ")) return { text, attachments: [] };
98
+ let attachments = [], kept = [];
99
+ for (let line of text.split(`
100
+ `)) {
101
+ let match = LEGACY_UPLOAD_LINE.exec(line.trim());
102
+ if (!match) {
103
+ kept.push(line);
104
+ continue;
105
+ }
106
+ let kind = mediaKindOfMime(match[1]);
107
+ attachments.push({ path: match[2], name: fileRefName({ path: match[2] }), mime_type: match[1], ...kind ? { kind } : {} });
108
+ }
109
+ return { text: kept.join(`
110
+ `).trim(), attachments };
111
+ }
112
+ function fileRefText(ref) {
113
+ return ref.deleted ? deletedFilePlaceholder(ref) : `[${fileRefKind(ref) ?? "file"}: ${ref.path}]`;
114
+ }
115
+ function applyFileRefChanges(blocks, changes) {
116
+ let out = null;
117
+ for (let i = 0; i < blocks.length; i++) {
118
+ let block = blocks[i];
119
+ if (!isFileRefBlock(block) || block.file_ref.deleted) continue;
120
+ let ref = block.file_ref;
121
+ for (let change of changes) {
122
+ if (ref.deleted) break;
123
+ change.op === "rename" && ref.path === change.from ? ref = { ...ref, path: change.to } : change.op === "delete" && ref.path === change.path && (ref = { ...ref, deleted: !0 });
124
+ }
125
+ ref !== block.file_ref && (out ??= blocks.slice(), out[i] = { ...block, file_ref: ref });
126
+ }
127
+ return out ?? blocks;
128
+ }
129
+
130
+ export {
131
+ isVisionMime,
132
+ isAudioInputMime,
133
+ isVideoInputMime,
134
+ mediaKindOfMime,
135
+ isFileRefBlock,
136
+ fileRefKind,
137
+ fileRefName,
138
+ deletedFilePlaceholder,
139
+ displayAttachment,
140
+ attachmentsOf,
141
+ splitLegacyUploads,
142
+ fileRefText,
143
+ applyFileRefChanges,
144
+ file_ref_exports
145
+ };
@@ -0,0 +1,29 @@
1
+ import { createRequire as __adfCreateRequire } from 'node:module';
2
+ import { fileURLToPath as __adfFileURLToPath } from 'node:url';
3
+ import { dirname as __adfDirname } from 'node:path';
4
+ const require = __adfCreateRequire(import.meta.url);
5
+ const __filename = __adfFileURLToPath(import.meta.url);
6
+ const __dirname = __adfDirname(__filename);
7
+
8
+ // src/main/utils/secret-file.ts
9
+ import { execFileSync } from "node:child_process";
10
+ import { chmodSync } from "node:fs";
11
+ import { userInfo } from "node:os";
12
+ function restrictToCurrentUserWindows(path, run = (file, args) => {
13
+ execFileSync(file, args, { windowsHide: !0, stdio: ["ignore", "ignore", "pipe"] });
14
+ }) {
15
+ let user = process.env.USERDOMAIN && process.env.USERNAME ? `${process.env.USERDOMAIN}\\${process.env.USERNAME}` : userInfo().username;
16
+ run("icacls", [path, "/inheritance:r", "/grant:r", `${user}:F`]);
17
+ }
18
+ function protectSecretFile(path, opts = {}) {
19
+ try {
20
+ return (opts.platform ?? process.platform) === "win32" ? restrictToCurrentUserWindows(path, opts.run) : chmodSync(path, 384), !0;
21
+ } catch (err) {
22
+ return console.warn(`[SecretFile] Could not restrict ${path} to the current user: ${err instanceof Error ? err.message : String(err)}`), !1;
23
+ }
24
+ }
25
+
26
+ export {
27
+ restrictToCurrentUserWindows,
28
+ protectSecretFile
29
+ };