- 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).
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-260713→ PR #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 fromgitService.listFiles(branch, false)); wired into the Root path field insrc/settings.ts. Vault folder field untouched (still uses localFolderSuggest). Evidence:npx eslint .→ 0 errors;npm run build→ clean;npx vitest run→ 302/302 passed. -
Issue #78 (filed in
firstsun-dev/blogbut 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:github-service.ts/gitea-service.tsgetApiUrl()now URL-encodes each path segment (fullPath.split('/').map(encodeURIComponent).join('/')), matchinggitlab-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.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 emptyshawhen the pre-deletegetFile()lookup 404s.SyncStatusView.tsperformLocalDeletion/performRemoteDeletionnow capture{path, message}instead of swallowing the error; the failure Notice shows the real message(s), andlogger.errorlogs full detail.
- Added 4 new tests (2 in
tests/services/github-service.test.ts, 2 intests/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
blogrepo) noting the fix landed ingit-files-syncinstead — 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, readfor a local-only symlinked folder.claude/skills/polish-blog) thatSyncStatusView.tsreadFileContent()calledadapter.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) hitadapter.read()on a directory → crash → status stuck, contributing to "delete never resolves". Fixed by extractingreadStringPathContent()with a catch-and-fallback toreadLocalSymlinkTarget(). 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-260713so 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
- Resolve feat-009's scope question with the user, then implement.
- Issue #37 (Bitbucket provider support) — large, deferred until #38 lands (per agreed order: 39→38→37).
- 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 touchingsettings.tsstrings 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-260713andclaude/fix-html-response-json-error-260713were merged intoclaude/fix-directory-symlink-pull-260713and their PRs (#52, #53) closed/auto-resolved;claude/settings-ux-improvements-260713andclaude/folder-picker-settings-260713were already merged in earlier the same way (PRs #49, #50 closed). Any further issue work this session should commit directly ontoclaude/fix-directory-symlink-pull-260713, not a new branch. src/changelog.tsis hand-curated, separate from the auto-generatedCHANGELOG.md: semantic-release already maintainsCHANGELOG.mdfrom 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 (onlymain.js/manifest.json/styles.cssare). 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/TextAreaComponenttest mocks, and deduped the GitHub/GiteagetBlob()bodies into a sharedfetchGitHubStyleBlob()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 commit4eebebc) - 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-checkgh issue listbefore 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.