Revert the desktop hotkey: a new crate needs a Cargo.lock this machine cannot write
Android / Build, or is the channel already serving this? (push) Successful in 3s
CI & Build / Build now, or wait for Android? (push) Successful in 4s
Android / Kotlin + Rust (APK) (push) Skipped
CI & Build / Python lint (push) Successful in 3s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 3s
CI & Build / TypeScript typecheck (push) Successful in 7s
CI & Build / Python tests (push) Successful in 10s
CI & Build / integration (push) Successful in 19s
CI & Build / Build & push image (push) Successful in 36s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 1m52s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 4m7s
Desktop (Tauri) / Update manifest (push) Successful in 4s

`42e06da` added `tauri-plugin-global-shortcut` to Cargo.toml without updating
Cargo.lock, and every cargo invocation in CI passes `--locked`. Both desktop
jobs failed on the same line before compiling anything:

    error: cannot update the lock file ... because --locked was passed

So this says nothing about whether the code is right — clippy never ran. The
gate did exactly its job.

There is no Rust toolchain on this workstation (rule 10 — CI verifies), and a
lockfile is the one artifact CI is deliberately forbidden to generate. Hand-
writing the entries is not a real option: it needs the exact checksum and the
whole transitive tree, and a wrong checksum fails harder than a missing one.

Reverted rather than left red, because a red `dev` blocks everything behind it
and the Android half of #1899 is green and unaffected at c8318c3. The work is
intact in 42e06da and comes back with `git revert 5e0c...` once the lockfile
exists — nothing here needs rewriting.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3MMqUtzX1TJgA1oypvm1c
This commit is contained in:
2026-09-01 09:10:33 -04:00
co-authored by Claude Opus 5
parent 42e06da576
commit 10ea15bef0
9 changed files with 3 additions and 511 deletions
-94
View File
@@ -5,11 +5,8 @@ import BaseButton from "../components/BaseButton.vue";
import BaseInput from "../components/BaseInput.vue";
import Icon from "../components/Icon.vue";
import {
SUGGESTED_CAPTURE_SHORTCUT,
capture as captureBridge,
sync as syncBridge,
updates as updateBridge,
type CaptureShortcut,
type Compatibility,
type ProbeResult,
type RevokeOutcome,
@@ -80,31 +77,6 @@ const checkedOnce = ref(false);
const updateAvailable = computed(() => !!update.value?.available);
// --- Quick capture -----------------------------------------------------------
// A desktop-local preference, so it lives here beside the update channel rather
// than in admin Settings: that screen is the SERVER's, and this is a property of
// this installation on this machine.
const shortcut = ref<CaptureShortcut>({ shortcut: "", registered: false });
const shortcutDraft = ref("");
const savingShortcut = ref(false);
const shortcutError = ref("");
async function saveShortcut(value: string) {
savingShortcut.value = true;
shortcutError.value = "";
try {
shortcut.value = await captureBridge.setShortcut(value);
shortcutDraft.value = shortcut.value.shortcut;
} catch (e) {
// The message comes from the core and names the actual reason — "something
// else is already using it" reads very differently from "that is not a
// shortcut this system understands", and both are things you can act on.
shortcutError.value = String((e as { message?: string }).message ?? e);
} finally {
savingShortcut.value = false;
}
}
async function checkUpdates() {
checking.value = true;
updateError.value = "";
@@ -154,13 +126,6 @@ async function refresh() {
// An older build without the update commands — leave the default showing
// rather than blocking the whole Sync screen on it.
}
try {
shortcut.value = await captureBridge.shortcut();
shortcutDraft.value = shortcut.value.shortcut;
} catch {
// Older build without the capture commands. Same reading as the channel
// above — show the default rather than block the screen.
}
try {
status.value = await syncBridge.status();
pending.value = await syncBridge.hasPending();
@@ -487,65 +452,6 @@ onMounted(refresh);
</form>
</template>
<!-- Quick capture. Outside the linked/unlinked split for the same reason as
updates: a hotkey that writes to the local store needs no server. -->
<section class="mt-10 border-t border-neutral-200 pt-8 dark:border-neutral-800">
<h2 class="text-sm font-semibold">Quick capture</h2>
<p class="mt-1 text-sm text-neutral-500 dark:text-neutral-400">
A system-wide shortcut that opens a small window to write a note in, without
bringing this one forward.
</p>
<div class="mt-4 flex items-end gap-3">
<BaseInput
id="capture-shortcut"
v-model="shortcutDraft"
label="Shortcut"
:placeholder="SUGGESTED_CAPTURE_SHORTCUT"
class="flex-1"
/>
<BaseButton :loading="savingShortcut" @click="saveShortcut(shortcutDraft)">Save</BaseButton>
<BaseButton
v-if="shortcut.shortcut"
variant="ghost"
:loading="savingShortcut"
@click="saveShortcut('')"
>
Turn off
</BaseButton>
</div>
<p v-if="shortcutError" class="mt-2 text-sm text-red-600 dark:text-red-400">
{{ shortcutError }}
</p>
<!-- Stored and LIVE are reported separately because they can disagree: a
combination another app grabbed first is saved here and does nothing when
pressed, and saying only "your shortcut is X" would be a lie with a
keystroke attached. -->
<p
v-else-if="shortcut.shortcut && !shortcut.registered"
class="mt-2 text-sm text-amber-700 dark:text-amber-400"
>
{{ shortcut.shortcut }} is saved but isn't active something else on this
system is holding it. Try a different combination.
</p>
<p v-else-if="shortcut.registered" class="mt-2 text-sm text-neutral-500 dark:text-neutral-400">
Press {{ shortcut.shortcut }} anywhere to capture a note.
</p>
<p v-else class="mt-2 text-sm text-neutral-500 dark:text-neutral-400">
Off. There's no default on purpose — any combination picked for you is one
taken away from something else on your machine.
<button
type="button"
class="underline hover:text-neutral-700 dark:hover:text-neutral-300"
@click="saveShortcut(SUGGESTED_CAPTURE_SHORTCUT)"
>
Use {{ SUGGESTED_CAPTURE_SHORTCUT }}
</button>
</p>
</section>
<!-- Updates sit outside the linked/unlinked split on purpose: an install that
has never touched a server still updates itself. -->
<section class="mt-10 border-t border-neutral-200 pt-8 dark:border-neutral-800">