firstsun-dev_git-files-sync/progress.md
ClaudiaFang 896d77bddf fix: remote-repo root path picker, delete-remote-only-file errors, symlinked-folder EISDIR
- Root path setting's folder picker now suggests folders from the remote
  repo tree (RemoteFolderSuggest) instead of the local vault, since Root
  path is a repo-side setting unrelated to local vault structure.
- GitHub/Gitea deleteFile: URL-encode path segments (matching GitLab's
  existing behavior) so paths with spaces/non-ASCII don't 404 on the
  pre-delete sha lookup; throw a clear error instead of silently sending
  a DELETE with an empty sha when that lookup 404s.
- SyncStatusView delete flow now surfaces the real error message instead
  of swallowing it into a bare "N failed" notice.
- SyncStatusView.readFileContent: guard against EISDIR when a hidden
  local-only symlinked folder (not yet known to the remote) is read as a
  file, falling back to the raw symlink target.

Closes firstsun-dev/blog#78 (misfiled; this is the actual fix location).
2026-07-14 09:11:26 +00:00

7.9 KiB

Session Progress Log

Completed work is archived in archive/, one file per calendar month — this file only tracks what's still open.

Current State

Last Updated: 2026-07-14 04:20 Session ID: current Active Feature: issue #78 (blog repo, misfiled — actually a git-files-sync bug: delete remote-only file fails) — investigation complete, fix in progress

Status

