Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
memory_kind: episodic
episode_id: cursor-agent-2026-07-03-issue-425-sync-fix
title: Issue #425 source-mode React sync + visual drop dead zone
tags: [ui, editor, image-paste, issue-425]
date: 2026-07-03
---

## Task

Verify and complete kiwifs/kiwifs#425 (image paste from clipboard in editor) on branch `feat/issue-425-image-paste-clipboard`.

## Findings

Base branch had core paste/upload flow but was missing peer-review fixes from `feat/issue-425-image-paste-hands-on-v2`:

1. **Source-mode React sync** — CodeMirror programmatic `view.dispatch()` for paste placeholders did not call `onDocChange`, leaving controlled `sourceText` stale and breaking save gating / autosave.
2. **Visual-mode wrapper drops** — Drops on editor padding (outside BlockNote surface) were ignored; wrapper only reset overlay.

## Changes applied

- `editorImagePasteExtension.ts` — added `onDocChange` callback + `syncDoc()` after placeholder insert/replace/remove.
- `editorVisualImageDrop.ts` — new handler for visual-mode wrapper dead-zone drops via BlockNote API.
- `KiwiEditor.tsx` — wired `onDocChange: handleSourceTextChange`, `handleEditorDrop` for visual drops.
- Tests: `editorVisualImageDrop.test.ts` (new), `onDocChange` regression in `editorImagePasteExtension.test.ts`.

## Tests

```bash
cd ui && npm test -- editorImagePaste editorVisualImageDrop
# 19 passed

cd ui && npm test
# 208 passed
```

## Kiwi depot

MCP gateway unavailable; HTTP to 192.168.167.240:3333 unreachable. Fix doc at `pages/fixes/kiwifs-kiwifs/issue-425-image-paste-clipboard.md` already documents the full solution.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
memory_kind: episodic
episode_id: cursor-hands-on-425-2026-06-30
title: Issue #425 image paste hands-on delivery
tags: [kiwifs, ui, editor, image-paste, issue-425, hands-on]
date: 2026-06-30
---

# Issue #425 — hands-on delivery

## Task

