Make pairing one sheet that says what it allows before it happens
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- react, typescript
- Domain
- backend-api-design, desktop
Research direction
Start with the listed pairing dialogs, especially InviteSourceDialog.tsx and AddConnectionDialog.tsx, then trace the connection calls and existing tests. The issue depends on #17, #16, #19 and #20, and leaves open decisions about SSH permissions and whether thread messages can start a model run; check those before implementation. Done means both pairing directions use one sheet with the stated consent, status, failure and entry-point behavior, and the listed tests and desktop and touch-context screenshots pass.
Written by the indexing model from the issue text.
Description
What feature would you like to see?
Pairing happens in two unrelated dialogs (a side panel to open another space, a centred dialog to show a pairing code), and both do things the person did not choose. Pressing "Pairing code" immediately and permanently switches on "Allow other Kikis to connect" and starts listening on the local network and Tailscale, which the dialog does not mention. Pairing also asks for and grants thread messages every time, and the GUI cannot leave them out.
Decided
- One pairing sheet with two directions: "open another space" and "let another space or device open this one". It opens from three places.
- Before a pairing code is generated, the sheet says what the other side will be allowed to do and what generating the code switches on; the person presses a button that names the consequence. The server keeps switching the gate on when a code is generated; the GUI just stops doing it silently.
- Thread messages are opt-in on both sides of a pairing, unchecked by default.
- A successful pairing does not switch into the new space; it offers a "Switch" button.
- Pairing codes stay the one regular way to pair; invitations and identity strings live under Advanced (moved by the settings-merge issue).
Design
Entry points (all open the same sheet: a right-side panel on desktop, a full-height sheet on phones):
- Switch panel: "Pair a space on another computer…" → opens directly in "open another space".
- Settings → Spaces, section "Spaces on other computers": "Pair…" → "open another space".
- Settings → Access → Other spaces: "Pairing code" → "let another space or device open this one".
Open another space.
Pair a space on another computer
On the other computer, open Settings → Access → Other spaces → Pairing code.
Way [Pairing code] [SSH] (SSH only in the desktop app with saved SSH hosts)
Address http://192.168.1.20:58627
https:// anywhere. http:// is enough on this machine, the local network, or a Tailscale address.
Code XXXX-XXXX
Name (optional; empty uses the other computer's name)
☐ Also ask for thread messages Let this space's agents message that space's threads and wait for replies.
☑ Show its working and waiting counts in the switch panel Reads two numbers only, never its threads.
[Cancel] [Pair]
zh copy fixed by the design: title "配对另一台电脑上的空间"; lead "在对方的电脑上打开:设置 → 接入 → 其他空间 → 配对码。"; "方式 [配对码][SSH]"; "名称 (可选,留空用对方电脑的名字)"; "☐ 同时请求线程消息 — 让这个空间的智能体给对方的线程发消息并等待回复。"; "☑ 在切换面板里显示它的进行中与待处理数量 — 只取两个数字,不加载对方的任何线程。"; buttons "取消" "配对". The address hint is the existing st.remote.endpointHint.
- The request is
connections.pair({ endpoint, code, label?, backgroundSummary, requestBridge })withrequestBridgefrom the first checkbox (the field added by therequestBridgeissue). - The SSH way reuses today's
AddConnectionBySshDialogflow inside the sheet. The SSH connect path always asks for thread messages today (packages/kap-server/src/services/connections/manager.ts:125) and has no field to decline, so the thread-message checkbox is shown only for the pairing-code way; a checkbox that cannot take effect is not shown. - States: filling (today's inline address rules); "正在配对… / Pairing…"; success: the sheet closes, the new row appears, and a toast "已配对 {名称}。[切换]" (en: "Paired {name}. [Switch]"); the window stays in its current space.
- Failure lines (zh fixed by the design; en follows): invalid or expired code "配对码不对,或已经过期。"; address unreachable "连不上这个地址。"; the other side's gate is off (
inbound_disabled) "对方没有打开“允许其他空间连接”。"; the address is this very space (identity_changedfrom claiming one's own code) "这个地址就是当前这个空间。". Keep the existing rate-limit line (st.remote.fail.pairingRate). - In the phone app the launcher already offers "Scan QR code" first and manual entry second; nothing changes there.
Let another space or device open this one. A first screen comes before any request:
Pairing code
After pairing with this code, the other side can:
☑ Open this space (browse and chat)
☐ Message this space's threads, and start a model run here
Generating a code turns on “Allow other spaces to connect” and lets this computer
accept pairing on the local network and Tailscale until you turn that switch off.
[Cancel] [Turn on and generate code]
zh copy fixed by the design: "配对码" / "对方用配对码配对后可以:" / "☑ 打开这个空间(浏览与对话)" / "☐ 给这个空间的线程发消息,并在这里发起一轮模型运行" / "生成配对码会打开“允许其他空间连接”,并让这台电脑在局域网和 Tailscale 上接受配对,直到你关掉这个开关。" / "[取消][打开并生成配对码]".
- "Open this space" is shown checked and cannot be unchecked: every pairing grants it.
- The thread-message box maps to
createPairCode({ allowBridge }); unchecked sendsallowBridge: false. When checked, the operations sent inbridgeOperationsmust be exactly the ones the copy promises (see the open question below). - When the gate is already on, the paragraph about turning it on is not shown and the button reads "生成配对码 / Generate code".
- No request is sent until that button is pressed. Today
InviteSourceDialogcallscreatePairCode({})as soon as it mounts. - After generating: today's content (code, QR, countdown, "对方可以使用的地址 / Addresses the other side can use", "换一个码 / New code", "完成 / Done"); with no direct address, today's
st.inbound.codeNoAddressline. When the other side uses the code, the sheet shows "{名称} 已配对。" (en: "{name} is paired.") and the new row appears in the list; when it expires, "这个配对码已过期。[换一个码]" (en: "This code has expired. [New code]"). When the runtime cannot accept pairing (authentication bypassed), the button is disabled with today's reason.
Incoming list facts. On Settings → Access → Other spaces, each allowed row gains the same facts as the outgoing rows: whether it can open this space, and the thread-message direction ("线程消息:双向 / 仅发出 / 仅接收 / 无 / 读不到"), from lib/threadBridges.ts; its menu gains "线程消息… / Thread messages…" (the ThreadMessagesPanel from the thread-message issue) next to "撤销… / Revoke…". Remove st.inbound.bridgeNote once the facts are shown.
Removal and revocation copy (replace today's text; zh fixed by the design):
- Remove a pairing: "移除后,这个空间不能再打开 {名称},保存的凭据会被删除。不会关掉对方,也不改对方的设置。"
- Revoke an incoming pairing: "{名称} 正在进行的连接会中断,以后也不能再打开这里。不影响其他配对。"
Switch panel. Point its "Pair a space on another computer…" entry at this sheet (in the switch-panel issue it opens Settings → Spaces).
Strings: add keys to both packages/session-core/src/i18n/en.ts and zh.ts; en copy follows the zh meaning where the design gives only zh.
Where
apps/kiki-gui/src/components/settings/remote/InviteSourceDialog.tsx:42-60(generates the code on mount withcreatePairCode({})),:75-132(code, QR, addresses, regenerate, done).apps/kiki-gui/src/components/settings/remote/AddConnectionDialog.tsx:69-90(connections.paircall),:52-58(way state), andAddConnectionBySshDialog.tsx.apps/kiki-gui/src/components/settings/InboundConnectionsSection.tsx:150-158(the "Pairing code" button),:189-199(grant rows).- Server side that stays as is:
packages/kap-server/src/services/connections/admission.ts:179-196(createPairCodeswitches the gate on),packages/kap-server/src/start.ts:1421(the gate starts the peer listeners),packages/protocol/src/rest/connections.ts:94-100(pairCodeCreateInputSchema,allowBridgedefaulttrue). - Today's copy that this replaces:
st.inbound.inviteBody("Browsing and thread messages come up together."),st.remote.addBody,st.inbound.bridgeNote,st.remote.removeBody,st.inbound.revokeBodyinpackages/session-core/src/i18n/en.tsandzh.ts.
Done when
- With the gate off, opening "Pairing code" sends no request until "Turn on and generate code" is pressed (test).
- Generating a code without ticking thread messages sends
allowBridge: false, and after the other side pairs, this space's thread-bridge list has no new entry (test against the fixture, or integration). - Pairing to open another space without ticking thread messages sends
requestBridge: false(test inremoteConnections.test.tsor the sheet's test). - After a successful pairing the window is still in its original space and the toast offers "Switch" (test).
- Each failure reason in the table shows its line (test).
- All three entry points open the same sheet in the right direction (test).
- Screenshots at desktop and phone width, light and dark, en and zh, with
node apps/kiki-gui/scripts/visual-proof.mjs: both directions' first screens, the gate-already-on variant, a generated code, a success toast, and the Access page rows with their thread-message facts. UI work is accepted only with these screenshots. - Phone-width screenshots are taken in a touch context (
isMobile: true, hasTouch: true, asapps/kiki-gui/scripts/visual-proof-mobile-reading.mjs:294-300does). Phone mode is(pointer: coarse) and (max-width: 639px)(apps/kiki-gui/src/lib/layoutHooks.ts:57), so a width-only--viewport narrowrun ofvisual-proof.mjsshows the desktop layout squeezed, not the phone layout.
Additional information
Order: after the requestBridge protocol issue (the GUI sends the new field), the settings-merge issue (entry points and the Access page layout), the switch-panel issue (its entry is repointed here) and the thread-message issue (lib/threadBridges.ts and ThreadMessagesPanel.tsx). This issue owns InboundConnectionsSection.tsx after the settings merge.
Changing the default makes "pair, and agents can already message each other" stop being true for GUI pairings; the CLI (kiki pair) keeps today's default. The documentation issue of this series updates the feature docs and CLI notes.
Owner question: the design's checkbox says the other side can "start a model run here", but the pairing default grants read, send and wait without wake (admission.ts:7), and without wake a bridged message stays pending instead of starting a turn (packages/kap-server/src/services/threadBridge/bridge.ts:309); decide whether ticking the box grants wake or the clause is dropped from the copy.
Owner question: whether the SSH way should also be able to decline thread messages (it would need requestBridge on the SSH connect input, which today hard-codes true).
Order and scope. Paths and line numbers refer to the code after the pending GUI interaction and mobile pull request is merged into kiki.
Depends on: #17, #16, #19, #20.
Main files: apps/kiki-gui/src/components/settings/remote/PairSheet.tsx (new), apps/kiki-gui/src/components/settings/remote/AddConnectionDialog.tsx, apps/kiki-gui/src/components/settings/remote/AddConnectionBySshDialog.tsx, apps/kiki-gui/src/components/settings/remote/InviteSourceDialog.tsx, apps/kiki-gui/src/components/settings/InboundConnectionsSection.tsx, apps/kiki-gui/src/components/SpaceSwitchSheet.tsx, apps/kiki-gui/src/lib/remoteConnections.ts, apps/kiki-gui/src/lib/remoteConnections.test.ts, apps/kiki-gui/src/components/settings/remote/AddConnectionDialog.sshWay.test.tsx, apps/kiki-gui/src/components/settings/remote/AddConnectionBySshDialog.test.tsx, packages/session-core/src/i18n/en.ts, packages/session-core/src/i18n/zh.ts.
- Dominant language
- TypeScript
- Stars
- 54
- Forks
- 5
- Avg merge
- 2h 54m
- Merged PRs (30d)
- 2
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from X-T-E-R/kiki
-
Document PowerShell shell semantics and read-only Bash deduplication in Built-in Tools referenceOpendocumentation
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug documentation
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
bug
Difficulty 4/5 3-5 days Newbie friendliness 54/100
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 1/100
-
documentation
Difficulty 5/5 Over a week Newbie friendliness 25/100
Similar issues
-
area: cli priority: P3 type: bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
appandflow/stim#5640 · 1 comment ·
Maintainers usually reply within 1 day
-
Claude Code: hook systemMessage lines never reach the chatPossibly taken @chphch claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
slopus/happy-agent#139 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
NangoHQ/nango#8285 · 1 comment ·
Maintainers usually reply within 1 day
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 85/100
lingdojo/kana-dojo#34009 · 1 comment · 5 reactions ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 73/100
paperclipai/paperclip#21197 ·
Maintainers usually reply within 1 day