Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
fec82fb
chore(web): wire svelte-check module/global resolution for type safety
cursoragent Jul 8, 2026
9629aa4
fix(web): resolve $lib aliases and core stream typing for svelte-check
cursoragent Jul 8, 2026
2d880b9
fix(web): correct rune/controller/api types across browse UI
cursoragent Jul 8, 2026
e654b11
fix(web): resolve remaining svelte-check type errors and enable CI ty…
cursoragent Jul 8, 2026
572af0d
better typing option
andykais Jul 19, 2026
6327933
update comments
andykais Jul 19, 2026
9f736f1
refactor(web): address PR review feedback
cursoragent Jul 19, 2026
f59664b
chore(web): declare shared deps once via jsrDepsInNodeModules
cursoragent Jul 20, 2026
65b6ace
fix(web): address review feedback on typechecking PR
cursoragent Sep 1, 2026
1143ff1
fix(web): reconcile typechecking changes with svelte context refactor
cursoragent Oct 14, 2026
fb45797
chore: regenerate deno.lock after rebase onto main
cursoragent Oct 14, 2026
1ed2543
fix(web): resolve state_referenced_locally warnings from svelte 5.56
cursoragent Oct 14, 2026
084b268
chore(web): drop redundant tsconfig exclude that overrode sveltekit's…
cursoragent Oct 14, 2026
e088811
docs(core): condense read_lines TextDecoderStream cast note
cursoragent Oct 14, 2026
e8e40e8
refactor(web): share AnyMediaResponse type between media runes
cursoragent Oct 14, 2026
39d009d
fix(web): do not open the media view for grouped results
cursoragent Oct 14, 2026
d9d91cd
refactor(web): use core input/model types directly and drop base_quer…
cursoragent Oct 14, 2026
d0ef76a
fix(ci): comment out stray publish steps that ran in the web test job
cursoragent Oct 14, 2026
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
12 changes: 6 additions & 6 deletions .github/workflows/web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ jobs:
# - name: Lint
# run: deno task lint

# - name: Typecheck
# run: deno task check
- name: Typecheck
run: deno task check

- name: Build
run: deno task build
Expand All @@ -46,11 +46,11 @@ jobs:
# needs: test

# steps:
- name: checkout repository
uses: actions/checkout@v6
# - name: checkout repository
# uses: actions/checkout@v6

- name: setup
uses: './.github/actions/shared_setup'
# - name: setup
# uses: './.github/actions/shared_setup'

