Release notes

IndyKnow

Release notes

Every build, newest first. The current published build is 1.9.10.

Server update — 2026-08-20

Stops printing questions being answered against the wrong copy of the printing code. Server-side only — nothing to reinstall, and no new version to install.

  • Printing questions now establish which program you are actually running, before diagnosing anything. There is not one event-printing program — there are three, each with its own copy of the same core file, and they were deliberately made different from one another: the standalone background printer, the copy built into Web-Tier Tools, and the one inside the template designer. A plausible-looking answer read off the wrong copy is simply wrong, and until now nothing made IndyKnow check. It now names the three, works out which one applies, and — when it genuinely cannot tell — leads with the assumption it made instead of burying it halfway down a debugging plan.
  • It can often answer the Web-Tier Tools question from the database instead of asking you. Where a database is connected, IndyKnow checks the setting that actually controls this, resolving it the same way the product does: per branch where the system is in vendor/branch mode, per user and location otherwise. That distinction matters, because the setting is rarely uniform — on one live system exactly one branch of ten has it switched on. When the rows disagree, IndyKnow says the setting is per-branch and asks which one the ticket concerns, rather than averaging them into a confident wrong answer. It also states plainly that a "no" never proves the negative, since a file on the workstation can override it.
  • The standalone printing program is readable at all now. It had never been added to any of the indexed code, so the most common printing lane was invisible to search — the one thing that made the question above unanswerable even when someone asked it.
  • The grouped module and service collections can actually be read on the hosted service. Six collections are deliberately views over a single downloaded copy of one large repository rather than six separate copies. The hosted service is told where that copy lives, but the setting named only one of the six — so the other five went looking in a folder that exists on a developer machine and not on the server, and quietly answered "no source" for every request. A location set for any collection in a sharing group now applies to the whole group, and a group configured with two conflicting locations refuses to start rather than letting half of it read the wrong disk.
  • Files that share a name across bundled programs are no longer hidden. Two of the code bundles group dozens of small standalone programs together, and each of those programs legitimately ships its own main, its own settings. IndyKnow filed code by filename, kept one, and silently dropped the rest — 69 files unreachable, including the print-server code its own guidance tells you to compare side by side. Everything is reachable now: ask for a name that is unique and nothing changes, ask for one that is shared and you get the list of candidates instead of an arbitrary pick, and you can request an exact file by its path. Listing files also now shows form and project files, which it never did before.

1.9.10 — 2026-08-18

Answers a question the version list couldn't before: "is this already fixed for the upcoming maintenance release?" Two development branches grow in parallel — the next major release, and the next maintenance build — and until now only the first was visible. The capability is server-side; this extension update only refreshes the in-chat tips, so existing installs pick the feature up as soon as the backend is deployed.

  • A new selectable version: latest-mr. The version list now shows the maintenance-release track alongside latest and the numbered releases, with a one-line explanation of how the two tracks relate. Select it and your code questions resolve against exactly what the next maintenance build will contain.
  • "Which version has this fix?" now covers the maintenance track. The version verdict gains a row for the maintenance branch — present or not, never omitted — and when a change hasn't reached any numbered release but is already on that branch, the answer says so outright: already fixed for the upcoming maintenance release, rather than implying it only exists in next-major development. Fixes carried onto the branch are recognized even though they ship there under a different commit identity.
  • Everything version-aware respects the new track. Switching to it warms its code index like any pinned version, repositories that require the next major correctly report as out of reach while pinned there, and proposing a fix while pinned to it is refused the same way as at any older pin — fixes always target the current development tip.

1.9.9 — 2026-08-18

Stops Claude-authored scripts and certificates from failing silently. This is an extension update — install the new .mcpb (or reinstall from file) and restart Claude Desktop. The backend is unchanged; nothing to deploy on the API.

  • The traps that ship wrong data or hang an alarm now live on the tools. list_script_functions already printed gotchas; it now includes the ones power users hit in production: SQL errors coming back from ReturnFromSQL as the string value, ShowMessage hanging an unattended/scheduled run, SYNC_ACTIVE not being a boolean, After Finish / OUTEQUIP_NUM, CURRENT_CUSTOM_FIELD vs CUSTOM_FIELD, and EVENT_DATE compared to today returning zero rows. A session without the downloaded Desktop skills still sees them.
  • CreateCustomReportWait is on the Common list — both overloads. Alarm/report scripts call CreateCustomReportWait (10 arguments) and CreateCustomReportWaitCcBcc (12). Both exist in the product and both now appear for every scripting context. Blank sPrintTo / sFileName still means the report never renders and the email never sends — that is now stated on the tool, because it is a silent no-op.
  • validate_script lints before you write. New local tool: unknown functions against the list_script_functions allowlist, dialect mix-ups (double-quoted SQL in Pascal, and the reverse), ungated ShowMessage, and a SELECT-only dry-run of ReturnFromSQL / RunSQL / tdDoSQLRecords literals on a local database. Write SQL extracted from RunSQL is reported and never executed. edit_project_script / edit_custom_rule run the same checks and still write unless you pass strict: true.
  • RAP on a print template can be edited. edit_print_template has a new set_rap op that replaces the source of an existing handler (report/programname, the same identity detail:"rap" already prints). It will not create a new handler — add the empty one in PrintBuilder first. Line endings of the handler being replaced are preserved.
  • Pipeline aliases are a tool, not a guess. list_pipeline_fields maps pEVENTS / pCALPNTS / pTRACE2 / pSTICKERS to raw column + RAP alias (GAGE_SNI.D.). read_print_template with detail:"rap" annotates each Events['I.D.']-style read with the raw column, or notes that an unknown alias prints blank.
  • Embedded images report print DPI. read_print_template (and replace_image / add_image) now show pixel size, print size, and DPI from the PNG/JPEG headers and the object's millimetre geometry. Below about 300 DPI you get a one-line "will look soft" note. Images are not transcoded.
  • MagicSQL / custom-report blobs warn instead of looking like a cert. If the template contains TdaSQL / TdaQueryDataView, read / edit / import lead with a hard warning: MagicSQL regenerates SQL from its field/table model, so editing SQLText does nothing. Ordinary CERTIFICATES / STANDARD templates do not show it. There is still no set-SQL op.

1.9.8 — 2026-08-10

