Skip to content

chore(deps): bump the go-modules group with 2 updates#138

Open
dependabot[bot] wants to merge 277 commits into
mainfrom
dependabot/go_modules/go-modules-e1a70ce3f6
Open

chore(deps): bump the go-modules group with 2 updates#138
dependabot[bot] wants to merge 277 commits into
mainfrom
dependabot/go_modules/go-modules-e1a70ce3f6

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jul 24, 2026

Copy link
Copy Markdown

Bumps the go-modules group with 2 updates: github.com/go-git/go-billy/v6 and modernc.org/sqlite.

Updates github.com/go-git/go-billy/v6 from 6.0.0-alpha.1 to 6.0.0-alpha.2

Commits
  • f9d9371 Merge pull request #227 from go-git/renovate/main-golang
  • 344ff97 build: Update module golang.org/x/sys to v0.47.0
  • 606e1d5 Merge pull request #218 from jfontan/mmap-addcleanup
  • 0741775 Send map and file as arguments to cleanup function
  • 695a78d Merge pull request #222 from go-git/renovate/main-tooling
  • cf99603 build: Update dependency golangci/golangci-lint to v2.12.2
  • 9bd8928 Merge pull request #223 from go-git/renovate/main-golang
  • 726cf1c build: Update module golang.org/x/sys to v0.46.0
  • 286d10f osfs: close mmap file in cleanup and improve mmap clean test
  • 1b220c4 Merge pull request #219 from go-git/renovate/main-tooling
  • Additional commits viewable in compare view

Updates modernc.org/sqlite from 1.53.0 to 1.54.0

Changelog

Sourced from modernc.org/sqlite's changelog.

Changelog

  • 2026-07-20 v1.55.0:

    • Add github.com/mattn/go-sqlite3-compatible shorthand DSN query parameters to ease migration from that driver: _busy_timeout/_timeout, _foreign_keys/_fk, _journal_mode/_journal, _synchronous/_sync, _auto_vacuum/_vacuum, and _query_only, each setting the correspondingly named PRAGMA. Values are validated against the same set mattn/go-sqlite3 accepts (case-insensitive) and an unrecognized value fails the connection with an error, so a typo such as _synchronous=fu1l or _foreign_keys=yes_please is reported rather than silently downgrading durability or dropping foreign-key enforcement. The keys are applied in a fixed order independent of their order in the DSN — _busy_timeout and _auto_vacuum before any _pragma values (auto_vacuum must be set before the database is first written), the rest after, and _query_only last — and where a key and its alias are both supplied the alias wins, matching mattn/go-sqlite3; selection is by presence rather than by value, so supplying the alias empty (_foreign_keys=on&_fk=) suppresses the PRAGMA rather than deferring to the primary key, again matching that driver. Behavior change to note: prior releases ignored these keys entirely, so a DSN carried over from a mattn/go-sqlite3 setup changes in two ways. A recognized key that previously did nothing now takes effect — _foreign_keys=on begins enforcing constraints against data that may already violate them, _journal_mode=wal persistently converts the database file, and _query_only=1 makes the connection read-only. And a value outside the accepted set now fails the connection with an error where the same DSN previously opened successfully — for example a duration-style _busy_timeout=5s or _timeout=5000ms, neither of which is the integer that key requires. Review such DSNs before upgrading. _pragma is unchanged and no pre-existing parameter changes meaning, though see the following entry for a change in when all of them are validated.
    • See [GitLab merge request #134](https://gitlab.com/cznic/sqlite/-/merge_requests/134), thanks Toni Spets (@​beeper-hifi) and Ian Chechin!
    • Validate every DSN query parameter before applying any of them. Parameters were previously checked as each was reached, so a DSN whose later parameter was rejected had already executed the PRAGMAs ahead of it. Because PRAGMA journal_mode and PRAGMA auto_vacuum are persistent changes to the database file, a DSN such as file:x.db?_journal_mode=wal&_synchronous=bogus failed the connection and yet left x.db converted to WAL. A failed Open now leaves the database as it found it. This covers the pre-existing _txlock, _timezone, _time_format, _time_integer_format, _inttotime and _texttotime parameters as well as the shorthand keys above: all of them were validated only after the _pragma list had already run, so the same DSN shape — a valid _pragma=journal_mode=wal alongside a misspelled _txlock — converted the file before reporting the error. Only the values accepted for each parameter are unchanged; a DSN that opened successfully before still opens, and one that failed still fails with the same error. _pragma remains the sole exception, since its values are executed verbatim and cannot be checked in advance: a malformed _pragma is still rejected by SQLite as it runs, after any earlier _pragma in the list has taken effect.
  • 2026-07-15 v1.54.0:

    • Upgrade to SQLite 3.53.3. This also bumps the pinned modernc.org/libc to v1.74.1; as always, downstream modules must pin the exact same modernc.org/libc version this module's go.mod pins (see [GitLab issue #177](https://gitlab.com/cznic/sqlite/-/issues/177)).
    • Under the opt-in _texttotime DSN parameter, best-effort parse date-shaped TEXT values from columns SQLite reports with an empty declared type — aggregates and expressions over a date column (MAX(d), COALESCE(d, ...), upper(d), d || ''), subqueries, and typeless real columns (CREATE TABLE t(x)) — into time.Time, instead of delivering them as a raw string that Scan cannot store into a *time.Time. The existing declared DATE/DATETIME/TIME/TIMESTAMP path is unchanged; this only adds the empty-decltype case. The conversion is strictly best-effort: a value that does not parse as a time falls through to the original string, so no Scan that worked before can newly fail. ColumnTypeScanType continues to report string for empty-decltype columns, since the declared type cannot prove the column is temporal. Without _texttotime the behavior is byte-for-byte unchanged. Resolves [GitLab issue #248](https://gitlab.com/cznic/sqlite/-/issues/248).
    • See [GitLab merge request #133](https://gitlab.com/cznic/sqlite/-/merge_requests/133), thanks Ian Chechin!
  • 2026-06-21 v1.53.0:

    • Add experimental netbsd/amd64 support, resolving the long-standing build break in [GitLab issue #246](https://gitlab.com/cznic/sqlite/-/issues/246). This target is intentionally not yet listed among the supported platforms in the package documentation: the port had been broken for years and is only now revived, and there is as yet no real-world experience running it under production workloads. Green CI is not the same as battle-tested — so while the full test suite (including the pcache and vec packages and the -race concurrency test) passes on NetBSD 10.1 / Go 1.26.3, and the entire upstream toolchain (libc, cc, ccgo, libz, libtcl8.6, libsqlite3, libsqlite_vec) is green on the NetBSD CI builder, the target is offered for evaluation only. If you run NetBSD, please exercise it with your own workloads and report back via #246; the intent is to promote it to a fully supported platform after a period of broader real-world testing (on the order of a month) elapses without surprises.
    • Implementation notes: the previously shipped lib/sqlite_netbsd_amd64.go was a stale old-generator transpile that no longer compiled (the mu.enter/mu.leave break in #246); it is replaced by a fresh new-generator transpile consistent with every other platform, and modernc.org/sqlite/vec (sqlite-vec) is vendored and auto-registers on netbsd. Correct operation requires the matching pinned modernc.org/libc, which carries two NetBSD-specific fixes found during this work: the mmap(2) PAD-argument ABI (without it, concurrent WAL access faults with SIGBUS in the WAL-index shared memory) and a working abort(3) (the prior stub left SQLite's crash-recovery writecrash test unable to terminate by signal). As usual, downstream modules must pin the exact modernc.org/libc version this module's go.mod pins.
    • See [GitLab merge request #82](https://gitlab.com/cznic/sqlite/-/merge_requests/82), thanks Leonardo Taccari (@​iamleot) and Thomas Klausner (@wiz)!
    • Add experimental freebsd/386 and freebsd/arm support. As with the netbsd/amd64 target above, these two 32-bit FreeBSD ports are intentionally not yet listed among the supported platforms in the package documentation: freebsd/386 previously shipped a stale, effectively untested SQLite 3.41 transpile, and freebsd/arm is entirely new, so neither has real-world production mileage yet. Both are now freshly transpiled at SQLite 3.53.2 consistent with every other platform, build cleanly, and pass the full test suite (core, WAL/concurrency, and the vec package) on the FreeBSD CI builders; they are offered for evaluation only. If you run 32-bit FreeBSD, please exercise these targets with your own workloads and report back — the intent is to promote freebsd/386, freebsd/arm, and netbsd/amd64 to fully supported platforms in a future release cycle, once a period of broader real-world testing elapses without surprises.
    • Implementation notes: correct operation on freebsd/arm requires the matching pinned modernc.org/libc (v1.73.4), which fixes the per-arch mmap(2) off_t encoding for 32-bit FreeBSD; without it the WAL shared-memory mapping faults with SIGBUS under concurrent access, the same class of bug found on the netbsd port. As usual, downstream modules must pin the exact modernc.org/libc version this module's go.mod pins.
    • See [GitLab merge request #119](https://gitlab.com/cznic/sqlite/-/merge_requests/119), thanks Olivier Cochard-Labbé (@​ocochard)!
    • Add a Go-facing wrapper for SQLITE_CONFIG_PCACHE2. PageCache is the factory and Cache the per-database instance, both idiomatic Go interfaces; Page exposes the raw Buf and Extra pointers that SQLite reads through the C pcache contract. RegisterPageCache and MustRegisterPageCache install the module process-globally before the first sql.Open; subsequent Open calls are gated through a one-shot Xsqlite3_config(SQLITE_CONFIG_PCACHE2) so a too-late Register returns ErrPageCacheTooLate rather than silently falling through to the built-in pcache1. The binding owns the sqlite3_pcache_page stub and re-consults the implementation on every Fetch, reusing the stub only when the returned Page value is unchanged, which keeps a bounded/evicting purgeable cache safe by construction.
    • See [GitLab merge request #126](https://gitlab.com/cznic/sqlite/-/merge_requests/126), thanks Ian Chechin!
    • Add modernc.org/sqlite/pcache, the reference page-cache implementation that accompanies the #126 SQLITE_CONFIG_PCACHE2 wrapper. pcache.New returns a *Pool satisfying the PageCache interface; register it once with sqlite.MustRegisterPageCache(pcache.New()) and every connection opened afterwards draws its pages from it. Each Pool.Create mints a fresh per-database Cache: a bounded, LRU-evicting page store that honours the PRAGMA cache_size soft cap and releases the least-recently-unpinned page when it must make room. Page memory — the Buf and Extra buffers SQLite reads through — is allocated with libc.Xmalloc/libc.Xcalloc and therefore lives off the Go heap, which keeps SQLite's interior pointer arithmetic on the page extras from tripping the race detector's checkptr enforcement. Pool.Stats reports aggregate lifetime counters (hits, misses, allocs, evictions, rekeys, truncates, caches) across every cache a Pool has created, so hit/miss/eviction behaviour is observable without instrumenting individual caches. Cross-connection page sharing is out of scope for now; each Create returns an independent per-database cache.
    • Validated end-to-end against the #126 stress workload (cache_size=16, 4000 BLOB rows with DELETE and incremental_vacuum, integrity_check clean under -race) and benchmarked for the memory-utilization goal tracked in [GitLab issue #204](https://gitlab.com/cznic/sqlite/-/issues/204).
    • See [GitLab merge request #127](https://gitlab.com/cznic/sqlite/-/merge_requests/127), thanks Ian Chechin!
    • Tighten the modernc.org/sqlite/pcache reference implementation per cznic's !127 review follow-ups. Adds Stats.EasyRefusals, a per-Pool counter for the cases where FetchCreateEasy returns nil at cap; SQLite reacts to a refusal by spilling dirty pages and retrying with FetchCreateForce, so the new field is a direct proxy for the I/O pressure the strict Easy contract imposes vs pcache1's recycle-without-spill behavior. BenchmarkPoolEvictionChurn was reworked to drive a rotating-residue DELETE (k % 3 = i % 3) and re-insert a matching batch each cycle so the spill pressure recurs and easy-refusals/op scales with b.N instead of capping at the seed's one-time first-cycle cost; both existing benchmarks now report easy-refusals/op alongside the page-allocs/evictions metrics. Stats.Evictions documentation was tightened to match the actual behavior (counts LRU eviction, Unpin(discard=true), Shrink releases, and Unpin(discard=false) trimming back to target after a FetchCreateForce overcommit; bulk frees from Truncate, Rekey collisions, and Destroy are not counted). The TestPoolRoundTripIntegrity comment claiming the workload exercises xRekey ~15 times has been corrected; the SQL surface does not reliably emit xRekey here, and that codepath is covered by the unit tests instead.
    • See [GitLab merge request #130](https://gitlab.com/cznic/sqlite/-/merge_requests/130), thanks Ian Chechin!
    • Make modernc.org/sqlite/pcache -race-clean under SQLite's cache=shared mode. The pool already runs correctly under shared-cache because every callback into a given Cache is serialised internally by SQLite's sqlite3BtreeEnter on the BtShared mutex; verified empirically with a lock-free in-flight probe (max-in-flight = 1 on the canonical two-connection workload, 4 on a positive control with goroutines hitting the cache directly). However the Go race detector does not recognise SQLite's libc mutex as a happens-before edge and reports false-positive races on Fetch vs Unpin reads/writes of the per-cache state, which surfaces as DATA RACE failures for any user who registers the pool and runs their suite under -race. A sync.Mutex on the cache type is now taken on every public method (SetSize, PageCount, Fetch, Unpin, Rekey, Truncate, Destroy, Shrink), always. On the common non-shared-cache path the lock is uncontended (one atomic CAS per Lock/Unlock pair, negligible next to the SQLite work it bookends); on the shared-cache path it just rubber-stamps the order SQLite's BtShared mutex already established. A new e2e_test.go TestSharedCacheTwoConns_Integrity drives two sql.Conn against the same cache=shared URI with concurrent writers and asserts PRAGMA integrity_check = ok under -race; passes cleanly with the lock, would surface the false-positive without it. Design notes live in pcache/sharing.go.
    • See [GitLab merge request #131](https://gitlab.com/cznic/sqlite/-/merge_requests/131), thanks Ian Chechin!
    • Add a Go wrapper for sqlite3_db_status, the per-connection runtime counters (cache hit/miss/write/spill rates, schema and prepared-statement memory, lookaside usage, deferred foreign keys). DBStatus is an interface implemented by the driver connection and reached through the database/sql escape hatch (*sql.Conn).Raw(), mirroring the existing FileControl surface; DBStatusOp is a distinct typed enum of the SQLITE_DBSTATUS_* verbs so a counter from a different op family will not compile in its place. Status(op, reset) returns the (current, high) pair and optionally resets the counter. This also lets modernc.org/sqlite/pcache measure real I/O instead of the EasyRefusals proxy: the new BenchmarkPoolSpillIO reads the pager-level SQLITE_DBSTATUS_CACHE_SPILL/_CACHE_WRITE counters, which the pager maintains identically for pcache1 and the pool, making the pcache1-vs-pool comparison cznic raised on the !127 review a genuine apples-to-apples measurement. On the rotating-residue eviction-churn workload at cache_size=16 the pool spills ~3.5x more than pcache1 (cache-spill/op 31.96 vs 8.96) for ~3% more page writes (cache-write/op 450 vs 436) at identical hit/miss, quantifying the I/O cost of the strict Easy contract that EasyRefusals only proxied.
    • See [GitLab merge request #132](https://gitlab.com/cznic/sqlite/-/merge_requests/132), thanks Ian Chechin!
    • Add an opt-in _dqs DSN query parameter that disables SQLite's double-quoted string literal compatibility quirk on a per-connection basis. When _dqs=0 (or any strconv.ParseBool false value) is supplied, the driver calls sqlite3_db_config with SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML set to off before any statement is prepared, so a double-quoted identifier that fails to resolve raises a parse error instead of silently falling back to a string literal. Absence of the parameter, or _dqs=1, leaves SQLite's default behavior unchanged; existing DSNs continue to work byte-for-byte. Resolves [GitLab issue #61](https://gitlab.com/cznic/sqlite/-/issues/61).
    • See [GitLab merge request #128](https://gitlab.com/cznic/sqlite/-/merge_requests/128), thanks Ian Chechin!
    • Add an opt-in _error_rc DSN query parameter for clearer error reporting on open-time failures. When _error_rc=1 (or any strconv.ParseBool true value) is supplied, error strings synthesised from a (rc, db) pair only append sqlite3_errmsg(db) when sqlite3_extended_errcode(db) is consistent with the operation rc (full match first, primary code &0xff as fallback). On mismatch the canonical sqlite3_errstr(rc) is used alone, so an open-time SQLITE_CANTOPEN no longer carries the temporary handle's stale "out of memory" errmsg. Absence of the parameter, or _error_rc=0, preserves the legacy "errstr: errmsg" form byte-for-byte; existing callers that parse error strings are unaffected. The driver's *Error.Code() returns the same SQLite result code in both modes. Parsed before sqlite3_open_v2 so open-time errors are covered. Resolves [GitLab issue #230](https://gitlab.com/cznic/sqlite/-/issues/230).
    • See [GitLab merge request #129](https://gitlab.com/cznic/sqlite/-/merge_requests/129), thanks Ian Chechin!
  • 2026-06-06 v1.52.0:

    • Upgrade to SQLite 3.53.2.
    • Add Backup.Remaining and Backup.PageCount, thin wrappers around the existing sqlite3_backup_remaining and sqlite3_backup_pagecount C symbols. Together they expose the per-Step progress counters that the underlying backup object already maintains, enabling progress reporting during online backups without dropping to modernc.org/sqlite/lib directly.
    • See [GitLab merge request #122](https://gitlab.com/cznic/sqlite/-/merge_requests/122), thanks Ian Chechin!
    • Drop the redundant second copy in (*conn).columnText, the path that backs every Rows.Scan into a Go string for a TEXT column. The value's bytes are still copied once out of SQLite-owned memory into a fresh Go buffer; that buffer is then reinterpreted as the result string with unsafe.String rather than copied a second time by the implicit string([]byte) conversion. This removes one allocation per TEXT value per row and roughly halves the bytes allocated on that path; on the new BenchmarkColumnTextScan cases it is ~13–20% faster for payloads of 256 B and larger, with no measurable change for very short strings. Purely internal: no API or behavioral change, and the returned string never aliases SQLite's buffer.
    • See [GitLab merge request #123](https://gitlab.com/cznic/sqlite/-/merge_requests/123), thanks Ian Chechin!
    • Cache each result column's declared type once per result set in newRows instead of recomputing it on every row. The TEXT branch of Rows.Next calls ColumnTypeDatabaseTypeName for every TEXT column on every row (independent of any DSN flag), which previously did a libc.GoString + strings.ToUpper each time; that lookup is now a single index into a cached, pre-uppercased []string, and ColumnTypeScanType reads the same cache and drops its per-call strings.ToLower. The declared type is fixed for the lifetime of a prepared statement, so the C round-trip is paid once per column rather than once per column per row, removing exactly 1 alloc + 8 B per TEXT column per row from the Next hot path. The new BenchmarkTextToTimeScan cases show ~7% faster on a 1000-row DATETIME SELECT under _texttotime=1. Purely internal: ColumnTypeDatabaseTypeName and ColumnTypeScanType return identical values, no API or behavioral change.
    • See [GitLab merge request #124](https://gitlab.com/cznic/sqlite/-/merge_requests/124), thanks Ian Chechin!
    • Cache, per result column, the parseTimeFormats index that first parsed a TEXT-stored DATE/DATETIME/TIMESTAMP value, and try that format first on later rows instead of re-walking the list from the top. (*conn).parseTime previously ran time.Parse down the format list on every such row; for the canonical SQLite TEXT datetime format every row paid two failed time.Parse attempts — each allocating a *time.ParseError — before the match. On a 1000-row DATETIME TEXT SELECT this cuts ~50% of allocs/op and ~57% of B/op and is ~37% faster. The fall-through chain is preserved exactly: the seven formats are mutually exclusive, so the cached hint can never select a different match than the in-order scan, and the parsed driver.Value is identical to before. Purely internal: no API or behavioral change.
    • See [GitLab merge request #125](https://gitlab.com/cznic/sqlite/-/merge_requests/125), thanks Ian Chechin!
  • 2026-05-28 v1.51.0:

    • Pool the []driver.Value slice passed to scalar/aggregate UDF callbacks and to vtab Filter/Insert/Update callbacks, eliminating the dominant per-row allocation on UDF-heavy queries. Benchmarks on a 1000-row, 3-arg noop scalar UDF show ~40% fewer bytes/op and ~15% fewer allocs/op.
    • Document the matching "arguments are not valid past return" contract on vtab.Cursor.Filter and vtab.Updater.Insert/Update, consistent with the existing rule for FunctionImpl.Scalar / AggregateFunction.Step / WindowInverse.
    • Resolves [GitLab issue #226](https://gitlab.com/cznic/sqlite/-/issues/226). See [GitLab merge request #114](https://gitlab.com/cznic/sqlite/-/merge_requests/114), thanks Ian Chechin!

... (truncated)

Commits
  • 693ff38 upgrade to SQLite 3.53.3
  • 5d24346 Merge branch 'texttotime-aggregates' into 'master'
  • 892d847 sqlite: document _texttotime empty-decltype upgrade, widen #248 comment, add ...
  • f2c8758 sqlite: _texttotime best-effort parse for empty-decltype TEXT columns (#248)
  • See full diff in compare view

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore <dependency name> major version will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)
  • @dependabot ignore <dependency name> minor version will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)
  • @dependabot ignore <dependency name> will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)
  • @dependabot unignore <dependency name> will remove all of the ignore conditions of the specified dependency
  • @dependabot unignore <dependency name> <ignore condition> will remove the ignore condition of the specified dependency and ignore conditions

jig and others added 30 commits July 2, 2026 23:08
VSCode spawns the debug adapter with an arbitrary working directory
(often /), which broke require's git-root search (.lisp/ was never
found) and any relative load-file path. The launch request now accepts
a `cwd` argument applied with os.Chdir before the program runs; the
extension defaults it to the workspace folder (launch.json can
override) and also spawns the LSP server at the workspace root for the
same reason. Extension version bumped to 0.3.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
go test ./... skips every build-tagged package (debugadapter, the
DAP/LSP command wiring), so the debugger tests never ran in CI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The only DAP request paths without any coverage: Shift-F11 from inside
a function body must stop at the caller's level, and pause must
interrupt a running program at the next evaluated form.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Future goroutines inherited the spawning context's runtime.Thread, so
their EVALs pushed/popped frames on the same live stack as the main
goroutine (corrupting stack traces and step depths) and could pause a
goroutine the client did not know about.

- concurrent.NewFuture now detaches the debug thread from the future's
  context (runtime.DetachThread, no-op in release builds)
- the DAP hook only reacts on the goroutine carrying the session's
  Thread; evaluations elsewhere (futures, Debug Console) never pause

Known limitation documented in the extension README: code inside
(future …) does not hit breakpoints and cannot be stepped. Full
multi-thread debugging is future work.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two editor features:

- lisp.languageServer.includeDirs: extra require search directories for
  the editor, sent as LSP initializationOptions and appended to the
  require cascade (the editor equivalent of the interpreter's -i).
  Without it, projects relying on -i showed unresolved requires in
  VSCode.

- textDocument/definition (F12): document-local definitions jump within
  the file; definitions imported through require jump into the module's
  file, using the position information the import analysis already
  carried.

Extension version bumped to 0.4.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Backlog with effort/risk/impact estimates and code entry points,
ordered from surgical quick wins to invasive changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
$NAME placeholders — the READWithPreamble mechanism Go embedders use to
pass data into lisp code — were unusable for scripts run from the CLI
or the debugger: load-file goes through read-string, which handed the
reader a nil placeholder map, and any $NAME in the file crashed with
"invalid memory address or nil pointer dereference".

- reader: a placeholder without provided values is now a proper parse
  error naming the placeholder instead of a panic
- new -P/--preamble flag (repeatable): `-P '$NUMBER 1984'`. Values also
  come from leading `;; $NAME <expr>` lines in the file itself
  (defaults); flags win. A placeholder with no value anywhere reads as
  nil (the historical READWithPreamble behaviour)
- runScript: with placeholders the file is evaluated directly with the
  same `;; $MODULE` wrapper load-file builds, so source rows — and
  therefore breakpoints — keep matching the on-disk file (verified
  end-to-end: BP on line 3 of a placeholder-bearing script); without
  placeholders the classic load-file path runs unchanged
- DAP: --preamble applies to debugged scripts; the extension forwards a
  `preamble` array from launch.json as --preamble flags (v0.5.0)
- LSP: analysed documents accept placeholders (treated as nil) instead
  of flagging every placeholder-bearing file as a parse error

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
test-preamble.lisp carries in-file placeholder defaults; the "LISP
DEBUGGER: PREAMBLE TEST" launch configuration overrides them through
the preamble attribute (forwarded as --preamble flags).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The single "Locals" scope enumerated the whole environment chain, so a
paused frame showed the user's bindings drowned among ~150 core
builtins. Scopes now mirror the env nesting, one per level, each
listing only its own bindings: "Locals" (the frame's immediate env),
"Closure"/"Closure N" (enclosing fn/let levels) and "Globals" (the root
env, complete — user defs and builtins alike, useful to review what is
loaded — marked expensive so clients keep it collapsed by default).

env gains an Outer() accessor alongside LocalSymbols().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
$NAME placeholders are read-time substitutions, invisible at run time,
so the editor is the only place to surface them: hovering one shows its
in-file default and origin line (or, when the file provides none, an
explanation that the value arrives at run time via --preamble /
launch.json / Go embedding and reads as nil when absent). F12 jumps to
the `;; $NAME <expr>` line and completion offers in-file placeholders
with their default.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds highlighting the old grammar missed: $NAME preamble placeholders
(including the leading `;; $NAME <expr>` default lines), ¬…¬ notation
strings with the ¬¬ escape, #{ set literals, the ^ metadata marker,
core macros (when, cond, and, or, ->, ->>, require, future, …), the
name being defined by def/defn/defmacro, and symbols in call position
as function names. Extension 0.5.1.

Semantic (LSP-computed) highlighting remains a roadmap item; this layer
is static TextMate config.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
<BINARY>PATH (LISPPATH for the default binary), OS path-list separated,
extends the require search cascade. Placed after the git-root .lisp/ so
a project's own modules always win over the shell environment — the
conservative placement, and the per-binary name keeps it distinctive
(GOPATH/PYTHONPATH style). -i/--include dirs still take precedence.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The server handles workspace/didChangeWatchedFiles by re-analysing
every open document (resolveRequires reads module files fresh from
disk), so editing a required module refreshes imported definitions and
require diagnostics in documents that use it — even when the module is
not open in an editor. The extension registers a **/*.{lisp,mal} file
watcher so the notification fires for those out-of-editor changes.
Extension 0.6.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
textDocument/signatureHelp shows the parameter list of the call form
surrounding the cursor, highlighting the argument being typed. The
enclosing call and active parameter are found by a bracket/string-aware
text scan; parameters come from user-defined defn/defmacro, local or
imported through require (qualified or :refer'd). Builtins carry no
parameter metadata and yield no signature. Triggered on space and `(`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signature help and hover now read parameter names from the interpreter
environment: any lisp-defined library function or macro (defn/defmacro,
e.g. reduce, partial, when, cond, ->, future) is a MalFunc whose Params
vector carries the real names, so signature help and hover show a
proper arglist without any annotation. The variadic `&` marker is
dropped from parameter labels so trailing arguments map to the rest
parameter.

Pure Go builtins keep no parameter metadata (Go reflection exposes
arity and types but not names), so they still yield no signature; a
curated arglist map would be needed to cover them (noted in ROADMAP).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(defn name "docstring" [params] body…) stores the docstring as
{:doc "…"} metadata on the function, retrievable with (doc name) (new
coreextended helper), (meta f), tooling. Implemented in the header lisp
macro (with-meta on the MalFunc); no interpreter core change. Fully
backwards compatible: a leading string is treated as a docstring only
when a parameter vector follows it, so (defn f [x] "literal") still
returns the string.

The LSP surfaces docstrings in hover, for document-local definitions
(definitionOf now parses the optional docstring so parameters are not
misread) and for functions/macros resolved from the interpreter
environment (via the {:doc …} MalFunc metadata).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New leaf package docmeta is the single source of truth for what the
interpreter cannot describe by itself: pure Go builtins (Go reflection
exposes arity and types but not parameter names) and special forms
(handled by EVAL's switch, never present in the environment). Each
entry carries an arglist, a kind (function/special form), a group for
the future reference-doc generator, and a one-line description. A
consistency test asserts every Function entry resolves as a Go builtin
in a loaded env and every SpecialForm entry is absent from it, so the
table cannot silently drift from reality.

The LSP consumes it: hover, signature help and completion now cover
curated Go builtins and — for the first time — special forms (do, if,
let, fn, quote, try/catch/finally, …), which resolve nowhere else.
Lisp-defined functions and macros are intentionally not in the table:
their MalFunc value already carries real parameter names and docstring
metadata, read from the live environment.

A representative common subset is filled in; the table extends
incrementally, guarded by the consistency test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… table

Documentation for Go builtins now travels with the value in the
environment instead of a static table compiled into the LSP, so tooling
reflects exactly what an interpreter loads — including an embedder's own
builtins. types.Func gains Doc/Arglist fields, attached at registration
with the new call.Doc(env, name, arglist, doc); each namespace
documents its own builtins next to their registration (core, concurrent
so far). A new Go (doc name) builtin reads them (and the {:doc} metadata
of lisp-defined functions/macros), replacing the old lisp doc helper.

Crucially the documentation is kept OFF metadata: (meta +) stays nil, as
kanaka/mal requires — an earlier attempt to store it in Func.Meta broke
the canonical stepA_mal.mal assertion. This matches Clojure too, where a
function value's meta is nil and docs live on the var.

docmeta shrinks to just special forms (do, if, let, fn, quote,
try/catch/finally, …), which are handled by EVAL and never bound in an
environment, so a static table is the only place for them. Per-namespace
consistency tests assert every documented builtin is registered with nil
meta, and every documented special form is absent from the env.

The LSP reads builtin arglists/docs from the environment (Func fields or
MalFunc params + docstring) and special forms from docmeta, for hover,
signature help and completion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fills in call.Doc metadata for the Go builtins that were still
undocumented, each next to its registration: core (collections,
base64/JSON, bytes, time, errors, set, macro?, assert, spew, …),
concurrent (future-*), system (getenv/setenv/unsetenv) and require
(require, resolve-require). Only internal deserialization constructors
(new-*) and the embedder-provided eval are intentionally left
undocumented. A system docs consistency test is added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
scan sliced list.Val[2:] (and [1:]) in the def/defn/defmacro/fn/let/
catch/require cases without checking the length, so a half-typed form
the reader returns as a short list — a bare (fn), (let), (def), … which
happen constantly while editing — panicked with "slice bounds out of
range [2:1]", crashing the language server (VSCode then stops
restarting it after five crashes).

All suffix slicing in scan now goes through a bounds-safe tail() helper.
Regression test covers a range of incomplete and nested-incomplete
forms.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add docstrings to every function/macro in header-coreextended.lisp so the
LSP surfaces them on hover and completion:

- plain fns via (defn name "doc" [params] body)
- macros and stateful closures via (with-meta … {:doc "…"})

Fix an inc docstring error (it is the integer successor, not predecessor)
and normalise the remaining (fn (args) …) forms to [args] so the LSP
renders clean arglists.

This makes coreextended depend on defn (from HeaderBasic); production load
order already satisfies that, so drop the redundant nscoreextended.Load
calls from the test helpers that loaded coreextended before HeaderBasic
(docstring_test, docmeta_test, require_test).

Extend debugadapter/test.lisp to exercise a docstring on sqr and hover on
a coreextended builtin (inc).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
core-test-base.mal and core-test_test.mal were leftovers from the
standalone `maltest` interpreter (cmd/maltest no longer exists). They
are not embedded, globbed or required anywhere, and core-test_test.mal
even called `test.suite` instead of the real `test-suite` macro.

Update the README to point at `lisp --test DIR`, which absorbed the
maltest behaviour and runs every *_test.mal in the directory.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- test.yml: bump checkout/setup-go v3 → v5; add a `quality` job running
  gofmt check and `go vet` in both the default and lispdebug builds.
- codeql.yml: CodeQL security scanning for Go (push/PR to main + weekly).
- lint.yml + .golangci.yml: golangci-lint (v2, lispdebug tag), kept
  non-blocking (continue-on-error) until the tree is clean.
- dependabot.yml: weekly updates for gomod, github-actions and the
  VSCode extension's npm deps, grouped to limit PR noise.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Configure golangci-lint to respect the interpreter's inherited kanaka/mal
conventions rather than churn the code:

- .golangci.yml: disable ST1001 (deliberate dot-import of `types`),
  ST1003 (`Foo_Q` predicate naming, part of the exported API), the
  ST1000/ST1020/ST1021 doc-comment format checks (section-header comment
  style), and the opt-in QF* quickfix suggestions.

Fix the genuine findings so the tree is clean:

- errcheck: handle the deferred/immediate Close() results on listeners,
  connections and pipes (command, repl, tests).
- staticcheck ST1019: drop the redundant qualified `types` import in the
  files that also dot-import it (concurrent, system, mal_test,
  placeholder_test), qualifying nothing new.
- staticcheck ST1016: unify *Position receiver names on `cursor`.
- govet: reflect.Ptr → reflect.Pointer.
- unused: remove the dead closeOnce/exited fields (and now-unused sync
  import) from the debug adapter.

lint.yml: drop continue-on-error and pin golangci-lint to v2.12.2, so a
future release with new linters surfaces as a Dependabot PR instead of
breaking main.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
actions/setup-go@v5 and golangci/golangci-lint-action@v7 still target
Node 20, which the runners now force onto Node 24 with a warning. Bump
to setup-go@v6 and golangci-lint-action@v9 (both node24); the latter
keeps the `version` input, so the pinned golangci-lint v2.12.2 is
unchanged. checkout@v5 already runs on node24.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Turn the mal-in-mal interpreter into a showcase of what jig/lisp adds
over kanaka/mal:

- rewrite every top-level definition as `defn` with a docstring (the
  multi-line ones use ¬…¬ strings, since " strings are single-line);
  these surface on LSP hover and via (doc name).
- extend the hosted `core_ns` with jig/lisp's extra *function* builtins
  (range, merge, get-in, assoc-in, update, reduce, take, uuid, sets, …)
  so programs interpreted by this mini-mal can use them; macros and
  special forms such as future/context/try stay out, as they can't be
  bound with (eval sym).
- teach the interpreted language a small `defn` macro of its own.
- refresh the banner/prompt to jig/lisp.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jig and others added 25 commits July 21, 2026 17:40
Pr_data now prints reader-macro expansions with their sugar instead of
the underlying call: (quote x)->'x, (quasiquote x)->`x, (unquote x)->~x,
(splice-unquote x)->~@x, (deref x)->@x, and (with-meta form meta)->
^meta form. Width-aware wrapping still applies (a long '[...] wraps with
the form aligned under the prefix), and the forms round-trip: the reader
re-expands the sugar to the same value.

This makes .state files (which serialize via Pr_data) read naturally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(printer): reader-macro sugar in Pr_data
The integrity audit log was one JSON line to stderr — fine for server
log ingestion, noisy for interactive use. Now, when stderr is a
terminal, print a human-readable block using the term package: a green
'✓ integrity verified' with ref/commit/signer each on its own line, or
a red '✗ integrity check failed' with the reason. When stderr is
redirected (pipe/file) the structured JSON line is kept, so machine
consumers are unaffected. Honors NO_COLOR / CLICOLOR_FORCE.

- lib/term: exported StderrStyle (Go-facing colorizer, stderr TTY +
  NO_COLOR/CLICOLOR_FORCE aware) and StderrIsTerminal; colorDecision
  refactored to take an fd.
- command: reportIntegrity/integrityBlock; a terminal failure prints
  the red block and returns ErrIntegrityReported so main exits non-zero
  without a second 'Error:' line.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(integrity): human-readable colored audit output on a terminal
Adds a regexp namespace, loaded by default, with first-class compiled
patterns and Clojure-style semantics:

- re-pattern compiles a reusable «regex …» value; the other functions
  accept a compiled regex or a raw pattern string (compiled on use).
- re-matches? / re-find? return booleans (anchored whole-string /
  unanchored substring).
- re-matches / re-find return Clojure-style match data: nil, the match
  string when there are no groups, or a vector [whole g1 g2 …] with an
  unmatched optional group as nil.

Patterns are Go RE2 (linear-time; no backreferences or lookaround) and
are written as raw ¬…¬ strings — jig/lisp's equivalent of Clojure's
#"…" literal, since a normal "…" string rejects \d. re-matches
anchors with \A(?:…)\z so it means the whole string regardless of
(?m). re-replace/re-split/re-seq are left for a later iteration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(regexp): regular expressions library (Go RE2)
state-save becomes variadic — (state-save name value & [message]) —
mirroring state-load. The message is the git commit message for the
state commit; it defaults to "state: name" as before, so existing
calls are unchanged. Nothing keys on the message (the .state/-only
descent check is path-based), so a custom message is safe.

Also make the command integrity tests' runGit helper hermetic (disable
commit.gpgsign/tag.gpgsign) so they don't fail on a machine whose global
git config enables signing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(integrity): optional commit message for state-save
Wrap the context-deadline tests (TestContextTimeoutFiresOnTime,
TestContextNoTimeout, the two future variants, TestTimeoutOnTryCatch) in
synctest.Test so the time package uses a fake clock: deadlines fire
deterministically (no wall-clock jitter) and instantly (no real wait).

This lets TestTimeoutOnTryCatch drop back to a tight 500ms deadline — the
value that was flaky under the real clock and which an earlier commit had
widened to 2s to paper over the jitter. Verified 30x under full CPU load,
all green, with and without -tags debugger. Also drops the redundant
concurrent.Load setup in the future tests (newEnv already loads it).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
test: run EVAL timeout tests under testing/synctest
…ve-all)

Adds to the system library:
- (chdir path)      -> nil; os.Chdir, process-global working directory.
- (cwd)             -> the working directory as an absolute path.
- (mkdtemp & [pfx]) -> a fresh unique temp directory (os.MkdirTemp).
- (remove-all path) -> nil; os.RemoveAll, recursive, no error if absent.

These let in-process tests drive state-save/state-load against a
temporary git repo (mkdtemp + git-init + chdir) instead of the real one,
verified end to end: state-save creates the first commit on an unborn
branch and state-load reads it back, both without --integrity.

The Go func is remove_all (snake_case) so the lisp name is remove-all;
the chdir test restores cwd (registered after t.TempDir so it runs
first) to avoid polluting other tests in the package.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(system): directory/process primitives (chdir, cwd, mkdtemp, remove-all)
slurp, spit, load-file and load-file-once move from core to the system
library. core becomes a pure base with no ambient filesystem access: it
keeps eval/read-program/read-string (evaluate code held as data) but can
no longer read a file to run it. File access is an explicit capability —
+system for raw I/O, +require for structured module loading (require
reads modules itself in Go, so it needs neither slurp nor system).

- Move slurp/slurp_source/spit + the VerifySource integrity hook from
  lib/core to lib/system; move the load-file header (header-load-file.lisp)
  and load-file-once from nscore.LoadInput to nssystem.Load. read-program
  and eval stay in core.
- command's setupIntegrity now installs system.VerifySource.
- Not user-facing: the lisp binary loads system by default, so scripts
  and CLI script execution (which uses load-file) are unaffected.
  Breaking for embedders loading only core — they must add nssystem.Load
  (after core + its input layer). Documented in the CHANGELOG.
- Updated the ~15 test harnesses that build core-only envs and use
  slurp/load-file to also load system/nssystem; docgen blurbs and
  LANGUAGE.md regenerated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fullEnv REPLed the load-file header but didn't register slurp-source
(which moved to system), so load-file failed and the DAP server hung
waiting for a stopped event that never came — a 10m timeout under
-tags debugger ./... on CI. Add system.Load(ns). Verified the full
tagged suite passes with no hang.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
refactor: move file I/O from core to system (capability model)
Complete the regexp library with the remaining Clojure-style builtins:

- re-seq: vector of every non-overlapping match, each shaped like
  re-find (match string, or [whole g1 g2 …] with groups)
- re-replace / re-replace-first: rewrite matches with $1 / ${name}
  group references ($$ for a literal $); replace-first leaves the
  string unchanged when there is no match
- re-split: split around matches into a vector, with an optional
  integer limit (Go Split semantics: trailing empties kept)

Docs (README, CHANGELOG, LANGUAGE.md) and tests updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat(regexp): re-seq, re-replace/-first, re-split
Calendar/duration arithmetic and ordering over the epoch-millisecond
ints that time-ms/time-format already use:

- (time-add ms {:years .. :months .. :days .. :hours .. :minutes ..
  :seconds .. :milliseconds ..}) — years/months/days go through
  time.AddDate (calendar-aware, overflow normalised like Go: Jan 31 +
  1 month -> March 2); the rest add a fixed duration. Missing keys are
  0, negatives shift backwards. Unknown key or non-integer value errors.
  The deltas map is read, never mutated.
- (time-before? t1 t2) / (time-after? t1 t2) — strict ordering.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat(core): time-add, time-before?, time-after?
Study for replacing the U+029E-prefixed-string keyword representation
with a dedicated Go type, including confirmed correctness bugs, design
options and benchmarks, a migration plan targeting 0.4, and the spec
for seqable hash-maps and sets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ring

Hash-maps seq as sorted [key value] entry vectors and sets as their
sorted elements, via a single choke point in types.GetSlice (plus
ConvertFrom for vec and a seq case for Clojure parity: seq of an empty
map or set is nil). This makes seq, first, rest, map, filter, reduce,
apply, cons, concat, vec, into and lazy-seqs work over both, enabling
(into {} (map (fn [[k v]] ...) m)).

The order is sorted rather than left unspecified because first and
rest each seq the collection independently: with Go's per-call
randomised map iteration, a first/rest traversal would drop or repeat
entries. nth rejects maps and sets explicitly (they seq but are not
indexed; Clojure errors too).

Binding forms gain sequential destructuring, which the entry idiom
requires and the language lacked: vector patterns in fn params and let
bindings bind positionally and recursively, missing elements bind nil,
& binds the remainder as a list. Top-level fn arity stays strict;
loop/recur bindings remain symbol-only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(core): seqable hash-maps and sets, sequential destructuring
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bumps the go-modules group with 2 updates: [github.com/go-git/go-billy/v6](https://github.com/go-git/go-billy) and [modernc.org/sqlite](https://gitlab.com/cznic/sqlite).


Updates `github.com/go-git/go-billy/v6` from 6.0.0-alpha.1 to 6.0.0-alpha.2
- [Release notes](https://github.com/go-git/go-billy/releases)
- [Commits](go-git/go-billy@v6.0.0-alpha.1...v6.0.0-alpha.2)

Updates `modernc.org/sqlite` from 1.53.0 to 1.54.0
- [Changelog](https://gitlab.com/cznic/sqlite/blob/master/CHANGELOG.md)
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.53.0...v1.54.0)

---
updated-dependencies:
- dependency-name: github.com/go-git/go-billy/v6
  dependency-version: 6.0.0-alpha.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-modules
- dependency-name: modernc.org/sqlite
  dependency-version: 1.54.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-modules
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file go Pull requests that update go code labels Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file go Pull requests that update go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant