-
Notifications
You must be signed in to change notification settings - Fork 135
fix(workspace): count an IDE pin and this client's manifest as binding evidence #1376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -772,11 +772,22 @@ async function hasManagedSnapshot(directory: string): Promise<boolean> { | |
| } | ||
| } | ||
|
|
||
| /** Whether local state says this project has a workspace: a snapshot a sync | ||
| * once published, or a cached binding. Decides if a failed binding lookup is | ||
| * worth telling the user about. */ | ||
| /** Whether this project is known to have a workspace. Decides if a failed | ||
| * binding lookup is worth telling the user about. */ | ||
| async function hasBindingEvidence(directory: string): Promise<boolean> { | ||
| if (await hasManagedSnapshot(directory)) return true | ||
| // The IDE's pin is a workspace the user chose for this tree, and it is never | ||
| // written to disk — an inaccessible pinned workspace would otherwise be | ||
| // silent. A malformed pin counts as well: the extension set one, and | ||
| // resolution fails closed on it for every directory. Scoped with the same | ||
| // `resolveWithinRoot` as the pin purge in `syncSkills`, so the purge and the | ||
| // warning always agree on which folders a pin speaks for — and the warning | ||
| // still fires after that purge has removed the manifest. | ||
| const pin = readPin() | ||
| if (pin.kind === "invalid") return true | ||
| if (pin.kind === "valid" && resolveWithinRoot(directory, pin.root) !== null) return true | ||
| // This client's manifest, not merely a `_workspace` folder: a tree the user | ||
| // or another tool created says nothing about a binding. | ||
| if ((await readManifest(directory).catch(() => null)) !== null) return true | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: The new Prompt for AI agents |
||
| return (await readLocalBinding(directory).catch(() => null)) !== null | ||
| } | ||
|
|
||
|
|
@@ -930,8 +941,9 @@ export async function syncSkills(directory: string): Promise<SyncResult> { | |
| // workspace. With a local binding row, offline resolves to a stale "bound" | ||
| // and fails later at the list; without one, the server is always asked, | ||
| // so offline lands here for EVERY opted-in project, including ones never | ||
| // linked. A snapshot on disk (a server-side binding that synced before) | ||
| // or a local row is that evidence; without either, stay quiet. | ||
| // linked. An IDE pin for this tree, this client's manifest (a server-side | ||
| // binding that synced before) or a local row is that evidence — see | ||
| // `hasBindingEvidence`; without any of them, stay quiet. | ||
| if (outcome.status === "unknown" && (await hasBindingEvidence(canon))) | ||
| syncError = "could not confirm this project's workspace (offline, or no access to it)" | ||
| return | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: This counts any shallowly parseable
.manifest.jsonas this client’s evidence, so a user or another tool can create a lookalike manifest and make an unlinked project emit offline warnings. Tighten manifest validation or ownership before using it for evidence.Prompt for AI agents