Calendar overnight-event rendering + clickable [View note] link from chat

- Calendar overnight events render proportionally across day boundaries
  via --start-frac / --end-frac CSS vars instead of bleeding as full-day
  on day 2.
- Recurring-event delete strips the master uid + all master::* sibling
  instances optimistically so the row clears immediately instead of
  waiting for the next sync re-render.
- manage_notes(create) now returns note_id + open_url, and agent_loop
  appends a markdown [View note](#note-<id>) link mirroring the
  deep-research pattern.
- chatRenderer's hash-link router (already wired for #note-id) reaches
  the new notes.openNote(id) helper, which force-closes/reopens the
  Notes panel, polls for the target card, and runs a brief outline
  flash so the user can locate it on long lists.
This commit is contained in:
pewdiepie-archdaemon
2026-06-05 14:41:48 +09:00
parent e2f449f4ef
commit fbd34334a5
4 changed files with 171 additions and 7 deletions

View File

@@ -2348,6 +2348,19 @@ async def stream_agent_loop(
_anchor = f"\n\n[Open in Deep Research](#research-{_rsid})\n"
yield 'data: ' + json.dumps({"delta": _anchor}) + '\n\n'
# Same pattern for notes: when manage_notes creates a note
# and returns note_id, drop a `[View note](#note-<id>)` link
# into the stream so chatRenderer's click handler routes to
# the new openNote() in notes.js — opens the notes panel and
# scrolls/flashes the matching card. Without this, the agent
# would write "View note" as a phrase with no target.
_nid = result.get("note_id")
if _nid and block.tool_type == "manage_notes":
_title = (result.get("note_title") or "").strip()
_label = f"View note: {_title}" if _title else "View note"
_anchor = f"\n\n[{_label}](#note-{_nid})\n"
yield 'data: ' + json.dumps({"delta": _anchor}) + '\n\n'
# Save for history persistence
tool_event = {
"round": round_num,

View File

@@ -1957,7 +1957,19 @@ async def do_manage_notes(content: str, owner: Optional[str] = None) -> Dict:
)
db.add(note)
db.commit()
return {"response": f"Note created: \"{title or '(untitled)'}\" (id: {note.id[:8]})", "exit_code": 0}
# Return note_id so the chat-side renderer can build a real
# "View note" button that opens the notes modal at this id.
# Previously the create response only included a prose
# confirmation; the model would type "View note" as a markdown
# link with no target, leaving the user with a click that
# did nothing and uncertainty about whether the note was made.
return {
"response": f"Note created: \"{title or '(untitled)'}\" (id: {note.id[:8]})",
"note_id": note.id,
"note_title": title or "",
"open_url": f"/#open=notes&note={note.id}",
"exit_code": 0,
}
elif action == "update":
note_id = args.get("id", "")