Repository navigation
Bump stv1024/auto-pin to 0.5.2 - #1223
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Auto-Pin 0.5.2 is approved for publication, @stv1024. I refreshed the listing’s screenshot URLs to this version and retained your English and Chinese overviews. Nothing further is needed from you.
Review data
- Reviewed registry head:
06f0ccc8d2ad375a5ba299271672a22709d0b07d. Main REVIEW.md blob:8da1286fd8870c87ff53767e8644858627b7371f. - Independently downloaded and compared npm
paseo-auto-pin0.5.1 and 0.5.2; both tarballs match their records and npm SHA-512/version metadata. Reviewed artifact:https://registry.npmjs.org/paseo-auto-pin/-/paseo-auto-pin-0.5.2.tgz, integritysha512-h8A6deihde7RgTX+4K+8i5Fi8E9/urOSnuPaE9RPgh6iVtFn9uFDu1Qb5DDCBdfi3plNoUJHGtnaMcF2Lo/mJQ==. Checked archive paths/types before extraction. npm-provided provenance names the existing author's repository, tag v0.5.2 and commite66d0c8e613dbee942eea76d22722416c9b8ef29; its subject digest matches this tarball. This was an artifact review, without a source-match gate. - Inspected the independent artifact delta, all ten plugin source modules, manifest/package metadata, both overviews and translation description, lockfile and existing listing media. All plugin TypeScript modules are unchanged after line-ending normalization. The production lock changes zod 4.5.4 to 4.6.7; remaining production pins are unchanged. Downloaded/checksummed all eight production packages against npm and the lock, inspected their manifests and confirmed no installation lifecycle hooks. All lockfile resolved entries use npm HTTPS sources and integrity hashes. No manifest preparation commands or package installation scripts. Dependency internals were not exhaustively audited.
- Purposeful access remains unchanged:
server/lifecycle.ts:10-19applies the saved project rule at workspace creation;server/pin.ts:10-55reads the daemon endpoint from config, sends the created workspace ID withpinned: truethrough the SDK and closes the connection. No credentials are supplied to that client.server/store.ts:7-9,64-82stores its settings under the Paseo home and removes only its temporary settings file. Project names/paths are returned to the connected UI. No subprocess, runtime software installation or unrelated network destination found in plugin source. - The Chinese overview accurately mirrors the English setup, rules, storage and connection limitations. Both use the author's pages. Visually inspected the packaged panel screenshot; current-version PNG URL and other media checks pass. Only registry edits are the review timestamp and two current-version screenshot URLs.
- Trusted main online validation passes for the completed changed record; all 172 registry tests and exact-head GitHub validation pass. No plugin or dependency installed, built, imported or executed; no live UI/pinning QA. Existing migration discussion and the author's 0.5.1 follow-up were read; no linked submission issue exists for this bump.
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.
stv1024/auto-pin: 0.5.1 → 0.5.2
@stv1024, this update is ready for review. The published version stays unchanged until approval.
Artifact and validation details
Package:
paseo-auto-pin.{ "previous": { "kind": "npm", "package": "paseo-auto-pin", "version": "0.5.1", "resolved": "https://registry.npmjs.org/paseo-auto-pin/-/paseo-auto-pin-0.5.1.tgz", "integrity": "sha512-yw9pzEA7rt5nUWWeTX+S/ghPM0415wt6tdVzYUsDg/hQwqITfmXSp98Sq4fw8x2sLCVSW7wi16hpTecEtJneWw==" }, "proposed": { "kind": "npm", "package": "paseo-auto-pin", "version": "0.5.2", "resolved": "https://registry.npmjs.org/paseo-auto-pin/-/paseo-auto-pin-0.5.2.tgz", "integrity": "sha512-h8A6deihde7RgTX+4K+8i5Fi8E9/urOSnuPaE9RPgh6iVtFn9uFDu1Qb5DDCBdfi3plNoUJHGtnaMcF2Lo/mJQ==" } }Inline validation passed: tests and artifact checks. Run
node scripts/validate.ts --online --changedon the completed listing before merging. The default GITHUB_TOKEN does not trigger the PR validation workflow.Artifact diff
The registry can lag behind npm for a few days while each new version is reviewed.
-Paseo 0.9.2 and later have a known sidebar synchronization issue
-that can temporarily hide a newly applied pin.
+Paseo 0.11.x and 0.12.x have a known sidebar synchronization issue
+that can temporarily hide a newly applied pin. Paseo 0.13.0 fixes it.
The Auto-Pin row in the sidebar header shows the default switch. Click the
switch to turn auto-pin on or off. Click the row to open the panel with project
@@ -84,7 +84,7 @@
Updating from 0.3 keeps your existing on/off setting. Every project starts on
Follow default until you choose otherwise.
-Auto-Pin 0.5.1 has been integration-tested with Paseo 0.11.1.
+Auto-Pin 0.5.2 has been integration-tested with Paseo 0.11.1, 0.12.0, and 0.13.0.
Future versions are allowed, but compatibility still depends on Paseo keeping
the APIs this plugin uses. Paseo 0.10 and earlier reject the 0.5 manifest.
For Paseo 0.9.1 to 0.10.x, use Auto-Pin 0.4.2:
@@ -102,11 +102,13 @@
If you just changed a setting on another device, press Refresh in the panel.
If a workspace appears pinned, disappears from Pinned, and returns later on
-Paseo 0.9.2 or later, see the known issue and upstream status.
+Paseo 0.9.2 to 0.12.x, update Paseo to 0.13.0 or later. See the
+known issue and its fix.
The daemon retains the pin; updating or reloading Auto-Pin does not fix this
host issue. The panel's Refresh button only refreshes plugin settings and
projects, so it does not repair the sidebar state.
-Upstream tracking: getpaseo/paseo#5447.
+Upstream fix: getpaseo/paseo#7758,
+for getpaseo/paseo#5447.
For errors or unexpected behavior, open an issue.
Include your Paseo and Auto-Pin versions, the rule you selected, and what happened.
diff -ruN a/package/docs/community.md b/package/docs/community.md
--- a/package/docs/community.md 1985-10-26 08:15:00.000000000 +0000
+++ b/package/docs/community.md 1985-10-26 08:15:00.000000000 +0000
@@ -22,6 +22,9 @@
announced in a discussion comment
on 2026-10-09.
+- Auto-Pin 0.5.1 release
npm-shrinkwrap.jsonand clearsWhere to check feedback
diff -ruN a/package/docs/development.md b/package/docs/development.md
--- a/package/docs/development.md 1985-10-26 08:15:00.000000000 +0000
+++ b/package/docs/development.md 1985-10-26 08:15:00.000000000 +0000
@@ -1,11 +1,11 @@
Developing Auto-Pin
-Auto-Pin 0.5.1 requires Paseo >=0.11.0, with no upper version limit. The
+Auto-Pin 0.5.2 requires Paseo >=0.11.0, with no upper version limit. The
manifest uses
name,icon, andmedia, and the client usesaddScreenandaddSidebarHeaderItem; Paseo 0.10 and earlier reject or lack these. The-integration suite has been verified with Paseo 0.11.1. Later
-stable versions may load without changing the manifest, but this is not a
-guarantee that future Paseo API changes will remain compatible.
+integration suite has been verified with Paseo 0.11.1, 0.12.0, and
+0.13.0. Later stable versions may load without changing the manifest, but
+this is not a guarantee that future Paseo API changes will remain compatible.
Both Paseo SDK dependencies are pinned to 0.11.1 for repeatable builds; these
dependency pins do not restrict the host's version. The host supplies React and
@@ -39,7 +39,24 @@
Publishing on npm
-Run the checks, then prepare a tarball:
+Releases are published by
+
.github/workflows/release.ymlwith npm+Trusted Publishing over GitHub OIDC. No npm token is stored in the
+repository, in GitHub, or on a machine. npm accepts a publish only when the
+repository, the workflow filename, and the tag match the package's trusted
+publisher record on npmjs.com.
+
+Release sequence:
+
+1. Bump
versioninpackage.jsonand add the changelog section.+2. Run the checks and pack the tarball (below).
+3. Commit, push
main, tag the release commit, and push the tag:git tag -a v0.5.2 -m "Auto-Pin 0.5.2" && git push origin v0.5.2.+4. Create the GitHub release from that tag.
+### Checks before a release
@@ -209,5 +234,11 @@
package root beside
paseo-plugin.json, must not contain installation commands,and should be updated whenever plugin behavior changes.
+The manifest's
translationsandOVERVIEW.zh-CN.mdgive the listing in+Simplified Chinese. Only the registry reads them; Paseo ignores both. When
+
OVERVIEW.mdor the manifestdescriptionchanges, update the translation in+the same change.
OVERVIEW.zh-CN.mdis a complete page, not a partial override,+and has the same rules as
OVERVIEW.md.+
When changing the supported Paseo version, recheck the internal pin adapter,
manifest validation, client/server compilation, and the daemon integration.
diff -ruN a/package/docs/paseo-workspace-race.md b/package/docs/paseo-workspace-race.md
--- a/package/docs/paseo-workspace-race.md 1985-10-26 08:15:00.000000000 +0000
+++ b/package/docs/paseo-workspace-race.md 1985-10-26 08:15:00.000000000 +0000
@@ -1,153 +1,234 @@
-# Known issue: new pins temporarily disappear on Paseo 0.9.2
-Auto-Pin can expose a client state race in Paseo 0.9.2: a workspace appears pinned,
-disappears from Pinned, and returns after a later directory update.
-The daemon's saved pin is not removed.
-## Status and user impact
-Upstream report: getpaseo/paseo#5447,
-filed September 26, 2026 with the reproduction script, raw output, and candidate
-patch. Filing the report does not imply that the fix has been accepted or released.
-Confirmed with Auto-Pin 0.4.0 and Paseo 0.9.2 on Windows 11. Paseo 0.9.2
-was still the latest stable release when checked on September 26, 2026.
-No fixed official release has been verified. Other versions have not been
-checked for this specific race; the plugin's supported range is not a claim
-that every host version is free of this issue.
-Update, October 9, 2026: the issue is still open (labeled p3). On September 26
-the Paseo maintainers' bot reproduced it on
mainwithout added delays when the-workspace starts with an initial agent, confirmed the cause, and left the choice
-of fix to the maintainer. Paseo 0.11.1 is the latest stable release and contains
-no fix. Its plugin SDK still has no way to set a pin as part of the creation request.
-The interval before the pin reappears depends on the next directory update or
-resynchronization. Auto-Pin has no timer that removes or reapplies pins. Its
-panel's Refresh button refreshes plugin settings and projects, not the host
-sidebar. Updating or reloading the plugin does not fix this host issue.
-Normal installation continues to use an official Paseo release. The candidate
-patch below is investigation material for maintainers, not an installation
-requirement or a supported custom Paseo distribution.
-## Cause
-Paseo captures a workspace descriptor during creation. While it finishes the
-creation request, Auto-Pin handles
workspace.createdand pins the workspace.-The client receives that live update before the older creation response.
-Both the response and creation progress callbacks feed their snapshots through
-
HostRuntimeController.acceptWorkspaceSnapshots(). The 0.9.2 workspace replica-overwrites its current row with each of these snapshots, including the old
-
pinnedAt: nullvalue.-Relevant source at
v0.9.2:-- Creation response merge
-- Workspace replica snapshot acceptance
-The same unconditional acceptance method was present in main at
-
76a9781ba566ab511ed8ec9b08ebf53425229f39. That was a source inspection; the-runtime reproduction and regression checks below target v0.9.2.
-## Reproduction for maintainers
-The reported desktop sequence is: enable Auto-Pin, create a workspace with an
-initial message, then observe it appear in Pinned, disappear, and return after
-a later workspace update. It is timing-dependent in normal use.
-For a deterministic wire-level reproduction, install a separate runtime and run
-the diagnostic from a checkout of this plugin with its dependencies installed:
-
bash -npm install --prefix /path/to/paseo-test-runtime --no-save --ignore-scripts @getpaseo/[email protected] -node scripts/repro-workspace-race.mjs --runtime /path/to/paseo-test-runtime --The script creates a temporary Paseo home and workspace, binds an automatically
-assigned loopback port, and disables agent providers, relay, MCP, and speech.
-It loads the real plugin, subscribes to workspace updates, and creates a
-workspace. In this test process only, it holds the return of
-
Session.createRequestedWorkspace()until the real pin update arrives. It does-not change the descriptor or stored pin. The original method is restored and
-the test daemon is stopped in
finally; test files and logs remain in the-printed temporary directory. The ordinary Paseo home and daemon are not used.
-Expected evidence is a non-null
livePinnedAtBeforeResponse, a null-
responsePinnedAt, and a matching non-nullrefreshedPinnedAt.-This script proves response ordering and retained server state. It does not
-launch the UI or by itself test the client merge; the regression below exercises
-Paseo's actual workspace replica and session store.
-## Candidate upstream fix
-The source patch targets Paseo
-tag
v0.9.2, commitc67b7158b441bb09026b38d86ae335cc4b49190a.-It is retained in this repository for upstream review and is not applied by
-plugin installation, update, or reload. Paseo source is licensed under Apache-2.0.
-Creation snapshots seed missing workspace rows. Once a row exists, directory
-updates and reconciliation own its state. The replica applies that rule before
-publishing to the session store or returning mutations for the persistent cache.
-It applies to the entire descriptor, so pins, titles, and other live fields do
-not need separate exceptions. Live updates can still pin or unpin a workspace.
-The public snapshot entry point is also used to restore an optimistically hidden
-workspace after an archive failure. A missing row can still be restored; an
-already received row keeps its current state.
-For source-level evaluation only, apply it in a separate Paseo source checkout:
-
bash -git checkout v0.9.2 -git apply --check /path/to/paseo-auto-pin/patches/paseo-0.9.2-workspace-snapshots.patch -git apply /path/to/paseo-auto-pin/patches/paseo-0.9.2-workspace-snapshots.patch --The proposal needs upstream review before it should be treated as a released
-fix. Its validation is scoped to the existing-row overwrite: removal/tombstone
-races and reconnect behavior have not been verified with this candidate.
-## Verification
-The new late-creation-response regression failed on the original Paseo code and
-passed after the change. All nine tests in
workspace-replica.test.tspass,-covering both arrival orders, mixed batches, manual unpinning, and archive
-rollback. The app typecheck and lint for both changed files pass after building
-the workspace dependencies and applying Paseo's normal postinstall patches.
-The source patch passes forward and reverse applicability checks against the
-v0.9.2 checkout. Auto-Pin's 36 tests and typecheck also pass.
-To run the focused host tests from a prepared Paseo checkout:
-
bash -npm run test --workspace=@getpaseo/app -- src/runtime/directory-sync/workspace-replica.test.ts --bail=1 -npm run typecheck --workspace=@getpaseo/app -npm run lint -- packages/app/src/runtime/directory-sync/workspace-replica.ts packages/app/src/runtime/directory-sync/workspace-replica.test.ts --This verifies the source change. A packaged client build and UI smoke test have
-not been performed, and the installed Paseo client has not been patched.
-## Maintenance policy
-Auto-Pin keeps its existing flow: one creation hook, one project-rule decision,
-one pin request. Keep host synchronization fixes in Paseo. Do not add arbitrary
-pin delays, periodic repinning, host monkey patches, or client-store writes to
-the shipped plugin to mask this race; these cannot guarantee response ordering
-and can interfere with manual pin changes. The diagnostic's timing injection
-is isolated test code and is not loaded by either plugin entry point.
-After an official fix is released, verify the released client with the stock
-plugin: initial-message and empty-workspace creation, local checkouts and
-worktrees, both update/response orders, and manual unpinning. Record the first
-verified fixed version and the upstream issue or release link here, then revise
-the README's known-issue notice. Keep the historical reproduction versioned;
-it demonstrates the old wire ordering, which may remain valid even after the
-client merge is fixed. Do not mark the plugin fixed merely because this source
-patch or a proposed upstream change exists.
-The existing integration compromises are documented in
-Paseo integration limits: a small
-internal-client pin adapter and plugin-owned settings persistence, because the
-Paseo 0.9.1 API does not expose those writes. They are independent of this race.
+# Known issue: new pins temporarily disappear on Paseo 0.9.2 to 0.12.x
+
+Auto-Pin can expose a client state race in Paseo 0.9.2 to 0.12.x: a workspace appears pinned,
+disappears from Pinned, and returns after a later directory update.
+The daemon's saved pin is not removed.
+
+Fixed in Paseo 0.13.0. To fix it, update Paseo to 0.13.0 or later. Auto-Pin
+needs no update for this fix. On Paseo 0.11.x and 0.12.x the race remains.
+
+## Status and user impact
+
+Upstream report: getpaseo/paseo#5447,
+filed September 26, 2026 with the reproduction script, raw output, and candidate
+patch. Filing the report does not imply that the fix has been accepted or released.
+
+Confirmed with Auto-Pin 0.4.0 and Paseo 0.9.2 on Windows 11. Paseo 0.9.2
+was still the latest stable release when checked on September 26, 2026.
+No fixed official release has been verified. Other versions have not been
+checked for this specific race; the plugin's supported range is not a claim
+that every host version is free of this issue.
+
+Update, October 9, 2026: the issue is still open (labeled p3). On September 26
+the Paseo maintainers' bot reproduced it on
mainwithout added delays when the+workspace starts with an initial agent, confirmed the cause, and left the choice
+of fix to the maintainer. Paseo 0.11.1 is the latest stable release and contains
+no fix. Its plugin SDK still has no way to set a pin as part of the creation request.
+
+Update, October 24, 2026: the race still reproduces on the released Paseo
+0.12.0 daemon with the diagnostic below.
acceptWorkspaces()is unchanged in+v0.12.0,
main, and v0.13.0-beta.2. The issue is open (p2). The 0.12.0 plugin+SDK changed only ACP code:
PaseoApistill has no pin mutation, and+
workspace.createstill has no pin field. The stock plugin passes the+integration suite on 0.12.0.
+
+Upstream fix proposal: getpaseo/paseo#7758,
+opened October 24, 2026 against
main. It applies the guard described below and+adds four replica unit tests and a browser E2E test. The E2E test creates a
+workspace with a prompt, pins it while the creation response is held, and counts
+frames in which the row is missing from Pinned. On unchanged
mainit failed in+3 of 3 runs (32 to 34 missing frames); with the change it passed in 4 of 4 runs.
+An open pull request is not a released fix.
+
+Update, October 26, 2026: fixed in Paseo 0.13.0. Paseo merged #7758 on
+October 24, 2026, which closed #5447, and released it the same day in
+Paseo 0.13.0
+(merge commit
632a7f885958f318ee9e0619b3af075d4798bf55; 0.13.0-beta.2 and+earlier do not contain it). In 0.13.0,
acceptWorkspaces()only seeds rows that+are missing. The daemon still sends the old creation response after the live pin
+update, but the app no longer applies it. Paseo 0.13.0 is the first verified
+fixed version: the stock plugin passed the
+released-client check below.
+
+The interval before the pin reappears depends on the next directory update or
+resynchronization. Auto-Pin has no timer that removes or reapplies pins. Its
+panel's Refresh button refreshes plugin settings and projects, not the host
+sidebar. Updating or reloading the plugin does not fix this host issue.
+
+Normal installation continues to use an official Paseo release. The candidate
+patch below is investigation material for maintainers, not an installation
+requirement or a supported custom Paseo distribution.
+
+## Cause
+
+Paseo captures a workspace descriptor during creation. While it finishes the
+creation request, Auto-Pin handles
workspace.createdand pins the workspace.+The client receives that live update before the older creation response.
+Both the response and creation progress callbacks feed their snapshots through
+
HostRuntimeController.acceptWorkspaceSnapshots(). The 0.9.2 workspace replica+overwrites its current row with each of these snapshots, including the old
+
pinnedAt: nullvalue.+
+Relevant source at
v0.9.2:+
+- Creation response merge
+- Workspace replica snapshot acceptance
+
+The same unconditional acceptance method was present in main at
+
76a9781ba566ab511ed8ec9b08ebf53425229f39. That was a source inspection; the+runtime reproduction and regression checks below target v0.9.2.
+
+## Reproduction for maintainers
+
+The reported desktop sequence is: enable Auto-Pin, create a workspace with an
+initial message, then observe it appear in Pinned, disappear, and return after
+a later workspace update. It is timing-dependent in normal use.
+
+For a deterministic wire-level reproduction, install a separate runtime and run
+the diagnostic from a checkout of this plugin with its dependencies installed:
+
+
bash +npm install --prefix /path/to/paseo-test-runtime --no-save --ignore-scripts @getpaseo/[email protected] +node scripts/repro-workspace-race.mjs --runtime /path/to/paseo-test-runtime ++
+The script accepts any installed Paseo version and prints it; replace
0.9.2+to check another release. The wire ordering was last confirmed on 0.13.0, where
+the app no longer applies the old response.
+
+The script creates a temporary Paseo home and workspace, binds an automatically
+assigned loopback port, and disables agent providers, relay, MCP, and speech.
+It loads the real plugin, subscribes to workspace updates, and creates a
+workspace. In this test process only, it holds the return of
+
Session.createRequestedWorkspace()until the real pin update arrives. It does+not change the descriptor or stored pin. The original method is restored and
+the test daemon is stopped in
finally; test files and logs remain in the+printed temporary directory. The ordinary Paseo home and daemon are not used.
+
+Expected evidence is a non-null
livePinnedAtBeforeResponse, a null+
responsePinnedAt, and a matching non-nullrefreshedPinnedAt.+This script proves response ordering and retained server state. It does not
+launch the UI or by itself test the client merge; the regression below exercises
+Paseo's actual workspace replica and session store.
+
+Add
--uito test the client merge in the app. The script then keeps the test+daemon and its bundled web app running, creates a Git project, and prints the
+app URL. It also enables Paseo's development-only mock agent provider, so the
+app can start a workspace with an initial message without a real provider.
+Every workspace that the app creates returns only after its pin update arrives
+(10-second limit). Add
--no-holdas well to let creation responses return+without delay. The script prints each pin, unpin, and held response. Press
+Enter to stop it.
+
+## Candidate upstream fix
+
+The source patch targets Paseo
+tag
v0.9.2, commitc67b7158b441bb09026b38d86ae335cc4b49190a.+It is retained in this repository for upstream review and is not applied by
+plugin installation, update, or reload. Paseo source is licensed under Apache-2.0.
+
+Creation snapshots seed missing workspace rows. Once a row exists, directory
+updates and reconciliation own its state. The replica applies that rule before
+publishing to the session store or returning mutations for the persistent cache.
+It applies to the entire descriptor, so pins, titles, and other live fields do
+not need separate exceptions. Live updates can still pin or unpin a workspace.
+
+The public snapshot entry point is also used to restore an optimistically hidden
+workspace after an archive failure. A missing row can still be restored; an
+already received row keeps its current state.
+
+For source-level evaluation only, apply it in a separate Paseo source checkout:
+
+
bash +git checkout v0.9.2 +git apply --check /path/to/paseo-auto-pin/patches/paseo-0.9.2-workspace-snapshots.patch +git apply /path/to/paseo-auto-pin/patches/paseo-0.9.2-workspace-snapshots.patch ++
+The proposal needs upstream review before it should be treated as a released
+fix. Its validation is scoped to the existing-row overwrite: removal/tombstone
+races and reconnect behavior have not been verified with this candidate.
+
+## Verification
+
+### Released fix (Paseo 0.13.0)
+
+Checked on October 26, 2026 on Windows 11 with the released Paseo 0.13.0
+daemon and web app and the stock plugin (the code in Auto-Pin 0.5.1 and 0.5.2). The diagnostic
+ran with
--ui. A headless Chrome, driven by Playwright from outside this+repository, used the app's New workspace screen to create workspaces:
+
+- with an initial message (mock agent) and empty;
+- as a local checkout and as a new worktree.
+
+For each workspace, the browser sampled every animation frame from Create
+until 3 seconds after the workspace opened. It counted the frames in which the
+new row was missing from Pinned after it first appeared there, as Paseo's own
+E2E test does. It also recorded the workspace messages that the app received.
+
+| Arrival order | Scenario | Paseo 0.13.0 | Paseo 0.12.0 (control) |
+| --- | --- | --- | --- |
+| Held: pin, then old response | Initial message, local | 0 frames (2 runs) | 171 frames; still missing at the end |
+| Held: pin, then old response | Initial message, worktree | 0 frames (2 runs) | not run |
+| Held: pin, then old response | Empty, local | 0 frames (3 runs) | 183 frames; still missing at the end |
+| Held: pin, then old response | Empty, worktree | 0 frames (2 runs) | 34 frames; back after a later update |
+| Not held: pin first | Initial message, local and worktree | 0 frames | not run |
+| Not held: response first | Empty, local | 0 frames | not run |
+| Not held: pin first | Empty, worktree | 0 frames | not run |
+
+In every held run, the app received the creation response with
+
pinnedAt: nullafter the pinned update, so each run reproduced the race on+the wire. With an initial message, the pin also arrived first without the
+hold, because the response waits for the agent to start. Every 0.13.0 row was
+still in Pinned at the end.
+
+Manual unpinning from the row menu also passed in both held runs. The row left
+Pinned in the next frame and stayed listed and unpinned, and the daemon
+recorded no new pin in the next 4 seconds.
+
+This check did not cover real agent providers, the desktop and mobile apps,
+reconnects, or archive and restore. The upstream E2E test and review covered
+the replica change with an agent.
+
+### Candidate patch (Paseo 0.9.2)
+
+The new late-creation-response regression failed on the original Paseo code and
+passed after the change. All nine tests in
workspace-replica.test.tspass,+covering both arrival orders, mixed batches, manual unpinning, and archive
+rollback. The app typecheck and lint for both changed files pass after building
+the workspace dependencies and applying Paseo's normal postinstall patches.
+The source patch passes forward and reverse applicability checks against the
+v0.9.2 checkout. Auto-Pin's 36 tests and typecheck also pass.
+
+To run the focused host tests from a prepared Paseo checkout:
+
+
bash +npm run test --workspace=@getpaseo/app -- src/runtime/directory-sync/workspace-replica.test.ts --bail=1 +npm run typecheck --workspace=@getpaseo/app +npm run lint -- packages/app/src/runtime/directory-sync/workspace-replica.ts packages/app/src/runtime/directory-sync/workspace-replica.test.ts ++
+This verifies the source change. A packaged client build and UI smoke test have
+not been performed, and the installed Paseo client has not been patched.
+
+## Maintenance policy
+
+Auto-Pin keeps its existing flow: one creation hook, one project-rule decision,
+one pin request. Keep host synchronization fixes in Paseo. Do not add arbitrary
+pin delays, periodic repinning, host monkey patches, or client-store writes to
+the shipped plugin to mask this race; these cannot guarantee response ordering
+and can interfere with manual pin changes. The diagnostic's timing injection
+is isolated test code and is not loaded by either plugin entry point.
+
+Paseo 0.13.0 is the first verified fixed version (see
+Released fix). The plugin still supports Paseo
+0.11.x and 0.12.x, where the race remains; tell users there to update Paseo.
+Keep the historical reproduction versioned: it shows the old wire ordering,
+which is still sent in 0.13.0. If a later Paseo release changes the creation
+flow or the workspace replica, run the
--uicheck again.+
+The existing integration compromises are documented in
+Paseo integration limits: a small
+internal-client pin adapter and plugin-owned settings persistence, because the
+Paseo plugin API (still in 0.13.0) does not expose those writes. They are
+independent of this race.
diff -ruN a/package/index.server.ts b/package/index.server.ts
--- a/package/index.server.ts 1985-10-26 08:15:00.000000000 +0000
+++ b/package/index.server.ts 1985-10-26 08:15:00.000000000 +0000
@@ -1,12 +1,12 @@
-import type { PluginServerContext } from "@getpaseo/plugin/server";
+import type { PluginServerContext } from "@getpaseo/plugin/server";
import { autopinEnsure, autopinProjects, autopinSetProjectRule, autopinToggle } from "./shared/contracts";
import { handleEnsure, handleProjects, handleSetProjectRule, handleToggle } from "./server/handlers";
-import { registerAutoPin } from "./server/lifecycle";
-export default function contribute(server: PluginServerContext) {
+import { registerAutoPin } from "./server/lifecycle";
+export default function contribute(server: PluginServerContext) {
server.handle(autopinToggle, handleToggle);
server.handle(autopinProjects, handleProjects);
server.handle(autopinSetProjectRule, handleSetProjectRule);
-}
+}
diff -ruN a/package/npm-shrinkwrap.json b/package/npm-shrinkwrap.json
--- a/package/npm-shrinkwrap.json 1985-10-26 08:15:00.000000000 +0000
+++ b/package/npm-shrinkwrap.json 1985-10-26 08:15:00.000000000 +0000
@@ -1,12 +1,12 @@
{
"name": "paseo-auto-pin",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "paseo-auto-pin",
@@ -5193,9 +5193,9 @@
}
},
"node_modules/zod": {
diff -ruN a/package/package.json b/package/package.json
--- a/package/package.json 1985-10-26 08:15:00.000000000 +0000
+++ b/package/package.json 1985-10-26 08:15:00.000000000 +0000
@@ -1,6 +1,6 @@
{
"name": "paseo-auto-pin",
"description": "Automatically pin new Paseo workspaces, with defaults and rules for individual projects.",
"license": "MIT",
"author": "stv1024",
@@ -18,6 +18,7 @@
"paseo-plugin.json",
"npm-shrinkwrap.json",
"OVERVIEW.md",
"assets/",
"index.client.tsx",
"index.server.ts",
diff -ruN a/package/paseo-plugin.json b/package/paseo-plugin.json
--- a/package/paseo-plugin.json 1985-10-26 08:15:00.000000000 +0000
+++ b/package/paseo-plugin.json 1985-10-26 08:15:00.000000000 +0000
@@ -9,6 +9,11 @@
"docs/demo.gif",
"https://github.com/stv1024/paseo-auto-pin/releases/download/v0.4.0/auto-pin-promo.mp4"
],
"requirements": {
"paseo": ">=0.11.0"
}
diff -ruN a/package/server/handlers.ts b/package/server/handlers.ts
--- a/package/server/handlers.ts 1985-10-26 08:15:00.000000000 +0000
+++ b/package/server/handlers.ts 1985-10-26 08:15:00.000000000 +0000
@@ -1,13 +1,13 @@
import type { PluginHandlerContext } from "@getpaseo/plugin/server";
import type { ProjectRule } from "../shared/contracts";
import { getConfig, setProjectRule, toggleEnabled } from "./store";
-import { isRunning } from "./lifecycle";
-export async function handleEnsure() {
+import { isRunning } from "./lifecycle";
+
+export async function handleEnsure() {
return { running: isRunning(), ...await getConfig() };
-}
-export async function handleToggle() {
+}
+
+export async function handleToggle() {
const config = await toggleEnabled();
console.log(
[auto-pin] default ${config.enabled ? "on" : "off"});return { running: isRunning(), ...config };
diff -ruN a/package/server/lifecycle.ts b/package/server/lifecycle.ts
--- a/package/server/lifecycle.ts 1985-10-26 08:15:00.000000000 +0000
+++ b/package/server/lifecycle.ts 1985-10-26 08:15:00.000000000 +0000
@@ -1,25 +1,25 @@
-import type { PluginServerContext } from "@getpaseo/plugin/server";
+import type { PluginServerContext } from "@getpaseo/plugin/server";
import { shouldPinProject } from "./store";
-import { pinWorkspace } from "./pin";
-let running = false;
-export function isRunning(): boolean { return running; }
-export function registerAutoPin(server: PluginServerContext) {
+import { pinWorkspace } from "./pin";
+let running = false;
+export function isRunning(): boolean { return running; }
+
+export function registerAutoPin(server: PluginServerContext) {
if (signal.aborted || workspace.archivedAt || !(await shouldPinProject(workspace.projectId))) return;
await pinWorkspace(workspace.id, signal);
if (signal.aborted) return;
if (signal.aborted) return;
-}
+}
diff -ruN a/package/server/pin.ts b/package/server/pin.ts
--- a/package/server/pin.ts 1985-10-26 08:15:00.000000000 +0000
+++ b/package/server/pin.ts 1985-10-26 08:15:00.000000000 +0000
@@ -1,19 +1,19 @@
-import { readFile } from "node:fs/promises";
-import { join } from "node:path";
-import { DaemonClient } from "@getpaseo/client/internal/daemon-client";
-import { PASEO_HOME } from "./store";
-const CONFIG_FILE = join(PASEO_HOME, "config.json");
-/** The injected PaseoApi exposes no pin mutation, so pinning goes through a
+import { readFile } from "node:fs/promises";
+import { join } from "node:path";
+import { DaemonClient } from "@getpaseo/client/internal/daemon-client";
+import { PASEO_HOME } from "./store";
+const CONFIG_FILE = join(PASEO_HOME, "config.json");
+
+/** The injected PaseoApi exposes no pin mutation, so pinning goes through a
export async function pinWorkspace(workspaceId: string, signal: AbortSignal): Promise {
signal.throwIfAborted();
const url = await daemonWsUrl();
signal.throwIfAborted();
const client = new DaemonClient({
url,
plugin-auto-pin-${process.pid},plugin-auto-pin-${process.pid},clientType: "cli",
connectTimeoutMs: 5_000,
reconnect: { enabled: false },
@@ -37,18 +37,18 @@
} finally {
signal.removeEventListener("abort", onAbort);
await client.close();
-}
-async function daemonWsUrl(): Promise {
ws://${listen}/ws;-}
+}
+async function daemonWsUrl(): Promise {
ws://${listen}/ws;+}
diff -ruN a/package/shared/contracts.ts b/package/shared/contracts.ts
--- a/package/shared/contracts.ts 1985-10-26 08:15:00.000000000 +0000
+++ b/package/shared/contracts.ts 1985-10-26 08:15:00.000000000 +0000
@@ -1,6 +1,6 @@
-import { defineRpc } from "@getpaseo/plugin";
-import { z } from "zod";
+import { defineRpc } from "@getpaseo/plugin";
+import { z } from "zod";
+
export const projectRuleSchema = z.enum(["default", "always", "never"]);
export type ProjectRule = z.infer;
export type ProjectRules = Record<string, Exclude<ProjectRule, "default">>;
@@ -18,15 +18,15 @@
/** The legacy name is retained for existing clients. This only reads status. */
export const autopinEnsure = defineRpc({
output: stateSchema,
-});
+});
+
/** Flips the default. Explicit project rules still take precedence. */
-export const autopinToggle = defineRpc({
+export const autopinToggle = defineRpc({
output: stateSchema,
});