PPysolate SpineREAD THE CODE · UNDERSTAND THE SYSTEM
课程与章节
源码索引 / CURRENT IMPLEMENTATION

site/scripts/prepare.mjs

106 行 · 点击行号可定位;函数链接随声明位置更新,不手填行号。

/* Public view: redacted lines; not a complete executable copy. */ // Explicit publishing boundary: only listed docs/source, never the whole repository.
import fs from 'node:fs';
import path from 'node:path';
import { symbolsFor } from './symbols.mjs';
import { readings, readingSources } from './readings.mjs'; import { goPatternDocs, goPatternSources } from './go-patterns.mjs'; import { deepDocs, deepSources } from './deep.mjs';
import { expandExcerpts, verifyCoverage } from './excerpts.mjs';
const root = path.resolve('..');
const docs = [
  ['foundations', '前置课程:从刚入门开始', 'docs/foundations/index.md', '只默认基本编程,先建立理解实现所需的知识地图。', 'basics'],
  ['basics-tools', '工程工具与数据', 'docs/foundations/engineering-basics.md', '终端、文件、依赖、JSON 与测试分别在做什么。', 'basics'],
  ['basics-go', 'Go 语言入门', 'docs/foundations/go-language.md', '从函数和变量读到 struct、方法与接口。', 'basics'],
  ['basics-values', 'Go 的值与内存', 'docs/foundations/go-values.md', '指针、slice、map、拷贝与生命周期。', 'basics'],
  ['basics-execution', '程序怎样运行', 'docs/foundations/execution-stack.md', '编译、解释、CPython、Wasm 与 Host/Guest。', 'basics'],
  ['basics-memory', '内存与跨语言 ABI', 'docs/foundations/memory-abi.md', '从 bit/byte 到指针、buffer 与引用计数。', 'basics'],
  ['basics-concurrency', '并发、等待与取消', 'docs/foundations/concurrency.md', 'goroutine、channel、可见性和任务收尾。', 'basics'],
  ['basics-plm', 'PLM 的思考基础', 'docs/foundations/plm-reasoning.md', '依赖、AST、只读快照与交付时机。', 'basics'],
  ['basics-linux', 'Ubuntu 构建与离线演示', 'docs/foundations/linux-build-and-offline.md', 'WSL、交叉编译、构建缓存与 network namespace。', 'basics'],
  ['basics-web', 'Web 与发布(可选)', 'docs/foundations/web-basics.md', '浏览器、HTTP、Pages,以及 noindex 的边界。', 'basics'],

  ['research-positioning', 'Pysolate 定位:云端 Agent 执行', 'docs/research/cloud-agent-execution.md', '轻重执行分工、驻留成本与固定资源下的任务容量。', 'research'],
  ['research-reuse', '研究探索:生成代码复用', 'docs/research/reusable-code-exploration.md', '从问题定义、方法方向到实验数据与后续设想。', 'research'],
  ['research-memory', '内存优化历程:每个新增 Guest 的成本', 'docs/research/memory-optimization.md', '从引擎冗余、COW 写放大到分配器布局,记录配对数据与失败方案。', 'research'],
  ['guide', '学习顺序与完整路径', 'docs/learning-guide.md', '从两行 Python 到 Host 边界,逐步读懂实现。'],
  ['flow', '调用与状态图', 'docs/execution-flow.md', '区分 Guest 控制流、Host 任务与 Future。'],
  ['plm', 'Whole-program PLM', 'docs/whole-program-plm.md', '依赖、控制流与原调用处的结果交付。'],
  ['prefix', '流式 Prefix', 'docs/prefix.md', '接收完整语句,复用同一个 Guest 与 Future。'],
  ['prepared-copy', '可选:Prepared full-copy', 'docs/prepared-copy.md', '先理解干净基线与全量私有副本。'],
  ['cow', 'Linux COW:共享与隔离', 'docs/cow.md', '虚拟内存、memfd、同地址映射与私有写入。'],
  ['examples', '五个边界例子', 'docs/walkthrough-examples.md', '独立、依赖、分支、错误和正常回退。'],
  ['python-provider', 'Python 工具实现', 'docs/python-provider.md', 'Guest 经固定 Go 桥调用 native Python worker。'],
  ['python-editor', 'Python IDE 类型提示', 'docs/python-editor.md', '保留原始源码,用静态声明识别注入工具。'],
  ['core-demos', '四个核心 Demo', 'docs/core-demos.md', '普通调用、PLM、prefix、隔离与 prepared 复用。'],
  ['demo-walkthrough', '扩展:报告与通知', 'docs/demo-walkthrough.md', '一个 Python 程序,三个 Host 结果,沿调用链理解执行与状态信息。'],
  ['interview', '演示与协作练习', 'docs/interview-playbook.md', '运行入口、讲解顺序和未解答的小需求。'],
  ['questions', '六张追问卡', 'docs/question-cards.md', '带源码入口的问题,不替你写标准答案。'],
  ['build', '构建与来源', 'docs/build-and-provenance.md', '实际 Wasm 的打包边界与使用条件。'], ['meal-curriculum', '饭点课分课路线', 'docs/meal-curriculum.md', '流程课与知识小点怎样对应代码带读。'],
  ['repository', '仓库说明', 'README.md', '命令、实现范围与文件导航。'],
];
const sourceFiles = [
  'cmd/python-provider/main.go', 'cmd/python-provider/main_test.go', 'examples/python_provider.py',
  'providers/report.py', 'examples/typings/__builtins__.pyi', 'pyrightconfig.json',
  'cmd/walkthrough/main.go', 'cmd/walkthrough/main_test.go', 'examples/notification.py', 'demos/walkthrough.sh', 'demos/core.sh',
  'runner.go', 'bridge.go', 'future.go', 'prefix.go', 'prepared.go',
  'cow.go', 'cow_linux.go', 'cow_other.go', 'cow_test.go', 'cow_linux_test.go',
  'guest/bootstrap.py', 'guest/plm.py', 'guest/prefix.py', 'guest/runtime.c',
  'cmd/demo/main.go', 'runner_test.go', 'plm_test.go', 'prefix_test.go', 'prepared_test.go',
  'cmd/demo/main_test.go', 'guest/test_plm.py', 'guest/test_prefix.py',
  'examples/lookup.py', 'examples/order.py', 'examples/dependency.py', 'examples/branch.py',
  'examples/error_delivery.py', 'examples/fallback.py', 'build-guest.sh', 'Makefile',
  'tools/setup-build-inputs.py', 'tools/build-inputs.lock.json',
  'go.mod', 'go.sum', 'LICENSE', '.gitignore', 'tools/offline-check.sh', 'tools/read-local.sh', 'site/public/_headers',
];
docs.unshift(...readings.map(([slug,title,file,description])=>[slug,title,`docs/code-reading/${file}.md`,description,'reading'])); docs.unshift(['order-tour','先跟完一次 order.py','docs/order-function-tour.md','按函数职责和调用目的读正常执行路径。','reading']);
sourceFiles.push(...readingSources.filter(name=>!sourceFiles.includes(name))); docs.push(...goPatternDocs, ...deepDocs); sourceFiles.push(...goPatternSources(root), ...deepSources); docs.push(['trading-demo','模拟交易:控制流与工具许可','docs/trading-demo.md','带时间戳观察安全读取、分支和本地下单。']); sourceFiles.push('examples/trading.py','cmd/trade-demo/main.go','cmd/trade-demo/market.go','cmd/trade-demo/main_test.go','cmd/trade-demo/market_test.go'); sourceFiles.push(...['run.sh','trade.sh','01-price-skip.sh','02-cash-skip.sh','03-host-denied.sh','04-approved.sh','05-prefix.sh','06-plm-source.sh'].map(name=>'demos/'+name));
const id = name => name.replace(/[^a-z0-9]+/gi, '-').replace(/^-|-$/g, '').toLowerCase();
const routes = new Map(docs.map(([slug,,file]) => [file, `/${slug}/`]));
for (const file of sourceFiles) routes.set(file, `/code/${id(file)}/`);
routes.set('site/public/plm-flow.svg', '/plm-flow.svg'); routes.set('site/public/deep-memory-domains.svg', '/deep-memory-domains.svg');
routes.set('site/public/robots.txt', '/robots.txt');
routes.set('tools/rebuild-guest.py', '/build/'); // Private machine defaults stay local.
/* [REDACTED: private operational rule] */
function check(text, name) {
  for (const pattern of forbidden) if (pattern.test(text)) throw new Error(`Private operational detail in ${name}: ${pattern}`);
}
// Only the privacy-rule implementations have a visibly redacted public view.
// Other source files still fail closed if private operational details appear.
const ruleFiles = new Set(['site/scripts/prepare.mjs', 'site/scripts/verify.mjs']);
const sources = [...new Set(sourceFiles)].map(name => {
  let code = fs.readFileSync(path.join(root,name),'utf8'), redacted = false;
  if (ruleFiles.has(name)) {
    code = code.split('\n').map(line=>{
      try { check(line,name); return line; }
      catch { redacted = true; return '/* [REDACTED: private operational rule] */'; }
    }).join('\n');
    if (redacted) code = '/* Public view: redacted lines; not a complete executable copy. */ '+code;
  }
  check(code,name);
  const ext = path.extname(name);
  const lang = ({'.go':'go','.py':'python','.c':'c','.sh':'bash','.mjs':'js','.ts':'ts','.astro':'astro','.css':'css','.json':'json'})[ext] || 'text';
  return {id:id(name),name,code,lang,redacted,symbols:symbolsFor(name,code)};
});
const sourceMap = new Map(sources.map(s=>[s.name,s]));
const usedLines = new Map();
fs.rmSync('.generated', { recursive: true, force: true });
fs.mkdirSync('.generated/docs', { recursive: true });
for (const [order, [slug,title,file,description,section = 'implementation']] of docs.entries()) {
  let body = fs.readFileSync(path.join(root,file), 'utf8');
  body = body.replace(/\]\(([^)]+)\)/g, (whole, target) => {
    if (/^(https?:|#|mailto:)/.test(target)) return whole;
    const [name,fragment] = target.split('#');
    const resolved = path.posix.normalize(path.posix.join(path.posix.dirname(file),name));
    const route = routes.get(resolved);
    if (!route) throw new Error(`Unlisted publication link: ${file} -> ${target}`);
    return `](${route}${fragment ? '#'+fragment : ''})`;
  });
  body = expandExcerpts(body,sourceMap,usedLines);
  check(body,file);
  body = body.replace(/^# [^\n]*\n/, '');
  fs.writeFileSync(`.generated/docs/${slug}.md`, `---\ntitle: ${JSON.stringify(title)}\norder: ${order}\nsection: ${JSON.stringify(section)}\ndescription: ${JSON.stringify(description)}\n---\n${body}`);
}
const coverage = verifyCoverage(sourceMap,readingSources,usedLines);
fs.writeFileSync('.generated/reading-coverage.json', JSON.stringify(coverage));
console.log(`Reading excerpts cover ${coverage.length} source files, ${coverage.reduce((n,f)=>n+f.covered,0)} nonblank lines.`);
fs.writeFileSync('.generated/sources.json', JSON.stringify(sources));
fs.writeFileSync('.generated/navigation.json', JSON.stringify(docs.map(([slug,title,,description,section = 'implementation'])=>({slug,title,description,section}))));
console.log(`Publishing ${docs.length} documents and ${sources.length} source views; no runtime artifacts.`);