weir-harness 1.2.2 → 2.0.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/cordis.patch.yml +7 -18
- package/lib/client.file-lease-badge.js +307 -0
- package/lib/client.js +20 -30
- package/lib/client.settings-page.js +10 -34
- package/package.json +2 -2
- package/src/capabilities/store/checked-contract.d.ts +2 -2
- package/src/capabilities/store/fs-adapter.js +2 -3
- package/src/context-guard/index.js +2 -2
- package/src/delegate/supervision-mount.js +5 -5
- package/src/delegate/tool.js +2 -10
- package/src/file-lease/client.js +1066 -0
- package/src/file-lease/index.js +30 -0
- package/src/file-lease/lineage.js +207 -0
- package/src/file-lease/node-contracts.d.ts +42 -0
- package/src/file-lease/plugin.js +789 -0
- package/src/file-lease/singleton.js +155 -0
- package/src/file-lease/spawn.js +62 -0
- package/src/file-lease/tools.js +459 -0
- package/src/file-lease/view.js +144 -0
- package/src/hashline-edit/index.js +76 -42
- package/src/hashline-edit/write-tool.js +90 -0
- package/src/intent-gate/matcher.js +27 -0
- package/src/lease-broker/entry.js +98 -0
- package/src/lease-broker/node-contracts.d.ts +63 -0
- package/src/lease-broker/protocol.js +236 -0
- package/src/lease-broker/server.js +399 -0
- package/src/lease-broker/state.js +425 -0
- package/src/lsp/admin.js +24 -13
- package/src/lsp/index.js +5 -2
- package/src/lsp/registry.js +83 -17
- package/src/lsp/tools.js +137 -27
- package/src/notify/commands.js +15 -2
- package/src/notify/index.js +48 -10
- package/src/notify/web-channel.js +26 -3
- package/src/process/index.js +11 -0
- package/src/settings/index.js +2 -44
- package/src/settings/sections.js +29 -28
- package/src/shared/audit.js +6 -1
- package/src/todo-driver/index.js +1 -6
- package/src/worktree/cards.js +6 -21
- package/src/worktree/lane-core.js +1 -19
- package/src/worktree/lane-workflows.js +11 -32
- package/lib/client.edit-lock-maintenance.js +0 -592
- package/lib/client.edit-lock-panel.js +0 -405
- package/src/edit-lock/adapter.js +0 -57
- package/src/edit-lock/admin-ledger.js +0 -149
- package/src/edit-lock/admin-recovery.js +0 -151
- package/src/edit-lock/admission.js +0 -82
- package/src/edit-lock/binding-attestation.js +0 -29
- package/src/edit-lock/binding-guidance.js +0 -72
- package/src/edit-lock/binding-machine.js +0 -312
- package/src/edit-lock/call-context.js +0 -65
- package/src/edit-lock/derived-facts.js +0 -67
- package/src/edit-lock/domain.js +0 -165
- package/src/edit-lock/domains.js +0 -170
- package/src/edit-lock/host.js +0 -149
- package/src/edit-lock/incarnations.js +0 -150
- package/src/edit-lock/index.js +0 -1303
- package/src/edit-lock/inspect.js +0 -219
- package/src/edit-lock/lifecycle.js +0 -579
- package/src/edit-lock/limits.js +0 -61
- package/src/edit-lock/maintenance.js +0 -310
- package/src/edit-lock/manager.js +0 -875
- package/src/edit-lock/negotiation.js +0 -132
- package/src/edit-lock/operation-history.js +0 -214
- package/src/edit-lock/peer-client.js +0 -86
- package/src/edit-lock/peer-transport.js +0 -76
- package/src/edit-lock/peer.js +0 -87
- package/src/edit-lock/publisher.js +0 -191
- package/src/edit-lock/read-authority.js +0 -101
- package/src/edit-lock/recovery.js +0 -139
- package/src/edit-lock/remote.js +0 -362
- package/src/edit-lock/request-binding.js +0 -42
- package/src/edit-lock/request-data.js +0 -40
- package/src/edit-lock/reservation.js +0 -301
- package/src/edit-lock/reserved-runtime.js +0 -45
- package/src/edit-lock/resource-identity.js +0 -130
- package/src/edit-lock/runtime.js +0 -145
- package/src/edit-lock/settle.js +0 -144
- package/src/edit-lock/snapshot.js +0 -175
- package/src/edit-lock/stale-sweep.js +0 -120
- package/src/edit-lock/state.js +0 -462
- package/src/edit-lock/store.js +0 -327
- package/src/edit-lock/tool-scope.js +0 -29
- package/src/edit-lock/view.js +0 -170
- package/src/edit-lock/write-scopes.js +0 -48
- package/src/edit-lock/write-tool.js +0 -45
- package/src/shared/delegate-edit-lifecycle.js +0 -36
- package/src/worktree/authority.js +0 -56
|
@@ -1,592 +0,0 @@
|
|
|
1
|
-
window.__ModuleLoader__.load({
|
|
2
|
-
id: "weir-harness",
|
|
3
|
-
chunk: "client.edit-lock-maintenance.js",
|
|
4
|
-
factory: (require) => {
|
|
5
|
-
var module = { exports: {} };
|
|
6
|
-
var exports = module.exports;
|
|
7
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
|
-
let react = require("react");
|
|
9
|
-
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
|
-
// Edit Lock maintenance panel (settings "Editing" group): the
|
|
11
|
-
// profile-wide switch status (SAVED vs actually mounted, restart
|
|
12
|
-
// semantics) plus read-only authority inspection per server-derived
|
|
13
|
-
// domain root, over the composition root's HTTP channel adapter
|
|
14
|
-
// (props.channel: (endpoint, payload?) => Promise<{ ok: true, value } |
|
|
15
|
-
// { ok: false, error }>, never rejecting; "/api/weir-edit-lock/maintenance/*").
|
|
16
|
-
// The panel never sends a path the server did not list first, and it
|
|
17
|
-
// offers recovery only while the manager is mounted. The switch itself
|
|
18
|
-
// field. Style constants are verbatim copies of the settings-page
|
|
19
|
-
// constants this panel uses (same-package sync require is impossible
|
|
20
|
-
// in the ModuleLoader).
|
|
21
|
-
const rowStyle = { display: "flex", alignItems: "center", justifyContent: "space-between", gap: "12px", padding: "10px 0" };
|
|
22
|
-
const labelGroupStyle = { display: "flex", flexDirection: "column", gap: "2px", minWidth: 0 };
|
|
23
|
-
const labelStyle = { fontSize: "14px", fontWeight: 500, lineHeight: "20px" };
|
|
24
|
-
const hintStyle = { fontSize: "12px", lineHeight: "16px", color: "var(--dsw-alias-label-secondary)" };
|
|
25
|
-
const warnStyle = { fontSize: "12px", lineHeight: "16px", color: "var(--dsw-alias-state-warn-primary)" };
|
|
26
|
-
const dangerStyle = { fontSize: "12px", lineHeight: "16px", color: "var(--dsw-alias-state-business-danger, #d64545)" };
|
|
27
|
-
const chainPanelStyle = { display: "flex", flexDirection: "column", gap: "12px", padding: "12px", border: "1px solid var(--dsw-alias-border-l2)", borderRadius: "var(--dsw-radius-md)", background: "var(--dsw-alias-interactive-bg-solid)", marginTop: "8px" };
|
|
28
|
-
const chainCategoryStyle = { fontSize: "13px", fontWeight: 600, lineHeight: "18px" };
|
|
29
|
-
const chainDescStyle = { fontSize: "12px", lineHeight: "16px", color: "var(--dsw-alias-label-secondary)" };
|
|
30
|
-
const chainButtonStyle = { background: "none", border: "none", cursor: "pointer", fontSize: "12px", color: "var(--dsw-alias-label-secondary)", textDecoration: "underline" };
|
|
31
|
-
const domainRowStyle = { display: "flex", alignItems: "center", justifyContent: "space-between", gap: "12px", padding: "6px 0" };
|
|
32
|
-
const monoStyle = { fontSize: "12px", lineHeight: "16px", fontFamily: "monospace", wordBreak: "break-all" };
|
|
33
|
-
// ---- Online administrative recovery (proposals from the host) ------
|
|
34
|
-
// The recovery derivation — eligibility, the scoped confirmation
|
|
35
|
-
// digest, the failing-precondition diagnosis — lives HOST-side
|
|
36
|
-
// (src/edit-lock/inspect.js recoveryProposals), computed from the same
|
|
37
|
-
// parsed authority image the inspection summarizes. The panel renders
|
|
38
|
-
// the server proposals and submits their scope and confirmation
|
|
39
|
-
// VERBATIM; it never re-derives a safety-sensitive rule. The manager
|
|
40
|
-
// re-verifies every precondition at commit time either way.
|
|
41
|
-
/** The unmet reason CODES (schemaVersion 1) mapped to dictionary keys;
|
|
42
|
-
* an unknown code falls back to a generic message naming the code. */
|
|
43
|
-
const RECOVERY_REASON_KEYS = {
|
|
44
|
-
"disposition-recorded": "editLockMaintRecoverReasonDispositionRecorded",
|
|
45
|
-
"owner-unknown": "editLockMaintRecoverReasonOwnerUnknown",
|
|
46
|
-
"not-interrupted": "editLockMaintRecoverReasonNotInterrupted",
|
|
47
|
-
"prepared-outstanding": "editLockMaintRecoverReasonPreparedOutstanding",
|
|
48
|
-
"publishing-outstanding": "editLockMaintRecoverReasonPublishingOutstanding",
|
|
49
|
-
"no-unresolved": "editLockMaintRecoverReasonNoUnresolved",
|
|
50
|
-
};
|
|
51
|
-
/** The fail-closed gate (a new client meeting an old or evolved host):
|
|
52
|
-
* only a schemaVersion-1 proposals payload is rendered at all; anything
|
|
53
|
-
* else disables the online recovery action with refresh guidance.
|
|
54
|
-
* @param {any} value the inspect response value */
|
|
55
|
-
const supportedProposals = (value) => value?.recoveryProposals?.schemaVersion === 1 ? value.recoveryProposals : null;
|
|
56
|
-
/** Recovery state is scoped exactly like the authority: per domain root
|
|
57
|
-
* AND owner. Session ids are not unique across independent domains, so
|
|
58
|
-
* one root's completed recovery must never disable another root's. */
|
|
59
|
-
const recoveryKey = (root, owner) => `${root}\n${owner}`;
|
|
60
|
-
/** Recovery-UX zone copy (D1/D2). The entry dictionaries (client.js) are
|
|
61
|
-
* owned by the entry chunk, so the zone copy lives HERE as
|
|
62
|
-
* template-layer English per the text discipline; the unmet reason prose
|
|
63
|
-
* lives in the dictionaries below (server reason CODES are localized),
|
|
64
|
-
* while file paths, session ids and statuses stay dynamic instance
|
|
65
|
-
* content. */
|
|
66
|
-
const RECOVERY_UX = Object.freeze({
|
|
67
|
-
blockedHeader: "Blocked files — one-click force release",
|
|
68
|
-
blockedHint: "Opening the panel ran the read-only inspection automatically. Each row settles the holder's unresolved publication fence (when present) and releases the lock in one operator-confirmed step.",
|
|
69
|
-
unmetHeader: "Blocked files — recovery preconditions not met",
|
|
70
|
-
forceRelease: "Force release",
|
|
71
|
-
holder: "holder",
|
|
72
|
-
stateFence: "publication fence",
|
|
73
|
-
stateInterrupted: "interrupted",
|
|
74
|
-
stateActive: "active",
|
|
75
|
-
});
|
|
76
|
-
/** Error boundary isolating the maintenance panel from the settings page. */
|
|
77
|
-
class EditLockMaintenanceBoundary extends react.Component {
|
|
78
|
-
constructor(props) {
|
|
79
|
-
super(props);
|
|
80
|
-
this.state = { failed: false };
|
|
81
|
-
}
|
|
82
|
-
static getDerivedStateFromError() {
|
|
83
|
-
return { failed: true };
|
|
84
|
-
}
|
|
85
|
-
render() {
|
|
86
|
-
if (this.state.failed) {
|
|
87
|
-
return react_jsx_runtime.jsx("div", { style: hintStyle, children: this.props.t?.("editLockMaintFailed") ?? "Edit Lock maintenance failed" });
|
|
88
|
-
}
|
|
89
|
-
return this.props.children;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
/** Switch-state banner keys (state names contain hyphens). */
|
|
93
|
-
const STATE_KEYS = { enforced: "Enforced", "disable-requested": "DisableRequested", "enable-requested": "EnableRequested", disabled: "Disabled", unknown: "Unknown" };
|
|
94
|
-
const onlineRecoveryAvailable = (state) => state === "enforced" || state === "disable-requested";
|
|
95
|
-
// Invoke the render callback only during descendant traversal, never while
|
|
96
|
-
// the parent constructs the boundary element.
|
|
97
|
-
function MaintenanceBody({ render }) {
|
|
98
|
-
return react_jsx_runtime.jsx("div", { style: chainPanelStyle, children: render() });
|
|
99
|
-
}
|
|
100
|
-
/** @typedef {{ status: 'loading' } | { status: 'error', message: string } | { status: 'ready', value: ReturnType<typeof import('../src/edit-lock/maintenance.js').maintenanceStatus> }} StatusView */
|
|
101
|
-
function EditLockMaintenanceField(props) {
|
|
102
|
-
const t = props.t;
|
|
103
|
-
const [open, setOpen] = react.useState(false);
|
|
104
|
-
const [view, setView] = react.useState(/** @type {StatusView | null} */ (null));
|
|
105
|
-
const [expanded, setExpanded] = react.useState(/** @type {string | null} */ (null));
|
|
106
|
-
const [inspections, setInspections] = react.useState({});
|
|
107
|
-
const [recoveries, setRecoveries] = react.useState(/** @type {Record<string, {status: 'busy'} | {status: 'done', revision: number, idempotent: boolean} | {status: 'error', message: string}>} */ ({}));
|
|
108
|
-
/** The one explicit action: submit the SERVER-computed confirmation
|
|
109
|
-
* for one displayed scope, unchanged. No hash typing, no restart.
|
|
110
|
-
* A refusal is shown next to a freshly reloaded scope.
|
|
111
|
-
* @param {string} root @param {ReturnType<typeof import('../src/edit-lock/inspect.js').recoveryProposals>['candidates'][number]} candidate */
|
|
112
|
-
const recover = (root, candidate) => {
|
|
113
|
-
if (view?.status !== "ready" || !onlineRecoveryAvailable(view.value.state)) return;
|
|
114
|
-
setRecoveries((previous) => ({ ...previous, [recoveryKey(root, candidate.owner)]: { status: "busy" } }));
|
|
115
|
-
props.channel("api/weir-edit-lock/maintenance/recover-online", {
|
|
116
|
-
root,
|
|
117
|
-
owner: candidate.owner,
|
|
118
|
-
expectedRevision: candidate.scope.expectedRevision,
|
|
119
|
-
operationIds: candidate.scope.operationIds,
|
|
120
|
-
recoveryId: globalThis.crypto?.randomUUID?.() ?? `panel-${Date.now()}-${Math.random().toString(16).slice(2)}`,
|
|
121
|
-
reason: "Confirmed in the Edit Lock maintenance panel: the operator reviewed the displayed scope and accepted the displayed late-writer risk.",
|
|
122
|
-
acceptLateWriterRisk: true,
|
|
123
|
-
confirmation: candidate.confirmation,
|
|
124
|
-
}).then((result) => {
|
|
125
|
-
setRecoveries((previous) => ({ ...previous, [recoveryKey(root, candidate.owner)]: result.ok === true
|
|
126
|
-
? { status: "done", revision: result.value.revision, idempotent: result.value.idempotent === true }
|
|
127
|
-
: { status: "error", message: result.error?.detail ?? result.error?.message ?? "unknown" } }));
|
|
128
|
-
inspect(root);
|
|
129
|
-
}).catch((error) => {
|
|
130
|
-
setRecoveries((previous) => ({ ...previous, [recoveryKey(root, candidate.owner)]: { status: "error", message: String(error?.message ?? error) } }));
|
|
131
|
-
inspect(root);
|
|
132
|
-
});
|
|
133
|
-
};
|
|
134
|
-
const load = () => {
|
|
135
|
-
setView({ status: "loading" });
|
|
136
|
-
props.channel("api/weir-edit-lock/maintenance/status")
|
|
137
|
-
.then((result) => {
|
|
138
|
-
setView(result.ok === true ? { status: "ready", value: result.value } : { status: "error", message: result.error.message });
|
|
139
|
-
// Recovery UX D1: opening the panel auto-runs the read-only
|
|
140
|
-
// inspection for every server-derived domain root, so the
|
|
141
|
-
// blocked/unmet zones render without any manual step. The
|
|
142
|
-
// inspection itself stays read-only (the same endpoint).
|
|
143
|
-
if (result.ok === true && Array.isArray(result.value?.domains)) result.value.domains.forEach((domain) => inspect(domain.root, false));
|
|
144
|
-
})
|
|
145
|
-
.catch((error) => setView({ status: "error", message: String(error?.message ?? error) }));
|
|
146
|
-
};
|
|
147
|
-
const toggle = () => {
|
|
148
|
-
const next = !open;
|
|
149
|
-
setOpen(next);
|
|
150
|
-
setExpanded(null);
|
|
151
|
-
if (next) load();
|
|
152
|
-
};
|
|
153
|
-
/** @param {string} root @param {boolean} [expand] manual clicks expand the per-domain detail; the automatic pass does not */
|
|
154
|
-
const inspect = (root, expand = true) => {
|
|
155
|
-
if (expand) setExpanded(root);
|
|
156
|
-
setInspections((previous) => ({ ...previous, [root]: { status: "loading" } }));
|
|
157
|
-
props.channel("api/weir-edit-lock/maintenance/inspect", { root })
|
|
158
|
-
.then((result) => {
|
|
159
|
-
setInspections((previous) => ({ ...previous, [root]: result.ok === true ? { status: "ready", value: result.value } : { status: "error", message: result.error.message } }));
|
|
160
|
-
})
|
|
161
|
-
.catch((error) => setInspections((previous) => ({ ...previous, [root]: { status: "error", message: String(error?.message ?? error) } })));
|
|
162
|
-
};
|
|
163
|
-
const scopeText = (scope) => {
|
|
164
|
-
if (scope?.kind === "file") return t("editLockMaintScopeFile");
|
|
165
|
-
if (scope?.kind === "subtree") return t("editLockMaintScopeSubtree");
|
|
166
|
-
if (scope?.kind === "domain") return t("editLockMaintScopeDomain");
|
|
167
|
-
return t("editLockMaintScopeNone");
|
|
168
|
-
};
|
|
169
|
-
/** The localized explanation for one server reason CODE; an unknown
|
|
170
|
-
* code falls back to a generic message naming the code itself. */
|
|
171
|
-
const reasonText = (reason) => {
|
|
172
|
-
const key = RECOVERY_REASON_KEYS[reason];
|
|
173
|
-
return key ? t(key) : t("editLockMaintRecoverReasonUnknown").replace("{code}", String(reason ?? ""));
|
|
174
|
-
};
|
|
175
|
-
const presenceRow = (value) => {
|
|
176
|
-
if (value.presence === "valid") return null;
|
|
177
|
-
const key = { none: "editLockMaintPresenceNone", empty: "editLockMaintPresenceEmpty", "no-committed-snapshot": "editLockMaintPresenceJunk", "not-a-file": "editLockMaintPresenceNotAFile", corrupt: "editLockMaintPresenceCorrupt", unreadable: "editLockMaintPresenceUnreadable" }[value.presence];
|
|
178
|
-
return react_jsx_runtime.jsx("div", { style: value.presence === "corrupt" || value.presence === "not-a-file" || value.presence === "no-committed-snapshot" ? dangerStyle : hintStyle, children: `${t(key) ?? value.presence}${value.message ? ` ${value.message}` : ""}` });
|
|
179
|
-
};
|
|
180
|
-
/** Recovery card for one eligible owner: the FULL server scope, the
|
|
181
|
-
* risk text and the server digest, then the one explicit button.
|
|
182
|
-
* @param {string} root @param {ReturnType<typeof import('../src/edit-lock/inspect.js').recoveryProposals>['candidates'][number]} candidate */
|
|
183
|
-
const recoveryCard = (root, candidate) => {
|
|
184
|
-
const state = recoveries[recoveryKey(root, candidate.owner)];
|
|
185
|
-
return react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px", padding: "8px", border: "1px solid var(--dsw-alias-border-l2)", borderRadius: "var(--dsw-radius-md)" }, children: [
|
|
186
|
-
react_jsx_runtime.jsx("div", { style: chainDescStyle, children: `${t("editLockMaintRecoverRoot")}: ${candidate.scope.root}` }),
|
|
187
|
-
react_jsx_runtime.jsx("div", { style: chainDescStyle, children: `${t("editLockMaintRecoverOwner")}: ${candidate.owner}` }),
|
|
188
|
-
react_jsx_runtime.jsx("div", { style: chainDescStyle, children: `${t("editLockMaintRecoverRevision")}: ${candidate.scope.expectedRevision}` }),
|
|
189
|
-
react_jsx_runtime.jsxs("div", { style: chainDescStyle, children: [
|
|
190
|
-
react_jsx_runtime.jsx("div", { children: `${t("editLockMaintRecoverOperations")}:` }),
|
|
191
|
-
...candidate.scope.operationIds.map((id, index) => react_jsx_runtime.jsx("div", { style: monoStyle, children: id }, index))
|
|
192
|
-
] }),
|
|
193
|
-
react_jsx_runtime.jsx("div", { style: dangerStyle, children: `${t("editLockMaintRecoverRisk")}: ${candidate.risk}` }),
|
|
194
|
-
react_jsx_runtime.jsx("div", { style: monoStyle, children: `${t("editLockMaintRecoverDigest")}: ${candidate.confirmation}` }),
|
|
195
|
-
state?.status === "done"
|
|
196
|
-
? react_jsx_runtime.jsx("div", { style: hintStyle, children: t("editLockMaintRecoverDone").replace("{revision}", String(state.revision)) })
|
|
197
|
-
: null,
|
|
198
|
-
state?.status === "error"
|
|
199
|
-
? react_jsx_runtime.jsx("div", { style: dangerStyle, children: `${t("editLockMaintRecoverFailed")} ${state.message}` })
|
|
200
|
-
: null,
|
|
201
|
-
react_jsx_runtime.jsx("div", { children: react_jsx_runtime.jsx("button", {
|
|
202
|
-
type: "button",
|
|
203
|
-
style: chainButtonStyle,
|
|
204
|
-
disabled: state?.status === "busy" || state?.status === "done",
|
|
205
|
-
onClick: () => recover(root, candidate),
|
|
206
|
-
children: state?.status === "busy" ? t("editLockMaintRecoverBusy") : t("editLockMaintRecoverConfirm")
|
|
207
|
-
}) })
|
|
208
|
-
], key: recoveryKey(root, candidate.owner) });
|
|
209
|
-
};
|
|
210
|
-
/** Row state fragment: lock status / publication fence + session liveness. */
|
|
211
|
-
const holderStateText = (row) => {
|
|
212
|
-
const parts = [];
|
|
213
|
-
if (row.lockStatus) parts.push(row.lockStatus);
|
|
214
|
-
if (row.fence) parts.push(RECOVERY_UX.stateFence);
|
|
215
|
-
parts.push(row.interrupted ? RECOVERY_UX.stateInterrupted : RECOVERY_UX.stateActive);
|
|
216
|
-
return parts.join(" · ");
|
|
217
|
-
};
|
|
218
|
-
/** Blocked-zone group for one eligible owner: one row per blocked file
|
|
219
|
-
* (file, holder, holder state, one primary force-release action per
|
|
220
|
-
* row) plus the FULL scope, risk and computed digest the operator
|
|
221
|
-
* accepts with the click — the same confirmation algorithm as the
|
|
222
|
-
* offline path, unchanged. */
|
|
223
|
-
const blockedZoneCard = (root, candidate, rows) => {
|
|
224
|
-
const state = recoveries[recoveryKey(root, candidate.owner)];
|
|
225
|
-
return react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px", padding: "8px", border: "1px solid var(--dsw-alias-border-l2)", borderRadius: "var(--dsw-radius-md)" }, children: [
|
|
226
|
-
...rows.map((row) => react_jsx_runtime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
227
|
-
react_jsx_runtime.jsxs("span", { style: { display: "flex", flexDirection: "column", gap: "2px", minWidth: 0 }, children: [
|
|
228
|
-
react_jsx_runtime.jsx("span", { style: monoStyle, children: row.resourceId }),
|
|
229
|
-
react_jsx_runtime.jsx("span", { style: chainDescStyle, children: `${RECOVERY_UX.holder} ${row.owner} · ${holderStateText(row)}` })
|
|
230
|
-
] }),
|
|
231
|
-
react_jsx_runtime.jsx("span", { style: { flex: 1 } }),
|
|
232
|
-
react_jsx_runtime.jsx("button", {
|
|
233
|
-
type: "button",
|
|
234
|
-
style: chainButtonStyle,
|
|
235
|
-
disabled: state?.status === "busy",
|
|
236
|
-
onClick: () => recover(root, candidate),
|
|
237
|
-
children: state?.status === "busy" ? t("editLockMaintRecoverBusy") : RECOVERY_UX.forceRelease
|
|
238
|
-
})
|
|
239
|
-
], key: row.resourceId })),
|
|
240
|
-
react_jsx_runtime.jsx("div", { style: chainDescStyle, children: `${t("editLockMaintRecoverRoot")}: ${candidate.scope.root}` }),
|
|
241
|
-
react_jsx_runtime.jsx("div", { style: chainDescStyle, children: `${t("editLockMaintRecoverOwner")}: ${candidate.owner}` }),
|
|
242
|
-
react_jsx_runtime.jsx("div", { style: chainDescStyle, children: `${t("editLockMaintRecoverRevision")}: ${candidate.scope.expectedRevision}` }),
|
|
243
|
-
react_jsx_runtime.jsxs("div", { style: chainDescStyle, children: [
|
|
244
|
-
react_jsx_runtime.jsx("div", { children: `${t("editLockMaintRecoverOperations")}:` }),
|
|
245
|
-
...candidate.scope.operationIds.map((id, index) => react_jsx_runtime.jsx("div", { style: monoStyle, children: id }, index))
|
|
246
|
-
] }),
|
|
247
|
-
react_jsx_runtime.jsx("div", { style: dangerStyle, children: `${t("editLockMaintRecoverRisk")}: ${candidate.risk}` }),
|
|
248
|
-
react_jsx_runtime.jsx("div", { style: monoStyle, children: `${t("editLockMaintRecoverDigest")}: ${candidate.confirmation}` }),
|
|
249
|
-
state?.status === "error"
|
|
250
|
-
? react_jsx_runtime.jsx("div", { style: dangerStyle, children: `${t("editLockMaintRecoverFailed")} ${state.message}` })
|
|
251
|
-
: null,
|
|
252
|
-
], key: recoveryKey(root, candidate.owner) });
|
|
253
|
-
};
|
|
254
|
-
/** Unmet-zone row for one ineligible blocking owner: the blocked files
|
|
255
|
-
* and the NAMED failing precondition, never a silent missing action. */
|
|
256
|
-
const unmetZoneRow = (root, entry) => react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px", padding: "8px", border: "1px solid var(--dsw-alias-border-l2)", borderRadius: "var(--dsw-radius-md)" }, children: [
|
|
257
|
-
react_jsx_runtime.jsx("div", { style: chainDescStyle, children: `${t("editLockMaintRecoverOwner")}: ${entry.owner}` }),
|
|
258
|
-
...entry.rows.map((row, index) => react_jsx_runtime.jsx("div", { style: monoStyle, children: `${row.resourceId} · ${RECOVERY_UX.holder} ${row.owner} · ${holderStateText(row)}` }, index)),
|
|
259
|
-
...entry.scopePaths.map((path, index) => react_jsx_runtime.jsx("div", { style: monoStyle, children: path }, index)),
|
|
260
|
-
react_jsx_runtime.jsx("div", { style: dangerStyle, children: reasonText(entry.reason) })
|
|
261
|
-
], key: `${root}\n${entry.owner}\nunmet` });
|
|
262
|
-
const snapshotSection = (/** @type {string} */ root, /** @type {any} */ value) => {
|
|
263
|
-
const snapshot = value.snapshot;
|
|
264
|
-
const proposals = supportedProposals(value);
|
|
265
|
-
return react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
|
|
266
|
-
react_jsx_runtime.jsx("div", { style: chainDescStyle, children: t("editLockMaintCounts")
|
|
267
|
-
.replace("{sessions}", String(snapshot.counts.sessions))
|
|
268
|
-
.replace("{locks}", String(snapshot.counts.locks))
|
|
269
|
-
.replace("{operations}", String(snapshot.counts.operations)) }),
|
|
270
|
-
react_jsx_runtime.jsx("div", { style: chainCategoryStyle, children: t("editLockMaintUnresolved") }),
|
|
271
|
-
snapshot.unresolved.length === 0
|
|
272
|
-
? react_jsx_runtime.jsx("div", { style: chainDescStyle, children: t("editLockMaintUnresolvedNone") })
|
|
273
|
-
: react_jsx_runtime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: snapshot.unresolved.map((op, index) => react_jsx_runtime.jsxs("div", { style: chainDescStyle, children: [
|
|
274
|
-
react_jsx_runtime.jsx("div", { children: `${scopeText(op.scope)}${op.scope.path ? ` — ${op.scope.path}` : ""}` }),
|
|
275
|
-
react_jsx_runtime.jsx("div", { style: monoStyle, children: `${op.target.tool ?? "?"} ${op.target.filePath ?? "?"} · ${op.phase}${op.outcome ? `/${op.outcome}` : ""}${op.closeouts > 0 ? ` · closeouts ${op.closeouts}` : ""}` }),
|
|
276
|
-
react_jsx_runtime.jsx("div", { style: monoStyle, children: `${op.key.sessionId} · ${op.key.operationId} · epoch ${op.origin.executionEpoch ?? "-"}` })
|
|
277
|
-
], key: index })) }),
|
|
278
|
-
snapshot.retainedLocks.length > 0
|
|
279
|
-
? react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
|
|
280
|
-
react_jsx_runtime.jsx("div", { style: chainCategoryStyle, children: t("editLockMaintRetained") }),
|
|
281
|
-
...snapshot.retainedLocks.map((lock, index) => react_jsx_runtime.jsx("div", { style: chainDescStyle, children: `${lock.resourceId} · ${lock.owner} · ${lock.status}${lock.reason ? `: ${lock.reason}` : ""} · gen ${lock.generation}` }, index))
|
|
282
|
-
] })
|
|
283
|
-
: null,
|
|
284
|
-
proposals !== null && onlineRecoveryAvailable(view?.status === "ready" ? view.value.state : null) && Array.isArray(proposals.candidates) && proposals.candidates.length > 0
|
|
285
|
-
? react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
|
|
286
|
-
react_jsx_runtime.jsx("div", { style: chainCategoryStyle, children: t("editLockMaintRecoveries") }),
|
|
287
|
-
react_jsx_runtime.jsx("div", { style: chainDescStyle, children: t("editLockMaintRecoverHint") }),
|
|
288
|
-
...proposals.candidates.map((candidate) => recoveryCard(root, candidate))
|
|
289
|
-
] }) : null
|
|
290
|
-
] });
|
|
291
|
-
};
|
|
292
|
-
const inspectionBody = (root) => {
|
|
293
|
-
const inspection = inspections[root];
|
|
294
|
-
if (!inspection) return null;
|
|
295
|
-
if (inspection.status === "loading") return react_jsx_runtime.jsx("div", { style: hintStyle, children: t("editLockMaintLoading") });
|
|
296
|
-
if (inspection.status === "error") {
|
|
297
|
-
return react_jsx_runtime.jsxs("div", { style: { display: "flex", gap: "12px", alignItems: "center" }, children: [
|
|
298
|
-
react_jsx_runtime.jsx("span", { style: hintStyle, children: `${t("editLockMaintUnavailable")} ${inspection.message}` }),
|
|
299
|
-
react_jsx_runtime.jsx("button", { type: "button", style: chainButtonStyle, onClick: () => inspect(root), children: t("editLockMaintRetry") })
|
|
300
|
-
] });
|
|
301
|
-
}
|
|
302
|
-
const value = inspection.value;
|
|
303
|
-
return react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "6px", paddingTop: "4px" }, children: [
|
|
304
|
-
value.reservation === true ? react_jsx_runtime.jsx("div", { style: hintStyle, children: t("editLockMaintReservation") }) : null,
|
|
305
|
-
presenceRow(value),
|
|
306
|
-
value.presence === "valid" ? snapshotSection(root, value) : null
|
|
307
|
-
] });
|
|
308
|
-
};
|
|
309
|
-
const domainRow = (domain) => react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
|
|
310
|
-
react_jsx_runtime.jsxs("div", { style: domainRowStyle, children: [
|
|
311
|
-
react_jsx_runtime.jsxs("span", { style: labelGroupStyle, children: [
|
|
312
|
-
react_jsx_runtime.jsx("span", { style: monoStyle, children: domain.root }),
|
|
313
|
-
react_jsx_runtime.jsx("span", { style: chainDescStyle, children: [
|
|
314
|
-
domain.hasAuthority === true ? t("editLockMaintAuthorityYes") : t("editLockMaintAuthorityNo"),
|
|
315
|
-
domain.mode ? ` · ${domain.mode}` : "",
|
|
316
|
-
domain.error ? ` · ${domain.error}` : ""
|
|
317
|
-
] })
|
|
318
|
-
] }),
|
|
319
|
-
react_jsx_runtime.jsx("button", { type: "button", style: chainButtonStyle, onClick: () => inspect(domain.root), children: expanded === domain.root ? t("chainCancel") : t("editLockMaintInspect") })
|
|
320
|
-
] }),
|
|
321
|
-
expanded === domain.root ? inspectionBody(domain.root) : null
|
|
322
|
-
], key: domain.root });
|
|
323
|
-
const panelBody = () => {
|
|
324
|
-
if (view === null) return null;
|
|
325
|
-
if (view.status === "loading") return react_jsx_runtime.jsx("div", { style: hintStyle, children: t("editLockMaintLoading") });
|
|
326
|
-
if (view.status === "error") {
|
|
327
|
-
return react_jsx_runtime.jsxs("div", { style: { display: "flex", gap: "12px", alignItems: "center" }, children: [
|
|
328
|
-
react_jsx_runtime.jsx("span", { style: hintStyle, children: `${t("editLockMaintUnavailable")} ${view.message}` }),
|
|
329
|
-
react_jsx_runtime.jsx("button", { type: "button", style: chainButtonStyle, onClick: load, children: t("editLockMaintRetry") })
|
|
330
|
-
] });
|
|
331
|
-
}
|
|
332
|
-
const value = view.value;
|
|
333
|
-
const stateKey = STATE_KEYS[value.state] ?? "Unknown";
|
|
334
|
-
// Retained authority is history, not a current block, without a mounted manager.
|
|
335
|
-
const online = onlineRecoveryAvailable(value.state);
|
|
336
|
-
const zoneGroups = new Map();
|
|
337
|
-
const zoneUnmet = [];
|
|
338
|
-
// Fail closed: a missing or unsupported proposals payload disables
|
|
339
|
-
// every zone derived from it — the panel never re-derives the
|
|
340
|
-
// recovery surface by itself.
|
|
341
|
-
let proposalsUnsupported = false;
|
|
342
|
-
for (const root of Object.keys(inspections)) {
|
|
343
|
-
const inspection = inspections[root];
|
|
344
|
-
if (inspection?.status !== "ready" || inspection.value?.presence !== "valid") continue;
|
|
345
|
-
const proposals = supportedProposals(inspection.value);
|
|
346
|
-
if (!proposals) { proposalsUnsupported = true; continue; }
|
|
347
|
-
for (const candidate of Array.isArray(proposals.candidates) ? proposals.candidates : []) {
|
|
348
|
-
if (!candidate || typeof candidate.owner !== "string" || !Array.isArray(candidate.rows) || candidate.rows.length === 0) continue;
|
|
349
|
-
const key = recoveryKey(root, candidate.owner);
|
|
350
|
-
const group = zoneGroups.get(key) ?? { root, candidate, rows: [] };
|
|
351
|
-
for (const row of candidate.rows) group.rows.push(row);
|
|
352
|
-
zoneGroups.set(key, group);
|
|
353
|
-
}
|
|
354
|
-
for (const entry of Array.isArray(proposals.unmet) ? proposals.unmet : []) zoneUnmet.push({ root, entry });
|
|
355
|
-
}
|
|
356
|
-
const blockedGroups = [...zoneGroups.values()];
|
|
357
|
-
zoneUnmet.sort((a, b) => a.entry.owner.localeCompare(b.entry.owner));
|
|
358
|
-
const historyRows = [...blockedGroups.flatMap((group) => group.rows), ...zoneUnmet.flatMap(({ entry }) => entry.rows)];
|
|
359
|
-
const historyScopes = zoneUnmet.flatMap(({ entry }) => entry.scopePaths);
|
|
360
|
-
for (const root of Object.keys(inspections)) {
|
|
361
|
-
const inspection = inspections[root];
|
|
362
|
-
if (inspection?.status !== "ready" || inspection.value?.presence !== "valid") continue;
|
|
363
|
-
for (const op of inspection.value.snapshot.unresolved) {
|
|
364
|
-
if (op.scope?.kind !== "file" && typeof op.scope?.path === "string" && !historyScopes.includes(op.scope.path)) historyScopes.push(op.scope.path);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
return react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "10px" }, children: [
|
|
368
|
-
react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [
|
|
369
|
-
react_jsx_runtime.jsx("span", { style: chainCategoryStyle, children: t(`editLockMaintState${stateKey}`) }),
|
|
370
|
-
react_jsx_runtime.jsx("span", { style: chainDescStyle, children: t(`editLockMaintState${stateKey}Hint`) }),
|
|
371
|
-
value.restartRequired ? react_jsx_runtime.jsx("span", { style: warnStyle, children: t("editLockMaintRestart") }) : null,
|
|
372
|
-
value.pinned ? react_jsx_runtime.jsx("span", { style: warnStyle, children: t("editLockMaintPinned") }) : null,
|
|
373
|
-
react_jsx_runtime.jsx("span", { style: chainDescStyle, children: t("editLockMaintScopeNote") })
|
|
374
|
-
] }),
|
|
375
|
-
!online ? react_jsx_runtime.jsx("div", { role: "alert", style: warnStyle, children: t(value.state === "unknown" ? "editLockMaintUnknownRisk" : "editLockMaintOffRisk") }) : null,
|
|
376
|
-
!online ? react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
|
|
377
|
-
react_jsx_runtime.jsx("span", { style: chainCategoryStyle, children: t(value.state === "unknown" ? "editLockMaintUnknownHistory" : "editLockMaintHistory") }),
|
|
378
|
-
react_jsx_runtime.jsx("span", { style: chainDescStyle, children: t(value.state === "unknown" ? "editLockMaintUnknownHistoryHint" : "editLockMaintHistoryHint") }),
|
|
379
|
-
...historyRows.map((row, index) => react_jsx_runtime.jsx("span", { style: monoStyle, children: `${row.resourceId} · ${row.owner}${row.lockStatus ? ` · ${row.lockStatus}` : ""}${row.fence ? ` · ${RECOVERY_UX.stateFence}` : ""}` }, index)),
|
|
380
|
-
...historyScopes.map((path, index) => react_jsx_runtime.jsx("span", { style: monoStyle, children: path }, `scope-${index}`))
|
|
381
|
-
] }) : null,
|
|
382
|
-
react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [
|
|
383
|
-
react_jsx_runtime.jsx("span", { style: warnStyle, children: t("editLockMaintWarnKeepHistory") }),
|
|
384
|
-
react_jsx_runtime.jsx("span", { style: warnStyle, children: t("editLockMaintWarnUnlock") })
|
|
385
|
-
] }),
|
|
386
|
-
proposalsUnsupported
|
|
387
|
-
? react_jsx_runtime.jsx("div", { style: warnStyle, children: t("editLockMaintRecoverUpgrade") })
|
|
388
|
-
: null,
|
|
389
|
-
online && blockedGroups.length > 0
|
|
390
|
-
? react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
|
|
391
|
-
react_jsx_runtime.jsx("span", { style: chainCategoryStyle, children: RECOVERY_UX.blockedHeader }),
|
|
392
|
-
react_jsx_runtime.jsx("span", { style: chainDescStyle, children: RECOVERY_UX.blockedHint }),
|
|
393
|
-
...blockedGroups.map((group) => blockedZoneCard(group.root, group.candidate, group.rows))
|
|
394
|
-
] })
|
|
395
|
-
: null,
|
|
396
|
-
online && zoneUnmet.length > 0
|
|
397
|
-
? react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
|
|
398
|
-
react_jsx_runtime.jsx("span", { style: chainCategoryStyle, children: RECOVERY_UX.unmetHeader }),
|
|
399
|
-
...zoneUnmet.map(({ root, entry }) => unmetZoneRow(root, entry))
|
|
400
|
-
] })
|
|
401
|
-
: null,
|
|
402
|
-
value.blocked.length > 0
|
|
403
|
-
? react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
|
|
404
|
-
react_jsx_runtime.jsx("span", { style: chainCategoryStyle, children: t("editLockMaintBlocked") }),
|
|
405
|
-
...value.blocked.map((row, index) => react_jsx_runtime.jsx("span", { style: dangerStyle, children: `${"root" in row ? row.root : "sessionId" in row ? row.sessionId : row.mountId} — ${row.reason}` }, index))
|
|
406
|
-
] })
|
|
407
|
-
: null,
|
|
408
|
-
react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [
|
|
409
|
-
react_jsx_runtime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
|
|
410
|
-
react_jsx_runtime.jsx("span", { style: chainCategoryStyle, children: t("editLockMaintDomains") }),
|
|
411
|
-
react_jsx_runtime.jsx("button", { type: "button", style: chainButtonStyle, onClick: load, children: t("editLockMaintRefresh") })
|
|
412
|
-
] }),
|
|
413
|
-
value.domains.length === 0
|
|
414
|
-
? react_jsx_runtime.jsx("span", { style: chainDescStyle, children: t("editLockMaintNoDomains") })
|
|
415
|
-
: value.domains.map(domainRow)
|
|
416
|
-
] })
|
|
417
|
-
] });
|
|
418
|
-
};
|
|
419
|
-
return react_jsx_runtime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [
|
|
420
|
-
react_jsx_runtime.jsxs("div", { style: rowStyle, children: [
|
|
421
|
-
react_jsx_runtime.jsxs("div", { style: labelGroupStyle, children: [
|
|
422
|
-
react_jsx_runtime.jsx("span", { style: labelStyle, children: t("editLockMaint") }),
|
|
423
|
-
react_jsx_runtime.jsx("span", { style: hintStyle, children: t("editLockMaintHint") })
|
|
424
|
-
] }),
|
|
425
|
-
react_jsx_runtime.jsx("button", { type: "button", style: chainButtonStyle, onClick: toggle, children: open ? t("chainCancel") : t("chainEdit") })
|
|
426
|
-
] }),
|
|
427
|
-
open ? react_jsx_runtime.jsx(EditLockMaintenanceBoundary, { t, children: react_jsx_runtime.jsx(MaintenanceBody, { render: panelBody }) }) : null
|
|
428
|
-
] });
|
|
429
|
-
}
|
|
430
|
-
// Locale data face (pure data, NO ctx calls — a chunk factory re-executes
|
|
431
|
-
// under HMR, so a chunk-local register would throw on the duplicate
|
|
432
|
-
// (namespace, locale) pair): the entry registers these under "settings.weir.page"
|
|
433
|
-
// inside a ctx.effect when this chunk arrives (lib/client.js
|
|
434
|
-
// registerChunkDictionaries). Pinned by test/client.test.js's dictionary
|
|
435
|
-
// union pin.
|
|
436
|
-
// (The entry merges every settings-batch slice into the single "settings.weir.page"
|
|
437
|
-
// registration — the whole settings card tree shares one t.)
|
|
438
|
-
const dictionaries = {
|
|
439
|
-
en: {
|
|
440
|
-
editLockMaint: "Edit Lock maintenance",
|
|
441
|
-
editLockMaintHint: "Profile-wide enforcement status and read-only diagnostics.",
|
|
442
|
-
editLockMaintFailed: "Edit Lock maintenance failed",
|
|
443
|
-
editLockMaintLoading: "Loading…",
|
|
444
|
-
editLockMaintUnavailable: "Maintenance data unavailable:",
|
|
445
|
-
editLockMaintRetry: "Retry",
|
|
446
|
-
editLockMaintRefresh: "Refresh",
|
|
447
|
-
editLockMaintInspect: "Inspect",
|
|
448
|
-
editLockMaintStateEnforced: "Enforced",
|
|
449
|
-
editLockMaintStateEnforcedHint: "The switch is on and the Edit Lock manager is mounted in this process.",
|
|
450
|
-
editLockMaintStateDisableRequested: "Disable requested — restart required",
|
|
451
|
-
editLockMaintStateDisableRequestedHint: "You turned the switch off, but the manager is still mounted and enforcing. The change applies after restarting DeepSeek Harness.",
|
|
452
|
-
editLockMaintStateEnableRequested: "Enable requested — restart required",
|
|
453
|
-
editLockMaintStateEnableRequestedHint: "You turned the switch on, but no manager is mounted in this process. The change applies after restarting DeepSeek Harness.",
|
|
454
|
-
editLockMaintStateDisabled: "Enforcement disabled",
|
|
455
|
-
editLockMaintStateDisabledHint: "The switch is off and every recorded, fully installed row reports enforcement disabled.",
|
|
456
|
-
editLockMaintStateUnknown: "Unknown",
|
|
457
|
-
editLockMaintStateUnknownHint: "Mount evidence is absent, inconsistent, installing, disposing or failed. The saved value alone never proves enforcement or disablement.",
|
|
458
|
-
editLockMaintRestart: "Applies after restarting DeepSeek Harness.",
|
|
459
|
-
editLockMaintPinned: "This composition pins the Edit Lock row configuration; the settings switch does not govern it here.",
|
|
460
|
-
editLockMaintScopeNote: "The switch is profile-wide: it covers every Weir session in this profile, not one workspace.",
|
|
461
|
-
editLockMaintWarnKeepHistory: "Turning enforcement off does not clear unresolved operations, fences or history — turning it back on can block the same files again.",
|
|
462
|
-
editLockMaintWarnUnlock: "An ordinary unlock frees one lock without validating content; it is not historical recovery and never settles an unknown publication.",
|
|
463
|
-
editLockMaintOffRisk: "Edit Lock is not mounted. Ordinary edits are UNPROTECTED and can overwrite another session's work. Retained locks and fences do not block off-period edits; they may block files again after you re-enable and restart.",
|
|
464
|
-
editLockMaintUnknownRisk: "Edit Lock mount status cannot be verified. If no manager is mounted, ordinary edits are UNPROTECTED and can overwrite another session's work. Do not treat retained fences as proof of current protection.",
|
|
465
|
-
editLockMaintHistory: "Retained history — not current blocks",
|
|
466
|
-
editLockMaintHistoryHint: "These old locks and publication fences remain on disk for inspection. Without a mounted manager they do not block ordinary edits; after re-enabling they may block files again. Online force release is unavailable here; separate offline administrator recovery remains available.",
|
|
467
|
-
editLockMaintUnknownHistory: "Retained authority — current effect unverified",
|
|
468
|
-
editLockMaintUnknownHistoryHint: "The saved value and old fences cannot establish whether a manager is mounted. Inspect this history read-only; online force release is unavailable until enforcement is verified. Separate offline administrator recovery remains available.",
|
|
469
|
-
editLockMaintBlocked: "Initialization blocked",
|
|
470
|
-
editLockMaintDomains: "Domains",
|
|
471
|
-
editLockMaintNoDomains: "No live session reports an Edit Lock domain in this profile.",
|
|
472
|
-
editLockMaintAuthorityYes: "authority present",
|
|
473
|
-
editLockMaintAuthorityNo: "authority currently absent",
|
|
474
|
-
editLockMaintReservation: "A publisher reservation is present: this or another Harness holds (or stranded) the publishing claim for this domain.",
|
|
475
|
-
editLockMaintPresenceNone: "No authority directory is currently present. Prior initialization cannot be determined.",
|
|
476
|
-
editLockMaintPresenceEmpty: "The authority directory is currently empty. Prior initialization cannot be determined.",
|
|
477
|
-
editLockMaintPresenceJunk: "The authority directory has contents but no committed snapshot; the store would refuse to open it. Nothing was changed.",
|
|
478
|
-
editLockMaintPresenceNotAFile: "snapshot.json is not a regular file; the store would refuse it. Nothing was changed.",
|
|
479
|
-
editLockMaintPresenceCorrupt: "The authority image failed integrity validation and was left untouched — no automatic repair exists. Refusal:",
|
|
480
|
-
editLockMaintPresenceUnreadable: "The authority could not be read:",
|
|
481
|
-
editLockMaintCounts: "{sessions} session(s) · {locks} lock(s) · {operations} recorded operation(s)",
|
|
482
|
-
editLockMaintUnresolved: "Unresolved operations",
|
|
483
|
-
editLockMaintUnresolvedNone: "No unresolved operations.",
|
|
484
|
-
editLockMaintRetained: "Retained locks (interrupted / abnormal / pending)",
|
|
485
|
-
editLockMaintScopeFile: "one file",
|
|
486
|
-
editLockMaintScopeSubtree: "a directory subtree",
|
|
487
|
-
editLockMaintScopeDomain: "the whole work directory",
|
|
488
|
-
editLockMaintScopeNone: "no recorded scope",
|
|
489
|
-
editLockMaintRecoveries: "Online administrative recovery",
|
|
490
|
-
editLockMaintRecoverHint: "Settle an interrupted owner's unknown publications in the running manager: one explicit click, no restart, no hash typing. The unknown outcome stays in history. If the scope changed since it was loaded, the manager refuses and the panel reloads it.",
|
|
491
|
-
editLockMaintRecoverRoot: "Root",
|
|
492
|
-
editLockMaintRecoverOwner: "Owner session",
|
|
493
|
-
editLockMaintRecoverRevision: "Authority revision",
|
|
494
|
-
editLockMaintRecoverOperations: "Unresolved operation IDs",
|
|
495
|
-
editLockMaintRecoverRisk: "Risk you accept",
|
|
496
|
-
editLockMaintRecoverDigest: "Confirmation digest",
|
|
497
|
-
editLockMaintRecoverConfirm: "Settle this owner online",
|
|
498
|
-
editLockMaintRecoverBusy: "Settling…",
|
|
499
|
-
editLockMaintRecoverDone: "Settled at revision {revision}; admission is unblocked and the unknown outcome stays in history.",
|
|
500
|
-
editLockMaintRecoverFailed: "Recovery not acknowledged:",
|
|
501
|
-
editLockMaintRecoverUpgrade: "Online administrative recovery is unavailable: the server did not return recovery proposals this panel understands (missing or unsupported version). Refresh this panel or upgrade DeepSeek Harness, then inspect again.",
|
|
502
|
-
editLockMaintRecoverReasonDispositionRecorded: "An administrative recovery is already recorded for this owner; admission for its operations is no longer blocked.",
|
|
503
|
-
editLockMaintRecoverReasonOwnerUnknown: "The owner session is not recorded in this authority image.",
|
|
504
|
-
editLockMaintRecoverReasonNotInterrupted: "The holding session is not durably interrupted; the online administrative recovery can only override an interrupted historical owner. Stop the session first, or ask it to release the file.",
|
|
505
|
-
editLockMaintRecoverReasonPreparedOutstanding: "The owner still has a prepared operation; recover to stable unknown history before an administrative override.",
|
|
506
|
-
editLockMaintRecoverReasonPublishingOutstanding: "The owner still has an operation in the publishing phase; only unknown outcomes can be overridden online.",
|
|
507
|
-
editLockMaintRecoverReasonNoUnresolved: "The owner has no unresolved operations; an ordinary unlock may be enough.",
|
|
508
|
-
editLockMaintRecoverReasonUnknown: "The server reported an unrecognized recovery precondition (code: {code}). Refresh or upgrade DeepSeek Harness for the localized explanation.",
|
|
509
|
-
},
|
|
510
|
-
zh: {
|
|
511
|
-
editLockMaint: "编辑锁维护",
|
|
512
|
-
editLockMaintHint: "查看全 profile 的强制执行状态与只读诊断。",
|
|
513
|
-
editLockMaintFailed: "编辑锁维护面板加载失败",
|
|
514
|
-
editLockMaintLoading: "加载中……",
|
|
515
|
-
editLockMaintUnavailable: "维护数据不可用:",
|
|
516
|
-
editLockMaintRetry: "重试",
|
|
517
|
-
editLockMaintRefresh: "刷新",
|
|
518
|
-
editLockMaintInspect: "检查",
|
|
519
|
-
editLockMaintStateEnforced: "强制执行中",
|
|
520
|
-
editLockMaintStateEnforcedHint: "开关已打开,且编辑锁管理器已在本进程中挂载。",
|
|
521
|
-
editLockMaintStateDisableRequested: "已请求停用——需要重启",
|
|
522
|
-
editLockMaintStateDisableRequestedHint: "你已关闭开关,但管理器仍处于挂载并强制执行状态。重启 DeepSeek Harness 后生效。",
|
|
523
|
-
editLockMaintStateEnableRequested: "已请求启用——需要重启",
|
|
524
|
-
editLockMaintStateEnableRequestedHint: "你已打开开关,但本进程尚未挂载管理器。重启 DeepSeek Harness 后生效。",
|
|
525
|
-
editLockMaintStateDisabled: "强制执行已停用",
|
|
526
|
-
editLockMaintStateDisabledHint: "开关关闭,所有已记录且完成安装的行均报告强制执行已停用。",
|
|
527
|
-
editLockMaintStateUnknown: "未知",
|
|
528
|
-
editLockMaintStateUnknownHint: "挂载证据缺失、不一致,或仍在安装、卸载、失败状态。仅凭已保存的值不能证明正在强制执行或已经停用。",
|
|
529
|
-
editLockMaintRestart: "重启 DeepSeek Harness 后生效。",
|
|
530
|
-
editLockMaintPinned: "当前组合在编辑锁行上钉死了配置;这里的设置开关对它不生效。",
|
|
531
|
-
editLockMaintScopeNote: "该开关对整个 profile 生效:覆盖此 profile 下的所有 Weir 会话,而非某一个工作区。",
|
|
532
|
-
editLockMaintWarnKeepHistory: "关闭强制执行不会清除未决操作、围栏或历史——重新打开后同一批文件可能再次被阻塞。",
|
|
533
|
-
editLockMaintWarnUnlock: "普通解锁只释放一把锁且不校验内容;它不是历史恢复,永远不会结清未知的发布。",
|
|
534
|
-
editLockMaintOffRisk: "编辑锁管理器未挂载。普通编辑不受保护,可能覆盖其他会话的工作。保留的锁和围栏不会阻止停用期间的编辑;重新启用并重启后可能再次阻塞文件。",
|
|
535
|
-
editLockMaintUnknownRisk: "无法核实编辑锁的挂载状态。如果管理器未挂载,普通编辑不受保护,可能覆盖其他会话的工作。不能把保留的围栏当成当前仍受保护的证据。",
|
|
536
|
-
editLockMaintHistory: "保留的历史——不是当前阻塞",
|
|
537
|
-
editLockMaintHistoryHint: "这些旧锁与发布围栏保留在磁盘供检查。没有挂载管理器时,它们不会阻止普通编辑;重新启用后可能再次阻塞文件。此处不可在线强制释放;独立的离线管理员恢复端点仍可使用。",
|
|
538
|
-
editLockMaintUnknownHistory: "保留的权威记录——当前作用未经核实",
|
|
539
|
-
editLockMaintUnknownHistoryHint: "仅凭已保存的值与旧围栏无法确认管理器是否挂载。可只读检查这些历史;核实强制执行前不可在线强制释放。独立的离线管理员恢复端点仍可使用。",
|
|
540
|
-
editLockMaintBlocked: "初始化受阻",
|
|
541
|
-
editLockMaintDomains: "管理域",
|
|
542
|
-
editLockMaintNoDomains: "此 profile 中没有活动会话报告编辑锁管理域。",
|
|
543
|
-
editLockMaintAuthorityYes: "权威已存在",
|
|
544
|
-
editLockMaintAuthorityNo: "当前无权威",
|
|
545
|
-
editLockMaintReservation: "存在发布者预留:本进程或另一个 Harness 持有(或遗留)了该域的发布权。",
|
|
546
|
-
editLockMaintPresenceNone: "当前没有权威目录。无法据此判断此前是否初始化过。",
|
|
547
|
-
editLockMaintPresenceEmpty: "权威目录当前为空。无法据此判断此前是否初始化过。",
|
|
548
|
-
editLockMaintPresenceJunk: "权威目录有内容但没有已提交的快照;存储层会拒绝打开它。未做任何改动。",
|
|
549
|
-
editLockMaintPresenceNotAFile: "snapshot.json 不是常规文件;存储层会拒绝它。未做任何改动。",
|
|
550
|
-
editLockMaintPresenceCorrupt: "权威镜像未通过完整性校验,已原样保留——不存在自动修复。拒绝原因:",
|
|
551
|
-
editLockMaintPresenceUnreadable: "无法读取权威:",
|
|
552
|
-
editLockMaintCounts: "{sessions} 个会话 · {locks} 把锁 · {operations} 条已记录操作",
|
|
553
|
-
editLockMaintUnresolved: "未决操作",
|
|
554
|
-
editLockMaintUnresolvedNone: "没有未决操作。",
|
|
555
|
-
editLockMaintRetained: "保留的锁(中断 / 异常 / 待确认)",
|
|
556
|
-
editLockMaintScopeFile: "单个文件",
|
|
557
|
-
editLockMaintScopeSubtree: "一个目录子树",
|
|
558
|
-
editLockMaintScopeDomain: "整个工作目录",
|
|
559
|
-
editLockMaintScopeNone: "无记录范围",
|
|
560
|
-
editLockMaintRecoveries: "在线管理员恢复",
|
|
561
|
-
editLockMaintRecoverHint: "在运行中的管理器里结清已中断 owner 的未知发布:一次明确点击,无需重启、无需手打哈希;历史中的未知结论原样保留。若范围自加载后发生变化,管理器会拒绝,面板会重新加载。",
|
|
562
|
-
editLockMaintRecoverRoot: "管理根",
|
|
563
|
-
editLockMaintRecoverOwner: "属主会话",
|
|
564
|
-
editLockMaintRecoverRevision: "权威 revision",
|
|
565
|
-
editLockMaintRecoverOperations: "未决操作 ID",
|
|
566
|
-
editLockMaintRecoverRisk: "你接受的风险",
|
|
567
|
-
editLockMaintRecoverDigest: "确认摘要",
|
|
568
|
-
editLockMaintRecoverConfirm: "在线结清该 owner",
|
|
569
|
-
editLockMaintRecoverBusy: "结清中……",
|
|
570
|
-
editLockMaintRecoverDone: "已在 revision {revision} 结清;准入阻塞解除,历史仍保持未知。",
|
|
571
|
-
editLockMaintRecoverFailed: "恢复未确认:",
|
|
572
|
-
editLockMaintRecoverUpgrade: "在线管理员恢复不可用:服务端未返回本面板可理解的恢复提案(缺失或版本不受支持)。请刷新本面板或升级 DeepSeek Harness,然后重新检查。",
|
|
573
|
-
editLockMaintRecoverReasonDispositionRecorded: "该 owner 已有记录在案的管理员恢复;其操作的准入已不再阻塞。",
|
|
574
|
-
editLockMaintRecoverReasonOwnerUnknown: "该 owner 会话未记录在此权威镜像中。",
|
|
575
|
-
editLockMaintRecoverReasonNotInterrupted: "持有会话尚未持久中断;在线管理员恢复只能撤权已中断的历史 owner。请先停止该会话,或请它释放文件。",
|
|
576
|
-
editLockMaintRecoverReasonPreparedOutstanding: "该 owner 仍持有 prepared 操作;请先恢复到稳定的 unknown 历史,再进行管理员撤权。",
|
|
577
|
-
editLockMaintRecoverReasonPublishingOutstanding: "该 owner 仍有处于 publishing 阶段的操作;只有 unknown 结论可以在线撤权。",
|
|
578
|
-
editLockMaintRecoverReasonNoUnresolved: "该 owner 没有未决操作;普通解锁或许就已足够。",
|
|
579
|
-
editLockMaintRecoverReasonUnknown: "服务端报告了本面板不认识的恢复前置条件(代码:{code})。请刷新或升级 DeepSeek Harness 以获取对应说明。",
|
|
580
|
-
},
|
|
581
|
-
};
|
|
582
|
-
|
|
583
|
-
exports.dictionaries = dictionaries;
|
|
584
|
-
exports.EditLockMaintenanceBoundary = EditLockMaintenanceBoundary;
|
|
585
|
-
exports.EditLockMaintenanceField = EditLockMaintenanceField;
|
|
586
|
-
// Exported for the chunk tests: the recovery progress key and the zone
|
|
587
|
-
// copy. The recovery derivation lives host-side (inspect.js); the chunk
|
|
588
|
-
// renders and forwards, never computes.
|
|
589
|
-
exports.editLockRecovery = Object.freeze({ recoveryKey, RECOVERY_UX });
|
|
590
|
-
return module.exports;
|
|
591
|
-
}
|
|
592
|
-
});
|