Update Versions - #75
Merged
Merged
Conversation
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.
Changepacks
devup-mcp@0.10.1 → 0.11.0 - crates/devup-mcp/Cargo.toml
Minor
installedmeantis_file()and nothing more, so aSKILL.mdwritten by a devup-mcp from six months ago was indistinguishable from the current document, and so was a one-line placeholder someone dropped in that directory. The practical sting was on the other side of the same check:installskipped anything already present, which meant there was no way to update a skill at all - the first install a machine ever did was the last one it would get, and every later call reported that stale copy as installed. Install state is now decided by comparing the bytes on disk against exactly what this build would write, and reported asinstallState.revision:current(identical, or fetched from upstream, which is at least as new as the vendored copy and cannot be compared further without the network),older(carries devup-mcp provenance but is not this build's),incomplete(the entry document is this build's but a file it links to is missing or differs - the shape that looks installed and whose links go nowhere), orforeign(no devup-mcp provenance note at all). An install now rewritesolderandincompletein place, at the roots where the stale copies actually are rather than where a fresh install would have chosen, and never touchesforeign, because replacing a document this server did not write would destroy someone's work and an install is not the moment to decide that was a mistake; it is reported underleftAloneinstead.reportcountsoutdatedapart frommissingbecause the two need different words from the caller - one is a skill the agent has never seen, the other is one it is reading right now and being taught rules this binary no longer emits. The runtime table grew from three clients to twelve, with Cursor, Zed, Windsurf, VS Code/Copilot, Gemini CLI, Cline, Continue, Amp and Goose added from their own source or official documentation. Cline is the entry that justifies the table: it reads.agents/skillsonly from the home directory, so the shared project-local convention is one directory it never opens, and the previous fallback would have written exactly there. JetBrains AI Assistant is deliberately absent - it has no auto-discovered directory and a human must register one, so guessing a path would be worse than the fallback. An unidentified client now reads every convention devup-mcp knows while still writing only the three broad ones: reading narrowly was making a Cursor user who had installed once into~/.cursor/skillsbe told the skill was missing, with a second copy as the remedy. The gap moved intodevup_project_contextas well, scoped to what each scope actually found, becausedevup.jsonis devup-ui's theme format, theopenapi.jsonunder scope api is generated by vespera routes and themodels/*.jsonunder scope db are vespertide schemas, and an agent about to edit one of them had no way to learn it needed those rules. Three guide rules moved intodevup_figma_export's own description - screenshots verify rather than author, do not hand-interpret the node tree, never guess a UI value - because those three produce wrong code rather than a worse response when violated, and they lived only in a resource that Codex collapses into a single namespace description.reportalso hands over the machine-wide skill directory for this runtime undermachineWide, as a path to run yourself: the home directory stays outside the allowed write root, and widening that so a design-to-code server can write to$HOMEis not a trade worth making for convenience. FinallyautoUpdate.installedPathNoteexplains that a version-named install directory belongs to the host and is fixed at install time, so a directory reading 0.9.0-dev around a binary reporting 0.10.1 is self-update working rather than a mismatch..agents/skillsand does not look at.claude/skills, but a fresh project has no skill root at all, so the choice fell through to the first known convention - which is.claude/skills- and the agent was told devup-ui was installed while it went on writing devup-ui from guesses. opencode never reported it because opencode scans.claude/skillsfor compatibility and so happened to work. The runtime is now read from the MCPclientInfoname sent at initialize and decides the directory; a client that does not name itself has every convention written, because with no name and no existing root there is nothing to choose on and picking one of three blind is a two-in-three chance of writing where nothing looks, against a cost of a few kilobytes inside a directory the project already owns. Install state now also reads the machine-wide roots -~/.claude/skills,~/.codex/skills,~/.config/opencode/skill,~/.agents/skills- because a skill there really is loaded: a workspace holding devup-ui in all four, every one of them live, was answeringinstalledCount: 0, which the README itself calls the noise that teaches a reader to ignore the field. Those roots are read and never written, so the allowed-write-root boundary is unchanged. The symmetric mistake is refused too, and it is the quieter one: a file in a directory this runtime never opens is not counted as installed.devup_skillstakesprojectRootlike every other tool, because without it the report described the server's own write root, which is not the project unless the two were configured alike - a host granting one shared parent, an Orca worktree pool or a monorepo checkout, had every call reporting on that parent and would have installed there. The inducement moved to where agents actually read. The strongest sentence used to live ondevup_skills's own description, which is the tool an agent has no reason to call; it is now indevup_figma_export's description, the one channel that reaches an agent which never sees the serverinstructions- a subagent handed tool schemas alone, and Codex, whereinstructionsbecomes a single namespace description rather than prompt text. The same gap is on the export response asskillGap, and deliberately not gated onprojectRoot, since the caller who does not know devup-ui is precisely the caller who does not send it;devup_ui_validatekeeps its own copy for the case where the code was already written and refused. Install state is resolved through oneLookupcarrying project, home and runtime rather than three threaded parameters, which also makes the home injectable - reading the real one had these assertions passing in CI and failing on the machine of anyone who has devup-ui installed in their own home, which is everyone working on this repository.Patch
unknown, every convention is written, and the result is safe and completely silent - indistinguishable from a client devup-mcp has genuinely never heard of. The report now echoes the name verbatim asruntime.clientNamebeside the verdict drawn from it, and when nothing matched it says whatunknownmeans, that it is safe rather than wrong, and that a client with its own skill directory whose name is not in the table is exactly what should be reported. That is the only path by which the table gets corrected, and it is the same class of silent failure the rest of this branch exists to remove.Lookup::newtakes the client name and derives the runtime from it rather than being handed a verdict, so the name and the conclusion cannot disagree.