Skip to content

Fix Commander emoji paste recovery and picker overflow - #662

Open
lopugit wants to merge 17 commits into
mainfrom
codex/commander-emoji-paste-recovery
Open

Fix Commander emoji paste recovery and picker overflow#662
lopugit wants to merge 17 commits into
mainfrom
codex/commander-emoji-paste-recovery

Conversation

@lopugit

@lopugit lopugit commented Sep 5, 2026

Copy link
Copy Markdown
Owner

✅ Develop S3 preview ready

The alias passed the develop bucket CORS preflight and a final live PR/SHA fence.

Generic Vercel Preview deployments use the shared development runtime; this controller adds the stable exact-SHA alias and marker-scoped cleanup.

Denied emoji paste stretched the picker content beyond its fixed native window and reordered recents despite inserting nothing. Constrain the emoji grid to its available width, keep failed paste attempts out of recents/learning, serialize pending actions, and show readable Accessibility recovery and explicit Copy Emoji controls.

The native keep-clipboard path now checks trust and target availability before touching the pasteboard. The observed enabled-but-denied grant belongs to the earlier Apple Development signature while the installed app uses Developer ID; macOS explicitly logged a code-requirement mismatch. Preserve the current signing identity and refresh only Commander's existing grant with the user's approval.

Validation: 205 TypeScript/JavaScript tests, 68 Rust tests and 28 Swift tests passed; full typecheck and builds passed. The final retry-feedback adjustment passed all eight focused emoji tests and the UI typecheck/build again.

The installed build uses source revision be86c3c6fab59898e28473d4bc79df1e41a9d630; the final PR commit adds only investigation notes and Graphify outputs. The bundle is Developer ID signed, notarized, stapled and verified, with its designated requirement unchanged across rebuilds. One installed host and its healthy daemon are running. Native visual checks cover normal and minimum window sizes, denied-paste feedback, the Actions menu and scrolling to the end of the results. Chrome rejected the local QA page under its URL policy; no workaround was attempted.

Successful-paste acceptance remains pending the user's Touch ID authentication for the explicitly approved Commander Accessibility grant refresh. System Settings still displays that authentication prompt; no other app's permissions have been changed. This is a local permission migration, not a CI or code-signing failure.

Graphify structural and semantic refresh completed through the local proxy, including portable outputs. Existing cross-source semantic identifier collisions are documented in the investigation note. No Vercel preview was published: preview authorization/publish checks are skipped for this native-app change.

@lopugit

lopugit commented Sep 5, 2026

Copy link
Copy Markdown
Owner Author

✅ Develop S3 preview ready

The alias passed the develop bucket CORS preflight and a final live PR/SHA fence.

Generic Vercel Preview deployments use the shared development runtime; this controller adds the stable exact-SHA alias and marker-scoped cleanup.

@lopugit lopugit added the preview: develop building tt-preview-state:v1:develop:building label Sep 5, 2026
@lopugit
lopugit temporarily deployed to develop-pr-662 September 5, 2026 13:54 Destroyed
@lopugit lopugit added last preview built 08/09 00:21 AEST #662 tt-pv1:662:develop:8a8524839353c43fe6d2abfe5bd03ccb9b429595:1788790879247 preview: develop ready tt-preview-state:v1:develop:ready and removed preview: develop building tt-preview-state:v1:develop:building labels Sep 5, 2026
@lopugit lopugit added preview: develop building tt-preview-state:v1:develop:building and removed preview: develop ready tt-preview-state:v1:develop:ready labels Sep 5, 2026
@lopugit
lopugit temporarily deployed to develop-pr-662 September 5, 2026 13:59 Destroyed
@github-actions github-actions Bot added lopu: mergeable The PR branches can currently be merged without conflicts lopu: overlapping files This PR changes files also changed by another open PR labels Sep 5, 2026
@lopugit lopugit added preview: develop ready tt-preview-state:v1:develop:ready and removed preview: develop building tt-preview-state:v1:develop:building labels Sep 5, 2026
@lopugit lopugit added preview: develop building tt-preview-state:v1:develop:building and removed preview: develop ready tt-preview-state:v1:develop:ready labels Sep 5, 2026
@lopugit
lopugit temporarily deployed to develop-pr-662 September 5, 2026 14:09 Destroyed
@github-actions github-actions Bot removed the lopu: overlapping files This PR changes files also changed by another open PR label Sep 5, 2026
@lopugit lopugit added preview: develop ready tt-preview-state:v1:develop:ready and removed preview: develop building tt-preview-state:v1:develop:building labels Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Lopu review — PR #662 (head d4ce0ed vs main @ e30df5d)

Reviewed and looks good. No changes made; none were justified.

The UNSTABLE state is not a defect in this PR

I enumerated every non-success check run on this exact head. All of them are cancelled control-plane jobs from three superseded pull_request_target runs — 33970880593, 33970890077, 33970991365 — all on the same head SHA, plus one job still in flight. That is a concurrency group doing its job. The substantive checks on this head pass: CodeQL, Analyze (actions), and the headless API suite. No repair needed here or in the controller.

CodeQL has zero open alerts on this head, so nothing to fix or dispose.

On the clipboard fix

This is the right fix for the right reason. The old paste() ran clearContents() + setString() before checking AXIsProcessTrusted(), then called restore() on the denied path — but restoring a value does not un-observe it. Two changeCount bumps had already fired and clipboard managers had already durably captured the emoji. Returning early before touching the pasteboard is the only ordering that actually holds the "your clipboard is unchanged" promise, and asserting on changeCount equality is exactly the right regression assertion.

On the CSS specificity, which I checked against the native side

.launcher-shell:has(> .emoji-picker-panel) is (0,2,0), so it beats the max-width: 720px 8px rule at (0,1,0) regardless of source order — that is the intended fix, since standard mode's 520px minimum width sits inside that media query under an 18px mask.

It also loses to :root[data-window-mode='compact'] .launcher-shell { padding: 12px } at (0,3,0). I checked whether that was a gap and it is not: setWindowMode computes surfaceInset = mode == .compact ? 12 : 18, so the 12px CSS matches compact's 12px native mask. Both modes land aligned. Worth stating explicitly since the compact case is easy to read as an oversight.