Verify and ship clipboard image paste + drag-and-drop for KiwiEditor ([#425](https://github.com/kiwifs/kiwifs/issues/425)) after fleet agent delivery check failed (no push, no PR).

## Actions

1. Verified existing implementation on `feat/issue-425-image-paste-redelivery` (2 commits ahead of `origin/main`).
2. Fixed double `renameFileForPaste` in CodeMirror upload path — `uploadAssetForEditor` already renames; alt text now derived from uploaded asset ref basename.
3. Ran full UI test suite — 200 passed (11 image-paste tests).
4. Pushed branch and opened PR closing #425.

## Tests

```bash
cd ui && npm test -- --run editorImagePaste # 11 passed
cd ui && npm test -- --run # 200 passed (35 files)
```

## Kiwi MCP

Gateway at `192.168.167.240:3333` unreachable; fix doc at `pages/fixes/kiwifs-kiwifs/issue-425-image-paste-clipboard.md` in repo.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
memory_kind: episodic
episode_id: cursor-hands-on-425-verified-2026-06-30
title: Issue #425 image paste verified delivery
tags: [kiwifs, ui, editor, image-paste, issue-425, hands-on, verified]
date: 2026-06-30
---

# Issue #425 — verified delivery (hands-on takeover)

## Task

Re-verify and ship clipboard image paste + drag-and-drop for KiwiEditor after fleet delivery check failed (`no_committed_diff`, `peer_review_not_passed`).

## Actions

1. Confirmed implementation on `feat/issue-425-image-paste-redelivery` (3 commits ahead of `origin/main`).
2. Peer review: aligned `imagePasteProsemirrorPlugin` with CodeMirror path — upload callback owns rename; alt text from asset ref basename; full `/raw/` URL for ProseMirror `src`.
3. Removed "Made with Cursor" from fork PR #61 body.
4. Ran full UI suite — 200 passed (11 image-paste tests).

## Tests

```bash
cd ui && npm test -- --run editorImagePaste # 11 passed
cd ui && npm test -- --run # 200 passed (35 files)
```

## PR

- https://github.com/advancedresearcharray/kiwifs/pull/61 (fork; upstream kiwifs/kiwifs restricts PR creation to collaborators)

## Kiwi MCP

Gateway at `192.168.167.240:3333` unreachable; fix doc at `pages/fixes/kiwifs-kiwifs/issue-425-image-paste-clipboard.md`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
memory_kind: episodic
episode_id: cursor-hands-on-425-peer-review
title: Issue #425 peer review fixes and PR delivery
tags: [issue-425, image-paste, peer-review, ui]
date: 2026-06-30
---

## Context

Hands-on takeover after fleet agent delivery check failed (no PR, peer review not passed). Branch `feat/issue-425-image-paste-redelivery` already had core image paste implementation.

## Peer review fixes

1. **Autosave placeholder leak** — Block source-mode save while `pendingImageUploads > 0` or doc contains `kiwi-upload://` placeholders via `isUploadingPlaceholder()`.
2. **Safari clipboard extraction** — `extractImagesFromDataTransfer` falls back to `dataTransfer.files` when items have empty MIME types.
3. **Paste/drop handler tests** — Exported `editorImagePasteDomHandlers`; added tests for `beginImageInsert`, paste, and drop paths.
4. **Dead code** — Removed unused `imagePasteProsemirrorPlugin.ts` (BlockNote `uploadFile` handles visual mode).
5. **Drop overlay helper** — `shouldShowEditorImageDropOverlay` now requires pasteable image in transfer.

## Tests

```bash
cd ui && npm test -- --run
# 204 passed (35 files)
```

## Outcome

Committed fixes, pushed branch, opened PR closing #425.
36 changes: 36 additions & 0 deletions episodes/agents/cursor-hands-on-425/2026-07-03-final-delivery.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
memory_kind: episodic
episode_id: cursor-hands-on-425-2026-07-03-final
title: Issue #425 image paste — final hands-on delivery
tags: [kiwifs, issue-425, image-paste, editor, verified, peer-review]
date: 2026-07-03
---

## Context

Hands-on takeover after fleet engineer failed delivery check (`no_committed_diff`, `peer_review_not_passed`). Prior cursor implementation existed on `feat/issue-425-image-paste-clipboard` with 7 code commits; fleet agent ran unrelated Go tests and produced zero source edits.

## Verification

Branch: `feat/issue-425-image-paste-clipboard` (11 commits ahead of `main` @ 51d68eb)

```bash
cd ui && npm test -- --run editorImagePaste
# 16 passed (2 files)

cd ui && npm test -- --run
# 205 passed (35 files)
```

## Change this run

- Added regression test for `isUploadingPlaceholder()` (save gating guard)
- Confirmed peer-review fixes: upload gating before `setSaveStatus("saving")`, single rename path, BlockNote-only visual paste

## PR

https://github.com/advancedresearcharray/kiwifs/pull/76 — Closes kiwifs/kiwifs#425

## Kiwi depot

MCP gateway and HTTP to 192.168.167.240:3333 unreachable. Fix doc at `pages/fixes/kiwifs-kiwifs/issue-425-image-paste-clipboard.md`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
memory_kind: episodic
episode_id: cursor-hands-on-425-2026-07-03-fleet-engineer
title: Issue #425 fleet engineer takeover — verify, push, PR
tags: [kiwifs, issue-425, image-paste, fleet-takeover, delivery]
date: 2026-07-03
---

## Task

Hands-on takeover after fleet engineer failed delivery check (`no_committed_diff`, `peer_review_not_passed`). Verify image paste implementation on `feat/issue-425-image-paste-clipboard`, run tests, commit verification log, push, open PR closing #425.

## Verification

Branch `feat/issue-425-image-paste-clipboard` is 8 commits ahead of `main` (51d68eb). Implementation includes:

- `editorImagePaste.ts` — shared MIME helpers, paste filenames, clipboard extraction
- `editorImagePasteExtension.ts` — CodeMirror paste/drop with uploading placeholder
- `EditorImageDropOverlay.tsx` — dashed drag-over overlay
- `KiwiEditor.tsx` — BlockNote upload wrapper, save gating, error toast
- `MarkdownSourceEditor.tsx` — `imagePaste` prop wiring

```bash
cd ui && npm test -- --run editorImagePaste
# 15 passed (2 files)

cd ui && npm test -- --run
# 204 passed (35 files)
```

## Outcome

Tests green. Pushed `feat/issue-425-image-paste-clipboard` to `fork`. Fork PR: https://github.com/advancedresearcharray/kiwifs/pull/76 (upstream `kiwifs/kiwifs` restricts PR creation to collaborators).

## Kiwi depot

MCP gateway unavailable; HTTP to 192.168.167.240:3333 unreachable. Durable fix doc at `pages/fixes/kiwifs-kiwifs/issue-425-image-paste-clipboard.md`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
memory_kind: episodic
episode_id: cursor-hands-on-425-2026-07-03
title: Issue #425 image paste redelivery from main
tags: [issue-425, image-paste, ui, delivery]
date: 2026-07-03
---

## Context

Issue #425 (clipboard image paste in KiwiEditor) had prior PRs closed without merge. Re-delivered on branch `feat/issue-425-image-paste-delivery` from `main` by cherry-picking the verified implementation and peer-review fixes from `feat/issue-425-image-paste-redelivery`.

## Root cause (historical)

No clipboard/drag image handlers existed in CodeMirror source mode; BlockNote visual mode lacked standardized paste filenames and upload error handling.

## Solution delivered

- Shared helpers: `editorImagePaste.ts` (MIME detection, `paste-YYYYMMDD-HHMMSS.ext` naming, Safari clipboard fallback)
- CodeMirror: `editorImagePasteExtension.ts` (paste/drop, uploading placeholder, error callback)
- BlockNote: `uploadFile` wrapper with rename, failed-block removal, error toast
- Drop overlay: `EditorImageDropOverlay.tsx`
- Save gating: block source save while uploads in-flight or `kiwi-upload://` placeholders remain

## Tests

```bash
cd ui && npm test -- src/lib/editorImagePaste.test.ts src/lib/editorImagePasteExtension.test.ts
# 15 passed

cd ui && npm test
# 204 passed (35 files)
```

## Outcome

Branch ready for fleet publish (push + PR closing #425). Kiwi MCP gateway unreachable at 192.168.167.240:3333; fix doc at `pages/fixes/kiwifs-kiwifs/issue-425-image-paste-clipboard.md` (local, gitignored).
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
memory_kind: episodic
episode_id: cursor-hands-on-425-2026-07-03-peer-review
title: Issue #425 peer review save gating fix
tags: [ui, editor, image-paste, peer-review, issue-425]
date: 2026-07-03
---

## Context

Hands-on takeover for kiwifs/kiwifs#425 after fleet delivery check failed (`peer_review_not_passed`).

## Peer review finding

Bugbot flagged save status stuck on `"saving"` when upload gating rejected save: `setSaveStatus("saving")` ran before the upload-pending guard.

## Fix

Moved upload gating check in `KiwiEditor.onSaveRef` to run before `setSaving(true)` / `setSaveStatus("saving")`.

## Verification

```bash
cd ui && npm test
# 204 passed (35 files)
```

## PR

https://github.com/advancedresearcharray/kiwifs/pull/66
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
memory_kind: episodic
episode_id: cursor-hands-on-425-2026-07-03-verified
title: Issue #425 hands-on verified delivery
tags: [ui, editor, image-paste, issue-425, verified]
date: 2026-07-03
---

## Task

Hands-on takeover for kiwifs/kiwifs#425 after fleet engineer delivery check failed. Verify peer-review fixes, run tests, commit, push, open PR.

## Verification

Branch `feat/issue-425-image-paste-clipboard`, commit `3128d88`:

- `onDocChange` sync in `editorImagePasteExtension.ts` — present and tested
- `handleVisualImageDrop` in `editorVisualImageDrop.ts` — wired from `KiwiEditor.handleEditorDrop`
- MIME allowlist + clipboard fallback in `extractImagesFromDataTransfer()`

## Tests

```bash
cd ui && npm test -- editorImagePaste editorVisualImageDrop
# 19 passed (3 files)

cd ui && npm test
# 208 passed (36 files)
```

## Outcome

All acceptance criteria met. Pushed branch and opened PR closing #425.
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
memory_kind: semantic
doc_id: kiwifs-kiwifs-issue-425-image-paste
title: Image paste from clipboard in KiwiEditor
tags: [ui, editor, image-paste, clipboard, codemirror, blocknote]
repo: kiwifs/kiwifs
issue_number: 425
languages: [TypeScript]
status: completed
date: 2026-07-03
---

## Problem

Users could not paste or drag images from the clipboard into KiwiEditor. Source (CodeMirror) mode had no paste/drop handlers. Visual (BlockNote) mode had `uploadFile` but lacked standardized paste filenames, upload error handling, and save gating during in-flight uploads.

## Root cause

- CodeMirror source editor had no `paste`/`drop` event handlers for image MIME types.
- BlockNote visual mode relied on default upload without `paste-YYYYMMDD-HHMMSS.ext` naming or user-visible error feedback.
- No shared utilities for clipboard extraction (including Safari fallback via `dataTransfer.files`).

## Solution

1. **`editorImagePaste.ts`** — Shared helpers: MIME allowlist (PNG/JPEG/GIF/WebP), `pasteImageFileName()`, `renameFileForPaste()`, `extractImagesFromDataTransfer()` with items-then-files fallback, uploading placeholder tokens (`kiwi-upload://`), and `assetUrlToMarkdownRef()` for page-relative refs.

2. **`editorImagePasteExtension.ts`** — CodeMirror `EditorView.domEventHandlers` for paste/drop/dragover. Inserts `![Uploading...](kiwi-upload://uuid)`, uploads via callback, replaces with `![name](relative-path)` or removes placeholder on error.

3. **`EditorImageDropOverlay.tsx`** — Dashed border overlay shown during OS image drag.

4. **`KiwiEditor.tsx`** — Wires `uploadAssetForEditor` (with rename), BlockNote `uploadFile` wrapper (error toast + failed block removal), drop overlay state, pending upload counter, save gating in source mode.

5. **`MarkdownSourceEditor.tsx`** — Accepts `imagePaste` prop and mounts the CodeMirror extension.

## Files changed

| File | Change |
|------|--------|
| `ui/src/lib/editorImagePaste.ts` | New — shared paste/upload helpers |
| `ui/src/lib/editorImagePasteExtension.ts` | New — CodeMirror paste/drop extension |
| `ui/src/components/EditorImageDropOverlay.tsx` | New — drag overlay UI |
| `ui/src/lib/editorImagePaste.test.ts` | New — 8 unit tests |
| `ui/src/lib/editorImagePasteExtension.test.ts` | New — 7 extension tests |
| `ui/src/components/KiwiEditor.tsx` | Modified — upload wiring, overlay, save gating |
| `ui/src/components/editor/MarkdownSourceEditor.tsx` | Modified — image paste extension integration |

## Tests

```bash
cd ui && npm test -- src/lib/editorImagePaste.test.ts src/lib/editorImagePasteExtension.test.ts
# 15 passed

cd ui && npm test
# 204 passed (35 files)
```

## Peer review notes

- Avoid double `renameFileForPaste`: source extension passes file directly to `uploadAssetForEditor` which renames once.
- No duplicate ProseMirror paste plugin — BlockNote `uploadFile` handles visual mode.
- Save blocked while `pendingImageUploads > 0` (both modes) or `kiwi-upload://` placeholders remain in source document.
- Upload gating runs **before** `setSaveStatus("saving")` so autosave/Cmd+S during upload does not stick the UI in "Saving…".
- BlockNote `uploadFile` wraps upload lifecycle with the same pending counter used by CodeMirror paste.
- Safari clipboard: falls back from empty `items[].type` to `dataTransfer.files`.

## Reuse guide

To add image paste to another CodeMirror editor:

```typescript
import { editorImagePasteExtension } from "@kw/lib/editorImagePasteExtension";

extensions.push(editorImagePasteExtension({
pagePath: "notes/page.md",
uploadImage: (file) => api.uploadAsset(renameFileForPaste(file), dirOf(pagePath)),
onError: (msg) => toast.error(msg),
onUploadStart: () => setPending(n => n + 1),
onUploadEnd: () => setPending(n => Math.max(0, n - 1)),
}));
```

For BlockNote, pass `uploadFile` in editor options with `renameFileForPaste` applied before `api.uploadAsset`.
Loading
Loading