## Background
Workspace `hasUncommittedChanges` / `hasUnpushedChanges` flags are written only by cloud sync. When a project stopped being a cloud project, those flags were never cleared, so the project overview cards kept showing "Uncommitted changes".
Repro:
1. Open a cloud project whose workspaces have uncommitted changes.
2. Remove the project from the remote.
3. Open the project overview. The cards still show "Uncommitted changes" although the project is now local.
A project converted from cloud to git carries the same residual flags, because the values come from its former cloud state.
## Changes
- Clear both workspace sync flags when a project's `remoteId` becomes `null` in the project service. Remote deletion, conversion to local, cross-organization move, and conversion to git all update the project through this service.
- Reuse the cleanup in the startup database repair to fix existing stale records. Only dirty workspace metas are written, and `modified` is preserved.
- Add service and repair tests.
## Testing
- `npm test -w insomnia-data` (538 tests)
- `npm run type-check -w insomnia-data`
- `npm run lint -w insomnia-data`
## References
- INS-3899
## Background
In a Git-synced project, restarting Insomnia without any change marked every design document as modified in the Git staging list. The diff of each affected YAML contained exactly one line: the embedded ApiSpec `meta.modified` timestamp.
The v5 design-doc YAML does not serialize `ApiSpec.fileName` (the v5 schema has no such field), while v5 import parses a missing `fileName` as an empty string. Any git round-trip therefore reset `fileName` to empty in the database, and the startup repair (`_applyApiSpecName`) rewrote it via `docUpdate`, which unconditionally restamped `modified: Date.now()` for every design document in one burst. RepoFileWatcher then re-exported the database to disk and git status reported all files as modified, repeating on every startup until committed.
## Changes
- Import: fall back `ApiSpec.fileName` to the file top-level name when the spec uses the `{ contents }` shape, so a round-trip never stores an empty fileName.
- Repair: skip the fileName backfill when it would write the existing value; a no-op write only restamps `modified`.
- Regression tests for both behaviors.
Fixes INS-4058
* fix: Warn when a Git Sync change cannot be discarded [INS-3689]
When a committed YAML file is not in the exact format Insomnia generates
(hand-edited, or written by an older version), discarding it restores the
file, the repo file watcher imports it and re-exports it, and the change
reappears. Users get stuck with a change they can never discard.
Detect this up front by replaying the import -> export round-trip in memory
on the raw index/HEAD content. When the result equals the working copy, the
whole diff is Insomnia re-generating the file, so the Commit Changes modal
shows a warning above the diff and the discard confirmation explains that
the file needs to be committed once.
- Add sync/git/canonical-file.ts, which mirrors database.update (initModel)
and the getWithDescendants ordering (created, then _id)
- Split getInsomniaV5DataExport into a DB fetch and a pure
serializeInsomniaV5Export
- Return rawHead/rawStage from GitVCS.fileStatus, since head/stage are
migrated and reordered for display
- Export initModel from insomnia-data/node
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* refactor: Replay the Git Sync round-trip on a scratch database [INS-3689]
The undiscardable-change check reimplemented parts of the import/export
pipeline (initModel, getWithDescendants ordering) to avoid touching the app
database. That copy would silently drift whenever the real pipeline changes.
Run the real pipeline instead: write the imported docs to a scratch
in-memory NeDB instance and export them with getInsomniaV5DataExport.
- Keep NeDB collections, change buffer and listeners per instance in
createNedbDatabase. They were module-level, so a second instance's init()
would have replaced the app's collections. flushChangesImpl is now handed
to the wrapper instead of being exported.
- Add an optional db parameter to getInsomniaV5DataExport and drop the
serializeInsomniaV5Export split and the initModel export
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix: Ignore import timestamps when detecting undiscardable changes [INS-3689]
Import fills a missing meta.created/modified with the current time, so a
hand-added entry without timestamps got a different value in the replay
than in the working copy the watcher wrote earlier. The exact comparison
then failed and the warning never showed, although the change still came
back after every discard.
Compare the replay with the working copy using hasSignificantChanges, the
same rules the Unstaged changes list uses, so differences the list already
ignores no longer hide the warning.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* chore: Reword the undiscardable change warning [INS-3689]
Explain the cause in user terms, using the wording suggested in the ticket.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* chore: Shorten the undiscardable change warning [INS-3689]
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* refactor: Rename committedContent to baselineContent [INS-3689]
The content a discard restores is the staged content when there is one, so
it is not necessarily committed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix: limit cookie template rendering to manually-set cookies and narrow template file access
* fix: only expand nested templates for variable substitution, not direct tag output
* test: cover OAuth2 access token exposure via the request tag for nested-template regression
* sec: exclude response-sourced cookies from WebSocket/Socket.IO connect rendering
* test: fix mTLS/cert smoke tests relying on secure-read-file path-prefix bug
* test: scope mtls smoke test locator to avoid strict-mode collision
* sec: close hard-link bypass of reserved NeDB database file check
* fix: avoid doubled path separator when allowlisted folder is a filesystem root
add initial settings for legacy test
add initial check for legacy unit test suites
show dropdown
remove spec route and merged with default debug page
showing document as collection
remove document term in UI
fix lint issue
fix ut failures
Move insomnia-data models, services, database code, and common utilities into a dedicated workspace package. Update consumers to import from the new package entrypoints and declare workspace dependencies for the extracted package.