{"record":{"id":"03c7c4aa9771368d","repo":"BigPizzaV3/CodexPlusPlus","slug":"codex-canvas-user","errorCode":null,"errorMessage":"当前 Codex 版本尚未适配对话脉络，请更新插件；已有整理结果仍保留","messagePattern":"当前 Codex 版本尚未适配对话脉络，请更新插件；已有整理结果仍保留","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"tools/conversation-canvas/public/canvas.user.js","lineNumber":362,"sourceCode":"  return {async get(key){if(memory.has(key))return memory.get(key);const value=await canvasStore(`history:${key}`);if(value!==undefined)memory.set(key,value);while(memory.size>500)memory.delete(memory.keys().next().value);return value;},\n    async set(key,value){await canvasStore(`history:${key}`,value);memory.set(key,value);while(memory.size>500)memory.delete(memory.keys().next().value);},\n    async delete(key){memory.delete(key);await canvasStore(`history:${key}`,null,true);}};\n}\n\n// Private Desktop exports change between builds. Only bind reviewed contracts;\n// discovering a new asset does not make its minified export names compatible.\nconst nativeBuilds={\n  'app-initial-f87238153a19.js':{ESt:'ESt',kr:'kr',Mr:'Mr',Q1:'Q1',lGt:'lGt',cGt:'cGt',jR:'jR'},\n  'app-initial-bcc2ff475eb6.js':{ESt:'EDt',kr:'MDt',lGt:'hJt',cGt:'mJt',jR:'TW'},\n};\nfunction nativeAssetCandidates(doc=globalThis.document,perf=globalThis.performance){\n  const urls=[...Array.from(doc?.querySelectorAll?.('script[src],link[rel=\"modulepreload\"][href]')||[],e=>e.src||e.href),\n    ...(perf?.getEntriesByType?.('resource')||[]).map(e=>e.name)];\n  return [...new Set(urls.filter(url=>/^app:\\/\\/-\\/assets\\/app-initial-[\\w-]+\\.js$/.test(url)))];\n}\nfunction bindNativeRuntime(module,filename){\n  const mapping=nativeBuilds[filename];\n  if(!mapping)throw Error('当前 Codex 版本尚未适配对话脉络，请更新插件；已有整理结果仍保留');\n  const adapter={};\n  // Keep live bindings: initialization populates the HTTP class and services.\n  for(const [key,value] of Object.entries(mapping))Object.defineProperty(adapter,key,{get:()=>module[value]});\n  return adapter;\n}\nfunction createNativeLoader({discover=nativeAssetCandidates,importModule=url=>import(url)}={}){\n  let pending;\n  return function load(){\n    if(!pending)pending=(async()=>{\n      const discovered=discover();\n      // Without resource timing (e.g. after a reload), try reviewed builds only.\n      const candidates=discovered.length?discovered:Object.keys(nativeBuilds).reverse().map(name=>'app://-/assets/'+name);\n      for(const url of candidates){\n        const filename=url.split('/').pop();\n        if(!nativeBuilds[filename])continue;\n        let module;\n        try{module=await importModule(url);}catch{continue;}\n        return bindNativeRuntime(module,filename);","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/tools/conversation-canvas/public/canvas.user.js#L344-L380","documentation":"bindNativeRuntime looks up the discovered app-initial-*.js asset filename in the plugin's nativeBuilds mapping of supported Codex builds. An unmapped filename means the installed Codex app ships a build the plugin has no adapter for. The error tells the user to update the plugin; existing organize results are preserved.","triggerScenarios":"Loading the native runtime after a Codex app update changed the content-hashed asset name (app-initial-<hash>.js) so the filename has no entry in nativeBuilds.","commonSituations":"Codex desktop app auto-updated to a new version while the conversation-canvas plugin is older; or running a dev/nightly Codex build whose asset hash is not in the plugin's mapping table.","solutions":["Update the conversation-canvas plugin to a version whose nativeBuilds includes the new app-initial hash","Downgrade or pin the Codex app to a version supported by the installed plugin","Check the plugin's release notes / nativeBuilds table for the newly supported Codex version","Existing organize results are retained — export them before troubleshooting"],"exampleFix":"// before\nconst nativeBuilds={'app-initial-abc123.js':{...}};\n// after (add mapping for the new Codex build)\nconst nativeBuilds={\n  'app-initial-abc123.js':{...},\n  'app-initial-def456.js':{...} // new Codex version\n};","handlingStrategy":"fallback","validationCode":"const discovered=await nativeAssetCandidates();\nconst unsupported=discovered.some(u=>!nativeBuilds[u.split('/').pop()]);\nif(unsupported) console.warn('Codex build not supported by this plugin version; update the plugin');","typeGuard":"function isSupportedBuild(filename){ return Object.hasOwn(nativeBuilds,filename); }","tryCatchPattern":"try { runtime=await nativeGetRuntime() } catch(e){ if(String(e.message).includes('尚未适配')){ showUpdatePluginDialog(); } else throw e; }","preventionTips":["Keep the plugin updated alongside Codex app updates","Check nativeBuilds coverage after every Codex upgrade","Export existing organize results before upgrading either component"],"tags":["version-incompatibility","native-module","plugin-update"],"backgroundTag":"unsupported-platform","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}