@playwo/opencode-cursor-oauth 0.0.0-dev.c80ebcb27754 → 0.0.0-dev.d7836f7ad39f

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 (74) hide show
  1. package/README.md +19 -91
  2. package/dist/auth.js +27 -3
  3. package/dist/constants.d.ts +2 -0
  4. package/dist/constants.js +2 -0
  5. package/dist/cursor/bidi-session.d.ts +13 -0
  6. package/dist/cursor/bidi-session.js +149 -0
  7. package/dist/cursor/config.d.ts +4 -0
  8. package/dist/cursor/config.js +4 -0
  9. package/dist/cursor/connect-framing.d.ts +10 -0
  10. package/dist/cursor/connect-framing.js +80 -0
  11. package/dist/cursor/headers.d.ts +6 -0
  12. package/dist/cursor/headers.js +16 -0
  13. package/dist/cursor/index.d.ts +5 -0
  14. package/dist/cursor/index.js +5 -0
  15. package/dist/cursor/unary-rpc.d.ts +13 -0
  16. package/dist/cursor/unary-rpc.js +181 -0
  17. package/dist/index.d.ts +2 -14
  18. package/dist/index.js +2 -229
  19. package/dist/logger.d.ts +6 -0
  20. package/dist/logger.js +147 -0
  21. package/dist/models.d.ts +3 -0
  22. package/dist/models.js +80 -54
  23. package/dist/openai/index.d.ts +3 -0
  24. package/dist/openai/index.js +3 -0
  25. package/dist/openai/messages.d.ts +40 -0
  26. package/dist/openai/messages.js +231 -0
  27. package/dist/openai/tools.d.ts +7 -0
  28. package/dist/openai/tools.js +58 -0
  29. package/dist/openai/types.d.ts +41 -0
  30. package/dist/openai/types.js +1 -0
  31. package/dist/plugin/cursor-auth-plugin.d.ts +3 -0
  32. package/dist/plugin/cursor-auth-plugin.js +140 -0
  33. package/dist/proto/agent_pb.js +637 -319
  34. package/dist/provider/index.d.ts +2 -0
  35. package/dist/provider/index.js +2 -0
  36. package/dist/provider/model-cost.d.ts +9 -0
  37. package/dist/provider/model-cost.js +206 -0
  38. package/dist/provider/models.d.ts +8 -0
  39. package/dist/provider/models.js +86 -0
  40. package/dist/proxy/bridge-non-streaming.d.ts +3 -0
  41. package/dist/proxy/bridge-non-streaming.js +119 -0
  42. package/dist/proxy/bridge-session.d.ts +5 -0
  43. package/dist/proxy/bridge-session.js +13 -0
  44. package/dist/proxy/bridge-streaming.d.ts +5 -0
  45. package/dist/proxy/bridge-streaming.js +311 -0
  46. package/dist/proxy/bridge.d.ts +3 -0
  47. package/dist/proxy/bridge.js +3 -0
  48. package/dist/proxy/chat-completion.d.ts +2 -0
  49. package/dist/proxy/chat-completion.js +138 -0
  50. package/dist/proxy/conversation-meta.d.ts +12 -0
  51. package/dist/proxy/conversation-meta.js +1 -0
  52. package/dist/proxy/conversation-state.d.ts +35 -0
  53. package/dist/proxy/conversation-state.js +95 -0
  54. package/dist/proxy/cursor-request.d.ts +6 -0
  55. package/dist/proxy/cursor-request.js +104 -0
  56. package/dist/proxy/index.d.ts +12 -0
  57. package/dist/proxy/index.js +12 -0
  58. package/dist/proxy/server.d.ts +6 -0
  59. package/dist/proxy/server.js +89 -0
  60. package/dist/proxy/sse.d.ts +5 -0
  61. package/dist/proxy/sse.js +5 -0
  62. package/dist/proxy/state-sync.d.ts +2 -0
  63. package/dist/proxy/state-sync.js +17 -0
  64. package/dist/proxy/stream-dispatch.d.ts +42 -0
  65. package/dist/proxy/stream-dispatch.js +491 -0
  66. package/dist/proxy/stream-state.d.ts +9 -0
  67. package/dist/proxy/stream-state.js +1 -0
  68. package/dist/proxy/title.d.ts +1 -0
  69. package/dist/proxy/title.js +103 -0
  70. package/dist/proxy/types.d.ts +27 -0
  71. package/dist/proxy/types.js +1 -0
  72. package/dist/proxy.d.ts +2 -19
  73. package/dist/proxy.js +2 -1221
  74. package/package.json +1 -1