# - name: Build
# run: deno task build
Expand Down
7 changes: 6 additions & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
"imports": {
"@std/datetime": "jsr:@std/datetime@^0.225.3",
"@std/yaml": "jsr:@std/yaml@^1.0.5",
"@std/fmt": "jsr:@std/fmt@0.225.6",
// NOTE mapped as an explicit subpath rather than a bare "@std/fmt" or an "@std/fmt/"
// prefix: `jsrDepsInNodeModules` rewrites those to their npm form
// ("npm:@jsr/std__fmt@0.225.6/"), which cannot resolve a subpath. Any other
// @std/fmt subpath we start importing needs its own entry here.
"@std/fmt/bytes": "jsr:@std/fmt@0.225.6/bytes",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, but the kind that bites later: @std/fmt and @std/fmt/bytes are now two independently pinned entries. Today they agree at 0.225.6; the next time someone bumps @std/fmt they will almost certainly not notice this line, and you'll silently be running two copies of the same package at different versions.

Since this exists to work around a subpath-rewrite gap in jsrDepsInNodeModules, a comment saying so — and saying "keep the version in sync with @std/fmt above" — would make the trap visible. Better still if it can be expressed as "@std/fmt/": "jsr:@std/fmt@0.225.6/" (trailing-slash prefix mapping), which keeps one version literal.

@andykais andykais Sep 1, 2026 •

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion, make it so

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made it so, though not quite the suggested form — the trailing-slash prefix mapping doesn't survive jsrDepsInNodeModules. I tried it:

"@std/fmt/": "jsr:@std/fmt@0.225.6/",
error: Failed to resolve the specifier ""@std/fmt/bytes"" as its after-prefix portion
""bytes"" could not be URL-parsed relative to the URL prefix
"npm:@jsr/std__fmt@0.225.6/" mapped to by the prefix "@std/fmt/"

That's the same failure the explicit entry was working around in the first place — the prefix gets rewritten to its npm form, and the subpath can't be parsed against it.

What did work is dropping the bare @std/fmt entry entirely, since nothing imports it bare (core's only use is @std/fmt/bytes; lib/test/lib/debugger.ts uses a fully-qualified jsr:@std/fmt@0.225.4/colors specifier that doesn't go through the import map). So there's now a single entry and a single version literal, which gets the outcome you were after:

// NOTE mapped as an explicit subpath rather than a bare "@std/fmt" or an "@std/fmt/"
// prefix: `jsrDepsInNodeModules` rewrites those to their npm form
// ("npm:@jsr/std__fmt@0.225.6/"), which cannot resolve a subpath. Any other
// @std/fmt subpath we start importing needs its own entry here.
"@std/fmt/bytes": "jsr:@std/fmt@0.225.6/bytes",

Verified with a clean rm -rf node_modules && deno install plus deno check on core's entrypoint.

"@std/fs": "jsr:@std/fs@0.229.3",
"@std/log": "jsr:@std/log@^0.224.6",
"@std/media-types": "jsr:@std/media-types@0.224.0",
Expand All @@ -31,5 +35,6 @@
"unstable": ["raw-imports"],

"nodeModulesDir": "auto",
"jsrDepsInNodeModules": true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flag is now load-bearing for the new CI step, but the Deno version it needs is undeclared anywhere.

On Deno 2.5.3, deno install materializes the JSR deps only as node_modules/@jsr/std__*, so tsc cannot resolve the bare @std/* specifiers and deno task --cwd packages/web check exits 1 with 36 errors of the form:

Cannot find module '@std/log' or its corresponding type declarations.
Cannot find module '@std/path' or its corresponding type declarations.
Property 'info' does not exist on type 'Logger'.     # fallout from the above

On Deno 2.9.0 (what .github/actions/shared_setup pins) node_modules/@std appears and the check passes cleanly. So the check is green in CI and broken locally for anyone on an older toolchain, with an error message that points nowhere near the actual cause. AGENTS.md still just says "Deno (canary)".

Cheapest guard is to declare the floor so deno task refuses rather than misleads. Either add a "deno": ">=2.9" engine constraint if the version of Deno you're targeting honors it, or at minimum note the minimum version next to this flag and in AGENTS.md.

Also worth deciding deliberately: this is set at the workspace root, so it changes deno install for core and cli too, purely to satisfy web's typechecker.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine. We already suggest using Canary/latest. I will solidify a stable version in the future

"allowScripts": ["npm:@sveltejs/kit@2.5.24", "npm:@tailwindcss/oxide@4.1.14", "npm:esbuild@0.25.10", "npm:fsevents@2.3.3"]
}
155 changes: 137 additions & 18 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion packages/core/src/lib/file_processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,11 @@ class FileProcessor {
}

static async * read_lines(stream: ReadableStream<Uint8Array>) {
const reader = stream.pipeThrough(new TextDecoderStream()).getReader()
// NOTE `deno check` passes without this cast, but @forager/web type-checks core's source
// under TypeScript's DOM lib, which types TextDecoderStream's writable side as
// WritableStream<BufferSource> and rejects piping a Uint8Array stream into it.
const decoder = new TextDecoderStream() as ReadableWritablePair<string, Uint8Array>
const reader = stream.pipeThrough(decoder).getReader()
let buffer = ''
while (true) {
const read_result = await reader.read()
Expand Down
4 changes: 2 additions & 2 deletions packages/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
},
"dependencies": {
"@andykais/ts-rpc": "npm:@jsr/andykais__ts-rpc@^0.2.4",
"@opentelemetry/api": "1.9.0",
"@torm/sqlite": "npm:@jsr/torm__sqlite@^1.9.7"
"@opentelemetry/api": "1.9.0"
},
"devDependencies": {
"@deno/vite-plugin": "1.0.6",
"@sveltejs/kit": "2.43.7",
"@sveltejs/vite-plugin-svelte": "6.2.1",
"@tailwindcss/vite": "4.1.14",
"@types/deno": "^2.5.0",
"svelte": "5.56.4",
"svelte-check": "4.3.2",
"tailwindcss": "4.1.14",
Expand Down
8 changes: 7 additions & 1 deletion packages/web/src/app.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
// See https://svelte.dev/docs/kit/types#app.d.ts
// for information about these interfaces
import type { Forager } from '@forager/core'
import type { Config } from '$lib/server/config.ts'

declare global {
namespace App {
// interface Error {}
// interface Locals {}
interface Locals {
forager: Forager
config: Config
}
// interface PageData {}
// interface PageState {}
// interface Platform {}
Expand Down
Loading
Loading