2.3.5–2.3.9: AI efficiency, diagnose_fault, target switch, documentation and build-artefact tools, workspace skills - #30
Merged
MatthiasHertelArm merged 39 commits intoSep 2, 2026
Conversation
MatthiasHertelArm
force-pushed
the
pr/2.3.5-ai-efficiency
branch
3 times, most recently
from
August 31, 2026 15:02
85ed021 to
1d0ef00
Compare
soumeh01
marked this pull request as ready for review
September 1, 2026 07:08
soumeh01
previously approved these changes
Sep 1, 2026
debugMCPServer.ts does not import vscode so it can run headless under the transport harness; settings therefore have to arrive through the constructor. Add a trailing DebugMCPServerOptions object (serialEnabled, telemetry.jsonlPath), fixed for the lifetime of a server instance so the tool list a client sees stays stable between turns, thread it through CoordinatorOptions.serverOptions, expose getOptions(), cover it in the transport check and document the contract. The settings themselves are declared by the packages that consume each field.
Each session's McpServer is now a MeasuredMcpServer whose registerTool wraps the callback at the MCP boundary, so what is measured is what the client experiences: argument and result bytes after parsing, redaction and routing, wall time including a forward to another window, and the outcome (ok, timeout read off the fence text, or error). A ToolMetrics ring per session feeds the new cmsis-developer-assistant://stats resource (per-tool totals for the session and the server instance plus the last 50 samples), a two-line trailer on get_session_status, one INFO line per call, and the optional JSONL file behind the new telemetry.jsonlPath setting (names and sizes only). The worker logs a matching control-op timing line; the real-board driver stores the statistics in its report. Covered by unit tests for the pure module and by the transport harness. Groundwork for measuring the response-size trimming (Open-CMSIS-Pack#18) and the agent evaluation runs (Open-CMSIS-Pack#27); closes Open-CMSIS-Pack#24.
Version 2.3.5 in package.json, SERVER_VERSION, TPIP and the provenance notes; CHANGELOG section for 2.3.5 (per-tool call telemetry, the stats resource, the get_session_status trailer and the telemetry.jsonlPath setting); rebuilt dist/extension.js.
The guide for harnesses that do not load skills arrived as one 21 KB block on every session. It is now sliced by marker comments a Markdown reader never sees: without a topic the tool returns a ~2 KB overview (the critical steps, the debugger-first rule) and the topic list; session, build, breakpoints, inspection, faults and troubleshooting return one section each. The guide gained a faults section (EXC_RETURN, the stacked frame, resolving BFAR, the usual cause per flag) and a build section (cmsis_action result line, long builds, flash, attach), and its inherited web-app root-cause examples were replaced by Cortex-M ones. Shipped docs are read once per server instance and also resolved from the repository root so the headless transport harness exercises the real guide. Closes Open-CMSIS-Pack#25.
The serialized tools/list a client receives at initialize is re-sent to the model on every turn, so its size is a per-turn cost. The per-call timeoutMs note is now one short line per tool with the rationale once in the server instructions; start_debugging, cmsis_action, reset, add_breakpoint, add_logpoint, flash and get_debug_instructions keep the trigger and the one caveat an agent needs at call time, with the reasoning moved to the cmsis-debug-live skill and the get_debug_instructions topics. The ten serial tools are registered only when the new serial.enabled setting is on, fixed per server instance so the tool list never changes between turns. The transport test asserts a byte budget for the list and a 700-character cap per description. Single-window surface: 33.2 kB → 26.7 kB. Closes Open-CMSIS-Pack#23.
Step, continue, pause and wait_for_stop returned the full debug state on every move — up to 50 frames and every breakpoint, pretty-printed — which is what drove repeated context compactions in long hardware sessions. They now return a compact state: location and frame ids, the top 5 frames with the rest counted, and the breakpoint list only when it changed since the last snapshot; the full snapshot still comes back when a session starts. read_memory defaults to hex. get_call_stack prints workspace-relative paths and collapses frames beyond 20 unless levels is given; get_threads lists up to 32. Variable listings without variableNames are capped at 40 per scope and 200 characters per value with a footer saying how to widen — with variableNames nothing is capped, and a redaction placeholder is never clipped. The recovery section after a motion timeout reads PC and LR instead of all 23 registers. Pure helpers in core/textBudget.ts; DebugState.toCompactString and the caps are unit-tested. Closes Open-CMSIS-Pack#18.
Agents asked "which bit in RCC.APB1ENR enables I2C1" or "what is at 0x40005400" and had to read the live register (needs a stopped session) or open the SVD themselves. Two read-only tools now answer from the device description without touching the target: the peripheral list, a peripheral's register map with absolute addresses, which peripheral and register sit at an address (turn a BFAR into I2C1.CR1, or name the SRAM/PPB region when the SVD has nothing there), and one register's bit fields with their enumerated values. The SVD is resolved from an explicit svdFile, the active session, out/**/*.cbuild-run.yml (pname picks the core) or a single workspace .svd, and the failure text lists every location tried. The parser reads addressBlocks, enumeratedValues and dim register arrays, keeps derivedFrom, no longer borrows a field's access for its register, and matches tag names whole. Unknown names get suggestions instead of the full name list; read_peripheral_register does the same and points at lookup_peripheral. Pure lookup module and parser covered by a hand-written fixture SVD; the tool list budget rises to 30 kB for the two tools. Closes Open-CMSIS-Pack#26.
Version 2.3.6 in package.json, SERVER_VERSION, TPIP and the provenance notes; CHANGELOG section for 2.3.6 (get_debug_instructions topics, the smaller tool list and serial.enabled, compact tool results, lookup_peripheral and lookup_register); rebuilt dist/extension.js.
Investigating a HardFault took an agent six calls in a fixed order and it often skipped the stacked frame or never resolved BFAR. diagnose_fault does the first pass in one call on a stopped target: the fault registers (one 24-byte SCS block read, word-by-word fallback), the stacked exception frame located through EXC_RETURN — PSP or MSP, basic or FP-extended — with the PC of the faulting instruction and its caller, the top frames, the faulting address resolved against the SVD or the Cortex-M system map, and up to three ranked hypotheses each with the next tool call: unclocked peripheral, null pointer, wild pointer, imprecise write, stack overflow with MSPLIM/PSPLIM, corrupted function pointer, missing Thumb bit, unaligned access, divide by zero, FPU off, bad VTOR. Sections after the fault registers degrade to a note instead of failing the call; without fault flags it returns a short stop context. The decoder is now structured (DecodedFault) with get_fault_info's text unchanged apart from the new STKOF and DEBUGEVT lines. Four long tool descriptions were shortened so the tool list stays within its budget. Pure triage and decoder modules are unit-tested. Closes Open-CMSIS-Pack#22.
Skill and tool changes were judged by feel. scripts/eval-scenario.ts runs a real Copilot CLI session against a planted bug in a small csolution with the cmsis-debug-live skill and the MCP server, and reports what it cost: tool calls by name with argument and result bytes, reasoning turns, wall time, the server's per-tool byte totals diffed from the stats resource around the run, and a verdict from the final answer against the expected root cause plus tool-call, turn and time budgets — infrastructure failures are reported as such. The fixture is the BSP Blinky example for the Corstone-300 FVP with the Arm-FVP target-set and the model shim (Docker on macOS); five deterministic overlays plant a divide by zero, an undefined instruction through a corrupted function pointer, an MSPLIM stack overflow, an unaligned access and an LED off-by-one with no fault. Opt-in only, never in npm test or CI; the pure logic — scenario validation, event aggregation, verdict, mcp-config edit — lives in src/core/evalScenario.ts and is unit-tested, and every shipped scenario file is validated by the suite. The skill-trigger script shares the Copilot CLI helpers. The fixture has not been built on the authoring machine (no cbuild there); the first run on a machine with the toolbox and the FVP is its validation. Closes Open-CMSIS-Pack#27.
cmsis_action only asked the CMSIS Solution extension whether a solution was active, never which target-type / target-set, and its result did not say — on a board + FVP or HE/HP solution a build or flash could go to the wrong context unnoticed. Every result now names the target it ran on and get_device_info reports the panel's target. The new optional `target` input (type or type@set, the csolution's names) selects one: a differing target is switched by writing the selection to .vscode/cmsis.json and re-activating the solution — the extension (1.70) re-reads the file on activation and exposes no command for this — and verified through cmsis-csolution.getActiveTargetSet before anything runs. Undeclared targets are refused with the declared list, an unverifiable switch with what was written and what the extension still reports, and a switch under a live session with a pointer to stop_debugging. src/core/cmsisTarget.ts holds the pure parts (reference parsing and matching, the target-types scan, the cmsis.json edit); the transport test drives the echo, refusal, switch and no-op paths against a stubbed extension. The build topic, the cmsis-debug-live skill, README and the acceptance test describe the input.
Version 2.3.7 in package.json, SERVER_VERSION, TPIP and the provenance notes; CHANGELOG section for 2.3.7 (cmsis_action target check and switch, the agent evaluation scenarios, diagnose_fault); rebuilt dist/extension.js.
The ten token- and round-trip-saving changes of 2.3.5–2.3.7 as one list under the 2.3.7 section, matching the v2.3.7 release notes.
A third extension-authored skill next to cmsis-debug-live and cmsis-help, always installed: add a board layer to an existing csolution by reading the packs and the csolution first, asking only the open decisions (scope, layer strategy, probe, STDIO transport, memory), then reusing the BSP layer, integrating the DFP's configuration generator when startup exists only as its output (the agent tells the user to run it — CubeMX, MCUXpresso Config Tools, Device Configurator, MCC), or writing a minimal bare-metal layer, and building to green. Hardware facts — register offsets, clock tree, VCP pins, errata — come from the pack documentation through the CMSIS Pack Docs MCP when it is installed, cited by document and page, cross-checked against the SVD. Registered as a bundled skill of the project category: the cmsis-project router's workflow points at it, cmsis-help lists it, the catalog test pins the three bundled entries, README and AGENTS name it.
Version 2.3.8 in package.json, SERVER_VERSION, TPIP and the provenance notes; CHANGELOG section for 2.3.8 (the bundled add-board-layer skill); rebuilt dist/extension.js.
…ets in From the experimental cmsis-pack-docs extension (0.13.1), as-is: the host-agnostic cores src/core/packDocs (target resolution from cbuild-run, pdsc <book> walking, Arm document catalogue and download, user and workspace document folders, pdftotext extraction, page store and BM25 index, peripheral dossiers over the SVD) and src/core/buildInfo (positioned ELF32 reader, GNU ld / armlink map parser, build-log diagnostics), the two handlers, the tool registrations, the panel (renamed PackDocsPanel), the 16 shipped Cortex-M core-peripheral SVDs with their generator, the cmsis-pack-docs skill, and the 22 test suites with their fixtures. Two adaptations so the move compiles here: the tool files call a PackDocsDispatch instead of a handler (src/packDocsDispatch.ts — the pack-docs counterpart of SerialDispatch, so the same registration serves the single-window and the routed case), and the op table gains PACKDOCS_DOC_OPS / PACKDOCS_BUILD_OPS with compile-time coverage of the handlers' handle* methods; the five documentation ops carry the ten-minute forward floor because indexing a manual takes minutes.
…outer Ten tools, off by default behind cmsis-developer-assistant.packDocs.enabled and buildInfo.enabled (fixed per window like serial.enabled): the server registers the groups only when a gate is on and the session has a dispatch, and its instructions gain one sentence per enabled group. Every window builds the handler pair at activation and hands it to its control server, whose dispatch is now three-way (serial, pack-docs docs/build, debug); the routing handler forwards packDocsOp like serialOp, so a documentation lookup runs in the window that owns the workspace. The enabled list is 55 tools / ~41 kB against its own 42 000-byte budget; the default list is unchanged at 45 tools under 30 000. Settings packDocs.* (extractor, pdftotextPath, maxPdfMb, includeUnlisted, workspaceDocDirs, userDocsDir — default ~/.cmsis-pack-docs/user so imported documents stay attributed) and buildInfo.* (maxSymbols, logGlobs) apply live; the gates prompt for a reload. Commands: List / Index Target Documentation, Import Document for Current Target, Open User Documents Folder, Open Pack Docs Panel. Activation warns when the standalone extension is still installed. cmsis-pack-docs is the fourth bundled skill (bring-up); cmsis-debug-live and add-board-layer point at the built-in tools instead of an external MCP, cmsis-help lists the two groups, commands and settings. Tests: the op table, a control-server round trip to the right handler and the refusal of a window without handlers; the transport harness measures the all-on list and the no-build answers; the packaged-VSIX check verifies the SVDs and the skill ship. README, AGENTS, docs/architecture/packDocs.md, the server architecture note, the provenance notes, the acceptance test and the changelog describe it.
With the documentation tools on, the MCP instructions now say to use them before asking the user for a datasheet or manual and instead of reading a PDF into context: a document the user provides goes into the workspace docs/ folder or through Import Document for Current Target and is searched. With the tools off — the default — the instructions name the packDocs.enabled setting, so an agent on a default install suggests it rather than asking for documents or opening PDFs itself. The same rule sits in the cmsis-pack-docs, cmsis-debug-live and add-board-layer skills, and the build topic of get_debug_instructions replaces its "check the documentation in the CMSIS Solution UI" advice with the tools. The transport test asserts the default instructions carry the pointer.
…lution Field feedback: an agent with the documentation tools went to the web for an ADC datasheet that was already indexed as a user document, because nothing said the user and workspace folders are for third-party parts, a part number reads like a web lookup, and the first correct call resolved a fixture's cbuild-run in the same workspace. Now the MCP instructions, the tool descriptions and the cmsis-pack-docs, cmsis-debug-live and add-board-layer skills say that sensors, ADCs, codecs and other third-party parts are documented the same way: any part number starts at list_target_docs, an unlisted datasheet is fetched by URL with fetch_doc (the web finds the URL, the tools read the document), and a PDF the user provides goes into docs/ or through Import Document for Current Target. The build topic and README say the same. Target resolution asks the CMSIS Solution extension for the active csolution and target-type (PackDocsHost / BuildInfoHost.activeContext) and picks that context when the workspace holds several solutions, noting the choice; `target` still wins, a hint that matches nothing keeps the ambiguity error with the active context named, and a failing extension is ignored. Covered by resolver tests for both cores. The e2e suite now uses a private user documents folder instead of the developer's real one. docs/improvement-notes.md records the field note as item 10.
search_target_docs ranked pages by BM25 over the body only; the heading was a post-hoc boost on pages the body had already returned, so a register page whose body speaks of bits and never repeats the description words was not a candidate. The heading is now a second indexed field (DocIndex version 2, headingPostings) scored at weight 5 on top of the body, the old ×3 post boost becomes a 1.5 tie-breaker, and an older index is rebuilt from the persisted pages on first load — no re-extraction. scripts/search-benchmark.ts (npm run bench:search) makes ranking changes measurable: gold pages are the manual headings that name a register, the queries come from the SVD descriptions, and it reports R@1 / R@3 / MRR per heading weight and post boost. RM0455 × STM32H7B3.svd: description-only queries MRR 0.621 → 0.741 (R@1 49.5 % → 64.5 %), description plus register name 0.873 → 0.994 (R@1 78.1 % → 98.8 %). Tables in docs/improvement-notes.md §11. Issue Open-CMSIS-Pack#29 part 1.
packDocs.extractor gains pdfjs and auto now means pdf.js (legacy build, pure JavaScript, loaded on first use), so a machine without pdftotext — most Windows hosts — indexes documents too. Lines are rebuilt from pdf.js text items by baseline, wide horizontal gaps become double spaces so register table columns stay separable, and the tokenizer applies NFKC so ligatures and full-width forms from either extractor meet on one term. A document extracted by the other extractor is re-extracted on its next use. VS Code's extension host is Electron and pdf.js does not take it for Node, so GlobalWorkerOptions.workerSrc points at the shipped worker module (re-included in the VSIX by .vscodeignore) and pdf.js runs it as a fake worker on the same thread; the packaged-VSIX check asserts the file ships. Gated by the search benchmark on RM0455 with the heading field on: pdf.js MRR 0.739 / 0.995 against pdftotext 0.740 / 0.994, 2 965 pages in 3.9 s. bench:search can extract a PDF with either extractor (--pdf, --extractor, --save). +0.8 MB in dist/extension.js; TPIP entry added. Issue Open-CMSIS-Pack#28.
An identifier-only query gains the words of its SVD description at half weight: a peripheral instance (USART1) brings its type synonyms and description, a bare field name (GPIOAEN) brings the register it lives in and the field's description, so the manual is found even when it never spells the identifier. Expansions never gate the all-terms boost and the result says what was expanded. Register names, prose and quoted phrases are left alone. The benchmark (now with a third set, the bare register name) showed expanding register names or the acronyms inside a sentence only dilutes the ranking — two points on description queries, 0.3 on bare register names — while the heading field already puts register pages first (R@1 98.2 % for the bare name). With the restriction all three sets are unchanged; the tables are in docs/improvement-notes.md §11. Issue Open-CMSIS-Pack#29 part 2.
assets/DebugMCP.webp (9.7 MB) was referenced by nothing and shipped in every package since the fork — 70 % of the VSIX; assets/DebugMCP.mp4 (15 MB) was excluded from the package but kept in the repository; assets/architecture.svg was an unused rendering of the diagram the README shows as PNG. All three are removed. The extension icon is 256 px instead of 1024 (1.4 MB → 52 KB). The design notes under docs/ no longer ship — only docs/agent-resources, which the MCP resources read, does. Packaged VSIX: 13.95 MB → 3.19 MB; the packaged-VSIX check still finds everything the runtime needs.
Every packDocs.* and buildInfo.* setting carries VS Code's experimental tag, so the Settings UI shows the badge and the Experimental filter finds them; the two .enabled descriptions say so first. README and the generated cmsis-help label the documentation and build-artefact tool groups the same way.
A Commands section between Getting Started and Agent Tools describes the seven palette commands — agent/skills setup and the five documentation commands — and the overview bullets point at it.
The same media/arm.png the other Arm extensions ship (CMSIS Solution, CMSIS Debugger, Keil Studio Pack, Device Manager) replaces the icon inherited from DebugMCP.
…egible on dark themes The How It Works picture gains the documentation retrieval box — pack PDFs, user and workspace documents and fetch_doc downloads through pdf.js into the page store, the search tools answering from it with the SVD joined in — and is rendered on an opaque background: the previous PNG was transparent with black labels, which vanish on the dark extension page. npm run diagram regenerates it from the Mermaid source with a local Chrome (scripts/puppeteer.json). The README explains the window routing and the documentation path in two paragraphs.
…efault Select Agent Skills (and step 2 of the setup) first asks where the AI Skills Pack goes. This workspace only — the default — copies the selected pack skills into the project's .agents/skills (and .claude/skills when Claude Code is installed or the project has a .claude directory), next to the sources, to commit or ignore; a skill in the personal directories is offered to the agent in every project and its description costs context there whether the project is CMSIS or not, a project skill is loaded only where it applies. This user keeps the previous behaviour. The choice is the target of the installedSkills setting, whose scope changes from application to resource: the User value drives the personal directories, a Workspace or Folder value the project's, each folder of a multi-root workspace from its own, so a selection checked out in .vscode/settings.json is applied on activation like one from Settings Sync and removing it sweeps the project copies. A project selection carries the pack skills and their hidden dependencies only — the extension's own skills stay personal — and a project without a selection never gains an empty .agents/skills. The installer takes its roots per sync, adding a folder to the workspace syncs it, and the install prompt counts a pack skill picked in either scope.
…erns hid src/core/buildInfo/buildLog.ts matched the Visual Studio pattern [Bb]uild[Ll]og.* in .gitignore, the build-log test fixtures matched *.log and the Arm document-catalogue fixtures under src/test/fixtures/packdocs/arm matched [Aa][Rr][Mm]/ — all inherited from DebugMCP and meant for build output. The files existed in the working copy, so every local build and test run passed while the pushed tree did not compile (CI for v2.3.9: "Cannot find module './buildLog'"). Negations keep the original patterns and track the four paths.
…n isolation The first CI run of the documentation and build-artefact code (it came in after v2.3.8 and was only ever run on macOS) failed on the Windows runners and, in one test, everywhere. Workspace-relative paths in the list_build_artifacts, get_memory_usage, get_build_diagnostics and list_target_docs results now use forward slashes on every platform — the agent copies them into commands, and the tests assert them that way. The tests themselves stop assuming POSIX: absolute expectations go through path.resolve (drive letter on Windows), the temp directory is escaped properly before it is put into a RegExp (the old character class was mis-parsed and escaped nothing, so C:\Users became C:Users), and the user-document folders named with glob characters are skipped on win32, where * and ? are not legal in file names. The end-to-end suites build their fixture workspace in suiteSetup, which takes longer than mocha's 2 s default on the Windows runners: the test config sets 20 s. The fetch_doc test asserted that the fetched document ranks Open-CMSIS-Pack#1 for VECTRESET when searched without a doc filter. VECTRESET is identifier- shaped, so the SVD expansion adds its description words and the "1 Debug" heading page can outrank p.2 depending on what else the store has indexed — the test passed only after the earlier tests of the suite had filled the store. It now asserts presence; the ranking is covered by the search tests.
The installer stages a skill as .<name>.tmp-<pid> next to its destination and renames it into place. A process that dies between the two — an extension host killed during a sync, which every interrupted test run is — leaves the staging directory behind, and Claude Code and VS Code list it as a skill named ".cmsis-pack-docs.tmp-25348". Five of them had accumulated here. installOne now removes every .<name>.tmp-* directory of the skill it is about to stage; other dot-directories are still left alone.
readdir order is a property of the file system: NTFS lists boards/ and cores/ before Keil/ (case-insensitive), APFS and ext4 the other way round. The order of the matched list is informational; the test compares the sorted lists.
Dependabot's bump of typescript to 7.0.2 (Open-CMSIS-Pack#35) cannot install: @typescript-eslint/eslint-plugin declares typescript ">=4.8.4 <6.1.0", and TypeScript 7.0 — the native compiler — ships no programmatic API for it to load anyway. The TypeScript 7.0 announcement's side-by-side setup resolves both: @typescript/native (an alias of typescript@7) provides tsc for compile, check-types and the test build, and the typescript package resolves to @typescript/typescript6, the TypeScript 6 API, which typescript-eslint 8.69 supports. The lint plugin and parser move from 8.56 to 8.69. TypeScript 6.0 stopped including every @types package it finds; the sources rely on the node, mocha and vscode globals, so tsconfig.json names them — the only change either compiler asked for: with it, 7.0.2 type-checks the tree with no errors. Verified with the new lockfile from a clean npm ci: check-types, lint, build, 415 unit tests, both transport suites, package and the packaged-VSIX check. The shipped bundle is unchanged — esbuild does not use tsc.
Two housekeeping actions in the Store tab, kept apart because they answer different needs: "clear extracted text…" removes every document's pages, metadata and search index across the store and prunes the emptied directories — downloads and fetch records stay, so a fetched document is still fetched and everything is extracted and indexed again on its next use (after an extractor switch, a suspect index, or to reclaim space); "delete downloaded PDFs…" removes the arm/ and web/ trees fetch_doc filled — PDFs, fetch records and their extraction — so those documents are offered as "not fetched" again. Each asks first: a modal confirmation names the documents, files and megabytes it is about to remove, computed by the new PageStore.storeUsage(). clearExtracted() and clearDownloads() drop the store's in-memory page and index caches, and the handler forgets its chapter cache. The panel shows the outcome in its status line and refreshes the Store and Target tabs. Covered by a pageStore test that sets up a pack document and a fetched Arm document and checks what each clear removes and keeps.
main brought zod 4.5.2, semver 7.8.5 and @types/express 5.0.6 (dependabot); the tree runs on them unchanged — 416 tests, both transport harnesses, the packaged VSIX. TPIP.md regenerated; dist rebuilt with zod 4.
MatthiasHertelArm
force-pushed
the
pr/2.3.5-ai-efficiency
branch
from
September 1, 2026 12:56
c937ca1 to
3f04c50
Compare
…linter" This reverts commit 0f93a5b.
pdf.js refuses to start when Array.prototype or Object.prototype carries an enumerable property, and the extension host is one process shared by every extension — the CMSIS csolution extension assigns Array.prototype.groupedBy, so every extraction died with "The `Array.prototype` contains unexpected enumerable property" and nothing could be indexed or searched. PdfjsExtractor now drives a worker_threads worker (pdfWorker.ts, bundled as dist/pdfWorker.js by a second esbuild entry point): a fresh realm no other extension can patch. The thread starts on the first document, is kept for the next, retired after a minute idle, and terminated when an extraction times out — which now stops pdf.js mid-document instead of waiting for the next page boundary. Where pdf.js detects Node it presets workerSrc to "./pdf.worker.mjs" beside pdf.mjs — which exists in node_modules, where the tests run, but not beside the bundle once esbuild has inlined the library. The worker therefore sets the shipped pdf.worker.min.mjs unconditionally, and the packaged-VSIX check now runs an extraction through the packaged dist/pdfWorker.js, the only place that class of bug is visible. itemsToPageText moves to pdfText.ts, shared by the worker and the tests. New tests cover extraction under a patched Array.prototype, a timeout followed by a fresh extraction, and a missing file.
The target picker — a cbuild-run context or pack + device — moves into a header shared by every tab, with the resolution and core under it, since it drives them all. The former Target tab, which stacked the SVD browser above the document list, splits into Documents (every document the tools see for the target, its state, and the fetch / index / browse / search actions) and Peripherals (the device SVD, the Arm core peripherals and the NPU as groups, instances and bit views); Store becomes Page store — what is extracted and indexed on disk across all targets, its header now on three short lines instead of a wrapping path — and Tools stays. Each tab carries a count and a tooltip and opens with a one-line description of what it shows; the header stays put while the active view scrolls, and nothing refers to "the Target tab" from other tabs any more. A tab saved by the old three-tab layout opens as Documents. Regenerates the bundle: dist/extension.js with both this and the worker thread, plus its new sibling dist/pdfWorker.js.
soumeh01
approved these changes
Sep 2, 2026
This was referenced Sep 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes
diagnose_fault: one-call fault triage instead of six round trips #22, Trim thetools/listpayload: shared timeout note, shorter descriptions, opt-in serial tools #23, Per-tool call telemetry: count, bytes, duration, timeout/heal flags #24,get_debug_instructions: return the relevant section instead of the whole 21 KB guide #25,lookup_peripheral/lookup_register: answer SVD questions without touching the target #26, Agent evaluation scenario: measure tool calls, iterations and payload per debug task #27 — theai_efficiencyset (2.3.5–2.3.7)search_target_docs: heading field and SVD expansion (2.3.9)Changes
Thirty-six commits on top of
main(rebased onto the currentmain—aecf4dc, with the dependabot bumps to zod 4.5, semver 7.8 and typescript-eslint 8.68 — plus a commit regenerating TPIP and the bundle). Version 2.3.9 — please cut it as a pre-release from the merge (odd minor ⇒scripts/package.tspackages with--pre-release). The same content is published as v2.3.9 on the fork with CI-built VSIX for the five platforms; the fork's v2.3.5–v2.3.8 pre-releases are the intermediate steps. Per-version detail in CHANGELOG.md.AI efficiency (2.3.5–2.3.7) — the
tools/listpayload every agent turn carries −20 % (33.2 → 26.7 kB; a 30 kB budget and a 700-char description cap are asserted in the transport test),serial.enableddrops the tenserial_*tools entirely;get_debug_instructionsserves the guide by topic instead of one 21 kB block; compact motion state (location, frame ids, top frames, breakpoints only when changed) and capped listings;diagnose_faultreplaces the ~6-call HardFault loop with one call (fault registers, stacked frame, address resolution, ranked hypotheses);lookup_peripheral/lookup_registeranswer from the SVD without a session;cmsis_actionnames the target it ran on andtargetswitches/verifies it; per-call telemetry (cmsis-developer-assistant://statsresource,get_session_statustrailer, optional JSONL) and an eval-scenario runner that scores an agent's run against tool-call, turn and time budgets.add-board-layerskill (2.3.8) — add a board layer to an existing csolution by interview: reads the csolution, the DFP/BSP pdsc and an existing layer first, asks only the open decisions, then reuses the BSP layer, integrates the DFP's configuration generator, or writes a minimal bare-metal layer; builds to green and hands over tocsolution-retarget.Documentation and build-artefact tools (2.3.9) — the experimental CMSIS Pack Docs extension moved in as-is:
list_target_docs,search_target_docs,read_doc_pages,fetch_doc,get_peripheral_docsandlist_build_artifacts,get_memory_usage,lookup_symbol,get_section_layout,get_build_diagnostics— off by default behindpackDocs.enabled/buildInfo.enabled, tagged experimental in the settings, routed like every other op across windows. PDFs are extracted with a bundled pdf.js so Windows hosts without poppler index too (#28); BM25 indexes the page heading as a weighted field and expands identifier-only queries from the SVD (#29; on RM0455 description-only queries R@1 49.5 % → 64.5 %, measured with the newnpm run bench:search); the MCP instructions and skills tell agents to search the documentation instead of asking for it. Five palette commands and a Pack Docs panel;cmsis-pack-docsships as a fourth bundled skill.Skills into the workspace (2.3.9) — Select Agent Skills first asks where the AI Skills Pack goes: This workspace only (the default — a skill in the personal directories is offered to the agent in every project and costs context there; a project skill is loaded only where it applies;
<workspace>/.agents/skills,.claude/skills) or This user (as before). The choice is the target of theinstalledSkillssetting, whose scope changes fromapplicationtoresource; each workspace folder syncs from its own value, a project selection carries pack skills only, and a project without one never gains an empty.agents/skills.Pack Docs panel: clear the store — two actions in the Store tab, each behind a modal confirmation that names the documents, files and MB involved: clear extracted text (pages, metadata and indexes of every document; downloads stay, re-extracted on next use) and delete downloaded PDFs (the
arm/andweb/treesfetch_docfilled; those documents show as "not fetched" again).PageStore.storeUsage()/clearExtracted()/clearDownloads(), tested.Also — the Arm logo as the extension icon; VSIX 13.95 → 3.19 MB (unused media dropped, icon 256 px); the architecture diagram shows the documentation path and renders on dark themes; README Commands section.
Screenshots
n/a — the one new UI element is a two-item quick pick (This workspace only / This user) ahead of the existing skill picker.
Checklist
npm test); both transport suites (npm run test:transport);npm run package+test/transport/packaged-vsix.json the rebased head.cmsis_actiontarget switch on a two-target solution (verified against the CMSIS Solution 1.70.0 bundle and a stubbed transport test only).localhostonly;fetch_docdownloads a PDF from a user- or agent-supplied URL into the extension's global storage (size-capped bypackDocs.maxPdfMb), nothing leaves the machine; credential-shaped values stay redacted.docs/architecture/*, the generatedcmsis-helpskill.pdfjs-dist6.3.289 (Apache-2.0) added;TPIP.mdregenerated for 2.3.9.