zigrix 0.1.0-alpha.8 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +159 -120
- package/dist/agents/registry.js +19 -2
- package/dist/agents/roles.d.ts +10 -0
- package/dist/agents/roles.js +83 -0
- package/dist/config/defaults.d.ts +88 -6
- package/dist/config/defaults.js +82 -50
- package/dist/config/load.d.ts +5 -3
- package/dist/config/load.js +69 -30
- package/dist/config/schema.d.ts +46 -4
- package/dist/config/schema.js +49 -3
- package/dist/configure.d.ts +2 -0
- package/dist/configure.js +37 -14
- package/dist/dashboard/.next/BUILD_ID +1 -1
- package/dist/dashboard/.next/app-build-manifest.json +13 -13
- package/dist/dashboard/.next/app-path-routes-manifest.json +3 -3
- package/dist/dashboard/.next/build-manifest.json +2 -2
- package/dist/dashboard/.next/prerender-manifest.json +6 -6
- package/dist/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/_not-found.html +1 -1
- package/dist/dashboard/.next/server/app/_not-found.rsc +1 -1
- package/dist/dashboard/.next/server/app/api/auth/login/route.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/logout/route.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/session/route.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/session/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/setup/route.js +1 -1
- package/dist/dashboard/.next/server/app/api/auth/setup/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/overview/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/stream/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/tasks/[taskId]/conversation/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/login.html +1 -1
- package/dist/dashboard/.next/server/app/login.rsc +1 -1
- package/dist/dashboard/.next/server/app/page.js +2 -2
- package/dist/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/dist/dashboard/.next/server/app/setup.html +1 -1
- package/dist/dashboard/.next/server/app/setup.rsc +1 -1
- package/dist/dashboard/.next/server/app-paths-manifest.json +3 -3
- package/dist/dashboard/.next/server/chunks/972.js +1 -1
- package/dist/dashboard/.next/server/functions-config-manifest.json +3 -3
- package/dist/dashboard/.next/server/middleware.js +1 -1
- package/dist/dashboard/.next/server/pages/404.html +1 -1
- package/dist/dashboard/.next/server/pages/500.html +1 -1
- package/dist/dashboard/.next/static/chunks/app/page-0314989c31e18b4b.js +1 -0
- package/dist/dashboard/.next/static/css/{94d75aff24d0c077.css → c3a7306cb2ba3f6c.css} +1 -1
- package/dist/dashboard.js +47 -0
- package/dist/doctor.js +28 -5
- package/dist/index.js +175 -171
- package/dist/onboard.d.ts +76 -2
- package/dist/onboard.js +529 -25
- package/dist/orchestration/dispatch.d.ts +3 -1
- package/dist/orchestration/dispatch.js +173 -45
- package/dist/orchestration/evidence.js +31 -4
- package/dist/orchestration/finalize.d.ts +1 -0
- package/dist/orchestration/finalize.js +5 -3
- package/dist/orchestration/report.js +9 -1
- package/dist/orchestration/worker.d.ts +1 -1
- package/dist/orchestration/worker.js +58 -8
- package/dist/rules/templates.js +3 -6
- package/dist/state/tasks.d.ts +12 -0
- package/dist/state/tasks.js +7 -0
- package/package.json +23 -2
- package/rules/defaults/README.md +9 -9
- package/rules/defaults/{back-zig.md → backend-agent.md} +4 -4
- package/rules/defaults/{front-zig.md → frontend-agent.md} +4 -4
- package/rules/defaults/orchestrator-agent.md +261 -0
- package/rules/defaults/{qa-zig.md → qa-agent.md} +11 -11
- package/rules/defaults/{sec-zig.md → security-agent.md} +4 -4
- package/rules/defaults/{sys-zig.md → system-agent.md} +8 -9
- package/rules/defaults/worker-common.md +25 -19
- package/skills/zigrix-doctor/SKILL.md +4 -2
- package/skills/zigrix-evidence/SKILL.md +7 -3
- package/skills/zigrix-main-agent-guide/SKILL.md +128 -0
- package/skills/zigrix-shared/SKILL.md +27 -3
- package/skills/zigrix-task-create/SKILL.md +8 -2
- package/skills/zigrix-task-status/SKILL.md +5 -2
- package/skills/zigrix-worker/SKILL.md +12 -4
- package/dist/dashboard/.next/static/chunks/app/page-25f54e54e74fb3af.js +0 -1
- package/rules/defaults/pro-zig.md +0 -238
- /package/dist/dashboard/.next/static/{2a4glWei05xr4Jg0Ly6cp → PT4hYxzrqxj-Zq4ZjtKNg}/_buildManifest.js +0 -0
- /package/dist/dashboard/.next/static/{2a4glWei05xr4Jg0Ly6cp → PT4hYxzrqxj-Zq4ZjtKNg}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: zigrix-main-agent-guide
|
|
3
|
+
version: 0.2.0
|
|
4
|
+
description: Main-agent guide for using Zigrix CLI (task issuance, orchestrator spawn, dashboard, and path resolution).
|
|
5
|
+
metadata:
|
|
6
|
+
openclaw:
|
|
7
|
+
requires:
|
|
8
|
+
bins: ["zigrix"]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Zigrix Main Agent Guide
|
|
12
|
+
|
|
13
|
+
메인 에이전트가 Zigrix를 사용할 때의 표준 흐름.
|
|
14
|
+
|
|
15
|
+
## 1) 기본 명령
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# 초기 설정
|
|
19
|
+
zigrix onboard --yes --json
|
|
20
|
+
|
|
21
|
+
# 환경/설정 점검
|
|
22
|
+
zigrix doctor
|
|
23
|
+
zigrix config validate --json
|
|
24
|
+
zigrix agent list --json
|
|
25
|
+
|
|
26
|
+
# 대시보드 실행
|
|
27
|
+
zigrix dashboard --port 5173
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 2) 태스크 발급 흐름 (권장)
|
|
31
|
+
|
|
32
|
+
`task create`보다 `task dispatch`를 우선 사용한다.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
zigrix task dispatch \
|
|
36
|
+
--title "Implement X" \
|
|
37
|
+
--description "..." \
|
|
38
|
+
--scale normal \
|
|
39
|
+
--project-dir /path/to/project \
|
|
40
|
+
--json
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
디스패치 결과에서 확인하고 다음 에이전트에 전달할 핵심 필드:
|
|
44
|
+
- `taskId`
|
|
45
|
+
- `orchestratorId`
|
|
46
|
+
- `qaAgentId`
|
|
47
|
+
- `baselineRequiredAgents`
|
|
48
|
+
- `candidateAgents`
|
|
49
|
+
- `orchestratorPrompt`
|
|
50
|
+
- `specPath` — resolved absolute path to spec markdown
|
|
51
|
+
- `metaPath` — resolved absolute path to metadata JSON
|
|
52
|
+
- `promptPath` — resolved absolute path to dispatch prompt
|
|
53
|
+
- `projectDir` — resolved project directory
|
|
54
|
+
|
|
55
|
+
## 3) 오케스트레이터 spawn 패턴
|
|
56
|
+
|
|
57
|
+
디스패치 응답의 `orchestratorPrompt`를 오케스트레이터 에이전트에게 전달한다.
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
sessions_spawn(
|
|
61
|
+
agentId: <orchestratorId>,
|
|
62
|
+
task: <dispatchResult.orchestratorPrompt>
|
|
63
|
+
)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
오케스트레이터는 이후 워커를 `zigrix worker prepare/register/complete` 체인으로 관리한다.
|
|
67
|
+
|
|
68
|
+
## 4) 워커/검증/최종 보고 체인
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# 워커 준비 (returns promptPath, specPath, metaPath, projectDir)
|
|
72
|
+
zigrix worker prepare --task-id <taskId> --agent-id <agentId> --description "..." --json
|
|
73
|
+
|
|
74
|
+
# 워커 세션 등록
|
|
75
|
+
zigrix worker register --task-id <taskId> --agent-id <agentId> --session-key <sessionKey> --run-id <runId> --json
|
|
76
|
+
|
|
77
|
+
# 워커 완료
|
|
78
|
+
zigrix worker complete --task-id <taskId> --agent-id <agentId> --session-key <sessionKey> --run-id <runId> --json
|
|
79
|
+
|
|
80
|
+
# evidence 수집 (returns evidencePath)
|
|
81
|
+
zigrix evidence collect --task-id <taskId> --agent-id <agentId> --summary "..." --json
|
|
82
|
+
|
|
83
|
+
# evidence 머지 (returns mergedPath)
|
|
84
|
+
zigrix evidence merge --task-id <taskId> --require-qa --json
|
|
85
|
+
|
|
86
|
+
# 최종화
|
|
87
|
+
zigrix task finalize <taskId> --auto-report --json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## 5) 경로 해석이 필요할 때
|
|
91
|
+
|
|
92
|
+
CLI JSON 응답의 resolved path 필드를 우선 사용한다. 런타임 디렉토리만 필요하면:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
zigrix path get tasksDir --json
|
|
96
|
+
zigrix path get workspace.projectsBaseDir --json
|
|
97
|
+
zigrix path list --json
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
bare symbolic key(`paths.tasksDir`, `workspace.projectsBaseDir`)를 파일 경로처럼 직접 쓰지 않는다.
|
|
101
|
+
|
|
102
|
+
## 6) 대시보드 사용 포인트
|
|
103
|
+
|
|
104
|
+
대시보드에서 확인:
|
|
105
|
+
- Task 상태 (OPEN → IN_PROGRESS → REPORTED)
|
|
106
|
+
- 워커 세션 매핑
|
|
107
|
+
- 이벤트 로그
|
|
108
|
+
- Conversation/증적 추적
|
|
109
|
+
|
|
110
|
+
문제 상황 디버깅 순서:
|
|
111
|
+
1. `zigrix task status <taskId> --json`
|
|
112
|
+
2. `zigrix task events <taskId> --json`
|
|
113
|
+
3. `zigrix evidence merge --task-id <taskId> --require-qa --json`
|
|
114
|
+
|
|
115
|
+
## 7) Standard CLI chain
|
|
116
|
+
|
|
117
|
+
| Step | Command | Key resolved path fields |
|
|
118
|
+
|------|---------|--------------------------|
|
|
119
|
+
| Dispatch | `zigrix task dispatch` | `specPath`, `metaPath`, `promptPath`, `projectDir` |
|
|
120
|
+
| Start | `zigrix task start` | |
|
|
121
|
+
| Worker prepare | `zigrix worker prepare` | `promptPath`, `specPath`, `metaPath`, `projectDir` |
|
|
122
|
+
| Worker register | `zigrix worker register` | |
|
|
123
|
+
| Worker complete | `zigrix worker complete` | |
|
|
124
|
+
| Evidence collect | `zigrix evidence collect` | `evidencePath` |
|
|
125
|
+
| Evidence merge | `zigrix evidence merge` | `mergedPath` |
|
|
126
|
+
| Finalize | `zigrix task finalize` | |
|
|
127
|
+
|
|
128
|
+
- JSON 출력(`--json`)을 기본으로 파이프라인에서 파싱
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: zigrix-shared
|
|
3
|
-
version: 0.
|
|
4
|
-
description: Shared guidance for Zigrix CLI usage, output modes, and safety.
|
|
3
|
+
version: 0.3.0
|
|
4
|
+
description: Shared guidance for Zigrix CLI usage, output modes, path resolution, and safety.
|
|
5
5
|
metadata:
|
|
6
6
|
openclaw:
|
|
7
7
|
requires:
|
|
@@ -14,16 +14,40 @@ Use Zigrix for multi-project parallel task orchestration with file-backed, inspe
|
|
|
14
14
|
|
|
15
15
|
## Rules
|
|
16
16
|
- Prefer `--json` for automation-heavy flows.
|
|
17
|
-
- Global state lives in `~/.zigrix/` (override: `ZIGRIX_HOME` env).
|
|
18
17
|
- Tasks are NOT project-bound — one Zigrix instance manages tasks across projects.
|
|
19
18
|
- Do not assume OpenClaw internals are required unless the task explicitly needs them.
|
|
20
19
|
|
|
20
|
+
## Path Resolution Contract
|
|
21
|
+
|
|
22
|
+
Bare symbolic keys like `paths.tasksDir` or `workspace.projectsBaseDir` are **not** auto-expanded variables. They are config key names. To get the actual absolute path, use the following priority:
|
|
23
|
+
|
|
24
|
+
1. **CLI JSON output fields** (preferred — already resolved)
|
|
25
|
+
- `zigrix task dispatch --json` → `specPath`, `metaPath`, `promptPath`, `projectDir`
|
|
26
|
+
- `zigrix task create --json` → `specPath`, `metaPath`, `projectDir`
|
|
27
|
+
- `zigrix task status <taskId> --json` → `specPath`, `metaPath`, `projectDir`
|
|
28
|
+
- `zigrix worker prepare --json` → `promptPath`, `specPath`, `metaPath`, `projectDir`
|
|
29
|
+
- `zigrix evidence collect --json` → `evidencePath`
|
|
30
|
+
- `zigrix evidence merge --json` → `mergedPath`
|
|
31
|
+
|
|
32
|
+
2. **`zigrix path` commands** (for runtime directory lookup)
|
|
33
|
+
```bash
|
|
34
|
+
zigrix path get tasksDir --json # → {"canonicalKey":"paths.tasksDir","value":"/abs/..."}
|
|
35
|
+
zigrix path get evidenceDir --json
|
|
36
|
+
zigrix path get workspace.projectsBaseDir --json
|
|
37
|
+
zigrix path list --json # → all resolved paths
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
3. **`zigrix doctor --json`** (for environment overview including paths)
|
|
41
|
+
|
|
42
|
+
4. **Last resort:** Read `~/.zigrix/zigrix.config.json` and resolve `paths.*` manually.
|
|
43
|
+
|
|
21
44
|
## Common commands
|
|
22
45
|
```bash
|
|
23
46
|
zigrix doctor --json
|
|
24
47
|
zigrix task list --json
|
|
25
48
|
zigrix task dispatch --title "..." --description "..." --scale normal --json
|
|
26
49
|
zigrix task finalize <taskId> --auto-report --json
|
|
50
|
+
zigrix path list --json
|
|
27
51
|
```
|
|
28
52
|
|
|
29
53
|
## Safety
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: zigrix-task-create
|
|
3
|
-
version: 0.
|
|
3
|
+
version: 0.3.0
|
|
4
4
|
description: Create a new Zigrix task with title, description, and scale.
|
|
5
5
|
metadata:
|
|
6
6
|
openclaw:
|
|
@@ -11,7 +11,7 @@ metadata:
|
|
|
11
11
|
|
|
12
12
|
# zigrix task create
|
|
13
13
|
|
|
14
|
-
Create a task
|
|
14
|
+
Create a task record. The JSON output includes resolved absolute paths (`specPath`, `metaPath`, `projectDir`).
|
|
15
15
|
|
|
16
16
|
For full orchestration metadata (work packages, execution units, boot prompt), use `zigrix task dispatch` instead.
|
|
17
17
|
|
|
@@ -31,4 +31,10 @@ zigrix task dispatch \
|
|
|
31
31
|
--json
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
Key JSON output fields for downstream use:
|
|
35
|
+
- `taskId` — the generated task identifier
|
|
36
|
+
- `specPath` — absolute path to the task spec markdown
|
|
37
|
+
- `metaPath` — absolute path to the task metadata JSON
|
|
38
|
+
- `projectDir` — resolved project directory (from `--project-dir` or config default)
|
|
39
|
+
|
|
34
40
|
Prefer `--json` when another agent or script will consume the result.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: zigrix-task-status
|
|
3
|
-
version: 0.
|
|
3
|
+
version: 0.2.0
|
|
4
4
|
description: Inspect Zigrix task records and state transitions.
|
|
5
5
|
metadata:
|
|
6
6
|
openclaw:
|
|
@@ -17,11 +17,14 @@ Use this to inspect one task or list tasks.
|
|
|
17
17
|
zigrix task list --json
|
|
18
18
|
zigrix task status TASK-20260313-001 --json
|
|
19
19
|
zigrix task events TASK-20260313-001 --json
|
|
20
|
-
zigrix task progress --task-id TASK-20260313-001 --actor
|
|
20
|
+
zigrix task progress --task-id TASK-20260313-001 --actor orchestrator-agent --message "진행 상황 요약" --json
|
|
21
21
|
zigrix task stale --hours 24 --json
|
|
22
22
|
zigrix task start TASK-20260313-001
|
|
23
23
|
zigrix task finalize TASK-20260313-001
|
|
24
24
|
zigrix task report TASK-20260313-001
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
`task status --json` returns resolved path fields (`specPath`, `metaPath`, `projectDir`) alongside task metadata.
|
|
28
|
+
Use these fields when absolute file paths are needed; do not construct paths from symbolic config keys.
|
|
29
|
+
|
|
27
30
|
Treat status transitions as explicit lifecycle events.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: zigrix-worker
|
|
3
|
-
version: 0.
|
|
3
|
+
version: 0.3.0
|
|
4
4
|
description: Prepare, register, and complete Zigrix worker runs.
|
|
5
5
|
metadata:
|
|
6
6
|
openclaw:
|
|
@@ -14,9 +14,17 @@ metadata:
|
|
|
14
14
|
Use worker lifecycle commands to bridge agent execution and global orchestration state.
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
zigrix worker prepare --task-id DEV-20260316-001 --agent-id
|
|
18
|
-
zigrix worker register --task-id DEV-20260316-001 --agent-id
|
|
19
|
-
zigrix worker complete --task-id DEV-20260316-001 --agent-id
|
|
17
|
+
zigrix worker prepare --task-id DEV-20260316-001 --agent-id <workerAgentId> --description "Run role-specific checks" --json
|
|
18
|
+
zigrix worker register --task-id DEV-20260316-001 --agent-id <workerAgentId> --session-key agent:test:worker --run-id run-001 --json
|
|
19
|
+
zigrix worker complete --task-id DEV-20260316-001 --agent-id <workerAgentId> --session-key agent:test:worker --run-id run-001 --json
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
Key JSON output fields from `worker prepare`:
|
|
23
|
+
- `promptPath` — absolute path to the generated worker prompt file (the canonical assignment)
|
|
24
|
+
- `specPath` — absolute path to the task spec markdown
|
|
25
|
+
- `metaPath` — absolute path to the task metadata JSON
|
|
26
|
+
- `projectDir` — resolved project directory for the worker to operate in
|
|
27
|
+
|
|
28
|
+
Workers should treat the `promptPath` content as their authoritative assignment. Do not reconstruct task file paths from symbolic config keys.
|
|
29
|
+
|
|
22
30
|
These commands intentionally avoid hard-coding OpenClaw internals into the Zigrix core.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[974],{109:e=>{e.exports={badge:"StatusBadge_badge__M4ZLM",status_OPEN:"StatusBadge_status_OPEN__0Pm_x",status_IN_PROGRESS:"StatusBadge_status_IN_PROGRESS__JhYac",status_BLOCKED:"StatusBadge_status_BLOCKED__8FFag",status_DONE_PENDING_REPORT:"StatusBadge_status_DONE_PENDING_REPORT__yVdnt",status_REPORTED:"StatusBadge_status_REPORTED__0p67U",status_UNKNOWN:"StatusBadge_status_UNKNOWN__VkyXw"}},594:e=>{e.exports={wrap:"ConversationTab_wrap__1QSeD",toggle:"ConversationTab_toggle__3CZ5X",list:"ConversationTab_list__3x9W9",message:"ConversationTab_message__ATEZY",header:"ConversationTab_header__JCM4X",agent:"ConversationTab_agent__y3KdF",meta:"ConversationTab_meta__dMgwn",body:"ConversationTab_body__uCFH9",markdown:"ConversationTab_markdown__A8qFO",thinking:"ConversationTab_thinking__9ksh2",toolBox:"ConversationTab_toolBox__z6pL2",toolName:"ConversationTab_toolName__SLqEU",notice:"ConversationTab_notice__wCw5J",empty:"ConversationTab_empty__aB__j"}},2357:e=>{e.exports={wrap:"EventLogTab_wrap__x2X_J",empty:"EventLogTab_empty__LRJDo",list:"EventLogTab_list__nm_mD",item:"EventLogTab_item__VL0dt",ts:"EventLogTab_ts__vQ9nA",name:"EventLogTab_name__4A39l"}},6143:e=>{e.exports={main:"DashboardClient_main__eZK1S",header:"DashboardClient_header__21U6H",brand:"DashboardClient_brand__1Ljqy",headerRight:"DashboardClient_headerRight__EinuX",sseWrap:"DashboardClient_sseWrap__dCBYi",dot:"DashboardClient_dot__NxKpZ",dot_connected:"DashboardClient_dot_connected__3UnYe",dot_disconnected:"DashboardClient_dot_disconnected__0IqOj",dot_connecting:"DashboardClient_dot_connecting__NNLev",statusBar:"DashboardClient_statusBar__eP3FN",statusItem:"DashboardClient_statusItem__Yi9TP",error:"DashboardClient_error__Tv__n",layout:"DashboardClient_layout__s4BTz",left:"DashboardClient_left__WqNyg",right:"DashboardClient_right__EWclx",tabs:"DashboardClient_tabs__tx3BS",tabActive:"DashboardClient_tabActive__5oF9r",panel:"DashboardClient_panel__bWB7I"}},6297:(e,t,a)=>{Promise.resolve().then(a.bind(a,9181))},6583:e=>{e.exports={wrap:"TaskDetailTab_wrap__dFSwq",empty:"TaskDetailTab_empty__wxQD4",header:"TaskDetailTab_header___564C",badges:"TaskDetailTab_badges__xm9EG",metaRow:"TaskDetailTab_metaRow__OSbDu",cancelButton:"TaskDetailTab_cancelButton__ReU0K",section:"TaskDetailTab_section__4dUxv",muted:"TaskDetailTab_muted__VWQMQ",units:"TaskDetailTab_units__XIBtG",unitCard:"TaskDetailTab_unitCard__jY43J",unitTop:"TaskDetailTab_unitTop__yZ5FK",unitMeta:"TaskDetailTab_unitMeta__LnHSZ",progressTrack:"TaskDetailTab_progressTrack__VlE22",progressFill:"TaskDetailTab_progressFill__JVS7w",evidenceList:"TaskDetailTab_evidenceList__xGfBZ",toggle:"TaskDetailTab_toggle__ujWwI",markdown:"TaskDetailTab_markdown__eoDyT"}},8157:e=>{e.exports={badge:"ScaleBadge_badge__Ufu_B",scale_simple:"ScaleBadge_scale_simple__MbInQ",scale_normal:"ScaleBadge_scale_normal__vPQOk",scale_risky:"ScaleBadge_scale_risky__pWko0",scale_large:"ScaleBadge_scale_large__aXng2",scale_unknown:"ScaleBadge_scale_unknown__gCQWs"}},9181:(e,t,a)=>{"use strict";a.d(t,{DashboardClient:()=>R});var s=a(5155),n=a(2115),l=a(109),i=a.n(l);let r={OPEN:{label:"대기",icon:"\uD83D\uDD35"},IN_PROGRESS:{label:"진행 중",icon:"\uD83D\uDFE0"},BLOCKED:{label:"차단",icon:"\uD83D\uDD34"},DONE_PENDING_REPORT:{label:"보고 대기",icon:"\uD83D\uDFE3"},REPORTED:{label:"보고 완료",icon:"\uD83D\uDFE2"}};function c(e){let{status:t}=e,a=(t||"UNKNOWN").toUpperCase(),n=r[a]||{label:t||"알 수 없음",icon:"⚪"};return(0,s.jsxs)("span",{className:"".concat(i().badge," ").concat(i()["status_".concat(a)]||i().status_UNKNOWN),children:[(0,s.jsx)("span",{"aria-hidden":!0,children:n.icon}),(0,s.jsx)("span",{children:n.label})]})}var o=a(8157),d=a.n(o);let u={simple:"simple",normal:"normal",risky:"risky",large:"large"};function _(e){let{scale:t}=e,a=(t||"unknown").toLowerCase(),n=u[a]||a;return(0,s.jsx)("span",{className:"".concat(d().badge," ").concat(d()["scale_".concat(a)]||d().scale_unknown),children:n})}function h(e){let{value:t}=e,[,a]=(0,n.useReducer)(e=>e+1,0);return(0,n.useEffect)(()=>{let e=setInterval(a,6e4);return()=>clearInterval(e)},[]),(0,s.jsx)("span",{title:t||"",children:function(e){if(!e)return"-";let t=new Date(e).getTime();if(!Number.isFinite(t))return e;let a=Math.floor((Date.now()-t)/1e3);if(a<5)return"방금 전";if(a<60)return"".concat(a,"초 전");let s=Math.floor(a/60);if(s<60)return"".concat(s,"분 전");let n=Math.floor(s/60);if(n<24)return"".concat(n,"시간 전");let l=Math.floor(n/24);return l<30?"".concat(l,"일 전"):new Date(e).toLocaleString("ko-KR")}(t)})}var m=a(9221),p=a.n(m);let x=["ALL","OPEN","IN_PROGRESS","BLOCKED","DONE_PENDING_REPORT","REPORTED"];function v(e){let{tasks:t,selectedTaskId:a,onSelectTask:l}=e,[i,r]=(0,n.useState)("ALL"),[o,d]=(0,n.useState)(""),[u,m]=(0,n.useState)("newest"),[v,g]=(0,n.useState)(1),k=(0,n.useMemo)(()=>{let e=o.trim().toLowerCase();return[...t.filter(t=>("ALL"===i||(t.status||"")===i)&&(!e||[t.taskId,t.title||"",t.actor||""].some(t=>t.toLowerCase().includes(e))))].sort((e,t)=>{if("taskId"===u)return e.taskId.localeCompare(t.taskId);let a=Date.parse(e.updatedAt||"")||0,s=Date.parse(t.updatedAt||"")||0;return"newest"===u?s-a:a-s})},[t,o,u,i]),N=Math.max(1,Math.ceil(k.length/12)),b=Math.min(v,N),j=k.slice((b-1)*12,12*b);return(0,s.jsxs)("section",{className:p().wrap,children:[(0,s.jsxs)("div",{className:p().filters,children:[(0,s.jsx)("div",{className:p().tabs,children:x.map(e=>(0,s.jsx)("button",{type:"button",className:"".concat(p().tab," ").concat(i===e?p().tabActive:""),onClick:()=>{r(e),g(1)},children:e},e))}),(0,s.jsx)("input",{className:p().input,placeholder:"taskId / title / actor 검색",value:o,onChange:e=>{d(e.target.value),g(1)}}),(0,s.jsxs)("select",{className:p().select,value:u,onChange:e=>{m(e.target.value),g(1)},children:[(0,s.jsx)("option",{value:"newest",children:"최신순"}),(0,s.jsx)("option",{value:"oldest",children:"오래된순"}),(0,s.jsx)("option",{value:"taskId",children:"taskId순"})]})]}),(0,s.jsx)("ul",{className:p().list,children:j.map(e=>(0,s.jsx)("li",{children:(0,s.jsxs)("button",{type:"button",className:"".concat(p().card," ").concat(a===e.taskId?p().cardSelected:""),onClick:()=>l(e.taskId),children:[(0,s.jsxs)("div",{className:p().cardTop,children:[(0,s.jsx)("code",{className:p().taskId,children:e.taskId}),(0,s.jsx)(c,{status:e.status})]}),(0,s.jsx)("p",{className:p().title,children:e.title||"(제목 없음)"}),(0,s.jsxs)("div",{className:p().metaRow,children:[(0,s.jsx)(_,{scale:e.scale}),(0,s.jsx)("span",{children:e.actor||"-"}),(0,s.jsx)("span",{className:p().dot,children:"•"}),(0,s.jsx)(h,{value:e.updatedAt})]})]})},e.taskId))}),(0,s.jsxs)("div",{className:p().pagination,children:[(0,s.jsx)("button",{type:"button",disabled:b<=1,onClick:()=>g(e=>Math.max(1,e-1)),children:"이전"}),(0,s.jsxs)("span",{children:[b," / ",N]}),(0,s.jsx)("button",{type:"button",disabled:b>=N,onClick:()=>g(e=>Math.min(N,e+1)),children:"다음"})]})]})}var g=a(856),k=a(6583),N=a.n(k);function b(e){var t,a;let{detail:l,onCancelTask:i,cancelling:r}=e,[o,d]=(0,n.useState)(!1),u=(0,n.useMemo)(()=>{var e,t;let a=null==l||null==(t=l.meta)||null==(e=t.data)?void 0:e.executionUnits;return Array.isArray(a)?a:[]},[l]);if(!l)return(0,s.jsx)("div",{className:N().empty,children:"태스크를 선택해 주세요."});let m=l.task.status,p=(l.spec.preview||"").split(/\r?\n/),x=o?p:p.slice(0,20),v=new Set(l.evidence.agents.map(e=>e.agentId)),k=Array.isArray(null==(t=l.evidence.merged)?void 0:t.requiredAgents)?null==(a=l.evidence.merged)?void 0:a.requiredAgents:Array.from(v);return(0,s.jsxs)("div",{className:N().wrap,children:[(0,s.jsxs)("div",{className:N().header,children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{children:l.task.title||"(제목 없음)"}),(0,s.jsx)("code",{children:l.task.taskId})]}),(0,s.jsxs)("div",{className:N().badges,children:[(0,s.jsx)(c,{status:m}),(0,s.jsx)(_,{scale:l.task.scale})]})]}),(0,s.jsxs)("div",{className:N().metaRow,children:[(0,s.jsxs)("span",{children:["생성: ",(0,s.jsx)(h,{value:l.spec.metadata.createdAt||null})]}),(0,s.jsxs)("span",{children:["업데이트: ",(0,s.jsx)(h,{value:l.task.updatedAt})]})]}),("OPEN"===m||"IN_PROGRESS"===m)&&(0,s.jsx)("button",{type:"button",className:N().cancelButton,onClick:()=>i(l.task.taskId),disabled:r,children:r?"취소 중...":"태스크 취소"}),(0,s.jsxs)("section",{className:N().section,children:[(0,s.jsx)("h4",{children:"Execution Units"}),0===u.length?(0,s.jsx)("p",{className:N().muted,children:"Execution Units 정보가 없습니다."}):(0,s.jsx)("div",{className:N().units,children:u.map((e,t)=>{let a=Array.isArray(e.workPackages)?e.workPackages:[],n=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return e.filter(e=>["DONE","REPORTED","DONE_PENDING_REPORT","COMPLETED"].includes((e.status||"").toUpperCase())).length}(a),l=a.length,i=l>0?Math.round(n/l*100):0;return(0,s.jsxs)("article",{className:N().unitCard,children:[(0,s.jsxs)("div",{className:N().unitTop,children:[(0,s.jsx)("strong",{children:e.title||e.unitId||"Unit ".concat(t+1)}),(0,s.jsx)("span",{children:e.status||"-"})]}),(0,s.jsxs)("div",{className:N().unitMeta,children:[(0,s.jsxs)("span",{children:["unitId: ",e.unitId||"-"]}),(0,s.jsxs)("span",{children:["owner: ",e.owner||e.workerAgent||"-"]}),(0,s.jsxs)("span",{children:[n,"/",l]})]}),(0,s.jsx)("div",{className:N().progressTrack,children:(0,s.jsx)("div",{className:N().progressFill,style:{width:"".concat(i,"%")}})})]},e.unitId||"".concat(e.title||"unit","-").concat(t))})})]}),(0,s.jsxs)("section",{className:N().section,children:[(0,s.jsx)("h4",{children:"Evidence"}),0===k.length?(0,s.jsx)("p",{className:N().muted,children:"증적 제출 정보가 없습니다."}):(0,s.jsx)("ul",{className:N().evidenceList,children:k.map(e=>(0,s.jsxs)("li",{children:[(0,s.jsx)("span",{children:e}),(0,s.jsx)("span",{children:v.has(e)?"제출됨":"미제출"})]},e))})]}),(0,s.jsxs)("section",{className:N().section,children:[(0,s.jsx)("h4",{children:"Spec Preview"}),0===p.length?(0,s.jsx)("p",{className:N().muted,children:"스펙 파일이 없습니다."}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("button",{type:"button",className:N().toggle,onClick:()=>d(e=>!e),children:o?"접기":"펼치기"}),(0,s.jsx)("div",{className:N().markdown,children:(0,s.jsx)(g.oz,{children:x.join("\n")})})]})]})]})}var j=a(2357),T=a.n(j);function y(e){let{events:t}=e,a=(0,n.useRef)(null);return(0,n.useEffect)(()=>{a.current&&(a.current.scrollTop=0)},[t.length]),(0,s.jsx)("div",{ref:a,className:T().wrap,children:0===t.length?(0,s.jsx)("p",{className:T().empty,children:"이벤트가 없습니다."}):(0,s.jsx)("ul",{className:T().list,children:t.map((e,t)=>{let a=e.event||"unknown";return(0,s.jsxs)("li",{className:T().item,children:[(0,s.jsxs)("span",{className:T().ts,children:["[",function(e){if(!e)return"-";let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleTimeString("ko-KR")}(e.ts),"]"]})," ",(0,s.jsx)("span",{className:T().name,children:a})," | ",(0,s.jsxs)("span",{children:["task=",e.taskId||"-"]})," | ",(0,s.jsxs)("span",{children:["status=",e.status||"-"]})," | ","worker_dispatched"===a?(0,s.jsxs)("strong",{children:[e.actor||e.agentId||"-"," → ",e.targetAgent||"-"]}):(0,s.jsxs)("span",{children:["actor=",e.actor||e.agentId||"-"]})]},"".concat(e.ts||"no-ts","-").concat(a,"-").concat(t))})})})}var w=a(594),E=a.n(w);function C(e){let{conversation:t}=e,[a,l]=(0,n.useState)(!1),i=(0,n.useRef)(null);(0,n.useEffect)(()=>{let e=i.current;e&&e.scrollHeight-e.scrollTop-e.clientHeight<200&&(e.scrollTop=e.scrollHeight)},[null==t?void 0:t.stream.length]);let r=(0,n.useMemo)(()=>(null==t?void 0:t.stream)||[],[t]);return t?t.openclawAvailable?(0,s.jsxs)("div",{className:E().wrap,children:[(0,s.jsxs)("label",{className:E().toggle,children:[(0,s.jsx)("input",{type:"checkbox",checked:a,onChange:e=>l(e.target.checked)}),(0,s.jsx)("span",{children:"Debug"})]}),(0,s.jsx)("div",{ref:i,className:E().list,children:r.map((e,t)=>{var n,l;let i=(n=e.content,l=e.toolName,"string"==typeof n?[{type:"text",text:n}]:Array.isArray(n)?n.flatMap(e=>{var t,a,s;if(!e||"object"!=typeof e)return[];let n=String(e.type||"text");return("text"===n||"markdown"===n)&&"string"==typeof e.text?[{type:"text",text:e.text}]:"thinking"===n&&"string"==typeof e.thinking?[{type:"thinking",text:e.thinking}]:("tool_use"===n||"toolCall"===n)&&("string"==typeof e.name||"string"==typeof e.toolName)?[{type:"toolCall",toolName:e.name||e.toolName||l||"tool",text:JSON.stringify(null!=(a=null!=(t=e.input)?t:e.arguments)?a:{},null,2)}]:"tool_result"===n||"toolResult"===n?[{type:"toolResult",toolName:l||"tool",text:"string"==typeof e.content?e.content:JSON.stringify(null!=(s=e.content)?s:e,null,2)}]:"string"==typeof e.text?[{type:"text",text:e.text}]:[{type:"text",text:JSON.stringify(e,null,2)}]}):[{type:"text",text:null==n?"":JSON.stringify(n,null,2)}]),r=function(e){let t=0;for(let a=0;a<e.length;a+=1)t=(t<<5)-t+e.charCodeAt(a);let a=Math.abs(t)%360;return"hsl(".concat(a," 65% 45%)")}(e.agentId||e.agentName||"agent");return(0,s.jsxs)("article",{className:E().message,children:[(0,s.jsxs)("header",{className:E().header,children:[(0,s.jsx)("span",{className:E().agent,style:{backgroundColor:r},children:e.agentName||e.agentId}),(0,s.jsx)("span",{className:E().meta,children:e.role||"unknown"}),(0,s.jsx)("span",{className:E().meta,children:e.ts?new Date(e.ts).toLocaleTimeString("ko-KR"):"-"})]}),(0,s.jsx)("div",{className:E().body,children:i.filter(t=>{var s;return s=e.role,"text"===t.type?"assistant"===s||"user"===s:a}).map((e,t)=>"thinking"===e.type?(0,s.jsxs)("details",{className:E().thinking,children:[(0,s.jsx)("summary",{children:"thinking"}),(0,s.jsx)("pre",{children:e.text})]},t):"toolCall"===e.type||"toolResult"===e.type?(0,s.jsxs)("div",{className:E().toolBox,children:[(0,s.jsxs)("span",{className:E().toolName,children:[e.type,": ",e.toolName]}),(0,s.jsx)("pre",{children:e.text})]},t):(0,s.jsx)("div",{className:E().markdown,children:(0,s.jsx)(g.oz,{children:e.text||""})},t))})]},"".concat(e.sessionKey,"-").concat(e.timestamp||t))})})]}):(0,s.jsx)("div",{className:E().notice,children:"OpenClaw 연동 필요"}):(0,s.jsx)("div",{className:E().empty,children:"태스크를 선택해 주세요."})}var f=a(6143),D=a.n(f);let S=["OPEN","IN_PROGRESS","BLOCKED","DONE_PENDING_REPORT","REPORTED"];async function I(e,t){let a=await fetch(e,{...t,cache:"no-store"});if(!a.ok){let e=await a.json().catch(()=>({}));throw Error("string"==typeof(null==e?void 0:e.error)?e.error:"HTTP ".concat(a.status))}return await a.json()}function R(e){var t;let{initialOverview:a,initialTaskDetail:l,initialConversation:i,initialSelectedTaskId:r}=e,[c,o]=(0,n.useState)(a),[d,u]=(0,n.useState)(r),[_,h]=(0,n.useState)(l),[m,p]=(0,n.useState)(i),[x,g]=(0,n.useState)("detail"),[k,N]=(0,n.useState)("connecting"),[j,T]=(0,n.useState)(!1),[w,E]=(0,n.useState)(null),[f,R]=(0,n.useState)(!1),O=(0,n.useRef)((null==(t=a.recentEvents[0])?void 0:t.ts)||null),L=(0,n.useRef)(null),P=(0,n.useRef)(null),A=(0,n.useMemo)(()=>{let e=new Map(c.activeTasks.map(e=>[e.taskId,e]));return Array.from(new Set([...c.taskHistory.map(e=>e.taskId),...c.activeTasks.map(e=>e.taskId)])).map(t=>{let a=c.taskHistory.find(e=>e.taskId===t),s=e.get(t);return{taskId:t,status:(null==a?void 0:a.status)||(null==s?void 0:s.status)||null,title:(null==s?void 0:s.title)||null,scale:(null==a?void 0:a.scale)||(null==s?void 0:s.scale)||null,actor:(null==a?void 0:a.actor)||null,updatedAt:(null==a?void 0:a.ts)||(null==s?void 0:s.updatedAt)||null}})},[c]),B=(0,n.useCallback)(async e=>{let[t,a]=await Promise.all([I("/api/tasks/".concat(encodeURIComponent(e))),I("/api/tasks/".concat(encodeURIComponent(e),"/conversation"))]);h(t),p(a)},[]),M=(0,n.useCallback)(async()=>{T(!0),E(null);try{var e,t;let a=await I("/api/overview");o(a);let s=(null==(e=a.recentEvents[0])?void 0:e.ts)||null;s&&(O.current=s);let n=d||(null==(t=a.taskHistory[0])?void 0:t.taskId)||null;n&&(u(n),await B(n))}catch(e){E(e.message||"새로고침 실패")}finally{T(!1)}},[B,d]),U=(0,n.useCallback)(async()=>{await fetch("/api/auth/logout",{method:"POST"}),window.location.href="/login"},[]),K=(0,n.useCallback)(async e=>{try{R(!0),E(null),await I("/api/tasks/".concat(encodeURIComponent(e),"/cancel"),{method:"POST"}),await M()}catch(e){E(e.message||"태스크 취소 실패")}finally{R(!1)}},[M]);return(0,n.useEffect)(()=>{d&&B(d).catch(e=>{E(e.message||"태스크 로딩 실패")})},[B,d]),(0,n.useEffect)(()=>{let e=!1,t=()=>{if(e)return;N("connecting");let a=new URLSearchParams;d&&a.set("taskId",d),O.current&&a.set("lastEventTs",O.current);let s=new EventSource("/api/stream".concat(a.toString()?"?".concat(a.toString()):""));P.current=s,s.onopen=()=>N("connected"),s.addEventListener("update",e=>{let t=JSON.parse(e.data);if(t.ts&&(O.current=t.ts),t.overview){var a,s;o(t.overview),!d&&(null==(a=t.overview.taskHistory[0])?void 0:a.taskId)&&u(t.overview.taskHistory[0].taskId);let e=null==(s=t.overview.recentEvents[0])?void 0:s.ts;e&&(O.current=e)}}),s.addEventListener("event_update",e=>{let t=JSON.parse(e.data);t.ts&&(O.current=t.ts),o(e=>({...e,recentEvents:t.recentEvents||e.recentEvents,taskHistory:t.taskHistory||e.taskHistory,bucketCounts:t.bucketCounts||e.bucketCounts}))}),s.addEventListener("task_detail_update",e=>{let t=JSON.parse(e.data);t.ts&&(O.current=t.ts),t.taskId&&t.taskId===d&&t.detail&&h(t.detail)}),s.addEventListener("conversation_update",e=>{let t=JSON.parse(e.data);t.ts&&(O.current=t.ts),t.taskId&&t.taskId===d&&p(e=>{var a,s;return{generatedAt:new Date().toISOString(),taskId:t.taskId||d,sessionKeys:t.sessionKeys||(null==e?void 0:e.sessionKeys)||[],stream:t.stream||(null==e?void 0:e.stream)||[],recentEvents:t.recentEvents||(null==e?void 0:e.recentEvents)||[],sessions:(null==e?void 0:e.sessions)||[],openclawAvailable:null!=(s=null!=(a=t.openclawAvailable)?a:null==e?void 0:e.openclawAvailable)&&s}})}),s.onerror=()=>{N("disconnected"),s.close(),L.current&&clearTimeout(L.current),L.current=setTimeout(t,1500)}};return t(),()=>{e=!0,L.current&&clearTimeout(L.current),P.current&&P.current.close()}},[d]),(0,s.jsxs)("main",{className:D().main,children:[(0,s.jsxs)("header",{className:D().header,children:[(0,s.jsx)("div",{className:D().brand,children:"Zigrix"}),(0,s.jsxs)("div",{className:D().headerRight,children:[(0,s.jsxs)("div",{className:D().sseWrap,children:[(0,s.jsx)("span",{className:"".concat(D().dot," ").concat(D()["dot_".concat(k)])}),(0,s.jsx)("span",{children:k})]}),(0,s.jsx)("button",{type:"button",onClick:()=>void M(),disabled:j,children:"새로고침"}),(0,s.jsx)("button",{type:"button",onClick:()=>void U(),children:"로그아웃"})]})]}),(0,s.jsx)("div",{className:D().statusBar,children:S.map(e=>(0,s.jsxs)("span",{className:D().statusItem,children:[e," (",c.bucketCounts[e]||0,")"]},e))}),w?(0,s.jsx)("p",{className:D().error,children:w}):null,(0,s.jsxs)("section",{className:D().layout,children:[(0,s.jsx)("aside",{className:D().left,children:(0,s.jsx)(v,{tasks:A,selectedTaskId:d,onSelectTask:u})}),(0,s.jsxs)("section",{className:D().right,children:[(0,s.jsxs)("nav",{className:D().tabs,children:[(0,s.jsx)("button",{type:"button",className:"detail"===x?D().tabActive:"",onClick:()=>g("detail"),children:"태스크 상세"}),(0,s.jsx)("button",{type:"button",className:"events"===x?D().tabActive:"",onClick:()=>g("events"),children:"이벤트 로그"}),(0,s.jsx)("button",{type:"button",className:"conversation"===x?D().tabActive:"",onClick:()=>g("conversation"),children:"대화 내역"})]}),(0,s.jsxs)("div",{className:D().panel,children:["detail"===x&&(0,s.jsx)(b,{detail:_,onCancelTask:K,cancelling:f}),"events"===x&&(0,s.jsx)(y,{events:c.recentEvents}),"conversation"===x&&(0,s.jsx)(C,{conversation:m})]})]})]})]})}},9221:e=>{e.exports={wrap:"TaskList_wrap__JJmVD",filters:"TaskList_filters__P_eut",tabs:"TaskList_tabs__MrUoG",tab:"TaskList_tab__PJ3u6",tabActive:"TaskList_tabActive__hqEIw",input:"TaskList_input__069mt",select:"TaskList_select__07ygx",list:"TaskList_list__zaHPI",card:"TaskList_card__UWMn4",cardSelected:"TaskList_cardSelected__e4ZHd",cardTop:"TaskList_cardTop__ogfsJ",taskId:"TaskList_taskId__RiYub",title:"TaskList_title__BjaLg",metaRow:"TaskList_metaRow__zxzxl",dot:"TaskList_dot__zkHSK",pagination:"TaskList_pagination__3aWZh"}}},e=>{e.O(0,[963,856,441,255,358],()=>e(e.s=6297)),_N_E=e.O()}]);
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
# pro-zig Rules (Orchestrator)
|
|
2
|
-
|
|
3
|
-
> pro-zig는 오케스트레이터로서 worker-common이 아닌 자체 규칙을 따른다.
|
|
4
|
-
|
|
5
|
-
## 1) Mission
|
|
6
|
-
- 사용자 개발 요청을 `simple|normal|risky|large`로 분류하고,
|
|
7
|
-
- 필수 에이전트에게 작업을 분배하고,
|
|
8
|
-
- 작업 증적(task/session/run)을 수집/검증한 뒤,
|
|
9
|
-
- QA 게이트 통과 시에만 최종 보고한다.
|
|
10
|
-
|
|
11
|
-
## 2) Hard Rules
|
|
12
|
-
1. 시작 전에 반드시 `taskId` 생성
|
|
13
|
-
2. 시작 전에 반드시 scale 분류 + 근거 기록
|
|
14
|
-
3. **명세문서 경로 고정:** `orchestration/tasks/<taskId>.md`
|
|
15
|
-
4. **normal|risky|large는 명세문서 미작성 시 진행 금지**
|
|
16
|
-
5. simple은 요약형 spec 허용(동일 경로 파일 사용)
|
|
17
|
-
6. 기계용 메타데이터는 `orchestration/tasks/<taskId>.meta.json`을 우선 신뢰
|
|
18
|
-
7. scale별 필수 참여 에이전트 누락 금지
|
|
19
|
-
7. `qa-zig`는 모든 scale에서 필수
|
|
20
|
-
8. 증적 없는 완료 보고 금지 (`sessionKey`, `runId` 필수)
|
|
21
|
-
9. 작업 중단 시 `nextAction`/`resumeHint` 업데이트 필수
|
|
22
|
-
10. **배포 순서 고정 (Hard Rule):** 코드 수정 → QA → QA 통과 확인 → 배포. 배포 후 QA 금지.
|
|
23
|
-
11. **오케스트레이션 파이프라인 필수 경유 (이후락 고정, 2026-03-04):**
|
|
24
|
-
- 작업은 메인(지그)이 `dev_dispatch.py`로 등록한 상태에서만 수신
|
|
25
|
-
- 오케스트레이션 미등록(taskId/spec 미존재) 작업은 수행 거부
|
|
26
|
-
12. **스크립트 체인 워크플로우 (필수, 2026-03-11):**
|
|
27
|
-
- pro-zig의 task prompt(boot prompt)는 **`dev_start.py` 실행 지시**만 포함한다.
|
|
28
|
-
- **dev_start.py 출력이 태스크 브리핑이자 작업 지시서**이다.
|
|
29
|
-
- 모든 상태 추적은 스크립트 체인을 통해 자동 기록된다.
|
|
30
|
-
- **스크립트를 건너뛰면 다음 지시를 받을 수 없다.**
|
|
31
|
-
- 아래 체인을 순서대로 따른다:
|
|
32
|
-
1. **착수:** `dev_start.py --task-id <taskId>` → 브리핑 + 워커 절차 출력
|
|
33
|
-
2. **워커 prompt 생성:** `orch_prepare_worker.py --task-id <taskId> --agent-id <workerId> --description "..."` → sessions_spawn에 전달할 prompt 출력
|
|
34
|
-
3. **워커 등록:** `orch_register_worker.py --task-id <taskId> --agent-id <workerId> --session-key <key> --run-id <rid>` → 다음 행동 출력
|
|
35
|
-
4. **워커 완료:** `orch_complete_worker.py --task-id <taskId> --agent-id <workerId> --session-key <key> --run-id <rid>` → 완료 여부 + 다음 행동 출력
|
|
36
|
-
5. **최종 보고:** `dev_finalize.py --task-id <taskId> --auto-report`
|
|
37
|
-
- 스크립트 경로: `/Users/janos/.openclaw/workspace/orchestration/scripts/`
|
|
38
|
-
- **구 worker lifecycle 스크립트(`dev_worker_dispatch.py`, `dev_worker_start.py`, `dev_worker_done.py`)는 제거됨.** worker 추적은 `orch_prepare_worker.py → orch_register_worker.py → orch_complete_worker.py` 체인만 사용한다.
|
|
39
|
-
13. task는 크게 유지하고 내부 실행은 `workPackages[]` + `executionUnits[]`로 세분화한다.
|
|
40
|
-
14. execution unit를 실제로 시작할 때는 `orch_prepare_worker.py`에 `--unit-id`를 넘겨 `unit_started` + meta status 전이를 남긴다.
|
|
41
|
-
15. execution unit 완료 시 `orch_complete_worker.py`에 같은 `--unit-id`를 넘겨 `unit_done` + evidence(unitId 포함)를 남긴다.
|
|
42
|
-
16. finalize 전 `executionUnits[].status`가 전부 `DONE`인지 확인해야 하며, 미완료 unit이 있으면 완료 보고 금지.
|
|
43
|
-
17. 중단 복구 판단은 session 문맥이 아니라 `meta.json.executionUnits[]`를 우선한다.
|
|
44
|
-
18. **Git Workflow Policy 준수 (2026-03-17):** 프로젝트 작업 시 `/Users/janos/.openclaw/public-knowledge/policies/git-workflow.md`를 반드시 따른다. GitHub 원격 저장소가 연결된 프로젝트는 기본 브랜치에서 직접 작업/commit/push 하지 않고, 신규 브랜치에서 작업 후 commit + PR까지를 기본 완료선으로 삼는다.
|
|
45
|
-
19. **상태 불변성 하드가드 (2026-03-17):** `/Users/janos/.openclaw/public-knowledge/policies/task-status-policy.md`를 따른다. task가 `REPORTED`가 된 이후에는 어떤 후속 completion/event가 와도 상태를 `DONE_PENDING_REPORT`/`IN_PROGRESS`/`BLOCKED`로 되돌리지 않는다. `REPORTED`는 terminal state이며, 후행 이벤트는 NO-OP(로그만) 처리한다.
|
|
46
|
-
20. **Git 워크플로우 완료 게이트 (2026-03-17):** GitHub 원격 저장소가 있는 프로젝트는 최종 완료(`REPORTED`) 전에 반드시 아래를 만족해야 한다. 하나라도 불충족이면 완료 보고 금지.
|
|
47
|
-
- 작업 브랜치가 `main/master`가 아닐 것
|
|
48
|
-
- 작업 커밋이 원격에 push되어 있을 것
|
|
49
|
-
- PR URL이 존재할 것(OPEN 또는 MERGED)
|
|
50
|
-
- PR/브랜치 근거를 최종 보고 본문에 포함할 것
|
|
51
|
-
|
|
52
|
-
## 3) Scale Matrix
|
|
53
|
-
|
|
54
|
-
### 고정 필수 에이전트
|
|
55
|
-
| Scale | 필수 |
|
|
56
|
-
|-------|------|
|
|
57
|
-
| simple | `pro-zig`, `qa-zig` |
|
|
58
|
-
| normal | `pro-zig`, `qa-zig` + 아래 선택 규칙 적용 |
|
|
59
|
-
| risky | `pro-zig`, `sec-zig`, `qa-zig` + 아래 선택 규칙 적용 |
|
|
60
|
-
| large | `pro-zig`, `sys-zig`, `sec-zig`, `qa-zig` + 아래 선택 규칙 적용 |
|
|
61
|
-
|
|
62
|
-
### 선택적 에이전트 호출 규칙 (normal 이상)
|
|
63
|
-
|
|
64
|
-
**front-zig 호출 조건** (하나라도 해당하면 호출)
|
|
65
|
-
- UI 컴포넌트, 화면, 스타일 변경 포함
|
|
66
|
-
- 프론트엔드 라이브러리 추가/변경
|
|
67
|
-
- API 연동 레이어(프론트 측) 변경
|
|
68
|
-
|
|
69
|
-
**back-zig 호출 조건** (하나라도 해당하면 호출)
|
|
70
|
-
- API 엔드포인트 추가/변경
|
|
71
|
-
- DB 스키마 또는 쿼리 변경
|
|
72
|
-
- 서버 사이드 로직/비즈니스 로직 변경
|
|
73
|
-
- 백그라운드 잡, 큐, 스케줄러 변경
|
|
74
|
-
|
|
75
|
-
**sys-zig 호출 조건** — `sys-zig.md` 호출 기준 참조
|
|
76
|
-
- normal 이상에서 새 기술 스택 도입, 모듈 신설, 아키텍처 변경 등 해당 시
|
|
77
|
-
- risky/large는 무조건 호출
|
|
78
|
-
|
|
79
|
-
> pro-zig는 태스크 내용을 보고 각 에이전트 호출 여부를 판단한다.
|
|
80
|
-
> 판단 근거를 `tasks.jsonl`의 `worker_dispatched` 이벤트에 기록한다.
|
|
81
|
-
> "프론트만 건드는 버그픽스"에 back-zig 호출 금지. "백엔드 전용 API 추가"에 front-zig 호출 금지.
|
|
82
|
-
|
|
83
|
-
## 4) Required Inputs
|
|
84
|
-
- taskId
|
|
85
|
-
- 사용자 목표/범위/완료조건
|
|
86
|
-
- 현재 제약(시간, 리스크, 배포 여부)
|
|
87
|
-
- 기존 관련 task/session context
|
|
88
|
-
|
|
89
|
-
## 4-1) 워커 spawn 및 세션 종료 규칙 (필수, 2026-03-11)
|
|
90
|
-
|
|
91
|
-
> 당분간 pro-zig는 main에 의해 `mode: "run"`으로 spawn된다.
|
|
92
|
-
> session 모드 제약/불안정성 해결 전까지 이를 임시 표준으로 사용한다.
|
|
93
|
-
|
|
94
|
-
### 워커 spawn 규칙 (Hard Rule)
|
|
95
|
-
워커 spawn 시 아래 **5가지를 반드시 준수**한다. 하나라도 누락 시 즉시 실패 처리.
|
|
96
|
-
|
|
97
|
-
1. **agentId 필수** — §5-1 매핑 테이블에 따라 역할에 맞는 agentId 지정
|
|
98
|
-
2. **label 필수** — `[agentId] <taskId>` 형식 (예: `[front-zig] DEV-20260311-007`)
|
|
99
|
-
3. **cwd 필수** — meta.json의 `projectPath` 절대경로 지정. 경로를 모르면 `memory_search("프로젝트 경로")`로 조회.
|
|
100
|
-
4. **mode 생략 (= run)** — 워커는 반드시 `mode: "run"`. session 금지.
|
|
101
|
-
5. **model 생략** — openclaw.json의 `agents.list[].model` 자동 적용. 임의 지정 금지.
|
|
102
|
-
|
|
103
|
-
```
|
|
104
|
-
❌ sessions_spawn(task="...") — agentId/label 누락
|
|
105
|
-
❌ sessions_spawn(agentId="front-zig", mode="session", ...) — 워커 session 금지
|
|
106
|
-
❌ sessions_spawn(agentId="front-zig", model="...", ...) — 모델 임의 지정 금지
|
|
107
|
-
❌ sessions_spawn(agentId="front-zig", label="...", task="...") — cwd 누락
|
|
108
|
-
✅ sessions_spawn(agentId="front-zig", label="[front-zig] DEV-20260311-007", cwd="<meta.json의 projectPath>", task="...")
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### 완료 후 종료 절차 (Hard Rule)
|
|
112
|
-
1. `dev_finalize.py --auto-report` 실행
|
|
113
|
-
2. 스크립트 출력의 `nextAction`에 따라 main 세션에 결과 전달:
|
|
114
|
-
`sessions_send(sessionKey: "agent:main:main", message: "<taskId> 완료: <요약>")`
|
|
115
|
-
3. 결과 전달 후 **더 이상 응답하지 않는다** (세션 종료 대기)
|
|
116
|
-
|
|
117
|
-
⚠️ main에 결과를 전달하지 않으면 이후락에게 완료 보고가 안 된다.
|
|
118
|
-
⚠️ finalize 없이 세션을 종료하면 태스크가 IN_PROGRESS로 방치된다.
|
|
119
|
-
|
|
120
|
-
## 5) Dispatch Contract
|
|
121
|
-
각 워커 호출 시 아래 정보를 반드시 포함:
|
|
122
|
-
- taskId
|
|
123
|
-
- 역할별 목표
|
|
124
|
-
- 산출물 형식(코드/문서/체크리스트)
|
|
125
|
-
- 완료 기준(Definition of Done)
|
|
126
|
-
- 금지사항/제약
|
|
127
|
-
|
|
128
|
-
### 5-1) agentId 고정 매핑 (Hard Rule)
|
|
129
|
-
워커 spawn 시 `agentId`를 반드시 명시한다. 누락 또는 불일치 시 즉시 실패 처리 (fallback 금지).
|
|
130
|
-
|
|
131
|
-
| 역할 | agentId |
|
|
132
|
-
|------|---------|
|
|
133
|
-
| 프론트엔드 | `front-zig` |
|
|
134
|
-
| 백엔드 | `back-zig` |
|
|
135
|
-
| 시스템/인프라 | `sys-zig` |
|
|
136
|
-
| 보안 | `sec-zig` |
|
|
137
|
-
| QA | `qa-zig` |
|
|
138
|
-
| 오케스트레이터 자신 | `pro-zig` |
|
|
139
|
-
|
|
140
|
-
```
|
|
141
|
-
❌ sessions_spawn(task="...") — agentId 누락 → 실패
|
|
142
|
-
✅ sessions_spawn(agentId="back-zig", task="...")
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### 5-2) label 규칙 (Hard Rule)
|
|
146
|
-
태스크 관련 spawn 시 `label` 필수: `[agentId] taskId` 형식
|
|
147
|
-
|
|
148
|
-
```
|
|
149
|
-
❌ sessions_spawn(agentId="front-zig", task="...") — label 누락 → 실패
|
|
150
|
-
✅ sessions_spawn(agentId="front-zig", label="[front-zig] DEV-20260305-007", task="...")
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
- label 없이 spawn하면 대시보드 카드 매핑 오류 발생
|
|
154
|
-
- 태스크 무관 spawn(탐색, 리서치 등)은 label 생략 가능
|
|
155
|
-
|
|
156
|
-
### 5-3) 모델 지정 규칙 (Hard Rule)
|
|
157
|
-
워커 spawn 시 `model` 파라미터를 **지정하지 않는다.** OpenClaw가 `openclaw.json`의 `agents.list[].model`을 자동 적용한다.
|
|
158
|
-
|
|
159
|
-
```
|
|
160
|
-
❌ sessions_spawn(agentId="front-zig", model="some-model", task="...") — 임의 모델 지정 금지
|
|
161
|
-
✅ sessions_spawn(agentId="front-zig", task="...") — openclaw.json 설정 자동 적용
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
- 모델 변경이 필요하면 `openclaw.json`의 `agents.list[].model`을 수정할 것
|
|
165
|
-
- rules에 모델명을 하드코딩하지 말 것 (sync 불일치 위험)
|
|
166
|
-
|
|
167
|
-
### 5-4) 프로젝트 디렉토리 명명 규칙 (Hard Rule)
|
|
168
|
-
`orchestration/tasks/`의 taskId 파일명은 기존대로 유지한다.
|
|
169
|
-
`workspace-pro-zig/projects/` 하위에 생성하는 프로젝트 디렉토리는 **의미있는 kebab-case 이름**을 우선 사용한다.
|
|
170
|
-
|
|
171
|
-
- 사용자 요청의 핵심 키워드를 반영한 kebab-case 이름 사용
|
|
172
|
-
- 예) `portfolio-owen`, `svg-playground`, `crm-dashboard`
|
|
173
|
-
- 의미있는 이름을 지정하기 어려운 경우 **taskId를 폴더명으로 사용** (예: `DEV-20260309-001/`)
|
|
174
|
-
- **taskId ↔ 프로젝트명 매핑은 반드시 `orchestration/tasks/<taskId>.md` 내 `projectDir` 필드에 기록**
|
|
175
|
-
|
|
176
|
-
```
|
|
177
|
-
✅ workspace-pro-zig/projects/portfolio-owen/ — 의미있는 이름 (우선)
|
|
178
|
-
✅ workspace-pro-zig/projects/DEV-20260309-001/ — 명명 어려울 때 taskId 허용
|
|
179
|
-
orchestration/tasks/DEV-20260309-001.md 내: projectDir: portfolio-owen 또는 DEV-20260309-001
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
## 6) Tracking Update Contract
|
|
183
|
-
분배/완료/차단 이벤트마다 업데이트:
|
|
184
|
-
- `orchestration/tasks.jsonl` (append)
|
|
185
|
-
- `orchestration/index.json` (current state)
|
|
186
|
-
- `orchestration/tasks/<taskId>.md` (detail)
|
|
187
|
-
|
|
188
|
-
## 7) Completion Gate
|
|
189
|
-
최종 보고 전 체크:
|
|
190
|
-
- [ ] 필수 워커 전원 DONE
|
|
191
|
-
- [ ] QA 결과 존재 + 회귀 체크 결과 존재
|
|
192
|
-
- [ ] BLOCKED 이슈 해소 또는 명시적 보고
|
|
193
|
-
- [ ] nextAction(후속 작업) 기록
|
|
194
|
-
- [ ] Git 원격 프로젝트인 경우 브랜치/PR 게이트 통과 (`main/master 직접 작업 금지`, `PR URL 존재`, `push 확인`)
|
|
195
|
-
|
|
196
|
-
### Final Decision Rule
|
|
197
|
-
- 보안/QA 이슈가 없으면 pro-zig가 최종 완료(`REPORTED`) 확정
|
|
198
|
-
- 보안/QA 이슈가 있으면 사용자 컨펌 전 완료 확정 금지
|
|
199
|
-
- `owner_confirmation_required` 이벤트 기록
|
|
200
|
-
- 상태는 `DONE_PENDING_REPORT` 또는 `BLOCKED` 유지
|
|
201
|
-
|
|
202
|
-
## 8) Recovery Protocol
|
|
203
|
-
1. `index.json`의 `activeTasks` 확인
|
|
204
|
-
2. `tasks/<taskId>.md`의 `nextAction`, `resumeHint` 확인
|
|
205
|
-
3. `tasks/<taskId>.meta.json`의 `workPackages[]`, `executionUnits[]` 확인
|
|
206
|
-
4. `sessions_history(...)`로 마지막 컨텍스트 복원
|
|
207
|
-
4. 같은 `taskId`로 재개, 새 runId 발급
|
|
208
|
-
5. `tasks.jsonl`에 `task_resumed` 기록
|
|
209
|
-
|
|
210
|
-
## 9) Git/배포 정책 (업데이트, 2026-03-17)
|
|
211
|
-
- 프로젝트 작업 시 `/Users/janos/.openclaw/public-knowledge/policies/git-workflow.md`를 우선 따른다.
|
|
212
|
-
- **GitHub 원격 저장소가 연결된 프로젝트**는 기본 브랜치 직접 작업/commit/push 금지.
|
|
213
|
-
- 해당 경우 기본 흐름은: 브랜치 생성 → 작업 → commit → 원격 branch push → PR 생성.
|
|
214
|
-
- 사용자의 **명시 지시 없이는** main 직접 merge, 자동 배포, 즉시 배포를 진행하지 않는다.
|
|
215
|
-
- **GitHub 원격 저장소가 없는 프로젝트**는 브랜치 생성 → 작업 → commit → 로컬 merge를 기본으로 한다.
|
|
216
|
-
- **커밋 메시지 형식:** `feat/fix/docs/chore: 변경 의도 요약\n\n<taskId>`
|
|
217
|
-
|
|
218
|
-
## 10) Output Template (to User)
|
|
219
|
-
- 작업유형: `simple|normal|risky|large`
|
|
220
|
-
- 진행 요약 (1~3줄)
|
|
221
|
-
- 에이전트별 수행 내역
|
|
222
|
-
- QA 결과
|
|
223
|
-
- 남은 리스크/후속 액션
|
|
224
|
-
- 피드백 요청
|
|
225
|
-
- 가능하면 `python3 /Users/janos/.openclaw/workspace/orchestration/scripts/dev_report_to_user.py --task-id <taskId> --record-events` 출력문을 그대로 사용
|
|
226
|
-
|
|
227
|
-
## 11) Final Feedback Step (필수)
|
|
228
|
-
- finalize 직후, 메인 내부 보고가 아니라 **사용자에게 직접 최종 보고**한다.
|
|
229
|
-
- 권장 순서:
|
|
230
|
-
1) `dev_finalize.py --task-id ... --evidence ... --auto-report`
|
|
231
|
-
2) `python3 /Users/janos/.openclaw/workspace/orchestration/scripts/dev_report_to_user.py --task-id <taskId> --record-events`
|
|
232
|
-
3) 출력된 보고문을 그대로 사용자에게 전달
|
|
233
|
-
- 최종 보고 직후 아래 질문으로 피드백을 요청한다.
|
|
234
|
-
1) 만족도(1~5)
|
|
235
|
-
2) 좋았던 점
|
|
236
|
-
3) 개선할 점
|
|
237
|
-
- `tasks.jsonl`에 `feedback_requested` 이벤트를 남긴다.
|
|
238
|
-
- 피드백을 받으면 `feedback_received` 이벤트를 남기고, 개선 요청은 후속 task로 연결한다.
|
|
File without changes
|
/package/dist/dashboard/.next/static/{2a4glWei05xr4Jg0Ly6cp → PT4hYxzrqxj-Zq4ZjtKNg}/_ssgManifest.js
RENAMED
|
File without changes
|