One follow-up, deliberately not folded into this PR

The generic non-emoji launcher still takes padding: 8px under @media (max-width: 720px) while standard mode's native mask inset stays 18px — the same defect class you just fixed, still present for the launcher, calculator and settings surfaces. Scoping the :has() selector to the emoji panel was the right call here; widening it without native visual verification could regress those other surfaces. Suggest a separate PR.

Minor, and I left it alone on purpose: the catch in runAction does not reset requiresAccessibility, so a throwing "Copy Emoji" retry keeps the Accessibility explanation under an unrelated error. Accessibility genuinely is still denied in that state and the retry button stays useful, so the current behavior is defensible rather than wrong.

Validation I ran in the PR worktree

Command Result
pnpm build:protocol exit 0
tsc --noEmit (desktop-ui) exit 0
vitest run EmojiPicker.test.tsx 8/8 passed
vitest run (full desktop-ui) 13 files, 79/79 passed

The XCTest target could not run here — Linux runner, no macOS/AppKit — so testDeniedEmojiPasteDoesNotTouchTheClipboard was reviewed by reading. Its assertions match the implementation.

Posted by Lopu, Thingtime's automated reviewer.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Lopu repository review

Lopu reviewed this PR against main as Thingtime's principal PR and repository manager. Using Claude Opus 5.

Lopu found no justified local change to publish from this review pass.

The model did not leave a detailed report; inspect this workflow run for the Lopu session log.

View Lopu workflow run

github-actions Bot added a commit that referenced this pull request Sep 5, 2026
…erflow

# Conflicts:
#	graphify-out/snapshots/v1/379189ef7046444518f6310ae62a404aa898fec3734db662fa60500f0966f65b/3446d7e121b850cb95583c7389f3de3fd6c4af453a50e0f175fbddc78d750595/cost.json
#	graphify-out/snapshots/v1/379189ef7046444518f6310ae62a404aa898fec3734db662fa60500f0966f65b/3446d7e121b850cb95583c7389f3de3fd6c4af453a50e0f175fbddc78d750595/graph.json
#	graphify-out/snapshots/v1/379189ef7046444518f6310ae62a404aa898fec3734db662fa60500f0966f65b/3446d7e121b850cb95583c7389f3de3fd6c4af453a50e0f175fbddc78d750595/manifest.json
#	graphify-out/snapshots/v1/904fc6c923923593a0ea65afcb9a357a9c7d4e1f2ee8da0d2d7b2c8cab5ab3fb/934fb6de6ec193ed6fc549e581df7491ea5ac02df80feda512b7f6df509d28e0/GRAPH_REPORT.md
#	graphify-out/snapshots/v1/904fc6c923923593a0ea65afcb9a357a9c7d4e1f2ee8da0d2d7b2c8cab5ab3fb/934fb6de6ec193ed6fc549e581df7491ea5ac02df80feda512b7f6df509d28e0/cost.json
#	graphify-out/snapshots/v1/904fc6c923923593a0ea65afcb9a357a9c7d4e1f2ee8da0d2d7b2c8cab5ab3fb/934fb6de6ec193ed6fc549e581df7491ea5ac02df80feda512b7f6df509d28e0/graph.json
#	graphify-out/snapshots/v1/904fc6c923923593a0ea65afcb9a357a9c7d4e1f2ee8da0d2d7b2c8cab5ab3fb/934fb6de6ec193ed6fc549e581df7491ea5ac02df80feda512b7f6df509d28e0/manifest.json
#	graphify-out/snapshots/v1/93216e139922f2f954f718126c932b27440b938e67a1d66488ee48b42ed07673/d4d6ba275f3d6291636692f4746135f022cea15aa777ae520d6dc2ee0ab75b53/cost.json
#	graphify-out/snapshots/v1/93216e139922f2f954f718126c932b27440b938e67a1d66488ee48b42ed07673/d4d6ba275f3d6291636692f4746135f022cea15aa777ae520d6dc2ee0ab75b53/graph.json
#	graphify-out/snapshots/v1/93216e139922f2f954f718126c932b27440b938e67a1d66488ee48b42ed07673/d4d6ba275f3d6291636692f4746135f022cea15aa777ae520d6dc2ee0ab75b53/manifest.json
@lopugit
lopugit temporarily deployed to develop-pr-662 September 5, 2026 15:15 Destroyed
@github-actions github-actions Bot removed the lopu: resolving Lopu is actively managing this PR branch label Sep 6, 2026
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Lopu review — PR #662 (head bbbb6303 vs main @ 6ad5ef21)

No failing checks: build + typecheck ratchet + unit tests, the API suite, CodeQL and GitGuardian all pass, and the trusted CodeQL snapshot for this head is empty, so there are no alerts to fix or dispose.

What holds up

I checked the CSS fix against the native mask rather than the description. CommanderWebView.launcherSurfaceInset is 18 and setWindowMode uses mode == .compact ? 12 : 18, so the base .launcher-shell padding and the compact override already mirror the mask — the @media (max-width: 720px) 8px rule is what breaks it once a standard-mode window is dragged below 720px (standard minimum width is 520px). The new :has() rule is specificity (0,2,0): it beats the media rule's (0,1,0) regardless of source order, and correctly loses to the compact rule's (0,3,0), so compact mode keeps its matching 12px. Both modes end up aligned.

The native clipboard guard is right for the reason the comment gives — clipboard observers latch on changeCount movement, so restore-after-write really did leak the emoji. The new early return is exactly equivalent to the two guards it front-runs, so no path changed meaning, and paste-and-copy keeps its useful untrusted fallback. Injecting isAccessibilityTrusted to assert the change count directly is a good call.

One thing worth calling out that the description undersells: recordSuccess() sets learnedSelectionID.current unconditionally, where learn() only did so for a non-empty query. That closes a second, quieter bug where an empty-query action reordered recents and left selectedIndex pointing at a different emoji.

One fix applied

Return could not activate the new recovery buttons. The window-level keydown handler cancels Enter unconditionally:

if (event.key === 'Enter' && selected) { event.preventDefault(); void runAction(defaultAction); }

It listens on window during bubble, so its preventDefault() runs before the browser performs a focused button's activation behaviour and suppresses the synthesized click. A keyboard user who tabbed to Copy Emoji or Open Accessibility Settings and pressed Return would not activate it — they would silently re-run the paste that had just been denied. That inverts the intent of the feature, and it lands on exactly the users most likely to be recovering an Accessibility grant by keyboard.

I let a focused recovery control keep its native Return, scoped to unmodified Enter inside .emoji-recovery-actions only, so Escape, ⌘↵ and ⇧⌘C still reach the picker and no pre-existing control changes behaviour. Added a regression test for it.

Validation: 9 emoji tests pass (8 existing + 1 new); full @commander/desktop-ui suite 81 passed across 13 files; tsc --noEmit clean; prettier --check clean. As a negative control I reverted just the source guard and re-ran — the new test fails, then passes again with it restored, so it pins the behaviour rather than passing vacuously.

Notes, no change requested

  • Pre-existing and out of scope: that same 8px media rule still misaligns the generic launcher against its 18px mask below 720px in standard mode. This PR correctly fixed only the surface it was about; a follow-up could hoist the rule to match the mask everywhere.
  • .launcher-shell:has(> .emoji-picker-panel) is the first :has() in app.css. Fine for a WKWebView-only target, worth knowing if this stylesheet is ever reused more widely.
  • The catch path leaves requiresAccessibility set, so an unrelated later error can render under the Accessibility help text. Cosmetic, and the guidance stays accurate while the grant is missing.

The diagnosis behind this PR is aimed at causes rather than symptoms, and with the Return fix the recovery path now works by keyboard as well as by pointer. No further blocking concerns from me.

— Lopu

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

🤖 Lopu review — PR #662 (head 52adf17c)

I compared the full head 52adf17c against main @ 6ad5ef21 in an isolated worktree, read the surrounding EmojiPicker / LauncherPanelController architecture, the clipboard.paste protocol contract and every other caller of it, and reproduced the validation locally.

Verdict: no changes needed. I made no edits to this branch.

Check state

All substantive checks on this head are green — Build + typecheck ratchet + unit tests, API suite (headless /tests runner), CodeQL, GitGuardian, Find merge-conflicting PRs, Comment product contract advisories. The large number of skipping rows are the control plane's conditional job placeholders, not failures. There is no failing, cancelled or timed-out check to diagnose on this head.

CodeQL: zero open alerts on this exact head, so the disposition file stays []. Nothing was dismissed.

What I verified locally

Check Result
vitest run src/components/EmojiPicker.test.tsx 9/9 passed
vitest run (full @commander/desktop-ui) 81/81 passed, 13 files
tsc -p tsconfig.json --noEmit clean
vite build succeeded

Swift tests are macOS-only and could not run on this Linux runner; I reviewed testDeniedEmojiPasteDoesNotTouchTheClipboard by hand instead — the injected isAccessibilityTrusted: seam, the argument order against the defaulted pinned:/pinningEnabled: parameters, and the changeCount assertion are all correct, and shutdown() exists.

Why the fix is sound

The native change is the important one, and it is right. Previously the keep-clipboard path snapshotted, cleared and wrote the pasteboard before checking AXIsProcessTrusted(), then restored on failure. Restoration does not undo the write from a clipboard observer's point of view, and it bumps changeCount twice. Hoisting trusted and returning early for preserveClipboard when untrusted, target-less, or target-terminated means a denied keep-clipboard paste now touches the pasteboard exactly zero times. I traced every branch of the rewritten paste(_:preserveClipboard:) and each one still produces a coherent (copied, pasted, requiresAccessibility) triple:

  • untrusted + paste-and-copy still deliberately falls through, writes the clipboard, and reports copied: true, pasted: false, requiresAccessibility: true — correct, because the copy half genuinely succeeded;
  • requiresAccessibility now defaults to !trusted rather than false, which is strictly more accurate and does not contradict the later explicit assignment;
  • if preserveClipboard, !trusted || pasteTarget == nil || pasteTarget?.isTerminated == true parses as intended, and the pasteTarget == nil clause makes the optional-chained comparison unambiguous.

NativePasteResult is unchanged and EmojiPicker.tsx is its only consumer, so there is no API-compatibility exposure. The application.open recovery URL passes the bridge's validator: x-apple.systempreferences is a legal RFC 3986 scheme (. is permitted), so URL(string:) yields a non-nil scheme and the file-path fallback is never taken. The value is a hardcoded constant, so it adds no new attack surface beyond what ExtensionsSettings/AccountSettings already pass through that same method.

On the UI side, moving remember/learn behind an explicit recordSuccess() is the correct shape: a rejected paste no longer mutates recents or learned ranking. The one intentional exception — if (result.copied && !preserveClipboard) recordSuccess() — is right, since for paste-and-copy the copy really did happen. The interleaved setStatus(null) inside recordSuccess() followed by the real setStatus(...) is safe: React 19 batches these even after an await, so the later value always wins. learnedSelectionID is set before remember/learn so the selection-restore effect reliably re-finds the emoji after the grid reorders.

On the CSS, grid-template-columns: minmax(0, 1fr) plus the min-width: 0 chain is the correct fix for the reported overflow — the implicit auto column was previously sized by the footer's min-content width. One specificity detail I checked because the comment doesn't mention it: .launcher-shell:has(> .emoji-picker-panel) is (0,2,0), so it beats the @media (max-width: 720px) rule's (0,1,0) regardless of source order, but it is correctly still lost to :root[data-window-mode='compact'] .launcher-shell at (0,3,0). Compact mode therefore keeps its deliberate 12px inset instead of being forced to 18px. That is the behaviour you want; it just isn't obvious from the comment.

The new tests are genuinely good — the changeCount assertion, the in-flight serialization test with a deferred promise, and the "denied double clicks don't reorder the unfiltered grid" test all pin the actual regressions rather than the implementation.

One non-blocking observation

Not worth a commit on your branch, and I have not changed it — but recording it since I verified it rather than guessed it.

When Accessibility is denied, a keyboard user tabs to Copy Emoji and presses Return. recordSuccess() sets requiresAccessibility to false, which unmounts .emoji-recovery-actions — including the button that currently holds focus. I confirmed with a throwaway probe (run, then deleted; the worktree is clean) that document.activeElement becomes <body>:

LOPU_PROBE activeElement = BODY "" isBody = true

The user is not stranded, because arrows / Return / Escape are all handled on window and keep working from body. The only real cost is that a subsequent Tab restarts from the top of the panel. If you ever want to tidy it, returning focus to the search input inside recordSuccess() when the recovery controls were mounted would close it. Entirely optional.

Relatedly, the catch branch does not clear requiresAccessibility, so a later unrelated failure (e.g. Clipboard access is unavailable) renders under the Accessibility help text. I looked at changing it and decided against: when that state was reached, Accessibility genuinely is still required, so leaving the guidance up is the more truthful behaviour.

Housekeeping

I could not enumerate which other open PRs overlap EmojiPicker.tsx / app.cssapi.github.com/graphql returned HTTP 502 while I was querying. That is a transient GitHub outage, not a signal about this branch; the existing lopu: overlapping files label still stands on its own.

The PRs/662-…md investigation note, both TESTING.md updates and the remix/CHANGELOG.md entry all follow the repository's existing conventions, and the manual-QA checklist additions are specific enough to actually be executed.

Nice work — this is a clean, well-scoped fix with the native and web halves properly aligned.

— Lopu, automated repository review

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Lopu review — PR #662 (head 52adf17c vs main @ 6ad5ef21)

The failing checks here are not yours

gh pr checks shows six CANCELLED control-plane jobs. I resolved every workflow run for this exact head SHA and took the newest run per workflow — all six conclude success or skipped. The cancelled entries are runs 34043973638 and 34044076944 of Lopu manages PRs after pull_request_target, superseded by run 34044084379 (success, 16:00:49Z) on the same SHA. Ordinary concurrency supersession that the rollup still surfaces. No rerun needed, no control-plane repair warranted.

CodeQL: no open alerts on this head, so nothing to fix or dispose.

The code

The core changes are correct and nicely targeted.

  • paste(_:preserveClipboard:) is the important one and it's right. Returning before clearContents() when the paste can't succeed means a denied keep-clipboard action never writes even transiently — the previous write-then-restore was observable to any clipboard watcher. Injecting isAccessibilityTrusted is what makes it testable, and asserting on NSPasteboard.general.changeCount is the correct invariant to pin.
  • I checked the result-flag algebra: requiresAccessibility seeds as !trusted and pasted can only flip after guard trusted, so no response can ever claim both. Consistent end to end.
  • actionInFlight is released in finally and reset-learning returns before it's ever set, so no path can wedge it. The runAction dependency array is complete.
  • Ordering in the !result.pasted branch is safe — recordSuccess() clears the flags and both are re-set from result in the same synchronous block, so the last write wins under batching.
  • Scoping the keydown early-return to Enter without metaKey is precise: Escape and ⌘↵ still reach the picker while a recovery control holds focus, and you test both.
  • grid-template-columns: minmax(0, 1fr) is the correct fix for the overflow — the implicit auto column was sizing to the feedback row's min-content width and dragging every cell past the native mask.
  • application.open with the x-apple.systempreferences: scheme is supported by the bridge (url.scheme != nil) and already used identically by IndexingSettings.tsx, so the recovery button follows existing convention rather than inventing one.

The four new denied-paste tests earn their keep, particularly the deferred-promise one for in-flight serialization.

One fix applied

remix/CHANGELOG.md linked the investigation note as ../../PRs/662-…md, which resolves above the repo root — dead link on GitHub. Corrected to ../PRs/…, matching the 83 existing entries. That's the only edit I made.

While verifying, I scripted a resolve of every ](../….md) target in that file: 86 resolve, 1 broken. The remaining one is line 225 (PR #648's entry) and is pre-existing — I left it alone rather than widen your diff, but it's worth a follow-up.

Non-blocking

The permission help text and recovery buttons sit outside the role="status" live region, so a screen reader gets the one-line status but not the recovery instructions. Wrapping .emoji-feedback in the live region would fix it, but that's a real judgement call about announcement verbosity — your call, not a regression.

Validation

Run in the PR worktree at 52adf17c:

  • pnpm --filter @commander/desktop-ui test13 files, 81/81 passed
  • npx vitest run src/components/EmojiPicker.test.tsx9/9 passed
  • pnpm --filter @commander/desktop-ui typecheck — clean
  • Changelog link resolution — 86 ok / 1 pre-existing broken (was 85 / 2)

Note pnpm build:protocol must run first or 9 of 13 desktop-ui test files fail to collect on @commander/protocol — pre-existing workspace-script behaviour, not something this PR introduced.

Looks good to merge. The clipboard-safety fix is the security-relevant part and it's done correctly.

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Lopu review — PR #662

Compared head 49d9ec98 against main 6ad5ef21. All live checks are pass/skipping, and the trusted CodeQL snapshot for this head is empty, so there was nothing to fix or dispose there.

What held up under review

I traced every exit path of the reworked Swift paste(_:preserveClipboard:). copied is only ever reported true when the pasteboard genuinely retains the emoji, and every keep-clipboard failure either returns before touching the pasteboard or restores the snapshot — the change-count assertion in the new test is the right invariant for the "clipboard observers latch a transient write" concern. Also confirmed:

  • requiresAccessibility is a required boolean in NativePasteResult, so the new state can't be fed undefined.
  • application.open admits any URL with a scheme, so the x-apple.systempreferences: deep link is genuinely submitted as a URL, not mis-handled as a file path.
  • .launcher-shell:has(> .emoji-picker-panel) outranks the later @media (max-width: 720px) rule on specificity, so the 18px native inset holds despite source order — the CSS comment is accurate.
  • learnedSelectionID can't get stuck now that recordSuccess sets it unconditionally: remember() always yields a new recentIDs array, so the reconciling effect always fires and clears it.
  • actionInFlight is set immediately before the try, and every exit — including the early returns inside it — passes through finally.

One defect, fixed in this branch

Activating Copy Emoji succeeds, clears requiresAccessibility, and unmounts the recovery controls — which drops focus to <body>. On a type-to-search surface that's a dead end: typing reaches nothing, with no visible cue. This PR itself establishes these controls as a keyboard path (the new keydown guard, and copyEmoji.focus() in its own test), so the case is reachable by design.

Confirmed before changing anything, via a throwaway probe:

BEFORE activeElement = BUTTON Copy Emoji
AFTER  activeElement = BODY null

The fix records focus entering .emoji-recovery-actions and returns focus to the search field when the controls disappear — but only when focus was genuinely lost (document.activeElement === document.body), so focus is repaired and never stolen from somewhere you deliberately moved it. Two tests added: one pins the restore, one pins the no-steal guard.

Validation

EmojiPicker.test.tsx 11 passed · full desktop-ui suite 83 passed / 13 files (was 81) · tsc --noEmit clean · vite build clean.

Negative control: with the new effect body replaced by an early return, the focus-restore test fails and everything else still passes — so it pins the fix rather than passing vacuously.

testDeniedEmojiPasteDoesNotTouchTheClipboard needs a macOS host and could not run on this Linux runner; I reviewed it by reading and its assertions match the changed control flow.

Left alone deliberately

  • In the !result.pasted branch the comment says a rejected paste "is not a choice", but result.copied && !preserveClipboard does record recents/learning. That behaviour is right — for paste-and-copy the clipboard really was updated — the comment just reads broader than the code it sits above. Wording only.
  • The catch path leaves requiresAccessibility set, so guidance persists alongside a new error. Access is still denied at that point, so this seems correct.
  • .emoji-footer's max-height: 50vh competes with the minmax(0, 1fr) results row in compact mode. The bound is reasonable and you report native visual acceptance; I can't render layout here and didn't want to speculate.

Nice work on the root-cause note — it matches what the code actually does, and dependency-injecting isAccessibilityTrusted specifically to make the denied path testable is the right call.

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Lopu review — approving on the merits, no changes made.

I compared 0a6ec78b against main @ 6ad5ef21 and re-derived the reasoning rather than trusting the description. Nothing needed a commit, so I left the worktree clean.

Checks / CodeQL: all green — no failing, cancelled or timed-out check. The long list of skipping control-plane jobs is the expected fan-out shape for a native-app change, not a suppressed failure. The trusted CodeQL snapshot for this head is empty, so there is nothing to fix or dispose of.

What I actually verified, beyond reading the diff:

  • The pasteboard gate is a real privacy fix, not a refactor. Restore-after-write cannot retract a value a clipboard observer already captured, so returning before PasteboardSnapshot.capture() is the correct shape. I walked every remaining path: for preserveClipboard with a trusted process but a missing target, old and new both return copied: false, pasted: false, so there is no regression for the JS caller. The one intentional difference — seeding requiresAccessibility from !trusted — makes an untrusted process whose pasteboard write itself fails report the permission problem instead of hiding it. The two guards after the write are now unreachable for keep-clipboard but still live for paste-and-copy, so they are not dead code.
  • actionInFlight cannot wedge the picker. The ref clears in finally, and nativeRequest rejects on a hard 10s timeout, so a hung native host can't leave every action permanently ignored.
  • The recovery button reaches a real handler. application.open accepts any URL with a scheme, and x-apple.systempreferences is a valid RFC 3986 scheme (. is permitted in schemes), so the deep link isn't a silently-failing button.
  • The CSS cascade works by specificity, not source order. .launcher-shell:has(> .emoji-picker-panel) (0,2,0) does override the max-width: 720px 8px rule (0,1,0), while compact mode (0,3,0) keeps its 12px inset. :has() is safe at the .macOS(.v14) deployment target. .emoji-status losing its own color is not a regression — it inherits var(--muted) from .emoji-footer.
  • The new Swift test compiles. Since this runner has no macOS toolchain I checked it against the declarations by hand: memberwise init order, bridge argument order, legal default-skipping before the new trailing parameter, and shutdown() all line up.

Validation I ran here: 11/11 EmojiPicker.test.tsx (all six new regressions), 83/83 across all 13 desktop-ui suites, and tsc --noEmit && vite build — all passed. The Swift and Rust suites cited in the description could not be re-run on this Linux runner; I reviewed that diff by reading and said so rather than implying I executed it.

Three observations I deliberately did not change:

  1. role="status" mounts together with its first message. Some screen readers miss an announcement when the live region and its content appear in the same commit. This is pre-existing, and the new tests intentionally assert the region unmounts on success — so it belongs in a separate accessibility pass, not bolted onto this one.
  2. The catch branch leaves requiresAccessibility set from an earlier denial, so a transient bridge error can surface permission help. Benign, since the advice is still correct if the grant was missing a moment ago.
  3. testDeniedEmojiPasteDoesNotTouchTheClipboard asserts on the process-global NSPasteboard.general.changeCount, which another app can bump mid-test. It's the strongest available assertion for "did not write even transiently", so the small flake risk looks like the right trade.

The outstanding Touch ID step for the Accessibility grant refresh is a local permission migration and gates nothing in CI.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

🤖 Lopu live PR update

Status: ✅ Lopu finished — this PR is mergeable

Current phase: GitHub verified the published branch result

Estimated completion: Done — no further active-work ETA.

Time conversion (UTC source)

Moment UTC Los Angeles Melbourne
Updated 2026-09-07 07:43 UTC (UTC+00:00) 2026-09-07 00:43 PDT (UTC-07:00) 2026-09-07 17:43 AEST (UTC+10:00)

Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically.

Lopu queue and PR pulse

Scope Metric Count
Repository Open PRs 29
Repository Conflicting 3
Repository Out-of-date with target 1
Repository GitHub state unknown 4
Repository Part of an open stack 2
Repository Touch files changed by another open PR 20
Repository Target a non-root branch without an open parent PR 0
This resolver batch Admitted snapshots 7
This resolver batch Currently resolving 0
This resolver batch Waiting 0
This resolver batch Finished 7

Related PR context

  • Stack: No open parent or child PR currently links to this branch.
  • Target: main is a repository root/integration branch.
  • Changed-file overlap: 3 changed files are also touched by #10, #295, #557, #564, #590, #595, #602, #607, #611, #631, #638, #659, +5 more.

Exact branch pair: maincodex/commander-emoji-paste-recovery.

Timeline

  • 05:58 UTC — Detected that main needs to be merged into codex/commander-emoji-paste-recovery; assigning the exact snapshot to the resolver queue.
  • 06:08 UTC — Still safely queued behind earlier admitted Lopu work; no duplicate resolver was spawned.
  • 06:19 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 06:29 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 06:40 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 06:51 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 07:02 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 07:12 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 07:23 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 07:33 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 07:39 UTC — Rebuilding Graphify structure and semantic context.
  • 07:42 UTC — Working inside the isolated resolver environment.
  • 07:43 UTC — The resolver worker completed successfully and GitHub now reports this PR as mergeable.

Technical run details — optional; this comment is the human-facing source of truth.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

🤝 Merged main into codex/commander-emoji-paste-recovery to bring this PR up to date via Lopu's PR manager.

No AI resolution was needed by merge time; the branch was updated with a plain merge commit.

graphify-out/ was reset wholesale to the main side (repo rule: one side, never mixed — the graph merge driver is unavailable in CI).

Rebuilt and committed the merged code graph with graphify update .; no LLM semantic credential was available for the second phase.

Please review the merge commit before relying on it.

Lopu-Conflict-Resolution: run=34088829197 pr=662

# Conflicts:
#	graphify-out/snapshots/v1/94433d17c176f2bdac5c0a3e90f71417ae106a476d7bd861d5d9b811b7fa25aa/a72fe54e341fcdc9153402f7ce761c58d7f7269bd5a972f94ac68e85ffc25a27/GRAPH_REPORT.md
#	graphify-out/snapshots/v1/94433d17c176f2bdac5c0a3e90f71417ae106a476d7bd861d5d9b811b7fa25aa/a72fe54e341fcdc9153402f7ce761c58d7f7269bd5a972f94ac68e85ffc25a27/cost.json
#	graphify-out/snapshots/v1/94433d17c176f2bdac5c0a3e90f71417ae106a476d7bd861d5d9b811b7fa25aa/a72fe54e341fcdc9153402f7ce761c58d7f7269bd5a972f94ac68e85ffc25a27/graph.json
#	graphify-out/snapshots/v1/94433d17c176f2bdac5c0a3e90f71417ae106a476d7bd861d5d9b811b7fa25aa/a72fe54e341fcdc9153402f7ce761c58d7f7269bd5a972f94ac68e85ffc25a27/manifest.json
#	graphify-out/snapshots/v1/f1ba09fc341f66c1eb80e7e61e4d5bb6d95de1cd339228d588354f88ed3d2f20/412c079b5a0af164a118dd52e28a0faed6b07903eb7e9bea2b9f5ae0f3dcb804/GRAPH_REPORT.md
#	graphify-out/snapshots/v1/f1ba09fc341f66c1eb80e7e61e4d5bb6d95de1cd339228d588354f88ed3d2f20/412c079b5a0af164a118dd52e28a0faed6b07903eb7e9bea2b9f5ae0f3dcb804/cost.json
#	graphify-out/snapshots/v1/f1ba09fc341f66c1eb80e7e61e4d5bb6d95de1cd339228d588354f88ed3d2f20/412c079b5a0af164a118dd52e28a0faed6b07903eb7e9bea2b9f5ae0f3dcb804/graph.json
#	graphify-out/snapshots/v1/f1ba09fc341f66c1eb80e7e61e4d5bb6d95de1cd339228d588354f88ed3d2f20/412c079b5a0af164a118dd52e28a0faed6b07903eb7e9bea2b9f5ae0f3dcb804/manifest.json
#	graphify-out/snapshots/v1/f7e629902b574fb823945c6fdf643102dc6d2d2a45d808e682ff1d6e0309ad29/9fdf09c60851ff3f5884a59af3930c059b5c85d70b1265a35aab688e61ae68c0/GRAPH_REPORT.md
#	graphify-out/snapshots/v1/f7e629902b574fb823945c6fdf643102dc6d2d2a45d808e682ff1d6e0309ad29/9fdf09c60851ff3f5884a59af3930c059b5c85d70b1265a35aab688e61ae68c0/cost.json
#	graphify-out/snapshots/v1/f7e629902b574fb823945c6fdf643102dc6d2d2a45d808e682ff1d6e0309ad29/9fdf09c60851ff3f5884a59af3930c059b5c85d70b1265a35aab688e61ae68c0/graph.json
#	graphify-out/snapshots/v1/f7e629902b574fb823945c6fdf643102dc6d2d2a45d808e682ff1d6e0309ad29/9fdf09c60851ff3f5884a59af3930c059b5c85d70b1265a35aab688e61ae68c0/manifest.json
Structural `graphify update` completed (graphify 0.9.4, no semantic credential available).

Refreshed by the resolve-pr-conflicts workflow: https://github.com/lopugit/thingtime/actions/runs/34088829197

Lopu-Conflict-Resolution: run=34088829197 pr=662
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

🤖 Lopu live PR update

Status: ✅ Lopu finished — this PR is mergeable

Current phase: GitHub verified the published branch result

Estimated completion: Done — no further active-work ETA.

Time conversion (UTC source)

Moment UTC Los Angeles Melbourne
Updated 2026-09-07 09:48 UTC (UTC+00:00) 2026-09-07 02:48 PDT (UTC-07:00) 2026-09-07 19:48 AEST (UTC+10:00)

Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically.

Lopu queue and PR pulse

Scope Metric Count
Repository Open PRs 28
Repository Conflicting 4
Repository Out-of-date with target 0
Repository GitHub state unknown 4
Repository Part of an open stack 2
Repository Touch files changed by another open PR 19
Repository Target a non-root branch without an open parent PR 0
This resolver batch Admitted snapshots 6
This resolver batch Currently resolving 0
This resolver batch Waiting 0
This resolver batch Finished 6

Related PR context

  • Stack: No open parent or child PR currently links to this branch.
  • Target: main is a repository root/integration branch.
  • Changed-file overlap: 3 changed files are also touched by #10, #295, #564, #590, #595, #602, #607, #611, #638, #665, #680, #682, +1 more.

Exact branch pair: maincodex/commander-emoji-paste-recovery.

Timeline

  • 07:52 UTC — Detected that main needs to be merged into codex/commander-emoji-paste-recovery; assigning the exact snapshot to the resolver queue.
  • 07:54 UTC — Still safely queued behind earlier admitted Lopu work; no duplicate resolver was spawned.
  • 08:04 UTC — Still safely queued behind earlier admitted Lopu work; no duplicate resolver was spawned.
  • 08:04 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 08:15 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 08:15 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 08:26 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 08:26 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 08:36 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 08:36 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 08:47 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 08:47 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 08:55 UTC — Rebuilding Graphify structure and semantic context.
  • 08:58 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 08:59 UTC — The resolver worker completed successfully and GitHub now reports this PR as mergeable.
  • 09:09 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 09:19 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 09:26 UTC — Working inside the isolated resolver environment.
  • 09:27 UTC — The resolver worker completed successfully and GitHub now reports this PR as mergeable.
  • 09:38 UTC — The resolver worker completed successfully and GitHub now reports this PR as mergeable.
  • 09:48 UTC — The resolver worker completed successfully and GitHub now reports this PR as mergeable.

Technical run details — optional; this comment is the human-facing source of truth.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

🤝 Merged main into codex/commander-emoji-paste-recovery to bring this PR up to date via Lopu's PR manager.

No AI resolution was needed by merge time; the branch was updated with a plain merge commit.

Rebuilt and committed the merged code graph with graphify update .; no LLM semantic credential was available for the second phase.

Please review the merge commit before relying on it.

Lopu-Conflict-Resolution: run=34097654441 pr=662
Structural `graphify update` completed (graphify 0.9.4, no semantic credential available).

Refreshed by the resolve-pr-conflicts workflow: https://github.com/lopugit/thingtime/actions/runs/34097654441

Lopu-Conflict-Resolution: run=34097654441 pr=662
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Lopu review — PR #662 (head 5ef632f7 vs main @ 64c0a33c)

Approving on the merits. I made no changes — nothing in the diff justified one.

No failing checks. Everything non-skipped on this head is green (CodeQL, GitGuardian, build + typecheck ratchet + unit tests, the headless API suite, contract advisories). The skipping control-plane entries are this repo's normal conditional-job pattern, not failures or cancellations. The trusted CodeQL snapshot for this exact head is empty, so there was nothing to fix and nothing to dispose.

I re-derived the PR's own contribution: 8 source/doc files plus regenerated Graphify output. Everything else in the range arrived through the two main merges carrying #678 and #684/#685.

What holds up

  • The blowout fix targets the actual cause. .launcher-panel is a grid with only implicit columns, so the long permission string set that column's min-content width and dragged the toolbar and 8-column grid past the fixed native mask. grid-template-columns: minmax(0, 1fr) plus min-width: 0 on the flex children is the minimal correction, not a magic number.
  • The :has() inset rule resolves the way it needs to. .launcher-shell:has(> .emoji-picker-panel) computes to (0,2,0), so it beats the max-width: 720px 8px rule at (0,1,0) but still loses to :root[data-window-mode='compact'] … at (0,3,0). Compact mode keeps its deliberate 12px. That's the correct outcome and an easy one to get wrong.
  • The native guard is a real correctness fix, not cosmetics. Returning before clearContents() on the keep-clipboard path means a denied paste no longer bumps NSPasteboard.changeCount. Snapshot-and-restore was never equivalent — clipboard-history observers latch the transient write. copied stays wrotePasteValue && !preserveClipboard, and paste-and-copy while untrusted still copies and reports requiresAccessibility: true.
  • Both hazards the new controls introduce are already closed. The window keydown listener would otherwise swallow Enter on a recovery button and re-fire the failing paste; the .emoji-recovery-actions early return is scoped to non-meta Enter, so Escape and ⌘↵ still reach the picker. The focus-restore effect clears recoveryHadFocus before the activeElement test, so it can neither strand the flag nor steal focus a reader moved deliberately. Both have direct regressions.
  • Recording only successful actions is right, and the result.copied && !preserveClipboard branch still recording is also right — for paste-and-copy the copy half genuinely succeeded.

Validation I ran in the PR worktree

Command Result
pnpm exec vitest run src/components/EmojiPicker.test.tsx 11/11 pass, incl. all 6 new regressions
pnpm -r test exit 0 — 206 tests (protocol 18, filesystem-indexer 6, raycast-compat 19, desktop-ui 83, daemon 80)
pnpm -r typecheck exit 0 across all 5 projects

I could not exercise the Swift target: this reviewer runs on Linux and CommanderWebViewTests needs AppKit/WebKit. That matches the repo — no PR workflow runs swift test. The new test is a plain XCTestCase using the same construction pattern as its neighbours, and every API it touches exists on this head. Native acceptance for the denied-paste visuals and the Accessibility grant migration stays with you, as the new checklist entries record.

Two non-blocking notes

  • On the catch path in runAction, requiresAccessibility isn't cleared, so an unrelated clipboard error can render beneath the Accessibility guidance. Defensible — the missing grant is still real and the recovery affordance still useful — so I left it. Only worth revisiting if that pairing ever reads as misattributed.
  • prettier --check flags EmojiPicker.test.tsx (two waitFor callbacks wrapped under the 110-column limit). Not enforced by any check here, and untouched AccountSettings.tsx fails identically — pre-existing, not introduced by this PR. I deliberately didn't reformat it; that would be churn, not a fix.

— Lopu 🤖

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

🤖 Lopu live PR update

Status: ✅ Lopu finished — this PR is mergeable

Current phase: GitHub verified the published branch result

Estimated completion: Done — no further active-work ETA.

Time conversion (UTC source)

Moment UTC Los Angeles Melbourne
Updated 2026-09-07 14:50 UTC (UTC+00:00) 2026-09-07 07:50 PDT (UTC-07:00) 2026-09-08 00:50 AEST (UTC+10:00)

Los Angeles and Melbourne use their real IANA time zones, so PDT/PST and AEST/AEDT offsets change automatically.

Lopu queue and PR pulse

Scope Metric Count
Repository Open PRs 27
Repository Conflicting 8
Repository Out-of-date with target 2
Repository GitHub state unknown 4
Repository Part of an open stack 2
Repository Touch files changed by another open PR 22
Repository Target a non-root branch without an open parent PR 0
This resolver batch Admitted snapshots 10
This resolver batch Currently resolving 1
This resolver batch Waiting 3
This resolver batch Finished 6

Related PR context

  • Stack: No open parent or child PR currently links to this branch.
  • Target: main is a repository root/integration branch.
  • Changed-file overlap: 3 changed files are also touched by #10, #295, #564, #590, #595, #602, #607, #611, #631, #659, #660, #665, +4 more.

Exact branch pair: maincodex/commander-emoji-paste-recovery.

Timeline

  • 12:18 UTC — Detected that main needs to be merged into codex/commander-emoji-paste-recovery; assigning the exact snapshot to the resolver queue.
  • 12:29 UTC — Still safely queued behind earlier admitted Lopu work; no duplicate resolver was spawned.
  • 12:40 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 12:51 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 13:01 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 13:12 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 13:23 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 13:34 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 13:45 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 13:55 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 14:05 UTC — 10-minute check-in: still working — Waiting in Lopu's serialized PR-management lane.
  • 14:12 UTC — Merging the target branch into the PR branch.
  • 14:16 UTC — Rebuilding Graphify structure and semantic context.
  • 14:18 UTC — The resolver worker completed successfully and GitHub now reports this PR as mergeable.
  • 14:29 UTC — The resolver worker completed successfully and GitHub now reports this PR as mergeable.
  • 14:39 UTC — The resolver worker completed successfully and GitHub now reports this PR as mergeable.
  • 14:50 UTC — The resolver worker completed successfully and GitHub now reports this PR as mergeable.

Technical run details — optional; this comment is the human-facing source of truth.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

🤝 Merged main into codex/commander-emoji-paste-recovery to bring this PR up to date via Lopu's PR manager.

No AI resolution was needed by merge time; the branch was updated with a plain merge commit.

graphify-out/ was reset wholesale to the main side (repo rule: one side, never mixed — the graph merge driver is unavailable in CI).

Rebuilt and committed the merged code graph with graphify update .; no LLM semantic credential was available for the second phase.

Please review the merge commit before relying on it.

Lopu-Conflict-Resolution: run=34121206780 pr=662

# Conflicts:
#	graphify-out/snapshots/v1/94433d17c176f2bdac5c0a3e90f71417ae106a476d7bd861d5d9b811b7fa25aa/a72fe54e341fcdc9153402f7ce761c58d7f7269bd5a972f94ac68e85ffc25a27/GRAPH_REPORT.md
#	graphify-out/snapshots/v1/94433d17c176f2bdac5c0a3e90f71417ae106a476d7bd861d5d9b811b7fa25aa/a72fe54e341fcdc9153402f7ce761c58d7f7269bd5a972f94ac68e85ffc25a27/cost.json
#	graphify-out/snapshots/v1/94433d17c176f2bdac5c0a3e90f71417ae106a476d7bd861d5d9b811b7fa25aa/a72fe54e341fcdc9153402f7ce761c58d7f7269bd5a972f94ac68e85ffc25a27/graph.json
#	graphify-out/snapshots/v1/94433d17c176f2bdac5c0a3e90f71417ae106a476d7bd861d5d9b811b7fa25aa/a72fe54e341fcdc9153402f7ce761c58d7f7269bd5a972f94ac68e85ffc25a27/manifest.json
#	graphify-out/snapshots/v1/984082b969db496ff66401bac879fdb80deaaf6e9bbcbca737c0a5b151cc3df8/3a0fc01eb858b55489f2a370c4441d91c18d46721a15d509de55783b4c5ee522/GRAPH_REPORT.md
#	graphify-out/snapshots/v1/984082b969db496ff66401bac879fdb80deaaf6e9bbcbca737c0a5b151cc3df8/3a0fc01eb858b55489f2a370c4441d91c18d46721a15d509de55783b4c5ee522/cost.json
#	graphify-out/snapshots/v1/984082b969db496ff66401bac879fdb80deaaf6e9bbcbca737c0a5b151cc3df8/3a0fc01eb858b55489f2a370c4441d91c18d46721a15d509de55783b4c5ee522/graph.json
#	graphify-out/snapshots/v1/984082b969db496ff66401bac879fdb80deaaf6e9bbcbca737c0a5b151cc3df8/3a0fc01eb858b55489f2a370c4441d91c18d46721a15d509de55783b4c5ee522/manifest.json
#	graphify-out/snapshots/v1/e3ba3c8ae982a537c4b89f873a52ca34486a7ca5b08d6b83eba889cbfef81466/61963b9eb04328ad6ca8f0cbd8eb52c2bf299b7a113ededa9faf069c8caed05e/GRAPH_REPORT.md
#	graphify-out/snapshots/v1/e3ba3c8ae982a537c4b89f873a52ca34486a7ca5b08d6b83eba889cbfef81466/61963b9eb04328ad6ca8f0cbd8eb52c2bf299b7a113ededa9faf069c8caed05e/cost.json
#	graphify-out/snapshots/v1/e3ba3c8ae982a537c4b89f873a52ca34486a7ca5b08d6b83eba889cbfef81466/61963b9eb04328ad6ca8f0cbd8eb52c2bf299b7a113ededa9faf069c8caed05e/graph.json
#	graphify-out/snapshots/v1/e3ba3c8ae982a537c4b89f873a52ca34486a7ca5b08d6b83eba889cbfef81466/61963b9eb04328ad6ca8f0cbd8eb52c2bf299b7a113ededa9faf069c8caed05e/manifest.json
Structural `graphify update` completed (graphify 0.9.4, no semantic credential available).

Refreshed by the resolve-pr-conflicts workflow: https://github.com/lopugit/thingtime/actions/runs/34121206780

Lopu-Conflict-Resolution: run=34121206780 pr=662
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

last preview built 08/09 00:21 AEST #662 tt-pv1:662:develop:8a8524839353c43fe6d2abfe5bd03ccb9b429595:1788790879247 lopu: out-of-date The PR branch is behind its target branch lopu: overlapping files This PR changes files also changed by another open PR lopu: queued The current PR snapshot is waiting in Lopu's PR-management queue preview: develop ready tt-preview-state:v1:develop:ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant