kin: KIN-084 Live console в Pipeline view: скрытая по умолчанию панель (раскрывается по клику), показывающая полный лог выполнения в реальном времени: запуск PM → параметры вызова claude → получен ответ JSON → парсинг pipeline → запуск backend_dev → параметры вызова → ответ → запуск tester... Как терминал, моноширинный шрифт, автоскролл. Runner пишет каждый шаг в отдельную таблицу pipeline_log или в agent_logs с детализацией. GUI поллит и дописывает.
This commit is contained in:
parent
939a30a3de
commit
4144c521be
1 changed files with 67 additions and 4 deletions
|
|
@ -773,13 +773,75 @@ async function addDecision() {
|
|||
<span class="text-gray-700">|</span>
|
||||
<router-link :to="`/chat/${project.id}`" class="text-indigo-500 hover:text-indigo-400 text-sm no-underline">Чат</router-link>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<div class="flex items-center gap-3 mb-2 flex-wrap">
|
||||
<h1 class="text-xl font-bold text-gray-100">{{ project.id }}</h1>
|
||||
<span class="text-gray-400">{{ project.name }}</span>
|
||||
<Badge :text="project.status" :color="project.status === 'active' ? 'green' : 'gray'" />
|
||||
<Badge v-if="project.project_type && project.project_type !== 'development'"
|
||||
:text="project.project_type"
|
||||
:color="project.project_type === 'operations' ? 'orange' : 'green'" />
|
||||
<button
|
||||
@click="runDeploy"
|
||||
:disabled="deploying || !hasDeployConfig"
|
||||
:title="hasDeployConfig ? 'Deploy project' : 'Настройте deploy-параметры в Settings'"
|
||||
class="px-3 py-1 text-xs bg-teal-900/50 text-teal-400 border border-teal-800 rounded hover:bg-teal-900 disabled:opacity-50 ml-auto"
|
||||
>
|
||||
<span v-if="deploying" class="inline-block w-3 h-3 border-2 border-teal-400 border-t-transparent rounded-full animate-spin mr-1"></span>
|
||||
{{ deploying ? 'Deploying...' : 'Deploy' }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Deploy result -->
|
||||
<div v-if="deployResult" class="mb-3 p-3 rounded border text-xs font-mono"
|
||||
:class="deployResult.overall_success !== false && deployResult.success ? 'border-teal-800 bg-teal-950/30 text-teal-300' : 'border-red-800 bg-red-950/30 text-red-300'">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<span :class="deployResult.overall_success !== false && deployResult.success ? 'text-teal-400' : 'text-red-400'" class="font-semibold">
|
||||
{{ deployResult.overall_success !== false && deployResult.success ? 'Deploy succeeded' : 'Deploy failed' }}
|
||||
</span>
|
||||
<span class="text-gray-500">{{ deployResult.duration_seconds }}s</span>
|
||||
<button @click.stop="deployResult = null" class="ml-auto text-gray-600 hover:text-gray-400 bg-transparent border-none cursor-pointer text-xs">x</button>
|
||||
</div>
|
||||
<!-- Structured steps -->
|
||||
<div v-if="deployResult.results?.length" class="space-y-1 mt-1">
|
||||
<details v-for="step in deployResult.results" :key="step.step" class="border border-gray-700 rounded">
|
||||
<summary class="flex items-center gap-2 px-2 py-1 cursor-pointer list-none">
|
||||
<span :class="step.exit_code === 0 ? 'text-teal-400' : 'text-red-400'" class="font-semibold text-[10px]">{{ step.exit_code === 0 ? 'ok' : 'fail' }}</span>
|
||||
<span class="text-gray-300 text-[11px]">{{ step.step }}</span>
|
||||
<span class="text-gray-600 text-[10px] ml-auto">exit {{ step.exit_code }}</span>
|
||||
</summary>
|
||||
<div class="px-2 pb-2">
|
||||
<pre v-if="step.stdout" class="whitespace-pre-wrap text-gray-300 max-h-32 overflow-y-auto text-[10px]">{{ step.stdout }}</pre>
|
||||
<pre v-if="step.stderr" class="whitespace-pre-wrap text-red-400/80 max-h-32 overflow-y-auto text-[10px] mt-1">{{ step.stderr }}</pre>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
<!-- Legacy output -->
|
||||
<template v-else>
|
||||
<pre v-if="deployResult.stdout" class="whitespace-pre-wrap text-gray-300 max-h-40 overflow-y-auto">{{ deployResult.stdout }}</pre>
|
||||
<pre v-if="deployResult.stderr" class="whitespace-pre-wrap text-red-400/80 max-h-40 overflow-y-auto mt-1">{{ deployResult.stderr }}</pre>
|
||||
</template>
|
||||
<!-- Dependents -->
|
||||
<div v-if="deployResult.dependents_deployed?.length" class="mt-2 border-t border-gray-700 pt-2">
|
||||
<p class="text-xs text-gray-400 font-semibold mb-1">Зависимые проекты:</p>
|
||||
<details v-for="dep in deployResult.dependents_deployed" :key="dep.project_id" class="border border-gray-700 rounded mb-1">
|
||||
<summary class="flex items-center gap-2 px-2 py-1 cursor-pointer list-none">
|
||||
<span :class="dep.success ? 'text-teal-400' : 'text-red-400'" class="font-semibold text-[10px]">{{ dep.success ? 'ok' : 'fail' }}</span>
|
||||
<span class="text-gray-300 text-[11px]">{{ dep.project_name }}</span>
|
||||
</summary>
|
||||
<div class="px-2 pb-2 space-y-1">
|
||||
<details v-for="step in dep.results" :key="step.step" class="border border-gray-800 rounded">
|
||||
<summary class="flex items-center gap-2 px-2 py-0.5 cursor-pointer list-none">
|
||||
<span :class="step.exit_code === 0 ? 'text-teal-400' : 'text-red-400'" class="text-[10px]">{{ step.exit_code === 0 ? 'ok' : 'fail' }}</span>
|
||||
<span class="text-gray-400 text-[10px]">{{ step.step }}</span>
|
||||
</summary>
|
||||
<div class="px-2 pb-1">
|
||||
<pre v-if="step.stdout" class="whitespace-pre-wrap text-gray-300 max-h-24 overflow-y-auto text-[10px]">{{ step.stdout }}</pre>
|
||||
<pre v-if="step.stderr" class="whitespace-pre-wrap text-red-400/80 max-h-24 overflow-y-auto text-[10px]">{{ step.stderr }}</pre>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2 flex-wrap mb-2" v-if="project.tech_stack?.length">
|
||||
<Badge v-for="t in project.tech_stack" :key="t" :text="t" color="purple" />
|
||||
|
|
@ -804,20 +866,21 @@ async function addDecision() {
|
|||
</div>
|
||||
|
||||
<!-- Tabs -->
|
||||
<div class="flex gap-1 mb-4 border-b border-gray-800">
|
||||
<button v-for="tab in (['tasks', 'phases', 'decisions', 'modules', 'kanban', 'environments'] as const)" :key="tab"
|
||||
<div class="flex gap-1 mb-4 border-b border-gray-800 flex-wrap">
|
||||
<button v-for="tab in (['tasks', 'phases', 'decisions', 'modules', 'kanban', 'environments', 'links'] as const)" :key="tab"
|
||||
@click="activeTab = tab"
|
||||
class="px-4 py-2 text-sm border-b-2 transition-colors"
|
||||
:class="activeTab === tab
|
||||
? 'text-gray-200 border-blue-500'
|
||||
: 'text-gray-500 border-transparent hover:text-gray-300'">
|
||||
{{ tab === 'kanban' ? 'Kanban' : tab === 'environments' ? 'Среды' : tab.charAt(0).toUpperCase() + tab.slice(1) }}
|
||||
{{ tab === 'kanban' ? 'Kanban' : tab === 'environments' ? 'Среды' : tab === 'links' ? 'Links' : tab.charAt(0).toUpperCase() + tab.slice(1) }}
|
||||
<span class="text-xs text-gray-600 ml-1">
|
||||
{{ tab === 'tasks' ? project.tasks.length
|
||||
: tab === 'phases' ? phases.length
|
||||
: tab === 'decisions' ? project.decisions.length
|
||||
: tab === 'modules' ? project.modules.length
|
||||
: tab === 'environments' ? environments.length
|
||||
: tab === 'links' ? links.length
|
||||
: project.tasks.length }}
|
||||
</span>
|
||||
</button>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue