Skip to content

chore: sync pstack 0.15.21 and preserve portable invocation gates - #9

Merged
yxhta merged 52 commits into
mainfrom
maintenance/pstack-20261013
Oct 13, 2026
Merged

yxhta merged 52 commits into
mainfrom
maintenance/pstack-20261013

Conversation

@yxhta

@yxhta yxhta commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Merge cursor/plugins at 1dcc2bacde73ddd284803b7af28164d0436198fc (51 commits after the previous pin), keeping upstream source pristine.
  • Preserve ketchup's explicit-only invocation on Claude Code and Codex.
  • Review the plan checker's fenced-code update, refresh its pinned digest, and add portable regressions.
  • Align delegated agent guidance with the parent-chat playbook runner and recognize both comment-sicko names.
  • Regenerate portable packages. Thermos and Claude-only Mods content digests remain unchanged.

Verification

  • 133 portable Python tests passed.
  • 63 upstream Bun tests and strict watch-pr TypeScript checks passed.
  • All repository plugin schemas passed.
  • Skills CLI 1.7.2 installed and verified 54 pstack and 3 Thermos skills for both Claude Code and Codex in isolated projects.
  • Generation/source integrity, shell syntax, and whitespace checks passed.
  • Independent review found no required fixes.

All four checks passed on the published head before the normal merge, including both portable validation runs, plugin schemas, and WIP. PR CI additionally passed native Claude Code 2.1.289 Mods strict validation, tests, generated typecheck, and no-inference loading. Model-turn behavior and GitHub watch-pr E2E remain unverified.

The published commit has exactly the reviewed local Git tree 0e36b749cbf81b5a485a2fa74cc65a4fbd8b973e and preserves both merge parents. Publication used the connected GitHub API because local Git/gh credentials were unavailable.

See maintenance evidence. This supersedes the older upstream snapshot in #8; the sync gate itself is unchanged.

djiang-jq and others added 30 commits October 9, 2026 20:02
- Drop the encrypted-only / "classic DMs are a different product"
  framing: decrypt now returns older unencrypted messages like any
  other message, and replies are still always encrypted.
- Drop the hint that empty `data` with `result_count: 0` can mean an
  empty thread, and the advice to keep `max_results` small.
- Never claim all chats were checked unless every thread was read to
  the end.
- Pull an existing xchat-lite clone so boxes pick up helper fixes.
- decrypt returns unencrypted messages marked `unencrypted`, still
  verifies encrypted events strictly, and marks encrypted messages it
  can't verify `unverified`. Tell the owner about both and name the
  senders in `unverified_senders`.
- Before decrypting, collect every sender across the fetched pages plus
  group members and call get_users_public_keys (up to 100 ids per call,
  all key versions). Pass the entries as returned.
- A page with `result_count: 0` that still has a `next_token` is not an
  empty thread: keep paging until `next_token` is absent, with
  `max_results` of at least 20.
Each message still carries a status. Drop the instruction to flag
unencrypted or unverified messages.
Do not estimate cost or check credits for X Chat calls. Page the inbox
and each relevant thread at max_results 100 until next_token is absent.
Every time the guide secret-requests the Chat PIN, it asks in the same
prompt whether to remember the X Chat key on this computer, with one
sentence that anyone with access to the computer could then read the
owner's X Chats. The default is no: --remember-key is passed only on a
yes, and the question is never asked at any other time.

Session bootstrap runs unlock-check before asking for the PIN. When the
helper reports key_source "saved", the guide uses the saved key, does
not ask for the PIN, and tells the owner that `forget` removes it.
Replace "X Chat is free in Grok Bot." in the guide, pricing reference and changelog.
- Read every conversation and both message request inboxes, not only the
  relevant ones. A request carries its latest events and key events;
  page older ones with get_chat_conversation_events. Do not use
  get_chat_message_request, which marks messages as delivered.
- Use conversation ids exactly as returned instead of rebuilding them.
- Retry a chat 503 with the same pagination_token up to 3 times and never
  treat a thread as complete after one.
- Answer from each message's display text and content, and describe the
  helper's readable text and placeholder rows.
