Skip to content

fix: make all typecheck and test gates green on macOS - #292

Open
VanniMnemonic wants to merge 7 commits into
lightningpixel:devfrom
VanniMnemonic:fix/typecheck-and-pytest-gates
Open

VanniMnemonic wants to merge 7 commits into
lightningpixel:devfrom
VanniMnemonic:fix/typecheck-and-pytest-gates

Conversation

@VanniMnemonic

Copy link
Copy Markdown

Summary

  • Repair the TypeScript gates: enable rewriteRelativeImportExtensions (node:test needs .ts specifiers for native type-stripping), include src/shared/types in the node project, drop the orphaned collections.ts, type Dirent[] entries, annotate assetLibraryUi map callbacks, add a null guard in the UI test.
  • Fix a macOS-only bug in generator_registry: os.path.abspath does not resolve /var/private/var, so correctly-authorized extensions stayed blocked as "incomplete installation". Now compares against ext_dir.resolve().
  • Make run-pytests.mjs prefer api/.venv (system Python lacks fastapi) and bump Electron to ^44.1.1 (pending from the packaging work).

Test plan

  • npx tsc --noEmit green on all four projects (node, web, root, builtins) — 26 errors → 0
  • npm run test:node — 118/118 pass
  • npm run test:py — 63/63 pass (was 2 import errors + 2 failures)
  • npx eslint . — clean
  • npm run build — exit 0

lightningpixel and others added 7 commits August 21, 2026 11:05
Modly had no SECURITY.md and no private channel for vulnerability
reports, which left email as the only route for researchers. Private
vulnerability reporting is now enabled on the repository; this points
people at it and sets expectations around it.

The policy leads with a threat model and lets the scope follow from it,
so that an excluded report comes with the reason it was excluded. Two
assumptions are deliberate: workflow files are untrusted input because
sharing them is normal, and any web page the user has open is an
untrusted caller of the loopback API. The second is why the
network-exposure exclusion is narrowed to deliberate exposure only --
a page in the user's own browser needs none.

Every claim was checked against the code. The policy does not call the
installer signed (no platform signs it), says nothing about PyTorch
(we do not ship it), and does not excuse social engineering on the
strength of UI warnings that do not exist.
…curity

docs: add a security policy with a private reporting route
tsc (node/web/root/builtins), eslint, build, test:node and test:py all
pass now.

- Enable rewriteRelativeImportExtensions: node:test runs the TS suites
  with native type stripping, which requires .ts import specifiers.
- Include src/shared/types in tsconfig.node.json and drop the orphaned
  collections.ts that pulled the renderer store into the node graph.
- Type readdir entries as Dirent[] and annotate the assetLibraryUi map
  callbacks so the null-filter predicates check against declared types.
- Fix the macOS registration bug in generator_registry: abspath does not
  resolve /var to /private/var, so authorized extensions stayed blocked
  as "incomplete installation". Compare against ext_dir.resolve() instead.
- Prefer api/.venv in run-pytests.mjs: the system Python lacks fastapi.
Drop unconditional stdout prints that fired at import time and on every
registry init/reload; WARNING and ERROR diagnostics are kept.
@lightningpixel
lightningpixel changed the base branch from main to dev September 12, 2026 12:02
@lightningpixel

Copy link
Copy Markdown
Owner

The macOS symlink fix in _discover_extensions looks like it'll break locally-linked extensions:

registration_authorization[2] == ext_dir.resolve() now follows the symlink/junction created by installFromLocal all the way to its target (the dev's real folder), while registration_authorization[2] itself is built with os.path.abspath() (which doesn't follow it). They'll never match, so any locally-linked extension gets flagged as "incomplete installation or interrupted runtime registration" right after a successful install — on Windows too, since junctions are resolved by Path.resolve() the same way.

Suggest resolving only the parent instead of the full path, mirroring how destination_path is built:

== ext_dir.parent.resolve() / ext_dir.name

That keeps the /var/private/var fix without breaking symlinked/junctioned extension folders. Worth adding a test with a symlinked ext_dir since the current suite doesn't cover it.

and not (
registration_authorization is not None
and registration_authorization[0] == ext_id
and registration_authorization[1].exists()
and registration_authorization[2]
== ext_dir.resolve()
)
)
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants