Commit graph

2844 commits

Author SHA1 Message Date
linonetwo
f59332da01 fix: use IPC toggle for tidgiMiniWindow sync scenario to avoid flaky keyboard shortcut on CI 2026-04-02 19:12:49 +08:00
linonetwo
6b010fdde2 fix: address Copilot review - main window lookup and comment clarity
- tidgiMiniWindow.ts: use index.html URL pattern to find main window
  (consistent with other step defs, avoids matching preferences window)
- ui.ts: clarify networkidle timeout comment
2026-04-02 18:41:53 +08:00
linonetwo
c82bded055 perf: merge scenarios + split CI steps for faster E2E
- Merge 3 defaultWiki scenarios into 1 (save 2 app launches)
- Merge 2 scheduledTask scenarios into 1 (save 1 app launch)
- Split CI test step into unit/prepare/e2e for visibility
- Add pnpm store cache to CI
- Fix viteEntry.ts: remove UTF-8 BOM, update stale JSDoc comment
- Set E2E timeout to 22min (was 25min in single step)
2026-04-02 18:05:23 +08:00
linonetwo
9b17736424 fix: await showWindow() in openTidgiMiniWindow to prevent race condition
The two showWindow() calls were using void (fire-and-forget), meaning
toggleTidgiMiniWindow returned before the window was actually shown.
On CI/Xvfb, the test checked isVisible() before show() completed.
2026-04-02 15:51:36 +08:00
linonetwo
00161509de fix: address CI failures - use IPC for mini window toggle, split talkWithAI clicks
- tidgiMiniWindow: use direct IPC toggle instead of keyboard shortcut after addTiddler
  to avoid race condition between TW syncer and keyboard event dispatch
- talkWithAI: split multi-click step into individual clicks so each gets its own
  25s timeout budget on CI
2026-04-02 15:21:49 +08:00
linonetwo
21ff2181c2 fix: flaky tests + merge scenarios to save 8 Electron launches
- crossWindowSync: wait for tiddler to be saved to disk via watch-fs before opening second window
- tidgiMiniWindowWorkspace: add retry backoff to 'should not see elements' step
- tidgiMiniWindow: add explicit window switch after addTiddler
- Merge 5 filesystemPlugin scenarios into 1 (save 4 launches)
- Merge 2 defaultWiki scenarios into 1 (save 1 launch)
- Merge 2 preference scenarios into 1 (save 1 launch)
- Merge smoke + logging into 1 (save 1 launch)
- Merge 2 tiddler scenarios into 1 (save 1 launch)
- Total: 65  57 scenarios (8 fewer Electron launches)
2026-04-02 14:45:43 +08:00
linonetwo
0d304dd5cd perf: only screenshot on failure, revert timeout to 25min
AfterStep was capturing a screenshot after every step (~1191 of 1446 steps).
Each screenshot requires IPC round-trip: getFirstWebContentsView  capturePage
 serialize PNG  transfer buffer  fs.writeFile. On CI this costs ~200-400ms
per step, totaling ~6 minutes of pure screenshot overhead.

Now screenshots are only taken for FAILED steps, saving ~6 minutes on CI.
This brings the total test time well within the 25-minute budget.
2026-04-02 03:49:07 +08:00
linonetwo
acced7d685 fix: copy tiddlywiki/core-server to packaged output
TiddlyWiki 5.4.0-prerelease introduced core-server/ directory which contains
commander.js (module-type: global). Without it, \.Commander is undefined
when load-modules.js startup runs \.Commander.initCommands(), crashing the
wiki worker with 'Cannot read properties of undefined (reading initCommands)'.

core-server is loaded by boot.js via loadPluginFolder(\.boot.coreServerPath),
which silently returns null when the directory is missing, so the error was
non-obvious and only manifested when actually starting a wiki workspace.
2026-04-02 01:21:03 +08:00
CI Auto
203af54516 ci: increase test timeout to 60min, fix find -o with xargs rm
- timeout-minutes: 25 -> 60 (packaging ~22min + unit tests ~1min + e2e needed)
- fix 'find ... -o ... | xargs rm' -> 'find ... \( -o \) ... -exec rm -rf {} +'
  (the unparenthesized -o with xargs caused 'rm: invalid option -- o' in CI)
2026-04-02 01:05:00 +08:00
lin onetwo
059c488293 fix: resolve AbortSignal realm mismatch in Electron 41 for streaming tests
In Electron 41, ELECTRON_RUN_AS_NODE mode uses Chromium-based fetch which
requires Blink's AbortSignal. Node.js AbortSignal fails the instanceof check.

Fixes:
- vitest.config.ts: set features/** to node environment via environmentMatchGlobs
  so HTTP-only tests use Node.js fetch (not Chromium fetch)
- setup-vitest.ts: guard all document/window access behind typeof document check
  so setup is safe in both jsdom and node environments
- callProviderAPI.ts: no change needed (signal issue is env-specific)
2026-04-01 23:49:37 +08:00
lin onetwo
7efb55bb83 chore: upgrade Electron 39->41, forge 7.10->7.11, fix native ABI and preload naming
- electron: 39.2.3 -> 41.1.1
- @electron-forge/*: 7.10.2 -> 7.11.1
- better-sqlite3: 12.4.5 -> 12.8.0 (rebuild against Electron 41 ABI 145)
- electron-unhandled: 5.0.0 -> 4.0.1 (v5 uses top-level await, breaks CJS main build)
- vite.preload.config.ts: emit preload.js (not index.js) to avoid collision with main
- viteEntry.ts: getPreloadPath() -> preload.js, renderer path unchanged
- package.json main: .vite/build/main.js (matches forge lib output)
- package.json: strip UTF-8 BOM that broke Volta manifest parsing
2026-04-01 23:11:12 +08:00
lin onetwo
84df7ab227 chore: pin tiddlywiki master commit and bump prerelease 2026-04-01 19:25:17 +08:00
lin onetwo
403154894e v0.13.0-prerelease23 2026-04-01 15:47:55 +08:00
lin onetwo
4c5e1d16c7
Fix/misc bug (#691)
* Use git service for backups and dynamic AI menus

Switch backup actions to call gitService.commitAndSync(commitOnly) so local backups work without remote auth and AI commit generation is triggered by omitting commitMessage. Make AI-related menu items always registered but use dynamic visibility/enabled checks (isAIEnabled) so they appear/disappear at runtime. Update menu item types/imports accordingly. Optimize workspace persistence to write only the single updated workspace to settings.json (stripping syncable fields when tidgi.config exists) instead of saving all workspaces; remove the old saveWorkspacesToSettings method. Add warnings/logging: warn if git worker observable is undefined, log/notify when cloud sync is skipped due to missing auth/gitUrl. Misc: remove a redundant debug log in tidgiConfig, remove native process monitoring startup call, include commitMessage for CommitDetailsPanel sync, and drop entriesFingerprint/debug noise from git log data.

* fix: avoid rewriting unchanged workspace config

* fix: separate plain and ai backup flows

* feat: add searchable settings views

* fix: narrow sync adaptor revision type

* chore: release tidgi-shared 0.1.3

* Preferences: unify Scheduled/Background tasks and fix skeleton nav

- Remove legacy background task UI/dialogs (use ScheduledTask unified system)
- Attach invisible anchors to skeleton placeholders so sidebar scrollIntoView works while loading
- Add English/zh translation keys for AddAlarm/AddHeartbeat
- Add requestIdleCallback polyfill (tests) and speed up to 0ms for tests
- Search: match English translations (txEn) in SearchResultsView

* Fix view zero-size on minimize; realign on restore/show

Guard view bounds from 0x0 content size to prevent BrowserView disappearing when window is minimized; fall back to safe offscreen size. Add window 'restore' and 'show' handlers to realign views. Add getMemoryUsage() in wiki worker and expose RSS/heap via getWorkersInfo; show worker memory in Developer Tools diagnostics.

* Fix background/quit behavior: synchronous close handler; platform-specific runOnBackground default; add getWindowMetaSync; add forced-exit timeout for before-quit cleanup

* Refactor preferences: add definitions and registry

Add a new structured preferences system: introduce definition schemas, typed item/section types, explicit section files, a registry (allSections/sectionById), side effects, action handlers, and helper builders (zodPreferencesSchema). Add custom preference UI items and registration (customItems, registerCustomSections) and tests validating schemas. Replace previous zod/settings schema files with the new definitions and make IPreferences an explicit TypeScript interface. Small UI updates: use LanguageSelectorItem and WikiUserNameItem in Guide and Help pages. Also remove net.isOnline() pre-checks from Git.commitAndSync and Git.forcePull to avoid false-negative network detections.

* Fix blank wiki after hide+reopen: re-attach orphaned views on realign

Root cause: three compounding issues when the main window is hidden and then re-shown via a second-instance shortcut click.

1. getView() now auto-removes stale entries whose webContents.isDestroyed() == true.
   This allows addView() / showWorkspaceView() to recreate destroyed views instead of
   silently skipping them (which left the new window blank).

2. realignView() now calls browserWindow.contentView.addChildView(view) before setBounds().
   If a view survived window destruction but became orphaned (detached from its parent
   BrowserWindow), re-attaching it makes it visible again.  addChildView is idempotent
   so normal re-entrant calls are safe.

3. window.open() existing-window branch now calls addViewForAllBrowserViews(activeWorkspace)
   before realignActiveWorkspace(). This ensures that any destroyed/missing view is
   recreated BEFORE the realign attempts to reposition it.  The call is a no-op when
   views already exist and are healthy.

* Fix blank WebContentsView after restoring hidden window (Windows bug)

Electron on Windows sometimes fails to repaint a WebContentsView that remains attached to a window that is hidden and then shown again. By unconditionally calling \
emoveChildView\ followed by \ddChildView\ during \
ealignView\ and \showView\, we force the Chromium compositor to reparent and paint the view correctly, ensuring the Wiki becomes visible as soon as the user restores the app from the background.

* Fix blank WebView on window restore: show view before realign, fix same-workspace click

Two root causes identified and fixed:

1. openWorkspaceTiddler silently skipped setActiveWorkspaceView when the user
   clicked the already-active workspace icon (guard: oldId !== newId).  The view
   was blank and clicking its icon did nothing.  Guard removed  setActiveWorkspaceView
   is now always called; it is safe with the same ID (hibernation guard is already
   correct for that case).

2. The 'show' event handler and window.open() existing-window path were calling
   realignActiveWorkspace() which only calls setBounds.  On Windows, when a window
   transitions from hidden/background to visible the Chromium compositor may not
   repaint a WebContentsView whose bounds have not changed.  Both paths now call
   refreshActiveWorkspaceView()  a new lightweight helper that calls showView()
   (removeChildView + addChildView + setBounds + webContents.focus) before realigning.
   This forces a compositor repaint and makes the wiki page visible immediately.

* Refactor view restore chain: clean up redundant repaint/realign calls

Full chain analysis identified 4 structural problems:

1. refreshActiveWorkspaceView() called TWICE concurrently on window restore:
   window.open() called existedWindow.show() which fired the 'show' event
    refreshActiveWorkspaceView() AND THEN immediately called refreshActiveWorkspaceView()
   again explicitly, creating a race condition on removeChildView+addChildView.

2. realignView() contained removeChildView+addChildView, which ran immediately after
   showView() already did removeChildView+addChildView+setBounds+focus.  The second
   remove+add clobbered the focus state set by showView, breaking keyboard focus.

3. setActiveWorkspaceView() called showWorkspaceView + realignActiveWorkspace, meaning
   the view was remove+add+setBounds+focused by showView, then immediately remove+add+
   setBounds-without-focus again by realignView.  Double bounds, lost focus.

4. Same pattern in refreshActiveWorkspaceView: showWorkspaceView + realignActiveWorkspace.

Clean design after refactor:
- showView()        = force-repaint path: remove+add+setBounds+focus (unchanged)
- realignView()     = bounds-only:        setBounds ONLY, no remove+add
- showWorkspaceView = calls showView for main+mini windows
- realignActiveWorkspace = calls realignView (now just setBounds) + buildMenu;
                     used for fullscreen/sidebar/resize events
- setActiveWorkspaceView = showWorkspaceView + buildMenu (not +realignActiveWorkspace)
- refreshActiveWorkspaceView = showWorkspaceView + buildMenu (not +realignActiveWorkspace);
                     called from 'show' window event (fire-and-forget: no rethrow)
- window.open() existing-window = show() only; 'show' event handler calls
                     refreshActiveWorkspaceView automatically, no duplicate call

* chore: bump electron-ipc-cat to 2.4.0

Rolling Observable timeout (120s initial, 60s idle) fixes git-upload-pack
timeout for large repos (100+ MB) during mobile sync.

* style: unify layout between Preferences and EditWorkspace

Use PageRoot and PageInner from PreferenceComponents to eliminate subtle padding/background differences. Resize EditWorkspace window to match Preferences. Clean up lint errors.

* Add E2E test for window-restore blank-view bug + log markers

Two changes:

1. Log markers added to aid diagnosis and enable E2E verification:
   - [test-id-VIEW_SHOWN]             in ViewService.showView()
   - [test-id-REFRESH_ACTIVE_VIEW_START/DONE] in WorkspaceView.refreshActiveWorkspaceView()

2. New E2E feature: features/windowRestore.feature
   Scenario 1: 'Wiki WebContentsView is visible immediately after restoring hidden window'
     - hides main window (same path as close+runOnBackground)
     - triggers second-instance via app.emit('second-instance')
     - asserts [test-id-REFRESH_ACTIVE_VIEW_DONE] and [test-id-VIEW_SHOWN] log markers
     - asserts browser view is within visible window bounds
     - asserts wiki content is readable
   Scenario 2: 'Clicking already-active workspace icon re-shows the WebContentsView'
     - verifies the removed oldId !== newId guard: clicking current workspace must
       now call setActiveWorkspaceView which fires showView

   Two step definitions added to features/stepDefinitions/application.ts:
   - 'I hide the main window as if closing with runOnBackground'
     calls BrowserWindow.hide() directly in main process
   - 'I reopen the main window as second instance would'
     emits app 'second-instance' event in main process

* Fix E2E test: correct second-instance emit args, add wiki-ready wait in Background

Three issues found and fixed by running the tests:

1. app.emit('second-instance') argument order wrong
   DeepLinkService listener: (_event, commandLine) => commandLine.pop()
   Our emit: app.emit('second-instance', [], process.cwd(), {})
   This made 'process.cwd()' land in commandLine, .pop() failed on a string.
   Fix: app.emit('second-instance', {}, [], '', {})  fake Event first,
   then empty argv array, then workingDirectory.

2. In test mode, window.open() skips existedWindow.show() to avoid UI popups.
   The 'show' event never fired so refreshActiveWorkspaceView was never called
   and the window stayed hidden from Playwright's perspective.
   Fix: explicitly call mainWindow.show() via app.evaluate() after emitting
   second-instance, replicating what production window.open() does.

3. Background used 'the browser view should be loaded and visible' which has
   a 21-second timeout and fails before TiddlyWiki finishes initializing in
   the test environment (pre-existing issue in defaultWiki.feature too).
   Fix: replaced with deterministic log marker waits:
     [test-id-WIKI_WORKER_STARTED] + [test-id-VIEW_LOADED]
   plus 'I confirm the main window browser view is positioned within visible
   window bounds' for a structural check without content dependency.

Result: both @window-restore scenarios pass (31/31 steps green, ~48s).

* Fix reopened main window restore after recreation and rebind view resize

Root cause on Windows was not the hide/show path, but the close+recreate path when tidgi mini window keeps the app alive while runOnBackground is false.

What was actually happening:
1. The user closed the main window.
2. The app stayed alive because tidgi mini window still existed.
3. A second-instance launch recreated a new main BrowserWindow.
4. The old workspace WebContentsView still existed in ViewService.
5. But the new main window missed the automatic restore because the BrowserWindow 'show' event fired inside handleCreateBasicWindow() before registerBrowserViewWindowListeners() attached the 'show' listener.
6. If the user then clicked the workspace icon, showView() reattached the old view manually, but its resize listener was still bound to the old destroyed BrowserWindow, so resizing the new window no longer resized the view.

Fix:
- ViewService now rebinds the debounced resize handler every time showView() attaches an existing view to a BrowserWindow.
- Window.open() now detects the recreate-main-window case for BrowserView windows and immediately calls refreshActiveWorkspaceView() if the active workspace already has an existing view instance.
  This restores the view without waiting for a workspace icon click.

Why old E2E missed it:
- It simulated hide/show (runOnBackground=true) instead of the real user path (main window close + app kept alive by tidgi mini window).
- It only checked that the view was within visible bounds; it did not resize the window and assert the view filled the content area after the reopen.

New E2E coverage:
- Configures tidgiMiniWindow=true and runOnBackground=false before launch.
- Closes the main window, reopens it via second-instance, verifies refresh/view-shown markers, verifies bounds, resizes the recreated main window, and asserts the BrowserView fills the content area after the debounced resize handler runs.
- Scenario passes locally: 1 scenario, 20 steps, all green.

* Update pnpm-lock.yaml

* fix: address Copilot PR review issues

- Restore workspaceID from window.meta() in EditWorkspace (was hard-coded debug value)
- Add missing React/type imports to customComponentRegistry.ts, workspaceCustomComponentRegistry.ts, registerCustomSections.tsx, registerWorkspaceCustomSections.tsx, useSections.ts
- Fix HighlightText regex: use index parity (odd index = match) instead of stateful regex.test() with global flag
- Fix actionHandlers native.pickDirectory to read current preference value instead of passing the key string as a path
- Move PreferenceComponents import before registerCustomSections() call to fix import ordering

* fix: fix import ordering to satisfy dprint/eslint format rules

* fix: stabilize e2e selectors and EditWorkspace loading fallback

- align workspace section testids in e2e features
- migrate background-task e2e to scheduled-task selectors
- add edit workspace fallback loading when metadata/observable is late
- add deterministic switch testid for schema boolean items
- make sync snackbar assertion resilient to progress text changes
- clear draft-check timeout handle in sync service

* fix: add apiKey to test provider config so isAIAvailable() returns true

The AI commit message e2e test expects both commit-now-button and
commit-now-ai-button to appear. The AI button only renders when
isAIGenerateBackupTitleEnabled() returns true, which internally calls
externalAPIService.isAIAvailable(). That method requires a non-empty
apiKey for openAICompatible providers, but the test's
createProviderConfig() never set one, causing isAIAvailable() to
return false and the AI button to never render.

* feat(gitServer): add generateFullArchive for fast mobile clone

- Add generateFullArchive() to IGitServerService interface
- Implement tar archive generation: git archive + system tar append
- Archives working tree + minimal .git metadata (HEAD, refs, objects)
- Cache by HEAD commit hash, auto-cleanup old archives
- Bump tidgi-shared to 0.1.5

* fix(e2e): resolve workspace by runtime name/folder in step defs

* fix(ci): satisfy lint rules in gitServer archive generation
2026-04-01 15:45:26 +08:00
lin onetwo
c53292b548
Fix/misc bug2 (#689)
* Improve IPC sync and multi-window browser views

Add robust revision tracking and per-title save serialization to the IPC sync adaptor to ignore stale SSE echoes and prevent overlapping saves (titlesBeingSaved, lastSavedRevisions, pendingSaveOperations, queueSaveOperation, markSaveStart/Finish). Ensure deletions and loads update stored revisions. Disable backgroundThrottling for BrowserWindow/WebContentsView so renderer callbacks (SSE/observables) continue while windows/views are hidden. Update webContents view helpers and step definitions to target a specific window/page (pass Page/currentWindow through executeInBrowserView, getTextContent, click/type/press helpers), and improve view selection by matching target window URL. Update docs to document hidden-window behavior and revision filtering, and add/update feature tests for cross-window sync, hidden TidGi mini window sync, and a rapid-save tiddler scenario.

* Handle main workspace routing for tiddlers

Adjust FileSystemAdaptor routing so that when a tiddler matches the main workspace it uses the main watch path (watchPathBase) instead of treating it as a sub-wiki folder. Add an isMainWorkspaceMatch check to pick the correct target directory and to avoid generating sub-wiki file info for the main workspace.

Also update tests and feature file: extend subWiki.feature to verify routing to the main workspace path when the workspace has a routing tag configured, and add unit tests to assert routing to the main wiki tiddlers folder and to the wiki root when useWikiFolderAsTiddlersPath is enabled.

* review

* v0.13.0-prerelease22
2026-03-24 18:28:38 +08:00
lin onetwo
949c7b00bb
Fix/misc bug1 (#688)
* fix: possible error on wiki creation

* Add isSubWiki/mainWikiToLink and optimize tidgi.config

Introduce new syncable wiki fields (isSubWiki, mainWikiToLink) with schema, types, and defaults; add localization for an autofill note. Expose Database.readWikiConfig over IPC and implement readTidgiConfig usage. When updating workspaces, only write tidgi.config.json if syncable fields actually changed to avoid redundant O(n) disk writes. Update AddWorkspace UI to eagerly read tidgi.config.json (when enabled) to pre-fill form fields and show a helper note. Improve workspace hibernation logic: avoid hibernating page workspaces' servers when switching and prevent concurrent duplicate hibernation calls. Also update template submodule reference.

* Update ErrorDuringRelease.md

* Fix workspace config sync and sub-workspace settings

* adjust menu

* Add sub-workspace UI, view navigation & types

Expose view navigation helpers and types, add sub-workspace UI and related translations, and introduce provider registry types.

- Add canGoBack/canGoForward/goBack/goForward APIs to view service and IPC interface to allow navigating embedded views.
- Implement UI for sub-workspace management in EditWorkspace: list bound sub-workspaces, open sub-workspace settings, and select main workspace for sub-wikis. Add tests IDs and small UX tweaks (cancel button test id).
- Update SaveAndSyncOptions and SubWorkspaceRouting to reflect new sub-workspace flows and remove deprecated main workspace path field.
- Add provider registry interface that re-exports external API types and IPC descriptor (src/services/providerRegistry/interface.ts).
- Add ambient type declarations for @modelcontextprotocol SDK client transports.
- Improve test/e2e support: detect packaged e2e runs via --test-scenario arg in environment constants, update step definition to open edit workspace via the window service using WindowNames, and adjust feature file assertions for sub-wiki bindings.
- Add English and Simplified Chinese translation keys for sub-workspace UI strings.

These changes enable managing sub-workspaces from the Edit Workspace window, provide programmatic view navigation, and add types/interfaces required for integrating external provider tooling and tests.

* fix lint

* Add diagnostics, process monitoring, and menu improvements

Add process diagnostics and monitoring: introduce shared processInfo types, native.getProcessInfo and startProcessMonitoring (30s snapshots + logs), label the main Node process and give descriptive initial window titles; include renderer PIDs in view info and log view creation. Unified Developer Tools panel into a Process & View Diagnostics dialog that shows Node/renderer memory and wiki worker info (wiki.getWorkersInfo). Fix FileSystemAdaptor to pass old fileInfo to generateTiddlerFileInfo to avoid numeric suffixes when overwriting tiddlers. Menu and workspace changes: add a Sync menu and move git items there, simplify context menu generation, remove some developer menu items, and adjust createBackupMenuItems signature. Window and workspace improvements: add recreateUnlessWorkspaceID option and safer window close handling, restore hibernated flag when bringing workspace views up, and improve sub-workspace settings UI. Also add several i18n entries for the new diagnostics and UI text.

* Add renderer metrics; fix hibernation & menus

Collect and display renderer process metrics and harden workspace/window logic.

Highlights:
- Add new i18n keys for renderer PID/CPU/private memory (en and zh-Hans).
- Native service: check and throw on shell.openPath errors; gather per-renderer metrics (private/working set KB and cpu percent) via app.getAppMetrics() and webContents, and improve logging.
- Extend IRendererProcessInfo with private_KB, workingSet_KB and cpu_percent.
- DeveloperTools UI: show PID tooltip, private memory and CPU columns, sort renderers by memory, color-code values, and fix SquirrelTemp path/openPath call.
- Git/menu changes: consolidate backup/sync items to include AI option inline; only show sync for cloud workspaces with a git remote and authenticated user; always show local backup.
- Workspaces/view: prevent races when switching to a workspace by tracking hibernation as awaitable promises (Map), awaiting in-flight hibernations, and re-fetching workspace state before actions.
- View/window safety: add null/undefined checks for view.webContents in several handlers (setupViewEventHandlers, handleAttachToTidgiMiniWindow) to avoid operations on destroyed/closed webContents.

These changes improve diagnostics, prevent race conditions, and make menu behavior more consistent.

* fix: lint errors - remove unused WindowNames import, fix import order and indentation

* fix: address review comments - remove mainWikiToLink from syncable config (absolute path unsafe to sync), fix missing-field detection in syncableChanged, precompute viewsInfo Map in renderer table, use stable pid as row key

* fix: auto-expand SubWorkspaceRouting accordion when bound sub-wikis exist, so e2e test selectors are visible

* fix: update e2e test menu paths - git/sync items moved from Wiki menu to Sync menu

* fix: stabilize sync settings and e2e sync helper
2026-03-23 02:48:46 +08:00
lin onetwo
613d811846
fix: ci (#687) 2026-03-13 19:04:12 +08:00
lin onetwo
84af09ba5f v0.13.0-prerelease21 2026-03-12 21:35:15 +08:00
lin onetwo
2a5eb349f2
Fix/misc bug (#686)
* refactor: replace time-window echo prevention with mtime+size and content checks

FileSystemWatcher: use recorded mtime+size (lastWriteStats) and saving-state
flag (titlesBeingSaved) to skip own-write echoes, plus content identity fallback.
Removes unreliable setTimeout-based exclude/scheduleFileInclusion.

ipcServerRoutes: replace TTL Map with synchronous Set (ipcPendingTitles),
attach changeCount as revision to change Observable.

ipc-syncadaptor: use lastSavedRevisions for revision-based echo prevention,
batch large syncs via requestIdleCallback.

Also: EditWorkspace controlled input fixes, port field local state, agent
framework config setConfig/persistConfig split, misc value ?? '' fixes.

* Enhance e2e screenshots and test logging

Improve end-to-end test reliability and diagnostics:

- Capture window screenshots for non-BrowserView steps: add captureWindowScreenshot and use it in AfterStep to capture the Electron BrowserWindow via webContents.capturePage() when appropriate; keep existing captureScreenshot for BrowserView steps. (features/supports/webContentsViewHelper.ts, features/stepDefinitions/application.ts)
- Prevent wiki restart race: wait for the wiki worker '[test-id-WIKI_WORKER_STARTED]' marker before restarting to avoid DoubleWikiInstanceError. (features/stepDefinitions/wiki.ts)
- Make git-related test markers more visible by switching logger.debug → logger.info for git init/commit/sync/checkout/revert and git-log rendering markers, ensuring e2e tests can reliably detect these events. (src/services/git/index.ts, src/windows/GitLog/useGitLogData.ts)
- Minor feature test tweak: wait for page to load in defaultWiki.feature before interacting with the editWorkspace window.

These changes reduce flaky screenshots and timing races in tests and improve test marker visibility for e2e detection.

* Enhance e2e screenshots and test logging

Improve end-to-end test reliability and diagnostics:

- Capture window screenshots for non-BrowserView steps: add captureWindowScreenshot and use it in AfterStep to capture the Electron BrowserWindow via webContents.capturePage() when appropriate; keep existing captureScreenshot for BrowserView steps. (features/supports/webContentsViewHelper.ts, features/stepDefinitions/application.ts)
- Prevent wiki restart race: wait for the wiki worker '[test-id-WIKI_WORKER_STARTED]' marker before restarting to avoid DoubleWikiInstanceError. (features/stepDefinitions/wiki.ts)
- Make git-related test markers more visible by switching logger.debug → logger.info for git init/commit/sync/checkout/revert and git-log rendering markers, ensuring e2e tests can reliably detect these events. (src/services/git/index.ts, src/windows/GitLog/useGitLogData.ts)
- Minor feature test tweak: wait for page to load in defaultWiki.feature before interacting with the editWorkspace window.

These changes reduce flaky screenshots and timing races in tests and improve test marker visibility for e2e detection.

* Use startTransition to update port on change

Import startTransition from React and update the port input handler to capture the raw value, update local display state, and defer parsing/setting the workspace port inside startTransition. The handler now parses an empty value as 0, validates the number (non-NaN and >= 0) before calling workspaceSetter, improving responsiveness by marking the workspace update as non-urgent. Also removed an obsolete inline comment.

* Improve E2E, view sync, and wiki IPC robustness

Multiple fixes and improvements across E2E tests, view management, wiki IPC, and workspace handling:

- Docs: add SHOW_E2E_WINDOW env var note to allow visible Electron windows during manual E2E runs.
- Features: simplify/adjust cross-window sync scenario and refine hibernation workspace selectors to avoid collisions with similarly named workspaces.
- E2E steps: make AI-request assertion resilient by polling (backOff); replace brittle DOM-driven tiddler creation with direct TiddlyWiki API calls in browserView step definitions for reliability; add small UI click pause and longer click timeout in ui steps.
- Timeouts: unify global timeout to 25s and derive Playwright short/log wait timeouts from it.
- WebContents helpers: prefer the last child wiki view (active one) when multiple views exist and update comments.
- WikiEmbedTabContent: wake workspace on mount and simplify cleanup to always clear custom bounds on unmount; handle errors.
- Chat UI: hide TabListDropdown in split view.
- Agent instances: default missing agentFrameworkID to 'basicPromptConcatHandler' for older definitions.
- View service: add activelyShownViews set to avoid hiding views that were explicitly shown via showView(); clear stale custom bounds when showing views; avoid moving views offscreen when actively shown; ensure cleanup removes active flag.
- IPC server routes: prefer URL-based workspace ID (resolve correct casing via workspace service) to handle cross-session routing; pass effective workspace ID to route handlers.
- Wiki service: add startup timeout to avoid indefinite hangs waiting for worker boot message.
- IPC sync adaptor: implement titlesBeingSaved/titlesBeingLoaded sets to prevent save-back and SSE echo issues; mark titles when saving/loading and suppress spurious saves.
- Wiki worker IPC routes: replace per-subscriber addEventListener with a shared Subject and single change listener to avoid missed events and cross-window sync bugs; forward subject events to subscribers and log readiness.
- Windows: keep windows hidden during tests by default but allow showing them when SHOW_E2E_WINDOW=1.
- Workspaces: compute next insert order so new wiki workspaces appear at the top of regular workspaces (shift others down).

Overall these changes reduce flakiness in tests, prevent cross-window echo and routing bugs, make view lifecycle handling safer, and improve developer ergonomics for debugging E2E runs.

* fix(e2e): bypass system proxy for git HTTP operations in sync test

Git clone/push/fetch to localhost was routed through the system proxy (port 1080),
which returned 502 Bad Gateway. Add -c http.proxy= to disable proxy for all
HTTP git commands in the sync test step definitions.

* fix: address CI lint errors and Copilot review comments

Lint fixes:
- useOptimisticField: rename *Ref/*Fn vars to *Reference/*Function (unicorn/prevent-abbreviations)
- wiki/index: rename args to arguments_ (unicorn/prevent-abbreviations)
- FileSystemWatcher: use specific type assertion for tiddler fields to avoid no-base-to-string warning
- webContentsViewHelper: rename loop var i to index
- interface.ts: merge duplicate imports from same module (dprint)
- ipc-syncadaptor: expand queueMicrotask callback (dprint)

Copilot review fixes:
- ipcServerRoutes: move subscription to outer scope so Observable teardown
  is returned synchronously from the constructor, preventing subscription leaks
  when observers are disposed before the async IIFE resolves
- useOptimisticField: capture localValue at focus time; on blur only commit
  when user actually changed the value (not when serverValue updated while focused)
- FileSystemWatcher.markSaveComplete: guard scheduleGitNotification behind
  non-empty absoluteFilePath to avoid spurious git notifications on error paths

* fix(e2e): handle corrupt settings.json in cleanup and use filechooser intercept for image upload

- tidgiMiniWindow cleanup: wrap readJson with try/catch so truncated/empty
  settings.json (race between app shutdown write and After hook read) is
  handled gracefully instead of throwing SyntaxError

- application.ts: add 'I prepare to select file ... for file chooser' step
  that registers a Playwright one-shot filechooser handler BEFORE the click
  that triggers fileInput.click(). This prevents the native OS dialog from
  appearing entirely (the chooser is resolved directly with the supplied file).

- talkWithAI.feature: replace two-step 'click then setInputFiles' with the
  new 'prepare filechooser  click' pattern so no OS dialog is shown during
  the AI image attachment test
2026-03-12 21:19:10 +08:00
lin onetwo
64cc965a4a
Feat/discuss note with agent (#685)
* Add wiki tiddler attachment support to agent chat

Implements the ability to attach wiki tiddlers to agent chat messages. Updates the UI to allow selection of tiddlers from active wiki workspaces, fetches and renders tiddler content as plain text, and appends it to the user message sent to the AI. Includes e2e tests, updates to store actions, service interfaces, and prompt concatenation logic to support this feature.

* fix: callback not useCallback cause autocomplete panel flash

* Add wiki tiddler attachments to message bubbles

Message bubbles now display attached wiki tiddlers as clickable chips, allowing users to navigate directly to the referenced tiddler in the appropriate workspace. Metadata handling and persistence for wiki tiddlers has been updated to include workspaceId, and tests have been added to verify the new UI behavior. The chat view also now closes the TiddlyWiki sidebar for better focus when navigating from a selection.

* Support split view navigation for wiki tiddler attachments

Adds isSplitView prop to ChatTabContent and related components to distinguish between split view and normal tab modes. Wiki tiddler attachment navigation now uses a different strategy in split view, opening tiddlers directly in the browser view. Updates types and tests to reflect the new behavior, and improves robustness of response handling in several places.

* docs: move to .github/instructions/testing.instructions.md

* test: view loading slow on mac

* refactor(e2e): move wiki load steps to Background in talkWithAI.feature; remove all sidebar close delays and polling, only set state when TiddlyWiki is ready; clean up code and logs for sidebar auto-close in split view

* docs: make test inst shorter

* lint

* refactor(view): slim ViewService, move menu to separate file, orchestrate view logic in WorkspaceViewService, update all callers, fix lint floating promise, all unit and e2e tests pass

* fix: add data-testid to attachment listbox for E2E test

- Add slotProps to MUI Autocomplete to ensure attachment-listbox is rendered with correct test-id
- Fix E2E test timeout when waiting for attachment listbox element

* lint

* put 'Talk with AI' menu on top and attachment i18n

Introduce a reusable createTalkWithAIMenuItems helper to build "Talk with AI" menu entries (default agent + other agents submenu) and integrate it into workspace menu generation. Add new i18n keys for Agent.Attachment and WikiEmbed across locales and update UI to use translation keys (remove hardcoded fallback strings). Improve chat input/attachment behavior: expose a test-id for the attachment listbox, use i18n for labels/placeholders, and tweak input component wiring. Fix Cucumber step handling by normalizing expected newline sequences and safely handling empty message content. Also adjust memo deps in SortableWorkspaceSelectorButton to include id.

* feat: enhance AI interaction in workspace context menu with local trigger support

* feat: add tool approval and timeout settings

- Introduced ToolApprovalConfig and related types for managing tool execution approvals.
- Implemented WebFetch and ZxScript tools for fetching web content and executing scripts, respectively.
- Added token estimation utilities for context window management.
- Enhanced ModelInfo interface with context window size and max output tokens.
- Created API Retry Utility for handling transient failures with exponential backoff.
- Updated AIAgent preferences section to include Tool Approval & Timeout Settings dialog.
- Developed ToolApprovalSettingsDialog for configuring tool-specific approval rules and retry settings.
- Modified vitest configuration to support aliasing for easier imports and stubbing.

* Refactor agent instance tools and services for improved modularity and maintainability

- Extracted type definitions and tool registry from defineTool.ts into separate files (defineToolTypes.ts, toolRegistry.ts) to reduce file size and enhance importability.
- Implemented a retry mechanism in ExternalAPIService for stream creation to handle transient failures.
- Updated ToolApprovalSettingsDialog to persist settings using localStorage instead of a preference service.
- Created agentMessagePersistence.ts and agentRepository.ts to manage agent message and instance CRUD operations, reducing the size of AgentInstanceService.
- Added a progress tracker document (AgentTODO.md) for the ongoing enhancement plan of the TidGi Agent.

* feat: add AgentSwitcher component for agent definition switching

- Implemented AgentSwitcher component with dropdown functionality for selecting agent definitions.
- Integrated loading of agent definitions on dropdown open.
- Added visual feedback for current selection and disabled state.

feat: create ToolResultRenderer for generic tool result messages

- Developed ToolResultRenderer to handle rendering of <functions_result> messages.
- Included collapsible parameters and result display with error handling.
- Added truncation for long results in collapsed view.

test: add comprehensive tests for MessageRenderer components

- Implemented tests for AskQuestionRenderer, ToolResultRenderer, ToolApprovalRenderer, and BaseMessageRenderer.
- Ensured proper rendering and functionality for various message types and states.
- Included pattern routing tests for MessageRenderer.

feat: introduce TurnActionBar for action management in agent turns

- Created TurnActionBar component for managing actions like rollback, retry, delete, and copy.
- Integrated visual feedback for file changes and rollback status.
- Added functionality for copying agent responses and full conversation to clipboard.

feat: implement askQuestionPending for managing user responses

- Developed infrastructure for handling pending ask-question requests.
- Implemented promise-based blocking until user responds to agent questions.
- Added timeout handling for ask-question requests.

* feat: Implement background task management for agent instances

- Added functionality to restore heartbeat timers and alarms for active agents upon service initialization.
- Introduced methods to retrieve active background tasks and cancel them via the UI.
- Enhanced alarm clock tool to persist alarm data in the database, ensuring alarms survive app restarts.
- Updated agent instance schema to include scheduled alarm data.
- Modified prompt concatenation logic to support context window size for message history.
- Removed system prompt parameter from model parameters schema and related components.
- Improved UI to display and manage background tasks, including heartbeat and alarm details.

* feat: Implement Scheduled Tasks Management and Background Task Settings

- Add feature for managing scheduled tasks for agents, including viewing, adding, and editing tasks.
- Create tests for agent repository and background task settings APIs.
- Introduce ScheduledTaskManager for unified scheduling of tasks with interval, at, and cron schedules.
- Implement edit-agent-definition tool for modifying agent configurations, including heartbeat and prompt settings.
- Ensure tasks persist across app restarts and respect active hours filtering.

* Update wiki

* fix(security): harden htmlToText against XSS via encoded tags

- Use tolerant script/style regex that handles </script > with spaces
- Stop decoding &lt;/&gt; entities to prevent reintroducing HTML tags
- Decode &amp; last to avoid double-unescaping (&amp;lt;  &lt;  <)
- Fixes all 4 CodeQL findings (bad filtering, incomplete sanitization,
  double escaping, incomplete multi-character sanitization)

* fix: lint and format errors (eslint naming, dprint formatting, stub classes)

* fix: exclude tidgi.config.json from template copy and fix log marker pattern

- Skip tidgi.config.json when copying wiki template to prevent overriding workspace name
- Change waitForLogMarker default pattern from 'wiki-' to '*' to match actual log filenames
- Filter tidgi.config.json in e2e step too (fs.copy in wiki creation step)

* perf(e2e): merge 5 scheduledTask scenarios into 2 to reduce app restarts

* perf(e2e): merge crossWindowSync and streamingStatus scenarios to reduce CI time

* ci: increase test timeout to 20min for larger e2e scenario count

* perf(e2e): merge agent scenarios and enable parallel on CI

- Merge agent.feature wiki-search + wiki-operation into one scenario
- Merge agent.feature create-agent-from-newtab + create-agent-from-fallback into one
- Enable cucumber parallel: 2 on CI (7GB RAM, dynamic ports for mock servers)
- Total scenarios: 66 -> 61

* fix: cleanup MCP client processes when deleting or closing agent

* ci: disable parallel (CPU contention), increase timeout to 30min for 61 scenarios

* perf(e2e): merge 3 preference background-task scenarios into 1, increase timeout to 45min

- Preference alarm/heartbeat CRUD merged into single scenario (saves 2 app restarts)
- Total scenarios: 59 (was 66)
- CI timeout 45min for the expanded e2e suite

* fix: restructure e2e scenarios, fix subscription leak and debounce cleanup

- Restructure agent/talkWithAI/streamingStatus feature files for reliability
- Fix talkWithAI scenarios missing mock server startup and app launch
- Remove duplicate subscription in handleSwitchAgent (useEffect already handles it)
- Clean up debounced update functions when agent is deleted/closed
- Use agentId:messageId key for debounced functions to enable per-agent cleanup

* fix(e2e): remove :last-child selectors broken by TurnActionBar, fix tab/dialog selectors, increase CI timeout to 25min

* fix: use const for non-reassigned variable (lint)

* fix(e2e): fix close-all-tabs opacity issue, scheduledTask undefined steps, MUI multiline textarea targeting

* fix(e2e): use tab-list-dropdown to close all tabs, fix selector for actual TabListDropdown component

* fix(e2e): add timing waits for BrowserView repositioning and git log UI refresh

* fix(e2e): make 'should not see' step wait for element to disappear instead of instant check

* fix(e2e): increase executeInBrowserView default timeout from 500ms to 2000ms
2026-03-09 04:07:39 +08:00
lin onetwo
b39bd0ea19 fix: exclude tidgi.config.json from e2e template copy and fix unit test paths for cross-platform 2026-03-08 14:10:47 +08:00
lin onetwo
b070896923 fix: exclude tidgi.config.json from template copy to prevent name override
When creating a wiki from template, the template's tidgi.config.json
(containing name='Tiddlywiki-NodeJS-Github-Template') was being copied,
causing all new wikis to inherit the template's name instead of using
the user's chosen name. This also broke e2e tests that expect workspace
name 'wiki'.
2026-03-08 05:06:29 +08:00
lin onetwo
21115e2e51 fix(e2e): waitForLogMarker default pattern 'wiki-' never matches actual log files
The wiki worker log is named after the workspace (e.g., 'Tiddlywiki-NodeJS-Github-Template-*.log'),
not 'wiki-*'. Changing default to '*' to match all .log files, fixing 25 scenario failures.
2026-03-08 04:10:29 +08:00
lin onetwo
3164fd6c29 fix(e2e): revert update-workspace-settings to use restartWiki() like master
The stop->update->start approach introduced a race condition that caused
'watch-fs did not stabilize after restart' failures in 25 out of 52 scenarios.
Reverting to the proven update->restartWiki() approach from master while still
supporting enableHTTPAPI restart.
2026-03-08 03:32:02 +08:00
lin onetwo
7047658838 perf(e2e): merge 3 sync scenarios into 1 to fit within 15min CI budget
Consolidate all sync tests (desktop cloud sync + mobile HTTP sync) into a single
scenario with Parts 1-3. This runs the Background only once instead of 3 times,
saving 2 full Electron app restart cycles (~4-6 min on CI).

- Part 1: Menu sync (commit & push)
- Part 2: Diverged history (auto-merge & conflict markers)
- Part 3: Mobile HTTP sync (fast-forward, merge, conflict resolution)
2026-03-08 02:06:38 +08:00
lin onetwo
07923c692f perf(e2e): merge mobileSyncConflict into sync.feature, share one Background to save 2 app restarts on CI
- Deleted mobileSyncConflict.feature
- Added mobilesync scenario as 3rd scenario in sync.feature
- Unified Background enables both enableFileSystemWatch and enableHTTPAPI
- Saves ~2-4 minutes of CI time (2 fewer Electron app restart cycles)
2026-03-08 01:00:02 +08:00
lin onetwo
ee77bbd13f ci: retrigger CI 2026-03-08 00:20:25 +08:00
lin onetwo
7ca460ea5e fix: merge 4 mobileSyncConflict scenarios into 1 to fit CI budget, fix git process leaks and error handling
- Consolidate 4 separate mobileSyncConflict scenarios into a single scenario
  with 4 parts, saving 3 app restarts (~2min on CI)
- Add Observable teardown to kill git child processes on unsubscribe
- Propagate stdin errors to subscriber instead of silently logging
- Validate git service parameter against allowlist
- Reorder readOnly check before expensive git operations
- Add error event handler to all git child process spawns
2026-03-07 23:26:34 +08:00
lin onetwo
a4669132c6 ci: increase test timeout to 25 min for mobile sync e2e scenarios 2026-03-07 16:09:45 +08:00
lin onetwo
1df1bf4236 update templatw wiki 2026-03-07 15:34:02 +08:00
lin onetwo
9a4766f85d Refine token sync info fields 2026-03-07 01:25:34 +08:00
lin onetwo
b3d1425d9c Respect token auth toggle 2026-03-07 00:09:02 +08:00
lin onetwo
2dc2faa627 Fix desktop review follow-ups 2026-03-07 00:04:01 +08:00
lin onetwo
6fe618ce64 perf(gitServer): run git gc --auto after auto-commit to pre-pack loose objects
Without gc, git upload-pack must delta-compress all loose objects on every
clone request, which is slow for wikis with many tiddlers.

git gc --auto runs only when git decides the repo has enough loose objects
(controlled by gc.auto threshold, default 6700). It's a no-op on already-
packed repos, so the overhead on each upload-pack preflight is negligible.
2026-03-06 22:24:23 +08:00
lin onetwo
acbefbd445 fix: add unknown type to catch callback, collect stderr in runGit, check exit codes in ensureCommittedBeforeServe
- src/main.ts: fix ESLint @typescript-eslint/use-unknown-in-catch-callback-variable (CI failure)
- mergeUtilities.ts: runGit now collects stderr for debugging; resolveAllConflicts logs stderr on commit failure
- gitServer/index.ts: ensureCommittedBeforeServe checks exit codes from git add/commit and logs warnings instead of silently ignoring failures; use runGit helper instead of raw gitSpawn
2026-03-06 16:07:34 +08:00
linonetwo
a0e7a6ec57 Add mobile HTTP git sync tests & merge utilities
Introduce end-to-end tests and server-side support for mobile-style Smart HTTP git sync. Adds a new mobileSyncConflict.feature and extended sync.step definitions to simulate HTTP clone/sync cycles, pushes, and assertions (including file content checks and HTTP readiness/backoff). Introduces src/services/gitServer/mergeUtilities.ts to resolve .tid conflicts (mobile metadata wins, body merged) and common git helpers, and wires those into the git server (use runGitCollectStdout, DESKTOP_GIT_IDENTITY, and mergeAfterPush endpoint). Misc: update workspace restart flow and settings handling, tweak test helpers (skip screenshot capture for file steps), adjust slugify rules, minor UI/formatting change, and bump git-sync-js dependency (with lockfile update).
2026-02-24 16:50:08 +08:00
linonetwo
eaf425ce4c Run before-quit cleanup and close DBs sequentially
Extract before-quit cleanup into runBeforeQuitCleanup(), and install a guarded before-quit handler that prevents default quitting, runs the cleanup once (tracked by beforeQuitCleanupPromise), and then exits the app. Cleanup stops wiki workers first, then closes databases, stores settings, and tears down windows; logger is destroyed and uninstall run in finally. Refactor DatabaseService.closeAllDatabases() to close each data source sequentially with per-key try/catch (remove the parallel Promise.allSettled and individual timeout wrappers) to avoid concurrent shutdown races and ensure clearer error logging.
2026-02-21 14:26:17 +08:00
linonetwo
185f719d94 Fix workspaceID case bug, esbuild outbase, autocomplete panel re-render, VIEW_LOADED handler, streaming status polling, and increase executeInBrowserView timeout for E2E stability. All 52 scenarios pass 2026-02-21 12:36:58 +08:00
linonetwo
975b7e3e1f feat(e2e): support simplified root wiki and stabilize browser-view waits 2026-02-20 18:51:14 +08:00
linonetwo
71b951c95c Import tidgi.config id and tighten git server
Add optional import of tidgi.config when creating/opening a workspace (UI checkbox + form plumbing). Include canonical workspace "id" in syncable config and JSON schema; remove port from syncable fields. Improve writeTidgiConfig to merge with existing file and only persist non-default fields (handling empty id). Workspace creation now applies synced id (with duplicate-id check) and supports a useTidgiConfig flag; sanitize/migrate stored workspace IDs and remap mainWikiID references. Add workspaceID info tiddler for sync. Harden Git server: auto-commit local changes before upload-pack, set receive.denyCurrentBranch=updateInstead, ensure config before receive-pack, and reject pushes to read-only workspaces. Small IPC/logging/UI adjustments related to these changes.
2026-02-17 01:38:24 +08:00
linonetwo
fe6a8db148 Add sub-workspaces info for mobile sync 2026-02-15 14:45:10 +08:00
linonetwo
f3dd26d98a Update TidGiServiceAPI.md 2026-02-12 21:45:33 +08:00
linonetwo
a00265b34c fix: $tw.tidgi.service not mounted 2026-02-12 21:44:12 +08:00
linonetwo
fa491658f1 fix: service type 2026-02-11 18:51:42 +08:00
linonetwo
021a8af106 Update index.ts 2026-02-10 19:31:18 +08:00
linonetwo
b677088a48 Expose TidGi services to $tw.tidgi and add types
Make TidGi IPC service proxies available inside the TiddlyWiki sandbox and provide typings for plugin authors. Added docs (docs/TidGiServiceAPI.md), bumped tidgi-shared to 0.1.2, and introduced shared type files (packages/tidgi-shared/src/{global.d.ts,tidgiGlobal.ts}) and tsconfig include for .d.ts files. Preload now exposes service via contextBridge and attaches it to $tw.tidgi.service (with DOMContentLoaded retry). Updated various wiki plugin files to use $tw.tidgi.service instead of window.service, adjusted worker-side service exports (no automatic global attach), and updated startNodeJSWiki to safely inject service into the wiki sandbox with proper typing. Added runtime TiddlyWiki type augmentations (src/types/tidgi-tw.d.ts). These changes ensure plugins running in the VM can reliably access typed service proxies.
2026-02-10 02:41:32 +08:00
linonetwo
593ed2d29c feat: publish tidgi-shared npm for types, and place tidgi.service 2026-02-09 23:16:49 +08:00
linonetwo
544a8b1bf3 refactor: use globalThis 2026-02-09 02:51:30 +08:00
linonetwo
fbb83125eb Improve shutdown sequence and add timeouts
Rework app shutdown to stop wiki workers before closing databases and to run remaining cleanup in parallel. In main.ts, wikiService.stopAllWiki() is called first (sequentially) and then database shutdown, settings store, and window cleanup are run via Promise.all to avoid blocking.

In database service: add checks for underlying driver transactions and warn if a DB has an open transaction; skip destroy for uninitialized dataSources; log database keys; add a per-database close timeout (10s) and additional debug logs to reduce better-sqlite3 crash risk and surface problems during shutdown.

In wiki service: add a timeout (5s) around worker.beforeExit to avoid hangs; collect worker IDs and stop each worker with per-worker try/catch so one failure doesn't block others; use Promise.allSettled and improved logging to ensure shutdown proceeds even if some workers fail.

Overall goal: make shutdown more robust, avoid hangs and sqlite crashes, and improve observability during shutdown.
2026-02-09 01:17:43 +08:00
linonetwo
f168e4a997 Include workspace name and token in info tiddlers
Pass workspaceName into the workspace destructure and add conditional info tiddlers for workspace name and workspace token ($:/info/tidgi/workspaceName and $:/info/tidgi/workspaceToken). These fields are added when available to include workspace metadata in the generated QR/code info without changing existing tokenAuth handling.
2026-02-09 01:00:59 +08:00