{
  "date": "2026-10-27",
  "source_resource": {
    "id": 60031,
    "offset": 24271366,
    "stored_bytes": 121181,
    "decoded_bytes": 417688,
    "compression": "gzip",
    "sha256": "abb264be0fb55cdef93096d6a77bc3a8c074a5ee0f8609ec3a4b7fffb2d29189",
    "file": "pak-60031.txt",
    "decoded_sha256": "913f16f4ec418b4ff6ccc5693ae8b15c86d7c13fdf40cac2fa37be528f6d29a4",
    "excerpts": [
      {
        "keyword": "chrome.bookmarks",
        "at": 105332,
        "text": "ment:o},t),cancel:e=>d.cancel(o,e),dispose:s}}class Ln{constructor(){}static getInstance(){return Ln.instance||(Ln.instance=new Ln),Ln.instance}checkBookmarksAPIAvailability(){if(!chrome.bookmarks)return console.warn(\"[BME] api not available\"),!1;const e=[\"getMetaInfo\",\"setMetaInfo\",\"deleteMetaInfo\",\"getRootChildId\"].filter(e=>!chrome.bookmarks[e]);return!(e.length>0&&(console.warn(`[BME] missing meta methods: ${e.join(\", \")}`),1))}async setMetaInfo(e,t,r){return new Promise((n,a)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.setMetaInfo(e,t,r,()=>{chrome.runtime.lastError?a(chrome.runtime.lastError):n()}):a(new Error(\"chrome.bookmarks API 不可用\"))})}async getMetaInfo(e,t){return new Promise((r,n)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.getMetaInfo(e,t,e=>{chrome.runtime.lastError?n(chrome.runtime.lastError):r(e)}):n(new Error(\"chrome.bookmarks API 不可用\"))})}async deleteMetaInfo(e,t){return new"
      },
      {
        "keyword": "chrome.bookmarks",
        "at": 105482,
        "text": "ookmarksAPIAvailability(){if(!chrome.bookmarks)return console.warn(\"[BME] api not available\"),!1;const e=[\"getMetaInfo\",\"setMetaInfo\",\"deleteMetaInfo\",\"getRootChildId\"].filter(e=>!chrome.bookmarks[e]);return!(e.length>0&&(console.warn(`[BME] missing meta methods: ${e.join(\", \")}`),1))}async setMetaInfo(e,t,r){return new Promise((n,a)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.setMetaInfo(e,t,r,()=>{chrome.runtime.lastError?a(chrome.runtime.lastError):n()}):a(new Error(\"chrome.bookmarks API 不可用\"))})}async getMetaInfo(e,t){return new Promise((r,n)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.getMetaInfo(e,t,e=>{chrome.runtime.lastError?n(chrome.runtime.lastError):r(e)}):n(new Error(\"chrome.bookmarks API 不可用\"))})}async deleteMetaInfo(e,t){return new Promise((r,n)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.deleteMetaInfo(e,t,()=>{chrome.runtime.lastError?n(chrome.runtime.lastError):r("
      },
      {
        "keyword": "chrome.bookmarks",
        "at": 105677,
        "text": "s[e]);return!(e.length>0&&(console.warn(`[BME] missing meta methods: ${e.join(\", \")}`),1))}async setMetaInfo(e,t,r){return new Promise((n,a)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.setMetaInfo(e,t,r,()=>{chrome.runtime.lastError?a(chrome.runtime.lastError):n()}):a(new Error(\"chrome.bookmarks API 不可用\"))})}async getMetaInfo(e,t){return new Promise((r,n)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.getMetaInfo(e,t,e=>{chrome.runtime.lastError?n(chrome.runtime.lastError):r(e)}):n(new Error(\"chrome.bookmarks API 不可用\"))})}async deleteMetaInfo(e,t){return new Promise((r,n)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.deleteMetaInfo(e,t,()=>{chrome.runtime.lastError?n(chrome.runtime.lastError):r()}):n(new Error(\"chrome.bookmarks API 不可用\"))})}async hasGuid(e){try{const t=await this.getBookmark(e);return!!t?.guid}catch(e){return console.error(\"[BME] check guid failed:\",e),!1}}async getGuid"
      },
      {
        "keyword": "chrome.bookmarks",
        "at": 105789,
        "text": ",r){return new Promise((n,a)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.setMetaInfo(e,t,r,()=>{chrome.runtime.lastError?a(chrome.runtime.lastError):n()}):a(new Error(\"chrome.bookmarks API 不可用\"))})}async getMetaInfo(e,t){return new Promise((r,n)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.getMetaInfo(e,t,e=>{chrome.runtime.lastError?n(chrome.runtime.lastError):r(e)}):n(new Error(\"chrome.bookmarks API 不可用\"))})}async deleteMetaInfo(e,t){return new Promise((r,n)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.deleteMetaInfo(e,t,()=>{chrome.runtime.lastError?n(chrome.runtime.lastError):r()}):n(new Error(\"chrome.bookmarks API 不可用\"))})}async hasGuid(e){try{const t=await this.getBookmark(e);return!!t?.guid}catch(e){return console.error(\"[BME] check guid failed:\",e),!1}}async getGuid(e){try{const t=await this.getBookmark(e);return t?.guid}catch(e){return void console.error(\"[BME] get guid fail"
      },
      {
        "keyword": "chrome.bookmarks",
        "at": 105906,
        "text": "ntime.lastError?a(chrome.runtime.lastError):n()}):a(new Error(\"chrome.bookmarks API 不可用\"))})}async getMetaInfo(e,t){return new Promise((r,n)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.getMetaInfo(e,t,e=>{chrome.runtime.lastError?n(chrome.runtime.lastError):r(e)}):n(new Error(\"chrome.bookmarks API 不可用\"))})}async deleteMetaInfo(e,t){return new Promise((r,n)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.deleteMetaInfo(e,t,()=>{chrome.runtime.lastError?n(chrome.runtime.lastError):r()}):n(new Error(\"chrome.bookmarks API 不可用\"))})}async hasGuid(e){try{const t=await this.getBookmark(e);return!!t?.guid}catch(e){return console.error(\"[BME] check guid failed:\",e),!1}}async getGuid(e){try{const t=await this.getBookmark(e);return t?.guid}catch(e){return void console.error(\"[BME] get guid failed:\",e)}}async getBookmark(e){return new Promise((t,r)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.get(e,"
      }
    ]
  },
  "contexts": [
    {
      "purpose": "cloud bookmarks switch lookup and login/switch listeners",
      "needle": "cloud_bookmarks",
      "excerpt": {
        "at": 4107,
        "text": "it async function(){try{return await ne().getSwitchConfigsWithState()}catch(e){return console.error(\"[TabInstanceManager] get switch configs error:\",e),null}}();return e?.find(e=>\"cloud_bookmarks\"===e.name)?.currentState??!1}catch(e){return console.error(\"[TabInstanceManager] check cloud bookmarks state failed:\",e),!1}}const ie=\"https\",ce=\"tabbit.com\",le=\"tabbit.ai\",de=\"skills\",ue=\"/plaza/skills\",he=[ce,le];function me(e,t){return`${e}.${t}`}function ge(e,t=\"\"){return`${ie}://${e}${t}`}const fe=me(\"web\",ce),pe=he.map(e=>me(\"web\",e));async function we(){try{return await async function(){try{return await ne().getTabScheme()}catch(e){return console.error(\"[TabInstanceManager] get scheme config error:\",e),null}}()||ie}catch(e){return console.warn(\"Failed to get tab scheme, using default:\",e),ie}}async function ye(){try{return await async function(){try{return await ne().getTabHost()}catch(e){return console.error(\"[TabInstanceManager] get host config error:\",e),null}}()||fe}catch(e){return console.warn(\"Failed to get tab host, using default:\",e),fe}}async function be()"
      }
    },
    {
      "purpose": "custom metadata API",
      "needle": "chrome.bookmarks.setMetaInfo",
      "excerpt": {
        "at": 105677,
        "text": "s[e]);return!(e.length>0&&(console.warn(`[BME] missing meta methods: ${e.join(\", \")}`),1))}async setMetaInfo(e,t,r){return new Promise((n,a)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.setMetaInfo(e,t,r,()=>{chrome.runtime.lastError?a(chrome.runtime.lastError):n()}):a(new Error(\"chrome.bookmarks API 不可用\"))})}async getMetaInfo(e,t){return new Promise((r,n)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.getMetaInfo(e,t,e=>{chrome.runtime.lastError?n(chrome.runtime.lastError):r(e)}):n(new Error(\"chrome.bookmarks API 不可用\"))})}async deleteMetaInfo(e,t){return new Promise((r,n)=>{this.checkBookmarksAPIAvailability()?chrome.bookmarks.deleteMetaInfo(e,t,()=>{chrome.runtime.lastError?n(chrome.runtime.lastError):r()}):n(new Error(\"chrome.bookmarks API 不可用\"))})}async hasGuid(e){try{const t=await this.getBookmark(e);return!!t?.guid}catch(e){return console.error(\"[BME] check guid failed:\",e),!1}}async getGuid(e){try{const t=await this.getBookmark(e);return t?.guid}catch(e){return void console.error(\"[BME] get guid failed:\",e)}}async getBookmark(e){return n"
      }
    },
    {
      "purpose": "AI bookmark summary scheduler",
      "needle": "bookmark-summary-work",
      "excerpt": {
        "at": 113911,
        "text": "IME type: ${e}`),e)}return\"WEBPAGE\"}catch(e){return\"WEBPAGE\"}}const Yn=\"ext.summary\",Xn=\"bookmark_summary_progress\",Jn=\"task_failure_records\",Zn=2048,ea=52428800,ta=3e5,ra=3e5,na=\"bookmark-summary-work\",aa=\"bookmark-summary-periodic\",oa=3e5,sa=6e4,ia=18e5,ca=()=>$e.strings.bookmarkSummary.cdpTimeout,la=()=>$e.strings.bookmarkSummary.fetchEmptyContent,da=()=>$e.strings.bookmarkSummary.unsupportedType,ua=()=>$e.strings.bookmarkSummary.contentNotExist,ha=()=>$e.strings.bookmarkSummary.generateSummaryError,ma=()=>$e.strings.bookmarkSummary.regenerateSummaryError,ga=\"任务已取消\";class fa extends Error{constructor(e){super(e),this.name=\"NotFoundError\"}}class pa extends Error{constructor(e){super(e),this.name=\"UnSupportTypeError\"}}class wa extends Error{constructor(e){super(e),this.name=\"ServiceResponseError\"}}class ya extends Error{constructor(e){super(e),this.name=\"FileServiceResponseError\"}}class ba extends Error{constructor(e){super(e),this.name=\"FileUploadError\"}}class Ia extends Error{constructor(e){super(e),this.name=\"RateLimitError\"}}class Ea extends Error{constructor"
      }
    },
    {
      "purpose": "bookmark summary metadata key",
      "needle": "const Yn=\"ext.summary\"",
      "excerpt": {
        "at": 113793,
        "text": ".log(`[FileDetector] Detected HTML content, forcing WEBPAGE: ${e}`),\"WEBPAGE\"):(console.log(`[FileDetector] Detected MIME type: ${e}`),e)}return\"WEBPAGE\"}catch(e){return\"WEBPAGE\"}}const Yn=\"ext.summary\",Xn=\"bookmark_summary_progress\",Jn=\"task_failure_records\",Zn=2048,ea=52428800,ta=3e5,ra=3e5,na=\"bookmark-summary-work\",aa=\"bookmark-summary-periodic\",oa=3e5,sa=6e4,ia=18e5,ca=()=>$e.strings.bookmarkSummary.cdpTimeout,la=()=>$e.strings.bookmarkSummary.fetchEmptyContent,da=()=>$e.strings.bookmarkSummary.unsupportedType,ua=()=>$e.strings.bookmarkSummary.contentNotExist,ha=()=>$e.strings.bookmarkSummary.generateSummaryError,ma=()=>$e.strings.bookmarkSummary.regenerateSummaryError,ga=\"任务已取消\";class fa extends Error{constructor(e){super(e),this.name=\"NotFoundError\"}}class pa extends Error{constructor(e){super(e),this.name=\"UnSupportTypeError\"}}class wa extends Error{constructor(e){super(e),this.name=\"ServiceResponseError\"}}class ya extends Error{constructor(e){super(e),this.name=\"FileServiceResponseError\"}}class ba extends Error{constructor(e){super(e),this.name=\"FileUploa"
      }
    },
    {
      "purpose": "selective URL update listener",
      "needle": "chrome.bookmarks.onChangedSelective",
      "excerpt": {
        "at": 270494,
        "text": "it this.addToPendingQueue({id:t.id,guid:t.guid,url:t.url,title:t.title})}catch(t){console.error(Sl,\"书签创建处理失败:\",e,t)}else console.log(Sl,\"跳过文件夹类型的书签:\",e)})}setupUpdateListener(){if(chrome.bookmarks.onChangedSelective?.addListener)try{chrome.bookmarks.onChangedSelective.addListener(async(e,t)=>{if(!await this.isReadyForEvent())return;if(console.log(Sl,\"检测到书签更新:\",{id:e,changeInfo:t}),!t.url)return void console.log(Sl,\"非URL更新，跳过:\",e);const r=Date.now()+300;try{if(await Il.record(e,r),!this.isListening)return;await yl.ensureAfter(oa),await this.processUrlChange(e,r)}catch(t){console.error(Sl,\"书签更新处理失败:\",e,t)}})}catch(e){console.warn(Sl,\"onChangedSelective 监听器注册失败:\",e)}else console.warn(Sl,\"onChangedSelective API 不可用，跳过URL更新监听\")}setupRemoveListener(){chrome.bookmarks.onRemoved.addListener(async(e,t)=>{if(await this.isReadyForEvent())try{const r=await this.removeBookmarkAndChildren(t.node);r.length>0&&ul.onBookmarksRemovedBatch(r),console.log(Sl,`书签移除完成: ${t.node.title||\"(无标题)\"} (${e}), 移除数量: ${r.length}`)}catch(t){console.error(Sl,\"书签移除处理失败:\",e,t)}})}async removeBookmar"
      }
    },
    {
      "purpose": "bookmark URL change -> summary regeneration",
      "needle": "onBookmarkUrlChangedOrRegenerator",
      "excerpt": {
        "at": 234468,
        "text": "ompletedCountFromStorage=Math.max(0,this.completedCountFromStorage-1)),console.log(dl,`书签删除: total=${this.totalCount}, pending=${this.pendingSet.size}`),this.saveToStorage()}async onBookmarkUrlChangedOrRegenerator(e){this.markLocalMutation();const t=this.pendingSet.has(e);this.pendingSet.add(e),this.alreadyWritten.delete(e),this.initializedFromScan||t||(this.completedCountFromStorage=Math.max(0,this.completedCountFromStorage-1)),console.log(dl,`URL变化或者重新生成: pending=${this.pendingSet.size}`),this.saveToStorage()}onSummaryWritten(e){if(this.alreadyWritten.has(e))return void this.pendingSet.delete(e);this.alreadyWritten.add(e);const t=this.pendingSet.has(e);this.pendingSet.delete(e),t?(this.markLocalMutation(),this.initializedFromScan||this.completedCountFromStorage++):(this.initializedFromScan||this.completedCountFromStorage++,console.warn(dl,`summ done fallback: guid=${e.substring(0,8)} not in pendingSet`)),console.log(dl,`summ done: pending=${this.pendingSet.size}, completed=${this.initializedFromScan?this.totalCount-this.pendingSet.size:this.completedCountFromSto"
      }
    }
  ],
  "feature_map": {
    "messages": [
      "save_tab_group_to_bookmarks",
      "fetch_bookmark_progress",
      "regenerate_bookmark_summary",
      "check_bookmark_summary_status"
    ],
    "custom_bookmark_api_names": [
      "getMetaInfo",
      "setMetaInfo",
      "deleteMetaInfo",
      "getRootChildId",
      "recordOpen",
      "getFavicon",
      "importData",
      "exportData"
    ],
    "custom_bookmark_events": [
      "onChangedSelective",
      "onUsageChanged",
      "onMetaInfoChanged"
    ],
    "cloud_switch": "cloud_bookmarks",
    "ai_summary_metadata_key": "ext.summary",
    "local_create_call": "chrome.bookmarks.create",
    "filename": "evidence/bookmark-history-review/pak-60031.txt"
  },
  "limitations": [
    "Static retained bundle; no target JS execution or network replay."
  ]
}