test(workbench): 워크벤치 검증과 로드맵 상태를 동기화한다
현재 마일스톤의 project-config 진행 상태와 workbench-shell 검증 근거를 로드맵에 반영한다.
This commit is contained in:
parent
0d6916fd48
commit
a5449ab91c
4 changed files with 64 additions and 14 deletions
|
|
@ -14,7 +14,7 @@
|
|||
완료, 검토중, 진행중, 계획, 스케치 순서로 두어 아래로 갈수록 미래 작업에 가까워지게 정렬한다.
|
||||
스케치 Milestone은 아직 구현 가능한 계획이 아니므로 계획 Milestone보다 아래에 둔다.
|
||||
|
||||
- [계획] Milestone Work Item Creation Sync
|
||||
- [진행중] Milestone Work Item Creation Sync
|
||||
- 경로: `agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/milestone-work-item-creation-sync.md`
|
||||
- 요약: Plane-origin 방식으로 Milestone을 생성하고 Plane Todo 티켓까지 동기화한 뒤 멈추는 계획 후보다. Workspace agent 실행은 IOP CLI 1차 통로를 선행으로 두며, Agent chat/IDE-origin 생성 projection은 이번 범위에서 제외한다.
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ Plane-origin 경로로 Milestone을 생성하고, `develop` branch의 agent-road
|
|||
|
||||
## 상태
|
||||
|
||||
[계획]
|
||||
[진행중]
|
||||
|
||||
## 구현 잠금
|
||||
|
||||
|
|
@ -47,14 +47,14 @@ Plane-origin 경로로 Milestone을 생성하고, `develop` branch의 agent-road
|
|||
|
||||
Plane project 단위로 Milestone sync에 필요한 기본 설정을 저장하고 이후 UI/UX가 소비할 project settings 경계를 만든다.
|
||||
|
||||
- [ ] [project-model] Plane project 단위 sync 설정 모델을 정의한다. 검증: 설정 모델이 provider project target, git remote URL, source-of-truth branch, workspace id/path를 필수 필드로 갖는다.
|
||||
- [ ] [project-store] Project sync 설정을 Core DB에 저장하는 persistence 경계를 정한다. 검증: Plane project별로 하나의 active sync 설정을 찾을 수 있고, Milestone 생성 동기화가 이 설정 없이는 진행되지 않는 기준이 문서화되어 있다.
|
||||
- [ ] [project-bind] Plane-origin 생성 동기화가 project sync 설정을 통해 Plane project, git repository, 작업 workspace를 해석하도록 한다. 검증: 같은 Plane project 안의 티켓은 같은 git/workspace 설정을 사용하며, 다른 Plane project와 섞이지 않는다.
|
||||
- [ ] [workspace-layout] NomadCode host 기준 workspace 경로 규칙을 정의한다. 검증: `workspace_base_path=/home/user/workspace`, `repo_dir_name=nomadcode`이면 project workspace root는 `/home/user/workspace/nomadcode`이고 실제 작업 slot path는 `/home/user/workspace/nomadcode/000`처럼 계산된다.
|
||||
- [ ] [workspace-slot] 병렬 운용을 위한 workspace slot index 모델을 정의한다. 검증: 기본 작업공간은 `000`이고, 병렬 요청이 들어오면 `001`, `002`처럼 3자리 zero-padded index를 증가시키며 각 slot이 독립 작업공간으로 예약된다.
|
||||
- [ ] [workspace-slot-state] Workspace slot의 사용중 상태 모델을 정의한다. 검증: 각 slot은 `available`, `in_use`, `dirty`, `error` 같은 상태 후보를 갖고, 새 작업은 `available` slot만 선택하며, 동시에 들어온 요청이 같은 slot을 잡지 않도록 DB에서 원자적으로 `in_use`로 전환하는 기준이 있다.
|
||||
- [ ] [workspace-checkout] Git repository checkout 정책을 project sync 설정과 연결한다. 검증: git remote는 project sync 설정에서 읽고, 안정성을 우선해 각 slot은 같은 remote의 독립 checkout을 기본으로 확보하며, 일반 단일 운용에서는 `000`만 사용한다.
|
||||
- [ ] [settings-ui] Project sync 설정을 이후 프로젝트 설정 UI/UX에서 관리해야 하는 후보로 남긴다. 검증: 이번 마일스톤에서는 UI 구현을 하지 않고, 후속 Project settings 화면이 provider project target, git remote, workspace를 표시/수정해야 한다는 요구가 남아 있다.
|
||||
- [x] [project-model] Plane project 단위 sync 설정 모델을 정의한다. 검증: 설정 모델이 provider project target, git remote URL, source-of-truth branch, workspace id/path를 필수 필드로 갖는다.
|
||||
- [x] [project-store] Project sync 설정을 Core DB에 저장하는 persistence 경계를 정한다. 검증: Plane project별로 하나의 active sync 설정을 찾을 수 있고, Milestone 생성 동기화가 이 설정 없이는 진행되지 않는 기준이 문서화되어 있다.
|
||||
- [x] [project-bind] Plane-origin 생성 동기화가 project sync 설정을 통해 Plane project, git repository, 작업 workspace를 해석하도록 한다. 검증: 같은 Plane project 안의 티켓은 같은 git/workspace 설정을 사용하며, 다른 Plane project와 섞이지 않는다.
|
||||
- [x] [workspace-layout] NomadCode host 기준 workspace 경로 규칙을 정의한다. 검증: `workspace_base_path=/home/user/workspace`, `repo_dir_name=nomadcode`이면 project workspace root는 `/home/user/workspace/nomadcode`이고 실제 작업 slot path는 `/home/user/workspace/nomadcode/000`처럼 계산된다.
|
||||
- [x] [workspace-slot] 병렬 운용을 위한 workspace slot index 모델을 정의한다. 검증: 기본 작업공간은 `000`이고, 병렬 요청이 들어오면 `001`, `002`처럼 3자리 zero-padded index를 증가시키며 각 slot이 독립 작업공간으로 예약된다.
|
||||
- [x] [workspace-slot-state] Workspace slot의 사용중 상태 모델을 정의한다. 검증: 각 slot은 `available`, `in_use`, `dirty`, `error` 같은 상태 후보를 갖고, 새 작업은 `available` slot만 선택하며, 동시에 들어온 요청이 같은 slot을 잡지 않도록 DB에서 원자적으로 `in_use`로 전환하는 기준이 있다.
|
||||
- [x] [workspace-checkout] Git repository checkout 정책을 project sync 설정과 연결한다. 검증: git remote는 project sync 설정에서 읽고, 안정성을 우선해 각 slot은 같은 remote의 독립 checkout을 기본으로 확보하며, 일반 단일 운용에서는 `000`만 사용한다.
|
||||
- [x] [settings-ui] Project sync 설정을 이후 프로젝트 설정 UI/UX에서 관리해야 하는 후보로 남긴다. 검증: 이번 마일스톤에서는 UI 구현을 하지 않고, 후속 Project settings 화면이 provider project target, git remote, workspace를 표시/수정해야 한다는 요구가 남아 있다.
|
||||
|
||||
### Epic: [agent-bridge] Workspace agent IOP CLI bridge
|
||||
|
||||
|
|
@ -120,6 +120,7 @@ Plane-origin 생성 경로를 `develop` agent-roadmap 기준의 `Todo` 검토
|
|||
- Slot 사용 상태: slot은 Core DB에서 `available` 또는 `in_use` 같은 사용 상태를 추적한다. 여기서 사용 상태는 해당 slot이 현재 작업에 배정되어 다른 병렬 작업이 잡으면 안 되는지를 나타낸다.
|
||||
- Checkout 기준: 안정성을 우선해 각 slot은 같은 git remote를 기준으로 독립 checkout을 갖는 작업공간으로 둔다. 초기 slot 생성 때 clone 비용이 들지만 이후 branch 이동과 일반 작업은 해당 slot 안에서 처리하므로 운영 비용을 낮춘다.
|
||||
- 후속 UI/UX: project settings 화면에서 Plane project target, git remote, workspace 설정을 확인하고 수정하는 UX가 필요하다.
|
||||
- 완료 근거(2026-06-07): `[project-config]`는 `services/core/internal/projectsync/`, `services/core/migrations/00004_create_project_sync_settings.sql`, `services/core/migrations/00005_create_workspace_slots.sql`, `services/core/queries/project_sync_settings.sql`, `services/core/queries/workspace_slots.sql`, `packages/contracts/notes/flutter-core-api-candidates.md`의 모델/저장/slot/UI 후보 경계와 테스트로 확인했다. 검증: `cd services/core && go test ./...` PASS.
|
||||
- 중지 지점: Plane-origin 생성이 Plane `Todo` 상위 티켓과 `develop` agent-roadmap Milestone identity로 연결된 상태다.
|
||||
- 루프 확인: Plane `Backlog + AGENT assignee` -> IOP CLI로 workspace agent authoring run 실행 -> agent가 Milestone 파일 작성/갱신 후 `develop` push -> sync layer가 push 완료 또는 roadmap scan을 감지 -> Plane 원문 댓글 보존/본문 치환/제목 변경/`Todo` 이동 -> 사용자가 확인 후 `In Progress`로 이동하는 지점까지다. `In Progress` 이후 실행은 후속 잠금 범위다.
|
||||
- 후속 잠금: `Todo -> In Progress` 이후 실행 lifecycle은 사용자가 명시적으로 잠금을 해제할 때까지 진행하지 않는다.
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ NomadCode Flutter 앱의 상단 titlebar와 우측 icon rail 기반 workbench sh
|
|||
|
||||
NomadCode는 여러 도메인 관리 화면을 우측 icon rail과 중앙 content host로 전환하는 제품 shell을 소유한다.
|
||||
|
||||
- [ ] [titlebar] NomadCode shell은 상단 titlebar 영역을 제공하고, 앱/워크스페이스/현재 컨텍스트 상태를 이 영역에서 표현한다.
|
||||
- [ ] [right-rail] NomadCode shell은 VS Code activity bar처럼 아이콘만 있는 우측 rail을 제공한다.
|
||||
- [ ] [center-content] 우측 rail item 선택에 따라 중앙 content가 Agent, Workflow, Web Context, Settings, provider slot 등으로 전환된다.
|
||||
- [ ] [layout-shape] 상단 titlebar와 우측 rail이 ㄱ자 구조를 만들고, 중앙 content는 host 도메인 화면을 침범 없이 표시한다. 검증: narrow/wide layout에서 titlebar, rail, center content가 겹치지 않는다.
|
||||
- [x] [titlebar] NomadCode shell은 상단 titlebar 영역을 제공하고, 앱/워크스페이스/현재 컨텍스트 상태를 이 영역에서 표현한다.
|
||||
- [x] [right-rail] NomadCode shell은 VS Code activity bar처럼 아이콘만 있는 우측 rail을 제공한다.
|
||||
- [x] [center-content] 우측 rail item 선택에 따라 중앙 content가 Agent, Workflow, Web Context, Settings, provider slot 등으로 전환된다.
|
||||
- [x] [layout-shape] 상단 titlebar와 우측 rail이 ㄱ자 구조를 만들고, 중앙 content는 host 도메인 화면을 침범 없이 표시한다. 검증: narrow/wide layout에서 titlebar, rail, center content가 겹치지 않는다.
|
||||
|
||||
### Epic: [provider-slots] Provider slot registry
|
||||
|
||||
|
|
@ -89,6 +89,7 @@ IOP와 OTO 관리는 webview나 별도 앱이 아니라 각 repository의 embedd
|
|||
- 표준선(선택): NomadCode shell은 상단 titlebar + 우측 icon rail + center content 구조를 소유한다.
|
||||
- 표준선(선택): 외부 제품 UI는 provider adapter/composition layer에서만 import하고, default build는 외부 제품 package 없이 빌드 가능해야 한다.
|
||||
- 표준선(선택): Agent shell은 공통 package, NomadCode/IOP/OTO는 각각 capability pack으로 조립한다.
|
||||
- 완료 근거(2026-06-07): `[workbench-shell]`은 `apps/client/lib/src/app/nomadcode_workbench_shell.dart`와 `apps/client/test/widget_test.dart`의 right rail, Agent dock, IOP/Workflow section 전환, narrow/wide layout rect 검증으로 확인했다. 검증: `cd apps/client && flutter test` PASS.
|
||||
- 선행 작업: Client Integration Standardization, Project Workspace Management UX
|
||||
- 선행 확인 대상: `../iop/packages/flutter/iop_console/`, `../oto/packages/flutter/oto_console/`
|
||||
- 후속 작업: 실제 desktop/mobile project workspace 화면 구현, workflow/provider 관리 탭별 세부 content 구현
|
||||
|
|
|
|||
|
|
@ -133,6 +133,54 @@ void main() {
|
|||
expect(find.textContaining('Optional IOP console package'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Workbench separates titlebar, right rail, and content', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
addTearDown(() {
|
||||
tester.view.resetPhysicalSize();
|
||||
tester.view.resetDevicePixelRatio();
|
||||
});
|
||||
|
||||
for (final size in const [Size(390, 800), Size(1280, 900)]) {
|
||||
tester.view.physicalSize = size;
|
||||
tester.view.devicePixelRatio = 1;
|
||||
await tester.pumpWidget(const NomadCodeClientApp());
|
||||
await tester.pump();
|
||||
|
||||
final titleRect = tester.getRect(find.text('NomadCode Console'));
|
||||
final workflowRailRect = tester.getRect(find.byTooltip('Workflow'));
|
||||
|
||||
expect(titleRect.bottom, lessThanOrEqualTo(workflowRailRect.top));
|
||||
|
||||
await tester.tap(find.byTooltip('Workflow'));
|
||||
await tester.pump();
|
||||
|
||||
final workflowContentRect = tester.getRect(
|
||||
find.text('Workflow management surface will mount here.'),
|
||||
);
|
||||
|
||||
expect(workflowContentRect.top, greaterThan(titleRect.bottom));
|
||||
expect(
|
||||
workflowContentRect.right,
|
||||
lessThanOrEqualTo(workflowRailRect.left),
|
||||
);
|
||||
|
||||
await tester.tap(find.byTooltip('Agent'));
|
||||
await tester.pump();
|
||||
|
||||
final agentRailRect = tester.getRect(find.byTooltip('Agent'));
|
||||
final agentContentRect = tester.getRect(
|
||||
find.text('Ask the workspace agent'),
|
||||
);
|
||||
|
||||
expect(agentContentRect.top, greaterThan(titleRect.bottom));
|
||||
expect(agentContentRect.right, lessThanOrEqualTo(agentRailRect.left));
|
||||
|
||||
await tester.pumpWidget(const SizedBox.shrink());
|
||||
await tester.pump();
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('WorkspaceHomePage triggers launcher callback on button tap', (
|
||||
WidgetTester tester,
|
||||
) async {
|
||||
|
|
|
|||
Loading…
Reference in a new issue