1. 目录 mcn-work-shop -> mcn-workshop(空间分组名取会话 cwd 的目录名,只改字符串无效,必须真改名) 2. 全仓替换 mcn-work-shop -> mcn-workshop:37 文件 121 处;历史日志按沿革句规矩保留当时目录名 3. 任务进度可见:/api/run/status 产出 已运行时长/工具调用/最近动作/停滞判定(读会话日志尾部),前端新增右下角常驻面板,四处任务入口接入 4. 会话归属目录配置化:新增 config.sessionCwd(留空=工作台自身目录),现指向 D://AI技能//mcn-workshop,使任务显示为命名分组而非「未分组任务」 5. 修前端轮询静默缺陷:连续 3 次查询失败即提示服务断开(原逻辑静默空转到 15 分钟超时,用户零感知)
71 lines
3.2 KiB
JavaScript
71 lines
3.2 KiB
JavaScript
// 验证「账号设定」内容区左右 20px 间隔(persona-wrap padding 0 20px)
|
||
const list = await fetch('http://localhost:9223/json').then((r) => r.json());
|
||
let page = list.find((t) => t.type === 'page' && t.url.includes('localhost:8899'));
|
||
if (!page) { console.log('ERR: no workbuddy page open'); process.exit(1); }
|
||
const ws = new WebSocket(page.webSocketDebuggerUrl);
|
||
let id = 0; const pending = new Map();
|
||
const send = (method, params = {}) => new Promise((res, rej) => { const i = ++id; pending.set(i, { res, rej }); ws.send(JSON.stringify({ id: i, method, params })); });
|
||
ws.onmessage = (e) => { const m = JSON.parse(e.data); if (m.id && pending.has(m.id)) { const p = pending.get(m.id); pending.delete(m.id); m.error ? p.rej(new Error(m.error.message)) : p.res(m.result); } };
|
||
await new Promise((r) => (ws.onopen = r));
|
||
const ev = async (expr) => { const r = await send('Runtime.evaluate', { expression: expr, returnByValue: true, awaitPromise: true }); if (r.exceptionDetails) return { __err: (r.exceptionDetails.exception?.description || r.exceptionDetails.text).slice(0, 300) }; return r.result.value; };
|
||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||
await send('Page.enable'); await send('Runtime.enable');
|
||
|
||
const goto = async (url) => {
|
||
await send('Page.navigate', { url });
|
||
await sleep(2500);
|
||
await send('Page.reload', { ignoreCache: true });
|
||
await sleep(3000);
|
||
};
|
||
|
||
console.log('=== 旧梦留声机 1629(有卡片)===');
|
||
await goto('http://localhost:8899/#/account/1629');
|
||
const tabClick = await ev(`(() => {
|
||
const b = document.querySelector('[data-tab="persona"]');
|
||
if (!b) return { err: 'no persona tab' };
|
||
b.click();
|
||
return 'clicked persona tab';
|
||
})()`);
|
||
console.log('切tab:', JSON.stringify(tabClick));
|
||
await sleep(1800);
|
||
|
||
const s1 = await ev(`(() => {
|
||
const wrap = document.querySelector('.persona-wrap');
|
||
const card = document.querySelector('.card-view');
|
||
const img = card && card.querySelector('img');
|
||
if (!wrap) return { err: 'no .persona-wrap' };
|
||
const cs = getComputedStyle(wrap);
|
||
const dbody = document.querySelector('.detail-body');
|
||
const dw = dbody ? dbody.getBoundingClientRect().width : null;
|
||
const ww = wrap.getBoundingClientRect().width;
|
||
const iw = img ? img.getBoundingClientRect().width : null;
|
||
return {
|
||
paddingLeft: cs.paddingLeft,
|
||
paddingRight: cs.paddingRight,
|
||
detailBodyW: dw,
|
||
wrapW: ww,
|
||
imgW: iw,
|
||
imgInset: iw !== null && dw !== null ? (dw - iw).toFixed(1) : null, // 卡片比内容区窄多少(两侧总和)
|
||
};
|
||
})()`);
|
||
console.log('persona padding 检查:', JSON.stringify(s1, null, 2));
|
||
|
||
// 切文字版后再看文字容器
|
||
const s2 = await ev(`(() => {
|
||
const btn = document.querySelector('.persona-vs-icons [data-vs="text"]');
|
||
if (btn) btn.click();
|
||
return 'switched to text';
|
||
})()`);
|
||
await sleep(600);
|
||
const s3 = await ev(`(() => {
|
||
const md = document.querySelector('.persona-text');
|
||
if (!md) return { err: 'no .persona-text' };
|
||
const dbody = document.querySelector('.detail-body');
|
||
const dw = dbody ? dbody.getBoundingClientRect().width : null;
|
||
const mw = md.getBoundingClientRect().width;
|
||
return { mdW: mw, inset: dw !== null ? (dw - mw).toFixed(1) : null };
|
||
})()`);
|
||
console.log('文字版检查:', JSON.stringify(s3, null, 2));
|
||
ws.close();
|
||
console.log('DONE');
|