diff --git a/.codex/skills/design-vpn-client-ui/SKILL.md b/.codex/skills/design-vpn-client-ui/SKILL.md index 9c52afa..3df0fe2 100644 --- a/.codex/skills/design-vpn-client-ui/SKILL.md +++ b/.codex/skills/design-vpn-client-ui/SKILL.md @@ -18,6 +18,15 @@ Preserve the repo's focused one-screen VPN client language: a centered primary a 7. Implement `prefers-reduced-motion` alongside every new animation. 8. Run `npm test`, `npm run build`, and `git diff --check`. Perform manual visual inspection only when explicitly requested. +## Communicating a proposed change + +For implementation proposals and progress summaries, combine structure instead of maximizing it: + +- start with one compact table grouped by affected modules such as frontend, UI, backend/API, styles, tests, and versions; +- use short lists only for cross-cutting details such as states, accessibility, motion, or changed files; +- keep unaffected modules visible in the table when that clarifies scope; +- avoid both an unstructured paragraph and a separate table for every subsection. + ## Non-negotiable decisions - Keep the power action on the screen's central vertical axis. Place subscription content to its right without shifting that axis. diff --git a/AGENTS.md b/AGENTS.md index 866bb7e..d2addc8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,4 +4,6 @@ Use the checked-in `workpack/` directory as the only roadmap source. Do not requ Follow `workpack/AGENTS.md` for every roadmap task, including status updates. Completed tasks must not be selected or implemented again unless the user explicitly asks to reopen one. +Before implementing any feature, record or refresh its plan in the selected `workpack/tasks/TASK-*.md` file using the mandatory feature-plan contract from `workpack/AGENTS.md`. Write the whole plan in simple language understandable without knowledge of the codebase: explain technical terms on first use, and use file paths or code names only as supporting detail. The plan must explain the implementation sequence and affected system components. For user-visible work it must also specify layout and states, exact icons, animation/motion behavior, accessibility and reduced-motion behavior; otherwise it must explicitly state that UI, icons and motion are unaffected. A proposed visible design is not owner approval. + For every runtime, UI, API, dependency or deployment-config change, use `.codex/skills/manage-harbor-versions/SKILL.md`. Before completion, classify the affected components, bump the required version level and run `npm run version:harbor -- check `. Documentation- and test-only changes do not require a bump. diff --git a/src/shared/versions.ts b/src/shared/versions.ts index 89803a9..bbfe9b7 100644 --- a/src/shared/versions.ts +++ b/src/shared/versions.ts @@ -1,6 +1,6 @@ export const HARBOR_VERSIONS = Object.freeze({ - macClient: '0.26.6', - gatewayClient: '0.27.6', + macClient: '0.26.7', + gatewayClient: '0.27.7', gatewayBackend: '0.27.0', }); diff --git a/src/web/features/diagnostics/ConnectivityDiagnosticsPanel.tsx b/src/web/features/diagnostics/ConnectivityDiagnosticsPanel.tsx index 4b8a676..f752afd 100644 --- a/src/web/features/diagnostics/ConnectivityDiagnosticsPanel.tsx +++ b/src/web/features/diagnostics/ConnectivityDiagnosticsPanel.tsx @@ -109,6 +109,34 @@ function Status({ value, route }: { value: StatusValue; route: string }) { ; } +function RowRefresh({ + label, + running, + disabled, + onRun, +}: { + label: string; + running: boolean; + disabled: boolean; + onRun: () => void; +}) { + return + + Проверить только эту строку + ; +} + function ipResult(path: DiagnosticPath | undefined, source: IpSourceDefinition) { if (!path?.available) return null; return source.family === 6 @@ -222,6 +250,7 @@ export function ConnectivityDiagnosticsPanel({ const sheetRef = useRef(null); const runnerRef = useRef(null); const previousTargetRef = useRef(null); + const retryTargetRef = useRef(undefined); const requestError = requestDetails(error); useEffect(() => { @@ -264,12 +293,13 @@ export function ConnectivityDiagnosticsPanel({ previousTargetRef.current = activeTarget; }, [activeTarget]); - async function run() { + async function run(onlyTarget?: string) { + retryTargetRef.current = onlyTarget; setStatus('running'); setError(null); try { let next = result; - const targets = [ + const targets = onlyTarget ? [onlyTarget] : [ CONNECTIVITY_NETWORK_SOURCE.id, ...CONNECTIVITY_IP_SOURCES.map(({ id }) => `ip:${id}`), ...sites.map(({ id }) => `site:${id}`), @@ -379,7 +409,7 @@ export function ConnectivityDiagnosticsPanel({ aria-label="Проверить маршруты" aria-busy={pending} disabled={pending} - onClick={run} + onClick={() => run()} >
{requestError.message} - {requestError.retryable && } + {requestError.retryable && }
} @@ -412,7 +442,15 @@ export function ConnectivityDiagnosticsPanel({ data-diagnostic-target={CONNECTIVITY_NETWORK_SOURCE.id} className={activeTarget === CONNECTIVITY_NETWORK_SOURCE.id ? 'is-running' : undefined} > - {CONNECTIVITY_NETWORK_SOURCE.label} + + {CONNECTIVITY_NETWORK_SOURCE.label} + run(CONNECTIVITY_NETWORK_SOURCE.id)} + /> + - {source.label} + + {source.label} + run(target)} + /> + })} @@ -460,7 +506,15 @@ export function ConnectivityDiagnosticsPanel({ style={{ viewTransitionName: removing ? 'none' : `diagnostic-service-${site.id}` }} inert={removing ? true : undefined} > - {site.label} + + {site.label} + run(`site:${site.id}`)} + /> +