@@ -0,0 +1,140 @@
1
+ import { generateCursorAuthParams, getTokenExpiry, pollCursorAuth, refreshCursorToken, } from "../auth";
2
+ import { CURSOR_PROVIDER_ID } from "../constants";
3
+ import { configurePluginLogger, errorDetails, logPluginError, logPluginWarn, } from "../logger";
4
+ import { getCursorModels } from "../models";
5
+ import { buildCursorProviderModels, buildDisabledProviderConfig, setProviderModels, stripAuthorizationHeader, } from "../provider/models";
6
+ import { startProxy, stopProxy } from "../proxy";
7
+ let lastModelDiscoveryError = null;
8
+ export const CursorAuthPlugin = async (input) => {
9
+ configurePluginLogger(input);
10
+ return {
11
+ auth: {
12
+ provider: CURSOR_PROVIDER_ID,
13
+ async loader(getAuth, provider) {
14
+ try {
15
+ const auth = await getAuth();
16
+ if (!auth || auth.type !== "oauth")
17
+ return {};
18
+ let accessToken = auth.access;
19
+ if (!accessToken || auth.expires < Date.now()) {
20
+ const refreshed = await refreshCursorToken(auth.refresh);
21
+ await input.client.auth.set({
22
+ path: { id: CURSOR_PROVIDER_ID },
23
+ body: {
24
+ type: "oauth",
25
+ refresh: refreshed.refresh,
26
+ access: refreshed.access,
27
+ expires: refreshed.expires,
28
+ },
29
+ });
30
+ accessToken = refreshed.access;
31
+ }
32
+ const models = await getCursorModels(accessToken);
33
+ lastModelDiscoveryError = null;
34
+ const port = await startProxy(async () => {
35
+ const currentAuth = await getAuth();
36
+ if (currentAuth.type !== "oauth") {
37
+ const authError = new Error("Cursor auth not configured");
38
+ logPluginError("Cursor proxy access token lookup failed", {
39
+ stage: "proxy_access_token",
40
+ ...errorDetails(authError),
41
+ });
42
+ throw authError;
43
+ }
44
+ if (!currentAuth.access || currentAuth.expires < Date.now()) {
45
+ const refreshed = await refreshCursorToken(currentAuth.refresh);
46
+ await input.client.auth.set({
47
+ path: { id: CURSOR_PROVIDER_ID },
48
+ body: {
49
+ type: "oauth",
50
+ refresh: refreshed.refresh,
51
+ access: refreshed.access,
52
+ expires: refreshed.expires,
53
+ },
54
+ });
55
+ return refreshed.access;
56
+ }
57
+ return currentAuth.access;
58
+ }, models);
59
+ setProviderModels(provider, buildCursorProviderModels(models, port));
60
+ return {
61
+ baseURL: `http://localhost:${port}/v1`,
62
+ apiKey: "cursor-proxy",
63
+ async fetch(requestInput, init) {
64
+ return fetch(requestInput, stripAuthorizationHeader(init));
65
+ },
66
+ };
67
+ }
68
+ catch (error) {
69
+ const message = error instanceof Error
70
+ ? error.message
71
+ : "Cursor model discovery failed.";
72
+ logPluginError("Cursor auth loader failed", {
73
+ stage: "loader",
74
+ providerID: CURSOR_PROVIDER_ID,
75
+ ...errorDetails(error),
76
+ });
77
+ stopProxy();
78
+ setProviderModels(provider, {});
79
+ if (message !== lastModelDiscoveryError) {
80
+ lastModelDiscoveryError = message;
81
+ await showDiscoveryFailureToast(input, message);
82
+ }
83
+ return buildDisabledProviderConfig(message);
84
+ }
85
+ },
86
+ methods: [
87
+ {
88
+ type: "oauth",
89
+ label: "Login with Cursor",
90
+ async authorize() {
91
+ const { verifier, uuid, loginUrl } = await generateCursorAuthParams();
92
+ return {
93
+ url: loginUrl,
94
+ instructions: "Complete login in your browser. This window will close automatically.",
95
+ method: "auto",
96
+ async callback() {
97
+ const { accessToken, refreshToken } = await pollCursorAuth(uuid, verifier);
98
+ return {
99
+ type: "success",
100
+ refresh: refreshToken,
101
+ access: accessToken,
102
+ expires: getTokenExpiry(accessToken),
103
+ };
104
+ },
105
+ };
106
+ },
107
+ },
108
+ ],
109
+ },
110
+ async "chat.headers"(incoming, output) {
111
+ if (incoming.model.providerID !== CURSOR_PROVIDER_ID)
112
+ return;
113
+ output.headers["x-opencode-session-id"] = incoming.sessionID;
114
+ output.headers["x-session-id"] = incoming.sessionID;
115
+ if (incoming.agent) {
116
+ output.headers["x-opencode-agent"] = incoming.agent;
117
+ }
118
+ },
119
+ };
120
+ };
121
+ async function showDiscoveryFailureToast(input, message) {
122
+ try {
123
+ await input.client.tui.showToast({
124
+ body: {
125
+ title: "Cursor plugin disabled",
126
+ message,
127
+ variant: "error",
128
+ duration: 8_000,
129
+ },
130
+ });
131
+ }
132
+ catch (error) {
133
+ logPluginWarn("Failed to display Cursor plugin toast", {
134
+ title: "Cursor plugin disabled",
135
+ message,
136
+ ...errorDetails(error),
137
+ });
138
+ }
139
+ }
140
+ export default CursorAuthPlugin;