gongxiangp2/apps/detail-agent-pi/scripts/read-public-contract.mjs
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

29 lines
1.8 KiB
JavaScript

import fs from 'node:fs/promises';
import path from 'node:path';
import { createHash } from 'node:crypto';
// Public documentation only. Never read a credential or follow an upstream redirect.
const output = path.resolve(process.argv[2] || 'output/pi-compatibility-20261021/public-docs');
await fs.mkdir(output, { recursive: true });
const paths = ['/api/v2/catalog/models?format=skill', '/api/v2/catalog/models', '/docs', '/openapi.json'];
const results = await Promise.all(paths.map(async (pathname, index) => {
try {
const response = await fetch('https://api.vip98k.com' + pathname, {
method: 'GET', redirect: 'manual', signal: AbortSignal.timeout(25000),
headers: { Accept: 'application/json, text/markdown, text/html;q=0.8' },
});
const text = await response.text();
if (Buffer.byteLength(text) > 8 * 1024 * 1024) throw Error('公开文档超过8MB验证上限');
const file = path.join(output, `${index}.txt`);
await fs.writeFile(file, text);
let value;
try { value = JSON.parse(text); } catch { /* A documentation page can be Markdown or HTML. */ }
return { path: pathname, status: response.status, contentType: response.headers.get('content-type'), bytes: Buffer.byteLength(text),
sha256: createHash('sha256').update(text).digest('hex'), file, keys: value ? Object.keys(value) : undefined,
title: text.match(/<title[^>]*>(.*?)<\/title>/)?.[1],
links: !value ? [...text.matchAll(/href=["']([^"']+)["']/g)].map(m => m[1]).filter(s => /doc|openapi|swagger|skill|api/i.test(s)).slice(0, 20) : undefined };
} catch (error) { return { path: pathname, error: error.message }; }
}));
await fs.writeFile(path.join(output, 'index.json'), JSON.stringify({ at: new Date().toISOString(), scope: 'public-GET-only', results }, null, 2));
console.log(JSON.stringify(results, null, 2));