fix: list and traverse folders shared with you (closes #7) - #55
Open
lionello wants to merge 2 commits into
Open
Conversation
The v1.4.0 publish never reached npm: package-lock.json pins ESLint 10.8.0, which (since v9) only reads eslint.config.js, so `npm ci && npm run lint` in the release workflow died with "ESLint couldn't find an eslint.config.(js|mjs|cjs) file" and exit 2. Port .eslintrc.js to flat config. ESLint 10 no longer bundles @eslint/js or globals, so both are declared as devDependencies. bin/onedrive has no .js extension and flat config only lints files matched by a `files` pattern, so it is listed explicitly -- without it eslint reports "File ignored because no matching configuration was supplied" and exits 0, i.e. a lint step that lints nothing. ESLint 9 also started applying no-unused-vars to caught errors, which flags four catch blocks that deliberately ignore the error. Drop the unused bindings (optional catch binding; engines already require Node >=18) rather than weakening the rule, and move ecmaVersion to 2022. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A folder shared with you is a stub on your drive carrying a `remoteItem`
facet; the real item lives on the owner's drive. That is why `stat`
worked (the stub is a real item) while `ls` reported no children (the
stub genuinely has none), and why nothing below it resolved by path.
sanitize() could only build /drive/root:/...: paths, so there was no way
to address an item on another drive. Add three primitives next to it:
itemAddress() /drives/{driveId}/items/{itemId}, following remoteItem
to the target on the owner's drive
resolveShared() for a path below a stub, walk down from the top; the
first ancestor with a remoteItem is the stub, and the
remainder is addressed relative to it. Documented for
exactly this case, see
learn.microsoft.com/onedrive/developer/rest-api/concepts/addressing-driveitems
withShared() retry wrapper; only fires after a 404, so ordinary
paths cost nothing extra
resolveFolder() eager resolve for child enumeration, which is the one
case that cannot be detected from a failure: listing a
stub's children succeeds and returns nothing
Applied to ls, find, cp -R, cat, stat, rm, mv, mkdir, wget, upload and
the MCP list/find/read tools.
Also fix the second symptom: is_folder() and the ls columns now read
through remoteItem, so a shared folder lists as a folder with its owner
and child count instead of as an empty file.
Recursive traversal in find/cp -R now tracks the display path as it
descends rather than deriving it from parentReference.path: a child on
someone else's drive reports a parent path that is not addressable from
our drive.
Closes #7
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #7, plus the release-blocking lint failure found along the way.
Shared folders (
d16b1c3)A folder shared with you is a stub on your drive carrying a
remoteItemfacet — the real item lives on the owner's drive. That is whystatworked (the stub is a real item) whilelsreported no children (the stub genuinely has none), and why nothing below it resolved by path.sanitize()could only build/drive/root:/…:paths, so there was no way to address an item on another drive. Three new primitives sit next to it:itemAddress()/drives/{driveId}/items/{itemId}, followingremoteItemto the target on the owner's driveresolveShared()remoteItemis the stub, and the remainder is addressed relative to itwithShared()resolveFolder()Item-relative path addressing off an item id is documented for exactly this case: "when working with shared folders, you can use a path-based URL relative to the shared folder's item ID".
Applied to
ls,find,cp -R,cat,stat,rm,mv,mkdir,wget,uploadand the MCPlist/find/readtools.Also fixes the second symptom noted in the issue:
is_folder()and thelscolumns now read throughremoteItem, so a shared folder lists as a folder with its owner and child count instead of as an empty file.Recursive traversal in
find/cp -Rnow tracks the display path as it descends rather than deriving it fromparentReference.path— a child on someone else's drive reports a parent path that isn't addressable from our drive.chmod/ln/sendmailare deliberately left alone: they are owner-side sharing operations, not meaningful on someone else's drive.ESLint flat config (
e997228)Independent of #7, but it blocks releases, so it is here as its own commit: the v1.4.0 publish never reached npm.
package-lock.jsonpins ESLint 10.8.0, which since v9 only readseslint.config.js, sonpm ci && npm run lintexited 2 beforenpm publish..eslintrc.js→eslint.config.js, with@eslint/jsandglobalsadded as devDeps (ESLint 10 no longer bundles either).bin/onedriveis listed explicitly infiles: flat config only lints files a pattern matches, and it has no.jsextension. Without it eslint reports "File ignored because no matching configuration was supplied" and exits 0 — a lint step that lints nothing.no-unused-varsto caught errors, flagging fourcatchblocks that deliberately ignore the error. Unused bindings dropped (optional catch binding;enginesalready requires Node >= 18) rather than weakening the rule.To actually ship 1.4.0, re-running the failed job won't help — it checks out the
v1.4.0tag, which predates this. Either move the tag after merging (package.jsonstill says 1.4.0, so the version-match step passes) or cut 1.4.1.Testing
The saved token here was expired, so I could not hit the live API. Instead I built a mock of the classic API with a shared folder on it and ran the CLI against it. Verified working:
lsof the stub and of folders below it,catat any depth,stat,findwith-name/-type,cp -R(correct contents and local tree),mkdir/rm/mvreaching the owner's drive, and the MCP helpers. Missing paths still fail cleanly in a bounded number of requests. Diffing old vs new output on non-shared paths shows no output changes — only the extra resolve GET and id-based recursion.npm run lintexits 0 against ESLint 10.8.0 and prettier is clean.Worth a check against a real shared folder before merging:
resolveShared()'s item-relative addressing is the one piece verified only against docs and the mock.🤖 Generated with Claude Code