@codemem/server 0.39.1 → 0.40.0

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.
package/static/app.js.br CHANGED
Binary file
package/static/app.js.gz CHANGED
Binary file
package/static/index.html CHANGED
@@ -200,7 +200,7 @@
200
200
  padding: var(--sp-3) var(--sp-4);
201
201
  border: none;
202
202
  background: transparent;
203
- color: var(--text-tertiary);
203
+ color: var(--text-secondary);
204
204
  font-family: var(--font-sans);
205
205
  font-size: var(--font-size-md);
206
206
  font-weight: var(--font-weight-medium);
@@ -213,10 +213,16 @@
213
213
  }
214
214
 
215
215
  .tab-btn.active {
216
- color: var(--accent);
216
+ color: var(--accent-hover);
217
217
  font-weight: var(--font-weight-semibold);
218
218
  }
219
219
 
220
+ #recipientPolicyManagementMount .small,
221
+ .recipient-policy-management-dialog .small,
222
+ #recipientPolicySharingMount .small {
223
+ color: var(--text-secondary);
224
+ }
225
+
220
226
  .tab-btn.active::after {
221
227
  content: "";
222
228
  position: absolute;
@@ -1129,6 +1135,198 @@
1129
1135
  margin-top: var(--sp-2);
1130
1136
  }
1131
1137
  .projects-pagination { margin-top: var(--sp-4); }
