{"record":{"id":"1a6e4c77c4892ddb","repo":"BigPizzaV3/CodexPlusPlus","slug":"codex-native-runtime","errorCode":null,"errorMessage":"当前 Codex 版本尚未适配对话脉络，请更新插件；已有整理结果仍保留","messagePattern":"当前 Codex 版本尚未适配对话脉络，请更新插件；已有整理结果仍保留","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tools/conversation-canvas/native-runtime.mjs","lineNumber":14,"sourceCode":"// Private Desktop exports change between builds. Only bind reviewed contracts;\n// discovering a new asset does not make its minified export names compatible.\nexport const 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};\nexport function 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}\nexport function 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}\nexport function 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":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/tools/conversation-canvas/native-runtime.mjs#L1-L32","documentation":"bindNativeRuntime maps minified exports of the Codex Desktop's app-initial bundle to the plugin's adapter, using the hardcoded `nativeBuilds` table keyed by exact asset filename. If the bundle filename is not in the table, the plugin has no reviewed export mapping for that Desktop build and throws, telling the user to update the plugin while preserving existing organized results.","triggerScenarios":"Calling `bindNativeRuntime(module, filename)` where `nativeBuilds[filename]` is undefined — i.e. a filename other than 'app-initial-f87238153a19.js' or 'app-initial-bcc2ff475eb6.js' (both directly, or via createNativeLoader's per-candidate check that skips unknown files).","commonSituations":"Codex Desktop auto-updated, producing a new hashed app-initial-*.js filename; running a dev/nightly Desktop build; plugin not updated after a Desktop release.","solutions":["Update the plugin to the latest release, which should contain a reviewed mapping for the new app-initial bundle hash.","Add an entry to `nativeBuilds` in native-runtime.mjs mapping the new filename to the current build's minified export names (verify each export against the bundle).","Pin/roll back the Codex Desktop version to one whose asset hash is present in nativeBuilds."],"exampleFix":"// before\nexport const nativeBuilds={\n  'app-initial-f87238153a19.js':{ESt:'ESt',kr:'kr',Mr:'Mr',Q1:'Q1',lGt:'lGt',cGt:'cGt',jR:'jR'},\n};\n// after\nexport const nativeBuilds={\n  'app-initial-f87238153a19.js':{ESt:'ESt',kr:'kr',Mr:'Mr',Q1:'Q1',lGt:'lGt',cGt:'cGt',jR:'jR'},\n  'app-initial-<newhash>.js':{ESt:'<newESt>',kr:'<newKr>',Mr:'<newMr>',Q1:'<newQ1>',lGt:'<newLGt>',cGt:'<newCGt>',jR:'<newJR>'},\n};","handlingStrategy":"try-catch","validationCode":"const supported=Object.keys(nativeBuilds);\nconst filename=assetUrl.split('/').pop();\nif(!supported.includes(filename))throw new Error('unsupported Codex build: '+filename);\n","typeGuard":"function isSupportedBuild(filename){return typeof filename==='string'&&filename in nativeBuilds;}\n","tryCatchPattern":"try{adapter=bindNativeRuntime(module,filename);}catch(e){showUpdatePromptPreservingResults(e.message);return null;}\n","preventionTips":["Check the installed app-initial asset hash against nativeBuilds before enabling the conversation-canvas feature.","Update the plugin whenever Codex Desktop updates (asset hashes change per build).","Never hand-bind unreviewed minified export names; only use reviewed nativeBuilds entries."],"tags":["version-compatibility","native-binding","codex-desktop"],"backgroundTag":"unsupported-version","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"}