mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-09 07:29:51 +00:00
* feat(web): feature-flagged rich composer for inline session @ mentions Custom segmented contenteditable (not TipTap) inserts caret-local session atoms from the existing @ picker and serializes to markdown links on send. Textarea path remains default until flag parity dogfood. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): rich composer mention boundary + #1215 refs Treat U+FFFC mirror atoms as word boundaries so @ after a session token still opens autocomplete. Point comments at Fixes #1215. Co-authored-by: Cursor <cursoragent@cursor.com> * test(web): peer-stack e2e for rich composer session @ mentions (#1215) Smoke: flag on, @ picker inserts inline session atom chip (not prose dump). Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): preserve newlines in rich composer Enter-newline mode Chromium splits contenteditable on Enter into block divs; serialize those as \\n and insert <br> when parent leaves Enter unhandled (Shift+Enter / enter-inserts-newline). Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): show @ badge when rich composer mentions flag is on Dogfood was invisible: flag-off looks like a normal textarea, and flag-on had no chrome. Surface a small @ badge when enabled. * fix(web): rich session composer on by default (not a user setting) The plan dual-path was an engineering kill-switch, not an opt-in. Default to the segmented composer; only richMentions=0 disables. Drop the flag badge and record a peer-stack motion proof covering chips + baseline UX. * fix(web): make rich composer Shift+Enter create a visible newline Trailing <br>+empty text node was a silent no-op at EOL. Use insertLineBreak (ZWSP pad fallback), assert real \\n in peer e2e. * feat(web): hover tooltips on rich composer session chips Show full title, status, short id, and path on chip hover via a portal bubble fed by live useSessions lookup (drafts fall back to title + id). * fix(web): dismiss rich composer chip tooltips on mouse leave contenteditable pointerout/relatedTarget was flaky so tips stuck after leaving the chip. Hit-test on pointermove, clear on prose/input/leave. * fix(web): address cold-review Blocker/Majors on rich composer Exclude peer e2e from default Playwright; force plain-text paste; restore newline hard-stop in findActiveWord; fix root-anchored selection mapping and nested-block serialize; cover with unit tests. * chore: drop accidental .cursor files from rich-composer tip * fix(web): close remaining cold-review gaps on rich composer Drop absolute peer e2e tooling imports, prove chip→markdown send, and harden paste/EOL/focus/tooltip/Enter edges before Meta rematerialize. Co-authored-by: Cursor <cursoragent@cursor.com> * chore: absorb soup playwright.config union for clean remat Keep fork peer-stack timeouts/annotated-video wiring and add testIgnore for e2e/peer so the next driver rematerialize does not conflict. Co-authored-by: Cursor <cursoragent@cursor.com> * revert: drop fork playwright tooling from upstreamable tip Peer-stack annotated-video + HAPI_PEER wiring stay on fork main / soup. Product tip only needs testIgnore for e2e/peer (see docs/tooling/peer-stack.md). Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): fix rich composer Shift+Enter double newline and paste space Prefer manual newline+pad over execCommand insertLineBreak, and stop applying autocomplete trailing-space on paste/drop paths. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): pad EOL Shift+Enter after Range.insertNode split insertNode always leaves an empty text sibling, so !nextSibling never saw EOL; detect meaningful trailing content and cover with jsdom tests. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): drop custom onDrop from rich composer Intercepting drop without caretRangeFromPoint landed text at EOF or no-oped in-editor moves. Native CE drop is enough for #1215; paste still forces plain text. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(web): sidebar-parity tooltips on rich composer session chips Reuse SessionRowSummary (flavor, thinking/attention, schedule, todos, relative ago, path) for chip hover so the tip matches the session list. Co-authored-by: Cursor <cursoragent@cursor.com> * chore: keep peer-stack e2e off the upstreamable tip Peer specs and playwright.peer.config stay on fork main per docs/tooling/peer-stack.md; default config still testIgnore's e2e/peer. Co-authored-by: Cursor <cursoragent@cursor.com> * feat: cite sessions with UUID wire + inspect_peer for agent/overseer Rich composer chips already serialize to [title](/sessions/<id>); flush before send so the agent prompt never gets title-only chip text. Add inspect_peer (MCP + hapi inspect-peer) as the read twin of ping_peer so that same id is immediately usable for overseer/agent peer lookup, with system-prompt glue from citations to inspect/ping. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(cli): gate inspect_peer behind permission approval Cross-session history reads need the same prompt path as ping_peer: keep inspect_peer off Claude --allowedTools and treat it as sensitive in ACP/OpenCode read-only mode so prompt injection cannot silently enumerate peer transcripts. Co-authored-by: Cursor <cursoragent@cursor.com> * chore: clarify playwright peer testIgnore is upstream-safe Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): keep session UUIDs on rich composer copy/cut/paste Copy/cut write wire markdown so chips do not collapse to @title-only clipboard text; paste reparses session links back into atoms. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
42 lines
2.6 KiB
TypeScript
42 lines
2.6 KiB
TypeScript
/**
|
|
* OpenCode-specific system prompt for change_title tool.
|
|
*
|
|
* OpenCode exposes MCP tools with the naming pattern: <server-name>_<tool-name>
|
|
* The hapi MCP server exposes `change_title`, so it's called as `hapi_change_title`.
|
|
*/
|
|
|
|
import { trimIdent } from '@/utils/trimIdent';
|
|
import { SKILL_LOOKUP_INSTRUCTION } from '@/modules/common/skillLookupInstruction';
|
|
|
|
/**
|
|
* Title instruction for OpenCode to call the hapi MCP tool.
|
|
*/
|
|
export const TITLE_INSTRUCTION = trimIdent(`
|
|
Use the title tool sparingly. For a new chat, call the tool "hapi_change_title" once after the user's initial request is clear, and set a concise task title. Do not rename the chat for routine progress, substeps, implementation details, or a slightly better wording. Rename only when the user's primary objective changes substantially and the existing title would be misleading.
|
|
When you create or find a local image file that the user should see, call the tool "hapi_display_image" with the image path so HAPI can show it inline.
|
|
When the user cites another HAPI session as [title](/sessions/<id>) (or a bare /sessions/<id>), extract that <id>. Call "hapi_inspect_peer" with sessionIdPrefix=<id> to read metadata and recent messages; call "hapi_ping_peer" with sessionIdPrefix=<id> and a message to nudge or hand off. Prefer these over JWT+curl. Shell fallbacks: hapi inspect-peer <id> / hapi ping-peer <id> <message>.
|
|
${SKILL_LOOKUP_INSTRUCTION}
|
|
`);
|
|
|
|
/**
|
|
* Tool instructions for native ACP sessions. Title updates come from ACP, so
|
|
* advertise only the MCP tools that remain available to the model.
|
|
*/
|
|
export const OPENCODE_NATIVE_TOOL_INSTRUCTION = trimIdent(`
|
|
When you create or find a local image file that the user should see, call the tool "hapi_display_image" with the image path so HAPI can show it inline.
|
|
When the user cites another HAPI session as [title](/sessions/<id>) (or a bare /sessions/<id>), extract that <id>. Call "hapi_inspect_peer" with sessionIdPrefix=<id> to read metadata and recent messages; call "hapi_ping_peer" with sessionIdPrefix=<id> and a message to nudge or hand off. Prefer these over JWT+curl. Shell fallbacks: hapi inspect-peer <id> / hapi ping-peer <id> <message>.
|
|
${SKILL_LOOKUP_INSTRUCTION}
|
|
`);
|
|
|
|
/**
|
|
* The system prompt to inject for OpenCode sessions.
|
|
*/
|
|
export const opencodeSystemPrompt = TITLE_INSTRUCTION;
|
|
|
|
/**
|
|
* Instruction prepended to OpenCode prompts while HAPI plan mode is active.
|
|
*/
|
|
export const PLAN_MODE_INSTRUCTION = trimIdent(`
|
|
You are in plan mode. Do not execute tools or make changes. Analyze the request, ask clarifying questions if needed, and respond with a concise implementation plan only.
|
|
`);
|