Restores bug reporting, stops a fix being proposed against code you are no longer looking at, and fixes four problems found while using the new history answers against the real repositories. Server-side only — nothing to reinstall.

  • Bug reporting works again. Filing a bug, searching existing ones, and adding to an open one have all been unreachable from Claude since shortly after they were built: the tools were connected to an older internal address that the connector stopped using a few days later. Nothing was removed and nothing was lost — the wiring simply never moved across. Ask Claude to report a bug, search for one, or add detail to an existing one, and it works as originally intended.
  • Bug reports can now cite code from every repository you can see. Supporting code attached to a report used to resolve against a single repository, so a report citing files from more than one quietly lost all but one of them. Every repository you have access to is now searched, and only those — evidence is never pulled from a repository your account cannot reach.
  • Proposed fixes are locked to the latest build. A fix is always applied to the current tip of a repository, so one written while viewing an older release could fail to apply — or, worse, still apply and change the wrong thing. Submitting a fix while an older version is selected is now refused outright, before anything is copied or created, with a message explaining how to switch back. The same rule covers repositories that did not exist in the selected version.
  • Asking by pull request now gives the same answer as asking by work item. Looking up a change by its pull-request number could report that no release carried it, while looking up the same change by its work item correctly reported the release it shipped in. The cause is worth knowing, because it also explains why the number alone is a weak thing to search for: when a fix is carried into a release line, the release records the carrying pull request, not the original one. IndyKnow now resolves a pull-request number to the work item behind it and answers on that, showing both — so the two routes agree. Where a pull request names no work item, the answer says what it actually searched instead of asserting the change never shipped.
  • Symbol history now accounts for every commit it looked at. Asking for the history of one routine could return, say, eight changes out of twenty-five commits with no explanation of the other seventeen — leaving no way to tell "this routine has been stable for years" from "this routine didn't exist yet". Both now appear as their own counts, and the three ways a page can come back empty — the routine exists but nothing here touched it, the routine didn't exist yet, or you've paged past the end of the history — now read differently instead of sharing one ambiguous sentence.
  • Pull-request search can no longer hang. Searching pull requests fetched each one and then its review discussion, one after another, with no time limit — enough to exceed the client's timeout on a first search. It now runs several at a time, loads review discussion only for the pull requests that actually match, and works to a fixed time budget: if it runs out, you get what it found plus a clear note that the list is partial, rather than a stalled request. Free-text searches no longer match against review comments; that's stated in the results, and matching pull requests still show their discussion.
  • The first question after a restart is no longer the slow one. The branch history each answer reads is now prepared in the background shortly after the service starts, instead of being built by whoever happened to ask first — which on a cold service could take long enough to time out and need retrying.
  • Release counts now say what moment they describe. Two answers minutes apart could legitimately disagree on how many releases a line contains, because the branch list is re-read as it changes. The count now carries the same as-of timestamp already shown alongside it, so a number that moves reads as current rather than contradictory.

1.9.7 — 2026-08-10

Adds the history axis — a third way to ask about the code, alongside "what does it say" and "which version am I reading". It answers which shipped release actually carries a fix, and why a line of code exists. Server-side only — nothing to reinstall.

  • "Which version has this fix?" now has a real answer. Ask about a work item or a pull request and IndyKnow reports the release it first shipped in, how far it carried, and — the part that usually gets missed — which releases and which entire release lines never received it. That backport gap is the blast-radius answer, so it's stated outright rather than left to be inferred from a list. A "not found" is never bare either: it always says which repositories were searched and how current they were, and it states that feature branches aren't searched, so the bound on the answer is never silent.
  • Why a line of code exists. A new developer-only tool walks a file's history — or the history of one routine, method, or type inside it — newest first, with the work items and pull requests behind each change. The symbol is re-resolved by name at every commit rather than tracked as a line range, so a routine that moved still reports its true history instead of whatever drifted into its old position.
  • Answers stay current without waiting on re-indexing. These answers read the repository's branches directly, so they refresh within minutes on demand instead of inheriting the much slower code-indexing cadence. A fix merged last week no longer reads as "not present". If a refresh can't run, the answer still comes back — stamped with how current it actually is, plus a one-line warning — rather than failing.
  • Support tier included. The version verdict is available to the support tier, since "which version has the fix" is exactly the support question; it returns the verdict alone, with no source-level detail. The file-and-symbol history tool is developer-only.
  • The pull request behind the change. The version answer now also shows the pull request that carried a fix — its title, the linked issue, and its cherry-pick trail. That trail is the reason a fix can ship in five releases under five different identities, and it's recorded nowhere in the commit history itself. A new developer-only tool searches those pull requests by ticket, id or free text. Where a pull request has no human review discussion — which is the norm here — the answer says so plainly instead of returning an empty result that reads like a failed search.
  • A data-quality check on release records. The answer now compares what the issue tracker claims a fix shipped in against what the release branches actually contain, and flags disagreement either way — naming what each side claims and stating that the branches are the authority, since the tracker field is maintained by hand. On the very first ticket checked, the tracker named a release no branch carried. The support tier sees this flag too.
  • Enrichment never becomes a dependency. If the pull-request service or the issue tracker can't be reached, the answer is still delivered in full from the release branches, with a one-line note — never a failed request.

1.9.6 — 2026-08-10

Adds contributor fix pull requests — a way to go from finding a bug to proposing the one-line fix without leaving the chat.

  • Propose a fix as a draft pull request. Users holding the new contributor role can ask Claude to submit a small, mechanical bug fix: it shows the exact diff and its reasoning in the chat first, then IndyKnow applies the edits to a fresh copy of the repository at its current head, checks them, pushes a branch, and opens a draft pull request labelled for review. Only the pull-request link comes back. Every fix is reviewed by a developer, who can reject or rewrite it freely — nothing merges on its own, and the pull request says plainly that a model drafted it.
  • Every proposed fix says where it came from. A submission has to name the customer or site that hit the problem and the exact scenario it happened in — what was being done, on which screen, with what data — and the environment number is stamped on from the signed-in session rather than typed in. All of it leads the pull request description, so the reviewer knows why the fix exists before they judge whether it's right, and the description states plainly that IndyKnow opened it and who asked for it.
  • Edits are exact, and self-correcting. Each edit is a literal find-and-replace that must match exactly once. If the text has moved on since Claude read it — or matches in more than one place — the current file content comes straight back so the fix can be corrected and re-submitted in the same turn, instead of failing with a dead end.
  • Mechanical guardrails, checked against the real change. Every submission is judged on what it actually changes, not on how it was described: at most 10 files and 500 changed lines, no CI or pipeline files, no database schema changes (including schema statements hidden inside ordinary source), no dependency changes, no connector manifests, no deletions or binary files, new files only where tests live, and a scan for credentials in added lines. A rejected submission names every rule it broke, with the file and line, so one round of corrections is enough.
  • Opt-in per repository, and invisible without the role. A repository accepts fix pull requests only when explicitly configured for it, and IndyKnow's own repository never does. Users without the contributor role don't see the tool at all. whoami now shows contributors which repositories accept fixes.
  • Bounded by design. Submissions are rate-limited per user, and a throttled attempt does no work at all — no copy of the repository, no branch, nothing on the remote. Every submission is recorded server-side with who submitted it, which repository, and the outcome.

1.9.5 — 2026-08-06

Teaches IndyKnow the names you gave your custom fields, so you can ask about them the way you already talk about them — and corrects a case where equipment identifier questions could be answered from the wrong column.

  • Your own field names, understood. Equipment and company records carry a pool of general-purpose custom fields, and most sites rename them to something meaningful — a cost centre, a purchase order number, an owning department. IndyKnow now reads those names straight from your database and uses them. Ask about "Cost Center" and it goes to the right field first time, instead of working through the generic ones looking for a likely match. Nothing to configure: it picks up whatever your site has already named, including the built-in names for identifiers, crib and bin numbers, and the status fields. Where a field is used as a yes/no marker rather than free text, IndyKnow now says so, so it won't try to match text against it.
  • Multi-site naming is handled. If two companies in the same database have given the same field different names, IndyKnow reports both and which companies use each — so a question phrased in one site's vocabulary can be answered against that site rather than blurred across all of them.
  • Equipment identifier questions now resolve to the right field. The equipment identifier and serial-number fields carry default display names that are the reverse of what the underlying column names suggest. IndyKnow previously followed the column names, so a question about a serial number could be answered from the identifier field instead — returning results that looked correct. It now follows the same names your client screens show, and flags the pairing explicitly so the two are never transposed again.
  • Partly-renamed fields still work. Where only some sites have renamed a field and the rest kept the standard name, IndyKnow reports both and who uses which, rather than picking one and hiding the other.
  • Quiet by default. Fields nobody has named are left out of the picture entirely — they stay fully searchable and queryable, they simply don't clutter every answer.
  • The same behaviour on every database you connect to. Field names are read the same way whether you're pointed at a hosted environment or a local SQL Server slot, so an answer doesn't change shape depending on which connection it came from.
  • Renamed a field since you started? Names are read once per database and then remembered for the session. If you rename one in the client and want IndyKnow to see it straight away, run refresh_local_sql_schema — the same refresh that reloads the rest of the database structure.

Includes an extension update — install it to pick up the local-database half.

1.9.4 — 2026-07-27

  • Reliable local database connections. Keeps local database connections fast and dependable on trusted local slots — no stalls or query timeouts. Modern servers are unaffected, and there's nothing to change on your database; the fix ships in this extension update.

1.9.3 — 2026-07-24

Fixes the intermittent "failed to connect" at Claude Desktop startup that made some installs need repeated reconnects before the tools appeared, and deepens coverage of the calibration desktop application.

  • Fast, dependable startup. IndyKnow now ships pre-bundled: starting the extension reads a handful of files instead of walking thousands of dependency files, which on a cold machine (antivirus scanning, several extensions starting at once) could take long enough that Claude Desktop gave up and showed the extension as disconnected — reconnecting only worked because the second try hit warm caches. Startup now completes in about a second and a half, well inside Claude Desktop's startup window, cold or warm.
  • A smaller download. The extension package drops to roughly a quarter of its previous installed footprint (about 12 MB packed), which also makes installs and updates quicker to scan and unpack.
  • Startup health is now visible and guarded. Each start records how long it took in the diagnostic log, and every release is now smoke-tested against the exact packed artifact: the handshake must complete inside Claude Desktop's startup window and the extension's protocol stream must stay clean, or the release fails before it ships.
  • Deeper coverage of the calibration desktop suite. IndyKnow now indexes the helper applications the main desktop app launches — the gage-studies statistics (bias / R&R / uncertainty), the specification manager, and the wider suite of report, editor, sync, import, and instrument-logger utilities — as directly-addressable repositories (repo:"gagestudies", repo:"specmanager", repo:"calmodules"). This closes a long-standing gap where source living in those sibling apps (rather than the main app) couldn't be found by search — only opened by exact path. They're built on first use so they never slow startup, and stay out of broad repo:"all" searches unless you target them by name. Server-side only — nothing to reinstall.

1.9.2 — 2026-07-16

Makes the viewer role a support tier and tidies the repository list in whoami.

  • Support-mode answers for the support team. The indyknow:viewer role is now a support tier rather than a redacted one. It investigates with the same full access as a developer — reading source, running read-only queries, searching everything — and delivers the answer support-mentor style: plain English, jargon defined the first time it appears, and what it means for the customer up front, with code or SQL shown (and walked through) only when it genuinely helps. Viewer answers are now accurate where the old tier had to guess around hidden source, live read-only queries (run_query) are available to every signed-in user, and developers still get the same facts back in terser, source-forward form. Server-side only — nothing to reinstall.
  • Clearer repository list in whoami. whoami now groups the repositories it can see into the ones included in a repo:"all" search versus the opt-in ones you target by key — each on its own line — so it's obvious at a glance which repositories a broad question will reach.

1.9.1 — 2026-07-16

Adds role-gated repositories — a way to make a repository visible only to users who hold a specific access role.

  • Role-gated repositories. A repository can now be gated behind an access role, making it fully invisible to anyone who does not hold that role: it never appears in the repository list, the per-tool repository choices, the steering text, or the system map, and a direct request for it is answered exactly like a request for a repository that does not exist — so even its existence stays private. Users who hold the role see and search it normally after signing in and restarting Claude Desktop. To make that work, IndyKnow now attaches your sign-in token to the up-front tools request silently — never prompting for sign-in at startup; if you are not signed in, nothing changes and the request stays anonymous.

1.9.0 — 2026-07-16

The first stable release since 1.7.1. It ships the entire 1.8.0 beta line at once — the PrintBuilder Template Studio and the write audit trail — and adds equipment-linked, field-level auditing, all on top of a round of reliability and security hardening under the hood. (The wider run_query/read_file result windows landed in 1.7.1 below and carry forward unchanged.)

  • Equipment-linked, field-level audit. The new update_equipment tool edits one gage's fields (keyed by company + serial) with a full client-parity audit trail attributed to you: every changed field writes a System Admin Log entry plus an equipment-linked companion row, only the fields you pass change, and key / identity / audit-stamp columns are refused. run_query can link a DML write to a gage with equipment: { company, gage_sn }, and read_audit_trail scope='equipment' reads a gage's per-field history the way the client's History form does. On a database whose add-on triggers audit the equipment tables, a raw run_query write to those tables warns that it would be mis-attributed and points you at update_equipment (which stamps last-modified-by first). Local, writable slots only.
  • PrintBuilder Template Studio. Read, edit, and recreate PrintBuilder certificate/sticker templates directly against a local, writable database — including recreating a certificate from a PDF (analyze_pdf_layout + the print-template-author skill), a wireframe preview_print_template, first-class subreport containers, and a family of structured, self-describing edit ops verified against designer-authored production templates.
  • A write audit trail on every change. Every IndyKnow config write — project scripts, custom rules, print templates, and now equipment — lands in the client's audit trail (Config Changes / System Admin Log) stamped with your IndyKnow identity, readable via read_audit_trail. Timestamps show your wall-clock time, audit dates read correctly in every timezone (a date-only field could previously show a day early west of UTC), and DML rowcounts are no longer inflated by legacy triggers.
  • Connections hardening. connections.json refuses duplicated keys (closing a real password-exposure hole where a shadowed slot's plaintext password was never encrypted), and whoami now leads with a clear, secret-free warning when the file is broken and reports the database it will actually use — after you set a default with switch_sql_target, whoami reflects that slot instead of a stale line.
  • Reliability. A cold or slow backend no longer shows "server disconnected" at startup — IndyKnow answers the handshake immediately and warms the backend in the background. Tool failures (backend unreachable, auth, a slow environment) now return as actionable tool errors instead of dropping the connection, and every backend call is bounded by a timeout so one slow request can't hang the session. Local read tools that enumerate a database (listing scripts, print templates, and the like) are bounded the same way — against a slow or remote database over a VPN they now return a clear timeout you can act on instead of hanging.
  • Security & packaging. Model-supplied file paths (PDF analysis, .rtm import/export) are confined to an allowlisted root; the local credential store tightens its on-disk permissions; and the release pipeline gained gates that block a native-binary regression, a build that would ship a stale version, or a manifest whose advertised tool list has drifted from the code.
Beta channel history — the 1.8.0 and 1.9.0 testing builds folded into 1.9.0 (newest first)

1.9.0-beta.1

Equipment-linked, field-level audit for IndyKnow writes. IndyKnow can now change a piece of equipment the way the client does — and leave the same audit trail, attributed to you.

  • New update_equipment tool. Edit fields on one gage (keyed by company + serial) with a full client-parity audit: every changed field writes a System Admin Log entry plus an equipment-linked companion row, and the row's last-modified-by / last-modified-date are stamped as your IndyKnow identity. Only the fields you pass change, a value equal to the current one is skipped, and the primary key / identity / audit-stamp columns are refused. Local, writable slots only — the read-only cloud environment and read-only local slots are declined before any write.
  • run_query can link a DML write to a gage. Pass equipment: { company, gage_sn } on an INSERT/UPDATE/DELETE and IndyKnow writes the equipment companion row alongside the audit entry, so the change shows up in the client's equipment History. Honored on writes only; using it with a read is a clear error.
  • read_audit_trail scope='equipment'. Read one gage's per-field change history (newest first — who, when, and the field's old → new value) via the same join the client's History form uses. Schemas without the equipment columns still return the base history.
  • Correct attribution on databases with audit triggers. On a database whose add-on triggers audit the equipment tables, a raw run_query write to those tables now warns that the change would be mis-attributed to whoever last touched the row — and points you at update_equipment, which stamps last-modified-by first so the audit attributes correctly. The warning never blocks the write.
  • allow_unaudited caveat carries through. As with the other write tools, an equipment write can be forced through without an audit record only as a deliberate, user-confirmed emergency override — such writes are stamped UNAUDITED WRITE.

