@lightcone-ai/daemon 0.9.54 → 0.9.56
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.
|
@@ -33,24 +33,45 @@ export class XhsAdapter {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
async checkLoginStatus() {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
//
|
|
43
|
-
await this._cdp.send('
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
36
|
+
const profileDir = process.env.XHS_PROFILE_DIR ?? '(not set)';
|
|
37
|
+
|
|
38
|
+
// Step 1: navigate to www first to establish session context (same as login origin)
|
|
39
|
+
await this._cdp.send('Page.navigate', { url: 'https://www.xiaohongshu.com' });
|
|
40
|
+
await sleep(4000);
|
|
41
|
+
|
|
42
|
+
// Step 2: check login via window.__INITIAL_STATE__ (auto-agent approach — more reliable than URL check)
|
|
43
|
+
const stateResult = await this._cdp.send('Runtime.evaluate', {
|
|
44
|
+
expression: `(function() {
|
|
45
|
+
try {
|
|
46
|
+
const state = window.__INITIAL_STATE__ || {};
|
|
47
|
+
const userInfo = state?.user?.userInfo?._rawValue || state?.user?.userInfo || {};
|
|
48
|
+
const userId = userInfo.userId || userInfo.userID || null;
|
|
49
|
+
const nickname = userInfo.nickname || userInfo.nickName || null;
|
|
50
|
+
return JSON.stringify({ userId, nickname });
|
|
51
|
+
} catch(e) { return JSON.stringify({ error: e.message }); }
|
|
52
|
+
})()`,
|
|
47
53
|
returnByValue: true,
|
|
48
54
|
});
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
const stateStr = stateResult.result?.value ?? '{}';
|
|
56
|
+
let stateData = {};
|
|
57
|
+
try { stateData = JSON.parse(stateStr); } catch {}
|
|
58
|
+
|
|
59
|
+
const loggedInViaState = !!(stateData.userId || stateData.nickname);
|
|
60
|
+
console.error(`[XhsAdapter] __INITIAL_STATE__ check: ${stateStr}`);
|
|
61
|
+
|
|
62
|
+
// Step 3: if logged in via state, also verify creator access
|
|
63
|
+
let creatorUrl = '';
|
|
64
|
+
if (loggedInViaState) {
|
|
65
|
+
await this._cdp.send('Page.navigate', { url: 'https://creator.xiaohongshu.com/publish/publish' });
|
|
66
|
+
await sleep(5000);
|
|
67
|
+
const urlResult = await this._cdp.send('Runtime.evaluate', { expression: 'window.location.href', returnByValue: true });
|
|
68
|
+
creatorUrl = urlResult.result?.value ?? '';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const loggedIn = loggedInViaState;
|
|
72
|
+
const url = creatorUrl || 'www check only';
|
|
73
|
+
console.error(`[XhsAdapter] checkLoginStatus: loggedIn=${loggedIn} creatorUrl=${creatorUrl} profileDir=${profileDir}`);
|
|
74
|
+
return { loggedIn, url, profileDir, userId: stateData.userId, nickname: stateData.nickname };
|
|
54
75
|
}
|
|
55
76
|
|
|
56
77
|
async publishImageText({ title, text, tags = [], images = [] }) {
|
|
@@ -152,13 +152,13 @@ server.tool(
|
|
|
152
152
|
const label = PLATFORM_LABELS[platform] ?? platform;
|
|
153
153
|
try {
|
|
154
154
|
const adapter = await getAdapter(platform);
|
|
155
|
-
const { loggedIn, url, profileDir,
|
|
155
|
+
const { loggedIn, url, profileDir, userId, nickname } = await adapter.checkLoginStatus();
|
|
156
156
|
if (loggedIn) {
|
|
157
|
-
return { content: [{ type: 'text', text: `✓ ${label}
|
|
157
|
+
return { content: [{ type: 'text', text: `✓ ${label} 已登录,用户: ${nickname ?? userId ?? '未知'},可以发布内容。` }] };
|
|
158
158
|
} else {
|
|
159
159
|
closeSession(platform);
|
|
160
160
|
return {
|
|
161
|
-
content: [{ type: 'text', text: `${label} 未登录或登录已过期。\n调试信息:
|
|
161
|
+
content: [{ type: 'text', text: `${label} 未登录或登录已过期。\n调试信息: url=${url}\nprofileDir=${profileDir}\nuserId=${userId} nickname=${nickname}\n请在「连接外部账号」中重新扫码连接。` }],
|
|
162
162
|
isError: true,
|
|
163
163
|
};
|
|
164
164
|
}
|
package/package.json
CHANGED
package/src/browser-login.js
CHANGED
|
@@ -256,9 +256,16 @@ export class BrowserLoginSession {
|
|
|
256
256
|
// Export decrypted cookies to cookies.json so chrome-pool can inject them
|
|
257
257
|
// without relying on platform-specific keychain encryption (fixes macOS cross-process issue)
|
|
258
258
|
try {
|
|
259
|
+
// For XHS: also visit creator subdomain so it sets its own session tokens
|
|
260
|
+
// before we snapshot cookies — otherwise creator.xiaohongshu.com rejects the session
|
|
261
|
+
if (this._platform === 'xhs') {
|
|
262
|
+
await this.send('Page.navigate', { url: 'https://creator.xiaohongshu.com' });
|
|
263
|
+
await sleep(4000);
|
|
264
|
+
}
|
|
259
265
|
const cookieResult = await this.send('Network.getAllCookies', {});
|
|
266
|
+
const baseDomain = new URL(this._config.loginUrl).hostname.split('.').slice(-2).join('.');
|
|
260
267
|
const cookies = (cookieResult.cookies ?? []).filter(c =>
|
|
261
|
-
c.domain.includes(
|
|
268
|
+
c.domain.includes(baseDomain)
|
|
262
269
|
);
|
|
263
270
|
writeFileSync(path.join(this._profileDir, 'cookies.json'), JSON.stringify(cookies));
|
|
264
271
|
console.log(`[BrowserLogin][${this._platform}] Saved ${cookies.length} cookies to cookies.json`);
|