2026-03-15 17:13:37 +02:00
|
|
|
|
const BASE = '/api'
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
|
2026-03-16 15:48:09 +02:00
|
|
|
|
export class ApiError extends Error {
|
|
|
|
|
|
code: string
|
|
|
|
|
|
constructor(code: string, message: string) {
|
|
|
|
|
|
super(message)
|
|
|
|
|
|
this.name = 'ApiError'
|
|
|
|
|
|
this.code = code
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function throwApiError(res: Response): Promise<never> {
|
|
|
|
|
|
let code = ''
|
|
|
|
|
|
let msg = `${res.status} ${res.statusText}`
|
|
|
|
|
|
try {
|
|
|
|
|
|
const data = await res.json()
|
|
|
|
|
|
if (data.error) code = data.error
|
|
|
|
|
|
if (data.message) msg = data.message
|
|
|
|
|
|
} catch {}
|
|
|
|
|
|
throw new ApiError(code, msg)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
async function get<T>(path: string): Promise<T> {
|
|
|
|
|
|
const res = await fetch(`${BASE}${path}`)
|
2026-03-16 15:48:09 +02:00
|
|
|
|
if (!res.ok) await throwApiError(res)
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
return res.json()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-15 18:17:57 +02:00
|
|
|
|
async function patch<T>(path: string, body: unknown): Promise<T> {
|
|
|
|
|
|
const res = await fetch(`${BASE}${path}`, {
|
|
|
|
|
|
method: 'PATCH',
|
|
|
|
|
|
headers: { 'Content-Type': 'application/json' },
|
|
|
|
|
|
body: JSON.stringify(body),
|
|
|
|
|
|
})
|
2026-03-16 15:48:09 +02:00
|
|
|
|
if (!res.ok) await throwApiError(res)
|
2026-03-15 18:17:57 +02:00
|
|
|
|
return res.json()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
async function post<T>(path: string, body: unknown): Promise<T> {
|
|
|
|
|
|
const res = await fetch(`${BASE}${path}`, {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
headers: { 'Content-Type': 'application/json' },
|
|
|
|
|
|
body: JSON.stringify(body),
|
|
|
|
|
|
})
|
2026-03-16 15:48:09 +02:00
|
|
|
|
if (!res.ok) await throwApiError(res)
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
return res.json()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-15 23:22:49 +02:00
|
|
|
|
async function del<T>(path: string): Promise<T> {
|
|
|
|
|
|
const res = await fetch(`${BASE}${path}`, { method: 'DELETE' })
|
2026-03-16 17:44:49 +02:00
|
|
|
|
if (!res.ok) await throwApiError(res)
|
|
|
|
|
|
if (res.status === 204) return undefined as T
|
2026-03-15 23:22:49 +02:00
|
|
|
|
return res.json()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-16 20:39:17 +02:00
|
|
|
|
async function postForm<T>(path: string, body: FormData): Promise<T> {
|
|
|
|
|
|
const res = await fetch(`${BASE}${path}`, { method: 'POST', body })
|
|
|
|
|
|
if (!res.ok) await throwApiError(res)
|
|
|
|
|
|
return res.json()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
export interface Project {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
name: string
|
|
|
|
|
|
path: string
|
|
|
|
|
|
status: string
|
|
|
|
|
|
priority: number
|
|
|
|
|
|
tech_stack: string[] | null
|
2026-03-15 20:02:01 +02:00
|
|
|
|
execution_mode: string | null
|
2026-03-16 07:06:34 +02:00
|
|
|
|
autocommit_enabled: number | null
|
2026-03-17 16:01:51 +02:00
|
|
|
|
auto_test_enabled: number | null
|
2026-03-16 07:14:32 +02:00
|
|
|
|
obsidian_vault_path: string | null
|
2026-03-16 08:21:13 +02:00
|
|
|
|
deploy_command: string | null
|
2026-03-17 15:49:37 +02:00
|
|
|
|
test_command: string | null
|
2026-03-17 17:39:40 +02:00
|
|
|
|
deploy_host: string | null
|
|
|
|
|
|
deploy_path: string | null
|
|
|
|
|
|
deploy_runtime: string | null
|
|
|
|
|
|
deploy_restart_cmd: string | null
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
created_at: string
|
|
|
|
|
|
total_tasks: number
|
|
|
|
|
|
done_tasks: number
|
|
|
|
|
|
active_tasks: number
|
|
|
|
|
|
blocked_tasks: number
|
Add task detail view, pipeline visualization, approve/reject workflow
API (web/api.py) — 5 new endpoints:
GET /api/tasks/{id}/pipeline — agent_logs as pipeline steps
GET /api/tasks/{id}/full — task + steps + related decisions
POST /api/tasks/{id}/approve — mark done, optionally add decision
POST /api/tasks/{id}/reject — return to pending with reason
POST /api/tasks/{id}/run — launch pipeline in background (202)
Frontend:
TaskDetail (/task/:id) — full task page with:
- Pipeline graph: role cards with icons, arrows, status colors
- Click step → expand output (pre-formatted, JSON detected)
- Action bar: Approve (with optional decision), Reject, Run Pipeline
- Polling for live pipeline updates
Dashboard: review_tasks badge ("awaiting review" in yellow)
ProjectView: task rows are now clickable links to /task/:id
Runner: output_summary no longer truncated (full output for GUI).
Models: get_project_summary includes review_tasks count.
13 new API tests, 105 total, all passing. Frontend builds clean.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:32:29 +02:00
|
|
|
|
review_tasks: number
|
2026-03-16 09:13:34 +02:00
|
|
|
|
project_type: string | null
|
|
|
|
|
|
ssh_host: string | null
|
|
|
|
|
|
ssh_user: string | null
|
|
|
|
|
|
ssh_key_path: string | null
|
|
|
|
|
|
ssh_proxy_jump: string | null
|
|
|
|
|
|
description: string | null
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-16 07:14:32 +02:00
|
|
|
|
export interface ObsidianSyncResult {
|
|
|
|
|
|
exported_decisions: number
|
|
|
|
|
|
tasks_updated: number
|
|
|
|
|
|
errors: string[]
|
|
|
|
|
|
vault_path: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
export interface ProjectDetail extends Project {
|
|
|
|
|
|
tasks: Task[]
|
|
|
|
|
|
modules: Module[]
|
|
|
|
|
|
decisions: Decision[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface Task {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
project_id: string
|
|
|
|
|
|
title: string
|
|
|
|
|
|
status: string
|
|
|
|
|
|
priority: number
|
|
|
|
|
|
assigned_role: string | null
|
|
|
|
|
|
parent_task_id: string | null
|
|
|
|
|
|
brief: Record<string, unknown> | null
|
|
|
|
|
|
spec: Record<string, unknown> | null
|
2026-03-15 20:02:01 +02:00
|
|
|
|
execution_mode: string | null
|
2026-03-15 23:22:49 +02:00
|
|
|
|
blocked_reason: string | null
|
2026-03-16 07:13:32 +02:00
|
|
|
|
dangerously_skipped: number | null
|
2026-03-16 08:21:13 +02:00
|
|
|
|
category: string | null
|
2026-03-16 10:04:01 +02:00
|
|
|
|
acceptance_criteria: string | null
|
2026-03-16 22:35:31 +02:00
|
|
|
|
feedback?: string | null
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
created_at: string
|
|
|
|
|
|
updated_at: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface Decision {
|
|
|
|
|
|
id: number
|
|
|
|
|
|
project_id: string
|
|
|
|
|
|
task_id: string | null
|
|
|
|
|
|
type: string
|
|
|
|
|
|
category: string | null
|
|
|
|
|
|
title: string
|
|
|
|
|
|
description: string
|
|
|
|
|
|
tags: string[] | null
|
|
|
|
|
|
created_at: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface Module {
|
|
|
|
|
|
id: number
|
|
|
|
|
|
project_id: string
|
|
|
|
|
|
name: string
|
|
|
|
|
|
type: string
|
|
|
|
|
|
path: string
|
|
|
|
|
|
description: string | null
|
|
|
|
|
|
owner_role: string | null
|
|
|
|
|
|
dependencies: string[] | null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
Add task detail view, pipeline visualization, approve/reject workflow
API (web/api.py) — 5 new endpoints:
GET /api/tasks/{id}/pipeline — agent_logs as pipeline steps
GET /api/tasks/{id}/full — task + steps + related decisions
POST /api/tasks/{id}/approve — mark done, optionally add decision
POST /api/tasks/{id}/reject — return to pending with reason
POST /api/tasks/{id}/run — launch pipeline in background (202)
Frontend:
TaskDetail (/task/:id) — full task page with:
- Pipeline graph: role cards with icons, arrows, status colors
- Click step → expand output (pre-formatted, JSON detected)
- Action bar: Approve (with optional decision), Reject, Run Pipeline
- Polling for live pipeline updates
Dashboard: review_tasks badge ("awaiting review" in yellow)
ProjectView: task rows are now clickable links to /task/:id
Runner: output_summary no longer truncated (full output for GUI).
Models: get_project_summary includes review_tasks count.
13 new API tests, 105 total, all passing. Frontend builds clean.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:32:29 +02:00
|
|
|
|
export interface PipelineStep {
|
|
|
|
|
|
id: number
|
|
|
|
|
|
agent_role: string
|
|
|
|
|
|
action: string
|
|
|
|
|
|
output_summary: string | null
|
|
|
|
|
|
success: boolean | number
|
|
|
|
|
|
duration_seconds: number | null
|
|
|
|
|
|
tokens_used: number | null
|
|
|
|
|
|
model: string | null
|
|
|
|
|
|
cost_usd: number | null
|
|
|
|
|
|
created_at: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-17 17:39:40 +02:00
|
|
|
|
export interface DeployStepResult {
|
|
|
|
|
|
step: string
|
2026-03-17 18:29:32 +02:00
|
|
|
|
command: string
|
2026-03-17 17:39:40 +02:00
|
|
|
|
stdout: string
|
|
|
|
|
|
stderr: string
|
|
|
|
|
|
exit_code: number
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface DependentDeploy {
|
|
|
|
|
|
project_id: string
|
|
|
|
|
|
project_name: string
|
|
|
|
|
|
success: boolean
|
|
|
|
|
|
results: DeployStepResult[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-16 08:21:13 +02:00
|
|
|
|
export interface DeployResult {
|
|
|
|
|
|
success: boolean
|
|
|
|
|
|
exit_code: number
|
|
|
|
|
|
stdout: string
|
|
|
|
|
|
stderr: string
|
|
|
|
|
|
duration_seconds: number
|
2026-03-17 17:39:40 +02:00
|
|
|
|
steps?: string[]
|
|
|
|
|
|
results?: DeployStepResult[]
|
|
|
|
|
|
dependents_deployed?: DependentDeploy[]
|
|
|
|
|
|
overall_success?: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface ProjectLink {
|
|
|
|
|
|
id: number
|
|
|
|
|
|
from_project: string
|
|
|
|
|
|
to_project: string
|
2026-03-17 18:54:02 +02:00
|
|
|
|
// WARNING (decision #527): поле называется `type` — так отдаёт бэкенд.
|
|
|
|
|
|
// НЕ переименовывать в link_type — это вызовет runtime undefined во всех компонентах.
|
2026-03-17 18:37:02 +02:00
|
|
|
|
type: string
|
2026-03-17 17:39:40 +02:00
|
|
|
|
description: string | null
|
|
|
|
|
|
created_at: string
|
2026-03-16 08:21:13 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
Add task detail view, pipeline visualization, approve/reject workflow
API (web/api.py) — 5 new endpoints:
GET /api/tasks/{id}/pipeline — agent_logs as pipeline steps
GET /api/tasks/{id}/full — task + steps + related decisions
POST /api/tasks/{id}/approve — mark done, optionally add decision
POST /api/tasks/{id}/reject — return to pending with reason
POST /api/tasks/{id}/run — launch pipeline in background (202)
Frontend:
TaskDetail (/task/:id) — full task page with:
- Pipeline graph: role cards with icons, arrows, status colors
- Click step → expand output (pre-formatted, JSON detected)
- Action bar: Approve (with optional decision), Reject, Run Pipeline
- Polling for live pipeline updates
Dashboard: review_tasks badge ("awaiting review" in yellow)
ProjectView: task rows are now clickable links to /task/:id
Runner: output_summary no longer truncated (full output for GUI).
Models: get_project_summary includes review_tasks count.
13 new API tests, 105 total, all passing. Frontend builds clean.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:32:29 +02:00
|
|
|
|
export interface TaskFull extends Task {
|
|
|
|
|
|
pipeline_steps: PipelineStep[]
|
|
|
|
|
|
related_decisions: Decision[]
|
2026-03-16 08:21:13 +02:00
|
|
|
|
project_deploy_command: string | null
|
2026-03-17 18:30:26 +02:00
|
|
|
|
project_deploy_host: string | null
|
|
|
|
|
|
project_deploy_path: string | null
|
2026-03-17 18:29:32 +02:00
|
|
|
|
project_deploy_runtime: string | null
|
2026-03-17 17:39:40 +02:00
|
|
|
|
pipeline_id: string | null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface PipelineLog {
|
|
|
|
|
|
id: number
|
|
|
|
|
|
ts: string
|
|
|
|
|
|
level: 'INFO' | 'DEBUG' | 'ERROR' | 'WARN'
|
|
|
|
|
|
message: string
|
|
|
|
|
|
extra_json: Record<string, unknown> | null
|
Add task detail view, pipeline visualization, approve/reject workflow
API (web/api.py) — 5 new endpoints:
GET /api/tasks/{id}/pipeline — agent_logs as pipeline steps
GET /api/tasks/{id}/full — task + steps + related decisions
POST /api/tasks/{id}/approve — mark done, optionally add decision
POST /api/tasks/{id}/reject — return to pending with reason
POST /api/tasks/{id}/run — launch pipeline in background (202)
Frontend:
TaskDetail (/task/:id) — full task page with:
- Pipeline graph: role cards with icons, arrows, status colors
- Click step → expand output (pre-formatted, JSON detected)
- Action bar: Approve (with optional decision), Reject, Run Pipeline
- Polling for live pipeline updates
Dashboard: review_tasks badge ("awaiting review" in yellow)
ProjectView: task rows are now clickable links to /task/:id
Runner: output_summary no longer truncated (full output for GUI).
Models: get_project_summary includes review_tasks count.
13 new API tests, 105 total, all passing. Frontend builds clean.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:32:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-15 15:16:48 +02:00
|
|
|
|
export interface PendingAction {
|
|
|
|
|
|
type: string
|
|
|
|
|
|
description: string
|
|
|
|
|
|
original_item: Record<string, unknown>
|
|
|
|
|
|
options: string[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
export interface CostEntry {
|
|
|
|
|
|
project_id: string
|
|
|
|
|
|
project_name: string
|
|
|
|
|
|
runs: number
|
|
|
|
|
|
total_tokens: number
|
|
|
|
|
|
total_cost_usd: number
|
|
|
|
|
|
total_duration_seconds: number
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-16 09:13:34 +02:00
|
|
|
|
export interface Phase {
|
|
|
|
|
|
id: number
|
|
|
|
|
|
project_id: string
|
|
|
|
|
|
role: string
|
|
|
|
|
|
phase_order: number
|
|
|
|
|
|
status: string
|
|
|
|
|
|
task_id: string | null
|
|
|
|
|
|
revise_count: number
|
kin: KIN-059 Workflow new_project с выбором команды. При создании нового проекта через GUI или CLI директор описывает проект свободным текстом и выбирает галочками какие этапы research нужны: ☐ Business analyst (бизнес-модель, аудитория, монетизация) ☐ Market researcher (конкуренты, ниша, отзывы, сильные/слабые стороны) ☐ Legal researcher (юрисдикция, лицензии, KYC/AML, GDPR) ☐ Tech researcher (API, ограничения, стоимость, альтернативы) ☐ UX designer (анализ UX конкурентов, user journey, wireframes) ☐ Marketer (стратегия продвижения, SEO, conversion-паттерны) ☐ Architect (blueprint на основе одобренных research'ей) — всегда последний Architect включается автоматически если выбран хотя бы один researcher. Каждый выбранный этап — отдельная задача на review. Директор одобряет, отклоняет, или просит доисследовать (Revise). Следующий этап только после approve предыдущего. GUI: форма 'New Project' с описанием + чекбоксы ролей + кнопка 'Start Research'. CLI: kin new-project 'описание' --roles 'business,market,tech,architect'
2026-03-16 09:30:00 +02:00
|
|
|
|
revise_comment: string | null
|
2026-03-16 09:13:34 +02:00
|
|
|
|
created_at: string
|
|
|
|
|
|
updated_at: string
|
|
|
|
|
|
task?: Task | null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface NewProjectPayload {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
name: string
|
|
|
|
|
|
path: string
|
|
|
|
|
|
description: string
|
|
|
|
|
|
roles: string[]
|
|
|
|
|
|
tech_stack?: string[]
|
|
|
|
|
|
priority?: number
|
|
|
|
|
|
language?: string
|
|
|
|
|
|
project_type?: string
|
|
|
|
|
|
ssh_host?: string
|
|
|
|
|
|
ssh_user?: string
|
|
|
|
|
|
ssh_key_path?: string
|
|
|
|
|
|
ssh_proxy_jump?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface NewProjectResult {
|
|
|
|
|
|
project: Project
|
|
|
|
|
|
phases: Phase[]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-15 17:44:16 +02:00
|
|
|
|
export interface AuditItem {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
reason: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface AuditResult {
|
|
|
|
|
|
success: boolean
|
|
|
|
|
|
already_done: AuditItem[]
|
|
|
|
|
|
still_pending: AuditItem[]
|
|
|
|
|
|
unclear: AuditItem[]
|
|
|
|
|
|
duration_seconds?: number
|
|
|
|
|
|
cost_usd?: number
|
|
|
|
|
|
error?: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-16 19:26:51 +02:00
|
|
|
|
export interface ProjectEnvironment {
|
|
|
|
|
|
id: number
|
|
|
|
|
|
project_id: string
|
|
|
|
|
|
name: string
|
|
|
|
|
|
host: string
|
|
|
|
|
|
port: number
|
|
|
|
|
|
username: string
|
|
|
|
|
|
auth_type: string
|
|
|
|
|
|
is_installed: number
|
|
|
|
|
|
created_at: string
|
|
|
|
|
|
updated_at: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-16 09:13:34 +02:00
|
|
|
|
export interface EscalationNotification {
|
|
|
|
|
|
task_id: string
|
|
|
|
|
|
project_id: string
|
|
|
|
|
|
agent_role: string
|
|
|
|
|
|
reason: string
|
|
|
|
|
|
pipeline_step: string | null
|
|
|
|
|
|
blocked_at: string
|
|
|
|
|
|
telegram_sent: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-16 19:26:51 +02:00
|
|
|
|
export interface ChatMessage {
|
|
|
|
|
|
id: number
|
|
|
|
|
|
project_id: string
|
|
|
|
|
|
role: 'user' | 'assistant'
|
|
|
|
|
|
content: string
|
|
|
|
|
|
message_type: string
|
|
|
|
|
|
task_id: string | null
|
|
|
|
|
|
created_at: string
|
|
|
|
|
|
task_stub?: {
|
|
|
|
|
|
id: string
|
|
|
|
|
|
title: string
|
|
|
|
|
|
status: string
|
|
|
|
|
|
} | null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface ChatSendResult {
|
|
|
|
|
|
user_message: ChatMessage
|
|
|
|
|
|
assistant_message: ChatMessage
|
2026-03-16 20:13:44 +02:00
|
|
|
|
task?: Task | null
|
2026-03-16 19:26:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-16 20:39:17 +02:00
|
|
|
|
export interface Attachment {
|
|
|
|
|
|
id: number
|
|
|
|
|
|
task_id: string
|
|
|
|
|
|
filename: string
|
|
|
|
|
|
mime_type: string
|
|
|
|
|
|
size: number
|
|
|
|
|
|
created_at: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
export const api = {
|
|
|
|
|
|
projects: () => get<Project[]>('/projects'),
|
|
|
|
|
|
project: (id: string) => get<ProjectDetail>(`/projects/${id}`),
|
Add task detail view, pipeline visualization, approve/reject workflow
API (web/api.py) — 5 new endpoints:
GET /api/tasks/{id}/pipeline — agent_logs as pipeline steps
GET /api/tasks/{id}/full — task + steps + related decisions
POST /api/tasks/{id}/approve — mark done, optionally add decision
POST /api/tasks/{id}/reject — return to pending with reason
POST /api/tasks/{id}/run — launch pipeline in background (202)
Frontend:
TaskDetail (/task/:id) — full task page with:
- Pipeline graph: role cards with icons, arrows, status colors
- Click step → expand output (pre-formatted, JSON detected)
- Action bar: Approve (with optional decision), Reject, Run Pipeline
- Polling for live pipeline updates
Dashboard: review_tasks badge ("awaiting review" in yellow)
ProjectView: task rows are now clickable links to /task/:id
Runner: output_summary no longer truncated (full output for GUI).
Models: get_project_summary includes review_tasks count.
13 new API tests, 105 total, all passing. Frontend builds clean.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:32:29 +02:00
|
|
|
|
task: (id: string) => get<Task>(`/tasks/${id}`),
|
|
|
|
|
|
taskFull: (id: string) => get<TaskFull>(`/tasks/${id}/full`),
|
|
|
|
|
|
taskPipeline: (id: string) => get<PipelineStep[]>(`/tasks/${id}/pipeline`),
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
cost: (days = 7) => get<CostEntry[]>(`/cost?days=${days}`),
|
2026-03-16 09:13:34 +02:00
|
|
|
|
createProject: (data: { id: string; name: string; path?: string; tech_stack?: string[]; priority?: number; project_type?: string; ssh_host?: string; ssh_user?: string; ssh_key_path?: string; ssh_proxy_jump?: string }) =>
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
post<Project>('/projects', data),
|
2026-03-16 10:04:01 +02:00
|
|
|
|
createTask: (data: { project_id: string; title: string; priority?: number; route_type?: string; category?: string; acceptance_criteria?: string }) =>
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
post<Task>('/tasks', data),
|
Add follow-up task generation on approve
When approving a task, PM agent analyzes pipeline output and creates
follow-up tasks automatically (e.g. security audit → 8 fix tasks).
core/followup.py:
generate_followups() — collects pipeline output, runs followup agent,
parses JSON task list, creates tasks with parent_task_id linkage.
Handles: bare arrays, {tasks:[...]} wrappers, invalid JSON, empty.
agents/prompts/followup.md — PM prompt for analyzing results and
creating actionable follow-up tasks with priority from severity.
CLI: kin approve <task_id> [--followup] [--decision "text"]
API: POST /api/tasks/{id}/approve {create_followups: true}
Returns {status, decision, followup_tasks: [...]}
Frontend (TaskDetail approve modal):
- Checkbox "Create follow-up tasks" (default ON)
- Loading state during generation
- Results view: list of created tasks with links to /task/:id
ProjectView: tasks show "from VDOL-001" for follow-ups.
13 new tests (followup), 125 total, all passing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 15:02:58 +02:00
|
|
|
|
approveTask: (id: string, data?: { decision_title?: string; decision_description?: string; decision_type?: string; create_followups?: boolean }) =>
|
2026-03-15 15:16:48 +02:00
|
|
|
|
post<{ status: string; followup_tasks: Task[]; needs_decision: boolean; pending_actions: PendingAction[] }>(`/tasks/${id}/approve`, data || {}),
|
|
|
|
|
|
resolveAction: (id: string, action: PendingAction, choice: string) =>
|
|
|
|
|
|
post<{ choice: string; result: unknown }>(`/tasks/${id}/resolve`, { action, choice }),
|
Add task detail view, pipeline visualization, approve/reject workflow
API (web/api.py) — 5 new endpoints:
GET /api/tasks/{id}/pipeline — agent_logs as pipeline steps
GET /api/tasks/{id}/full — task + steps + related decisions
POST /api/tasks/{id}/approve — mark done, optionally add decision
POST /api/tasks/{id}/reject — return to pending with reason
POST /api/tasks/{id}/run — launch pipeline in background (202)
Frontend:
TaskDetail (/task/:id) — full task page with:
- Pipeline graph: role cards with icons, arrows, status colors
- Click step → expand output (pre-formatted, JSON detected)
- Action bar: Approve (with optional decision), Reject, Run Pipeline
- Polling for live pipeline updates
Dashboard: review_tasks badge ("awaiting review" in yellow)
ProjectView: task rows are now clickable links to /task/:id
Runner: output_summary no longer truncated (full output for GUI).
Models: get_project_summary includes review_tasks count.
13 new API tests, 105 total, all passing. Frontend builds clean.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:32:29 +02:00
|
|
|
|
rejectTask: (id: string, reason: string) =>
|
|
|
|
|
|
post<{ status: string }>(`/tasks/${id}/reject`, { reason }),
|
2026-03-16 07:15:04 +02:00
|
|
|
|
reviseTask: (id: string, comment: string) =>
|
|
|
|
|
|
post<{ status: string; comment: string }>(`/tasks/${id}/revise`, { comment }),
|
2026-03-15 23:22:49 +02:00
|
|
|
|
runTask: (id: string) =>
|
|
|
|
|
|
post<{ status: string }>(`/tasks/${id}/run`, {}),
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
bootstrap: (data: { path: string; id: string; name: string }) =>
|
|
|
|
|
|
post<{ project: Project }>('/bootstrap', data),
|
2026-03-15 17:44:16 +02:00
|
|
|
|
auditProject: (projectId: string) =>
|
|
|
|
|
|
post<AuditResult>(`/projects/${projectId}/audit`, {}),
|
|
|
|
|
|
auditApply: (projectId: string, taskIds: string[]) =>
|
|
|
|
|
|
post<{ updated: string[]; count: number }>(`/projects/${projectId}/audit/apply`, { task_ids: taskIds }),
|
2026-03-16 10:04:01 +02:00
|
|
|
|
patchTask: (id: string, data: { status?: string; execution_mode?: string; priority?: number; route_type?: string; title?: string; brief_text?: string; acceptance_criteria?: string }) =>
|
2026-03-15 18:17:57 +02:00
|
|
|
|
patch<Task>(`/tasks/${id}`, data),
|
2026-03-17 17:39:40 +02:00
|
|
|
|
patchProject: (id: string, data: { execution_mode?: string; autocommit_enabled?: boolean; auto_test_enabled?: boolean; obsidian_vault_path?: string; deploy_command?: string; test_command?: string; project_type?: string; ssh_host?: string; ssh_user?: string; ssh_key_path?: string; ssh_proxy_jump?: string; deploy_host?: string; deploy_path?: string; deploy_runtime?: string; deploy_restart_cmd?: string }) =>
|
2026-03-15 20:02:01 +02:00
|
|
|
|
patch<Project>(`/projects/${id}`, data),
|
2026-03-16 08:21:13 +02:00
|
|
|
|
deployProject: (projectId: string) =>
|
|
|
|
|
|
post<DeployResult>(`/projects/${projectId}/deploy`, {}),
|
2026-03-16 07:14:32 +02:00
|
|
|
|
syncObsidian: (projectId: string) =>
|
|
|
|
|
|
post<ObsidianSyncResult>(`/projects/${projectId}/sync/obsidian`, {}),
|
2026-03-16 17:44:49 +02:00
|
|
|
|
deleteProject: (id: string) =>
|
|
|
|
|
|
del<void>(`/projects/${id}`),
|
2026-03-15 23:22:49 +02:00
|
|
|
|
deleteDecision: (projectId: string, decisionId: number) =>
|
|
|
|
|
|
del<{ deleted: number }>(`/projects/${projectId}/decisions/${decisionId}`),
|
2026-03-16 07:13:32 +02:00
|
|
|
|
createDecision: (data: { project_id: string; type: string; title: string; description: string; category?: string; tags?: string[] }) =>
|
|
|
|
|
|
post<Decision>('/decisions', data),
|
2026-03-16 09:13:34 +02:00
|
|
|
|
newProject: (data: NewProjectPayload) =>
|
|
|
|
|
|
post<NewProjectResult>('/projects/new', data),
|
|
|
|
|
|
getPhases: (projectId: string) =>
|
|
|
|
|
|
get<Phase[]>(`/projects/${projectId}/phases`),
|
|
|
|
|
|
notifications: (projectId?: string) =>
|
|
|
|
|
|
get<EscalationNotification[]>(`/notifications${projectId ? `?project_id=${projectId}` : ''}`),
|
|
|
|
|
|
approvePhase: (phaseId: number, comment?: string) =>
|
|
|
|
|
|
post<{ phase: Phase; next_phase: Phase | null }>(`/phases/${phaseId}/approve`, { comment }),
|
|
|
|
|
|
rejectPhase: (phaseId: number, reason: string) =>
|
|
|
|
|
|
post<Phase>(`/phases/${phaseId}/reject`, { reason }),
|
|
|
|
|
|
revisePhase: (phaseId: number, comment: string) =>
|
|
|
|
|
|
post<{ phase: Phase; new_task: Task }>(`/phases/${phaseId}/revise`, { comment }),
|
kin: KIN-059 Workflow new_project с выбором команды. При создании нового проекта через GUI или CLI директор описывает проект свободным текстом и выбирает галочками какие этапы research нужны: ☐ Business analyst (бизнес-модель, аудитория, монетизация) ☐ Market researcher (конкуренты, ниша, отзывы, сильные/слабые стороны) ☐ Legal researcher (юрисдикция, лицензии, KYC/AML, GDPR) ☐ Tech researcher (API, ограничения, стоимость, альтернативы) ☐ UX designer (анализ UX конкурентов, user journey, wireframes) ☐ Marketer (стратегия продвижения, SEO, conversion-паттерны) ☐ Architect (blueprint на основе одобренных research'ей) — всегда последний Architect включается автоматически если выбран хотя бы один researcher. Каждый выбранный этап — отдельная задача на review. Директор одобряет, отклоняет, или просит доисследовать (Revise). Следующий этап только после approve предыдущего. GUI: форма 'New Project' с описанием + чекбоксы ролей + кнопка 'Start Research'. CLI: kin new-project 'описание' --roles 'business,market,tech,architect'
2026-03-16 09:30:00 +02:00
|
|
|
|
startPhase: (projectId: string) =>
|
|
|
|
|
|
post<{ status: string; phase_id: number; task_id: string }>(`/projects/${projectId}/phases/start`, {}),
|
2026-03-16 19:26:51 +02:00
|
|
|
|
environments: (projectId: string) =>
|
|
|
|
|
|
get<ProjectEnvironment[]>(`/projects/${projectId}/environments`),
|
|
|
|
|
|
createEnvironment: (projectId: string, data: { name: string; host: string; port?: number; username: string; auth_type?: string; auth_value?: string; is_installed?: boolean }) =>
|
|
|
|
|
|
post<ProjectEnvironment & { scan_task_id?: string }>(`/projects/${projectId}/environments`, data),
|
|
|
|
|
|
updateEnvironment: (projectId: string, envId: number, data: { name?: string; host?: string; port?: number; username?: string; auth_type?: string; auth_value?: string; is_installed?: boolean }) =>
|
|
|
|
|
|
patch<ProjectEnvironment & { scan_task_id?: string }>(`/projects/${projectId}/environments/${envId}`, data),
|
|
|
|
|
|
deleteEnvironment: (projectId: string, envId: number) =>
|
|
|
|
|
|
del<void>(`/projects/${projectId}/environments/${envId}`),
|
|
|
|
|
|
scanEnvironment: (projectId: string, envId: number) =>
|
|
|
|
|
|
post<{ status: string; task_id: string }>(`/projects/${projectId}/environments/${envId}/scan`, {}),
|
|
|
|
|
|
chatHistory: (projectId: string, limit = 50) =>
|
|
|
|
|
|
get<ChatMessage[]>(`/projects/${projectId}/chat?limit=${limit}`),
|
|
|
|
|
|
sendChatMessage: (projectId: string, content: string) =>
|
|
|
|
|
|
post<ChatSendResult>(`/projects/${projectId}/chat`, { content }),
|
2026-03-16 20:39:17 +02:00
|
|
|
|
uploadAttachment: (taskId: string, file: File) => {
|
|
|
|
|
|
const fd = new FormData()
|
|
|
|
|
|
fd.append('file', file)
|
|
|
|
|
|
return postForm<Attachment>(`/tasks/${taskId}/attachments`, fd)
|
|
|
|
|
|
},
|
|
|
|
|
|
getAttachments: (taskId: string) =>
|
|
|
|
|
|
get<Attachment[]>(`/tasks/${taskId}/attachments`),
|
|
|
|
|
|
deleteAttachment: (taskId: string, id: number) =>
|
|
|
|
|
|
del<void>(`/tasks/${taskId}/attachments/${id}`),
|
|
|
|
|
|
attachmentUrl: (id: number) => `${BASE}/attachments/${id}/file`,
|
2026-03-17 17:39:40 +02:00
|
|
|
|
getPipelineLogs: (pipelineId: string, sinceId: number) =>
|
|
|
|
|
|
get<PipelineLog[]>(`/pipelines/${pipelineId}/logs?since_id=${sinceId}`),
|
|
|
|
|
|
projectLinks: (projectId: string) =>
|
|
|
|
|
|
get<ProjectLink[]>(`/projects/${projectId}/links`),
|
2026-03-17 18:37:02 +02:00
|
|
|
|
createProjectLink: (data: { from_project: string; to_project: string; type: string; description?: string }) =>
|
2026-03-17 17:39:40 +02:00
|
|
|
|
post<ProjectLink>('/project-links', data),
|
|
|
|
|
|
deleteProjectLink: (id: number) =>
|
|
|
|
|
|
del<void>(`/project-links/${id}`),
|
Add web GUI: FastAPI API + Vue 3 frontend with dark theme
API (web/api.py):
GET /api/projects, /api/projects/{id}, /api/tasks/{id}
GET /api/decisions?project=X, /api/cost?days=7, /api/support/tickets
POST /api/projects, /api/tasks, /api/decisions, /api/bootstrap
CORS for localhost:5173, all queries via models.py
Frontend (web/frontend/):
Vue 3 + TypeScript + Vite + Tailwind CSS v3
Dashboard: project cards with task counters, cost, status badges
ProjectView: tabs for Tasks/Decisions/Modules with filters
Modals: Add Project, Add Task, Add Decision, Bootstrap
Dark theme, monospace font, minimal clean design
Startup:
API: cd web && uvicorn api:app --reload --port 8420
Web: cd web/frontend && npm install && npm run dev
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 13:50:15 +02:00
|
|
|
|
}
|