Files
ai-app/app/gradle/libs.versions.toml
T
irisandClaude Opus 5 a2b11d516f Colour code with a scanner of our own instead of the library
dev.snipme:highlights 1.1.0 found comments before it knew the language and
paired /* with */ by ordinal, so `//` in any URL commented out the rest of
its line, every Rust `#[derive(...)]` greyed out as a comment, a `#` inside
a Kotlin string swallowed the line, and `x '*/a/*'` in shell produced a span
whose end preceded its start -- the one that crashed a card holding
`-path '*/.git/*'`. None of that could be post-processed away, because
comments won over strings before the language was known.

Highlighter.kt is one left-to-right scanner: at each position it is in a
line comment, a block comment, a string, or ordinary code, and every span is
emitted by advancing an index, so spans cannot overlap, arrive out of order
or run backwards. Languages.kt is a `Rules` row per language -- comment
tokens, block comment and whether it nests, the string forms, what opens an
attribute, and the keyword set -- so a new language is a table entry. The
keyword lists came from the library's SyntaxTokens.kt (Apache-2.0, noted at
the table) so nothing that is coloured today turns plain, and RON, TOML,
fish and JSON are coloured for the first time.

HighlighterTest.kt is a new JVM unit test source set -- 24 cases, the
library's mistakes kept as regressions, plus a sweep asserting no span
escapes the code for any language on unterminated and empty input.
AGENTS.md's app line now runs :androidApp:testDebugUnitTest.

Measured on the ai-app emulator, debug build, a ~200-line Kotlin fence sent
into a sandbox session:

  before  code highlighted: 1, 101.9ms total, 101.9ms mean, 101.9ms worst
  after   code highlighted: 1,  15.0ms total,  15.0ms mean,  15.0ms worst

and a second fence in the same run took 13.9ms, so that is the steady cost
rather than class loading. stream-bench.sh after the change:

  code highlighted: 1, 12.1ms total, 12.1ms mean, 12.1ms worst
  markdown reparsed while streaming: 1329, 2130.7ms total, 1.6ms mean, 8.7ms worst
  record: one block: 131, 11.4ms total, 0.1ms mean, 0.4ms worst
  draw phase 1.21ms per frame, the transcript 0.23ms of it

transcript-bench.sh after: draw phase 1.10ms per frame, the transcript
0.49ms (place 0.48), worst place 4.3ms -- unchanged within run-to-run noise,
as expected, since the scan happens in `warm` and not while drawing.

Looked at on the emulator: a URL inside a Kotlin string, a Rust attribute
with a lifetime and a raw string, a shell line with globs and `$#`, a RON
fence and a TOML fence all colour correctly; a Bash tool card still colours
its command; a plain Python fence -- which this change had no reason to
touch -- looks as it did; an unknown language stays plain; and a fence is
plain while it streams and colours when it freezes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 20:23:59 -04:00

98 lines
6.1 KiB
TOML

# Latest stable versions as of 2026-08-28 (checked against Google Maven /
# Maven Central; prereleases deliberately skipped). zxing-embedded checked
# 2026-08-25.
[versions]
# Checked 2026-09-03 against Google Maven; 9.5.0 was alpha only.
agp = "9.4.0"
kotlin = "2.4.10"
compose-multiplatform = "1.12.0"
# material3 ships on its own release train, separate from the CMP version.
compose-material3 = "1.9.0"
androidx-activityCompose = "1.13.0"
# Declared rather than inherited because this
# code now calls its extensions directly (SharedPreferences.edit, String
# .toUri), and a transitive it merely inherited could change under it.
androidx-core-ktx = "1.19.0"
zxing-embedded = "4.3.0"
# Markdown rendering for assistant replies. The widely-used Compose
# Multiplatform renderer; markdown is somebody else's specification and a
# hand-written subset disagrees with it at the edges, one bug report at a
# time.
#
# Read the version from `maven-metadata.xml`, not from the search API:
# `search.maven.org/solrsearch` still answers 0.26.0 with 0.27.0 only as
# release candidates, which is what pinned this nineteen releases behind
# and cost us table support -- tables arrived in 0.30.0 and simply
# rendered as run-together text until then.
# https://repo1.maven.org/maven2/com/mikepenz/multiplatform-markdown-renderer-m3/maven-metadata.xml
# Latest stable there, checked 2026-08-29.
markdown-renderer = "0.45.0"
# The support ExifInterface rather than android.media's, which lint warns off:
# the framework one is missing formats and the fixes for parsing hostile
# images, and images here arrive from outside the phone. Latest stable,
# checked 2026-08-31 against Google Maven.
androidx-exifinterface = "1.4.2"
# Declared rather than inherited for the same reason as core-ktx: SessionScreen
# now calls repeatOnLifecycle/LocalLifecycleOwner directly, to hold the event
# stream open only while the screen is on screen. Latest stable, checked
# 2026-08-29 against Google Maven; activity-compose alone would have pulled
# 2.9.4.
androidx-lifecycle = "2.11.0"
# The Kotlin formatter, run at its defaults (see CODE_RULES rule 27). ktfmt
# itself is Kotlin-org owned and has almost nothing to configure, which is
# the point; this is the Gradle wrapper for it. Checked 2026-08-28.
ktfmt-gradle = "0.27.0"
# The test framework for the app's JVM unit tests (Highlighter.kt's scanner).
# JUnit 6 is the current line -- Jupiter and the Platform ship on one version
# now -- and the tests themselves are written against `kotlin.test`, so the
# framework is a build-file choice rather than something the source names.
# Latest stable, checked 2026-09-03 against Maven Central.
junit = "6.1.3"
# Backports java.time (and more) to API 24, which UsageScreen needs: its
# reset countdown is OffsetDateTime/Duration, both API 26. Checked
# 2026-08-28 against Google Maven.
desugar-jdk-libs = "2.1.5"
[libraries]
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" }
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "androidx-core-ktx" }
androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
# In-app QR scanner: a ready-made scanning Activity (camera preview, runtime
# permission prompt, flashlight toggle) reached through the AndroidX Activity
# Result API (ScanContract, added in 4.3.0). Fully offline -- no Play
# Services / ML Kit model download involved.
zxing-embedded = { module = "com.journeyapps:zxing-android-embedded", version.ref = "zxing-embedded" }
desugar-jdk-libs = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugar-jdk-libs" }
# The -m3 flavour: it takes its colours and type from the ambient Material 3
# theme, so the app's Catppuccin scheme is what it draws with.
markdown-renderer = { module = "com.mikepenz:multiplatform-markdown-renderer-m3", version.ref = "markdown-renderer" }
androidx-exifinterface = { module = "androidx.exifinterface:exifinterface", version.ref = "androidx-exifinterface" }
# The framework-neutral assertions the tests are written against. The `-junit5`
# artifact rather than plain `kotlin-test`: AGP 9 compiles Kotlin itself rather
# than through the Kotlin Android plugin, so nothing here resolves the variant
# of `kotlin-test` that carries `kotlin.test.Test` -- naming the artifact is
# what makes the annotation exist.
kotlin-test-junit5 = { module = "org.jetbrains.kotlin:kotlin-test-junit5", version.ref = "kotlin" }
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }
junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit" }
# Declared directly rather than through the plugin's `compose.*` accessors,
# which are deprecated as of CMP 1.11.
compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "compose-multiplatform" }
# Names composables in a system trace, which is how a per-frame cost on the
# phone gets attributed to a composable rather than to "Compose". Inert until
# a trace is being recorded. Its own release train: 1.12.0 was the newest
# stable on Google Maven on 2026-09-02.
compose-runtime-tracing = { module = "androidx.compose.runtime:runtime-tracing", version = "1.12.0" }
compose-foundation = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "compose-multiplatform" }
compose-material3 = { module = "org.jetbrains.compose.material3:material3", version.ref = "compose-material3" }
compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "compose-multiplatform" }
[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
# For the :link subproject (wg-app-link/app), which resolves its plugins
# from the build including it rather than from its own catalog.
androidLibrary = { id = "com.android.library", version.ref = "agp" }
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" }
composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
ktfmt = { id = "com.ncorti.ktfmt.gradle", version.ref = "ktfmt-gradle" }