@agentdocumentformat/cli 0.7.8 → 0.8.0

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 (100) 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-A5GUFCFJ.mjs} +279 -293
  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-YJSGLMA4.mjs} +2 -2
  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-3UGZFWIF.mjs +26 -0
  21. package/dist/chunks/{chunk-5PO5PKRV.mjs → chunk-4OGZFUKA.mjs} +126 -67
  22. package/dist/chunks/{chunk-VN7UH7I5.mjs → chunk-6XQZGYMK.mjs} +246 -67
  23. package/dist/chunks/{chunk-XNPZBLYL.mjs → chunk-75DC5EWN.mjs} +13 -2
  24. package/dist/chunks/chunk-AZYOXXVL.mjs +865 -0
  25. package/dist/chunks/{chunk-6VQEXLE2.mjs → chunk-BHY7QDCM.mjs} +41 -3
  26. package/dist/chunks/chunk-C2S64Y6F.mjs +203 -0
  27. package/dist/chunks/chunk-C4GA5SI4.mjs +12799 -0
  28. package/dist/chunks/chunk-DDTTSKGG.mjs +2443 -0
  29. package/dist/chunks/{chunk-VAUOM3IN.mjs → chunk-DLWCKKIO.mjs} +1 -1
  30. package/dist/chunks/{chunk-QPLEAE6V.mjs → chunk-G6NBFYG5.mjs} +152 -824
  31. package/dist/chunks/{chunk-KXEF4F4E.mjs → chunk-GAZO6UMI.mjs} +1 -1
  32. package/dist/chunks/{chunk-XYTWGHFS.mjs → chunk-H3XLRWVE.mjs} +1 -1
  33. package/dist/chunks/{chunk-7T2YMTWL.mjs → chunk-H4C65MTP.mjs} +4 -4
  34. package/dist/chunks/chunk-HBOFZRUS.mjs +738 -0
  35. package/dist/chunks/chunk-JVPZIMXW.mjs +976 -0
  36. package/dist/chunks/{chunk-XYV3VCIX.mjs → chunk-JZFONJSL.mjs} +79 -20
  37. package/dist/chunks/chunk-KDDVQKCG.mjs +65 -0
  38. package/dist/chunks/chunk-KRPKWOMB.mjs +290 -0
  39. package/dist/chunks/{chunk-G6PH7RPW.mjs → chunk-LCMANRYY.mjs} +3 -3
  40. package/dist/chunks/{chunk-ZESQMP66.mjs → chunk-LGL6ML37.mjs} +3 -3
  41. package/dist/chunks/chunk-LKFHERRV.mjs +145 -0
  42. package/dist/chunks/chunk-LTX74NU6.mjs +29 -0
  43. package/dist/chunks/chunk-M2F7C2UJ.mjs +425 -0
  44. package/dist/chunks/{chunk-62NE4LG4.mjs → chunk-MQAMI5BF.mjs} +5 -5
  45. package/dist/chunks/chunk-MZRXFWPQ.mjs +278 -0
  46. package/dist/chunks/{chunk-PRMGZZM5.mjs → chunk-NZLEPJ5M.mjs} +2 -0
  47. package/dist/chunks/{chunk-CD3ATSXE.mjs → chunk-NZO5O4VN.mjs} +1 -1
  48. package/dist/chunks/{chunk-I3UYSITV.mjs → chunk-O7XKQ6CH.mjs} +1 -1
  49. package/dist/chunks/chunk-P3RG5LQA.mjs +244 -0
  50. package/dist/chunks/chunk-PAK5JCO2.mjs +48 -0
  51. package/dist/chunks/chunk-PC63YFB7.mjs +34 -0
  52. package/dist/chunks/{daemon-control-HKFVSQTQ.mjs → chunk-PRPTKMQW.mjs} +67 -26
  53. package/dist/chunks/{chunk-LFMB4PAA.mjs → chunk-TKXIH27X.mjs} +974 -113
  54. package/dist/chunks/{chunk-5W7KES6P.mjs → chunk-UZPDETEU.mjs} +1 -1
  55. package/dist/chunks/chunk-V2T6NZX2.mjs +517 -0
  56. package/dist/chunks/chunk-V3MM6PCH.mjs +366 -0
  57. package/dist/chunks/chunk-WJGPNHGX.mjs +67 -0
  58. package/dist/chunks/chunk-WVTPPOKK.mjs +290 -0
  59. package/dist/chunks/{chunk-J74STFKE.mjs → chunk-WX6QCUWI.mjs} +272 -51
  60. package/dist/chunks/{chunk-Y5ZLKFLE.mjs → chunk-XNNJQCZP.mjs} +196 -165
  61. package/dist/chunks/{chunk-HDBPBORT.mjs → chunk-XT2BJUFC.mjs} +15 -6
  62. package/dist/chunks/{chunk-HSBV6YFU.mjs → chunk-YRMKSHW3.mjs} +614 -92
  63. package/dist/chunks/{chunk-BNXUAOO4.mjs → chunk-ZGXUOAWZ.mjs} +3186 -959
  64. package/dist/chunks/chunk-ZPB3HYM7.mjs +45 -0
  65. package/dist/chunks/claude-subscription-33BMZB6I.mjs +29 -0
  66. package/dist/chunks/{cli-NMFIAR7Z.mjs → cli-I47IFDHJ.mjs} +797 -56
  67. package/dist/chunks/{commands-KPJWFRUE.mjs → commands-E4EQUHE5.mjs} +4 -3
  68. package/dist/chunks/{daemon-YDIK3AAM.mjs → daemon-FQ5BV3AP.mjs} +82058 -63958
  69. package/dist/chunks/daemon-control-L3CLG63P.mjs +59 -0
  70. package/dist/chunks/{daemon-token-WRSULP7G.mjs → daemon-token-L5QKTHU5.mjs} +3 -1
  71. package/dist/chunks/{discord-DSP4HUWI.mjs → discord-IR62565M.mjs} +3 -52
  72. package/dist/chunks/{email-BRG7KUO2.mjs → email-KHHTJBDW.mjs} +4 -2
  73. package/dist/chunks/{grok-subscription-4PYX7TBF.mjs → grok-subscription-E74FS5EG.mjs} +5 -2
  74. package/dist/chunks/{lib-N7FCZWKH.mjs → lib-L27L5PXM.mjs} +22 -22
  75. package/dist/chunks/{open-VAU7PXT6.mjs → open-TLGS2Z3Q.mjs} +4 -4
  76. package/dist/chunks/{parser-JVY2PWSM.mjs → parser-7GARNT5L.mjs} +1 -1
  77. package/dist/chunks/{pipeline-executor-O77NTGLP.mjs → pipeline-executor-FD4FBWQA.mjs} +6 -5
  78. package/dist/chunks/prompt-RRHZX4YT.mjs +13 -0
  79. package/dist/chunks/remote-access-cli-XXAPQWH6.mjs +268 -0
  80. package/dist/chunks/remote-hello-UFWUBDQI.mjs +37 -0
  81. package/dist/chunks/sdk-5FD2ZP7N.mjs +28422 -0
  82. package/dist/chunks/{slack-OCNNF4DX.mjs → slack-IYC5RAB5.mjs} +3 -4
  83. package/dist/chunks/{store-HUVDJPYN.mjs → store-ZRN2WCFB.mjs} +6 -3
  84. package/dist/chunks/tailscale-WLJATFMB.mjs +25 -0
  85. package/dist/chunks/{theme-SFE3JMA2.mjs → theme-HLBDTF6F.mjs} +1 -1
  86. package/dist/chunks/{themes-YLXLOIJF.mjs → themes-BQ72P446.mjs} +2 -2
  87. package/dist/chunks/{token-6G3HCMNX.mjs → token-6D22WECM.mjs} +20 -16
  88. package/dist/chunks/{token-util-UXYSDQIW.mjs → token-util-YF3ZWBZ4.mjs} +1 -2
  89. package/dist/chunks/{tui-UQJLK7XI.mjs → tui-SPSPDADM.mjs} +17 -14
  90. package/dist/chunks/{welcome-XHXFV7SH.mjs → welcome-J5JZZAM5.mjs} +1 -1
  91. package/dist/chunks/{whatsapp-AJMRQBT7.mjs → whatsapp-YJFFVN4Q.mjs} +9 -9
  92. package/package.json +1 -1
  93. package/dist/chunks/chunk-GKKCMXIZ.mjs +0 -94
  94. package/dist/chunks/chunk-IHDDCZBS.mjs +0 -112
  95. package/dist/chunks/chunk-KWFOS5WC.mjs +0 -41
  96. package/dist/chunks/chunk-UEZR2CNS.mjs +0 -65
  97. package/dist/chunks/chunk-VMHTYDH4.mjs +0 -172
  98. package/dist/chunks/chunk-Y2QA53AN.mjs +0 -259
  99. package/dist/chunks/{chunk-NBTUWMGP.mjs → chunk-2MTE22CR.mjs} +3 -3
  100. package/dist/chunks/{telegram-2EFGKIVK.mjs → telegram-JYY2VDTI.mjs} +5 -5
@@ -0,0 +1,278 @@
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/providers/claude-subscription/auth-manager.ts
9
+ import { execFile as execFile2, spawn } from "node:child_process";
10
+
11
+ // src/main/providers/claude-subscription/claude-code.ts
12
+ import { execFile } from "node:child_process";
13
+ import { access, readFile } from "node:fs/promises";
14
+ import { homedir } from "node:os";
15
+ import { delimiter, dirname, join } from "node:path";
16
+ var MIN_CLAUDE_CODE_VERSION = "2.1.248", CLAUDE_CODE_INSTALL_URL = "https://code.claude.com/docs/en/setup", isWindows = process.platform === "win32", exeName = isWindows ? "claude.exe" : "claude";
17
+ async function exists(path) {
18
+ try {
19
+ return await access(path), !0;
20
+ } catch {
21
+ return !1;
22
+ }
23
+ }
24
+ async function candidatePaths() {
25
+ let out = [], override = process.env.ADF_CLAUDE_CODE_PATH;
26
+ override && out.push(override);
27
+ let home = homedir();
28
+ out.push(join(home, ".local", "bin", exeName)), out.push(join(home, ".claude", "local", exeName)), isWindows || out.push("/opt/homebrew/bin/claude", "/usr/local/bin/claude");
29
+ for (let dir of (process.env.PATH ?? "").split(delimiter))
30
+ if (dir)
31
+ if (isWindows) {
32
+ out.push(join(dir, "claude.exe"));
33
+ let target = await resolveNpmShim(join(dir, "claude.cmd"));
34
+ target && out.push(target);
35
+ } else
36
+ out.push(join(dir, "claude"));
37
+ let appData = process.env.APPDATA;
38
+ isWindows && appData && out.push(join(appData, "npm", "node_modules", "@anthropic-ai", "claude-code", "bin", "claude.exe"));
39
+ let unique = [...new Set(out)], present = await Promise.all(unique.map(exists));
40
+ return unique.filter((_, i) => present[i]);
41
+ }
42
+ async function resolveNpmShim(shimPath) {
43
+ try {
44
+ let match = (await readFile(shimPath, "utf8")).match(/"%dp0%\\([^"]+?\.exe)"/i);
45
+ if (!match) return null;
46
+ let target = join(dirname(shimPath), match[1]);
47
+ return await exists(target) ? target : null;
48
+ } catch {
49
+ return null;
50
+ }
51
+ }
52
+ function runVersion(path) {
53
+ return new Promise((resolve) => {
54
+ execFile(path, ["--version"], { timeout: 15e3, windowsHide: !0 }, (err, stdout) => {
55
+ if (err) return resolve(null);
56
+ let match = String(stdout).match(/(\d+\.\d+\.\d+)/);
57
+ resolve(match ? match[1] : null);
58
+ });
59
+ });
60
+ }
61
+ function compareVersions(a, b) {
62
+ let pa = a.split(".").map(Number), pb = b.split(".").map(Number);
63
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
64
+ let d = (pa[i] ?? 0) - (pb[i] ?? 0);
65
+ if (d !== 0) return d < 0 ? -1 : 1;
66
+ }
67
+ return 0;
68
+ }
69
+ var cached = null, inflight = null, CACHE_MS = 6e4;
70
+ async function runProbe() {
71
+ let paths = await candidatePaths(), versions = await Promise.all(paths.map(runVersion)), install = null;
72
+ for (let i = 0; i < paths.length; i++) {
73
+ let version = versions[i];
74
+ version && (!install || compareVersions(version, install.version) > 0) && (install = { path: paths[i], version });
75
+ }
76
+ return install ? { found: !0, install, supported: compareVersions(install.version, MIN_CLAUDE_CODE_VERSION) >= 0 } : { found: !1 };
77
+ }
78
+ function probeClaudeCode(force = !1) {
79
+ if (!force && cached && Date.now() - cached.at < CACHE_MS) return Promise.resolve(cached.probe);
80
+ if (!force && inflight) return inflight;
81
+ let run = runProbe().then((probe) => (cached = { probe, at: Date.now() }, probe)).finally(() => {
82
+ inflight === run && (inflight = null);
83
+ });
84
+ return inflight = run, run;
85
+ }
86
+ async function requireClaudeCode() {
87
+ let probe = await probeClaudeCode();
88
+ if (!probe.found)
89
+ throw new Error(`Claude Code is not installed. Install it (${CLAUDE_CODE_INSTALL_URL}), then sign in with Claude.`);
90
+ if (!probe.supported)
91
+ throw new Error(
92
+ `Claude Code ${probe.install.version} is installed; ADF needs ${MIN_CLAUDE_CODE_VERSION} or newer. Run \`claude update\`.`
93
+ );
94
+ return probe.install;
95
+ }
96
+ var CLAUDE_ENV_DENY = /^(CLAUDE_CODE_|ANTHROPIC_|CLAUDECODE$)/i;
97
+ function claudeCodeEnv(extra) {
98
+ let env = {};
99
+ for (let [k, v] of Object.entries(process.env))
100
+ v === void 0 || CLAUDE_ENV_DENY.test(k) || k.toUpperCase() === "ELECTRON_RUN_AS_NODE" || (env[k] = v);
101
+ return { ...env, ...extra };
102
+ }
103
+
104
+ // src/main/providers/claude-subscription/auth-manager.ts
105
+ var LOGIN_TIMEOUT_MS = 10 * 6e4, STATUS_CACHE_MS = 3e4;
106
+ function stripAnsi(s) {
107
+ return s.replace(/\u001b\][^\u0007\u001b]*(?:\u0007|\u001b\\)/g, "").replace(/\u001b\[[0-9;?]*[ -/]*[@-~]/g, "");
108
+ }
109
+ function extractLoginUrl(output) {
110
+ return output.match(/https:\/\/[^\s\u0007\u001b"']+\/oauth\/authorize\?[^\s\u0007\u001b"']+/)?.[0];
111
+ }
112
+ function runCli(path, args, timeoutMs = 2e4) {
113
+ return new Promise((resolve) => {
114
+ execFile2(path, args, { timeout: timeoutMs, windowsHide: !0, env: claudeCodeEnv() }, (err, stdout, stderr) => {
115
+ let code = err ? typeof err.code == "number" ? err.code : 1 : 0;
116
+ resolve({ stdout: String(stdout), stderr: String(stderr), code });
117
+ });
118
+ });
119
+ }
120
+ var ClaudeAuthManager = class {
121
+ active = null;
122
+ starting = null;
123
+ startGen = 0;
124
+ lastFlowError;
125
+ statusCache = null;
126
+ statusInflight = null;
127
+ statusGen = 0;
128
+ /**
129
+ * Claude Code's sign-in state. `claude auth status` is a process spawn and
130
+ * this is polled by every status view and agent preflight, so results are
131
+ * cached briefly and concurrent callers share one read. While a sign-in is
132
+ * pending nothing is cached. `fresh` re-detects Claude Code and re-reads.
133
+ */
134
+ getAuthStatus(opts) {
135
+ let fresh = opts?.fresh === !0;
136
+ if (!fresh && !this.active && this.statusCache && Date.now() - this.statusCache.at < STATUS_CACHE_MS)
137
+ return Promise.resolve(this.statusCache.status);
138
+ if (!fresh && this.statusInflight) return this.statusInflight;
139
+ let gen = this.statusGen, run = this.readAuthStatus(fresh).then((status) => (gen === this.statusGen && !this.active && !("flowPending" in status && status.flowPending) && (this.statusCache = { status, at: Date.now() }), status)).finally(() => {
140
+ this.statusInflight === run && (this.statusInflight = null);
141
+ });
142
+ return this.statusInflight = run, run;
143
+ }
144
+ invalidateStatus() {
145
+ this.statusGen++, this.statusCache = null, this.statusInflight = null;
146
+ }
147
+ async readAuthStatus(fresh) {
148
+ let probe = await probeClaudeCode(fresh);
149
+ if (!probe.found)
150
+ return { authenticated: !1, installed: !1, installUrl: CLAUDE_CODE_INSTALL_URL };
151
+ let { version: installed, path } = probe.install, version = { version: installed, minVersion: MIN_CLAUDE_CODE_VERSION };
152
+ if (!probe.supported)
153
+ return {
154
+ authenticated: !1,
155
+ installed: !0,
156
+ ...version,
157
+ updateRequired: !0,
158
+ flowError: `Claude Code ${installed} is installed; ADF needs ${MIN_CLAUDE_CODE_VERSION} or newer. Run \`claude update\`.`
159
+ };
160
+ let { stdout } = await runCli(path, ["auth", "status", "--json"]), pending = this.active ? { flowPending: !0, ...this.active.url ? { flowUrl: this.active.url } : {} } : {}, cli = {};
161
+ try {
162
+ cli = JSON.parse(stdout);
163
+ } catch {
164
+ }
165
+ return cli.loggedIn ? cli.authMethod !== "claude.ai" ? {
166
+ authenticated: !1,
167
+ installed: !0,
168
+ ...version,
169
+ ...pending,
170
+ flowError: "Claude Code is signed in with an Anthropic Console account, not a Claude plan. Sign in with Claude to use your subscription."
171
+ } : {
172
+ authenticated: !0,
173
+ installed: !0,
174
+ ...version,
175
+ ...pending,
176
+ // A failed re-sign-in (e.g. switching accounts) leaves the old account
177
+ // signed in; report the failure so callers don't mistake it for success.
178
+ ...this.lastFlowError ? { flowError: this.lastFlowError } : {},
179
+ ...cli.email ? { email: cli.email } : {},
180
+ ...cli.subscriptionType ? { plan: cli.subscriptionType } : {}
181
+ } : { authenticated: !1, installed: !0, ...version, ...pending, ...this.lastFlowError ? { flowError: this.lastFlowError } : {} };
182
+ }
183
+ async isAuthenticated() {
184
+ return (await this.getAuthStatus()).authenticated;
185
+ }
186
+ /**
187
+ * Start `claude auth login`. Claude Code opens the browser itself; the
188
+ * returned URL is the fallback for when it cannot (remote daemon, headless
189
+ * box). If the browser page shows a code instead of finishing on its own,
190
+ * the user pastes it and it is handed to Claude Code via `submitCode`.
191
+ */
192
+ startAuthFlowDetached() {
193
+ if (this.active) return this.active.ready;
194
+ if (!this.starting) {
195
+ let starting = this.spawnFlow().finally(() => {
196
+ this.starting === starting && (this.starting = null);
197
+ });
198
+ this.starting = starting;
199
+ }
200
+ return this.starting;
201
+ }
202
+ async spawnFlow() {
203
+ let gen = this.startGen, { path } = await requireClaudeCode();
204
+ if (gen !== this.startGen) throw new Error("Claude sign-in was cancelled.");
205
+ this.lastFlowError = void 0;
206
+ let child = spawn(path, ["auth", "login", "--claudeai"], {
207
+ stdio: ["pipe", "pipe", "pipe"],
208
+ windowsHide: !0,
209
+ env: claudeCodeEnv()
210
+ }), resolveUrl, urlReady = new Promise((r) => {
211
+ resolveUrl = r;
212
+ }), state = { child, output: "", cancelled: !1, ready: void 0 }, onData = (d) => {
213
+ state.output += d.toString();
214
+ let url = extractLoginUrl(state.output);
215
+ url && (state.url ??= url, resolveUrl(url));
216
+ };
217
+ child.stdout.on("data", onData), child.stderr.on("data", onData);
218
+ let completion = new Promise((resolve, reject) => {
219
+ let timer = setTimeout(() => {
220
+ child.kill(), reject(new Error("Claude sign-in timed out. Try again."));
221
+ }, LOGIN_TIMEOUT_MS);
222
+ child.on("error", (err) => {
223
+ clearTimeout(timer), resolveUrl(void 0), reject(err);
224
+ }), child.on("exit", (code) => {
225
+ if (clearTimeout(timer), resolveUrl(void 0), code === 0) return resolve();
226
+ if (state.cancelled) return reject(new Error("Claude sign-in was cancelled."));
227
+ let tail = stripAnsi(state.output).trim().split(`
228
+ `).filter(Boolean).pop();
229
+ reject(new Error(tail && !/paste code/i.test(tail) ? `Claude sign-in failed: ${tail}` : "Claude sign-in was cancelled."));
230
+ });
231
+ }).then(
232
+ () => {
233
+ this.active === state && (this.active = null), this.invalidateStatus();
234
+ },
235
+ (err) => {
236
+ throw this.active === state && (this.active = null, state.cancelled || (this.lastFlowError = err instanceof Error ? err.message : String(err))), this.invalidateStatus(), err;
237
+ }
238
+ );
239
+ return completion.catch(() => {
240
+ }), state.ready = Promise.race([urlReady, new Promise((r) => setTimeout(() => r(void 0), 15e3))]).then((url) => ({ url, completion })), this.active = state, this.invalidateStatus(), state.ready;
241
+ }
242
+ async startAuthFlow() {
243
+ await (await this.startAuthFlowDetached()).completion;
244
+ }
245
+ /** Hand the code shown on Claude's sign-in page to the waiting Claude Code. */
246
+ submitCode(code) {
247
+ let trimmed = code.trim();
248
+ if (!this.active) throw new Error("No Claude sign-in is in progress.");
249
+ if (!trimmed) throw new Error("Paste the code shown on the Claude sign-in page.");
250
+ this.active.child.stdin.write(`${trimmed}
251
+ `);
252
+ }
253
+ cancelAuthFlow() {
254
+ this.startGen++, this.starting = null, this.active && (this.active.cancelled = !0, this.active.child.kill(), this.active = null), this.invalidateStatus();
255
+ }
256
+ /** Signs Claude Code out on this machine (shared with the user's own Claude Code use). */
257
+ async logout() {
258
+ this.cancelAuthFlow(), this.lastFlowError = void 0;
259
+ try {
260
+ let { path } = await requireClaudeCode(), { code, stderr } = await runCli(path, ["auth", "logout"]);
261
+ if (code !== 0) throw new Error(`Claude sign-out failed: ${stripAnsi(stderr).trim() || `exit ${code}`}`);
262
+ } finally {
263
+ this.invalidateStatus();
264
+ }
265
+ }
266
+ }, instance = null;
267
+ function getClaudeAuthManager() {
268
+ return instance || (instance = new ClaudeAuthManager()), instance;
269
+ }
270
+
271
+ export {
272
+ MIN_CLAUDE_CODE_VERSION,
273
+ requireClaudeCode,
274
+ claudeCodeEnv,
275
+ stripAnsi,
276
+ extractLoginUrl,
277
+ getClaudeAuthManager
278
+ };
@@ -71,6 +71,7 @@ var import_react = __toESM(require_react(), 1), ADF_COLORS = {
71
71
  mark: "\u258C",
72
72
  hbar: "\u2500",
73
73
  ellipsis: "\u2026",
74
+ approx: "\u2248",
74
75
  collapsed: "\u25B8",
75
76
  expanded: "\u25BE",
76
77
  spinner: ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"]
@@ -90,6 +91,7 @@ var import_react = __toESM(require_react(), 1), ADF_COLORS = {
90
91
  mark: ">",
91
92
  hbar: "-",
92
93
  ellipsis: "...",
94
+ approx: "~",
93
95
  collapsed: "+",
94
96
  expanded: "-",
95
97
  spinner: ["|", "/", "-", "\\"]
@@ -141,7 +141,6 @@ var AGENT_DEFAULTS = {
141
141
  provider: "",
142
142
  model_id: "",
143
143
  temperature: 0.7,
144
- max_tokens: 4096,
145
144
  vision: !1
146
145
  },
147
146
  context: {
@@ -292,6 +291,7 @@ export {
292
291
  META_PROTECTION_LEVELS,
293
292
  FILE_PROTECTION_LEVELS,
294
293
  DEFAULT_TOOLS,
294
+ AUDIT_DEFAULTS,
295
295
  AGENT_DEFAULTS,
296
296
  getDefaultDocumentContent,
297
297
  DEFAULT_MIND_CONTENT,
@@ -32,7 +32,7 @@ function enabledAdapters(config) {
32
32
  return Object.entries(config?.adapters ?? {}).filter(([, c]) => c?.enabled !== !1).map(([type]) => type);
33
33
  }
34
34
  function welcomeFacts(state, extras = EMPTY_EXTRAS) {
35
- let auth = state.auth, signedIn = !!auth?.chatgpt?.authenticated || !!auth?.grok?.authenticated, keyed = (auth?.providers ?? []).some((p) => p.hasApiKey === !0), ids = state.agentOrder.filter((id) => state.agents[id]), messaging = ids.some((id) => enabledAdapters(state.agents[id]?.config).length > 0 || (extras.adapters[id]?.length ?? 0) > 0), tasks = ids.some((id) => {
35
+ let auth = state.auth, signedIn = ["chatgpt", "grok", "claude"].some((p) => !!auth?.[p]?.authenticated), keyed = (auth?.providers ?? []).some((p) => p.hasApiKey === !0), ids = state.agentOrder.filter((id) => state.agents[id]), messaging = ids.some((id) => enabledAdapters(state.agents[id]?.config).length > 0 || (extras.adapters[id]?.length ?? 0) > 0), tasks = ids.some((id) => {
36
36
  let loops = state.agents[id]?.loops ?? [];
37
37
  return loops.some((l) => l.info.name !== "main") || loops.some((l) => l.info.name === "main" && (l.info.entryCount ?? 0) > 0) ? !0 : (extras.timers[id] ?? 0) > 0;
38
38
  });
@@ -0,0 +1,244 @@
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
+ createSubscriptionTokenStore
9
+ } from "./chunk-C2S64Y6F.mjs";
10
+ import {
11
+ __require
12
+ } from "./chunk-M2RX3S2T.mjs";
13
+
14
+ // src/main/providers/grok-subscription/token-store.ts
15
+ var store = createSubscriptionTokenStore("grok-subscription");
16
+ function readTokens() {
17
+ return store.readTokens();
18
+ }
19
+ function writeTokens(tokens) {
20
+ store.writeTokens(tokens);
21
+ }
22
+ function clearTokens() {
23
+ store.clearTokens();
24
+ }
25
+ function noteSignIn(accountId) {
26
+ store.signedIn(accountId);
27
+ }
28
+
29
+ // src/main/providers/grok-subscription/auth-manager.ts
30
+ var CLIENT_ID = "b1a00492-073a-47ea-816f-4c329264a828", DEVICE_AUTHORIZATION_URL = "https://auth.x.ai/oauth2/device/code", TOKEN_URL = "https://auth.x.ai/oauth2/token", DEVICE_CODE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code", SCOPE = "openid profile email offline_access grok-cli:access api:access", REFRESH_BUFFER_MS = 300 * 1e3, POLL_DEFAULT_INTERVAL_MS = 5e3, POLL_MIN_INTERVAL_MS = 1e3, POLL_SLOW_DOWN_INCREMENT_MS = 5e3, POLL_DEFAULT_EXPIRES_MS = 900 * 1e3;
31
+ function decodeJwtPayload(token) {
32
+ let parts = token.split(".");
33
+ if (parts.length < 2) return {};
34
+ try {
35
+ let payload = Buffer.from(parts[1], "base64url").toString("utf-8");
36
+ return JSON.parse(payload);
37
+ } catch {
38
+ return {};
39
+ }
40
+ }
41
+ async function openExternal(url) {
42
+ try {
43
+ let electron = __require("electron");
44
+ if (electron.shell?.openExternal) {
45
+ await electron.shell.openExternal(url);
46
+ return;
47
+ }
48
+ } catch {
49
+ }
50
+ console.log(`[Grok Auth] Open this URL to sign in: ${url}`);
51
+ }
52
+ function positiveSecondsToMs(value, defaultMs) {
53
+ let seconds = Number(value);
54
+ return Number.isFinite(seconds) && seconds > 0 ? seconds * 1e3 : defaultMs;
55
+ }
56
+ async function pollDeviceCodeToken(device, deps = {}) {
57
+ let fetchFn = deps.fetchFn ?? globalThis.fetch, sleep = deps.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms))), now = deps.now ?? (() => Date.now()), deadline = now() + positiveSecondsToMs(device.expires_in, POLL_DEFAULT_EXPIRES_MS), intervalMs = Math.max(
58
+ positiveSecondsToMs(device.interval, POLL_DEFAULT_INTERVAL_MS),
59
+ POLL_MIN_INTERVAL_MS
60
+ );
61
+ for (; now() < deadline; ) {
62
+ let response = await fetchFn(TOKEN_URL, {
63
+ method: "POST",
64
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
65
+ body: new URLSearchParams({
66
+ grant_type: DEVICE_CODE_GRANT_TYPE,
67
+ client_id: CLIENT_ID,
68
+ device_code: device.device_code
69
+ }).toString()
70
+ });
71
+ if (response.ok) return await response.json();
72
+ let body = await response.json().catch(() => ({}));
73
+ if (body.error === "authorization_pending") {
74
+ await sleep(Math.min(intervalMs, Math.max(0, deadline - now())));
75
+ continue;
76
+ }
77
+ if (body.error === "slow_down") {
78
+ intervalMs += POLL_SLOW_DOWN_INCREMENT_MS, await sleep(Math.min(intervalMs, Math.max(0, deadline - now())));
79
+ continue;
80
+ }
81
+ if (body.error === "access_denied" || body.error === "authorization_denied")
82
+ throw new Error("Sign-in was denied");
83
+ if (body.error === "expired_token")
84
+ throw new Error("Device code expired \u2014 please sign in again");
85
+ let detail = body.error_description ?? body.error ?? "";
86
+ throw new Error(`Grok token exchange failed (${response.status})${detail ? `: ${detail}` : ""}`);
87
+ }
88
+ throw new Error("Sign-in timed out \u2014 please try again");
89
+ }
90
+ var GrokAuthManager = class {
91
+ refreshPromise = null;
92
+ cachedTokens = null;
93
+ email;
94
+ activeAuthFlow = null;
95
+ lastFlowError;
96
+ constructor() {
97
+ this.syncFromDisk();
98
+ }
99
+ /**
100
+ * Re-read the token file, picking up writes from the other process. Studio
101
+ * and the daemon share one file. See the ChatGPT manager for the full
102
+ * rationale on why this never trusts a cache.
103
+ */
104
+ syncFromDisk() {
105
+ let tokens = readTokens();
106
+ return tokens?.access_token !== this.cachedTokens?.access_token && (this.email = void 0), this.cachedTokens = tokens, tokens;
107
+ }
108
+ persist(tokens) {
109
+ writeTokens(tokens), this.cachedTokens = tokens;
110
+ }
111
+ async startAuthFlow() {
112
+ await (await this.startAuthFlowDetached()).completion;
113
+ }
114
+ async startAuthFlowDetached() {
115
+ if (this.activeAuthFlow) return this.activeAuthFlow;
116
+ this.lastFlowError = void 0;
117
+ let response = await fetch(DEVICE_AUTHORIZATION_URL, {
118
+ method: "POST",
119
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
120
+ body: new URLSearchParams({
121
+ client_id: CLIENT_ID,
122
+ scope: SCOPE,
123
+ referrer: "adf-studio"
124
+ }).toString()
125
+ });
126
+ if (!response.ok) {
127
+ let body = await response.text().catch(() => "");
128
+ throw new Error(`Grok device code request failed (${response.status})${body ? `: ${body}` : ""}`);
129
+ }
130
+ let device = await response.json();
131
+ if (!device.device_code || !device.user_code || !device.verification_uri)
132
+ throw new Error("Grok device code response is missing device_code / user_code / verification_uri");
133
+ let openUrl = device.verification_uri_complete ?? device.verification_uri;
134
+ await openExternal(openUrl);
135
+ let completion = (async () => {
136
+ try {
137
+ let tokenData = await pollDeviceCodeToken(device), accountId = "";
138
+ if (tokenData.id_token) {
139
+ let claims = decodeJwtPayload(tokenData.id_token);
140
+ this.email = claims.email, accountId = claims.sub ?? "";
141
+ }
142
+ if (accountId || (accountId = decodeJwtPayload(tokenData.access_token).sub ?? ""), !tokenData.refresh_token)
143
+ throw new Error("Grok sign-in did not return a refresh token \u2014 is offline_access granted?");
144
+ this.persist({
145
+ access_token: tokenData.access_token,
146
+ refresh_token: tokenData.refresh_token,
147
+ expires_at: Date.now() + positiveSecondsToMs(tokenData.expires_in, 3600 * 1e3),
148
+ account_id: accountId
149
+ }), noteSignIn(accountId);
150
+ } catch (err) {
151
+ throw this.lastFlowError = err instanceof Error ? err.message : String(err), err;
152
+ } finally {
153
+ this.activeAuthFlow = null;
154
+ }
155
+ })();
156
+ return completion.catch(() => {
157
+ }), this.activeAuthFlow = {
158
+ userCode: device.user_code,
159
+ verificationUri: device.verification_uri,
160
+ verificationUriComplete: device.verification_uri_complete,
161
+ expiresIn: positiveSecondsToMs(device.expires_in, POLL_DEFAULT_EXPIRES_MS) / 1e3,
162
+ completion
163
+ }, this.activeAuthFlow;
164
+ }
165
+ async getValidAccessToken() {
166
+ let tokens = this.syncFromDisk();
167
+ if (!tokens)
168
+ throw new Error("Not authenticated \u2014 sign in first");
169
+ return Date.now() + REFRESH_BUFFER_MS < tokens.expires_at ? tokens.access_token : this.refreshPromise ? this.refreshPromise : (this.refreshPromise = this.refreshIfStillNeeded(tokens).finally(() => {
170
+ this.refreshPromise = null;
171
+ }), this.refreshPromise);
172
+ }
173
+ getAccountId() {
174
+ return this.syncFromDisk()?.account_id;
175
+ }
176
+ /**
177
+ * Re-check the file after winning the in-process refresh lock — Studio may
178
+ * have refreshed while this call queued, and xAI may rotate the refresh
179
+ * token, which would leave our copy dead.
180
+ */
181
+ async refreshIfStillNeeded(tokens) {
182
+ let fresh = this.syncFromDisk();
183
+ return fresh && Date.now() + REFRESH_BUFFER_MS < fresh.expires_at ? fresh.access_token : this.refreshTokens(fresh ?? tokens);
184
+ }
185
+ async refreshTokens(tokens) {
186
+ let data, rejected = !1;
187
+ try {
188
+ let response = await fetch(TOKEN_URL, {
189
+ method: "POST",
190
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
191
+ body: new URLSearchParams({
192
+ grant_type: "refresh_token",
193
+ client_id: CLIENT_ID,
194
+ refresh_token: tokens.refresh_token
195
+ }).toString()
196
+ });
197
+ if (!response.ok)
198
+ throw rejected = response.status === 400 || response.status === 401, new Error(`Token refresh failed (${response.status})`);
199
+ data = await response.json();
200
+ } catch (err) {
201
+ let fresh = this.syncFromDisk();
202
+ if (fresh && fresh.refresh_token !== tokens.refresh_token && Date.now() + REFRESH_BUFFER_MS < fresh.expires_at)
203
+ return fresh.access_token;
204
+ 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`);
205
+ }
206
+ if (data.id_token) {
207
+ let claims = decodeJwtPayload(data.id_token);
208
+ this.email = claims.email;
209
+ }
210
+ return this.persist({
211
+ access_token: data.access_token,
212
+ refresh_token: data.refresh_token || tokens.refresh_token,
213
+ expires_at: Date.now() + positiveSecondsToMs(data.expires_in, 3600 * 1e3),
214
+ account_id: tokens.account_id
215
+ }), data.access_token;
216
+ }
217
+ getAuthStatus() {
218
+ let tokens = this.syncFromDisk();
219
+ return tokens ? {
220
+ authenticated: !0,
221
+ email: this.email,
222
+ expiresAt: tokens.expires_at
223
+ } : {
224
+ authenticated: !1,
225
+ flowPending: this.activeAuthFlow !== null,
226
+ flowError: this.lastFlowError
227
+ };
228
+ }
229
+ isAuthenticated() {
230
+ return this.syncFromDisk() !== null;
231
+ }
232
+ logout() {
233
+ clearTokens(), this.cachedTokens = null, this.email = void 0, this.refreshPromise = null, this.lastFlowError = void 0;
234
+ }
235
+ }, instance = null;
236
+ function getGrokAuthManager() {
237
+ return instance || (instance = new GrokAuthManager()), instance;
238
+ }
239
+
240
+ export {
241
+ readTokens,
242
+ pollDeviceCodeToken,
243
+ getGrokAuthManager
244
+ };
@@ -0,0 +1,48 @@
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
+ __require
9
+ } from "./chunk-M2RX3S2T.mjs";
10
+
11
+ // src/main/utils/user-data-path.ts
12
+ import { homedir } from "node:os";
13
+ import { tmpdir } from "node:os";
14
+ import { join } from "node:path";
15
+ import { existsSync } from "node:fs";
16
+ var PRODUCT_NAME = "ADF Studio", PACKAGE_NAME = "adf-studio", SETTINGS_FILE = "adf-settings.json";
17
+ function getUserDataPath() {
18
+ if (process.env.ADF_USER_DATA_DIR) return process.env.ADF_USER_DATA_DIR;
19
+ let electronApp = getElectronApp();
20
+ return electronApp?.getPath ? electronApp.getPath("userData") : defaultUserDataPath();
21
+ }
22
+ function getTempPath() {
23
+ if (process.env.ADF_TEMP_DIR) return process.env.ADF_TEMP_DIR;
24
+ let electronApp = getElectronApp();
25
+ return electronApp?.getPath ? electronApp.getPath("temp") : tmpdir();
26
+ }
27
+ function platformConfigBase() {
28
+ return process.platform === "darwin" ? join(homedir(), "Library", "Application Support") : process.platform === "win32" ? process.env.APPDATA ?? join(homedir(), "AppData", "Roaming") : process.env.XDG_CONFIG_HOME ?? join(homedir(), ".config");
29
+ }
30
+ var loggedDefaultPath = null;
31
+ function defaultUserDataPath(options = {}) {
32
+ if (process.env.ADF_USER_DATA_DIR) return process.env.ADF_USER_DATA_DIR;
33
+ let base = platformConfigBase(), productDir = join(base, PRODUCT_NAME), packageDir = join(base, PACKAGE_NAME), chosen = existsSync(join(productDir, SETTINGS_FILE)) ? productDir : packageDir;
34
+ return !options.quiet && loggedDefaultPath !== chosen && (loggedDefaultPath = chosen, console.log(`[UserDataPath] Using user data directory: ${chosen}`)), chosen;
35
+ }
36
+ function getElectronApp() {
37
+ try {
38
+ return __require("electron").app ?? null;
39
+ } catch {
40
+ return null;
41
+ }
42
+ }
43
+
44
+ export {
45
+ getUserDataPath,
46
+ getTempPath,
47
+ defaultUserDataPath
48
+ };
@@ -0,0 +1,34 @@
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/cli/prompt.ts
9
+ import { createInterface } from "node:readline";
10
+ function stdinPrompt(input = process.stdin, output = process.stderr) {
11
+ let rl = null, ended = !1, lines = [], waiting = [], open = () => {
12
+ rl || ended || (rl = createInterface({ input, terminal: !1 }), rl.on("line", (line) => {
13
+ let next = waiting.shift();
14
+ next ? next(line) : lines.push(line);
15
+ }), rl.on("close", () => {
16
+ ended = !0;
17
+ for (let w of waiting.splice(0)) w(null);
18
+ }));
19
+ };
20
+ return {
21
+ ask(question) {
22
+ output.write(question), open();
23
+ let buffered = lines.shift();
24
+ return buffered !== void 0 ? Promise.resolve(buffered) : ended ? Promise.resolve(null) : new Promise((resolve) => waiting.push(resolve));
25
+ },
26
+ close() {
27
+ rl?.close(), rl = null;
28
+ }
29
+ };
30
+ }
31
+
32
+ export {
33
+ stdinPrompt
34
+ };