deuk-agent-flow 4.0.19
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/CHANGELOG.ko.md +223 -0
- package/CHANGELOG.md +227 -0
- package/LICENSE +184 -0
- package/README.ko.md +282 -0
- package/README.md +270 -0
- package/bin/deuk-agent-flow.js +50 -0
- package/bin/deuk-agent-rule.js +2 -0
- package/core-rules/AGENTS.md +153 -0
- package/core-rules/GEMINI.md +7 -0
- package/docs/architecture.ko.md +34 -0
- package/docs/architecture.md +33 -0
- package/docs/assets/architecture-v3.png +0 -0
- package/docs/how-it-works.ko.md +52 -0
- package/docs/how-it-works.md +71 -0
- package/docs/principles.ko.md +68 -0
- package/docs/principles.md +68 -0
- package/docs/usage-guide.ko.md +212 -0
- package/package.json +96 -0
- package/scripts/cli-args.mjs +200 -0
- package/scripts/cli-init-commands.mjs +1799 -0
- package/scripts/cli-init-logic.mjs +64 -0
- package/scripts/cli-prompts.mjs +104 -0
- package/scripts/cli-rule-compiler.mjs +112 -0
- package/scripts/cli-skill-commands.mjs +201 -0
- package/scripts/cli-telemetry-commands.mjs +599 -0
- package/scripts/cli-ticket-commands.mjs +2393 -0
- package/scripts/cli-ticket-index.mjs +298 -0
- package/scripts/cli-ticket-migration.mjs +320 -0
- package/scripts/cli-ticket-parser.mjs +209 -0
- package/scripts/cli-usage-commands.mjs +326 -0
- package/scripts/cli-utils.mjs +587 -0
- package/scripts/cli.mjs +246 -0
- package/scripts/lint-md.mjs +267 -0
- package/scripts/lint-rules.mjs +186 -0
- package/scripts/merge-logic.mjs +44 -0
- package/scripts/plan-parser.mjs +53 -0
- package/scripts/publish-dual-npm.mjs +141 -0
- package/scripts/smoke-npm-docker.mjs +102 -0
- package/scripts/smoke-npm-local.mjs +109 -0
- package/scripts/update-download-badge.mjs +107 -0
- package/templates/MODULE_RULE_TEMPLATE.md +11 -0
- package/templates/PROJECT_RULE.md +47 -0
- package/templates/TICKET_TEMPLATE.ko.md +44 -0
- package/templates/TICKET_TEMPLATE.md +44 -0
- package/templates/project-pilot/CONFORMANCE_GATE_TEMPLATE.md +23 -0
- package/templates/project-pilot/DRIFT_CHECKLIST.md +19 -0
- package/templates/project-pilot/FLOW_CONTRACT_TEMPLATE.md +26 -0
- package/templates/project-pilot/IMPLEMENTATION_MATRIX_TEMPLATE.md +30 -0
- package/templates/project-pilot/INTEGRATION_CONTRACT_TEMPLATE.md +26 -0
- package/templates/project-pilot/OWNER_MAP_TEMPLATE.md +15 -0
- package/templates/project-pilot/PROJECT_PILOT_RULE_TEMPLATE.md +34 -0
- package/templates/project-pilot/REFACTOR_CONTRACT_TEMPLATE.md +32 -0
- package/templates/project-pilot/REMEDIATION_PLAN_TEMPLATE.md +33 -0
- package/templates/rules.d/deukcontext-mcp.md +31 -0
- package/templates/rules.d/platform-coexistence.md +29 -0
- package/templates/skills/context-recall/SKILL.md +25 -0
- package/templates/skills/generated-file-guard/SKILL.md +25 -0
- package/templates/skills/project-pilot/SKILL.md +63 -0
- package/templates/skills/safe-refactor/SKILL.md +25 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# DeukAgentFlow 실전 사용 가이드 (Practical Usage Guide)
|
|
2
|
+
|
|
3
|
+
이 가이드는 DeukAgentFlow를 실제 프로젝트에 배포하고 에이전트와 함께 효율적으로 사용하는 방법을 단계별로 설명합니다.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 워크스페이스 적용 모델 (Deployment)
|
|
8
|
+
|
|
9
|
+
DeukAgentFlow의 초기화 단위는 단순히 "현재 폴더 하나"가 아닙니다. 실제 운영은 보통 **workspace 루트 + 여러 프로젝트 루트 + 필요 시 중첩 프로젝트** 구조로 잡습니다.
|
|
10
|
+
|
|
11
|
+
예:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
~/workspace/
|
|
15
|
+
AGENTS.md # workspace 전체 포인터
|
|
16
|
+
PROJECT_RULE.md # workspace 기본 규칙
|
|
17
|
+
DeukPack/
|
|
18
|
+
AGENTS.md
|
|
19
|
+
PROJECT_RULE.md
|
|
20
|
+
.deuk-agent/
|
|
21
|
+
DeukAgentContext/
|
|
22
|
+
AGENTS.md
|
|
23
|
+
PROJECT_RULE.md
|
|
24
|
+
.deuk-agent/
|
|
25
|
+
i/
|
|
26
|
+
AGENTS.md
|
|
27
|
+
PROJECT_RULE.md
|
|
28
|
+
.deuk-agent/
|
|
29
|
+
i_server/
|
|
30
|
+
AGENTS.md
|
|
31
|
+
PROJECT_RULE.md
|
|
32
|
+
.deuk-agent/
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
이 모델에서 workspace 루트는 "공통 진입점"이고, 실제 작업 단위는 각 프로젝트의 `.deuk-agent/`입니다. 에이전트는 현재 CWD에서 가장 가까운 프로젝트 규칙과 티켓을 우선 사용합니다.
|
|
36
|
+
|
|
37
|
+
이렇게 사용하면 효과가 극대화됩니다.
|
|
38
|
+
|
|
39
|
+
- workspace 루트에는 공통 포인터만 둬서 어느 대화창에서 시작해도 같은 코어 규칙을 읽게 합니다.
|
|
40
|
+
- 각 프로젝트 루트에는 별도 `PROJECT_RULE.md`와 `.deuk-agent/`를 둬서 작업 맥락, 티켓, 검증 기록이 섞이지 않게 합니다.
|
|
41
|
+
- 서버/앱/패키지처럼 lifecycle이 다른 하위 폴더는 중첩 프로젝트로 초기화해 독립 티켓을 갖게 합니다.
|
|
42
|
+
- 에이전트에게는 긴 명령 대신 "진행", "다음", "원인", "정리"처럼 짧게 말하고, 에이전트가 현재 CWD 기준으로 맞는 프로젝트 티켓을 선택하게 합니다.
|
|
43
|
+
- 공통 규칙은 코어 허브에서, 프로젝트별 아키텍처/빌드/검증 규칙은 해당 프로젝트의 `PROJECT_RULE.md`에서 관리합니다.
|
|
44
|
+
|
|
45
|
+
### 적용 기준
|
|
46
|
+
|
|
47
|
+
| 위치 | 역할 | 초기화 여부 |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| workspace 루트 | 여러 프로젝트가 공유하는 포인터와 기본 규칙 | 선택 |
|
|
50
|
+
| 개별 프로젝트 루트 | 실제 작업 티켓, 로컬 규칙, 에이전트 포인터 | 권장 |
|
|
51
|
+
| 중첩 프로젝트 | 독립 배포/서버/앱처럼 별도 lifecycle이 있는 하위 프로젝트 | 필요 시 |
|
|
52
|
+
| generated/output 폴더 | 빌드 산출물 | 금지 |
|
|
53
|
+
|
|
54
|
+
### 1단계: 글로벌 설치
|
|
55
|
+
`npx` 캐시 문제를 피하고 어디서든 명령어를 사용할 수 있도록 글로벌 설치를 권장합니다.
|
|
56
|
+
```bash
|
|
57
|
+
npm install -g deuk-agent-flow
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 2단계: 프로젝트 루트 초기화
|
|
61
|
+
작업을 관리할 각 프로젝트 루트에서 초기화 명령을 실행합니다.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
deuk-agent-flow init
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
이 명령은 다음 파일들을 생성/업데이트합니다:
|
|
68
|
+
- `PROJECT_RULE.md`: 현재 프로젝트의 고유 규칙 (전역 `AGENTS.md`를 오버라이드).
|
|
69
|
+
- `.deuk-agent/`: 티켓, 템플릿, 설정이 저장되는 디렉토리.
|
|
70
|
+
- `.cursor/rules/deuk-agent.mdc`, `GEMINI.md` 등: 각 에이전트 환경에 맞는 얇은 포인터 파일.
|
|
71
|
+
|
|
72
|
+
여러 프로젝트를 한 workspace에서 관리한다면 각 루트에서 반복 실행합니다.
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
cd ~/workspace/DeukPack && deuk-agent-flow init
|
|
76
|
+
cd ~/workspace/DeukAgentContext && deuk-agent-flow init
|
|
77
|
+
cd ~/workspace/i && deuk-agent-flow init
|
|
78
|
+
cd ~/workspace/i/i_server && deuk-agent-flow init
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
초기화 후에는 각 프로젝트의 `PROJECT_RULE.md`를 채워야 합니다. 기본 템플릿 상태라면 에이전트는 아키텍처를 임의로 추측하지 말고, 사용자에게 규칙 정의를 요청하거나 코드베이스 분석 초안을 제안해야 합니다.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 2. 에이전트와 협업하기 (Daily Workflow)
|
|
86
|
+
|
|
87
|
+
에이전트에게 작업을 시킬 때는 **짧게 말하면 됩니다**. 티켓 생성과 Phase 전환은 에이전트가 내부적으로 처리하고, 사용자는 방향과 승인 여부에 집중합니다.
|
|
88
|
+
|
|
89
|
+
### 1단계: 티켓 생성 (Phase 1: Ticket + Plan)
|
|
90
|
+
에이전트에게 짧게 말해 작업을 시작합니다.
|
|
91
|
+
> "티켓 잡고 진행"
|
|
92
|
+
|
|
93
|
+
에이전트는 맥락에서 주제를 잡고, 내부적으로 티켓/APC/compact plan을 채웁니다. 사용자가 직접 `ticket create` 옵션을 외우거나 입력할 필요는 없습니다.
|
|
94
|
+
|
|
95
|
+
기존 작업을 이어받으려는데 `ticket next`가 진행 가능한 티켓을 찾지 못하면, 에이전트는 새 티켓을 즉시 만들지 않고 최근 git history를 먼저 분석해 실제 후속 작업 후보를 복원합니다. 새 티켓은 그 분석 근거를 메인 티켓의 compact plan에 기록한 뒤 생성합니다.
|
|
96
|
+
|
|
97
|
+
### 2단계: APC(Agent Permission Contract) 기록
|
|
98
|
+
생성된 티켓은 기본적으로 **Phase 1 (Ticket + Plan)** 상태입니다. 에이전트는 코드를 수정하기 전에 티켓 내의 APC 블록(`[BOUNDARY]`, `[CONTRACT]`, `[PATCH PLAN]`)을 채워야 합니다.
|
|
99
|
+
|
|
100
|
+
티켓은 스코프, 제약, APC 계약, 라이프사이클 체크, 검증 결과를 맡습니다. 실행 로그, 명령 transcript, 완료 요약, 검증 결과를 계획 문구와 섞지 않습니다.
|
|
101
|
+
|
|
102
|
+
사용자가 실행을 명확히 요청했고 Phase 1 기록이 완성되어 있으면, 에이전트가 내부적으로 Phase 승급을 시도합니다.
|
|
103
|
+
만약 APC나 compact plan이 비어있거나 불완전하다면, 에이전트는 코딩 전에 이를 먼저 채웁니다.
|
|
104
|
+
|
|
105
|
+
이슈/회귀/정책 위반을 제기한 경우에는 티켓 생성 직후 바로 실행하지 않습니다. 에이전트는 Phase 1에 원인 가설, 범위, APC, 패치 계획을 채운 뒤 멈추고 사용자의 검토 승인을 기다립니다. 원래 요청에 "수정", "해결"이 포함되어 있어도 티켓 계획을 본 뒤의 승인으로 보지 않습니다.
|
|
106
|
+
|
|
107
|
+
### 3단계: 작업 실행 (Phase 2: Execute)
|
|
108
|
+
티켓이 **Phase 2 (Execute)** 로 승급되면, 에이전트는 제한된 경계 내에서 코드를 수정하고 단위 테스트 등 검증 작업을 수행합니다.
|
|
109
|
+
|
|
110
|
+
### 4단계: 작업 완료 및 아카이빙
|
|
111
|
+
작업이 끝나면 정리만 짧게 요청하세요.
|
|
112
|
+
> "검증 기록하고 정리"
|
|
113
|
+
|
|
114
|
+
이때 아카이브 작업 중 **Zero-Token 지식 증류(Knowledge Distillation)**가 동작하여 불필요한 컨텍스트 토큰 소모를 줄이도록 핵심 정보만 압축되어 저장됩니다.
|
|
115
|
+
|
|
116
|
+
### 5단계: 티켓 파일 깃 관리
|
|
117
|
+
티켓 파일도 깃 기록의 일부이지만, 소스 코드처럼 무심코 다루면 active/archive 상태가 쉽게 꼬입니다.
|
|
118
|
+
|
|
119
|
+
- `ticket create`, `ticket move`, `ticket close`, `ticket archive`로 바뀐 `.deuk-agent/tickets/INDEX*.json`은 함께 커밋합니다. 티켓 본문만 커밋하고 index를 빼면 다음 작업에서 상태가 맞지 않을 수 있습니다.
|
|
120
|
+
- `.deuk-agent/tickets/**/*.md`는 CLI가 만든 결과만 따라갑니다. 티켓 생성이 실패한 뒤 파일을 손으로 만들거나 고치지 않습니다.
|
|
121
|
+
- 작업 중 티켓 본문을 다듬는 것은 괜찮지만, 상태를 바꿀 때는 frontmatter를 직접 고치지 말고 반드시 CLI를 사용합니다.
|
|
122
|
+
- `.deuk-agent/telemetry.jsonl`은 보통 실행 로그에 가깝기 때문에, 저장소 정책상 꼭 추적하는 경우가 아니라면 커밋 목록에 넣지 않는 편이 안전합니다.
|
|
123
|
+
- 작업을 끝냈다면 `ticket archive`까지 마친 뒤 커밋하는 편이 좋습니다. archive는 티켓 파일 위치와 archive index를 함께 정리하므로, 중간에 손으로 옮기면 기록 흐름이 흐려집니다.
|
|
124
|
+
- 여러 작업을 한 커밋에 섞지 말고, 가능하면 "코드 변경 + 해당 티켓 lifecycle 변경" 묶음으로 나눕니다.
|
|
125
|
+
|
|
126
|
+
빠르게 확인할 때는 아래 정도를 습관처럼 보면 좋습니다.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
git status --short
|
|
130
|
+
git diff -- .deuk-agent/tickets/INDEX.json
|
|
131
|
+
git diff -- .deuk-agent/tickets/INDEX.archive.*.json
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
티켓 관련 변경이 보일 때는 "이 변경이 CLI lifecycle의 결과인가?"를 먼저 확인하세요. 아니라면 손으로 고치기보다 `ticket status`, `ticket list`, `ticket archive` 같은 명령으로 상태를 다시 맞추는 편이 안전합니다.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 3. 에이전트 프롬프트 가이드 (Agent Prompting)
|
|
139
|
+
|
|
140
|
+
에이전트가 DeukAgentFlow 프로토콜을 엄격히 준수하도록 하려면 프로젝트 시작 시 짧은 지침이면 충분합니다.
|
|
141
|
+
|
|
142
|
+
> **에이전트 지침 예시:**
|
|
143
|
+
> "DeukAgentFlow 규칙을 따르고, 사용자의 짧은 지시를 티켓/Phase/검증 기록으로 처리해라. 코드 수정 전에는 APC와 계획을 먼저 남긴다."
|
|
144
|
+
|
|
145
|
+
### `/` 단축 명령
|
|
146
|
+
|
|
147
|
+
지원되는 에이전트에서는 짧은 요청을 slash command로 노출할 수 있습니다. 다만 모든 클라이언트가 같은 방식으로 커스텀 `/` 명령을 지원하지는 않으므로, 기본 UX는 짧은 자연어 요청으로 둡니다.
|
|
148
|
+
|
|
149
|
+
| 의도 | 자연어 fallback | slash 후보 |
|
|
150
|
+
|---|---|---|
|
|
151
|
+
| 다음 단계 | "다음" | `/next` |
|
|
152
|
+
| 티켓 시작 | "진행" | `/flow` |
|
|
153
|
+
| 원인 분석 | "원인" | `/inspect` |
|
|
154
|
+
| 검증/정리 | "정리" | `/closeout` |
|
|
155
|
+
|
|
156
|
+
권장 매핑:
|
|
157
|
+
|
|
158
|
+
- Claude Code: 프로젝트 `.claude/skills/<name>/SKILL.md` 또는 `.claude/commands/<name>.md`
|
|
159
|
+
- Cursor: 프로젝트 `.cursor/commands/<name>.md`
|
|
160
|
+
- VS Code Copilot: 프로젝트 `.github/prompts/<name>.prompt.md`
|
|
161
|
+
- Codex: 우선 짧은 자연어와 skill 호출을 사용하고, 커스텀 slash 표준이 확인되면 별도 노출
|
|
162
|
+
|
|
163
|
+
### 스킬 리스트와 기존 스킬 추가
|
|
164
|
+
|
|
165
|
+
스킬은 전체 workflow를 대체하지 않는 짧은 행동 playbook입니다. DeukAgentFlow에서는 티켓/APC/Phase Gate가 계속 상위 권한이고, 스킬은 특정 실패 패턴에서 에이전트의 움직임만 더 날카롭게 만듭니다.
|
|
166
|
+
|
|
167
|
+
`init`을 실행하면 first-party 스킬 원본은 `.deuk-agent/skill-templates/`로 동기화됩니다. 실제 장착은 프로젝트 성격에 맞게 `skill add`로 선택합니다.
|
|
168
|
+
|
|
169
|
+
기본 추천 장착:
|
|
170
|
+
|
|
171
|
+
| 스킬 | 이유 |
|
|
172
|
+
|---|---|
|
|
173
|
+
| `safe-refactor` | 대부분의 AI 코딩 사고가 과한 리팩터링과 범위 확장에서 시작하기 때문 |
|
|
174
|
+
| `generated-file-guard` | generated output 직접 수정은 리뷰와 재생성 단계에서 가장 자주 깨지기 때문 |
|
|
175
|
+
|
|
176
|
+
선택 장착:
|
|
177
|
+
|
|
178
|
+
| 스킬 | 쓸 때 |
|
|
179
|
+
|---|---|
|
|
180
|
+
| `context-recall` | 과거 티켓/결정/실패 패턴을 찾아야 할 때 |
|
|
181
|
+
| `project-pilot` | 다국어, generated/runtime, protocol, 반복 drift 리팩터링 |
|
|
182
|
+
|
|
183
|
+
사용자는 이렇게 짧게 말해도 됩니다.
|
|
184
|
+
|
|
185
|
+
| 하고 싶은 일 | 말하기 |
|
|
186
|
+
|---|---|
|
|
187
|
+
| 설치 가능한 스킬 보기 | "스킬 리스트" |
|
|
188
|
+
| 기존 스킬 추가 | "safe-refactor 추가" |
|
|
189
|
+
| Claude에 노출 | "스킬 Claude에 노출" |
|
|
190
|
+
| Cursor에 노출 | "스킬 Cursor에 노출" |
|
|
191
|
+
|
|
192
|
+
메인테이너/자동화에서는 CLI를 직접 사용할 수 있습니다.
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
deuk-agent-flow skill list
|
|
196
|
+
deuk-agent-flow skill add --skill safe-refactor
|
|
197
|
+
deuk-agent-flow skill add --skill generated-file-guard
|
|
198
|
+
deuk-agent-flow skill add --skill context-recall
|
|
199
|
+
deuk-agent-flow skill add --skill project-pilot
|
|
200
|
+
deuk-agent-flow skill expose --platform claude
|
|
201
|
+
deuk-agent-flow skill expose --platform cursor
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
`skill add`는 프로젝트의 `.deuk-agent/skills/<id>/SKILL.md`에 스킬을 설치하고, `skill expose`는 설치된 스킬을 Claude/Cursor가 읽을 수 있는 얇은 포인터로 노출합니다.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## 4. 팁 및 모범 사례
|
|
209
|
+
|
|
210
|
+
- **No Ticket, No Code**: 티켓 없이 코드를 수정하는 것은 금지됩니다. 사용자는 짧게 말하고, 에이전트가 티켓 기록을 남깁니다.
|
|
211
|
+
- **RAG 활용**: `mcp_deukcontext_search_*` 도구를 사용하여 과거 티켓이나 구현 사례를 검색하면 환각을 줄일 수 있습니다.
|
|
212
|
+
- **주기적 동기화**: 프로젝트 규칙이 변경되었다면 `deuk-agent-flow init`을 다시 실행하여 모든 에이전트 포인터를 갱신하세요.
|
package/package.json
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "deuk-agent-flow",
|
|
3
|
+
"version": "4.0.19",
|
|
4
|
+
"description": "Keep AI coding work from vanishing between chats: repo-owned tickets, scope, verification, and memory for AGENTS.md-powered agents.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agents-md",
|
|
7
|
+
"cursor-rules",
|
|
8
|
+
"copilot",
|
|
9
|
+
"agent-config",
|
|
10
|
+
"agent-workflow",
|
|
11
|
+
"ai-coding-agent",
|
|
12
|
+
"gemini",
|
|
13
|
+
"claude",
|
|
14
|
+
"windsurf",
|
|
15
|
+
"jetbrains",
|
|
16
|
+
"ticket",
|
|
17
|
+
"ai-guardrails",
|
|
18
|
+
"agent-guardrails",
|
|
19
|
+
"deuk-family",
|
|
20
|
+
"deukpack-ecosystem"
|
|
21
|
+
],
|
|
22
|
+
"license": "Apache-2.0",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/joygram/DeukAgentFlow.git"
|
|
26
|
+
},
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/joygram/DeukAgentFlow/issues"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/joygram/DeukAgentFlow#readme",
|
|
31
|
+
"files": [
|
|
32
|
+
"LICENSE",
|
|
33
|
+
"bin/**/*",
|
|
34
|
+
"core-rules/**/*",
|
|
35
|
+
"docs/architecture.md",
|
|
36
|
+
"docs/architecture.ko.md",
|
|
37
|
+
"docs/how-it-works.md",
|
|
38
|
+
"docs/how-it-works.ko.md",
|
|
39
|
+
"docs/principles.md",
|
|
40
|
+
"docs/principles.ko.md",
|
|
41
|
+
"docs/npm-publish-guide.ko.md",
|
|
42
|
+
"docs/usage-guide.ko.md",
|
|
43
|
+
"docs/assets/**/*",
|
|
44
|
+
"templates/**/*",
|
|
45
|
+
"scripts/cli.mjs",
|
|
46
|
+
"scripts/cli-args.mjs",
|
|
47
|
+
"scripts/cli-usage-commands.mjs",
|
|
48
|
+
"scripts/cli-init-commands.mjs",
|
|
49
|
+
"scripts/cli-init-logic.mjs",
|
|
50
|
+
"scripts/cli-prompts.mjs",
|
|
51
|
+
"scripts/cli-rule-compiler.mjs",
|
|
52
|
+
"scripts/cli-skill-commands.mjs",
|
|
53
|
+
"scripts/cli-telemetry-commands.mjs",
|
|
54
|
+
"scripts/cli-ticket-commands.mjs",
|
|
55
|
+
"scripts/cli-ticket-index.mjs",
|
|
56
|
+
"scripts/cli-ticket-migration.mjs",
|
|
57
|
+
"scripts/cli-ticket-parser.mjs",
|
|
58
|
+
"scripts/cli-utils.mjs",
|
|
59
|
+
"scripts/lint-md.mjs",
|
|
60
|
+
"scripts/lint-rules.mjs",
|
|
61
|
+
"scripts/merge-logic.mjs",
|
|
62
|
+
"scripts/plan-parser.mjs",
|
|
63
|
+
"scripts/publish-dual-npm.mjs",
|
|
64
|
+
"scripts/smoke-npm-local.mjs",
|
|
65
|
+
"scripts/smoke-npm-docker.mjs",
|
|
66
|
+
"scripts/update-download-badge.mjs",
|
|
67
|
+
"README.md",
|
|
68
|
+
"README.ko.md",
|
|
69
|
+
"CHANGELOG.md",
|
|
70
|
+
"CHANGELOG.ko.md"
|
|
71
|
+
],
|
|
72
|
+
"scripts": {
|
|
73
|
+
"lint:md": "node scripts/lint-md.mjs",
|
|
74
|
+
"test": "node --test scripts/tests/*.test.mjs",
|
|
75
|
+
"publish": "node scripts/publish-dual-npm.mjs",
|
|
76
|
+
"publish:dry": "node scripts/publish-dual-npm.mjs --dry-run",
|
|
77
|
+
"smoke:npm:local": "node scripts/smoke-npm-local.mjs",
|
|
78
|
+
"smoke:npm:docker": "node scripts/smoke-npm-docker.mjs",
|
|
79
|
+
"publish:bootstrap": "node scripts/publish-dual-npm.mjs --alias-only",
|
|
80
|
+
"publish:bootstrap:dry": "node scripts/publish-dual-npm.mjs --alias-only --dry-run",
|
|
81
|
+
"badge:downloads": "node scripts/update-download-badge.mjs"
|
|
82
|
+
},
|
|
83
|
+
"engines": {
|
|
84
|
+
"node": ">=18"
|
|
85
|
+
},
|
|
86
|
+
"bin": {
|
|
87
|
+
"deuk-agent-flow": "./bin/deuk-agent-flow.js",
|
|
88
|
+
"deukagentflow": "./bin/deuk-agent-flow.js",
|
|
89
|
+
"deuk-agent-rule": "./bin/deuk-agent-rule.js",
|
|
90
|
+
"deukagentrule": "./bin/deuk-agent-rule.js"
|
|
91
|
+
},
|
|
92
|
+
"dependencies": {
|
|
93
|
+
"ejs": "^5.0.2",
|
|
94
|
+
"yaml": "^2.8.3"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
export function parseTicketArgs(argv) {
|
|
2
|
+
const out = { cwd: process.cwd(), dryRun: false, nonInteractive: false, limit: 20 };
|
|
3
|
+
for (let i = 0; i < argv.length; i++) {
|
|
4
|
+
const a = argv[i];
|
|
5
|
+
if (a === "--cwd") out.cwd = argv[++i];
|
|
6
|
+
else if (a === "--dry-run") out.dryRun = true;
|
|
7
|
+
else if (a === "--non-interactive") out.nonInteractive = true;
|
|
8
|
+
else if (a === "--topic" || a === "--id") out.topic = argv[++i];
|
|
9
|
+
else if (a === "--group") out.group = argv[++i];
|
|
10
|
+
else if (a === "--project") out.project = argv[++i];
|
|
11
|
+
else if (a === "--content") out.content = argv[++i];
|
|
12
|
+
else if (a === "--content-file") out.contentFile = argv[++i];
|
|
13
|
+
else if (a === "--from") out.from = argv[++i];
|
|
14
|
+
else if (a === "--plan-body") out.planBody = argv[++i];
|
|
15
|
+
else if (a === "--plan-body-file") out.planBodyFile = argv[++i];
|
|
16
|
+
else if (a === "--ref") out.ref = argv[++i];
|
|
17
|
+
else if (a === "--limit") out.limit = Number(argv[++i]);
|
|
18
|
+
else if (a === "--submodule") out.submodule = argv[++i];
|
|
19
|
+
else if (a === "--latest" || a === "-l") out.latest = true;
|
|
20
|
+
else if (a === "--path-only") out.pathOnly = true;
|
|
21
|
+
else if (a === "--print-content") out.printContent = true;
|
|
22
|
+
else if (a === "--all") out.all = true;
|
|
23
|
+
else if (a === "--status") out.status = argv[++i];
|
|
24
|
+
else if (a === "--archived") out.archived = true;
|
|
25
|
+
else if (a === "--priority") out.priority = argv[++i];
|
|
26
|
+
else if (a === "--report") out.report = argv[++i];
|
|
27
|
+
else if (a === "--json") out.json = true;
|
|
28
|
+
else if (a === "--remote") out.remote = argv[++i];
|
|
29
|
+
else if (a === "--sync") out.sync = true;
|
|
30
|
+
else if (a === "--no-sync") out.sync = false;
|
|
31
|
+
else if (a === "--chain") out.chain = true;
|
|
32
|
+
else if (a === "--render") out.render = true;
|
|
33
|
+
else if (a === "--docs-language") out.docsLanguage = argv[++i];
|
|
34
|
+
else if (a === "--workflow") out.workflowMode = argv[++i];
|
|
35
|
+
else if (a === "--approval") out.approval = argv[++i];
|
|
36
|
+
else if (a === "--ticket-started") out.ticketStarted = true;
|
|
37
|
+
else if (a === "--ticket-reviewed") out.ticketReviewed = true;
|
|
38
|
+
else if (a === "--evidence") out.evidence = argv[++i];
|
|
39
|
+
else if (a === "--skip-phase0") out.skipPhase0 = true;
|
|
40
|
+
else if (a === "--summary") out.summary = argv[++i];
|
|
41
|
+
else if (a === "--tags") out.tags = argv[++i];
|
|
42
|
+
else if (a === "--phase") out.phase = Number(argv[++i]);
|
|
43
|
+
else if (a === "--next") out.next = true;
|
|
44
|
+
else if (a === "--handoff") out.handoff = true;
|
|
45
|
+
else if (a === "--reason") out.reason = argv[++i];
|
|
46
|
+
else if (a === "--claim") out.claim = argv[++i];
|
|
47
|
+
else if (a === "--require-filled") out.requireFilled = true;
|
|
48
|
+
else if (a === "--allow-placeholder") out.allowPlaceholder = true;
|
|
49
|
+
else if (a === "--compact") out.compact = true;
|
|
50
|
+
else if (a === "--status-detail") out.statusDetail = true;
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function parseArgs(argv) {
|
|
56
|
+
const out = { cwd: process.cwd(), dryRun: false, backup: false };
|
|
57
|
+
for (let i = 0; i < argv.length; i++) {
|
|
58
|
+
const a = argv[i];
|
|
59
|
+
if (a === "--cwd") out.cwd = argv[++i];
|
|
60
|
+
else if (a === "--dry-run") out.dryRun = true;
|
|
61
|
+
else if (a === "--backup") out.backup = true;
|
|
62
|
+
else if (a === "--non-interactive") out.nonInteractive = true;
|
|
63
|
+
else if (a === "--interactive") out.interactive = true;
|
|
64
|
+
else if (a === "--clean") out.clean = true;
|
|
65
|
+
else if (a === "--tag") out.tag = argv[++i];
|
|
66
|
+
else if (a === "--marker-begin") out.markerBegin = argv[++i];
|
|
67
|
+
else if (a === "--marker-end") out.markerEnd = argv[++i];
|
|
68
|
+
else if (a === "--agents") out.agents = argv[++i];
|
|
69
|
+
else if (a === "--cursorrules") out.cursorrules = argv[++i];
|
|
70
|
+
else if (a === "--append-if-no-markers") out.appendIfNoMarkers = true;
|
|
71
|
+
else if (a === "--workflow") out.workflowMode = argv[++i];
|
|
72
|
+
else if (a === "--approval") out.approval = argv[++i];
|
|
73
|
+
else if (a === "--json") out.json = true;
|
|
74
|
+
else if (a === "--remote") out.remote = argv[++i];
|
|
75
|
+
else if (a === "--sync") out.sync = true;
|
|
76
|
+
else if (a === "--no-sync") out.sync = false;
|
|
77
|
+
else if (a === "--docs-language") out.docsLanguage = argv[++i];
|
|
78
|
+
else if (a === "--compact") out.compact = true;
|
|
79
|
+
else if (a === "-h" || a === "--help") out.help = true;
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function parseSkillArgs(argv) {
|
|
85
|
+
const out = { cwd: process.cwd(), dryRun: false, nonInteractive: false };
|
|
86
|
+
for (let i = 0; i < argv.length; i++) {
|
|
87
|
+
const a = argv[i];
|
|
88
|
+
if (a === "--cwd") out.cwd = argv[++i];
|
|
89
|
+
else if (a === "--dry-run") out.dryRun = true;
|
|
90
|
+
else if (a === "--non-interactive") out.nonInteractive = true;
|
|
91
|
+
else if (a === "--skill" || a === "--id") out.skill = argv[++i];
|
|
92
|
+
else if (a === "--platform") out.platform = argv[++i];
|
|
93
|
+
else if (a === "--json") out.json = true;
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function parseUsageArgs(argv) {
|
|
99
|
+
const out = {
|
|
100
|
+
cwd: process.cwd(),
|
|
101
|
+
json: false,
|
|
102
|
+
platform: "",
|
|
103
|
+
client: "",
|
|
104
|
+
agentId: "",
|
|
105
|
+
weeklyRemaining: null,
|
|
106
|
+
fiveHourRemaining: null,
|
|
107
|
+
weeklyReset: "",
|
|
108
|
+
fiveHourReset: "",
|
|
109
|
+
taskGrade: "",
|
|
110
|
+
taskLabel: "",
|
|
111
|
+
turnCount: 0,
|
|
112
|
+
linkedTicketCount: 0,
|
|
113
|
+
crossWorkspace: false
|
|
114
|
+
};
|
|
115
|
+
for (let i = 0; i < argv.length; i++) {
|
|
116
|
+
const a = argv[i];
|
|
117
|
+
if (a === "--cwd") out.cwd = argv[++i];
|
|
118
|
+
else if (a === "--platform") out.platform = argv[++i];
|
|
119
|
+
else if (a === "--client") out.client = argv[++i];
|
|
120
|
+
else if (a === "--agent" || a === "--agent-id") out.agentId = argv[++i];
|
|
121
|
+
else if (a === "--weekly-remaining") out.weeklyRemaining = Number(argv[++i]);
|
|
122
|
+
else if (a === "--five-hour-remaining") out.fiveHourRemaining = Number(argv[++i]);
|
|
123
|
+
else if (a === "--weekly-reset") out.weeklyReset = argv[++i];
|
|
124
|
+
else if (a === "--five-hour-reset") out.fiveHourReset = argv[++i];
|
|
125
|
+
else if (a === "--task-grade") out.taskGrade = argv[++i];
|
|
126
|
+
else if (a === "--task" || a === "--task-label") out.taskLabel = argv[++i];
|
|
127
|
+
else if (a === "--turns" || a === "--turn-count") out.turnCount = Number(argv[++i]);
|
|
128
|
+
else if (a === "--linked-tickets" || a === "--linked-ticket-count") out.linkedTicketCount = Number(argv[++i]);
|
|
129
|
+
else if (a === "--cross-workspace") out.crossWorkspace = true;
|
|
130
|
+
else if (a === "--json") out.json = true;
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function parseTelemetryArgs(argv) {
|
|
136
|
+
const out = {
|
|
137
|
+
cwd: process.cwd(),
|
|
138
|
+
tokens: 0,
|
|
139
|
+
tdw: 0,
|
|
140
|
+
model: "",
|
|
141
|
+
client: "",
|
|
142
|
+
agentId: "",
|
|
143
|
+
ticket: "",
|
|
144
|
+
action: "",
|
|
145
|
+
file: "",
|
|
146
|
+
remote: "",
|
|
147
|
+
source: "",
|
|
148
|
+
kind: "",
|
|
149
|
+
event: "",
|
|
150
|
+
occurredAt: "",
|
|
151
|
+
phase: "",
|
|
152
|
+
status: "",
|
|
153
|
+
ragResult: "",
|
|
154
|
+
localFallback: false,
|
|
155
|
+
knowledgeAction: "",
|
|
156
|
+
tokenQuality: "",
|
|
157
|
+
savedTokens: 0,
|
|
158
|
+
sessionMode: "",
|
|
159
|
+
retryCount: 0,
|
|
160
|
+
turnCount: 0,
|
|
161
|
+
failureCount: 0,
|
|
162
|
+
phaseTransitionCount: 0,
|
|
163
|
+
outcome: "",
|
|
164
|
+
qualityScore: 0,
|
|
165
|
+
json: false
|
|
166
|
+
};
|
|
167
|
+
for (let i = 0; i < argv.length; i++) {
|
|
168
|
+
const a = argv[i];
|
|
169
|
+
if (a === "--cwd") out.cwd = argv[++i];
|
|
170
|
+
else if (a === "--tokens") out.tokens = Number(argv[++i]);
|
|
171
|
+
else if (a === "--tdw") out.tdw = Number(argv[++i]);
|
|
172
|
+
else if (a === "--model") out.model = argv[++i];
|
|
173
|
+
else if (a === "--client") out.client = argv[++i];
|
|
174
|
+
else if (a === "--agent" || a === "--agent-id") out.agentId = argv[++i];
|
|
175
|
+
else if (a === "--ticket") out.ticket = argv[++i];
|
|
176
|
+
else if (a === "--action") out.action = argv[++i];
|
|
177
|
+
else if (a === "--file") out.file = argv[++i];
|
|
178
|
+
else if (a === "--remote") out.remote = argv[++i];
|
|
179
|
+
else if (a === "--source") out.source = argv[++i];
|
|
180
|
+
else if (a === "--kind") out.kind = argv[++i];
|
|
181
|
+
else if (a === "--event") out.event = argv[++i];
|
|
182
|
+
else if (a === "--occurred-at") out.occurredAt = argv[++i];
|
|
183
|
+
else if (a === "--phase") out.phase = Number(argv[++i]);
|
|
184
|
+
else if (a === "--status") out.status = argv[++i];
|
|
185
|
+
else if (a === "--rag-result") out.ragResult = argv[++i];
|
|
186
|
+
else if (a === "--local-fallback") out.localFallback = true;
|
|
187
|
+
else if (a === "--knowledge-action") out.knowledgeAction = argv[++i];
|
|
188
|
+
else if (a === "--token-quality") out.tokenQuality = argv[++i];
|
|
189
|
+
else if (a === "--saved-tokens") out.savedTokens = Number(argv[++i]);
|
|
190
|
+
else if (a === "--session-mode") out.sessionMode = argv[++i];
|
|
191
|
+
else if (a === "--retries") out.retryCount = Number(argv[++i]);
|
|
192
|
+
else if (a === "--turns") out.turnCount = Number(argv[++i]);
|
|
193
|
+
else if (a === "--failures") out.failureCount = Number(argv[++i]);
|
|
194
|
+
else if (a === "--phase-transitions") out.phaseTransitionCount = Number(argv[++i]);
|
|
195
|
+
else if (a === "--outcome") out.outcome = argv[++i];
|
|
196
|
+
else if (a === "--quality-score") out.qualityScore = Number(argv[++i]);
|
|
197
|
+
else if (a === "--json") out.json = true;
|
|
198
|
+
}
|
|
199
|
+
return out;
|
|
200
|
+
}
|