1138
+ .recipient-policy-review > h3 { margin-top: var(--sp-4); }
1139
+ .recipient-policy-review-status:empty { display: none; }
1140
+ .recipient-policy-review-list { margin-top: var(--sp-3); }
1141
+ .recipient-policy-review-item .project-inventory-actions label {
1142
+ color: var(--text-secondary);
1143
+ font-size: var(--font-size-sm);
1144
+ font-weight: var(--font-weight-semibold);
1145
+ }
1146
+ .recipient-policy-review-select { min-width: min(100%, 280px); }
1147
+ .recipient-policy-deferred { margin-top: var(--sp-3); }
1148
+ .recipient-policy-preview { margin-top: var(--sp-3); }
1149
+ .recipient-policy-preview-list { margin-top: var(--sp-2); }
1150
+ .recipient-policy-preview-list ul {
1151
+ margin-top: var(--sp-1);
1152
+ padding-left: var(--sp-5);
1153
+ }
1154
+ .recipient-policy-blocked-heading { margin-top: var(--sp-5) !important; }
1155
+ .project-selection-actions,
1156
+ .recipient-policy-management-actions,
1157
+ .recipient-policy-sharing-actions {
1158
+ align-items: center;
1159
+ flex-wrap: wrap;
1160
+ }
1161
+ .project-selection-target,
1162
+ .recipient-policy-management-target,
1163
+ .recipient-policy-sharing-target-24 {
1164
+ min-width: 24px;
1165
+ min-height: 24px;
1166
+ }
1167
+ .project-selection-control {
1168
+ display: inline-flex;
1169
+ align-items: center;
1170
+ justify-content: center;
1171
+ flex: 0 0 32px;
1172
+ min-width: 32px;
1173
+ min-height: 32px;
1174
+ cursor: pointer;
1175
+ }
1176
+ .project-selection-checkbox { width: 18px; height: 18px; }
1177
+ .project-recipient-summary { margin-top: var(--sp-3); }
1178
+ .project-recipient-status { color: var(--text-secondary); font-size: var(--font-size-sm); }
1179
+ .project-recipient-chips {
1180
+ display: flex;
1181
+ flex-wrap: wrap;
1182
+ gap: var(--sp-2);
1183
+ padding: 0;
1184
+ margin: var(--sp-2) 0 0;
1185
+ list-style: none;
1186
+ }
1187
+ .project-recipient-chip {
1188
+ padding: 3px 9px;
1189
+ border: 1px solid var(--border);
1190
+ border-radius: var(--radius-pill);
1191
+ background: var(--surface-2);
1192
+ color: var(--text-primary);
1193
+ font-size: var(--font-size-xs);
1194
+ }
1195
+ .project-advanced-administration { margin-top: var(--sp-3); }
1196
+ .project-advanced-surface summary,
1197
+ .advanced-administration-disclosure > summary {
1198
+ cursor: pointer;
1199
+ color: var(--text-primary);
1200
+ font-weight: var(--font-weight-semibold);
1201
+ }
1202
+ .recipient-policy-management-dialog .modal-card { width: min(720px, calc(100vw - 32px)); }
1203
+ .recipient-policy-management-selection fieldset { border: 0; padding: 0; margin: var(--sp-4) 0 0; }
1204
+ .recipient-policy-management-selection legend { font-weight: var(--font-weight-semibold); }
1205
+ .recipient-policy-management-review section + section { margin-top: var(--sp-4); }
1206
+ .recipient-policy-management-review h3 { margin: 0 0 var(--sp-2); }
1207
+ .recipient-policy-management-review p,
1208
+ .recipient-policy-management-review ul { margin-top: var(--sp-2); }
1209
+ .recipient-policy-management-review ul,
1210
+ .recipient-policy-management-details ul { padding-left: var(--sp-5); }
1211
+ .recipient-policy-management-name { overflow-wrap: anywhere; }
1212
+ .recipient-policy-management-choice > span { min-width: 0; }
1213
+ .recipient-policy-management-description,
1214
+ .recipient-policy-management-member-names,
1215
+ .recipient-policy-management-recipient-context,
1216
+ .recipient-policy-management-review li,
1217
+ .recipient-policy-management-review li span {
1218
+ min-width: 0;
1219
+ overflow-wrap: anywhere;
1220
+ }
1221
+ .recipient-policy-management-details {
1222
+ margin-top: var(--sp-3);
1223
+ color: var(--text-secondary);
1224
+ }
1225
+ .recipient-policy-management-details summary {
1226
+ color: var(--text-primary);
1227
+ cursor: pointer;
1228
+ font-weight: var(--font-weight-semibold);
1229
+ }
1230
+ .recipient-policy-management-details p { margin-top: var(--sp-2); }
1231
+ .recipient-policy-management-details li { overflow-wrap: anywhere; }
1232
+ .recipient-policy-management-status:empty { display: none; }
1233
+ .recipient-policy-sharing-header { margin-bottom: var(--sp-4); }
1234
+ .recipient-policy-sharing-tabs {
1235
+ position: static;
1236
+ display: flex;
1237
+ gap: var(--sp-1);
1238
+ margin-bottom: var(--sp-4);
1239
+ padding: 0;
1240
+ background: transparent;
1241
+ border: 0;
1242
+ z-index: auto;
1243
+ }
1244
+ .recipient-policy-sharing-tabs .tab-btn { color: var(--text-secondary); }
1245
+ .recipient-policy-sharing-tabs .tab-btn.active { color: var(--text-primary); }
1246
+ .recipient-policy-sharing-grid { display: grid; gap: var(--sp-3); }
1247
+ .recipient-policy-sharing-card { border: 1px solid var(--border); border-radius: var(--radius-md); }
1248
+ .recipient-policy-sharing-card-title {
1249
+ display: flex;
1250
+ align-items: center;
1251
+ justify-content: space-between;
1252
+ gap: var(--sp-3);
1253
+ }
1254
+ .recipient-policy-sharing-card-title h3 { margin: 0; }
1255
+ .recipient-policy-sharing-details { display: grid; gap: var(--sp-3); margin: var(--sp-4) 0; }
1256
+ .recipient-policy-sharing-details div {
1257
+ display: grid;
1258
+ grid-template-columns: minmax(150px, max-content) 1fr;
1259
+ gap: var(--sp-3);
1260
+ }
1261
+ .recipient-policy-sharing-details dt { color: var(--text-secondary); }
1262
+ .recipient-policy-sharing-details dd { margin: 0; color: var(--text-primary); }
1263
+ .recipient-policy-invitation-result {
1264
+ display: flex;
1265
+ align-items: flex-start;
1266
+ gap: var(--sp-3);
1267
+ padding: var(--sp-4);
1268
+ border: 1px solid color-mix(in srgb, var(--status-healthy) 36%, var(--border));
1269
+ border-radius: var(--radius-md);
1270
+ background: color-mix(in srgb, var(--status-healthy) 9%, var(--surface-1));
1271
+ }
1272
+ .recipient-policy-invitation-result:focus {
1273
+ outline: 2px solid var(--accent);
1274
+ outline-offset: 2px;
1275
+ box-shadow: 0 0 0 4px var(--focus-ring);
1276
+ }
1277
+ .recipient-policy-invitation-result-mark {
1278
+ display: inline-flex;
1279
+ align-items: center;
1280
+ justify-content: center;
1281
+ flex: 0 0 28px;
1282
+ width: 28px;
1283
+ height: 28px;
1284
+ border-radius: var(--radius-pill);
1285
+ background: color-mix(in srgb, var(--status-healthy) 18%, var(--surface-0));
1286
+ color: var(--status-healthy);
1287
+ font-weight: var(--font-weight-semibold);
1288
+ line-height: 1;
1289
+ }
1290
+ .recipient-policy-invitation-result-copy { min-width: 0; }
1291
+ .recipient-policy-invitation-result-copy h3 { margin: 0; }
1292
+ .recipient-policy-invitation-result-copy p {
1293
+ margin-top: var(--sp-2);
1294
+ color: var(--text-secondary);
1295
+ overflow-wrap: anywhere;
1296
+ }
1297
+
1298
+ #devicesMount .recipient-policy-sharing-grid {
1299
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
1300
+ list-style: none;
1301
+ padding: 0;
1302
+ }
1303
+ #devicesMount .recipient-policy-sharing-card { height: 100%; }
1304
+ #devicesMount .recipient-policy-sharing-card section + section { margin-top: var(--sp-4); }
1305
+ #devicesMount .recipient-policy-sharing-card section ul {
1306
+ display: grid;
1307
+ gap: var(--sp-2);
1308
+ margin-top: var(--sp-2);
1309
+ padding-left: var(--sp-5);
1310
+ }
1311
+ #devicesMount .recipient-policy-sharing-card > .settings-button { margin-top: var(--sp-4); }
1312
+
1313
+ @media (max-width: 720px) {
1314
+ .project-inventory-row-header { align-items: center; flex-wrap: wrap; }
1315
+ .project-inventory-title { flex: 1 1 calc(100% - 48px); }
1316
+ .project-recipient-action { width: 100%; }
1317
+ .recipient-policy-management-dialog .modal-card { width: calc(100vw - 16px); }
1318
+ .recipient-policy-management-actions,
1319
+ .recipient-policy-sharing-responsive-actions { display: grid; grid-template-columns: 1fr; }
1320
+ .recipient-policy-management-actions button,
1321
+ .recipient-policy-sharing-responsive-actions button { min-height: 44px; width: 100%; }
1322
+ .recipient-policy-sharing-responsive-tabs { overflow-x: auto; }
1323
+ .recipient-policy-sharing-details div { grid-template-columns: 1fr; gap: var(--sp-1); }
1324
+ .recipient-policy-invitation-result { padding: var(--sp-3); }
1325
+ #devicesMount .recipient-policy-sharing-card > .settings-button {
1326
+ min-height: 44px;
1327
+ width: 100%;
1328
+ }
1329
+ }
1132
1330
 
1133
1331
  /* 36×36 square icon buttons — theme toggle, settings gear. */
1134
1332
  .icon-button {
@@ -2635,7 +2833,7 @@
2635
2833
  font-size: var(--font-size-sm);
2636
2834
  transition: border-color var(--duration-fast) var(--ease-standard), background var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard);
2637
2835
  }
2638
- .modal-close-button:hover {
2836
+ .modal-close-button:hover:not(:disabled) {
2639
2837
  border-color: var(--border-hover);
2640
2838
  background: color-mix(in srgb, var(--surface-0) 92%, var(--control-hover-bg));
2641
2839
  color: var(--text-primary);
@@ -2645,6 +2843,13 @@
2645
2843
  outline-offset: 2px;
2646
2844
  box-shadow: 0 0 0 4px var(--focus-ring);
2647
2845
  }
2846
+ .modal-close-button:disabled {
2847
+ border-color: var(--border);
2848
+ background: var(--surface-1);
2849
+ color: var(--text-tertiary);
2850
+ cursor: not-allowed;
2851
+ opacity: 0.65;
2852
+ }
2648
2853
  .modal-close-button-icon {
2649
2854
  display: inline-flex;
2650
2855
  align-items: center;
@@ -3413,13 +3618,15 @@
3413
3618
 
3414
3619
  <!-- ── Tab bar ─────────────────────────────────────────── -->
3415
3620
  <nav class="tab-bar" aria-label="Main navigation">
3416
- <button class="tab-btn active" id="tabBtn-feed">Feed</button>
3621
+ <button class="tab-btn active" id="tabBtn-feed" aria-current="page">Feed</button>
3417
3622
  <button class="tab-btn" id="tabBtn-projects">Projects</button>
3418
- <button class="tab-btn" id="tabBtn-sync">Sync</button>
3623
+ <button class="tab-btn" id="tabBtn-sharing">Sharing</button>
3624
+ <button class="tab-btn" id="tabBtn-devices">Devices</button>
3419
3625
  <button class="tab-btn" id="tabBtn-health">Health</button>
3420
- <button class="tab-btn" id="tabBtn-coordinator-admin">Teams</button>
3626
+ <button class="tab-btn" id="tabBtn-advanced">Advanced</button>
3421
3627
  </nav>
3422
3628
  <div id="toastRoot"></div>
3629
+ <div id="recipientPolicyManagementMount"></div>
3423
3630
  <div class="viewer-reconnect-overlay" id="viewerReconnectOverlay" hidden>
3424
3631
  <div class="viewer-reconnect-card" role="status" aria-live="assertive">
3425
3632
  <div class="viewer-reconnect-eyebrow">Viewer connection</div>
@@ -3713,11 +3920,16 @@
3713
3920
 
3714
3921
  <!-- ── Tab: Projects ───────────────────────────────────── -->
3715
3922
  <div class="tab-panel" id="tab-projects" hidden>
3923
+ <div id="recipientPolicyReviewMount" hidden></div>
3716
3924
  <div class="card" style="animation-delay: 0s">
3717
3925
  <div class="section-header">
3718
3926
  <div>
3719
- <h2>Projects & Sharing domains</h2>
3720
- <div class="section-meta">Choose which Sharing domain future memories use. “Stays on this device” means no Sharing domain is assigned yet, so it belongs in Projects review rather than Sync triage.</div>
3927
+ <h2>Projects</h2>
3928
+ <div class="section-meta">Choose exact Projects, then share them with Teams or Identities.</div>
3929
+ </div>
3930
+ <div class="section-actions project-selection-actions">
3931
+ <span class="section-meta" id="projectsSelectionStatus" role="status" aria-live="polite">0 Projects selected.</span>
3932
+ <button class="settings-button project-selection-target" id="projectsShareSelected" type="button" disabled>Share selected</button>
3721
3933
  </div>
3722
3934
  </div>
3723
3935
  <div class="projects-toolbar">
@@ -3743,13 +3955,42 @@
3743
3955
  <button class="settings-button" id="projectsNextPage" type="button">Next</button>
3744
3956
  </div>
3745
3957
  </div>
3958
+ <details class="card project-advanced-surface">
3959
+ <summary>Advanced Project invitations</summary>
3960
+ <div class="section-meta">Use the legacy invitation flow when the recipient does not have an Identity yet.</div>
3961
+ <div class="section-actions" id="projectShareFlowMount"></div>
3962
+ </details>
3963
+ </div>
3964
+
3965
+ <!-- ── Tab: Sharing ────────────────────────────────────── -->
3966
+ <div class="tab-panel" id="tab-sharing" hidden>
3967
+ <div class="card" id="recipientPolicySharingMount"></div>
3968
+ </div>
3969
+
3970
+ <!-- ── Tab: Devices ────────────────────────────────────── -->
3971
+ <div class="tab-panel" id="tab-devices" hidden>
3972
+ <div class="card" id="devicesMount"></div>
3746
3973
  </div>
3747
3974
 
3748
- <!-- ── Tab: Sync ───────────────────────────────────────── -->
3749
- <div class="tab-panel" id="tab-sync" hidden>
3975
+ <!-- ── Tab: Advanced ───────────────────────────────────── -->
3976
+ <div class="tab-panel" id="tab-advanced" hidden>
3977
+ <div class="card">
3978
+ <div class="section-header">
3979
+ <div>
3980
+ <h2>Advanced</h2>
3981
+ <div class="section-meta">Compatibility tools for device sync and Team administration.</div>
3982
+ </div>
3983
+ <div class="section-actions" aria-label="Advanced sections">
3984
+ <button class="settings-button" id="advancedSyncButton" type="button" aria-pressed="true">Sync</button>
3985
+ <button class="settings-button" id="advancedTeamsButton" type="button" aria-pressed="false">Teams</button>
3986
+ </div>
3987
+ </div>
3988
+ </div>
3989
+
3990
+ <div id="advancedSyncContent">
3750
3991
 
3751
- <!-- Sub-view: main Sync surface. Toggled by syncViewController
3752
- based on #sync vs #sync/diagnostics in the URL hash. -->
3992
+ <!-- Sub-view: main Sync surface. Toggled by syncViewController and
3993
+ app compatibility routing for canonical and legacy hashes. -->
3753
3994
  <div id="syncMainView">
3754
3995
 
3755
3996
  <!-- 1. Needs attention + team setup/status -->
@@ -3760,8 +4001,9 @@
3760
4001
  <span class="sync-online-badge" id="syncOnlineBadge" hidden role="status" aria-live="polite"></span>
3761
4002
  </div>
3762
4003
  <div class="section-actions">
4004
+ <button class="settings-button" id="syncShareProjectsButton" type="button">Share projects</button>
3763
4005
  <button class="settings-button" id="syncNowButton">Sync now</button>
3764
- <a class="sync-subview-link" href="#sync/diagnostics">View diagnostics &rarr;</a>
4006
+ <a class="sync-subview-link" href="#advanced/sync/diagnostics">View diagnostics &rarr;</a>
3765
4007
  </div>
3766
4008
  </div>
3767
4009
  <div class="section-meta" id="syncTeamMeta">Start with the next step below, then review team status and device details.</div>
@@ -3778,7 +4020,15 @@
3778
4020
  <div class="actor-create-row" id="syncJoinPanel">
3779
4021
  <label for="syncJoinInvite" class="sr-only">Team invite or pairing payload</label>
3780
4022
  <textarea class="feed-search" id="syncJoinInvite" placeholder="Paste a team invite or device pairing payload"></textarea>
3781
- <button class="settings-button" id="syncJoinButton">Accept</button>
4023
+ <div id="syncProjectInviteReview" role="region" aria-labelledby="syncProjectInviteReviewHeading" hidden>
4024
+ <h4 id="syncProjectInviteReviewHeading" tabindex="-1">Review project invitation</h4>
4025
+ <div class="section-meta" id="syncProjectInviteContext"></div>
4026
+ <label for="syncRecipientName">Your name</label>
4027
+ <input class="feed-search" id="syncRecipientName" maxlength="120" autocomplete="name" />
4028
+ <label for="syncRecipientDeviceName">This device</label>
4029
+ <input class="feed-search" id="syncRecipientDeviceName" maxlength="120" />
4030
+ </div>
4031
+ <button class="settings-button" id="syncJoinButton">Review invite</button>
3782
4032
  </div>
3783
4033
  </div>
3784
4034
  <div id="syncAdminSection">
@@ -3797,6 +4047,13 @@
3797
4047
  <div class="card" style="animation-delay: 0.04s">
3798
4048
  <h2>People &amp; devices</h2>
3799
4049
 
4050
+ <h3 class="settings-group-title">Project sharing</h3>
4051
+ <div class="section-meta" id="syncProjectShareOperationsMeta">Loading project sharing status…</div>
4052
+ <div class="actor-list" id="syncProjectShareOperations" aria-live="polite"></div>
4053
+
4054
+ <details class="project-inventory-details" style="margin-top: 20px">
4055
+ <summary>Manual device and identity controls</summary>
4056
+
3800
4057
  <h3 class="settings-group-title">People</h3>
3801
4058
  <div class="section-meta" id="syncActorsMeta">Create and rename people here. Assign each device below.</div>
3802
4059
  <div class="actor-create-row">
@@ -3826,6 +4083,7 @@
3826
4083
  <div id="syncPairingDisclosureMount" style="display: contents"></div>
3827
4084
  </div>
3828
4085
  <div id="syncPairingPanelMount" style="display: contents"></div>
4086
+ </details>
3829
4087
 
3830
4088
  <div id="syncSharingReview" hidden>
3831
4089
  <h3 class="settings-group-title" style="margin-top: 20px">What teammates will receive</h3>
@@ -3846,13 +4104,13 @@
3846
4104
 
3847
4105
  </div><!-- /#syncMainView -->
3848
4106
 
3849
- <!-- Sub-view: Advanced diagnostics. Reached via #sync/diagnostics;
3850
- shown by syncViewController when that hash is active. -->
4107
+ <!-- Sub-view: Advanced diagnostics. Canonically reached through
4108
+ #advanced/sync/diagnostics; #sync/diagnostics remains compatible. -->
3851
4109
  <div id="syncDiagnosticsView" hidden>
3852
4110
  <div class="card" style="animation-delay: 0.06s">
3853
4111
  <div class="section-header">
3854
4112
  <div class="section-header-title">
3855
- <a class="sync-subview-link" href="#sync">&larr; Back to sync</a>
4113
+ <a class="sync-subview-link" href="#advanced/sync">&larr; Back to sync</a>
3856
4114
  <h2>Sync diagnostics</h2>
3857
4115
  </div>
3858
4116
  <div class="section-actions">
@@ -3875,10 +4133,17 @@
3875
4133
  <div class="attempts-list" id="syncAttempts"></div>
3876
4134
  </div>
3877
4135
  </div><!-- /#syncDiagnosticsView -->
3878
- </div>
3879
-
3880
- <div class="tab-panel" id="tab-coordinator-admin" hidden>
3881
- <div id="coordinatorAdminMount"></div>
4136
+ </div><!-- /#advancedSyncContent -->
4137
+
4138
+ <div id="advancedTeamsContent" hidden>
4139
+ <div class="card">
4140
+ <details class="advanced-administration-disclosure" open>
4141
+ <summary>Advanced Team administration</summary>
4142
+ <div class="section-meta">Manage legacy enrollment, Spaces, device administration, and coordinator settings.</div>
4143
+ <div id="coordinatorAdminMount"></div>
4144
+ </details>
4145
+ </div>
4146
+ </div>
3882
4147
  </div>
3883
4148
 
3884
4149
  <script src="/assets/app.js"></script>