- List get_chat_message_requests with the free X Chat calls.
When a saved key no longer matches and no PIN is stored, unlock-check stops because CHAT_PIN is not set, so the PIN request with the remember question applies.
Keep "X Chat is free for this plugin." and add that X Chat reads (GET /2/chat/*) and public key lookups are free everywhere, in Grok Bot and in Cursor, in the cost section, the X Chat section and the pricing reference.
Those list events are the prefix get_chat_conversation_events returns,
so collect them only when has_more_events is absent.
The plugin name mercury is already owned in the marketplace by Mercury's
own publisher (id 2908, from github.com/mercury/mercury-marketplace). The
duplicate entry here blocks publishing and reindexing cursor/plugins.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…s-fe3c

Read unencrypted X Chat messages in the X MCP guide
The PIN secret-request only has a masked field, so a remember question
inside that card never gets an answer. Send a Yes/No question widget
alongside it and add --remember-key only on a clear Yes.
…question-0c2f

X skill: ask about remembering the Chat key as a separate question
A thread with no conversation key still carries plain DMs, including
recent ones. status is internal metadata: don't mention encryption
status unless the user asks.
Unprompted encryption commentary gets in the way of reading messages.
Plain DMs are normal when a thread has no conversation key. Answer
encryption questions from status.
…atus-quiet-2f0c

X skill: don't surface per-message encryption status
…#570)

Give each /ketchup action item a side-by-side before and after:
screenshots or video when the change is visible, otherwise a table,
diff, or diagram. Make a visual from what the agent already has when
none exists, and say so plainly when it cannot, so it never invents
an artifact. Prefer visuals to dense prose in general.

Bump pstack to 0.15.18.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Remove sections the agent already follows without the text: restated
rules, generic search steps, evidence checklists, and return-format
blocks. Each cut was checked against the skill's behavior before and
after removal, and cuts that changed behavior were kept out.

Touches how, poteto-mode, why, and four principles (encode lessons
in structure, laziness protocol, exhaust the design space, guard the
context window). Bump pstack to 0.15.19.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…rst 100 (cursor#484)

The reviewThreads query requested reviewThreads(first: 100) with no
pageInfo and no cursor, and the reader issued it once. On a PR with more
than 100 review threads every thread past the first page was invisible,
so an unresolved thread beyond page 1 never blocked the readiness
decision and the PR was reported ready with no unresolved threads.

Paginate like the check-rollup query already does for contexts: add
 and pageInfo to the query, return one page from the reader, and
loop in resolveReviewThreads until hasNextPage is false.

Splitting the parser into parseReviewThreadPage and buildReviewThreads
keeps the Bugbot pass count global: it is derived from every thread in
the response, so accumulating raw pages first preserves the existing
count instead of computing it per page.

Fixes cursor#471

Co-authored-by: Yi-111-a <34198240+yi-111-a@users.noreply.github.com>
…r#572)

unslop sets disable-model-invocation: true, so the skill never runs on
its own. "Must always apply." in the description contradicts that, and
agents read it as a command.

Fixes cursor#308

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: João Neves <5117258+jhneves@users.noreply.github.com>
poteto and others added 22 commits October 11, 2026 22:47
… not origin/main (cursor#574)

* fix(pstack): worktree-audit checks MERGED against the default branch

worktree-audit.sh compared every worktree against a literal origin/main,
so in a repo whose default branch is master a merged branch showed
MERGED=no and landed in the review bucket.

Without -b the base is origin/HEAD, then origin/main, then origin/master,
with the choice on stderr. -b|--base <ref> sets it when PRs target another
branch. The fetch targets the chosen base. worktree-audit.sh [repo-path]
keeps working.

Co-authored-by: Helio Pinheiro <3743756+heliowap@users.noreply.github.com>

* fix(pstack): worktree-audit fetches the base before checking it exists

The base-ref check ran before the fetch, so -b origin/release exited 1
with "base ref not found" when that branch was not fetched yet, and the
fetch that would create it never ran. Fetch first, then check.

The fetch uses an explicit refspec. A plain `git fetch origin release`
does not create origin/release in a single-branch clone.

Co-authored-by: lauren <poteto@users.noreply.github.com>

* fix(pstack): worktree-audit handles -h/--help and names the base in the header

Before, -h and --help went to cd. -h/--help now prints the usage block,
an unknown option exits 2, and the table header prints `# base: <ref>`.

Co-authored-by: Helio Pinheiro <3743756+heliowap@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Helio Pinheiro <3743756+heliowap@users.noreply.github.com>
…legate (cursor#575)

poteto-agent described itself as the routing target for /poteto-mode, so
a parent chat could spawn one poteto-agent to run the whole playbook. A
subagent spawned that way is nested and has no Task tool, so it cannot
fan out how, why, Comment Sicko, or code delegates, and its todo list
does not reach the chat.

The chat that receives /poteto-mode now runs the playbook. poteto-agent
is the wrapper for delegates spawned during the run.

Fixes cursor#357

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: dev2o <2152810+dev2o@users.noreply.github.com>
Add a root plugin.json that targets the Agent Plugins 1.0.0 schema, so
clients that read that format can find pstack's skills. The version
matches .cursor-plugin/plugin.json. Cursor keeps reading
.cursor-plugin/plugin.json first.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: mantrakp04 <87142457+mantrakp04@users.noreply.github.com>
…ble (cursor#573)

* fix(pstack): create-verification-skill readiness means the app is usable

A port that answers is not a ready app. One measured case had a database
socket up at 3 s and init done at 19 s, so a generated verification skill
could start driving 16 s early.

- Launch: reach a usable state from an empty data dir, and readiness means
  that state. Drop "a port answering" from the ready examples.
- Step 3: a journey the seed data cannot satisfy reports a failure with the
  reason in that feature's Gotchas instead of being weakened.
- Step 4: setup a stand-in did that the real target will not stays
  unverified until a run on the real target covers it.

Co-authored-by: Sidney VanNess <8864069+sidneyvanness@users.noreply.github.com>

* fix(pstack): plain wording for create-verification-skill readiness rules

Co-authored-by: lauren <poteto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Sidney VanNess <8864069+sidneyvanness@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* Let the X MCP guide work with Grok Bot's built-in public reads

Grok Bot reads public posts, users, search, trends, and news through its own X access, with no X connection and no user credits. The guide now covers those reads in its trigger, and says not to ask the user to connect X, check credits, or estimate a cost for them. get_usage_credits and get_users_me exist only on the user's X connection, so their absence next to built-in reads is not error 2 or an outage.

* Use X Chat's unread state

* X skill: drop the free-credits congrats line

* Teach the X plugin to list, open, and accept Chat message requests.

A reply does not accept a request, and opening one marks it delivered, so those stay separate from scanning both inboxes.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: santiagomed <santiagomed@users.noreply.github.com>
Co-authored-by: Paul Vann <pvann@x.ai>
Co-authored-by: Cursor <cursoragent@cursor.com>
Leaf skills set disable-model-invocation, so an agent never sees their
paths, and poteto-mode names them only by bare name. A spawned
poteto-agent also has no way to locate poteto-mode itself.

poteto-mode now says leaves live at ../<name>/SKILL.md from its own
file and tells the parent to put that file's absolute path in every
poteto-agent prompt. poteto-agent reads poteto-mode from that path.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: sunxiuguo <32354149+sunxiuguo@users.noreply.github.com>
Co-authored-by: darkhan-nace <235999017+darkhan-nace@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
List unread conversations, then page each one's get_chat_conversation_events newest first and stop at the first event at or below last_read_event_id, the seen_until_sequence_id of the owner's latest read receipt; no parameter starts after an event. mark_chat_conversation_read takes only id and always marks the whole conversation read. Marking a conversation unread does not set unread.
…client

docs(workday): document the team API client and required TOKEN_ENDPOINT
get_chat_conversations now takes up to 1000 per page. Fall back to 100 if the API still rejects 1000.
Keep max_results 1000, events at 100 per page, paging past an empty events page with a next_token, and leaving out the owner's own messages. Drop text the live tools and API already cover: mark-read takes only id, unread is computed by the API, events come newest first with unread ones above last_read_event_id, and no parameter starts after an event.
…essages

X skill: exact unread messages, 1000-conversation inbox pages
For what's unread and for reading or summarizing chats, read only inbox conversations and end with one line offering message requests when meta.has_message_requests is true. Message requests are still read in full when the owner asks about them, and searched when a named person isn't in the inbox.
X skill: unread and chat summaries focus on the main inbox
@yxhta
yxhta marked this pull request as ready for review October 13, 2026 14:53
@yxhta
yxhta merged commit 2595adf into main Oct 13, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants