forked from Mike/freno-dev
site: remove the unproven remote claim from the Nook landing page
FRE-323. The one-click remote install is app-UI-only and needs hand-edited ~/.ssh/config plus a one-time ssh-copy-id (FRE-320); FRE-315 and FRE-322 hold the claim unverified and demo-gated. - drop the Remote tile and its mock from the feature collage - drop the "Any SSH box, one click away" breakdown, its demo and bullets - drop "Works across every hooked agent, local or remote" - drop the "One-click SSH setup" chip - move the copy to marketing/drafts/remote-ssh/ and mark remote held in marketing/positioning.md No replacement claim was added. Deploy waits on a push credential for the GitHub repo Vercel builds.
This commit is contained in:
76
marketing/drafts/remote-ssh/copy.md
Normal file
76
marketing/drafts/remote-ssh/copy.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# Remote SSH copy — HELD, do not publish
|
||||||
|
|
||||||
|
**Status:** removed from the live site on 2026-10-29 in the FRE-323 correction.
|
||||||
|
**Owner:** CMO. **Verified by:** CTO, on the FRE-320/FRE-205 work.
|
||||||
|
**Restore only when:** FRE-320/FRE-205 ship a genuinely one-click install, the CTO
|
||||||
|
verifies that flow, and a recording shows a remote agent joining the island.
|
||||||
|
Until then this file is the only home for these sentences.
|
||||||
|
|
||||||
|
## What was removed
|
||||||
|
|
||||||
|
### 1. Landing collage tile
|
||||||
|
|
||||||
|
Source: `src/components/nook/FeatureCollage.tsx` (removed 2026-10-29).
|
||||||
|
|
||||||
|
```
|
||||||
|
kicker: Remote
|
||||||
|
title: Agents on other machines
|
||||||
|
body: Run agents on Linux boxes and SSH servers — one click installs the
|
||||||
|
nook-hook, and their sessions join the same island.
|
||||||
|
```
|
||||||
|
|
||||||
|
The mock attached to it showed two session rows whose agent chips named
|
||||||
|
`build-box` and `gpu-rig`.
|
||||||
|
|
||||||
|
### 2. Landing feature breakdown section
|
||||||
|
|
||||||
|
Source: `src/components/nook/FeatureBreakdowns.tsx` (removed 2026-10-29).
|
||||||
|
|
||||||
|
```
|
||||||
|
kicker: Remote
|
||||||
|
title: Any SSH box, one click away
|
||||||
|
body: Pick a host from your ssh config or your tailnet and click once — the
|
||||||
|
nook-hook installs itself and its agents appear beside your local ones,
|
||||||
|
indistinguishable.
|
||||||
|
|
||||||
|
bullets:
|
||||||
|
- One click: connect, push the hook, configure agents, check it can reach this Mac
|
||||||
|
- Hosts mirror this Mac's installed integrations automatically
|
||||||
|
- Remote sessions are ordinary rows; the agent chip names the machine
|
||||||
|
```
|
||||||
|
|
||||||
|
The section's demo animated a `gpu-rig` host moving from "Not set up" through
|
||||||
|
`connecting` → `pushing the hook binary` → `configuring agents` → `checking the
|
||||||
|
host can reach this Mac` → `Live`, then showed a remote session row.
|
||||||
|
|
||||||
|
### 3. Approvals bullet
|
||||||
|
|
||||||
|
Source: `src/components/nook/FeatureBreakdowns.tsx` (removed 2026-10-29).
|
||||||
|
|
||||||
|
```
|
||||||
|
- Works across every hooked agent, local or remote
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Feature chip
|
||||||
|
|
||||||
|
Source: `src/components/nook/IslandExtras.tsx` (removed 2026-10-29).
|
||||||
|
|
||||||
|
```
|
||||||
|
One-click SSH setup
|
||||||
|
```
|
||||||
|
|
||||||
|
## What replaced it
|
||||||
|
|
||||||
|
Nothing. The Remote tile and section were removed rather than replaced; the
|
||||||
|
existing Approvals cell already carries the verified local claim:
|
||||||
|
|
||||||
|
> Approve an agent's tool call from your Mac's notch, and the agent carries on.
|
||||||
|
|
||||||
|
## Restore checklist
|
||||||
|
|
||||||
|
1. FRE-320/FRE-205 have shipped the one-click install and removed the
|
||||||
|
`~/.ssh/config` / `ssh-copy-id` friction described in FRE-320.
|
||||||
|
2. The CTO has verified the shipping flow and the evidence is on FRE-320.
|
||||||
|
3. A recording exists showing a remote agent joining the island.
|
||||||
|
4. CMO restores the copy above, then owns the launch plan for it — with an
|
||||||
|
owner and date per item — before anything goes back on the site.
|
||||||
28
marketing/drafts/remote-ssh/rationale.md
Normal file
28
marketing/drafts/remote-ssh/rationale.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# Why the remote claim is parked
|
||||||
|
|
||||||
|
The site was selling a setup path a buyer does not get.
|
||||||
|
|
||||||
|
FRE-320 measured today's actual path (2026-10-29): the one-click flow is
|
||||||
|
app-UI-only, needs a hand-edited `~/.ssh/config` for any host not already in ssh
|
||||||
|
config or on the tailnet, needs a one-time `ssh-copy-id` because the app runs ssh
|
||||||
|
with `BatchMode=yes`, and has no manual fallback for minting the per-host
|
||||||
|
credential. FRE-315 and FRE-322 §3 correction 4 marked the remote claim
|
||||||
|
unverified and demo-gated. The CTO named it the largest launch risk because it
|
||||||
|
was already in front of buyers.
|
||||||
|
|
||||||
|
So the landing page now says only what the product can back today: local agents,
|
||||||
|
the card, and the notch. The remote story is not deleted — it is parked here with
|
||||||
|
the FRE-320/FRE-205 work so it can return the day the one-click install ships and
|
||||||
|
is recorded.
|
||||||
|
|
||||||
|
## What has to be true before it returns
|
||||||
|
|
||||||
|
| Requirement | Owner | Date |
|
||||||
|
|---|---|---|
|
||||||
|
| One-click install ships without hand-edited `~/.ssh/config` or `ssh-copy-id` | FRE-320/FRE-205 engineering | When FRE-320/FRE-205 ships |
|
||||||
|
| CTO verifies the shipping flow and records the evidence on FRE-320 | CTO | Same day, before any copy moves |
|
||||||
|
| A recording shows a remote agent joining the island | Sponsor/CMO | Before restore |
|
||||||
|
| Restore copy and rebuild the launch plan with an owner + date per item | CMO | Day the three rows above are true |
|
||||||
|
|
||||||
|
Nothing in this folder is publishable. `marketing/approved/` remains the only
|
||||||
|
place a human publishes from.
|
||||||
@@ -9,7 +9,7 @@ Primary source: `~/Code/the-nook/docs/marketing-strategy.md`.
|
|||||||
## The sentence
|
## The sentence
|
||||||
|
|
||||||
> **Your Mac and your agents, under control.** The Nook puts your whole coding-agent
|
> **Your Mac and your agents, under control.** The Nook puts your whole coding-agent
|
||||||
> fleet in the notch — thirteen agents, local or over SSH — so you see what is running,
|
> fleet in the notch — thirteen agents — so you see what is running,
|
||||||
> unblock it in one tap, and keep the machine from overheating while it works.
|
> unblock it in one tap, and keep the machine from overheating while it works.
|
||||||
|
|
||||||
## The wedge
|
## The wedge
|
||||||
@@ -64,8 +64,14 @@ Never "no data leaves the device".
|
|||||||
### 4. Sell what works today
|
### 4. Sell what works today
|
||||||
|
|
||||||
Phone approvals are deferred until a shipped iOS app exists — no "(coming soon)"
|
Phone approvals are deferred until a shipped iOS app exists — no "(coming soon)"
|
||||||
parentheticals. The launch story is remote SSH: agents running on other machines,
|
parentheticals. The launch story is the approval card: an agent blocked on a
|
||||||
visible and unblockable from the Mac's notch.
|
permission prompt, unblocked from the Mac's notch, and work resumes.
|
||||||
|
|
||||||
|
Remote SSH is **held**, not approved. The one-click install has not shipped and
|
||||||
|
has not been recorded (FRE-320, FRE-205), and the current path needs hand-edited
|
||||||
|
`~/.ssh/config` and a one-time `ssh-copy-id` (FRE-320). Its copy is parked in
|
||||||
|
`marketing/drafts/remote-ssh/` until the CTO verifies the shipping flow and a
|
||||||
|
demo exists.
|
||||||
|
|
||||||
### 5. Humans hold every account
|
### 5. Humans hold every account
|
||||||
|
|
||||||
@@ -78,13 +84,18 @@ nothing posts itself.
|
|||||||
| Claim | Backing |
|
| Claim | Backing |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Thirteen hooked agents, one glance | `AgentSpec.all` — claude, codex, opencode, pi, omp, muse, hermes, openclaw, zai, gemini, cline, qwen, deepseek |
|
| Thirteen hooked agents, one glance | `AgentSpec.all` — claude, codex, opencode, pi, omp, muse, hermes, openclaw, zai, gemini, cline, qwen, deepseek |
|
||||||
| Remote agents over SSH | `hook/setup.go` remote install path; `NOOK_HOST` TCP transport |
|
|
||||||
| Permission gate answered from a card | awaitPolicyTable + bridge directive path (`hook/normalize.go`, `serialize.go`) |
|
| Permission gate answered from a card | awaitPolicyTable + bridge directive path (`hook/normalize.go`, `serialize.go`) |
|
||||||
| Fan / thermal / charge control | `helper/` (privileged helper, SMC, no kext) |
|
| Fan / thermal / charge control | `helper/` (privileged helper, SMC, no kext) |
|
||||||
| One-time purchase, no subscription | $10 → $15 at 1.0; Stripe checkout |
|
| One-time purchase, no subscription | $10 → $15 at 1.0; Stripe checkout |
|
||||||
| macOS 14+ | 27 source files use the `@Observable` framework |
|
| macOS 14+ | 27 source files use the `@Observable` framework |
|
||||||
| No prompt or code content leaves the device | envelope carries session/event/terminal metadata only (see `docs/agent-interface.md`) |
|
| No prompt or code content leaves the device | envelope carries session/event/terminal metadata only (see `docs/agent-interface.md`) |
|
||||||
|
|
||||||
|
## Held claims (not publishable)
|
||||||
|
|
||||||
|
| Claim | Why it is held | What has to be true first |
|
||||||
|
|---|---|---|
|
||||||
|
| Remote agents over SSH, one click to install | The one-click path is app-UI-only and needs hand-edited `~/.ssh/config` plus a one-time `ssh-copy-id`; no demo exists (FRE-320). FRE-315 and FRE-322 hold it unverified and demo-gated. | FRE-320/FRE-205 ship a genuinely one-click install, the CTO verifies it, and a recording shows a remote agent joining the island. Copy parked in `marketing/drafts/remote-ssh/`. |
|
||||||
|
|
||||||
## Voice
|
## Voice
|
||||||
|
|
||||||
- Short, concrete, no hype adjectives. Numbers over adjectives ("thirteen agents",
|
- Short, concrete, no hype adjectives. Numbers over adjectives ("thirteen agents",
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
For,
|
For,
|
||||||
Show,
|
|
||||||
createEffect,
|
createEffect,
|
||||||
createSignal,
|
createSignal,
|
||||||
onCleanup,
|
onCleanup,
|
||||||
@@ -21,7 +20,6 @@ import { Campfire, type CampfireState } from "./Campfire";
|
|||||||
import {
|
import {
|
||||||
ApprovalCardMock,
|
ApprovalCardMock,
|
||||||
SessionRowMock,
|
SessionRowMock,
|
||||||
Glyph,
|
|
||||||
CLAUDE,
|
CLAUDE,
|
||||||
CODEX
|
CODEX
|
||||||
} from "./ModuleMocks";
|
} from "./ModuleMocks";
|
||||||
@@ -37,7 +35,7 @@ import {
|
|||||||
* Detailed feature breakdowns: alternating copy + live-demo sections.
|
* Detailed feature breakdowns: alternating copy + live-demo sections.
|
||||||
* Each demo stages the real interaction loop: attention flares, approval
|
* Each demo stages the real interaction loop: attention flares, approval
|
||||||
* resolves, fans throttle, the charge ceiling holds, meetings surface,
|
* resolves, fans throttle, the charge ceiling holds, meetings surface,
|
||||||
* the camera wakes, a remote host goes live. Newer demos live in
|
* the camera wakes. Newer demos live in
|
||||||
* MoreDemos.tsx; app-anatomy pieces in ModuleMocks.tsx.
|
* MoreDemos.tsx; app-anatomy pieces in ModuleMocks.tsx.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -807,112 +805,6 @@ function CameraDemo() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Demo 7: Settings ▸ Remote hosts — one click to Live ──────────── */
|
|
||||||
|
|
||||||
/** RemoteMirror's progress steps, in order. */
|
|
||||||
const SETUP_STEPS = [
|
|
||||||
"connecting",
|
|
||||||
"pushing the hook binary",
|
|
||||||
"configuring agents",
|
|
||||||
"checking the host can reach this Mac"
|
|
||||||
];
|
|
||||||
|
|
||||||
function RemoteHostDemo() {
|
|
||||||
/* -1 not set up · 0…3 setting up · 4 live */
|
|
||||||
const [step, setStep] = createSignal(-1);
|
|
||||||
const [pressed, setPressed] = createSignal(false);
|
|
||||||
useDemoLoop(11000, [
|
|
||||||
[0, () => (setStep(-1), setPressed(false))],
|
|
||||||
[1400, () => setPressed(true)],
|
|
||||||
[1700, () => (setPressed(false), setStep(0))],
|
|
||||||
[2700, () => setStep(1)],
|
|
||||||
[3700, () => setStep(2)],
|
|
||||||
[4700, () => setStep(3)],
|
|
||||||
[5800, () => setStep(4)]
|
|
||||||
]);
|
|
||||||
const live = () => step() === 4;
|
|
||||||
const working = () => step() >= 0 && step() < 4;
|
|
||||||
const chip = () =>
|
|
||||||
live()
|
|
||||||
? { color: "rgb(48,209,88)", label: "Live" }
|
|
||||||
: working()
|
|
||||||
? { color: "rgba(255,255,255,0.55)", label: "Setting up" }
|
|
||||||
: { color: "rgba(255,255,255,0.35)", label: "Not set up" };
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div class="relative mx-auto w-full max-w-[360px] space-y-3">
|
|
||||||
{/* the host's card in Settings ▸ Agents ▸ Remote hosts */}
|
|
||||||
<ModuleCard>
|
|
||||||
<div class="space-y-2 text-left">
|
|
||||||
<div class="flex items-center gap-2.5">
|
|
||||||
<div class="min-w-0 flex-1">
|
|
||||||
<p class="text-[13px] font-semibold text-white">gpu-rig</p>
|
|
||||||
<p class="truncate text-[11px] text-white/45">tailnet peer</p>
|
|
||||||
</div>
|
|
||||||
<Show when={working()}>
|
|
||||||
<span class="h-3 w-3 animate-spin rounded-full border-[1.5px] border-white/25 border-t-white/80" />
|
|
||||||
</Show>
|
|
||||||
<span class="flex items-center gap-1.5 text-[10.5px] font-medium text-white/85">
|
|
||||||
<span
|
|
||||||
class="h-[7px] w-[7px] rounded-full transition-colors duration-300"
|
|
||||||
style={{ background: chip().color }}
|
|
||||||
/>
|
|
||||||
{chip().label}
|
|
||||||
</span>
|
|
||||||
<Show
|
|
||||||
when={live()}
|
|
||||||
fallback={
|
|
||||||
<span
|
|
||||||
class="rounded-md px-2.5 py-1 text-[11px] font-semibold text-white transition-all duration-200"
|
|
||||||
style={{
|
|
||||||
background: ACCENT,
|
|
||||||
opacity: working() ? 0 : 1,
|
|
||||||
transform: pressed() ? "scale(0.92)" : "scale(1)"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Set up
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Glyph name="refresh" size={11} class="text-white/50" />
|
|
||||||
<span class="rounded-md bg-white/10 px-2 py-1 text-[11px] font-semibold text-[#ff6961]">
|
|
||||||
Remove
|
|
||||||
</span>
|
|
||||||
</Show>
|
|
||||||
</div>
|
|
||||||
<p class="h-4 text-[11px] text-white/50">
|
|
||||||
{working() ? SETUP_STEPS[step()] : " "}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</ModuleCard>
|
|
||||||
|
|
||||||
{/* its agents arrive as ordinary rows, the machine named in the chip */}
|
|
||||||
<div
|
|
||||||
class="transition-all duration-500"
|
|
||||||
style={{
|
|
||||||
opacity: live() ? 1 : 0,
|
|
||||||
transform: live() ? "translateY(0)" : "translateY(6px)"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<SessionRowMock
|
|
||||||
title="trainer · fp16"
|
|
||||||
prompt="benchmark fp16"
|
|
||||||
state="Running python bench.py…"
|
|
||||||
status="running"
|
|
||||||
agent={CODEX}
|
|
||||||
host="gpu-rig"
|
|
||||||
origin="iTerm2"
|
|
||||||
age="now"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<FakeCursor
|
|
||||||
phase={pressed() ? "press" : step() === -1 ? "idle" : "live"}
|
|
||||||
at={{ x: 88, y: 16 }}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Demo 8: campfire states ───────────────────────────────────────── */
|
/* ── Demo 8: campfire states ───────────────────────────────────────── */
|
||||||
|
|
||||||
function CampfireDemo() {
|
function CampfireDemo() {
|
||||||
@@ -976,7 +868,6 @@ export default function FeatureBreakdowns() {
|
|||||||
"Approval cards pin above the session list; questions answer inside their row",
|
"Approval cards pin above the session list; questions answer inside their row",
|
||||||
"Allow for session waves through the rest of that session's requests",
|
"Allow for session waves through the rest of that session's requests",
|
||||||
"Answer from iPhone or Apple Watch too, now in TestFlight beta",
|
"Answer from iPhone or Apple Watch too, now in TestFlight beta",
|
||||||
"Works across every hooked agent, local or remote"
|
|
||||||
]}
|
]}
|
||||||
reversed
|
reversed
|
||||||
>
|
>
|
||||||
@@ -996,20 +887,6 @@ export default function FeatureBreakdowns() {
|
|||||||
<TerminalReplyDemo />
|
<TerminalReplyDemo />
|
||||||
</BreakdownSection>
|
</BreakdownSection>
|
||||||
|
|
||||||
<BreakdownSection
|
|
||||||
kicker="Remote"
|
|
||||||
title="Any SSH box, one click away"
|
|
||||||
body="Pick a host from your ssh config or your tailnet and click once — the nook-hook installs itself and its agents appear beside your local ones, indistinguishable."
|
|
||||||
bullets={[
|
|
||||||
"One click: connect, push the hook, configure agents, check it can reach this Mac",
|
|
||||||
"Hosts mirror this Mac's installed integrations automatically",
|
|
||||||
"Remote sessions are ordinary rows; the agent chip names the machine"
|
|
||||||
]}
|
|
||||||
reversed
|
|
||||||
>
|
|
||||||
<RemoteHostDemo />
|
|
||||||
</BreakdownSection>
|
|
||||||
|
|
||||||
<BreakdownSection
|
<BreakdownSection
|
||||||
kicker="The campfire"
|
kicker="The campfire"
|
||||||
title="A hearth that tells the truth"
|
title="A hearth that tells the truth"
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
import { For, createSignal, onCleanup, onMount, type JSX } from "solid-js";
|
import { For, createSignal, onCleanup, onMount, type JSX } from "solid-js";
|
||||||
import { IslandPill, STATUS, CALM, CRITICAL, ModuleCard } from "./IslandMock";
|
import { IslandPill, STATUS, CALM, CRITICAL, ModuleCard } from "./IslandMock";
|
||||||
import {
|
import { ApprovalCardMock, DieLine, CLAUDE } from "./ModuleMocks";
|
||||||
ApprovalCardMock,
|
|
||||||
SessionRowMock,
|
|
||||||
DieLine,
|
|
||||||
CLAUDE,
|
|
||||||
CODEX
|
|
||||||
} from "./ModuleMocks";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Feature collage: five cells sold as the app's actual UI. The hero cell
|
* Feature collage: five cells sold as the app's actual UI. The hero cell
|
||||||
@@ -105,35 +99,6 @@ function FansPanelMock() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Remote agents as the panel draws them: ordinary session rows whose agent
|
|
||||||
* chip names the machine ("Claude Code · build-box").
|
|
||||||
*/
|
|
||||||
function RemoteMock() {
|
|
||||||
return (
|
|
||||||
<div class="space-y-1.5">
|
|
||||||
<SessionRowMock
|
|
||||||
title="api · main"
|
|
||||||
prompt="fix the flaky test"
|
|
||||||
state="Running pytest -x…"
|
|
||||||
status="running"
|
|
||||||
agent={CLAUDE}
|
|
||||||
host="build-box"
|
|
||||||
age="4m"
|
|
||||||
/>
|
|
||||||
<SessionRowMock
|
|
||||||
title="trainer · fp16"
|
|
||||||
prompt="benchmark fp16"
|
|
||||||
state="Done · replied 1m ago"
|
|
||||||
status="ready"
|
|
||||||
agent={CODEX}
|
|
||||||
host="gpu-rig"
|
|
||||||
age="12m"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Deterministic usage wander for the traces. */
|
/* Deterministic usage wander for the traces. */
|
||||||
const wander = (n: number, k: number) =>
|
const wander = (n: number, k: number) =>
|
||||||
0.42 + 0.22 * Math.sin(n * 0.45 + k * 1.7) + 0.12 * Math.sin(n * 1.3 + k);
|
0.42 + 0.22 * Math.sin(n * 0.45 + k * 1.7) + 0.12 * Math.sin(n * 1.3 + k);
|
||||||
@@ -256,19 +221,6 @@ export default function FeatureCollage() {
|
|||||||
</InkStage>
|
</InkStage>
|
||||||
</CollageCell>
|
</CollageCell>
|
||||||
|
|
||||||
{/* Remote agents */}
|
|
||||||
<CollageCell
|
|
||||||
kicker="Remote"
|
|
||||||
title="Agents on other machines"
|
|
||||||
body="Run agents on Linux boxes and SSH servers — one click installs the nook-hook, and their sessions join the same island."
|
|
||||||
>
|
|
||||||
<InkStage class="w-full">
|
|
||||||
<div class="w-full px-3 text-left">
|
|
||||||
<RemoteMock />
|
|
||||||
</div>
|
|
||||||
</InkStage>
|
|
||||||
</CollageCell>
|
|
||||||
|
|
||||||
{/* Gauges */}
|
{/* Gauges */}
|
||||||
<CollageCell
|
<CollageCell
|
||||||
kicker="Your Mac"
|
kicker="Your Mac"
|
||||||
|
|||||||
@@ -740,7 +740,6 @@ const CHIPS_B = [
|
|||||||
"tmux · iTerm2 · kitty",
|
"tmux · iTerm2 · kitty",
|
||||||
"Markdown replies",
|
"Markdown replies",
|
||||||
"Tailscale hosts",
|
"Tailscale hosts",
|
||||||
"One-click SSH setup",
|
|
||||||
"iPhone widgets",
|
"iPhone widgets",
|
||||||
"Watch-face widgets",
|
"Watch-face widgets",
|
||||||
"Screenshots to clipboard",
|
"Screenshots to clipboard",
|
||||||
|
|||||||
Reference in New Issue
Block a user