Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
08d4d04
feat(context): persist typed inline context references
chrisdeeming Sep 5, 2026
e3ca9f8
fix(context): address foundation review findings and unused exports
chrisdeeming Sep 6, 2026
ad08b15
fix(context): preserve reference targets and reject ambiguous identities
chrisdeeming Sep 6, 2026
5e91f74
fix(context): bound future context payloads
chrisdeeming Sep 6, 2026
b64c9c4
fix(context): load context in the optimized turn-start query
chrisdeeming Sep 6, 2026
7001927
fix(context): preserve malformed legacy context as text
chrisdeeming Sep 6, 2026
19d815b
fix(context): distinguish preview boundaries from literal opening tags
chrisdeeming Sep 6, 2026
8fda4ec
fix(context): preserve invalid legacy input and reject ambiguous uploads
chrisdeeming Sep 7, 2026
1e934c3
fix(contracts): retain structured preview style edits for context tra…
chrisdeeming Sep 7, 2026
edba3c8
fix(context): normalize labels on manually entered references
chrisdeeming Sep 7, 2026
baf6a80
fix(context): bound aggregate payloads and preserve terminal token bo…
chrisdeeming Sep 7, 2026
a7c33dd
fix(shared): upgrade terminal labels before punctuation
chrisdeeming Sep 7, 2026
5b1ca2c
fix(shared): preserve malformed legacy context and token boundaries
chrisdeeming Sep 7, 2026
00eb0c7
fix(shared): preserve malformed legacy context atomically
chrisdeeming Sep 7, 2026
8a1b261
fix(shared): preserve review-shaped legacy context payloads
chrisdeeming Sep 7, 2026
f469165
fix(server): scope duplicate attachment IDs to turns
chrisdeeming Sep 8, 2026
09110a0
fix(server): project context before provider send
chrisdeeming Sep 8, 2026
d5c7fba
test(server): use effect test runtime for context projection
chrisdeeming Sep 8, 2026
b1d8ff4
fix(shared): preserve markdown hard breaks during context upgrade
chrisdeeming Sep 8, 2026
12f33c9
fix(server): tolerate renumbered context migration
chrisdeeming Sep 9, 2026
8ca9c95
feat(web): move composer context into inline references
chrisdeeming Sep 5, 2026
138dfa4
refactor(web): remove unused context helper exports
chrisdeeming Sep 6, 2026
19b40d8
refactor(web): defer paste helpers to the clipboard layer
chrisdeeming Sep 6, 2026
7bef34b
fix(web): keep composer context references and draft records in sync
chrisdeeming Sep 7, 2026
75f246b
fix(web): serialize exact preview style targets and values
chrisdeeming Sep 7, 2026
aebce60
test(web): cover structured annotation output in the composer layer
chrisdeeming Sep 7, 2026
88052f3
fix(web): normalize legacy terminal identities and context-only titles
chrisdeeming Sep 7, 2026
90a970a
fix(web): preserve malformed history and focus tooltip-only context
chrisdeeming Sep 7, 2026
7b355f2
fix(web): namespace context identities and migrate persisted references
chrisdeeming Sep 7, 2026
b0d6fa5
fix(web): resolve scoped references in the draft chip registry
chrisdeeming Sep 7, 2026
a6ef2a5
fix(web): hide standalone images already referenced inline
chrisdeeming Sep 7, 2026
a7f74cd
fix(web): report replacement attachments as accepted
chrisdeeming Sep 7, 2026
54053e9
fix(web): recall preview comments containing literal tag lines
chrisdeeming Sep 7, 2026
8d1c4c5
fix(web): preserve composer context identity and insertion behavior
chrisdeeming Sep 7, 2026
bd06ba4
fix(web): prefer canonical context links during draft migration
chrisdeeming Sep 7, 2026
f4180e1
fix(web): bind annotation screenshots only to images
chrisdeeming Sep 7, 2026
1db5d88
fix(web): restore file references with draft attachments
chrisdeeming Sep 7, 2026
b0f9ade
fix(web): synchronize bulk preview annotation references
chrisdeeming Sep 7, 2026
af6bb9f
fix(web): preserve composer context across servers, undo and large se…
chrisdeeming Sep 7, 2026
c3ec57e
fix(web): preserve single-image draft contract
chrisdeeming Sep 8, 2026
30348d6
fix(web): retain file attachment list after rebase
chrisdeeming Sep 8, 2026
7c32ed1
fix(web): retain attachment context through undo
chrisdeeming Sep 8, 2026
5980cb7
fix(web): keep inline files inside composer
chrisdeeming Sep 9, 2026
3102887
fix(web): preserve context in plan feedback and saved drafts
juliusmarminge Sep 9, 2026
d28ed67
feat(context): preserve references across copy paste and stash
chrisdeeming Sep 5, 2026
5f73d1c
fix(context): export record limit with its clipboard consumer
chrisdeeming Sep 6, 2026
87ddc59
fix(web): preserve context popovers in copied selections
chrisdeeming Sep 6, 2026
49a3b29
refactor(context): introduce paste helpers with their consumers
chrisdeeming Sep 6, 2026
26da99d
fix(clipboard): align fragment budgets and refresh stash context call…
chrisdeeming Sep 7, 2026
e3097db
fix(clipboard): restore preview styles from structured edit data
chrisdeeming Sep 7, 2026
b75a8bf
fix(mobile): mask context labels in the compatibility review parser
chrisdeeming Sep 7, 2026
7b47430
fix(clipboard): protect plain text and bound attachment downloads
chrisdeeming Sep 7, 2026
020bce0
fix(clipboard): import draft context without an active thread
chrisdeeming Sep 7, 2026
8a983d6
fix(clipboard): retain canonical positions for structured message copy
chrisdeeming Sep 7, 2026
f9d4d27
fix(web): preserve imported context ids and memoized chip rendering
chrisdeeming Sep 7, 2026
6549e54
fix(web): keep context renderer dependencies precise
chrisdeeming Sep 7, 2026
def532d
fix(web): preserve restorable attachment context in copy and stash
chrisdeeming Sep 7, 2026
fef4f71
fix(web): keep pasted context distinct and annotation screenshots intact
chrisdeeming Sep 7, 2026
63abdec
fix(web): preserve dependent clipboard context
chrisdeeming Sep 8, 2026
ab5612a
fix(clipboard): reuse attachments already in draft
chrisdeeming Sep 9, 2026
e803650
fix(web): import structured context through both paste entry points
juliusmarminge Sep 9, 2026
9ca84af
feat(web): unify context chip presentation and previews
chrisdeeming Sep 5, 2026
ff9a927
refactor(web): share context chip slots and media dialog styling
chrisdeeming Sep 6, 2026
f627d8f
refactor(web): reuse the shared terminal context popover
chrisdeeming Sep 6, 2026
3f1b9e7
refactor(web): reuse pull request state presentation
chrisdeeming Sep 6, 2026
2664aa7
fix(web): vertically align inline context chips
chrisdeeming Sep 6, 2026
48aa9d5
refactor(web): share the inline context chip shell
chrisdeeming Sep 6, 2026
eb1ca09
refactor(web): share the file context chip shell
chrisdeeming Sep 6, 2026
a40eddf
refactor(web): reuse the shared shell for terminal tooltips
chrisdeeming Sep 6, 2026
c6254ee
fix(web): expose unavailable file chip details to keyboard users
chrisdeeming Sep 7, 2026
13bd217
test(web): retain review fence and source-comment regressions
chrisdeeming Sep 7, 2026
6e3a25a
fix(web): render every known transcript context kind safely
chrisdeeming Sep 7, 2026
422bf12
fix(web): show unavailable state for empty annotation screenshots
chrisdeeming Sep 7, 2026
f4ed42a
merge: sync inline context presentation with upstream main
chrisdeeming Sep 7, 2026
7b37265
fix(web): keep snapshot details components private
chrisdeeming Sep 8, 2026
c132805
fix(web): compose context chips with button primitive
chrisdeeming Sep 8, 2026
71bfdbf
fix(web): preserve inline chip geometry
chrisdeeming Sep 9, 2026
e092429
fix(web): wrap backward media navigation across full cycles
juliusmarminge Sep 9, 2026
30b0122
feat(web): autocomplete repository pull request references
chrisdeeming Sep 5, 2026
554d3a0
fix(web): rank exact pull request matches ahead of substring matches
chrisdeeming Sep 7, 2026
dee7f2e
refactor(context): share exact pull request match ordering
juliusmarminge Sep 9, 2026
94299db
feat(mobile): bring inline context to native composer and chat
chrisdeeming Sep 7, 2026
224b919
fix(mobile): satisfy native checks for context handling
chrisdeeming Sep 7, 2026
6867c70
fix(mobile): retain context through pending task recovery
chrisdeeming Sep 7, 2026
e54be83
fix(mobile): keep context attachment edits atomic and labels opaque
chrisdeeming Sep 7, 2026
255651e
test(clipboard): preserve rich HTML alongside context metadata
chrisdeeming Sep 7, 2026
fe6389a
fix(mobile): preserve recovery context and resolve draft-only clipboa…
chrisdeeming Sep 7, 2026
0b3b41c
fix(mobile): retain live recovery records while bounding undo history
chrisdeeming Sep 7, 2026
abf2618
fix(web): centralize media dialog and control variants
chrisdeeming Sep 7, 2026
d27d4fb
fix(mobile): preserve context on legacy hosts and prioritize exact PR…
juliusmarminge Sep 9, 2026
16b09a8
fix(mobile): preserve context through draft reload and undo
juliusmarminge Sep 9, 2026
245f133
fix(mobile): match the default user bubble to web's message surface
chrisdeeming Sep 9, 2026
50f8a2e
fix(mobile): show only media above the composer and place the caret a…
chrisdeeming Sep 9, 2026
5bef735
fix(context): report a size on every attachment chip
chrisdeeming Sep 9, 2026
39cc64e
fix(mobile): give Android chips their size and picture identity
chrisdeeming Sep 9, 2026
df11a4f
fix(mobile): treat a picked picture as a picture, whichever picker fo…
chrisdeeming Sep 9, 2026
0c4ffee
fix(context): keep a picture a picture through send and render
chrisdeeming Sep 9, 2026
51b8285
fix(web): keep a picture's thumbnail when it also has a chip
chrisdeeming Sep 9, 2026
179359a
fix(web): size sent media to sit beside its chip
chrisdeeming Sep 9, 2026
6341627
fix(mobile): stop Android clipping the edges off a chip
chrisdeeming Sep 9, 2026
9078b00
fix(mobile): reserve the chip border a margin on both sides
chrisdeeming Sep 9, 2026
7d107ae
fix(mobile): stop truncation shaving the chip's right border
chrisdeeming Sep 9, 2026
6174ad0
fix(mobile): stop Android cropping the chip's right border
chrisdeeming Sep 9, 2026
cbba0ce
fix(context): give every chip kind the same visual weight
chrisdeeming Sep 9, 2026
1a1b015
fix(mobile): stop pull request suggestions crashing the composer
chrisdeeming Sep 9, 2026
4f6daaf
fix(mobile): colour pull request chips by their status
chrisdeeming Sep 9, 2026
fded0c6
fix(mobile): draw the pull request chip glyph web draws
chrisdeeming Sep 9, 2026
bc8cc04
fix(mobile): preview a draft picture from the bytes it actually has
chrisdeeming Sep 9, 2026
c1ce82b
fix(mobile): match web's chip borders and attachment icons
chrisdeeming Sep 9, 2026
947b309
fix(mobile): send a promoted picture under one consistent identity
chrisdeeming Sep 9, 2026
fa8127a
fix(context): keep every line of a multiline legacy comment
chrisdeeming Sep 9, 2026
6cd14db
fix(web): hold a send until a pasted attachment's bytes arrive
chrisdeeming Sep 9, 2026
d79ac5c
chore: stop tracking the local pnpm store
chrisdeeming Sep 9, 2026
ec0f61e
style(mobile): satisfy ktlint declaration spacing
chrisdeeming Sep 9, 2026
cad1864
fix(mobile): open a draft's file in the same screen a thread does
chrisdeeming Sep 9, 2026
dd49fa4
fix(context): end a legacy comment at a block, not at a blank line
chrisdeeming Sep 9, 2026
df48a18
style(mobile): group the chip's content into one parameter
chrisdeeming Sep 9, 2026
5321c26
fix(web): keep a pasted attachment tied to the draft that started it
chrisdeeming Sep 9, 2026
afb1b28
fix(web): reconcile the expanded image dialog with upstream
chrisdeeming Sep 10, 2026
bb50edc
fix(web): restore zoom, pan and snapshot details to the expanded dialog
chrisdeeming Sep 10, 2026
435c9e7
fix(context): only reclassify a file attachment as a picture
chrisdeeming Sep 10, 2026
0715f4b
fix(mobile): sit an inline chip on the same line as the words beside it
chrisdeeming Sep 10, 2026
34148a8
Revert "fix(mobile): sit an inline chip on the same line as the words…
chrisdeeming Sep 10, 2026
857d0ee
fix(mobile): keep an inline chip on its line without stretching the b…
chrisdeeming Sep 10, 2026
d97cffe
fix(web): theme the terminal context popover
chrisdeeming Sep 12, 2026
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ node_modules/
*.log
.env*
!.env.example

