Commit graph

88 commits

Author SHA1 Message Date
Darkatse
beea023157 fix(dialog): keep native alert and confirm
The dialog plugin's init script replaces window.alert and window.confirm
with async IPC. Its confirm calls a command the plugin removed in 2.7.0,
and a synchronous confirm() reads the returned Promise as yes, so
extensions ran confirmed actions without asking. Register the plugin
without that script: every webview already provides native synchronous
dialogs, and on iOS and macOS our WKUIDelegate bridge now handles the
main frame too. File pickers and Rust message dialogs still use the
plugin, and no dialog:allow-message grant is needed.

Remove the wrapper once the plugin stops overriding native dialogs or
offers an opt-out.

Fixes #334

Validation: pnpm run check; native alert/confirm/prompt in a macOS dev build.
2026-10-09 22:01:05 -04:00
Darkatse
b108c2d736 fix(routes): own the /api namespace instead of falling back to index.html
Unrouted same-origin /api requests passed through to the asset protocol,
which answers any missing path with 200 index.html in production while the
dev server answers 404/405. Upstream features read that as success:
MovingUI presets looked saved but were lost, Office/Fandom probes looked
available, and Stable Diffusion failed to load with Horde/OpenRouter.

Claim /api/* in the router so unimplemented endpoints, for any method, get
the dispatcher's standard Unsupported endpoint 404 in dev and production
alike, with the message as statusText for upstream toasts. Drop the stubs
that only dodged the fallback (/api/search/*, Edge TTS plugin, SpeechT5)
and the interceptors' unreachable second fallback.
2026-10-07 21:40:43 -04:00
Darkatse
007abf7f1e refactor(a11y): unify API connection and sampler controls
Name fields from text-only title spans and help links as "Docs" plus their title. Select2 forwards field names and the current value to its focused elements and accepts script clicks; sampler lists share drag and move buttons; icon checkboxes share a focus ring.

Restore saved values after their final constraints through one numeric entry point and report out-of-range adjustments once per operation. Secret operations reject on failure and leave notification to their callers.

NovelAI fills missing mirostat fields with LR 0.2 / Tau 4 from the bundled Erato-Dragonfruit preset, a named preset's values rather than a NovelAI default.

Validation: pnpm run check
2026-10-07 04:33:42 -04:00
Darkatse
2d446c9237 feat(ohos): adopt the native window layout contract
Bring OpenHarmony onto the contract Android and iOS already follow.
ArkUI lays the Web out in the safe area, ArkWeb's RESIZE_CONTENT
shrinks the layout viewport by the docked keyboard's overlap, and an
app-owned window-layout plugin publishes window snapshots and draws
wallpaper strips behind the system bars.

- Share the window-layout plugin transport between Android and OHOS.
- Drop the remaining OHOS branches in Rust and the frontend.
- Rotate with the sensor, within the system rotation lock.

The ability and plugins-workspace pins point at the Darkatse forks
until LeenHawk/openharmony-ability#1 and LeenHawk/plugins-workspace#1
merge.
2026-10-05 19:53:38 -04:00
Darkatse
f4e48eccc5 refactor(layout): move mobile viewport ownership into native hosts
Consume system bars, cutouts and docked keyboards in Android and iOS,
then let web content use the resulting viewport. Publish window wallpaper
strips through one shared background path.

Remove the old CSS and IME compensation layers, update layout ABI v2,
and keep the matching documentation and behavior tests together.
2026-10-05 05:50:20 -04:00
sun19970908
4517f4e688
feat(files): save remote images through host staging (#324)
Android long-press saving now covers cross-origin images that the page
cannot read because of CORS. Like a browser's "Save image", the host
downloads remote http(s) sources into staging, while sources the page
owns are still read in their window. Both end in deliver_staged_file,
so the save panel, result and feedback are the same on every Android
version, with no storage permission.

- stage_file_from_url downloads through ContentService, which already
  owns the URL rule for external imports.
- Compare origins with window.origin. srcdoc and about:blank frames
  report location.origin as "null", which misrouted their same-origin
  images and skipped their a[download] links.
- fetch_to_file returns the response Content-Type, so a remote image
  without an extension in its URL is named from its type.
- Keep a path segment that is not valid percent-encoding as written,
  so names like "100%.png" no longer make the save fail.
- File exports call staging and delivery commands through the host
  safeInvoke, so failures show the backend message instead of a
  generic one.

This replaces the original DownloadManager approach in #324.

Co-authored-by: Darkatse <39111369+Darkatse@users.noreply.github.com>
2026-10-04 20:10:59 -04:00
Darkatse
9329278c6d refactor(files): unify native file selection and delivery
Centralize file picking, staging and delivery across platforms, with explicit cancellation outcomes and source ownership.

Remove superseded platform bridges and redundant tests, and document the shared contract and platform differences.

Validation: pnpm run check; Android aarch64 cargo check; 117 host tests.
2026-10-04 16:28:48 -04:00
LeenHawk
0077e15241
feat: add experimental OpenHarmony HAP support (#300)
* feat: add experimental OpenHarmony application build

* build(ohos): isolate experimental NAPI dependencies

* ci(ohos): build in this repository with public toolchain image

* ci: run existing checks for OHOS adaptation

* fix(ohos): generate QuickJS bindings for the OHOS target

* fix(ohos): use private caches and exclude desktop migration logs

* feat(ohos): restore native plugins and trusted endpoint confirmation

* ci(ohos): verify native plugin integration with existing checks

* chore(ohos): remove completed one-off validation workflow

* fix(ohos): clean dependency warnings and enable HAP LTO

* fix(ohos): retain shared plugin callbacks for the native bridge

* refactor(ohos): keep the native project and align the framework baseline

* fix(ohos): pin frame authorization and name the launcher entry

* fix(ohos): bind native builds and HAP packaging to the selected ABI

* fix(ohos): pin ordered Tauri bridge initialization

* fix(ohos): compress native libraries in HAP packages

* refactor(ohos): simplify HAP builds and Canary publishing

Build Rust once through the OHOS CLI and derive HAP versions from its merged
configuration. Replace the demo with the application page and remove generated
configuration writes, CMake scaffolding, and redundant preparation steps.

Keep ARM64 HAPs optional for Canary, report unsupported dev-log exports clearly,
and document the current build and host contracts.

Validated with pnpm run check, a local x86_64 HAP build and simulator smoke checks,
and Windows notification smoke checks.

---------

Co-authored-by: Darkatse <39111369+Darkatse@users.noreply.github.com>
2026-10-04 14:09:37 +08:00
Darkatse
07f8247cca refactor(platform): centralize native host identity
Derive platform and shell kind in Rust and inject them before WebView scripts.
Replace frontend UA guesses and pass host facts and IPC budgets to adapters.

Keep chat width in the frontend, preserve iOS policy initialization, and
restore the mobile third-party resource limit. Align docs and test fixtures.
2026-10-03 22:50:26 -04:00
sun19970908
a2e8de7499
Feat/android native image context menu (#309)
* test(storage): build extension store assertion path component-wise

The assertion joined one forward-slash literal, which Windows keeps verbatim, so the expected path mixed separators while entry_path() builds the real one with per-component joins. The resulting strings never matched and the test failed on every Windows run. Join the same components the production path uses so the comparison holds on all platforms.

* feat(android): save images from the WebView long-press menu

Long-pressing an <img> inside the app offered no way to keep it. Add a host-side context menu that routes every source through one rule: if the system downloader can reach the URL, hand it over, otherwise let the page read the bytes.

DownloadManager can only fetch real network locations, so blob:, data: and the app's own loopback origin all go through the page instead. App assets are fetched relatively to stay same-origin. The bytes are published through the existing AndroidPublicDownloadJsBridge, so the MediaStore transaction, the Android 10+ gate and the staging cleanup are reused rather than reimplemented. No new dependency and no build.gradle.kts change.

The installer takes an application context and owns its own Toast and DownloadManager lookups, keeping MainActivity to a single construction and one install call.

Failures surface as a toast instead of staying in logcat, including page-side fetch errors reported back over the bridge.

* refactor(android): save long-pressed images through the download bridge

Android WebView offers no image context menu, and a native
OnCreateContextMenuListener consumes the long press before the page can
claim it. Supply the missing contextmenu default action in the download
bridge instead: it honors preventDefault(), asks for confirmation, reads
the image in its own window and exports through downloadBlobWithRuntime,
so Android 8-9 keep the SAF fallback and feedback stays localized.

Remove the native installer and its DownloadManager and base64 paths.

---------

Co-authored-by: Darkatse <39111369+Darkatse@users.noreply.github.com>
2026-10-03 18:35:51 -04:00
Darkatse
e59a4f0b3c refactor(chat): stream compatibility reads through shared readers 2026-10-02 18:58:13 -04:00
Darkatse
90440961b3 feat(extension-store): stream JSON and blob persistence 2026-10-02 02:29:35 -04:00
Darkatse
be07b7face docs: condense settings and startup guidance 2026-10-01 23:14:08 -04:00
Darkatse
dfdd92f25b refactor(world-info): unify persistence and byte commits
Preserve world-info JSON bytes through bounded commit sessions shared with chat. Centralize save ordering, failure propagation, and update events.

Remove obsolete protocol plumbing and preserve invoke headers under the performance HUD.

Validation: pnpm run check.
2026-10-01 20:35:29 -04:00
Darkatse
c9b380aa70 refactor(chat): unify payload and metadata commit sessions
Route full saves and metadata updates through one bounded commit protocol,
with session-owned staging and atomic publication that preserves message bytes.
Simplify behavioral coverage and keep documentation focused on core contracts.
2026-10-01 00:53:02 -04:00
Darkatse
ac8c38a04f feat(formatting): unify message formatting and reasoning refresh 2026-09-27 20:19:53 -04:00
Darkatse
32bd1cbb05 feat(macros): unify contextual evaluation and parameter templates
Capture Agent inputs after extension hooks and share MacroEnv across prompt and request templates. Remove frozen macro emulation while preserving live extension behavior.

Simplify live data reads and browser test discovery; document the public context APIs.

Validation: pnpm run check.
2026-09-27 18:25:44 -04:00
Darkatse
ce748722c8 refactor(chat): unify JSONL format contracts
Centralize header, BOM and record validation across chat read and write paths. Preserve header-only validation for full commits and byte-exact metadata bodies.

Consolidate repository behavior tests and keep documentation focused on shared contracts.
2026-09-26 23:01:21 -04:00
Darkatse
cbda79fa23 feat(agent): manage persistent sessions and their lifecycle 2026-09-22 13:40:05 -04:00
Darkatse
4260e7293e feat(agent): support extension tools across chat and sessions
Register WebView tools through a dedicated provider with shared tool selection, naming, and result handling. Keep extension availability independent from saved profile selections.

Clarify model-facing feedback and consolidate behavioral tests and architecture documentation.
2026-09-22 00:55:32 -04:00
Darkatse
3c4d7db117 feat(agent): add persistent session runtime
Add standalone sessions with a shared profile, continuous JSONL history, and persistent work/tmp directories. Reuse frontend preset assembly and the existing model/tool loop with explicit Chat and Session targets.

Validation: pnpm run check
2026-09-21 22:18:25 -04:00
Darkatse
8d12ac646c docs(agent): describe unified workspace capabilities
Document skill mounts, prompt catalogs and migration boundaries. Retain the JavaScript capability and kit references while removing obsolete executor details.
2026-09-20 19:59:31 -04:00
Darkatse
c899f6405d refactor(database): integrate TriviumDB through a native adapter
Move database ownership, blocking IO and TQL binding into tt-adapter-triviumdb
and upgrade the native engine to 0.8.8. Preserve the plugin API capabilities
with awaited open, numeric IDs and explicit shared-namespace lifecycle.

Coordinate archive IO with database maintenance and restore each namespace
as a complete file group. Keep behavior tests for persistence, parameter
binding, transactions and recovery instead of per-method forwarding tests.

Validated with pnpm run check and tauri-pilot against the macOS app using
the real data root; temporary test namespaces were removed afterward.
2026-09-18 01:42:56 -04:00
Darkatse
a03f2cdf68 feat(personas): store user personas in avatar PNGs 2026-09-15 23:20:44 -04:00
Darkatse
0a58a87128 feat(settings): expose opt-in cold swipe loading
Add a disabled-by-default setting with reload semantics and localized help. Document the cold representation, ownership, and save compatibility contracts.
2026-09-13 04:53:10 -04:00
Darkatse
67a27b4a37 feat(chat): commit chat metadata without rewriting the chat body
`saveMetadata()` used to delegate to a full chat save, so every metadata
write re-serialized and re-transmitted the whole history. It now
persists only the header's `chat_metadata` through a new
`commit_chat_metadata` command. storage-core rewrites the header inside
the existing path mutation lock and copies the body byte for byte in one
blocking task; JS and IPC work is proportional to the header.

The header writer is shared with `metadata.setExtension()`, which now
also invalidates the character memory cache. Metadata saves stay in the
chat save queue, do not cancel a pending full save, and recover an
integrity conflict with a forced full save inside the same queue task.
New group chats publish their initial header before greeting hooks run,
so metadata written by those hooks is kept.

This narrows the SillyTavern 1.18.0 semantics: message edits need an
explicit full save. The change is documented in ChatPayload.md §3.1 and
the frontend contracts.
2026-09-12 03:46:15 -04:00
Darkatse
ef9237afc6 perf(chat): save first-party chats directly through the payload transport
First-party saves no longer round-trip through the local fetch
interceptor, which serialized the whole request and parsed it back into
a second object graph before the commit session ever saw it. Character
and group saves, branches, checkpoints, solo-to-group conversion and
rename rewrites now call the transport directly.

The commit facade snapshots every record as JSON text before its first
await, so mutations during transfer cannot tear the saved file, and it
classifies the host's integrity rejection into a typed error that both
the save paths and the compatibility routes branch on. The integrity
overwrite prompt is shared by character and group saves.

`/api/chats/save` and `/api/chats/group/save` remain for extensions.
2026-09-12 01:53:32 -04:00
Darkatse
1d0165e0a2 fix(desktop): route file drops to frontend handlers 2026-09-11 14:25:17 -04:00
SRsama
1bcf273a00 fix(windows): pass file drops to frontend import handlers 2026-09-11 12:12:49 +08:00
Darkatse
2a52de78f1 feat(agent): resume chats and retry presentation saves 2026-09-08 01:45:04 -04:00
Darkatse
a996402de7 docs(agent): simplify and consolidate framework documentation 2026-09-06 20:53:05 -04:00
Darkatse
f16ad7bff0 feat(agent): show structured delegation and handoff details 2026-09-06 19:14:53 -04:00
Darkatse
bcf68539aa feat(chat): add cached async content preprocessing hooks 2026-09-06 00:48:25 -04:00
Darkatse
402ef9bd75 fix(agent): preserve persistent state across chat forks (#216) 2026-09-04 20:11:37 -04:00
Darkatse
a0bfd3a6b4 docs(agent): document live tool-call streaming 2026-08-28 02:35:43 -04:00
Darkatse
94133d79d0 feat(window): add native F11 fullscreen toggle (#204) 2026-08-26 17:25:50 -04:00
Darkatse
c3f8b3ee1b feat(mcp): add registration-level tool description overrides 2026-08-25 01:14:40 -04:00
Darkatse
61a1abd55b refactor(dev): migrate dev logs panel to React 2026-08-23 21:51:16 -04:00
Darkatse
6c0f7359d9 fix(clipboard): route writes through native plugin #190 2026-08-18 19:26:45 -04:00
Darkatse
605ae1b7fd refactor(agent): commit live workspace without checkpoints 2026-08-18 16:20:05 -04:00
Darkatse
a14070488c feat(agent): auto-commit text drafts before explicit commits 2026-08-13 01:16:57 -04:00
Darkatse
5fd500b84a feat(mobile): keep AI generations running in the background #18 2026-08-11 19:47:12 -04:00
Darkatse
6b3ef0346b fix(chat): preserve streaming generations across WebView suspension #18 2026-08-11 16:15:22 -04:00
Darkatse
516eff67fe feat(mcp): add editable HTTP connection settings 2026-08-10 19:55:27 -04:00
Darkatse
206acdeaa7 feat(mcp): add tool execution to legacy generation 2026-08-10 00:19:16 -04:00
Darkatse
6d942b30c0 feat(mcp): persist shared tool catalog snapshots 2026-08-09 02:35:47 -04:00
Darkatse
fc1ebb025e feat(mcp): add explicit user tool test calls 2026-08-09 01:01:02 -04:00
Darkatse
b7670ec6c2 docs(mcp): document the M1 architecture 2026-08-08 02:19:10 -04:00
Darkatse
008ab07af3 feat(skills): support batch ZIP and folder imports #153 2026-08-07 00:05:23 -04:00
Darkatse
40159b499e refactor(agent): make canonical tool descriptors the source of truth 2026-08-04 20:07:20 -04:00