IndyKnow does not re-implement the client's data-entry validation (required fields, dropdown/lookup values, referential integrity) — those remain the caller's responsibility, the same trust level as a direct run_query write. Read the row first to see the real column names and current values before editing.

1.8.0-beta.8

Designer-view parity and the authoring ops the last cert rebuild kept hand-rolling — with the wider result windows from 1.7.1 folded into the beta line. Everything in the 1.7.1 stable release below (4,000-character run_query cells, the 100,000-character budget, single-column whole-value reads, 1,000-line read_file) ships in this build too. On top of that:

  • read_print_template and the wireframe preview now state each band's print role — once on page 1 vs repeats every page vs once per data row — so a session can reason about what prints where without designer knowledge. Detail rows name their driving data pipeline, and the preview gains a role legend.
  • Paginated preview. The wireframe draws page-boundary lines where stacked band heights cross a printable page and names any object that straddles one. It is an approximation (PrintBuilder's Preview tab stays the sign-off), but enough to catch a block that will split across pages.
  • The editable type catalog now shows each type's base data pipeline at list and create time, so a work-order form lands under WORK ORDERS with the right pipeline instead of being rebuilt under CERTIFICATES.
  • New structure ops, each verified against designer-authored production templates: clear_band (empty a band in one call, RAP-safe), add_page_break (start a section on a fresh page), add_table (a ruled grid of rules + header cells in one op), and clone_objects (duplicate a selection at an X/Y offset — repeating rows, page-two stacks).
  • add_image now renders. A JPEG added through the tool used to ship but never display in the designer: the envelope was missing the byte-count field the designer reads before the image data (found by byte-diffing designer-authored images). PNG and JPEG now embed in their verified envelopes; formats without a designer-verified sample are refused rather than shipped broken.
  • add_shape takes an optional solid fill for section-header bars, streaming the fill exactly as designer-authored shapes do.

1.8.0-beta.7

The designer labels bands below their content — the tools now say so everywhere it can bite. A live beta session compared IndyKnow's band readout against the PrintBuilder designer canvas and concluded the two disagreed about which band held what (Header content "showing in the Title lane", Detail content "under Header"). Investigating against designer-authored production templates showed the placements were correct — the confusion is a label-convention inversion: the PrintBuilder designer names each band in the divider bar BELOW the band's white space (a band's content sits above its own label; ReportBuilder's manual defines the header band as "the white space above the word 'Header'"), while IndyKnow's wireframe preview labels lanes at their top-left like most tools do. Read top-down, a designer canvas therefore looks shifted exactly one band up, and a session can be talked into "fixing" correct placements.

The misread is now called out at every surface where band names meet a reader: the preview_print_template and edit_print_template descriptions, the wireframe's legend text, both certificate-anatomy references, and the template-author skill's preview loop — each with the instruction to treat read_print_template's band assignment as authoritative and rule out the misread before relocating "misplaced" content.

Three more quick fixes from the same field session's feedback brief:

  • set_band_print visible:false now says what it does NOT do. The property suppresses printing only — the designer canvas still draws the hidden band and its objects, which read as "my change didn't take". The op result and description now state that and point at the real recipe for visually emptying a band (delete the objects, set height 0).
  • create_print_template now surfaces the type catalog. A work-order form was built under CERTIFICATES because nothing ever mentioned a WORK ORDERS type existed. The tool description now says to pick the TEMPLATE_TYPE before picking a source, and every successful create echoes the database's editable template types ("CERTIFICATES (12), WORK ORDERS (3), …") with a rebuild hint when the artifact belongs elsewhere.
  • Over-length template descriptions are refused up front with the actual column limit — read live from the database schema (they vary across IndySoft versions) — instead of surfacing as a raw SQL "String or binary data would be truncated" error after the fact.

1.8.0-beta.6

Band guidance rewritten from real production certs, not theory. Live testing showed cert builds still piling everything into the repeating Header. We pulled complete production certificates out of live customer databases (four finished certs from two independent labs, plus the stock cert) and compared their actual band populations against what the tools were telling Claude — two pieces of our own guidance were steering it wrong:

  • The "put the first-page block in Title" advice pointed at an invisible band. Every production cert ships the main Title band Visible:false at height 0 — content added there silently never prints, and the fallback was the Header. The guidance now states the production idiom first (Header = ~32mm letterhead strip ONLY, repeated every page) and spells out that the Title pattern requires set_band_print Title visible:true + set_band_height first.
  • The add_* op examples said "main/DetailBand" — the one band that must stay content-free. In every production cert the main Detail hosts ONLY subreport containers; each body section (equipment info, cal data, standards, procedures, compliance text, sign-off) is its own subreport chained via ShiftRelativeTo, with one-shot text blocks in a dedicated subreport's SUMMARY band. Examples and descriptions now say so, create_print_template recommends cloning the closest complete production template instead of stock STANDARD, and both certificate-anatomy references gained a verified "where content goes" placement table.

No engine changes — descriptions, examples, and docs only.

1.8.0-beta.5

The shim will no longer write a template that errors on designer load. A live beta.4 session deleted RAP-bound objects (with force) and left their OnPrint handlers dangling — PrintBuilder then popped "Unable to load OnPrint code for DBText19, no object with this name found" on every open. Two layers of fix:

  • Forced deletes now remove the object's RAP handlers WITH the object — the deleted-object case that produced the incident is structurally impossible now. Deleting a subreport container also requires force:true when its hosted report carries RAP code (previously that code was destroyed silently), and the refusal names the exact handlers (e.g. OnPrint) so the decision is informed.
  • A write-time RAP integrity gate on every edit: output that would newly dangle a handler binding is refused outright, whatever op caused it. (Pre-existing quirks in a template don't block unrelated edits — the gate compares before/after.)

Field-feedback batch from the 3-page cert rebuild session (the ~250-wasted-ops problems):

  • move_to_band — reparent an object to another band of the same report in place, keeping properties and RAP handlers. Relocating content is no longer delete + fully re-specified re-add.
  • offset_band_objects — shift every object in a band by one delta (bulk translate).
  • set_band_print — band scheduling: printOnFirstPage/printOnLastPage on Header/Footer/PageSummary bands, visible on any band (a hidden Title band can finally be turned on). Enables the standard cert pattern: Header off on page 1, first-page block in the Title band.
  • set_page_setup — page margins, custom paper size, and orientation on the main report; multi-page layouts stop faking pagination with one tall Detail band.
  • RAP code is now readable: read_print_template detail:"rap" returns every handler's full source per report, never truncated — read it before deleting anything marked Calc: yes. report:"<name>" scopes any read to one report/subreport (same addressing as preview), and the full-dump truncation notice now points at it.
  • Object names are checked per report, not per template — real customer templates legitimately reuse names (e.g. DBText4) across subreports; those templates were previously unrepairable through the API.
  • Band-roles guidance in the tool rewritten from field practice: Title sits BELOW the Header on page 1 (pair it with set_band_print Header printOnFirstPage:false); Detail loops once per data-pipeline row; Summary mirrors Title on the last page; page Header/Footer belong to the main report — inside subreports, repeating section headers come from designer groups (ReprintOnSubsequentPage).

1.8.0-beta.4

Fixes for the template-editing debugging loops observed in live beta testing — a Claude editing a template had to discover the tool's op shapes and the template's subreport structure by trial and error, burning conversation turns:

  • edit_print_template now advertises the exact shape of every edit op. The ops array items were published as a bare "object" — the model literally could not see that add_label requires band, name, caption, leftUm, topUm, widthUm, heightUm, or that font is flat on set_font but a nested object on add_label. The full per-op schema (all 14 ops, required + optional fields) is now in the tool definition, so the first call is right instead of the fifth.
  • Validation errors now teach the whole fix in one message. Previously only the FIRST problem was reported — wrong font type, then missing widthUm, then missing heightUm, one failed call each. A bad batch now gets every issue at once, each failing op's full one-line signature, and the valid op list on an unknown op — with an explicit "fix ALL of the following and retry the whole batch once".
  • Subreport containers are now first-class objects (they were invisible). read_print_template and the wireframe preview showed subreport content as separate reports but never showed the container in its host band — a stock certificate's DetailBand looked empty while actually hosting 8 subreports, and the containers could not be addressed at all. They now appear in band listings and the preview (as labeled SUB: boxes at true position), and support move / resize / set_visible / delete_object (which removes that whole subreport). Content-style ops on a container are refused with the correct addressing hint.
  • Band-roles guidance baked into the tool (from the IndySoft docs): Title prints once on page 1, Header repeats on EVERY page, Detail per data row, Footer at each page bottom, Summary once at the end — so one-time content stops being piled into a repeating Header.
  • preview_print_template accepts report:"main" — the same name edit ops use to address the main report (previously only subreport names matched).

1.8.0-beta.3

  • New: preview_print_template — Claude can now SEE the template it is editing. Renders the template's current state as a wireframe image: bands as labeled lanes at true scale, every object as a box color-coded by class (blue static labels, green data-bound fields, orange barcodes, purple image placeholders), captions and field bindings drawn inside, hidden objects crossed out in red, and overlaps stacked in real z-order. Called between edit batches, it turns blind coordinate work into look-and-adjust; pass report to zoom into one subreport of a big certificate. It is deliberately a wireframe, not a print preview — fonts are schematic, images aren't decoded, calc code isn't evaluated — so PrintBuilder remains the final visual check. Pure JS end to end (the PNG encoder is ~60 lines on node:zlib) — still zero native dependencies.

1.8.0-beta.2

Fixes from the first live beta pass (all found by real testing against a customer-shaped database):

  • analyze_pdf_layout now works inside Claude Desktop. The first beta failed with No "GlobalWorkerOptions.workerSrc" specified: Claude Desktop runs IndyKnow in an Electron utility process, which defeats PDF.js's environment detection — it concluded it wasn't in Node and refused to start its in-process worker (plain Node, where all our tests run, was fine). IndyKnow now hands PDF.js its worker directly, up front, so extraction behaves identically everywhere.

  • Audit timestamps now show YOUR wall-clock time, not the server's. The first beta stamped Config Changes / System Admin Log entries with the database server's clock — and IndySoft DB servers commonly run on UTC, so a 1:45 PM write displayed as 6:45 PM in the client. IndyKnow now stamps the time the way the IndySoft client itself does: from the machine the write came from. (The separate *_UTC columns keep true UTC.)

  • DML rowcounts are no longer inflated by legacy triggers. Most core IndySoft tables carry change-tracking triggers that leak their internal rowcounts, so a single-row UPDATE via run_query reported "3 row(s) affected" — in the tool output and on the permanent SYSADMINLOG record. IndyKnow now reports the statement's own count (the correct "1 row(s) affected").

  • Claude is now told to check real column names before writing SQL. IndySoft schemas are proprietary and vary across databases and product versions — run_query's description now steers Claude to get_table_detail (or read_audit_trail for the audit tables) instead of guessing.

1.8.0-beta.1

Everything below this heading ships in the beta download only; the stable download remains 1.7.0. The beta bundles three efforts for combined testing: the PrintBuilder Template Studio, the write audit trail (every IndyKnow config write — scripts, custom rules, and now print templates — lands in the client's CONFIGCHANGES audit trail, plus read_audit_trail), and the connections.json duplicate-key guard. Template writes participate in the audit trail: create/edit/import record a PrintBuilder Templates Config Changes entry (with note check-in comments and the same audit-failure revert semantics as the script tools), readable via read_audit_trail scope='template'.

Connections hardening

  • connections.json now refuses duplicated keys — closing a real password-exposure hole. If the file lists the same key twice (say, slot "O" pasted twice while adding databases), JSON parsing keeps only the last one and silently ignores the other — so a plaintext password typed into the shadowed entry was never encrypted and never removed from the file. It just sat there. IndyKnow now scans the raw file for duplicated keys at any depth — a doubled slot letter, a doubled profile name, even a doubled "password" line inside one slot — and refuses the file with a message naming the exact duplicate (e.g. profiles.prod.O) and how to fix it. Your last working configuration stays in effect until the file is corrected, and nothing is silently dropped: before this fix, IndyKnow's own password-scrub rewrite could also silently delete the shadowed entry.
  • whoami now tells you when your connections file is broken. A bad edit — invalid JSON, duplicated keys, no usable profile — used to warn only in a log file you never see; your edit just "didn't take effect". whoami now leads with a ⚠ block quoting the exact (secret-free) problem, says whether you're running on the last working configuration or on extension settings, and reminds you that "open my connections file" gets you straight to the fix.

PrintBuilder Template Studio

PrintBuilder Template Studio. IndyKnow can now read, edit, and recreate IndySoft PrintBuilder certificate/sticker print templates — the EVENTPRINTTEMPLATE blobs (the same TPF0 binary as an exported .rtm) — directly against a local, writable database.

Recreate a certificate from a PDF
  • New: analyze_pdf_layout — point it at a local PDF (a customer's existing certificate, a letterhead, a target design) and it returns the page's geometry: every text run with its position/size in micrometres, font, and bold/italic; embedded image placements (with the original logo bytes when the PDF stored a JPEG — standalone or deflated in place, the shape print-driver PDFs produce); and ruled lines/table borders. Font names come back as installable families (Segoe UI + a bold flag, not KWSUAJ+SegoeUI,Bold), ready for set_font. It reads the file off disk, never contacts the backend, and works signed-out. A scanned page (no text layer) is reported as such. (A PDF attached in the Desktop chat isn't on disk — save it and pass the real file path.)
  • New: the print-template-author skill — walks the whole loop: extract the PDF's geometry as ground truth → propose a section map (which regions are static labels vs database fields, matched to the right pipeline) → clone the stock STANDARD template → lay the design in with the extractor's coordinates verbatim → hand off to a PrintBuilder preview loop.
Edit print templates
  • The print-template tool familylist_print_templates (catalog, classifying TPF0 vs RTF/INI/flowchart rows), read_print_template (bands, bound fields, calc-code flags), create_print_template (clone STANDARD to a new name), edit_print_template (batched semantic ops — add/move/resize/restyle labels, DB-text, shapes, images), and export_print_template / import_print_template (raw .rtm round-trip).
  • Safety. The three writing tools require a local, writable database — cloud slots are refused. edit_print_template backs up the prior blob before writing (fail-closed), refuses non-TPF0 bytes, supports expectedSha optimistic concurrency, embeds images as-is (no transcoding, 250 KB budget), and preserves RAP calc code byte-identically (deleting a calc-bound object needs force).

Reference: docs/reference/rtm/certificate_anatomy.md (structure + pipeline → DataField surface) and docs/reference/rtm/format_spec.md (TPF0 byte format).

Backend update — 2026-07-16 (legacy REST API / 3-tier server; no client update needed)

IndyKnow can now read the legacy REST API / 3-tier server — but only when you ask for it by name (legacyapi). This is a server-side change only: nothing to install or update, and no new version to pack. The legacy app-server service layer (the REST folder of the Delphi repository — login, equipment, orders, printing, mobile, and the other app-server services) is indexed as its own opt-in repository, parsed the way the 3-tier server is actually built rather than through the desktop client's view. Like the Fulfillment module it is excluded from whole-codebase (repo:"all") searches — its equipment/orders/login vocabulary overlaps the shipped client, so it answers only when you name it: "in the legacy API, how does the equipment service compute due dates?" Unlike the newer repositories it is reachable at every pinned version — the 3-tier server long predates v15. One deliberate omission: the generated ORM map (a 213,000-line, one-class-per-table file) is excluded from search results so they stay readable; the live database schema remains the SQL tools' job.

1.7.1 — 2026-07-13

Long values stop coming back in crumbs. A user reading project scripts through run_query watched Claude reassemble them from dozens of 200-character fragments — burning tool calls, context, and patience. This release widens every result window that caused it.

  • run_query cells now carry up to 4,000 characters (was 200), with a 100,000-character total budget per result so one query can return real content without flooding the session. When something is still clipped or the budget runs out, the result says so — and says what to do about it.
  • Select a long column by itself and you get it whole — a single-column SELECT spends the full 100,000-character budget on that column, so a stored script, XML blob, or log entry comes back in one call instead of a SUBSTRING crawl.
  • Clipped local results point at the right tool — when a local run_query result is clipped, it now ends with a tip that read_project_script / read_custom_rule return a script's full content in one call.
  • read_file reads 1,000 lines by default (was 200) across every repository — a 4,000-line unit is four calls, not twenty. Explicit start/end still widen without limit.

1.7.0 — 2026-07-09

Two things in one release: the multi-database file grows up — reach any database in any profile without switching, with up to 26 databases per profile — and connections.json setup stops being a scavenger hunt, especially on Microsoft-Store installs of Claude Desktop, where Windows quietly relocates the file.

Cross-profile addressing + A–Z slots

  • Reach any database in any profile, any time — the SQL and script tools' db parameter now takes a compound profile/slot address ("compare EQUIPMENT in prod/A and staging/A") alongside the familiar bare letter for the active profile. No profile switch, one call per side — built for cross-environment comparison and migration work.
  • Up to 26 databases per profile — slots now run A–Z (was A–D), in connections.json and the per-call db parameter alike.
  • whoami shows the whole map — every profile (active first), every database with its address (bare letter or profile/slot), read/write state, which is the default, and what still needs a password.
  • The db picker teaches itself — its allowed values are built from your configuration at launch: the active profile's letters plus every profile/slot. Claude offers your real databases, not guesses. (Like all tool-list changes, new profiles added mid-session appear in the picker after a Claude Desktop restart — whoami and use_profile see them immediately.)
  • Cross-environment writes stay deliberate — read-only by default everywhere, cloud always read-only, and a write into another profile's database requires that slot to be explicitly writable ("readOnly": false).

The reported connections.json path is now always the truth

  • Fixed: "IndyKnow says the file is in AppData\Roaming — but there's nothing there." Claude Desktop installed from the Microsoft Store runs in a Windows app container, and Windows silently redirects IndyKnow's app-data writes to %LOCALAPPDATA%\Packages\Claude_...\LocalCache\Roaming\IndyKnow\. IndyKnow kept reporting the canonical path — true inside the container, false in your Explorer — which sent users hunting through an empty folder. IndyKnow now detects the redirect by file identity and reports the file's REAL location everywhere (init_connections, whoami), with a short note explaining the Store quirk. Website/.exe installs see no change.
  • New: just say "open my connections file" — the open_connections_file tool opens connections.json in Notepad (macOS: your default text editor) at its true physical location, wherever that is. Type your passwords between the quotes, save, run whoami — no folder navigation, ever. If an editor can't launch, IndyKnow answers with exact manual steps for your OS (Win+R paste / Finder Go to Folder) and the real path. init_connections chains straight into it.
  • Quickstart updated — including the Store-install trap to avoid: hand-placing a file into %APPDATA%\IndyKnow when IndyKnow already created one means Windows keeps using the LocalCache copy — your edits are silently ignored and a plaintext password in your copy would never be scrubbed. Ask Claude to open the file instead.

Backend update — 2026-07-08 (documentation search; no client update needed)

IndyKnow can now search the IndySoft product documentation — the manuals at docs.indysoft.com — as a fifth repository (userdocs). This is a server-side change only: nothing to install or update, and no new version to pack. Ask about what a feature is for or how a customer is guided to use it — "what does the manual say about creating a work order?" — and IndyKnow reads the relevant manual page, can quote it verbatim, and cites the live docs.indysoft.com link. Unlike the Fulfillment module, the documentation is included in whole-product (repo:"all") searches, and it's reachable at every pinned version. Two things to know: the manuals are English-only (translated pages aren't searched), and they describe how the product is meant to work — the code is still the source of truth for what it actually does, so IndyKnow confirms implementation details in the code and tells you when the docs and the code disagree.

Backend update — 2026-07-08 (no client update needed)

IndyKnow can now index a fourth repository — the Accredited Calibration Module (fulfillment) — but only when you ask for it by name. This is a server-side change only: nothing to install or update, no new version to pack, and no change to any existing repository, tool, or setting. The module is opt-in and treated as unreleased — it is excluded from whole-codebase (repo:"all") searches, and IndyKnow consults it only when you explicitly ask about the Fulfillment / Accredited Calibration Module by name. General questions about the shipped product are never answered from it — its "calibration / equipment / events" vocabulary overlaps the released app, which is exactly why it stays walled off from general searches. To explore it, name it directly — "in the fulfillment module, how does the budget-engine compute uncertainty?" — and IndyKnow will index its .NET CQRS server, its React Designer/Runtime client, and the docs/database migrations.

1.6.4 — 2026-07-07

Hotfix release: the script read/edit tools now participate fully in the multi-database world 1.6.0 introduced — they follow your connections.json profiles and per-slot permissions instead of the legacy Settings connection, and their writes adapt to the target database's actual schema. Every fix below was verified live against both Calibrations- and Scales-product databases.

  • The script tools now follow your profiles/slotslist_scripts, read_project_script, read_custom_rule, edit_project_script, and edit_custom_rule used to be hard-wired to the legacy Local SQL Settings fields, silently ignoring connections.json profiles, the DB-A…D slots, and use_profile/switch_sql_target. They now resolve their target database exactly like the SQL tools: an optional per-call db parameter (A–D), falling back to your default slot. "Read the MainScript in the jlr database" now goes where you'd expect.
  • Per-slot write control applies to script edits — the two edit tools honor the target slot's own read/write flag: a slot marked "readOnly": true in connections.json refuses script edits with a message naming the slot and the fix; a cloud slot is always refused (script tools are local-only by design). The legacy Allow local SQL writes setting keeps working for Settings-based setups.
  • test_local_sql tests the database you're actually pointed at — it used to always test the legacy Local SQL Settings connection, so in profiles mode it could report "connection OK" for a server your session never touches. It now takes the same optional db parameter (A–D), defaults to your default slot, names the slot in its output (DB-B (jlr): Local SQL connection OK — …), and reports that slot's own read/write state. A cloud slot says so instead of testing the wrong server.
  • Script edits work on older/Scales-variant schemasedit_project_script / edit_custom_rule unconditionally refreshed a LAST_MODIFIED_DATE_TIME_UTC column on the script tables, which some databases don't have — the whole edit failed with Invalid column name (found live on a Scales-product database whose SCRIPT_PROJECT_FILES has no timestamp column). The tools now check the target table's schema and include the timestamp refresh only where the column exists.
  • (1.6.1–1.6.3 were internal test builds — no public release.)

1.6.0 — 2026-07-03

  • Quickstart guide + downloadable templatedocs/CONNECTIONS-QUICKSTART.md is the five-minute, plain-English setup guide (ask-Claude setup, the one manual password step, when to restart Claude Desktop, how to talk to Claude about your databases, password rotation), and docs/connections.template.json is a ready-to-download two-profile starter for anyone who prefers editing a file by hand.
  • Change the default database inside a profileswitch_sql_target with a slot letter ("switch to DB-B") now works in profiles mode too, persisting the default database within the active profile; only the legacy env/local aliases are redirected to use_profile. (Found in live smoke: the earlier blanket redirect left profiles mode with no way to move the default.)
  • First-run restart note — creating a connections.json mid-session (which is exactly what init_connections does) can't refresh the already-loaded tool list: the SQL tools' per-call db parameter and the multi-database primer only appear after a Claude Desktop restart. init_connections now says so explicitly; whoami, use_profile, and switch_sql_target work immediately either way.
  • connections.json is now the multi-database surface — the DB-A…D Settings wall is retired — the 28 per-slot fields (and the "Enable multi-database mode" toggle) are gone from the extension Settings, which now carry only the basics: your Environment Id and the optional Local SQL fields. Multiple databases and named profiles live in connections.json, and when that file exists it takes precedence over the Settings. Same capability, one editable (and shareable) file instead of a Settings wall. (The INDYKNOW_DB_* environment variables still work for scripted setups; since the DB-A…D fields never shipped to a customer, nothing to migrate.)
  • Ask IndyKnow to create your connections.json for you — the new init_connections tool writes the file into your IndyKnow app-data folder so you never hunt for %APPDATA%. Say "set up a connections.json" for a starter template, or describe what you want — "three profiles: prod, staging, dev, each with a cloud database on A and my local restore on B" — and it writes the whole thing in one shot. Passwords never go through the tool (anything typed in chat leaves your machine): every local database is written with an empty "password": "" line — type yours between the quotes — and shows NEEDS PASSWORD in whoami until you do; on the next call IndyKnow encrypts it locally and scrubs it to "@stored" as usual. It never overwrites an existing file. The file opens with a short help note (safe to delete) that also reminds you Claude can edit the file for you — "add an acme profile" just works. The starter template's default slot is local on purpose, so first reads can't land on a cloud environment that isn't SQL-registered on the backend yet.
  • Name whole database setups as profiles in one file — instead of re-typing the DB-A…D fields in Settings every time you switch jobs, put your database sets in a connections.json file and give each a name. One profile might be acme (their cloud env as DB-A, your local restore as DB-B); another globex. Switch the entire A…D set with a single "use the acme profile" — no restart, no re-typing. Run whoami to see the file location, the active profile, the available profiles, and the slot table. connections.json lives in your IndyKnow app-data folder (%APPDATA%\IndyKnow\ on Windows, ~/Library/Application Support/IndyKnow/ on macOS, ~/.config/indyknow/ on Linux).
  • Passwords are written once, then encrypted and removed from the file — put a SQL password straight into connections.json; on the next load IndyKnow encrypts it into the local store and rewrites the file with "@stored" in its place, so the password never lingers in plaintext. The file is then safe to keep, diff, or share. This is ingest-and-scrub: the same one-time plaintext window as the refresh token IndyKnow already stores.
  • Edits are picked up live — save a change to connections.json (fix a typo, add a slot, tweak a label) and the next tool call sees it — no restart. A broken edit is ignored with a warning and your last working setup keeps running; delete the file and IndyKnow falls back to your Settings-based databases; put it back and it's picked up again.
  • use_profile tool — switch the active profile by name (use_profile with profile: "acme"), or call it with no argument to see the current and available profiles. Switching persists across restarts and re-points what A…D mean for the whole session; the per-call db: parameter still targets one slot. In profiles mode, switch_sql_target points you at use_profile instead.
  • Share the file, not the secrets — because passwords are scrubbed to "@stored" and the encrypted store is keyed to your machine, you can hand a teammate your connections.json and they just add their own passwords once (which get scrubbed on their machine too). No credential ever travels in the file.
  • Nothing changes without a file — no connections.json means IndyKnow behaves exactly as 1.5.0 did (Settings-based DB-A…D or single-database mode). The feature needs no new Settings and no "multi-database" toggle. Note: avoid a ; in a connections.json password (it can't be represented in a SQL connection string) — IndyKnow warns if it sees one.

1.5.0 — 2026-07-01

  • Connect up to four databases at once (DB-A/B/C/D) — IndyKnow can now talk to as many as four databases in one session, each independently either a cloud environment (an IndySoft environment id) or a local SQL Server (a connection string). Configure them in Settings under the new DB-A … DB-D fields. The headline use case is data migration and implementation mapping: label one slot source and another destination, then ask Claude to "compare the schema of source and destination" or "map the EQUIPMENT table from source into destination".
  • Pick a database per call with db: — the four SQL tools (get_table_detail, get_proc_body, grep_ddl, run_query) take an optional db parameter (AD). Omit it and the call uses your default database. Just ask in plain English — "show me the GAGES table in the source database" — and Claude routes the call. whoami prints a table of your configured databases (label, type, read/write, default), and "switch to DB-B" (or switch_sql_target) changes the default.
  • Each call hits one database — no cross-database JOINs — IndyKnow can't JOIN across slots (they're separate servers/pools). To compare, it queries each database and reasons over the results — which is exactly what you want for a migration diff.
  • Per-database read/write controlcloud databases are always read-only (a structural guarantee — a write is rejected in the shim before it ever reaches the backend). Local databases default to read-only and opt into writes per slot via the DB-X Read-only toggle; DDL stays blocked everywhere. A write aimed at a read-only database comes back with a clear, slot-named message.
  • Nothing changes for single-database users — if you don't set any DB-A…D fields, IndyKnow behaves exactly as before (your environment id is DB-A, your local SQL is DB-B, and your existing writes setting is preserved). Your SQL password is stored as a sensitive setting — Claude Desktop keeps it in your OS keychain, never in plaintext; the server, database, and login are ordinary settings, and the shim assembles them in memory at launch and never writes a connection string to disk or its logs.

1.4.5 — 2026-06-26

  • IndyKnow now teaches the script dialect, not just the function list — every list_script_functions result now includes the core syntax rules for that context's dialect: Pascal (script projects — single-quoted strings, :=, // comments) vs VBScript (custom rules — double-quoted strings, =, ' comments), and the rule that bites most: calls with arguments always need parentheses (ShowMessage("x"), never ShowMessage "x"). Pass syntax: true for the complete dialect reference — control flow, the standard-function surface (IntToStr/Copy/Pos in Pascal vs CStr/Mid/InStr in VBScript), what's not registered (e.g. DateAdd), and the common anti-patterns. These rules ship inside the tool, so they're present whenever you use IndyKnow — no separate skill required.
  • The script read/edit tools carry the same rules — the steering header on read_project_script / edit_custom_rule / read_custom_rule / edit_project_script now states the parens + quoting rule for the script's dialect, so a rule or project script is written in the right syntax the first time.
  • Function-surface fixes (verified against live Calibrations source) — the Login context now lists the registered NewPasswordNumberAlpha / Numbers / Uppercase / LowerCase / Extended password-policy functions, and script-project:TASK now correctly wires the Task library (LookupTaskAttribute* / SetTaskAttribute*, GotoNextLink, GetPopupPos) instead of claiming it isn't compiled.

1.4.4 — 2026-06-25

  • Deeper, honest, paged searchesgrep and grep_ddl no longer stop silently at the result cap. When a search matches more than fits on one page, the results end with a visible note that more exist — and now tell Claude the exact offset to pass for the next page. A 600-match search becomes a deliberate walk (offset 0 → 200 → 400 …) instead of a silently-truncated first slice that Claude mistakes for the whole answer. The page size was also raised 50 → 200 now that IndyKnow runs research on your Claude subscription. Just ask Claude to "keep going" / "show the rest" and it pages for you.
  • run_query returns more rows + pages — the row cap was raised 100 → 500, keeping the "results truncated" note when it engages, and its guidance now points at ORDER BY … OFFSET <n> ROWS FETCH NEXT 500 ROWS ONLY to page through big result sets. Wide cells are still clipped so a large result can't blow out the context window.
  • Why cap-and-page instead of no limit? An LLM's accuracy degrades as its context fills, so the most thorough deep dives come from Claude making many targeted, paged searches — which it can now do freely on your subscription — not from one giant result dump.

1.4.3 — 2026-06-24

  • list_script_functions tool — ask which IndySoft script functions are actually callable in a given scripting context and get back the exact list with signatures, dialect, in-scope libraries, and gotchas — instead of guessing from raw source. Pass a context key (event-custom-rule, script-project:EVENT), a friendly alias (equipment rule), or a raw SCRIPT_TYPE/RULE_TYPE plus a scope. A bare ambiguous name like EVENT (which exists as both a custom rule and a script project) asks you to specify the scope rather than silently guessing the wrong one. Local-only — no SQL connection or sign-in required.
  • Context-aware steering on the script toolsread_project_script, edit_project_script, read_custom_rule, edit_custom_rule, and list_scripts now name the script's context on every successful result and point at list_script_functions as the allowlist of callable functions. This stops generated rules and scripts from calling functions that exist somewhere in the IndySoft source but aren't registered for that context — e.g. LookupEventNum is equipment-only, so event rules are steered to LookupCurrentEventNum. The same one-line rule is built into each tool's description.
  • Opt-in reconcilelist_script_functions(..., reconcile: true) diffs the bundled function list against the live IndySoft source and reports anything missing or stale, so the bundled list can be kept honest between IndySoft releases. Reads source only; degrades gracefully when source isn't reachable.

1.4.2 — 2026-06-23

  • Recoverable script editsedit_project_script and edit_custom_rule now return the prior content verbatim (previously only its character count), so an edit can be undone byte-exact by calling the same tool again with the returned text.

1.4.1 — 2026-06-23

  • Edit IndySoft scripts in Local SQL mode — five new tools to read and edit your project scripts (.ssproj) and custom rules directly in your local database: list_scripts, read_project_script, read_custom_rule, edit_project_script, and edit_custom_rule. edit_project_script writes the file's source into SCRIPT_PROJECT_FILES and clears the compiled cache so the client recompiles from source on the next run; edit_custom_rule updates event and lifecycle rule scripts. Local SQL only — the cloud environment stays read-only, and a writable (db_datawriter) login is required. Each edit returns the prior text so changes are recoverable.

1.4.0 — 2026-06-18

  • Per-user Calibrations version selection — pick which Calibrations code version your answers resolve against with the new set_version tool (and list_versions to see the choices, each with its readiness). The choice is personal and remembered across sessions; the default stays the latest line. Ask a code question and Claude answers against your selected version's source.
  • The v15 boundaryenterpriseweb and signalrhub were introduced at v15, so when you select a Calibrations version below 15 only the calibrations (Delphi) repo is in scope; the two newer repos are unreachable until you switch back with set_version latest (or a v15+ release). A call targeting them returns a plain-English refusal, and repo: "all" notes the omission — this is policy, not an error. set_version reports which repos your selection can reach.
  • What is not versioned — the SQL tools (get_table_detail, get_proc_body, grep_ddl, run_query) and read_module_doc summaries always reflect the present shared schema and current docs, never the selected version — only the Calibrations source tools follow your pin.
  • whoami now ends with quick tips — running whoami to get your bearings also prints a short, plain-English cheat-sheet (switch code version, point at your local database, re-authenticate) phrased as things to ask Claude, so you never have to memorize tool names. The version-switch tip only appears where version selection is available.

1.3.0 — 2026-06-17

  • Multi-repo awareness — IndyKnow now spans the three IndySoft repositories in one extension: calibrations (Delphi), EnterpriseWeb (C# API), and SignalRHub (C#). Ask a cross-repo question and Claude targets the right codebase, so you can trace a feature across the legacy Delphi app, the SignalR bridge, and the new C# API in one conversation.
  • system_map tool — shows what each repo is and the integration seams between them (REST endpoints, SignalR hubs, the shared database). Claude also receives it as orientation at session start, so it knows where to look before searching.
  • Per-tool repo targeting — the code tools (list_units, get_unit_detail, read_module_doc, list_files, read_file, grep) take a repo parameter to pick a repository; grep and list_files also accept repo: "all" to fan out across every repo at once.
  • whoami now lists the repositories available to you.
  • New repositories can be added server-side later with no extension update — the repo list is served by the backend.

1.2.0 — 2026-06-10

  • Local SQL writes (DML)run_query can now run INSERT / UPDATE / DELETE / MERGE against your local SQL Server, so Claude can seed test data, reproduce a bug, fix a row, and verify the result in one conversation. The IndyKnow cloud/environment database is always read-only — writes there are structurally impossible, regardless of any setting.
  • "Allow local SQL writes (DML)" setting — on by default; untick it to keep your local connection read-only. Either way, schema changes (CREATE/ALTER/DROP/TRUNCATE), EXEC, and admin commands stay blocked, one statement at a time.
  • test_local_sql tool — verifies your local SQL connection and login in one step, reporting server, database, login, and latency — or specific fix-it guidance when it fails (TCP/IP not enabled, wrong password, named instance, TLS).
  • whoami now shows whether local writes are enabled for the local target.
  • Recommended login setup — give the local connection a db_datareader + db_datawriter login (not db_owner): Claude can change data, and SQL Server itself refuses schema changes as the final backstop.

1.1.0 — 2026-06-03

  • Local SQL Mode — point IndyKnow at your own local SQL Server and ask schema and data questions against it instead of the cloud environment. Toggle it with the Use Local SQL setting or the switch_sql_target tool.
  • Simple local-DB setup — configure the connection with four plain fields (Server, Database, Login, Password) instead of a raw connection string. Server defaults to localhost.
  • Credentials stay secure — the SQL Login and Password are stored in your OS keychain and masked in the extension settings.
  • refresh_local_sql_schema tool — re-read your local schema after running migrations.
  • whoami SQL block — shows which SQL target you're pointed at, plus the current database and login (never the password).

1.0.8 — earlier

  • Baseline release: ask plain-English questions about IndySoft customer Delphi source and SQL schema from inside Claude Desktop.