@agent-native/core 0.128.0 → 0.128.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +27 -0
  3. package/corpus/core/package.json +3 -1
  4. package/corpus/core/src/server/builder-design-systems.ts +299 -82
  5. package/corpus/core/src/server/email-template.ts +33 -0
  6. package/corpus/core/src/server/index.ts +8 -0
  7. package/corpus/templates/analytics/_gitignore +2 -0
  8. package/corpus/templates/assets/_gitignore +2 -0
  9. package/corpus/templates/calendar/_gitignore +2 -0
  10. package/corpus/templates/chat/_gitignore +2 -0
  11. package/corpus/templates/clips/AGENTS.md +6 -1
  12. package/corpus/templates/clips/_gitignore +2 -0
  13. package/corpus/templates/clips/actions/complete-transactional-email-summary.ts +56 -0
  14. package/corpus/templates/clips/actions/import-loom-recording.ts +258 -76
  15. package/corpus/templates/clips/actions/lib/direct-video.ts +96 -0
  16. package/corpus/templates/clips/actions/lib/loom-import-job.ts +53 -2
  17. package/corpus/templates/clips/actions/lib/loom-video.ts +2 -62
  18. package/corpus/templates/clips/actions/lib/video-download-limits.ts +62 -0
  19. package/corpus/templates/clips/actions/list-transactional-email-ai-requests.ts +249 -0
  20. package/corpus/templates/clips/app/components/library/library-grid.tsx +65 -0
  21. package/corpus/templates/clips/app/components/library/library-layout.tsx +55 -0
  22. package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +28 -126
  23. package/corpus/templates/clips/app/global.css +23 -0
  24. package/corpus/templates/clips/app/hooks/use-transactional-email-bridge.ts +98 -0
  25. package/corpus/templates/clips/app/i18n/en-US.ts +20 -0
  26. package/corpus/templates/clips/app/routes/_app.tsx +2 -0
  27. package/corpus/templates/clips/app/routes/import.tsx +396 -0
  28. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +8 -6
  29. package/corpus/templates/clips/app/routes/record.tsx +13 -71
  30. package/corpus/templates/clips/changelog/2026-07-25-two-clip-emails-now-include-a-concise-summary-generated-secu.md +6 -0
  31. package/corpus/templates/clips/data/clips-transactional-emails/config.json +3 -0
  32. package/corpus/templates/clips/server/jobs/transactional-emails.ts +1034 -0
  33. package/corpus/templates/clips/server/lib/transactional-email-store.ts +865 -0
  34. package/corpus/templates/clips/server/lib/transactional-email-templates.ts +270 -0
  35. package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
  36. package/corpus/templates/clips/server/routes/api/view-event.post.ts +59 -2
  37. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +8 -2
  38. package/corpus/templates/content/AGENTS.md +8 -0
  39. package/corpus/templates/content/_gitignore +2 -0
  40. package/corpus/templates/content/actions/_content-database-personal-view.ts +28 -3
  41. package/corpus/templates/content/actions/_property-utils.ts +32 -2
  42. package/corpus/templates/content/actions/configure-document-property.ts +12 -2
  43. package/corpus/templates/content/actions/delete-document-property.ts +13 -3
  44. package/corpus/templates/content/actions/duplicate-document-property.ts +13 -3
  45. package/corpus/templates/content/actions/list-content-spaces.ts +5 -2
  46. package/corpus/templates/content/actions/list-document-properties.ts +12 -3
  47. package/corpus/templates/content/actions/move-database-item.ts +74 -55
  48. package/corpus/templates/content/actions/reorder-document-property.ts +20 -4
  49. package/corpus/templates/content/actions/set-document-property.ts +10 -1
  50. package/corpus/templates/content/actions/update-content-database-personal-view.ts +7 -0
  51. package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +31 -21
  52. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +30 -3
  53. package/corpus/templates/content/app/components/editor/DocumentInfoPanel.tsx +8 -1
  54. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +72 -20
  55. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +79 -10
  56. package/corpus/templates/content/app/components/editor/database/TimelineView.tsx +8 -1
  57. package/corpus/templates/content/app/components/editor/database/settings.tsx +6 -0
  58. package/corpus/templates/content/app/components/editor/database/sidebar.tsx +246 -26
  59. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +491 -197
  60. package/corpus/templates/content/app/components/sidebar/DocumentTreeItem.tsx +3 -3
  61. package/corpus/templates/content/app/components/sidebar/sidebar-reorder.tsx +409 -0
  62. package/corpus/templates/content/app/hooks/use-content-database.ts +117 -3
  63. package/corpus/templates/content/app/hooks/use-content-spaces.ts +1 -0
  64. package/corpus/templates/content/app/hooks/use-document-properties.ts +62 -18
  65. package/corpus/templates/content/app/hooks/use-documents.ts +13 -5
  66. package/corpus/templates/content/app/i18n-data.ts +261 -3
  67. package/corpus/templates/content/app/routes/_app.page.$id.tsx +9 -2
  68. package/corpus/templates/content/changelog/2026-07-24-database-page-properties-keep-their-context.md +6 -0
  69. package/corpus/templates/content/changelog/2026-07-26-sidebar-references-can-now-be-personally-reordered.md +6 -0
  70. package/corpus/templates/content/docs/solutions/2026-07-24-database-property-context-switch-diagnosis.md +249 -0
  71. package/corpus/templates/content/docs/solutions/content-sidebar-order-shape.md +389 -0
  72. package/corpus/templates/content/shared/api.ts +28 -0
  73. package/corpus/templates/design/_gitignore +2 -0
  74. package/corpus/templates/design/app/i18n-data.ts +10 -0
  75. package/corpus/templates/design/app/lib/builder-design-system-upload.ts +280 -0
  76. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +90 -54
  77. package/corpus/templates/design/changelog/2026-07-28-figma-fig-uploads-now-show-indexing-progress-and-an-open-in-.md +6 -0
  78. package/corpus/templates/design/server/handlers/design-system-decode-job-status.ts +49 -0
  79. package/corpus/templates/design/server/handlers/design-system-upload-start.ts +87 -0
  80. package/corpus/templates/design/server/handlers/index-design-system-sources.ts +82 -0
  81. package/corpus/templates/design/server/routes/api/design-system-decode-job-status.get.ts +1 -0
  82. package/corpus/templates/design/server/routes/api/design-system-upload-start.post.ts +1 -0
  83. package/corpus/templates/design/server/routes/api/index-design-system-sources.post.ts +1 -0
  84. package/corpus/templates/dispatch/_gitignore +2 -0
  85. package/corpus/templates/forms/_gitignore +2 -0
  86. package/corpus/templates/macros/_gitignore +2 -0
  87. package/corpus/templates/mail/_gitignore +2 -0
  88. package/corpus/templates/plan/_gitignore +2 -0
  89. package/corpus/templates/slides/_gitignore +2 -0
  90. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +126 -53
  91. package/corpus/templates/slides/app/components/design-system/builder-design-system-upload.ts +271 -0
  92. package/corpus/templates/slides/app/components/design-system/builder-index-response.ts +1 -1
  93. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  94. package/corpus/templates/slides/server/handlers/design-system-decode-job-status.ts +49 -0
  95. package/corpus/templates/slides/server/handlers/design-system-upload-start.ts +87 -0
  96. package/corpus/templates/slides/server/handlers/index-design-system-sources.ts +79 -0
  97. package/corpus/templates/slides/server/routes/api/design-system-decode-job-status.get.ts +1 -0
  98. package/corpus/templates/slides/server/routes/api/design-system-upload-start.post.ts +1 -0
  99. package/corpus/templates/slides/server/routes/api/index-design-system-sources.post.ts +1 -0
  100. package/corpus/templates/tasks/_gitignore +2 -0
  101. package/corpus/toolkit/CHANGELOG.md +6 -0
  102. package/corpus/toolkit/package.json +1 -1
  103. package/corpus/toolkit/src/editor/DragHandle.ts +63 -9
  104. package/dist/collab/routes.d.ts +1 -1
  105. package/dist/collab/struct-routes.d.ts +1 -1
  106. package/dist/observability/routes.d.ts +3 -3
  107. package/dist/progress/routes.d.ts +1 -1
  108. package/dist/provider-api/actions/custom-provider-registration.d.ts +10 -10
  109. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  110. package/dist/server/builder-design-systems.d.ts +49 -0
  111. package/dist/server/builder-design-systems.d.ts.map +1 -1
  112. package/dist/server/builder-design-systems.js +221 -69
  113. package/dist/server/builder-design-systems.js.map +1 -1
  114. package/dist/server/email-template.d.ts +7 -0
  115. package/dist/server/email-template.d.ts.map +1 -1
  116. package/dist/server/email-template.js +24 -0
  117. package/dist/server/email-template.js.map +1 -1
  118. package/dist/server/index.d.ts +1 -1
  119. package/dist/server/index.d.ts.map +1 -1
  120. package/dist/server/index.js +1 -1
  121. package/dist/server/index.js.map +1 -1
  122. package/dist/server/transcribe-voice.d.ts +1 -1
  123. package/dist/templates/chat/_gitignore +2 -0
  124. package/package.json +5 -3
  125. package/src/server/builder-design-systems.ts +299 -82
  126. package/src/server/email-template.ts +33 -0
  127. package/src/server/index.ts +8 -0
  128. package/src/templates/chat/_gitignore +2 -0
  129. package/corpus/templates/design/server/handlers/index-design-system-with-builder.ts +0 -151
  130. package/corpus/templates/design/server/routes/api/index-design-system-with-builder.post.ts +0 -1
  131. package/corpus/templates/slides/server/handlers/index-design-system-with-builder.ts +0 -119
  132. package/corpus/templates/slides/server/routes/api/index-design-system-with-builder.post.ts +0 -1