What's Done

  • feat-001..008 (project setup, settings UX bundle, folder picker, symlink pull fix, tree-SHA refresh, HTML-response error clarity, what's-new modal) — see archive/2026-07.md

  • All consolidated onto branch claude/fix-directory-symlink-pull-260713PR #51 (open, all CI green as of last check), per user's explicit request to keep the PR count down rather than one PR per issue.

  • "Root path" folder picker now suggests folders from the remote repo tree instead of the local vault. Added src/ui/RemoteFolderSuggest.ts (derives folder paths from gitService.listFiles(branch, false)); wired into the Root path field in src/settings.ts. Vault folder field untouched (still uses local FolderSuggest). Evidence: npx eslint . → 0 errors; npm run build → clean; npx vitest run → 302/302 passed.

  • Issue #78 (filed in firstsun-dev/blog but actually a git-files-sync bug — user confirmed to fix it here regardless of repo mismatch): "delete remote only file fail". Root-caused via subagent investigation, then fixed:

    1. github-service.ts/gitea-service.ts getApiUrl() now URL-encodes each path segment (fullPath.split('/').map(encodeURIComponent).join('/')), matching gitlab-service.ts's existing behavior. This was the likely actual trigger: paths with spaces/non-ASCII (e.g. Chinese filenames) 404'd on the Contents API.
    2. deleteFile() in both services now throws a clear error (Cannot delete "<path>": file was not found on branch "<branch>".) instead of silently sending a DELETE with an empty sha when the pre-delete getFile() lookup 404s.
    3. SyncStatusView.ts performLocalDeletion/performRemoteDeletion now capture {path, message} instead of swallowing the error; the failure Notice shows the real message(s), and logger.error logs full detail.
    • Added 4 new tests (2 in tests/services/github-service.test.ts, 2 in tests/services/gitea-service.test.ts) covering the empty-sha throw and non-ASCII/space path encoding.
    • Evidence: npx eslint . → 0 errors; npm run build → clean; npx vitest run → 306/306 passed.
    • Not yet done: comment on/reference issue #78 (in the blog repo) noting the fix landed in git-files-sync instead — flag to user before doing so since it crosses repos.
    • Second root cause found after user re-tested: user confirmed the file they were deleting was NOT a symlink, so the encoding/empty-sha fixes above weren't the whole story. Separately spotted (from a real console error the user pasted: EISDIR: illegal operation on a directory, read for a local-only symlinked folder .claude/skills/polish-blog) that SyncStatusView.ts readFileContent() called adapter.read() directly on string paths with no symlink guard — only the sha-based path (readLocalContentForSha) checked for symlinks, and only when the remote already knew about the entry as a symlink. A new local-only symlinked folder (not yet pushed) hit adapter.read() on a directory → crash → status stuck, contributing to "delete never resolves". Fixed by extracting readStringPathContent() with a catch-and-fallback to readLocalSymlinkTarget(). This is a distinct bug from the original #78 report but was surfaced by the same debugging session.
    • Still unresolved as of this turn: user reports "N failed" with no message when deleting a genuinely non-symlink remote-only file on GitHub — this is the old pre-fix Notice text, meaning none of the above fixes have reached the user's actual test vault yet (everything above is uncommitted in this sandbox). Next step: commit + push these changes to claude/fix-directory-symlink-pull-260713 so the user can rebuild/reload and re-test with real error messages before further root-causing.

What's In Progress

  • feat-009 - i18n / multi-language support (issue #38) — still paused, awaiting scope decision from user (unchanged from prior session).

What's Next

  1. Resolve feat-009's scope question with the user, then implement.
  2. Issue #37 (Bitbucket provider support) — large, deferred until #38 lands (per agreed order: 39→38→37).
  3. Re-sync against gh issue list --repo firstsun-dev/git-files-sync --state open — as of this session, #40/#41/#42/#48/#33/#36/#31/#39 are technically still "open" on GitHub but are all done in code and waiting on PR #51 to merge (they'll auto-close then). Remaining genuinely-unstarted issues: #47 (regex ignore lists), #45 (SonarQube findings), #38 (i18n, in progress), #37 (Bitbucket), #28 (non-engineering: community visibility).

Blockers / Risks

  • feat-009 (i18n) is blocked on a scope decision from the user — do not start writing src/i18n/* or touching settings.ts strings until that's confirmed, to avoid an inconsistent half-migration.
  • PR #51 is large (6 issues' worth of changes). If the user wants to review/merge it before more work piles on, flag this rather than continuing to add commits indefinitely.

Decisions Made

  • All work goes into one PR (#51): user explicitly said "不要那麼多pr merge" (don't want so many PRs). Branches claude/tree-sha-status-refresh-260713 and claude/fix-html-response-json-error-260713 were merged into claude/fix-directory-symlink-pull-260713 and their PRs (#52, #53) closed/auto-resolved; claude/settings-ux-improvements-260713 and claude/folder-picker-settings-260713 were already merged in earlier the same way (PRs #49, #50 closed). Any further issue work this session should commit directly onto claude/fix-directory-symlink-pull-260713, not a new branch.
  • src/changelog.ts is hand-curated, separate from the auto-generated CHANGELOG.md: semantic-release already maintains CHANGELOG.md from Conventional Commit messages, but it's commit-log-level detail (too granular for an end-user popup) and isn't shipped in the release assets (only main.js/manifest.json/styles.css are). The new modal needs a small, hand-written, user-facing "highlights" list instead — added as part of cutting a release, not auto-generated.
  • Fixed two duplication regressions mid-session (SonarCloud gate is 3% on new code, learned the hard way on PR #49 earlier): deduped TextComponent/TextAreaComponent test mocks, and deduped the GitHub/Gitea getBlob() bodies into a shared fetchGitHubStyleBlob() base helper.

Files Modified This Session

See archive/2026-07.md entries feat-003/005/006/007/008 for the full per-feature file lists. No files touched yet for feat-009 (i18n) — paused before any code was written.

Evidence of Completion

  • Tests pass: npx vitest run → 302/302 passed (as of commit 4eebebc)
  • Type check clean: npm run build → clean
  • Lint clean: npx eslint . → 0 errors
  • Manual verification in Obsidian: not done (no Obsidian instance available in this environment) for any feature this session

Notes for Next Session

  • Start by getting the user's answer on feat-009's scope (see "What's In Progress" above) before writing any i18n code.
  • feature_list.json's backlog is a snapshot from this session — re-check gh issue list before trusting it, though as of now it should be accurate (checked at end of session).
  • Working branch for all further commits: claude/fix-directory-symlink-pull-260713 (PR #51). Do not open a new branch/PR for the next issue unless the user says otherwise.