From 68f6e08da836fe6259cdf1c2553c88e4427cecd1 Mon Sep 17 00:00:00 2001 From: toki Date: Tue, 2 Jun 2026 15:37:34 +0900 Subject: [PATCH] feat: update control-plane-client roadmap, add edge Dockerfile & config, update docker-compose & dev scripts --- .../milestones/control-plane-client.md | 27 +++-- .../embeddable-iop-console-workbench.md | 94 ------------------ apps/edge/Dockerfile | 29 ++++++ configs/edge-compose.yaml | 61 ++++++++++++ docker-compose.yml | 27 +++-- ...28829e100ef67db14ea2.cache.dill.track.dill | Bin 45937888 -> 45937888 bytes scripts/dev/web.sh | 2 +- 7 files changed, 127 insertions(+), 113 deletions(-) delete mode 100644 agent-roadmap/phase/control-plane-portal-ops/milestones/embeddable-iop-console-workbench.md create mode 100644 apps/edge/Dockerfile create mode 100644 configs/edge-compose.yaml diff --git a/agent-roadmap/phase/control-plane-portal-ops/milestones/control-plane-client.md b/agent-roadmap/phase/control-plane-portal-ops/milestones/control-plane-client.md index 23a0a52..422f463 100644 --- a/agent-roadmap/phase/control-plane-portal-ops/milestones/control-plane-client.md +++ b/agent-roadmap/phase/control-plane-portal-ops/milestones/control-plane-client.md @@ -16,17 +16,20 @@ Client는 NomadCode 전용 화면이 아니라 IOP가 독립적으로 운영되 ## 구현 잠금 -- 상태: 잠금 -- 결정 필요: 아래 체크리스트 - - [ ] Client의 첫 운영 화면 범위를 Edge/Node 상태 조회 중심으로 둘지, 명령/설정 변경까지 포함할지 결정한다. - - [ ] IOP client가 범용 운영 UI로 남기 위해 제외할 NomadCode 전용 UX 경계를 결정한다. +- 상태: 해제 +- 결정 필요: 없음 +- 결정 결과: + - Client의 첫 운영 화면은 Edge/Node 운영 lifecycle을 얇게 파악하는 데 필요한 설정 조회, Node registry, 연결 상태, 로그/이벤트 중심으로 둔다. + - 설정 변경, 명령 실행, 권한이 필요한 조작 UX는 첫 화면에 무겁게 넣지 않고 조회/상태/근거가 안정화된 뒤 후속으로 덧붙인다. + - IOP client는 범용 운영 UI로 유지하며 NomadCode 전용 project/workspace/webview/diff/PR/branch/commit UX를 포함하지 않는다. ## 범위 - Control Plane Go server의 Edge connection 관리 - Client-Control Plane wire surface와 Control Plane-Edge Wire Baseline 위의 운영 표면 확장 - Flutter client의 Runtime/Automation/Serving 운영 화면 기초 -- Edge 상태 조회, 설정 변경, 명령 전달, 이벤트 수신 +- Edge/Node 설정 조회, Node registry, 연결 상태, 로그/이벤트 수신을 중심으로 한 얇은 lifecycle 운영 화면 +- 설정 변경과 명령 전달은 lifecycle 조회 표면 위에 붙일 후속 확장 후보로 정리 - Edge agent 생성과 bootstrap command 발급 상태 조회/관리 - remote terminal bridge session 생성/조회/권한 확인 표면 - IOP 책임 범위 안의 model serving, automation, session, routing, policy, history, audit 운영 UX @@ -36,14 +39,16 @@ Client는 NomadCode 전용 화면이 아니라 IOP가 독립적으로 운영되 ### Epic: [edge-ops-boundary] Edge Operations Boundary - [ ] [edge-mediated] Control Plane은 Node를 직접 연결하거나 직접 스케줄링하지 않는다. -- [ ] [edge-status] Control Plane은 선행 Wire Baseline으로 연결된 하나 이상의 Edge 상태를 조회할 수 있다. 검증: Edge 연결 상태 조회 경로가 동작하는지 확인한다. -- [ ] [edge-command-events] Edge 명령 전달과 이벤트 수신 흐름이 Control Plane-Edge Wire Baseline 위의 IOP Wire Protocol 기준으로 문서화된다. -- [ ] [client-via-cp] Client는 Control Plane을 통해 Edge 운영 상태를 조회한다. +- [ ] [edge-status] Control Plane은 선행 Wire Baseline으로 연결된 하나 이상의 Edge 연결 상태를 조회할 수 있다. 검증: Edge 연결 상태 조회 경로가 동작하는지 확인한다. +- [ ] [node-registry] Control Plane은 Edge가 보고하는 Node registry와 Node 연결 상태를 운영 표면에 전달할 수 있다. 검증: Node 목록과 연결 상태가 Control Plane을 통해 조회된다. +- [ ] [edge-node-config-view] Control Plane/Client는 Edge/Node의 현재 운영 설정 요약을 조회 중심으로 보여준다. 검증: 설정 원본이나 effective config 요약이 조작 없이 표시된다. +- [ ] [edge-event-logs] Edge lifecycle event와 기본 로그/상태 이벤트 수신 흐름이 Control Plane-Edge Wire Baseline 위의 IOP Wire Protocol 기준으로 정리된다. +- [ ] [client-via-cp] Client는 Control Plane을 통해 Edge/Node 운영 lifecycle 상태를 조회한다. ### Epic: [client-wire-surface] Client Wire Surface - [x] [client-boundary] Flutter client는 IOP 자체 운영 UI/UX이며 NomadCode에 맞춘 전용 shell로 만들지 않는다. -- [ ] [client-status] Client는 Edge/Node/agent 상태를 사용자에게 보여줄 수 있다. 검증: Client 상태 화면 또는 상태 표시 경로를 확인한다. +- [ ] [client-status] Client는 Edge/Node 설정 요약, registry, 연결 상태, 로그/이벤트를 lifecycle 중심으로 얇게 보여줄 수 있다. 검증: Client 상태 화면 또는 상태 표시 경로를 확인한다. - [x] [server-bridge] 브라우저 직접 TCP가 어려운 구간은 Control Plane server-side bridge를 둔다. - [x] [client-wire-hello] Client-Control Plane proto-socket WebSocket hello handshake scaffold가 구현되고 테스트되어 있다. 검증: Control Plane과 client 테스트에서 hello handshake가 통과한다. - [x] [http-boundary] `net/http`는 health/readiness/bootstrap 같은 보조 endpoint 용도로 유지한다. @@ -64,6 +69,7 @@ Client는 NomadCode 전용 화면이 아니라 IOP가 독립적으로 운영되 - Control Plane을 Kubernetes식 중앙 스케줄러로 만드는 작업 - Edge 내부 DB를 Control Plane DB로 대체 - 모든 런타임 상태를 Control Plane 단일 원본으로 만드는 작업 +- 첫 운영 화면에서 설정 변경, 명령 실행, 권한 조작 UX를 무겁게 구현하는 작업 - NomadCode Agent Shell 자체 구현 - NomadCode 전용 Project Workspace, diff/PR/branch/commit UX @@ -73,6 +79,7 @@ Client는 NomadCode 전용 화면이 아니라 IOP가 독립적으로 운영되 - 표준선(선택): Control Plane은 Node를 직접 스케줄링하지 않고 Edge를 통해 관찰/제어한다. - 표준선(선택): Control Plane-Edge 통신 레일은 `Control Plane-Edge Wire Baseline` 선행 Milestone에서 먼저 구축한다. - 표준선(선택): Client-Control Plane의 첫 wire surface는 `/client` WebSocket hello handshake를 기준으로 둔다. +- 표준선(선택): 첫 운영 화면은 설정 조회, Node registry, 연결 상태, 로그/이벤트처럼 한 lifecycle을 이해하는 데 필요한 얇은 조회 표면을 우선한다. - 선행 작업: Control Plane-Edge Wire Baseline, Flutter-first Client 마이그레이션, Edge Command와 Control Plane 운영 경계, Agent Bootstrap과 OTO 등록, 정책/이력/감사 일부 기준 - 후속 작업: Multi-Edge 운영 -- 확인 필요: Client 첫 화면 범위, NomadCode 전용 UX 제외 기준 +- 확인 필요: 없음 diff --git a/agent-roadmap/phase/control-plane-portal-ops/milestones/embeddable-iop-console-workbench.md b/agent-roadmap/phase/control-plane-portal-ops/milestones/embeddable-iop-console-workbench.md deleted file mode 100644 index 13afda2..0000000 --- a/agent-roadmap/phase/control-plane-portal-ops/milestones/embeddable-iop-console-workbench.md +++ /dev/null @@ -1,94 +0,0 @@ -# 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가 없다. -- [ ] [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를 전환한다. -- [ ] [execution-logs] Execution/Logs 영역은 별도 rail item, Runtime 하위 화면, Maintenance 하위 화면 중 어디에 둘지 정리하고 표시 경로를 추가한다. -- [ ] [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를 열 수 있다. -- [ ] [iop-capabilities] IOP agent capability는 Edge/Node 상태, runtime/adapter/target, execution, logs, maintenance command 같은 IOP 책임 범위만 포함한다. -- [ ] [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를 제공한다. -- [ ] [config-injection] host는 Control Plane endpoint, auth/token reference, theme adapter, navigation callback을 주입하고 IOP package는 host 전역 상태를 직접 소유하지 않는다. -- [ ] [optional-consumer] IOP package는 optional consumer인 NomadCode 없이도 단독으로 테스트되고 빌드된다. 검증: IOP repository 안에서 package test/analyze 경로가 독립적으로 통과한다. - -## 완료 리뷰 - -- 상태: 없음 -- 요청일: 없음 -- 완료 근거: `packages/flutter/iop_console` package boundary, left rail shell, standalone app mount, agent shell link는 구현되었으나 모든 기능 Task와 Task 안에 명시된 검증은 아직 충족되지 않았다. -- 리뷰 필요: - - [ ] 사용자가 완료 결과를 확인했다 - - [ ] 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, Agent, Settings다. Execution/Logs, controller/config injection, 독립 package test/analyze는 남은 작업이다. -- 선행 작업: Control Plane과 Client, Flutter-first Client 마이그레이션, Control Plane-Edge Wire Baseline -- 후속 작업: NomadCode Workbench Shell and Optional IOP Composition, Multi-Edge 운영 -- 확인 필요: Execution/Logs의 화면 배치, Control Plane endpoint/auth/theme/navigation injection public API, package 독립 검증 경로를 확정한다. diff --git a/apps/edge/Dockerfile b/apps/edge/Dockerfile new file mode 100644 index 0000000..6a688d4 --- /dev/null +++ b/apps/edge/Dockerfile @@ -0,0 +1,29 @@ +# syntax=docker/dockerfile:1 + +FROM golang:1.24-alpine AS builder + +WORKDIR /workspace/iop +RUN apk add --no-cache git + +# docker-compose builds this Dockerfile with /config/workspace as context so +# the local ../proto-socket/go replace in go.mod is available. +COPY iop/go.mod iop/go.sum ./ +COPY proto-socket/go /workspace/proto-socket/go +RUN go mod download + +COPY iop/ ./ +RUN CGO_ENABLED=0 GOFLAGS=-trimpath go build -o /out/edge ./apps/edge/cmd/edge + +FROM alpine:3.22 + +RUN addgroup -S iop && adduser -S iop -G iop +WORKDIR /app + +COPY --from=builder /out/edge /usr/local/bin/edge +COPY --from=builder /workspace/iop/configs/edge-compose.yaml /app/configs/edge-compose.yaml + +EXPOSE 9090 + +USER iop +ENTRYPOINT ["edge"] +CMD ["serve", "--config", "/app/configs/edge-compose.yaml"] diff --git a/configs/edge-compose.yaml b/configs/edge-compose.yaml new file mode 100644 index 0000000..c4523e0 --- /dev/null +++ b/configs/edge-compose.yaml @@ -0,0 +1,61 @@ +edge: + id: "edge-compose" + name: "Compose Edge" + +server: + listen: "0.0.0.0:9090" + advertise_host: "" + +bootstrap: + artifact_base_url: "" + listen: "0.0.0.0:18080" + artifact_dir: "/tmp/iop-artifacts" + +tls: + enabled: false + +logging: + level: "info" + pretty: true + path: "/tmp/iop-edge/edge.log" + +metrics: + port: 0 + +control_plane: + enabled: true + wire_addr: "control-plane:19081" + reconnect_interval_sec: 5 + +a2a: + enabled: false + +openai: + enabled: false + +console: + adapter: "cli" + target: "codex" + session_id: "default" + background: false + timeout_sec: 300 + +nodes: + - id: "external-node" + alias: "external-node" + token: "changeme" + adapters: + cli: + enabled: true + profiles: + codex: + command: "codex" + args: [] + persistent: false + terminal: false + response_idle_timeout_ms: 1000 + startup_idle_timeout_ms: 1000 + output_format: "plain" + mode: "exec" + runtime: + concurrency: 1 diff --git a/docker-compose.yml b/docker-compose.yml index d8d156c..006adab 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: POSTGRES_PASSWORD: ${IOP_POSTGRES_PASSWORD:-iop_dev_password} POSTGRES_DB: ${IOP_POSTGRES_DB:-iop-control-plane-dev} ports: - - "${IOP_POSTGRES_PORT:-5432}:5432" + - "${IOP_POSTGRES_BIND:-127.0.0.1}:${IOP_POSTGRES_PORT:-5432}:5432" volumes: - control-plane-postgres:/var/lib/postgresql/data healthcheck: @@ -23,7 +23,7 @@ services: restart: unless-stopped command: ["redis-server", "--appendonly", "yes"] ports: - - "${IOP_REDIS_PORT:-6379}:6379" + - "${IOP_REDIS_BIND:-127.0.0.1}:${IOP_REDIS_PORT:-6379}:6379" volumes: - control-plane-redis:/data healthcheck: @@ -42,9 +42,9 @@ services: IOP_REDIS_URL: "redis://redis:6379/${IOP_REDIS_DB:-2}" IOP_REDIS_KEY_PREFIX: "${IOP_REDIS_KEY_PREFIX:-iop:control-plane:dev:}" ports: - - "${IOP_CONTROL_PLANE_HTTP_PORT:-9080}:9080" - - "${IOP_CONTROL_PLANE_WIRE_PORT:-19080}:19080" - - "${IOP_CONTROL_PLANE_EDGE_WIRE_PORT:-19081}:19081" + - "${IOP_CONTROL_PLANE_HTTP_BIND:-127.0.0.1}:${IOP_CONTROL_PLANE_HTTP_PORT:-9080}:9080" + - "${IOP_CONTROL_PLANE_WIRE_BIND:-0.0.0.0}:${IOP_CONTROL_PLANE_WIRE_PORT:-19080}:19080" + - "${IOP_CONTROL_PLANE_EDGE_WIRE_BIND:-127.0.0.1}:${IOP_CONTROL_PLANE_EDGE_WIRE_PORT:-19081}:19081" depends_on: postgres: condition: service_healthy @@ -56,16 +56,27 @@ services: timeout: 3s retries: 5 + edge: + build: + context: .. + dockerfile: iop/apps/edge/Dockerfile + restart: unless-stopped + ports: + - "${IOP_EDGE_NODE_BIND:-0.0.0.0}:${IOP_EDGE_NODE_PORT:-19090}:9090" + depends_on: + control-plane: + condition: service_healthy + web: build: context: .. dockerfile: iop/apps/client/Dockerfile args: - IOP_CONTROL_PLANE_HTTP_URL: "http://localhost:${IOP_CONTROL_PLANE_HTTP_PORT:-9080}" - IOP_CONTROL_PLANE_WIRE_URL: "ws://localhost:${IOP_CONTROL_PLANE_WIRE_PORT:-19080}/client" + IOP_CONTROL_PLANE_HTTP_URL: "${IOP_CONTROL_PLANE_HTTP_URL:-http://localhost:9080}" + IOP_CONTROL_PLANE_WIRE_URL: "${IOP_CONTROL_PLANE_WIRE_URL:-ws://localhost:19080/client}" restart: unless-stopped ports: - - "${IOP_WEB_PORT:-3000}:3000" + - "${IOP_WEB_BIND:-0.0.0.0}:${IOP_WEB_PORT:-13000}:3000" depends_on: control-plane: condition: service_healthy diff --git a/packages/flutter/iop_console/build/test_cache/build/99111e0c5b6228829e100ef67db14ea2.cache.dill.track.dill b/packages/flutter/iop_console/build/test_cache/build/99111e0c5b6228829e100ef67db14ea2.cache.dill.track.dill index 9317824cc7b3fceee03a14f1ac0fc3cdb4b8d32e..4ebcab384178ef4263626358930346077a9ba64c 100644 GIT binary patch delta 1954 zcmZw8SNITu0*3MD`&2ZwrIJ-zXhd*b5IJUaEj#M9Fn3bmf|Uqk|~u#Q#xf*Hsw-2 z6;d&WrBV)0HJvDM%YNl3dr%vkT_?(avQ!n+?APsX;8s+3P zPLrIHrfHT_(>$l;^qi41(;_X?Dy`EdZPPC8(;*$xDV@_LXQgY-&N(?Z-O@ehrAK)A zNOt7WJeJ4vM4rr3c{Mk8pYuz8&2RZV2l7Y$%wPFC z|4bGV76*w!qOd3;4i<-qqN126E=q`!qLesPlon+~Sy4`u7ZpTBahRwi4i}Y06;V|j zA*zWZ#ZlsDaf~=tR2MbGaiXTEC2EU0qOLezoFGmV^+bKqKr|F5iALgN(O5JQr--Ja znK)H67pIBS#TnvE(L%Hotwd|lMzj^}M0?RebQGOLXVFERCAx~U#W~_!(M@z0=ZPMo zr|2cl7rn&=qK~*xTqOF6e&S+riRdo|h=Jl#F-Qy+L&Q*VnHVN67sJH}F;ZM1Mv2j4 zj2J7f6jzC>#WmtuF;0vZ*NN-J1Tj(EAZ`>liHMuUByo$FET)L5VwynQDyECu#0)W0 z%o4N395GkS6Z6Fau}~}$i^c8Y4soYgBJL7*i>2Zou}s`6mWvf)rC23ai~GbHu~w`T z>%|7KQEU>M#r@&|@t}A}Y!O?=LhtSH)}Mb@7IHQ|uORiMPc&;$88ccwc-VJ`{VzN8)4giTG4}CO#Km zh%d!nu}^#@z82qzZ^d`wd+~$#QS28#iJ!$U;#cvT_+1cf}Oe1r$X>6L9Q%qCS%$#bPo72qc z<_vSDX<=HLR;IOSW7?W_roHK4I+{+Vv*}{aGF{Et<{Wdb>1Mi{^GpxZ)ATauo8IOE z)5lzBE;4;hKXb9U#Pl}<%s_Lg8Ds{VA!ew#%nUP^o8e}J8ELLCqs(YC#*8&rnybv! z<{ERY8E3|u>&*3Lf|+P;FgKc;Ow7$@lDWl9HdD-0GtFRbHPg*)W`>z*W|`S$j+txb znfYdcS!foS#pZT%hq==%F?X4}%~ErZS!V7v%gqY2(yTJ8&3$H#S!>pr^=5^ldC)v$wwSGEo7wJy0w35}xJUbr-C8aAXJ>&c74F@mRl7Djs=id}Il}bj@Rw<&PU5F$p?Sx9}lhhmSWVN)>GKxRhyJT;& zmA%QxdCt|jI2Z5L?|Jv^{i)KP|1>#@Qz(T~BnPEvilul;(xf+Br7I<@nS|-PFqosh$aJPt!C@^R!6Iv`Xuokv3_Yb~!Wc(;;W&>~zdIIX9isIbG5<=cQY^r$>6G zS9+&U`lesb&jqQxF{hG79~X~QCgG{WkoqrUQ`ejMI}*L93rZSLq%0_n5ZVI ziyGo^afCQh)D%aFTHS=qJt>7l;c*e{qqxSPT%Ch=Jl#F-Tk{28+wZ5HVC-A%=iQ-x@NlX?~#8fd&L|iAPi|fSaih3N%n@_N zJTYG^5DUd3u~^(JmWW%#t>QLuySPIv70bkOu|ljAcZyYFwOAw8igjYW*dXo_cZ++( zMzKk37F)ztaj&>f+%Fyw+r)P9pm<0Wh=;`^VuyHCJSH9&PlzYQQ{rjyjCfW&C!QBC zh!@39u}i!pc8izAE8I^kiMPc&;$88ccwc-VJ`{VzN8)4giTG4}CO#Km zh%d!nu}^#@z82qzZ^d`wd+~$#QT!x+7QcvJ#c$$w@rT$i{uF|f}o06uKDQ(J_vZkCVZz`CIrjn^_4lz~Cp{A-i%v3YgO$~FnIl>%i zYMP@=EpxOv#?&^)n&ZszrjDs=>X{Qvebc}+G$)!y<|K2nImMi68k;8OG;_LXYMPnm zriE!~TA9}74AaK6HSNrqroHK4&N644j^-S5uIXetn=YoSInQ)6-AxbE)ATaEO&`A3AvSn1RCvj#}JmQMrms7t|i)vWs`G*;i^ur+o#UTjF1LLhSAU diff --git a/scripts/dev/web.sh b/scripts/dev/web.sh index 9281408..ae6a3ba 100755 --- a/scripts/dev/web.sh +++ b/scripts/dev/web.sh @@ -6,7 +6,7 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" CLIENT_DIR="$REPO_ROOT/apps/client" WEB_HOST="${IOP_WEB_HOST:-0.0.0.0}" -WEB_PORT="${IOP_WEB_PORT:-3000}" +WEB_PORT="${IOP_WEB_PORT:-13000}" IOP_CONTROL_PLANE_HTTP_URL="${IOP_CONTROL_PLANE_HTTP_URL:-http://localhost:9080}" IOP_CONTROL_PLANE_WIRE_URL="${IOP_CONTROL_PLANE_WIRE_URL:-ws://localhost:19080/client}"