WuYongJie 1b6425b552 feat(desktop): connect native Pi sessions with scoped rules and recovery
Track the fixed PhotoCraft source baseline with the existing native client integration. Use the actual Pi SDK for normal sends, durable session recovery, demand-loaded enterprise rules and checked undoable canvas tools. Retain request identities and never resend unknown inference. Include local packaging and real-call acceptance evidence.
2026-10-22 10:49:58 +08:00

33 lines
2.3 KiB
JavaScript

import fs from 'node:fs/promises';
import path from 'node:path';
import assert from 'node:assert/strict';
import { NativeCanvas } from '../src/native-bridge.mjs';
import { atomic } from '../src/store.mjs';
const config = JSON.parse(await fs.readFile(process.argv[2], 'utf8'));
const canvas = await NativeCanvas.connect(config.canvas);
const cmd = (command, params = {}) => canvas.call('engine.execute', { command, params });
const flatten = layers => layers.flatMap(layer => { const { children, selected, ...row } = layer; return [row, ...flatten(children || [])]; });
try {
const current = await canvas.call('jiansun.state');
if (current.busy || current.queued) throw Error('先等待模型阶段结束,不中断原任务');
const edited = await cmd('document.inspect');
assert.equal(flatten(edited.layers).find(l => l.id === 16).text.text, '温润质感');
await cmd('edit.undo');
const unmoved = await cmd('document.inspect');
assert.equal(flatten(unmoved.layers).find(l => l.id === 16).text.text, '温润质感');
await cmd('edit.undo');
const original = await cmd('document.inspect');
const oldTitle = flatten(original.layers).find(l => l.id === 16), newTitle = flatten(edited.layers).find(l => l.id === 16);
assert.equal(oldTitle.text.text, '实木电脑桌');
assert.equal(newTitle.text.font, oldTitle.text.font); assert.equal(newTitle.text.sizePt, oldTitle.text.sizePt);
assert.deepEqual(flatten(original.layers).filter(l => l.id !== 16), flatten(edited.layers).filter(l => l.id !== 16));
await cmd('edit.redo'); await cmd('edit.redo');
const redone = await cmd('document.inspect');
assert.deepEqual(flatten(redone.layers), flatten(edited.layers));
await canvas.call('ui.screenshot', { path: path.join(config.output, 'pi-undo-redo.png'), focus: false });
await canvas.call('app.save', { path: path.join(path.dirname(config.output), 'canvas/pi-1440-local.pcraft') });
const result = { passed: true, width: edited.width, height: edited.height, target: 16, originalText: oldTitle.text.text, changedText: newTitle.text.text, font: newTitle.text.font, fontSizePt: newTitle.text.sizePt, otherLayersUnchanged: true, undoAndRedoExact: true, history: edited.history };
await atomic(path.join(config.output, 'real-model-undo-redo.json'), result);
console.log(JSON.stringify(result, null, 2));
} finally { canvas.close(); }