@oh-my-pi/pi-ai 6.7.670 → 6.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.
@@ -0,0 +1,199 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Authentication</title>
7
+ <style>
8
+ :root {
9
+ --bg: #09090b;
10
+ --card-bg: #18181b;
11
+ --text-main: #fafafa;
12
+ --text-muted: #a1a1aa;
13
+ --success: #22c55e;
14
+ --error: #ef4444;
15
+ --border: #27272a;
16
+ }
17
+ body {
18
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
19
+ background-color: var(--bg);
20
+ color: var(--text-main);
21
+ display: flex;
22
+ align-items: center;
23
+ justify-content: center;
24
+ height: 100vh;
25
+ margin: 0;
26
+ overflow: hidden;
27
+ }
28
+ .container {
29
+ background: var(--card-bg);
30
+ border: 1px solid var(--border);
31
+ border-radius: 12px;
32
+ padding: 2.5rem;
33
+ width: 100%;
34
+ max-width: 400px;
35
+ text-align: center;
36
+ box-shadow:
37
+ 0 20px 25px -5px rgba(0, 0, 0, 0.1),
38
+ 0 10px 10px -5px rgba(0, 0, 0, 0.04);
39
+ opacity: 0;
40
+ transform: translateY(10px);
41
+ animation: fadeIn 0.4s ease-out forwards;
42
+ }
43
+ @keyframes fadeIn {
44
+ to {
45
+ opacity: 1;
46
+ transform: translateY(0);
47
+ }
48
+ }
49
+ .icon-circle {
50
+ position: relative;
51
+ width: 64px;
52
+ height: 64px;
53
+ border-radius: 50%;
54
+ display: flex;
55
+ align-items: center;
56
+ justify-content: center;
57
+ margin: 0 auto 1.5rem;
58
+ background: rgba(255, 255, 255, 0.05);
59
+ }
60
+ .icon {
61
+ width: 32px;
62
+ height: 32px;
63
+ z-index: 2;
64
+ }
65
+ .timer-svg {
66
+ position: absolute;
67
+ top: -2px;
68
+ left: -2px;
69
+ width: 68px;
70
+ height: 68px;
71
+ transform: rotate(-90deg);
72
+ z-index: 1;
73
+ pointer-events: none;
74
+ }
75
+ .timer-circle {
76
+ fill: none;
77
+ stroke-width: 2;
78
+ stroke-linecap: round;
79
+ stroke-dasharray: 201;
80
+ stroke-dashoffset: 0;
81
+ }
82
+ .countdown .timer-circle {
83
+ animation: countdown 3s linear forwards;
84
+ }
85
+ @keyframes countdown {
86
+ to {
87
+ stroke-dashoffset: 201;
88
+ }
89
+ }
90
+ h1 {
91
+ font-size: 1.5rem;
92
+ font-weight: 600;
93
+ margin: 0 0 0.75rem;
94
+ letter-spacing: -0.025em;
95
+ }
96
+ p {
97
+ color: var(--text-muted);
98
+ line-height: 1.5;
99
+ margin: 0 0 1.5rem;
100
+ font-size: 0.95rem;
101
+ }
102
+ .btn {
103
+ display: inline-block;
104
+ background: var(--text-main);
105
+ color: var(--bg);
106
+ font-weight: 500;
107
+ padding: 0.6rem 1.2rem;
108
+ border-radius: 6px;
109
+ text-decoration: none;
110
+ font-size: 0.9rem;
111
+ transition: opacity 0.2s;
112
+ cursor: pointer;
113
+ border: none;
114
+ }
115
+ .btn:hover {
116
+ opacity: 0.9;
117
+ }
118
+
119
+ /* State: success */
120
+ .success .icon-circle {
121
+ background: rgba(34, 197, 94, 0.1);
122
+ }
123
+ .success .icon {
124
+ color: var(--success);
125
+ }
126
+ .success .timer-circle {
127
+ stroke: var(--success);
128
+ }
129
+ .success .icon-error {
130
+ display: none;
131
+ }
132
+
133
+ /* State: error */
134
+ .error .icon-circle {
135
+ background: rgba(239, 68, 68, 0.1);
136
+ }
137
+ .error .icon {
138
+ color: var(--error);
139
+ }
140
+ .error .timer-circle {
141
+ stroke: var(--error);
142
+ }
143
+ .error .icon-success,
144
+ .error .timer-svg {
145
+ display: none;
146
+ }
147
+ </style>
148
+ </head>
149
+ <body>
150
+ <div id="app" class="container">
151
+ <div class="icon-circle">
152
+ <svg class="timer-svg" viewBox="0 0 68 68">
153
+ <circle class="timer-circle" cx="34" cy="34" r="32"></circle>
154
+ </svg>
155
+ <svg class="icon icon-success" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
156
+ <path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
157
+ </svg>
158
+ <svg class="icon icon-error" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
159
+ <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
160
+ </svg>
161
+ </div>
162
+ <h1 id="title">Authentication</h1>
163
+ <p id="message"></p>
164
+ <button onclick="window.close()" class="btn">Close Window</button>
165
+ </div>
166
+
167
+ <script id="server-state" type="application/json">
168
+ __OAUTH_STATE__
169
+ </script>
170
+
171
+ <script>
172
+ let serverState;
173
+ try {
174
+ serverState = JSON.parse(document.getElementById("server-state").textContent);
175
+ } catch {
176
+ const params = new URLSearchParams(window.location.search);
177
+ serverState = {
178
+ ok: params.get("ok") === "1",
179
+ error: params.get("error") || "Authentication failed",
180
+ };
181
+ }
182
+
183
+ const app = document.getElementById("app");
184
+ const title = document.getElementById("title");
185
+ const message = document.getElementById("message");
186
+
187
+ if (serverState.ok) {
188
+ app.classList.add("success", "countdown");
189
+ title.textContent = "Authentication Successful";
190
+ message.innerHTML = "You have successfully logged in.<br>This window will close automatically.";
191
+ setTimeout(() => window.close(), 3000);
192
+ } else {
193
+ app.classList.add("error");
194
+ title.textContent = "Authentication Failed";
195
+ message.textContent = serverState.error || "An error occurred";
196
+ }
197
+ </script>
198
+ </body>
199
+ </html>