Contents
This is the second of a monthly series: tools I use or am trying out, each checked against its latest release on the day I publish, and each with the one thing I would check before adopting it.
At a glance
| Tool | Version | Licence | Watch for |
|---|---|---|---|
| TypeScript | 7.0.2 | Apache-2.0 | no compiler API at the package root; typescript-eslint stops at 6.0 |
| PyYAML | 6.0.3 | MIT | an impossible date raises ValueError, which except yaml.YAMLError misses; timestamps load as datetime |
| uv | 0.13.7 | MIT or Apache-2.0 | upgrading uv does not upgrade the Pythons it installed, or their pip |
| Colima | 0.10.3 | MIT | only your home folder is shared by default; -v from elsewhere mounts an empty directory |
| MegaLinter | 10.2.0 | AGPL-3.0 | markdownlint counts as a formatter; formatter errors only warn by default |
| Dependabot | core 0.403.0 | MIT | list only a Bun workspace's root, or PRs skip bun.lock |
| GitHub CLI | 2.103.3 | MIT | :repo in a query string is silently replaced in a clone; write %3A |
| pandoc | 3.13 | GPL-2.0-or-later | no is now a string, which templates treat as true; duplicate keys are errors |
| Obsidian | 1.15.0 | proprietary | diagrams drawn by Pele, not Mermaid; closing tokens get new node names |
Languages and libraries
TypeScript 7.0.2. Microsoft's compiler, a native Go port since 7.0. VaultOre (alpha, 0.2.0), one of my CronAI Labs tools, is not on it yet: its main is on 6.0.3 (PR #200). Caveat: 7.0 "does not ship with an API", as Microsoft's announcement says; require("typescript") returns version and versionMajorMinor, nothing else. Dependabot's plain bump to 7.0.2 crashed VaultOre's .d.ts build in tsup 8.5.1 with TypeError: Cannot read properties of undefined (reading 'useCaseSensitiveFileNames') (issue #195). typescript-eslint 8.72.1, the latest, accepts only >=4.8.4 <6.1.0. So VaultOre holds TypeScript 7 back: its Dependabot config ignores typescript >=7.0.0 until both run on it. Microsoft's way out is an npm alias: typescript points to @typescript/typescript6, which re-exports the 6.0 API, and 7.0 goes in under a second name. tsup 9.0.0's code falls back to that package. I have not tried either.
PyYAML 6.0.3. A YAML parser and emitter for Python, and the only required dependency of OKF Vault Kit, one of my CronAI Labs tools (alpha, v0.2.0), which reads every note's front matter with yaml.safe_load. Caveat: except yaml.YAMLError does not catch everything safe_load raises. An unquoted impossible date such as created: 2026-02-30 raises a ValueError (issue #382, open since February 2020), and explicit tags such as !!int '' leak IndexError or KeyError (issue #933). I reproduced both with 6.0.3, with and without libyaml. The kit has the same gap: in v0.2.0, one note with that date stops kit.py validate and kit.py index with a traceback before either reports anything (issue #108). Catch Exception around each safe_load and report the note. Timestamps load as datetime, a subclass of date, so test for datetime first.
Runtimes and containers
uv 0.13.7. Astral's Python package manager, which also installs its own CPython builds. OKF Vault Kit is a uv project, and schriftsatz, my CronAI Labs Markdown-to-PDF tool (shipped, v0.3.1), runs its pypdf checks through it. Caveat: upgrading uv does not upgrade the Pythons it installed. uv 0.13.4 dropped the emSign ECC Root CA - G3 root, whose intermediates were compromised (GHSA-hq85-5cpj-mr62), from its own certificate store. Run uv python upgrade: the 0.13.5 builds for 3.11 and newer ship pip 26.2.2, whose certifi drops the root. Pinned virtual environments keep the old build, existing ones need a pip upgrade, and 3.10 and older get no fixed build. On 5 November my uv was 0.13.7, yet every managed build I had installed still carried a pip that trusts the root, and uv, by default, preferred them to Homebrew's newer Pythons.
Colima 0.10.3. Container runtimes in a Linux VM on macOS, through Lima: Docker, containerd or Incus. Docker on my Mac runs through it, and VaultOre lists it as an engine. Caveat: by default only your home folder is shared with the VM, where Docker looks up bind-mount sources. A -v from anywhere else, such as /private/tmp, mounts an empty directory that Docker creates in the VM, with no error. The fix, from Colima's FAQ: list the folder under mounts: in colima.yaml, then run colima restart. List ~/ with writable: true as well, because any entry replaces the home default. --mount does not create a missing source, so this check, which I ran with 0.10.3, fails when the VM lacks the folder and otherwise shows what the container got:
# run it from the folder you want to mount
docker run --rm --mount "type=bind,source=$PWD,target=/w,readonly" alpine:3.20 grep ' /w ' /proc/mounts
# ... /w fuse.sshfs ... or /w virtiofs ... -> shared from the Mac
# ... /w ext4 ... -> a directory on the VM's own disk, not your folder
# ... bind source path does not exist: ... -> the VM cannot see this folder
GitHub and CI
MegaLinter 10.2.0. Runs linters, formatters and security scanners in one Docker image, configured by one .mega-linter.yml. It is the lint gate in three of my public repositories, among them alfred-little-snitch-control. Both issues I reported in October are closed as fixed in 10.2.0; my note on FAIL_IF_UPDATED_SOURCES describes them. Caveat: markdownlint counts as a formatter, and by default a formatter's errors do not fail the run. It is documented, and Linter.py lines 255-265 implement it; prettier and shfmt are formatters too. In August, on 10.0.0, markdownlint found three errors in alfred-little-snitch-control's CHANGELOG.md on main, the log said "Successfully linted all files, but with ignored errors", and the check stayed green (PR #23). Set FORMATTERS_DISABLE_ERRORS: false in .mega-linter.yml, as all three of mine do.
Dependabot, core 0.403.0. GitHub's hosted service for version and security updates; the release is dependabot-core's, the MIT-licensed library at its heart. It runs weekly in five of my public repositories and on this site. Caveat: in a Bun workspace, list only the root directory in dependabot.yml. VaultOre first listed /packages/* next to /; on 18 August Dependabot opened seven per-package PRs, each changing one package.json and not bun.lock. All seven failed bun install --frozen-lockfile with "lockfile had changes, but lockfile is frozen". With a single directory: "/", all 25 PRs that followed, up to 3 November, changed bun.lock. The npm updater's PRs had the same defect; since core 0.398.0 it stops with an error that says to set package-ecosystem: "bun" instead.
GitHub CLI 2.103.3. GitHub's command-line client, with gh api for authenticated calls to its APIs. My tools' release workflows call it. Caveat: gh api still expands :owner, :repo and :branch anywhere in the endpoint, query string included, although its help switched to {owner}, {repo} and {branch} in 1.10.0. In a clone, or with GH_REPO set (except for :branch), it does so silently: in my OKF Vault Kit clone, search/repositories?q=topic:repo went out as q=topicokf-vault-kit, found 0 repositories instead of 680 and exited 0. Elsewhere the call fails. I reproduced both with 2.103.3. An audit-log phrase such as action:repo.archived is rewritten too; a repo:cli/cli qualifier is not. -F values are expanded as well, -f values are not, so pass the query as -X GET -f q=topic:repo, or write the colon as %3A:
gh api --verbose 'search/repositories?q=topic:repo' | grep '^> GET'
# in a clone: > GET /search/repositories?q=topic<repo-name> HTTP/1.1
# outside a repository: unable to expand placeholder in path: failed to run git: ...
gh api --verbose 'search/repositories?q=topic%3Arepo' | grep '^> GET'
# anywhere: > GET /search/repositories?q=topic%3Arepo HTTP/1.1
Notes and documents
pandoc 3.13. Converts between document formats and writes PDF through LaTeX; YAML front matter reaches its templates as metadata. schriftsatz drives it: its cask pulls in Homebrew's pandoc, 3.13 since 29 October, though schriftsatz's CI tests only up to 3.10.2. Caveat: 3.13 parses metadata as YAML 1.2, so yes, no, on, off, y and n are strings, not booleans, and a duplicate key is an error, no longer a warning. indent: no becomes the string no, which templates treat as true: LaTeX output indents first lines. -V sets only strings, so -V indent=false inverts too, as schriftsatz once shipped (issue #45); since 3.7, --variable-json sets booleans. I reproduced both changes with 3.13 on 5 November; the earlier behaviour is from the release notes. Write true and false, as the schriftsatz README does, and check what your front matter parses to:
pandoc DOC.md -t json | jq -c '.meta | map_values(.t)'
# indent: no gives {"indent":"MetaInlines"}, a string; a boolean shows "MetaBool"
Obsidian 1.15.0. A Markdown note app, proprietary but free for any use. I run it; VaultOre is a plugin for it and OKF Vault Kit a vault template. Caveat: "Obsidian no longer includes Mermaid", says the 1.15 changelog. Obsidian's own MIT-licensed library, Pele, now draws Mermaid blocks with its own layout and visual style, and the "Show Mermaid diagrams in notes" setting is gone. I listed the app's archives with @electron/asar 4.3.1: 1.14.5 ships /lib/mermaid.min.js beside Pele 1.8.0, and 1.15.0 the same Pele file alone. CSS written for Mermaid no longer matches: diagram elements carry .pele-* classes, and new --mermaid-* variables set colours, corner radius and font weights. For plugins, loadMermaid() and window.mermaid now draw with Pele, and the node names of closing formatting tokens gain a formatting-*-end segment, so a full-name match such as formatting-code_inline-code misses them; the changelog says to match formatting-code instead. VaultOre uses none of these.
Since October
All nine caveats in October's roundup still hold, and four of its tools have new releases:
- gh-stack 0.3.0 (26 October):
pushandsubmitare atomic by default. Its merge docs are unchanged, so the tip-only CI caveat stands. - jj 0.47.0 and 0.47.1 (4 and 5 November): in non-colocated workspaces,
jj git fetchandpushno longer update remote-tracking Git refs (usejj git export).git.colocatestill defaults to true, so the.jjcaveat stands. - container 1.6.0 (20 October): fixes two medium-severity advisories. A pull by digest did not verify that the registry returned the pinned digest (GHSA-vgrw-36j7-r93w), and
container buildcould serve files outside the build context when a symlink was swapped during a read (GHSA-fqxg-rrf3-358v). 1.6.1 followed on 23 October. - skills 1.7.5 and 1.7.6 (2 and 3 November): 1.7.5 stops the installer from copying symlink targets from outside a skill's directory (PR #2589), and 1.7.6 extends that to links nested in linked directories and to
skills use(PR #2652). Before that, a skill could link to, say, your project's.env, and the installer copied its contents into the skill, inside your project, where a later push could carry it. No GitHub advisory was published, so Dependabot has nothing to alert on.
qmd 2.8.3, git-cliff 2.14.2, gitleaks 8.30.1 and lychee 0.24.2 are still the latest releases, and the Open Knowledge Format spec is still at 0.2.