RELEASE_NOTES.md
RELEASE_NOTES.md
The ripgrep fast path now installs correctly on the LM Studio Hub. pattern_scan's B' prefilter and grep_files' rg engine load the npm package ripgrep lazily at tool-call time β but it was declared as a devDependency, so any production-scoped install would have silently disabled the fast path for every Hub user (permanent pure-JS fallback, no visible error).
devDependencies β dependencies) + lock refresh; version pin unchanged at 0.3.1 β the build verified live this session on a fresh reinstall.package.json/package-lock.json; a dependency required at runtime must sit in dependencies. Graceful fallback behavior is untouched either way β this removes the silent-degradation risk, not code.lms push.pattern_scan ripgrep phase-1 prefilter (B')Faster regex-mode scanning for directory targets β same contract, same fallback guarantee. The Option A architecture that v1.9.13 shipped to grep_files now runs in pattern_scan: an in-process WASM ripgrep pass names the files whose content can match; only those go through the worker pipeline, while every non-named file still produces byte-identical gate records and scan stats.
get_memory local-file parse guard (hotfix)Memory reads no longer silently abandon the project-local store. After reinstalling v1.9.13, verification showed every get_memory call in projects with auto-context history logging a parse error to plugin stderr and falling back away from the documented #1 source (the working-dir memory file).
grep_files ripgrep-backed regex engine with JS fallbackFaster regex-mode scanning for directory targets β same contract, same guards. A new self-contained module (src/utils/ripgrepEngine.ts) runs an in-process WASM ripgrep (pithings/ripgrep-node 0.3.1, lazy-loaded on first use) as a phase-1 candidate-file prefilter before grep_files scans; phase 2 shapes matches with the existing code, byte-for-byte.
Removed 13 audited orphan files after a full AST + import-graph audit of all 140 TS files (zero referencers confirmed for each): src/utils/simulation.ts, src/toolsDocumentation.ts, src/tools/imageAnalysisTools.ts (superseded by live imageProcessingTools.ts), src/tools/{backupUtils,toolProtocolWarnings,executionRegistry,utilityRegistry}.ts, dead recodeTool rules rules/{deadCodeDetection,asyncModernizer,typeInference,modulePathNormalization}.ts, plus stale artifacts src/toolsProvider.ts.bak + tests/executedToolTransparency.test.ts.bak.
executedTool (silent-substitution incident follow-up)Every plain-object tool result now carries the ground truth of what actually ran. Follow-up to the 2026-09-01 "silent tool substitution" incident (model called a disabled tool name; log evidence attributed it to model-side substitution, not an ai_toolbox routing defect β but the transcript had no way to verify which implementation executed).
pattern_scan tool + puppeteer connected fix + dead-file removalShips three code changes from the post-v1.9.11 (28.08) window, plus a full MD docs sync against current code.
Versioning: released as v1.9.12 β package.json + manifest.json bumped v1.9.11 β v1.9.12 on 31.08 (user-directed); manifest revision advanced 22 β 23 so LM Studio detects the update. (The "folds into next release" framing in this entry was written pre-decision and is superseded by this line.)
grep_files limits (docs-only, folds into v1.9.11)Added a "π Standout Tools" highlight table to README.md directly under the 130-tools hero block, plus corrected TOOLS_REFERENCE.md so its grep_files entry matches the current tool contract.
grep_files per-call completion telemetry (live-verified; folds into next release)Every grep_files call now logs a one-line wall-clock summary to the plugin's stderr channel (%APPDATA%\LM Studio\logs\main.log): completed in <N>ms β <files scanned>, <matches>, <skipped> (abort path logs aborted in β¦ [partial results]).
Canceling predictions timed out class, recurring 08-26β08-30).Closes the last hang class of grep_files: catastrophic-backtracking patterns can no longer block the event loop (and with it every timeout guard).
Closes the v1.9.10 maintenance window with a version bump to v1.9.11 (user-directed decision, supersedes the 25.08 "no bump" policy). Headline fix eliminates a class of silent 0-match failures in grep_files.
& match correctly (live-verified: 4/4 expected matches in TOOLS_REFERENCE.md)*, + or ?patternMode:"regex" + exactly 4 matchesVersioning: released as v1.9.11 β package.json + manifest.json bumped v1.9.10 β v1.9.11 on 28.08 (~20:45) per user decision; baseline backup taken (.ai_toolbox_backups/ai_toolbox-v1.9.11-release-baseline-2026-08-28.zip).
Fixed a deterministic multi-day V8 heap OOM (Ineffective mark-compacts near heap limit) in the vector-RAG text chunkers β and closed the last failing test (cross-test mock contamination) in tests/webResearchTools.test.ts.
npm test).npm run build; bundles carry no version strings).Versioning: stayed at v1.9.10 (no bump) β maintainer decision 25.08 (superseded by the v1.9.11 release of 28.08).
Eliminated a class of plugin-host crashes (JavaScript heap out of memory) caused by unbounded page-body buffering in the web tools.
fetch_web_content: previously buffered the full page with response.text() and only then checked its 50 KB cap β oversized pages exhausted the host's heap first. The cap is now enforced while streaming; the socket is cancelled the moment the budget trips.Page too large (β¦) β¦ Use searxng_search + summary_only).Eliminated silent auto-registration of wrong/stale project paths without user confirmation.
Prior to this fix, the silent auto-registration bug occurred because:
register_project tool call with confirmed pathEliminated all synchronous file writes from the codebase; introduced shared crash-resilient atomic write utility with randomized temp filenames and rollback-on-failure protection.
crypto.randomBytes(9) for unique temp file names β prevents collisions even under rapid concurrent writes, eliminates stale temp files from prior crashesatomicWriteBinaryFile() function uses raw buffer writes with no text encoding β preserves exact binary content for image processing and other non-text operationsAll previously synchronous file-write tools converted to async with shared atomicWrite:
| Module | Tools Affected | Previous State | New State |
|---|---|---|---|
| lineOperations.ts | delete_lines, line_operations | Sync writes via fs.writeFileSync | Async β atomicWrite |
| refactorCodeTools.ts | rename_identifier, move_function, extract_function, unused_import_cleanup | Sync writes | Async β atomicWrite + rollback-on-failure |
| utilityTools.ts | ~25 utility tools (backup, chart, line ops) | Mixed sync/async | All async β atomicWrite |
| dataVisualizationTools.ts | generate_chart | Sync PNG write | Async β atomicWriteBinaryFile |
| imageProcessingTools.ts | describe_image, compare_images output saves | Sync writes | Async β atomicWriteBinaryFile |
| markdownPreviewTools.ts | markdown_preview HTML save | Sync write | Async β atomicWrite |
| browserAutomationTools.ts | screenshot_desktop PNG save | Sync write | Async β atomicWriteBinaryFile |
| uiGenerationTools.ts | UI component saves | Sync writes | Async β atomicWrite |
| recodeEngine.ts (recodeTool/) | AST transformation output | Sync writes | Async β atomicWrite + rollback-on-failure |
.bak backup before returning error β prevents corrupted source filesReplaced all child_process.exec() calls with explicit shell spawning via spawn(cmd.exe /c, ...) in gitGithubTools.ts. Zero behavioral changes; zero breaking changes.
import { spawn } from 'child_process'cmd.exe /c (Windows) or /bin/sh -c (Unix/macOS) β never uses { shell: true }, avoiding Node.js DEP0190 warningFixed the checkpoint warning that was generated but never surfaced in chat; restored confirm-first working-directory switching and added German JA/NEIN reply support.
A Step 0.7 refactor silently switched the working directory on project-keyword match β burying the pending checkpoint warning (logs: "THRESHOLD PROMPT GENERATED"; chat: nothing) and bypassed Step 0.6 reply handling. Reply detection accepted only English YES/NO, and transitionTo() cleared pending warnings on any state change.
promptPreprocessor.ts): confirm-first banner β no CWD change on detection; one-shot switch only after an explicit YES/JA reply in a later message, then resetspromptPreprocessor.ts): JA/NEIN normalized onto canonical YES/NO FSM inputs for checkpoint repliesautoTracker.ts): transitionTo() no longer clears pendingCheckpointWarning on unrelated state changes; warning injected into all preprocessor return paths while pendingEliminated the "ai-toolbox not found" clarification loop by adding Step 0.7 project keyword detection in promptPreprocessor.ts and _syncFromSessionMemory() lazy registry sync.
When users mentioned a registered project name (e.g., "switch to ai-toolbox"), the AI would:
search_projects(query="ai-toolbox") β empty results (stale registry)Root Cause: The cross-project registry was never synced from session memory decisions. Projects detected via keyword matching in Step 0.7 were registered once but not auto-synced when search_projects was called later.
| Tool | Sync Trigger | Purpose |
|---|---|---|
| search_projects | _syncFromSessionMemory() before query | Ensures registry includes projects from past decisions |
| get_project_info | _syncFromSessionMemory() before lookup | Same β prevents stale registry entries |
Resolved TypeScript compilation errors and ESLint warnings through ESM conversion and proper type assertions.
require('../attachmentManager.js') (CommonJS) with static ESM import β eliminates @typescript-eslint/no-require-imports warningSynchronized version references and added missing module documentation across project files.
The ripgrep fast path now installs correctly on the LM Studio Hub. pattern_scan's B' prefilter and grep_files' rg engine load the npm package ripgrep lazily at tool-call time β but it was declared as a devDependency, so any production-scoped install would have silently disabled the fast path for every Hub user (permanent pure-JS fallback, no visible error).
devDependencies β dependencies) + lock refresh; version pin unchanged at 0.3.1 β the build verified live this session on a fresh reinstall.package.json/package-lock.json; a dependency required at runtime must sit in dependencies. Graceful fallback behavior is untouched either way β this removes the silent-degradation risk, not code.lms push.pattern_scan ripgrep phase-1 prefilter (B')Faster regex-mode scanning for directory targets β same contract, same fallback guarantee. The Option A architecture that v1.9.13 shipped to grep_files now runs in pattern_scan: an in-process WASM ripgrep pass names the files whose content can match; only those go through the worker pipeline, while every non-named file still produces byte-identical gate records and scan stats.
get_memory local-file parse guard (hotfix)Memory reads no longer silently abandon the project-local store. After reinstalling v1.9.13, verification showed every get_memory call in projects with auto-context history logging a parse error to plugin stderr and falling back away from the documented #1 source (the working-dir memory file).
grep_files ripgrep-backed regex engine with JS fallbackFaster regex-mode scanning for directory targets β same contract, same guards. A new self-contained module (src/utils/ripgrepEngine.ts) runs an in-process WASM ripgrep (pithings/ripgrep-node 0.3.1, lazy-loaded on first use) as a phase-1 candidate-file prefilter before grep_files scans; phase 2 shapes matches with the existing code, byte-for-byte.
Removed 13 audited orphan files after a full AST + import-graph audit of all 140 TS files (zero referencers confirmed for each): src/utils/simulation.ts, src/toolsDocumentation.ts, src/tools/imageAnalysisTools.ts (superseded by live imageProcessingTools.ts), src/tools/{backupUtils,toolProtocolWarnings,executionRegistry,utilityRegistry}.ts, dead recodeTool rules rules/{deadCodeDetection,asyncModernizer,typeInference,modulePathNormalization}.ts, plus stale artifacts src/toolsProvider.ts.bak + tests/executedToolTransparency.test.ts.bak.
executedTool (silent-substitution incident follow-up)Every plain-object tool result now carries the ground truth of what actually ran. Follow-up to the 2026-09-01 "silent tool substitution" incident (model called a disabled tool name; log evidence attributed it to model-side substitution, not an ai_toolbox routing defect β but the transcript had no way to verify which implementation executed).
pattern_scan tool + puppeteer connected fix + dead-file removalShips three code changes from the post-v1.9.11 (28.08) window, plus a full MD docs sync against current code.
Versioning: released as v1.9.12 β package.json + manifest.json bumped v1.9.11 β v1.9.12 on 31.08 (user-directed); manifest revision advanced 22 β 23 so LM Studio detects the update. (The "folds into next release" framing in this entry was written pre-decision and is superseded by this line.)
grep_files limits (docs-only, folds into v1.9.11)Added a "π Standout Tools" highlight table to README.md directly under the 130-tools hero block, plus corrected TOOLS_REFERENCE.md so its grep_files entry matches the current tool contract.
grep_files per-call completion telemetry (live-verified; folds into next release)Every grep_files call now logs a one-line wall-clock summary to the plugin's stderr channel (%APPDATA%\LM Studio\logs\main.log): completed in <N>ms β <files scanned>, <matches>, <skipped> (abort path logs aborted in β¦ [partial results]).
Canceling predictions timed out class, recurring 08-26β08-30).Closes the last hang class of grep_files: catastrophic-backtracking patterns can no longer block the event loop (and with it every timeout guard).
Closes the v1.9.10 maintenance window with a version bump to v1.9.11 (user-directed decision, supersedes the 25.08 "no bump" policy). Headline fix eliminates a class of silent 0-match failures in grep_files.
& match correctly (live-verified: 4/4 expected matches in TOOLS_REFERENCE.md)*, + or ?patternMode:"regex" + exactly 4 matchesVersioning: released as v1.9.11 β package.json + manifest.json bumped v1.9.10 β v1.9.11 on 28.08 (~20:45) per user decision; baseline backup taken (.ai_toolbox_backups/ai_toolbox-v1.9.11-release-baseline-2026-08-28.zip).
Fixed a deterministic multi-day V8 heap OOM (Ineffective mark-compacts near heap limit) in the vector-RAG text chunkers β and closed the last failing test (cross-test mock contamination) in tests/webResearchTools.test.ts.
npm test).npm run build; bundles carry no version strings).Versioning: stayed at v1.9.10 (no bump) β maintainer decision 25.08 (superseded by the v1.9.11 release of 28.08).
Eliminated a class of plugin-host crashes (JavaScript heap out of memory) caused by unbounded page-body buffering in the web tools.
fetch_web_content: previously buffered the full page with response.text() and only then checked its 50 KB cap β oversized pages exhausted the host's heap first. The cap is now enforced while streaming; the socket is cancelled the moment the budget trips.Page too large (β¦) β¦ Use searxng_search + summary_only).Eliminated silent auto-registration of wrong/stale project paths without user confirmation.
Prior to this fix, the silent auto-registration bug occurred because:
register_project tool call with confirmed pathEliminated all synchronous file writes from the codebase; introduced shared crash-resilient atomic write utility with randomized temp filenames and rollback-on-failure protection.
crypto.randomBytes(9) for unique temp file names β prevents collisions even under rapid concurrent writes, eliminates stale temp files from prior crashesatomicWriteBinaryFile() function uses raw buffer writes with no text encoding β preserves exact binary content for image processing and other non-text operationsAll previously synchronous file-write tools converted to async with shared atomicWrite:
| Module | Tools Affected | Previous State | New State |
|---|---|---|---|
| lineOperations.ts | delete_lines, line_operations | Sync writes via fs.writeFileSync | Async β atomicWrite |
| refactorCodeTools.ts | rename_identifier, move_function, extract_function, unused_import_cleanup | Sync writes | Async β atomicWrite + rollback-on-failure |
| utilityTools.ts | ~25 utility tools (backup, chart, line ops) | Mixed sync/async | All async β atomicWrite |
| dataVisualizationTools.ts | generate_chart | Sync PNG write | Async β atomicWriteBinaryFile |
| imageProcessingTools.ts | describe_image, compare_images output saves | Sync writes | Async β atomicWriteBinaryFile |
| markdownPreviewTools.ts | markdown_preview HTML save | Sync write | Async β atomicWrite |
| browserAutomationTools.ts | screenshot_desktop PNG save | Sync write | Async β atomicWriteBinaryFile |
| uiGenerationTools.ts | UI component saves | Sync writes | Async β atomicWrite |
| recodeEngine.ts (recodeTool/) | AST transformation output | Sync writes | Async β atomicWrite + rollback-on-failure |
.bak backup before returning error β prevents corrupted source filesReplaced all child_process.exec() calls with explicit shell spawning via spawn(cmd.exe /c, ...) in gitGithubTools.ts. Zero behavioral changes; zero breaking changes.
import { spawn } from 'child_process'cmd.exe /c (Windows) or /bin/sh -c (Unix/macOS) β never uses { shell: true }, avoiding Node.js DEP0190 warningFixed the checkpoint warning that was generated but never surfaced in chat; restored confirm-first working-directory switching and added German JA/NEIN reply support.
A Step 0.7 refactor silently switched the working directory on project-keyword match β burying the pending checkpoint warning (logs: "THRESHOLD PROMPT GENERATED"; chat: nothing) and bypassed Step 0.6 reply handling. Reply detection accepted only English YES/NO, and transitionTo() cleared pending warnings on any state change.
promptPreprocessor.ts): confirm-first banner β no CWD change on detection; one-shot switch only after an explicit YES/JA reply in a later message, then resetspromptPreprocessor.ts): JA/NEIN normalized onto canonical YES/NO FSM inputs for checkpoint repliesautoTracker.ts): transitionTo() no longer clears pendingCheckpointWarning on unrelated state changes; warning injected into all preprocessor return paths while pendingEliminated the "ai-toolbox not found" clarification loop by adding Step 0.7 project keyword detection in promptPreprocessor.ts and _syncFromSessionMemory() lazy registry sync.
When users mentioned a registered project name (e.g., "switch to ai-toolbox"), the AI would:
search_projects(query="ai-toolbox") β empty results (stale registry)Root Cause: The cross-project registry was never synced from session memory decisions. Projects detected via keyword matching in Step 0.7 were registered once but not auto-synced when search_projects was called later.
| Tool | Sync Trigger | Purpose |
|---|---|---|
| search_projects | _syncFromSessionMemory() before query | Ensures registry includes projects from past decisions |
| get_project_info | _syncFromSessionMemory() before lookup | Same β prevents stale registry entries |
Resolved TypeScript compilation errors and ESLint warnings through ESM conversion and proper type assertions.
require('../attachmentManager.js') (CommonJS) with static ESM import β eliminates @typescript-eslint/no-require-imports warningSynchronized version references and added missing module documentation across project files.
src/utils/ripgrepEngine.ts module β same instance and lazy-load discipline as grep_files, so a missing dep can never break plugin boot). Literal mode is honored for explicit-literal or demoted patterns; case-sensitivity follows the call (caseSensitive, default true β unlike grep_files' hardcoded -i).'binary' skip record (detection needs content inspection; such files are unobservable in all other output fields). Pinned by tests that accept both regimes and fail on anything else.package.json/manifest.json bumped v1.9.14 β v1.9.15 on 02.09, revision advanced 25 β 26 so LM Studio detects the update (user-directed).save_memory facts ({key,value,timestamp}) sit next to auto-context entries ({id,title,type,content,tags,β¦}), which carry no key. The reader's e.key.startsWith('memory_') filter threw on the first such record, aborting the entire read. Writes were never affected; only reads degraded β facts lived in RAM but not from disk across a restart.src/tools/contextManagementTools.ts at both read sites (local project file + plugin-root fallback) β keyless records are now skipped by the filter instead of throwing. No schema change, no new files, no behavior change for valid facts; all other output fields untouched.get_memory returns all local memory_* facts with no parse-failure line in main.log.package.json/manifest.json bumped v1.9.13 β v1.9.14 on 02.09, revision advanced 24 β 25 so LM Studio detects the update (user-directed).skipped_files records stay byte-identical to pre-change output (size-gate and line-cap entries included β verified by the parity suite vs a frozen golden baseline); -i always applies in regex mode as before; hidden-file scanning mirrors previous walker semantics.package.json/manifest.json bumped v1.9.12 β v1.9.13 on 02.09, revision advanced 23 β 24 so LM Studio detects the update (user-directed).src/index.ts) β zero shipped-bundle impact; live equivalents kept and verified present in the same listings (recodeEngine.ts, recodeTypes.ts, rules/unusedImports.ts); jest.config.cjs needed no edits (full re-read confirmed).tests/grep_files.test.ts as importing a missing module; full-file read showed the string exists only in test-fixture template literals β gate held, test kept.ARCHITECTURE.md module tree & recode-rule sections and TOOLS_REFERENCE.md rule table updated to current code state; historical changelog entries left as history.executedTool transparency stamp below).src/toolsProvider.ts): the instrumentation wrapper stamps executedTool = registered name of the implementation that actually executed into every plain-object result. Additive-only: strings/numbers/arrays/null and non-plain objects pass through byte-identical; routing, side effects, timing and error propagation unchanged; FIX #20 token bookkeeping semantics preserved (records the original payload with the same ground-truth name).executedTool: "Y", substitution is visible in the transcript instead of hidden behind a plausible-looking success narrative.tests/executedToolTransparency.test.ts runs the real registrationβminifyβinstrument pipeline with six side-effect-free probe tools (mocked at the jest-mapped stub path); includes a regression guard for FIX #20 A1 bookkeeping and unchanged error propagation. Guard logic additionally verified offline: 14/14 edge cases pass.npx jest tests/executedToolTransparency.test.ts + full baseline (657 + 8 new expected green). Live activation = sync src/toolsProvider.ts into the LM Studio install (source-run) + full restart.pattern_scan tool (src/tools/fileSystemTools.ts; clean-room engine src/tools/patternScan.ts) β recursive content search {file, line, content}; unsafe/invalid regexes auto-demote to literal mode (demotedToLiteral); caps: 256 KB / 10k lines per file (skips reported), 50 matches/file, global 200; single-file or directory root. Jest mock + mapper added; full suite green 657/657 (user-verified); live probe on the running plugin passed incl. dist-bundle stress test.connected property-read fix (browserAutomationTools.ts + types.d.ts) β puppeteer 24 exposes Browser.connected as a getter property, not a method; d.ts now declares readonly connected: boolean. Live probe passed (screenshot PNG magic-verified).src/browserAutomationTools.ts deleted behind backup .ai_toolbox_backups/ai_toolbox-pre-deadfile-delete-20260831.zip; seven stale .bak files cleaned, re-verified zero. Typecheck + jest green post-deletion (user-confirmed).ARCHITECTURE.md, TOOLS_REFERENCE.md, DOCUMENTATION.md, QUICK_START.md aligned with code β pattern_scan documented, File System 22β23 tools, unique totals 130β131, Git & GitHub table corrected to 15 (code-verified), dead-file reference removed, screenshot_desktop write lines re-attributed to imageProcessingTools.ts (external platform process writes the file β no Node-side atomic write there). .bak backups created for every edited MD.pattern_scan) and test-bench figure updated to 657 tests / 38 suites β completes the MD alignment; version badge + release-highlights row now read v1.9.12refactor_code, unique in field), AutoTracker + ContextGuard pipeline (mid-loop 75%/90% token thresholds, automatic checkpoint summarization & compression β absent from every surveyed plugin), hang-safe grep_files/find_replace_all, guarded line_operations, background-command suite, browser automation, integrated multi-format RAG (PDF/DOCX/XLSX), run_tests, planning state machine, secret_scan, data visualization (generate_chart β zero in field), cross-project memory registry, backup/restore suite.grep_files: added missing params max_depth (default 10, range 1β50) and max_lines (default 5000); documented deadline behavior (aborted: true + partial results per v1.9.9) and REV-24 prose-alternation handling..bak backups created for both files before edit.patternNeedsWorkerIsolation) routes only patterns that cannot be proven cheap into an isolated node:worker_threads Worker β hard-killed after 2 s budget, recorded in skipped_files, scan continues. Safe patterns keep the inline fast path (zero overhead).((a+){3}){4}x-style quantified subgroups now route correctly (old $-anchored check was defeatable by trailing content; T1b double-freeze root cause).parentPort; the browser-style shape threw self is not defined, misreporting every risky pattern as a 2 s kill with zero work done). Offline repro: catastrophic payload hard-killed at exactly 2000 ms.& alternations stay in regex mode (REV-24) (src/security.ts, isSafeRegex()): prose patterns like "Backup & Restore|Git & GitHub" were silently forced into literal mode β 0 matches β LLM retry loops. Root cause: the code-signature heuristic paired a bare & with *+? indicators β though & is not a JS regex metacharacter (zero ReDoS risk). Clause-1 char class now excludes bare &.src/tools/fileSystemTools.ts): forced-literal outcomes now return patternMode:"auto_escaped" with a human-readable hint string β no more silent failures.src/tools/vectorRagTools.ts): chunkText, chunkDocxText, and chunkPdfText could loop forever when a partial final chunk was shorter than the overlap word budget β for certain text lengths the window start reached a fixed point (startIndex === endIndex). All three now enforce strict forward progress: startIndex = Math.max(endIndex, startIndex + 1).tests/vectorRagTools.ragWebContent.test.ts): the oversized-page spec exercises the poison-remainder path end-to-end; heading assertion aligned with html-to-text's default heading uppercasing (case-insensitive).tests/webResearchTools.test.ts): shared mocks are now reset in beforeEach and re-seeded explicitly β no more state leaking between tests.rag_web_content (vectorRAG): previously a raw, uncapped, unbounded fetch plus ~5β10Γ memory amplification in chunking. Now bounded to 500 KB and routed through the shared timeout/retry helper.fetchWithRetry paths: every attempt is now time-bounded (30 s AbortController timeout), matching the existing http_* tools' convention β slow or stalled transfers can no longer hang indefinitely.writeFileSync blocking the event loop during LLM tool chainsatomicWriteBinaryFile() uses raw buffer writes β image processing and chart generation preserve exact binary contentsrc/utils/ripgrepEngine.ts module β same instance and lazy-load discipline as grep_files, so a missing dep can never break plugin boot). Literal mode is honored for explicit-literal or demoted patterns; case-sensitivity follows the call (caseSensitive, default true β unlike grep_files' hardcoded -i).'binary' skip record (detection needs content inspection; such files are unobservable in all other output fields). Pinned by tests that accept both regimes and fail on anything else.package.json/manifest.json bumped v1.9.14 β v1.9.15 on 02.09, revision advanced 25 β 26 so LM Studio detects the update (user-directed).save_memory facts ({key,value,timestamp}) sit next to auto-context entries ({id,title,type,content,tags,β¦}), which carry no key. The reader's e.key.startsWith('memory_') filter threw on the first such record, aborting the entire read. Writes were never affected; only reads degraded β facts lived in RAM but not from disk across a restart.src/tools/contextManagementTools.ts at both read sites (local project file + plugin-root fallback) β keyless records are now skipped by the filter instead of throwing. No schema change, no new files, no behavior change for valid facts; all other output fields untouched.get_memory returns all local memory_* facts with no parse-failure line in main.log.package.json/manifest.json bumped v1.9.13 β v1.9.14 on 02.09, revision advanced 24 β 25 so LM Studio detects the update (user-directed).skipped_files records stay byte-identical to pre-change output (size-gate and line-cap entries included β verified by the parity suite vs a frozen golden baseline); -i always applies in regex mode as before; hidden-file scanning mirrors previous walker semantics.package.json/manifest.json bumped v1.9.12 β v1.9.13 on 02.09, revision advanced 23 β 24 so LM Studio detects the update (user-directed).src/index.ts) β zero shipped-bundle impact; live equivalents kept and verified present in the same listings (recodeEngine.ts, recodeTypes.ts, rules/unusedImports.ts); jest.config.cjs needed no edits (full re-read confirmed).tests/grep_files.test.ts as importing a missing module; full-file read showed the string exists only in test-fixture template literals β gate held, test kept.ARCHITECTURE.md module tree & recode-rule sections and TOOLS_REFERENCE.md rule table updated to current code state; historical changelog entries left as history.executedTool transparency stamp below).src/toolsProvider.ts): the instrumentation wrapper stamps executedTool = registered name of the implementation that actually executed into every plain-object result. Additive-only: strings/numbers/arrays/null and non-plain objects pass through byte-identical; routing, side effects, timing and error propagation unchanged; FIX #20 token bookkeeping semantics preserved (records the original payload with the same ground-truth name).executedTool: "Y", substitution is visible in the transcript instead of hidden behind a plausible-looking success narrative.tests/executedToolTransparency.test.ts runs the real registrationβminifyβinstrument pipeline with six side-effect-free probe tools (mocked at the jest-mapped stub path); includes a regression guard for FIX #20 A1 bookkeeping and unchanged error propagation. Guard logic additionally verified offline: 14/14 edge cases pass.npx jest tests/executedToolTransparency.test.ts + full baseline (657 + 8 new expected green). Live activation = sync src/toolsProvider.ts into the LM Studio install (source-run) + full restart.pattern_scan tool (src/tools/fileSystemTools.ts; clean-room engine src/tools/patternScan.ts) β recursive content search {file, line, content}; unsafe/invalid regexes auto-demote to literal mode (demotedToLiteral); caps: 256 KB / 10k lines per file (skips reported), 50 matches/file, global 200; single-file or directory root. Jest mock + mapper added; full suite green 657/657 (user-verified); live probe on the running plugin passed incl. dist-bundle stress test.connected property-read fix (browserAutomationTools.ts + types.d.ts) β puppeteer 24 exposes Browser.connected as a getter property, not a method; d.ts now declares readonly connected: boolean. Live probe passed (screenshot PNG magic-verified).src/browserAutomationTools.ts deleted behind backup .ai_toolbox_backups/ai_toolbox-pre-deadfile-delete-20260831.zip; seven stale .bak files cleaned, re-verified zero. Typecheck + jest green post-deletion (user-confirmed).ARCHITECTURE.md, TOOLS_REFERENCE.md, DOCUMENTATION.md, QUICK_START.md aligned with code β pattern_scan documented, File System 22β23 tools, unique totals 130β131, Git & GitHub table corrected to 15 (code-verified), dead-file reference removed, screenshot_desktop write lines re-attributed to imageProcessingTools.ts (external platform process writes the file β no Node-side atomic write there). .bak backups created for every edited MD.pattern_scan) and test-bench figure updated to 657 tests / 38 suites β completes the MD alignment; version badge + release-highlights row now read v1.9.12refactor_code, unique in field), AutoTracker + ContextGuard pipeline (mid-loop 75%/90% token thresholds, automatic checkpoint summarization & compression β absent from every surveyed plugin), hang-safe grep_files/find_replace_all, guarded line_operations, background-command suite, browser automation, integrated multi-format RAG (PDF/DOCX/XLSX), run_tests, planning state machine, secret_scan, data visualization (generate_chart β zero in field), cross-project memory registry, backup/restore suite.grep_files: added missing params max_depth (default 10, range 1β50) and max_lines (default 5000); documented deadline behavior (aborted: true + partial results per v1.9.9) and REV-24 prose-alternation handling..bak backups created for both files before edit.patternNeedsWorkerIsolation) routes only patterns that cannot be proven cheap into an isolated node:worker_threads Worker β hard-killed after 2 s budget, recorded in skipped_files, scan continues. Safe patterns keep the inline fast path (zero overhead).((a+){3}){4}x-style quantified subgroups now route correctly (old $-anchored check was defeatable by trailing content; T1b double-freeze root cause).parentPort; the browser-style shape threw self is not defined, misreporting every risky pattern as a 2 s kill with zero work done). Offline repro: catastrophic payload hard-killed at exactly 2000 ms.& alternations stay in regex mode (REV-24) (src/security.ts, isSafeRegex()): prose patterns like "Backup & Restore|Git & GitHub" were silently forced into literal mode β 0 matches β LLM retry loops. Root cause: the code-signature heuristic paired a bare & with *+? indicators β though & is not a JS regex metacharacter (zero ReDoS risk). Clause-1 char class now excludes bare &.src/tools/fileSystemTools.ts): forced-literal outcomes now return patternMode:"auto_escaped" with a human-readable hint string β no more silent failures.src/tools/vectorRagTools.ts): chunkText, chunkDocxText, and chunkPdfText could loop forever when a partial final chunk was shorter than the overlap word budget β for certain text lengths the window start reached a fixed point (startIndex === endIndex). All three now enforce strict forward progress: startIndex = Math.max(endIndex, startIndex + 1).tests/vectorRagTools.ragWebContent.test.ts): the oversized-page spec exercises the poison-remainder path end-to-end; heading assertion aligned with html-to-text's default heading uppercasing (case-insensitive).tests/webResearchTools.test.ts): shared mocks are now reset in beforeEach and re-seeded explicitly β no more state leaking between tests.rag_web_content (vectorRAG): previously a raw, uncapped, unbounded fetch plus ~5β10Γ memory amplification in chunking. Now bounded to 500 KB and routed through the shared timeout/retry helper.fetchWithRetry paths: every attempt is now time-bounded (30 s AbortController timeout), matching the existing http_* tools' convention β slow or stalled transfers can no longer hang indefinitely.writeFileSync blocking the event loop during LLM tool chainsatomicWriteBinaryFile() uses raw buffer writes β image processing and chart generation preserve exact binary content