From 8f87f03ee6303c0dc6441dff4a2b404b0139772e Mon Sep 17 00:00:00 2001 From: DCCONSTRUCTIONS Date: Sat, 16 May 2026 11:28:21 +0300 Subject: [PATCH] =?UTF-8?q?UI=20-=20TASKER=20CODEX:=20=D1=83=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=89=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=D0=B4=D0=BA?= =?UTF-8?q?=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B8=20local=20p?= =?UTF-8?q?review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plane-app/docker-compose.local-web-build.yaml | 4 + plane-app/reload-web-local-light.sh | 36 ++++ .../settings/codex-agent-api-settings.tsx | 167 ++++++------------ 3 files changed, 96 insertions(+), 111 deletions(-) create mode 100644 plane-app/docker-compose.local-web-build.yaml create mode 100755 plane-app/reload-web-local-light.sh diff --git a/plane-app/docker-compose.local-web-build.yaml b/plane-app/docker-compose.local-web-build.yaml new file mode 100644 index 0000000..038c218 --- /dev/null +++ b/plane-app/docker-compose.local-web-build.yaml @@ -0,0 +1,4 @@ +services: + web: + volumes: + - ../plane-src/apps/web/build/client:/usr/share/nginx/html:ro diff --git a/plane-app/reload-web-local-light.sh b/plane-app/reload-web-local-light.sh new file mode 100755 index 0000000..e1468a7 --- /dev/null +++ b/plane-app/reload-web-local-light.sh @@ -0,0 +1,36 @@ +#!/bin/sh +set -eu + +ROOT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)" +SOURCE_DIR="$ROOT_DIR/plane-src" +APP_DIR="$ROOT_DIR/plane-app" + +cd "$SOURCE_DIR" + +VITE_API_BASE_URL="${VITE_API_BASE_URL-}" \ +VITE_ADMIN_BASE_URL="${VITE_ADMIN_BASE_URL-}" \ +VITE_ADMIN_BASE_PATH="${VITE_ADMIN_BASE_PATH:-/nodedcsudo}" \ +VITE_SPACE_BASE_URL="${VITE_SPACE_BASE_URL-}" \ +VITE_SPACE_BASE_PATH="${VITE_SPACE_BASE_PATH:-/spaces}" \ +VITE_LIVE_BASE_URL="${VITE_LIVE_BASE_URL-}" \ +VITE_LIVE_BASE_PATH="${VITE_LIVE_BASE_PATH:-/live}" \ +VITE_WEB_BASE_URL="${VITE_WEB_BASE_URL-}" \ +VITE_NODEDC_LAUNCHER_URL="${VITE_NODEDC_LAUNCHER_URL:-http://launcher.local.nodedc}" \ +VITE_NODEDC_OIDC_LOGIN_ENABLED="${VITE_NODEDC_OIDC_LOGIN_ENABLED:-1}" \ +pnpm --filter web build + +cd "$APP_DIR" + +/usr/local/bin/docker compose \ + -p plane-app \ + --env-file plane.env \ + -f docker-compose.yaml \ + -f docker-compose.local-web-build.yaml \ + up -d --no-build --force-recreate web + +/usr/local/bin/docker compose \ + -p plane-app \ + --env-file plane.env \ + -f docker-compose.yaml \ + -f docker-compose.local-web-build.yaml \ + ps web diff --git a/plane-src/apps/web/core/components/workspace/settings/codex-agent-api-settings.tsx b/plane-src/apps/web/core/components/workspace/settings/codex-agent-api-settings.tsx index 67cd119..46f10d5 100644 --- a/plane-src/apps/web/core/components/workspace/settings/codex-agent-api-settings.tsx +++ b/plane-src/apps/web/core/components/workspace/settings/codex-agent-api-settings.tsx @@ -44,9 +44,8 @@ const AGENT_AVATAR_ACCEPT = "image/png,image/jpeg,image/webp,image/gif"; const MAX_AGENT_AVATAR_SOURCE_BYTES = 50 * 1024 * 1024; const AGENT_AVATAR_RENDER_SIZE = 512; const AGENT_AVATAR_OUTPUT_QUALITY = 0.86; -const OPS_AGENT_FILENAME = "OPS_AGENT.md"; +const CODEX_AGENT_TOKEN_PREFIX = "ndcag_"; const CODEX_MCP_SERVER_NAME = "nodedc-ops-agent"; -const CODEX_TOKEN_ENV_VAR = "NODEDC_OPS_AGENT_TOKEN"; const DEFAULT_OPS_AGENT_MCP_ENDPOINT = "https://ops-agents.nodedc.ru/mcp"; const codexAgentService = new WorkspaceCodexAgentService(); @@ -143,29 +142,16 @@ export const CodexAgentApiSettingsContent = observer(function CodexAgentApiSetti ); const connectionGuideMcpEndpoint = getMcpEndpoint(setupCards.find((card) => card.setup)?.setup); const connectionGuideConfigSnippet = buildCodexConfigSnippet(connectionGuideMcpEndpoint); - const connectionGuideOpsAgentMd = buildOpsAgentMarkdown(connectionGuideMcpEndpoint); const handleCopy = async (value: string, label: string) => { await navigator.clipboard.writeText(value); setToast({ type: TOAST_TYPE.SUCCESS, title: `${label} скопирован`, - message: "Секрет не хранится в Ops Agent.md. Token нужно сохранить в локальном Codex отдельно.", + message: "Вставьте скопированный фрагмент в нужное место локальной настройки Codex.", }); }; - const handleDownload = (value: string, fileName: string) => { - const blob = new Blob([value], { type: "text/markdown;charset=utf-8" }); - const objectUrl = URL.createObjectURL(blob); - const linkElement = document.createElement("a"); - linkElement.href = objectUrl; - linkElement.download = fileName; - document.body.appendChild(linkElement); - linkElement.click(); - linkElement.remove(); - URL.revokeObjectURL(objectUrl); - }; - const handleCreateAvatarChange = async (event: ChangeEvent) => { const file = event.target.files?.[0]; event.target.value = ""; @@ -603,7 +589,9 @@ export const CodexAgentApiSettingsContent = observer(function CodexAgentApiSetti
{agentTokens.map((token) => { const revealedToken = revealedTokens[token.id]; - const tokenValue = revealedToken ?? maskToken(token); + const tokenValue = revealedToken + ? stripCodexAgentTokenPrefix(revealedToken) + : maskToken(token); return (
@@ -614,16 +602,25 @@ export const CodexAgentApiSettingsContent = observer(function CodexAgentApiSetti {tokenValue} - + {revealedToken && ( + + )}
+ {revealedToken && ( +

+ Сохраните токен в надежное место. После обновления страницы полный токен будет + недоступен. +

+ )}
); })} @@ -670,8 +667,7 @@ export const CodexAgentApiSettingsContent = observer(function CodexAgentApiSetti void handleCopy(connectionGuideConfigSnippet, "config.toml")} - onDownloadAgentsMd={() => handleDownload(connectionGuideOpsAgentMd, OPS_AGENT_FILENAME)} + onCopyConfig={() => void handleCopy(connectionGuideConfigSnippet, "MCP-блок")} /> )} @@ -687,7 +683,6 @@ type TCodexConnectionGuideProps = { configSnippet: string; mcpEndpoint: string; onCopyConfig: () => void; - onDownloadAgentsMd: () => void; }; function CodexConnectionGuide(props: TCodexConnectionGuideProps) { @@ -715,44 +710,40 @@ function CodexConnectionGuide(props: TCodexConnectionGuideProps) {
-
2. Сохраните токен
+
2. Скопируйте готовый MCP-блок

- Создайте пользовательскую переменную окружения {CODEX_TOKEN_ENV_VAR}, заменив токен из примера - на уникальный токен конкретного агента. + Скопируйте блок ниже и вставьте его в конец config.toml. Если такой блок уже есть — замените + только его. +

+

+ В строке Authorization замените только ВАШ_УНИКАЛЬНЫЙ_ТОКЕН на значение из{" "} + Agent token. Bearer и ndcag_ оставьте как есть.

- - {CODEX_TOKEN_ENV_VAR}=ndcag_... -
-
3. Добавьте Ops Agent.md
+
3. Перезапустите Codex

- Скачайте {OPS_AGENT_FILENAME}. Если в проекте уже есть AGENTS.md, добавьте - содержимое Ops Agent.md в начало текущего файла. Если файла правил нет — положите Ops Agent.md в корень - проекта. + Сохраните config.toml и перезапустите локальный Codex. После старта попросите Codex проверить + доступные проекты через tasker_list_projects.

- +

Правила работы и grants Codex получит сам через MCP по токену.

config.toml block
-