PageSourceSearch

https://joplinapp.org/assets/js/d6a9c0db.2ff5f8d5.js

js joplinapp.org collected 2026-09-24 08:44:18 UTC 422,470 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunk_joplin_doc_builder=self.webpackChunk_joplin_doc_builder||[]).push([[3472],{3905:function(e,n,t){t.d(n,{Zo:function(){return p},kt:function(){return C}});var i=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function l(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function r(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?l(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):l(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function o(e,n){if(null==e)return{};var t,i,a=function(e,n){if(null==e)return{};var t,i,a={},l=Object.keys(e);for(i=0;i<l.length;i++)t=l[i],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(i=0;i<l.length;i++)t=l[i],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var d=i.createContext({}),s=function(e){var n=i.useContext(d),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},p=function(e){var n=s(e.components);return i.createElement(d.Provider,{value:n},e.children)},m="mdxType",k={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},N=i.forwardRef((function(e,n){var t=e.components,a=e.mdxType,l=e.originalType,d=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),m=s(t),N=a,C=m["".concat(d,".").concat(N)]||m[N]||k[N]||l;return t?i.createElement(C,r(r({ref:n},p),{},{components:t})):i.createElement(C,r({ref:n},p))}));function C(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var l=t.length,r=new Array(l);r[0]=N;var o={};for(var d in n)hasOwnProperty.call(n,d)&&(o[d]=n[d]);o.originalType=e,o[m]="string"==typeof e?e:a,r[1]=o;for(var s=2;s<l;s++)r[s]=t[s];return i.createElement.apply(null,r)}return i.createElement.apply(null,t)}N.displayName="MDXCreateElement"},43765:function(e,n,t){t.r(n),t.d(n,{assets:function(){return d},contentTitle:function(){return r},default:function(){return k},frontMatter:function(){return l},metadata:function(){return o},toc:function(){return s}});var i=t(87462),a=(t(67294),t(3905));const l={sidebar_label:"`any` Cleanup Progress - details",title:"`any` Cleanup Progress - details",description:"packages/pdf-viewer Session date: 2026-05-11 Files processed: messageService.ts \u2014 1 removed, 0 left. Replaced data?: any with data?: Record&lt;string, unknown>. Page.tsx \u2014 1 removed, 0 left. Replac..."},r="any Cleanup Progress - details",o={unversionedId:"dev/any_cleanup_progress_details",id:"dev/any_cleanup_progress_details",title:"`any` Cleanup Progress - details",description:"packages/pdf-viewer Session date: 2026-05-11 Files processed: messageService.ts \u2014 1 removed, 0 left. Replaced data?: any with data?: Record&lt;string, unknown>. Page.tsx \u2014 1 removed, 0 left. Replac...",source:"@site/help/dev/any_cleanup_progress_details.md",sourceDirName:"dev",slug:"/dev/any_cleanup_progress_details",permalink:"/help/dev/any_cleanup_progress_details",draft:!1,editUrl:"https://github.com/laurent22/joplin/tree/dev/readme/dev/any_cleanup_progress_details.md",tags:[],version:"current",frontMatter:{sidebar_label:"`any` Cleanup Progress - details",title:"`any` Cleanup Progress - details",description:"packages/pdf-viewer Session date: 2026-05-11 Files processed: messageService.ts \u2014 1 removed, 0 left. Replaced data?: any with data?: Record&lt;string, unknown>. Page.tsx \u2014 1 removed, 0 left. Replac..."},sidebar:"helpSidebar",previous:{title:"`any` Cleanup Progress",permalink:"/help/dev/any_cleanup_progress"},next:{title:"Build troubleshooting",permalink:"/help/dev/build_troubleshooting"}},d={},s=[{value:"packages/pdf-viewer",id:"packagespdf-viewer",level:2},{value:"packages/react-native-saf-x",id:"packagesreact-native-saf-x",level:2},{value:"packages/default-plugins",id:"packagesdefault-plugins",level:2},{value:"packages/editor",id:"packageseditor",level:2},{value:"packages/utils",id:"packagesutils",level:2},{value:"packages/renderer",id:"packagesrenderer",level:2},{value:"packages/tools",id:"packagestools",level:2},{value:"packages/plugin-repo-cli",id:"packagesplugin-repo-cli",level:2},{value:"packages/app-mobile",id:"packagesapp-mobile",level:2},{value:"packages/server",id:"packagesserver",level:2},{value:"packages/app-desktop",id:"packagesapp-desktop",level:2},{value:"Summary",id:"summary",level:2},{value:"packages/app-cli",id:"packagesapp-cli",level:2},{value:"packages/lib",id:"packageslib",level:2},{value:"packages/lib summary",id:"packageslib-summary",level:2},{value:"Multiple packages - June 2026",id:"multiple-packages---june-2026",level:2}],p={toc:s},m="wrapper";
1function k(e){let{components:n,...t}=e;return(0,a.kt)(m,(0,i.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"any-cleanup-progress---details"},(0,a.kt)("inlineCode",{parentName:"h1"},"any")," Cleanup Progress - details"),(0,a.kt)("div",{className:"donate-links"},(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://www.paypal.com/donate/?hosted_button_id=WQCERTSSLCC7U"},(0,a.kt)("img",{parentName:"a",src:"https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Donate-PayPal-green.svg",alt:"Donate using PayPal"}))," ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/sponsors/laurent22/"},(0,a.kt)("img",{parentName:"a",src:"https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/GitHub-Badge.svg",alt:"Sponsor on GitHub"}))," ",(0,a.kt)("a",{parentName:"p",href:"https://www.patreon.com/joplin"},(0,a.kt)("img",{parentName:"a",src:"https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Patreon-Badge.svg",alt:"Become a patron"}))," ",(0,a.kt)("a",{parentName:"p",href:"https://joplinapp.org/donate/#donations"},(0,a.kt)("img",{parentName:"a",src:"https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Donate-IBAN.svg",alt:"Donate using IBAN"})))),(0,a.kt)("h2",{id:"packagespdf-viewer"},"packages/pdf-viewer"),(0,a.kt)("p",null,"Session date: 2026-05-11"),(0,a.kt)("p",null,"Files processed:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"messageService.ts")," \u2014 1 removed, 0 left. Replaced ",(0,a.kt)("inlineCode",{parentName:"li"},"data?: any")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"data?: Record<string, unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Page.tsx")," \u2014 1 removed, 0 left. Replaced ",(0,a.kt)("inlineCode",{parentName:"li"},"let style: any")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"let style: CSSProperties")," (imported from ",(0,a.kt)("inlineCode",{parentName:"li"},"react"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"PdfDocument.ts")," \u2014 3 removed, 0 left. Imported ",(0,a.kt)("inlineCode",{parentName:"li"},"PDFDocumentProxy")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"PDFPageProxy")," from ",(0,a.kt)("inlineCode",{parentName:"li"},"pdfjs-dist"),"; typed ",(0,a.kt)("inlineCode",{parentName:"li"},"doc"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"pages")," (as ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<number, PDFPageProxy>"),") and the local ",(0,a.kt)("inlineCode",{parentName:"li"},"pdfDocument"),".")),(0,a.kt)("p",null,"Verification: ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean, ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn linter-ci packages/pdf-viewer/")," clean."),(0,a.kt)("h2",{id:"packagesreact-native-saf-x"},"packages/react-native-saf-x"),(0,a.kt)("p",null,"Session date: 2026-05-11"),(0,a.kt)("p",null,"Files processed:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"src/index.ts")," \u2014 1 removed, 0 left. Replaced ",(0,a.kt)("inlineCode",{parentName:"li"},"{} as any")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"{} as SafxInterface")," (the interface declared in the same file).")),(0,a.kt)("p",null,"Verification: ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean, ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn linter-ci packages/react-native-saf-x/")," clean."),(0,a.kt)("h2",{id:"packagesdefault-plugins"},"packages/default-plugins"),(0,a.kt)("p",null,"Session date: 2026-05-11"),(0,a.kt)("p",null,"Files processed:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"build.ts")," \u2014 4 removed, 0 left. Imported ",(0,a.kt)("inlineCode",{parentName:"li"},"Argv")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"ArgumentsCamelCase")," from ",(0,a.kt)("inlineCode",{parentName:"li"},"yargs"),"; typed builder callbacks as ",(0,a.kt)("inlineCode",{parentName:"li"},"(yargs: Argv) => ...")," and handler args as ",(0,a.kt)("inlineCode",{parentName:"li"},"ArgumentsCamelCase<{ outputDir: string }>")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"ArgumentsCamelCase<{ plugin: string }>"),".")),(0,a.kt)("p",null,"Verification: ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean, ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn linter-ci packages/default-plugins/")," clean."),(0,a.kt)("h2",{id:"packageseditor"},"packages/editor"),(0,a.kt)("p",null,"Session date: 2026-05-11"),(0,a.kt)("p",null,"Files processed:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.ts")," \u2014 2 removed, 6 left.",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Removed: ",(0,a.kt)("inlineCode",{parentName:"li"},"isPosition")," type guard now uses ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<DocumentPosition>")," instead of ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"removeOverlay")," overlay param uses ",(0,a.kt)("inlineCode",{parentName:"li"},"OverlayType<unknown>")," instead of ",(0,a.kt)("inlineCode",{parentName:"li"},"OverlayType<any>"),"."),(0,a.kt)("li",{parentName:"ul"},"Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"OptionUpdateCallback")," ",(0,a.kt)("inlineCode",{parentName:"li"},"newVal/oldVal: any")," (the source is ",(0,a.kt)("inlineCode",{parentName:"li"},"value: any"),", which is API-driven; narrowing in callbacks would be a logic change); ",(0,a.kt)("inlineCode",{parentName:"li"},"addOverlay")," return type (the ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," structurally deceives the base-class signature ",(0,a.kt)("inlineCode",{parentName:"li"},"SearchQuery | undefined")," to allow returning ",(0,a.kt)("inlineCode",{parentName:"li"},"{ clear: () => void }")," from the decorator branch \u2014 fixing it is a class-hierarchy refactor, not a typing tweak); ",(0,a.kt)("inlineCode",{parentName:"li"},"commands as any"),' cast (same kind of structural deception of the base class); and the 4 entries already tagged "CodeMirror 5 API requires any" / "Must match base class signature". Re-checked after the rule was clarified to allow small new type definitions \u2014 none of these are amenable to that.'))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"CodeMirror/pluginApi/PluginLoader.ts")," \u2014 4 removed, 1 left.",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Removed: introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginLoaderWindow")," type alias (",(0,a.kt)("inlineCode",{parentName:"li"},"Window & { __pluginLoaderScriptLoadCallbacks: Record<number, OnScriptLoadCallback>; __pluginLoaderRequireFunctions: Record<number, typeof codeMirrorRequire> }"),"); replaced four ",(0,a.kt)("inlineCode",{parentName:"li"},"(window as any).__pluginLoader\u2026")," casts with ",(0,a.kt)("inlineCode",{parentName:"li"},"(window as unknown as PluginLoaderWindow).\u2026"),"."),(0,a.kt)("li",{parentName:"ul"},"Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"OnScriptLoadCallback")," ",(0,a.kt)("inlineCode",{parentName:"li"},"exports: any"),' (already tagged "Plugin exports have dynamic structure").')))),(0,a.kt)("p",null,'Files ski
1pped entirely (only non-"Old code" tags inside):'),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"types.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"execCommand"),"/varying argument types."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"CodeMirror/editorCommands/editorCommands.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"EditorCommandFunction")," varying argument types."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"CodeMirror/CodeMirror5Emulation/CodeMirror5Emulation.test.ts")," \u2014 dynamic-extension test casts.")),(0,a.kt)("p",null,"Verification: ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean, ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn linter-ci packages/editor/")," clean."),(0,a.kt)("h2",{id:"packagesutils"},"packages/utils"),(0,a.kt)("p",null,"Session date: 2026-05-11"),(0,a.kt)("p",null,"Files processed:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dom.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"findParentElementByClassName")," parameter typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Element | null")," (broad enough to accept ",(0,a.kt)("inlineCode",{parentName:"li"},"EventTarget & Element")," from callers in app-desktop)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"splitCommandString.ts")," \u2014 1 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"SplitCommandStringOptions { handleEscape?: boolean }")," interface."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"cli.ts")," \u2014 0 removed, 1 left. Tried ",(0,a.kt)("inlineCode",{parentName:"li"},"Interface")," from ",(0,a.kt)("inlineCode",{parentName:"li"},"readline/promises"),", but ",(0,a.kt)("inlineCode",{parentName:"li"},"@types/node")," in this repo does not declare the ",(0,a.kt)("inlineCode",{parentName:"li"},"readline/promises")," submodule. Updated reason on the disable comment to reflect that."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"execCommand.ts")," \u2014 1 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"env")," typed as ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string | undefined>"),". The other entry is already tagged with a Workaround reason (Expo/NodeJs.ProcessEnv conflict)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"net.ts")," \u2014 1 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"FetchWithRetryOptions extends RequestInit")," interface with ",(0,a.kt)("inlineCode",{parentName:"li"},"retry"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"callback"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"pause")," fields."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"object.ts")," \u2014 0 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"objectValueFromPath")," does successive indexing (",(0,a.kt)("inlineCode",{parentName:"li"},"result = result[e]"),") which requires ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),"; tightened to ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," failed because intermediate values are ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"checkObjectHasProperties")," is called with ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderEntity")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"ItemSlice")," (interfaces without index signatures) \u2014 tightening forces every caller to widen. Updated reasons to explain why."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"html.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"attributesHtml(attr: Record<string, string>)")," to match the local-only usage; renderer package has its own ",(0,a.kt)("inlineCode",{parentName:"li"},"attributesHtml")," already typed the same way."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Logger.ts")," \u2014 17 removed, 1 left.",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Removed: ",(0,a.kt)("inlineCode",{parentName:"li"},"TargetOptions.console")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Console"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"Logger.create")," wrapper args ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"addTarget")," field copy uses paired ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," casts; ",(0,a.kt)("inlineCode",{parentName:"li"},"objectToString")," outer param ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),", inner Error branch uses a typed intersection cast; ",(0,a.kt)("inlineCode",{parentName:"li"},"objectsToString"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"error/warn/info/debug")," rest args ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"items: unknown[]"),"; global-logger fallback typed as a ",(0,a.kt)("inlineCode",{parentName:"li"},"Logger")," cast; ",(0,a.kt)("inlineCode",{parentName:"li"},"consoleObj[fn]")," indexed through ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, (...args: unknown[]) => void>")," cast."),(0,a.kt)("li",{parentName:"ul"},"Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"TargetOptions.database")," \u2014 tightening leaks through ",(0,a.kt)("inlineCode",{parentName:"li"},"lastEntries()")," to all downstream consumers (e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"app-mobile/exportDebugReport.ts"),") that read ",(0,a.kt)("inlineCode",{parentName:"li"},".timestamp/.level/.message")," via ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),". Refactoring those is out of scope. Updated reason on the disable comment."))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"env.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(error as Error).message = \u2026"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"key_value = \u2026 as RegExpMatchArray")," (and the inner nested ",(0,a.kt)("inlineCode",{parentName:"li"}
1,".match()")," typed the same way to preserve the original implicit non-null assumption).")),(0,a.kt)("p",null,"Verification: ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean for the utils package; root ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," (all workspaces) clean \u2014 initial attempt broke 4 downstream files in app-desktop/app-mobile/server/tools, which forced reverts on ",(0,a.kt)("inlineCode",{parentName:"p"},"checkObjectHasProperties")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"LoggerDatabase")," and a widening of ",(0,a.kt)("inlineCode",{parentName:"p"},"findParentElementByClassName"),". ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn linter-ci packages/utils/")," clean."),(0,a.kt)("h2",{id:"packagesrenderer"},"packages/renderer"),(0,a.kt)("p",null,"Session date: 2026-05-11"),(0,a.kt)("p",null,"Shared work: added a new ",(0,a.kt)("inlineCode",{parentName:"p"},"RendererTheme")," interface in ",(0,a.kt)("inlineCode",{parentName:"p"},"types.ts")," (a structural superset of the application theme that the renderer reads \u2014 ",(0,a.kt)("inlineCode",{parentName:"p"},"cacheKey"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"appearance"),", colors, ",(0,a.kt)("inlineCode",{parentName:"p"},"noteViewerFontSize"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"bodyPaddingTop/Bottom"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"buttonStyle"),", etc.). All fields are optional because callers pass either ",(0,a.kt)("inlineCode",{parentName:"p"},"ThemeStyle")," from ",(0,a.kt)("inlineCode",{parentName:"p"},"@joplin/lib"),", the renderer's ",(0,a.kt)("inlineCode",{parentName:"p"},"defaultNoteStyle")," merge, or bare ",(0,a.kt)("inlineCode",{parentName:"p"},"{}")," (tests). This made it possible to replace ",(0,a.kt)("inlineCode",{parentName:"p"},"theme: any")," across the package without touching call sites in ",(0,a.kt)("inlineCode",{parentName:"p"},"app-desktop"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"app-mobile"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"server"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"lib/commands/renderMarkup"),", etc. Also exported ",(0,a.kt)("inlineCode",{parentName:"p"},"ResourceEntity")," from ",(0,a.kt)("inlineCode",{parentName:"p"},"types.ts")," so ",(0,a.kt)("inlineCode",{parentName:"p"},"Link.resource")," could be typed."),(0,a.kt)("p",null,"Files processed:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"types.ts")," \u2014 7 removed, 1 left.",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Removed: ",(0,a.kt)("inlineCode",{parentName:"li"},"theme?"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"plugins?")," (typed as ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, Record<string, unknown>>")," so it can be spread), ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkupRenderer.render"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkupRenderer.allAssets"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkupToHtmlConverter.render")," (also tightened ",(0,a.kt)("inlineCode",{parentName:"li"},"options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RenderOptions"),"), ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkupToHtmlConverter.allAssets"),"."),(0,a.kt)("li",{parentName:"ul"},"Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"FsDriver.cacheCssToFile")," \u2014 return is used loosely as a ",(0,a.kt)("inlineCode",{parentName:"li"},"RenderResultPluginAsset")," push target while the actual returned object only has ",(0,a.kt)("inlineCode",{parentName:"li"},"{ path, mime }"),"; tightening forces logic changes. Updated reason on the comment."))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"HtmlToHtml.ts")," \u2014 2 removed, 0 left. Both ",(0,a.kt)("inlineCode",{parentName:"li"},"theme: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RendererTheme"),". Also made ",(0,a.kt)("inlineCode",{parentName:"li"},"Options.ResourceModel")," optional (constructor already handles ",(0,a.kt)("inlineCode",{parentName:"li"},"null"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"}
1,"MarkupToHtml.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"rawMarkdownIt_")," typed as ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt")," (added a type-only ",(0,a.kt)("inlineCode",{parentName:"li"},"import type * as MarkdownItType from 'markdown-it'"),"). The ",(0,a.kt)("inlineCode",{parentName:"li"},"as any")," on the ",(0,a.kt)("inlineCode",{parentName:"li"},"RendererClass")," construction went away by branching to explicit ",(0,a.kt)("inlineCode",{parentName:"li"},"new MdToHtml(this.options_)")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"new HtmlToHtml(this.options_)")," calls. ",(0,a.kt)("inlineCode",{parentName:"li"},"theme: any")," on ",(0,a.kt)("inlineCode",{parentName:"li"},"render")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"allAssets")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RendererTheme"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml.ts")," \u2014 19 removed, 4 left.",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Removed: ",(0,a.kt)("inlineCode",{parentName:"li"},"RendererRule.install")," (typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginContext"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"RuleOptions"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"), ",(0,a.kt)("inlineCode",{parentName:"li"},"RendererRule.assets")," (",(0,a.kt)("inlineCode",{parentName:"li"},"(theme: RendererTheme) => PluginAsset[]"),"), ",(0,a.kt)("inlineCode",{parentName:"li"},"RendererRule.plugin")," (",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt.PluginWithOptions"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"RendererPlugin.module")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"options")," (typed plugin + ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"ExtraRendererRule.module")," (",(0,a.kt)("inlineCode",{parentName:"li"},"Omit<RendererRule, 'assetPath' | 'pluginId' | 'assetPathIsAbsolute'>"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"Options.pluginOptions")," (",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, { enabled?: boolean } & Record<string, unknown>>"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"Link.resource")," (",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceEntity | null"),"); the four ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginContext")," ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," fields (",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>")," for css, ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, PluginAsset[]>")," for pluginAssets, ",(0,a.kt)("inlineCode",{parentName:"li"},"InMemoryCache")," for cache, ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, Record<string, unknown>>")," for userData); ",(0,a.kt)("inlineCode",{parentName:"li"},"RuleOptions.theme")," (",(0,a.kt)("inlineCode",{parentName:"li"},"RendererTheme"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"pluginOptions_")," (",(0,a.kt)("inlineCode",{parentName:"li"},"NonNullable<Options['pluginOptions']>"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"loadExtraRendererRule.module")," (matches new ",(0,a.kt)("inlineCode",{parentName:"li"},"ExtraRendererRule['module']"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"allProcessedAssets.theme"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"allProcessedAssets.assets")," (",(0,a.kt)("inlineCode",{parentName:"li"},"PluginAssets"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"allAssets.theme")," and inner ",(0,a.kt)("inlineCode",{parentName:"li"},"assets")," (",(0,a.kt)("inlineCode",{parentName:"li"},"PluginAssets"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"render.theme")," (",(0,a.kt)("inlineCode",{parentName:"li"},"RendererTheme"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"_attrs: any")," on ",(0,a.kt)("inlineCode",{parentName:"li"},"highlight()")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"."),(0,a.kt)("li",{parentName:"ul"},"Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"outputAssetsToExternalAssets_(output: any)")," \u2014 the function mutates with ",(0,a.kt)("inlineCode",{parentName:"li"},"delete output.cssStrings"),", which ",(0,a.kt)("inlineCode",{parentName:"li"},"RenderResult")," does not permit; updated reason on the comment. ",(0,a.kt)("inlineCode",{parentName:"li"},"render"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"theme: any = null")," was tightened to ",(0,a.kt)("inlineCode",{parentName:"li"},"theme: RendererTheme = null")," (note: keeping ",(0,a.kt)("inlineCode",{parentName:"li"},"null")," default required RendererTheme to allow ",(0,a.kt)("inlineCode",{parentName:"li"},"null")," via callers passing it through, handled because all fields are optional). ",(0,a.kt)("inlineCode",{parentName:"li"},"highlight()")," returns ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," because the function returns either a ",(0,a.kt)("inlineCode",{parentName:"li"},"string")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"{ wrapCode, html }")," depending on whether ",(0,a.kt)("inlineCode",{parentName:"li"},"rules.fence")," is set \u2014 a non-standard markdown-it return. ",(0,a.kt)("inlineCode",{parentName:"li"},"loadPlugin(plugin: any, options: any)")," \u2014 plugin may be a function or an ES-module wrapper with ",(0,a.kt)("inlineCode",{parentName:"li"},".default"),", and the function reassigns it before calling ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt.use(plugin, options)"),"; tightening forces logic restructuring. Updated reasons."))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"noteStyle.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"theme: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RendererTheme")," (all fields optional, so ",(0,a.kt)("inlineCode",{parentName:"li"},"theme = theme ? theme : {}")," continues to type-check)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"headerAnchor.ts")," \u2014 2 removed, 0 left. Added type-only imports for ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"MarkdownIt")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"markdown-it/lib/rules_core/state_core"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"state: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"StateCore"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"InMemoryCache.ts")," \u2014 0 removed, 3 left. Generic cache: values are heterogeneous across calls (different keys store different shapes); ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),' would force narrowing changes at every caller. Updated reason on one comment that was tagged "Old code" to match the existing "Generic cache" reason.'),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/setupLinkify.ts")," \u2014 2 removed, 0 left. Added type-only imports for ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"linkify-it"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"self: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"LinkifyIt.LinkifyIt"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/linkReplacement.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"LinkReplacementResult.resource: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceEntity | null"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/renderMedia.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Options.theme: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RendererTheme"),".")),(0,a.kt)("p",null,"Verification at checkpoint (after top-level files, before processing ",(0,a.kt)("inlineCode",{parentName:"p"},"MdToHtml/rules/*"),"): package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; root ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean."),(0,a.kt)("p",null,"Shared work for the rules subdirectory: across most rules the ",(0,a.kt)("inlineCode",{parentName:"p"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"p"},"MarkdownIt"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"state: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"p"},"StateCore")," / ",(0,a.kt)("inlineCode",{parentName:"p"},"StateInline")," / ",(0,a.kt)("inlineCode",{parentName:"p"},"StateBlock"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"tokens: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"p"},"Token[]"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"Token: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"p"},"typeof import('markdown-it/lib/token')"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"(tokens, idx, options, env, self)")," rule signatures pick up ",(0,a.kt)("inlineCode",{parentName:"p"},"Renderer.RenderRule")," (or its component types). All these are type-only imports from ",(0,a.kt)("inlineCode",{parentName:"p"},"markdown-it"),"'s ",(0,a.kt)("inlineCode",{parentName:"p"},"@types")," package, so they have no runtime cost. Two ",(0,a.kt)("inlineCode",{parentName:"p"},"RuleOptions")," extensions: ",(0,a.kt)("inlineCode",{parentName:"p"},"globalSettings"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"settingValue")," (set per-rule by ",(0,a.kt)("inlineCode",{parentName:"p"},"MdToHtml.render()"),"), and ",(0,a.kt)("inlineCode",{parentName:"p"},"mapsToLine")," (used only by ",(0,a.kt)("inlineCode",{parentName:"p"},"source_map")," rule)."),(0,a.kt)("p",null,"One unrelated typing fix: ",(0,a.kt)("inlineCode",{parentName:"p"},"utils.getAttr(attrs: string[], ...)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"p"},"(attrs: [string, string][], ...)")," \u2014 the function indexes ",(0,a.kt)("inlineCode",{parentName:"p"},"attrs[i][0]")," / ",(0,a.kt)("inlineCode",{parentName:"p"},"attrs[i][1]"),", so the original ",(0,a.kt)("inlineCode",{parentName:"p"},"string[]")," signature was wrong and prevented typing the ",(0,a.kt)("inlineCode",{parentName:"p"},"tokens[idx].attrs")," calls in ",(0,a.kt)("inlineCode",{parentName:"p"},"image.ts")," correctly."),(0,a.kt)("p",null,"Files processed:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/abc.ts")," \u2014 1 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"ruleOptions: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RuleOptions"),' (the existing comment said "we still don\'t have a type for ruleOptions"; we do now). Left: ',(0,a.kt)("inlineCode",{parentName:"li"},"(self.renderToken as any)(tokens, idx, options, env, self)")," \u2014 extra args beyond the typed signature; reason already documented."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/code_inline.ts")," \u2014 3 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"defaultRender: Renderer.RenderRule"),"; outer ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"MarkdownIt"),"; rule signature gets proper types."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/externalEmbed.ts")," \u2014 0 removed, 2 left. Both ",(0,a.kt)("inlineCode",{parentName:"li"},"(self.renderToken as any)(...)")," casts pass ",(0,a.kt)("inlineCode",{parentName:"li"},"env, self")," which ",(0,a.kt)("inlineCode",{parentName:"li"},"renderToken"),"'s typed signature does not declare. Updated reasons."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/checkbox.ts")," \u2014 5 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"theme: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RendererTheme"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"Token: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"typeof import('markdown-it/lib/token')"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"sourceToken: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Token"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"state: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"StateCore"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/fence.ts")," \u2014 2 removed, 1 left. Typed the rule signature with ",(0,a.kt)("inlineCode",{parentName:"li"},"Token[]")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt.Options")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"Renderer"),". Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"options: any")," on the fence renderer \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"options.highlight")," here returns either a string or ",(0,a.kt)("inlineCode",{parentName:"li"},"{ wrapCode, html }"),"; the typed signature can't express that disjunction without restructuring ",(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml.render"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"tmpToken as Token")," cast added because the rule constructs a partial ",(0,a.kt)("inlineCode",{parentName:"li"},"Token")," (",(0,a.kt)("inlineCode",{parentName:"li"},"{ attrs }"),") just to call ",(0,a.kt)("inlineCode",{parentName:"li"},"slf.renderAttrs"),", which only reads ",(0,a.kt)("inlineCode",{parentName:"li"},"attrs"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/image.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt"),"; rule signature gets typed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/fountain.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"theme: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RendererTheme"),' (the existing comment said "Theme is defined in @joplin/lib and we don\'t import it here" \u2014 but now we have a local ',(0,a.kt)("inlineCode",{parentName:"li"},"RendererTheme"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt"),"; rule signatures typed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/highlight_keywords.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Token: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"typeof import('markdown-it/lib/token')"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"state: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"StateCore"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/katex.ts")," \u2014 9 removed, 0 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"KatexMacroToken"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"KatexMacro"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"KatexOptions")," local interfaces (matching the macro shape documented in the file's own comments). ",(0,a.kt)("inlineCode",{parentName:"li"},"stringifyKatexOptions"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"renderToStringWithCache"),", and the inner ",(0,a.kt)("inlineCode",{parentName:"li"},"toSerialize")," now use these types. ",(0,a.kt)("inlineCode",{parentName:"li"},"(t: any) => t.text")," typed via the ",(0,a.kt)("inlineCode",{parentName:"li"},"KatexMacroToken.text")," field. ",(0,a.kt)("inlineCode",{parentName:"li"},"state: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"StateInline")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"StateBlock"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"MarkdownIt"),"; the two renderer functions typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"Token[]"),". A single ",(0,a.kt)("inlineCode",{parentName:"li"},"as KatexOptions['macros']")," cast on the macros pulled from ",(0,a.kt)("inlineCode",{parentName:"li"},"options.context.userData.__katex.macros"),", since ",(0,a.kt)("inlineCode",{parentName:"li"},"userData")," is typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, Record<string, unknown>>")," and the renderer doesn't know the per-plugin shape there."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/html_image.ts")," \u2014 6 removed, 0 left. Both default render fallbacks typed as ",(0,a.kt)("inlineCode",{parentName:"li"},"Renderer.RenderRule"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"handleImageTags")," now returns ",(0,a.kt)("inlineCode",{parentName:"li"},"Renderer.RenderRule"),"; outer ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt"),"; inner ",(0,a.kt)("inlineCode",{parentName:"li"},"content.replace")," callback uses ",(0,a.kt)("inlineCode",{parentName:"li"},"string")," instead of ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/link_close.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"defaultRender: Renderer.RenderRule"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt"),"; rule signature typed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/mermaid.ts")," \u2014 3 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"theme: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RendererTheme"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt"),"; rule signature typed. Left: the ",(0,a.kt)("inlineCode",{parentName:"li"},"(self.renderToken as any)(tokens, idx, options, env, self)")," cast in the fence-rule fallback \u2014 same pattern as ",(0,a.kt)("inlineCode",{parentName:"li"},"abc.ts")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"externalEmbed.ts"),", passes extra args beyond the typed ",(0,a.kt)("inlineCode",{parentName:"li"},"renderToken")," signature."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/sanitize_html.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"state: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"StateCore"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"tokens: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Token[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/link_open.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownIt: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownIt"),"; rule signature typed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"MdToHtml/rules/source_map.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"params: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RuleOptions")," (added ",(0,a.kt)("inlineCode",{parentName:"li"},"mapsToLine?: boolean")," to ",(0,a.kt)("inlineCode",{parentName:"li"},"RuleOptions"),"); rule signature typed.")),(0,a.kt)("p",null,"Verification: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean, ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn linter-ci packages/renderer/")," clean, root ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean."),(0,a.kt)("p",null,"Summary: 99 \u2192 12 disable comments. The 12 remaining are all either documented skip cases (cache values, ",(0,a.kt)("inlineCode",{parentName:"p"},"as any")," to pass extra args to typed ",(0,a.kt)("inlineCode",{parentName:"p"},"renderToken"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"output: any")," that mutates ",(0,a.kt)("inlineCode",{parentName:"p"},"delete output.cssStrings"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"cacheCssToFile")," return used loosely, ",(0,a.kt)("inlineCode",{parentName:"p"},"loadPlugin")," accepting both functions and ",(0,a.kt)("inlineCode",{parentName:"p"},"{ default }")," wrappers, the non-standard ",(0,a.kt)("inlineCode",{parentName:"p"},"highlight()")," return shape, generic in-memory cache) or genuinely cannot be replaced without code-logic changes that are out of scope for this PR."),(0,a.kt)("h2",{id:"packagestools"},"packages/tools"),(0,a.kt)("p",null,"Session date: 2026-05-11"),(0,a.kt)("p",null,"Note: the starting count of ",(0,a.kt)("strong",{parentName:"p"},"49")," included 3 disables inside ",(0,a.kt)("inlineCode",{parentName:"p"},"packages/tools/node_modules/")," (docusaurus and one in ",(0,a.kt)("inlineCode",{parentName:"p"},"node_modules/@docusaurus/utils"),") which are vendored copies of third-party code and n
1ot in scope. In-scope was ",(0,a.kt)("strong",{parentName:"p"},"46"),"; after this session, ",(0,a.kt)("strong",{parentName:"p"},"1")," in-scope and ",(0,a.kt)("strong",{parentName:"p"},"3")," vendored remain (total ",(0,a.kt)("strong",{parentName:"p"},"4"),")."),(0,a.kt)("p",null,"Files processed:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"postPreReleasesToForum.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"processedReleases: Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, boolean>")," (the stored value is always ",(0,a.kt)("inlineCode",{parentName:"li"},"true"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"generate-images.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"output: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(string | number | undefined)[]")," (matches the heterogeneous values pushed from ",(0,a.kt)("inlineCode",{parentName:"li"},"Operation"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"generate-database-types.ts")," \u2014 5 removed, 0 left. Imported ",(0,a.kt)("inlineCode",{parentName:"li"},"Table")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"Column")," from ",(0,a.kt)("inlineCode",{parentName:"li"},"@rmp135/sql-ts/dist/Typings"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"createRuntimeObject"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"generateListRenderDependencyType"),"/the two ",(0,a.kt)("inlineCode",{parentName:"li"},".map()")," callbacks all typed via those. The column-push uses ",(0,a.kt)("inlineCode",{parentName:"li"},"as Column")," because adding the missing ",(0,a.kt)("inlineCode",{parentName:"li"},"ColumnDefinition")," fields explicitly may change ",(0,a.kt)("inlineCode",{parentName:"li"},"sql-ts.fromObject()")," output."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"update-readme-contributors.ts")," \u2014 1 removed, 0 left. The ",(0,a.kt)("inlineCode",{parentName:"li"},"request")," callback typed ",(0,a.kt)("inlineCode",{parentName:"li"},"(error: Error | null, response: { statusCode: number }, data: Contributor[])"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"release-clipper.ts")," \u2014 1 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"Manifest = Record<string, unknown> & { background?, browser_specific_settings? }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"removeManifestKeys(manifest: Manifest): Manifest"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"update-readme-download.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"main(argv: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"main(argv: string[])")," (called as ",(0,a.kt)("inlineCode",{parentName:"li"},"main(process.argv)"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"setupNewRelease.ts")," \u2014 1 removed, 0 left. yargs ",(0,a.kt)("inlineCode",{parentName:"li"},".argv")," cast to ",(0,a.kt)("inlineCode",{parentName:"li"},"{ _: string[]; updateVersion?: string; updateDependenciesVersion?: string }")," (rather than ",(0,a.kt)("inlineCode",{parentName:"li"},"yargs.Arguments<T>"),", because ",(0,a.kt)("inlineCode",{parentName:"li"},"Arguments._")," is ",(0,a.kt)("inlineCode",{parentName:"li"},"Array<string | number>")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"parse-numbers: false")," guarantees strings at runtime \u2014 using the library type would require a ",(0,a.kt)("inlineCode",{parentName:"li"},"_[0] as string")," cast at every call site)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"tool-utils.ts")," \u2014 11 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"saveGitHubUsernameCache(cache: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"execCommand")," options typed ",(0,a.kt)("inlineCode",{parentName:"li"},"{ cwd?; env?; maxBuffer? }")," and its callback ",(0,a.kt)("inlineCode",{parentName:"li"},"(error: (Error & {signal?: string}) | null, stdout: string, stderr: string)"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"execCommandWithPipes")," ",(0,a.kt)("inlineCode",{parentName:"li"},"error: Error"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"code: number | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"setPackagePrivateField(value: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"boolean"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"downloadFile"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"https.get")," callback ",(0,a.kt)("inlineCode",{parentName:"li"},"response: import('http').IncomingMessage"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"error: Error"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"fileSha256")," stream ",(0,a.kt)("inlineCode",{parentName:"li"},"data: Buffer")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"error: Error"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"fileExists")," stat callback ",(0,a.kt)("inlineCode",{parentName:"li"},"error: NodeJS.ErrnoException | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"gitHubLatestRelease"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"gitHubLatestRelease_KeepInCaseMicrosoftBreaksTheApiAgain")," ",(0,a.kt)("inlineCode",{parentName:"li"},"response: any")," deleted (node-fetch's inferred ",(0,a.kt)("inlineCode",{parentName:"li"},"Response")," works fine); ",(0,a.kt)("inlineCode",{parentName:"li"},"githubRelease(options: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ isDraft?: boolean; isPreRelease?: boolean }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"build-release-stats.ts")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"createMarkdownTable")," is typed ",(0,a.kt)("inlineCode",{parentName:"li"},"(headers, rows: MarkdownTableRow[])")," where ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"MarkdownTableRow = Record<string, string>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"Release")," rows contain numeric counts (",(0,a.kt)("inlineCode",{parentName:"li"},"windows_count"),", etc.), so the cast ",(0,a.kt)("inlineCode",{parentName:"li"},"rows as any[]")," masks a real type mismatch. Tightening would require widening ",(0,a.kt)("inlineCode",{parentName:"li"},"createMarkdownTable")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"@joplin/lib")," (cross-package change). Updated reason."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"licenses/licenseChecker.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"enforceString(line: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string | string[] | undefined | null")," (matches the ",(0,a.kt)("inlineCode",{parentName:"li"},"Array.isArray(line) ? line.join(', ') : ...")," branches)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"website/updateNews.ts")," \u2014 1 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"RssFeedItem")," interface (",(0,a.kt)("inlineCode",{parentName:"li"},"rss")," is untyped); ",(0,a.kt)("inlineCode",{parentName:"li"},"feedItems: RssFeedItem[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"website/processDocs.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"currentLinkAttrs?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"[string, string][] | null"),"; imported ",(0,a.kt)("inlineCode",{parentName:"li"},"Token")," from ",(0,a.kt)("inlineCode",{parentName:"li"},"markdown-it/lib/token")," so ",(0,a.kt)("inlineCode",{parentName:"li"},"processToken(token: Token, \u2026)"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onopentag")," ",(0,a.kt)("inlineCode",{parentName:"li"},"attrs: Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>")," (matches ",(0,a.kt)("inlineCode",{parentName:"li"},"htmlentities(attrs[n])")," usage and the local ",(0,a.kt)("inlineCode",{parentName:"li"},"attributesHtml")," signature)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"website/build.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"scriptsToImport: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ id: string; sourcePath: string; md5: string; filename: string }[]")," (the entries are all commented out, but the shape is implied by the loop that follows)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"website/utils/applyTranslations.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"onopentag")," ",(0,a.kt)("inlineCode",{parentName:"li"},"attrs: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"website/utils/convertLinksToLocale.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"[string, any, string][]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"[string, Partial<Locale>, string][]")," with a ",(0,a.kt)("inlineCode",{parentName:"li"},"locale as Locale")," cast at the call site (the test cases only supply ",(0,a.kt)("inlineCode",{parentName:"li"},"pathPrefix"),", not the full ",(0,a.kt)("inlineCode",{parentName:"li"},"Locale")," shape)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"website/utils/frontMatter.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"yaml.load(...)")," cast directly to ",(0,a.kt)("inlineCode",{parentName:"li"},"FrontMatter"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"formatFrontMatterValue(value: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FrontMatter[keyof FrontMatter]"),"; the ",(0,a.kt)("inlineCode",{parentName:"li"},"(header as any)[key] = \u2026")," assignment refactored to a separate ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>")," output map."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"website/utils/frontMatter.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"testCases: any[][]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"[string, FrontMatter, string, string][]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"website/utils/render.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"state: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"StateCore")," (imported from ",(0,a.kt)("inlineCode",{parentName:"li"},"markdown-it/lib/rules_core/state_core"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/translation.ts")," \u2014 1 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"GettextTranslation")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"GettextParsed")," interfaces capturing only the fields read (",(0,a.kt)("inlineCode",{parentName:"li"},"gettext-parser")," is ",(0,a.kt)("inlineCode",{parentName:"li"},"require"),"-d and has no types). ",(0,a.kt)("inlineCode",{parentName:"li"},"serializeTranslation"),"'s parameter in ",(0,a.kt)("inlineCode",{parentName:"li"},"build-translation.ts")," was incorrectly typed as ",(0,a.kt)("inlineCode",{parentName:"li"},"string")," \u2014 corrected to ",(0,a.kt)("inlineCode",{parentName:"li"},"Parameters<typeof parseTranslations>[0]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/discourse.ts")," \u2014 5 removed, 0 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"DiscourseApiError extends Error { apiObject; status }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"new Error(...) as DiscourseApiError")," then setting ",(0,a.kt)("inlineCode",{parentName:"li"},"error.apiObject"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"error.status")," directly. ",(0,a.kt)("inlineCode",{parentName:"li"},"response.json() as any")," deleted \u2014 node-fetch's inferred return works fine for the downstream ",(0,a.kt)("inlineCode",{parentName:"li"},".error.status === 404")," reads. ",(0,a.kt)("inlineCode",{parentName:"li"},"createTopic"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"createPost"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"updatePost")," body params \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string | number>")," (matches ",(0,a.kt)("inlineCode",{parentName:"li"},"execApi"),").")),(0,a.kt)("p",null,"Verification: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean, ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn linter-ci packages/tools/")," clean, root ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean."),(0,a.kt)("p",null,"Summary: 49 \u2192 4 disable comments; in-scope 46 \u2192 1 (3 are inside ",(0,a.kt)("inlineCode",{parentName:"p"},"node_modules/")," vendored copies, not touched). The single in-scope remaining one is ",(0,a.kt)("inlineCode",{parentName:"p"},"build-release-stats.ts"),", where fixing would require widening ",(0,a.kt)("inlineCode",{parentName:"p"},"createMarkdownTable"),"'s signature in ",(0,a.kt)("inlineCode",{parentName:"p"},"@joplin/lib"),"."),(0,a.kt)("h2",{id:"packagesplugin-repo-cli"},"packages/plugin-repo-cli"),(0,a.kt)("p",null,"Session date: 2026-05-11"),(0,a.kt)("p",null,"Shared work: imported ",(0,a.kt)("inlineCode",{parentName:"p"},"PluginManifest")," from ",(0,a.kt)("inlineCode",{parentName:"p"},"@joplin/lib/services/plugins/utils/types")," (plugin-repo-cli already depends on ",(0,a.kt)("inlineCode",{parentName:"p"},"@joplin/lib"),"). Most ",(0,a.kt)("inlineCode",{parentName:"p"},"manifest: any")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"manifests: any")," parameters became ",(0,a.kt)("inlineCode",{parentName:"p"},"PluginManifest")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"Record<string, PluginManifest>"),". The ",(0,a.kt)("inlineCode",{parentName:"p"},"*.test.ts")," files in this package frequently use partial manifest fixtures, so a few ",(0,a.kt)("inlineCode",{parentName:"p"},"as unknown as PluginManifest")," casts at call sites were needed to keep tests typing without bulking up every fixture with the full ",(0,a.kt)("inlineCode",{parentName:"p"},"manifest_version"),"/",(0,a.kt)("inlineCode",{parentName:"p"},"name"),"/",(0,a.kt)("inlineCode",{parentName:"p"},"app_min_version")," set. Two helper functions were widened structurally (rather than via casts) where they only read a subset of fields: ",(0,a.kt)("inlineCode",{parentName:"p"},"gitCompareUrl")," now takes ",(0,a.kt)("inlineCode",{parentName:"p"},"Pick<PluginManifest, 'repository_url' | '_publish_commit'>"),", and ",(0,a.kt)("inlineCode",{parentName:"p"},"getObsoleteManifests")," became a generic ",(0,a.kt)("inlineCode",{parentName:"p"},"<T extends { _obsolete?: boolean }>")," so the existing-test fixtures still type-check."),(0,a.kt)("p",null,"Files processed:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"index.ts")," \u2014 13 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"extractPluginFilesFromPackage")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"existingManifests: PluginManifests"),", return ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<PluginManifest>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"files.find((f: any) => \u2026)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(f: string)")," (since ",(0,a.kt)("inlineCode",{parentName:"li"},"fs.readdir")," returns ",(0,a.kt)("inlineCode",{parentName:"li"},"string[]"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"commitMessage")," parameters typed (",(0,a.kt)("inlineCode",{parentName:"li"},"manifest: PluginManifest | null"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"previousManifest: PluginManifest | null"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"error: Error | null"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"readManifests"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"writeManifests")," return/take ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginManifests"),"; the four ",(0,a.kt)("inlineCode",{parentName:"li"},"let X: any = {}")," locals in ",(0,a.kt)("inlineCode",{parentName:"li"},"processNpmPackage")," typed; the yargs handlers refactored \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"setSelectedCommand")," and the three command handlers now share a ",(0,a.kt)("inlineCode",{parentName:"li"},"CommandArgs")," type matching the ",(0,a.kt)("inlineCode",{parentName:"li"},"{ pluginRepoDir, dryRun }")," shape both ",(0,a.kt)("inlineCode",{parentName:"li"},"commandBuild")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"commandUpdateRelease")," expect (the previous ",(0,a.kt)("inlineCode",{parentName:"li"},"selectedCommandArgs = ''")," declaration also implicitly drifted from string \u2192 object); ",(0,a.kt)("inlineCode",{parentName:"li"},"commands: Record<string, Function>")," replaced with ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, (args: CommandArgs)=> Promise<void>>"),". The two ",(0,a.kt)("inlineCode",{parentName:"li"},"await readJsonFile(...)")," callers in this file pass an explicit type parameter (",(0,a.kt)("inlineCode",{parentName:"li"},"readJsonFile<PluginManifest>(...)"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"readJsonFile<{ version: string }>(...)"),") since ",(0,a.kt)("inlineCode",{parentName:"li"},"readJsonFile")," is now generic."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"commands/updateRelease.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(error: Error, assets: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"assets: unknown")," (return is not consumed by callers); ",(0,a.kt)("inlineCode",{parentName:"li"},"(resolve: Function, reject: Function)")," ban-types disable replaced with explicit ",(0,a.kt)("inlineCode",{parentName:"li"},"(assets: unknown)=> void")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"(error: Error)=> void"),"; introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginVersionStats")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginStats")," types and used them for ",(0,a.kt)("inlineCode",{parentName:"li"},"createStats"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"saveStats"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"lib/checkIfPluginCanBeAdded.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"caseInsensitiveFindManifest"),"/default-export both typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginManifests")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginManifest"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"lib/overrideUtils.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"applyManifestOverrides(manifests: PluginManifests, \u2026)"),"; the inner ",(0,a.kt)("inlineCode",{parentName:"li"},"manifest[propName] = propValue")," write uses ",(0,a.kt)("inlineCode",{parentName:"li"},"as PluginManifest & Record<string, unknown>")," because we mutate via a ",(0,a.kt)("inlineCode",{parentName:"li"},"for...of")," over ",(0,a.kt)("inlineCode",{parentName:"li"},"Object.entries(override)")," keys. ",(0,a.kt)("inlineCode",{parentName:"li"},"getObsoleteManifests")," made generic over ",(0,a.kt)("inlineCode",{parentName:"li"},"<T extends { _obsolete?: boolean }>")," so the existing test (which passes manifest-shaped fixtures rather than ",(0,a.kt)("inlineCode",{parentName:"li"},"ManifestOverride"),"-shaped ones) types correctly without rewriting its data."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"lib/errorsHaveChanged.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"testCases: any[][]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"[ImportErrors, ImportErrors, boolean][]"),"; dropped the ",(0,a.kt)("inlineCode",{parentName:"li"},"as any")," cast in the destructuring loop."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"lib/validateUntrustedManifest.ts")," \u2014 1 removed, 0 left. Parameters typed ",(0,a.kt)("inlineCode",{parentName:"li"},"manifest: PluginManifest"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"existingManifests: Record<string, PluginManifest>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"lib/updateReadme.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"manifests: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, PluginManifest>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"lib/updateReadme.ts")," \u2014 2 removed, 0 left. Parameter ",(0,a.kt)("inlineCode",{parentName:"li"},"manifests: Record<string, PluginManifest>"),"; the ",(0,a.kt)("inlineCode",{parentName:"li"},"rows.push(manifests[pluginId])")," line uses an ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as MarkdownTableRow")," cast (the existing code stores PluginManifest objects inside a ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownTableRow[]")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"createMarkdownTable")," is typed for ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>")," rows \u2014 the same impedance mismatch documented on ",(0,a.kt)("inlineCode",{parentName:"li"},"build-release-stats.ts")," last session); the ",(0,a.kt)("inlineCode",{parentName:"li"},"rows.sort((a: any, b: any) => \u2026)")," callback's args type-infer from ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownTableRow")," directly."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"lib/utils.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"readJsonFile")," made generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T = unknown>(manifestPath, defaultValue: T = null): Promise<T>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"isJoplinPluginPackage(pack: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ keywords?: string[]; name: string }")," (matches the two fields it reads)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"lib/overrideUtils.test.ts")," \u2014 2 removed, 0 left. First test's ",(0,a.kt)("inlineCode",{parentName:"li"},"manifestOverrides: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, { _obsolete?: boolean; description?: string; [key: string]: unknown }>")," (matches the heterogeneous fixture). Second test's ",(0,a.kt)("inlineCode",{parentName:"li"},"manifests: any")," \u2192 inferred from the literal."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"lib/gitCompareUrl.ts")," \u2014 1 removed, 0 left. Widened to ",(0,a.kt)("inlineCode",{parentName:"li"},"Pick<PluginManifest, 'repository_url' | '_publish_commit'>")," (matches the fields the function actually reads, so the test fixtures don't need to spell out the whole ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginManifest"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"lib/checkIfPluginCanBeAdded.test.ts")," \u2014 needed touching even though it had no disable comments: the test passes partial fixtures, so call sites cast via ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Parameters<typeof checkIfPluginCanBeAdded>[0/1]"),". Same pattern in ",(0,a.kt)("inlineCode",{parentName:"li"},"lib/validateUntrustedManifest.test.ts")," (",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as PluginManifest"),") and ",(0,a.kt)("inlineCode",{parentName:"li"},"lib/gitCompareUrl.test.ts")," (where the tuple is typed ",(0,a.kt)("inlineCode",{parentName:"li"},"[GitCompareManifest, GitCompareManifest | null, string | null]"),").")),(0,a.kt)("p",null,"Verification: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean, ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn linter-ci packages/plugin-repo-cli/")," clean, root ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean, ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn test")," (in plugin-repo-cli) clean \u2014 all 13 tests pass."),(0,a.kt)("p",null,"Summary: 33 \u2192 0 disable comments. Every one was tagged ",(0,a.kt)("inlineCode",{parentName:"p"},"Old code before rule was applied")," and could be replaced with ",(0,a.kt)("inlineCode",{parentName:"p"},"PluginManifest"),", ",(0,a.kt)("inlineCode",{parentName:"p"},"ImportErrors"),", structural picks, or generics."),(0,a.kt)("h2",{id:"packagesapp-mobile"},"packages/app-mobile"),(0,a.kt)("p",null,"Session date: 2026-05-12"),(0,a.kt)("p",null,"Note: starting baseline was 131 comments across 37 files. The grep also matched build artifacts under packages/app-mobile (compiled ",(0,a.kt)("inlineCode",{parentName:"p"},".js"),"/",(0,a.kt)("inlineCode",{parentName:"p"},".bundle.js.map"),") which are gitignored; the source counts (",(0,a.kt)("inlineCode",{parentName:"p"},".ts"),"/",(0,a.kt)("inlineCode",{parentName:"p"}
1,".tsx")," only) match the 131/37 baseline exactly."),(0,a.kt)("p",null,"Files processed (partial \u2014 checkpoint):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/debounce.tsx")," \u2014 2 removed, 0 left. Replaced ",(0,a.kt)("inlineCode",{parentName:"li"},"(...args: any[])")," with generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<Args extends unknown[]>(...args: Args)=> void")," so callers like ",(0,a.kt)("inlineCode",{parentName:"li"},"Note.tsx"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"(event: EditorChangeEvent)=> void")," still type-check."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/getVersionInfoText.ts")," \u2014 1 removed, 0 left. Replaced ",(0,a.kt)("inlineCode",{parentName:"li"},"(global as any).HermesInternal")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"(global as { HermesInternal?: unknown }).HermesInternal"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/screens/ConfigScreen/types.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"UpdateSettingValueCallback")," value param ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," (callers don't read it as typed values)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/base-screen.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<number, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<number, ReturnType<typeof StyleSheet.create>>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/database-driver-react-native.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"react-native-sqlite-storage")," ships no ",(0,a.kt)("inlineCode",{parentName:"li"},".d.ts")," and no ",(0,a.kt)("inlineCode",{parentName:"li"},"@types/...")," is installed, so introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"SqliteDb"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"SqliteResultSet")," interfaces covering the two methods used (",(0,a.kt)("inlineCode",{parentName:"li"},"executeSql"),", returning rows/insertId). The base ",(0,a.kt)("inlineCode",{parentName:"li"},"DatabaseDriver")," interface uses ",(0,a.kt)("inlineCode",{parentName:"li"},"SelectResult = any"),", so the narrower return type still satisfies it."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/buildStartupTasks.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"resourceFetcher_downloadComplete(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"event: { id: string; encrypted: boolean }")," (the shape emitted by ",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceFetcher.eventEmitter_.emit('downloadComplete', ...)"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"index.web.ts")," \u2014 1 removed, 0 left. Removed the ",(0,a.kt)("inlineCode",{parentName:"li"},"Root as any")," cast \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"Root extends React.Component")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"AppRegistry.registerComponent"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"ComponentProvider")," is ",(0,a.kt)("inlineCode",{parentName:"li"},"() => React.ComponentType<any>"),", which ",(0,a.kt)("inlineCode",{parentName:"li"},"() => Root")," satisfies."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/fs-driver/fs-driver-rn.ts")," \u2014 7 removed, 2 left (down from 9).",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Removed: ",(0,a.kt)("inlineCode",{parentName:"li"},"appendFile"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"writeFile")," content param ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string")," (base class uses ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"rnfsStatToStd_")," param ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," \u2192 local ",(0,a.kt)("inlineCode",{parentName:"li"},"RnfsStatLike")," union of ",(0,a.kt)("inlineCode",{parentName:"li"},"StatResultT | ReadDirResItemT | DocumentFileDetail")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"in"),"-checks; ",(0,a.kt)("inlineCode",{parentName:"li"},"readDirStats")," options ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReadDirStatsOptions")," (with ",(0,a.kt)("inlineCode",{parentName:"li"},"stats: RnfsStatLike[]"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"close(handle: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," (handle is ignored); ",(0,a.kt)("inlineCode",{parentName:"li"},"readFileChunk(handle: any)")," \u2192 typed inline ",(0,a.kt)("inlineCode",{parentName:"li"},"{ path: string; offset: number; mode: string; stat: { size: number } | null }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"tarExtract"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"tarCreate")," options ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Omit<Parameters<typeof tar*>[0], 'cwd'> & { cwd?: string }"),"."),(0,a.kt)("li",{parentName:"ul"},"Left: the inner ",(0,a.kt)("inlineCode",{parentName:"li"},"output: any[]")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"readDirStats")," \u2014 entries can be either ",(0,a.kt)("inlineCode",{parentName:"li"},"DocumentFileDetail")," (SAF) or the normalized ",(0,a.kt)("inlineCode",{parentName:"li"},"Stat"),"-shaped object from ",(0,a.kt)("inlineCode",{parentName:"li"},"rnfsStatToStd_"),", the recursion helpers also accept this heterogeneous shape, so a single concrete type would force restructuring. Reason updated on the disable comment."))),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/AlarmServiceDriver.android.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"@joplin/react-native-alarm-notification")," ships no types, so introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"ScheduledAlarm { id: string; data?: { joplinNotificationId?: number } }")," covering the two fields read."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/AlarmServiceDriver.ios.ts")," \u2014 6 removed, 0 left. Imported ",(0,a.kt)("inlineCode",{parentName:"li"},"PushNotification"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"PushNotificationPermissions"),", ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"ScheduleLocalNotificationDetails")," from ",(0,a.kt)("inlineCode",{parentName:"li"},"@react-native-community/push-notification-ios"),". Notes: ",(0,a.kt)("inlineCode",{parentName:"li"},"requestPermissions")," options ",(0,a.kt)("inlineCode",{parentName:"li"},"{ alert: 1, badge: 1, sound: 1 }")," \u2192 booleans (the typed interface declares them as ",(0,a.kt)("inlineCode",{parentName:"li"},"boolean?"),"; runtime accepts both, but the type is stricter). ",(0,a.kt)("inlineCode",{parentName:"li"},"hasPermissions")," return tightened to ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<boolean>")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"perm.alert && perm.badge && perm.sound")," wrapped in ",(0,a.kt)("inlineCode",{parentName:"li"},"!!()")," since the fields are optional booleans. ",(0,a.kt)("inlineCode",{parentName:"li"},"scheduleNotification"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"iosNotification")," keeps ",(0,a.kt)("inlineCode",{parentName:"li"},"id: string")," and a final ",(0,a.kt)("inlineCode",{parentName:"li"},"as ScheduleLocalNotificationDetails")," cast because the library's typed ",(0,a.kt)("inlineCode",{parentName:"li"},"ScheduleLocalNotificationDetails")," declares neither ",(0,a.kt)("inlineCode",{parentName:"li"},"id")," nor ",(0,a.kt)("inlineCode",{parentName:"li"},"alertBody?")," \u2014 but the runtime requires ",(0,a.kt)("inlineCode",{parentName:"li"},"id")," (and ",(0,a.kt)("inlineCode",{parentName:"li"},"alertBody")," may be omitted), so the cast preserves existing behavior."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"root.tsx")," \u2014 4 removed, 5 left.",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Removed: ",(0,a.kt)("inlineCode",{parentName:"li"},"generalMiddleware")," inner ",(0,a.kt)("inlineCode",{parentName:"li"},"scheduleRefreshFolders((action: any) => storeDispatch(action), ...)")," simplified to ",(0,a.kt)("inlineCode",{parentName:"li"},"scheduleRefreshFolders(storeDispatch, ...)"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"componentDidUpdate(prevProps: any)")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"UNSAFE_componentWillReceiveProps(newProps: any)")," typed as ",(0,a.kt)("inlineCode",{parentName:"li"},"AppComponentProps")," (this also forced adding the missing ",(0,a.kt)("inlineCode",{parentName:"li"},"syncStarted: boolean")," field that ",(0,a.kt)("inlineCode",{parentName:"li"},"mapStateToProps")," populates but the interface had not declared); the inner ",(0,a.kt)("inlineCode",{parentName:"li"},"(action: any) => this.props.dispatch(action)")," simplified to ",(0,a.kt)("inlineCode",{parentName:"li"},"(action) => ..."),"."),(0,a.kt)("li",{parentName:"ul"},"Left: the three top-of-file ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),"s on the middleware (",(0,a.kt)("inlineCode",{parentName:"li"},"storeDispatch: any"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"logReducerAction(action: any)"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"generalMiddleware = (store: any) => (next: any) => async (action: any)"),") require typing redux actions across many call sites \u2014 significant refactoring; ",(0,a.kt)("inlineCode",{parentName:"li"},"handleOpenURL_(event: any)")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"ShareExtension.shareURL")," has a pre-existing typing inconsistency (declared ",(0,a.kt)("inlineCode",{parentName:"li"},"()=> string")," but assigned both as a function and a string literal) so typing the event would expose that unrelated bug; one ",(0,a.kt)("inlineCode",{parentName:"li"},"await reduxSharedMiddleware(store, next, action, storeDispatch as any)")," \u2014 kept as ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," cast since the upstream signature uses ",(0,a.kt)("inlineCode",{parentName:"li"},"Dispatch")," and storeDispatch is already typed loosely. Reasons updated on the disable comments.")))),(0,a.kt)("p",null,"In progress \u2014 packages with files still containing disable comments (see grep summary): components/",(0,a.kt)("em",{parentName:"p"}," (ExtendedWebView, NoteEditor, NoteList, ScreenHeader, SelectDateTimeDialog, app-nav, plugins/backgroundPage, screens/{ConfigScreen, LogScreen, Note}, side-menu-content), contentScripts/"),", services/plugins/PlatformImplementation, utils/{appReducer, types}."),(0,a.kt)("p",null,"Second batch:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/ExtendedWebView/types.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"OnMessageEvent.data: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string")," (consumers ",(0,a.kt)("inlineCode",{parentName:"li"},"JSON.parse")," it). Required casting the ",(0,a.kt)("inlineCode",{parentName:"li"},"data")," field in ",(0,a.kt)("inlineCode",{parentName:"li"},"index.jest.tsx"),"'s test mock to ",(0,a.kt)("inlineCode",{parentName:"li"},"as string")," (the mock passes pre-stringify values), and forced a typing tweak elsewhere."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/ExtendedWebView/index.tsx")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"postMessage(message: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," (it's JSON-stringified). ",(0,a.kt)("inlineCode",{parentName:"li"},"(props.style as any)")," cast removed by switching to array-style ",(0,a.kt)("inlineCode",{parentName:"li"},"style={[{...inline...}, props.style]}"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/ExtendedWebView/index.jest.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"additionalProps: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; kept inline comment explaining the HACK."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/screens/ConfigScreen/SettingsToggle.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"boolean"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/NoteList.tsx")," \u2014 1 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch: (action: any)=> void")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Dispatch")," (from redux). Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"styles_: Record<string, StyleSheet.NamedStyles<any>>")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"NamedStyles<T>")," requires ",(0,a.kt)("inlineCode",{parentName:"li"},"T")," to be the same record being passed; tightening to ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," breaks property access. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"}
1,"components/app-nav.tsx")," \u2014 1 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Dispatch"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"screens")," widened to ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, { screen: ComponentType<any> }>")," (typed wrapper, screens still have heterogeneous props). Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"route: any")," (NAV action with heterogeneous payload across NAV_GO/NAV_BACK/etc.) and the inner ",(0,a.kt)("inlineCode",{parentName:"li"},"ComponentType<any>")," for screens. Reasons updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/SelectDateTimeDialog.tsx")," \u2014 3 removed, 0 left. Replaced ",(0,a.kt)("inlineCode",{parentName:"li"},"PureComponent<any, any>")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"PureComponent<SelectDateTimeDialogProps, SelectDateTimeDialogState>")," (local interfaces capturing ",(0,a.kt)("inlineCode",{parentName:"li"},"themeId"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"shown"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"date"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"onAccept"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"onReject")," and state shape)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/ScreenHeader/index.tsx")," \u2014 12 removed, 1 left. Added local ",(0,a.kt)("inlineCode",{parentName:"li"},"type ScreenHeaderStyles = ReturnType<typeof StyleSheet.create>")," and replaced every inner button factory's ",(0,a.kt)("inlineCode",{parentName:"li"},"styles: any")," parameter with it (12 occurrences). Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"styleObject")," builder uses ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, any>")," because it incrementally mixes ",(0,a.kt)("inlineCode",{parentName:"li"},"ViewStyle"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"TextStyle"),", and ",(0,a.kt)("inlineCode",{parentName:"li"},"IconStyle")," entries spread from theme.icon \u2014 splitting into typed sub-objects would force restructuring. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/screens/ConfigScreen/SettingComponent.tsx")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," (callers pass arbitrary setting values; the inner branches narrow before forwarding). ",(0,a.kt)("inlineCode",{parentName:"li"},"output: any = null")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.ReactElement | null = null"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"items as any")," (for the Dropdown options from ",(0,a.kt)("inlineCode",{parentName:"li"},"enumOptionsToValueLabels"),") \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"items as unknown as DropdownListItem[]")," because ",(0,a.kt)("inlineCode",{parentName:"li"},"enumOptionsToValueLabels")," returns ",(0,a.kt)("inlineCode",{parentName:"li"},"{ [computedKey]: string }[]")," where the runtime values happen to be ",(0,a.kt)("inlineCode",{parentName:"li"},"label"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"value")," but the type system can't tell. Forwarding to ",(0,a.kt)("inlineCode",{parentName:"li"},"SettingsToggle"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"ValidatedIntegerInput"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"SettingTextInput")," adds explicit narrowing (",(0,a.kt)("inlineCode",{parentName:"li"},"!!props.value"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"props.value as number"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"props.value as string"),") per Setting type."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/screens/ConfigScreen/SectionSelector/index.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"settings: Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," (the local ",(0,a.kt)("inlineCode",{parentName:"li"},"SettingsMap")," type isn't exported from ",(0,a.kt)("inlineCode",{parentName:"li"},"@joplin/lib/components/shared/config/config-shared"),"; the function accepts a wider record)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/screens/LogScreen.tsx")," \u2014 2 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"navigation: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ state: { defaultFilter?: string } }")," (the only field accessed). ",(0,a.kt)("inlineCode",{parentName:"li"},"navigationOptions(): any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},": { header: null }"),". Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"styles: any")," builder \u2014 same heterogeneous-style-record pattern as ",(0,a.kt)("inlineCode",{parentName:"li"},"ScreenHeader.styleObject"),". Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/screens/ConfigScreen/ConfigScreen.tsx")," \u2014 touched (not yet processed for disable count, but ",(0,a.kt)("inlineCode",{parentName:"li"},"renderToggle"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"value={value}")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"value={!!value}")," to satisfy the narrowed ",(0,a.kt)("inlineCode",{parentName:"li"},"SettingsToggle.value: boolean"),").")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn linter-ci packages/app-mobile/")," clean. Current state: 131 \u2192 71 disable comments (60 removed)."),(0,a.kt)("p",null,"Third batch (completing the package):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/screens/ConfigScreen/ConfigScreen.tsx")," \u2014 12 removed, 4 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"navigation: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ state?: { sectionName?: string } }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"navigationOptions(): any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},": { header: null }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onHeaderLayout"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"onSectionLayout"),"/inline ",(0,a.kt)("inlineCode",{parentName:"li"},"onLayout")," events \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"LayoutChangeEvent")," (imported from ",(0,a.kt)("inlineCode",{parentName:"li"},"react-native"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"renderButton"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"addSettingButton")," options \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ description?: string; statusComp?: ReactElement; disabled?: boolean }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"handleSetting"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"settingToComponent"),"/inner ",(0,a.kt)("inlineCode",{parentName:"li"},"updateSettingValue")," ",(0,a.kt)("inlineCode",{parentName:"li"},"value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"renderFeatureFlags"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"output: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReactElement[]"),". Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"settings: Record<string, any>")," on both state and props (and the parameters that take settings) \u2014 heterogeneous values (string/number/boolean/object) accessed by string key across many call sites; ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," forces casts at every read. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/screens/Note/Note.tsx")," \u2014 13 removed, 4 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"emptyArray: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"never[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"lastSavedNote: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"styles_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, ReturnType<typeof StyleSheet.create>>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"noteTagDialog_closeRequested: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"()=> void"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"refreshResource(resource: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"focusUpdateIID_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof setTimeout> | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"folderPickerOptions_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderPickerOptions")," (imported from ",(0,a.kt)("inlineCode",{parentName:"li"},"../../ScreenHeader"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"navigationOptions(): any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},": { header: null }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"setState((state: any))")," \u2192 inferred; ",(0,a.kt)("inlineCode",{parentName:"li"},"onMarkForDownload(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ resourceId: string }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onPlainEditorSelectionChange(event: NativeSyntheticEvent<any>)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NativeSyntheticEvent<{ selection: SelectionRange }>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"saveOneProperty(value: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),". Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"editorRef: any")," (union of Markdown/RichText/NoteBody viewers, each with different c
1ommand surfaces); ",(0,a.kt)("inlineCode",{parentName:"li"},"menuOptionsCache_: Record<string, any>")," (heterogeneous command/option entries); ",(0,a.kt)("inlineCode",{parentName:"li"},"dialogbox: any")," (react-native-dialogbox ref, no library types); ",(0,a.kt)("inlineCode",{parentName:"li"},"styles: any")," builder (heterogeneous view/text/icon style entries). Reasons updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/side-menu-content.tsx")," \u2014 1 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"menuItems: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"PromptButtonSpec[]")," (imported from ",(0,a.kt)("inlineCode",{parentName:"li"},"./DialogManager/types"),"). Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"syncReport: any")," \u2014 matches ",(0,a.kt)("inlineCode",{parentName:"li"},"state.syncReport: any")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"@joplin/lib/reducer")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"Synchronizer.reportToLines(report: any)"),"; tightening here would require updating the lib types first. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/NoteEditor/NoteEditor.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"execCommand(command, ...args: any[])")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/NoteEditor/hooks/useEditorCommandHandler.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(...args: any[])")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"; the ",(0,a.kt)("inlineCode",{parentName:"li"},"args[0]?.name")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"args[0]?.args")," reads cast through ",(0,a.kt)("inlineCode",{parentName:"li"},"{ name?: string; args?: unknown[] }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/PlatformImplementation.ts")," \u2014 2 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Components.[key: string]: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"registerComponent(component: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),". Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"get nativeImage(): any")," \u2014 matches ",(0,a.kt)("inlineCode",{parentName:"li"},"BasePlatformImplementation.nativeImage: any"),". Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/plugins/backgroundPage/initializePluginBackgroundIframe.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(window as any).joplin = ...")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(window as Window & { joplin?: unknown }).joplin = ..."),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/plugins/backgroundPage/utils/wrapConsoleLog.ts")," \u2014 2 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"originalLog as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as ((...args: unknown[])=> void) | undefined"),"; outer wrapper signature ",(0,a.kt)("inlineCode",{parentName:"li"},"(...args: any[])")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),". Left: the ",(0,a.kt)("inlineCode",{parentName:"li"},"} as any;")," cast at end of ",(0,a.kt)("inlineCode",{parentName:"li"},"wrapLogFunction")," \u2014 assigning a generic ",(0,a.kt)("inlineCode",{parentName:"li"},"(...args: unknown[])=> void")," to a specific console method requires going through ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," because TypeScript treats ",(0,a.kt)("inlineCode",{parentName:"li"},"console[key]"),"'s type as the intersection of all method signatures. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/NoteEditor/ImageEditor/ImageEditor.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"onError(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"WebViewErrorEvent")," (imported from ",(0,a.kt)("inlineCode",{parentName:"li"},"react-native-webview/lib/WebViewTypes"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"contentScripts/markdownEditorBundle/utils/useCodeMirrorPlugins.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"postMessageHandler(message: any): Promise<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<unknown>")," (matches ",(0,a.kt)("inlineCode",{parentName:"li"},"ContentScriptData.postMessageHandler: (message: unknown)=> unknown")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"@joplin/editor/types"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"contentScripts/rendererBundle/useWebViewSetup.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"pluginOptions: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginOptions")," (imported from ",(0,a.kt)("inlineCode",{parentName:"li"},"@joplin/renderer/MarkupToHtml"),"); inner ",(0,a.kt)("inlineCode",{parentName:"li"},"enabled: subValues[n]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"enabled: !!subValues[n]")," (PluginOptions expects boolean)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"contentScripts/rendererBundle/contentScript/Renderer.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"pluginSettings: Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"contentScripts/imageEditorBundle/contentScript/index.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"window.ResizeObserver = class { ... } as any")," \u2014 added the missing ",(0,a.kt)("inlineCode",{parentName:"li"},"unobserve()")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"disconnect()")," methods so the class satisfies the ",(0,a.kt)("inlineCode",{parentName:"li"},"ResizeObserver")," interface without a cast."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"root.tsx")," \u2014 0 removed, 6 left (reasons updated). ",(0,a.kt)("inlineCode",{parentName:"li"},"storeDispatch: any")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"logReducerAction(action: any)")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"generalMiddleware = (store: any) => (next: any) => async (action: any)")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"reduxSharedMiddleware(...storeDispatch as any)")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"handleOpenURL_: any")," \u2014 all kept as ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," because redux actions in this codebase don't have a single typed union; tightening would require a coordinated rewrite of every dispatched action across the mobile app. Reasons updated on every disable comment."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/appReducer.ts")," \u2014 0 removed, 8 left (reasons updated). The 3 ",(0,a.kt)("inlineCode",{parentName:"li"},"Old code before rule was applied")," entries got their reason rewritten; the 5 ",(0,a.kt)("inlineCode",{parentName:"li"},"Assigning types... would be too big of a refactoring")," entries were already correctly tagged."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/types.ts")," \u2014 0 removed, 2 left (reasons updated). ",(0,a.kt)("inlineCode",{parentName:"li"},"AppState.route")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"AppState.noteSideMenuOptions")," \u2014 same redux NAV / per-screen heterogeneous-payload story as appReducer."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/fs-driver/fs-driver-rn.ts")," \u2014 0 removed, 1 left (reason already documented in the first batch)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"}
1,"components/app-nav.tsx")," \u2014 0 removed, 2 left (reasons documented in the second batch)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/NoteList.tsx")," \u2014 0 removed, 1 left (",(0,a.kt)("inlineCode",{parentName:"li"},"StyleSheet.NamedStyles<any>")," \u2014 reason documented in the second batch)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/ScreenHeader/index.tsx")," \u2014 0 removed, 1 left (heterogeneous ",(0,a.kt)("inlineCode",{parentName:"li"},"styleObject")," builder \u2014 reason documented in the second batch)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/screens/LogScreen.tsx")," \u2014 0 removed, 1 left (heterogeneous ",(0,a.kt)("inlineCode",{parentName:"li"},"styles")," builder \u2014 reason documented in the second batch).")),(0,a.kt)("p",null,"Verification: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn linter-ci packages/app-mobile/")," clean; root ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," (all workspaces) clean."),(0,a.kt)("p",null,'Summary: 131 \u2192 33 disable comments (98 removed). The 33 remaining all fall into a small set of "structural" categories:'),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Redux action/route shapes across ",(0,a.kt)("inlineCode",{parentName:"li"},"root.tsx")," (6), ",(0,a.kt)("inlineCode",{parentName:"li"},"appReducer.ts")," (8), ",(0,a.kt)("inlineCode",{parentName:"li"},"utils/types.ts")," (2), ",(0,a.kt)("inlineCode",{parentName:"li"},"app-nav.tsx")," (2) \u2014 total 18. Tightening requires a discriminated action union across the mobile codebase."),(0,a.kt)("li",{parentName:"ul"},"Heterogeneous style-builder objects in ",(0,a.kt)("inlineCode",{parentName:"li"},"ScreenHeader/index.tsx")," (1), ",(0,a.kt)("inlineCode",{parentName:"li"},"LogScreen.tsx")," (1), ",(0,a.kt)("inlineCode",{parentName:"li"},"Note.tsx")," (1) \u2014 total 3. Each mixes ViewStyle/TextStyle/IconStyle entries built incrementally."),(0,a.kt)("li",{parentName:"ul"},"Heterogeneous redux state fields tied to lib's loose typing: ",(0,a.kt)("inlineCode",{parentName:"li"},"syncReport: any")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"side-menu-content.tsx")," (1); ",(0,a.kt)("inlineCode",{parentName:"li"},"nativeImage: any")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"PlatformImplementation.ts")," (1) \u2014 total 2. Tightening requires updating the lib base types first."),(0,a.kt)("li",{parentName:"ul"},"Per-screen ConfigScreen settings: ",(0,a.kt)("inlineCode",{parentName:"li"},"settings: Record<string, any>")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"ConfigScreen.tsx")," (4 occurrences: state, props, ",(0,a.kt)("inlineCode",{parentName:"li"},"sectionToComponent"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"renderFeatureFlags"),") \u2014 total 4. Tightening to ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," forces casts at every ",(0,a.kt)("inlineCode",{parentName:"li"},"settings[key]")," read across the file."),(0,a.kt)("li",{parentName:"ul"},"Per-component fields that the library doesn't type: ",(0,a.kt)("inlineCode",{parentName:"li"},"editorRef"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"dialogbox"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"menuOptionsCache_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"styles")," builder in ",(0,a.kt)("inlineCode",{parentName:"li"},"Note.tsx")," (4) \u2014 total 4."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"NamedStyles<any>")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteList.tsx")," (1) \u2014 TypeScript pattern limitation."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"console[key] = ... as any")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"wrapConsoleLog.ts")," (1) \u2014 TypeScript pattern limitation (intersection of console method signatures)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"output: any[]")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"fs-driver-rn.ts")," (1) \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"readDirStats")," output mixes SAF ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"DocumentFileDetail")," and normalized ",(0,a.kt)("inlineCode",{parentName:"li"},"Stat"),"-shaped entries.")),(0,a.kt)("h2",{id:"packagesserver"},"packages/server"),(0,a.kt)("p",null,"Session date: 2026-05-12"),(0,a.kt)("p",null,"Starting baseline 2026-05-12 matches the progress doc: 227 disable comments across 67 files, all tagged ",(0,a.kt)("inlineCode",{parentName:"p"},"Old code before rule was applied"),"."),(0,a.kt)("p",null,"General observation (different from prior packages): many of the server's ",(0,a.kt)("inlineCode",{parentName:"p"},"any"),"s sit at junction points (Koa context, Knex query callbacks, view contents, error payloads) where tightening propagates through many call sites. So this package will have a much lower remove-rate than the front-end packages."),(0,a.kt)("p",null,"First batch:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/strings.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"yesOrNo(value: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/array.ts")," \u2014 1 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"removeElement")," typed generically as ",(0,a.kt)("inlineCode",{parentName:"li"},"<T>(array: T[], element: T)"),". Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"unique(array: any[])")," \u2014 tried generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T>"),", but ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseModel.loadByIds")," calls it with ",(0,a.kt)("inlineCode",{parentName:"li"},"string[] | number[]")," and TS can't unify ",(0,a.kt)("inlineCode",{parentName:"li"},"T")," across the union, forcing a cast at the call site (a wider blast radius). Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/cache.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"CacheEntry.object: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string")," (always JSON-stringified); ",(0,a.kt)("inlineCode",{parentName:"li"},"setAny/setObject")," ",(0,a.kt)("inlineCode",{parentName:"li"},"o: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"getAny")," return ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<unknown>")," (existing ",(0,a.kt)("inlineCode",{parentName:"li"},"as object")," cast at the one public consumer remains valid)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/errors.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"ErrorOptions.details?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"ApiError.details: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"errorToPlainObject(error: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"'httpCode' in error")," narrowing followed by ",(0,a.kt)("inlineCode",{parentName:"li"},"(error as { httpCode?: number }).httpCode")," casts on each field read (TS's ",(0,a.kt)("inlineCode",{parentName:"li"},"in")," operator doesn't narrow ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," to a typed shape, only to ",(0,a.kt)("inlineCode",{parentName:"li"},"object"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/MustacheService.ts")," \u2014 1 removed, 1 left. The local ",(0,a.kt)("inlineCode",{parentName:"li"},"layoutView: any")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"renderView")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),". Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"View.content?: any")," \u2014 tried tightening to ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),", but ",(0,a.kt)("inlineCode",{parentName:"li"},"routeHandler.ts:61")," reads ",(0,a.kt)("inlineCode",{parentName:"li"},"view.content.error.httpCode")," and other dynamic paths; views contribute heterogeneous content shapes per route. Reason updated.")),(0,a.kt)("p",null,"Files attempted but reverted (still ",(0,a.kt)("inlineCode",{parentName:"p"},"any"),"):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"commands/BaseCommand.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"run(argv: any)"),". Tried ",(0,a.kt)("inlineCode",{parentName:"li"},"yargs.Arguments"),", but subclasses (e.g. ",(0,a.kt)("inlineCode",{parentName:"li"},"CompressOldChangesCommand"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"StorageCommand"),") narrow ",(0,a.kt)("inlineCode",{parentName:"li"},"argv")," to a per-command ",(0,a.kt)("inlineCode",{parentName:"li"},"Argv")," interface, and TS function-parameter contravariance forbids that without making the whole class generic \u2014 which would propagate through every ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseCommand[]")," consumer. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/urlUtils.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"setQueryParameters(query: any)"),". Callers pass Koa ",(0,a.kt)("inlineCode",{parentName:"li"},"ParsedUrlQuery")," (",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string | string[]>"),"), pagination shapes with numbers, and plain string records. Tightening forces fixes at every call site. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"config.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"initConfig(overrides: any)"),". Tried ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<Config>"),", but ",(0,a.kt)("inlineCode",{parentName:"li"},"Config.resourceDir: string")," is required and only set by some test overrides; the existing spread relies on ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," to bypass the missing-field issue. Reason updated.")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean. 227 \u2192 217 disable comments (10 removed)."),(0,a.kt)("p",null,"Second batch:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/KeyValueModel.ts")," \u2014 3 removed, 0 left. The two ",(0,a.kt)("inlineCode",{parentName:"li"},"as any")," casts in ",(0,a.kt)("inlineCode",{parentName:"li"},"value<T>")," use the existing type parameter (",(0,a.kt)("inlineCode",{parentName:"li"},"as T"),"). The local ",(0,a.kt)("inlineCode",{parentName:"li"},"value: any")," in ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"readThenWrite")," becomes ",(0,a.kt)("inlineCode",{parentName:"li"},"await this.value<Value>(key)")," \u2014 the explicit type param uses the public ",(0,a.kt)("inlineCode",{parentName:"li"},"Value = number | string")," already defined in the file."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/BackupItemModel.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"add(content: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string | Buffer")," (the only runtime caller passes a JSON string; the storage type is ",(0,a.kt)("inlineCode",{parentName:"li"},"Buffer"),"). Inner assignment uses ",(0,a.kt)("inlineCode",{parentName:"li"},"content as Buffer"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/UserItemModel.ts")," \u2014 1 removed, 0 left. Dropped ",(0,a.kt)("inlineCode",{parentName:"li"},"as any")," on ",(0,a.kt)("inlineCode",{parentName:"li"},"loadByIds(options.byUserItemIds as any)")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"byUserItemIds")," is already typed ",(0,a.kt)("inlineCode",{parentName:"li"},"number[]")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"loadByIds")," accepts ",(0,a.kt)("inlineCode",{parentName:"li"},"string[] | number[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/UserDeletionModel.ts")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"end(error: any)"),": tried ",(0,a.kt)("inlineCode",{parentName:"li"},"Error"),", but tests pass plain strings. Tried ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | string"),", but ",(0,a.kt)("inlineCode",{parentName:"li"},"errorToString")," requires ",(0,a.kt)("inlineCode",{parentName:"li"},"Error"),"; wrapping strings in ",(0,a.kt)("inlineCode",{parentName:"li"},"new Error()")," changes runtime output (adds a ",(0,a.kt)("inlineCode",{parentName:"li"},"stack")," field to the serialized payload). Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/utils/pagination.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"requestPaginationOrder(query: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ParsedUrlQuery | PaginationQueryParams")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"as string")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"as PaginationOrderDir")," narrowing on the read fields; ",(0,a.kt)("inlineCode",{parentName:"li"},"requestPagination(query: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(Pagination & PaginationQueryParams) | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"filterPaginationQueryParams(query: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"PaginationQueryParams | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"paginateDbQuery")," made generic over ",(0,a.kt)("inlineCode",{parentName:"li"},"<T = unknown>")," for ",(0,a.kt)("inlineCode",{parentName:"li"},"PaginatedResults<T>")," and the local ",(0,a.kt)("inlineCode",{parentName:"li"},"orderSql: any[]")," inferred from ",(0,a.kt)("inlineCode",{parentName:"li"},".map"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/views/table.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Table.requestQuery?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"PaginationQueryParams"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"makeTablePagination(query: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ParsedUrlQuery")," (imported from ",(0,a.kt)("inlineCode",{parentName:"li"},"querystring"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/views/select.ts")," \u2014 0 removed, 2 left. Tried ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),", but callers pass concrete entity types like ",(0,a.kt)("inlineCode",{parentName:"li"},"User")," (no index signature). Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/ChangeModel/ChangeModel.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"requestDeltaPagination(query: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ChangePagination | null"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/ShareModel.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"shareUrl(query: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string | number>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"itemCountByShareIdPerUser"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"groupBy('user_id') as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as { item_count: number; user_id: Uuid }[]")," (Knex's typed builder doesn't carry the aggregate column shape through ",(0,a.kt)("inlineCode",{parentName:"li"},"db.raw"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/testing/koa/FakeRequest.ts")," \u2014 2 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"FakeNodeRequest { method?: string }")," (the only field used)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/testing/koa/FakeResponse.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"body: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"headers_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"set"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"get")," params/return \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/testing/fileApiUtils.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"getDelta")," return type and inner cast ",(0,a.kt)("inlineCode",{parentName:"li"},"PaginatedResults<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"PaginatedResults<unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/items/storage/testUtils.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"let error: any = null")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error & { code?: CustomErrorCode }"),".")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean. 227 \u2192 193 disable comments (34 removed)."),(0,a.kt)("p",null,"Third batch:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/prettycron.ts")," \u2014 17 removed, 0 left. All ",(0,a.kt)("inlineCode",{parentName:"li"},"numbers: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"number[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"numberToDateName(value: any, type: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(value: number | string, type: 'dow' | 'mon')")," (the function does ",(0,a.kt)("inlineCode",{parentName:"li"},"value - 1"),", so wrapping in ",(0,a.kt)("inlineCode",{parentName:"li"},"Number()"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"dateList(numbers: any[], type: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(numbers: number[], type: 'dow' | 'mon')"),"; introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"type LaterSchedule = Record<string, number[]>")," and used it for ",(0,a.kt)("inlineCode",{parentName:"li"},"removeFromSchedule"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"scheduleToSentence"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"removeFromSchedule(schedule, member: any, length: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(LaterSchedule, string, number)"),"; the four ",(0,a.kt)("inlineCode",{parentName:"li"},"cronspec: any"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"numDates: any")," handlers typed as ",(0,a.kt)("inlineCode",{parentName:"li"},"string")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"number"),"; the final ",(0,a.kt)("inlineCode",{parentName:"li"},"(window as any).prettyCron")," cast tightened to ",(0,a.kt)("inlineCode",{parentName:"li"},"(window as Window & { prettyCron?: Record<string, unknown> }).prettyCron"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/routeUtils.test.ts")," \u2014 4 removed, 0 left. Three ",(0,a.kt)("inlineCode",{parentName:"li"},"testCases: any[]")," typed as tuple arrays (",(0,a.kt)("inlineCode",{parentName:"li"},"[string, string, string, ItemAddressingType][]"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"[string, {...}][]"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"[string, string[]][]"),"). ",(0,a.kt)("inlineCode",{parentName:"li"},"routes: Record<string, any>")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, number>")," with three ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Parameters<typeof findMatchingRoute>[1]")," casts at call sites (the test injects numbers in place of ",(0,a.kt)("inlineCode",{parentName:"li"},"Router")," instances)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/api/sessions.test.ts")," \u2014 8 removed, 0 left. Eight ",(0,a.kt)("inlineCode",{parentName:"li"},"(context.response.body as any).id")," casts \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as { id: string }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/api/items.test.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"tree: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, Record<string, null>>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"PaginatedResults<any>")," (\xd72) \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"<unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"result.items as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as SaveFromRawContentResult"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/api/shares.test.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"tree: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, Record<string, null>>"),"; both ",(0,a.kt)("inlineCode",{parentName:"li"},"PaginatedResults<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"<Share>")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"<{ user: { email: string }; status: ShareUserStatus }>")," (the test only reads those fields)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/index/users.test.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"postUser(props: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<User>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"patchUser(user: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<User> & Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"as any).value")," on a ",(0,a.kt)("inlineCode",{parentName:"li"},"querySelector")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"querySelector<HTMLInputElement>('input[name=email]').value"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/admin/users.test.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"postUser(props: any)")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"patchUser(user: any)")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," (tests intentionally pass ",(0,a.kt)("inlineCode",{parentName:"li"},"max_item_size: ''")," which ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<User>")," would reject)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/index/stripe.test.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"WebhookOptions.stripe?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof mockStripe>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"simulateWebhook(object: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/index/shares.link.test.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"getShareContent(query: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"; the inner ",(0,a.kt)("inlineCode",{parentName:"li"},"as any")," return cast \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as string | Buffer"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/api/share_users.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"bodyFields<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"bodyFields<{ status?: number }>
1"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"items: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/api/share_users.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"PaginatedResults<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"<{ share: { id: string } }>"),".")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; spellcheck clean. 227 \u2192 145 disable comments (82 removed)."),(0,a.kt)("p",null,"Fourth batch:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/api/batch.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"SubRequest.body: any")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"SubRequestResponse.body: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"SubRequestResponse.header: Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/api/batch_items.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"PaginatedResults<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"<unknown>"),"; the inner ",(0,a.kt)("inlineCode",{parentName:"li"},"as any")," cast \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as unknown[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/UserModel.test.ts")," \u2014 3 removed, 0 left. The three ",(0,a.kt)("inlineCode",{parentName:"li"},"syncInfo*: any")," test fixtures share a single inline object-shape type with optional ",(0,a.kt)("inlineCode",{parentName:"li"},"ppk")," (the third variant deletes it)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/index/login.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"makeView(error: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | null"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/index/home.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"context.response.body as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as string"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/index/items.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"items: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, Record<string, never>>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/items/storage/StorageDriverS3.ts")," \u2014 2 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"ReadableLike")," interface (only the 3 listener overloads used) so ",(0,a.kt)("inlineCode",{parentName:"li"},"stream2buffer")," is typed; the S3 SDK return is an opaque union, so cast at the call site: ",(0,a.kt)("inlineCode",{parentName:"li"},"stream2buffer(response.Body as ReadableLike)"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/items/storage/StorageDriverS3.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"parse: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"StorageDriverConfig & { enabled?: boolean }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/api/users.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"bodyFields<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"bodyFields<Partial<User>>")," (",(0,a.kt)("inlineCode",{parentName:"li"},"fromApiInput")," accepts a partial user)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/api/users.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"results: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"getApi<{ items: User[] }>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/api/ping.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"body as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as { status: string; message: string }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/LockModel.test.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"'wrongtype' as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as LockType")," (and the same for ",(0,a.kt)("inlineCode",{parentName:"li"},"LockClientType"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"db.migrations.test.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"dbSchemaSnapshot")," return \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Awaited<ReturnType<typeof sqlts.toTypeScript>>"),"; the ",(0,a.kt)("inlineCode",{parentName:"li"},"db as any")," cast \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Parameters<typeof sqlts.toTypeScript>[1]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/testing/testUtils.ts")," \u2014 4 removed, 3 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"createItemTree(tree: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"createItemTree3(tree: any[])")," \u2192 local ",(0,a.kt)("inlineCode",{parentName:"li"},"ItemTree3Node")," interface; ",(0,a.kt)("inlineCode",{parentName:"li"},"checkContextError"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"body: any")," \u2192 cast through ",(0,a.kt)("inlineCode",{parentName:"li"},"as { code?: ErrorCode }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"setupAppContext({} as any, ...)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as AppContext"),". Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"AppContextTestOptions.request: any")," (",(0,a.kt)("inlineCode",{parentName:"li"},"httpMocks.RequestOptions")," is too narrow; callers pass ",(0,a.kt)("inlineCode",{parentName:"li"},"files: { file: { path: string } }")," and free-form bodies); ",(0,a.kt)("inlineCode",{parentName:"li"},"appContext: any")," inside ",(0,a.kt)("inlineCode",{parentName:"li"},"koaAppContext")," (intentionally mocks only a subset of ",(0,a.kt)("inlineCode",{parentName:"li"},"AppContext"),", cast at return); the ",(0,a.kt)("inlineCode",{parentName:"li"},"createBaseAppContext")," one was removed. Reasons updated on the two remaining ones."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/requestUtils.ts")," \u2014 2 removed, 7 left. Two safe removals: the outer ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"IncomingMessage")," cast in ",(0,a.kt)("inlineCode",{parentName:"li"},"formParse")," uses ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as FormParseRequest"),"; the ",(0,a.kt)("inlineCode",{parentName:"li"},"bodyFields"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"bodyFiles")," ",(0,a.kt)("inlineCode",{parentName:"li"},"req: any")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"IncomingMessage"),". The other entries (",(0,a.kt)("inlineCode",{parentName:"li"},"BodyFields"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"FormParseResult.files"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"FormParseRequest.body"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"convertFieldsToKeyValue")," return) were attempted but reverted \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," breaks ",(0,a.kt)("inlineCode",{parentName:"li"},"Fields"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"Files")," compatibility (formidable's ",(0,a.kt)("inlineCode",{parentName:"li"},"File | File[]")," union surfaces ",(0,a.kt)("inlineCode",{parentName:"li"},".filepath")," access errors), and ",(0,a.kt)("inlineCode",{parentName:"li"},"BodyFields")," widening propagates to every route handler that reads ",(0,a.kt)("inlineCode",{parentName:"li"},"body.fields.email")," etc. without narrowing. Reasons updated on the remaining ones."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/routeUtils.ts")," \u2014 5 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Response.response: any")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"constructor(response: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"internalRedirect(...args: any[])")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"ExecRequestResult.response: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"respondWithItemContent(koaResponse: any)")," \u2192 local ",(0,a.kt)("inlineCode",{parentName:"li"},"KoaResponseLike")," interface with just ",(0,a.kt)("inlineCode",{parentName:"li"},"body")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"set()"),". Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"RouteHandler"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"...args: any[], Promise<any>")," \u2014 concrete handlers (login, mfa, users) narrow ",(0,a.kt)("inlineCode",{parentName:"li"},"args")," to per-route field types; tightening propagates through every route. Reason updated. (Plus a downstream cast ",(0,a.kt)("inlineCode",{parentName:"li"},"responseObject.response as typeof ctx.response")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"routeHandler.ts:56")," for the now-",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," response.)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/ChangeModel/ChangeModel.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"itemsToCreate: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ id: string; children: never[] }[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/ChangeModel/ChangeModel.old.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Knex.Raw<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Knex.Raw<unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/api/items.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"bodyFields.items.map((item: any))")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(item: { name: string; body?: string })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"tools/generateTypes.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"'pascal' as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as Config['tableNameCasing']"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/utils/pagination.test.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"testCases: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"[Record<string, unknown> | null, Pagination][]"),"; the inline ",(0,a.kt)("inlineCode",{parentName:"li"},"input: any")," removed by inferring from the tuple. Inner literal ",(0,a.kt)("inlineCode",{parentName:"li"},"dir: 'asc'")," switched to ",(0,a.kt)("inlineCode",{parentName:"li"},"PaginationOrderDir.ASC"),".")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; spellcheck clean. 227 \u2192 102 disable comments (125 removed)."),(0,a.kt)("p",null,"Fifth batch:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/joplinUtils.ts")," \u2014 11 removed, 1 left. Tightened ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"FileViewerResponse.body"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceInfo"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"LinkedItemInfo")," to concrete shapes (",(0,a.kt)("inlineCode",{parentName:"li"},"Buffer | string"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity")," etc.); ",(0,a.kt)("inlineCode",{parentName:"li"},"unserializeJoplinItem")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"serializeJoplinItem")," typed against ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"getResourceInfos")," output uses the named ",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceInfos")," alias; ",(0,a.kt)("inlineCode",{parentName:"li"},"jopItem")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"itemToRender")," use ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity & { ...optional fields }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"FileToRender.content")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Buffer | null")," (the ",(0,a.kt)("inlineCode",{parentName:"li"},"null as any")," cast is no longer needed). Left: the ",(0,a.kt)("inlineCode",{parentName:"li"},"renderOptions: any")," for ",(0,a.kt)("inlineCode",{parentName:"li"},"markupToHtml.render")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"@joplin/renderer"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"RenderOptions")," is loosely typed in that package; tightening would require updating renderer first."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"db.ts")," \u2014 14 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"ConnectionCheckResult.error/latestMigration: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | null")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"{ name: string } | null"),"; the slow-query handler ",(0,a.kt)("inlineCode",{parentName:"li"},"connection: any, bindings: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"DbConnection")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"; the inner ",(0,a.kt)("inlineCode",{parentName:"li"},"queryInfos: Record<any, QueryInfo>")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"timeoutId: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, QueryInfo>")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof setTimeout>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"filterBindings(bindings: any[]): Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"KnexQueryErrorData.bindings: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"migrateList"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"migrations: any")," typed as the actual ",(0,a.kt)("inlineCode",{parentName:"li"},"[string | { file } | { name | file }][]")," tuple via a ",(0,a.kt)("inlineCode",{parentName:"li"},"MigrationInfo")," alias; ",(0,a.kt)("inlineCode",{parentName:"li"},"isNoSuchTableError"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"isUniqueConstraintError")," ",(0,a.kt)("inlineCode",{parentName:"li"},"error: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ code?: string; message?: string } | null | undefined"),". The ",(0,a.kt)("inlineCode",{parentName:"li"},"pg")," ",(0,a.kt)("inlineCode",{parentName:"li"},"setTypeParser")," callback's ",(0,a.kt)("inlineCode",{parentName:"li"},"val: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/testing/apiUtils.ts")," \u2014 11 removed, 0 left. All the ",(0,a.kt)("inlineCode",{parentName:"li"},"body: Record<string, any>")," parameters (\xd79 functions) \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"body: object")," (entity types like ",(0,a.kt)("inlineCode",{parentName:"li"},"User"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"FormUser")," don't have an index signature, so ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," rejects them \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"object")," accepts both concrete entities and plain records). The ",(0,a.kt)("inlineCode",{parentName:"li"},"query: Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," (callers always pass plain objects).")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; lint clean. 227 \u2192 67 disable comments (160 removed)."),(0,a.kt)("p",null,"Sixth batch:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/ItemModel.ts")," \u2014 4 removed, 3 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"SaveFromRawContentResultItem.error")," \u2192 union of ",(0,a.kt)("inlineCode",{parentName:"li"},"Error & { httpCode?: number; code?: string }")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"PlainObjectError")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"null")," (callers read ",(0,a.kt)("inlineCode",{parentName:"li"},".httpCode")," on it; ",(0,a.kt)("inlineCode",{parentName:"li"},"errorToPlainObject")," is also assigned to it). ",(0,a.kt)("inlineCode",{parentName:"li"},"objectToApiOutput")," inner ",(0,a.kt)("inlineCode",{parentName:"li"},"as any[k]")," casts \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(output as Record<string, unknown>)[k]"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"allForDebug")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"(Omit<Item, 'content'> & { content?: string | Buffer }
1)[]")," and now spreads instead of mutating. Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"itemToJoplinItem(): any")," (heterogeneous Note/Folder/Resource/Tag return); the matching ",(0,a.kt)("inlineCode",{parentName:"li"},"joplinItem?: any")," field; the inner ",(0,a.kt)("inlineCode",{parentName:"li"},"joplinItem: any")," local. Reasons updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/BaseModel.ts")," \u2014 7 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"SaveOptions.validationRules"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"previousItem"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"DeleteOptions.validationRules"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"ValidateOptions.rules")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"all()")," ",(0,a.kt)("inlineCode",{parentName:"li"},"rows: any[]")," cast \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as T[]")," only. ",(0,a.kt)("inlineCode",{parentName:"li"},"fromApiInput")," local ",(0,a.kt)("inlineCode",{parentName:"li"},"output: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"as Record<string, unknown>")," on the input spread and ",(0,a.kt)("inlineCode",{parentName:"li"},"as T")," on the return. ",(0,a.kt)("inlineCode",{parentName:"li"},"isNew"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"'id' in (object as any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"typeof object === 'object' && object && 'id' in object")," narrowing."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app.ts")," \u2014 7 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"defaultEnvVariables: Record<Env, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<Env, Partial<EnvVariables>>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"markPasswords(o: Record<string, any>)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"object")," parameter (concrete entity types like ",(0,a.kt)("inlineCode",{parentName:"li"},"DatabaseConfig")," lack index signatures) with an internal cast to ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," for iteration. ",(0,a.kt)("inlineCode",{parentName:"li"},"getEnvFilePath(argv: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ envFile?: string }"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"argv: Argv = yargsArgv as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Argv"),". The ",(0,a.kt)("inlineCode",{parentName:"li"},"commandArgv._")," cast \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as Argv & { _: string[] }"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"main().catch((error: any))")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(error: Error)"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/testing/testRouters.ts")," \u2014 3 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"exec")," callback ",(0,a.kt)("inlineCode",{parentName:"li"},"error/stdout/stderr: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(Error & { signal?: string }) | null")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"string")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"serverProcess: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof spawn>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"checkAndPrintResult(result: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"in")," narrowing. Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"curl")," return type (it parses heterogeneous JSON responses that callers read without narrowing) and the ",(0,a.kt)("inlineCode",{parentName:"li"},"response: any")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"main()")," (same reason). Reasons updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/testing/shareApiUtils.ts")," \u2014 5 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"LegacyTreeNode")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"ShareTreeNode")," interfaces (with ",(0,a.kt)("inlineCode",{parentName:"li"},"[key: string]: unknown")," on ",(0,a.kt)("inlineCode",{parentName:"li"},"ShareTreeNode")," so test fixtures can include arbitrary fields like ",(0,a.kt)("inlineCode",{parentName:"li"},"title"),"). ",(0,a.kt)("inlineCode",{parentName:"li"},"convertTree(tree: any)")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"createItemTree3(tree: any[])")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"shareFolderWithUser(itemTree: any)")," use those types."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/admin/users.ts")," \u2014 5 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"boolOrDefaultToValue"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"intOrDefaultToValue"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"makeUser")," ",(0,a.kt)("inlineCode",{parentName:"li"},"fields: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),". The field reads in ",(0,a.kt)("inlineCode",{parentName:"li"},"makeUser")," cast via ",(0,a.kt)("inlineCode",{parentName:"li"},"as string")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"as number")," per User shape. ",(0,a.kt)("inlineCode",{parentName:"li"},"error: any")," on ",(0,a.kt)("inlineCode",{parentName:"li"},"admin/users/:id")," route handler \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | null"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"accountTypeOptions().map((o: any))")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(o: { value: number; selected?: boolean })"),". The ",(0,a.kt)("inlineCode",{parentName:"li"},"formParse().fields")," is cast ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Record<string, unknown> & { id?: Uuid }
1")," at the makeUser call.")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; lint clean. 227 \u2192 36 disable comments (191 removed)."),(0,a.kt)("p",null,"Final batch:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/index/stripe.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"stripeEvent(req: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"IncomingMessage"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"StripeRouteHandler")," return \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<unknown>"),"; the two ",(0,a.kt)("inlineCode",{parentName:"li"},"(postHandlers as any)[path.id]")," casts collapsed into a single typed lookup."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"env.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"parseEnv(defaultOverrides: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<EnvVariables>"),". The three ",(0,a.kt)("inlineCode",{parentName:"li"},"(output as any)[key]")," writes go through a single ",(0,a.kt)("inlineCode",{parentName:"li"},"outputAsRecord = output as unknown as Record<string, unknown>")," alias."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"routes/index/users.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"makeUser(fields: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"as string")," narrowing on field reads; ",(0,a.kt)("inlineCode",{parentName:"li"},"error: any")," on ",(0,a.kt)("inlineCode",{parentName:"li"},"users/:id")," GET \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"accountTypeOptions().map((o: any))")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(o: { value: number; selected?: boolean })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/UserModel.ts")," \u2014 2 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(resource as any)[key]")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"(previousResource as any)[key]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as Record<string, unknown>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"syncInfo(): Promise<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<{ ppk?: { value: PublicPrivateKeyPair } }>"),". Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"checkMaxItemSizeLimit(joplinItem: any)")," \u2014 same heterogeneous itemToJoplinItem return as ItemModel."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"middleware/routeHandler.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"const r: any = { error }")," \u2192 typed ",(0,a.kt)("inlineCode",{parentName:"li"},"{ error: string; stack?: string; code?: string }"),".")),(0,a.kt)("p",null,"Verification: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn linter-ci packages/server/src/")," clean; root ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," (all workspaces) clean."),(0,a.kt)("p",null,"Summary: 227 \u2192 22 disable comments (205 removed). Zero remaining ",(0,a.kt)("inlineCode",{parentName:"p"},"Old code before rule was applied")," disables \u2014 all 22 left have descriptive reasons explaining why they can't be tightened. They fall into these categories:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Heterogeneous redux/Koa shapes")," (5): ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseCommand.run(argv: any)")," (per-command Argv narrowing forbids the base type from being typed without making the class generic); ",(0,a.kt)("inlineCode",{parentName:"li"},"routeUtils.RouteHandler")," (per-route argument types); ",(0,a.kt)("inlineCode",{parentName:"li"},"joplinUtils.renderOptions")," (renderer package's RenderOptions is loose); ",(0,a.kt)("inlineCode",{parentName:"li"},"MustacheService.View.content")," (each view contributes different fields); ",(0,a.kt)("inlineCode",{parentName:"li"},"testUtils.appContext")," (Koa mock only provides a subset)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Heterogeneous Joplin item types")," (3): ",(0,a.kt)("inlineCode",{parentName:"li"},"ItemModel.itemToJoplinItem")," plus the two ",(0,a.kt)("inlineCode",{parentName:"li"},"joplinItem: any")," locals it feeds; ",(0,a.kt)("inlineCode",{parentName:"li"},"UserModel.checkMaxItemSizeLimit.joplinItem"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Heterogeneous error shapes")," (1): ",(0,a.kt)("inlineCode",{parentName:"li"},"UserDeletionModel.end(error: any)")," \u2014 tests pass strings while runtime callers pass Errors."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Concrete entity types without index signatures")," (3): ",(0,a.kt)("inlineCode",{parentName:"li"},"urlUtils.setQueryParameters(query: any)"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"select.ts")," ",(0,a.kt)("inlineCode",{parentName:"li"},"yesNoOptions"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"yesNoDefaultOptions"),"; ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"app.ts")," config initConfig overrides."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Loose lib-typed defaults")," (1): ",(0,a.kt)("inlineCode",{parentName:"li"},"config.ts")," ",(0,a.kt)("inlineCode",{parentName:"li"},"initConfig(overrides: any)")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<Config>")," requires ",(0,a.kt)("inlineCode",{parentName:"li"},"resourceDir"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Heterogeneous test fixtures / API call results")," (3): ",(0,a.kt)("inlineCode",{parentName:"li"},"testRouters.curl")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"response")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"main")," (parsed JSON responses); ",(0,a.kt)("inlineCode",{parentName:"li"},"array.ts")," ",(0,a.kt)("inlineCode",{parentName:"li"},"unique")," (TS can't unify ",(0,a.kt)("inlineCode",{parentName:"li"},"T")," across ",(0,a.kt)("inlineCode",{parentName:"li"},"string[] | number[]"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"TypeScript pattern limitations")," (6): ",(0,a.kt)("inlineCode",{parentName:"li"},"testUtils.AppContextTestOptions.request"),"; the 4 in ",(0,a.kt)("inlineCode",{parentName:"li"},"requestUtils.ts")," (",(0,a.kt)("inlineCode",{parentName:"li"},"BodyFields"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"FormParseResult.files"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"FormParseRequest.body"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"convertFieldsToKeyValue")," \u2014 all centered on formidable's ",(0,a.kt)("inlineCode",{parentName:"li"},"Fields | Files")," union not allowing narrowing).")),(0,a.kt)("h2",{id:"packagesapp-desktop"},"packages/app-desktop"),(0,a.kt)("p",null,"Session date: 2026-05-13Branch: any_refactor_6"),(0,a.kt)("p",null,"Files processed:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"commands/exportFolders.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"_context: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"CommandContext"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"commands/exportNotes.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"_context: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"CommandContext"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"commands/focusElement.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"_context: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"CommandContext"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"commands/toggleExternalEditing.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"mapStateToTitle(state: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"AppState"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"checkForUpdates.ts")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"parentWindow: any")," is passed to ",(0,a.kt)("inlineCode",{parentName:"li"},"bridge().showMessageBox(parentWindow, ...)")," but the bridge signature is ",(0,a.kt)("inlineCode",{parentName:"li"},"showMessageBox(message: string, ...)")," \u2014 tightening would expose a pre-existing call-site mismatch (logic change). Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ConfigScreen/ButtonBar.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"type StyleProps = any")," \u2192 local interface with theme fields used in template literals."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"}
1,"gui/ConfigScreen/controls/plugins/PluginBox.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"styled.div<{ mb: any }>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string | number"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ConfigScreen/controls/plugins/SearchPlugins.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"onPluginSettingsChange(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"OnPluginSettingChangeEvent")," (already used by callers)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/DialogButtonRow.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"okButtonRef?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.Ref<HTMLButtonElement>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/DialogButtonRow/useKeyboardHandler.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"isInSubModal(targetElement: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"EventTarget | null"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/Dropdown/Dropdown.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"onChange(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.ChangeEvent<HTMLSelectElement>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/EditFolderDialog/Dialog.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"onFolderTitleChange(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.ChangeEvent<HTMLInputElement>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/EditFolderDialog/IconSelector.tsx")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(window as any).EmojiButton")," \u2014 emoji-button library is dynamically loaded onto window with no published types. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ErrorBoundary.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"componentDidCatch(error: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | string")," (matches the ",(0,a.kt)("inlineCode",{parentName:"li"},"typeof === 'string'")," narrowing already in the body); needs ",(0,a.kt)("inlineCode",{parentName:"li"},"as Error")," after the narrowing branch."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/utils/index.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"cursorPos: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ line: number; ch: number }")," (CodeMirror 5 position shape used inside the function)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/utils/types.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"pluginAssets: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RenderResultPluginAsset[]")," (from ",(0,a.kt)("inlineCode",{parentName:"li"},"@joplin/renderer/types"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/utils/useContextMenu.ts")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(editorRef.current as any).alignSelection")," \u2014 CodeMirror 5 runtime method not in the type. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useExternalPlugins.ts")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"CodeMirror: any")," \u2014 receives dynamically-loaded CM5 namespace used for plugin registration; @types/codemirror's signature is too narrow. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/commands/focusElementNoteBody.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"comp: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"WindowCommandDependencies"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/commands/pasteAsMarkdown.ts")," \u2014 1 removed, 0 left. Same."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/commands/pasteAsText.ts")," \u2014 1 removed, 0 left. Same."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/commands/showLocalSearch.ts")," \u2014 1 removed, 0 left. Same."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/commands/showRevisions.ts")," \u2014 1 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"ShowRevisionsDependencies")," (NoteEditor passes a different shape with ",(0,a.kt)("inlineCode",{parentName:"li"},"setShowRevisions"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"isInFocusedDocument")," for this command only \u2014 not registered via ",(0,a.kt)("inlineCode",{parentName:"li"},"useWindowCommandHandler"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useJoplinCommands.ts")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"CodeMirror: any")," \u2014 same reason as ",(0,a.kt)("inlineCode",{parentName:"li"},"useExternalPlugins.ts"),". Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useKeymap.ts")," \u2014 0 removed, 1 left. Same."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useScrollUtils.ts")," \u2014 0 removed, 1 left. Same."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useContentScriptRegistration.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"postMessageHandler(message: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," (consumed by ",(0,a.kt)("inlineCode",{parentName:"li"},"emitContentScriptMessage")," which already accepts ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/PlainEditor/PlainEditor.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"onChange(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.ChangeEvent<HTMLTextAreaElement>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/TinyMCE/utils/joplinCommandToTinyMceCommands.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"value?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"string")," (every literal in the file uses string values)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/TinyMCE/utils/useEditDialog.ts")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"onSubmit(dialogApi: any)")," \u2014 TinyMCE dialog API not in published types. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/editorCommandDeclarations.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, boolean>")," (every literal in the file is a boolean)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/utils/contextMenu.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"saveFileData(data: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string | NodeJS.ArrayBufferView")," (matches ",(0,a.kt)("inlineCode",{parentName:"li"},"fs.writeFile"),"'s accepted data types)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/addProfile.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"comp: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"WindowControl"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onClose(answer: string)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"as string")," (matches ",(0,a.kt)("inlineCode",{parentName:"li"},"PromptOptions.onClose")," shape)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/moveToFolder.ts")," \u2014 1 removed, 0 left. Same \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"WindowControl"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/renameFolder.ts")," \u2014 1 removed, 0 left. Same; onClose answer narrowed via cast."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/renameTag.ts")," \u2014 1 removed, 0 left. Same."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/OneDriveLoginScreen.tsx")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"React.Component<any, any>")," \u2014 old class component without state/props refactor. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ResizableLayout/ResizableLayout.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"newSize: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ width?: number; height?: number }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ResizableLayout/utils/layoutItemProp.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(item as any)[propName]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"propName: keyof LayoutItem"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"item[propName]")," is typed; caller (MainScreen.tsx) needs ",(0,a.kt)("inlineCode",{parentName:"li"},"as string")," for previously-loose ",(0,a.kt)("inlineCode",{parentName:"li"},"item.context.pluginId"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ResizableLayout/utils/persist.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"layout: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"LayoutItem")," (the type was already imported)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ResizableLayout/utils/style.ts")," \u2014 0 removed, 1 left. styled-components ",(0,a.kt)("inlineCode",{parentName:"li"},".attrs")," typing collides with the dynamic style attrs (",(0,a.kt)("inlineCode",{parentName:"li"},"props.size"),"). Reason updated; ",(0,a.kt)("inlineCode",{parentName:"li"},"(props: any)")," callback now typed inline."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ResizableLayout/utils/types.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"context?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ResizableLayout/utils/useWindowResizeEvent.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"eventEmitter: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ current: { emit: (name: string) => void } }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/Root.tsx")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"React.Component<Props, any>")," \u2014 implicit state shape; tightening requires structural refactor. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/Sidebar/styles/index.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"type StyleProps = any")," \u2192 local interface with theme + item discriminators."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/StatusScreen/StatusScreen.tsx")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"style: any")," is spread into ",(0,a.kt)("inlineCode",{parentName:"li"},"theme.containerStyle")," (loosely typed). Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/SyncWizard/Dialog.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"boxes: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.ReactNode[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/utils/useDropHandler.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"editorRef: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RefObject<NoteBodyEditorRef>"),". Tightening exposed two ",(0,a.kt)("inlineCode",{parentName:"li"},"execCommand()")," floating-Promise calls; fixed with ",(0,a.kt)("inlineCode",{parentName:"li"},"void")," (same ",(0,a.kt)("inlineCode",{parentName:"li"},"void")," pattern as showLocalSearch)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/utils/useMessageHandler.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"editorRef: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RefObject<NoteBodyEditorRef>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/utils/useNoteSearchBar.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"noteSearchBarRef: MutableRefObject<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MutableRefObject<HTMLInputElement | null>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/utils/usePluginServiceRegistration.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"ref: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Ref<unknown>")," (must use ",(0,a.kt)("inlineCode",{parentName:"li"},"Ref"),", not ",(0,a.kt)("inlineCode",{parentName:"li"},"RefObject"),", to accept ",(0,a.kt)("inlineCode",{parentName:"li"},"ForwardedRef")," callers)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/utils/useSearchMarkers.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"keywords: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ value: string; type?: string; accuracy?: string }[]")," (matches both ",(0,a.kt)("inlineCode",{parentName:"li"},"Keyword"),"-consuming code and the literal from ",(0,a.kt)("inlineCode",{parentName:"li"},"useNoteSearchBar"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteList/utils/useOnNoteClick.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(event.target as any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"HTMLElement"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteList/utils/useScroll.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"event: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.UIEvent<HTMLDivElement>"),"; switched ",(0,a.kt)("inlineCode",{parentName:"li"},"event.target")," to ",(0,a.kt)("inlineCode",{parentName:"li"},"event.currentTarget")," (target is ",(0,a.kt)("inlineCode",{parentName:"li"},"EventTarget")," without scrollTop)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteListControls/commands/focusSearch.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"searchBarRef: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ current: { select: ()=> void } | null }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteListHeader/useDragAndDrop.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as InsertAt")," (now exported from ",(0,a.kt)("inlineCode",{parentName:"li"},"useDragAndDrop"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"}
1,"gui/NoteListHeader/utils/validateColumns.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(props: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<NoteListColumn>[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/showNoteContentProperties.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"comp: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"WindowControl"),".")),(0,a.kt)("p",null,"Checkpoint 5 (2026-05-13):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/showNoteProperties.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"comp: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"WindowControl"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/showShareFolderDialog.ts")," \u2014 1 removed, 0 left. Same."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/showShareNoteDialog.ts")," \u2014 1 removed, 0 left. Same."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/showSpellCheckerMenu.ts")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Menu.buildFromTemplate(menuItems as any)")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"spellCheckerConfigMenuItems")," returns a heterogeneous menu shape that doesn't satisfy Electron's ",(0,a.kt)("inlineCode",{parentName:"li"},"MenuItemConstructorOptions")," structurally. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/toggleNotesSortOrderField.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"field?: string | any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string | [string, boolean]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/utils/useWindowControl.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"onClose(answer: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"as PromptSuggestion<T>")," cast inside."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/dialogs.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"options: any = null")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/hooks/usePrevious.ts")," \u2014 1 removed, 0 left. Dangling disable comment (no ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," in the body) \u2014 removed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/style/StyledInput.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"type StyleProps = any")," \u2192 local interface with theme fields."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/utils/convertToScreenCoordinates.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"o: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," with internal ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," narrowing after ",(0,a.kt)("inlineCode",{parentName:"li"},"JSON.parse(JSON.stringify(o))"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"integration-tests/util/setMessageBoxResponse.ts")," \u2014 0 removed, 1 left. Mock return cast prevents breakage when Electron's ",(0,a.kt)("inlineCode",{parentName:"li"},"MessageBoxReturnValue")," shape evolves. Reason updated; redundant block comment removed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"tools/notarizeMacApp.ts")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"appBundleId")," is no longer in ",(0,a.kt)("inlineCode",{parentName:"li"},"@electron/notarize"),"'s ",(0,a.kt)("inlineCode",{parentName:"li"},"NotaryToolStartOptions")," but still required at runtime. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/checkForUpdatesUtilsTestData.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"releases1/2/3: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown as GitHubRelease[]")," cast at the end of each array literal (fixtures include extra GitHub API fields not in ",(0,a.kt)("inlineCode",{parentName:"li"},"GitHubRelease"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/checkForUpdatesUtils.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"testCases: [any, \u2026][]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"[GitHubRelease[], \u2026][]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/Navigator.tsx")," \u2014 0 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"ScreenProps = any"),": heterogeneous per-screen prop shapes; the navigator just spreads them. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NewWindowOrIFrame.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"createPortal(...) as any")," cast wasn't needed; ",(0,a.kt)("inlineCode",{parentName:"li"},"ReactPortal")," already assignable to ",(0,a.kt)("inlineCode",{parentName:"li"},"ReactNode"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/DropboxLoginScreen.tsx")," \u2014 0 removed, 2 left. Reasons updated (old class component + JS module without exported type)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/Sidebar/Sidebar.tsx")," \u2014 0 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"syncReport: any")," matches the lib reducer shape; the inner ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"syncCompletedWithoutError")," already had a descriptive reason. Both reasons now explain why they can't be tightened locally."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/Button/Button.tsx")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"type StyleProps = any")," \u2192 local theme interface; ",(0,a.kt)("inlineCode",{parentName:"li"},"ref: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.Ref<HTMLButtonElement>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ExtensionBadge.tsx")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"style?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.CSSProperties"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"themeSelector(_state: any, props: any)")," \u2192 typed by ",(0,a.kt)("inlineCode",{parentName:"li"},"Props"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ImportScreen.tsx")," \u2014 2 removed, 0 left. Local ",(0,a.kt)("inlineCode",{parentName:"li"},"ProgressState")," interface; ",(0,a.kt)("inlineCode",{parentName:"li"},"onError(error: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/MultiNoteActions.tsx")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"notes: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"multiNotesButton_click(item: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MenuItem")," (electron)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteRevisionViewer.tsx")," \u2014 2 removed, 0 left. Dangling disable on ",(0,a.kt)("inlineCode",{parentName:"li"},"revisionList_onChange")," removed; ",(0,a.kt)("inlineCode",{parentName:"li"},"webview_ipcMessage(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ channel?: string; args?: unknown[] }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ResizableLayout/utils/setLayoutItemProps.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"props: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<LayoutItem>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"(item as any)[n]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(item as unknown as Record<string, unknown>)[n]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ResizableLayout/utils/useLayoutItemSizes.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"noWidth/HeightChildren: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ item: LayoutItem; parent: LayoutItem }[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ToggleEditorsButton/styles/index.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"innerButton/output: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"CSSProperties")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, CSSProperties>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/gotoAnything.ts")," \u2014 2 removed, 0 left. Local ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginMenuItem")," interface for ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginManager.menuItems().find(...)"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/importFrom.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"errors: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(string|Error)[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onProgress(status: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/hooks/useEffectDebugger.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"effectHook/dependencies/dependencyNames")," typed as ",(0,a.kt)("inlineCode",{parentName:"li"},"EffectCallback"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"string[]"),"; reduce accum typed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/hooks/useImperativeHandlerDebugger.ts")," \u2014 2 removed, 0 left. Made generic over T; ",(0,a.kt)("inlineCode",{parentName:"li"},"ref: Ref<T>"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"effectHook: ()=> T"),", deps typed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/hooks/usePropsDebugger.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"props: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"dependencies: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/lib/SearchInput/SearchInput.tsx")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"inputRef?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.Ref<HTMLInputElement>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onChange(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.ChangeEvent<HTMLInputElement>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/utils/loadScript.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"attrs?: Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"element: any")," \u2192 typed ",(0,a.kt)("inlineCode",{parentName:"li"},"HTMLLinkElement | HTMLScriptElement | null")," with branch-specific locals."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/PlatformImplementation.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Components")," index \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"registerComponent(_, component: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/UserWebview.tsx")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"theme?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"ref: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.Ref<UserWebviewRef>")," (new exported interface)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/utils/useEditorSearchHandler.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"searchMarkers: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"SearchMarkers"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"webviewRef: RefObject<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RefObject<NoteViewerControl>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/utils/useWebviewIpcMessage.ts")," \u2014 2 removed, 0 left. Local ",(0,a.kt)("inlineCode",{parentName:"li"},"WebviewIpcEvent { channel?; args? }")," used for both ",(0,a.kt)("inlineCode",{parentName:"li"},"onMessage")," parameter and the returned callback; ",(0,a.kt)("inlineCode",{parentName:"li"},"arg0")," cast ",(0,a.kt)("inlineCode",{parentName:"li"},"as number")," at the ",(0,a.kt)("inlineCode",{parentName:"li"},"percentScroll")," call."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useLineSorting.ts")," \u2014 0 removed, 2 left. Same dynamic CM5 loader / runtime instance reason as the other v5 utils. Reasons updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/TinyMCE/utils/setupToolbarButtons.ts")," \u2014 0 removed, 2 left. TinyMCE editor + ToggleButton api types not in published types. Reasons updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/TinyMCE/utils/useScroll.ts")," \u2014 1 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"scheduleOnScroll(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ percent: number }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"editor: any")," stays (TinyMCE Editor type narrower than getDoc/getWin usage). Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/utils/useFormNote.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"editorRef: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RefObject<NoteBodyEditorRef>")," (exposed a floating Promise in ",(0,a.kt)("inlineCode",{parentName:"li"},"handleAutoFocus"),"; fixed with ",(0,a.kt)("inlineCode",{parentName:"li"},"void"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"onResourceChange(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ id: string }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/utils/useWindowCommandHandler.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"noteSearchBarRef: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MutableRefObject<HTMLInputElement | null>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"execute(..., ...args: any[])")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteList/utils/types.ts")," \u2014 2 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"themeId: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"number"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"resizableLayoutEventEmitter: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"EventEmitter"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"searches: any[]")," left with descriptive reason (matches lib reducer shape)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteListWrapper/NoteListWrapper.tsx")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"resizableLayoutEventEmitter: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"EventEmitter"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"depNameToNoteProp(event.name as any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"as ListRendererDependency"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/Sidebar/hooks/useOnRenderItem.tsx")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(folder as any).note_count")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(folder as FolderEntity & { note_count?: number }).note_count")," (dynamic SQL-only field).")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; lint clean on changed files; spellcheck clean. 431 \u2192 368 disable comments (63 removed; cumulative 109/477)."),(0,a.kt)("p",null,"Checkpoint 6 (2026-05-13):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/editAlarm.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"comp: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"WindowControl"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onClose(answer: any, buttonType: string)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(unknown, unknown)")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"as number")," for ",(0,a.kt)("inlineCode",{parentName:"li"},"todo_due"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"mapStateToTitle(state: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"State")," (from lib reducer)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteListHeader/useDragAndDrop.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"setupDataTransfer.data: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onResizerDragOver as any")," (\xd72) \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as EventListener")," for ",(0,a.kt)("inlineCode",{parentName:"li"},"add/removeEventListener"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteListItem/utils/prepareViewProps.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"output: any")," \u2192 typed local shape ",(0,a.kt)("inlineCode",{parentName:"li"},"{note?: {folder?}; item?: {size?; selected?; index?}}"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"(note as any)[propName]")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"(itemSize as any)[propName]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Record<string, unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ResizableLayout/utils/movements.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"array_move")," made generic over T; ",(0,a.kt)("inlineCode",{parentName:"li"},"produce(layout, (draft: any))")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"LayoutItem"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"newSize: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ width?: number; height?: number }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ToolbarButton/ToolbarButton.tsx")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"getProp(props, name, defaultValue: any = null)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," default; record-cast accessors; cast ",(0,a.kt)("inlineCode",{parentName:"li"},"title/tooltip/iconName as string")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"onClick as (()=> void) | undefined")," at call sites."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"InteropServiceHelper.ts")," \u2014 1 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<Buffer | null>")," (this exposed a downstream ",(0,a.kt)("inlineCode",{parentName:"li"},"writeFile(string)")," mismatch in ",(0,a.kt)("inlineCode",{parentName:"li"},"usePrintToCallback.ts")," \u2014 added ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as string")," there with the runtime accepting Buffer). The other two (",(0,a.kt)("inlineCode",{parentName:"li"},"pageSize as any"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"webContents.print(options as any)"),") stay with descriptive reasons (Electron's option types stricter than what we pass)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/MasterPasswordDialog/Dialog.tsx")," \u2014 0 removed, 3 left. PasswordInput's ",(0,a.kt)("inlineCode",{parentName:"li"},"ChangeEventHandler")," is typed as ",(0,a.kt)("inlineCode",{parentName:"li"},"(event: {value: string})=> void")," but the runtime hands a DOM ",(0,a.kt)("inlineCode",{parentName:"li"},"React.ChangeEvent")," through (StyledInput passes the raw onChange). Updated reason on all three handlers."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/EncryptionConfigScreen/EncryptionConfigScreen.tsx")," \u2014 2 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"themeId: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"number"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"infoComp: any = null")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.ReactNode"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"onPasswordInputChange")," left for the same PasswordInput reason above; reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteListControls/NoteListControls.tsx")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"StyleProps = any")," \u2192 local interface; ",(0,a.kt)("inlineCode",{parentName:"li"},"StyledRoot: any")," typed via interface; ",(0,a.kt)("inlineCode",{parentName:"li"},"iconMap: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/PdfViewer.tsx")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"StyleProps = any")," \u2192 local theme interface; ",(0,a.kt)("inlineCode",{parentName:"li"},"resource: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onMessage_(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MessageEvent<{ name; text? }>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"}
1,"gui/ConfigScreen/controls/SettingComponent.tsx")," \u2014 2 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"onChange(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ value: unknown }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"inputStyle: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"CSSProperties"),". The ",(0,a.kt)("inlineCode",{parentName:"li"},"settingKeyToControl")," declaration's ",(0,a.kt)("inlineCode",{parentName:"li"},"React.FC<any>")," left \u2014 each control's props differ and tightening would require structural changes. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/v6/CodeMirror.tsx")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"pluginAssets: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RenderResultPluginAsset[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"(commands as any)[cmd.name](cmd.value)")," \u2192 typed record cast; ",(0,a.kt)("inlineCode",{parentName:"li"},"options: any")," \u2192 inline typed object with optional ",(0,a.kt)("inlineCode",{parentName:"li"},"percent"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ResizableLayout/utils/persist.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"saveLayout(layout): any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<LayoutItem>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"produce(layout, (draft: any))")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"LayoutItem"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"delete (item as any)[k]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"loadLayout(layout: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<LayoutItem> | null")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"as LayoutItem")," on the spread."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/utils/resourceHandling.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"commandAttachFileToBody.options")," \u2192 local ",(0,a.kt)("inlineCode",{parentName:"li"},"CommandAttachFileToBodyOptions"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"resourcesStatus.resourceInfos: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceInfos")," (renderer); ",(0,a.kt)("inlineCode",{parentName:"li"},"clipboardImageToResource.image: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NativeImage")," (electron type import); ",(0,a.kt)("inlineCode",{parentName:"li"},"getResourcesFromPasteEvent.event: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ preventDefault } | null"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/SearchBar/SearchBar.tsx")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"inputRef?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MutableRefObject<HTMLInputElement | null>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onChange(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ value: string }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onKeyDown(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.KeyboardEvent"),"; inner ",(0,a.kt)("inlineCode",{parentName:"li"},"document.activeElement as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as HTMLElement"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/showPrompt.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"comp: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"WindowControl"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"value?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string")," (matches DialogState shape); ",(0,a.kt)("inlineCode",{parentName:"li"},"autocomplete?: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onClose(answer: any, buttonType: string)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(unknown, unknown)"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/v6/useEditorCommands.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"webviewRef: RefObject<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RefObject<NoteViewerControl>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"insertText(value: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"(editorRef.current as any)[value.name]")," (\xd72) \u2192 single ",(0,a.kt)("inlineCode",{parentName:"li"},"editorAsRecord")," alias typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, (...args: unknown[])=> unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"bridge.ts")," \u2014 3 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"showOpenDialog")," ",(0,a.kt)("inlineCode",{parentName:"li"},"(this.lastSelectedPaths_ as any)[fileType]")," (\xd72) \u2192 typed ",(0,a.kt)("inlineCode",{parentName:"li"},"keyof LastSelectedPath"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"shouldShowMenu(_event: any, params: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(unknown, { isEditable: boolean })"),". The remaining ",(0,a.kt)("inlineCode",{parentName:"li"},"as any")," on ",(0,a.kt)("inlineCode",{parentName:"li"},"dialog.showOpenDialog(this.activeWindow(), options as any)")," stays \u2014 our ",(0,a.kt)("inlineCode",{parentName:"li"},"OpenDialogOptions.properties")," is ",(0,a.kt)("inlineCode",{parentName:"li"},"string[]")," but Electron's is a strict union. Reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"}
1,"gui/ConfigScreen/controls/plugins/PluginsStates.tsx")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"styled.div<any>")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"styled(StyledMessage)<any>")," \u2192 typed prop interfaces; ",(0,a.kt)("inlineCode",{parentName:"li"},"value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"SerializedPluginSettings"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onSearchPluginSettingsChange(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"OnPluginSettingChangeEvent"),".")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; lint clean on changed files; spellcheck clean. 368 \u2192 312 disable comments (56 removed; cumulative 165/477)."),(0,a.kt)("p",null,"Checkpoint 7 (2026-05-13):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/utils/useEditorSearchExtension.ts")," \u2014 3 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"getSearchTerm.keyword: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Keyword"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"match: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{from: {line; ch}; to: {line; ch}}")," (CodeMirror 5 DocumentPosition); ",(0,a.kt)("inlineCode",{parentName:"li"},"marks: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof highlightSearch>[]"),". The ",(0,a.kt)("inlineCode",{parentName:"li"},"stream: any")," overlay token signature stays \u2014 CM5 StringStream isn't typed in this repo."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useCursorUtils.ts")," \u2014 0 removed, 5 left. All ",(0,a.kt)("inlineCode",{parentName:"li"},"CodeMirror: any")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"cm: any")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"params: any")," reasons updated to mention the CM5 dynamic loader / no @types/codemirror."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ResourceScreen.tsx")," \u2014 5 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"onResourceClick/Delete/ToggleSorting"),"'s return ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"void"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"rootStyle: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"CSSProperties & { height?; width? }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"mapStateToProps(state: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"AppState"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/utils/appDialogs.tsx")," \u2014 0 removed, 5 left. Reasons consolidated \u2014 each dialog requires a different ",(0,a.kt)("inlineCode",{parentName:"li"},"customProps")," shape and the render functions intentionally spread an open shape."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app.reducer.ts")," \u2014 5 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"watchedResources: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"navHistory: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"AppStateRoute[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"createAppDefaultState.resourceEditWatcherDefaultState: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<AppState>")," (this required spreading ",(0,a.kt)("inlineCode",{parentName:"li"},"backgroundWindows: {}")," to override the lib's looser default); ",(0,a.kt)("inlineCode",{parentName:"li"},"getNextLayout.currentLayout: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string | string[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"(item as any)[propName]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Record<string, unknown>"),". The main reducer ",(0,a.kt)("inlineCode",{parentName:"li"},"action: any")," stays with reason \u2014 would need a redux action union."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ShareFolderDialog/ShareFolderDialog.tsx")," \u2014 6 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"styled(StyledMessage)<any>")," \xd7 2 \u2192 typed prop interfaces (",(0,a.kt)("inlineCode",{parentName:"li"},"<{index: number}>")," and the bare form); ",(0,a.kt)("inlineCode",{parentName:"li"},"StyleProps = any")," \u2192 local interface; ",(0,a.kt)("inlineCode",{parentName:"li"},"handleError(error: any)")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"defer(error: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"recipientEmail_change(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.ChangeEvent<HTMLInputElement>"),". Needed ",(0,a.kt)("inlineCode",{parentName:"li"},'type="info"')," on ",(0,a.kt)("inlineCode",{parentName:"li"},"<StyledRecipient>")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"<StyledShareState>")," to satisfy the StyledMessage's ",(0,a.kt)("inlineCode",{parentName:"li"},"type: string")," required prop that the original ",(0,a.kt)("inlineCode",{parentName:"li"},"<any>")," cast had hidden (runtime branches on ",(0,a.kt)("inlineCode",{parentName:"li"},"type === 'error'"),", so 'info' = default styling)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteEditor.tsx")," \u2014 6 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"onFieldChange.value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onTitleChange(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.ChangeEvent<HTMLInputElement>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onBodyWillChange(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ changeId: number }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"externalEditWatcher_noteChange(event: any)")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"onNotePropertyChange(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ id; note: NoteEntity }")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"{ note: NoteEntity }")," (matches the ",(0,a.kt)("inlineCode",{parentName:"li"},"AlarmChangeEvent")," shape lib emits); ",(0,a.kt)("inlineCode",{parentName:"li"},"(newFormNote as any)[key]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Record<string, unknown>")," via a typed ",(0,a.kt)("inlineCode",{parentName:"li"},"noteAsRecord")," alias."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ElectronAppWrapper.ts")," \u2014 7 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"stateOptions: any")," \u2192 typed object literal; ",(0,a.kt)("inlineCode",{parentName:"li"},"windowOptions: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"BrowserWindowConstructorOptions")," (uncovered that ",(0,a.kt)("inlineCode",{parentName:"li"},"enableRemoteModule")," is no longer in the published ",(0,a.kt)("inlineCode",{parentName:"li"},"WebPreferences"),"; cast with comment explaining @electron/remote still relies on it); ",(0,a.kt)("inlineCode",{parentName:"li"},"(event as any).isMainFrame")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as Electron.Event & {isMainFrame?: boolean}"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"close/open-url")," event handlers \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"import('electron').Event"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"ipcMain.on")," handlers \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"import('electron').IpcMainEvent")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"args")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," and cast at the assignment site. (Used ",(0,a.kt)("inlineCode",{parentName:"li"},"import('electron').*")," inline rather than ",(0,a.kt)("inlineCode",{parentName:"li"},"Electron.*")," because the project's lint config doesn't surface the ",(0,a.kt)("inlineCode",{parentName:"li"},"Electron")," global.)"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/v5/CodeMirror.tsx")," \u2014 4 removed, 3 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"commands: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, (...args: any[])=> unknown>")," (kept inner ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with reason \u2014 commands are heterogeneous and dispatched by name); ",(0,a.kt)("inlineCode",{parentName:"li"},"replaceSelection.value: any")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"insertText.value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onEditorPaste.event: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ preventDefault } | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"loadScript.script: any")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"element: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{src; id?; attrs?}")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"HTMLScriptElement | HTMLLinkElement")," with branch-specific narrowing; ",(0,a.kt)("inlineCode",{parentName:"li"},"options: any")," \u2192 typed object with optional ",(0,a.kt)("inlineCode",{parentName:"li"},"percent"),". Two of the remaining disables collapsed into the new ",(0,a.kt)("inlineCode",{parentName:"li"},"commands")," typing comment."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useJoplinMode.ts")," \u2014 0 removed, 7 left. All CM5 mode/state/stream ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),"s reason-updated (no @types/codemirror in this repo)."),
1(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteListItem/utils/useItemElement.ts")," \u2014 7 removed, 0 left. All ",(0,a.kt)("inlineCode",{parentName:"li"},"as any")," event-listener casts \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as EventListener"),"; React\u2192DOM event casts \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as React.MouseEvent<HTMLDivElement>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"(element.style as any)[n]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Record<string, unknown>"),".")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; lint clean on changed files; spellcheck clean. 312 \u2192 266 disable comments (46 removed; cumulative 211/477)."),(0,a.kt)("p",null,"Checkpoint 8 (2026-05-13):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/WindowCommandsAndDialogs/commands/setTags.ts")," \u2014 8 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"comp: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"WindowControl"),"; introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"TagOption { value; label }")," for the suggestion arrays; sort/map callbacks typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"TagEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onClose(answer: any[])")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," with internal ",(0,a.kt)("inlineCode",{parentName:"li"},"as TagOption[]"),". The ",(0,a.kt)("inlineCode",{parentName:"li"},"value: startTags")," needed ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as string")," because DialogState's value is typed ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NotePropertiesDialog.tsx")," \u2014 7 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"okButton: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RefObject<HTMLButtonElement>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"styles_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, CSSProperties>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"buttonRow_click(event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ buttonName: string }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"editPropertyButtonClick.initialValue: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string | number | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"(newFormNote as any)[k]")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"(formNote as any)[key]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Record<string, unknown>")," casts; ",(0,a.kt)("inlineCode",{parentName:"li"},"editedValue: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string | number | null"),". Two stay with descriptive reasons: ",(0,a.kt)("inlineCode",{parentName:"li"},"latLongFromLocation")," output spreads into NoteEntity which expects number lat/long while the code keeps them as strings (runtime coercion); ",(0,a.kt)("inlineCode",{parentName:"li"},"createNoteField.value")," is genuinely heterogeneous (timestamps + ids + urls)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/utils/NoteListUtils.ts")," \u2014 0 removed, 11 left. All ",(0,a.kt)("inlineCode",{parentName:"li"},"commandToStatefulMenuItem(...) as any")," casts get a consolidated reason: lib's MenuItem shape doesn't structurally satisfy Electron's MenuItemConstructorOptions."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app.ts")," \u2014 4 removed, 6 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"shouldShowMenu(_event: any, params: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(unknown, { isEditable; inputFieldType })"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceEditWatcher.on('resourceChange', event: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ id: string }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"(window as any).joplin")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Record<string, unknown>"),". The reducer/middleware/Tesseract/menu callback/redux dispatch ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),"s stay with descriptive reasons (base class signatures, dynamic loader, heterogeneous menu items)."),
1(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/ConfigScreen/ConfigScreen.tsx")," \u2014 8 removed, 2 left. Class declaration ",(0,a.kt)("inlineCode",{parentName:"li"},"<any, any>")," stays with reason (legacy class component); ",(0,a.kt)("inlineCode",{parentName:"li"},"private rowStyle_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.CSSProperties"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"sidebar_selectionChange.event: any")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"renderSectionDescription.section: any")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"sectionToComponent.section: any/settings: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"SettingMetadataSection")," + ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"sectionWidths: Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"sectionStyle: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.CSSProperties"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"needRestartComp: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.ReactNode"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"mapStateToProps(state: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"AppState"),". Required ",(0,a.kt)("inlineCode",{parentName:"li"},"settings['sync.target'] as number")," casts at call sites. Constructor ",(0,a.kt)("inlineCode",{parentName:"li"},"props: any")," stays (matches the class's open props type)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/PluginRunner.ts")," \u2014 11 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"ipcRendererSend.args")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"eventHandler.args")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginMessage.args/result/error")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"CallbackPromise")," interface and typed ",(0,a.kt)("inlineCode",{parentName:"li"},"callbackPromises: Record<string, CallbackPromise>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"mapEventIdsToHandlers.arg: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," with internal ",(0,a.kt)("inlineCode",{parentName:"li"},"as Record<string, unknown>")," for the object-iteration branch; ",(0,a.kt)("inlineCode",{parentName:"li"},"ipcRenderer.on")," handler typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"IpcRendererEvent"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"result/error")," locals \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | null")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"as Error")," in the catch."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/utils/useScrollHandler.ts")," \u2014 3 removed, 7 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"scrollTimeoutId_: any")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"restoreEditorPercentScrollTimeoutId_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof setTimeout> | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"scheduleOnScroll.event: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ percent: number }"),". The remaining seven CM5 ",(0,a.kt)("inlineCode",{parentName:"li"},"cm/codeMirror: any")," entries reason-updated to mention the dynamic editor/scrollInfo types."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/v5/utils/useListIdent.ts")," \u2014 0 removed, 9 left. All CM5 plugin-loader ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),"s reason-updated.")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; lint clean on changed files; spellcheck clean. 266 \u2192 226 disable comments (40 removed; cumulative 251/477)."),(0,a.kt)("p",null,"Checkpoint 9 (2026-05-13):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/MainScreen.tsx")," \u2014 12 removed, 4 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"style: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"CSSProperties & { width?; height? }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"State")," fields ",(0,a.kt)("inlineCode",{parentName:"li"},"promptOptions/notePropertiesDialogOptions/noteContentPropertiesDialogOptions/shareNoteDialogOptions")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"waitForNotesSavedIID_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof setInterval>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"ipcRenderer.on")," handler \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(IpcRendererEvent, string, { url })"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"produce(layout, (draft: any))")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"LayoutItem"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"layoutModeListenerKeyDown.event: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"KeyboardEvent"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"urlStyle: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.CSSProperties"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"renderNotification.styles: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, CSSProperties>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"resizableLayout_resize.event: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ layout: LayoutItem }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"resizableLayout_renderItem.event: any")," \u2192 typed shape (",(0,a.kt)("inlineCode",{parentName:"li"},"eventEmitter: EventEmitter; visible; size: Size; item: LayoutItem"),") \u2014 also added missing ",(0,a.kt)("inlineCode",{parentName:"li"},"return null;")," and the explicit ",(0,a.kt)("inlineCode",{parentName:"li"},": React.ReactNode")," return type; ",(0,a.kt)("inlineCode",{parentName:"li"},"components: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, ()=> React.ReactNode>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Dispatch"),". Left: ",(0,a.kt)("inlineCode",{parentName:"li"},"styles_: any")," (heterogeneous \u2014 CSSProperties blocks + computed numbers like rowHeight); reducer/middleware-like patterns elsewhere."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/v5/Editor.tsx")," \u2014 0 removed, 17 left. All CM5 dynamic editor/event/options ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),"s reason-updated; covers ",(0,a.kt)("inlineCode",{parentName:"li"},"EditorProps")," heterogeneous callbacks (",(0,a.kt)("inlineCode",{parentName:"li"},"onChange/onScroll/onEditorPaste/onResize/onUpdate"),"), the dynamic ",(0,a.kt)("inlineCode",{parentName:"li"},"cmOptions")," record, and ref/wrapper signatures."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/utils/types.ts")," \u2014 12 removed, 5 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEditorProps"),": ",(0,a.kt)("inlineCode",{parentName:"li"},"notes: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"editorNoteStatuses: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"selectedNoteTags: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"TagEntity[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"watchedResources: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"highlightedWords: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string[]"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteBodyEditorProps"),": ",(0,a.kt)("inlineCode",{parentName:"li"},"style: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.CSSProperties"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onWillChange.event: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ changeId: number }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"noteToolbar: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.ReactNode"),"; dangling ",(0,a.kt)("inlineCode",{parentName:"li"},"searchMarkers: any")," disable removed (already typed ",(0,a.kt)("inlineCode",{parentName:"li"},"SearchMarkers"),"). ",(0,a.kt)("inlineCode",{parentName:"li"},"MessageEvent.args: any[]")," reason updated. ",(0,a.kt)("inlineCode",{parentName:"li"},"bodyEditorContent: any")," reason updated (TinyMCE retains a raw editor object). ",(0,a.kt)("inlineCode",{parentName:"li"},"ScrollOptions.value")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"OnChangeEvent.content")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"EditorCommand.value")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"CommandValue.args/value")," stay with descriptive reasons \u2014 each editor dispatches heterogeneous shapes through these fields; tightening would require per-command discriminated unions across all editors. ",(0,a.kt)("inlineCode",{parentName:"li"},"searches: any[]")," stays (matches lib reducer).")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; lint clean on changed files; spellcheck clean. 226 \u2192 202 disable comments (24 removed; cumulative 275/477)."),(0,a.kt)("p",null,"Checkpoint 10 (2026-05-13):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/PromptDialog.tsx")," \u2014 11 removed, 9 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"defaultValue/answer/autocomplete/buttons: any")," stay with descriptive reasons (DialogState.promptOptions has heterogeneous values per inputType). ",(0,a.kt)("inlineCode",{parentName:"li"},"styles_: any")," stays (heterogeneous style blocks + react-select factories). ",(0,a.kt)("inlineCode",{parentName:"li"},"answerInput_: any")," stays (HTMLInputElement vs react-select ref depending on inputType). All six react-select style/theme factory callbacks (",(0,a.kt)("inlineCode",{parentName:"li"},"control/input/menu/option/multiValueLabel/multiValueRemove"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"selectTheme"),") reason-updated. ",(0,a.kt)("inlineCode",{parentName:"li"},"onSelectChange.newValue: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onKeyDown.event: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.KeyboardEvent"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"makeAnimated() as any")," casts kept inline with reasons."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/plugins/GotoAnything.tsx")," \u2014 13 removed, 7 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"UserDataCallbackEvent.item: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity | FolderEntity | ResourceEntity | TagEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"folders: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderEntity[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"Dialog: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"React.ComponentType<Props>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"manifest: any")," \u2192 typed object with menuItem shape; ",(0,a.kt)("inlineCode",{parentName:"li"},"onTrigger.event: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ userData }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"inputRef/itemListRef: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RefObject<HTMLInputElement>")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"RefObject<ItemList<...>>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"input_onChange/listItem_onClick/input_onKeyDown.event: any")," \u2192 React event types; ",(0,a.kt)("inlineCode",{parentName:"li"},"results: any[]")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"row: any")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"result: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"GotoAnythingSearchResult[]")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"result.id")," accesses; ",(0,a.kt)("inlineCode",{parentName:"li"},"mergeOverlappingIntervals.f: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"[number, number]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"gotoItem.item: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"GotoAnythingSearchResult & { commandArgs? }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"selectedItemIndex.results: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"GotoAnythingSearchResult[]"),". Notes results from ",(0,a.kt)("inlineCode",{parentName:"li"},"Tag.searchAllWithNotes"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"SearchEngine.search")," and the ",(0,a.kt)("inlineCode",{parentName:"li"},"folder")," spread need ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"as unknown as GotoAnythingSearchResult[]")," casts since lib's signatures are looser. ",(0,a.kt)("inlineCode",{parentName:"li"},"styles_: any")," and the heterogeneous ",(0,a.kt)("inlineCode",{parentName:"li"},"commandResults")," callback signature stay."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/MenuBar.tsx")," \u2014 0 removed, 23 left. All 23 ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," usages reason-updated: Electron ",(0,a.kt)("inlineCode",{parentName:"li"},"MenuItemConstructorOptions")," has heterogeneous shapes (submenu/role/type/click vary by item kind) and the menu structure is built dynamically.")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; lint clean on changed files; spellcheck clean. 202 \u2192 179 disable comments (23 removed; cumulative 298/477)."),(0,a.kt)("p",null,"Checkpoint 11 (2026-05-13) \u2014 final:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx")," \u2014 2 removed, 18 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"stripMarkup.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ collapseWhiteSpaces?: boolean }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatchDidUpdateIID_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof setTimeout> | null"),". All 18 remaining ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),"s reason-updated to mention TinyMCE editor instance/event types being looser than @types/tinymce (we use APIs like getDoc/getWin/formatter/ui.registry/undoManager extensions that aren't in the published types)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/MenuBar.tsx")," \u2014 already updated reasons in checkpoint 10."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/utils/useContextMenu.ts")," \u2014 0 removed, 1 left. Combined ",(0,a.kt)("inlineCode",{parentName:"li"},"github/array-foreach")," + ",(0,a.kt)("inlineCode",{parentName:"li"},"no-explicit-any")," disable kept on one line (lint requires consecutive ",(0,a.kt)("inlineCode",{parentName:"li"},"disable-next-line")," directives to be merged); reason updated to mention lib's MenuItem shape vs Electron's MenuItemConstructorOptions."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/CodeMirror/utils/useScrollHandler.ts")," \u2014 already in checkpoint 8. Inline disable consolidated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/utils/useSearchMarkers.ts")," \u2014 0 removed, 1 left. Combined ",(0,a.kt)("inlineCode",{parentName:"li"},"ban-types")," + ",(0,a.kt)("inlineCode",{parentName:"li"},"no-explicit-any")," disable kept on one line; reason explains ",(0,a.kt)("inlineCode",{parentName:"li"},"searches: any[]")," matches lib reducer and ",(0,a.kt)("inlineCode",{parentName:"li"},"highlightedWords")," is heterogeneous (string[] at call site, keyword shapes inside).")),(0,a.kt)("p",null,"Verification at checkpoint: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; lint clean on changed files; spellcheck clean. 179 \u2192 177 disable comments (2 removed; cumulative 300/477 \u2014 63% reduction)."),(0,a.kt)("h2",{id:"summary"},"Summary"),(0,a.kt)("p",null,"app-desktop final state: ",(0,a.kt)("strong",{parentName:"p"},"177 disable comments remaining out of 477 (300 removed, 63% reduction)"),"."),(0,a.kt)("p",null,"All 177 remaining disables now have ",(0,a.kt)("strong",{parentName:"p"},"descriptive ",(0,a.kt)("inlineCode",{parentName:"strong"},"-- reason")," comments")," explaining why they can't be tightened. They fall into these categories:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"CodeMirror 5 dynamic loader / dynamic editor / scrollInfo / line-handle types")," \u2014 no ",(0,a.kt)("inlineCode",{parentName:"li"},"@types/codemirror")," in this monorepo. Files: ",(0,a.kt)("inlineCode",{parentName:"li"},"useJoplinMode.ts")," (7), ",(0,a.kt)("inlineCode",{parentName:"li"},"useCursorUtils.ts")," (5), ",(0,a.kt)("inlineCode",{parentName:"li"},"useListIdent.ts")," (9), ",(0,a.kt)("inlineCode",{parentName:"li"},"useScrollHandler.ts")," (7), ",(0,a.kt)("inlineCode",{parentName:"li"},"v5/CodeMirror.tsx")," (3), ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"Editor.tsx")," (17), and several smaller utils."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"TinyMCE editor / event types")," \u2014 looser than ",(0,a.kt)("inlineCode",{parentName:"li"},"@types/tinymce")," (we use APIs not in the published types). File: ",(0,a.kt)("inlineCode",{parentName:"li"},"TinyMCE.tsx")," (18)."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"Electron MenuItemConstructorOptions")," \u2014 heterogeneous shapes (submenu/role/type/click vary by item kind). Files: ",(0,a.kt)("inlineCode",{parentName:"li"},"MenuBar.tsx")," (23), ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteListUtils.ts")," (11), ",(0,a.kt)("inlineCode",{parentName:"li"},"app.ts")," (a few)."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"react-select style/theme factories")," \u2014 library's own provided styles, tightening requires importing each StyleConfig generic. File: ",(0,a.kt)("inlineCode",{parentName:"li"},"PromptDialog.tsx")," (9)."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"Redux actions / middleware")," \u2014 heterogeneous action types; tightening would require an action-type union and base class signature change. Files: ",(0,a.kt)("inlineCode",{parentName:"li"},"app.ts"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"app.reducer.ts"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"MainScreen.tsx"),"."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"Legacy class components without props/state interfaces")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"Root.tsx"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"OneDriveLoginScreen.tsx"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"DropboxLoginScreen.tsx"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"ConfigScreen.tsx"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"PromptDialog.tsx"),"."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"Heterogeneous editor commands")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"EditorCommand.value")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"CommandValue.args/value")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"ScrollOptions.value")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"OnChangeEvent.content")," \u2014 each editor dispatches different shapes by name."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"Library API mismatches")," \u2014 Electron's ",(0,a.kt)("inlineCode",{parentName:"li"},"@electron/notarize")," types missing ",(0,a.kt)("inlineCode",{parentName:"li"},"appBundleId"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"WebPreferences.enableRemoteModule")," removed; Electron's ",(0,a.kt)("inlineCode",{parentName:"li"},"OpenDialogOptions.properties")," is a strict union but the app uses ",(0,a.kt)("inlineCode",{parentName:"li"},"string[]"),"."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"Heterogeneous test fixtures / external library shapes")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"electron-context-menu"),"'s actions/props, PluginManager dynamic menu items, ",(0,a.kt)("inlineCode",{parentName:"li"},"tesseract.js")," dynamic loader."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"CSS / styling")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"styled-components.attrs")," typing conflicts; ",(0,a.kt)("inlineCode",{parentName:"li"},"styles_")," blocks that mix CSSProperties with computed numbers.")),(0,a.kt)("h2",{id:"packagesapp-cli"},"packages/app-cli"),(0,a.kt)("p",null,"Session date: 2026-05-13"),(0,a.kt)("p",null,"Files processed:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-cp.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ note, notebook? })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-mv.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ item, notebook })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-ren.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ item, name })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-rmbook.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ notebook, options? })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-rmnote.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ 'note-pattern', options? })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-restore.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ pattern })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-edit.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ note })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-import.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ path, notebook?, options })"),"; outputFormat assignment now requires ",(0,a.kt)("inlineCode",{parentName:"li"},"as ImportModuleOutputFormat"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-mkbook.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ 'new-notebook', options })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-help.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ command? })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-use.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ notebook })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-attach.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ note, file })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-cat.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ note, options })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-geoloc.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ note })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-apidoc.ts")," \u2014 1 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action({ file })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-done.ts")," \u2014 2 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"handleAction(args: { note })")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"action(args: { note })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-set.ts")," \u2014 2 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action(args: { note, name, value? })"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"newNote: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," (still accepted by ",(0,a.kt)("inlineCode",{parentName:"li"},"Note.save"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-ls.ts")," \u2014 1 removed, 1 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action")," args; left ",(0,a.kt)("inlineCode",{parentName:"li"},"queryOptions: any")," because it is fed to both ",(0,a.kt)("inlineCode",{parentName:"li"},"Folder.all")," (FolderLoadOptions) and ",(0,a.kt)("inlineCode",{parentName:"li"},"Note.previews")," (PreviewsOptions) and the union has fields that neither type carries (",(0,a.kt)("inlineCode",{parentName:"li"},"caseInsensitive"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"orderBy"),"). Comment reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/setupCommand.ts")," \u2014 2 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"cmd: BaseCommand"),", introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"PromptOptions"),"; the dispatcher arg is inferred from ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"BaseCommand.setDispatcher(fn: DispatcherFn)")," (added in base-command.ts edit), eliminating the last ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," here. Side fix: ",(0,a.kt)("inlineCode",{parentName:"li"},"App.setupCommand(cmd: string)")," was a wrong-pre-existing-annotation, now typed ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseCommand"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-e2ee.ts")," \u2014 2 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action")," args; typed ",(0,a.kt)("inlineCode",{parentName:"li"},"askForMasterKey(error: { masterKeyId })"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-config.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"chunks: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Buffer[]"),"; typed action args; ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," for resultObj."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-export.ts")," \u2014 3 removed, 0 left. Typed action args; ",(0,a.kt)("inlineCode",{parentName:"li"},"n.id")," map callbacks now infer entity types from ",(0,a.kt)("inlineCode",{parentName:"li"},"loadItems"),"; format assignment uses ",(0,a.kt)("inlineCode",{parentName:"li"},"ExportModuleOutputFormat.Jex"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/gui/FolderListWidget.ts")," \u2014 3 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderListItem = FolderEntity | TagEntity | SearchItem | '-'")," for ",(0,a.kt)("inlineCode",{parentName:"li"},"itemRenderer")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"newItems"),"; replaced ",(0,a.kt)("inlineCode",{parentName:"li"},"(this.folders[i] as any).note_count")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderEntity & { note_count?: number }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-settingschema.ts")," \u2014 4 removed, 0 left. Typed action args; ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," for schema, props; removed unused ",(0,a.kt)("inlineCode",{parentName:"li"},"v: any")," annotation."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/gui/StatusBarWidget.ts")," \u2014 2 removed, 2 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"prompt(promptString: string, options)")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"textStyle: (s: string) => s"),". Left 2 ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," for tkwidgets terminal-kit ",(0,a.kt)("inlineCode",{parentName:"li"},"inputField")," options/callback \u2014 no published types and tkwidgets has no .d.ts. Comments updated with reason."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/LinkSelector.ts")," \u2014 5 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"TextWidget")," interface for tk text widget shape; replaced ",(0,a.kt)("inlineCode",{parentName:"li"},"(lines[i] as any).matchAll")," with direct call (",(0,a.kt)("inlineCode",{parentName:"li"},"String.prototype.matchAll")," is well-typed)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-sync.ts")," \u2014 3 removed, 2 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action")," args, ",(0,a.kt)("inlineCode",{parentName:"li"},"log(...s: string[])"),". Left ",(0,a.kt)("inlineCode",{parentName:"li"},"options: any")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"report: any")," because ",(0,a.kt)("inlineCode",{parentName:"li"},"Synchronizer.start(options: any)")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"Synchronizer.reportToLines(report: any)")," in lib are themselves ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," \u2014 tightening here would diverge from lib. Comments updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/command-testing.ts")," \u2014 5 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"randomElement")," \u2192 generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T>(array: T[]): T | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"itemCount(args: { arg0 })"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"options(): [string, string][]"),"; typed ",(0,a.kt)("inlineCode",{parentName:"li"},"action")," args; ",(0,a.kt)("inlineCode",{parentName:"li"},"promises: Promise<unknown>[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/app.ts")," \u2014 0 removed, 6 left. All disables had descriptive reasons (",(0,a.kt)("inlineCode",{parentName:"li"},"Dynamic command loading system"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"Dynamic command metadata"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"Dynamic command type"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"Dynamic GUI type with many optional methods"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"Redux dispatch type requires AnyAction"),") \u2014 none were ",(0,a.kt)("inlineCode",{parentName:"li"},"Old code before rule was applied"),", so out of scope per rule 3. Side fix in checkpoint 1: ",(0,a.kt)("inlineCode",{parentName:"li"},"App.setupCommand(cmd: string)")," annotation corrected to ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseCommand"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/services/plugins/PluginRunner.ts")," \u2014 6 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"wrapper: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, (...args: unknown[]) => unknown>")," with final cast to ",(0,a.kt)("inlineCode",{parentName:"li"},"typeof Console")," to match ",(0,a.kt)("inlineCode",{parentName:"li"},"SandboxProxy.console"),"; arg arrays \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"activeSandboxCalls_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, boolean>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/base-command.ts")," \u2014 4 removed, 4 left. Introduced typed ",(0,a.kt)("inlineCode",{parentName:"li"},"StdoutFn"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"PromptFn"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"DispatcherFn")," aliases; typed ",(0,a.kt)("inlineCode",{parentName:"li"},"stdout_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"prompt_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"dispatcher_")," fields; typed ",(0,a.kt)("inlineCode",{parentName:"li"},"encryptionCheck(item: { encryption_applied? })"),". Left ",(0,a.kt)("inlineCode",{parentName:"li"},"action(_args: any)")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"options(): unknown[]"),": parameters are contravariant so tightening base would break all subclass overrides. The 3 remaining ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," are now centralized in the type aliases at the top of the file (with reasons): stdout accepts arbitrary message values, prompt response varies, dispatch action shape varies; tests pass sync mocks that don't return Promises."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"tests/HtmlToMd.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"htmlToMdOptions: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ParseOptions")," (exported from ",(0,a.kt)("inlineCode",{parentName:"li"},"@joplin/lib/HtmlToMd"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"tests/MdToHtml.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"newTestMdToHtml(options: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<MdToHtmlConstructorOptions>"),"; the ",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceModel")," mock requires ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as")," cast because it intentionally omits ",(0,a.kt)("inlineCode",{parentName:"li"},"filename")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"isSupportedImageMimeType"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"mdToHtmlOptions")," already had a real type, just a stale disable comment. ",(0,a.kt)("inlineCode",{parentName:"li"},"pluginOptions: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, { enabled: boolean }>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"tests/testUtils.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," on ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginServiceOptions.getState"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"tests/services/keychain/KeychainService.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"describeIfCompatible(fn: any, elseFn: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"() => void"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"tests/services/plugins/PluginService.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(f: any) => f.title")," \u2192 inferred ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderEntity")," (from ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"Folder.all()"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"tests/services/plugins/api/JoplinWorkspace.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"appState: Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string[]>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"result: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ id: string; event: number }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"tests/services/plugins/sandboxProxy.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"args: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"target: any")," \u2192 inferred function type (both ",(0,a.kt)("inlineCode",{parentName:"li"},"it")," blocks).")),(0,a.kt)("p",null,"Verification: package ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," clean; ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn linter-ci packages/app-cli/")," clean; root ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," (all workspaces) clean; spellcheck clean."),(0,a.kt)("p",null,"Summary: 90 \u2192 16 disable comments (74 removed). Zero remaining ",(0,a.kt)("inlineCode",{parentName:"p"},"Old code before rule was applied")," disables \u2014 all 16 left have descriptive reasons explaining why they cannot be tightened. They fall into these categories:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Base-class contravariance")," (4): ",(0,a.kt)("inlineCode",{parentName:"li"},"base-command.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"StdoutFn"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"PromptFn"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"DispatcherFn")," aliases at the top of the file (centralized) and the ",(0,a.kt)("inlineCode",{parentName:"li"},"action(_args: any)")," method. Parameters are contravariant; subclasses narrow per-command, so the base must stay permissive. Tests pass synchronous mocks that don't return Promises."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Heterogeneous query options")," (1): ",(0,a.kt)("inlineCode",{parentName:"li"},"command-ls.ts")," ",(0,a.kt)("inlineCode",{parentName:"li"},"queryOptions")," is passed to both ",(0,a.kt)("inlineCode",{parentName:"li"},"Folder.all")," (FolderLoadOptions) and ",(0,a.kt)("inlineCode",{parentName:"li"},"Note.previews")," (PreviewsOptions) and the union has fields neither type carries; splitting would be a structural refactor."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Loose lib-typed APIs")," (2): ",(0,a.kt)("inlineCode",{parentName:"li"},"command-sync.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"Synchronizer.start(options: any)")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"Synchronizer.reportToLines(report: any)")," in lib are themselves ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),"; tightening here would diverge from lib."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"No published types for JS modules")," (3): ",(0,a.kt)("inlineCode",{parentName:"li"},"StatusBarWidget")," (tkwidgets terminal-kit ",(0,a.kt)("inlineCode",{parentName:"li"},"inputField")," options + callback) and ",(0,a.kt)("inlineCode",{parentName:"li"},"command-sync.ts")," ",(0,a.kt)("inlineCode",{parentName:"li"},"oneDriveApiUtils_")," (",(0,a.kt)("inlineCode",{parentName:"li"},"onedrive-api-node-utils.js")," is plain JS)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("strong",{parentName:"li"},"Dynamic command/state shapes already documented")," (6): all of ",(0,a.kt)("inlineCode",{parentName:"li"},"app.ts"),' was already annotated with descriptive non-"Old code" reasons before this pass \u2014 ',(0,a.kt)("inlineCode",{parentName:"li"},"commands_"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"commandMetadata_"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"activeCommand_"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"gui_"),", dynamic command type at L175, and the redux dispatch type.")),(0,a.kt)("h2",{id:"packageslib"},"packages/lib"),(0,a.kt)("p",null,"Session date: 2026-05-14"),(0,a.kt)("p",null,"Starting count: 1138 disable comments across 212 files (excluding ",(0,a.kt)("inlineCode",{parentName:"p"},"node_modules/"),")."),(0,a.kt)("p",null,"Checkpoint 1 (2026-05-14): 1138 \u2192 1101 (37 removed across ~25 files)."),(0,a.kt)("p",null,"Files processed:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"SyncTargetNone.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"null as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"null as unknown as Synchronizer")," with type-only import."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/shared/config/shouldShowMissingPasswordWarning.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"settings: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"folders-screen-utils.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"scheduleRefreshFoldersIID_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof shim.setTimeout>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"geolocation-node.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"fetchJson")," return \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," (and renamed shadowed ",(0,a.kt)("inlineCode",{parentName:"li"},"let r")," to ",(0,a.kt)("inlineCode",{parentName:"li"},"const response")," to keep types straight after ",(0,a.kt)("inlineCode",{parentName:"li"},".json()"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"hooks/useAsyncEffect.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"dependencies: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"DependencyList")," (type-only import from react)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"hooks/useElementSize.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"elementRef: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RefObject<HTMLElement>")," (type-only import from react)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"markdownUtils.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"searchUrls(tokens: any[])")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownItType.Token[]")," (already had type-only import)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"markupLanguageUtils.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"pluginOptions: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, { enabled: boolean }>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Note.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"t[0]")," cast ",(0,a.kt)("inlineCode",{parentName:"li"},"as NoteEntity")," instead of inner ",(0,a.kt)("inlineCode",{parentName:"li"},"let input: any"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/NoteResource.ts")," \u2014 1 removed, 0 left. Introduced exported ",(0,a.kt)("inlineCode",{parentName:"li"},"AssociatedResourceNote = Partial<NoteEntity> & { resource_id; note_id }")," to reflect the join shape."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Revision.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"input as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"input as RevisionEntity"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Revision.ts")," \u2014 0 removed, 1 left. Tried ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]")," for parsePatch; broke ",(0,a.kt)("inlineCode",{parentName:"li"},"patchItem.diffs")," access. Reverted with updated reason \u2014 diff-match-patch JSON shape, no installed ",(0,a.kt)("inlineCode",{parentName:"li"},"@types/diff-match-patch"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Setting.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"loadSettingsFromFile(): Promise<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<Record<string, unknown>>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/settings/FileHandler.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"SettingValues = Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ntp.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"error: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | null")," in the NTP callback signature."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/ResourceEditWatcher/reducer.ts")," \u2014 0 removed, 1 left. Reason updated (heterogeneous redux state composed across desktop/mobile; action types untyped)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/database/isSqliteSyntaxError.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"sqliteError: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ message?: string }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Importer_EnexToMd.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ImportOptions"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Importer_Raw.test.ts")," \u2014 1 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderEntityWithChildren")," interface; ",(0,a.kt)("inlineCode",{parentName:"li"},"tree: any")," \u2192 typed cast."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/Module.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"format: ... as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as ExportModuleOutputFormat"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/Module.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"format: '' as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as ExportModuleOutputFormat"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/joplinCloudUtils.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Action.payload?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string")," (only ever holds errorMessage)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/noteList/defaultMultiColumnsRenderer.ts")," \u2014 0 removed, 1 left. Reason updated (matches OnRenderNoteHandler which is ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," by design; props heterogeneous per renderer's itemProps)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/noteList/renderTemplate.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"name: '\u2026' as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as ColumnName"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/noteList/renderViewProps.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," with inner narrowing casts."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/ocr/OcrService.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"maintenanceTimer_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof shim.setInterval>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/MenuController.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"store: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginStore")," (new exported alias from ",(0,a.kt)("inlineCode",{parentName:"li"},"ViewController"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/MenuItemController.ts")," \u2014 1 removed, 0 left. Same fix via ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginStore"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/ToolbarButtonController.ts")," \u2014 1 removed, 0 left. Same fix via ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginStore"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/ViewController.ts")," \u2014 3 removed, 1 left. Introduced exported ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginStore = Store<any>")," (state heterogeneous across desktop/mobile \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"mainLayout")," lives on AppState only); typed ",(0,a.kt)("inlineCode",{parentName:"li"},"store_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"store"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"message"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"storeView")," stays ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," (controllers index different view shapes)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/Plugin.ts")," \u2014 4 removed, 0 left. Introduced exported ",(0,a.kt)("inlineCode",{parentName:"li"},"MessageListenerCallback = (message: unknown)=> Promise<unknown>"),"; typed ",(0,a.kt)("inlineCode",{parentName:"li"},"messageListener_"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"contentScriptMessageListeners_"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"emitMessage"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"onMessage"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"onContentScriptMessage"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"emitContentScriptMessage"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/RepositoryApi.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(manifest as any)[field]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as const")," tuple + direct indexing."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinContentScripts.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"callback: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MessageListenerCallback"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinInterop.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"...module as any")," \u2192 spread + ",(0,a.kt)("inlineCode",{parentName:"li"},"format: module.format as ExportModuleOutputFormat"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/utils/loadContentScripts.ts")," \u2014 1 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"postMessageHandler")," now async returning ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<unknown>"),". The ",(0,a.kt)("inlineCode",{parentName:"li"},"loadedModule.codeMirrorResources/codeMirrorOptions")," access kept ",(0,a.kt)("inlineCode",{parentName:"li"},"as any")," with updated reason \u2014 these properties are not on ",(0,a.kt)("inlineCode",{parentName:"li"},"ContentScriptModule"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Importer_EnexToHtml.ts")," \u2014 follow-up fix: ",(0,a.kt)("inlineCode",{parentName:"li"},"outputFormat: 'html'")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ImportModuleOutputFormat.Html")," (caused by ImportOptions tightening).")),(0,a.kt)("p",null,"Files ski
1pped entirely:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"database-driver.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"SelectResult = any"),' already tagged "Partial refactor"; out of scope.'),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"file-api-driver-local.ts"),' \u2014 already tagged "Partial refactor".'),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Importer_Md_frontmatter.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"parseRawYamlToFolderIcon"),' already tagged "The raw YAML output is untyped".'),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/e2ee/ppk/RSA.node.ts"),' \u2014 already tagged "Workaround for incorrect types".'),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/e2ee/types.ts"),' \u2014 already tagged "Partial refactor".'),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/commands/ToolbarButtonUtils.ts"),' \u2014 already tagged "WhenClauseContext can be partial in tests".')),(0,a.kt)("p",null,"Checkpoint 2 (2026-05-14): 1101 \u2192 1053 (48 removed across ~25 files)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinPlugins.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"require(_path): any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," (stub)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/utils/manifestFromObject.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(o: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; PluginService.validateManifest now casts on the caller side."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/utils/mapEventHandlersToIds.ts")," \u2014 0 removed, 1 left. Reason updated (recursive walker; tightening to ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," forces narrowing at every branch and recursive call)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/utils/validatePluginPlatforms.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"platforms: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; inner cast in call."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/profileConfig/index.ts")," \u2014 1 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"MigratingProfile"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"MigratingProfileConfig")," interfaces describing the v1\u2192v2 transition."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/rest/ApiResponse.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"body: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/rest/routes/auth.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"output: any")," \u2192 inline ",(0,a.kt)("inlineCode",{parentName:"li"},"{ status: AuthTokenStatus; token?: string }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/rest/routes/search.ts")," \u2014 1 removed, 0 left. Restructured to construct the options as a typed object literal; NotesForQueryOptions branch narrows the LoadOptions.fields union to string[]."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/rest/utils/defaultAction.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"getOneModel.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"LoadOptions"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/rest/utils/defaultLoadOptions.ts")," \u2014 1 removed, 0 left. Return \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"LoadOptions"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/rest/utils/defaultSaveOptions.ts")," \u2014 1 removed, 0 left. Introduced exported ",(0,a.kt)("inlineCode",{parentName:"li"},"DefaultSaveOptions { userSideValidation; isNew?; autoTimestamp? }"),"; callers set ",(0,a.kt)("inlineCode",{parentName:"li"},"autoTimestamp")," after construction."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/search/SearchFilter.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"let engine: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"SearchEngine"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/sortOrder/PerFolderSortOrderService.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"event: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ value: string }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/style/loadCssToTheme.ts")," \u2014 1 removed, 0 left. Removed ",(0,a.kt)("inlineCode",{parentName:"li"},"(f: any)")," annotation \u2014 readDirStats returns typed Stat[]."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/synchronizer/ItemUploader.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"preUploadedItems_: Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, { error?: { message?; code? } }>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/synchronizer/MigrationHandler.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"autoLockError: any")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"error: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | null"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/synchronizer/gui/useSyncTargetUpgrade.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"error: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | null"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/synchronizer/migrations/1.ts")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"2.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"api: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FileApi"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/synchronizer/utils/handleConflictAction.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"remoteContent/local: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseItemEntity"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/ipc/types.ts"),' \u2014 0 removed, 1 left. Reason updated (structural constraint can\'t express "args extend SerializableData[]" without index-signature errors).'),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/ipc/utils/mergeCallbacksAndSerializable.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"OnAfterCallbackCreated")," callback typed properly."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/ipc/utils/separateCallbacksFromSerializable.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"as any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as string[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"file-api-driver.test.ts")," \u2014 1 removed, 0 left. Removed ",(0,a.kt)("inlineCode",{parentName:"li"},"(f: any)")," from map; items typed already."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"file-api.test.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"syncContext: any")," \u2192 inferred from literal with ",(0,a.kt)("inlineCode",{parentName:"li"},"null as unknown")," for cache fields."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ArrayUtils.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"mergeOverlappingIntervals")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"[number, number][]"),"; one caller (",(0,a.kt)("inlineCode",{parentName:"li"},"GotoAnything.tsx"),") annotated its ",(0,a.kt)("inlineCode",{parentName:"li"},"indices")," accordingly."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"JoplinError.ts")," \u2014 2 removed, 0 left. Introduced exported ",(0,a.kt)("inlineCode",{parentName:"li"},"JoplinErrorCode = string | number | null"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ObjectUtils.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"output: any")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"sortByValue")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"convertValuesToFunctions")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, ...>")," with final cast to the typed return type."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"dom.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"isInsideContainer(node: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"EventTarget | Node | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"waitForElement")," made generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T extends HTMLElement>")," returning ",(0,a.kt)("inlineCode",{parentName:"li"},"T | null"),". One caller (",(0,a.kt)("inlineCode",{parentName:"li"},"useRootElement.ts"),") now uses the generic explicitly."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"errorUtils.ts")," \u2014 2 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"WrapErrorInput")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"WrappedError")," interfaces."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"net-utils.ts")," \u2014 2 removed, 0 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"TcpPortUsed { check(port): Promise<boolean> }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>")," for headers."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/utils/types.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"LoadOptions.whereParams: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(string|number|boolean)[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"SaveOptions.oldItem: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; added ",(0,a.kt)("inlineCode",{parentName:"li"},"SaveOptions.fields?: string[]")," (used by ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseModel.save")," and at least one renameTag caller)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Alarm.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"selectAll")," cast to ",(0,a.kt)("inlineCode",{parentName:"li"},"{ id: string }[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"makeNotification(alarm, note)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"AlarmEntity"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Tag.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"searchAllWithNotes(options: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"SearchOptions")," (new exported interface in ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseModel"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"save.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"SaveOptions"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/utils/readOnly.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Folder: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"typeof import('../Folder').default"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseItem: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"typeof import('../BaseItem').default"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/shared/config/config-shared.ts")," \u2014 1 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"updateSettingValue.value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),". The ",(0,a.kt)("inlineCode",{parentName:"li"},"setState")," field is left ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with a new reason \u2014 mirrors ",(0,a.kt)("inlineCode",{parentName:"li"},"React.Component.setState")," (",(0,a.kt)("inlineCode",{parentName:"li"},"Pick<S, K>"),"); narrowing breaks subclass ",(0,a.kt)("inlineCode",{parentName:"li"},"this")," assignment to the interface in app-mobile's class-based ConfigScreen."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/shared/config/plugins/useOnInstallHandler.ts")," \u2014 2 removed, 0 left. Both ",(0,a.kt)("inlineCode",{parentName:"li"},"setInstallingPluginIds((prev: any))")," callbacks rely on the ",(0,a.kt)("inlineCode",{parentName:"li"},"React.Dispatch<SetStateAction<...>>")," inferred type."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/shared/reduxSharedMiddleware.ts")," \u2014 1 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"sortNoteListTimeout: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof shim.setTimeout>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"store/_next")," typed (",(0,a.kt)("inlineCode",{parentName:"li"},"Store<State>"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"Dispatch"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"action: any")," kept with new reason explaining the heterogeneous action union."),(0,a.kt)("li",{parentName:"ul"},"New shared types: ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseModel.SearchOptions"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"JoplinError.JoplinErrorCode"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"models/NoteResource.AssociatedResourceNote"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/ViewController.PluginStore"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/Plugin.MessageListenerCallback"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"services/rest/utils/defaultSaveOptions.DefaultSaveOptions"),".")),(0,a.kt)("p",null,"Follow-up edits in other packages (caused by lib tightenings):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app-desktop/gui/NoteListItem/utils/useRootElement.ts")," \u2014 call ",(0,a.kt)("inlineCode",{parentName:"li"},"waitForElement<HTMLDivElement>(...)")," explicitly."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app-desktop/plugins/GotoAnything.tsx")," \u2014 annotated local ",(0,a.kt)("inlineCode",{parentName:"li"},"indices: [number, number][]"),".")),(0,a.kt)("p",null,"Checkpoint 3 (2026-05-14): 1053 \u2192 1004 (49 removed)."),(0,a.kt)("p",null,"Plugin-API files (mostly thanks to the new ",(0,a.kt)("inlineCode",{parentName:"p"},"PluginStore")," / ",(0,a.kt)("inlineCode",{parentName:"p"},"MessageListenerCallback")," aliases from checkpoint 1):"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinClipboard.ts")," \u2014 3 removed, 0 left. Local ",(0,a.kt)("inlineCode",{parentName:"li"},"ElectronClipboardLike")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"ElectronNativeImageLike")," interfaces (electron module not available in non-desktop packages)."),
1(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinViews.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"implementation")," now ",(0,a.kt)("inlineCode",{parentName:"li"},"BasePlatformImplementation.JoplinViews")," (the actual sub-object passed in); ",(0,a.kt)("inlineCode",{parentName:"li"},"store")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginStore"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinViewsDialogs.ts")," \u2014 3 removed, 0 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"ShowOpenDialogOptions")," in ",(0,a.kt)("inlineCode",{parentName:"li"},"BasePlatformImplementation"),"; tightened return to ",(0,a.kt)("inlineCode",{parentName:"li"},"string[] | null"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinViewsEditor.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"store")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginStore"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onMessage.callback: Function")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MessageListenerCallback"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"postMessage.message: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinViewsPanels.ts")," \u2014 3 removed, 0 left. Same pattern (",(0,a.kt)("inlineCode",{parentName:"li"},"PluginStore")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"MessageListenerCallback")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinViewsToolbarButtons.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"store")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginStore"),"; deprecation cast typed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinViewsMenus.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"store")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginStore"),"; deprecation casts typed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinViewsMenuItems.ts")," \u2014 4 removed, 0 left. Same."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinSettings.ts")," \u2014 4 removed, 0 left. All four setting-value returns/inputs \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinPlugins.ts")," \u2014 already in batch 2."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/Joplin.ts")," \u2014 follow-up: cast ",(0,a.kt)("inlineCode",{parentName:"li"},"implementation.clipboard/.nativeImage")," to the JoplinClipboard constructor parameter shapes."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/BasePlatformImplementation.ts")," \u2014 4 removed, 0 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"ShowOpenDialogOptions"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"clipboard"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"nativeImage"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"registerComponent")," returns/params \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/noteListType.ts")," \u2014 1 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"OnChangeEvent.value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"RenderNoteView")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"OnRenderNoteHandler.props")," kept ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with updated reasons (heterogeneous per-renderer shape).")),(0,a.kt)("p",null,"Top-level lib files:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"eventManager.ts")," \u2014 0 removed, 3 left. Reason updated on ",(0,a.kt)("inlineCode",{parentName:"li"},"filterEmit.object: any")," (filter objects vary per filter name). Two ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial refactor")," reasons already in scope; no change."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"hooks/useEventListener.ts")," \u2014 4 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"EventHandler = (event: Event) => void"),"; typed ",(0,a.kt)("inlineCode",{parentName:"li"},"element")," as ",(0,a.kt)("inlineCode",{parentName:"li"},"RefObject<EventTarget | null>")," (type-only import from react)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/AlarmService.ts")," \u2014 3 removed, 0 left. Introduced exported ",(0,a.kt)("inlineCode",{parentName:"li"},"AlarmServiceDriver")," interface; ",(0,a.kt)("inlineCode",{parentName:"li"},"updateNoteNotification.noteOrId")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity | string"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Alarm.ts")," \u2014 follow-up: ",(0,a.kt)("inlineCode",{parentName:"li"},"selectAll")," cast updated to ",(0,a.kt)("inlineCode",{parentName:"li"},"{ id: number }[]")," (alarm IDs are integers, unlike note IDs); ",(0,a.kt)("inlineCode",{parentName:"li"},"batchDelete")," call now casts the resulting ",(0,a.kt)("inlineCode",{parentName:"li"},"number[]")," (the function's signature accepts ",(0,a.kt)("inlineCode",{parentName:"li"},"string[]")," for note-style IDs)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/KvStore.ts")," \u2014 4 removed, 0 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"JoplinDatabase")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"MutexInterface")," imports for typed fields; ",(0,a.kt)("inlineCode",{parentName:"li"},"formatValues_")," callers cast the ",(0,a.kt)("inlineCode",{parentName:"li"},"Row[]")," results to ",(0,a.kt)("inlineCode",{parentName:"li"},"KvStoreKeyValue[]"),".")),(0,a.kt)("p",null,"Checkpoint 4 (2026-05-14): 1004 \u2192 977 (27 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"TaskQueue.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"TaskCallback"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"TaskResult.result"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"completeTask.result")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"HtmlToMd.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"turndownOpts: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"blankReplacement"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"replacement")," callbacks typed with ",(0,a.kt)("inlineCode",{parentName:"li"},"HTMLElement"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"InMemoryCache.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Record.value"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"value()"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"setValue()")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"SyncTargetOneDrive.ts")," \u2014 2 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"api_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"OneDriveApi"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"(a: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),". Left the inherited ",(0,a.kt)("inlineCode",{parentName:"li"},"db/options")," constructor params (BaseSyncTarget still uses ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," there)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"htmlUtils.ts")," \u2014 3 removed, 5 left (4 of the 5 are existing ",(0,a.kt)("inlineCode",{parentName:"li"},"ban-types")," Function disables and now-typed callbacks via new ",(0,a.kt)("inlineCode",{parentName:"li"},"ReplaceUrlCallback")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"ProcessImageTagCallback")," aliases). ",(0,a.kt)("inlineCode",{parentName:"li"},"attributesHtml.attr: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"headAndBodyHtml.doc: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Document"),". One test (",(0,a.kt)("inlineCode",{parentName:"li"},"htmlUtils2.test.ts"),") gets a typed cast. The ",(0,a.kt)("inlineCode",{parentName:"li"},"Function"),"-typed ",(0,a.kt)("inlineCode",{parentName:"li"},"processImageTags"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"replaceImageUrls"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"replaceEmbedUrls"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"replaceMediaUrls")," callbacks are now typed via new aliases \u2014 the ban-types disables go away with the explicit-any ones."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"downloadController.ts")," \u2014 3 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"DownloadRequest")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"DownloadChunk")," interfaces."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Exporter_Base.ts")," \u2014 3 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"prepareForProcessingItemType.itemsToExport: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseItemEntity[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"processItem.item: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseItemEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"processResource.resource: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"updateContext.context: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"object"),". The ",(0,a.kt)("inlineCode",{parentName:"li"},"context_")," field stays ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with updated reason \u2014 shape is exporter-specific (Html has ",(0,a.kt)("inlineCode",{parentName:"li"},"cssStrings/customAssets"),", Md has ",(0,a.kt)("inlineCode",{parentName:"li"},"noteTags/tagTitles"),") and indexed dynamically by subclasses."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Exporter_Jex.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"processItem"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"processResource")," now match the tightened base; ",(0,a.kt)("inlineCode",{parentName:"li"},"readDirStats.filter/map")," callbacks no longer need a cast."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Exporter_Html.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"style_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ThemeStyle"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"init.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ExportOptions"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"processItem.item: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity"),".")),(0,a.kt)("p",null,"Follow-up: ",(0,a.kt)("inlineCode",{parentName:"p"},"htmlUtils2.test.ts")," typed cast; ",(0,a.kt)("inlineCode",{parentName:"p"},"app-desktop/.../resourceHandling.ts")," doesn't need changes (return type of its ",(0,a.kt)("inlineCode",{parentName:"p"},"replaceImageUrls")," callback is ",(0,a.kt)("inlineCode",{parentName:"p"},"void"),", which ",(0,a.kt)("inlineCode",{parentName:"p"},"ReplaceUrlCallback")," now allows)."),(0,a.kt)("p",null,"Checkpoint 5 (2026-05-14): 977 \u2192 965 (12 removed across a handful of larger files)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/share/ShareService.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"formatShareInvitations.invitations: any[]")," \u2192 typed shape using ",(0,a.kt)("inlineCode",{parentName:"li"},"ShareInvitation"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"MasterKeyEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"store_: Store<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Store<unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"state")," getter narrows via ",(0,a.kt)("inlineCode",{parentName:"li"},"as Record<string, unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/ExternalEditWatcher.ts")," \u2014 5 removed, 3 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"DispatchFn"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"BridgeFn"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"eventEmitter_")," typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"EventEmitter")," (switched to ES import). ",(0,a.kt)("inlineCode",{parentName:"li"},"chokidar_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"watcher_")," stay ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with a single shared reason (chokidar typings vary across platforms; we use a small subset structurally). ",(0,a.kt)("inlineCode",{parentName:"li"},"on"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"off")," callbacks stay ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with reason (EventEmitter payloads vary per event name; per-event union would require touching every caller)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"theme.ts")," \u2014 2 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"cachedStyles_")," shape typed (",(0,a.kt)("inlineCode",{parentName:"li"},"themeId"),", indexed ",(0,a.kt)("inlineCode",{parentName:"li"},"styles")," record); ",(0,a.kt)("inlineCode",{parentName:"li"},"buildStyle.cacheKey: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string | (string | number)[]"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"BuildStyleCallback")," return stays ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," (heterogeneous: CSSProperties, styled-components objects, plain CSS strings)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/share/reducer.ts")," \u2014 2 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"parseShareCache.raw: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<State>"),". The reducer's ",(0,a.kt)("inlineCode",{parentName:"li"},"action: any")," keeps a reason about heterogeneous SHARE_* action shapes. ",(0,a.kt)("inlineCode",{parentName:"li"},"(draft.shareUsers as any)")," cast removed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/types.ts")," \u2014 2 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"ImportOptions.destinationFolder: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onError: (error: any)")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"onProgress")," stays ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with reason \u2014 Importer/Exporter share this options bag, export side passes ExportProgressState here."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/PluginService.ts")," \u2014 3 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"loadManifestToObject(path): Promise<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<Record<string, unknown>>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"plugin dispatch")," action typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"Plugin.PluginDispatchCallback"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"readDirStats")," filter/map untyped. The ",(0,a.kt)("inlineCode",{parentName:"li"},"store_")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"platformImplementation_")," fields stay ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with reason \u2014 test fixtures across app-cli/app-mobile pass partial shapes (",(0,a.kt)("inlineCode",{parentName:"li"},"{ joplin: {} }"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"{ dispatch, getState }"),") that the strict interfaces don't accept."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/Plugin.ts")," \u2014 2 removed, 0 left. Introduced exported ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginDispatchCallback"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch_"),"/constructor ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch")," parameter typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"eventEmitter_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"InstanceType<typeof EventEmitter>"),".")),(0,a.kt)("p",null,"Checkpoint 6 (2026-05-14): 965 \u2192 949 (16 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/rest/utils/collectionToPaginatedResults.ts")," \u2014 3 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"items")," callbacks and sort comparator typed; the outer ",(0,a.kt)("inlineCode",{parentName:"li"},"items: any[]")," stays with a new reason \u2014 callers pass entity types (NoteEntity, FolderEntity) without index signatures."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinImaging.ts")," \u2014 4 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"NativeImageLike")," interface (toPNG/toJPEG/resize/crop/getSize); ",(0,a.kt)("inlineCode",{parentName:"li"},"cacheImage")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"Image.data")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"toJpgResource"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"toPngResource.resourceProps")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<ResourceEntity>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"testing/syncTargetUtils.ts")," \u2014 4 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"TestDataNode")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"TestData")," types for the recursive test data structure."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"time.ts")," \u2014 5 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"formatLocalToMs"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"anythingToDateTime"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"anythingToMs"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"goBackInTime"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"goForwardInTime")," typed using ",(0,a.kt)("inlineCode",{parentName:"li"},"string | number | Date | { toDate }")," unions; added type-only ",(0,a.kt)("inlineCode",{parentName:"li"},"MomentTypes")," import for ",(0,a.kt)("inlineCode",{parentName:"li"},"unitOfTime")," namespace. ",(0,a.kt)("inlineCode",{parentName:"li"},"msleep")," switched from ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise((resolve: Function))")," to ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<void>(resolve => ...)")," (removes the ban-types disable too).")),(0,a.kt)("p",null,"Checkpoint 7 (2026-05-14): 949 \u2192 929 (20 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinWorkspace.ts")," \u2014 4 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"store")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginStore"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"onNoteChange")," wrapper event typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"selectedNote(): Promise<any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<NoteEntity | null>"),'. Two left (one is "No plugin-api-accessible Note type defined" reason already; one is the ',(0,a.kt)("inlineCode",{parentName:"li"},"Function")," ban-types in ",(0,a.kt)("inlineCode",{parentName:"li"},"onNoteSelectionChange"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/PostMessageService.ts")," \u2014 4 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"MessageResponse.response/.error")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"Message.content")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"sendResponse.responseContent")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"ViewMessageHandler")," left ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with updated reason \u2014 callers register handlers with concrete payload types (MessageResponse, SerializableData); making this generic would force changes at every dispatch site."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"locale.ts")," \u2014 5 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"supportedLocales_")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, Record<string, string[]>>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"localeStats_")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, Record<string, unknown>>")," (per-locale stats include pluralForms function); ",(0,a.kt)("inlineCode",{parentName:"li"},"_/_n/stringByLocale")," rest args \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),". Single inner cast ",(0,a.kt)("inlineCode",{parentName:"li"},"as ParsePluralFormFunction")," for the plural-forms field."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/reducer.ts")," \u2014 3 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"(view as any)")," casts on ",(0,a.kt)("inlineCode",{parentName:"li"},"PLUGIN_VIEW_PROP_SET"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"_PUSH")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Record<string, unknown[]>")," etc. The reducer's ",(0,a.kt)("inlineCode",{parentName:"li"},"action: any")," keeps a reason (heterogeneous PLUGIN_* action shapes). ",(0,a.kt)("inlineCode",{parentName:"li"},"viewsByType")," returns ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"any[]")," with reason (menu views have menuItems not on PluginViewState)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"JoplinDatabase.ts")," \u2014 4 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"TableField.default: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string | number | boolean | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"tableDescriptions_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, Record<string, string>>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"open.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"tableFields.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ includeDescription?: boolean }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"createDefaultRow.row: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"constructor(driver: any)")," kept with reason \u2014 base Database.driver is ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," across multiple driver implementations (sqlite/better-sqlite3/web).")),(0,a.kt)("p",null,"Checkpoint 8 (2026-05-14): 929 \u2192 886 (43 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/utils/paginatedFeed.ts")," \u2014 2 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"db: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"JoplinDatabase"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"WhereQuery.params")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(string|number|boolean)[]"),". The ",(0,a.kt)("inlineCode",{parentName:"li"},"items: any[]")," stays with new reason (callers receive Note/Folder/Resource entities without index signatures)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/settings/settingValidations.ts")," \u2014 2 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"validateSetting.oldValue/newValue"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"newValues")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),". The ",(0,a.kt)("inlineCode",{parentName:"li"},"ValidationHandler")," type alias keeps ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with a new reason \u2014 settings are heterogeneous; each validator narrows from this base."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/DecryptionWorker.ts")," \u2014 5 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"DecryptionWorkerStartOptions")," interface; ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatchReport.report: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch: Function")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(action: { type; ... })"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"on"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"off")," callbacks updated reasons (heterogeneous payloads by event name)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Folder.test.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"foldersById: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, FolderEntity & { note_count?: number }>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/search/SearchEngineUtils.test.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"searchEngine: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"SearchEngine"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NotesForQueryOptions"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/search/SearchEngine.test.ts")," \u2014 4 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"ExpectedTerms")," interface; helper ",(0,a.kt)("inlineCode",{parentName:"li"},"extractValue")," narrows ",(0,a.kt)("inlineCode",{parentName:"li"},"string | { value: string }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/share/ShareService.test.ts")," \u2014 5 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"extraExecHandlers")," callbacks typed; per-handler body casts to specific shapes; ",(0,a.kt)("inlineCode",{parentName:"li"},"Function")," ban-types disable goes away with the explicit-any ones."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/ExternalEditWatcher/utils.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"spawnCommand.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"SpawnOptions")," from ",(0,a.kt)("inlineCode",{parentName:"li"},"child_process"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"wrapError.error: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"subProcess.on('error')")," callback typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Error"),"; introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"ExternalBridge { openItem }")," interface."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Importer_Raw.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"itemIdMap/createdResources: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, ResourceEntity>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"folderExists.stats: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Stat[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"defaultFolder_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderEntity | null"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/ViewController.ts")," \u2014 2 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"emitMessage")," returns ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<unknown>"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"postMessage.message: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),". The other two disables (Store state heterogeneous; storeView shape varies) keep updated reasons."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/spellChecker/SpellCheckerService.ts")," \u2014 2 removed, 2 left. Removed ",(0,a.kt)("inlineCode",{parentName:"li"},"(a: any, b: any) => ...")," sort callbacks (already-typed array items work). Two stay with updated reasons (Electron MenuItemConstructorOptions union not imported in lib)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/WhenClause.ts")," \u2014 6 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"AdvancedExpression.subExpressions: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"evaluate"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"validate.context: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"object")," (matches existing callers that pass ",(0,a.kt)("inlineCode",{parentName:"li"},"WhenClauseContext"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"createContext.getValue")," uses generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T>")," to match ",(0,a.kt)("inlineCode",{parentName:"li"},"IContext.getValue<T>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinData.ts")," \u2014 6 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"api_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Api"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"serializeApiBody.body: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; route calls typed with ",(0,a.kt)("inlineCode",{parentName:"li"},"RequestMethod")," enum and ",(0,a.kt)("inlineCode",{parentName:"li"},"RequestFile[]"),".")),(0,a.kt)("p",null,"Checkpoint 9 (2026-05-14): 886 \u2192 829 (57 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/settings/types.ts")," \u2014 3 removed, 3 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"value: any")," keeps a new reason (settings heterogeneous, each consumer narrows); ",(0,a.kt)("inlineCode",{parentName:"li"},"options/show")," left ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with reasons (varying per setting/heterogeneous setting access). ",(0,a.kt)("inlineCode",{parentName:"li"},"unitLabel/filter")," left where parameters are contravariant per-setting."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/utils/executeSandboxCall.ts")," \u2014 4 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"EventHandler.args: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"; nested ",(0,a.kt)("inlineCode",{parentName:"li"},"args: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),". Recursive walker ",(0,a.kt)("inlineCode",{parentName:"li"},"arg")," and dotted-path ",(0,a.kt)("inlineCode",{parentName:"li"},"parent/fn")," left ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with new reasons (heterogeneous sandbox object shape)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Exporter_Custom.ts")," \u2014 5 removed, 1 left. Each ",(0,a.kt)("inlineCode",{parentName:"li"},"CustomImporter")," method typed: ",(0,a.kt)("inlineCode",{parentName:"li"},"context: ExportContext"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"item: BaseItemEntity"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"resource: ResourceEntity"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/debug/populateDatabase.ts")," \u2014 6 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"randomIndex/randomElement/randomElements")," made generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"db: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"JoplinDatabase & { clearForTesting }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"folder/note: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderEntity")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"database-driver-better-sqlite.ts")," \u2014 6 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"BetterSqliteDatabase")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"PreparedStatement")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"SqliteError")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"WrappedError")," / ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"SqlParams")," types."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"fs-driver-base.ts")," \u2014 5 removed, 3 left. Introduced exported ",(0,a.kt)("inlineCode",{parentName:"li"},"FileHandle = unknown")," (drivers use different concrete shapes) and ",(0,a.kt)("inlineCode",{parentName:"li"},"TarOptions { strict?, portable?, file, cwd }"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"appendFile/open/close/readFileChunk*")," typed. ",(0,a.kt)("inlineCode",{parentName:"li"},"ReadDirStatsOptions.recursive")," made optional. ",(0,a.kt)("inlineCode",{parentName:"li"},"readFile")," stays ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with reason \u2014 widening to ",(0,a.kt)("inlineCode",{parentName:"li"},"string|Buffer")," cascades broken call sites across many lib files."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"fs-driver-node.ts")," \u2014 9 removed, 0 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"FsError"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"WrappedFsError"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"fsErrorToJsError_"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"setTimestamp"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"readDirStats"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"open"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"close"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"readFileChunk"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"tarExtract"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"tarCreate")," typed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/AlarmServiceDriverNode.ts")," \u2014 7 removed, 0 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"StoredNotification")," (extends Notification with timeoutId); ",(0,a.kt)("inlineCode",{parentName:"li"},"notifications_/service_/setService")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"displayDefault/electron")," notification options typed with proper interface; ",(0,a.kt)("inlineCode",{parentName:"li"},"notifier.notify")," callback typed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/WebviewController.ts")," \u2014 6 removed, 3 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"LayoutItem")," for ",(0,a.kt)("inlineCode",{parentName:"li"},"findItemByKey"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"CloseResponse.resolve/reject")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"messageListener_/onMessage")," use ",(0,a.kt)("inlineCode",{parentName:"li"},"MessageListenerCallback"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"store")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"PluginStore"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"postMessage/setStoreProp")," value typed ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"registry.ts")," \u2014 9 removed, 2 left. Various private fields typed (",(0,a.kt)("inlineCode",{parentName:"li"},"scheduleSyncId_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"recurrentSyncId_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"db_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"showErrorMessageBoxHandler_"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"setShowErrorMessageBoxHandler"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"setDb"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"saveContextHandler")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"promiseResolve")," typed. ",(0,a.kt)("inlineCode",{parentName:"li"},"syncTargets_/scheduleSync.syncOptions")," keep ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with reasons (heterogeneous sync target API and Synchronizer.start options)."),(0,a.kt)("li",{parentName:"ul"},"Side fix: ",(0,a.kt)("inlineCode",{parentName:"li"},"app-cli/app/command-apidoc.ts")," \u2014 cast ",(0,a.kt)("inlineCode",{parentName:"li"},"tableFields")," to ",(0,a.kt)("inlineCode",{parentName:"li"},"MarkdownTableRow[]")," (now that ",(0,a.kt)("inlineCode",{parentName:"li"},"TableField")," no longer has an index signature compatible with MarkdownTableRow).")),(0,a.kt)("p",null,"Checkpoint 10 (2026-05-14): 829 \u2192 816 (13 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/UndoRedoService.ts")," \u2014 8 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"UndoQueue.inner_")," and methods \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"state/redoState/undoState/push.state/schedulePush.state")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch: Function")," removed (no usage). Two ",(0,a.kt)("inlineCode",{parentName:"li"},"on"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"off")," callbacks stay ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with reason (EventEmitter payloads vary). Follow-up in ",(0,a.kt)("inlineCode",{parentName:"li"},"app-mobile/.../Note.tsx")," casts the undo state to its concrete shape."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"JoplinServerApi.ts")," \u2014 5 removed, 3 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"connectionErrorMessage.error")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"requestToCurl_.options")," typed inline; ",(0,a.kt)("inlineCode",{parentName:"li"},"exec/exec_.query/headers")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"responseJson_")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),". Three stay with reasons \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"body")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"fetchOptions.body")," flow through ",(0,a.kt)("inlineCode",{parentName:"li"},"shim.fetch/fetchBlob/uploadBlob")," (FetchOptions) which type body as ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"hidePasswords")," accepts both stringified bodies and header records; ",(0,a.kt)("inlineCode",{parentName:"li"},"response")," is the shim/blob return."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/ResourceFetcher.ts")," \u2014 9 removed, 4 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch: Function")," typed via the action shape; ",(0,a.kt)("inlineCode",{parentName:"li"},"queue_/autoAddResourcesCalls_")," typed; timer IDs typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof shim.setTimeout>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"on"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"off")," reasons updated; the ",(0,a.kt)("inlineCode",{parentName:"li"},"as any")," cast on ",(0,a.kt)("inlineCode",{parentName:"li"},"notifyDisabledSyncItems")," callback replaced with a typed adapter. Four stay with reasons (",(0,a.kt)("inlineCode",{parentName:"li"},"fetchingItems_")," mixed bool/Entity; ",(0,a.kt)("inlineCode",{parentName:"li"},"fileApi_/setFileApi/constructor")," widened for test mocks).")),(0,a.kt)("p",null,"Checkpoint 11 (2026-05-14): 816 \u2192 805 (11 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/RevisionService.ts")," \u2014 7 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"changedSinceCollectionCache_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"maintenanceCalls_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"maintenanceTimer1_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"maintenanceTimer2_")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"noteMetadata_.md")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"output.type_")," cast uses ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity & { type_? }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"BaseSyncTarget.ts")," \u2014 8 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch: Function")," typed via action shape; ",(0,a.kt)("inlineCode",{parentName:"li"},"initState_/options_")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"option"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"unsupportedPlatforms"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"checkConfig")," typed. Two stay (",(0,a.kt)("inlineCode",{parentName:"li"},"db_/fileApi_/constructor.db/setFileApi.v/initFileApi"),") with reasons \u2014 sync target subclasses each pass concrete shapes (FileApi subclasses, FileApiOptions) s
1o tightening here forces every subclass to match.")),(0,a.kt)("p",null,"Checkpoint 12 (2026-05-14): 805 \u2192 789 (16 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Resource.ts")," \u2014 9 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"fsDriver_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FsDriverBase"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"fetchStatuses")," return \u2192 typed shape; ",(0,a.kt)("inlineCode",{parentName:"li"},"markupTag.resource")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceEntity & { alt? }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"localState"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"setLocalStateQueries"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"setLocalState.resourceOrId")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceEntity | string"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"itemCanBeEncrypted")," cast uses ",(0,a.kt)("inlineCode",{parentName:"li"},"Parameters<...>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"params: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(string|number)[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"resourceConflictFolder")," return type inferred."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Folder.ts")," \u2014 7 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"fieldsToLabels: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"tableNameToClasses: Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, typeof BaseItem>")," (2 places); ",(0,a.kt)("inlineCode",{parentName:"li"},"handleTitleNaturalSorting.options")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"allAsTree.options")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderLoadOptions & { includeNotes? }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"idToFolders.any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderEntityWithChildren"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"save.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"SaveOptions & {duplicateCheck?, reservedTitleCheck?, stripLeftSlashes?}"),".")),(0,a.kt)("p",null,"Checkpoint 13 (2026-05-14): 789 \u2192 777 (12 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"WebDavApi.ts")," \u2014 4 removed, 5 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"RequestInfo.options")," typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"FetchOptions & ..."),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"_requestToCurl.options")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"serializeRequest")," callback body uses ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),". Five remain with updated reasons (xml2js heterogeneous output, url-parse Url shape, JsonValue alias, fetchOptions/response are platform-specific shapes via shim)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"file-api.ts")," \u2014 8 removed, 5 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"RemoteItem.isDir")," added (used by list filter); ",(0,a.kt)("inlineCode",{parentName:"li"},"requestCanBeRepeated.error")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"tryAndRepeat")," made generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T>")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"Function"),"\u2192",(0,a.kt)("inlineCode",{parentName:"li"},"()=> T|Promise<T>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"list")," filter callbacks typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"put.content: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string | Buffer | null"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"multiPut.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ source? }"),"; introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"BasicDeltaContext")," and typed the helper; ",(0,a.kt)("inlineCode",{parentName:"li"},"getDirStatFn: Function")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(path) => ItemStat[]|Promise<ItemStat[]>"),"; sort/map callbacks typed. Five stay with reasons: ",(0,a.kt)("inlineCode",{parentName:"li"},"RemoteItem.jopItem"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"PaginatedList.context"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"driver_"),", constructor ",(0,a.kt)("inlineCode",{parentName:"li"},"driver"),", and the ",(0,a.kt)("inlineCode",{parentName:"li"},"output: any[]")," mixed array of ItemStat + deleted-items.")),(0,a.kt)("p",null,"Checkpoint 14 (2026-05-14): 777 \u2192 756 (21 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/ResourceEditWatcher/index.ts")," \u2014 10 removed, 3 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"logger_/dispatch")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"eventEmitter_")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"InstanceType<typeof EventEmitter>")," with proper ES import; ",(0,a.kt)("inlineCode",{parentName:"li"},"externalApi.openAndWatch/watch/stopWatching/isWatched")," callbacks typed ",(0,a.kt)("inlineCode",{parentName:"li"},"{ resourceId: string }"),"; watcher 'all'/'raw' event handlers typed. Three remain with reasons (chokidar typings vary across platforms; on/off heterogeneous events)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"file-api-driver-joplinServer.ts")," \u2014 11 removed, 0 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"metadataToStat_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"metadataToStats_")," arguments; introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"RemoteItem")," return type (added ",(0,a.kt)("inlineCode",{parentName:"li"},"id: ''")," to satisfy the interface); typed ",(0,a.kt)("inlineCode",{parentName:"li"},"delta"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"list"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"get"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"put"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"multiPut")," options via ",(0,a.kt)("inlineCode",{parentName:"li"},"ExecOptions")," from JoplinServerApi; typed ",(0,a.kt)("inlineCode",{parentName:"li"},"isRejectedBySyncTargetError"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"isReadyOnlyError.error"),"; typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Object.entries<...>")," response shape. Also caught a typo: ",(0,a.kt)("inlineCode",{parentName:"li"},"response.has_more")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"response.hasMore")," (the returned object actually exposes ",(0,a.kt)("inlineCode",{parentName:"li"},"hasMore"),").")),(0,a.kt)("p",null,"Checkpoint 15 (2026-05-14): 756 \u2192 732 (24 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ClipperServer.ts")," \u2014 11 removed, 2 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"ClipperDispatch")," alias for the dispatch field; ",(0,a.kt)("inlineCode",{parentName:"li"},"server_")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"http.Server & { destroy? }")," (server-destroy adds ",(0,a.kt)("inlineCode",{parentName:"li"},".destroy")," at runtime); all request/response handler callbacks typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"IncomingMessage"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"ServerResponse"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"writeCorsHeaders"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"writeResponseJson"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"writeResponseText"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"writeResponseInstance"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"writeResponse"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"execRequest")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"multiparty.Form.parse")," callback typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"request.on('data')")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Buffer | string"),". Two stay with reasons (",(0,a.kt)("inlineCode",{parentName:"li"},"actionApi")," shape varies, the Api ",(0,a.kt)("inlineCode",{parentName:"li"},"route")," method parameter cast)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"testing/test-utils.ts")," \u2014 13 removed, 2 left. Typed ",(0,a.kt)("inlineCode",{parentName:"li"},"switchClient"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"setupDatabase"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"setupDatabaseAndSynchronizer")," options bag; introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderTreeNode")," for ",(0,a.kt)("inlineCode",{parentName:"li"},"createFolderTree"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"objectsEqual")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"checkThrowAsync"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"expectThrow"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"expectNotThrow"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"checkThrow")," \u2192 function signatures; ",(0,a.kt)("inlineCode",{parentName:"li"},"id"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"ids"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"sortedIds")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ id?: string }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"at<T>")," made generic; ",(0,a.kt)("inlineCode",{parentName:"li"},"createNTestNotes.folder")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"middlewareCalls_: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"boolean[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"start.argv")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string[]"),". Two stay (",(0,a.kt)("inlineCode",{parentName:"li"},"synchronizerStart.extraOptions")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"generalMiddleware")," \u2014 Synchronizer.start signature and BaseApplication.generalMiddleware override force ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),").")),(0,a.kt)("p",null,"Checkpoint 16 (2026-05-14): 732 \u2192 700 (32 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"file-api-driver-memory.ts")," \u2014 6 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"MemoryItem")," interface for ",(0,a.kt)("inlineCode",{parentName:"li"},"items_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"deletedItems_"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"encodeContent_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"decodeContent_")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"string | Buffer")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"setTimestamp")," return ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<void>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"get"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"put"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"multiPut"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"delta")," options typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"GetOptions"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"PutOptions"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"DeltaOptions"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"multiPut.output")," typed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"eventManager.ts")," \u2014 4 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"AppStateChangeCallback")," made generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"FilterHandler")," made generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T>")," (matches plugin api/types ",(0,a.kt)("inlineCode",{parentName:"li"},"FilterHandler<T>"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"filterEmit"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"filterOn"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"filterOff"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"appStateOn"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"appStateOff")," all generic with internal ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"-cast for storage; ",(0,a.kt)("inlineCode",{parentName:"li"},"stateValue_")," uses ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," instead of ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"markdownUtils.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"prependBaseUrl")," replace callback ",(0,a.kt)("inlineCode",{parentName:"li"},"_match: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/focusHandler.ts")," \u2014 2 removed, 0 left. Adopted ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," for ",(0,a.kt)("inlineCode",{parentName:"li"},"element")," arg with a ",(0,a.kt)("inlineCode",{parentName:"li"},"MaybeFocusable")," cast inside ",(0,a.kt)("inlineCode",{parentName:"li"},"toggleFocus")," so the runtime ",(0,a.kt)("inlineCode",{parentName:"li"},"typeof")," check narrows the call. Many call sites pass things like ",(0,a.kt)("inlineCode",{parentName:"li"},"Element"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"EventTarget"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"EditorView")," that have only ",(0,a.kt)("inlineCode",{parentName:"li"},"focus"),", so any typed interface would have rejected them."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/joplinCloud/index.ts")," \u2014 2 removed, 0 left. Extended ",(0,a.kt)("inlineCode",{parentName:"li"},"PlanFeature")," with missing ",(0,a.kt)("inlineCode",{parentName:"li"},"basicInfo/proInfo/teamsInfo/joplinServerBusinessInfo*")," keys (used at call sites but undeclared); ",(0,a.kt)("inlineCode",{parentName:"li"},"getFeatureLabel"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"getCellInfo")," use ",(0,a.kt)("inlineCode",{parentName:"li"},"keyof PlanFeature")," indexing with ",(0,a.kt)("inlineCode",{parentName:"li"},"typeof v === 'string'")," guards."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/frontMatter.ts")," \u2014 3 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"toLowerCase")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"parse")," added local ",(0,a.kt)("inlineCode",{parentName:"li"},"asString"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"asNumber")," coercion helpers since ",(0,a.kt)("inlineCode",{parentName:"li"},"yaml.load")," returns ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"-shaped values; ",(0,a.kt)("inlineCode",{parentName:"li"},"'tags' in md")," check now also requires ",(0,a.kt)("inlineCode",{parentName:"li"},"Array.isArray")," before assigning."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/ipc/RemoteMessenger.ts")," \u2014 9 removed, 0 left. Replaced ambient ",(0,a.kt)("inlineCode",{parentName:"li"},"FinalizationRegistry")," constructor/register ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"(id: string)=> void")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"object"),"; Proxy ",(0,a.kt)("inlineCode",{parentName:"li"},"get")," returns ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"canRemoteAccessProperty.parentObject"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"trackCallbackFinalization.callback"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"methodFromPath")," parent/current/stack typed ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," with narrowing ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," casts where indexing is required."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"file-api-driver-local.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"fsErrorToJsError_.output")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Error & { code?: JoplinError['code'] }")," instead of ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),"
1."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"SyncTargetOneDrive.ts")," \u2014 1 removed, 0 left. Constructor ",(0,a.kt)("inlineCode",{parentName:"li"},"options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," (matches BaseSyncTarget); ",(0,a.kt)("inlineCode",{parentName:"li"},"db: any")," keeps reason via ",(0,a.kt)("inlineCode",{parentName:"li"},"// eslint-disable-next-line")," referencing BaseSyncTarget."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"file-api.ts")," \u2014 1 removed, 0 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"ListOptions")," interface ({ includeHidden?, includeDirs?, syncItemsOnly?, context? }); ",(0,a.kt)("inlineCode",{parentName:"li"},"FileApi.list.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ListOptions"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"database-driver.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"SelectResult = any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," with a comment explaining narrowing happens at the model layer."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"database.ts")," \u2014 1 removed, 8 left with updated reasons. Tried widening ",(0,a.kt)("inlineCode",{parentName:"li"},"Row"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"selectAllFields"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"open"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"insertQuery"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"updateQuery"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"formatValue")," to ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," but each cascaded into many downstream errors across ",(0,a.kt)("inlineCode",{parentName:"li"},"JoplinDatabase"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"models/*"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"services/KvStore"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"services/RevisionService"),", etc. (typically requiring index-signature errors, or explicit narrowing for already-extant column accesses). Reverted to ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with descriptive reasons. The one removed was ",(0,a.kt)("inlineCode",{parentName:"li"},"enumId")," using ",(0,a.kt)("inlineCode",{parentName:"li"},"(this as unknown as Record<string, number>)")," for the dynamic ",(0,a.kt)("inlineCode",{parentName:"li"},"TYPE_*")," lookup. ",(0,a.kt)("inlineCode",{parentName:"li"},"wrapQueries"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"wrapQuery")," were already widened safely (",(0,a.kt)("inlineCode",{parentName:"li"},"(string | SqlQuery | [string, SqlParams?])[]"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/synchronizer/syncInfoUtils.ts")," \u2014 9 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"masterKeys"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"masterKeyMap")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"MasterKeyEntity[]"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, MasterKeyEntity>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"fetchSyncInfo.output: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ version: number; [k: string]: unknown }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"toObject")," return type inferred; ",(0,a.kt)("inlineCode",{parentName:"li"},"setWithTimestamp"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"keyTimestamp"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"setKeyTimestamp")," all use ",(0,a.kt)("inlineCode",{parentName:"li"},"(this as unknown as Record<...>)")," casts. The ",(0,a.kt)("inlineCode",{parentName:"li"},"load.s: any")," stays \u2014 JSON parse output varies per sync target version and is validated per-field via ",(0,a.kt)("inlineCode",{parentName:"li"},"'x' in s")," checks below.")),(0,a.kt)("p",null,"Checkpoint 17 (2026-05-14): 700 \u2192 681 (19 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/CommandService.ts")," \u2014 5 removed, 7 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"CommandContext.dispatch: Function")," kept (acts as a variance escape hatch \u2014 desktop runtimes type dispatch more strictly via ",(0,a.kt)("inlineCode",{parentName:"li"},"DesktopCommandContext"),"). ",(0,a.kt)("inlineCode",{parentName:"li"},"ReduxStore")," simplified to ",(0,a.kt)("inlineCode",{parentName:"li"},"type ReduxStore = any")," with a reason \u2014 tests and platforms pass partials and add subscribe etc. ",(0,a.kt)("inlineCode",{parentName:"li"},"scheduleExecute.args: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"componentUnregisterCommands.commands")," kept ",(0,a.kt)("inlineCode",{parentName:"li"},"ComponentCommandSpec<any>")," with updated reason. ",(0,a.kt)("inlineCode",{parentName:"li"},"CommandRuntime.execute")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"Api.execute")," kept ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with updated reasons (per-command/per-route shapes). ",(0,a.kt)("inlineCode",{parentName:"li"},"createContext.dispatch.action")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/rest/Api.ts")," \u2014 7 removed, 5 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Request.params: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"Request.action?: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"RequestContext.dispatch: Function")," \u2192 typed dispatch. ",(0,a.kt)("inlineCode",{parentName:"li"},"RouteFunction")," reason updated. ",(0,a.kt)("inlineCode",{parentName:"li"},"Api.token_: string | Function")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string | (()=> string)"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"knownNounces_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch_: Function")," \u2192 typed dispatch. Constructor and private ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch")," typed. ",(0,a.kt)("inlineCode",{parentName:"li"},"actionApi_")," stays ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with reason. ",(0,a.kt)("inlineCode",{parentName:"li"},"execServiceActionFromRequest_.externalApi: any")," \u2192 typed. ",(0,a.kt)("inlineCode",{parentName:"li"},"Request.body"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"bodyJson_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"bodyJson"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"Api.route")," keep ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with route-specific reasons."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService.ts")," \u2014 4 removed, 2 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"eventEmitter_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"EventEmitter")," (changed ",(0,a.kt)("inlineCode",{parentName:"li"},"require")," \u2192 ES ",(0,a.kt)("inlineCode",{parentName:"li"},"import { EventEmitter } from 'events'"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"on/off.callback: Function")," \u2192 typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"context: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ resourcePaths; destResourcePaths?; notePaths? }"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"normalizeItemForExport")," made generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T extends Record<string, unknown>>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"override: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<{ is_shared; share_id }>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"itemsToExport: any[]"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"queueExportItem.itemOrId: any")," kept ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with updated reasons (mirror exporter signatures across all subclasses; structural { type, itemOrId })."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Exporter_Md.ts")," \u2014 5 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"makeDirPath_.item")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity | FolderEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"replaceLinkedItemIdsByRelativePaths_.item")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"replaceItemIdsByRelativePaths_.paths/fn_createRelativePath")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"prepareForProcessingItemType")," context inner type narrowed; ",(0,a.kt)("inlineCode",{parentName:"li"},"processItem.item")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity | FolderEntity"),". The outer ",(0,a.kt)("inlineCode",{parentName:"li"},"prepareForProcessingItemType.itemsToExport: any[]")," stays with reason matching InteropService.")),(0,a.kt)("p",null,"Checkpoint 18 (2026-05-14): 681 \u2192 620 (61 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Exporter_Md.test.ts")," \u2014 21 removed, 0 left. The same ",(0,a.kt)("inlineCode",{parentName:"li"},"itemsToExport: any[]")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"queueExportItem")," boilerplate appeared 10 times; replaced all with ",(0,a.kt)("inlineCode",{parentName:"li"},"const { items: itemsToExport, queue: queueExportItem } = createExportItems();")," (the helper already existed at the top of the file). One inline ",(0,a.kt)("inlineCode",{parentName:"li"},"context: any")," \u2192 typed shape. Resource.load call sites cast ",(0,a.kt)("inlineCode",{parentName:"li"},"itemOrId as string"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService.test.ts")," \u2014 11 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"fieldsEqual")," made generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T extends object>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"Item.object: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; export callback signatures typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseItemEntity"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"Folder.all")," result typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"result: any")," typed inline; ",(0,a.kt)("inlineCode",{parentName:"li"},"format: 'testing' as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as ExportModuleOutputFormat"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/synchronizer/synchronizer_MigrationHandler.test.ts")," \u2014 10 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"MigrationTests.[key]: Function")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"()=> Promise<void>"),"; the 10 ",(0,a.kt)("inlineCode",{parentName:"li"},"items.filter((i: any) => ...)")," callbacks rely on RemoteItem inference now."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/synchronizer/ItemUploader.test.ts")," \u2014 6 removed, 0 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"MultiPutItem")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"MultiPutResult")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"ItemBodyCallback")," aliases; ",(0,a.kt)("inlineCode",{parentName:"li"},"ApiCall.args: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"clearArray")," made generic; ",(0,a.kt)("inlineCode",{parentName:"li"},"newFakeApi"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"newFakeApiCall")," typed; the ",(0,a.kt)("inlineCode",{parentName:"li"},"args[0].length")," accesses now cast via ",(0,a.kt)("inlineCode",{parentName:"li"},"MultiPutItem[]"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/rest/routes/notes.ts")," \u2014 13 removed, 0 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"Stylesheet"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"ImageSize"),", exported ",(0,a.kt)("inlineCode",{parentName:"li"},"ImageSizes"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"htmlToMdParser_")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"HtmlToMd"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"RequestNote.id: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"anchor_names: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string[]"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"stylesheets: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Stylesheet[]"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"image_sizes")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ImageSizes"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"requestNoteToNote.output: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"tryToGuessExtFromMimeType.response: any")," \u2192 headers shape. ",(0,a.kt)("inlineCode",{parentName:"li"},"replaceUrlsByResources.imageSizes")," typed; the replace callback ",(0,a.kt)("inlineCode",{parentName:"li"},"_match: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"attachImageFromDataUrl.note: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"cropRect: any")," typed. ",(0,a.kt)("inlineCode",{parentName:"li"},"extractNoteFromHTML.imageSizes")," typed.")),(0,a.kt)("p",null,"Checkpoint 19 (2026-05-14): 620 \u2192 574 (46 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/settings/builtInMetadata.ts")," \u2014 28 removed, 0 left. The 20 ",(0,a.kt)("inlineCode",{parentName:"li"},"show: (settings: any)")," callbacks all inherit the type from ",(0,a.kt)("inlineCode",{parentName:"li"},"SettingItem.show?(settings: any)"),"; dropping the explicit annotation removes the disable comments while keeping the interface as-is. ",(0,a.kt)("inlineCode",{parentName:"li"},"themeOptions")," / multiple ",(0,a.kt)("inlineCode",{parentName:"li"},"options()")," callbacks ",(0,a.kt)("inlineCode",{parentName:"li"},": any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string|number, string>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"filter: (value: any)")," \u2192 infers from interface; ",(0,a.kt)("inlineCode",{parentName:"li"},"'notes.sharedSortOrder'")," value cast to ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),". Side fix: ",(0,a.kt)("inlineCode",{parentName:"li"},"services/sortOrder/PerFolderSortOrderService.ts")," widens the read-back to ",(0,a.kt)("inlineCode",{parentName:"li"},"{ field?: string; reverse?: boolean } & Record<...>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"}
1,"Synchronizer.ts")," \u2014 18 removed, 4 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"ProgressReport")," interface (",(0,a.kt)("inlineCode",{parentName:"li"},"errors"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"state?"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"startTime?"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"completedTime?"),", counter index signature) typed across ",(0,a.kt)("inlineCode",{parentName:"li"},"progressReport_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"reportHasErrors"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"completionTime"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"reportToLines"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"logSyncSummary"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"isCannotSyncError.error: any")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"downloadQueue_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"TaskQueue")," (constructor now passes logger via TaskQueue's second arg instead of mutating a private field); ",(0,a.kt)("inlineCode",{parentName:"li"},"setEncryptionService.v: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"EncryptionService"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"logSyncOperation.local")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"{ id?, path?, type_? }"),". Several lambda callbacks typed: ",(0,a.kt)("inlineCode",{parentName:"li"},"startAutoLockRefresh.error: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Error"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"result.items.filter((it: any))")," infers from itemsThatNeedSync. ",(0,a.kt)("inlineCode",{parentName:"li"},"local = resource as any")," \u2192 cast through ",(0,a.kt)("inlineCode",{parentName:"li"},"typeof local"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"(action: any) => dispatch(action)")," typings dropped (infer). Four stay with reasons: ",(0,a.kt)("inlineCode",{parentName:"li"},"apiCall")," dispatch by name (FileApi heterogeneous methods), ",(0,a.kt)("inlineCode",{parentName:"li"},"start.options: any")," (caller bag), ",(0,a.kt)("inlineCode",{parentName:"li"},"handleCannotSyncItem.item: any")," (BaseItem.saveSyncDisabled), and the BaseItem.save ",(0,a.kt)("inlineCode",{parentName:"li"},"options")," bag during DELTA. Side fix: ",(0,a.kt)("inlineCode",{parentName:"li"},"cancel()")," now uses ",(0,a.kt)("inlineCode",{parentName:"li"},"void this.downloadQueue_.stop()")," (was already an awaitable promise but unmarked).")),(0,a.kt)("p",null,"Checkpoint 20 (2026-05-14): 574 \u2192 539 (35 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Setting.ts")," \u2014 17 removed, 7 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"appType: 'SET_ME' as any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"as AppType"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"saveTimeoutId_/changeEventTimeoutId_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof shim.setTimeout>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"rows.map((r: any))")," typed inline; ",(0,a.kt)("inlineCode",{parentName:"li"},"toPlainObject.keyToValues: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"incValue.inc: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"number"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"setArrayValue.settingValue: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"objectValue/setObjectValue.value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"enumOptionLabel/isAllowedEnumOption.value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"subValues.output: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"groupMetadatasBySections.{generalSection,nameToSections}: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"SettingMetadataSection"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, SettingMetadataSection>"),". The 7 that stay (with reasons): ",(0,a.kt)("inlineCode",{parentName:"li"},"SettingValueType")," fallback, ",(0,a.kt)("inlineCode",{parentName:"li"},"CacheItem.value"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"keychainService_")," and its setter (concrete class in app-desktop/app-mobile), ",(0,a.kt)("inlineCode",{parentName:"li"},"valueToString"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"formatValue")," (heterogeneous values per setting type), and the ",(0,a.kt)("inlineCode",{parentName:"li"},"constants_")," lookup in ",(0,a.kt)("inlineCode",{parentName:"li"},"value()"),". Side fix: ",(0,a.kt)("inlineCode",{parentName:"li"},"markupLanguageUtils.ts")," now coerces with ",(0,a.kt)("inlineCode",{parentName:"li"},"!!")," for ",(0,a.kt)("inlineCode",{parentName:"li"},"pluginOptions.enabled"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Note.ts")," \u2014 11 removed, 13 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"PreviewsOptions.conditionsParams: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(string|number|boolean)[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"geolocationCache_/dueDateObjects_: any")," \u2192 typed shapes. ",(0,a.kt)("inlineCode",{parentName:"li"},"linkedItemIds.links")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"{ itemId: string }[]"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"replaceResource{Internal,External}ToInternalLinks.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ useAbsolutePaths? }"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"sortNotes.orders: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ by: string; dir: string }[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"noteFieldComp")," made generic; sort prop access typed ",(0,a.kt)("inlineCode",{parentName:"li"},"string|number|boolean"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"previewFields.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ includeTimestamps? }"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"loadFolderNoteByField.value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string|number|boolean"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"preview.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ fields?: string|string[]; excludeConflicts? }"),". Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"DuplicateOptions")," for ",(0,a.kt)("inlineCode",{parentName:"li"},"duplicateMultipleNotes"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"duplicate"),". The 13 that stay are mostly around the dynamic ",(0,a.kt)("inlineCode",{parentName:"li"},"(newNote as any)[field]")," patterns retained as ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," casts and ",(0,a.kt)("inlineCode",{parentName:"li"},"search.options")," forwarding to BaseItem.search. Side fixes: ",(0,a.kt)("inlineCode",{parentName:"li"},"models/Note.test.ts")," testCases typed ",(0,a.kt)("inlineCode",{parentName:"li"},"[boolean, string, string][]"),".")),(0,a.kt)("p",null,"Checkpoint 21 (2026-05-14): 539 \u2192 506 (33 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"shim.ts")," \u2014 11 removed, 25 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"msleep_")," resolver typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Promise<void>")," (no Function). ",(0,a.kt)("inlineCode",{parentName:"li"},"isElectron")," window/process casts use structural types instead of ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"fetchRequestCanBeRetried.error: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ code?, message? }"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"fetchText.options")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FetchOptions"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"fetchBlob/uploadBlob/imageFromDataUrl")," keep ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with descriptive reasons. Throwing stub methods now have concrete return types where unambiguou
1s (",(0,a.kt)("inlineCode",{parentName:"li"},"stringByteLength: number"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"appVersion: string"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"pathRelativeToCwd: string"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"writeImageToFile.format: string"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"setReact/setReactDom")," typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"typeof React"),"). Several stay ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," for genuine cross-platform polymorphism: ",(0,a.kt)("inlineCode",{parentName:"li"},"Geolocation"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"electronBridge_"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"fsDriver_"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"httpAgent_"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"proxyAgent"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"nodeSqlite_"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"sjclModule"),", the node datagram module, ",(0,a.kt)("inlineCode",{parentName:"li"},"requireDynamic"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"fetchWithRetry.fetchFn"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"setTimeout/setInterval")," return types, ",(0,a.kt)("inlineCode",{parentName:"li"},"openUrl")," (boolean vs Promise), ",(0,a.kt)("inlineCode",{parentName:"li"},"readLocalFileBase64")," (string vs Promise)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"BaseApplication.ts")," \u2014 10 removed, 9 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"eventEmitter_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"EventEmitter")," (changed ",(0,a.kt)("inlineCode",{parentName:"li"},"require")," \u2192 ES ",(0,a.kt)("inlineCode",{parentName:"li"},"import"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"scheduleAutoAddResourcesIID_")," typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof shim.setTimeout>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"currentFolder_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderEntity"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"on(callback: Function)")," \u2192 typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"switchCurrentFolder.folder")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"FolderEntity"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"refreshNotes.state: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"State")," (with ",(0,a.kt)("inlineCode",{parentName:"li"},"parentType: string|number")," to allow reassign to ModelType numeric); ",(0,a.kt)("inlineCode",{parentName:"li"},"resourceFetcher_downloadComplete.event")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"reducerActionToString.action")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"{ type; [k]: unknown }"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"applySettingsSideEffects.action"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"sideEffects")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"readFlagsFromFile.flags: any")," replaced with ",(0,a.kt)("inlineCode",{parentName:"li"},"flagArgs: string[]"),". The 9 that stay are around the redux middleware (",(0,a.kt)("inlineCode",{parentName:"li"},"generalMiddleware"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"generalMiddlewareFn"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"reducer"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"initRedux"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"start"),") where per-app state and action unions diverge, plus the refreshFolders dispatch wrapper."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"onedrive-api.ts")," \u2014 12 removed, 7 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"OneDriveAuth")," interface and ",(0,a.kt)("inlineCode",{parentName:"li"},"ListenerCallback")," type. ",(0,a.kt)("inlineCode",{parentName:"li"},"auth_/setAuth/auth()")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"accountProperties_")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"listeners_: Record<string, ListenerCallback[]>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch.param/setAccountProperties")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"oneDriveErrorResponseToError.errorResponse")," typed (return still ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," since downstream augments with ",(0,a.kt)("inlineCode",{parentName:"li"},"request"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"headers"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"body")," fields); ",(0,a.kt)("inlineCode",{parentName:"li"},"execTokenRequest.body/refreshAccessToken.body")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"authorizationTokenRemoved.data")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," with ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," inner cast. The 7 remaining (",(0,a.kt)("inlineCode",{parentName:"li"},"uploadChunk"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"uploadBigFile"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"exec"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"execJson"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"execText"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"handleRequestRepeat.error"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"oneDriveErrorResponseToError")," return) cover FetchOptions/handle/buffer bags and network error augmentation.")),(0,a.kt)("p",null,"Checkpoint 22 (2026-05-14): 506 \u2192 477 (29 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/e2ee/EncryptionService.ts")," \u2014 12 removed, 13 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"EncryptionCustomHandler<Context = any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"<Context = unknown>"),". ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"EncryptOptions.onProgress: Function")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"(event: { doneSize: number })=> void"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"activeMasterKeyId")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"loadedMasterKey")," error throws now use ",(0,a.kt)("inlineCode",{parentName:"li"},"Error & { code; masterKeyId? }")," casts instead of ",(0,a.kt)("inlineCode",{parentName:"li"},"any"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"wrapSjclError.sjclError")," typed. ",(0,a.kt)("inlineCode",{parentName:"li"},"randomHexString"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"generateMasterKeyContent_")," cast ",(0,a.kt)("inlineCode",{parentName:"li"},"shim.randomBytes")," to ",(0,a.kt)("inlineCode",{parentName:"li"},"number[]")," at use site. ",(0,a.kt)("inlineCode",{parentName:"li"},"stringWriter_")," typed inline; ",(0,a.kt)("inlineCode",{parentName:"li"},"fileReader_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"fileWriter_")," encoding params \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"encryptString"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"decryptString")," plain/cipher text \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"headerTemplate")," indexes via ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<number, { fields: (string|number)[][] }>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"encodeHeader_")," parameter typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"decodeHeaderString.cipherText")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"decodeHeaderBytes_.output")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string|number>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"itemIsEncrypted.item")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"{ encryption_applied?, encryption_cipher_text?, type_? }"),". The 13 that stay (with reasons) are ",(0,a.kt)("inlineCode",{parentName:"li"},"fsDriver_"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"encryptAbstract_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"decryptAbstract_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"decodeHeaderSource_")," source/destination (duck-typed reader/writer union), and a handful of polymorphic API surface bits."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/types.ts")," \u2014 8 removed, 16 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Command.execute")," reason updated. ",(0,a.kt)("inlineCode",{parentName:"li"},"ExportModule.onProcessItem/onProcessResource")," reasons updated. ",(0,a.kt)("inlineCode",{parentName:"li"},"KeymapItem.userData/ImportContext.options/Script.onStart")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"MenuItem.commandArgs: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown[]"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"FormValue.value/DialogResult.formData")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"SettingItem.options")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string|number, string>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"ContentScriptModuleLoadedEvent.userData")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),". The 16 staying are all plugin API surface tied to external libraries (markdown-it, CodeMirror 6) where the concrete types aren't imported in lib. Side fix: ",(0,a.kt)("inlineCode",{parentName:"li"},"app-mobile/components/plugins/dialogs/PluginDialogWebView.tsx")," casts ",(0,a.kt)("inlineCode",{parentName:"li"},"formData")," from ",(0,a.kt)("inlineCode",{parentName:"li"},"SerializableData")," to ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," at the call site.")),(0,a.kt)("p",null,"Checkpoint 23 (2026-05-14): 477 \u2192 433 (44 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"reducer.ts")," \u2014 33 removed, 14 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"AdditionalReducer")," (kept as a 3-",(0,a.kt)("inlineCode",{parentName:"li"},"any")," interface \u2014 reducers from plugin/share services are immer-based with Draft mutation and per-sub-state shapes) and ",(0,a.kt)("inlineCode",{parentName:"li"},"SearchEntry")," for ",(0,a.kt)("inlineCode",{parentName:"li"},"State.searches"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"StateLastSelectedNotesIds.{Folder,Tag,Search}: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string[]>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"StateDecryptionWorker.decryptedItemCounts")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, number>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"State.masterKeys: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"MasterKeyEntity[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"pluginsLegacy/syncReport/screens")," typed. ",(0,a.kt)("inlineCode",{parentName:"li"},"derivedStateCache_")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"cacheEnabledOutput")," made generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T>"),". Selectors and ",(0,a.kt)("inlineCode",{parentName:"li"},"selectArrayShallow")," typed. ",(0,a.kt)("inlineCode",{parentName:"li"},"StateUtils.{selectArrayShallow,notesOrder,foldersOrder,lastSelectedNoteIds}")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"arrayHasEncryptedItems")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ encryption_applied? }[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"removeAdjacentDuplicates")," made generic. ",(0,a.kt)("inlineCode",{parentName:"li"},"(windowDraft as any)[k]")," patterns replaced with ",(0,a.kt)("inlineCode",{parentName:"li"},"(windowDraft as unknown as Record<string, unknown>)[k]"),". Helpers ",(0,a.kt)("inlineCode",{parentName:"li"},"updateOneItem"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"handleHistory"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"getContextFromHistory"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"removeItemFromArray"),", the top-level ",(0,a.kt)("inlineCode",{parentName:"li"},"reducer")," body keep ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with descriptive reasons matching the redux-action-union discrimination pattern. Side fixes: ",(0,a.kt)("inlineCode",{parentName:"li"},"PLUGINLEGACY_DIALOG_SET")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"DECRYPTION_WORKER_SET")," reducer cases use typed intermediates."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/BaseItem.ts")," \u2014 11 removed, 20 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"ItemsThatNeedDecryptionResult.items: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseItemEntity[]"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"isSystemPath")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"pathToId")," use local ",(0,a.kt)("inlineCode",{parentName:"li"},"const"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"split")," chains instead of mutating an ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," variable; ",(0,a.kt)("inlineCode",{parentName:"li"},"loadItemByField.value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string|number|boolean"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"syncItemClassNames"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"syncItemTypes")," map callbacks typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"encrypt")," error and ",(0,a.kt)("inlineCode",{parentName:"li"},"reducedItem")," casts now go through structural types; ",(0,a.kt)("inlineCode",{parentName:"li"},"decrypt"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"serialize"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"unserialize"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"serialize_format"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"unserialize_format")," kept ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with descriptive reasons for their unavoidably heterogeneous parameters. ",(0,a.kt)("inlineCode",{parentName:"li"},"updateSyncTimeQueries"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"saveSyncTime")," kept ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," because tests pass loose objects with ",(0,a.kt)("inlineCode",{parentName:"li"},"id")," as number.")),(0,a.kt)("p",null,"Checkpoint 24 (2026-05-14): 433 \u2192 411 (22 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"BaseModel.ts")," \u2014 22 removed, 19 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"typeEnum_: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"[string, ModelType][]"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"saveMutexes_")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, { acquire }>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"setDb.db: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"JoplinDatabase"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"defaultValues.output: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"applySqlOptions.params/all.params")," typed as primitive arrays; ",(0,a.kt)("inlineCode",{parentName:"li"},"allIds.rows.map")," typed inline. ",(0,a.kt)("inlineCode",{parentName:"li"},"count.options/loadByField.fieldValue/loadByFields.fields/loadByTitle.fieldValue/fieldType.defaultValue/releaseSaveMutex.release/saveMutex.modelOrId")," all typed concretely. ",(0,a.kt)("inlineCode",{parentName:"li"},"saveQuery.temp/filtered: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"userSideValidation.o")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"{ id?, user_updated_time?, user_created_time? }"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"count.then")," callback typed. Several stay ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with descriptive reasons: ",(0,a.kt)("inlineCode",{parentName:"li"},"addModelMd"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"byId"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"modelIndexById")," (subclass overrides return per-entity types so a base-class generic conflicts with subclass return-type variance), ",(0,a.kt)("inlineCode",{parentName:"li"},"removeUnknownFields"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"new"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"save"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"modOptions"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"saveQuery.o"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"saveQuery.query"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"diffObjects"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"modelsAreSame"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"modelSelectAll<T = any>")," (heterogeneous entity slices across subclasses), and ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch: Function")," for variance.")),(0,a.kt)("p",null,"Checkpoint 25 (2026-05-14): 411 \u2192 361 (50 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/shared/note-screen-shared.ts")," \u2014 21 removed, 2 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"AttachedResource"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"AttachedResources"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"SaveNoteOptions"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"AttachFileAsset"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceHandler")," types. ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseState.noteResources: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"AttachedResources"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"Shared")," interface methods all typed (saveOneProperty/noteComponent",(0,a.kt)("em",{parentName:"li"},"change/installResourceHandling/uninstallResourceHandling/attachedResources/toggleCheckboxRange). ",(0,a.kt)("inlineCode",{parentName:"em"},"saveNoteButton_press.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"em"},"SaveNoteOptions"),". ",(0,a.kt)("inlineCode",{parentName:"em"},"newState: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"em"},"Partial<BaseState>"),". `resourceCache"),": any",(0,a.kt)("inlineCode",{parentName:"li"},"\u2192"),"AttachedResources",(0,a.kt)("inlineCode",{parentName:"li"},". "),"toggleCheckboxLine",(0,a.kt)("inlineCode",{parentName:"li"},"return \u2192"),"ToggleCheckboxResult",(0,a.kt)("inlineCode",{parentName:"li"},"discriminated union, downstream callers handle the string|tuple shape."),"setState(state: any)",(0,a.kt)("inlineCode",{parentName:"li"},"kept with reason (React component setState signature)."),"ResourceHandler",(0,a.kt)("inlineCode",{parentName:"li"},"parameter"),"any[]",(0,a.kt)("inlineCode",{parentName:"li"},"kept with reason (EventEmitter heterogeneous payloads). Side fixes:"),"app-desktop/.../useWebviewIpcMessage.ts",(0,a.kt)("inlineCode",{parentName:"li"},"handles the new string return;"),"Note.tsx",(0,a.kt)("inlineCode",{parentName:"li"},"resource handler signature is already compatible via variadic"),"any[]`."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"shim-init-node.ts")," \u2014 12 removed, 9 left. Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"ProxySettings")," interface; ",(0,a.kt)("inlineCode",{parentName:"li"},"proxySettings.any")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"setupProxySettings.options.any")," typed. ",(0,a.kt)("inlineCode",{parentName:"li"},"ShimInitOptions")," ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," fields kept with descriptive reasons (sharp/keytar/React/electronBridge/nodeSqlite are external module types). ",(0,a.kt)("inlineCode",{parentName:"li"},"detectAndSetLocale.Setting: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"typeof Setting"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"saveOptions: any")," \u2192 typed structurally. ",(0,a.kt)("inlineCode",{parentName:"li"},"imageOptions: any")," \u2192 typed. ",(0,a.kt)("inlineCode",{parentName:"li"},"cleanUpOnError/file/request.on('error')")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Error"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"requestOptions")," kept ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," (node http/https request options + agent). ",(0,a.kt)("inlineCode",{parentName:"li"},"sites")," call site typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"NodeJS.CallSite[]"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"makeResponse.response")," typed structurally."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"import-enex.ts")," \u2014 17 removed, 3 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"sourceStream/destStream.on('error')")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Error"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"removeUndefinedProperties")," made generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"saveNoteResources.toSave: any")," cast tightened via ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<Pick<...>>")," for the delete keys. ",(0,a.kt)("inlineCode",{parentName:"li"},"Node.attributes: Record<string, any>")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"saveNoteToStorage")," cast through ",(0,a.kt)("inlineCode",{parentName:"li"},"as ExtractedNote"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"handleSaxStreamEvent")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"(...args: any[])=> void")," with reason (sax events heterogeneous). ",(0,a.kt)("inlineCode",{parentName:"li"},"noteAttributes/noteResourceAttributes")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"createErrorWithNoteTitle")," typed. Stream and saxStream ",(0,a.kt)("inlineCode",{parentName:"li"},"on('error')")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Error"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"noteResource[n]")," indexing uses a typed cast through ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"is_todo")," cast to ",(0,a.kt)("inlineCode",{parentName:"li"},"0|1"),". Latitude/longitude/altitude need ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as number")," casts since ENEX values arrive as strings.")),(0,a.kt)("p",null,"Checkpoint 26 (2026-05-14): 361 \u2192 323 (38 removed)."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/search/SearchEngine.ts")," \u2014 22 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"ComplexTerm.scriptType: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch: Function")," \u2192 action-shape dispatch. ",(0,a.kt)("inlineCode",{parentName:"li"},"syncCalls_: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"boolean[]"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"scheduleSyncTablesIID_")," typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof shim.setTimeout>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"setDb.db: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"JoplinDatabase"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"fieldNamesFromOffsets_.offsets: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"number[]"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"hitsThisRow"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"docsWithHits")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Uint32Array"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"processBasicSearchResults_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"processResults_")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"ProcessResultsRow[]")," + ",(0,a.kt)("inlineCode",{parentName:"li"},"ParsedQuery"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"queryTermToRegex.term: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"basicSearch.searchOptions: any")," typed structurally; ",(0,a.kt)("inlineCode",{parentName:"li"},"determineSearchType_.preferredSearchType")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"SearchType"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"allTerms: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Term[]"),". Side: added ",(0,a.kt)("inlineCode",{parentName:"li"},"fuzziness?: number")," to ",(0,a.kt)("inlineCode",{parentName:"li"},"ProcessResultsRow")," (was being assigned at runtime but not declared)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"import-enex-md-gen.ts")," \u2014 16 removed, 5 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Section.lines: any[]")," kept ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with reason (mixed strings/Section/Hr objects). ",(0,a.kt)("inlineCode",{parentName:"li"},"ParserState.{anchorAttributes,spanAttributes}: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string>[]"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"collapseWhiteSpaceAndAppend.state: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ParserState"),". Introduced ",(0,a.kt)("inlineCode",{parentName:"li"},"SaxContext")," type alias; ",(0,a.kt)("inlineCode",{parentName:"li"},"cssValue/isInvisibleBlock/isHighlight/isCodeBlock/displaySaxWarning")," typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"SaxContext")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"{ style?: string }"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"attributeToLowerCase.node")," typed structurally. ",(0,a.kt)("inlineCode",{parentName:"li"},"isSpanWithStyle/isSpanStyleBold/isSpanStyleItalic.attributes")," typed. ",(0,a.kt)("inlineCode",{parentName:"li"},"saxStream.on('error')")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"Error"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"saxStream.on('opentag')")," ",(0,a.kt)("inlineCode",{parentName:"li"},"node: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"{ name; attributes? }"),". ",(0,a.kt)("inlineCode",{parentName:"li"}
1,"captionLines: any[]")," lets inference do the work. ",(0,a.kt)("inlineCode",{parentName:"li"},"enexXmlToMdArray.stream"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"renderLine/renderLines.lines"),", and ",(0,a.kt)("inlineCode",{parentName:"li"},"currentCells")," keep ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with descriptive reasons (sax stream / heterogeneous nested Section objects).")),(0,a.kt)("p",null,"Checkpoint 27 (2026-05-14): 323 \u2192 293 (30 removed)."),(0,a.kt)("p",null,"Scatter cleanup across many smaller files:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/synchronizer/LockHandler.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"RefreshTimer.id: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof shim.setInterval>"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"lockFileToObject.file: any")," typed structurally with optional path/updated_time."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/synchronizer/utils/types.ts")," \u2014 1 removed, 1 left with updated reason. ",(0,a.kt)("inlineCode",{parentName:"li"},"LogSyncOperationFunction.local: any")," typed structurally; ",(0,a.kt)("inlineCode",{parentName:"li"},"ApiCallFunction")," keeps ",(0,a.kt)("inlineCode",{parentName:"li"},"any[]"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"any")," (dispatches by name across drivers)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/style/themeToCss.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"isColor.v")," typed ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," with type predicate; theme indexing via ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," cast."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/style/cssToTheme.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"declarations"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"output")," typed; final return cast ",(0,a.kt)("inlineCode",{parentName:"li"},"as unknown as Theme"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/profileConfig/mergeGlobalAndLocalSettings.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"rootSettings"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"subProfileSettings"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"output")," all ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/attachedResources.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"resourceCache_"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"output: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"AttachedResources"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/noteList/renderTemplate.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"Cell.value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"valueToString.value: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown")," (using ",(0,a.kt)("inlineCode",{parentName:"li"},"String(value)"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinWindow.ts")," \u2014 2 removed, 0 left. Introduced local ",(0,a.kt)("inlineCode",{parentName:"li"},"DispatchStore")," type for store_."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/Global.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"implementation: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"BasePlatformImplementation"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"store: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Store<any>")," with descriptive reason; ",(0,a.kt)("inlineCode",{parentName:"li"},"process: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NodeJS.Process"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/Joplin.ts")," \u2014 1 removed, 1 left with updated reason. ",(0,a.kt)("inlineCode",{parentName:"li"},"store: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Store<any>")," with reason. ",(0,a.kt)("inlineCode",{parentName:"li"},"require.return: any")," kept with plugin-API reason."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinCommands.ts")," \u2014 2 removed (reasons updated)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/utils/loadContentScripts.ts")," \u2014 1 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"loadedModule as any")," cast \u2192 typed extension. ",(0,a.kt)("inlineCode",{parentName:"li"},"ExtraContentScript.module: any")," kept with descriptive reason."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/ResourceService.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"maintenanceTimer1_/maintenanceTimer2_: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ReturnType<typeof shim.setTimeout/setInterval>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/KeymapService.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"modifiersRegExp: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RegExp"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"domToElectronAccelerator.event: any")," typed structurally with the 5 fields actually read."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Importer_Base.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"setMetadata.md: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Partial<ImportMetadata>")," with cast; ",(0,a.kt)("inlineCode",{parentName:"li"},"init.options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ImportOptions"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Importer_Custom.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"options: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," on ",(0,a.kt)("inlineCode",{parentName:"li"},"CustomImporter.onExec.context.options")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"processedOptions"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Exporter_Raw.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"processItem.item/processResource.resource")," typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseItemEntity"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"ResourceEntity"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/ipc/utils/mergeCallbacksAndSerializable.test.ts")," \u2014 1 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"data: any")," typed inline."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/ipc/RemoteMessenger.test.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"transfer.o: any")," made generic ",(0,a.kt)("inlineCode",{parentName:"li"},"<T>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"testObjects: any[]")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>[]"),"."),(0,a.kt)("li",{parentName:"ul"},"Side fix: ",(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Importer_Md.test.ts")," uses ",(0,a.kt)("inlineCode",{parentName:"li"},"ImportModuleOutputFormat")," enum members rather than raw string literals.")),(0,a.kt)("p",null,"Checkpoint 28 (2026-05-14): 293 \u2192 272 (21 removed)."),(0,a.kt)("p",null,'Scatter cleanup chasing remaining "Old code before rule was applied" comments across many files:'),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Note.ts")," \u2014 5 removed, 7 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"previewFieldsWithDefaultValues.options")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"(n as any)[field]")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"(o as any)[field]")," patterns \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," casts; ",(0,a.kt)("inlineCode",{parentName:"li"},"beforeChangeItems: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, string | null>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"updateNoteOrder_.order")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"number"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"handleTitleNaturalSorting.options")," typed."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/BaseItem.ts")," \u2014 4 removed, 16 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"displayTitle.item")," typed structurally; ",(0,a.kt)("inlineCode",{parentName:"li"},"items.map((item: any))")," typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"modelSelectAll<{ id: string }>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"markdownTag.itemOrId/isMarkdownTag.md")," typed structurally; ",(0,a.kt)("inlineCode",{parentName:"li"},"save.o")," reason updated."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"BaseModel.ts")," \u2014 3 removed, 16 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"isNew.object/options")," typed; ",(0,a.kt)("inlineCode",{parentName:"li"},"filterArray"),"/",(0,a.kt)("inlineCode",{parentName:"li"},"filter")," reasons updated; static enum loop uses ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, ModelType>")," cast."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Folder.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"report: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, number>"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/Plugin.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"emit.event: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/JoplinPlugins.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"script.onStart.catch.error: any")," typed structurally."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/commands/MenuUtils.ts")," \u2014 1 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"commandToStatefulMenuItem.commandTarget: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/interop/InteropService_Exporter_Md_frontmatter.ts")," \u2014 0 removed (reason updated)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"import-enex.ts")," \u2014 1 removed, 2 left. saxStream cdata callback typed ",(0,a.kt)("inlineCode",{parentName:"li"},"string"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"}
1,"testing/test-utils-synchronizer.ts")," \u2014 0 removed (kept with reason matching the heterogeneous test fixtures)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/CommandService.test.ts")," \u2014 1 removed, 1 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"createCommand.options")," kept ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," with reason (test fixtures), execute mock kept with reason."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/synchronizer/Synchronizer.conflicts.test.ts")," \u2014 2 removed, 0 left. dynamic field iteration uses ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, unknown>")," casts."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"services/rest/Api.test.ts")," \u2014 2 removed, 0 left. ",(0,a.kt)("inlineCode",{parentName:"li"},"response: any")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEntity"),"; sort callback typed ",(0,a.kt)("inlineCode",{parentName:"li"},"{ id: string }"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/ipc/utils/mergeCallbacksAndSerializable.test.ts")," \u2014 1 left with reason (mergeCallbacksAndSerializable return shape).")),(0,a.kt)("h2",{id:"packageslib-summary"},"packages/lib summary"),(0,a.kt)("p",null,"Final: 1138 \u2192 272 (",(0,a.kt)("strong",{parentName:"p"},"866 removed, 76% reduction"),"), processed in 28 batches over 2026-05-13 \u2192 2026-05-14."),(0,a.kt)("p",null,"Of the 272 remaining disables, 270 have descriptive ",(0,a.kt)("inlineCode",{parentName:"p"},"-- reason")," comments. The 2 without are inside commented-out code in ",(0,a.kt)("inlineCode",{parentName:"p"},"services/synchronizer/synchronizer_LockHandler.test.ts:103-105"),"."),(0,a.kt)("p",null,"The remaining ",(0,a.kt)("inlineCode",{parentName:"p"},"any")," annotations cluster into a handful of structural reasons that resist simple narrowing:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"Per-app polymorphism"),": ",(0,a.kt)("inlineCode",{parentName:"li"},"shim.ts")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"shim-init-node.ts")," cross-platform shims (sharp, keytar, react, electron bridge, nodeSqlite, fsDriver, httpAgent, proxyAgent, node datagram module), redux store/state/dispatch differing across cli/desktop/mobile, FileApi driver subclass shapes."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"Plugin API surface"),": ",(0,a.kt)("inlineCode",{parentName:"li"},"services/plugins/api/types.ts"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"Joplin.ts"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"JoplinCommands.ts"),", command/script/content-script entry points where args/returns are arbitrary by design \u2014 narrowing would break plugin authors."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"External library types not imported here"),": markdown-it, CodeMirror 6 (EditorView/Extension/CompletionSource), sax stream callbacks, node http/https request bag, css-tools declarations, sharp instance."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"BaseModel/BaseItem subclass variance"),": ",(0,a.kt)("inlineCode",{parentName:"li"},"byId"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"modelIndexById"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"save"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"serialize"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"filter"),", etc. are overridden by every subclass with stricter per-entity types; narrowing the base forces subclass return-type incompatibilities or many call-site casts."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"Reducer action unions"),": ",(0,a.kt)("inlineCode",{parentName:"li"},"reducer.ts")," matches dynamically on ",(0,a.kt)("inlineCode",{parentName:"li"},"action.type")," across all redux actions in the app; the action union diverges across cli/desktop/mobile so a strict union here would not compose."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("strong",{parentName:"li"},"Test fixtures"),": a handful of tests pass loose ",(0,a.kt)("inlineCode",{parentName:"li"},"{ id: 1, type_: ... }")," objects with ",(0,a.kt)("inlineCode",{parentName:"li"},"id")," as ",(0,a.kt)("inlineCode",{parentName:"li"},"number"),", mocked stores without ",(0,a.kt)("inlineCode",{parentName:"li"},"dispatch"),", or partial entity slices that don't satisfy the production-typed signatures.")),(0,a.kt)("p",null,"All ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn tsc --noEmit")," and ",(0,a.kt)("inlineCode",{parentName:"p"},"yarn linter-ci packages/lib/")," runs pass for every batch commit."),(0,a.kt)("h2",{id:"multiple-packages---june-2026"},"Multiple packages - June 2026"),(0,a.kt)("p",null,"Migrated several ",(0,a.kt)("inlineCode",{parentName:"p"},"any")," types that weren't migrated before. Some of these required changes spanning multiple packages and were previously left aside for this reason. Others were missed during the previous migrations."),(0,a.kt)("p",null,"The common technique was to tighten the type at its ",(0,a.kt)("strong",{parentName:"p"},"definition")," (the source) so that callers' documented skips cascade away too. The changes, by package:"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"packages/lib")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"}
1,"Synchronizer.ts")," \u2014 added exported ",(0,a.kt)("inlineCode",{parentName:"li"},"SyncStartOptions"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"SyncContext")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"ProgressReport"),"; typed ",(0,a.kt)("inlineCode",{parentName:"li"},"start(options)"),". Cascaded to ",(0,a.kt)("inlineCode",{parentName:"li"},"registry.ts")," (",(0,a.kt)("inlineCode",{parentName:"li"},"scheduleSync"),"), ",(0,a.kt)("inlineCode",{parentName:"li"},"app-cli/command-sync.ts")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"testing/test-utils.ts"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/BaseItem.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"encryptionService_")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"revisionService_")," typed via ",(0,a.kt)("inlineCode",{parentName:"li"},"import type")," of ",(0,a.kt)("inlineCode",{parentName:"li"},"EncryptionService")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"RevisionService")," (a value import would re-create the runtime cycle those services have with ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseItem"),")."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"models/Setting.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"CacheItem")," made generic (",(0,a.kt)("inlineCode",{parentName:"li"},"CacheItem<T>"),") with ",(0,a.kt)("inlineCode",{parentName:"li"},"loadOne<T>")," returning the precise per-key value; ",(0,a.kt)("inlineCode",{parentName:"li"},"formatValue")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"valueToString")," params \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"SettingItem.value")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"unknown"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"keychainService_")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"import type KeychainService"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"reducer.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"State.syncReport")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"ProgressReport")," (cascaded to ",(0,a.kt)("inlineCode",{parentName:"li"},"app-desktop/gui/Sidebar")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"app-mobile/side-menu-content"),"); ",(0,a.kt)("inlineCode",{parentName:"li"},"State.sharedData")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"SharedData")," (exported from ",(0,a.kt)("inlineCode",{parentName:"li"},"note-screen-shared.ts"),"). Removing ",(0,a.kt)("inlineCode",{parentName:"li"},"sharedData: any")," un-poisoned ",(0,a.kt)("inlineCode",{parentName:"li"},"State[keyof State]")," and surfaced a previously-masked dynamic-key access in ",(0,a.kt)("inlineCode",{parentName:"li"},"handleItemDelete"),", fixed with a localized cast.")),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"packages/utils")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"Logger.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"TargetOptions.database")," \u2192 a minimal structural ",(0,a.kt)("inlineCode",{parentName:"li"},"LoggerDatabase")," interface (the concrete ",(0,a.kt)("inlineCode",{parentName:"li"},"Database")," lives in ",(0,a.kt)("inlineCode",{parentName:"li"},"@joplin/lib"),", which depends on this package, so it cannot be imported); added exported ",(0,a.kt)("inlineCode",{parentName:"li"},"LogEntry")," and typed ",(0,a.kt)("inlineCode",{parentName:"li"},"lastEntries()"),". Cascaded to ",(0,a.kt)("inlineCode",{parentName:"li"},"app-mobile/LogScreen.tsx")," (removed a duplicate ",(0,a.kt)("inlineCode",{parentName:"li"},"LogEntry")," and a cast) and ",(0,a.kt)("inlineCode",{parentName:"li"},"exportDebugReport.ts"),".")),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"packages/app-cli")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"app/app.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"commands_")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"activeCommand_")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"BaseCommand"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"commandMetadata_")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, ReturnType<BaseCommand['metadata']>>"),"; the redux dispatch callback now infers from ",(0,a.kt)("inlineCode",{parentName:"li"},"Dispatch"),". ",(0,a.kt)("inlineCode",{parentName:"li"},"gui_")," left ",(0,a.kt)("inlineCode",{parentName:"li"},"any")," (the GUI is the untyped ",(0,a.kt)("inlineCode",{parentName:"li"},"app-gui.js"),"). ",(0,a.kt)("inlineCode",{parentName:"li"},"autocompletion.ts")," gained one localized cast for ",(0,a.kt)("inlineCode",{parentName:"li"},"base-command"),"'s loose ",(0,a.kt)("inlineCode",{parentName:"li"},"options")," element.")),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"packages/app-mobile")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/types.ts")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"AppState.route")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Route")," (the ",(0,a.kt)("inlineCode",{parentName:"li"},"Route")," interface was moved here from ",(0,a.kt)("inlineCode",{parentName:"li"},"appReducer.ts")," and shared); ",(0,a.kt)("inlineCode",{parentName:"li"},"noteSideMenuOptions")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"SideMenuContentOptions"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"utils/appReducer.ts")," \u2014 the nav-history helpers (",(0,a.kt)("inlineCode",{parentName:"li"},"removeAdjacent*"),", ",(0,a.kt)("inlineCode",{parentName:"li"},"removeLatestFolderIfSelected"),") \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Route[]")," / ",(0,a.kt)("inlineCode",{parentName:"li"},"Route"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"}
1,"components/app-nav.tsx")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"Props.route")," \u2192 the shared ",(0,a.kt)("inlineCode",{parentName:"li"},"Route"),"."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"components/screens/Note/Note.tsx")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"menuOptionsCache_")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"Record<string, MenuOptionType[]>"),"; ",(0,a.kt)("inlineCode",{parentName:"li"},"editorRef")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RefObject<EditorControl>")," (it only ever attaches to ",(0,a.kt)("inlineCode",{parentName:"li"},"NoteEditor"),", whose handle is ",(0,a.kt)("inlineCode",{parentName:"li"},"EditorControl"),").")),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"packages/app-desktop")),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx")," \u2014 ",(0,a.kt)("inlineCode",{parentName:"li"},"pluginAssets")," \u2192 ",(0,a.kt)("inlineCode",{parentName:"li"},"RenderResultPluginAsset[]"),".")),(0,a.kt)("p",null,"Genuinely-untyped boundaries were left as ",(0,a.kt)("inlineCode",{parentName:"p"},"any")," with accurate reasons: the ",(0,a.kt)("inlineCode",{parentName:"p"},"app-gui.js")," GUI handle, the ",(0,a.kt)("inlineCode",{parentName:"p"},"react-native-dialogbox")," ref, mixed React-Native style records, the heterogeneous reducer ",(0,a.kt)("inlineCode",{parentName:"p"},"action")," union, the per-screen ",(0,a.kt)("inlineCode",{parentName:"p"},"ComponentType<any>"),", and the TinyMCE editor / event types that are looser than the published ",(0,a.kt)("inlineCode",{parentName:"p"},"@types/tinymce"),"."),(0,a.kt)("p",null,"One pre-existing inconsistency was uncovered and left for separate follow-up: ",(0,a.kt)("inlineCode",{parentName:"p"},"app-mobile"),"'s ",(0,a.kt)("inlineCode",{parentName:"p"},"ShareExtension.SharedData")," declares ",(0,a.kt)("inlineCode",{parentName:"p"},"resources: string[]"),", but the lib consumer reads each resource as a ",(0,a.kt)("inlineCode",{parentName:"p"},"SharedResource")," object \u2014 the two same-named types should be reconciled after verifying the native share payload."))}k.isMDXComponent=!0}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.