# Milestone: Embeddable IOP Console Workbench

## 위치

- Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/control-plane-portal-ops/PHASE.md`

## 목표

IOP standalone 앱은 application shell로 유지하되, 실제 IOP 관리 기능과 UI 위젯 전체는 Flutter package 형태로 분리한다. 이 package는 IOP 앱에서는 좌측 icon rail + center content 구조로 보이고, NomadCode 같은 host 앱에서는 같은 native Flutter 위젯이 별도 제품 shell 안에 그대로 들어갈 수 있어야 한다.

## 상태

[완료]

## 구현 잠금

- 상태: 해제
- 결정 필요: 없음

## 범위

- `iop/apps/client`를 standalone application shell로 유지하는 구조
- IOP 관리 화면, route/controller, rail item, agent capability를 embeddable Flutter package로 분리하는 구조
- IOP standalone에서는 좌측 icon rail만 두고 중앙 content를 전환하는 workbench layout
- host 앱이 IOP package를 선택적으로 import해 native Flutter widget으로 삽입할 수 있는 public API
- 공통 agent shell package와 IOP agent capability pack의 연결 경계
- IOP package가 NomadCode 제품 shell, WebView 조작 UX, workflow/task UX를 알지 못하게 하는 의존성 경계

## 기능

### Epic: [package-boundary] IOP console package boundary

IOP 운영 경험을 application shell에서 분리해, standalone 앱과 외부 host가 같은 관리 UI를 재사용할 수 있는 package 경계를 만든다.

- [x] [console-package] IOP 관리 UI를 `MaterialApp`/global bootstrap 없이 import 가능한 `packages/flutter/iop_console` Flutter package로 분리하고, `IopConsoleShell`, `IopConsoleSection`, `IopAgentPanel`을 public export로 제공한다. 검증: package public export가 app shell 없이 widget/section 단위로 소비 가능하다.
- [x] [standalone-shell] `iop/apps/client`는 Firebase/SystemChrome/app bootstrap과 standalone theme를 담당하고, 실제 workbench shell은 IOP console package를 감싸서 실행한다. 검증: standalone 앱에서 IOP console이 좌측 rail + center content 구조로 표시되고 agent panel 진입 widget test가 있다.
- [x] [host-agnostic] IOP console package는 NomadCode, Project/Workspace, WebView 조작, product workflow 개념을 import하거나 전제하지 않는다. 검증: package dependency graph에 NomadCode 전용 package가 없다.
- [x] [overview-boundary] Control Plane wire status overview는 현재 `apps/client/lib/main.dart`의 host-injected content로 남아 있다. 재사용 가능한 package widget으로 옮길지, standalone host content로 유지할지 경계를 확정한다.

### Epic: [workbench-layout] IOP left-rail workbench

IOP standalone 화면은 좌측 icon rail을 기준으로 중앙 content를 전환하는 운영 workbench로 정리한다.

- [x] [left-rail] IOP standalone layout은 좌측 icon rail과 center content host를 기본 구조로 둔다.
- [x] [content-switch] Overview, Edges, Nodes, Runtime, Maintenance, Agent, Settings 영역은 rail item 선택에 따라 중앙 content를 전환한다.
- [x] [execution-logs] Execution/Logs 영역은 별도 rail item, Runtime 하위 화면, Maintenance 하위 화면 중 어디에 둘지 정리하고 표시 경로를 추가한다.
- [x] [stable-widgets] rail item, tooltip, selected state, content host는 host layout 크기에 따라 안정적으로 배치된다. 검증: desktop/mobile 또는 narrow/wide viewport에서 rail과 content가 겹치지 않는다.

### Epic: [agent-capability] IOP agent capability pack

공통 agent shell은 외부 package로 두고, IOP는 자신의 운영 capability만 제공한다.

- [x] [agent-shell-link] IOP console package는 공통 `agent_shell` 계열 package를 통해 채팅형 agent surface를 열 수 있다.
- [x] [iop-capabilities] IOP agent capability는 Edge/Node 상태, runtime/adapter/target, execution, logs, maintenance command 같은 IOP 책임 범위만 포함한다.
- [x] [capability-api] IOP capability pack은 host가 agent shell registry에 꽂을 수 있는 public API를 제공한다. 검증: IOP standalone과 외부 host가 같은 IOP capability pack을 등록할 수 있다.

### Epic: [embedding-contract] External host embedding contract

NomadCode 같은 외부 host가 IOP UI를 optional feature로 넣거나 빼도 빌드 경계가 깨지지 않도록 한다.

- [x] [public-widget] IOP package는 `IopConsoleShell`, `IopConsoleSection`, `IopAgentPanel` public entry를 제공한다.
- [x] [config-injection] host는 Control Plane endpoint, auth/token reference, theme adapter, navigation callback을 주입하고 IOP package는 host 전역 상태를 직접 소유하지 않는다.
- [x] [optional-consumer] IOP package는 optional consumer인 NomadCode 없이도 단독으로 테스트되고 빌드된다. 검증: IOP repository 안에서 package test/analyze 경로가 독립적으로 통과한다.

## 완료 리뷰

- 상태: 승인됨
- 요청일: 2026-06-02
- 완료 근거: `m-embeddable-iop-console-workbench` split task 완료 로그와 PASS 리뷰를 반영했다. 남은 `optional-consumer`는 `cd packages/flutter/iop_console && flutter analyze --no-fatal-infos`, `cd packages/flutter/iop_console && flutter test`, `cd apps/client && flutter test` 통과로 충족되었다.
- 리뷰 필요:
  - [x] 사용자가 완료 결과를 확인했다
  - [x] archive 이동을 승인했다
- 리뷰 코멘트: 사용자 요청에 따라 마일스톤을 완료 처리하고 archive로 이동한다.

## 범위 제외

- NomadCode의 우측 rail, titlebar, workflow/project/webview UX 구현
- NomadCode default build와 IOP 포함 build의 조립 전략 구현
- IOP 내부 모델 라우팅, RAG, MCP/tool policy, output validation 세부 구현
- 런타임 동적 plugin framework 도입
- IOP package가 NomadCode 전용 화면을 직접 import하거나 소유하는 구조

## 작업 컨텍스트

- 관련 경로: `apps/client/`, `packages/flutter/iop_console/`, `proto/iop/`, `apps/control-plane/`
- 표준선(선택): IOP는 범용 추론/자동화 운영 엔진이며 NomadCode 전용 Agent Shell이 아니다.
- 표준선(선택): shared UI는 application shell이 아니라 package/widget/controller/capability 단위로 재사용한다.
- 표준선(선택): IOP standalone은 좌측 icon rail + center content 구조를 기본 workbench로 둔다.
- 구현 근거: `49872ae feat(client): iop_console 패키지로 클라이언트 UI를 분리한다`에서 `packages/flutter/iop_console` package, `IopConsoleShell`, `IopAgentPanel`, `apps/client` mount와 widget test가 추가되었다.
- 현재 구현 상태: package 이름은 `iop_console`으로 확정되었고 rail item은 Overview, Edges, Nodes, Runtime, Maintenance, Execution/Logs, Agent, Settings다. Reusable overview, reference-only auth config, theme/navigation/capability injection, IOP capability pack API, narrow/wide widget stability 검증, package 독립 test/analyze 검증이 반영되었다.
- 선행 작업: Control Plane과 Client, Flutter-first Client 마이그레이션, Control Plane-Edge Wire Baseline
- 후속 작업: NomadCode Workbench Shell and Optional IOP Composition, Multi-Edge 운영
- 확인 필요: 없음
