@codemem/server 0.33.0-alpha.3 → 0.34.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/dist/index.js +146 -6
- package/dist/index.js.map +1 -1
- package/dist/routes/stats.d.ts.map +1 -1
- package/dist/routes/sync.d.ts.map +1 -1
- package/package.json +2 -2
- package/static/app.js +485 -533
- package/static/index.html +340 -447
- package/static/themes.css +143 -0
- package/static/tokens.css +156 -0
package/static/app.js
CHANGED
|
@@ -3146,11 +3146,11 @@
|
|
|
3146
3146
|
const controller = new AbortController();
|
|
3147
3147
|
const timeoutId = window.setTimeout(() => controller.abort(), timeoutMs);
|
|
3148
3148
|
try {
|
|
3149
|
-
const resp = await fetch("/api/
|
|
3149
|
+
const resp = await fetch("/api/runtime", {
|
|
3150
3150
|
cache: "no-store",
|
|
3151
3151
|
signal: controller.signal
|
|
3152
3152
|
});
|
|
3153
|
-
if (!resp.ok) throw new Error(`/api/
|
|
3153
|
+
if (!resp.ok) throw new Error(`/api/runtime: ${resp.status} ${resp.statusText}`);
|
|
3154
3154
|
} finally {
|
|
3155
3155
|
window.clearTimeout(timeoutId);
|
|
3156
3156
|
}
|
|
@@ -3509,6 +3509,71 @@
|
|
|
3509
3509
|
}, 1200);
|
|
3510
3510
|
}
|
|
3511
3511
|
//#endregion
|
|
3512
|
+
//#region src/lib/keyboard.ts
|
|
3513
|
+
var FORM_CONTROL_TAGS = new Set([
|
|
3514
|
+
"BUTTON",
|
|
3515
|
+
"A",
|
|
3516
|
+
"SELECT"
|
|
3517
|
+
]);
|
|
3518
|
+
var INPUT_TYPES_WITH_NATIVE_ENTER = new Set([
|
|
3519
|
+
"button",
|
|
3520
|
+
"checkbox",
|
|
3521
|
+
"color",
|
|
3522
|
+
"file",
|
|
3523
|
+
"image",
|
|
3524
|
+
"radio",
|
|
3525
|
+
"range",
|
|
3526
|
+
"reset",
|
|
3527
|
+
"submit"
|
|
3528
|
+
]);
|
|
3529
|
+
function shouldIgnoreTarget(target) {
|
|
3530
|
+
if (!target) return false;
|
|
3531
|
+
if (typeof target.closest !== "function") return false;
|
|
3532
|
+
return target.closest("[data-primary-action-ignore=\"true\"]") !== null;
|
|
3533
|
+
}
|
|
3534
|
+
function isTextareaOrEditable(target) {
|
|
3535
|
+
if (!target) return false;
|
|
3536
|
+
if (target instanceof HTMLTextAreaElement) return true;
|
|
3537
|
+
if ("isContentEditable" in target && target.isContentEditable) return true;
|
|
3538
|
+
return false;
|
|
3539
|
+
}
|
|
3540
|
+
function hasNativeEnterBehavior(target) {
|
|
3541
|
+
if (!target) return false;
|
|
3542
|
+
if (FORM_CONTROL_TAGS.has(target.tagName)) return true;
|
|
3543
|
+
return target instanceof HTMLInputElement && INPUT_TYPES_WITH_NATIVE_ENTER.has(target.type);
|
|
3544
|
+
}
|
|
3545
|
+
function hasPrimaryModifier(event) {
|
|
3546
|
+
return event.metaKey || event.ctrlKey;
|
|
3547
|
+
}
|
|
3548
|
+
/**
|
|
3549
|
+
* Handle a keydown event according to the primary-action conventions
|
|
3550
|
+
* documented at the top of this module.
|
|
3551
|
+
*
|
|
3552
|
+
* This function is a pure helper: it inspects the event, decides whether to
|
|
3553
|
+
* fire `onSubmit` or `onCancel`, and calls `event.preventDefault()` when it
|
|
3554
|
+
* acts. It never mutates DOM state directly. Callers should attach it to the
|
|
3555
|
+
* scope that owns the primary action (modal card, form element, inline
|
|
3556
|
+
* editor row).
|
|
3557
|
+
*/
|
|
3558
|
+
function handlePrimaryActionKeyboard(event, options) {
|
|
3559
|
+
if (options.disabled) return;
|
|
3560
|
+
if (event.defaultPrevented) return;
|
|
3561
|
+
if (event.isComposing) return;
|
|
3562
|
+
if (event.key !== "Enter" && event.key !== "Escape") return;
|
|
3563
|
+
const target = event.target instanceof HTMLElement ? event.target : null;
|
|
3564
|
+
if (shouldIgnoreTarget(target)) return;
|
|
3565
|
+
if (event.key === "Escape") {
|
|
3566
|
+
if (!options.onCancel) return;
|
|
3567
|
+
event.preventDefault();
|
|
3568
|
+
options.onCancel();
|
|
3569
|
+
return;
|
|
3570
|
+
}
|
|
3571
|
+
if (hasNativeEnterBehavior(target)) return;
|
|
3572
|
+
if (isTextareaOrEditable(target) && !hasPrimaryModifier(event)) return;
|
|
3573
|
+
event.preventDefault();
|
|
3574
|
+
options.onSubmit();
|
|
3575
|
+
}
|
|
3576
|
+
//#endregion
|
|
3512
3577
|
//#region src/lib/state.ts
|
|
3513
3578
|
var ALL_TAB_IDS = [
|
|
3514
3579
|
"feed",
|
|
@@ -4146,10 +4211,18 @@
|
|
|
4146
4211
|
const pending = coordinatorAdminState.deviceActionPendingId === deviceId;
|
|
4147
4212
|
const draft = coordinatorAdminState.deviceRenameDrafts.get(deviceId) ?? String(item.display_name || "");
|
|
4148
4213
|
const enabled = item.enabled !== false && item.enabled !== 0;
|
|
4214
|
+
const actionDisabled = !deviceId || pending || summary.readiness !== "ready";
|
|
4149
4215
|
return _$3("div", {
|
|
4150
4216
|
class: "peer-card peer-card--padded",
|
|
4151
4217
|
key: deviceId || String(item.fingerprint || "unknown")
|
|
4152
|
-
}, _$3("div", { class: "peer-title" }, _$3("strong", null, draft || displayName)), _$3("div", { class: "peer-submeta" }, copy.statusLabel), _$3("div", { class: "peer-meta" }, copy.advancedDetail), _$3("
|
|
4218
|
+
}, _$3("div", { class: "peer-title" }, _$3("strong", null, draft || displayName)), _$3("div", { class: "peer-submeta" }, copy.statusLabel), _$3("div", { class: "peer-meta" }, copy.advancedDetail), _$3("form", {
|
|
4219
|
+
class: "coordinator-admin-form",
|
|
4220
|
+
onSubmit: (event) => {
|
|
4221
|
+
event.preventDefault();
|
|
4222
|
+
if (actionDisabled) return;
|
|
4223
|
+
runDevice(deviceId, teamId, displayName, "rename");
|
|
4224
|
+
}
|
|
4225
|
+
}, _$3("div", { class: "coordinator-admin-form-grid" }, _$3("label", { class: "coordinator-admin-field" }, _$3("span", null, "Display name"), _$3(TextInput, {
|
|
4153
4226
|
class: "peer-scope-input",
|
|
4154
4227
|
disabled: summary.readiness !== "ready" || pending,
|
|
4155
4228
|
onInput: (event) => {
|
|
@@ -4159,25 +4232,24 @@
|
|
|
4159
4232
|
value: draft
|
|
4160
4233
|
}))), _$3("div", { class: "peer-actions" }, _$3("button", {
|
|
4161
4234
|
class: "settings-button",
|
|
4162
|
-
disabled:
|
|
4163
|
-
|
|
4164
|
-
type: "button"
|
|
4235
|
+
disabled: actionDisabled,
|
|
4236
|
+
type: "submit"
|
|
4165
4237
|
}, pending && coordinatorAdminState.deviceActionPendingKind === "rename" ? "Renaming…" : "Rename"), enabled ? _$3("button", {
|
|
4166
4238
|
class: "settings-button danger",
|
|
4167
|
-
disabled:
|
|
4239
|
+
disabled: actionDisabled,
|
|
4168
4240
|
onClick: () => runDevice(deviceId, teamId, displayName, "disable"),
|
|
4169
4241
|
type: "button"
|
|
4170
4242
|
}, pending && coordinatorAdminState.deviceActionPendingKind === "disable" ? "Disabling…" : "Disable") : _$3("button", {
|
|
4171
4243
|
class: "settings-button",
|
|
4172
|
-
disabled:
|
|
4244
|
+
disabled: actionDisabled,
|
|
4173
4245
|
onClick: () => runDevice(deviceId, teamId, displayName, "enable"),
|
|
4174
4246
|
type: "button"
|
|
4175
4247
|
}, pending && coordinatorAdminState.deviceActionPendingKind === "enable" ? "Enabling…" : "Enable"), _$3("button", {
|
|
4176
4248
|
class: "settings-button danger",
|
|
4177
|
-
disabled:
|
|
4249
|
+
disabled: actionDisabled,
|
|
4178
4250
|
onClick: () => runDevice(deviceId, teamId, displayName, "remove"),
|
|
4179
4251
|
type: "button"
|
|
4180
|
-
}, pending && coordinatorAdminState.deviceActionPendingKind === "remove" ? "Removing…" : "Remove")));
|
|
4252
|
+
}, pending && coordinatorAdminState.deviceActionPendingKind === "remove" ? "Removing…" : "Remove"))));
|
|
4181
4253
|
})));
|
|
4182
4254
|
}
|
|
4183
4255
|
//#endregion
|
|
@@ -9731,6 +9803,23 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
9731
9803
|
label: `${actor.label}${actor.isLocal ? " (You)" : ""}`,
|
|
9732
9804
|
value: actor.actorId
|
|
9733
9805
|
}));
|
|
9806
|
+
const mergeReady = Boolean(primary?.actorId && secondary?.actorId);
|
|
9807
|
+
const submitMerge = () => {
|
|
9808
|
+
if (!primary?.actorId || !secondary?.actorId) return;
|
|
9809
|
+
resolveCurrentDialog({
|
|
9810
|
+
action: "merge",
|
|
9811
|
+
primaryActorId: primary.actorId,
|
|
9812
|
+
secondaryActorId: secondary.actorId
|
|
9813
|
+
});
|
|
9814
|
+
};
|
|
9815
|
+
const submitMergeFromRadioKey = (event) => {
|
|
9816
|
+
const target = event.target instanceof HTMLElement ? event.target : null;
|
|
9817
|
+
if (event.defaultPrevented || event.isComposing || event.key !== "Enter") return;
|
|
9818
|
+
if (!target?.closest(".sync-dialog-radio-list")) return;
|
|
9819
|
+
if (!mergeReady) return;
|
|
9820
|
+
event.preventDefault();
|
|
9821
|
+
submitMerge();
|
|
9822
|
+
};
|
|
9734
9823
|
return step === "choice" ? /* @__PURE__ */ u("div", {
|
|
9735
9824
|
className: "sync-dialog-stack",
|
|
9736
9825
|
children: /* @__PURE__ */ u("ul", {
|
|
@@ -9739,6 +9828,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
9739
9828
|
/* @__PURE__ */ u("li", { children: /* @__PURE__ */ u("button", {
|
|
9740
9829
|
autoFocus: true,
|
|
9741
9830
|
className: "settings-button",
|
|
9831
|
+
"data-primary-action": "true",
|
|
9742
9832
|
"data-sync-primary-action": "true",
|
|
9743
9833
|
onClick: () => setStep("merge"),
|
|
9744
9834
|
type: "button",
|
|
@@ -9760,6 +9850,13 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
9760
9850
|
})
|
|
9761
9851
|
}) : /* @__PURE__ */ u("div", {
|
|
9762
9852
|
className: "sync-dialog-stack",
|
|
9853
|
+
onKeyDown: (event) => {
|
|
9854
|
+
submitMergeFromRadioKey(event);
|
|
9855
|
+
handlePrimaryActionKeyboard(event, {
|
|
9856
|
+
onSubmit: submitMerge,
|
|
9857
|
+
disabled: !mergeReady
|
|
9858
|
+
});
|
|
9859
|
+
},
|
|
9763
9860
|
children: [
|
|
9764
9861
|
/* @__PURE__ */ u("div", {
|
|
9765
9862
|
className: "small",
|
|
@@ -9808,15 +9905,9 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
9808
9905
|
children: "Back"
|
|
9809
9906
|
}), /* @__PURE__ */ u("button", {
|
|
9810
9907
|
className: "settings-button",
|
|
9811
|
-
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
resolveCurrentDialog({
|
|
9815
|
-
action: "merge",
|
|
9816
|
-
primaryActorId: primary.actorId,
|
|
9817
|
-
secondaryActorId: secondary.actorId
|
|
9818
|
-
});
|
|
9819
|
-
},
|
|
9908
|
+
"data-primary-action": "true",
|
|
9909
|
+
disabled: !mergeReady,
|
|
9910
|
+
onClick: submitMerge,
|
|
9820
9911
|
type: "button",
|
|
9821
9912
|
children: "Combine people"
|
|
9822
9913
|
})]
|
|
@@ -10283,7 +10374,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10283
10374
|
if (!scopeId) return;
|
|
10284
10375
|
if (!await openSyncConfirmDialog({
|
|
10285
10376
|
title: spaceRevokeMemberTitle(scope, displayName, deviceId),
|
|
10286
|
-
description: "Revocation
|
|
10377
|
+
description: "Revocation blocks future sync for this Space. It does not remove data already copied to the revoked device; offline devices, backups, copied databases, malicious peers, or old versions may retain data.",
|
|
10287
10378
|
confirmLabel: "Revoke membership",
|
|
10288
10379
|
cancelLabel: "Keep membership",
|
|
10289
10380
|
tone: "danger"
|
|
@@ -10366,7 +10457,14 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10366
10457
|
loadGroupScopeManagement(groupId, renderShell, checked);
|
|
10367
10458
|
},
|
|
10368
10459
|
thumbClassName: "coordinator-admin-switch-thumb"
|
|
10369
|
-
})), _$3("
|
|
10460
|
+
})), _$3("form", {
|
|
10461
|
+
class: "coordinator-admin-form",
|
|
10462
|
+
onSubmit: (event) => {
|
|
10463
|
+
event.preventDefault();
|
|
10464
|
+
if (disabled) return;
|
|
10465
|
+
createScope(groupId, renderShell);
|
|
10466
|
+
}
|
|
10467
|
+
}, _$3("div", { class: "coordinator-admin-form-grid" }, _$3("label", { class: "coordinator-admin-field" }, _$3("span", null, "New Space id"), _$3(TextInput, {
|
|
10370
10468
|
class: "peer-scope-input",
|
|
10371
10469
|
disabled,
|
|
10372
10470
|
onInput: (event) => {
|
|
@@ -10405,14 +10503,13 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10405
10503
|
}))), _$3("div", { class: "peer-actions" }, _$3("button", {
|
|
10406
10504
|
class: "settings-button",
|
|
10407
10505
|
disabled,
|
|
10408
|
-
|
|
10409
|
-
type: "button"
|
|
10506
|
+
type: "submit"
|
|
10410
10507
|
}, draft.actionPendingKind === "create" ? "Creating…" : "Create Space"), _$3("button", {
|
|
10411
10508
|
class: "settings-button",
|
|
10412
10509
|
disabled,
|
|
10413
10510
|
onClick: () => void loadGroupScopeManagement(groupId, renderShell, draft.includeInactive),
|
|
10414
10511
|
type: "button"
|
|
10415
|
-
}, draft.loading ? "Refreshing…" : "Refresh")), draft.error ? _$3("div", { class: "peer-submeta coordinator-admin-error" }, draft.error) : null, draft.scopes.length ? _$3("div", { class: "coordinator-admin-scope-card-list" }, draft.scopes.map((scope) => renderScopeCard(groupId, scope, draft, ready, renderShell))) : _$3("div", { class: "peer-meta coordinator-admin-empty-state" }, "No Spaces are defined for this Team yet. Create a Space, then grant specific devices. Projects stay local-only until assigned to a Space."));
|
|
10512
|
+
}, draft.loading ? "Refreshing…" : "Refresh"))), draft.error ? _$3("div", { class: "peer-submeta coordinator-admin-error" }, draft.error) : null, draft.scopes.length ? _$3("div", { class: "coordinator-admin-scope-card-list" }, draft.scopes.map((scope) => renderScopeCard(groupId, scope, draft, ready, renderShell))) : _$3("div", { class: "peer-meta coordinator-admin-empty-state" }, "No Spaces are defined for this Team yet. Create a Space, then grant specific devices. Projects stay local-only until assigned to a Space."));
|
|
10416
10513
|
}
|
|
10417
10514
|
//#endregion
|
|
10418
10515
|
//#region src/tabs/coordinator-admin/components/groups-panel.ts
|
|
@@ -10650,43 +10747,52 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10650
10747
|
return _$3(RadixTabsContent, {
|
|
10651
10748
|
className: "coordinator-admin-panel",
|
|
10652
10749
|
value: "groups"
|
|
10653
|
-
}, _$3("h3", null, "Teams"), _$3("p", { class: "peer-submeta" }, selectedGroup ? `Managing ${selectedGroup}${configuredGroup && configuredGroup !== selectedGroup ? ` · this node uses ${configuredGroup} for discovery` : ""}` : configuredGroup ? `This node uses ${configuredGroup} for discovery. Select a Team below to manage it.` : "No Team selected yet. Create one or select an existing Team to manage."), groups.length ? _$3("p", { class: "peer-submeta" }, countParts.join(" · ")) : null, !targetExists && selectedGroup ? _$3("div", { class: "peer-meta coordinator-admin-inline-warning" }, `The selected Team (${selectedGroup}) is configured locally but does not exist in the coordinator yet. Create it below or switch to another Team once one exists.`) : null, renderTeamSetupGuide(renderShell),
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10660
|
-
|
|
10661
|
-
|
|
10662
|
-
|
|
10663
|
-
|
|
10664
|
-
|
|
10665
|
-
|
|
10666
|
-
|
|
10667
|
-
|
|
10668
|
-
|
|
10669
|
-
|
|
10670
|
-
|
|
10671
|
-
|
|
10672
|
-
|
|
10673
|
-
|
|
10674
|
-
|
|
10675
|
-
|
|
10676
|
-
|
|
10677
|
-
|
|
10678
|
-
|
|
10679
|
-
|
|
10680
|
-
"
|
|
10681
|
-
|
|
10682
|
-
|
|
10683
|
-
|
|
10684
|
-
|
|
10685
|
-
|
|
10686
|
-
|
|
10687
|
-
},
|
|
10688
|
-
|
|
10689
|
-
|
|
10750
|
+
}, _$3("h3", null, "Teams"), _$3("p", { class: "peer-submeta" }, selectedGroup ? `Managing ${selectedGroup}${configuredGroup && configuredGroup !== selectedGroup ? ` · this node uses ${configuredGroup} for discovery` : ""}` : configuredGroup ? `This node uses ${configuredGroup} for discovery. Select a Team below to manage it.` : "No Team selected yet. Create one or select an existing Team to manage."), groups.length ? _$3("p", { class: "peer-submeta" }, countParts.join(" · ")) : null, !targetExists && selectedGroup ? _$3("div", { class: "peer-meta coordinator-admin-inline-warning" }, `The selected Team (${selectedGroup}) is configured locally but does not exist in the coordinator yet. Create it below or switch to another Team once one exists.`) : null, renderTeamSetupGuide(renderShell), (() => {
|
|
10751
|
+
const createGroupDisabled = summary.readiness !== "ready" || coordinatorAdminState.groupActionPendingKind === "create";
|
|
10752
|
+
return _$3("form", {
|
|
10753
|
+
class: "coordinator-admin-form",
|
|
10754
|
+
onSubmit: (event) => {
|
|
10755
|
+
event.preventDefault();
|
|
10756
|
+
if (createGroupDisabled) return;
|
|
10757
|
+
createGroup();
|
|
10758
|
+
}
|
|
10759
|
+
}, _$3("div", { class: "coordinator-admin-form-grid" }, _$3("label", { class: "coordinator-admin-field" }, _$3("span", null, "New Team id"), _$3(TextInput, {
|
|
10760
|
+
class: "peer-scope-input",
|
|
10761
|
+
disabled: createGroupDisabled,
|
|
10762
|
+
onInput: (event) => {
|
|
10763
|
+
coordinatorAdminState.createGroupId = String(event.currentTarget.value || "");
|
|
10764
|
+
},
|
|
10765
|
+
placeholder: "team-alpha",
|
|
10766
|
+
type: "text",
|
|
10767
|
+
value: coordinatorAdminState.createGroupId
|
|
10768
|
+
})), _$3("label", { class: "coordinator-admin-field" }, _$3("span", null, "Display name"), _$3(TextInput, {
|
|
10769
|
+
class: "peer-scope-input",
|
|
10770
|
+
disabled: createGroupDisabled,
|
|
10771
|
+
onInput: (event) => {
|
|
10772
|
+
coordinatorAdminState.createGroupDisplayName = String(event.currentTarget.value || "");
|
|
10773
|
+
},
|
|
10774
|
+
placeholder: "Team Alpha",
|
|
10775
|
+
type: "text",
|
|
10776
|
+
value: coordinatorAdminState.createGroupDisplayName
|
|
10777
|
+
}))), _$3("div", { class: "section-actions coordinator-admin-groups-toolbar" }, _$3("div", { class: "coordinator-admin-primary-actions" }, _$3("button", {
|
|
10778
|
+
class: "settings-button",
|
|
10779
|
+
disabled: createGroupDisabled,
|
|
10780
|
+
type: "submit"
|
|
10781
|
+
}, coordinatorAdminState.groupActionPendingKind === "create" ? "Creating…" : "Create Team")), _$3("div", { class: "coordinator-admin-secondary-actions" }, _$3("label", { class: "coordinator-admin-inline-filter" }, _$3("span", {
|
|
10782
|
+
class: "section-meta",
|
|
10783
|
+
id: "coordinatorAdminShowArchivedLabel"
|
|
10784
|
+
}, "Show archived"), _$3(RadixSwitch, {
|
|
10785
|
+
"aria-labelledby": "coordinatorAdminShowArchivedLabel",
|
|
10786
|
+
checked: coordinatorAdminState.showArchivedGroups,
|
|
10787
|
+
className: "coordinator-admin-switch",
|
|
10788
|
+
disabled: summary.readiness !== "ready",
|
|
10789
|
+
onCheckedChange: (checked) => {
|
|
10790
|
+
coordinatorAdminState.showArchivedGroups = checked;
|
|
10791
|
+
renderShell();
|
|
10792
|
+
},
|
|
10793
|
+
thumbClassName: "coordinator-admin-switch-thumb"
|
|
10794
|
+
})))));
|
|
10795
|
+
})(), !visibleGroups.length ? _$3("div", { class: "peer-meta coordinator-admin-empty-state" }, summary.readiness === "ready" ? coordinatorAdminState.showArchivedGroups ? "No Teams are available yet." : "No active Teams yet. Create one to get started." : "Team browsing will appear here once setup is complete.") : _$3("div", { class: "peer-list" }, visibleGroups.map((group) => {
|
|
10690
10796
|
const selected = group.group_id === selectedGroup;
|
|
10691
10797
|
const pending = coordinatorAdminState.groupActionPendingId === group.group_id;
|
|
10692
10798
|
const archived = Boolean(group.archived_at);
|
|
@@ -10800,10 +10906,18 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10800
10906
|
const effectiveGroup = coordinatorAdminState.inviteGroup.trim() || activeGroup;
|
|
10801
10907
|
const output = String(state.lastTeamInvite?.encoded || "").trim();
|
|
10802
10908
|
const warnings = Array.isArray(state.lastTeamInvite?.warnings) ? state.lastTeamInvite?.warnings : [];
|
|
10909
|
+
const inviteDisabled = summary.readiness !== "ready" || coordinatorAdminState.invitePending;
|
|
10803
10910
|
return _$3(RadixTabsContent, {
|
|
10804
10911
|
className: "coordinator-admin-panel",
|
|
10805
10912
|
value: "invites"
|
|
10806
|
-
}, _$3("h3", null, "Create teammate invite"), _$3("p", { class: "peer-submeta" }, summary.readiness === "ready" ? "Generate an invite for the selected Team. Default Space access is controlled by that Team's auto-grant setting." : "Finish setup first. Invite creation stays disabled until the local coordinator admin configuration is ready."), _$3("
|
|
10913
|
+
}, _$3("h3", null, "Create teammate invite"), _$3("p", { class: "peer-submeta" }, summary.readiness === "ready" ? "Generate an invite for the selected Team. Default Space access is controlled by that Team's auto-grant setting." : "Finish setup first. Invite creation stays disabled until the local coordinator admin configuration is ready."), _$3("form", {
|
|
10914
|
+
class: "coordinator-admin-form",
|
|
10915
|
+
onSubmit: (event) => {
|
|
10916
|
+
event.preventDefault();
|
|
10917
|
+
if (inviteDisabled) return;
|
|
10918
|
+
createInvite();
|
|
10919
|
+
}
|
|
10920
|
+
}, _$3("div", { class: "coordinator-admin-form-grid" }, _$3("label", { class: "coordinator-admin-field" }, _$3("span", null, "Team"), _$3(TextInput, {
|
|
10807
10921
|
class: "peer-scope-input",
|
|
10808
10922
|
disabled: summary.readiness !== "ready",
|
|
10809
10923
|
onInput: (event) => {
|
|
@@ -10844,12 +10958,9 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
10844
10958
|
value: coordinatorAdminState.inviteTtlHours
|
|
10845
10959
|
}))), _$3("div", { class: "section-actions" }, _$3("button", {
|
|
10846
10960
|
class: "settings-button",
|
|
10847
|
-
disabled:
|
|
10848
|
-
|
|
10849
|
-
|
|
10850
|
-
},
|
|
10851
|
-
type: "button"
|
|
10852
|
-
}, coordinatorAdminState.invitePending ? "Creating…" : "Create invite"), effectiveGroup ? _$3("span", { class: "peer-submeta" }, `Using Team ${effectiveGroup}`) : null), output ? _$3("label", { class: "coordinator-admin-field" }, _$3("span", null, "Generated invite"), _$3(TextArea, {
|
|
10961
|
+
disabled: inviteDisabled,
|
|
10962
|
+
type: "submit"
|
|
10963
|
+
}, coordinatorAdminState.invitePending ? "Creating…" : "Create invite"), effectiveGroup ? _$3("span", { class: "peer-submeta" }, `Using Team ${effectiveGroup}`) : null)), output ? _$3("label", { class: "coordinator-admin-field" }, _$3("span", null, "Generated invite"), _$3(TextArea, {
|
|
10853
10964
|
class: "feed-search coordinator-admin-output",
|
|
10854
10965
|
readOnly: true,
|
|
10855
10966
|
value: output
|
|
@@ -13567,6 +13678,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
13567
13678
|
const tagContent = tags.length ? ` · ${tags.map((t) => formatTagLabel(t)).join(", ")}` : "";
|
|
13568
13679
|
const fileContent = files.length ? ` · ${formatFileList(files)}` : "";
|
|
13569
13680
|
const memoryId = Number(item.id || 0);
|
|
13681
|
+
const memoryIdLabel = memoryId > 0 ? `ID ${memoryId}` : "";
|
|
13570
13682
|
const [isNew, setIsNew] = d$2(state.newItemKeys.has(rowKey));
|
|
13571
13683
|
const summaryObj = isSessionSummary ? getSummaryObject({
|
|
13572
13684
|
...item,
|
|
@@ -13743,7 +13855,13 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
13743
13855
|
}), _$3(ProvenanceChip, {
|
|
13744
13856
|
label: visibility || "private",
|
|
13745
13857
|
variant: visibility || "private"
|
|
13746
|
-
})
|
|
13858
|
+
}), memoryIdLabel ? _$3(Tooltip, {
|
|
13859
|
+
label: `Memory database id ${memoryId}`,
|
|
13860
|
+
side: "top"
|
|
13861
|
+
}, _$3(ProvenanceChip, {
|
|
13862
|
+
label: memoryIdLabel,
|
|
13863
|
+
variant: "memory-id"
|
|
13864
|
+
})) : null), _$3("div", { className: "feed-meta" }, metaText || "No tags, files, or provenance details attached."), bodyContent, _$3("div", { className: "feed-footer" }, _$3("div", { className: "feed-footer-left" }, tags.length ? _$3("div", { className: "feed-tags" }, tags.map((tag, index) => _$3(TagChip, {
|
|
13747
13865
|
key: `${String(tag)}-${index}`,
|
|
13748
13866
|
tag
|
|
13749
13867
|
}))) : null, item.owned_by_self && memoryId > 0 ? _$3("div", { className: "feed-visibility-controls" }, _$3("select", {
|
|
@@ -14628,6 +14746,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14628
14746
|
var openProjectDetails = /* @__PURE__ */ new Set();
|
|
14629
14747
|
var openProjectClusters = /* @__PURE__ */ new Set();
|
|
14630
14748
|
var draftDomainSelections = /* @__PURE__ */ new Map();
|
|
14749
|
+
var draftClusterDomainSelections = /* @__PURE__ */ new Map();
|
|
14631
14750
|
var pendingConfirmations = /* @__PURE__ */ new Map();
|
|
14632
14751
|
var pendingForgetConfirmations = /* @__PURE__ */ new Map();
|
|
14633
14752
|
var skippedProjectRefreshForActiveSelect = false;
|
|
@@ -14846,6 +14965,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
14846
14965
|
workspace_identity: project.workspace_identity
|
|
14847
14966
|
})) });
|
|
14848
14967
|
showGlobalNotice(`Updated ${assignable.length} project identit${assignable.length === 1 ? "y" : "ies"}. Device access grants are unchanged.`);
|
|
14968
|
+
draftClusterDomainSelections.delete(projectClusterKey(assignable[0]));
|
|
14849
14969
|
refreshProjects?.();
|
|
14850
14970
|
} catch (error) {
|
|
14851
14971
|
showGlobalNotice(error instanceof SharingDomainGuardrailConfirmationError ? "One or more identities in this group need review before bulk assignment. Expand the group and save those identities directly." : error instanceof Error ? error.message : "Unable to update project Spaces.", "warning");
|
|
@@ -15201,14 +15321,16 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
15201
15321
|
placeholder.textContent = "Choose Space…";
|
|
15202
15322
|
select.appendChild(placeholder);
|
|
15203
15323
|
appendAssignableScopeOptions(select);
|
|
15204
|
-
select.value =
|
|
15324
|
+
select.value = firstSafeSelection(draftClusterDomainSelections.get(clusterKey));
|
|
15205
15325
|
const save = document.createElement("button");
|
|
15206
15326
|
save.className = "settings-button";
|
|
15207
15327
|
save.type = "button";
|
|
15208
15328
|
save.textContent = `Save Space for ${assignableProjects.length} identit${assignableProjects.length === 1 ? "y" : "ies"}`;
|
|
15209
|
-
save.disabled =
|
|
15329
|
+
save.disabled = !select.value || hasGuardrailWarnings;
|
|
15210
15330
|
save.addEventListener("click", () => void saveProjectClusterMapping(assignableProjects, select.value));
|
|
15211
15331
|
select.addEventListener("change", () => {
|
|
15332
|
+
if (select.value) draftClusterDomainSelections.set(clusterKey, select.value);
|
|
15333
|
+
else draftClusterDomainSelections.delete(clusterKey);
|
|
15212
15334
|
save.disabled = !select.value || hasGuardrailWarnings;
|
|
15213
15335
|
});
|
|
15214
15336
|
select.addEventListener("blur", refreshSkippedProjectDataAfterSelectBlur);
|
|
@@ -15252,10 +15374,14 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
15252
15374
|
empty.textContent = message;
|
|
15253
15375
|
list.appendChild(empty);
|
|
15254
15376
|
}
|
|
15377
|
+
function hideProjectInventorySkeleton() {
|
|
15378
|
+
document.getElementById("projectsInventorySkeleton")?.remove();
|
|
15379
|
+
}
|
|
15255
15380
|
function renderProjectInventory(result) {
|
|
15256
15381
|
const meta = el("projectsInventoryMeta");
|
|
15257
15382
|
const list = el("projectsInventoryList");
|
|
15258
15383
|
if (!meta || !list) return;
|
|
15384
|
+
hideProjectInventorySkeleton();
|
|
15259
15385
|
list.textContent = "";
|
|
15260
15386
|
if (result.projects.length === 0) renderEmpty("No projects match those filters.");
|
|
15261
15387
|
else for (const cluster of projectClusters(result.projects)) list.appendChild(renderProjectCluster(cluster));
|
|
@@ -15292,6 +15418,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
15292
15418
|
renderProjectInventory(result);
|
|
15293
15419
|
refreshProjectCoordinatorGroupNamesInBackground(result);
|
|
15294
15420
|
} catch (error) {
|
|
15421
|
+
hideProjectInventorySkeleton();
|
|
15295
15422
|
meta.textContent = "Project inventory failed to load.";
|
|
15296
15423
|
renderEmpty(error instanceof Error ? error.message : "Unable to load project inventory.");
|
|
15297
15424
|
}
|
|
@@ -16919,487 +17046,167 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
16919
17046
|
] });
|
|
16920
17047
|
}
|
|
16921
17048
|
//#endregion
|
|
16922
|
-
//#region src/tabs/settings/components/
|
|
16923
|
-
function
|
|
16924
|
-
|
|
16925
|
-
|
|
16926
|
-
|
|
16927
|
-
|
|
16928
|
-
function projectSubtitle(project) {
|
|
16929
|
-
if (project.git_remote) return `Matched by git remote · ${project.git_remote}`;
|
|
16930
|
-
if (project.cwd) return `Matched by path · ${project.cwd}`;
|
|
16931
|
-
return `Matched by ${project.identity_source} · ${project.workspace_identity}`;
|
|
16932
|
-
}
|
|
16933
|
-
function resolutionLabel(reason) {
|
|
16934
|
-
switch (reason) {
|
|
16935
|
-
case "exact_mapping": return "explicit project mapping";
|
|
16936
|
-
case "pattern_mapping": return "pattern mapping";
|
|
16937
|
-
case "explicit_override": return "explicit override";
|
|
16938
|
-
default: return "local-only fallback";
|
|
16939
|
-
}
|
|
16940
|
-
}
|
|
16941
|
-
function scopeName(scopes, scopeId) {
|
|
16942
|
-
return scopes.find((scope) => scope.scope_id === scopeId)?.label || scopeId;
|
|
16943
|
-
}
|
|
16944
|
-
function resetDrafts(settings) {
|
|
16945
|
-
return Object.fromEntries(settings.projects.map((project) => [project.workspace_identity, project.suggested_scope_id ?? project.resolved_scope_id]));
|
|
16946
|
-
}
|
|
16947
|
-
function canAssignProject(project) {
|
|
16948
|
-
return project.identity_source !== "unmapped";
|
|
16949
|
-
}
|
|
16950
|
-
function warningKey(warning, index) {
|
|
16951
|
-
return [
|
|
16952
|
-
warning.code,
|
|
16953
|
-
warning.workspace_identity,
|
|
16954
|
-
warning.project_pattern,
|
|
16955
|
-
index
|
|
16956
|
-
].join(":");
|
|
16957
|
-
}
|
|
16958
|
-
function visibleProjectWarnings(project) {
|
|
16959
|
-
return (project.guardrail_warnings ?? []).filter((warning) => warning.severity === "warning" || warning.code === "unknown_project_local_only");
|
|
16960
|
-
}
|
|
16961
|
-
function isUsingSuggestion(project, currentValue) {
|
|
16962
|
-
return Boolean(project.suggested_scope_id && currentValue === project.suggested_scope_id && project.suggested_scope_id !== project.resolved_scope_id);
|
|
16963
|
-
}
|
|
16964
|
-
function settingsMappingWarnings(settings) {
|
|
16965
|
-
return settings.mappings.flatMap((mapping) => mapping.guardrail_warnings ?? []);
|
|
16966
|
-
}
|
|
16967
|
-
function GuardrailMessages({ label = "Space assignment guardrail", warnings }) {
|
|
16968
|
-
if (warnings.length === 0) return null;
|
|
16969
|
-
return /* @__PURE__ */ u("div", {
|
|
16970
|
-
"aria-label": label,
|
|
16971
|
-
className: "settings-note",
|
|
16972
|
-
role: "status",
|
|
16973
|
-
children: /* @__PURE__ */ u("ul", { children: warnings.map((warning, index) => /* @__PURE__ */ u("li", { children: warning.message }, warningKey(warning, index))) })
|
|
16974
|
-
});
|
|
16975
|
-
}
|
|
16976
|
-
function SharingDomainsPanel() {
|
|
16977
|
-
const [settings, setSettings] = d$2(null);
|
|
16978
|
-
const [drafts, setDrafts] = d$2({});
|
|
16979
|
-
const [loading, setLoading] = d$2(false);
|
|
16980
|
-
const [savingKey, setSavingKey] = d$2(null);
|
|
16981
|
-
const [error, setError] = d$2(null);
|
|
16982
|
-
const [confirmation, setConfirmation] = d$2(null);
|
|
16983
|
-
const reload = async () => {
|
|
16984
|
-
setLoading(true);
|
|
16985
|
-
setError(null);
|
|
16986
|
-
try {
|
|
16987
|
-
const next = await loadSharingDomainSettings();
|
|
16988
|
-
setSettings(next);
|
|
16989
|
-
setDrafts(resetDrafts(next));
|
|
16990
|
-
} catch (err) {
|
|
16991
|
-
setError(err instanceof Error ? err.message : "Unable to load Spaces");
|
|
16992
|
-
} finally {
|
|
16993
|
-
setLoading(false);
|
|
16994
|
-
}
|
|
16995
|
-
};
|
|
16996
|
-
y$2(() => {
|
|
16997
|
-
reload();
|
|
16998
|
-
}, []);
|
|
16999
|
-
const scopeOptions = T$1(() => (settings?.scopes ?? []).filter((scope) => scope.scope_id !== "legacy-shared-review").map((scope) => ({
|
|
17000
|
-
value: scope.scope_id,
|
|
17001
|
-
label: domainLabel(scope)
|
|
17002
|
-
})), [settings?.scopes]);
|
|
17003
|
-
const saveProject = async (project) => {
|
|
17004
|
-
await saveProjectWithGuardrails(project);
|
|
17005
|
-
};
|
|
17006
|
-
const saveProjectWithGuardrails = async (project, confirmedGuardrailTokens = []) => {
|
|
17007
|
-
if (!canAssignProject(project)) {
|
|
17008
|
-
setError("Unmapped projects need a stable path, git remote, or workspace id before assignment.");
|
|
17009
|
-
return;
|
|
17010
|
-
}
|
|
17011
|
-
const scopeId = drafts[project.workspace_identity] ?? project.resolved_scope_id;
|
|
17012
|
-
setSavingKey(project.workspace_identity);
|
|
17013
|
-
setError(null);
|
|
17014
|
-
try {
|
|
17015
|
-
await saveSharingDomainProjectMapping({
|
|
17016
|
-
...project.mapping_id && project.resolution_reason === "exact_mapping" ? { id: project.mapping_id } : {},
|
|
17017
|
-
...confirmedGuardrailTokens.length > 0 ? { confirmed_guardrail_tokens: confirmedGuardrailTokens } : {},
|
|
17018
|
-
workspace_identity: project.workspace_identity,
|
|
17019
|
-
project_pattern: project.display_project,
|
|
17020
|
-
scope_id: scopeId
|
|
17021
|
-
});
|
|
17022
|
-
setConfirmation(null);
|
|
17023
|
-
showGlobalNotice("Project Space assignment updated. Device access grants are unchanged.");
|
|
17024
|
-
await reload();
|
|
17025
|
-
} catch (err) {
|
|
17026
|
-
if (err instanceof SharingDomainGuardrailConfirmationError) {
|
|
17027
|
-
setConfirmation({
|
|
17028
|
-
workspaceIdentity: project.workspace_identity,
|
|
17029
|
-
requiredGuardrailTokens: err.requiredGuardrailTokens,
|
|
17030
|
-
warnings: err.guardrailWarnings
|
|
17031
|
-
});
|
|
17032
|
-
return;
|
|
17033
|
-
}
|
|
17034
|
-
setError(err instanceof Error ? err.message : "Unable to save Space assignment");
|
|
17035
|
-
} finally {
|
|
17036
|
-
setSavingKey(null);
|
|
17037
|
-
}
|
|
17038
|
-
};
|
|
17039
|
-
const resetProject = async (project) => {
|
|
17040
|
-
if (!project.mapping_id) return;
|
|
17041
|
-
setSavingKey(project.workspace_identity);
|
|
17042
|
-
setError(null);
|
|
17043
|
-
try {
|
|
17044
|
-
await deleteSharingDomainProjectMapping(project.mapping_id);
|
|
17045
|
-
setConfirmation(null);
|
|
17046
|
-
showGlobalNotice("Project Space assignment removed. The next fallback now applies.");
|
|
17047
|
-
await reload();
|
|
17048
|
-
} catch (err) {
|
|
17049
|
-
setError(err instanceof Error ? err.message : "Unable to reset Space assignment");
|
|
17050
|
-
} finally {
|
|
17051
|
-
setSavingKey(null);
|
|
17052
|
-
}
|
|
17053
|
-
};
|
|
17054
|
-
const openProjects = () => {
|
|
17055
|
-
window.location.hash = "projects";
|
|
17056
|
-
};
|
|
17057
|
-
return /* @__PURE__ */ u("div", {
|
|
17049
|
+
//#region src/tabs/settings/components/SyncPanel.tsx
|
|
17050
|
+
function SyncPanel({ values, hiddenUnlessAdvanced, onTextInput, onSwitchInput, protectedConfigHelp }) {
|
|
17051
|
+
return /* @__PURE__ */ u(k$3, { children: [/* @__PURE__ */ u(SettingsSectionIntro, {
|
|
17052
|
+
detail: "Choose whether this device syncs at all, how often it checks peers, and which coordinator group it should join.",
|
|
17053
|
+
title: "Device sync"
|
|
17054
|
+
}), /* @__PURE__ */ u("div", {
|
|
17058
17055
|
className: "settings-group",
|
|
17059
17056
|
children: [
|
|
17060
17057
|
/* @__PURE__ */ u("h3", {
|
|
17061
17058
|
className: "settings-group-title",
|
|
17062
|
-
children: "
|
|
17059
|
+
children: "Device Sync"
|
|
17060
|
+
}),
|
|
17061
|
+
/* @__PURE__ */ u(SettingsSwitchRow, {
|
|
17062
|
+
checked: values.syncEnabled,
|
|
17063
|
+
className: "field",
|
|
17064
|
+
id: "syncEnabled",
|
|
17065
|
+
label: "Enable sync",
|
|
17066
|
+
onCheckedChange: onSwitchInput("syncEnabled")
|
|
17063
17067
|
}),
|
|
17064
17068
|
/* @__PURE__ */ u("div", {
|
|
17065
|
-
className: "
|
|
17066
|
-
children:
|
|
17069
|
+
className: "field",
|
|
17070
|
+
children: [
|
|
17071
|
+
/* @__PURE__ */ u("label", {
|
|
17072
|
+
htmlFor: "syncInterval",
|
|
17073
|
+
children: "Sync interval (seconds)"
|
|
17074
|
+
}),
|
|
17075
|
+
/* @__PURE__ */ u(TextInput, {
|
|
17076
|
+
id: "syncInterval",
|
|
17077
|
+
min: "10",
|
|
17078
|
+
onInput: onTextInput("syncInterval"),
|
|
17079
|
+
type: "number",
|
|
17080
|
+
value: values.syncInterval
|
|
17081
|
+
}),
|
|
17082
|
+
/* @__PURE__ */ u("div", {
|
|
17083
|
+
className: "small",
|
|
17084
|
+
children: "How often this device checks for sync work when sync is enabled."
|
|
17085
|
+
})
|
|
17086
|
+
]
|
|
17067
17087
|
}),
|
|
17068
17088
|
/* @__PURE__ */ u("div", {
|
|
17069
|
-
className: "
|
|
17070
|
-
|
|
17089
|
+
className: "field settings-advanced",
|
|
17090
|
+
hidden: hiddenUnlessAdvanced(),
|
|
17091
|
+
children: [/* @__PURE__ */ u("label", {
|
|
17092
|
+
htmlFor: "syncHost",
|
|
17093
|
+
children: "Sync host"
|
|
17094
|
+
}), /* @__PURE__ */ u(TextInput, {
|
|
17095
|
+
id: "syncHost",
|
|
17096
|
+
onInput: onTextInput("syncHost"),
|
|
17097
|
+
placeholder: "127.0.0.1",
|
|
17098
|
+
value: values.syncHost
|
|
17099
|
+
})]
|
|
17071
17100
|
}),
|
|
17072
17101
|
/* @__PURE__ */ u("div", {
|
|
17073
|
-
className: "
|
|
17074
|
-
|
|
17075
|
-
|
|
17076
|
-
|
|
17077
|
-
|
|
17078
|
-
|
|
17079
|
-
|
|
17102
|
+
className: "field settings-advanced",
|
|
17103
|
+
hidden: hiddenUnlessAdvanced(),
|
|
17104
|
+
children: [/* @__PURE__ */ u("label", {
|
|
17105
|
+
htmlFor: "syncPort",
|
|
17106
|
+
children: "Sync port"
|
|
17107
|
+
}), /* @__PURE__ */ u(TextInput, {
|
|
17108
|
+
id: "syncPort",
|
|
17109
|
+
min: "1",
|
|
17110
|
+
onInput: onTextInput("syncPort"),
|
|
17111
|
+
type: "number",
|
|
17112
|
+
value: values.syncPort
|
|
17113
|
+
})]
|
|
17080
17114
|
}),
|
|
17081
|
-
|
|
17082
|
-
|
|
17083
|
-
|
|
17084
|
-
|
|
17085
|
-
|
|
17086
|
-
|
|
17087
|
-
|
|
17088
|
-
}) : null,
|
|
17089
|
-
error ? /* @__PURE__ */ u("div", {
|
|
17090
|
-
className: "settings-note",
|
|
17091
|
-
role: "alert",
|
|
17092
|
-
children: error
|
|
17093
|
-
}) : null,
|
|
17094
|
-
settings && settings.projects.length === 0 ? /* @__PURE__ */ u("div", {
|
|
17095
|
-
className: "small",
|
|
17096
|
-
children: "No projects with memories are available yet."
|
|
17097
|
-
}) : null,
|
|
17098
|
-
settings?.projects.map((project, index) => {
|
|
17099
|
-
const fieldId = `sharingDomainProject-${index}`;
|
|
17100
|
-
const currentValue = drafts[project.workspace_identity] ?? project.resolved_scope_id;
|
|
17101
|
-
const saving = savingKey === project.workspace_identity;
|
|
17102
|
-
const unchanged = currentValue === project.resolved_scope_id;
|
|
17103
|
-
const assignable = canAssignProject(project);
|
|
17104
|
-
const currentScopeName = scopeName(settings.scopes, project.resolved_scope_id);
|
|
17105
|
-
const usingSuggestion = isUsingSuggestion(project, currentValue);
|
|
17106
|
-
const suggestedScopeName = project.suggested_scope_id ? scopeName(settings.scopes, project.suggested_scope_id) : null;
|
|
17107
|
-
const pendingConfirmation = confirmation?.workspaceIdentity === project.workspace_identity ? confirmation : null;
|
|
17108
|
-
const canRemoveProjectMapping = assignable && project.mapping_id != null && project.resolution_reason === "exact_mapping";
|
|
17109
|
-
return /* @__PURE__ */ u("div", {
|
|
17110
|
-
className: "field",
|
|
17111
|
-
children: [
|
|
17112
|
-
/* @__PURE__ */ u("label", {
|
|
17113
|
-
htmlFor: fieldId,
|
|
17114
|
-
children: project.display_project
|
|
17115
|
-
}),
|
|
17116
|
-
/* @__PURE__ */ u("div", {
|
|
17117
|
-
className: "small",
|
|
17118
|
-
children: projectSubtitle(project)
|
|
17119
|
-
}),
|
|
17120
|
-
/* @__PURE__ */ u(RadixSelect, {
|
|
17121
|
-
ariaLabel: `Space for ${project.display_project}`,
|
|
17122
|
-
contentClassName: "settings-select-content",
|
|
17123
|
-
disabled: !assignable || saving || scopeOptions.length === 0,
|
|
17124
|
-
id: fieldId,
|
|
17125
|
-
itemClassName: "settings-select-item",
|
|
17126
|
-
onValueChange: (value) => {
|
|
17127
|
-
setDrafts((prev) => ({
|
|
17128
|
-
...prev,
|
|
17129
|
-
[project.workspace_identity]: value
|
|
17130
|
-
}));
|
|
17131
|
-
if (confirmation?.workspaceIdentity === project.workspace_identity) setConfirmation(null);
|
|
17132
|
-
},
|
|
17133
|
-
options: scopeOptions,
|
|
17134
|
-
placeholder: "Choose Space",
|
|
17135
|
-
triggerClassName: "settings-select-trigger",
|
|
17136
|
-
value: currentValue,
|
|
17137
|
-
viewportClassName: "settings-select-viewport"
|
|
17138
|
-
}),
|
|
17139
|
-
/* @__PURE__ */ u("div", {
|
|
17140
|
-
className: "small",
|
|
17141
|
-
children: [
|
|
17142
|
-
"Current Space: ",
|
|
17143
|
-
currentScopeName,
|
|
17144
|
-
" · ",
|
|
17145
|
-
resolutionLabel(project.resolution_reason)
|
|
17146
|
-
]
|
|
17147
|
-
}),
|
|
17148
|
-
project.suggested_scope_id && project.suggestion_reason ? /* @__PURE__ */ u("div", {
|
|
17149
|
-
className: "settings-note",
|
|
17150
|
-
role: "status",
|
|
17151
|
-
children: [
|
|
17152
|
-
/* @__PURE__ */ u("strong", { children: ["Suggested mapping: ", suggestedScopeName] }),
|
|
17153
|
-
/* @__PURE__ */ u("div", { children: project.suggestion_reason }),
|
|
17154
|
-
/* @__PURE__ */ u("div", { children: "Folders, paths, and git remotes are hints only. Saving this mapping requires your confirmation and does not grant any peer access." })
|
|
17155
|
-
]
|
|
17156
|
-
}) : null,
|
|
17157
|
-
/* @__PURE__ */ u(GuardrailMessages, { warnings: visibleProjectWarnings(project) }),
|
|
17158
|
-
!assignable ? /* @__PURE__ */ u("div", {
|
|
17159
|
-
className: "settings-note",
|
|
17160
|
-
children: "This project is missing a stable identity, so Space assignment is disabled. Add a path, git remote, or workspace id first; until then it remains Local only."
|
|
17161
|
-
}) : null,
|
|
17162
|
-
pendingConfirmation ? /* @__PURE__ */ u("div", {
|
|
17163
|
-
className: "settings-note",
|
|
17164
|
-
role: "alert",
|
|
17165
|
-
children: [
|
|
17166
|
-
/* @__PURE__ */ u("strong", { children: "Review before saving this Space assignment." }),
|
|
17167
|
-
/* @__PURE__ */ u("ul", { children: pendingConfirmation.warnings.map((warning, warningIndex) => /* @__PURE__ */ u("li", { children: warning.message }, warningKey(warning, warningIndex))) }),
|
|
17168
|
-
/* @__PURE__ */ u("div", {
|
|
17169
|
-
className: "section-actions",
|
|
17170
|
-
children: [/* @__PURE__ */ u("button", {
|
|
17171
|
-
className: "settings-button",
|
|
17172
|
-
disabled: saving,
|
|
17173
|
-
onClick: () => void saveProjectWithGuardrails(project, pendingConfirmation.requiredGuardrailTokens),
|
|
17174
|
-
type: "button",
|
|
17175
|
-
children: "Confirm and save"
|
|
17176
|
-
}), /* @__PURE__ */ u("button", {
|
|
17177
|
-
className: "settings-button",
|
|
17178
|
-
disabled: saving,
|
|
17179
|
-
onClick: () => setConfirmation(null),
|
|
17180
|
-
type: "button",
|
|
17181
|
-
children: "Cancel"
|
|
17182
|
-
})]
|
|
17183
|
-
})
|
|
17184
|
-
]
|
|
17185
|
-
}) : null,
|
|
17186
|
-
/* @__PURE__ */ u("div", {
|
|
17187
|
-
className: "section-actions",
|
|
17188
|
-
children: [/* @__PURE__ */ u("button", {
|
|
17189
|
-
className: "settings-button",
|
|
17190
|
-
disabled: !assignable || saving || unchanged,
|
|
17191
|
-
onClick: () => void saveProject(project),
|
|
17192
|
-
type: "button",
|
|
17193
|
-
children: saving ? "Saving…" : usingSuggestion ? "Confirm suggested mapping" : "Save Space"
|
|
17194
|
-
}), /* @__PURE__ */ u("button", {
|
|
17195
|
-
className: "settings-button",
|
|
17196
|
-
disabled: saving || !canRemoveProjectMapping,
|
|
17197
|
-
onClick: () => void resetProject(project),
|
|
17198
|
-
type: "button",
|
|
17199
|
-
children: "Remove project mapping"
|
|
17200
|
-
})]
|
|
17201
|
-
})
|
|
17202
|
-
]
|
|
17203
|
-
}, project.workspace_identity);
|
|
17204
|
-
})
|
|
17205
|
-
]
|
|
17206
|
-
});
|
|
17207
|
-
}
|
|
17208
|
-
//#endregion
|
|
17209
|
-
//#region src/tabs/settings/components/SyncPanel.tsx
|
|
17210
|
-
function SyncPanel({ values, hiddenUnlessAdvanced, onTextInput, onSwitchInput, protectedConfigHelp }) {
|
|
17211
|
-
return /* @__PURE__ */ u(k$3, { children: [
|
|
17212
|
-
/* @__PURE__ */ u(SettingsSectionIntro, {
|
|
17213
|
-
detail: "Choose whether this device syncs at all, how often it checks peers, and which coordinator group it should join.",
|
|
17214
|
-
title: "Device sync"
|
|
17215
|
-
}),
|
|
17216
|
-
/* @__PURE__ */ u("div", {
|
|
17217
|
-
className: "settings-group",
|
|
17218
|
-
children: [
|
|
17219
|
-
/* @__PURE__ */ u("h3", {
|
|
17220
|
-
className: "settings-group-title",
|
|
17221
|
-
children: "Device Sync"
|
|
17222
|
-
}),
|
|
17223
|
-
/* @__PURE__ */ u(SettingsSwitchRow, {
|
|
17224
|
-
checked: values.syncEnabled,
|
|
17225
|
-
className: "field",
|
|
17226
|
-
id: "syncEnabled",
|
|
17227
|
-
label: "Enable sync",
|
|
17228
|
-
onCheckedChange: onSwitchInput("syncEnabled")
|
|
17229
|
-
}),
|
|
17230
|
-
/* @__PURE__ */ u("div", {
|
|
17231
|
-
className: "field",
|
|
17232
|
-
children: [
|
|
17233
|
-
/* @__PURE__ */ u("label", {
|
|
17234
|
-
htmlFor: "syncInterval",
|
|
17235
|
-
children: "Sync interval (seconds)"
|
|
17236
|
-
}),
|
|
17237
|
-
/* @__PURE__ */ u(TextInput, {
|
|
17238
|
-
id: "syncInterval",
|
|
17239
|
-
min: "10",
|
|
17240
|
-
onInput: onTextInput("syncInterval"),
|
|
17241
|
-
type: "number",
|
|
17242
|
-
value: values.syncInterval
|
|
17243
|
-
}),
|
|
17244
|
-
/* @__PURE__ */ u("div", {
|
|
17245
|
-
className: "small",
|
|
17246
|
-
children: "How often this device checks for sync work when sync is enabled."
|
|
17247
|
-
})
|
|
17248
|
-
]
|
|
17249
|
-
}),
|
|
17250
|
-
/* @__PURE__ */ u("div", {
|
|
17251
|
-
className: "field settings-advanced",
|
|
17252
|
-
hidden: hiddenUnlessAdvanced(),
|
|
17253
|
-
children: [/* @__PURE__ */ u("label", {
|
|
17254
|
-
htmlFor: "syncHost",
|
|
17255
|
-
children: "Sync host"
|
|
17256
|
-
}), /* @__PURE__ */ u(TextInput, {
|
|
17257
|
-
id: "syncHost",
|
|
17258
|
-
onInput: onTextInput("syncHost"),
|
|
17259
|
-
placeholder: "127.0.0.1",
|
|
17260
|
-
value: values.syncHost
|
|
17261
|
-
})]
|
|
17262
|
-
}),
|
|
17263
|
-
/* @__PURE__ */ u("div", {
|
|
17264
|
-
className: "field settings-advanced",
|
|
17265
|
-
hidden: hiddenUnlessAdvanced(),
|
|
17266
|
-
children: [/* @__PURE__ */ u("label", {
|
|
17267
|
-
htmlFor: "syncPort",
|
|
17268
|
-
children: "Sync port"
|
|
17269
|
-
}), /* @__PURE__ */ u(TextInput, {
|
|
17270
|
-
id: "syncPort",
|
|
17271
|
-
min: "1",
|
|
17272
|
-
onInput: onTextInput("syncPort"),
|
|
17273
|
-
type: "number",
|
|
17274
|
-
value: values.syncPort
|
|
17275
|
-
})]
|
|
17276
|
-
}),
|
|
17277
|
-
/* @__PURE__ */ u(SettingsSwitchRow, {
|
|
17278
|
-
checked: values.syncMdns,
|
|
17279
|
-
className: "field settings-advanced",
|
|
17280
|
-
hidden: hiddenUnlessAdvanced(),
|
|
17281
|
-
id: "syncMdns",
|
|
17282
|
-
label: "Enable mDNS discovery",
|
|
17283
|
-
onCheckedChange: onSwitchInput("syncMdns")
|
|
17284
|
-
}),
|
|
17285
|
-
/* @__PURE__ */ u("div", {
|
|
17286
|
-
className: "field",
|
|
17287
|
-
children: [
|
|
17288
|
-
/* @__PURE__ */ u("label", {
|
|
17289
|
-
htmlFor: "syncCoordinatorUrl",
|
|
17290
|
-
children: "Coordinator URL"
|
|
17291
|
-
}),
|
|
17292
|
-
/* @__PURE__ */ u(TextInput, {
|
|
17293
|
-
disabled: true,
|
|
17294
|
-
id: "syncCoordinatorUrl",
|
|
17295
|
-
placeholder: "https://coord.example.com",
|
|
17296
|
-
value: values.syncCoordinatorUrl
|
|
17297
|
-
}),
|
|
17298
|
-
/* @__PURE__ */ u("div", {
|
|
17299
|
-
className: "small",
|
|
17300
|
-
children: protectedConfigHelp("sync_coordinator_url")
|
|
17301
|
-
})
|
|
17302
|
-
]
|
|
17303
|
-
}),
|
|
17304
|
-
/* @__PURE__ */ u("div", {
|
|
17305
|
-
className: "field",
|
|
17306
|
-
children: [
|
|
17307
|
-
/* @__PURE__ */ u("label", {
|
|
17308
|
-
htmlFor: "syncCoordinatorGroup",
|
|
17309
|
-
children: "Coordinator group"
|
|
17310
|
-
}),
|
|
17311
|
-
/* @__PURE__ */ u(TextInput, {
|
|
17312
|
-
id: "syncCoordinatorGroup",
|
|
17313
|
-
onInput: onTextInput("syncCoordinatorGroup"),
|
|
17314
|
-
placeholder: "team-alpha",
|
|
17315
|
-
value: values.syncCoordinatorGroup
|
|
17316
|
-
}),
|
|
17317
|
-
/* @__PURE__ */ u("div", {
|
|
17318
|
-
className: "small",
|
|
17319
|
-
children: "Discovery namespace for peers using the same coordinator."
|
|
17320
|
-
})
|
|
17321
|
-
]
|
|
17322
|
-
}),
|
|
17323
|
-
/* @__PURE__ */ u("div", {
|
|
17324
|
-
className: "field settings-advanced",
|
|
17325
|
-
hidden: hiddenUnlessAdvanced(),
|
|
17326
|
-
children: /* @__PURE__ */ u(SettingsHint, {
|
|
17327
|
-
hidden: hiddenUnlessAdvanced(),
|
|
17328
|
-
children: "These network overrides are for unusual local-network setups. Leave them alone unless you know this device needs non-default sync discovery or coordinator timing."
|
|
17329
|
-
})
|
|
17330
|
-
}),
|
|
17331
|
-
/* @__PURE__ */ u("div", {
|
|
17332
|
-
className: "field settings-advanced",
|
|
17333
|
-
hidden: hiddenUnlessAdvanced(),
|
|
17334
|
-
children: [/* @__PURE__ */ u("label", {
|
|
17335
|
-
htmlFor: "syncCoordinatorTimeout",
|
|
17336
|
-
children: "Coordinator timeout (seconds)"
|
|
17337
|
-
}), /* @__PURE__ */ u(TextInput, {
|
|
17338
|
-
id: "syncCoordinatorTimeout",
|
|
17339
|
-
min: "1",
|
|
17340
|
-
onInput: onTextInput("syncCoordinatorTimeout"),
|
|
17341
|
-
type: "number",
|
|
17342
|
-
value: values.syncCoordinatorTimeout
|
|
17343
|
-
})]
|
|
17344
|
-
}),
|
|
17345
|
-
/* @__PURE__ */ u("div", {
|
|
17346
|
-
className: "field settings-advanced",
|
|
17347
|
-
hidden: hiddenUnlessAdvanced(),
|
|
17348
|
-
children: [/* @__PURE__ */ u("label", {
|
|
17349
|
-
htmlFor: "syncCoordinatorPresenceTtl",
|
|
17350
|
-
children: "Presence TTL (seconds)"
|
|
17351
|
-
}), /* @__PURE__ */ u(TextInput, {
|
|
17352
|
-
id: "syncCoordinatorPresenceTtl",
|
|
17353
|
-
min: "1",
|
|
17354
|
-
onInput: onTextInput("syncCoordinatorPresenceTtl"),
|
|
17355
|
-
type: "number",
|
|
17356
|
-
value: values.syncCoordinatorPresenceTtl
|
|
17357
|
-
})]
|
|
17358
|
-
})
|
|
17359
|
-
]
|
|
17360
|
-
}),
|
|
17361
|
-
/* @__PURE__ */ u(AnchorPeerSetupCard, {}),
|
|
17362
|
-
/* @__PURE__ */ u(SharingDomainsPanel, {})
|
|
17363
|
-
] });
|
|
17364
|
-
}
|
|
17365
|
-
function AnchorPeerSetupCard() {
|
|
17366
|
-
return /* @__PURE__ */ u("section", {
|
|
17367
|
-
"aria-labelledby": "anchor-peer-setup-title",
|
|
17368
|
-
className: "settings-group",
|
|
17369
|
-
children: [
|
|
17370
|
-
/* @__PURE__ */ u("h3", {
|
|
17371
|
-
className: "settings-group-title",
|
|
17372
|
-
id: "anchor-peer-setup-title",
|
|
17373
|
-
children: "Always-on peers"
|
|
17115
|
+
/* @__PURE__ */ u(SettingsSwitchRow, {
|
|
17116
|
+
checked: values.syncMdns,
|
|
17117
|
+
className: "field settings-advanced",
|
|
17118
|
+
hidden: hiddenUnlessAdvanced(),
|
|
17119
|
+
id: "syncMdns",
|
|
17120
|
+
label: "Enable mDNS discovery",
|
|
17121
|
+
onCheckedChange: onSwitchInput("syncMdns")
|
|
17374
17122
|
}),
|
|
17375
|
-
/* @__PURE__ */ u("
|
|
17376
|
-
className: "
|
|
17377
|
-
children:
|
|
17123
|
+
/* @__PURE__ */ u("div", {
|
|
17124
|
+
className: "field",
|
|
17125
|
+
children: [
|
|
17126
|
+
/* @__PURE__ */ u("label", {
|
|
17127
|
+
htmlFor: "syncCoordinatorUrl",
|
|
17128
|
+
children: "Coordinator URL"
|
|
17129
|
+
}),
|
|
17130
|
+
/* @__PURE__ */ u(TextInput, {
|
|
17131
|
+
disabled: true,
|
|
17132
|
+
id: "syncCoordinatorUrl",
|
|
17133
|
+
placeholder: "https://coord.example.com",
|
|
17134
|
+
value: values.syncCoordinatorUrl
|
|
17135
|
+
}),
|
|
17136
|
+
/* @__PURE__ */ u("div", {
|
|
17137
|
+
className: "small",
|
|
17138
|
+
children: protectedConfigHelp("sync_coordinator_url")
|
|
17139
|
+
})
|
|
17140
|
+
]
|
|
17378
17141
|
}),
|
|
17379
|
-
/* @__PURE__ */ u("
|
|
17380
|
-
className: "
|
|
17142
|
+
/* @__PURE__ */ u("div", {
|
|
17143
|
+
className: "field",
|
|
17381
17144
|
children: [
|
|
17382
|
-
/* @__PURE__ */ u("
|
|
17383
|
-
|
|
17384
|
-
|
|
17385
|
-
|
|
17145
|
+
/* @__PURE__ */ u("label", {
|
|
17146
|
+
htmlFor: "syncCoordinatorGroup",
|
|
17147
|
+
children: "Coordinator group"
|
|
17148
|
+
}),
|
|
17149
|
+
/* @__PURE__ */ u(TextInput, {
|
|
17150
|
+
id: "syncCoordinatorGroup",
|
|
17151
|
+
onInput: onTextInput("syncCoordinatorGroup"),
|
|
17152
|
+
placeholder: "team-alpha",
|
|
17153
|
+
value: values.syncCoordinatorGroup
|
|
17154
|
+
}),
|
|
17155
|
+
/* @__PURE__ */ u("div", {
|
|
17156
|
+
className: "small",
|
|
17157
|
+
children: "Discovery namespace for peers using the same coordinator."
|
|
17158
|
+
})
|
|
17386
17159
|
]
|
|
17387
17160
|
}),
|
|
17388
|
-
/* @__PURE__ */ u("
|
|
17389
|
-
className: "settings-
|
|
17390
|
-
|
|
17391
|
-
|
|
17392
|
-
|
|
17393
|
-
|
|
17161
|
+
/* @__PURE__ */ u("div", {
|
|
17162
|
+
className: "field settings-advanced",
|
|
17163
|
+
hidden: hiddenUnlessAdvanced(),
|
|
17164
|
+
children: /* @__PURE__ */ u(SettingsHint, {
|
|
17165
|
+
hidden: hiddenUnlessAdvanced(),
|
|
17166
|
+
children: "These network overrides are for unusual local-network setups. Leave them alone unless you know this device needs non-default sync discovery or coordinator timing."
|
|
17167
|
+
})
|
|
17168
|
+
}),
|
|
17169
|
+
/* @__PURE__ */ u("div", {
|
|
17170
|
+
className: "field settings-advanced",
|
|
17171
|
+
hidden: hiddenUnlessAdvanced(),
|
|
17172
|
+
children: [/* @__PURE__ */ u("label", {
|
|
17173
|
+
htmlFor: "syncCoordinatorTimeout",
|
|
17174
|
+
children: "Coordinator timeout (seconds)"
|
|
17175
|
+
}), /* @__PURE__ */ u(TextInput, {
|
|
17176
|
+
id: "syncCoordinatorTimeout",
|
|
17177
|
+
min: "1",
|
|
17178
|
+
onInput: onTextInput("syncCoordinatorTimeout"),
|
|
17179
|
+
type: "number",
|
|
17180
|
+
value: values.syncCoordinatorTimeout
|
|
17181
|
+
})]
|
|
17182
|
+
}),
|
|
17183
|
+
/* @__PURE__ */ u("div", {
|
|
17184
|
+
className: "field settings-advanced",
|
|
17185
|
+
hidden: hiddenUnlessAdvanced(),
|
|
17186
|
+
children: [/* @__PURE__ */ u("label", {
|
|
17187
|
+
htmlFor: "syncCoordinatorPresenceTtl",
|
|
17188
|
+
children: "Presence TTL (seconds)"
|
|
17189
|
+
}), /* @__PURE__ */ u(TextInput, {
|
|
17190
|
+
id: "syncCoordinatorPresenceTtl",
|
|
17191
|
+
min: "1",
|
|
17192
|
+
onInput: onTextInput("syncCoordinatorPresenceTtl"),
|
|
17193
|
+
type: "number",
|
|
17194
|
+
value: values.syncCoordinatorPresenceTtl
|
|
17195
|
+
})]
|
|
17394
17196
|
})
|
|
17395
17197
|
]
|
|
17396
|
-
});
|
|
17198
|
+
})] });
|
|
17397
17199
|
}
|
|
17398
17200
|
//#endregion
|
|
17399
17201
|
//#region src/tabs/settings/components/SettingsModalContent.tsx
|
|
17400
17202
|
function SettingsModalContent({ panelProps, activeTab, showAdvanced, renderState, settingsDirty, onClose, onSave, onActiveTabChange, onAdvancedToggle, observerStatusBannerSlot }) {
|
|
17203
|
+
const saveDisabled = !settingsDirty || renderState.isSaving;
|
|
17401
17204
|
return /* @__PURE__ */ u("div", {
|
|
17402
17205
|
className: "modal-card",
|
|
17206
|
+
onKeyDown: (event) => handlePrimaryActionKeyboard(event, {
|
|
17207
|
+
onSubmit: onSave,
|
|
17208
|
+
disabled: saveDisabled
|
|
17209
|
+
}),
|
|
17403
17210
|
children: [
|
|
17404
17211
|
/* @__PURE__ */ u("div", {
|
|
17405
17212
|
className: "modal-header",
|
|
@@ -17504,7 +17311,8 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
17504
17311
|
children: renderState.statusText
|
|
17505
17312
|
}), /* @__PURE__ */ u("button", {
|
|
17506
17313
|
className: "settings-save",
|
|
17507
|
-
|
|
17314
|
+
"data-primary-action": "true",
|
|
17315
|
+
disabled: saveDisabled,
|
|
17508
17316
|
id: "settingsSave",
|
|
17509
17317
|
onClick: onSave,
|
|
17510
17318
|
type: "button",
|
|
@@ -18924,6 +18732,24 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
18924
18732
|
}
|
|
18925
18733
|
//#endregion
|
|
18926
18734
|
//#region src/tabs/sync/diagnostics/render/sync-status.ts
|
|
18735
|
+
function numeric(value) {
|
|
18736
|
+
const parsed = Number(value ?? 0);
|
|
18737
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
18738
|
+
}
|
|
18739
|
+
function cleanupDiagnosticLabel(cleanup) {
|
|
18740
|
+
const state = String(cleanup?.state ?? "clear");
|
|
18741
|
+
const stale = cleanup?.stale_peer_rows ?? {};
|
|
18742
|
+
const ops = cleanup?.access_cleanup_ops ?? {};
|
|
18743
|
+
const wouldRemove = numeric(stale.would_remove);
|
|
18744
|
+
const ambiguous = numeric(stale.ambiguous);
|
|
18745
|
+
const applied = numeric(ops.applied);
|
|
18746
|
+
const sourceAuthored = numeric(ops.source_authored);
|
|
18747
|
+
if (state === "cleanup_pending" || wouldRemove > 0) return `${wouldRemove} pending removal`;
|
|
18748
|
+
if (state === "needs_review" || ambiguous > 0) return `${ambiguous} needs review`;
|
|
18749
|
+
if (state === "cleanup_applied" || applied > 0) return `${applied} applied`;
|
|
18750
|
+
if (state === "cleanup_announced" || sourceAuthored > 0) return `${sourceAuthored} announced`;
|
|
18751
|
+
return "Clear";
|
|
18752
|
+
}
|
|
18927
18753
|
function renderSyncStatus() {
|
|
18928
18754
|
const syncStatusGrid = document.getElementById("syncStatusGrid");
|
|
18929
18755
|
const syncMeta = document.getElementById("syncMeta");
|
|
@@ -18948,6 +18774,10 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
18948
18774
|
const daemonDetail = String(status.daemon_detail || "");
|
|
18949
18775
|
const daemonState = String(status.daemon_state || "unknown");
|
|
18950
18776
|
const retention = status.retention || {};
|
|
18777
|
+
const cleanup = status.cleanup_diagnostics;
|
|
18778
|
+
const cleanupStale = cleanup?.stale_peer_rows ?? {};
|
|
18779
|
+
const cleanupWouldRemove = numeric(cleanupStale.would_remove);
|
|
18780
|
+
const cleanupAmbiguous = numeric(cleanupStale.ambiguous);
|
|
18951
18781
|
const retentionEnabled = retention.enabled === true;
|
|
18952
18782
|
const retentionDeleted = Number(retention.last_deleted_ops || 0);
|
|
18953
18783
|
const retentionLastRunAt = retention.last_run_at || null;
|
|
@@ -18966,6 +18796,8 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
18966
18796
|
if (daemonDetail && daemonState === "stopped") parts.push(`Detail: ${daemonDetail}`);
|
|
18967
18797
|
if (daemonDetail && (daemonState === "needs_attention" || daemonState === "rebootstrapping")) parts.push(`Detail: ${daemonDetail}`);
|
|
18968
18798
|
if (retentionEnabled) parts.push(retentionLastRunAt ? `Retention last ran ${formatAgeShort(secondsSince(retentionLastRunAt))} ago (approx oldest-first)` : "Retention enabled");
|
|
18799
|
+
if (cleanupWouldRemove > 0) parts.push(`${cleanupWouldRemove.toLocaleString()} stale peer rows pending cleanup`);
|
|
18800
|
+
else if (cleanupAmbiguous > 0) parts.push(`${cleanupAmbiguous.toLocaleString()} stale peer rows retained because safe cleanup could not be proven`);
|
|
18969
18801
|
syncMeta.textContent = parts.join(" · ");
|
|
18970
18802
|
}
|
|
18971
18803
|
const items = syncDisabled ? [
|
|
@@ -19040,6 +18872,10 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
19040
18872
|
label: retentionLastError,
|
|
19041
18873
|
value: "Retention"
|
|
19042
18874
|
});
|
|
18875
|
+
if (!syncDisabled && !syncNoPeers && cleanup) items.push({
|
|
18876
|
+
label: "Cleanup",
|
|
18877
|
+
value: cleanupDiagnosticLabel(cleanup)
|
|
18878
|
+
});
|
|
19043
18879
|
renderDiagnosticsGrid(syncStatusGrid, items);
|
|
19044
18880
|
const actions = [];
|
|
19045
18881
|
if (syncNoPeers) {} else if (daemonState === "offline-peers") {} else if (daemonState === "stopped") {
|
|
@@ -19072,6 +18908,14 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
19072
18908
|
label: "Pending sync work detected. Run one pass now.",
|
|
19073
18909
|
command: "codemem sync once"
|
|
19074
18910
|
});
|
|
18911
|
+
if (!syncDisabled && cleanupAmbiguous > 0) actions.push({
|
|
18912
|
+
label: "Some stale peer rows were retained because cleanup was ambiguous.",
|
|
18913
|
+
command: "codemem sync doctor"
|
|
18914
|
+
});
|
|
18915
|
+
else if (!syncDisabled && cleanupWouldRemove > 0) actions.push({
|
|
18916
|
+
label: "Stale peer rows are eligible for cleanup. Run one sync pass now.",
|
|
18917
|
+
command: "codemem sync once"
|
|
18918
|
+
});
|
|
19075
18919
|
renderActionList(syncActions, actions);
|
|
19076
18920
|
}
|
|
19077
18921
|
//#endregion
|
|
@@ -19304,11 +19148,16 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
19304
19148
|
disabled: renameBusy || mergeBusy,
|
|
19305
19149
|
type: "text",
|
|
19306
19150
|
value: name,
|
|
19307
|
-
onInput: (event) => setName(event.currentTarget.value)
|
|
19151
|
+
onInput: (event) => setName(event.currentTarget.value),
|
|
19152
|
+
onKeyDown: (event) => handlePrimaryActionKeyboard(event, {
|
|
19153
|
+
onSubmit: () => void rename(),
|
|
19154
|
+
disabled: renameBusy || mergeBusy || !name.trim()
|
|
19155
|
+
})
|
|
19308
19156
|
}),
|
|
19309
19157
|
/* @__PURE__ */ u("button", {
|
|
19310
19158
|
type: "button",
|
|
19311
19159
|
className: "settings-button",
|
|
19160
|
+
"data-primary-action": "true",
|
|
19312
19161
|
disabled: renameBusy || mergeBusy,
|
|
19313
19162
|
onClick: () => void rename(),
|
|
19314
19163
|
children: renameLabel
|
|
@@ -20201,6 +20050,12 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
20201
20050
|
const syncActorCreateButton = document.getElementById("syncActorCreateButton");
|
|
20202
20051
|
const syncActorCreateInput = document.getElementById("syncActorCreateInput");
|
|
20203
20052
|
const syncLegacyClaimButton = document.getElementById("syncLegacyClaimButton");
|
|
20053
|
+
syncActorCreateInput?.addEventListener("keydown", (event) => {
|
|
20054
|
+
handlePrimaryActionKeyboard(event, {
|
|
20055
|
+
onSubmit: () => syncActorCreateButton?.click(),
|
|
20056
|
+
disabled: !syncActorCreateButton || syncActorCreateButton.disabled
|
|
20057
|
+
});
|
|
20058
|
+
});
|
|
20204
20059
|
syncActorCreateButton?.addEventListener("click", async () => {
|
|
20205
20060
|
if (!syncActorCreateButton || !syncActorCreateInput) return;
|
|
20206
20061
|
const displayName = String(syncActorCreateInput.value || "").trim();
|
|
@@ -20428,6 +20283,12 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
20428
20283
|
}
|
|
20429
20284
|
}
|
|
20430
20285
|
});
|
|
20286
|
+
syncJoinInvite?.addEventListener("keydown", (event) => {
|
|
20287
|
+
handlePrimaryActionKeyboard(event, {
|
|
20288
|
+
onSubmit: () => syncJoinButton?.click(),
|
|
20289
|
+
disabled: !syncJoinButton || syncJoinButton.disabled
|
|
20290
|
+
});
|
|
20291
|
+
});
|
|
20431
20292
|
syncJoinButton?.addEventListener("click", async () => {
|
|
20432
20293
|
if (!syncJoinButton || !syncJoinInvite) return;
|
|
20433
20294
|
const inviteValue = syncJoinInvite.value.trim();
|
|
@@ -21380,6 +21241,72 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
21380
21241
|
default: return "Other Space";
|
|
21381
21242
|
}
|
|
21382
21243
|
}
|
|
21244
|
+
function formatSampleDate(value) {
|
|
21245
|
+
if (!value) return "date unavailable";
|
|
21246
|
+
const date = new Date(value);
|
|
21247
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
21248
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
21249
|
+
day: "numeric",
|
|
21250
|
+
month: "short",
|
|
21251
|
+
timeZone: "UTC",
|
|
21252
|
+
year: "numeric"
|
|
21253
|
+
}).format(date);
|
|
21254
|
+
}
|
|
21255
|
+
function sampleOrigin(sample) {
|
|
21256
|
+
if (sample.gitRemote) return sample.gitRemote;
|
|
21257
|
+
if (sample.cwd) return sample.cwd;
|
|
21258
|
+
if (sample.project) return sample.project;
|
|
21259
|
+
return "source identity unavailable";
|
|
21260
|
+
}
|
|
21261
|
+
function LegacyMemorySamples({ group }) {
|
|
21262
|
+
const samples = group.memorySamples ?? [];
|
|
21263
|
+
const shownCount = samples.length;
|
|
21264
|
+
return /* @__PURE__ */ u("details", {
|
|
21265
|
+
className: "legacy-review-samples",
|
|
21266
|
+
children: [
|
|
21267
|
+
/* @__PURE__ */ u("summary", { children: ["Inspect affected memories", shownCount ? ` (${shownCount} sample${shownCount === 1 ? "" : "s"})` : ""] }),
|
|
21268
|
+
/* @__PURE__ */ u("div", {
|
|
21269
|
+
className: "legacy-review-cleanup-note",
|
|
21270
|
+
children: "Showing representative memories from this project group before reassignment. Local memories can be reassigned; peer-owned memories stay in review on this device."
|
|
21271
|
+
}),
|
|
21272
|
+
samples.length > 0 ? /* @__PURE__ */ u("ul", {
|
|
21273
|
+
className: "legacy-review-sample-list",
|
|
21274
|
+
children: samples.map((sample) => /* @__PURE__ */ u("li", {
|
|
21275
|
+
className: "legacy-review-sample",
|
|
21276
|
+
children: [
|
|
21277
|
+
/* @__PURE__ */ u("div", {
|
|
21278
|
+
className: "legacy-review-sample-title",
|
|
21279
|
+
children: sample.title
|
|
21280
|
+
}),
|
|
21281
|
+
/* @__PURE__ */ u("div", {
|
|
21282
|
+
className: "legacy-review-group-meta",
|
|
21283
|
+
children: [
|
|
21284
|
+
sample.kind || "memory",
|
|
21285
|
+
" · ",
|
|
21286
|
+
formatSampleDate(sample.updatedAt ?? sample.createdAt),
|
|
21287
|
+
" ",
|
|
21288
|
+
"·",
|
|
21289
|
+
" ",
|
|
21290
|
+
sample.ownership === "local" ? "local, reassignable" : "peer-owned, stays in review"
|
|
21291
|
+
]
|
|
21292
|
+
}),
|
|
21293
|
+
sample.bodyPreview ? /* @__PURE__ */ u("div", {
|
|
21294
|
+
className: "legacy-review-sample-body",
|
|
21295
|
+
children: sample.bodyPreview
|
|
21296
|
+
}) : null,
|
|
21297
|
+
/* @__PURE__ */ u("div", {
|
|
21298
|
+
className: "legacy-review-group-meta mono",
|
|
21299
|
+
children: sampleOrigin(sample)
|
|
21300
|
+
})
|
|
21301
|
+
]
|
|
21302
|
+
}, sample.id))
|
|
21303
|
+
}) : /* @__PURE__ */ u("div", {
|
|
21304
|
+
className: "legacy-review-cleanup-note",
|
|
21305
|
+
children: "No samples are available for this group. Refresh Sync and try again before reassigning."
|
|
21306
|
+
})
|
|
21307
|
+
]
|
|
21308
|
+
});
|
|
21309
|
+
}
|
|
21383
21310
|
function formatLegacyReviewError(error, scopeId, targetScopes) {
|
|
21384
21311
|
let result = (error instanceof Error ? error.message : "Unable to reassign legacy review memories.").replace(/sharing domain/gi, "Space");
|
|
21385
21312
|
if (scopeId) result = result.replace(new RegExp(`\\b${escapeRegExp(scopeId)}\\b`, "g"), targetScopeLabel(scopeId, targetScopes));
|
|
@@ -21578,7 +21505,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
21578
21505
|
}),
|
|
21579
21506
|
/* @__PURE__ */ u("div", {
|
|
21580
21507
|
className: "peer-meta legacy-review-warning",
|
|
21581
|
-
children: "
|
|
21508
|
+
children: "Fix peer-owned projects on their source device. Reassignment updates future sync authorization; online compatible peers should converge after syncing, but offline devices, backups, copied databases, malicious peers, or old versions may retain old copies."
|
|
21582
21509
|
})
|
|
21583
21510
|
] }), /* @__PURE__ */ u("div", {
|
|
21584
21511
|
className: "actor-actions",
|
|
@@ -21679,7 +21606,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
21679
21606
|
}),
|
|
21680
21607
|
!canReassignLegacyGroup(group) ? /* @__PURE__ */ u("div", {
|
|
21681
21608
|
className: "legacy-review-cleanup-note",
|
|
21682
|
-
children: "Peer-owned only. These older memories were received from another device, so this device cannot reassign them to a Space."
|
|
21609
|
+
children: "Peer-owned only. These older memories were received from another device, so this device cannot reassign them to a Space. Assign this project to a Space on the source device; after sync, this review should clear here."
|
|
21683
21610
|
}) : group.peerOwnedMemoryCount ? /* @__PURE__ */ u("div", {
|
|
21684
21611
|
className: "legacy-review-cleanup-note",
|
|
21685
21612
|
children: [
|
|
@@ -21734,6 +21661,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
21734
21661
|
"."
|
|
21735
21662
|
]
|
|
21736
21663
|
}) : null,
|
|
21664
|
+
/* @__PURE__ */ u(LegacyMemorySamples, { group }),
|
|
21737
21665
|
targetScopes.length > 0 && onReassign && canReassignLegacyGroup(group) ? /* @__PURE__ */ u("label", {
|
|
21738
21666
|
className: "legacy-review-target",
|
|
21739
21667
|
children: [/* @__PURE__ */ u("span", { children: "Destination Space" }), /* @__PURE__ */ u("select", {
|
|
@@ -21827,6 +21755,22 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
21827
21755
|
identitySource: String(raw.identity_source || "unknown"),
|
|
21828
21756
|
lastUpdatedAt: typeof raw.last_updated_at === "string" ? raw.last_updated_at : null,
|
|
21829
21757
|
memoryCount: Number(raw.memory_count || 0),
|
|
21758
|
+
memorySamples: Array.isArray(raw.memory_samples) ? raw.memory_samples.map((sample) => {
|
|
21759
|
+
const sampleRaw = sample;
|
|
21760
|
+
const ownership = sampleRaw.ownership === "peer" ? "peer" : "local";
|
|
21761
|
+
return {
|
|
21762
|
+
bodyPreview: typeof sampleRaw.body_preview === "string" ? sampleRaw.body_preview : null,
|
|
21763
|
+
createdAt: typeof sampleRaw.created_at === "string" ? sampleRaw.created_at : null,
|
|
21764
|
+
cwd: typeof sampleRaw.cwd === "string" ? sampleRaw.cwd : null,
|
|
21765
|
+
gitRemote: typeof sampleRaw.git_remote === "string" ? sampleRaw.git_remote : null,
|
|
21766
|
+
id: Number(sampleRaw.id || 0),
|
|
21767
|
+
kind: typeof sampleRaw.kind === "string" ? sampleRaw.kind : null,
|
|
21768
|
+
ownership,
|
|
21769
|
+
project: typeof sampleRaw.project === "string" ? sampleRaw.project : null,
|
|
21770
|
+
title: String(sampleRaw.title || `Memory ${Number(sampleRaw.id || 0)}`),
|
|
21771
|
+
updatedAt: typeof sampleRaw.updated_at === "string" ? sampleRaw.updated_at : null
|
|
21772
|
+
};
|
|
21773
|
+
}) : [],
|
|
21830
21774
|
peerOwnedMemoryCount: Number(raw.peer_owned_memory_count || 0),
|
|
21831
21775
|
reassignableMemoryCount: Number(raw.reassignable_memory_count || 0),
|
|
21832
21776
|
suggestedScopeId: typeof raw.suggested_scope_id === "string" ? raw.suggested_scope_id : null,
|
|
@@ -22052,7 +21996,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
22052
21996
|
try {
|
|
22053
21997
|
const runtime = await loadRuntimeInfo();
|
|
22054
21998
|
if (!runtime?.version) return;
|
|
22055
|
-
setRuntimeLabel(runtime.version, "
|
|
21999
|
+
setRuntimeLabel(runtime.version, "36573e4");
|
|
22056
22000
|
} catch {}
|
|
22057
22001
|
}
|
|
22058
22002
|
var lastAnnouncedRefreshState = null;
|
|
@@ -22113,6 +22057,14 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
|
|
|
22113
22057
|
setLegacyUpgradeNotice(false);
|
|
22114
22058
|
return;
|
|
22115
22059
|
}
|
|
22060
|
+
if (event.key === "Enter") {
|
|
22061
|
+
const primary = $("legacyUpgradeReviewGroups");
|
|
22062
|
+
handlePrimaryActionKeyboard(event, {
|
|
22063
|
+
onSubmit: () => primary?.click(),
|
|
22064
|
+
disabled: !primary || primary.disabled
|
|
22065
|
+
});
|
|
22066
|
+
return;
|
|
22067
|
+
}
|
|
22116
22068
|
if (event.key !== "Tab") return;
|
|
22117
22069
|
const focusable = legacyUpgradeFocusableElements();
|
|
22118
22070
|
if (focusable.length === 0) return;
|