# pnpm content-addressable store; never belongs in the repo.
.pnpm-store/
Binary file added .pnpm-store/v11/index.db
Binary file not shown.
32 changes: 16 additions & 16 deletions apps/mobile/generated-uniwind-default-theme-variables.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@
"--color-md-blockquote-bg": "rgba(0, 0, 0, 0.02)",
"--color-md-code-bg": "rgba(0, 0, 0, 0.04)",
"--color-md-code-text": "#262626",
"--color-md-user-code-bg": "rgba(255, 255, 255, 0.22)",
"--color-md-user-code-text": "#ffffff",
"--color-md-user-fence-bg": "rgba(0, 0, 0, 0.16)",
"--color-md-user-fence-text": "#ffffff",
"--color-md-user-code-bg": "rgba(0, 0, 0, 0.04)",
"--color-md-user-code-text": "#262626",
"--color-md-user-fence-bg": "rgba(0, 0, 0, 0.06)",
"--color-md-user-fence-text": "#262626",
"--color-md-hr": "rgba(0, 0, 0, 0.08)",
"--color-user-bubble": "#007aff",
"--color-user-bubble-foreground": "#ffffff",
"--color-user-bubble-foreground-muted": "rgba(255, 255, 255, 0.78)",
"--color-user-bubble-skill-foreground": "#f0abfc",
"--color-user-bubble": "#ffffff",
"--color-user-bubble-foreground": "#262626",
"--color-user-bubble-foreground-muted": "rgba(38, 38, 38, 0.78)",
"--color-user-bubble-skill-foreground": "#2563eb",
"--color-backdrop": "rgba(0, 0, 0, 0.22)",
"--color-drawer": "rgba(255, 255, 255, 0.99)",
"--color-drawer-shadow": "rgba(0, 0, 0, 0.12)",
Expand Down Expand Up @@ -137,15 +137,15 @@
"--color-md-blockquote-bg": "rgba(255, 255, 255, 0.03)",
"--color-md-code-bg": "rgba(255, 255, 255, 0.06)",
"--color-md-code-text": "#e5e5e5",
"--color-md-user-code-bg": "rgba(255, 255, 255, 0.18)",
"--color-md-user-code-text": "#ffffff",
"--color-md-user-fence-bg": "rgba(0, 0, 0, 0.28)",
"--color-md-user-fence-text": "#ffffff",
"--color-md-user-code-bg": "rgba(255, 255, 255, 0.06)",
"--color-md-user-code-text": "#e5e5e5",
"--color-md-user-fence-bg": "rgba(255, 255, 255, 0.09)",
"--color-md-user-fence-text": "#e5e5e5",
"--color-md-hr": "rgba(255, 255, 255, 0.08)",
"--color-user-bubble": "#0a84ff",
"--color-user-bubble-foreground": "#ffffff",
"--color-user-bubble-foreground-muted": "rgba(255, 255, 255, 0.78)",
"--color-user-bubble-skill-foreground": "#f0abfc",
"--color-user-bubble": "#171717",
"--color-user-bubble-foreground": "#f5f5f5",
"--color-user-bubble-foreground-muted": "rgba(245, 245, 245, 0.78)",
"--color-user-bubble-skill-foreground": "#60a5fa",
"--color-backdrop": "rgba(0, 0, 0, 0.48)",
"--color-drawer": "rgba(14, 14, 14, 0.99)",
"--color-drawer-shadow": "rgba(0, 0, 0, 0.32)",
Expand Down
36 changes: 18 additions & 18 deletions apps/mobile/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -97,17 +97,17 @@
--color-md-blockquote-bg: rgba(0, 0, 0, 0.02);
--color-md-code-bg: rgba(0, 0, 0, 0.04);
--color-md-code-text: #262626;
--color-md-user-code-bg: rgba(255, 255, 255, 0.22);
--color-md-user-code-text: #ffffff;
--color-md-user-fence-bg: rgba(0, 0, 0, 0.16);
--color-md-user-fence-text: #ffffff;
--color-md-user-code-bg: rgba(0, 0, 0, 0.04);
--color-md-user-code-text: #262626;
--color-md-user-fence-bg: rgba(0, 0, 0, 0.06);
--color-md-user-fence-text: #262626;
--color-md-hr: rgba(0, 0, 0, 0.08);

/* iMessage-style user bubble */
--color-user-bubble: #007aff;
--color-user-bubble-foreground: #ffffff;
--color-user-bubble-foreground-muted: rgba(255, 255, 255, 0.78);
--color-user-bubble-skill-foreground: #f0abfc;
/* User bubble: a raised card on the thread canvas, matching web's message surface */
--color-user-bubble: #ffffff;
--color-user-bubble-foreground: #262626;
--color-user-bubble-foreground-muted: rgba(38, 38, 38, 0.78);
--color-user-bubble-skill-foreground: #2563eb;

/* Drawer / modal backdrop */
--color-backdrop: rgba(0, 0, 0, 0.22);
Expand Down Expand Up @@ -208,17 +208,17 @@
--color-md-blockquote-bg: rgba(255, 255, 255, 0.03);
--color-md-code-bg: rgba(255, 255, 255, 0.06);
--color-md-code-text: #e5e5e5;
--color-md-user-code-bg: rgba(255, 255, 255, 0.18);
--color-md-user-code-text: #ffffff;
--color-md-user-fence-bg: rgba(0, 0, 0, 0.28);
--color-md-user-fence-text: #ffffff;
--color-md-user-code-bg: rgba(255, 255, 255, 0.06);
--color-md-user-code-text: #e5e5e5;
--color-md-user-fence-bg: rgba(255, 255, 255, 0.09);
--color-md-user-fence-text: #e5e5e5;
--color-md-hr: rgba(255, 255, 255, 0.08);

/* iMessage-style user bubble */
--color-user-bubble: #0a84ff;
--color-user-bubble-foreground: #ffffff;
--color-user-bubble-foreground-muted: rgba(255, 255, 255, 0.78);
--color-user-bubble-skill-foreground: #f0abfc;
/* User bubble: a raised card on the thread canvas, matching web's message surface */
--color-user-bubble: #171717;
--color-user-bubble-foreground: #f5f5f5;
--color-user-bubble-foreground-muted: rgba(245, 245, 245, 0.78);
--color-user-bubble-skill-foreground: #60a5fa;

/* Drawer / modal backdrop */
--color-backdrop: rgba(0, 0, 0, 0.48);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ android {

dependencies {
implementation project(':expo-modules-core')
implementation project(':t3tools-mobile-markdown-text')
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,83 @@ package expo.modules.t3composereditor

import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import org.json.JSONObject
import org.json.JSONArray

internal object T3ComposerClipboard {
fun write(context: Context, text: String, fragment: String) {
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val payload = try {
JSONObject(fragment)
} catch (_: Exception) {
null
}
val records = payload?.optJSONArray("records")
if (payload == null || records == null) {
clipboard.setPrimaryClip(ClipData.newPlainText("T3 Code", text))
return
}
val all = (0 until records.length()).map { records.getJSONObject(it) }
val selected = all.filter { text.contains("/${it.optString("contextId")})") }.toMutableList()
val screenshots = selected.map { it.optString("screenshotContextId") }.toSet()
selected.addAll(
all.filter {
screenshots.contains(it.optString("contextId")) &&
!selected.contains(it)
}
)
payload.put("records", JSONArray(selected))
val encoded = java.net.URLEncoder.encode(payload.toString(), "UTF-8").replace("+", "%20")
val escaped = text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
clipboard.setPrimaryClip(
if (selected.isEmpty()) {
ClipData.newPlainText(
"T3 Code",
text
)
} else {
ClipData.newHtmlText(
"T3 Code",
text,
"<pre data-t3-context-fragment=\"$encoded\">$escaped</pre>"
)
}
)
}

fun read(context: Context): Map<String, String> {
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = clipboard.primaryClip
val item = if (clip != null && clip.itemCount > 0) clip.getItemAt(0) else null
return mapOf(
"text" to (item?.text?.toString() ?: ""),
"html" to (item?.htmlText ?: ""),
"fragment" to ""
)
}
}

class T3ComposerEditorModule : Module() {
override fun definition() = ModuleDefinition {
Name("T3ComposerEditor")

AsyncFunction("writeContextClipboard") { text: String, fragment: String ->
T3ComposerClipboard.write(requireNotNull(appContext.reactContext), text, fragment)
}

View(T3ComposerEditorView::class) {
Prop("controlledDocumentJson") { view: T3ComposerEditorView, documentJson: String ->
view.setControlledDocumentJson(documentJson)
}
Prop("themeJson") { view: T3ComposerEditorView, themeJson: String ->
view.setThemeJson(themeJson)
}
Prop("clipboardFragment") { view: T3ComposerEditorView, fragment: String ->
view.setClipboardFragment(fragment)
}
Prop("placeholder") { view: T3ComposerEditorView, placeholder: String ->
view.setPlaceholder(placeholder)
}
Expand All @@ -36,6 +101,9 @@ class T3ComposerEditorModule : Module() {
Prop("editable") { view: T3ComposerEditorView, editable: Boolean ->
view.setEditable(editable)
}
Prop("readOnly") { view: T3ComposerEditorView, readOnly: Boolean ->
view.setReadOnly(readOnly)
}
Prop("scrollEnabled") { view: T3ComposerEditorView, scrollEnabled: Boolean ->
view.setScrollEnabled(scrollEnabled)
}
Expand All @@ -55,6 +123,8 @@ class T3ComposerEditorModule : Module() {
"onComposerFocus",
"onComposerBlur",
"onComposerPasteImages",
"onComposerContextPress",
"onComposerPasteContext",
"onComposerContentSizeChange",
)

Expand Down
Loading
Loading