dsh-codex-connect 0.1.0-alpha.4.3

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/lib/bin.js ADDED
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env node
2
+ import { A as logoutOpenAICodex, F as openAICodexAuthPath, j as openAICodexAuthStatus, k as loginOpenAICodex, w as diagnoseOpenAICodex } from "./src-ILOioCkA.js";
3
+ import { spawn } from "node:child_process";
4
+ import { realpathSync } from "node:fs";
5
+ import { createInterface } from "node:readline/promises";
6
+ import { fileURLToPath } from "node:url";
7
+ //#region src/bin.ts
8
+ /** Standalone credential CLI for the optional OpenAI Codex bundle. */
9
+ /** Open one trusted HTTPS URL with the platform browser, best effort. */
10
+ function openBrowser(rawUrl) {
11
+ const url = new URL(rawUrl);
12
+ if (url.protocol !== "https:") throw new Error(`refusing to open non-HTTPS authorization URL from ${url.host}`);
13
+ const command = process.platform === "win32" ? {
14
+ file: "rundll32.exe",
15
+ args: ["url.dll,FileProtocolHandler", url.href]
16
+ } : process.platform === "darwin" ? {
17
+ file: "open",
18
+ args: [url.href]
19
+ } : {
20
+ file: "xdg-open",
21
+ args: [url.href]
22
+ };
23
+ try {
24
+ const child = spawn(command.file, command.args, {
25
+ detached: true,
26
+ stdio: "ignore",
27
+ windowsHide: true
28
+ });
29
+ child.on("error", () => {});
30
+ child.unref();
31
+ } catch {}
32
+ }
33
+ /** Remove token-like strings from an external OAuth diagnostic. */
34
+ function safeMessage(error) {
35
+ return (error instanceof Error ? error.message : String(error)).replace(/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/gu, "[redacted token]").replace(/(\b(?:code|token|refresh_token|access_token)=)[^&\s]+/giu, "$1[redacted]");
36
+ }
37
+ /** Render one provider event without exposing stored credentials. */
38
+ function notify(event, useBrowser) {
39
+ switch (event.type) {
40
+ case "auth_url":
41
+ process.stdout.write(`Open this URL to sign in:\n${event.url}\n`);
42
+ if (event.instructions !== void 0) process.stdout.write(`${event.instructions}\n`);
43
+ if (useBrowser) openBrowser(event.url);
44
+ break;
45
+ case "device_code":
46
+ process.stdout.write(`Open this URL to sign in:\n${event.verificationUri}\nEnter code: ${event.userCode}\n`);
47
+ if (useBrowser) openBrowser(event.verificationUri);
48
+ break;
49
+ case "info":
50
+ case "progress": process.stdout.write(`${event.message}\n`);
51
+ }
52
+ }
53
+ /** Answer a provider auth prompt through the terminal. */
54
+ async function answerPrompt(prompt, deviceCode, question) {
55
+ if (prompt.type === "select") {
56
+ const wanted = deviceCode ? "device_code" : "browser";
57
+ if (!prompt.options.some((option) => option.id === wanted)) throw new Error(`OpenAI Codex login did not offer the requested ${wanted} method`);
58
+ return wanted;
59
+ }
60
+ const suffix = prompt.placeholder === void 0 ? "" : ` (${prompt.placeholder})`;
61
+ return question(`${prompt.message}${suffix}: `, { ...prompt.signal === void 0 ? {} : { signal: prompt.signal } });
62
+ }
63
+ /** Print the standalone command help. */
64
+ function printHelp() {
65
+ process.stdout.write([
66
+ "Usage: dsh-codex-connect <doctor|login|logout|status> [--device-code]",
67
+ "",
68
+ " doctor inspect secret-free runtime and OAuth file metadata",
69
+ " login sign in with a separate ChatGPT OAuth session",
70
+ " logout remove the dsh credential without changing ~/.codex",
71
+ " status report non-secret dsh credential state",
72
+ " --device-code use headless device-code login (login only)",
73
+ ""
74
+ ].join("\n"));
75
+ }
76
+ /** Execute one boot-free credential command. */
77
+ async function run(argv) {
78
+ if (argv.length === 0 || argv[0] === "--help" || argv[0] === "-h") {
79
+ printHelp();
80
+ return 0;
81
+ }
82
+ const [rawAction, ...flags] = argv;
83
+ if (rawAction !== "doctor" && rawAction !== "login" && rawAction !== "logout" && rawAction !== "status") {
84
+ process.stderr.write(`dsh-codex-connect: expected doctor, login, logout, or status; got ${JSON.stringify(rawAction)}\n`);
85
+ return 1;
86
+ }
87
+ const action = rawAction;
88
+ if (flags.filter((flag) => flag !== "--device-code").length > 0 || flags.includes("--device-code") && action !== "login") {
89
+ process.stderr.write(`dsh-codex-connect: invalid options for ${action}: ${flags.join(" ")}\n`);
90
+ return 1;
91
+ }
92
+ try {
93
+ switch (action) {
94
+ case "doctor": {
95
+ const report = await diagnoseOpenAICodex();
96
+ process.stdout.write([
97
+ `Codex Connect ${report.version} on ${report.node}`,
98
+ `OAuth file metadata: ${report.credentialFile.state} (${report.credentialFile.path})`,
99
+ `Optional capability defaults: search=${report.capabilities.search ? "enabled" : "disabled"}, imageTool=${report.capabilities.imageTool ? "enabled" : "disabled"}`,
100
+ "Harness defaults: unchanged by this plugin",
101
+ ...report.hints.map((hint) => `Hint: ${hint}`),
102
+ ""
103
+ ].join("\n"));
104
+ return report.credentialFile.state === "permissions-too-broad" || report.credentialFile.state === "not-a-regular-file" || report.credentialFile.state === "unreadable-metadata" ? 1 : 0;
105
+ }
106
+ case "status": {
107
+ const status = await openAICodexAuthStatus();
108
+ if (!status.authenticated) {
109
+ process.stdout.write("Codex Connect: signed out\n");
110
+ return 1;
111
+ }
112
+ const expires = status.expiresAt;
113
+ const suffix = expires === void 0 || Number.isNaN(expires.valueOf()) ? "" : `; access token expires ${expires.toISOString()} (refresh is automatic)`;
114
+ process.stdout.write(`Codex Connect: signed in${suffix}\n`);
115
+ return 0;
116
+ }
117
+ case "logout":
118
+ await logoutOpenAICodex();
119
+ process.stdout.write(`Codex Connect: signed out; removed ${openAICodexAuthPath()}\n`);
120
+ return 0;
121
+ case "login": {
122
+ const readline = createInterface({
123
+ input: process.stdin,
124
+ output: process.stdout
125
+ });
126
+ try {
127
+ await loginOpenAICodex({
128
+ prompt: (prompt) => answerPrompt(prompt, flags.includes("--device-code"), (text, options) => readline.question(text, options)),
129
+ notify: (event) => notify(event, true)
130
+ });
131
+ } finally {
132
+ readline.close();
133
+ }
134
+ process.stdout.write(`Codex Connect: signed in; credentials saved to ${openAICodexAuthPath()}\n`);
135
+ return 0;
136
+ }
137
+ }
138
+ } catch (error) {
139
+ process.stderr.write(`dsh-codex-connect: ${action} failed: ${safeMessage(error)}\n`);
140
+ return 1;
141
+ }
142
+ }
143
+ if (process.argv[1] !== void 0 && fileURLToPath(import.meta.url) === realpathSync(process.argv[1])) process.exitCode = await run(process.argv.slice(2));
144
+ //#endregion
145
+ export { run };