Skip to content

Releases: nlink-jp/shell-agent-v2

v0.18.1

Choose a tag to compare

@magifd2 magifd2 released this 25 Oct 16:52

Build

  • Built with the current Go again. Wails moved from v2.12.0 to v2.16.0,
    whose CLI reads Go 1.27, so the GOTOOLCHAIN=go1.26.10 pin in app/Makefile
    is gone. In its place, make build / make dev refuse a wails CLI other than
    the version in app/go.mod and print the install command — a stale CLI is
    what broke the build.
  • The release zip no longer carries macOS file metadata. make package
    zipped the app with plain ditto -c -k, which stores each file's extended
    attributes as ._* AppleDouble entries (9 of them in the v0.18.0 build).
    It now passes --norsrc --noextattr, and make verify-release runs
    scripts/verify-app-zip.sh — the org's copy — which refuses a zip with
    metadata entries or without the app icon. The published v0.18.0 zip was
    re-zipped this way from the same notarized app before upload; v0.17.1 and
    earlier zips still carry the entries (the app inside is unaffected).

Security

  • The read tools can no longer write. query_sql, quick_summary,
    analyze_data, export-sql-to-csv and the body of save_query decided
    "read-only" by checking that the SQL did not start with one of nine keywords.
    A second statement after a semicolon passed and ran (SELECT 1; DROP TABLE t
    dropped the table), as did WITH … INSERT, COPY … TO, ATTACH, SET,
    CALL and EXPLAIN ANALYZE. The engine now enforces it in three layers: the
    query must be one statement of type SELECT as DuckDB's parser classifies it;
    agent SQL runs on a throwaway in-memory instance with the session file
    attached READ_ONLY, so DuckDB refuses every write to it — a data-modifying
    CTE (WITH d AS (DELETE … RETURNING *) SELECT …), dbgen / dsdgen, and SQL
    run through json_execute_serialized_sql, which a read-only transaction did
    not stop; and the configuration is locked with extension autoinstall/autoload
    off, which refuses enable_profiling / enable_logging (both wrote files
    from a plain SELECT) and extension installs. save_query runs its body the same
    way into a staging file and copies only the result table into the session.
    DESCRIBE, SUMMARIZE, SHOW, FROM t and WITH … SELECT still work;
    EXPLAIN and dynamic PIVOT are now refused; reading local files with
    read_csv & co. remains possible. See ADR-0034.

v0.18.0

Choose a tag to compare

@magifd2 magifd2 released this 25 Oct 15:04

Changed

  • DuckDB driver moved to github.com/duckdb/duckdb-go/v2 v2.20000.0, which
    bundles DuckDB v2.0.0 LTS
    (was github.com/marcboeker/go-duckdb v1.8.5 with
    DuckDB v1.1.3). The old module path no longer receives releases, so the
    analysis engine could never take a DuckDB fix. The UI, the LLM's tool results
    and CSV export render every type as before: MAP now arrives as an ordered map
    and is converted to the same string-keyed form, including a MAP inside a LIST
    or STRUCT. See ADR-0033.
  • Sessions created by this release do not open in older versions. DuckDB 2.0
    writes a storage format DuckDB 1.x cannot read. Session databases created
    earlier keep working here and stay readable by v0.17.x after this release has
    used them; a new session — or a .shellagent bundle exported from one — does
    not open in v0.17.x.

Security

  • CVE-2026-111497 (Brotli decoder out-of-bounds write) is not fixed yet.
    DuckDB's parquet extension vendors Brotli 1.1.0, and every DuckDB release so
    far — v2.0.0 included — still does; the upstream fix (duckdb/duckdb#27791) was
    unmerged on 2026-10-25. It is reachable when the agent's SQL reads a crafted
    Brotli-compressed Parquet file (read_parquet). This release moves the
    analysis engine onto the maintained driver line so the fix lands as a
    dependency bump once DuckDB ships it.
  • Go dependencies with known vulnerabilities reachable from the binary are
    updated
    : golang.org/x/net v0.60.0 (GO-2026-6617, -6612, -6611, -6610,
    -6603, -5026, -4918), google.golang.org/grpc v1.83.1 (GO-2026-6348,
    -6061), golang.org/x/text v0.42.0 (GO-2026-5970) and
    go.opentelemetry.io/otel v1.44.0 (GO-2026-5506), and grpc further to
    v1.83.2 (GO-2026-6443). govulncheck now reports none reachable.
  • Built with Go 1.26.10. The previous release was built with Go 1.26.4,
    whose standard library has reachable vulnerabilities in net/http,
    crypto/tls and crypto/x509 (fixed by 1.26.9 / 1.26.10).

Build

  • make build / make dev no longer pass -tags no_duckdb_arrow: the new
    driver's Arrow interface is opt-in, so the tag does nothing and Arrow stays
    out of the binary as before.
  • make pins GOTOOLCHAIN=go1.26.10. The wails v2.12.0 CLI's static analysis
    (golang.org/x/tools v0.30.0) cannot read Go 1.27 export data, so under go1.27
    every wails build stopped with internal error: package ... without types was imported from .... Override with GOTOOLCHAIN=... on the command line.

Documentation

  • Every document reference resolves again. The move into
    docs/{en,ja}/{reference,history,adr}/ left 46 links pointing at the old flat
    paths — both READMEs' feature lists, the history index, and the cross-links
    between the memory-model reference and its deep dives. Each now points at its
    own language's copy, and the two labels that spelled a different path than
    they linked were corrected with them. check-org.sh resolves these now, so
    the next move is caught rather than discovered.

shell-agent-v2 v0.17.1

Choose a tag to compare

@magifd2 magifd2 released this 12 Jul 10:42

Packaging / release-naming change — no change to the app's behaviour.

shell-agent-v2 is a Wails v2 (Go + React) macOS app and remains darwin/arm64 only (Apple Silicon).

Changed

  • Release archive renamed from shell-agent-v2-vX.Y.Z-darwin.zip to shell-agent-v2-vX.Y.Z-darwin-arm64.zip, adding the explicit arm64 architecture token per the org-wide Release Archive Standard (nlink-jp/.github CONVENTIONS.md). The build now pins wails build -platform darwin/arm64 so the .app is guaranteed arm64-only (no universal binary). The archive still contains the notarized, stapled shell-agent-v2.app.

Install

Download the .zip, unzip it, and move shell-agent-v2.app to Applications. It is Developer ID signed + Apple-notarized (stapled), so it launches without Gatekeeper prompts and works offline.

Asset

  • shell-agent-v2-v0.17.1-darwin-arm64.zip — notarized + stapled shell-agent-v2.app

v0.17.0

Choose a tag to compare

@magifd2 magifd2 released this 06 Jun 08:45

Two ADRs landing together to close the "long sessions re-anchor to early topics" symptom end-to-end.

Added

  • Memory entries gain a lifecycle (ADR-0031). Global Memory and Session Memory entries now carry a four-state machine — fresh/active/dormant/archived — driven by a per-user-turn relevance decay. Decay multiplier, fresh window, state thresholds, and touch / consolidation Jaccard thresholds are tunable under Memory.Lifecycle.* in the JSON config. Entries lexically referenced by the user turn (or named in the extractor's new touched| lines) reset to relevance 1.0; near-duplicate Add calls consolidate into the existing entry instead of appending. Eviction under cap pressure prefers archived → dormant → active → fresh. The sidebar Memory tab gains per-row state badges, a thin relevance bar, and a Show archived (N) disclosure. All state transitions log to app.log.

  • Context compaction v2 (ADR-0032). The conversation-tail summary is no longer a single block. contextbuild.Build now produces a two-tier summary (far ~5% of budget, near ~15%) plus a verbatim anchor block rendered between the summaries and the raw records. Anchors are detected by lexical Jaccard against decision / preference Global Memory facts. Records lexically matching a dormant / archived Session Memory fact (with a live-clause safety net) are dropped from the summary input entirely and surfaced as a [N dead-topic turns suppressed] elision marker. The summary cache key is content-hashed: stable across turn additions that don't change a tier's input, invalidates when the ADR-0031 lifecycle changes the drop set. The summarizer prompt drops "Preserve key facts, decisions, and context" — the load-bearing source of early-anchor reinforcement — in favour of a topic-bullet format. Tunable under ContextBudget.{FarSummaryShare, NearSummaryShare, AnchorJaccardThreshold, DeadTopicJaccardThreshold}.

Backward compatibility

  • Legacy global_memory.json / session_memory.json files load as active with relevance 1.0 and re-save with the new fields populated.
  • Legacy summaries.json cache files load without error; their range-keyed entries are skipped by the v2 cache lookup and FIFO-cleaned over time.

Docs

  • ADR-0031 (memory entry lifecycle)
  • ADR-0032 (context compaction v2)
  • docs/{en,ja}/reference/memory-model updated with §7 and §10 reflecting both ADRs

v0.16.2

Choose a tag to compare

@magifd2 magifd2 released this 29 May 00:25

Fixed

  • Memory sidebar stayed on the previous session's facts after New / Import / Load Session while the panel was open (issue #15). The Memory-panel refresh effect only depended on sidebarPanel, so a session switch updated the chat pane (which sets messages directly) but never refetched GetSessionMemories(). Added currentSessionId to the effect's dependency list so the panel refreshes when the active session changes while it is visible. No backend or binding change.

See CHANGELOG.md for full history.

v0.16.1

Choose a tag to compare

@magifd2 magifd2 released this 28 May 03:38

Patch release. Production data-race fix surfaced while investigating issue #13.

Fixed

  • Data race on a.session pointer between title generation and the extraction's auto-dispatched SendWithAttachments. Caught by the Go race detector during issue #13 investigation. The title goroutine read a.session (in generateTitleIfNeeded) while agentLoop's defensive nil-init wrote to it, both without holding a.mu. In normal use a.session is initialised by LoadSession before any SEND, so the agentLoop nil-init is usually a no-op and the race rarely manifests in practice — but the same race also exists between LoadSession's write and a concurrent title-gen read, so the bug is latent regardless. No user-visible impact has been observed, but the fix lands now because the race is real. Fixed by snapshotting a.session under a.mu at both sites (the lock is NOT held across backend.Chat, which can take seconds). No API or on-disk behaviour change. See ADR-0030.
  • Two flaky tests in the agent package (issue #13). Pure test fixes (barrier pattern for TestQueuedSend_ExtractionErrorStillDispatches, relaxed wall-clock deadline for TestAutoDispatch_DrainedByWait).

v0.16.0

Choose a tag to compare

@magifd2 magifd2 released this 28 May 02:52

Added

  • Configurable analysis row caps. New analysis.max_query_rows (default 10 000, chat-output queries) and analysis.max_export_rows (default 1 000 000, sandbox CSV export) settings, surfaced under Settings → General → Data analysis. Per-session engine honours both via Engine.SetRowCaps; changes apply live on Save without a session switch. See ADR-0029.

Fixed

  • export-sql-to-csv no longer throttled by the chat-output cap (issue #14). The path that writes a SELECT's rows as CSV into the sandbox /work dir was capped at the same 10 000-row chat-output limit, even though its rows never enter the chat. Users frequently hit the cap on real workloads (~27 k-row tables) and had to ask the agent to "split the data", or the agent invented convoluted workarounds. The default for this path is now 1 000 000 rows (matching MaxAnalyzeRows, which has the same "rows never hit the chat" property), and the cap is configurable — see Added above. The previous behaviour is recoverable by setting analysis.max_export_rows: 10000.

v0.15.1

Choose a tag to compare

@magifd2 magifd2 released this 27 May 05:18

Fixed

  • Failure notices now actually appear. window.alert() is not reliably rendered in the Wails v2 WKWebView, so error messages on session export/import, session/finding/object delete, pin-to-global, oversized attachments, and sandbox-image actions were silently swallowed. All now route through a native dialog (wailsRuntime.MessageDialog), the same mechanism v0.15.0 Global Memory import/export uses. window.alert() is no longer used anywhere in the frontend.

macOS app (Apple-notarized). Download shell-agent-v2-v0.15.1-darwin.zip, unzip, move to Applications.

v0.15.0

Choose a tag to compare

@magifd2 magifd2 released this 27 May 05:07

Added

  • Global Memory export / import. Back up the cross-session Global Memory to a JSON file, and import one back, from two buttons in the sidebar Memory tab. Import merges, skipping duplicates (by fact text) — non-destructive and idempotent. The file is a versioned envelope (kind + schema_version) so a wrong file (a session bundle, arbitrary JSON) is rejected with a clear message. Suited to backup and cross-machine migration of Global Memory. (ADR-0027.)

Removed

  • Unused provenance fields dropped from Global Memory entries (SessionID, SourceTurnIndex, PromotedFromID). Written at promotion/extraction time but read by nothing, and — being references into the machine-local session namespace — unreliable across machines. Removing them eliminates a cross-machine collision hazard at the schema level. Backward compatible: existing global_memory.json files load fine and the obsolete keys drop out on next save. Source (trust tag) and ToolOriginated unchanged. (ADR-0028.)

macOS app (Apple-notarized). Download shell-agent-v2-v0.15.0-darwin.zip, unzip, move to Applications.

v0.14.9

Choose a tag to compare

@magifd2 magifd2 released this 26 May 04:55

Changed

  • MCP guardian start failures now report the process exit status. When a guardian process dies before initialising — e.g. macOS SIGKILLs a quarantined or cloud-synced (~/bin via Dropbox) binary — the error now reads guardian process exited before initialising: signal: killed … with a hint to re-sign (codesign --force --sign -) or move the binary out of the synced path, instead of the opaque initialize: read response: EOF. Non-signal early exits surface exit status N. (ADR-0026)

macOS (Apple Silicon), Developer ID signed + notarized + stapled.