@harars/opencode-switch-openai-auth-plugin 0.1.4 → 0.1.6
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/dist/index.js +61 -21
- package/dist/tui.js +61 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -39,6 +39,7 @@ import { insert as _$insert } from "@opentui/solid";
|
|
|
39
39
|
import { setProp as _$setProp } from "@opentui/solid";
|
|
40
40
|
import { createElement as _$createElement } from "@opentui/solid";
|
|
41
41
|
import { TextAttributes } from "@opentui/core";
|
|
42
|
+
import { onMount } from "solid-js";
|
|
42
43
|
import { useKeyboard } from "@opentui/solid";
|
|
43
44
|
|
|
44
45
|
// src/login-helpers.ts
|
|
@@ -74,12 +75,34 @@ async function clip(text) {
|
|
|
74
75
|
function target(authz) {
|
|
75
76
|
return authz.instructions.match(/[A-Z0-9]{4}-[A-Z0-9]{4,5}/)?.[0] ?? authz.url;
|
|
76
77
|
}
|
|
78
|
+
function detail(err) {
|
|
79
|
+
if (err instanceof Error)
|
|
80
|
+
return err.message;
|
|
81
|
+
if (typeof err === "string")
|
|
82
|
+
return err;
|
|
83
|
+
try {
|
|
84
|
+
return JSON.stringify(err);
|
|
85
|
+
} catch {
|
|
86
|
+
return String(err);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function explain(err) {
|
|
90
|
+
const msg = detail(err);
|
|
91
|
+
const port = msg.match(/port\s+(\d+)\s+in use/i)?.[1];
|
|
92
|
+
if (port) {
|
|
93
|
+
return `Browser login could not start because local port ${port} is already in use. Close the other OpenCode login window or finish the other browser login first.`;
|
|
94
|
+
}
|
|
95
|
+
if (msg.includes("this.client") || msg.includes("\u672A\u5B9A\u4E49\u7684\u4E0D\u662F\u4E00\u4E2Aobject")) {
|
|
96
|
+
return "Browser login callback failed inside OpenCode. Update the plugin to the latest version and retry.";
|
|
97
|
+
}
|
|
98
|
+
return msg;
|
|
99
|
+
}
|
|
77
100
|
async function runOAuthCallback(callback, input) {
|
|
78
101
|
try {
|
|
79
102
|
const res = await callback(input);
|
|
80
|
-
return
|
|
81
|
-
} catch {
|
|
82
|
-
return false;
|
|
103
|
+
return res.error ? { ok: false, error: res.error } : { ok: true };
|
|
104
|
+
} catch (err) {
|
|
105
|
+
return { ok: false, error: detail(err) };
|
|
83
106
|
}
|
|
84
107
|
}
|
|
85
108
|
|
|
@@ -428,6 +451,8 @@ function visible(prompt, values) {
|
|
|
428
451
|
if (!prompt.when)
|
|
429
452
|
return true;
|
|
430
453
|
const cur = values[prompt.when.key];
|
|
454
|
+
if (cur === undefined)
|
|
455
|
+
return false;
|
|
431
456
|
if (prompt.when.op === "eq")
|
|
432
457
|
return cur === prompt.when.value;
|
|
433
458
|
return cur !== prompt.when.value;
|
|
@@ -446,12 +471,14 @@ function unwrap(input) {
|
|
|
446
471
|
}
|
|
447
472
|
if ("error" in input && input.error !== undefined) {
|
|
448
473
|
return {
|
|
449
|
-
ok: false
|
|
474
|
+
ok: false,
|
|
475
|
+
error: input.error
|
|
450
476
|
};
|
|
451
477
|
}
|
|
452
478
|
if ("data" in input) {
|
|
453
479
|
return input.data === undefined ? {
|
|
454
|
-
ok: false
|
|
480
|
+
ok: false,
|
|
481
|
+
error: "Missing response data"
|
|
455
482
|
} : {
|
|
456
483
|
ok: true,
|
|
457
484
|
data: input.data
|
|
@@ -482,6 +509,9 @@ function bind(api, authz) {
|
|
|
482
509
|
}
|
|
483
510
|
function WaitView(props) {
|
|
484
511
|
bind(props.api, props.authz);
|
|
512
|
+
onMount(() => {
|
|
513
|
+
props.run();
|
|
514
|
+
});
|
|
485
515
|
return (() => {
|
|
486
516
|
var _el$ = _$createElement("box"), _el$2 = _$createElement("text"), _el$3 = _$createElement("text"), _el$4 = _$createElement("text"), _el$5 = _$createElement("text"), _el$7 = _$createElement("text");
|
|
487
517
|
_$insertNode(_el$, _el$2);
|
|
@@ -532,9 +562,9 @@ function wait(api, title, authz, run) {
|
|
|
532
562
|
api.ui.dialog.replace(() => _$createComponent(WaitView, {
|
|
533
563
|
api,
|
|
534
564
|
title,
|
|
535
|
-
authz
|
|
565
|
+
authz,
|
|
566
|
+
run
|
|
536
567
|
}));
|
|
537
|
-
run();
|
|
538
568
|
}
|
|
539
569
|
async function choose(api, methods) {
|
|
540
570
|
if (methods.length === 1)
|
|
@@ -660,19 +690,25 @@ async function code(api, index, method, authz) {
|
|
|
660
690
|
},
|
|
661
691
|
authz,
|
|
662
692
|
onConfirm: async (value) => {
|
|
663
|
-
resolve(await runOAuthCallback(api.client.provider.oauth.callback, {
|
|
693
|
+
resolve(await runOAuthCallback((input) => api.client.provider.oauth.callback(input), {
|
|
664
694
|
providerID: "openai",
|
|
665
695
|
method: index,
|
|
666
696
|
code: value
|
|
667
697
|
}));
|
|
668
698
|
},
|
|
669
|
-
onCancel: () => resolve(
|
|
670
|
-
|
|
699
|
+
onCancel: () => resolve({
|
|
700
|
+
ok: false,
|
|
701
|
+
error: "Cancelled"
|
|
702
|
+
})
|
|
703
|
+
}), () => resolve({
|
|
704
|
+
ok: false,
|
|
705
|
+
error: "Cancelled"
|
|
706
|
+
}));
|
|
671
707
|
});
|
|
672
|
-
if (!ok) {
|
|
708
|
+
if (!ok.ok) {
|
|
673
709
|
api.ui.toast({
|
|
674
710
|
variant: "error",
|
|
675
|
-
message:
|
|
711
|
+
message: `Login failed: ${explain(ok.error)}`
|
|
676
712
|
});
|
|
677
713
|
return false;
|
|
678
714
|
}
|
|
@@ -682,16 +718,16 @@ async function auto(api, index, method, authz) {
|
|
|
682
718
|
const prev = await readCurrentAuth();
|
|
683
719
|
const ok = await new Promise((resolve) => {
|
|
684
720
|
wait(api, method.label, authz, async () => {
|
|
685
|
-
resolve(await runOAuthCallback(api.client.provider.oauth.callback, {
|
|
721
|
+
resolve(await runOAuthCallback((input) => api.client.provider.oauth.callback(input), {
|
|
686
722
|
providerID: "openai",
|
|
687
723
|
method: index
|
|
688
724
|
}));
|
|
689
725
|
});
|
|
690
726
|
});
|
|
691
|
-
if (!ok) {
|
|
727
|
+
if (!ok.ok) {
|
|
692
728
|
api.ui.toast({
|
|
693
729
|
variant: "error",
|
|
694
|
-
message:
|
|
730
|
+
message: `Login failed: ${explain(ok.error)}`
|
|
695
731
|
});
|
|
696
732
|
return false;
|
|
697
733
|
}
|
|
@@ -723,9 +759,13 @@ async function loginOpenAI(api) {
|
|
|
723
759
|
return false;
|
|
724
760
|
const picked = methods[index];
|
|
725
761
|
const method = picked.method;
|
|
726
|
-
|
|
727
|
-
if (method.prompts?.length
|
|
728
|
-
|
|
762
|
+
let inputs;
|
|
763
|
+
if (method.prompts?.length) {
|
|
764
|
+
const value = await prompts(api, method.label, method);
|
|
765
|
+
if (!value)
|
|
766
|
+
return false;
|
|
767
|
+
inputs = value;
|
|
768
|
+
}
|
|
729
769
|
const authz = unwrap(await api.client.provider.oauth.authorize({
|
|
730
770
|
providerID: "openai",
|
|
731
771
|
method: picked.index,
|
|
@@ -734,7 +774,7 @@ async function loginOpenAI(api) {
|
|
|
734
774
|
if (!authz.ok) {
|
|
735
775
|
api.ui.toast({
|
|
736
776
|
variant: "error",
|
|
737
|
-
message:
|
|
777
|
+
message: `Login failed: ${explain(authz.error)}`
|
|
738
778
|
});
|
|
739
779
|
return false;
|
|
740
780
|
}
|
|
@@ -747,10 +787,10 @@ async function loginOpenAI(api) {
|
|
|
747
787
|
message: "Unsupported auth method"
|
|
748
788
|
});
|
|
749
789
|
return false;
|
|
750
|
-
} catch {
|
|
790
|
+
} catch (err) {
|
|
751
791
|
api.ui.toast({
|
|
752
792
|
variant: "error",
|
|
753
|
-
message:
|
|
793
|
+
message: `Login failed: ${explain(err)}`
|
|
754
794
|
});
|
|
755
795
|
return false;
|
|
756
796
|
}
|
package/dist/tui.js
CHANGED
|
@@ -39,6 +39,7 @@ import { insert as _$insert } from "@opentui/solid";
|
|
|
39
39
|
import { setProp as _$setProp } from "@opentui/solid";
|
|
40
40
|
import { createElement as _$createElement } from "@opentui/solid";
|
|
41
41
|
import { TextAttributes } from "@opentui/core";
|
|
42
|
+
import { onMount } from "solid-js";
|
|
42
43
|
import { useKeyboard } from "@opentui/solid";
|
|
43
44
|
|
|
44
45
|
// src/login-helpers.ts
|
|
@@ -74,12 +75,34 @@ async function clip(text) {
|
|
|
74
75
|
function target(authz) {
|
|
75
76
|
return authz.instructions.match(/[A-Z0-9]{4}-[A-Z0-9]{4,5}/)?.[0] ?? authz.url;
|
|
76
77
|
}
|
|
78
|
+
function detail(err) {
|
|
79
|
+
if (err instanceof Error)
|
|
80
|
+
return err.message;
|
|
81
|
+
if (typeof err === "string")
|
|
82
|
+
return err;
|
|
83
|
+
try {
|
|
84
|
+
return JSON.stringify(err);
|
|
85
|
+
} catch {
|
|
86
|
+
return String(err);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function explain(err) {
|
|
90
|
+
const msg = detail(err);
|
|
91
|
+
const port = msg.match(/port\s+(\d+)\s+in use/i)?.[1];
|
|
92
|
+
if (port) {
|
|
93
|
+
return `Browser login could not start because local port ${port} is already in use. Close the other OpenCode login window or finish the other browser login first.`;
|
|
94
|
+
}
|
|
95
|
+
if (msg.includes("this.client") || msg.includes("\u672A\u5B9A\u4E49\u7684\u4E0D\u662F\u4E00\u4E2Aobject")) {
|
|
96
|
+
return "Browser login callback failed inside OpenCode. Update the plugin to the latest version and retry.";
|
|
97
|
+
}
|
|
98
|
+
return msg;
|
|
99
|
+
}
|
|
77
100
|
async function runOAuthCallback(callback, input) {
|
|
78
101
|
try {
|
|
79
102
|
const res = await callback(input);
|
|
80
|
-
return
|
|
81
|
-
} catch {
|
|
82
|
-
return false;
|
|
103
|
+
return res.error ? { ok: false, error: res.error } : { ok: true };
|
|
104
|
+
} catch (err) {
|
|
105
|
+
return { ok: false, error: detail(err) };
|
|
83
106
|
}
|
|
84
107
|
}
|
|
85
108
|
|
|
@@ -428,6 +451,8 @@ function visible(prompt, values) {
|
|
|
428
451
|
if (!prompt.when)
|
|
429
452
|
return true;
|
|
430
453
|
const cur = values[prompt.when.key];
|
|
454
|
+
if (cur === undefined)
|
|
455
|
+
return false;
|
|
431
456
|
if (prompt.when.op === "eq")
|
|
432
457
|
return cur === prompt.when.value;
|
|
433
458
|
return cur !== prompt.when.value;
|
|
@@ -446,12 +471,14 @@ function unwrap(input) {
|
|
|
446
471
|
}
|
|
447
472
|
if ("error" in input && input.error !== undefined) {
|
|
448
473
|
return {
|
|
449
|
-
ok: false
|
|
474
|
+
ok: false,
|
|
475
|
+
error: input.error
|
|
450
476
|
};
|
|
451
477
|
}
|
|
452
478
|
if ("data" in input) {
|
|
453
479
|
return input.data === undefined ? {
|
|
454
|
-
ok: false
|
|
480
|
+
ok: false,
|
|
481
|
+
error: "Missing response data"
|
|
455
482
|
} : {
|
|
456
483
|
ok: true,
|
|
457
484
|
data: input.data
|
|
@@ -482,6 +509,9 @@ function bind(api, authz) {
|
|
|
482
509
|
}
|
|
483
510
|
function WaitView(props) {
|
|
484
511
|
bind(props.api, props.authz);
|
|
512
|
+
onMount(() => {
|
|
513
|
+
props.run();
|
|
514
|
+
});
|
|
485
515
|
return (() => {
|
|
486
516
|
var _el$ = _$createElement("box"), _el$2 = _$createElement("text"), _el$3 = _$createElement("text"), _el$4 = _$createElement("text"), _el$5 = _$createElement("text"), _el$7 = _$createElement("text");
|
|
487
517
|
_$insertNode(_el$, _el$2);
|
|
@@ -532,9 +562,9 @@ function wait(api, title, authz, run) {
|
|
|
532
562
|
api.ui.dialog.replace(() => _$createComponent(WaitView, {
|
|
533
563
|
api,
|
|
534
564
|
title,
|
|
535
|
-
authz
|
|
565
|
+
authz,
|
|
566
|
+
run
|
|
536
567
|
}));
|
|
537
|
-
run();
|
|
538
568
|
}
|
|
539
569
|
async function choose(api, methods) {
|
|
540
570
|
if (methods.length === 1)
|
|
@@ -660,19 +690,25 @@ async function code(api, index, method, authz) {
|
|
|
660
690
|
},
|
|
661
691
|
authz,
|
|
662
692
|
onConfirm: async (value) => {
|
|
663
|
-
resolve(await runOAuthCallback(api.client.provider.oauth.callback, {
|
|
693
|
+
resolve(await runOAuthCallback((input) => api.client.provider.oauth.callback(input), {
|
|
664
694
|
providerID: "openai",
|
|
665
695
|
method: index,
|
|
666
696
|
code: value
|
|
667
697
|
}));
|
|
668
698
|
},
|
|
669
|
-
onCancel: () => resolve(
|
|
670
|
-
|
|
699
|
+
onCancel: () => resolve({
|
|
700
|
+
ok: false,
|
|
701
|
+
error: "Cancelled"
|
|
702
|
+
})
|
|
703
|
+
}), () => resolve({
|
|
704
|
+
ok: false,
|
|
705
|
+
error: "Cancelled"
|
|
706
|
+
}));
|
|
671
707
|
});
|
|
672
|
-
if (!ok) {
|
|
708
|
+
if (!ok.ok) {
|
|
673
709
|
api.ui.toast({
|
|
674
710
|
variant: "error",
|
|
675
|
-
message:
|
|
711
|
+
message: `Login failed: ${explain(ok.error)}`
|
|
676
712
|
});
|
|
677
713
|
return false;
|
|
678
714
|
}
|
|
@@ -682,16 +718,16 @@ async function auto(api, index, method, authz) {
|
|
|
682
718
|
const prev = await readCurrentAuth();
|
|
683
719
|
const ok = await new Promise((resolve) => {
|
|
684
720
|
wait(api, method.label, authz, async () => {
|
|
685
|
-
resolve(await runOAuthCallback(api.client.provider.oauth.callback, {
|
|
721
|
+
resolve(await runOAuthCallback((input) => api.client.provider.oauth.callback(input), {
|
|
686
722
|
providerID: "openai",
|
|
687
723
|
method: index
|
|
688
724
|
}));
|
|
689
725
|
});
|
|
690
726
|
});
|
|
691
|
-
if (!ok) {
|
|
727
|
+
if (!ok.ok) {
|
|
692
728
|
api.ui.toast({
|
|
693
729
|
variant: "error",
|
|
694
|
-
message:
|
|
730
|
+
message: `Login failed: ${explain(ok.error)}`
|
|
695
731
|
});
|
|
696
732
|
return false;
|
|
697
733
|
}
|
|
@@ -723,9 +759,13 @@ async function loginOpenAI(api) {
|
|
|
723
759
|
return false;
|
|
724
760
|
const picked = methods[index];
|
|
725
761
|
const method = picked.method;
|
|
726
|
-
|
|
727
|
-
if (method.prompts?.length
|
|
728
|
-
|
|
762
|
+
let inputs;
|
|
763
|
+
if (method.prompts?.length) {
|
|
764
|
+
const value = await prompts(api, method.label, method);
|
|
765
|
+
if (!value)
|
|
766
|
+
return false;
|
|
767
|
+
inputs = value;
|
|
768
|
+
}
|
|
729
769
|
const authz = unwrap(await api.client.provider.oauth.authorize({
|
|
730
770
|
providerID: "openai",
|
|
731
771
|
method: picked.index,
|
|
@@ -734,7 +774,7 @@ async function loginOpenAI(api) {
|
|
|
734
774
|
if (!authz.ok) {
|
|
735
775
|
api.ui.toast({
|
|
736
776
|
variant: "error",
|
|
737
|
-
message:
|
|
777
|
+
message: `Login failed: ${explain(authz.error)}`
|
|
738
778
|
});
|
|
739
779
|
return false;
|
|
740
780
|
}
|
|
@@ -747,10 +787,10 @@ async function loginOpenAI(api) {
|
|
|
747
787
|
message: "Unsupported auth method"
|
|
748
788
|
});
|
|
749
789
|
return false;
|
|
750
|
-
} catch {
|
|
790
|
+
} catch (err) {
|
|
751
791
|
api.ui.toast({
|
|
752
792
|
variant: "error",
|
|
753
|
-
message:
|
|
793
|
+
message: `Login failed: ${explain(err)}`
|
|
754
794
|
});
|
|
755
795
|
return false;
|
|
756
796
|
}
|