@thinkingai/ae-cli 6.0.48-workbuddy.1 → 6.0.48-workbuddy.2
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.
|
@@ -262,11 +262,93 @@ function sleep(ms) {
|
|
|
262
262
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
+
// src/integrations/workbuddy/auth.ts
|
|
266
|
+
import { setTimeout as delay } from "timers/promises";
|
|
267
|
+
|
|
265
268
|
// src/integrations/workbuddy/host-page.ts
|
|
266
269
|
import { randomBytes } from "crypto";
|
|
267
270
|
import fs from "fs";
|
|
268
271
|
import { createServer } from "http";
|
|
269
272
|
import { fileURLToPath } from "url";
|
|
273
|
+
|
|
274
|
+
// src/integrations/workbuddy/entry-page.ts
|
|
275
|
+
function renderWorkBuddyEntryPage(sessionPath, nonce) {
|
|
276
|
+
return `<!doctype html>
|
|
277
|
+
<html lang="zh-CN">
|
|
278
|
+
<head>
|
|
279
|
+
<meta charset="utf-8">
|
|
280
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
281
|
+
<title>ThinkingAI \xD7 WorkBuddy</title>
|
|
282
|
+
<style nonce="${nonce}">
|
|
283
|
+
* { box-sizing: border-box; }
|
|
284
|
+
body { margin: 0; min-height: 100vh; display: grid; place-items: center; padding: 48px 24px; color: #111d35; font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; background: radial-gradient(circle at 18% 7%, rgba(64,130,255,.09), transparent 29%), radial-gradient(circle at 86% 92%, rgba(37,204,173,.08), transparent 26%), #f4f8fd; }
|
|
285
|
+
.shell { width: min(940px, 100%); padding: 48px 52px 32px; border: 1px solid #dce5f1; border-radius: 28px; background: #fff; box-shadow: 0 24px 70px rgba(35,67,115,.13); }
|
|
286
|
+
.brands { display: flex; align-items: center; justify-content: center; gap: 22px; min-height: 72px; }
|
|
287
|
+
.thinkingai { width: 256px; height: auto; }
|
|
288
|
+
.workbuddy { width: 142px; height: auto; }
|
|
289
|
+
.dots { display: flex; align-items: center; gap: 7px; padding: 0 2px; }
|
|
290
|
+
.dots i { width: 7px; height: 7px; border-radius: 50%; background: #9aa7ba; animation: pulse 1.4s ease-in-out infinite; }
|
|
291
|
+
.dots i:nth-child(2) { animation-delay: .18s; }
|
|
292
|
+
.dots i:nth-child(3) { animation-delay: .36s; }
|
|
293
|
+
@keyframes pulse { 0%, 65%, 100% { opacity: .36; transform: scale(.82); } 30% { opacity: 1; transform: scale(1.18); } }
|
|
294
|
+
h1 { margin: 30px 0 8px; text-align: center; font-size: 38px; line-height: 1.25; letter-spacing: -.8px; }
|
|
295
|
+
.routes { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-top: 34px; }
|
|
296
|
+
.route { position: relative; display: flex; min-height: 286px; flex-direction: column; padding: 28px; border: 1.5px solid #d8e2ef; border-radius: 20px; background: #fff; }
|
|
297
|
+
.route.primary { border-color: #8db9ff; background: linear-gradient(150deg, #f4f8ff, #eef6ff); box-shadow: 0 12px 30px rgba(22,115,243,.08); }
|
|
298
|
+
.badge { position: absolute; top: 20px; right: 20px; padding: 6px 10px; border-radius: 999px; color: #1368dd; background: #e4efff; font-size: 12px; font-weight: 700; }
|
|
299
|
+
.secondary .badge { color: #5d6b82; background: #eef2f7; }
|
|
300
|
+
.icon { display: grid; place-items: center; width: 48px; height: 48px; margin-bottom: 24px; border-radius: 14px; color: #fff; background: #1677ff; box-shadow: 0 9px 20px rgba(22,119,255,.2); }
|
|
301
|
+
.secondary .icon { color: #315174; background: #edf3fa; box-shadow: none; }
|
|
302
|
+
.icon svg { width: 25px; height: 25px; }
|
|
303
|
+
.route h2 { margin: 0 0 10px; font-size: 22px; letter-spacing: -.2px; }
|
|
304
|
+
.route p { margin: 0 0 16px; color: #64738c; font-size: 15px; line-height: 1.72; }
|
|
305
|
+
.route .handoff-note { color: #7b899e; font-size: 13px; }
|
|
306
|
+
.action { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 50px; margin-top: auto; border: 1px solid #c8d6e8; border-radius: 12px; color: #263852; background: #fff; font-size: 16px; font-weight: 700; text-decoration: none; }
|
|
307
|
+
.primary .action { border-color: #1677ff; color: #fff; background: #1677ff; }
|
|
308
|
+
.action:hover { background: #f3f7fc; }
|
|
309
|
+
.primary .action:hover { background: #0869ed; }
|
|
310
|
+
.action:focus-visible { outline: 3px solid #8db9ff; outline-offset: 3px; }
|
|
311
|
+
.note { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 24px 0 0; color: #7b899e; font-size: 13px; }
|
|
312
|
+
.note svg { width: 16px; height: 16px; flex: none; }
|
|
313
|
+
footer { margin-top: 22px; padding-top: 22px; border-top: 1px solid #edf1f6; color: #8995a8; text-align: center; font-size: 13px; }
|
|
314
|
+
@media (prefers-reduced-motion: reduce) { .dots i { animation: none; opacity: .65; } }
|
|
315
|
+
@media (max-width: 740px) { body { padding: 0; background: #fff; } .shell { min-height: 100vh; padding: 32px 20px 26px; border: 0; border-radius: 0; box-shadow: none; } .thinkingai { width: 188px; } .workbuddy { width: 106px; } .brands { gap: 12px; } h1 { font-size: 30px; } .routes { grid-template-columns: 1fr; } .route { min-height: 246px; } }
|
|
316
|
+
@media (max-width: 400px) { .thinkingai { width: 160px; } .workbuddy { width: 90px; } .dots { gap: 4px; } .dots i { width: 5px; height: 5px; } }
|
|
317
|
+
</style>
|
|
318
|
+
</head>
|
|
319
|
+
<body>
|
|
320
|
+
<main class="shell">
|
|
321
|
+
<div class="brands" aria-label="ThinkingAI \u4E0E WorkBuddy">
|
|
322
|
+
<img class="thinkingai" src="${sessionPath}thinkingai.svg" alt="ThinkingAI">
|
|
323
|
+
<span class="dots" aria-hidden="true"><i></i><i></i><i></i></span>
|
|
324
|
+
<img class="workbuddy" src="${sessionPath}workbuddy.png" alt="WorkBuddy">
|
|
325
|
+
</div>
|
|
326
|
+
<h1>\u9009\u62E9\u4F7F\u7528\u65B9\u5F0F</h1>
|
|
327
|
+
<section class="routes" aria-label="\u4F7F\u7528\u65B9\u5F0F">
|
|
328
|
+
<article class="route primary">
|
|
329
|
+
<span class="badge">\u63A8\u8350\u65B0\u7528\u6237</span>
|
|
330
|
+
<div class="icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3a15 15 0 0 1 0 18M12 3a15 15 0 0 0 0 18"/></svg></div>
|
|
331
|
+
<h2>\u524D\u5F80 ThinkingAI \u5B98\u7F51</h2>
|
|
332
|
+
<p>\u9996\u6B21\u4F7F\u7528 ThinkingAI\uFF0C\u6216\u5E0C\u671B\u5728\u5B98\u7F51\u5B8C\u6210\u6CE8\u518C\u3001\u5F00\u901A\u53CA\u540E\u7EED\u4F7F\u7528\u3002</p>
|
|
333
|
+
<p class="handoff-note">\u5C06\u79BB\u5F00 WorkBuddy\uFF0C\u524D\u5F80\u5B98\u7F51\u7EE7\u7EED\u4F7F\u7528\u3002</p>
|
|
334
|
+
<a class="action" href="${sessionPath}website">\u524D\u5F80\u5B98\u7F51</a>
|
|
335
|
+
</article>
|
|
336
|
+
<article class="route secondary">
|
|
337
|
+
<span class="badge">\u5DF2\u6709 AE \u7528\u6237</span>
|
|
338
|
+
<div class="icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 0 0 7.5.5l2-2a5 5 0 0 0-7-7l-1.1 1.1"/><path d="M14 11a5 5 0 0 0-7.5-.5l-2 2a5 5 0 0 0 7 7l1.1-1.1"/></svg></div>
|
|
339
|
+
<h2>\u8FDE\u63A5\u5DF2\u6709 AE \u73AF\u5883</h2>
|
|
340
|
+
<p>\u5DF2\u7ECF\u4F7F\u7528 ae-cli \u6216\u62E5\u6709 AE Host\uFF0C\u5728 WorkBuddy \u4E2D\u7EE7\u7EED\u5B8C\u6210\u8FDE\u63A5\u3002</p>
|
|
341
|
+
<a class="action" href="${sessionPath}host">\u7EE7\u7EED\u8FDE\u63A5</a>
|
|
342
|
+
</article>
|
|
343
|
+
</section>
|
|
344
|
+
<p class="note"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z"/></svg>\u8D26\u53F7\u5BC6\u7801\u53EA\u4F1A\u5728 AE \u7EDF\u4E00\u767B\u5F55\u9875\u8F93\u5165\uFF1B\u89E3\u7ED1\u540E\u53EF\u4EE5\u91CD\u65B0\u9009\u62E9\u4F7F\u7528\u65B9\u5F0F</p>
|
|
345
|
+
<footer>\u7531 WorkBuddy \xB7 ae-cli \u53D1\u8D77</footer>
|
|
346
|
+
</main>
|
|
347
|
+
</body>
|
|
348
|
+
</html>`;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// src/integrations/workbuddy/host-page.ts
|
|
270
352
|
var LOOPBACK_ADDRESS = "127.0.0.1";
|
|
271
353
|
var MAX_REQUEST_BYTES = 4096;
|
|
272
354
|
function validateWorkBuddyHost(input) {
|
|
@@ -316,6 +398,8 @@ function renderWorkBuddyHostPage(hosts, sessionPath, nonce) {
|
|
|
316
398
|
@keyframes connectionPulse { 0%, 70%, 100% { opacity: .2; transform: translateY(0) scale(.82); } 35% { opacity: 1; transform: translateY(-1px) scale(1); } }
|
|
317
399
|
h1 { margin: 0; text-align: center; font-size: 30px; line-height: 1.25; letter-spacing: -.025em; }
|
|
318
400
|
.subtitle { margin: 7px 0 22px; text-align: center; color: #62708a; font-size: 16px; }
|
|
401
|
+
.back { display: inline-block; margin-bottom: 18px; color: #62708a; font-size: 13px; text-decoration: none; }
|
|
402
|
+
.back:hover { color: #0878f9; }
|
|
319
403
|
fieldset { margin: 0; padding: 0; border: 0; }
|
|
320
404
|
legend, .field-label { display: block; margin-bottom: 10px; color: #18243c; font-size: 15px; font-weight: 700; }
|
|
321
405
|
.host-list { display: grid; gap: 8px; max-height: 188px; overflow: auto; }
|
|
@@ -353,6 +437,7 @@ function renderWorkBuddyHostPage(hosts, sessionPath, nonce) {
|
|
|
353
437
|
</head>
|
|
354
438
|
<body>
|
|
355
439
|
<main class="card">
|
|
440
|
+
<a class="back" href="${sessionPath}">\u2190 \u8FD4\u56DE\u9009\u62E9\u4F7F\u7528\u65B9\u5F0F</a>
|
|
356
441
|
<header>
|
|
357
442
|
<div class="brands" aria-label="ThinkingAI \u4E0E WorkBuddy">
|
|
358
443
|
<img class="thinkingai" src="${sessionPath}thinkingai.svg" alt="ThinkingAI">
|
|
@@ -452,13 +537,29 @@ async function startWorkBuddyHostPage(options = {}) {
|
|
|
452
537
|
const selection = new Promise((resolve) => {
|
|
453
538
|
resolveSelection = resolve;
|
|
454
539
|
});
|
|
540
|
+
let resolveWebsiteHandoff = () => {
|
|
541
|
+
};
|
|
542
|
+
const websiteHandoff = new Promise((resolve) => {
|
|
543
|
+
resolveWebsiteHandoff = resolve;
|
|
544
|
+
});
|
|
455
545
|
const server = createServer(async (request, response) => {
|
|
456
546
|
setSecurityHeaders(response, nonce);
|
|
457
547
|
const requestUrl = new URL(request.url ?? "/", `http://${LOOPBACK_ADDRESS}`);
|
|
458
548
|
if (request.method === "GET" && requestUrl.pathname === sessionPath) {
|
|
549
|
+
respond(response, 200, "text/html; charset=utf-8", renderWorkBuddyEntryPage(sessionPath, nonce));
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
if (request.method === "GET" && requestUrl.pathname === `${sessionPath}host`) {
|
|
459
553
|
respond(response, 200, "text/html; charset=utf-8", renderWorkBuddyHostPage(hosts, sessionPath, nonce));
|
|
460
554
|
return;
|
|
461
555
|
}
|
|
556
|
+
if (request.method === "GET" && requestUrl.pathname === `${sessionPath}website`) {
|
|
557
|
+
response.once("finish", resolveWebsiteHandoff);
|
|
558
|
+
response.statusCode = 302;
|
|
559
|
+
response.setHeader("Location", "https://www.thinkingai.cn/workbuddy/");
|
|
560
|
+
response.end();
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
462
563
|
if (request.method === "GET" && requestUrl.pathname === `${sessionPath}thinkingai.svg`) {
|
|
463
564
|
respond(response, 200, "image/svg+xml", assets.thinkingai);
|
|
464
565
|
return;
|
|
@@ -489,6 +590,7 @@ async function startWorkBuddyHostPage(options = {}) {
|
|
|
489
590
|
return {
|
|
490
591
|
url: `http://${LOOPBACK_ADDRESS}:${address.port}${sessionPath}`,
|
|
491
592
|
selection,
|
|
593
|
+
websiteHandoff,
|
|
492
594
|
close: () => closeServer(server)
|
|
493
595
|
};
|
|
494
596
|
}
|
|
@@ -594,12 +696,17 @@ function registerWorkBuddyAuth(auth) {
|
|
|
594
696
|
process.stderr.write(`[ae-cli] WorkBuddy host selection:
|
|
595
697
|
${page.url}
|
|
596
698
|
`);
|
|
597
|
-
const
|
|
598
|
-
page.selection.then(() =>
|
|
599
|
-
|
|
699
|
+
const outcome = await Promise.race([
|
|
700
|
+
page.selection.then(() => "selected"),
|
|
701
|
+
page.websiteHandoff.then(() => "website"),
|
|
702
|
+
waitForTerminationSignal().then(() => "terminated")
|
|
600
703
|
]);
|
|
601
704
|
await page.close();
|
|
602
|
-
if (
|
|
705
|
+
if (outcome === "website") {
|
|
706
|
+
await delay(3e3);
|
|
707
|
+
process.stderr.write("[ae-cli] Website selected; WorkBuddy authentication stopped.\n");
|
|
708
|
+
}
|
|
709
|
+
if (outcome !== "selected") process.exitCode = 1;
|
|
603
710
|
});
|
|
604
711
|
}
|
|
605
712
|
function waitForTerminationSignal() {
|
package/dist/index.js
CHANGED
|
@@ -2389,7 +2389,7 @@ async function loadCommands() {
|
|
|
2389
2389
|
}
|
|
2390
2390
|
async function registerAuthCommands() {
|
|
2391
2391
|
try {
|
|
2392
|
-
const { registerAuth } = await import("./auth-
|
|
2392
|
+
const { registerAuth } = await import("./auth-HK246OGX.js");
|
|
2393
2393
|
registerAuth(program);
|
|
2394
2394
|
} catch {
|
|
2395
2395
|
}
|