feat(chat): view context — tell the assistant what you're looking at
Nightly Build / build (push) Successful in 7m51s

An eye next to the paperclip shares what the user has open with their next
message: the page, the folder being browsed, the file open in the viewer and
any highlighted passage (line numbers where a source view exists), plus which
entity a detail page is about. The bag is client-authored {label, value} pairs
in English — the backend only clamps (chars, never bytes), neutralizes the
harness tag and renders one <system-extra> block per message, deduped
consecutively so it appears exactly when the view changed. On by default,
per-device toggle, hover/tap to preview, a chip on every sent message;
docs/view-context.md for users, an updated harness.md clause for the model.
This commit is contained in:
Daniele
2026-08-23 20:53:30 +01:00
parent 488c702517
commit 505f2e95c1
42 changed files with 2096 additions and 122 deletions
+138
View File
@@ -780,6 +780,144 @@
.attach-chip-remove:hover { background: var(--sidebar-hover); color: #dc2626; }
/* ── View context: composer eye + sent-bubble chip ───────────────────────────
The pill belongs to the composer and would sit more naturally in
copilot-input.css — but that file is desktop-only, and the eye is the same
control on both shells. This stylesheet is the one both index.html and
mobile.html load, so both halves of the feature live here together. */
.view-ctx-wrap {
position: relative;
display: inline-flex;
}
.view-ctx-btn {
display: inline-flex;
align-items: center;
gap: 0.25rem;
height: 2rem;
padding: 0 0.45rem;
border: 1px solid transparent;
border-radius: 999px;
background: transparent;
color: var(--placeholder-color);
font-size: 0.85rem;
line-height: 1;
cursor: pointer;
transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.view-ctx-btn:hover {
background: var(--sidebar-hover);
color: var(--text-primary, #1e293b);
}
.view-ctx-btn--on {
color: var(--accent);
}
.view-ctx-btn--on:hover {
background: rgba(var(--accent-rgb), 0.08);
border-color: rgba(var(--accent-rgb), 0.3);
color: var(--accent);
}
.view-ctx-count {
font-size: 0.7rem;
font-weight: 600;
font-variant-numeric: tabular-nums;
}
.view-ctx-overlay {
position: fixed;
inset: 0;
z-index: 99;
}
.view-ctx-panel {
position: absolute;
bottom: calc(100% + 6px);
left: 0;
z-index: 100;
width: max-content;
max-width: min(28rem, 80vw);
max-height: 18rem;
overflow-y: auto;
padding: 0.5rem 0.65rem;
border: 1px solid var(--toolbar-border);
border-radius: 0.5rem;
background: var(--msg-assistant-bg);
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
font-size: 0.75rem;
/* The composer bubble uses pre-wrap; the panel formats its own values. */
white-space: normal;
}
.view-ctx-panel-title {
font-weight: 600;
color: var(--text-primary, #1e293b);
margin-bottom: 0.35rem;
}
.view-ctx-empty {
color: var(--placeholder-color);
line-height: 1.35;
}
.view-ctx-items {
display: flex;
flex-direction: column;
gap: 0.35rem;
}
.view-ctx-item {
min-width: 0;
}
.view-ctx-label {
color: var(--placeholder-color);
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.02em;
}
/* A selection arrives as it was selected: keep its line breaks, but never let a
long unbroken path or word push the panel (or the bubble) wider. */
.view-ctx-value {
white-space: pre-wrap;
overflow-wrap: anywhere;
line-height: 1.35;
}
/* The chip inside a sent user bubble: collapsed by default, same muted weight as
the reasoning block — it is evidence, not content. */
.view-ctx-chip {
margin-top: 0.4rem;
font-size: 0.75rem;
white-space: normal;
}
.view-ctx-chip > summary {
display: inline-flex;
align-items: center;
gap: 0.3rem;
padding: 0.2rem 0.45rem;
border: 1px solid var(--toolbar-border);
border-radius: 0.5rem;
color: var(--placeholder-color);
cursor: pointer;
list-style: none;
line-height: 1.2;
}
.view-ctx-chip > summary::-webkit-details-marker { display: none; }
.view-ctx-chip > summary:hover { border-color: var(--accent); color: var(--accent); }
.view-ctx-chip .view-ctx-items {
margin-top: 0.4rem;
padding-left: 0.15rem;
}
/* ── Tool card "view details" (eye) ────────────────────────────────────────── */
.copilot-tool-eye {