Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import java.util.Properties
import java.io.FileInputStream
import org.gradle.internal.os.OperatingSystem
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
id("com.android.application")
Expand Down Expand Up @@ -113,10 +114,6 @@ android {
targetCompatibility = JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = "17"
}

testOptions {
// JVM unit tests run against a stubbed android.jar whose methods throw
// "Method ... not mocked" by default. MarketplaceFetcher.fetchIndex() calls
Expand All @@ -129,6 +126,17 @@ android {
}
}

// Kotlin JVM target. This used to be `android { kotlinOptions { jvmTarget = "17" } }`,
// which Kotlin 2.4 removed from the Gradle plugin (deprecated since 2.0), so the
// build script stopped compiling on the dependabot bump. `compilerOptions` is the
// replacement DSL; it lives at the top level, not inside `android {}`. Keep this
// in step with compileOptions.sourceCompatibility/targetCompatibility above.
kotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_17)
}
}

// Auto-bundle the React UI into Android assets before APK packaging.
//
// Why: app/src/main/assets/web/ is gitignored except for index.html. The actual
Expand Down Expand Up @@ -227,7 +235,7 @@ dependencies {
implementation("com.github.luben:zstd-jni:1.5.7-11")

// Markdown parsing for chat view
implementation("org.commonmark:commonmark:0.29.0")
implementation("org.commonmark:commonmark:0.30.0")

// WebSocket server for React UI bridge
implementation("com.squareup.okhttp3:okhttp:4.12.0")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import org.mockito.Mockito.mock
import org.mockito.Mockito.`when`
import java.io.ByteArrayInputStream
import java.io.File
// Kotlin 2.4 made kotlin.io.createTempDir() a compile ERROR (it was deprecated
// for creating world-readable temp dirs); this is the replacement the stdlib
// points at, and what PluginInstallerUpgradeTest already uses.
import kotlin.io.path.createTempDirectory

/**
* Tests LocalSkillProvider.getInstalled() backfill behavior — specifically the
Expand All @@ -30,7 +34,7 @@ class LocalSkillProviderInstalledTest {

@Before
fun setUp() {
tmpHome = createTempDir(prefix = "youcoded-localprov-")
tmpHome = createTempDirectory(prefix = "youcoded-localprov-").toFile()
context = mock(Context::class.java)
val assets = mock(AssetManager::class.java)
`when`(context.assets).thenReturn(assets)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import java.io.File
// Kotlin 2.4 made kotlin.io.createTempDir() a compile ERROR (it was deprecated
// for creating world-readable temp dirs); this is the replacement the stdlib
// points at, and what PluginInstallerUpgradeTest already uses.
import kotlin.io.path.createTempDirectory

/**
* Regression coverage for the Android-only "uninstalling a plugin wipes every
Expand Down Expand Up @@ -52,7 +56,7 @@ class SkillConfigStoreChipsTest {
private fun store() = SkillConfigStore(tmpHome).apply { load() }

@Before
fun setUp() { tmpHome = createTempDir(prefix = "youcoded-chips-") }
fun setUp() { tmpHome = createTempDirectory(prefix = "youcoded-chips-").toFile() }

@After
fun tearDown() { tmpHome.deleteRecursively() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import org.mockito.Mockito.mock
import org.mockito.Mockito.`when`
import java.io.ByteArrayInputStream
import java.io.File
// Kotlin 2.4 made kotlin.io.createTempDir() a compile ERROR (it was deprecated
// for creating world-readable temp dirs); this is the replacement the stdlib
// points at, and what PluginInstallerUpgradeTest already uses.
import kotlin.io.path.createTempDirectory

/**
* Tests SkillScanner Pass 1 (top-level plugin scan) and Pass 2 (installed_plugins.json).
Expand All @@ -26,7 +30,7 @@ class SkillScannerTest {

@Before
fun setUp() {
tmpHome = createTempDir(prefix = "youcoded-scanner-")
tmpHome = createTempDirectory(prefix = "youcoded-scanner-").toFile()
context = mock(Context::class.java)
val assets = mock(android.content.res.AssetManager::class.java)
`when`(context.assets).thenReturn(assets)
Expand Down
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
id("com.android.application") version "8.7.0" apply false
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
id("org.jetbrains.kotlin.plugin.compose") version "2.1.0" apply false
id("org.jetbrains.kotlin.android") version "2.4.10" apply false
id("org.jetbrains.kotlin.plugin.compose") version "2.4.10" apply false
}
59 changes: 40 additions & 19 deletions desktop/knip.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
// JSONC (not .json) specifically so the ignore rationale below can live next
// to the ignores. Every entry here is a VERIFIED false positive, not a
// silenced real finding.
"$schema": "https://unpkg.com/knip@5/schema.json",
"$schema": "https://unpkg.com/knip@6/schema.json",

// main.ts, renderer/index.tsx and vite.config.ts are NOT listed: knip 6's
// vite/electron plugins derive them from package.json + vite.config.ts and
// flag a hand-written copy as a redundant entry pattern.
"entry": [
"src/main/main.ts",
"src/main/preload.ts",
"src/main/pty-worker.js",
"src/renderer/index.tsx",
"vite.config.ts",
"scripts/*.js",
"src/**/*.test.ts",
"src/**/*.test.tsx",
Expand All @@ -28,17 +28,36 @@
"test-engine/**/*.mjs"
],

"project": ["src/**/*.{ts,tsx}"],
// The old `src/renderer/dev/fixtures/**` ignore is gone: those fixtures moved
// under dev/workbench/ and are DELIBERATELY left unignored. Workbench fixture
// modules are ordinary imports, so knip catching an unused one is the point —
// it is what flagged a models.ts that existed only "for symmetry".
"ignore": ["dist/**"],
// .css is in `project` so knip follows CSS `@import "tailwindcss"` etc. —
// knip 6 hints that a compiled extension left out of `project` means those
// imports are silently not followed. Nothing is reported for CSS files today;
// it is what lets tailwindcss be seen as a real dependency (below).
"project": ["src/**/*.{ts,tsx,css}"],
// No `ignore` block: the old `dist/**` entry is redundant (knip 6 never scans
// build output that isn't under `project`, and hints to remove it), and the
// older `src/renderer/dev/fixtures/**` ignore is gone on purpose — workbench
// fixture modules are ordinary imports, so knip catching an unused one is the
// point; it is what flagged a models.ts that existed only "for symmetry".

// OS-level tools the main process shells out to. knip 6 started reading the
// command name out of child_process execFile/spawn calls and reports any
// that no dependency provides ("unlisted binary"). None of these is, or could
// be, an npm package — each is VERIFIED below — so they are listed here and
// the `binaries` category stays at its default (error), so a NEW unlisted
// binary still fails CI.
"ignoreBinaries": [
// Linux socket-stats tool, engine-supervisor.ts: which process holds the port.
"ss",
// Windows process lister, sync-service.ts: is this sync PID still alive.
"tasklist",
// The Drive/cloud sync transport, sync-service.ts — users install it themselves.
"rclone"
],

"ignoreDependencies": [
// Peer of @tailwindcss/postcss, wired through postcss.config.js rather
// than imported. Removing it breaks the CSS build with no import to trace.
"tailwindcss",
// tailwindcss is NOT listed any more: with .css in `project`, knip resolves
// the `@import "tailwindcss"` in the stylesheet itself and hints that the
// old ignore is redundant.
// Spawned as a subprocess by scripts/run-dev.js:52
// (`spawn(npx, ['wait-on', viteUrl])`), so no static import exists.
"wait-on",
Expand All @@ -50,11 +69,14 @@
// Gate on the categories that are CLEAN today, so CI ratchets (nothing new
// rots in) without demanding a big-bang cleanup first. The noisy-but-real
// categories report as warnings and are tracked in ROADMAP instead:
// - types (262): dominated by src/shared/types.ts, a deliberate shared
// type surface consumed structurally. Erroring here would be wrong.
// - exports (10) / unlisted (4): real findings, but deleting an export or
// re-pinning a transitive dep is a reviewed change, not a lint autofix.
// - types (172 under knip 6; 379 under knip 5): dominated by
// components/ui/index.ts and src/shared/types.ts, deliberate shared type
// surfaces consumed structurally. Erroring here would be wrong.
// - exports (77): real findings, but deleting an export or re-pinning a
// transitive dep is a reviewed change, not a lint autofix.
// Tighten these to "error" as each category is driven to zero.
// `classMembers` is not listed: knip 6 dropped that issue type (it relied on
// a TypeScript API that goes away in TS 6), and an unknown key only warns.
"rules": {
"files": "error",
"unresolved": "error",
Expand All @@ -63,7 +85,6 @@
"unlisted": "warn",
"exports": "warn",
"types": "warn",
"enumMembers": "warn",
"classMembers": "warn"
"enumMembers": "warn"
}
}
Loading