@@ -0,0 +1,249 @@
1
+ # Database page properties switch to Files fields after a Select edit
2
+
3
+ ## Answer
4
+
5
+ The bug is reproduced and diagnosed. A database row can belong both to the
6
+ database the user is viewing and to its workspace's canonical Files database.
7
+ The sidebar preview initially warms its property cache from the viewed database,
8
+ but a property save invalidates that cache and refetches properties using only
9
+ the page id. The server then chooses one of the page's database memberships
10
+ without receiving or ordering by the active database. When it chooses Files, the
11
+ preview replaces the user's fields with the Files system fields `Kind`,
12
+ `Parent`, and `Source`.
13
+
14
+ The colored Select interaction is the reliable trigger because a successful
15
+ `set-document-property` invalidates `list-document-properties`. The color option
16
+ implementation is not the cause.
17
+
18
+ This is a context-loss bug across the action boundary, not a Builder hydration
19
+ bug and not a continuation of the draft-conflict banner fixed by PR #2303.
20
+
21
+ ## Evidence
22
+
23
+ ### Reported behavior
24
+
25
+ The supplied report and comparison screenshots establish that:
26
+
27
+ - The original page-body interruption appears resolved.
28
+ - In the database sidebar preview, choosing a colored Select value can replace
29
+ the database's fields with unclickable `Kind`, `Parent`, and `Source`.
30
+ - `+ Add property` remains visible.
31
+ - Opening the full page shows no fields above the body.
32
+ - The reporter reasonably suspected the recent Select-color work because selecting a
33
+ colored value triggers the transition, but the evidence below excludes the
34
+ palette code as the cause.
35
+
36
+ The preview screenshot shows a page
37
+ `Agencies` with only `Kind`, `Parent`, and `Source`, each empty, followed by an
38
+ enabled-looking `+ Add property` control. The comparison screenshot shows the same
39
+ title and body with no properties above the body. Together they corroborate the
40
+ reported schema replacement and distinguish it from the intentional full-page
41
+ Info-rail presentation. They do not show the click sequence, so the disposable
42
+ dual-membership reproduction remains the causal proof.
43
+
44
+ ### Executed database reproduction
45
+
46
+ A disposable SQLite fixture was migrated and run through Content's real
47
+ Drizzle property resolvers under Node 24. The fixture created:
48
+
49
+ - one row page;
50
+ - a Files membership whose properties were `Kind`, `Parent`, and `Source`; and
51
+ - a custom database membership whose colored Select property was `Status`.
52
+
53
+ The same page produced:
54
+
55
+ ```json
56
+ {
57
+ "cachedPreviewSchema": ["Status"],
58
+ "refetchedPageOnlySchema": ["Kind", "Parent", "Source"],
59
+ "memberships": ["files-db", "custom-db"]
60
+ }
61
+ ```
62
+
63
+ The fixture and its SQLite sidecars were removed after the run.
64
+
65
+ The existing cache-seeding unit test also passed under the repository's compiled
66
+ runtime:
67
+
68
+ ```text
69
+ app/hooks/use-documents.test.ts
70
+ 1 passed, 14 skipped
71
+ ```
72
+
73
+ That test confirms that opening a database row warms the
74
+ `list-document-properties` cache with the row's contextual database and
75
+ properties.
76
+
77
+ ### Causal code path
78
+
79
+ 1. The preview seeds `list-document-properties` from the active database row,
80
+ including that row's exact `databaseId`
81
+ ([use-documents.ts](../../app/hooks/use-documents.ts#L242),
82
+ [DatabaseView.tsx](../../app/components/editor/database/DatabaseView.tsx#L4346)).
83
+ The cache key itself contains only `documentId`
84
+ ([use-documents.ts](../../app/hooks/use-documents.ts#L42)).
85
+ 2. `DocumentProperties` receives `databaseDocumentId`, but its read hook drops
86
+ that context and calls `list-document-properties` with only `documentId`
87
+ ([DocumentProperties.tsx](../../app/components/editor/DocumentProperties.tsx#L798),
88
+ [use-document-properties.ts](../../app/hooks/use-document-properties.ts#L25)).
89
+ 3. A successful Select value save invalidates that page-only query
90
+ ([use-document-properties.ts](../../app/hooks/use-document-properties.ts#L102)).
91
+ 4. `list-document-properties` accepts only `documentId`
92
+ ([list-document-properties.ts](../../actions/list-document-properties.ts#L12)).
93
+ Its resolver selects the first membership without an `orderBy` or an active
94
+ database id
95
+ ([\_property-utils.ts](../../actions/_property-utils.ts#L103)).
96
+ 5. The refetched Files definitions render as non-editable because system-role
97
+ properties deliberately suppress management and value controls
98
+ ([DocumentProperties.tsx](../../app/components/editor/DocumentProperties.tsx#L930)).
99
+
100
+ There is already a safer membership preference in the separate document-read
101
+ path: `getDatabaseItemByDocumentId` orders non-system databases ahead of system
102
+ databases ([\_database-utils.ts](../../actions/_database-utils.ts#L732)). The
103
+ property resolver does not share it. Copying that heuristic would reduce the
104
+ Files symptom but would still be wrong for a page in multiple user databases;
105
+ the active database must be explicit.
106
+
107
+ ### Data-integrity edge
108
+
109
+ Avoiding `+ Add property` was the safe choice. The control is rendered from the
110
+ refetched database response, but it passes only `documentId`
111
+ ([DocumentProperties.tsx](../../app/components/editor/DocumentProperties.tsx#L848)).
112
+ `configure-document-property` resolves a database from that ambiguous page id
113
+ before inserting the definition
114
+ ([configure-document-property.ts](../../actions/configure-document-property.ts#L91)).
115
+ In the reproduced state, a new property can therefore target Files rather than
116
+ the database the user is looking at.
117
+
118
+ ### Full-page behavior
119
+
120
+ Not showing database fields directly above the full-page body is currently
121
+ intentional: the full-page surface renders them in the Info rail
122
+ ([DocumentInfoPanel.tsx](../../app/components/editor/DocumentInfoPanel.tsx#L21)).
123
+ However, the Info rail uses the same page-only read hook, so its schema can still
124
+ be wrong. Opening a page from a database should preserve the originating
125
+ database context through the route/application state and into the Info rail.
126
+
127
+ ## Inferences
128
+
129
+ - PR #2310 made the Select interaction more visible and optimized, but it did
130
+ not introduce the server's page-only membership resolver. The trigger and
131
+ cause merely happen to shake hands.
132
+ - PR #2344 correctly narrowed property-save invalidation and began passing the
133
+ parent database document id into value-mutation cache work. It did not add the
134
+ active database id to the property read action or its cache key, so this
135
+ context switch remains.
136
+ - Pages created in or later added to more than one database are the affected
137
+ constituency. Single-membership pages cannot exhibit this schema swap.
138
+
139
+ ## Uncertainties
140
+
141
+ - Production UI acceptance was not available during diagnosis.
142
+ - The exact membership insertion order on the reported page was not inspected. It is
143
+ unnecessary to establish the defect because the API is under-specified for
144
+ any multi-membership page, but it would explain why this particular page
145
+ resolves to Files after refetch.
146
+
147
+ ## Recommendation
148
+
149
+ Make property database context explicit end to end:
150
+
151
+ 1. Add exact `databaseId` context to `list-document-properties` and validate
152
+ that the page is a member of that accessible database.
153
+ 2. Include `{ documentId, databaseId }` in the query key.
154
+ 3. Pass the active `databaseId` from `DatabaseItemPreview` to
155
+ `DocumentProperties`, every value/definition mutation, hidden-property
156
+ controls, and `+ Add property`.
157
+ 4. Preserve the originating database id when `Open Page` navigates, then use it
158
+ in the full-page Info rail.
159
+ 5. Keep an ordered non-system fallback only for context-free entry points; do
160
+ not treat it as equivalent to explicit context.
161
+
162
+ Do not patch the color picker or merely add `orderBy` to the ambiguous resolver.
163
+ Those would quiet one ghost while leaving the house politely haunted.
164
+
165
+ ## Acceptance story
166
+
167
+ Given a page that belongs to Files and at least one user database:
168
+
169
+ 1. Opening it from a user database preview shows that database's exact scalar
170
+ and Blocks fields.
171
+ 2. Selecting and changing colored Select, Status, and Multi-select values keeps
172
+ the same schema before the optimistic update, after the action response, and
173
+ after the invalidated query refetch.
174
+ 3. `+ Add property`, hidden-property changes, rename/reorder/delete, and value
175
+ edits mutate only the active user database.
176
+ 4. `Open Page` followed by opening Info shows the same database's fields.
177
+ 5. Opening the same page from Files shows Files fields, and opening it from a
178
+ second user database shows that second database's fields.
179
+ 6. A forged or inaccessible `databaseId` fails closed without revealing or
180
+ mutating another database.
181
+ 7. Real-interface coverage exercises the sidebar preview and full-page Info rail
182
+ in the Builder workspace after deployment.
183
+
184
+ Visual baseline for steps 1 and 4: the preview must not regress to the supplied
185
+ `Agencies` screenshot's `Kind` / `Parent` / `Source` schema when opened from the
186
+ user database. The full page may continue to omit properties above the body, as
187
+ shown in the comparison screenshot, but opening Info must reveal the originating
188
+ database's exact fields.
189
+
190
+ ## Shaped implementation boundary
191
+
192
+ - **Outcome:** preserve the active database's property schema and mutations
193
+ across preview edits and full-page navigation.
194
+ - **Shipping surface:** `BuilderIO/agent-native`, Content database preview and
195
+ full-page Info rail, for Content users with multi-membership pages.
196
+ - **Durable destination:** the public Content template on the repository's
197
+ integration branch through an ordinary reviewed pull request and later merge.
198
+ - **Governing architecture:** actions remain the source of truth; database
199
+ context is explicit, validated, and carried in action/query/navigation state.
200
+ - **Public product boundary:** any Content developer can reproduce this with the
201
+ public SQL schema and a local dual-membership page; it needs no private source
202
+ material, machine state, credentials, or orchestration, so the fix belongs in
203
+ the public template.
204
+ - **Risk strategy:** system-ready, with a fail-closed authorization regression
205
+ and deployed Builder workspace acceptance before calling it shipped; no
206
+ feature flag is necessary for the bounded fix.
207
+
208
+ ## Work evidence
209
+
210
+ The bounded fix now carries the exact `databaseId` through property reads,
211
+ `{ documentId, databaseId }` query keys, definition and value mutations,
212
+ preview-to-page navigation, and the full-page Info rail. Explicit context is
213
+ validated against both database access and the page's exact membership. A
214
+ forged, inaccessible, or wrong-database id fails before either reading fields or
215
+ creating a definition. Context-free direct page entry keeps the existing
216
+ fallback without treating it as equivalent to a database-originated route.
217
+
218
+ Automated acceptance under Node 24 is green:
219
+
220
+ - `pnpm typecheck`;
221
+ - 142 focused tests across the property, cache, navigation, and database
222
+ lifecycle surfaces;
223
+ - the full Content suite: 151 files passed, 1 skipped; 1,850 tests passed, 3
224
+ expected failures, and 5 skipped; and
225
+ - the production build, with only the repository's existing doctor and
226
+ optional dynamic-import warnings.
227
+
228
+ The database lifecycle regression creates one page in Files and a user
229
+ database, proves exact schemas for both contexts, rejects a wrong-database
230
+ rename without changing either schema, creates a new property only in the
231
+ requested user database, and rejects forged and inaccessible database ids.
232
+
233
+ A root-run local real-interface pass used the same deterministic membership
234
+ shape. It confirmed that `Status` survives green `Active` and orange `Paused`
235
+ Select saves and their refetches; `QA Context Note` created from the user
236
+ preview appears only in that database; `Open page` preserves
237
+ both database query parameters; Info shows the user
238
+ fields; Files shows its own `Parent` and `Source` fields without either user
239
+ field; and returning to the user database restores both user fields. No console
240
+ errors occurred during that pass.
241
+
242
+ Exact-head deployed interface acceptance remains required before this work can
243
+ be called shipped; local interface evidence is supporting evidence only.
244
+
245
+ ## Sources
246
+
247
+ - Supplied, visually inspected preview and full-page comparison screenshots.
248
+ - Current repository source and the disposable migrated SQLite reproduction.
249
+ - Historical comparison: PR #2303 and PR #2344 in repository history.
@@ -0,0 +1,389 @@
1
+ # Content sidebar personal ordering
2
+
3
+ > SHAPE V3 APPROVED FOR WORK
4
+ >
5
+ > Alice supplied a concrete feedback recording and explicitly requested that the
6
+ > revised plan be shaped, implemented, and returned on PR #2423's existing
7
+ > preview. This revision supersedes the earlier handle-and-menu interaction
8
+ > plan while retaining its personal-order persistence boundary.
9
+ >
10
+ > Alice's July 28 follow-up clip clarifies the same approved interaction story;
11
+ > it does not add a shipping surface or change the persistence boundary. The
12
+ > clarifications below are tracked as v3.1 implementation and acceptance
13
+ > evidence under the existing fingerprint.
14
+
15
+ ## Refresher
16
+
17
+ Content now supports personal custom order for Pinned references, workspace
18
+ roots, and each workspace's Files list. The first implementation proved the
19
+ data boundary but exposed too much implementation chrome: visible grip handles,
20
+ full-width `Order: Custom` rows, and overflow commands for moving an item.
21
+ Pointer dragging could also escape horizontally and create an oversized scroll
22
+ region, and its landing position was not explicit enough.
23
+
24
+ Alice's July 27 feedback establishes the revised interaction:
25
+
26
+ - The primary surface of a reorderable sidebar row is the drag target. There is
27
+ no dedicated visible grip.
28
+ - Drag motion is vertical and bounded to valid visible slots in its current
29
+ list. A clear horizontal insertion bar shows the landing slot.
30
+ - Interactive children such as expand, add, overflow, and sort controls remain
31
+ ordinary controls and never initiate a drag.
32
+ - Keyboard dragging remains available from the focusable primary row; the new
33
+ `Move up`, `Move down`, and `Move to position` overflow commands are removed.
34
+ - In an expanded workspace, a compact sort icon next to its add button replaces
35
+ the separate `Order: Custom` row and opens `Custom`, `Last edited`, `Name`,
36
+ and `Created`; collapsed workspaces stay data-lazy.
37
+ - Workspace folder icons and labels share one visual baseline.
38
+ - The editor block preview stays aligned to the point where the user grabbed
39
+ the block instead of floating below the pointer.
40
+
41
+ All sidebar dragging changes only the current viewer's order. It never reparents
42
+ a document, moves it between workspaces, changes access or ownership, or
43
+ rewrites shared Files membership.
44
+
45
+ ## July 28 feedback clarification (v3.1)
46
+
47
+ The second preview review showed four defects inside the frozen v3 story:
48
+
49
+ - Releasing a pointer drag on a sidebar row can still activate its link. The
50
+ release must commit the reorder without navigating; a later ordinary click
51
+ must continue to navigate normally.
52
+ - The primary row advertises a grab cursor before a drag exists. It should use
53
+ the app's ordinary pointer cursor at rest and switch to dragging feedback only
54
+ after the activation threshold is crossed.
55
+ - Long row and workspace labels reserve action-button space even while those
56
+ actions are hidden. At rest, text may use the full available row width and
57
+ ellipsize at the actual boundary; hover or focus reveals actions and contracts
58
+ the label immediately, without animation.
59
+ - Nested Files rows inherit a narrower right edge from their indentation
60
+ wrapper. Nesting changes only the left edge; overflow and add controls remain
61
+ aligned to the sidebar's shared right rail at every depth.
62
+
63
+ The clip also exposes a regression in the already-approved Toolkit assertion:
64
+ after a successful editor block drop, the moved block retains a visible text or
65
+ node selection and editor focus. Completing the drop must collapse incidental
66
+ selection and blur the editor while preserving the moved block and every
67
+ existing before/after, column, and cross-editor drop contract.
68
+
69
+ These points clarify assertions 2, 6, 9, 10, and 13 below. They restore the
70
+ intended click-versus-drag and editor-drop behavior; they do not change the
71
+ outcome, shipping surfaces, governing architecture, risk strategy, or durable
72
+ order model.
73
+
74
+ ## Interaction contract
75
+
76
+ ```text
77
+ NORMAL DRAGGING
78
+ ┌────────────────────────────┐ ┌────────────────────────────┐
79
+ │ PINNED │ │ PINNED │
80
+ │ Launch brief │ │ Launch brief │
81
+ │ Roadmap │ → │ ━ landing slot ━━━━━━━━━━ │
82
+ │ Research notes │ │ Roadmap │
83
+ └────────────────────────────┘ │ Research notes │
84
+ └────────────────────────────┘
85
+
86
+ Primary row: click opens; drag reorders; Space picks up for keyboard reorder
87
+ Row controls: expand/add/sort/overflow keep their ordinary click behavior
88
+ Movement: vertical, clamped to the current visible list, same-parent where needed
89
+
90
+ WORKSPACE HEADER
91
+ ┌───────────────────────────────────┐
92
+ │ ▾ Personal ⇅ + │
93
+ └───────────────────────────────────┘
94
+
95
+ └─ Custom / Last edited / Name / Created
96
+ ```
97
+
98
+ The insertion bar uses normal foreground contrast. It is a slot marker, not a
99
+ document hierarchy affordance. Files drops across parent boundaries remain
100
+ invalid; nesting still uses the explicit document-move capability.
101
+
102
+ ## Desired outcome
103
+
104
+ Each signed-in Content user can quietly arrange Pinned references, workspace
105
+ roots, and eligible Files siblings through a familiar row-drag interaction,
106
+ choose useful computed Files orders from the workspace header, and trust that
107
+ the operation affects only their personal navigation view.
108
+
109
+ ## Product decisions
110
+
111
+ | Surface | Durable order | Pointer interaction | Keyboard interaction | Order modes |
112
+ | --------------- | ------------------------------------------------ | -------------------------------------------------- | -------------------------------------- | ---------------------------------- |
113
+ | Pinned | Personal Pinned membership positions | Drag primary row | Focus row, Space/arrow reorder | Custom |
114
+ | Workspace roots | Personal Workspaces catalog membership positions | Drag primary row | Focus row, Space/arrow reorder | Custom |
115
+ | Workspace Files | Per-user database-view ordered membership IDs | Drag primary row in eligible Custom view | Focus row, Space/arrow reorder | Custom, Last edited, Name, Created |
116
+ | Editor blocks | Existing document structure | Existing block grip; preview preserves grab offset | Existing block-menu behavior unchanged | Not applicable |
117
+
118
+ Computed Files modes retain the saved Custom sequence. Manual Files reorder is
119
+ available only in `Custom` with no active grouping/filter ambiguity and only
120
+ within the visible sibling set. New references append; inaccessible or stale
121
+ IDs are ignored and pruned by the existing normalization path.
122
+
123
+ ## Architecture grounding and fit
124
+
125
+ Architecture grounding is required because one feedback item touches the
126
+ shared editor Toolkit.
127
+
128
+ ### Demonstrated callers
129
+
130
+ - Content sidebar user dragging Pinned, workspace, and Files rows in the PR
131
+ #2423 preview.
132
+ - Content `VisualEditor` user dragging a text block and observing its clone
133
+ below the pointer in the July 27 feedback recording.
134
+
135
+ ### Existing primitives and ownership boundaries
136
+
137
+ - `templates/content/app/components/sidebar/sidebar-reorder.tsx` owns the
138
+ Content-local sortable controller, personal-order semantics, keyboard sensor,
139
+ and announcements.
140
+ - `templates/content/app/components/editor/database/sidebar.tsx` owns Files
141
+ presentation and order-mode selection.
142
+ - `templates/content/app/components/sidebar/DocumentSidebar.tsx` owns workspace
143
+ headers and the Pinned/workspace integration.
144
+ - `packages/toolkit/src/editor/DragHandle.ts` owns the shared floating block
145
+ preview and drop geometry used by Content and Plan. Host apps own its CSS.
146
+
147
+ ### Legacy contracts that remain unchanged
148
+
149
+ - Exact Pinned/workspace membership persistence and per-user Files settings.
150
+ - Same-parent Files validation, optimistic rollback, and canonical refetch.
151
+ - Native link activation, modified click, middle click, context menu, focus, and
152
+ nested action controls.
153
+ - Toolkit block selection, action menu, before/after reorder, side-column drops,
154
+ cross-editor transfer, drop indicators, and wrapper configuration.
155
+
156
+ ### Smallest compatible delta
157
+
158
+ Keep sidebar sorting Content-local. Replace handle-only listeners with primary
159
+ row listeners, expose one slot indicator from the existing sortable context,
160
+ and bound pointer transforms to the list's vertical geometry without changing
161
+ the persistence actions. In Toolkit, record the pointer-to-source-block offset
162
+ when a drag begins and reuse that offset for the floating preview transform.
163
+
164
+ ### Deferred capabilities
165
+
166
+ - Shared Toolkit sidebar-sortable controller.
167
+ - Shared organization Files order.
168
+ - Drag-to-reparent or drag-to-move between workspaces.
169
+ - A permanently visible keyboard reorder menu.
170
+ - Rich auto-scroll for lists longer than the visible sidebar; this slice favors
171
+ bounded visible slots over runaway off-screen motion.
172
+
173
+ ### Evidence classification
174
+
175
+ Direct evidence:
176
+
177
+ - The July 27 clip demonstrates visible handles, horizontal escape, oversized
178
+ scrolling, absent landing clarity, block-preview offset, workspace icon
179
+ misalignment, the full-width order control, and move-command menu clutter.
180
+ - Current source shows the sidebar listeners attached only to
181
+ `SidebarDragHandle` and the Toolkit preview positioned with hard-coded pointer
182
+ offsets.
183
+
184
+ Inference:
185
+
186
+ - Preserving keyboard drag on the primary row satisfies the accessibility goal
187
+ without retaining the menus Alice asked to remove. This must be proven in the
188
+ real interface.
189
+
190
+ Unresolved owner questions: none.
191
+
192
+ ## Implementation plan
193
+
194
+ ### 1. Revise the Content-local reorder primitive
195
+
196
+ - Remove the exported visible drag-handle and move-command menu components.
197
+ - Expose sortable attributes/listeners as primary-row drag props.
198
+ - Track active and over IDs and expose a before/after slot indicator only for a
199
+ valid same-parent target.
200
+ - Force pointer transforms onto the vertical axis, clamp them to the current
201
+ reorder container, and suppress runaway auto-scroll.
202
+ - Preserve keyboard sensors, localized announcements, and optimistic reorder
203
+ callbacks.
204
+
205
+ ### 2. Apply row dragging across all three sidebar surfaces
206
+
207
+ - Put drag props on each row's primary link/surface, not on expand/add/sort or
208
+ overflow controls.
209
+ - Render the slot indicator at the correct row boundary.
210
+ - Remove reorder commands from Pinned, workspace, and Files overflow menus while
211
+ preserving pin, delete, add, and other non-reorder actions.
212
+ - Keep Files hierarchy and computed-mode guards intact.
213
+
214
+ ### 3. Simplify workspace order controls and alignment
215
+
216
+ - Lift the Files order menu into the workspace header next to `+` as an icon-only
217
+ shadcn dropdown with tooltip and mode-aware accessible name.
218
+ - Remove the separate full-width order row from `ContentFilesSidebarView`.
219
+ - Align folder/toggle icon and label within the same header flex geometry.
220
+
221
+ ### 4. Align the shared block drag preview
222
+
223
+ - Extend the Toolkit drag session with the pointer's offset from the source
224
+ block at mouse-down.
225
+ - Position the preview from that captured offset rather than fixed `+12/+10`
226
+ values.
227
+ - Add focused Toolkit tests covering offset capture and transform behavior and a
228
+ Toolkit changeset; keep every drop contract unchanged.
229
+
230
+ ### 5. Verify and return to the same preview
231
+
232
+ - Update focused component/source tests, i18n expectations, Content docs, and
233
+ the existing changelog entry if its wording becomes inaccurate.
234
+ - Run format, focused sidebar/Toolkit tests, Content typecheck, and the relevant
235
+ Content build.
236
+ - Obtain independent technical review for the final material diff.
237
+ - Run independent real-interface QA against the exact new PR head and the
238
+ existing dummy account/fixture.
239
+ - Commit and push the current task branch so Netlify updates
240
+ `deploy-preview-2423--agent-native-content.netlify.app`; verify the exact head
241
+ and interaction before returning the link.
242
+
243
+ ## Acceptance story
244
+
245
+ Successful-user story `content-sidebar-personal-order-v3`:
246
+
247
+ A signed-in Content user drags a Pinned row, workspace root, or eligible Files
248
+ row from its primary surface; the item stays inside the visible vertical list,
249
+ a clear insertion bar marks the landing slot, and reload preserves only that
250
+ user's order. Workspace order mode is chosen from the compact header icon.
251
+ Underlying documents and shared memberships never move. An editor block preview
252
+ stays aligned with its grab point.
253
+
254
+ Required assertions:
255
+
256
+ 1. No visible sidebar grip handles or reorder-only overflow commands remain.
257
+ 2. Dragging starts from the primary row surface while nested controls remain
258
+ independently clickable.
259
+ 3. Pointer motion is vertical and bounded; horizontal escape and giant drag
260
+ scroll regions do not occur.
261
+ 4. A visible insertion bar identifies every valid landing slot, including first
262
+ and last positions, and invalid cross-parent targets show no slot.
263
+ 5. Keyboard dragging remains operable from the primary row with accurate
264
+ localized announcements.
265
+ 6. Pinned, workspace, and eligible Files orders persist across reload and a
266
+ second tab without changing another user's order.
267
+ 7. Computed Files modes disable manual reorder and returning to Custom restores
268
+ the saved sequence.
269
+ 8. For an expanded workspace, the order icon sits beside `+`, exposes the
270
+ current mode accessibly, and opens all four order choices; the old full-width
271
+ row is absent and collapsed workspaces do not fetch their Files view.
272
+ 9. Folder/toggle icons and workspace labels share a consistent baseline.
273
+ 10. Row links preserve ordinary, modified, middle-click, context-menu, and
274
+ keyboard navigation behavior.
275
+ 11. Reorder never changes document parentage, canonical position, workspace,
276
+ access, visibility, sharing, ownership, or shared Files membership.
277
+ 12. Failed persistence rolls back visibly and refetches canonical state.
278
+ 13. Content and Plan block dragging retain existing drop behavior while the
279
+ floating preview preserves the pointer's source-block offset; completing a
280
+ successful drop leaves no incidental text/node selection or editor focus.
281
+
282
+ ## Architecture fingerprint and authority envelope
283
+
284
+ ```yaml
285
+ stage: work
286
+ authority-source: Alice's July 27 request to shape the new implementation plan, work it, and show the same preview
287
+ authorized-scope:
288
+ repositories: [builderio/agent-native]
289
+ product-surfaces:
290
+ - Content Pinned section
291
+ - Content workspace-root navigation
292
+ - Content workspace Files sidebar view
293
+ - shared Toolkit editor block drag preview used by Content and Plan
294
+ outcome: Quiet, bounded row-drag personal sidebar ordering with compact workspace sort controls and pointer-aligned editor block previews.
295
+ allowed-mutations:
296
+ - artifact-write
297
+ - branch
298
+ - commit
299
+ - push
300
+ - pull-request
301
+ - deploy
302
+ - ephemeral-test-resource
303
+ write-targets:
304
+ artifacts:
305
+ - templates/content/docs/solutions/content-sidebar-order-shape.md
306
+ production-source:
307
+ - templates/content/app
308
+ - templates/content/app/i18n
309
+ - templates/content/.agents/skills
310
+ - templates/content/changelog
311
+ - packages/toolkit/src/editor
312
+ - packages/toolkit tests
313
+ - .changeset
314
+ governing-artifact:
315
+ path: templates/content/docs/solutions/content-sidebar-order-shape.md
316
+ revision: shape-v3-feedback-approved
317
+ architecture-fingerprint:
318
+ outcome: Bounded primary-row sidebar dragging, compact Files ordering, and aligned shared block preview geometry.
319
+ shipping-surfaces:
320
+ - id: content-pinned-custom-order
321
+ repository: builderio/agent-native
322
+ product-surface: Content sidebar Pinned section
323
+ constituency: signed-in Content users
324
+ durable-destination: user-scoped Pinned membership positions
325
+ integration-action: merge
326
+ - id: content-workspace-custom-order
327
+ repository: builderio/agent-native
328
+ product-surface: Content workspace-root navigation
329
+ constituency: signed-in Content users
330
+ durable-destination: user-scoped Workspaces catalog membership positions
331
+ integration-action: merge
332
+ - id: content-files-sidebar-order
333
+ repository: builderio/agent-native
334
+ product-surface: Content workspace Files sidebar view
335
+ constituency: signed-in Content workspace viewers
336
+ durable-destination: per-user database personal-view settings
337
+ integration-action: merge
338
+ - id: toolkit-editor-drag-preview-alignment
339
+ repository: builderio/agent-native
340
+ product-surface: shared Toolkit editor drag preview
341
+ constituency: Content and Plan editor users
342
+ durable-destination: packages/toolkit editor primitive
343
+ integration-action: merge
344
+ governing-architecture: Content owns personal sidebar ordering; Toolkit owns shared block-preview geometry; neither path changes document hierarchy or authorization.
345
+ acceptance-story:
346
+ id: content-sidebar-personal-order-v3
347
+ summary: The successful-user story and thirteen required assertions above.
348
+ risk-strategy:
349
+ kind: system-ready
350
+ production-validation-after-merge: false
351
+ architecture-grounding:
352
+ applicability: required
353
+ status: grounded
354
+ smallest-compatible-delta: Content-only sidebar interaction revision plus one pointer-offset correction in the existing shared Toolkit primitive.
355
+ unresolved-owner-questions: []
356
+ test-resources:
357
+ - id: pr2423-sidebar-fixture
358
+ kind: account
359
+ surface: https://deploy-preview-2423--agent-native-content.netlify.app
360
+ ownership-marker: sidebar-fixture-2423-20260727@example.com and pages 3Bhw76VZaFfk, be8GwXDPsSdj, UdCg05CsA0M6
361
+ allowed-actions: [acquire, exercise, update]
362
+ cleanup-trigger: after Alice completes preview validation or preview teardown
363
+ cleanup-method: delete the dummy preview account and its task-created pages through the preview UI/action surface
364
+ cleanup-proof: authenticated absence check for the exact email and page IDs
365
+ shared-impact: none
366
+ isolation: branch-preview
367
+ ownership: task-exclusive
368
+ production-data: false
369
+ customer-data: false
370
+ cost: none
371
+ status: active
372
+ phase: work
373
+ ledger-revision: content-sidebar-order-work-v3
374
+ status: active
375
+ ```
376
+
377
+ ## Non-goals
378
+
379
+ - Reparenting documents or moving them between workspaces.
380
+ - Shared organization ordering.
381
+ - New persistence actions or schema changes.
382
+ - A general Toolkit sidebar navigation API.
383
+ - Merge or production enablement; this Work unit ends at the updated PR preview.
384
+
385
+ ## Natural next stage
386
+
387
+ After the exact PR head passes technical and independent real-interface evidence,
388
+ return the same preview for Alice's validation. Merge remains a separate `/land`
389
+ decision.